Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenaka Moorthi <benaka.moorthi@gmail.com>2013-08-10 03:25:50 +0400
committerBenaka Moorthi <benaka.moorthi@gmail.com>2013-08-10 03:25:50 +0400
commita3bc6979a99444f29da1aa7973338e3dcd72d309 (patch)
tree2ac49526db2e40a9a3dfedd0b95cb68b07062265 /plugins
parentcfb17ed2795101ea90d71d124d91b0cbad09858c (diff)
Refs #3089, add initial visitor profile popup that uses dynamic data from Live plugin API. No client-side behavior yet & placeholder images still present.
Diffstat (limited to 'plugins')
-rw-r--r--plugins/CoreHome/CoreHome.php5
-rw-r--r--plugins/CoreHome/javascripts/popover.js35
-rw-r--r--plugins/Live/API.php152
-rw-r--r--plugins/Live/Controller.php15
-rw-r--r--plugins/Live/Live.php3
-rw-r--r--plugins/Live/images/REMOVE_ME_avatar.jpgbin0 -> 13984 bytes
-rw-r--r--plugins/Live/images/REMOVE_ME_chart.pngbin0 -> 15208 bytes
-rw-r--r--plugins/Live/images/REMOVE_ME_map.jpgbin0 -> 64945 bytes
-rw-r--r--plugins/Live/images/avatar_frame.pngbin0 -> 5375 bytes
-rw-r--r--plugins/Live/images/paperclip.pngbin0 -> 10924 bytes
-rw-r--r--plugins/Live/images/visitor_profile_background.jpgbin0 -> 11060 bytes
-rw-r--r--plugins/Live/images/visitor_profile_close.png (renamed from plugins/SegmentEditor/images/down_arrow.png)bin2898 -> 4734 bytes
-rw-r--r--plugins/Live/images/visitor_profile_gradient.png (renamed from plugins/SegmentEditor/images/slide.png)bin2831 -> 2840 bytes
-rw-r--r--plugins/Live/stylesheets/visitor_profile.less365
-rw-r--r--plugins/Live/templates/_actionsList.twig106
-rw-r--r--plugins/Live/templates/getVisitorLog.twig111
-rw-r--r--plugins/Live/templates/getVisitorProfilePopup.twig121
-rw-r--r--plugins/SegmentEditor/SegmentEditor.php5
-rw-r--r--plugins/SegmentEditor/images/scroller.pngbin3329 -> 0 bytes
-rw-r--r--plugins/SegmentEditor/images/up_arrow.pngbin2881 -> 0 bytes
-rw-r--r--plugins/SegmentEditor/javascripts/jquery.jscrollpane.js1341
-rw-r--r--plugins/SegmentEditor/javascripts/jquery.mousewheel.js117
-rw-r--r--plugins/SegmentEditor/javascripts/mwheelIntent.js76
-rw-r--r--plugins/SegmentEditor/stylesheets/jquery.jscrollpane.css119
-rw-r--r--plugins/SegmentEditor/stylesheets/scroll.less140
25 files changed, 794 insertions, 1917 deletions
diff --git a/plugins/CoreHome/CoreHome.php b/plugins/CoreHome/CoreHome.php
index c78d5b3d6e..c7b6e01a5f 100644
--- a/plugins/CoreHome/CoreHome.php
+++ b/plugins/CoreHome/CoreHome.php
@@ -41,6 +41,8 @@ class Piwik_CoreHome extends Plugin
public function getCssFiles(&$cssFiles)
{
$cssFiles[] = "libs/jquery/themes/base/jquery-ui.css";
+ $cssFiles[] = "libs/jquery/stylesheets/jquery.jscrollpane.css";
+ $cssFiles[] = "libs/jquery/stylesheets/scroll.less";
$cssFiles[] = "plugins/Zeitgeist/stylesheets/base.less";
$cssFiles[] = "plugins/CoreHome/stylesheets/coreHome.less";
$cssFiles[] = "plugins/CoreHome/stylesheets/menu.less";
@@ -62,6 +64,9 @@ class Piwik_CoreHome extends Plugin
$jsFiles[] = "libs/jquery/jquery.truncate.js";
$jsFiles[] = "libs/jquery/jquery.scrollTo.js";
$jsFiles[] = "libs/jquery/jquery.history.js";
+ $jsFiles[] = "libs/jquery/jquery.jscrollpane.js";
+ $jsFiles[] = "libs/jquery/jquery.mousewheel.js";
+ $jsFiles[] = "libs/jquery/mwheelIntent.js";
$jsFiles[] = "libs/javascript/sprintf.js";
$jsFiles[] = "plugins/Zeitgeist/javascripts/piwikHelper.js";
$jsFiles[] = "plugins/Zeitgeist/javascripts/ajaxHelper.js";
diff --git a/plugins/CoreHome/javascripts/popover.js b/plugins/CoreHome/javascripts/popover.js
index 0ffe6d7619..27c07dc334 100644
--- a/plugins/CoreHome/javascripts/popover.js
+++ b/plugins/CoreHome/javascripts/popover.js
@@ -17,10 +17,11 @@ var Piwik_Popover = (function () {
}
};
- var openPopover = function (title) {
+ var openPopover = function (title, dialogClass) {
createContainer();
- container.dialog({
+ var options =
+ {
title: title,
modal: true,
width: '950px',
@@ -28,6 +29,10 @@ var Piwik_Popover = (function () {
resizable: false,
autoOpen: true,
open: function (event, ui) {
+ if (dialogClass) {
+ $(this).parent().addClass(dialogClass).attr('style', '');
+ }
+
$('.ui-widget-overlay').on('click.popover', function () {
container.dialog('close');
});
@@ -45,7 +50,9 @@ var Piwik_Popover = (function () {
closeCallback = false;
}
}
- });
+ };
+
+ container.dialog(options);
// override the undocumented _title function to ensure that the title attribute is not escaped (according to jQueryUI bug #6016)
container.data( "uiDialog" )._title = function(title) {
@@ -70,7 +77,7 @@ var Piwik_Popover = (function () {
* @param {string} [popoverSubject] subject of the popover (e.g. url, optional)
* @param {int} [height] height of the popover in px (optional)
*/
- showLoading: function (popoverName, popoverSubject, height) {
+ showLoading: function (popoverName, popoverSubject, height, dialogClass) {
var loading = $(document.createElement('div')).addClass('Piwik_Popover_Loading');
var loadingMessage = popoverSubject ? translations.General_LoadingPopoverFor_js :
@@ -94,7 +101,7 @@ var Piwik_Popover = (function () {
}
if (!isOpen) {
- openPopover();
+ openPopover(null, dialogClass);
}
this.setContent(loading);
@@ -203,9 +210,18 @@ var Piwik_Popover = (function () {
* @param {string} url
* @param {string} loadingName
*/
- createPopupAndLoadUrl: function (url, loadingName) {
+ createPopupAndLoadUrl: function (url, loadingName, dialogClass) {
+ // make sure the minimum top position of the popover is 106px
+ var ensureMinimumTop = function () {
+ var popoverContainer = $('#Piwik_Popover').parent();
+ if (popoverContainer.position().top < 106) {
+ popoverContainer.css('top', '106px');
+ }
+ };
+
// open the popover
- var box = Piwik_Popover.showLoading(loadingName);
+ var box = Piwik_Popover.showLoading(loadingName, null, null, dialogClass);
+ ensureMinimumTop();
var callback = function (html) {
function setPopoverTitleIfOneFoundInContainer() {
@@ -218,6 +234,7 @@ var Piwik_Popover = (function () {
Piwik_Popover.setContent(html);
setPopoverTitleIfOneFoundInContainer();
+ ensureMinimumTop();
};
var ajaxRequest = new ajaxHelper();
ajaxRequest.addParams(piwikHelper.getArrayFromQueryString(url), 'get');
@@ -226,6 +243,4 @@ var Piwik_Popover = (function () {
ajaxRequest.send(false);
}
};
-
-})();
-
+})(); \ No newline at end of file
diff --git a/plugins/Live/API.php b/plugins/Live/API.php
index 3354c67335..739973bb99 100644
--- a/plugins/Live/API.php
+++ b/plugins/Live/API.php
@@ -155,6 +155,158 @@ class Piwik_Live_API
return $dataTable;
}
+ const VISITOR_PROFILE_MAX_VISITS_TO_AGGREGATE = 100;
+ const VISITOR_PROFILE_MAX_VISITS_TO_SHOW = 10;
+ const VISITOR_PROFILE_DATE_FORMAT = '%day% %shortMonth% %longYear%';
+
+ /**
+ * TODO
+ * TODO: add abandoned cart info.
+ * TODO: check for most recent vs. first visit
+ * TODO: make sure ecommerce is enabled for site, check for goals plugin, etc.
+ */
+ public function getVisitorProfile($idSite, $period, $date, $idVisitor, $segment = false)
+ {
+ if ($segment !== false) {
+ $segment .= '&';
+ }
+ $segment .= 'visitorId==' . $idVisitor; // TODO what happens when visitorId is in the segment?
+
+ $visits = $this->getLastVisitsDetails($idSite, $period, $date, $segment, $filter_limit = self::VISITOR_PROFILE_MAX_VISITS_TO_AGGREGATE);
+ if ($visits->getRowsCount() == 0) {
+ return array();
+ }
+
+ $result = array();
+
+ // use the most recent visit for IP/browser/OS/etc. info
+ // TODO: could just do all of this in twig/JS... really need to do it here?
+ $mostRecentVisit = $visits->getFirstRow();
+ $result['latestVisitIp'] = $mostRecentVisit->getColumn('visitIp');
+ $result['visitorId'] = $mostRecentVisit->getColumn('visitorId');
+ $result['browserCode'] = $mostRecentVisit->getColumn('browserCode');
+ $result['browserName'] = Piwik_UserSettings_getBrowserFromBrowserVersion($mostRecentVisit->getColumn('browserName'));
+ $result['browserLogo'] = $mostRecentVisit->getColumn('browserIcon');
+ $result['operatingSystemCode'] = $mostRecentVisit->getColumn('operatingSystemCode');
+ $result['operatingSystemShortName'] = $mostRecentVisit->getColumn('operatingSystemShortName');
+ $result['operatingSystemLogo'] = $mostRecentVisit->getColumn('operatingSystemIcon');
+ $result['resolution'] = $mostRecentVisit->getColumn('resolution');
+ $result['customVariables'] = $mostRecentVisit->getColumn('customVariables');
+
+ // aggregate all requested visits info for total_* info
+ $result['totalVisits'] = 0;
+ $result['totalVisitDuration'] = 0;
+ $result['totalActionCount'] = 0;
+ $result['totalGoalConversions'] = 0;
+ $result['totalEcommerceConversions'] = 0;
+ $result['totalEcommerceRevenue'] = 0;
+ $result['totalEcommerceItems'] = 0;
+ $result['totalAbandonedCarts'] = 0;
+ $result['totalAbandonedCartsRevenue'] = 0;
+ $result['totalAbandonedCartsItems'] = 0;
+ foreach ($visits->getRows() as $visit) {
+ ++$result['totalVisits'];
+
+ $result['totalVisitDuration'] += $visit->getColumn('visitDuration');
+ $result['totalActionCount'] += $visit->getColumn('actions');
+ $result['totalGoalConversions'] += $visit->getColumn('goalConversions');
+
+ // individual goal conversions are stored in action details
+ foreach ($visit->getColumn('actionDetails') as $action) {
+ if ($action['type'] == 'goal') { // handle goal conversion
+ $idGoal = $action['goalId'];
+
+ if (!isset($result['totalConversionsByGoal'][$idGoal])) {
+ $result['totalConversionsByGoal'][$idGoal] = 0;
+ }
+ ++$result['totalConversionsByGoal'][$idGoal];
+
+ if (!empty($action['revenue'])) {
+ if (!isset($result['totalRevenueByGoal'][$idGoal])) {
+ $result['totalRevenueByGoal'][$idGoal] = 0;
+ }
+ $result['totalRevenueByGoal'][$idGoal] += $action['revenue'];
+ }
+ } else if ($action['type'] == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER) { // handle ecommerce order
+ ++$result['totalEcommerceConversions'];
+ $result['totalEcommerceRevenue'] += $action['revenue'];
+ $result['totalEcommerceItems'] += $action['items'];
+ } else if ($action['type'] == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART) { // handler abandoned cart
+ ++$result['totalAbandonedCarts'];
+ $result['totalAbandonedCartsRevenue'] += $action['revenue'];
+ $result['totalAbandonedCartsItems'] += $action['items'];
+ }
+ }
+ }
+
+ $result['totalVisitDurationPretty'] = Piwik::getPrettyTimeFromSeconds($result['totalVisitDuration']);
+
+ // use requested visits for first/last visit info
+ $result['firstVisit'] = $this->getVisitorProfileVisitSummary(end($visits->getRows()));
+ $result['lastVisit'] = $this->getVisitorProfileVisitSummary(reset($visits->getRows()));
+
+ // use N most recent visits for last_visits
+ $visits->deleteRowsOffset(self::VISITOR_PROFILE_MAX_VISITS_TO_SHOW);
+ $result['lastVisits'] = $visits;
+
+ // use the right date format for the pretty server date
+ $timezone = Site::getTimezoneFor($idSite);
+ foreach ($result['lastVisits']->getRows() as $visit) {
+ $dateTimeVisitFirstAction = Date::factory($visit->getColumn('firstActionTimestamp'), $timezone);
+ $dateTimePretty = $dateTimeVisitFirstAction->getLocalized(self::VISITOR_PROFILE_DATE_FORMAT);
+
+ $visit->setColumn('serverDatePrettyFirstAction', $dateTimePretty);
+ }
+
+ return $result;
+ }
+
+ /**
+ * Returns a summary for an important visit. Used to describe the first & last visits of a visitor.
+ *
+ * @param Piwik\DataTable\Row $visit
+ */
+ private function getVisitorProfileVisitSummary($visit)
+ {
+ $today = Date::today();
+
+ $serverDate = $visit->getColumn('serverDate');
+ return array(
+ 'date' => $serverDate,
+ 'prettyDate' => Date::factory($serverDate)->getLocalized(self::VISITOR_PROFILE_DATE_FORMAT),
+ 'daysAgo' => (int)Date::secondsToDays($today->getTimestamp() - Date::factory($serverDate)->getTimestamp()),
+ 'referralSummary' => $this->getReferrerSummaryForVisit($visit),
+ );
+ }
+
+ /**
+ * Returns a summary for a visit's referral.
+ *
+ * @param Piwik\DataTable\Row $visit
+ */
+ private function getReferrerSummaryForVisit($visit)
+ {
+ $referrerType = $visit->getColumn('referrerType');
+ if ($referrerType === false
+ || $referrerType == 'direct'
+ ) {
+ $result = Piwik_Translate('Referers_DirectEntry');
+ } else if ($referrerType == 'search') {
+ $result = $visit->getColumn('referrerName');
+
+ $keyword = $visit->getColumn('referrerKeyword');
+ if ($keyword !== false) {
+ $result .= ' (' . $keyword . ')';
+ }
+ } else if ($referrerType == 'campaign') {
+ $result = Piwik_Translate('Referers_ColumnCampaign') . ' (' . $visit->getColumn('referrerName') . ')';
+ } else {
+ $result = $visit->getColumn('referrerName');
+ }
+
+ return $result;
+ }
+
/**
* @deprecated
*/
diff --git a/plugins/Live/Controller.php b/plugins/Live/Controller.php
index 3e708d4d79..f1ee8bda23 100644
--- a/plugins/Live/Controller.php
+++ b/plugins/Live/Controller.php
@@ -99,6 +99,7 @@ class Piwik_Live_Controller extends Controller
*/
public function getVisitorLog($fetch = false)
{
+ $test = array(); $str = (string)$test;
return $this->getLastVisitsDetails($fetch);
}
@@ -130,4 +131,18 @@ class Piwik_Live_Controller extends Controller
$view->pisToday = $today['actions'];
return $view;
}
+
+ /**
+ * TODO
+ */
+ public function getVisitorProfilePopup()
+ {
+ $idSite = Common::getRequestVar('idSite', null, 'int');
+
+ $view = new View('@Live/getVisitorProfilePopup.twig');
+ $view->idSite = $idSite;
+ $view->goals = Piwik_Goals_API::getInstance()->getGoals($idSite);
+ $view->visitorData = Request::processRequest('Live.getVisitorProfile');
+ echo $view->render();
+ }
} \ No newline at end of file
diff --git a/plugins/Live/Live.php b/plugins/Live/Live.php
index e4c15c1ed7..54820cd836 100644
--- a/plugins/Live/Live.php
+++ b/plugins/Live/Live.php
@@ -35,6 +35,7 @@ class Piwik_Live extends Plugin
public function getCssFiles(&$cssFiles)
{
$cssFiles[] = "plugins/Live/stylesheets/live.less";
+ $cssFiles[] = "plugins/Live/stylesheets/visitor_profile.less";
}
public function getJsFiles(&$jsFiles)
@@ -89,4 +90,4 @@ class Piwik_Live extends Plugin
)
);
}
-}
+} \ No newline at end of file
diff --git a/plugins/Live/images/REMOVE_ME_avatar.jpg b/plugins/Live/images/REMOVE_ME_avatar.jpg
new file mode 100644
index 0000000000..dfd7ec81de
--- /dev/null
+++ b/plugins/Live/images/REMOVE_ME_avatar.jpg
Binary files differ
diff --git a/plugins/Live/images/REMOVE_ME_chart.png b/plugins/Live/images/REMOVE_ME_chart.png
new file mode 100644
index 0000000000..5f8f03ad6a
--- /dev/null
+++ b/plugins/Live/images/REMOVE_ME_chart.png
Binary files differ
diff --git a/plugins/Live/images/REMOVE_ME_map.jpg b/plugins/Live/images/REMOVE_ME_map.jpg
new file mode 100644
index 0000000000..ffae900c21
--- /dev/null
+++ b/plugins/Live/images/REMOVE_ME_map.jpg
Binary files differ
diff --git a/plugins/Live/images/avatar_frame.png b/plugins/Live/images/avatar_frame.png
new file mode 100644
index 0000000000..23eccfd5fb
--- /dev/null
+++ b/plugins/Live/images/avatar_frame.png
Binary files differ
diff --git a/plugins/Live/images/paperclip.png b/plugins/Live/images/paperclip.png
new file mode 100644
index 0000000000..b38d33caa1
--- /dev/null
+++ b/plugins/Live/images/paperclip.png
Binary files differ
diff --git a/plugins/Live/images/visitor_profile_background.jpg b/plugins/Live/images/visitor_profile_background.jpg
new file mode 100644
index 0000000000..082d637dcf
--- /dev/null
+++ b/plugins/Live/images/visitor_profile_background.jpg
Binary files differ
diff --git a/plugins/SegmentEditor/images/down_arrow.png b/plugins/Live/images/visitor_profile_close.png
index a364892c7d..ae132b7b2c 100644
--- a/plugins/SegmentEditor/images/down_arrow.png
+++ b/plugins/Live/images/visitor_profile_close.png
Binary files differ
diff --git a/plugins/SegmentEditor/images/slide.png b/plugins/Live/images/visitor_profile_gradient.png
index 657b9a6de5..ac5068b54d 100644
--- a/plugins/SegmentEditor/images/slide.png
+++ b/plugins/Live/images/visitor_profile_gradient.png
Binary files differ
diff --git a/plugins/Live/stylesheets/visitor_profile.less b/plugins/Live/stylesheets/visitor_profile.less
new file mode 100644
index 0000000000..4b34c32698
--- /dev/null
+++ b/plugins/Live/stylesheets/visitor_profile.less
@@ -0,0 +1,365 @@
+.visitor-profile {
+ position:relative;
+ width:1149px;
+ height:758px;
+ border:1px solid #a19e96;
+ border-radius:5px;
+ background:url(../images/visitor_profile_background.jpg) repeat;
+ box-shadow:5px 5px 5px rgba(0,0,0,0.22);
+
+ h1 {
+ font-size:18px;
+ color:#7e7363;
+ text-shadow:0 1px 0 rgba(255,255,255,1);
+ margin:9px 0 0 0;
+ padding:0;
+
+ a {
+ font-size:12px;
+ margin-left:3px;
+ }
+ }
+
+ span, strong {
+ display:inline-block;
+ font-size:14px;
+ color:#5e5e5c;
+ line-height:19px;
+ padding-left:4px;
+ }
+
+ p {
+ font-size:13px;
+ color:#5e5e5c;
+ line-height:20px;
+ }
+
+ h2 {
+ display:inline-block;
+ font-size:14px;
+ margin:0 0 0 5px;
+ padding:0;
+ font-weight:bold;
+ color:black;
+ }
+
+ // TODO: iOS icon looks better in mockup
+ // TODO: remove temporary images
+}
+
+.visitor-profile-close {
+ position:absolute;
+ right:-17px;
+ top:-16px;
+ height:35px;
+ width:35px;
+ background:url(../images/visitor_profile_close.png) no-repeat;
+}
+
+.visitor-profile a {
+ text-decoration:none;
+ color:#255792;
+}
+
+.visitor-profile > div {
+ width:100%;
+}
+
+.visitor-profile-info {
+ height:705px;
+ border-top:2px solid #f6f6f6;
+ border-bottom:1px solid #d1cec8;
+ border-radius:5px 5px 0 0;
+ box-shadow:inset 0 25px 15px -10px #e0e0e0, inset 0 -25px 15px -10px #e0e0e0;
+
+ > div {
+ width:573px;
+ height:100%;
+ float:left;
+ border-left:1px solid #d1cec8;
+
+ > div {
+ border-bottom:1px solid #d1cec8;
+ }
+ }
+
+ > div:first-child {
+ border-left:none;
+ }
+
+ > div:last-child {
+ border-bottom:none;
+ }
+}
+
+.visitor-profile-avatar > div {
+ position:relative;
+ float:left;
+ height:145px;
+ margin-right:15px;
+ padding:12px 0 13px;
+}
+
+.visitor-profile-avatar > div:first-child {
+ width:166px;
+ margin-right:0;
+ padding-left:16px;
+
+ > .visitor-profile-image-frame {
+ width:149px;
+ height:154px;
+ background:url(../images/avatar_frame.png) no-repeat;
+
+ > img { // avatar image
+ width:122px;
+ height:120px;
+ margin:11px 0 0 12px;
+ }
+ }
+
+ > img { // paperclip image
+ position:absolute;
+ top:-8px;
+ left:3px;
+ z-index:2;
+ }
+}
+
+.visitor-profile-avatar > div:last-child {
+ margin-right:0;
+}
+
+.visitor-profile-more-info {
+ height:18px;
+ border-top:1px solid #fff;
+ border-radius:0 0 5px 5px;
+ text-align:center;
+ padding:20px 0 13px;
+
+ > a {
+ font-size:14px;
+ text-decoration:none;
+ color:#255792;
+ text-shadow:0 1px 0 rgba(255,255,255,1);
+ }
+}
+
+.visitor-profile-latest-visit-column {
+ padding-top:6px;
+ display:inline-block;
+ vertical-align:top;
+}
+
+.visitor-profile-browser {
+ width:75px;
+ display:inline-block;
+}
+
+.visitor-profile-os {
+ width:75px;
+ display:inline-block;
+}
+
+.visitor-profile-latest-visit-column:first-child {
+ margin-right:9px;
+}
+
+.visitor-profile-avatar ul {
+ width:178px;
+}
+
+.visitor-profile-avatar ul li {
+ display:inline-block;
+ height:24px;
+ border-bottom:1px solid #d1cec8;
+ width:100%;
+}
+
+.visitor-profile-avatar ul li:last-child {
+ border-bottom:none;
+}
+
+.visitor-profile-avatar ul li:first-child {
+ border-bottom:1px solid #d1cec8; // make sure there is a border if only one item is shown in the list
+}
+
+.visitor-profile-map {
+ padding:19px 0 18px 19px;
+}
+
+.visitor-profile-map * {
+ border-radius:2px;
+ background-color:#fff;
+ width:532px;
+ height:243px;
+ padding:2px;
+}
+
+.visitor-profile-summary,.visitor-profile-important-visits {
+ overflow:hidden;
+ height:116px;
+ padding:5px 0 0 22px;
+}
+
+.visitor-profile-summary > div {
+ margin-top:6px;
+}
+
+.visitor-profile-important-visits {
+
+ > div {
+ float:left;
+ width:265px;
+ height:100%;
+
+ > div {
+ margin-top:13px;
+ }
+ }
+
+ span {
+ padding-left:0;
+ }
+}
+
+.visitor-profile-location {
+ padding:10px 0 4px 19px;
+
+ img {
+ margin-top:-12px;
+ }
+}
+
+.visitor-profile-pages-visited {
+ height:42px;
+ overflow-y:auto;
+ position:relative;
+ margin-right:10px;
+ border-bottom:none!important;
+ padding:8px 18px 10px 13px;
+
+ h1 {
+ margin-left:6px;
+ }
+}
+
+.visitor-profile-actions {
+ height:460px;
+ overflow-y:auto;
+ position:relative;
+ margin-right:10px;
+ border-bottom:none!important;
+ padding:0 18px 0 13px;
+
+ ol {
+ counter-reset:item;
+ list-style-type:none;
+
+ > li {
+ display:block;
+ font-size:12px;
+ font-weight:700;
+ line-height:25px;
+ padding:0 0 10px 13px;
+
+ span {
+ font-size:13px;
+ font-weight:700;
+ line-height:25px;
+ padding-left:0;
+ }
+ }
+
+ > li:before {
+ content:counter(item) " ";
+ counter-increment:item;
+ }
+ }
+
+ // TODO: unordered lists no longer used, remove
+ ol li ul,ol li ol {
+ border-top:1px solid #d1cec8;
+ }
+
+ ol li ul {
+ padding-left:15px;
+ }
+
+ ol > li > ol > li {
+ margin-left:-12px;
+ }
+
+ ol li ul li,ol li ol li {
+ display:block;
+ color:#5e5e5c;
+ font-size:13px;
+ line-height:22px;
+ padding-top:1px;
+ padding-bottom:1px;
+ }
+
+ ol li ol li {
+ padding-bottom:4px;
+ }
+
+ ol li ul li a,ol li ol li a {
+ display:inline-block;
+ }
+
+ ol > li ol li span {
+ padding-left:4px;
+ }
+
+ ol > li ol li .action-list-url {
+ margin-left:15px;
+ line-height:14px;
+ display:inline-block;
+ }
+
+ ol > li ol li img {
+ margin-left:7px;
+ }
+
+ // overrides for _actionsDetails styles
+ strong {
+ font-size:13px;
+ line-height:25px;
+ }
+}
+
+.visitor-profile-date {
+ float:right;
+ font-size:13px;
+ line-height:26px;
+}
+
+.visitor-profile-fog {
+ height:25px;
+ width:546px;
+ position:absolute;
+ bottom:51px;
+ right:28px;
+ background:url(../images/visitor_profile_gradient.png) repeat-x;
+}
+
+// popup css
+.visitor-profile-popup {
+ width: 1151px;
+ height: auto;
+ padding: 0;
+
+ > .ui-dialog-titlebar {
+ display: none;
+ }
+
+ > #Piwik_Popover {
+ padding: 0;
+ margin: 0;
+ overflow: visible;
+ }
+}
+
+.visitor-profile-goal-name {
+ font-weight:bold;
+ font-style:italic;
+} \ No newline at end of file
diff --git a/plugins/Live/templates/_actionsList.twig b/plugins/Live/templates/_actionsList.twig
new file mode 100644
index 0000000000..9f5bc672e4
--- /dev/null
+++ b/plugins/Live/templates/_actionsList.twig
@@ -0,0 +1,106 @@
+{% set visitorHasSomeEcommerceActivity %}0{% endset %}
+{% for action in actionDetails %}
+ {% set customVariablesTooltip %}
+ {% if action.customVariables is defined %}
+ {{ 'CustomVariables_CustomVariables'|translate }}
+ {% for id,customVariable in action.customVariables %}
+ {% set name = 'customVariablePageName' ~ id %}
+ {% set value = 'customVariablePageValue' ~ id %}
+ - {{ customVariable[name]|raw }} {% if customVariable[value]|length > 0 %} = {{ customVariable[value]|raw }}{% endif %}
+ {% endfor %}
+ {% endif %}
+ {% endset %}
+ {% if not javascriptVariablesToSet.filterEcommerce or action.type == 'ecommerceOrder' or action.type == 'ecommerceAbandonedCart' %}
+ <li class="{% if action.goalName is defined %}goal{% else %}action{% endif %}"
+ title="{{ action.serverTimePretty }}{% if action.url is defined and action.url|trim|length %}
+ {{ action.url }}{% endif %} {% if customVariablesTooltip|trim|length %}
+
+ {{ customVariablesTooltip|trim }}{% endif %}{% if action.timeSpentPretty is defined %}
+
+ {{ 'General_TimeOnPage'|translate }}: {{ action.timeSpentPretty|raw }}{% endif %}{% if action.generationTime is defined %}
+
+ {{ 'General_ColumnGenerationTime'|translate }}: {{ action.generationTime|raw }}{% endif %}">
+ {% if action.type == 'ecommerceOrder' or action.type == 'ecommerceAbandonedCart' %}
+ {# Ecommerce Abandoned Cart / Ecommerce Order #}
+ <img src="{{ action.icon }}"/>
+ {% if action.type == 'ecommerceOrder' %}
+ {% set visitorHasSomeEcommerceActivity %}1{% endset %}
+ <strong>{{ 'Goals_EcommerceOrder'|translate }}</strong>
+ <span style='color:#666666'>({{ action.orderId }})</span>
+ {% else %}
+ <strong>{{'Goals_AbandonedCart'|translate}}</strong>
+
+ {# TODO: would be nice to have the icons Orders / Cart in the ecommerce log footer #}
+ {% if javascriptVariablesToSet.filterEcommerce == 2 %}
+ {% set visitorHasSomeEcommerceActivity %}1{% endset %}
+ {% endif %}
+ {% endif %}
+ <br/>
+ <span {% if not isWidget %}style='margin-left:20px'{% endif %}>
+ {% if action.type == 'ecommerceOrder' %}
+ <abbr title="
+ {{ 'Live_GoalRevenue'|translate }}: {{ action.revenue|money(javascriptVariablesToSet.idSite)|raw }}
+ {% if action.revenueSubTotal is not empty %} - {{ 'General_Subtotal'|translate }}: {{ action.revenueSubTotal|money(javascriptVariablesToSet.idSite)|raw }}{% endif %}
+ {% if action.revenueTax is not empty %} - {{ 'General_Tax'|translate }}: {{ action.revenueTax|money(javascriptVariablesToSet.idSite)|raw }}{% endif %}
+ {% if action.revenueShipping is not empty %} - {{ 'General_Shipping'|translate }}: {{ action.revenueShipping|money(javascriptVariablesToSet.idSite)|raw }}{% endif %}
+ {% if action.revenueDiscount is not empty %} - {{ 'General_Discount'|translate }}: {{ action.revenueDiscount|money(javascriptVariablesToSet.idSite)|raw }}{% endif %}
+ ">{{ 'Live_GoalRevenue'|translate }}:
+ {% else %}
+ {% set revenueLeft %}{{ 'Live_GoalRevenue'|translate }}{% endset %}
+ {{ 'Goals_LeftInCart'|translate(revenueLeft) }}:
+ {% endif %}
+ <strong>{{ action.revenue|money(javascriptVariablesToSet.idSite)|raw }}</strong>
+ {% if action.type == 'ecommerceOrder' %}
+ </abbr>
+ {% endif %}, {{ 'General_Quantity'|translate }}: {{ action.items }}
+
+ {# Ecommerce items in Cart/Order #}
+ {% if action.itemDetails is not empty %}
+ <ul style='list-style:square;margin-left:{% if isWidget %}15{% else %}50{% endif %}px'>
+ {% for product in action.itemDetails %}
+ <li>
+ {{ product.itemSKU }}{% if product.itemName is not empty %}: {{ product.itemName }}{% endif %}
+ {% if product.itemCategory is not empty %} ({{ product.itemCategory }}){% endif %}
+ ,
+ {{ 'General_Quantity'|translate }}: {{ product.quantity }},
+ {{ 'General_Price'|translate }}: {{ product.price|money(javascriptVariablesToSet.idSite)|raw }}
+ </li>
+ {% endfor %}
+ </ul>
+ {% endif %}
+ </span>
+ {% elseif action.goalName is not defined%}
+ {# Page view / Download / Outlink #}
+ {% if action.pageTitle is defined and action.pageTitle is not empty %}
+ <span>{{ action.pageTitle|truncate(80) }}</span>
+ {% endif %}
+ {% if action.siteSearchKeyword is defined %}
+ {% if action.type == 'search' %}
+ <img src='{{ action.icon }}' title='{{ 'Actions_SubmenuSitesearch'|translate }}'>
+ {% endif %}
+ {{ action.siteSearchKeyword|truncate(80) }}
+ {% endif %}
+ {% if action.url is not empty %}
+ {% if action.type == 'action' and action.pageTitle is not empty %}<br/>{% endif %}
+ {% if action.type == 'download' or action.type == 'outlink' %}
+ <img src='{{ action.icon }}'>
+ {% endif %}
+ <a href="{{ action.url }}" target="_blank" class="action-list-url"
+ {% if overrideLinkStyle is not defined or overrideLinkStyle %}style="{% if action.type=='action' and action.pageTitle is not empty %}margin-left: 25px;{% endif %}text-decoration:underline;"{% endif %}>
+ {{ action.url|truncate(80) }}
+ </a>
+ {% elseif action.type != 'search' %}
+ <br/>
+ <span style="margin-left: 25px;">{{ javascriptVariablesToSet.pageUrlNotDefined }}</span>
+ {% endif %}
+ {% else %}
+ {# Goal conversion #}
+ <img src="{{ action.icon }}" />
+ <strong>{{ action.goalName }}</strong>
+ {% if action.revenue > 0 %}, {{ 'Live_GoalRevenue'|translate }}:
+ <strong>{{ action.revenue|money(javascriptVariablesToSet.idSite)|raw }}</strong>
+ {% endif %}
+ {% endif %}
+ </li>
+ {% endif %}
+{% endfor %} \ No newline at end of file
diff --git a/plugins/Live/templates/getVisitorLog.twig b/plugins/Live/templates/getVisitorLog.twig
index 953528ac2f..211d1d0cb3 100644
--- a/plugins/Live/templates/getVisitorLog.twig
+++ b/plugins/Live/templates/getVisitorLog.twig
@@ -187,112 +187,7 @@
</strong>
<br/>
<ol class='visitorLog'>
- {% set visitorHasSomeEcommerceActivity %}0{% endset %}
- {% for action in visitor.getColumn('actionDetails') %}
- {% set customVariablesTooltip %}
- {% if action.customVariables is defined %}
- {{ 'CustomVariables_CustomVariables'|translate }}
- {% for id,customVariable in action.customVariables %}
- {% set name = 'customVariablePageName' ~ id %}
- {% set value = 'customVariablePageValue' ~ id %}
- - {{ customVariable[name]|raw }} {% if customVariable[value]|length > 0 %} = {{ customVariable[value]|raw }}{% endif %}
- {% endfor %}
- {% endif %}
- {% endset %}
- {% if not javascriptVariablesToSet.filterEcommerce or action.type == 'ecommerceOrder' or action.type == 'ecommerceAbandonedCart' %}
- <li class="{% if action.goalName is defined %}goal{% else %}action{% endif %}"
- title="{{ action.serverTimePretty }}{% if action.url is defined and action.url|trim|length %}
- {{ action.url }}{% endif %} {% if customVariablesTooltip|trim|length %}
-
- {{ customVariablesTooltip|trim }}{% endif %}{% if action.timeSpentPretty is defined %}
-
- {{ 'General_TimeOnPage'|translate }}: {{ action.timeSpentPretty|raw }}{% endif %}{% if action.generationTime is defined %}
-
- {{ 'General_ColumnGenerationTime'|translate }}: {{ action.generationTime|raw }}{% endif %}">
- {% if action.type == 'ecommerceOrder' or action.type == 'ecommerceAbandonedCart' %}
- {# Ecommerce Abandoned Cart / Ecommerce Order #}
- <img src="{{ action.icon }}"/>
- {% if action.type == 'ecommerceOrder' %}
- {% set visitorHasSomeEcommerceActivity %}1{% endset %}
- <strong>{{ 'Goals_EcommerceOrder'|translate }}</strong>
- <span style='color:#666666'>({{ action.orderId }})</span>
- {% else %}
- <strong>{{'Goals_AbandonedCart'|translate}}</strong>
-
- {# TODO: would be nice to have the icons Orders / Cart in the ecommerce log footer #}
- {% if javascriptVariablesToSet.filterEcommerce == 2 %}
- {% set visitorHasSomeEcommerceActivity %}1{% endset %}
- {% endif %}
- {% endif %}
- <br/>
- <span {% if not isWidget %}style='margin-left:20px'{% endif %}>
- {% if action.type == 'ecommerceOrder' %}
- <abbr title="
- {{ 'Live_GoalRevenue'|translate }}: {{ action.revenue|money(javascriptVariablesToSet.idSite)|raw }}
- {% if action.revenueSubTotal is not empty %} - {{ 'General_Subtotal'|translate }}: {{ action.revenueSubTotal|money(javascriptVariablesToSet.idSite)|raw }}{% endif %}
- {% if action.revenueTax is not empty %} - {{ 'General_Tax'|translate }}: {{ action.revenueTax|money(javascriptVariablesToSet.idSite)|raw }}{% endif %}
- {% if action.revenueShipping is not empty %} - {{ 'General_Shipping'|translate }}: {{ action.revenueShipping|money(javascriptVariablesToSet.idSite)|raw }}{% endif %}
- {% if action.revenueDiscount is not empty %} - {{ 'General_Discount'|translate }}: {{ action.revenueDiscount|money(javascriptVariablesToSet.idSite)|raw }}{% endif %}
- ">{{ 'Live_GoalRevenue'|translate }}:
- {% else %}
- {% set revenueLeft %}{{ 'Live_GoalRevenue'|translate }}{% endset %}
- {{ 'Goals_LeftInCart'|translate(revenueLeft) }}:
- {% endif %}
- <strong>{{ action.revenue|money(javascriptVariablesToSet.idSite)|raw }}</strong>
- {% if action.type == 'ecommerceOrder' %}
- </abbr>
- {% endif %}, {{ 'General_Quantity'|translate }}: {{ action.items }}
-
- {# Ecommerce items in Cart/Order #}
- {% if action.itemDetails is not empty %}
- <ul style='list-style:square;margin-left:{% if isWidget %}15{% else %}50{% endif %}px'>
- {% for product in action.itemDetails %}
- <li>
- {{ product.itemSKU }}{% if product.itemName is not empty %}: {{ product.itemName }}{% endif %}
- {% if product.itemCategory is not empty %} ({{ product.itemCategory }}){% endif %}
- ,
- {{ 'General_Quantity'|translate }}: {{ product.quantity }},
- {{ 'General_Price'|translate }}: {{ product.price|money(javascriptVariablesToSet.idSite)|raw }}
- </li>
- {% endfor %}
- </ul>
- {% endif %}
- </span>
- {% elseif action.goalName is not defined%}
- {# Page view / Download / Outlink #}
- {% if action.pageTitle is defined %}
- {{ action.pageTitle|truncate(80) }}
- {% endif %}
- {% if action.siteSearchKeyword is defined %}
- {% if action.type == 'search' %}
- <img src='{{ action.icon }}' title='{{ 'Actions_SubmenuSitesearch'|translate }}'>
- {% endif %}
- {{ action.siteSearchKeyword|truncate(80) }}
- {% endif %}
- {% if action.url is not empty %}
- {% if action.type == 'action' and action.pageTitle is not empty %}<br/>{% endif %}
- {% if action.type == 'download' or action.type == 'outlink' %}
- <img src='{{ action.icon }}'>
- {% endif %}
- <a href="{{ action.url }}" target="_blank"
- style="{% if action.type=='action' and action.pageTitle is not empty %}margin-left: 25px;{% endif %}text-decoration:underline;">
- {{ action.url|truncate(80) }}
- </a>
- {% elseif action.type != 'search' %}
- <br/>
- <span style="margin-left: 25px;">{{ javascriptVariablesToSet.pageUrlNotDefined }}</span>
- {% endif %}
- {% else %}
- {# Goal conversion #}
- <img src="{{ action.icon }}" />
- <strong>{{ action.goalName }}</strong>
- {% if action.revenue > 0 %}, {{ 'Live_GoalRevenue'|translate }}:
- <strong>{{ action.revenue|money(javascriptVariablesToSet.idSite)|raw }}</strong>
- {% endif %}
- {% endif %}
- </li>
- {% endif %}
- {% endfor %}
+ {% include "@Live/_actionsList.twig" with {'actionDetails': visitor.getColumn('actionDetails')} %}
</ol>
</td>
</tr>
@@ -317,8 +212,8 @@
var visitorLogTitle = '{{ 'Live_VisitorLog'|translate|e('js') }}';
function Piwik_Live_LoadVisitorPopover(visitorId) {
var startingDate = piwik.minDateYear + '-01-01';
- var url = 'module=Live&action=getVisitorLog&period=range&date=' + startingDate + ',today&show_footer=0&segment=visitorId' + encodeURIComponent('==') + visitorId;
- return Piwik_Popover.createPopupAndLoadUrl(url, visitorLogTitle);
+ var url = 'module=Live&action=getVisitorProfilePopup&period=range&date=' + startingDate + ',today&idVisitor=' + encodeURIComponent(visitorId);
+ return Piwik_Popover.createPopupAndLoadUrl(url, visitorLogTitle, 'visitor-profile-popup');
}
$(document).ready(function () {
diff --git a/plugins/Live/templates/getVisitorProfilePopup.twig b/plugins/Live/templates/getVisitorProfilePopup.twig
new file mode 100644
index 0000000000..8fe3ef39e2
--- /dev/null
+++ b/plugins/Live/templates/getVisitorProfilePopup.twig
@@ -0,0 +1,121 @@
+<div class="visitor-profile">
+ <a href class="visitor-profile-close"></a>
+ <div class="visitor-profile-info">
+ <div>
+ <div class="visitor-profile-avatar">
+ <div>
+ <div class="visitor-profile-image-frame"><!-- TODO translate -->
+ <img src="plugins/Live/images/REMOVE_ME_avatar.jpg" alt=""/>
+ </div>
+ <img src="plugins/Live/images/paperclip.png" alt=""/>
+ </div>
+ <div>
+ <h1>Visitor profile</h1>
+ <div>
+ <div class="visitor-profile-latest-visit-column">
+ <ul>
+ <li><span>IP</span><strong>{{ visitorData.latestVisitIp }}</strong></li>
+ <li><span>ID</span><strong>{{ visitorData.visitorId }}</strong></li>
+ <li>
+ <div class="visitor-profile-browser">
+ <img src="{{ visitorData.browserLogo }}"/><span>{{ visitorData.browserName }}</span>
+ </div>
+ <div class="visitor-profile-os">
+ <img src="{{ visitorData.operatingSystemLogo }}"/><span>{{ visitorData.operatingSystemShortName }}</span>
+ </div>
+ </li>
+ <li><span>Resolution</span><strong>{{ visitorData.resolution }}</strong></li>
+ </ul>
+ </div>
+ <div class="visitor-profile-latest-visit-column">
+ <ul>
+ {% for id,customVariable in visitorData.customVariables %}
+ {% if loop.index0 < 4 %}
+ {% set name='customVariableName' ~ id %}
+ {% set value='customVariableValue' ~ id %}
+ <li><span>{{ customVariable[name]|truncate(30) }}</span>{% if customVariable[value]|length > 0 %}<strong>{{ customVariable[value]|truncate(50) }}</strong>{% endif %}</li>
+ {% endif %}
+ {% endfor %}
+ {# TODO: Other custom vars go in expanding div. #}
+ </ul>
+ </div>
+ </div>
+ </div>
+ <p style="clear:both; border:none!important;"></p>
+ </div>
+ <div style="clear:both; border:none!important;"></div>
+ <div class="visitor-profile-map">
+ <img alt="" src="plugins/Live/images/REMOVE_ME_map.jpg"/> {# TODO: map #}
+ </div>
+ <div class="visitor-profile-important-visits">
+ <div>
+ <h1>First visit</h1>
+ <div>
+ <p><strong>{{ visitorData.firstVisit.prettyDate }}</strong><span> - {{ visitorData.firstVisit.daysAgo }} days ago</span></p>
+ <p><span>from:</span></p>
+ <p><strong>{{ visitorData.firstVisit.referralSummary }}</strong></p>
+ </div>
+ </div>
+ <div>
+ <h1>Last visit</h1>
+ <div>
+ <p><strong>{{ visitorData.lastVisit.prettyDate }}</strong><span> - {{ visitorData.lastVisit.daysAgo }} days ago</span></p>
+ <p><span>from:</span></p>
+ <p><strong>{{ visitorData.lastVisit.referralSummary }}</strong></p>
+ </div>
+ </div>
+ </div>
+ <div class="visitor-profile-summary">
+ <h1>Summary</h1>
+ <div>
+ <p>Spent a total of <strong>{{ visitorData.totalVisitDurationPretty|raw }} on the website</strong>, and <strong>viewed {{ visitorData.totalActionCount }} pages in {{ visitorData.totalVisits }} visits.</strong></p>
+ <p><strong>Converted {{ visitorData.totalGoalConversions }} Goals</strong> (
+ {%- for idGoal, totalConversions in visitorData.totalConversionsByGoal -%}
+ {%- if not loop.first %}, {% endif -%}{{- totalConversions }} <span class="visitor-profile-goal-name">{{ goals[idGoal]['name'] -}}</span>
+ {%- endfor -%}
+ ).</p>
+ <p>Ecommerce: <strong>{{ visitorData.totalEcommerceConversions }} orders for a total of {{ visitorData.totalEcommerceRevenue|money(idSite)|raw }}</strong>, purchased {{ visitorData.totalEcommerceItems }} items.</p>
+ </div>
+ </div>
+ </div>
+ <div>
+ <div class="visitor-profile-location">
+ <h1>Location</h1>
+ <img src="plugins/Live/images/REMOVE_ME_chart.png" alt=""/> {# TODO: country & bar graph #}
+ </div>
+ <div class="visitor-profile-pages-visited">
+ <h1>Visited pages<a href>see all</a></h1>
+ </div>
+ <div class="visitor-profile-actions">
+ <ol>
+ {% for visitInfo in visitorData.lastVisits.getRows() %}
+ <li><h2>Visit</h2><span class="visitor-profile-date">{{ visitInfo.getColumn('serverDatePrettyFirstAction') }}</span>
+ <ol>
+ {% include "@Live/_actionsList.twig" with {'actionDetails': visitInfo.getColumn('actionDetails'),
+ 'javascriptVariablesToSet': {
+ 'filterEcommerce': false,
+ 'idSite': idSite
+ },
+ 'overrideLinkStyle': false} %}
+ </ol>
+ </li>
+ {% endfor %}
+ </ol>
+ <br/>
+ </div>
+ <div class="visitor-profile-fog"></div>
+ </div>
+ </div>
+ <div class="visitor-profile-more-info">
+ <a href="#">View more visitor information</a>
+ </div>
+</div>
+<script type="text/javascript">
+$(function() {
+ $('.visitor-profile-actions').jScrollPane({
+ showArrows: true,
+ verticalArrowPositions: 'os',
+ horizontalArrowPositions: 'os'
+ });
+});
+</script> \ No newline at end of file
diff --git a/plugins/SegmentEditor/SegmentEditor.php b/plugins/SegmentEditor/SegmentEditor.php
index 5d1731c006..48359598a6 100644
--- a/plugins/SegmentEditor/SegmentEditor.php
+++ b/plugins/SegmentEditor/SegmentEditor.php
@@ -97,16 +97,11 @@ class Piwik_SegmentEditor extends Plugin
public function getJsFiles(&$jsFiles)
{
- $jsFiles[] = "plugins/SegmentEditor/javascripts/jquery.jscrollpane.js";
$jsFiles[] = "plugins/SegmentEditor/javascripts/Segmentation.js";
- $jsFiles[] = "plugins/SegmentEditor/javascripts/jquery.mousewheel.js";
- $jsFiles[] = "plugins/SegmentEditor/javascripts/mwheelIntent.js";
}
public function getCssFiles(&$cssFiles)
{
$cssFiles[] = "plugins/SegmentEditor/stylesheets/segmentation.less";
- $cssFiles[] = "plugins/SegmentEditor/stylesheets/jquery.jscrollpane.css";
- $cssFiles[] = "plugins/SegmentEditor/stylesheets/scroll.less";
}
}
diff --git a/plugins/SegmentEditor/images/scroller.png b/plugins/SegmentEditor/images/scroller.png
deleted file mode 100644
index ddcab93426..0000000000
--- a/plugins/SegmentEditor/images/scroller.png
+++ /dev/null
Binary files differ
diff --git a/plugins/SegmentEditor/images/up_arrow.png b/plugins/SegmentEditor/images/up_arrow.png
deleted file mode 100644
index c7cb24c2b4..0000000000
--- a/plugins/SegmentEditor/images/up_arrow.png
+++ /dev/null
Binary files differ
diff --git a/plugins/SegmentEditor/javascripts/jquery.jscrollpane.js b/plugins/SegmentEditor/javascripts/jquery.jscrollpane.js
deleted file mode 100644
index 48d8be8537..0000000000
--- a/plugins/SegmentEditor/javascripts/jquery.jscrollpane.js
+++ /dev/null
@@ -1,1341 +0,0 @@
-/*!
- * jScrollPane - v2.0.0beta12 - 2012-09-27
- * http://jscrollpane.kelvinluck.com/
- *
- * Copyright (c) 2010 Kelvin Luck
- * Dual licensed under the MIT or GPL licenses.
- */
-
-// Script: jScrollPane - cross browser customisable scrollbars
-//
-// *Version: 2.0.0beta12, Last updated: 2012-09-27*
-//
-// Project Home - http://jscrollpane.kelvinluck.com/
-// GitHub - http://github.com/vitch/jScrollPane
-// Source - http://github.com/vitch/jScrollPane/raw/master/script/jquery.jscrollpane.js
-// (Minified) - http://github.com/vitch/jScrollPane/raw/master/script/jquery.jscrollpane.js
-//
-// About: License
-//
-// Copyright (c) 2012 Kelvin Luck
-// Dual licensed under the MIT or GPL Version 2 licenses.
-// http://jscrollpane.kelvinluck.com/MIT-LICENSE.txt
-// http://jscrollpane.kelvinluck.com/GPL-LICENSE.txt
-//
-// About: Examples
-//
-// All examples and demos are available through the jScrollPane example site at:
-// http://jscrollpane.kelvinluck.com/
-//
-// About: Support and Testing
-//
-// This plugin is tested on the browsers below and has been found to work reliably on them. If you run
-// into a problem on one of the supported browsers then please visit the support section on the jScrollPane
-// website (http://jscrollpane.kelvinluck.com/) for more information on getting support. You are also
-// welcome to fork the project on GitHub if you can contribute a fix for a given issue.
-//
-// jQuery Versions - tested in 1.4.2+ - reported to work in 1.3.x
-// Browsers Tested - Firefox 3.6.8, Safari 5, Opera 10.6, Chrome 5.0, IE 6, 7, 8
-//
-// About: Release History
-//
-// 2.0.0beta12 - (2012-09-27) fix for jQuery 1.8+
-// 2.0.0beta11 - (2012-05-14)
-// 2.0.0beta10 - (2011-04-17) cleaner required size calculation, improved keyboard support, stickToBottom/Left, other small fixes
-// 2.0.0beta9 - (2011-01-31) new API methods, bug fixes and correct keyboard support for FF/OSX
-// 2.0.0beta8 - (2011-01-29) touchscreen support, improved keyboard support
-// 2.0.0beta7 - (2011-01-23) scroll speed consistent (thanks Aivo Paas)
-// 2.0.0beta6 - (2010-12-07) scrollToElement horizontal support
-// 2.0.0beta5 - (2010-10-18) jQuery 1.4.3 support, various bug fixes
-// 2.0.0beta4 - (2010-09-17) clickOnTrack support, bug fixes
-// 2.0.0beta3 - (2010-08-27) Horizontal mousewheel, mwheelIntent, keyboard support, bug fixes
-// 2.0.0beta2 - (2010-08-21) Bug fixes
-// 2.0.0beta1 - (2010-08-17) Rewrite to follow modern best practices and enable horizontal scrolling, initially hidden
-// elements and dynamically sized elements.
-// 1.x - (2006-12-31 - 2010-07-31) Initial version, hosted at googlecode, deprecated
-
-(function ($, window, undefined) {
-
- $.fn.jScrollPane = function (settings) {
- // JScrollPane "class" - public methods are available through $('selector').data('jsp')
- function JScrollPane(elem, s) {
- var settings, jsp = this, pane, paneWidth, paneHeight, container, contentWidth, contentHeight,
- percentInViewH, percentInViewV, isScrollableV, isScrollableH, verticalDrag, dragMaxY,
- verticalDragPosition, horizontalDrag, dragMaxX, horizontalDragPosition,
- verticalBar, verticalTrack, scrollbarWidth, verticalTrackHeight, verticalDragHeight, arrowUp, arrowDown,
- horizontalBar, horizontalTrack, horizontalTrackWidth, horizontalDragWidth, arrowLeft, arrowRight,
- reinitialiseInterval, originalPadding, originalPaddingTotalWidth, previousContentWidth,
- wasAtTop = true, wasAtLeft = true, wasAtBottom = false, wasAtRight = false,
- originalElement = elem.clone(false, false).empty(),
- mwEvent = $.fn.mwheelIntent ? 'mwheelIntent.jsp' : 'mousewheel.jsp';
-
- originalPadding = elem.css('paddingTop') + ' ' +
- elem.css('paddingRight') + ' ' +
- elem.css('paddingBottom') + ' ' +
- elem.css('paddingLeft');
- originalPaddingTotalWidth = (parseInt(elem.css('paddingLeft'), 10) || 0) +
- (parseInt(elem.css('paddingRight'), 10) || 0);
-
- function initialise(s) {
-
- var /*firstChild, lastChild, */isMaintainingPositon, lastContentX, lastContentY,
- hasContainingSpaceChanged, originalScrollTop, originalScrollLeft,
- maintainAtBottom = false, maintainAtRight = false;
-
- settings = s;
-
- if (pane === undefined) {
- originalScrollTop = elem.scrollTop();
- originalScrollLeft = elem.scrollLeft();
-
- elem.css(
- {
- overflow: 'hidden',
- padding: 0
- }
- );
- // TODO: Deal with where width/ height is 0 as it probably means the element is hidden and we should
- // come back to it later and check once it is unhidden...
- paneWidth = elem.innerWidth();
- paneHeight = elem.innerHeight();
-
- elem.width(paneWidth);
-
- pane = $('<div class="jspPane" />').css('padding', originalPadding).append(elem.children());
- container = $('<div class="jspContainer" />')
- .css({
- 'width': paneWidth + 'px',
- 'height': paneHeight + 'px'
- }
- ).append(pane).appendTo(elem);
-
- /*
- // Move any margins from the first and last children up to the container so they can still
- // collapse with neighbouring elements as they would before jScrollPane
- firstChild = pane.find(':first-child');
- lastChild = pane.find(':last-child');
- elem.css(
- {
- 'margin-top': firstChild.css('margin-top'),
- 'margin-bottom': lastChild.css('margin-bottom')
- }
- );
- firstChild.css('margin-top', 0);
- lastChild.css('margin-bottom', 0);
- */
- } else {
- elem.css('width', '');
-
- maintainAtBottom = settings.stickToBottom && isCloseToBottom();
- maintainAtRight = settings.stickToRight && isCloseToRight();
-
- hasContainingSpaceChanged = elem.innerWidth() + originalPaddingTotalWidth != paneWidth || elem.outerHeight() != paneHeight;
-
- if (hasContainingSpaceChanged) {
- paneWidth = elem.innerWidth() + originalPaddingTotalWidth;
- paneHeight = elem.innerHeight();
- container.css({
- width: paneWidth + 'px',
- height: paneHeight + 'px'
- });
- }
-
- // If nothing changed since last check...
- if (!hasContainingSpaceChanged && previousContentWidth == contentWidth && pane.outerHeight() == contentHeight) {
- elem.width(paneWidth);
- return;
- }
- previousContentWidth = contentWidth;
-
- pane.css('width', '');
- elem.width(paneWidth);
-
- container.find('>.jspVerticalBar,>.jspHorizontalBar').remove().end();
- }
-
- pane.css('overflow', 'auto');
- if (s.contentWidth) {
- contentWidth = s.contentWidth;
- } else {
- contentWidth = pane[0].scrollWidth;
- }
- contentHeight = pane[0].scrollHeight;
- pane.css('overflow', '');
-
- percentInViewH = contentWidth / paneWidth;
- percentInViewV = contentHeight / paneHeight;
- isScrollableV = percentInViewV > 1;
-
- isScrollableH = percentInViewH > 1;
-
- //console.log(paneWidth, paneHeight, contentWidth, contentHeight, percentInViewH, percentInViewV, isScrollableH, isScrollableV);
-
- if (!(isScrollableH || isScrollableV)) {
- elem.removeClass('jspScrollable');
- pane.css({
- top: 0,
- width: container.width() - originalPaddingTotalWidth
- });
- removeMousewheel();
- removeFocusHandler();
- removeKeyboardNav();
- removeClickOnTrack();
- } else {
- elem.addClass('jspScrollable');
-
- isMaintainingPositon = settings.maintainPosition && (verticalDragPosition || horizontalDragPosition);
- if (isMaintainingPositon) {
- lastContentX = contentPositionX();
- lastContentY = contentPositionY();
- }
-
- initialiseVerticalScroll();
- initialiseHorizontalScroll();
- resizeScrollbars();
-
- if (isMaintainingPositon) {
- scrollToX(maintainAtRight ? (contentWidth - paneWidth ) : lastContentX, false);
- scrollToY(maintainAtBottom ? (contentHeight - paneHeight) : lastContentY, false);
- }
-
- initFocusHandler();
- initMousewheel();
- initTouch();
-
- if (settings.enableKeyboardNavigation) {
- initKeyboardNav();
- }
- if (settings.clickOnTrack) {
- initClickOnTrack();
- }
-
- observeHash();
- if (settings.hijackInternalLinks) {
- hijackInternalLinks();
- }
- }
-
- if (settings.autoReinitialise && !reinitialiseInterval) {
- reinitialiseInterval = setInterval(
- function () {
- initialise(settings);
- },
- settings.autoReinitialiseDelay
- );
- } else if (!settings.autoReinitialise && reinitialiseInterval) {
- clearInterval(reinitialiseInterval);
- }
-
- originalScrollTop && elem.scrollTop(0) && scrollToY(originalScrollTop, false);
- originalScrollLeft && elem.scrollLeft(0) && scrollToX(originalScrollLeft, false);
-
- elem.trigger('jsp-initialised', [isScrollableH || isScrollableV]);
- }
-
- function initialiseVerticalScroll() {
- if (isScrollableV) {
-
- container.append(
- $('<div class="jspVerticalBar" />').append(
- $('<div class="jspCap jspCapTop" />'),
- $('<div class="jspTrack" />').append(
- $('<div class="jspDrag" />').append(
- $('<div class="jspDragTop" />'),
- $('<div class="jspDragBottom" />')
- )
- ),
- $('<div class="jspCap jspCapBottom" />')
- )
- );
-
- verticalBar = container.find('>.jspVerticalBar');
- verticalTrack = verticalBar.find('>.jspTrack');
- verticalDrag = verticalTrack.find('>.jspDrag');
-
- if (settings.showArrows) {
- arrowUp = $('<a class="jspArrow jspArrowUp" />').bind(
- 'mousedown.jsp', getArrowScroll(0, -1)
- ).bind('click.jsp', nil);
- arrowDown = $('<a class="jspArrow jspArrowDown" />').bind(
- 'mousedown.jsp', getArrowScroll(0, 1)
- ).bind('click.jsp', nil);
- if (settings.arrowScrollOnHover) {
- arrowUp.bind('mouseover.jsp', getArrowScroll(0, -1, arrowUp));
- arrowDown.bind('mouseover.jsp', getArrowScroll(0, 1, arrowDown));
- }
-
- appendArrows(verticalTrack, settings.verticalArrowPositions, arrowUp, arrowDown);
- }
-
- verticalTrackHeight = paneHeight;
- container.find('>.jspVerticalBar>.jspCap:visible,>.jspVerticalBar>.jspArrow').each(
- function () {
- verticalTrackHeight -= $(this).outerHeight();
- }
- );
-
-
- verticalDrag.hover(
- function () {
- verticalDrag.addClass('jspHover');
- },
- function () {
- verticalDrag.removeClass('jspHover');
- }
- ).bind(
- 'mousedown.jsp',
- function (e) {
- // Stop IE from allowing text selection
- $('html').bind('dragstart.jsp selectstart.jsp', nil);
-
- verticalDrag.addClass('jspActive');
-
- var startY = e.pageY - verticalDrag.position().top;
-
- $('html').bind(
- 'mousemove.jsp',
- function (e) {
- positionDragY(e.pageY - startY, false);
- }
- ).bind('mouseup.jsp mouseleave.jsp', cancelDrag);
- return false;
- }
- );
- sizeVerticalScrollbar();
- }
- }
-
- function sizeVerticalScrollbar() {
- verticalTrack.height(verticalTrackHeight + 'px');
- verticalDragPosition = 0;
- scrollbarWidth = settings.verticalGutter + verticalTrack.outerWidth();
-
- // Make the pane thinner to allow for the vertical scrollbar
- pane.width(paneWidth - scrollbarWidth - originalPaddingTotalWidth);
-
- // Add margin to the left of the pane if scrollbars are on that side (to position
- // the scrollbar on the left or right set it's left or right property in CSS)
- try {
- if (verticalBar.position().left === 0) {
- pane.css('margin-left', scrollbarWidth + 'px');
- }
- } catch (err) {
- }
- }
-
- function initialiseHorizontalScroll() {
- if (isScrollableH) {
-
- container.append(
- $('<div class="jspHorizontalBar" />').append(
- $('<div class="jspCap jspCapLeft" />'),
- $('<div class="jspTrack" />').append(
- $('<div class="jspDrag" />').append(
- $('<div class="jspDragLeft" />'),
- $('<div class="jspDragRight" />')
- )
- ),
- $('<div class="jspCap jspCapRight" />')
- )
- );
-
- horizontalBar = container.find('>.jspHorizontalBar');
- horizontalTrack = horizontalBar.find('>.jspTrack');
- horizontalDrag = horizontalTrack.find('>.jspDrag');
-
- if (settings.showArrows) {
- arrowLeft = $('<a class="jspArrow jspArrowLeft" />').bind(
- 'mousedown.jsp', getArrowScroll(-1, 0)
- ).bind('click.jsp', nil);
- arrowRight = $('<a class="jspArrow jspArrowRight" />').bind(
- 'mousedown.jsp', getArrowScroll(1, 0)
- ).bind('click.jsp', nil);
- if (settings.arrowScrollOnHover) {
- arrowLeft.bind('mouseover.jsp', getArrowScroll(-1, 0, arrowLeft));
- arrowRight.bind('mouseover.jsp', getArrowScroll(1, 0, arrowRight));
- }
- appendArrows(horizontalTrack, settings.horizontalArrowPositions, arrowLeft, arrowRight);
- }
-
- horizontalDrag.hover(
- function () {
- horizontalDrag.addClass('jspHover');
- },
- function () {
- horizontalDrag.removeClass('jspHover');
- }
- ).bind(
- 'mousedown.jsp',
- function (e) {
- // Stop IE from allowing text selection
- $('html').bind('dragstart.jsp selectstart.jsp', nil);
-
- horizontalDrag.addClass('jspActive');
-
- var startX = e.pageX - horizontalDrag.position().left;
-
- $('html').bind(
- 'mousemove.jsp',
- function (e) {
- positionDragX(e.pageX - startX, false);
- }
- ).bind('mouseup.jsp mouseleave.jsp', cancelDrag);
- return false;
- }
- );
- horizontalTrackWidth = container.innerWidth();
- sizeHorizontalScrollbar();
- }
- }
-
- function sizeHorizontalScrollbar() {
- container.find('>.jspHorizontalBar>.jspCap:visible,>.jspHorizontalBar>.jspArrow').each(
- function () {
- horizontalTrackWidth -= $(this).outerWidth();
- }
- );
-
- horizontalTrack.width(horizontalTrackWidth + 'px');
- horizontalDragPosition = 0;
- }
-
- function resizeScrollbars() {
- if (isScrollableH && isScrollableV) {
- var horizontalTrackHeight = horizontalTrack.outerHeight(),
- verticalTrackWidth = verticalTrack.outerWidth();
- verticalTrackHeight -= horizontalTrackHeight;
- $(horizontalBar).find('>.jspCap:visible,>.jspArrow').each(
- function () {
- horizontalTrackWidth += $(this).outerWidth();
- }
- );
- horizontalTrackWidth -= verticalTrackWidth;
- paneHeight -= verticalTrackWidth;
- paneWidth -= horizontalTrackHeight;
- horizontalTrack.parent().append(
- $('<div class="jspCorner" />').css('width', horizontalTrackHeight + 'px')
- );
- sizeVerticalScrollbar();
- sizeHorizontalScrollbar();
- }
- // reflow content
- if (isScrollableH) {
- pane.width((container.outerWidth() - originalPaddingTotalWidth) + 'px');
- }
- contentHeight = pane.outerHeight();
- percentInViewV = contentHeight / paneHeight;
-
- if (isScrollableH) {
- horizontalDragWidth = Math.ceil(1 / percentInViewH * horizontalTrackWidth);
- if (horizontalDragWidth > settings.horizontalDragMaxWidth) {
- horizontalDragWidth = settings.horizontalDragMaxWidth;
- } else if (horizontalDragWidth < settings.horizontalDragMinWidth) {
- horizontalDragWidth = settings.horizontalDragMinWidth;
- }
- horizontalDrag.width(horizontalDragWidth + 'px');
- dragMaxX = horizontalTrackWidth - horizontalDragWidth;
- _positionDragX(horizontalDragPosition); // To update the state for the arrow buttons
- }
- if (isScrollableV) {
- verticalDragHeight = Math.ceil(1 / percentInViewV * verticalTrackHeight);
- if (verticalDragHeight > settings.verticalDragMaxHeight) {
- verticalDragHeight = settings.verticalDragMaxHeight;
- } else if (verticalDragHeight < settings.verticalDragMinHeight) {
- verticalDragHeight = settings.verticalDragMinHeight;
- }
- verticalDrag.height(verticalDragHeight + 'px');
- dragMaxY = verticalTrackHeight - verticalDragHeight;
- _positionDragY(verticalDragPosition); // To update the state for the arrow buttons
- }
- }
-
- function appendArrows(ele, p, a1, a2) {
- var p1 = "before", p2 = "after", aTemp;
-
- // Sniff for mac... Is there a better way to determine whether the arrows would naturally appear
- // at the top or the bottom of the bar?
- if (p == "os") {
- p = /Mac/.test(navigator.platform) ? "after" : "split";
- }
- if (p == p1) {
- p2 = p;
- } else if (p == p2) {
- p1 = p;
- aTemp = a1;
- a1 = a2;
- a2 = aTemp;
- }
-
- ele[p1](a1)[p2](a2);
- }
-
- function getArrowScroll(dirX, dirY, ele) {
- return function () {
- arrowScroll(dirX, dirY, this, ele);
- this.blur();
- return false;
- };
- }
-
- function arrowScroll(dirX, dirY, arrow, ele) {
- arrow = $(arrow).addClass('jspActive');
-
- var eve,
- scrollTimeout,
- isFirst = true,
- doScroll = function () {
- if (dirX !== 0) {
- jsp.scrollByX(dirX * settings.arrowButtonSpeed);
- }
- if (dirY !== 0) {
- jsp.scrollByY(dirY * settings.arrowButtonSpeed);
- }
- scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.arrowRepeatFreq);
- isFirst = false;
- };
-
- doScroll();
-
- eve = ele ? 'mouseout.jsp' : 'mouseup.jsp';
- ele = ele || $('html');
- ele.bind(
- eve,
- function () {
- arrow.removeClass('jspActive');
- scrollTimeout && clearTimeout(scrollTimeout);
- scrollTimeout = null;
- ele.unbind(eve);
- }
- );
- }
-
- function initClickOnTrack() {
- removeClickOnTrack();
- if (isScrollableV) {
- verticalTrack.bind(
- 'mousedown.jsp',
- function (e) {
- if (e.originalTarget === undefined || e.originalTarget == e.currentTarget) {
- var clickedTrack = $(this),
- offset = clickedTrack.offset(),
- direction = e.pageY - offset.top - verticalDragPosition,
- scrollTimeout,
- isFirst = true,
- doScroll = function () {
- var offset = clickedTrack.offset(),
- pos = e.pageY - offset.top - verticalDragHeight / 2,
- contentDragY = paneHeight * settings.scrollPagePercent,
- dragY = dragMaxY * contentDragY / (contentHeight - paneHeight);
- if (direction < 0) {
- if (verticalDragPosition - dragY > pos) {
- jsp.scrollByY(-contentDragY);
- } else {
- positionDragY(pos);
- }
- } else if (direction > 0) {
- if (verticalDragPosition + dragY < pos) {
- jsp.scrollByY(contentDragY);
- } else {
- positionDragY(pos);
- }
- } else {
- cancelClick();
- return;
- }
- scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.trackClickRepeatFreq);
- isFirst = false;
- },
- cancelClick = function () {
- scrollTimeout && clearTimeout(scrollTimeout);
- scrollTimeout = null;
- $(document).unbind('mouseup.jsp', cancelClick);
- };
- doScroll();
- $(document).bind('mouseup.jsp', cancelClick);
- return false;
- }
- }
- );
- }
-
- if (isScrollableH) {
- horizontalTrack.bind(
- 'mousedown.jsp',
- function (e) {
- if (e.originalTarget === undefined || e.originalTarget == e.currentTarget) {
- var clickedTrack = $(this),
- offset = clickedTrack.offset(),
- direction = e.pageX - offset.left - horizontalDragPosition,
- scrollTimeout,
- isFirst = true,
- doScroll = function () {
- var offset = clickedTrack.offset(),
- pos = e.pageX - offset.left - horizontalDragWidth / 2,
- contentDragX = paneWidth * settings.scrollPagePercent,
- dragX = dragMaxX * contentDragX / (contentWidth - paneWidth);
- if (direction < 0) {
- if (horizontalDragPosition - dragX > pos) {
- jsp.scrollByX(-contentDragX);
- } else {
- positionDragX(pos);
- }
- } else if (direction > 0) {
- if (horizontalDragPosition + dragX < pos) {
- jsp.scrollByX(contentDragX);
- } else {
- positionDragX(pos);
- }
- } else {
- cancelClick();
- return;
- }
- scrollTimeout = setTimeout(doScroll, isFirst ? settings.initialDelay : settings.trackClickRepeatFreq);
- isFirst = false;
- },
- cancelClick = function () {
- scrollTimeout && clearTimeout(scrollTimeout);
- scrollTimeout = null;
- $(document).unbind('mouseup.jsp', cancelClick);
- };
- doScroll();
- $(document).bind('mouseup.jsp', cancelClick);
- return false;
- }
- }
- );
- }
- }
-
- function removeClickOnTrack() {
- if (horizontalTrack) {
- horizontalTrack.unbind('mousedown.jsp');
- }
- if (verticalTrack) {
- verticalTrack.unbind('mousedown.jsp');
- }
- }
-
- function cancelDrag() {
- $('html').unbind('dragstart.jsp selectstart.jsp mousemove.jsp mouseup.jsp mouseleave.jsp');
-
- if (verticalDrag) {
- verticalDrag.removeClass('jspActive');
- }
- if (horizontalDrag) {
- horizontalDrag.removeClass('jspActive');
- }
- }
-
- function positionDragY(destY, animate) {
- if (!isScrollableV) {
- return;
- }
- if (destY < 0) {
- destY = 0;
- } else if (destY > dragMaxY) {
- destY = dragMaxY;
- }
-
- // can't just check if(animate) because false is a valid value that could be passed in...
- if (animate === undefined) {
- animate = settings.animateScroll;
- }
- if (animate) {
- jsp.animate(verticalDrag, 'top', destY, _positionDragY);
- } else {
- verticalDrag.css('top', destY);
- _positionDragY(destY);
- }
-
- }
-
- function _positionDragY(destY) {
- if (destY === undefined) {
- destY = verticalDrag.position().top;
- }
-
- container.scrollTop(0);
- verticalDragPosition = destY;
-
- var isAtTop = verticalDragPosition === 0,
- isAtBottom = verticalDragPosition == dragMaxY,
- percentScrolled = destY / dragMaxY,
- destTop = -percentScrolled * (contentHeight - paneHeight);
-
- if (wasAtTop != isAtTop || wasAtBottom != isAtBottom) {
- wasAtTop = isAtTop;
- wasAtBottom = isAtBottom;
- elem.trigger('jsp-arrow-change', [wasAtTop, wasAtBottom, wasAtLeft, wasAtRight]);
- }
-
- updateVerticalArrows(isAtTop, isAtBottom);
- pane.css('top', destTop);
- elem.trigger('jsp-scroll-y', [-destTop, isAtTop, isAtBottom]).trigger('scroll');
- }
-
- function positionDragX(destX, animate) {
- if (!isScrollableH) {
- return;
- }
- if (destX < 0) {
- destX = 0;
- } else if (destX > dragMaxX) {
- destX = dragMaxX;
- }
-
- if (animate === undefined) {
- animate = settings.animateScroll;
- }
- if (animate) {
- jsp.animate(horizontalDrag, 'left', destX, _positionDragX);
- } else {
- horizontalDrag.css('left', destX);
- _positionDragX(destX);
- }
- }
-
- function _positionDragX(destX) {
- if (destX === undefined) {
- destX = horizontalDrag.position().left;
- }
-
- container.scrollTop(0);
- horizontalDragPosition = destX;
-
- var isAtLeft = horizontalDragPosition === 0,
- isAtRight = horizontalDragPosition == dragMaxX,
- percentScrolled = destX / dragMaxX,
- destLeft = -percentScrolled * (contentWidth - paneWidth);
-
- if (wasAtLeft != isAtLeft || wasAtRight != isAtRight) {
- wasAtLeft = isAtLeft;
- wasAtRight = isAtRight;
- elem.trigger('jsp-arrow-change', [wasAtTop, wasAtBottom, wasAtLeft, wasAtRight]);
- }
-
- updateHorizontalArrows(isAtLeft, isAtRight);
- pane.css('left', destLeft);
- elem.trigger('jsp-scroll-x', [-destLeft, isAtLeft, isAtRight]).trigger('scroll');
- }
-
- function updateVerticalArrows(isAtTop, isAtBottom) {
- if (settings.showArrows) {
- arrowUp[isAtTop ? 'addClass' : 'removeClass']('jspDisabled');
- arrowDown[isAtBottom ? 'addClass' : 'removeClass']('jspDisabled');
- }
- }
-
- function updateHorizontalArrows(isAtLeft, isAtRight) {
- if (settings.showArrows) {
- arrowLeft[isAtLeft ? 'addClass' : 'removeClass']('jspDisabled');
- arrowRight[isAtRight ? 'addClass' : 'removeClass']('jspDisabled');
- }
- }
-
- function scrollToY(destY, animate) {
- var percentScrolled = destY / (contentHeight - paneHeight);
- positionDragY(percentScrolled * dragMaxY, animate);
- }
-
- function scrollToX(destX, animate) {
- var percentScrolled = destX / (contentWidth - paneWidth);
- positionDragX(percentScrolled * dragMaxX, animate);
- }
-
- function scrollToElement(ele, stickToTop, animate) {
- var e, eleHeight, eleWidth, eleTop = 0, eleLeft = 0, viewportTop, viewportLeft, maxVisibleEleTop, maxVisibleEleLeft, destY, destX;
-
- // Legal hash values aren't necessarily legal jQuery selectors so we need to catch any
- // errors from the lookup...
- try {
- e = $(ele);
- } catch (err) {
- return;
- }
- eleHeight = e.outerHeight();
- eleWidth = e.outerWidth();
-
- container.scrollTop(0);
- container.scrollLeft(0);
-
- // loop through parents adding the offset top of any elements that are relatively positioned between
- // the focused element and the jspPane so we can get the true distance from the top
- // of the focused element to the top of the scrollpane...
- while (!e.is('.jspPane')) {
- eleTop += e.position().top;
- eleLeft += e.position().left;
- e = e.offsetParent();
- if (/^body|html$/i.test(e[0].nodeName)) {
- // we ended up too high in the document structure. Quit!
- return;
- }
- }
-
- viewportTop = contentPositionY();
- maxVisibleEleTop = viewportTop + paneHeight;
- if (eleTop < viewportTop || stickToTop) { // element is above viewport
- destY = eleTop - settings.verticalGutter;
- } else if (eleTop + eleHeight > maxVisibleEleTop) { // element is below viewport
- destY = eleTop - paneHeight + eleHeight + settings.verticalGutter;
- }
- if (destY) {
- scrollToY(destY, animate);
- }
-
- viewportLeft = contentPositionX();
- maxVisibleEleLeft = viewportLeft + paneWidth;
- if (eleLeft < viewportLeft || stickToTop) { // element is to the left of viewport
- destX = eleLeft - settings.horizontalGutter;
- } else if (eleLeft + eleWidth > maxVisibleEleLeft) { // element is to the right viewport
- destX = eleLeft - paneWidth + eleWidth + settings.horizontalGutter;
- }
- if (destX) {
- scrollToX(destX, animate);
- }
-
- }
-
- function contentPositionX() {
- return -pane.position().left;
- }
-
- function contentPositionY() {
- return -pane.position().top;
- }
-
- function isCloseToBottom() {
- var scrollableHeight = contentHeight - paneHeight;
- return (scrollableHeight > 20) && (scrollableHeight - contentPositionY() < 10);
- }
-
- function isCloseToRight() {
- var scrollableWidth = contentWidth - paneWidth;
- return (scrollableWidth > 20) && (scrollableWidth - contentPositionX() < 10);
- }
-
- function initMousewheel() {
- container.unbind(mwEvent).bind(
- mwEvent,
- function (event, delta, deltaX, deltaY) {
- var dX = horizontalDragPosition, dY = verticalDragPosition;
- jsp.scrollBy(deltaX * settings.mouseWheelSpeed, -deltaY * settings.mouseWheelSpeed, false);
- // return true if there was no movement so rest of screen can scroll
- return dX == horizontalDragPosition && dY == verticalDragPosition;
- }
- );
- }
-
- function removeMousewheel() {
- container.unbind(mwEvent);
- }
-
- function nil() {
- return false;
- }
-
- function initFocusHandler() {
- pane.find(':input,a').unbind('focus.jsp').bind(
- 'focus.jsp',
- function (e) {
- scrollToElement(e.target, false);
- }
- );
- }
-
- function removeFocusHandler() {
- pane.find(':input,a').unbind('focus.jsp');
- }
-
- function initKeyboardNav() {
- var keyDown, elementHasScrolled, validParents = [];
- isScrollableH && validParents.push(horizontalBar[0]);
- isScrollableV && validParents.push(verticalBar[0]);
-
- // IE also focuses elements that don't have tabindex set.
- pane.focus(
- function () {
- elem.focus();
- }
- );
-
- elem.attr('tabindex', 0)
- .unbind('keydown.jsp keypress.jsp')
- .bind(
- 'keydown.jsp',
- function (e) {
- if (e.target !== this && !(validParents.length && $(e.target).closest(validParents).length)) {
- return;
- }
- var dX = horizontalDragPosition, dY = verticalDragPosition;
- switch (e.keyCode) {
- case 40: // down
- case 38: // up
- case 34: // page down
- case 32: // space
- case 33: // page up
- case 39: // right
- case 37: // left
- keyDown = e.keyCode;
- keyDownHandler();
- break;
- case 35: // end
- scrollToY(contentHeight - paneHeight);
- keyDown = null;
- break;
- case 36: // home
- scrollToY(0);
- keyDown = null;
- break;
- }
-
- elementHasScrolled = e.keyCode == keyDown && dX != horizontalDragPosition || dY != verticalDragPosition;
- return !elementHasScrolled;
- }
- ).bind(
- 'keypress.jsp', // For FF/ OSX so that we can cancel the repeat key presses if the JSP scrolls...
- function (e) {
- if (e.keyCode == keyDown) {
- keyDownHandler();
- }
- return !elementHasScrolled;
- }
- );
-
- if (settings.hideFocus) {
- elem.css('outline', 'none');
- if ('hideFocus' in container[0]) {
- elem.attr('hideFocus', true);
- }
- } else {
- elem.css('outline', '');
- if ('hideFocus' in container[0]) {
- elem.attr('hideFocus', false);
- }
- }
-
- function keyDownHandler() {
- var dX = horizontalDragPosition, dY = verticalDragPosition;
- switch (keyDown) {
- case 40: // down
- jsp.scrollByY(settings.keyboardSpeed, false);
- break;
- case 38: // up
- jsp.scrollByY(-settings.keyboardSpeed, false);
- break;
- case 34: // page down
- case 32: // space
- jsp.scrollByY(paneHeight * settings.scrollPagePercent, false);
- break;
- case 33: // page up
- jsp.scrollByY(-paneHeight * settings.scrollPagePercent, false);
- break;
- case 39: // right
- jsp.scrollByX(settings.keyboardSpeed, false);
- break;
- case 37: // left
- jsp.scrollByX(-settings.keyboardSpeed, false);
- break;
- }
-
- elementHasScrolled = dX != horizontalDragPosition || dY != verticalDragPosition;
- return elementHasScrolled;
- }
- }
-
- function removeKeyboardNav() {
- elem.attr('tabindex', '-1')
- .removeAttr('tabindex')
- .unbind('keydown.jsp keypress.jsp');
- }
-
- function observeHash() {
- if (location.hash && location.hash.length > 1) {
- var e,
- retryInt,
- hash = escape(location.hash.substr(1)) // hash must be escaped to prevent XSS
- ;
- try {
- e = $('#' + hash + ', a[name="' + hash + '"]');
- } catch (err) {
- return;
- }
-
- if (e.length && pane.find(hash)) {
- // nasty workaround but it appears to take a little while before the hash has done its thing
- // to the rendered page so we just wait until the container's scrollTop has been messed up.
- if (container.scrollTop() === 0) {
- retryInt = setInterval(
- function () {
- if (container.scrollTop() > 0) {
- scrollToElement(e, true);
- $(document).scrollTop(container.position().top);
- clearInterval(retryInt);
- }
- },
- 50
- );
- } else {
- scrollToElement(e, true);
- $(document).scrollTop(container.position().top);
- }
- }
- }
- }
-
- function hijackInternalLinks() {
- // only register the link handler once
- if ($(document.body).data('jspHijack')) {
- return;
- }
-
- // remember that the handler was bound
- $(document.body).data('jspHijack', true);
-
- // use live handler to also capture newly created links
- $(document.body).delegate('a[href*=#]', 'click', function (event) {
- // does the link point to the same page?
- // this also takes care of cases with a <base>-Tag or Links not starting with the hash #
- // e.g. <a href="index.html#test"> when the current url already is index.html
- var href = this.href.substr(0, this.href.indexOf('#')),
- locationHref = location.href,
- hash,
- element,
- container,
- jsp,
- scrollTop,
- elementTop;
- if (location.href.indexOf('#') !== -1) {
- locationHref = location.href.substr(0, location.href.indexOf('#'));
- }
- if (href !== locationHref) {
- // the link points to another page
- return;
- }
-
- // check if jScrollPane should handle this click event
- hash = escape(this.href.substr(this.href.indexOf('#') + 1));
-
- // find the element on the page
- try {
- element = $('#' + hash + ', a[name="' + hash + '"]');
- } catch (e) {
- // hash is not a valid jQuery identifier
- return;
- }
-
- if (!element.length) {
- // this link does not point to an element on this page
- return;
- }
-
- container = element.closest('.jspScrollable');
- jsp = container.data('jsp');
-
- // jsp might be another jsp instance than the one, that bound this event
- // remember: this event is only bound once for all instances.
- jsp.scrollToElement(element, true);
-
- if (container[0].scrollIntoView) {
- // also scroll to the top of the container (if it is not visible)
- scrollTop = $(window).scrollTop();
- elementTop = element.offset().top;
- if (elementTop < scrollTop || elementTop > scrollTop + $(window).height()) {
- container[0].scrollIntoView();
- }
- }
-
- // jsp handled this event, prevent the browser default (scrolling :P)
- event.preventDefault();
- });
- }
-
- // Init touch on iPad, iPhone, iPod, Android
- function initTouch() {
- var startX,
- startY,
- touchStartX,
- touchStartY,
- moved,
- moving = false;
-
- container.unbind('touchstart.jsp touchmove.jsp touchend.jsp click.jsp-touchclick').bind(
- 'touchstart.jsp',
- function (e) {
- var touch = e.originalEvent.touches[0];
- startX = contentPositionX();
- startY = contentPositionY();
- touchStartX = touch.pageX;
- touchStartY = touch.pageY;
- moved = false;
- moving = true;
- }
- ).bind(
- 'touchmove.jsp',
- function (ev) {
- if (!moving) {
- return;
- }
-
- var touchPos = ev.originalEvent.touches[0],
- dX = horizontalDragPosition, dY = verticalDragPosition;
-
- jsp.scrollTo(startX + touchStartX - touchPos.pageX, startY + touchStartY - touchPos.pageY);
-
- moved = moved || Math.abs(touchStartX - touchPos.pageX) > 5 || Math.abs(touchStartY - touchPos.pageY) > 5;
-
- // return true if there was no movement so rest of screen can scroll
- return dX == horizontalDragPosition && dY == verticalDragPosition;
- }
- ).bind(
- 'touchend.jsp',
- function (e) {
- moving = false;
- /*if(moved) {
- return false;
- }*/
- }
- ).bind(
- 'click.jsp-touchclick',
- function (e) {
- if (moved) {
- moved = false;
- return false;
- }
- }
- );
- }
-
- function destroy() {
- var currentY = contentPositionY(),
- currentX = contentPositionX();
- elem.removeClass('jspScrollable').unbind('.jsp');
- elem.replaceWith(originalElement.append(pane.children()));
- originalElement.scrollTop(currentY);
- originalElement.scrollLeft(currentX);
-
- // clear reinitialize timer if active
- if (reinitialiseInterval) {
- clearInterval(reinitialiseInterval);
- }
- }
-
- // Public API
- $.extend(
- jsp,
- {
- // Reinitialises the scroll pane (if it's internal dimensions have changed since the last time it
- // was initialised). The settings object which is passed in will override any settings from the
- // previous time it was initialised - if you don't pass any settings then the ones from the previous
- // initialisation will be used.
- reinitialise: function (s) {
- s = $.extend({}, settings, s);
- initialise(s);
- },
- // Scrolls the specified element (a jQuery object, DOM node or jQuery selector string) into view so
- // that it can be seen within the viewport. If stickToTop is true then the element will appear at
- // the top of the viewport, if it is false then the viewport will scroll as little as possible to
- // show the element. You can also specify if you want animation to occur. If you don't provide this
- // argument then the animateScroll value from the settings object is used instead.
- scrollToElement: function (ele, stickToTop, animate) {
- scrollToElement(ele, stickToTop, animate);
- },
- // Scrolls the pane so that the specified co-ordinates within the content are at the top left
- // of the viewport. animate is optional and if not passed then the value of animateScroll from
- // the settings object this jScrollPane was initialised with is used.
- scrollTo: function (destX, destY, animate) {
- scrollToX(destX, animate);
- scrollToY(destY, animate);
- },
- // Scrolls the pane so that the specified co-ordinate within the content is at the left of the
- // viewport. animate is optional and if not passed then the value of animateScroll from the settings
- // object this jScrollPane was initialised with is used.
- scrollToX: function (destX, animate) {
- scrollToX(destX, animate);
- },
- // Scrolls the pane so that the specified co-ordinate within the content is at the top of the
- // viewport. animate is optional and if not passed then the value of animateScroll from the settings
- // object this jScrollPane was initialised with is used.
- scrollToY: function (destY, animate) {
- scrollToY(destY, animate);
- },
- // Scrolls the pane to the specified percentage of its maximum horizontal scroll position. animate
- // is optional and if not passed then the value of animateScroll from the settings object this
- // jScrollPane was initialised with is used.
- scrollToPercentX: function (destPercentX, animate) {
- scrollToX(destPercentX * (contentWidth - paneWidth), animate);
- },
- // Scrolls the pane to the specified percentage of its maximum vertical scroll position. animate
- // is optional and if not passed then the value of animateScroll from the settings object this
- // jScrollPane was initialised with is used.
- scrollToPercentY: function (destPercentY, animate) {
- scrollToY(destPercentY * (contentHeight - paneHeight), animate);
- },
- // Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
- // the value of animateScroll from the settings object this jScrollPane was initialised with is used.
- scrollBy: function (deltaX, deltaY, animate) {
- jsp.scrollByX(deltaX, animate);
- jsp.scrollByY(deltaY, animate);
- },
- // Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
- // the value of animateScroll from the settings object this jScrollPane was initialised with is used.
- scrollByX: function (deltaX, animate) {
- var destX = contentPositionX() + Math[deltaX < 0 ? 'floor' : 'ceil'](deltaX),
- percentScrolled = destX / (contentWidth - paneWidth);
- positionDragX(percentScrolled * dragMaxX, animate);
- },
- // Scrolls the pane by the specified amount of pixels. animate is optional and if not passed then
- // the value of animateScroll from the settings object this jScrollPane was initialised with is used.
- scrollByY: function (deltaY, animate) {
- var destY = contentPositionY() + Math[deltaY < 0 ? 'floor' : 'ceil'](deltaY),
- percentScrolled = destY / (contentHeight - paneHeight);
- positionDragY(percentScrolled * dragMaxY, animate);
- },
- // Positions the horizontal drag at the specified x position (and updates the viewport to reflect
- // this). animate is optional and if not passed then the value of animateScroll from the settings
- // object this jScrollPane was initialised with is used.
- positionDragX: function (x, animate) {
- positionDragX(x, animate);
- },
- // Positions the vertical drag at the specified y position (and updates the viewport to reflect
- // this). animate is optional and if not passed then the value of animateScroll from the settings
- // object this jScrollPane was initialised with is used.
- positionDragY: function (y, animate) {
- positionDragY(y, animate);
- },
- // This method is called when jScrollPane is trying to animate to a new position. You can override
- // it if you want to provide advanced animation functionality. It is passed the following arguments:
- // * ele - the element whose position is being animated
- // * prop - the property that is being animated
- // * value - the value it's being animated to
- // * stepCallback - a function that you must execute each time you update the value of the property
- // You can use the default implementation (below) as a starting point for your own implementation.
- animate: function (ele, prop, value, stepCallback) {
- var params = {};
- params[prop] = value;
- ele.animate(
- params,
- {
- 'duration': settings.animateDuration,
- 'easing': settings.animateEase,
- 'queue': false,
- 'step': stepCallback
- }
- );
- },
- // Returns the current x position of the viewport with regards to the content pane.
- getContentPositionX: function () {
- return contentPositionX();
- },
- // Returns the current y position of the viewport with regards to the content pane.
- getContentPositionY: function () {
- return contentPositionY();
- },
- // Returns the width of the content within the scroll pane.
- getContentWidth: function () {
- return contentWidth;
- },
- // Returns the height of the content within the scroll pane.
- getContentHeight: function () {
- return contentHeight;
- },
- // Returns the horizontal position of the viewport within the pane content.
- getPercentScrolledX: function () {
- return contentPositionX() / (contentWidth - paneWidth);
- },
- // Returns the vertical position of the viewport within the pane content.
- getPercentScrolledY: function () {
- return contentPositionY() / (contentHeight - paneHeight);
- },
- // Returns whether or not this scrollpane has a horizontal scrollbar.
- getIsScrollableH: function () {
- return isScrollableH;
- },
- // Returns whether or not this scrollpane has a vertical scrollbar.
- getIsScrollableV: function () {
- return isScrollableV;
- },
- // Gets a reference to the content pane. It is important that you use this method if you want to
- // edit the content of your jScrollPane as if you access the element directly then you may have some
- // problems (as your original element has had additional elements for the scrollbars etc added into
- // it).
- getContentPane: function () {
- return pane;
- },
- // Scrolls this jScrollPane down as far as it can currently scroll. If animate isn't passed then the
- // animateScroll value from settings is used instead.
- scrollToBottom: function (animate) {
- positionDragY(dragMaxY, animate);
- },
- // Hijacks the links on the page which link to content inside the scrollpane. If you have changed
- // the content of your page (e.g. via AJAX) and want to make sure any new anchor links to the
- // contents of your scroll pane will work then call this function.
- hijackInternalLinks: $.noop,
- // Removes the jScrollPane and returns the page to the state it was in before jScrollPane was
- // initialised.
- destroy: function () {
- destroy();
- }
- }
- );
-
- initialise(s);
- }
-
- // Pluginifying code...
- settings = $.extend({}, $.fn.jScrollPane.defaults, settings);
-
- // Apply default speed
- $.each(['mouseWheelSpeed', 'arrowButtonSpeed', 'trackClickSpeed', 'keyboardSpeed'], function () {
- settings[this] = settings[this] || settings.speed;
- });
-
- return this.each(
- function () {
- var elem = $(this), jspApi = elem.data('jsp');
- if (jspApi) {
- jspApi.reinitialise(settings);
- } else {
- $("script", elem).filter('[type="text/javascript"],:not([type])').remove();
- jspApi = new JScrollPane(elem, settings);
- elem.data('jsp', jspApi);
- }
- }
- );
- };
-
- $.fn.jScrollPane.defaults = {
- showArrows: false,
- maintainPosition: true,
- stickToBottom: false,
- stickToRight: false,
- clickOnTrack: true,
- autoReinitialise: false,
- autoReinitialiseDelay: 500,
- verticalDragMinHeight: 0,
- verticalDragMaxHeight: 99999,
- horizontalDragMinWidth: 0,
- horizontalDragMaxWidth: 99999,
- contentWidth: undefined,
- animateScroll: false,
- animateDuration: 300,
- animateEase: 'linear',
- hijackInternalLinks: false,
- verticalGutter: 4,
- horizontalGutter: 4,
- mouseWheelSpeed: 0,
- arrowButtonSpeed: 0,
- arrowRepeatFreq: 50,
- arrowScrollOnHover: false,
- trackClickSpeed: 0,
- trackClickRepeatFreq: 70,
- verticalArrowPositions: 'split',
- horizontalArrowPositions: 'split',
- enableKeyboardNavigation: true,
- hideFocus: false,
- keyboardSpeed: 0,
- initialDelay: 300, // Delay before starting repeating
- speed: 30, // Default speed when others falsey
- scrollPagePercent: .8 // Percent of visible area scrolled when pageUp/Down or track area pressed
- };
-
-})(jQuery, this);
diff --git a/plugins/SegmentEditor/javascripts/jquery.mousewheel.js b/plugins/SegmentEditor/javascripts/jquery.mousewheel.js
deleted file mode 100644
index 9d65c7162b..0000000000
--- a/plugins/SegmentEditor/javascripts/jquery.mousewheel.js
+++ /dev/null
@@ -1,117 +0,0 @@
-/*! Copyright (c) 2013 Brandon Aaron (http://brandonaaron.net)
- * Licensed under the MIT License (LICENSE.txt).
- *
- * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
- * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
- * Thanks to: Seamus Leahy for adding deltaX and deltaY
- *
- * Version: 3.1.3
- *
- * Requires: 1.2.2+
- */
-
-(function (factory) {
- if ( typeof define === 'function' && define.amd ) {
- // AMD. Register as an anonymous module.
- define(['jquery'], factory);
- } else if (typeof exports === 'object') {
- // Node/CommonJS style for Browserify
- module.exports = factory;
- } else {
- // Browser globals
- factory(jQuery);
- }
-}(function ($) {
-
- var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'];
- var toBind = 'onwheel' in document || document.documentMode >= 9 ? ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'];
- var lowestDelta, lowestDeltaXY;
-
- if ( $.event.fixHooks ) {
- for ( var i = toFix.length; i; ) {
- $.event.fixHooks[ toFix[--i] ] = $.event.mouseHooks;
- }
- }
-
- $.event.special.mousewheel = {
- setup: function() {
- if ( this.addEventListener ) {
- for ( var i = toBind.length; i; ) {
- this.addEventListener( toBind[--i], handler, false );
- }
- } else {
- this.onmousewheel = handler;
- }
- },
-
- teardown: function() {
- if ( this.removeEventListener ) {
- for ( var i = toBind.length; i; ) {
- this.removeEventListener( toBind[--i], handler, false );
- }
- } else {
- this.onmousewheel = null;
- }
- }
- };
-
- $.fn.extend({
- mousewheel: function(fn) {
- return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
- },
-
- unmousewheel: function(fn) {
- return this.unbind("mousewheel", fn);
- }
- });
-
-
- function handler(event) {
- var orgEvent = event || window.event,
- args = [].slice.call(arguments, 1),
- delta = 0,
- deltaX = 0,
- deltaY = 0,
- absDelta = 0,
- absDeltaXY = 0,
- fn;
- event = $.event.fix(orgEvent);
- event.type = "mousewheel";
-
- // Old school scrollwheel delta
- if ( orgEvent.wheelDelta ) { delta = orgEvent.wheelDelta; }
- if ( orgEvent.detail ) { delta = orgEvent.detail * -1; }
-
- // New school wheel delta (wheel event)
- if ( orgEvent.deltaY ) {
- deltaY = orgEvent.deltaY * -1;
- delta = deltaY;
- }
- if ( orgEvent.deltaX ) {
- deltaX = orgEvent.deltaX;
- delta = deltaX * -1;
- }
-
- // Webkit
- if ( orgEvent.wheelDeltaY !== undefined ) { deltaY = orgEvent.wheelDeltaY; }
- if ( orgEvent.wheelDeltaX !== undefined ) { deltaX = orgEvent.wheelDeltaX * -1; }
-
- // Look for lowest delta to normalize the delta values
- absDelta = Math.abs(delta);
- if ( !lowestDelta || absDelta < lowestDelta ) { lowestDelta = absDelta; }
- absDeltaXY = Math.max(Math.abs(deltaY), Math.abs(deltaX));
- if ( !lowestDeltaXY || absDeltaXY < lowestDeltaXY ) { lowestDeltaXY = absDeltaXY; }
-
- // Get a whole value for the deltas
- fn = delta > 0 ? 'floor' : 'ceil';
- delta = Math[fn](delta / lowestDelta);
- deltaX = Math[fn](deltaX / lowestDeltaXY);
- deltaY = Math[fn](deltaY / lowestDeltaXY);
-
- // Add event and delta to the front of the arguments
- args.unshift(event, delta, deltaX, deltaY);
-
- return ($.event.dispatch || $.event.handle).apply(this, args);
- }
-
-}));
diff --git a/plugins/SegmentEditor/javascripts/mwheelIntent.js b/plugins/SegmentEditor/javascripts/mwheelIntent.js
deleted file mode 100644
index 72b7d135ca..0000000000
--- a/plugins/SegmentEditor/javascripts/mwheelIntent.js
+++ /dev/null
@@ -1,76 +0,0 @@
-/**
- * @author trixta
- * @version 1.2
- */
-(function($){
-
- var mwheelI = {
- pos: [-260, -260]
- },
- minDif = 3,
- doc = document,
- root = doc.documentElement,
- body = doc.body,
- longDelay, shortDelay
- ;
-
- function unsetPos(){
- if(this === mwheelI.elem){
- mwheelI.pos = [-260, -260];
- mwheelI.elem = false;
- minDif = 3;
- }
- }
-
- $.event.special.mwheelIntent = {
- setup: function(){
- var jElm = $(this).bind('mousewheel', $.event.special.mwheelIntent.handler);
- if( this !== doc && this !== root && this !== body ){
- jElm.bind('mouseleave', unsetPos);
- }
- jElm = null;
- return true;
- },
- teardown: function(){
- $(this)
- .unbind('mousewheel', $.event.special.mwheelIntent.handler)
- .unbind('mouseleave', unsetPos)
- ;
- return true;
- },
- handler: function(e, d){
- var pos = [e.clientX, e.clientY];
- if( this === mwheelI.elem || Math.abs(mwheelI.pos[0] - pos[0]) > minDif || Math.abs(mwheelI.pos[1] - pos[1]) > minDif ){
- mwheelI.elem = this;
- mwheelI.pos = pos;
- minDif = 250;
-
- clearTimeout(shortDelay);
- shortDelay = setTimeout(function(){
- minDif = 10;
- }, 200);
- clearTimeout(longDelay);
- longDelay = setTimeout(function(){
- minDif = 3;
- }, 1500);
- e = $.extend({}, e, {type: 'mwheelIntent'});
- return $.event.dispatch.apply(this, arguments);
- }
- }
- };
- $.fn.extend({
- mwheelIntent: function(fn) {
- return fn ? this.bind("mwheelIntent", fn) : this.trigger("mwheelIntent");
- },
-
- unmwheelIntent: function(fn) {
- return this.unbind("mwheelIntent", fn);
- }
- });
-
- $(function(){
- body = doc.body;
- //assume that document is always scrollable, doesn't hurt if not
- $(doc).bind('mwheelIntent.mwheelIntentDefault', $.noop);
- });
-})(jQuery);
diff --git a/plugins/SegmentEditor/stylesheets/jquery.jscrollpane.css b/plugins/SegmentEditor/stylesheets/jquery.jscrollpane.css
deleted file mode 100644
index 0364216fe0..0000000000
--- a/plugins/SegmentEditor/stylesheets/jquery.jscrollpane.css
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * CSS Styles that are needed by jScrollPane for it to operate correctly.
- *
- * Include this stylesheet in your site or copy and paste the styles below into your stylesheet - jScrollPane
- * may not operate correctly without them.
- */
-
-.jspContainer
-{
- overflow: hidden;
- position: relative;
-}
-
-.jspPane
-{
- position: absolute;
-}
-
-.jspVerticalBar
-{
- position: absolute;
- top: 0;
- right: 0;
- width: 8px;
- height: 100%;
- background: red;
-}
-
-.jspHorizontalBar
-{
- position: absolute;
- bottom: 0;
- left: 0;
- width: 100%;
- height: 16px;
- background: red;
-}
-
-.jspVerticalBar *,
-.jspHorizontalBar *
-{
- margin: 0;
- padding: 0;
-}
-
-.jspCap
-{
- display: none;
-}
-
-.jspHorizontalBar .jspCap
-{
- float: left;
-}
-
-.jspTrack
-{
- background: #dde;
- position: relative;
-}
-
-.jspDrag
-{
- background: #bbd;
- position: relative;
- top: 0;
- left: 0;
- cursor: pointer;
-}
-
-.jspHorizontalBar .jspTrack,
-.jspHorizontalBar .jspDrag
-{
- float: left;
- height: 100%;
-}
-
-.jspArrow
-{
- background: #50506d;
- text-indent: -20000px;
- display: block;
- cursor: pointer;
-}
-
-.jspArrow.jspDisabled
-{
- cursor: default;
-}
-
-.jspVerticalBar .jspArrow
-{
- height: 16px;
-}
-
-.jspHorizontalBar .jspArrow
-{
- width: 16px;
- float: left;
- height: 100%;
-}
-
-.jspVerticalBar .jspArrow:focus
-{
- outline: none;
-}
-
-.jspCorner
-{
- background: #eeeef4;
- float: left;
- height: 100%;
-}
-
-/* Yuk! CSS Hack for IE6 3 pixel bug :( */
-* html .jspCorner
-{
- margin: 0 -3px 0 0;
-} \ No newline at end of file
diff --git a/plugins/SegmentEditor/stylesheets/scroll.less b/plugins/SegmentEditor/stylesheets/scroll.less
deleted file mode 100644
index 23c0402e15..0000000000
--- a/plugins/SegmentEditor/stylesheets/scroll.less
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * CSS Styles that are needed by jScrollPane for it to operate correctly.
- *
- * Include this stylesheet in your site or copy and paste the styles below into your stylesheet - jScrollPane
- * may not operate correctly without them.
- */
-
-.jspContainer
-{
- /*overflow: hidden;*/
- position: relative;
-}
-
-.jspPane
-{
- position: absolute;
-}
-
-.jspVerticalBar
-{
- position: absolute;
- top: 0;
- right: 0;
- width: 16px;
- height: 100%;
-}
-
-.jspHorizontalBar
-{
- position: absolute;
- bottom: 0;
- left: 0;
- width: 100%;
- height: 16px;
- background: red;
-}
-
-.jspVerticalBar *,
-.jspHorizontalBar *
-{
- margin: 0;
- padding: 0;
-}
-
-.jspCap
-{
- display: none;
-}
-
-.jspHorizontalBar .jspCap
-{
- float: left;
-}
-
-.jspTrack
-{
- background: url("plugins/SegmentEditor/images/slide.png") transparent no-repeat 7px;
- position: relative;
- background-size: 20% 100%;
- /*height: 447px!important;*/
-}
-
-.jspDrag
-{
- background: url("plugins/SegmentEditor/images/scroller.png") transparent no-repeat;
- background-size: 100% 100%;
- width: 17px;
- position: relative;
- top: 0;
- left: 0;
- cursor: pointer;
-}
-
-.jspHorizontalBar .jspTrack,
-.jspHorizontalBar .jspDrag
-{
- float: left;
- height: 100%;
-}
-
-.jspArrow
-{
-
- text-indent: -20000px;
- display: block;
- cursor: pointer;
-}
-.jspArrowDown{
- background: url("plugins/SegmentEditor/images/down_arrow.png") transparent no-repeat;
-}
-.jspArrowUp{
- background: url("plugins/SegmentEditor/images/up_arrow.png") transparent no-repeat;
-}
-
-.jspVerticalBar .jspArrow
-{
- height: 14px;
-
-}
-
-.jspHorizontalBar .jspArrow
-{
- width: 16px;
- float: left;
- height: 100%;
-}
-
-.jspVerticalBar .jspArrow:focus
-{
- outline: none;
-}
-
-.jspCorner
-{
- background: #eeeef4;
- float: left;
- height: 100%;
-}
-
-/* Yuk! CSS Hack for IE6 3 pixel bug :( */
-* html .jspCorner
-{
- margin: 0 -3px 0 0;
-}
-
-/* Styles specific to this particular page */
-.scroll-pane-before,
-.scroll-pane-after,
-.scroll-pane-split,
-.scroll-pane-os
-{
- width: 100%;
- height: 200px;
- overflow: auto;
-}
-.horizontal-only
-{
- height: auto;
- max-height: 200px;
-}