Commit 2f9b088a authored by Thibaut Frain's avatar Thibaut Frain

renderjs 0.3.2 update

parent a6373f47
......@@ -8,6 +8,7 @@
<!-- Jquery -->
<script src="../lib/jquery.js" type="text/javascript"></script>
<!-- renderjs -->
<script src="../lib/rsvp.js" type="text/javascript"></script>
<script src="../lib/jschannel.js" type="text/javascript"></script>
<script src="../lib/renderjs.js" type="text/javascript"></script>
</head>
......
......@@ -12,6 +12,7 @@
<script src="../lib/jquery.hotkeys.js"></script>
<script src="../lib/bootstrap.min.js"></script>
<script src="../lib/bootstrap-wysiwyg.js"></script>
<script src="../lib/rsvp.js"></script>
<script src="../lib/jschannel.js"></script>
<script src="../lib/renderjs.js"></script>
<script src="../js/gadget_bootstrap_wysiwyg.js"></script>
......
......@@ -9,6 +9,7 @@
<link rel="stylesheet" href="../css/codemirror.css">
<script src="../lib/jquery.js"></script>
<script src="../lib/rsvp.js"></script>
<script src="../lib/jschannel.js"></script>
<script src="../lib/renderjs.js"></script>
<script src="../lib/codemirror/codemirror.js"></script>
......
......@@ -8,6 +8,7 @@
<!-- Jquery -->
<script src="../lib/jquery.js" type="text/javascript"></script>
<!-- renderjs -->
<script src="../lib/rsvp.js" type="text/javascript"></script>
<script src="../lib/jschannel.js" type="text/javascript"></script>
<script src="../lib/renderjs.js" type="text/javascript"></script>
</head>
......
......@@ -8,6 +8,7 @@
<!-- Jquery -->
<script src="../lib/jquery.js" type="text/javascript"></script>
<!-- renderjs -->
<script src="../lib/rsvp.js" type="text/javascript"></script>
<script src="../lib/jschannel.js" type="text/javascript"></script>
<script src="../lib/renderjs.js" type="text/javascript"></script>
</head>
......
......@@ -26,6 +26,7 @@
<script src="../lib/jquery.mobile.js" type="text/javascript"></script>
<script src="../lib/extensions.js" type="text/javascript"></script>
<!-- renderjs -->
<script src="../lib/rsvp.js" type="text/javascript"></script>
<script src="../lib/jschannel.js" type="text/javascript"></script>
<script src="../lib/renderjs.js" type="text/javascript"></script>
<!-- route -->
......
......@@ -7,6 +7,7 @@
<!-- Jquery -->
<script src="../lib/jquery.js" type="text/javascript"></script>
<!-- renderjs -->
<script src="../lib/rsvp.js" type="text/javascript"></script>
<script src="../lib/jschannel.js" type="text/javascript"></script>
<script src="../lib/renderjs.js" type="text/javascript"></script>
......
......@@ -11,6 +11,7 @@
<script src="../lib/jquery.sheet-2.0.0/jquery-1.5.2.min.js"></script>
<script src="../lib/jschannel.js"></script>
<script src="../lib/rsvp.js"></script>
<script src="../lib/renderjs.js"></script>
<script src="../lib/jquery.sheet-2.0.0/jquery.sheet.min.js"></script>
<script src="../lib/jquery.sheet-2.0.0/parser.js"></script>
......@@ -19,7 +20,7 @@
</head>
<body>
<div class="jQuerySheet"></div>
<div id="jQuerySheet"></div>
</body>
......
......@@ -8,6 +8,7 @@
<!-- Jquery -->
<script src="../lib/jquery.js" type="text/javascript"></script>
<!-- renderjs -->
<script src="../lib/rsvp.js" type="text/javascript"></script>
<script src="../lib/jschannel.js" type="text/javascript"></script>
<script src="../lib/renderjs.js" type="text/javascript"></script>
<!-- custom script -->
......
......@@ -21,8 +21,8 @@
rJS(this).editor.html('');
})
.ready(function () {
init.apply(rJS(this));
.ready(function (g) {
init.apply(g);
});
}(window, jQuery, rJS));
......@@ -20,9 +20,9 @@
return rJS(this).cmInstance;
})
.ready(function () {
.ready(function (g) {
var textarea = $("textarea#codemirror")[0];
rJS(this).cmInstance = CodeMirror.fromTextArea(textarea);
g.cmInstance = CodeMirror.fromTextArea(textarea);
});
}(window, jQuery, rJS, CodeMirror));
......@@ -4,7 +4,7 @@
(function (window, $, rJS) {
function init(config) {
this.parent = this.context.find('.jQuerySheet');
this.parent = $(window.document.getElementById('jQuerySheet'));
this.parent.sheet(config);
this.instance = this.parent.getSheet();
}
......@@ -49,8 +49,9 @@
init.apply(rJS(this), [default_config]);
})
.ready(function () {
init.apply(rJS(this), [default_config]);
.ready(function (g) {
console.log('truc');
init.apply(g, [default_config]);
});
}(window, jQuery, rJS));
/*! RenderJs v0.2 */
/*global jQuery, window, document, DOMParser, Channel */
"use strict";
/*! RenderJs */
/*
* DOMParser HTML extension
......@@ -12,6 +10,7 @@
*/
/*! @source https://gist.github.com/1129031 */
(function (DOMParser) {
"use strict";
var DOMParser_proto = DOMParser.prototype,
real_parseFromString = DOMParser_proto.parseFromString;
......@@ -22,7 +21,7 @@
// text/html parsing is natively supported
return;
}
} catch (ex) {}
} catch (ignore) {}
DOMParser_proto.parseFromString = function (markup, type) {
var result, doc, doc_elt, first_elt;
......@@ -50,17 +49,24 @@
* renderJs - Generic Gadget library renderer.
* http://www.renderjs.org/documentation
*/
(function (document, window, $, DOMParser, Channel, undefined) {
(function (document, window, RSVP, DOMParser, Channel, undefined) {
"use strict";
var gadget_model_dict = {},
javascript_registration_dict = {},
stylesheet_registration_dict = {},
gadget_loading_klass,
methods,
loading_gadget_promise,
renderJS;
function RenderJSGadget() {}
/////////////////////////////////////////////////////////////////
// RenderJSGadget
/////////////////////////////////////////////////////////////////
function RenderJSGadget() {
if (!(this instanceof RenderJSGadget)) {
return new RenderJSGadget();
}
}
RenderJSGadget.prototype.title = "";
RenderJSGadget.prototype.interface_list = [];
RenderJSGadget.prototype.path = "";
......@@ -74,37 +80,18 @@
return this;
};
/////////////////////////////////////////////////////////////////
// RenderJSGadget.declareMethod
/////////////////////////////////////////////////////////////////
RenderJSGadget.declareMethod = function (name, callback) {
// // Register the potentially loading javascript
// var script_element = $('script').last(),
// src = script_element.attr('src');
// if (src !== undefined) {
// if (javascript_registration_dict[src] === undefined) {
// // First time loading the JS file.
// // Remember all declareMethod calls
// javascript_registration_dict[src] = {
// loaded: false,
// method_list: [[name, callback]],
// };
// script_element.load(function () {
// javascript_registration_dict[src].loaded = true;
// });
// } else if (!javascript_registration_dict[src].loaded) {
// javascript_registration_dict[src].method_list.push([name, callback]);
// }
// }
this.prototype[name] = function () {
var dfr = $.Deferred(),
gadget = this;
$.when(callback.apply(this, arguments))
.done(function () {
dfr.resolveWith(gadget, arguments);
})
.fail(function () {
dfr.rejectWith(gadget, arguments);
var context = this,
argument_list = arguments;
return new RSVP.Queue()
.push(function () {
return callback.apply(context, argument_list);
});
return dfr.promise();
};
// Allow chain
return this;
......@@ -131,80 +118,23 @@
// Returns the title of a gadget
return this.title;
})
.declareMethod('getHTML', function () {
// Returns the HTML of a gadget
return this.html;
.declareMethod('getElement', function () {
// Returns the DOM Element of a gadget
if (this.element === undefined) {
throw new Error("No element defined");
}
return this.element;
});
/////////////////////////////////////////////////////////////////
// RenderJSEmbeddedGadget
/////////////////////////////////////////////////////////////////
// Class inheritance
function RenderJSEmbeddedGadget() {
var root_gadget = this,
declare_method_count = 0,
gadget_ready = false,
// Create the communication channel
embedded_channel = Channel.build({
window: window.parent,
origin: "*",
scope: "renderJS"
});
RenderJSGadget.call(this);
// Bind calls to renderJS method on the instance
embedded_channel.bind("methodCall", function (trans, v) {
root_gadget[v[0]].apply(root_gadget, v[1]).done(function (g) {
trans.complete(g);
}).fail(function () {
trans.error(Array.prototype.slice.call(arguments, 0));
});
trans.delayReturn(true);
});
// Notify parent about gadget instanciation
function notifyReady() {
if ((declare_method_count === 0) && (gadget_ready === true)) {
embedded_channel.notify({method: "ready"});
}
}
// Inform parent gadget about declareMethod calls here.
function notifyDeclareMethod(name) {
declare_method_count += 1;
embedded_channel.call({
method: "declareMethod",
params: name,
success: function () {
declare_method_count -= 1;
notifyReady();
},
error: function () {
declare_method_count -= 1;
// console.error(Array.prototype.slice.call(arguments, 0));
},
});
if (!(this instanceof RenderJSEmbeddedGadget)) {
return new RenderJSEmbeddedGadget();
}
notifyDeclareMethod("getInterfaceList");
notifyDeclareMethod("getRequiredCSSList");
notifyDeclareMethod("getRequiredJSList");
notifyDeclareMethod("getPath");
notifyDeclareMethod("getTitle");
notifyDeclareMethod("getHTML");
// Surcharge declareMethod to inform parent window
this.constructor.declareMethod = function (name, callback) {
notifyDeclareMethod(name);
return RenderJSGadget.declareMethod.apply(this, [name, callback]);
};
// Inform parent window that gadget is correctly loaded
loading_gadget_promise.done(function () {
gadget_ready = true;
notifyReady();
}).fail(function () {
embedded_channel.notify({method: "failed"});
});
return root_gadget;
RenderJSGadget.call(this);
}
RenderJSEmbeddedGadget.ready_list = [];
RenderJSEmbeddedGadget.ready =
......@@ -212,319 +142,229 @@
RenderJSEmbeddedGadget.prototype = new RenderJSGadget();
RenderJSEmbeddedGadget.prototype.constructor = RenderJSEmbeddedGadget;
// Class inheritance
/////////////////////////////////////////////////////////////////
// privateDeclarePublicGadget
/////////////////////////////////////////////////////////////////
function privateDeclarePublicGadget(url, options) {
var gadget_instance;
if (options.element === undefined) {
options.element = document.createElement("div");
}
return new RSVP.Queue()
.push(function () {
return renderJS.declareGadgetKlass(url);
})
// Get the gadget class and instanciate it
.push(function (Klass) {
var i,
template_node_list = Klass.template_element.body.childNodes;
gadget_loading_klass = Klass;
gadget_instance = new Klass();
gadget_instance.element = options.element;
for (i = 0; i < template_node_list.length; i += 1) {
gadget_instance.element.appendChild(
template_node_list[i].cloneNode(true)
);
}
// Load dependencies if needed
return RSVP.all([
gadget_instance.getRequiredJSList(),
gadget_instance.getRequiredCSSList()
]);
})
// Load all JS/CSS
.push(function (all_list) {
var parameter_list = [],
i;
// Load JS
for (i = 0; i < all_list[0].length; i += 1) {
parameter_list.push(renderJS.declareJS(all_list[0][i]));
}
// Load CSS
for (i = 0; i < all_list[1].length; i += 1) {
parameter_list.push(renderJS.declareCSS(all_list[1][i]));
}
return RSVP.all(parameter_list);
})
.push(function () {
return gadget_instance;
});
}
/////////////////////////////////////////////////////////////////
// RenderJSIframeGadget
/////////////////////////////////////////////////////////////////
function RenderJSIframeGadget() {
if (!(this instanceof RenderJSIframeGadget)) {
return new RenderJSIframeGadget();
}
RenderJSGadget.call(this);
}
RenderJSIframeGadget.ready_list = [];
RenderJSIframeGadget.declareMethod =
RenderJSGadget.declareMethod;
RenderJSIframeGadget.ready =
RenderJSGadget.ready;
RenderJSIframeGadget.prototype = new RenderJSGadget();
RenderJSIframeGadget.prototype.constructor = RenderJSIframeGadget;
RenderJSGadget.prototype.declareIframedGadget =
function (url, jquery_context) {
var previous_loading_gadget_promise = loading_gadget_promise,
next_loading_gadget_deferred = $.Deferred();
/////////////////////////////////////////////////////////////////
// privateDeclareIframeGadget
/////////////////////////////////////////////////////////////////
function privateDeclareIframeGadget(url, options) {
var gadget_instance,
iframe,
node,
iframe_loading_deferred = RSVP.defer();
// Change the global variable to update the loading queue
loading_gadget_promise = next_loading_gadget_deferred.promise();
if (options.element === undefined) {
throw new Error("DOM element is required to create Iframe Gadget " +
url);
}
// Wait for previous gadget loading to finish first
previous_loading_gadget_promise.always(function () {
// Instanciate iframe
var gadget = new RenderJSIframeGadget();
gadget.context = jquery_context;
// XXX Do not set this info on the instance!
gadget.path = url;
// XXX onload onerror
// $('iframe').load(function() {
// RunAfterIFrameLoaded();
// });
// Create the iframe
if (gadget.context !== undefined) {
$(gadget.context).html(
// Use encodeURI to prevent XSS
'<iframe src="' + encodeURI(url) + '"></iframe>'
);
gadget.chan = Channel.build({
window: gadget.context.find('iframe').first()[0].contentWindow,
// Check if the element is attached to the DOM
node = options.element.parentNode;
while (node !== null) {
if (node === document) {
break;
}
node = node.parentNode;
}
if (node === null) {
throw new Error("The parent element is not attached to the DOM for " +
url);
}
gadget_instance = new RenderJSIframeGadget();
iframe = document.createElement("iframe");
// gadget_instance.element.setAttribute("seamless", "seamless");
iframe.setAttribute("src", url);
gadget_instance.path = url;
gadget_instance.element = options.element;
// Attach it to the DOM
options.element.appendChild(iframe);
// XXX Manage unbind when deleting the gadget
// Create the communication channel with the iframe
gadget_instance.chan = Channel.build({
window: iframe.contentWindow,
origin: "*",
scope: "renderJS"
});
// gadget.getTitle = function () {
// var dfr = $.Deferred();
// gadget.chan.call({
// method: "getTitle",
// success: function (v) {
// dfr.resolve(v);
// }
// });
// return dfr.promise();
// };
gadget.chan.bind("declareMethod", function (trans, method_name) {
gadget[method_name] = function () {
var dfr = $.Deferred();
gadget.chan.call({
// Create new method from the declareMethod call inside the iframe
gadget_instance.chan.bind("declareMethod", function (trans, method_name) {
gadget_instance[method_name] = function () {
var argument_list = arguments;
return new RSVP.Promise(function (resolve, reject) {
gadget_instance.chan.call({
method: "methodCall",
params: [
method_name,
Array.prototype.slice.call(arguments, 0)],
success: function () {
dfr.resolveWith(gadget, arguments);
Array.prototype.slice.call(argument_list, 0)],
success: function (s) {
resolve(s);
},
error: function () {
dfr.rejectWith(gadget, arguments);
error: function (e) {
reject(e);
}
// XXX Error callback
});
return dfr.promise();
});
};
return "OK";
});
// Wait for the iframe to be loaded before continuing
gadget.chan.bind("ready", function (trans) {
next_loading_gadget_deferred.resolve(gadget);
gadget_instance.chan.bind("ready", function (trans) {
iframe_loading_deferred.resolve(gadget_instance);
return "OK";
});
gadget.chan.bind("failed", function (trans) {
next_loading_gadget_deferred.reject();
gadget_instance.chan.bind("failed", function (trans, params) {
iframe_loading_deferred.reject(params);
return "OK";
});
} else {
next_loading_gadget_deferred.reject();
return RSVP.any([
iframe_loading_deferred.promise,
// Timeout to prevent non renderJS embeddable gadget
// XXX Maybe using iframe.onload/onerror would be safer?
RSVP.timeout(5000)
]);
}
});
loading_gadget_promise
// Drop the current loading klass info used by selector
.done(function () {
gadget_loading_klass = undefined;
})
.fail(function () {
gadget_loading_klass = undefined;
})
.done(function (created_gadget) {
$.each(created_gadget.constructor.ready_list,
function (i, callback) {
callback.apply(created_gadget);
});
});
return loading_gadget_promise;
};
/////////////////////////////////////////////////////////////////
// RenderJSGadget.declareGadget
/////////////////////////////////////////////////////////////////
RenderJSGadget.prototype.declareGadget = function (url, options) {
var queue,
previous_loading_gadget_promise = loading_gadget_promise;
RenderJSGadget.prototype.declareGadget = function (url, jquery_context) {
var previous_loading_gadget_promise = loading_gadget_promise,
next_loading_gadget_deferred = $.Deferred();
if (options === undefined) {
options = {};
}
if (options.sandbox === undefined) {
options.sandbox = "public";
}
// Change the global variable to update the loading queue
loading_gadget_promise = next_loading_gadget_deferred.promise();
queue = new RSVP.Queue()
// Wait for previous gadget loading to finish first
previous_loading_gadget_promise.always(function () {
// Get the gadget class and instanciate it
renderJS.declareGadgetKlass(url).done(function (Klass) {
var gadget = new Klass();
gadget.context = jquery_context;
// Load dependencies if needed
$.when(gadget.getRequiredJSList(), gadget.getRequiredCSSList())
.done(function (js_list, css_list) {
var result_list = [],
first_deferred = $.Deferred(),
first_promise = first_deferred.promise();
gadget_loading_klass = Klass;
// Load JS and follow the dependency declaration defined in the
// head
function next(next_js_list) {
var next_js = next_js_list.shift();
if (next_js === undefined) {
first_deferred.resolve();
} else {
renderJS.declareJS(next_js)
.done(function () {
next(next_js_list);
.push(function () {
return previous_loading_gadget_promise;
})
.fail(function () {
first_deferred.reject.apply(
first_deferred,
arguments
);
});
}
.push(undefined, function () {
// Forget previous declareGadget error
return;
})
.push(function () {
var method;
if (options.sandbox === "public") {
method = privateDeclarePublicGadget;
} else if (options.sandbox === "iframe") {
method = privateDeclareIframeGadget;
} else {
throw new Error("Unsupported sandbox options '" +
options.sandbox + "'");
}
next(js_list);
result_list.push(first_promise);
// Load CSS
$.each(css_list, function (i, required_url) {
result_list.push(renderJS.declareCSS(required_url));
});
$.when.apply(this, result_list)
.done(function () {
// Dependency correctly loaded. Fire instanciation success.
next_loading_gadget_deferred.resolve(gadget);
}).fail(function () {
// console.error(Array.prototype.slice.call(arguments, 0));
// One error during css/js loading
next_loading_gadget_deferred.reject.apply(
next_loading_gadget_deferred,
arguments
);
});
}).fail(function () {
// Failed to fetch dependencies information.
next_loading_gadget_deferred.reject.apply(
next_loading_gadget_deferred,
arguments
);
});
}).fail(function () {
// Klass not correctly loaded. Reject instanciation
next_loading_gadget_deferred.reject.apply(next_loading_gadget_deferred,
arguments);
});
});
loading_gadget_promise
return method(url, options);
})
// Set the HTML context
.push(function (gadget_instance) {
var i;
// Drop the current loading klass info used by selector
.done(function () {
gadget_loading_klass = undefined;
// Trigger calling of all ready callback
function ready_wrapper() {
return gadget_instance;
}
for (i = 0; i < gadget_instance.constructor.ready_list.length;
i += 1) {
// Put a timeout?
queue.push(gadget_instance.constructor.ready_list[i]);
// Always return the gadget instance after ready function
queue.push(ready_wrapper);
}
return gadget_instance;
})
.fail(function () {
.push(undefined, function (e) {
// Drop the current loading klass info used by selector
// even in case of error
gadget_loading_klass = undefined;
})
.done(function (created_gadget) {
// Set the content html and call the ready list if instance is
// correctly loaded
if (created_gadget.context !== undefined) {
$(created_gadget.context).html(
created_gadget.constructor.prototype.html
);
}
$.each(created_gadget.constructor.ready_list, function (i, callback) {
callback.apply(created_gadget);
console.warn(e);
throw e;
});
});
loading_gadget_promise = queue;
return loading_gadget_promise;
};
methods = {
loadGadgetFromDom: function () {
$(this).find('[data-gadget-path]').each(function (index, value) {
$(this).renderJS('declareGadget', $(this).attr('data-gadget-path'), {
scope: $(this).attr('data-gadget-scope'),
})
.done(function (value) {
var parsed_xml;
// Check that context is still attached to the DOM
// XXX Usefull?
if ($(this).closest(document.body).length) {
parsed_xml = $($.parseXML(value));
// Inject the css
// XXX Manage relative URL
$.each(parsed_xml.find('link[rel=stylesheet]'),
function (i, link) {
$('head').append(
'<link rel="stylesheet" href="' +
$(link).attr('href') +
'" type="text/css" />'
);
});
// Inject the js
// XXX Manage relative URL
$.each(parsed_xml.find('script[type="text/javascript"]'),
function (i, script) {
// $('head').append(
// '<script type="text/javascript" href="' +
// $(script).attr('src') +
// '" />'
// );
// Prevent infinite recursion if loading render.js
// more than once
if ($('head').find('script[src="' + $(script).attr('src')
+ '"]').length === 0) {
var headID = document.getElementsByTagName("head")[0],
newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.src = $(script).attr('src');
headID.appendChild(newScript);
}
});
// Inject the html
// XXX parseXML does not support <div /> (without 2 tags)
$(this).html(parsed_xml.find('body').clone());
// XXX No idea why it is required to make it work
// Probably because of parseXML
$(this).html($(this).html())
.renderJS('loadGadgetFromDom');
}
});
});
},
};
// // Define a local copy of renderJS
// renderJS = function (selector) {
// // The renderJS object is actually just the init constructor 'enhanced'
// return new renderJS.fn.init(selector, rootrenderJS);
// };
// renderJS.fn = renderJS.prototype = {
// constructor: renderJS,
// init: function (selector, rootrenderJS) {
// var result;
// // HANDLE: $(""), $(null), $(undefined), $(false)
// if (!selector) {
// console.log("no selector");
// result = this;
// // // HANDLE: $(DOMElement)
// // } else if (selector.nodeType) {
// // this.context = this[0] = selector;
// // this.length = 1;
// // result = this;
// // } else if (selector === this) {
// // result = this.constructor();
// } else {
// // throw new Error("Not implemented selector " + selector);
// result = this.constructor();
// }
// return result;
// },
// };
// // Give the init function the renderJS prototype for later instantiation
// renderJS.fn.init.prototype = renderJS.fn;
//
// jQuery.fn.extend({
// attr: function (name, value) {
// return jQuery.access(this, jQuery.attr, name, value,
// arguments.length > 1);
// },
// });
/////////////////////////////////////////////////////////////////
// renderJS selector
/////////////////////////////////////////////////////////////////
renderJS = function (selector) {
var result;
// if (selector.nodeType) {
// console.log(selector);
// } else {
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
result = gadget_loading_klass;
// } else if ($.isFunction(selector)) {
// console.log(selector);
} else if (selector instanceof RenderJSGadget) {
result = selector;
}
......@@ -534,91 +374,76 @@
return result;
};
/////////////////////////////////////////////////////////////////
// renderJS.declareJS
/////////////////////////////////////////////////////////////////
renderJS.declareJS = function (url) {
// // Prevent infinite recursion if loading render.js
// // more than once
// if ($('head').find('script[src="' + $(script).attr('src')
// + '"]').length === 0) {
// var headID = document.getElementsByTagName("head")[0],
// newScript = document.createElement('script');
// newScript.type = 'text/javascript';
// newScript.src = $(script).attr('src');
// headID.appendChild(newScript);
// }
var dfr,
origin_dfr = $.Deferred(),
head_element,
script_element;
// Prevent infinite recursion if loading render.js
// more than once
var result;
if (javascript_registration_dict.hasOwnProperty(url)) {
setTimeout(function () {
origin_dfr.resolve();
});
dfr = origin_dfr.promise();
result = RSVP.resolve();
} else {
dfr = $.ajax({
url: url,
dataType: "script",
cache: true,
}).done(function (script, textStatus) {
result = new RSVP.Promise(function (resolve, reject) {
var newScript;
newScript = document.createElement('script');
newScript.type = 'text/javascript';
newScript.src = url;
newScript.onload = function () {
javascript_registration_dict[url] = null;
// }).fail(function () {
// console.error(Array.prototype.slice.call(arguments, 0));
resolve();
};
newScript.onerror = function (e) {
reject(e);
};
document.head.appendChild(newScript);
});
}
return dfr;
return result;
};
/////////////////////////////////////////////////////////////////
// renderJS.declareCSS
/////////////////////////////////////////////////////////////////
renderJS.declareCSS = function (url) {
// 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...
// http://requirejs.org/docs/faq-advanced.html#css
var origin_dfr = $.Deferred(),
origin_promise = origin_dfr.promise(),
head,
link;
var result;
if (stylesheet_registration_dict.hasOwnProperty(url)) {
setTimeout(function () {
origin_dfr.resolve();
});
result = RSVP.resolve();
} else {
head = document.getElementsByTagName('head')[0];
result = new RSVP.Promise(function (resolve, reject) {
var link;
link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = url;
origin_promise.done(function () {
link.onload = function () {
stylesheet_registration_dict[url] = null;
resolve();
};
link.onerror = function (e) {
reject(e);
};
document.head.appendChild(link);
});
head.appendChild(link);
setTimeout(function () {
origin_dfr.resolve();
});
}
return origin_promise;
return result;
};
/////////////////////////////////////////////////////////////////
// renderJS.declareGadgetKlass
/////////////////////////////////////////////////////////////////
renderJS.declareGadgetKlass = function (url) {
var dfr = $.Deferred(),
parsed_html;
var result,
xhr;
if (gadget_model_dict.hasOwnProperty(url)) {
dfr.resolve(gadget_model_dict[url]);
} else {
$.ajax(url)
.done(function (value, textStatus, jqXHR) {
var klass, tmp_constructor, key;
if (/^text\/html[;]?/.test(
jqXHR.getResponseHeader("Content-Type") || ""
)) {
try {
function parse() {
var tmp_constructor,
key,
parsed_html;
if (!gadget_model_dict.hasOwnProperty(url)) {
// Class inheritance
tmp_constructor = function () {
......@@ -632,30 +457,77 @@
tmp_constructor.prototype = new RenderJSGadget();
tmp_constructor.prototype.constructor = tmp_constructor;
tmp_constructor.prototype.path = url;
parsed_html = renderJS.parseGadgetHTML(value);
// 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/Code_snippets/HTML_to_DOM
tmp_constructor.template_element =
(new DOMParser()).parseFromString(xhr.responseText, "text/html");
parsed_html = renderJS.parseGadgetHTMLDocument(
tmp_constructor.template_element
);
for (key in parsed_html) {
if (parsed_html.hasOwnProperty(key)) {
tmp_constructor.prototype[key] = parsed_html[key];
}
}
gadget_model_dict[url] = tmp_constructor;
}
dfr.resolve(gadget_model_dict[url]);
} catch (e) {
dfr.reject(jqXHR, "HTML Parsing failed");
return gadget_model_dict[url];
}
function resolver(resolve, reject) {
function handler() {
var tmp_result;
try {
if (xhr.readyState === 0) {
// UNSENT
reject(xhr);
} else if (xhr.readyState === 4) {
// DONE
if ((xhr.status < 200) || (xhr.status >= 300) ||
(!/^text\/html[;]?/.test(
xhr.getResponseHeader("Content-Type") || ""
))) {
reject(xhr);
} else {
dfr.reject(jqXHR, "Unexpected content type");
tmp_result = parse();
resolve(tmp_result);
}
}
} catch (e) {
reject(e);
}
}
xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.onreadystatechange = handler;
xhr.setRequestHeader('Accept', 'text/html');
xhr.withCredentials = true;
xhr.send();
}
function canceller() {
if ((xhr !== undefined) && (xhr.readyState !== xhr.DONE)) {
xhr.abort();
}
})
.fail(function () {
dfr.reject.apply(dfr, arguments);
});
}
return dfr.promise();
if (gadget_model_dict.hasOwnProperty(url)) {
// Return klass object if it already exists
result = RSVP.resolve(gadget_model_dict[url]);
} else {
// Fetch the HTML page and parse it
result = new RSVP.Promise(resolver, canceller);
}
return result;
};
/////////////////////////////////////////////////////////////////
// renderJS.clearGadgetKlassList
/////////////////////////////////////////////////////////////////
// For test purpose only
renderJS.clearGadgetKlassList = function () {
gadget_model_dict = {};
......@@ -663,55 +535,48 @@
stylesheet_registration_dict = {};
};
renderJS.parseGadgetHTML = function (html) {
var parsed_xml,
result,
settings = {
/////////////////////////////////////////////////////////////////
// renderJS.parseGadgetHTMLDocument
/////////////////////////////////////////////////////////////////
renderJS.parseGadgetHTMLDocument = function (document_element) {
var settings = {
title: "",
interface_list: [],
html: "",
required_css_list: [],
required_js_list: [],
};
if (html.constructor === String) {
// 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/Code_snippets/HTML_to_DOM
// parsed_xml = $($.parseXML(html));
// parsed_xml = $('<div/>').html(html);
parsed_xml = $((new DOMParser()).parseFromString(html, "text/html"));
settings.title = parsed_xml.find('head > title').first().text();
required_js_list: []
},
i,
element;
if (document_element.nodeType === 9) {
settings.title = document_element.title;
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
$.each(parsed_xml.find('head > link[rel=stylesheet]'),
function (i, link) {
settings.required_css_list.push($(link).attr('href'));
});
$.each(parsed_xml.find('head > script[type="text/javascript"]'),
function (i, script) {
settings.required_js_list.push($(script).attr('src'));
});
$.each(parsed_xml.find(
'head > link[rel="http://www.renderjs.org/rel/interface"]'
), function (i, link) {
settings.interface_list.push($(link).attr('href'));
});
settings.html = parsed_xml.find('html > body').first().html();
if (settings.html === undefined) {
settings.html = "";
// element.href returns absolute URL in firefox but "" in chrome;
if (element.rel === "stylesheet") {
settings.required_css_list.push(element.getAttribute("href"));
} else if (element.type === "text/javascript") {
settings.required_js_list.push(element.getAttribute("src"));
} else if (element.rel === "http://www.renderjs.org/rel/interface") {
settings.interface_list.push(element.getAttribute("href"));
}
}
}
result = settings;
} else {
throw new Error(html + " is not a string");
throw new Error("The first parameter should be an HTMLDocument");
}
return result;
return settings;
};
/////////////////////////////////////////////////////////////////
// global
/////////////////////////////////////////////////////////////////
window.rJS = window.renderJS = renderJS;
window.RenderJSGadget = RenderJSGadget;
window.RenderJSEmbeddedGadget = RenderJSEmbeddedGadget;
window.RenderJSIframeGadget = RenderJSIframeGadget;
///////////////////////////////////////////////////
// Bootstrap process. Register the self gadget.
......@@ -721,14 +586,18 @@
var url = window.location.href,
tmp_constructor,
root_gadget,
loading_gadget_deferred = $.Deferred();
declare_method_count = 0,
embedded_channel,
notifyReady,
notifyDeclareMethod,
gadget_ready = false;
// Create the gadget class for the current url
if (gadget_model_dict.hasOwnProperty(url)) {
throw new Error("bootstrap should not be called twice");
}
loading_gadget_promise = loading_gadget_deferred.promise();
loading_gadget_promise = new RSVP.Promise(function (resolve, reject) {
if (window.self === window.top) {
// XXX Copy/Paste from declareGadgetKlass
tmp_constructor = function () {
......@@ -744,47 +613,138 @@
// Create the root gadget instance and put it in the loading stack
root_gadget = new gadget_model_dict[url]();
} else {
// Create the communication channel
embedded_channel = Channel.build({
window: window.parent,
origin: "*",
scope: "renderJS"
});
// Create the root gadget instance and put it in the loading stack
tmp_constructor = RenderJSEmbeddedGadget;
root_gadget = new RenderJSEmbeddedGadget();
// Bind calls to renderJS method on the instance
embedded_channel.bind("methodCall", function (trans, v) {
root_gadget[v[0]].apply(root_gadget, v[1]).then(function (g) {
trans.complete(g);
}).fail(function (e) {
trans.error(e.toString());
});
trans.delayReturn(true);
});
// Notify parent about gadget instanciation
notifyReady = function () {
if ((declare_method_count === 0) && (gadget_ready === true)) {
embedded_channel.notify({method: "ready"});
}
gadget_loading_klass = tmp_constructor;
};
// Inform parent gadget about declareMethod calls here.
notifyDeclareMethod = function (name) {
declare_method_count += 1;
embedded_channel.call({
method: "declareMethod",
params: name,
success: function () {
declare_method_count -= 1;
notifyReady();
},
error: function () {
declare_method_count -= 1;
}
});
};
notifyDeclareMethod("getInterfaceList");
notifyDeclareMethod("getRequiredCSSList");
notifyDeclareMethod("getRequiredJSList");
notifyDeclareMethod("getPath");
notifyDeclareMethod("getTitle");
// Surcharge declareMethod to inform parent window
tmp_constructor.declareMethod = function (name, callback) {
var result = RenderJSGadget.declareMethod.apply(
this,
[name, callback]
);
notifyDeclareMethod(name);
return result;
};
}
gadget_loading_klass = tmp_constructor;
$(document).ready(function () {
function init() {
// XXX HTML properties can only be set when the DOM is fully loaded
var settings = renderJS.parseGadgetHTML($('html')[0].outerHTML),
promise,
var settings = renderJS.parseGadgetHTMLDocument(document),
j,
key;
for (key in settings) {
if (settings.hasOwnProperty(key)) {
tmp_constructor.prototype[key] = settings[key];
}
}
root_gadget.context = $('body');
promise = $.when(root_gadget.getRequiredJSList(),
root_gadget.getRequiredCSSList())
.done(function (js_list, css_list) {
$.each(js_list, function (i, required_url) {
javascript_registration_dict[required_url] = null;
});
$.each(css_list, function (i, required_url) {
stylesheet_registration_dict[url] = null;
tmp_constructor.template_element = document.createElement("div");
root_gadget.element = document.body;
for (j = 0; j < root_gadget.element.childNodes.length; j += 1) {
tmp_constructor.template_element.appendChild(
root_gadget.element.childNodes[j].cloneNode(true)
);
}
RSVP.all([root_gadget.getRequiredJSList(),
root_gadget.getRequiredCSSList()])
.then(function (all_list) {
var i,
js_list = all_list[0],
css_list = all_list[1],
queue;
for (i = 0; i < js_list.length; i += 1) {
javascript_registration_dict[js_list[i]] = null;
}
for (i = 0; i < css_list.length; i += 1) {
stylesheet_registration_dict[css_list[i]] = null;
}
gadget_loading_klass = undefined;
queue = new RSVP.Queue();
function ready_wrapper() {
return root_gadget;
}
queue.push(ready_wrapper);
for (i = 0; i < tmp_constructor.ready_list.length; i += 1) {
// Put a timeout?
queue.push(tmp_constructor.ready_list[i]);
// Always return the gadget instance after ready function
queue.push(ready_wrapper);
}
queue.push(resolve, function (e) {
reject(e);
throw e;
});
$.each(tmp_constructor.ready_list, function (i, callback) {
callback.apply(root_gadget);
return queue;
}).fail(function (e) {
console.warn(e);
reject(e);
});
gadget_loading_klass = undefined;
loading_gadget_deferred.resolve();
}).fail(function () {
loading_gadget_deferred.reject.apply(loading_gadget_deferred,
arguments);
}
document.addEventListener('DOMContentLoaded', init, false);
});
if (window.self !== window.top) {
// Inform parent window that gadget is correctly loaded
loading_gadget_promise.then(function () {
gadget_ready = true;
notifyReady();
}).fail(function (e) {
console.warn(e);
embedded_channel.notify({method: "failed", params: e.toString()});
throw e;
});
}
}
bootstrap();
}(document, window, jQuery, DOMParser, Channel));
}(document, window, RSVP, DOMParser, Channel));
!function(){var a,b;!function(){var c={},d={};a=function(a,b,d){c[a]={deps:b,callback:d}},b=function(a){if(d[a])return d[a];d[a]={};var e=c[a];if(!e)throw new Error("Module '"+a+"' not found.");for(var f,g=e.deps,h=e.callback,i=[],j=0,k=g.length;k>j;j++)"exports"===g[j]?i.push(f={}):i.push(b(g[j]));var l=h.apply(this,i);return d[a]=f||l}}(),a("rsvp/all",["rsvp/promise","exports"],function(a,b){"use strict";function c(a,b){function c(){for(var a,c=0;c<b.length;c++)a=b[c],a&&"function"==typeof a.then&&"function"==typeof a.cancel&&a.cancel()}if("[object Array]"!==Object.prototype.toString.call(b))throw new TypeError("You must pass an array to all.");return new f(function(d,e,f){function g(a){return function(b){h(a,b)}}function h(a,b){l[a]=b,--m===n&&(0===n?d(l):(d(b),c()))}function i(a){return function(b){f({index:a,value:b})}}function j(a){e(a),c()}var k,l=[],m=b.length,n=b.length-a;0===m&&(1===a?d():d([]));for(var o=0;o<b.length;o++)k=b[o],k&&"function"==typeof k.then?k.then(g(o),j,i(o)):h(o,k)},c)}function d(a){return c(a.length,a)}function e(a){return c(1,a)}var f=a.Promise;b.all=d,b.any=e}),a("rsvp/async",["exports"],function(a){"use strict";function b(){return function(a,b){process.nextTick(function(){a(b)})}}function c(){return function(a,b){setImmediate(function(){a(b)})}}function d(){var a=[],b=new h(function(){var b=a.slice();a=[],b.forEach(function(a){var b=a[0],c=a[1];b(c)})}),c=document.createElement("div");return b.observe(c,{attributes:!0}),window.addEventListener("unload",function(){b.disconnect(),b=null},!1),function(b,d){a.push([b,d]),c.setAttribute("drainQueue","drainQueue")}}function e(){return function(a,b){i.setTimeout(function(){a(b)},1)}}var f,g="undefined"!=typeof window?window:{},h=g.MutationObserver||g.WebKitMutationObserver,i="undefined"!=typeof global?global:this;f="function"==typeof setImmediate?c():"undefined"!=typeof process&&"[object process]"==={}.toString.call(process)?b():h?d():e(),a.async=f}),a("rsvp/cancellation_error",["exports"],function(a){"use strict";function b(a){if(this.name="cancel",void 0!==a&&"string"!=typeof a)throw new TypeError("You must pass a string.");this.message=a||"Default Message"}b.prototype=new Error,b.prototype.constructor=b,a.CancellationError=b}),a("rsvp/config",["rsvp/async","exports"],function(a,b){"use strict";var c=a.async,d={};d.async=c,b.config=d}),a("rsvp/defer",["rsvp/promise","exports"],function(a,b){"use strict";function c(){var a={resolve:void 0,reject:void 0,promise:void 0};return a.promise=new d(function(b,c){a.resolve=b,a.reject=c}),a}var d=a.Promise;b.defer=c}),a("rsvp/events",["exports"],function(a){"use strict";var b=function(a,b){this.type=a;for(var c in b)b.hasOwnProperty(c)&&(this[c]=b[c])},c=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c][0]===b)return c;return-1},d=function(a){var b=a._promiseCallbacks;return b||(b=a._promiseCallbacks={}),b},e={mixin:function(a){return a.on=this.on,a.off=this.off,a.trigger=this.trigger,a},on:function(a,b,e){var f,g,h=d(this);for(a=a.split(/\s+/),e=e||this;g=a.shift();)f=h[g],f||(f=h[g]=[]),-1===c(f,b)&&f.push([b,e])},off:function(a,b){var e,f,g,h=d(this);for(a=a.split(/\s+/);f=a.shift();)b?(e=h[f],g=c(e,b),-1!==g&&e.splice(g,1)):h[f]=[]},trigger:function(a,c){var e,f,g,h,i,j=d(this);if(e=j[a])for(var k=0;k<e.length;k++)f=e[k],g=f[0],h=f[1],"object"!=typeof c&&(c={detail:c}),i=new b(a,c),g.call(h,i)}};a.EventTarget=e}),a("rsvp/hash",["rsvp/defer","exports"],function(a,b){"use strict";function c(a){var b=0;for(var c in a)b++;return b}function d(a){var b={},d=e(),f=c(a);0===f&&d.resolve({});var g=function(a){return function(b){h(a,b)}},h=function(a,c){b[a]=c,0===--f&&d.resolve(b)},i=function(a){d.reject(a)};for(var j in a)a[j]&&"function"==typeof a[j].then?a[j].then(g(j),i):h(j,a[j]);return d.promise}var e=a.defer;b.hash=d}),a("rsvp/node",["rsvp/promise","rsvp/all","exports"],function(a,b,c){"use strict";function d(a,b){return function(c,d){c?b(c):arguments.length>2?a(Array.prototype.slice.call(arguments,1)):a(d)}}function e(a){return function(){var b,c,e=Array.prototype.slice.call(arguments),h=this,i=new f(function(a,d){b=a,c=d});return g(e).then(function(e){e.push(d(b,c));try{a.apply(h,e)}catch(f){c(f)}}),i}}var f=a.Promise,g=b.all;c.denodeify=e}),a("rsvp/promise",["rsvp/config","rsvp/events","rsvp/cancellation_error","exports"],function(a,b,c,d){"use strict";function e(a){return f(a)||"object"==typeof a&&null!==a}function f(a){return"function"==typeof a}function g(a){m.onerror&&m.onerror(a.detail)}function h(a,b){a===b?j(a,b):i(a,b)||j(a,b)}function i(a,b){var c,d=null;try{if(a===b)throw new TypeError("A promises callback cannot return that same promise.");if(e(b)&&(d=b.then,f(d)))return a.on("promise:cancelled",function(){f(b.cancel)&&b.cancel()}),d.call(b,function(d){return c?!0:(c=!0,b!==d?h(a,d):j(a,d),void 0)},function(b){return c?!0:(c=!0,k(a,b),void 0)}),!0}catch(g){return k(a,g),!0}return!1}function j(a,b){m.async(function(){a.isFulfilled||a.isRejected||(a.trigger("promise:resolved",{detail:b}),a.isFulfilled=!0,a.fulfillmentValue=b)})}function k(a,b){m.async(function(){a.isFulfilled||a.isRejected||(a.trigger("promise:failed",{detail:b}),a.isRejected=!0,a.rejectedReason=b)})}function l(a,b){m.async(function(){a.trigger("promise:notified",{detail:b})})}var m=a.config,n=b.EventTarget,o=c.CancellationError,p=function(a,b){var c=this,d=!1;if("function"!=typeof a)throw new TypeError("You must pass a resolver function as the sole argument to the promise constructor");if(void 0!==b&&"function"!=typeof b)throw new TypeError("You can only pass a canceller function as the second argument to the promise constructor");if(!(c instanceof p))return new p(a,b);var e=function(a){d||(d=!0,h(c,a))},f=function(a){d||(d=!0,k(c,a))},i=function(a){d||l(c,a)};this.on("promise:failed",function(a){this.trigger("error",{detail:a.detail})},this),this.on("error",g),this.cancel=function(){if(!d){if(void 0!==b)try{b()}catch(a){return f(a),void 0}f(new o)}};try{a(e,f,i)}catch(j){f(j)}},q=function(a,b,c,d){var e,g,j,l,m=f(c);if(!b.isFulfilled&&!b.isRejected){if(m)try{e=c(d.detail),j=!0}catch(n){l=!0,g=n}else e=d.detail,j=!0;i(b,e)||(m&&j?h(b,e):l?k(b,g):"resolve"===a?h(b,e):"reject"===a&&k(b,e))}},r=function(a,b,c){var d;if("function"==typeof b){try{d=b(c.detail)}catch(e){return}l(a,d)}else l(a,c.detail)};p.prototype={constructor:p,isRejected:void 0,isFulfilled:void 0,rejectedReason:void 0,fulfillmentValue:void 0,then:function(a,b,c){this.off("error",g);var d=new this.constructor(function(){},function(){d.trigger("promise:cancelled",{})});return this.isFulfilled&&m.async(function(b){q("resolve",d,a,{detail:b.fulfillmentValue})},this),this.isRejected&&m.async(function(a){q("reject",d,b,{detail:a.rejectedReason})},this),this.on("promise:resolved",function(b){q("resolve",d,a,b)}),this.on("promise:failed",function(a){q("reject",d,b,a)}),this.on("promise:notified",function(a){r(d,c,a)}),d},fail:function(a){return this.then(null,a)},always:function(a){return this.then(a,a)}},n.mixin(p.prototype),d.Promise=p}),a("rsvp/queue",["rsvp/promise","rsvp/timeout","exports"],function(a,b,c){"use strict";function d(a){if(this.name="resolved",void 0!==a&&"string"!=typeof a)throw new TypeError("You must pass a string.");this.message=a||"Default Message"}var e=a.Promise,f=b.delay;d.prototype=new Error,d.prototype.constructor=d;var g=function(){function a(){for(var a=0;2>a;a++)k[a].cancel()}var b,c,h,i,j=this,k=[];return this instanceof g?(b=new e(function(a,b){c=function(b){return i?void 0:(j.isFulfilled=!0,j.fulfillmentValue=b,i=!0,a(b))},h=function(a){return i?void 0:(j.isRejected=!0,j.rejectedReason=a,i=!0,b(a))}},a),k.push(f()),k.push(k[0].then(function(){k.splice(0,2),0===k.length&&c()})),j.cancel=function(){i||(i=!0,b.cancel(),b.fail(function(a){j.isRejected=!0,j.rejectedReason=a}))},j.then=function(){return b.then.apply(b,arguments)},j.push=function(a,b){var e,f=k[k.length-1];if(i)throw new d;return e=f.then(a,b),k.push(e),k.push(e.then(function(a){return k.splice(0,2),0!==k.length?a:(c(a),void 0)},function(a){if(k.splice(0,2),0!==k.length)throw a;h(a)})),this},void 0):new g};g.prototype=Object.create(e.prototype),g.prototype.constructor=g,c.Queue=g,c.ResolvedQueueError=d}),a("rsvp/reject",["rsvp/promise","exports"],function(a,b){"use strict";function c(a){return new d(function(b,c){c(a)})}var d=a.Promise;b.reject=c}),a("rsvp/resolve",["rsvp/promise","exports"],function(a,b){"use strict";function c(a){return new d(function(b,c){if("object"==typeof a&&null!==a){var d=a.then;if(void 0!==d&&"function"==typeof d)return d.apply(a,[b,c])}return b(a)},function(){void 0!==a&&void 0!==a.cancel&&a.cancel()})}var d=a.Promise;b.resolve=c}),a("rsvp/rethrow",["exports"],function(a){"use strict";function b(a){throw c.setTimeout(function(){throw a}),a}var c="undefined"==typeof global?this:global;a.rethrow=b}),a("rsvp/timeout",["rsvp/promise","exports"],function(a,b){"use strict";function c(a,b,c){function d(d,e){g=setTimeout(function(){b?e(c):d(c)},a)}function e(){clearTimeout(g)}var g;return new f(d,e)}function d(a,b){return c(a,!1,b)}function e(a){return c(a,!0,"Timed out after "+a+" ms")}var f=a.Promise;f.prototype.delay=function(a){return this.then(function(b){return d(a,b)})},b.delay=d,b.timeout=e}),a("rsvp",["rsvp/events","rsvp/cancellation_error","rsvp/promise","rsvp/node","rsvp/all","rsvp/queue","rsvp/timeout","rsvp/hash","rsvp/rethrow","rsvp/defer","rsvp/config","rsvp/resolve","rsvp/reject","exports"],function(a,b,c,d,e,f,g,h,i,j,k,l,m,n){"use strict";function o(a,b){C[a]=b}var p=a.EventTarget,q=b.CancellationError,r=c.Promise,s=d.denodeify,t=e.all,u=e.any,v=f.Queue,w=f.ResolvedQueueError,x=g.delay,y=g.timeout,z=h.hash,A=i.rethrow,B=j.defer,C=k.config,D=l.resolve,E=m.reject;n.CancellationError=q,n.Promise=r,n.EventTarget=p,n.all=t,n.any=u,n.Queue=v,n.ResolvedQueueError=w,n.delay=x,n.timeout=y,n.hash=z,n.rethrow=A,n.defer=B,n.denodeify=s,n.configure=o,n.resolve=D,n.reject=E}),window.RSVP=b("rsvp")}(window);
\ No newline at end of file
......@@ -11,6 +11,7 @@
<script src="../src/lib/jquery.js"></script>
<script src="../src/lib/qunit/qunit.js"></script>
<script src="../src/lib/sinon/sinon.js"></script>
<script src="../src/lib/rsvp.js"></script>
<script src="../src/lib/jschannel.js"></script>
<script src="../src/lib/renderjs.js"></script>
<script src="bw-gadget-test.js"></script>
......@@ -18,6 +19,5 @@
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<div id="gadget" style="display:none;"></div>
</body>
</html>
......@@ -20,12 +20,12 @@ QUnit.config.testTimeout = 1000;
return $('iframe').contents().find(selectorString);
}
rJS(window).ready(function () {
var g = rJS(this),
gadget_context = g.context.find('#gadget').first();
rJS(window).ready(function (g) {
var gadget_context = document.getElementById('qunit-fixture');
asyncTest("Bootstrap wysiwyg loading", 1, function () {
g.declareIframedGadget(bwGadgetURL, gadget_context)
asyncTest("[bootstrap wysiwyg] loading (iframed)", 1, function () {
g.declareGadget(bwGadgetURL,
{sandbox: "iframe", element: gadget_context})
.then(function () {
var edattr = iframeSelector("#editor").attr('contenteditable');
equal(edattr,"true");
......@@ -33,8 +33,10 @@ QUnit.config.testTimeout = 1000;
.always(start);
});
asyncTest("Bootstrap wysiwyg loading : textarea is empty", 1, function () {
g.declareIframedGadget(bwGadgetURL, gadget_context)
asyncTest("[bootstrap wysiwyg] textarea start empty (iframed)", 1,
function () {
g.declareGadget(bwGadgetURL,
{sandbox: "iframe", element: gadget_context})
.then(function () {
var ed = iframeSelector("#editor");
equal(ed.html(),"");
......@@ -42,8 +44,9 @@ QUnit.config.testTimeout = 1000;
.always(start);
});
asyncTest("clear content of editor", 1, function () {
g.declareIframedGadget(bwGadgetURL, gadget_context)
asyncTest("[bootstrap wysiwyg] clear content (iframed)", 1, function () {
g.declareGadget(bwGadgetURL,
{sandbox: "iframe", element: gadget_context})
.then(function (gadget) {
iframeSelector('#editor').html('A value');
return gadget;
......@@ -56,8 +59,10 @@ QUnit.config.testTimeout = 1000;
.always(start);
});
asyncTest("get content of editor", 1, function () {
g.declareIframedGadget(bwGadgetURL, gadget_context)
asyncTest("[bootstrap wysiwyg] get content (iframed)", 1,
function () {
g.declareGadget(bwGadgetURL,
{sandbox: "iframe", element: gadget_context})
.then(function (gadget) {
iframeSelector('#editor').html('A value');
return gadget;
......@@ -70,10 +75,11 @@ QUnit.config.testTimeout = 1000;
.always(start);
});
asyncTest("set content of sheet", 2, function () {
asyncTest("[bootstrap wysiwyg] set content (iframed)", 2, function () {
var gadget, content;
g.declareIframedGadget(bwGadgetURL, gadget_context)
g.declareGadget(bwGadgetURL,
{sandbox: "iframe", element: gadget_context})
.then(function (gd) {
iframeSelector('#editor').html('A value');
gadget = gd;
......
......@@ -11,6 +11,7 @@
<script src="../src/lib/jquery.js"></script>
<script src="../src/lib/qunit/qunit.js"></script>
<script src="../src/lib/sinon/sinon.js"></script>
<script src="../src/lib/rsvp.js"></script>
<script src="../src/lib/jschannel.js"></script>
<script src="../src/lib/renderjs.js"></script>
<script src="codemirror-gadget-test.js"></script>
......@@ -18,6 +19,5 @@
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<div id="gadget" style="display:none;"></div>
</body>
</html>
......@@ -20,20 +20,21 @@ QUnit.config.testTimeout = 1000;
return $('iframe').contents().find(selectorString);
}
rJS(window).ready(function () {
var g = rJS(this),
gadget_context = g.context.find('#gadget').first();
rJS(window).ready(function (g) {
var gadget_context = document.getElementById('qunit-fixture');
asyncTest("[codemirror gadget] loading", 1, function () {
g.declareIframedGadget(codemirrorGadgetURL, gadget_context)
asyncTest("[codemirror gadget] loading (iframed)", 1, function () {
g.declareGadget(codemirrorGadgetURL,
{sandbox: "iframe", element: gadget_context})
.then(function () {
ok(iframeSelector(".CodeMirror")[0]);
})
.always(start);
});
asyncTest("[codemirror gadget] empty initial textarea", 1, function () {
g.declareIframedGadget(codemirrorGadgetURL, gadget_context)
asyncTest("[codemirror gadget] empty initial textarea (iframed)", 1, function () {
g.declareGadget(codemirrorGadgetURL,
{sandbox: "iframe", element: gadget_context})
.then(function (gadget) {
return gadget.getContent();
})
......@@ -43,9 +44,10 @@ QUnit.config.testTimeout = 1000;
.always(start);
});
asyncTest("[codemirror gadget] clear content", 1, function () {
asyncTest("[codemirror gadget] clear content (iframed)", 1, function () {
var gadget;
g.declareIframedGadget(codemirrorGadgetURL, gadget_context)
g.declareGadget(codemirrorGadgetURL,
{sandbox: "iframe", element: gadget_context})
.then(function (g) {
gadget = g;
return gadget.setContent("A content");
......@@ -62,9 +64,10 @@ QUnit.config.testTimeout = 1000;
.always(start);
});
asyncTest("[codemirror gadget] set/get content", 1, function () {
asyncTest("[codemirror gadget] set/get content (iframed)", 1, function () {
var gadget;
g.declareIframedGadget(codemirrorGadgetURL, gadget_context)
g.declareGadget(codemirrorGadgetURL,
{sandbox: "iframe", element: gadget_context})
.then(function (g) {
gadget = g;
return gadget.setContent("A content");
......
......@@ -11,6 +11,7 @@
<script src="../src/lib/jquery.js"></script>
<script src="../src/lib/qunit/qunit.js"></script>
<script src="../src/lib/sinon/sinon.js"></script>
<script src="../src/lib/rsvp.js"></script>
<script src="../src/lib/jschannel.js"></script>
<script src="../src/lib/renderjs.js"></script>
<script src="jqs-gadget-test.js"></script>
......@@ -18,6 +19,5 @@
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<div id="gadget" style="display:none;"></div>
</body>
</html>
......@@ -2,7 +2,7 @@
/*jslint indent: 2, maxerr: 3, maxlen: 79 */
"use strict";
QUnit.config.testTimeout = 1000;
QUnit.config.testTimeout = 5000;
(function (window, $, QUnit, rJS) {
......@@ -21,15 +21,15 @@ QUnit.config.testTimeout = 1000;
return res+n+"_table0_cell_c"+i+"_r"+j;
}
rJS(window).ready(function () {
var g = rJS(this),
gadget_context = g.context.find('#gadget').first();
rJS(window).ready(function (g) {
var gadget_context = document.getElementById('qunit-fixture');
asyncTest("(iframe) jquery.sheet loading: sheet loads", 2, function () {
asyncTest("[jquery.sheet] loading (iframed)", 2, function () {
var c0r0 = buildSelector(0,0,0);
var c1r1 = buildSelector(0,1,1);
g.declareIframedGadget(jqsGadgetURL, gadget_context)
g.declareGadget(jqsGadgetURL,
{sandbox: "iframe", element: gadget_context})
.then(function () {
ok(iframeSelector(c0r0).length != 0);
ok(iframeSelector(c1r1).length != 0);
......@@ -37,11 +37,12 @@ QUnit.config.testTimeout = 1000;
.always(start);
});
asyncTest("(iframe) jquery.sheet loading: sheet is empty", 2, function () {
asyncTest("[jquery.sheet] sheet start empty (iframed)", 2, function () {
var c0r0 = buildSelector(0,0,0);
var c1r1 = buildSelector(0,1,1);
g.declareIframedGadget(jqsGadgetURL, gadget_context)
g.declareGadget(jqsGadgetURL,
{sandbox: "iframe", element: gadget_context})
.then(function () {
equal(iframeSelector(c0r0).html(),"");
equal(iframeSelector(c1r1).html(),"");
......@@ -49,11 +50,12 @@ QUnit.config.testTimeout = 1000;
.always(start);
});
asyncTest("(iframe) clear content", 2, function () {
asyncTest("[jquery.sheet] clear content (iframed)", 2, function () {
var c0r0 = buildSelector(0,0,0);
var c1r1 = buildSelector(0,1,1);
g.declareIframedGadget(jqsGadgetURL, gadget_context)
g.declareGadget(jqsGadgetURL,
{sandbox: "iframe", element: gadget_context})
.then(function (gadget) {
iframeSelector(c0r0).html('c0r0Value');
iframeSelector(c1r1).html('c1r1Value');
......@@ -68,11 +70,12 @@ QUnit.config.testTimeout = 1000;
.always(start);
});
asyncTest("(iframe) get content of sheet", 2, function () {
asyncTest("[jquery.sheet] get content (iframed)", 2, function () {
var c0r0 = buildSelector(0,0,0);
var c1r1 = buildSelector(0,1,1);
g.declareIframedGadget(jqsGadgetURL, gadget_context)
g.declareGadget(jqsGadgetURL,
{sandbox: "iframe", element: gadget_context})
.then(function (gadget) {
iframeSelector(c0r0).html('c0r0Value');
iframeSelector(c1r1).html('c1r1Value');
......@@ -88,14 +91,15 @@ QUnit.config.testTimeout = 1000;
.always(start);
});
asyncTest("(iframe) set content of sheet", 4, function () {
asyncTest("[jquery.sheet] set content (iframed)", 4, function () {
var gadget, content,
t0c0r0 = buildSelector(0,0,0),
t0c1r1 = buildSelector(0,1,1),
t2c0r0 = buildSelector(2,0,0),
t2c1r1 = buildSelector(2,1,1);
g.declareIframedGadget(jqsGadgetURL, gadget_context)
g.declareGadget(jqsGadgetURL,
{sandbox: "iframe", element: gadget_context})
.then(function (gd) {
iframeSelector(t0c0r0).html('c0r0Value');
iframeSelector(t0c1r1).html('c1r1Value');
......@@ -118,100 +122,98 @@ QUnit.config.testTimeout = 1000;
.always(start);
});
asyncTest("jquery.sheet loading : sheet loads", 2, function () {
var c0r0 = buildSelector(0,0,0);
var c1r1 = buildSelector(0,1,1);
g.declareGadget(jqsGadgetURL, gadget_context)
.then(function () {
ok($(c0r0).length != 0);
ok($(c1r1).length != 0);
})
.always(start);
});
asyncTest("jquery.sheet loading: sheet is empty", 2, function () {
var c0r0 = buildSelector(0,0,0);
var c1r1 = buildSelector(0,1,1);
g.declareIframedGadget(jqsGadgetURL, gadget_context)
.then(function () {
equal($(c0r0).html(),"");
equal($(c1r1).html(),"");
})
.always(start);
});
asyncTest("clear content", 2, function () {
var c0r0 = buildSelector(0,0,0);
var c1r1 = buildSelector(0,1,1);
g.declareIframedGadget(jqsGadgetURL, gadget_context)
.then(function (gadget) {
$(c0r0).html('c0r0Value');
$(c1r1).html('c1r1Value');
return gadget;
})
.then(function (gadget) {
return gadget.clearContent().then(function () {
equal($(c0r0).text(),"");
equal($(c1r1).text(),"");
});
})
.always(start);
});
asyncTest("get content of sheet", 2, function () {
var c0r0 = buildSelector(0,0,0);
var c1r1 = buildSelector(0,1,1);
g.declareIframedGadget(jqsGadgetURL, gadget_context)
.then(function (gadget) {
$(c0r0).html('c0r0Value');
$(c1r1).html('c1r1Value');
return gadget;
})
.then(function (gadget) {
return gadget.getContent().then(function (content) {
var json = JSON.parse(content)[0];
equal(json.data.r0.c0.value,"c0r0Value");
equal(json.data.r1.c1.value,"c1r1Value");
});
})
.always(start);
});
asyncTest("set content of sheet", 4, function () {
var gadget, content,
t0c0r0 = buildSelector(0,0,0),
t0c1r1 = buildSelector(0,1,1),
t2c0r0 = buildSelector(2,0,0),
t2c1r1 = buildSelector(2,1,1);
g.declareIframedGadget(jqsGadgetURL, gadget_context)
.then(function (gd) {
$(t0c0r0).html('c0r0Value');
$(t0c1r1).html('c1r1Value');
gadget = gd;
return gadget.getContent();
})
.then(function (c) {
content = c;
return gadget.clearContent();
})
.then(function () {
equal($(t0c0r0).text(),"");
equal($(t2c1r1).text(),"");
return gadget.setContent(content);
})
.then(function () {
equal($(t2c0r0).text(),"c0r0Value");
equal($(t2c1r1).text(),"c1r1Value");
})
.always(start);
});
// asyncTest("jquery.sheet loading : sheet loads", 2, function () {
// var c0r0 = buildSelector(0,0,0);
// var c1r1 = buildSelector(0,1,1);
// g.declareGadget(jqsGadgetURL, {element: gadget_context})
// .then(function () {
// ok($(c0r0).length != 0);
// ok($(c1r1).length != 0);
// })
// .always(start);
// });
// asyncTest("jquery.sheet loading: sheet is empty", 2, function () {
// var c0r0 = buildSelector(0,0,0);
// var c1r1 = buildSelector(0,1,1);
// g.declareGadget(jqsGadgetURL, {element: gadget_context})
// .then(function () {
// equal($(c0r0).html(),"");
// equal($(c1r1).html(),"");
// })
// .always(start);
// });
// asyncTest("clear content", 2, function () {
// var c0r0 = buildSelector(0,0,0);
// var c1r1 = buildSelector(0,1,1);
// g.declareGadget(jqsGadgetURL, {element: gadget_context})
// .then(function (gadget) {
// $(c0r0).html('c0r0Value');
// $(c1r1).html('c1r1Value');
// return gadget;
// })
// .then(function (gadget) {
// return gadget.clearContent().then(function () {
// equal($(c0r0).text(),"");
// equal($(c1r1).text(),"");
// });
// })
// .always(start);
// });
// asyncTest("get content of sheet", 2, function () {
// var c0r0 = buildSelector(0,0,0);
// var c1r1 = buildSelector(0,1,1);
// g.declareGadget(jqsGadgetURL, {element: gadget_context})
// .then(function (gadget) {
// $(c0r0).html('c0r0Value');
// $(c1r1).html('c1r1Value');
// return gadget;
// })
// .then(function (gadget) {
// return gadget.getContent().then(function (content) {
// var json = JSON.parse(content)[0];
// equal(json.data.r0.c0.value,"c0r0Value");
// equal(json.data.r1.c1.value,"c1r1Value");
// });
// })
// .always(start);
// });
// asyncTest("set content of sheet", 4, function () {
// var gadget, content,
// t0c0r0 = buildSelector(0,0,0),
// t0c1r1 = buildSelector(0,1,1),
// t2c0r0 = buildSelector(2,0,0),
// t2c1r1 = buildSelector(2,1,1);
// g.declareGadget(jqsGadgetURL, {element: gadget_context})
// .then(function (gd) {
// $(t0c0r0).html('c0r0Value');
// $(t0c1r1).html('c1r1Value');
// gadget = gd;
// return gadget.getContent();
// })
// .then(function (c) {
// content = c;
// return gadget.clearContent();
// })
// .then(function () {
// equal($(t0c0r0).text(),"");
// equal($(t2c1r1).text(),"");
// return gadget.setContent(content);
// })
// .then(function () {
// equal($(t2c0r0).text(),"c0r0Value");
// equal($(t2c1r1).text(),"c1r1Value");
// })
// .always(start);
// });
});
} (window, jQuery, QUnit, rJS));
......@@ -11,6 +11,7 @@
<script src="../src/lib/jquery.js"></script>
<script src="../src/lib/qunit/qunit.js"></script>
<script src="../src/lib/sinon/sinon.js"></script>
<script src="../src/lib/rsvp.js"></script>
<script src="../src/lib/jschannel.js"></script>
<script src="../src/lib/renderjs.js"></script>
<script src="bw-gadget-test.js"></script>
......@@ -20,6 +21,5 @@
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<div id="gadget" style="display:none;"></div>
</body>
</html>
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