wacomink
Version:
608 lines (606 loc) • 27.2 kB
JavaScript
/*
window.debug = true;
window.onerror = function(message, url, line) {
var body = url +
"\n\n" + message +
"\n" + "Line #: " + line;
if (window.debug) {
alert(body);
throw Error(message);
}
};
*/
if (!String.prototype.contains)
String.prototype.contains = function (str) { return (this.indexOf(str) != -1); };
if (!String.prototype.startsWith)
String.prototype.startsWith = function (str) { return (this.length >= str.length && this.substring(0, str.length) == str); };
if (!String.prototype.endsWith)
String.prototype.endsWith = function (str) { return (this.length >= str.length && this.substring(this.length - str.length, this.length) == str); };
String.prototype.charsCode = function () { return this.split("").reduce(function (previous, current) { return previous + current.charCodeAt(0); }, 0); };
String.prototype.containsIgnoreCase = function (str) { return (this.toUpperCase().indexOf(str.toUpperCase()) != -1); };
String.prototype.toCharArray = function (bytes) { var list = bytes ? new Uint8Array(this.length) : new Array(this.length); list.bytes = true; for (var i = 0; i < this.length; i++) {
var code = this.charCodeAt(i);
if (code > 255)
list.bytes = false;
list[i] = code;
} return list; };
String.fromCharArray = function (arr) { var binary = ""; try {
binary = String.fromCharCode.apply(null, arr);
}
catch (e) {
for (var i = 0; i < bytes.length; i++)
binary += String.fromCharCode(bytes[i]);
} return binary; };
String.prototype.pad = function (length, char) { return (this.length < length) ? new Array(length - this.length + 1).join(char || "-") + this : this.toString(); };
Number.prototype.pad = function (length) { return (String(this).length < length) ? new Array(length - String(this).length + 1).join(0) + String(this) : this.toString(); };
Number.prototype.toFloat32 = function () { var fa32 = new Float32Array(1); fa32[0] = this; return fa32[0]; };
Object.defineProperty(Array.prototype, "first", { get: function () { return this[0]; } });
Object.defineProperty(Array.prototype, "last", { get: function () { return this[this.length - 1]; } });
Array.prototype.contains = function (value) { return this.indexOf(value) > -1; };
Array.prototype.clone = function () { var result = new Array(); this.forEach(function (value) { result.push(Object.clone(value)); }); return result; };
Array.prototype.pushArray = function () { this.push.apply(this, this.concat.apply([], arguments)); };
Array.prototype.add = function (item) { if (!this.contains(item))
return this.push(item); };
Array.prototype.remove = function (element) { return this.removeAt(this.indexOf(element)); };
Array.prototype.removeAt = function (idx) { if (idx > -1)
this.splice(idx, 1); return this; };
Array.prototype.replace = function (element, replaceWith) {
var index = this.indexOf(element);
if (index > -1) {
if (replaceWith instanceof Array) {
var args = [index, 1];
for (var i = 0; i < replaceWith.length; i++)
args.push(replaceWith[i]);
this.splice.apply(this, args);
}
else
this.splice(index, 1, replaceWith);
}
return this;
};
Array.protoTypedArrays = function () {
["Int8", "Uint8", "Uint8Clamped", "Int16", "Uint16", "Int32", "Uint32", "Float32", "Float64"].forEach(function (type) {
var typedArray = eval(type + "Array");
if (typedArray.from)
Array.prototype["to" + type + "Array"] = function () { return typedArray.from(this); };
else
Array.prototype["to" + type + "Array"] = function () { return new typedArray(this); };
if (Array.from)
typedArray.prototype.toArray = function () { return Array.from(this); };
else
typedArray.prototype.toArray = function () { return Array.prototype.slice.call(this); };
typedArray.prototype.clone = function () { return new typedArray(this, this.byteOffset, this.length); };
// Safari fix, remove when possible
if (!typedArray.prototype.forEach)
typedArray.prototype.forEach = Array.prototype.forEach;
});
};
Array.protoTypedArrays();
delete Array.protoTypedArrays;
ArrayBuffer.isTypedArray = function (o) {
return ArrayBuffer.isView(o) && !(o instanceof DataView);
// return !!(
// o instanceof Int8Array || o instanceof Uint8Array || o instanceof Uint8ClampedArray ||
// o instanceof Int16Array || o instanceof Uint16Array ||
// o instanceof Int32Array || o instanceof Uint32Array ||
// o instanceof Float32Array || o instanceof Float64Array
// );
};
if (!Function.name)
Function.name = "Function";
if (!Array.prototype.constructor.name)
Array.prototype.constructor.name = "Array";
Function.create = function (name, body) {
if (!body)
body = function () { };
var args = body.getArguments();
var f = new Function("body", "return function " + name + "(" + args + ") {return body.apply(this, arguments);};")(body);
f.toString = function () { return body.toString(); };
f.toSource = function () { return body.toSource(); };
return f;
// return new Function("body", "return function " + name + "() {return body.apply(this, arguments);};")(body || function() {});
};
if (!("name" in Function.prototype))
Object.defineProperty(Function.prototype, "name", { configurable: true, get: function () { var m = this.toString().match(/^function\s([\w$]+)/); return m ? m[1] : ""; } });
Function.prototype.getArguments = function () { var m = this.toString().match(/\((.*?)\)/)[1].replace(/\s*/g, ""); return (m.length == 0) ? [] : m.split(","); };
Function.prototype.getBody = function () { return this.toString().match(/\{([\s\S]*)\}/m)[1].replace(/^\s*\/\/.*$/mg, ""); };
Function.prototype.construct = function (oThis) {
var fnArguments = arguments.callee.caller.arguments;
this.getArguments().forEach(function (name, i) {
this[name] = fnArguments[i];
}, oThis);
};
Function.prototype.createEnum = function (name, keys) {
if (this[name])
throw new Error("Already exists key: " + name);
this[name] = new Object();
for (var i = 0; i < keys.length; i++) {
var value = name + "_" + keys[i];
var type = this[name];
type[keys[i]] = (function () {
var enm = Object.create(Object.prototype, {
constructor: { value: Function.create(value) },
type: { value: name },
name: { value: keys[i] },
value: { value: i }
});
Object.defineProperty(type, i, { get: function () { return enm; } });
return enm;
})();
}
};
Function.prototype.argsToJSON = function (defaults) {
var json = {};
if (!defaults)
defaults = {};
var fnArguments = arguments.callee.caller.arguments;
this.getArguments().forEach(function (name, i) {
json[name] = fnArguments[i];
if (typeof json[name] == "undefined" && name in defaults)
json[name] = defaults[name];
});
return json;
};
Function.prototype.getInheritanceChain = function () {
var result = new Array();
var parent = this.constructor;
result.push(this.prototype.constructor);
while (parent.name != "Function") {
result.push(parent);
parent = parent.constructor;
}
if (parent != this.prototype.constructor)
result.push(parent);
return result;
};
Function.prototype.isClassMethod = function (method) {
var result = false;
if (method.name)
result = this.prototype[method.name] == method;
else {
for (var name in this.prototype) {
if (this.prototype[name] == method) {
result = true;
break;
}
}
}
return result;
};
Function.prototype.extends = function (superClass) {
this.prototype = Object.create(superClass.prototype);
this.prototype.constructor = this;
this.constructor = superClass.prototype.constructor;
for (var property in superClass) {
if (superClass.hasOwnProperty(property))
this[property] = superClass[property];
}
if (!this.prototype.$parent) {
Object.defineProperty(this.prototype, "super", {
get: function () {
var result;
var self = this;
var chain = this.constructor.getInheritanceChain();
var caller = arguments.callee.caller;
if (!caller)
return null;
if (chain.contains(caller)) {
var parent = this.constructor.constructor;
var depth = chain.indexOf(caller);
while (depth > 0) {
parent = parent.constructor;
depth--;
}
result = function () {
parent.apply(self, arguments);
};
result.bind = function (name) {
var method = parent.prototype[name];
if (!method)
throw new Error("super function with name '" + name + "' not found");
return function () {
return method.apply(self, arguments);
};
};
}
else {
var callerClass;
for (var i = 0; i < chain.length; i++) {
var clazz = chain[i];
if (clazz.isClassMethod(caller)) {
callerClass = clazz;
break;
}
}
if (!callerClass)
throw new Error("super call is outside of inheritance chain");
var bind = function (name) {
var caller = callerClass.prototype[name];
var parent = callerClass.constructor;
while (parent && parent.prototype[name] == caller) {
parent = parent.constructor;
if (parent.name == "Function")
parent = null;
}
if (!parent)
throw new Error("super not found");
var method = parent.prototype[name];
if (!method)
throw new Error("super function with name '" + name + "' not found");
return function () {
return method.apply(self, arguments);
};
};
result = function (name) {
if (!name || (typeof name != "string"))
throw new Error("super function 'name' is required");
var method = bind(name);
return method.apply(self, Array.prototype.splice.call(arguments, 1));
};
result.bind = bind;
}
return result;
}
});
}
};
Object.extend = function (o, data, replace) {
var override = false;
var parent = replace ? o.$parent : null;
if (!parent && !replace) {
parent = new Object();
parent["$$"] = new Object();
}
for (property in data) {
if (!replace && typeof o[property] == "function") {
parent["$$"][property] = o[property];
(function (property) {
parent[property] = function () {
var context = this["$$"].context;
if (!context)
throw new Error("Context not found in \"" + arguments.callee.caller.name + "\".");
return this["$$"][property].apply(context, arguments);
};
})(property);
o[property] = data[property];
override = true;
}
else if (typeof o[property] == "object")
Object.extend(o[property], data[property], replace);
else
o[property] = data[property];
}
if (override && !replace) {
if (!o.hasOwnProperty("super")) {
Object.defineProperty(o, "super", {
get: function () {
var result;
var caller = arguments.callee.caller;
if (!caller)
throw "\"super\" not applicable for root";
var lvl = caller.lvl;
if (lvl > 0) {
var result = this.$parent;
while (result["$$"].lvl > lvl - 1)
result = result.$parent;
}
else
result = this.$parent;
result["$$"].context = this;
return result;
}
});
}
if (o.$parent) {
parent.$parent = o.$parent;
parent["$$"].lvl = o.$parent["$$"].lvl + 1;
for (property in parent.$parent) {
if (typeof parent.$parent[property] == "function" && typeof parent[property] == "undefined") {
(function (property) {
parent[property] = function () {
if (!this.$parent["$$"].context)
this.$parent["$$"].context = this["$$"].context;
return this.$parent[property].apply(this.$parent, arguments);
};
})(property);
}
}
}
else
parent["$$"].lvl = 1;
for (property in parent["$$"]) {
if (typeof parent["$$"][property] == "function")
parent["$$"][property].lvl = parent["$$"].lvl;
}
o.$parent = parent;
}
};
Object.equals = function (x, y) {
// if both x and y are null or undefined and exactly the same
if (x === y)
return true;
// if they are not strictly equal, they both need to be Objects
if (!(x instanceof Object && y instanceof Object))
return false;
// they must have the exact same prototype chain, the closest we can do is test there constructor.
if (x.constructor !== y.constructor)
return false;
for (var p in x) {
// other properties were tested using x.constructor === y.constructor
if (!x.hasOwnProperty(p))
continue;
// allows to compare x[p] and y[p] when set to undefined
if (!y.hasOwnProperty(p))
return false;
// if they have the same strict value or identity then they are equal
if (x[p] === y[p])
continue;
// Numbers, Strings, Functions, Booleans must be strictly equal
if (typeof (x[p]) !== "object")
return false;
// Objects and Arrays must be tested recursively
if (!Object.equals(x[p], y[p]))
return false;
}
for (p in y) {
// allows x[p] to be set to undefined
if (y.hasOwnProperty(p) && !x.hasOwnProperty(p))
return false;
}
return true;
};
Object.clone = function (oReferance, bDataOnly) {
var aReferances = new Array();
function deepCopy(oSource) {
if (oSource === null)
return null;
if (typeof (oSource) !== "object" || oSource.mutable)
return oSource;
if (typeof oSource.clone === "function")
return oSource.clone();
for (var i = 0; i < aReferances.length; i++) {
if (aReferances[i][0] === oSource)
return aReferances[i][1];
}
var oCopy = Object.create(Object.getPrototypeOf(oSource));
aReferances.push([oSource, oCopy]);
for (sPropertyName in oSource) {
if (bDataOnly && typeof oSource[sPropertyName] === "function")
continue;
if (oSource.hasOwnProperty(sPropertyName))
oCopy[sPropertyName] = deepCopy(oSource[sPropertyName]);
}
return oCopy;
}
return deepCopy(oReferance);
};
Object.nameAnonymousFunctions = function (o, constructorName) {
for (var name in o) {
if (typeof o[name] == "function" && !o[name].name) {
if (name == "constructor" && constructorName)
Object.defineProperty(o[name], "name", { value: constructorName });
else
Object.defineProperty(o[name], "name", { value: name });
}
}
};
JSON.toBase64 = function (json) {
return btoa(JSON.stringify(json));
};
JSON.fromBase64 = function (base64) {
return JSON.parse(atob(base64));
};
JSON.encode = function (json) {
var base64 = JSON.toBase64(json);
return base64.toCharArray(true);
};
JSON.decode = function (bytes) {
var base64 = String.fromCharArray(bytes);
return JSON.fromBase64(base64);
};
Math.toDegrees = function (angle) { return angle * (180 / this.PI); };
Math.toRadians = function (angle) { return angle * (this.PI / 180); };
Math.randomInt = function (min, max) { return Math.floor(this.random() * (max - min + 1)) + min; };
var ENVIRONMENT = (function () {
var WEB = typeof window === "object";
var WORKER = typeof importScripts === "function";
var NODE = typeof process === "object" && typeof require === "function" && !WEB && !WORKER;
Function.prototype.createEnum.call(this, "EnvironmentType", ["WEB", "WORKER", "NODE", "SHELL"]);
if (WEB)
return EnvironmentType.WEB;
else if (WORKER)
return EnvironmentType.WORKER;
else if (NODE)
return EnvironmentType.NODE;
else
return this.EnvironmentType.SHELL;
})();
if (ENVIRONMENT == EnvironmentType.WEB) {
HTMLElement.prototype.getInlineStyle = function (property) {
return this.style[property] || this.style["-webkit-" + property] || this.style["-khtml-" + property] || this.style["-moz-" + property] || this.style["-ms-" + property] || this.style["-o-" + property] || "";
};
HTMLElement.prototype.setStyle = function (property, value) {
var prefixList = ["-webkit", "-khtml", "-moz", "-ms", "-o"];
prefixList.forEach(function (prefix) {
this.style[prefix + "-" + property] = value;
}, this);
this.style[property] = value;
};
HTMLElement.prototype.getStyle = function (property) {
var value = property;
var vendorPrefixed = property.startsWith("-");
if (vendorPrefixed)
value = property.substring(1);
var arr = value.split("-");
for (var i = arr.length - 1; i > 0; i--)
arr[i] = arr[i].substring(0, 1).toUpperCase() + arr[i].substring(1);
value = arr.join("");
// Firefox else IE
var result = window.getComputedStyle ? document.defaultView.getComputedStyle(this, null)[value] : this.currentStyle[value];
if (!vendorPrefixed && typeof result === "undefined") {
var prefixList = ["-webkit", "-khtml", "-moz", "-ms", "-o"];
for (var i = 0; i < prefixList.length; i++) {
result = this.getStyle(prefixList[i] + "-" + property);
if (result != "undefined")
break;
}
}
return result;
};
HTMLElement.prototype.getMathStyle = function (property, inline) {
var value = inline ? this.getInlineStyle(property) : this.getStyle(property);
if (value == "auto")
value = 0;
return parseFloat(value);
};
HTMLElement.prototype.getTransformStyle = function () {
var result = {
translate: { x: 0, y: 0 },
scale: { x: 1, y: 1 },
rotate: { angle: 0 },
skew: { angleX: 0, angleY: 0 },
matrix: { a: 1, b: 0, c: 0, d: 1, tx: 0, ty: 0 }
};
var transform = this.getStyle("transform");
if (transform != "none") {
var values = transform.substring(transform.indexOf("(") + 1, transform.indexOf(")")).split(/,\s*/g);
var a = parseFloat(values[0]);
var b = parseFloat(values[1]);
var c = parseFloat(values[2]);
var d = parseFloat(values[3]);
var tx = parseFloat(values[4]);
var ty = parseFloat(values[5]);
result.scale = { x: Math.sqrt(a * a + c * c), y: Math.sqrt(d * d + b * b) };
result.skew = { angleX: Math.tan(c), angleY: Math.tan(b) };
result.rotate = { angle: Math.atan2(b, a) };
result.translate = { x: tx, y: ty };
result.matrix = { a: a, b: b, c: c, d: d, tx: tx, ty: ty };
}
return result;
};
/**
* type xy location possible values: TL, BR, TR, BL, default is TL
*/
HTMLElement.prototype.toRect = function (type) {
var rect = new Object();
var alpha = this.getTransformStyle().rotate.angle;
var clientRect = this.getBoundingClientRect();
rect.width = this.offsetWidth;
rect.height = this.offsetHeight;
rect.left = this.offsetLeft;
rect.top = this.offsetTop;
rect.right = rect.left + rect.width;
rect.bottom = rect.top + rect.height;
rect.scaleFactor = Math.max(rect.width, rect.height) / Math.min(rect.width, rect.height);
rect.offsetWidth = this.offsetWidth;
rect.offsetHeight = this.offsetHeight;
rect.fullWidth = this.offsetWidth + this.getMathStyle("margin-left") + this.getMathStyle("margin-right");
rect.fullHeight = this.offsetHeight + this.getMathStyle("margin-top") + this.getMathStyle("margin-bottom");
rect.center = { x: rect.width / 2, y: rect.height / 2 };
// rect.rotationFrameWidth = rect.width*Math.abs(Math.cos(alpha)) + rect.height*Math.abs(Math.sin(alpha));
// rect.rotationFrameHeight = rect.height*Math.abs(Math.sin(alpha)) + rect.height*Math.abs(Math.cos(alpha));
// rect.rotationCenter = {x: rect.rotationFrameWidth/2, y: rect.rotationFrameHeight / 2};
rect.rotationFrameWidth = clientRect.width;
rect.rotationFrameHeight = clientRect.height;
rect.rotationCenter = { x: clientRect.width / 2, y: clientRect.height / 2 };
Object.defineProperty(rect, "x", { get: function () { return this.left; } });
Object.defineProperty(rect, "y", { get: function () { return this.top; } });
rect.centerOnParent = { x: rect.left + rect.rotationCenter.x, y: rect.top + rect.rotationCenter.y };
rect.centerOnScreen = { x: clientRect.left + rect.rotationCenter.x, y: clientRect.top + rect.rotationCenter.y };
return rect;
};
HTMLImageElement.prototype.toDataURL = function (type) {
var canvas = document.createElement("canvas");
canvas.width = this.width;
canvas.height = this.height;
canvas.getContext("2d").drawImage(this, 0, 0);
return canvas.toDataURL(type || "image/png");
};
HTMLImageElement.prototype.toBlob = function (type) {
return new Blob([this.getBytes(type).buffer], { type: type || "image/png" });
};
HTMLImageElement.prototype.getBytes = function (type) {
var dataURL = this.toDataURL(type);
var base64 = dataURL.split(",")[1];
// var mime = dataURL.split(",")[0].split(":")[1].split(";")[0];
return atob(base64).toCharArray(true);
};
Image.fromBytes = function (bytes, callback, type) {
var image = new Image();
image.onload = function () {
URL.revokeObjectURL(this.src);
if (callback)
callback.call(this);
};
image.src = URL.createObjectURL(new Blob([bytes.buffer], { type: "image/" + (type || "png") }));
return image;
};
CanvasRenderingContext2D.prototype.clearCanvas = function (color) {
this.clearRect(0, 0, this.canvas.width, this.canvas.height);
if (color) {
this.fillStyle = color;
this.fillRect(0, 0, this.canvas.width, this.canvas.height);
}
};
Object.defineProperty(Screen.prototype, "deviceWidth", { get: function () {
if (window.orientation == 90 || window.orientation == -90) {
if (this.orientation)
delete this.orientation;
else {
this.orientation = true;
return this.deviceHeight;
}
}
var width = this.width;
if (!window.matchMedia("(-webkit-device-pixel-ratio)").matches) {
width = Math.ceil(width * window.devicePixelRatio);
if (width % 10 != 0) {
if (width % 10 > 5)
width += (10 - width % 10);
else
width -= width % 10;
}
}
return width;
} });
Object.defineProperty(Screen.prototype, "deviceHeight", { get: function () {
if (window.orientation == 90 || window.orientation == -90) {
if (this.orientation)
delete this.orientation;
else {
this.orientation = true;
return this.deviceWidth;
}
}
var height = this.height;
if (!window.matchMedia("(-webkit-device-pixel-ratio)").matches) {
height = Math.ceil(height * window.devicePixelRatio);
if (height % 10 != 0) {
if (height % 10 > 5)
height += (10 - height % 10);
else
height -= height % 10;
}
}
return height;
} });
// Safari FIX
(function () {
try {
var clientRect = document.createElement("div").getBoundingClientRect();
if (!("x" in clientRect)) {
Object.extend(HTMLElement.prototype, {
getBoundingClientRect: function () {
var clientRect = this.super.getBoundingClientRect();
clientRect.x = clientRect.left;
clientRect.y = clientRect.top;
return clientRect;
}
});
}
}
catch (e) {
// IE throws exception
}
})();
}