zui
Version:
一个基于 Bootstrap 深度定制开源前端实践方案,帮助你快速构建现代跨屏应用。
1,766 lines (1,458 loc) • 299 kB
JavaScript
;var MXI_DEBUG = true;
/**
* mOxie - multi-runtime File API & XMLHttpRequest L2 Polyfill
* v1.5.7
*
* Copyright 2013, Moxiecode Systems AB
* Released under GPL License.
*
* License: http://www.plupload.com/license
* Contributing: http://www.plupload.com/contributing
*
* Date: 2017-11-03
*/
;(function (global, factory) {
var extract = function() {
var ctx = {};
factory.apply(ctx, arguments);
return ctx.moxie;
};
if (typeof define === "function" && define.amd) {
define("moxie", [], extract);
} else if (typeof module === "object" && module.exports) {
module.exports = extract();
} else {
global.moxie = extract();
}
}(this || window, function() {
/**
* Compiled inline version. (Library mode)
*/
/*jshint smarttabs:true, undef:true, latedef:true, curly:true, bitwise:true, camelcase:true */
/*globals $code */
(function(exports, undefined) {
"use strict";
var modules = {};
function require(ids, callback) {
var module, defs = [];
for (var i = 0; i < ids.length; ++i) {
module = modules[ids[i]] || resolve(ids[i]);
if (!module) {
throw 'module definition dependecy not found: ' + ids[i];
}
defs.push(module);
}
callback.apply(null, defs);
}
function define(id, dependencies, definition) {
if (typeof id !== 'string') {
throw 'invalid module definition, module id must be defined and be a string';
}
if (dependencies === undefined) {
throw 'invalid module definition, dependencies must be specified';
}
if (definition === undefined) {
throw 'invalid module definition, definition function must be specified';
}
require(dependencies, function() {
modules[id] = definition.apply(null, arguments);
});
}
function defined(id) {
return !!modules[id];
}
function resolve(id) {
var target = exports;
var fragments = id.split(/[.\/]/);
for (var fi = 0; fi < fragments.length; ++fi) {
if (!target[fragments[fi]]) {
return;
}
target = target[fragments[fi]];
}
return target;
}
function expose(ids) {
for (var i = 0; i < ids.length; i++) {
var target = exports;
var id = ids[i];
var fragments = id.split(/[.\/]/);
for (var fi = 0; fi < fragments.length - 1; ++fi) {
if (target[fragments[fi]] === undefined) {
target[fragments[fi]] = {};
}
target = target[fragments[fi]];
}
target[fragments[fragments.length - 1]] = modules[id];
}
}
// Included from: src/javascript/core/utils/Basic.js
/**
* Basic.js
*
* Copyright 2013, Moxiecode Systems AB
* Released under GPL License.
*
* License: http://www.plupload.com/license
* Contributing: http://www.plupload.com/contributing
*/
/**
@class moxie/core/utils/Basic
@public
@static
*/
define('moxie/core/utils/Basic', [], function() {
/**
Gets the true type of the built-in object (better version of typeof).
@author Angus Croll (http://javascriptweblog.wordpress.com/)
@method typeOf
@static
@param {Object} o Object to check.
@return {String} Object [[Class]]
*/
function typeOf(o) {
var undef;
if (o === undef) {
return 'undefined';
} else if (o === null) {
return 'null';
} else if (o.nodeType) {
return 'node';
}
// the snippet below is awesome, however it fails to detect null, undefined and arguments types in IE lte 8
return ({}).toString.call(o).match(/\s([a-z|A-Z]+)/)[1].toLowerCase();
}
/**
Extends the specified object with another object(s).
@method extend
@static
@param {Object} target Object to extend.
@param {Object} [obj]* Multiple objects to extend with.
@return {Object} Same as target, the extended object.
*/
function extend() {
return merge(false, false, arguments);
}
/**
Extends the specified object with another object(s), but only if the property exists in the target.
@method extendIf
@static
@param {Object} target Object to extend.
@param {Object} [obj]* Multiple objects to extend with.
@return {Object} Same as target, the extended object.
*/
function extendIf() {
return merge(true, false, arguments);
}
function extendImmutable() {
return merge(false, true, arguments);
}
function extendImmutableIf() {
return merge(true, true, arguments);
}
function clone(value) {
switch (typeOf(value)) {
case 'array':
return merge(false, true, [[], value]);
case 'object':
return merge(false, true, [{}, value]);
default:
return value;
}
}
function shallowCopy(obj) {
switch (typeOf(obj)) {
case 'array':
return Array.prototype.slice.call(obj);
case 'object':
return extend({}, obj);
}
return obj;
}
function merge(strict, immutable, args) {
var undef;
var target = args[0];
each(args, function(arg, i) {
if (i > 0) {
each(arg, function(value, key) {
var isComplex = inArray(typeOf(value), ['array', 'object']) !== -1;
if (value === undef || strict && target[key] === undef) {
return true;
}
if (isComplex && immutable) {
value = shallowCopy(value);
}
if (typeOf(target[key]) === typeOf(value) && isComplex) {
merge(strict, immutable, [target[key], value]);
} else {
target[key] = value;
}
});
}
});
return target;
}
/**
A way to inherit one `class` from another in a consisstent way (more or less)
@method inherit
@static
@since >1.4.1
@param {Function} child
@param {Function} parent
@return {Function} Prepared constructor
*/
function inherit(child, parent) {
// copy over all parent properties
for (var key in parent) {
if ({}.hasOwnProperty.call(parent, key)) {
child[key] = parent[key];
}
}
// give child `class` a place to define its own methods
function ctor() {
this.constructor = child;
if (MXI_DEBUG) {
var getCtorName = function(fn) {
var m = fn.toString().match(/^function\s([^\(\s]+)/);
return m ? m[1] : false;
};
this.ctorName = getCtorName(child);
}
}
ctor.prototype = parent.prototype;
child.prototype = new ctor();
// keep a way to reference parent methods
child.parent = parent.prototype;
return child;
}
/**
Executes the callback function for each item in array/object. If you return false in the
callback it will break the loop.
@method each
@static
@param {Object} obj Object to iterate.
@param {function} callback Callback function to execute for each item.
*/
function each(obj, callback) {
var length, key, i, undef;
if (obj) {
try {
length = obj.length;
} catch(ex) {
length = undef;
}
if (length === undef || typeof(length) !== 'number') {
// Loop object items
for (key in obj) {
if (obj.hasOwnProperty(key)) {
if (callback(obj[key], key) === false) {
return;
}
}
}
} else {
// Loop array items
for (i = 0; i < length; i++) {
if (callback(obj[i], i) === false) {
return;
}
}
}
}
}
/**
Checks if object is empty.
@method isEmptyObj
@static
@param {Object} o Object to check.
@return {Boolean}
*/
function isEmptyObj(obj) {
var prop;
if (!obj || typeOf(obj) !== 'object') {
return true;
}
for (prop in obj) {
return false;
}
return true;
}
/**
Recieve an array of functions (usually async) to call in sequence, each function
receives a callback as first argument that it should call, when it completes. Finally,
after everything is complete, main callback is called. Passing truthy value to the
callback as a first argument will interrupt the sequence and invoke main callback
immediately.
@method inSeries
@static
@param {Array} queue Array of functions to call in sequence
@param {Function} cb Main callback that is called in the end, or in case of error
*/
function inSeries(queue, cb) {
var i = 0, length = queue.length;
if (typeOf(cb) !== 'function') {
cb = function() {};
}
if (!queue || !queue.length) {
cb();
}
function callNext(i) {
if (typeOf(queue[i]) === 'function') {
queue[i](function(error) {
/*jshint expr:true */
++i < length && !error ? callNext(i) : cb(error);
});
}
}
callNext(i);
}
/**
Recieve an array of functions (usually async) to call in parallel, each function
receives a callback as first argument that it should call, when it completes. After
everything is complete, main callback is called. Passing truthy value to the
callback as a first argument will interrupt the process and invoke main callback
immediately.
@method inParallel
@static
@param {Array} queue Array of functions to call in sequence
@param {Function} cb Main callback that is called in the end, or in case of erro
*/
function inParallel(queue, cb) {
var count = 0, num = queue.length, cbArgs = new Array(num);
each(queue, function(fn, i) {
fn(function(error) {
if (error) {
return cb(error);
}
var args = [].slice.call(arguments);
args.shift(); // strip error - undefined or not
cbArgs[i] = args;
count++;
if (count === num) {
cbArgs.unshift(null);
cb.apply(this, cbArgs);
}
});
});
}
/**
Find an element in array and return it's index if present, otherwise return -1.
@method inArray
@static
@param {Mixed} needle Element to find
@param {Array} array
@return {Int} Index of the element, or -1 if not found
*/
function inArray(needle, array) {
if (array) {
if (Array.prototype.indexOf) {
return Array.prototype.indexOf.call(array, needle);
}
for (var i = 0, length = array.length; i < length; i++) {
if (array[i] === needle) {
return i;
}
}
}
return -1;
}
/**
Returns elements of first array if they are not present in second. And false - otherwise.
@private
@method arrayDiff
@param {Array} needles
@param {Array} array
@return {Array|Boolean}
*/
function arrayDiff(needles, array) {
var diff = [];
if (typeOf(needles) !== 'array') {
needles = [needles];
}
if (typeOf(array) !== 'array') {
array = [array];
}
for (var i in needles) {
if (inArray(needles[i], array) === -1) {
diff.push(needles[i]);
}
}
return diff.length ? diff : false;
}
/**
Find intersection of two arrays.
@private
@method arrayIntersect
@param {Array} array1
@param {Array} array2
@return {Array} Intersection of two arrays or null if there is none
*/
function arrayIntersect(array1, array2) {
var result = [];
each(array1, function(item) {
if (inArray(item, array2) !== -1) {
result.push(item);
}
});
return result.length ? result : null;
}
/**
Forces anything into an array.
@method toArray
@static
@param {Object} obj Object with length field.
@return {Array} Array object containing all items.
*/
function toArray(obj) {
var i, arr = [];
for (i = 0; i < obj.length; i++) {
arr[i] = obj[i];
}
return arr;
}
/**
Generates an unique ID. The only way a user would be able to get the same ID is if the two persons
at the same exact millisecond manage to get the same 5 random numbers between 0-65535; it also uses
a counter so each ID is guaranteed to be unique for the given page. It is more probable for the earth
to be hit with an asteroid.
@method guid
@static
@param {String} prefix to prepend (by default 'o' will be prepended).
@method guid
@return {String} Virtually unique id.
*/
var guid = (function() {
var counter = 0;
return function(prefix) {
var guid = new Date().getTime().toString(32), i;
for (i = 0; i < 5; i++) {
guid += Math.floor(Math.random() * 65535).toString(32);
}
return (prefix || 'o_') + guid + (counter++).toString(32);
};
}());
/**
Trims white spaces around the string
@method trim
@static
@param {String} str
@return {String}
*/
function trim(str) {
if (!str) {
return str;
}
return String.prototype.trim ? String.prototype.trim.call(str) : str.toString().replace(/^\s*/, '').replace(/\s*$/, '');
}
/**
Parses the specified size string into a byte value. For example 10kb becomes 10240.
@method parseSizeStr
@static
@param {String/Number} size String to parse or number to just pass through.
@return {Number} Size in bytes.
*/
function parseSizeStr(size) {
if (typeof(size) !== 'string') {
return size;
}
var muls = {
t: 1099511627776,
g: 1073741824,
m: 1048576,
k: 1024
},
mul;
size = /^([0-9\.]+)([tmgk]?)$/.exec(size.toLowerCase().replace(/[^0-9\.tmkg]/g, ''));
mul = size[2];
size = +size[1];
if (muls.hasOwnProperty(mul)) {
size *= muls[mul];
}
return Math.floor(size);
}
/**
* Pseudo sprintf implementation - simple way to replace tokens with specified values.
*
* @param {String} str String with tokens
* @return {String} String with replaced tokens
*/
function sprintf(str) {
var args = [].slice.call(arguments, 1);
return str.replace(/%([a-z])/g, function($0, $1) {
var value = args.shift();
switch ($1) {
case 's':
return value + '';
case 'd':
return parseInt(value, 10);
case 'f':
return parseFloat(value);
case 'c':
return '';
default:
return value;
}
});
}
function delay(cb, timeout) {
var self = this;
setTimeout(function() {
cb.call(self);
}, timeout || 1);
}
return {
guid: guid,
typeOf: typeOf,
extend: extend,
extendIf: extendIf,
extendImmutable: extendImmutable,
extendImmutableIf: extendImmutableIf,
clone: clone,
inherit: inherit,
each: each,
isEmptyObj: isEmptyObj,
inSeries: inSeries,
inParallel: inParallel,
inArray: inArray,
arrayDiff: arrayDiff,
arrayIntersect: arrayIntersect,
toArray: toArray,
trim: trim,
sprintf: sprintf,
parseSizeStr: parseSizeStr,
delay: delay
};
});
// Included from: src/javascript/core/utils/Encode.js
/**
* Encode.js
*
* Copyright 2013, Moxiecode Systems AB
* Released under GPL License.
*
* License: http://www.plupload.com/license
* Contributing: http://www.plupload.com/contributing
*/
/**
@class moxie/core/utils/Encode
@public
@static
*/
define('moxie/core/utils/Encode', [], function() {
/**
Encode string with UTF-8
@method utf8_encode
@static
@param {String} str String to encode
@return {String} UTF-8 encoded string
*/
var utf8_encode = function(str) {
return unescape(encodeURIComponent(str));
};
/**
Decode UTF-8 encoded string
@method utf8_decode
@static
@param {String} str String to decode
@return {String} Decoded string
*/
var utf8_decode = function(str_data) {
return decodeURIComponent(escape(str_data));
};
/**
Decode Base64 encoded string (uses browser's default method if available),
from: https://raw.github.com/kvz/phpjs/master/functions/url/base64_decode.js
@method atob
@static
@param {String} data String to decode
@return {String} Decoded string
*/
var atob = function(data, utf8) {
if (typeof(window.atob) === 'function') {
return utf8 ? utf8_decode(window.atob(data)) : window.atob(data);
}
// http://kevin.vanzonneveld.net
// + original by: Tyler Akins (http://rumkin.com)
// + improved by: Thunder.m
// + input by: Aman Gupta
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + bugfixed by: Onno Marsman
// + bugfixed by: Pellentesque Malesuada
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + input by: Brett Zamir (http://brett-zamir.me)
// + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// * example 1: base64_decode('S2V2aW4gdmFuIFpvbm5ldmVsZA==');
// * returns 1: 'Kevin van Zonneveld'
// mozilla has this native
// - but breaks in 2.0.0.12!
//if (typeof this.window.atob == 'function') {
// return atob(data);
//}
var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var o1, o2, o3, h1, h2, h3, h4, bits, i = 0,
ac = 0,
dec = "",
tmp_arr = [];
if (!data) {
return data;
}
data += '';
do { // unpack four hexets into three octets using index points in b64
h1 = b64.indexOf(data.charAt(i++));
h2 = b64.indexOf(data.charAt(i++));
h3 = b64.indexOf(data.charAt(i++));
h4 = b64.indexOf(data.charAt(i++));
bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
o1 = bits >> 16 & 0xff;
o2 = bits >> 8 & 0xff;
o3 = bits & 0xff;
if (h3 == 64) {
tmp_arr[ac++] = String.fromCharCode(o1);
} else if (h4 == 64) {
tmp_arr[ac++] = String.fromCharCode(o1, o2);
} else {
tmp_arr[ac++] = String.fromCharCode(o1, o2, o3);
}
} while (i < data.length);
dec = tmp_arr.join('');
return utf8 ? utf8_decode(dec) : dec;
};
/**
Base64 encode string (uses browser's default method if available),
from: https://raw.github.com/kvz/phpjs/master/functions/url/base64_encode.js
@method btoa
@static
@param {String} data String to encode
@return {String} Base64 encoded string
*/
var btoa = function(data, utf8) {
if (utf8) {
data = utf8_encode(data);
}
if (typeof(window.btoa) === 'function') {
return window.btoa(data);
}
// http://kevin.vanzonneveld.net
// + original by: Tyler Akins (http://rumkin.com)
// + improved by: Bayron Guevara
// + improved by: Thunder.m
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + bugfixed by: Pellentesque Malesuada
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
// + improved by: Rafał Kukawski (http://kukawski.pl)
// * example 1: base64_encode('Kevin van Zonneveld');
// * returns 1: 'S2V2aW4gdmFuIFpvbm5ldmVsZA=='
// mozilla has this native
// - but breaks in 2.0.0.12!
var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var o1, o2, o3, h1, h2, h3, h4, bits, i = 0,
ac = 0,
enc = "",
tmp_arr = [];
if (!data) {
return data;
}
do { // pack three octets into four hexets
o1 = data.charCodeAt(i++);
o2 = data.charCodeAt(i++);
o3 = data.charCodeAt(i++);
bits = o1 << 16 | o2 << 8 | o3;
h1 = bits >> 18 & 0x3f;
h2 = bits >> 12 & 0x3f;
h3 = bits >> 6 & 0x3f;
h4 = bits & 0x3f;
// use hexets to index into b64, and append result to encoded string
tmp_arr[ac++] = b64.charAt(h1) + b64.charAt(h2) + b64.charAt(h3) + b64.charAt(h4);
} while (i < data.length);
enc = tmp_arr.join('');
var r = data.length % 3;
return (r ? enc.slice(0, r - 3) : enc) + '==='.slice(r || 3);
};
return {
utf8_encode: utf8_encode,
utf8_decode: utf8_decode,
atob: atob,
btoa: btoa
};
});
// Included from: src/javascript/core/utils/Env.js
/**
* Env.js
*
* Copyright 2013, Moxiecode Systems AB
* Released under GPL License.
*
* License: http://www.plupload.com/license
* Contributing: http://www.plupload.com/contributing
*/
/**
@class moxie/core/utils/Env
@public
@static
*/
define("moxie/core/utils/Env", [
"moxie/core/utils/Basic"
], function(Basic) {
/**
* UAParser.js v0.7.7
* Lightweight JavaScript-based User-Agent string parser
* https://github.com/faisalman/ua-parser-js
*
* Copyright © 2012-2015 Faisal Salman <fyzlman@gmail.com>
* Dual licensed under GPLv2 & MIT
*/
var UAParser = (function (undefined) {
//////////////
// Constants
/////////////
var EMPTY = '',
UNKNOWN = '?',
FUNC_TYPE = 'function',
UNDEF_TYPE = 'undefined',
OBJ_TYPE = 'object',
MAJOR = 'major',
MODEL = 'model',
NAME = 'name',
TYPE = 'type',
VENDOR = 'vendor',
VERSION = 'version',
ARCHITECTURE= 'architecture',
CONSOLE = 'console',
MOBILE = 'mobile',
TABLET = 'tablet';
///////////
// Helper
//////////
var util = {
has : function (str1, str2) {
return str2.toLowerCase().indexOf(str1.toLowerCase()) !== -1;
},
lowerize : function (str) {
return str.toLowerCase();
}
};
///////////////
// Map helper
//////////////
var mapper = {
rgx : function () {
// loop through all regexes maps
for (var result, i = 0, j, k, p, q, matches, match, args = arguments; i < args.length; i += 2) {
var regex = args[i], // even sequence (0,2,4,..)
props = args[i + 1]; // odd sequence (1,3,5,..)
// construct object barebones
if (typeof(result) === UNDEF_TYPE) {
result = {};
for (p in props) {
q = props[p];
if (typeof(q) === OBJ_TYPE) {
result[q[0]] = undefined;
} else {
result[q] = undefined;
}
}
}
// try matching uastring with regexes
for (j = k = 0; j < regex.length; j++) {
matches = regex[j].exec(this.getUA());
if (!!matches) {
for (p = 0; p < props.length; p++) {
match = matches[++k];
q = props[p];
// check if given property is actually array
if (typeof(q) === OBJ_TYPE && q.length > 0) {
if (q.length == 2) {
if (typeof(q[1]) == FUNC_TYPE) {
// assign modified match
result[q[0]] = q[1].call(this, match);
} else {
// assign given value, ignore regex match
result[q[0]] = q[1];
}
} else if (q.length == 3) {
// check whether function or regex
if (typeof(q[1]) === FUNC_TYPE && !(q[1].exec && q[1].test)) {
// call function (usually string mapper)
result[q[0]] = match ? q[1].call(this, match, q[2]) : undefined;
} else {
// sanitize match using given regex
result[q[0]] = match ? match.replace(q[1], q[2]) : undefined;
}
} else if (q.length == 4) {
result[q[0]] = match ? q[3].call(this, match.replace(q[1], q[2])) : undefined;
}
} else {
result[q] = match ? match : undefined;
}
}
break;
}
}
if(!!matches) break; // break the loop immediately if match found
}
return result;
},
str : function (str, map) {
for (var i in map) {
// check if array
if (typeof(map[i]) === OBJ_TYPE && map[i].length > 0) {
for (var j = 0; j < map[i].length; j++) {
if (util.has(map[i][j], str)) {
return (i === UNKNOWN) ? undefined : i;
}
}
} else if (util.has(map[i], str)) {
return (i === UNKNOWN) ? undefined : i;
}
}
return str;
}
};
///////////////
// String map
//////////////
var maps = {
browser : {
oldsafari : {
major : {
'1' : ['/8', '/1', '/3'],
'2' : '/4',
'?' : '/'
},
version : {
'1.0' : '/8',
'1.2' : '/1',
'1.3' : '/3',
'2.0' : '/412',
'2.0.2' : '/416',
'2.0.3' : '/417',
'2.0.4' : '/419',
'?' : '/'
}
}
},
device : {
sprint : {
model : {
'Evo Shift 4G' : '7373KT'
},
vendor : {
'HTC' : 'APA',
'Sprint' : 'Sprint'
}
}
},
os : {
windows : {
version : {
'ME' : '4.90',
'NT 3.11' : 'NT3.51',
'NT 4.0' : 'NT4.0',
'2000' : 'NT 5.0',
'XP' : ['NT 5.1', 'NT 5.2'],
'Vista' : 'NT 6.0',
'7' : 'NT 6.1',
'8' : 'NT 6.2',
'8.1' : 'NT 6.3',
'RT' : 'ARM'
}
}
}
};
//////////////
// Regex map
/////////////
var regexes = {
browser : [[
// Presto based
/(opera\smini)\/([\w\.-]+)/i, // Opera Mini
/(opera\s[mobiletab]+).+version\/([\w\.-]+)/i, // Opera Mobi/Tablet
/(opera).+version\/([\w\.]+)/i, // Opera > 9.80
/(opera)[\/\s]+([\w\.]+)/i // Opera < 9.80
], [NAME, VERSION], [
/\s(opr)\/([\w\.]+)/i // Opera Webkit
], [[NAME, 'Opera'], VERSION], [
// Mixed
/(kindle)\/([\w\.]+)/i, // Kindle
/(lunascape|maxthon|netfront|jasmine|blazer)[\/\s]?([\w\.]+)*/i,
// Lunascape/Maxthon/Netfront/Jasmine/Blazer
// Trident based
/(avant\s|iemobile|slim|baidu)(?:browser)?[\/\s]?([\w\.]*)/i,
// Avant/IEMobile/SlimBrowser/Baidu
/(?:ms|\()(ie)\s([\w\.]+)/i, // Internet Explorer
// Webkit/KHTML based
/(rekonq)\/([\w\.]+)*/i, // Rekonq
/(chromium|flock|rockmelt|midori|epiphany|silk|skyfire|ovibrowser|bolt|iron|vivaldi)\/([\w\.-]+)/i
// Chromium/Flock/RockMelt/Midori/Epiphany/Silk/Skyfire/Bolt/Iron
], [NAME, VERSION], [
/(trident).+rv[:\s]([\w\.]+).+like\sgecko/i // IE11
], [[NAME, 'IE'], VERSION], [
/(edge)\/((\d+)?[\w\.]+)/i // Microsoft Edge
], [NAME, VERSION], [
/(yabrowser)\/([\w\.]+)/i // Yandex
], [[NAME, 'Yandex'], VERSION], [
/(comodo_dragon)\/([\w\.]+)/i // Comodo Dragon
], [[NAME, /_/g, ' '], VERSION], [
/(chrome|omniweb|arora|[tizenoka]{5}\s?browser)\/v?([\w\.]+)/i,
// Chrome/OmniWeb/Arora/Tizen/Nokia
/(uc\s?browser|qqbrowser)[\/\s]?([\w\.]+)/i
// UCBrowser/QQBrowser
], [NAME, VERSION], [
/(dolfin)\/([\w\.]+)/i // Dolphin
], [[NAME, 'Dolphin'], VERSION], [
/((?:android.+)crmo|crios)\/([\w\.]+)/i // Chrome for Android/iOS
], [[NAME, 'Chrome'], VERSION], [
/XiaoMi\/MiuiBrowser\/([\w\.]+)/i // MIUI Browser
], [VERSION, [NAME, 'MIUI Browser']], [
/android.+version\/([\w\.]+)\s+(?:mobile\s?safari|safari)/i // Android Browser
], [VERSION, [NAME, 'Android Browser']], [
/FBAV\/([\w\.]+);/i // Facebook App for iOS
], [VERSION, [NAME, 'Facebook']], [
/version\/([\w\.]+).+?mobile\/\w+\s(safari)/i // Mobile Safari
], [VERSION, [NAME, 'Mobile Safari']], [
/version\/([\w\.]+).+?(mobile\s?safari|safari)/i // Safari & Safari Mobile
], [VERSION, NAME], [
/webkit.+?(mobile\s?safari|safari)(\/[\w\.]+)/i // Safari < 3.0
], [NAME, [VERSION, mapper.str, maps.browser.oldsafari.version]], [
/(konqueror)\/([\w\.]+)/i, // Konqueror
/(webkit|khtml)\/([\w\.]+)/i
], [NAME, VERSION], [
// Gecko based
/(navigator|netscape)\/([\w\.-]+)/i // Netscape
], [[NAME, 'Netscape'], VERSION], [
/(swiftfox)/i, // Swiftfox
/(icedragon|iceweasel|camino|chimera|fennec|maemo\sbrowser|minimo|conkeror)[\/\s]?([\w\.\+]+)/i,
// IceDragon/Iceweasel/Camino/Chimera/Fennec/Maemo/Minimo/Conkeror
/(firefox|seamonkey|k-meleon|icecat|iceape|firebird|phoenix)\/([\w\.-]+)/i,
// Firefox/SeaMonkey/K-Meleon/IceCat/IceApe/Firebird/Phoenix
/(mozilla)\/([\w\.]+).+rv\:.+gecko\/\d+/i, // Mozilla
// Other
/(polaris|lynx|dillo|icab|doris|amaya|w3m|netsurf)[\/\s]?([\w\.]+)/i,
// Polaris/Lynx/Dillo/iCab/Doris/Amaya/w3m/NetSurf
/(links)\s\(([\w\.]+)/i, // Links
/(gobrowser)\/?([\w\.]+)*/i, // GoBrowser
/(ice\s?browser)\/v?([\w\._]+)/i, // ICE Browser
/(mosaic)[\/\s]([\w\.]+)/i // Mosaic
], [NAME, VERSION]
],
engine : [[
/windows.+\sedge\/([\w\.]+)/i // EdgeHTML
], [VERSION, [NAME, 'EdgeHTML']], [
/(presto)\/([\w\.]+)/i, // Presto
/(webkit|trident|netfront|netsurf|amaya|lynx|w3m)\/([\w\.]+)/i, // WebKit/Trident/NetFront/NetSurf/Amaya/Lynx/w3m
/(khtml|tasman|links)[\/\s]\(?([\w\.]+)/i, // KHTML/Tasman/Links
/(icab)[\/\s]([23]\.[\d\.]+)/i // iCab
], [NAME, VERSION], [
/rv\:([\w\.]+).*(gecko)/i // Gecko
], [VERSION, NAME]
],
os : [[
// Windows based
/microsoft\s(windows)\s(vista|xp)/i // Windows (iTunes)
], [NAME, VERSION], [
/(windows)\snt\s6\.2;\s(arm)/i, // Windows RT
/(windows\sphone(?:\sos)*|windows\smobile|windows)[\s\/]?([ntce\d\.\s]+\w)/i
], [NAME, [VERSION, mapper.str, maps.os.windows.version]], [
/(win(?=3|9|n)|win\s9x\s)([nt\d\.]+)/i
], [[NAME, 'Windows'], [VERSION, mapper.str, maps.os.windows.version]], [
// Mobile/Embedded OS
/\((bb)(10);/i // BlackBerry 10
], [[NAME, 'BlackBerry'], VERSION], [
/(blackberry)\w*\/?([\w\.]+)*/i, // Blackberry
/(tizen)[\/\s]([\w\.]+)/i, // Tizen
/(android|webos|palm\os|qnx|bada|rim\stablet\sos|meego|contiki)[\/\s-]?([\w\.]+)*/i,
// Android/WebOS/Palm/QNX/Bada/RIM/MeeGo/Contiki
/linux;.+(sailfish);/i // Sailfish OS
], [NAME, VERSION], [
/(symbian\s?os|symbos|s60(?=;))[\/\s-]?([\w\.]+)*/i // Symbian
], [[NAME, 'Symbian'], VERSION], [
/\((series40);/i // Series 40
], [NAME], [
/mozilla.+\(mobile;.+gecko.+firefox/i // Firefox OS
], [[NAME, 'Firefox OS'], VERSION], [
// Console
/(nintendo|playstation)\s([wids3portablevu]+)/i, // Nintendo/Playstation
// GNU/Linux based
/(mint)[\/\s\(]?(\w+)*/i, // Mint
/(mageia|vectorlinux)[;\s]/i, // Mageia/VectorLinux
/(joli|[kxln]?ubuntu|debian|[open]*suse|gentoo|arch|slackware|fedora|mandriva|centos|pclinuxos|redhat|zenwalk|linpus)[\/\s-]?([\w\.-]+)*/i,
// Joli/Ubuntu/Debian/SUSE/Gentoo/Arch/Slackware
// Fedora/Mandriva/CentOS/PCLinuxOS/RedHat/Zenwalk/Linpus
/(hurd|linux)\s?([\w\.]+)*/i, // Hurd/Linux
/(gnu)\s?([\w\.]+)*/i // GNU
], [NAME, VERSION], [
/(cros)\s[\w]+\s([\w\.]+\w)/i // Chromium OS
], [[NAME, 'Chromium OS'], VERSION],[
// Solaris
/(sunos)\s?([\w\.]+\d)*/i // Solaris
], [[NAME, 'Solaris'], VERSION], [
// BSD based
/\s([frentopc-]{0,4}bsd|dragonfly)\s?([\w\.]+)*/i // FreeBSD/NetBSD/OpenBSD/PC-BSD/DragonFly
], [NAME, VERSION],[
/(ip[honead]+)(?:.*os\s*([\w]+)*\slike\smac|;\sopera)/i // iOS
], [[NAME, 'iOS'], [VERSION, /_/g, '.']], [
/(mac\sos\sx)\s?([\w\s\.]+\w)*/i,
/(macintosh|mac(?=_powerpc)\s)/i // Mac OS
], [[NAME, 'Mac OS'], [VERSION, /_/g, '.']], [
// Other
/((?:open)?solaris)[\/\s-]?([\w\.]+)*/i, // Solaris
/(haiku)\s(\w+)/i, // Haiku
/(aix)\s((\d)(?=\.|\)|\s)[\w\.]*)*/i, // AIX
/(plan\s9|minix|beos|os\/2|amigaos|morphos|risc\sos|openvms)/i,
// Plan9/Minix/BeOS/OS2/AmigaOS/MorphOS/RISCOS/OpenVMS
/(unix)\s?([\w\.]+)*/i // UNIX
], [NAME, VERSION]
]
};
/////////////////
// Constructor
////////////////
var UAParser = function (uastring) {
var ua = uastring || ((window && window.navigator && window.navigator.userAgent) ? window.navigator.userAgent : EMPTY);
this.getBrowser = function () {
return mapper.rgx.apply(this, regexes.browser);
};
this.getEngine = function () {
return mapper.rgx.apply(this, regexes.engine);
};
this.getOS = function () {
return mapper.rgx.apply(this, regexes.os);
};
this.getResult = function() {
return {
ua : this.getUA(),
browser : this.getBrowser(),
engine : this.getEngine(),
os : this.getOS()
};
};
this.getUA = function () {
return ua;
};
this.setUA = function (uastring) {
ua = uastring;
return this;
};
this.setUA(ua);
};
return UAParser;
})();
function version_compare(v1, v2, operator) {
// From: http://phpjs.org/functions
// + original by: Philippe Jausions (http://pear.php.net/user/jausions)
// + original by: Aidan Lister (http://aidanlister.com/)
// + reimplemented by: Kankrelune (http://www.webfaktory.info/)
// + improved by: Brett Zamir (http://brett-zamir.me)
// + improved by: Scott Baker
// + improved by: Theriault
// * example 1: version_compare('8.2.5rc', '8.2.5a');
// * returns 1: 1
// * example 2: version_compare('8.2.50', '8.2.52', '<');
// * returns 2: true
// * example 3: version_compare('5.3.0-dev', '5.3.0');
// * returns 3: -1
// * example 4: version_compare('4.1.0.52','4.01.0.51');
// * returns 4: 1
// Important: compare must be initialized at 0.
var i = 0,
x = 0,
compare = 0,
// vm maps textual PHP versions to negatives so they're less than 0.
// PHP currently defines these as CASE-SENSITIVE. It is important to
// leave these as negatives so that they can come before numerical versions
// and as if no letters were there to begin with.
// (1alpha is < 1 and < 1.1 but > 1dev1)
// If a non-numerical value can't be mapped to this table, it receives
// -7 as its value.
vm = {
'dev': -6,
'alpha': -5,
'a': -5,
'beta': -4,
'b': -4,
'RC': -3,
'rc': -3,
'#': -2,
'p': 1,
'pl': 1
},
// This function will be called to prepare each version argument.
// It replaces every _, -, and + with a dot.
// It surrounds any nonsequence of numbers/dots with dots.
// It replaces sequences of dots with a single dot.
// version_compare('4..0', '4.0') == 0
// Important: A string of 0 length needs to be converted into a value
// even less than an unexisting value in vm (-7), hence [-8].
// It's also important to not strip spaces because of this.
// version_compare('', ' ') == 1
prepVersion = function (v) {
v = ('' + v).replace(/[_\-+]/g, '.');
v = v.replace(/([^.\d]+)/g, '.$1.').replace(/\.{2,}/g, '.');
return (!v.length ? [-8] : v.split('.'));
},
// This converts a version component to a number.
// Empty component becomes 0.
// Non-numerical component becomes a negative number.
// Numerical component becomes itself as an integer.
numVersion = function (v) {
return !v ? 0 : (isNaN(v) ? vm[v] || -7 : parseInt(v, 10));
};
v1 = prepVersion(v1);
v2 = prepVersion(v2);
x = Math.max(v1.length, v2.length);
for (i = 0; i < x; i++) {
if (v1[i] == v2[i]) {
continue;
}
v1[i] = numVersion(v1[i]);
v2[i] = numVersion(v2[i]);
if (v1[i] < v2[i]) {
compare = -1;
break;
} else if (v1[i] > v2[i]) {
compare = 1;
break;
}
}
if (!operator) {
return compare;
}
// Important: operator is CASE-SENSITIVE.
// "No operator" seems to be treated as "<."
// Any other values seem to make the function return null.
switch (operator) {
case '>':
case 'gt':
return (compare > 0);
case '>=':
case 'ge':
return (compare >= 0);
case '<=':
case 'le':
return (compare <= 0);
case '==':
case '=':
case 'eq':
return (compare === 0);
case '<>':
case '!=':
case 'ne':
return (compare !== 0);
case '':
case '<':
case 'lt':
return (compare < 0);
default:
return null;
}
}
var can = (function() {
var caps = {
access_global_ns: function () {
return !!window.moxie;
},
define_property: (function() {
/* // currently too much extra code required, not exactly worth it
try { // as of IE8, getters/setters are supported only on DOM elements
var obj = {};
if (Object.defineProperty) {
Object.defineProperty(obj, 'prop', {
enumerable: true,
configurable: true
});
return true;
}
} catch(ex) {}
if (Object.prototype.__defineGetter__ && Object.prototype.__defineSetter__) {
return true;
}*/
return false;
}()),
create_canvas: function() {
// On the S60 and BB Storm, getContext exists, but always returns undefined
// so we actually have to call getContext() to verify
// github.com/Modernizr/Modernizr/issues/issue/97/
var el = document.createElement('canvas');
var isSupported = !!(el.getContext && el.getContext('2d'));
caps.create_canvas = isSupported;
return isSupported;
},
return_response_type: function(responseType) {
try {
if (Basic.inArray(responseType, ['', 'text', 'document']) !== -1) {
return true;
} else if (window.XMLHttpRequest) {
var xhr = new XMLHttpRequest();
xhr.open('get', '/'); // otherwise Gecko throws an exception
if ('responseType' in xhr) {
xhr.responseType = responseType;
// as of 23.0.1271.64, Chrome switched from throwing exception to merely logging it to the console (why? o why?)
if (xhr.responseType !== responseType) {
return false;
}
return true;
}
}
} catch (ex) {}
return false;
},
use_blob_uri: function() {
var URL = window.URL;
caps.use_blob_uri = (URL &&
'createObjectURL' in URL &&
'revokeObjectURL' in URL &&
(Env.browser !== 'IE' || Env.verComp(Env.version, '11.0.46', '>=')) // IE supports createObjectURL, but not fully, for example it fails to use it as a src for the image
);
return caps.use_blob_uri;
},
// ideas for this heavily come from Modernizr (http://modernizr.com/)
use_data_uri: (function() {
var du = new Image();
du.onload = function() {
caps.use_data_uri = (du.width === 1 && du.height === 1);
};
setTimeout(function() {
du.src = "data:image/gif;base64,R0lGODlhAQABAIAAAP8AAAAAACH5BAAAAAAALAAAAAABAAEAAAICRAEAOw==";
}, 1);
return false;
}()),
use_data_uri_over32kb: function() { // IE8
return caps.use_data_uri && (Env.browser !== 'IE' || Env.version >= 9);
},
use_data_uri_of: function(bytes) {
return (caps.use_data_uri && bytes < 33000 || caps.use_data_uri_over32kb());
},
use_fileinput: function() {
if (navigator.userAgent.match(/(Android (1.0|1.1|1.5|1.6|2.0|2.1))|(Windows Phone (OS 7|8.0))|(XBLWP)|(ZuneWP)|(w(eb)?OSBrowser)|(webOS)|(Kindle\/(1.0|2.0|2.5|3.0))/)) {
return false;
}
var el = document.createElement('input');
el.setAttribute('type', 'file');
return caps.use_fileinput = !el.disabled;
},
use_webgl: function() {
var canvas = document.createElement('canvas');
var gl = null, isSupported;
try {
gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
}
catch(e) {}
if (!gl) { // it seems that sometimes it doesn't throw exception, but still fails to get context
gl = null;
}
isSupported = !!gl;
caps.use_webgl = isSupported; // save result of our check
canvas = undefined;
return isSupported;
}
};
return function(cap) {
var args = [].slice.call(arguments);
args.shift(); // shift of cap
return Basic.typeOf(caps[cap]) === 'function' ? caps[cap].apply(this, args) : !!caps[cap];
};
}());
var uaResult = new UAParser().getResult();
var Env = {
can: can,
uaParser: UAParser,
browser: uaResult.browser.name,
version: uaResult.browser.version,
os: uaResult.os.name, // everybody intuitively types it in a lowercase for some reason
osVersion: uaResult.os.version,
verComp: version_compare,
swf_url: "../flash/Moxie.swf",
xap_url: "../silverlight/Moxie.xap",
global_event_dispatcher: "moxie.core.EventTarget.instance.dispatchEvent"
};
// for backward compatibility
// @deprecated Use `Env.os` instead
Env.OS = Env.os;
if (MXI_DEBUG) {
Env.debug = {
runtime: true,
events: false
};
Env.log = function() {
function logObj(data) {
// TODO: this should recursively print out the object in a pretty way
console.appendChild(document.createTextNode(data + "\n"));
}
// if debugger present, IE8 might have window.console.log method, but not be able to apply on it (why...)
if (window && window.console && window.console.log && window.console.log.apply) {
window.console.log.apply(window.console, arguments);
} else if (document) {
var console = document.getElementById('moxie-console');
if (!console) {
console = document.createElement('pre');
console.id = 'moxie-console';
//console.style.display = 'none';
document.body.appendChild(console);
}
var data = arguments[0];
if (Basic.typeOf(data) === 'string') {
data = Basic.sprintf.apply(this, arguments);
} else if (Basic.inArray(Basic.typeOf(data), ['object', 'array']) !== -1) {
logObj(data);
return;
}
console.appendChild(document.createTextNode(data + "\n"));
}
};
}
return Env;
});
// Included from: src/javascript/core/Exceptions.js
/**
* Exceptions.js
*
* Copyright 2013, Moxiecode Systems AB
* Released under GPL License.
*
* License: http://www.plupload.com/license
* Contributing: http://www.plupload.com/contributing
*/
define('moxie/core/Exceptions', [
'moxie/core/utils/Basic'
], function(Basic) {
function _findKey(obj, value) {
var key;
for (key in obj) {
if (obj[key] === value) {
return key;
}
}
return null;
}
/**
@class moxie/core/Exception
*/
return {
RuntimeError: (function() {
var namecodes = {
NOT_INIT_ERR: 1,
EXCEPTION_ERR: 3,
NOT_SUPPORTED_ERR: 9,
JS_ERR: 4
};
function RuntimeError(code, message) {
this.code = code;
this.name = _findKey(namecodes, code);
this.message = this.name + (message || ": RuntimeError " + this.code);
}
Basic.extend(RuntimeError, namecodes);
RuntimeError.prototype = Error.prototype;
return RuntimeError;
}()),
OperationNotAllowedException: (function() {
function OperationNotAllowedException(code) {
this.code = code;
this.name = 'OperationNotAllowedException';
}
Basic.extend(OperationNotAllowedException, {
NOT_ALLOWED_ERR: 1
});
OperationNotAllowedException.prototype = Error.prototype;
return OperationNotAllowedException;
}()),
ImageError: (function() {
var namecodes = {
WRONG_FORMAT: 1,
MAX_RESOLUTION_ERR: 2,
INVALID_META_ERR: 3
};
function ImageError(code) {
this.code = code;
this.name = _findKey(namecodes, code);
this.message = this.name + ": ImageError " + this.code;
}
Basic.extend(ImageError, namecodes);
ImageError.prototype = Error.prototype;
return ImageError;
}()),
FileException: (function() {
var namecodes = {
NOT_FOUND_ERR: 1,
SECURITY_ERR: 2,
ABORT_ERR: 3,
NOT_READABLE_ERR: 4,
ENCODING_ERR: 5,
NO_MODIFICATION_ALLOWED_ERR: 6,
INVALID_STATE_ERR: 7,
SYNTAX_ERR: 8
};
function FileException(code) {
this.code = code;
this.name = _findKey(namecodes, code);
this.message = this.name + ": FileException " + this.code;
}
Basic.extend(FileException, namecodes);
FileException.prototype = Error.prototype;
return FileException;
}()),
DOMException: (function() {
var namecodes = {
INDEX_SIZE_ERR: 1,
DOMSTRING_SIZE_ERR: 2,
HIERARCHY_REQUEST_ERR: 3,
WRONG_DOCUMENT_ERR: 4,
INVALID_CHARACTER_ERR: 5,
NO_DATA_ALLOWED_ERR: 6,
NO_MODIFICATION_ALLOWED_ERR: 7,
NOT_FOUND_ERR: 8,
NOT_SUPPORTED_ERR: 9,
INUSE_ATTRIBUTE_ERR: 10,
INVALID_STATE_ERR: 11,
SYNTAX_ERR: 12,
INVALID_MODIFICATION_ERR: 13,
NAMESPACE_ERR: 14,
INVALID_ACCESS_ERR: 15,
VALIDATION_ERR: 16,
TYPE_MISMATCH_ERR: 17,
SECURITY_ERR: 18,
NETWORK_ERR: 19,
ABORT_ERR: 20,
URL_MISMATCH_ERR: 21,
QUOTA_EXCEEDED_ERR: 22,
TIMEOUT_ERR: 23,
INVALID_NODE_TYPE_ERR: 24,
DATA_CLONE_ERR: 25
};
function DOMException(code) {
this.code = code;
this.name = _findKey(namecodes, code);
this.message = this.name + ": DOMException " + this.code;
}
Basic.extend(DOMException, namecodes);
DOMException.prototype = Error.prototype;
return DOMException;
}()),
EventException: (function() {
function EventException(code) {
this.code = code;
this.name = 'EventException';
}
Basic.extend(EventException, {
UNSPECIFIED_EVENT_TYPE_ERR: 0
});
EventException.prototype = Error.prototype;
return EventException;
}())
};
});
// Included from: src/javascript/core/utils/Dom.js
/**
* Dom.js
*
* Copyright 2013, Moxiecode Systems AB
* Released under GPL License.
*
* License: http://www.plupload.com/license
* Contributing: http://www.plupload.com/contributing
*/
/**
@class moxie/core/utils/Dom
@public
@static
*/
define('moxie/core/utils/Dom', ['moxie/core/utils/Env'], func