135 lines
3.7 KiB
JavaScript
135 lines
3.7 KiB
JavaScript
// @ts-check
|
|
// Module dini/style
|
|
// Inserts a link to the appropriate W3C style for the specification's maturity level.
|
|
// CONFIGURATION
|
|
// - specStatus: the short code for the specification's maturity level or type (required)
|
|
|
|
import {
|
|
createResourceHint,
|
|
linkCSS,
|
|
showWarning,
|
|
toKeyValuePairs,
|
|
} from "../core/utils.js";
|
|
import { sub } from "../core/pubsubhub.js";
|
|
export const name = "dini/style";
|
|
function attachFixupScript(doc, version) {
|
|
const script = doc.createElement("script");
|
|
if (location.hash) {
|
|
script.addEventListener(
|
|
"load",
|
|
() => {
|
|
window.location.href = location.hash;
|
|
},
|
|
{ once: true }
|
|
);
|
|
}
|
|
script.src = `https://www.w3.org/scripts/TR/${version}/fixup.js`;
|
|
doc.body.appendChild(script);
|
|
}
|
|
|
|
/**
|
|
* Make a best effort to attach meta viewport at the top of the head.
|
|
* Other plugins might subsequently push it down, but at least we start
|
|
* at the right place. When ReSpec exports the HTML, it again moves the
|
|
* meta viewport to the top of the head - so to make sure it's the first
|
|
* thing the browser sees. See js/ui/save-html.js.
|
|
*/
|
|
function createMetaViewport() {
|
|
const meta = document.createElement("meta");
|
|
meta.name = "viewport";
|
|
const contentProps = {
|
|
width: "device-width",
|
|
"initial-scale": "1",
|
|
"shrink-to-fit": "no",
|
|
};
|
|
meta.content = toKeyValuePairs(contentProps).replace(/"/g, "");
|
|
return meta;
|
|
}
|
|
|
|
function createBaseStyle() {
|
|
const link = document.createElement("link");
|
|
link.rel = "stylesheet";
|
|
link.href = "https://www.w3.org/StyleSheets/TR/2016/base.css";
|
|
link.classList.add("removeOnSave");
|
|
return link;
|
|
}
|
|
|
|
function createResourceHints() {
|
|
/** @type ResourceHintOption[] */
|
|
const opts = [
|
|
{
|
|
hint: "preconnect", // for W3C styles and scripts.
|
|
href: "https://www.w3.org",
|
|
},
|
|
{
|
|
hint: "preload", // all specs need it, and we attach it on end-all.
|
|
href: "https://www.w3.org/scripts/TR/2016/fixup.js",
|
|
as: "script",
|
|
},
|
|
{
|
|
hint: "preload", // all specs include on base.css.
|
|
href: "https://www.w3.org/StyleSheets/TR/2016/base.css",
|
|
as: "style",
|
|
},
|
|
];
|
|
const resourceHints = document.createDocumentFragment();
|
|
for (const link of opts.map(createResourceHint)) {
|
|
resourceHints.appendChild(link);
|
|
}
|
|
return resourceHints;
|
|
}
|
|
// Collect elements for insertion (document fragment)
|
|
const elements = createResourceHints();
|
|
|
|
// Opportunistically apply base style
|
|
elements.appendChild(createBaseStyle());
|
|
if (!document.head.querySelector("meta[name=viewport]")) {
|
|
// Make meta viewport the first element in the head.
|
|
elements.prepend(createMetaViewport());
|
|
}
|
|
|
|
document.head.prepend(elements);
|
|
|
|
function styleMover(linkURL) {
|
|
return exportDoc => {
|
|
const w3cStyle = exportDoc.querySelector(`head link[href="${linkURL}"]`);
|
|
exportDoc.querySelector("head").append(w3cStyle);
|
|
};
|
|
}
|
|
|
|
export function run(conf) {
|
|
if (!conf.specStatus) {
|
|
const msg = "`respecConfig.specStatus` missing. Defaulting to 'base'.";
|
|
conf.specStatus = "base";
|
|
showWarning(msg, name);
|
|
}
|
|
|
|
let styleFile = "";
|
|
|
|
// Figure out which style file to use.
|
|
switch (conf.specStatus.toUpperCase()) {
|
|
case "UNOFFICIAL":
|
|
styleFile = "W3C-UD";
|
|
break;
|
|
case "BASE":
|
|
styleFile = "base.css";
|
|
break;
|
|
}
|
|
|
|
// Attach W3C fixup script after we are done.
|
|
if (!conf.noToc) {
|
|
sub(
|
|
"end-all",
|
|
() => {
|
|
attachFixupScript(document, "2016");
|
|
},
|
|
{ once: true }
|
|
);
|
|
}
|
|
const finalStyleURL = `https://www.w3.org/StyleSheets/TR/2016/${styleFile}`;
|
|
linkCSS(document, finalStyleURL);
|
|
// Make sure the W3C stylesheet is the last stylesheet, as required by W3C Pub Rules.
|
|
const moveStyle = styleMover(finalStyleURL);
|
|
sub("beforesave", moveStyle);
|
|
}
|