Commit 0c2428ca authored by Romain Courteaud's avatar Romain Courteaud

Give a name to all anonymous functions.

This will make JS stack more readable.
parent be096475
......@@ -5,19 +5,20 @@
* renderJs - Generic Gadget library renderer.
* http://www.renderjs.org/documentation
*/
(function (document, window, RSVP, DOMParser, Channel, MutationObserver,
Node, FileReader, Blob, navigator, Event, URL) {
(function wrapRenderJS(document, window, RSVP, DOMParser, Channel,
MutationObserver, Node, FileReader, Blob, navigator,
Event, URL) {
"use strict";
function readBlobAsDataURL(blob) {
var fr = new FileReader();
return new RSVP.Promise(function (resolve, reject) {
fr.addEventListener("load", function (evt) {
return new RSVP.Promise(function waitFormDataURLRead(resolve, reject) {
fr.addEventListener("load", function handleDataURLRead(evt) {
resolve(evt.target.result);
});
fr.addEventListener("error", reject);
fr.readAsDataURL(blob);
}, function () {
}, function cancelReadBlobAsDataURL() {
fr.abort();
});
}
......@@ -50,7 +51,7 @@
}
function itsANonResolvableTrap(resolve, reject) {
var result;
handle_event_callback = function (evt) {
handle_event_callback = function handleEventCallback(evt) {
if (prevent_default) {
evt.stopPropagation();
evt.preventDefault();
......@@ -66,10 +67,10 @@
callback_promise = result;
new RSVP.Queue()
.push(function () {
.push(function waitForEventCallbackResult() {
return result;
})
.push(undefined, function (error) {
.push(undefined, function handleEventCallbackError(error) {
if (!(error instanceof RSVP.CancellationError)) {
canceller();
reject(error);
......@@ -147,11 +148,11 @@
error_list = [],
all_dependency_loaded_deferred;
window.addEventListener('error', function (error) {
window.addEventListener('error', function handleGlobalError(error) {
error_list.push(error);
});
window.addEventListener('beforeunload', function () {
window.addEventListener('beforeunload', function handleBeforeUnload() {
// XXX If another listener cancel the page unload,
// it will not restore renderJS crash report
is_page_unloaded = true;
......@@ -294,7 +295,7 @@
ResolvedMonitorError.prototype = new Error();
ResolvedMonitorError.prototype.constructor = ResolvedMonitorError;
Monitor = function () {
Monitor = function createMonitor() {
var monitor = this,
promise_list = [],
promise,
......@@ -316,8 +317,8 @@
promise_list = [];
}
promise = new RSVP.Promise(function (done, fail, progress) {
reject = function (rejectedReason) {
promise = new RSVP.Promise(function promiseMonitor(done, fail, progress) {
reject = function rejectMonitor(rejectedReason) {
if (resolved) {
return;
}
......@@ -330,33 +331,29 @@
notify = progress;
}, canceller);
monitor.cancel = function () {
monitor.cancel = function cancelMonitor() {
if (resolved) {
return;
}
resolved = true;
promise.cancel();
promise.fail(function (rejectedReason) {
promise.fail(function rejectMonitorPromise(rejectedReason) {
monitor.isRejected = true;
monitor.rejectedReason = rejectedReason;
});
};
monitor.then = function () {
return promise.then.apply(promise, arguments);
};
monitor.fail = function () {
return promise.fail.apply(promise, arguments);
};
monitor.then = promise.then.bind(promise);
monitor.fail = promise.fail.bind(promise);
monitor.monitor = function (promise_to_monitor) {
monitor.monitor = function startMonitor(promise_to_monitor) {
if (resolved) {
throw new ResolvedMonitorError();
}
var queue = new RSVP.Queue()
.push(function () {
.push(function waitForPromiseToMonitor() {
return promise_to_monitor;
})
.push(function (fulfillmentValue) {
.push(function handlePromiseToMonitorSuccess(fulfillmentValue) {
// Promise to monitor is fullfilled, remove it from the list
var len = promise_list.length,
sub_promise_to_monitor,
......@@ -370,7 +367,7 @@
}
}
promise_list = new_promise_list;
}, function (rejectedReason) {
}, function handlePromiseToMonitorError(rejectedReason) {
if (rejectedReason instanceof RSVP.CancellationError) {
if (!(promise_to_monitor.isFulfilled &&
promise_to_monitor.isRejected)) {
......@@ -380,7 +377,7 @@
}
reject(rejectedReason);
throw rejectedReason;
}, function (notificationValue) {
}, function handlePromiseToMonitorNotification(notificationValue) {
notify(notificationValue);
return notificationValue;
});
......@@ -409,7 +406,7 @@
RenderJSGadget.prototype.__required_css_list = [];
RenderJSGadget.prototype.__required_js_list = [];
function createMonitor(g) {
function createGadgetMonitor(g) {
if (g.__monitor !== undefined) {
g.__monitor.cancel();
}
......@@ -417,19 +414,17 @@
g.__job_dict = {};
g.__job_list = [];
g.__job_triggered = false;
g.__monitor.fail(function (error) {
g.__monitor.fail(function handleGadgetMonitorError(error) {
if (!(error instanceof RSVP.CancellationError)) {
return g.aq_reportServiceError(error);
}
}).fail(function (error) {
// Crash the application if the acquisition generates an error.
return letsCrash(error);
});
// Crash the application if the acquisition generates an error.
}).fail(letsCrash);
}
function clearGadgetInternalParameters() {
this.__sub_gadget_dict = {};
createMonitor(this);
createGadgetMonitor(this);
}
function loadSubGadgetDOMDeclaration() {
......@@ -443,7 +438,7 @@
context = this;
function prepareReportGadgetDeclarationError(scope) {
return function (error) {
return function reportGadgetDeclarationError(error) {
var aq_dict = context.__acquired_method_dict || {},
method_name = 'reportGadgetDeclarationError';
if (aq_dict.hasOwnProperty(method_name)) {
......@@ -476,58 +471,56 @@
RenderJSGadget.__ready_list = [clearGadgetInternalParameters,
loadSubGadgetDOMDeclaration];
RenderJSGadget.ready = function (callback) {
RenderJSGadget.ready = function ready(callback) {
this.__ready_list.push(callback);
return this;
};
RenderJSGadget.setState = function (state_dict) {
RenderJSGadget.setState = function setState(state_dict) {
var json_state = JSON.stringify(state_dict);
this.__ready_list.unshift(function () {
this.__ready_list.unshift(function setStateDefaultValue() {
this.state = JSON.parse(json_state);
});
return this;
};
RenderJSGadget.onStateChange = function (callback) {
RenderJSGadget.onStateChange = function onStateChange(callback) {
this.prototype.__state_change_callback = callback;
return this;
};
RenderJSGadget.__service_list = [];
RenderJSGadget.declareService = function (callback) {
RenderJSGadget.declareService = function declareService(callback) {
this.__service_list.push(callback);
return this;
};
RenderJSGadget.onEvent = function (type, callback, use_capture,
prevent_default) {
this.__service_list.push(function () {
RenderJSGadget.onEvent = function onEvent(type, callback, use_capture,
prevent_default) {
this.__service_list.push(function startLoopEventListenerService() {
return loopEventListener(this.element, type, use_capture,
callback.bind(this), prevent_default);
});
return this;
};
RenderJSGadget.onLoop = function (callback, delay) {
RenderJSGadget.onLoop = function onLoop(callback, delay) {
if (delay === undefined) {
delay = 0;
}
this.__service_list.push(function () {
this.__service_list.push(function handleServiceCallback() {
var queue_loop = new RSVP.Queue(),
context = this,
wait = function () {
wait = function waitForLoopIteration() {
queue_loop
.push(function () {
.push(function waitNextOnLoopDelay() {
return RSVP.delay(delay);
})
.push(function () {
.push(function waitNextOnLoopAnimationFrame() {
// Only loop when the app has the focus
return promiseAnimationFrame();
})
.push(function () {
.push(function executeOnLoopCallback() {
return callback.apply(context, []);
})
.push(function () {
wait();
});
.push(wait);
};
wait();
return queue_loop;
......@@ -537,7 +530,7 @@
function runJob(gadget, name, callback, argument_list) {
var job_promise = new RSVP.Queue()
.push(function () {
.push(function waitForJobCallback() {
return callback.apply(gadget, argument_list);
});
if (gadget.__job_dict.hasOwnProperty(name)) {
......@@ -545,10 +538,10 @@
}
gadget.__job_dict[name] = job_promise;
gadget.__monitor.monitor(new RSVP.Queue()
.push(function () {
.push(function waitForJobPromise() {
return job_promise;
})
.push(undefined, function (error) {
.push(undefined, function handleJobError(error) {
if (!(error instanceof RSVP.CancellationError)) {
throw error;
}
......@@ -557,7 +550,7 @@
function startService(gadget) {
gadget.__monitor.monitor(new RSVP.Queue()
.push(function () {
.push(function monitorAllServiceList() {
var i,
service_list = gadget.constructor.__service_list,
job_list = gadget.__job_list;
......@@ -578,8 +571,8 @@
// gadget internal method, which trigger execution
// of a function inside a service
/////////////////////////////////////////////////////////////////
RenderJSGadget.declareJob = function (name, callback) {
this.prototype[name] = function () {
RenderJSGadget.declareJob = function declareJob(name, callback) {
this.prototype[name] = function triggerJob() {
var context = this,
argument_list = arguments;
......@@ -596,13 +589,13 @@
/////////////////////////////////////////////////////////////////
// RenderJSGadget.declareMethod
/////////////////////////////////////////////////////////////////
RenderJSGadget.declareMethod = function (name, callback) {
this.prototype[name] = function () {
RenderJSGadget.declareMethod = function declareMethod(name, callback) {
this.prototype[name] = function triggerMethod() {
var context = this,
argument_list = arguments;
return new RSVP.Queue()
.push(function () {
.push(function waitForMethodCallback() {
return callback.apply(context, argument_list);
});
};
......@@ -611,27 +604,27 @@
};
RenderJSGadget
.declareMethod('getInterfaceList', function () {
.declareMethod('getInterfaceList', function getInterfaceList() {
// Returns the list of gadget prototype
return this.__interface_list;
})
.declareMethod('getRequiredCSSList', function () {
.declareMethod('getRequiredCSSList', function getRequiredCSSList() {
// Returns a list of CSS required by the gadget
return this.__required_css_list;
})
.declareMethod('getRequiredJSList', function () {
.declareMethod('getRequiredJSList', function getRequiredJSList() {
// Returns a list of JS required by the gadget
return this.__required_js_list;
})
.declareMethod('getPath', function () {
.declareMethod('getPath', function getPath() {
// Returns the path of the code of a gadget
return this.__path;
})
.declareMethod('getTitle', function () {
.declareMethod('getTitle', function getTitle() {
// Returns the title of a gadget
return this.__title;
})
.declareMethod('getElement', function () {
.declareMethod('getElement', function getElement() {
// Returns the DOM Element of a gadget
// XXX Kept for compatibility. Use element property directly
if (this.element === undefined) {
......@@ -639,24 +632,24 @@
}
return this.element;
})
.declareMethod('changeState', function (state_dict) {
.declareMethod('changeState', function changeState(state_dict) {
var next_onStateChange = new RSVP.Queue(),
previous_onStateCHange,
context = this;
if (context.hasOwnProperty('__previous_onStateChange')) {
previous_onStateCHange = context.__previous_onStateChange;
next_onStateChange
.push(function () {
.push(function waitForPreviousStateChange() {
return previous_onStateCHange;
})
.push(undefined, function () {
.push(undefined, function handlePreviousStateChangeError() {
// Run callback even if previous failed
return;
});
}
context.__previous_onStateChange = next_onStateChange;
return next_onStateChange
.push(function () {
.push(function checkStateModification() {
var key,
modified = false,
previous_cancelled = context.hasOwnProperty('__modification_dict'),
......@@ -678,10 +671,10 @@
if (modified && context.__state_change_callback !== undefined) {
context.__modification_dict = modification_dict;
return new RSVP.Queue()
.push(function () {
.push(function waitForStateChangeCallback() {
return context.__state_change_callback(modification_dict);
})
.push(function (result) {
.push(function handleStateChangeSuccess(result) {
delete context.__modification_dict;
return result;
});
......@@ -705,7 +698,7 @@
}
}
return new RSVP.Queue()
.push(function () {
.push(function waitForAcquireMethod() {
// Do not specify default __acquired_method_dict on prototype
// to prevent modifying this default value (with
// allowPublicAcquiredMethod for example)
......@@ -716,7 +709,7 @@
}
throw new renderJS.AcquisitionError("aq_dynamic is not defined");
})
.push(undefined, function (error) {
.push(undefined, function handleAcquireMethodError(error) {
if (error instanceof renderJS.AcquisitionError) {
return gadget.__aq_parent(method_name, argument_list);
}
......@@ -725,12 +718,12 @@
}
RenderJSGadget.declareAcquiredMethod =
function (name, method_name_to_acquire) {
this.prototype[name] = function () {
function declareAcquiredMethod(name, method_name_to_acquire) {
this.prototype[name] = function acquireMethod() {
var argument_list = Array.prototype.slice.call(arguments, 0),
gadget = this;
return new RSVP.Queue()
.push(function () {
.push(function waitForAqParent() {
return gadget.__aq_parent(method_name_to_acquire, argument_list);
});
};
......@@ -747,7 +740,7 @@
// RenderJSGadget.allowPublicAcquisition
/////////////////////////////////////////////////////////////////
RenderJSGadget.allowPublicAcquisition =
function (method_name, callback) {
function allowPublicAcquisition(method_name, callback) {
this.prototype.__acquired_method_dict[method_name] = callback;
// Allow chain
......@@ -756,10 +749,11 @@
// Set aq_parent on gadget_instance which call acquire on parent_gadget
function setAqParent(gadget_instance, parent_gadget) {
gadget_instance.__aq_parent = function (method_name, argument_list) {
return acquire.apply(parent_gadget, [gadget_instance, method_name,
argument_list]);
};
gadget_instance.__aq_parent =
function __aq_parent(method_name, argument_list) {
return acquire.apply(parent_gadget, [gadget_instance, method_name,
argument_list]);
};
}
/////////////////////////////////////////////////////////////////
......@@ -795,19 +789,13 @@
/////////////////////////////////////////////////////////////////
function privateDeclarePublicGadget(url, options, parent_gadget) {
return new RSVP.Queue()
.push(function () {
return renderJS.declareGadgetKlass(url)
// gadget loading should not be interrupted
// if not, gadget's definition will not be complete
//.then will return another promise
//so loading_klass_promise can't be cancel
.then(function (result) {
return result;
});
})
// Get the gadget class and instanciate it
.push(function (Klass) {
return renderJS.declareGadgetKlass(url)
// gadget loading should not be interrupted
// if not, gadget's definition will not be complete
//.then will return another promise
//so loading_klass_promise can't be cancel
.then(function createPrivateInstanceFromKlass(Klass) {
// Get the gadget class and instanciate it
if (options.element === undefined) {
options.element = document.createElement("div");
}
......@@ -876,12 +864,12 @@
gadget_instance = new RenderJSIframeGadget();
setAqParent(gadget_instance, parent_gadget);
iframe = document.createElement("iframe");
iframe.addEventListener('error', function (error) {
iframe.addEventListener('error', function handleIframeError(error) {
iframe_loading_deferred.reject(error);
});
iframe.addEventListener('load', function () {
iframe.addEventListener('load', function handleIframeLoad() {
return RSVP.timeout(5000)
.fail(function () {
.fail(function triggerIframeTimeout() {
iframe_loading_deferred.reject(
new Error('Timeout while loading: ' + url)
);
......@@ -906,46 +894,51 @@
});
// Create new method from the declareMethod call inside the iframe
gadget_instance.__chan.bind("declareMethod",
function (trans, method_name) {
gadget_instance[method_name] = function () {
gadget_instance.__chan.bind(
"declareMethod",
function handleChannelDeclareMethod(trans, method_name) {
gadget_instance[method_name] = function triggerChannelDeclareMethod() {
var argument_list = arguments,
wait_promise = new RSVP.Promise(function (resolve, reject) {
gadget_instance.__chan.call({
method: "methodCall",
params: [
method_name,
Array.prototype.slice.call(argument_list, 0)],
success: resolve,
error: reject
});
});
wait_promise = new RSVP.Promise(
function handleChannelCall(resolve, reject) {
gadget_instance.__chan.call({
method: "methodCall",
params: [
method_name,
Array.prototype.slice.call(argument_list, 0)],
success: resolve,
error: reject
});
}
);
return new RSVP.Queue()
.push(function () {
.push(function waitForChannelCall() {
return wait_promise;
});
};
return "OK";
});
}
);
// Wait for the iframe to be loaded before continuing
gadget_instance.__chan.bind("ready", function (trans) {
gadget_instance.__chan.bind("ready", function handleChannelReady(trans) {
iframe_loading_deferred.resolve(gadget_instance);
return "OK";
});
gadget_instance.__chan.bind("failed", function (trans, params) {
iframe_loading_deferred.reject(params);
return "OK";
});
gadget_instance.__chan.bind("acquire", function (trans, params) {
gadget_instance.__aq_parent.apply(gadget_instance, params)
.then(function (g) {
trans.complete(g);
}).fail(function (e) {
trans.error(e.toString());
});
trans.delayReturn(true);
});
gadget_instance.__chan.bind("failed",
function handleChannelFail(trans, params) {
iframe_loading_deferred.reject(params);
return "OK";
});
gadget_instance.__chan.bind("acquire",
function handleChannelAcquire(trans, params) {
gadget_instance.__aq_parent.apply(gadget_instance, params)
.then(trans.complete)
.fail(function handleChannelAcquireError(e) {
trans.error(e.toString());
});
trans.delayReturn(true);
});
return iframe_loading_deferred.promise;
}
......@@ -956,10 +949,10 @@
function privateDeclareDataUrlGadget(url, options, parent_gadget) {
return new RSVP.Queue()
.push(function () {
.push(function waitForDataUrlAjax() {
return ajax(url);
})
.push(function (xhr) {
.push(function handleDataURLAjaxResponse(xhr) {
// Insert a "base" element, in order to resolve all relative links
// which could get broken with a data url
var doc = (new DOMParser()).parseFromString(xhr.responseText,
......@@ -972,7 +965,7 @@
{type: "text/html;charset=UTF-8"});
return readBlobAsDataURL(blob);
})
.push(function (data_url) {
.push(function handleDataURL(data_url) {
return privateDeclareIframeGadget(data_url, options, parent_gadget);
});
}
......@@ -981,7 +974,7 @@
// RenderJSGadget.declareGadget
/////////////////////////////////////////////////////////////////
RenderJSGadget
.declareMethod('declareGadget', function (url, options) {
.declareMethod('declareGadget', function declareGadget(url, options) {
var parent_gadget = this;
if (options === undefined) {
......@@ -995,7 +988,7 @@
url = renderJS.getAbsoluteURL(url, this.__path);
return new RSVP.Queue()
.push(function () {
.push(function waitForPrivateDeclareGadget() {
var method;
if (options.sandbox === "public") {
method = privateDeclarePublicGadget;
......@@ -1010,7 +1003,7 @@
return method(url, options, parent_gadget);
})
// Set the HTML context
.push(function (gadget_instance) {
.push(function setGadgetInstanceHTMLContext(gadget_instance) {
var i,
scope,
queue = new RSVP.Queue();
......@@ -1019,7 +1012,7 @@
return gadget_instance;
}
function ready_executable_wrapper(fct) {
return function () {
return function executeReadyWrapper() {
return fct.call(gadget_instance, gadget_instance);
};
}
......@@ -1063,13 +1056,14 @@
return queue;
});
})
.declareMethod('getDeclaredGadget', function (gadget_scope) {
if (!this.__sub_gadget_dict.hasOwnProperty(gadget_scope)) {
throw new Error("Gadget scope '" + gadget_scope + "' is not known.");
}
return this.__sub_gadget_dict[gadget_scope];
})
.declareMethod('dropGadget', function (gadget_scope) {
.declareMethod('getDeclaredGadget',
function getDeclaredGadget(gadget_scope) {
if (!this.__sub_gadget_dict.hasOwnProperty(gadget_scope)) {
throw new Error("Gadget scope '" + gadget_scope + "' is not known.");
}
return this.__sub_gadget_dict[gadget_scope];
})
.declareMethod('dropGadget', function dropGadget(gadget_scope) {
if (!this.__sub_gadget_dict.hasOwnProperty(gadget_scope)) {
throw new Error("Gadget scope '" + gadget_scope + "' is not known.");
}
......@@ -1080,7 +1074,7 @@
/////////////////////////////////////////////////////////////////
// renderJS selector
/////////////////////////////////////////////////////////////////
renderJS = function (selector) {
renderJS = function getLoadingGadget(selector) {
var result;
if (selector === window) {
// window is the 'this' value when loading a javascript file
......@@ -1096,7 +1090,7 @@
/////////////////////////////////////////////////////////////////
// renderJS.AcquisitionError
/////////////////////////////////////////////////////////////////
renderJS.AcquisitionError = function (message) {
renderJS.AcquisitionError = function createAcquisitionError(message) {
this.name = "AcquisitionError";
if ((message !== undefined) && (typeof message !== "string")) {
throw new TypeError('You must pass a string.');
......@@ -1110,7 +1104,7 @@
/////////////////////////////////////////////////////////////////
// renderJS.getAbsoluteURL
/////////////////////////////////////////////////////////////////
renderJS.getAbsoluteURL = function (url, base_url) {
renderJS.getAbsoluteURL = function getAbsoluteURL(url, base_url) {
if (base_url && url) {
return new URL(url, base_url).href;
}
......@@ -1120,7 +1114,7 @@
/////////////////////////////////////////////////////////////////
// renderJS.declareJS
/////////////////////////////////////////////////////////////////
renderJS.declareJS = function (url, container, pop) {
renderJS.declareJS = function declareJS(url, container, pop) {
// https://www.html5rocks.com/en/tutorials/speed/script-loading/
// Prevent infinite recursion if loading render.js
// more than once
......@@ -1129,28 +1123,30 @@
result = RSVP.resolve();
} else {
javascript_registration_dict[url] = null;
result = new RSVP.Promise(function (resolve, reject) {
var newScript;
newScript = document.createElement('script');
newScript.async = false;
newScript.type = 'text/javascript';
newScript.onload = function () {
if (pop === true) {
// Drop the current loading klass info used by selector
gadget_loading_klass_list.shift();
}
resolve();
};
newScript.onerror = function (e) {
if (pop === true) {
// Drop the current loading klass info used by selector
gadget_loading_klass_list.shift();
}
reject(e);
};
newScript.src = url;
container.appendChild(newScript);
});
result = new RSVP.Promise(
function waitForJSLoadEvent(resolve, reject) {
var newScript;
newScript = document.createElement('script');
newScript.async = false;
newScript.type = 'text/javascript';
newScript.onload = function triggerJSLoaded() {
if (pop === true) {
// Drop the current loading klass info used by selector
gadget_loading_klass_list.shift();
}
resolve();
};
newScript.onerror = function triggerJSNotLoaded(e) {
if (pop === true) {
// Drop the current loading klass info used by selector
gadget_loading_klass_list.shift();
}
reject(e);
};
newScript.src = url;
container.appendChild(newScript);
}
);
}
return result;
};
......@@ -1158,7 +1154,7 @@
/////////////////////////////////////////////////////////////////
// renderJS.declareCSS
/////////////////////////////////////////////////////////////////
renderJS.declareCSS = function (url, container) {
renderJS.declareCSS = function declareCSS(url, container) {
// https://github.com/furf/jquery-getCSS/blob/master/jquery.getCSS.js
// No way to cleanly check if a css has been loaded
// So, always resolve the promise...
......@@ -1167,19 +1163,17 @@
if (stylesheet_registration_dict.hasOwnProperty(url)) {
result = RSVP.resolve();
} else {
result = new RSVP.Promise(function (resolve, reject) {
result = new RSVP.Promise(function waitForCSSLoadEvent(resolve, reject) {
var link;
link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = url;
link.onload = function () {
link.onload = function triggerCSSLoaded() {
stylesheet_registration_dict[url] = null;
resolve();
};
link.onerror = function (e) {
reject(e);
};
link.onerror = reject;
container.appendChild(link);
});
}
......@@ -1195,7 +1189,7 @@
key,
parsed_html;
// Class inheritance
tmp_constructor = function () {
tmp_constructor = function createSuperKlass() {
RenderJSGadget.call(this);
};
tmp_constructor.__ready_list = RenderJSGadget.__ready_list.slice();
......@@ -1241,7 +1235,7 @@
return tmp_constructor;
}
renderJS.declareGadgetKlass = function (url) {
renderJS.declareGadgetKlass = function declareGadgetKlass(url) {
if (gadget_model_defer_dict.hasOwnProperty(url)) {
// Return klass object if it already exists
return gadget_model_defer_dict[url].promise;
......@@ -1254,10 +1248,10 @@
// Fetch the HTML page and parse it
return new RSVP.Queue()
.push(function () {
.push(function waitForGadgetKlassAjax() {
return ajax(url);
})
.push(function (result) {
.push(function handleGadgetKlassAjax(result) {
tmp_constructor = parse(result, url);
var fragment = document.createDocumentFragment(),
promise_list = [],
......@@ -1279,11 +1273,11 @@
document.head.appendChild(fragment);
return RSVP.all(promise_list);
})
.push(function () {
.push(function handleGadgetKlassLoadingSuccess() {
defer.resolve(tmp_constructor);
return tmp_constructor;
})
.push(undefined, function (e) {
.push(undefined, function handleGadgetKlassLoadingError(e) {
// Drop the current loading klass info used by selector
// even in case of error
defer.reject(e);
......@@ -1295,7 +1289,7 @@
// renderJS.clearGadgetKlassList
/////////////////////////////////////////////////////////////////
// For test purpose only
renderJS.clearGadgetKlassList = function () {
renderJS.clearGadgetKlassList = function clearGadgetKlassList() {
gadget_model_defer_dict = {};
javascript_registration_dict = {};
stylesheet_registration_dict = {};
......@@ -1304,53 +1298,54 @@
/////////////////////////////////////////////////////////////////
// renderJS.parseGadgetHTMLDocument
/////////////////////////////////////////////////////////////////
renderJS.parseGadgetHTMLDocument = function (document_element, url) {
var settings = {
title: "",
interface_list: [],
required_css_list: [],
required_js_list: []
},
i,
element;
if (!url || !isAbsoluteOrDataURL.test(url)) {
throw new Error("The url should be absolute: " + url);
}
renderJS.parseGadgetHTMLDocument =
function parseGadgetHTMLDocument(document_element, url) {
var settings = {
title: "",
interface_list: [],
required_css_list: [],
required_js_list: []
},
i,
element;
if (!url || !isAbsoluteOrDataURL.test(url)) {
throw new Error("The url should be absolute: " + url);
}
if (document_element.nodeType === 9) {
settings.title = document_element.title;
if (document_element.head !== null) {
for (i = 0; i < document_element.head.children.length; i += 1) {
element = document_element.head.children[i];
if (element.href !== null) {
// XXX Manage relative URL during extraction of URLs
// element.href returns absolute URL in firefox but "" in chrome;
if (element.rel === "stylesheet") {
settings.required_css_list.push(
renderJS.getAbsoluteURL(element.getAttribute("href"), url)
);
} else if (element.nodeName === "SCRIPT" &&
(element.type === "text/javascript" ||
!element.type)) {
settings.required_js_list.push(
renderJS.getAbsoluteURL(element.getAttribute("src"), url)
);
} else if (element.rel ===
"http://www.renderjs.org/rel/interface") {
settings.interface_list.push(
renderJS.getAbsoluteURL(element.getAttribute("href"), url)
);
if (document_element.nodeType === 9) {
settings.title = document_element.title;
if (document_element.head !== null) {
for (i = 0; i < document_element.head.children.length; i += 1) {
element = document_element.head.children[i];
if (element.href !== null) {
// XXX Manage relative URL during extraction of URLs
// element.href returns absolute URL in firefox but "" in chrome;
if (element.rel === "stylesheet") {
settings.required_css_list.push(
renderJS.getAbsoluteURL(element.getAttribute("href"), url)
);
} else if (element.nodeName === "SCRIPT" &&
(element.type === "text/javascript" ||
!element.type)) {
settings.required_js_list.push(
renderJS.getAbsoluteURL(element.getAttribute("src"), url)
);
} else if (element.rel ===
"http://www.renderjs.org/rel/interface") {
settings.interface_list.push(
renderJS.getAbsoluteURL(element.getAttribute("href"), url)
);
}
}
}
}
} else {
throw new Error("The first parameter should be an HTMLDocument");
}
} else {
throw new Error("The first parameter should be an HTMLDocument");
}
return settings;
};
return settings;
};
/////////////////////////////////////////////////////////////////
// global
......@@ -1370,7 +1365,7 @@
// is triggered before everything was ready.
// (For instance, the HTML-tag for the self gadget gets inserted after
// page load)
renderJS.manualBootstrap = function () {
renderJS.manualBootstrap = function manualBootstrap() {
all_dependency_loaded_deferred.resolve();
};
document.addEventListener('DOMContentLoaded',
......@@ -1398,7 +1393,7 @@
TmpConstructor.__template_element.appendChild(fragment);
return RSVP.all([root_gadget.getRequiredJSList(),
root_gadget.getRequiredCSSList()])
.then(function (all_list) {
.then(function handleRequireDependencyList(all_list) {
var i,
js_list = all_list[0],
css_list = all_list[1];
......@@ -1409,14 +1404,14 @@
stylesheet_registration_dict[css_list[i]] = null;
}
gadget_loading_klass_list.shift();
}).then(function () {
}).then(function createMutationObserver() {
// select the target node
var target = document.querySelector('body'),
// create an observer instance
observer = new MutationObserver(function (mutations) {
observer = new MutationObserver(function observeMutatios(mutations) {
var i, k, len, len2, node, added_list;
mutations.forEach(function (mutation) {
mutations.forEach(function observerMutation(mutation) {
if (mutation.type === 'childList') {
len = mutation.removedNodes.length;
......@@ -1425,7 +1420,7 @@
if (node.nodeType === Node.ELEMENT_NODE) {
if (node.hasAttribute("data-gadget-url") &&
(node._gadget !== undefined)) {
createMonitor(node._gadget);
createGadgetMonitor(node._gadget);
}
added_list =
node.querySelectorAll("[data-gadget-url]");
......@@ -1433,7 +1428,7 @@
for (k = 0; k < len2; k += 1) {
node = added_list[k];
if (node._gadget !== undefined) {
createMonitor(node._gadget);
createGadgetMonitor(node._gadget);
}
}
}
......@@ -1484,13 +1479,13 @@
function createLastAcquisitionGadget() {
var last_acquisition_gadget = new RenderJSGadget();
last_acquisition_gadget.__acquired_method_dict = {
reportServiceError: function (param_list) {
reportServiceError: function reportServiceError(param_list) {
letsCrash(param_list[0]);
}
};
// Stop acquisition on the last acquisition gadget
// Do not put this on the klass, as their could be multiple instances
last_acquisition_gadget.__aq_parent = function (method_name) {
last_acquisition_gadget.__aq_parent = function __aq_parent(method_name) {
throw new renderJS.AcquisitionError(
"No gadget provides " + method_name
);
......@@ -1538,7 +1533,7 @@
];
// Inform parent gadget about declareMethod calls here.
notifyDeclareMethod = function (name) {
notifyDeclareMethod = function notifyDeclareMethod(name) {
declare_method_list_waiting.push(name);
};
......@@ -1551,13 +1546,13 @@
loading_result = RSVP.any([
channel_defer.promise,
new RSVP.Queue()
.push(function () {
.push(function waitForParentChannelCreation() {
// Expect the channel to parent to be usable after 1 second
// If not, consider the gadget as the root
// Drop all iframe channel communication
return RSVP.delay(1000);
})
.push(function () {
.push(function handleParentChannelCreation() {
real_result_list[2] = undefined;
return real_result_list;
})
......@@ -1567,20 +1562,22 @@
window: window.parent,
origin: "*",
scope: "renderJS",
onReady: function () {
onReady: function onChannelReady() {
var k,
len;
// Channel is ready, so now declare all methods
notifyDeclareMethod = function (name) {
notifyDeclareMethod = function notifyDeclareMethod(name) {
declare_method_list_waiting.push(
new RSVP.Promise(function (resolve, reject) {
embedded_channel.call({
method: "declareMethod",
params: name,
success: resolve,
error: reject
});
})
new RSVP.Promise(
function promiseChannelDeclareMethodCall(resolve, reject) {
embedded_channel.call({
method: "declareMethod",
params: name,
success: resolve,
error: reject
});
}
)
);
};
......@@ -1596,7 +1593,7 @@
}
// Surcharge declareMethod to inform parent window
TmpConstructor.declareMethod = function (name, callback) {
TmpConstructor.declareMethod = function declareMethod(name, callback) {
var result = RenderJSGadget.declareMethod.apply(
this,
[name, callback]
......@@ -1633,11 +1630,11 @@
return root_gadget;
}
function ready_executable_wrapper(fct) {
return function (g) {
return function wrapReadyFunction(g) {
return fct.call(g, g);
};
}
TmpConstructor.ready(function () {
TmpConstructor.ready(function startServiceInReady() {
return startService(this);
});
......@@ -1656,35 +1653,32 @@
embedded_channel) {
// Define __aq_parent to inform parent window
root_gadget.__aq_parent =
TmpConstructor.prototype.__aq_parent = function (method_name,
argument_list,
time_out) {
return new RSVP.Promise(function (resolve, reject) {
embedded_channel.call({
method: "acquire",
params: [
method_name,
argument_list
],
success: function (s) {
resolve(s);
},
error: function (e) {
reject(e);
},
timeout: time_out
});
});
TmpConstructor.prototype.__aq_parent = function aq_parent(method_name,
argument_list,
time_out) {
return new RSVP.Promise(
function waitForChannelAcquire(resolve, reject) {
embedded_channel.call({
method: "acquire",
params: [
method_name,
argument_list
],
success: resolve,
error: reject,
timeout: time_out
});
}
);
};
// bind calls to renderJS method on the instance
embedded_channel.bind("methodCall", function (trans, v) {
embedded_channel.bind("methodCall", function methodCall(trans, v) {
root_gadget[v[0]].apply(root_gadget, v[1])
.push(function (g) {
trans.complete(g);
}, function (e) {
trans.error(e.toString());
});
.push(trans.complete,
function handleMethodCallError(e) {
trans.error(e.toString());
});
trans.delayReturn(true);
});
}
......@@ -1698,11 +1692,11 @@
declare_method_list_waiting;
return new RSVP.Queue()
.push(function () {
.push(function waitForLoadingGadget() {
// Wait for the loading gadget to be created
return wait_for_gadget_loaded;
})
.push(function (result_list) {
.push(function handleLoadingGadget(result_list) {
TmpConstructor = result_list[0];
root_gadget = result_list[1];
embedded_channel = result_list[2];
......@@ -1710,11 +1704,11 @@
// Wait for all the gadget dependencies to be loaded
return all_dependency_loaded_deferred.promise;
})
.push(function () {
.push(function waitForDeclareMethodList() {
// Wait for all methods to be correctly declared
return RSVP.all(declare_method_list_waiting);
})
.push(function (result_list) {
.push(function waitForMutationObserver(result_list) {
if (embedded_channel !== undefined) {
finishAqParentConfiguration(TmpConstructor, root_gadget,
embedded_channel);
......@@ -1722,16 +1716,16 @@
// Check all DOM modifications to correctly start/stop services
return configureMutationObserver(TmpConstructor, url, root_gadget);
})
.push(function () {
.push(function waitForReadyList() {
// Trigger all ready functions
return triggerReadyList(TmpConstructor, root_gadget);
})
.push(function () {
.push(function notifyReady() {
if (embedded_channel !== undefined) {
embedded_channel.notify({method: "ready"});
}
})
.push(undefined, function (e) {
.push(undefined, function handleBootstrapError(e) {
letsCrash(e);
if (embedded_channel !== undefined) {
embedded_channel.notify({method: "failed", params: e.toString()});
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment