Commit 3f1110c4 authored by Romain Courteaud's avatar Romain Courteaud

[erp5_xhtml_style/erp5_web_renderjs_ui] Update renderJS 0.14.0

parent 7c8fc367
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -230,7 +230,7 @@ ...@@ -230,7 +230,7 @@
</item> </item>
<item> <item>
<key> <string>serial</string> </key> <key> <string>serial</string> </key>
<value> <string>955.51226.25726.38263</string> </value> <value> <string>956.46086.45265.8004</string> </value>
</item> </item>
<item> <item>
<key> <string>state</string> </key> <key> <string>state</string> </key>
...@@ -248,7 +248,7 @@ ...@@ -248,7 +248,7 @@
</tuple> </tuple>
<state> <state>
<tuple> <tuple>
<float>1481043805.03</float> <float>1484732189.17</float>
<string>UTC</string> <string>UTC</string>
</tuple> </tuple>
</state> </state>
......
...@@ -673,7 +673,7 @@ if (typeof document.contains !== 'function') { ...@@ -673,7 +673,7 @@ if (typeof document.contains !== 'function') {
* http://www.renderjs.org/documentation * http://www.renderjs.org/documentation
*/ */
(function (document, window, RSVP, DOMParser, Channel, MutationObserver, (function (document, window, RSVP, DOMParser, Channel, MutationObserver,
Node, FileReader, Blob, navigator, Event) { Node, FileReader, Blob, navigator, Event, URL) {
"use strict"; "use strict";
function readBlobAsDataURL(blob) { function readBlobAsDataURL(blob) {
...@@ -789,10 +789,10 @@ if (typeof document.contains !== 'function') { ...@@ -789,10 +789,10 @@ if (typeof document.contains !== 'function') {
return new RSVP.Promise(resolver, canceller); return new RSVP.Promise(resolver, canceller);
} }
var gadget_model_dict = {}, var gadget_model_defer_dict = {},
javascript_registration_dict = {}, javascript_registration_dict = {},
stylesheet_registration_dict = {}, stylesheet_registration_dict = {},
gadget_loading_klass, gadget_loading_klass_list = [],
loading_klass_promise, loading_klass_promise,
renderJS, renderJS,
Monitor, Monitor,
...@@ -1081,19 +1081,32 @@ if (typeof document.contains !== 'function') { ...@@ -1081,19 +1081,32 @@ if (typeof document.contains !== 'function') {
}); });
} }
function clearGadgetInternalParameters(g) { function clearGadgetInternalParameters() {
g.__sub_gadget_dict = {}; this.__sub_gadget_dict = {};
createMonitor(g); createMonitor(this);
} }
function loadSubGadgetDOMDeclaration(g) { function loadSubGadgetDOMDeclaration() {
var element_list = g.element.querySelectorAll('[data-gadget-url]'), var element_list = this.element.querySelectorAll('[data-gadget-url]'),
element, element,
promise_list = [], promise_list = [],
scope, scope,
url, url,
sandbox, sandbox,
i; i,
context = this;
function prepareReportGadgetDeclarationError(scope) {
return function (error) {
var aq_dict = context.__acquired_method_dict || {},
method_name = 'reportGadgetDeclarationError';
if (aq_dict.hasOwnProperty(method_name)) {
return aq_dict[method_name].apply(context,
[arguments, scope]);
}
throw error;
};
}
for (i = 0; i < element_list.length; i += 1) { for (i = 0; i < element_list.length; i += 1) {
element = element_list[i]; element = element_list[i];
...@@ -1101,11 +1114,14 @@ if (typeof document.contains !== 'function') { ...@@ -1101,11 +1114,14 @@ if (typeof document.contains !== 'function') {
url = element.getAttribute("data-gadget-url"); url = element.getAttribute("data-gadget-url");
sandbox = element.getAttribute("data-gadget-sandbox"); sandbox = element.getAttribute("data-gadget-sandbox");
if (url !== null) { if (url !== null) {
promise_list.push(g.declareGadget(url, { promise_list.push(
element: element, context.declareGadget(url, {
scope: scope || undefined, element: element,
sandbox: sandbox || undefined scope: scope || undefined,
})); sandbox: sandbox || undefined
})
.push(undefined, prepareReportGadgetDeclarationError(scope))
);
} }
} }
...@@ -1120,9 +1136,10 @@ if (typeof document.contains !== 'function') { ...@@ -1120,9 +1136,10 @@ if (typeof document.contains !== 'function') {
}; };
RenderJSGadget.setState = function (state_dict) { RenderJSGadget.setState = function (state_dict) {
var json_state = JSON.stringify(state_dict); var json_state = JSON.stringify(state_dict);
return this.ready(function () { this.__ready_list.unshift(function () {
this.state = JSON.parse(json_state); this.state = JSON.parse(json_state);
}); });
return this;
}; };
RenderJSGadget.onStateChange = function (callback) { RenderJSGadget.onStateChange = function (callback) {
this.prototype.__state_change_callback = callback; this.prototype.__state_change_callback = callback;
...@@ -1331,6 +1348,8 @@ if (typeof document.contains !== 'function') { ...@@ -1331,6 +1348,8 @@ if (typeof document.contains !== 'function') {
}; };
RenderJSGadget.declareAcquiredMethod("aq_reportServiceError", RenderJSGadget.declareAcquiredMethod("aq_reportServiceError",
"reportServiceError"); "reportServiceError");
RenderJSGadget.declareAcquiredMethod("aq_reportGadgetDeclarationError",
"reportGadgetDeclarationError");
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// RenderJSGadget.allowPublicAcquisition // RenderJSGadget.allowPublicAcquisition
...@@ -1381,56 +1400,37 @@ if (typeof document.contains !== 'function') { ...@@ -1381,56 +1400,37 @@ if (typeof document.contains !== 'function') {
// privateDeclarePublicGadget // privateDeclarePublicGadget
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
function privateDeclarePublicGadget(url, options, parent_gadget) { function privateDeclarePublicGadget(url, options, parent_gadget) {
var gadget_instance;
if (options.element === undefined) {
options.element = document.createElement("div");
}
function loadDependency(method, url) {
return function () {
return method(url);
};
}
return new RSVP.Queue() return new RSVP.Queue()
.push(function () { .push(function () {
return renderJS.declareGadgetKlass(url); 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 // Get the gadget class and instanciate it
.push(function (Klass) { .push(function (Klass) {
if (options.element === undefined) {
options.element = document.createElement("div");
}
var i, var i,
template_node_list = Klass.__template_element.body.childNodes; gadget_instance,
gadget_loading_klass = Klass; template_node_list = Klass.__template_element.body.childNodes,
fragment = document.createDocumentFragment();
gadget_instance = new Klass(); gadget_instance = new Klass();
gadget_instance.element = options.element; gadget_instance.element = options.element;
gadget_instance.state = {}; gadget_instance.state = {};
for (i = 0; i < template_node_list.length; i += 1) { for (i = 0; i < template_node_list.length; i += 1) {
gadget_instance.element.appendChild( fragment.appendChild(
template_node_list[i].cloneNode(true) template_node_list[i].cloneNode(true)
); );
} }
gadget_instance.element.appendChild(fragment);
setAqParent(gadget_instance, parent_gadget); setAqParent(gadget_instance, parent_gadget);
// Load dependencies if needed
return RSVP.all([
gadget_instance.getRequiredJSList(),
gadget_instance.getRequiredCSSList()
]);
})
// Load all JS/CSS
.push(function (all_list) {
var q = new RSVP.Queue(),
i;
// Load JS
for (i = 0; i < all_list[0].length; i += 1) {
q.push(loadDependency(renderJS.declareJS, all_list[0][i]));
}
// Load CSS
for (i = 0; i < all_list[1].length; i += 1) {
q.push(loadDependency(renderJS.declareCSS, all_list[1][i]));
}
return q;
})
.push(function () {
return gadget_instance; return gadget_instance;
}); });
} }
...@@ -1480,6 +1480,17 @@ if (typeof document.contains !== 'function') { ...@@ -1480,6 +1480,17 @@ if (typeof document.contains !== 'function') {
gadget_instance = new RenderJSIframeGadget(); gadget_instance = new RenderJSIframeGadget();
setAqParent(gadget_instance, parent_gadget); setAqParent(gadget_instance, parent_gadget);
iframe = document.createElement("iframe"); iframe = document.createElement("iframe");
iframe.addEventListener('error', function (error) {
iframe_loading_deferred.reject(error);
});
iframe.addEventListener('load', function () {
return RSVP.timeout(5000)
.fail(function () {
iframe_loading_deferred.reject(
new Error('Timeout while loading: ' + url)
);
});
});
// gadget_instance.element.setAttribute("seamless", "seamless"); // gadget_instance.element.setAttribute("seamless", "seamless");
iframe.setAttribute("src", url); iframe.setAttribute("src", url);
gadget_instance.__path = url; gadget_instance.__path = url;
...@@ -1543,18 +1554,7 @@ if (typeof document.contains !== 'function') { ...@@ -1543,18 +1554,7 @@ if (typeof document.contains !== 'function') {
trans.delayReturn(true); trans.delayReturn(true);
}); });
return RSVP.any([ return iframe_loading_deferred.promise;
iframe_loading_deferred.promise,
// Timeout to prevent non renderJS embeddable gadget
// XXX Maybe using iframe.onload/onerror would be safer?
new RSVP.Queue()
.push(function () {
return RSVP.timeout(5000);
})
.push(undefined, function () {
throw new Error('Timeout while loading: ' + url);
})
]);
} }
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
...@@ -1589,10 +1589,7 @@ if (typeof document.contains !== 'function') { ...@@ -1589,10 +1589,7 @@ if (typeof document.contains !== 'function') {
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
RenderJSGadget RenderJSGadget
.declareMethod('declareGadget', function (url, options) { .declareMethod('declareGadget', function (url, options) {
var queue, var parent_gadget = this;
parent_gadget = this,
local_loading_klass_promise,
previous_loading_klass_promise = loading_klass_promise;
if (options === undefined) { if (options === undefined) {
options = {}; options = {};
...@@ -1603,16 +1600,8 @@ if (typeof document.contains !== 'function') { ...@@ -1603,16 +1600,8 @@ if (typeof document.contains !== 'function') {
// transform url to absolute url if it is relative // transform url to absolute url if it is relative
url = renderJS.getAbsoluteURL(url, this.__path); url = renderJS.getAbsoluteURL(url, this.__path);
// Change the global variable to update the loading queue
loading_klass_promise = new RSVP.Queue() return new RSVP.Queue()
// Wait for previous gadget loading to finish first
.push(function () {
return previous_loading_klass_promise;
})
.push(undefined, function () {
// Forget previous declareGadget error
return;
})
.push(function () { .push(function () {
var method; var method;
if (options.sandbox === "public") { if (options.sandbox === "public") {
...@@ -1628,41 +1617,17 @@ if (typeof document.contains !== 'function') { ...@@ -1628,41 +1617,17 @@ if (typeof document.contains !== 'function') {
return method(url, options, parent_gadget); return method(url, options, parent_gadget);
}) })
// Set the HTML context // Set the HTML context
.push(function (gadget_instance) {
// Drop the current loading klass info used by selector
gadget_loading_klass = undefined;
return gadget_instance;
})
.push(undefined, function (e) {
// Drop the current loading klass info used by selector
// even in case of error
gadget_loading_klass = undefined;
throw e;
});
//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
local_loading_klass_promise = loading_klass_promise
.then(function (gadget_instance) {
return gadget_instance;
});
queue = new RSVP.Queue()
.push(function () {
return local_loading_klass_promise;
})
// Set the HTML context
.push(function (gadget_instance) { .push(function (gadget_instance) {
var i, var i,
scope; scope,
queue = new RSVP.Queue();
// Trigger calling of all ready callback // Trigger calling of all ready callback
function ready_wrapper() { function ready_wrapper() {
return gadget_instance; return gadget_instance;
} }
function ready_executable_wrapper(fct) { function ready_executable_wrapper(fct) {
return function (g) { return function () {
return fct.call(g, g); return fct.call(gadget_instance, gadget_instance);
}; };
} }
for (i = 0; i < gadget_instance.constructor.__ready_list.length; for (i = 0; i < gadget_instance.constructor.__ready_list.length;
...@@ -1702,9 +1667,8 @@ if (typeof document.contains !== 'function') { ...@@ -1702,9 +1667,8 @@ if (typeof document.contains !== 'function') {
// Always return the gadget instance after ready function // Always return the gadget instance after ready function
queue.push(ready_wrapper); queue.push(ready_wrapper);
return gadget_instance; return queue;
}); });
return queue;
}) })
.declareMethod('getDeclaredGadget', function (gadget_scope) { .declareMethod('getDeclaredGadget', function (gadget_scope) {
if (!this.__sub_gadget_dict.hasOwnProperty(gadget_scope)) { if (!this.__sub_gadget_dict.hasOwnProperty(gadget_scope)) {
...@@ -1728,7 +1692,7 @@ if (typeof document.contains !== 'function') { ...@@ -1728,7 +1692,7 @@ if (typeof document.contains !== 'function') {
if (selector === window) { if (selector === window) {
// window is the 'this' value when loading a javascript file // window is the 'this' value when loading a javascript file
// In this case, use the current loading gadget constructor // In this case, use the current loading gadget constructor
result = gadget_loading_klass; result = gadget_loading_klass_list[0];
} }
if (result === undefined) { if (result === undefined) {
throw new Error("Unknown selector '" + selector + "'"); throw new Error("Unknown selector '" + selector + "'");
...@@ -1754,18 +1718,8 @@ if (typeof document.contains !== 'function') { ...@@ -1754,18 +1718,8 @@ if (typeof document.contains !== 'function') {
// renderJS.getAbsoluteURL // renderJS.getAbsoluteURL
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
renderJS.getAbsoluteURL = function (url, base_url) { renderJS.getAbsoluteURL = function (url, base_url) {
var doc, base, link, if (base_url && url) {
html = "<!doctype><html><head></head></html>"; return new URL(url, base_url).href;
if (url && base_url && !isAbsoluteOrDataURL.test(url)) {
doc = (new DOMParser()).parseFromString(html, 'text/html');
base = doc.createElement('base');
link = doc.createElement('link');
doc.head.appendChild(base);
doc.head.appendChild(link);
base.href = base_url;
link.href = url;
return link.href;
} }
return url; return url;
}; };
...@@ -1773,26 +1727,36 @@ if (typeof document.contains !== 'function') { ...@@ -1773,26 +1727,36 @@ if (typeof document.contains !== 'function') {
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// renderJS.declareJS // renderJS.declareJS
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
renderJS.declareJS = function (url) { renderJS.declareJS = function (url, container, pop) {
// https://www.html5rocks.com/en/tutorials/speed/script-loading/
// Prevent infinite recursion if loading render.js // Prevent infinite recursion if loading render.js
// more than once // more than once
var result; var result;
if (javascript_registration_dict.hasOwnProperty(url)) { if (javascript_registration_dict.hasOwnProperty(url)) {
result = RSVP.resolve(); result = RSVP.resolve();
} else { } else {
javascript_registration_dict[url] = null;
result = new RSVP.Promise(function (resolve, reject) { result = new RSVP.Promise(function (resolve, reject) {
var newScript; var newScript;
newScript = document.createElement('script'); newScript = document.createElement('script');
newScript.async = false;
newScript.type = 'text/javascript'; newScript.type = 'text/javascript';
newScript.src = url;
newScript.onload = function () { newScript.onload = function () {
javascript_registration_dict[url] = null; if (pop === true) {
// Drop the current loading klass info used by selector
gadget_loading_klass_list.shift();
}
resolve(); resolve();
}; };
newScript.onerror = function (e) { newScript.onerror = function (e) {
if (pop === true) {
// Drop the current loading klass info used by selector
gadget_loading_klass_list.shift();
}
reject(e); reject(e);
}; };
document.head.appendChild(newScript); newScript.src = url;
container.appendChild(newScript);
}); });
} }
return result; return result;
...@@ -1801,7 +1765,7 @@ if (typeof document.contains !== 'function') { ...@@ -1801,7 +1765,7 @@ if (typeof document.contains !== 'function') {
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// renderJS.declareCSS // renderJS.declareCSS
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
renderJS.declareCSS = function (url) { renderJS.declareCSS = function (url, container) {
// https://github.com/furf/jquery-getCSS/blob/master/jquery.getCSS.js // https://github.com/furf/jquery-getCSS/blob/master/jquery.getCSS.js
// No way to cleanly check if a css has been loaded // No way to cleanly check if a css has been loaded
// So, always resolve the promise... // So, always resolve the promise...
...@@ -1823,7 +1787,7 @@ if (typeof document.contains !== 'function') { ...@@ -1823,7 +1787,7 @@ if (typeof document.contains !== 'function') {
link.onerror = function (e) { link.onerror = function (e) {
reject(e); reject(e);
}; };
document.head.appendChild(link); container.appendChild(link);
}); });
} }
return result; return result;
...@@ -1832,77 +1796,107 @@ if (typeof document.contains !== 'function') { ...@@ -1832,77 +1796,107 @@ if (typeof document.contains !== 'function') {
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// renderJS.declareGadgetKlass // renderJS.declareGadgetKlass
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
renderJS.declareGadgetKlass = function (url) {
var result;
function parse(xhr) { function parse(xhr, url) {
var tmp_constructor, var tmp_constructor,
key, key,
parsed_html; parsed_html;
if (!gadget_model_dict.hasOwnProperty(url)) { // Class inheritance
// Class inheritance tmp_constructor = function () {
tmp_constructor = function () { RenderJSGadget.call(this);
RenderJSGadget.call(this); };
}; tmp_constructor.__ready_list = RenderJSGadget.__ready_list.slice();
tmp_constructor.__ready_list = RenderJSGadget.__ready_list.slice(); tmp_constructor.__service_list = RenderJSGadget.__service_list.slice();
tmp_constructor.__service_list = RenderJSGadget.__service_list.slice(); tmp_constructor.declareMethod =
tmp_constructor.declareMethod = RenderJSGadget.declareMethod;
RenderJSGadget.declareMethod; tmp_constructor.declareJob =
tmp_constructor.declareJob = RenderJSGadget.declareJob;
RenderJSGadget.declareJob; tmp_constructor.declareAcquiredMethod =
tmp_constructor.declareAcquiredMethod = RenderJSGadget.declareAcquiredMethod;
RenderJSGadget.declareAcquiredMethod; tmp_constructor.allowPublicAcquisition =
tmp_constructor.allowPublicAcquisition = RenderJSGadget.allowPublicAcquisition;
RenderJSGadget.allowPublicAcquisition; tmp_constructor.ready =
tmp_constructor.ready = RenderJSGadget.ready;
RenderJSGadget.ready; tmp_constructor.setState =
tmp_constructor.setState = RenderJSGadget.setState;
RenderJSGadget.setState; tmp_constructor.onStateChange =
tmp_constructor.onStateChange = RenderJSGadget.onStateChange;
RenderJSGadget.onStateChange; tmp_constructor.declareService =
tmp_constructor.declareService = RenderJSGadget.declareService;
RenderJSGadget.declareService; tmp_constructor.onEvent =
tmp_constructor.onEvent = RenderJSGadget.onEvent;
RenderJSGadget.onEvent; tmp_constructor.prototype = new RenderJSGadget();
tmp_constructor.prototype = new RenderJSGadget(); tmp_constructor.prototype.constructor = tmp_constructor;
tmp_constructor.prototype.constructor = tmp_constructor; tmp_constructor.prototype.__path = url;
tmp_constructor.prototype.__path = url; tmp_constructor.prototype.__acquired_method_dict = {};
tmp_constructor.prototype.__acquired_method_dict = {}; // https://developer.mozilla.org/en-US/docs/HTML_in_XMLHttpRequest
// https://developer.mozilla.org/en-US/docs/HTML_in_XMLHttpRequest // https://developer.mozilla.org/en-US/docs/Web/API/DOMParser
// https://developer.mozilla.org/en-US/docs/Web/API/DOMParser // https://developer.mozilla.org/en-US/docs/Code_snippets/HTML_to_DOM
// https://developer.mozilla.org/en-US/docs/Code_snippets/HTML_to_DOM tmp_constructor.__template_element =
tmp_constructor.__template_element = (new DOMParser()).parseFromString(xhr.responseText, "text/html");
(new DOMParser()).parseFromString(xhr.responseText, "text/html"); parsed_html = renderJS.parseGadgetHTMLDocument(
parsed_html = renderJS.parseGadgetHTMLDocument( tmp_constructor.__template_element,
tmp_constructor.__template_element, url
url );
); for (key in parsed_html) {
for (key in parsed_html) { if (parsed_html.hasOwnProperty(key)) {
if (parsed_html.hasOwnProperty(key)) { tmp_constructor.prototype['__' + key] = parsed_html[key];
tmp_constructor.prototype['__' + key] = parsed_html[key];
}
}
gadget_model_dict[url] = tmp_constructor;
} }
return gadget_model_dict[url];
} }
return tmp_constructor;
}
if (gadget_model_dict.hasOwnProperty(url)) { renderJS.declareGadgetKlass = function (url) {
if (gadget_model_defer_dict.hasOwnProperty(url)) {
// Return klass object if it already exists // Return klass object if it already exists
result = RSVP.resolve(gadget_model_dict[url]); return gadget_model_defer_dict[url].promise;
} else {
// Fetch the HTML page and parse it
result = new RSVP.Queue()
.push(function () {
return ajax(url);
})
.push(function (xhr) {
return parse(xhr);
});
} }
return result;
var tmp_constructor,
defer = RSVP.defer();
gadget_model_defer_dict[url] = defer;
// Change the global variable to update the loading queue
loading_klass_promise = defer.promise;
// Fetch the HTML page and parse it
return new RSVP.Queue()
.push(function () {
return ajax(url);
})
.push(function (result) {
tmp_constructor = parse(result, url);
var fragment = document.createDocumentFragment(),
promise_list = [],
i,
js_list = tmp_constructor.prototype.__required_js_list,
css_list = tmp_constructor.prototype.__required_css_list;
// Load JS
if (js_list.length) {
gadget_loading_klass_list.push(tmp_constructor);
for (i = 0; i < js_list.length - 1; i += 1) {
promise_list.push(renderJS.declareJS(js_list[i], fragment));
}
promise_list.push(renderJS.declareJS(js_list[i], fragment, true));
}
// Load CSS
for (i = 0; i < css_list.length; i += 1) {
promise_list.push(renderJS.declareCSS(css_list[i], fragment));
}
document.head.appendChild(fragment);
return RSVP.all(promise_list);
})
.push(function () {
defer.resolve(tmp_constructor);
return tmp_constructor;
})
.push(undefined, function (e) {
// Drop the current loading klass info used by selector
// even in case of error
defer.reject(e);
throw e;
});
}; };
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
...@@ -1910,7 +1904,7 @@ if (typeof document.contains !== 'function') { ...@@ -1910,7 +1904,7 @@ if (typeof document.contains !== 'function') {
///////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////
// For test purpose only // For test purpose only
renderJS.clearGadgetKlassList = function () { renderJS.clearGadgetKlassList = function () {
gadget_model_dict = {}; gadget_model_defer_dict = {};
javascript_registration_dict = {}; javascript_registration_dict = {};
stylesheet_registration_dict = {}; stylesheet_registration_dict = {};
}; };
...@@ -1980,7 +1974,7 @@ if (typeof document.contains !== 'function') { ...@@ -1980,7 +1974,7 @@ if (typeof document.contains !== 'function') {
function bootstrap() { function bootstrap() {
var url = removeHash(window.location.href), var url = removeHash(window.location.href),
tmp_constructor, TmpConstructor,
root_gadget, root_gadget,
loading_gadget_promise = new RSVP.Queue(), loading_gadget_promise = new RSVP.Queue(),
declare_method_count = 0, declare_method_count = 0,
...@@ -1996,7 +1990,7 @@ if (typeof document.contains !== 'function') { ...@@ -1996,7 +1990,7 @@ if (typeof document.contains !== 'function') {
connection_ready = false; connection_ready = false;
// Create the gadget class for the current url // Create the gadget class for the current url
if (gadget_model_dict.hasOwnProperty(url)) { if (gadget_model_defer_dict.hasOwnProperty(url)) {
throw new Error("bootstrap should not be called twice"); throw new Error("bootstrap should not be called twice");
} }
loading_klass_promise = new RSVP.Promise(function (resolve, reject) { loading_klass_promise = new RSVP.Promise(function (resolve, reject) {
...@@ -2025,40 +2019,42 @@ if (typeof document.contains !== 'function') { ...@@ -2025,40 +2019,42 @@ if (typeof document.contains !== 'function') {
// tmp_constructor = RenderJSEmbeddedGadget // tmp_constructor = RenderJSEmbeddedGadget
if (window.self === window.top) { if (window.self === window.top) {
// XXX Copy/Paste from declareGadgetKlass // XXX Copy/Paste from declareGadgetKlass
tmp_constructor = function () { TmpConstructor = function () {
RenderJSGadget.call(this); RenderJSGadget.call(this);
}; };
tmp_constructor.declareMethod = RenderJSGadget.declareMethod; TmpConstructor.declareMethod = RenderJSGadget.declareMethod;
tmp_constructor.declareJob = RenderJSGadget.declareJob; TmpConstructor.declareJob = RenderJSGadget.declareJob;
tmp_constructor.declareAcquiredMethod = TmpConstructor.declareAcquiredMethod =
RenderJSGadget.declareAcquiredMethod; RenderJSGadget.declareAcquiredMethod;
tmp_constructor.allowPublicAcquisition = TmpConstructor.allowPublicAcquisition =
RenderJSGadget.allowPublicAcquisition; RenderJSGadget.allowPublicAcquisition;
tmp_constructor.__ready_list = RenderJSGadget.__ready_list.slice(); TmpConstructor.__ready_list = RenderJSGadget.__ready_list.slice();
tmp_constructor.ready = RenderJSGadget.ready; TmpConstructor.ready = RenderJSGadget.ready;
tmp_constructor.setState = RenderJSGadget.setState; TmpConstructor.setState = RenderJSGadget.setState;
tmp_constructor.onStateChange = RenderJSGadget.onStateChange; TmpConstructor.onStateChange = RenderJSGadget.onStateChange;
tmp_constructor.__service_list = RenderJSGadget.__service_list.slice(); TmpConstructor.__service_list = RenderJSGadget.__service_list.slice();
tmp_constructor.declareService = TmpConstructor.declareService =
RenderJSGadget.declareService; RenderJSGadget.declareService;
tmp_constructor.onEvent = TmpConstructor.onEvent =
RenderJSGadget.onEvent; RenderJSGadget.onEvent;
tmp_constructor.prototype = new RenderJSGadget(); TmpConstructor.prototype = new RenderJSGadget();
tmp_constructor.prototype.constructor = tmp_constructor; TmpConstructor.prototype.constructor = TmpConstructor;
tmp_constructor.prototype.__path = url; TmpConstructor.prototype.__path = url;
gadget_model_dict[url] = tmp_constructor; gadget_model_defer_dict[url] = {
promise: RSVP.resolve(TmpConstructor)
};
// Create the root gadget instance and put it in the loading stack // Create the root gadget instance and put it in the loading stack
root_gadget = new gadget_model_dict[url](); root_gadget = new TmpConstructor();
setAqParent(root_gadget, last_acquisition_gadget); setAqParent(root_gadget, last_acquisition_gadget);
} else { } else {
// Create the root gadget instance and put it in the loading stack // Create the root gadget instance and put it in the loading stack
tmp_constructor = RenderJSEmbeddedGadget; TmpConstructor = RenderJSEmbeddedGadget;
tmp_constructor.__ready_list = RenderJSGadget.__ready_list.slice(); TmpConstructor.__ready_list = RenderJSGadget.__ready_list.slice();
tmp_constructor.__service_list = RenderJSGadget.__service_list.slice(); TmpConstructor.__service_list = RenderJSGadget.__service_list.slice();
tmp_constructor.prototype.__path = url; TmpConstructor.prototype.__path = url;
root_gadget = new RenderJSEmbeddedGadget(); root_gadget = new RenderJSEmbeddedGadget();
setAqParent(root_gadget, last_acquisition_gadget); setAqParent(root_gadget, last_acquisition_gadget);
...@@ -2072,7 +2068,7 @@ if (typeof document.contains !== 'function') { ...@@ -2072,7 +2068,7 @@ if (typeof document.contains !== 'function') {
iframe_top_gadget = false; iframe_top_gadget = false;
//Default: Define __aq_parent to inform parent window //Default: Define __aq_parent to inform parent window
root_gadget.__aq_parent = root_gadget.__aq_parent =
tmp_constructor.prototype.__aq_parent = function (method_name, TmpConstructor.prototype.__aq_parent = function (method_name,
argument_list, time_out) { argument_list, time_out) {
return new RSVP.Promise(function (resolve, reject) { return new RSVP.Promise(function (resolve, reject) {
embedded_channel.call({ embedded_channel.call({
...@@ -2154,7 +2150,7 @@ if (typeof document.contains !== 'function') { ...@@ -2154,7 +2150,7 @@ if (typeof document.contains !== 'function') {
notifyDeclareMethod("getTitle"); notifyDeclareMethod("getTitle");
// Surcharge declareMethod to inform parent window // Surcharge declareMethod to inform parent window
tmp_constructor.declareMethod = function (name, callback) { TmpConstructor.declareMethod = function (name, callback) {
var result = RenderJSGadget.declareMethod.apply( var result = RenderJSGadget.declareMethod.apply(
this, this,
[name, callback] [name, callback]
...@@ -2163,41 +2159,43 @@ if (typeof document.contains !== 'function') { ...@@ -2163,41 +2159,43 @@ if (typeof document.contains !== 'function') {
return result; return result;
}; };
tmp_constructor.declareService = TmpConstructor.declareService =
RenderJSGadget.declareService; RenderJSGadget.declareService;
tmp_constructor.declareJob = TmpConstructor.declareJob =
RenderJSGadget.declareJob; RenderJSGadget.declareJob;
tmp_constructor.onEvent = TmpConstructor.onEvent =
RenderJSGadget.onEvent; RenderJSGadget.onEvent;
tmp_constructor.declareAcquiredMethod = TmpConstructor.declareAcquiredMethod =
RenderJSGadget.declareAcquiredMethod; RenderJSGadget.declareAcquiredMethod;
tmp_constructor.allowPublicAcquisition = TmpConstructor.allowPublicAcquisition =
RenderJSGadget.allowPublicAcquisition; RenderJSGadget.allowPublicAcquisition;
iframe_top_gadget = true; iframe_top_gadget = true;
} }
tmp_constructor.prototype.__acquired_method_dict = {}; TmpConstructor.prototype.__acquired_method_dict = {};
gadget_loading_klass = tmp_constructor; gadget_loading_klass_list.push(TmpConstructor);
function init() { function init() {
// XXX HTML properties can only be set when the DOM is fully loaded // XXX HTML properties can only be set when the DOM is fully loaded
var settings = renderJS.parseGadgetHTMLDocument(document, url), var settings = renderJS.parseGadgetHTMLDocument(document, url),
j, j,
key; key,
fragment = document.createDocumentFragment();
for (key in settings) { for (key in settings) {
if (settings.hasOwnProperty(key)) { if (settings.hasOwnProperty(key)) {
tmp_constructor.prototype['__' + key] = settings[key]; TmpConstructor.prototype['__' + key] = settings[key];
} }
} }
tmp_constructor.__template_element = document.createElement("div"); TmpConstructor.__template_element = document.createElement("div");
root_gadget.element = document.body; root_gadget.element = document.body;
root_gadget.state = {}; root_gadget.state = {};
for (j = 0; j < root_gadget.element.childNodes.length; j += 1) { for (j = 0; j < root_gadget.element.childNodes.length; j += 1) {
tmp_constructor.__template_element.appendChild( fragment.appendChild(
root_gadget.element.childNodes[j].cloneNode(true) root_gadget.element.childNodes[j].cloneNode(true)
); );
} }
TmpConstructor.__template_element.appendChild(fragment);
RSVP.all([root_gadget.getRequiredJSList(), RSVP.all([root_gadget.getRequiredJSList(),
root_gadget.getRequiredCSSList()]) root_gadget.getRequiredCSSList()])
.then(function (all_list) { .then(function (all_list) {
...@@ -2210,7 +2208,7 @@ if (typeof document.contains !== 'function') { ...@@ -2210,7 +2208,7 @@ if (typeof document.contains !== 'function') {
for (i = 0; i < css_list.length; i += 1) { for (i = 0; i < css_list.length; i += 1) {
stylesheet_registration_dict[css_list[i]] = null; stylesheet_registration_dict[css_list[i]] = null;
} }
gadget_loading_klass = undefined; gadget_loading_klass_list.shift();
}).then(function () { }).then(function () {
// select the target node // select the target node
...@@ -2304,15 +2302,15 @@ if (typeof document.contains !== 'function') { ...@@ -2304,15 +2302,15 @@ if (typeof document.contains !== 'function') {
return fct.call(g, g); return fct.call(g, g);
}; };
} }
tmp_constructor.ready(function (g) { TmpConstructor.ready(function () {
return startService(g); return startService(this);
}); });
loading_gadget_promise.push(ready_wrapper); loading_gadget_promise.push(ready_wrapper);
for (i = 0; i < tmp_constructor.__ready_list.length; i += 1) { for (i = 0; i < TmpConstructor.__ready_list.length; i += 1) {
// Put a timeout? // Put a timeout?
loading_gadget_promise loading_gadget_promise
.push(ready_executable_wrapper(tmp_constructor.__ready_list[i])) .push(ready_executable_wrapper(TmpConstructor.__ready_list[i]))
// Always return the gadget instance after ready function // Always return the gadget instance after ready function
.push(ready_wrapper); .push(ready_wrapper);
} }
...@@ -2349,4 +2347,4 @@ if (typeof document.contains !== 'function') { ...@@ -2349,4 +2347,4 @@ if (typeof document.contains !== 'function') {
bootstrap(); bootstrap();
}(document, window, RSVP, DOMParser, Channel, MutationObserver, Node, }(document, window, RSVP, DOMParser, Channel, MutationObserver, Node,
FileReader, Blob, navigator, Event)); FileReader, Blob, navigator, Event, URL));
\ No newline at end of file
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