diff options
| author | HumairAK <humair88@hotmail.com> | 2016-07-26 07:43:08 +0000 |
|---|---|---|
| committer | HumairAK <humair88@hotmail.com> | 2016-07-26 07:43:08 +0000 |
| commit | 3983edb2518acd91f991ad5fc6308bcaf46700f5 (patch) | |
| tree | a81da7c47c8f9d0b853d478c619baadcf35d8237 /node_modules/jsdom/lib | |
| parent | f016bdbc35b7efa44bd63413bde09433ea916c59 (diff) | |
| parent | a345cf13d3b952ef0d427b61475f5cf722b3cbb0 (diff) | |
Merge branch 'master' of https://github.com/HumairAK/solutions_repo
Diffstat (limited to 'node_modules/jsdom/lib')
35 files changed, 0 insertions, 9999 deletions
diff --git a/node_modules/jsdom/lib/README.md b/node_modules/jsdom/lib/README.md deleted file mode 100644 index 8f0856c..0000000 --- a/node_modules/jsdom/lib/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Note: this codebase is in a transitional state - -We're slowly moving from a historical model based on layered "levels" of specs, to the [living standard model](https://wiki.whatwg.org/wiki/FAQ#What_does_.22Living_Standard.22_mean.3F) actually implemented by browsers. As such, the code is kind of a mess. - -**Summary**: new features go in `lib/jsdom/living` and follow the code style there; modifications to existing features will require some spelunking to find out what to modify in-place. - ---- - -A lot of the main implementation is in `lib/jsdom/level1` and `lib/jsdom/level2`. (That includes things that didn't appear in the original DOM Level 1 and Level 2 specs, just because the code was located there and we had to patch it.) We're trying to avoid adding new code there, but patching old code is often still required. - -New features generally go in the `lib/jsdom/living` folder, in nice small files, with a clear coding style enforced by JSHint. - -We're planning to fix this whole situation with a multi-stage process: - -- First, consolidate any leftovers in `lib/jsdom/browser` and `lib/jsdom/level3`, as well as the more substantial body of code in `lib/jsdom/level2`, into `lib/jsdom/level1`. This will contain the "historical" portion of the jsdom codebase. -- Then, embark on a major cleanup and refactoring effort, splitting out small pieces from `lib/jsdom/level1` and into `lib/jsdom/living`, cleaning up the code style and spec compliance as we go. -- Finally, collapse the silly directory hierarchy into something less nested. diff --git a/node_modules/jsdom/lib/jsdom.js b/node_modules/jsdom/lib/jsdom.js deleted file mode 100644 index e801634..0000000 --- a/node_modules/jsdom/lib/jsdom.js +++ /dev/null @@ -1,379 +0,0 @@ -var fs = require('fs'); -var path = require('path'); -var URL = require('url'); - -var toFileUrl = require('./jsdom/utils').toFileUrl; -var defineGetter = require('./jsdom/utils').defineGetter; -var defineSetter = require('./jsdom/utils').defineSetter; -var features = require('./jsdom/browser/documentfeatures'); -var dom = require('./jsdom/living'); -var browserAugmentation = require('./jsdom/browser/index').browserAugmentation; -var domToHtml = require('./jsdom/browser/domtohtml').domToHtml; -var VirtualConsole = require('./jsdom/virtual-console'); - -var canReadFilesFromFS = !!fs.readFile; // in a browserify environment, this isn't present - -var request = function() { // lazy loading request - request = require('request'); - return request.apply(undefined, arguments); -} - -exports.getVirtualConsole = function (window) { - return window._virtualConsole; -}; -exports.debugMode = false; - -// Proxy feature functions to features module. -['availableDocumentFeatures', - 'defaultDocumentFeatures', - 'applyDocumentFeatures'].forEach(function (propName) { - defineGetter(exports, propName, function () { - return features[propName]; - }); - defineSetter(exports, propName, function (val) { - return features[propName] = val; - }); -}); - -exports.jsdom = function (html, options) { - if (options === undefined) { - options = {}; - } - if (options.parsingMode === undefined || options.parsingMode === 'auto') { - options.parsingMode = 'html'; - } - - var browser = browserAugmentation(dom, options); - var doc = new browser.HTMLDocument(options); - - if (options.created) { - options.created(null, doc.parentWindow); - } - - features.applyDocumentFeatures(doc, options.features); - - if (html === undefined) { - html = ''; - } - html = String(html); - doc.write(html); - - if (doc.close && !options.deferClose) { - doc.close(); - } - - return doc; -}; - -exports.jQueryify = exports.jsdom.jQueryify = function (window, jqueryUrl, callback) { - if (!window || !window.document) { - return; - } - - var features = window.document.implementation._features; - window.document.implementation._addFeature('FetchExternalResources', ['script']); - window.document.implementation._addFeature('ProcessExternalResources', ['script']); - window.document.implementation._addFeature('MutationEvents', ['2.0']); - - var scriptEl = window.document.createElement('script'); - scriptEl.className = 'jsdom'; - scriptEl.src = jqueryUrl; - scriptEl.onload = scriptEl.onerror = function () { - window.document.implementation._features = features; - - if (callback) { - callback(window, window.jQuery); - } - }; - - window.document.body.appendChild(scriptEl); -}; - -exports.env = exports.jsdom.env = function () { - var config = getConfigFromArguments(arguments); - - if (config.file && canReadFilesFromFS) { - fs.readFile(config.file, 'utf-8', function (err, text) { - if (err) { - if (config.created) { - config.created(err); - } - if (config.done) { - config.done([err]); - } - return; - } - - setParsingModeFromExtension(config, config.file); - - config.html = text; - processHTML(config); - }); - } else if (config.html !== undefined) { - processHTML(config); - } else if (config.url) { - handleUrl(config); - } else if (config.somethingToAutodetect !== undefined) { - var url = URL.parse(config.somethingToAutodetect); - if (url.protocol && url.hostname) { - config.url = config.somethingToAutodetect; - handleUrl(config.somethingToAutodetect); - } else if (canReadFilesFromFS) { - fs.readFile(config.somethingToAutodetect, 'utf-8', function (err, text) { - if (err) { - // the toString() test is because in Node.js, there is no proper code for this. - // This is fixed in io.js: https://github.com/iojs/io.js/issues/517 so: - // TODO: remove when we start requiring io.js - if (err.code === 'ENOENT' || err.code === 'ENAMETOOLONG' - || (err.toString() == 'Error: Path must be a string without null bytes.') - ) { - config.html = config.somethingToAutodetect; - processHTML(config); - } else { - if (config.created) { - config.created(err); - } - if (config.done) { - config.done([err]); - } - } - } else { - setParsingModeFromExtension(config, config.somethingToAutodetect); - - config.html = text; - config.url = toFileUrl(config.somethingToAutodetect); - processHTML(config); - } - }); - } else { - config.html = config.somethingToAutodetect; - processHTML(config); - } - } - - function handleUrl() { - var options = { - uri: config.url, - encoding: config.encoding || 'utf8', - headers: config.headers || {}, - proxy: config.proxy || null, - jar: config.jar !== undefined ? config.jar : true - }; - - request(options, function (err, res, responseText) { - if (err) { - if (config.created) { - config.created(err); - } - if (config.done) { - config.done([err]); - } - return; - } - - // The use of `res.request.uri.href` ensures that `window.location.href` - // is updated when `request` follows redirects. - config.html = responseText; - config.url = res.request.uri.href; - - if (config.parsingMode === "auto" && ( - res.headers["content-type"] === "application/xml" || - res.headers["content-type"] === "text/xml" || - res.headers["content-type"] === "application/xhtml+xml")) { - config.parsingMode = "xml"; - } - - processHTML(config); - }); - } -}; - -exports.serializeDocument = function (doc) { - return domToHtml(doc, true); -}; - -function processHTML(config) { - var options = { - features: config.features, - url: config.url, - parser: config.parser, - parsingMode: config.parsingMode, - created: config.created, - resourceLoader: config.resourceLoader - }; - - if (config.document) { - options.referrer = config.document.referrer; - options.cookie = config.document.cookie; - options.cookieDomain = config.document.cookieDomain; - } - - var window = exports.jsdom(config.html, options).parentWindow; - var features = JSON.parse(JSON.stringify(window.document.implementation._features)); - - var docsLoaded = 0; - var totalDocs = config.scripts.length + config.src.length; - var readyState = null; - var errors = []; - - if (!window || !window.document) { - if (config.created) { - config.created(new Error('JSDOM: a window object could not be created.')); - } - if (config.done) { - config.done([new Error('JSDOM: a window object could not be created.')]); - } - return; - } - - window.document.implementation._addFeature('FetchExternalResources', ['script']); - window.document.implementation._addFeature('ProcessExternalResources', ['script']); - window.document.implementation._addFeature('MutationEvents', ['2.0']); - - function scriptComplete() { - docsLoaded++; - - if (docsLoaded >= totalDocs) { - window.document.implementation._features = features; - - errors = errors.concat(window.document.errors || []); - if (errors.length === 0) { - errors = null; - } - - process.nextTick(function() { - if (config.loaded) { - config.loaded(errors, window); - } - if (config.done) { - config.done(errors, window); - } - }); - } - } - - function handleScriptError(e) { - if (!errors) { - errors = []; - } - errors.push(e.error || e.message); - - // nextTick so that an exception within scriptComplete won't cause - // another script onerror (which would be an infinite loop) - process.nextTick(scriptComplete); - } - - if (config.scripts.length > 0 || config.src.length > 0) { - config.scripts.forEach(function (scriptSrc) { - var script = window.document.createElement('script'); - script.className = 'jsdom'; - script.onload = scriptComplete; - script.onerror = handleScriptError; - script.src = scriptSrc; - - try { - // protect against invalid dom - // ex: http://www.google.com/foo#bar - window.document.documentElement.appendChild(script); - } catch (e) { - handleScriptError(e); - } - }); - - config.src.forEach(function (scriptText) { - var script = window.document.createElement('script'); - script.onload = scriptComplete; - script.onerror = handleScriptError; - script.text = scriptText; - - window.document.documentElement.appendChild(script); - window.document.documentElement.removeChild(script); - }); - } else { - if (window.document.readyState === 'complete') { - scriptComplete(); - } else { - window.addEventListener('load', function() { - scriptComplete(); - }); - } - } -} - -function getConfigFromArguments(args, callback) { - var config = {}; - if (typeof args[0] === 'object') { - var configToClone = args[0]; - Object.keys(configToClone).forEach(function (key) { - config[key] = configToClone[key]; - }); - } else { - var stringToAutodetect = null; - - Array.prototype.forEach.call(args, function (arg) { - switch (typeof arg) { - case 'string': - config.somethingToAutodetect = arg; - break; - case 'function': - config.done = arg; - break; - case 'object': - if (Array.isArray(arg)) { - config.scripts = arg; - } else { - extend(config, arg); - } - break; - } - }); - } - - if (!config.done && !config.created && !config.loaded) { - throw new Error('Must pass a "created", "loaded", "done" option or a callback to jsdom.env.'); - } - - if (config.somethingToAutodetect === undefined && - config.html === undefined && !config.file && !config.url) { - throw new Error('Must pass a "html", "file", or "url" option, or a string, to jsdom.env'); - } - - config.scripts = ensureArray(config.scripts); - config.src = ensureArray(config.src); - config.parsingMode = config.parsingMode || "auto"; - - config.features = config.features || { - FetchExternalResources: false, - ProcessExternalResources: false, - SkipExternalResources: false - }; - - if (!config.url && config.file) { - config.url = toFileUrl(config.file); - } - - return config; -} - -function ensureArray(value) { - var array = value || []; - if (typeof array === 'string') { - array = [array]; - } - return array; -} - -function extend(config, overrides) { - Object.keys(overrides).forEach(function (key) { - config[key] = overrides[key]; - }); -} - -function setParsingModeFromExtension(config, filename) { - if (config.parsingMode === "auto") { - var ext = path.extname(filename); - if (ext === ".xhtml" || ext === ".xml") { - config.parsingMode = "xml"; - } - } -} diff --git a/node_modules/jsdom/lib/jsdom/browser/Window.js b/node_modules/jsdom/lib/jsdom/browser/Window.js deleted file mode 100644 index 1cee5cb..0000000 --- a/node_modules/jsdom/lib/jsdom/browser/Window.js +++ /dev/null @@ -1,291 +0,0 @@ -"use strict"; - -var URL = require("url"); -var CSSStyleDeclaration = require("cssstyle").CSSStyleDeclaration; -var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest; -var dom = require("../level1/core"); -var NOT_IMPLEMENTED = require("./utils").NOT_IMPLEMENTED; -var createFrom = require("../utils").createFrom; -var History = require("./history"); -var VirtualConsole = require("../virtual-console"); - -var cssSelectorSplitRE = /((?:[^,"']|"[^"]*"|'[^']*')+)/; - -function matchesDontThrow(el, selector) { - try { - return el.matches(selector); - } catch (e) { - return false; - } -} - -function startTimer(window, startFn, stopFn, callback, ms) { - var res = startFn(callback, ms); - window.__timers.push([res, stopFn]); - return res; -} - -function stopTimer(window, id) { - if (typeof id === "undefined") { - return; - } - for (var i in window.__timers) { - if (window.__timers[i][0] === id) { - window.__timers[i][1].call(window, id); - window.__timers.splice(i, 1); - break; - } - } -} - -function stopAllTimers(window) { - window.__timers.forEach(function (t) { - t[1].call(window, t[0]); - }); - window.__timers = []; -} - -function Window(document) { - this.__timers = []; - - // TODO: very little of this belongs on the instance; they should be prototype methods instead. - - var window = this; - this._document = document; - this.history = new History(this); - - this.addEventListener = function () { - dom.Node.prototype.addEventListener.apply(window, arguments); - }; - this.removeEventListener = function () { - dom.Node.prototype.removeEventListener.apply(window, arguments); - }; - this.dispatchEvent = function () { - dom.Node.prototype.dispatchEvent.apply(window, arguments); - }; - this.raise = function () { - dom.Node.prototype.raise.apply(window.document, arguments); - }; - - this.setTimeout = function (fn, ms) { return startTimer(window, setTimeout, clearTimeout, fn, ms); }; - this.setInterval = function (fn, ms) { return startTimer(window, setInterval, clearInterval, fn, ms); }; - this.clearInterval = stopTimer.bind(this, window); - this.clearTimeout = stopTimer.bind(this, window); - this.__stopAllTimers = stopAllTimers.bind(this, window); - this.Image = function (width, height) { - var element = window._document.createElement("img"); - element.width = width; - element.height = height; - return element; - }; - - this._virtualConsole = new VirtualConsole(); - - function wrapConsoleMethod(method) { - return function () { - var args = Array.prototype.slice.call(arguments); - window._virtualConsole.emit.apply(window._virtualConsole, [method].concat(args)); - }; - } - - this.console = { - assert: wrapConsoleMethod("assert"), - clear: wrapConsoleMethod("clear"), - count: wrapConsoleMethod("count"), - debug: wrapConsoleMethod("debug"), - error: wrapConsoleMethod("error"), - group: wrapConsoleMethod("group"), - groupCollapse: wrapConsoleMethod("groupCollapse"), - groupEnd: wrapConsoleMethod("groupEnd"), - info: wrapConsoleMethod("info"), - log: wrapConsoleMethod("log"), - table: wrapConsoleMethod("table"), - time: wrapConsoleMethod("time"), - timeEnd: wrapConsoleMethod("timeEnd"), - trace: wrapConsoleMethod("trace"), - warn: wrapConsoleMethod("warn") - }; - - this.XMLHttpRequest = function () { - var xhr = new XMLHttpRequest(); - var lastUrl = ""; - xhr._open = xhr.open; - xhr.open = function (method, url, async, user, password) { - url = URL.resolve(window.document.URL, url); - lastUrl = url; - return xhr._open(method, url, async, user, password); - }; - xhr._send = xhr.send; - xhr.send = function (data) { - if (window.document.cookie) { - var cookieDomain = window.document._cookieDomain; - var url = URL.parse(lastUrl); - var host = url.host.split(":")[0]; - if (host.indexOf(cookieDomain, host.length - cookieDomain.length) !== -1) { - xhr.setDisableHeaderCheck(true); - xhr.setRequestHeader("cookie", window.document.cookie); - xhr.setDisableHeaderCheck(false); - } - } - return xhr._send(data); - }; - return xhr; - }; -} - -Window.prototype = createFrom(dom || null, { - constructor: Window, - // This implements window.frames.length, since window.frames returns a - // self reference to the window object. This value is incremented in the - // HTMLFrameElement init function (see: level2/html.js). - _length: 0, - get length() { - return this._length; - }, - get document() { - return this._document; - }, - get location() { - return this._document._location; - }, - close: function () { - // Recursively close child frame windows, then ourselves. - var currentWindow = this; - (function windowCleaner(window) { - var i; - // We could call window.frames.length etc, but window.frames just points - // back to window. - if (window.length > 0) { - for (i = 0; i < window.length; i++) { - windowCleaner(window[i]); - } - } - // We"re already in our own window.close(). - if (window !== currentWindow) { - window.close(); - } - })(this); - - if (this._document) { - if (this._document.body) { - this._document.body.innerHTML = ""; - } - - if (this._document.close) { - // We need to empty out the event listener array because - // document.close() causes "load" event to re-fire. - this._document._listeners = []; - this._document.close(); - } - delete this._document; - } - - stopAllTimers(currentWindow); - // Clean up the window"s execution context. - // dispose() is added by Contextify. - this.dispose(); - }, - getComputedStyle: function (node) { - var s = node.style, - cs = new CSSStyleDeclaration(), - forEach = Array.prototype.forEach; - - function setPropertiesFromRule(rule) { - if (!rule.selectorText) { - return; - } - - var selectors = rule.selectorText.split(cssSelectorSplitRE); - var matched = false; - selectors.forEach(function (selectorText) { - if (selectorText !== "" && selectorText !== "," && !matched && matchesDontThrow(node, selectorText)) { - matched = true; - forEach.call(rule.style, function (property) { - cs.setProperty(property, rule.style.getPropertyValue(property), rule.style.getPropertyPriority(property)); - }); - } - }); - } - - forEach.call(node.ownerDocument.styleSheets, function (sheet) { - forEach.call(sheet.cssRules, function (rule) { - if (rule.media) { - if (Array.prototype.indexOf.call(rule.media, "screen") !== -1) { - forEach.call(rule.cssRules, setPropertiesFromRule); - } - } else { - setPropertiesFromRule(rule); - } - }); - }); - - forEach.call(s, function (property) { - cs.setProperty(property, s.getPropertyValue(property), s.getPropertyPriority(property)); - }); - - return cs; - }, - - // TODO: all of the below data properties should be getters; right now they are shared between Window instances - // which is of course bad. - navigator: { - get userAgent() { return "Node.js (" + process.platform + "; U; rv:" + process.version + ")"; }, - get appName() { return "Node.js jsDom"; }, - get platform() { return process.platform; }, - get appVersion() { return process.version; }, - noUI: true, - get cookieEnabled() { return true; } - }, - - name: "nodejs", - innerWidth: 1024, - innerHeight: 768, - outerWidth: 1024, - outerHeight: 768, - pageXOffset: 0, - pageYOffset: 0, - screenX: 0, - screenY: 0, - screenLeft: 0, - screenTop: 0, - scrollX: 0, - scrollY: 0, - scrollTop: 0, - scrollLeft: 0, - alert: NOT_IMPLEMENTED("window.alert"), - blur: NOT_IMPLEMENTED("window.blur"), - confirm: NOT_IMPLEMENTED("window.confirm"), - createPopup: NOT_IMPLEMENTED("window.createPopup"), - focus: NOT_IMPLEMENTED("window.focus"), - moveBy: NOT_IMPLEMENTED("window.moveBy"), - moveTo: NOT_IMPLEMENTED("window.moveTo"), - open: NOT_IMPLEMENTED("window.open"), - print: NOT_IMPLEMENTED("window.print"), - prompt: NOT_IMPLEMENTED("window.prompt"), - resizeBy: NOT_IMPLEMENTED("window.resizeBy"), - resizeTo: NOT_IMPLEMENTED("window.resizeTo"), - scroll: NOT_IMPLEMENTED("window.scroll"), - scrollBy: NOT_IMPLEMENTED("window.scrollBy"), - scrollTo: NOT_IMPLEMENTED("window.scrollTo"), - screen: { - width: 0, - height: 0 - }, - - // Note: these will not be necessary for newer Node.js versions, which have - // typed arrays in V8 and thus on every global object. (That is, in newer - // versions we"ll get `ArrayBuffer` just as automatically as we get - // `Array`.) But to support older versions, we explicitly set them here. - Int8Array: global.Int8Array, - Int16Array: global.Int16Array, - Int32Array: global.Int32Array, - Float32Array: global.Float32Array, - Float64Array: global.Float64Array, - Uint8Array: global.Uint8Array, - Uint8ClampedArray: global.Uint8ClampedArray, - Uint16Array: global.Uint16Array, - Uint32Array: global.Uint32Array, - ArrayBuffer: global.ArrayBuffer -}); - -module.exports = Window; diff --git a/node_modules/jsdom/lib/jsdom/browser/documentAdapter.js b/node_modules/jsdom/lib/jsdom/browser/documentAdapter.js deleted file mode 100644 index 7d66168..0000000 --- a/node_modules/jsdom/lib/jsdom/browser/documentAdapter.js +++ /dev/null @@ -1,62 +0,0 @@ -//Tree traversing -exports.getFirstChild = function (node) { - return node.childNodes[0]; -}; - -exports.getChildNodes = function (node) { - return node.childNodes; -}; - -exports.getParentNode = function (node) { - return node.parentNode; -}; - -exports.getAttrList = function (node) { - return node.attributes; -}; - -//Node data -exports.getTagName = function (element) { - return element.tagName.toLowerCase(); -}; - -exports.getNamespaceURI = function (element) { - return element.namespaceURI || 'http://www.w3.org/1999/xhtml'; -}; - -exports.getTextNodeContent = function (textNode) { - return textNode.nodeValue; -}; - -exports.getCommentNodeContent = function (commentNode) { - return commentNode.nodeValue; -}; - -exports.getDocumentTypeNodeName = function (doctypeNode) { - return doctypeNode.name; -}; - -exports.getDocumentTypeNodePublicId = function (doctypeNode) { - return doctypeNode.publicId || null; -}; - -exports.getDocumentTypeNodeSystemId = function (doctypeNode) { - return doctypeNode.systemId || null; -}; - -//Node types -exports.isTextNode = function (node) { - return node.nodeName === '#text'; -}; - -exports.isCommentNode = function (node) { - return node.nodeName === '#comment'; -}; - -exports.isDocumentTypeNode = function (node) { - return node.nodeType === 10; -}; - -exports.isElementNode = function (node) { - return !!node.tagName; -}; diff --git a/node_modules/jsdom/lib/jsdom/browser/documentfeatures.js b/node_modules/jsdom/lib/jsdom/browser/documentfeatures.js deleted file mode 100644 index 2e562cb..0000000 --- a/node_modules/jsdom/lib/jsdom/browser/documentfeatures.js +++ /dev/null @@ -1,52 +0,0 @@ -exports.availableDocumentFeatures = [ - 'FetchExternalResources', - 'ProcessExternalResources', - 'MutationEvents', - 'SkipExternalResources' -]; - -exports.defaultDocumentFeatures = { - "FetchExternalResources": ['script', 'link'/*, 'img', 'css', 'frame'*/], - "ProcessExternalResources": ['script'/*, 'frame', 'iframe'*/], - "MutationEvents": '2.0', - "SkipExternalResources": false -}; - -exports.applyDocumentFeatures = function(doc, features) { - var i, maxFeatures = exports.availableDocumentFeatures.length, - defaultFeatures = exports.defaultDocumentFeatures, - j, - k, - featureName, - featureSource; - - features = features || {}; - - for (i=0; i<maxFeatures; i++) { - featureName = exports.availableDocumentFeatures[i]; - if (typeof features[featureName] !== 'undefined') { - featureSource = features[featureName]; - // We have to check the lowercase version also because the Document feature - // methods convert everything to lowercase. - } else if (typeof features[featureName.toLowerCase()] !== 'undefined') { - featureSource = features[featureName.toLowerCase()]; - } else if (defaultFeatures[featureName]) { - featureSource = defaultFeatures[featureName]; - } else { - continue; - } - - doc.implementation._removeFeature(featureName); - - if (typeof featureSource !== 'undefined') { - if (featureSource instanceof Array) { - k = featureSource.length; - for (j=0; j<k; j++) { - doc.implementation._addFeature(featureName, featureSource[j]); - } - } else { - doc.implementation._addFeature(featureName, featureSource); - } - } - } -}; diff --git a/node_modules/jsdom/lib/jsdom/browser/domtohtml.js b/node_modules/jsdom/lib/jsdom/browser/domtohtml.js deleted file mode 100644 index 0c256c4..0000000 --- a/node_modules/jsdom/lib/jsdom/browser/domtohtml.js +++ /dev/null @@ -1,24 +0,0 @@ -"use strict"; - -var parse5 = require('parse5'); -var serializer = new parse5.TreeSerializer(require('./documentAdapter')); - -exports.domToHtml = function(dom) { - if (dom._toArray) { - // node list - dom = dom._toArray(); - } - if (typeof dom.length !== "undefined") { - var ret = ""; - for (var i = 0, len = dom.length; i < len; i++) { - ret += dom[i].nodeType === dom.DOCUMENT_NODE ? - serializer.serialize(dom[i]) : - serializer.serialize({ childNodes: [dom[i]] }); - } - return ret; - } else { - return dom.nodeType === dom.DOCUMENT_NODE ? - serializer.serialize(dom) : - serializer.serialize({ childNodes: [dom] }); - } -}; diff --git a/node_modules/jsdom/lib/jsdom/browser/history.js b/node_modules/jsdom/lib/jsdom/browser/history.js deleted file mode 100644 index 674b4ad..0000000 --- a/node_modules/jsdom/lib/jsdom/browser/history.js +++ /dev/null @@ -1,94 +0,0 @@ -"use strict"; -var URL = require("url"); -var resolveHref = require("../utils").resolveHref; - -function StateEntry(data, title, url) { - this.data = data; - this.title = title; - this.url = url; -} - -module.exports = History; - -function History(window) { - this._states = [new StateEntry(null, "", window.location._url.href)]; - this._index = 0; - this._window = window; - this._location = window.location; -} - -History.prototype = { - constructor: History, - - get length() { - return this._states.length; - }, - - get state() { - var state = this._states[this._index]; - return state ? state.data : null; - }, - - back: function () { - this.go(-1); - }, - - forward: function () { - this.go(1); - }, - - go: function (delta) { - if (typeof delta === "undefined" || delta === 0) { - this._location.reload(); - return; - } - - var newIndex = this._index + delta; - - if (newIndex < 0 || newIndex >= this.length) { - return; - } - - this._index = newIndex; - - var state = this._states[newIndex]; - - this._applyState(state); - this._signalPopstate(state); - }, - - pushState: function (data, title, url) { - var state = new StateEntry(data, title, url); - if (this._index + 1 !== this._states.length) { - this._states = this._states.slice(0, this._index + 1); - } - this._states.push(state); - this._applyState(state); - this._index++; - }, - - replaceState: function (data, title, url) { - var state = new StateEntry(data, title, url); - this._states[this._index] = state; - this._applyState(state); - }, - - _applyState: function (state) { - this._location._url = URL.parse(resolveHref(this._location._url.href, state.url)); - }, - - _signalPopstate: function(state) { - if (this._window.document) { - var ev = this._window.document.createEvent("HTMLEvents"); - ev.initEvent("popstate", false, false); - ev.state = state.data; - process.nextTick(function () { - this._window.dispatchEvent(ev); - }.bind(this)); - } - }, - - toString: function () { - return "[object History]"; - } -}; diff --git a/node_modules/jsdom/lib/jsdom/browser/htmltodom.js b/node_modules/jsdom/lib/jsdom/browser/htmltodom.js deleted file mode 100644 index 88908dc..0000000 --- a/node_modules/jsdom/lib/jsdom/browser/htmltodom.js +++ /dev/null @@ -1,231 +0,0 @@ -var parse5 = require('parse5'); -var htmlparser2 = require('htmlparser2'); - -function HtmlToDom(parser, parsingMode) { - if (!parser) { - if (parsingMode === "xml") { - parser = htmlparser2; - } else { - parser = parse5; - } - } - - if (parser.DefaultHandler || (parser.Parser && parser.TreeAdapters)) { - - // Forgiving HTML parser - - if (parser.DefaultHandler){ - // fb55/htmlparser2 - - parser.ParseHtml = function(rawHtml) { - var handler = new parser.DefaultHandler(); - // Check if document is XML - var isXML = parsingMode === "xml"; - var parserInstance = new parser.Parser(handler, { - xmlMode: isXML, - lowerCaseTags: !isXML, - lowerCaseAttributeNames: !isXML, - decodeEntities: true - }); - - parserInstance.includeLocation = false; - parserInstance.parseComplete(rawHtml); - return handler.dom; - }; - } else if (parser.Parser && parser.TreeAdapters) { - parser.ParseHtml = function (rawHtml) { - if (parsingMode === 'xml') { - throw new Error('Can\'t parse XML with parse5, please use htmlparser2 instead.'); - } - var instance = new parser.Parser(parser.TreeAdapters.htmlparser2); - var dom = instance.parse(rawHtml); - return dom.children; - }; - } - - this.appendHtmlToElement = function(html, element) { - - if (typeof html !== 'string') { - html +=''; - } - - var parsed = parser.ParseHtml(html); - - for (var i = 0; i < parsed.length; i++) { - setChild(element, parsed[i]); - } - - return element; - }; - this.appendHtmlToDocument = this.appendHtmlToElement; - - if (parser.Parser && parser.TreeAdapters) { - this.appendHtmlToElement = function (html, element) { - - if (typeof html !== 'string') { - html += ''; - } - - var instance = new parser.Parser(parser.TreeAdapters.htmlparser2); - var parentElement = parser.TreeAdapters.htmlparser2.createElement(element.tagName.toLowerCase(), element.namespaceURI, []); - var dom = instance.parseFragment(html, parentElement); - var parsed = dom.children; - - for (var i = 0; i < parsed.length; i++) { - setChild(element, parsed[i]); - } - - return element; - }; - } - - } else if (parser.moduleName == 'HTML5') { /* HTML5 parser */ - this.appendHtmlToElement = function(html, element) { - - if (typeof html !== 'string') { - html += ''; - } - if (html.length > 0) { - if (element.nodeType == 9) { - new parser.Parser({document: element}).parse(html); - } - else { - var p = new parser.Parser({document: element.ownerDocument}); - p.parse_fragment(html, element); - } - } - }; - } else { - this.appendHtmlToElement = function () { - console.log(''); - console.log('###########################################################'); - console.log('# WARNING: No compatible HTML parser was given.'); - console.log('# Element.innerHTML setter support has been disabled'); - console.log('# Element.innerHTML getter support will still function'); - console.log('###########################################################'); - console.log(''); - }; - } -}; - -// utility function for forgiving parser -function setChild(parent, node) { - - var c, newNode, currentDocument = parent._ownerDocument || parent; - - switch (node.type) - { - case 'tag': - case 'script': - case 'style': - try { - newNode = currentDocument._createElementNoTagNameValidation(node.name); - newNode._namespaceURI = node.namespace || "http://www.w3.org/1999/xhtml"; - if (node.location) { - newNode.sourceLocation = node.location; - newNode.sourceLocation.file = parent.sourceLocation.file; - } - } catch (err) { - currentDocument.raise('error', 'invalid markup', { - exception: err, - node : node - }); - - return null; - } - break; - - case 'root': - // If we are in <template> then implicitly create #document-fragment for it's content - if(parent.tagName === 'TEMPLATE' && parent._namespaceURI === 'http://www.w3.org/1999/xhtml') { - newNode = currentDocument.createDocumentFragment(); - // Mark fragment as parser-created template content, so it will be accepted by appendChild() - newNode._templateContent = true; - } - break; - - case 'text': - // HTML entities should already be decoded by the parser, so no need to decode them - newNode = currentDocument.createTextNode(node.data); - break; - - case 'comment': - newNode = currentDocument.createComment(node.data); - break; - - case 'directive': - if (node.name[0] === '?' && node.name.toLowerCase() !== '?xml') { - var data = node.data.slice(node.name.length + 1, -1); - newNode = currentDocument.createProcessingInstruction(node.name.substring(1), data); - } else if (node.name.toLowerCase() === '!doctype') { - newNode = parseDocType(currentDocument, '<' + node.data + '>'); - } - break; - - default: - return null; - break; - } - - if (!newNode) - return null; - - newNode._localName = node.name; - - if (node.attribs) { - for (c in node.attribs) { - var prefix = node['x-attribsPrefix'] && node['x-attribsPrefix'][c] ? node['x-attribsPrefix'][c] + ':' : ''; - // catchin errors here helps with improperly escaped attributes - // but properly fixing parent should (can only?) be done in the htmlparser itself - try { - newNode._setAttributeNoValidation(prefix + c, node.attribs[c]); - newNode.attributes[prefix + c]._namespaceURI = node['x-attribsNamespace'][c] || null; - newNode.attributes[prefix + c]._prefix = node['x-attribsPrefix'][c] || null; - newNode.attributes[prefix + c]._localName = c; - } catch(e2) { /* noop */ } - } - } - - if (node.children) { - for (c = 0; c < node.children.length; c++) { - setChild(newNode, node.children[c]); - } - } - - try{ - return parent.appendChild(newNode); - }catch(err){ - currentDocument.raise('error', err.message, { - exception: err, - node : node - }); - return null; - } -} - -var HTML5_DOCTYPE = /<!doctype html>/i; -var PUBLIC_DOCTYPE = /<!doctype\s+([^\s]+)\s+public\s+"([^"]+)"\s+"([^"]+)"/i; -var SYSTEM_DOCTYPE = /<!doctype\s+([^\s]+)\s+system\s+"([^"]+)"/i; - -function parseDocType(doc, html) { - if (HTML5_DOCTYPE.test(html)) { - return doc.implementation.createDocumentType("html", "", ""); - } - - var publicPieces = PUBLIC_DOCTYPE.exec(html); - if (publicPieces) { - return doc.implementation.createDocumentType(publicPieces[1], publicPieces[2], publicPieces[3]); - } - - var systemPieces = SYSTEM_DOCTYPE.exec(html); - if (systemPieces) { - return doc.implementation.createDocumentType(systemPieces[1], systemPieces[2], ""); - } - - // Shouldn't get here (the parser shouldn't let us know about invalid doctypes), but our logic likely isn't - // real-world perfect, so let's fallback. - return doc.implementation.createDocumentType("html", "", ""); -} - - -exports.HtmlToDom = HtmlToDom; diff --git a/node_modules/jsdom/lib/jsdom/browser/index.js b/node_modules/jsdom/lib/jsdom/browser/index.js deleted file mode 100644 index 0d44dc1..0000000 --- a/node_modules/jsdom/lib/jsdom/browser/index.js +++ /dev/null @@ -1,85 +0,0 @@ -var HtmlToDom = require('./htmltodom').HtmlToDom, - jsdom = require('../../jsdom'), - defineGetter = require('../utils').defineGetter, - defineSetter = require('../utils').defineSetter, - Contextify = require('contextify'), - Window = require('./Window'); - -function windowAugmentation(document) { - var window = createWindow(document); - - if (document.addEventListener) { - if (document.readyState == 'complete') { - var ev = document.createEvent('HTMLEvents'); - ev.initEvent('load', false, false); - process.nextTick(function () { - window.dispatchEvent(ev); - }); - } - else { - document.addEventListener('load', function(ev) { - window.dispatchEvent(ev); - }); - } - } - - return window; -}; - -function createWindow(document) { - var window = new Window(document); - - Contextify(window); - - // We need to set up self references using Contextify's getGlobal() so that - // the global object identity is correct (window === this). - // See Contextify README for more info. - var windowGlobal = window.getGlobal(); - - // Set up the window as if it's a top level window. - // If it's not, then references will be corrected by frame/iframe code. - // Note: window.frames is maintained in the HTMLFrameElement init function. - window.window = window.frames - = window.self - = window.parent - = window.top = windowGlobal; - - return window; -}; - -/** - * Augments the given DOM by adding browser-specific properties and methods (BOM). - * Returns the augmented DOM. - */ -// TODO: this function is HORIBBLE. It modifies the *shared* `dom` variable with document-specific stuff. -// We call it in `jsdom.jsdom`, i.e. per-document. The checks `if (dom._augment && ...)` just mean that it won't modify -// the global twice *for the same options*. Bad stuff. -// -// None of the properties set here should be on `dom`, really. -exports.browserAugmentation = function (dom, options) { - if (!options) { - options = {}; - } - - var parser = options.parser; - - if (dom._augmented && dom._parser === parser && dom._parsingMode === options.parsingMode) { - return dom; - } - - dom._parser = parser; - dom._parsingMode = options.parsingMode; - var htmltodom = new HtmlToDom(parser, options.parsingMode); - dom.Document.prototype._htmlToDom = htmltodom; - dom.Document.prototype._domImpl = dom.DOMImplementation; - - defineGetter(dom.Document.prototype, 'parentWindow', function() { - if (!this._parentWindow) { - this.parentWindow = windowAugmentation(this); - } - return this._parentWindow; - }); - - dom._augmented = true; - return dom; -}; diff --git a/node_modules/jsdom/lib/jsdom/browser/location.js b/node_modules/jsdom/lib/jsdom/browser/location.js deleted file mode 100644 index 92ece8c..0000000 --- a/node_modules/jsdom/lib/jsdom/browser/location.js +++ /dev/null @@ -1,103 +0,0 @@ -"use strict"; - -var URL = require("url"); -var resolveHref = require("../utils").resolveHref; -var NOT_IMPLEMENTED = require("./utils").NOT_IMPLEMENTED; - -module.exports = Location; - -function Location(urlString, document) { - this._url = URL.parse(urlString); - this._document = document; -} - -Location.prototype = { - constructor: Location, - reload: function () { - NOT_IMPLEMENTED("location.reload", this._document)(); - }, - get protocol() { return this._url.protocol || ":"; }, - get host() { return this._url.host || ""; }, - get auth() { return this._url.auth; }, - get hostname() { return this._url.hostname || ""; }, - get origin() { - return ((this._url.protocol !== undefined && this._url.protocol !== null) ? - this._url.protocol + "//" : - this._url.protocol) + - this._url.host || ""; - }, - get port() { return this._url.port || ""; }, - get pathname() { return this._url.pathname || ""; }, - get href() { return this._url.href; }, - get hash() { return this._url.hash || ""; }, - get search() { return this._url.search || ""; }, - - set href(val) { - var oldUrl = this._url.href; - var oldProtocol = this._url.protocol; - var oldHost = this._url.host; - var oldPathname = this._url.pathname; - var oldHash = this._url.hash || ""; - - this._url = URL.parse(resolveHref(oldUrl, val)); - var newUrl = this._url.href; - var newProtocol = this._url.protocol; - var newHost = this._url.host; - var newPathname = this._url.pathname; - var newHash = this._url.hash || ""; - - if (oldProtocol === newProtocol && oldHost === newHost && oldPathname === newPathname && oldHash !== newHash) { - this._signalHashChange(oldUrl, newUrl); - } else { - NOT_IMPLEMENTED("location.href (no reload)", this._document)(); - } - }, - - set hash(val) { - var oldUrl = this._url.href; - var oldHash = this._url.hash || ""; - - if (val.lastIndexOf("#", 0) !== 0) { - val = "#" + val; - } - - this._url = URL.parse(resolveHref(oldUrl, val)); - var newUrl = this._url.href; - var newHash = this._url.hash || ""; - - if (oldHash !== newHash) { - this._signalHashChange(oldUrl, newUrl); - } - }, - - set search(val) { - var oldUrl = this._url.href; - var oldHash = this._url.hash || ""; - if (val.length) { - if (val.lastIndexOf("?", 0) !== 0) { - val = "?" + val; - } - this._url = URL.parse(resolveHref(oldUrl, val + oldHash)); - } else { - this._url = URL.parse(oldUrl.replace(/\?([^#]+)/, "")); - } - }, - - replace: function (val) { - this.href = val; - }, - - toString: function () { - return this._url.href; - }, - - _signalHashChange: function (oldUrl, newUrl) { - var ev = this._document.createEvent("HTMLEvents"); - ev.initEvent("hashchange", false, false); - ev.oldUrl = oldUrl; - ev.newUrl = newUrl; - process.nextTick(function () { - this._document.parentWindow.dispatchEvent(ev); - }.bind(this)); - } -}; diff --git a/node_modules/jsdom/lib/jsdom/browser/utils.js b/node_modules/jsdom/lib/jsdom/browser/utils.js deleted file mode 100644 index 87e952e..0000000 --- a/node_modules/jsdom/lib/jsdom/browser/utils.js +++ /dev/null @@ -1,15 +0,0 @@ -"use strict"; - -exports.NOT_IMPLEMENTED = function (nameForErrorMessage, target) { - return function () { - if (target === undefined) { - target = this; - } - - if (target && target.raise) { - target.raise("error", "NOT_IMPLEMENTED: " + nameForErrorMessage); - } else if (typeof console !== "undefined" && console.log) { - console.log(new Error("Called NOT_IMPLEMENTED without an element to raise on: " + nameForErrorMessage)); - } - }; -}; diff --git a/node_modules/jsdom/lib/jsdom/contextify-shim.js b/node_modules/jsdom/lib/jsdom/contextify-shim.js deleted file mode 100644 index 0bf22a9..0000000 --- a/node_modules/jsdom/lib/jsdom/contextify-shim.js +++ /dev/null @@ -1,53 +0,0 @@ -"use strict"; - -var acorn = require("acorn"); -var findGlobals = require("acorn-globals"); -var escodegen = require("escodegen"); - -module.exports = function (o) { - o.getGlobal = function () { - return o; - }; - - o.run = function (code, filename) { - var comments = [], tokens = []; - var ast = acorn.parse(code, { - ecmaVersion: 6, - allowReturnOutsideFunction: true, - ranges: true, - // collect comments in Esprima's format - onComment: comments, - // collect token ranges - onToken: tokens - }); - - // make sure we keep comments - escodegen.attachComments(ast, comments, tokens); - - var globals = findGlobals(ast); - for (var i = 0; i < globals.length; ++i) { - if (globals[i].name === "window") { - continue; - } - - var nodes = globals[i].nodes; - for (var j = 0; j < nodes.length; ++j) { - var type = nodes[j].type; - var name = nodes[j].name; - nodes[j].type = "MemberExpression"; - nodes[j].property = { - name: name, - type: type - }; - nodes[j].computed = false; - nodes[j].object = { - name: "window", - type: "Identifier" - }; - } - } - - code = escodegen.generate(ast, { comment: true }); - new Function("window", code + "\n//# sourceURL=" + filename).bind(o)(o); // jshint ignore:line - }; -}; diff --git a/node_modules/jsdom/lib/jsdom/level1/core.js b/node_modules/jsdom/lib/jsdom/level1/core.js deleted file mode 100644 index 26c8484..0000000 --- a/node_modules/jsdom/lib/jsdom/level1/core.js +++ /dev/null @@ -1,1794 +0,0 @@ -/* - ServerJS Javascript DOM Level 1 -*/ -var inheritFrom = require("../utils").inheritFrom; -var domToHtml = require("../browser/domtohtml").domToHtml; -var defineGetter = require("../utils").defineGetter; -var memoizeQuery = require("../utils").memoizeQuery; -var validateName = require('../living/helpers/validate-names').name; -var Location = require("../browser/location"); - -// utility functions -var attachId = function(id,elm,doc) { - if (id && elm && doc) { - if (!doc._ids[id]) { - doc._ids[id] = []; - } - doc._ids[id].push(elm); - } -}; -var detachId = function(id,elm,doc) { - var elms, i; - if (id && elm && doc) { - if (doc._ids && doc._ids[id]) { - elms = doc._ids[id]; - for (i=0;i<elms.length;i++) { - if (elms[i] === elm) { - elms.splice(i,1); - i--; - } - } - if (elms.length === 0) { - delete doc._ids[id]; - } - } - } -}; - -function setInnerHTML(dom, node, html) { - //Clear the children first: - var child; - while ((child = node._childNodes[0])) { - node.removeChild(child); - } - - var isDoc = node.nodeName === '#document'; - if (html !== "" && html != null) { - if (isDoc) { - dom._htmlToDom.appendHtmlToDocument(html, node); - } else { - dom._htmlToDom.appendHtmlToElement(html, node); - } - } -} - -// TODO: move all of these to utils.js. Right now they are exposed on window, which is bizarre. -var core = module.exports = { - mapper: function(parent, filter, recursive) { - return function() { - return core.mapDOMNodes(parent, recursive !== false, filter); - }; - }, - - // Returns Array - mapDOMNodes : function(parent, recursive, callback) { - function visit(parent, result) { - return parent._childNodes.reduce(reducer, result); - } - - function reducer(array, child) { - if (callback(child)) { - array.push(child); - } - if (recursive && child._childNodes) { - visit(child, array); - } - return array; - } - - return visit(parent, []); - }, - - visitTree: function(root, callback) { - var cur = root; // TODO: Unroll this. - - function visit(el) { - if (el) { - callback(el); - if (el._childNodes) { - var i = 0, - children = el._childNodes, - l = children.length; - - for (i; i<l; i++) { - visit(children[i]); - } - } - } - } - visit(root); - }, - - markTreeReadonly: function(node) { - function markLevel(el) { - el._readonly = true; - // also mark attributes and their children read-only - if (el.attributes) { - var attributes = el.attributes, l = attributes.length, i=0; - attributes._readonly = true; - - for (i; i<l; i++) { - core.visitTree(attributes[i], markLevel); - } - } - } - - core.visitTree(node, markLevel); - } -}; - -// ExceptionCode -var INDEX_SIZE_ERR = core.INDEX_SIZE_ERR = 1, - DOMSTRING_SIZE_ERR = core.DOMSTRING_SIZE_ERR = 2, - HIERARCHY_REQUEST_ERR = core.HIERARCHY_REQUEST_ERR = 3, - WRONG_DOCUMENT_ERR = core.WRONG_DOCUMENT_ERR = 4, - INVALID_CHARACTER_ERR = core.INVALID_CHARACTER_ERR = 5, - NO_DATA_ALLOWED_ERR = core.NO_DATA_ALLOWED_ERR = 6, - NO_MODIFICATION_ALLOWED_ERR = core.NO_MODIFICATION_ALLOWED_ERR = 7, - NOT_FOUND_ERR = core.NOT_FOUND_ERR = 8, - NOT_SUPPORTED_ERR = core.NOT_SUPPORTED_ERR = 9, - INUSE_ATTRIBUTE_ERR = core.INUSE_ATTRIBUTE_ERR = 10, - INVALID_STATE_ERR = core.INVALID_STATE_ERR = 11, - SYNTAX_ERR = core.SYNTAX_ERR = 12, - INVALID_MODIFICATION_ERR = core.INVALID_MODIFICATION_ERR = 13, - NAMESPACE_ERR = core.NAMESPACE_ERR = 14, - INVALID_ACCESS_ERR = core.INVALID_ACCESS_ERR = 15, -// Node Types - ELEMENT_NODE = 1, - ATTRIBUTE_NODE = 2, - TEXT_NODE = 3, - CDATA_SECTION_NODE = 4, - ENTITY_REFERENCE_NODE = 5, - ENTITY_NODE = 6, - PROCESSING_INSTRUCTION_NODE = 7, - COMMENT_NODE = 8, - DOCUMENT_NODE = 9, - DOCUMENT_TYPE_NODE = 10, - DOCUMENT_FRAGMENT_NODE = 11, - NOTATION_NODE = 12; - -var messages = core.exceptionMessages = { }; -messages[INDEX_SIZE_ERR] = "Index size error"; -messages[DOMSTRING_SIZE_ERR] = "DOMString size error"; -messages[HIERARCHY_REQUEST_ERR] = "Hierarchy request error"; -messages[WRONG_DOCUMENT_ERR] = "Wrong document"; -messages[INVALID_CHARACTER_ERR] = "Invalid character"; -messages[NO_DATA_ALLOWED_ERR] = "No data allowed"; -messages[NO_MODIFICATION_ALLOWED_ERR] = "No modification allowed"; -messages[NOT_FOUND_ERR] = "Not found"; -messages[NOT_SUPPORTED_ERR] = "Not supported"; -messages[INUSE_ATTRIBUTE_ERR] = "Attribute in use"; -messages[NAMESPACE_ERR] = "Invalid namespace"; - -core.DOMException = function DOMException(code, message) { - Error.call(this, core.exceptionMessages[code]); - this.message = core.exceptionMessages[code]; - this.code = code; - - if (message) { - this.message = this.message + ": " + message; - } - - if (Error.captureStackTrace) { - - Error.captureStackTrace(this, DOMException); - } -}; - -core.DOMException.INDEX_SIZE_ERR = INDEX_SIZE_ERR; -core.DOMException.DOMSTRING_SIZE_ERR = DOMSTRING_SIZE_ERR; -core.DOMException.HIERARCHY_REQUEST_ERR = HIERARCHY_REQUEST_ERR; -core.DOMException.WRONG_DOCUMENT_ERR = WRONG_DOCUMENT_ERR; -core.DOMException.INVALID_CHARACTER_ERR = INVALID_CHARACTER_ERR; -core.DOMException.NO_DATA_ALLOWED_ERR = NO_DATA_ALLOWED_ERR; -core.DOMException.NO_MODIFICATION_ALLOWED_ERR = NO_MODIFICATION_ALLOWED_ERR; -core.DOMException.NOT_FOUND_ERR = NOT_FOUND_ERR; -core.DOMException.NOT_SUPPORTED_ERR = NOT_SUPPORTED_ERR; -core.DOMException.INUSE_ATTRIBUTE_ERR = INUSE_ATTRIBUTE_ERR; -core.DOMException.INVALID_STATE_ERR = INVALID_STATE_ERR; -core.DOMException.SYNTAX_ERR = SYNTAX_ERR; -core.DOMException.INVALID_MODIFICATION_ERR = INVALID_MODIFICATION_ERR; -core.DOMException.NAMESPACE_ERR = NAMESPACE_ERR; -core.DOMException.INVALID_ACCESS_ERR = INVALID_ACCESS_ERR; - -inheritFrom(Error, core.DOMException, { - name: "DOMException", - INDEX_SIZE_ERR : INDEX_SIZE_ERR, - DOMSTRING_SIZE_ERR : DOMSTRING_SIZE_ERR, - HIERARCHY_REQUEST_ERR : HIERARCHY_REQUEST_ERR, - WRONG_DOCUMENT_ERR : WRONG_DOCUMENT_ERR, - INVALID_CHARACTER_ERR : INVALID_CHARACTER_ERR, - NO_DATA_ALLOWED_ERR : NO_DATA_ALLOWED_ERR, - NO_MODIFICATION_ALLOWED_ERR : NO_MODIFICATION_ALLOWED_ERR, - NOT_FOUND_ERR : NOT_FOUND_ERR, - NOT_SUPPORTED_ERR : NOT_SUPPORTED_ERR, - INUSE_ATTRIBUTE_ERR : INUSE_ATTRIBUTE_ERR, - INVALID_STATE_ERR : INVALID_STATE_ERR, - SYNTAX_ERR : SYNTAX_ERR, - INVALID_MODIFICATION_ERR : INVALID_MODIFICATION_ERR, - NAMESPACE_ERR : NAMESPACE_ERR, - INVALID_ACCESS_ERR : INVALID_ACCESS_ERR -}); - -core.NodeList = function NodeList(element, query) { - if (!query) { - // Non-live NodeList - if (Array.isArray(element)) { - Array.prototype.push.apply(this, element); - } - Object.defineProperties(this, { - _length: {value: element ? element.length : 0, writable:true} - }); - } else { - Object.defineProperties(this, { - _element: {value: element}, - _query: {value: query}, - _snapshot: {writable: true}, - _length: {value: 0, writable: true}, - _version: {value: -1, writable: true} - }); - this._update(); - } -}; - -function lengthFromProperties(arrayLike) { - var max = -1; - var keys = Object.keys(arrayLike); - var highestKeyIndex = keys.length - 1; - - // abuses a v8 implementation detail for a very fast case - // (if this implementation detail changes, this method will still - // return correct results) - if (highestKeyIndex == keys[highestKeyIndex]) { // not === - return keys.length; - } - - for (var i = highestKeyIndex; i >= 0 ; --i) { - var asNumber = + keys[i]; - - if (!isNaN(asNumber) && asNumber > max) { - max = asNumber; - } - } - return max + 1; -} -core.NodeList.prototype = { - _update: function() { - var i; - - if (!this._element) { - this._length = lengthFromProperties(this); - } else { - if (this._version < this._element._version) { - var nodes = this._snapshot = this._query(); - this._resetTo(nodes); - this._version = this._element._version; - } - } - }, - _resetTo: function(array) { - var startingLength = lengthFromProperties(this); - for (var i = 0; i < startingLength; ++i) { - delete this[i]; - } - - for (var j = 0; j < array.length; ++j) { - this[j] = array[j]; - } - this._length = array.length; - }, - _toArray: function() { - if (this._element) { - this._update(); - return this._snapshot; - } - - return Array.prototype.slice.call(this); - }, - get length() { - this._update(); - return this._length || 0; - }, - set length(length) { - return this._length; - }, - item: function(index) { - this._update(); - return this[index] || null; - }, - toString: function() { - return '[ jsdom NodeList ]: contains ' + this.length + ' items'; - } -}; -Object.defineProperty(core.NodeList.prototype, 'constructor', { - value: core.NodeList, - writable: true, - configurable: true -}); - -core.DOMImplementation = function DOMImplementation(document, /* Object */ features) { - this._ownerDocument = document; - this._features = {}; - - if (features) { - for (var feature in features) { - if (features.hasOwnProperty(feature)) { - this._addFeature(feature.toLowerCase(), features[feature]); - } - } - } -}; - -core.DOMImplementation.prototype = { - // All of these are legacy, left because jsdom uses them internally :(. jsdom confused the idea of browser features - // and jsdom features - _removeFeature : function(feature, version) { - feature = feature.toLowerCase(); - if (this._features[feature]) { - if (version) { - var j = 0, - versions = this._features[feature], - l = versions.length; - - for (j; j<l; j++) { - if (versions[j] === version) { - versions.splice(j,1); - return; - } - } - } else { - delete this._features[feature]; - } - } - }, - - _addFeature: function(feature, version) { - feature = feature.toLowerCase(); - - if (version) { - - if (!this._features[feature]) { - this._features[feature] = []; - } - - if (version instanceof Array) { - Array.prototype.push.apply(this._features[feature], version); - } else { - this._features[feature].push(version); - } - } - }, - - // The real hasFeature is in living/dom-implementation.js, and returns true always. - // This one is used internally - _hasFeature: function(/* string */ feature, /* string */ version) { - feature = (feature) ? feature.toLowerCase() : ''; - var versions = (this._features[feature]) ? - this._features[feature] : - false; - - if (!version && versions.length && versions.length > 0) { - return true; - } else if (typeof versions === 'string') { - return versions === version; - } else if (versions.indexOf && versions.length > 0) { - for (var i = 0; i < versions.length; i++) { - var found = versions[i] instanceof RegExp ? - versions[i].test(version) : - versions[i] === version; - if (found) { return true; } - } - return false; - } else { - return false; - } - } -}; - - -var attrCopy = function(src, dest, fn) { - if (src.attributes) { - var attrs = src.attributes, i, l = attrs.length, attr, copied; - for (i=0;i<l;i++) { - attr = attrs[i]; - // skip over default attributes - if (!attr.specified) { - continue; - } - // TODO: consider duplicating this code and moving it into level2/core - if (attr.namespaceURI) { - dest.setAttributeNS(attr.namespaceURI, - attr.name, - attr.value); - var localName = attr.name.split(':').pop(); - copied = dest.getAttributeNodeNS(attr.namespaceURI, localName); - } else { - dest.setAttribute(attr.name, attr.value); - copied = dest.getAttributeNode(attr.name); - } - if (typeof fn == "function") { - fn(attr, copied); - } - - } - } - return dest; -}; - -core.Node = function Node(ownerDocument) { - this._childNodes = []; - this._childNodesList = null; - this._ownerDocument = ownerDocument; - this._attributes = new AttributeList(ownerDocument, this); - this._childrenList = null; - this._version = 0; - this._parentNode = null; - this._memoizedQueries = {}; - this._readonly = false; -}; - -core.Node.ELEMENT_NODE = ELEMENT_NODE; -core.Node.ATTRIBUTE_NODE = ATTRIBUTE_NODE; -core.Node.TEXT_NODE = TEXT_NODE; -core.Node.CDATA_SECTION_NODE = CDATA_SECTION_NODE; -core.Node.ENTITY_REFERENCE_NODE = ENTITY_REFERENCE_NODE; -core.Node.ENTITY_NODE = ENTITY_NODE; -core.Node.PROCESSING_INSTRUCTION_NODE = PROCESSING_INSTRUCTION_NODE; -core.Node.COMMENT_NODE = COMMENT_NODE; -core.Node.DOCUMENT_NODE = DOCUMENT_NODE; -core.Node.DOCUMENT_TYPE_NODE = DOCUMENT_TYPE_NODE; -core.Node.DOCUMENT_FRAGMENT_NODE = DOCUMENT_FRAGMENT_NODE; -core.Node.NOTATION_NODE = NOTATION_NODE; - -core.Node.prototype = { - ELEMENT_NODE : ELEMENT_NODE, - ATTRIBUTE_NODE : ATTRIBUTE_NODE, - TEXT_NODE : TEXT_NODE, - CDATA_SECTION_NODE : CDATA_SECTION_NODE, - ENTITY_REFERENCE_NODE : ENTITY_REFERENCE_NODE, - ENTITY_NODE : ENTITY_NODE, - PROCESSING_INSTRUCTION_NODE : PROCESSING_INSTRUCTION_NODE, - COMMENT_NODE : COMMENT_NODE, - DOCUMENT_NODE : DOCUMENT_NODE, - DOCUMENT_TYPE_NODE : DOCUMENT_TYPE_NODE, - DOCUMENT_FRAGMENT_NODE : DOCUMENT_FRAGMENT_NODE, - NOTATION_NODE : NOTATION_NODE, - - get children() { - if (!this._childrenList) { - var self = this; - this._childrenList = new core.NodeList(this, function() { - return self._childNodes.filter(function(node) { - return node.tagName; - }); - }); - } - this._childrenList._update(); - return this._childrenList; - }, - get nodeValue() { - if (this.nodeType === core.Node.TEXT_NODE || - this.nodeType === core.Node.COMMENT_NODE || - this.nodeType === core.Node.PROCESSING_INSTRUCTION_NODE) { - return this._data; - } - - return null; - }, - set nodeValue(value) { - if (this.nodeType === core.Node.TEXT_NODE || - this.nodeType === core.Node.COMMENT_NODE || - this.nodeType === core.Node.PROCESSING_INSTRUCTION_NODE) { - this.replaceData(0, this.length, value); - } - }, - get parentNode() { return this._parentNode;}, - - get nodeName() { - switch (this.nodeType) { - case ELEMENT_NODE: - return this.tagName; - case TEXT_NODE: - return "#text"; - case PROCESSING_INSTRUCTION_NODE: - return this.target; - case COMMENT_NODE: - return "#comment"; - case DOCUMENT_NODE: - return "#document"; - case DOCUMENT_TYPE_NODE: - return this.name; - case DOCUMENT_FRAGMENT_NODE: - return "#document-fragment"; - case ATTRIBUTE_NODE: - // TODO: remove this; attributes should not be nodes and should not have a nodeName property - // Removing it breaks some legit-seeming xpath tests :-/ - return this.name; - } - }, - set nodeName(unused) { throw new core.DOMException();}, - get firstChild() { - return this._childNodes.length > 0 ? this._childNodes[0] : null; - }, - get ownerDocument() { return this._ownerDocument;}, - get readonly() { return this._readonly;}, - - get lastChild() { - var len = this._childNodes.length; - return len > 0 ? this._childNodes[len -1] : null; - }, - - get childNodes() { - if (!this._childNodesList) { - var self = this; - this._childNodesList = new core.NodeList(this, function() { - return self._childNodes.slice(); - }); - } - this._childNodesList._update(); - return this._childNodesList; - }, - set childNodes(unused) { throw new core.DOMException();}, - - _indexOf: function(/*Node*/ child) { - return this._childNodes.indexOf(child); - }, - - get nextSibling() { - // find this node's index in the parentNode, add one and call it a day - if (!this._parentNode || !this._parentNode._indexOf) { - return null; - } - - var index = this._parentNode._indexOf(this); - - if (index == -1 || index+1 >= this._parentNode._childNodes.length) { - return null; - } - - return this._parentNode._childNodes[index+1] || null; - }, - set nextSibling(unused) { throw new core.DOMException();}, - - get previousSibling() { - if (!this._parentNode || !this._parentNode._indexOf) { - return null; - } - - var index = this._parentNode._indexOf(this); - - if (index == -1 || index-1 < 0) { - return null; - } - - return this._parentNode._childNodes[index-1] || null; - }, - set previousSibling(unused) { throw new core.DOMException();}, - - /* returns Node */ - insertBefore : function(/* Node */ newChild, /* Node*/ refChild) { - if (this._readonly === true) { - throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR, 'Attempting to modify a read-only node'); - } - - // Adopt unowned children, for weird nodes like DocumentType - if (!newChild._ownerDocument) newChild._ownerDocument = this._ownerDocument; - - // TODO - if (!newChild) then? - if (!(this instanceof core.Document) && newChild._ownerDocument !== this._ownerDocument) { - throw new core.DOMException(WRONG_DOCUMENT_ERR); - } - - if (newChild.nodeType && newChild.nodeType === ATTRIBUTE_NODE) { - throw new core.DOMException(HIERARCHY_REQUEST_ERR); - } - - // search for parents matching the newChild - var current = this; - do { - if (current === newChild) { - throw new core.DOMException(HIERARCHY_REQUEST_ERR); - } - } while((current = current._parentNode)); - - // fragments are merged into the element (except parser-created fragments in <template>) - if (newChild.nodeType === DOCUMENT_FRAGMENT_NODE && !newChild._templateContent) { - var tmpNode, i = newChild._childNodes.length; - while (i-- > 0) { - tmpNode = newChild.removeChild(newChild.firstChild); - this.insertBefore(tmpNode, refChild); - } - } else if (newChild === refChild) { - return newChild; - } else { - // if the newChild is already in the tree elsewhere, remove it first - if (newChild._parentNode) { - newChild._parentNode.removeChild(newChild); - } - - if (refChild == null) { - this._childNodes.push(newChild); - } else { - var refChildIndex = this._indexOf(refChild); - if (refChildIndex == -1) { - throw new core.DOMException(NOT_FOUND_ERR); - } - this._childNodes.splice(refChildIndex, 0, newChild); - } - - newChild._parentNode = this; - if (this._attached && newChild._attach) { - newChild._attach(); - } - - this._modified(); - this._descendantAdded(this, newChild); - } - - return newChild; - }, // raises(DOMException); - - _modified: function() { - this._version++; - if (this._ownerDocument) { - this._ownerDocument._version++; - } - - if (this._childrenList) { - this._childrenList._update(); - } - this._clearMemoizedQueries() - }, - - _clearMemoizedQueries: function() { - this._memoizedQueries = {}; - if (this._parentNode && this._parentNode !== this) { - this._parentNode._clearMemoizedQueries(); - } - }, - - _descendantRemoved: function(parent, child) { - if (this._parentNode && this._parentNode !== this) { - this._parentNode._descendantRemoved(parent, child); - } - }, - - _descendantAdded: function(parent, child) { - if (this._parentNode && this._parentNode !== this) { - this._parentNode._descendantAdded(parent, child); - } - }, - - _attrModified: function(name, value, oldValue) { - if (name == 'id' && this._attached) { - var doc = this._ownerDocument; - detachId(oldValue,this,doc); - attachId(value,this,doc); - } - - // Check for inline event handlers. - // We can't set these like other attributes then look it up in - // dispatchEvent() because that would create 2 'traditional' event handlers - // in the case where there's an inline event handler attribute, plus one - // set using element.on* in a script. - // - // @see http://www.w3.org/TR/2011/WD-html5-20110405/webappapis.html#event-handler-content-attributes - if ((name.length > 2) && (name[0] == 'o') && (name[1] == 'n')) { - if (value) { - var self = this; - // Check whether we're the window. This can happen because inline - // handlers on the body are proxied to the window. - var w = (typeof self.run !== 'undefined') ? self : self._ownerDocument.parentWindow; - self[name] = function (event) { - // The handler code probably refers to functions declared in the - // window context, so we need to call run(). - - // Use awesome hacks to get the correct `this` context for the - // inline event handler. This would only be necessary if we're an - // element, but for the sake of simplicity we also do it on window. - - // Also set event variable and support `return false`. - w.__tempContextForInlineEventHandler = self; - w.__tempEvent = event; - w.run("if ((function (event) {" + value + "}).call(" + - "window.__tempContextForInlineEventHandler, window.__tempEvent) === false) {" + - "window.__tempEvent.preventDefault()}"); - delete w.__tempContextForInlineEventHandler; - delete w.__tempEvent; - }; - } else { - this[name] = null; - } - } - }, - - /* returns Node */ - replaceChild : function(/* Node */ newChild, /* Node */ oldChild){ - this.insertBefore(newChild, oldChild); - return this.removeChild(oldChild); - }, //raises(DOMException); - - /* returns void */ - _attach : function() { - this._attached = true; - if (this.id) { - attachId(this.id,this,this._ownerDocument); - } - for (var i = 0, len = this._childNodes.length; i < len; i++) { - if (this._childNodes[i]._attach) { - this._childNodes[i]._attach(); - } - } - }, - /* returns void */ - _detach : function() { - var i, elms; - this._attached = false; - if (this.id) { - detachId(this.id,this,this._ownerDocument); - } - for (var i = 0, len = this._childNodes.length; i < len; i++) { - this._childNodes[i]._detach(); - } - }, - - /* returns Node */ - removeChild : function(/* Node */ oldChild){ - if (this._readonly === true) { - throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR); - } - - // TODO - if (!oldChild) then? - - // Use lastIndexOf so that removing all the children by - // going backwards through childNodes is fast - // (because of splice) - var oldChildIndex = this._childNodes.lastIndexOf(oldChild); - if (oldChildIndex == -1) { - throw new core.DOMException(NOT_FOUND_ERR); - } - - this._childNodes.splice(oldChildIndex, 1); - oldChild._parentNode = null; - this._modified(); - oldChild._detach(); - this._descendantRemoved(this, oldChild); - return oldChild; - }, // raises(DOMException); - - /* returns Node */ - appendChild : function(/* Node */ newChild) { - return this.insertBefore(newChild, null); - }, // raises(DOMException); - - /* returns boolean */ - hasChildNodes : function() { - return this._childNodes.length > 0; - }, - - /* returns Node */ - cloneNode : function(/* bool */ deep, fn) { - - var object = null; - switch (this.nodeType) { - - case this.ELEMENT_NODE: - object = attrCopy(this,this._ownerDocument.createElementNS(this.namespaceURI, this.nodeName), fn); - // Using this.nodeName isn't always exact because of uppercasing-related stuff - object._prefix = this._prefix; - object._localName = this._localName; - break; - - case this.TEXT_NODE: - object = attrCopy(this,this._ownerDocument.createTextNode(this.tagName)); - object.nodeValue = this.nodeValue; - break; - case this.ATTRIBUTE_NODE: - object = this._ownerDocument.createAttribute(this.name); - break; - break; - case this.PROCESSING_INSTRUCTION_NODE: - var pi = this._ownerDocument.createProcessingInstruction(this._target, - this._data); - object = attrCopy(this, pi); - break; - case this.COMMENT_NODE: - object = this._ownerDocument.createComment(this.tagName); - object.nodeValue = this.nodeValue; - break; - case this.DOCUMENT_NODE: - object = attrCopy(this, new this.constructor({ parsingMode: this._parsingMode })); - // TODO: clone the doctype? - break; - case this.DOCUMENT_TYPE_NODE: - object = new core.DocumentType(this._ownerDocument, this._name, this._publicId, this._systemId); - break; - case this.DOCUMENT_FRAGMENT_NODE: - object = this._ownerDocument.createDocumentFragment(); - break; - default: - throw new core.DOMException(NOT_FOUND_ERR); - break; - } - - if (typeof fn === "function") { - fn(this, object); - } - - if (deep || this.nodeType === ATTRIBUTE_NODE) { - var clone = null; - for (var i=0,len=this._childNodes.length;i<len;i++) - { - clone = this._childNodes[i].cloneNode(true); - if (clone.nodeType === ATTRIBUTE_NODE) { - object.setAttributeNode(clone); - } else { - var readonly = object._readonly; - object._readonly = false; - object.appendChild(clone); - object._readonly = readonly; - } - } - } - - return object; - }, - - /* returns void */ - normalize: function() { - var prevChild, child, attr,i; - - if (this._attributes && this._attributes.length) { - for (i=0;i<this._attributes.length;i++) - { - if (this._attributes[i]) { - attr = this._attributes[i].normalize(); - } - } - } - - for (i=0;i<this._childNodes.length;i++) - { - child = this._childNodes[i]; - - if (child.normalize) { - child.normalize(); - } - - // Level2/core clean off empty nodes - if (child.nodeValue === "") { - this.removeChild(child); - i--; - continue; - } - - if (i>0) { - prevChild = this._childNodes[i-1]; - - if (child.nodeType === TEXT_NODE && - prevChild.nodeType === TEXT_NODE) - { - - // remove the child and decrement i - prevChild.appendData(child.nodeValue); - - this.removeChild(child); - i--; - } - } - } - }, - toString: function() { - var id = ''; - if (this.id) { - id = '#' + this.id; - } - if (this.className) { - var classes = this.className.split(/\s+/); - for (var i = 0, len = classes.length; i < len; i++) { - id += '.' + classes[i]; - } - } - return '[ ' + this.tagName + id + ' ]'; - }, - raise: function(type, message, data) { - var text = type + ": " + message; - - if (data) { - if (data.exception) { - text = data.exception.stack; - } else { - text += ' - More:\n' + data; - } - } - - if (type === "error") { - if (!this.errors) { - this.errors = []; - } - // TODO: consider using actual `Error` objects or `DOMException`s even.. - var err = { - type : type, - message : message || "No message", - data : data || null - }; - - this.errors.push(err); - - if (this._ownerDocument && - this._ownerDocument.raise && - this !== this._ownerDocument) - { - this._ownerDocument.raise(type, message, data); - } - } - } -}; - - -core.NamedNodeMap = function NamedNodeMap(document) { - this._nodes = Object.create(null); - this._nsStore = {}; - this.length = 0; - this._ownerDocument = document; - this._readonly = false; -}; -core.NamedNodeMap.prototype = { - get readonly() { return this._readonly;}, - get ownerDocument() { this._ownerDocument;}, - - exists : function(name) { - return (this._nodes[name] || this._nodes[name] === null) ? true : false; - }, - - /* returns Node */ - getNamedItem: function(/* string */ name) { - return this._nodes[name] || null; - }, - - /* returns Node */ - setNamedItem: function(/* Node */ arg) { - - // readonly - if (this._readonly === true) { - throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR); - } - - // arg is from a different document - if (arg && arg._ownerDocument !== this._ownerDocument) { - throw new core.DOMException(WRONG_DOCUMENT_ERR); - } - - // if this argument is already in use.. - if (arg && arg._ownerElement) { - throw new core.DOMException(INUSE_ATTRIBUTE_ERR); - } - - var name = arg.name || arg.tagName; - var ret = this._nodes[name]; - if (!ret) { - this.length++; - ret = null; - } - this._nodes[name] = arg; - - // Avoid overwriting prototype methods etc.: - if (this.hasOwnProperty(name) || !(name in this)) { - this[name] = arg; - } - return ret; - }, // raises: function(DOMException) {}, - - /* returns Node */ - removeNamedItem: function(/* string */ name) { - - // readonly - if (this._readonly === true) { - throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR); - } - - if (!this._nodes[name]) { - throw new core.DOMException(NOT_FOUND_ERR); - } - - var prev = this._nodes[name] || null; - delete this._nodes[name]; - delete this[name]; - - this.length--; - return prev; - }, // raises: function(DOMException) {}, - - /* returns Node */ - item: function(/* int */ index) { - var current = 0; - for (var member in this._nodes) { - if (current === index && this._nodes[member]) { - return this._nodes[member]; - } - current++; - } - return null; - } -}; - -// -// For historical reasons, AttributeList objects must allow accessing -// attributes as if the object were an associative array. For -// instance, if `attributes` is an AttributeList object then -// `attributes.x` should evaluate to the attribute named `x` (which is -// not in any namespace). The AttributeList class uses the dollar -// symbol ($) to reduce the possibility of a clash between its field -// names and possible attribute names. For instance, if the method -// currently named `$set` were instead named `set` then it would not -// be possible to access an attribute named `set` through -// `attributes.set`. The dollar symbol is not valid in attribute names -// so `$set` cannot clash. -// -// Some fields do not get the $ because: -// -// * They are part of the API (e.g. `setNamedItem`, `length`), so they -// must be visible under a specific name. -// -// * Jsdom's code which traverses the DOM tree expects regularly named -// fields (e.g. `_parentNode`). -// -function AttributeList(document, parentNode) { - this._ownerDocument = document; - this._parentNode = parentNode; - this._readonly = false; - this._$ns_to_attrs = Object.create(null); - this._$name_to_attrs = Object.create(null); - this.length = 0; -} - -AttributeList.prototype = { - _$reserved: [], // Initialized later - - - // - // Code internal to jsdom and which manipulates an AttributeList - // object should use the following methods rather than the methods - // that provide the NamedNodeMap interface. - // - - // This method *ignores* namespaces. This is *not* the same thing as - // requesting an attribute with a null namespace. - $getNoNS: function (name) { - var attrs = this._$name_to_attrs[name]; - if (!attrs) { - return null; - } - - return attrs[0] || null; - }, - - $getNode: function (namespace, localName) { - var attrs = this._$ns_to_attrs[namespace]; - if (!attrs) { - return null; - } - - var ret = attrs[localName]; - if (!ret) { - return null; - } - - return ret; - }, - - // This method *ignores* namespaces. This is *not* the same thing as - // requesting an attribute with a null namespace. - $setNoNS: function (name, value, dontValidate) { - var attr = this.$getNoNS(name); - if (!attr) { - this.$set(name, value, undefined, undefined, undefined, dontValidate); - return; - } - - var prev_val = attr.value; - attr.value = value; - - this._parentNode._attrModified(attr.name, attr.value, prev_val); - this._parentNode._modified(); - }, - - $set: function (localName, value, name, prefix, namespace, dontValidate) { - if (this._readonly) { - throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR); - } - - if (name === undefined) { - name = localName; - } - - if (prefix === undefined) { - prefix = null; - } - - if (namespace === undefined) { - namespace = null; - } - - var prev_attr = this.$getNode(namespace, localName); - var attr; - - var prev_val = null; - if (prev_attr) { - prev_val = prev_attr.value; - prev_attr._prefix = prefix; - prev_attr.value = value; - attr = prev_attr; - - this._parentNode._attrModified(attr.name, attr.value, prev_val); - this._parentNode._modified(); - } - else { - var method = dontValidate ? '_createAttributeNoNameValidation' : 'createAttribute'; - attr = this._ownerDocument[method](name); - attr._ownerElement = this._parentNode; - attr.value = value; - attr._namespaceURI = namespace; - attr._prefix = prefix; - attr._localName = localName; - attr._parentNode = this._parentNode; - this.$setNode(attr); - // $setNode calls the parent node methods. - } - }, - - $setNode: function (attr) { - if (this._readonly) { - throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR); - } - - if (attr.nodeType !== ATTRIBUTE_NODE) { - throw new core.DOMException(HIERARCHY_REQUEST_ERR); - } - - if (attr._ownerDocument !== this._ownerDocument) { - throw new core.DOMException(WRONG_DOCUMENT_ERR); - } - - if (attr._parentNode && attr._parentNode !== this._parentNode) { - throw new core.DOMException(INUSE_ATTRIBUTE_ERR); - } - - var localName = attr._localName; - var name = attr.name; - var prefix = attr._prefix; - var namespace = attr._namespaceURI; - - if (name === undefined) { - name = localName; - } - - if (prefix === undefined) { - prefix = null; - } - - if (namespace === undefined) { - namespace = null; - } - - var prev_attr = this.$getNode(namespace, localName); - - var prev_val = null; - if (prev_attr) { - prev_val = prev_attr.value; - // Remove the old attribute - this._$onlyRemoveNode(prev_attr); - } - - attr._parentNode = this._parentNode; - attr._ownerElement = this._parentNode; - - var attrs = this._$ns_to_attrs[namespace]; - if (!attrs) { - attrs = this._$ns_to_attrs[namespace] = Object.create(null); - } - attrs[localName] = attr; - - attrs = this._$name_to_attrs[name]; - if (!attrs) { - attrs = this._$name_to_attrs[name] = [attr]; - } - else { - attrs.push(attr); - } - - // Only attributes in the null namespace can be set this way. - if (namespace === null) { - // Make the node a field on this object but ONLY if it does not - // clash with the reserved names. - if (this._$reserved.indexOf(name) === -1) { - this[name] = attr; - } - } - - this[this.length] = attr; - this.length++; - - this._parentNode._attrModified(attr.name, attr.value, prev_val); - this._parentNode._modified(); - - return prev_attr; - }, - - // This method *ignores* namespaces. This is *not* the same thing as - // requesting an attribute with a null namespace. - $removeNoNS: function (name) { - var attr = this.$getNoNS(name); - return attr ? this.$removeNode(attr) : null; - }, - - $remove: function (namespace, localName) { - var attr = this.$getNode(namespace, localName); - return attr ? this.$removeNode(attr) : null; - }, - - /* Only removes the node, and does not add a default value. */ - _$onlyRemoveNode: function (attr) { - var namespace = attr._namespaceURI; - var localName = attr._localName; - - var attrs = this._$ns_to_attrs[namespace]; - if (!attrs) { - return null; - } - - var found_attr = attrs[localName]; - if (found_attr !== attr) { - return null; - } - - if (this._readonly) { - throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR); - } - - attr._ownerElement = null; - attr._parentNode = null; - delete attrs[localName]; - - attrs = this._$name_to_attrs[attr.name]; - attrs.splice(attrs.indexOf(attr), 1); - - var ix = Array.prototype.indexOf.call(this, attr); - // Splice also modifies length. - Array.prototype.splice.call(this, ix, 1); - - if (this[attr.name] === attr) { - delete this[attr.name]; - } - - this._parentNode._attrModified(attr.name); - this._parentNode._modified(); - - return attr; - }, - - $removeNode: function (attr) { - if (!this._$onlyRemoveNode(attr)) { - return null; - } - return attr; - }, - - // Although http://dom.spec.whatwg.org/#concept-element-attribute - // does not specify that the attributes field on an Element should - // support NamedNodeMap, in practice browsers still support this - // interface so we should support it for compatibility. - - getNamedItem: function (name) { - return this.getNamedItemNS(null, name); - }, - removeNamedItem: function (name) { - return this.removeNamedItemNS(null, name); - }, - item: function (i) { - return this[i]; - }, - getNamedItemNS: function (namespaceURI, localName) { - if (namespaceURI === "") { - namespaceURI = null; - } - - return this.$getNode(namespaceURI, localName); - }, - removeNamedItemNS: function (namespaceURI, localName) { - var ret = this.$remove(namespaceURI, localName); - - if (ret === null) { - throw new core.DOMException(NOT_FOUND_ERR); - } - - return ret; - } -}; - -// Alias these methods. -AttributeList.prototype.setNamedItem = AttributeList.prototype.$setNode; -AttributeList.prototype.setNamedItemNS = AttributeList.prototype.$setNode; - -(function () { - // Construct the list of reserved attribute names from a temporarily - // created AttributeList and from the chain of prototypes. We need - // this because JavaScript code running an a browser expects to be - // able to do el.attributes.x to get the value of the attribute "x" - // on an element. Unfortunately, JavaScript *currently* does not - // allow us to elegantly provide such functionality without risking - // a clash with the fields and methods set on the AttributeList - // object. Hence we need a list of reserved field names. - - var reserved = Object.keys(new AttributeList()); - var prototype = AttributeList.prototype; - while (prototype) { - reserved = reserved.concat(Object.getOwnPropertyNames(prototype)); - prototype = Object.getPrototypeOf(prototype); - } - AttributeList.prototype._$reserved = reserved; -})(); - -core.AttributeList = AttributeList; - -core.Element = function Element(document, localName) { - core.Node.call(this, document); - this._namespaceURI = null; - this._prefix = null; - this._localName = localName; -}; - -inheritFrom(core.Node, core.Element, { - get namespaceURI() { - return this._namespaceURI; - }, - get prefix() { - return this._prefix; - }, - get localName() { - return this._localName; - }, - get tagName() { - var qualifiedName = this._prefix !== null ? this._prefix + ":" + this._localName : this._localName; - if (this.namespaceURI === "http://www.w3.org/1999/xhtml" && this._ownerDocument._parsingMode === "html") { - qualifiedName = qualifiedName.toUpperCase(); - } - return qualifiedName; - }, - - get id() { - var idAttr = this.getAttribute("id"); - if (idAttr === null) { - return ""; - } - return idAttr; - }, - - nodeType : ELEMENT_NODE, - get attributes() { - return this._attributes; - }, - - get sourceIndex() { - /* - * According to QuirksMode: - * Get the sourceIndex of element x. This is also the index number for - * the element in the document.getElementsByTagName('*') array. - * http://www.quirksmode.org/dom/w3c_core.html#t77 - */ - var items = this.ownerDocument.getElementsByTagName('*'), - len = items.length; - - for (var i = 0; i < len; i++) { - if (items[i] === this) { - return i; - } - } - }, - - get outerHTML() { - return domToHtml(this, true); - }, - - get innerHTML() { - var tagName = this.tagName; - if (tagName === 'SCRIPT' || tagName === 'STYLE') { - var type = this.getAttribute('type'); - if (!type || /^text\//i.test(type) || /\/javascript$/i.test(type)) { - return domToHtml(this._childNodes, true, true); - } - } - - // In case of <template> we should pass it's content fragment as a serialization root if we have one - if(tagName === 'TEMPLATE' && - this._namespaceURI === 'http://www.w3.org/1999/xhtml' && - this._childNodes[0] && this._childNodes[0]._templateContent) { - return domToHtml(this._childNodes[0]._childNodes, true); - } - - return domToHtml(this._childNodes, true); - }, - - set innerHTML(html) { - setInnerHTML(this.ownerDocument, this, html); - }, - - scrollTop: 0, - scrollLeft: 0, - - hasAttributes: function () { - return this._attributes.length > 0; - }, - - /* returns Attr */ - setAttributeNode: function(/* Attr */ newAttr) { - var prevNode = this._attributes.$getNode(null, newAttr.name); - if (prevNode) { - prevNode._ownerElement = null; - } - - newAttr._ownerElement = this; - this._attributes.$setNode(newAttr); - - return (prevNode && prevNode.specified) ? prevNode : null; - }, // raises: function(DOMException) {}, - - /* returns Attr */ - removeAttributeNode: function(/* Attr */ oldAttr) { - var ret = this._attributes.$removeNode(oldAttr); - - if (ret !== null) { - return ret; - } - - throw new core.DOMException(NOT_FOUND_ERR); - }, //raises: function(DOMException) {}, - - /* returns NodeList */ - getElementsByTagName: memoizeQuery(function(/* string */ name) { - name = name.toLowerCase(); - - function filterByTagName(child) { - if (child.nodeName && child.nodeType === ELEMENT_NODE) { - return name === "*" || (child.nodeName.toLowerCase() === name); - } - - return false; - } - return new core.NodeList(this._ownerDocument || this, core.mapper(this, filterByTagName, true)); - }), - - getElementsByClassName: function (className) { - - function filterByClassName(child) { - if (!child) { - return false; - } - - var classString = child.className; - if (classString) { - var s = classString.split(" "); - for (var i = 0; i < s.length; i++) { - if (s[i] === className) { - return true; - } - } - } - return false; - } - - return new core.NodeList(this.ownerDocument || this, core.mapper(this, filterByClassName)); - } -}); - -core.DocumentFragment = function DocumentFragment(document) { - core.Node.call(this, document); -}; -inheritFrom(core.Node, core.DocumentFragment, { - nodeType : DOCUMENT_FRAGMENT_NODE -}); - -core.Document = function Document(options) { - if (!options || !options.parsingMode || (options.parsingMode !== "html" && options.parsingMode !== "xml")) { - throw new Error("options must exist and contain a parsingMode of html or xml"); - } - - core.Node.call(this, "#document"); - this._parsingMode = options.parsingMode; - this._implementation = new core.DOMImplementation(this); - this._documentElement = null; - this._ids = Object.create(null); - this._attached = true; - this._ownerDocument = this; - this._readonly = false; - - this._contentType = options.contentType; - if (this._contentType === undefined) { - this._contentType = this._parsingMode === "xml" ? "application/xml" : "text/html"; - } - - this._URL = options.url; - if (this._URL === undefined) { - this._URL = "about:blank"; - } - this._location = new Location(this._URL, this); -}; - - -var tagRegEx = /[^\w:\d_\.-]+/i; -var entRegEx = /[^\w\d_\-&;]+/; -var invalidAttrRegEx = /[\s"'>/=\u0000-\u001A]/; - -inheritFrom(core.Node, core.Document, { - nodeType : DOCUMENT_NODE, - _elementBuilders : { }, - _defaultElementBuilder: function(document, tagName) { - return new core.Element(document, tagName); - }, - get contentType() { return this._contentType;}, - get compatMode() { return (this._parsingMode === "xml" || this.doctype) ? "CSS1Compat" : "BackCompat"; }, - get characterSet() { return "UTF-8"; }, - get inputEncoding() { return "UTF-8"; }, - get doctype() { - for (var i = 0; i < this._childNodes.length; ++i) { - if (this._childNodes[i].nodeType === DOCUMENT_TYPE_NODE) { - return this._childNodes[i]; - } - } - return null; - }, - get URL() { - return this._URL; - }, - get documentURI() { - return this._URL; - }, - get location() { - return this._location; - }, - get documentElement() { - if (this._documentElement) { - return this._documentElement; - } else { - for (var i = 0; i < this._childNodes.length; ++i) { - if (this._childNodes[i].nodeType === ELEMENT_NODE) { - this._documentElement = this._childNodes[i]; - return this._documentElement; - } - } - return null; - } - }, - - get implementation() { return this._implementation;}, - set implementation(implementation) { this._implementation = implementation;}, - get ownerDocument() { return null;}, - get readonly() { return this._readonly;}, - - set parentWindow(window) { - // Contextify does not support getters and setters, so we have to set them - // on the original object instead. - window._frame = function (name, frame) { - if (typeof frame === 'undefined') { - delete window[name]; - } else { - defineGetter(window, name, function () { return frame.contentWindow; }); - } - }; - this._parentWindow = window.getGlobal(); - }, - - get defaultView() { - return this.parentWindow; - }, - - toString: function () { - return '[object HTMLDocument]'; - }, - - _createElementNoTagNameValidation: function (tagName) { - var element = (this._elementBuilders[tagName.toLowerCase()] || this._defaultElementBuilder)(this, tagName); - element._namespaceURI = "http://www.w3.org/1999/xhtml"; - return element; - }, - - createElement: function (localName) { - localName = String(localName); - validateName(localName, core); - if (this._parsingMode === "html") { - localName = localName.toLowerCase(); - } - - return this._createElementNoTagNameValidation(localName); - }, - - /* returns DocumentFragment */ - createDocumentFragment: function() { - return new core.DocumentFragment(this); - }, - - /* returns Attr */ - createAttribute: function (localName) { - localName = String(localName); - validateName(localName, core); - - return this._createAttributeNoNameValidation(localName); - }, // raises: function(DOMException) {}, - - _createAttributeNoNameValidation: function (localName) { - return new core.Attr(this, localName, ""); - }, - - appendChild : function(/* Node */ arg) { - if (this.documentElement && arg.nodeType == ELEMENT_NODE) { - throw new core.DOMException(HIERARCHY_REQUEST_ERR); - } - return core.Node.prototype.appendChild.call(this, arg); - }, - - removeChild : function(/* Node */ arg) { - var ret = core.Node.prototype.removeChild.call(this, arg); - if (arg == this._documentElement) { - this._documentElement = null;// force a recalculation - } - return ret; - }, - - /* returns NodeList */ - getElementsByTagName: memoizeQuery(function(/* string */ name) { - function filterByTagName(child) { - if (child.nodeName && child.nodeType === ELEMENT_NODE) - { - if (name === "*") { - return true; - - // case insensitivity for html - } else if (child._ownerDocument && child._ownerDocument._doctype && - //child._ownerDocument._doctype.name === "html" && - child.nodeName.toLowerCase() === name.toLowerCase()) - { - return true; - } else if (child.nodeName.toLowerCase() === name.toLowerCase()) { - return true; - } - } - return false; - } - return new core.NodeList(this.documentElement || this, core.mapper(this, filterByTagName, true)); - }), - - getElementsByClassName: function (className) { - - function filterByClassName(child) { - if (!child) { - return false; - } - - var classString = child.className; - if (classString) { - var s = classString.split(" "); - for (var i = 0; i < s.length; i++) { - if (s[i] === className) { - return true; - } - } - } - return false; - } - - return new core.NodeList(this.ownerDocument || this, core.mapper(this, filterByClassName)); - }, - - write: function (text) { - if (this._writeAfterElement) { - // If called from an script element directly (during the first tick), - // the new elements are inserted right after that element. - var tempDiv = this.createElement('div'); - setInnerHTML(this, tempDiv, text); - - var child = tempDiv.firstChild; - var previous = this._writeAfterElement; - var parent = this._writeAfterElement.parentNode; - - while (child) { - var node = child; - child = child.nextSibling; - parent.insertBefore(node, previous.nextSibling); - previous = node; - } - } else if (this.readyState === "loading") { - // During page loading, document.write appends to the current element - // Find the last child that has been added to the document. - var node = this; - while (node.lastChild && node.lastChild.nodeType === this.ELEMENT_NODE) { - node = node.lastChild; - } - setInnerHTML(this, node, text || "<html><head></head><body></body></html>"); - } else if (text) { - setInnerHTML(this, this, text); - } - } -}); - -core.Attr = function Attr(document, name, value) { - core.Node.call(this, document); - this._valueForAttrModified = value; - this._name = name; - this._ownerElement = null; - this._namespaceURI = null; - this._localName = name; - this._prefix = null; -}; -inheritFrom(core.Node, core.Attr, { - nodeType : ATTRIBUTE_NODE, - get namespaceURI() { - return this._namespaceURI; - }, - get prefix() { - return this._prefix; - }, - get localName() { - return this._localName; - }, - get name() { - return this._name; - }, - get ownerElement() { - return this._ownerElement; - }, - get nodeValue() { - var val = ''; - for (var i=0,len=this._childNodes.length;i<len;i++) { - var child = this._childNodes[i]; - val += child.nodeValue; - } - return val; - }, - set nodeValue(value) { - // readonly - if (this._readonly) { - throw new core.DOMException(NO_MODIFICATION_ALLOWED_ERR); - } - - this._childNodes.length = 1; - this._childNodes[0] = this._ownerDocument.createTextNode(value); - this._modified(); - var prev = this._valueForAttrModified; - this._nodeValue = value; - if (this._ownerElement) { - this._ownerElement._attrModified(this._name, value, prev); - } - }, - get specified() { - return true; - }, - get value() { - return this.nodeValue; - }, - set value(value) { - this.nodeValue = value; - }, - get parentNode() { return null;}, - - insertBefore : function(/* Node */ newChild, /* Node*/ refChild){ - if (newChild.nodeType === CDATA_SECTION_NODE || - newChild.nodeType === ELEMENT_NODE) - { - throw new core.DOMException(HIERARCHY_REQUEST_ERR); - } - - return core.Node.prototype.insertBefore.call(this, newChild, refChild); - }, - - appendChild : function(/* Node */ arg) { - - if (arg.nodeType === CDATA_SECTION_NODE || - arg.nodeType === ELEMENT_NODE) - { - throw new core.DOMException(HIERARCHY_REQUEST_ERR); - } - - return core.Node.prototype.appendChild.call(this, arg); - } - -}); diff --git a/node_modules/jsdom/lib/jsdom/level2/core.js b/node_modules/jsdom/lib/jsdom/level2/core.js deleted file mode 100644 index 6a52baf..0000000 --- a/node_modules/jsdom/lib/jsdom/level2/core.js +++ /dev/null @@ -1,306 +0,0 @@ -var core = require("../level1/core"); -var defineGetter = require('../utils').defineGetter; -var defineSetter = require('../utils').defineSetter; -var memoizeQuery = require('../utils').memoizeQuery; -var validateQname = require('../living/helpers/validate-names').qname; -var validateAndExtract = require('../living/helpers/validate-names').validateAndExtract; - -core.NamedNodeMap.prototype.getNamedItemNS = function(/* string */ namespaceURI, - /* string */ localName) -{ - if (this._nsStore[namespaceURI] && this._nsStore[namespaceURI][localName]) { - return this._nsStore[namespaceURI][localName]; - } - return null; -}; - -core.NamedNodeMap.prototype.setNamedItemNS = function(/* Node */ arg) -{ - if (this._readonly) { - throw new core.DOMException(core.NO_MODIFICATION_ALLOWED_ERR); - } - - if (this._ownerDocument !== arg.ownerDocument) { - throw new core.DOMException(core.WRONG_DOCUMENT_ERR); - } - - if (arg._ownerElement) { - throw new core.DOMException(core.INUSE_ATTRIBUTE_ERR); - } - - // readonly - if (this._readonly === true) { - throw new core.DOMException(core.NO_MODIFICATION_ALLOWED_ERR); - } - - - if (!this._nsStore[arg.namespaceURI]) { - this._nsStore[arg.namespaceURI] = {}; - } - var existing = null; - if (this._nsStore[arg.namespaceURI][arg.localName]) { - var existing = this._nsStore[arg.namespaceURI][arg.localName]; - } - - this._nsStore[arg.namespaceURI][arg.localName] = arg; - - arg._ownerDocument = this._ownerDocument; - - return this.setNamedItem(arg); -}; - -core.NamedNodeMap.prototype.removeNamedItemNS = function(/*string */ namespaceURI, - /* string */ localName) -{ - - if (this.readonly) { - throw new core.DOMException(core.NO_MODIFICATION_ALLOWED_ERR); - } - - - var parent = this._parentNode, - found = null, - defaults, - clone, - defaultEl, - defaultAttr; - - if (this._nsStore[namespaceURI] && - this._nsStore[namespaceURI][localName]) - { - found = this._nsStore[namespaceURI][localName]; - this.removeNamedItem(found.qualifiedName); - delete this._nsStore[namespaceURI][localName]; - } - - if (!found) { - throw new core.DOMException(core.NOT_FOUND_ERR); - } - - return found; -}; - -core.NamedNodeMap.prototype._map = function(fn) { - var ret = [], l = this.length, i = 0, node; - for(i; i<l; i++) { - node = this.item(i); - if (fn && fn(node)) { - ret.push(node); - } - } - return ret; -}; - -core.Element.prototype.getAttribute = function(/* string */ name) -{ - var attr = this.getAttributeNode(name); - return attr && attr.value; -}; - -core.Element.prototype.getAttributeNode = function(/* string */ name) -{ - return this._attributes.$getNoNS(name); -}; - -core.Element.prototype.removeAttribute = function(/* string */ name) -{ - return this._attributes.$removeNoNS(name); -}; - -core.Element.prototype.getAttributeNS = function(/* string */ namespaceURI, - /* string */ localName) -{ - if (namespaceURI === "") { - namespaceURI = null; - } - - var attr = this._attributes.$getNode(namespaceURI, localName); - return attr && attr.value; -}; - -core.Element.prototype.setAttribute = function(/* string */ name, - /* string */ value) -{ - this._attributes.$setNoNS(name, value); -}; - -core.Element.prototype._setAttributeNoValidation = function (name, value) { - this._attributes.$setNoNS(name, value, true); -}; - -core.Element.prototype.setAttributeNS = function (namespace, name, value) { - namespace = namespace !== null ? String(namespace) : namespace; - name = String(name); - value = String(value); - - var extracted = validateAndExtract(namespace, name, core); - - this._attributes.$set(extracted.localName, value, extracted.qualifiedName, extracted.prefix, extracted.namespace); -}; - -core.Element.prototype.removeAttributeNS = function(/* string */ namespaceURI, - /* string */ localName) -{ - if (namespaceURI === "") { - namespaceURI = null; - } - - this._attributes.$remove(namespaceURI, localName); -}; - -core.Element.prototype.getAttributeNodeNS = function(/* string */ namespaceURI, - /* string */ localName) -{ - if (namespaceURI === "") { - namespaceURI = null; - } - - return this._attributes.$getNode(namespaceURI, localName); -}; - -core.Element.prototype.setAttributeNodeNS = function(/* Attr */ newAttr) -{ - if (newAttr.ownerElement) { - throw new core.DOMException(core.INUSE_ATTRIBUTE_ERR); - } - - return this._attributes.$setNode(newAttr); -}; - -core.Element.prototype.getElementsByTagNameNS = memoizeQuery(function(/* String */ namespaceURI, - /* String */ localName) -{ - var nsPrefixCache = {}; - - function filterByTagName(child) { - var localMatch = child.localName === localName, - nsMatch = child.namespaceURI === namespaceURI; - - if ((localMatch || localName === "*") && - (nsMatch || namespaceURI === "*")) - { - if (child.nodeType === child.ELEMENT_NODE) { - return true; - } - } - return false; - } - - return new core.NodeList(this.ownerDocument || this, - core.mapper(this, filterByTagName)); -}); - -core.Element.prototype.hasAttribute = function(/* string */name) -{ - if (!this._attributes) { - return false; - } - - // Note: you might think you only need the latter condition. However, it makes a test case fail. - // HOWEVER, that test case is for a XML DTD feature called "default attributes" that never was implemented by - // browsers, so when we remove default attributes, we should be able to fix this code too. - return !!this._attributes.$getNoNS(name) || !!this._attributes.$getNoNS(name.toLowerCase()); -}; - -core.Element.prototype.hasAttributeNS = function(/* string */namespaceURI, - /* string */localName) -{ - if (namespaceURI === "") { - namespaceURI = null; - } - - return (this._attributes.getNamedItemNS(namespaceURI, localName) || - this.hasAttribute(localName)); -}; - -core.Document.prototype.importNode = function(/* Node */ importedNode, - /* bool */ deep) -{ - if (importedNode && importedNode.nodeType) { - if (importedNode.nodeType === this.DOCUMENT_NODE || - importedNode.nodeType === this.DOCUMENT_TYPE_NODE) { - throw new core.DOMException(core.NOT_SUPPORTED_ERR); - } - } - - var self = this, - newNode = importedNode.cloneNode(deep, function(a, b) { - b._prefix = a._prefix; - b._namespaceURI = a._namespaceURI; - b._localName = a._localName; - }); - - function lastChance(el) { - var attr, defaultEl, i, len; - - el._ownerDocument = self; - if (el.id) { - if (!self._ids) {self._ids = {};} - if (!self._ids[el.id]) {self._ids[el.id] = [];} - self._ids[el.id].push(el); - } - if (el._attributes) { - var drop = []; - el._attributes._ownerDocument = self; - for (i=0,len=el._attributes.length; i < len; i++) { - attr = el._attributes[i]; - attr._ownerDocument = self; - } - - // Remove obsolete default nodes. - for(i = 0; i < drop.length; ++i) { - el._attributes.$removeNode(drop[i]); - } - - } - } - - if (deep) { - core.visitTree(newNode, lastChance); - } - else { - lastChance(newNode); - } - - return newNode; -}; - -core.Document.prototype.createElementNS = function (namespace, qualifiedName) { - namespace = namespace !== null ? String(namespace) : namespace; - qualifiedName = String(qualifiedName); - - var extracted = validateAndExtract(namespace, qualifiedName, core); - var element = this.createElement(extracted.localName); - element._namespaceURI = extracted.namespace; - element._prefix = extracted.prefix; - - return element; -}; - -core.Document.prototype.createAttributeNS = function (namespace, qualifiedName) { - namespace = namespace !== null ? String(namespace) : namespace; - qualifiedName = String(qualifiedName); - - var extracted = validateAndExtract(namespace, qualifiedName, core); - attribute = this.createAttribute(extracted.qualifiedName); - - attribute._namespaceURI = extracted.namespace; - attribute._prefix = extracted.prefix; - attribute._localName = extracted.localName; - attribute._name = extracted.qualifiedName; - - return attribute; -}; - -core.Document.prototype.getElementsByTagNameNS = function(/* String */ namespaceURI, - /* String */ localName) -{ - return core.Element.prototype.getElementsByTagNameNS.call(this, - namespaceURI, - localName); -}; - -core.Document.prototype.getElementById = function(id) { - // return the first element - return (this._ids && this._ids[id] && this._ids[id].length > 0 ? this._ids[id][0] : null); -}; diff --git a/node_modules/jsdom/lib/jsdom/level2/events.js b/node_modules/jsdom/lib/jsdom/level2/events.js deleted file mode 100644 index 2b19033..0000000 --- a/node_modules/jsdom/lib/jsdom/level2/events.js +++ /dev/null @@ -1,441 +0,0 @@ -/* DOM Level2 Events implemented as described here: - * - * http://www.w3.org/TR/2000/REC-DOM-Level-2-Events-20001113/events.html - * - */ -var core = require("../level1/core"), - utils = require("../utils"), - defineGetter = utils.defineGetter, - defineSetter = utils.defineSetter, - inheritFrom = utils.inheritFrom; - -core.EventException = function() { - if (arguments.length > 0) { - this._code = arguments[0]; - } else { - this._code = 0; - } - if (arguments.length > 1) { - this._message = arguments[1]; - } else { - this._message = "Unspecified event type"; - } - Error.call(this, this._message); - if (Error.captureStackTrace) { - Error.captureStackTrace(this, core.EventException); - } -}; -inheritFrom(Error, core.EventException, { - UNSPECIFIED_EVENT_TYPE_ERR : 0, - get code() { return this._code;} -}); - -core.Event = function(eventType) { - this._eventType = eventType; - this._type = null; - this._bubbles = null; - this._cancelable = null; - this._target = null; - this._currentTarget = null; - this._eventPhase = 0; - this._timeStamp = null; - this._preventDefault = false; - this._stopPropagation = false; -}; -core.Event.prototype = { - initEvent: function(type, bubbles, cancelable) { - this._type = type; - this._bubbles = bubbles; - this._cancelable = cancelable; - }, - preventDefault: function() { - if (this._cancelable) { - this._preventDefault = true; - } - }, - stopPropagation: function() { - this._stopPropagation = true; - }, - NONE : 0, - CAPTURING_PHASE : 1, - AT_TARGET : 2, - BUBBLING_PHASE : 3, - get eventType() { return this._eventType; }, - get type() { return this._type; }, - get bubbles() { return this._bubbles; }, - get cancelable() { return this._cancelable; }, - get target() { return this._target; }, - get currentTarget() { return this._currentTarget; }, - get eventPhase() { return this._eventPhase; }, - get timeStamp() { return this._timeStamp; } -}; - - -core.UIEvent = function(eventType) { - core.Event.call(this, eventType); - this.view = null; - this.detail = null; -}; -inheritFrom(core.Event, core.UIEvent, { - initUIEvent: function(type, bubbles, cancelable, view, detail) { - this.initEvent(type, bubbles, cancelable); - this.view = view; - this.detail = detail; - }, -}); - - -core.MouseEvent = function(eventType) { - core.UIEvent.call(this, eventType); - this.screenX = null; - this.screenY = null; - this.clientX = null; - this.clientY = null; - this.ctrlKey = null; - this.shiftKey = null; - this.altKey = null; - this.metaKey = null; - this.button = null; - this.relatedTarget = null; -}; -inheritFrom(core.UIEvent, core.MouseEvent, { - initMouseEvent: function(type, - bubbles, - cancelable, - view, - detail, - screenX, - screenY, - clientX, - clientY, - ctrlKey, - altKey, - shiftKey, - metaKey, - button, - relatedTarget) { - this.initUIEvent(type, bubbles, cancelable, view, detail); - this.screenX = screenX - this.screenY = screenY - this.clientX = clientX - this.clientY = clientY - this.ctrlKey = ctrlKey - this.shiftKey = shiftKey - this.altKey = altKey - this.metaKey = metaKey - this.button = button - this.relatedTarget = relatedTarget - } -}); - - -core.MutationEvent = function(eventType) { - core.Event.call(this, eventType); - this.relatedNode = null; - this.prevValue = null; - this.newValue = null; - this.attrName = null; - this.attrChange = null; -}; -inheritFrom(core.Event, core.MutationEvent, { - initMutationEvent: function(type, - bubbles, - cancelable, - relatedNode, - prevValue, - newValue, - attrName, - attrChange) { - this.initEvent(type, bubbles, cancelable); - this.relatedNode = relatedNode; - this.prevValue = prevValue; - this.newValue = newValue; - this.attrName = attrName; - this.attrChange = attrChange; - }, - MODIFICATION : 1, - ADDITION : 2, - REMOVAL : 3 -}); - -core.EventTarget = function() {}; - -function getListeners(target, type, capturing) { - var listeners = target._listeners - && target._listeners[type] - && target._listeners[type][capturing] || []; - if (!capturing) { - var traditionalHandler = target['on' + type]; - if (traditionalHandler) { - var implementation = (target._ownerDocument ? target._ownerDocument.implementation - : target.document.implementation); - - if (implementation._hasFeature('ProcessExternalResources', 'script')) { - if (listeners.indexOf(traditionalHandler) < 0) { - listeners.push(traditionalHandler); - } - } - } - } - return listeners; -} - -function dispatchPhase(event, iterator) { - var target = iterator(); - - while (target && !event._stopPropagation) { - if (event._eventPhase === event.CAPTURING_PHASE || event._eventPhase === event.AT_TARGET) { - callListeners(event, target, getListeners(target, event._type, true)); - } - if (event._eventPhase === event.AT_TARGET || event._eventPhase === event.BUBBLING_PHASE) { - callListeners(event, target, getListeners(target, event._type, false)); - } - target = iterator(); - } -} - -function callListeners(event, target, listeners) { - var currentListener = listeners.length; - while (currentListener--) { - event._currentTarget = target; - try { - listeners[currentListener].call(target, event); - } catch (e) { - target.raise( - 'error', "Dispatching event '" + event._type + "' failed", - {error: e, event: event} - ); - } - } -} - -function forwardIterator(list) { - var i = 0, len = list.length; - return function iterator() { return i < len ? list[i++] : null }; -} - -function backwardIterator(list) { - var i = list.length; - return function iterator() { return i >=0 ? list[--i] : null }; -} - -function singleIterator(obj) { - var i = 1; - return function iterator() { return i-- ? obj : null }; -} - -core.EventTarget.prototype = { - addEventListener: function(type, listener, capturing) { - this._listeners = this._listeners || {}; - var listeners = this._listeners[type] || {}; - capturing = (capturing === true); - var capturingListeners = listeners[capturing] || []; - for (var i=0; i < capturingListeners.length; i++) { - if (capturingListeners[i] === listener) { - return; - } - } - capturingListeners.push(listener); - listeners[capturing] = capturingListeners; - this._listeners[type] = listeners; - }, - - removeEventListener: function(type, listener, capturing) { - var listeners = this._listeners && this._listeners[type]; - if (!listeners) return; - var capturingListeners = listeners[(capturing === true)]; - if (!capturingListeners) return; - for (var i=0; i < capturingListeners.length; i++) { - if (capturingListeners[i] === listener) { - capturingListeners.splice(i, 1); - return; - } - } - }, - - dispatchEvent: function(event) { - if (event == null) { - throw new core.EventException(0, "Null event"); - } - if (event._type == null || event._type == "") { - throw new core.EventException(0, "Uninitialized event"); - } - - var targetList = []; - - event._target = this; - - //per the spec we gather the list of targets first to ensure - //against dom modifications during actual event dispatch - var target = this, - targetParent = target._parentNode; - while (targetParent) { - targetList.push(targetParent); - target = targetParent; - targetParent = target._parentNode; - } - targetParent = target._parentWindow; - if (targetParent) { - targetList.push(targetParent); - } - - var iterator = backwardIterator(targetList); - - event._eventPhase = event.CAPTURING_PHASE; - dispatchPhase(event, iterator); - - iterator = singleIterator(event._target); - event._eventPhase = event.AT_TARGET; - dispatchPhase(event, iterator); - - if (event._bubbles) { - iterator = forwardIterator(targetList); - event._eventPhase = event.BUBBLING_PHASE; - dispatchPhase(event, iterator); - } - - event._currentTarget = null; - event._eventPhase = event.NONE; - - return !event._preventDefault; - } - -}; - -// Reinherit class heirarchy with EventTarget at its root -inheritFrom(core.EventTarget, core.Node, core.Node.prototype); - -// Node -inheritFrom(core.Node, core.Attr, core.Attr.prototype); -inheritFrom(core.Node, core.Document, core.Document.prototype); -inheritFrom(core.Node, core.DocumentFragment, core.DocumentFragment.prototype); -inheritFrom(core.Node, core.Element, core.Element.prototype); - - -function getDocument(el) { - return el.nodeType == core.Node.DOCUMENT_NODE ? el : el._ownerDocument; -} - -function mutationEventsEnabled(el) { - return el.nodeType != core.Node.ATTRIBUTE_NODE && - getDocument(el).implementation._hasFeature('MutationEvents'); -} - -var insertBefore_super = core.Node.prototype.insertBefore; -core.Node.prototype.insertBefore = function(newChild, refChild) { - var ret = insertBefore_super.apply(this, arguments); - if (mutationEventsEnabled(this)) { - var doc = getDocument(this), - ev = doc.createEvent("MutationEvents"); - - ev.initMutationEvent("DOMNodeInserted", true, false, this, null, null, null, null); - newChild.dispatchEvent(ev); - if (this.nodeType == core.Node.DOCUMENT_NODE || this._attachedToDocument) { - ev = doc.createEvent("MutationEvents"); - ev.initMutationEvent("DOMNodeInsertedIntoDocument", false, false, null, null, null, null, null); - core.visitTree(newChild, function(el) { - if (el.nodeType == core.Node.ELEMENT_NODE) { - el.dispatchEvent(ev); - el._attachedToDocument = true; - } - }); - } - } - return ret; -}; - -var removeChild_super = core.Node.prototype.removeChild; -core.Node.prototype.removeChild = function (oldChild) { - if (mutationEventsEnabled(this)) { - var doc = getDocument(this), - ev = doc.createEvent("MutationEvents"); - - ev.initMutationEvent("DOMNodeRemoved", true, false, this, null, null, null, null); - oldChild.dispatchEvent(ev); - - ev = doc.createEvent("MutationEvents"); - ev.initMutationEvent("DOMNodeRemovedFromDocument", false, false, null, null, null, null, null); - core.visitTree(oldChild, function(el) { - if (el.nodeType == core.Node.ELEMENT_NODE) { - el.dispatchEvent(ev); - el._attachedToDocument = false; - } - }); - } - return removeChild_super.apply(this, arguments); -}; - -function dispatchAttrEvent(doc, target, prevVal, newVal, attrName, attrChange) { - if (!newVal || newVal != prevVal) { - var ev = doc.createEvent("MutationEvents"); - ev.initMutationEvent("DOMAttrModified", true, false, target, prevVal, - newVal, attrName, attrChange); - target.dispatchEvent(ev); - } -} - -function attrNodeInterceptor(_super, change) { - return function(node) { - var target = this._parentNode, - prev = _super.apply(this, arguments); - - if (mutationEventsEnabled(target)) { - dispatchAttrEvent(target._ownerDocument, - target, - prev && prev.value || null, - change == 'ADDITION' ? node.value : null, - prev && prev.name || node.name, - core.MutationEvent.prototype[change]); - } - - return prev; - }; -} - -function attrInterceptor(_super, ns) { - return function(localName, value, _name, _prefix, _namespace) { - var target = this._parentNode, - namespace = _namespace; // do not reassign parameters when using "arguments" (performance) - - if (!mutationEventsEnabled(target)) { - _super.apply(this, arguments); - return; - } - - if (namespace === undefined) { - namespace = null; - } - - var prev = - ns ? this.$getNode(namespace, localName) : this.$getNoNS(localName); - var prevVal = prev && prev.value || null; - - _super.apply(this, arguments); - - var node = ns ? this.$getNode(namespace, localName): - this.$getNoNS(localName); - - dispatchAttrEvent(target._ownerDocument, - target, - prevVal, - node.value, - node.name, - core.MutationEvent.prototype.ADDITION); - }; -} - - -core.AttributeList.prototype.$removeNode = attrNodeInterceptor(core.AttributeList.prototype.$removeNode, 'REMOVAL'); -core.AttributeList.prototype.$setNode = attrNodeInterceptor(core.AttributeList.prototype.$setNode, 'ADDITION'); -core.AttributeList.prototype.$set = attrInterceptor(core.AttributeList.prototype.$set, true); -core.AttributeList.prototype.$setNoNS = attrInterceptor(core.AttributeList.prototype.$setNoNS, false); - -core.Document.prototype.createEvent = function(eventType) { - switch (eventType) { - case "MutationEvents": return new core.MutationEvent(eventType); - case "UIEvents": return new core.UIEvent(eventType); - case "MouseEvents": return new core.MouseEvent(eventType); - case "HTMLEvents": return new core.Event(eventType); - } - return new core.Event(eventType); -}; diff --git a/node_modules/jsdom/lib/jsdom/level2/html.js b/node_modules/jsdom/lib/jsdom/level2/html.js deleted file mode 100644 index 752f575..0000000 --- a/node_modules/jsdom/lib/jsdom/level2/html.js +++ /dev/null @@ -1,2140 +0,0 @@ -var core = require("../level1/core"), - applyDocumentFeatures = require('../browser/documentfeatures').applyDocumentFeatures, - defineGetter = require('../utils').defineGetter, - defineSetter = require('../utils').defineSetter, - inheritFrom = require("../utils").inheritFrom, - resolveHref = require("../utils").resolveHref, - URL = require("url"), - Path = require('path'), - fs = require("fs"), - http = require('http'), - https = require('https'); - -var isBrowser = Object.prototype.toString.call(process) !== "[object process]"; - -// Setup the javascript language processor -core.languageProcessors = { - javascript : require("./languages/javascript").javascript -}; - -core.resourceLoader = { - load: function(element, href, callback) { - var ownerDoc = element._ownerDocument; - var ownerImplementation = ownerDoc.implementation; - - if (ownerImplementation._hasFeature('FetchExternalResources', element.tagName.toLowerCase())) { - var full = this.resolve(ownerDoc, href); - var url = URL.parse(full); - if (ownerImplementation._hasFeature('SkipExternalResources', full)) { - return false; - } - - var cookie = ownerDoc.cookie; - var cookieDomain = ownerDoc._cookieDomain; - var baseUrl = this.baseUrl(ownerDoc); - var enqueued = this.enqueue(element, callback, full); - - if (typeof ownerDoc._resourceLoader == 'function') { - var fetch = this.fetch.bind(this); - ownerDoc._resourceLoader.call(null, { - url: url, - cookie: cookie, - cookieDomain: cookieDomain, - baseUrl: baseUrl, - defaultFetch: function(callback) { - fetch(this.url, this.cookie, this.cookieDomain, this.baseUrl, callback); - } - }, enqueued); - } else { - this.fetch(url, cookie, cookieDomain, baseUrl, enqueued); - } - } - }, - enqueue: function(element, callback, filename) { - var loader = this, - doc = element.nodeType === core.Node.DOCUMENT_NODE ? - element : - element._ownerDocument; - - if (!doc._queue) { - return function() {}; - } - - return doc._queue.push(function(err, data) { - var ev = doc.createEvent('HTMLEvents'); - - if (!err) { - try { - callback.call(element, data, filename || doc.URL); - ev.initEvent('load', false, false); - } - catch(e) { - err = e; - } - } - - if (err) { - ev.initEvent('error', false, false); - ev.error = err; - } - - element.dispatchEvent(ev); - }); - }, - - baseUrl: function(document) { - var baseElements = document.getElementsByTagName('base'); - var baseUrl = document.URL; - - if (baseElements.length > 0) { - var baseHref = baseElements.item(0).href; - if (baseHref) { - baseUrl = resolveHref(baseUrl, baseHref); - } - } - - return baseUrl; - }, - resolve: function(document, href) { - // if getAttribute returns null, there is no href - // lets resolve to an empty string (nulls are not expected farther up) - if (href === null) { - return ''; - } - - var baseUrl = this.baseUrl(document); - - return resolveHref(baseUrl, href); - }, - fetch: function(url, cookie, cookieDomain, referrer, callback) { - if (url.hostname) { - this.download(url, cookie, cookieDomain, referrer, callback); - } else { - this.readFile(url.pathname, callback); - } - }, - download: function(url, cookie, cookieDomain, referrer, callback) { - var path = (url.pathname || '') + (url.search || ''), - options = {'method': 'GET', 'host': url.hostname, 'path': path}, - request; - if (url.protocol === 'https:') { - options.port = url.port || 443; - request = https.request(options); - } else { - options.port = url.port || 80; - request = http.request(options); - } - - // set header; accomodate browserify - if (referrer && !isBrowser) { - request.setHeader('Referer', referrer); - } - if (cookie) { - var host = url.host.split(':')[0]; - if (host.indexOf(cookieDomain, host.length - cookieDomain.length) !== -1) { - request.setHeader('cookie', cookie); - } - } - - request.on('response', function (response) { - var data = ''; - function success () { - if ([301, 302, 303, 307].indexOf(response.statusCode) > -1) { - var redirect = URL.resolve(url, response.headers["location"]); - core.resourceLoader.download(URL.parse(redirect), cookie, cookieDomain, referrer, callback); - } else { - callback(null, data); - } - } - - // Accomodate browserify - if (response.setEncoding) { - response.setEncoding('utf8'); - } - - response.on('data', function (chunk) { - data += chunk.toString(); - }); - response.on('end', function() { - // According to node docs, 'close' can fire after 'end', but not - // vice versa. Remove 'close' listener so we don't call success twice. - response.removeAllListeners('close'); - success(); - }); - response.on('close', function (err) { - if (err) { - callback(err); - } else { - success(); - } - }); - }); - - request.on('error', callback); - request.end(); - }, - readFile: function(url, callback) { - fs.readFile(url.replace(/^file:\/\//, "").replace(/^\/([a-z]):\//i, '$1:/').replace(/%20/g, ' '), 'utf8', callback); - } -}; - -function define(elementClass, def) { - var tagName = def.tagName, - tagNames = def.tagNames || (tagName? [tagName] : []), - parentClass = def.parentClass || core.HTMLElement, - attrs = def.attributes || [], - proto = def.proto || {}; - - var elem = core[elementClass] = function(document, name) { - parentClass.call(this, document, name || tagName.toUpperCase()); - if (elem._init) { - elem._init.call(this); - } - }; - elem._init = def.init; - - inheritFrom(parentClass, elem, proto); - - attrs.forEach(function(n) { - var prop = n.prop || n, - attr = n.attr || prop.toLowerCase(); - - if (!n.prop || n.read !== false) { - defineGetter(elem.prototype, prop, function() { - var s = this.getAttribute(attr); - if (n.type && n.type === 'boolean') { - return s !== null; - } - if (n.type && n.type === 'long') { - return +s; - } - if (typeof n === 'object' && n.normalize) { // see GH-491 - return n.normalize(s); - } - if (s === null) { - s = ''; - } - return s; - }); - } - - if (!n.prop || n.write !== false) { - defineSetter(elem.prototype, prop, function(val) { - if (!val) { - this.removeAttribute(attr); - } - else { - var s = val.toString(); - if (typeof n === 'object' && n.normalize) { - s = n.normalize(s); - } - this.setAttribute(attr, s); - } - }); - } - }); - - tagNames.forEach(function(tag) { - core.Document.prototype._elementBuilders[tag.toLowerCase()] = function(doc, s) { - var el = new elem(doc, s); - - if (def.elementBuilder) { - return def.elementBuilder(el, doc, s); - } - - return el; - }; - }); -} - - - -core.HTMLCollection = function HTMLCollection(element, query) { - this._keys = []; - core.NodeList.call(this, element, query); -}; -inheritFrom(core.NodeList, core.HTMLCollection, { - namedItem: function(name) { - // Try property shortcut; should work in most cases - if (Object.prototype.hasOwnProperty.call(this, name)) { - return this[name]; - } - - var results = this._toArray(), - l = results.length, - node, - matchingName = null; - - for (var i=0; i<l; i++) { - node = results[i]; - if (node.getAttribute('id') === name) { - return node; - } else if (node.getAttribute('name') === name) { - matchingName = node; - } - } - return matchingName; - }, - toString: function() { - return '[ jsdom HTMLCollection ]: contains ' + this.length + ' items'; - }, - _resetTo: function(array) { - var i, _this = this; - - for (i = 0; i < this._keys.length; ++i) { - delete this[this._keys[i]]; - } - this._keys = []; - - core.NodeList.prototype._resetTo.apply(this, arguments); - - function testAttr(node, attr) { - var val = node.getAttribute(attr); - if (val && !Object.prototype.hasOwnProperty.call(_this, val)) { - _this[val] = node; - _this._keys.push(val); - } - } - for (i = 0; i < array.length; ++i) { - testAttr(array[i], 'id'); - } - for (i = 0; i < array.length; ++i) { - testAttr(array[i], 'name'); - } - } -}); -Object.defineProperty(core.HTMLCollection.prototype, 'constructor', { - value: core.NodeList, - writable: true, - configurable: true -}); - -core.HTMLOptionsCollection = core.HTMLCollection; - -function closest(e, tagName) { - tagName = tagName.toUpperCase(); - while (e) { - if (e.nodeName.toUpperCase() === tagName || - (e.tagName && e.tagName.toUpperCase() === tagName)) - { - return e; - } - e = e._parentNode; - } - return null; -} - -function descendants(e, tagName, recursive) { - var owner = recursive ? e._ownerDocument || e : e; - return new core.HTMLCollection(owner, core.mapper(e, function(n) { - return n.tagName === tagName; - }, recursive)); -} - -function firstChild(e, tagName) { - if (!e) { - return null; - } - var c = descendants(e, tagName, false); - return c.length > 0 ? c[0] : null; -} - -function ResourceQueue(paused) { - this.paused = !!paused; -} -ResourceQueue.prototype = { - push: function(callback) { - var q = this; - var item = { - prev: q.tail, - check: function() { - if (!q.paused && !this.prev && this.fired){ - callback(this.err, this.data); - if (this.next) { - this.next.prev = null; - this.next.check(); - }else{//q.tail===this - q.tail = null; - } - } - } - }; - if (q.tail) { - q.tail.next = item; - } - q.tail = item; - return function(err, data) { - item.fired = 1; - item.err = err; - item.data = data; - item.check(); - }; - }, - resume: function() { - if(!this.paused){ - return; - } - this.paused = false; - var head = this.tail; - while(head && head.prev){ - head = head.prev; - } - if(head){ - head.check(); - } - } -}; - -core.HTMLDocument = function HTMLDocument(options) { - core.Document.call(this, options); - this._referrer = options.referrer; - this._cookie = options.cookie; - this._cookieDomain = options.cookieDomain || '127.0.0.1'; - this._documentRoot = options.documentRoot || Path.dirname(this._URL); - this._queue = new ResourceQueue(options.deferClose); - this._resourceLoader = options.resourceLoader; - this.readyState = 'loading'; - - // Add level2 features - this.implementation._addFeature('core' , '2.0'); - this.implementation._addFeature('html' , '2.0'); - this.implementation._addFeature('xhtml' , '2.0'); - this.implementation._addFeature('xml' , '2.0'); -}; - -inheritFrom(core.Document, core.HTMLDocument, { - _referrer : "", - get referrer() { - return this._referrer || ''; - }, - get domain() { - return ""; - }, - get images() { - return this.getElementsByTagName('IMG'); - }, - get applets() { - return new core.HTMLCollection(this, core.mapper(this, function(el) { - if (el && el.tagName) { - var upper = el.tagName.toUpperCase(); - if (upper === "APPLET") { - return true; - } else if (upper === "OBJECT" && - el.getElementsByTagName('APPLET').length > 0) - { - return true; - } - } - })); - }, - get links() { - return new core.HTMLCollection(this, core.mapper(this, function(el) { - if (el && el.tagName) { - var upper = el.tagName.toUpperCase(); - if (upper === "AREA" || (upper === "A" && el.href)) { - return true; - } - } - })); - }, - get forms() { - return this.getElementsByTagName('FORM'); - }, - get anchors() { - return this.getElementsByTagName('A'); - }, - open : function() { - this._childNodes = []; - this._documentElement = null; - this._modified(); - }, - close : function() { - this._queue.resume(); - // Set the readyState to 'complete' once all resources are loaded. - // As a side-effect the document's load-event will be dispatched. - core.resourceLoader.enqueue(this, function() { - this.readyState = 'complete'; - var ev = this.createEvent('HTMLEvents'); - ev.initEvent('DOMContentLoaded', false, false); - this.dispatchEvent(ev); - })(null, true); - }, - - // document.write is defined in browser/index.js. - - writeln : function(text) { - this.write(text + '\n'); - }, - - getElementsByName : function(elementName) { - return new core.HTMLCollection(this, core.mapper(this, function(el) { - return (el.getAttribute && el.getAttribute("name") === elementName); - })); - }, - - get title() { - var head = this.head, - title = head ? firstChild(head, 'TITLE') : null; - return title ? title.textContent : ''; - }, - - set title(val) { - var title = firstChild(this.head, 'TITLE'); - if (!title) { - title = this.createElement('TITLE'); - var head = this.head; - if (!head) { - head = this.createElement('HEAD'); - this.documentElement.insertBefore(head, this.documentElement.firstChild); - } - head.appendChild(title); - } - title.textContent = val; - }, - - get head() { - return firstChild(this.documentElement, 'HEAD'); - }, - - set head(unused) { /* noop */ }, - - get body() { - var body = firstChild(this.documentElement, 'BODY'); - if (!body) { - body = firstChild(this.documentElement, 'FRAMESET'); - } - return body; - }, - - _cookie : "", - get cookie() { - var cookies = Array.isArray(this._cookie) ? - this._cookie : - (this._cookie && this._cookie.length > 0 ? [this._cookie] : []); - - return cookies.map(function (x) { - return x.split(';')[0]; - }).join('; '); - }, - set cookie(val) { - if (val == null) return val; - var key = val.split('=')[0]; - var cookies = Array.isArray(this._cookie) ? - this._cookie : - (this._cookie && this._cookie.length > 0 ? [this._cookie] : []); - for (var i = 0; i < cookies.length; i++) { - if (cookies[i].lastIndexOf(key + '=', 0) === 0) { - cookies[i] = val; - key = null; - break; - } - } - if (key) { - cookies.push(val); - } - if (cookies.length === 1) { - this._cookie = cookies[0]; - } else { - this._cookie = cookies; - } - return val; - } -}); - -define('HTMLElement', { - parentClass: core.Element, - proto : { - // Add default event behavior (click link to navigate, click button to submit - // form, etc). We start by wrapping dispatchEvent so we can forward events to - // the element's _eventDefault function (only events that did not incur - // preventDefault). - dispatchEvent : function (event) { - var outcome = core.Node.prototype.dispatchEvent.call(this, event) - - if (!event._preventDefault && - event.target._eventDefaults[event.type] && - typeof event.target._eventDefaults[event.type] === 'function') - { - event.target._eventDefaults[event.type](event) - } - return outcome; - }, - getBoundingClientRect: function () { - return { - bottom: 0, - height: 0, - left: 0, - right: 0, - top: 0, - width: 0 - }; - }, - focus : function() { - this._ownerDocument.activeElement = this; - }, - blur : function() { - this._ownerDocument.activeElement = this._ownerDocument.body; - }, - _eventDefaults : {} - }, - attributes: [ - 'id', - 'title', - 'lang', - 'dir', - {prop: 'className', attr: 'class', normalize: function(s) { return s || ''; }} - ] -}); - -core.Document.prototype._defaultElementBuilder = function(document, tagName) { - return new core.HTMLElement(document, tagName); -}; - -// http://www.whatwg.org/specs/web-apps/current-work/#category-listed -var listedElements = /button|fieldset|input|keygen|object|select|textarea/i; - -define('HTMLFormElement', { - tagName: 'FORM', - proto: { - _descendantAdded: function(parent, child) { - var form = this; - core.visitTree(child, function(el) { - if (typeof el._changedFormOwner === 'function') { - el._changedFormOwner(form); - } - }); - - core.HTMLElement.prototype._descendantAdded.apply(this, arguments); - }, - _descendantRemoved: function(parent, child) { - core.visitTree(child, function(el) { - if (typeof el._changedFormOwner === 'function') { - el._changedFormOwner(null); - } - }); - - core.HTMLElement.prototype._descendantRemoved.apply(this, arguments); - }, - get elements() { - return new core.HTMLCollection(this._ownerDocument, core.mapper(this, function(e) { - return listedElements.test(e.nodeName) ; // TODO exclude <input type="image"> - })); - }, - get length() { - return this.elements.length; - }, - _dispatchSubmitEvent: function() { - var ev = this._ownerDocument.createEvent('HTMLEvents'); - ev.initEvent('submit', true, true); - if (!this.dispatchEvent(ev)) { - this.submit(); - }; - }, - submit: function() { - }, - reset: function() { - this.elements._toArray().forEach(function(el) { - if (typeof el._formReset === 'function') { - el._formReset(); - } - }); - } - }, - attributes: [ - 'name', - {prop: 'acceptCharset', attr: 'accept-charset'}, - 'action', - 'enctype', - 'method', - 'target' - ] -}); - -define('HTMLLinkElement', { - tagName: 'LINK', - proto: { - get href() { - return core.resourceLoader.resolve(this._ownerDocument, this.getAttribute('href')); - } - }, - attributes: [ - {prop: 'disabled', type: 'boolean'}, - 'charset', - 'href', - 'hreflang', - 'media', - 'rel', - 'rev', - 'target', - 'type' - ] -}); - -define('HTMLMetaElement', { - tagName: 'META', - attributes: [ - 'content', - {prop: 'httpEquiv', attr: 'http-equiv'}, - 'name', - 'scheme' - ] -}); - -define('HTMLHtmlElement', { - tagName: 'HTML', - attributes: [ - 'version' - ] -}); - -define('HTMLHeadElement', { - tagName: 'HEAD', - attributes: [ - 'profile' - ] -}); - -define('HTMLTitleElement', { - tagName: 'TITLE', - proto: { - get text() { - return this.innerHTML; - }, - set text(s) { - this.innerHTML = s; - } - } -}); - -define('HTMLBaseElement', { - tagName: 'BASE', - attributes: [ - 'href', - 'target' - ] -}); - - -//**Deprecated** -define('HTMLIsIndexElement', { - tagName : 'ISINDEX', - parentClass : core.Element, - proto : { - get form() { - return closest(this, 'FORM'); - } - }, - attributes : [ - 'prompt' - ] -}); - - -define('HTMLStyleElement', { - tagName: 'STYLE', - attributes: [ - {prop: 'disabled', type: 'boolean'}, - 'media', - 'type', - ] -}); - -define('HTMLBodyElement', { - proto: (function() { - var proto = {}; - // The body element's "traditional" event handlers are proxied to the - // window object. - // See: http://www.whatwg.org/specs/web-apps/current-work/#the-body-element - ['onafterprint', 'onbeforeprint', 'onbeforeunload', 'onblur', 'onerror', - 'onfocus', 'onhashchange', 'onload', 'onmessage', 'onoffline', 'ononline', - 'onpagehide', 'onpageshow', 'onpopstate', 'onresize', 'onscroll', - 'onstorage', 'onunload'].forEach(function (name) { - defineSetter(proto, name, function (handler) { - this._ownerDocument.parentWindow[name] = handler; - }); - defineGetter(proto, name, function () { - return this._ownerDocument.parentWindow[name]; - }); - }); - return proto; - })(), - tagName: 'BODY', - attributes: [ - 'aLink', - 'background', - 'bgColor', - 'link', - 'text', - 'vLink' - ] -}); - -define('HTMLSelectElement', { - tagName: 'SELECT', - proto: { - _formReset: function() { - this.options._toArray().forEach(function(option, i) { - option._selectedness = option.defaultSelected; - option._dirtyness = false; - }); - this._askedForAReset(); - }, - _askedForAReset: function() { - if (this.hasAttribute('multiple')) { - return; - } - - var options = this.options._toArray(); - var selected = options.filter(function(option){ - return option._selectedness; - }); - - // size = 1 is default if not multiple - if ((!this.size || this.size === 1) && !selected.length) { - // select the first option that is not disabled - for (var i = 0; i < options.length; ++i) { - var option = options[i]; - var disabled = option.disabled; - if (option._parentNode && - option._parentNode.nodeName.toUpperCase() === 'OPTGROUP' && - option._parentNode.disabled) { - disabled = true; - } - - if (!disabled) { - // (do not set dirty) - option._selectedness = true; - break; - } - } - } else if (selected.length >= 2) { - // select the last selected option - selected.forEach(function(option, index) { - option._selectedness = index === selected.length - 1; - }); - } - }, - _descendantAdded: function(parent, child) { - if (child.nodeType === core.Node.ELEMENT_NODE) { - this._askedForAReset(); - } - - core.HTMLElement.prototype._descendantAdded.apply(this, arguments); - }, - _descendantRemoved: function(parent, child) { - if (child.nodeType === core.Node.ELEMENT_NODE) { - this._askedForAReset(); - } - - core.HTMLElement.prototype._descendantRemoved.apply(this, arguments); - }, - _attrModified: function(name, value) { - if (name === 'multiple' || name === 'size') { - this._askedForAReset(); - } - core.HTMLElement.prototype._attrModified.apply(this, arguments); - }, - get options() { - return new core.HTMLOptionsCollection(this, core.mapper(this, function(n) { - return n.nodeName === 'OPTION'; - })); - }, - - get length() { - return this.options.length; - }, - - get selectedIndex() { - return this.options._toArray().reduceRight(function(prev, option, i) { - return option.selected ? i : prev; - }, -1); - }, - - set selectedIndex(index) { - this.options._toArray().forEach(function(option, i) { - option.selected = i === index; - }); - }, - - get value() { - var i = this.selectedIndex; - if (this.options.length && (i === -1)) { - i = 0; - } - if (i === -1) { - return ''; - } - return this.options[i].value; - }, - - set value(val) { - var self = this; - this.options._toArray().forEach(function(option) { - if (option.value === val) { - option.selected = true; - } else { - if (!self.hasAttribute('multiple')) { - // Remove the selected bit from all other options in this group - // if the multiple attr is not present on the select - option.selected = false; - } - } - }); - }, - - get form() { - return closest(this, 'FORM'); - }, - - get type() { - return this.multiple ? 'select-multiple' : 'select-one'; - }, - - add: function(opt, before) { - if (before) { - this.insertBefore(opt, before); - } - else { - this.appendChild(opt); - } - }, - - remove: function(index) { - var opts = this.options._toArray(); - if (index >= 0 && index < opts.length) { - var el = opts[index]; - el._parentNode.removeChild(el); - } - } - - }, - attributes: [ - {prop: 'disabled', type: 'boolean'}, - {prop: 'multiple', type: 'boolean'}, - 'name', - {prop: 'size', type: 'long'}, - {prop: 'tabIndex', type: 'long'}, - ] -}); - -define('HTMLOptGroupElement', { - tagName: 'OPTGROUP', - attributes: [ - {prop: 'disabled', type: 'boolean'}, - 'label' - ] -}); - -define('HTMLOptionElement', { - tagName: 'OPTION', - proto: { - // whenever selectedness is set to true, make sure all - // other options set selectedness to false - _selectedness: false, - _dirtyness: false, - _removeOtherSelectedness: function() { - //Remove the selectedness flag from all other options in this select - var select = this._selectNode; - - if (select && !select.multiple) { - var o = select.options; - for (var i = 0; i < o.length; i++) { - if (o[i] !== this) { - o[i]._selectedness = false; - } - } - } - }, - _askForAReset: function() { - var select = this._selectNode; - if (select) { - select._askedForAReset(); - } - }, - _attrModified: function(name, value) { - if (!this._dirtyness && name === 'selected') { - this._selectedness = this.defaultSelected; - if (this._selectedness) { - this._removeOtherSelectedness(); - } - this._askForAReset(); - } - core.HTMLElement.prototype._attrModified.apply(this, arguments); - }, - get _selectNode() { - var select = this._parentNode; - if (!select) return null; - if (select.nodeName.toUpperCase() !== 'SELECT') { - select = select._parentNode; - if (!select) return null; - if (select.nodeName.toUpperCase() !== 'SELECT') return null; - } - return select; - }, - get form() { - return closest(this, 'FORM'); - }, - get defaultSelected() { - return this.getAttribute('selected') !== null; - }, - set defaultSelected(s) { - if (s) this.setAttribute('selected', 'selected'); - else this.removeAttribute('selected'); - }, - get text() { - return this.innerHTML; - }, - get value() { - return (this.hasAttribute('value')) ? this.getAttribute('value') : this.innerHTML; - }, - set value(val) { - this.setAttribute('value', val); - }, - get index() { - return closest(this, 'SELECT').options._toArray().indexOf(this); - }, - get selected() { - return this._selectedness; - }, - set selected(s) { - this._dirtyness = true; - this._selectedness = !!s; - if (this._selectedness) { - this._removeOtherSelectedness(); - } - this._askForAReset(); - } - }, - attributes: [ - {prop: 'disabled', type: 'boolean'}, - 'label' - ] -}); - -define('HTMLInputElement', { - tagName: 'INPUT', - init: function() { - if (!this.type) { - this.type = 'text'; - } - }, - proto: { - _value: null, - _dirtyValue: false, - _checkedness: false, - _dirtyCheckedness: false, - _attrModified: function(name, value) { - if (!this._dirtyValue && name === 'value') { - this._value = this.defaultValue; - } - if (!this._dirtyCheckedness && name === 'checked') { - this._checkedness = this.defaultChecked; - if (this._checkedness) { - this._removeOtherRadioCheckedness(); - } - } - - if (name === 'name' || name === 'type') { - if (this._checkedness) { - this._removeOtherRadioCheckedness(); - } - } - - core.HTMLElement.prototype._attrModified.apply(this, arguments); - }, - _formReset: function() { - this._value = this.defaultValue; - this._dirtyValue = false; - this._checkedness = this.defaultChecked; - this._dirtyCheckedness = false; - if (this._checkedness) { - this._removeOtherRadioCheckedness(); - } - }, - _changedFormOwner: function(newForm) { - if (this._checkedness) { - this._removeOtherRadioCheckedness(); - } - }, - _removeOtherRadioCheckedness: function() { - var root = this._radioButtonGroupRoot; - if (!root) { - return; - } - - var name = this.name.toLowerCase(); - var radios = new core.HTMLCollection(this, core.mapper(root, function(el) { - return el.type === 'radio' && - el.name && - el.name.toLowerCase() === name && - el._radioButtonGroupRoot === root; - })); - - radios._toArray().forEach(function(radio) { - if (radio !== this) { - radio._checkedness = false; - } - }, this); - }, - get _radioButtonGroupRoot() { - if (this.type !== 'radio' || !this.name) { - return null; - } - - var e = this._parentNode; - while (e) { - // root node of this home sub tree - // or the form element we belong to - if (!e._parentNode || e.nodeName.toUpperCase() === 'FORM') { - return e; - } - e = e._parentNode; - } - return null; - }, - get form() { - return closest(this, 'FORM'); - }, - get defaultValue() { - var val = this.getAttribute('value'); - return val !== null ? val : ""; - }, - set defaultValue(val) { - this.setAttribute('value', String(val)); - }, - get defaultChecked() { - return this.getAttribute('checked') !== null; - }, - set defaultChecked(s) { - if (s) this.setAttribute('checked', 'checked'); - else this.removeAttribute('checked'); - }, - get checked() { - return this._checkedness; - }, - set checked(checked) { - this._checkedness = !!checked; - this._dirtyCheckedness = true; - if (this._checkedness) { - this._removeOtherRadioCheckedness(); - } - }, - get value() { - if (this._value === null) { - return ''; - } - return this._value; - }, - set value(val) { - this._dirtyValue = true; - if (val === null) { - this._value = null; - } else { - this._value = String(val); - } - }, - get type() { - var type = this.getAttribute('type'); - return type ? type : 'text'; - }, - set type(type) { - this.setAttribute('type', type); - }, - select: function() { - }, - - _dispatchClickEvent: function() { - var event = this._ownerDocument.createEvent("HTMLEvents"); - event.initEvent("click", true, true); - this.dispatchEvent(event); - }, - - click: function() { - if (this.type === 'checkbox') { - this.checked = !this.checked; - } - else if (this.type === 'radio') { - this.checked = true; - } - else if (this.type === 'submit') { - var form = this.form; - if (form) { - form._dispatchSubmitEvent(); - } - } - this._dispatchClickEvent(); - } - }, - attributes: [ - 'accept', - 'accessKey', - 'align', - 'alt', - {prop: 'disabled', type: 'boolean'}, - {prop: 'maxLength', type: 'long'}, - 'name', - {prop: 'readOnly', type: 'boolean'}, - {prop: 'size', type: 'long'}, - 'src', - {prop: 'tabIndex', type: 'long'}, - {prop: 'type', normalize: function(val) { - return val ? val.toLowerCase() : 'text'; - }}, - 'useMap' - ] -}); - -define('HTMLTextAreaElement', { - tagName: 'TEXTAREA', - proto: { - _apiValue: null, - _dirtyValue: false, - // "raw value" and "value" are not used here because jsdom has no GUI - _formReset: function() { - this._apiValue = null; - this._dirtyValue = false; - }, - get form() { - return closest(this, 'FORM'); - }, - get defaultValue() { - return this.textContent; - }, - set defaultValue(val) { - this.textContent = val; - }, - get value() { - // The WHATWG specifies that when "textContent" changes, the "raw value" - // (just the API value in jsdom) must also be updated. - // This slightly different solution has identical results, but is a lot less complex. - if (this._dirtyValue) { - if (this._apiValue === null) { - return ''; - } - return this._apiValue; - } - - var val = this.defaultValue; - val = val.replace(/\r\n|\r/g, '\n'); // API value normalizes line breaks per WHATWG - return val; - }, - set value(val) { - if (val) { - val = val.replace(/\r\n|\r/g, '\n'); // API value normalizes line breaks per WHATWG - } - - this._dirtyValue = true; - this._apiValue = val; - }, - get textLength() { - return this.value.length; // code unit length (16 bit) - }, - get type() { - return 'textarea'; - }, - select: function() { - } - }, - attributes: [ - 'accessKey', - {prop: 'cols', type: 'long'}, - {prop: 'disabled', type: 'boolean'}, - {prop: 'maxLength', type: 'long'}, - 'name', - {prop: 'readOnly', type: 'boolean'}, - {prop: 'rows', type: 'long'}, - {prop: 'tabIndex', type: 'long'} - ] -}); - -define('HTMLButtonElement', { - tagName: 'BUTTON', - proto: { - get form() { - return closest(this, 'FORM'); - } - }, - attributes: [ - 'accessKey', - {prop: 'disabled', type: 'boolean'}, - 'name', - {prop: 'tabIndex', type: 'long'}, - 'type', - 'value' - ] -}); - -define('HTMLLabelElement', { - tagName: 'LABEL', - proto: { - get form() { - return closest(this, 'FORM'); - } - }, - attributes: [ - 'accessKey', - {prop: 'htmlFor', attr: 'for'} - ] -}); - -define('HTMLFieldSetElement', { - tagName: 'FIELDSET', - proto: { - get form() { - return closest(this, 'FORM'); - } - } -}); - -define('HTMLLegendElement', { - tagName: 'LEGEND', - proto: { - get form() { - return closest(this, 'FORM'); - } - }, - attributes: [ - 'accessKey', - 'align' - ] -}); - -define('HTMLUListElement', { - tagName: 'UL', - attributes: [ - {prop: 'compact', type: 'boolean'}, - 'type' - ] -}); - -define('HTMLOListElement', { - tagName: 'OL', - attributes: [ - {prop: 'compact', type: 'boolean'}, - {prop: 'start', type: 'long'}, - 'type' - ] -}); - -define('HTMLDListElement', { - tagName: 'DL', - attributes: [ - {prop: 'compact', type: 'boolean'} - ] -}); - -define('HTMLDirectoryElement', { - tagName: 'DIR', - attributes: [ - {prop: 'compact', type: 'boolean'} - ] -}); - -define('HTMLMenuElement', { - tagName: 'MENU', - attributes: [ - {prop: 'compact', type: 'boolean'} - ] -}); - -define('HTMLLIElement', { - tagName: 'LI', - attributes: [ - 'type', - {prop: 'value', type: 'long'} - ] -}); - -define('HTMLCanvasElement', { - tagName: 'CANVAS', - attributes: [ - 'align' - ], - elementBuilder: function (element) { - // require node-canvas and catch the error if it blows up - try { - var canvas = new (require('canvas'))(0,0); - for (var attr in element) { - if (!canvas[attr]) { - canvas[attr] = element[attr]; - } - } - return canvas; - } catch (e) { - return element; - } - } -}); - -define('HTMLDivElement', { - tagName: 'DIV', - attributes: [ - 'align' - ], - proto: { - toString: function() { return '[object HTMLDivElement]'; } - } -}); - -define('HTMLParagraphElement', { - tagName: 'P', - attributes: [ - 'align' - ] -}); - -define('HTMLHeadingElement', { - tagNames: ['H1','H2','H3','H4','H5','H6'], - attributes: [ - 'align' - ] -}); - -define('HTMLQuoteElement', { - tagNames: ['Q','BLOCKQUOTE'], - attributes: [ - 'cite' - ] -}); - -define('HTMLPreElement', { - tagName: 'PRE', - attributes: [ - {prop: 'width', type: 'long'} - ] -}); - -define('HTMLBRElement', { - tagName: 'BR', - attributes: [ - 'clear' - ] -}); - -define('HTMLBaseFontElement', { - tagName: 'BASEFONT', - attributes: [ - 'color', - 'face', - {prop: 'size', type: 'long'} - ] -}); - -define('HTMLFontElement', { - tagName: 'FONT', - attributes: [ - 'color', - 'face', - 'size' - ] -}); - -define('HTMLHRElement', { - tagName: 'HR', - attributes: [ - 'align', - {prop: 'noShade', type: 'boolean'}, - 'size', - 'width' - ] -}); - -define('HTMLModElement', { - tagNames: ['INS', 'DEL'], - attributes: [ - 'cite', - 'dateTime' - ] -}); - -define('HTMLAnchorElement', { - tagName: 'A', - - proto: { - get href() { - return core.resourceLoader.resolve(this._ownerDocument, this.getAttribute('href')); - }, - get hostname() { - return URL.parse(this.href).hostname || ''; - }, - get host() { - return URL.parse(this.href).host || ''; - }, - get origin() { - var proto = URL.parse(this.href).protocol; - - if (proto !== undefined && proto !== null) { - proto += '//'; - } - - return proto + URL.parse(this.href).host || ''; - }, - get port() { - return URL.parse(this.href).port || ''; - }, - get protocol() { - var protocol = URL.parse(this.href).protocol; - return (protocol == null) ? ':' : protocol; - }, - get password() { - var auth = URL.parse(this.href).auth; - return auth.substr(auth.indexOf(':') + 1); - }, - get pathname() { - return URL.parse(this.href).pathname || ''; - }, - get username() { - var auth = URL.parse(this.href).auth; - return auth.substr(0, auth.indexOf(':')); - }, - get search() { - return URL.parse(this.href).search || ''; - }, - get hash() { - return URL.parse(this.href).hash || ''; - } - }, - attributes: [ - 'accessKey', - 'charset', - 'coords', - {prop: 'href', type: 'string', read: false}, - 'hreflang', - 'name', - 'rel', - 'rev', - 'shape', - {prop: 'tabIndex', type: 'long'}, - 'target', - 'type' - ] -}); - -define('HTMLImageElement', { - tagName: 'IMG', - proto: { - _attrModified: function(name, value, oldVal) { - if (name == 'src' && value !== oldVal) { - core.resourceLoader.enqueue(this, function() {})(); - } - }, - get src() { - return core.resourceLoader.resolve(this._ownerDocument, this.getAttribute('src')); - } - }, - attributes: [ - 'name', - 'align', - 'alt', - 'border', - {prop: 'height', type: 'long'}, - {prop: 'hspace', type: 'long'}, - {prop: 'isMap', type: 'boolean'}, - 'longDesc', - {prop: 'src', type: 'string', read: false}, - 'useMap', - {prop: 'vspace', type: 'long'}, - {prop: 'width', type: 'long'} - ] -}); - -define('HTMLObjectElement', { - tagName: 'OBJECT', - proto: { - get form() { - return closest(this, 'FORM'); - }, - get contentDocument() { - return null; - } - }, - attributes: [ - 'code', - 'align', - 'archive', - 'border', - 'codeBase', - 'codeType', - 'data', - {prop: 'declare', type: 'boolean'}, - {prop: 'height', type: 'long'}, - {prop: 'hspace', type: 'long'}, - 'name', - 'standby', - {prop: 'tabIndex', type: 'long'}, - 'type', - 'useMap', - {prop: 'vspace', type: 'long'}, - {prop: 'width', type: 'long'} - ] -}); - -define('HTMLParamElement', { - tagName: 'PARAM', - attributes: [ - 'name', - 'type', - 'value', - 'valueType' - ] -}); - -define('HTMLAppletElement', { - tagName: 'APPLET', - attributes: [ - 'align', - 'alt', - 'archive', - 'code', - 'codeBase', - 'height', - {prop: 'hspace', type: 'long'}, - 'name', - 'object', - {prop: 'vspace', type: 'long'}, - 'width' - ] -}); - -define('HTMLMapElement', { - tagName: 'MAP', - proto: { - get areas() { - return this.getElementsByTagName("AREA"); - } - }, - attributes: [ - 'name' - ] -}); - -define('HTMLAreaElement', { - tagName: 'AREA', - attributes: [ - 'accessKey', - 'alt', - 'coords', - 'href', - {prop: 'noHref', type: 'boolean'}, - 'shape', - {prop: 'tabIndex', type: 'long'}, - 'target' - ] -}); - -define('HTMLScriptElement', { - tagName: 'SCRIPT', - init: function() { - this.addEventListener('DOMNodeInsertedIntoDocument', function() { - if (this.src) { - core.resourceLoader.load(this, this.src, this._eval); - } - else { - var src = this.sourceLocation || {}, - filename = src.file || this._ownerDocument.URL; - - if (src) { - filename += ':' + src.line + ':' + src.col; - } - filename += '<script>'; - - core.resourceLoader.enqueue(this, this._eval, filename)(null, this.text); - } - }); - }, - proto: { - _eval: function(text, filename) { - if (this._ownerDocument.implementation._hasFeature("ProcessExternalResources", "script") && - this.language && - core.languageProcessors[this.language]) - { - this._ownerDocument._writeAfterElement = this; - core.languageProcessors[this.language](this, text, filename); - delete this._ownerDocument._writeAfterElement; - } - }, - get language() { - var type = this.type || "text/javascript"; - return type.split("/").pop().toLowerCase(); - }, - get text() { - var i=0, children = this._childNodes, l = children.length, ret = []; - - for (i; i<l; i++) { - ret.push(children[i].nodeValue); - } - - return ret.join(""); - }, - set text(text) { - while (this._childNodes.length) { - this.removeChild(this._childNodes[this._childNodes.length-1]); - } - this.appendChild(this._ownerDocument.createTextNode(text)); - } - }, - attributes : [ - {prop: 'defer', 'type': 'boolean'}, - 'htmlFor', - 'event', - 'charset', - 'type', - 'src' - ] -}) - -define('HTMLTableElement', { - tagName: 'TABLE', - proto: { - get caption() { - return firstChild(this, 'CAPTION'); - }, - get tHead() { - return firstChild(this, 'THEAD'); - }, - get tFoot() { - return firstChild(this, 'TFOOT'); - }, - get rows() { - if (!this._rows) { - var table = this; - this._rows = new core.HTMLCollection(this._ownerDocument, function() { - var sections = [table.tHead].concat(table.tBodies._toArray(), table.tFoot).filter(function(s) { return !!s }); - - if (sections.length === 0) { - return core.mapDOMNodes(table, false, function(el) { - return el.tagName === 'TR'; - }); - } - - return sections.reduce(function(prev, s) { - return prev.concat(s.rows._toArray()); - }, []); - - }); - } - return this._rows; - }, - get tBodies() { - if (!this._tBodies) { - this._tBodies = descendants(this, 'TBODY', false); - } - return this._tBodies; - }, - createTHead: function() { - var el = this.tHead; - if (!el) { - el = this._ownerDocument.createElement('THEAD'); - this.appendChild(el); - } - return el; - }, - deleteTHead: function() { - var el = this.tHead; - if (el) { - el._parentNode.removeChild(el); - } - }, - createTFoot: function() { - var el = this.tFoot; - if (!el) { - el = this._ownerDocument.createElement('TFOOT'); - this.appendChild(el); - } - return el; - }, - deleteTFoot: function() { - var el = this.tFoot; - if (el) { - el._parentNode.removeChild(el); - } - }, - createCaption: function() { - var el = this.caption; - if (!el) { - el = this._ownerDocument.createElement('CAPTION'); - this.appendChild(el); - } - return el; - }, - deleteCaption: function() { - var c = this.caption; - if (c) { - c._parentNode.removeChild(c); - } - }, - insertRow: function(index) { - var tr = this._ownerDocument.createElement('TR'); - if (this._childNodes.length === 0) { - this.appendChild(this._ownerDocument.createElement('TBODY')); - } - var rows = this.rows._toArray(); - if (index < -1 || index > rows.length) { - throw new core.DOMException(core.INDEX_SIZE_ERR); - } - if (index === -1 || (index === 0 && rows.length === 0)) { - this.tBodies.item(0).appendChild(tr); - } - else if (index === rows.length) { - var ref = rows[index-1]; - ref._parentNode.appendChild(tr); - } - else { - var ref = rows[index]; - ref._parentNode.insertBefore(tr, ref); - } - return tr; - }, - deleteRow: function(index) { - var rows = this.rows._toArray(), l = rows.length; - if (index === -1) { - index = l-1; - } - if (index < 0 || index >= l) { - throw new core.DOMException(core.INDEX_SIZE_ERR); - } - var tr = rows[index]; - tr._parentNode.removeChild(tr); - } - }, - attributes: [ - 'align', - 'bgColor', - 'border', - 'cellPadding', - 'cellSpacing', - 'frame', - 'rules', - 'summary', - 'width' - ] -}); - -define('HTMLTableCaptionElement', { - tagName: 'CAPTION', - attributes: [ - 'align' - ] -}); - -define('HTMLTableColElement', { - tagNames: ['COL','COLGROUP'], - attributes: [ - 'align', - {prop: 'ch', attr: 'char'}, - {prop: 'chOff', attr: 'charoff'}, - {prop: 'span', type: 'long'}, - 'vAlign', - 'width', - ] -}); - -define('HTMLTableSectionElement', { - tagNames: ['THEAD','TBODY','TFOOT'], - proto: { - get rows() { - if (!this._rows) { - this._rows = descendants(this, 'TR', false); - } - return this._rows; - }, - insertRow: function(index) { - var tr = this._ownerDocument.createElement('TR'); - var rows = this.rows._toArray(); - if (index < -1 || index > rows.length) { - throw new core.DOMException(core.INDEX_SIZE_ERR); - } - if (index === -1 || index === rows.length) { - this.appendChild(tr); - } - else { - var ref = rows[index]; - this.insertBefore(tr, ref); - } - return tr; - }, - deleteRow: function(index) { - var rows = this.rows._toArray(); - if (index === -1) { - index = rows.length-1; - } - if (index < 0 || index >= rows.length) { - throw new core.DOMException(core.INDEX_SIZE_ERR); - } - var tr = this.rows[index]; - this.removeChild(tr); - } - }, - attributes: [ - 'align', - {prop: 'ch', attr: 'char'}, - {prop: 'chOff', attr: 'charoff'}, - {prop: 'span', type: 'long'}, - 'vAlign', - 'width', - ] -}); - -define('HTMLTableRowElement', { - tagName: 'TR', - proto: { - get cells() { - if (!this._cells) { - this._cells = new core.HTMLCollection(this, core.mapper(this, function(n) { - return n.nodeName === 'TD' || n.nodeName === 'TH'; - }, false)); - } - return this._cells; - }, - get rowIndex() { - var table = closest(this, 'TABLE'); - return table ? table.rows._toArray().indexOf(this) : -1; - }, - - get sectionRowIndex() { - return this._parentNode.rows._toArray().indexOf(this); - }, - insertCell: function(index) { - var td = this._ownerDocument.createElement('TD'); - var cells = this.cells._toArray(); - if (index < -1 || index > cells.length) { - throw new core.DOMException(core.INDEX_SIZE_ERR); - } - if (index === -1 || index === cells.length) { - this.appendChild(td); - } - else { - var ref = cells[index]; - this.insertBefore(td, ref); - } - return td; - }, - deleteCell: function(index) { - var cells = this.cells._toArray(); - if (index === -1) { - index = cells.length-1; - } - if (index < 0 || index >= cells.length) { - throw new core.DOMException(core.INDEX_SIZE_ERR); - } - var td = this.cells[index]; - this.removeChild(td); - } - }, - attributes: [ - 'align', - 'bgColor', - {prop: 'ch', attr: 'char'}, - {prop: 'chOff', attr: 'charoff'}, - 'vAlign' - ] -}); - -define('HTMLTableCellElement', { - tagNames: ['TH','TD'], - proto: { - _headers: null, - set headers(h) { - if (h === '') { - //Handle resetting headers so the dynamic getter returns a query - this._headers = null; - return; - } - if (!(h instanceof Array)) { - h = [h]; - } - this._headers = h; - }, - get headers() { - if (this._headers) { - return this._headers.join(' '); - } - var cellIndex = this.cellIndex, - headings = [], - siblings = this._parentNode.getElementsByTagName(this.tagName); - - for (var i=0; i<siblings.length; i++) { - if (siblings.item(i).cellIndex >= cellIndex) { - break; - } - headings.push(siblings.item(i).id); - } - this._headers = headings; - return headings.join(' '); - }, - get cellIndex() { - return closest(this, 'TR').cells._toArray().indexOf(this); - } - }, - attributes: [ - 'abbr', - 'align', - 'axis', - 'bgColor', - {prop: 'ch', attr: 'char'}, - {prop: 'chOff', attr: 'charoff'}, - {prop: 'colSpan', type: 'long'}, - 'height', - {prop: 'noWrap', type: 'boolean'}, - {prop: 'rowSpan', type: 'long'}, - 'scope', - 'vAlign', - 'width' - ] -}); - -define('HTMLFrameSetElement', { - tagName: 'FRAMESET', - attributes: [ - 'cols', - 'rows' - ] -}); - -function loadFrame (frame) { - if (frame._contentDocument) { - // We don't want to access document.parentWindow, since the getter will - // cause a new window to be allocated if it doesn't exist. Probe the - // private variable instead. - if (frame._contentDocument._parentWindow) { - // close calls delete on its document. - frame._contentDocument.parentWindow.close(); - } else { - delete frame._contentDocument; - } - } - - var src = frame.src.trim() === '' ? 'about:blank' : frame.src; - var parentDoc = frame._ownerDocument; - - // If the URL can't be resolved or the src attribute is missing / blank, - // then url should be set to the string "about:blank". - // (http://www.whatwg.org/specs/web-apps/current-work/#the-iframe-element) - var url = core.resourceLoader.resolve(parentDoc, src); - var contentDoc = frame._contentDocument = new core.HTMLDocument({ - parsingMode: 'html', - url: url, - documentRoot: Path.dirname(url) - }); - applyDocumentFeatures(contentDoc, parentDoc.implementation._features); - - var parent = parentDoc.parentWindow; - var contentWindow = contentDoc.parentWindow; - contentWindow.parent = parent; - contentWindow.top = parent.top; - - // Handle about:blank with a simulated load of an empty document. - if(url === 'about:blank') { - core.resourceLoader.enqueue(frame, function() { - contentDoc.write(); - contentDoc.close(); - })(); - } else { - core.resourceLoader.load(frame, url, function(html, filename) { - contentDoc.write(html); - contentDoc.close(); - }); - } -} - -define('HTMLFrameElement', { - tagName: 'FRAME', - init : function () { - // Set up the frames array. window.frames really just returns a reference - // to the window object, so the frames array is just implemented as indexes - // on the window. - var parent = this._ownerDocument.parentWindow; - var frameID = parent._length++; - var self = this; - defineGetter(parent, frameID, function () { - return self.contentWindow; - }); - - // The contentDocument/contentWindow shouldn't be created until the frame - // is inserted: - // "When an iframe element is first inserted into a document, the user - // agent must create a nested browsing context, and then process the - // iframe attributes for the first time." - // (http://www.whatwg.org/specs/web-apps/current-work/#the-iframe-element) - this._initInsertListener = function () { - loadFrame(self); - }; - this.addEventListener('DOMNodeInsertedIntoDocument', this._initInsertListener, false); - }, - proto: { - _attrModified: function(name, value, oldVal) { - core.HTMLElement.prototype._attrModified.call(this, name, value, oldVal); - var self = this; - if (name === 'name') { - // Remove named frame access. - if (oldVal) { - this._ownerDocument.parentWindow._frame(oldVal); - } - // Set up named frame access. - if (value) { - this._ownerDocument.parentWindow._frame(value, this); - } - } else if (name === 'src') { - // Page we don't fetch the page until the node is inserted. This at - // least seems to be the way Chrome does it. - if (!this._attachedToDocument) { - if (!this._waitingOnInsert) { - // First, remove the listener added in 'init'. - this.removeEventListener('DOMNodeInsertedIntoDocument', - this._initInsertListener, false) - - // If we aren't already waiting on an insert, add a listener. - // This guards against src being set multiple times before the frame - // is inserted into the document - we don't want to register multiple - // callbacks. - this.addEventListener('DOMNodeInsertedIntoDocument', function loader () { - self.removeEventListener('DOMNodeInsertedIntoDocument', loader, false); - this._waitingOnInsert = false; - loadFrame(self); - }, false); - this._waitingOnInsert = true; - } - } else { - loadFrame(self); - } - } - }, - _contentDocument : null, - get contentDocument() { - if (this._contentDocument == null) { - this._contentDocument = new core.HTMLDocument({ parsingMode: "html" }); - } - return this._contentDocument; - }, - get contentWindow() { - return this.contentDocument.parentWindow; - } - }, - attributes: [ - 'frameBorder', - 'longDesc', - 'marginHeight', - 'marginWidth', - 'name', - {prop: 'noResize', type: 'boolean'}, - 'scrolling', - {prop: 'src', type: 'string', write: false} - ] -}); - -define('HTMLIFrameElement', { - tagName: 'IFRAME', - parentClass: core.HTMLFrameElement, - attributes: [ - 'align', - 'frameBorder', - 'height', - 'longDesc', - 'marginHeight', - 'marginWidth', - 'name', - 'scrolling', - 'src', - 'width' - ] -}); diff --git a/node_modules/jsdom/lib/jsdom/level2/languages/javascript.js b/node_modules/jsdom/lib/jsdom/level2/languages/javascript.js deleted file mode 100644 index 308724d..0000000 --- a/node_modules/jsdom/lib/jsdom/level2/languages/javascript.js +++ /dev/null @@ -1,13 +0,0 @@ -exports.javascript = function(element, code, filename) { - var doc = element.ownerDocument, window = doc && doc.parentWindow; - if (window) { - try { - window.run(code, filename); - } catch (e) { - element.raise( - 'error', 'Running ' + filename + ' failed.', - {error: e, filename: filename} - ); - } - } -}; diff --git a/node_modules/jsdom/lib/jsdom/level2/style.js b/node_modules/jsdom/lib/jsdom/level2/style.js deleted file mode 100644 index ab63fcc..0000000 --- a/node_modules/jsdom/lib/jsdom/level2/style.js +++ /dev/null @@ -1,263 +0,0 @@ -var core = require("../level1/core"), - utils = require("../utils"), - defineGetter = utils.defineGetter, - defineSetter = utils.defineSetter, - inheritFrom = utils.inheritFrom, - cssom = require("cssom"), - cssstyle = require("cssstyle"), - assert = require('assert'); - -// What works now: -// - Accessing the rules defined in individual stylesheets -// - Modifications to style content attribute are reflected in style property -// - Modifications to style property are reflected in style content attribute -// TODO -// - Modifications to style element's textContent are reflected in sheet property. -// - Modifications to style element's sheet property are reflected in textContent. -// - Modifications to link.href property are reflected in sheet property. -// - Less-used features of link: disabled -// - Less-used features of style: disabled, scoped, title -// - CSSOM-View -// - getComputedStyle(): requires default stylesheet, cascading, inheritance, -// filtering by @media (screen? print?), layout for widths/heights -// - Load events are not in the specs, but apparently some browsers -// implement something. Should onload only fire after all @imports have been -// loaded, or only the primary sheet? - -core.StyleSheet = cssom.StyleSheet; -core.MediaList = cssom.MediaList; -core.CSSStyleSheet = cssom.CSSStyleSheet; -core.CSSRule = cssom.CSSRule; -core.CSSStyleRule = cssom.CSSStyleRule; -core.CSSMediaRule = cssom.CSSMediaRule; -core.CSSImportRule = cssom.CSSImportRule; -core.CSSStyleDeclaration = cssstyle.CSSStyleDeclaration; - -// Relavant specs -// http://www.w3.org/TR/DOM-Level-2-Style (2000) -// http://www.w3.org/TR/cssom-view/ (2008) -// http://dev.w3.org/csswg/cssom/ (2010) Meant to replace DOM Level 2 Style -// http://www.whatwg.org/specs/web-apps/current-work/multipage/ HTML5, of course -// http://dev.w3.org/csswg/css-style-attr/ not sure what's new here - -// Objects that aren't in cssom library but should be: -// CSSRuleList (cssom just uses array) -// CSSFontFaceRule -// CSSPageRule - -// These rules don't really make sense to implement, so CSSOM draft makes them -// obsolete. -// CSSCharsetRule -// CSSUnknownRule - -// These objects are considered obsolete by CSSOM draft, although modern -// browsers implement them. -// CSSValue -// CSSPrimitiveValue -// CSSValueList -// RGBColor -// Rect -// Counter - -// StyleSheetList - -// http://www.w3.org/TR/DOM-Level-2-Style/stylesheets.html#StyleSheets-StyleSheetList -// added a push method to help manage the length -core.StyleSheetList = function() { - this._length = 0; -}; -core.StyleSheetList.prototype = { - item: function (i) { - return this[i]; - }, - push: function (sheet) { - this[this._length] = sheet; - this._length++; - }, - get length() { - return this._length; - } -}; - -defineGetter(core.Document.prototype, 'styleSheets', function() { - if (!this._styleSheets) { - this._styleSheets = new core.StyleSheetList(); - } - // TODO: each style and link element should register its sheet on creation - // and remove it on removal. - return this._styleSheets; -}); - - -/** - * @this {core.HTMLLinkElement|core.HTMLStyleElement} - * @param {string} url - * @param {cssom.CSSStyleSheet} sheet - * @see http://dev.w3.org/csswg/cssom/#requirements-on-user-agents-implementing0 - */ -function fetchStylesheet(url, sheet) { - core.resourceLoader.load(this, url, function(data, filename) { - // TODO: abort if the content-type is not text/css, and the document is - // in strict mode - sheet.href = core.resourceLoader.resolve(this.ownerDocument, url); - evaluateStylesheet.call(this, data, sheet, url); - }); -} -/** - * @this {core.HTMLLinkElement|core.HTMLStyleElement} - * @param {string} data - * @param {cssom.CSSStyleSheet} sheet - * @param {string} baseUrl - */ -function evaluateStylesheet(data, sheet, baseUrl) { - // this is the element - var newStyleSheet = cssom.parse(data); - var spliceArgs = newStyleSheet.cssRules; - spliceArgs.unshift(0, sheet.cssRules.length); - Array.prototype.splice.apply(sheet.cssRules, spliceArgs); - scanForImportRules.call(this, sheet.cssRules, baseUrl); - this.ownerDocument.styleSheets.push(sheet); -} -/** - * @this {core.HTMLLinkElement|core.HTMLStyleElement} - * @param {cssom.CSSStyleSheet} sheet - * @param {string} baseUrl - */ -function scanForImportRules(cssRules, baseUrl) { - if (!cssRules) return; - for (var i = 0; i < cssRules.length; ++i) { - if (cssRules[i].cssRules) { - // @media rule: keep searching inside it. - scanForImportRules.call(this, cssRules[i].cssRules, baseUrl); - } else if (cssRules[i].href) { - // @import rule: fetch the resource and evaluate it. - // See http://dev.w3.org/csswg/cssom/#css-import-rule - // If loading of the style sheet fails its cssRules list is simply - // empty. I.e. an @import rule always has an associated style sheet. - fetchStylesheet.call(this, cssRules[i].href, this.sheet); - } - } -} - -/** - * @param {string} data - * @param {cssstyle.CSSStyleDeclaration} style - */ -function evaluateStyleAttribute(data) { - // this is the element. - -} - -/** - * Subclass of core.Attr that reflects the current cssText. - */ -function StyleAttr(node, value) { - this._node = node; - core.Attr.call(this, node.ownerDocument, 'style'); - if (!this._node._ignoreValueOfStyleAttr) { - this.nodeValue = value; - } -} -inheritFrom(core.Attr, StyleAttr, { - get nodeValue() { - if (typeof this._node._style === 'string') { - return this._node._style; - } else { - return this._node.style.cssText; - } - }, - set nodeValue(value) { - this._node._style = value; - } -}); - -var $setNode_super = core.AttributeList.prototype.$setNode; -/** - * Overwrite core.AttrNodeMap#setNamedItem to create a StyleAttr instance - * instead of a core.Attr if the name equals 'style'. - */ -core.AttributeList.prototype.$setNode = function(attr) { - if (attr.name == 'style') { - attr = new StyleAttr(this._parentNode, attr.nodeValue); - } - return $setNode_super.call(this, attr); -}; - -/** - * Lazily create a CSSStyleDeclaration. - */ -defineGetter(core.HTMLElement.prototype, 'style', function() { - if (typeof this._style === 'string') { - // currently, cssom's parse doesn't really work if you pass in - // {state: 'name'}, so instead we just build a dummy sheet. - var styleSheet = cssom.parse('dummy{' + this._style + '}'); - this._style = new cssstyle.CSSStyleDeclaration(); - if (styleSheet.cssRules.length > 0 && styleSheet.cssRules[0].style) { - var newStyle = styleSheet.cssRules[0].style; - for (var i = 0; i < newStyle.length; ++i) { - var prop = newStyle[i]; - this._style.setProperty( - prop, - newStyle.getPropertyValue(prop), - newStyle.getPropertyPriority(prop)); - } - } - } - if (!this._style) { - this._style = new cssstyle.CSSStyleDeclaration(); - - } - if (!this.getAttributeNode('style')) { - // Tell the StyleAttr constructor to not overwrite this._style - this._ignoreValueOfStyleAttr = true; - this.setAttribute('style'); - this._ignoreValueOfStyleAttr = false; - } - return this._style; -}); - -assert.equal(undefined, core.HTMLLinkElement._init); -core.HTMLLinkElement._init = function() { - this.addEventListener('DOMNodeInsertedIntoDocument', function() { - if (!/(?:[ \t\n\r\f]|^)stylesheet(?:[ \t\n\r\f]|$)/i.test(this.rel)) { - // rel is a space-separated list of tokens, and the original rel types - // are case-insensitive. - return; - } - if (this.href) { - fetchStylesheet.call(this, this.href, this.sheet); - } - }); - this.addEventListener('DOMNodeRemovedFromDocument', function() { - }); -}; -/** - * @this {HTMLStyleElement|HTMLLinkElement} - */ -var getOrCreateSheet = function() { - if (!this._cssStyleSheet) { - this._cssStyleSheet = new cssom.CSSStyleSheet(); - } - return this._cssStyleSheet; -}; -defineGetter(core.HTMLLinkElement.prototype, 'sheet', getOrCreateSheet); - -assert.equal(undefined, core.HTMLStyleElement._init); -core.HTMLStyleElement._init = function() { - //console.log('init style') - this.addEventListener('DOMNodeInsertedIntoDocument', function() { - //console.log('style inserted') - //console.log('sheet: ', this.sheet); - if (this.type && this.type !== 'text/css') { - //console.log('bad type: ' + this.type) - return; - } - var content = ''; - this._childNodes.forEach(function (child) { - if (child.nodeType === child.TEXT_NODE) { // text node - content += child.nodeValue; - } - }); - evaluateStylesheet.call(this, content, this.sheet, this._ownerDocument.URL); - }); -}; -defineGetter(core.HTMLStyleElement.prototype, 'sheet', getOrCreateSheet); diff --git a/node_modules/jsdom/lib/jsdom/level3/core.js b/node_modules/jsdom/lib/jsdom/level3/core.js deleted file mode 100644 index 0d0820e..0000000 --- a/node_modules/jsdom/lib/jsdom/level3/core.js +++ /dev/null @@ -1,597 +0,0 @@ -var core = require("../level1/core"), - defineGetter = require('../utils').defineGetter, - defineSetter = require('../utils').defineSetter, - HtmlToDom = require('../browser/htmltodom').HtmlToDom, - domToHtml = require('../browser/domtohtml').domToHtml; - -/* - valuetype DOMString sequence<unsigned short>; - typedef unsigned long long DOMTimeStamp; - typedef any DOMUserData; - typedef Object DOMObject; - -*/ -// ExceptionCode -core.VALIDATION_ERR = 16; -core.TYPE_MISMATCH_ERR = 17; - -/* - // Introduced in DOM Level 3: - interface NameList { - DOMString getName(in unsigned long index); - DOMString getNamespaceURI(in unsigned long index); - readonly attribute unsigned long length; - boolean contains(in DOMString str); - boolean containsNS(in DOMString namespaceURI, - in DOMString name); - }; - - // Introduced in DOM Level 3: - interface DOMImplementationList { - DOMImplementation item(in unsigned long index); - readonly attribute unsigned long length; - }; - - // Introduced in DOM Level 3: - interface DOMImplementationSource { - DOMImplementation getDOMImplementation(in DOMString features); - DOMImplementationList getDOMImplementationList(in DOMString features); - }; -*/ - - -core.DOMImplementation.prototype.getFeature = function(feature, version) { - -}; - -/* - interface Node { - // Modified in DOM Level 3: - Node insertBefore(in Node newChild, - in Node refChild) - raises(DOMException); - // Modified in DOM Level 3: - Node replaceChild(in Node newChild, - in Node oldChild) - raises(DOMException); - // Modified in DOM Level 3: - Node removeChild(in Node oldChild) - raises(DOMException); - // Modified in DOM Level 3: - Node appendChild(in Node newChild) - raises(DOMException); - boolean hasChildNodes(); - Node cloneNode(in boolean deep); - // Modified in DOM Level 3: - void normalize(); - // Introduced in DOM Level 3: - readonly attribute DOMString baseURI; -*/ - -// Compare Document Position -var DOCUMENT_POSITION_DISCONNECTED = core.Node.DOCUMENT_POSITION_DISCONNECTED = - core.Node.prototype.DOCUMENT_POSITION_DISCONNECTED = 0x01; - -var DOCUMENT_POSITION_PRECEDING = core.Node.DOCUMENT_POSITION_PRECEDING = - core.Node.prototype.DOCUMENT_POSITION_PRECEDING = 0x02; - -var DOCUMENT_POSITION_FOLLOWING = core.Node.DOCUMENT_POSITION_FOLLOWING = - core.Node.prototype.DOCUMENT_POSITION_FOLLOWING = 0x04; - -var DOCUMENT_POSITION_CONTAINS = core.Node.DOCUMENT_POSITION_CONTAINS = - core.Node.prototype.DOCUMENT_POSITION_CONTAINS = 0x08; - -var DOCUMENT_POSITION_CONTAINED_BY = core.Node.DOCUMENT_POSITION_CONTAINED_BY = - core.Node.prototype.DOCUMENT_POSITION_CONTAINED_BY = 0x10; - -var DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = core.Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = - core.Node.prototype.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20; - -var DOCUMENT_TYPE_NODE = core.Node.prototype.DOCUMENT_TYPE_NODE; - -core.Node.prototype.compareDocumentPosition = function compareDocumentPosition( otherNode ) { - if( !(otherNode instanceof core.Node) ) { - throw Error("Comparing position against non-Node values is not allowed") - } - var thisOwner, otherOwner; - - if( this.nodeType === this.DOCUMENT_NODE) - thisOwner = this - else - thisOwner = this.ownerDocument - - if( otherNode.nodeType === this.DOCUMENT_NODE) - otherOwner = otherNode - else - otherOwner = otherNode.ownerDocument - - if( this === otherNode ) return 0 - if( this === otherNode.ownerDocument ) return DOCUMENT_POSITION_FOLLOWING + DOCUMENT_POSITION_CONTAINED_BY - if( this.ownerDocument === otherNode ) return DOCUMENT_POSITION_PRECEDING + DOCUMENT_POSITION_CONTAINS - if( thisOwner !== otherOwner ) return DOCUMENT_POSITION_DISCONNECTED - - // Text nodes for attributes does not have a _parentNode. So we need to find them as attribute child. - if( this.nodeType === this.ATTRIBUTE_NODE && this._childNodes && this._childNodes.indexOf(otherNode) !== -1) - return DOCUMENT_POSITION_FOLLOWING + DOCUMENT_POSITION_CONTAINED_BY - - if( otherNode.nodeType === this.ATTRIBUTE_NODE && otherNode._childNodes && otherNode._childNodes.indexOf(this) !== -1) - return DOCUMENT_POSITION_PRECEDING + DOCUMENT_POSITION_CONTAINS - - var point = this - var parents = [ ] - var previous = null - while( point ) { - if( point == otherNode ) return DOCUMENT_POSITION_PRECEDING + DOCUMENT_POSITION_CONTAINS - parents.push( point ) - point = point._parentNode - } - point = otherNode - previous = null - while( point ) { - if( point == this ) return DOCUMENT_POSITION_FOLLOWING + DOCUMENT_POSITION_CONTAINED_BY - var location_index = parents.indexOf( point ) - if( location_index !== -1) { - var smallest_common_ancestor = parents[ location_index ] - var this_index = smallest_common_ancestor._childNodes.indexOf( parents[location_index - 1] ) - var other_index = smallest_common_ancestor._childNodes.indexOf( previous ) - if( this_index > other_index ) { - return DOCUMENT_POSITION_PRECEDING - } - else { - return DOCUMENT_POSITION_FOLLOWING - } - } - previous = point - point = point._parentNode - } - return DOCUMENT_POSITION_DISCONNECTED -}; - -// @see http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#Node3-textContent -defineGetter(core.Node.prototype, 'textContent', function() { - switch (this.nodeType) { - case this.COMMENT_NODE: - case this.CDATA_SECTION_NODE: - case this.PROCESSING_INSTRUCTION_NODE: - case this.TEXT_NODE: - return this.nodeValue; - - case this.ATTRIBUTE_NODE: - case this.DOCUMENT_FRAGMENT_NODE: - case this.ELEMENT_NODE: - var out = ''; - for (var i = 0 ; i < this._childNodes.length ; ++i) { - if (this._childNodes[i].nodeType !== this.COMMENT_NODE && - this._childNodes[i].nodeType !== this.PROCESSING_INSTRUCTION_NODE) { - out += this._childNodes[i].textContent || ''; - } - } - return out; - - default: - return null; - } -}); - -defineSetter(core.Node.prototype, 'textContent', function(txt) { - switch (this.nodeType) { - case this.COMMENT_NODE: - case this.CDATA_SECTION_NODE: - case this.PROCESSING_INSTRUCTION_NODE: - case this.TEXT_NODE: - return this.nodeValue = String(txt); - } - - for (var i = this._childNodes.length; --i >=0;) { - this.removeChild(this._childNodes[i]); - } - if (txt !== "" && txt != null) { - this.appendChild(this._ownerDocument.createTextNode(txt)); - } - return txt; -}); - -/* - // Introduced in DOM Level 3: - DOMString lookupPrefix(in DOMString namespaceURI); - // Introduced in DOM Level 3: - boolean isDefaultNamespace(in DOMString namespaceURI); - // Introduced in DOM Level 3: - DOMString lookupNamespaceURI(in DOMString prefix); - // Introduced in DOM Level 3: - DOMObject getFeature(in DOMString feature, - in DOMString version); -*/ -// Introduced in DOM Level 3: -core.Node.prototype.setUserData = function(key, data, handler) { - var r = this[key] || null; - this[key] = data; - return(r); -}; - -// Introduced in DOM Level 3: -core.Node.prototype.getUserData = function(key) { - var r = this[key] || null; - return(r); -}; -/* - interface NodeList { - Node item(in unsigned long index); - readonly attribute unsigned long length; - }; - - interface NamedNodeMap { - Node getNamedItem(in DOMString name); - Node setNamedItem(in Node arg) - raises(DOMException); - Node removeNamedItem(in DOMString name) - raises(DOMException); - Node item(in unsigned long index); - readonly attribute unsigned long length; - // Introduced in DOM Level 2: - Node getNamedItemNS(in DOMString namespaceURI, - in DOMString localName) - raises(DOMException); - // Introduced in DOM Level 2: - Node setNamedItemNS(in Node arg) - raises(DOMException); - // Introduced in DOM Level 2: - Node removeNamedItemNS(in DOMString namespaceURI, - in DOMString localName) - raises(DOMException); - }; - - interface CharacterData : Node { - attribute DOMString data; - // raises(DOMException) on setting - // raises(DOMException) on retrieval - - readonly attribute unsigned long length; - DOMString substringData(in unsigned long offset, - in unsigned long count) - raises(DOMException); - void appendData(in DOMString arg) - raises(DOMException); - void insertData(in unsigned long offset, - in DOMString arg) - raises(DOMException); - void deleteData(in unsigned long offset, - in unsigned long count) - raises(DOMException); - void replaceData(in unsigned long offset, - in unsigned long count, - in DOMString arg) - raises(DOMException); - }; - - interface Attr : Node { - readonly attribute DOMString name; - readonly attribute boolean specified; - attribute DOMString value; - // raises(DOMException) on setting - - // Introduced in DOM Level 2: - readonly attribute Element ownerElement; - // Introduced in DOM Level 3: - readonly attribute TypeInfo schemaTypeInfo; - -*/ - // Introduced in DOM Level 3: -defineGetter(core.Attr.prototype, 'isId', function() { - return (this.name.toLowerCase() === 'id'); -}); -/* - }; - - interface Element : Node { - readonly attribute DOMString tagName; - DOMString getAttribute(in DOMString name); - void setAttribute(in DOMString name, - in DOMString value) - raises(DOMException); - void removeAttribute(in DOMString name) - raises(DOMException); - Attr getAttributeNode(in DOMString name); - Attr setAttributeNode(in Attr newAttr) - raises(DOMException); - Attr removeAttributeNode(in Attr oldAttr) - raises(DOMException); - NodeList getElementsByTagName(in DOMString name); - // Introduced in DOM Level 2: - DOMString getAttributeNS(in DOMString namespaceURI, - in DOMString localName) - raises(DOMException); - // Introduced in DOM Level 2: - void setAttributeNS(in DOMString namespaceURI, - in DOMString qualifiedName, - in DOMString value) - raises(DOMException); - // Introduced in DOM Level 2: - void removeAttributeNS(in DOMString namespaceURI, - in DOMString localName) - raises(DOMException); - // Introduced in DOM Level 2: - Attr getAttributeNodeNS(in DOMString namespaceURI, - in DOMString localName) - raises(DOMException); - // Introduced in DOM Level 2: - Attr setAttributeNodeNS(in Attr newAttr) - raises(DOMException); - // Introduced in DOM Level 2: - NodeList getElementsByTagNameNS(in DOMString namespaceURI, - in DOMString localName) - raises(DOMException); - // Introduced in DOM Level 2: - boolean hasAttribute(in DOMString name); - // Introduced in DOM Level 2: - boolean hasAttributeNS(in DOMString namespaceURI, - in DOMString localName) - raises(DOMException); - // Introduced in DOM Level 3: - readonly attribute TypeInfo schemaTypeInfo; - // Introduced in DOM Level 3: - void setIdAttribute(in DOMString name, - in boolean isId) - raises(DOMException); - // Introduced in DOM Level 3: - void setIdAttributeNS(in DOMString namespaceURI, - in DOMString localName, - in boolean isId) - raises(DOMException); - // Introduced in DOM Level 3: - void setIdAttributeNode(in Attr idAttr, - in boolean isId) - raises(DOMException); - }; - - interface Text : CharacterData { - Text splitText(in unsigned long offset) - raises(DOMException); - // Introduced in DOM Level 3: - readonly attribute boolean isElementContentWhitespace; - // Introduced in DOM Level 3: - readonly attribute DOMString wholeText; - // Introduced in DOM Level 3: - Text replaceWholeText(in DOMString content) - raises(DOMException); - }; - - interface Comment : CharacterData { - }; - - // Introduced in DOM Level 3: - interface TypeInfo { - readonly attribute DOMString typeName; - readonly attribute DOMString typeNamespace; - - // DerivationMethods - const unsigned long DERIVATION_RESTRICTION = 0x00000001; - const unsigned long DERIVATION_EXTENSION = 0x00000002; - const unsigned long DERIVATION_UNION = 0x00000004; - const unsigned long DERIVATION_LIST = 0x00000008; - - boolean isDerivedFrom(in DOMString typeNamespaceArg, - in DOMString typeNameArg, - in unsigned long derivationMethod); - }; -*/ -// Introduced in DOM Level 3: -core.UserDataHandler = function() {}; -core.UserDataHandler.prototype.NODE_CLONED = 1; -core.UserDataHandler.prototype.NODE_IMPORTED = 2; -core.UserDataHandler.prototype.NODE_DELETED = 3; -core.UserDataHandler.prototype.NODE_RENAMED = 4; -core.UserDataHandler.prototype.NODE_ADOPTED = 5; -core.UserDataHandler.prototype.handle = function(operation, key, data, src, dst) {}; - -// Introduced in DOM Level 3: -core.DOMError = function(severity, message, type, relatedException, relatedData, location) { - this._severity = severity; - this._message = message; - this._type = type; - this._relatedException = relatedException; - this._relatedData = relatedData; - this._location = location; -}; -core.DOMError.prototype = {}; -core.DOMError.prototype.SEVERITY_WARNING = 1; -core.DOMError.prototype.SEVERITY_ERROR = 2; -core.DOMError.prototype.SEVERITY_FATAL_ERROR = 3; -defineGetter(core.DOMError.prototype, 'severity', function() { - return this._severity; -}); -defineGetter(core.DOMError.prototype, 'message', function() { - return this._message; -}); -defineGetter(core.DOMError.prototype, 'type', function() { - return this._type; -}); -defineGetter(core.DOMError.prototype, 'relatedException', function() { - return this._relatedException; -}); -defineGetter(core.DOMError.prototype, 'relatedData', function() { - return this._relatedData; -}); -defineGetter(core.DOMError.prototype, 'location', function() { - return this._location; -}); - -/* - // Introduced in DOM Level 3: - interface DOMErrorHandler { - boolean handleError(in DOMError error); - }; - - // Introduced in DOM Level 3: - interface DOMLocator { - readonly attribute long lineNumber; - readonly attribute long columnNumber; - readonly attribute long byteOffset; - readonly attribute long utf16Offset; - readonly attribute Node relatedNode; - readonly attribute DOMString uri; - }; -*/ - -// Introduced in DOM Level 3: -core.DOMConfiguration = function(){ - var possibleParameterNames = { - 'canonical-form': [false, true], // extra rules for true - 'cdata-sections': [true, false], - 'check-character-normalization': [false, true], - 'comments': [true, false], - 'datatype-normalization': [false, true], - 'element-content-whitespace': [true, false], - 'entities': [true, false], - // 'error-handler': [], - 'infoset': [undefined, true, false], // extra rules for true - 'namespaces': [true, false], - 'namespace-declarations': [true, false], // only checked if namespaces is true - 'normalize-characters': [false, true], - // 'schema-location': [], - // 'schema-type': [], - 'split-cdata-sections': [true, false], - 'validate': [false, true], - 'validate-if-schema': [false, true], - 'well-formed': [true, false] - } -}; - -core.DOMConfiguration.prototype = { - setParameter: function(name, value) {}, - getParameter: function(name) {}, - canSetParameter: function(name, value) {}, - parameterNames: function() {} -}; - -//core.Document.prototype._domConfig = new core.DOMConfiguration(); -defineGetter(core.Document.prototype, 'domConfig', function() { - return this._domConfig || new core.DOMConfiguration();; -}); - -// Introduced in DOM Level 3: -core.DOMStringList = function() {}; - -core.DOMStringList.prototype = { - item: function() {}, - length: function() {}, - contains: function() {} -}; - - -/* - interface CDATASection : Text { - }; - - interface DocumentType : Node { - readonly attribute DOMString name; - readonly attribute NamedNodeMap entities; - readonly attribute NamedNodeMap notations; - // Introduced in DOM Level 2: - readonly attribute DOMString publicId; - // Introduced in DOM Level 2: - readonly attribute DOMString systemId; - // Introduced in DOM Level 2: - readonly attribute DOMString internalSubset; - }; - - interface Notation : Node { - readonly attribute DOMString publicId; - readonly attribute DOMString systemId; - }; - - interface Entity : Node { - readonly attribute DOMString publicId; - readonly attribute DOMString systemId; - readonly attribute DOMString notationName; - // Introduced in DOM Level 3: - readonly attribute DOMString inputEncoding; - // Introduced in DOM Level 3: - readonly attribute DOMString xmlEncoding; - // Introduced in DOM Level 3: - readonly attribute DOMString xmlVersion; - }; - - interface EntityReference : Node { - }; - - interface ProcessingInstruction : Node { - readonly attribute DOMString target; - attribute DOMString data; - // raises(DOMException) on setting - - }; - - interface DocumentFragment : Node { - }; - - interface Document : Node { - // Modified in DOM Level 3: - readonly attribute DocumentType doctype; - readonly attribute DOMImplementation implementation; - readonly attribute Element documentElement; - Element createElement(in DOMString tagName) - raises(DOMException); - DocumentFragment createDocumentFragment(); - Text createTextNode(in DOMString data); - Comment createComment(in DOMString data); - CDATASection createCDATASection(in DOMString data) - raises(DOMException); - ProcessingInstruction createProcessingInstruction(in DOMString target, - in DOMString data) - raises(DOMException); - Attr createAttribute(in DOMString name) - raises(DOMException); - EntityReference createEntityReference(in DOMString name) - raises(DOMException); - NodeList getElementsByTagName(in DOMString tagname); - // Introduced in DOM Level 2: - Node importNode(in Node importedNode, - in boolean deep) - raises(DOMException); - // Introduced in DOM Level 2: - Element createElementNS(in DOMString namespaceURI, - in DOMString qualifiedName) - raises(DOMException); - // Introduced in DOM Level 2: - Attr createAttributeNS(in DOMString namespaceURI, - in DOMString qualifiedName) - raises(DOMException); - // Introduced in DOM Level 2: - NodeList getElementsByTagNameNS(in DOMString namespaceURI, - in DOMString localName); - // Introduced in DOM Level 2: - Element getElementById(in DOMString elementId); -*/ -/* - // Introduced in DOM Level 3: - readonly attribute DOMString xmlEncoding; - // Introduced in DOM Level 3: - attribute boolean xmlStandalone; - // raises(DOMException) on setting - - // Introduced in DOM Level 3: - attribute DOMString xmlVersion; - // raises(DOMException) on setting - - // Introduced in DOM Level 3: - attribute boolean strictErrorChecking; - // Introduced in DOM Level 3: - attribute DOMString documentURI; - // Introduced in DOM Level 3: - Node adoptNode(in Node source) - raises(DOMException); - // Introduced in DOM Level 3: - readonly attribute DOMConfiguration domConfig; - // Introduced in DOM Level 3: - void normalizeDocument(); - // Introduced in DOM Level 3: - Node renameNode(in Node n, - in DOMString namespaceURI, - in DOMString qualifiedName) - raises(DOMException); - }; -}; - -#endif // _DOM_IDL_ -*/ diff --git a/node_modules/jsdom/lib/jsdom/level3/ls.js b/node_modules/jsdom/lib/jsdom/level3/ls.js deleted file mode 100644 index 5cc44f4..0000000 --- a/node_modules/jsdom/lib/jsdom/level3/ls.js +++ /dev/null @@ -1,211 +0,0 @@ -// w3c Load/Save functionality: http://www.w3.org/TR/2004/REC-DOM-Level-3-LS-20040407/ - -var core = require('../level1/core'); -var createFrom = require('../utils').createFrom; - -var ls = {}; - -// TODO: what is this? -//typedef dom::DOMConfiguration DOMConfiguration; - -ls.LSException = function LSException(code) { - this.code = code; -}; - -ls.LSException.prototype = { - // LSExceptionCode - PARSE_ERR : 81, - SERIALIZE_ERR : 82 -}; - -ls.DOMImplementationLS = function DOMImplementationLS() { - -}; - -var DOMImplementationExtension = { - - // DOMImplementationLSMode - MODE_SYNCHRONOUS : 1, - MODE_ASYNCHRONOUS : 2, - - // raises(dom::DOMException); - createLSParser : function(/* int */ mode, /* string */ schemaType) { - return new ls.LSParser(mode, schemaType); - }, - - createLSSerializer : function() { - return new ls.LSSerializer(); - }, - - createLSInput : function() { - return new ls.LSInput(); - }, - - createLSOutput : function() { - return new ls.LSOutput(); - } -}; - -Object.keys(DOMImplementationExtension).forEach(function(k, v) { - core.DOMImplementation.prototype[k] = DOMImplementationExtension[k]; -}); - -ls.DOMImplementationLS.prototype = DOMImplementationExtension; - -core.Document.getFeature = function() { - return DOMImplementationExtension; -}; - -ls.LSParser = function LSParser() { - this._domConfig = new core.DOMConfiguration(); -}; -ls.LSParser.prototype = { - get domConfig() { return this._domConfig; }, - get filter() { return this._filter || null; }, - set filter(value) { this._filter = value; }, - get async() { return this._async; }, - get busy() { return this._busy; }, - - // raises(dom::DOMException, LSException); - parse : function (/* LSInput */ input) { - var doc = new core.Document(); - doc._inputEncoding = 'UTF-16'; - return doc; - }, - - // raises(dom::DOMException, LSException); - parseURI : function(/* string */ uri) { - return new core.Document(); - }, - - // ACTION_TYPES - ACTION_APPEND_AS_CHILDREN : 1, - ACTION_REPLACE_CHILDREN : 2, - ACTION_INSERT_BEFORE : 3, - ACTION_INSERT_AFTER : 4, - ACTION_REPLACE : 5, - - // @returns Node - // @raises DOMException, LSException - parseWithContext : function(/* LSInput */ input, /* Node */ contextArg, /* int */ action) { - return new core.Node(); - }, - - abort : function() { - // TODO: implement - } -}; - -ls.LSInput = function LSInput() {}; -ls.LSInput.prototype = { - get characterStream() { return this._characterStream || null; }, - set characterStream(value) { this._characterStream = value; }, - get byteStream() { return this._byteStream || null; }, - set byteStream(value) { this._byteStream = value; }, - get stringData() { return this._stringData || null; }, - set stringData(value) { this._stringData = value; }, - get systemId() { return this._systemId || null; }, - set systemId(value) { this._systemId = value; }, - get publicId() { return this._publicId || null; }, - set publicId(value) { this._publicId = value; }, - get baseURI() { return this._baseURI || null; }, - set baseURI(value) { this._baseURI = value; }, - get encoding() { return this._encoding || null; }, - set encoding(value) { this._encoding = value; }, - get certifiedText() { return this._certifiedText || null; }, - set certifiedText(value) { this._certifiedText = value; }, -}; - -ls.LSResourceResolver = function LSResourceResolver() {}; - -// @returns LSInput -ls.LSResourceResolver.prototype.resolveResource = function(type, namespaceURI, publicId, systemId, baseURI) { - return new ls.LSInput(); -}; - -ls.LSParserFilter = function LSParserFilter() {}; -ls.LSParserFilter.prototype = { - - // Constants returned by startElement and acceptNode - FILTER_ACCEPT : 1, - FILTER_REJECT : 2, - FILTER_SKIP : 3, - FILTER_INTERRUPT : 4, - - get whatToShow() { return this._whatToShow; }, - - // @returns int - startElement : function(/* Element */ elementArg) { - return 0; - }, - - // @returns int - acceptNode : function(/* Node */ nodeArg) { - return nodeArg; - } -}; - -ls.LSSerializer = function LSSerializer() { - this._domConfig = new core.DOMConfiguration(); -}; -ls.LSSerializer.prototype = { - get domConfig() { return this._domConfig; }, - get newLine() { return this._newLine || null; }, - set newLine(value) { this._newLine = value; }, - get filter() { return this._filter || null; }, - set filter(value) { this._filter = value; }, - - // @returns boolean - // @raises LSException - write : function(/* Node */ nodeArg, /* LSOutput */ destination) { - return true; - }, - - // @returns boolean - // @raises LSException - writeToURI : function(/* Node */ nodeArg, /* string */ uri) { - return true; - }, - - // @returns string - // @raises DOMException, LSException - writeToString : function(/* Node */ nodeArg) { - return ""; - } -}; - -ls.LSOutput = function LSOutput() {}; -ls.LSOutput.prototype = { - get characterStream() { return this._characterStream || null; }, - set characterStream(value) { this._characterStream = value; }, - get byteStream() { return this._byteStream || null; }, - set byteStream(value) { this._byteStream = value; }, - get systemId() { return this._systemId || null; }, - set systemId(value) { this._systemId = value; }, - get encoding() { return this._encoding || null; }, - set encoding(value) { this._encoding = value; }, -}; - -ls.LSProgressEvent = function LSProgressEvent() {}; -ls.LSProgressEvent.prototype = createFrom(core.Event, { - constructor: ls.LSProgressEvent, - get input() { return this._input; }, - get position() { return this._position; }, - get totalSize() { return this._totalSize; }, -}); - -ls.LSLoadEvent = function LSLoadEvent() {}; -ls.LSLoadEvent.prototype = createFrom(core.Event, { - get newDocument() { return this._newDocument; }, - get input() { return this._input; }, -}); - - -// TODO: do traversal -ls.LSSerializerFilter = function LSSerializerFilter() {}; -ls.LSSerializerFilter.prototype = { - get whatToShow() { return this._whatToShow; }, -}; - -// ls.LSSerializerFilter.prototype.__proto__ = level2.traversal.NodeFiler; - diff --git a/node_modules/jsdom/lib/jsdom/level3/xpath.js b/node_modules/jsdom/lib/jsdom/level3/xpath.js deleted file mode 100644 index 98e3a7d..0000000 --- a/node_modules/jsdom/lib/jsdom/level3/xpath.js +++ /dev/null @@ -1,1866 +0,0 @@ -/** Here is yet another implementation of XPath 1.0 in Javascript. - * - * My goal was to make it relatively compact, but as I fixed all the axis bugs - * the axes became more and more complicated. :-(. - * - * I have not implemented namespaces or case-sensitive axes for XML yet. - * - * How to test it in Chrome: You can make a Chrome extension that replaces - * the WebKit XPath parser with this one. But it takes a bit of effort to - * get around isolated world and same-origin restrictions: - * manifest.json: - { - "name": "XPathTest", - "version": "0.1", - "content_scripts": [{ - "matches": ["http://localhost/*"], // or wildcard host - "js": ["xpath.js", "injection.js"], - "all_frames": true, "run_at": "document_start" - }] - } - * injection.js: - // goal: give my xpath object to the website's JS context. - var script = document.createElement('script'); - script.textContent = - "document.addEventListener('xpathextend', function(e) {\n" + - " console.log('extending document with xpath...');\n" + - " e.detail(window);" + - "});"; - document.documentElement.appendChild(script); - document.documentElement.removeChild(script); - var evt = document.createEvent('CustomEvent'); - evt.initCustomEvent('xpathextend', true, true, this.xpath.extend); - document.dispatchEvent(evt); - */ -(function() { - var xpath; - var core; - if ('function' === typeof require) { - xpath = exports; // the tests go through this - core = require("../level1/core"); - } else { - xpath = {}; - core = this; - } - - - /*************************************************************************** - * Tokenization * - ***************************************************************************/ - /** - * The XPath lexer is basically a single regular expression, along with - * some helper functions to pop different types. - */ - var Stream = xpath.Stream = function Stream(str) { - this.original = this.str = str; - this.peeked = null; - // TODO: not really needed, but supposedly tokenizer also disambiguates - // a * b vs. node test * - this.prev = null; // for debugging - this.prevprev = null; - } - Stream.prototype = { - peek: function() { - if (this.peeked) return this.peeked; - var m = this.re.exec(this.str); - if (!m) return null; - this.str = this.str.substr(m[0].length); - return this.peeked = m[1]; - }, - /** Peek 2 tokens ahead. */ - peek2: function() { - this.peek(); // make sure this.peeked is set - var m = this.re.exec(this.str); - if (!m) return null; - return m[1]; - }, - pop: function() { - var r = this.peek(); - this.peeked = null; - this.prevprev = this.prev; - this.prev = r; - return r; - }, - trypop: function(tokens) { - var tok = this.peek(); - if (tok === tokens) return this.pop(); - if (Array.isArray(tokens)) { - for (var i = 0; i < tokens.length; ++i) { - var t = tokens[i]; - if (t == tok) return this.pop();; - } - } - }, - trypopfuncname: function() { - var tok = this.peek(); - if (!this.isQnameRe.test(tok)) - return null; - switch (tok) { - case 'comment': case 'text': case 'processing-instruction': case 'node': - return null; - } - if ('(' != this.peek2()) return null; - return this.pop(); - }, - trypopaxisname: function() { - var tok = this.peek(); - switch (tok) { - case 'ancestor': case 'ancestor-or-self': case 'attribute': - case 'child': case 'descendant': case 'descendant-or-self': - case 'following': case 'following-sibling': case 'namespace': - case 'parent': case 'preceding': case 'preceding-sibling': case 'self': - if ('::' == this.peek2()) return this.pop(); - } - return null; - }, - trypopnametest: function() { - var tok = this.peek(); - if ('*' === tok || this.startsWithNcNameRe.test(tok)) return this.pop(); - return null; - }, - trypopliteral: function() { - var tok = this.peek(); - if (null == tok) return null; - var first = tok.charAt(0); - var last = tok.charAt(tok.length - 1); - if ('"' === first && '"' === last || - "'" === first && "'" === last) { - this.pop(); - return tok.substr(1, tok.length - 2); - } - }, - trypopnumber: function() { - var tok = this.peek(); - if (this.isNumberRe.test(tok)) return parseFloat(this.pop()); - else return null; - }, - trypopvarref: function() { - var tok = this.peek(); - if (null == tok) return null; - if ('$' === tok.charAt(0)) return this.pop().substr(1); - else return null; - }, - position: function() { - return this.original.length - this.str.length; - } - }; - (function() { - // http://www.w3.org/TR/REC-xml-names/#NT-NCName - var nameStartCharsExceptColon = - 'A-Z_a-z\xc0-\xd6\xd8-\xf6\xF8-\u02FF\u0370-\u037D\u037F-\u1FFF' + - '\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF' + - '\uFDF0-\uFFFD'; // JS doesn't support [#x10000-#xEFFFF] - var nameCharExceptColon = nameStartCharsExceptColon + - '\\-\\.0-9\xb7\u0300-\u036F\u203F-\u2040'; - var ncNameChars = '[' + nameStartCharsExceptColon + - '][' + nameCharExceptColon + ']*' - // http://www.w3.org/TR/REC-xml-names/#NT-QName - var qNameChars = ncNameChars + '(?::' + ncNameChars + ')?'; - var otherChars = '\\.\\.|[\\(\\)\\[\\].@,]|::'; // .. must come before [.] - var operatorChars = - 'and|or|mod|div|' + - '//|!=|<=|>=|[*/|+\\-=<>]'; // //, !=, <=, >= before individual ones. - var literal = '"[^"]*"|' + "'[^']*'"; - var numberChars = '[0-9]+(?:\\.[0-9]*)?|\\.[0-9]+'; - var variableReference = '\\$' + qNameChars; - var nameTestChars = '\\*|' + ncNameChars + ':\\*|' + qNameChars; - var optionalSpace = '[ \t\r\n]*'; // stricter than regexp \s. - var nodeType = 'comment|text|processing-instruction|node'; - var re = new RegExp( - // numberChars before otherChars so that leading-decimal doesn't become . - '^' + optionalSpace + '(' + numberChars + '|' + otherChars + '|' + - nameTestChars + '|' + operatorChars + '|' + literal + '|' + - variableReference + ')' - // operatorName | nodeType | functionName | axisName are lumped into - // qName for now; we'll check them on pop. - ); - Stream.prototype.re = re; - Stream.prototype.startsWithNcNameRe = new RegExp('^' + ncNameChars); - Stream.prototype.isQnameRe = new RegExp('^' + qNameChars + '$'); - Stream.prototype.isNumberRe = new RegExp('^' + numberChars + '$'); - })(); - - /*************************************************************************** - * Parsing * - ***************************************************************************/ - var parse = xpath.parse = function parse(stream, a) { - var r = orExpr(stream,a); - var x, unparsed = []; - while (x = stream.pop()) { - unparsed.push(x); - } - if (unparsed.length) - throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, - 'Position ' + stream.position() + - ': Unparsed tokens: ' + unparsed.join(' ')); - return r; - } - - /** - * binaryL ::= subExpr - * | binaryL op subExpr - * so a op b op c becomes ((a op b) op c) - */ - function binaryL(subExpr, stream, a, ops) { - var lhs = subExpr(stream, a); - if (lhs == null) return null; - var op; - while (op = stream.trypop(ops)) { - var rhs = subExpr(stream, a); - if (rhs == null) - throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, - 'Position ' + stream.position() + - ': Expected something after ' + op); - lhs = a.node(op, lhs, rhs); - } - return lhs; - } - /** - * Too bad this is never used. If they made a ** operator (raise to power), - ( we would use it. - * binaryR ::= subExpr - * | subExpr op binaryR - * so a op b op c becomes (a op (b op c)) - */ - function binaryR(subExpr, stream, a, ops) { - var lhs = subExpr(stream, a); - if (lhs == null) return null; - var op = stream.trypop(ops); - if (op) { - var rhs = binaryR(stream, a); - if (rhs == null) - throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, - 'Position ' + stream.position() + - ': Expected something after ' + op); - return a.node(op, lhs, rhs); - } else { - return lhs;// TODO - } - } - /** [1] LocationPath::= RelativeLocationPath | AbsoluteLocationPath - * e.g. a, a/b, //a/b - */ - function locationPath(stream, a) { - return absoluteLocationPath(stream, a) || - relativeLocationPath(null, stream, a); - } - /** [2] AbsoluteLocationPath::= '/' RelativeLocationPath? | AbbreviatedAbsoluteLocationPath - * [10] AbbreviatedAbsoluteLocationPath::= '//' RelativeLocationPath - */ - function absoluteLocationPath(stream, a) { - var op = stream.peek(); - if ('/' === op || '//' === op) { - var lhs = a.node('Root'); - return relativeLocationPath(lhs, stream, a, true); - } else { - return null; - } - } - /** [3] RelativeLocationPath::= Step | RelativeLocationPath '/' Step | - * | AbbreviatedRelativeLocationPath - * [11] AbbreviatedRelativeLocationPath::= RelativeLocationPath '//' Step - * e.g. p/a, etc. - */ - function relativeLocationPath(lhs, stream, a, isOnlyRootOk) { - if (null == lhs) { - lhs = step(stream, a); - if (null == lhs) return lhs; - } - var op; - while (op = stream.trypop(['/', '//'])) { - if ('//' === op) { - lhs = a.node('/', lhs, - a.node('Axis', 'descendant-or-self', 'node', undefined)); - } - var rhs = step(stream, a); - if (null == rhs && '/' === op && isOnlyRootOk) return lhs; - else isOnlyRootOk = false; - if (null == rhs) - throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, - 'Position ' + stream.position() + - ': Expected step after ' + op); - lhs = a.node('/', lhs, rhs); - } - return lhs; - } - /** [4] Step::= AxisSpecifier NodeTest Predicate* | AbbreviatedStep - * [12] AbbreviatedStep::= '.' | '..' - * e.g. @href, self::p, p, a[@href], ., .. - */ - function step(stream, a) { - var abbrStep = stream.trypop(['.', '..']); - if ('.' === abbrStep) // A location step of . is short for self::node(). - return a.node('Axis', 'self', 'node'); - if ('..' === abbrStep) // A location step of .. is short for parent::node() - return a.node('Axis', 'parent', 'node'); - - var axis = axisSpecifier(stream, a); - var nodeType = nodeTypeTest(stream, a); - var nodeName; - if (null == nodeType) nodeName = nodeNameTest(stream, a); - if (null == axis && null == nodeType && null == nodeName) return null; - if (null == nodeType && null == nodeName) - throw new XPathException( - XPathException.INVALID_EXPRESSION_ERR, - 'Position ' + stream.position() + - ': Expected nodeTest after axisSpecifier ' + axis); - if (null == axis) axis = 'child'; - if (null == nodeType) { - // When there's only a node name, then the node type is forced to be the - // principal node type of the axis. - // see http://www.w3.org/TR/xpath/#dt-principal-node-type - if ('attribute' === axis) nodeType = 'attribute'; - else if ('namespace' === axis) nodeType = 'namespace'; - else nodeType = 'element'; - } - var lhs = a.node('Axis', axis, nodeType, nodeName); - var pred; - while (null != (pred = predicate(lhs, stream, a))) { - lhs = pred; - } - return lhs; - } - /** [5] AxisSpecifier::= AxisName '::' | AbbreviatedAxisSpecifier - * [6] AxisName::= 'ancestor' | 'ancestor-or-self' | 'attribute' | 'child' - * | 'descendant' | 'descendant-or-self' | 'following' - * | 'following-sibling' | 'namespace' | 'parent' | - * | 'preceding' | 'preceding-sibling' | 'self' - * [13] AbbreviatedAxisSpecifier::= '@'? - */ - function axisSpecifier(stream, a) { - var attr = stream.trypop('@'); - if (null != attr) return 'attribute'; - var axisName = stream.trypopaxisname(); - if (null != axisName) { - var coloncolon = stream.trypop('::'); - if (null == coloncolon) - throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, - 'Position ' + stream.position() + - ': Should not happen. Should be ::.'); - return axisName; - } - } - /** [7] NodeTest::= NameTest | NodeType '(' ')' | 'processing-instruction' '(' Literal ')' - * [38] NodeType::= 'comment' | 'text' | 'processing-instruction' | 'node' - * I've split nodeTypeTest from nodeNameTest for convenience. - */ - function nodeTypeTest(stream, a) { - if ('(' !== stream.peek2()) { - return null; - } - var type = stream.trypop(['comment', 'text', 'processing-instruction', 'node']); - if (null != type) { - if (null == stream.trypop('(')) - throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, - 'Position ' + stream.position() + - ': Should not happen.'); - var param = undefined; - if (type == 'processing-instruction') { - param = stream.trypopliteral(); - } - if (null == stream.trypop(')')) - throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, - 'Position ' + stream.position() + - ': Expected close parens.'); - return type - } - } - function nodeNameTest(stream, a) { - var name = stream.trypopnametest(); - if (name != null) return name; - else return null; - } - /** [8] Predicate::= '[' PredicateExpr ']' - * [9] PredicateExpr::= Expr - */ - function predicate(lhs, stream, a) { - if (null == stream.trypop('[')) return null; - var expr = orExpr(stream, a); - if (null == expr) - throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, - 'Position ' + stream.position() + - ': Expected expression after ['); - if (null == stream.trypop(']')) - throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, - 'Position ' + stream.position() + - ': Expected ] after expression.'); - return a.node('Predicate', lhs, expr); - } - /** [14] Expr::= OrExpr - */ - /** [15] PrimaryExpr::= VariableReference | '(' Expr ')' | Literal | Number | FunctionCall - * e.g. $x, (3+4), "hi", 32, f(x) - */ - function primaryExpr(stream, a) { - var x = stream.trypopliteral(); - if (null == x) - x = stream.trypopnumber(); - if (null != x) { - return x; - } - var varRef = stream.trypopvarref(); - if (null != varRef) return a.node('VariableReference', varRef); - var funCall = functionCall(stream, a); - if (null != funCall) { - return funCall; - } - if (stream.trypop('(')) { - var e = orExpr(stream, a); - if (null == e) - throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, - 'Position ' + stream.position() + - ': Expected expression after (.'); - if (null == stream.trypop(')')) - throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, - 'Position ' + stream.position() + - ': Expected ) after expression.'); - return e; - } - return null; - } - /** [16] FunctionCall::= FunctionName '(' ( Argument ( ',' Argument )* )? ')' - * [17] Argument::= Expr - */ - function functionCall(stream, a) { - var name = stream.trypopfuncname(stream, a); - if (null == name) return null; - if (null == stream.trypop('(')) - throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, - 'Position ' + stream.position() + - ': Expected ( ) after function name.'); - var params = []; - var first = true; - while (null == stream.trypop(')')) { - if (!first && null == stream.trypop(',')) - throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, - 'Position ' + stream.position() + - ': Expected , between arguments of the function.'); - first = false; - var param = orExpr(stream, a); - if (param == null) - throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, - 'Position ' + stream.position() + - ': Expected expression as argument of function.'); - params.push(param); - } - return a.node('FunctionCall', name, params); - } - - /** [18] UnionExpr::= PathExpr | UnionExpr '|' PathExpr - */ - function unionExpr(stream, a) { return binaryL(pathExpr, stream, a, '|'); } - /** [19] PathExpr ::= LocationPath - * | FilterExpr - * | FilterExpr '/' RelativeLocationPath - * | FilterExpr '//' RelativeLocationPath - * Unlike most other nodes, this one always generates a node because - * at this point all reverse nodesets must turn into a forward nodeset - */ - function pathExpr(stream, a) { - // We have to do FilterExpr before LocationPath because otherwise - // LocationPath will eat up the name from a function call. - var filter = filterExpr(stream, a); - if (null == filter) { - var loc = locationPath(stream, a); - if (null == loc) { - throw new Error - throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, - 'Position ' + stream.position() + - ': The expression shouldn\'t be empty...'); - } - return a.node('PathExpr', loc); - } - var rel = relativeLocationPath(filter, stream, a, false); - if (filter === rel) return rel; - else return a.node('PathExpr', rel); - } - /** [20] FilterExpr::= PrimaryExpr | FilterExpr Predicate - * aka. FilterExpr ::= PrimaryExpr Predicate* - */ - function filterExpr(stream, a) { - var primary = primaryExpr(stream, a); - if (primary == null) return null; - var pred, lhs = primary; - while (null != (pred = predicate(lhs, stream, a))) { - lhs = pred; - } - return lhs; - } - - /** [21] OrExpr::= AndExpr | OrExpr 'or' AndExpr - */ - function orExpr(stream, a) { - var orig = (stream.peeked || '') + stream.str - var r = binaryL(andExpr, stream, a, 'or'); - var now = (stream.peeked || '') + stream.str; - return r; - } - /** [22] AndExpr::= EqualityExpr | AndExpr 'and' EqualityExpr - */ - function andExpr(stream, a) { return binaryL(equalityExpr, stream, a, 'and'); } - /** [23] EqualityExpr::= RelationalExpr | EqualityExpr '=' RelationalExpr - * | EqualityExpr '!=' RelationalExpr - */ - function equalityExpr(stream, a) { return binaryL(relationalExpr, stream, a, ['=','!=']); } - /** [24] RelationalExpr::= AdditiveExpr | RelationalExpr '<' AdditiveExpr - * | RelationalExpr '>' AdditiveExpr - * | RelationalExpr '<=' AdditiveExpr - * | RelationalExpr '>=' AdditiveExpr - */ - function relationalExpr(stream, a) { return binaryL(additiveExpr, stream, a, ['<','>','<=','>=']); } - /** [25] AdditiveExpr::= MultiplicativeExpr - * | AdditiveExpr '+' MultiplicativeExpr - * | AdditiveExpr '-' MultiplicativeExpr - */ - function additiveExpr(stream, a) { return binaryL(multiplicativeExpr, stream, a, ['+','-']); } - /** [26] MultiplicativeExpr::= UnaryExpr - * | MultiplicativeExpr MultiplyOperator UnaryExpr - * | MultiplicativeExpr 'div' UnaryExpr - * | MultiplicativeExpr 'mod' UnaryExpr - */ - function multiplicativeExpr(stream, a) { return binaryL(unaryExpr, stream, a, ['*','div','mod']); } - /** [27] UnaryExpr::= UnionExpr | '-' UnaryExpr - */ - function unaryExpr(stream, a) { - if (stream.trypop('-')) { - var e = unaryExpr(stream, a); - if (null == e) - throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, - 'Position ' + stream.position() + - ': Expected unary expression after -'); - return a.node('UnaryMinus', e); - } - else return unionExpr(stream, a); - } - var astFactory = { - node: function() {return Array.prototype.slice.call(arguments);} - }; - - - /*************************************************************************** - * Optimizations (TODO) * - ***************************************************************************/ - /** - * Some things I've been considering: - * 1) a//b becomes a/descendant::b if there's no predicate that uses - * position() or last() - * 2) axis[pred]: when pred doesn't use position, evaluate it just once per - * node in the node-set rather than once per (node, position, last). - * For more optimizations, look up Gecko's optimizer: - * http://mxr.mozilla.org/mozilla-central/source/content/xslt/src/xpath/txXPathOptimizer.cpp - */ - // TODO - function optimize(ast) { - } - - /*************************************************************************** - * Evaluation: axes * - ***************************************************************************/ - - /** - * Data types: For string, number, boolean, we just use Javascript types. - * Node-sets have the form - * {nodes: [node, ...]} - * or {nodes: [node, ...], pos: [[1], [2], ...], lasts: [[1], [2], ...]} - * - * Most of the time, only the node is used and the position information is - * discarded. But if you use a predicate, we need to try every value of - * position and last in case the predicate calls position() or last(). - */ - - /** - * The NodeMultiSet is a helper class to help generate - * {nodes:[], pos:[], lasts:[]} structures. It is useful for the - * descendant, descendant-or-self, following-sibling, and - * preceding-sibling axes for which we can use a stack to organize things. - */ - function NodeMultiSet(isReverseAxis) { - this.nodes = []; - this.pos = []; - this.lasts = []; - this.nextPos = []; - this.seriesIndexes = []; // index within nodes that each series begins. - this.isReverseAxis = isReverseAxis; - this._pushToNodes = isReverseAxis ? Array.prototype.unshift : Array.prototype.push; - } - NodeMultiSet.prototype = { - pushSeries: function pushSeries() { - this.nextPos.push(1); - this.seriesIndexes.push(this.nodes.length); - }, - popSeries: function popSeries() { - console.assert(0 < this.nextPos.length, this.nextPos); - var last = this.nextPos.pop() - 1, - indexInPos = this.nextPos.length, - seriesBeginIndex = this.seriesIndexes.pop(), - seriesEndIndex = this.nodes.length; - for (var i = seriesBeginIndex; i < seriesEndIndex; ++i) { - console.assert(indexInPos < this.lasts[i].length); - console.assert(undefined === this.lasts[i][indexInPos]); - this.lasts[i][indexInPos] = last; - } - }, - finalize: function() { - if (null == this.nextPos) return this; - console.assert(0 === this.nextPos.length); - for (var i = 0; i < this.lasts.length; ++i) { - for (var j = 0; j < this.lasts[i].length; ++j) { - console.assert(null != this.lasts[i][j], i + ',' + j + ':' + JSON.stringify(this.lasts)); - } - } - this.pushSeries = this.popSeries = this.addNode = function() { - throw new Error('Already finalized.'); - }; - return this; - }, - addNode: function addNode(node) { - console.assert(node); - this._pushToNodes.call(this.nodes, node) - this._pushToNodes.call(this.pos, this.nextPos.slice()); - this._pushToNodes.call(this.lasts, new Array(this.nextPos.length)); - for (var i = 0; i < this.nextPos.length; ++i) this.nextPos[i]++; - }, - simplify: function() { - this.finalize(); - return {nodes:this.nodes, pos:this.pos, lasts:this.lasts}; - } - }; - function eachContext(nodeMultiSet) { - var r = []; - for (var i = 0; i < nodeMultiSet.nodes.length; i++) { - var node = nodeMultiSet.nodes[i]; - if (!nodeMultiSet.pos) { - r.push({nodes:[node], pos: [[i + 1]], lasts: [[nodeMultiSet.nodes.length]]}); - } else { - for (var j = 0; j < nodeMultiSet.pos[i].length; ++j) { - r.push({nodes:[node], pos: [[nodeMultiSet.pos[i][j]]], lasts: [[nodeMultiSet.lasts[i][j]]]}); - } - } - } - return r; - } - /** Matcher used in the axes. - */ - function NodeMatcher(nodeTypeNum, nodeName, shouldLowerCase) { - this.nodeTypeNum = nodeTypeNum; - this.nodeName = nodeName; - this.shouldLowerCase = shouldLowerCase; - this.nodeNameTest = - null == nodeName ? this._alwaysTrue : - shouldLowerCase ? this._nodeNameLowerCaseEquals : - this._nodeNameEquals; - } - NodeMatcher.prototype = { - matches: function matches(node) { - return (0 === this.nodeTypeNum || node.nodeType === this.nodeTypeNum) && - this.nodeNameTest(node.nodeName); - }, - _alwaysTrue: function(name) {return true;}, - _nodeNameEquals: function _nodeNameEquals(name) { - return this.nodeName === name; - }, - _nodeNameLowerCaseEquals: function _nodeNameLowerCaseEquals(name) { - return this.nodeName === name.toLowerCase(); - } - }; - - function followingSiblingHelper(nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase, shift, peek, followingNode, andSelf, isReverseAxis) { - var matcher = new NodeMatcher(nodeTypeNum, nodeName, shouldLowerCase); - var nodeMultiSet = new NodeMultiSet(isReverseAxis); - while (0 < nodeList.length) { // can be if for following, preceding - var node = shift.call(nodeList); - console.assert(node != null); - node = followingNode(node); - nodeMultiSet.pushSeries(); - var numPushed = 1; - while (null != node) { - if (! andSelf && matcher.matches(node)) - nodeMultiSet.addNode(node); - if (node === peek.call(nodeList)) { - shift.call(nodeList); - nodeMultiSet.pushSeries(); - numPushed++; - } - if (andSelf && matcher.matches(node)) - nodeMultiSet.addNode(node); - node = followingNode(node); - } - while (0 < numPushed--) - nodeMultiSet.popSeries(); - } - return nodeMultiSet; - } - - /** Returns the next non-descendant node in document order. - * This is the first node in following::node(), if node is the context. - */ - function followingNonDescendantNode(node) { - if (node.ownerElement) { - if (node.ownerElement.firstChild) - return node.ownerElement.firstChild; - node = node.ownerElement; - } - do { - if (node.nextSibling) return node.nextSibling; - } while (node = node.parentNode); - return null; - } - - /** Returns the next node in a document-order depth-first search. - * See the definition of document order[1]: - * 1) element - * 2) namespace nodes - * 3) attributes - * 4) children - * [1]: http://www.w3.org/TR/xpath/#dt-document-order - */ - function followingNode(node) { - if (node.ownerElement) // attributes: following node of element. - node = node.ownerElement; - if (null != node.firstChild) - return node.firstChild; - do { - if (null != node.nextSibling) { - return node.nextSibling; - } - node = node.parentNode; - } while (node); - return null; - } - /** Returns the previous node in document order (excluding attributes - * and namespace nodes). - */ - function precedingNode(node) { - if (node.ownerElement) - return node.ownerElement; - if (null != node.previousSibling) { - node = node.previousSibling; - while (null != node.lastChild) { - node = node.lastChild; - } - return node; - } - if (null != node.parentNode) { - return node.parentNode; - } - return null; - } - /** This axis is inefficient if there are many nodes in the nodeList. - * But I think it's a pretty useless axis so it's ok. */ - function followingHelper(nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase) { - var matcher = new NodeMatcher(nodeTypeNum, nodeName, shouldLowerCase); - var nodeMultiSet = new NodeMultiSet(false); - var cursor = nodeList[0]; - var unorderedFollowingStarts = []; - for (var i = 0; i < nodeList.length; i++) { - var node = nodeList[i]; - var start = followingNonDescendantNode(node); - if (start) - unorderedFollowingStarts.push(start); - } - if (0 === unorderedFollowingStarts.length) - return {nodes:[]}; - var pos = [], nextPos = []; - var started = 0; - while (cursor = followingNode(cursor)) { - for (var i = unorderedFollowingStarts.length - 1; i >= 0; i--){ - if (cursor === unorderedFollowingStarts[i]) { - nodeMultiSet.pushSeries(); - unorderedFollowingStarts.splice(i,i+1); - started++; - } - } - if (started && matcher.matches(cursor)) { - nodeMultiSet.addNode(cursor); - } - } - console.assert(0 === unorderedFollowingStarts.length); - for (var i = 0; i < started; i++) - nodeMultiSet.popSeries(); - return nodeMultiSet.finalize(); - } - function precedingHelper(nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase) { - var matcher = new NodeMatcher(nodeTypeNum, nodeName, shouldLowerCase); - var cursor = nodeList.pop(); - if (null == cursor) return {nodes:{}}; - var r = {nodes:[], pos:[], lasts:[]}; - var nextParents = [cursor.parentNode || cursor.ownerElement], nextPos = [1]; - while (cursor = precedingNode(cursor)) { - if (cursor === nodeList[nodeList.length - 1]) { - nextParents.push(nodeList.pop()); - nextPos.push(1); - } - var matches = matcher.matches(cursor); - var pos, someoneUsed = false; - if (matches) - pos = nextPos.slice(); - - for (var i = 0; i < nextParents.length; ++i) { - if (cursor === nextParents[i]) { - nextParents[i] = cursor.parentNode || cursor.ownerElement; - if (matches) { - pos[i] = null; - } - } else { - if (matches) { - pos[i] = nextPos[i]++; - someoneUsed = true; - } - } - } - if (someoneUsed) { - r.nodes.unshift(cursor); - r.pos.unshift(pos); - } - } - for (var i = 0; i < r.pos.length; ++i) { - var lasts = []; - r.lasts.push(lasts); - for (var j = r.pos[i].length - 1; j >= 0; j--) { - if (null == r.pos[i][j]) { - r.pos[i].splice(j, j+1); - } else { - lasts.unshift(nextPos[j] - 1); - } - } - } - return r; - } - - /** node-set, axis -> node-set */ - function descendantDfs(nodeMultiSet, node, remaining, matcher, andSelf, attrIndices, attrNodes) { - while (0 < remaining.length && null != remaining[0].ownerElement) { - var attr = remaining.shift(); - if (andSelf && matcher.matches(attr)) { - attrNodes.push(attr); - attrIndices.push(nodeMultiSet.nodes.length); - } - } - if (null != node && !andSelf) { - if (matcher.matches(node)) - nodeMultiSet.addNode(node); - } - var pushed = false; - if (null == node) { - if (0 === remaining.length) return; - node = remaining.shift(); - nodeMultiSet.pushSeries(); - pushed = true; - } else if (0 < remaining.length && node === remaining[0]) { - nodeMultiSet.pushSeries(); - pushed = true; - remaining.shift(); - } - if (andSelf) { - if (matcher.matches(node)) - nodeMultiSet.addNode(node); - } - // TODO: use optimization. Also try element.getElementsByTagName - // var nodeList = 1 === nodeTypeNum && null != node.children ? node.children : node.childNodes; - var nodeList = node.childNodes; - for (var j = 0; j < nodeList.length; ++j) { - var child = nodeList[j]; - descendantDfs(nodeMultiSet, child, remaining, matcher, andSelf, attrIndices, attrNodes); - } - if (pushed) { - nodeMultiSet.popSeries(); - } - } - function descenantHelper(nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase, andSelf) { - var matcher = new NodeMatcher(nodeTypeNum, nodeName, shouldLowerCase); - var nodeMultiSet = new NodeMultiSet(false); - var attrIndices = [], attrNodes = []; - while (0 < nodeList.length) { - // var node = nodeList.shift(); - descendantDfs(nodeMultiSet, null, nodeList, matcher, andSelf, attrIndices, attrNodes); - } - nodeMultiSet.finalize(); - for (var i = attrNodes.length-1; i >= 0; --i) { - nodeMultiSet.nodes.splice(attrIndices[i], attrIndices[i], attrNodes[i]); - nodeMultiSet.pos.splice(attrIndices[i], attrIndices[i], [1]); - nodeMultiSet.lasts.splice(attrIndices[i], attrIndices[i], [1]); - } - return nodeMultiSet; - } - /** - */ - function ancestorHelper(nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase, andSelf) { - var matcher = new NodeMatcher(nodeTypeNum, nodeName, shouldLowerCase); - var ancestors = []; // array of non-empty arrays of matching ancestors - for (var i = 0; i < nodeList.length; ++i) { - var node = nodeList[i]; - var isFirst = true; - var a = []; - while (null != node) { - if (!isFirst || andSelf) { - if (matcher.matches(node)) - a.push(node); - } - isFirst = false; - node = node.parentNode || node.ownerElement; - } - if (0 < a.length) - ancestors.push(a); - } - var lasts = []; - for (var i = 0; i < ancestors.length; ++i) lasts.push(ancestors[i].length); - var nodeMultiSet = new NodeMultiSet(true); - var newCtx = {nodes:[], pos:[], lasts:[]}; - while (0 < ancestors.length) { - var pos = [ancestors[0].length]; - var last = [lasts[0]]; - var node = ancestors[0].pop(); - for (var i = ancestors.length - 1; i > 0; --i) { - if (node === ancestors[i][ancestors[i].length - 1]) { - pos.push(ancestors[i].length); - last.push(lasts[i]); - ancestors[i].pop(); - if (0 === ancestors[i].length) { - ancestors.splice(i, i+1); - lasts.splice(i, i+1); - } - } - } - if (0 === ancestors[0].length) { - ancestors.shift(); - lasts.shift(); - } - newCtx.nodes.push(node); - newCtx.pos.push(pos); - newCtx.lasts.push(last); - } - return newCtx; - } - /** Helper function for sortDocumentOrder. Returns a list of indices, from the - * node to the root, of positions within parent. - * For convenience, the node is the first element of the array. - */ - function addressVector(node) { - var r = [node]; - if (null != node.ownerElement) { - node = node.ownerElement; - r.push(-1); - } - while (null != node) { - var i = 0; - while (null != node.previousSibling) { - node = node.previousSibling; - i++; - } - r.push(i); - node = node.parentNode - } - return r; - } - function addressComparator(a, b) { - var minlen = Math.min(a.length - 1, b.length - 1), // not including [0]=node - alen = a.length, - blen = b.length; - if (a[0] === b[0]) return 0; - var c; - for (var i = 0; i < minlen; ++i) { - c = a[alen - i - 1] - b[blen - i - 1]; - if (0 !== c) - break; - } - if (null == c || 0 === c) { - // All equal until one of the nodes. The longer one is the descendant. - c = alen - blen; - } - if (0 === c) - c = a.nodeName - b.nodeName; - if (0 === c) - c = 1; - return c; - } - var sortUniqDocumentOrder = xpath.sortUniqDocumentOrder = function(nodes) { - var a = []; - for (var i = 0; i < nodes.length; i++) { - var node = nodes[i]; - var v = addressVector(node); - a.push(v); - } - a.sort(addressComparator); - var b = []; - for (var i = 0; i < a.length; i++) { - if (0 < i && a[i][0] === a[i - 1][0]) - continue; - b.push(a[i][0]); - } - return b; - } - /** Sort node multiset. Does not do any de-duping. */ - function sortNodeMultiSet(nodeMultiSet) { - var a = []; - for (var i = 0; i < nodeMultiSet.nodes.length; i++) { - var v = addressVector(nodeMultiSet.nodes[i]); - a.push({v:v, n:nodeMultiSet.nodes[i], - p:nodeMultiSet.pos[i], l:nodeMultiSet.lasts[i]}); - } - a.sort(compare); - var r = {nodes:[], pos:[], lasts:[]}; - for (var i = 0; i < a.length; ++i) { - r.nodes.push(a[i].n); - r.pos.push(a[i].p); - r.lasts.push(a[i].l); - } - function compare(x, y) { - return addressComparator(x.v, y.v); - } - return r; - } - /** Returns an array containing all the ancestors down to a node. - * The array starts with document. - */ - function nodeAndAncestors(node) { - var ancestors = [node]; - var p = node; - while (p = p.parentNode || p.ownerElement) { - ancestors.unshift(p); - } - return ancestors; - } - function compareSiblings(a, b) { - if (a === b) return 0; - var c = a; - while (c = c.previousSibling) { - if (c === b) - return 1; // b < a - } - c = b; - while (c = c.previousSibling) { - if (c === a) - return -1; // a < b - } - throw new Error('a and b are not siblings: ' + xpath.stringifyObject(a) + ' vs ' + xpath.stringifyObject(b)); - } - /** The merge in merge-sort.*/ - function mergeNodeLists(x, y) { - var a, b, aanc, banc, r = []; - if ('object' !== typeof x) - throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, - 'Invalid LHS for | operator ' + - '(expected node-set): ' + x); - if ('object' !== typeof y) - throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, - 'Invalid LHS for | operator ' + - '(expected node-set): ' + y); - while (true) { - if (null == a) { - a = x.shift(); - if (null != a) - aanc = addressVector(a); - } - if (null == b) { - b = y.shift(); - if (null != b) - banc = addressVector(b); - } - if (null == a || null == b) break; - var c = addressComparator(aanc, banc); - if (c < 0) { - r.push(a); - a = null; - aanc = null; - } else if (c > 0) { - r.push(b); - b = null; - banc = null; - } else if (a.nodeName < b.nodeName) { // attributes - r.push(a); - a = null; - aanc = null; - } else if (a.nodeName > b.nodeName) { // attributes - r.push(b); - b = null; - banc = null; - } else if (a !== b) { - // choose b arbitrarily - r.push(b); - b = null; - banc = null; - } else { - console.assert(a === b, c); - // just skip b without pushing it. - b = null; - banc = null; - } - } - while (a) { - r.push(a); - a = x.shift(); - } - while (b) { - r.push(b); - b = y.shift(); - } - return r; - } - function comparisonHelper(test, x, y, isNumericComparison) { - var coersion; - if (isNumericComparison) - coersion = fn.number; - else coersion = - 'boolean' === typeof x || 'boolean' === typeof y ? fn['boolean'] : - 'number' === typeof x || 'number' === typeof y ? fn.number : - fn.string; - if ('object' === typeof x && 'object' === typeof y) { - var aMap = {}; - for (var i = 0; i < x.nodes.length; ++i) { - var xi = coersion({nodes:[x.nodes[i]]}); - for (var j = 0; j < y.nodes.length; ++j) { - var yj = coersion({nodes:[y.nodes[j]]}); - if (test(xi, yj)) return true; - } - } - return false; - } else if ('object' === typeof x && x.nodes && x.nodes.length) { - for (var i = 0; i < x.nodes.length; ++i) { - var xi = coersion({nodes:[x.nodes[i]]}), yc = coersion(y); - if (test(xi, yc)) - return true; - } - return false; - } else if ('object' === typeof y && x.nodes && x.nodes.length) { - for (var i = 0; i < x.nodes.length; ++i) { - var yi = coersion({nodes:[y.nodes[i]]}), xc = coersion(x); - if (test(xc, yi)) - return true; - } - return false; - } else { - var xc = coersion(x), yc = coersion(y); - return test(xc, yc); - } - } - var axes = xpath.axes = { - 'ancestor': - function ancestor(nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase) { - return ancestorHelper( - nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase, false); - }, - 'ancestor-or-self': - function ancestorOrSelf(nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase) { - return ancestorHelper( - nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase, true); - }, - 'attribute': - function attribute(nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase) { - // TODO: figure out whether positions should be undefined here. - var matcher = new NodeMatcher(nodeTypeNum, nodeName, shouldLowerCase); - var nodeMultiSet = new NodeMultiSet(false); - if (null != nodeName) { - // TODO: with namespace - for (var i = 0; i < nodeList.length; ++i) { - var node = nodeList[i]; - if (null == node.getAttributeNode) - continue; // only Element has .getAttributeNode - var attr = node.getAttributeNode(nodeName); - if (null != attr && matcher.matches(attr)) { - nodeMultiSet.pushSeries(); - nodeMultiSet.addNode(attr); - nodeMultiSet.popSeries(); - } - } - } else { - for (var i = 0; i < nodeList.length; ++i) { - var node = nodeList[i]; - if (null != node.attributes) { - nodeMultiSet.pushSeries(); - for (var j = 0; j < node.attributes.length; j++) { // all nodes have .attributes - var attr = node.attributes[j]; - if (matcher.matches(attr)) // TODO: I think this check is unnecessary - nodeMultiSet.addNode(attr); - } - nodeMultiSet.popSeries(); - } - } - } - return nodeMultiSet.finalize(); - }, - 'child': - function child(nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase) { - var matcher = new NodeMatcher(nodeTypeNum, nodeName, shouldLowerCase); - var nodeMultiSet = new NodeMultiSet(false); - for (var i = 0; i < nodeList.length; ++i) { - var n = nodeList[i]; - if (n.ownerElement) // skip attribute nodes' text child. - continue; - if (n.childNodes) { - nodeMultiSet.pushSeries(); - var childList = 1 === nodeTypeNum && null != n.children ? - n.children : n.childNodes; - for (var j = 0; j < childList.length; ++j) { - var child = childList[j]; - if (matcher.matches(child)) { - nodeMultiSet.addNode(child); - } - // don't have to do de-duping because children have parent, - // which are current context. - } - nodeMultiSet.popSeries(); - } - } - nodeMultiSet.finalize(); - return sortNodeMultiSet(nodeMultiSet); - }, - 'descendant': - function descenant(nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase) { - return descenantHelper( - nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase, false); - }, - 'descendant-or-self': - function descenantOrSelf(nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase) { - return descenantHelper( - nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase, true); - }, - 'following': - function following(nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase) { - return followingHelper(nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase); - }, - 'following-sibling': - function followingSibling(nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase) { - return followingSiblingHelper( - nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase, - Array.prototype.shift, function() {return this[0];}, - function(node) {return node.nextSibling;}); - }, - 'namespace': - function namespace(nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase) { - // TODO - }, - 'parent': - function parent(nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase) { - var matcher = new NodeMatcher(nodeTypeNum, nodeName, shouldLowerCase); - var nodes = [], pos = []; - for (var i = 0; i < nodeList.length; ++i) { - var parent = nodeList[i].parentNode || nodeList[i].ownerElement; - if (null == parent) - continue; - if (!matcher.matches(parent)) - continue; - if (nodes.length > 0 && parent === nodes[nodes.length-1]) - continue; - nodes.push(parent); - pos.push([1]); - } - return {nodes:nodes, pos:pos, lasts:pos}; - }, - 'preceding': - function preceding(nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase) { - return precedingHelper( - nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase); - }, - 'preceding-sibling': - function precedingSibling(nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase) { - return followingSiblingHelper( - nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase, - Array.prototype.pop, function() {return this[this.length-1];}, - function(node) {return node.previousSibling}, - false, true); - }, - 'self': - function self(nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase) { - var nodes = [], pos = []; - var matcher = new NodeMatcher(nodeTypeNum, nodeName, shouldLowerCase); - for (var i = 0; i < nodeList.length; ++i) { - if (matcher.matches(nodeList[i])) { - nodes.push(nodeList[i]); - pos.push([1]); - } - } - return {nodes: nodes, pos: pos, lasts: pos} - } - }; - - /*************************************************************************** - * Evaluation: functions * - ***************************************************************************/ - var fn = { - 'number': function number(optObject) { - if ('number' === typeof optObject) - return optObject; - if ('string' === typeof optObject) - return parseFloat(optObject); // note: parseFloat(' ') -> NaN, unlike +' ' -> 0. - if ('boolean' === typeof optObject) - return +optObject; - return fn.number(fn.string.call(this, optObject)); // for node-sets - }, - 'string': function string(optObject) { - if (null == optObject) - return fn.string(this); - if ('string' === typeof optObject || 'boolean' === typeof optObject || - 'number' === typeof optObject) - return '' + optObject; - if (0 == optObject.nodes.length) return ''; - if (null != optObject.nodes[0].textContent) - return optObject.nodes[0].textContent; - return optObject.nodes[0].nodeValue; - }, - 'boolean': function booleanVal(x) { - return 'object' === typeof x ? x.nodes.length > 0 : !!x; - }, - 'last': function last() { - console.assert(Array.isArray(this.pos)); - console.assert(Array.isArray(this.lasts)); - console.assert(1 === this.pos.length); - console.assert(1 === this.lasts.length); - console.assert(1 === this.lasts[0].length); - return this.lasts[0][0]; - }, - 'position': function position() { - console.assert(Array.isArray(this.pos)); - console.assert(Array.isArray(this.lasts)); - console.assert(1 === this.pos.length); - console.assert(1 === this.lasts.length); - console.assert(1 === this.pos[0].length); - return this.pos[0][0]; - }, - 'count': function count(nodeSet) { - if ('object' !== typeof nodeSet) - throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, - 'Position ' + stream.position() + - ': Function count(node-set) ' + - 'got wrong argument type: ' + nodeSet); - return nodeSet.nodes.length; - }, - 'id': function id(object) { - var r = {nodes: []}; - var doc = this.nodes[0].ownerDocument || this.nodes[0]; - console.assert(doc); - var ids; - if ('object' === typeof object) { - // for node-sets, map id over each node value. - ids = []; - for (var i = 0; i < object.nodes.length; ++i) { - var idNode = object.nodes[i]; - var idsString = fn.string({nodes:[idNode]}); - var a = idsString.split(/[ \t\r\n]+/g); - Array.prototype.push.apply(ids, a); - } - } else { - var idsString = fn.string(object); - var a = idsString.split(/[ \t\r\n]+/g); - ids = a; - } - for (var i = 0; i < ids.length; ++i) { - var id = ids[i]; - if (0 === id.length) - continue; - var node = doc.getElementById(id); - if (null != node) - r.nodes.push(node); - } - r.nodes = sortUniqDocumentOrder(r.nodes); - return r; - }, - 'local-name': function(nodeSet) { - if (null == nodeSet) - return fn.name(this); - if (null == nodeSet.nodes) { - throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, - 'argument to name() must be a node-set. got ' + nodeSet); - } - // TODO: namespaced version - return nodeSet.nodes[0].nodeName.toLowerCase(); // TODO: no toLowerCase for xml - }, - 'namespace-uri': function(nodeSet) { - // TODO - throw new Error('not implemented yet'); - }, - 'name': function(nodeSet) { - if (null == nodeSet) - return fn.name(this); - if (null == nodeSet.nodes) { - throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, - 'argument to name() must be a node-set. got ' + nodeSet); - } - return nodeSet.nodes[0].nodeName.toLowerCase(); // TODO: no toLowerCase for xml - }, - 'concat': function concat(x) { - var l = []; - for (var i = 0; i < arguments.length; ++i) { - l.push(fn.string(arguments[i])); - } - return l.join(''); - }, - 'starts-with': function startsWith(a, b) { - var as = fn.string(a), bs = fn.string(b); - return as.substr(0, bs.length) === bs; - }, - 'contains': function contains(a, b) { - var as = fn.string(a), bs = fn.string(b); - var i = as.indexOf(bs); - if (-1 === i) return false; - return true; - }, - 'substring-before': function substringBefore(a, b) { - var as = fn.string(a), bs = fn.string(b); - var i = as.indexOf(bs); - if (-1 === i) return ''; - return as.substr(0, i); - }, - 'substring-after': function substringBefore(a, b) { - var as = fn.string(a), bs = fn.string(b); - var i = as.indexOf(bs); - if (-1 === i) return ''; - return as.substr(i + bs.length); - }, - 'substring': function substring(string, start, optEnd) { - if (null == string || null == start) { - throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, - 'Must be at least 2 arguments to string()'); - } - var sString = fn.string(string), - iStart = fn.round(start), - iEnd = optEnd == null ? null : fn.round(optEnd); - // Note that xpath string positions user 1-based index - if (iEnd == null) - return sString.substr(iStart - 1); - else - return sString.substr(iStart - 1, iEnd); - }, - 'string-length': function stringLength(optString) { - return fn.string.call(this, optString).length; - }, - 'normalize-space': function normalizeSpace(optString) { - var s = fn.string.call(this, optString); - return s.replace(/[ \t\r\n]+/g, ' ').replace(/^ | $/g, ''); - }, - 'translate': function translate(string, from, to) { - var sString = fn.string.call(this, string), - sFrom = fn.string(from), - sTo = fn.string(to); - var eachCharRe = []; - var map = {}; - for (var i = 0; i < sFrom.length; ++i) { - var c = sFrom.charAt(i); - map[c] = sTo.charAt(i); // returns '' if beyond length of sTo. - // copied from goog.string.regExpEscape in the Closure library. - eachCharRe.push( - c.replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, '\\$1'). - replace(/\x08/g, '\\x08')); - } - var re = new RegExp(eachCharRe.join('|'), 'g'); - return sString.replace(re, function(c) {return map[c];}); - }, - /// Boolean functions - 'not': function not(x) { - var bx = fn['boolean'](x); - return !bx; - }, - 'true': function trueVal() { return true; }, - 'false': function falseVal() { return false; }, - // TODO - 'lang': function lang(string) { throw new Error('Not implemented');}, - 'sum': function sum(optNodeSet) { - if (null == optNodeSet) return fn.sum(this); - // for node-sets, map id over each node value. - var sum = 0; - for (var i = 0; i < optNodeSet.nodes.length; ++i) { - var node = optNodeSet.nodes[i]; - var x = fn.number({nodes:[node]}); - sum += x; - } - return sum; - }, - 'floor': function floor(number) { - return Math.floor(fn.number(number)); - }, - 'ceiling': function ceiling(number) { - return Math.ceil(fn.number(number)); - }, - 'round': function round(number) { - return Math.round(fn.number(number)); - } - }; - /*************************************************************************** - * Evaluation: operators * - ***************************************************************************/ - var more = { - UnaryMinus: function(x) { return -fn.number(x); }, - '+': function(x, y) { return fn.number(x) + fn.number(y); }, - '-': function(x, y) { return fn.number(x) - fn.number(y); }, - '*': function(x, y) { return fn.number(x) * fn.number(y); }, - 'div': function(x, y) { return fn.number(x) / fn.number(y); }, - 'mod': function(x, y) { return fn.number(x) % fn.number(y); }, - '<': function(x, y) { - return comparisonHelper(function(x, y) { return fn.number(x) < fn.number(y);}, x, y, true); - }, - '<=': function(x, y) { - return comparisonHelper(function(x, y) { return fn.number(x) <= fn.number(y);}, x, y, true); - }, - '>': function(x, y) { - return comparisonHelper(function(x, y) { return fn.number(x) > fn.number(y);}, x, y, true); - }, - '>=': function(x, y) { - return comparisonHelper(function(x, y) { return fn.number(x) >= fn.number(y);}, x, y, true); - }, - 'and': function(x, y) { return fn['boolean'](x) && fn['boolean'](y); }, - 'or': function(x, y) { return fn['boolean'](x) || fn['boolean'](y); }, - '|': function(x, y) { return {nodes: mergeNodeLists(x.nodes, y.nodes)}; }, - '=': function(x, y) { - // optimization for two node-sets case: avoid n^2 comparisons. - if ('object' === typeof x && 'object' === typeof y) { - var aMap = {}; - for (var i = 0; i < x.nodes.length; ++i) { - var s = fn.string({nodes:[x.nodes[i]]}); - aMap[s] = true; - } - for (var i = 0; i < y.nodes.length; ++i) { - var s = fn.string({nodes:[y.nodes[i]]}); - if (aMap[s]) return true; - } - return false; - } else { - return comparisonHelper(function(x, y) {return x === y;}, x, y); - } - }, - '!=': function(x, y) { - // optimization for two node-sets case: avoid n^2 comparisons. - if ('object' === typeof x && 'object' === typeof y) { - if (0 === x.nodes.length || 0 === y.nodes.length) return false; - var aMap = {}; - for (var i = 0; i < x.nodes.length; ++i) { - var s = fn.string({nodes:[x.nodes[i]]}); - aMap[s] = true; - } - for (var i = 0; i < y.nodes.length; ++i) { - var s = fn.string({nodes:[y.nodes[i]]}); - if (!aMap[s]) return true; - } - return false; - } else { - return comparisonHelper(function(x, y) {return x !== y;}, x, y); - } - } - }; - var nodeTypes = xpath.nodeTypes = { - 'node': 0, - 'attribute': 2, - 'comment': 8, // this.doc.COMMENT_NODE, - 'text': 3, // this.doc.TEXT_NODE, - 'processing-instruction': 7, // this.doc.PROCESSING_INSTRUCTION_NODE, - 'element': 1 //this.doc.ELEMENT_NODE - }; - /** For debugging and unit tests: returnjs a stringified version of the - * argument. */ - var stringifyObject = xpath.stringifyObject = function stringifyObject(ctx) { - var seenKey = 'seen' + Math.floor(Math.random()*1000000000); - return JSON.stringify(helper(ctx)); - - function helper(ctx) { - if (Array.isArray(ctx)) { - return ctx.map(function(x) {return helper(x);}); - } - if ('object' !== typeof ctx) return ctx; - if (null == ctx) return ctx; - // if (ctx.toString) return ctx.toString(); - if (null != ctx.outerHTML) return ctx.outerHTML; - if (null != ctx.nodeValue) return ctx.nodeName + '=' + ctx.nodeValue; - if (ctx[seenKey]) return '[circular]'; - ctx[seenKey] = true; - var nicer = {}; - for (var key in ctx) { - if (seenKey === key) - continue; - try { - nicer[key] = helper(ctx[key]); - } catch (e) { - nicer[key] = '[exception: ' + e.message + ']'; - } - } - delete ctx[seenKey]; - return nicer; - } - } - var Evaluator = xpath.Evaluator = function Evaluator(doc) { - this.doc = doc; - } - Evaluator.prototype = { - val: function val(ast, ctx) { - console.assert(ctx.nodes); - - if ('number' === typeof ast || 'string' === typeof ast) return ast; - if (more[ast[0]]) { - var evaluatedParams = []; - for (var i = 1; i < ast.length; ++i) { - evaluatedParams.push(this.val(ast[i], ctx)); - } - var r = more[ast[0]].apply(ctx, evaluatedParams); - return r; - } - switch (ast[0]) { - case 'Root': return {nodes: [this.doc]}; - case 'FunctionCall': - var functionName = ast[1], functionParams = ast[2]; - if (null == fn[functionName]) - throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, - 'Unknown function: ' + functionName); - var evaluatedParams = []; - for (var i = 0; i < functionParams.length; ++i) { - evaluatedParams.push(this.val(functionParams[i], ctx)); - } - var r = fn[functionName].apply(ctx, evaluatedParams); - return r; - case 'Predicate': - var lhs = this.val(ast[1], ctx); - var ret = {nodes: []}; - var contexts = eachContext(lhs); - for (var i = 0; i < contexts.length; ++i) { - var singleNodeSet = contexts[i]; - var rhs = this.val(ast[2], singleNodeSet); - var success; - if ('number' === typeof rhs) { - success = rhs === singleNodeSet.pos[0][0]; - } else { - success = fn['boolean'](rhs); - } - if (success) { - var node = singleNodeSet.nodes[0]; - ret.nodes.push(node); - // skip over all the rest of the same node. - while (i+1 < contexts.length && node === contexts[i+1].nodes[0]) { - i++; - } - } - } - return ret; - case 'PathExpr': - // turn the path into an expressoin; i.e., remove the position - // information of the last axis. - var x = this.val(ast[1], ctx); - // Make the nodeset a forward-direction-only one. - if (x.finalize) { // it is a NodeMultiSet - for (var i = 0; i < x.nodes.length; ++i) { - console.assert(null != x.nodes[i].nodeType); - } - return {nodes: x.nodes}; - } else { - return x; - } - case '/': - // TODO: don't generate '/' nodes, just Axis nodes. - var lhs = this.val(ast[1], ctx); - console.assert(null != lhs); - var r = this.val(ast[2], lhs); - console.assert(null != r); - return r; - case 'Axis': - // All the axis tests from Step. We only get AxisSpecifier NodeTest, - // not the predicate (which is applied later) - var axis = ast[1], - nodeType = ast[2], - nodeTypeNum = nodeTypes[nodeType], - shouldLowerCase = true, // TODO: give option - nodeName = ast[3] && shouldLowerCase ? ast[3].toLowerCase() : ast[3]; - nodeName = nodeName === '*' ? null : nodeName; - if ('object' !== typeof ctx) return {nodes:[], pos:[]}; - var nodeList = ctx.nodes.slice(); // TODO: is copy needed? - var r = axes[axis](nodeList /*destructive!*/, nodeTypeNum, nodeName, shouldLowerCase); - return r; - } - } - }; - var evaluate = xpath.evaluate = function evaluate(expr, doc, context) { - //var astFactory = new AstEvaluatorFactory(doc, context); - var stream = new Stream(expr); - var ast = parse(stream, astFactory); - var val = new Evaluator(doc).val(ast, {nodes: [context]}); - return val; - } - - /*************************************************************************** - * DOM interface * - ***************************************************************************/ - var XPathException = xpath.XPathException = function XPathException(code, message) { - var e = new Error(message); - e.name = 'XPathException'; - e.code = code; - return e; - } - XPathException.INVALID_EXPRESSION_ERR = 51; - XPathException.TYPE_ERR = 52; - - - var XPathEvaluator = xpath.XPathEvaluator = function XPathEvaluator() {} - XPathEvaluator.prototype = { - createExpression: function(expression, resolver) { - return new XPathExpression(expression, resolver); - }, - createNSResolver: function(nodeResolver) { - // TODO - }, - evaluate: function evaluate(expression, contextNode, resolver, type, result) { - var expr = new XPathExpression(expression, resolver); - return expr.evaluate(contextNode, type, result); - } - }; - - - var XPathExpression = xpath.XPathExpression = function XPathExpression(expression, resolver, optDoc) { - var stream = new Stream(expression); - this._ast = parse(stream, astFactory); - this._doc = optDoc; - } - XPathExpression.prototype = { - evaluate: function evaluate(contextNode, type, result) { - if (null == contextNode.nodeType) - throw new Error('bad argument (expected context node): ' + contextNode); - var doc = contextNode.ownerDocument || contextNode; - if (null != this._doc && this._doc !== doc) { - throw new core.DOMException( - core.WRONG_DOCUMENT_ERR, - 'The document must be the same as the context node\'s document.'); - } - var evaluator = new Evaluator(doc); - var value = evaluator.val(this._ast, {nodes: [contextNode]}); - if (XPathResult.NUMBER_TYPE === type) - value = fn.number(value); - else if (XPathResult.STRING_TYPE === type) - value = fn.string(value); - else if (XPathResult.BOOLEAN_TYPE === type) - value = fn['boolean'](value); - else if (XPathResult.ANY_TYPE !== type && - XPathResult.UNORDERED_NODE_ITERATOR_TYPE !== type && - XPathResult.ORDERED_NODE_ITERATOR_TYPE !== type && - XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE !== type && - XPathResult.ORDERED_NODE_SNAPSHOT_TYPE !== type && - XPathResult.ANY_UNORDERED_NODE_TYPE !== type && - XPathResult.FIRST_ORDERED_NODE_TYPE !== type) - throw new core.DOMException( - core.NOT_SUPPORTED_ERR, - 'You must provide an XPath result type (0=any).'); - else if (XPathResult.ANY_TYPE !== type && - 'object' !== typeof value) - throw new XPathException( - XPathException.TYPE_ERR, - 'Value should be a node-set: ' + value); - return new XPathResult(doc, value, type); - } - } - - var XPathResult = xpath.XPathResult = function XPathResult(doc, value, resultType) { - this._value = value; - this._resultType = resultType; - this._i = 0; - this._invalidated = false; - if (this.resultType === XPathResult.UNORDERED_NODE_ITERATOR_TYPE || - this.resultType === XPathResult.ORDERED_NODE_ITERATOR_TYPE) { - doc.addEventListener('DOMSubtreeModified', invalidate, true); - var self = this; - function invalidate() { - self._invalidated = true; - doc.removeEventListener('DOMSubtreeModified', invalidate, true); - } - } - } - XPathResult.ANY_TYPE = 0; - XPathResult.NUMBER_TYPE = 1; - XPathResult.STRING_TYPE = 2; - XPathResult.BOOLEAN_TYPE = 3; - XPathResult.UNORDERED_NODE_ITERATOR_TYPE = 4; - XPathResult.ORDERED_NODE_ITERATOR_TYPE = 5; - XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE = 6; - XPathResult.ORDERED_NODE_SNAPSHOT_TYPE = 7; - XPathResult.ANY_UNORDERED_NODE_TYPE = 8; - XPathResult.FIRST_ORDERED_NODE_TYPE = 9; - var proto = { - // XPathResultType - get resultType() { - if (this._resultType) return this._resultType; - switch (typeof this._value) { - case 'number': return XPathResult.NUMBER_TYPE; - case 'string': return XPathResult.STRING_TYPE; - case 'boolean': return XPathResult.BOOLEAN_TYPE; - default: return XPathResult.UNORDERED_NODE_ITERATOR_TYPE; - } - }, - get numberValue() { - if (XPathResult.NUMBER_TYPE !== this.resultType) - throw new XPathException(XPathException.TYPE_ERR, - 'You should have asked for a NUMBER_TYPE.'); - return this._value; - }, - get stringValue() { - if (XPathResult.STRING_TYPE !== this.resultType) - throw new XPathException(XPathException.TYPE_ERR, - 'You should have asked for a STRING_TYPE.'); - return this._value; - }, - get booleanValue() { - if (XPathResult.BOOLEAN_TYPE !== this.resultType) - throw new XPathException(XPathException.TYPE_ERR, - 'You should have asked for a BOOLEAN_TYPE.'); - return this._value; - }, - get singleNodeValue() { - if (XPathResult.ANY_UNORDERED_NODE_TYPE !== this.resultType && - XPathResult.FIRST_ORDERED_NODE_TYPE !== this.resultType) - throw new XPathException( - XPathException.TYPE_ERR, - 'You should have asked for a FIRST_ORDERED_NODE_TYPE.'); - return this._value.nodes[0] || null; - }, - get invalidIteratorState() { - if (XPathResult.UNORDERED_NODE_ITERATOR_TYPE !== this.resultType && - XPathResult.ORDERED_NODE_ITERATOR_TYPE !== this.resultType) - return false; - return !!this._invalidated; - }, - get snapshotLength() { - if (XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE !== this.resultType && - XPathResult.ORDERED_NODE_SNAPSHOT_TYPE !== this.resultType) - throw new XPathException( - XPathException.TYPE_ERR, - 'You should have asked for a ORDERED_NODE_SNAPSHOT_TYPE.'); - return this._value.nodes.length; - }, - iterateNext: function iterateNext() { - if (XPathResult.UNORDERED_NODE_ITERATOR_TYPE !== this.resultType && - XPathResult.ORDERED_NODE_ITERATOR_TYPE !== this.resultType) - throw new XPathException( - XPathException.TYPE_ERR, - 'You should have asked for a ORDERED_NODE_ITERATOR_TYPE.'); - if (this.invalidIteratorState) - throw new core.DOMException( - core.INVALID_STATE_ERR, - 'The document has been mutated since the result was returned'); - return this._value.nodes[this._i++] || null; - }, - snapshotItem: function snapshotItem(index) { - if (XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE !== this.resultType && - XPathResult.ORDERED_NODE_SNAPSHOT_TYPE !== this.resultType) - throw new XPathException( - XPathException.TYPE_ERR, - 'You should have asked for a ORDERED_NODE_SNAPSHOT_TYPE.'); - return this._value.nodes[index] || null; - } - }; - // so you can access ANY_TYPE etc. from the instances: - XPathResult.prototype = Object.create(XPathResult, - Object.keys(proto).reduce(function (descriptors, name) { - descriptors[name] = Object.getOwnPropertyDescriptor(proto, name); - return descriptors; - }, { - constructor: { - value: XPathResult, - writable: true, - configurable: true - } - })); - - core.XPathException = XPathException; - core.XPathExpression = XPathExpression; - core.XPathResult = XPathResult; - core.XPathEvaluator = XPathEvaluator; - - core.Document.prototype.createExpression = - XPathEvaluator.prototype.createExpression; - - core.Document.prototype.createNSResolver = - XPathEvaluator.prototype.createNSResolver; - - core.Document.prototype.evaluate = XPathEvaluator.prototype.evaluate; - -})(); diff --git a/node_modules/jsdom/lib/jsdom/living/character-data.js b/node_modules/jsdom/lib/jsdom/living/character-data.js deleted file mode 100644 index 89b2eaa..0000000 --- a/node_modules/jsdom/lib/jsdom/living/character-data.js +++ /dev/null @@ -1,90 +0,0 @@ -"use strict"; -var inheritFrom = require("../utils").inheritFrom; - -module.exports = function (core) { - core.CharacterData = function CharacterData(ownerDocument, data) { - core.Node.call(this, ownerDocument); - - this._data = data; - }; - - inheritFrom(core.Node, core.CharacterData, { - get data() { return this._data; }, - set data(data) { - if (data === null) { - data = ""; - } - data = String(data); - - this._setData(data); - }, - - get length() { - return this._data.length; - }, - - substringData: function (offset, count) { - offset = offset >>> 0; - count = count >>> 0; - - var length = this.length; - - if (offset > length) { - throw new core.DOMException(core.DOMException.INDEX_SIZE_ERR); - } - - if (offset + count > length) { - return this._data.substring(offset); - } - - return this._data.substring(offset, offset + count); - }, - - appendData: function (data) { - this.replaceData(this.length, 0, data); - }, - - insertData: function (offset, data) { - this.replaceData(offset, 0, data); - }, - - deleteData: function (offset, count) { - this.replaceData(offset, count, ""); - }, - - replaceData: function (offset, count, data) { - offset = offset >>> 0; - count = count >>> 0; - data = String(data); - - var length = this.length; - - if (offset > length) { - throw new core.DOMException(core.DOMException.INDEX_SIZE_ERR); - } - - if (offset + count > length) { - count = length - offset; - } - - var start = this._data.substring(0, offset); - var end = this._data.substring(offset + count); - - this._setData(start + data + end); - - // TODO: range stuff - }, - - _setData: function (newData) { - // TODO: remove this once we no longer rely on mutation events internally, since they are nonstandard - var oldData = this._data; - this._data = newData; - - if (this._ownerDocument && this._parentNode && this._ownerDocument.implementation._hasFeature("MutationEvents")) { - var ev = this._ownerDocument.createEvent("MutationEvents"); - ev.initMutationEvent("DOMCharacterDataModified", true, false, this, oldData, newData, null, null); - this.dispatchEvent(ev); - } - } - }); -}; diff --git a/node_modules/jsdom/lib/jsdom/living/comment.js b/node_modules/jsdom/lib/jsdom/living/comment.js deleted file mode 100644 index 471eb5d..0000000 --- a/node_modules/jsdom/lib/jsdom/living/comment.js +++ /dev/null @@ -1,13 +0,0 @@ -"use strict"; -var inheritFrom = require("../utils").inheritFrom; - -module.exports = function (core) { - // TODO: constructor should not take ownerDocument - core.Comment = function Comment(ownerDocument, data) { - core.CharacterData.call(this, ownerDocument, data); - }; - - inheritFrom(core.CharacterData, core.Comment, { - nodeType: core.Node.COMMENT_NODE, // TODO should be on prototype, not here - }); -}; diff --git a/node_modules/jsdom/lib/jsdom/living/document-type.js b/node_modules/jsdom/lib/jsdom/living/document-type.js deleted file mode 100644 index abd80aa..0000000 --- a/node_modules/jsdom/lib/jsdom/living/document-type.js +++ /dev/null @@ -1,19 +0,0 @@ -"use strict"; -var inheritFrom = require("../utils").inheritFrom; - -module.exports = function (core) { - core.DocumentType = function DocumentType(ownerDocument, name, publicId, systemId) { - core.Node.call(this, ownerDocument); - - this._name = name; - this._publicId = publicId; - this._systemId = systemId; - }; - - inheritFrom(core.Node, core.DocumentType, { - nodeType: core.Node.DOCUMENT_TYPE_NODE, // TODO should be on prototype, not here - get name() { return this._name; }, - get publicId() { return this._publicId; }, - get systemId() { return this._systemId; } - }); -}; diff --git a/node_modules/jsdom/lib/jsdom/living/document.js b/node_modules/jsdom/lib/jsdom/living/document.js deleted file mode 100644 index 9943519..0000000 --- a/node_modules/jsdom/lib/jsdom/living/document.js +++ /dev/null @@ -1,26 +0,0 @@ -"use strict"; -var validateNames = require("./helpers/validate-names"); - -module.exports = function (core) { - core.Document.prototype.createProcessingInstruction = function (target, data) { - target = String(target); - data = String(data); - - validateNames.name(target, core); - - if (data.indexOf("?>") !== -1) { - throw new core.DOMException(core.DOMException.INVALID_CHARACTER_ERR, - "Processing instruction data cannot contain the string \"?>\""); - } - - return new core.ProcessingInstruction(this._ownerDocument, target, data); - }; - - core.Document.prototype.createTextNode = function (data) { - return new core.Text(this, String(data)); - }; - - core.Document.prototype.createComment = function (data) { - return new core.Comment(this, String(data)); - }; -}; diff --git a/node_modules/jsdom/lib/jsdom/living/dom-implementation.js b/node_modules/jsdom/lib/jsdom/living/dom-implementation.js deleted file mode 100644 index 5ca8989..0000000 --- a/node_modules/jsdom/lib/jsdom/living/dom-implementation.js +++ /dev/null @@ -1,85 +0,0 @@ -"use strict"; -var validateNames = require("./helpers/validate-names"); - -module.exports = function (core) { - core.DOMImplementation.prototype.hasFeature = function () { - return true; - }; - - core.DOMImplementation.prototype.createDocumentType = function (qualifiedName, publicId, systemId) { - qualifiedName = String(qualifiedName); - publicId = String(publicId); - systemId = String(systemId); - - validateNames.qname(qualifiedName, core); - - return new core.DocumentType(this._ownerDocument, qualifiedName, publicId, systemId); - }; - - core.DOMImplementation.prototype.createDocument = function (namespace, qualifiedName, doctype) { - namespace = namespace !== null ? String(namespace) : namespace; - qualifiedName = qualifiedName === null ? "" : String(qualifiedName); - if (doctype === undefined) { - doctype = null; - } - - var document = new core.Document({ parsingMode: "xml" }); - - var element = null; - if (qualifiedName !== "") { - element = document.createElementNS(namespace, qualifiedName); - } - - if (doctype !== null) { - document.appendChild(doctype); - } - - if (element !== null) { - document.appendChild(element); - } - - return document; - }; - - core.DOMImplementation.prototype.createHTMLDocument = function (title) { - // Let doc be a new document that is an HTML document. - // Set doc's content type to "text/html". - var document = new core.HTMLDocument({ parsingMode: "html" }); - - // Create a doctype, with "html" as its name and with its node document set - // to doc. Append the newly created node to doc. - var doctype = this.createDocumentType("html", "", ""); - document.appendChild(doctype); - - // Create an html element in the HTML namespace, and append it to doc. - var htmlElement = document.createElementNS("http://www.w3.org/1999/xhtml", "html"); - document.appendChild(htmlElement); - - // Create a head element in the HTML namespace, and append it to the html - // element created in the previous step. - var headElement = document.createElement("head"); - htmlElement.appendChild(headElement); - - // If the title argument is not omitted: - if (title !== undefined) { - // Create a title element in the HTML namespace, and append it to the head - // element created in the previous step. - var titleElement = document.createElement("title"); - headElement.appendChild(titleElement); - - // Create a Text node, set its data to title (which could be the empty - // string), and append it to the title element created in the previous step. - titleElement.appendChild(document.createTextNode(title)); - } - - // Create a body element in the HTML namespace, and append it to the html - // element created in the earlier step. - htmlElement.appendChild(document.createElement("body")); - - // doc's origin is an alias to the origin of the context object's associated - // document, and doc's effective script origin is an alias to the effective - // script origin of the context object's associated document. - - return document; - }; -}; diff --git a/node_modules/jsdom/lib/jsdom/living/helpers/validate-names.js b/node_modules/jsdom/lib/jsdom/living/helpers/validate-names.js deleted file mode 100644 index 5f4622f..0000000 --- a/node_modules/jsdom/lib/jsdom/living/helpers/validate-names.js +++ /dev/null @@ -1,63 +0,0 @@ -"use strict"; -var xnv = require("xml-name-validator"); - -// https://dom.spec.whatwg.org/#validate - -exports.name = function (name, core) { - try { - xnv.name(name); - } catch (e) { - throw new core.DOMException(core.DOMException.INVALID_CHARACTER_ERR, - "\"" + name + "\" did not match the Name production: " + e.message); - } -}; - -exports.qname = function (qname, core) { - exports.name(qname, core); - - try { - xnv.qname(qname); - } catch (e) { - throw new core.DOMException(core.DOMException.NAMESPACE_ERR, - "\"" + qname + "\" did not match the QName production: " + e.message); - } -}; - -exports.validateAndExtract = function (namespace, qualifiedName, core) { - if (namespace === "") { - namespace = null; - } - - exports.qname(qualifiedName, core); - - var prefix = null; - var localName = qualifiedName; - - var colonIndex = qualifiedName.indexOf(":"); - if (colonIndex !== -1) { - prefix = qualifiedName.substring(0, colonIndex); - localName = qualifiedName.substring(colonIndex + 1); - } - - if (prefix !== null && namespace === null) { - throw new core.DOMException(core.DOMException.NAMESPACE_ERR, - "A namespace was given but a prefix was also extracted from the qualifiedName"); - } - - if (prefix === "xml" && namespace !== "http://www.w3.org/XML/1998/namespace") { - throw new core.DOMException(core.DOMException.NAMESPACE_ERR, - "A prefix of \"xml\" was given but the namespace was not the XML namespace"); - } - - if ((qualifiedName === "xmlns" || prefix === "xmlns") && namespace !== "http://www.w3.org/2000/xmlns/") { - throw new core.DOMException(core.DOMException.NAMESPACE_ERR, - "A prefix or qualifiedName of \"xmlns\" was given but the namespace was not the XMLNS namespace"); - } - - if (namespace === "http://www.w3.org/2000/xmlns/" && qualifiedName !== "xmlns" && prefix !== "xmlns") { - throw new core.DOMException(core.DOMException.NAMESPACE_ERR, - "The XMLNS namespace was given but neither the prefix nor qualifiedName was \"xmlns\""); - } - - return { namespace: namespace, prefix: prefix, localName: localName, qualifiedName: qualifiedName }; -}; diff --git a/node_modules/jsdom/lib/jsdom/living/index.js b/node_modules/jsdom/lib/jsdom/living/index.js deleted file mode 100644 index e4b67a0..0000000 --- a/node_modules/jsdom/lib/jsdom/living/index.js +++ /dev/null @@ -1,23 +0,0 @@ -"use strict"; -var core = module.exports = require("../level1/core"); - -// These (because of how they were written) directly include level1/core and modify it. -// ORDER IS IMPORTANT -require("../level2/core"); -require("../level2/events"); -require("../level2/html"); -require("../level2/style"); -require("../level3/core"); -require("../level3/ls"); -require("../level3/xpath"); - -require("./document-type")(core); -require("./character-data")(core); -require("./processing-instruction")(core); -require("./comment")(core); -require("./text")(core); -require("./dom-implementation")(core); -require("./document")(core); -require("./node-filter")(core); -require("./node")(core); -require("./selectors")(core); diff --git a/node_modules/jsdom/lib/jsdom/living/node-filter.js b/node_modules/jsdom/lib/jsdom/living/node-filter.js deleted file mode 100644 index f945b84..0000000 --- a/node_modules/jsdom/lib/jsdom/living/node-filter.js +++ /dev/null @@ -1,47 +0,0 @@ -"use strict"; -var addConstants = require("../utils").addConstants; - -module.exports = function (core) { - // https://dom.spec.whatwg.org/#interface-nodefilter - core.NodeFilter = function () { - throw new TypeError("Illegal constructor"); - }; - - /** - * Returns an unsigned short that will be used to tell if a given Node must - * be accepted or not by the NodeIterator or TreeWalker iteration - * algorithm. This method is expected to be written by the user of a - * NodeFilter. - * - * @see https://developer.mozilla.org/en-US/docs/Web/API/NodeFilter - * @interface - * - * @param {Node} node DOM Node - * @return {FILTER_ACCEPT|FILTER_REJECT|FILTER_SKIP} - */ - core.NodeFilter.acceptNode = function(/* node */) { - throw new Error("This method is expected to be written by the user of a NodeFilter."); - }; - - addConstants(core.NodeFilter, { - // Constants for whatToShow - SHOW_ALL : 0xFFFFFFFF, - SHOW_ELEMENT : 0x00000001, - SHOW_ATTRIBUTE : 0x00000002, - SHOW_TEXT : 0x00000004, - SHOW_CDATA_SECTION : 0x00000008, - SHOW_ENTITY_REFERENCE : 0x00000010, - SHOW_ENTITY : 0x00000020, - SHOW_PROCESSING_INSTRUCTION : 0x00000040, - SHOW_COMMENT : 0x00000080, - SHOW_DOCUMENT : 0x00000100, - SHOW_DOCUMENT_TYPE : 0x00000200, - SHOW_DOCUMENT_FRAGMENT : 0x00000400, - SHOW_NOTATION : 0x00000800, - - // Constants returned by acceptNode - FILTER_ACCEPT : 1, - FILTER_REJECT : 2, - FILTER_SKIP : 3 - }); -}; diff --git a/node_modules/jsdom/lib/jsdom/living/node.js b/node_modules/jsdom/lib/jsdom/living/node.js deleted file mode 100644 index 0ff38f9..0000000 --- a/node_modules/jsdom/lib/jsdom/living/node.js +++ /dev/null @@ -1,261 +0,0 @@ -"use strict"; -var defineGetter = require("../utils").defineGetter; - -module.exports = function (core) { - var DOCUMENT_POSITION_DISCONNECTED = core.Node.DOCUMENT_POSITION_DISCONNECTED; - var DOCUMENT_POSITION_PRECEDING = core.Node.DOCUMENT_POSITION_PRECEDING; - var DOCUMENT_POSITION_FOLLOWING = core.Node.DOCUMENT_POSITION_FOLLOWING; - var DOCUMENT_POSITION_CONTAINS = core.Node.DOCUMENT_POSITION_CONTAINS; - var DOCUMENT_POSITION_CONTAINED_BY = core.Node.DOCUMENT_POSITION_CONTAINED_BY; - var DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = core.Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC; - - /** - * Return true if node is of a type obsoleted by the WHATWG living standard - * @param {Node} node - * @return {Boolean} - */ - function isObsoleteNodeType(node) { - return node.nodeType === core.Node.ENTITY_NODE || - node.nodeType === core.Node.ENTITY_REFERENCE_NODE || - node.nodeType === core.Node.NOTATION_NODE || - node.nodeType === core.Node.CDATA_SECTION_NODE; - } - - /** - * Return the parent node of node, whatever its nodeType is - * @param {Node} node - * @return {Node or null} - */ - function getNodeParent(node) { - - if(!node) { - return node; - } - - switch (node.nodeType) { - - case core.Node.DOCUMENT_NODE: - case core.Node.DOCUMENT_FRAGMENT_NODE: - return null; - - case core.Node.COMMENT_NODE: - case core.Node.DOCUMENT_TYPE_NODE: - case core.Node.ELEMENT_NODE: - case core.Node.PROCESSING_INSTRUCTION_NODE: - case core.Node.TEXT_NODE: - return node.parentNode; - - case core.Node.ATTRIBUTE_NODE: - - return node._parentNode; - - default: - throw new Error("Unknown node type:" + node.nodeType); - } - } - - /** - * Walk up the node tree and return the nodes root node - * @param {Node} node - * @return {Node} - */ - function findNodeRoot(node) { - if (!getNodeParent(node)) { - return node; - } - - return findNodeRoot(getNodeParent(node)); - } - - /** - * Walk up the node tree returning true if otherNode is an ancestor of node - * @param {Node} node - * @param {Node} otherNode - * @return {Boolean} - */ - function isAncestor(node, otherNode) { - var parentNode = node.nodeType === node.ATTRIBUTE_NODE ? node._parentNode : node.parentNode; - - if (!parentNode) { - return false; - } - - if(parentNode === otherNode) { - return true; - } - - return isAncestor(parentNode, otherNode); - } - - /** - * Traverse the node tree starting at current. Return DOCUMENT_POSITION_FOLLOWING if otherNode follows node. Return - * DOCUMENT_POSITION_PRECEDING if otherNode precedes node - * @param {Node} current - * @param {Node} node - * @param {Node} otherNode - * @return {Number} - */ - function followingOrPreceding(current, node, otherNode) { - if (current === node) { - return core.Node.DOCUMENT_POSITION_FOLLOWING; - } - - if (current === otherNode) { - return core.Node.DOCUMENT_POSITION_PRECEDING; - } - - var i = 0, len = current._childNodes.length, child, result; - - for(; i < len; i += 1) { - - child = current._childNodes[i]; - - if((result = followingOrPreceding(child, node, otherNode)) !== 0) { - return result; - } - } - - return 0; - } - - /** - * Returns a bitmask Number composed of DOCUMENT_POSITION constants based upon the rules defined in - * http://dom.spec.whatwg.org/#dom-node-comparedocumentposition - * @param {Node} other - * @return {Number} - */ - core.Node.prototype.compareDocumentPosition = function compareDocumentPosition (other) { - // Let reference be the context object. - var reference = this; - - if(!(other instanceof core.Node)) { - throw Error("Comparing position against non-Node values is not allowed"); - } - - if (isObsoleteNodeType(reference) || isObsoleteNodeType(other)) { - throw new Error("Obsolete node type"); - } - - // If other and reference are the same object, return zero. - if (reference === other) { - return 0; - } - - // If other and reference are not in the same tree, return the result of adding DOCUMENT_POSITION_DISCONNECTED, - // DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC, and either DOCUMENT_POSITION_PRECEDING or DOCUMENT_POSITION_FOLLOWING, - // with the constraint that this is to be consistent, together. - if (findNodeRoot(reference) !== findNodeRoot(other)) { - return DOCUMENT_POSITION_DISCONNECTED + DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC + DOCUMENT_POSITION_FOLLOWING; - } - - // If other is an ancestor of reference, return the result of adding DOCUMENT_POSITION_CONTAINS to - // DOCUMENT_POSITION_PRECEDING. - if (isAncestor(reference, other)) { - return DOCUMENT_POSITION_CONTAINS + DOCUMENT_POSITION_PRECEDING; - } - - // If other is a descendant of reference, return the result of adding DOCUMENT_POSITION_CONTAINED_BY to - // DOCUMENT_POSITION_FOLLOWING. - if (isAncestor(other, reference)) { - return DOCUMENT_POSITION_CONTAINED_BY + DOCUMENT_POSITION_FOLLOWING; - } - - // If other is preceding reference return DOCUMENT_POSITION_PRECEDING, otherwise return DOCUMENT_POSITION_FOLLOWING - return followingOrPreceding(findNodeRoot(reference), reference, other); - }; - - /** - * The contains(other) method returns true if other is an inclusive descendant of the context object, - * and false otherwise (including when other is null). - * @param {[Node]} other [the node to test] - * @return {[boolean]} [whether other is an inclusive descendant of this] - */ - core.Node.prototype.contains = function (other) { - return other instanceof core.Node && - (this === other || this.compareDocumentPosition(other) & DOCUMENT_POSITION_CONTAINED_BY); - }; - - // http://dom.spec.whatwg.org/#dom-node-parentelement - defineGetter(core.Node.prototype, "parentElement", function () { - return this._parentNode !== null && this._parentNode.nodeType === core.Node.ELEMENT_NODE ? this._parentNode : null; - }); - - function nodeEquals(a, b) { - if (a.nodeType !== b.nodeType) { - return false; - } - - switch (a.nodeType) { - case core.Node.DOCUMENT_TYPE_NODE: - if (a._name !== b._name || a._publicId !== b._publicId || a._systemId !== b._systemId) { - return false; - } - break; - case core.Node.ELEMENT_NODE: - if (a._namespaceURI !== b._namespaceURI || a._prefix !== b._prefix || a._localName !== b._localName || - a._attributes.length !== b._attributes.length) { - return false; - } - break; - case core.Node.PROCESSING_INSTRUCTION_NODE: - if (a._target !== b._target || a._data !== b._data) { - return false; - } - break; - case core.Node.TEXT_NODE: - case core.Node.COMMENT_NODE: - if (a._data !== b._data) { - return false; - } - break; - } - - if (a.nodeType === core.Node.ELEMENT_NODE) { - for (var i = 0; i < a._attributes.length; ++i) { - var aAttr = a._attributes[i]; - var bAttr = b._attributes.$getNode(aAttr._namespaceURI, aAttr._localName); - if (!bAttr) { - return false; - } - - // TODO: once Attr is simplified, check the internal property instead of the public getter - if (aAttr.value !== bAttr.value) { - return false; - } - } - } - - if (a._childNodes.length !== b._childNodes.length) { - return false; - } - - for (var j = 0; j < a._childNodes.length; ++j) { - if (!nodeEquals(a._childNodes[j], b._childNodes[j])) { - return false; - } - } - - return true; - } - - // https://dom.spec.whatwg.org/#dom-node-isequalnode - core.Node.prototype.isEqualNode = function (node) { - if (node === undefined) { - // this is what Node? means in the IDL - node = null; - } - - if (node === null) { - return false; - } - - // Fast-path, not in the spec - if (this === node) { - return true; - } - - return nodeEquals(this, node); - }; -}; - - diff --git a/node_modules/jsdom/lib/jsdom/living/processing-instruction.js b/node_modules/jsdom/lib/jsdom/living/processing-instruction.js deleted file mode 100644 index ce9c4b7..0000000 --- a/node_modules/jsdom/lib/jsdom/living/processing-instruction.js +++ /dev/null @@ -1,15 +0,0 @@ -"use strict"; -var inheritFrom = require("../utils").inheritFrom; - -module.exports = function (core) { - core.ProcessingInstruction = function ProcessingInstruction(ownerDocument, target, data) { - core.CharacterData.call(this, ownerDocument, data); - - this._target = target; - }; - - inheritFrom(core.CharacterData, core.ProcessingInstruction, { - nodeType: core.Node.PROCESSING_INSTRUCTION_NODE, // TODO should be on prototype, not here - get target() { return this._target; } - }); -}; diff --git a/node_modules/jsdom/lib/jsdom/living/selectors.js b/node_modules/jsdom/lib/jsdom/living/selectors.js deleted file mode 100644 index d159f5a..0000000 --- a/node_modules/jsdom/lib/jsdom/living/selectors.js +++ /dev/null @@ -1,32 +0,0 @@ -"use strict"; -var nwmatcher = require("nwmatcher/src/nwmatcher-noqsa"); -var memoizeQuery = require("../utils").memoizeQuery; - -module.exports = function (core) { - [core.Document, core.DocumentFragment, core.Element].forEach(function (Class) { - Class.prototype.querySelector = memoizeQuery(function (selectors) { - return addNwmatcher(this).first(String(selectors), this); - }); - - Class.prototype.querySelectorAll = memoizeQuery(function (selectors) { - return new core.NodeList(addNwmatcher(this).select(String(selectors), this)); - }); - }); - - core.Element.prototype.matches = memoizeQuery(function (selectors) { - return addNwmatcher(this).match(this, selectors); - }); -}; - -// nwmatcher gets `document.documentElement` at creation-time, so we have to initialize lazily, since in the initial -// stages of Document initialization, there is no documentElement present yet. -function addNwmatcher(parentNode) { - var document = parentNode._ownerDocument; - - if (!document._nwmatcher) { - document._nwmatcher = nwmatcher({ document: document }); - document._nwmatcher.configure({ UNIQUE_ID: false }); - } - - return document._nwmatcher; -} diff --git a/node_modules/jsdom/lib/jsdom/living/text.js b/node_modules/jsdom/lib/jsdom/living/text.js deleted file mode 100644 index ecd8c63..0000000 --- a/node_modules/jsdom/lib/jsdom/living/text.js +++ /dev/null @@ -1,41 +0,0 @@ -"use strict"; -var inheritFrom = require("../utils").inheritFrom; - -module.exports = function (core) { - // TODO: constructor should not take ownerDocument - core.Text = function Text(ownerDocument, data) { - core.CharacterData.call(this, ownerDocument, data); - }; - - inheritFrom(core.CharacterData, core.Text, { - nodeType: core.Node.TEXT_NODE, // TODO should be on prototype, not here - splitText: function (offset) { - offset = offset >>> 0; - - var length = this.length; - - if (offset > length) { - throw new core.DOMException(core.DOMException.INDEX_SIZE_ERR); - } - - var count = length - offset; - var newData = this.substringData(offset, count); - - var newNode = this._ownerDocument.createTextNode(newData); - - var parent = this._parentNode; - - if (parent !== null) { - parent.insertBefore(newNode, this.nextSibling); - } - - this.replaceData(offset, count, ""); - - return newNode; - - // TODO: range stuff - }, - - // TODO: wholeText property - }); -}; diff --git a/node_modules/jsdom/lib/jsdom/utils.js b/node_modules/jsdom/lib/jsdom/utils.js deleted file mode 100644 index 1894611..0000000 --- a/node_modules/jsdom/lib/jsdom/utils.js +++ /dev/null @@ -1,223 +0,0 @@ -"use strict"; -var path = require("path"); -var url = require("url"); - -exports.toFileUrl = function (fileName) { - // Beyond just the `path.resolve`, this is mostly for the benefit of Windows, - // where we need to convert "\" to "/" and add an extra "/" prefix before the - // drive letter. - var pathname = path.resolve(process.cwd(), fileName).replace(/\\/g, "/"); - if (pathname[0] !== "/") { - pathname = "/" + pathname; - } - - return "file://" + pathname; -}; - -/** - * Define a setter on an object - * - * This method replaces any existing setter but leaves getters in place. - * - * - `object` {Object} the object to define the setter on - * - `property` {String} the name of the setter - * - `setterFn` {Function} the setter - */ -exports.defineSetter = function defineSetter(object, property, setterFn) { - var descriptor = Object.getOwnPropertyDescriptor(object, property) || { - configurable: true, - enumerable: true - }; - - descriptor.set = setterFn; - - Object.defineProperty(object, property, descriptor); -}; - -/** - * Define a getter on an object - * - * This method replaces any existing getter but leaves setters in place. - * - * - `object` {Object} the object to define the getter on - * - `property` {String} the name of the getter - * - `getterFn` {Function} the getter - */ -exports.defineGetter = function defineGetter(object, property, getterFn) { - var descriptor = Object.getOwnPropertyDescriptor(object, property) || { - configurable: true, - enumerable: true - }; - - descriptor.get = getterFn; - - Object.defineProperty(object, property, descriptor); -}; - -/** - * Create an object with the given prototype - * - * Optionally augment the created object. - * - * - `prototype` {Object} the created object's prototype - * - `[properties]` {Object} properties to attach to the created object - */ -exports.createFrom = function createFrom(prototype, properties) { - properties = properties || {}; - - var descriptors = {}; - Object.getOwnPropertyNames(properties).forEach(function (name) { - descriptors[name] = Object.getOwnPropertyDescriptor(properties, name); - }); - - return Object.create(prototype, descriptors); -}; - -/** - * Create an inheritance relationship between two classes - * - * Optionally augment the inherited prototype. - * - * - `Superclass` {Function} the inherited class - * - `Subclass` {Function} the inheriting class - * - `[properties]` {Object} properties to attach to the inherited prototype - */ -exports.inheritFrom = function inheritFrom(Superclass, Subclass, properties) { - properties = properties || {}; - - Object.defineProperty(properties, "constructor", { - value: Subclass, - writable: true, - configurable: true - }); - - Subclass.prototype = exports.createFrom(Superclass.prototype, properties); -}; - -/** - * Define a list of constants on a constructor and its .prototype - * - * - `Constructor` {Function} the constructor to define the constants on - * - `propertyMap` {Object} key/value map of properties to define - */ -exports.addConstants = function addConstants(Constructor, propertyMap) { - for (var property in propertyMap) { - var value = propertyMap[property]; - addConstant(Constructor, property, value); - addConstant(Constructor.prototype, property, value); - } -}; - -function addConstant(object, property, value) { - Object.defineProperty(object, property, { - configurable: false, - enumerable: true, - value: value, - writable: false - }); -} - -var memoizeQueryTypeCounter = 0; - -/** - * Returns a version of a method that memoizes specific types of calls on the object - * - * - `fn` {Function} the method to be memozied - */ -exports.memoizeQuery = function memoizeQuery(fn) { - // Only memoize query functions with arity <= 2 - if (fn.length > 2) { - return fn; - } - - var type = memoizeQueryTypeCounter++; - - return function () { - if (!this._memoizedQueries) { - return fn.apply(this, arguments); - } - - if (!this._memoizedQueries[type]) { - this._memoizedQueries[type] = Object.create(null); - } - - var key; - if (arguments.length === 1 && typeof arguments[0] === "string") { - key = arguments[0]; - } else if (arguments.length === 2 && typeof arguments[0] === "string" && typeof arguments[1] === "string") { - key = arguments[0] + "::" + arguments[1]; - } else { - return fn.apply(this, arguments); - } - - if (!(key in this._memoizedQueries[type])) { - this._memoizedQueries[type][key] = fn.apply(this, arguments); - } - return this._memoizedQueries[type][key]; - }; -}; - -/** -* A slightly-more-compliant version of `url.resolve`, taking care of a few Node bugs. -*/ -exports.resolveHref = function resolveHref(baseUrl, href) { - var about = "about:blank"; - - // if we're redirecting to another site on about:blank, just let it through - if (href.substring(0, about.length) === about) { - return href; - } - - // if we have to resolve from about:blank we need a bit of special logic - if (baseUrl.substring(0, about.length) === about) { - if (href.search(/^([A-Za-z0-9]+):/) === 0) { // we have an absolute url - baseUrl = href; - href = ""; - } else if (href[0] === "#") { // we have a location hash on about:blank - return baseUrl.split(/#/)[0] + href; - } else if (!href) { // we just have some base url - return baseUrl; - } else { // must be a file url - baseUrl = "file://" + href; - href = ""; - } - } - - if (baseUrl === resolveHref.memoizedUrl && resolveHref.cache && resolveHref.cache[href]) { - return resolveHref.cache[href]; - } - - // When switching protocols, the path doesn't get canonicalized (i.e. .s and ..s are still left): - // https://github.com/joyent/node/issues/5453 - var intermediate = url.resolve(baseUrl, href); - - // This canonicalizes the path, at the cost of overwriting the hash. - var nextStep = url.resolve(intermediate, "#"); - - // But it breaks file URLs by removing their colon O_o, so put that back. - nextStep = nextStep.replace(/^file:\/\/([a-z])\//i, "file:///$1:/"); - - // So, insert the hash back in, if there was one. - var parsed = url.parse(intermediate); - var fixed = nextStep.slice(0, -1) + (parsed.hash || ""); - - // Finally, fix file:/// URLs on Windows, where Node removes their drive letters: - // https://github.com/joyent/node/issues/5452 - if (/^file\:\/\/\/[a-z]\:\//i.test(baseUrl) && /^file\:\/\/\//.test(fixed) && - !/^file\:\/\/\/[a-z]\:\//i.test(fixed)) { - fixed = fixed.replace(/^file\:\/\/\//, baseUrl.substring(0, 11)); - } - - // HORRIBLE HACK: encode \u00E4 correctly just so that we pass - // https://github.com/w3c/web-platform-tests/blob/e75f01a689a3481f5c773315c2c2527712cf8c2c/dom/nodes/DOMImplementation-createHTMLDocument.html#L71-L72 - // Eventually we should replace this with a real URL parser based on the URL standard. - fixed = fixed.replace(/\u00E4/, "%C3%A4"); - - if (baseUrl !== resolveHref.memoizedUrl) { - resolveHref.memoizedUrl = baseUrl; - resolveHref.cache = {}; - } - resolveHref.cache[href] = fixed; - - return fixed; -}; diff --git a/node_modules/jsdom/lib/jsdom/virtual-console.js b/node_modules/jsdom/lib/jsdom/virtual-console.js deleted file mode 100644 index 1cc7723..0000000 --- a/node_modules/jsdom/lib/jsdom/virtual-console.js +++ /dev/null @@ -1,24 +0,0 @@ -"use strict"; - -var EventEmitter = require("events").EventEmitter; -var utils = require("./utils"); - -function VirtualConsole() { - // If "error" event has no listeners, - // EventEmitter throws an exception - this.on("error", function () {}); -} - -utils.inheritFrom(EventEmitter, VirtualConsole, { - sendTo: function (anyConsole) { - Object.keys(anyConsole).forEach(function (method) { - if (typeof anyConsole[method] === "function") { - this.on(method, function () { - anyConsole[method].apply(anyConsole, arguments); - }); - } - }, this); - } -}); - -module.exports = VirtualConsole; |
