lampa-main в git: клиент переживает пересоздание контейнера
- каталог lampa-main/ (yumata/lampa) смонтирован bind-mountом в /lampac/wwwroot/lampa-main (override) - в образе 1.72.0 клиента нет, LampaCron из GitHub не докачивает (нет доступа к GitHub) -> / отдавал 500 - README/AGENT: механика обновления клиента через git - compose: 1.72.0, cache/database как bind-mountы, секреты в init.conf
This commit is contained in:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Vendored
+10253
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,884 @@
|
||||
/*!
|
||||
*
|
||||
* simple-keyboard v2.32.123
|
||||
* https://github.com/hodgef/simple-keyboard
|
||||
*
|
||||
* Copyright (c) Francisco Hodge (https://github.com/hodgef)
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
*/
|
||||
! function(t, e) {
|
||||
"object" === typeof exports && "object" === typeof module ? module.exports = e() : "function" === typeof define && define.amd ? define("SimpleKeyboard", [], e) : "object" === typeof exports ? exports.SimpleKeyboard = e() : t.SimpleKeyboard = e()
|
||||
}(this, (function() {
|
||||
return function(t) {
|
||||
var e = {};
|
||||
|
||||
function __webpack_require__(n) {
|
||||
if (e[n]) return e[n].exports;
|
||||
var o = e[n] = {
|
||||
i: n,
|
||||
l: !1,
|
||||
exports: {}
|
||||
};
|
||||
return t[n].call(o.exports, o, o.exports, __webpack_require__), o.l = !0, o.exports
|
||||
}
|
||||
return __webpack_require__.m = t, __webpack_require__.c = e, __webpack_require__.d = function(t, e, n) {
|
||||
__webpack_require__.o(t, e) || Object.defineProperty(t, e, {
|
||||
enumerable: !0,
|
||||
get: n
|
||||
})
|
||||
}, __webpack_require__.r = function(t) {
|
||||
"undefined" !== typeof Symbol && Symbol.toStringTag && Object.defineProperty(t, Symbol.toStringTag, {
|
||||
value: "Module"
|
||||
}), Object.defineProperty(t, "__esModule", {
|
||||
value: !0
|
||||
})
|
||||
}, __webpack_require__.t = function(t, e) {
|
||||
if (1 & e && (t = __webpack_require__(t)), 8 & e) return t;
|
||||
if (4 & e && "object" === typeof t && t && t.__esModule) return t;
|
||||
var n = Object.create(null);
|
||||
if (__webpack_require__.r(n), Object.defineProperty(n, "default", {
|
||||
enumerable: !0,
|
||||
value: t
|
||||
}), 2 & e && "string" != typeof t)
|
||||
for (var o in t) __webpack_require__.d(n, o, function(e) {
|
||||
return t[e]
|
||||
}.bind(null, o));
|
||||
return n
|
||||
}, __webpack_require__.n = function(t) {
|
||||
var e = t && t.__esModule ? function() {
|
||||
return t.default
|
||||
} : function() {
|
||||
return t
|
||||
};
|
||||
return __webpack_require__.d(e, "a", e), e
|
||||
}, __webpack_require__.o = function(t, e) {
|
||||
return Object.prototype.hasOwnProperty.call(t, e)
|
||||
}, __webpack_require__.p = "/", __webpack_require__(__webpack_require__.s = 0)
|
||||
}([function(t, e, n) {
|
||||
t.exports = n(1)
|
||||
}, function(t, e, n) {
|
||||
"use strict";
|
||||
n.r(e);
|
||||
|
||||
function _createForOfIteratorHelper(t, e) {
|
||||
var n;
|
||||
if ("undefined" === typeof Symbol || null == t[Symbol.iterator]) {
|
||||
if (Array.isArray(t) || (n = function(t, e) {
|
||||
if (!t) return;
|
||||
if ("string" === typeof t) return _arrayLikeToArray(t, e);
|
||||
var n = Object.prototype.toString.call(t).slice(8, -1);
|
||||
"Object" === n && t.constructor && (n = t.constructor.name);
|
||||
if ("Map" === n || "Set" === n) return Array.from(t);
|
||||
if ("Arguments" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(t, e)
|
||||
}(t)) || e && t && "number" === typeof t.length) {
|
||||
n && (t = n);
|
||||
var o = 0,
|
||||
F = function() {};
|
||||
return {
|
||||
s: F,
|
||||
n: function() {
|
||||
return o >= t.length ? {
|
||||
done: !0
|
||||
} : {
|
||||
done: !1,
|
||||
value: t[o++]
|
||||
}
|
||||
},
|
||||
e: function(t) {
|
||||
throw t
|
||||
},
|
||||
f: F
|
||||
}
|
||||
}
|
||||
throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")
|
||||
}
|
||||
var i, s = !0,
|
||||
a = !1;
|
||||
return {
|
||||
s: function() {
|
||||
n = t[Symbol.iterator]()
|
||||
},
|
||||
n: function() {
|
||||
var t = n.next();
|
||||
return s = t.done, t
|
||||
},
|
||||
e: function(t) {
|
||||
a = !0, i = t
|
||||
},
|
||||
f: function() {
|
||||
try {
|
||||
s || null == n.return || n.return()
|
||||
} finally {
|
||||
if (a) throw i
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function _arrayLikeToArray(t, e) {
|
||||
(null == e || e > t.length) && (e = t.length);
|
||||
for (var n = 0, o = new Array(e); n < e; n++) o[n] = t[n];
|
||||
return o
|
||||
}
|
||||
|
||||
function _typeof(t) {
|
||||
return (_typeof = "function" === typeof Symbol && "symbol" === typeof Symbol.iterator ? function(t) {
|
||||
return typeof t
|
||||
} : function(t) {
|
||||
return t && "function" === typeof Symbol && t.constructor === Symbol && t !== Symbol.prototype ? "symbol" : typeof t
|
||||
})(t)
|
||||
}
|
||||
|
||||
function _defineProperties(t, e) {
|
||||
for (var n = 0; n < e.length; n++) {
|
||||
var o = e[n];
|
||||
o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(t, o.key, o)
|
||||
}
|
||||
}
|
||||
var o, i, s, a = function() {
|
||||
function Utilities(t) {
|
||||
var e = t.getOptions,
|
||||
n = t.getCaretPosition,
|
||||
o = t.getCaretPositionEnd,
|
||||
i = t.dispatch;
|
||||
! function(t, e) {
|
||||
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
|
||||
}(this, Utilities), this.getOptions = e, this.getCaretPosition = n, this.getCaretPositionEnd = o, this.dispatch = i, Utilities.bindMethods(Utilities, this)
|
||||
}
|
||||
var t, e, n;
|
||||
return t = Utilities, n = [{
|
||||
key: "bindMethods",
|
||||
value: function(t, e) {
|
||||
var n, o = _createForOfIteratorHelper(Object.getOwnPropertyNames(t.prototype));
|
||||
try {
|
||||
for (o.s(); !(n = o.n()).done;) {
|
||||
var i = n.value;
|
||||
"constructor" === i || "bindMethods" === i || (e[i] = e[i].bind(e))
|
||||
}
|
||||
} catch (s) {
|
||||
o.e(s)
|
||||
} finally {
|
||||
o.f()
|
||||
}
|
||||
}
|
||||
}], (e = [{
|
||||
key: "getButtonClass",
|
||||
value: function(t) {
|
||||
var e = t.includes("{") && t.includes("}") && "{//}" !== t ? "functionBtn" : "standardBtn",
|
||||
n = t.replace("{", "").replace("}", ""),
|
||||
o = "";
|
||||
return "standardBtn" !== e && (o = " hg-button-".concat(n)), "hg-".concat(e).concat(o)
|
||||
}
|
||||
}, {
|
||||
key: "getDefaultDiplay",
|
||||
value: function() {
|
||||
return {
|
||||
"{bksp}": "backspace",
|
||||
"{backspace}": "backspace",
|
||||
"{enter}": "< enter",
|
||||
"{shift}": "shift",
|
||||
"{shiftleft}": "shift",
|
||||
"{shiftright}": "shift",
|
||||
"{alt}": "alt",
|
||||
"{s}": "shift",
|
||||
"{tab}": "tab",
|
||||
"{lock}": "caps",
|
||||
"{capslock}": "caps",
|
||||
"{accept}": "Submit",
|
||||
"{space}": " ",
|
||||
"{//}": " ",
|
||||
"{esc}": "esc",
|
||||
"{escape}": "esc",
|
||||
"{f1}": "f1",
|
||||
"{f2}": "f2",
|
||||
"{f3}": "f3",
|
||||
"{f4}": "f4",
|
||||
"{f5}": "f5",
|
||||
"{f6}": "f6",
|
||||
"{f7}": "f7",
|
||||
"{f8}": "f8",
|
||||
"{f9}": "f9",
|
||||
"{f10}": "f10",
|
||||
"{f11}": "f11",
|
||||
"{f12}": "f12",
|
||||
"{numpaddivide}": "/",
|
||||
"{numlock}": "lock",
|
||||
"{arrowup}": "\u2191",
|
||||
"{arrowleft}": "\u2190",
|
||||
"{arrowdown}": "\u2193",
|
||||
"{arrowright}": "\u2192",
|
||||
"{prtscr}": "print",
|
||||
"{scrolllock}": "scroll",
|
||||
"{pause}": "pause",
|
||||
"{insert}": "ins",
|
||||
"{home}": "home",
|
||||
"{pageup}": "up",
|
||||
"{delete}": "del",
|
||||
"{end}": "end",
|
||||
"{pagedown}": "down",
|
||||
"{numpadmultiply}": "*",
|
||||
"{numpadsubtract}": "-",
|
||||
"{numpadadd}": "+",
|
||||
"{numpadenter}": "enter",
|
||||
"{period}": ".",
|
||||
"{numpaddecimal}": ".",
|
||||
"{numpad0}": "0",
|
||||
"{numpad1}": "1",
|
||||
"{numpad2}": "2",
|
||||
"{numpad3}": "3",
|
||||
"{numpad4}": "4",
|
||||
"{numpad5}": "5",
|
||||
"{numpad6}": "6",
|
||||
"{numpad7}": "7",
|
||||
"{numpad8}": "8",
|
||||
"{numpad9}": "9"
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: "getButtonDisplayName",
|
||||
value: function(t, e, n) {
|
||||
return (e = n ? Object.assign({}, this.getDefaultDiplay(), e) : e || this.getDefaultDiplay())[t] || t
|
||||
}
|
||||
}, {
|
||||
key: "getUpdatedInput",
|
||||
value: function(t, e, n) {
|
||||
var o = arguments.length > 3 && void 0 !== arguments[3] ? arguments[3] : n,
|
||||
i = arguments.length > 4 && void 0 !== arguments[4] && arguments[4],
|
||||
s = this.getOptions(),
|
||||
a = [n, o, i],
|
||||
r = e;
|
||||
return ("{bksp}" === t || "{backspace}" === t) && r.length > 0 ? r = this.removeAt.apply(this, [r].concat(a)) : "{space}" === t ? r = this.addStringAt.apply(this, [r, " "].concat(a)) : "{tab}" !== t || "boolean" === typeof s.tabCharOnTab && !1 === s.tabCharOnTab ? "{enter}" !== t && "{numpadenter}" !== t || !s.newLineOnEnter ? t.includes("numpad") && Number.isInteger(Number(t[t.length - 2])) ? r = this.addStringAt.apply(this, [r, t[t.length - 2]].concat(a)) : "{numpaddivide}" === t ? r = this.addStringAt.apply(this, [r, "/"].concat(a)) : "{numpadmultiply}" === t ? r = this.addStringAt.apply(this, [r, "*"].concat(a)) : "{numpadsubtract}" === t ? r = this.addStringAt.apply(this, [r, "-"].concat(a)) : "{numpadadd}" === t ? r = this.addStringAt.apply(this, [r, "+"].concat(a)) : "{numpaddecimal}" === t ? r = this.addStringAt.apply(this, [r, "."].concat(a)) : "{" === t || "}" === t ? r = this.addStringAt.apply(this, [r, t].concat(a)) : t.includes("{") || t.includes("}") || (r = this.addStringAt.apply(this, [r, t].concat(a))) : r = this.addStringAt.apply(this, [r, "\n"].concat(a)) : r = this.addStringAt.apply(this, [r, "\t"].concat(a)), r
|
||||
}
|
||||
}, {
|
||||
key: "updateCaretPos",
|
||||
value: function(t, e) {
|
||||
var n = this.updateCaretPosAction(t, e);
|
||||
this.dispatch((function(t) {
|
||||
t.setCaretPosition(n)
|
||||
}))
|
||||
}
|
||||
}, {
|
||||
key: "updateCaretPosAction",
|
||||
value: function(t, e) {
|
||||
var n = this.getOptions(),
|
||||
o = this.getCaretPosition();
|
||||
return e ? o > 0 && (o -= t) : o += t, n.debug && console.log("Caret at:", o, "(".concat(this.keyboardDOMClass, ")")), o
|
||||
}
|
||||
}, {
|
||||
key: "addStringAt",
|
||||
value: function(t, e) {
|
||||
var n, o = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : t.length,
|
||||
i = arguments.length > 3 && void 0 !== arguments[3] ? arguments[3] : t.length,
|
||||
s = arguments.length > 4 && void 0 !== arguments[4] && arguments[4];
|
||||
return o || 0 === o ? (n = [t.slice(0, o), e, t.slice(i)].join(""), this.isMaxLengthReached() || s && this.updateCaretPos(e.length)) : n = t + e, n
|
||||
}
|
||||
}, {
|
||||
key: "removeAt",
|
||||
value: function(t) {
|
||||
var e, n = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : t.length,
|
||||
o = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : t.length,
|
||||
i = arguments.length > 3 && void 0 !== arguments[3] && arguments[3];
|
||||
if (0 === n && 0 === o) return t;
|
||||
if (n === o) {
|
||||
var s = /([\uD800-\uDBFF][\uDC00-\uDFFF])/g;
|
||||
n && n >= 0 ? t.substring(n - 2, n).match(s) ? (e = t.substr(0, n - 2) + t.substr(n), i && this.updateCaretPos(2, !0)) : (e = t.substr(0, n - 1) + t.substr(n), i && this.updateCaretPos(1, !0)) : t.slice(-2).match(s) ? (e = t.slice(0, -2), i && this.updateCaretPos(2, !0)) : (e = t.slice(0, -1), i && this.updateCaretPos(1, !0))
|
||||
} else e = t.slice(0, n) + t.slice(o), i && this.dispatch((function(t) {
|
||||
t.setCaretPosition(n)
|
||||
}));
|
||||
return e
|
||||
}
|
||||
}, {
|
||||
key: "handleMaxLength",
|
||||
value: function(t, e) {
|
||||
var n = this.getOptions(),
|
||||
o = n.maxLength,
|
||||
i = t[n.inputName],
|
||||
s = e.length - 1 >= o;
|
||||
if (e.length <= i.length) return !1;
|
||||
if (Number.isInteger(o)) return n.debug && console.log("maxLength (num) reached:", s), s ? (this.maxLengthReached = !0, !0) : (this.maxLengthReached = !1, !1);
|
||||
if ("object" === _typeof(o)) {
|
||||
var a = e.length - 1 >= o[n.inputName];
|
||||
return n.debug && console.log("maxLength (obj) reached:", a), a ? (this.maxLengthReached = !0, !0) : (this.maxLengthReached = !1, !1)
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: "isMaxLengthReached",
|
||||
value: function() {
|
||||
return Boolean(this.maxLengthReached)
|
||||
}
|
||||
}, {
|
||||
key: "isTouchDevice",
|
||||
value: function() {
|
||||
return "ontouchstart" in window || navigator.maxTouchPoints
|
||||
}
|
||||
}, {
|
||||
key: "pointerEventsSupported",
|
||||
value: function() {
|
||||
return window.PointerEvent
|
||||
}
|
||||
}, {
|
||||
key: "camelCase",
|
||||
value: function(t) {
|
||||
return !!t && t.toLowerCase().trim().split(/[.\-_\s]/g).reduce((function(t, e) {
|
||||
return e.length ? t + e[0].toUpperCase() + e.slice(1) : t
|
||||
}))
|
||||
}
|
||||
}]) && _defineProperties(t.prototype, e), n && _defineProperties(t, n), Utilities
|
||||
}();
|
||||
s = function() {}, (i = "noop") in (o = a) ? Object.defineProperty(o, i, {
|
||||
value: s,
|
||||
enumerable: !0,
|
||||
configurable: !0,
|
||||
writable: !0
|
||||
}) : o[i] = s;
|
||||
var r = a;
|
||||
|
||||
function PhysicalKeyboard_defineProperties(t, e) {
|
||||
for (var n = 0; n < e.length; n++) {
|
||||
var o = e[n];
|
||||
o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(t, o.key, o)
|
||||
}
|
||||
}
|
||||
var u = function() {
|
||||
function PhysicalKeyboard(t) {
|
||||
var e = t.dispatch,
|
||||
n = t.getOptions;
|
||||
! function(t, e) {
|
||||
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
|
||||
}(this, PhysicalKeyboard), this.dispatch = e, this.getOptions = n, r.bindMethods(PhysicalKeyboard, this)
|
||||
}
|
||||
var t, e, n;
|
||||
return t = PhysicalKeyboard, (e = [{
|
||||
key: "handleHighlightKeyDown",
|
||||
value: function(t) {
|
||||
var e = this.getOptions(),
|
||||
n = this.getSimpleKeyboardLayoutKey(t);
|
||||
this.dispatch((function(t) {
|
||||
var o = t.getButtonElement(n) || t.getButtonElement("{".concat(n, "}"));
|
||||
o && (o.style.backgroundColor = e.physicalKeyboardHighlightBgColor || "#dadce4", o.style.color = e.physicalKeyboardHighlightTextColor || "black", e.physicalKeyboardHighlightPress && (o.onpointerdown || o.onmousedown || o.ontouchstart || r.noop)())
|
||||
}))
|
||||
}
|
||||
}, {
|
||||
key: "handleHighlightKeyUp",
|
||||
value: function(t) {
|
||||
var e = this.getOptions(),
|
||||
n = this.getSimpleKeyboardLayoutKey(t);
|
||||
this.dispatch((function(t) {
|
||||
var o = t.getButtonElement(n) || t.getButtonElement("{".concat(n, "}"));
|
||||
o && o.removeAttribute && (o.removeAttribute("style"), e.physicalKeyboardHighlightPress && (o.onpointerup || o.onmouseup || o.ontouchend || r.noop)())
|
||||
}))
|
||||
}
|
||||
}, {
|
||||
key: "getSimpleKeyboardLayoutKey",
|
||||
value: function(t) {
|
||||
var e;
|
||||
return ((e = t.code.includes("Numpad") || t.code.includes("Shift") || t.code.includes("Space") || t.code.includes("Backspace") || t.code.includes("Control") || t.code.includes("Alt") || t.code.includes("Meta") ? t.code : t.key) && e !== e.toUpperCase() || "F" === t.code[0] && Number.isInteger(Number(t.code[1])) && t.code.length <= 3) && (e = e ? e.toLowerCase() : e), e
|
||||
}
|
||||
}]) && PhysicalKeyboard_defineProperties(t.prototype, e), n && PhysicalKeyboard_defineProperties(t, n), PhysicalKeyboard
|
||||
}();
|
||||
|
||||
function _toConsumableArray(t) {
|
||||
return function(t) {
|
||||
if (Array.isArray(t)) return Keyboard_arrayLikeToArray(t)
|
||||
}(t) || function(t) {
|
||||
if ("undefined" !== typeof Symbol && Symbol.iterator in Object(t)) return Array.from(t)
|
||||
}(t) || function(t, e) {
|
||||
if (!t) return;
|
||||
if ("string" === typeof t) return Keyboard_arrayLikeToArray(t, e);
|
||||
var n = Object.prototype.toString.call(t).slice(8, -1);
|
||||
"Object" === n && t.constructor && (n = t.constructor.name);
|
||||
if ("Map" === n || "Set" === n) return Array.from(t);
|
||||
if ("Arguments" === n || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return Keyboard_arrayLikeToArray(t, e)
|
||||
}(t) || function() {
|
||||
throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")
|
||||
}()
|
||||
}
|
||||
|
||||
function Keyboard_arrayLikeToArray(t, e) {
|
||||
(null == e || e > t.length) && (e = t.length);
|
||||
for (var n = 0, o = new Array(e); n < e; n++) o[n] = t[n];
|
||||
return o
|
||||
}
|
||||
|
||||
function Keyboard_classCallCheck(t, e) {
|
||||
if (!(t instanceof e)) throw new TypeError("Cannot call a class as a function")
|
||||
}
|
||||
|
||||
function Keyboard_defineProperties(t, e) {
|
||||
for (var n = 0; n < e.length; n++) {
|
||||
var o = e[n];
|
||||
o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(t, o.key, o)
|
||||
}
|
||||
}
|
||||
|
||||
function Keyboard_defineProperty(t, e, n) {
|
||||
return e in t ? Object.defineProperty(t, e, {
|
||||
value: n,
|
||||
enumerable: !0,
|
||||
configurable: !0,
|
||||
writable: !0
|
||||
}) : t[e] = n, t
|
||||
}
|
||||
var c = function() {
|
||||
function SimpleKeyboard() {
|
||||
var t = this;
|
||||
Keyboard_classCallCheck(this, SimpleKeyboard), Keyboard_defineProperty(this, "handleParams", (function(t) {
|
||||
var e, n, o;
|
||||
if ("string" === typeof t[0]) e = t[0].split(".").join(""), n = document.querySelector(".".concat(e)), o = t[1];
|
||||
else if (t[0] instanceof HTMLDivElement) {
|
||||
if (!t[0].className) throw console.warn("Any DOM element passed as parameter must have a class."), new Error("KEYBOARD_DOM_CLASS_ERROR");
|
||||
e = t[0].className.split(" ")[0], n = t[0], o = t[1]
|
||||
} else e = "simple-keyboard", n = document.querySelector(".".concat(e)), o = t[0];
|
||||
return {
|
||||
keyboardDOMClass: e,
|
||||
keyboardDOM: n,
|
||||
options: o
|
||||
}
|
||||
})), Keyboard_defineProperty(this, "getOptions", (function() {
|
||||
return t.options
|
||||
})), Keyboard_defineProperty(this, "getCaretPosition", (function() {
|
||||
return t.caretPosition
|
||||
})), Keyboard_defineProperty(this, "getCaretPositionEnd", (function() {
|
||||
return t.caretPositionEnd
|
||||
})), Keyboard_defineProperty(this, "registerModule", (function(e, n) {
|
||||
t.modules[e] || (t.modules[e] = {}), n(t.modules[e])
|
||||
})), Keyboard_defineProperty(this, "getKeyboardClassString", (function() {
|
||||
for (var e = arguments.length, n = new Array(e), o = 0; o < e; o++) n[o] = arguments[o];
|
||||
var i = [t.keyboardDOMClass].concat(n).filter((function(t) {
|
||||
return !!t
|
||||
}));
|
||||
return i.join(" ")
|
||||
}));
|
||||
for (var e = arguments.length, n = new Array(e), o = 0; o < e; o++) n[o] = arguments[o];
|
||||
var i = this.handleParams(n),
|
||||
s = i.keyboardDOMClass,
|
||||
a = i.keyboardDOM,
|
||||
c = i.options,
|
||||
l = void 0 === c ? {} : c;
|
||||
if (this.utilities = new r({
|
||||
getOptions: this.getOptions,
|
||||
getCaretPosition: this.getCaretPosition,
|
||||
getCaretPositionEnd: this.getCaretPositionEnd,
|
||||
dispatch: this.dispatch
|
||||
}), this.caretPosition = null, this.caretPositionEnd = null, this.keyboardDOM = a, this.options = l, this.options.layoutName = this.options.layoutName || "default", this.options.theme = this.options.theme || "hg-theme-default", this.options.inputName = this.options.inputName || "default", this.options.preventMouseDownDefault = this.options.preventMouseDownDefault || !1, this.keyboardPluginClasses = "", r.bindMethods(SimpleKeyboard, this), this.input = {}, this.input[this.options.inputName] = "", this.keyboardDOMClass = s, this.buttonElements = {}, window.SimpleKeyboardInstances || (window.SimpleKeyboardInstances = {}), this.currentInstanceName = this.utilities.camelCase(this.keyboardDOMClass), window.SimpleKeyboardInstances[this.currentInstanceName] = this, this.allKeyboardInstances = window.SimpleKeyboardInstances, this.keyboardInstanceNames = Object.keys(window.SimpleKeyboardInstances), this.isFirstKeyboardInstance = this.keyboardInstanceNames[0] === this.currentInstanceName, this.physicalKeyboard = new u({
|
||||
dispatch: this.dispatch,
|
||||
getOptions: this.getOptions
|
||||
}), !this.keyboardDOM) throw console.warn('".'.concat(s, '" was not found in the DOM.')), new Error("KEYBOARD_DOM_ERROR");
|
||||
this.render(), this.modules = {}, this.loadModules()
|
||||
}
|
||||
var t, e, n;
|
||||
return t = SimpleKeyboard, (e = [{
|
||||
key: "setCaretPosition",
|
||||
value: function(t, e) {
|
||||
this.caretPosition = t, this.caretPositionEnd = e || t
|
||||
}
|
||||
}, {
|
||||
key: "handleButtonClicked",
|
||||
value: function(t) {
|
||||
var e = this.options.debug;
|
||||
if ("{//}" === t) return !1;
|
||||
"function" === typeof this.options.onKeyPress && this.options.onKeyPress(t), this.input[this.options.inputName] || (this.input[this.options.inputName] = "");
|
||||
var n = this.utilities.getUpdatedInput(t, this.input[this.options.inputName], this.caretPosition, this.caretPositionEnd);
|
||||
if (this.input[this.options.inputName] !== n && (!this.options.inputPattern || this.options.inputPattern && this.inputPatternIsValid(n))) {
|
||||
if (this.options.maxLength && this.utilities.handleMaxLength(this.input, n)) return !1;
|
||||
this.input[this.options.inputName] = this.utilities.getUpdatedInput(t, this.input[this.options.inputName], this.caretPosition, this.caretPositionEnd, !0), e && console.log("Input changed:", this.getAllInputs()), this.options.debug && console.log("Caret at: ", this.getCaretPosition(), this.getCaretPositionEnd(), "(".concat(this.keyboardDOMClass, ")")), this.options.syncInstanceInputs && this.syncInstanceInputs(), "function" === typeof this.options.onChange && this.options.onChange(this.getInput(this.options.inputName, !0)), "function" === typeof this.options.onChangeAll && this.options.onChangeAll(this.getAllInputs())
|
||||
}
|
||||
e && console.log("Key pressed:", t)
|
||||
}
|
||||
}, {
|
||||
key: "handleButtonMouseDown",
|
||||
value: function(t, e) {
|
||||
var n = this;
|
||||
e && (this.options.preventMouseDownDefault && e.preventDefault(), this.options.stopMouseDownPropagation && e.stopPropagation(), e.target.classList.add(this.activeButtonClass)), this.holdInteractionTimeout && clearTimeout(this.holdInteractionTimeout), this.holdTimeout && clearTimeout(this.holdTimeout), this.isMouseHold = !0, this.options.disableButtonHold || (this.holdTimeout = setTimeout((function() {
|
||||
(n.isMouseHold && (!t.includes("{") && !t.includes("}") || "{delete}" === t || "{backspace}" === t || "{bksp}" === t || "{space}" === t || "{tab}" === t) || "{arrowright}" === t || "{arrowleft}" === t || "{arrowup}" === t || "{arrowdown}" === t) && (n.options.debug && console.log("Button held:", t), n.handleButtonHold(t, e)), clearTimeout(n.holdTimeout)
|
||||
}), 500))
|
||||
}
|
||||
}, {
|
||||
key: "handleButtonMouseUp",
|
||||
value: function() {
|
||||
var t = this,
|
||||
e = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : null,
|
||||
n = arguments.length > 1 && void 0 !== arguments[1] ? arguments[1] : null;
|
||||
n && (this.options.preventMouseUpDefault && n.preventDefault(), this.options.stopMouseUpPropagation && n.stopPropagation()), this.recurseButtons((function(e) {
|
||||
e.classList.remove(t.activeButtonClass)
|
||||
})), this.isMouseHold = !1, this.holdInteractionTimeout && clearTimeout(this.holdInteractionTimeout), e && "function" === typeof this.options.onKeyReleased && this.options.onKeyReleased(e)
|
||||
}
|
||||
}, {
|
||||
key: "handleKeyboardContainerMouseDown",
|
||||
value: function(t) {
|
||||
this.options.preventMouseDownDefault && t.preventDefault()
|
||||
}
|
||||
}, {
|
||||
key: "handleButtonHold",
|
||||
value: function(t) {
|
||||
var e = this;
|
||||
this.holdInteractionTimeout && clearTimeout(this.holdInteractionTimeout), this.holdInteractionTimeout = setTimeout((function() {
|
||||
e.isMouseHold ? (e.handleButtonClicked(t), e.handleButtonHold(t)) : clearTimeout(e.holdInteractionTimeout)
|
||||
}), 100)
|
||||
}
|
||||
}, {
|
||||
key: "syncInstanceInputs",
|
||||
value: function() {
|
||||
var t = this;
|
||||
this.dispatch((function(e) {
|
||||
e.replaceInput(t.input), e.setCaretPosition(t.caretPosition, t.caretPositionEnd)
|
||||
}))
|
||||
}
|
||||
}, {
|
||||
key: "clearInput",
|
||||
value: function(t) {
|
||||
t = t || this.options.inputName, this.input[t] = "", this.setCaretPosition(0), this.options.syncInstanceInputs && this.syncInstanceInputs()
|
||||
}
|
||||
}, {
|
||||
key: "getInput",
|
||||
value: function(t) {
|
||||
var e = arguments.length > 1 && void 0 !== arguments[1] && arguments[1];
|
||||
if (t = t || this.options.inputName, this.options.syncInstanceInputs && !e && this.syncInstanceInputs(), this.options.rtl) {
|
||||
var n = this.input[t].replace("\u202b", "").replace("\u202c", "");
|
||||
return "\u202b" + n + "\u202c"
|
||||
}
|
||||
return this.input[t]
|
||||
}
|
||||
}, {
|
||||
key: "getAllInputs",
|
||||
value: function() {
|
||||
var t = this,
|
||||
e = {};
|
||||
return Object.keys(this.input).forEach((function(n) {
|
||||
e[n] = t.getInput(n, !0)
|
||||
})), e
|
||||
}
|
||||
}, {
|
||||
key: "setInput",
|
||||
value: function(t, e) {
|
||||
e = e || this.options.inputName, this.input[e] = t, this.options.syncInstanceInputs && this.syncInstanceInputs()
|
||||
}
|
||||
}, {
|
||||
key: "replaceInput",
|
||||
value: function(t) {
|
||||
this.input = t
|
||||
}
|
||||
}, {
|
||||
key: "setOptions",
|
||||
value: function() {
|
||||
var t = arguments.length > 0 && void 0 !== arguments[0] ? arguments[0] : {},
|
||||
e = this.changedOptions(t);
|
||||
this.options = Object.assign(this.options, t), e.length && (this.options.debug && console.log("changedOptions", e), this.onSetOptions(t), this.render())
|
||||
}
|
||||
}, {
|
||||
key: "changedOptions",
|
||||
value: function(t) {
|
||||
var e = this;
|
||||
return Object.keys(t).filter((function(n) {
|
||||
return JSON.stringify(t[n]) !== JSON.stringify(e.options[n])
|
||||
}))
|
||||
}
|
||||
}, {
|
||||
key: "onSetOptions",
|
||||
value: function(t) {
|
||||
t.inputName && (this.options.debug && console.log("inputName changed. caretPosition reset."), this.setCaretPosition(null))
|
||||
}
|
||||
}, {
|
||||
key: "clear",
|
||||
value: function() {
|
||||
this.keyboardDOM.innerHTML = "", this.keyboardDOM.className = this.keyboardDOMClass, this.buttonElements = {}
|
||||
}
|
||||
}, {
|
||||
key: "dispatch",
|
||||
value: function(t) {
|
||||
if (!window.SimpleKeyboardInstances) throw console.warn("SimpleKeyboardInstances is not defined. Dispatch cannot be called."), new Error("INSTANCES_VAR_ERROR");
|
||||
return Object.keys(window.SimpleKeyboardInstances).forEach((function(e) {
|
||||
t(window.SimpleKeyboardInstances[e], e)
|
||||
}))
|
||||
}
|
||||
}, {
|
||||
key: "addButtonTheme",
|
||||
value: function(t, e) {
|
||||
var n = this;
|
||||
if (!e || !t) return !1;
|
||||
t.split(" ").forEach((function(o) {
|
||||
e.split(" ").forEach((function(e) {
|
||||
n.options.buttonTheme || (n.options.buttonTheme = []);
|
||||
var i = !1;
|
||||
n.options.buttonTheme.map((function(t) {
|
||||
if (t.class.split(" ").includes(e)) {
|
||||
i = !0;
|
||||
var n = t.buttons.split(" ");
|
||||
n.includes(o) || (i = !0, n.push(o), t.buttons = n.join(" "))
|
||||
}
|
||||
return t
|
||||
})), i || n.options.buttonTheme.push({
|
||||
class: e,
|
||||
buttons: t
|
||||
})
|
||||
}))
|
||||
})), this.render()
|
||||
}
|
||||
}, {
|
||||
key: "removeButtonTheme",
|
||||
value: function(t, e) {
|
||||
var n = this;
|
||||
if (!t && !e) return this.options.buttonTheme = [], this.render(), !1;
|
||||
t && Array.isArray(this.options.buttonTheme) && this.options.buttonTheme.length && (t.split(" ").forEach((function(t) {
|
||||
n.options.buttonTheme.map((function(o, i) {
|
||||
if (e && e.includes(o.class) || !e) {
|
||||
var s = o.buttons.split(" ").filter((function(e) {
|
||||
return e !== t
|
||||
}));
|
||||
s.length ? o.buttons = s.join(" ") : (n.options.buttonTheme.splice(i, 1), o = null)
|
||||
}
|
||||
return o
|
||||
}))
|
||||
})), this.render())
|
||||
}
|
||||
}, {
|
||||
key: "getButtonElement",
|
||||
value: function(t) {
|
||||
var e, n = this.buttonElements[t];
|
||||
return n && (e = n.length > 1 ? n : n[0]), e
|
||||
}
|
||||
}, {
|
||||
key: "inputPatternIsValid",
|
||||
value: function(t) {
|
||||
var e, n = this.options.inputPattern;
|
||||
if ((e = n instanceof RegExp ? n : n[this.options.inputName]) && t) {
|
||||
var o = e.test(t);
|
||||
return this.options.debug && console.log('inputPattern ("'.concat(e, '"): ').concat(o ? "passed" : "did not pass!")), o
|
||||
}
|
||||
return !0
|
||||
}
|
||||
}, {
|
||||
key: "setEventListeners",
|
||||
value: function() {
|
||||
!this.isFirstKeyboardInstance && this.allKeyboardInstances || (this.options.debug && console.log("Caret handling started (".concat(this.keyboardDOMClass, ")")), document.addEventListener("keyup", this.handleKeyUp), document.addEventListener("keydown", this.handleKeyDown), document.addEventListener("mouseup", this.handleMouseUp), document.addEventListener("touchend", this.handleTouchEnd))
|
||||
}
|
||||
}, {
|
||||
key: "handleKeyUp",
|
||||
value: function(t) {
|
||||
this.caretEventHandler(t), this.options.physicalKeyboardHighlight && this.physicalKeyboard.handleHighlightKeyUp(t)
|
||||
}
|
||||
}, {
|
||||
key: "handleKeyDown",
|
||||
value: function(t) {
|
||||
this.options.physicalKeyboardHighlight && this.physicalKeyboard.handleHighlightKeyDown(t)
|
||||
}
|
||||
}, {
|
||||
key: "handleMouseUp",
|
||||
value: function(t) {
|
||||
this.caretEventHandler(t)
|
||||
}
|
||||
}, {
|
||||
key: "handleTouchEnd",
|
||||
value: function(t) {
|
||||
this.caretEventHandler(t)
|
||||
}
|
||||
}, {
|
||||
key: "caretEventHandler",
|
||||
value: function(t) {
|
||||
var e;
|
||||
t.target.tagName && (e = t.target.tagName.toLowerCase()), this.dispatch((function(n) {
|
||||
var o = t.target === n.keyboardDOM || t.target && n.keyboardDOM.contains(t.target);
|
||||
n.isMouseHold && (n.isMouseHold = !1), "textarea" !== e && "input" !== e || !("selectionStart" in t.target) || !("selectionEnd" in t.target) || n.options.disableCaretPositioning ? !n.options.disableCaretPositioning && o || n.setCaretPosition(null) : (n.setCaretPosition(t.target.selectionStart, t.target.selectionEnd), n.options.debug && console.log("Caret at: ", n.getCaretPosition(), n.getCaretPositionEnd(), t && t.target.tagName.toLowerCase(), "(".concat(n.keyboardDOMClass, ")")))
|
||||
}))
|
||||
}
|
||||
}, {
|
||||
key: "recurseButtons",
|
||||
value: function(t) {
|
||||
var e = this;
|
||||
t && Object.keys(this.buttonElements).forEach((function(n) {
|
||||
return e.buttonElements[n].forEach(t)
|
||||
}))
|
||||
}
|
||||
}, {
|
||||
key: "destroy",
|
||||
value: function() {
|
||||
this.options.debug && console.log("Destroying simple-keyboard instance: ".concat(this.currentInstanceName)), document.removeEventListener("keyup", this.handleKeyUp), document.removeEventListener("keydown", this.handleKeyDown), document.removeEventListener("mouseup", this.handleMouseUp), document.removeEventListener("touchend", this.handleTouchEnd), document.onpointerup = null, document.ontouchend = null, document.ontouchcancel = null, document.onmouseup = null;
|
||||
var deleteButton = function(t) {
|
||||
t.onpointerdown = null, t.onpointerup = null, t.onpointercancel = null, t.ontouchstart = null, t.ontouchend = null, t.ontouchcancel = null, t.onclick = null, t.onmousedown = null, t.onmouseup = null, t.remove(), t = null
|
||||
};
|
||||
this.recurseButtons(deleteButton), this.recurseButtons = null, deleteButton = null, this.keyboardDOM.onpointerdown = null, this.keyboardDOM.ontouchstart = null, this.keyboardDOM.onmousedown = null, this.clear(), window.SimpleKeyboardInstances[this.currentInstanceName] = null, delete window.SimpleKeyboardInstances[this.currentInstanceName], this.initialized = !1
|
||||
}
|
||||
}, {
|
||||
key: "getButtonThemeClasses",
|
||||
value: function(t) {
|
||||
var e = this.options.buttonTheme,
|
||||
n = [];
|
||||
return Array.isArray(e) && e.forEach((function(e) {
|
||||
if (e.class && "string" === typeof e.class && e.buttons && "string" === typeof e.buttons) {
|
||||
var o = e.class.split(" ");
|
||||
e.buttons.split(" ").includes(t) && (n = [].concat(_toConsumableArray(n), _toConsumableArray(o)))
|
||||
} else console.warn('Incorrect "buttonTheme". Please check the documentation.', e)
|
||||
})), n
|
||||
}
|
||||
}, {
|
||||
key: "setDOMButtonAttributes",
|
||||
value: function(t, e) {
|
||||
var n = this.options.buttonAttributes;
|
||||
Array.isArray(n) && n.forEach((function(n) {
|
||||
n.attribute && "string" === typeof n.attribute && n.value && "string" === typeof n.value && n.buttons && "string" === typeof n.buttons ? n.buttons.split(" ").includes(t) && e(n.attribute, n.value) : console.warn('Incorrect "buttonAttributes". Please check the documentation.', n)
|
||||
}))
|
||||
}
|
||||
}, {
|
||||
key: "onTouchDeviceDetected",
|
||||
value: function() {
|
||||
this.processAutoTouchEvents(), this.disableContextualWindow()
|
||||
}
|
||||
}, {
|
||||
key: "disableContextualWindow",
|
||||
value: function() {
|
||||
window.oncontextmenu = function(t) {
|
||||
if (t.target.classList.contains("hg-button")) return t.preventDefault(), t.stopPropagation(), !1
|
||||
}
|
||||
}
|
||||
}, {
|
||||
key: "processAutoTouchEvents",
|
||||
value: function() {
|
||||
this.options.autoUseTouchEvents && (this.options.useTouchEvents = !0, this.options.debug && console.log("autoUseTouchEvents: Touch device detected, useTouchEvents enabled."))
|
||||
}
|
||||
}, {
|
||||
key: "onInit",
|
||||
value: function() {
|
||||
this.options.debug && console.log("".concat(this.keyboardDOMClass, " Initialized")), this.setEventListeners(), "function" === typeof this.options.onInit && this.options.onInit()
|
||||
}
|
||||
}, {
|
||||
key: "beforeFirstRender",
|
||||
value: function() {
|
||||
this.utilities.isTouchDevice() && this.onTouchDeviceDetected(), "function" === typeof this.options.beforeFirstRender && this.options.beforeFirstRender(), this.isFirstKeyboardInstance && this.utilities.pointerEventsSupported() && !this.options.useTouchEvents && !this.options.useMouseEvents && this.options.debug && console.log("Using PointerEvents as it is supported by this browser"), this.options.useTouchEvents && this.options.debug && console.log("useTouchEvents has been enabled. Only touch events will be used.")
|
||||
}
|
||||
}, {
|
||||
key: "beforeRender",
|
||||
value: function() {
|
||||
"function" === typeof this.options.beforeRender && this.options.beforeRender()
|
||||
}
|
||||
}, {
|
||||
key: "onRender",
|
||||
value: function() {
|
||||
"function" === typeof this.options.onRender && this.options.onRender()
|
||||
}
|
||||
}, {
|
||||
key: "onModulesLoaded",
|
||||
value: function() {
|
||||
"function" === typeof this.options.onModulesLoaded && this.options.onModulesLoaded(this)
|
||||
}
|
||||
}, {
|
||||
key: "loadModules",
|
||||
value: function() {
|
||||
var t = this;
|
||||
Array.isArray(this.options.modules) && (this.options.modules.forEach((function(e) {
|
||||
(new e).init(t)
|
||||
})), this.keyboardPluginClasses = "modules-loaded", this.render(), this.onModulesLoaded())
|
||||
}
|
||||
}, {
|
||||
key: "getModuleProp",
|
||||
value: function(t, e) {
|
||||
return !!this.modules[t] && this.modules[t][e]
|
||||
}
|
||||
}, {
|
||||
key: "getModulesList",
|
||||
value: function() {
|
||||
return Object.keys(this.modules)
|
||||
}
|
||||
}, {
|
||||
key: "parseRowDOMContainers",
|
||||
value: function(t, e, n, o) {
|
||||
var i = this,
|
||||
s = Array.from(t.children),
|
||||
a = 0;
|
||||
return s.length && n.forEach((function(n, r) {
|
||||
var u = o[r];
|
||||
if (!u || !(u > n)) return !1;
|
||||
var c = n - a,
|
||||
l = u - a,
|
||||
h = document.createElement("div");
|
||||
h.className += "hg-button-container";
|
||||
var d = "".concat(i.options.layoutName, "-r").concat(e, "c").concat(r);
|
||||
h.setAttribute("data-skUID", d);
|
||||
var p = s.splice(c, l - c + 1);
|
||||
a = l - c, p.forEach((function(t) {
|
||||
return h.appendChild(t)
|
||||
})), s.splice(c, 0, h), t.innerHTML = "", s.forEach((function(e) {
|
||||
return t.appendChild(e)
|
||||
})), i.options.debug && console.log("rowDOMContainer", p, c, l, a + 1)
|
||||
})), t
|
||||
}
|
||||
}, {
|
||||
key: "render",
|
||||
value: function() {
|
||||
var t = this;
|
||||
this.clear(), this.initialized || this.beforeFirstRender(), this.beforeRender();
|
||||
var e = "hg-layout-".concat(this.options.layoutName),
|
||||
n = this.options.layout || {
|
||||
default: ["` 1 2 3 4 5 6 7 8 9 0 - = {bksp}", "{tab} q w e r t y u i o p [ ] \\", "{lock} a s d f g h j k l ; ' {enter}", "{shift} z x c v b n m , . / {shift}", ".com @ {space}"],
|
||||
shift: ["~ ! @ # $ % ^ & * ( ) _ + {bksp}", "{tab} Q W E R T Y U I O P { } |", '{lock} A S D F G H J K L : " {enter}', "{shift} Z X C V B N M < > ? {shift}", ".com @ {space}"]
|
||||
},
|
||||
o = this.options.useTouchEvents || !1,
|
||||
i = o ? "hg-touch-events" : "",
|
||||
s = this.options.useMouseEvents || !1,
|
||||
a = this.options.disableRowButtonContainers;
|
||||
this.keyboardDOM.className = this.getKeyboardClassString(this.options.theme, e, this.keyboardPluginClasses, i), n[this.options.layoutName].forEach((function(e, n) {
|
||||
var i = e.split(" "),
|
||||
r = document.createElement("div");
|
||||
r.className += "hg-row";
|
||||
var u = [],
|
||||
c = [];
|
||||
i.forEach((function(e, i) {
|
||||
var l, h = !a && "string" === typeof e && e.length > 1 && 0 === e.indexOf("["),
|
||||
d = !a && "string" === typeof e && e.length > 1 && e.indexOf("]") === e.length - 1;
|
||||
h && (u.push(i), e = e.replace(/\[/g, "")), d && (c.push(i), e = e.replace(/\]/g, ""));
|
||||
var p = t.utilities.getButtonClass(e),
|
||||
f = t.utilities.getButtonDisplayName(e, t.options.display, t.options.mergeDisplay),
|
||||
y = t.options.useButtonTag ? "button" : "div",
|
||||
b = document.createElement(y);
|
||||
b.className += "hg-button ".concat(p),
|
||||
/*(l = b.classList).add.apply(l, _toConsumableArray(t.getButtonThemeClasses(e))),*/
|
||||
t.setDOMButtonAttributes(e, (function(t, e) {
|
||||
b.setAttribute(t, e)
|
||||
})), t.activeButtonClass = "hg-activeButton", !t.utilities.pointerEventsSupported() || o || s ? o ? (b.ontouchstart = function(n) {
|
||||
t.handleButtonClicked(e), t.handleButtonMouseDown(e, n)
|
||||
}, b.ontouchend = function(n) {
|
||||
t.handleButtonMouseUp(e, n)
|
||||
}, b.ontouchcancel = function(n) {
|
||||
t.handleButtonMouseUp(e, n)
|
||||
}) : (b.onclick = function() {
|
||||
t.isMouseHold = !1, t.handleButtonClicked(e)
|
||||
}, b.onmousedown = function(n) {
|
||||
t.handleButtonMouseDown(e, n)
|
||||
}, b.onmouseup = function(n) {
|
||||
t.handleButtonMouseUp(e, n)
|
||||
}) : (b.onpointerdown = function(n) {
|
||||
t.handleButtonClicked(e), t.handleButtonMouseDown(e, n)
|
||||
}, b.onpointerup = function(n) {
|
||||
t.handleButtonMouseUp(e, n)
|
||||
}, b.onpointercancel = function(n) {
|
||||
t.handleButtonMouseUp(e, n)
|
||||
}), b.setAttribute("data-skBtn", e);
|
||||
var m = "".concat(t.options.layoutName, "-r").concat(n, "b").concat(i);
|
||||
b.setAttribute("data-skBtnUID", m);
|
||||
var g = document.createElement("span");
|
||||
g.innerHTML = f, b.appendChild(g), t.buttonElements[e] || (t.buttonElements[e] = []), t.buttonElements[e].push(b), r.appendChild(b)
|
||||
})), r = t.parseRowDOMContainers(r, n, u, c), t.keyboardDOM.appendChild(r)
|
||||
})), this.onRender(), this.initialized || (this.initialized = !0, !this.utilities.pointerEventsSupported() || o || s ? o ? (document.ontouchend = function() {
|
||||
return t.handleButtonMouseUp()
|
||||
}, document.ontouchcancel = function() {
|
||||
return t.handleButtonMouseUp()
|
||||
}, this.keyboardDOM.ontouchstart = function(e) {
|
||||
return t.handleKeyboardContainerMouseDown(e)
|
||||
}) : o || (document.onmouseup = function() {
|
||||
return t.handleButtonMouseUp()
|
||||
}, this.keyboardDOM.onmousedown = function(e) {
|
||||
return t.handleKeyboardContainerMouseDown(e)
|
||||
}) : (document.onpointerup = function() {
|
||||
return t.handleButtonMouseUp()
|
||||
}, this.keyboardDOM.onpointerdown = function(e) {
|
||||
return t.handleKeyboardContainerMouseDown(e)
|
||||
}), this.onInit())
|
||||
}
|
||||
}]) && Keyboard_defineProperties(t.prototype, e), n && Keyboard_defineProperties(t, n), SimpleKeyboard
|
||||
}();
|
||||
e.default = c
|
||||
}])
|
||||
}));
|
||||
//# sourceMappingURL=index.js.map
|
||||
@@ -0,0 +1,12 @@
|
||||
/*!
|
||||
*
|
||||
* simple-keyboard v2.32.123
|
||||
* https://github.com/hodgef/simple-keyboard
|
||||
*
|
||||
* Copyright (c) Francisco Hodge (https://github.com/hodgef)
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
*/.hg-theme-default{width:100%;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;box-sizing:border-box;overflow:hidden;touch-action:manipulation}.hg-theme-default .hg-button span{pointer-events:none}.hg-theme-default button.hg-button{border-width:0;outline:0;font-size:inherit}.hg-theme-default{font-family:"HelveticaNeue-Light","Helvetica Neue Light","Helvetica Neue",Helvetica,Arial,"Lucida Grande",sans-serif;background-color:#ececec;padding:5px;border-radius:5px}.hg-theme-default .hg-button{display:inline-block;flex-grow:1}.hg-theme-default .hg-row{display:flex}.hg-theme-default .hg-row:not(:last-child){margin-bottom:5px}.hg-theme-default .hg-row .hg-button-container,.hg-theme-default .hg-row .hg-button:not(:last-child){margin-right:5px}.hg-theme-default .hg-row>div:last-child{margin-right:0}.hg-theme-default .hg-row .hg-button-container{display:flex}.hg-theme-default .hg-button{box-shadow:0 0 3px -1px rgba(0,0,0,.3);height:40px;border-radius:5px;box-sizing:border-box;padding:5px;background:#fff;border-bottom:1px solid #b5b5b5;cursor:pointer;display:flex;align-items:center;justify-content:center;-webkit-tap-highlight-color:rgba(0,0,0,0)}.hg-theme-default .hg-button.hg-activeButton{background:#efefef}.hg-theme-default.hg-layout-numeric .hg-button{width:33.3%;height:60px;align-items:center;display:flex;justify-content:center}.hg-theme-default .hg-button.hg-button-numpadadd,.hg-theme-default .hg-button.hg-button-numpadenter{height:85px}.hg-theme-default .hg-button.hg-button-numpad0{width:105px}.hg-theme-default .hg-button.hg-button-com{max-width:85px}.hg-theme-default .hg-button.hg-standardBtn.hg-button-at{max-width:45px}.hg-theme-default .hg-button.hg-selectedButton{background:rgba(5,25,70,.53);color:#fff}.hg-theme-default .hg-button.hg-standardBtn[data-skbtn=".com"]{max-width:82px}.hg-theme-default .hg-button.hg-standardBtn[data-skbtn="@"]{max-width:60px}
|
||||
/*# sourceMappingURL=index.css.map */
|
||||
@@ -0,0 +1,962 @@
|
||||
/**
|
||||
* SpatialNavigator simulates four-direction navigation in Javascript level.
|
||||
*
|
||||
* Navigation is the ability to navigate between focusable elements
|
||||
* within a structured document or user interface according to the spatial
|
||||
* location. Users are assumed navigating among elements on a 2D plane by
|
||||
* arrow keys (up/down/left/right).
|
||||
*
|
||||
* SpatialNavigator keeps a 'focused' element by itself. When navigating,
|
||||
* focus/unfocus events are triggered automatically. Notice the focus is just
|
||||
* an internal state rather than actual focus of DOM Element. User should
|
||||
* add event listeners of those events, and design required behaviors.
|
||||
*
|
||||
* @class SpatialNavigator
|
||||
* @param {Array.<SpatialNavigatorElement>} [collection=[]]
|
||||
* An initial set of traversable elements.
|
||||
* @param {Object} [config]
|
||||
* An initial set of configurations.
|
||||
*/
|
||||
/**
|
||||
* SpatialNavigatorElement is a navigable element which can be traversed
|
||||
* by {@link SpatialNavigator}. Valid types are as follows:
|
||||
*
|
||||
* 1. a standard HTMLElement.
|
||||
* 2. an Object contains at least 4 properties: left, top, width, and height.
|
||||
* 3. an Object implementing getBoundingRect() which returns an object of 2.
|
||||
*
|
||||
* @typedef {Object} SpatialNavigatorElement
|
||||
*/
|
||||
/**
|
||||
* Fired when an element is focused.
|
||||
* @event SpatialNavigator#focus
|
||||
* @property {SpatialNavigatorElement} elem The element which got focus.
|
||||
*/
|
||||
/**
|
||||
* Fired when an element is unfocused.
|
||||
* @event SpatialNavigator#unfocus
|
||||
* @property {SpatialNavigatorElement} elem The element which lost focus.
|
||||
*/
|
||||
var SpatialNavigator = function () {
|
||||
this._focus = null;
|
||||
this._previous = null;
|
||||
this._collection = [];
|
||||
|
||||
//this.setCollection(collection);
|
||||
|
||||
/*
|
||||
if (config) {
|
||||
for (var key in config) {
|
||||
this[key] = config[key];
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
SpatialNavigator.prototype = {
|
||||
/**
|
||||
* Limit the navigating direction to vertical and horizontal only. Targets
|
||||
* in oblique (left-top, right-top, left-bottom, and right-bottom)
|
||||
* directions are always ignored.
|
||||
* @type {Boolean}
|
||||
* @default false
|
||||
* @memberof SpatialNavigator.prototype
|
||||
*/
|
||||
straightOnly: true,
|
||||
|
||||
/**
|
||||
* This threshold is used to determine whether an element is considered in
|
||||
* straight (vertical or horizontal) directions. Valid number is between 0
|
||||
* to 1.0. Setting it to 0.3 means an element is counted in the straight
|
||||
* directions if it overlaps the straight area at least 0.3x of width of the
|
||||
* area.
|
||||
* @type {Number}
|
||||
* @default 0.5
|
||||
* @memberof SpatialNavigator.prototype
|
||||
*/
|
||||
straightOverlapThreshold: 0.5,
|
||||
|
||||
/**
|
||||
* Ignore elements with "display: none", "visibility: hidden" or
|
||||
* "aria-hidden=true".
|
||||
* @type {Boolean}
|
||||
* @default false
|
||||
* @memberof SpatialNavigator.prototype
|
||||
*/
|
||||
ignoreHiddenElement: false,
|
||||
|
||||
/**
|
||||
* The previous focused element has high priority to be chosen as the next
|
||||
* candidate.
|
||||
* @type {Boolean}
|
||||
* @default false
|
||||
* @memberof SpatialNavigator.prototype
|
||||
*/
|
||||
rememberSource: false,
|
||||
|
||||
/**
|
||||
* A callback function that accepcts an element as the first argument will
|
||||
* be triggered everytime when SpatialNavigator tries to traverse every
|
||||
* single candidate. You can ignore arbitrary elements by returning "false"
|
||||
* in this function.
|
||||
* @type {Function}
|
||||
* @default null
|
||||
* @memberof SpatialNavigator.prototype
|
||||
*/
|
||||
navigableFilter: null,
|
||||
|
||||
/**
|
||||
* setting this property true prevents spatialNavigator from emitting any
|
||||
* events.
|
||||
* @type {Boolean}
|
||||
*/
|
||||
silent: false,
|
||||
|
||||
/**
|
||||
* Rect represents position and dimension of a 2D object.
|
||||
* @typedef {Object} Rect
|
||||
* @property {Integer} left Left position
|
||||
* @property {Integer} top Top position
|
||||
* @property {Integer} right Right position
|
||||
* @property {Integer} bottom Bottom position
|
||||
* @property {Integer} width Width dimension
|
||||
* @property {Integer} height Height dimension
|
||||
* @property {Rect} [center] Center position
|
||||
* @property {Integer} [x] same as left
|
||||
* @property {Integer} [y] same as top
|
||||
* @access private
|
||||
* @memberof SpatialNavigator.prototype
|
||||
*/
|
||||
|
||||
|
||||
follow: function ( type, listener ) {
|
||||
|
||||
if ( this._listeners === undefined ) this._listeners = {};
|
||||
|
||||
var listeners = this._listeners;
|
||||
|
||||
if ( listeners[ type ] === undefined ) {
|
||||
|
||||
listeners[ type ] = [];
|
||||
|
||||
}
|
||||
|
||||
if ( listeners[ type ].indexOf( listener ) === - 1 ) {
|
||||
|
||||
listeners[ type ].push( listener );
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
hasListener: function ( type, listener ) {
|
||||
|
||||
if ( this._listeners === undefined ) return false;
|
||||
|
||||
var listeners = this._listeners;
|
||||
|
||||
return listeners[ type ] !== undefined && listeners[ type ].indexOf( listener ) !== - 1;
|
||||
|
||||
},
|
||||
|
||||
removeListener: function ( type, listener ) {
|
||||
|
||||
if ( this._listeners === undefined ) return;
|
||||
|
||||
var listeners = this._listeners;
|
||||
var listenerArray = listeners[ type ];
|
||||
|
||||
if ( listenerArray !== undefined ) {
|
||||
|
||||
var index = listenerArray.indexOf( listener );
|
||||
|
||||
if ( index !== - 1 ) {
|
||||
|
||||
listenerArray.splice( index, 1 );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
send: function ( type,event ) {
|
||||
|
||||
if ( this._listeners === undefined ) return;
|
||||
|
||||
var listeners = this._listeners;
|
||||
var listenerArray = listeners[ type ];
|
||||
|
||||
if ( listenerArray !== undefined ) {
|
||||
|
||||
event.target = this;
|
||||
|
||||
var array = listenerArray.slice( 0 );
|
||||
|
||||
for ( var i = 0, l = array.length; i < l; i ++ ) {
|
||||
|
||||
array[ i ].call( this, event );
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Get {@link Rect} of a {@link SpatialNavigatorElement}.
|
||||
*
|
||||
* @param {SpatialNavigatorElement} elem
|
||||
*
|
||||
* @return {Rect} dimension of elem.
|
||||
*
|
||||
* @access private
|
||||
* @memberof SpatialNavigator.prototype
|
||||
*/
|
||||
_getRect: function snGetRect(elem) {
|
||||
var rect = null;
|
||||
|
||||
if (!this._isNavigable(elem)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (elem.getBoundingClientRect) {
|
||||
var cr = elem.getBoundingClientRect();
|
||||
rect = {
|
||||
left: cr.left,
|
||||
top: cr.top,
|
||||
width: cr.width,
|
||||
height: cr.height
|
||||
};
|
||||
} else if (elem.left !== undefined) {
|
||||
rect = {
|
||||
left: parseInt(elem.left || 0, 10),
|
||||
top: parseInt(elem.top || 0, 10),
|
||||
width: parseInt(elem.width || 0, 10),
|
||||
height: parseInt(elem.height || 0, 10)
|
||||
};
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
rect.element = elem;
|
||||
rect.right = rect.left + rect.width;
|
||||
rect.bottom = rect.top + rect.height;
|
||||
rect.center = {
|
||||
x: rect.left + Math.floor(rect.width / 2),
|
||||
y: rect.top + Math.floor(rect.height / 2)
|
||||
};
|
||||
rect.center.left = rect.center.right = rect.center.x;
|
||||
rect.center.top = rect.center.bottom = rect.center.y;
|
||||
|
||||
return rect;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get all {@link Rect} objects from the collection.
|
||||
*
|
||||
* @param {SpatialNavigatorElement} [excludedElem]
|
||||
* You can pass excludedElem here to ignore it from calculating.
|
||||
* (most likely, the currently focused element is passed).
|
||||
*
|
||||
* @return {Array.<Rect>} {@link Rect} objects of all traversable elements.
|
||||
*
|
||||
* @access private
|
||||
* @memberof SpatialNavigator.prototype
|
||||
*/
|
||||
_getAllRects: function snGetAllRects(excludedElem) {
|
||||
var rects = [];
|
||||
|
||||
this._collection.forEach(function (elem) {
|
||||
if (!excludedElem || excludedElem !== elem) {
|
||||
var rect = this._getRect(elem);
|
||||
if (rect) {
|
||||
rects.push(rect);
|
||||
}
|
||||
}
|
||||
}, this);
|
||||
|
||||
return rects;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check whether a {@link SpatialNavigatorElement} is navigable.
|
||||
*
|
||||
* @param {SpatialNavigatorElement} elem
|
||||
*
|
||||
* @return {Boolean} true if it's navigable.
|
||||
*
|
||||
* @access private
|
||||
* @memberof SpatialNavigator.prototype
|
||||
*/
|
||||
_isNavigable: function snIsNavigable(elem) {
|
||||
if (this.ignoreHiddenElement && elem instanceof HTMLElement) {
|
||||
var computedStyle = window.getComputedStyle(elem);
|
||||
if ((elem.offsetWidth <= 0 && elem.offsetHeight <= 0) ||
|
||||
computedStyle.getPropertyValue('visibility') == 'hidden' ||
|
||||
computedStyle.getPropertyValue('display') == 'none' ||
|
||||
elem.hasAttribute('aria-hidden')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (this.navigableFilter && !this.navigableFilter(elem)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Given a set of {@link Rect} array, divide them into 9 groups with
|
||||
* respect to the position of targetRect. Rects centered inside targetRect
|
||||
* are grouped as 4th group; straight left as 3rd group; straight right as
|
||||
* 5th group; ..... and so on. See below for the corresponding group number:
|
||||
*
|
||||
* <pre>
|
||||
* |---+---+---|
|
||||
* | 0 | 1 | 2 |
|
||||
* |---+---+---|
|
||||
* | 3 | 4 | 5 |
|
||||
* |---+---+---|
|
||||
* | 6 | 7 | 8 |
|
||||
* |---+---+---|
|
||||
* </pre>
|
||||
*
|
||||
* @param {Array.<Rect>} rects
|
||||
* {@link RectS} to be divided.
|
||||
* @param {Rect} targetRect
|
||||
* Reference position for groups.
|
||||
*
|
||||
* @return {Array.Array.<SpatialNavigatorElement>}
|
||||
* A 9-elements array of array, where rects are categorized into
|
||||
* these 9 arrays by their group number.
|
||||
*
|
||||
* @access private
|
||||
* @memberof SpatialNavigator.prototype
|
||||
*
|
||||
*/
|
||||
_partition: function snDemarcate(rects, targetRect) {
|
||||
var groups = [[], [], [], [], [], [], [], [], []];
|
||||
|
||||
var threshold = this.straightOverlapThreshold;
|
||||
if (threshold > 1 || threshold < 0) {
|
||||
// Fallback to default value
|
||||
threshold = 0.5;
|
||||
}
|
||||
|
||||
rects.forEach(function (rect) {
|
||||
var center = rect.center;
|
||||
var x, y, groupId;
|
||||
|
||||
if (center.x < targetRect.left) {
|
||||
x = 0;
|
||||
} else if (center.x <= targetRect.right) {
|
||||
x = 1;
|
||||
} else {
|
||||
x = 2;
|
||||
}
|
||||
|
||||
if (center.y < targetRect.top) {
|
||||
y = 0;
|
||||
} else if (center.y <= targetRect.bottom) {
|
||||
y = 1;
|
||||
} else {
|
||||
y = 2;
|
||||
}
|
||||
|
||||
groupId = y * 3 + x;
|
||||
groups[groupId].push(rect);
|
||||
|
||||
// Although a rect is in the oblique directions, we categorize it in
|
||||
// the straight area as well if it overlaps the straight directions more
|
||||
// than a specified threshold (0.5 by default).
|
||||
if ([0, 2, 6, 8].indexOf(groupId) !== -1) {
|
||||
if (rect.left <= targetRect.right - targetRect.width * threshold) {
|
||||
if (groupId === 2) {
|
||||
groups[1].push(rect);
|
||||
} else if (groupId === 8) {
|
||||
groups[7].push(rect);
|
||||
}
|
||||
}
|
||||
|
||||
if (rect.right >= targetRect.left + targetRect.width * threshold) {
|
||||
if (groupId === 0) {
|
||||
groups[1].push(rect);
|
||||
} else if (groupId === 6) {
|
||||
groups[7].push(rect);
|
||||
}
|
||||
}
|
||||
|
||||
if (rect.top <= targetRect.bottom - targetRect.height * threshold) {
|
||||
if (groupId === 6) {
|
||||
groups[3].push(rect);
|
||||
} else if (groupId === 8) {
|
||||
groups[5].push(rect);
|
||||
}
|
||||
}
|
||||
|
||||
if (rect.bottom >= targetRect.top + targetRect.height * threshold) {
|
||||
if (groupId === 0) {
|
||||
groups[3].push(rect);
|
||||
} else if (groupId === 2) {
|
||||
groups[5].push(rect);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return groups;
|
||||
},
|
||||
|
||||
/**
|
||||
* Bind targetRect to a set of distance functions for ranking. These
|
||||
* functions work with another {@link Rect} object passed to get a ranking
|
||||
* value relative to targetRect.
|
||||
*
|
||||
* @param {Rect} targetRect
|
||||
*
|
||||
* @return {Object.<function>}
|
||||
* An object containing a bunch of functions bound with targetRect.
|
||||
*
|
||||
* @access private
|
||||
* @memberof SpatialNavigator.prototype
|
||||
*/
|
||||
_getDistanceFunction: function snGetDistanceFunction(targetRect) {
|
||||
return {
|
||||
/* Plumb Line: a vertical line through the center of the
|
||||
targetRect. */
|
||||
nearPlumbLineIsBetter: function (rect) {
|
||||
var d;
|
||||
if (rect.center.x < targetRect.center.x) {
|
||||
d = targetRect.center.x - rect.right;
|
||||
} else {
|
||||
d = rect.left - targetRect.center.x;
|
||||
}
|
||||
return d < 0 ? 0 : d;
|
||||
},
|
||||
|
||||
/* Horizon: a horizontal line through the center of the
|
||||
"targetRect". */
|
||||
nearHorizonIsBetter: function (rect) {
|
||||
var d;
|
||||
if (rect.center.y < targetRect.center.y) {
|
||||
d = targetRect.center.y - rect.bottom;
|
||||
} else {
|
||||
d = rect.top - targetRect.center.y;
|
||||
}
|
||||
return d < 0 ? 0 : d;
|
||||
},
|
||||
|
||||
/* Target Left: a coincident line of the left edge of the
|
||||
"targetRect". */
|
||||
nearTargetLeftIsBetter: function (rect) {
|
||||
var d;
|
||||
if (rect.center.x < targetRect.center.x) {
|
||||
d = targetRect.left - rect.right;
|
||||
} else {
|
||||
d = rect.left - targetRect.left;
|
||||
}
|
||||
return d < 0 ? 0 : d;
|
||||
},
|
||||
|
||||
/* Target Top: a coincident line of the top edge of the
|
||||
"targetRect". */
|
||||
nearTargetTopIsBetter: function (rect) {
|
||||
var d;
|
||||
if (rect.center.y < targetRect.center.y) {
|
||||
d = targetRect.top - rect.bottom;
|
||||
} else {
|
||||
d = rect.top - targetRect.top;
|
||||
}
|
||||
return d < 0 ? 0 : d;
|
||||
},
|
||||
|
||||
/* top, bottom, left, and right: Just ranking by absolute coordinate
|
||||
without respect to targetRect. Usually they are used as fallback
|
||||
rules when ranks above are draw. */
|
||||
topIsBetter: function (rect) {
|
||||
return rect.top;
|
||||
},
|
||||
bottomIsBetter: function (rect) {
|
||||
return -1 * rect.bottom;
|
||||
},
|
||||
leftIsBetter: function (rect) {
|
||||
return rect.left;
|
||||
},
|
||||
rightIsBetter: function (rect) {
|
||||
return -1 * rect.right;
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* PrioritySet contains a set of elements with distance functions that
|
||||
* should be used to rank them (obtained from {@link
|
||||
* SpatialNavigator#_getDistanceFunction}).
|
||||
*
|
||||
* @typedef PrioritySet
|
||||
* @property {Array.<Rects>} group
|
||||
* {@link Rects} of elements that need to be prioritized.
|
||||
* @property {Array.<function>} distance
|
||||
* Distance functions. Primary ranking rule should be put in index
|
||||
* 0; secondary in index 1 (fallback rule when primary rule draws
|
||||
* ); and so on.
|
||||
* @access private
|
||||
* @memberof SpatialNavigator.prototype
|
||||
*/
|
||||
/**
|
||||
* Pick a {@link Rect} with highest priority.
|
||||
*
|
||||
* @param {Array.<PrioritySet>} priorities
|
||||
* An array of {@link PrioritySet} that need to be prioritized. The
|
||||
* set with lowest index containing non-empty {PrioritySet.group}
|
||||
* would be prioritized.
|
||||
* @param {SpatialNavigatorElement} target
|
||||
* The origin of coordinates for traversal.
|
||||
* @param {String} direction
|
||||
* It should be "left", "right", "up" or "down".
|
||||
*
|
||||
* @return {Rect} the {@link Rect} of highest priority.
|
||||
*
|
||||
* @access private
|
||||
* @memberof SpatialNavigator.prototype
|
||||
*/
|
||||
_prioritize: function snPrioritize(priorities, target, direction) {
|
||||
var destPriority = priorities.find(function (p) {
|
||||
return !!p.group.length;
|
||||
});
|
||||
|
||||
if (!destPriority) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (this.rememberSource &&
|
||||
this._previous &&
|
||||
target == this._previous.destination &&
|
||||
direction == this._previous.reverse) {
|
||||
|
||||
var source = this._previous.source;
|
||||
var found = destPriority.group.find(function (dest) {
|
||||
return dest.element == source;
|
||||
});
|
||||
if (found) {
|
||||
return found;
|
||||
}
|
||||
}
|
||||
|
||||
destPriority.group.sort(function (a, b) {
|
||||
return destPriority.distance.reduce(function (answer, distance) {
|
||||
return answer || (distance(a) - distance(b));
|
||||
}, 0);
|
||||
});
|
||||
|
||||
return destPriority.group[0];
|
||||
},
|
||||
|
||||
/**
|
||||
* Replace the set of traversable elements.
|
||||
*
|
||||
* @param {Array.<SpatialNavigatorElement>} [collection=[]]
|
||||
elements to be replaced. The array is deep-copied and never
|
||||
be changed directly by SpatialNavigator.
|
||||
*
|
||||
* @fires SpatialNavigator#unfocus
|
||||
* @memberof SpatialNavigator.prototype
|
||||
*/
|
||||
setCollection: function snSetCollection(collection) {
|
||||
this.unfocus();
|
||||
this._collection = [];
|
||||
if (collection) {
|
||||
this.multiAdd(collection);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Add an element to traversable set.
|
||||
*
|
||||
* @param {SpatialNavigatorElement} elem
|
||||
* @return {Boolean} true if succeed.
|
||||
*
|
||||
* @memberof SpatialNavigator.prototype
|
||||
*/
|
||||
add: function snAdd(elem) {
|
||||
var index = this._collection.indexOf(elem);
|
||||
if (index >= 0) {
|
||||
return false;
|
||||
}
|
||||
this._collection.push(elem);
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a bunch of elements to traversable set.
|
||||
*
|
||||
* @param {Array.<SpatialNavigatorElement>} elements
|
||||
* @return {Boolean} true if all elements are added successfully.
|
||||
*
|
||||
* @memberof SpatialNavigator.prototype
|
||||
*/
|
||||
multiAdd: function snMultiAdd(elements) {
|
||||
return Array.from(elements).every(this.add, this);
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove an element from traversable set.
|
||||
*
|
||||
* @param {SpatialNavigatorElement} elem
|
||||
* @return {Boolean} true if succeed. false if elem does not exist.
|
||||
*
|
||||
* @fires SpatialNavigator#unfocus
|
||||
* @memberof SpatialNavigator.prototype
|
||||
*/
|
||||
remove: function snRemove(elem) {
|
||||
var index = this._collection.indexOf(elem);
|
||||
if (index < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this._focus === elem) {
|
||||
this.unfocus();
|
||||
}
|
||||
|
||||
this._collection.splice(index, 1);
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove a bunch of elements to traversable set.
|
||||
*
|
||||
* @param {Array.<SpatialNavigatorElement>} elements
|
||||
* @return {Boolean} true if all elements are removed successfully.
|
||||
*
|
||||
* @memberof SpatialNavigator.prototype
|
||||
*/
|
||||
multiRemove: function snMultiRemove(elements) {
|
||||
return Array.from(elements).every(this.remove, this);
|
||||
},
|
||||
|
||||
focused: function (elem) {
|
||||
this._focus = elem;
|
||||
},
|
||||
|
||||
/**
|
||||
* Move focus to an existing element.
|
||||
*
|
||||
* @param {SpatialNavigatorElement} [elem]
|
||||
* when omitted, it focuses the last focused element or the first
|
||||
* navigable element if no previously-focused element is found.
|
||||
*
|
||||
* @return {Boolean} true if succeed. false if element doesn't exist.
|
||||
*
|
||||
* @fires SpatialNavigator#focus
|
||||
* @fires SpatialNavigator#unfocus
|
||||
* @memberof SpatialNavigator.prototype
|
||||
*/
|
||||
focus: function snFocus(elem) {
|
||||
// If no arguments are received, let current focused element be the
|
||||
// default.
|
||||
if (!elem && this._focus && this._isNavigable(this._focus)) {
|
||||
elem = this._focus;
|
||||
}
|
||||
|
||||
if (!this._collection) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!elem) {
|
||||
var navigableElems = this._collection.filter(this._isNavigable, this);
|
||||
if (!navigableElems.length) {
|
||||
return false;
|
||||
}
|
||||
elem = navigableElems[0];
|
||||
} else if (this._collection.indexOf(elem) < 0 ||
|
||||
!this._isNavigable(elem)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.unfocus();
|
||||
this._focus = elem;
|
||||
|
||||
if (!this.silent) {
|
||||
this.send('focus',{elem: this._focus });
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove focus if any.
|
||||
*
|
||||
* It will trigger "unfocus" event.
|
||||
*
|
||||
* @return {Boolean} succeed or not.
|
||||
*
|
||||
* @fires SpatialNavigator#unfocus
|
||||
* @memberof SpatialNavigator.prototype
|
||||
*/
|
||||
unfocus: function snUnfocus() {
|
||||
if (this._focus) {
|
||||
var elem = this._focus;
|
||||
this._focus = null;
|
||||
if (!this.silent) {
|
||||
this.send('unfocus',{ elem: elem });
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get the currently focused element.
|
||||
*
|
||||
* @return {SpatialNavigatorElement} or null if nothing focused.
|
||||
*
|
||||
* @memberof SpatialNavigator.prototype
|
||||
*/
|
||||
getFocusedElement: function snGetFocusedElement() {
|
||||
return this._focus;
|
||||
},
|
||||
|
||||
/**
|
||||
* Given a direction, find the element nearest to the focus element in that
|
||||
* direction. This is equivalent to {@link SpatialNavigator#navigate} with
|
||||
* focused element passed as target.
|
||||
*
|
||||
* @param {String} direction
|
||||
* It should be "left", "right", "up" or "down".
|
||||
*
|
||||
* @return {Boolean} true if succeed, false if nothing can be focused.
|
||||
*
|
||||
* @memberof SpatialNavigator.prototype
|
||||
*/
|
||||
move: function snMove(direction) {
|
||||
var reverse = {
|
||||
'left': 'right',
|
||||
'up': 'down',
|
||||
'right': 'left',
|
||||
'down': 'up'
|
||||
};
|
||||
|
||||
if (!this._focus) {
|
||||
this._previous = null;
|
||||
this.focus();
|
||||
} else {
|
||||
var elem = this.navigate(this._focus, direction);
|
||||
if (!elem) {
|
||||
return false;
|
||||
}
|
||||
if (this.rememberSource) {
|
||||
this._previous = {
|
||||
source: this._focus,
|
||||
destination: elem,
|
||||
reverse: reverse[direction.toLowerCase()]
|
||||
};
|
||||
}
|
||||
this.unfocus();
|
||||
this.focus(elem);
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
|
||||
canmove: function (direction) {
|
||||
if (this._focus) {
|
||||
var elem = this.navigate(this._focus, direction);
|
||||
|
||||
if (elem !== null) return elem;
|
||||
}
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Given a direction, find an element nearest to the target element in that
|
||||
* direction.
|
||||
*
|
||||
* @param {SpatialNavigatorElement} target
|
||||
* The origin of coordinates for traversal.
|
||||
* @param {String} direction
|
||||
* It should be "left", "right", "up" or "down".
|
||||
*
|
||||
* @return {SpatialNavigatorElement}
|
||||
* The destination of the element which has the highest priority.
|
||||
*
|
||||
* @memberof SpatialNavigator.prototype
|
||||
*/
|
||||
navigate: function snNavigate(target, direction) {
|
||||
if (!target || !direction || !this._collection) {
|
||||
return null;
|
||||
}
|
||||
|
||||
direction = direction.toLowerCase();
|
||||
|
||||
var rects = this._getAllRects(target);
|
||||
var targetRect = this._getRect(target);
|
||||
if (!targetRect || !rects.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/* Get distance functions for ranking priorities relative to targetRect */
|
||||
var distanceFunction = this._getDistanceFunction(targetRect);
|
||||
|
||||
/* Candidate {@link Rect}s are divided into nine regions based on its
|
||||
position with respect to targetRect. */
|
||||
var groups = this._partition(rects, targetRect);
|
||||
|
||||
/* {@link Rect}s in group 4 overlaps with targetRect. We distribute them
|
||||
further into 9 regions based on its position with respect to the
|
||||
center point of targetRect. */
|
||||
var internalGroups = this._partition(groups[4], targetRect.center);
|
||||
|
||||
/* priorities: This big array carrys candidate elements with related
|
||||
* distance functions by appropriate priority we want. Depenging on the
|
||||
* direction, 3 kinds of elements are added separately in the following
|
||||
* order:
|
||||
*
|
||||
* - 1st: candidates centered inside targetRect (group 4)
|
||||
* (so we pick up corresponding internalGroups).
|
||||
* - 2nd: in groups of straight direction (group 1, 3, 5, 7).
|
||||
* - 3rd: in groups of oblique direction (group 0, 2, 6, 8).
|
||||
*
|
||||
* For each kind of element above, ranking is performed by the following
|
||||
* rules (distance functions) in order:
|
||||
*
|
||||
* - 1st: distance between candidate and target.
|
||||
* - 2nd: absolute coordinate of candidates.
|
||||
* - 3rd: distance of left or top coordinate between candidate and
|
||||
* target (for oblique direction only)
|
||||
*
|
||||
* The switch...case block below is just to construct this array.
|
||||
* We just pick the required order into array here, then call
|
||||
* {SpatialNavigator#_prioritize} to do the trick.
|
||||
*/
|
||||
var priorities;
|
||||
|
||||
switch (direction) {
|
||||
case 'left':
|
||||
priorities = [
|
||||
{
|
||||
group: internalGroups[0].concat(internalGroups[3])
|
||||
.concat(internalGroups[6]),
|
||||
distance: [
|
||||
distanceFunction.nearPlumbLineIsBetter,
|
||||
distanceFunction.topIsBetter
|
||||
]
|
||||
},
|
||||
{
|
||||
group: groups[3],
|
||||
distance: [
|
||||
distanceFunction.nearPlumbLineIsBetter,
|
||||
distanceFunction.topIsBetter
|
||||
]
|
||||
},
|
||||
{
|
||||
group: groups[0].concat(groups[6]),
|
||||
distance: [
|
||||
distanceFunction.nearHorizonIsBetter,
|
||||
distanceFunction.rightIsBetter,
|
||||
distanceFunction.nearTargetTopIsBetter
|
||||
]
|
||||
}
|
||||
];
|
||||
break;
|
||||
case 'right':
|
||||
priorities = [
|
||||
{
|
||||
group: internalGroups[2].concat(internalGroups[5])
|
||||
.concat(internalGroups[8]),
|
||||
distance: [
|
||||
distanceFunction.nearPlumbLineIsBetter,
|
||||
distanceFunction.topIsBetter
|
||||
]
|
||||
},
|
||||
{
|
||||
group: groups[5],
|
||||
distance: [
|
||||
distanceFunction.nearPlumbLineIsBetter,
|
||||
distanceFunction.topIsBetter
|
||||
]
|
||||
},
|
||||
{
|
||||
group: groups[2].concat(groups[8]),
|
||||
distance: [
|
||||
distanceFunction.nearHorizonIsBetter,
|
||||
distanceFunction.leftIsBetter,
|
||||
distanceFunction.nearTargetTopIsBetter
|
||||
]
|
||||
}
|
||||
];
|
||||
break;
|
||||
case 'up':
|
||||
priorities = [
|
||||
{
|
||||
group: internalGroups[0].concat(internalGroups[1])
|
||||
.concat(internalGroups[2]),
|
||||
distance: [
|
||||
distanceFunction.nearHorizonIsBetter,
|
||||
distanceFunction.leftIsBetter
|
||||
]
|
||||
},
|
||||
{
|
||||
group: groups[1],
|
||||
distance: [
|
||||
distanceFunction.nearHorizonIsBetter,
|
||||
distanceFunction.leftIsBetter
|
||||
]
|
||||
},
|
||||
{
|
||||
group: groups[0].concat(groups[2]),
|
||||
distance: [
|
||||
distanceFunction.nearPlumbLineIsBetter,
|
||||
distanceFunction.bottomIsBetter,
|
||||
distanceFunction.nearTargetLeftIsBetter
|
||||
]
|
||||
}
|
||||
];
|
||||
break;
|
||||
case 'down':
|
||||
priorities = [
|
||||
{
|
||||
group: internalGroups[6].concat(internalGroups[7])
|
||||
.concat(internalGroups[8]),
|
||||
distance: [
|
||||
distanceFunction.nearHorizonIsBetter,
|
||||
distanceFunction.leftIsBetter
|
||||
]
|
||||
},
|
||||
{
|
||||
group: groups[7],
|
||||
distance: [
|
||||
distanceFunction.nearHorizonIsBetter,
|
||||
distanceFunction.leftIsBetter
|
||||
]
|
||||
},
|
||||
{
|
||||
group: groups[6].concat(groups[8]),
|
||||
distance: [
|
||||
distanceFunction.nearPlumbLineIsBetter,
|
||||
distanceFunction.topIsBetter,
|
||||
distanceFunction.nearTargetLeftIsBetter
|
||||
]
|
||||
}
|
||||
];
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
if (this.straightOnly) {
|
||||
// Ignore candidates in oblique direction.
|
||||
priorities.pop();
|
||||
}
|
||||
|
||||
var dest = this._prioritize(priorities, target, direction);
|
||||
if (!dest) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return dest.element;
|
||||
}
|
||||
};
|
||||
|
||||
var Navigator = new SpatialNavigator();
|
||||
@@ -0,0 +1,625 @@
|
||||
/* Notify.js - http://notifyjs.com/ Copyright (c) 2015 MIT */
|
||||
(function (factory) {
|
||||
// UMD start
|
||||
// https://github.com/umdjs/umd/blob/master/jqueryPluginCommonjs.js
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// AMD. Register as an anonymous module.
|
||||
define(['jquery'], factory);
|
||||
} else if (typeof module === 'object' && module.exports) {
|
||||
// Node/CommonJS
|
||||
module.exports = function( root, jQuery ) {
|
||||
if ( jQuery === undefined ) {
|
||||
// require('jQuery') returns a factory that requires window to
|
||||
// build a jQuery instance, we normalize how we use modules
|
||||
// that require this pattern but the window provided is a noop
|
||||
// if it's defined (how jquery works)
|
||||
if ( typeof window !== 'undefined' ) {
|
||||
jQuery = require('jquery');
|
||||
}
|
||||
else {
|
||||
jQuery = require('jquery')(root);
|
||||
}
|
||||
}
|
||||
factory(jQuery);
|
||||
return jQuery;
|
||||
};
|
||||
} else {
|
||||
// Browser globals
|
||||
factory(jQuery);
|
||||
}
|
||||
}(function ($) {
|
||||
//IE8 indexOf polyfill
|
||||
var indexOf = [].indexOf || function(item) {
|
||||
for (var i = 0, l = this.length; i < l; i++) {
|
||||
if (i in this && this[i] === item) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
|
||||
var pluginName = "notify";
|
||||
var pluginClassName = pluginName + "js";
|
||||
var blankFieldName = pluginName + "!blank";
|
||||
|
||||
var positions = {
|
||||
t: "top",
|
||||
m: "middle",
|
||||
b: "bottom",
|
||||
l: "left",
|
||||
c: "center",
|
||||
r: "right"
|
||||
};
|
||||
var hAligns = ["l", "c", "r"];
|
||||
var vAligns = ["t", "m", "b"];
|
||||
var mainPositions = ["t", "b", "l", "r"];
|
||||
var opposites = {
|
||||
t: "b",
|
||||
m: null,
|
||||
b: "t",
|
||||
l: "r",
|
||||
c: null,
|
||||
r: "l"
|
||||
};
|
||||
|
||||
var parsePosition = function(str) {
|
||||
var pos;
|
||||
pos = [];
|
||||
$.each(str.split(/\W+/), function(i, word) {
|
||||
var w;
|
||||
w = word.toLowerCase().charAt(0);
|
||||
if (positions[w]) {
|
||||
return pos.push(w);
|
||||
}
|
||||
});
|
||||
return pos;
|
||||
};
|
||||
|
||||
var styles = {};
|
||||
|
||||
var coreStyle = {
|
||||
name: "core",
|
||||
html: "<div class=\"" + pluginClassName + "-wrapper\">\n <div class=\"" + pluginClassName + "-arrow\"></div>\n <div class=\"" + pluginClassName + "-container\"></div>\n</div>",
|
||||
css: "." + pluginClassName + "-corner {\n position: fixed;\n margin: 5px;\n z-index: 1050;\n}\n\n." + pluginClassName + "-corner ." + pluginClassName + "-wrapper,\n." + pluginClassName + "-corner ." + pluginClassName + "-container {\n position: relative;\n display: block;\n height: inherit;\n width: inherit;\n margin: 3px;\n}\n\n." + pluginClassName + "-wrapper {\n z-index: 1;\n position: absolute;\n display: inline-block;\n height: 0;\n width: 0;\n}\n\n." + pluginClassName + "-container {\n display: none;\n z-index: 1;\n position: absolute;\n}\n\n." + pluginClassName + "-hidable {\n cursor: pointer;\n}\n\n[data-notify-text],[data-notify-html] {\n position: relative;\n}\n\n." + pluginClassName + "-arrow {\n position: absolute;\n z-index: 2;\n width: 0;\n height: 0;\n}"
|
||||
};
|
||||
|
||||
var stylePrefixes = {
|
||||
"border-radius": ["-webkit-", "-moz-"]
|
||||
};
|
||||
|
||||
var getStyle = function(name) {
|
||||
return styles[name];
|
||||
};
|
||||
|
||||
var removeStyle = function(name) {
|
||||
if (!name) {
|
||||
throw "Missing Style name";
|
||||
}
|
||||
if (styles[name]) {
|
||||
delete styles[name];
|
||||
}
|
||||
};
|
||||
|
||||
var addStyle = function(name, def) {
|
||||
if (!name) {
|
||||
throw "Missing Style name";
|
||||
}
|
||||
if (!def) {
|
||||
throw "Missing Style definition";
|
||||
}
|
||||
if (!def.html) {
|
||||
throw "Missing Style HTML";
|
||||
}
|
||||
//remove existing style
|
||||
var existing = styles[name];
|
||||
if (existing && existing.cssElem) {
|
||||
if (window.console) {
|
||||
console.warn(pluginName + ": overwriting style '" + name + "'");
|
||||
}
|
||||
styles[name].cssElem.remove();
|
||||
}
|
||||
def.name = name;
|
||||
styles[name] = def;
|
||||
var cssText = "";
|
||||
if (def.classes) {
|
||||
$.each(def.classes, function(className, props) {
|
||||
cssText += "." + pluginClassName + "-" + def.name + "-" + className + " {\n";
|
||||
$.each(props, function(name, val) {
|
||||
if (stylePrefixes[name]) {
|
||||
$.each(stylePrefixes[name], function(i, prefix) {
|
||||
return cssText += " " + prefix + name + ": " + val + ";\n";
|
||||
});
|
||||
}
|
||||
return cssText += " " + name + ": " + val + ";\n";
|
||||
});
|
||||
return cssText += "}\n";
|
||||
});
|
||||
}
|
||||
if (def.css) {
|
||||
cssText += "/* styles for " + def.name + " */\n" + def.css;
|
||||
}
|
||||
if (cssText) {
|
||||
def.cssElem = insertCSS(cssText);
|
||||
def.cssElem.attr("id", "notify-" + def.name);
|
||||
}
|
||||
var fields = {};
|
||||
var elem = $(def.html);
|
||||
findFields("html", elem, fields);
|
||||
findFields("text", elem, fields);
|
||||
def.fields = fields;
|
||||
};
|
||||
|
||||
var insertCSS = function(cssText) {
|
||||
var e, elem, error;
|
||||
elem = createElem("style");
|
||||
elem.attr("type", 'text/css');
|
||||
$("head").append(elem);
|
||||
try {
|
||||
elem.html(cssText);
|
||||
} catch (_) {
|
||||
elem[0].styleSheet.cssText = cssText;
|
||||
}
|
||||
return elem;
|
||||
};
|
||||
|
||||
var findFields = function(type, elem, fields) {
|
||||
var attr;
|
||||
if (type !== "html") {
|
||||
type = "text";
|
||||
}
|
||||
attr = "data-notify-" + type;
|
||||
return find(elem, "[" + attr + "]").each(function() {
|
||||
var name;
|
||||
name = $(this).attr(attr);
|
||||
if (!name) {
|
||||
name = blankFieldName;
|
||||
}
|
||||
fields[name] = type;
|
||||
});
|
||||
};
|
||||
|
||||
var find = function(elem, selector) {
|
||||
if (elem.is(selector)) {
|
||||
return elem;
|
||||
} else {
|
||||
return elem.find(selector);
|
||||
}
|
||||
};
|
||||
|
||||
var pluginOptions = {
|
||||
clickToHide: true,
|
||||
autoHide: true,
|
||||
autoHideDelay: 5000,
|
||||
arrowShow: true,
|
||||
arrowSize: 5,
|
||||
breakNewLines: true,
|
||||
elementPosition: "bottom",
|
||||
globalPosition: "top right",
|
||||
style: "bootstrap",
|
||||
className: "error",
|
||||
showAnimation: "slideDown",
|
||||
showDuration: 400,
|
||||
hideAnimation: "slideUp",
|
||||
hideDuration: 200,
|
||||
gap: 5
|
||||
};
|
||||
|
||||
var inherit = function(a, b) {
|
||||
var F;
|
||||
F = function() {};
|
||||
F.prototype = a;
|
||||
return $.extend(true, new F(), b);
|
||||
};
|
||||
|
||||
var defaults = function(opts) {
|
||||
return $.extend(pluginOptions, opts);
|
||||
};
|
||||
|
||||
var createElem = function(tag) {
|
||||
return $("<" + tag + "></" + tag + ">");
|
||||
};
|
||||
|
||||
var globalAnchors = {};
|
||||
|
||||
var getAnchorElement = function(element) {
|
||||
var radios;
|
||||
if (element.is('[type=radio]')) {
|
||||
radios = element.parents('form:first').find('[type=radio]').filter(function(i, e) {
|
||||
return $(e).attr("name") === element.attr("name");
|
||||
});
|
||||
element = radios.first();
|
||||
}
|
||||
return element;
|
||||
};
|
||||
|
||||
var incr = function(obj, pos, val) {
|
||||
var opp, temp;
|
||||
if (typeof val === "string") {
|
||||
val = parseInt(val, 10);
|
||||
} else if (typeof val !== "number") {
|
||||
return;
|
||||
}
|
||||
if (isNaN(val)) {
|
||||
return;
|
||||
}
|
||||
opp = positions[opposites[pos.charAt(0)]];
|
||||
temp = pos;
|
||||
if (obj[opp] !== undefined) {
|
||||
pos = positions[opp.charAt(0)];
|
||||
val = -val;
|
||||
}
|
||||
if (obj[pos] === undefined) {
|
||||
obj[pos] = val;
|
||||
} else {
|
||||
obj[pos] += val;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
var realign = function(alignment, inner, outer) {
|
||||
if (alignment === "l" || alignment === "t") {
|
||||
return 0;
|
||||
} else if (alignment === "c" || alignment === "m") {
|
||||
return outer / 2 - inner / 2;
|
||||
} else if (alignment === "r" || alignment === "b") {
|
||||
return outer - inner;
|
||||
}
|
||||
throw "Invalid alignment";
|
||||
};
|
||||
|
||||
var encode = function(text) {
|
||||
encode.e = encode.e || createElem("div");
|
||||
return encode.e.text(text).html();
|
||||
};
|
||||
|
||||
function Notification(elem, data, options) {
|
||||
if (typeof options === "string") {
|
||||
options = {
|
||||
className: options
|
||||
};
|
||||
}
|
||||
this.options = inherit(pluginOptions, $.isPlainObject(options) ? options : {});
|
||||
this.loadHTML();
|
||||
this.wrapper = $(coreStyle.html);
|
||||
if (this.options.clickToHide) {
|
||||
this.wrapper.addClass(pluginClassName + "-hidable");
|
||||
}
|
||||
this.wrapper.data(pluginClassName, this);
|
||||
this.arrow = this.wrapper.find("." + pluginClassName + "-arrow");
|
||||
this.container = this.wrapper.find("." + pluginClassName + "-container");
|
||||
this.container.append(this.userContainer);
|
||||
if (elem && elem.length) {
|
||||
this.elementType = elem.attr("type");
|
||||
this.originalElement = elem;
|
||||
this.elem = getAnchorElement(elem);
|
||||
this.elem.data(pluginClassName, this);
|
||||
this.elem.before(this.wrapper);
|
||||
}
|
||||
this.container.hide();
|
||||
this.run(data);
|
||||
}
|
||||
|
||||
Notification.prototype.loadHTML = function() {
|
||||
var style;
|
||||
style = this.getStyle();
|
||||
this.userContainer = $(style.html);
|
||||
this.userFields = style.fields;
|
||||
};
|
||||
|
||||
Notification.prototype.show = function(show, userCallback) {
|
||||
var args, callback, elems, fn, hidden;
|
||||
callback = (function(_this) {
|
||||
return function() {
|
||||
if (!show && !_this.elem) {
|
||||
_this.destroy();
|
||||
}
|
||||
if (userCallback) {
|
||||
return userCallback();
|
||||
}
|
||||
};
|
||||
})(this);
|
||||
hidden = this.container.parent().parents(':hidden').length > 0;
|
||||
elems = this.container.add(this.arrow);
|
||||
args = [];
|
||||
if (hidden && show) {
|
||||
fn = "show";
|
||||
} else if (hidden && !show) {
|
||||
fn = "hide";
|
||||
} else if (!hidden && show) {
|
||||
fn = this.options.showAnimation;
|
||||
args.push(this.options.showDuration);
|
||||
} else if (!hidden && !show) {
|
||||
fn = this.options.hideAnimation;
|
||||
args.push(this.options.hideDuration);
|
||||
} else {
|
||||
return callback();
|
||||
}
|
||||
args.push(callback);
|
||||
return elems[fn].apply(elems, args);
|
||||
};
|
||||
|
||||
Notification.prototype.setGlobalPosition = function() {
|
||||
var p = this.getPosition();
|
||||
var pMain = p[0];
|
||||
var pAlign = p[1];
|
||||
var main = positions[pMain];
|
||||
var align = positions[pAlign];
|
||||
var key = pMain + "|" + pAlign;
|
||||
var anchor = globalAnchors[key];
|
||||
if (!anchor || !document.body.contains(anchor[0])) {
|
||||
anchor = globalAnchors[key] = createElem("div");
|
||||
var css = {};
|
||||
css[main] = 0;
|
||||
if (align === "middle") {
|
||||
css.top = '45%';
|
||||
} else if (align === "center") {
|
||||
css.left = '45%';
|
||||
} else {
|
||||
css[align] = 0;
|
||||
}
|
||||
anchor.css(css).addClass(pluginClassName + "-corner");
|
||||
$("body").append(anchor);
|
||||
}
|
||||
return anchor.prepend(this.wrapper);
|
||||
};
|
||||
|
||||
Notification.prototype.setElementPosition = function() {
|
||||
var arrowColor, arrowCss, arrowSize, color, contH, contW, css, elemH, elemIH, elemIW, elemPos, elemW, gap, j, k, len, len1, mainFull, margin, opp, oppFull, pAlign, pArrow, pMain, pos, posFull, position, ref, wrapPos;
|
||||
position = this.getPosition();
|
||||
pMain = position[0];
|
||||
pAlign = position[1];
|
||||
pArrow = position[2];
|
||||
elemPos = this.elem.position();
|
||||
elemH = this.elem.outerHeight();
|
||||
elemW = this.elem.outerWidth();
|
||||
elemIH = this.elem.innerHeight();
|
||||
elemIW = this.elem.innerWidth();
|
||||
wrapPos = this.wrapper.position();
|
||||
contH = this.container.height();
|
||||
contW = this.container.width();
|
||||
mainFull = positions[pMain];
|
||||
opp = opposites[pMain];
|
||||
oppFull = positions[opp];
|
||||
css = {};
|
||||
css[oppFull] = pMain === "b" ? elemH : pMain === "r" ? elemW : 0;
|
||||
incr(css, "top", elemPos.top - wrapPos.top);
|
||||
incr(css, "left", elemPos.left - wrapPos.left);
|
||||
ref = ["top", "left"];
|
||||
for (j = 0, len = ref.length; j < len; j++) {
|
||||
pos = ref[j];
|
||||
margin = parseInt(this.elem.css("margin-" + pos), 10);
|
||||
if (margin) {
|
||||
incr(css, pos, margin);
|
||||
}
|
||||
}
|
||||
gap = Math.max(0, this.options.gap - (this.options.arrowShow ? arrowSize : 0));
|
||||
incr(css, oppFull, gap);
|
||||
if (!this.options.arrowShow) {
|
||||
this.arrow.hide();
|
||||
} else {
|
||||
arrowSize = this.options.arrowSize;
|
||||
arrowCss = $.extend({}, css);
|
||||
arrowColor = this.userContainer.css("border-color") || this.userContainer.css("border-top-color") || this.userContainer.css("background-color") || "white";
|
||||
for (k = 0, len1 = mainPositions.length; k < len1; k++) {
|
||||
pos = mainPositions[k];
|
||||
posFull = positions[pos];
|
||||
if (pos === opp) {
|
||||
continue;
|
||||
}
|
||||
color = posFull === mainFull ? arrowColor : "transparent";
|
||||
arrowCss["border-" + posFull] = arrowSize + "px solid " + color;
|
||||
}
|
||||
incr(css, positions[opp], arrowSize);
|
||||
if (indexOf.call(mainPositions, pAlign) >= 0) {
|
||||
incr(arrowCss, positions[pAlign], arrowSize * 2);
|
||||
}
|
||||
}
|
||||
if (indexOf.call(vAligns, pMain) >= 0) {
|
||||
incr(css, "left", realign(pAlign, contW, elemW));
|
||||
if (arrowCss) {
|
||||
incr(arrowCss, "left", realign(pAlign, arrowSize, elemIW));
|
||||
}
|
||||
} else if (indexOf.call(hAligns, pMain) >= 0) {
|
||||
incr(css, "top", realign(pAlign, contH, elemH));
|
||||
if (arrowCss) {
|
||||
incr(arrowCss, "top", realign(pAlign, arrowSize, elemIH));
|
||||
}
|
||||
}
|
||||
if (this.container.is(":visible")) {
|
||||
css.display = "block";
|
||||
}
|
||||
this.container.removeAttr("style").css(css);
|
||||
if (arrowCss) {
|
||||
return this.arrow.removeAttr("style").css(arrowCss);
|
||||
}
|
||||
};
|
||||
|
||||
Notification.prototype.getPosition = function() {
|
||||
var pos, ref, ref1, ref2, ref3, ref4, ref5, text;
|
||||
text = this.options.position || (this.elem ? this.options.elementPosition : this.options.globalPosition);
|
||||
pos = parsePosition(text);
|
||||
if (pos.length === 0) {
|
||||
pos[0] = "b";
|
||||
}
|
||||
if (ref = pos[0], indexOf.call(mainPositions, ref) < 0) {
|
||||
throw "Must be one of [" + mainPositions + "]";
|
||||
}
|
||||
if (pos.length === 1 || ((ref1 = pos[0], indexOf.call(vAligns, ref1) >= 0) && (ref2 = pos[1], indexOf.call(hAligns, ref2) < 0)) || ((ref3 = pos[0], indexOf.call(hAligns, ref3) >= 0) && (ref4 = pos[1], indexOf.call(vAligns, ref4) < 0))) {
|
||||
pos[1] = (ref5 = pos[0], indexOf.call(hAligns, ref5) >= 0) ? "m" : "l";
|
||||
}
|
||||
if (pos.length === 2) {
|
||||
pos[2] = pos[1];
|
||||
}
|
||||
return pos;
|
||||
};
|
||||
|
||||
Notification.prototype.getStyle = function(name) {
|
||||
var style;
|
||||
if (!name) {
|
||||
name = this.options.style;
|
||||
}
|
||||
if (!name) {
|
||||
name = "default";
|
||||
}
|
||||
style = styles[name];
|
||||
if (!style) {
|
||||
throw "Missing style: " + name;
|
||||
}
|
||||
return style;
|
||||
};
|
||||
|
||||
Notification.prototype.updateClasses = function() {
|
||||
var classes, style;
|
||||
classes = ["base"];
|
||||
if ($.isArray(this.options.className)) {
|
||||
classes = classes.concat(this.options.className);
|
||||
} else if (this.options.className) {
|
||||
classes.push(this.options.className);
|
||||
}
|
||||
style = this.getStyle();
|
||||
classes = $.map(classes, function(n) {
|
||||
return pluginClassName + "-" + style.name + "-" + n;
|
||||
}).join(" ");
|
||||
return this.userContainer.attr("class", classes);
|
||||
};
|
||||
|
||||
Notification.prototype.run = function(data, options) {
|
||||
var d, datas, name, type, value;
|
||||
if ($.isPlainObject(options)) {
|
||||
$.extend(this.options, options);
|
||||
} else if ($.type(options) === "string") {
|
||||
this.options.className = options;
|
||||
}
|
||||
if (this.container && !data) {
|
||||
this.show(false);
|
||||
return;
|
||||
} else if (!this.container && !data) {
|
||||
return;
|
||||
}
|
||||
datas = {};
|
||||
if ($.isPlainObject(data)) {
|
||||
datas = data;
|
||||
} else {
|
||||
datas[blankFieldName] = data;
|
||||
}
|
||||
for (name in datas) {
|
||||
d = datas[name];
|
||||
type = this.userFields[name];
|
||||
if (!type) {
|
||||
continue;
|
||||
}
|
||||
if (type === "text") {
|
||||
d = encode(d);
|
||||
if (this.options.breakNewLines) {
|
||||
d = d.replace(/\n/g, '<br/>');
|
||||
}
|
||||
}
|
||||
value = name === blankFieldName ? '' : '=' + name;
|
||||
find(this.userContainer, "[data-notify-" + type + value + "]").html(d);
|
||||
}
|
||||
this.updateClasses();
|
||||
if (this.elem) {
|
||||
this.setElementPosition();
|
||||
} else {
|
||||
this.setGlobalPosition();
|
||||
}
|
||||
this.show(true);
|
||||
if (this.options.autoHide) {
|
||||
clearTimeout(this.autohideTimer);
|
||||
this.autohideTimer = setTimeout(this.show.bind(this, false), this.options.autoHideDelay);
|
||||
}
|
||||
};
|
||||
|
||||
Notification.prototype.destroy = function() {
|
||||
this.wrapper.data(pluginClassName, null);
|
||||
this.wrapper.remove();
|
||||
};
|
||||
|
||||
$[pluginName] = function(elem, data, options) {
|
||||
if ((elem && elem.nodeName) || elem.jquery) {
|
||||
$(elem)[pluginName](data, options);
|
||||
} else {
|
||||
options = data;
|
||||
data = elem;
|
||||
new Notification(null, data, options);
|
||||
}
|
||||
return elem;
|
||||
};
|
||||
|
||||
$.fn[pluginName] = function(data, options) {
|
||||
$(this).each(function() {
|
||||
var prev = getAnchorElement($(this)).data(pluginClassName);
|
||||
if (prev) {
|
||||
prev.destroy();
|
||||
}
|
||||
var curr = new Notification($(this), data, options);
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
$.extend($[pluginName], {
|
||||
defaults: defaults,
|
||||
addStyle: addStyle,
|
||||
removeStyle: removeStyle,
|
||||
pluginOptions: pluginOptions,
|
||||
getStyle: getStyle,
|
||||
insertCSS: insertCSS
|
||||
});
|
||||
|
||||
//always include the default bootstrap style
|
||||
addStyle("bootstrap", {
|
||||
html: "<div>\n<span data-notify-text></span>\n</div>",
|
||||
classes: {
|
||||
base: {
|
||||
"font-weight": "bold",
|
||||
"padding": "8px 15px 8px 14px",
|
||||
"text-shadow": "0 1px 0 rgba(255, 255, 255, 0.5)",
|
||||
"background-color": "#fcf8e3",
|
||||
"border": "1px solid #fbeed5",
|
||||
"border-radius": "4px",
|
||||
"white-space": "nowrap",
|
||||
"padding-left": "25px",
|
||||
"background-repeat": "no-repeat",
|
||||
"background-position": "3px 7px"
|
||||
},
|
||||
error: {
|
||||
"color": "#B94A48",
|
||||
"background-color": "#F2DEDE",
|
||||
"border-color": "#EED3D7",
|
||||
"background-image": "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAtRJREFUeNqkVc1u00AQHq+dOD+0poIQfkIjalW0SEGqRMuRnHos3DjwAH0ArlyQeANOOSMeAA5VjyBxKBQhgSpVUKKQNGloFdw4cWw2jtfMOna6JOUArDTazXi/b3dm55socPqQhFka++aHBsI8GsopRJERNFlY88FCEk9Yiwf8RhgRyaHFQpPHCDmZG5oX2ui2yilkcTT1AcDsbYC1NMAyOi7zTX2Agx7A9luAl88BauiiQ/cJaZQfIpAlngDcvZZMrl8vFPK5+XktrWlx3/ehZ5r9+t6e+WVnp1pxnNIjgBe4/6dAysQc8dsmHwPcW9C0h3fW1hans1ltwJhy0GxK7XZbUlMp5Ww2eyan6+ft/f2FAqXGK4CvQk5HueFz7D6GOZtIrK+srupdx1GRBBqNBtzc2AiMr7nPplRdKhb1q6q6zjFhrklEFOUutoQ50xcX86ZlqaZpQrfbBdu2R6/G19zX6XSgh6RX5ubyHCM8nqSID6ICrGiZjGYYxojEsiw4PDwMSL5VKsC8Yf4VRYFzMzMaxwjlJSlCyAQ9l0CW44PBADzXhe7xMdi9HtTrdYjFYkDQL0cn4Xdq2/EAE+InCnvADTf2eah4Sx9vExQjkqXT6aAERICMewd/UAp/IeYANM2joxt+q5VI+ieq2i0Wg3l6DNzHwTERPgo1ko7XBXj3vdlsT2F+UuhIhYkp7u7CarkcrFOCtR3H5JiwbAIeImjT/YQKKBtGjRFCU5IUgFRe7fF4cCNVIPMYo3VKqxwjyNAXNepuopyqnld602qVsfRpEkkz+GFL1wPj6ySXBpJtWVa5xlhpcyhBNwpZHmtX8AGgfIExo0ZpzkWVTBGiXCSEaHh62/PoR0p/vHaczxXGnj4bSo+G78lELU80h1uogBwWLf5YlsPmgDEd4M236xjm+8nm4IuE/9u+/PH2JXZfbwz4zw1WbO+SQPpXfwG/BBgAhCNZiSb/pOQAAAAASUVORK5CYII=)"
|
||||
},
|
||||
success: {
|
||||
"color": "#468847",
|
||||
"background-color": "#DFF0D8",
|
||||
"border-color": "#D6E9C6",
|
||||
"background-image": "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAutJREFUeNq0lctPE0Ecx38zu/RFS1EryqtgJFA08YCiMZIAQQ4eRG8eDGdPJiYeTIwHTfwPiAcvXIwXLwoXPaDxkWgQ6islKlJLSQWLUraPLTv7Gme32zoF9KSTfLO7v53vZ3d/M7/fIth+IO6INt2jjoA7bjHCJoAlzCRw59YwHYjBnfMPqAKWQYKjGkfCJqAF0xwZjipQtA3MxeSG87VhOOYegVrUCy7UZM9S6TLIdAamySTclZdYhFhRHloGYg7mgZv1Zzztvgud7V1tbQ2twYA34LJmF4p5dXF1KTufnE+SxeJtuCZNsLDCQU0+RyKTF27Unw101l8e6hns3u0PBalORVVVkcaEKBJDgV3+cGM4tKKmI+ohlIGnygKX00rSBfszz/n2uXv81wd6+rt1orsZCHRdr1Imk2F2Kob3hutSxW8thsd8AXNaln9D7CTfA6O+0UgkMuwVvEFFUbbAcrkcTA8+AtOk8E6KiQiDmMFSDqZItAzEVQviRkdDdaFgPp8HSZKAEAL5Qh7Sq2lIJBJwv2scUqkUnKoZgNhcDKhKg5aH+1IkcouCAdFGAQsuWZYhOjwFHQ96oagWgRoUov1T9kRBEODAwxM2QtEUl+Wp+Ln9VRo6BcMw4ErHRYjH4/B26AlQoQQTRdHWwcd9AH57+UAXddvDD37DmrBBV34WfqiXPl61g+vr6xA9zsGeM9gOdsNXkgpEtTwVvwOklXLKm6+/p5ezwk4B+j6droBs2CsGa/gNs6RIxazl4Tc25mpTgw/apPR1LYlNRFAzgsOxkyXYLIM1V8NMwyAkJSctD1eGVKiq5wWjSPdjmeTkiKvVW4f2YPHWl3GAVq6ymcyCTgovM3FzyRiDe2TaKcEKsLpJvNHjZgPNqEtyi6mZIm4SRFyLMUsONSSdkPeFtY1n0mczoY3BHTLhwPRy9/lzcziCw9ACI+yql0VLzcGAZbYSM5CCSZg1/9oc/nn7+i8N9p/8An4JMADxhH+xHfuiKwAAAABJRU5ErkJggg==)"
|
||||
},
|
||||
info: {
|
||||
"color": "#3A87AD",
|
||||
"background-color": "#D9EDF7",
|
||||
"border-color": "#BCE8F1",
|
||||
"background-image": "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QYFAhkSsdes/QAAA8dJREFUOMvVlGtMW2UYx//POaWHXg6lLaW0ypAtw1UCgbniNOLcVOLmAjHZolOYlxmTGXVZdAnRfXQm+7SoU4mXaOaiZsEpC9FkiQs6Z6bdCnNYruM6KNBw6YWewzl9z+sHImEWv+vz7XmT95f/+3/+7wP814v+efDOV3/SoX3lHAA+6ODeUFfMfjOWMADgdk+eEKz0pF7aQdMAcOKLLjrcVMVX3xdWN29/GhYP7SvnP0cWfS8caSkfHZsPE9Fgnt02JNutQ0QYHB2dDz9/pKX8QjjuO9xUxd/66HdxTeCHZ3rojQObGQBcuNjfplkD3b19Y/6MrimSaKgSMmpGU5WevmE/swa6Oy73tQHA0Rdr2Mmv/6A1n9w9suQ7097Z9lM4FlTgTDrzZTu4StXVfpiI48rVcUDM5cmEksrFnHxfpTtU/3BFQzCQF/2bYVoNbH7zmItbSoMj40JSzmMyX5qDvriA7QdrIIpA+3cdsMpu0nXI8cV0MtKXCPZev+gCEM1S2NHPvWfP/hL+7FSr3+0p5RBEyhEN5JCKYr8XnASMT0xBNyzQGQeI8fjsGD39RMPk7se2bd5ZtTyoFYXftF6y37gx7NeUtJJOTFlAHDZLDuILU3j3+H5oOrD3yWbIztugaAzgnBKJuBLpGfQrS8wO4FZgV+c1IxaLgWVU0tMLEETCos4xMzEIv9cJXQcyagIwigDGwJgOAtHAwAhisQUjy0ORGERiELgG4iakkzo4MYAxcM5hAMi1WWG1yYCJIcMUaBkVRLdGeSU2995TLWzcUAzONJ7J6FBVBYIggMzmFbvdBV44Corg8vjhzC+EJEl8U1kJtgYrhCzgc/vvTwXKSib1paRFVRVORDAJAsw5FuTaJEhWM2SHB3mOAlhkNxwuLzeJsGwqWzf5TFNdKgtY5qHp6ZFf67Y/sAVadCaVY5YACDDb3Oi4NIjLnWMw2QthCBIsVhsUTU9tvXsjeq9+X1d75/KEs4LNOfcdf/+HthMnvwxOD0wmHaXr7ZItn2wuH2SnBzbZAbPJwpPx+VQuzcm7dgRCB57a1uBzUDRL4bfnI0RE0eaXd9W89mpjqHZnUI5Hh2l2dkZZUhOqpi2qSmpOmZ64Tuu9qlz/SEXo6MEHa3wOip46F1n7633eekV8ds8Wxjn37Wl63VVa+ej5oeEZ/82ZBETJjpJ1Rbij2D3Z/1trXUvLsblCK0XfOx0SX2kMsn9dX+d+7Kf6h8o4AIykuffjT8L20LU+w4AZd5VvEPY+XpWqLV327HR7DzXuDnD8r+ovkBehJ8i+y8YAAAAASUVORK5CYII=)"
|
||||
},
|
||||
warn: {
|
||||
"color": "#C09853",
|
||||
"background-color": "#FCF8E3",
|
||||
"border-color": "#FBEED5",
|
||||
"background-image": "url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAMAAAC6V+0/AAABJlBMVEXr6eb/2oD/wi7/xjr/0mP/ykf/tQD/vBj/3o7/uQ//vyL/twebhgD/4pzX1K3z8e349vK6tHCilCWbiQymn0jGworr6dXQza3HxcKkn1vWvV/5uRfk4dXZ1bD18+/52YebiAmyr5S9mhCzrWq5t6ufjRH54aLs0oS+qD751XqPhAybhwXsujG3sm+Zk0PTwG6Shg+PhhObhwOPgQL4zV2nlyrf27uLfgCPhRHu7OmLgAafkyiWkD3l49ibiAfTs0C+lgCniwD4sgDJxqOilzDWowWFfAH08uebig6qpFHBvH/aw26FfQTQzsvy8OyEfz20r3jAvaKbhgG9q0nc2LbZxXanoUu/u5WSggCtp1anpJKdmFz/zlX/1nGJiYmuq5Dx7+sAAADoPUZSAAAAAXRSTlMAQObYZgAAAAFiS0dEAIgFHUgAAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfdBgUBGhh4aah5AAAAlklEQVQY02NgoBIIE8EUcwn1FkIXM1Tj5dDUQhPU502Mi7XXQxGz5uVIjGOJUUUW81HnYEyMi2HVcUOICQZzMMYmxrEyMylJwgUt5BljWRLjmJm4pI1hYp5SQLGYxDgmLnZOVxuooClIDKgXKMbN5ggV1ACLJcaBxNgcoiGCBiZwdWxOETBDrTyEFey0jYJ4eHjMGWgEAIpRFRCUt08qAAAAAElFTkSuQmCC)"
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
$(function() {
|
||||
insertCSS(coreStyle.css).attr("id", "core-notify");
|
||||
$(document).on("click", "." + pluginClassName + "-hidable", function(e) {
|
||||
$(this).trigger("notify-hide");
|
||||
});
|
||||
$(document).on("notify-hide", "." + pluginClassName + "-wrapper", function(e) {
|
||||
var elem = $(this).data(pluginClassName);
|
||||
if(elem) {
|
||||
elem.show(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
}));
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,791 @@
|
||||
/*************** SCROLLBAR BASE CSS ***************/
|
||||
|
||||
.scroll-wrapper {
|
||||
overflow: hidden !important;
|
||||
padding: 0 !important;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.scroll-wrapper > .scroll-content {
|
||||
border: none !important;
|
||||
box-sizing: content-box !important;
|
||||
height: auto;
|
||||
left: 0;
|
||||
margin: 0;
|
||||
max-height: none;
|
||||
max-width: none !important;
|
||||
overflow: scroll !important;
|
||||
padding: 0;
|
||||
position: relative !important;
|
||||
top: 0;
|
||||
width: auto !important;
|
||||
}
|
||||
|
||||
.scroll-wrapper > .scroll-content::-webkit-scrollbar {
|
||||
height: 0;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
.scroll-element {
|
||||
display: none;
|
||||
}
|
||||
.scroll-element, .scroll-element div {
|
||||
box-sizing: content-box;
|
||||
}
|
||||
|
||||
.scroll-element.scroll-x.scroll-scrollx_visible,
|
||||
.scroll-element.scroll-y.scroll-scrolly_visible {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.scroll-element .scroll-bar,
|
||||
.scroll-element .scroll-arrow {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.scroll-textarea {
|
||||
border: 1px solid #cccccc;
|
||||
border-top-color: #999999;
|
||||
}
|
||||
.scroll-textarea > .scroll-content {
|
||||
overflow: hidden !important;
|
||||
}
|
||||
.scroll-textarea > .scroll-content > textarea {
|
||||
border: none !important;
|
||||
box-sizing: border-box;
|
||||
height: 100% !important;
|
||||
margin: 0;
|
||||
max-height: none !important;
|
||||
max-width: none !important;
|
||||
overflow: scroll !important;
|
||||
outline: none;
|
||||
padding: 2px;
|
||||
position: relative !important;
|
||||
top: 0;
|
||||
width: 100% !important;
|
||||
}
|
||||
.scroll-textarea > .scroll-content > textarea::-webkit-scrollbar {
|
||||
height: 0;
|
||||
width: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*************** SIMPLE INNER SCROLLBAR ***************/
|
||||
|
||||
.scrollbar-inner > .scroll-element,
|
||||
.scrollbar-inner > .scroll-element div
|
||||
{
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.scrollbar-inner > .scroll-element div {
|
||||
display: block;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-inner > .scroll-element.scroll-x {
|
||||
bottom: 2px;
|
||||
height: 8px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-inner > .scroll-element.scroll-y {
|
||||
height: 100%;
|
||||
right: 2px;
|
||||
top: 0;
|
||||
width: 8px;
|
||||
}
|
||||
|
||||
.scrollbar-inner > .scroll-element .scroll-element_outer {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.scrollbar-inner > .scroll-element .scroll-element_outer,
|
||||
.scrollbar-inner > .scroll-element .scroll-element_track,
|
||||
.scrollbar-inner > .scroll-element .scroll-bar {
|
||||
-webkit-border-radius: 8px;
|
||||
-moz-border-radius: 8px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.scrollbar-inner > .scroll-element .scroll-element_track,
|
||||
.scrollbar-inner > .scroll-element .scroll-bar {
|
||||
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=40)";
|
||||
filter: alpha(opacity=40);
|
||||
opacity: 0.4;
|
||||
}
|
||||
|
||||
.scrollbar-inner > .scroll-element .scroll-element_track { background-color: #e0e0e0; }
|
||||
.scrollbar-inner > .scroll-element .scroll-bar { background-color: #c2c2c2; }
|
||||
.scrollbar-inner > .scroll-element:hover .scroll-bar { background-color: #919191; }
|
||||
.scrollbar-inner > .scroll-element.scroll-draggable .scroll-bar { background-color: #919191; }
|
||||
|
||||
|
||||
/* update scrollbar offset if both scrolls are visible */
|
||||
|
||||
.scrollbar-inner > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_track { left: -12px; }
|
||||
.scrollbar-inner > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_track { top: -12px; }
|
||||
|
||||
|
||||
.scrollbar-inner > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size { left: -12px; }
|
||||
.scrollbar-inner > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size { top: -12px; }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*************** SIMPLE OUTER SCROLLBAR ***************/
|
||||
|
||||
.scrollbar-outer > .scroll-element,
|
||||
.scrollbar-outer > .scroll-element div
|
||||
{
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.scrollbar-outer > .scroll-element {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.scrollbar-outer > .scroll-element div {
|
||||
display: block;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-outer > .scroll-element.scroll-x {
|
||||
bottom: 0;
|
||||
height: 12px;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-outer > .scroll-element.scroll-y {
|
||||
height: 100%;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 12px;
|
||||
}
|
||||
|
||||
.scrollbar-outer > .scroll-element.scroll-x .scroll-element_outer { height: 8px; top: 2px; }
|
||||
.scrollbar-outer > .scroll-element.scroll-y .scroll-element_outer { left: 2px; width: 8px; }
|
||||
|
||||
.scrollbar-outer > .scroll-element .scroll-element_outer { overflow: hidden; }
|
||||
.scrollbar-outer > .scroll-element .scroll-element_track { background-color: #eeeeee; }
|
||||
|
||||
.scrollbar-outer > .scroll-element .scroll-element_outer,
|
||||
.scrollbar-outer > .scroll-element .scroll-element_track,
|
||||
.scrollbar-outer > .scroll-element .scroll-bar {
|
||||
-webkit-border-radius: 8px;
|
||||
-moz-border-radius: 8px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
.scrollbar-outer > .scroll-element .scroll-bar { background-color: #d9d9d9; }
|
||||
.scrollbar-outer > .scroll-element .scroll-bar:hover { background-color: #c2c2c2; }
|
||||
.scrollbar-outer > .scroll-element.scroll-draggable .scroll-bar { background-color: #919191; }
|
||||
|
||||
|
||||
/* scrollbar height/width & offset from container borders */
|
||||
|
||||
.scrollbar-outer > .scroll-content.scroll-scrolly_visible { left: -12px; margin-left: 12px; }
|
||||
.scrollbar-outer > .scroll-content.scroll-scrollx_visible { top: -12px; margin-top: 12px; }
|
||||
|
||||
.scrollbar-outer > .scroll-element.scroll-x .scroll-bar { min-width: 10px; }
|
||||
.scrollbar-outer > .scroll-element.scroll-y .scroll-bar { min-height: 10px; }
|
||||
|
||||
|
||||
/* update scrollbar offset if both scrolls are visible */
|
||||
|
||||
.scrollbar-outer > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_track { left: -14px; }
|
||||
.scrollbar-outer > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_track { top: -14px; }
|
||||
|
||||
.scrollbar-outer > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size { left: -14px; }
|
||||
.scrollbar-outer > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size { top: -14px; }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*************** SCROLLBAR MAC OS X ***************/
|
||||
|
||||
.scrollbar-macosx > .scroll-element,
|
||||
.scrollbar-macosx > .scroll-element div
|
||||
{
|
||||
background: none;
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.scrollbar-macosx > .scroll-element div {
|
||||
display: block;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-macosx > .scroll-element .scroll-element_track { display: none; }
|
||||
.scrollbar-macosx > .scroll-element .scroll-bar {
|
||||
background-color: #6C6E71;
|
||||
display: block;
|
||||
|
||||
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";
|
||||
filter: alpha(opacity=0);
|
||||
opacity: 0;
|
||||
|
||||
-webkit-border-radius: 7px;
|
||||
-moz-border-radius: 7px;
|
||||
border-radius: 7px;
|
||||
|
||||
-webkit-transition: opacity 0.2s linear;
|
||||
-moz-transition: opacity 0.2s linear;
|
||||
-o-transition: opacity 0.2s linear;
|
||||
-ms-transition: opacity 0.2s linear;
|
||||
transition: opacity 0.2s linear;
|
||||
}
|
||||
.scrollbar-macosx:hover > .scroll-element .scroll-bar,
|
||||
.scrollbar-macosx > .scroll-element.scroll-draggable .scroll-bar {
|
||||
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)";
|
||||
filter: alpha(opacity=70);
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
|
||||
.scrollbar-macosx > .scroll-element.scroll-x {
|
||||
bottom: 0px;
|
||||
height: 0px;
|
||||
left: 0;
|
||||
min-width: 100%;
|
||||
overflow: visible;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-macosx > .scroll-element.scroll-y {
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
right: 0px;
|
||||
top: 0;
|
||||
width: 0px;
|
||||
}
|
||||
|
||||
/* scrollbar height/width & offset from container borders */
|
||||
.scrollbar-macosx > .scroll-element.scroll-x .scroll-bar { height: 7px; min-width: 10px; top: -9px; }
|
||||
.scrollbar-macosx > .scroll-element.scroll-y .scroll-bar { left: -9px; min-height: 10px; width: 7px; }
|
||||
|
||||
.scrollbar-macosx > .scroll-element.scroll-x .scroll-element_outer { left: 2px; }
|
||||
.scrollbar-macosx > .scroll-element.scroll-x .scroll-element_size { left: -4px; }
|
||||
|
||||
.scrollbar-macosx > .scroll-element.scroll-y .scroll-element_outer { top: 2px; }
|
||||
.scrollbar-macosx > .scroll-element.scroll-y .scroll-element_size { top: -4px; }
|
||||
|
||||
/* update scrollbar offset if both scrolls are visible */
|
||||
.scrollbar-macosx > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size { left: -11px; }
|
||||
.scrollbar-macosx > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size { top: -11px; }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*************** SCROLLBAR LIGHT ***************/
|
||||
|
||||
.scrollbar-light > .scroll-element,
|
||||
.scrollbar-light > .scroll-element div {
|
||||
border: none;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.scrollbar-light > .scroll-element {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.scrollbar-light > .scroll-element div {
|
||||
display: block;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-light > .scroll-element .scroll-element_outer {
|
||||
-webkit-border-radius: 10px;
|
||||
-moz-border-radius: 10px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.scrollbar-light > .scroll-element .scroll-element_size {
|
||||
background: #dbdbdb;
|
||||
background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2RiZGJkYiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNlOGU4ZTgiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+');
|
||||
background: -moz-linear-gradient(left, #dbdbdb 0%, #e8e8e8 100%);
|
||||
background: -webkit-gradient(linear, left top, right top, color-stop(0%,#dbdbdb), color-stop(100%,#e8e8e8));
|
||||
background: -webkit-linear-gradient(left, #dbdbdb 0%,#e8e8e8 100%);
|
||||
background: -o-linear-gradient(left, #dbdbdb 0%,#e8e8e8 100%);
|
||||
background: -ms-linear-gradient(left, #dbdbdb 0%,#e8e8e8 100%);
|
||||
background: linear-gradient(to right, #dbdbdb 0%,#e8e8e8 100%);
|
||||
|
||||
-webkit-border-radius: 10px;
|
||||
-moz-border-radius: 10px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
.scrollbar-light > .scroll-element.scroll-x {
|
||||
bottom: 0;
|
||||
height: 17px;
|
||||
left: 0;
|
||||
min-width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-light > .scroll-element.scroll-y {
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 17px;
|
||||
}
|
||||
|
||||
.scrollbar-light > .scroll-element .scroll-bar {
|
||||
background: #fefefe;
|
||||
background: url('data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIxMDAlIiB5Mj0iMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2ZlZmVmZSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmNWY1ZjUiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+');
|
||||
background: -moz-linear-gradient(left, #fefefe 0%, #f5f5f5 100%);
|
||||
background: -webkit-gradient(linear, left top, right top, color-stop(0%,#fefefe), color-stop(100%,#f5f5f5));
|
||||
background: -webkit-linear-gradient(left, #fefefe 0%,#f5f5f5 100%);
|
||||
background: -o-linear-gradient(left, #fefefe 0%,#f5f5f5 100%);
|
||||
background: -ms-linear-gradient(left, #fefefe 0%,#f5f5f5 100%);
|
||||
background: linear-gradient(to right, #fefefe 0%,#f5f5f5 100%);
|
||||
|
||||
border: 1px solid #dbdbdb;
|
||||
-webkit-border-radius: 10px;
|
||||
-moz-border-radius: 10px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
|
||||
/* scrollbar height/width & offset from container borders */
|
||||
|
||||
.scrollbar-light > .scroll-content.scroll-scrolly_visible { left: -17px; margin-left: 17px; }
|
||||
.scrollbar-light > .scroll-content.scroll-scrollx_visible { top: -17px; margin-top: 17px; }
|
||||
|
||||
.scrollbar-light > .scroll-element.scroll-x .scroll-bar { height: 10px; min-width: 10px; top: 0px; }
|
||||
.scrollbar-light > .scroll-element.scroll-y .scroll-bar { left: 0px; min-height: 10px; width: 10px; }
|
||||
|
||||
.scrollbar-light > .scroll-element.scroll-x .scroll-element_outer { height: 12px; left: 2px; top: 2px; }
|
||||
.scrollbar-light > .scroll-element.scroll-x .scroll-element_size { left: -4px; }
|
||||
|
||||
.scrollbar-light > .scroll-element.scroll-y .scroll-element_outer { left: 2px; top: 2px; width: 12px; }
|
||||
.scrollbar-light > .scroll-element.scroll-y .scroll-element_size { top: -4px; }
|
||||
|
||||
/* update scrollbar offset if both scrolls are visible */
|
||||
|
||||
.scrollbar-light > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size { left: -19px; }
|
||||
.scrollbar-light > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size { top: -19px; }
|
||||
|
||||
.scrollbar-light > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_track { left: -19px; }
|
||||
.scrollbar-light > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_track { top: -19px; }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*************** SCROLLBAR RAIL ***************/
|
||||
|
||||
.scrollbar-rail > .scroll-element,
|
||||
.scrollbar-rail > .scroll-element div
|
||||
{
|
||||
border: none;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.scrollbar-rail > .scroll-element {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.scrollbar-rail > .scroll-element div {
|
||||
display: block;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-rail > .scroll-element .scroll-element_size {
|
||||
background-color: #999;
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.scrollbar-rail > .scroll-element .scroll-element_outer:hover .scroll-element_size {
|
||||
background-color: #666;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.scrollbar-rail > .scroll-element.scroll-x {
|
||||
bottom: 0;
|
||||
height: 12px;
|
||||
left: 0;
|
||||
min-width: 100%;
|
||||
padding: 3px 0 2px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-rail > .scroll-element.scroll-y {
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
padding: 0 2px 0 3px;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 12px;
|
||||
}
|
||||
|
||||
.scrollbar-rail > .scroll-element .scroll-bar {
|
||||
background-color: #d0b9a0;
|
||||
|
||||
-webkit-border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
|
||||
box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.scrollbar-rail > .scroll-element .scroll-element_outer:hover .scroll-bar {
|
||||
box-shadow: 1px 1px 3px rgba(0, 0, 0, 0.6);
|
||||
}
|
||||
|
||||
/* scrollbar height/width & offset from container borders */
|
||||
|
||||
.scrollbar-rail > .scroll-content.scroll-scrolly_visible { left: -17px; margin-left: 17px; }
|
||||
.scrollbar-rail > .scroll-content.scroll-scrollx_visible { margin-top: 17px; top: -17px; }
|
||||
|
||||
.scrollbar-rail > .scroll-element.scroll-x .scroll-bar { height: 10px; min-width: 10px; top: 1px; }
|
||||
.scrollbar-rail > .scroll-element.scroll-y .scroll-bar { left: 1px; min-height: 10px; width: 10px; }
|
||||
|
||||
.scrollbar-rail > .scroll-element.scroll-x .scroll-element_outer { height: 15px; left: 5px; }
|
||||
.scrollbar-rail > .scroll-element.scroll-x .scroll-element_size { height: 2px; left: -10px; top: 5px; }
|
||||
|
||||
.scrollbar-rail > .scroll-element.scroll-y .scroll-element_outer { top: 5px; width: 15px; }
|
||||
.scrollbar-rail > .scroll-element.scroll-y .scroll-element_size { left: 5px; top: -10px; width: 2px; }
|
||||
|
||||
/* update scrollbar offset if both scrolls are visible */
|
||||
|
||||
.scrollbar-rail > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size { left: -25px; }
|
||||
.scrollbar-rail > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size { top: -25px; }
|
||||
|
||||
.scrollbar-rail > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_track { left: -25px; }
|
||||
.scrollbar-rail > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_track { top: -25px; }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*************** SCROLLBAR DYNAMIC ***************/
|
||||
|
||||
.scrollbar-dynamic > .scroll-element,
|
||||
.scrollbar-dynamic > .scroll-element div
|
||||
{
|
||||
background: none;
|
||||
border: none;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.scrollbar-dynamic > .scroll-element div {
|
||||
display: block;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-dynamic > .scroll-element.scroll-x {
|
||||
bottom: 2px;
|
||||
height: 7px;
|
||||
left: 0;
|
||||
min-width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-dynamic > .scroll-element.scroll-y {
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
right: 2px;
|
||||
top: 0;
|
||||
width: 7px;
|
||||
}
|
||||
|
||||
.scrollbar-dynamic > .scroll-element .scroll-element_outer {
|
||||
opacity: 0.3;
|
||||
|
||||
-webkit-border-radius: 12px;
|
||||
-moz-border-radius: 12px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
.scrollbar-dynamic > .scroll-element .scroll-element_size {
|
||||
background-color: #cccccc;
|
||||
opacity: 0;
|
||||
|
||||
-webkit-border-radius: 12px;
|
||||
-moz-border-radius: 12px;
|
||||
border-radius: 12px;
|
||||
|
||||
-webkit-transition: opacity 0.2s;
|
||||
-moz-transition: opacity 0.2s;
|
||||
-o-transition: opacity 0.2s;
|
||||
-ms-transition: opacity 0.2s;
|
||||
transition: opacity 0.2s;
|
||||
}
|
||||
|
||||
.scrollbar-dynamic > .scroll-element .scroll-bar {
|
||||
background-color: #6c6e71;
|
||||
|
||||
-webkit-border-radius: 7px;
|
||||
-moz-border-radius: 7px;
|
||||
border-radius: 7px;
|
||||
}
|
||||
|
||||
/* scrollbar height/width & offset from container borders */
|
||||
|
||||
.scrollbar-dynamic > .scroll-element.scroll-x .scroll-bar {
|
||||
bottom: 0;
|
||||
height: 7px;
|
||||
min-width: 24px;
|
||||
top: auto;
|
||||
}
|
||||
.scrollbar-dynamic > .scroll-element.scroll-y .scroll-bar {
|
||||
left: auto;
|
||||
min-height: 24px;
|
||||
right: 0;
|
||||
width: 7px;
|
||||
}
|
||||
|
||||
.scrollbar-dynamic > .scroll-element.scroll-x .scroll-element_outer {
|
||||
bottom: 0;
|
||||
top: auto;
|
||||
left: 2px;
|
||||
|
||||
-webkit-transition: height 0.2s;
|
||||
-moz-transition: height 0.2s;
|
||||
-o-transition: height 0.2s;
|
||||
-ms-transition: height 0.2s;
|
||||
transition: height 0.2s;
|
||||
}
|
||||
|
||||
.scrollbar-dynamic > .scroll-element.scroll-y .scroll-element_outer {
|
||||
left: auto;
|
||||
right: 0;
|
||||
top: 2px;
|
||||
|
||||
-webkit-transition: width 0.2s;
|
||||
-moz-transition: width 0.2s;
|
||||
-o-transition: width 0.2s;
|
||||
-ms-transition: width 0.2s;
|
||||
transition: width 0.2s;
|
||||
}
|
||||
|
||||
.scrollbar-dynamic > .scroll-element.scroll-x .scroll-element_size { left: -4px; }
|
||||
.scrollbar-dynamic > .scroll-element.scroll-y .scroll-element_size { top: -4px; }
|
||||
|
||||
|
||||
/* update scrollbar offset if both scrolls are visible */
|
||||
|
||||
.scrollbar-dynamic > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size { left: -11px; }
|
||||
.scrollbar-dynamic > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size { top: -11px; }
|
||||
|
||||
|
||||
/* hover & drag */
|
||||
|
||||
.scrollbar-dynamic > .scroll-element:hover .scroll-element_outer,
|
||||
.scrollbar-dynamic > .scroll-element.scroll-draggable .scroll-element_outer {
|
||||
overflow: hidden;
|
||||
|
||||
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=70)";
|
||||
filter: alpha(opacity=70);
|
||||
opacity: 0.7;
|
||||
}
|
||||
.scrollbar-dynamic > .scroll-element:hover .scroll-element_outer .scroll-element_size,
|
||||
.scrollbar-dynamic > .scroll-element.scroll-draggable .scroll-element_outer .scroll-element_size {
|
||||
opacity: 1;
|
||||
}
|
||||
.scrollbar-dynamic > .scroll-element:hover .scroll-element_outer .scroll-bar,
|
||||
.scrollbar-dynamic > .scroll-element.scroll-draggable .scroll-element_outer .scroll-bar {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
-webkit-border-radius: 12px;
|
||||
-moz-border-radius: 12px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.scrollbar-dynamic > .scroll-element.scroll-x:hover .scroll-element_outer,
|
||||
.scrollbar-dynamic > .scroll-element.scroll-x.scroll-draggable .scroll-element_outer {
|
||||
height: 20px;
|
||||
min-height: 7px;
|
||||
}
|
||||
.scrollbar-dynamic > .scroll-element.scroll-y:hover .scroll-element_outer,
|
||||
.scrollbar-dynamic > .scroll-element.scroll-y.scroll-draggable .scroll-element_outer {
|
||||
min-width: 7px;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*************** SCROLLBAR GOOGLE CHROME ***************/
|
||||
|
||||
.scrollbar-chrome > .scroll-element,
|
||||
.scrollbar-chrome > .scroll-element div
|
||||
{
|
||||
border: none;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element {
|
||||
background-color: #ffffff;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element div {
|
||||
display: block;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element .scroll-element_outer {}
|
||||
|
||||
.scrollbar-chrome > .scroll-element .scroll-element_track {
|
||||
background: #f1f1f1;
|
||||
border: 1px solid #dbdbdb;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element.scroll-x {
|
||||
bottom: 0;
|
||||
height: 16px;
|
||||
left: 0;
|
||||
min-width: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element.scroll-y {
|
||||
height: 100%;
|
||||
min-height: 100%;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 16px;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element .scroll-bar {
|
||||
background-color: #d9d9d9;
|
||||
border: 1px solid #bdbdbd;
|
||||
cursor: default;
|
||||
|
||||
-webkit-border-radius: 2px;
|
||||
-moz-border-radius: 2px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element .scroll-bar:hover {
|
||||
background-color: #c2c2c2;
|
||||
border-color: #a9a9a9;
|
||||
}
|
||||
|
||||
.scrollbar-chrome > .scroll-element.scroll-draggable .scroll-bar {
|
||||
background-color: #919191;
|
||||
border-color: #7e7e7e;
|
||||
}
|
||||
|
||||
/* scrollbar height/width & offset from container borders */
|
||||
|
||||
.scrollbar-chrome > .scroll-content.scroll-scrolly_visible { left: -16px; margin-left: 16px; }
|
||||
.scrollbar-chrome > .scroll-content.scroll-scrollx_visible { top: -16px; margin-top: 16px; }
|
||||
|
||||
.scrollbar-chrome > .scroll-element.scroll-x .scroll-bar { height: 8px; min-width: 10px; top: 3px; }
|
||||
.scrollbar-chrome > .scroll-element.scroll-y .scroll-bar { left: 3px; min-height: 10px; width: 8px; }
|
||||
|
||||
.scrollbar-chrome > .scroll-element.scroll-x .scroll-element_outer { border-left: 1px solid #dbdbdb; }
|
||||
.scrollbar-chrome > .scroll-element.scroll-x .scroll-element_track { height: 14px; left: -3px; }
|
||||
.scrollbar-chrome > .scroll-element.scroll-x .scroll-element_size { height: 14px; left: -4px; }
|
||||
|
||||
.scrollbar-chrome > .scroll-element.scroll-y .scroll-element_outer { border-top: 1px solid #dbdbdb; }
|
||||
.scrollbar-chrome > .scroll-element.scroll-y .scroll-element_track { top: -3px; width: 14px; }
|
||||
.scrollbar-chrome > .scroll-element.scroll-y .scroll-element_size { top: -4px; width: 14px; }
|
||||
|
||||
/* update scrollbar offset if both scrolls are visible */
|
||||
|
||||
.scrollbar-chrome > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_size { left: -19px; }
|
||||
.scrollbar-chrome > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_size { top: -19px; }
|
||||
|
||||
.scrollbar-chrome > .scroll-element.scroll-x.scroll-scrolly_visible .scroll-element_track { left: -19px; }
|
||||
.scrollbar-chrome > .scroll-element.scroll-y.scroll-scrollx_visible .scroll-element_track { top: -19px; }
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,781 @@
|
||||
/**
|
||||
* jQuery CSS Customizable Scrollbar
|
||||
*
|
||||
* Copyright 2015, Yuriy Khabarov
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
*
|
||||
* If you found bug, please contact me via email <13real008@gmail.com>
|
||||
*
|
||||
* @author Yuriy Khabarov aka Gromo
|
||||
* @version 0.2.10
|
||||
* @url https://github.com/gromo/jquery.scrollbar/
|
||||
*
|
||||
*/
|
||||
;
|
||||
(function (root, factory) {
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
define(['jquery'], factory);
|
||||
} else {
|
||||
factory(root.jQuery);
|
||||
}
|
||||
}(this, function ($) {
|
||||
'use strict';
|
||||
|
||||
// init flags & variables
|
||||
var debug = false;
|
||||
|
||||
var browser = {
|
||||
data: {
|
||||
index: 0,
|
||||
name: 'scrollbar'
|
||||
},
|
||||
macosx: /mac/i.test(navigator.platform),
|
||||
mobile: /android|webos|iphone|ipad|ipod|blackberry/i.test(navigator.userAgent),
|
||||
overlay: null,
|
||||
scroll: null,
|
||||
scrolls: [],
|
||||
webkit: /webkit/i.test(navigator.userAgent) && !/edge\/\d+/i.test(navigator.userAgent)
|
||||
};
|
||||
|
||||
browser.scrolls.add = function (instance) {
|
||||
this.remove(instance).push(instance);
|
||||
};
|
||||
browser.scrolls.remove = function (instance) {
|
||||
while ($.inArray(instance, this) >= 0) {
|
||||
this.splice($.inArray(instance, this), 1);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
var defaults = {
|
||||
"autoScrollSize": true, // automatically calculate scrollsize
|
||||
"autoUpdate": true, // update scrollbar if content/container size changed
|
||||
"debug": false, // debug mode
|
||||
"disableBodyScroll": false, // disable body scroll if mouse over container
|
||||
"duration": 200, // scroll animate duration in ms
|
||||
"ignoreMobile": false, // ignore mobile devices
|
||||
"ignoreOverlay": false, // ignore browsers with overlay scrollbars (mobile, MacOS)
|
||||
"scrollStep": 30, // scroll step for scrollbar arrows
|
||||
"showArrows": false, // add class to show arrows
|
||||
"stepScrolling": true, // when scrolling to scrollbar mousedown position
|
||||
|
||||
"scrollx": null, // horizontal scroll element
|
||||
"scrolly": null, // vertical scroll element
|
||||
|
||||
"onDestroy": null, // callback function on destroy,
|
||||
"onInit": null, // callback function on first initialization
|
||||
"onScroll": null, // callback function on content scrolling
|
||||
"onUpdate": null // callback function on init/resize (before scrollbar size calculation)
|
||||
};
|
||||
|
||||
|
||||
var BaseScrollbar = function (container) {
|
||||
|
||||
if (!browser.scroll) {
|
||||
browser.overlay = isScrollOverlaysContent();
|
||||
browser.scroll = getBrowserScrollSize();
|
||||
updateScrollbars();
|
||||
|
||||
$(window).resize(function () {
|
||||
var forceUpdate = false;
|
||||
if (browser.scroll && (browser.scroll.height || browser.scroll.width)) {
|
||||
var scroll = getBrowserScrollSize();
|
||||
if (scroll.height !== browser.scroll.height || scroll.width !== browser.scroll.width) {
|
||||
browser.scroll = scroll;
|
||||
forceUpdate = true; // handle page zoom
|
||||
}
|
||||
}
|
||||
updateScrollbars(forceUpdate);
|
||||
});
|
||||
}
|
||||
|
||||
this.container = container;
|
||||
this.namespace = '.scrollbar_' + browser.data.index++;
|
||||
this.options = $.extend({}, defaults, window.jQueryScrollbarOptions || {});
|
||||
this.scrollTo = null;
|
||||
this.scrollx = {};
|
||||
this.scrolly = {};
|
||||
|
||||
container.data(browser.data.name, this);
|
||||
browser.scrolls.add(this);
|
||||
};
|
||||
|
||||
BaseScrollbar.prototype = {
|
||||
|
||||
destroy: function () {
|
||||
|
||||
if (!this.wrapper) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.container.removeData(browser.data.name);
|
||||
browser.scrolls.remove(this);
|
||||
|
||||
// init variables
|
||||
var scrollLeft = this.container.scrollLeft();
|
||||
var scrollTop = this.container.scrollTop();
|
||||
|
||||
this.container.insertBefore(this.wrapper).css({
|
||||
"height": "",
|
||||
"margin": "",
|
||||
"max-height": ""
|
||||
})
|
||||
.removeClass('scroll-content scroll-scrollx_visible scroll-scrolly_visible')
|
||||
.off(this.namespace)
|
||||
.scrollLeft(scrollLeft)
|
||||
.scrollTop(scrollTop);
|
||||
|
||||
this.scrollx.scroll.removeClass('scroll-scrollx_visible').find('div').andSelf().off(this.namespace);
|
||||
this.scrolly.scroll.removeClass('scroll-scrolly_visible').find('div').andSelf().off(this.namespace);
|
||||
|
||||
this.wrapper.remove();
|
||||
|
||||
$(document).add('body').off(this.namespace);
|
||||
|
||||
if ($.isFunction(this.options.onDestroy)){
|
||||
this.options.onDestroy.apply(this, [this.container]);
|
||||
}
|
||||
},
|
||||
init: function (options) {
|
||||
|
||||
// init variables
|
||||
var S = this,
|
||||
c = this.container,
|
||||
cw = this.containerWrapper || c,
|
||||
namespace = this.namespace,
|
||||
o = $.extend(this.options, options || {}),
|
||||
s = {x: this.scrollx, y: this.scrolly},
|
||||
w = this.wrapper;
|
||||
|
||||
var initScroll = {
|
||||
"scrollLeft": c.scrollLeft(),
|
||||
"scrollTop": c.scrollTop()
|
||||
};
|
||||
|
||||
// do not init if in ignorable browser
|
||||
if ((browser.mobile && o.ignoreMobile)
|
||||
|| (browser.overlay && o.ignoreOverlay)
|
||||
|| (browser.macosx && !browser.webkit) // still required to ignore nonWebKit browsers on Mac
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// init scroll container
|
||||
if (!w) {
|
||||
this.wrapper = w = $('<div>').addClass('scroll-wrapper').addClass(c.attr('class'))
|
||||
.css('position', c.css('position') == 'absolute' ? 'absolute' : 'relative')
|
||||
.insertBefore(c).append(c);
|
||||
|
||||
if (c.is('textarea')) {
|
||||
this.containerWrapper = cw = $('<div>').insertBefore(c).append(c);
|
||||
w.addClass('scroll-textarea');
|
||||
}
|
||||
|
||||
cw.addClass('scroll-content').css({
|
||||
"height": "auto",
|
||||
"margin-bottom": browser.scroll.height * -1 + 'px',
|
||||
"margin-right": browser.scroll.width * -1 + 'px',
|
||||
"max-height": ""
|
||||
});
|
||||
|
||||
c.on('scroll' + namespace, function (event) {
|
||||
if ($.isFunction(o.onScroll)) {
|
||||
o.onScroll.call(S, {
|
||||
"maxScroll": s.y.maxScrollOffset,
|
||||
"scroll": c.scrollTop(),
|
||||
"size": s.y.size,
|
||||
"visible": s.y.visible
|
||||
}, {
|
||||
"maxScroll": s.x.maxScrollOffset,
|
||||
"scroll": c.scrollLeft(),
|
||||
"size": s.x.size,
|
||||
"visible": s.x.visible
|
||||
});
|
||||
}
|
||||
s.x.isVisible && s.x.scroll.bar.css('left', c.scrollLeft() * s.x.kx + 'px');
|
||||
s.y.isVisible && s.y.scroll.bar.css('top', c.scrollTop() * s.y.kx + 'px');
|
||||
});
|
||||
|
||||
/* prevent native scrollbars to be visible on #anchor click */
|
||||
w.on('scroll' + namespace, function () {
|
||||
w.scrollTop(0).scrollLeft(0);
|
||||
});
|
||||
|
||||
if (o.disableBodyScroll) {
|
||||
var handleMouseScroll = function (event) {
|
||||
isVerticalScroll(event) ?
|
||||
s.y.isVisible && s.y.mousewheel(event) :
|
||||
s.x.isVisible && s.x.mousewheel(event);
|
||||
};
|
||||
w.on('MozMousePixelScroll' + namespace, handleMouseScroll);
|
||||
w.on('mousewheel' + namespace, handleMouseScroll);
|
||||
|
||||
if (browser.mobile) {
|
||||
w.on('touchstart' + namespace, function (event) {
|
||||
var touch = event.originalEvent.touches && event.originalEvent.touches[0] || event;
|
||||
var originalTouch = {
|
||||
"pageX": touch.pageX,
|
||||
"pageY": touch.pageY
|
||||
};
|
||||
var originalScroll = {
|
||||
"left": c.scrollLeft(),
|
||||
"top": c.scrollTop()
|
||||
};
|
||||
$(document).on('touchmove' + namespace, function (event) {
|
||||
var touch = event.originalEvent.targetTouches && event.originalEvent.targetTouches[0] || event;
|
||||
c.scrollLeft(originalScroll.left + originalTouch.pageX - touch.pageX);
|
||||
c.scrollTop(originalScroll.top + originalTouch.pageY - touch.pageY);
|
||||
event.preventDefault();
|
||||
});
|
||||
$(document).on('touchend' + namespace, function () {
|
||||
$(document).off(namespace);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
if ($.isFunction(o.onInit)){
|
||||
o.onInit.apply(this, [c]);
|
||||
}
|
||||
} else {
|
||||
cw.css({
|
||||
"height": "auto",
|
||||
"margin-bottom": browser.scroll.height * -1 + 'px',
|
||||
"margin-right": browser.scroll.width * -1 + 'px',
|
||||
"max-height": ""
|
||||
});
|
||||
}
|
||||
|
||||
// init scrollbars & recalculate sizes
|
||||
$.each(s, function (d, scrollx) {
|
||||
|
||||
var scrollCallback = null;
|
||||
var scrollForward = 1;
|
||||
var scrollOffset = (d === 'x') ? 'scrollLeft' : 'scrollTop';
|
||||
var scrollStep = o.scrollStep;
|
||||
var scrollTo = function () {
|
||||
var currentOffset = c[scrollOffset]();
|
||||
c[scrollOffset](currentOffset + scrollStep);
|
||||
if (scrollForward == 1 && (currentOffset + scrollStep) >= scrollToValue)
|
||||
currentOffset = c[scrollOffset]();
|
||||
if (scrollForward == -1 && (currentOffset + scrollStep) <= scrollToValue)
|
||||
currentOffset = c[scrollOffset]();
|
||||
if (c[scrollOffset]() == currentOffset && scrollCallback) {
|
||||
scrollCallback();
|
||||
}
|
||||
}
|
||||
var scrollToValue = 0;
|
||||
|
||||
if (!scrollx.scroll) {
|
||||
|
||||
scrollx.scroll = S._getScroll(o['scroll' + d]).addClass('scroll-' + d);
|
||||
|
||||
if(o.showArrows){
|
||||
scrollx.scroll.addClass('scroll-element_arrows_visible');
|
||||
}
|
||||
|
||||
scrollx.mousewheel = function (event) {
|
||||
|
||||
if (!scrollx.isVisible || (d === 'x' && isVerticalScroll(event))) {
|
||||
return true;
|
||||
}
|
||||
if (d === 'y' && !isVerticalScroll(event)) {
|
||||
s.x.mousewheel(event);
|
||||
return true;
|
||||
}
|
||||
|
||||
var delta = event.originalEvent.wheelDelta * -1 || event.originalEvent.detail;
|
||||
var maxScrollValue = scrollx.size - scrollx.visible - scrollx.offset;
|
||||
|
||||
if ((delta > 0 && scrollToValue < maxScrollValue) || (delta < 0 && scrollToValue > 0)) {
|
||||
scrollToValue = scrollToValue + delta;
|
||||
if (scrollToValue < 0)
|
||||
scrollToValue = 0;
|
||||
if (scrollToValue > maxScrollValue)
|
||||
scrollToValue = maxScrollValue;
|
||||
|
||||
S.scrollTo = S.scrollTo || {};
|
||||
S.scrollTo[scrollOffset] = scrollToValue;
|
||||
setTimeout(function () {
|
||||
if (S.scrollTo) {
|
||||
c.stop().animate(S.scrollTo, 240, 'linear', function () {
|
||||
scrollToValue = c[scrollOffset]();
|
||||
});
|
||||
S.scrollTo = null;
|
||||
}
|
||||
}, 1);
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
return false;
|
||||
};
|
||||
|
||||
scrollx.scroll
|
||||
.on('MozMousePixelScroll' + namespace, scrollx.mousewheel)
|
||||
.on('mousewheel' + namespace, scrollx.mousewheel)
|
||||
.on('mouseenter' + namespace, function () {
|
||||
scrollToValue = c[scrollOffset]();
|
||||
});
|
||||
|
||||
// handle arrows & scroll inner mousedown event
|
||||
scrollx.scroll.find('.scroll-arrow, .scroll-element_track')
|
||||
.on('mousedown' + namespace, function (event) {
|
||||
|
||||
if (event.which != 1) // lmb
|
||||
return true;
|
||||
|
||||
scrollForward = 1;
|
||||
|
||||
var data = {
|
||||
"eventOffset": event[(d === 'x') ? 'pageX' : 'pageY'],
|
||||
"maxScrollValue": scrollx.size - scrollx.visible - scrollx.offset,
|
||||
"scrollbarOffset": scrollx.scroll.bar.offset()[(d === 'x') ? 'left' : 'top'],
|
||||
"scrollbarSize": scrollx.scroll.bar[(d === 'x') ? 'outerWidth' : 'outerHeight']()
|
||||
};
|
||||
var timeout = 0, timer = 0;
|
||||
|
||||
if ($(this).hasClass('scroll-arrow')) {
|
||||
scrollForward = $(this).hasClass("scroll-arrow_more") ? 1 : -1;
|
||||
scrollStep = o.scrollStep * scrollForward;
|
||||
scrollToValue = scrollForward > 0 ? data.maxScrollValue : 0;
|
||||
} else {
|
||||
scrollForward = (data.eventOffset > (data.scrollbarOffset + data.scrollbarSize) ? 1
|
||||
: (data.eventOffset < data.scrollbarOffset ? -1 : 0));
|
||||
scrollStep = Math.round(scrollx.visible * 0.75) * scrollForward;
|
||||
scrollToValue = (data.eventOffset - data.scrollbarOffset -
|
||||
(o.stepScrolling ? (scrollForward == 1 ? data.scrollbarSize : 0)
|
||||
: Math.round(data.scrollbarSize / 2)));
|
||||
scrollToValue = c[scrollOffset]() + (scrollToValue / scrollx.kx);
|
||||
}
|
||||
|
||||
S.scrollTo = S.scrollTo || {};
|
||||
S.scrollTo[scrollOffset] = o.stepScrolling ? c[scrollOffset]() + scrollStep : scrollToValue;
|
||||
|
||||
if (o.stepScrolling) {
|
||||
scrollCallback = function () {
|
||||
scrollToValue = c[scrollOffset]();
|
||||
clearInterval(timer);
|
||||
clearTimeout(timeout);
|
||||
timeout = 0;
|
||||
timer = 0;
|
||||
};
|
||||
timeout = setTimeout(function () {
|
||||
timer = setInterval(scrollTo, 40);
|
||||
}, o.duration + 100);
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
if (S.scrollTo) {
|
||||
c.animate(S.scrollTo, o.duration);
|
||||
S.scrollTo = null;
|
||||
}
|
||||
}, 1);
|
||||
|
||||
return S._handleMouseDown(scrollCallback, event);
|
||||
});
|
||||
|
||||
// handle scrollbar drag'n'drop
|
||||
scrollx.scroll.bar.on('mousedown' + namespace, function (event) {
|
||||
|
||||
if (event.which != 1) // lmb
|
||||
return true;
|
||||
|
||||
var eventPosition = event[(d === 'x') ? 'pageX' : 'pageY'];
|
||||
var initOffset = c[scrollOffset]();
|
||||
|
||||
scrollx.scroll.addClass('scroll-draggable');
|
||||
|
||||
$(document).on('mousemove' + namespace, function (event) {
|
||||
var diff = parseInt((event[(d === 'x') ? 'pageX' : 'pageY'] - eventPosition) / scrollx.kx, 10);
|
||||
c[scrollOffset](initOffset + diff);
|
||||
});
|
||||
|
||||
return S._handleMouseDown(function () {
|
||||
scrollx.scroll.removeClass('scroll-draggable');
|
||||
scrollToValue = c[scrollOffset]();
|
||||
}, event);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// remove classes & reset applied styles
|
||||
$.each(s, function (d, scrollx) {
|
||||
var scrollClass = 'scroll-scroll' + d + '_visible';
|
||||
var scrolly = (d == "x") ? s.y : s.x;
|
||||
|
||||
scrollx.scroll.removeClass(scrollClass);
|
||||
scrolly.scroll.removeClass(scrollClass);
|
||||
cw.removeClass(scrollClass);
|
||||
});
|
||||
|
||||
// calculate init sizes
|
||||
$.each(s, function (d, scrollx) {
|
||||
$.extend(scrollx, (d == "x") ? {
|
||||
"offset": parseInt(c.css('left'), 10) || 0,
|
||||
"size": c.prop('scrollWidth'),
|
||||
"visible": w.width()
|
||||
} : {
|
||||
"offset": parseInt(c.css('top'), 10) || 0,
|
||||
"size": c.prop('scrollHeight'),
|
||||
"visible": w.height()
|
||||
});
|
||||
});
|
||||
|
||||
// update scrollbar visibility/dimensions
|
||||
this._updateScroll('x', this.scrollx);
|
||||
this._updateScroll('y', this.scrolly);
|
||||
|
||||
if ($.isFunction(o.onUpdate)){
|
||||
o.onUpdate.apply(this, [c]);
|
||||
}
|
||||
|
||||
// calculate scroll size
|
||||
$.each(s, function (d, scrollx) {
|
||||
|
||||
var cssOffset = (d === 'x') ? 'left' : 'top';
|
||||
var cssFullSize = (d === 'x') ? 'outerWidth' : 'outerHeight';
|
||||
var cssSize = (d === 'x') ? 'width' : 'height';
|
||||
var offset = parseInt(c.css(cssOffset), 10) || 0;
|
||||
|
||||
var AreaSize = scrollx.size;
|
||||
var AreaVisible = scrollx.visible + offset;
|
||||
|
||||
var scrollSize = scrollx.scroll.size[cssFullSize]() + (parseInt(scrollx.scroll.size.css(cssOffset), 10) || 0);
|
||||
|
||||
if (o.autoScrollSize) {
|
||||
scrollx.scrollbarSize = parseInt(scrollSize * AreaVisible / AreaSize, 10);
|
||||
scrollx.scroll.bar.css(cssSize, scrollx.scrollbarSize + 'px');
|
||||
}
|
||||
|
||||
scrollx.scrollbarSize = scrollx.scroll.bar[cssFullSize]();
|
||||
scrollx.kx = ((scrollSize - scrollx.scrollbarSize) / (AreaSize - AreaVisible)) || 1;
|
||||
scrollx.maxScrollOffset = AreaSize - AreaVisible;
|
||||
});
|
||||
|
||||
c.scrollLeft(initScroll.scrollLeft).scrollTop(initScroll.scrollTop).trigger('scroll');
|
||||
},
|
||||
|
||||
/**
|
||||
* Get scrollx/scrolly object
|
||||
*
|
||||
* @param {Mixed} scroll
|
||||
* @returns {jQuery} scroll object
|
||||
*/
|
||||
_getScroll: function (scroll) {
|
||||
var types = {
|
||||
advanced: [
|
||||
'<div class="scroll-element">',
|
||||
'<div class="scroll-element_corner"></div>',
|
||||
'<div class="scroll-arrow scroll-arrow_less"></div>',
|
||||
'<div class="scroll-arrow scroll-arrow_more"></div>',
|
||||
'<div class="scroll-element_outer">',
|
||||
'<div class="scroll-element_size"></div>', // required! used for scrollbar size calculation !
|
||||
'<div class="scroll-element_inner-wrapper">',
|
||||
'<div class="scroll-element_inner scroll-element_track">', // used for handling scrollbar click
|
||||
'<div class="scroll-element_inner-bottom"></div>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'<div class="scroll-bar">', // required
|
||||
'<div class="scroll-bar_body">',
|
||||
'<div class="scroll-bar_body-inner"></div>',
|
||||
'</div>',
|
||||
'<div class="scroll-bar_bottom"></div>',
|
||||
'<div class="scroll-bar_center"></div>',
|
||||
'</div>',
|
||||
'</div>',
|
||||
'</div>'
|
||||
].join(''),
|
||||
simple: [
|
||||
'<div class="scroll-element">',
|
||||
'<div class="scroll-element_outer">',
|
||||
'<div class="scroll-element_size"></div>', // required! used for scrollbar size calculation !
|
||||
'<div class="scroll-element_track"></div>', // used for handling scrollbar click
|
||||
'<div class="scroll-bar"></div>', // required
|
||||
'</div>',
|
||||
'</div>'
|
||||
].join('')
|
||||
};
|
||||
if (types[scroll]) {
|
||||
scroll = types[scroll];
|
||||
}
|
||||
if (!scroll) {
|
||||
scroll = types['simple'];
|
||||
}
|
||||
if (typeof (scroll) == 'string') {
|
||||
scroll = $(scroll).appendTo(this.wrapper);
|
||||
} else {
|
||||
scroll = $(scroll);
|
||||
}
|
||||
$.extend(scroll, {
|
||||
bar: scroll.find('.scroll-bar'),
|
||||
size: scroll.find('.scroll-element_size'),
|
||||
track: scroll.find('.scroll-element_track')
|
||||
});
|
||||
return scroll;
|
||||
},
|
||||
|
||||
_handleMouseDown: function(callback, event) {
|
||||
|
||||
var namespace = this.namespace;
|
||||
|
||||
$(document).on('blur' + namespace, function () {
|
||||
$(document).add('body').off(namespace);
|
||||
callback && callback();
|
||||
});
|
||||
$(document).on('dragstart' + namespace, function (event) {
|
||||
event.preventDefault();
|
||||
return false;
|
||||
});
|
||||
$(document).on('mouseup' + namespace, function () {
|
||||
$(document).add('body').off(namespace);
|
||||
callback && callback();
|
||||
});
|
||||
$('body').on('selectstart' + namespace, function (event) {
|
||||
event.preventDefault();
|
||||
return false;
|
||||
});
|
||||
|
||||
event && event.preventDefault();
|
||||
return false;
|
||||
},
|
||||
|
||||
_updateScroll: function (d, scrollx) {
|
||||
|
||||
var container = this.container,
|
||||
containerWrapper = this.containerWrapper || container,
|
||||
scrollClass = 'scroll-scroll' + d + '_visible',
|
||||
scrolly = (d === 'x') ? this.scrolly : this.scrollx,
|
||||
offset = parseInt(this.container.css((d === 'x') ? 'left' : 'top'), 10) || 0,
|
||||
wrapper = this.wrapper;
|
||||
|
||||
var AreaSize = scrollx.size;
|
||||
var AreaVisible = scrollx.visible + offset;
|
||||
|
||||
scrollx.isVisible = (AreaSize - AreaVisible) > 1; // bug in IE9/11 with 1px diff
|
||||
if (scrollx.isVisible) {
|
||||
scrollx.scroll.addClass(scrollClass);
|
||||
scrolly.scroll.addClass(scrollClass);
|
||||
containerWrapper.addClass(scrollClass);
|
||||
} else {
|
||||
scrollx.scroll.removeClass(scrollClass);
|
||||
scrolly.scroll.removeClass(scrollClass);
|
||||
containerWrapper.removeClass(scrollClass);
|
||||
}
|
||||
|
||||
if (d === 'y') {
|
||||
if(container.is('textarea') || AreaSize < AreaVisible){
|
||||
containerWrapper.css({
|
||||
"height": (AreaVisible + browser.scroll.height) + 'px',
|
||||
"max-height": "none"
|
||||
});
|
||||
} else {
|
||||
containerWrapper.css({
|
||||
//"height": "auto", // do not reset height value: issue with height:100%!
|
||||
"max-height": (AreaVisible + browser.scroll.height) + 'px'
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (scrollx.size != container.prop('scrollWidth')
|
||||
|| scrolly.size != container.prop('scrollHeight')
|
||||
|| scrollx.visible != wrapper.width()
|
||||
|| scrolly.visible != wrapper.height()
|
||||
|| scrollx.offset != (parseInt(container.css('left'), 10) || 0)
|
||||
|| scrolly.offset != (parseInt(container.css('top'), 10) || 0)
|
||||
) {
|
||||
$.extend(this.scrollx, {
|
||||
"offset": parseInt(container.css('left'), 10) || 0,
|
||||
"size": container.prop('scrollWidth'),
|
||||
"visible": wrapper.width()
|
||||
});
|
||||
$.extend(this.scrolly, {
|
||||
"offset": parseInt(container.css('top'), 10) || 0,
|
||||
"size": this.container.prop('scrollHeight'),
|
||||
"visible": wrapper.height()
|
||||
});
|
||||
this._updateScroll(d === 'x' ? 'y' : 'x', scrolly);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var CustomScrollbar = BaseScrollbar;
|
||||
|
||||
/*
|
||||
* Extend jQuery as plugin
|
||||
*
|
||||
* @param {Mixed} command to execute
|
||||
* @param {Mixed} arguments as Array
|
||||
* @return {jQuery}
|
||||
*/
|
||||
$.fn.scrollbar = function (command, args) {
|
||||
if (typeof command !== 'string') {
|
||||
args = command;
|
||||
command = 'init';
|
||||
}
|
||||
if (typeof args === 'undefined') {
|
||||
args = [];
|
||||
}
|
||||
if (!$.isArray(args)) {
|
||||
args = [args];
|
||||
}
|
||||
this.not('body, .scroll-wrapper').each(function () {
|
||||
var element = $(this),
|
||||
instance = element.data(browser.data.name);
|
||||
if (instance || command === 'init') {
|
||||
if (!instance) {
|
||||
instance = new CustomScrollbar(element);
|
||||
}
|
||||
if (instance[command]) {
|
||||
instance[command].apply(instance, args);
|
||||
}
|
||||
}
|
||||
});
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* Connect default options to global object
|
||||
*/
|
||||
$.fn.scrollbar.options = defaults;
|
||||
|
||||
|
||||
/**
|
||||
* Check if scroll content/container size is changed
|
||||
*/
|
||||
|
||||
var updateScrollbars = (function () {
|
||||
var timer = 0,
|
||||
timerCounter = 0;
|
||||
|
||||
return function (force) {
|
||||
var i, container, options, scroll, wrapper, scrollx, scrolly;
|
||||
for (i = 0; i < browser.scrolls.length; i++) {
|
||||
scroll = browser.scrolls[i];
|
||||
container = scroll.container;
|
||||
options = scroll.options;
|
||||
wrapper = scroll.wrapper;
|
||||
scrollx = scroll.scrollx;
|
||||
scrolly = scroll.scrolly;
|
||||
if (force || (options.autoUpdate && wrapper && wrapper.is(':visible') &&
|
||||
(container.prop('scrollWidth') != scrollx.size || container.prop('scrollHeight') != scrolly.size || wrapper.width() != scrollx.visible || wrapper.height() != scrolly.visible))) {
|
||||
scroll.init();
|
||||
|
||||
if (options.debug) {
|
||||
window.console && console.log({
|
||||
scrollHeight: container.prop('scrollHeight') + ':' + scroll.scrolly.size,
|
||||
scrollWidth: container.prop('scrollWidth') + ':' + scroll.scrollx.size,
|
||||
visibleHeight: wrapper.height() + ':' + scroll.scrolly.visible,
|
||||
visibleWidth: wrapper.width() + ':' + scroll.scrollx.visible
|
||||
}, true);
|
||||
timerCounter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (debug && timerCounter > 10) {
|
||||
window.console && console.log('Scroll updates exceed 10');
|
||||
updateScrollbars = function () {};
|
||||
} else {
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(updateScrollbars, 300);
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
/* ADDITIONAL FUNCTIONS */
|
||||
/**
|
||||
* Get native browser scrollbar size (height/width)
|
||||
*
|
||||
* @param {Boolean} actual size or CSS size, default - CSS size
|
||||
* @returns {Object} with height, width
|
||||
*/
|
||||
function getBrowserScrollSize(actualSize) {
|
||||
|
||||
if (browser.webkit && !actualSize) {
|
||||
return {
|
||||
"height": 0,
|
||||
"width": 0
|
||||
};
|
||||
}
|
||||
|
||||
if (!browser.data.outer) {
|
||||
var css = {
|
||||
"border": "none",
|
||||
"box-sizing": "content-box",
|
||||
"height": "200px",
|
||||
"margin": "0",
|
||||
"padding": "0",
|
||||
"width": "200px"
|
||||
};
|
||||
browser.data.inner = $("<div>").css($.extend({}, css));
|
||||
browser.data.outer = $("<div>").css($.extend({
|
||||
"left": "-1000px",
|
||||
"overflow": "scroll",
|
||||
"position": "absolute",
|
||||
"top": "-1000px"
|
||||
}, css)).append(browser.data.inner).appendTo("body");
|
||||
}
|
||||
|
||||
browser.data.outer.scrollLeft(1000).scrollTop(1000);
|
||||
|
||||
return {
|
||||
"height": Math.ceil((browser.data.outer.offset().top - browser.data.inner.offset().top) || 0),
|
||||
"width": Math.ceil((browser.data.outer.offset().left - browser.data.inner.offset().left) || 0)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if native browser scrollbars overlay content
|
||||
*
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
function isScrollOverlaysContent() {
|
||||
var scrollSize = getBrowserScrollSize(true);
|
||||
return !(scrollSize.height || scrollSize.width);
|
||||
}
|
||||
|
||||
function isVerticalScroll(event) {
|
||||
var e = event.originalEvent;
|
||||
if (e.axis && e.axis === e.HORIZONTAL_AXIS)
|
||||
return false;
|
||||
if (e.wheelDeltaX)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Extend AngularJS as UI directive
|
||||
* and expose a provider for override default config
|
||||
*
|
||||
*/
|
||||
if (window.angular) {
|
||||
(function (angular) {
|
||||
angular.module('jQueryScrollbar', [])
|
||||
.provider('jQueryScrollbar', function () {
|
||||
var defaultOptions = defaults;
|
||||
return {
|
||||
setOptions: function (options) {
|
||||
angular.extend(defaultOptions, options);
|
||||
},
|
||||
$get: function () {
|
||||
return {
|
||||
options: angular.copy(defaultOptions)
|
||||
};
|
||||
}
|
||||
};
|
||||
})
|
||||
.directive('jqueryScrollbar', ['jQueryScrollbar', '$parse', function (jQueryScrollbar, $parse) {
|
||||
return {
|
||||
"restrict": "AC",
|
||||
"link": function (scope, element, attrs) {
|
||||
var model = $parse(attrs.jqueryScrollbar),
|
||||
options = model(scope);
|
||||
element.scrollbar(options || jQueryScrollbar.options)
|
||||
.on('$destroy', function () {
|
||||
element.scrollbar('destroy');
|
||||
});
|
||||
}
|
||||
};
|
||||
}]);
|
||||
})(window.angular);
|
||||
}
|
||||
}));
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user