Merge remote-tracking branch 'upstream/develop' into post-delivery-data
This commit is contained in:
commit
84e3892955
|
@ -50,7 +50,6 @@
|
||||||
"bower-asset/base64": "^1.0",
|
"bower-asset/base64": "^1.0",
|
||||||
"bower-asset/chart-js": "^2.8",
|
"bower-asset/chart-js": "^2.8",
|
||||||
"bower-asset/dompurify": "^1.0",
|
"bower-asset/dompurify": "^1.0",
|
||||||
"bower-asset/perfect-scrollbar": "^0.6",
|
|
||||||
"bower-asset/vue": "^2.6",
|
"bower-asset/vue": "^2.6",
|
||||||
"npm-asset/es-jquery-sortable": "^0.9.13",
|
"npm-asset/es-jquery-sortable": "^0.9.13",
|
||||||
"npm-asset/jquery": "^2.0",
|
"npm-asset/jquery": "^2.0",
|
||||||
|
|
|
@ -237,37 +237,6 @@
|
||||||
],
|
],
|
||||||
"time": "2019-02-28T15:21:34+00:00"
|
"time": "2019-02-28T15:21:34+00:00"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"name": "bower-asset/perfect-scrollbar",
|
|
||||||
"version": "0.6.16",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/utatti/perfect-scrollbar-bower.git",
|
|
||||||
"reference": "3049129e5dbb403295ce8507a461cdd0f200938c"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/utatti/perfect-scrollbar-bower/zipball/3049129e5dbb403295ce8507a461cdd0f200938c",
|
|
||||||
"reference": "3049129e5dbb403295ce8507a461cdd0f200938c",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"type": "bower-asset-library",
|
|
||||||
"extra": {
|
|
||||||
"bower-asset-main": [
|
|
||||||
"css/perfect-scrollbar.css",
|
|
||||||
"js/perfect-scrollbar.js"
|
|
||||||
],
|
|
||||||
"bower-asset-ignore": [
|
|
||||||
"**/.*",
|
|
||||||
"bower_components"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"description": "Minimalistic but perfect custom scrollbar plugin",
|
|
||||||
"time": "2017-01-10T01:04:09+00:00"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "bower-asset/vue",
|
"name": "bower-asset/vue",
|
||||||
"version": "v2.6.10",
|
"version": "v2.6.10",
|
||||||
|
|
|
@ -107,12 +107,24 @@ function notification($params)
|
||||||
$item_id = 0;
|
$item_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($params['item']['uri-id'])) {
|
||||||
|
$uri_id = $params['item']['uri-id'];
|
||||||
|
} else {
|
||||||
|
$uri_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (isset($params['parent'])) {
|
if (isset($params['parent'])) {
|
||||||
$parent_id = $params['parent'];
|
$parent_id = $params['parent'];
|
||||||
} else {
|
} else {
|
||||||
$parent_id = 0;
|
$parent_id = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isset($params['item']['parent-uri-id'])) {
|
||||||
|
$parent_uri_id = $params['item']['parent-uri-id'];
|
||||||
|
} else {
|
||||||
|
$parent_uri_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
$epreamble = '';
|
$epreamble = '';
|
||||||
$preamble = '';
|
$preamble = '';
|
||||||
$subject = '';
|
$subject = '';
|
||||||
|
@ -452,17 +464,19 @@ function notification($params)
|
||||||
|
|
||||||
if ($show_in_notification_page) {
|
if ($show_in_notification_page) {
|
||||||
$notification = DI::notify()->insert([
|
$notification = DI::notify()->insert([
|
||||||
'name' => $params['source_name'] ?? '',
|
'name' => $params['source_name'] ?? '',
|
||||||
'name_cache' => substr(strip_tags(BBCode::convert($params['source_name'] ?? '')), 0, 255),
|
'name_cache' => substr(strip_tags(BBCode::convert($params['source_name'] ?? '')), 0, 255),
|
||||||
'url' => $params['source_link'] ?? '',
|
'url' => $params['source_link'] ?? '',
|
||||||
'photo' => $params['source_photo'] ?? '',
|
'photo' => $params['source_photo'] ?? '',
|
||||||
'link' => $itemlink ?? '',
|
'link' => $itemlink ?? '',
|
||||||
'uid' => $params['uid'] ?? 0,
|
'uid' => $params['uid'] ?? 0,
|
||||||
'iid' => $item_id ?? 0,
|
'iid' => $item_id,
|
||||||
'parent' => $parent_id ?? 0,
|
'uri-id' => $uri_id,
|
||||||
'type' => $params['type'] ?? '',
|
'parent' => $parent_id,
|
||||||
'verb' => $params['verb'] ?? '',
|
'parent-uri-id' => $parent_uri_id,
|
||||||
'otype' => $params['otype'] ?? '',
|
'type' => $params['type'] ?? '',
|
||||||
|
'verb' => $params['verb'] ?? '',
|
||||||
|
'otype' => $params['otype'] ?? '',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$notification->msg = Renderer::replaceMacros($epreamble, ['$itemlink' => $notification->link]);
|
$notification->msg = Renderer::replaceMacros($epreamble, ['$itemlink' => $notification->link]);
|
||||||
|
@ -486,8 +500,9 @@ function notification($params)
|
||||||
if (!DBA::exists('notify-threads', ['master-parent-item' => $params['parent'], 'receiver-uid' => $params['uid']])) {
|
if (!DBA::exists('notify-threads', ['master-parent-item' => $params['parent'], 'receiver-uid' => $params['uid']])) {
|
||||||
Logger::log("notify_id:" . intval($notify_id) . ", parent: " . intval($params['parent']) . "uid: " . intval($params['uid']), Logger::DEBUG);
|
Logger::log("notify_id:" . intval($notify_id) . ", parent: " . intval($params['parent']) . "uid: " . intval($params['uid']), Logger::DEBUG);
|
||||||
|
|
||||||
$fields = ['notify-id' => $notify_id, 'master-parent-item' => $params['parent'],
|
$fields = ['notify-id' => $notify_id, 'master-parent-item' => $params['parent'],
|
||||||
'receiver-uid' => $params['uid'], 'parent-item' => 0];
|
'master-parent-uri-id' => $parent_uri_id,
|
||||||
|
'receiver-uid' => $params['uid'], 'parent-item' => 0];
|
||||||
DBA::insert('notify-threads', $fields);
|
DBA::insert('notify-threads', $fields);
|
||||||
|
|
||||||
$additional_mail_header .= "Message-ID: <${id_for_parent}>\n";
|
$additional_mail_header .= "Message-ID: <${id_for_parent}>\n";
|
||||||
|
@ -574,7 +589,7 @@ function check_user_notification($itemid) {
|
||||||
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
|
||||||
*/
|
*/
|
||||||
function check_item_notification($itemid, $uid, $notification_type) {
|
function check_item_notification($itemid, $uid, $notification_type) {
|
||||||
$fields = ['id', 'mention', 'parent', 'title', 'body',
|
$fields = ['id', 'uri-id', 'mention', 'parent', 'parent-uri-id', 'title', 'body',
|
||||||
'author-link', 'author-name', 'author-avatar', 'author-id',
|
'author-link', 'author-name', 'author-avatar', 'author-id',
|
||||||
'guid', 'parent-uri', 'uri', 'contact-id', 'network'];
|
'guid', 'parent-uri', 'uri', 'contact-id', 'network'];
|
||||||
$condition = ['id' => $itemid, 'gravity' => [GRAVITY_PARENT, GRAVITY_COMMENT], 'deleted' => false];
|
$condition = ['id' => $itemid, 'gravity' => [GRAVITY_PARENT, GRAVITY_COMMENT], 'deleted' => false];
|
||||||
|
|
|
@ -2081,11 +2081,9 @@ class OStatus
|
||||||
XML::addElement($doc, $entry, "ostatus:conversation", $conversation_uri, $attributes);
|
XML::addElement($doc, $entry, "ostatus:conversation", $conversation_uri, $attributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
$tags = Tag::getByURIId($item['uri-id']);
|
// uri-id isn't present for follow entry pseudo-items
|
||||||
if (count($tags)) {
|
foreach (Tag::getByURIId($item['uri-id'] ?? 0) as $tag) {
|
||||||
foreach ($tags as $tag) {
|
$mentioned[$tag['url']] = $tag['url'];
|
||||||
$mentioned[$tag['url']] = $tag['url'];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that mentions are accepted (GNU Social has problems with mixing HTTP and HTTPS)
|
// Make sure that mentions are accepted (GNU Social has problems with mixing HTTP and HTTPS)
|
||||||
|
|
|
@ -908,6 +908,8 @@ return [
|
||||||
"link" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
|
"link" => ["type" => "varchar(255)", "not null" => "1", "default" => "", "comment" => ""],
|
||||||
"iid" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "relation" => ["item" => "id"], "comment" => "item.id"],
|
"iid" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "relation" => ["item" => "id"], "comment" => "item.id"],
|
||||||
"parent" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "relation" => ["item" => "id"], "comment" => ""],
|
"parent" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "relation" => ["item" => "id"], "comment" => ""],
|
||||||
|
"uri-id" => ["type" => "int unsigned", "relation" => ["item-uri" => "id"], "comment" => "Item-uri id of the related post"],
|
||||||
|
"parent-uri-id" => ["type" => "int unsigned", "relation" => ["item-uri" => "id"], "comment" => "Item-uri id of the parent of the related post"],
|
||||||
"seen" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
|
"seen" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => ""],
|
||||||
"verb" => ["type" => "varchar(100)", "not null" => "1", "default" => "", "comment" => ""],
|
"verb" => ["type" => "varchar(100)", "not null" => "1", "default" => "", "comment" => ""],
|
||||||
"otype" => ["type" => "varchar(10)", "not null" => "1", "default" => "", "comment" => ""],
|
"otype" => ["type" => "varchar(10)", "not null" => "1", "default" => "", "comment" => ""],
|
||||||
|
@ -926,8 +928,8 @@ return [
|
||||||
"fields" => [
|
"fields" => [
|
||||||
"id" => ["type" => "int unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1", "comment" => "sequential ID"],
|
"id" => ["type" => "int unsigned", "not null" => "1", "extra" => "auto_increment", "primary" => "1", "comment" => "sequential ID"],
|
||||||
"notify-id" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "relation" => ["notify" => "id"], "comment" => ""],
|
"notify-id" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "relation" => ["notify" => "id"], "comment" => ""],
|
||||||
"master-parent-item" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "relation" => ["item" => "id"],
|
"master-parent-item" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "relation" => ["item" => "id"], "comment" => ""],
|
||||||
"comment" => ""],
|
"master-parent-uri-id" => ["type" => "int unsigned", "relation" => ["item-uri" => "id"], "comment" => "Item-uri id of the parent of the related post"],
|
||||||
"parent-item" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "comment" => ""],
|
"parent-item" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "comment" => ""],
|
||||||
"receiver-uid" => ["type" => "mediumint unsigned", "not null" => "1", "default" => "0", "relation" => ["user" => "uid"],
|
"receiver-uid" => ["type" => "mediumint unsigned", "not null" => "1", "default" => "0", "relation" => ["user" => "uid"],
|
||||||
"comment" => "User id"],
|
"comment" => "User id"],
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2016 Hyunje Alex Jun
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
# Bower Package of perfect-scrollbar
|
||||||
|
|
||||||
|
This is the [Bower](https://bower.io/) package of perfect-scrollbar.
|
||||||
|
|
||||||
|
For details and usage please read more on [https://github.com/noraesae/perfect-scrollbar](https://github.com/noraesae/perfect-scrollbar).
|
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"name": "perfect-scrollbar",
|
||||||
|
"version": "0.6.16",
|
||||||
|
"homepage": "http://noraesae.github.io/perfect-scrollbar/",
|
||||||
|
"authors": [
|
||||||
|
"Hyunje Jun <me@noraesae.net>"
|
||||||
|
],
|
||||||
|
"description": "Minimalistic but perfect custom scrollbar plugin",
|
||||||
|
"main": [
|
||||||
|
"css/perfect-scrollbar.css",
|
||||||
|
"js/perfect-scrollbar.js"
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"ignore": [
|
||||||
|
"**/.*",
|
||||||
|
"bower_components"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
/* perfect-scrollbar v0.6.16 */
|
||||||
|
.ps-container {
|
||||||
|
-ms-touch-action: auto;
|
||||||
|
touch-action: auto;
|
||||||
|
overflow: hidden !important;
|
||||||
|
-ms-overflow-style: none; }
|
||||||
|
@supports (-ms-overflow-style: none) {
|
||||||
|
.ps-container {
|
||||||
|
overflow: auto !important; } }
|
||||||
|
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
|
||||||
|
.ps-container {
|
||||||
|
overflow: auto !important; } }
|
||||||
|
.ps-container.ps-active-x > .ps-scrollbar-x-rail,
|
||||||
|
.ps-container.ps-active-y > .ps-scrollbar-y-rail {
|
||||||
|
display: block;
|
||||||
|
background-color: transparent; }
|
||||||
|
.ps-container.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail {
|
||||||
|
background-color: #eee;
|
||||||
|
opacity: 0.9; }
|
||||||
|
.ps-container.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail > .ps-scrollbar-x {
|
||||||
|
background-color: #999;
|
||||||
|
height: 11px; }
|
||||||
|
.ps-container.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail {
|
||||||
|
background-color: #eee;
|
||||||
|
opacity: 0.9; }
|
||||||
|
.ps-container.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail > .ps-scrollbar-y {
|
||||||
|
background-color: #999;
|
||||||
|
width: 11px; }
|
||||||
|
.ps-container > .ps-scrollbar-x-rail {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
/* please don't change 'position' */
|
||||||
|
opacity: 0;
|
||||||
|
-webkit-transition: background-color .2s linear, opacity .2s linear;
|
||||||
|
-o-transition: background-color .2s linear, opacity .2s linear;
|
||||||
|
-moz-transition: background-color .2s linear, opacity .2s linear;
|
||||||
|
transition: background-color .2s linear, opacity .2s linear;
|
||||||
|
bottom: 0px;
|
||||||
|
/* there must be 'bottom' for ps-scrollbar-x-rail */
|
||||||
|
height: 15px; }
|
||||||
|
.ps-container > .ps-scrollbar-x-rail > .ps-scrollbar-x {
|
||||||
|
position: absolute;
|
||||||
|
/* please don't change 'position' */
|
||||||
|
background-color: #aaa;
|
||||||
|
-webkit-border-radius: 6px;
|
||||||
|
-moz-border-radius: 6px;
|
||||||
|
border-radius: 6px;
|
||||||
|
-webkit-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;
|
||||||
|
transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;
|
||||||
|
-o-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;
|
||||||
|
-moz-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;
|
||||||
|
transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;
|
||||||
|
transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -webkit-border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;
|
||||||
|
bottom: 2px;
|
||||||
|
/* there must be 'bottom' for ps-scrollbar-x */
|
||||||
|
height: 6px; }
|
||||||
|
.ps-container > .ps-scrollbar-x-rail:hover > .ps-scrollbar-x, .ps-container > .ps-scrollbar-x-rail:active > .ps-scrollbar-x {
|
||||||
|
height: 11px; }
|
||||||
|
.ps-container > .ps-scrollbar-y-rail {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
/* please don't change 'position' */
|
||||||
|
opacity: 0;
|
||||||
|
-webkit-transition: background-color .2s linear, opacity .2s linear;
|
||||||
|
-o-transition: background-color .2s linear, opacity .2s linear;
|
||||||
|
-moz-transition: background-color .2s linear, opacity .2s linear;
|
||||||
|
transition: background-color .2s linear, opacity .2s linear;
|
||||||
|
right: 0;
|
||||||
|
/* there must be 'right' for ps-scrollbar-y-rail */
|
||||||
|
width: 15px; }
|
||||||
|
.ps-container > .ps-scrollbar-y-rail > .ps-scrollbar-y {
|
||||||
|
position: absolute;
|
||||||
|
/* please don't change 'position' */
|
||||||
|
background-color: #aaa;
|
||||||
|
-webkit-border-radius: 6px;
|
||||||
|
-moz-border-radius: 6px;
|
||||||
|
border-radius: 6px;
|
||||||
|
-webkit-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;
|
||||||
|
transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;
|
||||||
|
-o-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;
|
||||||
|
-moz-transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;
|
||||||
|
transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;
|
||||||
|
transition: background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -webkit-border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;
|
||||||
|
right: 2px;
|
||||||
|
/* there must be 'right' for ps-scrollbar-y */
|
||||||
|
width: 6px; }
|
||||||
|
.ps-container > .ps-scrollbar-y-rail:hover > .ps-scrollbar-y, .ps-container > .ps-scrollbar-y-rail:active > .ps-scrollbar-y {
|
||||||
|
width: 11px; }
|
||||||
|
.ps-container:hover.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail {
|
||||||
|
background-color: #eee;
|
||||||
|
opacity: 0.9; }
|
||||||
|
.ps-container:hover.ps-in-scrolling.ps-x > .ps-scrollbar-x-rail > .ps-scrollbar-x {
|
||||||
|
background-color: #999;
|
||||||
|
height: 11px; }
|
||||||
|
.ps-container:hover.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail {
|
||||||
|
background-color: #eee;
|
||||||
|
opacity: 0.9; }
|
||||||
|
.ps-container:hover.ps-in-scrolling.ps-y > .ps-scrollbar-y-rail > .ps-scrollbar-y {
|
||||||
|
background-color: #999;
|
||||||
|
width: 11px; }
|
||||||
|
.ps-container:hover > .ps-scrollbar-x-rail,
|
||||||
|
.ps-container:hover > .ps-scrollbar-y-rail {
|
||||||
|
opacity: 0.6; }
|
||||||
|
.ps-container:hover > .ps-scrollbar-x-rail:hover {
|
||||||
|
background-color: #eee;
|
||||||
|
opacity: 0.9; }
|
||||||
|
.ps-container:hover > .ps-scrollbar-x-rail:hover > .ps-scrollbar-x {
|
||||||
|
background-color: #999; }
|
||||||
|
.ps-container:hover > .ps-scrollbar-y-rail:hover {
|
||||||
|
background-color: #eee;
|
||||||
|
opacity: 0.9; }
|
||||||
|
.ps-container:hover > .ps-scrollbar-y-rail:hover > .ps-scrollbar-y {
|
||||||
|
background-color: #999; }
|
|
@ -0,0 +1,2 @@
|
||||||
|
/* perfect-scrollbar v0.6.16 */
|
||||||
|
.ps-container{-ms-touch-action:auto;touch-action:auto;overflow:hidden !important;-ms-overflow-style:none}@supports (-ms-overflow-style: none){.ps-container{overflow:auto !important}}@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none){.ps-container{overflow:auto !important}}.ps-container.ps-active-x>.ps-scrollbar-x-rail,.ps-container.ps-active-y>.ps-scrollbar-y-rail{display:block;background-color:transparent}.ps-container.ps-in-scrolling.ps-x>.ps-scrollbar-x-rail{background-color:#eee;opacity:.9}.ps-container.ps-in-scrolling.ps-x>.ps-scrollbar-x-rail>.ps-scrollbar-x{background-color:#999;height:11px}.ps-container.ps-in-scrolling.ps-y>.ps-scrollbar-y-rail{background-color:#eee;opacity:.9}.ps-container.ps-in-scrolling.ps-y>.ps-scrollbar-y-rail>.ps-scrollbar-y{background-color:#999;width:11px}.ps-container>.ps-scrollbar-x-rail{display:none;position:absolute;opacity:0;-webkit-transition:background-color .2s linear, opacity .2s linear;-o-transition:background-color .2s linear, opacity .2s linear;-moz-transition:background-color .2s linear, opacity .2s linear;transition:background-color .2s linear, opacity .2s linear;bottom:0px;height:15px}.ps-container>.ps-scrollbar-x-rail>.ps-scrollbar-x{position:absolute;background-color:#aaa;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;-o-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;-moz-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -webkit-border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;bottom:2px;height:6px}.ps-container>.ps-scrollbar-x-rail:hover>.ps-scrollbar-x,.ps-container>.ps-scrollbar-x-rail:active>.ps-scrollbar-x{height:11px}.ps-container>.ps-scrollbar-y-rail{display:none;position:absolute;opacity:0;-webkit-transition:background-color .2s linear, opacity .2s linear;-o-transition:background-color .2s linear, opacity .2s linear;-moz-transition:background-color .2s linear, opacity .2s linear;transition:background-color .2s linear, opacity .2s linear;right:0;width:15px}.ps-container>.ps-scrollbar-y-rail>.ps-scrollbar-y{position:absolute;background-color:#aaa;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;-o-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;-moz-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -webkit-border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;right:2px;width:6px}.ps-container>.ps-scrollbar-y-rail:hover>.ps-scrollbar-y,.ps-container>.ps-scrollbar-y-rail:active>.ps-scrollbar-y{width:11px}.ps-container:hover.ps-in-scrolling.ps-x>.ps-scrollbar-x-rail{background-color:#eee;opacity:.9}.ps-container:hover.ps-in-scrolling.ps-x>.ps-scrollbar-x-rail>.ps-scrollbar-x{background-color:#999;height:11px}.ps-container:hover.ps-in-scrolling.ps-y>.ps-scrollbar-y-rail{background-color:#eee;opacity:.9}.ps-container:hover.ps-in-scrolling.ps-y>.ps-scrollbar-y-rail>.ps-scrollbar-y{background-color:#999;width:11px}.ps-container:hover>.ps-scrollbar-x-rail,.ps-container:hover>.ps-scrollbar-y-rail{opacity:.6}.ps-container:hover>.ps-scrollbar-x-rail:hover{background-color:#eee;opacity:.9}.ps-container:hover>.ps-scrollbar-x-rail:hover>.ps-scrollbar-x{background-color:#999}.ps-container:hover>.ps-scrollbar-y-rail:hover{background-color:#eee;opacity:.9}.ps-container:hover>.ps-scrollbar-y-rail:hover>.ps-scrollbar-y{background-color:#999}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,3 @@
|
||||||
|
@import 'variables';
|
||||||
|
@import 'mixins';
|
||||||
|
@import 'themes';
|
|
@ -0,0 +1,128 @@
|
||||||
|
@mixin scrollbar-rail-default($theme) {
|
||||||
|
display: none;
|
||||||
|
position: absolute; /* please don't change 'position' */
|
||||||
|
opacity: map_get($theme, rail-default-opacity);
|
||||||
|
transition: background-color .2s linear, opacity .2s linear;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin scrollbar-rail-hover($theme) {
|
||||||
|
background-color: map_get($theme, rail-hover-bg);
|
||||||
|
opacity: map_get($theme, rail-hover-opacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin scrollbar-default($theme) {
|
||||||
|
position: absolute; /* please don't change 'position' */
|
||||||
|
background-color: map_get($theme, bar-container-hover-bg);
|
||||||
|
border-radius: map_get($theme, border-radius);
|
||||||
|
transition: background-color .2s linear, height .2s linear, width .2s ease-in-out,
|
||||||
|
border-radius .2s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin scrollbar-hover($theme) {
|
||||||
|
background-color: map_get($theme, bar-hover-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@mixin in-scrolling($theme) {
|
||||||
|
&.ps-in-scrolling {
|
||||||
|
&.ps-x > .ps-scrollbar-x-rail {
|
||||||
|
@include scrollbar-rail-hover($theme);
|
||||||
|
> .ps-scrollbar-x {
|
||||||
|
@include scrollbar-hover($theme);
|
||||||
|
height: map_get($theme, scrollbar-x-hover-height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&.ps-y > .ps-scrollbar-y-rail {
|
||||||
|
@include scrollbar-rail-hover($theme);
|
||||||
|
> .ps-scrollbar-y {
|
||||||
|
@include scrollbar-hover($theme);
|
||||||
|
width: map_get($theme, scrollbar-y-hover-width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Layout and theme mixin
|
||||||
|
@mixin ps-container($theme) {
|
||||||
|
-ms-touch-action: auto;
|
||||||
|
touch-action: auto;
|
||||||
|
overflow: hidden !important;
|
||||||
|
-ms-overflow-style: none;
|
||||||
|
|
||||||
|
// Edge
|
||||||
|
@supports (-ms-overflow-style: none) {
|
||||||
|
overflow: auto !important;
|
||||||
|
}
|
||||||
|
// IE10+
|
||||||
|
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
|
||||||
|
overflow: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.ps-active-x > .ps-scrollbar-x-rail,
|
||||||
|
&.ps-active-y > .ps-scrollbar-y-rail {
|
||||||
|
display: block;
|
||||||
|
background-color: map_get($theme, bar-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@include in-scrolling($theme);
|
||||||
|
|
||||||
|
> .ps-scrollbar-x-rail {
|
||||||
|
@include scrollbar-rail-default($theme);
|
||||||
|
bottom: map_get($theme, scrollbar-x-rail-bottom); /* there must be 'bottom' for ps-scrollbar-x-rail */
|
||||||
|
height: map_get($theme, scrollbar-x-rail-height);
|
||||||
|
|
||||||
|
> .ps-scrollbar-x {
|
||||||
|
@include scrollbar-default($theme);
|
||||||
|
bottom: map_get($theme, scrollbar-x-bottom); /* there must be 'bottom' for ps-scrollbar-x */
|
||||||
|
height: map_get($theme, scrollbar-x-height);
|
||||||
|
}
|
||||||
|
&:hover,
|
||||||
|
&:active {
|
||||||
|
> .ps-scrollbar-x {
|
||||||
|
height: map_get($theme, scrollbar-x-hover-height);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> .ps-scrollbar-y-rail {
|
||||||
|
@include scrollbar-rail-default($theme);
|
||||||
|
right: map_get($theme, scrollbar-y-rail-right); /* there must be 'right' for ps-scrollbar-y-rail */
|
||||||
|
width: map_get($theme, scrollbar-y-rail-width);
|
||||||
|
|
||||||
|
> .ps-scrollbar-y {
|
||||||
|
@include scrollbar-default($theme);
|
||||||
|
right: map_get($theme, scrollbar-y-right); /* there must be 'right' for ps-scrollbar-y */
|
||||||
|
width: map_get($theme, scrollbar-y-width);
|
||||||
|
}
|
||||||
|
&:hover,
|
||||||
|
&:active {
|
||||||
|
> .ps-scrollbar-y {
|
||||||
|
width: map_get($theme, scrollbar-y-hover-width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
@include in-scrolling($theme);
|
||||||
|
|
||||||
|
> .ps-scrollbar-x-rail,
|
||||||
|
> .ps-scrollbar-y-rail {
|
||||||
|
opacity: map_get($theme, rail-container-hover-opacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
> .ps-scrollbar-x-rail:hover {
|
||||||
|
@include scrollbar-rail-hover($theme);
|
||||||
|
|
||||||
|
> .ps-scrollbar-x {
|
||||||
|
@include scrollbar-hover($theme);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> .ps-scrollbar-y-rail:hover {
|
||||||
|
@include scrollbar-rail-hover($theme);
|
||||||
|
|
||||||
|
> .ps-scrollbar-y {
|
||||||
|
@include scrollbar-hover($theme);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
$ps-theme-default: (
|
||||||
|
border-radius: $ps-border-radius,
|
||||||
|
rail-default-opacity: $ps-rail-default-opacity,
|
||||||
|
rail-container-hover-opacity: $ps-rail-container-hover-opacity,
|
||||||
|
rail-hover-opacity: $ps-rail-hover-opacity,
|
||||||
|
bar-bg: $ps-bar-bg,
|
||||||
|
bar-container-hover-bg: $ps-bar-container-hover-bg,
|
||||||
|
bar-hover-bg: $ps-bar-hover-bg,
|
||||||
|
rail-hover-bg: $ps-rail-hover-bg,
|
||||||
|
scrollbar-x-rail-bottom: $ps-scrollbar-x-rail-bottom,
|
||||||
|
scrollbar-x-rail-height: $ps-scrollbar-x-rail-height,
|
||||||
|
scrollbar-x-bottom: $ps-scrollbar-x-bottom,
|
||||||
|
scrollbar-x-height: $ps-scrollbar-x-height,
|
||||||
|
scrollbar-x-hover-height: $ps-scrollbar-x-hover-height,
|
||||||
|
scrollbar-y-rail-right: $ps-scrollbar-y-rail-right,
|
||||||
|
scrollbar-y-rail-width: $ps-scrollbar-y-rail-width,
|
||||||
|
scrollbar-y-right: $ps-scrollbar-y-right,
|
||||||
|
scrollbar-y-width: $ps-scrollbar-y-width,
|
||||||
|
scrollbar-y-hover-width: $ps-scrollbar-y-hover-width,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Default theme
|
||||||
|
.ps-container {
|
||||||
|
@include ps-container($ps-theme-default);
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
// Colors
|
||||||
|
$ps-border-radius: 6px !default;
|
||||||
|
|
||||||
|
$ps-rail-default-opacity: 0 !default;
|
||||||
|
$ps-rail-container-hover-opacity: 0.6 !default;
|
||||||
|
$ps-rail-hover-opacity: 0.9 !default;
|
||||||
|
|
||||||
|
$ps-bar-bg: transparent !default;
|
||||||
|
$ps-bar-container-hover-bg: #aaa !default;
|
||||||
|
$ps-bar-hover-bg: #999 !default;
|
||||||
|
$ps-rail-hover-bg: #eee !default;
|
||||||
|
|
||||||
|
// Sizes
|
||||||
|
$ps-scrollbar-x-rail-bottom: 0px !default;
|
||||||
|
$ps-scrollbar-x-rail-height: 15px !default;
|
||||||
|
$ps-scrollbar-x-bottom: 2px !default;
|
||||||
|
$ps-scrollbar-x-height: 6px !default;
|
||||||
|
$ps-scrollbar-x-hover-height: 11px !default;
|
||||||
|
|
||||||
|
$ps-scrollbar-y-rail-right: 0 !default;
|
||||||
|
$ps-scrollbar-y-rail-width: 15px !default;
|
||||||
|
$ps-scrollbar-y-right: 2px !default;
|
||||||
|
$ps-scrollbar-y-width: 6px !default;
|
||||||
|
$ps-scrollbar-y-hover-width: 11px !default;
|
|
@ -0,0 +1,14 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var ps = require('../main');
|
||||||
|
|
||||||
|
if (typeof define === 'function' && define.amd) {
|
||||||
|
// AMD
|
||||||
|
define(ps);
|
||||||
|
} else {
|
||||||
|
// Add to a global object.
|
||||||
|
window.PerfectScrollbar = ps;
|
||||||
|
if (typeof window.Ps === 'undefined') {
|
||||||
|
window.Ps = ps;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var ps = require('../main');
|
||||||
|
var psInstances = require('../plugin/instances');
|
||||||
|
|
||||||
|
function mountJQuery(jQuery) {
|
||||||
|
jQuery.fn.perfectScrollbar = function (settingOrCommand) {
|
||||||
|
return this.each(function () {
|
||||||
|
if (typeof settingOrCommand === 'object' ||
|
||||||
|
typeof settingOrCommand === 'undefined') {
|
||||||
|
// If it's an object or none, initialize.
|
||||||
|
var settings = settingOrCommand;
|
||||||
|
|
||||||
|
if (!psInstances.get(this)) {
|
||||||
|
ps.initialize(this, settings);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Unless, it may be a command.
|
||||||
|
var command = settingOrCommand;
|
||||||
|
|
||||||
|
if (command === 'update') {
|
||||||
|
ps.update(this);
|
||||||
|
} else if (command === 'destroy') {
|
||||||
|
ps.destroy(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof define === 'function' && define.amd) {
|
||||||
|
// AMD. Register as an anonymous module.
|
||||||
|
define(['jquery'], mountJQuery);
|
||||||
|
} else {
|
||||||
|
var jq = window.jQuery ? window.jQuery : window.$;
|
||||||
|
if (typeof jq !== 'undefined') {
|
||||||
|
mountJQuery(jq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = mountJQuery;
|
|
@ -0,0 +1,42 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
function oldAdd(element, className) {
|
||||||
|
var classes = element.className.split(' ');
|
||||||
|
if (classes.indexOf(className) < 0) {
|
||||||
|
classes.push(className);
|
||||||
|
}
|
||||||
|
element.className = classes.join(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
function oldRemove(element, className) {
|
||||||
|
var classes = element.className.split(' ');
|
||||||
|
var idx = classes.indexOf(className);
|
||||||
|
if (idx >= 0) {
|
||||||
|
classes.splice(idx, 1);
|
||||||
|
}
|
||||||
|
element.className = classes.join(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.add = function (element, className) {
|
||||||
|
if (element.classList) {
|
||||||
|
element.classList.add(className);
|
||||||
|
} else {
|
||||||
|
oldAdd(element, className);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.remove = function (element, className) {
|
||||||
|
if (element.classList) {
|
||||||
|
element.classList.remove(className);
|
||||||
|
} else {
|
||||||
|
oldRemove(element, className);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.list = function (element) {
|
||||||
|
if (element.classList) {
|
||||||
|
return Array.prototype.slice.apply(element.classList);
|
||||||
|
} else {
|
||||||
|
return element.className.split(' ');
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,84 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var DOM = {};
|
||||||
|
|
||||||
|
DOM.e = function (tagName, className) {
|
||||||
|
var element = document.createElement(tagName);
|
||||||
|
element.className = className;
|
||||||
|
return element;
|
||||||
|
};
|
||||||
|
|
||||||
|
DOM.appendTo = function (child, parent) {
|
||||||
|
parent.appendChild(child);
|
||||||
|
return child;
|
||||||
|
};
|
||||||
|
|
||||||
|
function cssGet(element, styleName) {
|
||||||
|
return window.getComputedStyle(element)[styleName];
|
||||||
|
}
|
||||||
|
|
||||||
|
function cssSet(element, styleName, styleValue) {
|
||||||
|
if (typeof styleValue === 'number') {
|
||||||
|
styleValue = styleValue.toString() + 'px';
|
||||||
|
}
|
||||||
|
element.style[styleName] = styleValue;
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
function cssMultiSet(element, obj) {
|
||||||
|
for (var key in obj) {
|
||||||
|
var val = obj[key];
|
||||||
|
if (typeof val === 'number') {
|
||||||
|
val = val.toString() + 'px';
|
||||||
|
}
|
||||||
|
element.style[key] = val;
|
||||||
|
}
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
DOM.css = function (element, styleNameOrObject, styleValue) {
|
||||||
|
if (typeof styleNameOrObject === 'object') {
|
||||||
|
// multiple set with object
|
||||||
|
return cssMultiSet(element, styleNameOrObject);
|
||||||
|
} else {
|
||||||
|
if (typeof styleValue === 'undefined') {
|
||||||
|
return cssGet(element, styleNameOrObject);
|
||||||
|
} else {
|
||||||
|
return cssSet(element, styleNameOrObject, styleValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
DOM.matches = function (element, query) {
|
||||||
|
if (typeof element.matches !== 'undefined') {
|
||||||
|
return element.matches(query);
|
||||||
|
} else {
|
||||||
|
if (typeof element.matchesSelector !== 'undefined') {
|
||||||
|
return element.matchesSelector(query);
|
||||||
|
} else if (typeof element.webkitMatchesSelector !== 'undefined') {
|
||||||
|
return element.webkitMatchesSelector(query);
|
||||||
|
} else if (typeof element.mozMatchesSelector !== 'undefined') {
|
||||||
|
return element.mozMatchesSelector(query);
|
||||||
|
} else if (typeof element.msMatchesSelector !== 'undefined') {
|
||||||
|
return element.msMatchesSelector(query);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
DOM.remove = function (element) {
|
||||||
|
if (typeof element.remove !== 'undefined') {
|
||||||
|
element.remove();
|
||||||
|
} else {
|
||||||
|
if (element.parentNode) {
|
||||||
|
element.parentNode.removeChild(element);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
DOM.queryChildren = function (element, selector) {
|
||||||
|
return Array.prototype.filter.call(element.childNodes, function (child) {
|
||||||
|
return DOM.matches(child, selector);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = DOM;
|
|
@ -0,0 +1,71 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var EventElement = function (element) {
|
||||||
|
this.element = element;
|
||||||
|
this.events = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
EventElement.prototype.bind = function (eventName, handler) {
|
||||||
|
if (typeof this.events[eventName] === 'undefined') {
|
||||||
|
this.events[eventName] = [];
|
||||||
|
}
|
||||||
|
this.events[eventName].push(handler);
|
||||||
|
this.element.addEventListener(eventName, handler, false);
|
||||||
|
};
|
||||||
|
|
||||||
|
EventElement.prototype.unbind = function (eventName, handler) {
|
||||||
|
var isHandlerProvided = (typeof handler !== 'undefined');
|
||||||
|
this.events[eventName] = this.events[eventName].filter(function (hdlr) {
|
||||||
|
if (isHandlerProvided && hdlr !== handler) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
this.element.removeEventListener(eventName, hdlr, false);
|
||||||
|
return false;
|
||||||
|
}, this);
|
||||||
|
};
|
||||||
|
|
||||||
|
EventElement.prototype.unbindAll = function () {
|
||||||
|
for (var name in this.events) {
|
||||||
|
this.unbind(name);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var EventManager = function () {
|
||||||
|
this.eventElements = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
EventManager.prototype.eventElement = function (element) {
|
||||||
|
var ee = this.eventElements.filter(function (eventElement) {
|
||||||
|
return eventElement.element === element;
|
||||||
|
})[0];
|
||||||
|
if (typeof ee === 'undefined') {
|
||||||
|
ee = new EventElement(element);
|
||||||
|
this.eventElements.push(ee);
|
||||||
|
}
|
||||||
|
return ee;
|
||||||
|
};
|
||||||
|
|
||||||
|
EventManager.prototype.bind = function (element, eventName, handler) {
|
||||||
|
this.eventElement(element).bind(eventName, handler);
|
||||||
|
};
|
||||||
|
|
||||||
|
EventManager.prototype.unbind = function (element, eventName, handler) {
|
||||||
|
this.eventElement(element).unbind(eventName, handler);
|
||||||
|
};
|
||||||
|
|
||||||
|
EventManager.prototype.unbindAll = function () {
|
||||||
|
for (var i = 0; i < this.eventElements.length; i++) {
|
||||||
|
this.eventElements[i].unbindAll();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
EventManager.prototype.once = function (element, eventName, handler) {
|
||||||
|
var ee = this.eventElement(element);
|
||||||
|
var onceHandler = function (e) {
|
||||||
|
ee.unbind(eventName, onceHandler);
|
||||||
|
handler(e);
|
||||||
|
};
|
||||||
|
ee.bind(eventName, onceHandler);
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = EventManager;
|
|
@ -0,0 +1,13 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = (function () {
|
||||||
|
function s4() {
|
||||||
|
return Math.floor((1 + Math.random()) * 0x10000)
|
||||||
|
.toString(16)
|
||||||
|
.substring(1);
|
||||||
|
}
|
||||||
|
return function () {
|
||||||
|
return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
|
||||||
|
s4() + '-' + s4() + s4() + s4();
|
||||||
|
};
|
||||||
|
})();
|
|
@ -0,0 +1,83 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var cls = require('./class');
|
||||||
|
var dom = require('./dom');
|
||||||
|
|
||||||
|
var toInt = exports.toInt = function (x) {
|
||||||
|
return parseInt(x, 10) || 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
var clone = exports.clone = function (obj) {
|
||||||
|
if (!obj) {
|
||||||
|
return null;
|
||||||
|
} else if (obj.constructor === Array) {
|
||||||
|
return obj.map(clone);
|
||||||
|
} else if (typeof obj === 'object') {
|
||||||
|
var result = {};
|
||||||
|
for (var key in obj) {
|
||||||
|
result[key] = clone(obj[key]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.extend = function (original, source) {
|
||||||
|
var result = clone(original);
|
||||||
|
for (var key in source) {
|
||||||
|
result[key] = clone(source[key]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.isEditable = function (el) {
|
||||||
|
return dom.matches(el, "input,[contenteditable]") ||
|
||||||
|
dom.matches(el, "select,[contenteditable]") ||
|
||||||
|
dom.matches(el, "textarea,[contenteditable]") ||
|
||||||
|
dom.matches(el, "button,[contenteditable]");
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.removePsClasses = function (element) {
|
||||||
|
var clsList = cls.list(element);
|
||||||
|
for (var i = 0; i < clsList.length; i++) {
|
||||||
|
var className = clsList[i];
|
||||||
|
if (className.indexOf('ps-') === 0) {
|
||||||
|
cls.remove(element, className);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.outerWidth = function (element) {
|
||||||
|
return toInt(dom.css(element, 'width')) +
|
||||||
|
toInt(dom.css(element, 'paddingLeft')) +
|
||||||
|
toInt(dom.css(element, 'paddingRight')) +
|
||||||
|
toInt(dom.css(element, 'borderLeftWidth')) +
|
||||||
|
toInt(dom.css(element, 'borderRightWidth'));
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.startScrolling = function (element, axis) {
|
||||||
|
cls.add(element, 'ps-in-scrolling');
|
||||||
|
if (typeof axis !== 'undefined') {
|
||||||
|
cls.add(element, 'ps-' + axis);
|
||||||
|
} else {
|
||||||
|
cls.add(element, 'ps-x');
|
||||||
|
cls.add(element, 'ps-y');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.stopScrolling = function (element, axis) {
|
||||||
|
cls.remove(element, 'ps-in-scrolling');
|
||||||
|
if (typeof axis !== 'undefined') {
|
||||||
|
cls.remove(element, 'ps-' + axis);
|
||||||
|
} else {
|
||||||
|
cls.remove(element, 'ps-x');
|
||||||
|
cls.remove(element, 'ps-y');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.env = {
|
||||||
|
isWebKit: 'WebkitAppearance' in document.documentElement.style,
|
||||||
|
supportsTouch: (('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch),
|
||||||
|
supportsIePointer: window.navigator.msMaxTouchPoints !== null
|
||||||
|
};
|
|
@ -0,0 +1,11 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var destroy = require('./plugin/destroy');
|
||||||
|
var initialize = require('./plugin/initialize');
|
||||||
|
var update = require('./plugin/update');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
initialize: initialize,
|
||||||
|
update: update,
|
||||||
|
destroy: destroy
|
||||||
|
};
|
|
@ -0,0 +1,16 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
handlers: ['click-rail', 'drag-scrollbar', 'keyboard', 'wheel', 'touch'],
|
||||||
|
maxScrollbarLength: null,
|
||||||
|
minScrollbarLength: null,
|
||||||
|
scrollXMarginOffset: 0,
|
||||||
|
scrollYMarginOffset: 0,
|
||||||
|
suppressScrollX: false,
|
||||||
|
suppressScrollY: false,
|
||||||
|
swipePropagation: true,
|
||||||
|
useBothWheelAxes: false,
|
||||||
|
wheelPropagation: false,
|
||||||
|
wheelSpeed: 1,
|
||||||
|
theme: 'default'
|
||||||
|
};
|
|
@ -0,0 +1,22 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var _ = require('../lib/helper');
|
||||||
|
var dom = require('../lib/dom');
|
||||||
|
var instances = require('./instances');
|
||||||
|
|
||||||
|
module.exports = function (element) {
|
||||||
|
var i = instances.get(element);
|
||||||
|
|
||||||
|
if (!i) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
i.event.unbindAll();
|
||||||
|
dom.remove(i.scrollbarX);
|
||||||
|
dom.remove(i.scrollbarY);
|
||||||
|
dom.remove(i.scrollbarXRail);
|
||||||
|
dom.remove(i.scrollbarYRail);
|
||||||
|
_.removePsClasses(element);
|
||||||
|
|
||||||
|
instances.remove(element);
|
||||||
|
};
|
|
@ -0,0 +1,39 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var instances = require('../instances');
|
||||||
|
var updateGeometry = require('../update-geometry');
|
||||||
|
var updateScroll = require('../update-scroll');
|
||||||
|
|
||||||
|
function bindClickRailHandler(element, i) {
|
||||||
|
function pageOffset(el) {
|
||||||
|
return el.getBoundingClientRect();
|
||||||
|
}
|
||||||
|
var stopPropagation = function (e) { e.stopPropagation(); };
|
||||||
|
|
||||||
|
i.event.bind(i.scrollbarY, 'click', stopPropagation);
|
||||||
|
i.event.bind(i.scrollbarYRail, 'click', function (e) {
|
||||||
|
var positionTop = e.pageY - window.pageYOffset - pageOffset(i.scrollbarYRail).top;
|
||||||
|
var direction = positionTop > i.scrollbarYTop ? 1 : -1;
|
||||||
|
|
||||||
|
updateScroll(element, 'top', element.scrollTop + direction * i.containerHeight);
|
||||||
|
updateGeometry(element);
|
||||||
|
|
||||||
|
e.stopPropagation();
|
||||||
|
});
|
||||||
|
|
||||||
|
i.event.bind(i.scrollbarX, 'click', stopPropagation);
|
||||||
|
i.event.bind(i.scrollbarXRail, 'click', function (e) {
|
||||||
|
var positionLeft = e.pageX - window.pageXOffset - pageOffset(i.scrollbarXRail).left;
|
||||||
|
var direction = positionLeft > i.scrollbarXLeft ? 1 : -1;
|
||||||
|
|
||||||
|
updateScroll(element, 'left', element.scrollLeft + direction * i.containerWidth);
|
||||||
|
updateGeometry(element);
|
||||||
|
|
||||||
|
e.stopPropagation();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function (element) {
|
||||||
|
var i = instances.get(element);
|
||||||
|
bindClickRailHandler(element, i);
|
||||||
|
};
|
|
@ -0,0 +1,103 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var _ = require('../../lib/helper');
|
||||||
|
var dom = require('../../lib/dom');
|
||||||
|
var instances = require('../instances');
|
||||||
|
var updateGeometry = require('../update-geometry');
|
||||||
|
var updateScroll = require('../update-scroll');
|
||||||
|
|
||||||
|
function bindMouseScrollXHandler(element, i) {
|
||||||
|
var currentLeft = null;
|
||||||
|
var currentPageX = null;
|
||||||
|
|
||||||
|
function updateScrollLeft(deltaX) {
|
||||||
|
var newLeft = currentLeft + (deltaX * i.railXRatio);
|
||||||
|
var maxLeft = Math.max(0, i.scrollbarXRail.getBoundingClientRect().left) + (i.railXRatio * (i.railXWidth - i.scrollbarXWidth));
|
||||||
|
|
||||||
|
if (newLeft < 0) {
|
||||||
|
i.scrollbarXLeft = 0;
|
||||||
|
} else if (newLeft > maxLeft) {
|
||||||
|
i.scrollbarXLeft = maxLeft;
|
||||||
|
} else {
|
||||||
|
i.scrollbarXLeft = newLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
var scrollLeft = _.toInt(i.scrollbarXLeft * (i.contentWidth - i.containerWidth) / (i.containerWidth - (i.railXRatio * i.scrollbarXWidth))) - i.negativeScrollAdjustment;
|
||||||
|
updateScroll(element, 'left', scrollLeft);
|
||||||
|
}
|
||||||
|
|
||||||
|
var mouseMoveHandler = function (e) {
|
||||||
|
updateScrollLeft(e.pageX - currentPageX);
|
||||||
|
updateGeometry(element);
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
};
|
||||||
|
|
||||||
|
var mouseUpHandler = function () {
|
||||||
|
_.stopScrolling(element, 'x');
|
||||||
|
i.event.unbind(i.ownerDocument, 'mousemove', mouseMoveHandler);
|
||||||
|
};
|
||||||
|
|
||||||
|
i.event.bind(i.scrollbarX, 'mousedown', function (e) {
|
||||||
|
currentPageX = e.pageX;
|
||||||
|
currentLeft = _.toInt(dom.css(i.scrollbarX, 'left')) * i.railXRatio;
|
||||||
|
_.startScrolling(element, 'x');
|
||||||
|
|
||||||
|
i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler);
|
||||||
|
i.event.once(i.ownerDocument, 'mouseup', mouseUpHandler);
|
||||||
|
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function bindMouseScrollYHandler(element, i) {
|
||||||
|
var currentTop = null;
|
||||||
|
var currentPageY = null;
|
||||||
|
|
||||||
|
function updateScrollTop(deltaY) {
|
||||||
|
var newTop = currentTop + (deltaY * i.railYRatio);
|
||||||
|
var maxTop = Math.max(0, i.scrollbarYRail.getBoundingClientRect().top) + (i.railYRatio * (i.railYHeight - i.scrollbarYHeight));
|
||||||
|
|
||||||
|
if (newTop < 0) {
|
||||||
|
i.scrollbarYTop = 0;
|
||||||
|
} else if (newTop > maxTop) {
|
||||||
|
i.scrollbarYTop = maxTop;
|
||||||
|
} else {
|
||||||
|
i.scrollbarYTop = newTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
var scrollTop = _.toInt(i.scrollbarYTop * (i.contentHeight - i.containerHeight) / (i.containerHeight - (i.railYRatio * i.scrollbarYHeight)));
|
||||||
|
updateScroll(element, 'top', scrollTop);
|
||||||
|
}
|
||||||
|
|
||||||
|
var mouseMoveHandler = function (e) {
|
||||||
|
updateScrollTop(e.pageY - currentPageY);
|
||||||
|
updateGeometry(element);
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
};
|
||||||
|
|
||||||
|
var mouseUpHandler = function () {
|
||||||
|
_.stopScrolling(element, 'y');
|
||||||
|
i.event.unbind(i.ownerDocument, 'mousemove', mouseMoveHandler);
|
||||||
|
};
|
||||||
|
|
||||||
|
i.event.bind(i.scrollbarY, 'mousedown', function (e) {
|
||||||
|
currentPageY = e.pageY;
|
||||||
|
currentTop = _.toInt(dom.css(i.scrollbarY, 'top')) * i.railYRatio;
|
||||||
|
_.startScrolling(element, 'y');
|
||||||
|
|
||||||
|
i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler);
|
||||||
|
i.event.once(i.ownerDocument, 'mouseup', mouseUpHandler);
|
||||||
|
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function (element) {
|
||||||
|
var i = instances.get(element);
|
||||||
|
bindMouseScrollXHandler(element, i);
|
||||||
|
bindMouseScrollYHandler(element, i);
|
||||||
|
};
|
|
@ -0,0 +1,154 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var _ = require('../../lib/helper');
|
||||||
|
var dom = require('../../lib/dom');
|
||||||
|
var instances = require('../instances');
|
||||||
|
var updateGeometry = require('../update-geometry');
|
||||||
|
var updateScroll = require('../update-scroll');
|
||||||
|
|
||||||
|
function bindKeyboardHandler(element, i) {
|
||||||
|
var hovered = false;
|
||||||
|
i.event.bind(element, 'mouseenter', function () {
|
||||||
|
hovered = true;
|
||||||
|
});
|
||||||
|
i.event.bind(element, 'mouseleave', function () {
|
||||||
|
hovered = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
var shouldPrevent = false;
|
||||||
|
function shouldPreventDefault(deltaX, deltaY) {
|
||||||
|
var scrollTop = element.scrollTop;
|
||||||
|
if (deltaX === 0) {
|
||||||
|
if (!i.scrollbarYActive) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((scrollTop === 0 && deltaY > 0) || (scrollTop >= i.contentHeight - i.containerHeight && deltaY < 0)) {
|
||||||
|
return !i.settings.wheelPropagation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var scrollLeft = element.scrollLeft;
|
||||||
|
if (deltaY === 0) {
|
||||||
|
if (!i.scrollbarXActive) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((scrollLeft === 0 && deltaX < 0) || (scrollLeft >= i.contentWidth - i.containerWidth && deltaX > 0)) {
|
||||||
|
return !i.settings.wheelPropagation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
i.event.bind(i.ownerDocument, 'keydown', function (e) {
|
||||||
|
if ((e.isDefaultPrevented && e.isDefaultPrevented()) || e.defaultPrevented) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var focused = dom.matches(i.scrollbarX, ':focus') ||
|
||||||
|
dom.matches(i.scrollbarY, ':focus');
|
||||||
|
|
||||||
|
if (!hovered && !focused) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var activeElement = document.activeElement ? document.activeElement : i.ownerDocument.activeElement;
|
||||||
|
if (activeElement) {
|
||||||
|
if (activeElement.tagName === 'IFRAME') {
|
||||||
|
activeElement = activeElement.contentDocument.activeElement;
|
||||||
|
} else {
|
||||||
|
// go deeper if element is a webcomponent
|
||||||
|
while (activeElement.shadowRoot) {
|
||||||
|
activeElement = activeElement.shadowRoot.activeElement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_.isEditable(activeElement)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var deltaX = 0;
|
||||||
|
var deltaY = 0;
|
||||||
|
|
||||||
|
switch (e.which) {
|
||||||
|
case 37: // left
|
||||||
|
if (e.metaKey) {
|
||||||
|
deltaX = -i.contentWidth;
|
||||||
|
} else if (e.altKey) {
|
||||||
|
deltaX = -i.containerWidth;
|
||||||
|
} else {
|
||||||
|
deltaX = -30;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 38: // up
|
||||||
|
if (e.metaKey) {
|
||||||
|
deltaY = i.contentHeight;
|
||||||
|
} else if (e.altKey) {
|
||||||
|
deltaY = i.containerHeight;
|
||||||
|
} else {
|
||||||
|
deltaY = 30;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 39: // right
|
||||||
|
if (e.metaKey) {
|
||||||
|
deltaX = i.contentWidth;
|
||||||
|
} else if (e.altKey) {
|
||||||
|
deltaX = i.containerWidth;
|
||||||
|
} else {
|
||||||
|
deltaX = 30;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 40: // down
|
||||||
|
if (e.metaKey) {
|
||||||
|
deltaY = -i.contentHeight;
|
||||||
|
} else if (e.altKey) {
|
||||||
|
deltaY = -i.containerHeight;
|
||||||
|
} else {
|
||||||
|
deltaY = -30;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 33: // page up
|
||||||
|
deltaY = 90;
|
||||||
|
break;
|
||||||
|
case 32: // space bar
|
||||||
|
if (e.shiftKey) {
|
||||||
|
deltaY = 90;
|
||||||
|
} else {
|
||||||
|
deltaY = -90;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 34: // page down
|
||||||
|
deltaY = -90;
|
||||||
|
break;
|
||||||
|
case 35: // end
|
||||||
|
if (e.ctrlKey) {
|
||||||
|
deltaY = -i.contentHeight;
|
||||||
|
} else {
|
||||||
|
deltaY = -i.containerHeight;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 36: // home
|
||||||
|
if (e.ctrlKey) {
|
||||||
|
deltaY = element.scrollTop;
|
||||||
|
} else {
|
||||||
|
deltaY = i.containerHeight;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateScroll(element, 'top', element.scrollTop - deltaY);
|
||||||
|
updateScroll(element, 'left', element.scrollLeft + deltaX);
|
||||||
|
updateGeometry(element);
|
||||||
|
|
||||||
|
shouldPrevent = shouldPreventDefault(deltaX, deltaY);
|
||||||
|
if (shouldPrevent) {
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function (element) {
|
||||||
|
var i = instances.get(element);
|
||||||
|
bindKeyboardHandler(element, i);
|
||||||
|
};
|
|
@ -0,0 +1,141 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var instances = require('../instances');
|
||||||
|
var updateGeometry = require('../update-geometry');
|
||||||
|
var updateScroll = require('../update-scroll');
|
||||||
|
|
||||||
|
function bindMouseWheelHandler(element, i) {
|
||||||
|
var shouldPrevent = false;
|
||||||
|
|
||||||
|
function shouldPreventDefault(deltaX, deltaY) {
|
||||||
|
var scrollTop = element.scrollTop;
|
||||||
|
if (deltaX === 0) {
|
||||||
|
if (!i.scrollbarYActive) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((scrollTop === 0 && deltaY > 0) || (scrollTop >= i.contentHeight - i.containerHeight && deltaY < 0)) {
|
||||||
|
return !i.settings.wheelPropagation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var scrollLeft = element.scrollLeft;
|
||||||
|
if (deltaY === 0) {
|
||||||
|
if (!i.scrollbarXActive) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((scrollLeft === 0 && deltaX < 0) || (scrollLeft >= i.contentWidth - i.containerWidth && deltaX > 0)) {
|
||||||
|
return !i.settings.wheelPropagation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getDeltaFromEvent(e) {
|
||||||
|
var deltaX = e.deltaX;
|
||||||
|
var deltaY = -1 * e.deltaY;
|
||||||
|
|
||||||
|
if (typeof deltaX === "undefined" || typeof deltaY === "undefined") {
|
||||||
|
// OS X Safari
|
||||||
|
deltaX = -1 * e.wheelDeltaX / 6;
|
||||||
|
deltaY = e.wheelDeltaY / 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.deltaMode && e.deltaMode === 1) {
|
||||||
|
// Firefox in deltaMode 1: Line scrolling
|
||||||
|
deltaX *= 10;
|
||||||
|
deltaY *= 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (deltaX !== deltaX && deltaY !== deltaY/* NaN checks */) {
|
||||||
|
// IE in some mouse drivers
|
||||||
|
deltaX = 0;
|
||||||
|
deltaY = e.wheelDelta;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.shiftKey) {
|
||||||
|
// reverse axis with shift key
|
||||||
|
return [-deltaY, -deltaX];
|
||||||
|
}
|
||||||
|
return [deltaX, deltaY];
|
||||||
|
}
|
||||||
|
|
||||||
|
function shouldBeConsumedByChild(deltaX, deltaY) {
|
||||||
|
var child = element.querySelector('textarea:hover, select[multiple]:hover, .ps-child:hover');
|
||||||
|
if (child) {
|
||||||
|
if (!window.getComputedStyle(child).overflow.match(/(scroll|auto)/)) {
|
||||||
|
// if not scrollable
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var maxScrollTop = child.scrollHeight - child.clientHeight;
|
||||||
|
if (maxScrollTop > 0) {
|
||||||
|
if (!(child.scrollTop === 0 && deltaY > 0) && !(child.scrollTop === maxScrollTop && deltaY < 0)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var maxScrollLeft = child.scrollLeft - child.clientWidth;
|
||||||
|
if (maxScrollLeft > 0) {
|
||||||
|
if (!(child.scrollLeft === 0 && deltaX < 0) && !(child.scrollLeft === maxScrollLeft && deltaX > 0)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function mousewheelHandler(e) {
|
||||||
|
var delta = getDeltaFromEvent(e);
|
||||||
|
|
||||||
|
var deltaX = delta[0];
|
||||||
|
var deltaY = delta[1];
|
||||||
|
|
||||||
|
if (shouldBeConsumedByChild(deltaX, deltaY)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldPrevent = false;
|
||||||
|
if (!i.settings.useBothWheelAxes) {
|
||||||
|
// deltaX will only be used for horizontal scrolling and deltaY will
|
||||||
|
// only be used for vertical scrolling - this is the default
|
||||||
|
updateScroll(element, 'top', element.scrollTop - (deltaY * i.settings.wheelSpeed));
|
||||||
|
updateScroll(element, 'left', element.scrollLeft + (deltaX * i.settings.wheelSpeed));
|
||||||
|
} else if (i.scrollbarYActive && !i.scrollbarXActive) {
|
||||||
|
// only vertical scrollbar is active and useBothWheelAxes option is
|
||||||
|
// active, so let's scroll vertical bar using both mouse wheel axes
|
||||||
|
if (deltaY) {
|
||||||
|
updateScroll(element, 'top', element.scrollTop - (deltaY * i.settings.wheelSpeed));
|
||||||
|
} else {
|
||||||
|
updateScroll(element, 'top', element.scrollTop + (deltaX * i.settings.wheelSpeed));
|
||||||
|
}
|
||||||
|
shouldPrevent = true;
|
||||||
|
} else if (i.scrollbarXActive && !i.scrollbarYActive) {
|
||||||
|
// useBothWheelAxes and only horizontal bar is active, so use both
|
||||||
|
// wheel axes for horizontal bar
|
||||||
|
if (deltaX) {
|
||||||
|
updateScroll(element, 'left', element.scrollLeft + (deltaX * i.settings.wheelSpeed));
|
||||||
|
} else {
|
||||||
|
updateScroll(element, 'left', element.scrollLeft - (deltaY * i.settings.wheelSpeed));
|
||||||
|
}
|
||||||
|
shouldPrevent = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateGeometry(element);
|
||||||
|
|
||||||
|
shouldPrevent = (shouldPrevent || shouldPreventDefault(deltaX, deltaY));
|
||||||
|
if (shouldPrevent) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof window.onwheel !== "undefined") {
|
||||||
|
i.event.bind(element, 'wheel', mousewheelHandler);
|
||||||
|
} else if (typeof window.onmousewheel !== "undefined") {
|
||||||
|
i.event.bind(element, 'mousewheel', mousewheelHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function (element) {
|
||||||
|
var i = instances.get(element);
|
||||||
|
bindMouseWheelHandler(element, i);
|
||||||
|
};
|
|
@ -0,0 +1,15 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var instances = require('../instances');
|
||||||
|
var updateGeometry = require('../update-geometry');
|
||||||
|
|
||||||
|
function bindNativeScrollHandler(element, i) {
|
||||||
|
i.event.bind(element, 'scroll', function () {
|
||||||
|
updateGeometry(element);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function (element) {
|
||||||
|
var i = instances.get(element);
|
||||||
|
bindNativeScrollHandler(element, i);
|
||||||
|
};
|
|
@ -0,0 +1,115 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var _ = require('../../lib/helper');
|
||||||
|
var instances = require('../instances');
|
||||||
|
var updateGeometry = require('../update-geometry');
|
||||||
|
var updateScroll = require('../update-scroll');
|
||||||
|
|
||||||
|
function bindSelectionHandler(element, i) {
|
||||||
|
function getRangeNode() {
|
||||||
|
var selection = window.getSelection ? window.getSelection() :
|
||||||
|
document.getSelection ? document.getSelection() : '';
|
||||||
|
if (selection.toString().length === 0) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return selection.getRangeAt(0).commonAncestorContainer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var scrollingLoop = null;
|
||||||
|
var scrollDiff = {top: 0, left: 0};
|
||||||
|
function startScrolling() {
|
||||||
|
if (!scrollingLoop) {
|
||||||
|
scrollingLoop = setInterval(function () {
|
||||||
|
if (!instances.get(element)) {
|
||||||
|
clearInterval(scrollingLoop);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateScroll(element, 'top', element.scrollTop + scrollDiff.top);
|
||||||
|
updateScroll(element, 'left', element.scrollLeft + scrollDiff.left);
|
||||||
|
updateGeometry(element);
|
||||||
|
}, 50); // every .1 sec
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function stopScrolling() {
|
||||||
|
if (scrollingLoop) {
|
||||||
|
clearInterval(scrollingLoop);
|
||||||
|
scrollingLoop = null;
|
||||||
|
}
|
||||||
|
_.stopScrolling(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
var isSelected = false;
|
||||||
|
i.event.bind(i.ownerDocument, 'selectionchange', function () {
|
||||||
|
if (element.contains(getRangeNode())) {
|
||||||
|
isSelected = true;
|
||||||
|
} else {
|
||||||
|
isSelected = false;
|
||||||
|
stopScrolling();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
i.event.bind(window, 'mouseup', function () {
|
||||||
|
if (isSelected) {
|
||||||
|
isSelected = false;
|
||||||
|
stopScrolling();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
i.event.bind(window, 'keyup', function () {
|
||||||
|
if (isSelected) {
|
||||||
|
isSelected = false;
|
||||||
|
stopScrolling();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
i.event.bind(window, 'mousemove', function (e) {
|
||||||
|
if (isSelected) {
|
||||||
|
var mousePosition = {x: e.pageX, y: e.pageY};
|
||||||
|
var containerGeometry = {
|
||||||
|
left: element.offsetLeft,
|
||||||
|
right: element.offsetLeft + element.offsetWidth,
|
||||||
|
top: element.offsetTop,
|
||||||
|
bottom: element.offsetTop + element.offsetHeight
|
||||||
|
};
|
||||||
|
|
||||||
|
if (mousePosition.x < containerGeometry.left + 3) {
|
||||||
|
scrollDiff.left = -5;
|
||||||
|
_.startScrolling(element, 'x');
|
||||||
|
} else if (mousePosition.x > containerGeometry.right - 3) {
|
||||||
|
scrollDiff.left = 5;
|
||||||
|
_.startScrolling(element, 'x');
|
||||||
|
} else {
|
||||||
|
scrollDiff.left = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mousePosition.y < containerGeometry.top + 3) {
|
||||||
|
if (containerGeometry.top + 3 - mousePosition.y < 5) {
|
||||||
|
scrollDiff.top = -5;
|
||||||
|
} else {
|
||||||
|
scrollDiff.top = -20;
|
||||||
|
}
|
||||||
|
_.startScrolling(element, 'y');
|
||||||
|
} else if (mousePosition.y > containerGeometry.bottom - 3) {
|
||||||
|
if (mousePosition.y - containerGeometry.bottom + 3 < 5) {
|
||||||
|
scrollDiff.top = 5;
|
||||||
|
} else {
|
||||||
|
scrollDiff.top = 20;
|
||||||
|
}
|
||||||
|
_.startScrolling(element, 'y');
|
||||||
|
} else {
|
||||||
|
scrollDiff.top = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scrollDiff.top === 0 && scrollDiff.left === 0) {
|
||||||
|
stopScrolling();
|
||||||
|
} else {
|
||||||
|
startScrolling();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function (element) {
|
||||||
|
var i = instances.get(element);
|
||||||
|
bindSelectionHandler(element, i);
|
||||||
|
};
|
|
@ -0,0 +1,179 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var _ = require('../../lib/helper');
|
||||||
|
var instances = require('../instances');
|
||||||
|
var updateGeometry = require('../update-geometry');
|
||||||
|
var updateScroll = require('../update-scroll');
|
||||||
|
|
||||||
|
function bindTouchHandler(element, i, supportsTouch, supportsIePointer) {
|
||||||
|
function shouldPreventDefault(deltaX, deltaY) {
|
||||||
|
var scrollTop = element.scrollTop;
|
||||||
|
var scrollLeft = element.scrollLeft;
|
||||||
|
var magnitudeX = Math.abs(deltaX);
|
||||||
|
var magnitudeY = Math.abs(deltaY);
|
||||||
|
|
||||||
|
if (magnitudeY > magnitudeX) {
|
||||||
|
// user is perhaps trying to swipe up/down the page
|
||||||
|
|
||||||
|
if (((deltaY < 0) && (scrollTop === i.contentHeight - i.containerHeight)) ||
|
||||||
|
((deltaY > 0) && (scrollTop === 0))) {
|
||||||
|
return !i.settings.swipePropagation;
|
||||||
|
}
|
||||||
|
} else if (magnitudeX > magnitudeY) {
|
||||||
|
// user is perhaps trying to swipe left/right across the page
|
||||||
|
|
||||||
|
if (((deltaX < 0) && (scrollLeft === i.contentWidth - i.containerWidth)) ||
|
||||||
|
((deltaX > 0) && (scrollLeft === 0))) {
|
||||||
|
return !i.settings.swipePropagation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function applyTouchMove(differenceX, differenceY) {
|
||||||
|
updateScroll(element, 'top', element.scrollTop - differenceY);
|
||||||
|
updateScroll(element, 'left', element.scrollLeft - differenceX);
|
||||||
|
|
||||||
|
updateGeometry(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
var startOffset = {};
|
||||||
|
var startTime = 0;
|
||||||
|
var speed = {};
|
||||||
|
var easingLoop = null;
|
||||||
|
var inGlobalTouch = false;
|
||||||
|
var inLocalTouch = false;
|
||||||
|
|
||||||
|
function globalTouchStart() {
|
||||||
|
inGlobalTouch = true;
|
||||||
|
}
|
||||||
|
function globalTouchEnd() {
|
||||||
|
inGlobalTouch = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTouch(e) {
|
||||||
|
if (e.targetTouches) {
|
||||||
|
return e.targetTouches[0];
|
||||||
|
} else {
|
||||||
|
// Maybe IE pointer
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function shouldHandle(e) {
|
||||||
|
if (e.targetTouches && e.targetTouches.length === 1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (e.pointerType && e.pointerType !== 'mouse' && e.pointerType !== e.MSPOINTER_TYPE_MOUSE) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
function touchStart(e) {
|
||||||
|
if (shouldHandle(e)) {
|
||||||
|
inLocalTouch = true;
|
||||||
|
|
||||||
|
var touch = getTouch(e);
|
||||||
|
|
||||||
|
startOffset.pageX = touch.pageX;
|
||||||
|
startOffset.pageY = touch.pageY;
|
||||||
|
|
||||||
|
startTime = (new Date()).getTime();
|
||||||
|
|
||||||
|
if (easingLoop !== null) {
|
||||||
|
clearInterval(easingLoop);
|
||||||
|
}
|
||||||
|
|
||||||
|
e.stopPropagation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function touchMove(e) {
|
||||||
|
if (!inLocalTouch && i.settings.swipePropagation) {
|
||||||
|
touchStart(e);
|
||||||
|
}
|
||||||
|
if (!inGlobalTouch && inLocalTouch && shouldHandle(e)) {
|
||||||
|
var touch = getTouch(e);
|
||||||
|
|
||||||
|
var currentOffset = {pageX: touch.pageX, pageY: touch.pageY};
|
||||||
|
|
||||||
|
var differenceX = currentOffset.pageX - startOffset.pageX;
|
||||||
|
var differenceY = currentOffset.pageY - startOffset.pageY;
|
||||||
|
|
||||||
|
applyTouchMove(differenceX, differenceY);
|
||||||
|
startOffset = currentOffset;
|
||||||
|
|
||||||
|
var currentTime = (new Date()).getTime();
|
||||||
|
|
||||||
|
var timeGap = currentTime - startTime;
|
||||||
|
if (timeGap > 0) {
|
||||||
|
speed.x = differenceX / timeGap;
|
||||||
|
speed.y = differenceY / timeGap;
|
||||||
|
startTime = currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldPreventDefault(differenceX, differenceY)) {
|
||||||
|
e.stopPropagation();
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function touchEnd() {
|
||||||
|
if (!inGlobalTouch && inLocalTouch) {
|
||||||
|
inLocalTouch = false;
|
||||||
|
|
||||||
|
clearInterval(easingLoop);
|
||||||
|
easingLoop = setInterval(function () {
|
||||||
|
if (!instances.get(element)) {
|
||||||
|
clearInterval(easingLoop);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!speed.x && !speed.y) {
|
||||||
|
clearInterval(easingLoop);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Math.abs(speed.x) < 0.01 && Math.abs(speed.y) < 0.01) {
|
||||||
|
clearInterval(easingLoop);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
applyTouchMove(speed.x * 30, speed.y * 30);
|
||||||
|
|
||||||
|
speed.x *= 0.8;
|
||||||
|
speed.y *= 0.8;
|
||||||
|
}, 10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (supportsTouch) {
|
||||||
|
i.event.bind(window, 'touchstart', globalTouchStart);
|
||||||
|
i.event.bind(window, 'touchend', globalTouchEnd);
|
||||||
|
i.event.bind(element, 'touchstart', touchStart);
|
||||||
|
i.event.bind(element, 'touchmove', touchMove);
|
||||||
|
i.event.bind(element, 'touchend', touchEnd);
|
||||||
|
} else if (supportsIePointer) {
|
||||||
|
if (window.PointerEvent) {
|
||||||
|
i.event.bind(window, 'pointerdown', globalTouchStart);
|
||||||
|
i.event.bind(window, 'pointerup', globalTouchEnd);
|
||||||
|
i.event.bind(element, 'pointerdown', touchStart);
|
||||||
|
i.event.bind(element, 'pointermove', touchMove);
|
||||||
|
i.event.bind(element, 'pointerup', touchEnd);
|
||||||
|
} else if (window.MSPointerEvent) {
|
||||||
|
i.event.bind(window, 'MSPointerDown', globalTouchStart);
|
||||||
|
i.event.bind(window, 'MSPointerUp', globalTouchEnd);
|
||||||
|
i.event.bind(element, 'MSPointerDown', touchStart);
|
||||||
|
i.event.bind(element, 'MSPointerMove', touchMove);
|
||||||
|
i.event.bind(element, 'MSPointerUp', touchEnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function (element) {
|
||||||
|
if (!_.env.supportsTouch && !_.env.supportsIePointer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var i = instances.get(element);
|
||||||
|
bindTouchHandler(element, i, _.env.supportsTouch, _.env.supportsIePointer);
|
||||||
|
};
|
|
@ -0,0 +1,37 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var _ = require('../lib/helper');
|
||||||
|
var cls = require('../lib/class');
|
||||||
|
var instances = require('./instances');
|
||||||
|
var updateGeometry = require('./update-geometry');
|
||||||
|
|
||||||
|
// Handlers
|
||||||
|
var handlers = {
|
||||||
|
'click-rail': require('./handler/click-rail'),
|
||||||
|
'drag-scrollbar': require('./handler/drag-scrollbar'),
|
||||||
|
'keyboard': require('./handler/keyboard'),
|
||||||
|
'wheel': require('./handler/mouse-wheel'),
|
||||||
|
'touch': require('./handler/touch'),
|
||||||
|
'selection': require('./handler/selection')
|
||||||
|
};
|
||||||
|
var nativeScrollHandler = require('./handler/native-scroll');
|
||||||
|
|
||||||
|
module.exports = function (element, userSettings) {
|
||||||
|
userSettings = typeof userSettings === 'object' ? userSettings : {};
|
||||||
|
|
||||||
|
cls.add(element, 'ps-container');
|
||||||
|
|
||||||
|
// Create a plugin instance.
|
||||||
|
var i = instances.add(element);
|
||||||
|
|
||||||
|
i.settings = _.extend(i.settings, userSettings);
|
||||||
|
cls.add(element, 'ps-theme-' + i.settings.theme);
|
||||||
|
|
||||||
|
i.settings.handlers.forEach(function (handlerName) {
|
||||||
|
handlers[handlerName](element);
|
||||||
|
});
|
||||||
|
|
||||||
|
nativeScrollHandler(element);
|
||||||
|
|
||||||
|
updateGeometry(element);
|
||||||
|
};
|
|
@ -0,0 +1,107 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var _ = require('../lib/helper');
|
||||||
|
var cls = require('../lib/class');
|
||||||
|
var defaultSettings = require('./default-setting');
|
||||||
|
var dom = require('../lib/dom');
|
||||||
|
var EventManager = require('../lib/event-manager');
|
||||||
|
var guid = require('../lib/guid');
|
||||||
|
|
||||||
|
var instances = {};
|
||||||
|
|
||||||
|
function Instance(element) {
|
||||||
|
var i = this;
|
||||||
|
|
||||||
|
i.settings = _.clone(defaultSettings);
|
||||||
|
i.containerWidth = null;
|
||||||
|
i.containerHeight = null;
|
||||||
|
i.contentWidth = null;
|
||||||
|
i.contentHeight = null;
|
||||||
|
|
||||||
|
i.isRtl = dom.css(element, 'direction') === "rtl";
|
||||||
|
i.isNegativeScroll = (function () {
|
||||||
|
var originalScrollLeft = element.scrollLeft;
|
||||||
|
var result = null;
|
||||||
|
element.scrollLeft = -1;
|
||||||
|
result = element.scrollLeft < 0;
|
||||||
|
element.scrollLeft = originalScrollLeft;
|
||||||
|
return result;
|
||||||
|
})();
|
||||||
|
i.negativeScrollAdjustment = i.isNegativeScroll ? element.scrollWidth - element.clientWidth : 0;
|
||||||
|
i.event = new EventManager();
|
||||||
|
i.ownerDocument = element.ownerDocument || document;
|
||||||
|
|
||||||
|
function focus() {
|
||||||
|
cls.add(element, 'ps-focus');
|
||||||
|
}
|
||||||
|
|
||||||
|
function blur() {
|
||||||
|
cls.remove(element, 'ps-focus');
|
||||||
|
}
|
||||||
|
|
||||||
|
i.scrollbarXRail = dom.appendTo(dom.e('div', 'ps-scrollbar-x-rail'), element);
|
||||||
|
i.scrollbarX = dom.appendTo(dom.e('div', 'ps-scrollbar-x'), i.scrollbarXRail);
|
||||||
|
i.scrollbarX.setAttribute('tabindex', 0);
|
||||||
|
i.event.bind(i.scrollbarX, 'focus', focus);
|
||||||
|
i.event.bind(i.scrollbarX, 'blur', blur);
|
||||||
|
i.scrollbarXActive = null;
|
||||||
|
i.scrollbarXWidth = null;
|
||||||
|
i.scrollbarXLeft = null;
|
||||||
|
i.scrollbarXBottom = _.toInt(dom.css(i.scrollbarXRail, 'bottom'));
|
||||||
|
i.isScrollbarXUsingBottom = i.scrollbarXBottom === i.scrollbarXBottom; // !isNaN
|
||||||
|
i.scrollbarXTop = i.isScrollbarXUsingBottom ? null : _.toInt(dom.css(i.scrollbarXRail, 'top'));
|
||||||
|
i.railBorderXWidth = _.toInt(dom.css(i.scrollbarXRail, 'borderLeftWidth')) + _.toInt(dom.css(i.scrollbarXRail, 'borderRightWidth'));
|
||||||
|
// Set rail to display:block to calculate margins
|
||||||
|
dom.css(i.scrollbarXRail, 'display', 'block');
|
||||||
|
i.railXMarginWidth = _.toInt(dom.css(i.scrollbarXRail, 'marginLeft')) + _.toInt(dom.css(i.scrollbarXRail, 'marginRight'));
|
||||||
|
dom.css(i.scrollbarXRail, 'display', '');
|
||||||
|
i.railXWidth = null;
|
||||||
|
i.railXRatio = null;
|
||||||
|
|
||||||
|
i.scrollbarYRail = dom.appendTo(dom.e('div', 'ps-scrollbar-y-rail'), element);
|
||||||
|
i.scrollbarY = dom.appendTo(dom.e('div', 'ps-scrollbar-y'), i.scrollbarYRail);
|
||||||
|
i.scrollbarY.setAttribute('tabindex', 0);
|
||||||
|
i.event.bind(i.scrollbarY, 'focus', focus);
|
||||||
|
i.event.bind(i.scrollbarY, 'blur', blur);
|
||||||
|
i.scrollbarYActive = null;
|
||||||
|
i.scrollbarYHeight = null;
|
||||||
|
i.scrollbarYTop = null;
|
||||||
|
i.scrollbarYRight = _.toInt(dom.css(i.scrollbarYRail, 'right'));
|
||||||
|
i.isScrollbarYUsingRight = i.scrollbarYRight === i.scrollbarYRight; // !isNaN
|
||||||
|
i.scrollbarYLeft = i.isScrollbarYUsingRight ? null : _.toInt(dom.css(i.scrollbarYRail, 'left'));
|
||||||
|
i.scrollbarYOuterWidth = i.isRtl ? _.outerWidth(i.scrollbarY) : null;
|
||||||
|
i.railBorderYWidth = _.toInt(dom.css(i.scrollbarYRail, 'borderTopWidth')) + _.toInt(dom.css(i.scrollbarYRail, 'borderBottomWidth'));
|
||||||
|
dom.css(i.scrollbarYRail, 'display', 'block');
|
||||||
|
i.railYMarginHeight = _.toInt(dom.css(i.scrollbarYRail, 'marginTop')) + _.toInt(dom.css(i.scrollbarYRail, 'marginBottom'));
|
||||||
|
dom.css(i.scrollbarYRail, 'display', '');
|
||||||
|
i.railYHeight = null;
|
||||||
|
i.railYRatio = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getId(element) {
|
||||||
|
return element.getAttribute('data-ps-id');
|
||||||
|
}
|
||||||
|
|
||||||
|
function setId(element, id) {
|
||||||
|
element.setAttribute('data-ps-id', id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeId(element) {
|
||||||
|
element.removeAttribute('data-ps-id');
|
||||||
|
}
|
||||||
|
|
||||||
|
exports.add = function (element) {
|
||||||
|
var newId = guid();
|
||||||
|
setId(element, newId);
|
||||||
|
instances[newId] = new Instance(element);
|
||||||
|
return instances[newId];
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.remove = function (element) {
|
||||||
|
delete instances[getId(element)];
|
||||||
|
removeId(element);
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.get = function (element) {
|
||||||
|
return instances[getId(element)];
|
||||||
|
};
|
|
@ -0,0 +1,126 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var _ = require('../lib/helper');
|
||||||
|
var cls = require('../lib/class');
|
||||||
|
var dom = require('../lib/dom');
|
||||||
|
var instances = require('./instances');
|
||||||
|
var updateScroll = require('./update-scroll');
|
||||||
|
|
||||||
|
function getThumbSize(i, thumbSize) {
|
||||||
|
if (i.settings.minScrollbarLength) {
|
||||||
|
thumbSize = Math.max(thumbSize, i.settings.minScrollbarLength);
|
||||||
|
}
|
||||||
|
if (i.settings.maxScrollbarLength) {
|
||||||
|
thumbSize = Math.min(thumbSize, i.settings.maxScrollbarLength);
|
||||||
|
}
|
||||||
|
return thumbSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateCss(element, i) {
|
||||||
|
var xRailOffset = {width: i.railXWidth};
|
||||||
|
if (i.isRtl) {
|
||||||
|
xRailOffset.left = i.negativeScrollAdjustment + element.scrollLeft + i.containerWidth - i.contentWidth;
|
||||||
|
} else {
|
||||||
|
xRailOffset.left = element.scrollLeft;
|
||||||
|
}
|
||||||
|
if (i.isScrollbarXUsingBottom) {
|
||||||
|
xRailOffset.bottom = i.scrollbarXBottom - element.scrollTop;
|
||||||
|
} else {
|
||||||
|
xRailOffset.top = i.scrollbarXTop + element.scrollTop;
|
||||||
|
}
|
||||||
|
dom.css(i.scrollbarXRail, xRailOffset);
|
||||||
|
|
||||||
|
var yRailOffset = {top: element.scrollTop, height: i.railYHeight};
|
||||||
|
if (i.isScrollbarYUsingRight) {
|
||||||
|
if (i.isRtl) {
|
||||||
|
yRailOffset.right = i.contentWidth - (i.negativeScrollAdjustment + element.scrollLeft) - i.scrollbarYRight - i.scrollbarYOuterWidth;
|
||||||
|
} else {
|
||||||
|
yRailOffset.right = i.scrollbarYRight - element.scrollLeft;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (i.isRtl) {
|
||||||
|
yRailOffset.left = i.negativeScrollAdjustment + element.scrollLeft + i.containerWidth * 2 - i.contentWidth - i.scrollbarYLeft - i.scrollbarYOuterWidth;
|
||||||
|
} else {
|
||||||
|
yRailOffset.left = i.scrollbarYLeft + element.scrollLeft;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dom.css(i.scrollbarYRail, yRailOffset);
|
||||||
|
|
||||||
|
dom.css(i.scrollbarX, {left: i.scrollbarXLeft, width: i.scrollbarXWidth - i.railBorderXWidth});
|
||||||
|
dom.css(i.scrollbarY, {top: i.scrollbarYTop, height: i.scrollbarYHeight - i.railBorderYWidth});
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = function (element) {
|
||||||
|
var i = instances.get(element);
|
||||||
|
|
||||||
|
i.containerWidth = element.clientWidth;
|
||||||
|
i.containerHeight = element.clientHeight;
|
||||||
|
i.contentWidth = element.scrollWidth;
|
||||||
|
i.contentHeight = element.scrollHeight;
|
||||||
|
|
||||||
|
var existingRails;
|
||||||
|
if (!element.contains(i.scrollbarXRail)) {
|
||||||
|
existingRails = dom.queryChildren(element, '.ps-scrollbar-x-rail');
|
||||||
|
if (existingRails.length > 0) {
|
||||||
|
existingRails.forEach(function (rail) {
|
||||||
|
dom.remove(rail);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
dom.appendTo(i.scrollbarXRail, element);
|
||||||
|
}
|
||||||
|
if (!element.contains(i.scrollbarYRail)) {
|
||||||
|
existingRails = dom.queryChildren(element, '.ps-scrollbar-y-rail');
|
||||||
|
if (existingRails.length > 0) {
|
||||||
|
existingRails.forEach(function (rail) {
|
||||||
|
dom.remove(rail);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
dom.appendTo(i.scrollbarYRail, element);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!i.settings.suppressScrollX && i.containerWidth + i.settings.scrollXMarginOffset < i.contentWidth) {
|
||||||
|
i.scrollbarXActive = true;
|
||||||
|
i.railXWidth = i.containerWidth - i.railXMarginWidth;
|
||||||
|
i.railXRatio = i.containerWidth / i.railXWidth;
|
||||||
|
i.scrollbarXWidth = getThumbSize(i, _.toInt(i.railXWidth * i.containerWidth / i.contentWidth));
|
||||||
|
i.scrollbarXLeft = _.toInt((i.negativeScrollAdjustment + element.scrollLeft) * (i.railXWidth - i.scrollbarXWidth) / (i.contentWidth - i.containerWidth));
|
||||||
|
} else {
|
||||||
|
i.scrollbarXActive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!i.settings.suppressScrollY && i.containerHeight + i.settings.scrollYMarginOffset < i.contentHeight) {
|
||||||
|
i.scrollbarYActive = true;
|
||||||
|
i.railYHeight = i.containerHeight - i.railYMarginHeight;
|
||||||
|
i.railYRatio = i.containerHeight / i.railYHeight;
|
||||||
|
i.scrollbarYHeight = getThumbSize(i, _.toInt(i.railYHeight * i.containerHeight / i.contentHeight));
|
||||||
|
i.scrollbarYTop = _.toInt(element.scrollTop * (i.railYHeight - i.scrollbarYHeight) / (i.contentHeight - i.containerHeight));
|
||||||
|
} else {
|
||||||
|
i.scrollbarYActive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i.scrollbarXLeft >= i.railXWidth - i.scrollbarXWidth) {
|
||||||
|
i.scrollbarXLeft = i.railXWidth - i.scrollbarXWidth;
|
||||||
|
}
|
||||||
|
if (i.scrollbarYTop >= i.railYHeight - i.scrollbarYHeight) {
|
||||||
|
i.scrollbarYTop = i.railYHeight - i.scrollbarYHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateCss(element, i);
|
||||||
|
|
||||||
|
if (i.scrollbarXActive) {
|
||||||
|
cls.add(element, 'ps-active-x');
|
||||||
|
} else {
|
||||||
|
cls.remove(element, 'ps-active-x');
|
||||||
|
i.scrollbarXWidth = 0;
|
||||||
|
i.scrollbarXLeft = 0;
|
||||||
|
updateScroll(element, 'left', 0);
|
||||||
|
}
|
||||||
|
if (i.scrollbarYActive) {
|
||||||
|
cls.add(element, 'ps-active-y');
|
||||||
|
} else {
|
||||||
|
cls.remove(element, 'ps-active-y');
|
||||||
|
i.scrollbarYHeight = 0;
|
||||||
|
i.scrollbarYTop = 0;
|
||||||
|
updateScroll(element, 'top', 0);
|
||||||
|
}
|
||||||
|
};
|
|
@ -0,0 +1,97 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var instances = require('./instances');
|
||||||
|
|
||||||
|
var lastTop;
|
||||||
|
var lastLeft;
|
||||||
|
|
||||||
|
var createDOMEvent = function (name) {
|
||||||
|
var event = document.createEvent("Event");
|
||||||
|
event.initEvent(name, true, true);
|
||||||
|
return event;
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = function (element, axis, value) {
|
||||||
|
if (typeof element === 'undefined') {
|
||||||
|
throw 'You must provide an element to the update-scroll function';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof axis === 'undefined') {
|
||||||
|
throw 'You must provide an axis to the update-scroll function';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof value === 'undefined') {
|
||||||
|
throw 'You must provide a value to the update-scroll function';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (axis === 'top' && value <= 0) {
|
||||||
|
element.scrollTop = value = 0; // don't allow negative scroll
|
||||||
|
element.dispatchEvent(createDOMEvent('ps-y-reach-start'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (axis === 'left' && value <= 0) {
|
||||||
|
element.scrollLeft = value = 0; // don't allow negative scroll
|
||||||
|
element.dispatchEvent(createDOMEvent('ps-x-reach-start'));
|
||||||
|
}
|
||||||
|
|
||||||
|
var i = instances.get(element);
|
||||||
|
|
||||||
|
if (axis === 'top' && value >= i.contentHeight - i.containerHeight) {
|
||||||
|
// don't allow scroll past container
|
||||||
|
value = i.contentHeight - i.containerHeight;
|
||||||
|
if (value - element.scrollTop <= 1) {
|
||||||
|
// mitigates rounding errors on non-subpixel scroll values
|
||||||
|
value = element.scrollTop;
|
||||||
|
} else {
|
||||||
|
element.scrollTop = value;
|
||||||
|
}
|
||||||
|
element.dispatchEvent(createDOMEvent('ps-y-reach-end'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (axis === 'left' && value >= i.contentWidth - i.containerWidth) {
|
||||||
|
// don't allow scroll past container
|
||||||
|
value = i.contentWidth - i.containerWidth;
|
||||||
|
if (value - element.scrollLeft <= 1) {
|
||||||
|
// mitigates rounding errors on non-subpixel scroll values
|
||||||
|
value = element.scrollLeft;
|
||||||
|
} else {
|
||||||
|
element.scrollLeft = value;
|
||||||
|
}
|
||||||
|
element.dispatchEvent(createDOMEvent('ps-x-reach-end'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lastTop) {
|
||||||
|
lastTop = element.scrollTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lastLeft) {
|
||||||
|
lastLeft = element.scrollLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (axis === 'top' && value < lastTop) {
|
||||||
|
element.dispatchEvent(createDOMEvent('ps-scroll-up'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (axis === 'top' && value > lastTop) {
|
||||||
|
element.dispatchEvent(createDOMEvent('ps-scroll-down'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (axis === 'left' && value < lastLeft) {
|
||||||
|
element.dispatchEvent(createDOMEvent('ps-scroll-left'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (axis === 'left' && value > lastLeft) {
|
||||||
|
element.dispatchEvent(createDOMEvent('ps-scroll-right'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (axis === 'top') {
|
||||||
|
element.scrollTop = lastTop = value;
|
||||||
|
element.dispatchEvent(createDOMEvent('ps-scroll-y'));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (axis === 'left') {
|
||||||
|
element.scrollLeft = lastLeft = value;
|
||||||
|
element.dispatchEvent(createDOMEvent('ps-scroll-x'));
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
|
@ -0,0 +1,37 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var _ = require('../lib/helper');
|
||||||
|
var dom = require('../lib/dom');
|
||||||
|
var instances = require('./instances');
|
||||||
|
var updateGeometry = require('./update-geometry');
|
||||||
|
var updateScroll = require('./update-scroll');
|
||||||
|
|
||||||
|
module.exports = function (element) {
|
||||||
|
var i = instances.get(element);
|
||||||
|
|
||||||
|
if (!i) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recalcuate negative scrollLeft adjustment
|
||||||
|
i.negativeScrollAdjustment = i.isNegativeScroll ? element.scrollWidth - element.clientWidth : 0;
|
||||||
|
|
||||||
|
// Recalculate rail margins
|
||||||
|
dom.css(i.scrollbarXRail, 'display', 'block');
|
||||||
|
dom.css(i.scrollbarYRail, 'display', 'block');
|
||||||
|
i.railXMarginWidth = _.toInt(dom.css(i.scrollbarXRail, 'marginLeft')) + _.toInt(dom.css(i.scrollbarXRail, 'marginRight'));
|
||||||
|
i.railYMarginHeight = _.toInt(dom.css(i.scrollbarYRail, 'marginTop')) + _.toInt(dom.css(i.scrollbarYRail, 'marginBottom'));
|
||||||
|
|
||||||
|
// Hide scrollbars not to affect scrollWidth and scrollHeight
|
||||||
|
dom.css(i.scrollbarXRail, 'display', 'none');
|
||||||
|
dom.css(i.scrollbarYRail, 'display', 'none');
|
||||||
|
|
||||||
|
updateGeometry(element);
|
||||||
|
|
||||||
|
// Update top/left scroll to trigger events
|
||||||
|
updateScroll(element, 'top', element.scrollTop);
|
||||||
|
updateScroll(element, 'left', element.scrollLeft);
|
||||||
|
|
||||||
|
dom.css(i.scrollbarXRail, 'display', '');
|
||||||
|
dom.css(i.scrollbarYRail, 'display', '');
|
||||||
|
};
|
|
@ -6,7 +6,7 @@
|
||||||
<link rel="stylesheet" href="view/asset/jquery-colorbox/example5/colorbox.css?v={{$smarty.const.FRIENDICA_VERSION}}" type="text/css" media="screen" />
|
<link rel="stylesheet" href="view/asset/jquery-colorbox/example5/colorbox.css?v={{$smarty.const.FRIENDICA_VERSION}}" type="text/css" media="screen" />
|
||||||
<link rel="stylesheet" href="view/asset/jgrowl/jquery.jgrowl.min.css?v={{$smarty.const.FRIENDICA_VERSION}}" type="text/css" media="screen" />
|
<link rel="stylesheet" href="view/asset/jgrowl/jquery.jgrowl.min.css?v={{$smarty.const.FRIENDICA_VERSION}}" type="text/css" media="screen" />
|
||||||
<link rel="stylesheet" href="view/asset/jquery-datetimepicker/build/jquery.datetimepicker.min.css?v={{$smarty.const.FRIENDICA_VERSION}}" type="text/css" media="screen" />
|
<link rel="stylesheet" href="view/asset/jquery-datetimepicker/build/jquery.datetimepicker.min.css?v={{$smarty.const.FRIENDICA_VERSION}}" type="text/css" media="screen" />
|
||||||
<link rel="stylesheet" href="view/asset/perfect-scrollbar/css/perfect-scrollbar.min.css?v={{$smarty.const.FRIENDICA_VERSION}}" type="text/css" media="screen" />
|
<link rel="stylesheet" href="view/js/perfect-scrollbar/css/perfect-scrollbar.min.css?v={{$smarty.const.FRIENDICA_VERSION}}" type="text/css" media="screen" />
|
||||||
|
|
||||||
{{foreach $stylesheets as $stylesheetUrl}}
|
{{foreach $stylesheets as $stylesheetUrl}}
|
||||||
<link rel="stylesheet" href="{{$stylesheetUrl}}" type="text/css" media="screen" />
|
<link rel="stylesheet" href="{{$stylesheetUrl}}" type="text/css" media="screen" />
|
||||||
|
@ -40,7 +40,7 @@
|
||||||
<script type="text/javascript" src="view/asset/jquery-colorbox/jquery.colorbox-min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
<script type="text/javascript" src="view/asset/jquery-colorbox/jquery.colorbox-min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
||||||
<script type="text/javascript" src="view/asset/jgrowl/jquery.jgrowl.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
<script type="text/javascript" src="view/asset/jgrowl/jquery.jgrowl.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
||||||
<script type="text/javascript" src="view/asset/jquery-datetimepicker/build/jquery.datetimepicker.full.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
<script type="text/javascript" src="view/asset/jquery-datetimepicker/build/jquery.datetimepicker.full.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
||||||
<script type="text/javascript" src="view/asset/perfect-scrollbar/js/perfect-scrollbar.jquery.min.js?v={{$smarty.const.FRIENDICA_VERSION}}" ></script>
|
<script type="text/javascript" src="view/js/perfect-scrollbar/js/perfect-scrollbar.jquery.min.js?v={{$smarty.const.FRIENDICA_VERSION}}" ></script>
|
||||||
<script type="text/javascript" src="view/asset/imagesloaded/imagesloaded.pkgd.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
<script type="text/javascript" src="view/asset/imagesloaded/imagesloaded.pkgd.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
||||||
<script type="text/javascript" src="view/asset/base64/base64.min.js?v={{$smarty.const.FRIENDICA_VERSION}}" ></script>
|
<script type="text/javascript" src="view/asset/base64/base64.min.js?v={{$smarty.const.FRIENDICA_VERSION}}" ></script>
|
||||||
<script type="text/javascript" src="view/asset/dompurify/dist/purify.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
<script type="text/javascript" src="view/asset/dompurify/dist/purify.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
<link rel="stylesheet" href="view/asset/jquery-colorbox/example5/colorbox.css?v={{$smarty.const.FRIENDICA_VERSION}}" type="text/css" media="screen" />
|
<link rel="stylesheet" href="view/asset/jquery-colorbox/example5/colorbox.css?v={{$smarty.const.FRIENDICA_VERSION}}" type="text/css" media="screen" />
|
||||||
<link rel="stylesheet" href="view/asset/jgrowl/jquery.jgrowl.min.css?v={{$smarty.const.FRIENDICA_VERSION}}" type="text/css" media="screen" />
|
<link rel="stylesheet" href="view/asset/jgrowl/jquery.jgrowl.min.css?v={{$smarty.const.FRIENDICA_VERSION}}" type="text/css" media="screen" />
|
||||||
<link rel="stylesheet" href="view/asset/jquery-datetimepicker/build/jquery.datetimepicker.min.css?v={{$smarty.const.FRIENDICA_VERSION}}" type="text/css" media="screen" />
|
<link rel="stylesheet" href="view/asset/jquery-datetimepicker/build/jquery.datetimepicker.min.css?v={{$smarty.const.FRIENDICA_VERSION}}" type="text/css" media="screen" />
|
||||||
<link rel="stylesheet" href="view/asset/perfect-scrollbar/css/perfect-scrollbar.min.css?v={{$smarty.const.FRIENDICA_VERSION}}" type="text/css" media="screen" />
|
<link rel="stylesheet" href="view/js/perfect-scrollbar/css/perfect-scrollbar.min.css?v={{$smarty.const.FRIENDICA_VERSION}}" type="text/css" media="screen" />
|
||||||
|
|
||||||
<link rel="stylesheet" href="view/theme/frio/frameworks/bootstrap/css/bootstrap.min.css?v={{$smarty.const.FRIENDICA_VERSION}}" type="text/css" media="screen"/>
|
<link rel="stylesheet" href="view/theme/frio/frameworks/bootstrap/css/bootstrap.min.css?v={{$smarty.const.FRIENDICA_VERSION}}" type="text/css" media="screen"/>
|
||||||
<link rel="stylesheet" href="view/theme/frio/frameworks/bootstrap/css/bootstrap-theme.min.css?v={{$smarty.const.FRIENDICA_VERSION}}" type="text/css" media="screen"/>
|
<link rel="stylesheet" href="view/theme/frio/frameworks/bootstrap/css/bootstrap-theme.min.css?v={{$smarty.const.FRIENDICA_VERSION}}" type="text/css" media="screen"/>
|
||||||
|
@ -61,7 +61,7 @@
|
||||||
<script type="text/javascript" src="view/asset/jquery-colorbox/jquery.colorbox-min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
<script type="text/javascript" src="view/asset/jquery-colorbox/jquery.colorbox-min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
||||||
<script type="text/javascript" src="view/asset/jgrowl/jquery.jgrowl.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
<script type="text/javascript" src="view/asset/jgrowl/jquery.jgrowl.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
||||||
<script type="text/javascript" src="view/asset/jquery-datetimepicker/build/jquery.datetimepicker.full.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
<script type="text/javascript" src="view/asset/jquery-datetimepicker/build/jquery.datetimepicker.full.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
||||||
<script type="text/javascript" src="view/asset/perfect-scrollbar/js/perfect-scrollbar.jquery.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
<script type="text/javascript" src="view/js/perfect-scrollbar/js/perfect-scrollbar.jquery.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
||||||
<script type="text/javascript" src="view/asset/imagesloaded/imagesloaded.pkgd.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
<script type="text/javascript" src="view/asset/imagesloaded/imagesloaded.pkgd.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
||||||
<script type="text/javascript" src="view/asset/base64/base64.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
<script type="text/javascript" src="view/asset/base64/base64.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
||||||
<script type="text/javascript" src="view/asset/dompurify/dist/purify.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
<script type="text/javascript" src="view/asset/dompurify/dist/purify.min.js?v={{$smarty.const.FRIENDICA_VERSION}}"></script>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user