Skip to content

Commit

Permalink
Merge branch 'develop' of github.com:w3c/respec into develop
Browse files Browse the repository at this point in the history
* 'develop' of github.com:w3c/respec:
  Fix(SpecHelper): remove isPhantom() dead code
  Feat(utils): map/reduce linkCSS() instead of jQuery
  Fix (SpecHelper): reduce dependece on jQuery
  Fix(style): reduce ReSpec FOUC (relates to #326)
  • Loading branch information
marcoscaceres committed May 23, 2016
2 parents d355e53 + e8cb5da commit d746b45
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 88 deletions.
51 changes: 27 additions & 24 deletions js/core/style.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,35 @@

// Module core/style
// Inserts the CSS that ReSpec uses into the document.
//
// IMPORTANT NOTE
// The extraCSS configuration option is now deprecated. People rarely use it, and it
// does not work well with the growing restrictions that browsers impose on loading
// local content. You can still add your own styles: for that you will have to create
// a plugin that declares the css as a dependency and create a build of your new
// ReSpec profile. It's rather easy, really.
// To add you own styles, create a plugin that declares the css as a dependency
// and create a build of your new ReSpec profile.
//
// CONFIGURATION
// - noReSpecCSS: if you're using a profile that loads this module but you don't want
// the style, set this to true

"use strict";
define(
["text!core/css/respec2.css"],
function (css) {
return {
run: function (conf, doc, cb, msg) {
msg.pub("start", "core/style");
if (conf.extraCSS) {
msg.pub("warn", "The 'extraCSS' configuration property is now deprecated.");
}
if (!conf.noReSpecCSS) {
$("<style/>").appendTo($("head", $(doc)))
.text(css);
}
msg.pub("end", "core/style");
cb();
}
};
}
[
"text!core/css/respec2.css",
"core/utils",
],
function(css, utils) {
// Opportunistically inserts the style, with the chance to reduce some FOUC
var styleElement = document.createElement("style");
styleElement.id = "respec-mainstyle";
styleElement.textContent = css;
var swapStyleOwner = utils.makeOwnerSwapper(styleElement);
swapStyleOwner(document, document.head);
return {
run: function(conf, doc, cb) {
if (conf.noReSpecCSS) {
styleElement.remove();
} else if (styleElement.ownerDocument !== doc) {
swapStyleOwner(doc, doc.head);
}
cb();
},
};
}
);
18 changes: 14 additions & 4 deletions js/core/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -315,10 +315,20 @@ define(
// take a document and either a link or an array of links to CSS and appends a <link/> element
// to the head pointing to each
, linkCSS: function (doc, styles) {
if (!$.isArray(styles)) styles = [styles];
$.each(styles, function (i, css) {
$('head', doc).append($("<link/>").attr({ rel: 'stylesheet', href: css }));
});
if (!Array.isArray(styles)) {
styles = [styles];
}
styles
.map(function (url) {
var link = doc.createElement("link");
link.rel = "stylesheet";
link.href = url;
return link;
})
.reduce(function(elem, nextLink) {
elem.appendChild(nextLink);
return elem;
}, doc.head);
}

// --- TRANSFORMATIONS ------------------------------------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions tests/.jshintrc
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"shadow": false,
"sub": false,
"supernew": false,
"validthis": false,
"validthis": true,
"browser": true,
"browserify": false,
"couch": false,
Expand All @@ -63,7 +63,7 @@
"worker": false,
"wsh": false,
"yui": false,
"predef": [ "makeStandardOps", "makeDefaultBody", "makeRSDoc", "flushIframes", "isPhantom", "makeBasicConfig", "require", "pickRandomsFromList" ],
"predef": [ "makeStandardOps", "makeDefaultBody", "makeRSDoc", "flushIframes", "makeBasicConfig", "require", "pickRandomsFromList" ],
"globals": {
"expect": true
},
Expand Down
126 changes: 68 additions & 58 deletions tests/spec/SpecHelper.js
Original file line number Diff line number Diff line change
@@ -1,71 +1,85 @@
/*exported pickRandomsFromList, makeRSDoc, flushIframes,
makeStandardOps, makeDefaultBody, makeBasicConfig, isPhantom*/
makeStandardOps, makeDefaultBody, makeBasicConfig*/
"use strict";
var iframes = [];

function makeRSDoc(opts, cb, src, style) {
return new Promise(function(resove, reject) {
if (!src) {
src = "about:blank";
}
if (!style) {
style = "display: none";
}
var $ifr = $("<iframe src='" + src + "' style='" + style + "'></iframe>");
var ifr = document.createElement("iframe");
opts = opts || {};
$ifr.on("load", function() {
var destDoc = $ifr[0].contentDocument;
var body = destDoc.body;
var head = destDoc.head;
if (opts.htmlAttrs) {
$(destDoc.documentElement).attr(opts.htmlAttrs);
}
if (opts.title) {
destDoc.title = opts.title;
}
$(body).append(opts.abstract || $("<section id='abstract'><p>test abstract</p></section>"));
if (opts.body) {
$(body).append(opts.body);
}
var path = opts.jsPath || "../js/";
var config = destDoc.createElement("script");
$(config)
.text("var respecConfig = " + JSON.stringify(opts.config || {}) + ";")
.addClass("remove");
head.appendChild(config);
var loader = destDoc.createElement("script");
var loadAttr = {
src: "/node_modules/requirejs/require.js",
"data-main": path + (opts.profile || "profile-w3c-common")
};
$(loader)
.attr(loadAttr)
.addClass("remove");
head.appendChild(loader);
var handleAndVerify = function(doc) {
return function handler(ev) {
if (ev.data.topic === "end-all" && doc === ev.source.document) {
window.removeEventListener("message", handler);
cb(doc);
resove();
}
};
};
// intercept that in the iframe we have finished processing
window.addEventListener("message", handleAndVerify(destDoc));
});
// trigger load
$ifr.appendTo($("body"));
iframes.push($ifr);
setTimeout(function() {
// reject when DEFAULT_TIMEOUT_INTERVAL passes
var timeoutId = setTimeout(function() {
reject(new Error("Timed out waiting on " + src));
}, jasmine.DEFAULT_TIMEOUT_INTERVAL);
ifr.addEventListener("load", function () {
var doc = this.contentDocument;
decorateDocument(doc, opts);
window.addEventListener("message", function msgHandler(ev){
if (doc && doc === ev.source.document && ev.data.topic === "end-all") {
window.removeEventListener("message", msgHandler);
cb(doc);
resove();
clearTimeout(timeoutId);
}
});
});
ifr.style = (style) ? style : "display: none";
ifr.src = (src) ? src : "about:blank";
// trigger load
document.body.appendChild(ifr);
iframes.push(ifr);
});
}

function decorateDocument(doc, opts){
function intoAttributes(element, key){
element.setAttribute(key, this[key]);
return element;
}

function decorateHead(opts){
var path = opts.jsPath || "../js/";
var loader = this.ownerDocument.createElement("script");
var config = this.ownerDocument.createElement("script");
var configText = "var respecConfig = " + JSON.stringify(opts.config || {}) + ";";
config.classList.add("remove");
config.innerText = configText;
var loadAttr = {
src: "/node_modules/requirejs/require.js",
"data-main": path + (opts.profile || "profile-w3c-common")
};
Object
.keys(loadAttr)
.reduce(intoAttributes.bind(loadAttr), loader)
.classList.add("remove");
this.appendChild(config);
this.appendChild(loader);
}

function decorateBody(opts){
// We only need to use jQuery to polyfill ParentElement.append()
var body = (this.append) ? this : $(this);
body.append(opts.abstract || "<section id='abstract'><p>test abstract</p></section>");
if (opts.body) {
body.append(opts.body);
}
}

if (opts.htmlAttrs) {
Object
.keys(opts.htmlAttrs)
.reduce(intoAttributes.bind(opts.htmlAttrs), doc.documentElement);
}
if (opts.title) {
doc.title = opts.title;
}
decorateBody.call(doc.body, opts);
decorateHead.call(doc.head, opts);
}

function flushIframes() {
while (iframes.length) {
// Poping them from the list prevents memory leaks.
// Popping them from the list prevents memory leaks.
iframes.pop().remove();
}
}
Expand Down Expand Up @@ -98,10 +112,6 @@ function pickRandomsFromList(list, howMany) {
}, []);
}

function isPhantom() {
return window.callPhantom || window._phantom;
}

function makeBasicConfig() {
return {
editors: [{
Expand Down

0 comments on commit d746b45

Please sign in to comment.