(function() { var gaTracker, Events, custom, es5Shim, es5Sham, base64, polyFills, core, Media, utils, Utils, Styles, Theme, WindowOrigin, WindowPlacement, Base, Error, WixDataCursor, responseHandlers, Billing, Activities, Settings, WixInternalSDK, Contacts, PubSub, Worker, Dashboard, Wix; gaTracker = function () { var gaq = window._gaq || (window._gaq = []); var trackSDKCall = function (callName, label) { gaTrackEvent('SDK', callName, label); }; var gaTrackEvent = function (category, action, label, value) { gaq.push([ 'wix._trackEvent', category || 'default', action || 'default', label || '', value ]); }; var gaInit = function () { gaq.push([ 'wix._setAccount', 'UA-2117194-51' ]); gaq.push(['wix._trackPageview']); (function () { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' === document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); }()); }; return { gaInit: gaInit, trackSDKCall: trackSDKCall, gaTrackEvent: gaTrackEvent }; }(); /** * @memberof Wix * @namespace Events */ Events = { /** * Called when a site owner toggles between preview and edit mode in the Wix Editor. * @memberof Wix.Events * @since 1.11.0 * @example * { * editMode: 'editor' or 'preview' * } */ EDIT_MODE_CHANGE: 'EDIT_MODE_CHANGE', /** * Called when a user navigates (in Editor, preview or Viewer) to the page where the TPA component (Widget/Page) is. * @memberof Wix.Events * @since 1.11.0 * @deprecated * @example * { * toPage: 'mainPage', * fromPage: 'cee5"' * } */ PAGE_NAVIGATION_CHANGE: 'PAGE_NAVIGATION_CHANGE', /** * Issued when the site owner publishes the site (in editor). * @memberof Wix.Events * @since 1.13.0 */ SITE_PUBLISHED: 'SITE_PUBLISHED', /** * Issued when the site owner deletes (in editor) a TPA component (Widget/Page). * @memberof Wix.Events * @since 1.13.0 */ COMPONENT_DELETED: 'COMPONENT_DELETED', /** * Issued by the Settings endpoint when new settings are applied by the site owner. * @memberof Wix.Events * @since 1.17.0 * @example * Custom JSON */ SETTINGS_UPDATED: 'SETTINGS_UPDATED', /** * Signal window placement change * @memberof Wix.Events * @since 1.18.0 */ WINDOW_PLACEMENT_CHANGED: 'WINDOW_PLACEMENT_CHANGED', /** * @memberof Wix.Events * @private */ ON_MESSAGE_RESPONSE: 'ON_MESSAGE_RESPONSE', /** * @memberof Wix.Events * @since 1.22.0 */ THEME_CHANGE: 'THEME_CHANGE', /** * @memberof Wix.Events * @since 1.22.0 * */ STYLE_PARAMS_CHANGE: 'STYLE_PARAMS_CHANGE', /** * @memberof Wix.Events * @since 1.25.0 * @description * Issued when scroll happens inside the site (not when it happen inside the app iframe). * The event data contains multiple details that helps the app determine it's behaviour considering it's position in the site, * the browser window dimensions and a state. * * Name | Type | Description * ---------------|-----------|------------ * scrollTop | `Number` | Site's scroll position on the y axis * scrollLeft | `Number` | site's scroll position on the x axis * documentHeight | `Number` | Site's document height * documentWidth | `Number` | Site's document width * x | `Number` | App offset within the site's page on the x axis (doesn't change) * y | `Number` | App offset within the site's page on the y axis (doesn't change) * height | `Number` | App height * width | `Number` | App width * left | `Number` | App top-left offset,within the viewport, from the left * bottom | `Number` | App top-left, offset within the viewport, from the bottom * right | `Number` | App top-left, offset within the viewport, from the right * top | `Number` | App top-left, offset within the viewport, from the top * * @example * { * "scrollTop": 4, * "scrollLeft": 0, * "documentHeight": 724, * "documentWidth": 1227, * "x": 124, * "y": 131, * "height": 682, * "width": 978, * "left": 124.5, * "bottom": 809, * "right": 1102.5, * "top": 127 * } */ SCROLL: 'SCROLL', /** * Issued on any page navigation within the Wix site. * @memberof Wix.Events * @since 1.25.0 * @example * { * toPage: 'mainPage', * fromPage: 'cee5"' * } */ PAGE_NAVIGATION: 'PAGE_NAVIGATION', /** * Issued on any page in navigation within the Wix site. This event is a utility event on top of the PAGE_NAVIGATION event. * @memberof Wix.Events * @since 1.25.0 * @example * { * toPage: 'mainPage', * fromPage: 'cee5"' * } */ PAGE_NAVIGATION_IN: 'PAGE_NAVIGATION_IN', /** * Issued on any page out navigation within the Wix site. This event is a utility event on top of the PAGE_NAVIGATION event. * @memberof Wix.Events * @since 1.25.0 * @example * { * toPage: 'mainPage', * fromPage: 'cee5"' * } */ PAGE_NAVIGATION_OUT: 'PAGE_NAVIGATION_OUT', /** * Issued when the site state changed. * @memberof Wix.Events * @since 1.29.0 * @example * { * newState: 'state' * } */ STATE_CHANGED: 'STATE_CHANGED' }; (function () { var isFunction = function (o) { return typeof o == 'function'; }; var bind, slice = [].slice, proto = Function.prototype, featureMap; featureMap = { 'function-bind': 'bind' }; function has(feature) { var prop = featureMap[feature]; return isFunction(proto[prop]); } // check for missing features if (!has('function-bind')) { // adapted from Mozilla Developer Network example at // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind bind = function bind(obj) { var args = slice.call(arguments, 1), self = this, nop = function () { }, bound = function () { return self.apply(this instanceof nop ? this : obj || {}, args.concat(slice.call(arguments))); }; nop.prototype = this.prototype || {}; // Firefox cries sometimes if prototype is undefined bound.prototype = new nop(); return bound; }; proto.bind = bind; } }()); custom /*! * https://github.com/es-shims/es5-shim * @license es5-shim Copyright 2009-2014 by contributors, MIT License * see https://github.com/es-shims/es5-shim/blob/master/LICENSE */ // vim: ts=4 sts=4 sw=4 expandtab //Add semicolon to prevent IIFE from being passed as argument to concatenated code. = undefined; // UMD (Universal Module Definition) // see https://github.com/umdjs/umd/blob/master/returnExports.js (function (root, factory) { if (true) { // AMD. Register as an anonymous module. es5Shim = function () { return typeof factory === 'function' ? factory() : factory; }(); } else if (typeof exports === 'object') { // Node. Does not work with strict CommonJS, but // only CommonJS-like enviroments that support module.exports, // like Node. module.exports = factory(); } else { // Browser globals (root is window) root.returnExports = factory(); } }(this, function () { /** * Brings an environment as close to ECMAScript 5 compliance * as is possible with the facilities of erstwhile engines. * * Annotated ES5: http://es5.github.com/ (specific links below) * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/ */ // Shortcut to an often accessed properties, in order to avoid multiple // dereference that costs universally. var ArrayPrototype = Array.prototype; var ObjectPrototype = Object.prototype; var FunctionPrototype = Function.prototype; var StringPrototype = String.prototype; var NumberPrototype = Number.prototype; var array_slice = ArrayPrototype.slice; var array_splice = ArrayPrototype.splice; var array_push = ArrayPrototype.push; var array_unshift = ArrayPrototype.unshift; var call = FunctionPrototype.call; // Having a toString local variable name breaks in Opera so use _toString. var _toString = ObjectPrototype.toString; var isFunction = function (val) { return ObjectPrototype.toString.call(val) === '[object Function]'; }; var isRegex = function (val) { return ObjectPrototype.toString.call(val) === '[object RegExp]'; }; var isArray = function isArray(obj) { return _toString.call(obj) === '[object Array]'; }; var isString = function isString(obj) { return _toString.call(obj) === '[object String]'; }; var isArguments = function isArguments(value) { var str = _toString.call(value); var isArgs = str === '[object Arguments]'; if (!isArgs) { isArgs = !isArray(value) && value !== null && typeof value === 'object' && typeof value.length === 'number' && value.length >= 0 && isFunction(value.callee); } return isArgs; }; var supportsDescriptors = Object.defineProperty && function () { try { Object.defineProperty({}, 'x', {}); return true; } catch (e) { /* this is ES3 */ return false; } }(); // Define configurable, writable and non-enumerable props // if they don't exist. var defineProperty; if (supportsDescriptors) { defineProperty = function (object, name, method, forceAssign) { if (!forceAssign && name in object) { return; } Object.defineProperty(object, name, { configurable: true, enumerable: false, writable: true, value: method }); }; } else { defineProperty = function (object, name, method, forceAssign) { if (!forceAssign && name in object) { return; } object[name] = method; }; } var defineProperties = function (object, map, forceAssign) { for (var name in map) { if (ObjectPrototype.hasOwnProperty.call(map, name)) { defineProperty(object, name, map[name], forceAssign); } } }; // // Util // ====== // // ES5 9.4 // http://es5.github.com/#x9.4 // http://jsperf.com/to-integer function toInteger(n) { n = +n; if (n !== n) { // isNaN n = 0; } else if (n !== 0 && n !== 1 / 0 && n !== -(1 / 0)) { n = (n > 0 || -1) * Math.floor(Math.abs(n)); } return n; } function isPrimitive(input) { var type = typeof input; return input === null || type === 'undefined' || type === 'boolean' || type === 'number' || type === 'string'; } function toPrimitive(input) { var val, valueOf, toStr; if (isPrimitive(input)) { return input; } valueOf = input.valueOf; if (isFunction(valueOf)) { val = valueOf.call(input); if (isPrimitive(val)) { return val; } } toStr = input.toString; if (isFunction(toStr)) { val = toStr.call(input); if (isPrimitive(val)) { return val; } } throw new TypeError(); } // ES5 9.9 // http://es5.github.com/#x9.9 var toObject = function (o) { if (o == null) { // this matches both null and undefined throw new TypeError('can\'t convert ' + o + ' to object'); } return Object(o); }; var ToUint32 = function ToUint32(x) { return x >>> 0; }; // // Function // ======== // // ES-5 15.3.4.5 // http://es5.github.com/#x15.3.4.5 function Empty() { } defineProperties(FunctionPrototype, { bind: function bind(that) { // .length is 1 // 1. Let Target be the this value. var target = this; // 2. If IsCallable(Target) is false, throw a TypeError exception. if (!isFunction(target)) { throw new TypeError('Function.prototype.bind called on incompatible ' + target); } // 3. Let A be a new (possibly empty) internal list of all of the // argument values provided after thisArg (arg1, arg2 etc), in order. // XXX slicedArgs will stand in for "A" if used var args = array_slice.call(arguments, 1); // for normal call // 4. Let F be a new native ECMAScript object. // 11. Set the [[Prototype]] internal property of F to the standard // built-in Function prototype object as specified in 15.3.3.1. // 12. Set the [[Call]] internal property of F as described in // 15.3.4.5.1. // 13. Set the [[Construct]] internal property of F as described in // 15.3.4.5.2. // 14. Set the [[HasInstance]] internal property of F as described in // 15.3.4.5.3. var binder = function () { if (this instanceof bound) { // 15.3.4.5.2 [[Construct]] // When the [[Construct]] internal method of a function object, // F that was created using the bind function is called with a // list of arguments ExtraArgs, the following steps are taken: // 1. Let target be the value of F's [[TargetFunction]] // internal property. // 2. If target has no [[Construct]] internal method, a // TypeError exception is thrown. // 3. Let boundArgs be the value of F's [[BoundArgs]] internal // property. // 4. Let args be a new list containing the same values as the // list boundArgs in the same order followed by the same // values as the list ExtraArgs in the same order. // 5. Return the result of calling the [[Construct]] internal // method of target providing args as the arguments. var result = target.apply(this, args.concat(array_slice.call(arguments))); if (Object(result) === result) { return result; } return this; } else { // 15.3.4.5.1 [[Call]] // When the [[Call]] internal method of a function object, F, // which was created using the bind function is called with a // this value and a list of arguments ExtraArgs, the following // steps are taken: // 1. Let boundArgs be the value of F's [[BoundArgs]] internal // property. // 2. Let boundThis be the value of F's [[BoundThis]] internal // property. // 3. Let target be the value of F's [[TargetFunction]] internal // property. // 4. Let args be a new list containing the same values as the // list boundArgs in the same order followed by the same // values as the list ExtraArgs in the same order. // 5. Return the result of calling the [[Call]] internal method // of target providing boundThis as the this value and // providing args as the arguments. // equiv: target.call(this, ...boundArgs, ...args) return target.apply(that, args.concat(array_slice.call(arguments))); } }; // 15. If the [[Class]] internal property of Target is "Function", then // a. Let L be the length property of Target minus the length of A. // b. Set the length own property of F to either 0 or L, whichever is // larger. // 16. Else set the length own property of F to 0. var boundLength = Math.max(0, target.length - args.length); // 17. Set the attributes of the length own property of F to the values // specified in 15.3.5.1. var boundArgs = []; for (var i = 0; i < boundLength; i++) { boundArgs.push('$' + i); } // XXX Build a dynamic function with desired amount of arguments is the only // way to set the length property of a function. // In environments where Content Security Policies enabled (Chrome extensions, // for ex.) all use of eval or Function costructor throws an exception. // However in all of these environments Function.prototype.bind exists // and so this code will never be executed. var bound = Function('binder', 'return function (' + boundArgs.join(',') + '){return binder.apply(this,arguments)}')(binder); if (target.prototype) { Empty.prototype = target.prototype; bound.prototype = new Empty(); // Clean up dangling references. Empty.prototype = null; } // TODO // 18. Set the [[Extensible]] internal property of F to true. // TODO // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3). // 20. Call the [[DefineOwnProperty]] internal method of F with // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]: // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and // false. // 21. Call the [[DefineOwnProperty]] internal method of F with // arguments "arguments", PropertyDescriptor {[[Get]]: thrower, // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false}, // and false. // TODO // NOTE Function objects created using Function.prototype.bind do not // have a prototype property or the [[Code]], [[FormalParameters]], and // [[Scope]] internal properties. // XXX can't delete prototype in pure-js. // 22. Return F. return bound; } }); // _Please note: Shortcuts are defined after `Function.prototype.bind` as we // us it in defining shortcuts. var owns = call.bind(ObjectPrototype.hasOwnProperty); // If JS engine supports accessors creating shortcuts. var defineGetter; var defineSetter; var lookupGetter; var lookupSetter; var supportsAccessors; if (supportsAccessors = owns(ObjectPrototype, '__defineGetter__')) { defineGetter = call.bind(ObjectPrototype.__defineGetter__); defineSetter = call.bind(ObjectPrototype.__defineSetter__); lookupGetter = call.bind(ObjectPrototype.__lookupGetter__); lookupSetter = call.bind(ObjectPrototype.__lookupSetter__); } // // Array // ===== // // ES5 15.4.4.12 // http://es5.github.com/#x15.4.4.12 var spliceNoopReturnsEmptyArray = function () { var a = [ 1, 2 ]; var result = a.splice(); return a.length === 2 && isArray(result) && result.length === 0; }(); defineProperties(ArrayPrototype, { // Safari 5.0 bug where .splice() returns undefined splice: function splice(start, deleteCount) { if (arguments.length === 0) { return []; } else { return array_splice.apply(this, arguments); } } }, spliceNoopReturnsEmptyArray); var spliceWorksWithEmptyObject = function () { var obj = {}; ArrayPrototype.splice.call(obj, 0, 0, 1); return obj.length === 1; }(); defineProperties(ArrayPrototype, { splice: function splice(start, deleteCount) { if (arguments.length === 0) { return []; } var args = arguments; this.length = Math.max(toInteger(this.length), 0); if (arguments.length > 0 && typeof deleteCount !== 'number') { args = array_slice.call(arguments); if (args.length < 2) { args.push(this.length - start); } else { args[1] = toInteger(deleteCount); } } return array_splice.apply(this, args); } }, !spliceWorksWithEmptyObject); // ES5 15.4.4.12 // http://es5.github.com/#x15.4.4.13 // Return len+argCount. // [bugfix, ielt8] // IE < 8 bug: [].unshift(0) === undefined but should be "1" var hasUnshiftReturnValueBug = [].unshift(0) !== 1; defineProperties(ArrayPrototype, { unshift: function () { array_unshift.apply(this, arguments); return this.length; } }, hasUnshiftReturnValueBug); // ES5 15.4.3.2 // http://es5.github.com/#x15.4.3.2 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray defineProperties(Array, { isArray: isArray }); // The IsCallable() check in the Array functions // has been replaced with a strict check on the // internal class of the object to trap cases where // the provided function was actually a regular // expression literal, which in V8 and // JavaScriptCore is a typeof "function". Only in // V8 are regular expression literals permitted as // reduce parameters, so it is desirable in the // general case for the shim to match the more // strict and common behavior of rejecting regular // expressions. // ES5 15.4.4.18 // http://es5.github.com/#x15.4.4.18 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach // Check failure of by-index access of string characters (IE < 9) // and failure of `0 in boxedString` (Rhino) var boxedString = Object('a'); var splitString = boxedString[0] !== 'a' || !(0 in boxedString); var properlyBoxesContext = function properlyBoxed(method) { // Check node 0.6.21 bug where third parameter is not boxed var properlyBoxesNonStrict = true; var properlyBoxesStrict = true; if (method) { method.call('foo', function (_, __, context) { if (typeof context !== 'object') { properlyBoxesNonStrict = false; } }); method.call([1], function () { properlyBoxesStrict = typeof this === 'string'; }, 'x'); } return !!method && properlyBoxesNonStrict && properlyBoxesStrict; }; defineProperties(ArrayPrototype, { forEach: function forEach(fun) { var object = toObject(this), self = splitString && isString(this) ? this.split('') : object, thisp = arguments[1], i = -1, length = self.length >>> 0; // If no callback function or if callback is not a callable function if (!isFunction(fun)) { throw new TypeError(); // TODO message } while (++i < length) { if (i in self) { // Invoke the callback function with call, passing arguments: // context, property value, property key, thisArg object // context fun.call(thisp, self[i], i, object); } } } }, !properlyBoxesContext(ArrayPrototype.forEach)); // ES5 15.4.4.19 // http://es5.github.com/#x15.4.4.19 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map defineProperties(ArrayPrototype, { map: function map(fun) { var object = toObject(this), self = splitString && isString(this) ? this.split('') : object, length = self.length >>> 0, result = Array(length), thisp = arguments[1]; // If no callback function or if callback is not a callable function if (!isFunction(fun)) { throw new TypeError(fun + ' is not a function'); } for (var i = 0; i < length; i++) { if (i in self) { result[i] = fun.call(thisp, self[i], i, object); } } return result; } }, !properlyBoxesContext(ArrayPrototype.map)); // ES5 15.4.4.20 // http://es5.github.com/#x15.4.4.20 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter defineProperties(ArrayPrototype, { filter: function filter(fun) { var object = toObject(this), self = splitString && isString(this) ? this.split('') : object, length = self.length >>> 0, result = [], value, thisp = arguments[1]; // If no callback function or if callback is not a callable function if (!isFunction(fun)) { throw new TypeError(fun + ' is not a function'); } for (var i = 0; i < length; i++) { if (i in self) { value = self[i]; if (fun.call(thisp, value, i, object)) { result.push(value); } } } return result; } }, !properlyBoxesContext(ArrayPrototype.filter)); // ES5 15.4.4.16 // http://es5.github.com/#x15.4.4.16 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every defineProperties(ArrayPrototype, { every: function every(fun) { var object = toObject(this), self = splitString && isString(this) ? this.split('') : object, length = self.length >>> 0, thisp = arguments[1]; // If no callback function or if callback is not a callable function if (!isFunction(fun)) { throw new TypeError(fun + ' is not a function'); } for (var i = 0; i < length; i++) { if (i in self && !fun.call(thisp, self[i], i, object)) { return false; } } return true; } }, !properlyBoxesContext(ArrayPrototype.every)); // ES5 15.4.4.17 // http://es5.github.com/#x15.4.4.17 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some defineProperties(ArrayPrototype, { some: function some(fun) { var object = toObject(this), self = splitString && isString(this) ? this.split('') : object, length = self.length >>> 0, thisp = arguments[1]; // If no callback function or if callback is not a callable function if (!isFunction(fun)) { throw new TypeError(fun + ' is not a function'); } for (var i = 0; i < length; i++) { if (i in self && fun.call(thisp, self[i], i, object)) { return true; } } return false; } }, !properlyBoxesContext(ArrayPrototype.some)); // ES5 15.4.4.21 // http://es5.github.com/#x15.4.4.21 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce var reduceCoercesToObject = false; if (ArrayPrototype.reduce) { reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) { return list; }) === 'object'; } defineProperties(ArrayPrototype, { reduce: function reduce(fun) { var object = toObject(this), self = splitString && isString(this) ? this.split('') : object, length = self.length >>> 0; // If no callback function or if callback is not a callable function if (!isFunction(fun)) { throw new TypeError(fun + ' is not a function'); } // no value to return if no initial value and an empty array if (!length && arguments.length === 1) { throw new TypeError('reduce of empty array with no initial value'); } var i = 0; var result; if (arguments.length >= 2) { result = arguments[1]; } else { do { if (i in self) { result = self[i++]; break; } // if array contains no values, no initial value to return if (++i >= length) { throw new TypeError('reduce of empty array with no initial value'); } } while (true); } for (; i < length; i++) { if (i in self) { result = fun.call(void 0, result, self[i], i, object); } } return result; } }, !reduceCoercesToObject); // ES5 15.4.4.22 // http://es5.github.com/#x15.4.4.22 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight var reduceRightCoercesToObject = false; if (ArrayPrototype.reduceRight) { reduceRightCoercesToObject = typeof ArrayPrototype.reduceRight.call('es5', function (_, __, ___, list) { return list; }) === 'object'; } defineProperties(ArrayPrototype, { reduceRight: function reduceRight(fun) { var object = toObject(this), self = splitString && isString(this) ? this.split('') : object, length = self.length >>> 0; // If no callback function or if callback is not a callable function if (!isFunction(fun)) { throw new TypeError(fun + ' is not a function'); } // no value to return if no initial value, empty array if (!length && arguments.length === 1) { throw new TypeError('reduceRight of empty array with no initial value'); } var result, i = length - 1; if (arguments.length >= 2) { result = arguments[1]; } else { do { if (i in self) { result = self[i--]; break; } // if array contains no values, no initial value to return if (--i < 0) { throw new TypeError('reduceRight of empty array with no initial value'); } } while (true); } if (i < 0) { return result; } do { if (i in self) { result = fun.call(void 0, result, self[i], i, object); } } while (i--); return result; } }, !reduceRightCoercesToObject); // ES5 15.4.4.14 // http://es5.github.com/#x15.4.4.14 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf var hasFirefox2IndexOfBug = Array.prototype.indexOf && [ 0, 1 ].indexOf(1, 2) !== -1; defineProperties(ArrayPrototype, { indexOf: function indexOf(sought) { var self = splitString && isString(this) ? this.split('') : toObject(this), length = self.length >>> 0; if (!length) { return -1; } var i = 0; if (arguments.length > 1) { i = toInteger(arguments[1]); } // handle negative indices i = i >= 0 ? i : Math.max(0, length + i); for (; i < length; i++) { if (i in self && self[i] === sought) { return i; } } return -1; } }, hasFirefox2IndexOfBug); // ES5 15.4.4.15 // http://es5.github.com/#x15.4.4.15 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf var hasFirefox2LastIndexOfBug = Array.prototype.lastIndexOf && [ 0, 1 ].lastIndexOf(0, -3) !== -1; defineProperties(ArrayPrototype, { lastIndexOf: function lastIndexOf(sought) { var self = splitString && isString(this) ? this.split('') : toObject(this), length = self.length >>> 0; if (!length) { return -1; } var i = length - 1; if (arguments.length > 1) { i = Math.min(i, toInteger(arguments[1])); } // handle negative indices i = i >= 0 ? i : length - Math.abs(i); for (; i >= 0; i--) { if (i in self && sought === self[i]) { return i; } } return -1; } }, hasFirefox2LastIndexOfBug); // // Object // ====== // // ES5 15.2.3.14 // http://es5.github.com/#x15.2.3.14 // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation var hasDontEnumBug = !{ 'toString': null }.propertyIsEnumerable('toString'), hasProtoEnumBug = function () { }.propertyIsEnumerable('prototype'), dontEnums = [ 'toString', 'toLocaleString', 'valueOf', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor' ], dontEnumsLength = dontEnums.length; defineProperties(Object, { keys: function keys(object) { var isFn = isFunction(object), isArgs = isArguments(object), isObject = object !== null && typeof object === 'object', isStr = isObject && isString(object); if (!isObject && !isFn && !isArgs) { throw new TypeError('Object.keys called on a non-object'); } var theKeys = []; var skipProto = hasProtoEnumBug && isFn; if (isStr || isArgs) { for (var i = 0; i < object.length; ++i) { theKeys.push(String(i)); } } else { for (var name in object) { if (!(skipProto && name === 'prototype') && owns(object, name)) { theKeys.push(String(name)); } } } if (hasDontEnumBug) { var ctor = object.constructor, skipConstructor = ctor && ctor.prototype === object; for (var j = 0; j < dontEnumsLength; j++) { var dontEnum = dontEnums[j]; if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) { theKeys.push(dontEnum); } } } return theKeys; } }); var keysWorksWithArguments = Object.keys && function () { // Safari 5.0 bug return Object.keys(arguments).length === 2; }(1, 2); var originalKeys = Object.keys; defineProperties(Object, { keys: function keys(object) { if (isArguments(object)) { return originalKeys(ArrayPrototype.slice.call(object)); } else { return originalKeys(object); } } }, !keysWorksWithArguments); // // Date // ==== // // ES5 15.9.5.43 // http://es5.github.com/#x15.9.5.43 // This function returns a String value represent the instance in time // represented by this Date object. The format of the String is the Date Time // string format defined in 15.9.1.15. All fields are present in the String. // The time zone is always UTC, denoted by the suffix Z. If the time value of // this object is not a finite Number a RangeError exception is thrown. var negativeDate = -62198755200000; var negativeYearString = '-000001'; var hasNegativeDateBug = Date.prototype.toISOString && new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1; defineProperties(Date.prototype, { toISOString: function toISOString() { var result, length, value, year, month; if (!isFinite(this)) { throw new RangeError('Date.prototype.toISOString called on non-finite value.'); } year = this.getUTCFullYear(); month = this.getUTCMonth(); // see https://github.com/es-shims/es5-shim/issues/111 year += Math.floor(month / 12); month = (month % 12 + 12) % 12; // the date time string format is specified in 15.9.1.15. result = [ month + 1, this.getUTCDate(), this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds() ]; year = (year < 0 ? '-' : year > 9999 ? '+' : '') + ('00000' + Math.abs(year)).slice(0 <= year && year <= 9999 ? -4 : -6); length = result.length; while (length--) { value = result[length]; // pad months, days, hours, minutes, and seconds to have two // digits. if (value < 10) { result[length] = '0' + value; } } // pad milliseconds to have three digits. return year + '-' + result.slice(0, 2).join('-') + 'T' + result.slice(2).join(':') + '.' + ('000' + this.getUTCMilliseconds()).slice(-3) + 'Z'; } }, hasNegativeDateBug); // ES5 15.9.5.44 // http://es5.github.com/#x15.9.5.44 // This function provides a String representation of a Date object for use by // JSON.stringify (15.12.3). var dateToJSONIsSupported = false; try { dateToJSONIsSupported = Date.prototype.toJSON && new Date(NaN).toJSON() === null && new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 && Date.prototype.toJSON.call({ // generic toISOString: function () { return true; } }); } catch (e) { } if (!dateToJSONIsSupported) { Date.prototype.toJSON = function toJSON(key) { // When the toJSON method is called with argument key, the following // steps are taken: // 1. Let O be the result of calling ToObject, giving it the this // value as its argument. // 2. Let tv be toPrimitive(O, hint Number). var o = Object(this), tv = toPrimitive(o), toISO; // 3. If tv is a Number and is not finite, return null. if (typeof tv === 'number' && !isFinite(tv)) { return null; } // 4. Let toISO be the result of calling the [[Get]] internal method of // O with argument "toISOString". toISO = o.toISOString; // 5. If IsCallable(toISO) is false, throw a TypeError exception. if (typeof toISO !== 'function') { throw new TypeError('toISOString property is not callable'); } // 6. Return the result of calling the [[Call]] internal method of // toISO with O as the this value and an empty argument list. return toISO.call(o); // NOTE 1 The argument is ignored. // NOTE 2 The toJSON function is intentionally generic; it does not // require that its this value be a Date object. Therefore, it can be // transferred to other kinds of objects for use as a method. However, // it does require that any such object have a toISOString method. An // object is free to use the argument key to filter its // stringification. }; } // ES5 15.9.4.2 // http://es5.github.com/#x15.9.4.2 // based on work shared by Daniel Friesen (dantman) // http://gist.github.com/303249 var supportsExtendedYears = Date.parse('+033658-09-27T01:46:40.000Z') === 1000000000000000; var acceptsInvalidDates = !isNaN(Date.parse('2012-04-04T24:00:00.500Z')) || !isNaN(Date.parse('2012-11-31T23:59:59.000Z')); var doesNotParseY2KNewYear = isNaN(Date.parse('2000-01-01T00:00:00.000Z')); if (!Date.parse || doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) { // XXX global assignment won't work in embeddings that use // an alternate object for the context. Date = function (NativeDate) { // Date.length === 7 function Date(Y, M, D, h, m, s, ms) { var length = arguments.length; if (this instanceof NativeDate) { var date = length === 1 && String(Y) === Y ? // isString(Y) // We explicitly pass it through parse: new NativeDate(Date.parse(Y)) : // We have to manually make calls depending on argument // length here length >= 7 ? new NativeDate(Y, M, D, h, m, s, ms) : length >= 6 ? new NativeDate(Y, M, D, h, m, s) : length >= 5 ? new NativeDate(Y, M, D, h, m) : length >= 4 ? new NativeDate(Y, M, D, h) : length >= 3 ? new NativeDate(Y, M, D) : length >= 2 ? new NativeDate(Y, M) : length >= 1 ? new NativeDate(Y) : new NativeDate(); // Prevent mixups with unfixed Date object date.constructor = Date; return date; } return NativeDate.apply(this, arguments); } // 15.9.1.15 Date Time String Format. var isoDateExpression = new RegExp('^' + '(\\d{4}|[+-]\\d{6})' + // four-digit year capture or sign + // 6-digit extended year '(?:-(\\d{2})' + // optional month capture '(?:-(\\d{2})' + // optional day capture '(?:' + // capture hours:minutes:seconds.milliseconds 'T(\\d{2})' + // hours capture ':(\\d{2})' + // minutes capture '(?:' + // optional :seconds.milliseconds ':(\\d{2})' + // seconds capture '(?:(\\.\\d{1,}))?' + // milliseconds capture ')?' + '(' + // capture UTC offset component 'Z|' + // UTC capture '(?:' + // offset specifier +/-hours:minutes '([-+])' + // sign capture '(\\d{2})' + // hours offset capture ':(\\d{2})' + // minutes offset capture ')' + ')?)?)?)?' + '$'); var months = [ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 ]; function dayFromMonth(year, month) { var t = month > 1 ? 1 : 0; return months[month] + Math.floor((year - 1969 + t) / 4) - Math.floor((year - 1901 + t) / 100) + Math.floor((year - 1601 + t) / 400) + 365 * (year - 1970); } function toUTC(t) { return Number(new NativeDate(1970, 0, 1, 0, 0, 0, t)); } // Copy any custom methods a 3rd party library may have added for (var key in NativeDate) { Date[key] = NativeDate[key]; } // Copy "native" methods explicitly; they may be non-enumerable Date.now = NativeDate.now; Date.UTC = NativeDate.UTC; Date.prototype = NativeDate.prototype; Date.prototype.constructor = Date; // Upgrade Date.parse to handle simplified ISO 8601 strings Date.parse = function parse(string) { var match = isoDateExpression.exec(string); if (match) { // parse months, days, hours, minutes, seconds, and milliseconds // provide default values if necessary // parse the UTC offset component var year = Number(match[1]), month = Number(match[2] || 1) - 1, day = Number(match[3] || 1) - 1, hour = Number(match[4] || 0), minute = Number(match[5] || 0), second = Number(match[6] || 0), millisecond = Math.floor(Number(match[7] || 0) * 1000), // When time zone is missed, local offset should be used // (ES 5.1 bug) // see https://bugs.ecmascript.org/show_bug.cgi?id=112 isLocalTime = Boolean(match[4] && !match[8]), signOffset = match[9] === '-' ? 1 : -1, hourOffset = Number(match[10] || 0), minuteOffset = Number(match[11] || 0), result; if (hour < (minute > 0 || second > 0 || millisecond > 0 ? 24 : 25) && minute < 60 && second < 60 && millisecond < 1000 && month > -1 && month < 12 && hourOffset < 24 && minuteOffset < 60 && // detect invalid offsets day > -1 && day < dayFromMonth(year, month + 1) - dayFromMonth(year, month)) { result = ((dayFromMonth(year, month) + day) * 24 + hour + hourOffset * signOffset) * 60; result = ((result + minute + minuteOffset * signOffset) * 60 + second) * 1000 + millisecond; if (isLocalTime) { result = toUTC(result); } if (-8640000000000000 <= result && result <= 8640000000000000) { return result; } } return NaN; } return NativeDate.parse.apply(this, arguments); }; return Date; }(Date); } // ES5 15.9.4.4 // http://es5.github.com/#x15.9.4.4 if (!Date.now) { Date.now = function now() { return new Date().getTime(); }; } // // Number // ====== // // ES5.1 15.7.4.5 // http://es5.github.com/#x15.7.4.5 var hasToFixedBugs = NumberPrototype.toFixed && (0.00008.toFixed(3) !== '0.000' || 0.9.toFixed(0) !== '1' || 1.255.toFixed(2) !== '1.25' || 1000000000000000100..toFixed(0) !== '1000000000000000128'); var toFixedHelpers = { base: 10000000, size: 6, data: [ 0, 0, 0, 0, 0, 0 ], multiply: function multiply(n, c) { var i = -1; while (++i < toFixedHelpers.size) { c += n * toFixedHelpers.data[i]; toFixedHelpers.data[i] = c % toFixedHelpers.base; c = Math.floor(c / toFixedHelpers.base); } }, divide: function divide(n) { var i = toFixedHelpers.size, c = 0; while (--i >= 0) { c += toFixedHelpers.data[i]; toFixedHelpers.data[i] = Math.floor(c / n); c = c % n * toFixedHelpers.base; } }, numToString: function numToString() { var i = toFixedHelpers.size; var s = ''; while (--i >= 0) { if (s !== '' || i === 0 || toFixedHelpers.data[i] !== 0) { var t = String(toFixedHelpers.data[i]); if (s === '') { s = t; } else { s += '0000000'.slice(0, 7 - t.length) + t; } } } return s; }, pow: function pow(x, n, acc) { return n === 0 ? acc : n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc); }, log: function log(x) { var n = 0; while (x >= 4096) { n += 12; x /= 4096; } while (x >= 2) { n += 1; x /= 2; } return n; } }; defineProperties(NumberPrototype, { toFixed: function toFixed(fractionDigits) { var f, x, s, m, e, z, j, k; // Test for NaN and round fractionDigits down f = Number(fractionDigits); f = f !== f ? 0 : Math.floor(f); if (f < 0 || f > 20) { throw new RangeError('Number.toFixed called with invalid number of decimals'); } x = Number(this); // Test for NaN if (x !== x) { return 'NaN'; } // If it is too big or small, return the string value of the number if (x <= -1e+21 || x >= 1e+21) { return String(x); } s = ''; if (x < 0) { s = '-'; x = -x; } m = '0'; if (x > 1e-21) { // 1e-21 < x < 1e21 // -70 < log2(x) < 70 e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69; z = e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1); z *= 4503599627370496; // Math.pow(2, 52); e = 52 - e; // -18 < e < 122 // x = z / 2 ^ e if (e > 0) { toFixedHelpers.multiply(0, z); j = f; while (j >= 7) { toFixedHelpers.multiply(10000000, 0); j -= 7; } toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0); j = e - 1; while (j >= 23) { toFixedHelpers.divide(1 << 23); j -= 23; } toFixedHelpers.divide(1 << j); toFixedHelpers.multiply(1, 1); toFixedHelpers.divide(2); m = toFixedHelpers.numToString(); } else { toFixedHelpers.multiply(0, z); toFixedHelpers.multiply(1 << -e, 0); m = toFixedHelpers.numToString() + '0.00000000000000000000'.slice(2, 2 + f); } } if (f > 0) { k = m.length; if (k <= f) { m = s + '0.0000000000000000000'.slice(0, f - k + 2) + m; } else { m = s + m.slice(0, k - f) + '.' + m.slice(k - f); } } else { m = s + m; } return m; } }, hasToFixedBugs); // // String // ====== // // ES5 15.5.4.14 // http://es5.github.com/#x15.5.4.14 // [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers] // Many browsers do not split properly with regular expressions or they // do not perform the split correctly under obscure conditions. // See http://blog.stevenlevithan.com/archives/cross-browser-split // I've tested in many browsers and this seems to cover the deviant ones: // 'ab'.split(/(?:ab)*/) should be ["", ""], not [""] // '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""] // 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not // [undefined, "t", undefined, "e", ...] // ''.split(/.?/) should be [], not [""] // '.'.split(/()()/) should be ["."], not ["", "", "."] var string_split = StringPrototype.split; if ('ab'.split(/(?:ab)*/).length !== 2 || '.'.split(/(.?)(.?)/).length !== 4 || 'tesst'.split(/(s)*/)[1] === 't' || 'test'.split(/(?:)/, -1).length !== 4 || ''.split(/.?/).length || '.'.split(/()()/).length > 1) { (function () { var compliantExecNpcg = /()??/.exec('')[1] === void 0; // NPCG: nonparticipating capturing group StringPrototype.split = function (separator, limit) { var string = this; if (separator === void 0 && limit === 0) { return []; } // If `separator` is not a regex, use native split if (_toString.call(separator) !== '[object RegExp]') { return string_split.call(this, separator, limit); } var output = [], flags = (separator.ignoreCase ? 'i' : '') + (separator.multiline ? 'm' : '') + (separator.extended ? 'x' : '') + (separator.sticky ? 'y' : ''), // Firefox 3+ lastLastIndex = 0, // Make `global` and avoid `lastIndex` issues by working with a copy separator2, match, lastIndex, lastLength; separator = new RegExp(separator.source, flags + 'g'); string += ''; // Type-convert if (!compliantExecNpcg) { // Doesn't need flags gy, but they don't hurt separator2 = new RegExp('^' + separator.source + '$(?!\\s)', flags); } /* Values for `limit`, per the spec: * If undefined: 4294967295 // Math.pow(2, 32) - 1 * If 0, Infinity, or NaN: 0 * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296; * If negative number: 4294967296 - Math.floor(Math.abs(limit)) * If other: Type-convert, then use the above rules */ limit = limit === void 0 ? -1 >>> 0 : // Math.pow(2, 32) - 1 ToUint32(limit); while (match = separator.exec(string)) { // `separator.lastIndex` is not reliable cross-browser lastIndex = match.index + match[0].length; if (lastIndex > lastLastIndex) { output.push(string.slice(lastLastIndex, match.index)); // Fix browsers whose `exec` methods don't consistently return `undefined` for // nonparticipating capturing groups if (!compliantExecNpcg && match.length > 1) { match[0].replace(separator2, function () { for (var i = 1; i < arguments.length - 2; i++) { if (arguments[i] === void 0) { match[i] = void 0; } } }); } if (match.length > 1 && match.index < string.length) { ArrayPrototype.push.apply(output, match.slice(1)); } lastLength = match[0].length; lastLastIndex = lastIndex; if (output.length >= limit) { break; } } if (separator.lastIndex === match.index) { separator.lastIndex++; // Avoid an infinite loop } } if (lastLastIndex === string.length) { if (lastLength || !separator.test('')) { output.push(''); } } else { output.push(string.slice(lastLastIndex)); } return output.length > limit ? output.slice(0, limit) : output; }; }()); // [bugfix, chrome] // If separator is undefined, then the result array contains just one String, // which is the this value (converted to a String). If limit is not undefined, // then the output array is truncated so that it contains no more than limit // elements. // "0".split(undefined, 0) -> [] } else if ('0'.split(void 0, 0).length) { StringPrototype.split = function split(separator, limit) { if (separator === void 0 && limit === 0) { return []; } return string_split.call(this, separator, limit); }; } var str_replace = StringPrototype.replace; var replaceReportsGroupsCorrectly = function () { var groups = []; 'x'.replace(/x(.)?/g, function (match, group) { groups.push(group); }); return groups.length === 1 && typeof groups[0] === 'undefined'; }(); if (!replaceReportsGroupsCorrectly) { StringPrototype.replace = function replace(searchValue, replaceValue) { var isFn = isFunction(replaceValue); var hasCapturingGroups = isRegex(searchValue) && /\)[*?]/.test(searchValue.source); if (!isFn || !hasCapturingGroups) { return str_replace.call(this, searchValue, replaceValue); } else { var wrappedReplaceValue = function (match) { var length = arguments.length; var originalLastIndex = searchValue.lastIndex; searchValue.lastIndex = 0; var args = searchValue.exec(match) || []; searchValue.lastIndex = originalLastIndex; args.push(arguments[length - 2], arguments[length - 1]); return replaceValue.apply(this, args); }; return str_replace.call(this, searchValue, wrappedReplaceValue); } }; } // ECMA-262, 3rd B.2.3 // Not an ECMAScript standard, although ECMAScript 3rd Edition has a // non-normative section suggesting uniform semantics and it should be // normalized across all browsers // [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE var string_substr = StringPrototype.substr; var hasNegativeSubstrBug = ''.substr && '0b'.substr(-1) !== 'b'; defineProperties(StringPrototype, { substr: function substr(start, length) { return string_substr.call(this, start < 0 ? (start = this.length + start) < 0 ? 0 : start : start, length); } }, hasNegativeSubstrBug); // ES5 15.5.4.20 // whitespace from: http://es5.github.io/#x15.5.4.20 var ws = '\t\n\x0B\f\r \xA0\u1680\u180E\u2000\u2001\u2002\u2003' + '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' + '\u2029\uFEFF'; var zeroWidth = '\u200B'; var wsRegexChars = '[' + ws + ']'; var trimBeginRegexp = new RegExp('^' + wsRegexChars + wsRegexChars + '*'); var trimEndRegexp = new RegExp(wsRegexChars + wsRegexChars + '*$'); var hasTrimWhitespaceBug = StringPrototype.trim && (ws.trim() || !zeroWidth.trim()); defineProperties(StringPrototype, { // http://blog.stevenlevithan.com/archives/faster-trim-javascript // http://perfectionkills.com/whitespace-deviations/ trim: function trim() { if (this === void 0 || this === null) { throw new TypeError('can\'t convert ' + this + ' to object'); } return String(this).replace(trimBeginRegexp, '').replace(trimEndRegexp, ''); } }, hasTrimWhitespaceBug); // ES-5 15.1.2.2 if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) { parseInt = function (origParseInt) { var hexRegex = /^0[xX]/; return function parseIntES5(str, radix) { str = String(str).trim(); if (!Number(radix)) { radix = hexRegex.test(str) ? 16 : 10; } return origParseInt(str, radix); }; }(parseInt); } })); /*! * https://github.com/es-shims/es5-shim * @license es5-shim Copyright 2009-2014 by contributors, MIT License * see https://github.com/es-shims/es5-shim/blob/master/LICENSE */ // vim: ts=4 sts=4 sw=4 expandtab //Add semicolon to prevent IIFE from being passed as argument to concated code. // UMD (Universal Module Definition) // see https://github.com/umdjs/umd/blob/master/returnExports.js (function (root, factory) { if (true) { // AMD. Register as an anonymous module. es5Sham = function () { return typeof factory === 'function' ? factory() : factory; }(); } else if (typeof exports === 'object') { // Node. Does not work with strict CommonJS, but // only CommonJS-like enviroments that support module.exports, // like Node. module.exports = factory(); } else { // Browser globals (root is window) root.returnExports = factory(); } }(this, function () { var call = Function.prototype.call; var prototypeOfObject = Object.prototype; var owns = call.bind(prototypeOfObject.hasOwnProperty); // If JS engine supports accessors creating shortcuts. var defineGetter; var defineSetter; var lookupGetter; var lookupSetter; var supportsAccessors = owns(prototypeOfObject, '__defineGetter__'); if (supportsAccessors) { defineGetter = call.bind(prototypeOfObject.__defineGetter__); defineSetter = call.bind(prototypeOfObject.__defineSetter__); lookupGetter = call.bind(prototypeOfObject.__lookupGetter__); lookupSetter = call.bind(prototypeOfObject.__lookupSetter__); } // ES5 15.2.3.2 // http://es5.github.com/#x15.2.3.2 if (!Object.getPrototypeOf) { // https://github.com/es-shims/es5-shim/issues#issue/2 // http://ejohn.org/blog/objectgetprototypeof/ // recommended by fschaefer on github // // sure, and webreflection says ^_^ // ... this will nerever possibly return null // ... Opera Mini breaks here with infinite loops Object.getPrototypeOf = function getPrototypeOf(object) { var proto = object.__proto__; if (proto || proto === null) { return proto; } else if (object.constructor) { return object.constructor.prototype; } else { return prototypeOfObject; } }; } //ES5 15.2.3.3 //http://es5.github.com/#x15.2.3.3 function doesGetOwnPropertyDescriptorWork(object) { try { object.sentinel = 0; return Object.getOwnPropertyDescriptor(object, 'sentinel').value === 0; } catch (exception) { } } //check whether getOwnPropertyDescriptor works if it's given. Otherwise, //shim partially. if (Object.defineProperty) { var getOwnPropertyDescriptorWorksOnObject = doesGetOwnPropertyDescriptorWork({}); var getOwnPropertyDescriptorWorksOnDom = typeof document === 'undefined' || doesGetOwnPropertyDescriptorWork(document.createElement('div')); if (!getOwnPropertyDescriptorWorksOnDom || !getOwnPropertyDescriptorWorksOnObject) { var getOwnPropertyDescriptorFallback = Object.getOwnPropertyDescriptor; } } if (!Object.getOwnPropertyDescriptor || getOwnPropertyDescriptorFallback) { var ERR_NON_OBJECT = 'Object.getOwnPropertyDescriptor called on a non-object: '; Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) { if (typeof object !== 'object' && typeof object !== 'function' || object === null) { throw new TypeError(ERR_NON_OBJECT + object); } // make a valiant attempt to use the real getOwnPropertyDescriptor // for I8's DOM elements. if (getOwnPropertyDescriptorFallback) { try { return getOwnPropertyDescriptorFallback.call(Object, object, property); } catch (exception) { } } // If object does not owns property return undefined immediately. if (!owns(object, property)) { return; } // If object has a property then it's for sure both `enumerable` and // `configurable`. var descriptor = { enumerable: true, configurable: true }; // If JS engine supports accessor properties then property may be a // getter or setter. if (supportsAccessors) { // Unfortunately `__lookupGetter__` will return a getter even // if object has own non getter property along with a same named // inherited getter. To avoid misbehavior we temporary remove // `__proto__` so that `__lookupGetter__` will return getter only // if it's owned by an object. var prototype = object.__proto__; var notPrototypeOfObject = object !== prototypeOfObject; // avoid recursion problem, breaking in Opera Mini when // Object.getOwnPropertyDescriptor(Object.prototype, 'toString') // or any other Object.prototype accessor if (notPrototypeOfObject) { object.__proto__ = prototypeOfObject; } var getter = lookupGetter(object, property); var setter = lookupSetter(object, property); if (notPrototypeOfObject) { // Once we have getter and setter we can put values back. object.__proto__ = prototype; } if (getter || setter) { if (getter) { descriptor.get = getter; } if (setter) { descriptor.set = setter; } // If it was accessor property we're done and return here // in order to avoid adding `value` to the descriptor. return descriptor; } } // If we got this far we know that object has an own property that is // not an accessor so we set it as a value and return descriptor. descriptor.value = object[property]; descriptor.writable = true; return descriptor; }; } // ES5 15.2.3.4 // http://es5.github.com/#x15.2.3.4 if (!Object.getOwnPropertyNames) { Object.getOwnPropertyNames = function getOwnPropertyNames(object) { return Object.keys(object); }; } // ES5 15.2.3.5 // http://es5.github.com/#x15.2.3.5 if (!Object.create) { // Contributed by Brandon Benvie, October, 2012 var createEmpty; var supportsProto = !({ __proto__: null } instanceof Object); // the following produces false positives // in Opera Mini => not a reliable check // Object.prototype.__proto__ === null if (supportsProto || typeof document === 'undefined') { createEmpty = function () { return { '__proto__': null }; }; } else { // In old IE __proto__ can't be used to manually set `null`, nor does // any other method exist to make an object that inherits from nothing, // aside from Object.prototype itself. Instead, create a new global // object and *steal* its Object.prototype and strip it bare. This is // used as the prototype to create nullary objects. createEmpty = function () { var iframe = document.createElement('iframe'); var parent = document.body || document.documentElement; iframe.style.display = 'none'; parent.appendChild(iframe); iframe.src = 'javascript:'; var empty = iframe.contentWindow.Object.prototype; parent.removeChild(iframe); iframe = null; delete empty.constructor; delete empty.hasOwnProperty; delete empty.propertyIsEnumerable; delete empty.isPrototypeOf; delete empty.toLocaleString; delete empty.toString; delete empty.valueOf; empty.__proto__ = null; function Empty() { } Empty.prototype = empty; // short-circuit future calls createEmpty = function () { return new Empty(); }; return new Empty(); }; } Object.create = function create(prototype, properties) { var object; function Type() { } // An empty constructor. if (prototype === null) { object = createEmpty(); } else { if (typeof prototype !== 'object' && typeof prototype !== 'function') { // In the native implementation `parent` can be `null` // OR *any* `instanceof Object` (Object|Function|Array|RegExp|etc) // Use `typeof` tho, b/c in old IE, DOM elements are not `instanceof Object` // like they are in modern browsers. Using `Object.create` on DOM elements // is...err...probably inappropriate, but the native version allows for it. throw new TypeError('Object prototype may only be an Object or null'); // same msg as Chrome } Type.prototype = prototype; object = new Type(); // IE has no built-in implementation of `Object.getPrototypeOf` // neither `__proto__`, but this manually setting `__proto__` will // guarantee that `Object.getPrototypeOf` will work as expected with // objects created using `Object.create` object.__proto__ = prototype; } if (properties !== void 0) { Object.defineProperties(object, properties); } return object; }; } // ES5 15.2.3.6 // http://es5.github.com/#x15.2.3.6 // Patch for WebKit and IE8 standard mode // Designed by hax // related issue: https://github.com/es-shims/es5-shim/issues#issue/5 // IE8 Reference: // http://msdn.microsoft.com/en-us/library/dd282900.aspx // http://msdn.microsoft.com/en-us/library/dd229916.aspx // WebKit Bugs: // https://bugs.webkit.org/show_bug.cgi?id=36423 function doesDefinePropertyWork(object) { try { Object.defineProperty(object, 'sentinel', {}); return 'sentinel' in object; } catch (exception) { } } // check whether defineProperty works if it's given. Otherwise, // shim partially. if (Object.defineProperty) { var definePropertyWorksOnObject = doesDefinePropertyWork({}); var definePropertyWorksOnDom = typeof document === 'undefined' || doesDefinePropertyWork(document.createElement('div')); if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) { var definePropertyFallback = Object.defineProperty, definePropertiesFallback = Object.defineProperties; } } if (!Object.defineProperty || definePropertyFallback) { var ERR_NON_OBJECT_DESCRIPTOR = 'Property description must be an object: '; var ERR_NON_OBJECT_TARGET = 'Object.defineProperty called on non-object: '; var ERR_ACCESSORS_NOT_SUPPORTED = 'getters & setters can not be defined ' + 'on this javascript engine'; Object.defineProperty = function defineProperty(object, property, descriptor) { if (typeof object !== 'object' && typeof object !== 'function' || object === null) { throw new TypeError(ERR_NON_OBJECT_TARGET + object); } if (typeof descriptor !== 'object' && typeof descriptor !== 'function' || descriptor === null) { throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor); } // make a valiant attempt to use the real defineProperty // for I8's DOM elements. if (definePropertyFallback) { try { return definePropertyFallback.call(Object, object, property, descriptor); } catch (exception) { } } // If it's a data property. if (owns(descriptor, 'value')) { // fail silently if "writable", "enumerable", or "configurable" // are requested but not supported /* // alternate approach: if ( // can't implement these features; allow false but not true !(owns(descriptor, "writable") ? descriptor.writable : true) || !(owns(descriptor, "enumerable") ? descriptor.enumerable : true) || !(owns(descriptor, "configurable") ? descriptor.configurable : true) ) throw new RangeError( "This implementation of Object.defineProperty does not " + "support configurable, enumerable, or writable." ); */ if (supportsAccessors && (lookupGetter(object, property) || lookupSetter(object, property))) { // As accessors are supported only on engines implementing // `__proto__` we can safely override `__proto__` while defining // a property to make sure that we don't hit an inherited // accessor. var prototype = object.__proto__; object.__proto__ = prototypeOfObject; // Deleting a property anyway since getter / setter may be // defined on object itself. delete object[property]; object[property] = descriptor.value; // Setting original `__proto__` back now. object.__proto__ = prototype; } else { object[property] = descriptor.value; } } else { if (!supportsAccessors) { throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED); } // If we got that far then getters and setters can be defined !! if (owns(descriptor, 'get')) { defineGetter(object, property, descriptor.get); } if (owns(descriptor, 'set')) { defineSetter(object, property, descriptor.set); } } return object; }; } // ES5 15.2.3.7 // http://es5.github.com/#x15.2.3.7 if (!Object.defineProperties || definePropertiesFallback) { Object.defineProperties = function defineProperties(object, properties) { // make a valiant attempt to use the real defineProperties if (definePropertiesFallback) { try { return definePropertiesFallback.call(Object, object, properties); } catch (exception) { } } for (var property in properties) { if (owns(properties, property) && property !== '__proto__') { Object.defineProperty(object, property, properties[property]); } } return object; }; } // ES5 15.2.3.8 // http://es5.github.com/#x15.2.3.8 if (!Object.seal) { Object.seal = function seal(object) { // this is misleading and breaks feature-detection, but // allows "securable" code to "gracefully" degrade to working // but insecure code. return object; }; } // ES5 15.2.3.9 // http://es5.github.com/#x15.2.3.9 if (!Object.freeze) { Object.freeze = function freeze(object) { // this is misleading and breaks feature-detection, but // allows "securable" code to "gracefully" degrade to working // but insecure code. return object; }; } // detect a Rhino bug and patch it try { Object.freeze(function () { }); } catch (exception) { Object.freeze = function freeze(freezeObject) { return function freeze(object) { if (typeof object === 'function') { return object; } else { return freezeObject(object); } }; }(Object.freeze); } // ES5 15.2.3.10 // http://es5.github.com/#x15.2.3.10 if (!Object.preventExtensions) { Object.preventExtensions = function preventExtensions(object) { // this is misleading and breaks feature-detection, but // allows "securable" code to "gracefully" degrade to working // but insecure code. return object; }; } // ES5 15.2.3.11 // http://es5.github.com/#x15.2.3.11 if (!Object.isSealed) { Object.isSealed = function isSealed(object) { return false; }; } // ES5 15.2.3.12 // http://es5.github.com/#x15.2.3.12 if (!Object.isFrozen) { Object.isFrozen = function isFrozen(object) { return false; }; } // ES5 15.2.3.13 // http://es5.github.com/#x15.2.3.13 if (!Object.isExtensible) { Object.isExtensible = function isExtensible(object) { // 1. If Type(O) is not Object throw a TypeError exception. if (Object(object) !== object) { throw new TypeError(); // TODO message } // 2. Return the Boolean value of the [[Extensible]] internal property of O. var name = ''; while (owns(object, name)) { name += '?'; } object[name] = true; var returnValue = owns(object, name); delete object[name]; return returnValue; }; } })); (function () { var object = typeof exports != 'undefined' ? exports : this, // #8: web workers chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=', INVALID_CHARACTER_ERR = function () { // fabricate a suitable error object try { document.createElement('$'); } catch (error) { return error; } }(); // encoder // [https://gist.github.com/999166] by [https://github.com/nignag] object.btoa || (object.btoa = function (input) { for (// initialize result and counter var block, charCode, idx = 0, map = chars, output = ''; // if the next input index does not exist: // change the mapping table to "=" // check if d has no fractional digits input.charAt(idx | 0) || (map = '=', idx % 1); // "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8 output += map.charAt(63 & block >> 8 - idx % 1 * 8)) { charCode = input.charCodeAt(idx += 3 / 4); if (charCode > 255) throw INVALID_CHARACTER_ERR; block = block << 8 | charCode; } return output; }); // decoder // [https://gist.github.com/1020396] by [https://github.com/atk] object.atob || (object.atob = function (input) { input = input.replace(/=+$/, ''); if (input.length % 4 == 1) throw INVALID_CHARACTER_ERR; for (// initialize result and counters var bc = 0, bs, buffer, idx = 0, output = ''; // get next character buffer = input.charAt(idx++); // character found in table? initialize bit storage and add its ascii value; ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer, // and if not first of each 4 characters, // convert the first 8 bits to one ascii character bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0) { // try to find character in table (0-63, not found => -1) buffer = chars.indexOf(buffer); } return output; }); }()); base64 = undefined; polyFills = undefined; core = function (gaTracker, Events, polyFills) { var compId, deviceType, queryMap, readyQ; var isReady = false; var version = '1.41.0'; var EventsCallbacks = {}; var callbacks = {}; var callId = 1; var MessageTypes = { REFRESH_APP: 'refreshApp', APP_IS_ALIVE: 'appIsAlive', APP_STATE_CHANGED: 'appStateChanged', CLOSE_WINDOW: 'closeWindow', RESIZE_WINDOW: 'resizeWindow', SET_WINDOW_PLACEMENT: 'setWindowPlacement', GET_WINDOW_PLACEMENT: 'getWindowPlacement', OPEN_POPUP: 'openPopup', OPEN_MODAL: 'openModal', OPEN_MEDIA_DIALOG: 'openMediaDialog', OPEN_BILLING_PAGE: 'openBillingPage', GET_SITE_PAGES: 'getSitePages', GET_SITE_COLORS: 'getSiteColors', GET_USER_SESSION: 'getUserSession', NAVIGATE_TO_PAGE: 'navigateToPage', POST_MESSAGE: 'postMessage', HEIGHT_CHANGED: 'heightChanged', NAVIGATE_TO_STATE: 'navigateToState', SM_REQUEST_LOGIN: 'smRequestLogin', SM_CURRENT_MEMBER: 'smCurrentMember', SITE_INFO: 'siteInfo', BOUNDING_RECT_AND_OFFSETS: 'boundingRectAndOffsets', SCROLL_TO: 'scrollTo', SCROLL_BY: 'scrollBy', SET_STYLE_PARAM: 'setStyleParam', GET_STYLE_PARAMS: 'getStyleParams', REGISTER_EVENT_LISTENER: 'registerEventListener', REMOVE_EVENT_LISTENER: 'removeEventListener', PUBLISH: 'publish', GET_CONTACT_BY_ID: 'getContactById', GET_CONTACTS: 'getContacts', CREATE_CONTACT: 'createContact', GET_ACTIVITY_BY_ID: 'getActivityById', GET_ACTIVITIES: 'getActivities', POST_ACTIVITY: 'postActivity', NAVIGATE_TO_SECTION_PAGE: 'navigateToSectionPage', GET_CURRENT_PAGE_ID: 'getCurrentPageId', GET_CONTACT_LABELS: 'getContactLabels', GET_DASHBOARD_APP_URL: 'getDashboardAppUrl', GET_EDITOR_URL: 'getEditorUrl', SETTINGS_OPEN_MODAL: 'settingsOpenModal', GET_SECTION_URL: 'getSectionUrl', OPEN_BILLING_PAGE_FOR_PRODUCT: 'openBillingPageForProduct', GET_BILLING_PAGE_FOR_PRODUCT: 'getBillingPageForProduct', GET_ACTIVE_BILLING_PACKAGE: 'getActiveBillingPackage', GET_BILLING_PACKAGES: 'getBillingPackages' }; var styles = { mappedColors: null, siteColors: null, style: null, siteTextPresets: null, fontsMeta: null, fontsSpriteUrl: null, mappedFonts: null }; var currentEditMode = 'site'; var init = function (opts) { // initialize google analytics gaTracker.gaInit(); // initialize error tracking logic errorTrackingInit(); // get our comp id compId = getQueryParameter('compId') || '[UNKNOWN]'; deviceType = getQueryParameter('deviceType') || 'desktop'; // register post message hub function addPostMessageCallback(receiver); // initialize edit mode state tracking currentEditMode = getQueryParameter('viewMode') || currentEditMode; addEventListenerInternal('EDIT_MODE_CHANGE', function (params) { currentEditMode = params.editMode; }); if (opts && opts.endpointType !== 'worker') { // report ready to Wix sendMessage(MessageTypes.APP_IS_ALIVE, { version: getVersion() }, initStyle); } }; var receiver = function (event) { if (!event || !event.data) { return; } var data = {}; try { data = JSON.parse(event.data); } catch (e) { return; } switch (data.intent) { case 'TPA_RESPONSE': if (data.callId && callbacks[data.callId]) { callbacks[data.callId](data.res); delete callbacks[data.callId]; } break; case 'addEventListener': callEventListeners(data); break; } }; var getDecodedInstance = function () { var instanceStr = getQueryParameter('instance'); var encodedInstance = instanceStr.substring(instanceStr.indexOf('.') + 1); return JSON.parse(decodeBase64(encodedInstance)); }; var getInstanceValue = function (key) { var decodedInstance = getDecodedInstance(); if (decodedInstance) { return decodedInstance[key] || null; } return null; }; var decodeBase64 = function (str) { return atob(str); }; var initStyle = function (params) { var primeColorsReferences = [ 'white/black', 'black/white', 'primery-1', 'primery-2', 'primery-3' ]; function mapColors(colors, styleColors) { var colorMap = {}; var y = 1; var index; for (var i = 0; i < colors.length; i++) { index = +colors[i].name.split('_').pop(); if (index <= 5) { colors[i].reference = primeColorsReferences[i]; colorMap[primeColorsReferences[i]] = colors[i]; } else if (index > 10) { colors[i].reference = 'color-' + y; colorMap['color-' + y] = colors[i]; y++; } } for (var color in styleColors) { if (styleColors.hasOwnProperty(color)) { colorMap['style.' + color] = styleColors[color]; } } return colorMap; } function mapFonts(fonts) { if (!fonts) { return; } var mappedFonts = {}; for (var font in fonts) { if (fonts.hasOwnProperty(font)) { mappedFonts['style.' + font] = fonts[font]; } } return mappedFonts; } function evalTemplate(str, data, getter) { getter = getter || function (data, key) { return data[key]; }; return str.replace(/\{\{([^}]+)\}\}/gim, function (fullmatch, key) { var val = fullmatch; var keysInFallbackOrder = key.split(/\s+/); for (var i = 0; i < keysInFallbackOrder.length; i++) { if (keysInFallbackOrder.length === 0) { continue; } try { val = getter(data, keysInFallbackOrder[i]); if (val !== undefined) { return val; } else if (i === keysInFallbackOrder.length - 1) { return keysInFallbackOrder[i]; } } catch (e) { try { console.log('Warning: could not find key "' + keysInFallbackOrder[i] + '" for match "' + fullmatch + '"'); } catch (err) { } } } return fullmatch; }); } function findEndOfMediaQueryIndex(startIndex, styleTpl) { var memIndex = 0; var index = startIndex; var currentChar; for (; index < styleTpl.length; index++) { currentChar = styleTpl.charAt(index); if (currentChar === '{') { memIndex += 1; } if (currentChar === '}') { memIndex -= 1; } if (memIndex < 0) { index++; break; } } return index; } function applyWixMediaQuery(cssText, currentMediaType) { var endIndex, id, start, end, mediaQuery, match, panic = 100000, rndId = Math.random(), mediaRegExp = /@media\s*\(\s*wix-device-type\s*:\s*(\w+)\s*\)\s*\{/m, mediaQueries = []; while (true) { if (panic-- < 0) { return mediaQueries; } match = cssText.match(mediaRegExp); if (match) { endIndex = findEndOfMediaQueryIndex(match.index + match[0].length, cssText); id = '/*** wix-media ' + rndId + '$' + mediaQueries.length + ' ***/'; mediaQuery = cssText.slice(match.index, endIndex); cssText = cssText.replace(mediaQuery, id); start = mediaQuery.indexOf('{'); end = mediaQuery.lastIndexOf('}'); mediaQueries.push({ id: id, mediaQuery: mediaQuery.slice(start + 1, end - 1), mediaType: match[1] }); } else { break; } } mediaQueries.forEach(function (media) { if (media.mediaType === currentMediaType) { cssText = cssText.replace(media.id, media.id + media.mediaQuery); } else { cssText = cssText.replace(media.id, ''); } }); return cssText; } function getValueForTemplate(styles, keyName) { return (styles.mappedColors ? styles.mappedColors[keyName] ? styles.mappedColors[keyName].value : undefined : undefined) || (styles.mappedFonts ? styles.mappedFonts[keyName] ? styles.mappedFonts[keyName].value : undefined : undefined) || (styles.siteTextPresets ? styles.siteTextPresets[keyName] ? styles.siteTextPresets[keyName].value : undefined : undefined); } function updateStyleElement(ownerNode) { if (ownerNode && ownerNode.hasAttribute('wix-style')) { if (!ownerNode._wixTemplate) { if (ownerNode.nodeName.toLowerCase() === 'link') { throw new TypeError('"wix-style" is not supported on link elements, use inline style inside the document head'); } else { ownerNode._wixTemplate = ownerNode.textContent; } } ownerNode.textContent = evalTemplate(applyWixMediaQuery(ownerNode._wixTemplate, getQueryParameter('deviceType') || 'desktop'), styles, getValueForTemplate); } } function updateCSSStyleSheets() { var styles = document.getElementsByTagName('style'); //document.styleSheets for (var i = 0; i < styles.length; i++) { updateStyleElement(styles[i]); } } function createInjectedStyleElement() { var head = document.getElementsByTagName('head')[0]; var text = '.Title{ {{Title}} } .Menu{ {{Menu}} } .Page-title{ {{Page-title}} } .Heading-XL{ {{Heading-XL}} } .Heading-L{ {{Heading-L}} } .Heading-M{ {{Heading-M}} } .Heading-S{ {{Heading-S}} } .Body-L{ {{Body-L}} } .Body-M{ {{Body-M}} } .Body-S{ {{Body-S}} } .Body-XS{ {{Body-XS}} } }'; head.insertAdjacentHTML('afterbegin', '<' + 'sty' + 'le wix-style type="text/css">' + text + ''); } function setReferencesForSavedStyles(style) { for (var prop in style.colors) { if (style.colors.hasOwnProperty(prop)) { var color = style.colors[prop]; if (!color.themeName) { continue; } var editorIndex = +color.themeName.split('_').pop(); if (editorIndex <= 5) { color.themeName = primeColorsReferences[editorIndex - 1]; } else if (editorIndex > 10) { color.themeName = 'color-' + (editorIndex - 10); } } } return style; } function updateStylesCache(params) { cacheGoogleFontsCssUrl(params.style); handleFonts(params.fonts); styles.siteColors = params.siteColors || styles.siteColors; styles.siteTextPresets = params.siteTextPresets || styles.siteTextPresets; styles.fontsMeta = extractFontsMeta(params.fonts) || styles.fontsMeta; styles.style = params.style ? setReferencesForSavedStyles(params.style) : styles.style; styles.mappedColors = mapColors(styles.siteColors, styles.style.colors); styles.mappedFonts = mapFonts(styles.style.fonts); } function extractFontsMeta(fonts) { if (!fonts) { return null; } return fonts.fontsMeta; } function appendLinkToHead(url, id) { var head = document.getElementsByTagName('head')[0]; var link = document.createElement('link'); link.setAttribute('type', 'text/css'); link.setAttribute('rel', 'stylesheet'); link.setAttribute('href', url); if (typeof id === 'string') { link.id = id; } head.appendChild(link); return link; } function updateGoogleFontsLink(url) { var elToRemove; if (!url) { return; } if (updateGoogleFontsLink.$linkElement && updateGoogleFontsLink.$linkElement.getAttribute('href') === url) { return; } else if (updateGoogleFontsLink.$linkElement) { elToRemove = updateGoogleFontsLink.$linkElement; setTimeout(function () { if (elToRemove.parentNode) { elToRemove.parentNode.removeChild(elToRemove); } elToRemove = null; }, 5000); } updateGoogleFontsLink.$linkElement = appendLinkToHead(url, 'wix-google-fonts'); } function cacheGoogleFontsCssUrl(fonts) { styles.googleFontsCssUrl = fonts && fonts.googleFontsCssUrl || styles.googleFontsCssUrl; } addEventListenerInternal(Events.THEME_CHANGE, function (params) { updateStylesCache(params); callEventListeners({ params: styles.style, eventType: Events.STYLE_PARAMS_CHANGE }, 'internal'); }); addEventListenerInternal(Events.STYLE_PARAMS_CHANGE, function (params, typeOfCall) { if (typeOfCall !== 'internal') { updateStylesCache({ style: params }); } updateGoogleFontsLink(styles.googleFontsCssUrl); updateCSSStyleSheets(); }); function handleFonts(fonts) { if (!fonts) { return; } var links = document.getElementsByTagName('link'); fonts.cssUrls.forEach(function (url) { for (var i = 0; i < links.length; i++) { if (links[i].getAttribute('href') === url) { return; } } appendLinkToHead(url); }); styles.fontsSpriteUrl = fonts.imageSpriteUrl; } createInjectedStyleElement(); updateStylesCache(params); updateGoogleFontsLink(styles.googleFontsCssUrl); updateCSSStyleSheets(); setReady(); }; var callEventListeners = function (data, typeOfCall) { trackEventCall(data.eventType); if (EventsCallbacks[data.eventType]) { EventsCallbacks[data.eventType].forEach(function (callbackHandler) { callbackHandler.callback.call(this, data.params, typeOfCall); }); } }; var trackEventCall = function (eventName) { gaTracker.gaTrackEvent('Event', eventName); }; var setReady = function () { isReady = true; callReadyQ(); }; var callReadyQ = function () { if (isReady && readyQ) { for (var i = 0; i < readyQ.length; i++) { readyQ[i].call(null); } } }; var addToReadyQ = function (action) { readyQ = readyQ || []; readyQ.push(action); }; var getVersion = function () { var version = !!version ? version : window.location.pathname.split('/')[3] || 'unknown'; return version; }; var getCallId = function () { return callId++; }; var addEventListenerInternal = function (eventKey, callBack, skipValidation, params) { if (!skipValidation && (!eventKey || !Events.hasOwnProperty(eventKey))) { reportSdkError('Unsupported event name, ' + eventKey); return; } var id = getCallId(); EventsCallbacks[eventKey] = EventsCallbacks[eventKey] || []; EventsCallbacks[eventKey].push({ callback: callBack, id: id }); //params can be used as override params for the event to add more functionality params = params || {}; params.eventKey = eventKey; sendMessage(MessageTypes.REGISTER_EVENT_LISTENER, params, handleAddEventListenerResponse.bind(null, callBack)); return id; }; var handleAddEventListenerResponse = function (callback, event) { if (event.drain) { event.data.forEach(function (data) { callback(data); }, null); } }; var removeEventListenerInternal = function (eventName, callBackOrId, skipValidation) { if (!skipValidation && (!eventName || !Events.hasOwnProperty(eventName))) { reportSdkError('Unsupported event name, ' + eventName); return; } var i = -1; var eventCallbacks = EventsCallbacks[eventName]; if (eventCallbacks) { for (var y = 0; y < eventCallbacks.length; y++) { if (eventCallbacks[y].callback === callBackOrId || eventCallbacks[y].id === callBackOrId) { i = y; break; } } if (i !== -1) { eventCallbacks.splice(i, 1); } } if (i >= 0 && eventCallbacks.length === 0) { sendMessage(MessageTypes.REMOVE_EVENT_LISTENER, eventName); } }; var addPostMessageCallback = function (callback) { window.addEventListener('message', callback, false); }; var getQueryParameter = function (parameterName) { if (!queryMap) { queryMap = {}; var queryString = location.search.substring(1) || ''; var queryArray = queryString.split('&'); queryArray.forEach(function (element) { var parts = element.split('='); queryMap[parts[0]] = decodeURIComponent(parts[1]); }); } return queryMap[parameterName] || null; }; var errorTrackingInit = function () { var event = 'onerror'; var listener = errorHandler; window.addEventListener(event.replace(/^on/, ''), listener, false); }; var errorHandler = function (errorMsg, url, lineNumber) { trackError(errorMsg, lineNumber); return false; }; var trackError = function (errorMessage) { gaTracker.gaTrackEvent('Error', errorMessage); }; var reportSdkError = function (errorMessage) { var error = new TypeError('Wix SDK: ' + errorMessage); throw error.stack; }; var reportSdkMsg = function (message) { log(new TypeError('Wix SDK: ' + message)); }; var log = function (text) { if (window.console) { window.console.log(text); } }; var sendMessage = function (msgType, params, callback) { if (!msgType) { return; } var blob = getBlob(msgType, params, callback); var target = parent.postMessage ? parent : parent.document.postMessage ? parent.document : undefined; if (target && typeof target !== 'undefined') { var dataStr = ''; try { dataStr = JSON.stringify(params); } catch (err) { } target.postMessage(JSON.stringify(blob), '*'); gaTracker.trackSDKCall(msgType, dataStr); } }; var getBlob = function (msgType, params, onResponseCallback) { var blob = { intent: 'TPA2', callId: getCallId(), type: msgType, compId: compId, deviceType: deviceType, data: params }; if (onResponseCallback) { callbacks[blob.callId] = onResponseCallback; } return blob; }; var getCompId = function () { return compId; }; var getCurrentEditMode = function () { return currentEditMode; }; return { init: init, sendMessage: sendMessage, reportSdkError: reportSdkError, reportSdkMsg: reportSdkMsg, MessageTypes: MessageTypes, getCurrentEditMode: getCurrentEditMode, Styles: styles, getQueryParameter: getQueryParameter, addToReadyQ: addToReadyQ, getCompId: getCompId, getInstanceValue: getInstanceValue, addEventListenerInternal: addEventListenerInternal, removeEventListenerInternal: removeEventListenerInternal }; }(gaTracker, Events, polyFills); /** * This is the description for the Media namespace. * @memberof Wix.Utils * @namespace Wix.Utils.Media */ Media = function (core, gaTracker) { var getImageUrl = function (relativeUrl) { gaTracker.trackSDKCall('Utils.Media.getImageUrl'); return 'http://static.wix.com/media/' + relativeUrl; }; var getResizedImageUrl = function (relativeUrl, width, height, sharpParams) { gaTracker.trackSDKCall('Utils.Media.getResizedImageUrl'); // assign sharp default parameters sharpParams = sharpParams || {}; sharpParams.quality = sharpParams.quality || 75; sharpParams.resizaFilter = sharpParams.resizaFilter || 22; sharpParams.usm_r = sharpParams.usm_r || 0.5; sharpParams.usm_a = sharpParams.usm_a || 1.2; sharpParams.usm_t = sharpParams.usm_t || 0; var urlArr = []; var splitUrl = /[.]([^.]+)$/.exec(relativeUrl); var ext = splitUrl && /[.]([^.]+)$/.exec(relativeUrl)[1] || ''; // build the image url relativeUrl = 'http://static.wix.com/media/' + relativeUrl; urlArr.push(relativeUrl); urlArr.push('srz'); urlArr.push(width); urlArr.push(height); // sharpening parameters urlArr.push(sharpParams.quality); urlArr.push(sharpParams.resizaFilter); urlArr.push(sharpParams.usm_r); urlArr.push(sharpParams.usm_a); urlArr.push(sharpParams.quality); urlArr.push(ext); // get file extension urlArr.push('srz'); return urlArr.join('_'); }; var getAudioUrl = function (relativeUrl) { gaTracker.trackSDKCall('Utils.Media.getAudioUrl'); return 'http://media.wix.com/mp3/' + relativeUrl; }; var getDocumentUrl = function (relativeUrl) { gaTracker.trackSDKCall('Utils.Media.getDocumentUrl'); return 'http://media.wix.com/ugd/' + relativeUrl; }; var getSwfUrl = function (relativeUrl) { gaTracker.trackSDKCall('Utils.Media.getSwfUrl'); return 'http://static.wix.com/media/' + relativeUrl; }; return { /** * This method constructs a URL for a media item of type image. * @function * @memberof Wix.Utils.Media * @since 1.17.0 * @param {String} Image item uri (relative to Wix media gallery). * @returns {String} A full URL pointing to the Wix static servers of an image with the default dimensions - width and height. * @example * * var imageUrl = Wix.Utils.Media.getImageUrl('relative_url.jpg') */ getImageUrl: getImageUrl, /** * This method constructs a URL for a media item of type image and let the developer change the image dimensions as well as it's sharpening properties (optional), * see sharpening explained here - http://en.wikipedia.org/wiki/Unsharp_masking. * @function * @memberof Wix.Utils.Media * @since 1.17.0 * @param {String} relativeUrl Static image url provided by the media dialog. * @param {Number} width Desired image width. * @param {Number} height Desired image height. * @param {Object} [sharpParams] * @param {Number} sharpParams.quality JPEG quality, leave as is (75) unless image size is important for your app. * @param {Number} sharpParams.resizaFilter Resize filter. * @param {Number} sharpParams.usm_r Unsharp mask radius. * @param {Number} sharpParams.usm_a Unsharp mask amount (percentage). * @param {Number} sharpParams.usm_t Unsharp mask threshold. * @returns {String} A full URL pointing to the Wix static servers of an image with the custom dimension parameters. * @example * * var resizedImageUrl = Wix.Utils.Media.getResizedImageUrl('relative_url.jpg', 500, 500) */ getResizedImageUrl: getResizedImageUrl, /** * This method constructs a URL for a media item of type audio. * @function * @memberof Wix.Utils.Media * @since 1.17.0 * @param {String} relativeUri audio item uri (relative to Wix media gallery) * @returns {String} A full URL pointing to the Wix static servers of an audio file with the default dimensions. * @example * * var audioUrl = Wix.Utils.Media.getAudioUrl('relative_url.mp3') */ getAudioUrl: getAudioUrl, /** * This method constructs a URL for a media item of type document. * @function * @memberof Wix.Utils.Media * @since 1.17.0 * @param {String} relativeUri Document item uri (relative to Wix media gallery). * @returns {String} A full URL pointing to the Wix static servers of a document media file with the default dimensions. * @example * * var documentUrl = Wix.Utils.Media.getDocumentUrl('relative_url.pdf') */ getDocumentUrl: getDocumentUrl, /** * This method constructs a URL for a media item of type swf. * @function * @memberof Wix.Utils.Media * @since 1.17.0 * @param {String} relativeUri Swf item uri (relative to Wix media gallery). * @returns {String} A full URL pointing to the Wix static servers of a swf media file with the default dimensions. * @example * * var swfUrl = Wix.Utils.Media.getSwfUrl('relative_url.swf') */ getSwfUrl: getSwfUrl }; }(core, gaTracker); utils = function () { var isString = function (arg) { return typeof arg === 'string'; }; var isFunction = function (arg) { return typeof arg === 'function'; }; var isObject = function (arg) { return typeof arg === 'object'; }; var isNumber = function (arg) { return Object.prototype.toString.call(arg) === '[object Number]'; }; var isPercentValue = function (value) { return Object.prototype.toString.call(value) === '[object String]' && /^[0-9]+%$/.test(value); }; var isArray = Array.isArray || function (obj) { return Object.prototype.toString.call(obj) === '[object Array]'; }; var has = function (obj, key) { return obj !== null && hasOwnProperty.call(obj, key); }; return { isString: isString, isFunction: isFunction, isObject: isObject, isNumber: isNumber, isPercentValue: isPercentValue, isArray: isArray, has: has }; }(); /** * This is the description for the Utils namespace. * @memberof Wix * @namespace Wix.Utils */ Utils = function (core, gaTracker, Media, utils) { var getViewMode = function () { gaTracker.trackSDKCall('Utils.getViewMode'); return window.top === window ? 'standalone' : core.getCurrentEditMode(); }; var toWixDate = function (date) { gaTracker.trackSDKCall('Utils.toWixDate'); return date.toISOString(); }; var getCompId = function () { gaTracker.trackSDKCall('Utils.getCompId'); return core.getCompId(); }; var getOrigCompId = function () { gaTracker.trackSDKCall('Utils.getOrigCompId'); return core.getQueryParameter('origCompId'); }; var getWidth = function () { gaTracker.trackSDKCall('Utils.getWidth'); return core.getQueryParameter('width'); }; var getLocale = function () { gaTracker.trackSDKCall('Utils.getLocale'); return core.getQueryParameter('locale'); }; var getCacheKiller = function () { gaTracker.trackSDKCall('Utils.getCacheKiller'); return core.getQueryParameter('cacheKiller'); }; var getTarget = function () { gaTracker.trackSDKCall('Utils.getTarget'); return core.getQueryParameter('target'); }; var getSectionUrl = function (sectionIdentifier, callback) { gaTracker.trackSDKCall('Utils.getSectionUrl'); if (utils.isObject(sectionIdentifier)) { if (utils.isFunction(callback)) { if (sectionIdentifier.sectionId) { var args = { sectionIdentifier: sectionIdentifier.sectionId }; core.sendMessage(core.MessageTypes.GET_SECTION_URL, args, callback); } else { core.reportSdkError('Wrong arguments - an Object with sectionId must be provided'); } } else { core.reportSdkError('Mandatory arguments - callback must be specified'); } } else { var sectionUrl = core.getQueryParameter('section-url'); return sectionUrl && sectionUrl.replace(/\?$/, ''); } }; var getInstanceId = function () { gaTracker.trackSDKCall('Utils.getInstanceId'); return core.getInstanceValue('instanceId'); }; var getSignDate = function () { gaTracker.trackSDKCall('Utils.getSignDate'); return core.getInstanceValue('signDate'); }; var getUid = function () { gaTracker.trackSDKCall('Utils.getUid'); return core.getInstanceValue('uid'); }; var getPermissions = function () { gaTracker.trackSDKCall('Utils.getPermissions'); return core.getInstanceValue('permissions'); }; var getIpAndPort = function () { gaTracker.trackSDKCall('Utils.getIpAndPort'); return core.getInstanceValue('ipAndPort'); }; var getDemoMode = function () { gaTracker.trackSDKCall('Utils.getDemoMode'); var mode = core.getInstanceValue('demoMode'); mode = mode === null ? false : mode; return mode; }; var getDeviceType = function () { gaTracker.trackSDKCall('Utils.getDeviceType'); return core.getQueryParameter('deviceType') || 'desktop'; }; var navigateToSection = function (sectionIdentifier, state, onFailure) { gaTracker.trackSDKCall('Utils.navigateToSectionPage'); var args; if (utils.isFunction(sectionIdentifier)) { onFailure = sectionIdentifier; } else if (utils.isString(sectionIdentifier)) { args = { state: sectionIdentifier }; onFailure = state; } else if (utils.isObject(sectionIdentifier) && utils.isFunction(state)) { args = { sectionIdentifier: sectionIdentifier }; onFailure = state; } else { args = { sectionIdentifier: sectionIdentifier, state: state }; } core.sendMessage(core.MessageTypes.NAVIGATE_TO_SECTION_PAGE, args, onFailure); }; return { /** * This method returns a String which represents the current view mode. * @function * @memberof Wix.Utils * @since 1.12.0 * @returns {String} The current view mode (editor/preview/site/standalone). * @example * * //viewMode will get a value like 'editor/preview/site' * var viewMode = Wix.Utils.getViewMode(); */ getViewMode: getViewMode, /** * Converts a JavaScript Date object into the correct format, ISO 8601, used by Wix APIs when dealing with dates. * It follows the same example provided by Mozilla as a polyfill for non-ECMA 262, 5th edition browsers. * @function * @memberof Wix.Utils * @since 1.28.0 * @param {Date} * @return {String} Represents the given date formatted in ISO 8601. */ toWixDate: toWixDate, /** * This method returns a String which represents the Widget/Page/Settings iframe's component id. * @function * @memberof Wix.Utils * @since 1.12.0 * @returns {String} The Widget/Page/Settings iframe's component id. * @example * * //compId will get a value like 'TPWdgt-d88e26c-217b-505f-196d-2f6d87f1c2db' * var compId = Wix.Utils.getCompId(); */ getCompId: getCompId, /** * This method returns for valid endpoints a String which represents the Widget/Page iframe's component id which opened the App Settings panel. * @function * @memberof Wix.Utils * @since 1.12.0 * @returns {String} The Widget/Page iframe's component id which opened the App Settings panel, popup or modal. If not exist returns null. * @example * * //origCompId will get a value like 'TPWdgt-d88e26c-217b-505f-196d-2f6d87f1c2db' * var origCompId = Wix.Utils.getOrigCompId(); */ getOrigCompId: getOrigCompId, /** * This method returns a Number which represents the Widget/Page/Settings iframe's width. * @function * @memberof Wix.Utils * @since 1.12.0 * @returns {Number} The Widget/Page/Settings iframe's width. * @example * * // width will get a value like 300 * var width = Wix.Utils.getWidth(); */ getWidth: getWidth, /** * This method for valid endpoints (Widget/Page/Settings) returns a String which represents the current locale of the site/editor. A locale is an abbreviated language tag that defines the user's language, country and any special variant preference of the user interface (e.g. Number format, Date format, etc.). * @function * @memberof Wix.Utils * @since 1.14.0 * @return {String} A standard IETF language tag - en (English), es (Spanish), fr (Franch), it (Italian), etc. * @example * * //locale will get a value like 'en', 'es', etc. * var locale = Wix.Utils.getLocale() */ getLocale: getLocale, /** * This method for valid endpoints (Widget/Page) returns a String which is the cacheKiller query parameter. * @function * @memberof Wix.Utils * @since 1.12.0 * @returns {String} The cacheKiller query parameter, if not exist returns null. * @example * * //cacheKiller will get a value of a random string - 1359996970511 *var cacheKiller = Wix.Utils.getCacheKiller(); */ getCacheKiller: getCacheKiller, /** * This method for valid endpoints (Widget/Page) returns a String which is the target query parameter (for the section-url). * @function * @memberof Wix.Utils * @since 1.12.0 * @returns {String} The target query parameter, if not exist returns null. * @example * * //target will get a value like '_top' or '_self' * var target = Wix.Utils.getTarget(); */ getTarget: getTarget, /** * This method when no sectionId is given is valid for Page endpoint only. * * When a sectionId is not provided this method returns a string which is the section-url query parameter. * * When a sectionId and a callback function are provided this method returns the page app Url for the given sectionId. * * Please note: The parameter "section-url" here refers to the Page app URL. * @function * @memberof Wix.Utils * @since 1.37.0 * @private * @param {Object} [sectionId] App pageId defined in dev.wix.com * @param {Function} [callback] A callback function that returns the section's URL - this is mandatory if sectionId was provided. * * @returns {String} The section-url query parameter, if not exist returns null. * @returns {Object} The section url for the given sectionId * * @example * * //url will get a value of a valid url like 'http://user.wix.com/site#!page/ch6q' * var url = Wix.Utils.getSectionUrl() * * var url = Wix.Utils.getSectionUrl({sectionId: 'mySectionId'}, function(data) { * //do something with data.url * }) */ getSectionUrl: getSectionUrl, /** * This method returns a String which represents the app instance Id. * @function * @memberof Wix.Utils * @since 1.12.0 * @returns {String} An app instance id - a GUID like value (decoded property of the instance query parameter) * @example * * //instanceId will get a GUID like value - e.g. '12de5bae-01e7-eaab-325f-436462858228' * var instanceId = Wix.Utils.getInstanceId(); */ getInstanceId: getInstanceId, /** * This method returns a String which represents the app instance signDate. * @function * @memberof Wix.Utils * @deprecated 1.13.0 * @returns {String} An app instance signDate (property of the decoded instance query parameter). * @example * * //date will get a value like '2013-01-04T02:45:35.302-06:00' * var date = Wix.Utils.getSignDate(); */ getSignDate: getSignDate, /** * This method returns a String which represents the user identifier. * @function * @memberof Wix.Utils * @since 1.12.0 * @returns {String} A user identifier (decoded property of the instance query parameter). * @example * * var uid = Wix.Utils.getUid(); */ getUid: getUid, /** * This method returns a String which represents the user's permissions (decoded property of the instance query parameter). * @function * @memberof Wix.Utils * @since 1.12.0 * @returns {String} User's permissions (decoded property of the instance query parameter) - permissions can get the value of 'OWNER' for the site owner otherwise it will be null. * @example * * var permissions = Wix.Utils.getPermissions(); */ getPermissions: getPermissions, /** * This method returns a String which represents the app IP and port. * @function * @memberof Wix.Utils * @since 1.13.0 * @returns {String} An app IP and port (decoded property of the instance query parameter). * @example * * //ipAndPort will get a value like '91.199.119.254/61308' * var ipAndPort = Wix.Utils.getIpAndPort(); */ getIpAndPort: getIpAndPort, /** * This method returns a Boolean which represents the app instance demo mode state. * @function * @memberof Wix.Utils * @since 1.12.0 * @returns {Boolean} An app instance demo mode state (decoded property of the instance query parameter). * @example * * // demoMode will get a value like true/false * var demoMode = Wix.Utils.getDemoMode(); */ getDemoMode: getDemoMode, /** * This method returns a String which represents the current device type. * @function * @memberof Wix.Utils * @since 1.20.0 * @returns {String} The current device type. One of the following: * desktop *mobile * @example * * // deviceType will get a value of 'desktop' or 'mobile' * var deviceType = Wix.Worker.Utils.getDeviceType(); */ getDeviceType: getDeviceType, /** * Navigates to the callers section page in the hosted site. * @function * @memberof Wix.Utils * @since 1.33.0 * @param {Object} [sectionIdenfitier] App page id defined in dev.wix.com {sectionId : 'sectionId'}. * @param {String} [state] New app's state to push into the editor history stack. * @param {Function} onFailure This will be called if the hosting site does not include the section app, or if the caller's application does not include a section. * @example * * * Wix.Utils.navigateToSection({ sectionId : 'sectionId' }, 'myState', function(error){ * //Handle error use-case * }); */ navigateToSection: navigateToSection, Media: Media }; }(core, gaTracker, Media, utils); /** * This is the description for the Utils namespace. * @memberof Wix * @namespace Wix.Styles */ Styles = function (core) { var EDITOR_PARAM_TYPES = [ 'color', 'number', 'boolean', 'font' ]; var getStyle = function (callback, key) { if (core.Styles[key] && callback) { callback(core.Styles[key]); } else { core.addToReadyQ(function () { if (callback) { callback(core.Styles[key]); } }); } return core.Styles[key]; }; var setEditorParam = function (type, key, value) { if (EDITOR_PARAM_TYPES.indexOf(type) === -1) { core.reportSdkError('Invalid editor param type: "' + type + '"'); } if (!key) { core.reportSdkError('Invalid key name'); } core.sendMessage(core.MessageTypes.SET_STYLE_PARAM, { type: type, key: key, param: value }); }; var shallowCloneObject = function (obj, ignoreKeys) { var newObj = {}; for (var p in obj) { if (obj.hasOwnProperty(p) && ignoreKeys.indexOf(p) === -1) { newObj[p] = obj[p]; } } return newObj; }; var getStyleParams = function (callback) { return getStyle(callback, 'style'); }; var setFontParam = function (key, value) { setEditorParam('font', key, value); }; var getEditorFonts = function (callback) { return getStyle(callback, 'fontsMeta'); }; var getSiteTextPresets = function (callback) { return getStyle(callback, 'siteTextPresets'); }; var getFontsSpriteUrl = function (callback) { return getStyle(callback, 'fontsSpriteUrl'); }; var getStyleFontByKey = function (fontKey) { var font = core.Styles.mappedFonts && core.Styles.mappedFonts['style.' + fontKey]; return font; }; var getStyleFontByReference = function (fontReference) { return core.Styles.siteTextPresets && core.Styles.siteTextPresets[fontReference]; }; var getSiteColors = function (callback) { return getStyle(callback, 'siteColors'); }; var getStyleColorByKey = function (colorKey) { var color = core.Styles.mappedColors && core.Styles.mappedColors['style.' + colorKey]; return color ? color.value : ''; }; var getColorByreference = function (colorReference) { var color = core.Styles.mappedColors && core.Styles.mappedColors[colorReference]; color = shallowCloneObject(color, ['name']); return color; }; var setColorParam = function (key, value) { if (value.hasOwnProperty('reference') && value.reference) { value.color = getColorByreference(value.reference); } setEditorParam('color', key, value); }; var setNumberParam = function (key, value) { setEditorParam('number', key, value); }; var setBooleanParam = function (key, value) { setEditorParam('boolean', key, value); }; return { /** * * The getStyleParams method is used to retrieve the style parameters from the hosting Wix Platform. * The parameters includes colors numbers, booleans. * @function * @memberof Wix.Styles * @since 1.26.0 * @param {Function} callback Callback function to retrieve the style values. * @example * * Wix.Styles.getStyleParams( function(styleParams) { * //do something with the style params * }); */ getStyleParams: getStyleParams, /** * Sets a style font parameter in the Wix site * * @function * @memberof Wix.Styles * @private * @since 1.26.0 * @param {String} key a unique key describing a boolean style parameter that was chosen by the developer in the ui-lib component. * @param {Boolean} value to store. */ setFontParam: setFontParam, /** * Returns the list of Wix fonts meta data from the editor * * @function * @memberof Wix.Styles * @private * @since 1.26.0 * @param {Function} callback A callback function to pass the Editor's font. */ getEditorFonts: getEditorFonts, /** * * Returns the list of the text presets from the editor * @function * @memberof Wix.Styles * @private * @since 1.26.0 * @param {Function} callback A callback function to pass the text presets. */ getSiteTextPresets: getSiteTextPresets, /** * * Returns the url of the Wix fonts sprite, used to render the font picker. * * @function * @memberof Wix.Styles * @private * @since 1.26.0 * @param {Function} callback A callback function to pass the sprite url. */ getFontsSpriteUrl: getFontsSpriteUrl, /** * * Returns style font by a unique key * * @function * @memberof Wix.Styles * @private * @since 1.26.0 * @param {String} fontKey The font key that was chosen by the developer in the ui-lib component. * @return {Object} */ getStyleFontByKey: getStyleFontByKey, /** * * Returns a style font by it's reference name * * @private * @function * @memberof Wix.Styles * @since 1.26.0 * @param {String} fontReference Font reference, e.g., 'Title'. * @return {Object} */ getStyleFontByReference: getStyleFontByReference, /** * Function getSiteColors * * Returns the currently active site colors * @private * @function * @memberof Wix.Styles * @since 1.26.0 * @param {Function} callback */ getSiteColors: getSiteColors, /** * * Returns the css color value of saved style parameter * * @private * @function * @memberof Wix.Styles * @since 1.26.0 * @param {String} colorKey A unique key describing a color style parameter that was chosen by the developer in the ui-lib component. * @return {String} css Color string. e.g., "#FFFFFF" or "rgba(0,0,0,0.5)" */ getStyleColorByKey: getStyleColorByKey, /** * * Returns the color object of editor style * * @private * @function * @memberof Wix.Styles * @since 1.26.0 * @param {String} colorReference A unique key describing a theme color parameter. * @return {Object} data A map describing a Wix style color. */ getColorByreference: getColorByreference, /** * * Sets a style color parameter * * @private * @function * @memberof Wix.Styles * @since 1.26.0 * @param {String} key A unique key describing a color style parameter that was chosen by the developer in the ui-lib component. * @param {Object} value */ setColorParam: setColorParam, /** * Function setNumberParam * * Sets a style number parameter * * @private * @function * @memberof Wix.Styles * @since 1.22.0 * @param {String} key A unique key describing a number style parameter that was chosen by the developer in the ui-lib component. * @param {Number} value */ setNumberParam: setNumberParam, /** * Function setBooleanParam * * Sets a style boolean parameter * * @private * @function * @memberof Wix.Styles * @since 1.22.0 * @param {String} key A unique key describing a boolean style parameter that was chosen by the developer in the ui-lib component. * @param {Boolean} value */ setBooleanParam: setBooleanParam }; }(core); /** * A theme for a popup window. * @memberof Wix * @namespace Theme */ Theme = { /** * Default theme is used for regular popup look & feel - border, shadow, close button. * @memberof Wix.Theme * @since 1.17.0 */ DEFAULT: 'DEFAULT', /** * Bare theme is used for no decorations at all. * @memberof Wix.Theme * @since 1.17.0 */ BARE: 'BARE' }; /** * Represents a Wix popup window origin. A window can be positioned where it is origin is the view port (0,0) or * where the origin is another widget (x,y). * @memberof Wix * @namespace WindowOrigin */ WindowOrigin = { /** * Default position. The popup will be placed inside the browser viewport. * @see WindowOrigin.FIXED * @memberof Wix.WindowOrigin * @since 1.17.0 */ DEFAULT: 'FIXED', /** * Fixed position. The popup will be placed inside the browser viewport. * @memberof Wix.WindowOrigin * @since 1.17.0 */ FIXED: 'FIXED', /** * Relative position. The popup will be placed relative to the opening widget (Not supported for Page). * @memberof Wix.WindowOrigin * @since 1.17.0 */ RELATIVE: 'RELATIVE', /** * Absolute position. The popup will be placed relative to a given x,y coordinates that their origin is the top-left corner of the widget. * @memberof Wix.WindowOrigin * @author mayah@wix.com * @since 1.28.0 */ ABSOLUTE: 'ABSOLUTE' }; /** * Represents a predefined values to position a Wix popup windows without the hassle of figuring out the position yourself. * Can be used to position the window relatively (to the calling widget) or absolutely (to the view port). * * @memberof Wix * @namespace WindowPlacement */ WindowPlacement = { /** * Top left placement. * @memberof Wix.WindowPlacement * @since 1.17.0 */ TOP_LEFT: 'TOP_LEFT', /** * Top right placement. * @memberof Wix.WindowPlacement * @since 1.17.0 */ TOP_RIGHT: 'TOP_RIGHT', /** * Bottom right placement. * @memberof Wix.WindowPlacement * @since 1.17.0 */ BOTTOM_RIGHT: 'BOTTOM_RIGHT', /** * Bottom left placement. * @memberof Wix.WindowPlacement * @since 1.17.0 */ BOTTOM_LEFT: 'BOTTOM_LEFT', /** * Top center placement. * @memberof Wix.WindowPlacement * @since 1.17.0 */ TOP_CENTER: 'TOP_CENTER', /** * Center right placement. * @memberof Wix.WindowPlacement * @since 1.17.0 */ CENTER_RIGHT: 'CENTER_RIGHT', /** * Bottom center placement. * @memberof Wix.WindowPlacement * @since 1.17.0 */ BOTTOM_CENTER: 'BOTTOM_CENTER', /** * Center left placement. * @memberof Wix.WindowPlacement * @since 1.17.0 */ CENTER_LEFT: 'CENTER_LEFT', /** * (FIXED origin only) center of the screen. * @memberof Wix.WindowPlacement * @since 1.17.0 */ CENTER: 'CENTER' }; /** * This is the description for the Wix namespace. * @namespace Wix */ Base = function (core, Utils, Styles, utils, Theme, WindowOrigin, WindowPlacement) { var openModal = function (url, width, height, onClose) { if (Utils.getViewMode() === 'editor') { core.reportSdkError('Invalid View Mode, editor, only preview and site are supported'); return; } var args = { url: url, width: width, height: height }; core.sendMessage(core.MessageTypes.OPEN_MODAL, args, onClose); }; var setHeight = function (height) { if (!utils.isNumber(height)) { core.reportSdkError('Mandatory argument - height - should be of type Number'); return; } else if (height < 0) { core.reportSdkError('height should be a positive integer'); return; } core.sendMessage(core.MessageTypes.HEIGHT_CHANGED, { 'height': height }); }; var closeWindow = function (message) { var args = { message: message }; core.sendMessage(core.MessageTypes.CLOSE_WINDOW, args); }; var scrollTo = function (x, y) { var args = { x: x, y: y }; core.sendMessage(core.MessageTypes.SCROLL_TO, args); }; var getSiteInfo = function (onSuccess) { core.sendMessage(core.MessageTypes.SITE_INFO, null, onSuccess); }; var getSitePages = function (callback) { core.sendMessage(core.MessageTypes.GET_SITE_PAGES, null, callback); }; var getStyleParams = function (callback) { core.reportSdkMsg('Wix.getStyleParams is DEPRECATED use Wix.Styles.getStyleParams'); return Styles.getStyleParams(callback); }; var reportHeightChange = function (height) { core.reportSdkError('Deprecated, use Wix.setHeight instead'); }; var pushState = function (state) { if (!utils.isString(state)) { core.reportSdkError('Missing mandatory argument - state - should be of type String'); return; } core.sendMessage(core.MessageTypes.APP_STATE_CHANGED, { 'state': state }); }; var getCurrentPageId = function (callback) { core.sendMessage(core.MessageTypes.GET_CURRENT_PAGE_ID, null, callback); }; var navigateToPage = function (pageId) { if (!pageId) { core.reportSdkError('Missing mandatory argument - pageId'); return; } core.sendMessage(core.MessageTypes.NAVIGATE_TO_PAGE, { pageId: pageId }); }; var currentMember = function (onSuccess) { if (Utils.getViewMode() !== 'site') { core.reportSdkError('Invalid View Mode, this method works only for site view mode'); return; } core.sendMessage(core.MessageTypes.SM_CURRENT_MEMBER, null, onSuccess); }; var requestLogin = function (onSuccess) { core.sendMessage(core.MessageTypes.SM_REQUEST_LOGIN, null, onSuccess); }; var openPopup = function (url, width, height, position, onClose, theme) { if (Utils.getViewMode() === 'editor') { core.reportSdkError('Invalid View Mode, editor, only preview and site are supported'); return; } // in case position was omitted and the last argument is the onClose callback if (arguments.length === 4 && utils.isFunction(arguments[3])) { position = {}; } position = position || {}; position.origin = position.origin || WindowOrigin.DEFAULT; position.placement = position.placement || WindowPlacement.CENTER; var args = { url: url, width: width, height: height, position: position, theme: theme || Theme.DEFAULT }; core.sendMessage(core.MessageTypes.OPEN_POPUP, args, onClose); }; var resizeWindow = function (width, height, onComplete) { var args = { width: width, height: height }; core.sendMessage(core.MessageTypes.RESIZE_WINDOW, args, onComplete); }; var addEventListener = function (eventName, callBack) { return core.addEventListenerInternal(eventName, callBack, false); }; var removeEventListener = function (eventName, callBackOrId) { core.removeEventListenerInternal(eventName, callBackOrId, false); }; var scrollBy = function (x, y) { var args = { x: x, y: y }; core.sendMessage(core.MessageTypes.SCROLL_BY, args); }; var getBoundingRectAndOffsets = function (callback) { core.sendMessage(core.MessageTypes.BOUNDING_RECT_AND_OFFSETS, null, callback); }; return { /** * The openModal method allows an app to open a modal window within the site or preview. * * A modal is a runtime Widget that is not part of the site structure. * * The modal window is a singleton (every new modal closes the previous one) and contains a lightbox. * * A modal can be dismissed by the user if it touches the lightbox, presses the closing button or by the app itself * if it calls the Wix.closeWindow from within the modal iframe. * * The onClose argument can be used to detect modal close. * @function * @memberof Wix * @since 1.16.0 * @param {String} url Model iframe url. * @param {Number} width The modal window width. * @param {Number} height The modal window height. * @param {Function} [onClose] Onclose callback function. * @example * * var onClose = function(message) { console.log("modal closed", message); } * Wix.openModal("http://sslstatic.wix.com/services/js-sdk/1.16.0/html/modal.html", 400, 400, onClose); * */ openModal: openModal, /** * * @function * @memberof Wix * * @description * * The openPopup method allows an app to open a popup window within the site or preview. * * A popup is a runtime Widget that is not part of the site structure. * * Unlike the modal, a popup is not a singleton and doesn't present a lightbox. * * A popup can also be positioned by the caller. We currently support a predefined set of * positions that can be used when opening a popup. * * A popup is dismissed by the user if he presses the close button or by the app itself if it calls the Wix.closeWindow from within * the popup iframe. * * The onClose argument can be used to detect modal close. * * Popup positioning * A popup position is determined by two properties, it's position origin and it's position placement. * A position origin determines the origin point (x,y) which will be used to apply the position placement. * The position origin is defined under [Wix.WindowOrigin](Wix.WindowOrigin) and can have the following values: * * [Wix.WindowOrigin.DEFAULT](Wix.WindowOrigin.html#DEFAULT) * * [Wix.WindowOrigin.FIXED](Wix.WindowOrigin.html#FIXED) * * [Wix.WindowOrigin.RELATIVE]((Wix.WindowOrigin.html#RELATIVE) * * [Wix.WindowOrigin.ABSOLUTE]((Wix.WindowOrigin.html#ABSOLUTE) * * A position placement is a predefined set of locations when a popup will be placed. * The placement values are valid for Wix.WindowOrigin.FIXED, Wix.WindowOrigin.ABSOLUTE and Wix.WindowOrigin.RELATIVE origins but mapped to a different positions on the screen. * The position placement is defined under Wix.WindowPlacement and can have the following values: * * [Wix.WindowPlacement.TOP_LEFT](Wix.WindowPlacement.html#TOP_LEFT) * * [Wix.WindowPlacement.TOP_CENTER](Wix.WindowPlacement.html#TOP_CENTER) * * [Wix.WindowPlacement.TOP_RIGHT](Wix.WindowPlacement.html#TOP_RIGHT) * * [Wix.WindowPlacement.CENTER_LEFT](Wix.WindowPlacement.html#CENTER_LEFT) * * [Wix.WindowPlacement.CENTER](Wix.WindowPlacement.html#CENTER) * * [Wix.WindowPlacement.CENTER_RIGHT](Wix.WindowPlacement.html#CENTER_RIGHT) * * [Wix.WindowPlacement.BOTTOM_LEFT](Wix.WindowPlacement.html#BOTTOM_LEFT) * * [Wix.WindowPlacement.BOTTOM_CENTER](Wix.WindowPlacement.html#BOTTOM_CENTER) * * [Wix.WindowPlacement.BOTTOM_RIGHT](Wix.WindowPlacement.html#BOTTOM_RIGHT) * * @since 1.17.0 * @param {String} url Popup iframe's url. * @param {Number} width Popup width in pixels. * @param {Number} height Popup height in pixels. * @param {Object} position * @param {Function} [onClose] Callback function. * @param {Wix.Theme} theme The popup window theme, one of Wix.Theme values. Wix.Theme.DEFAULT is used for regular popup look & feel - border, shadow, close button. Wix.Theme.BARE is used for no decorations at all. * * Note: * In a RELATIVE or ABSOLUTE origin, there is a chance that the requested popup can not fit in the * desired position since it's size exceeds the margin between the opening Widget and the screen size. * A Widget position is determined by site owners when they build their sites while the Widget * is not aware to it's position in the site. When the Wix Platform render popups, * it calculates if a popup in the requested size can fit the requested position. * If not, the Wix Platform will default the position to {origin: Wix.WindowOrigin.FIXED, placement: Wix.WindowPlacement.CENTER}, * i.e., the center of the screen. * * * @example * // The following call will open a popup window positioned in the center of the screen * var position = {origin: Wix.WindowOrigin.FIXED, placement: Wix.WindowPlacement.CENTER}; * var onClose = function(message) { console.log("popup closed", message) }; * Wix.openPopup("http://sslstatic.wix.com/services/js-sdk/1.16.0/html/modal.html", 400, 400, position, onClose); * @example * // The following call will open a popup window positioned bottom-right to the point (x, y), originated in the top-left corner of the widget * var position = {origin: Wix.WindowOrigin.ABSOLUTE, placement: Wix.WindowPlacement.BOTTOM_RIGHT, x: 20, y: 100}; * var onClose = function(message) { console.log("popup closed", message) }; * Wix.openPopup("http://sslstatic.wix.com/services/js-sdk/1.16.0/html/modal.html", 400, 400, position, onClose); * */ openPopup: openPopup, /** * This method requests the hosting Wix platform to change the iframe height inside the site/editor. * @function * @memberof Wix * @since 1.22.0 * @param {Number} height An integer that represents the desired height in pixels. * @example * * Wix.setHeight(height); * */ setHeight: setHeight, /** * The closeWindow method is available only under a modal endpoint (will not have any effect for other endpoints). It allows the modal to close itself programmatically. * @function * @memberof Wix * @since 1.16.0 * @param {Object} [message] A custom message object to pass to the opener's onClose callback function. * @example * * // The following call will close the modal/popup window and send a the object message to the opener onClose callback * var message = {"reason": "button-clicked"}; * Wix.closeWindow(message); * */ closeWindow: closeWindow, /** * The scrollTo method will perform a scroll to a fixed position in the app's hosting site window exactly as the standard method do. * @function * @memberof Wix * @since 1.19.0 * @param {Number} x The coordinate to scroll to, along the x-axis. * @param {Number} y The coordinate to scroll to, along the y-axis. * @example * * Wix.scrollTo(0, 0); * */ scrollTo: scrollTo, /** * The scrollBy method will perform a scroll by the specified number of pixels in the app's hosting site window exactly as the standard method - http://www.w3schools.com/jsref/met_win_scrollto.asp do. * @function * @memberof Wix * @since 1.19.0 * @param {Number} x How many pixels to scroll by, along the x-axis (horizontal) * @param {Number} y How many pixels to scroll by, along the y-axis (vertical) * @example * * // The following call will scroll to the top of the page * Wix.scrollBy(0, 0); * */ scrollBy: scrollBy, /** * The getsiteInfo method is used to retrieve information about the host site in which the app is shown. * @function * @memberof Wix * @since 1.3.0 * @param callback (Function) a callback function to receive the site pages. * @return {Object} data JSON containing the site info. It's properties are: * * Name | Type | Description * ----------------|-----------|------------ * siteTitle | `String` | The title of the site that is used for SEO. * pageTitle | `String` | The site current page title that is used for SEO. * siteDescription | `String` | The description of the site that is used for SEO * siteKeywords | `String` | The keywords which were related to the site and are used for SEO. * referrer | `String` | The referrer header of the http request. * url | `String` | The full url taken from the location.href, include internal site state, for example: http://user.wix.com/site-name#!pageTitle/pageId, http://www.domain.com#!pageTitle/pageId * baseUrl | `String` | Base url of the current site, for example: http://user.wix.com/site-name, http://www.domain.com * * @example * Wix.getSiteInfo( function(siteInfo) { * // do something with the siteInfo * }); */ getSiteInfo: getSiteInfo, /** * The getSitePages method is used to retrieve the site structure from the hosting Wix Platform. The site structure includes visible and hidden pages as well as sub pages. * @function * @memberof Wix * @since 1.17.0 * @param {Function} callback A callback function to receive the site pages. * @return {Array} Array containing an ordered set of the site pages. A single page description contains the following properties: * * Name | Type | Description * ------------------|-----------|------------ * id | `String` | The page id. * title | `String` | The page title. * hide | `Boolean` | A flag indicating if the page is hidden. * subPages(optional)| `Array` | An ordered set of sub pages. * @example * * Wix.getSitePages(function(sitePages) { * // do something with the site pages * }); */ getSitePages: getSitePages, /** * The getBoundingRectAndOffsets method returns the app's component bounding rect and site's offset. * @function * @memberof Wix * @since 1.26.0 * @param {Function} callback A callback function which passes back the bounding rect and offsets. * * @example * Wix.getBoundingRectAndOffsets(function(data){ * // use the offsets and rect details * }); */ getBoundingRectAndOffsets: getBoundingRectAndOffsets, /** * The removeEventListener method allows to remove previously assigned event listeners that were specified using Wix.addEventListener. * @function * @memberof Wix * @since 1.25.0 * @param {Wix.Events} eventName Unique event identifier. * @param {Function} callBackOrId A callback function that was used with addEventListener or an id returned by addEventListener. * * @example * var callback = function(){}; * var id = Wix.addEventListener(Wix.Events.EDIT_MODE_CHANGE, function(data) { * //do something * }); * Wix.addEventListener(Wix.Events.PAGE_NAVIGATION, callback); * // remove listener as a callback function * Wix.removeEventListener(Wix.Events.PAGE_NAVIGATION, callback); * // remove listener as an id * Wix.removeEventListener(Wix.Events.EDIT_MODE_CHANGE, id); */ removeEventListener: removeEventListener, /** * The addEventListener method lets the App listen to events that happens inside the editor/site. * @function * @memberof Wix * @since 1.11.0 * @param {Wix.Events} eventName Unique event identifier. * @param {Function} handler A callback function that will get called by the SDK once an event occur. * The events that you can currently listen to are: * @see Wix.Events.EDIT_MODE_CHANGE * @see Wix.Events.PAGE_NAVIGATION_CHANGE * @see Wix.Events.PAGE_NAVIGATION * @see Wix.Events.PAGE_NAVIGATION_IN * @see Wix.Events.PAGE_NAVIGATION_OUT * @see Wix.Events.SCROLL * @see Wix.Events.COMPONENT_DELETED * @see Wix.Events.SITE_PUBLISHED * @see Wix.Events.SETTINGS_UPDATED * @see Wix.Events.STATE_CHANGED * */ addEventListener: addEventListener, /** * The resizeWindow method is valid only for fixed position widgets. It re-sizes the widget window. * @function * @memberof Wix * @since 1.19.0 * @param {Number} width Window width in pixels. * @param {Number} height Window height in pixels. * @param [Function] onComplete On resize complete callback function. * @example * * // The following call will resize the widget window * Wix.resizeWindow(300,300); * */ resizeWindow: resizeWindow, /** * *
* This method is part of Wix Site Members feature. To use it a manual provisioning is required by the Wix team, contact apps@wix.com to enable it for your app. *
* * This method is relevant for live sites and not from the App Settings. The method requests the current site visitor of the Wix site to log-in or register. * * After a successful log-in, the Wix site will reload including the app iframe and the new signed-instance parameter will contain the details of the logged in user. * * * The method has an affect only for a published site. If called in the Wix editor, the method has no affect. * * * @function * @memberof Wix * @since 1.6.0 * @param {Function} callback A callback function to receive the current member details. * @example * * Wix.requestLogin(function (data) { * //do something with data * } */ requestLogin: requestLogin, /** * *
* This method is part of Wix Site Members feature. To use it a manual provisioning is required by the Wix team, contact apps@wix.com to enable it for your app. *
* * This method is relevant for live sites and not from the App Settings. * * @function * @memberof Wix * @since 1.6.0 * @param {Function} callback A callback function to receive the current member details. * @returns {Object} JSON Containing the user's details. * * This method returns the details of the current site visitor that is logged into the Wix site, using the Wix site member options. * * Name | Type | Value * ------------------|-----------|------------ * name | 'String' | The current member's name * email | 'String' | The current member's email * id | 'String' | The current member's id * owner | 'Boolean' | Indicates if the user is the owner of the site * * @example * * Wix.currentMember(function(memberDetails) { * // save memberDetails * } * * */ currentMember: currentMember, /** * The navigateToPage method is used to navigate to a specific page inside the editor/preview/site. * * The function accepts a single argument, page id, which is retrieved by using the method Wix.getSitePages(). * * @function * @memberof Wix * @since 1.17.0 * @param {String} pageId A string representing the page id target. * @returns {Object} JSON Containing the user's details. * * This method returns the details of the current site visitor that is logged into the Wix site, using the Wix site member options. * * Name | Type | Value * ------------------|-----------|------------ * name | 'String' | The current member's name * email | 'String' | The current member's email * id | 'String' | The current member's id * owner | 'Boolean' | Indicates if the user is the owner of the site * * @example * * Wix.navigateToPage(PAGE_ID); */ navigateToPage: navigateToPage, /** * The getCurrentPageId method returns the page id of the app hosting page. * * @function * @memberof Wix * @since 1.31.0 * @author lior.shefer@wix.com * @example * * // The following call will return the page id of the app hosting page. * Wix.getCurrentPageId(function(pageId) { * //store the site pageId * } */ getCurrentPageId: getCurrentPageId, /** * This method enable AJAX style Page apps to inform the Wix platform about a change in the app internal state. The new state will be reflected in the site/page URL. * Once you call the pushState method, the browser top window URL will change the 'app-state' path part to the new state you provide with the pushState * method (similar to the browser history API - https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history). * For a full explanation of how deep-linking works with AJAX style apps, see Deep Linking for AJAX Style Apps - http://dev.wix.com/docs/display/DRAF/Developing+a+Page+App. * @function * @memberof Wix * @since 1.8.0 * @param {String} state New app's state to push into the editor history stack. * @example * * Wix.pushState("app-state"); * */ pushState: pushState, /** * This method requests the hosting Wix platform to change the iframe height inside the site/editor. * @function * @memberof Wix * @since 1.8.0 * @deprecated * @see Wix.setHeight * @param {Number} height An integer that represents the desired height in pixels. * * @example * * Wix.reportHeightChange(height); * */ reportHeightChange: reportHeightChange, /** * The getStyleParams method is used to retrieve the style parameters from the hosting Wix Platform. The parameters includes colors numbers, booleans. * @function * @memberof Wix * @since 1.22.0 * @deprecated * @see Wix.Styles.getStyleParams * @param {function} callback A callback function to receive the style parameters. * * @example * * Wix.getStyleParams( function(styleParams) { * // do something with the style params * }); * */ getStyleParams: getStyleParams }; }(core, Utils, Styles, utils, Theme, WindowOrigin, WindowPlacement); /** * This is the description for the Error namespace. * @memberof Wix * @namespace Wix.Error */ Error = { /** * Indicates an unknown error happened on Wix side which could not be recovered. When handling this error, you can try again or prompt the user with an error dialog. * @memberof Wix.Error * @since 1.27.0 */ WIX_ERROR: 'WIX_ERROR', /** * Indicates the activity could not be found. * @memberof Wix.Error * @since 1.27.0 */ NOT_FOUND: 'NOT_FOUND', /** * Indicates the dates you provided are in the wrong format or are not valid date ranges. * @memberof Wix.Error * @since 1.27.0 */ BAD_REQUEST: 'BAD_REQUEST', /** * @memberof Wix.Error * @since 1.27.0 */ INVALID_SCHEMA: 'INVALID_SCHEMA' }; /** * @class WixDataCursor */ WixDataCursor = function () { var _callService = function (onSuccess, onFailure, cursorId) { var that = this; var onComplete = function onComplete(response) { if (response.error) { onFailure(response); } else { that._nextCursor = response.data.nextCursor; that._previousCursor = response.data.previousCursor; that._data = response.data.results; onSuccess(response.data.results); } }; var args = { cursorId: cursorId, options: this._options }; this.core.sendMessage(this._serviceMessageType, args, onComplete); }; function WixDataCursor(core, serviceMessageType, data, total, pageSize) { if (typeof serviceMessageType !== 'string' || typeof core === 'undefined') { throw new TypeError('Mandatory parameters are missing.'); } this._serviceMessageType = serviceMessageType; this._data = data || []; this._nextCursor = null; this._previousCursor = null; this._total = total; this._pageSize = pageSize; this._options = {}; this.core = core; } /** * @memberof WixDataCursor * @returns {boolean} If WixDataCursor has more data. */ WixDataCursor.prototype.hasNext = function hasNext() { return !!this._nextCursor; }; /** * @memberof WixDataCursor * @returns {boolean} If WixDataCursor has previous data. */ WixDataCursor.prototype.hasPrevious = function hasPrevious() { return !!this._previousCursor; }; /** * @memberof WixDataCursor * @param onSuccess * @param onFailure * @returns {boolean} The next WixDataCursor object. */ WixDataCursor.prototype.next = function next(onSuccess, onFailure) { if (this.hasNext()) { _callService.call(this, onSuccess, onFailure, this._nextCursor); } else { onSuccess([]); } }; /** * @memberof WixDataCursor * @param onSuccess * @param onFailure * @returns {boolean} The previous WixDataCursor object. */ WixDataCursor.prototype.previous = function previous(onSuccess, onFailure) { if (this.hasPrevious()) { _callService.call(this, onSuccess, onFailure, this._previousCursor); } else { onSuccess([]); } }; /** * @memberof WixDataCursor * @private * @param {Object} data */ WixDataCursor.prototype.setData = function setData(data) { this._data = data; }; /** * @memberof WixDataCursor * @private * @returns {WixDataCursor[]} */ WixDataCursor.prototype.getData = function getData() { return this._data; }; /** * @memberof WixDataCursor * @private * @param {WixDataCursor} cursor */ WixDataCursor.prototype.setNextCursor = function setNextCursor(cursor) { this._nextCursor = cursor; }; /** * @memberof WixDataCursor * @private * @param {WixDataCursor} cursor */ WixDataCursor.prototype.setPreviousCursor = function setPreviousCursor(cursor) { this._previousCursor = cursor; }; /** * @memberof WixDataCursor * @returns {Number} The total number of Object in the cursor. */ WixDataCursor.prototype.getTotal = function getTotal() { return this._total; }; /** * @memberof WixDataCursor * @returns {Number} The number of the cursor page size. */ WixDataCursor.prototype.getPageSize = function getPageSize() { return this._pageSize; }; /** * @memberof WixDataCursor * @param {Object} options * @private * @returns Sets the cursor options object. */ WixDataCursor.prototype.setOptions = function setOptions(options) { this._options = options; }; return WixDataCursor; }(); responseHandlers = function (core, Error, WixDataCursor) { var getWixError = function (errorCode) { var wixErrorMessage = Error.WIX_ERROR; switch (errorCode) { case 404: wixErrorMessage = Error.NOT_FOUND; break; case 400: wixErrorMessage = Error.BAD_REQUEST; break; case 'INVALID_SCHEMA': wixErrorMessage = Error.INVALID_SCHEMA; break; } return wixErrorMessage; }; var handleDataResponse = function (response, onSuccess, onFailure) { if (response.error) { var wixErrorMessage = this.getWixError(response.error.errorCode); if (onFailure) { onFailure(wixErrorMessage); } } else { onSuccess(response.data); } }; var handleCursorResponse = function (response, onSuccess, onFailure, messageType, options) { if (!response.error) { var cursor = new WixDataCursor(core, messageType, response.data.results, response.data.total, response.data.pageSize); cursor.setNextCursor(response.data.nextCursor); cursor.setPreviousCursor(response.data.previousCursor); cursor.setOptions(options); onSuccess(cursor); } else { var wixErrorMessage = this.getWixError(response.error.errorCode); if (onFailure) { onFailure(wixErrorMessage); } } }; return { getWixError: getWixError, handleDataResponse: handleDataResponse, handleCursorResponse: handleCursorResponse }; }(core, Error, WixDataCursor); /** * Functions and objects relating to the purchasing and billing process. To define products for purchase within your app, go to the Features section of the Wix Developer app registration dev.wix.com. * @memberof Wix * @namespace Wix.Billing */ Billing = function (core, utils, responseHandlers) { var openBillingPageForProduct = function (vendorProductId, cycle, onError) { if (!utils.isString(vendorProductId)) { core.reportSdkError('Missing mandatory argument - vendorProductId must be a string'); return; } if (!utils.has(this.Cycle, cycle)) { core.reportSdkError('Missing mandatory argument - cycle must be one of Wix.Billing.Cycle'); return; } var args = { vendorProductId: vendorProductId, cycle: cycle }; core.sendMessage(core.MessageTypes.OPEN_BILLING_PAGE_FOR_PRODUCT, args, onError); }; var getBillingPageForProduct = function (vendorProductId, cycle, onSuccess, onError) { if (!utils.isString(vendorProductId)) { core.reportSdkError('Missing mandatory argument - vendorProductId must be a string'); return; } if (!utils.has(this.Cycle, cycle)) { core.reportSdkError('Missing mandatory argument - cycle must be one of Wix.Billing.Cycle'); return; } if (!utils.isFunction(onSuccess)) { core.reportSdkError('Missing mandatory argument - onSuccess must be a function'); return; } var args = { vendorProductId: vendorProductId, cycle: cycle }; var onComplete = function onComplete(result) { responseHandlers.handleDataResponse(result, onSuccess, onError); }; core.sendMessage(core.MessageTypes.GET_BILLING_PAGE_FOR_PRODUCT, args, onComplete); }; var getBillingPackages = function (vendorProductIds, onSuccess, onError) { if (utils.isFunction(vendorProductIds)) { onSuccess = vendorProductIds; vendorProductIds = undefined; } if (!utils.isFunction(onSuccess)) { core.reportSdkError('Missing mandatory argument - onSuccess must be a function'); return; } var args = { vendorProductIds: vendorProductIds }; var onComplete = function onComplete(result) { responseHandlers.handleDataResponse(result, onSuccess, onError); }; core.sendMessage(core.MessageTypes.GET_BILLING_PACKAGES, args, onComplete); }; var getActiveBillingPackage = function (onSuccess, onError) { if (!utils.isFunction(onSuccess)) { core.reportSdkError('Missing mandatory argument - onSuccess must be a function'); return; } var onComplete = function onComplete(result) { responseHandlers.handleDataResponse(result, onSuccess, onError); }; core.sendMessage(core.MessageTypes.GET_ACTIVE_BILLING_PACKAGE, undefined, onComplete); }; return { /** * @enum * @memberof Wix.Billing * @since 1.37.0 */ Cycle: { MONTHLY: 'MONTHLY', YEARLY: 'YEARLY', ONE_TIME: 'ONE_TIME' }, /** * Opens the Wix billing page in a new window with information about the product and cycle requested. This API is internal and works with the Upgrade button component found in the UI Lib. * * @function * @memberof Wix.Billing * @author lior.shefer@wix.com * @since 1.37.0 * @private * @param {String} vendorProductId The vendor product id associated with the initiated purchase. * @param {Wix.Billing.Cycle} cycle The billing cycle. * @param {Function} [onError] A callback error function. An error might be a result of a wrong cycle, missing cycle or bad vendor product Id. * missing cycle or bad productId. * * @example * Wix.Billing.openBillingPageForProduct('vendorProductId', Wix.Billing.Cycle.MONTHLY, function () { * //handle error * ); * */ openBillingPageForProduct: openBillingPageForProduct, /** * Returns a link to Wix Billing page with information about the product and cycle requested. * * @function * @memberof Wix.Billing * @author lior.shefer@wix.com * @since 1.37.0 * @param {String} vendorProductId Vendor product id as detailed in the Features section of the Wix Developer App Registration dev.wix.com * @param {Wix.Billing.Cycle} cycle The billing cycle. * @param {Function} onSuccess A callback function, returns a link the Wix billing page with information about the product and cycle requested. * @param {Function} [onError] A callback error function, Error is wrong cycle, * missing cycle or bad productId. * * @example * var onError = function () { * //handle the error * }; * Wix.Billing.getBillingPageForProduct('vendorProductId', Wix.Billing.Cycle.MONTHLY, function () { * //handle return value i.e., //https://premium.wix.com/... * }, onError); * */ getBillingPageForProduct: getBillingPageForProduct, /** * Returns an Array of objects containing product and pricing info. As is defined in the Features section of the Wix Developer App Registration dev.wix.com * * @function * @memberof Wix.Billing * @author lior.shefer@wix.com * @since 1.37.0 * @param {Array} [vendorProductIds] A list of vendor product ids (each representing a billing package), as detailed in the Features section of the Wix Developer App Registration dev.wix.com * @param {Function} onSuccess A callback function to receive the product info. * @param {Function} [onError] A callback error function. * * @return {Array} Array of Objects containing the product info: * * Name | Type | Description * --------------|----------------------|------------ * prices | `Array` | - * price | `Object` | Name | Type | Description * - | - | value |`String` | The product price. * - | - | currencyCode |`String` | The product payment currency code. * - | - | currencySymbol |`String` | The product payment currency symbol. * - | - | cycle |[Wix.Billing.Cycle](Wix.Billing.html#Cycle) | The product payment cycle * * @example * var onError = function () { * //handle the error * }; * var onSuccess = function (data) { * //handle onSuccess * //sample data schema: * [{ * id: , * prices: [ * { * value : '3.99', * currencyCode: 'USD', * currencySymbol: '$', * cycle: 'MONTHLY' * }] * }] * * }; * Wix.Billing.getBillingPackages(onSuccess, onError); * */ getBillingPackages: getBillingPackages }; }(core, utils, responseHandlers); /** * @memberof Wix * @namespace Activities */ Activities = function (core, responseHandlers, gaTracker, utils) { var postActivity = function (activity, onSuccess, onFailure) { if (utils.getViewMode() !== 'site') { core.reportSdkError('Invalid View Mode, Wix.postActivity is available only for site view mode'); return; } var args = { activity: activity }; var onComplete = null; if (onSuccess || onFailure) { onComplete = function (result) { if (result.status && onSuccess) { onSuccess(result.response); } else if (onFailure) { onFailure(result.response); } }; } core.sendMessage(core.MessageTypes.POST_ACTIVITY, args, onComplete); }; var getActivities = function (onSuccess, onFailure, query) { if (typeof onSuccess !== 'function') { core.reportSdkError('Missing mandatory argument - onSuccess, must be a function'); return; } if (typeof onFailure !== 'function') { core.reportSdkError('Missing mandatory argument - onFailure, must be a function'); return; } gaTracker.trackSDKCall('Activities.getActivities'); var args = { query: query }; var onComplete = function onComplete(response) { responseHandlers.handleCursorResponse(response, onSuccess, onFailure, core.MessageTypes.GET_ACTIVITIES); }; core.sendMessage(core.MessageTypes.GET_ACTIVITIES, args, onComplete); }; var getActivityById = function (id, onSuccess, onFailure) { if (typeof id !== 'string') { core.reportSdkError('Missing mandatory argument - id, must be a string'); return; } if (typeof onSuccess !== 'function') { core.reportSdkError('Missing mandatory argument - onSuccess, must be a function'); return; } if (typeof onFailure !== 'function') { core.reportSdkError('Missing mandatory argument - onFailure, must be a function'); return; } gaTracker.trackSDKCall('Activities.getActivityById'); var args = { id: id }; var onComplete = function onComplete(result) { responseHandlers.handleDataResponse(result, onSuccess, onFailure); }; core.sendMessage(core.MessageTypes.GET_ACTIVITY_BY_ID, args, onComplete); }; var getUserSessionToken = function (callback) { core.sendMessage(core.MessageTypes.GET_USER_SESSION, null, callback); }; return { /** * @enum * @memberof Wix.Activities * @since 1.25.0 */ Type: { /** * Indicates a contact form was filled out. */ CONTACT_CONTACT_FORM: 'contact/contact-form', /** * Indicates a conversion with a contact was completed. */ CONVERSION_COMPLETE: 'conversion/complete', /** * Indicates a purchase was made through ecommerce. */ ECOMMERCE_PURCHASE: 'e_commerce/purchase', /** * Indicates a message was sent to a contact. */ SEND_MESSAGE: 'messaging/send', /** * Indicates a hotel reservation has been cancelled. */ HOTELS_CANCEL: 'hotels/cancel', /** * Indicates a hotel reservation has been confirmed. */ HOTELS_CONFIRMATION: 'hotels/confirmation', /** * Indicates a hotel purchase has been made. */ HOTELS_PURCHASE: 'hotels/purchase', /** * Indicates a hotel purchase has failed. * @constant */ HOTELS_PURCHASE_FAILED: 'hotels/purchase-failed', /** * Indicates a contact liked an album of music. */ ALBUM_FAN: 'music/album-fan', /** * Indicates a contact shared an album of music. */ ALBUM_SHARE: 'music/album-share', /** * indicates a contact played an album to completion */ ALBUM_PLAYED: 'music/album-played', /** * Indicates a contact viewed the lyrics of a song. */ TRACK_LYRICS: 'music/track-lyrics', /** * Indicates a contact begun to play a track. */ TRACK_PLAY: 'music/track-play', /** * Indicates a contact played a track to completion. */ TRACK_PLAYED: 'music/track-played', /** * Indicates a contact shared a track. */ TRACK_SHARE: 'music/track-share', /** * Indicates a contact skipped a track. */ TRACK_SKIP: 'music/track-skip', /** * Indicates an appointment has been scheduled. */ SCHEDULER_APPOINTMENT: 'scheduler/appointment' }, /** * @enum * @memberof Wix.Activities * @since 1.25.0 */ Error: { BAD_DATES: 'BAD_DATES', ACTIVITY_NOT_FOUND: 'ACTIVITY_NOT_FOUND', WRONG_PERMISSIONS: 'WRONG_PERMISSIONS' }, /** * This method posts an Activity to the current site. An Activity is an action performed by a site viewer on the installed site. * By reporting Activities, your application better integrates with the Wix ecosystem. Each Activity conforms to a specific schema predefined by Wix. * When the Activity is successfully created, the id of the activity will be returned. If schema validation fails, or other errors occur, an error will be returned. * * * @function * @memberof Wix.Activities * @since 1.25.0 * @param {Object} activity An activity descriptor, must follow specific type/schema pattern: * Name | Type | Description ||| * --------------|-----------|------------ * type | `String` | The Activity Type. [Wix.Activities.ActivityType](Wix.Activities.html#toc4) ||| * info | `Object` | The Activity information, specified by the Activity type. ||| * details | `Object` | Name | Type | Description * - | - | additionalInfoUrl |`String` | URL for additional information about this Activity. * - | - | summary |`String` | Additional information about this Activity. * contactUpdate | `Object` | Additional Contact information relevant to this Activity. ||| * * @param {Function} [onSuccess] Success callback function. * @param {Function} [onFailure] Failure callback function. * * @example * var activity = { * type:Wix.Activities.Type.CONTACT_CONTACT_FORM, * info:{"fields":[{"name":"email","value":"email@email.com"},{"name":"message","value":"messageValue"}]}, * details:{additionalInfoUrl:null, summary:"testing tpa contact form"}, * contactUpdate:{} * }; * * Wix.Activities.postActivity(activity, onSuccess, onFailure); * */ postActivity: postActivity, /** * Gets a list of all activities that have been performed by users on the current site, optionally bound by date ranges, activity types and scope (app/site). * The results are returned through a callback that delivers a WixDataCursor object, with the results being in descending order by date. * @function * @memberof Wix.Activities * @since 1.28.0 * @param {Object} [query] An Object containing params to restrict our results. * @param {Function} onSuccess A function that receives a WixDataCursor object. * @param {Function} onFailure A function that receives an error object in case of invalid input. * @returns {WixDataCursor} * @example * var query = { * from: < ISO 8601 timestamp>, * until: < ISO 8601 timestamp>, * scope: <'app' 'scope'>, * activityTypes: [ 'type1', 'type2', ...] * }; * * Wix.Activities.getActivities(query, onSuccess, onFailure); * */ getActivities: getActivities, /** * Gets a specific Activity that occurred on the current site. * @function * @memberof Wix.Activities * @since 1.28.0 * @param {String} id The id of the Activity to look up. * @param {Function} onSuccess Callback triggered when data about the Activity is returned from Wix. * @param {Function} onFailure Callback triggered if the data could not be returned successfully. * @returns {Activity} * @example * * Wix.Activities.getActivityById(id, onSuccess, onFailure) * */ getActivityById: getActivityById, /** * Returns a session token which can be used to make AJAX calls to Wix RESTful API. * @function * @memberof Wix.Activities * @since 1.25.0 * @param {Function} callback a callback function to receive the token. * @example * * Wix.Activities.getUserSessionToken(callback); * */ getUserSessionToken: getUserSessionToken }; }(core, responseHandlers, gaTracker, Utils); /** * This is the description for the Settings namespace. * @memberof Wix * @namespace Wix.Settings */ Settings = function (core, gaTracker, Styles, Base, WindowPlacement, utils) { var getStyleParams = function (callback) { core.reportSdkMsg('Wix.Settings.getStyleParams is DEPRECATED use Wix.Styles.getStyleParams'); return Styles.getStyleParams(callback); }; /** Function getStyleColorByKey * * Returns the css color value of saved style parameter * * @deprecated * @since SDK 1.22.0 * @param colorKey (String) a unique key describing a color style parameter * @return (String) css color string. E.g "#FFFFFF" or "rgba(0,0,0,0.5)" */ var getStyleColorByKey = function (colorKey) { core.reportSdkMsg('Wix.Settings.getStyleColorByKey is DEPRECATED use Wix.Styles.getStyleColorByKey'); return Styles.getStyleColorByKey(colorKey); }; /** * Function getColorByreference * Returns the color object of editor style * * @deprecated * @since 1.22.0 * @param colorReference (String) a unique key describing a theme color parameter * @return (Object) a map describing a Wix style color. */ var getColorByreference = function (colorReference) { core.reportSdkMsg('Wix.Settings.getColorByreference is DEPRECATED use Wix.Styles.getColorByreference'); return Styles.getColorByreference(colorReference); }; /** * Function setColorParam * Sets a style color parameter * * @deprecated * @since 1.22.0 * @param key (String) a unique key describing a color style parameter * @param value (Object) */ var setColorParam = function (key, value) { core.reportSdkMsg('Wix.Settings.setColorParam is DEPRECATED use Wix.Styles.setColorParam'); return Styles.setColorParam(key, value); }; /** * Function setNumberParam * Sets a style number parameter * * @deprecated * @since 1.22.0 * @param key (String) a unique key describing a number style parameter * @param value (Number) */ var setNumberParam = function (key, value) { core.reportSdkMsg('Wix.Settings.setNumberParam is DEPRECATED use Wix.Styles.setNumberParam'); return Styles.setNumberParam(key, value); }; /** Function setBooleanParam * * Sets a style boolean parameter * * @deprecated * @since 1.22.0 * @param key (String) a unique key describing a boolean style parameter * @param value (Boolean) */ var setBooleanParam = function (key, value) { core.reportSdkMsg('Wix.Settings.setBooleanParam is DEPRECATED use Wix.Styles.setBooleanParam'); return Styles.setBooleanParam(key, value); }; /** Function getSiteColors * * Returns the currently active site colors * * @deprecated * @since 1.12.0 * @param callback (Function) callback function: function(colors) */ var getSiteColors = function (callback) { core.reportSdkMsg('Wix.Settings.getSiteColors is DEPRECATED use Wix.Styles.getSiteColors'); return Styles.getSiteColors(callback); }; /** * Get window placement for a widget * * @param compId (String) component id to change placement to * @param callback (Function) a callback function that returns the component placement * callback signature: function(data) {} */ var getWindowPlacement = function (compId, callback) { if (!compId || !callback) { core.reportSdkError('Mandatory arguments - compId & callback must be specified'); } core.sendMessage(core.MessageTypes.GET_WINDOW_PLACEMENT, { 'compId': compId }, callback); }; var getSiteInfo = function (onSuccess) { Base.getSiteInfo(onSuccess); }; var refreshApp = function (queryParams) { refreshAppByCompIds(null, queryParams); }; var refreshAppByCompIds = function (compIds, queryParams) { core.sendMessage(core.MessageTypes.REFRESH_APP, { 'queryParams': queryParams, 'compIds': compIds }); }; var openBillingPage = function () { core.sendMessage(core.MessageTypes.OPEN_BILLING_PAGE); }; var openMediaDialog = function (mediaType, multipleSelection, onSuccess, onCancel) { if (!onSuccess) { return; } mediaType = mediaType || this.MediaType.IMAGE; multipleSelection = multipleSelection || false; var onCancelCallbackSpecified = typeof onCancel === 'function'; var callback = function (data) { if (data.wasCancelled) { if (onCancelCallbackSpecified) { onCancel.apply(this, arguments); } } else { onSuccess.apply(this, arguments); } }; core.sendMessage(core.MessageTypes.OPEN_MEDIA_DIALOG, { mediaType: mediaType, multiSelection: multipleSelection, callOnCancel: onCancelCallbackSpecified }, callback); }; var triggerSettingsUpdatedEvent = function (message, compId) { message = message || {}; compId = compId || '*'; core.sendMessage(core.MessageTypes.POST_MESSAGE, { 'message': message, 'compId': compId }); }; var getSitePages = function (callback) { core.sendMessage(core.MessageTypes.GET_SITE_PAGES, null, callback); }; var setWindowPlacement = function (compId, placement, verticalMargin, horizontalMargin) { if (!compId || !placement) { core.reportSdkError('Mandatory arguments - compId & placement must be specified'); } if (!WindowPlacement.hasOwnProperty(placement)) { core.reportSdkError('Invalid argument - placement value should be set using Wix.WindowPlacement'); } core.sendMessage(core.MessageTypes.SET_WINDOW_PLACEMENT, { 'compId': compId, placement: placement, verticalMargin: verticalMargin, horizontalMargin: horizontalMargin }); }; var getDashboardAppUrl = function (callback) { if (!callback) { core.reportSdkError('Mandatory arguments - a callback must be specified'); } core.sendMessage(core.MessageTypes.GET_DASHBOARD_APP_URL, undefined, callback); }; var openModal = function (url, width, height, title, onClose) { if (!url || !width || !height) { core.reportSdkError('Mandatory arguments - url & width & height must be specified'); return; } if (!utils.isString(url)) { core.reportSdkError('Invalid argument - a Url must be of type string'); return; } if (!utils.isNumber(width) && !utils.isPercentValue(width)) { core.reportSdkError('Invalid argument - a width must be of type Number or Percentage'); return; } if (!utils.isNumber(height) && !utils.isPercentValue(height)) { core.reportSdkError('Invalid argument - a height must be of type Number or Percentage'); return; } var args = { url: url, width: width, height: height }; if (utils.isFunction(title)) { onClose = title; } else { args.title = title; } core.sendMessage(core.MessageTypes.SETTINGS_OPEN_MODAL, args, onClose); }; var closeWindow = function (message) { Base.closeWindow(message); }; return { /** * @enum * @memberof Wix.Settings * @since 1.35.0 */ MediaType: { IMAGE: 'photos', BACKGROUND: 'backgrounds', AUDIO: 'audio', DOCUMENT: 'documents', SWF: 'swf' }, getColorByreference: getColorByreference, setBooleanParam: setBooleanParam, setColorParam: setColorParam, setNumberParam: setNumberParam, getSiteColors: getSiteColors, getStyleColorByKey: getStyleColorByKey, getWindowPlacement: getWindowPlacement, /** * This method returns the URL leading to your BackOffice (AKA Business) application, in the Wix Dashboard. * The URL is fully qualified and starts with "//" for using HTTPS if supported. If the site is not saved, save dialog will be prompted. * @function * @memberof Wix.Settings * @author tomergab@wix.com * @since 1.32.0 * @param {Function} callback A callback function to receive the URL of the app in the dashboard (AKA BackOffice/Business). * @example * * Wix.Settings.getDashboardAppUrl(function(url) { * // do something with the URL * }); */ getDashboardAppUrl: getDashboardAppUrl, /** * The getsiteInfo method is used to retrieve information about the host site in which the app is shown. * @function * @memberof Wix.Settings * @since 1.12.0 * @see Wix.getSiteInfo * * @example * * Wix.Settings.getSiteInfo(function(siteInfo) { * // do something with the siteInfo * }); * */ getSiteInfo: getSiteInfo, /** * The getSitePages method is used to retrieve the site structure from the hosting Wix Platform. The site structure includes visible and hidden pages as well as sub pages. * @function * @memberof Wix.Settings * @since 1.17.0 * @see Wix.getSitePages * * @example * * Wix.Settings.getSitePages(function(sitePages) { * // do something with the site pages * }); */ getSitePages: getSitePages, /** * The getStyleParams method is used to retrieve the style parameters from the hosting Wix Platform. The parameters includes colors numbers, booleans. * @function * @memberof Wix.Settings * @deprecated Use Wix.Styles.getStyleParams * @since 1.22.0 * @param {Function} callback A callback function to receive the style parameters. * @example * * Wix.Settings.getStyleParams(function(styleParams) { * // do something with the style params * }); */ getStyleParams: getStyleParams, /** * The Setting.openBillingPage method allows the app to offer a premium package from within the app settings. * When called it will open the Wix billing system page in a new browser window. * @function * @memberof Wix.Settings * @since 1.16.0 * @example * * Wix.Settings.openBillingPage(); */ openBillingPage: openBillingPage, /** * This method opens the Wix media dialog inside the WIx Editor, and let's the site owner choose a an existing file from the Wix media galleries, * or upload a new file instead. When completed a callback function returns the meta data of the selected item/s. * This method returns a meta data descriptor for a selected media item. To access the media item from your code you will need to construct a * full URL using that descriptor. Since the media items URLs format is set by Wix and might changed in the future, * we are requiring that the URL construction will be done using the SDK. Use one of the Wix.Utils.Media.get* methods to get the desired media item URL. * @function * @memberof Wix.Settings * @since 1.17.0 * @param {Settings.MediaType} mediaType Media gallery to choose from - image, background, audio and swf. * @param {Boolean} multiSelect selection mode, single (false) or multiple (true) item to choose from. * @param {Function} onSuccess callback function, passing the media item/s meta data. * @param {Function} onCancel callback function called when user cancels. * @return This is an asynchronous function, the returned value is passed in the onSuccess callback function. * An object (single selection) or Array of objects (multiple selection). The object describes the meta data of the selected media item. * * @example * * var imageUrl = Wix.Settings.openMediaDialog(Wix.Settings.MediaType.IMAGE, false, function(data) { * // save image data * }; */ openMediaDialog: openMediaDialog, /** * Notifying the host site that the app requires reloading. * The refreshApp method is normally used when a user changes the app settings in the settings iframe, and as a result requires that the Widget or Page iframes should be reloaded such that the new settings will take affect. * The refreshApp method accepts a single optional argument, an object. Where each of the object's properties will translate into a query parameter in the iframe URL. * @function * @memberof Wix.Settings * @since 1.12.0 * @param {Object} [queryParams] A map of custom query parameters that should be added to the iframe URL. * @example * * //The App's components (all of them) will be refreshed without custom query parameters * Wix.Settings.refreshApp(); * * //The App's components (all of them) will be refreshed with custom query parameters as specified in the object argument - [BASE-URL]?[WIX-QUERY-PARAMETERS]¶m1=value1¶m2=value2 * Wix.Settings.refreshApp({param1: "value1", param2: "value2"}) */ refreshApp: refreshApp, /** * Notifying the host site that some specific components of the app requires reloading. It does the same as Settings.refreshApp but for specific components. * @function * @memberof Wix.Settings * @since 1.12.0 * @param {Array} compIds An array of the app component ids that should be refreshed. * @param {Object} [queryParams] A map of custom query parameters that should be added to the iframe URL. * @example * * //For example, if the user adds 3 components of the same app with ids: "id1", "id2" and "id3", and then he changes something in * the settings iframe that affects only 2 components display, to refresh these 2 components: * //The App's components with ids "id1" and "id3" will be refreshed without custom query parameters * Wix.Settings.refreshAppByCompIds(["id1", "id3"]); * //The App's components with ids "id1" and "id3" will be refreshed with custom query parameters as specified in the object argument - [BASE-URL]?[WIX-QUERY-PARAMETERS]¶m1=value1¶m2=value2 * Wix.Settings.refreshAppByCompIds(["id1", "id3"], {param1: "value1", param2: "value2"}); */ refreshAppByCompIds: refreshAppByCompIds, /** * The setWindowPlacement method sets the placement for fixed position widgets in an editing session. * @function * @memberof Wix.Settings * @since 1.19.0 * @param {String} compId Component id to change window placement to. * @param {WindowPlacement} placement New placement for the widget window * @param {Number} [verticalMargin] Vertical offset from the window placement * @param {Number} [horizontalMargin] Horizontal offset from the window placement * @example * * var compId = Wix.Utils.getOrigCompId(); * Wix.Settings.setWindowPlacement(compId, Wix.WindowPlacement.CENTER, 10, 20); */ setWindowPlacement: setWindowPlacement, /** * The triggerSettingsUpdatedEvent method is used from the Settings iframe to trigger a Wix.Events.SETTINGS_UPDATED event in a WIdget/Page iframe. * It should be used in an editing session when a developer wants to reflect editing changes but avoid refresh/reload on the Widget/Page iframe. * @function * @memberof Wix.Settings * @since 1.17.0 * @param {Object} message A custom JSON which will be passed to the Widget/Page as the event data. * @param {String} compId A component id we want to trigger the event on, or '*' to trigger the event on all the app components. The most obvious compId is Utils.getOrigCompId(). * @example * * Wix.Settings.triggerSettingsUpdatedEvent(message, compId); */ triggerSettingsUpdatedEvent: triggerSettingsUpdatedEvent, /** * The openModal method allows the Settings iframe to open a modal window. * * The modal window is a singleton (every new modal closes the previous one) and contains a lightbox. * * A modal can be dismissed by the user if it touches the lightbox, presses the closing button or by the app itself * if it calls the Wix.closeWindow from within the modal iframe. * * @function * @memberof Wix.Settings * @author lior.shefer@wix.com * @since 1.41.0 * @param {String} url Model iframe url. * @param {Number} width The modal window width (can be a string for percent, i.e., '90%', or an integer for pixels, i.e., 90). * @param {Number} height The modal window height (can be a string for percent, i.e., '90%', or an integer for pixels, i.e., 90). * @param {String} title Title of the modal. * @param {Function} [onClose] Onclose callback function. * @example * * var onClose = function(message) { console.log("modal closed", message); } * //Open a modal when width and height are in pixels. * Wix.Settings.openModal("http://sslstatic.wix.com/services/js-sdk/1.41.0/html/modal.html", 400, 400, "My modal's title", onClose); * * //Open a modal when width and height in percentages. * Wix.Settings.openModal("http://sslstatic.wix.com/services/js-sdk/1.41.0/html/modal.html", '70%', '90%', "My modal's title", onClose); */ openModal: openModal, /** * The closeWindow method is available only under a modal endpoint (will not have any effect for other endpoints). It allows the modal to close itself programmatically. * @function * @memberof Wix.Settings * @since 1.37.0 * @see Wix.closeWindow * @example * * // The following call will close the modal/popup window and send a the object message to the opener onClose callback * var message = {"reason": "button-clicked"}; * Wix.Settings.closeWindow(message); * */ closeWindow: closeWindow }; }(core, gaTracker, Styles, Base, WindowPlacement, utils); WixInternalSDK = undefined; /** * @memberof Wix * @namespace Contacts */ Contacts = function (core, gaTracker, responseHandlers) { var getContacts = function (options, onSuccess, onFailure) { gaTracker.trackSDKCall('Contacts.getContacts'); if (options === null || typeof options !== 'object') { core.reportSdkError('Missing mandatory argument - options, must be an object'); return; } if (typeof onSuccess !== 'function') { core.reportSdkError('Missing mandatory argument - onSuccess, must be a function'); return; } var args = { options: options }; var onComplete = function onComplete(response) { responseHandlers.handleCursorResponse(response, onSuccess, onFailure, core.MessageTypes.GET_CONTACTS, options); }; core.sendMessage(core.MessageTypes.GET_CONTACTS, args, onComplete); }; var getContactById = function (id, onSuccess, onFailure) { gaTracker.trackSDKCall('Contacts.getContactById'); if (typeof id !== 'string') { core.reportSdkError('Missing mandatory argument - id, must be a string'); return; } if (typeof onSuccess !== 'function') { core.reportSdkError('Missing mandatory argument - onSuccess, must be a function'); return; } if (typeof onFailure !== 'function') { core.reportSdkError('Missing mandatory argument - onFailure, must be a function'); return; } var args = { id: id }; var onComplete = function onComplete(response) { responseHandlers.handleDataResponse(response, onSuccess, onFailure); }; core.sendMessage(core.MessageTypes.GET_CONTACT_BY_ID, args, onComplete); }; var getContactLabels = function (onSuccess, onFailure) { gaTracker.trackSDKCall('Contacts.getContactLabels'); if (typeof onSuccess !== 'function') { core.reportSdkError('Missing mandatory argument - onSuccess, must be a function'); return; } if (typeof onFailure !== 'function') { core.reportSdkError('Missing mandatory argument - onFailure, must be a function'); return; } var onComplete = function onComplete(response) { responseHandlers.handleDataResponse(response, onSuccess, onFailure); }; core.sendMessage(core.MessageTypes.GET_CONTACT_LABELS, {}, onComplete); }; return { /** * Gets a list of all contacts that have interacted with a given site. * @memberof Wix.Contacts * @author lior.shefer@wix.com * @since 1.31.0 * @function * @param {Object} options object that supports two parameters: 'label' and 'pageSize'. * 'label' can either be a list of strings or a string. if a list, the strings are joined together with a comma * to be sent to the contacts endpoint. 'pageSize' accepts either 25, 50 or 100 and defaults to 25. * @param {Function} onSuccess An on success callback which gets WixDataCursor as parameter. * @param {Function} onFailure An on failure callback. * @return {WixDataCursor} cursor. * @example * Wix.Contacts.getContacts(function(WixDataCursor), function(errorType)); */ getContacts: getContacts, /** * Gets a specific Contact that has interacted with the current site by its id. * @memberof Wix.Contacts * @author lior.shefer@wix.com * @since 1.27.0 * @function * @param {String} id The id of the Contact to look up. * @param {Function} onSuccess A function that receives data about the Contact. * @param {Function} onFailure A function called when an error occurs that receives a Wix.Error. * @return {Contact} */ getContactById: getContactById, /** * Returns all the Contact labels for the given site that have opted in to receiving communications from applications * @memberof Wix.Contacts * @author lior.shefer@wix.com * @since 1.32.0 * @function * @param {Function} onSuccess A function that receives an array of labels. * @param {Function} onFailure A function called when an error occurs that receives a Wix.Error. * @return {String[]} An array of labels */ getContactLabels: getContactLabels }; }(core, gaTracker, responseHandlers); /** * This is the description for the PubSub namespace. * @memberof Wix * @namespace Wix.PubSub */ PubSub = function (core, utils) { var TPA_PUB_SUB_PREFIX = 'TPA_PUB_SUB_'; var unsubscribe = function (eventName, callBackOrId) { core.removeEventListenerInternal(TPA_PUB_SUB_PREFIX + eventName, callBackOrId, true); }; var subscribe = function (eventName, callBack, receivePastEvents) { if (!utils.isString(eventName)) { core.reportSdkError('Missing mandatory argument - eventName, must be a string'); return; } if (!utils.isFunction(callBack)) { core.reportSdkError('Missing mandatory argument - callBack, must be a function'); return; } return core.addEventListenerInternal(TPA_PUB_SUB_PREFIX + eventName, callBack, true, { receivePastEvents: receivePastEvents }); }; var publish = function (eventName, data, isPersistent) { if (!utils.isString(eventName)) { core.reportSdkError('Missing mandatory argument - eventName, must be a string'); return; } core.sendMessage(core.MessageTypes.PUBLISH, { eventKey: TPA_PUB_SUB_PREFIX + eventName, isPersistent: !!isPersistent || false, eventData: data || {} }); }; return { /** * Unsubscribes from receiving further events. The id from the initial subscribe call is used to unsubscribe from furthers notifications. * @memberof Wix.PubSub * @since 1.25.0 * @function * @param {String} eventName The name of the event to unsubscribe from. * @param {Function} function that will respond to events sent from other extensions of the broadcasting app. it will be given the event object itself and the source of the event. * @example * //subscribe and then unsubscribe to "my_event_name" event * var id = Wix.PubSub.subscribe("my_event_name", function(event) { }); * Wix.PubSub.unsubscribe("my_event_name", id); */ unsubscribe: unsubscribe, /** * Subscribes to events from other app parts of a multi-widget TPA. If the components span multiple pages, they will be notified once they are rendered. * It is also possible to receive all notifications prior to rendering by specifying a flag when subscribing to events. * If the flag is set, the widget will be notified immediately of any prior events of the type it is registered to receive. * @memberof Wix.PubSub * @since 1.25.0 * @function * @param {String} eventName The name of the event to subscribe to. * @param {Function} callBack function that will respond to events sent from other components of the broadcasting app. it will be given the event object itself and the source of the event. * @param {Boolean} [receivePastEvents] a flag to indicate that all past instances of the registered event should be sent to registered listener. This will happen immediately upon registration. * @example * //subscribe and then unsubscribe to "my_event_name" event * Wix.PubSub.subscribe("my_event_name", function(event) { * //process the event which has the following format : * // { * // name:eventName, * // data: eventData, * // origin: compId * // } * }); * // subscribe to "my_event_name" event, events which also happened before this component was rendered will send * Wix.PubSub.subscribe("my_event_name", function(event) { }, true); */ subscribe: subscribe, /** * Broadcasts an event to other extensions of a multi-widget TPA. * If the app extensions (Widget, Fixed Positioned Widget, Page) span multiple pages, they will be notified when they are rendered. * @memberof Wix.PubSub * @since 1.25.0 * @function * @param {String} eventName The name of the event to publish. * @param {Object} data Data the object to send to subscribers for this event type. * @param {Boolean} isPersistent Indicates whether this event is persisted for event subscribers who have not yet subscribed. * @example * // The following call will publish an app event that can be consumed by all the app parts and persist => even of those parts are not rendered yet. * Wix.PubSub.publish("my_event_name", {value:"this is my message"}, true); */ publish: publish }; }(core, utils); /** * This is the description for the Worker namespace. * @memberof Wix * @namespace Wix.Worker */ Worker = function (Base, PubSub, Utils) { var getSiteInfo = function (onSuccess) { Base.getSiteInfo(onSuccess); }; var getSitePages = function (callback) { Base.getSitePages(callback); }; var addEventListener = function (eventName, callBack) { return Base.addEventListener(eventName, callBack); }; var removeEventListener = function (eventName, callBackOrId) { return Base.removeEventListener(eventName, callBackOrId); }; var currentMember = function (onSuccess) { return Base.currentMember(onSuccess); }; var publish = function (eventKey, data, isPersistent) { return PubSub.publish(eventKey, data, isPersistent); }; var subscribe = function (eventKey, callBack, receivePastEvents) { return PubSub.subscribe(eventKey, callBack, receivePastEvents); }; var unsubscribe = function (eventKey, callBackOrId) { return PubSub.unsubscribe(eventKey, callBackOrId); }; var getViewMode = function () { return Utils.getViewMode(); }; var getDeviceType = function () { return Utils.getDeviceType(); }; var getLocale = function () { return Utils.getLocale(); }; var getInstanceId = function () { return Utils.getInstanceId(); }; var getIpAndPort = function () { return Utils.getIpAndPort(); }; var navigateToSection = function (sectionIdentifier, state, onFailure) { Utils.navigateToSection(sectionIdentifier, state, onFailure); }; return { /** * @memberof Wix.Worker * @since 1.30.0 * @see Wix.getSiteInfo */ getSiteInfo: getSiteInfo, /** * @memberof Wix.Worker * @since 1.30.0 * @see Wix.getSitePages */ getSitePages: getSitePages, /** * @memberof Worker * @since 1.30.0 * @see Wix.addEventListener */ addEventListener: addEventListener, /** * @memberof Wix.Worker * @since 1.30.0 * @see Wix.removeEventListener */ removeEventListener: removeEventListener, /** * @memberof Wix.Worker * @since 1.30.0 * @see Wix.currentMember */ currentMember: currentMember, /** * This is the description for the PubSub namespace. * @memberof Wix.Worker * @namespace Wix.Worker.PubSub */ PubSub: { /** * @since 1.30.0 * @memberof Wix.Worker.PubSub * @see Wix.PubSub.publish */ publish: publish, /** * @since 1.30.0 * @memberof Wix.Worker.PubSub * @see Wix.PubSub.subscribe */ subscribe: subscribe, /** * @since 1.30.0 * @memberof Wix.Worker.PubSub * @see Wix.PubSub.unsubscribe */ unsubscribe: unsubscribe }, /** * @memberof Wix.Worker * @namespace Wix.Worker.Utils */ Utils: { /** * @since 1.30.0 * @memberof Wix.Worker.Utils * @see Wix.Utils.getViewMode */ getViewMode: getViewMode, /** * @since 1.30.0 * @memberof Wix.Worker.Utils * @see Wix.Utils.getDeviceType */ getDeviceType: getDeviceType, /** * @since 1.30.0 * @memberof Worker.Utils * @see Wix.Utils.getLocale */ getLocale: getLocale, /** * @since 1.30.0 * @memberof Wix.Worker.Utils * @see Wix.Utils.getInstanceId */ getInstanceId: getInstanceId, /** * @since 1.30.0 * @memberof Wix.Worker.Utils * @see Wix.Utils.getDeviceType */ getIpAndPort: getIpAndPort, /** * @since 1.39.0 * @memberof Wix.Worker.Utils * @author lior.shefer@wix.com * @see Wix.Utils.navigateToSection */ navigateToSection: navigateToSection } }; }(Base, PubSub, Utils); /** * @memberof Wix * @namespace Dashboard */ Dashboard = function (core, Base, Settings) { var setHeight = function (height) { Base.setHeight(height); }; var resizeWindow = function (width, height, onComplete) { Base.resizeWindow(width, height, onComplete); }; var openMediaDialog = function (mediaType, multipleSelection, onSuccess, onCancel) { Settings.openMediaDialog(mediaType, multipleSelection, onSuccess, onCancel); }; var openBillingPage = function () { Settings.openBillingPage(); }; var openModal = function (url, width, height, onClose) { Base.openModal(url, width, height, onClose); }; var closeWindow = function (message) { Base.closeWindow(message); }; var scrollTo = function (x, y) { Base.scrollTo(x, y); }; var getEditorUrl = function (callback) { if (!callback) { core.reportSdkError('Mandatory arguments - a callback must be specified'); return; } core.sendMessage(core.MessageTypes.GET_EDITOR_URL, undefined, callback); }; var pushState = function (state) { if (typeof state !== 'string') { core.reportSdkError('Missing mandatory argument - state'); return; } core.sendMessage(core.MessageTypes.APP_STATE_CHANGED, { 'state': state }); }; return { /** * This method requests the hosting Wix platform to change the iframe height inside the side dashboard (under the My Account tab in Wix.com). Works on the app or modal iframes. * @function * @author lior.shefer@wix.com * @memberof Wix.Dashboard * @since 1.24.0 * @see Wix.setHeight * @example * * Wix.Dashboard.setHeight(height); * */ setHeight: setHeight, /** * This method opens Wix media dialog inside WIx Dashboard, and let's the site owner choose a an existing file from the Wix media galleries, * or upload a new file instead. When completed a callback function returns the meta data of the selected item/s. * This method returns a meta data descriptor for a selected media item. * To access the media item from your code you will need to construct a full URL using that descriptor. * Since the media items URLs format is set by Wix and might changed in the future, we are requiring that the URL construction will be done using the SDK. * Use one of the Wix.Utils.Media.get* methods to get the desired media item URL. * The following media type are currently supported - Wix.Settings.MediaType * @function * @author lior.shefer@wix.com * @memberof Wix.Dashboard * @since 1.27.0 * @param {Settings.MediaType} mediaType Media gallery to choose from - image, background, audio and swf. * @param {Boolean} multiSelect selection mode, single (false) or multiple (true) item to choose from. * @param {Function} onSuccess callback function, passing the media item/s meta data. * @param {Function} onCancel callback function called when user cancels. * @return This is an asynchronous function, the returned value is passed in the onSuccess callback function. * An object (single selection) or Array of objects (multiple selection). The object describes the meta data of the selected media item. * * @example * * var imageUrl = Wix.Dashboard.openMediaDialog(Wix.Settings.MediaType.IMAGE, false, function(data) { * // save image data * }; */ openMediaDialog: openMediaDialog, /** * The Dashboard.openBillingPage method allows the app to offer a premium package from within the app. * When called will open the Wix billing system page in a new browser window. * @function * @author lior.shefer@wix.com * @memberof Wix.Dashboard * @since 1.31.0 * @example * * Wix.Dashboard.openBillingPage(); * */ openBillingPage: openBillingPage, /** * The openModal method allows an app to open a modal window within the dashboard. A modal is a runtime Widget that is not part of the dashboard structure. * The modal window is a singleton (every new modal closes the previous one) and contains a lightbox. * A modal can be dismissed by the user if it touches the lightbox, presses the closing button or by the app itself * if it calls the Wix.Dashboard.closeWindow() from within the modal iframe. The onClose argument can be used to detect modal close. * @function * @memberof Wix.Dashboard * @since 1.27.0 * @see Wix.openModal * @example * * var onClose = function(message) { console.log("modal closed", message); } * Wix.Dashboard.openModal("http://sslstatic.wix.com/services/js-sdk/1.16.0/html/modal.html", 400, 400, onClose); * */ openModal: openModal, /** * The closeWindow method is available only under a modal endpoint (will not have any effect for other endpoints). It allows the modal to close itself programmatically. * @function * @memberof Dashboard * @since 1.27.0 * @see Wix.closeWindow * @example * * // The following call will close the modal/popup window and send a the object message to the opener onClose callback * var message = {"reason": "button-clicked"}; * Wix.Dashboard.closeWindow(message); * */ closeWindow: closeWindow, /** * The Dashboard.scrollTo method allows the app to scroll to an absolute offset - vertical & horizontal. * @function * @author lior.shefer@wix.com * @memberof Dashboard * @since 1.31.0 * @see Wix.scrollTo * @example * * Wix.Dashboard.scrollTo(0, 0); * */ scrollTo: scrollTo, /** * Returns the editor Url for the dashboard app. * @function * @memberof Wix.Dashboard * @since 1.33.0 * @param {Function} callback A callback which gets editor url as parameter. * @example * * Wix.Dashboard.getEditorUrl(function(url) { * //editor url as a callback parameter * }); * */ getEditorUrl: getEditorUrl, /** * This method enable AJAX style Page apps to inform the Wix platform about a change in the app internal state. The new state will be reflected in the site/page URL. * Once you call the pushState method, the browser top window URL will change the 'app-state' path part to the new state you provide with the pushState * method (similar to the browser history API - https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Manipulating_the_browser_history). * For a full explanation of how deep-linking works with AJAX style apps, see Deep Linking for AJAX Style Apps - http://dev.wix.com/docs/display/DRAF/Developing+a+Page+App. * @function * @memberof Wix.Dashboard * @since 1.35.0 * @see Wix.pushState * @example * * Wix.Dashboard.pushState("app-state"); * */ pushState: pushState, /** * Applicable only for modal component. Re-sizes the modal window. * @function * @memberof Wix.Dashboard * @author tomergab@wix.com * @since 1.40.0 * @see Wix.resizeWindow * @param {Number} width Window width in pixels. * @param {Number} height Window height in pixels. * @param [Function] onComplete On resize complete callback function. * @example * * // The following call will resize the widget window * Wix.Dashboard.resizeWindow(300, 300); * */ resizeWindow: resizeWindow }; }(core, Base, Settings); Wix = function (core, Base, Billing, utils, Activities, Settings, WixInternalSDK, Contacts, Utils, Styles, Events, Error, Media, WindowOrigin, WindowPlacement, Worker, PubSub, Dashboard, Theme) { core.init({ endpointType: core.getQueryParameter('endpointType') }); var getNamespaceToExport = function () { if (core.getQueryParameter('endpointType') === 'worker') { return { Worker: Worker, Events: Events, Error: Error }; } return getDefaultNamespaces(); }; var getDefaultNamespaces = function () { return { Activities: Activities, Billing: Billing, Contacts: Contacts, Dashboard: Dashboard, Error: Error, Events: Events, Media: Media, PubSub: PubSub, Settings: Settings, Styles: Styles, Theme: Theme, Utils: Utils, WindowOrigin: WindowOrigin, WindowPlacement: WindowPlacement, openModal: Base.openModal, openPopup: Base.openPopup, setHeight: Base.setHeight, closeWindow: Base.closeWindow, scrollTo: Base.scrollTo, scrollBy: Base.scrollBy, getSiteInfo: Base.getSiteInfo, getSitePages: Base.getSitePages, getBoundingRectAndOffsets: Base.getBoundingRectAndOffsets, removeEventListener: Base.removeEventListener, addEventListener: Base.addEventListener, resizeWindow: Base.resizeWindow, requestLogin: Base.requestLogin, currentMember: Base.currentMember, navigateToPage: Base.navigateToPage, getCurrentPageId: Base.getCurrentPageId, pushState: Base.pushState, reportHeightChange: Base.reportHeightChange, getStyleParams: Base.getStyleParams }; }; return getNamespaceToExport(); }(core, Base, Billing, utils, Activities, Settings, WixInternalSDK, Contacts, Utils, Styles, Events, Error, Media, WindowOrigin, WindowPlacement, Worker, PubSub, Dashboard, Theme); window.Wix = Wix; }());