gecko-dev/browser/metro/modules/ContentUtil.jsm

107 lines
3.3 KiB
JavaScript

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
this.EXPORTED_SYMBOLS = ["ContentUtil"];
const XHTML_NS = "http://www.w3.org/1999/xhtml";
const nsIDOMKeyEvent = Components.interfaces.nsIDOMKeyEvent;
this.ContentUtil = {
populateFragmentFromString: function populateFragmentFromString(fragment, str) {
let re = /^([^#]*)#(\d+)\b([^#]*)/,
document = fragment.ownerDocument,
// the remaining arguments are our {text, className} values
replacements = Array.slice(arguments, 2),
match;
// walk over the string, building textNode/spans as nec. with replacement content
// note that #1,#2 etc. may not appear in numerical order in the string
while ((match = re.exec(str))) {
let [mstring,pre,num,post] = match,
replaceText = "",
replaceClass,
idx = num-1; // markers are 1-based, replacement indices 0 based
str = str.substring(re.lastIndex+mstring.length);
if (pre)
fragment.appendChild(document.createTextNode(pre));
if (replacements[idx]) {
replaceText = replacements[idx].text;
let spanNode = document.createElementNS(XHTML_NS, "span");
spanNode.appendChild(document.createTextNode(replaceText));
// add class to the span when provided
if(replacements[idx].className)
spanNode.classList.add(replacements[idx].className);
fragment.appendChild(spanNode);
} else {
// put it back if no replacement was provided
fragment.appendChild(document.createTextNode("#"+num));
}
if(post)
fragment.appendChild(document.createTextNode(post));
}
if(str)
fragment.appendChild(document.createTextNode(str));
return fragment;
},
// Pass several objects in and it will combine them all into the first object and return it.
// NOTE: Deep copy is not supported
extend: function extend() {
// copy reference to target object
let target = arguments[0] || {};
let length = arguments.length;
if (length === 1) {
return target;
}
// Handle case when target is a string or something
if (typeof target != "object" && typeof target != "function") {
target = {};
}
for (let i = 1; i < length; i++) {
// Only deal with non-null/undefined values
let options = arguments[i];
if (options != null) {
// Extend the base object
for (let name in options) {
let copy = options[name];
// Prevent never-ending loop
if (target === copy)
continue;
if (copy !== undefined)
target[name] = copy;
}
}
}
// Return the modified object
return target;
},
// Checks if a keycode is used for list navigation.
isNavigationKey: function (keyCode) {
let navigationKeys = [
nsIDOMKeyEvent.DOM_VK_DOWN,
nsIDOMKeyEvent.DOM_VK_UP,
nsIDOMKeyEvent.DOM_VK_LEFT,
nsIDOMKeyEvent.DOM_VK_RIGHT,
nsIDOMKeyEvent.DOM_VK_PAGE_UP,
nsIDOMKeyEvent.DOM_VK_PAGE_DOWN,
nsIDOMKeyEvent.DOM_VK_ESCAPE];
return navigationKeys.indexOf(keyCode) != -1;
}
};