UNPKG

ibm-mfp-web-sdk

Version:

IBM MobileFirst Platform Foundation Web Environment SDK

1,536 lines (1,338 loc) 311 kB
/** * @license Licensed Materials - Property of IBM (C) Copyright 2015 IBM Corp. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /** * This file is a wrapper for the web SDK which is in target/jslibexpanded/app/web/worklight.js * Its purpose is to make the web SDK as an AMD module. * * There is a placeholder in this file which will be replaced with the web sdk during the build of client-javascript. * The replacement is defined in expandjslib.xml inside buildEnv_web target * After the replacement the file will be renamed to worklight.js */ (function (root, factory) { var wlanalytics = dummyanalytics();//This function is being injected later on the "skeleton.placeholder" below // scripts which are AMD defined by calling define function // if 'define' is in our global name space then we expose our web SDK as an AMD module with one dependency: wlanalytics. if (typeof define === 'function' && define.amd) { if (!require.specified('ibmmfpfanalytics')) { define("ibmmfpfanalytics",function() { return dummyanalytics(); }); } define(['ibmmfpfanalytics'], factory); } else { // not using 'define', so we expose our web sdk (WL) to the global name space. // if wlanalytics is not in the global name space, we use dummy implementation for them if (!root.ibmmfpfanalytics) { root.ibmmfpfanalytics = wlanalytics; } root.WL = factory(root.ibmmfpfanalytics); } function dummyanalytics() { logger = { pkg: _apiAnalyticsMissing, state: _apiAnalyticsMissing, capture: _apiAnalyticsMissing, enable: _apiAnalyticsMissing, updateConfigFromServer: _apiAnalyticsMissing, trace : _apiAnalyticsMissing, debug : _apiAnalyticsMissing, log : _apiAnalyticsMissing, info : _apiAnalyticsMissing, warn : _apiAnalyticsMissing, error : _apiAnalyticsMissing, fatal : _apiAnalyticsMissing }; return { init: _apiAnalyticsMissing, enable : _apiAnalyticsMissing, state: _apiAnalyticsMissing, send: _apiAnalyticsMissing, setUserContext: _apiAnalyticsMissing, addEvent: _apiAnalyticsMissing, enableAutoSend: _apiAnalyticsMissing, _setClientId: _apiAnalyticsMissing, logger: logger } function _apiAnalyticsMissing(message){ var textMssg = ''; if (typeof message === 'string'){ textMssg = ' (message sent: ' + message + ')'; } console.log("Sending analytics data to the MobileFirst Analytics server is ignored. Are you sure the MobileFirst Analytics JavaScript file is included in your project?." + textMssg); }; }; }(this, function(wlanalytics) { /** * ================================================================= * Source file taken from :: wldeferredjs.js * ================================================================= */ /* Licensed Materials - Property of IBM (C) Copyright 2016 IBM Corp. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /** * @license * deferred-js https://github.com/warpdesign/deferred-js#licence * Copyright 2012 © Nicolas Ramz * Released under the MIT license */ (function(global) { function isArray(arr) { return Object.prototype.toString.call(arr) === '[object Array]'; } function foreach(arr, handler) { if (isArray(arr)) { for (var i = 0; i < arr.length; i++) { handler(arr[i]); } } else handler(arr); } function D(fn) { var status = 'pending', doneFuncs = [], failFuncs = [], progressFuncs = [], resultArgs = null, promise = { done: function() { for (var i = 0; i < arguments.length; i++) { // skip any undefined or null arguments if (!arguments[i]) { continue; } if (isArray(arguments[i])) { var arr = arguments[i]; for (var j = 0; j < arr.length; j++) { // immediately call the function if the deferred has been resolved if (status === 'resolved') { arr[j].apply(this, resultArgs); } doneFuncs.push(arr[j]); } } else { // immediately call the function if the deferred has been resolved if (status === 'resolved') { arguments[i].apply(this, resultArgs); } doneFuncs.push(arguments[i]); } } return this; }, fail: function() { for (var i = 0; i < arguments.length; i++) { // skip any undefined or null arguments if (!arguments[i]) { continue; } if (isArray(arguments[i])) { var arr = arguments[i]; for (var j = 0; j < arr.length; j++) { // immediately call the function if the deferred has been resolved if (status === 'rejected') { arr[j].apply(this, resultArgs); } failFuncs.push(arr[j]); } } else { // immediately call the function if the deferred has been resolved if (status === 'rejected') { arguments[i].apply(this, resultArgs); } failFuncs.push(arguments[i]); } } return this; }, always: function() { return this.done.apply(this, arguments).fail.apply(this, arguments); }, progress: function() { for (var i = 0; i < arguments.length; i++) { // skip any undefined or null arguments if (!arguments[i]) { continue; } if (isArray(arguments[i])) { var arr = arguments[i]; for (var j = 0; j < arr.length; j++) { // immediately call the function if the deferred has been resolved if (status === 'pending') { progressFuncs.push(arr[j]); } } } else { // immediately call the function if the deferred has been resolved if (status === 'pending') { progressFuncs.push(arguments[i]); } } } return this; }, then: function() { // fail callbacks if (arguments.length > 1 && arguments[1]) { this.fail(arguments[1]); } // done callbacks if (arguments.length > 0 && arguments[0]) { this.done(arguments[0]); } // notify callbacks if (arguments.length > 2 && arguments[2]) { this.progress(arguments[2]); } }, promise: function(obj) { if (obj == null) { return promise; } else { for (var i in promise) { obj[i] = promise[i]; } return obj; } }, state: function() { return status; }, debug: function() { console.log('[debug]', doneFuncs, failFuncs, status); }, isRejected: function() { return status === 'rejected'; }, isResolved: function() { return status === 'resolved'; }, pipe: function(done, fail, progress) { return D(function(def) { foreach(done, function(func) { // filter function if (typeof func === 'function') { deferred.done(function() { var returnval = func.apply(this, arguments); // if a new deferred/promise is returned, its state is passed to the current deferred/promise if (returnval && typeof returnval === 'function') { returnval.promise().then(def.resolve, def.reject, def.notify); } else { // if new return val is passed, it is passed to the piped done def.resolve(returnval); } }); } else { deferred.done(def.resolve); } }); foreach(fail, function(func) { if (typeof func === 'function') { deferred.fail(function() { var returnval = func.apply(this, arguments); if (returnval && typeof returnval === 'function') { returnval.promise().then(def.resolve, def.reject, def.notify); } else { def.reject(returnval); } }); } else { deferred.fail(def.reject); } }); }).promise(); } }, deferred = { resolveWith: function(context) { if (status === 'pending') { status = 'resolved'; var args = resultArgs = (arguments.length > 1) ? arguments[1] : []; for (var i = 0; i < doneFuncs.length; i++) { doneFuncs[i].apply(context, args); } } return this; }, rejectWith: function(context) { if (status === 'pending') { status = 'rejected'; var args = resultArgs = (arguments.length > 1) ? arguments[1] : []; for (var i = 0; i < failFuncs.length; i++) { failFuncs[i].apply(context, args); } } return this; }, notifyWith: function(context) { if (status === 'pending') { var args = resultArgs = (arguments.length > 1) ? arguments[1] : []; for (var i = 0; i < progressFuncs.length; i++) { progressFuncs[i].apply(context, args); } } return this; }, resolve: function() { return this.resolveWith(this, arguments); }, reject: function() { return this.rejectWith(this, arguments); }, notify: function() { return this.notifyWith(this, arguments); } } var obj = promise.promise(deferred); if (fn) { fn.apply(obj, [obj]); } return obj; } D.when = function() { if (arguments.length < 2) { var obj = arguments.length ? arguments[0] : undefined; if (obj && (typeof obj.isResolved === 'function' && typeof obj.isRejected === 'function')) { return obj.promise(); } else { return D().resolve(obj).promise(); } } else { return (function(args){ var df = D(), size = args.length, done = 0, rp = new Array(size); // resolve params: params of each resolve, we need to track down them to be able to pass them in the correct order if the master needs to be resolved for (var i = 0; i < args.length; i++) { (function(j) { var obj = null; if (args[j].done) { args[j].done(function() { rp[j] = (arguments.length < 2) ? arguments[0] : arguments; if (++done == size) { df.resolve.apply(df, rp); }}) .fail(function() { df.reject(arguments); }); } else { obj = args[j]; args[j] = new Deferred(); args[j].done(function() { rp[j] = (arguments.length < 2) ? arguments[0] : arguments; if (++done == size) { df.resolve.apply(df, rp); }}) .fail(function() { df.reject(arguments); }).resolve(obj); } })(i); } return df.promise(); })(arguments); } }, D.isEmptyObject = function( obj ) { var name; for ( name in obj ) { return false; } return true; } global.Deferred = D; global.WLJQ = D; global.WLJQ.Deferred = function () { return new Deferred(); } })(window);/* Licensed Materials - Property of IBM (C) Copyright 2015 IBM Corp. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /** * ================================================================= * Source file taken from :: stacktrace.min.js * ================================================================= */ // Domain Public by Eric Wendelin http://eriwen.com/ (2008) // Luke Smith http://lucassmith.name/ (2008) // Loic Dachary <loic@dachary.org> (2008) // Johan Euphrosine <proppy@aminche.com> (2008) // Oyvind Sean Kinsey http://kinsey.no/blog (2010) // Victor Homyakov <victor-homyakov@users.sourceforge.net> (2010) // https://github.com/eriwen/javascript-stacktrace/blob/v0.5.0/stacktrace.js function printStackTrace(e){e=e||{guess:true};var t=e.e||null,n=!!e.guess;var r=new printStackTrace.implementation,i=r.run(t);return n?r.guessAnonymousFunctions(i):i}if(typeof module!=="undefined"&&module.exports){module.exports=printStackTrace}printStackTrace.implementation=function(){};printStackTrace.implementation.prototype={run:function(e,t){e=e||this.createException();t=t||this.mode(e);if(t==="other"){return this.other(arguments.callee)}else{return this[t](e)}},createException:function(){try{this.undef()}catch(e){return e}},mode:function(e){if(e["arguments"]&&e.stack){return"chrome"}else if(e.stack&&e.sourceURL){return"safari"}else if(e.stack&&e.number){return"ie"}else if(typeof e.message==="string"&&typeof window!=="undefined"&&window.opera){if(!e.stacktrace){return"opera9"}if(e.message.indexOf("\n")>-1&&e.message.split("\n").length>e.stacktrace.split("\n").length){return"opera9"}if(!e.stack){return"opera10a"}if(e.stacktrace.indexOf("called from line")<0){return"opera10b"}return"opera11"}else if(e.stack){return"firefox"}return"other"},instrumentFunction:function(e,t,n){e=e||window;var r=e[t];e[t]=function(){n.call(this,printStackTrace().slice(4));return e[t]._instrumented.apply(this,arguments)};e[t]._instrumented=r},deinstrumentFunction:function(e,t){if(e[t].constructor===Function&&e[t]._instrumented&&e[t]._instrumented.constructor===Function){e[t]=e[t]._instrumented}},chrome:function(e){var t=(e.stack+"\n").replace(/^\S[^\(]+?[\n$]/gm,"").replace(/^\s+(at eval )?at\s+/gm,"").replace(/^([^\(]+?)([\n$])/gm,"{anonymous}()@$1$2").replace(/^Object.<anonymous>\s*\(([^\)]+)\)/gm,"{anonymous}()@$1").split("\n");t.pop();return t},safari:function(e){return e.stack.replace(/\[native code\]\n/m,"").replace(/^(?=\w+Error\:).*$\n/m,"").replace(/^@/gm,"{anonymous}()@").split("\n")},ie:function(e){var t=/^.*at (\w+) \(([^\)]+)\)$/gm;return e.stack.replace(/at Anonymous function /gm,"{anonymous}()@").replace(/^(?=\w+Error\:).*$\n/m,"").replace(t,"$1@$2").split("\n")},firefox:function(e){return e.stack.replace(/(?:\n@:0)?\s+$/m,"").replace(/^[\(@]/gm,"{anonymous}()@").split("\n")},opera11:function(e){var t="{anonymous}",n=/^.*line (\d+), column (\d+)(?: in (.+))? in (\S+):$/;var r=e.stacktrace.split("\n"),i=[];for(var s=0,o=r.length;s<o;s+=2){var u=n.exec(r[s]);if(u){var a=u[4]+":"+u[1]+":"+u[2];var f=u[3]||"global code";f=f.replace(/<anonymous function: (\S+)>/,"$1").replace(/<anonymous function>/,t);i.push(f+"@"+a+" -- "+r[s+1].replace(/^\s+/,""))}}return i},opera10b:function(e){var t=/^(.*)@(.+):(\d+)$/;var n=e.stacktrace.split("\n"),r=[];for(var i=0,s=n.length;i<s;i++){var o=t.exec(n[i]);if(o){var u=o[1]?o[1]+"()":"global code";r.push(u+"@"+o[2]+":"+o[3])}}return r},opera10a:function(e){var t="{anonymous}",n=/Line (\d+).*script (?:in )?(\S+)(?:: In function (\S+))?$/i;var r=e.stacktrace.split("\n"),i=[];for(var s=0,o=r.length;s<o;s+=2){var u=n.exec(r[s]);if(u){var a=u[3]||t;i.push(a+"()@"+u[2]+":"+u[1]+" -- "+r[s+1].replace(/^\s+/,""))}}return i},opera9:function(e){var t="{anonymous}",n=/Line (\d+).*script (?:in )?(\S+)/i;var r=e.message.split("\n"),i=[];for(var s=2,o=r.length;s<o;s+=2){var u=n.exec(r[s]);if(u){i.push(t+"()@"+u[2]+":"+u[1]+" -- "+r[s+1].replace(/^\s+/,""))}}return i},other:function(e){var t="{anonymous}",n=/function\s*([\w\-$]+)?\s*\(/i,r=[],i,s,o=10;while(e&&e["arguments"]&&r.length<o){i=n.test(e.toString())?RegExp.$1||t:t;s=Array.prototype.slice.call(e["arguments"]||[]);r[r.length]=i+"("+this.stringifyArguments(s)+")";e=e.caller}return r},stringifyArguments:function(e){var t=[];var n=Array.prototype.slice;for(var r=0;r<e.length;++r){var i=e[r];if(i===undefined){t[r]="undefined"}else if(i===null){t[r]="null"}else if(i.constructor){if(i.constructor===Array){if(i.length<3){t[r]="["+this.stringifyArguments(i)+"]"}else{t[r]="["+this.stringifyArguments(n.call(i,0,1))+"..."+this.stringifyArguments(n.call(i,-1))+"]"}}else if(i.constructor===Object){t[r]="#object"}else if(i.constructor===Function){t[r]="#function"}else if(i.constructor===String){t[r]='"'+i+'"'}else if(i.constructor===Number){t[r]=i}}}return t.join(",")},sourceCache:{},ajax:function(e){var t=this.createXMLHTTPObject();if(t){try{t.open("GET",e,false);t.send(null);return t.responseText}catch(n){}}return""},createXMLHTTPObject:function(){var e,t=[function(){return new XMLHttpRequest},function(){return new ActiveXObject("Msxml2.XMLHTTP")},function(){return new ActiveXObject("Msxml3.XMLHTTP")},function(){return new ActiveXObject("Microsoft.XMLHTTP")}];for(var n=0;n<t.length;n++){try{e=t[n]();this.createXMLHTTPObject=t[n];return e}catch(r){}}},isSameDomain:function(e){return typeof location!=="undefined"&&e.indexOf(location.hostname)!==-1},getSource:function(e){if(!(e in this.sourceCache)){this.sourceCache[e]=this.ajax(e).split("\n")}return this.sourceCache[e]},guessAnonymousFunctions:function(e){for(var t=0;t<e.length;++t){var n=/\{anonymous\}\(.*\)@(.*)/,r=/^(.*?)(?::(\d+))(?::(\d+))?(?: -- .+)?$/,i=e[t],s=n.exec(i);if(s){var o=r.exec(s[1]);if(o){var u=o[1],a=o[2],f=o[3]||0;if(u&&this.isSameDomain(u)&&a){var l=this.guessAnonymousFunction(u,a,f);e[t]=i.replace("{anonymous}",l)}}}}return e},guessAnonymousFunction:function(e,t,n){var r;try{r=this.findFunctionName(this.getSource(e),t)}catch(i){r="getSource failed with url: "+e+", exception: "+i.toString()}return r},findFunctionName:function(e,t){var n=/function\s+([^(]*?)\s*\(([^)]*)\)/;var r=/['"]?([$_A-Za-z][$_A-Za-z0-9]*)['"]?\s*[:=]\s*function\b/;var i=/['"]?([$_A-Za-z][$_A-Za-z0-9]*)['"]?\s*[:=]\s*(?:eval|new Function)\b/;var s="",o,u=Math.min(t,20),a,f;for(var l=0;l<u;++l){o=e[t-l-1];f=o.indexOf("//");if(f>=0){o=o.substr(0,f)}if(o){s=o+s;a=r.exec(s);if(a&&a[1]){return a[1]}a=n.exec(s);if(a&&a[1]){return a[1]}a=i.exec(s);if(a&&a[1]){return a[1]}}}return"(?)"}} /** * ================================================================= * Source file taken from :: wljsx.js * ================================================================= */ /* Licensed Materials - Property of IBM (C) Copyright 2015 IBM Corp. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /*globals WLJSX, WLJQ*/ /*jshint unused:false*/ function __WL() {} var WL = WL ? WL : {}; window.WLJSX = { /*jshint strict:false*/ /* * Constant values, required for prototype.js functionality */ emptyFunction: function() {}, /** * Search for an element with a specified ID and returns it as a DOM element. * Returns null if element is not found * * @Param selector - a string with the requires DOM element's Id */ $: function(id) { var elements = WLJQ('#' + id); if (elements.length === 0) { return null; } else { return elements[0]; } }, /** * Searches for the elements with a specified selector and returns them as an array of DOM elements * * @Param selector - a string representing a CSS selector */ $$: function(selector) { return WLJQ(selector); }, $$$: function(elem) { var elements = WLJQ(elem); if (elements.length === 0) { return null; } else { return elements[0]; } }, /** * Same as $$ but searches inside of a given element only. Returns array of DOM elements * * @Param el - the DOM element to search inside of * @Param selector - a string representing a CSS selector */ find: function(el, selector) { return WLJQ(el).find(selector); }, /** * Creates a new DOM element and returns it * * @Param type - a string representing the element type (tag name, e.g. '<div/>') * @Param attrs - an object of attributes to be added to newly created element */ newElement: function(type, attrs) { return WLJQ(type, attrs)[0]; }, /** * Appends the content before the end of a DOM element * * @Param el - the DOM element (or CSS selector string) to append content to * @Param content - new content to be appended */ append: function(el, content) { WLJQ(el).append(content); }, /** * Prepends the content at the beginning of a DOM element * * @Param el - the DOM element (or CSS selector string) to prepend content to * @Param content - new content to be prepended */ prepend: function(el, content) { WLJQ(el).prepend(content); }, /** * Sets or Gets DOM element's content * * @Param el - the DOM element to update content in * @Param content - new content, can be string or other DOM elements */ html: function(el, content) { if (content) { WLJQ(el).html(content); } else { return WLJQ(el).html(); } }, /** * Empties the content of a given DOM element * * @Param el - the DOM element (or CSS selector string) to empty */ empty: function(el) { WLJQ(el).empty(); }, /** * Shows a DOM element (makes visible) * * @Param el - the DOM element (or CSS selector string) to make visible */ show: function(el) { WLJQ(el).show(); }, /** * Hides a DOM element (makes invisible) * * @Param el - the DOM element (or CSS selector string) to hide */ hide: function(el) { WLJQ(el).hide(); }, /** * Adds a specified CSS class to DOM elements * * @Param el - the DOM element (or CSS selector string) to add the CSS class to * @Param className - string with the class' name */ addClass: function(el, className) { WLJQ(el).addClass(className); }, /** * Removes a specified CSS class from DOM elements * * @Param el - the DOM element (or CSS selector string) to remove the CSS class from * @Param className - string with the class' name */ removeClass: function(el, className) { WLJQ(el).removeClass(className); }, /** * Sets or Gets the width of a DOM element (first one in case several elements fit CSS selector) * * @Param el - the DOM element to get/set width * @Param width - new width to set */ width: function(el, width) { if (width) { WLJQ(el).width(width); } else { return WLJQ(el).width(); } }, /** * Sets or Gets the height of a DOM element (first one in case several elements fit CSS selector) * * @Param el - the DOM element to get/set height * @Param height - new height to set */ height: function(el, height) { if (height) { WLJQ(el).height(height); } else { return WLJQ(el).height(); } }, /** * Removes an element from the DOM. * * @Param el - the DOM element (or CSS selector string) to remove */ remove: function(el) { WLJQ(el).remove(); }, /** * Sets specific CSS style on the DOM elements * * @Param el - the DOM element (or CSS selector string) to set CSS style on * @Param style - an object of CSS styles to be set */ css: function(el, style) { WLJQ(el).css(style); }, /** * Sets or Gets the attribute of a DOM element * * @Param el - the DOM element to get/set attribute * @Param attrName - the name of an attribute * @Param attrValue - the new value of the attribute */ attr: function(el, attrName, attrValue) { if (attrValue) { WLJQ(el).attr(attrName, attrValue); } else { return WLJQ(el).attr(attrName); } }, /** * Adds the event listener to DOM elements for a specified event * * @Param el - the DOM element (or CSS selector string) to add event listener to * @Param event - string with the event's name, e.g. 'click', 'change' etc. * @Param callback - a JavaScript function to be invoked once event is triggered */ bind: function(el, event, callback) { WLJQ(el).bind(event, callback); }, /** * Removes the event listener from DOM elements * * @Param el - the DOM element (or CSS selector string) to remove event listener form * @Param event - string with the event's name, e.g. 'click', 'change' etc. */ unbind: function(el, event) { if (event) { WLJQ(el).unbind(event); } else { WLJQ(el).unbind(); } }, /** * Triggers a specific event on DOM elements * * @Param el - the DOM element (or CSS selector string) to trigger the event on * @Param event - string with the event's name, e.g. 'click', 'change' etc. */ trigger: function(el, event) { WLJQ(el).trigger(event); }, /** * Retrieves the element that triggered the event (event's target) * * @Param event - event to get the target from */ eventTarget: function(event) { return event.target; }, /* * Detects browser types. Implementation taken from Prototype.js */ detectBrowser: function() { var userAgent = navigator.userAgent; /*jshint eqeqeq:false*/ var isOpera = Object.prototype.toString.call(window.opera) == '[object Opera]'; return { isIE: !!window.attachEvent && !isOpera, isOpera: isOpera, isWebKit: userAgent.indexOf('AppleWebKit/') > -1, isGecko: userAgent.indexOf('Gecko') > -1 && userAgent.indexOf('KHTML') === -1, isMobileSafari: /Apple.*Mobile/.test(userAgent), isWP81RT: userAgent.indexOf('Windows Phone 8.1') > -1 }; }, /* * Returns viewport root element depending on a browser. Implementation taken from Prototype.js */ getViewportRootElement: function() { var browser = WLJSX.detectBrowser(); if (browser.isWebKit && !document.evaluate) { return document; } if (browser.isOpera && window.parseFloat(window.opera.version()) < 9.5) { return document.body; } return document.documentElement; }, /* * Returns the width of a viewport */ getViewportWidth: function() { return (this.getViewportRootElement())['clientWidth']; }, /* * Returns the height of a viewport */ getViewportHeight: function() { return (this.getViewportRootElement())['clientHeight']; }, isEmptyObject: function(obj) { return WLJQ.isEmptyObject(obj); } }; /* * The following namespaces are taken from prototypejs framework and adopted to work with MobileFirst Platform */ /* * Class object defines a Class.create API for object oriented JS approach */ window.WLJSX.Class = (function() { var IS_DONTENUM_BUGGY = (function() { for (var p in { toString: 1 }) { if (p === 'toString') { return false; } } return true; })(); function subclass() {} function create() { var parent = null; var properties = WLJSX.Object.toArray(arguments); if (WLJSX.Object.isFunction(properties[0])) { parent = properties.shift(); } function klass() { this.initialize.apply(this, arguments); } WLJSX.Object.extend(klass, WLJSX.Class.Methods); klass.superclass = parent; klass.subclasses = []; if (parent) { subclass.prototype = parent.prototype; /*jshint newcap:false*/ klass.prototype = new subclass(); parent.subclasses.push(klass); } for (var i = 0, length = properties.length; i < length; i++) { klass.addMethods(properties[i]); } if (!klass.prototype.initialize) { klass.prototype.initialize = WLJSX.emptyFunction; } klass.prototype.constructor = klass; return klass; } function addMethods(source) { var ancestor = this.superclass && this.superclass.prototype, properties = WLJSX.Object.keys(source); if (IS_DONTENUM_BUGGY) { /*jshint eqeqeq:false*/ if (source.toString != Object.prototype.toString) { properties.push('toString'); } if (source.valueOf != Object.prototype.valueOf) { properties.push('valueOf'); } } for (var i = 0, length = properties.length; i < length; i++) { var property = properties[i], value = source[property]; if (ancestor && WLJSX.Object.isFunction(value) && value.argumentNames()[0] == '__super') { var method = value; /*jshint -W083*/ value = (function(m) { return function() { return ancestor[m].apply(this, arguments); }; }) (property).wrap(method); value.valueOf = method.valueOf.bind(method); value.toString = method.toString.bind(method); } this.prototype[property] = value; } return this; } return { create: create, Methods: { addMethods: addMethods } }; })(); /* * WLJSX.Object APIs are responsible for Object related functionality * * WLJSX.Object.objectSize(obj) - returns the number of properties in the supplied object * WLJSX.Object.toArray(iterable) - coverts object to array * WLJSX.Object.toJSON(obj) - converts object to it's JSON representation * WLJSX.Object.extend(destination, source) - extends destination object with properties from the source object * WLJSX.Object.toQueryString(obj) - converts object to a query string * WLJSX.Object.keys(obj) - returns object keys as array * WLJSX.Object.clone(obj) - returns a new copy of a supplied object * WLJSX.Object.isArray(obj) - checks whether object is an array * WLJSX.Object.isFunction(obj) - checks whether object is a function * WLJSX.Object.isString(obj) - checks whether object is a string * WLJSX.Object.isNumber(obj) - checks whether object is a number * WLJSX.Object.isDate(obj) - checks whether object is a date * WLJSX.Object.isUndefined(obj) - checks whether object is undefined */ window.WLJSX.Object = { _toString: Object.prototype.toString, NULL_TYPE: 'Null', UNDEFINED_TYPE: 'Undefined', BOOLEAN_TYPE: 'Boolean', NUMBER_TYPE: 'Number', STRING_TYPE: 'String', OBJECT_TYPE: 'Object', FUNCTION_CLASS: '[object Function]', BOOLEAN_CLASS: '[object Boolean]', NUMBER_CLASS: '[object Number]', STRING_CLASS: '[object String]', ARRAY_CLASS: '[object Array]', DATE_CLASS: '[object Date]', NATIVE_JSON_STRINGIFY_SUPPORT: (window.JSON && typeof JSON.stringify === 'function' && JSON.stringify(0) === '0' && typeof JSON.stringify(function(x) { return x; }) === 'undefined'), objectSize: function(obj) { var count = 0; /*jshint forin:false*/ for (var key in obj) { count++; } return count; }, toArray: function(iterable) { if (!iterable) { return []; } if ('toArray' in Object(iterable)) { return iterable.toArray(); } var length = iterable.length || 0; var result = new Array(length); while (length--) { result[length] = iterable[length]; } return result; }, Type: function(o) { switch (o) { case null: return WLJSX.Object.NULL_TYPE; case (void 0): return WLJSX.Object.UNDEFINED_TYPE; } var type = typeof o; switch (type) { case 'boolean': return WLJSX.Object.BOOLEAN_TYPE; case 'number': return WLJSX.Object.NUMBER_TYPE; case 'string': return WLJSX.Object.STRING_TYPE; } return WLJSX.Object.OBJECT_TYPE; }, extend: function(destination, source) { /*jshint forin:false*/ for (var property in source) { destination[property] = source[property]; } return destination; }, toJSON: function(object) { if (WLJSX.Object.NATIVE_JSON_STRINGIFY_SUPPORT) { return JSON.stringify(object); } else { return WLJSX.Object.Str('', { '': object }, []); } }, Str: function(key, holder, stack) { var value = holder[key]; var type = typeof value; if (WLJSX.Object.Type(value) === WLJSX.Object.OBJECT_TYPE && typeof value.toJSON === 'function') { value = value.toJSON(key); } var _class = WLJSX.Object._toString.call(value); switch (_class) { case WLJSX.Object.NUMBER_CLASS: case WLJSX.Object.BOOLEAN_CLASS: case WLJSX.Object.STRING_CLASS: value = value.valueOf(); } switch (value) { case null: return 'null'; case true: return 'true'; case false: return 'false'; } type = typeof value; switch (type) { case 'string': return value; case 'number': return isFinite(value) ? String(value) : 'null'; case 'object': for (var i = 0, length = stack.length; i < length; i++) { if (stack[i] === value) { throw new TypeError(); } } stack.push(value); var partial = []; if (_class === WLJSX.Object.ARRAY_CLASS) { for (i = 0, length = value.length; i < length; i++) { var str = WLJSX.Object.Str(i, value, stack); partial.push(typeof str === 'undefined' ? 'null' : str); } partial = '[' + partial.join(',') + ']'; } else { var keys = WLJSX.Object.keys(value); for (i = 0, length = keys.length; i < length; i++) { key = keys[i]; var strResult = WLJSX.Object.Str(key, value, stack); if (typeof strResult !== 'undefined') { partial.push(WLJSX.String.inspect(key, true) + ':' + strResult); } } partial = '{' + partial.join(',') + '}'; } stack.pop(); return partial; } }, toQueryString: function(object) { var results = []; /*jshint forin:false*/ for (var key in object) { key = encodeURIComponent(key); var value = object[key]; var queryPair = (WLJSX.Object.isUndefined(value)) ? key : key + '=' + encodeURIComponent(WLJSX.String.interpret(value)); results.push(queryPair); } return results.join('&'); }, keys: function(object) { if (WLJSX.Object.Type(object) !== WLJSX.Object.OBJECT_TYPE) { throw new TypeError(); } var results = []; for (var property in object) { if (object.hasOwnProperty(property)) { results.push(property); } } return results; }, clone: function(object) { return WLJSX.Object.extend({}, object); }, isArray: function(object) { if ((typeof Array.isArray === 'function') && Array.isArray([]) && !Array.isArray({})) { return Array.isArray(object); } else { return WLJSX.Object._toString.call(object) === WLJSX.Object.ARRAY_CLASS; } }, isFunction: function(object) { return WLJSX.Object._toString.call(object) === WLJSX.Object.FUNCTION_CLASS; }, isString: function(object) { return WLJSX.Object._toString.call(object) === WLJSX.Object.STRING_CLASS; }, isNumber: function(object) { return WLJSX.Object._toString.call(object) === WLJSX.Object.NUMBER_CLASS; }, isDate: function(object) { return WLJSX.Object._toString.call(object) === WLJSX.Object.DATE_CLASS; }, isUndefined: function(object) { return typeof object === 'undefined'; } }; /*jshint -W100*/ /* * WLJSX.String APIs are responsible for String related functionality * * WLJSX.String.stripScripts(str) - stripts <script> tags from string * WLJSX.String.escapeHTML(str) - replaces &, < and > characters with their escaped HTML values * WLJSX.String.inspect(str) - Returns a debug-oriented version of the string (i.e. wrapped in single or double quotes, with backslashes and quotes escaped) * WLJSX.String.interpret(str) - Forces value into a string. Returns an empty string for null * WLJSX.String.strip(str) - Strips all leading and trailing whitespace from a string * WLJSX.String.isJSON(str) - validates whether string is a valid JSON representation * WLJSX.String.isBlank(str) - Check if the string is 'blank' � either empty (length of 0) or containing only whitespace. * WLJSX.String.unfilterJSON(str) - Strips comment delimiters around Ajax JSON or JavaScript responses. This security method is called internally * WLJSX.String.evalJSON(str) - Evaluates the JSON in the string and returns the resulting object * WLJSX.String.parseResponseHeaders(str) - Parses the string returned by the XMLHttpRequest.getAllResponseHeaders() method and returns an map holding the response headers * WLJSX.String.getHeaderByKey(headers, key) - case insenstive search in a map for a given key, Returns the header as json */ window.WLJSX.String = { specialChar: { '\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '\\': '\\\\' }, stripScripts: function(str) { return str.replace(new RegExp('<script[^>]*>([\\S\\s]*?)<\/script>', 'img'), ''); }, escapeHTML: function(str) { return str.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;'); }, interpret: function(str) { return str === null ? '' : String(str); }, strip: function(str) { return str.replace(/^\s+/, '').replace(/\s+$/, ''); }, toQueryParams: function(str) { var match = WLJSX.String.strip(str).match(/([^?#]*)(#.*)?$/); if (!match) { return {}; } var paramsArray = match[1].split('&'); var paramsObj = {}; for (var i = 0; i < paramsArray.length; i++) { var pair = paramsArray[i].split('='); if (pair[0]) { (pair.shift()).toString().replace(/%/g , '%25'); var key = decodeURIComponent(pair.shift()); var value = pair.length > 1 ? pair.join('=') : pair[0]; if (value !== undefined) { value = decodeURIComponent(value); } paramsObj[key] = value; } } return paramsObj; }, isJSON: function(str) { if (WLJSX.String.isBlank(str)) { return false; } str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'); str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'); str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, ''); return (/^[\],:{}\s]*$/).test(str); }, isBlank: function(str) { return (/^\s*$/).test(str); }, inspect: function(str, useDoubleQuotes) { var escapedString = str.replace(/[\x00-\x1f\\]/g, function(character) { if (character in WLJSX.String.specialChar) { return WLJSX.String.specialChar[character]; } return '\\u00' + character.charCodeAt().toPaddedString(2, 16); }); if (useDoubleQuotes) { return '"' + escapedString.replace(/"/g, '\\"') + '"'; } return '\'' + escapedString.replace(/'/g, '\\\'') + '\''; }, unfilterJSON: function(str) { return str.replace(/^\/\*-secure-([\s\S]*)\*\/\s*$/, '$1'); }, evalJSON: function(str, sanitize) { var json = WLJSX.String.unfilterJSON(str); if (window.JSON && typeof JSON.parse === 'function' && JSON.parse('{"test": true}').test) { // Native json parse support return JSON.parse(json); } else { // No native json parse support var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g; if (cx.test(json)) { json = json.replace(cx, function(a) { return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); }); } try { if (!sanitize || WLJSX.String.isJSON(json)) { /*jshint evil:true*/ return eval('(' + json + ')'); } } catch (e) {} throw new SyntaxError('Badly formed JSON string: ' + WLJSX.String.inspect(str)); } }, parseResponseHeaders: function(responseHeadersString) { var responseHeaders = {}; if (responseHeadersString !== null && typeof (responseHeadersString) !== 'undefined') { var delimiter = responseHeadersString.indexOf('\r') > -1 ? '\r\n' : '\n'; var allHeaders = responseHeadersString.split(delimiter); /*jshint maxdepth:4*/ for (var i = 0; i < allHeaders.length; i++) { var pair = allHeaders[i]; var index = pair.indexOf(': '); /*jshint maxdepth:5*/ if (index > 0) { var key = pair.substring(0, index); var value = pair.substring(index + 2); responseHeaders[key] = value; } } } return responseHeaders; }, getHeaderByKey: function(headers, key) { //case insensitive search for (var headerKey in headers) { if (headerKey.toLowerCase() === key.toLowerCase()) { var jsonHeader = {}; jsonHeader[key] = headers[headerKey]; return jsonHeader; } } return null; } }; /* * WLJSX.PeriodicalExecuter APIs are responsible for PeriodicalExecuter related functionality * * WLJSX.Object.execute() - Executes a callback supplied at initialization * WLJSX.Object.stop() - Stops the timer interval execution * new WLJSX.PeriodicalExecuter(callback, frequency) - returns new WLJSX.PeriodicalExecuter() object * which will call callback at specified frequencies (in seconds) */ window.WLJSX.PeriodicalExecuter = function(callback, frequency) { var currentlyExecuting = false; function onTimerEvent() { if (!currentlyExecuting) { try { currentlyExecuting = true; callback(); currentlyExecuting = false; } catch (e) { currentlyExecuting = false; throw e; } } } var timer = setInterval(onTimerEvent.bind(this), frequency * 1000); return { execute: function() { callback(this); }, stop: function() { if (!timer) { return; } clearInterval(timer); timer = null; } }; }; /* * Extends JavaScript Function object * * Public API: * functionName.argumentNames - http://api.prototypejs.org/language/Function/prototype/argumentNames/ * finctionName.bind - http://api.prototypejs.org/language/Function/prototype/bind/ * functionName.bindAsEventListener - http://api.prototypejs.org/language/Function/prototype/bindAsEventListener/ * functionName.curry - http://api.prototypejs.org/language/Function/prototype/curry/ * functionName.delay - http://api.prototypejs.org/language/Function/prototype/delay/ * functionName.defer - http://api.prototypejs.org/language/Function/prototype/defer/ * functionName.wrap - http://api.prototypejs.org/language/Function/prototype/wrap/ */ WLJSX.Object.extend(Function.prototype, (function() { var slice = Array.prototype.slice; function update(array, args) { var arrayLength = array.length, length = args.length; while (length--) { array[arrayLength + length] = args[length]; } return array; } function merge(array, args) { array = slice.call(array, 0); return update(array, args); } function argumentNames() { var names = this.toString().match(/^[\s\(]*function[^(]*\(([^)]*)\)/)[1] .replace(/\/\/.*?[\r\n]|\/\*(?:.|[\r\n])*?\*\//g, '') .replace(/\s+/g, '').split(','); /*jshint eqeqeq:false*/ return names.length == 1 && !names[0] ? [] : names; } function bind(obj) { var args = Array.prototype.slice.call(arguments, 1), self = this, Nop = function() { }, bound = function() { return self.apply( this instanceof Nop ? this : (obj || {}), args.concat( Array.prototype.slice.call(arguments) ) ); }; Nop.prototype = this.prototype || {}; bound.prototype = new Nop(); return bound; } function bindAsEventListener(context) { var __method = this, args = slice.call(arguments, 1); return function(event) { var a = update([event || window.event], args); return __method.apply(context, a); }; } function curry() { if (!arguments.length) { return this; } var __method = this, args = slice.call(arguments, 0); return function() { var a = merge(args, arguments); return __method.apply(this, a); }; } function delay(timeout) { var __method = this, args = slice.call(arguments, 1); timeout = timeout * 1000; return window.setTimeout(function() { return __method.apply(__method, args); }, timeout); } function defer() { var args = update([0.01], arguments); return this.delay.apply(this, args); } function wrap(wrapper) { var __method = this; return function() { var a = update([__method.bind(this)], arguments); return wrapper.apply(this, a); }; } return { argumentNames: argumentNames, bind: bind, bindAsEventListener: bindAsEventListener, curry: curry, delay: delay, defer: defer, wrap: wrap }; })()); /** * ================================================================= * Source file taken from :: validators.js * ================================================================= */ /* Licensed Materials - Property of IBM (C) Copyright 2015 IBM Corp. Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ /** * Validators are responsible for validating method arguments in development mode. */ WL.Validators = { // Validation should be disabled by default - so Welcome pages do not validate in production. // If we want validation for the welcome page we must add a solution to turn it off in production. isValidationEnabled : false, verbose : true, // True when 'o' is set, the native JavaScript event is defined, and 'o' has an event phase isEvent : function(obj) { return obj && obj.type; }, logAndThrow : function(msg, callerName) { // Logger is not be available in public resources (welcome page). if (WL.Logger) { if (callerName) { msg = "Invalid invocation of method " + callerName + "; " + msg; } if (this.verbose) { WL.Logger.error(msg); } } throw new Error(msg); }, enableValidation : function() { this.isValidationEnabled = true; }, disableValidation : function() { this.isValidationEnabled = false; }, validateArguments : function(validators, args, callerName) { if (validators.length < args.length) { // More arguments than validators ... accept only if last argument is an Event. if ((validators.length !== (args.length - 1)) || !this.isEvent(args[args.length - 1])) { this.logAndThrow("Method was passed " + args.length + " arguments, expected only " + validators.length + " " + WLJSX.Object.toJSON(validators) + ".", callerName); } } this.validateArray(validators, args, callerName); }, validateMinimumArguments : function(args, mandatoryArgsLength, callerName) { if (args.length < mandatoryArgsLength) { this.logAndThrow("Method passed: " + args.length + " arguments. Minimum arguments expected are: " + mandatoryArgsLength + " arguments.", callerName); } }, /** * Validates each argument in the array with the matching validator. @Param array - a JavaScript array. * @Param validators - an array of validators - a validator can be a function or a simple JavaScript type * (string). */ validateArray : function(validators, array, callerName) { if (!this.isValidationEnabled) { return; } for ( var i = 0; i < validators.length; ++i) { this.validateArgument(validators[i], array[i], callerName); } }, /** * Validates a single argument. @Param arg - an argument of any type. @Param validator - a function or a * simple JavaScript type (string). */ validateArgument : function(validator, arg, callerName) { if (!this.isValidationEnabled) { return; } switch (typeof validator) { // Case validation function. case 'function': validator.call(this, arg); break; // Case direct type. case 'string': if (typeof arg !== validator) { this.logAndThrow("Invalid value '" + WLJSX.Object.toJSON(arg) + "' (" + (typeof arg) + "), expected type '" + validator + "'.", callerName); } break; default: // This error can be caused only if IBM MobileFirst Platform code is bugged. this.logAndThrow("Invalid or undefined validator for argument '" + WLJSX.Object.toJSON(arg) + "'", callerName); } }, /** * Validates that each option attribute in the given options has a valid name and type. @Param options - * the options to validate. @Param validOptions - the valid options hash with their validators: * validOptions = { onSuccess : 'function', timeout : function(value){...} } * */ validateOptions : function(validOptions, options, callerName) { this.validateObjectProperties(validOptions, options, true, callerName); }, /** * Validates that option attribute in the given options have a valid name and type - only if they are * explicitly defined in validOptions. If an option attribute does not exist in validOptions, it is simply * ignored @Param options - the options to validate. @Param validOptions - the valid options hash with * their validators: validOptions = { onSuccess : 'function', timeout : function(value){...} } * */ validateOptionsLoose : function(validOptions, options, callerName) { this.validateObjectProperties(validOptions, options, false, callerName); }, /** * Validates that each option attribute in the given options has a valid name and type. @Param options - * the options to validate. @Param validOptions - the valid options hash with their validators: * validOptions = { onSuccess : 'function', timeout : function(value){...} } @Param strict - a boolean * indicating whether options' properties that don't exist in