ref: de7f6220b338f2e7b18b753d038737de134abae5
parent: 8f3e38f10a26e17f398c32a6caac5d3d19bb715b
author: Philip Silva <[email protected]>
date: Thu Nov 4 11:53:11 EDT 2021
Move hacky js into separate repository
--- a/README.md
+++ b/README.md
@@ -75,9 +75,12 @@
https://golang.org/pkg There is also highly experimental ES6 support with Babel.
(Needs also https://github.com/psilva261/6to5)
-Build the js engine:
+Install the js engine:
```
+cd ..
+git/clone https://github.com/psilva261/gojafs
+cd gojafs
go install ./cmd/gojafs
```
--- a/cmd/gojafs/domino/domino-lib/CSSStyleDeclaration.js
+++ /dev/null
@@ -1,579 +1,0 @@
-"use strict";
-var parserlib = require('./cssparser');
-
-module.exports = CSSStyleDeclaration;
-
-function CSSStyleDeclaration(elt) {
- this._element = elt;
-}
-
-// Utility function for parsing style declarations
-// Pass in a string like "margin-left: 5px; border-style: solid"
-// and this function returns an object like
-// {"margin-left":"5px", "border-style":"solid"}
-function parseStyles(s) {
- var parser = new parserlib.css.Parser();
- var result = { property: Object.create(null), priority: Object.create(null) };
- parser.addListener("property", function(e) {
- if (e.invalid) return; // Skip errors
- result.property[e.property.text] = e.value.text;
- if (e.important) result.priority[e.property.text] = 'important';
- });
- s = (''+s).replace(/^;/, '');
- parser.parseStyleAttribute(s);
- return result;
-}
-
-var NO_CHANGE = {}; // Private marker object
-
-CSSStyleDeclaration.prototype = Object.create(Object.prototype, {
-
- // Return the parsed form of the element's style attribute.
- // If the element's style attribute has never been parsed
- // or if it has changed since the last parse, then reparse it
- // Note that the styles don't get parsed until they're actually needed
- _parsed: { get: function() {
- if (!this._parsedStyles || this.cssText !== this._lastParsedText) {
- var text = this.cssText;
- this._parsedStyles = parseStyles(text);
- this._lastParsedText = text;
- delete this._names;
- }
- return this._parsedStyles;
- }},
-
- // Call this method any time the parsed representation of the
- // style changes. It converts the style properties to a string and
- // sets cssText and the element's style attribute
- _serialize: { value: function() {
- var styles = this._parsed;
- var s = "";
-
- for(var name in styles.property) {
- if (s) s += " ";
- s += name + ": " + styles.property[name];
- if (styles.priority[name]) {
- s += " !" + styles.priority[name];
- }
- s += ";";
- }
-
- this.cssText = s; // also sets the style attribute
- this._lastParsedText = s; // so we don't reparse
- delete this._names;
- }},
-
- cssText: {
- get: function() {
- // XXX: this is a CSSStyleDeclaration for an element.
- // A different impl might be necessary for a set of styles
- // associated returned by getComputedStyle(), e.g.
- return this._element.getAttribute("style");
- },
- set: function(value) {
- // XXX: I should parse and serialize the value to
- // normalize it and remove errors. FF and chrome do that.
- this._element.setAttribute("style", value);
- }
- },
-
- length: { get: function() {
- if (!this._names)
- this._names = Object.getOwnPropertyNames(this._parsed.property);
- return this._names.length;
- }},
-
- item: { value: function(n) {
- if (!this._names)
- this._names = Object.getOwnPropertyNames(this._parsed.property);
- return this._names[n];
- }},
-
- getPropertyValue: { value: function(property) {
- property = property.toLowerCase();
- return this._parsed.property[property] || "";
- }},
-
- getPropertyPriority: { value: function(property) {
- property = property.toLowerCase();
- return this._parsed.priority[property] || "";
- }},
-
- setProperty: { value: function(property, value, priority) {
- property = property.toLowerCase();
- if (value === null || value === undefined) {
- value = "";
- }
- if (priority === null || priority === undefined) {
- priority = "";
- }
-
- // String coercion
- if (value !== NO_CHANGE) {
- value = "" + value;
- }
-
- if (value === "") {
- this.removeProperty(property);
- return;
- }
-
- if (priority !== "" && priority !== NO_CHANGE &&
- !/^important$/i.test(priority)) {
- return;
- }
-
- var styles = this._parsed;
- if (value === NO_CHANGE) {
- if (!styles.property[property]) {
- return; // Not a valid property name.
- }
- if (priority !== "") {
- styles.priority[property] = "important";
- } else {
- delete styles.priority[property];
- }
- } else {
- // We don't just accept the property value. Instead
- // we parse it to ensure that it is something valid.
- // If it contains a semicolon it is invalid
- if (value.indexOf(";") !== -1) return;
-
- var newprops = parseStyles(property + ":" + value);
- if (Object.getOwnPropertyNames(newprops.property).length === 0) {
- return; // no valid property found
- }
- if (Object.getOwnPropertyNames(newprops.priority).length !== 0) {
- return; // if the value included '!important' it wasn't valid.
- }
-
- // XXX handle shorthand properties
-
- for (var p in newprops.property) {
- styles.property[p] = newprops.property[p];
- if (priority === NO_CHANGE) {
- continue;
- } else if (priority !== "") {
- styles.priority[p] = "important";
- } else if (styles.priority[p]) {
- delete styles.priority[p];
- }
- }
- }
-
- // Serialize and update cssText and element.style!
- this._serialize();
- }},
-
- setPropertyValue: { value: function(property, value) {
- return this.setProperty(property, value, NO_CHANGE);
- }},
-
- setPropertyPriority: { value: function(property, priority) {
- return this.setProperty(property, NO_CHANGE, priority);
- }},
-
- removeProperty: { value: function(property) {
- property = property.toLowerCase();
- var styles = this._parsed;
- if (property in styles.property) {
- delete styles.property[property];
- delete styles.priority[property];
-
- // Serialize and update cssText and element.style!
- this._serialize();
- }
- }},
-});
-
-var cssProperties = {
- alignContent: "align-content",
- alignItems: "align-items",
- alignmentBaseline: "alignment-baseline",
- alignSelf: "align-self",
- animation: "animation",
- animationDelay: "animation-delay",
- animationDirection: "animation-direction",
- animationDuration: "animation-duration",
- animationFillMode: "animation-fill-mode",
- animationIterationCount: "animation-iteration-count",
- animationName: "animation-name",
- animationPlayState: "animation-play-state",
- animationTimingFunction: "animation-timing-function",
- backfaceVisibility: "backface-visibility",
- background: "background",
- backgroundAttachment: "background-attachment",
- backgroundClip: "background-clip",
- backgroundColor: "background-color",
- backgroundImage: "background-image",
- backgroundOrigin: "background-origin",
- backgroundPosition: "background-position",
- backgroundPositionX: "background-position-x",
- backgroundPositionY: "background-position-y",
- backgroundRepeat: "background-repeat",
- backgroundSize: "background-size",
- baselineShift: "baseline-shift",
- border: "border",
- borderBottom: "border-bottom",
- borderBottomColor: "border-bottom-color",
- borderBottomLeftRadius: "border-bottom-left-radius",
- borderBottomRightRadius: "border-bottom-right-radius",
- borderBottomStyle: "border-bottom-style",
- borderBottomWidth: "border-bottom-width",
- borderCollapse: "border-collapse",
- borderColor: "border-color",
- borderImage: "border-image",
- borderImageOutset: "border-image-outset",
- borderImageRepeat: "border-image-repeat",
- borderImageSlice: "border-image-slice",
- borderImageSource: "border-image-source",
- borderImageWidth: "border-image-width",
- borderLeft: "border-left",
- borderLeftColor: "border-left-color",
- borderLeftStyle: "border-left-style",
- borderLeftWidth: "border-left-width",
- borderRadius: "border-radius",
- borderRight: "border-right",
- borderRightColor: "border-right-color",
- borderRightStyle: "border-right-style",
- borderRightWidth: "border-right-width",
- borderSpacing: "border-spacing",
- borderStyle: "border-style",
- borderTop: "border-top",
- borderTopColor: "border-top-color",
- borderTopLeftRadius: "border-top-left-radius",
- borderTopRightRadius: "border-top-right-radius",
- borderTopStyle: "border-top-style",
- borderTopWidth: "border-top-width",
- borderWidth: "border-width",
- bottom: "bottom",
- boxShadow: "box-shadow",
- boxSizing: "box-sizing",
- breakAfter: "break-after",
- breakBefore: "break-before",
- breakInside: "break-inside",
- captionSide: "caption-side",
- clear: "clear",
- clip: "clip",
- clipPath: "clip-path",
- clipRule: "clip-rule",
- color: "color",
- colorInterpolationFilters: "color-interpolation-filters",
- columnCount: "column-count",
- columnFill: "column-fill",
- columnGap: "column-gap",
- columnRule: "column-rule",
- columnRuleColor: "column-rule-color",
- columnRuleStyle: "column-rule-style",
- columnRuleWidth: "column-rule-width",
- columns: "columns",
- columnSpan: "column-span",
- columnWidth: "column-width",
- content: "content",
- counterIncrement: "counter-increment",
- counterReset: "counter-reset",
- cssFloat: "float",
- cursor: "cursor",
- direction: "direction",
- display: "display",
- dominantBaseline: "dominant-baseline",
- emptyCells: "empty-cells",
- enableBackground: "enable-background",
- fill: "fill",
- fillOpacity: "fill-opacity",
- fillRule: "fill-rule",
- filter: "filter",
- flex: "flex",
- flexBasis: "flex-basis",
- flexDirection: "flex-direction",
- flexFlow: "flex-flow",
- flexGrow: "flex-grow",
- flexShrink: "flex-shrink",
- flexWrap: "flex-wrap",
- floodColor: "flood-color",
- floodOpacity: "flood-opacity",
- font: "font",
- fontFamily: "font-family",
- fontFeatureSettings: "font-feature-settings",
- fontSize: "font-size",
- fontSizeAdjust: "font-size-adjust",
- fontStretch: "font-stretch",
- fontStyle: "font-style",
- fontVariant: "font-variant",
- fontWeight: "font-weight",
- glyphOrientationHorizontal: "glyph-orientation-horizontal",
- glyphOrientationVertical: "glyph-orientation-vertical",
- grid: "grid",
- gridArea: "grid-area",
- gridAutoColumns: "grid-auto-columns",
- gridAutoFlow: "grid-auto-flow",
- gridAutoRows: "grid-auto-rows",
- gridColumn: "grid-column",
- gridColumnEnd: "grid-column-end",
- gridColumnGap: "grid-column-gap",
- gridColumnStart: "grid-column-start",
- gridGap: "grid-gap",
- gridRow: "grid-row",
- gridRowEnd: "grid-row-end",
- gridRowGap: "grid-row-gap",
- gridRowStart: "grid-row-start",
- gridTemplate: "grid-template",
- gridTemplateAreas: "grid-template-areas",
- gridTemplateColumns: "grid-template-columns",
- gridTemplateRows: "grid-template-rows",
- height: "height",
- imeMode: "ime-mode",
- justifyContent: "justify-content",
- kerning: "kerning",
- layoutGrid: "layout-grid",
- layoutGridChar: "layout-grid-char",
- layoutGridLine: "layout-grid-line",
- layoutGridMode: "layout-grid-mode",
- layoutGridType: "layout-grid-type",
- left: "left",
- letterSpacing: "letter-spacing",
- lightingColor: "lighting-color",
- lineBreak: "line-break",
- lineHeight: "line-height",
- listStyle: "list-style",
- listStyleImage: "list-style-image",
- listStylePosition: "list-style-position",
- listStyleType: "list-style-type",
- margin: "margin",
- marginBottom: "margin-bottom",
- marginLeft: "margin-left",
- marginRight: "margin-right",
- marginTop: "margin-top",
- marker: "marker",
- markerEnd: "marker-end",
- markerMid: "marker-mid",
- markerStart: "marker-start",
- mask: "mask",
- maxHeight: "max-height",
- maxWidth: "max-width",
- minHeight: "min-height",
- minWidth: "min-width",
- msContentZoomChaining: "-ms-content-zoom-chaining",
- msContentZooming: "-ms-content-zooming",
- msContentZoomLimit: "-ms-content-zoom-limit",
- msContentZoomLimitMax: "-ms-content-zoom-limit-max",
- msContentZoomLimitMin: "-ms-content-zoom-limit-min",
- msContentZoomSnap: "-ms-content-zoom-snap",
- msContentZoomSnapPoints: "-ms-content-zoom-snap-points",
- msContentZoomSnapType: "-ms-content-zoom-snap-type",
- msFlowFrom: "-ms-flow-from",
- msFlowInto: "-ms-flow-into",
- msFontFeatureSettings: "-ms-font-feature-settings",
- msGridColumn: "-ms-grid-column",
- msGridColumnAlign: "-ms-grid-column-align",
- msGridColumns: "-ms-grid-columns",
- msGridColumnSpan: "-ms-grid-column-span",
- msGridRow: "-ms-grid-row",
- msGridRowAlign: "-ms-grid-row-align",
- msGridRows: "-ms-grid-rows",
- msGridRowSpan: "-ms-grid-row-span",
- msHighContrastAdjust: "-ms-high-contrast-adjust",
- msHyphenateLimitChars: "-ms-hyphenate-limit-chars",
- msHyphenateLimitLines: "-ms-hyphenate-limit-lines",
- msHyphenateLimitZone: "-ms-hyphenate-limit-zone",
- msHyphens: "-ms-hyphens",
- msImeAlign: "-ms-ime-align",
- msOverflowStyle: "-ms-overflow-style",
- msScrollChaining: "-ms-scroll-chaining",
- msScrollLimit: "-ms-scroll-limit",
- msScrollLimitXMax: "-ms-scroll-limit-x-max",
- msScrollLimitXMin: "-ms-scroll-limit-x-min",
- msScrollLimitYMax: "-ms-scroll-limit-y-max",
- msScrollLimitYMin: "-ms-scroll-limit-y-min",
- msScrollRails: "-ms-scroll-rails",
- msScrollSnapPointsX: "-ms-scroll-snap-points-x",
- msScrollSnapPointsY: "-ms-scroll-snap-points-y",
- msScrollSnapType: "-ms-scroll-snap-type",
- msScrollSnapX: "-ms-scroll-snap-x",
- msScrollSnapY: "-ms-scroll-snap-y",
- msScrollTranslation: "-ms-scroll-translation",
- msTextCombineHorizontal: "-ms-text-combine-horizontal",
- msTextSizeAdjust: "-ms-text-size-adjust",
- msTouchAction: "-ms-touch-action",
- msTouchSelect: "-ms-touch-select",
- msUserSelect: "-ms-user-select",
- msWrapFlow: "-ms-wrap-flow",
- msWrapMargin: "-ms-wrap-margin",
- msWrapThrough: "-ms-wrap-through",
- opacity: "opacity",
- order: "order",
- orphans: "orphans",
- outline: "outline",
- outlineColor: "outline-color",
- outlineOffset: "outline-offset",
- outlineStyle: "outline-style",
- outlineWidth: "outline-width",
- overflow: "overflow",
- overflowX: "overflow-x",
- overflowY: "overflow-y",
- padding: "padding",
- paddingBottom: "padding-bottom",
- paddingLeft: "padding-left",
- paddingRight: "padding-right",
- paddingTop: "padding-top",
- page: "page",
- pageBreakAfter: "page-break-after",
- pageBreakBefore: "page-break-before",
- pageBreakInside: "page-break-inside",
- perspective: "perspective",
- perspectiveOrigin: "perspective-origin",
- pointerEvents: "pointer-events",
- position: "position",
- quotes: "quotes",
- right: "right",
- rotate: "rotate",
- rubyAlign: "ruby-align",
- rubyOverhang: "ruby-overhang",
- rubyPosition: "ruby-position",
- scale: "scale",
- size: "size",
- stopColor: "stop-color",
- stopOpacity: "stop-opacity",
- stroke: "stroke",
- strokeDasharray: "stroke-dasharray",
- strokeDashoffset: "stroke-dashoffset",
- strokeLinecap: "stroke-linecap",
- strokeLinejoin: "stroke-linejoin",
- strokeMiterlimit: "stroke-miterlimit",
- strokeOpacity: "stroke-opacity",
- strokeWidth: "stroke-width",
- tableLayout: "table-layout",
- textAlign: "text-align",
- textAlignLast: "text-align-last",
- textAnchor: "text-anchor",
- textDecoration: "text-decoration",
- textIndent: "text-indent",
- textJustify: "text-justify",
- textKashida: "text-kashida",
- textKashidaSpace: "text-kashida-space",
- textOverflow: "text-overflow",
- textShadow: "text-shadow",
- textTransform: "text-transform",
- textUnderlinePosition: "text-underline-position",
- top: "top",
- touchAction: "touch-action",
- transform: "transform",
- transformOrigin: "transform-origin",
- transformStyle: "transform-style",
- transition: "transition",
- transitionDelay: "transition-delay",
- transitionDuration: "transition-duration",
- transitionProperty: "transition-property",
- transitionTimingFunction: "transition-timing-function",
- translate: "translate",
- unicodeBidi: "unicode-bidi",
- verticalAlign: "vertical-align",
- visibility: "visibility",
- webkitAlignContent: "-webkit-align-content",
- webkitAlignItems: "-webkit-align-items",
- webkitAlignSelf: "-webkit-align-self",
- webkitAnimation: "-webkit-animation",
- webkitAnimationDelay: "-webkit-animation-delay",
- webkitAnimationDirection: "-webkit-animation-direction",
- webkitAnimationDuration: "-webkit-animation-duration",
- webkitAnimationFillMode: "-webkit-animation-fill-mode",
- webkitAnimationIterationCount: "-webkit-animation-iteration-count",
- webkitAnimationName: "-webkit-animation-name",
- webkitAnimationPlayState: "-webkit-animation-play-state",
- webkitAnimationTimingFunction: "-webkit-animation-timing-funciton",
- webkitAppearance: "-webkit-appearance",
- webkitBackfaceVisibility: "-webkit-backface-visibility",
- webkitBackgroundClip: "-webkit-background-clip",
- webkitBackgroundOrigin: "-webkit-background-origin",
- webkitBackgroundSize: "-webkit-background-size",
- webkitBorderBottomLeftRadius: "-webkit-border-bottom-left-radius",
- webkitBorderBottomRightRadius: "-webkit-border-bottom-right-radius",
- webkitBorderImage: "-webkit-border-image",
- webkitBorderRadius: "-webkit-border-radius",
- webkitBorderTopLeftRadius: "-webkit-border-top-left-radius",
- webkitBorderTopRightRadius: "-webkit-border-top-right-radius",
- webkitBoxAlign: "-webkit-box-align",
- webkitBoxDirection: "-webkit-box-direction",
- webkitBoxFlex: "-webkit-box-flex",
- webkitBoxOrdinalGroup: "-webkit-box-ordinal-group",
- webkitBoxOrient: "-webkit-box-orient",
- webkitBoxPack: "-webkit-box-pack",
- webkitBoxSizing: "-webkit-box-sizing",
- webkitColumnBreakAfter: "-webkit-column-break-after",
- webkitColumnBreakBefore: "-webkit-column-break-before",
- webkitColumnBreakInside: "-webkit-column-break-inside",
- webkitColumnCount: "-webkit-column-count",
- webkitColumnGap: "-webkit-column-gap",
- webkitColumnRule: "-webkit-column-rule",
- webkitColumnRuleColor: "-webkit-column-rule-color",
- webkitColumnRuleStyle: "-webkit-column-rule-style",
- webkitColumnRuleWidth: "-webkit-column-rule-width",
- webkitColumns: "-webkit-columns",
- webkitColumnSpan: "-webkit-column-span",
- webkitColumnWidth: "-webkit-column-width",
- webkitFilter: "-webkit-filter",
- webkitFlex: "-webkit-flex",
- webkitFlexBasis: "-webkit-flex-basis",
- webkitFlexDirection: "-webkit-flex-direction",
- webkitFlexFlow: "-webkit-flex-flow",
- webkitFlexGrow: "-webkit-flex-grow",
- webkitFlexShrink: "-webkit-flex-shrink",
- webkitFlexWrap: "-webkit-flex-wrap",
- webkitJustifyContent: "-webkit-justify-content",
- webkitOrder: "-webkit-order",
- webkitPerspective: "-webkit-perspective-origin",
- webkitPerspectiveOrigin: "-webkit-perspective-origin",
- webkitTapHighlightColor: "-webkit-tap-highlight-color",
- webkitTextFillColor: "-webkit-text-fill-color",
- webkitTextSizeAdjust: "-webkit-text-size-adjust",
- webkitTextStroke: "-webkit-text-stroke",
- webkitTextStrokeColor: "-webkit-text-stroke-color",
- webkitTextStrokeWidth: "-webkit-text-stroke-width",
- webkitTransform: "-webkit-transform",
- webkitTransformOrigin: "-webkit-transform-origin",
- webkitTransformStyle: "-webkit-transform-style",
- webkitTransition: "-webkit-transition",
- webkitTransitionDelay: "-webkit-transition-delay",
- webkitTransitionDuration: "-webkit-transition-duration",
- webkitTransitionProperty: "-webkit-transition-property",
- webkitTransitionTimingFunction: "-webkit-transition-timing-function",
- webkitUserModify: "-webkit-user-modify",
- webkitUserSelect: "-webkit-user-select",
- webkitWritingMode: "-webkit-writing-mode",
- whiteSpace: "white-space",
- widows: "widows",
- width: "width",
- wordBreak: "word-break",
- wordSpacing: "word-spacing",
- wordWrap: "word-wrap",
- writingMode: "writing-mode",
- zIndex: "z-index",
- zoom: "zoom",
- resize: "resize",
- userSelect: "user-select",
-};
-
-for(var prop in cssProperties) defineStyleProperty(prop);
-
-function defineStyleProperty(jsname) {
- var cssname = cssProperties[jsname];
- Object.defineProperty(CSSStyleDeclaration.prototype, jsname, {
- get: function() {
- return this.getPropertyValue(cssname);
- },
- set: function(value) {
- this.setProperty(cssname, value);
- }
- });
-
- if (!CSSStyleDeclaration.prototype.hasOwnProperty(cssname)) {
- Object.defineProperty(CSSStyleDeclaration.prototype, cssname, {
- get: function() {
- return this.getPropertyValue(cssname);
- },
- set: function(value) {
- this.setProperty(cssname, value);
- }
- });
- }
-}
--- a/cmd/gojafs/domino/domino-lib/CharacterData.js
+++ /dev/null
@@ -1,120 +1,0 @@
-/* jshint bitwise: false */
-"use strict";
-module.exports = CharacterData;
-
-var Leaf = require('./Leaf');
-var utils = require('./utils');
-var ChildNode = require('./ChildNode');
-var NonDocumentTypeChildNode = require('./NonDocumentTypeChildNode');
-
-function CharacterData() {
- Leaf.call(this);
-}
-
-CharacterData.prototype = Object.create(Leaf.prototype, {
- // DOMString substringData(unsigned long offset,
- // unsigned long count);
- // The substringData(offset, count) method must run these steps:
- //
- // If offset is greater than the context object's
- // length, throw an INDEX_SIZE_ERR exception and
- // terminate these steps.
- //
- // If offset+count is greater than the context
- // object's length, return a DOMString whose value is
- // the UTF-16 code units from the offsetth UTF-16 code
- // unit to the end of data.
- //
- // Return a DOMString whose value is the UTF-16 code
- // units from the offsetth UTF-16 code unit to the
- // offset+countth UTF-16 code unit in data.
- substringData: { value: function substringData(offset, count) {
- if (arguments.length < 2) { throw new TypeError("Not enough arguments"); }
- // Convert arguments to WebIDL "unsigned long"
- offset = offset >>> 0;
- count = count >>> 0;
- if (offset > this.data.length || offset < 0 || count < 0) {
- utils.IndexSizeError();
- }
- return this.data.substring(offset, offset+count);
- }},
-
- // void appendData(DOMString data);
- // The appendData(data) method must append data to the context
- // object's data.
- appendData: { value: function appendData(data) {
- if (arguments.length < 1) { throw new TypeError("Not enough arguments"); }
- this.data += String(data);
- }},
-
- // void insertData(unsigned long offset, DOMString data);
- // The insertData(offset, data) method must run these steps:
- //
- // If offset is greater than the context object's
- // length, throw an INDEX_SIZE_ERR exception and
- // terminate these steps.
- //
- // Insert data into the context object's data after
- // offset UTF-16 code units.
- //
- insertData: { value: function insertData(offset, data) {
- return this.replaceData(offset, 0, data);
- }},
-
-
- // void deleteData(unsigned long offset, unsigned long count);
- // The deleteData(offset, count) method must run these steps:
- //
- // If offset is greater than the context object's
- // length, throw an INDEX_SIZE_ERR exception and
- // terminate these steps.
- //
- // If offset+count is greater than the context
- // object's length var count be length-offset.
- //
- // Starting from offset UTF-16 code units remove count
- // UTF-16 code units from the context object's data.
- deleteData: { value: function deleteData(offset, count) {
- return this.replaceData(offset, count, '');
- }},
-
-
- // void replaceData(unsigned long offset, unsigned long count,
- // DOMString data);
- //
- // The replaceData(offset, count, data) method must act as
- // if the deleteData() method is invoked with offset and
- // count as arguments followed by the insertData() method
- // with offset and data as arguments and re-throw any
- // exceptions these methods might have thrown.
- replaceData: { value: function replaceData(offset, count, data) {
- var curtext = this.data, len = curtext.length;
- // Convert arguments to correct WebIDL type
- offset = offset >>> 0;
- count = count >>> 0;
- data = String(data);
-
- if (offset > len || offset < 0) utils.IndexSizeError();
-
- if (offset+count > len)
- count = len - offset;
-
- var prefix = curtext.substring(0, offset),
- suffix = curtext.substring(offset+count);
-
- this.data = prefix + data + suffix;
- }},
-
- // Utility method that Node.isEqualNode() calls to test Text and
- // Comment nodes for equality. It is okay to put it here, since
- // Node will have already verified that nodeType is equal
- isEqual: { value: function isEqual(n) {
- return this._data === n._data;
- }},
-
- length: { get: function() { return this.data.length; }}
-
-});
-
-Object.defineProperties(CharacterData.prototype, ChildNode);
-Object.defineProperties(CharacterData.prototype, NonDocumentTypeChildNode);
--- a/cmd/gojafs/domino/domino-lib/ChildNode.js
+++ /dev/null
@@ -1,119 +1,0 @@
-"use strict";
-
-var Node = require('./Node');
-var LinkedList = require('./LinkedList');
-
-var createDocumentFragmentFromArguments = function(document, args) {
- var docFrag = document.createDocumentFragment();
-
- for (var i=0; i<args.length; i++) {
- var argItem = args[i];
- var isNode = argItem instanceof Node;
- docFrag.appendChild(isNode ? argItem :
- document.createTextNode(String(argItem)));
- }
-
- return docFrag;
-};
-
-// The ChildNode interface contains methods that are particular to `Node`
-// objects that can have a parent. It is implemented by `Element`,
-// `DocumentType`, and `CharacterData` objects.
-var ChildNode = {
-
- // Inserts a set of Node or String objects in the children list of this
- // ChildNode's parent, just after this ChildNode. String objects are
- // inserted as the equivalent Text nodes.
- after: { value: function after() {
- var argArr = Array.prototype.slice.call(arguments);
- var parentNode = this.parentNode, nextSibling = this.nextSibling;
- if (parentNode === null) { return; }
- // Find "viable next sibling"; that is, next one not in argArr
- while (nextSibling && argArr.some(function(v) { return v===nextSibling; }))
- nextSibling = nextSibling.nextSibling;
- // ok, parent and sibling are saved away since this node could itself
- // appear in argArr and we're about to move argArr to a document fragment.
- var docFrag = createDocumentFragmentFromArguments(this.doc, argArr);
-
- parentNode.insertBefore(docFrag, nextSibling);
- }},
-
- // Inserts a set of Node or String objects in the children list of this
- // ChildNode's parent, just before this ChildNode. String objects are
- // inserted as the equivalent Text nodes.
- before: { value: function before() {
- var argArr = Array.prototype.slice.call(arguments);
- var parentNode = this.parentNode, prevSibling = this.previousSibling;
- if (parentNode === null) { return; }
- // Find "viable prev sibling"; that is, prev one not in argArr
- while (prevSibling && argArr.some(function(v) { return v===prevSibling; }))
- prevSibling = prevSibling.previousSibling;
- // ok, parent and sibling are saved away since this node could itself
- // appear in argArr and we're about to move argArr to a document fragment.
- var docFrag = createDocumentFragmentFromArguments(this.doc, argArr);
-
- var nextSibling =
- prevSibling ? prevSibling.nextSibling : parentNode.firstChild;
- parentNode.insertBefore(docFrag, nextSibling);
- }},
-
- // Remove this node from its parent
- remove: { value: function remove() {
- if (this.parentNode === null) return;
-
- // Send mutation events if necessary
- if (this.doc) {
- this.doc._preremoveNodeIterators(this);
- if (this.rooted) {
- this.doc.mutateRemove(this);
- }
- }
-
- // Remove this node from its parents array of children
- // and update the structure id for all ancestors
- this._remove();
-
- // Forget this node's parent
- this.parentNode = null;
- }},
-
- // Remove this node w/o uprooting or sending mutation events
- // (But do update the structure id for all ancestors)
- _remove: { value: function _remove() {
- var parent = this.parentNode;
- if (parent === null) return;
- if (parent._childNodes) {
- parent._childNodes.splice(this.index, 1);
- } else if (parent._firstChild === this) {
- if (this._nextSibling === this) {
- parent._firstChild = null;
- } else {
- parent._firstChild = this._nextSibling;
- }
- }
- LinkedList.remove(this);
- parent.modify();
- }},
-
- // Replace this node with the nodes or strings provided as arguments.
- replaceWith: { value: function replaceWith() {
- var argArr = Array.prototype.slice.call(arguments);
- var parentNode = this.parentNode, nextSibling = this.nextSibling;
- if (parentNode === null) { return; }
- // Find "viable next sibling"; that is, next one not in argArr
- while (nextSibling && argArr.some(function(v) { return v===nextSibling; }))
- nextSibling = nextSibling.nextSibling;
- // ok, parent and sibling are saved away since this node could itself
- // appear in argArr and we're about to move argArr to a document fragment.
- var docFrag = createDocumentFragmentFromArguments(this.doc, argArr);
- if (this.parentNode === parentNode) {
- parentNode.replaceChild(docFrag, this);
- } else {
- // `this` was inserted into docFrag
- parentNode.insertBefore(docFrag, nextSibling);
- }
- }},
-
-};
-
-module.exports = ChildNode;
--- a/cmd/gojafs/domino/domino-lib/Comment.js
+++ /dev/null
@@ -1,39 +1,0 @@
-"use strict";
-module.exports = Comment;
-
-var Node = require('./Node');
-var CharacterData = require('./CharacterData');
-
-function Comment(doc, data) {
- CharacterData.call(this);
- this.nodeType = Node.COMMENT_NODE;
- this.ownerDocument = doc;
- this._data = data;
-}
-
-var nodeValue = {
- get: function() { return this._data; },
- set: function(v) {
- if (v === null || v === undefined) { v = ''; } else { v = String(v); }
- this._data = v;
- if (this.rooted)
- this.ownerDocument.mutateValue(this);
- }
-};
-
-Comment.prototype = Object.create(CharacterData.prototype, {
- nodeName: { value: '#comment' },
- nodeValue: nodeValue,
- textContent: nodeValue,
- data: {
- get: nodeValue.get,
- set: function(v) {
- nodeValue.set.call(this, v===null ? '' : String(v));
- },
- },
-
- // Utility methods
- clone: { value: function clone() {
- return new Comment(this.ownerDocument, this._data);
- }},
-});
--- a/cmd/gojafs/domino/domino-lib/ContainerNode.js
+++ /dev/null
@@ -1,80 +1,0 @@
-"use strict";
-module.exports = ContainerNode;
-
-var Node = require('./Node');
-var NodeList = require('./NodeList');
-
-// This class defines common functionality for node subtypes that
-// can have children
-
-function ContainerNode() {
- Node.call(this);
- this._firstChild = this._childNodes = null;
-}
-
-// Primary representation is a circular linked list of siblings
-ContainerNode.prototype = Object.create(Node.prototype, {
-
- hasChildNodes: { value: function() {
- if (this._childNodes) {
- return this._childNodes.length > 0;
- }
- return this._firstChild !== null;
- }},
-
- childNodes: { get: function() {
- this._ensureChildNodes();
- return this._childNodes;
- }},
-
- firstChild: { get: function() {
- if (this._childNodes) {
- return this._childNodes.length === 0 ? null : this._childNodes[0];
- }
- return this._firstChild;
- }},
-
- lastChild: { get: function() {
- var kids = this._childNodes, first;
- if (kids) {
- return kids.length === 0 ? null: kids[kids.length-1];
- }
- first = this._firstChild;
- if (first === null) { return null; }
- return first._previousSibling; // circular linked list
- }},
-
- _ensureChildNodes: { value: function() {
- if (this._childNodes) { return; }
- var first = this._firstChild,
- kid = first,
- childNodes = this._childNodes = new NodeList();
- if (first) do {
- childNodes.push(kid);
- kid = kid._nextSibling;
- } while (kid !== first); // circular linked list
- this._firstChild = null; // free memory
- }},
-
- // Remove all of this node's children. This is a minor
- // optimization that only calls modify() once.
- removeChildren: { value: function removeChildren() {
- var root = this.rooted ? this.ownerDocument : null,
- next = this.firstChild,
- kid;
- while (next !== null) {
- kid = next;
- next = kid.nextSibling;
-
- if (root) root.mutateRemove(kid);
- kid.parentNode = null;
- }
- if (this._childNodes) {
- this._childNodes.length = 0;
- } else {
- this._firstChild = null;
- }
- this.modify(); // Update last modified type once only
- }},
-
-});
--- a/cmd/gojafs/domino/domino-lib/CustomEvent.js
+++ /dev/null
@@ -1,12 +1,0 @@
-"use strict";
-module.exports = CustomEvent;
-
-var Event = require('./Event');
-
-function CustomEvent(type, dictionary) {
- // Just use the superclass constructor to initialize
- Event.call(this, type, dictionary);
-}
-CustomEvent.prototype = Object.create(Event.prototype, {
- constructor: { value: CustomEvent }
-});
--- a/cmd/gojafs/domino/domino-lib/DOMException.js
+++ /dev/null
@@ -1,134 +1,0 @@
-"use strict";
-module.exports = DOMException;
-
-var INDEX_SIZE_ERR = 1;
-var HIERARCHY_REQUEST_ERR = 3;
-var WRONG_DOCUMENT_ERR = 4;
-var INVALID_CHARACTER_ERR = 5;
-var NO_MODIFICATION_ALLOWED_ERR = 7;
-var NOT_FOUND_ERR = 8;
-var NOT_SUPPORTED_ERR = 9;
-var INVALID_STATE_ERR = 11;
-var SYNTAX_ERR = 12;
-var INVALID_MODIFICATION_ERR = 13;
-var NAMESPACE_ERR = 14;
-var INVALID_ACCESS_ERR = 15;
-var TYPE_MISMATCH_ERR = 17;
-var SECURITY_ERR = 18;
-var NETWORK_ERR = 19;
-var ABORT_ERR = 20;
-var URL_MISMATCH_ERR = 21;
-var QUOTA_EXCEEDED_ERR = 22;
-var TIMEOUT_ERR = 23;
-var INVALID_NODE_TYPE_ERR = 24;
-var DATA_CLONE_ERR = 25;
-
-// Code to name
-var names = [
- null, // No error with code 0
- 'INDEX_SIZE_ERR',
- null, // historical
- 'HIERARCHY_REQUEST_ERR',
- 'WRONG_DOCUMENT_ERR',
- 'INVALID_CHARACTER_ERR',
- null, // historical
- 'NO_MODIFICATION_ALLOWED_ERR',
- 'NOT_FOUND_ERR',
- 'NOT_SUPPORTED_ERR',
- 'INUSE_ATTRIBUTE_ERR', // historical
- 'INVALID_STATE_ERR',
- 'SYNTAX_ERR',
- 'INVALID_MODIFICATION_ERR',
- 'NAMESPACE_ERR',
- 'INVALID_ACCESS_ERR',
- null, // historical
- 'TYPE_MISMATCH_ERR',
- 'SECURITY_ERR',
- 'NETWORK_ERR',
- 'ABORT_ERR',
- 'URL_MISMATCH_ERR',
- 'QUOTA_EXCEEDED_ERR',
- 'TIMEOUT_ERR',
- 'INVALID_NODE_TYPE_ERR',
- 'DATA_CLONE_ERR',
-];
-
-// Code to message
-// These strings are from the 13 May 2011 Editor's Draft of DOM Core.
-// http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html
-// Copyright © 2011 W3C® (MIT, ERCIM, Keio), All Rights Reserved.
-// Used under the terms of the W3C Document License:
-// http://www.w3.org/Consortium/Legal/2002/copyright-documents-20021231
-var messages = [
- null, // No error with code 0
- 'INDEX_SIZE_ERR (1): the index is not in the allowed range',
- null,
- 'HIERARCHY_REQUEST_ERR (3): the operation would yield an incorrect nodes model',
- 'WRONG_DOCUMENT_ERR (4): the object is in the wrong Document, a call to importNode is required',
- 'INVALID_CHARACTER_ERR (5): the string contains invalid characters',
- null,
- 'NO_MODIFICATION_ALLOWED_ERR (7): the object can not be modified',
- 'NOT_FOUND_ERR (8): the object can not be found here',
- 'NOT_SUPPORTED_ERR (9): this operation is not supported',
- 'INUSE_ATTRIBUTE_ERR (10): setAttributeNode called on owned Attribute',
- 'INVALID_STATE_ERR (11): the object is in an invalid state',
- 'SYNTAX_ERR (12): the string did not match the expected pattern',
- 'INVALID_MODIFICATION_ERR (13): the object can not be modified in this way',
- 'NAMESPACE_ERR (14): the operation is not allowed by Namespaces in XML',
- 'INVALID_ACCESS_ERR (15): the object does not support the operation or argument',
- null,
- 'TYPE_MISMATCH_ERR (17): the type of the object does not match the expected type',
- 'SECURITY_ERR (18): the operation is insecure',
- 'NETWORK_ERR (19): a network error occurred',
- 'ABORT_ERR (20): the user aborted an operation',
- 'URL_MISMATCH_ERR (21): the given URL does not match another URL',
- 'QUOTA_EXCEEDED_ERR (22): the quota has been exceeded',
- 'TIMEOUT_ERR (23): a timeout occurred',
- 'INVALID_NODE_TYPE_ERR (24): the supplied node is invalid or has an invalid ancestor for this operation',
- 'DATA_CLONE_ERR (25): the object can not be cloned.'
-];
-
-// Name to code
-var constants = {
- INDEX_SIZE_ERR: INDEX_SIZE_ERR,
- DOMSTRING_SIZE_ERR: 2, // historical
- HIERARCHY_REQUEST_ERR: HIERARCHY_REQUEST_ERR,
- WRONG_DOCUMENT_ERR: WRONG_DOCUMENT_ERR,
- INVALID_CHARACTER_ERR: INVALID_CHARACTER_ERR,
- NO_DATA_ALLOWED_ERR: 6, // historical
- NO_MODIFICATION_ALLOWED_ERR: NO_MODIFICATION_ALLOWED_ERR,
- NOT_FOUND_ERR: NOT_FOUND_ERR,
- NOT_SUPPORTED_ERR: NOT_SUPPORTED_ERR,
- INUSE_ATTRIBUTE_ERR: 10, // historical
- 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,
- VALIDATION_ERR: 16, // historical
- TYPE_MISMATCH_ERR: TYPE_MISMATCH_ERR,
- SECURITY_ERR: SECURITY_ERR,
- NETWORK_ERR: NETWORK_ERR,
- ABORT_ERR: ABORT_ERR,
- URL_MISMATCH_ERR: URL_MISMATCH_ERR,
- QUOTA_EXCEEDED_ERR: QUOTA_EXCEEDED_ERR,
- TIMEOUT_ERR: TIMEOUT_ERR,
- INVALID_NODE_TYPE_ERR: INVALID_NODE_TYPE_ERR,
- DATA_CLONE_ERR: DATA_CLONE_ERR
-};
-
-function DOMException(code) {
- Error.call(this);
- Error.captureStackTrace(this, this.constructor);
- this.code = code;
- this.message = messages[code];
- this.name = names[code];
-}
-DOMException.prototype.__proto__ = Error.prototype;
-
-// Initialize the constants on DOMException and DOMException.prototype
-for(var c in constants) {
- var v = { value: constants[c] };
- Object.defineProperty(DOMException, c, v);
- Object.defineProperty(DOMException.prototype, c, v);
-}
--- a/cmd/gojafs/domino/domino-lib/DOMImplementation.js
+++ /dev/null
@@ -1,94 +1,0 @@
-"use strict";
-module.exports = DOMImplementation;
-
-var Document = require('./Document');
-var DocumentType = require('./DocumentType');
-var HTMLParser = require('./HTMLParser');
-var utils = require('./utils');
-var xml = require('./xmlnames');
-
-// Each document must have its own instance of the domimplementation object
-function DOMImplementation(contextObject) {
- this.contextObject = contextObject;
-}
-
-
-// Feature/version pairs that DOMImplementation.hasFeature() returns
-// true for. It returns false for anything else.
-var supportedFeatures = {
- 'xml': { '': true, '1.0': true, '2.0': true }, // DOM Core
- 'core': { '': true, '2.0': true }, // DOM Core
- 'html': { '': true, '1.0': true, '2.0': true} , // HTML
- 'xhtml': { '': true, '1.0': true, '2.0': true} , // HTML
-};
-
-DOMImplementation.prototype = {
- hasFeature: function hasFeature(feature, version) {
- var f = supportedFeatures[(feature || '').toLowerCase()];
- return (f && f[version || '']) || false;
- },
-
- createDocumentType: function createDocumentType(qualifiedName, publicId, systemId) {
- if (!xml.isValidQName(qualifiedName)) utils.InvalidCharacterError();
-
- return new DocumentType(this.contextObject, qualifiedName, publicId, systemId);
- },
-
- createDocument: function createDocument(namespace, qualifiedName, doctype) {
- //
- // Note that the current DOMCore spec makes it impossible to
- // create an HTML document with this function, even if the
- // namespace and doctype are propertly set. See this thread:
- // http://lists.w3.org/Archives/Public/www-dom/2011AprJun/0132.html
- //
- var d = new Document(false, null);
- var e;
-
- if (qualifiedName)
- e = d.createElementNS(namespace, qualifiedName);
- else
- e = null;
-
- if (doctype) {
- d.appendChild(doctype);
- }
-
- if (e) d.appendChild(e);
- if (namespace === utils.NAMESPACE.HTML) {
- d._contentType = 'application/xhtml+xml';
- } else if (namespace === utils.NAMESPACE.SVG) {
- d._contentType = 'image/svg+xml';
- } else {
- d._contentType = 'application/xml';
- }
-
- return d;
- },
-
- createHTMLDocument: function createHTMLDocument(titleText) {
- var d = new Document(true, null);
- d.appendChild(new DocumentType(d, 'html'));
- var html = d.createElement('html');
- d.appendChild(html);
- var head = d.createElement('head');
- html.appendChild(head);
- if (titleText !== undefined) {
- var title = d.createElement('title');
- head.appendChild(title);
- title.appendChild(d.createTextNode(titleText));
- }
- html.appendChild(d.createElement('body'));
- d.modclock = 1; // Start tracking modifications
- return d;
- },
-
- mozSetOutputMutationHandler: function(doc, handler) {
- doc.mutationHandler = handler;
- },
-
- mozGetInputMutationHandler: function(doc) {
- utils.nyi();
- },
-
- mozHTMLParser: HTMLParser,
-};
--- a/cmd/gojafs/domino/domino-lib/DOMTokenList.js
+++ /dev/null
@@ -1,186 +1,0 @@
-"use strict";
-// DOMTokenList implementation based on https://github.com/Raynos/DOM-shim
-var utils = require('./utils');
-
-module.exports = DOMTokenList;
-
-function DOMTokenList(getter, setter) {
- this._getString = getter;
- this._setString = setter;
- this._length = 0;
- this._lastStringValue = '';
- this._update();
-}
-
-Object.defineProperties(DOMTokenList.prototype, {
- length: { get: function() { return this._length; } },
- item: { value: function(index) {
- var list = getList(this);
- if (index < 0 || index >= list.length) {
- return null;
- }
- return list[index];
- }},
-
- contains: { value: function(token) {
- token = String(token); // no error checking for contains()
- var list = getList(this);
- return list.indexOf(token) > -1;
- }},
-
- add: { value: function() {
- var list = getList(this);
- for (var i = 0, len = arguments.length; i < len; i++) {
- var token = handleErrors(arguments[i]);
- if (list.indexOf(token) < 0) {
- list.push(token);
- }
- }
- // Note: as per spec, if handleErrors() throws any errors, we never
- // make it here and none of the changes take effect.
- // Also per spec: we run the "update steps" even if no change was
- // made (ie, if the token already existed)
- this._update(list);
- }},
-
- remove: { value: function() {
- var list = getList(this);
- for (var i = 0, len = arguments.length; i < len; i++) {
- var token = handleErrors(arguments[i]);
- var index = list.indexOf(token);
- if (index > -1) {
- list.splice(index, 1);
- }
- }
- // Note: as per spec, if handleErrors() throws any errors, we never
- // make it here and none of the changes take effect.
- // Also per spec: we run the "update steps" even if no change was
- // made (ie, if the token wasn't previously present)
- this._update(list);
- }},
-
- toggle: { value: function toggle(token, force) {
- token = handleErrors(token);
- if (this.contains(token)) {
- if (force === undefined || force === false) {
- this.remove(token);
- return false;
- }
- return true;
- } else {
- if (force === undefined || force === true) {
- this.add(token);
- return true;
- }
- return false;
- }
- }},
-
- replace: { value: function replace(token, newToken) {
- // weird corner case of spec: if `token` contains whitespace, but
- // `newToken` is the empty string, we must throw SyntaxError not
- // InvalidCharacterError (sigh)
- if (String(newToken)==='') { utils.SyntaxError(); }
- token = handleErrors(token);
- newToken = handleErrors(newToken);
- var list = getList(this);
- var idx = list.indexOf(token);
- if (idx < 0) {
- // Note that, per spec, we do not run the update steps on this path.
- return false;
- }
- var idx2 = list.indexOf(newToken);
- if (idx2 < 0) {
- list[idx] = newToken;
- } else {
- // "replace the first instance of either `token` or `newToken` with
- // `newToken` and remove all other instances"
- if (idx < idx2) {
- list[idx] = newToken;
- list.splice(idx2, 1);
- } else {
- // idx2 is already `newToken`
- list.splice(idx, 1);
- }
- }
- this._update(list);
- return true;
- }},
-
- toString: { value: function() {
- return this._getString();
- }},
-
- value: {
- get: function() {
- return this._getString();
- },
- set: function(v) {
- this._setString(v);
- this._update();
- }
- },
-
- // Called when the setter is called from outside this interface.
- _update: { value: function(list) {
- if (list) {
- fixIndex(this, list);
- this._setString(list.join(" ").trim());
- } else {
- fixIndex(this, getList(this));
- }
- this._lastStringValue = this._getString();
- } },
-});
-
-function fixIndex(clist, list) {
- var oldLength = clist._length;
- var i;
- clist._length = list.length;
- for (i = 0; i < list.length; i++) {
- clist[i] = list[i];
- }
- // Clear/free old entries.
- for (; i < oldLength; i++) {
- clist[i] = undefined;
- }
-}
-
-function handleErrors(token) {
- token = String(token);
- if (token === "") {
- utils.SyntaxError();
- }
- if (/[ \t\r\n\f]/.test(token)) {
- utils.InvalidCharacterError();
- }
- return token;
-}
-
-function toArray(clist) {
- var length = clist._length;
- var arr = Array(length);
- for (var i = 0; i < length; i++) {
- arr[i] = clist[i];
- }
- return arr;
-}
-
-function getList(clist) {
- var strProp = clist._getString();
- if (strProp === clist._lastStringValue) {
- return toArray(clist);
- }
- var str = strProp.replace(/(^[ \t\r\n\f]+)|([ \t\r\n\f]+$)/g, '');
- if (str === "") {
- return [];
- } else {
- var seen = Object.create(null);
- return str.split(/[ \t\r\n\f]+/g).filter(function(n) {
- var key = '$' + n;
- if (seen[key]) { return false; }
- seen[key] = true;
- return true;
- });
- }
-}
--- a/cmd/gojafs/domino/domino-lib/Document.js
+++ /dev/null
@@ -1,884 +1,0 @@
-"use strict";
-module.exports = Document;
-
-var Node = require('./Node');
-var NodeList = require('./NodeList');
-var ContainerNode = require('./ContainerNode');
-var Element = require('./Element');
-var Text = require('./Text');
-var Comment = require('./Comment');
-var Event = require('./Event');
-var DocumentFragment = require('./DocumentFragment');
-var ProcessingInstruction = require('./ProcessingInstruction');
-var DOMImplementation = require('./DOMImplementation');
-var TreeWalker = require('./TreeWalker');
-var NodeIterator = require('./NodeIterator');
-var NodeFilter = require('./NodeFilter');
-var URL = require('./URL');
-var select = require('./select');
-var events = require('./events');
-var xml = require('./xmlnames');
-var html = require('./htmlelts');
-var svg = require('./svg');
-var utils = require('./utils');
-var MUTATE = require('./MutationConstants');
-var NAMESPACE = utils.NAMESPACE;
-var isApiWritable = require("./config").isApiWritable;
-
-function Document(isHTML, address) {
- ContainerNode.call(this);
- this.nodeType = Node.DOCUMENT_NODE;
- this.isHTML = isHTML;
- this._address = address || 'about:blank';
- this.readyState = 'loading';
- this.implementation = new DOMImplementation(this);
-
- // DOMCore says that documents are always associated with themselves
- this.ownerDocument = null; // ... but W3C tests expect null
- this._contentType = isHTML ? 'text/html' : 'application/xml';
-
- // These will be initialized by our custom versions of
- // appendChild and insertBefore that override the inherited
- // Node methods.
- // XXX: override those methods!
- this.doctype = null;
- this.documentElement = null;
-
- // "Associated inert template document"
- this._templateDocCache = null;
- // List of active NodeIterators, see NodeIterator#_preremove()
- this._nodeIterators = null;
-
- // Documents are always rooted, by definition
- this._nid = 1;
- this._nextnid = 2; // For numbering children of the document
- this._nodes = [null, this]; // nid to node map
-
- // This maintains the mapping from element ids to element nodes.
- // We may need to update this mapping every time a node is rooted
- // or uprooted, and any time an attribute is added, removed or changed
- // on a rooted element.
- this.byId = Object.create(null);
-
- // This property holds a monotonically increasing value akin to
- // a timestamp used to record the last modification time of nodes
- // and their subtrees. See the lastModTime attribute and modify()
- // method of the Node class. And see FilteredElementList for an example
- // of the use of lastModTime
- this.modclock = 0;
-}
-
-// Map from lowercase event category names (used as arguments to
-// createEvent()) to the property name in the impl object of the
-// event constructor.
-var supportedEvents = {
- event: 'Event',
- customevent: 'CustomEvent',
- uievent: 'UIEvent',
- mouseevent: 'MouseEvent'
-};
-
-// Certain arguments to document.createEvent() must be treated specially
-var replacementEvent = {
- events: 'event',
- htmlevents: 'event',
- mouseevents: 'mouseevent',
- mutationevents: 'mutationevent',
- uievents: 'uievent'
-};
-
-var mirrorAttr = function(f, name, defaultValue) {
- return {
- get: function() {
- var o = f.call(this);
- if (o) { return o[name]; }
- return defaultValue;
- },
- set: function(value) {
- var o = f.call(this);
- if (o) { o[name] = value; }
- },
- };
-};
-
-/** @spec https://dom.spec.whatwg.org/#validate-and-extract */
-function validateAndExtract(namespace, qualifiedName) {
- var prefix, localName, pos;
- if (namespace==='') { namespace = null; }
- // See https://github.com/whatwg/dom/issues/671
- // and https://github.com/whatwg/dom/issues/319
- if (!xml.isValidQName(qualifiedName)) {
- utils.InvalidCharacterError();
- }
- prefix = null;
- localName = qualifiedName;
-
- pos = qualifiedName.indexOf(':');
- if (pos >= 0) {
- prefix = qualifiedName.substring(0, pos);
- localName = qualifiedName.substring(pos+1);
- }
- if (prefix !== null && namespace === null) {
- utils.NamespaceError();
- }
- if (prefix === 'xml' && namespace !== NAMESPACE.XML) {
- utils.NamespaceError();
- }
- if ((prefix === 'xmlns' || qualifiedName === 'xmlns') &&
- namespace !== NAMESPACE.XMLNS) {
- utils.NamespaceError();
- }
- if (namespace === NAMESPACE.XMLNS && !(prefix==='xmlns' || qualifiedName==='xmlns')) {
- utils.NamespaceError();
- }
- return { namespace: namespace, prefix: prefix, localName: localName };
-}
-
-Document.prototype = Object.create(ContainerNode.prototype, {
- // This method allows dom.js to communicate with a renderer
- // that displays the document in some way
- // XXX: I should probably move this to the window object
- _setMutationHandler: { value: function(handler) {
- this.mutationHandler = handler;
- }},
-
- // This method allows dom.js to receive event notifications
- // from the renderer.
- // XXX: I should probably move this to the window object
- _dispatchRendererEvent: { value: function(targetNid, type, details) {
- var target = this._nodes[targetNid];
- if (!target) return;
- target._dispatchEvent(new Event(type, details), true);
- }},
-
- nodeName: { value: '#document'},
- nodeValue: {
- get: function() {
- return null;
- },
- set: function() {}
- },
-
- // XXX: DOMCore may remove documentURI, so it is NYI for now
- documentURI: { get: function() { return this._address; }, set: utils.nyi.bind(this, 'set documentURI') },
- compatMode: { get: function() {
- // The _quirks property is set by the HTML parser
- return this._quirks ? 'BackCompat' : 'CSS1Compat';
- }},
-
- createTextNode: { value: function(data) {
- return new Text(this, String(data));
- }},
- createComment: { value: function(data) {
- return new Comment(this, data);
- }},
- createDocumentFragment: { value: function() {
- return new DocumentFragment(this);
- }},
- createProcessingInstruction: { value: function(target, data) {
- if (!xml.isValidName(target) || data.indexOf('?>') !== -1)
- utils.InvalidCharacterError();
- return new ProcessingInstruction(this, target, data);
- }},
-
- createAttribute: { value: function(localName) {
- localName = String(localName);
- if (!xml.isValidName(localName)) utils.InvalidCharacterError();
- if (this.isHTML) {
- localName = utils.toASCIILowerCase(localName);
- }
- return new Element._Attr(null, localName, null, null, '');
- }},
- createAttributeNS: { value: function(namespace, qualifiedName) {
- // Convert parameter types according to WebIDL
- namespace =
- (namespace === null || namespace === undefined || namespace === '') ? null :
- String(namespace);
- qualifiedName = String(qualifiedName);
- var ve = validateAndExtract(namespace, qualifiedName);
- return new Element._Attr(null, ve.localName, ve.prefix, ve.namespace, '');
- }},
-
- createElement: { value: function(localName) {
- localName = String(localName);
- if (!xml.isValidName(localName)) utils.InvalidCharacterError();
- // Per spec, namespace should be HTML namespace if "context object is
- // an HTML document or context object's content type is
- // "application/xhtml+xml", and null otherwise.
- if (this.isHTML) {
- if (/[A-Z]/.test(localName))
- localName = utils.toASCIILowerCase(localName);
- return html.createElement(this, localName, null);
- } else if (this.contentType === 'application/xhtml+xml') {
- return html.createElement(this, localName, null);
- } else {
- return new Element(this, localName, null, null);
- }
- }, writable: isApiWritable },
-
- createElementNS: { value: function(namespace, qualifiedName) {
- // Convert parameter types according to WebIDL
- namespace =
- (namespace === null || namespace === undefined || namespace === '') ? null :
- String(namespace);
- qualifiedName = String(qualifiedName);
- var ve = validateAndExtract(namespace, qualifiedName);
- return this._createElementNS(ve.localName, ve.namespace, ve.prefix);
- }, writable: isApiWritable },
-
- // This is used directly by HTML parser, which allows it to create
- // elements with localNames containing ':' and non-default namespaces
- _createElementNS: { value: function(localName, namespace, prefix) {
- if (namespace === NAMESPACE.HTML) {
- return html.createElement(this, localName, prefix);
- }
- else if (namespace === NAMESPACE.SVG) {
- return svg.createElement(this, localName, prefix);
- }
-
- return new Element(this, localName, namespace, prefix);
- }},
-
- createEvent: { value: function createEvent(interfaceName) {
- interfaceName = interfaceName.toLowerCase();
- var name = replacementEvent[interfaceName] || interfaceName;
- var constructor = events[supportedEvents[name]];
-
- if (constructor) {
- var e = new constructor();
- e._initialized = false;
- return e;
- }
- else {
- utils.NotSupportedError();
- }
- }},
-
- // See: http://www.w3.org/TR/dom/#dom-document-createtreewalker
- createTreeWalker: {value: function (root, whatToShow, filter) {
- if (!root) { throw new TypeError("root argument is required"); }
- if (!(root instanceof Node)) { throw new TypeError("root not a node"); }
- whatToShow = whatToShow === undefined ? NodeFilter.SHOW_ALL : (+whatToShow);
- filter = filter === undefined ? null : filter;
-
- return new TreeWalker(root, whatToShow, filter);
- }},
-
- // See: http://www.w3.org/TR/dom/#dom-document-createnodeiterator
- createNodeIterator: {value: function (root, whatToShow, filter) {
- if (!root) { throw new TypeError("root argument is required"); }
- if (!(root instanceof Node)) { throw new TypeError("root not a node"); }
- whatToShow = whatToShow === undefined ? NodeFilter.SHOW_ALL : (+whatToShow);
- filter = filter === undefined ? null : filter;
-
- return new NodeIterator(root, whatToShow, filter);
- }},
-
- _attachNodeIterator: { value: function(ni) {
- // XXX ideally this should be a weak reference from Document to NodeIterator
- if (!this._nodeIterators) { this._nodeIterators = []; }
- this._nodeIterators.push(ni);
- }},
-
- _detachNodeIterator: { value: function(ni) {
- // ni should always be in list of node iterators
- var idx = this._nodeIterators.indexOf(ni);
- this._nodeIterators.splice(idx, 1);
- }},
-
- _preremoveNodeIterators: { value: function(toBeRemoved) {
- if (this._nodeIterators) {
- this._nodeIterators.forEach(function(ni) { ni._preremove(toBeRemoved); });
- }
- }},
-
- // Maintain the documentElement and
- // doctype properties of the document. Each of the following
- // methods chains to the Node implementation of the method
- // to do the actual inserting, removal or replacement.
-
- _updateDocTypeElement: { value: function _updateDocTypeElement() {
- this.doctype = this.documentElement = null;
- for (var kid = this.firstChild; kid !== null; kid = kid.nextSibling) {
- if (kid.nodeType === Node.DOCUMENT_TYPE_NODE)
- this.doctype = kid;
- else if (kid.nodeType === Node.ELEMENT_NODE)
- this.documentElement = kid;
- }
- }},
-
- insertBefore: { value: function insertBefore(child, refChild) {
- Node.prototype.insertBefore.call(this, child, refChild);
- this._updateDocTypeElement();
- return child;
- }},
-
- replaceChild: { value: function replaceChild(node, child) {
- Node.prototype.replaceChild.call(this, node, child);
- this._updateDocTypeElement();
- return child;
- }},
-
- removeChild: { value: function removeChild(child) {
- Node.prototype.removeChild.call(this, child);
- this._updateDocTypeElement();
- return child;
- }},
-
- getElementById: { value: function(id) {
- var n = this.byId[id];
- if (!n) return null;
- if (n instanceof MultiId) { // there was more than one element with this id
- return n.getFirst();
- }
- return n;
- }},
-
- _hasMultipleElementsWithId: { value: function(id) {
- // Used internally by querySelectorAll optimization
- return (this.byId[id] instanceof MultiId);
- }},
-
- // Just copy this method from the Element prototype
- getElementsByName: { value: Element.prototype.getElementsByName },
- getElementsByTagName: { value: Element.prototype.getElementsByTagName },
- getElementsByTagNameNS: { value: Element.prototype.getElementsByTagNameNS },
- getElementsByClassName: { value: Element.prototype.getElementsByClassName },
-
- adoptNode: { value: function adoptNode(node) {
- if (node.nodeType === Node.DOCUMENT_NODE) utils.NotSupportedError();
- if (node.nodeType === Node.ATTRIBUTE_NODE) { return node; }
-
- if (node.parentNode) node.parentNode.removeChild(node);
-
- if (node.ownerDocument !== this)
- recursivelySetOwner(node, this);
-
- return node;
- }},
-
- importNode: { value: function importNode(node, deep) {
- return this.adoptNode(node.cloneNode(deep));
- }, writable: isApiWritable },
-
- // The following attributes and methods are from the HTML spec
- origin: { get: function origin() { return null; } },
- characterSet: { get: function characterSet() { return "UTF-8"; } },
- contentType: { get: function contentType() { return this._contentType; } },
- URL: { get: function URL() { return this._address; } },
- domain: { get: utils.nyi.bind(this, 'domain'), set: utils.nyi.bind(this, 'domain') },
- referrer: { get: opossum.referrer },
- //cookie: { get: utils.nyi.bind(this, 'cookie get'), set: utils.nyi.bind(this, 'cookie set') },
- lastModified: { get: utils.nyi.bind(this, 'lastModified get') },
- location: {
- get: function() {
- return this.defaultView ? this.defaultView.location : null; // gh #75
- },
- set: utils.nyi.bind(this, 'location set')
- },
- _titleElement: {
- get: function() {
- // The title element of a document is the first title element in the
- // document in tree order, if there is one, or null otherwise.
- return this.getElementsByTagName('title').item(0) || null;
- }
- },
- title: {
- get: function() {
- var elt = this._titleElement;
- // The child text content of the title element, or '' if null.
- var value = elt ? elt.textContent : '';
- // Strip and collapse whitespace in value
- return value.replace(/[ \t\n\r\f]+/g, ' ').replace(/(^ )|( $)/g, '');
- },
- set: function(value) {
- var elt = this._titleElement;
- var head = this.head;
- if (!elt && !head) { return; /* according to spec */ }
- if (!elt) {
- elt = this.createElement('title');
- head.appendChild(elt);
- }
- elt.textContent = value;
- }
- },
- dir: mirrorAttr(function() {
- var htmlElement = this.documentElement;
- if (htmlElement && htmlElement.tagName === 'HTML') { return htmlElement; }
- }, 'dir', ''),
- fgColor: mirrorAttr(function() { return this.body; }, 'text', ''),
- linkColor: mirrorAttr(function() { return this.body; }, 'link', ''),
- vlinkColor: mirrorAttr(function() { return this.body; }, 'vLink', ''),
- alinkColor: mirrorAttr(function() { return this.body; }, 'aLink', ''),
- bgColor: mirrorAttr(function() { return this.body; }, 'bgColor', ''),
-
- // Historical aliases of Document#characterSet
- charset: { get: function() { return this.characterSet; } },
- inputEncoding: { get: function() { return this.characterSet; } },
-
- scrollingElement: {
- get: function() {
- return this._quirks ? this.body : this.documentElement;
- }
- },
-
- // Return the first <body> child of the document element.
- // XXX For now, setting this attribute is not implemented.
- body: {
- get: function() {
- return namedHTMLChild(this.documentElement, 'body');
- },
- set: utils.nyi.bind(this, 'body set')
- },
- // Return the first <head> child of the document element.
- head: { get: function() {
- return namedHTMLChild(this.documentElement, 'head');
- }},
- images: { get: utils.nyi.bind(this, 'images get') },
- embeds: { get: utils.nyi.bind(this, 'embeds get') },
- plugins: { get: utils.nyi.bind(this, 'plugins get') },
- links: { get: utils.nyi.bind(this, 'links get') },
- forms: { get: utils.nyi.bind(this, 'forms get') },
- scripts: { get: utils.nyi.bind(this, 'scripts get') },
- applets: { get: function() { return []; } },
- activeElement: { get: function() { return null; } },
- innerHTML: {
- get: function() { return this.serialize(); },
- set: utils.nyi
- },
- outerHTML: {
- get: function() { return this.serialize(); },
- set: utils.nyi
- },
-
- write: { value: function(args) {
- if (!this.isHTML) utils.InvalidStateError();
-
- // XXX: still have to implement the ignore part
- if (!this._parser /* && this._ignore_destructive_writes > 0 */ )
- return;
-
- if (!this._parser) {
- // XXX call document.open, etc.
- }
-
- var s = arguments.join('');
-
- // If the Document object's reload override flag is set, then
- // append the string consisting of the concatenation of all the
- // arguments to the method to the Document's reload override
- // buffer.
- // XXX: don't know what this is about. Still have to do it
-
- // If there is no pending parsing-blocking script, have the
- // tokenizer process the characters that were inserted, one at a
- // time, processing resulting tokens as they are emitted, and
- // stopping when the tokenizer reaches the insertion point or when
- // the processing of the tokenizer is aborted by the tree
- // construction stage (this can happen if a script end tag token is
- // emitted by the tokenizer).
-
- // XXX: still have to do the above. Sounds as if we don't
- // always call parse() here. If we're blocked, then we just
- // insert the text into the stream but don't parse it reentrantly...
-
- // Invoke the parser reentrantly
- this._parser.parse(s);
- }},
-
- writeln: { value: function writeln(args) {
- this.write(Array.prototype.join.call(arguments, '') + '\n');
- }},
-
- open: { value: function() {
- this.documentElement = null;
- }},
-
- close: { value: function() {
- this.readyState = 'interactive';
- this._dispatchEvent(new Event('readystatechange'), true);
- this._dispatchEvent(new Event('DOMContentLoaded'), true);
- this.readyState = 'complete';
- this._dispatchEvent(new Event('readystatechange'), true);
- if (this.defaultView) {
- this.defaultView._dispatchEvent(new Event('load'), true);
- }
- }},
-
- // Utility methods
- clone: { value: function clone() {
- var d = new Document(this.isHTML, this._address);
- d._quirks = this._quirks;
- d._contentType = this._contentType;
- return d;
- }},
-
- // We need to adopt the nodes if we do a deep clone
- cloneNode: { value: function cloneNode(deep) {
- var clone = Node.prototype.cloneNode.call(this, false);
- if (deep) {
- for (var kid = this.firstChild; kid !== null; kid = kid.nextSibling) {
- clone._appendChild(clone.importNode(kid, true));
- }
- }
- clone._updateDocTypeElement();
- return clone;
- }},
-
- isEqual: { value: function isEqual(n) {
- // Any two documents are shallowly equal.
- // Node.isEqualNode will also test the children
- return true;
- }},
-
- // Implementation-specific function. Called when a text, comment,
- // or pi value changes.
- mutateValue: { value: function(node) {
- if (this.mutationHandler) {
- this.mutationHandler({
- type: MUTATE.VALUE,
- target: node,
- data: node.data
- });
- }
- }},
-
- // Invoked when an attribute's value changes. Attr holds the new
- // value. oldval is the old value. Attribute mutations can also
- // involve changes to the prefix (and therefore the qualified name)
- mutateAttr: { value: function(attr, oldval) {
- // Manage id->element mapping for getElementsById()
- // XXX: this special case id handling should not go here,
- // but in the attribute declaration for the id attribute
- /*
- if (attr.localName === 'id' && attr.namespaceURI === null) {
- if (oldval) delId(oldval, attr.ownerElement);
- addId(attr.value, attr.ownerElement);
- }
- */
- if (this.mutationHandler) {
- this.mutationHandler({
- type: MUTATE.ATTR,
- target: attr.ownerElement,
- attr: attr
- });
- }
- }},
-
- // Used by removeAttribute and removeAttributeNS for attributes.
- mutateRemoveAttr: { value: function(attr) {
-/*
-* This is now handled in Attributes.js
- // Manage id to element mapping
- if (attr.localName === 'id' && attr.namespaceURI === null) {
- this.delId(attr.value, attr.ownerElement);
- }
-*/
- if (this.mutationHandler) {
- this.mutationHandler({
- type: MUTATE.REMOVE_ATTR,
- target: attr.ownerElement,
- attr: attr
- });
- }
- }},
-
- // Called by Node.removeChild, etc. to remove a rooted element from
- // the tree. Only needs to generate a single mutation event when a
- // node is removed, but must recursively mark all descendants as not
- // rooted.
- mutateRemove: { value: function(node) {
- // Send a single mutation event
- if (this.mutationHandler) {
- this.mutationHandler({
- type: MUTATE.REMOVE,
- target: node.parentNode,
- node: node
- });
- }
-
- // Mark this and all descendants as not rooted
- recursivelyUproot(node);
- }},
-
- // Called when a new element becomes rooted. It must recursively
- // generate mutation events for each of the children, and mark them all
- // as rooted.
- mutateInsert: { value: function(node) {
- // Mark node and its descendants as rooted
- recursivelyRoot(node);
-
- // Send a single mutation event
- if (this.mutationHandler) {
- this.mutationHandler({
- type: MUTATE.INSERT,
- target: node.parentNode,
- node: node
- });
- }
- }},
-
- // Called when a rooted element is moved within the document
- mutateMove: { value: function(node) {
- if (this.mutationHandler) {
- this.mutationHandler({
- type: MUTATE.MOVE,
- target: node
- });
- }
- }},
-
-
- // Add a mapping from id to n for n.ownerDocument
- addId: { value: function addId(id, n) {
- var val = this.byId[id];
- if (!val) {
- this.byId[id] = n;
- }
- else {
- // TODO: Add a way to opt-out console warnings
- //console.warn('Duplicate element id ' + id);
- if (!(val instanceof MultiId)) {
- val = new MultiId(val);
- this.byId[id] = val;
- }
- val.add(n);
- }
- }},
-
- // Delete the mapping from id to n for n.ownerDocument
- delId: { value: function delId(id, n) {
- var val = this.byId[id];
- utils.assert(val);
-
- if (val instanceof MultiId) {
- val.del(n);
- if (val.length === 1) { // convert back to a single node
- this.byId[id] = val.downgrade();
- }
- }
- else {
- this.byId[id] = undefined;
- }
- }},
-
- _resolve: { value: function(href) {
- //XXX: Cache the URL
- return new URL(this._documentBaseURL).resolve(href);
- }},
-
- _documentBaseURL: { get: function() {
- // XXX: This is not implemented correctly yet
- var url = this._address;
- if (url === 'about:blank') url = '/';
-
- var base = this.querySelector('base[href]');
- if (base) {
- return new URL(url).resolve(base.getAttribute('href'));
- }
- return url;
-
- // The document base URL of a Document object is the
- // absolute URL obtained by running these substeps:
-
- // Let fallback base url be the document's address.
-
- // If fallback base url is about:blank, and the
- // Document's browsing context has a creator browsing
- // context, then let fallback base url be the document
- // base URL of the creator Document instead.
-
- // If the Document is an iframe srcdoc document, then
- // let fallback base url be the document base URL of
- // the Document's browsing context's browsing context
- // container's Document instead.
-
- // If there is no base element that has an href
- // attribute, then the document base URL is fallback
- // base url; abort these steps. Otherwise, let url be
- // the value of the href attribute of the first such
- // element.
-
- // Resolve url relative to fallback base url (thus,
- // the base href attribute isn't affected by xml:base
- // attributes).
-
- // The document base URL is the result of the previous
- // step if it was successful; otherwise it is fallback
- // base url.
- }},
-
- _templateDoc: { get: function() {
- if (!this._templateDocCache) {
- // "associated inert template document"
- var newDoc = new Document(this.isHTML, this._address);
- this._templateDocCache = newDoc._templateDocCache = newDoc;
- }
- return this._templateDocCache;
- }},
-
- querySelector: { value: function(selector) {
- return select(selector, this)[0];
- }},
-
- querySelectorAll: { value: function(selector) {
- var nodes = select(selector, this);
- return nodes.item ? nodes : new NodeList(nodes);
- }}
-
-});
-
-
-var eventHandlerTypes = [
- 'abort', 'canplay', 'canplaythrough', 'change', 'click', 'contextmenu',
- 'cuechange', 'dblclick', 'drag', 'dragend', 'dragenter', 'dragleave',
- 'dragover', 'dragstart', 'drop', 'durationchange', 'emptied', 'ended',
- 'input', 'invalid', 'keydown', 'keypress', 'keyup', 'loadeddata',
- 'loadedmetadata', 'loadstart', 'mousedown', 'mousemove', 'mouseout',
- 'mouseover', 'mouseup', 'mousewheel', 'pause', 'play', 'playing',
- 'progress', 'ratechange', 'readystatechange', 'reset', 'seeked',
- 'seeking', 'select', 'show', 'stalled', 'submit', 'suspend',
- 'timeupdate', 'volumechange', 'waiting',
-
- 'blur', 'error', 'focus', 'load', 'scroll'
-];
-
-// Add event handler idl attribute getters and setters to Document
-eventHandlerTypes.forEach(function(type) {
- // Define the event handler registration IDL attribute for this type
- Object.defineProperty(Document.prototype, 'on' + type, {
- get: function() {
- return this._getEventHandler(type);
- },
- set: function(v) {
- this._setEventHandler(type, v);
- }
- });
-});
-
-function namedHTMLChild(parent, name) {
- if (parent && parent.isHTML) {
- for (var kid = parent.firstChild; kid !== null; kid = kid.nextSibling) {
- if (kid.nodeType === Node.ELEMENT_NODE &&
- kid.localName === name &&
- kid.namespaceURI === NAMESPACE.HTML) {
- return kid;
- }
- }
- }
- return null;
-}
-
-function root(n) {
- n._nid = n.ownerDocument._nextnid++;
- n.ownerDocument._nodes[n._nid] = n;
- // Manage id to element mapping
- if (n.nodeType === Node.ELEMENT_NODE) {
- var id = n.getAttribute('id');
- if (id) n.ownerDocument.addId(id, n);
-
- // Script elements need to know when they're inserted
- // into the document
- if (n._roothook) n._roothook();
- }
-}
-
-function uproot(n) {
- // Manage id to element mapping
- if (n.nodeType === Node.ELEMENT_NODE) {
- var id = n.getAttribute('id');
- if (id) n.ownerDocument.delId(id, n);
- }
- n.ownerDocument._nodes[n._nid] = undefined;
- n._nid = undefined;
-}
-
-function recursivelyRoot(node) {
- root(node);
- // XXX:
- // accessing childNodes on a leaf node creates a new array the
- // first time, so be careful to write this loop so that it
- // doesn't do that. node is polymorphic, so maybe this is hard to
- // optimize? Try switching on nodeType?
-/*
- if (node.hasChildNodes()) {
- var kids = node.childNodes;
- for(var i = 0, n = kids.length; i < n; i++)
- recursivelyRoot(kids[i]);
- }
-*/
- if (node.nodeType === Node.ELEMENT_NODE) {
- for (var kid = node.firstChild; kid !== null; kid = kid.nextSibling)
- recursivelyRoot(kid);
- }
-}
-
-function recursivelyUproot(node) {
- uproot(node);
- for (var kid = node.firstChild; kid !== null; kid = kid.nextSibling)
- recursivelyUproot(kid);
-}
-
-function recursivelySetOwner(node, owner) {
- node.ownerDocument = owner;
- node._lastModTime = undefined; // mod times are document-based
- if (Object.prototype.hasOwnProperty.call(node, '_tagName')) {
- node._tagName = undefined; // Element subclasses might need to change case
- }
- for (var kid = node.firstChild; kid !== null; kid = kid.nextSibling)
- recursivelySetOwner(kid, owner);
-}
-
-// A class for storing multiple nodes with the same ID
-function MultiId(node) {
- this.nodes = Object.create(null);
- this.nodes[node._nid] = node;
- this.length = 1;
- this.firstNode = undefined;
-}
-
-// Add a node to the list, with O(1) time
-MultiId.prototype.add = function(node) {
- if (!this.nodes[node._nid]) {
- this.nodes[node._nid] = node;
- this.length++;
- this.firstNode = undefined;
- }
-};
-
-// Remove a node from the list, with O(1) time
-MultiId.prototype.del = function(node) {
- if (this.nodes[node._nid]) {
- delete this.nodes[node._nid];
- this.length--;
- this.firstNode = undefined;
- }
-};
-
-// Get the first node from the list, in the document order
-// Takes O(N) time in the size of the list, with a cache that is invalidated
-// when the list is modified.
-MultiId.prototype.getFirst = function() {
- /* jshint bitwise: false */
- if (!this.firstNode) {
- var nid;
- for (nid in this.nodes) {
- if (this.firstNode === undefined ||
- this.firstNode.compareDocumentPosition(this.nodes[nid]) & Node.DOCUMENT_POSITION_PRECEDING) {
- this.firstNode = this.nodes[nid];
- }
- }
- }
- return this.firstNode;
-};
-
-// If there is only one node left, return it. Otherwise return "this".
-MultiId.prototype.downgrade = function() {
- if (this.length === 1) {
- var nid;
- for (nid in this.nodes) {
- return this.nodes[nid];
- }
- }
- return this;
-};
--- a/cmd/gojafs/domino/domino-lib/DocumentFragment.js
+++ /dev/null
@@ -1,68 +1,0 @@
-"use strict";
-module.exports = DocumentFragment;
-
-var Node = require('./Node');
-var NodeList = require('./NodeList');
-var ContainerNode = require('./ContainerNode');
-var Element = require('./Element');
-var select = require('./select');
-var utils = require('./utils');
-
-function DocumentFragment(doc) {
- ContainerNode.call(this);
- this.nodeType = Node.DOCUMENT_FRAGMENT_NODE;
- this.ownerDocument = doc;
-}
-
-DocumentFragment.prototype = Object.create(ContainerNode.prototype, {
- nodeName: { value: '#document-fragment' },
- nodeValue: {
- get: function() {
- return null;
- },
- set: function() {}
- },
- // Copy the text content getter/setter from Element
- textContent: Object.getOwnPropertyDescriptor(Element.prototype, 'textContent'),
-
- querySelector: { value: function(selector) {
- // implement in terms of querySelectorAll
- var nodes = this.querySelectorAll(selector);
- return nodes.length ? nodes[0] : null;
- }},
- querySelectorAll: { value: function(selector) {
- // create a context
- var context = Object.create(this);
- // add some methods to the context for zest implementation, without
- // adding them to the public DocumentFragment API
- context.isHTML = true; // in HTML namespace (case-insensitive match)
- context.getElementsByTagName = Element.prototype.getElementsByTagName;
- context.nextElement =
- Object.getOwnPropertyDescriptor(Element.prototype, 'firstElementChild').
- get;
- // invoke zest
- var nodes = select(selector, context);
- return nodes.item ? nodes : new NodeList(nodes);
- }},
-
- // Utility methods
- clone: { value: function clone() {
- return new DocumentFragment(this.ownerDocument);
- }},
- isEqual: { value: function isEqual(n) {
- // Any two document fragments are shallowly equal.
- // Node.isEqualNode() will test their children for equality
- return true;
- }},
-
- // Non-standard, but useful (github issue #73)
- innerHTML: {
- get: function() { return this.serialize(); },
- set: utils.nyi
- },
- outerHTML: {
- get: function() { return this.serialize(); },
- set: utils.nyi
- },
-
-});
--- a/cmd/gojafs/domino/domino-lib/DocumentType.js
+++ /dev/null
@@ -1,36 +1,0 @@
-"use strict";
-module.exports = DocumentType;
-
-var Node = require('./Node');
-var Leaf = require('./Leaf');
-var ChildNode = require('./ChildNode');
-
-function DocumentType(ownerDocument, name, publicId, systemId) {
- Leaf.call(this);
- this.nodeType = Node.DOCUMENT_TYPE_NODE;
- this.ownerDocument = ownerDocument || null;
- this.name = name;
- this.publicId = publicId || "";
- this.systemId = systemId || "";
-}
-
-DocumentType.prototype = Object.create(Leaf.prototype, {
- nodeName: { get: function() { return this.name; }},
- nodeValue: {
- get: function() { return null; },
- set: function() {}
- },
-
- // Utility methods
- clone: { value: function clone() {
- return new DocumentType(this.ownerDocument, this.name, this.publicId, this.systemId);
- }},
-
- isEqual: { value: function isEqual(n) {
- return this.name === n.name &&
- this.publicId === n.publicId &&
- this.systemId === n.systemId;
- }}
-});
-
-Object.defineProperties(DocumentType.prototype, ChildNode);
--- a/cmd/gojafs/domino/domino-lib/Element.js
+++ /dev/null
@@ -1,1202 +1,0 @@
-"use strict";
-module.exports = Element;
-
-var xml = require('./xmlnames');
-var utils = require('./utils');
-var NAMESPACE = utils.NAMESPACE;
-var attributes = require('./attributes');
-var Node = require('./Node');
-var NodeList = require('./NodeList');
-var NodeUtils = require('./NodeUtils');
-var FilteredElementList = require('./FilteredElementList');
-var DOMException = require('./DOMException');
-var DOMTokenList = require('./DOMTokenList');
-var select = require('./select');
-var ContainerNode = require('./ContainerNode');
-var ChildNode = require('./ChildNode');
-var NonDocumentTypeChildNode = require('./NonDocumentTypeChildNode');
-var NamedNodeMap = require('./NamedNodeMap');
-
-var uppercaseCache = Object.create(null);
-
-function Element(doc, localName, namespaceURI, prefix) {
- ContainerNode.call(this);
- this.nodeType = Node.ELEMENT_NODE;
- this.ownerDocument = doc;
- this.localName = localName;
- this.namespaceURI = namespaceURI;
- this.prefix = prefix;
- this._tagName = undefined;
-
- // These properties maintain the set of attributes
- this._attrsByQName = Object.create(null); // The qname->Attr map
- this._attrsByLName = Object.create(null); // The ns|lname->Attr map
- this._attrKeys = []; // attr index -> ns|lname
-}
-
-function recursiveGetText(node, a) {
- if (node.nodeType === Node.TEXT_NODE) {
- a.push(node._data);
- }
- else {
- for(var i = 0, n = node.childNodes.length; i < n; i++)
- recursiveGetText(node.childNodes[i], a);
- }
-}
-
-Element.prototype = Object.create(ContainerNode.prototype, {
- isHTML: { get: function isHTML() {
- return this.namespaceURI === NAMESPACE.HTML && this.ownerDocument.isHTML;
- }},
- tagName: { get: function tagName() {
- if (this._tagName === undefined) {
- var tn;
- if (this.prefix === null) {
- tn = this.localName;
- } else {
- tn = this.prefix + ':' + this.localName;
- }
- if (this.isHTML) {
- var up = uppercaseCache[tn];
- if (!up) {
- // Converting to uppercase can be slow, so cache the conversion.
- uppercaseCache[tn] = up = utils.toASCIIUpperCase(tn);
- }
- tn = up;
- }
- this._tagName = tn;
- }
- return this._tagName;
- }},
- nodeName: { get: function() { return this.tagName; }},
- nodeValue: {
- get: function() {
- return null;
- },
- set: function() {}
- },
- textContent: {
- get: function() {
- var strings = [];
- recursiveGetText(this, strings);
- return strings.join('');
- },
- set: function(newtext) {
- this.removeChildren();
- if (newtext !== null && newtext !== undefined && newtext !== '') {
- this._appendChild(this.ownerDocument.createTextNode(newtext));
- }
- }
- },
- innerHTML: {
- get: function() {
- return this.serialize();
- },
- set: utils.nyi
- },
- outerHTML: {
- get: function() {
- // "the attribute must return the result of running the HTML fragment
- // serialization algorithm on a fictional node whose only child is
- // the context object"
- //
- // The serialization logic is intentionally implemented in a separate
- // `NodeUtils` helper instead of the more obvious choice of a private
- // `_serializeOne()` method on the `Node.prototype` in order to avoid
- // the megamorphic `this._serializeOne` property access, which reduces
- // performance unnecessarily. If you need specialized behavior for a
- // certain subclass, you'll need to implement that in `NodeUtils`.
- // See https://github.com/fgnass/domino/pull/142 for more information.
- return NodeUtils.serializeOne(this, { nodeType: 0 });
- },
- set: function(v) {
- var document = this.ownerDocument;
- var parent = this.parentNode;
- if (parent === null) { return; }
- if (parent.nodeType === Node.DOCUMENT_NODE) {
- utils.NoModificationAllowedError();
- }
- if (parent.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
- parent = parent.ownerDocument.createElement("body");
- }
- var parser = document.implementation.mozHTMLParser(
- document._address,
- parent
- );
- parser.parse(v===null?'':String(v), true);
- this.replaceWith(parser._asDocumentFragment());
- },
- },
-
- _insertAdjacent: { value: function _insertAdjacent(position, node) {
- var first = false;
- switch(position) {
- case 'beforebegin':
- first = true;
- /* falls through */
- case 'afterend':
- var parent = this.parentNode;
- if (parent === null) { return null; }
- return parent.insertBefore(node, first ? this : this.nextSibling);
- case 'afterbegin':
- first = true;
- /* falls through */
- case 'beforeend':
- return this.insertBefore(node, first ? this.firstChild : null);
- default:
- return utils.SyntaxError();
- }
- }},
-
- insertAdjacentElement: { value: function insertAdjacentElement(position, element) {
- if (element.nodeType !== Node.ELEMENT_NODE) {
- throw new TypeError('not an element');
- }
- position = utils.toASCIILowerCase(String(position));
- return this._insertAdjacent(position, element);
- }},
-
- insertAdjacentText: { value: function insertAdjacentText(position, data) {
- var textNode = this.ownerDocument.createTextNode(data);
- position = utils.toASCIILowerCase(String(position));
- this._insertAdjacent(position, textNode);
- // "This method returns nothing because it existed before we had a chance
- // to design it."
- }},
-
- insertAdjacentHTML: { value: function insertAdjacentHTML(position, text) {
- position = utils.toASCIILowerCase(String(position));
- text = String(text);
- var context;
- switch(position) {
- case 'beforebegin':
- case 'afterend':
- context = this.parentNode;
- if (context === null || context.nodeType === Node.DOCUMENT_NODE) {
- utils.NoModificationAllowedError();
- }
- break;
- case 'afterbegin':
- case 'beforeend':
- context = this;
- break;
- default:
- utils.SyntaxError();
- }
- if ( (!(context instanceof Element)) || (
- context.ownerDocument.isHTML &&
- context.localName === 'html' &&
- context.namespaceURI === NAMESPACE.HTML
- ) ) {
- context = context.ownerDocument.createElementNS(NAMESPACE.HTML, 'body');
- }
- var parser = this.ownerDocument.implementation.mozHTMLParser(
- this.ownerDocument._address, context
- );
- parser.parse(text, true);
- this._insertAdjacent(position, parser._asDocumentFragment());
- }},
-
- children: { get: function() {
- if (!this._children) {
- this._children = new ChildrenCollection(this);
- }
- return this._children;
- }},
-
- attributes: { get: function() {
- if (!this._attributes) {
- this._attributes = new AttributesArray(this);
- }
- return this._attributes;
- }},
-
-
- firstElementChild: { get: function() {
- for (var kid = this.firstChild; kid !== null; kid = kid.nextSibling) {
- if (kid.nodeType === Node.ELEMENT_NODE) return kid;
- }
- return null;
- }},
-
- lastElementChild: { get: function() {
- for (var kid = this.lastChild; kid !== null; kid = kid.previousSibling) {
- if (kid.nodeType === Node.ELEMENT_NODE) return kid;
- }
- return null;
- }},
-
- childElementCount: { get: function() {
- return this.children.length;
- }},
-
-
- // Return the next element, in source order, after this one or
- // null if there are no more. If root element is specified,
- // then don't traverse beyond its subtree.
- //
- // This is not a DOM method, but is convenient for
- // lazy traversals of the tree.
- nextElement: { value: function(root) {
- if (!root) root = this.ownerDocument.documentElement;
- var next = this.firstElementChild;
- if (!next) {
- // don't use sibling if we're at root
- if (this===root) return null;
- next = this.nextElementSibling;
- }
- if (next) return next;
-
- // If we can't go down or across, then we have to go up
- // and across to the parent sibling or another ancestor's
- // sibling. Be careful, though: if we reach the root
- // element, or if we reach the documentElement, then
- // the traversal ends.
- for(var parent = this.parentElement;
- parent && parent !== root;
- parent = parent.parentElement) {
-
- next = parent.nextElementSibling;
- if (next) return next;
- }
-
- return null;
- }},
-
- // XXX:
- // Tests are currently failing for this function.
- // Awaiting resolution of:
- // http://lists.w3.org/Archives/Public/www-dom/2011JulSep/0016.html
- getElementsByTagName: { value: function getElementsByTagName(lname) {
- var filter;
- if (!lname) return new NodeList();
- if (lname === '*')
- filter = function() { return true; };
- else if (this.isHTML)
- filter = htmlLocalNameElementFilter(lname);
- else
- filter = localNameElementFilter(lname);
-
- return new FilteredElementList(this, filter);
- }},
-
- getElementsByTagNameNS: { value: function getElementsByTagNameNS(ns, lname){
- var filter;
- if (ns === '*' && lname === '*')
- filter = function() { return true; };
- else if (ns === '*')
- filter = localNameElementFilter(lname);
- else if (lname === '*')
- filter = namespaceElementFilter(ns);
- else
- filter = namespaceLocalNameElementFilter(ns, lname);
-
- return new FilteredElementList(this, filter);
- }},
-
- getElementsByClassName: { value: function getElementsByClassName(names){
- names = String(names).trim();
- if (names === '') {
- var result = new NodeList(); // Empty node list
- return result;
- }
- names = names.split(/[ \t\r\n\f]+/); // Split on ASCII whitespace
- return new FilteredElementList(this, classNamesElementFilter(names));
- }},
-
- getElementsByName: { value: function getElementsByName(name) {
- return new FilteredElementList(this, elementNameFilter(String(name)));
- }},
-
- // Utility methods used by the public API methods above
- clone: { value: function clone() {
- var e;
-
- // XXX:
- // Modify this to use the constructor directly or
- // avoid error checking in some other way. In case we try
- // to clone an invalid node that the parser inserted.
- //
- if (this.namespaceURI !== NAMESPACE.HTML || this.prefix || !this.ownerDocument.isHTML) {
- e = this.ownerDocument.createElementNS(
- this.namespaceURI, (this.prefix !== null) ?
- (this.prefix + ':' + this.localName) : this.localName
- );
- } else {
- e = this.ownerDocument.createElement(this.localName);
- }
-
- for(var i = 0, n = this._attrKeys.length; i < n; i++) {
- var lname = this._attrKeys[i];
- var a = this._attrsByLName[lname];
- var b = a.cloneNode();
- b._setOwnerElement(e);
- e._attrsByLName[lname] = b;
- e._addQName(b);
- }
- e._attrKeys = this._attrKeys.concat();
-
- return e;
- }},
-
- isEqual: { value: function isEqual(that) {
- if (this.localName !== that.localName ||
- this.namespaceURI !== that.namespaceURI ||
- this.prefix !== that.prefix ||
- this._numattrs !== that._numattrs)
- return false;
-
- // Compare the sets of attributes, ignoring order
- // and ignoring attribute prefixes.
- for(var i = 0, n = this._numattrs; i < n; i++) {
- var a = this._attr(i);
- if (!that.hasAttributeNS(a.namespaceURI, a.localName))
- return false;
- if (that.getAttributeNS(a.namespaceURI,a.localName) !== a.value)
- return false;
- }
-
- return true;
- }},
-
- // This is the 'locate a namespace prefix' algorithm from the
- // DOM specification. It is used by Node.lookupPrefix()
- // (Be sure to compare DOM3 and DOM4 versions of spec.)
- _lookupNamespacePrefix: { value: function _lookupNamespacePrefix(ns, originalElement) {
- if (
- this.namespaceURI &&
- this.namespaceURI === ns &&
- this.prefix !== null &&
- originalElement.lookupNamespaceURI(this.prefix) === ns
- ) {
- return this.prefix;
- }
-
- for(var i = 0, n = this._numattrs; i < n; i++) {
- var a = this._attr(i);
- if (
- a.prefix === 'xmlns' &&
- a.value === ns &&
- originalElement.lookupNamespaceURI(a.localName) === ns
- ) {
- return a.localName;
- }
- }
-
- var parent = this.parentElement;
- return parent ? parent._lookupNamespacePrefix(ns, originalElement) : null;
- }},
-
- // This is the 'locate a namespace' algorithm for Element nodes
- // from the DOM Core spec. It is used by Node#lookupNamespaceURI()
- lookupNamespaceURI: { value: function lookupNamespaceURI(prefix) {
- if (prefix === '' || prefix === undefined) { prefix = null; }
- if (this.namespaceURI !== null && this.prefix === prefix)
- return this.namespaceURI;
-
- for(var i = 0, n = this._numattrs; i < n; i++) {
- var a = this._attr(i);
- if (a.namespaceURI === NAMESPACE.XMLNS) {
- if (
- (a.prefix === 'xmlns' && a.localName === prefix) ||
- (prefix === null && a.prefix === null && a.localName === 'xmlns')
- ) {
- return a.value || null;
- }
- }
- }
-
- var parent = this.parentElement;
- return parent ? parent.lookupNamespaceURI(prefix) : null;
- }},
-
- //
- // Attribute handling methods and utilities
- //
-
- /*
- * Attributes in the DOM are tricky:
- *
- * - there are the 8 basic get/set/has/removeAttribute{NS} methods
- *
- * - but many HTML attributes are also 'reflected' through IDL
- * attributes which means that they can be queried and set through
- * regular properties of the element. There is just one attribute
- * value, but two ways to get and set it.
- *
- * - Different HTML element types have different sets of reflected
- attributes.
- *
- * - attributes can also be queried and set through the .attributes
- * property of an element. This property behaves like an array of
- * Attr objects. The value property of each Attr is writeable, so
- * this is a third way to read and write attributes.
- *
- * - for efficiency, we really want to store attributes in some kind
- * of name->attr map. But the attributes[] array is an array, not a
- * map, which is kind of unnatural.
- *
- * - When using namespaces and prefixes, and mixing the NS methods
- * with the non-NS methods, it is apparently actually possible for
- * an attributes[] array to have more than one attribute with the
- * same qualified name. And certain methods must operate on only
- * the first attribute with such a name. So for these methods, an
- * inefficient array-like data structure would be easier to
- * implement.
- *
- * - The attributes[] array is live, not a snapshot, so changes to the
- * attributes must be immediately visible through existing arrays.
- *
- * - When attributes are queried and set through IDL properties
- * (instead of the get/setAttributes() method or the attributes[]
- * array) they may be subject to type conversions, URL
- * normalization, etc., so some extra processing is required in that
- * case.
- *
- * - But access through IDL properties is probably the most common
- * case, so we'd like that to be as fast as possible.
- *
- * - We can't just store attribute values in their parsed idl form,
- * because setAttribute() has to return whatever string is passed to
- * getAttribute even if it is not a legal, parseable value. So
- * attribute values must be stored in unparsed string form.
- *
- * - We need to be able to send change notifications or mutation
- * events of some sort to the renderer whenever an attribute value
- * changes, regardless of the way in which it changes.
- *
- * - Some attributes, such as id and class affect other parts of the
- * DOM API, like getElementById and getElementsByClassName and so
- * for efficiency, we need to specially track changes to these
- * special attributes.
- *
- * - Some attributes like class have different names (className) when
- * reflected.
- *
- * - Attributes whose names begin with the string 'data-' are treated
- specially.
- *
- * - Reflected attributes that have a boolean type in IDL have special
- * behavior: setting them to false (in IDL) is the same as removing
- * them with removeAttribute()
- *
- * - numeric attributes (like HTMLElement.tabIndex) can have default
- * values that must be returned by the idl getter even if the
- * content attribute does not exist. (The default tabIndex value
- * actually varies based on the type of the element, so that is a
- * tricky one).
- *
- * See
- * http://www.whatwg.org/specs/web-apps/current-work/multipage/urls.html#reflect
- * for rules on how attributes are reflected.
- *
- */
-
- getAttribute: { value: function getAttribute(qname) {
- var attr = this.getAttributeNode(qname);
- return attr ? attr.value : null;
- }},
-
- getAttributeNS: { value: function getAttributeNS(ns, lname) {
- var attr = this.getAttributeNodeNS(ns, lname);
- return attr ? attr.value : null;
- }},
-
- getAttributeNode: { value: function getAttributeNode(qname) {
- qname = String(qname);
- if (/[A-Z]/.test(qname) && this.isHTML)
- qname = utils.toASCIILowerCase(qname);
- var attr = this._attrsByQName[qname];
- if (!attr) return null;
-
- if (Array.isArray(attr)) // If there is more than one
- attr = attr[0]; // use the first
-
- return attr;
- }},
-
- getAttributeNodeNS: { value: function getAttributeNodeNS(ns, lname) {
- ns = (ns === undefined || ns === null) ? '' : String(ns);
- lname = String(lname);
- var attr = this._attrsByLName[ns + '|' + lname];
- return attr ? attr : null;
- }},
-
- hasAttribute: { value: function hasAttribute(qname) {
- qname = String(qname);
- if (/[A-Z]/.test(qname) && this.isHTML)
- qname = utils.toASCIILowerCase(qname);
- return this._attrsByQName[qname] !== undefined;
- }},
-
- hasAttributeNS: { value: function hasAttributeNS(ns, lname) {
- ns = (ns === undefined || ns === null) ? '' : String(ns);
- lname = String(lname);
- var key = ns + '|' + lname;
- return this._attrsByLName[key] !== undefined;
- }},
-
- hasAttributes: { value: function hasAttributes() {
- return this._numattrs > 0;
- }},
-
- toggleAttribute: { value: function toggleAttribute(qname, force) {
- qname = String(qname);
- if (!xml.isValidName(qname)) utils.InvalidCharacterError();
- if (/[A-Z]/.test(qname) && this.isHTML)
- qname = utils.toASCIILowerCase(qname);
- var a = this._attrsByQName[qname];
- if (a === undefined) {
- if (force === undefined || force === true) {
- this._setAttribute(qname, '');
- return true;
- }
- return false;
- } else {
- if (force === undefined || force === false) {
- this.removeAttribute(qname);
- return false;
- }
- return true;
- }
- }},
-
- // Set the attribute without error checking. The parser uses this.
- _setAttribute: { value: function _setAttribute(qname, value) {
- // XXX: the spec says that this next search should be done
- // on the local name, but I think that is an error.
- // email pending on www-dom about it.
- var attr = this._attrsByQName[qname];
- var isnew;
- if (!attr) {
- attr = this._newattr(qname);
- isnew = true;
- }
- else {
- if (Array.isArray(attr)) attr = attr[0];
- }
-
- // Now set the attribute value on the new or existing Attr object.
- // The Attr.value setter method handles mutation events, etc.
- attr.value = value;
- if (this._attributes) this._attributes[qname] = attr;
- if (isnew && this._newattrhook) this._newattrhook(qname, value);
- }},
-
- // Check for errors, and then set the attribute
- setAttribute: { value: function setAttribute(qname, value) {
- qname = String(qname);
- if (!xml.isValidName(qname)) utils.InvalidCharacterError();
- if (/[A-Z]/.test(qname) && this.isHTML)
- qname = utils.toASCIILowerCase(qname);
- this._setAttribute(qname, String(value));
- }},
-
-
- // The version with no error checking used by the parser
- _setAttributeNS: { value: function _setAttributeNS(ns, qname, value) {
- var pos = qname.indexOf(':'), prefix, lname;
- if (pos < 0) {
- prefix = null;
- lname = qname;
- }
- else {
- prefix = qname.substring(0, pos);
- lname = qname.substring(pos+1);
- }
-
- if (ns === '' || ns === undefined) ns = null;
- var key = (ns === null ? '' : ns) + '|' + lname;
-
- var attr = this._attrsByLName[key];
- var isnew;
- if (!attr) {
- attr = new Attr(this, lname, prefix, ns);
- isnew = true;
- this._attrsByLName[key] = attr;
- if (this._attributes) {
- this._attributes[this._attrKeys.length] = attr;
- }
- this._attrKeys.push(key);
-
- // We also have to make the attr searchable by qname.
- // But we have to be careful because there may already
- // be an attr with this qname.
- this._addQName(attr);
- }
- else if (false /* changed in DOM 4 */) {
- // Calling setAttributeNS() can change the prefix of an
- // existing attribute in DOM 2/3.
- if (attr.prefix !== prefix) {
- // Unbind the old qname
- this._removeQName(attr);
- // Update the prefix
- attr.prefix = prefix;
- // Bind the new qname
- this._addQName(attr);
- }
-
- }
- attr.value = value; // Automatically sends mutation event
- if (isnew && this._newattrhook) this._newattrhook(qname, value);
- }},
-
- // Do error checking then call _setAttributeNS
- setAttributeNS: { value: function setAttributeNS(ns, qname, value) {
- // Convert parameter types according to WebIDL
- ns = (ns === null || ns === undefined || ns === '') ? null : String(ns);
- qname = String(qname);
- if (!xml.isValidQName(qname)) utils.InvalidCharacterError();
-
- var pos = qname.indexOf(':');
- var prefix = (pos < 0) ? null : qname.substring(0, pos);
-
- if ((prefix !== null && ns === null) ||
- (prefix === 'xml' && ns !== NAMESPACE.XML) ||
- ((qname === 'xmlns' || prefix === 'xmlns') &&
- (ns !== NAMESPACE.XMLNS)) ||
- (ns === NAMESPACE.XMLNS &&
- !(qname === 'xmlns' || prefix === 'xmlns')))
- utils.NamespaceError();
-
- this._setAttributeNS(ns, qname, String(value));
- }},
-
- setAttributeNode: { value: function setAttributeNode(attr) {
- if (attr.ownerElement !== null && attr.ownerElement !== this) {
- throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR);
- }
- var result = null;
- var oldAttrs = this._attrsByQName[attr.name];
- if (oldAttrs) {
- if (!Array.isArray(oldAttrs)) { oldAttrs = [ oldAttrs ]; }
- if (oldAttrs.some(function(a) { return a===attr; })) {
- return attr;
- } else if (attr.ownerElement !== null) {
- throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR);
- }
- oldAttrs.forEach(function(a) { this.removeAttributeNode(a); }, this);
- result = oldAttrs[0];
- }
- this.setAttributeNodeNS(attr);
- return result;
- }},
-
- setAttributeNodeNS: { value: function setAttributeNodeNS(attr) {
- if (attr.ownerElement !== null) {
- throw new DOMException(DOMException.INUSE_ATTRIBUTE_ERR);
- }
- var ns = attr.namespaceURI;
- var key = (ns === null ? '' : ns) + '|' + attr.localName;
- var oldAttr = this._attrsByLName[key];
- if (oldAttr) { this.removeAttributeNode(oldAttr); }
- attr._setOwnerElement(this);
- this._attrsByLName[key] = attr;
- if (this._attributes) {
- this._attributes[this._attrKeys.length] = attr;
- }
- this._attrKeys.push(key);
- this._addQName(attr);
- if (this._newattrhook) this._newattrhook(attr.name, attr.value);
- return oldAttr || null;
- }},
-
- removeAttribute: { value: function removeAttribute(qname) {
- qname = String(qname);
- if (/[A-Z]/.test(qname) && this.isHTML)
- qname = utils.toASCIILowerCase(qname);
-
- var attr = this._attrsByQName[qname];
- if (!attr) return;
-
- // If there is more than one match for this qname
- // so don't delete the qname mapping, just remove the first
- // element from it.
- if (Array.isArray(attr)) {
- if (attr.length > 2) {
- attr = attr.shift(); // remove it from the array
- }
- else {
- this._attrsByQName[qname] = attr[1];
- attr = attr[0];
- }
- }
- else {
- // only a single match, so remove the qname mapping
- this._attrsByQName[qname] = undefined;
- }
-
- var ns = attr.namespaceURI;
- // Now attr is the removed attribute. Figure out its
- // ns+lname key and remove it from the other mapping as well.
- var key = (ns === null ? '' : ns) + '|' + attr.localName;
- this._attrsByLName[key] = undefined;
-
- var i = this._attrKeys.indexOf(key);
- if (this._attributes) {
- Array.prototype.splice.call(this._attributes, i, 1);
- this._attributes[qname] = undefined;
- }
- this._attrKeys.splice(i, 1);
-
- // Onchange handler for the attribute
- var onchange = attr.onchange;
- attr._setOwnerElement(null);
- if (onchange) {
- onchange.call(attr, this, attr.localName, attr.value, null);
- }
- // Mutation event
- if (this.rooted) this.ownerDocument.mutateRemoveAttr(attr);
- }},
-
- removeAttributeNS: { value: function removeAttributeNS(ns, lname) {
- ns = (ns === undefined || ns === null) ? '' : String(ns);
- lname = String(lname);
- var key = ns + '|' + lname;
- var attr = this._attrsByLName[key];
- if (!attr) return;
-
- this._attrsByLName[key] = undefined;
-
- var i = this._attrKeys.indexOf(key);
- if (this._attributes) {
- Array.prototype.splice.call(this._attributes, i, 1);
- }
- this._attrKeys.splice(i, 1);
-
- // Now find the same Attr object in the qname mapping and remove it
- // But be careful because there may be more than one match.
- this._removeQName(attr);
-
- // Onchange handler for the attribute
- var onchange = attr.onchange;
- attr._setOwnerElement(null);
- if (onchange) {
- onchange.call(attr, this, attr.localName, attr.value, null);
- }
- // Mutation event
- if (this.rooted) this.ownerDocument.mutateRemoveAttr(attr);
- }},
-
- removeAttributeNode: { value: function removeAttributeNode(attr) {
- var ns = attr.namespaceURI;
- var key = (ns === null ? '' : ns) + '|' + attr.localName;
- if (this._attrsByLName[key] !== attr) {
- utils.NotFoundError();
- }
- this.removeAttributeNS(ns, attr.localName);
- return attr;
- }},
-
- getAttributeNames: { value: function getAttributeNames() {
- var elt = this;
- return this._attrKeys.map(function(key) {
- return elt._attrsByLName[key].name;
- });
- }},
-
- // This 'raw' version of getAttribute is used by the getter functions
- // of reflected attributes. It skips some error checking and
- // namespace steps
- _getattr: { value: function _getattr(qname) {
- // Assume that qname is already lowercased, so don't do it here.
- // Also don't check whether attr is an array: a qname with no
- // prefix will never have two matching Attr objects (because
- // setAttributeNS doesn't allow a non-null namespace with a
- // null prefix.
- var attr = this._attrsByQName[qname];
- return attr ? attr.value : null;
- }},
-
- // The raw version of setAttribute for reflected idl attributes.
- _setattr: { value: function _setattr(qname, value) {
- var attr = this._attrsByQName[qname];
- var isnew;
- if (!attr) {
- attr = this._newattr(qname);
- isnew = true;
- }
- attr.value = String(value);
- if (this._attributes) this._attributes[qname] = attr;
- if (isnew && this._newattrhook) this._newattrhook(qname, value);
- }},
-
- // Create a new Attr object, insert it, and return it.
- // Used by setAttribute() and by set()
- _newattr: { value: function _newattr(qname) {
- var attr = new Attr(this, qname, null, null);
- var key = '|' + qname;
- this._attrsByQName[qname] = attr;
- this._attrsByLName[key] = attr;
- if (this._attributes) {
- this._attributes[this._attrKeys.length] = attr;
- }
- this._attrKeys.push(key);
- return attr;
- }},
-
- // Add a qname->Attr mapping to the _attrsByQName object, taking into
- // account that there may be more than one attr object with the
- // same qname
- _addQName: { value: function(attr) {
- var qname = attr.name;
- var existing = this._attrsByQName[qname];
- if (!existing) {
- this._attrsByQName[qname] = attr;
- }
- else if (Array.isArray(existing)) {
- existing.push(attr);
- }
- else {
- this._attrsByQName[qname] = [existing, attr];
- }
- if (this._attributes) this._attributes[qname] = attr;
- }},
-
- // Remove a qname->Attr mapping to the _attrsByQName object, taking into
- // account that there may be more than one attr object with the
- // same qname
- _removeQName: { value: function(attr) {
- var qname = attr.name;
- var target = this._attrsByQName[qname];
-
- if (Array.isArray(target)) {
- var idx = target.indexOf(attr);
- utils.assert(idx !== -1); // It must be here somewhere
- if (target.length === 2) {
- this._attrsByQName[qname] = target[1-idx];
- if (this._attributes) {
- this._attributes[qname] = this._attrsByQName[qname];
- }
- } else {
- target.splice(idx, 1);
- if (this._attributes && this._attributes[qname] === attr) {
- this._attributes[qname] = target[0];
- }
- }
- }
- else {
- utils.assert(target === attr); // If only one, it must match
- this._attrsByQName[qname] = undefined;
- if (this._attributes) {
- this._attributes[qname] = undefined;
- }
- }
- }},
-
- // Return the number of attributes
- _numattrs: { get: function() { return this._attrKeys.length; }},
- // Return the nth Attr object
- _attr: { value: function(n) {
- return this._attrsByLName[this._attrKeys[n]];
- }},
-
- // Define getters and setters for an 'id' property that reflects
- // the content attribute 'id'.
- id: attributes.property({name: 'id'}),
-
- // Define getters and setters for a 'className' property that reflects
- // the content attribute 'class'.
- className: attributes.property({name: 'class'}),
-
- classList: { get: function() {
- var self = this;
- if (this._classList) {
- return this._classList;
- }
- var dtlist = new DOMTokenList(
- function() {
- return self.className || "";
- },
- function(v) {
- self.className = v;
- }
- );
- this._classList = dtlist;
- return dtlist;
- }, set: function(v) { this.className = v; }},
-
- matches: { value: function(selector) {
- return select.matches(this, selector);
- }},
-
- closest: { value: function(selector) {
- var el = this;
- do {
- if (el.matches && el.matches(selector)) { return el; }
- el = el.parentElement || el.parentNode;
- } while (el !== null && el.nodeType === Node.ELEMENT_NODE);
- return null;
- }},
-
- querySelector: { value: function(selector) {
- return select(selector, this)[0];
- }},
-
- querySelectorAll: { value: function(selector) {
- var nodes = select(selector, this);
- return nodes.item ? nodes : new NodeList(nodes);
- }}
-
-});
-
-Object.defineProperties(Element.prototype, ChildNode);
-Object.defineProperties(Element.prototype, NonDocumentTypeChildNode);
-
-// Register special handling for the id attribute
-attributes.registerChangeHandler(Element, 'id',
- function(element, lname, oldval, newval) {
- if (element.rooted) {
- if (oldval) {
- element.ownerDocument.delId(oldval, element);
- }
- if (newval) {
- element.ownerDocument.addId(newval, element);
- }
- }
- }
-);
-attributes.registerChangeHandler(Element, 'class',
- function(element, lname, oldval, newval) {
- if (element._classList) { element._classList._update(); }
- }
-);
-
-// The Attr class represents a single attribute. The values in
-// _attrsByQName and _attrsByLName are instances of this class.
-function Attr(elt, lname, prefix, namespace, value) {
- // localName and namespace are constant for any attr object.
- // But value may change. And so can prefix, and so, therefore can name.
- this.localName = lname;
- this.prefix = (prefix===null || prefix==='') ? null : ('' + prefix);
- this.namespaceURI = (namespace===null || namespace==='') ? null : ('' + namespace);
- this.data = value;
- // Set ownerElement last to ensure it is hooked up to onchange handler
- this._setOwnerElement(elt);
-}
-
-// In DOM 3 Attr was supposed to extend Node; in DOM 4 that was abandoned.
-Attr.prototype = Object.create(Object.prototype, {
- ownerElement: {
- get: function() { return this._ownerElement; },
- },
- _setOwnerElement: { value: function _setOwnerElement(elt) {
- this._ownerElement = elt;
- if (this.prefix === null && this.namespaceURI === null && elt) {
- this.onchange = elt._attributeChangeHandlers[this.localName];
- } else {
- this.onchange = null;
- }
- }},
-
- name: { get: function() {
- return this.prefix ? this.prefix + ':' + this.localName : this.localName;
- }},
-
- specified: { get: function() {
- // Deprecated
- return true;
- }},
-
- value: {
- get: function() {
- return this.data;
- },
- set: function(value) {
- var oldval = this.data;
- value = (value === undefined) ? '' : value + '';
- if (value === oldval) return;
-
- this.data = value;
-
- // Run the onchange hook for the attribute
- // if there is one.
- if (this.ownerElement) {
- if (this.onchange)
- this.onchange(this.ownerElement,this.localName, oldval, value);
-
- // Generate a mutation event if the element is rooted
- if (this.ownerElement.rooted)
- this.ownerElement.ownerDocument.mutateAttr(this, oldval);
- }
- },
- },
-
- cloneNode: { value: function cloneNode(deep) {
- // Both this method and Document#createAttribute*() create unowned Attrs
- return new Attr(
- null, this.localName, this.prefix, this.namespaceURI, this.data
- );
- }},
-
- // Legacy aliases (see gh#70 and https://dom.spec.whatwg.org/#interface-attr)
- nodeType: { get: function() { return Node.ATTRIBUTE_NODE; } },
- nodeName: { get: function() { return this.name; } },
- nodeValue: {
- get: function() { return this.value; },
- set: function(v) { this.value = v; },
- },
- textContent: {
- get: function() { return this.value; },
- set: function(v) {
- if (v === null || v === undefined) { v = ''; }
- this.value = v;
- },
- },
-});
-// Sneakily export this class for use by Document.createAttribute()
-Element._Attr = Attr;
-
-// The attributes property of an Element will be an instance of this class.
-// This class is really just a dummy, though. It only defines a length
-// property and an item() method. The AttrArrayProxy that
-// defines the public API just uses the Element object itself.
-function AttributesArray(elt) {
- NamedNodeMap.call(this, elt);
- for (var name in elt._attrsByQName) {
- this[name] = elt._attrsByQName[name];
- }
- for (var i = 0; i < elt._attrKeys.length; i++) {
- this[i] = elt._attrsByLName[elt._attrKeys[i]];
- }
-}
-AttributesArray.prototype = Object.create(NamedNodeMap.prototype, {
- length: { get: function() {
- return this.element._attrKeys.length;
- }, set: function() { /* ignore */ } },
- item: { value: function(n) {
- /* jshint bitwise: false */
- n = n >>> 0;
- if (n >= this.length) { return null; }
- return this.element._attrsByLName[this.element._attrKeys[n]];
- /* jshint bitwise: true */
- } },
-});
-
-// We can't make direct array access work (without Proxies, node >=6)
-// but we can make `Array.from(node.attributes)` and for-of loops work.
-if (global.Symbol && global.Symbol.iterator) {
- AttributesArray.prototype[global.Symbol.iterator] = function() {
- var i=0, n=this.length, self=this;
- return {
- next: function() {
- if (i<n) return { value: self.item(i++) };
- return { done: true };
- }
- };
- };
-}
-
-
-// The children property of an Element will be an instance of this class.
-// It defines length, item() and namedItem() and will be wrapped by an
-// HTMLCollection when exposed through the DOM.
-function ChildrenCollection(e) {
- this.element = e;
- this.updateCache();
-}
-
-ChildrenCollection.prototype = Object.create(Object.prototype, {
- length: { get: function() {
- this.updateCache();
- return this.childrenByNumber.length;
- } },
- item: { value: function item(n) {
- this.updateCache();
- return this.childrenByNumber[n] || null;
- } },
-
- namedItem: { value: function namedItem(name) {
- this.updateCache();
- return this.childrenByName[name] || null;
- } },
-
- // This attribute returns the entire name->element map.
- // It is not part of the HTMLCollection API, but we need it in
- // src/HTMLCollectionProxy
- namedItems: { get: function() {
- this.updateCache();
- return this.childrenByName;
- } },
-
- updateCache: { value: function updateCache() {
- var namedElts = /^(a|applet|area|embed|form|frame|frameset|iframe|img|object)$/;
- if (this.lastModTime !== this.element.lastModTime) {
- this.lastModTime = this.element.lastModTime;
-
- var n = this.childrenByNumber && this.childrenByNumber.length || 0;
- for(var i = 0; i < n; i++) {
- this[i] = undefined;
- }
-
- this.childrenByNumber = [];
- this.childrenByName = Object.create(null);
-
- for (var c = this.element.firstChild; c !== null; c = c.nextSibling) {
- if (c.nodeType === Node.ELEMENT_NODE) {
-
- this[this.childrenByNumber.length] = c;
- this.childrenByNumber.push(c);
-
- // XXX Are there any requirements about the namespace
- // of the id property?
- var id = c.getAttribute('id');
-
- // If there is an id that is not already in use...
- if (id && !this.childrenByName[id])
- this.childrenByName[id] = c;
-
- // For certain HTML elements we check the name attribute
- var name = c.getAttribute('name');
- if (name &&
- this.element.namespaceURI === NAMESPACE.HTML &&
- namedElts.test(this.element.localName) &&
- !this.childrenByName[name])
- this.childrenByName[id] = c;
- }
- }
- }
- } },
-});
-
-// These functions return predicates for filtering elements.
-// They're used by the Document and Element classes for methods like
-// getElementsByTagName and getElementsByClassName
-
-function localNameElementFilter(lname) {
- return function(e) { return e.localName === lname; };
-}
-
-function htmlLocalNameElementFilter(lname) {
- var lclname = utils.toASCIILowerCase(lname);
- if (lclname === lname)
- return localNameElementFilter(lname);
-
- return function(e) {
- return e.isHTML ? e.localName === lclname : e.localName === lname;
- };
-}
-
-function namespaceElementFilter(ns) {
- return function(e) { return e.namespaceURI === ns; };
-}
-
-function namespaceLocalNameElementFilter(ns, lname) {
- return function(e) {
- return e.namespaceURI === ns && e.localName === lname;
- };
-}
-
-function classNamesElementFilter(names) {
- return function(e) {
- return names.every(function(n) { return e.classList.contains(n); });
- };
-}
-
-function elementNameFilter(name) {
- return function(e) {
- // All the *HTML elements* in the document with the given name attribute
- if (e.namespaceURI !== NAMESPACE.HTML) { return false; }
- return e.getAttribute('name') === name;
- };
-}
--- a/cmd/gojafs/domino/domino-lib/Event.js
+++ /dev/null
@@ -1,66 +1,0 @@
-"use strict";
-module.exports = Event;
-
-Event.CAPTURING_PHASE = 1;
-Event.AT_TARGET = 2;
-Event.BUBBLING_PHASE = 3;
-
-function Event(type, dictionary) {
- // Initialize basic event properties
- this.type = '';
- this.target = null;
- this.currentTarget = null;
- this.eventPhase = Event.AT_TARGET;
- this.bubbles = false;
- this.cancelable = false;
- this.isTrusted = false;
- this.defaultPrevented = false;
- this.timeStamp = Date.now();
-
- // Initialize internal flags
- // XXX: Would it be better to inherit these defaults from the prototype?
- this._propagationStopped = false;
- this._immediatePropagationStopped = false;
- this._initialized = true;
- this._dispatching = false;
-
- // Now initialize based on the constructor arguments (if any)
- if (type) this.type = type;
- if (dictionary) {
- for(var p in dictionary) {
- this[p] = dictionary[p];
- }
- }
-}
-
-Event.prototype = Object.create(Object.prototype, {
- constructor: { value: Event },
- stopPropagation: { value: function stopPropagation() {
- this._propagationStopped = true;
- }},
-
- stopImmediatePropagation: { value: function stopImmediatePropagation() {
- this._propagationStopped = true;
- this._immediatePropagationStopped = true;
- }},
-
- preventDefault: { value: function preventDefault() {
- if (this.cancelable) this.defaultPrevented = true;
- }},
-
- initEvent: { value: function initEvent(type, bubbles, cancelable) {
- this._initialized = true;
- if (this._dispatching) return;
-
- this._propagationStopped = false;
- this._immediatePropagationStopped = false;
- this.defaultPrevented = false;
- this.isTrusted = false;
-
- this.target = null;
- this.type = type;
- this.bubbles = bubbles;
- this.cancelable = cancelable;
- }},
-
-});
--- a/cmd/gojafs/domino/domino-lib/EventTarget.js
+++ /dev/null
@@ -1,298 +1,0 @@
-"use strict";
-var Event = require('./Event');
-var MouseEvent = require('./MouseEvent');
-var utils = require('./utils');
-
-module.exports = EventTarget;
-
-function EventTarget() {}
-
-EventTarget.prototype = {
- // XXX
- // See WebIDL §4.8 for details on object event handlers
- // and how they should behave. We actually have to accept
- // any object to addEventListener... Can't type check it.
- // on registration.
-
- // XXX:
- // Capturing event listeners are sort of rare. I think I can optimize
- // them so that dispatchEvent can skip the capturing phase (or much of
- // it). Each time a capturing listener is added, increment a flag on
- // the target node and each of its ancestors. Decrement when removed.
- // And update the counter when nodes are added and removed from the
- // tree as well. Then, in dispatch event, the capturing phase can
- // abort if it sees any node with a zero count.
- addEventListener: function addEventListener(type, listener, capture) {
- if (!listener) return;
- if (capture === undefined) capture = false;
- if (!this._listeners) this._listeners = Object.create(null);
- if (!this._listeners[type]) this._listeners[type] = [];
- var list = this._listeners[type];
-
- // If this listener has already been registered, just return
- for(var i = 0, n = list.length; i < n; i++) {
- var l = list[i];
- if (l.listener === listener && l.capture === capture)
- return;
- }
-
- // Add an object to the list of listeners
- var obj = { listener: listener, capture: capture };
- if (typeof listener === 'function') obj.f = listener;
- list.push(obj);
- },
-
- removeEventListener: function removeEventListener(type,
- listener,
- capture) {
- if (capture === undefined) capture = false;
- if (this._listeners) {
- var list = this._listeners[type];
- if (list) {
- // Find the listener in the list and remove it
- for(var i = 0, n = list.length; i < n; i++) {
- var l = list[i];
- if (l.listener === listener && l.capture === capture) {
- if (list.length === 1) {
- this._listeners[type] = undefined;
- }
- else {
- list.splice(i, 1);
- }
- return;
- }
- }
- }
- }
- },
-
- // This is the public API for dispatching untrusted public events.
- // See _dispatchEvent for the implementation
- dispatchEvent: function dispatchEvent(event) {
- // Dispatch an untrusted event
- return this._dispatchEvent(event, false);
- },
-
- //
- // See DOMCore §4.4
- // XXX: I'll probably need another version of this method for
- // internal use, one that does not set isTrusted to false.
- // XXX: see Document._dispatchEvent: perhaps that and this could
- // call a common internal function with different settings of
- // a trusted boolean argument
- //
- // XXX:
- // The spec has changed in how to deal with handlers registered
- // on idl or content attributes rather than with addEventListener.
- // Used to say that they always ran first. That's how webkit does it
- // Spec now says that they run in a position determined by
- // when they were first set. FF does it that way. See:
- // http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#event-handlers
- //
- _dispatchEvent: function _dispatchEvent(event, trusted) {
- if (typeof trusted !== 'boolean') trusted = false;
- function invoke(target, event) {
- var type = event.type, phase = event.eventPhase;
- event.currentTarget = target;
-
- // If there was an individual handler defined, invoke it first
- // XXX: see comment above: this shouldn't always be first.
- if (phase !== Event.CAPTURING_PHASE &&
- target._handlers && target._handlers[type])
- {
- var handler = target._handlers[type];
- var rv;
- if (typeof handler === 'function') {
- rv=handler.call(event.currentTarget, event);
- }
- else {
- var f = handler.handleEvent;
- if (typeof f !== 'function')
- throw new TypeError('handleEvent property of ' +
- 'event handler object is' +
- 'not a function.');
- rv=f.call(handler, event);
- }
-
- switch(event.type) {
- case 'mouseover':
- if (rv === true) // Historical baggage
- event.preventDefault();
- break;
- case 'beforeunload':
- // XXX: eventually we need a special case here
- /* falls through */
- default:
- if (rv === false)
- event.preventDefault();
- break;
- }
- }
-
- // Now invoke list list of listeners for this target and type
- var list = target._listeners && target._listeners[type];
- if (!list) return;
- list = list.slice();
- for(var i = 0, n = list.length; i < n; i++) {
- if (event._immediatePropagationStopped) return;
- var l = list[i];
- if ((phase === Event.CAPTURING_PHASE && !l.capture) ||
- (phase === Event.BUBBLING_PHASE && l.capture))
- continue;
- if (l.f) {
- l.f.call(event.currentTarget, event);
- }
- else {
- var fn = l.listener.handleEvent;
- if (typeof fn !== 'function')
- throw new TypeError('handleEvent property of event listener object is not a function.');
- fn.call(l.listener, event);
- }
- }
- }
-
- if (!event._initialized || event._dispatching) utils.InvalidStateError();
- event.isTrusted = trusted;
-
- // Begin dispatching the event now
- event._dispatching = true;
- event.target = this;
-
- // Build the list of targets for the capturing and bubbling phases
- // XXX: we'll eventually have to add Window to this list.
- var ancestors = [];
- for(var n = this.parentNode; n; n = n.parentNode)
- ancestors.push(n);
-
- // Capturing phase
- event.eventPhase = Event.CAPTURING_PHASE;
- for(var i = ancestors.length-1; i >= 0; i--) {
- invoke(ancestors[i], event);
- if (event._propagationStopped) break;
- }
-
- // At target phase
- if (!event._propagationStopped) {
- event.eventPhase = Event.AT_TARGET;
- invoke(this, event);
- }
-
- // Bubbling phase
- if (event.bubbles && !event._propagationStopped) {
- event.eventPhase = Event.BUBBLING_PHASE;
- for(var ii = 0, nn = ancestors.length; ii < nn; ii++) {
- invoke(ancestors[ii], event);
- if (event._propagationStopped) break;
- }
- }
-
- event._dispatching = false;
- event.eventPhase = Event.AT_TARGET;
- event.currentTarget = null;
-
- // Deal with mouse events and figure out when
- // a click has happened
- if (trusted && !event.defaultPrevented && event instanceof MouseEvent) {
- switch(event.type) {
- case 'mousedown':
- this._armed = {
- x: event.clientX,
- y: event.clientY,
- t: event.timeStamp
- };
- break;
- case 'mouseout':
- case 'mouseover':
- this._armed = null;
- break;
- case 'mouseup':
- if (this._isClick(event)) this._doClick(event);
- this._armed = null;
- break;
- }
- }
-
-
-
- return !event.defaultPrevented;
- },
-
- // Determine whether a click occurred
- // XXX We don't support double clicks for now
- _isClick: function(event) {
- return (this._armed !== null &&
- event.type === 'mouseup' &&
- event.isTrusted &&
- event.button === 0 &&
- event.timeStamp - this._armed.t < 1000 &&
- Math.abs(event.clientX - this._armed.x) < 10 &&
- Math.abs(event.clientY - this._armed.Y) < 10);
- },
-
- // Clicks are handled like this:
- // http://www.whatwg.org/specs/web-apps/current-work/multipage/elements.html#interactive-content-0
- //
- // Note that this method is similar to the HTMLElement.click() method
- // The event argument must be the trusted mouseup event
- _doClick: function(event) {
- if (this._click_in_progress) return;
- this._click_in_progress = true;
-
- // Find the nearest enclosing element that is activatable
- // An element is activatable if it has a
- // _post_click_activation_steps hook
- var activated = this;
- while(activated && !activated._post_click_activation_steps)
- activated = activated.parentNode;
-
- if (activated && activated._pre_click_activation_steps) {
- activated._pre_click_activation_steps();
- }
-
- var click = this.ownerDocument.createEvent('MouseEvent');
- click.initMouseEvent('click', true, true,
- this.ownerDocument.defaultView, 1,
- event.screenX, event.screenY,
- event.clientX, event.clientY,
- event.ctrlKey, event.altKey,
- event.shiftKey, event.metaKey,
- event.button, null);
-
- var result = this._dispatchEvent(click, true);
-
- if (activated) {
- if (result) {
- // This is where hyperlinks get followed, for example.
- if (activated._post_click_activation_steps)
- activated._post_click_activation_steps(click);
- }
- else {
- if (activated._cancelled_activation_steps)
- activated._cancelled_activation_steps();
- }
- }
- },
-
- //
- // An event handler is like an event listener, but it registered
- // by setting an IDL or content attribute like onload or onclick.
- // There can only be one of these at a time for any event type.
- // This is an internal method for the attribute accessors and
- // content attribute handlers that need to register events handlers.
- // The type argument is the same as in addEventListener().
- // The handler argument is the same as listeners in addEventListener:
- // it can be a function or an object. Pass null to remove any existing
- // handler. Handlers are always invoked before any listeners of
- // the same type. They are not invoked during the capturing phase
- // of event dispatch.
- //
- _setEventHandler: function _setEventHandler(type, handler) {
- if (!this._handlers) this._handlers = Object.create(null);
- this._handlers[type] = handler;
- },
-
- _getEventHandler: function _getEventHandler(type) {
- return (this._handlers && this._handlers[type]) || null;
- }
-
-};
--- a/cmd/gojafs/domino/domino-lib/FilteredElementList.js
+++ /dev/null
@@ -1,92 +1,0 @@
-"use strict";
-module.exports = FilteredElementList;
-
-var Node = require('./Node');
-
-//
-// This file defines node list implementation that lazily traverses
-// the document tree (or a subtree rooted at any element) and includes
-// only those elements for which a specified filter function returns true.
-// It is used to implement the
-// {Document,Element}.getElementsBy{TagName,ClassName}{,NS} methods.
-//
-// XXX this should inherit from NodeList
-
-function FilteredElementList(root, filter) {
- this.root = root;
- this.filter = filter;
- this.lastModTime = root.lastModTime;
- this.done = false;
- this.cache = [];
- this.traverse();
-}
-
-FilteredElementList.prototype = Object.create(Object.prototype, {
- length: { get: function() {
- this.checkcache();
- if (!this.done) this.traverse();
- return this.cache.length;
- } },
-
- item: { value: function(n) {
- this.checkcache();
- if (!this.done && n >= this.cache.length) {
- // This can lead to O(N^2) behavior if we stop when we get to n
- // and the caller is iterating through the items in order; so
- // be sure to do the full traverse here.
- this.traverse(/*n*/);
- }
- return this.cache[n];
- } },
-
- checkcache: { value: function() {
- if (this.lastModTime !== this.root.lastModTime) {
- // subtree has changed, so invalidate cache
- for (var i = this.cache.length-1; i>=0; i--) {
- this[i] = undefined;
- }
- this.cache.length = 0;
- this.done = false;
- this.lastModTime = this.root.lastModTime;
- }
- } },
-
- // If n is specified, then traverse the tree until we've found the nth
- // item (or until we've found all items). If n is not specified,
- // traverse until we've found all items.
- traverse: { value: function(n) {
- // increment n so we can compare to length, and so it is never falsy
- if (n !== undefined) n++;
-
- var elt;
- while ((elt = this.next()) !== null) {
- this[this.cache.length] = elt; //XXX Use proxy instead
- this.cache.push(elt);
- if (n && this.cache.length === n) return;
- }
-
- // no next element, so we've found everything
- this.done = true;
- } },
-
- // Return the next element under root that matches filter
- next: { value: function() {
- var start = (this.cache.length === 0) ? this.root // Start at the root or at
- : this.cache[this.cache.length-1]; // the last element we found
-
- var elt;
- if (start.nodeType === Node.DOCUMENT_NODE)
- elt = start.documentElement;
- else
- elt = start.nextElement(this.root);
-
- while(elt) {
- if (this.filter(elt)) {
- return elt;
- }
-
- elt = elt.nextElement(this.root);
- }
- return null;
- } },
-});
--- a/cmd/gojafs/domino/domino-lib/HTMLParser.js
+++ /dev/null
@@ -1,7264 +1,0 @@
-"use strict";
-module.exports = HTMLParser;
-
-var Document = require('./Document');
-var DocumentType = require('./DocumentType');
-var Node = require('./Node');
-var NAMESPACE = require('./utils').NAMESPACE;
-var html = require('./htmlelts');
-var impl = html.elements;
-
-var pushAll = Function.prototype.apply.bind(Array.prototype.push);
-
-/*
- * This file contains an implementation of the HTML parsing algorithm.
- * The algorithm and the implementation are complex because HTML
- * explicitly defines how the parser should behave for all possible
- * valid and invalid inputs.
- *
- * Usage:
- *
- * The file defines a single HTMLParser() function, which dom.js exposes
- * publicly as document.implementation.mozHTMLParser(). This is a
- * factory function, not a constructor.
- *
- * When you call document.implementation.mozHTMLParser(), it returns
- * an object that has parse() and document() methods. To parse HTML text,
- * pass the text (in one or more chunks) to the parse() method. When
- * you've passed all the text (on the last chunk, or afterward) pass
- * true as the second argument to parse() to tell the parser that there
- * is no more coming. Call document() to get the document object that
- * the parser is parsing into. You can call this at any time, before
- * or after calling parse().
- *
- * The first argument to mozHTMLParser is the absolute URL of the document.
- *
- * The second argument is optional and is for internal use only. Pass an
- * element as the fragmentContext to do innerHTML parsing for the
- * element. To do innerHTML parsing on a document, pass null. Otherwise,
- * omit the 2nd argument. See HTMLElement.innerHTML for an example. Note
- * that if you pass a context element, the end() method will return an
- * unwrapped document instead of a wrapped one.
- *
- * Implementation details:
- *
- * This is a long file of almost 7000 lines. It is structured as one
- * big function nested within another big function. The outer
- * function defines a bunch of constant data, utility functions
- * that use that data, and a couple of classes used by the parser.
- * The outer function also defines and returns the
- * inner function. This inner function is the HTMLParser factory
- * function that implements the parser and holds all the parser state
- * as local variables. The HTMLParser function is quite big because
- * it defines many nested functions that use those local variables.
- *
- * There are three tightly coupled parser stages: a scanner, a
- * tokenizer and a tree builder. In a (possibly misguided) attempt at
- * efficiency, the stages are not implemented as separate classes:
- * everything shares state and is (mostly) implemented in imperative
- * (rather than OO) style.
- *
- * The stages of the parser work like this: When the client code calls
- * the parser's parse() method, the specified string is passed to
- * scanChars(). The scanner loops through that string and passes characters
- * (sometimes one at a time, sometimes in chunks) to the tokenizer stage.
- * The tokenizer groups the characters into tokens: tags, endtags, runs
- * of text, comments, doctype declarations, and the end-of-file (EOF)
- * token. These tokens are then passed to the tree building stage via
- * the insertToken() function. The tree building stage builds up the
- * document tree.
- *
- * The tokenizer stage is a finite state machine. Each state is
- * implemented as a function with a name that ends in "_state". The
- * initial state is data_state(). The current tokenizer state is stored
- * in the variable 'tokenizer'. Most state functions expect a single
- * integer argument which represents a single UTF-16 codepoint. Some
- * states want more characters and set a lookahead property on
- * themselves. The scanChars() function in the scanner checks for this
- * lookahead property. If it doesn't exist, then scanChars() just passes
- * the next input character to the current tokenizer state function.
- * Otherwise, scanChars() looks ahead (a given # of characters, or for a
- * matching string, or for a matching regexp) and passes a string of
- * characters to the current tokenizer state function.
- *
- * As a shortcut, certain states of the tokenizer use regular expressions
- * to look ahead in the scanner's input buffer for runs of text, simple
- * tags and attributes. For well-formed input, these shortcuts skip a
- * lot of state transitions and speed things up a bit.
- *
- * When a tokenizer state function has consumed a complete token, it
- * emits that token, by calling insertToken(), or by calling a utility
- * function that itself calls insertToken(). These tokens are passed to
- * the tree building stage, which is also a state machine. Like the
- * tokenizer, the tree building states are implemented as functions, and
- * these functions have names that end with _mode (because the HTML spec
- * refers to them as insertion modes). The current insertion mode is held
- * by the 'parser' variable. Each insertion mode function takes up to 4
- * arguments. The first is a token type, represented by the constants
- * TAG, ENDTAG, TEXT, COMMENT, DOCTYPE and EOF. The second argument is
- * the value of the token: the text or comment data, or tagname or
- * doctype. For tags, the 3rd argument is an array of attributes. For
- * DOCTYPES it is the optional public id. For tags, the 4th argument is
- * true if the tag is self-closing. For doctypes, the 4th argument is the
- * optional system id.
- *
- * Search for "***" to find the major sub-divisions in the code.
- */
-
-
-/***
- * Data prolog. Lots of constants declared here, including some
- * very large objects. They're used throughout the code that follows
- */
-// Token types for the tree builder.
-var EOF = -1;
-var TEXT = 1;
-var TAG = 2;
-var ENDTAG = 3;
-var COMMENT = 4;
-var DOCTYPE = 5;
-
-// A re-usable empty array
-var NOATTRS = [];
-
-// These DTD public ids put the browser in quirks mode
-var quirkyPublicIds = /^HTML$|^-\/\/W3O\/\/DTD W3 HTML Strict 3\.0\/\/EN\/\/$|^-\/W3C\/DTD HTML 4\.0 Transitional\/EN$|^\+\/\/Silmaril\/\/dtd html Pro v0r11 19970101\/\/|^-\/\/AdvaSoft Ltd\/\/DTD HTML 3\.0 asWedit \+ extensions\/\/|^-\/\/AS\/\/DTD HTML 3\.0 asWedit \+ extensions\/\/|^-\/\/IETF\/\/DTD HTML 2\.0 Level 1\/\/|^-\/\/IETF\/\/DTD HTML 2\.0 Level 2\/\/|^-\/\/IETF\/\/DTD HTML 2\.0 Strict Level 1\/\/|^-\/\/IETF\/\/DTD HTML 2\.0 Strict Level 2\/\/|^-\/\/IETF\/\/DTD HTML 2\.0 Strict\/\/|^-\/\/IETF\/\/DTD HTML 2\.0\/\/|^-\/\/IETF\/\/DTD HTML 2\.1E\/\/|^-\/\/IETF\/\/DTD HTML 3\.0\/\/|^-\/\/IETF\/\/DTD HTML 3\.2 Final\/\/|^-\/\/IETF\/\/DTD HTML 3\.2\/\/|^-\/\/IETF\/\/DTD HTML 3\/\/|^-\/\/IETF\/\/DTD HTML Level 0\/\/|^-\/\/IETF\/\/DTD HTML Level 1\/\/|^-\/\/IETF\/\/DTD HTML Level 2\/\/|^-\/\/IETF\/\/DTD HTML Level 3\/\/|^-\/\/IETF\/\/DTD HTML Strict Level 0\/\/|^-\/\/IETF\/\/DTD HTML Strict Level 1\/\/|^-\/\/IETF\/\/DTD HTML Strict Level 2\/\/|^-\/\/IETF\/\/DTD HTML Strict Level 3\/\/|^-\/\/IETF\/\/DTD HTML Strict\/\/|^-\/\/IETF\/\/DTD HTML\/\/|^-\/\/Metrius\/\/DTD Metrius Presentational\/\/|^-\/\/Microsoft\/\/DTD Internet Explorer 2\.0 HTML Strict\/\/|^-\/\/Microsoft\/\/DTD Internet Explorer 2\.0 HTML\/\/|^-\/\/Microsoft\/\/DTD Internet Explorer 2\.0 Tables\/\/|^-\/\/Microsoft\/\/DTD Internet Explorer 3\.0 HTML Strict\/\/|^-\/\/Microsoft\/\/DTD Internet Explorer 3\.0 HTML\/\/|^-\/\/Microsoft\/\/DTD Internet Explorer 3\.0 Tables\/\/|^-\/\/Netscape Comm\. Corp\.\/\/DTD HTML\/\/|^-\/\/Netscape Comm\. Corp\.\/\/DTD Strict HTML\/\/|^-\/\/O'Reilly and Associates\/\/DTD HTML 2\.0\/\/|^-\/\/O'Reilly and Associates\/\/DTD HTML Extended 1\.0\/\/|^-\/\/O'Reilly and Associates\/\/DTD HTML Extended Relaxed 1\.0\/\/|^-\/\/SoftQuad Software\/\/DTD HoTMetaL PRO 6\.0::19990601::extensions to HTML 4\.0\/\/|^-\/\/SoftQuad\/\/DTD HoTMetaL PRO 4\.0::19971010::extensions to HTML 4\.0\/\/|^-\/\/Spyglass\/\/DTD HTML 2\.0 Extended\/\/|^-\/\/SQ\/\/DTD HTML 2\.0 HoTMetaL \+ extensions\/\/|^-\/\/Sun Microsystems Corp\.\/\/DTD HotJava HTML\/\/|^-\/\/Sun Microsystems Corp\.\/\/DTD HotJava Strict HTML\/\/|^-\/\/W3C\/\/DTD HTML 3 1995-03-24\/\/|^-\/\/W3C\/\/DTD HTML 3\.2 Draft\/\/|^-\/\/W3C\/\/DTD HTML 3\.2 Final\/\/|^-\/\/W3C\/\/DTD HTML 3\.2\/\/|^-\/\/W3C\/\/DTD HTML 3\.2S Draft\/\/|^-\/\/W3C\/\/DTD HTML 4\.0 Frameset\/\/|^-\/\/W3C\/\/DTD HTML 4\.0 Transitional\/\/|^-\/\/W3C\/\/DTD HTML Experimental 19960712\/\/|^-\/\/W3C\/\/DTD HTML Experimental 970421\/\/|^-\/\/W3C\/\/DTD W3 HTML\/\/|^-\/\/W3O\/\/DTD W3 HTML 3\.0\/\/|^-\/\/WebTechs\/\/DTD Mozilla HTML 2\.0\/\/|^-\/\/WebTechs\/\/DTD Mozilla HTML\/\//i;
-
-var quirkySystemId = "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd";
-
-var conditionallyQuirkyPublicIds = /^-\/\/W3C\/\/DTD HTML 4\.01 Frameset\/\/|^-\/\/W3C\/\/DTD HTML 4\.01 Transitional\/\//i;
-
-// These DTD public ids put the browser in limited quirks mode
-var limitedQuirkyPublicIds = /^-\/\/W3C\/\/DTD XHTML 1\.0 Frameset\/\/|^-\/\/W3C\/\/DTD XHTML 1\.0 Transitional\/\//i;
-
-
-// Element sets below. See the isA() function for a way to test
-// whether an element is a member of a set
-var specialSet = Object.create(null);
-specialSet[NAMESPACE.HTML] = {
- __proto__: null,
- "address":true, "applet":true, "area":true, "article":true,
- "aside":true, "base":true, "basefont":true, "bgsound":true,
- "blockquote":true, "body":true, "br":true, "button":true,
- "caption":true, "center":true, "col":true, "colgroup":true,
- "dd":true, "details":true, "dir":true,
- "div":true, "dl":true, "dt":true, "embed":true,
- "fieldset":true, "figcaption":true, "figure":true, "footer":true,
- "form":true, "frame":true, "frameset":true, "h1":true,
- "h2":true, "h3":true, "h4":true, "h5":true,
- "h6":true, "head":true, "header":true, "hgroup":true,
- "hr":true, "html":true, "iframe":true, "img":true,
- "input":true, "li":true, "link":true,
- "listing":true, "main":true, "marquee":true, "menu":true, "meta":true,
- "nav":true, "noembed":true, "noframes":true, "noscript":true,
- "object":true, "ol":true, "p":true, "param":true,
- "plaintext":true, "pre":true, "script":true, "section":true,
- "select":true, "source":true, "style":true, "summary":true, "table":true,
- "tbody":true, "td":true, "template":true, "textarea":true, "tfoot":true,
- "th":true, "thead":true, "title":true, "tr":true, "track":true,
- // Note that "xmp" was removed from the "special" set in the latest
- // spec, apparently by accident; see
- // https://github.com/whatwg/html/pull/1919
- "ul":true, "wbr":true, "xmp":true
-};
-specialSet[NAMESPACE.SVG] = {
- __proto__: null,
- "foreignObject": true, "desc": true, "title": true
-};
-specialSet[NAMESPACE.MATHML] = {
- __proto__: null,
- "mi":true, "mo":true, "mn":true, "ms":true,
- "mtext":true, "annotation-xml":true
-};
-
-// The set of address, div, and p HTML tags
-var addressdivpSet = Object.create(null);
-addressdivpSet[NAMESPACE.HTML] = {
- __proto__: null,
- "address":true, "div":true, "p":true
-};
-
-var dddtSet = Object.create(null);
-dddtSet[NAMESPACE.HTML] = {
- __proto__: null,
- "dd":true, "dt":true
-};
-
-var tablesectionrowSet = Object.create(null);
-tablesectionrowSet[NAMESPACE.HTML] = {
- __proto__: null,
- "table":true, "thead":true, "tbody":true, "tfoot":true, "tr":true
-};
-
-var impliedEndTagsSet = Object.create(null);
-impliedEndTagsSet[NAMESPACE.HTML] = {
- __proto__: null,
- "dd": true, "dt": true, "li": true, "menuitem": true, "optgroup": true,
- "option": true, "p": true, "rb": true, "rp": true, "rt": true, "rtc": true
-};
-
-var thoroughImpliedEndTagsSet = Object.create(null);
-thoroughImpliedEndTagsSet[NAMESPACE.HTML] = {
- __proto__: null,
- "caption": true, "colgroup": true, "dd": true, "dt": true, "li": true,
- "optgroup": true, "option": true, "p": true, "rb": true, "rp": true,
- "rt": true, "rtc": true, "tbody": true, "td": true, "tfoot": true,
- "th": true, "thead": true, "tr": true
-};
-
-var tableContextSet = Object.create(null);
-tableContextSet[NAMESPACE.HTML] = {
- __proto__: null,
- "table": true, "template": true, "html": true
-};
-
-var tableBodyContextSet = Object.create(null);
-tableBodyContextSet[NAMESPACE.HTML] = {
- __proto__: null,
- "tbody": true, "tfoot": true, "thead": true, "template": true, "html": true
-};
-
-var tableRowContextSet = Object.create(null);
-tableRowContextSet[NAMESPACE.HTML] = {
- __proto__: null,
- "tr": true, "template": true, "html": true
-};
-
-// See http://www.w3.org/TR/html5/forms.html#form-associated-element
-var formassociatedSet = Object.create(null);
-formassociatedSet[NAMESPACE.HTML] = {
- __proto__: null,
- "button": true, "fieldset": true, "input": true, "keygen": true,
- "object": true, "output": true, "select": true, "textarea": true,
- "img": true
-};
-
-var inScopeSet = Object.create(null);
-inScopeSet[NAMESPACE.HTML]= {
- __proto__: null,
- "applet":true, "caption":true, "html":true, "table":true,
- "td":true, "th":true, "marquee":true, "object":true,
- "template":true
-};
-inScopeSet[NAMESPACE.MATHML] = {
- __proto__: null,
- "mi":true, "mo":true, "mn":true, "ms":true,
- "mtext":true, "annotation-xml":true
-};
-inScopeSet[NAMESPACE.SVG] = {
- __proto__: null,
- "foreignObject":true, "desc":true, "title":true
-};
-
-var inListItemScopeSet = Object.create(inScopeSet);
-inListItemScopeSet[NAMESPACE.HTML] =
- Object.create(inScopeSet[NAMESPACE.HTML]);
-inListItemScopeSet[NAMESPACE.HTML].ol = true;
-inListItemScopeSet[NAMESPACE.HTML].ul = true;
-
-var inButtonScopeSet = Object.create(inScopeSet);
-inButtonScopeSet[NAMESPACE.HTML] =
- Object.create(inScopeSet[NAMESPACE.HTML]);
-inButtonScopeSet[NAMESPACE.HTML].button = true;
-
-var inTableScopeSet = Object.create(null);
-inTableScopeSet[NAMESPACE.HTML] = {
- __proto__: null,
- "html":true, "table":true, "template":true
-};
-
-// The set of elements for select scope is the everything *except* these
-var invertedSelectScopeSet = Object.create(null);
-invertedSelectScopeSet[NAMESPACE.HTML] = {
- __proto__: null,
- "optgroup":true, "option":true
-};
-
-var mathmlTextIntegrationPointSet = Object.create(null);
-mathmlTextIntegrationPointSet[NAMESPACE.MATHML] = {
- __proto__: null,
- mi: true,
- mo: true,
- mn: true,
- ms: true,
- mtext: true
-};
-
-var htmlIntegrationPointSet = Object.create(null);
-htmlIntegrationPointSet[NAMESPACE.SVG] = {
- __proto__: null,
- foreignObject: true,
- desc: true,
- title: true
-};
-
-var foreignAttributes = {
- __proto__: null,
- "xlink:actuate": NAMESPACE.XLINK, "xlink:arcrole": NAMESPACE.XLINK,
- "xlink:href": NAMESPACE.XLINK, "xlink:role": NAMESPACE.XLINK,
- "xlink:show": NAMESPACE.XLINK, "xlink:title": NAMESPACE.XLINK,
- "xlink:type": NAMESPACE.XLINK, "xml:base": NAMESPACE.XML,
- "xml:lang": NAMESPACE.XML, "xml:space": NAMESPACE.XML,
- "xmlns": NAMESPACE.XMLNS, "xmlns:xlink": NAMESPACE.XMLNS
-};
-
-
-// Lowercase to mixed case mapping for SVG attributes and tagnames
-var svgAttrAdjustments = {
- __proto__: null,
- attributename: "attributeName", attributetype: "attributeType",
- basefrequency: "baseFrequency", baseprofile: "baseProfile",
- calcmode: "calcMode", clippathunits: "clipPathUnits",
- diffuseconstant: "diffuseConstant",
- edgemode: "edgeMode",
- filterunits: "filterUnits",
- glyphref: "glyphRef", gradienttransform: "gradientTransform",
- gradientunits: "gradientUnits", kernelmatrix: "kernelMatrix",
- kernelunitlength: "kernelUnitLength", keypoints: "keyPoints",
- keysplines: "keySplines", keytimes: "keyTimes",
- lengthadjust: "lengthAdjust", limitingconeangle: "limitingConeAngle",
- markerheight: "markerHeight", markerunits: "markerUnits",
- markerwidth: "markerWidth", maskcontentunits: "maskContentUnits",
- maskunits: "maskUnits", numoctaves: "numOctaves",
- pathlength: "pathLength", patterncontentunits: "patternContentUnits",
- patterntransform: "patternTransform", patternunits: "patternUnits",
- pointsatx: "pointsAtX", pointsaty: "pointsAtY",
- pointsatz: "pointsAtZ", preservealpha: "preserveAlpha",
- preserveaspectratio: "preserveAspectRatio",
- primitiveunits: "primitiveUnits", refx: "refX",
- refy: "refY", repeatcount: "repeatCount",
- repeatdur: "repeatDur", requiredextensions: "requiredExtensions",
- requiredfeatures: "requiredFeatures",
- specularconstant: "specularConstant",
- specularexponent: "specularExponent", spreadmethod: "spreadMethod",
- startoffset: "startOffset", stddeviation: "stdDeviation",
- stitchtiles: "stitchTiles", surfacescale: "surfaceScale",
- systemlanguage: "systemLanguage", tablevalues: "tableValues",
- targetx: "targetX", targety: "targetY",
- textlength: "textLength", viewbox: "viewBox",
- viewtarget: "viewTarget", xchannelselector: "xChannelSelector",
- ychannelselector: "yChannelSelector", zoomandpan: "zoomAndPan"
-};
-
-var svgTagNameAdjustments = {
- __proto__: null,
- altglyph: "altGlyph", altglyphdef: "altGlyphDef",
- altglyphitem: "altGlyphItem", animatecolor: "animateColor",
- animatemotion: "animateMotion", animatetransform: "animateTransform",
- clippath: "clipPath", feblend: "feBlend",
- fecolormatrix: "feColorMatrix",
- fecomponenttransfer: "feComponentTransfer", fecomposite: "feComposite",
- feconvolvematrix: "feConvolveMatrix",
- fediffuselighting: "feDiffuseLighting",
- fedisplacementmap: "feDisplacementMap",
- fedistantlight: "feDistantLight", feflood: "feFlood",
- fefunca: "feFuncA", fefuncb: "feFuncB",
- fefuncg: "feFuncG", fefuncr: "feFuncR",
- fegaussianblur: "feGaussianBlur", feimage: "feImage",
- femerge: "feMerge", femergenode: "feMergeNode",
- femorphology: "feMorphology", feoffset: "feOffset",
- fepointlight: "fePointLight", fespecularlighting: "feSpecularLighting",
- fespotlight: "feSpotLight", fetile: "feTile",
- feturbulence: "feTurbulence", foreignobject: "foreignObject",
- glyphref: "glyphRef", lineargradient: "linearGradient",
- radialgradient: "radialGradient", textpath: "textPath"
-};
-
-
-// Data for parsing numeric and named character references
-// These next 3 objects are direct translations of tables
-// in the HTML spec into JavaScript object format
-var numericCharRefReplacements = {
- __proto__: null,
- 0x00:0xFFFD, 0x80:0x20AC, 0x82:0x201A, 0x83:0x0192, 0x84:0x201E,
- 0x85:0x2026, 0x86:0x2020, 0x87:0x2021, 0x88:0x02C6, 0x89:0x2030,
- 0x8A:0x0160, 0x8B:0x2039, 0x8C:0x0152, 0x8E:0x017D, 0x91:0x2018,
- 0x92:0x2019, 0x93:0x201C, 0x94:0x201D, 0x95:0x2022, 0x96:0x2013,
- 0x97:0x2014, 0x98:0x02DC, 0x99:0x2122, 0x9A:0x0161, 0x9B:0x203A,
- 0x9C:0x0153, 0x9E:0x017E, 0x9F:0x0178
-};
-
-/*
- * This table is generated with test/tools/update-entities.js
- */
-var namedCharRefs = {
- __proto__: null,
- "AElig":0xc6, "AElig;":0xc6,
- "AMP":0x26, "AMP;":0x26,
- "Aacute":0xc1, "Aacute;":0xc1,
- "Abreve;":0x102, "Acirc":0xc2,
- "Acirc;":0xc2, "Acy;":0x410,
- "Afr;":[0xd835,0xdd04], "Agrave":0xc0,
- "Agrave;":0xc0, "Alpha;":0x391,
- "Amacr;":0x100, "And;":0x2a53,
- "Aogon;":0x104, "Aopf;":[0xd835,0xdd38],
- "ApplyFunction;":0x2061, "Aring":0xc5,
- "Aring;":0xc5, "Ascr;":[0xd835,0xdc9c],
- "Assign;":0x2254, "Atilde":0xc3,
- "Atilde;":0xc3, "Auml":0xc4,
- "Auml;":0xc4, "Backslash;":0x2216,
- "Barv;":0x2ae7, "Barwed;":0x2306,
- "Bcy;":0x411, "Because;":0x2235,
- "Bernoullis;":0x212c, "Beta;":0x392,
- "Bfr;":[0xd835,0xdd05], "Bopf;":[0xd835,0xdd39],
- "Breve;":0x2d8, "Bscr;":0x212c,
- "Bumpeq;":0x224e, "CHcy;":0x427,
- "COPY":0xa9, "COPY;":0xa9,
- "Cacute;":0x106, "Cap;":0x22d2,
- "CapitalDifferentialD;":0x2145, "Cayleys;":0x212d,
- "Ccaron;":0x10c, "Ccedil":0xc7,
- "Ccedil;":0xc7, "Ccirc;":0x108,
- "Cconint;":0x2230, "Cdot;":0x10a,
- "Cedilla;":0xb8, "CenterDot;":0xb7,
- "Cfr;":0x212d, "Chi;":0x3a7,
- "CircleDot;":0x2299, "CircleMinus;":0x2296,
- "CirclePlus;":0x2295, "CircleTimes;":0x2297,
- "ClockwiseContourIntegral;":0x2232, "CloseCurlyDoubleQuote;":0x201d,
- "CloseCurlyQuote;":0x2019, "Colon;":0x2237,
- "Colone;":0x2a74, "Congruent;":0x2261,
- "Conint;":0x222f, "ContourIntegral;":0x222e,
- "Copf;":0x2102, "Coproduct;":0x2210,
- "CounterClockwiseContourIntegral;":0x2233, "Cross;":0x2a2f,
- "Cscr;":[0xd835,0xdc9e], "Cup;":0x22d3,
- "CupCap;":0x224d, "DD;":0x2145,
- "DDotrahd;":0x2911, "DJcy;":0x402,
- "DScy;":0x405, "DZcy;":0x40f,
- "Dagger;":0x2021, "Darr;":0x21a1,
- "Dashv;":0x2ae4, "Dcaron;":0x10e,
- "Dcy;":0x414, "Del;":0x2207,
- "Delta;":0x394, "Dfr;":[0xd835,0xdd07],
- "DiacriticalAcute;":0xb4, "DiacriticalDot;":0x2d9,
- "DiacriticalDoubleAcute;":0x2dd, "DiacriticalGrave;":0x60,
- "DiacriticalTilde;":0x2dc, "Diamond;":0x22c4,
- "DifferentialD;":0x2146, "Dopf;":[0xd835,0xdd3b],
- "Dot;":0xa8, "DotDot;":0x20dc,
- "DotEqual;":0x2250, "DoubleContourIntegral;":0x222f,
- "DoubleDot;":0xa8, "DoubleDownArrow;":0x21d3,
- "DoubleLeftArrow;":0x21d0, "DoubleLeftRightArrow;":0x21d4,
- "DoubleLeftTee;":0x2ae4, "DoubleLongLeftArrow;":0x27f8,
- "DoubleLongLeftRightArrow;":0x27fa, "DoubleLongRightArrow;":0x27f9,
- "DoubleRightArrow;":0x21d2, "DoubleRightTee;":0x22a8,
- "DoubleUpArrow;":0x21d1, "DoubleUpDownArrow;":0x21d5,
- "DoubleVerticalBar;":0x2225, "DownArrow;":0x2193,
- "DownArrowBar;":0x2913, "DownArrowUpArrow;":0x21f5,
- "DownBreve;":0x311, "DownLeftRightVector;":0x2950,
- "DownLeftTeeVector;":0x295e, "DownLeftVector;":0x21bd,
- "DownLeftVectorBar;":0x2956, "DownRightTeeVector;":0x295f,
- "DownRightVector;":0x21c1, "DownRightVectorBar;":0x2957,
- "DownTee;":0x22a4, "DownTeeArrow;":0x21a7,
- "Downarrow;":0x21d3, "Dscr;":[0xd835,0xdc9f],
- "Dstrok;":0x110, "ENG;":0x14a,
- "ETH":0xd0, "ETH;":0xd0,
- "Eacute":0xc9, "Eacute;":0xc9,
- "Ecaron;":0x11a, "Ecirc":0xca,
- "Ecirc;":0xca, "Ecy;":0x42d,
- "Edot;":0x116, "Efr;":[0xd835,0xdd08],
- "Egrave":0xc8, "Egrave;":0xc8,
- "Element;":0x2208, "Emacr;":0x112,
- "EmptySmallSquare;":0x25fb, "EmptyVerySmallSquare;":0x25ab,
- "Eogon;":0x118, "Eopf;":[0xd835,0xdd3c],
- "Epsilon;":0x395, "Equal;":0x2a75,
- "EqualTilde;":0x2242, "Equilibrium;":0x21cc,
- "Escr;":0x2130, "Esim;":0x2a73,
- "Eta;":0x397, "Euml":0xcb,
- "Euml;":0xcb, "Exists;":0x2203,
- "ExponentialE;":0x2147, "Fcy;":0x424,
- "Ffr;":[0xd835,0xdd09], "FilledSmallSquare;":0x25fc,
- "FilledVerySmallSquare;":0x25aa, "Fopf;":[0xd835,0xdd3d],
- "ForAll;":0x2200, "Fouriertrf;":0x2131,
- "Fscr;":0x2131, "GJcy;":0x403,
- "GT":0x3e, "GT;":0x3e,
- "Gamma;":0x393, "Gammad;":0x3dc,
- "Gbreve;":0x11e, "Gcedil;":0x122,
- "Gcirc;":0x11c, "Gcy;":0x413,
- "Gdot;":0x120, "Gfr;":[0xd835,0xdd0a],
- "Gg;":0x22d9, "Gopf;":[0xd835,0xdd3e],
- "GreaterEqual;":0x2265, "GreaterEqualLess;":0x22db,
- "GreaterFullEqual;":0x2267, "GreaterGreater;":0x2aa2,
- "GreaterLess;":0x2277, "GreaterSlantEqual;":0x2a7e,
- "GreaterTilde;":0x2273, "Gscr;":[0xd835,0xdca2],
- "Gt;":0x226b, "HARDcy;":0x42a,
- "Hacek;":0x2c7, "Hat;":0x5e,
- "Hcirc;":0x124, "Hfr;":0x210c,
- "HilbertSpace;":0x210b, "Hopf;":0x210d,
- "HorizontalLine;":0x2500, "Hscr;":0x210b,
- "Hstrok;":0x126, "HumpDownHump;":0x224e,
- "HumpEqual;":0x224f, "IEcy;":0x415,
- "IJlig;":0x132, "IOcy;":0x401,
- "Iacute":0xcd, "Iacute;":0xcd,
- "Icirc":0xce, "Icirc;":0xce,
- "Icy;":0x418, "Idot;":0x130,
- "Ifr;":0x2111, "Igrave":0xcc,
- "Igrave;":0xcc, "Im;":0x2111,
- "Imacr;":0x12a, "ImaginaryI;":0x2148,
- "Implies;":0x21d2, "Int;":0x222c,
- "Integral;":0x222b, "Intersection;":0x22c2,
- "InvisibleComma;":0x2063, "InvisibleTimes;":0x2062,
- "Iogon;":0x12e, "Iopf;":[0xd835,0xdd40],
- "Iota;":0x399, "Iscr;":0x2110,
- "Itilde;":0x128, "Iukcy;":0x406,
- "Iuml":0xcf, "Iuml;":0xcf,
- "Jcirc;":0x134, "Jcy;":0x419,
- "Jfr;":[0xd835,0xdd0d], "Jopf;":[0xd835,0xdd41],
- "Jscr;":[0xd835,0xdca5], "Jsercy;":0x408,
- "Jukcy;":0x404, "KHcy;":0x425,
- "KJcy;":0x40c, "Kappa;":0x39a,
- "Kcedil;":0x136, "Kcy;":0x41a,
- "Kfr;":[0xd835,0xdd0e], "Kopf;":[0xd835,0xdd42],
- "Kscr;":[0xd835,0xdca6], "LJcy;":0x409,
- "LT":0x3c, "LT;":0x3c,
- "Lacute;":0x139, "Lambda;":0x39b,
- "Lang;":0x27ea, "Laplacetrf;":0x2112,
- "Larr;":0x219e, "Lcaron;":0x13d,
- "Lcedil;":0x13b, "Lcy;":0x41b,
- "LeftAngleBracket;":0x27e8, "LeftArrow;":0x2190,
- "LeftArrowBar;":0x21e4, "LeftArrowRightArrow;":0x21c6,
- "LeftCeiling;":0x2308, "LeftDoubleBracket;":0x27e6,
- "LeftDownTeeVector;":0x2961, "LeftDownVector;":0x21c3,
- "LeftDownVectorBar;":0x2959, "LeftFloor;":0x230a,
- "LeftRightArrow;":0x2194, "LeftRightVector;":0x294e,
- "LeftTee;":0x22a3, "LeftTeeArrow;":0x21a4,
- "LeftTeeVector;":0x295a, "LeftTriangle;":0x22b2,
- "LeftTriangleBar;":0x29cf, "LeftTriangleEqual;":0x22b4,
- "LeftUpDownVector;":0x2951, "LeftUpTeeVector;":0x2960,
- "LeftUpVector;":0x21bf, "LeftUpVectorBar;":0x2958,
- "LeftVector;":0x21bc, "LeftVectorBar;":0x2952,
- "Leftarrow;":0x21d0, "Leftrightarrow;":0x21d4,
- "LessEqualGreater;":0x22da, "LessFullEqual;":0x2266,
- "LessGreater;":0x2276, "LessLess;":0x2aa1,
- "LessSlantEqual;":0x2a7d, "LessTilde;":0x2272,
- "Lfr;":[0xd835,0xdd0f], "Ll;":0x22d8,
- "Lleftarrow;":0x21da, "Lmidot;":0x13f,
- "LongLeftArrow;":0x27f5, "LongLeftRightArrow;":0x27f7,
- "LongRightArrow;":0x27f6, "Longleftarrow;":0x27f8,
- "Longleftrightarrow;":0x27fa, "Longrightarrow;":0x27f9,
- "Lopf;":[0xd835,0xdd43], "LowerLeftArrow;":0x2199,
- "LowerRightArrow;":0x2198, "Lscr;":0x2112,
- "Lsh;":0x21b0, "Lstrok;":0x141,
- "Lt;":0x226a, "Map;":0x2905,
- "Mcy;":0x41c, "MediumSpace;":0x205f,
- "Mellintrf;":0x2133, "Mfr;":[0xd835,0xdd10],
- "MinusPlus;":0x2213, "Mopf;":[0xd835,0xdd44],
- "Mscr;":0x2133, "Mu;":0x39c,
- "NJcy;":0x40a, "Nacute;":0x143,
- "Ncaron;":0x147, "Ncedil;":0x145,
- "Ncy;":0x41d, "NegativeMediumSpace;":0x200b,
- "NegativeThickSpace;":0x200b, "NegativeThinSpace;":0x200b,
- "NegativeVeryThinSpace;":0x200b, "NestedGreaterGreater;":0x226b,
- "NestedLessLess;":0x226a, "NewLine;":0xa,
- "Nfr;":[0xd835,0xdd11], "NoBreak;":0x2060,
- "NonBreakingSpace;":0xa0, "Nopf;":0x2115,
- "Not;":0x2aec, "NotCongruent;":0x2262,
- "NotCupCap;":0x226d, "NotDoubleVerticalBar;":0x2226,
- "NotElement;":0x2209, "NotEqual;":0x2260,
- "NotEqualTilde;":[0x2242,0x338], "NotExists;":0x2204,
- "NotGreater;":0x226f, "NotGreaterEqual;":0x2271,
- "NotGreaterFullEqual;":[0x2267,0x338], "NotGreaterGreater;":[0x226b,0x338],
- "NotGreaterLess;":0x2279, "NotGreaterSlantEqual;":[0x2a7e,0x338],
- "NotGreaterTilde;":0x2275, "NotHumpDownHump;":[0x224e,0x338],
- "NotHumpEqual;":[0x224f,0x338], "NotLeftTriangle;":0x22ea,
- "NotLeftTriangleBar;":[0x29cf,0x338], "NotLeftTriangleEqual;":0x22ec,
- "NotLess;":0x226e, "NotLessEqual;":0x2270,
- "NotLessGreater;":0x2278, "NotLessLess;":[0x226a,0x338],
- "NotLessSlantEqual;":[0x2a7d,0x338], "NotLessTilde;":0x2274,
- "NotNestedGreaterGreater;":[0x2aa2,0x338], "NotNestedLessLess;":[0x2aa1,0x338],
- "NotPrecedes;":0x2280, "NotPrecedesEqual;":[0x2aaf,0x338],
- "NotPrecedesSlantEqual;":0x22e0, "NotReverseElement;":0x220c,
- "NotRightTriangle;":0x22eb, "NotRightTriangleBar;":[0x29d0,0x338],
- "NotRightTriangleEqual;":0x22ed, "NotSquareSubset;":[0x228f,0x338],
- "NotSquareSubsetEqual;":0x22e2, "NotSquareSuperset;":[0x2290,0x338],
- "NotSquareSupersetEqual;":0x22e3, "NotSubset;":[0x2282,0x20d2],
- "NotSubsetEqual;":0x2288, "NotSucceeds;":0x2281,
- "NotSucceedsEqual;":[0x2ab0,0x338], "NotSucceedsSlantEqual;":0x22e1,
- "NotSucceedsTilde;":[0x227f,0x338], "NotSuperset;":[0x2283,0x20d2],
- "NotSupersetEqual;":0x2289, "NotTilde;":0x2241,
- "NotTildeEqual;":0x2244, "NotTildeFullEqual;":0x2247,
- "NotTildeTilde;":0x2249, "NotVerticalBar;":0x2224,
- "Nscr;":[0xd835,0xdca9], "Ntilde":0xd1,
- "Ntilde;":0xd1, "Nu;":0x39d,
- "OElig;":0x152, "Oacute":0xd3,
- "Oacute;":0xd3, "Ocirc":0xd4,
- "Ocirc;":0xd4, "Ocy;":0x41e,
- "Odblac;":0x150, "Ofr;":[0xd835,0xdd12],
- "Ograve":0xd2, "Ograve;":0xd2,
- "Omacr;":0x14c, "Omega;":0x3a9,
- "Omicron;":0x39f, "Oopf;":[0xd835,0xdd46],
- "OpenCurlyDoubleQuote;":0x201c, "OpenCurlyQuote;":0x2018,
- "Or;":0x2a54, "Oscr;":[0xd835,0xdcaa],
- "Oslash":0xd8, "Oslash;":0xd8,
- "Otilde":0xd5, "Otilde;":0xd5,
- "Otimes;":0x2a37, "Ouml":0xd6,
- "Ouml;":0xd6, "OverBar;":0x203e,
- "OverBrace;":0x23de, "OverBracket;":0x23b4,
- "OverParenthesis;":0x23dc, "PartialD;":0x2202,
- "Pcy;":0x41f, "Pfr;":[0xd835,0xdd13],
- "Phi;":0x3a6, "Pi;":0x3a0,
- "PlusMinus;":0xb1, "Poincareplane;":0x210c,
- "Popf;":0x2119, "Pr;":0x2abb,
- "Precedes;":0x227a, "PrecedesEqual;":0x2aaf,
- "PrecedesSlantEqual;":0x227c, "PrecedesTilde;":0x227e,
- "Prime;":0x2033, "Product;":0x220f,
- "Proportion;":0x2237, "Proportional;":0x221d,
- "Pscr;":[0xd835,0xdcab], "Psi;":0x3a8,
- "QUOT":0x22, "QUOT;":0x22,
- "Qfr;":[0xd835,0xdd14], "Qopf;":0x211a,
- "Qscr;":[0xd835,0xdcac], "RBarr;":0x2910,
- "REG":0xae, "REG;":0xae,
- "Racute;":0x154, "Rang;":0x27eb,
- "Rarr;":0x21a0, "Rarrtl;":0x2916,
- "Rcaron;":0x158, "Rcedil;":0x156,
- "Rcy;":0x420, "Re;":0x211c,
- "ReverseElement;":0x220b, "ReverseEquilibrium;":0x21cb,
- "ReverseUpEquilibrium;":0x296f, "Rfr;":0x211c,
- "Rho;":0x3a1, "RightAngleBracket;":0x27e9,
- "RightArrow;":0x2192, "RightArrowBar;":0x21e5,
- "RightArrowLeftArrow;":0x21c4, "RightCeiling;":0x2309,
- "RightDoubleBracket;":0x27e7, "RightDownTeeVector;":0x295d,
- "RightDownVector;":0x21c2, "RightDownVectorBar;":0x2955,
- "RightFloor;":0x230b, "RightTee;":0x22a2,
- "RightTeeArrow;":0x21a6, "RightTeeVector;":0x295b,
- "RightTriangle;":0x22b3, "RightTriangleBar;":0x29d0,
- "RightTriangleEqual;":0x22b5, "RightUpDownVector;":0x294f,
- "RightUpTeeVector;":0x295c, "RightUpVector;":0x21be,
- "RightUpVectorBar;":0x2954, "RightVector;":0x21c0,
- "RightVectorBar;":0x2953, "Rightarrow;":0x21d2,
- "Ropf;":0x211d, "RoundImplies;":0x2970,
- "Rrightarrow;":0x21db, "Rscr;":0x211b,
- "Rsh;":0x21b1, "RuleDelayed;":0x29f4,
- "SHCHcy;":0x429, "SHcy;":0x428,
- "SOFTcy;":0x42c, "Sacute;":0x15a,
- "Sc;":0x2abc, "Scaron;":0x160,
- "Scedil;":0x15e, "Scirc;":0x15c,
- "Scy;":0x421, "Sfr;":[0xd835,0xdd16],
- "ShortDownArrow;":0x2193, "ShortLeftArrow;":0x2190,
- "ShortRightArrow;":0x2192, "ShortUpArrow;":0x2191,
- "Sigma;":0x3a3, "SmallCircle;":0x2218,
- "Sopf;":[0xd835,0xdd4a], "Sqrt;":0x221a,
- "Square;":0x25a1, "SquareIntersection;":0x2293,
- "SquareSubset;":0x228f, "SquareSubsetEqual;":0x2291,
- "SquareSuperset;":0x2290, "SquareSupersetEqual;":0x2292,
- "SquareUnion;":0x2294, "Sscr;":[0xd835,0xdcae],
- "Star;":0x22c6, "Sub;":0x22d0,
- "Subset;":0x22d0, "SubsetEqual;":0x2286,
- "Succeeds;":0x227b, "SucceedsEqual;":0x2ab0,
- "SucceedsSlantEqual;":0x227d, "SucceedsTilde;":0x227f,
- "SuchThat;":0x220b, "Sum;":0x2211,
- "Sup;":0x22d1, "Superset;":0x2283,
- "SupersetEqual;":0x2287, "Supset;":0x22d1,
- "THORN":0xde, "THORN;":0xde,
- "TRADE;":0x2122, "TSHcy;":0x40b,
- "TScy;":0x426, "Tab;":0x9,
- "Tau;":0x3a4, "Tcaron;":0x164,
- "Tcedil;":0x162, "Tcy;":0x422,
- "Tfr;":[0xd835,0xdd17], "Therefore;":0x2234,
- "Theta;":0x398, "ThickSpace;":[0x205f,0x200a],
- "ThinSpace;":0x2009, "Tilde;":0x223c,
- "TildeEqual;":0x2243, "TildeFullEqual;":0x2245,
- "TildeTilde;":0x2248, "Topf;":[0xd835,0xdd4b],
- "TripleDot;":0x20db, "Tscr;":[0xd835,0xdcaf],
- "Tstrok;":0x166, "Uacute":0xda,
- "Uacute;":0xda, "Uarr;":0x219f,
- "Uarrocir;":0x2949, "Ubrcy;":0x40e,
- "Ubreve;":0x16c, "Ucirc":0xdb,
- "Ucirc;":0xdb, "Ucy;":0x423,
- "Udblac;":0x170, "Ufr;":[0xd835,0xdd18],
- "Ugrave":0xd9, "Ugrave;":0xd9,
- "Umacr;":0x16a, "UnderBar;":0x5f,
- "UnderBrace;":0x23df, "UnderBracket;":0x23b5,
- "UnderParenthesis;":0x23dd, "Union;":0x22c3,
- "UnionPlus;":0x228e, "Uogon;":0x172,
- "Uopf;":[0xd835,0xdd4c], "UpArrow;":0x2191,
- "UpArrowBar;":0x2912, "UpArrowDownArrow;":0x21c5,
- "UpDownArrow;":0x2195, "UpEquilibrium;":0x296e,
- "UpTee;":0x22a5, "UpTeeArrow;":0x21a5,
- "Uparrow;":0x21d1, "Updownarrow;":0x21d5,
- "UpperLeftArrow;":0x2196, "UpperRightArrow;":0x2197,
- "Upsi;":0x3d2, "Upsilon;":0x3a5,
- "Uring;":0x16e, "Uscr;":[0xd835,0xdcb0],
- "Utilde;":0x168, "Uuml":0xdc,
- "Uuml;":0xdc, "VDash;":0x22ab,
- "Vbar;":0x2aeb, "Vcy;":0x412,
- "Vdash;":0x22a9, "Vdashl;":0x2ae6,
- "Vee;":0x22c1, "Verbar;":0x2016,
- "Vert;":0x2016, "VerticalBar;":0x2223,
- "VerticalLine;":0x7c, "VerticalSeparator;":0x2758,
- "VerticalTilde;":0x2240, "VeryThinSpace;":0x200a,
- "Vfr;":[0xd835,0xdd19], "Vopf;":[0xd835,0xdd4d],
- "Vscr;":[0xd835,0xdcb1], "Vvdash;":0x22aa,
- "Wcirc;":0x174, "Wedge;":0x22c0,
- "Wfr;":[0xd835,0xdd1a], "Wopf;":[0xd835,0xdd4e],
- "Wscr;":[0xd835,0xdcb2], "Xfr;":[0xd835,0xdd1b],
- "Xi;":0x39e, "Xopf;":[0xd835,0xdd4f],
- "Xscr;":[0xd835,0xdcb3], "YAcy;":0x42f,
- "YIcy;":0x407, "YUcy;":0x42e,
- "Yacute":0xdd, "Yacute;":0xdd,
- "Ycirc;":0x176, "Ycy;":0x42b,
- "Yfr;":[0xd835,0xdd1c], "Yopf;":[0xd835,0xdd50],
- "Yscr;":[0xd835,0xdcb4], "Yuml;":0x178,
- "ZHcy;":0x416, "Zacute;":0x179,
- "Zcaron;":0x17d, "Zcy;":0x417,
- "Zdot;":0x17b, "ZeroWidthSpace;":0x200b,
- "Zeta;":0x396, "Zfr;":0x2128,
- "Zopf;":0x2124, "Zscr;":[0xd835,0xdcb5],
- "aacute":0xe1, "aacute;":0xe1,
- "abreve;":0x103, "ac;":0x223e,
- "acE;":[0x223e,0x333], "acd;":0x223f,
- "acirc":0xe2, "acirc;":0xe2,
- "acute":0xb4, "acute;":0xb4,
- "acy;":0x430, "aelig":0xe6,
- "aelig;":0xe6, "af;":0x2061,
- "afr;":[0xd835,0xdd1e], "agrave":0xe0,
- "agrave;":0xe0, "alefsym;":0x2135,
- "aleph;":0x2135, "alpha;":0x3b1,
- "amacr;":0x101, "amalg;":0x2a3f,
- "amp":0x26, "amp;":0x26,
- "and;":0x2227, "andand;":0x2a55,
- "andd;":0x2a5c, "andslope;":0x2a58,
- "andv;":0x2a5a, "ang;":0x2220,
- "ange;":0x29a4, "angle;":0x2220,
- "angmsd;":0x2221, "angmsdaa;":0x29a8,
- "angmsdab;":0x29a9, "angmsdac;":0x29aa,
- "angmsdad;":0x29ab, "angmsdae;":0x29ac,
- "angmsdaf;":0x29ad, "angmsdag;":0x29ae,
- "angmsdah;":0x29af, "angrt;":0x221f,
- "angrtvb;":0x22be, "angrtvbd;":0x299d,
- "angsph;":0x2222, "angst;":0xc5,
- "angzarr;":0x237c, "aogon;":0x105,
- "aopf;":[0xd835,0xdd52], "ap;":0x2248,
- "apE;":0x2a70, "apacir;":0x2a6f,
- "ape;":0x224a, "apid;":0x224b,
- "apos;":0x27, "approx;":0x2248,
- "approxeq;":0x224a, "aring":0xe5,
- "aring;":0xe5, "ascr;":[0xd835,0xdcb6],
- "ast;":0x2a, "asymp;":0x2248,
- "asympeq;":0x224d, "atilde":0xe3,
- "atilde;":0xe3, "auml":0xe4,
- "auml;":0xe4, "awconint;":0x2233,
- "awint;":0x2a11, "bNot;":0x2aed,
- "backcong;":0x224c, "backepsilon;":0x3f6,
- "backprime;":0x2035, "backsim;":0x223d,
- "backsimeq;":0x22cd, "barvee;":0x22bd,
- "barwed;":0x2305, "barwedge;":0x2305,
- "bbrk;":0x23b5, "bbrktbrk;":0x23b6,
- "bcong;":0x224c, "bcy;":0x431,
- "bdquo;":0x201e, "becaus;":0x2235,
- "because;":0x2235, "bemptyv;":0x29b0,
- "bepsi;":0x3f6, "bernou;":0x212c,
- "beta;":0x3b2, "beth;":0x2136,
- "between;":0x226c, "bfr;":[0xd835,0xdd1f],
- "bigcap;":0x22c2, "bigcirc;":0x25ef,
- "bigcup;":0x22c3, "bigodot;":0x2a00,
- "bigoplus;":0x2a01, "bigotimes;":0x2a02,
- "bigsqcup;":0x2a06, "bigstar;":0x2605,
- "bigtriangledown;":0x25bd, "bigtriangleup;":0x25b3,
- "biguplus;":0x2a04, "bigvee;":0x22c1,
- "bigwedge;":0x22c0, "bkarow;":0x290d,
- "blacklozenge;":0x29eb, "blacksquare;":0x25aa,
- "blacktriangle;":0x25b4, "blacktriangledown;":0x25be,
- "blacktriangleleft;":0x25c2, "blacktriangleright;":0x25b8,
- "blank;":0x2423, "blk12;":0x2592,
- "blk14;":0x2591, "blk34;":0x2593,
- "block;":0x2588, "bne;":[0x3d,0x20e5],
- "bnequiv;":[0x2261,0x20e5], "bnot;":0x2310,
- "bopf;":[0xd835,0xdd53], "bot;":0x22a5,
- "bottom;":0x22a5, "bowtie;":0x22c8,
- "boxDL;":0x2557, "boxDR;":0x2554,
- "boxDl;":0x2556, "boxDr;":0x2553,
- "boxH;":0x2550, "boxHD;":0x2566,
- "boxHU;":0x2569, "boxHd;":0x2564,
- "boxHu;":0x2567, "boxUL;":0x255d,
- "boxUR;":0x255a, "boxUl;":0x255c,
- "boxUr;":0x2559, "boxV;":0x2551,
- "boxVH;":0x256c, "boxVL;":0x2563,
- "boxVR;":0x2560, "boxVh;":0x256b,
- "boxVl;":0x2562, "boxVr;":0x255f,
- "boxbox;":0x29c9, "boxdL;":0x2555,
- "boxdR;":0x2552, "boxdl;":0x2510,
- "boxdr;":0x250c, "boxh;":0x2500,
- "boxhD;":0x2565, "boxhU;":0x2568,
- "boxhd;":0x252c, "boxhu;":0x2534,
- "boxminus;":0x229f, "boxplus;":0x229e,
- "boxtimes;":0x22a0, "boxuL;":0x255b,
- "boxuR;":0x2558, "boxul;":0x2518,
- "boxur;":0x2514, "boxv;":0x2502,
- "boxvH;":0x256a, "boxvL;":0x2561,
- "boxvR;":0x255e, "boxvh;":0x253c,
- "boxvl;":0x2524, "boxvr;":0x251c,
- "bprime;":0x2035, "breve;":0x2d8,
- "brvbar":0xa6, "brvbar;":0xa6,
- "bscr;":[0xd835,0xdcb7], "bsemi;":0x204f,
- "bsim;":0x223d, "bsime;":0x22cd,
- "bsol;":0x5c, "bsolb;":0x29c5,
- "bsolhsub;":0x27c8, "bull;":0x2022,
- "bullet;":0x2022, "bump;":0x224e,
- "bumpE;":0x2aae, "bumpe;":0x224f,
- "bumpeq;":0x224f, "cacute;":0x107,
- "cap;":0x2229, "capand;":0x2a44,
- "capbrcup;":0x2a49, "capcap;":0x2a4b,
- "capcup;":0x2a47, "capdot;":0x2a40,
- "caps;":[0x2229,0xfe00], "caret;":0x2041,
- "caron;":0x2c7, "ccaps;":0x2a4d,
- "ccaron;":0x10d, "ccedil":0xe7,
- "ccedil;":0xe7, "ccirc;":0x109,
- "ccups;":0x2a4c, "ccupssm;":0x2a50,
- "cdot;":0x10b, "cedil":0xb8,
- "cedil;":0xb8, "cemptyv;":0x29b2,
- "cent":0xa2, "cent;":0xa2,
- "centerdot;":0xb7, "cfr;":[0xd835,0xdd20],
- "chcy;":0x447, "check;":0x2713,
- "checkmark;":0x2713, "chi;":0x3c7,
- "cir;":0x25cb, "cirE;":0x29c3,
- "circ;":0x2c6, "circeq;":0x2257,
- "circlearrowleft;":0x21ba, "circlearrowright;":0x21bb,
- "circledR;":0xae, "circledS;":0x24c8,
- "circledast;":0x229b, "circledcirc;":0x229a,
- "circleddash;":0x229d, "cire;":0x2257,
- "cirfnint;":0x2a10, "cirmid;":0x2aef,
- "cirscir;":0x29c2, "clubs;":0x2663,
- "clubsuit;":0x2663, "colon;":0x3a,
- "colone;":0x2254, "coloneq;":0x2254,
- "comma;":0x2c, "commat;":0x40,
- "comp;":0x2201, "compfn;":0x2218,
- "complement;":0x2201, "complexes;":0x2102,
- "cong;":0x2245, "congdot;":0x2a6d,
- "conint;":0x222e, "copf;":[0xd835,0xdd54],
- "coprod;":0x2210, "copy":0xa9,
- "copy;":0xa9, "copysr;":0x2117,
- "crarr;":0x21b5, "cross;":0x2717,
- "cscr;":[0xd835,0xdcb8], "csub;":0x2acf,
- "csube;":0x2ad1, "csup;":0x2ad0,
- "csupe;":0x2ad2, "ctdot;":0x22ef,
- "cudarrl;":0x2938, "cudarrr;":0x2935,
- "cuepr;":0x22de, "cuesc;":0x22df,
- "cularr;":0x21b6, "cularrp;":0x293d,
- "cup;":0x222a, "cupbrcap;":0x2a48,
- "cupcap;":0x2a46, "cupcup;":0x2a4a,
- "cupdot;":0x228d, "cupor;":0x2a45,
- "cups;":[0x222a,0xfe00], "curarr;":0x21b7,
- "curarrm;":0x293c, "curlyeqprec;":0x22de,
- "curlyeqsucc;":0x22df, "curlyvee;":0x22ce,
- "curlywedge;":0x22cf, "curren":0xa4,
- "curren;":0xa4, "curvearrowleft;":0x21b6,
- "curvearrowright;":0x21b7, "cuvee;":0x22ce,
- "cuwed;":0x22cf, "cwconint;":0x2232,
- "cwint;":0x2231, "cylcty;":0x232d,
- "dArr;":0x21d3, "dHar;":0x2965,
- "dagger;":0x2020, "daleth;":0x2138,
- "darr;":0x2193, "dash;":0x2010,
- "dashv;":0x22a3, "dbkarow;":0x290f,
- "dblac;":0x2dd, "dcaron;":0x10f,
- "dcy;":0x434, "dd;":0x2146,
- "ddagger;":0x2021, "ddarr;":0x21ca,
- "ddotseq;":0x2a77, "deg":0xb0,
- "deg;":0xb0, "delta;":0x3b4,
- "demptyv;":0x29b1, "dfisht;":0x297f,
- "dfr;":[0xd835,0xdd21], "dharl;":0x21c3,
- "dharr;":0x21c2, "diam;":0x22c4,
- "diamond;":0x22c4, "diamondsuit;":0x2666,
- "diams;":0x2666, "die;":0xa8,
- "digamma;":0x3dd, "disin;":0x22f2,
- "div;":0xf7, "divide":0xf7,
- "divide;":0xf7, "divideontimes;":0x22c7,
- "divonx;":0x22c7, "djcy;":0x452,
- "dlcorn;":0x231e, "dlcrop;":0x230d,
- "dollar;":0x24, "dopf;":[0xd835,0xdd55],
- "dot;":0x2d9, "doteq;":0x2250,
- "doteqdot;":0x2251, "dotminus;":0x2238,
- "dotplus;":0x2214, "dotsquare;":0x22a1,
- "doublebarwedge;":0x2306, "downarrow;":0x2193,
- "downdownarrows;":0x21ca, "downharpoonleft;":0x21c3,
- "downharpoonright;":0x21c2, "drbkarow;":0x2910,
- "drcorn;":0x231f, "drcrop;":0x230c,
- "dscr;":[0xd835,0xdcb9], "dscy;":0x455,
- "dsol;":0x29f6, "dstrok;":0x111,
- "dtdot;":0x22f1, "dtri;":0x25bf,
- "dtrif;":0x25be, "duarr;":0x21f5,
- "duhar;":0x296f, "dwangle;":0x29a6,
- "dzcy;":0x45f, "dzigrarr;":0x27ff,
- "eDDot;":0x2a77, "eDot;":0x2251,
- "eacute":0xe9, "eacute;":0xe9,
- "easter;":0x2a6e, "ecaron;":0x11b,
- "ecir;":0x2256, "ecirc":0xea,
- "ecirc;":0xea, "ecolon;":0x2255,
- "ecy;":0x44d, "edot;":0x117,
- "ee;":0x2147, "efDot;":0x2252,
- "efr;":[0xd835,0xdd22], "eg;":0x2a9a,
- "egrave":0xe8, "egrave;":0xe8,
- "egs;":0x2a96, "egsdot;":0x2a98,
- "el;":0x2a99, "elinters;":0x23e7,
- "ell;":0x2113, "els;":0x2a95,
- "elsdot;":0x2a97, "emacr;":0x113,
- "empty;":0x2205, "emptyset;":0x2205,
- "emptyv;":0x2205, "emsp13;":0x2004,
- "emsp14;":0x2005, "emsp;":0x2003,
- "eng;":0x14b, "ensp;":0x2002,
- "eogon;":0x119, "eopf;":[0xd835,0xdd56],
- "epar;":0x22d5, "eparsl;":0x29e3,
- "eplus;":0x2a71, "epsi;":0x3b5,
- "epsilon;":0x3b5, "epsiv;":0x3f5,
- "eqcirc;":0x2256, "eqcolon;":0x2255,
- "eqsim;":0x2242, "eqslantgtr;":0x2a96,
- "eqslantless;":0x2a95, "equals;":0x3d,
- "equest;":0x225f, "equiv;":0x2261,
- "equivDD;":0x2a78, "eqvparsl;":0x29e5,
- "erDot;":0x2253, "erarr;":0x2971,
- "escr;":0x212f, "esdot;":0x2250,
- "esim;":0x2242, "eta;":0x3b7,
- "eth":0xf0, "eth;":0xf0,
- "euml":0xeb, "euml;":0xeb,
- "euro;":0x20ac, "excl;":0x21,
- "exist;":0x2203, "expectation;":0x2130,
- "exponentiale;":0x2147, "fallingdotseq;":0x2252,
- "fcy;":0x444, "female;":0x2640,
- "ffilig;":0xfb03, "fflig;":0xfb00,
- "ffllig;":0xfb04, "ffr;":[0xd835,0xdd23],
- "filig;":0xfb01, "fjlig;":[0x66,0x6a],
- "flat;":0x266d, "fllig;":0xfb02,
- "fltns;":0x25b1, "fnof;":0x192,
- "fopf;":[0xd835,0xdd57], "forall;":0x2200,
- "fork;":0x22d4, "forkv;":0x2ad9,
- "fpartint;":0x2a0d, "frac12":0xbd,
- "frac12;":0xbd, "frac13;":0x2153,
- "frac14":0xbc, "frac14;":0xbc,
- "frac15;":0x2155, "frac16;":0x2159,
- "frac18;":0x215b, "frac23;":0x2154,
- "frac25;":0x2156, "frac34":0xbe,
- "frac34;":0xbe, "frac35;":0x2157,
- "frac38;":0x215c, "frac45;":0x2158,
- "frac56;":0x215a, "frac58;":0x215d,
- "frac78;":0x215e, "frasl;":0x2044,
- "frown;":0x2322, "fscr;":[0xd835,0xdcbb],
- "gE;":0x2267, "gEl;":0x2a8c,
- "gacute;":0x1f5, "gamma;":0x3b3,
- "gammad;":0x3dd, "gap;":0x2a86,
- "gbreve;":0x11f, "gcirc;":0x11d,
- "gcy;":0x433, "gdot;":0x121,
- "ge;":0x2265, "gel;":0x22db,
- "geq;":0x2265, "geqq;":0x2267,
- "geqslant;":0x2a7e, "ges;":0x2a7e,
- "gescc;":0x2aa9, "gesdot;":0x2a80,
- "gesdoto;":0x2a82, "gesdotol;":0x2a84,
- "gesl;":[0x22db,0xfe00], "gesles;":0x2a94,
- "gfr;":[0xd835,0xdd24], "gg;":0x226b,
- "ggg;":0x22d9, "gimel;":0x2137,
- "gjcy;":0x453, "gl;":0x2277,
- "glE;":0x2a92, "gla;":0x2aa5,
- "glj;":0x2aa4, "gnE;":0x2269,
- "gnap;":0x2a8a, "gnapprox;":0x2a8a,
- "gne;":0x2a88, "gneq;":0x2a88,
- "gneqq;":0x2269, "gnsim;":0x22e7,
- "gopf;":[0xd835,0xdd58], "grave;":0x60,
- "gscr;":0x210a, "gsim;":0x2273,
- "gsime;":0x2a8e, "gsiml;":0x2a90,
- "gt":0x3e, "gt;":0x3e,
- "gtcc;":0x2aa7, "gtcir;":0x2a7a,
- "gtdot;":0x22d7, "gtlPar;":0x2995,
- "gtquest;":0x2a7c, "gtrapprox;":0x2a86,
- "gtrarr;":0x2978, "gtrdot;":0x22d7,
- "gtreqless;":0x22db, "gtreqqless;":0x2a8c,
- "gtrless;":0x2277, "gtrsim;":0x2273,
- "gvertneqq;":[0x2269,0xfe00], "gvnE;":[0x2269,0xfe00],
- "hArr;":0x21d4, "hairsp;":0x200a,
- "half;":0xbd, "hamilt;":0x210b,
- "hardcy;":0x44a, "harr;":0x2194,
- "harrcir;":0x2948, "harrw;":0x21ad,
- "hbar;":0x210f, "hcirc;":0x125,
- "hearts;":0x2665, "heartsuit;":0x2665,
- "hellip;":0x2026, "hercon;":0x22b9,
- "hfr;":[0xd835,0xdd25], "hksearow;":0x2925,
- "hkswarow;":0x2926, "hoarr;":0x21ff,
- "homtht;":0x223b, "hookleftarrow;":0x21a9,
- "hookrightarrow;":0x21aa, "hopf;":[0xd835,0xdd59],
- "horbar;":0x2015, "hscr;":[0xd835,0xdcbd],
- "hslash;":0x210f, "hstrok;":0x127,
- "hybull;":0x2043, "hyphen;":0x2010,
- "iacute":0xed, "iacute;":0xed,
- "ic;":0x2063, "icirc":0xee,
- "icirc;":0xee, "icy;":0x438,
- "iecy;":0x435, "iexcl":0xa1,
- "iexcl;":0xa1, "iff;":0x21d4,
- "ifr;":[0xd835,0xdd26], "igrave":0xec,
- "igrave;":0xec, "ii;":0x2148,
- "iiiint;":0x2a0c, "iiint;":0x222d,
- "iinfin;":0x29dc, "iiota;":0x2129,
- "ijlig;":0x133, "imacr;":0x12b,
- "image;":0x2111, "imagline;":0x2110,
- "imagpart;":0x2111, "imath;":0x131,
- "imof;":0x22b7, "imped;":0x1b5,
- "in;":0x2208, "incare;":0x2105,
- "infin;":0x221e, "infintie;":0x29dd,
- "inodot;":0x131, "int;":0x222b,
- "intcal;":0x22ba, "integers;":0x2124,
- "intercal;":0x22ba, "intlarhk;":0x2a17,
- "intprod;":0x2a3c, "iocy;":0x451,
- "iogon;":0x12f, "iopf;":[0xd835,0xdd5a],
- "iota;":0x3b9, "iprod;":0x2a3c,
- "iquest":0xbf, "iquest;":0xbf,
- "iscr;":[0xd835,0xdcbe], "isin;":0x2208,
- "isinE;":0x22f9, "isindot;":0x22f5,
- "isins;":0x22f4, "isinsv;":0x22f3,
- "isinv;":0x2208, "it;":0x2062,
- "itilde;":0x129, "iukcy;":0x456,
- "iuml":0xef, "iuml;":0xef,
- "jcirc;":0x135, "jcy;":0x439,
- "jfr;":[0xd835,0xdd27], "jmath;":0x237,
- "jopf;":[0xd835,0xdd5b], "jscr;":[0xd835,0xdcbf],
- "jsercy;":0x458, "jukcy;":0x454,
- "kappa;":0x3ba, "kappav;":0x3f0,
- "kcedil;":0x137, "kcy;":0x43a,
- "kfr;":[0xd835,0xdd28], "kgreen;":0x138,
- "khcy;":0x445, "kjcy;":0x45c,
- "kopf;":[0xd835,0xdd5c], "kscr;":[0xd835,0xdcc0],
- "lAarr;":0x21da, "lArr;":0x21d0,
- "lAtail;":0x291b, "lBarr;":0x290e,
- "lE;":0x2266, "lEg;":0x2a8b,
- "lHar;":0x2962, "lacute;":0x13a,
- "laemptyv;":0x29b4, "lagran;":0x2112,
- "lambda;":0x3bb, "lang;":0x27e8,
- "langd;":0x2991, "langle;":0x27e8,
- "lap;":0x2a85, "laquo":0xab,
- "laquo;":0xab, "larr;":0x2190,
- "larrb;":0x21e4, "larrbfs;":0x291f,
- "larrfs;":0x291d, "larrhk;":0x21a9,
- "larrlp;":0x21ab, "larrpl;":0x2939,
- "larrsim;":0x2973, "larrtl;":0x21a2,
- "lat;":0x2aab, "latail;":0x2919,
- "late;":0x2aad, "lates;":[0x2aad,0xfe00],
- "lbarr;":0x290c, "lbbrk;":0x2772,
- "lbrace;":0x7b, "lbrack;":0x5b,
- "lbrke;":0x298b, "lbrksld;":0x298f,
- "lbrkslu;":0x298d, "lcaron;":0x13e,
- "lcedil;":0x13c, "lceil;":0x2308,
- "lcub;":0x7b, "lcy;":0x43b,
- "ldca;":0x2936, "ldquo;":0x201c,
- "ldquor;":0x201e, "ldrdhar;":0x2967,
- "ldrushar;":0x294b, "ldsh;":0x21b2,
- "le;":0x2264, "leftarrow;":0x2190,
- "leftarrowtail;":0x21a2, "leftharpoondown;":0x21bd,
- "leftharpoonup;":0x21bc, "leftleftarrows;":0x21c7,
- "leftrightarrow;":0x2194, "leftrightarrows;":0x21c6,
- "leftrightharpoons;":0x21cb, "leftrightsquigarrow;":0x21ad,
- "leftthreetimes;":0x22cb, "leg;":0x22da,
- "leq;":0x2264, "leqq;":0x2266,
- "leqslant;":0x2a7d, "les;":0x2a7d,
- "lescc;":0x2aa8, "lesdot;":0x2a7f,
- "lesdoto;":0x2a81, "lesdotor;":0x2a83,
- "lesg;":[0x22da,0xfe00], "lesges;":0x2a93,
- "lessapprox;":0x2a85, "lessdot;":0x22d6,
- "lesseqgtr;":0x22da, "lesseqqgtr;":0x2a8b,
- "lessgtr;":0x2276, "lesssim;":0x2272,
- "lfisht;":0x297c, "lfloor;":0x230a,
- "lfr;":[0xd835,0xdd29], "lg;":0x2276,
- "lgE;":0x2a91, "lhard;":0x21bd,
- "lharu;":0x21bc, "lharul;":0x296a,
- "lhblk;":0x2584, "ljcy;":0x459,
- "ll;":0x226a, "llarr;":0x21c7,
- "llcorner;":0x231e, "llhard;":0x296b,
- "lltri;":0x25fa, "lmidot;":0x140,
- "lmoust;":0x23b0, "lmoustache;":0x23b0,
- "lnE;":0x2268, "lnap;":0x2a89,
- "lnapprox;":0x2a89, "lne;":0x2a87,
- "lneq;":0x2a87, "lneqq;":0x2268,
- "lnsim;":0x22e6, "loang;":0x27ec,
- "loarr;":0x21fd, "lobrk;":0x27e6,
- "longleftarrow;":0x27f5, "longleftrightarrow;":0x27f7,
- "longmapsto;":0x27fc, "longrightarrow;":0x27f6,
- "looparrowleft;":0x21ab, "looparrowright;":0x21ac,
- "lopar;":0x2985, "lopf;":[0xd835,0xdd5d],
- "loplus;":0x2a2d, "lotimes;":0x2a34,
- "lowast;":0x2217, "lowbar;":0x5f,
- "loz;":0x25ca, "lozenge;":0x25ca,
- "lozf;":0x29eb, "lpar;":0x28,
- "lparlt;":0x2993, "lrarr;":0x21c6,
- "lrcorner;":0x231f, "lrhar;":0x21cb,
- "lrhard;":0x296d, "lrm;":0x200e,
- "lrtri;":0x22bf, "lsaquo;":0x2039,
- "lscr;":[0xd835,0xdcc1], "lsh;":0x21b0,
- "lsim;":0x2272, "lsime;":0x2a8d,
- "lsimg;":0x2a8f, "lsqb;":0x5b,
- "lsquo;":0x2018, "lsquor;":0x201a,
- "lstrok;":0x142, "lt":0x3c,
- "lt;":0x3c, "ltcc;":0x2aa6,
- "ltcir;":0x2a79, "ltdot;":0x22d6,
- "lthree;":0x22cb, "ltimes;":0x22c9,
- "ltlarr;":0x2976, "ltquest;":0x2a7b,
- "ltrPar;":0x2996, "ltri;":0x25c3,
- "ltrie;":0x22b4, "ltrif;":0x25c2,
- "lurdshar;":0x294a, "luruhar;":0x2966,
- "lvertneqq;":[0x2268,0xfe00], "lvnE;":[0x2268,0xfe00],
- "mDDot;":0x223a, "macr":0xaf,
- "macr;":0xaf, "male;":0x2642,
- "malt;":0x2720, "maltese;":0x2720,
- "map;":0x21a6, "mapsto;":0x21a6,
- "mapstodown;":0x21a7, "mapstoleft;":0x21a4,
- "mapstoup;":0x21a5, "marker;":0x25ae,
- "mcomma;":0x2a29, "mcy;":0x43c,
- "mdash;":0x2014, "measuredangle;":0x2221,
- "mfr;":[0xd835,0xdd2a], "mho;":0x2127,
- "micro":0xb5, "micro;":0xb5,
- "mid;":0x2223, "midast;":0x2a,
- "midcir;":0x2af0, "middot":0xb7,
- "middot;":0xb7, "minus;":0x2212,
- "minusb;":0x229f, "minusd;":0x2238,
- "minusdu;":0x2a2a, "mlcp;":0x2adb,
- "mldr;":0x2026, "mnplus;":0x2213,
- "models;":0x22a7, "mopf;":[0xd835,0xdd5e],
- "mp;":0x2213, "mscr;":[0xd835,0xdcc2],
- "mstpos;":0x223e, "mu;":0x3bc,
- "multimap;":0x22b8, "mumap;":0x22b8,
- "nGg;":[0x22d9,0x338], "nGt;":[0x226b,0x20d2],
- "nGtv;":[0x226b,0x338], "nLeftarrow;":0x21cd,
- "nLeftrightarrow;":0x21ce, "nLl;":[0x22d8,0x338],
- "nLt;":[0x226a,0x20d2], "nLtv;":[0x226a,0x338],
- "nRightarrow;":0x21cf, "nVDash;":0x22af,
- "nVdash;":0x22ae, "nabla;":0x2207,
- "nacute;":0x144, "nang;":[0x2220,0x20d2],
- "nap;":0x2249, "napE;":[0x2a70,0x338],
- "napid;":[0x224b,0x338], "napos;":0x149,
- "napprox;":0x2249, "natur;":0x266e,
- "natural;":0x266e, "naturals;":0x2115,
- "nbsp":0xa0, "nbsp;":0xa0,
- "nbump;":[0x224e,0x338], "nbumpe;":[0x224f,0x338],
- "ncap;":0x2a43, "ncaron;":0x148,
- "ncedil;":0x146, "ncong;":0x2247,
- "ncongdot;":[0x2a6d,0x338], "ncup;":0x2a42,
- "ncy;":0x43d, "ndash;":0x2013,
- "ne;":0x2260, "neArr;":0x21d7,
- "nearhk;":0x2924, "nearr;":0x2197,
- "nearrow;":0x2197, "nedot;":[0x2250,0x338],
- "nequiv;":0x2262, "nesear;":0x2928,
- "nesim;":[0x2242,0x338], "nexist;":0x2204,
- "nexists;":0x2204, "nfr;":[0xd835,0xdd2b],
- "ngE;":[0x2267,0x338], "nge;":0x2271,
- "ngeq;":0x2271, "ngeqq;":[0x2267,0x338],
- "ngeqslant;":[0x2a7e,0x338], "nges;":[0x2a7e,0x338],
- "ngsim;":0x2275, "ngt;":0x226f,
- "ngtr;":0x226f, "nhArr;":0x21ce,
- "nharr;":0x21ae, "nhpar;":0x2af2,
- "ni;":0x220b, "nis;":0x22fc,
- "nisd;":0x22fa, "niv;":0x220b,
- "njcy;":0x45a, "nlArr;":0x21cd,
- "nlE;":[0x2266,0x338], "nlarr;":0x219a,
- "nldr;":0x2025, "nle;":0x2270,
- "nleftarrow;":0x219a, "nleftrightarrow;":0x21ae,
- "nleq;":0x2270, "nleqq;":[0x2266,0x338],
- "nleqslant;":[0x2a7d,0x338], "nles;":[0x2a7d,0x338],
- "nless;":0x226e, "nlsim;":0x2274,
- "nlt;":0x226e, "nltri;":0x22ea,
- "nltrie;":0x22ec, "nmid;":0x2224,
- "nopf;":[0xd835,0xdd5f], "not":0xac,
- "not;":0xac, "notin;":0x2209,
- "notinE;":[0x22f9,0x338], "notindot;":[0x22f5,0x338],
- "notinva;":0x2209, "notinvb;":0x22f7,
- "notinvc;":0x22f6, "notni;":0x220c,
- "notniva;":0x220c, "notnivb;":0x22fe,
- "notnivc;":0x22fd, "npar;":0x2226,
- "nparallel;":0x2226, "nparsl;":[0x2afd,0x20e5],
- "npart;":[0x2202,0x338], "npolint;":0x2a14,
- "npr;":0x2280, "nprcue;":0x22e0,
- "npre;":[0x2aaf,0x338], "nprec;":0x2280,
- "npreceq;":[0x2aaf,0x338], "nrArr;":0x21cf,
- "nrarr;":0x219b, "nrarrc;":[0x2933,0x338],
- "nrarrw;":[0x219d,0x338], "nrightarrow;":0x219b,
- "nrtri;":0x22eb, "nrtrie;":0x22ed,
- "nsc;":0x2281, "nsccue;":0x22e1,
- "nsce;":[0x2ab0,0x338], "nscr;":[0xd835,0xdcc3],
- "nshortmid;":0x2224, "nshortparallel;":0x2226,
- "nsim;":0x2241, "nsime;":0x2244,
- "nsimeq;":0x2244, "nsmid;":0x2224,
- "nspar;":0x2226, "nsqsube;":0x22e2,
- "nsqsupe;":0x22e3, "nsub;":0x2284,
- "nsubE;":[0x2ac5,0x338], "nsube;":0x2288,
- "nsubset;":[0x2282,0x20d2], "nsubseteq;":0x2288,
- "nsubseteqq;":[0x2ac5,0x338], "nsucc;":0x2281,
- "nsucceq;":[0x2ab0,0x338], "nsup;":0x2285,
- "nsupE;":[0x2ac6,0x338], "nsupe;":0x2289,
- "nsupset;":[0x2283,0x20d2], "nsupseteq;":0x2289,
- "nsupseteqq;":[0x2ac6,0x338], "ntgl;":0x2279,
- "ntilde":0xf1, "ntilde;":0xf1,
- "ntlg;":0x2278, "ntriangleleft;":0x22ea,
- "ntrianglelefteq;":0x22ec, "ntriangleright;":0x22eb,
- "ntrianglerighteq;":0x22ed, "nu;":0x3bd,
- "num;":0x23, "numero;":0x2116,
- "numsp;":0x2007, "nvDash;":0x22ad,
- "nvHarr;":0x2904, "nvap;":[0x224d,0x20d2],
- "nvdash;":0x22ac, "nvge;":[0x2265,0x20d2],
- "nvgt;":[0x3e,0x20d2], "nvinfin;":0x29de,
- "nvlArr;":0x2902, "nvle;":[0x2264,0x20d2],
- "nvlt;":[0x3c,0x20d2], "nvltrie;":[0x22b4,0x20d2],
- "nvrArr;":0x2903, "nvrtrie;":[0x22b5,0x20d2],
- "nvsim;":[0x223c,0x20d2], "nwArr;":0x21d6,
- "nwarhk;":0x2923, "nwarr;":0x2196,
- "nwarrow;":0x2196, "nwnear;":0x2927,
- "oS;":0x24c8, "oacute":0xf3,
- "oacute;":0xf3, "oast;":0x229b,
- "ocir;":0x229a, "ocirc":0xf4,
- "ocirc;":0xf4, "ocy;":0x43e,
- "odash;":0x229d, "odblac;":0x151,
- "odiv;":0x2a38, "odot;":0x2299,
- "odsold;":0x29bc, "oelig;":0x153,
- "ofcir;":0x29bf, "ofr;":[0xd835,0xdd2c],
- "ogon;":0x2db, "ograve":0xf2,
- "ograve;":0xf2, "ogt;":0x29c1,
- "ohbar;":0x29b5, "ohm;":0x3a9,
- "oint;":0x222e, "olarr;":0x21ba,
- "olcir;":0x29be, "olcross;":0x29bb,
- "oline;":0x203e, "olt;":0x29c0,
- "omacr;":0x14d, "omega;":0x3c9,
- "omicron;":0x3bf, "omid;":0x29b6,
- "ominus;":0x2296, "oopf;":[0xd835,0xdd60],
- "opar;":0x29b7, "operp;":0x29b9,
- "oplus;":0x2295, "or;":0x2228,
- "orarr;":0x21bb, "ord;":0x2a5d,
- "order;":0x2134, "orderof;":0x2134,
- "ordf":0xaa, "ordf;":0xaa,
- "ordm":0xba, "ordm;":0xba,
- "origof;":0x22b6, "oror;":0x2a56,
- "orslope;":0x2a57, "orv;":0x2a5b,
- "oscr;":0x2134, "oslash":0xf8,
- "oslash;":0xf8, "osol;":0x2298,
- "otilde":0xf5, "otilde;":0xf5,
- "otimes;":0x2297, "otimesas;":0x2a36,
- "ouml":0xf6, "ouml;":0xf6,
- "ovbar;":0x233d, "par;":0x2225,
- "para":0xb6, "para;":0xb6,
- "parallel;":0x2225, "parsim;":0x2af3,
- "parsl;":0x2afd, "part;":0x2202,
- "pcy;":0x43f, "percnt;":0x25,
- "period;":0x2e, "permil;":0x2030,
- "perp;":0x22a5, "pertenk;":0x2031,
- "pfr;":[0xd835,0xdd2d], "phi;":0x3c6,
- "phiv;":0x3d5, "phmmat;":0x2133,
- "phone;":0x260e, "pi;":0x3c0,
- "pitchfork;":0x22d4, "piv;":0x3d6,
- "planck;":0x210f, "planckh;":0x210e,
- "plankv;":0x210f, "plus;":0x2b,
- "plusacir;":0x2a23, "plusb;":0x229e,
- "pluscir;":0x2a22, "plusdo;":0x2214,
- "plusdu;":0x2a25, "pluse;":0x2a72,
- "plusmn":0xb1, "plusmn;":0xb1,
- "plussim;":0x2a26, "plustwo;":0x2a27,
- "pm;":0xb1, "pointint;":0x2a15,
- "popf;":[0xd835,0xdd61], "pound":0xa3,
- "pound;":0xa3, "pr;":0x227a,
- "prE;":0x2ab3, "prap;":0x2ab7,
- "prcue;":0x227c, "pre;":0x2aaf,
- "prec;":0x227a, "precapprox;":0x2ab7,
- "preccurlyeq;":0x227c, "preceq;":0x2aaf,
- "precnapprox;":0x2ab9, "precneqq;":0x2ab5,
- "precnsim;":0x22e8, "precsim;":0x227e,
- "prime;":0x2032, "primes;":0x2119,
- "prnE;":0x2ab5, "prnap;":0x2ab9,
- "prnsim;":0x22e8, "prod;":0x220f,
- "profalar;":0x232e, "profline;":0x2312,
- "profsurf;":0x2313, "prop;":0x221d,
- "propto;":0x221d, "prsim;":0x227e,
- "prurel;":0x22b0, "pscr;":[0xd835,0xdcc5],
- "psi;":0x3c8, "puncsp;":0x2008,
- "qfr;":[0xd835,0xdd2e], "qint;":0x2a0c,
- "qopf;":[0xd835,0xdd62], "qprime;":0x2057,
- "qscr;":[0xd835,0xdcc6], "quaternions;":0x210d,
- "quatint;":0x2a16, "quest;":0x3f,
- "questeq;":0x225f, "quot":0x22,
- "quot;":0x22, "rAarr;":0x21db,
- "rArr;":0x21d2, "rAtail;":0x291c,
- "rBarr;":0x290f, "rHar;":0x2964,
- "race;":[0x223d,0x331], "racute;":0x155,
- "radic;":0x221a, "raemptyv;":0x29b3,
- "rang;":0x27e9, "rangd;":0x2992,
- "range;":0x29a5, "rangle;":0x27e9,
- "raquo":0xbb, "raquo;":0xbb,
- "rarr;":0x2192, "rarrap;":0x2975,
- "rarrb;":0x21e5, "rarrbfs;":0x2920,
- "rarrc;":0x2933, "rarrfs;":0x291e,
- "rarrhk;":0x21aa, "rarrlp;":0x21ac,
- "rarrpl;":0x2945, "rarrsim;":0x2974,
- "rarrtl;":0x21a3, "rarrw;":0x219d,
- "ratail;":0x291a, "ratio;":0x2236,
- "rationals;":0x211a, "rbarr;":0x290d,
- "rbbrk;":0x2773, "rbrace;":0x7d,
- "rbrack;":0x5d, "rbrke;":0x298c,
- "rbrksld;":0x298e, "rbrkslu;":0x2990,
- "rcaron;":0x159, "rcedil;":0x157,
- "rceil;":0x2309, "rcub;":0x7d,
- "rcy;":0x440, "rdca;":0x2937,
- "rdldhar;":0x2969, "rdquo;":0x201d,
- "rdquor;":0x201d, "rdsh;":0x21b3,
- "real;":0x211c, "realine;":0x211b,
- "realpart;":0x211c, "reals;":0x211d,
- "rect;":0x25ad, "reg":0xae,
- "reg;":0xae, "rfisht;":0x297d,
- "rfloor;":0x230b, "rfr;":[0xd835,0xdd2f],
- "rhard;":0x21c1, "rharu;":0x21c0,
- "rharul;":0x296c, "rho;":0x3c1,
- "rhov;":0x3f1, "rightarrow;":0x2192,
- "rightarrowtail;":0x21a3, "rightharpoondown;":0x21c1,
- "rightharpoonup;":0x21c0, "rightleftarrows;":0x21c4,
- "rightleftharpoons;":0x21cc, "rightrightarrows;":0x21c9,
- "rightsquigarrow;":0x219d, "rightthreetimes;":0x22cc,
- "ring;":0x2da, "risingdotseq;":0x2253,
- "rlarr;":0x21c4, "rlhar;":0x21cc,
- "rlm;":0x200f, "rmoust;":0x23b1,
- "rmoustache;":0x23b1, "rnmid;":0x2aee,
- "roang;":0x27ed, "roarr;":0x21fe,
- "robrk;":0x27e7, "ropar;":0x2986,
- "ropf;":[0xd835,0xdd63], "roplus;":0x2a2e,
- "rotimes;":0x2a35, "rpar;":0x29,
- "rpargt;":0x2994, "rppolint;":0x2a12,
- "rrarr;":0x21c9, "rsaquo;":0x203a,
- "rscr;":[0xd835,0xdcc7], "rsh;":0x21b1,
- "rsqb;":0x5d, "rsquo;":0x2019,
- "rsquor;":0x2019, "rthree;":0x22cc,
- "rtimes;":0x22ca, "rtri;":0x25b9,
- "rtrie;":0x22b5, "rtrif;":0x25b8,
- "rtriltri;":0x29ce, "ruluhar;":0x2968,
- "rx;":0x211e, "sacute;":0x15b,
- "sbquo;":0x201a, "sc;":0x227b,
- "scE;":0x2ab4, "scap;":0x2ab8,
- "scaron;":0x161, "sccue;":0x227d,
- "sce;":0x2ab0, "scedil;":0x15f,
- "scirc;":0x15d, "scnE;":0x2ab6,
- "scnap;":0x2aba, "scnsim;":0x22e9,
- "scpolint;":0x2a13, "scsim;":0x227f,
- "scy;":0x441, "sdot;":0x22c5,
- "sdotb;":0x22a1, "sdote;":0x2a66,
- "seArr;":0x21d8, "searhk;":0x2925,
- "searr;":0x2198, "searrow;":0x2198,
- "sect":0xa7, "sect;":0xa7,
- "semi;":0x3b, "seswar;":0x2929,
- "setminus;":0x2216, "setmn;":0x2216,
- "sext;":0x2736, "sfr;":[0xd835,0xdd30],
- "sfrown;":0x2322, "sharp;":0x266f,
- "shchcy;":0x449, "shcy;":0x448,
- "shortmid;":0x2223, "shortparallel;":0x2225,
- "shy":0xad, "shy;":0xad,
- "sigma;":0x3c3, "sigmaf;":0x3c2,
- "sigmav;":0x3c2, "sim;":0x223c,
- "simdot;":0x2a6a, "sime;":0x2243,
- "simeq;":0x2243, "simg;":0x2a9e,
- "simgE;":0x2aa0, "siml;":0x2a9d,
- "simlE;":0x2a9f, "simne;":0x2246,
- "simplus;":0x2a24, "simrarr;":0x2972,
- "slarr;":0x2190, "smallsetminus;":0x2216,
- "smashp;":0x2a33, "smeparsl;":0x29e4,
- "smid;":0x2223, "smile;":0x2323,
- "smt;":0x2aaa, "smte;":0x2aac,
- "smtes;":[0x2aac,0xfe00], "softcy;":0x44c,
- "sol;":0x2f, "solb;":0x29c4,
- "solbar;":0x233f, "sopf;":[0xd835,0xdd64],
- "spades;":0x2660, "spadesuit;":0x2660,
- "spar;":0x2225, "sqcap;":0x2293,
- "sqcaps;":[0x2293,0xfe00], "sqcup;":0x2294,
- "sqcups;":[0x2294,0xfe00], "sqsub;":0x228f,
- "sqsube;":0x2291, "sqsubset;":0x228f,
- "sqsubseteq;":0x2291, "sqsup;":0x2290,
- "sqsupe;":0x2292, "sqsupset;":0x2290,
- "sqsupseteq;":0x2292, "squ;":0x25a1,
- "square;":0x25a1, "squarf;":0x25aa,
- "squf;":0x25aa, "srarr;":0x2192,
- "sscr;":[0xd835,0xdcc8], "ssetmn;":0x2216,
- "ssmile;":0x2323, "sstarf;":0x22c6,
- "star;":0x2606, "starf;":0x2605,
- "straightepsilon;":0x3f5, "straightphi;":0x3d5,
- "strns;":0xaf, "sub;":0x2282,
- "subE;":0x2ac5, "subdot;":0x2abd,
- "sube;":0x2286, "subedot;":0x2ac3,
- "submult;":0x2ac1, "subnE;":0x2acb,
- "subne;":0x228a, "subplus;":0x2abf,
- "subrarr;":0x2979, "subset;":0x2282,
- "subseteq;":0x2286, "subseteqq;":0x2ac5,
- "subsetneq;":0x228a, "subsetneqq;":0x2acb,
- "subsim;":0x2ac7, "subsub;":0x2ad5,
- "subsup;":0x2ad3, "succ;":0x227b,
- "succapprox;":0x2ab8, "succcurlyeq;":0x227d,
- "succeq;":0x2ab0, "succnapprox;":0x2aba,
- "succneqq;":0x2ab6, "succnsim;":0x22e9,
- "succsim;":0x227f, "sum;":0x2211,
- "sung;":0x266a, "sup1":0xb9,
- "sup1;":0xb9, "sup2":0xb2,
- "sup2;":0xb2, "sup3":0xb3,
- "sup3;":0xb3, "sup;":0x2283,
- "supE;":0x2ac6, "supdot;":0x2abe,
- "supdsub;":0x2ad8, "supe;":0x2287,
- "supedot;":0x2ac4, "suphsol;":0x27c9,
- "suphsub;":0x2ad7, "suplarr;":0x297b,
- "supmult;":0x2ac2, "supnE;":0x2acc,
- "supne;":0x228b, "supplus;":0x2ac0,
- "supset;":0x2283, "supseteq;":0x2287,
- "supseteqq;":0x2ac6, "supsetneq;":0x228b,
- "supsetneqq;":0x2acc, "supsim;":0x2ac8,
- "supsub;":0x2ad4, "supsup;":0x2ad6,
- "swArr;":0x21d9, "swarhk;":0x2926,
- "swarr;":0x2199, "swarrow;":0x2199,
- "swnwar;":0x292a, "szlig":0xdf,
- "szlig;":0xdf, "target;":0x2316,
- "tau;":0x3c4, "tbrk;":0x23b4,
- "tcaron;":0x165, "tcedil;":0x163,
- "tcy;":0x442, "tdot;":0x20db,
- "telrec;":0x2315, "tfr;":[0xd835,0xdd31],
- "there4;":0x2234, "therefore;":0x2234,
- "theta;":0x3b8, "thetasym;":0x3d1,
- "thetav;":0x3d1, "thickapprox;":0x2248,
- "thicksim;":0x223c, "thinsp;":0x2009,
- "thkap;":0x2248, "thksim;":0x223c,
- "thorn":0xfe, "thorn;":0xfe,
- "tilde;":0x2dc, "times":0xd7,
- "times;":0xd7, "timesb;":0x22a0,
- "timesbar;":0x2a31, "timesd;":0x2a30,
- "tint;":0x222d, "toea;":0x2928,
- "top;":0x22a4, "topbot;":0x2336,
- "topcir;":0x2af1, "topf;":[0xd835,0xdd65],
- "topfork;":0x2ada, "tosa;":0x2929,
- "tprime;":0x2034, "trade;":0x2122,
- "triangle;":0x25b5, "triangledown;":0x25bf,
- "triangleleft;":0x25c3, "trianglelefteq;":0x22b4,
- "triangleq;":0x225c, "triangleright;":0x25b9,
- "trianglerighteq;":0x22b5, "tridot;":0x25ec,
- "trie;":0x225c, "triminus;":0x2a3a,
- "triplus;":0x2a39, "trisb;":0x29cd,
- "tritime;":0x2a3b, "trpezium;":0x23e2,
- "tscr;":[0xd835,0xdcc9], "tscy;":0x446,
- "tshcy;":0x45b, "tstrok;":0x167,
- "twixt;":0x226c, "twoheadleftarrow;":0x219e,
- "twoheadrightarrow;":0x21a0, "uArr;":0x21d1,
- "uHar;":0x2963, "uacute":0xfa,
- "uacute;":0xfa, "uarr;":0x2191,
- "ubrcy;":0x45e, "ubreve;":0x16d,
- "ucirc":0xfb, "ucirc;":0xfb,
- "ucy;":0x443, "udarr;":0x21c5,
- "udblac;":0x171, "udhar;":0x296e,
- "ufisht;":0x297e, "ufr;":[0xd835,0xdd32],
- "ugrave":0xf9, "ugrave;":0xf9,
- "uharl;":0x21bf, "uharr;":0x21be,
- "uhblk;":0x2580, "ulcorn;":0x231c,
- "ulcorner;":0x231c, "ulcrop;":0x230f,
- "ultri;":0x25f8, "umacr;":0x16b,
- "uml":0xa8, "uml;":0xa8,
- "uogon;":0x173, "uopf;":[0xd835,0xdd66],
- "uparrow;":0x2191, "updownarrow;":0x2195,
- "upharpoonleft;":0x21bf, "upharpoonright;":0x21be,
- "uplus;":0x228e, "upsi;":0x3c5,
- "upsih;":0x3d2, "upsilon;":0x3c5,
- "upuparrows;":0x21c8, "urcorn;":0x231d,
- "urcorner;":0x231d, "urcrop;":0x230e,
- "uring;":0x16f, "urtri;":0x25f9,
- "uscr;":[0xd835,0xdcca], "utdot;":0x22f0,
- "utilde;":0x169, "utri;":0x25b5,
- "utrif;":0x25b4, "uuarr;":0x21c8,
- "uuml":0xfc, "uuml;":0xfc,
- "uwangle;":0x29a7, "vArr;":0x21d5,
- "vBar;":0x2ae8, "vBarv;":0x2ae9,
- "vDash;":0x22a8, "vangrt;":0x299c,
- "varepsilon;":0x3f5, "varkappa;":0x3f0,
- "varnothing;":0x2205, "varphi;":0x3d5,
- "varpi;":0x3d6, "varpropto;":0x221d,
- "varr;":0x2195, "varrho;":0x3f1,
- "varsigma;":0x3c2, "varsubsetneq;":[0x228a,0xfe00],
- "varsubsetneqq;":[0x2acb,0xfe00], "varsupsetneq;":[0x228b,0xfe00],
- "varsupsetneqq;":[0x2acc,0xfe00], "vartheta;":0x3d1,
- "vartriangleleft;":0x22b2, "vartriangleright;":0x22b3,
- "vcy;":0x432, "vdash;":0x22a2,
- "vee;":0x2228, "veebar;":0x22bb,
- "veeeq;":0x225a, "vellip;":0x22ee,
- "verbar;":0x7c, "vert;":0x7c,
- "vfr;":[0xd835,0xdd33], "vltri;":0x22b2,
- "vnsub;":[0x2282,0x20d2], "vnsup;":[0x2283,0x20d2],
- "vopf;":[0xd835,0xdd67], "vprop;":0x221d,
- "vrtri;":0x22b3, "vscr;":[0xd835,0xdccb],
- "vsubnE;":[0x2acb,0xfe00], "vsubne;":[0x228a,0xfe00],
- "vsupnE;":[0x2acc,0xfe00], "vsupne;":[0x228b,0xfe00],
- "vzigzag;":0x299a, "wcirc;":0x175,
- "wedbar;":0x2a5f, "wedge;":0x2227,
- "wedgeq;":0x2259, "weierp;":0x2118,
- "wfr;":[0xd835,0xdd34], "wopf;":[0xd835,0xdd68],
- "wp;":0x2118, "wr;":0x2240,
- "wreath;":0x2240, "wscr;":[0xd835,0xdccc],
- "xcap;":0x22c2, "xcirc;":0x25ef,
- "xcup;":0x22c3, "xdtri;":0x25bd,
- "xfr;":[0xd835,0xdd35], "xhArr;":0x27fa,
- "xharr;":0x27f7, "xi;":0x3be,
- "xlArr;":0x27f8, "xlarr;":0x27f5,
- "xmap;":0x27fc, "xnis;":0x22fb,
- "xodot;":0x2a00, "xopf;":[0xd835,0xdd69],
- "xoplus;":0x2a01, "xotime;":0x2a02,
- "xrArr;":0x27f9, "xrarr;":0x27f6,
- "xscr;":[0xd835,0xdccd], "xsqcup;":0x2a06,
- "xuplus;":0x2a04, "xutri;":0x25b3,
- "xvee;":0x22c1, "xwedge;":0x22c0,
- "yacute":0xfd, "yacute;":0xfd,
- "yacy;":0x44f, "ycirc;":0x177,
- "ycy;":0x44b, "yen":0xa5,
- "yen;":0xa5, "yfr;":[0xd835,0xdd36],
- "yicy;":0x457, "yopf;":[0xd835,0xdd6a],
- "yscr;":[0xd835,0xdcce], "yucy;":0x44e,
- "yuml":0xff, "yuml;":0xff,
- "zacute;":0x17a, "zcaron;":0x17e,
- "zcy;":0x437, "zdot;":0x17c,
- "zeetrf;":0x2128, "zeta;":0x3b6,
- "zfr;":[0xd835,0xdd37], "zhcy;":0x436,
- "zigrarr;":0x21dd, "zopf;":[0xd835,0xdd6b],
- "zscr;":[0xd835,0xdccf], "zwj;":0x200d,
- "zwnj;":0x200c,
-};
-/*
- * This regexp is generated with test/tools/update-entities.js
- * It will always match at least one character -- but note that there
- * are no entities whose names are a single character long.
- */
-var NAMEDCHARREF = /(A(?:Elig;?|MP;?|acute;?|breve;|c(?:irc;?|y;)|fr;|grave;?|lpha;|macr;|nd;|o(?:gon;|pf;)|pplyFunction;|ring;?|s(?:cr;|sign;)|tilde;?|uml;?)|B(?:a(?:ckslash;|r(?:v;|wed;))|cy;|e(?:cause;|rnoullis;|ta;)|fr;|opf;|reve;|scr;|umpeq;)|C(?:Hcy;|OPY;?|a(?:cute;|p(?:;|italDifferentialD;)|yleys;)|c(?:aron;|edil;?|irc;|onint;)|dot;|e(?:dilla;|nterDot;)|fr;|hi;|ircle(?:Dot;|Minus;|Plus;|Times;)|lo(?:ckwiseContourIntegral;|seCurly(?:DoubleQuote;|Quote;))|o(?:lon(?:;|e;)|n(?:gruent;|int;|tourIntegral;)|p(?:f;|roduct;)|unterClockwiseContourIntegral;)|ross;|scr;|up(?:;|Cap;))|D(?:D(?:;|otrahd;)|Jcy;|Scy;|Zcy;|a(?:gger;|rr;|shv;)|c(?:aron;|y;)|el(?:;|ta;)|fr;|i(?:a(?:critical(?:Acute;|Do(?:t;|ubleAcute;)|Grave;|Tilde;)|mond;)|fferentialD;)|o(?:pf;|t(?:;|Dot;|Equal;)|uble(?:ContourIntegral;|Do(?:t;|wnArrow;)|L(?:eft(?:Arrow;|RightArrow;|Tee;)|ong(?:Left(?:Arrow;|RightArrow;)|RightArrow;))|Right(?:Arrow;|Tee;)|Up(?:Arrow;|DownArrow;)|VerticalBar;)|wn(?:Arrow(?:;|Bar;|UpArrow;)|Breve;|Left(?:RightVector;|TeeVector;|Vector(?:;|Bar;))|Right(?:TeeVector;|Vector(?:;|Bar;))|Tee(?:;|Arrow;)|arrow;))|s(?:cr;|trok;))|E(?:NG;|TH;?|acute;?|c(?:aron;|irc;?|y;)|dot;|fr;|grave;?|lement;|m(?:acr;|pty(?:SmallSquare;|VerySmallSquare;))|o(?:gon;|pf;)|psilon;|qu(?:al(?:;|Tilde;)|ilibrium;)|s(?:cr;|im;)|ta;|uml;?|x(?:ists;|ponentialE;))|F(?:cy;|fr;|illed(?:SmallSquare;|VerySmallSquare;)|o(?:pf;|rAll;|uriertrf;)|scr;)|G(?:Jcy;|T;?|amma(?:;|d;)|breve;|c(?:edil;|irc;|y;)|dot;|fr;|g;|opf;|reater(?:Equal(?:;|Less;)|FullEqual;|Greater;|Less;|SlantEqual;|Tilde;)|scr;|t;)|H(?:ARDcy;|a(?:cek;|t;)|circ;|fr;|ilbertSpace;|o(?:pf;|rizontalLine;)|s(?:cr;|trok;)|ump(?:DownHump;|Equal;))|I(?:Ecy;|Jlig;|Ocy;|acute;?|c(?:irc;?|y;)|dot;|fr;|grave;?|m(?:;|a(?:cr;|ginaryI;)|plies;)|n(?:t(?:;|e(?:gral;|rsection;))|visible(?:Comma;|Times;))|o(?:gon;|pf;|ta;)|scr;|tilde;|u(?:kcy;|ml;?))|J(?:c(?:irc;|y;)|fr;|opf;|s(?:cr;|ercy;)|ukcy;)|K(?:Hcy;|Jcy;|appa;|c(?:edil;|y;)|fr;|opf;|scr;)|L(?:Jcy;|T;?|a(?:cute;|mbda;|ng;|placetrf;|rr;)|c(?:aron;|edil;|y;)|e(?:ft(?:A(?:ngleBracket;|rrow(?:;|Bar;|RightArrow;))|Ceiling;|Do(?:ubleBracket;|wn(?:TeeVector;|Vector(?:;|Bar;)))|Floor;|Right(?:Arrow;|Vector;)|T(?:ee(?:;|Arrow;|Vector;)|riangle(?:;|Bar;|Equal;))|Up(?:DownVector;|TeeVector;|Vector(?:;|Bar;))|Vector(?:;|Bar;)|arrow;|rightarrow;)|ss(?:EqualGreater;|FullEqual;|Greater;|Less;|SlantEqual;|Tilde;))|fr;|l(?:;|eftarrow;)|midot;|o(?:ng(?:Left(?:Arrow;|RightArrow;)|RightArrow;|left(?:arrow;|rightarrow;)|rightarrow;)|pf;|wer(?:LeftArrow;|RightArrow;))|s(?:cr;|h;|trok;)|t;)|M(?:ap;|cy;|e(?:diumSpace;|llintrf;)|fr;|inusPlus;|opf;|scr;|u;)|N(?:Jcy;|acute;|c(?:aron;|edil;|y;)|e(?:gative(?:MediumSpace;|Thi(?:ckSpace;|nSpace;)|VeryThinSpace;)|sted(?:GreaterGreater;|LessLess;)|wLine;)|fr;|o(?:Break;|nBreakingSpace;|pf;|t(?:;|C(?:ongruent;|upCap;)|DoubleVerticalBar;|E(?:lement;|qual(?:;|Tilde;)|xists;)|Greater(?:;|Equal;|FullEqual;|Greater;|Less;|SlantEqual;|Tilde;)|Hump(?:DownHump;|Equal;)|Le(?:ftTriangle(?:;|Bar;|Equal;)|ss(?:;|Equal;|Greater;|Less;|SlantEqual;|Tilde;))|Nested(?:GreaterGreater;|LessLess;)|Precedes(?:;|Equal;|SlantEqual;)|R(?:everseElement;|ightTriangle(?:;|Bar;|Equal;))|S(?:quareSu(?:bset(?:;|Equal;)|perset(?:;|Equal;))|u(?:bset(?:;|Equal;)|cceeds(?:;|Equal;|SlantEqual;|Tilde;)|perset(?:;|Equal;)))|Tilde(?:;|Equal;|FullEqual;|Tilde;)|VerticalBar;))|scr;|tilde;?|u;)|O(?:Elig;|acute;?|c(?:irc;?|y;)|dblac;|fr;|grave;?|m(?:acr;|ega;|icron;)|opf;|penCurly(?:DoubleQuote;|Quote;)|r;|s(?:cr;|lash;?)|ti(?:lde;?|mes;)|uml;?|ver(?:B(?:ar;|rac(?:e;|ket;))|Parenthesis;))|P(?:artialD;|cy;|fr;|hi;|i;|lusMinus;|o(?:incareplane;|pf;)|r(?:;|ecedes(?:;|Equal;|SlantEqual;|Tilde;)|ime;|o(?:duct;|portion(?:;|al;)))|s(?:cr;|i;))|Q(?:UOT;?|fr;|opf;|scr;)|R(?:Barr;|EG;?|a(?:cute;|ng;|rr(?:;|tl;))|c(?:aron;|edil;|y;)|e(?:;|verse(?:E(?:lement;|quilibrium;)|UpEquilibrium;))|fr;|ho;|ight(?:A(?:ngleBracket;|rrow(?:;|Bar;|LeftArrow;))|Ceiling;|Do(?:ubleBracket;|wn(?:TeeVector;|Vector(?:;|Bar;)))|Floor;|T(?:ee(?:;|Arrow;|Vector;)|riangle(?:;|Bar;|Equal;))|Up(?:DownVector;|TeeVector;|Vector(?:;|Ba
\ No newline at end of file
-
-var NAMEDCHARREF_MAXLEN = 32;
-
-// Regular expression constants used by the tokenizer and parser
-
-// Note that \r is included in all of these regexps because it will need
-// to be converted to LF by the scanChars() function.
-var DBLQUOTEATTRVAL = /[^\r"&\u0000]+/g;
-var SINGLEQUOTEATTRVAL = /[^\r'&\u0000]+/g;
-var UNQUOTEDATTRVAL = /[^\r\t\n\f &>\u0000]+/g;
-var TAGNAME = /[^\r\t\n\f \/>A-Z\u0000]+/g;
-var ATTRNAME = /[^\r\t\n\f \/=>A-Z\u0000]+/g;
-
-var CDATATEXT = /[^\]\r\u0000\uffff]*/g;
-var DATATEXT = /[^&<\r\u0000\uffff]*/g;
-var RAWTEXT = /[^<\r\u0000\uffff]*/g;
-var PLAINTEXT = /[^\r\u0000\uffff]*/g;
-// Since we don't have the 'sticky tag', add '|.' to the end of SIMPLETAG
-// and SIMPLEATTR so that we are guaranteed to always match. This prevents
-// us from scanning past the lastIndex set. (Note that the desired matches
-// are always greater than 1 char long, so longest-match will ensure that .
-// is not matched unless the desired match fails.)
-var SIMPLETAG = /(?:(\/)?([a-z]+)>)|[\s\S]/g;
-var SIMPLEATTR = /(?:([-a-z]+)[ \t\n\f]*=[ \t\n\f]*('[^'&\r\u0000]*'|"[^"&\r\u0000]*"|[^\t\n\r\f "&'\u0000>][^&> \t\n\r\f\u0000]*[ \t\n\f]))|[\s\S]/g;
-
-var NONWS = /[^\x09\x0A\x0C\x0D\x20]/;
-var ALLNONWS = /[^\x09\x0A\x0C\x0D\x20]/g; // like above, with g flag
-var NONWSNONNUL = /[^\x00\x09\x0A\x0C\x0D\x20]/; // don't allow NUL either
-var LEADINGWS = /^[\x09\x0A\x0C\x0D\x20]+/;
-var NULCHARS = /\x00/g;
-
-/***
- * These are utility functions that don't use any of the parser's
- * internal state.
- */
-function buf2str(buf) {
- var CHUNKSIZE=16384;
- if (buf.length < CHUNKSIZE) {
- return String.fromCharCode.apply(String, buf);
- }
- // special case for large strings, to avoid busting the stack.
- var result = '';
- for (var i = 0; i < buf.length; i += CHUNKSIZE) {
- result += String.fromCharCode.apply(String, buf.slice(i, i+CHUNKSIZE));
- }
- return result;
-}
-
-function str2buf(s) {
- var result = [];
- for (var i=0; i<s.length; i++) {
- result[i] = s.charCodeAt(i);
- }
- return result;
-}
-
-// Determine whether the element is a member of the set.
-// The set is an object that maps namespaces to objects. The objects
-// then map local tagnames to the value true if that tag is part of the set
-function isA(elt, set) {
- if (typeof set === 'string') {
- // convenience case for testing a particular HTML element
- return elt.namespaceURI === NAMESPACE.HTML &&
- elt.localName === set;
- }
- var tagnames = set[elt.namespaceURI];
- return tagnames && tagnames[elt.localName];
-}
-
-function isMathmlTextIntegrationPoint(n) {
- return isA(n, mathmlTextIntegrationPointSet);
-}
-
-function isHTMLIntegrationPoint(n) {
- if (isA(n, htmlIntegrationPointSet)) return true;
- if (n.namespaceURI === NAMESPACE.MATHML &&
- n.localName === "annotation-xml") {
- var encoding = n.getAttribute("encoding");
- if (encoding) encoding = encoding.toLowerCase();
- if (encoding === "text/html" ||
- encoding === "application/xhtml+xml")
- return true;
- }
- return false;
-}
-
-function adjustSVGTagName(name) {
- if (name in svgTagNameAdjustments)
- return svgTagNameAdjustments[name];
- else
- return name;
-}
-
-function adjustSVGAttributes(attrs) {
- for(var i = 0, n = attrs.length; i < n; i++) {
- if (attrs[i][0] in svgAttrAdjustments) {
- attrs[i][0] = svgAttrAdjustments[attrs[i][0]];
- }
- }
-}
-
-function adjustMathMLAttributes(attrs) {
- for(var i = 0, n = attrs.length; i < n; i++) {
- if (attrs[i][0] === "definitionurl") {
- attrs[i][0] = "definitionURL";
- break;
- }
- }
-}
-
-function adjustForeignAttributes(attrs) {
- for(var i = 0, n = attrs.length; i < n; i++) {
- if (attrs[i][0] in foreignAttributes) {
- // Attributes with namespaces get a 3rd element:
- // [Qname, value, namespace]
- attrs[i].push(foreignAttributes[attrs[i][0]]);
- }
- }
-}
-
-// For each attribute in attrs, if elt doesn't have an attribute
-// by that name, add the attribute to elt
-// XXX: I'm ignoring namespaces for now
-function transferAttributes(attrs, elt) {
- for(var i = 0, n = attrs.length; i < n; i++) {
- var name = attrs[i][0], value = attrs[i][1];
- if (elt.hasAttribute(name)) continue;
- elt._setAttribute(name, value);
- }
-}
-
-/***
- * The ElementStack class
- */
-HTMLParser.ElementStack = function ElementStack() {
- this.elements = [];
- this.top = null; // stack.top is the "current node" in the spec
-};
-
-/*
-// This is for debugging only
-HTMLParser.ElementStack.prototype.toString = function(e) {
- return "STACK: " +
- this.elements.map(function(e) {return e.localName;}).join("-");
-}
-*/
-
-HTMLParser.ElementStack.prototype.push = function(e) {
- this.elements.push(e);
- this.top = e;
-};
-
-HTMLParser.ElementStack.prototype.pop = function(e) {
- this.elements.pop();
- this.top = this.elements[this.elements.length-1];
-};
-
-// Pop elements off the stack up to and including the first
-// element with the specified (HTML) tagname
-HTMLParser.ElementStack.prototype.popTag = function(tag) {
- for(var i = this.elements.length-1; i > 0; i--) {
- var e = this.elements[i];
- if (isA(e, tag)) break;
- }
- this.elements.length = i;
- this.top = this.elements[i-1];
-};
-
-// Pop elements off the stack up to and including the first
-// element that is an instance of the specified type
-HTMLParser.ElementStack.prototype.popElementType = function(type) {
- for(var i = this.elements.length-1; i > 0; i--) {
- if (this.elements[i] instanceof type) break;
- }
- this.elements.length = i;
- this.top = this.elements[i-1];
-};
-
-// Pop elements off the stack up to and including the element e.
-// Note that this is very different from removeElement()
-// This requires that e is on the stack.
-HTMLParser.ElementStack.prototype.popElement = function(e) {
- for(var i = this.elements.length-1; i > 0; i--) {
- if (this.elements[i] === e) break;
- }
- this.elements.length = i;
- this.top = this.elements[i-1];
-};
-
-// Remove a specific element from the stack.
-// Do nothing if the element is not on the stack
-HTMLParser.ElementStack.prototype.removeElement = function(e) {
- if (this.top === e) this.pop();
- else {
- var idx = this.elements.lastIndexOf(e);
- if (idx !== -1)
- this.elements.splice(idx, 1);
- }
-};
-
-HTMLParser.ElementStack.prototype.clearToContext = function(set) {
- // Note that we don't loop to 0. Never pop the <html> elt off.
- for(var i = this.elements.length-1; i > 0; i--) {
- if (isA(this.elements[i], set)) break;
- }
- this.elements.length = i+1;
- this.top = this.elements[i];
-};
-
-HTMLParser.ElementStack.prototype.contains = function(tag) {
- return this.inSpecificScope(tag, Object.create(null));
-};
-
-HTMLParser.ElementStack.prototype.inSpecificScope = function(tag, set) {
- for(var i = this.elements.length-1; i >= 0; i--) {
- var elt = this.elements[i];
- if (isA(elt, tag)) return true;
- if (isA(elt, set)) return false;
- }
- return false;
-};
-
-// Like the above, but for a specific element, not a tagname
-HTMLParser.ElementStack.prototype.elementInSpecificScope = function(target, set) {
- for(var i = this.elements.length-1; i >= 0; i--) {
- var elt = this.elements[i];
- if (elt === target) return true;
- if (isA(elt, set)) return false;
- }
- return false;
-};
-
-// Like the above, but for an element interface, not a tagname
-HTMLParser.ElementStack.prototype.elementTypeInSpecificScope = function(target, set) {
- for(var i = this.elements.length-1; i >= 0; i--) {
- var elt = this.elements[i];
- if (elt instanceof target) return true;
- if (isA(elt, set)) return false;
- }
- return false;
-};
-
-HTMLParser.ElementStack.prototype.inScope = function(tag) {
- return this.inSpecificScope(tag, inScopeSet);
-};
-
-HTMLParser.ElementStack.prototype.elementInScope = function(e) {
- return this.elementInSpecificScope(e, inScopeSet);
-};
-
-HTMLParser.ElementStack.prototype.elementTypeInScope = function(type) {
- return this.elementTypeInSpecificScope(type, inScopeSet);
-};
-
-HTMLParser.ElementStack.prototype.inButtonScope = function(tag) {
- return this.inSpecificScope(tag, inButtonScopeSet);
-};
-
-HTMLParser.ElementStack.prototype.inListItemScope = function(tag) {
- return this.inSpecificScope(tag, inListItemScopeSet);
-};
-
-HTMLParser.ElementStack.prototype.inTableScope = function(tag) {
- return this.inSpecificScope(tag, inTableScopeSet);
-};
-
-HTMLParser.ElementStack.prototype.inSelectScope = function(tag) {
- // Can't implement this one with inSpecificScope, since it involves
- // a set defined by inverting another set. So implement manually.
- for(var i = this.elements.length-1; i >= 0; i--) {
- var elt = this.elements[i];
- if (elt.namespaceURI !== NAMESPACE.HTML) return false;
- var localname = elt.localName;
- if (localname === tag) return true;
- if (localname !== "optgroup" && localname !== "option")
- return false;
- }
- return false;
-};
-
-HTMLParser.ElementStack.prototype.generateImpliedEndTags = function(butnot, thorough) {
- var endTagSet = thorough ? thoroughImpliedEndTagsSet : impliedEndTagsSet;
- for(var i = this.elements.length-1; i >= 0; i--) {
- var e = this.elements[i];
- if (butnot && isA(e, butnot)) break;
- if (!isA(this.elements[i], endTagSet)) break;
- }
-
- this.elements.length = i+1;
- this.top = this.elements[i];
-};
-
-/***
- * The ActiveFormattingElements class
- */
-HTMLParser.ActiveFormattingElements = function AFE() {
- this.list = []; // elements
- this.attrs = []; // attribute tokens for cloning
-};
-
-HTMLParser.ActiveFormattingElements.prototype.MARKER = { localName: "|" };
-
-/*
-// For debugging
-HTMLParser.ActiveFormattingElements.prototype.toString = function() {
- return "AFE: " +
- this.list.map(function(e) { return e.localName; }).join("-");
-}
-*/
-
-HTMLParser.ActiveFormattingElements.prototype.insertMarker = function() {
- this.list.push(this.MARKER);
- this.attrs.push(this.MARKER);
-};
-
-HTMLParser.ActiveFormattingElements.prototype.push = function(elt, attrs) {
- // Scan backwards: if there are already 3 copies of this element
- // before we encounter a marker, then drop the last one
- var count = 0;
- for(var i = this.list.length-1; i >= 0; i--) {
- if (this.list[i] === this.MARKER) break;
- // equal() is defined below
- if (equal(elt, this.list[i], this.attrs[i])) {
- count++;
- if (count === 3) {
- this.list.splice(i, 1);
- this.attrs.splice(i, 1);
- break;
- }
- }
- }
-
-
- // Now push the element onto the list
- this.list.push(elt);
-
- // Copy the attributes and push those on, too
- var attrcopy = [];
- for(var ii = 0; ii < attrs.length; ii++) {
- attrcopy[ii] = attrs[ii];
- }
-
- this.attrs.push(attrcopy);
-
- // This function defines equality of two elements for the purposes
- // of the AFE list. Note that it compares the new elements
- // attributes to the saved array of attributes associated with
- // the old element because a script could have changed the
- // old element's set of attributes
- function equal(newelt, oldelt, oldattrs) {
- if (newelt.localName !== oldelt.localName) return false;
- if (newelt._numattrs !== oldattrs.length) return false;
- for(var i = 0, n = oldattrs.length; i < n; i++) {
- var oldname = oldattrs[i][0];
- var oldval = oldattrs[i][1];
- if (!newelt.hasAttribute(oldname)) return false;
- if (newelt.getAttribute(oldname) !== oldval) return false;
- }
- return true;
- }
-};
-
-HTMLParser.ActiveFormattingElements.prototype.clearToMarker = function() {
- for(var i = this.list.length-1; i >= 0; i--) {
- if (this.list[i] === this.MARKER) break;
- }
- if (i < 0) i = 0;
- this.list.length = i;
- this.attrs.length = i;
-};
-
-// Find and return the last element with the specified tag between the
-// end of the list and the last marker on the list.
-// Used when parsing <a> in_body_mode()
-HTMLParser.ActiveFormattingElements.prototype.findElementByTag = function(tag) {
- for(var i = this.list.length-1; i >= 0; i--) {
- var elt = this.list[i];
- if (elt === this.MARKER) break;
- if (elt.localName === tag) return elt;
- }
- return null;
-};
-
-HTMLParser.ActiveFormattingElements.prototype.indexOf = function(e) {
- return this.list.lastIndexOf(e);
-};
-
-// Find the element e in the list and remove it
-// Used when parsing <a> in_body()
-HTMLParser.ActiveFormattingElements.prototype.remove = function(e) {
- var idx = this.list.lastIndexOf(e);
- if (idx !== -1) {
- this.list.splice(idx, 1);
- this.attrs.splice(idx, 1);
- }
-};
-
-// Find element a in the list and replace it with element b
-// XXX: Do I need to handle attributes here?
-HTMLParser.ActiveFormattingElements.prototype.replace = function(a, b, attrs) {
- var idx = this.list.lastIndexOf(a);
- if (idx !== -1) {
- this.list[idx] = b;
- this.attrs[idx] = attrs;
- }
-};
-
-// Find a in the list and insert b after it
-// This is only used for insert a bookmark object, so the
-// attrs array doesn't really matter
-HTMLParser.ActiveFormattingElements.prototype.insertAfter = function(a,b) {
- var idx = this.list.lastIndexOf(a);
- if (idx !== -1) {
- this.list.splice(idx, 0, b);
- this.attrs.splice(idx, 0, b);
- }
-};
-
-
-
-
-/***
- * This is the parser factory function. It is the return value of
- * the outer closure that it is defined within. Most of the parser
- * implementation details are inside this function.
- */
-function HTMLParser(address, fragmentContext, options) {
- /***
- * These are the parser's state variables
- */
- // Scanner state
- var chars = null;
- var numchars = 0; // Length of chars
- var nextchar = 0; // Index of next char
- var input_complete = false; // Becomes true when end() called.
- var scanner_skip_newline = false; // If previous char was CR
- var reentrant_invocations = 0;
- var saved_scanner_state = [];
- var leftovers = "";
- var first_batch = true;
- var paused = 0; // Becomes non-zero while loading scripts
-
-
- // Tokenizer state
- var tokenizer = data_state; // Current tokenizer state
- var return_state;
- var character_reference_code;
- var tagnamebuf = "";
- var lasttagname = ""; // holds the target end tag for text states
- var tempbuf = [];
- var attrnamebuf = "";
- var attrvaluebuf = "";
- var commentbuf = [];
- var doctypenamebuf = [];
- var doctypepublicbuf = [];
- var doctypesystembuf = [];
- var attributes = [];
- var is_end_tag = false;
-
- // Tree builder state
- var parser = initial_mode; // Current insertion mode
- var originalInsertionMode = null; // A saved insertion mode
- var templateInsertionModes = []; // Stack of template insertion modes.
- var stack = new HTMLParser.ElementStack(); // Stack of open elements
- var afe = new HTMLParser.ActiveFormattingElements(); // mis-nested tags
- var fragment = (fragmentContext!==undefined); // For innerHTML, etc.
- var head_element_pointer = null;
- var form_element_pointer = null;
- var scripting_enabled = true;
- if (fragmentContext) {
- scripting_enabled = fragmentContext.ownerDocument._scripting_enabled;
- }
- if (options && options.scripting_enabled === false)
- scripting_enabled = false;
- var frameset_ok = true;
- var force_quirks = false;
- var pending_table_text;
- var text_integration_mode; // XXX a spec bug workaround?
-
- // A single run of characters, buffered up to be sent to
- // the parser as a single string.
- var textrun = [];
- var textIncludesNUL = false;
- var ignore_linefeed = false;
-
- /***
- * This is the parser object that will be the return value of this
- * factory function, which is some 5000 lines below.
- * Note that the variable "parser" is the current state of the
- * parser's state machine. This variable "htmlparser" is the
- * return value and defines the public API of the parser
- */
- var htmlparser = {
- document: function() {
- return doc;
- },
-
- // Convenience function for internal use. Can only be called once,
- // as it removes the nodes from `doc` to add them to fragment.
- _asDocumentFragment: function() {
- var frag = doc.createDocumentFragment();
- var root = doc.firstChild;
- while(root.hasChildNodes()) {
- frag.appendChild(root.firstChild);
- }
- return frag;
- },
-
- // Internal function used from HTMLScriptElement to pause the
- // parser while a script is being loaded from the network
- pause: function() {
- // print("pausing parser");
- paused++;
- },
-
- // Called when a script finishes loading
- resume: function() {
- // print("resuming parser");
- paused--;
- // XXX: added this to force a resumption.
- // Is this the right thing to do?
- this.parse("");
- },
-
- // Parse the HTML text s.
- // The second argument should be true if there is no more
- // text to be parsed, and should be false or omitted otherwise.
- // The second argument must not be set for recursive invocations
- // from document.write()
- parse: function(s, end, shouldPauseFunc) {
- var moreToDo;
-
- // If we're paused, remember the text to parse, but
- // don't parse it now.
- // (Don't invoke shouldPauseFunc because we haven't handled 'end' yet.)
- if (paused > 0) {
- leftovers += s;
- return true; // more to do
- }
-
-
- if (reentrant_invocations === 0) {
- // A normal, top-level invocation
- if (leftovers) {
- s = leftovers + s;
- leftovers = "";
- }
-
- // Add a special marker character to the end of
- // the buffer. If the scanner is at the end of
- // the buffer and input_complete is set, then this
- // character will transform into an EOF token.
- // Having an actual character that represents EOF
- // in the character buffer makes lookahead regexp
- // matching work more easily, and this is
- // important for character references.
- if (end) {
- s += "\uFFFF";
- input_complete = true; // Makes scanChars() send EOF
- }
-
- chars = s;
- numchars = s.length;
- nextchar = 0;
-
- if (first_batch) {
- // We skip a leading Byte Order Mark (\uFEFF)
- // on first batch of text we're given
- first_batch = false;
- if (chars.charCodeAt(0) === 0xFEFF) nextchar = 1;
- }
-
- reentrant_invocations++;
- moreToDo = scanChars(shouldPauseFunc);
- leftovers = chars.substring(nextchar, numchars);
- reentrant_invocations--;
- }
- else {
- // This is the re-entrant case, which we have to
- // handle a little differently.
- reentrant_invocations++;
-
- // Save current scanner state
- saved_scanner_state.push(chars, numchars, nextchar);
-
- // Set new scanner state
- chars = s;
- numchars = s.length;
- nextchar = 0;
-
- // Now scan as many of these new chars as we can
- scanChars();
- moreToDo = false;
-
- leftovers = chars.substring(nextchar, numchars);
-
- // restore old scanner state
- nextchar = saved_scanner_state.pop();
- numchars = saved_scanner_state.pop();
- chars = saved_scanner_state.pop();
-
- // If there were leftover chars from this invocation
- // insert them into the pending invocation's buffer
- // and trim already processed chars at the same time
- if (leftovers) {
- chars = leftovers + chars.substring(nextchar);
- numchars = chars.length;
- nextchar = 0;
- leftovers = "";
- }
-
- // Decrement the counter
- reentrant_invocations--;
- }
- return moreToDo;
- }
- };
-
-
- // This is the document we'll be building up
- var doc = new Document(true, address);
-
- // The document needs to know about the parser, for document.write().
- // This _parser property will be deleted when we're done parsing.
- doc._parser = htmlparser;
-
- // XXX I think that any document we use this parser on should support
- // scripts. But I may need to configure that through a parser parameter
- // Only documents with windows ("browsing contexts" to be precise)
- // allow scripting.
- doc._scripting_enabled = scripting_enabled;
-
-
- /***
- * The actual code of the HTMLParser() factory function begins here.
- */
-
- if (fragmentContext) { // for innerHTML parsing
- if (fragmentContext.ownerDocument._quirks)
- doc._quirks = true;
- if (fragmentContext.ownerDocument._limitedQuirks)
- doc._limitedQuirks = true;
-
- // Set the initial tokenizer state
- if (fragmentContext.namespaceURI === NAMESPACE.HTML) {
- switch(fragmentContext.localName) {
- case "title":
- case "textarea":
- tokenizer = rcdata_state;
- break;
- case "style":
- case "xmp":
- case "iframe":
- case "noembed":
- case "noframes":
- case "script":
- case "plaintext":
- tokenizer = plaintext_state;
- break;
- case "noscript":
- if (scripting_enabled)
- tokenizer = plaintext_state;
- }
- }
-
- var root = doc.createElement("html");
- doc._appendChild(root);
- stack.push(root);
- if (fragmentContext instanceof impl.HTMLTemplateElement) {
- templateInsertionModes.push(in_template_mode);
- }
- resetInsertionMode();
-
- for(var e = fragmentContext; e !== null; e = e.parentElement) {
- if (e instanceof impl.HTMLFormElement) {
- form_element_pointer = e;
- break;
- }
- }
- }
-
- /***
- * Scanner functions
- */
- // Loop through the characters in chars, and pass them one at a time
- // to the tokenizer FSM. Return when no more characters can be processed
- // (This may leave 1 or more characters in the buffer: like a CR
- // waiting to see if the next char is LF, or for states that require
- // lookahead...)
- function scanChars(shouldPauseFunc) {
- var codepoint, s, pattern, eof;
-
- while(nextchar < numchars) {
-
- // If we just tokenized a </script> tag, then the paused flag
- // may have been set to tell us to stop tokenizing while
- // the script is loading
- if (paused > 0 || (shouldPauseFunc && shouldPauseFunc())) {
- return true;
- }
-
-
- switch(typeof tokenizer.lookahead) {
- case 'undefined':
- codepoint = chars.charCodeAt(nextchar++);
- if (scanner_skip_newline) {
- scanner_skip_newline = false;
- if (codepoint === 0x000A) {
- nextchar++;
- continue;
- }
- }
- switch(codepoint) {
- case 0x000D:
- // CR always turns into LF, but if the next character
- // is LF, then that second LF is skipped.
- if (nextchar < numchars) {
- if (chars.charCodeAt(nextchar) === 0x000A)
- nextchar++;
- }
- else {
- // We don't know the next char right now, so we
- // can't check if it is a LF. So set a flag
- scanner_skip_newline = true;
- }
-
- // In either case, emit a LF
- tokenizer(0x000A);
-
- break;
- case 0xFFFF:
- if (input_complete && nextchar === numchars) {
- tokenizer(EOF); // codepoint will be 0xFFFF here
- break;
- }
- /* falls through */
- default:
- tokenizer(codepoint);
- break;
- }
- break;
-
- case 'number':
- codepoint = chars.charCodeAt(nextchar);
-
- // The only tokenizer states that require fixed lookahead
- // only consume alphanum characters, so we don't have
- // to worry about CR and LF in this case
-
- // tokenizer wants n chars of lookahead
- var n = tokenizer.lookahead;
- var needsString = true;
- if (n < 0) {
- needsString = false;
- n = -n;
- }
-
- if (n < numchars - nextchar) {
- // If we can look ahead that far
- s = needsString ? chars.substring(nextchar, nextchar+n) : null;
- eof = false;
- }
- else { // if we don't have that many characters
- if (input_complete) { // If no more are coming
- // Just return what we have
- s = needsString ? chars.substring(nextchar, numchars) : null;
- eof = true;
- if (codepoint === 0xFFFF && nextchar === numchars-1)
- codepoint = EOF;
- }
- else {
- // Return now and wait for more chars later
- return true;
- }
- }
- tokenizer(codepoint, s, eof);
- break;
- case 'string':
- codepoint = chars.charCodeAt(nextchar);
-
- // tokenizer wants characters up to a matching string
- pattern = tokenizer.lookahead;
- var pos = chars.indexOf(pattern, nextchar);
- if (pos !== -1) {
- s = chars.substring(nextchar, pos + pattern.length);
- eof = false;
- }
- else { // No match
- // If more characters coming, wait for them
- if (!input_complete) return true;
-
- // Otherwise, we've got to return what we've got
- s = chars.substring(nextchar, numchars);
- if (codepoint === 0xFFFF && nextchar === numchars-1)
- codepoint = EOF;
- eof = true;
- }
-
- // The tokenizer states that require this kind of
- // lookahead have to be careful to handle CR characters
- // correctly
- tokenizer(codepoint, s, eof);
- break;
- }
- }
- return false; // no more characters to scan!
- }
-
-
- /***
- * Tokenizer utility functions
- */
- function addAttribute(name,value) {
- // Make sure there isn't already an attribute with this name
- // If there is, ignore this one.
- for(var i = 0; i < attributes.length; i++) {
- if (attributes[i][0] === name) return;
- }
-
- if (value !== undefined) {
- attributes.push([name, value]);
- }
- else {
- attributes.push([name]);
- }
- }
-
- // Shortcut for simple attributes
- function handleSimpleAttribute() {
- SIMPLEATTR.lastIndex = nextchar-1;
- var matched = SIMPLEATTR.exec(chars);
- if (!matched) throw new Error("should never happen");
- var name = matched[1];
- if (!name) return false;
- var value = matched[2];
- var len = value.length;
- switch(value[0]) {
- case '"':
- case "'":
- value = value.substring(1, len-1);
- nextchar += (matched[0].length-1);
- tokenizer = after_attribute_value_quoted_state;
- break;
- default:
- tokenizer = before_attribute_name_state;
- nextchar += (matched[0].length-1);
- value = value.substring(0, len-1);
- break;
- }
-
- // Make sure there isn't already an attribute with this name
- // If there is, ignore this one.
- for(var i = 0; i < attributes.length; i++) {
- if (attributes[i][0] === name) return true;
- }
-
- attributes.push([name, value]);
- return true;
- }
-
- function beginTagName() {
- is_end_tag = false;
- tagnamebuf = "";
- attributes.length = 0;
- }
- function beginEndTagName() {
- is_end_tag = true;
- tagnamebuf = "";
- attributes.length = 0;
- }
-
- function beginTempBuf() { tempbuf.length = 0; }
- function beginAttrName() { attrnamebuf = ""; }
- function beginAttrValue() { attrvaluebuf = ""; }
- function beginComment() { commentbuf.length = 0; }
- function beginDoctype() {
- doctypenamebuf.length = 0;
- doctypepublicbuf = null;
- doctypesystembuf = null;
- }
- function beginDoctypePublicId() { doctypepublicbuf = []; }
- function beginDoctypeSystemId() { doctypesystembuf = []; }
- function forcequirks() { force_quirks = true; }
- function cdataAllowed() {
- return stack.top &&
- stack.top.namespaceURI !== "http://www.w3.org/1999/xhtml";
- }
-
- // Return true if the codepoints in the specified buffer match the
- // characters of lasttagname
- function appropriateEndTag(buf) {
- return lasttagname === buf;
- }
-
- function flushText() {
- if (textrun.length > 0) {
- var s = buf2str(textrun);
- textrun.length = 0;
-
- if (ignore_linefeed) {
- ignore_linefeed = false;
- if (s[0] === "\n") s = s.substring(1);
- if (s.length === 0) return;
- }
-
- insertToken(TEXT, s);
- textIncludesNUL = false;
- }
- ignore_linefeed = false;
- }
-
- // Consume chars matched by the pattern and return them as a string. Starts
- // matching at the current position, so users should drop the current char
- // otherwise.
- function getMatchingChars(pattern) {
- pattern.lastIndex = nextchar - 1;
- var match = pattern.exec(chars);
- if (match && match.index === nextchar - 1) {
- match = match[0];
- nextchar += match.length - 1;
- /* Careful! Make sure we haven't matched the EOF character! */
- if (input_complete && nextchar === numchars) {
- // Oops, backup one.
- match = match.slice(0, -1);
- nextchar--;
- }
- return match;
- } else {
- throw new Error("should never happen");
- }
- }
-
- // emit a string of chars that match a regexp
- // Returns false if no chars matched.
- function emitCharsWhile(pattern) {
- pattern.lastIndex = nextchar-1;
- var match = pattern.exec(chars)[0];
- if (!match) return false;
- emitCharString(match);
- nextchar += match.length - 1;
- return true;
- }
-
- // This is used by CDATA sections
- function emitCharString(s) {
- if (textrun.length > 0) flushText();
-
- if (ignore_linefeed) {
- ignore_linefeed = false;
- if (s[0] === "\n") s = s.substring(1);
- if (s.length === 0) return;
- }
-
- insertToken(TEXT, s);
- }
-
- function emitTag() {
- if (is_end_tag) insertToken(ENDTAG, tagnamebuf);
- else {
- // Remember the last open tag we emitted
- var tagname = tagnamebuf;
- tagnamebuf = "";
- lasttagname = tagname;
- insertToken(TAG, tagname, attributes);
- }
- }
-
-
- // A shortcut: look ahead and if this is a open or close tag
- // in lowercase with no spaces and no attributes, just emit it now.
- function emitSimpleTag() {
- if (nextchar === numchars) { return false; /* not even 1 char left */ }
- SIMPLETAG.lastIndex = nextchar;
- var matched = SIMPLETAG.exec(chars);
- if (!matched) throw new Error("should never happen");
- var tagname = matched[2];
- if (!tagname) return false;
- var endtag = matched[1];
- if (endtag) {
- nextchar += (tagname.length+2);
- insertToken(ENDTAG, tagname);
- }
- else {
- nextchar += (tagname.length+1);
- lasttagname = tagname;
- insertToken(TAG, tagname, NOATTRS);
- }
- return true;
- }
-
- function emitSelfClosingTag() {
- if (is_end_tag) insertToken(ENDTAG, tagnamebuf, null, true);
- else {
- insertToken(TAG, tagnamebuf, attributes, true);
- }
- }
-
- function emitDoctype() {
- insertToken(DOCTYPE,
- buf2str(doctypenamebuf),
- doctypepublicbuf ? buf2str(doctypepublicbuf) : undefined,
- doctypesystembuf ? buf2str(doctypesystembuf) : undefined);
- }
-
- function emitEOF() {
- flushText();
- parser(EOF); // EOF never goes to insertForeignContent()
- doc.modclock = 1; // Start tracking modifications
- }
-
- // Insert a token, either using the current parser insertion mode
- // (for HTML stuff) or using the insertForeignToken() method.
- var insertToken = htmlparser.insertToken = function insertToken(t, value, arg3, arg4) {
- flushText();
- var current = stack.top;
-
- if (!current || current.namespaceURI === NAMESPACE.HTML) {
- // This is the common case
- parser(t, value, arg3, arg4);
- }
- else {
- // Otherwise we may need to insert this token as foreign content
- if (t !== TAG && t !== TEXT) {
- insertForeignToken(t, value, arg3, arg4);
- }
- else {
- // But in some cases we treat it as regular content
- if ((isMathmlTextIntegrationPoint(current) &&
- (t === TEXT ||
- (t === TAG &&
- value !== "mglyph" && value !== "malignmark"))) ||
- (t === TAG &&
- value === "svg" &&
- current.namespaceURI === NAMESPACE.MATHML &&
- current.localName === "annotation-xml") ||
- isHTMLIntegrationPoint(current)) {
-
- // XXX: the text_integration_mode stuff is an
- // attempted bug workaround of mine
- text_integration_mode = true;
- parser(t, value, arg3, arg4);
- text_integration_mode = false;
- }
- // Otherwise it is foreign content
- else {
- insertForeignToken(t, value, arg3, arg4);
- }
- }
- }
- };
-
-
- /***
- * Tree building utility functions
- */
- function insertComment(data) {
- var parent = stack.top;
- if (foster_parent_mode && isA(parent, tablesectionrowSet)) {
- fosterParent(function(doc) { return doc.createComment(data); });
- } else {
- // "If the adjusted insertion location is inside a template element,
- // let it instead be inside the template element's template contents"
- if (parent instanceof impl.HTMLTemplateElement) {
- parent = parent.content;
- }
- parent._appendChild(parent.ownerDocument.createComment(data));
- }
- }
-
- function insertText(s) {
- var parent = stack.top;
- if (foster_parent_mode && isA(parent, tablesectionrowSet)) {
- fosterParent(function(doc) { return doc.createTextNode(s); });
- } else {
- // "If the adjusted insertion location is inside a template element,
- // let it instead be inside the template element's template contents"
- if (parent instanceof impl.HTMLTemplateElement) {
- parent = parent.content;
- }
- // "If there is a Text node immediately before the adjusted insertion
- // location, then append data to that Text node's data."
- var lastChild = parent.lastChild;
- if (lastChild && lastChild.nodeType === Node.TEXT_NODE) {
- lastChild.appendData(s);
- } else {
- parent._appendChild(parent.ownerDocument.createTextNode(s));
- }
- }
- }
-
- function createHTMLElt(doc, name, attrs) {
- // Create the element this way, rather than with
- // doc.createElement because createElement() does error
- // checking on the element name that we need to avoid here.
- var elt = html.createElement(doc, name, null);
-
- if (attrs) {
- for(var i = 0, n = attrs.length; i < n; i++) {
- // Use the _ version to avoid testing the validity
- // of the attribute name
- elt._setAttribute(attrs[i][0], attrs[i][1]);
- }
- }
- // XXX
- // If the element is a resettable form element,
- // run its reset algorithm now
- // XXX
- // handle case where form-element-pointer is not null
- return elt;
- }
-
- // The in_table insertion mode turns on this flag, and that makes
- // insertHTMLElement use the foster parenting algorithm for elements
- // tags inside a table
- var foster_parent_mode = false;
-
- function insertHTMLElement(name, attrs) {
- var elt = insertElement(function(doc) {
- return createHTMLElt(doc, name, attrs);
- });
-
- // XXX
- // If this is a form element, set its form attribute property here
- if (isA(elt, formassociatedSet)) {
- elt._form = form_element_pointer;
- }
-
- return elt;
- }
-
- // Insert the element into the open element or foster parent it
- function insertElement(eltFunc) {
- var elt;
- if (foster_parent_mode && isA(stack.top, tablesectionrowSet)) {
- elt = fosterParent(eltFunc);
- }
- else if (stack.top instanceof impl.HTMLTemplateElement) {
- // "If the adjusted insertion location is inside a template element,
- // let it instead be inside the template element's template contents"
- elt = eltFunc(stack.top.content.ownerDocument);
- stack.top.content._appendChild(elt);
- } else {
- elt = eltFunc(stack.top.ownerDocument);
- stack.top._appendChild(elt);
- }
-
- stack.push(elt);
- return elt;
- }
-
- function insertForeignElement(name, attrs, ns) {
- return insertElement(function(doc) {
- // We need to prevent createElementNS from trying to parse `name` as a
- // `qname`, so use an internal Document#_createElementNS() interface.
- var elt = doc._createElementNS(name, ns, null);
- if (attrs) {
- for(var i = 0, n = attrs.length; i < n; i++) {
- var attr = attrs[i];
- if (attr.length === 2)
- elt._setAttribute(attr[0], attr[1]);
- else {
- elt._setAttributeNS(attr[2], attr[0], attr[1]);
- }
- }
- }
- return elt;
- });
- }
-
- function lastElementOfType(type) {
- for(var i = stack.elements.length-1; i >= 0; i--) {
- if (stack.elements[i] instanceof type) {
- return i;
- }
- }
- return -1;
- }
-
- function fosterParent(eltFunc) {
- var parent, before, lastTable = -1, lastTemplate = -1, elt;
-
- lastTable = lastElementOfType(impl.HTMLTableElement);
- lastTemplate = lastElementOfType(impl.HTMLTemplateElement);
-
- if (lastTemplate >= 0 && (lastTable < 0 || lastTemplate > lastTable)) {
- parent = stack.elements[lastTemplate];
- } else if (lastTable >= 0) {
- parent = stack.elements[lastTable].parentNode;
- if (parent) {
- before = stack.elements[lastTable];
- } else {
- parent = stack.elements[lastTable - 1];
- }
- }
- if (!parent) parent = stack.elements[0]; // the `html` element.
-
- // "If the adjusted insertion location is inside a template element,
- // let it instead be inside the template element's template contents"
- if (parent instanceof impl.HTMLTemplateElement) {
- parent = parent.content;
- }
- // Create element in the appropriate document.
- elt = eltFunc(parent.ownerDocument);
-
- if (elt.nodeType === Node.TEXT_NODE) {
- var prev;
- if (before) prev = before.previousSibling;
- else prev = parent.lastChild;
- if (prev && prev.nodeType === Node.TEXT_NODE) {
- prev.appendData(elt.data);
- return elt;
- }
- }
- if (before)
- parent.insertBefore(elt, before);
- else
- parent._appendChild(elt);
- return elt;
- }
-
-
- function resetInsertionMode() {
- var last = false;
- for(var i = stack.elements.length-1; i >= 0; i--) {
- var node = stack.elements[i];
- if (i === 0) {
- last = true;
- if (fragment) {
- node = fragmentContext;
- }
- }
- if (node.namespaceURI === NAMESPACE.HTML) {
- var tag = node.localName;
- switch(tag) {
- case "select":
- for(var j = i; j > 0; ) {
- var ancestor = stack.elements[--j];
- if (ancestor instanceof impl.HTMLTemplateElement) {
- break;
- } else if (ancestor instanceof impl.HTMLTableElement) {
- parser = in_select_in_table_mode;
- return;
- }
- }
- parser = in_select_mode;
- return;
- case "tr":
- parser = in_row_mode;
- return;
- case "tbody":
- case "tfoot":
- case "thead":
- parser = in_table_body_mode;
- return;
- case "caption":
- parser = in_caption_mode;
- return;
- case "colgroup":
- parser = in_column_group_mode;
- return;
- case "table":
- parser = in_table_mode;
- return;
- case "template":
- parser = templateInsertionModes[templateInsertionModes.length-1];
- return;
- case "body":
- parser = in_body_mode;
- return;
- case "frameset":
- parser = in_frameset_mode;
- return;
- case "html":
- if (head_element_pointer === null) {
- parser = before_head_mode;
- } else {
- parser = after_head_mode;
- }
- return;
- default:
- if (!last) {
- if (tag === "head") {
- parser = in_head_mode;
- return;
- }
- if (tag === "td" || tag === "th") {
- parser = in_cell_mode;
- return;
- }
- }
- }
- }
- if (last) {
- parser = in_body_mode;
- return;
- }
- }
- }
-
-
- function parseRawText(name, attrs) {
- insertHTMLElement(name, attrs);
- tokenizer = rawtext_state;
- originalInsertionMode = parser;
- parser = text_mode;
- }
-
- function parseRCDATA(name, attrs) {
- insertHTMLElement(name, attrs);
- tokenizer = rcdata_state;
- originalInsertionMode = parser;
- parser = text_mode;
- }
-
- // Make a copy of element i on the list of active formatting
- // elements, using its original attributes, not current
- // attributes (which may have been modified by a script)
- function afeclone(doc, i) {
- return {
- elt: createHTMLElt(doc, afe.list[i].localName, afe.attrs[i]),
- attrs: afe.attrs[i],
- };
- }
-
-
- function afereconstruct() {
- if (afe.list.length === 0) return;
- var entry = afe.list[afe.list.length-1];
- // If the last is a marker , do nothing
- if (entry === afe.MARKER) return;
- // Or if it is an open element, do nothing
- if (stack.elements.lastIndexOf(entry) !== -1) return;
-
- // Loop backward through the list until we find a marker or an
- // open element, and then move forward one from there.
- for(var i = afe.list.length-2; i >= 0; i--) {
- entry = afe.list[i];
- if (entry === afe.MARKER) break;
- if (stack.elements.lastIndexOf(entry) !== -1) break;
- }
-
- // Now loop forward, starting from the element after the current
- // one, recreating formatting elements and pushing them back onto
- // the list of open elements
- for(i = i+1; i < afe.list.length; i++) {
- var newelt = insertElement(function(doc) { return afeclone(doc, i).elt; });
- afe.list[i] = newelt;
- }
- }
-
- // Used by the adoptionAgency() function
- var BOOKMARK = {localName:"BM"};
-
- function adoptionAgency(tag) {
- // If the current node is an HTML element whose tag name is subject,
- // and the current node is not in the list of active formatting
- // elements, then pop the current node off the stack of open
- // elements and abort these steps.
- if (isA(stack.top, tag) && afe.indexOf(stack.top) === -1) {
- stack.pop();
- return true; // no more handling required
- }
-
- // Let outer loop counter be zero.
- var outer = 0;
-
- // Outer loop: If outer loop counter is greater than or
- // equal to eight, then abort these steps.
- while(outer < 8) {
- // Increment outer loop counter by one.
- outer++;
-
- // Let the formatting element be the last element in the list
- // of active formatting elements that: is between the end of
- // the list and the last scope marker in the list, if any, or
- // the start of the list otherwise, and has the same tag name
- // as the token.
- var fmtelt = afe.findElementByTag(tag);
-
- // If there is no such node, then abort these steps and instead
- // act as described in the "any other end tag" entry below.
- if (!fmtelt) {
- return false; // false means handle by the default case
- }
-
- // Otherwise, if there is such a node, but that node is not in
- // the stack of open elements, then this is a parse error;
- // remove the element from the list, and abort these steps.
- var index = stack.elements.lastIndexOf(fmtelt);
- if (index === -1) {
- afe.remove(fmtelt);
- return true; // true means no more handling required
- }
-
- // Otherwise, if there is such a node, and that node is also in
- // the stack of open elements, but the element is not in scope,
- // then this is a parse error; ignore the token, and abort
- // these steps.
- if (!stack.elementInScope(fmtelt)) {
- return true;
- }
-
- // Let the furthest block be the topmost node in the stack of
- // open elements that is lower in the stack than the formatting
- // element, and is an element in the special category. There
- // might not be one.
- var furthestblock = null, furthestblockindex;
- for(var i = index+1; i < stack.elements.length; i++) {
- if (isA(stack.elements[i], specialSet)) {
- furthestblock = stack.elements[i];
- furthestblockindex = i;
- break;
- }
- }
-
- // If there is no furthest block, then the UA must skip the
- // subsequent steps and instead just pop all the nodes from the
- // bottom of the stack of open elements, from the current node
- // up to and including the formatting element, and remove the
- // formatting element from the list of active formatting
- // elements.
- if (!furthestblock) {
- stack.popElement(fmtelt);
- afe.remove(fmtelt);
- return true;
- }
- else {
- // Let the common ancestor be the element immediately above
- // the formatting element in the stack of open elements.
- var ancestor = stack.elements[index-1];
-
- // Let a bookmark note the position of the formatting
- // element in the list of active formatting elements
- // relative to the elements on either side of it in the
- // list.
- afe.insertAfter(fmtelt, BOOKMARK);
-
- // Let node and last node be the furthest block.
- var node = furthestblock;
- var lastnode = furthestblock;
- var nodeindex = furthestblockindex;
- var nodeafeindex;
-
- // Let inner loop counter be zero.
- var inner = 0;
-
- while (true) {
-
- // Increment inner loop counter by one.
- inner++;
-
- // Let node be the element immediately above node in
- // the stack of open elements, or if node is no longer
- // in the stack of open elements (e.g. because it got
- // removed by this algorithm), the element that was
- // immediately above node in the stack of open elements
- // before node was removed.
- node = stack.elements[--nodeindex];
-
- // If node is the formatting element, then go
- // to the next step in the overall algorithm.
- if (node === fmtelt) break;
-
- // If the inner loop counter is greater than three and node
- // is in the list of active formatting elements, then remove
- // node from the list of active formatting elements.
- nodeafeindex = afe.indexOf(node);
- if (inner > 3 && nodeafeindex !== -1) {
- afe.remove(node);
- nodeafeindex = -1;
- }
-
- // If node is not in the list of active formatting
- // elements, then remove node from the stack of open
- // elements and then go back to the step labeled inner
- // loop.
- if (nodeafeindex === -1) {
- stack.removeElement(node);
- continue;
- }
-
- // Create an element for the token for which the
- // element node was created with common ancestor as
- // the intended parent, replace the entry for node
- // in the list of active formatting elements with an
- // entry for the new element, replace the entry for
- // node in the stack of open elements with an entry for
- // the new element, and let node be the new element.
- var newelt = afeclone(ancestor.ownerDocument, nodeafeindex);
- afe.replace(node, newelt.elt, newelt.attrs);
- stack.elements[nodeindex] = newelt.elt;
- node = newelt.elt;
-
- // If last node is the furthest block, then move the
- // aforementioned bookmark to be immediately after the
- // new node in the list of active formatting elements.
- if (lastnode === furthestblock) {
- afe.remove(BOOKMARK);
- afe.insertAfter(newelt.elt, BOOKMARK);
- }
-
- // Insert last node into node, first removing it from
- // its previous parent node if any.
- node._appendChild(lastnode);
-
- // Let last node be node.
- lastnode = node;
- }
-
- // If the common ancestor node is a table, tbody, tfoot,
- // thead, or tr element, then, foster parent whatever last
- // node ended up being in the previous step, first removing
- // it from its previous parent node if any.
- if (foster_parent_mode && isA(ancestor, tablesectionrowSet)) {
- fosterParent(function() { return lastnode; });
- }
- // Otherwise, append whatever last node ended up being in
- // the previous step to the common ancestor node, first
- // removing it from its previous parent node if any.
- else if (ancestor instanceof impl.HTMLTemplateElement) {
- ancestor.content._appendChild(lastnode);
- } else {
- ancestor._appendChild(lastnode);
- }
-
- // Create an element for the token for which the
- // formatting element was created, with furthest block
- // as the intended parent.
- var newelt2 = afeclone(furthestblock.ownerDocument, afe.indexOf(fmtelt));
-
- // Take all of the child nodes of the furthest block and
- // append them to the element created in the last step.
- while(furthestblock.hasChildNodes()) {
- newelt2.elt._appendChild(furthestblock.firstChild);
- }
-
- // Append that new element to the furthest block.
- furthestblock._appendChild(newelt2.elt);
-
- // Remove the formatting element from the list of active
- // formatting elements, and insert the new element into the
- // list of active formatting elements at the position of
- // the aforementioned bookmark.
- afe.remove(fmtelt);
- afe.replace(BOOKMARK, newelt2.elt, newelt2.attrs);
-
- // Remove the formatting element from the stack of open
- // elements, and insert the new element into the stack of
- // open elements immediately below the position of the
- // furthest block in that stack.
- stack.removeElement(fmtelt);
- var pos = stack.elements.lastIndexOf(furthestblock);
- stack.elements.splice(pos+1, 0, newelt2.elt);
- }
- }
-
- return true;
- }
-
- // We do this when we get /script in in_text_mode
- function handleScriptEnd() {
- // XXX:
- // This is just a stub implementation right now and doesn't run scripts.
- // Getting this method right involves the event loop, URL resolution
- // script fetching etc. For now I just want to be able to parse
- // documents and test the parser.
-
- //var script = stack.top;
- stack.pop();
- parser = originalInsertionMode;
- //script._prepare();
- return;
-
- // XXX: here is what this method is supposed to do
-
- // Provide a stable state.
-
- // Let script be the current node (which will be a script
- // element).
-
- // Pop the current node off the stack of open elements.
-
- // Switch the insertion mode to the original insertion mode.
-
- // Let the old insertion point have the same value as the current
- // insertion point. Let the insertion point be just before the
- // next input character.
-
- // Increment the parser's script nesting level by one.
-
- // Prepare the script. This might cause some script to execute,
- // which might cause new characters to be inserted into the
- // tokenizer, and might cause the tokenizer to output more tokens,
- // resulting in a reentrant invocation of the parser.
-
- // Decrement the parser's script nesting level by one. If the
- // parser's script nesting level is zero, then set the parser
- // pause flag to false.
-
- // Let the insertion point have the value of the old insertion
- // point. (In other words, restore the insertion point to its
- // previous value. This value might be the "undefined" value.)
-
- // At this stage, if there is a pending parsing-blocking script,
- // then:
-
- // If the script nesting level is not zero:
-
- // Set the parser pause flag to true, and abort the processing
- // of any nested invocations of the tokenizer, yielding
- // control back to the caller. (Tokenization will resume when
- // the caller returns to the "outer" tree construction stage.)
-
- // The tree construction stage of this particular parser is
- // being called reentrantly, say from a call to
- // document.write().
-
- // Otherwise:
-
- // Run these steps:
-
- // Let the script be the pending parsing-blocking
- // script. There is no longer a pending
- // parsing-blocking script.
-
- // Block the tokenizer for this instance of the HTML
- // parser, such that the event loop will not run tasks
- // that invoke the tokenizer.
-
- // If the parser's Document has a style sheet that is
- // blocking scripts or the script's "ready to be
- // parser-executed" flag is not set: spin the event
- // loop until the parser's Document has no style sheet
- // that is blocking scripts and the script's "ready to
- // be parser-executed" flag is set.
-
- // Unblock the tokenizer for this instance of the HTML
- // parser, such that tasks that invoke the tokenizer
- // can again be run.
-
- // Let the insertion point be just before the next
- // input character.
-
- // Increment the parser's script nesting level by one
- // (it should be zero before this step, so this sets
- // it to one).
-
- // Execute the script.
-
- // Decrement the parser's script nesting level by
- // one. If the parser's script nesting level is zero
- // (which it always should be at this point), then set
- // the parser pause flag to false.
-
- // Let the insertion point be undefined again.
-
- // If there is once again a pending parsing-blocking
- // script, then repeat these steps from step 1.
-
-
- }
-
- function stopParsing() {
- // XXX This is just a temporary implementation to get the parser working.
- // A full implementation involves scripts and events and the event loop.
-
- // Remove the link from document to parser.
- // This is instead of "set the insertion point to undefined".
- // It means that document.write() can't write into the doc anymore.
- delete doc._parser;
-
- stack.elements.length = 0; // pop everything off
-
- // If there is a window object associated with the document
- // then trigger an load event on it
- if (doc.defaultView) {
- doc.defaultView.dispatchEvent(new impl.Event("load",{}));
- }
-
- }
-
- /****
- * Tokenizer states
- */
-
- /**
- * This file was partially mechanically generated from
- * http://www.whatwg.org/specs/web-apps/current-work/multipage/tokenization.html
- *
- * After mechanical conversion, it was further converted from
- * prose to JS by hand, but the intent is that it is a very
- * faithful rendering of the HTML tokenization spec in
- * JavaScript.
- *
- * It is not a goal of this tokenizer to detect or report
- * parse errors.
- *
- * XXX The tokenizer is supposed to work with straight UTF32
- * codepoints. But I don't think it has any dependencies on
- * any character outside of the BMP so I think it is safe to
- * pass it UTF16 characters. I don't think it will ever change
- * state in the middle of a surrogate pair.
- */
-
- /*
- * Each state is represented by a function. For most states, the
- * scanner simply passes the next character (as an integer
- * codepoint) to the current state function and automatically
- * consumes the character. If the state function can't process
- * the character it can call pushback() to push it back to the
- * scanner.
- *
- * Some states require lookahead, though. If a state function has
- * a lookahead property, then it is invoked differently. In this
- * case, the scanner invokes the function with 3 arguments: 1) the
- * next codepoint 2) a string of lookahead text 3) a boolean that
- * is true if the lookahead goes all the way to the EOF. (XXX
- * actually maybe this third is not necessary... the lookahead
- * could just include \uFFFF?)
- *
- * If the lookahead property of a state function is an integer, it
- * specifies the number of characters required. If it is a string,
- * then the scanner will scan for that string and return all
- * characters up to and including that sequence, or up to EOF. If
- * the lookahead property is a regexp, then the scanner will match
- * the regexp at the current point and return the matching string.
- *
- * States that require lookahead are responsible for explicitly
- * consuming the characters they process. They do this by
- * incrementing nextchar by the number of processed characters.
- */
- function reconsume(c, new_state) {
- tokenizer = new_state;
- nextchar--; // pushback
- }
-
- function data_state(c) {
- switch(c) {
- case 0x0026: // AMPERSAND
- return_state = data_state;
- tokenizer = character_reference_state;
- break;
- case 0x003C: // LESS-THAN SIGN
- if (emitSimpleTag()) // Shortcut for <p>, <dl>, </div> etc.
- break;
- tokenizer = tag_open_state;
- break;
- case 0x0000: // NULL
- // Usually null characters emitted by the tokenizer will be
- // ignored by the tree builder, but sometimes they'll be
- // converted to \uFFFD. I don't want to have the search every
- // string emitted to replace NULs, so I'll set a flag
- // if I've emitted a NUL.
- textrun.push(c);
- textIncludesNUL = true;
- break;
- case -1: // EOF
- emitEOF();
- break;
- default:
- // Instead of just pushing a single character and then
- // coming back to the very same place, lookahead and
- // emit everything we can at once.
- /*jshint -W030 */
- emitCharsWhile(DATATEXT) || textrun.push(c);
- break;
- }
- }
-
- function rcdata_state(c) {
- // Save the open tag so we can find a matching close tag
- switch(c) {
- case 0x0026: // AMPERSAND
- return_state = rcdata_state;
- tokenizer = character_reference_state;
- break;
- case 0x003C: // LESS-THAN SIGN
- tokenizer = rcdata_less_than_sign_state;
- break;
- case 0x0000: // NULL
- textrun.push(0xFFFD); // REPLACEMENT CHARACTER
- textIncludesNUL = true;
- break;
- case -1: // EOF
- emitEOF();
- break;
- default:
- textrun.push(c);
- break;
- }
- }
-
- function rawtext_state(c) {
- switch(c) {
- case 0x003C: // LESS-THAN SIGN
- tokenizer = rawtext_less_than_sign_state;
- break;
- case 0x0000: // NULL
- textrun.push(0xFFFD); // REPLACEMENT CHARACTER
- break;
- case -1: // EOF
- emitEOF();
- break;
- default:
- /*jshint -W030 */
- emitCharsWhile(RAWTEXT) || textrun.push(c);
- break;
- }
- }
-
- function script_data_state(c) {
- switch(c) {
- case 0x003C: // LESS-THAN SIGN
- tokenizer = script_data_less_than_sign_state;
- break;
- case 0x0000: // NULL
- textrun.push(0xFFFD); // REPLACEMENT CHARACTER
- break;
- case -1: // EOF
- emitEOF();
- break;
- default:
- /*jshint -W030 */
- emitCharsWhile(RAWTEXT) || textrun.push(c);
- break;
- }
- }
-
- function plaintext_state(c) {
- switch(c) {
- case 0x0000: // NULL
- textrun.push(0xFFFD); // REPLACEMENT CHARACTER
- break;
- case -1: // EOF
- emitEOF();
- break;
- default:
- /*jshint -W030 */
- emitCharsWhile(PLAINTEXT) || textrun.push(c);
- break;
- }
- }
-
- function tag_open_state(c) {
- switch(c) {
- case 0x0021: // EXCLAMATION MARK
- tokenizer = markup_declaration_open_state;
- break;
- case 0x002F: // SOLIDUS
- tokenizer = end_tag_open_state;
- break;
- case 0x0041: // [A-Z]
- case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:
- case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:
- case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
- case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
- case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
- case 0x0061: // [a-z]
- case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:
- case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:
- case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:
- case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
- case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
- beginTagName();
- reconsume(c, tag_name_state);
- break;
- case 0x003F: // QUESTION MARK
- reconsume(c, bogus_comment_state);
- break;
- default:
- textrun.push(0x003C); // LESS-THAN SIGN
- reconsume(c, data_state);
- break;
- }
- }
-
- function end_tag_open_state(c) {
- switch(c) {
- case 0x0041: // [A-Z]
- case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:
- case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:
- case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
- case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
- case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
- case 0x0061: // [a-z]
- case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:
- case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:
- case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:
- case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
- case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
- beginEndTagName();
- reconsume(c, tag_name_state);
- break;
- case 0x003E: // GREATER-THAN SIGN
- tokenizer = data_state;
- break;
- case -1: // EOF
- textrun.push(0x003C); // LESS-THAN SIGN
- textrun.push(0x002F); // SOLIDUS
- emitEOF();
- break;
- default:
- reconsume(c, bogus_comment_state);
- break;
- }
- }
-
- function tag_name_state(c) {
- switch(c) {
- case 0x0009: // CHARACTER TABULATION (tab)
- case 0x000A: // LINE FEED (LF)
- case 0x000C: // FORM FEED (FF)
- case 0x0020: // SPACE
- tokenizer = before_attribute_name_state;
- break;
- case 0x002F: // SOLIDUS
- tokenizer = self_closing_start_tag_state;
- break;
- case 0x003E: // GREATER-THAN SIGN
- tokenizer = data_state;
- emitTag();
- break;
- case 0x0041: // [A-Z]
- case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:
- case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:
- case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
- case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
- case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
- tagnamebuf += String.fromCharCode(c + 0x0020);
- break;
- case 0x0000: // NULL
- tagnamebuf += String.fromCharCode(0xFFFD /* REPLACEMENT CHARACTER */);
- break;
- case -1: // EOF
- emitEOF();
- break;
- default:
- tagnamebuf += getMatchingChars(TAGNAME);
- break;
- }
- }
-
- function rcdata_less_than_sign_state(c) {
- /* identical to the RAWTEXT less-than sign state, except s/RAWTEXT/RCDATA/g */
- if (c === 0x002F) { // SOLIDUS
- beginTempBuf();
- tokenizer = rcdata_end_tag_open_state;
- }
- else {
- textrun.push(0x003C); // LESS-THAN SIGN
- reconsume(c, rcdata_state);
- }
- }
-
- function rcdata_end_tag_open_state(c) {
- /* identical to the RAWTEXT (and Script data) end tag open state, except s/RAWTEXT/RCDATA/g */
- switch(c) {
- case 0x0041: // [A-Z]
- case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:
- case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:
- case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
- case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
- case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
- case 0x0061: // [a-z]
- case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:
- case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:
- case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:
- case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
- case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
- beginEndTagName();
- reconsume(c, rcdata_end_tag_name_state);
- break;
- default:
- textrun.push(0x003C); // LESS-THAN SIGN
- textrun.push(0x002F); // SOLIDUS
- reconsume(c, rcdata_state);
- break;
- }
- }
-
- function rcdata_end_tag_name_state(c) {
- /* identical to the RAWTEXT (and Script data) end tag name state, except s/RAWTEXT/RCDATA/g */
- switch(c) {
- case 0x0009: // CHARACTER TABULATION (tab)
- case 0x000A: // LINE FEED (LF)
- case 0x000C: // FORM FEED (FF)
- case 0x0020: // SPACE
- if (appropriateEndTag(tagnamebuf)) {
- tokenizer = before_attribute_name_state;
- return;
- }
- break;
- case 0x002F: // SOLIDUS
- if (appropriateEndTag(tagnamebuf)) {
- tokenizer = self_closing_start_tag_state;
- return;
- }
- break;
- case 0x003E: // GREATER-THAN SIGN
- if (appropriateEndTag(tagnamebuf)) {
- tokenizer = data_state;
- emitTag();
- return;
- }
- break;
- case 0x0041: // [A-Z]
- case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:
- case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:
- case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
- case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
- case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
-
- tagnamebuf += String.fromCharCode(c + 0x0020);
- tempbuf.push(c);
- return;
- case 0x0061: // [a-z]
- case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:
- case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:
- case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:
- case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
- case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
-
- tagnamebuf += String.fromCharCode(c);
- tempbuf.push(c);
- return;
- default:
- break;
- }
-
- // If we don't return in one of the cases above, then this was not
- // an appropriately matching close tag, so back out by emitting all
- // the characters as text
- textrun.push(0x003C); // LESS-THAN SIGN
- textrun.push(0x002F); // SOLIDUS
- pushAll(textrun, tempbuf);
- reconsume(c, rcdata_state);
- }
-
- function rawtext_less_than_sign_state(c) {
- /* identical to the RCDATA less-than sign state, except s/RCDATA/RAWTEXT/g
- */
- if (c === 0x002F) { // SOLIDUS
- beginTempBuf();
- tokenizer = rawtext_end_tag_open_state;
- }
- else {
- textrun.push(0x003C); // LESS-THAN SIGN
- reconsume(c, rawtext_state);
- }
- }
-
- function rawtext_end_tag_open_state(c) {
- /* identical to the RCDATA (and Script data) end tag open state, except s/RCDATA/RAWTEXT/g */
- switch(c) {
- case 0x0041: // [A-Z]
- case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:
- case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:
- case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
- case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
- case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
- case 0x0061: // [a-z]
- case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:
- case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:
- case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:
- case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
- case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
- beginEndTagName();
- reconsume(c, rawtext_end_tag_name_state);
- break;
- default:
- textrun.push(0x003C); // LESS-THAN SIGN
- textrun.push(0x002F); // SOLIDUS
- reconsume(c, rawtext_state);
- break;
- }
- }
-
- function rawtext_end_tag_name_state(c) {
- /* identical to the RCDATA (and Script data) end tag name state, except s/RCDATA/RAWTEXT/g */
- switch(c) {
- case 0x0009: // CHARACTER TABULATION (tab)
- case 0x000A: // LINE FEED (LF)
- case 0x000C: // FORM FEED (FF)
- case 0x0020: // SPACE
- if (appropriateEndTag(tagnamebuf)) {
- tokenizer = before_attribute_name_state;
- return;
- }
- break;
- case 0x002F: // SOLIDUS
- if (appropriateEndTag(tagnamebuf)) {
- tokenizer = self_closing_start_tag_state;
- return;
- }
- break;
- case 0x003E: // GREATER-THAN SIGN
- if (appropriateEndTag(tagnamebuf)) {
- tokenizer = data_state;
- emitTag();
- return;
- }
- break;
- case 0x0041: // [A-Z]
- case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:
- case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:
- case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
- case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
- case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
- tagnamebuf += String.fromCharCode(c + 0x0020);
- tempbuf.push(c);
- return;
- case 0x0061: // [a-z]
- case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:
- case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:
- case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:
- case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
- case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
- tagnamebuf += String.fromCharCode(c);
- tempbuf.push(c);
- return;
- default:
- break;
- }
-
- // If we don't return in one of the cases above, then this was not
- // an appropriately matching close tag, so back out by emitting all
- // the characters as text
- textrun.push(0x003C); // LESS-THAN SIGN
- textrun.push(0x002F); // SOLIDUS
- pushAll(textrun,tempbuf);
- reconsume(c, rawtext_state);
- }
-
- function script_data_less_than_sign_state(c) {
- switch(c) {
- case 0x002F: // SOLIDUS
- beginTempBuf();
- tokenizer = script_data_end_tag_open_state;
- break;
- case 0x0021: // EXCLAMATION MARK
- tokenizer = script_data_escape_start_state;
- textrun.push(0x003C); // LESS-THAN SIGN
- textrun.push(0x0021); // EXCLAMATION MARK
- break;
- default:
- textrun.push(0x003C); // LESS-THAN SIGN
- reconsume(c, script_data_state);
- break;
- }
- }
-
- function script_data_end_tag_open_state(c) {
- /* identical to the RCDATA (and RAWTEXT) end tag open state, except s/RCDATA/Script data/g */
- switch(c) {
- case 0x0041: // [A-Z]
- case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:
- case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:
- case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
- case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
- case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
- case 0x0061: // [a-z]
- case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:
- case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:
- case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:
- case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
- case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
- beginEndTagName();
- reconsume(c, script_data_end_tag_name_state);
- break;
- default:
- textrun.push(0x003C); // LESS-THAN SIGN
- textrun.push(0x002F); // SOLIDUS
- reconsume(c, script_data_state);
- break;
- }
- }
-
- function script_data_end_tag_name_state(c) {
- /* identical to the RCDATA (and RAWTEXT) end tag name state, except s/RCDATA/Script data/g */
- switch(c) {
- case 0x0009: // CHARACTER TABULATION (tab)
- case 0x000A: // LINE FEED (LF)
- case 0x000C: // FORM FEED (FF)
- case 0x0020: // SPACE
- if (appropriateEndTag(tagnamebuf)) {
- tokenizer = before_attribute_name_state;
- return;
- }
- break;
- case 0x002F: // SOLIDUS
- if (appropriateEndTag(tagnamebuf)) {
- tokenizer = self_closing_start_tag_state;
- return;
- }
- break;
- case 0x003E: // GREATER-THAN SIGN
- if (appropriateEndTag(tagnamebuf)) {
- tokenizer = data_state;
- emitTag();
- return;
- }
- break;
- case 0x0041: // [A-Z]
- case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:
- case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:
- case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
- case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
- case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
-
- tagnamebuf += String.fromCharCode(c + 0x0020);
- tempbuf.push(c);
- return;
- case 0x0061: // [a-z]
- case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:
- case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:
- case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:
- case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
- case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
-
- tagnamebuf += String.fromCharCode(c);
- tempbuf.push(c);
- return;
- default:
- break;
- }
-
- // If we don't return in one of the cases above, then this was not
- // an appropriately matching close tag, so back out by emitting all
- // the characters as text
- textrun.push(0x003C); // LESS-THAN SIGN
- textrun.push(0x002F); // SOLIDUS
- pushAll(textrun,tempbuf);
- reconsume(c, script_data_state);
- }
-
- function script_data_escape_start_state(c) {
- if (c === 0x002D) { // HYPHEN-MINUS
- tokenizer = script_data_escape_start_dash_state;
- textrun.push(0x002D); // HYPHEN-MINUS
- }
- else {
- reconsume(c, script_data_state);
- }
- }
-
- function script_data_escape_start_dash_state(c) {
- if (c === 0x002D) { // HYPHEN-MINUS
- tokenizer = script_data_escaped_dash_dash_state;
- textrun.push(0x002D); // HYPHEN-MINUS
- }
- else {
- reconsume(c, script_data_state);
- }
- }
-
- function script_data_escaped_state(c) {
- switch(c) {
- case 0x002D: // HYPHEN-MINUS
- tokenizer = script_data_escaped_dash_state;
- textrun.push(0x002D); // HYPHEN-MINUS
- break;
- case 0x003C: // LESS-THAN SIGN
- tokenizer = script_data_escaped_less_than_sign_state;
- break;
- case 0x0000: // NULL
- textrun.push(0xFFFD); // REPLACEMENT CHARACTER
- break;
- case -1: // EOF
- emitEOF();
- break;
- default:
- textrun.push(c);
- break;
- }
- }
-
- function script_data_escaped_dash_state(c) {
- switch(c) {
- case 0x002D: // HYPHEN-MINUS
- tokenizer = script_data_escaped_dash_dash_state;
- textrun.push(0x002D); // HYPHEN-MINUS
- break;
- case 0x003C: // LESS-THAN SIGN
- tokenizer = script_data_escaped_less_than_sign_state;
- break;
- case 0x0000: // NULL
- tokenizer = script_data_escaped_state;
- textrun.push(0xFFFD); // REPLACEMENT CHARACTER
- break;
- case -1: // EOF
- emitEOF();
- break;
- default:
- tokenizer = script_data_escaped_state;
- textrun.push(c);
- break;
- }
- }
-
- function script_data_escaped_dash_dash_state(c) {
- switch(c) {
- case 0x002D: // HYPHEN-MINUS
- textrun.push(0x002D); // HYPHEN-MINUS
- break;
- case 0x003C: // LESS-THAN SIGN
- tokenizer = script_data_escaped_less_than_sign_state;
- break;
- case 0x003E: // GREATER-THAN SIGN
- tokenizer = script_data_state;
- textrun.push(0x003E); // GREATER-THAN SIGN
- break;
- case 0x0000: // NULL
- tokenizer = script_data_escaped_state;
- textrun.push(0xFFFD); // REPLACEMENT CHARACTER
- break;
- case -1: // EOF
- emitEOF();
- break;
- default:
- tokenizer = script_data_escaped_state;
- textrun.push(c);
- break;
- }
- }
-
- function script_data_escaped_less_than_sign_state(c) {
- switch(c) {
- case 0x002F: // SOLIDUS
- beginTempBuf();
- tokenizer = script_data_escaped_end_tag_open_state;
- break;
- case 0x0041: // [A-Z]
- case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:
- case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:
- case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
- case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
- case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
- case 0x0061: // [a-z]
- case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:
- case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:
- case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:
- case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
- case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
- beginTempBuf();
- textrun.push(0x003C); // LESS-THAN SIGN
- reconsume(c, script_data_double_escape_start_state);
- break;
- default:
- textrun.push(0x003C); // LESS-THAN SIGN
- reconsume(c, script_data_escaped_state);
- break;
- }
- }
-
- function script_data_escaped_end_tag_open_state(c) {
- switch(c) {
- case 0x0041: // [A-Z]
- case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:
- case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:
- case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
- case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
- case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
- case 0x0061: // [a-z]
- case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:
- case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:
- case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:
- case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
- case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
- beginEndTagName();
- reconsume(c, script_data_escaped_end_tag_name_state);
- break;
- default:
- textrun.push(0x003C); // LESS-THAN SIGN
- textrun.push(0x002F); // SOLIDUS
- reconsume(c, script_data_escaped_state);
- break;
- }
- }
-
- function script_data_escaped_end_tag_name_state(c) {
- switch(c) {
- case 0x0009: // CHARACTER TABULATION (tab)
- case 0x000A: // LINE FEED (LF)
- case 0x000C: // FORM FEED (FF)
- case 0x0020: // SPACE
- if (appropriateEndTag(tagnamebuf)) {
- tokenizer = before_attribute_name_state;
- return;
- }
- break;
- case 0x002F: // SOLIDUS
- if (appropriateEndTag(tagnamebuf)) {
- tokenizer = self_closing_start_tag_state;
- return;
- }
- break;
- case 0x003E: // GREATER-THAN SIGN
- if (appropriateEndTag(tagnamebuf)) {
- tokenizer = data_state;
- emitTag();
- return;
- }
- break;
- case 0x0041: // [A-Z]
- case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:
- case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:
- case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
- case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
- case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
- tagnamebuf += String.fromCharCode(c + 0x0020);
- tempbuf.push(c);
- return;
- case 0x0061: // [a-z]
- case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:
- case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:
- case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:
- case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
- case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
- tagnamebuf += String.fromCharCode(c);
- tempbuf.push(c);
- return;
- default:
- break;
- }
-
- // We get here in the default case, and if the closing tagname
- // is not an appropriate tagname.
- textrun.push(0x003C); // LESS-THAN SIGN
- textrun.push(0x002F); // SOLIDUS
- pushAll(textrun,tempbuf);
- reconsume(c, script_data_escaped_state);
- }
-
- function script_data_double_escape_start_state(c) {
- switch(c) {
- case 0x0009: // CHARACTER TABULATION (tab)
- case 0x000A: // LINE FEED (LF)
- case 0x000C: // FORM FEED (FF)
- case 0x0020: // SPACE
- case 0x002F: // SOLIDUS
- case 0x003E: // GREATER-THAN SIGN
- if (buf2str(tempbuf) === "script") {
- tokenizer = script_data_double_escaped_state;
- }
- else {
- tokenizer = script_data_escaped_state;
- }
- textrun.push(c);
- break;
- case 0x0041: // [A-Z]
- case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:
- case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:
- case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
- case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
- case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
- tempbuf.push(c + 0x0020);
- textrun.push(c);
- break;
- case 0x0061: // [a-z]
- case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:
- case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:
- case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:
- case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
- case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
- tempbuf.push(c);
- textrun.push(c);
- break;
- default:
- reconsume(c, script_data_escaped_state);
- break;
- }
- }
-
- function script_data_double_escaped_state(c) {
- switch(c) {
- case 0x002D: // HYPHEN-MINUS
- tokenizer = script_data_double_escaped_dash_state;
- textrun.push(0x002D); // HYPHEN-MINUS
- break;
- case 0x003C: // LESS-THAN SIGN
- tokenizer = script_data_double_escaped_less_than_sign_state;
- textrun.push(0x003C); // LESS-THAN SIGN
- break;
- case 0x0000: // NULL
- textrun.push(0xFFFD); // REPLACEMENT CHARACTER
- break;
- case -1: // EOF
- emitEOF();
- break;
- default:
- textrun.push(c);
- break;
- }
- }
-
- function script_data_double_escaped_dash_state(c) {
- switch(c) {
- case 0x002D: // HYPHEN-MINUS
- tokenizer = script_data_double_escaped_dash_dash_state;
- textrun.push(0x002D); // HYPHEN-MINUS
- break;
- case 0x003C: // LESS-THAN SIGN
- tokenizer = script_data_double_escaped_less_than_sign_state;
- textrun.push(0x003C); // LESS-THAN SIGN
- break;
- case 0x0000: // NULL
- tokenizer = script_data_double_escaped_state;
- textrun.push(0xFFFD); // REPLACEMENT CHARACTER
- break;
- case -1: // EOF
- emitEOF();
- break;
- default:
- tokenizer = script_data_double_escaped_state;
- textrun.push(c);
- break;
- }
- }
-
- function script_data_double_escaped_dash_dash_state(c) {
- switch(c) {
- case 0x002D: // HYPHEN-MINUS
- textrun.push(0x002D); // HYPHEN-MINUS
- break;
- case 0x003C: // LESS-THAN SIGN
- tokenizer = script_data_double_escaped_less_than_sign_state;
- textrun.push(0x003C); // LESS-THAN SIGN
- break;
- case 0x003E: // GREATER-THAN SIGN
- tokenizer = script_data_state;
- textrun.push(0x003E); // GREATER-THAN SIGN
- break;
- case 0x0000: // NULL
- tokenizer = script_data_double_escaped_state;
- textrun.push(0xFFFD); // REPLACEMENT CHARACTER
- break;
- case -1: // EOF
- emitEOF();
- break;
- default:
- tokenizer = script_data_double_escaped_state;
- textrun.push(c);
- break;
- }
- }
-
- function script_data_double_escaped_less_than_sign_state(c) {
- if (c === 0x002F) { // SOLIDUS
- beginTempBuf();
- tokenizer = script_data_double_escape_end_state;
- textrun.push(0x002F); // SOLIDUS
- }
- else {
- reconsume(c, script_data_double_escaped_state);
- }
- }
-
- function script_data_double_escape_end_state(c) {
- switch(c) {
- case 0x0009: // CHARACTER TABULATION (tab)
- case 0x000A: // LINE FEED (LF)
- case 0x000C: // FORM FEED (FF)
- case 0x0020: // SPACE
- case 0x002F: // SOLIDUS
- case 0x003E: // GREATER-THAN SIGN
- if (buf2str(tempbuf) === "script") {
- tokenizer = script_data_escaped_state;
- }
- else {
- tokenizer = script_data_double_escaped_state;
- }
- textrun.push(c);
- break;
- case 0x0041: // [A-Z]
- case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:
- case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:
- case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
- case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
- case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
- tempbuf.push(c + 0x0020);
- textrun.push(c);
- break;
- case 0x0061: // [a-z]
- case 0x0062:case 0x0063:case 0x0064:case 0x0065:case 0x0066:
- case 0x0067:case 0x0068:case 0x0069:case 0x006A:case 0x006B:
- case 0x006C:case 0x006D:case 0x006E:case 0x006F:case 0x0070:
- case 0x0071:case 0x0072:case 0x0073:case 0x0074:case 0x0075:
- case 0x0076:case 0x0077:case 0x0078:case 0x0079:case 0x007A:
- tempbuf.push(c);
- textrun.push(c);
- break;
- default:
- reconsume(c, script_data_double_escaped_state);
- break;
- }
- }
-
- function before_attribute_name_state(c) {
- switch(c) {
- case 0x0009: // CHARACTER TABULATION (tab)
- case 0x000A: // LINE FEED (LF)
- case 0x000C: // FORM FEED (FF)
- case 0x0020: // SPACE
- /* Ignore the character. */
- break;
- // For SOLIDUS, GREATER-THAN SIGN, and EOF, spec says "reconsume in
- // the after attribute name state", but in our implementation that
- // state always has an active attribute in attrnamebuf. Just clone
- // the rules here, without the addAttribute business.
- case 0x002F: // SOLIDUS
- tokenizer = self_closing_start_tag_state;
- break;
- case 0x003E: // GREATER-THAN SIGN
- tokenizer = data_state;
- emitTag();
- break;
- case -1: // EOF
- emitEOF();
- break;
- case 0x003D: // EQUALS SIGN
- beginAttrName();
- attrnamebuf += String.fromCharCode(c);
- tokenizer = attribute_name_state;
- break;
- default:
- if (handleSimpleAttribute()) break;
- beginAttrName();
- reconsume(c, attribute_name_state);
- break;
- }
- }
-
- // beginAttrName() must have been called before this point
- // There is an active attribute in attrnamebuf (but not attrvaluebuf)
- function attribute_name_state(c) {
- switch(c) {
- case 0x0009: // CHARACTER TABULATION (tab)
- case 0x000A: // LINE FEED (LF)
- case 0x000C: // FORM FEED (FF)
- case 0x0020: // SPACE
- case 0x002F: // SOLIDUS
- case 0x003E: // GREATER-THAN SIGN
- case -1: // EOF
- reconsume(c, after_attribute_name_state);
- break;
- case 0x003D: // EQUALS SIGN
- tokenizer = before_attribute_value_state;
- break;
- case 0x0041: // [A-Z]
- case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:
- case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:
- case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
- case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
- case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
- attrnamebuf += String.fromCharCode(c + 0x0020);
- break;
- case 0x0000: // NULL
- attrnamebuf += String.fromCharCode(0xFFFD /* REPLACEMENT CHARACTER */);
- break;
- case 0x0022: // QUOTATION MARK
- case 0x0027: // APOSTROPHE
- case 0x003C: // LESS-THAN SIGN
- /* falls through */
- default:
- attrnamebuf += getMatchingChars(ATTRNAME);
- break;
- }
- }
-
- // There is an active attribute in attrnamebuf, but not yet in attrvaluebuf.
- function after_attribute_name_state(c) {
- switch(c) {
- case 0x0009: // CHARACTER TABULATION (tab)
- case 0x000A: // LINE FEED (LF)
- case 0x000C: // FORM FEED (FF)
- case 0x0020: // SPACE
- /* Ignore the character. */
- break;
- case 0x002F: // SOLIDUS
- // Keep in sync with before_attribute_name_state.
- addAttribute(attrnamebuf);
- tokenizer = self_closing_start_tag_state;
- break;
- case 0x003D: // EQUALS SIGN
- tokenizer = before_attribute_value_state;
- break;
- case 0x003E: // GREATER-THAN SIGN
- // Keep in sync with before_attribute_name_state.
- tokenizer = data_state;
- addAttribute(attrnamebuf);
- emitTag();
- break;
- case -1: // EOF
- // Keep in sync with before_attribute_name_state.
- addAttribute(attrnamebuf);
- emitEOF();
- break;
- default:
- addAttribute(attrnamebuf);
- beginAttrName();
- reconsume(c, attribute_name_state);
- break;
- }
- }
-
- function before_attribute_value_state(c) {
- switch(c) {
- case 0x0009: // CHARACTER TABULATION (tab)
- case 0x000A: // LINE FEED (LF)
- case 0x000C: // FORM FEED (FF)
- case 0x0020: // SPACE
- /* Ignore the character. */
- break;
- case 0x0022: // QUOTATION MARK
- beginAttrValue();
- tokenizer = attribute_value_double_quoted_state;
- break;
- case 0x0027: // APOSTROPHE
- beginAttrValue();
- tokenizer = attribute_value_single_quoted_state;
- break;
- case 0x003E: // GREATER-THAN SIGN
- /* falls through */
- default:
- beginAttrValue();
- reconsume(c, attribute_value_unquoted_state);
- break;
- }
- }
-
- function attribute_value_double_quoted_state(c) {
- switch(c) {
- case 0x0022: // QUOTATION MARK
- addAttribute(attrnamebuf, attrvaluebuf);
- tokenizer = after_attribute_value_quoted_state;
- break;
- case 0x0026: // AMPERSAND
- return_state = attribute_value_double_quoted_state;
- tokenizer = character_reference_state;
- break;
- case 0x0000: // NULL
- attrvaluebuf += String.fromCharCode(0xFFFD /* REPLACEMENT CHARACTER */);
- break;
- case -1: // EOF
- emitEOF();
- break;
- case 0x000A: // LF
- // this could be a converted \r, so don't use getMatchingChars
- attrvaluebuf += String.fromCharCode(c);
- break;
- default:
- attrvaluebuf += getMatchingChars(DBLQUOTEATTRVAL);
- break;
- }
- }
-
- function attribute_value_single_quoted_state(c) {
- switch(c) {
- case 0x0027: // APOSTROPHE
- addAttribute(attrnamebuf, attrvaluebuf);
- tokenizer = after_attribute_value_quoted_state;
- break;
- case 0x0026: // AMPERSAND
- return_state = attribute_value_single_quoted_state;
- tokenizer = character_reference_state;
- break;
- case 0x0000: // NULL
- attrvaluebuf += String.fromCharCode(0xFFFD /* REPLACEMENT CHARACTER */);
- break;
- case -1: // EOF
- emitEOF();
- break;
- case 0x000A: // LF
- // this could be a converted \r, so don't use getMatchingChars
- attrvaluebuf += String.fromCharCode(c);
- break;
- default:
- attrvaluebuf += getMatchingChars(SINGLEQUOTEATTRVAL);
- break;
- }
- }
-
- function attribute_value_unquoted_state(c) {
- switch(c) {
- case 0x0009: // CHARACTER TABULATION (tab)
- case 0x000A: // LINE FEED (LF)
- case 0x000C: // FORM FEED (FF)
- case 0x0020: // SPACE
- addAttribute(attrnamebuf, attrvaluebuf);
- tokenizer = before_attribute_name_state;
- break;
- case 0x0026: // AMPERSAND
- return_state = attribute_value_unquoted_state;
- tokenizer = character_reference_state;
- break;
- case 0x003E: // GREATER-THAN SIGN
- addAttribute(attrnamebuf, attrvaluebuf);
- tokenizer = data_state;
- emitTag();
- break;
- case 0x0000: // NULL
- attrvaluebuf += String.fromCharCode(0xFFFD /* REPLACEMENT CHARACTER */);
- break;
- case -1: // EOF
- nextchar--; // pushback
- tokenizer = data_state;
- break;
- case 0x0022: // QUOTATION MARK
- case 0x0027: // APOSTROPHE
- case 0x003C: // LESS-THAN SIGN
- case 0x003D: // EQUALS SIGN
- case 0x0060: // GRAVE ACCENT
- /* falls through */
- default:
- attrvaluebuf += getMatchingChars(UNQUOTEDATTRVAL);
- break;
- }
- }
-
- function after_attribute_value_quoted_state(c) {
- switch(c) {
- case 0x0009: // CHARACTER TABULATION (tab)
- case 0x000A: // LINE FEED (LF)
- case 0x000C: // FORM FEED (FF)
- case 0x0020: // SPACE
- tokenizer = before_attribute_name_state;
- break;
- case 0x002F: // SOLIDUS
- tokenizer = self_closing_start_tag_state;
- break;
- case 0x003E: // GREATER-THAN SIGN
- tokenizer = data_state;
- emitTag();
- break;
- case -1: // EOF
- emitEOF();
- break;
- default:
- reconsume(c, before_attribute_name_state);
- break;
- }
- }
-
- function self_closing_start_tag_state(c) {
- switch(c) {
- case 0x003E: // GREATER-THAN SIGN
- // Set the <i>self-closing flag</i> of the current tag token.
- tokenizer = data_state;
- emitSelfClosingTag(true);
- break;
- case -1: // EOF
- emitEOF();
- break;
- default:
- reconsume(c, before_attribute_name_state);
- break;
- }
- }
-
- function bogus_comment_state(c, lookahead, eof) {
- var len = lookahead.length;
-
- if (eof) {
- nextchar += len-1; // don't consume the eof
- }
- else {
- nextchar += len;
- }
-
- var comment = lookahead.substring(0, len-1);
-
- comment = comment.replace(/\u0000/g,"\uFFFD");
- comment = comment.replace(/\u000D\u000A/g,"\u000A");
- comment = comment.replace(/\u000D/g,"\u000A");
-
- insertToken(COMMENT, comment);
- tokenizer = data_state;
- }
- bogus_comment_state.lookahead = ">";
-
- function markup_declaration_open_state(c, lookahead, eof) {
- if (lookahead[0] === "-" && lookahead[1] === "-") {
- nextchar += 2;
- beginComment();
- tokenizer = comment_start_state;
- return;
- }
-
- if (lookahead.toUpperCase() === "DOCTYPE") {
- nextchar += 7;
- tokenizer = doctype_state;
- }
- else if (lookahead === "[CDATA[" && cdataAllowed()) {
- nextchar += 7;
- tokenizer = cdata_section_state;
- }
- else {
- tokenizer = bogus_comment_state;
- }
- }
- markup_declaration_open_state.lookahead = 7;
-
- function comment_start_state(c) {
- beginComment();
- switch(c) {
- case 0x002D: // HYPHEN-MINUS
- tokenizer = comment_start_dash_state;
- break;
- case 0x003E: // GREATER-THAN SIGN
- tokenizer = data_state;
- insertToken(COMMENT, buf2str(commentbuf));
- break; /* see comment in comment end state */
- default:
- reconsume(c, comment_state);
- break;
- }
- }
-
- function comment_start_dash_state(c) {
- switch(c) {
- case 0x002D: // HYPHEN-MINUS
- tokenizer = comment_end_state;
- break;
- case 0x003E: // GREATER-THAN SIGN
- tokenizer = data_state;
- insertToken(COMMENT, buf2str(commentbuf));
- break;
- case -1: // EOF
- insertToken(COMMENT, buf2str(commentbuf));
- emitEOF();
- break; /* see comment in comment end state */
- default:
- commentbuf.push(0x002D /* HYPHEN-MINUS */);
- reconsume(c, comment_state);
- break;
- }
- }
-
- function comment_state(c) {
- switch(c) {
- case 0x003C: // LESS-THAN SIGN
- commentbuf.push(c);
- tokenizer = comment_less_than_sign_state;
- break;
- case 0x002D: // HYPHEN-MINUS
- tokenizer = comment_end_dash_state;
- break;
- case 0x0000: // NULL
- commentbuf.push(0xFFFD /* REPLACEMENT CHARACTER */);
- break;
- case -1: // EOF
- insertToken(COMMENT, buf2str(commentbuf));
- emitEOF();
- break; /* see comment in comment end state */
- default:
- commentbuf.push(c);
- break;
- }
- }
-
- function comment_less_than_sign_state(c) {
- switch(c) {
- case 0x0021: // EXCLAMATION MARK
- commentbuf.push(c);
- tokenizer = comment_less_than_sign_bang_state;
- break;
- case 0x003C: // LESS-THAN SIGN
- commentbuf.push(c);
- break;
- default:
- reconsume(c, comment_state);
- break;
- }
- }
-
- function comment_less_than_sign_bang_state(c) {
- switch(c) {
- case 0x002D: // HYPHEN-MINUS
- tokenizer = comment_less_than_sign_bang_dash_state;
- break;
- default:
- reconsume(c, comment_state);
- break;
- }
- }
-
- function comment_less_than_sign_bang_dash_state(c) {
- switch(c) {
- case 0x002D: // HYPHEN-MINUS
- tokenizer = comment_less_than_sign_bang_dash_dash_state;
- break;
- default:
- reconsume(c, comment_end_dash_state);
- break;
- }
- }
-
- function comment_less_than_sign_bang_dash_dash_state(c) {
- switch(c) {
- case 0x003E: // GREATER-THAN SIGN
- case -1: // EOF
- reconsume(c, comment_end_state);
- break;
- default:
- // parse error
- reconsume(c, comment_end_state);
- break;
- }
- }
-
- function comment_end_dash_state(c) {
- switch(c) {
- case 0x002D: // HYPHEN-MINUS
- tokenizer = comment_end_state;
- break;
- case -1: // EOF
- insertToken(COMMENT, buf2str(commentbuf));
- emitEOF();
- break; /* see comment in comment end state */
- default:
- commentbuf.push(0x002D /* HYPHEN-MINUS */);
- reconsume(c, comment_state);
- break;
- }
- }
-
- function comment_end_state(c) {
- switch(c) {
- case 0x003E: // GREATER-THAN SIGN
- tokenizer = data_state;
- insertToken(COMMENT, buf2str(commentbuf));
- break;
- case 0x0021: // EXCLAMATION MARK
- tokenizer = comment_end_bang_state;
- break;
- case 0x002D: // HYPHEN-MINUS
- commentbuf.push(0x002D);
- break;
- case -1: // EOF
- insertToken(COMMENT, buf2str(commentbuf));
- emitEOF();
- break; /* For security reasons: otherwise, hostile user could put a script in a comment e.g. in a blog comment and then DOS the server so that the end tag isn't read, and then the commented script tag would be treated as live code */
- default:
- commentbuf.push(0x002D);
- commentbuf.push(0x002D);
- reconsume(c, comment_state);
- break;
- }
- }
-
- function comment_end_bang_state(c) {
- switch(c) {
- case 0x002D: // HYPHEN-MINUS
- commentbuf.push(0x002D);
- commentbuf.push(0x002D);
- commentbuf.push(0x0021);
- tokenizer = comment_end_dash_state;
- break;
- case 0x003E: // GREATER-THAN SIGN
- tokenizer = data_state;
- insertToken(COMMENT, buf2str(commentbuf));
- break;
- case -1: // EOF
- insertToken(COMMENT, buf2str(commentbuf));
- emitEOF();
- break; /* see comment in comment end state */
- default:
- commentbuf.push(0x002D);
- commentbuf.push(0x002D);
- commentbuf.push(0x0021);
- reconsume(c, comment_state);
- break;
- }
- }
-
- function doctype_state(c) {
- switch(c) {
- case 0x0009: // CHARACTER TABULATION (tab)
- case 0x000A: // LINE FEED (LF)
- case 0x000C: // FORM FEED (FF)
- case 0x0020: // SPACE
- tokenizer = before_doctype_name_state;
- break;
- case -1: // EOF
- beginDoctype();
- forcequirks();
- emitDoctype();
- emitEOF();
- break;
- default:
- reconsume(c, before_doctype_name_state);
- break;
- }
- }
-
- function before_doctype_name_state(c) {
- switch(c) {
- case 0x0009: // CHARACTER TABULATION (tab)
- case 0x000A: // LINE FEED (LF)
- case 0x000C: // FORM FEED (FF)
- case 0x0020: // SPACE
- /* Ignore the character. */
- break;
- case 0x0041: // [A-Z]
- case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:
- case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:
- case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
- case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
- case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
- beginDoctype();
- doctypenamebuf.push(c + 0x0020);
- tokenizer = doctype_name_state;
- break;
- case 0x0000: // NULL
- beginDoctype();
- doctypenamebuf.push(0xFFFD);
- tokenizer = doctype_name_state;
- break;
- case 0x003E: // GREATER-THAN SIGN
- beginDoctype();
- forcequirks();
- tokenizer = data_state;
- emitDoctype();
- break;
- case -1: // EOF
- beginDoctype();
- forcequirks();
- emitDoctype();
- emitEOF();
- break;
- default:
- beginDoctype();
- doctypenamebuf.push(c);
- tokenizer = doctype_name_state;
- break;
- }
- }
-
- function doctype_name_state(c) {
- switch(c) {
- case 0x0009: // CHARACTER TABULATION (tab)
- case 0x000A: // LINE FEED (LF)
- case 0x000C: // FORM FEED (FF)
- case 0x0020: // SPACE
- tokenizer = after_doctype_name_state;
- break;
- case 0x003E: // GREATER-THAN SIGN
- tokenizer = data_state;
- emitDoctype();
- break;
- case 0x0041: // [A-Z]
- case 0x0042:case 0x0043:case 0x0044:case 0x0045:case 0x0046:
- case 0x0047:case 0x0048:case 0x0049:case 0x004A:case 0x004B:
- case 0x004C:case 0x004D:case 0x004E:case 0x004F:case 0x0050:
- case 0x0051:case 0x0052:case 0x0053:case 0x0054:case 0x0055:
- case 0x0056:case 0x0057:case 0x0058:case 0x0059:case 0x005A:
- doctypenamebuf.push(c + 0x0020);
- break;
- case 0x0000: // NULL
- doctypenamebuf.push(0xFFFD /* REPLACEMENT CHARACTER */);
- break;
- case -1: // EOF
- forcequirks();
- emitDoctype();
- emitEOF();
- break;
- default:
- doctypenamebuf.push(c);
- break;
- }
- }
-
- function after_doctype_name_state(c, lookahead, eof) {
- switch(c) {
- case 0x0009: // CHARACTER TABULATION (tab)
- case 0x000A: // LINE FEED (LF)
- case 0x000C: // FORM FEED (FF)
- case 0x0020: // SPACE
- /* Ignore the character. */
- nextchar += 1;
- break;
- case 0x003E: // GREATER-THAN SIGN
- tokenizer = data_state;
- nextchar += 1;
- emitDoctype();
- break;
- case -1: // EOF
- forcequirks();
- emitDoctype();
- emitEOF();
- break;
- default:
- lookahead = lookahead.toUpperCase();
- if (lookahead === "PUBLIC") {
- nextchar += 6;
- tokenizer = after_doctype_public_keyword_state;
- }
- else if (lookahead === "SYSTEM") {
- nextchar += 6;
- tokenizer = after_doctype_system_keyword_state;
- }
- else {
- forcequirks();
- tokenizer = bogus_doctype_state;
- }
- break;
- }
- }
- after_doctype_name_state.lookahead = 6;
-
- function after_doctype_public_keyword_state(c) {
- switch(c) {
- case 0x0009: // CHARACTER TABULATION (tab)
- case 0x000A: // LINE FEED (LF)
- case 0x000C: // FORM FEED (FF)
- case 0x0020: // SPACE
- tokenizer = before_doctype_public_identifier_state;
- break;
- case 0x0022: // QUOTATION MARK
- beginDoctypePublicId();
- tokenizer = doctype_public_identifier_double_quoted_state;
- break;
- case 0x0027: // APOSTROPHE
- beginDoctypePublicId();
- tokenizer = doctype_public_identifier_single_quoted_state;
- break;
- case 0x003E: // GREATER-THAN SIGN
- forcequirks();
- tokenizer = data_state;
- emitDoctype();
- break;
- case -1: // EOF
- forcequirks();
- emitDoctype();
- emitEOF();
- break;
- default:
- forcequirks();
- tokenizer = bogus_doctype_state;
- break;
- }
- }
-
- function before_doctype_public_identifier_state(c) {
- switch(c) {
- case 0x0009: // CHARACTER TABULATION (tab)
- case 0x000A: // LINE FEED (LF)
- case 0x000C: // FORM FEED (FF)
- case 0x0020: // SPACE
- /* Ignore the character. */
- break;
- case 0x0022: // QUOTATION MARK
- beginDoctypePublicId();
- tokenizer = doctype_public_identifier_double_quoted_state;
- break;
- case 0x0027: // APOSTROPHE
- beginDoctypePublicId();
- tokenizer = doctype_public_identifier_single_quoted_state;
- break;
- case 0x003E: // GREATER-THAN SIGN
- forcequirks();
- tokenizer = data_state;
- emitDoctype();
- break;
- case -1: // EOF
- forcequirks();
- emitDoctype();
- emitEOF();
- break;
- default:
- forcequirks();
- tokenizer = bogus_doctype_state;
- break;
- }
- }
-
- function doctype_public_identifier_double_quoted_state(c) {
- switch(c) {
- case 0x0022: // QUOTATION MARK
- tokenizer = after_doctype_public_identifier_state;
- break;
- case 0x0000: // NULL
- doctypepublicbuf.push(0xFFFD /* REPLACEMENT CHARACTER */);
- break;
- case 0x003E: // GREATER-THAN SIGN
- forcequirks();
- tokenizer = data_state;
- emitDoctype();
- break;
- case -1: // EOF
- forcequirks();
- emitDoctype();
- emitEOF();
- break;
- default:
- doctypepublicbuf.push(c);
- break;
- }
- }
-
- function doctype_public_identifier_single_quoted_state(c) {
- switch(c) {
- case 0x0027: // APOSTROPHE
- tokenizer = after_doctype_public_identifier_state;
- break;
- case 0x0000: // NULL
- doctypepublicbuf.push(0xFFFD /* REPLACEMENT CHARACTER */);
- break;
- case 0x003E: // GREATER-THAN SIGN
- forcequirks();
- tokenizer = data_state;
- emitDoctype();
- break;
- case -1: // EOF
- forcequirks();
- emitDoctype();
- emitEOF();
- break;
- default:
- doctypepublicbuf.push(c);
- break;
- }
- }
-
- function after_doctype_public_identifier_state(c) {
- switch(c) {
- case 0x0009: // CHARACTER TABULATION (tab)
- case 0x000A: // LINE FEED (LF)
- case 0x000C: // FORM FEED (FF)
- case 0x0020: // SPACE
- tokenizer = between_doctype_public_and_system_identifiers_state;
- break;
- case 0x003E: // GREATER-THAN SIGN
- tokenizer = data_state;
- emitDoctype();
- break;
- case 0x0022: // QUOTATION MARK
- beginDoctypeSystemId();
- tokenizer = doctype_system_identifier_double_quoted_state;
- break;
- case 0x0027: // APOSTROPHE
- beginDoctypeSystemId();
- tokenizer = doctype_system_identifier_single_quoted_state;
- break;
- case -1: // EOF
- forcequirks();
- emitDoctype();
- emitEOF();
- break;
- default:
- forcequirks();
- tokenizer = bogus_doctype_state;
- break;
- }
- }
-
- function between_doctype_public_and_system_identifiers_state(c) {
- switch(c) {
- case 0x0009: // CHARACTER TABULATION (tab)
- case 0x000A: // LINE FEED (LF)
- case 0x000C: // FORM FEED (FF)
- case 0x0020: // SPACE Ignore the character.
- break;
- case 0x003E: // GREATER-THAN SIGN
- tokenizer = data_state;
- emitDoctype();
- break;
- case 0x0022: // QUOTATION MARK
- beginDoctypeSystemId();
- tokenizer = doctype_system_identifier_double_quoted_state;
- break;
- case 0x0027: // APOSTROPHE
- beginDoctypeSystemId();
- tokenizer = doctype_system_identifier_single_quoted_state;
- break;
- case -1: // EOF
- forcequirks();
- emitDoctype();
- emitEOF();
- break;
- default:
- forcequirks();
- tokenizer = bogus_doctype_state;
- break;
- }
- }
-
- function after_doctype_system_keyword_state(c) {
- switch(c) {
- case 0x0009: // CHARACTER TABULATION (tab)
- case 0x000A: // LINE FEED (LF)
- case 0x000C: // FORM FEED (FF)
- case 0x0020: // SPACE
- tokenizer = before_doctype_system_identifier_state;
- break;
- case 0x0022: // QUOTATION MARK
- beginDoctypeSystemId();
- tokenizer = doctype_system_identifier_double_quoted_state;
- break;
- case 0x0027: // APOSTROPHE
- beginDoctypeSystemId();
- tokenizer = doctype_system_identifier_single_quoted_state;
- break;
- case 0x003E: // GREATER-THAN SIGN
- forcequirks();
- tokenizer = data_state;
- emitDoctype();
- break;
- case -1: // EOF
- forcequirks();
- emitDoctype();
- emitEOF();
- break;
- default:
- forcequirks();
- tokenizer = bogus_doctype_state;
- break;
- }
- }
-
- function before_doctype_system_identifier_state(c) {
- switch(c) {
- case 0x0009: // CHARACTER TABULATION (tab)
- case 0x000A: // LINE FEED (LF)
- case 0x000C: // FORM FEED (FF)
- case 0x0020: // SPACE Ignore the character.
- break;
- case 0x0022: // QUOTATION MARK
- beginDoctypeSystemId();
- tokenizer = doctype_system_identifier_double_quoted_state;
- break;
- case 0x0027: // APOSTROPHE
- beginDoctypeSystemId();
- tokenizer = doctype_system_identifier_single_quoted_state;
- break;
- case 0x003E: // GREATER-THAN SIGN
- forcequirks();
- tokenizer = data_state;
- emitDoctype();
- break;
- case -1: // EOF
- forcequirks();
- emitDoctype();
- emitEOF();
- break;
- default:
- forcequirks();
- tokenizer = bogus_doctype_state;
- break;
- }
- }
-
- function doctype_system_identifier_double_quoted_state(c) {
- switch(c) {
- case 0x0022: // QUOTATION MARK
- tokenizer = after_doctype_system_identifier_state;
- break;
- case 0x0000: // NULL
- doctypesystembuf.push(0xFFFD /* REPLACEMENT CHARACTER */);
- break;
- case 0x003E: // GREATER-THAN SIGN
- forcequirks();
- tokenizer = data_state;
- emitDoctype();
- break;
- case -1: // EOF
- forcequirks();
- emitDoctype();
- emitEOF();
- break;
- default:
- doctypesystembuf.push(c);
- break;
- }
- }
-
- function doctype_system_identifier_single_quoted_state(c) {
- switch(c) {
- case 0x0027: // APOSTROPHE
- tokenizer = after_doctype_system_identifier_state;
- break;
- case 0x0000: // NULL
- doctypesystembuf.push(0xFFFD /* REPLACEMENT CHARACTER */);
- break;
- case 0x003E: // GREATER-THAN SIGN
- forcequirks();
- tokenizer = data_state;
- emitDoctype();
- break;
- case -1: // EOF
- forcequirks();
- emitDoctype();
- emitEOF();
- break;
- default:
- doctypesystembuf.push(c);
- break;
- }
- }
-
- function after_doctype_system_identifier_state(c) {
- switch(c) {
- case 0x0009: // CHARACTER TABULATION (tab)
- case 0x000A: // LINE FEED (LF)
- case 0x000C: // FORM FEED (FF)
- case 0x0020: // SPACE
- /* Ignore the character. */
- break;
- case 0x003E: // GREATER-THAN SIGN
- tokenizer = data_state;
- emitDoctype();
- break;
- case -1: // EOF
- forcequirks();
- emitDoctype();
- emitEOF();
- break;
- default:
- tokenizer = bogus_doctype_state;
- /* This does *not* set the DOCTYPE token's force-quirks flag. */
- break;
- }
- }
-
- function bogus_doctype_state(c) {
- switch(c) {
- case 0x003E: // GREATER-THAN SIGN
- tokenizer = data_state;
- emitDoctype();
- break;
- case -1: // EOF
- emitDoctype();
- emitEOF();
- break;
- default:
- /* Ignore the character. */
- break;
- }
- }
-
- function cdata_section_state(c) {
- switch(c) {
- case 0x005D: // RIGHT SQUARE BRACKET
- tokenizer = cdata_section_bracket_state;
- break;
- case -1: // EOF
- emitEOF();
- break;
- case 0x0000: // NULL
- textIncludesNUL = true;
- /* fall through */
- default:
- // Instead of just pushing a single character and then
- // coming back to the very same place, lookahead and
- // emit everything we can at once.
- /*jshint -W030 */
- emitCharsWhile(CDATATEXT) || textrun.push(c);
- break;
- }
- }
-
- function cdata_section_bracket_state(c) {
- switch(c) {
- case 0x005D: // RIGHT SQUARE BRACKET
- tokenizer = cdata_section_end_state;
- break;
- default:
- textrun.push(0x005D);
- reconsume(c, cdata_section_state);
- break;
- }
- }
-
- function cdata_section_end_state(c) {
- switch(c) {
- case 0x005D: // RIGHT SQUARE BRACKET
- textrun.push(0x005D);
- break;
- case 0x003E: // GREATER-THAN SIGN
- flushText();
- tokenizer = data_state;
- break;
- default:
- textrun.push(0x005D);
- textrun.push(0x005D);
- reconsume(c, cdata_section_state);
- break;
- }
- }
-
- function character_reference_state(c) {
- beginTempBuf();
- tempbuf.push(0x0026);
- switch(c) {
- case 0x0009: // TAB
- case 0x000A: // LINE FEED
- case 0x000C: // FORM FEED
- case 0x0020: // SPACE
- case 0x003C: // LESS-THAN SIGN
- case 0x0026: // AMPERSAND
- case -1: // EOF
- reconsume(c, character_reference_end_state);
- break;
- case 0x0023: // NUMBER SIGN
- tempbuf.push(c);
- tokenizer = numeric_character_reference_state;
- break;
- default:
- reconsume(c, named_character_reference_state);
- break;
- }
- }
-
- function named_character_reference_state(c) {
- NAMEDCHARREF.lastIndex = nextchar; // w/ lookahead no char has been consumed
- var matched = NAMEDCHARREF.exec(chars);
- if (!matched) throw new Error("should never happen");
- var name = matched[1];
- if (!name) {
- // If no match can be made, switch to the character reference end state
- tokenizer = character_reference_end_state;
- return;
- }
-
- // Consume the matched characters and append them to temporary buffer
- nextchar += name.length;
- pushAll(tempbuf, str2buf(name));
-
- switch(return_state) {
- case attribute_value_double_quoted_state:
- case attribute_value_single_quoted_state:
- case attribute_value_unquoted_state:
- // If the character reference was consumed as part of an attribute...
- if (name[name.length-1] !== ';') { // ...and the last char is not ;
- if (/[=A-Za-z0-9]/.test(chars[nextchar])) {
- tokenizer = character_reference_end_state;
- return;
- }
- }
- break;
- default:
- break;
- }
-
- beginTempBuf();
- var rv = namedCharRefs[name];
- if (typeof rv === 'number') {
- tempbuf.push(rv);
- } else {
- pushAll(tempbuf, rv);
- }
- tokenizer = character_reference_end_state;
- }
- // We might need to pause tokenization until we have enough characters
- // in the buffer for longest possible character reference.
- named_character_reference_state.lookahead = -NAMEDCHARREF_MAXLEN;
-
- function numeric_character_reference_state(c) {
- character_reference_code = 0;
- switch(c) {
- case 0x0078: // x
- case 0x0058: // X
- tempbuf.push(c);
- tokenizer = hexadecimal_character_reference_start_state;
- break;
- default:
- reconsume(c, decimal_character_reference_start_state);
- break;
- }
- }
-
- function hexadecimal_character_reference_start_state(c) {
- switch(c) {
- case 0x0030: case 0x0031: case 0x0032: case 0x0033: case 0x0034:
- case 0x0035: case 0x0036: case 0x0037: case 0x0038: case 0x0039: // [0-9]
- case 0x0041: case 0x0042: case 0x0043: case 0x0044: case 0x0045:
- case 0x0046: // [A-F]
- case 0x0061: case 0x0062: case 0x0063: case 0x0064: case 0x0065:
- case 0x0066: // [a-f]
- reconsume(c, hexadecimal_character_reference_state);
- break;
- default:
- reconsume(c, character_reference_end_state);
- break;
- }
- }
-
- function decimal_character_reference_start_state(c) {
- switch(c) {
- case 0x0030: case 0x0031: case 0x0032: case 0x0033: case 0x0034:
- case 0x0035: case 0x0036: case 0x0037: case 0x0038: case 0x0039: // [0-9]
- reconsume(c, decimal_character_reference_state);
- break;
- default:
- reconsume(c, character_reference_end_state);
- break;
- }
- }
-
- function hexadecimal_character_reference_state(c) {
- switch(c) {
- case 0x0041: case 0x0042: case 0x0043: case 0x0044: case 0x0045:
- case 0x0046: // [A-F]
- character_reference_code *= 16;
- character_reference_code += (c - 0x0037);
- break;
- case 0x0061: case 0x0062: case 0x0063: case 0x0064: case 0x0065:
- case 0x0066: // [a-f]
- character_reference_code *= 16;
- character_reference_code += (c - 0x0057);
- break;
- case 0x0030: case 0x0031: case 0x0032: case 0x0033: case 0x0034:
- case 0x0035: case 0x0036: case 0x0037: case 0x0038: case 0x0039: // [0-9]
- character_reference_code *= 16;
- character_reference_code += (c - 0x0030);
- break;
- case 0x003B: // SEMICOLON
- tokenizer = numeric_character_reference_end_state;
- break;
- default:
- reconsume(c, numeric_character_reference_end_state);
- break;
- }
- }
-
- function decimal_character_reference_state(c) {
- switch(c) {
- case 0x0030: case 0x0031: case 0x0032: case 0x0033: case 0x0034:
- case 0x0035: case 0x0036: case 0x0037: case 0x0038: case 0x0039: // [0-9]
- character_reference_code *= 10;
- character_reference_code += (c - 0x0030);
- break;
- case 0x003B: // SEMICOLON
- tokenizer = numeric_character_reference_end_state;
- break;
- default:
- reconsume(c, numeric_character_reference_end_state);
- break;
- }
- }
-
- function numeric_character_reference_end_state(c) {
- if (character_reference_code in numericCharRefReplacements) {
- character_reference_code = numericCharRefReplacements[character_reference_code];
- } else if (character_reference_code > 0x10FFFF || (character_reference_code >= 0xD800 && character_reference_code < 0xE000)) {
- character_reference_code = 0xFFFD;
- }
-
- beginTempBuf();
- if (character_reference_code <= 0xFFFF) {
- tempbuf.push(character_reference_code);
- } else {
- character_reference_code = character_reference_code - 0x10000;
- /* jshint bitwise: false */
- tempbuf.push(0xD800 + (character_reference_code >> 10));
- tempbuf.push(0xDC00 + (character_reference_code & 0x03FF));
- }
- reconsume(c, character_reference_end_state);
- }
-
- function character_reference_end_state(c) {
- switch(return_state) {
- case attribute_value_double_quoted_state:
- case attribute_value_single_quoted_state:
- case attribute_value_unquoted_state:
- // append each character to the current attribute's value
- attrvaluebuf += buf2str(tempbuf);
- break;
- default:
- pushAll(textrun, tempbuf);
- break;
- }
- reconsume(c, return_state);
- }
-
- /***
- * The tree builder insertion modes
- */
-
- // 11.2.5.4.1 The "initial" insertion mode
- function initial_mode(t, value, arg3, arg4) {
- switch(t) {
- case 1: // TEXT
- value = value.replace(LEADINGWS, ""); // Ignore spaces
- if (value.length === 0) return; // Are we done?
- break; // Handle anything non-space text below
- case 4: // COMMENT
- doc._appendChild(doc.createComment(value));
- return;
- case 5: // DOCTYPE
- var name = value;
- var publicid = arg3;
- var systemid = arg4;
- // Use the constructor directly instead of
- // implementation.createDocumentType because the create
- // function throws errors on invalid characters, and
- // we don't want the parser to throw them.
- doc.appendChild(new DocumentType(doc, name, publicid, systemid));
-
- // Note that there is no public API for setting quirks mode We can
- // do this here because we have access to implementation details
- if (force_quirks ||
- name.toLowerCase() !== "html" ||
- quirkyPublicIds.test(publicid) ||
- (systemid && systemid.toLowerCase() === quirkySystemId) ||
- (systemid === undefined &&
- conditionallyQuirkyPublicIds.test(publicid)))
- doc._quirks = true;
- else if (limitedQuirkyPublicIds.test(publicid) ||
- (systemid !== undefined &&
- conditionallyQuirkyPublicIds.test(publicid)))
- doc._limitedQuirks = true;
- parser = before_html_mode;
- return;
- }
-
- // tags or non-whitespace text
- doc._quirks = true;
- parser = before_html_mode;
- parser(t,value,arg3,arg4);
- }
-
- // 11.2.5.4.2 The "before html" insertion mode
- function before_html_mode(t,value,arg3,arg4) {
- var elt;
- switch(t) {
- case 1: // TEXT
- value = value.replace(LEADINGWS, ""); // Ignore spaces
- if (value.length === 0) return; // Are we done?
- break; // Handle anything non-space text below
- case 5: // DOCTYPE
- /* ignore the token */
- return;
- case 4: // COMMENT
- doc._appendChild(doc.createComment(value));
- return;
- case 2: // TAG
- if (value === "html") {
- elt = createHTMLElt(doc, value, arg3);
- stack.push(elt);
- doc.appendChild(elt);
- // XXX: handle application cache here
- parser = before_head_mode;
- return;
- }
- break;
- case 3: // ENDTAG
- switch(value) {
- case "html":
- case "head":
- case "body":
- case "br":
- break; // fall through on these
- default:
- return; // ignore most end tags
- }
- }
-
- // Anything that didn't get handled above is handled like this:
- elt = createHTMLElt(doc, "html", null);
- stack.push(elt);
- doc.appendChild(elt);
- // XXX: handle application cache here
- parser = before_head_mode;
- parser(t,value,arg3,arg4);
- }
-
- // 11.2.5.4.3 The "before head" insertion mode
- function before_head_mode(t,value,arg3,arg4) {
- switch(t) {
- case 1: // TEXT
- value = value.replace(LEADINGWS, ""); // Ignore spaces
- if (value.length === 0) return; // Are we done?
- break; // Handle anything non-space text below
- case 5: // DOCTYPE
- /* ignore the token */
- return;
- case 4: // COMMENT
- insertComment(value);
- return;
- case 2: // TAG
- switch(value) {
- case "html":
- in_body_mode(t,value,arg3,arg4);
- return;
- case "head":
- var elt = insertHTMLElement(value, arg3);
- head_element_pointer = elt;
- parser = in_head_mode;
- return;
- }
- break;
- case 3: // ENDTAG
- switch(value) {
- case "html":
- case "head":
- case "body":
- case "br":
- break;
- default:
- return; // ignore most end tags
- }
- }
-
- // If not handled explicitly above
- before_head_mode(TAG, "head", null); // create a head tag
- parser(t, value, arg3, arg4); // then try again with this token
- }
-
- function in_head_mode(t, value, arg3, arg4) {
- switch(t) {
- case 1: // TEXT
- var ws = value.match(LEADINGWS);
- if (ws) {
- insertText(ws[0]);
- value = value.substring(ws[0].length);
- }
- if (value.length === 0) return;
- break; // Handle non-whitespace below
- case 4: // COMMENT
- insertComment(value);
- return;
- case 5: // DOCTYPE
- return;
- case 2: // TAG
- switch(value) {
- case "html":
- in_body_mode(t, value, arg3, arg4);
- return;
- case "meta":
- // XXX:
- // May need to change the encoding based on this tag
- /* falls through */
- case "base":
- case "basefont":
- case "bgsound":
- case "link":
- insertHTMLElement(value, arg3);
- stack.pop();
- return;
- case "title":
- parseRCDATA(value, arg3);
- return;
- case "noscript":
- if (!scripting_enabled) {
- insertHTMLElement(value, arg3);
- parser = in_head_noscript_mode;
- return;
- }
- // Otherwise, if scripting is enabled...
- /* falls through */
- case "noframes":
- case "style":
- parseRawText(value,arg3);
- return;
- case "script":
- insertElement(function(doc) {
- var elt = createHTMLElt(doc, value, arg3);
- elt._parser_inserted = true;
- elt._force_async = false;
- if (fragment) elt._already_started = true;
- flushText();
- return elt;
- });
- tokenizer = script_data_state;
- originalInsertionMode = parser;
- parser = text_mode;
- return;
- case "template":
- insertHTMLElement(value, arg3);
- afe.insertMarker();
- frameset_ok = false;
- parser = in_template_mode;
- templateInsertionModes.push(parser);
- return;
- case "head":
- return; // ignore it
- }
- break;
- case 3: // ENDTAG
- switch(value) {
- case "head":
- stack.pop();
- parser = after_head_mode;
- return;
- case "body":
- case "html":
- case "br":
- break; // handle these at the bottom of the function
- case "template":
- if (!stack.contains("template")) {
- return;
- }
- stack.generateImpliedEndTags(null, "thorough");
- stack.popTag("template");
- afe.clearToMarker();
- templateInsertionModes.pop();
- resetInsertionMode();
- return;
- default:
- // ignore any other end tag
- return;
- }
- break;
- }
-
- // If not handled above
- in_head_mode(ENDTAG, "head", null); // synthetic </head>
- parser(t, value, arg3, arg4); // Then redo this one
- }
-
- // 13.2.5.4.5 The "in head noscript" insertion mode
- function in_head_noscript_mode(t, value, arg3, arg4) {
- switch(t) {
- case 5: // DOCTYPE
- return;
- case 4: // COMMENT
- in_head_mode(t, value);
- return;
- case 1: // TEXT
- var ws = value.match(LEADINGWS);
- if (ws) {
- in_head_mode(t, ws[0]);
- value = value.substring(ws[0].length);
- }
- if (value.length === 0) return; // no more text
- break; // Handle non-whitespace below
- case 2: // TAG
- switch(value) {
- case "html":
- in_body_mode(t, value, arg3, arg4);
- return;
- case "basefont":
- case "bgsound":
- case "link":
- case "meta":
- case "noframes":
- case "style":
- in_head_mode(t, value, arg3);
- return;
- case "head":
- case "noscript":
- return;
- }
- break;
- case 3: // ENDTAG
- switch(value) {
- case "noscript":
- stack.pop();
- parser = in_head_mode;
- return;
- case "br":
- break; // goes to the outer default
- default:
- return; // ignore other end tags
- }
- break;
- }
-
- // If not handled above
- in_head_noscript_mode(ENDTAG, "noscript", null);
- parser(t, value, arg3, arg4);
- }
-
- function after_head_mode(t, value, arg3, arg4) {
- switch(t) {
- case 1: // TEXT
- var ws = value.match(LEADINGWS);
- if (ws) {
- insertText(ws[0]);
- value = value.substring(ws[0].length);
- }
- if (value.length === 0) return;
- break; // Handle non-whitespace below
- case 4: // COMMENT
- insertComment(value);
- return;
- case 5: // DOCTYPE
- return;
- case 2: // TAG
- switch(value) {
- case "html":
- in_body_mode(t, value, arg3, arg4);
- return;
- case "body":
- insertHTMLElement(value, arg3);
- frameset_ok = false;
- parser = in_body_mode;
- return;
- case "frameset":
- insertHTMLElement(value, arg3);
- parser = in_frameset_mode;
- return;
- case "base":
- case "basefont":
- case "bgsound":
- case "link":
- case "meta":
- case "noframes":
- case "script":
- case "style":
- case "template":
- case "title":
- stack.push(head_element_pointer);
- in_head_mode(TAG, value, arg3);
- stack.removeElement(head_element_pointer);
- return;
- case "head":
- return;
- }
- break;
- case 3: // ENDTAG
- switch(value) {
- case "template":
- return in_head_mode(t, value, arg3, arg4);
- case "body":
- case "html":
- case "br":
- break;
- default:
- return; // ignore any other end tag
- }
- break;
- }
-
- after_head_mode(TAG, "body", null);
- frameset_ok = true;
- parser(t, value, arg3, arg4);
- }
-
- // 13.2.5.4.7 The "in body" insertion mode
- function in_body_mode(t,value,arg3,arg4) {
- var body, i, node, elt;
- switch(t) {
- case 1: // TEXT
- if (textIncludesNUL) {
- value = value.replace(NULCHARS, "");
- if (value.length === 0) return;
- }
- // If any non-space characters
- if (frameset_ok && NONWS.test(value))
- frameset_ok = false;
- afereconstruct();
- insertText(value);
- return;
- case 5: // DOCTYPE
- return;
- case 4: // COMMENT
- insertComment(value);
- return;
- case -1: // EOF
- if (templateInsertionModes.length) {
- return in_template_mode(t);
- }
- stopParsing();
- return;
- case 2: // TAG
- switch(value) {
- case "html":
- if (stack.contains("template")) {
- return;
- }
- transferAttributes(arg3, stack.elements[0]);
- return;
- case "base":
- case "basefont":
- case "bgsound":
- case "link":
- case "meta":
- case "noframes":
- case "script":
- case "style":
- case "template":
- case "title":
- in_head_mode(TAG, value, arg3);
- return;
- case "body":
- body = stack.elements[1];
- if (!body || !(body instanceof impl.HTMLBodyElement) ||
- stack.contains("template"))
- return;
- frameset_ok = false;
- transferAttributes(arg3, body);
- return;
- case "frameset":
- if (!frameset_ok) return;
- body = stack.elements[1];
- if (!body || !(body instanceof impl.HTMLBodyElement))
- return;
- if (body.parentNode) body.parentNode.removeChild(body);
- while(!(stack.top instanceof impl.HTMLHtmlElement))
- stack.pop();
- insertHTMLElement(value, arg3);
- parser = in_frameset_mode;
- return;
-
- case "address":
- case "article":
- case "aside":
- case "blockquote":
- case "center":
- case "details":
- case "dialog":
- case "dir":
- case "div":
- case "dl":
- case "fieldset":
- case "figcaption":
- case "figure":
- case "footer":
- case "header":
- case "hgroup":
- case "main":
- case "nav":
- case "ol":
- case "p":
- case "section":
- case "summary":
- case "ul":
- if (stack.inButtonScope("p")) in_body_mode(ENDTAG, "p");
- insertHTMLElement(value, arg3);
- return;
-
- case "menu":
- if (stack.inButtonScope("p")) in_body_mode(ENDTAG, "p");
- if (isA(stack.top, 'menuitem')) {
- stack.pop();
- }
- insertHTMLElement(value, arg3);
- return;
-
- case "h1":
- case "h2":
- case "h3":
- case "h4":
- case "h5":
- case "h6":
- if (stack.inButtonScope("p")) in_body_mode(ENDTAG, "p");
- if (stack.top instanceof impl.HTMLHeadingElement)
- stack.pop();
- insertHTMLElement(value, arg3);
- return;
-
- case "pre":
- case "listing":
- if (stack.inButtonScope("p")) in_body_mode(ENDTAG, "p");
- insertHTMLElement(value, arg3);
- ignore_linefeed = true;
- frameset_ok = false;
- return;
-
- case "form":
- if (form_element_pointer && !stack.contains("template")) return;
- if (stack.inButtonScope("p")) in_body_mode(ENDTAG, "p");
- elt = insertHTMLElement(value, arg3);
- if (!stack.contains("template"))
- form_element_pointer = elt;
- return;
-
- case "li":
- frameset_ok = false;
- for(i = stack.elements.length-1; i >= 0; i--) {
- node = stack.elements[i];
- if (node instanceof impl.HTMLLIElement) {
- in_body_mode(ENDTAG, "li");
- break;
- }
- if (isA(node, specialSet) && !isA(node, addressdivpSet))
- break;
- }
- if (stack.inButtonScope("p")) in_body_mode(ENDTAG, "p");
- insertHTMLElement(value, arg3);
- return;
-
- case "dd":
- case "dt":
- frameset_ok = false;
- for(i = stack.elements.length-1; i >= 0; i--) {
- node = stack.elements[i];
- if (isA(node, dddtSet)) {
- in_body_mode(ENDTAG, node.localName);
- break;
- }
- if (isA(node, specialSet) && !isA(node, addressdivpSet))
- break;
- }
- if (stack.inButtonScope("p")) in_body_mode(ENDTAG, "p");
- insertHTMLElement(value, arg3);
- return;
-
- case "plaintext":
- if (stack.inButtonScope("p")) in_body_mode(ENDTAG, "p");
- insertHTMLElement(value, arg3);
- tokenizer = plaintext_state;
- return;
-
- case "button":
- if (stack.inScope("button")) {
- in_body_mode(ENDTAG, "button");
- parser(t, value, arg3, arg4);
- }
- else {
- afereconstruct();
- insertHTMLElement(value, arg3);
- frameset_ok = false;
- }
- return;
-
- case "a":
- var activeElement = afe.findElementByTag("a");
- if (activeElement) {
- in_body_mode(ENDTAG, value);
- afe.remove(activeElement);
- stack.removeElement(activeElement);
- }
- /* falls through */
- case "b":
- case "big":
- case "code":
- case "em":
- case "font":
- case "i":
- case "s":
- case "small":
- case "strike":
- case "strong":
- case "tt":
- case "u":
- afereconstruct();
- afe.push(insertHTMLElement(value,arg3), arg3);
- return;
-
- case "nobr":
- afereconstruct();
-
- if (stack.inScope(value)) {
- in_body_mode(ENDTAG, value);
- afereconstruct();
- }
- afe.push(insertHTMLElement(value,arg3), arg3);
- return;
-
- case "applet":
- case "marquee":
- case "object":
- afereconstruct();
- insertHTMLElement(value,arg3);
- afe.insertMarker();
- frameset_ok = false;
- return;
-
- case "table":
- if (!doc._quirks && stack.inButtonScope("p")) {
- in_body_mode(ENDTAG, "p");
- }
- insertHTMLElement(value,arg3);
- frameset_ok = false;
- parser = in_table_mode;
- return;
-
- case "area":
- case "br":
- case "embed":
- case "img":
- case "keygen":
- case "wbr":
- afereconstruct();
- insertHTMLElement(value,arg3);
- stack.pop();
- frameset_ok = false;
- return;
-
- case "input":
- afereconstruct();
- elt = insertHTMLElement(value,arg3);
- stack.pop();
- var type = elt.getAttribute("type");
- if (!type || type.toLowerCase() !== "hidden")
- frameset_ok = false;
- return;
-
- case "param":
- case "source":
- case "track":
- insertHTMLElement(value,arg3);
- stack.pop();
- return;
-
- case "hr":
- if (stack.inButtonScope("p")) in_body_mode(ENDTAG, "p");
- if (isA(stack.top, 'menuitem')) {
- stack.pop();
- }
- insertHTMLElement(value,arg3);
- stack.pop();
- frameset_ok = false;
- return;
-
- case "image":
- in_body_mode(TAG, "img", arg3, arg4);
- return;
-
- case "textarea":
- insertHTMLElement(value,arg3);
- ignore_linefeed = true;
- frameset_ok = false;
- tokenizer = rcdata_state;
- originalInsertionMode = parser;
- parser = text_mode;
- return;
-
- case "xmp":
- if (stack.inButtonScope("p")) in_body_mode(ENDTAG, "p");
- afereconstruct();
- frameset_ok = false;
- parseRawText(value, arg3);
- return;
-
- case "iframe":
- frameset_ok = false;
- parseRawText(value, arg3);
- return;
-
- case "noembed":
- parseRawText(value,arg3);
- return;
-
- case "noscript":
- if (scripting_enabled) {
- parseRawText(value,arg3);
- return;
- }
- break; // XXX Otherwise treat it as any other open tag?
-
- case "select":
- afereconstruct();
- insertHTMLElement(value,arg3);
- frameset_ok = false;
- if (parser === in_table_mode ||
- parser === in_caption_mode ||
- parser === in_table_body_mode ||
- parser === in_row_mode ||
- parser === in_cell_mode)
- parser = in_select_in_table_mode;
- else
- parser = in_select_mode;
- return;
-
- case "optgroup":
- case "option":
- if (stack.top instanceof impl.HTMLOptionElement) {
- in_body_mode(ENDTAG, "option");
- }
- afereconstruct();
- insertHTMLElement(value,arg3);
- return;
-
- case "menuitem":
- if (isA(stack.top, 'menuitem')) {
- stack.pop();
- }
- afereconstruct();
- insertHTMLElement(value, arg3);
- return;
-
- case "rb":
- case "rtc":
- if (stack.inScope("ruby")) {
- stack.generateImpliedEndTags();
- }
- insertHTMLElement(value,arg3);
- return;
-
- case "rp":
- case "rt":
- if (stack.inScope("ruby")) {
- stack.generateImpliedEndTags("rtc");
- }
- insertHTMLElement(value,arg3);
- return;
-
- case "math":
- afereconstruct();
- adjustMathMLAttributes(arg3);
- adjustForeignAttributes(arg3);
- insertForeignElement(value, arg3, NAMESPACE.MATHML);
- if (arg4) // self-closing flag
- stack.pop();
- return;
-
- case "svg":
- afereconstruct();
- adjustSVGAttributes(arg3);
- adjustForeignAttributes(arg3);
- insertForeignElement(value, arg3, NAMESPACE.SVG);
- if (arg4) // self-closing flag
- stack.pop();
- return;
-
- case "caption":
- case "col":
- case "colgroup":
- case "frame":
- case "head":
- case "tbody":
- case "td":
- case "tfoot":
- case "th":
- case "thead":
- case "tr":
- // Ignore table tags if we're not in_table mode
- return;
- }
-
- // Handle any other start tag here
- // (and also noscript tags when scripting is disabled)
- afereconstruct();
- insertHTMLElement(value,arg3);
- return;
-
- case 3: // ENDTAG
- switch(value) {
- case "template":
- in_head_mode(ENDTAG, value, arg3);
- return;
- case "body":
- if (!stack.inScope("body")) return;
- parser = after_body_mode;
- return;
- case "html":
- if (!stack.inScope("body")) return;
- parser = after_body_mode;
- parser(t, value, arg3);
- return;
-
- case "address":
- case "article":
- case "aside":
- case "blockquote":
- case "button":
- case "center":
- case "details":
- case "dialog":
- case "dir":
- case "div":
- case "dl":
- case "fieldset":
- case "figcaption":
- case "figure":
- case "footer":
- case "header":
- case "hgroup":
- case "listing":
- case "main":
- case "menu":
- case "nav":
- case "ol":
- case "pre":
- case "section":
- case "summary":
- case "ul":
- // Ignore if there is not a matching open tag
- if (!stack.inScope(value)) return;
- stack.generateImpliedEndTags();
- stack.popTag(value);
- return;
-
- case "form":
- if (!stack.contains("template")) {
- var openform = form_element_pointer;
- form_element_pointer = null;
- if (!openform || !stack.elementInScope(openform)) return;
- stack.generateImpliedEndTags();
- stack.removeElement(openform);
- } else {
- if (!stack.inScope("form")) return;
- stack.generateImpliedEndTags();
- stack.popTag("form");
- }
- return;
-
- case "p":
- if (!stack.inButtonScope(value)) {
- in_body_mode(TAG, value, null);
- parser(t, value, arg3, arg4);
- }
- else {
- stack.generateImpliedEndTags(value);
- stack.popTag(value);
- }
- return;
-
- case "li":
- if (!stack.inListItemScope(value)) return;
- stack.generateImpliedEndTags(value);
- stack.popTag(value);
- return;
-
- case "dd":
- case "dt":
- if (!stack.inScope(value)) return;
- stack.generateImpliedEndTags(value);
- stack.popTag(value);
- return;
-
- case "h1":
- case "h2":
- case "h3":
- case "h4":
- case "h5":
- case "h6":
- if (!stack.elementTypeInScope(impl.HTMLHeadingElement)) return;
- stack.generateImpliedEndTags();
- stack.popElementType(impl.HTMLHeadingElement);
- return;
-
- case "sarcasm":
- // Take a deep breath, and then:
- break;
-
- case "a":
- case "b":
- case "big":
- case "code":
- case "em":
- case "font":
- case "i":
- case "nobr":
- case "s":
- case "small":
- case "strike":
- case "strong":
- case "tt":
- case "u":
- var result = adoptionAgency(value);
- if (result) return; // If we did something we're done
- break; // Go to the "any other end tag" case
-
- case "applet":
- case "marquee":
- case "object":
- if (!stack.inScope(value)) return;
- stack.generateImpliedEndTags();
- stack.popTag(value);
- afe.clearToMarker();
- return;
-
- case "br":
- in_body_mode(TAG, value, null); // Turn </br> into <br>
- return;
- }
-
- // Any other end tag goes here
- for(i = stack.elements.length-1; i >= 0; i--) {
- node = stack.elements[i];
- if (isA(node, value)) {
- stack.generateImpliedEndTags(value);
- stack.popElement(node);
- break;
- }
- else if (isA(node, specialSet)) {
- return;
- }
- }
-
- return;
- }
- }
-
- function text_mode(t, value, arg3, arg4) {
- switch(t) {
- case 1: // TEXT
- insertText(value);
- return;
- case -1: // EOF
- if (stack.top instanceof impl.HTMLScriptElement)
- stack.top._already_started = true;
- stack.pop();
- parser = originalInsertionMode;
- parser(t);
- return;
- case 3: // ENDTAG
- if (value === "script") {
- handleScriptEnd();
- }
- else {
- stack.pop();
- parser = originalInsertionMode;
- }
- return;
- default:
- // We should never get any other token types
- return;
- }
- }
-
- function in_table_mode(t, value, arg3, arg4) {
- function getTypeAttr(attrs) {
- for(var i = 0, n = attrs.length; i < n; i++) {
- if (attrs[i][0] === "type")
- return attrs[i][1].toLowerCase();
- }
- return null;
- }
-
- switch(t) {
- case 1: // TEXT
- // XXX the text_integration_mode stuff is
- // just a hack I made up
- if (text_integration_mode) {
- in_body_mode(t, value, arg3, arg4);
- return;
- }
- else if (isA(stack.top, tablesectionrowSet)) {
- pending_table_text = [];
- originalInsertionMode = parser;
- parser = in_table_text_mode;
- parser(t, value, arg3, arg4);
- return;
- }
- break;
- case 4: // COMMENT
- insertComment(value);
- return;
- case 5: // DOCTYPE
- return;
- case 2: // TAG
- switch(value) {
- case "caption":
- stack.clearToContext(tableContextSet);
- afe.insertMarker();
- insertHTMLElement(value,arg3);
- parser = in_caption_mode;
- return;
- case "colgroup":
- stack.clearToContext(tableContextSet);
- insertHTMLElement(value,arg3);
- parser = in_column_group_mode;
- return;
- case "col":
- in_table_mode(TAG, "colgroup", null);
- parser(t, value, arg3, arg4);
- return;
- case "tbody":
- case "tfoot":
- case "thead":
- stack.clearToContext(tableContextSet);
- insertHTMLElement(value,arg3);
- parser = in_table_body_mode;
- return;
- case "td":
- case "th":
- case "tr":
- in_table_mode(TAG, "tbody", null);
- parser(t, value, arg3, arg4);
- return;
-
- case "table":
- if (!stack.inTableScope(value)) {
- return; // Ignore the token
- }
- in_table_mode(ENDTAG, value);
- parser(t, value, arg3, arg4);
- return;
-
- case "style":
- case "script":
- case "template":
- in_head_mode(t, value, arg3, arg4);
- return;
-
- case "input":
- var type = getTypeAttr(arg3);
- if (type !== "hidden") break; // to the anything else case
- insertHTMLElement(value,arg3);
- stack.pop();
- return;
-
- case "form":
- if (form_element_pointer || stack.contains("template")) return;
- form_element_pointer = insertHTMLElement(value, arg3);
- stack.popElement(form_element_pointer);
- return;
- }
- break;
- case 3: // ENDTAG
- switch(value) {
- case "table":
- if (!stack.inTableScope(value)) return;
- stack.popTag(value);
- resetInsertionMode();
- return;
- case "body":
- case "caption":
- case "col":
- case "colgroup":
- case "html":
- case "tbody":
- case "td":
- case "tfoot":
- case "th":
- case "thead":
- case "tr":
- return;
- case "template":
- in_head_mode(t, value, arg3, arg4);
- return;
- }
-
- break;
- case -1: // EOF
- in_body_mode(t, value, arg3, arg4);
- return;
- }
-
- // This is the anything else case
- foster_parent_mode = true;
- in_body_mode(t, value, arg3, arg4);
- foster_parent_mode = false;
- }
-
- function in_table_text_mode(t, value, arg3, arg4) {
- if (t === TEXT) {
- if (textIncludesNUL) {
- value = value.replace(NULCHARS, "");
- if (value.length === 0) return;
- }
- pending_table_text.push(value);
- }
- else {
- var s = pending_table_text.join("");
- pending_table_text.length = 0;
- if (NONWS.test(s)) { // If any non-whitespace characters
- // This must be the same code as the "anything else"
- // case of the in_table mode above.
- foster_parent_mode = true;
- in_body_mode(TEXT, s);
- foster_parent_mode = false;
- }
- else {
- insertText(s);
- }
- parser = originalInsertionMode;
- parser(t, value, arg3, arg4);
- }
- }
-
-
- function in_caption_mode(t, value, arg3, arg4) {
- function end_caption() {
- if (!stack.inTableScope("caption")) return false;
- stack.generateImpliedEndTags();
- stack.popTag("caption");
- afe.clearToMarker();
- parser = in_table_mode;
- return true;
- }
-
- switch(t) {
- case 2: // TAG
- switch(value) {
- case "caption":
- case "col":
- case "colgroup":
- case "tbody":
- case "td":
- case "tfoot":
- case "th":
- case "thead":
- case "tr":
- if (end_caption()) parser(t, value, arg3, arg4);
- return;
- }
- break;
- case 3: // ENDTAG
- switch(value) {
- case "caption":
- end_caption();
- return;
- case "table":
- if (end_caption()) parser(t, value, arg3, arg4);
- return;
- case "body":
- case "col":
- case "colgroup":
- case "html":
- case "tbody":
- case "td":
- case "tfoot":
- case "th":
- case "thead":
- case "tr":
- return;
- }
- break;
- }
-
- // The Anything Else case
- in_body_mode(t, value, arg3, arg4);
- }
-
- function in_column_group_mode(t, value, arg3, arg4) {
- switch(t) {
- case 1: // TEXT
- var ws = value.match(LEADINGWS);
- if (ws) {
- insertText(ws[0]);
- value = value.substring(ws[0].length);
- }
- if (value.length === 0) return;
- break; // Handle non-whitespace below
-
- case 4: // COMMENT
- insertComment(value);
- return;
- case 5: // DOCTYPE
- return;
- case 2: // TAG
- switch(value) {
- case "html":
- in_body_mode(t, value, arg3, arg4);
- return;
- case "col":
- insertHTMLElement(value, arg3);
- stack.pop();
- return;
- case "template":
- in_head_mode(t, value, arg3, arg4);
- return;
- }
- break;
- case 3: // ENDTAG
- switch(value) {
- case "colgroup":
- if (!isA(stack.top, 'colgroup')) {
- return; // Ignore the token.
- }
- stack.pop();
- parser = in_table_mode;
- return;
- case "col":
- return;
- case "template":
- in_head_mode(t, value, arg3, arg4);
- return;
- }
- break;
- case -1: // EOF
- in_body_mode(t, value, arg3, arg4);
- return;
- }
-
- // Anything else
- if (!isA(stack.top, 'colgroup')) {
- return; // Ignore the token.
- }
- in_column_group_mode(ENDTAG, "colgroup");
- parser(t, value, arg3, arg4);
- }
-
- function in_table_body_mode(t, value, arg3, arg4) {
- function endsect() {
- if (!stack.inTableScope("tbody") &&
- !stack.inTableScope("thead") &&
- !stack.inTableScope("tfoot"))
- return;
- stack.clearToContext(tableBodyContextSet);
- in_table_body_mode(ENDTAG, stack.top.localName, null);
- parser(t, value, arg3, arg4);
- }
-
- switch(t) {
- case 2: // TAG
- switch(value) {
- case "tr":
- stack.clearToContext(tableBodyContextSet);
- insertHTMLElement(value, arg3);
- parser = in_row_mode;
- return;
- case "th":
- case "td":
- in_table_body_mode(TAG, "tr", null);
- parser(t, value, arg3, arg4);
- return;
- case "caption":
- case "col":
- case "colgroup":
- case "tbody":
- case "tfoot":
- case "thead":
- endsect();
- return;
- }
- break;
- case 3: // ENDTAG
- switch(value) {
- case "table":
- endsect();
- return;
- case "tbody":
- case "tfoot":
- case "thead":
- if (stack.inTableScope(value)) {
- stack.clearToContext(tableBodyContextSet);
- stack.pop();
- parser = in_table_mode;
- }
- return;
- case "body":
- case "caption":
- case "col":
- case "colgroup":
- case "html":
- case "td":
- case "th":
- case "tr":
- return;
- }
- break;
- }
-
- // Anything else:
- in_table_mode(t, value, arg3, arg4);
- }
-
- function in_row_mode(t, value, arg3, arg4) {
- function endrow() {
- if (!stack.inTableScope("tr")) return false;
- stack.clearToContext(tableRowContextSet);
- stack.pop();
- parser = in_table_body_mode;
- return true;
- }
-
- switch(t) {
- case 2: // TAG
- switch(value) {
- case "th":
- case "td":
- stack.clearToContext(tableRowContextSet);
- insertHTMLElement(value, arg3);
- parser = in_cell_mode;
- afe.insertMarker();
- return;
- case "caption":
- case "col":
- case "colgroup":
- case "tbody":
- case "tfoot":
- case "thead":
- case "tr":
- if (endrow()) parser(t, value, arg3, arg4);
- return;
- }
- break;
- case 3: // ENDTAG
- switch(value) {
- case "tr":
- endrow();
- return;
- case "table":
- if (endrow()) parser(t, value, arg3, arg4);
- return;
- case "tbody":
- case "tfoot":
- case "thead":
- if (stack.inTableScope(value)) {
- if (endrow()) parser(t, value, arg3, arg4);
- }
- return;
- case "body":
- case "caption":
- case "col":
- case "colgroup":
- case "html":
- case "td":
- case "th":
- return;
- }
- break;
- }
-
- // anything else
- in_table_mode(t, value, arg3, arg4);
- }
-
- function in_cell_mode(t, value, arg3, arg4) {
- switch(t) {
- case 2: // TAG
- switch(value) {
- case "caption":
- case "col":
- case "colgroup":
- case "tbody":
- case "td":
- case "tfoot":
- case "th":
- case "thead":
- case "tr":
- if (stack.inTableScope("td")) {
- in_cell_mode(ENDTAG, "td");
- parser(t, value, arg3, arg4);
- }
- else if (stack.inTableScope("th")) {
- in_cell_mode(ENDTAG, "th");
- parser(t, value, arg3, arg4);
- }
- return;
- }
- break;
- case 3: // ENDTAG
- switch(value) {
- case "td":
- case "th":
- if (!stack.inTableScope(value)) return;
- stack.generateImpliedEndTags();
- stack.popTag(value);
- afe.clearToMarker();
- parser = in_row_mode;
- return;
-
- case "body":
- case "caption":
- case "col":
- case "colgroup":
- case "html":
- return;
-
- case "table":
- case "tbody":
- case "tfoot":
- case "thead":
- case "tr":
- if (!stack.inTableScope(value)) return;
- in_cell_mode(ENDTAG, stack.inTableScope("td") ? "td" : "th");
- parser(t, value, arg3, arg4);
- return;
- }
- break;
- }
-
- // anything else
- in_body_mode(t, value, arg3, arg4);
- }
-
- function in_select_mode(t, value, arg3, arg4) {
- switch(t) {
- case 1: // TEXT
- if (textIncludesNUL) {
- value = value.replace(NULCHARS, "");
- if (value.length === 0) return;
- }
- insertText(value);
- return;
- case 4: // COMMENT
- insertComment(value);
- return;
- case 5: // DOCTYPE
- return;
- case -1: // EOF
- in_body_mode(t, value, arg3, arg4);
- return;
- case 2: // TAG
- switch(value) {
- case "html":
- in_body_mode(t, value, arg3, arg4);
- return;
- case "option":
- if (stack.top instanceof impl.HTMLOptionElement)
- in_select_mode(ENDTAG, value);
- insertHTMLElement(value, arg3);
- return;
- case "optgroup":
- if (stack.top instanceof impl.HTMLOptionElement)
- in_select_mode(ENDTAG, "option");
- if (stack.top instanceof impl.HTMLOptGroupElement)
- in_select_mode(ENDTAG, value);
- insertHTMLElement(value, arg3);
- return;
- case "select":
- in_select_mode(ENDTAG, value); // treat it as a close tag
- return;
-
- case "input":
- case "keygen":
- case "textarea":
- if (!stack.inSelectScope("select")) return;
- in_select_mode(ENDTAG, "select");
- parser(t, value, arg3, arg4);
- return;
-
- case "script":
- case "template":
- in_head_mode(t, value, arg3, arg4);
- return;
- }
- break;
- case 3: // ENDTAG
- switch(value) {
- case "optgroup":
- if (stack.top instanceof impl.HTMLOptionElement &&
- stack.elements[stack.elements.length-2] instanceof
- impl.HTMLOptGroupElement) {
- in_select_mode(ENDTAG, "option");
- }
- if (stack.top instanceof impl.HTMLOptGroupElement)
- stack.pop();
-
- return;
-
- case "option":
- if (stack.top instanceof impl.HTMLOptionElement)
- stack.pop();
- return;
-
- case "select":
- if (!stack.inSelectScope(value)) return;
- stack.popTag(value);
- resetInsertionMode();
- return;
-
- case "template":
- in_head_mode(t, value, arg3, arg4);
- return;
- }
-
- break;
- }
-
- // anything else: just ignore the token
- }
-
- function in_select_in_table_mode(t, value, arg3, arg4) {
- switch(value) {
- case "caption":
- case "table":
- case "tbody":
- case "tfoot":
- case "thead":
- case "tr":
- case "td":
- case "th":
- switch(t) {
- case 2: // TAG
- in_select_in_table_mode(ENDTAG, "select");
- parser(t, value, arg3, arg4);
- return;
- case 3: // ENDTAG
- if (stack.inTableScope(value)) {
- in_select_in_table_mode(ENDTAG, "select");
- parser(t, value, arg3, arg4);
- }
- return;
- }
- }
-
- // anything else
- in_select_mode(t, value, arg3, arg4);
- }
-
- function in_template_mode(t, value, arg3, arg4) {
- function switchModeAndReprocess(mode) {
- parser = mode;
- templateInsertionModes[templateInsertionModes.length-1] = parser;
- parser(t, value, arg3, arg4);
- }
- switch(t) {
- case 1: // TEXT
- case 4: // COMMENT
- case 5: // DOCTYPE
- in_body_mode(t, value, arg3, arg4);
- return;
- case -1: // EOF
- if (!stack.contains("template")) {
- stopParsing();
- } else {
- stack.popTag("template");
- afe.clearToMarker();
- templateInsertionModes.pop();
- resetInsertionMode();
- parser(t, value, arg3, arg4);
- }
- return;
- case 2: // TAG
- switch(value) {
- case "base":
- case "basefont":
- case "bgsound":
- case "link":
- case "meta":
- case "noframes":
- case "script":
- case "style":
- case "template":
- case "title":
- in_head_mode(t, value, arg3, arg4);
- return;
- case "caption":
- case "colgroup":
- case "tbody":
- case "tfoot":
- case "thead":
- switchModeAndReprocess(in_table_mode);
- return;
- case "col":
- switchModeAndReprocess(in_column_group_mode);
- return;
- case "tr":
- switchModeAndReprocess(in_table_body_mode);
- return;
- case "td":
- case "th":
- switchModeAndReprocess(in_row_mode);
- return;
- }
- switchModeAndReprocess(in_body_mode);
- return;
- case 3: // ENDTAG
- switch(value) {
- case "template":
- in_head_mode(t, value, arg3, arg4);
- return;
- default:
- return;
- }
- }
- }
-
- function after_body_mode(t, value, arg3, arg4) {
- switch(t) {
- case 1: // TEXT
- // If any non-space chars, handle below
- if (NONWS.test(value)) break;
- in_body_mode(t, value);
- return;
- case 4: // COMMENT
- // Append it to the <html> element
- stack.elements[0]._appendChild(doc.createComment(value));
- return;
- case 5: // DOCTYPE
- return;
- case -1: // EOF
- stopParsing();
- return;
- case 2: // TAG
- if (value === "html") {
- in_body_mode(t, value, arg3, arg4);
- return;
- }
- break; // for any other tags
- case 3: // ENDTAG
- if (value === "html") {
- if (fragment) return;
- parser = after_after_body_mode;
- return;
- }
- break; // for any other tags
- }
-
- // anything else
- parser = in_body_mode;
- parser(t, value, arg3, arg4);
- }
-
- function in_frameset_mode(t, value, arg3, arg4) {
- switch(t) {
- case 1: // TEXT
- // Ignore any non-space characters
- value = value.replace(ALLNONWS, "");
- if (value.length > 0) insertText(value);
- return;
- case 4: // COMMENT
- insertComment(value);
- return;
- case 5: // DOCTYPE
- return;
- case -1: // EOF
- stopParsing();
- return;
- case 2: // TAG
- switch(value) {
- case "html":
- in_body_mode(t, value, arg3, arg4);
- return;
- case "frameset":
- insertHTMLElement(value, arg3);
- return;
- case "frame":
- insertHTMLElement(value, arg3);
- stack.pop();
- return;
- case "noframes":
- in_head_mode(t, value, arg3, arg4);
- return;
- }
- break;
- case 3: // ENDTAG
- if (value === "frameset") {
- if (fragment && stack.top instanceof impl.HTMLHtmlElement)
- return;
- stack.pop();
- if (!fragment &&
- !(stack.top instanceof impl.HTMLFrameSetElement))
- parser = after_frameset_mode;
- return;
- }
- break;
- }
-
- // ignore anything else
- }
-
- function after_frameset_mode(t, value, arg3, arg4) {
- switch(t) {
- case 1: // TEXT
- // Ignore any non-space characters
- value = value.replace(ALLNONWS, "");
- if (value.length > 0) insertText(value);
- return;
- case 4: // COMMENT
- insertComment(value);
- return;
- case 5: // DOCTYPE
- return;
- case -1: // EOF
- stopParsing();
- return;
- case 2: // TAG
- switch(value) {
- case "html":
- in_body_mode(t, value, arg3, arg4);
- return;
- case "noframes":
- in_head_mode(t, value, arg3, arg4);
- return;
- }
- break;
- case 3: // ENDTAG
- if (value === "html") {
- parser = after_after_frameset_mode;
- return;
- }
- break;
- }
-
- // ignore anything else
- }
-
- function after_after_body_mode(t, value, arg3, arg4) {
- switch(t) {
- case 1: // TEXT
- // If any non-space chars, handle below
- if (NONWS.test(value)) break;
- in_body_mode(t, value, arg3, arg4);
- return;
- case 4: // COMMENT
- doc._appendChild(doc.createComment(value));
- return;
- case 5: // DOCTYPE
- in_body_mode(t, value, arg3, arg4);
- return;
- case -1: // EOF
- stopParsing();
- return;
- case 2: // TAG
- if (value === "html") {
- in_body_mode(t, value, arg3, arg4);
- return;
- }
- break;
- }
-
- // anything else
- parser = in_body_mode;
- parser(t, value, arg3, arg4);
- }
-
- function after_after_frameset_mode(t, value, arg3, arg4) {
- switch(t) {
- case 1: // TEXT
- // Ignore any non-space characters
- value = value.replace(ALLNONWS, "");
- if (value.length > 0)
- in_body_mode(t, value, arg3, arg4);
- return;
- case 4: // COMMENT
- doc._appendChild(doc.createComment(value));
- return;
- case 5: // DOCTYPE
- in_body_mode(t, value, arg3, arg4);
- return;
- case -1: // EOF
- stopParsing();
- return;
- case 2: // TAG
- switch(value) {
- case "html":
- in_body_mode(t, value, arg3, arg4);
- return;
- case "noframes":
- in_head_mode(t, value, arg3, arg4);
- return;
- }
- break;
- }
-
- // ignore anything else
- }
-
-
- // 13.2.5.5 The rules for parsing tokens in foreign content
- //
- // This is like one of the insertion modes above, but is
- // invoked somewhat differently when the current token is not HTML.
- // See the insertToken() function.
- function insertForeignToken(t, value, arg3, arg4) {
- // A <font> tag is an HTML font tag if it has a color, font, or size
- // attribute. Otherwise we assume it is foreign content
- function isHTMLFont(attrs) {
- for(var i = 0, n = attrs.length; i < n; i++) {
- switch(attrs[i][0]) {
- case "color":
- case "face":
- case "size":
- return true;
- }
- }
- return false;
- }
-
- var current;
-
- switch(t) {
- case 1: // TEXT
- // If any non-space, non-nul characters
- if (frameset_ok && NONWSNONNUL.test(value))
- frameset_ok = false;
- if (textIncludesNUL) {
- value = value.replace(NULCHARS, "\uFFFD");
- }
- insertText(value);
- return;
- case 4: // COMMENT
- insertComment(value);
- return;
- case 5: // DOCTYPE
- // ignore it
- return;
- case 2: // TAG
- switch(value) {
- case "font":
- if (!isHTMLFont(arg3)) break;
- /* falls through */
- case "b":
- case "big":
- case "blockquote":
- case "body":
- case "br":
- case "center":
- case "code":
- case "dd":
- case "div":
- case "dl":
- case "dt":
- case "em":
- case "embed":
- case "h1":
- case "h2":
- case "h3":
- case "h4":
- case "h5":
- case "h6":
- case "head":
- case "hr":
- case "i":
- case "img":
- case "li":
- case "listing":
- case "menu":
- case "meta":
- case "nobr":
- case "ol":
- case "p":
- case "pre":
- case "ruby":
- case "s":
- case "small":
- case "span":
- case "strong":
- case "strike":
- case "sub":
- case "sup":
- case "table":
- case "tt":
- case "u":
- case "ul":
- case "var":
- if (fragment) {
- break;
- }
- do {
- stack.pop();
- current = stack.top;
- } while(current.namespaceURI !== NAMESPACE.HTML &&
- !isMathmlTextIntegrationPoint(current) &&
- !isHTMLIntegrationPoint(current));
-
- insertToken(t, value, arg3, arg4); // reprocess
- return;
- }
-
- // Any other start tag case goes here
- current = (stack.elements.length===1 && fragment) ? fragmentContext :
- stack.top;
- if (current.namespaceURI === NAMESPACE.MATHML) {
- adjustMathMLAttributes(arg3);
- }
- else if (current.namespaceURI === NAMESPACE.SVG) {
- value = adjustSVGTagName(value);
- adjustSVGAttributes(arg3);
- }
- adjustForeignAttributes(arg3);
-
- insertForeignElement(value, arg3, current.namespaceURI);
- if (arg4) { // the self-closing flag
- if (value === 'script' && current.namespaceURI === NAMESPACE.SVG) {
- // XXX deal with SVG scripts here
- }
- stack.pop();
- }
- return;
-
- case 3: // ENDTAG
- current = stack.top;
- if (value === "script" &&
- current.namespaceURI === NAMESPACE.SVG &&
- current.localName === "script") {
-
- stack.pop();
-
- // XXX
- // Deal with SVG scripts here
- }
- else {
- // The any other end tag case
- var i = stack.elements.length-1;
- var node = stack.elements[i];
- for(;;) {
- if (node.localName.toLowerCase() === value) {
- stack.popElement(node);
- break;
- }
- node = stack.elements[--i];
- // If non-html, keep looping
- if (node.namespaceURI !== NAMESPACE.HTML)
- continue;
- // Otherwise process the end tag as html
- parser(t, value, arg3, arg4);
- break;
- }
- }
- return;
- }
- }
-
- /***
- * Finally, this is the end of the HTMLParser() factory function.
- * It returns the htmlparser object with the append() and end() methods.
- */
-
- // Sneak another method into the htmlparser object to allow us to run
- // tokenizer tests. This can be commented out in production code.
- // This is a hook for testing the tokenizer. It has to be here
- // because the tokenizer details are all hidden away within the closure.
- // It should return an array of tokens generated while parsing the
- // input string.
- htmlparser.testTokenizer = function(input, initialState, lastStartTag, charbychar) {
- var tokens = [];
-
- switch(initialState) {
- case "PCDATA state":
- tokenizer = data_state;
- break;
- case "RCDATA state":
- tokenizer = rcdata_state;
- break;
- case "RAWTEXT state":
- tokenizer = rawtext_state;
- break;
- case "PLAINTEXT state":
- tokenizer = plaintext_state;
- break;
- }
-
- if (lastStartTag) {
- lasttagname = lastStartTag;
- }
-
- insertToken = function(t, value, arg3, arg4) {
- flushText();
- switch(t) {
- case 1: // TEXT
- if (tokens.length > 0 &&
- tokens[tokens.length-1][0] === "Character") {
- tokens[tokens.length-1][1] += value;
- }
- else tokens.push(["Character", value]);
- break;
- case 4: // COMMENT
- tokens.push(["Comment", value]);
- break;
- case 5: // DOCTYPE
- tokens.push(["DOCTYPE", value,
- arg3 === undefined ? null : arg3,
- arg4 === undefined ? null : arg4,
- !force_quirks]);
- break;
- case 2: // TAG
- var attrs = Object.create(null);
- for(var i = 0; i < arg3.length; i++) {
- // XXX: does attribute order matter?
- var a = arg3[i];
- if (a.length === 1) {
- attrs[a[0]] = "";
- }
- else {
- attrs[a[0]] = a[1];
- }
- }
- var token = ["StartTag", value, attrs];
- if (arg4) token.push(true);
- tokens.push(token);
- break;
- case 3: // ENDTAG
- tokens.push(["EndTag", value]);
- break;
- case -1: // EOF
- break;
- }
- };
-
- if (!charbychar) {
- this.parse(input, true);
- }
- else {
- for(var i = 0; i < input.length; i++) {
- this.parse(input[i]);
- }
- this.parse("", true);
- }
- return tokens;
- };
-
- // Return the parser object from the HTMLParser() factory function
- return htmlparser;
-}
--- a/cmd/gojafs/domino/domino-lib/LICENSE
+++ /dev/null
@@ -1,25 +1,0 @@
-Copyright (c) 2011 The Mozilla Foundation.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are
-met:
-
- Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
-IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
-TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
-PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
-TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
-PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
-LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
-NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--- a/cmd/gojafs/domino/domino-lib/Leaf.js
+++ /dev/null
@@ -1,37 +1,0 @@
-"use strict";
-module.exports = Leaf;
-
-var Node = require('./Node');
-var NodeList = require('./NodeList');
-var utils = require('./utils');
-var HierarchyRequestError = utils.HierarchyRequestError;
-var NotFoundError = utils.NotFoundError;
-
-// This class defines common functionality for node subtypes that
-// can never have children
-function Leaf() {
- Node.call(this);
-}
-
-Leaf.prototype = Object.create(Node.prototype, {
- hasChildNodes: { value: function() { return false; }},
- firstChild: { value: null },
- lastChild: { value: null },
- insertBefore: { value: function(node, child) {
- if (!node.nodeType) throw new TypeError('not a node');
- HierarchyRequestError();
- }},
- replaceChild: { value: function(node, child) {
- if (!node.nodeType) throw new TypeError('not a node');
- HierarchyRequestError();
- }},
- removeChild: { value: function(node) {
- if (!node.nodeType) throw new TypeError('not a node');
- NotFoundError();
- }},
- removeChildren: { value: function() { /* no op */ }},
- childNodes: { get: function() {
- if (!this._childNodes) this._childNodes = new NodeList();
- return this._childNodes;
- }}
-});
--- a/cmd/gojafs/domino/domino-lib/LinkedList.js
+++ /dev/null
@@ -1,44 +1,0 @@
-"use strict";
-var utils = require('./utils');
-
-var LinkedList = module.exports = {
- // basic validity tests on a circular linked list a
- valid: function(a) {
- utils.assert(a, "list falsy");
- utils.assert(a._previousSibling, "previous falsy");
- utils.assert(a._nextSibling, "next falsy");
- // xxx check that list is actually circular
- return true;
- },
- // insert a before b
- insertBefore: function(a, b) {
- utils.assert(LinkedList.valid(a) && LinkedList.valid(b));
- var a_first = a, a_last = a._previousSibling;
- var b_first = b, b_last = b._previousSibling;
- a_first._previousSibling = b_last;
- a_last._nextSibling = b_first;
- b_last._nextSibling = a_first;
- b_first._previousSibling = a_last;
- utils.assert(LinkedList.valid(a) && LinkedList.valid(b));
- },
- // replace a single node a with a list b (which could be null)
- replace: function(a, b) {
- utils.assert(LinkedList.valid(a) && (b===null || LinkedList.valid(b)));
- if (b!==null) {
- LinkedList.insertBefore(b, a);
- }
- LinkedList.remove(a);
- utils.assert(LinkedList.valid(a) && (b===null || LinkedList.valid(b)));
- },
- // remove single node a from its list
- remove: function(a) {
- utils.assert(LinkedList.valid(a));
- var prev = a._previousSibling;
- if (prev === a) { return; }
- var next = a._nextSibling;
- prev._nextSibling = next;
- next._previousSibling = prev;
- a._previousSibling = a._nextSibling = a;
- utils.assert(LinkedList.valid(a));
- }
-};
--- a/cmd/gojafs/domino/domino-lib/Location.js
+++ /dev/null
@@ -1,56 +1,0 @@
-"use strict";
-var URL = require('./URL');
-var URLUtils = require('./URLUtils');
-
-module.exports = Location;
-
-function Location(window, href) {
- this._window = window;
- this._href = href;
-}
-
-Location.prototype = Object.create(URLUtils.prototype, {
- constructor: { value: Location },
-
- // Special behavior when href is set
- href: {
- get: function() { return this._href; },
- set: function(v) { this.assign(v); }
- },
-
- assign: { value: function(url) {
- // Resolve the new url against the current one
- // XXX:
- // This is not actually correct. It should be resolved against
- // the URL of the document of the script. For now, though, I only
- // support a single window and there is only one base url.
- // So this is good enough for now.
- var current = new URL(this._href);
- var newurl = current.resolve(url);
-
- // Save the new url
- this._href = newurl;
-
- // Start loading the new document!
- // XXX
- // This is just something hacked together.
- // The real algorithm is: http://www.whatwg.org/specs/web-apps/current-work/multipage/history.html#navigate
- }},
-
- replace: { value: function(url) {
- // XXX
- // Since we aren't tracking history yet, replace is the same as assign
- this.assign(url);
- }},
-
- reload: { value: function() {
- // XXX:
- // Actually, the spec is a lot more complicated than this
- this.assign(this.href);
- }},
-
- toString: { value: function() {
- return this.href;
- }}
-
-});
--- a/cmd/gojafs/domino/domino-lib/MouseEvent.js
+++ /dev/null
@@ -1,52 +1,0 @@
-"use strict";
-var UIEvent = require('./UIEvent');
-
-module.exports = MouseEvent;
-
-function MouseEvent() {
- // Just use the superclass constructor to initialize
- UIEvent.call(this);
-
- this.screenX = this.screenY = this.clientX = this.clientY = 0;
- this.ctrlKey = this.altKey = this.shiftKey = this.metaKey = false;
- this.button = 0;
- this.buttons = 1;
- this.relatedTarget = null;
-}
-MouseEvent.prototype = Object.create(UIEvent.prototype, {
- constructor: { value: MouseEvent },
- initMouseEvent: { value: function(type, bubbles, cancelable,
- view, detail,
- screenX, screenY, clientX, clientY,
- ctrlKey, altKey, shiftKey, metaKey,
- button, relatedTarget) {
-
- this.initEvent(type, bubbles, cancelable, view, detail);
- this.screenX = screenX;
- this.screenY = screenY;
- this.clientX = clientX;
- this.clientY = clientY;
- this.ctrlKey = ctrlKey;
- this.altKey = altKey;
- this.shiftKey = shiftKey;
- this.metaKey = metaKey;
- this.button = button;
- switch(button) {
- case 0: this.buttons = 1; break;
- case 1: this.buttons = 4; break;
- case 2: this.buttons = 2; break;
- default: this.buttons = 0; break;
- }
- this.relatedTarget = relatedTarget;
- }},
-
- getModifierState: { value: function(key) {
- switch(key) {
- case "Alt": return this.altKey;
- case "Control": return this.ctrlKey;
- case "Shift": return this.shiftKey;
- case "Meta": return this.metaKey;
- default: return false;
- }
- }}
-});
--- a/cmd/gojafs/domino/domino-lib/MutationConstants.js
+++ /dev/null
@@ -1,9 +1,0 @@
-"use strict";
-module.exports = {
- VALUE: 1, // The value of a Text, Comment or PI node changed
- ATTR: 2, // A new attribute was added or an attribute value and/or prefix changed
- REMOVE_ATTR: 3, // An attribute was removed
- REMOVE: 4, // A node was removed
- MOVE: 5, // A node was moved
- INSERT: 6 // A node (or a subtree of nodes) was inserted
-};
\ No newline at end of file
--- a/cmd/gojafs/domino/domino-lib/NamedNodeMap.js
+++ /dev/null
@@ -1,41 +1,0 @@
-"use strict";
-module.exports = NamedNodeMap;
-
-var utils = require('./utils');
-
-/* This is a hacky implementation of NamedNodeMap, intended primarily to
- * satisfy clients (like dompurify and the web-platform-tests) which check
- * to ensure that Node#attributes instanceof NamedNodeMap. */
-
-function NamedNodeMap(element) {
- this.element = element;
-}
-Object.defineProperties(NamedNodeMap.prototype, {
- length: { get: utils.shouldOverride },
- item: { value: utils.shouldOverride },
-
- getNamedItem: { value: function getNamedItem(qualifiedName) {
- return this.element.getAttributeNode(qualifiedName);
- } },
- getNamedItemNS: { value: function getNamedItemNS(namespace, localName) {
- return this.element.getAttributeNodeNS(namespace, localName);
- } },
- setNamedItem: { value: utils.nyi },
- setNamedItemNS: { value: utils.nyi },
- removeNamedItem: { value: function removeNamedItem(qualifiedName) {
- var attr = this.element.getAttributeNode(qualifiedName);
- if (attr) {
- this.element.removeAttribute(qualifiedName);
- return attr;
- }
- utils.NotFoundError();
- } },
- removeNamedItemNS: { value: function removeNamedItemNS(ns, lname) {
- var attr = this.element.getAttributeNodeNS(ns, lname);
- if (attr) {
- this.element.removeAttributeNS(ns, lname);
- return attr;
- }
- utils.NotFoundError();
- } },
-});
--- a/cmd/gojafs/domino/domino-lib/NavigatorID.js
+++ /dev/null
@@ -1,17 +1,0 @@
-"use strict";
-
-// https://html.spec.whatwg.org/multipage/webappapis.html#navigatorid
-var NavigatorID = Object.create(null, {
- appCodeName: { value: "Mozilla" },
- appName: { value: "Netscape" },
- appVersion: { value: "4.0" },
- platform: { value: "" },
- product: { value: "Gecko" },
- productSub: { value: "20100101" },
- userAgent: { value: "" },
- vendor: { value: "" },
- vendorSub: { value: "" },
- taintEnabled: { value: function() { return false; } }
-});
-
-module.exports = NavigatorID;
--- a/cmd/gojafs/domino/domino-lib/Node.js
+++ /dev/null
@@ -1,738 +1,0 @@
-"use strict";
-module.exports = Node;
-
-var EventTarget = require('./EventTarget');
-var LinkedList = require('./LinkedList');
-var NodeUtils = require('./NodeUtils');
-var utils = require('./utils');
-
-// All nodes have a nodeType and an ownerDocument.
-// Once inserted, they also have a parentNode.
-// This is an abstract class; all nodes in a document are instances
-// of a subtype, so all the properties are defined by more specific
-// constructors.
-function Node() {
- EventTarget.call(this);
- this.parentNode = null;
- this._nextSibling = this._previousSibling = this;
- this._index = undefined;
-}
-
-var ELEMENT_NODE = Node.ELEMENT_NODE = 1;
-var ATTRIBUTE_NODE = Node.ATTRIBUTE_NODE = 2;
-var TEXT_NODE = Node.TEXT_NODE = 3;
-var CDATA_SECTION_NODE = Node.CDATA_SECTION_NODE = 4;
-var ENTITY_REFERENCE_NODE = Node.ENTITY_REFERENCE_NODE = 5;
-var ENTITY_NODE = Node.ENTITY_NODE = 6;
-var PROCESSING_INSTRUCTION_NODE = Node.PROCESSING_INSTRUCTION_NODE = 7;
-var COMMENT_NODE = Node.COMMENT_NODE = 8;
-var DOCUMENT_NODE = Node.DOCUMENT_NODE = 9;
-var DOCUMENT_TYPE_NODE = Node.DOCUMENT_TYPE_NODE = 10;
-var DOCUMENT_FRAGMENT_NODE = Node.DOCUMENT_FRAGMENT_NODE = 11;
-var NOTATION_NODE = Node.NOTATION_NODE = 12;
-
-var DOCUMENT_POSITION_DISCONNECTED = Node.DOCUMENT_POSITION_DISCONNECTED = 0x01;
-var DOCUMENT_POSITION_PRECEDING = Node.DOCUMENT_POSITION_PRECEDING = 0x02;
-var DOCUMENT_POSITION_FOLLOWING = Node.DOCUMENT_POSITION_FOLLOWING = 0x04;
-var DOCUMENT_POSITION_CONTAINS = Node.DOCUMENT_POSITION_CONTAINS = 0x08;
-var DOCUMENT_POSITION_CONTAINED_BY = Node.DOCUMENT_POSITION_CONTAINED_BY = 0x10;
-var DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 0x20;
-
-Node.prototype = Object.create(EventTarget.prototype, {
-
- // Node that are not inserted into the tree inherit a null parent
-
- // XXX: the baseURI attribute is defined by dom core, but
- // a correct implementation of it requires HTML features, so
- // we'll come back to this later.
- baseURI: { get: utils.nyi },
-
- parentElement: { get: function() {
- return (this.parentNode && this.parentNode.nodeType===ELEMENT_NODE) ? this.parentNode : null;
- }},
-
- hasChildNodes: { value: utils.shouldOverride },
-
- firstChild: { get: utils.shouldOverride },
-
- lastChild: { get: utils.shouldOverride },
-
- previousSibling: { get: function() {
- var parent = this.parentNode;
- if (!parent) return null;
- if (this === parent.firstChild) return null;
- return this._previousSibling;
- }},
-
- nextSibling: { get: function() {
- var parent = this.parentNode, next = this._nextSibling;
- if (!parent) return null;
- if (next === parent.firstChild) return null;
- return next;
- }},
-
- textContent: {
- // Should override for DocumentFragment/Element/Attr/Text/PI/Comment
- get: function() { return null; },
- set: function(v) { /* do nothing */ },
- },
-
- _countChildrenOfType: { value: function(type) {
- var sum = 0;
- for (var kid = this.firstChild; kid !== null; kid = kid.nextSibling) {
- if (kid.nodeType === type) sum++;
- }
- return sum;
- }},
-
- _ensureInsertValid: { value: function _ensureInsertValid(node, child, isPreinsert) {
- var parent = this, i, kid;
- if (!node.nodeType) throw new TypeError('not a node');
- // 1. If parent is not a Document, DocumentFragment, or Element
- // node, throw a HierarchyRequestError.
- switch (parent.nodeType) {
- case DOCUMENT_NODE:
- case DOCUMENT_FRAGMENT_NODE:
- case ELEMENT_NODE:
- break;
- default: utils.HierarchyRequestError();
- }
- // 2. If node is a host-including inclusive ancestor of parent,
- // throw a HierarchyRequestError.
- if (node.isAncestor(parent)) utils.HierarchyRequestError();
- // 3. If child is not null and its parent is not parent, then
- // throw a NotFoundError. (replaceChild omits the 'child is not null'
- // and throws a TypeError here if child is null.)
- if (child !== null || !isPreinsert) {
- if (child.parentNode !== parent) utils.NotFoundError();
- }
- // 4. If node is not a DocumentFragment, DocumentType, Element,
- // Text, ProcessingInstruction, or Comment node, throw a
- // HierarchyRequestError.
- switch (node.nodeType) {
- case DOCUMENT_FRAGMENT_NODE:
- case DOCUMENT_TYPE_NODE:
- case ELEMENT_NODE:
- case TEXT_NODE:
- case PROCESSING_INSTRUCTION_NODE:
- case COMMENT_NODE:
- break;
- default: utils.HierarchyRequestError();
- }
- // 5. If either node is a Text node and parent is a document, or
- // node is a doctype and parent is not a document, throw a
- // HierarchyRequestError.
- // 6. If parent is a document, and any of the statements below, switched
- // on node, are true, throw a HierarchyRequestError.
- if (parent.nodeType === DOCUMENT_NODE) {
- switch (node.nodeType) {
- case TEXT_NODE:
- utils.HierarchyRequestError();
- break;
- case DOCUMENT_FRAGMENT_NODE:
- // 6a1. If node has more than one element child or has a Text
- // node child.
- if (node._countChildrenOfType(TEXT_NODE) > 0)
- utils.HierarchyRequestError();
- switch (node._countChildrenOfType(ELEMENT_NODE)) {
- case 0:
- break;
- case 1:
- // 6a2. Otherwise, if node has one element child and either
- // parent has an element child, child is a doctype, or child
- // is not null and a doctype is following child. [preinsert]
- // 6a2. Otherwise, if node has one element child and either
- // parent has an element child that is not child or a
- // doctype is following child. [replaceWith]
- if (child !== null /* always true here for replaceWith */) {
- if (isPreinsert && child.nodeType === DOCUMENT_TYPE_NODE)
- utils.HierarchyRequestError();
- for (kid = child.nextSibling; kid !== null; kid = kid.nextSibling) {
- if (kid.nodeType === DOCUMENT_TYPE_NODE)
- utils.HierarchyRequestError();
- }
- }
- i = parent._countChildrenOfType(ELEMENT_NODE);
- if (isPreinsert) {
- // "parent has an element child"
- if (i > 0)
- utils.HierarchyRequestError();
- } else {
- // "parent has an element child that is not child"
- if (i > 1 || (i === 1 && child.nodeType !== ELEMENT_NODE))
- utils.HierarchyRequestError();
- }
- break;
- default: // 6a1, continued. (more than one Element child)
- utils.HierarchyRequestError();
- }
- break;
- case ELEMENT_NODE:
- // 6b. parent has an element child, child is a doctype, or
- // child is not null and a doctype is following child. [preinsert]
- // 6b. parent has an element child that is not child or a
- // doctype is following child. [replaceWith]
- if (child !== null /* always true here for replaceWith */) {
- if (isPreinsert && child.nodeType === DOCUMENT_TYPE_NODE)
- utils.HierarchyRequestError();
- for (kid = child.nextSibling; kid !== null; kid = kid.nextSibling) {
- if (kid.nodeType === DOCUMENT_TYPE_NODE)
- utils.HierarchyRequestError();
- }
- }
- i = parent._countChildrenOfType(ELEMENT_NODE);
- if (isPreinsert) {
- // "parent has an element child"
- if (i > 0)
- utils.HierarchyRequestError();
- } else {
- // "parent has an element child that is not child"
- if (i > 1 || (i === 1 && child.nodeType !== ELEMENT_NODE))
- utils.HierarchyRequestError();
- }
- break;
- case DOCUMENT_TYPE_NODE:
- // 6c. parent has a doctype child, child is non-null and an
- // element is preceding child, or child is null and parent has
- // an element child. [preinsert]
- // 6c. parent has a doctype child that is not child, or an
- // element is preceding child. [replaceWith]
- if (child === null) {
- if (parent._countChildrenOfType(ELEMENT_NODE))
- utils.HierarchyRequestError();
- } else {
- // child is always non-null for [replaceWith] case
- for (kid = parent.firstChild; kid !== null; kid = kid.nextSibling) {
- if (kid === child) break;
- if (kid.nodeType === ELEMENT_NODE)
- utils.HierarchyRequestError();
- }
- }
- i = parent._countChildrenOfType(DOCUMENT_TYPE_NODE);
- if (isPreinsert) {
- // "parent has an doctype child"
- if (i > 0)
- utils.HierarchyRequestError();
- } else {
- // "parent has an doctype child that is not child"
- if (i > 1 || (i === 1 && child.nodeType !== DOCUMENT_TYPE_NODE))
- utils.HierarchyRequestError();
- }
- break;
- }
- } else {
- // 5, continued: (parent is not a document)
- if (node.nodeType === DOCUMENT_TYPE_NODE) utils.HierarchyRequestError();
- }
- }},
-
- insertBefore: { value: function insertBefore(node, child) {
- var parent = this;
- // 1. Ensure pre-insertion validity
- parent._ensureInsertValid(node, child, true);
- // 2. Let reference child be child.
- var refChild = child;
- // 3. If reference child is node, set it to node's next sibling
- if (refChild === node) { refChild = node.nextSibling; }
- // 4. Adopt node into parent's node document.
- parent.doc.adoptNode(node);
- // 5. Insert node into parent before reference child.
- node._insertOrReplace(parent, refChild, false);
- // 6. Return node
- return node;
- }},
-
-
- appendChild: { value: function(child) {
- // This invokes _appendChild after doing validity checks.
- return this.insertBefore(child, null);
- }},
-
- _appendChild: { value: function(child) {
- child._insertOrReplace(this, null, false);
- }},
-
- removeChild: { value: function removeChild(child) {
- var parent = this;
- if (!child.nodeType) throw new TypeError('not a node');
- if (child.parentNode !== parent) utils.NotFoundError();
- child.remove();
- return child;
- }},
-
- // To replace a `child` with `node` within a `parent` (this)
- replaceChild: { value: function replaceChild(node, child) {
- var parent = this;
- // Ensure validity (slight differences from pre-insertion check)
- parent._ensureInsertValid(node, child, false);
- // Adopt node into parent's node document.
- if (node.doc !== parent.doc) {
- // XXX adoptNode has side-effect of removing node from its parent
- // and generating a mutation event, thus causing the _insertOrReplace
- // to generate two deletes and an insert instead of a 'move'
- // event. It looks like the new MutationObserver stuff avoids
- // this problem, but for now let's only adopt (ie, remove `node`
- // from its parent) here if we need to.
- parent.doc.adoptNode(node);
- }
- // Do the replace.
- node._insertOrReplace(parent, child, true);
- return child;
- }},
-
- // See: http://ejohn.org/blog/comparing-document-position/
- contains: { value: function contains(node) {
- if (node === null) { return false; }
- if (this === node) { return true; /* inclusive descendant */ }
- /* jshint bitwise: false */
- return (this.compareDocumentPosition(node) &
- DOCUMENT_POSITION_CONTAINED_BY) !== 0;
- }},
-
- compareDocumentPosition: { value: function compareDocumentPosition(that){
- // Basic algorithm for finding the relative position of two nodes.
- // Make a list the ancestors of each node, starting with the
- // document element and proceeding down to the nodes themselves.
- // Then, loop through the lists, looking for the first element
- // that differs. The order of those two elements give the
- // order of their descendant nodes. Or, if one list is a prefix
- // of the other one, then that node contains the other.
-
- if (this === that) return 0;
-
- // If they're not owned by the same document or if one is rooted
- // and one is not, then they're disconnected.
- if (this.doc !== that.doc ||
- this.rooted !== that.rooted)
- return (DOCUMENT_POSITION_DISCONNECTED +
- DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC);
-
- // Get arrays of ancestors for this and that
- var these = [], those = [];
- for(var n = this; n !== null; n = n.parentNode) these.push(n);
- for(n = that; n !== null; n = n.parentNode) those.push(n);
- these.reverse(); // So we start with the outermost
- those.reverse();
-
- if (these[0] !== those[0]) // No common ancestor
- return (DOCUMENT_POSITION_DISCONNECTED +
- DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC);
-
- n = Math.min(these.length, those.length);
- for(var i = 1; i < n; i++) {
- if (these[i] !== those[i]) {
- // We found two different ancestors, so compare
- // their positions
- if (these[i].index < those[i].index)
- return DOCUMENT_POSITION_FOLLOWING;
- else
- return DOCUMENT_POSITION_PRECEDING;
- }
- }
-
- // If we get to here, then one of the nodes (the one with the
- // shorter list of ancestors) contains the other one.
- if (these.length < those.length)
- return (DOCUMENT_POSITION_FOLLOWING +
- DOCUMENT_POSITION_CONTAINED_BY);
- else
- return (DOCUMENT_POSITION_PRECEDING +
- DOCUMENT_POSITION_CONTAINS);
- }},
-
- isSameNode: {value : function isSameNode(node) {
- return this === node;
- }},
-
-
- // This method implements the generic parts of node equality testing
- // and defers to the (non-recursive) type-specific isEqual() method
- // defined by subclasses
- isEqualNode: { value: function isEqualNode(node) {
- if (!node) return false;
- if (node.nodeType !== this.nodeType) return false;
-
- // Check type-specific properties for equality
- if (!this.isEqual(node)) return false;
-
- // Now check children for number and equality
- for (var c1 = this.firstChild, c2 = node.firstChild;
- c1 && c2;
- c1 = c1.nextSibling, c2 = c2.nextSibling) {
- if (!c1.isEqualNode(c2)) return false;
- }
- return c1 === null && c2 === null;
- }},
-
- // This method delegates shallow cloning to a clone() method
- // that each concrete subclass must implement
- cloneNode: { value: function(deep) {
- // Clone this node
- var clone = this.clone();
-
- // Handle the recursive case if necessary
- if (deep) {
- for (var kid = this.firstChild; kid !== null; kid = kid.nextSibling) {
- clone._appendChild(kid.cloneNode(true));
- }
- }
-
- return clone;
- }},
-
- lookupPrefix: { value: function lookupPrefix(ns) {
- var e;
- if (ns === '' || ns === null || ns === undefined) return null;
- switch(this.nodeType) {
- case ELEMENT_NODE:
- return this._lookupNamespacePrefix(ns, this);
- case DOCUMENT_NODE:
- e = this.documentElement;
- return e ? e.lookupPrefix(ns) : null;
- case ENTITY_NODE:
- case NOTATION_NODE:
- case DOCUMENT_FRAGMENT_NODE:
- case DOCUMENT_TYPE_NODE:
- return null;
- case ATTRIBUTE_NODE:
- e = this.ownerElement;
- return e ? e.lookupPrefix(ns) : null;
- default:
- e = this.parentElement;
- return e ? e.lookupPrefix(ns) : null;
- }
- }},
-
-
- lookupNamespaceURI: {value: function lookupNamespaceURI(prefix) {
- if (prefix === '' || prefix === undefined) { prefix = null; }
- var e;
- switch(this.nodeType) {
- case ELEMENT_NODE:
- return utils.shouldOverride();
- case DOCUMENT_NODE:
- e = this.documentElement;
- return e ? e.lookupNamespaceURI(prefix) : null;
- case ENTITY_NODE:
- case NOTATION_NODE:
- case DOCUMENT_TYPE_NODE:
- case DOCUMENT_FRAGMENT_NODE:
- return null;
- case ATTRIBUTE_NODE:
- e = this.ownerElement;
- return e ? e.lookupNamespaceURI(prefix) : null;
- default:
- e = this.parentElement;
- return e ? e.lookupNamespaceURI(prefix) : null;
- }
- }},
-
- isDefaultNamespace: { value: function isDefaultNamespace(ns) {
- if (ns === '' || ns === undefined) { ns = null; }
- var defaultNamespace = this.lookupNamespaceURI(null);
- return (defaultNamespace === ns);
- }},
-
- // Utility methods for nodes. Not part of the DOM
-
- // Return the index of this node in its parent.
- // Throw if no parent, or if this node is not a child of its parent
- index: { get: function() {
- var parent = this.parentNode;
- if (this === parent.firstChild) return 0; // fast case
- var kids = parent.childNodes;
- if (this._index === undefined || kids[this._index] !== this) {
- // Ensure that we don't have an O(N^2) blowup if none of the
- // kids have defined indices yet and we're traversing via
- // nextSibling or previousSibling
- for (var i=0; i<kids.length; i++) {
- kids[i]._index = i;
- }
- utils.assert(kids[this._index] === this);
- }
- return this._index;
- }},
-
- // Return true if this node is equal to or is an ancestor of that node
- // Note that nodes are considered to be ancestors of themselves
- isAncestor: { value: function(that) {
- // If they belong to different documents, then they're unrelated.
- if (this.doc !== that.doc) return false;
- // If one is rooted and one isn't then they're not related
- if (this.rooted !== that.rooted) return false;
-
- // Otherwise check by traversing the parentNode chain
- for(var e = that; e; e = e.parentNode) {
- if (e === this) return true;
- }
- return false;
- }},
-
- // DOMINO Changed the behavior to conform with the specs. See:
- // https://groups.google.com/d/topic/mozilla.dev.platform/77sIYcpdDmc/discussion
- ensureSameDoc: { value: function(that) {
- if (that.ownerDocument === null) {
- that.ownerDocument = this.doc;
- }
- else if(that.ownerDocument !== this.doc) {
- utils.WrongDocumentError();
- }
- }},
-
- removeChildren: { value: utils.shouldOverride },
-
- // Insert this node as a child of parent before the specified child,
- // or insert as the last child of parent if specified child is null,
- // or replace the specified child with this node, firing mutation events as
- // necessary
- _insertOrReplace: { value: function _insertOrReplace(parent, before, isReplace) {
- var child = this, before_index, i;
-
- if (child.nodeType === DOCUMENT_FRAGMENT_NODE && child.rooted) {
- utils.HierarchyRequestError();
- }
-
- /* Ensure index of `before` is cached before we (possibly) remove it. */
- if (parent._childNodes) {
- before_index = (before === null) ? parent._childNodes.length :
- before.index; /* ensure _index is cached */
-
- // If we are already a child of the specified parent, then
- // the index may have to be adjusted.
- if (child.parentNode === parent) {
- var child_index = child.index;
- // If the child is before the spot it is to be inserted at,
- // then when it is removed, the index of that spot will be
- // reduced.
- if (child_index < before_index) {
- before_index--;
- }
- }
- }
-
- // Delete the old child
- if (isReplace) {
- if (before.rooted) before.doc.mutateRemove(before);
- before.parentNode = null;
- }
-
- var n = before;
- if (n === null) { n = parent.firstChild; }
-
- // If both the child and the parent are rooted, then we want to
- // transplant the child without uprooting and rerooting it.
- var bothRooted = child.rooted && parent.rooted;
- if (child.nodeType === DOCUMENT_FRAGMENT_NODE) {
- var spliceArgs = [0, isReplace ? 1 : 0], next;
- for (var kid = child.firstChild; kid !== null; kid = next) {
- next = kid.nextSibling;
- spliceArgs.push(kid);
- kid.parentNode = parent;
- }
- var len = spliceArgs.length;
- // Add all nodes to the new parent, overwriting the old child
- if (isReplace) {
- LinkedList.replace(n, len > 2 ? spliceArgs[2] : null);
- } else if (len > 2 && n !== null) {
- LinkedList.insertBefore(spliceArgs[2], n);
- }
- if (parent._childNodes) {
- spliceArgs[0] = (before === null) ?
- parent._childNodes.length : before._index;
- parent._childNodes.splice.apply(parent._childNodes, spliceArgs);
- for (i=2; i<len; i++) {
- spliceArgs[i]._index = spliceArgs[0] + (i - 2);
- }
- } else if (parent._firstChild === before) {
- if (len > 2) {
- parent._firstChild = spliceArgs[2];
- } else if (isReplace) {
- parent._firstChild = null;
- }
- }
- // Remove all nodes from the document fragment
- if (child._childNodes) {
- child._childNodes.length = 0;
- } else {
- child._firstChild = null;
- }
- // Call the mutation handlers
- // Use spliceArgs since the original array has been destroyed. The
- // liveness guarantee requires us to clone the array so that
- // references to the childNodes of the DocumentFragment will be empty
- // when the insertion handlers are called.
- if (parent.rooted) {
- parent.modify();
- for (i = 2; i < len; i++) {
- parent.doc.mutateInsert(spliceArgs[i]);
- }
- }
- } else {
- if (before === child) { return; }
- if (bothRooted) {
- // Remove the child from its current position in the tree
- // without calling remove(), since we don't want to uproot it.
- child._remove();
- } else if (child.parentNode) {
- child.remove();
- }
-
- // Insert it as a child of its new parent
- child.parentNode = parent;
- if (isReplace) {
- LinkedList.replace(n, child);
- if (parent._childNodes) {
- child._index = before_index;
- parent._childNodes[before_index] = child;
- } else if (parent._firstChild === before) {
- parent._firstChild = child;
- }
- } else {
- if (n !== null) {
- LinkedList.insertBefore(child, n);
- }
- if (parent._childNodes) {
- child._index = before_index;
- parent._childNodes.splice(before_index, 0, child);
- } else if (parent._firstChild === before) {
- parent._firstChild = child;
- }
- }
- if (bothRooted) {
- parent.modify();
- // Generate a move mutation event
- parent.doc.mutateMove(child);
- } else if (parent.rooted) {
- parent.modify();
- parent.doc.mutateInsert(child);
- }
- }
- }},
-
-
- // Return the lastModTime value for this node. (For use as a
- // cache invalidation mechanism. If the node does not already
- // have one, initialize it from the owner document's modclock
- // property. (Note that modclock does not return the actual
- // time; it is simply a counter incremented on each document
- // modification)
- lastModTime: { get: function() {
- if (!this._lastModTime) {
- this._lastModTime = this.doc.modclock;
- }
- return this._lastModTime;
- }},
-
- // Increment the owner document's modclock and use the new
- // value to update the lastModTime value for this node and
- // all of its ancestors. Nodes that have never had their
- // lastModTime value queried do not need to have a
- // lastModTime property set on them since there is no
- // previously queried value to ever compare the new value
- // against, so only update nodes that already have a
- // _lastModTime property.
- modify: { value: function() {
- if (this.doc.modclock) { // Skip while doc.modclock == 0
- var time = ++this.doc.modclock;
- for(var n = this; n; n = n.parentElement) {
- if (n._lastModTime) {
- n._lastModTime = time;
- }
- }
- }
- }},
-
- // This attribute is not part of the DOM but is quite helpful.
- // It returns the document with which a node is associated. Usually
- // this is the ownerDocument. But ownerDocument is null for the
- // document object itself, so this is a handy way to get the document
- // regardless of the node type
- doc: { get: function() {
- return this.ownerDocument || this;
- }},
-
-
- // If the node has a nid (node id), then it is rooted in a document
- rooted: { get: function() {
- return !!this._nid;
- }},
-
- normalize: { value: function() {
- var next;
- for (var child=this.firstChild; child !== null; child=next) {
- next = child.nextSibling;
-
- if (child.normalize) {
- child.normalize();
- }
-
- if (child.nodeType !== Node.TEXT_NODE) {
- continue;
- }
-
- if (child.nodeValue === "") {
- this.removeChild(child);
- continue;
- }
-
- var prevChild = child.previousSibling;
- if (prevChild === null) {
- continue;
- } else if (prevChild.nodeType === Node.TEXT_NODE) {
- // merge this with previous and remove the child
- prevChild.appendData(child.nodeValue);
- this.removeChild(child);
- }
- }
- }},
-
- // Convert the children of a node to an HTML string.
- // This is used by the innerHTML getter
- // The serialization spec is at:
- // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#serializing-html-fragments
- //
- // The serialization logic is intentionally implemented in a separate
- // `NodeUtils` helper instead of the more obvious choice of a private
- // `_serializeOne()` method on the `Node.prototype` in order to avoid
- // the megamorphic `this._serializeOne` property access, which reduces
- // performance unnecessarily. If you need specialized behavior for a
- // certain subclass, you'll need to implement that in `NodeUtils`.
- // See https://github.com/fgnass/domino/pull/142 for more information.
- serialize: { value: function() {
- var s = '';
- for (var kid = this.firstChild; kid !== null; kid = kid.nextSibling) {
- s += NodeUtils.serializeOne(kid, this);
- }
- return s;
- }},
-
- // Non-standard, but often useful for debugging.
- outerHTML: {
- get: function() {
- return NodeUtils.serializeOne(this, { nodeType: 0 });
- },
- set: utils.nyi,
- },
-
- // mirror node type properties in the prototype, so they are present
- // in instances of Node (and subclasses)
- ELEMENT_NODE: { value: ELEMENT_NODE },
- ATTRIBUTE_NODE: { value: ATTRIBUTE_NODE },
- TEXT_NODE: { value: TEXT_NODE },
- CDATA_SECTION_NODE: { value: CDATA_SECTION_NODE },
- ENTITY_REFERENCE_NODE: { value: ENTITY_REFERENCE_NODE },
- ENTITY_NODE: { value: ENTITY_NODE },
- PROCESSING_INSTRUCTION_NODE: { value: PROCESSING_INSTRUCTION_NODE },
- COMMENT_NODE: { value: COMMENT_NODE },
- DOCUMENT_NODE: { value: DOCUMENT_NODE },
- DOCUMENT_TYPE_NODE: { value: DOCUMENT_TYPE_NODE },
- DOCUMENT_FRAGMENT_NODE: { value: DOCUMENT_FRAGMENT_NODE },
- NOTATION_NODE: { value: NOTATION_NODE },
-
- DOCUMENT_POSITION_DISCONNECTED: { value: DOCUMENT_POSITION_DISCONNECTED },
- DOCUMENT_POSITION_PRECEDING: { value: DOCUMENT_POSITION_PRECEDING },
- DOCUMENT_POSITION_FOLLOWING: { value: DOCUMENT_POSITION_FOLLOWING },
- DOCUMENT_POSITION_CONTAINS: { value: DOCUMENT_POSITION_CONTAINS },
- DOCUMENT_POSITION_CONTAINED_BY: { value: DOCUMENT_POSITION_CONTAINED_BY },
- DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: { value: DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC },
-});
--- a/cmd/gojafs/domino/domino-lib/NodeFilter.js
+++ /dev/null
@@ -1,24 +1,0 @@
-"use strict";
-var NodeFilter = {
- // Constants for acceptNode()
- FILTER_ACCEPT: 1,
- FILTER_REJECT: 2,
- FILTER_SKIP: 3,
-
- // Constants for whatToShow
- SHOW_ALL: 0xFFFFFFFF,
- SHOW_ELEMENT: 0x1,
- SHOW_ATTRIBUTE: 0x2, // historical
- SHOW_TEXT: 0x4,
- SHOW_CDATA_SECTION: 0x8, // historical
- SHOW_ENTITY_REFERENCE: 0x10, // historical
- SHOW_ENTITY: 0x20, // historical
- SHOW_PROCESSING_INSTRUCTION: 0x40,
- SHOW_COMMENT: 0x80,
- SHOW_DOCUMENT: 0x100,
- SHOW_DOCUMENT_TYPE: 0x200,
- SHOW_DOCUMENT_FRAGMENT: 0x400,
- SHOW_NOTATION: 0x800 // historical
-};
-
-module.exports = (NodeFilter.constructor = NodeFilter.prototype = NodeFilter);
--- a/cmd/gojafs/domino/domino-lib/NodeIterator.js
+++ /dev/null
@@ -1,217 +1,0 @@
-"use strict";
-module.exports = NodeIterator;
-
-var NodeFilter = require('./NodeFilter');
-var NodeTraversal = require('./NodeTraversal');
-var utils = require('./utils');
-
-/* Private methods and helpers */
-
-/**
- * @based on WebKit's NodeIterator::moveToNext and NodeIterator::moveToPrevious
- * https://trac.webkit.org/browser/trunk/Source/WebCore/dom/NodeIterator.cpp?rev=186279#L51
- */
-function move(node, stayWithin, directionIsNext) {
- if (directionIsNext) {
- return NodeTraversal.next(node, stayWithin);
- } else {
- if (node === stayWithin) {
- return null;
- }
- return NodeTraversal.previous(node, null);
- }
-}
-
-function isInclusiveAncestor(node, possibleChild) {
- for ( ; possibleChild; possibleChild = possibleChild.parentNode) {
- if (node === possibleChild) { return true; }
- }
- return false;
-}
-
-/**
- * @spec http://www.w3.org/TR/dom/#concept-nodeiterator-traverse
- * @method
- * @access private
- * @param {NodeIterator} ni
- * @param {string} direction One of 'next' or 'previous'.
- * @return {Node|null}
- */
-function traverse(ni, directionIsNext) {
- var node, beforeNode;
- node = ni._referenceNode;
- beforeNode = ni._pointerBeforeReferenceNode;
- while (true) {
- if (beforeNode === directionIsNext) {
- beforeNode = !beforeNode;
- } else {
- node = move(node, ni._root, directionIsNext);
- if (node === null) {
- return null;
- }
- }
- var result = ni._internalFilter(node);
- if (result === NodeFilter.FILTER_ACCEPT) {
- break;
- }
- }
- ni._referenceNode = node;
- ni._pointerBeforeReferenceNode = beforeNode;
- return node;
-}
-
-/* Public API */
-
-/**
- * Implemented version: http://www.w3.org/TR/2015/WD-dom-20150618/#nodeiterator
- * Latest version: http://www.w3.org/TR/dom/#nodeiterator
- *
- * @constructor
- * @param {Node} root
- * @param {number} whatToShow [optional]
- * @param {Function|NodeFilter} filter [optional]
- * @throws Error
- */
-function NodeIterator(root, whatToShow, filter) {
- if (!root || !root.nodeType) {
- utils.NotSupportedError();
- }
-
- // Read-only properties
- this._root = root;
- this._referenceNode = root;
- this._pointerBeforeReferenceNode = true;
- this._whatToShow = Number(whatToShow) || 0;
- this._filter = filter || null;
- this._active = false;
- // Record active node iterators in the document, in order to perform
- // "node iterator pre-removal steps".
- root.doc._attachNodeIterator(this);
-}
-
-Object.defineProperties(NodeIterator.prototype, {
- root: { get: function root() {
- return this._root;
- } },
- referenceNode: { get: function referenceNode() {
- return this._referenceNode;
- } },
- pointerBeforeReferenceNode: { get: function pointerBeforeReferenceNode() {
- return this._pointerBeforeReferenceNode;
- } },
- whatToShow: { get: function whatToShow() {
- return this._whatToShow;
- } },
- filter: { get: function filter() {
- return this._filter;
- } },
-
- /**
- * @method
- * @param {Node} node
- * @return {Number} Constant NodeFilter.FILTER_ACCEPT,
- * NodeFilter.FILTER_REJECT or NodeFilter.FILTER_SKIP.
- */
- _internalFilter: { value: function _internalFilter(node) {
- /* jshint bitwise: false */
- var result, filter;
- if (this._active) {
- utils.InvalidStateError();
- }
-
- // Maps nodeType to whatToShow
- if (!(((1 << (node.nodeType - 1)) & this._whatToShow))) {
- return NodeFilter.FILTER_SKIP;
- }
-
- filter = this._filter;
- if (filter === null) {
- result = NodeFilter.FILTER_ACCEPT;
- } else {
- this._active = true;
- try {
- if (typeof filter === 'function') {
- result = filter(node);
- } else {
- result = filter.acceptNode(node);
- }
- } finally {
- this._active = false;
- }
- }
-
- // Note that coercing to a number means that
- // `true` becomes `1` (which is NodeFilter.FILTER_ACCEPT)
- // `false` becomes `0` (neither accept, reject, or skip)
- return (+result);
- } },
-
- /**
- * @spec https://dom.spec.whatwg.org/#nodeiterator-pre-removing-steps
- * @method
- * @return void
- */
- _preremove: { value: function _preremove(toBeRemovedNode) {
- if (isInclusiveAncestor(toBeRemovedNode, this._root)) { return; }
- if (!isInclusiveAncestor(toBeRemovedNode, this._referenceNode)) { return; }
- if (this._pointerBeforeReferenceNode) {
- var next = toBeRemovedNode;
- while (next.lastChild) {
- next = next.lastChild;
- }
- next = NodeTraversal.next(next, this.root);
- if (next) {
- this._referenceNode = next;
- return;
- }
- this._pointerBeforeReferenceNode = false;
- // fall through
- }
- if (toBeRemovedNode.previousSibling === null) {
- this._referenceNode = toBeRemovedNode.parentNode;
- } else {
- this._referenceNode = toBeRemovedNode.previousSibling;
- var lastChild;
- for (lastChild = this._referenceNode.lastChild;
- lastChild;
- lastChild = this._referenceNode.lastChild) {
- this._referenceNode = lastChild;
- }
- }
- } },
-
- /**
- * @spec http://www.w3.org/TR/dom/#dom-nodeiterator-nextnode
- * @method
- * @return {Node|null}
- */
- nextNode: { value: function nextNode() {
- return traverse(this, true);
- } },
-
- /**
- * @spec http://www.w3.org/TR/dom/#dom-nodeiterator-previousnode
- * @method
- * @return {Node|null}
- */
- previousNode: { value: function previousNode() {
- return traverse(this, false);
- } },
-
- /**
- * @spec http://www.w3.org/TR/dom/#dom-nodeiterator-detach
- * @method
- * @return void
- */
- detach: { value: function detach() {
- /* "The detach() method must do nothing.
- * Its functionality (disabling a NodeIterator object) was removed,
- * but the method itself is preserved for compatibility.
- */
- } },
-
- /** For compatibility with web-platform-tests. */
- toString: { value: function toString() {
- return "[object NodeIterator]";
- } },
-});
--- a/cmd/gojafs/domino/domino-lib/NodeList.es5.js
+++ /dev/null
@@ -1,15 +1,0 @@
-"use strict";
-
-// No support for subclassing array, return an actual Array object.
-function item(i) {
- /* jshint validthis: true */
- return this[i] || null;
-}
-
-function NodeList(a) {
- if (!a) a = [];
- a.item = item;
- return a;
-}
-
-module.exports = NodeList;
--- a/cmd/gojafs/domino/domino-lib/NodeList.es6.js
+++ /dev/null
@@ -1,12 +1,0 @@
-/* jshint esversion: 6 */
-"use strict";
-
-module.exports = class NodeList extends Array {
- constructor(a) {
- super((a && a.length) || 0);
- if (a) {
- for (var idx in a) { this[idx] = a[idx]; }
- }
- }
- item(i) { return this[i] || null; }
-};
--- a/cmd/gojafs/domino/domino-lib/NodeList.js
+++ /dev/null
@@ -1,13 +1,0 @@
-"use strict";
-
-var NodeList;
-
-try {
- // Attempt to use ES6-style Array subclass if possible.
- NodeList = require('./NodeList.es6.js');
-} catch (e) {
- // No support for subclassing array, return an actual Array object.
- NodeList = require('./NodeList.es5.js');
-}
-
-module.exports = NodeList;
--- a/cmd/gojafs/domino/domino-lib/NodeTraversal.js
+++ /dev/null
@@ -1,87 +1,0 @@
-"use strict";
-/* exported NodeTraversal */
-var NodeTraversal = module.exports = {
- nextSkippingChildren: nextSkippingChildren,
- nextAncestorSibling: nextAncestorSibling,
- next: next,
- previous: previous,
- deepLastChild: deepLastChild
-};
-
-/**
- * @based on WebKit's NodeTraversal::nextSkippingChildren
- * https://trac.webkit.org/browser/trunk/Source/WebCore/dom/NodeTraversal.h?rev=179143#L109
- */
-function nextSkippingChildren(node, stayWithin) {
- if (node === stayWithin) {
- return null;
- }
- if (node.nextSibling !== null) {
- return node.nextSibling;
- }
- return nextAncestorSibling(node, stayWithin);
-}
-
-/**
- * @based on WebKit's NodeTraversal::nextAncestorSibling
- * https://trac.webkit.org/browser/trunk/Source/WebCore/dom/NodeTraversal.cpp?rev=179143#L93
- */
-function nextAncestorSibling(node, stayWithin) {
- for (node = node.parentNode; node !== null; node = node.parentNode) {
- if (node === stayWithin) {
- return null;
- }
- if (node.nextSibling !== null) {
- return node.nextSibling;
- }
- }
- return null;
-}
-
-/**
- * @based on WebKit's NodeTraversal::next
- * https://trac.webkit.org/browser/trunk/Source/WebCore/dom/NodeTraversal.h?rev=179143#L99
- */
-function next(node, stayWithin) {
- var n;
- n = node.firstChild;
- if (n !== null) {
- return n;
- }
- if (node === stayWithin) {
- return null;
- }
- n = node.nextSibling;
- if (n !== null) {
- return n;
- }
- return nextAncestorSibling(node, stayWithin);
-}
-
-/**
- * @based on WebKit's NodeTraversal::deepLastChild
- * https://trac.webkit.org/browser/trunk/Source/WebCore/dom/NodeTraversal.cpp?rev=179143#L116
- */
-function deepLastChild(node) {
- while (node.lastChild) {
- node = node.lastChild;
- }
- return node;
-}
-
-/**
- * @based on WebKit's NodeTraversal::previous
- * https://trac.webkit.org/browser/trunk/Source/WebCore/dom/NodeTraversal.h?rev=179143#L121
- */
-function previous(node, stayWithin) {
- var p;
- p = node.previousSibling;
- if (p !== null) {
- return deepLastChild(p);
- }
- p = node.parentNode;
- if (p === stayWithin) {
- return null;
- }
- return p;
-}
--- a/cmd/gojafs/domino/domino-lib/NodeUtils.js
+++ /dev/null
@@ -1,168 +1,0 @@
-"use strict";
-module.exports = {
- // NOTE: The `serializeOne()` function used to live on the `Node.prototype`
- // as a private method `Node#_serializeOne(child)`, however that requires
- // a megamorphic property access `this._serializeOne` just to get to the
- // method, and this is being done on lots of different `Node` subclasses,
- // which puts a lot of pressure on V8's megamorphic stub cache. So by
- // moving the helper off of the `Node.prototype` and into a separate
- // function in this helper module, we get a monomorphic property access
- // `NodeUtils.serializeOne` to get to the function and reduce pressure
- // on the megamorphic stub cache.
- // See https://github.com/fgnass/domino/pull/142 for more information.
- serializeOne: serializeOne
-};
-
-var utils = require('./utils');
-var NAMESPACE = utils.NAMESPACE;
-
-var hasRawContent = {
- STYLE: true,
- SCRIPT: true,
- XMP: true,
- IFRAME: true,
- NOEMBED: true,
- NOFRAMES: true,
- PLAINTEXT: true
-};
-
-var emptyElements = {
- area: true,
- base: true,
- basefont: true,
- bgsound: true,
- br: true,
- col: true,
- embed: true,
- frame: true,
- hr: true,
- img: true,
- input: true,
- keygen: true,
- link: true,
- meta: true,
- param: true,
- source: true,
- track: true,
- wbr: true
-};
-
-var extraNewLine = {
- /* Removed in https://github.com/whatwg/html/issues/944
- pre: true,
- textarea: true,
- listing: true
- */
-};
-
-function escape(s) {
- return s.replace(/[&<>\u00A0]/g, function(c) {
- switch(c) {
- case '&': return '&';
- case '<': return '<';
- case '>': return '>';
- case '\u00A0': return ' ';
- }
- });
-}
-
-function escapeAttr(s) {
- var toEscape = /[&"\u00A0]/g;
- if (!toEscape.test(s)) {
- // nothing to do, fast path
- return s;
- } else {
- return s.replace(toEscape, function(c) {
- switch(c) {
- case '&': return '&';
- case '"': return '"';
- case '\u00A0': return ' ';
- }
- });
- }
-}
-
-function attrname(a) {
- var ns = a.namespaceURI;
- if (!ns)
- return a.localName;
- if (ns === NAMESPACE.XML)
- return 'xml:' + a.localName;
- if (ns === NAMESPACE.XLINK)
- return 'xlink:' + a.localName;
-
- if (ns === NAMESPACE.XMLNS) {
- if (a.localName === 'xmlns') return 'xmlns';
- else return 'xmlns:' + a.localName;
- }
- return a.name;
-}
-
-function serializeOne(kid, parent) {
- var s = '';
- switch(kid.nodeType) {
- case 1: //ELEMENT_NODE
- var ns = kid.namespaceURI;
- var html = ns === NAMESPACE.HTML;
- var tagname = (html || ns === NAMESPACE.SVG || ns === NAMESPACE.MATHML) ? kid.localName : kid.tagName;
-
- s += '<' + tagname;
-
- for(var j = 0, k = kid._numattrs; j < k; j++) {
- var a = kid._attr(j);
- s += ' ' + attrname(a);
- if (a.value !== undefined) s += '="' + escapeAttr(a.value) + '"';
- }
- s += '>';
-
- if (!(html && emptyElements[tagname])) {
- var ss = kid.serialize();
- if (html && extraNewLine[tagname] && ss.charAt(0)==='\n') s += '\n';
- // Serialize children and add end tag for all others
- s += ss;
- s += '</' + tagname + '>';
- }
- break;
- case 3: //TEXT_NODE
- case 4: //CDATA_SECTION_NODE
- var parenttag;
- if (parent.nodeType === 1 /*ELEMENT_NODE*/ &&
- parent.namespaceURI === NAMESPACE.HTML)
- parenttag = parent.tagName;
- else
- parenttag = '';
-
- if (hasRawContent[parenttag] ||
- (parenttag==='NOSCRIPT' && parent.ownerDocument._scripting_enabled)) {
- s += kid.data;
- } else {
- s += escape(kid.data);
- }
- break;
- case 8: //COMMENT_NODE
- s += '<!--' + kid.data + '-->';
- break;
- case 7: //PROCESSING_INSTRUCTION_NODE
- s += '<?' + kid.target + ' ' + kid.data + '?>';
- break;
- case 10: //DOCUMENT_TYPE_NODE
- s += '<!DOCTYPE ' + kid.name;
-
- if (false) {
- // Latest HTML serialization spec omits the public/system ID
- if (kid.publicID) {
- s += ' PUBLIC "' + kid.publicId + '"';
- }
-
- if (kid.systemId) {
- s += ' "' + kid.systemId + '"';
- }
- }
-
- s += '>';
- break;
- default:
- utils.InvalidStateError();
- }
- return s;
-}
--- a/cmd/gojafs/domino/domino-lib/NonDocumentTypeChildNode.js
+++ /dev/null
@@ -1,26 +1,0 @@
-"use strict";
-var Node = require('./Node');
-
-var NonDocumentTypeChildNode = {
-
- nextElementSibling: { get: function() {
- if (this.parentNode) {
- for (var kid = this.nextSibling; kid !== null; kid = kid.nextSibling) {
- if (kid.nodeType === Node.ELEMENT_NODE) return kid;
- }
- }
- return null;
- }},
-
- previousElementSibling: { get: function() {
- if (this.parentNode) {
- for (var kid = this.previousSibling; kid !== null; kid = kid.previousSibling) {
- if (kid.nodeType === Node.ELEMENT_NODE) return kid;
- }
- }
- return null;
- }}
-
-};
-
-module.exports = NonDocumentTypeChildNode;
--- a/cmd/gojafs/domino/domino-lib/ProcessingInstruction.js
+++ /dev/null
@@ -1,43 +1,0 @@
-"use strict";
-module.exports = ProcessingInstruction;
-
-var Node = require('./Node');
-var CharacterData = require('./CharacterData');
-
-function ProcessingInstruction(doc, target, data) {
- CharacterData.call(this);
- this.nodeType = Node.PROCESSING_INSTRUCTION_NODE;
- this.ownerDocument = doc;
- this.target = target;
- this._data = data;
-}
-
-var nodeValue = {
- get: function() { return this._data; },
- set: function(v) {
- if (v === null || v === undefined) { v = ''; } else { v = String(v); }
- this._data = v;
- if (this.rooted) this.ownerDocument.mutateValue(this);
- }
-};
-
-ProcessingInstruction.prototype = Object.create(CharacterData.prototype, {
- nodeName: { get: function() { return this.target; }},
- nodeValue: nodeValue,
- textContent: nodeValue,
- data: {
- get: nodeValue.get,
- set: function(v) {
- nodeValue.set.call(this, v===null ? '' : String(v));
- },
- },
-
- // Utility methods
- clone: { value: function clone() {
- return new ProcessingInstruction(this.ownerDocument, this.target, this._data);
- }},
- isEqual: { value: function isEqual(n) {
- return this.target === n.target && this._data === n._data;
- }}
-
-});
--- a/cmd/gojafs/domino/domino-lib/Text.js
+++ /dev/null
@@ -1,74 +1,0 @@
-"use strict";
-module.exports = Text;
-
-var utils = require('./utils');
-var Node = require('./Node');
-var CharacterData = require('./CharacterData');
-
-function Text(doc, data) {
- CharacterData.call(this);
- this.nodeType = Node.TEXT_NODE;
- this.ownerDocument = doc;
- this._data = data;
- this._index = undefined;
-}
-
-var nodeValue = {
- get: function() { return this._data; },
- set: function(v) {
- if (v === null || v === undefined) { v = ''; } else { v = String(v); }
- if (v === this._data) return;
- this._data = v;
- if (this.rooted)
- this.ownerDocument.mutateValue(this);
- if (this.parentNode &&
- this.parentNode._textchangehook)
- this.parentNode._textchangehook(this);
- }
-};
-
-Text.prototype = Object.create(CharacterData.prototype, {
- nodeName: { value: "#text" },
- // These three attributes are all the same.
- // The data attribute has a [TreatNullAs=EmptyString] but we'll
- // implement that at the interface level
- nodeValue: nodeValue,
- textContent: nodeValue,
- data: {
- get: nodeValue.get,
- set: function(v) {
- nodeValue.set.call(this, v===null ? '' : String(v));
- },
- },
-
- splitText: { value: function splitText(offset) {
- if (offset > this._data.length || offset < 0) utils.IndexSizeError();
-
- var newdata = this._data.substring(offset),
- newnode = this.ownerDocument.createTextNode(newdata);
- this.data = this.data.substring(0, offset);
-
- var parent = this.parentNode;
- if (parent !== null)
- parent.insertBefore(newnode, this.nextSibling);
-
- return newnode;
- }},
-
- wholeText: { get: function wholeText() {
- var result = this.textContent;
- for (var next = this.nextSibling; next; next = next.nextSibling) {
- if (next.nodeType !== Node.TEXT_NODE) { break; }
- result += next.textContent;
- }
- return result;
- }},
- // Obsolete, removed from spec.
- replaceWholeText: { value: utils.nyi },
-
- // Utility methods
- clone: { value: function clone() {
- return new Text(this.ownerDocument, this._data);
- }},
-
-});
--- a/cmd/gojafs/domino/domino-lib/TreeWalker.js
+++ /dev/null
@@ -1,336 +1,0 @@
-"use strict";
-module.exports = TreeWalker;
-
-var Node = require('./Node');
-var NodeFilter = require('./NodeFilter');
-var NodeTraversal = require('./NodeTraversal');
-var utils = require('./utils');
-
-var mapChild = {
- first: 'firstChild',
- last: 'lastChild',
- next: 'firstChild',
- previous: 'lastChild'
-};
-
-var mapSibling = {
- first: 'nextSibling',
- last: 'previousSibling',
- next: 'nextSibling',
- previous: 'previousSibling'
-};
-
-/* Private methods and helpers */
-
-/**
- * @spec https://dom.spec.whatwg.org/#concept-traverse-children
- * @method
- * @access private
- * @param {TreeWalker} tw
- * @param {string} type One of 'first' or 'last'.
- * @return {Node|null}
- */
-function traverseChildren(tw, type) {
- var child, node, parent, result, sibling;
- node = tw._currentNode[mapChild[type]];
- while (node !== null) {
- result = tw._internalFilter(node);
- if (result === NodeFilter.FILTER_ACCEPT) {
- tw._currentNode = node;
- return node;
- }
- if (result === NodeFilter.FILTER_SKIP) {
- child = node[mapChild[type]];
- if (child !== null) {
- node = child;
- continue;
- }
- }
- while (node !== null) {
- sibling = node[mapSibling[type]];
- if (sibling !== null) {
- node = sibling;
- break;
- }
- parent = node.parentNode;
- if (parent === null || parent === tw.root || parent === tw._currentNode) {
- return null;
- } else {
- node = parent;
- }
- }
- }
- return null;
-}
-
-/**
- * @spec https://dom.spec.whatwg.org/#concept-traverse-siblings
- * @method
- * @access private
- * @param {TreeWalker} tw
- * @param {TreeWalker} type One of 'next' or 'previous'.
- * @return {Node|nul}
- */
-function traverseSiblings(tw, type) {
- var node, result, sibling;
- node = tw._currentNode;
- if (node === tw.root) {
- return null;
- }
- while (true) {
- sibling = node[mapSibling[type]];
- while (sibling !== null) {
- node = sibling;
- result = tw._internalFilter(node);
- if (result === NodeFilter.FILTER_ACCEPT) {
- tw._currentNode = node;
- return node;
- }
- sibling = node[mapChild[type]];
- if (result === NodeFilter.FILTER_REJECT || sibling === null) {
- sibling = node[mapSibling[type]];
- }
- }
- node = node.parentNode;
- if (node === null || node === tw.root) {
- return null;
- }
- if (tw._internalFilter(node) === NodeFilter.FILTER_ACCEPT) {
- return null;
- }
- }
-}
-
-
-/* Public API */
-
-/**
- * Latest version: https://dom.spec.whatwg.org/#treewalker
- *
- * @constructor
- * @param {Node} root
- * @param {number} whatToShow [optional]
- * @param {Function|NodeFilter} filter [optional]
- * @throws Error
- */
-function TreeWalker(root, whatToShow, filter) {
- if (!root || !root.nodeType) {
- utils.NotSupportedError();
- }
-
- // Read-only properties
- this._root = root;
- this._whatToShow = Number(whatToShow) || 0;
- this._filter = filter || null;
- this._active = false;
- // Read-write property
- this._currentNode = root;
-}
-
-Object.defineProperties(TreeWalker.prototype, {
- root: { get: function() { return this._root; } },
- whatToShow: { get: function() { return this._whatToShow; } },
- filter: { get: function() { return this._filter; } },
-
- currentNode: {
- get: function currentNode() {
- return this._currentNode;
- },
- set: function setCurrentNode(v) {
- if (!(v instanceof Node)) {
- throw new TypeError("Not a Node"); // `null` is also not a node
- }
- this._currentNode = v;
- },
- },
-
- /**
- * @method
- * @param {Node} node
- * @return {Number} Constant NodeFilter.FILTER_ACCEPT,
- * NodeFilter.FILTER_REJECT or NodeFilter.FILTER_SKIP.
- */
- _internalFilter: { value: function _internalFilter(node) {
- /* jshint bitwise: false */
- var result, filter;
- if (this._active) {
- utils.InvalidStateError();
- }
-
- // Maps nodeType to whatToShow
- if (!(((1 << (node.nodeType - 1)) & this._whatToShow))) {
- return NodeFilter.FILTER_SKIP;
- }
-
- filter = this._filter;
- if (filter === null) {
- result = NodeFilter.FILTER_ACCEPT;
- } else {
- this._active = true;
- try {
- if (typeof filter === 'function') {
- result = filter(node);
- } else {
- result = filter.acceptNode(node);
- }
- } finally {
- this._active = false;
- }
- }
-
- // Note that coercing to a number means that
- // `true` becomes `1` (which is NodeFilter.FILTER_ACCEPT)
- // `false` becomes `0` (neither accept, reject, or skip)
- return (+result);
- }},
-
- /**
- * @spec https://dom.spec.whatwg.org/#dom-treewalker-parentnode
- * @based on WebKit's TreeWalker::parentNode
- * https://trac.webkit.org/browser/webkit/trunk/Source/WebCore/dom/TreeWalker.cpp?rev=220453#L50
- * @method
- * @return {Node|null}
- */
- parentNode: { value: function parentNode() {
- var node = this._currentNode;
- while (node !== this.root) {
- node = node.parentNode;
- if (node === null) {
- return null;
- }
- if (this._internalFilter(node) === NodeFilter.FILTER_ACCEPT) {
- this._currentNode = node;
- return node;
- }
- }
- return null;
- }},
-
- /**
- * @spec https://dom.spec.whatwg.org/#dom-treewalker-firstchild
- * @method
- * @return {Node|null}
- */
- firstChild: { value: function firstChild() {
- return traverseChildren(this, 'first');
- }},
-
- /**
- * @spec https://dom.spec.whatwg.org/#dom-treewalker-lastchild
- * @method
- * @return {Node|null}
- */
- lastChild: { value: function lastChild() {
- return traverseChildren(this, 'last');
- }},
-
- /**
- * @spec http://www.w3.org/TR/dom/#dom-treewalker-previoussibling
- * @method
- * @return {Node|null}
- */
- previousSibling: { value: function previousSibling() {
- return traverseSiblings(this, 'previous');
- }},
-
- /**
- * @spec http://www.w3.org/TR/dom/#dom-treewalker-nextsibling
- * @method
- * @return {Node|null}
- */
- nextSibling: { value: function nextSibling() {
- return traverseSiblings(this, 'next');
- }},
-
- /**
- * @spec https://dom.spec.whatwg.org/#dom-treewalker-previousnode
- * @based on WebKit's TreeWalker::previousNode
- * https://trac.webkit.org/browser/webkit/trunk/Source/WebCore/dom/TreeWalker.cpp?rev=220453#L181
- * @method
- * @return {Node|null}
- */
- previousNode: { value: function previousNode() {
- var node, result, previousSibling, lastChild;
- node = this._currentNode;
- while (node !== this._root) {
- for (previousSibling = node.previousSibling;
- previousSibling;
- previousSibling = node.previousSibling) {
- node = previousSibling;
- result = this._internalFilter(node);
- if (result === NodeFilter.FILTER_REJECT) {
- continue;
- }
- for (lastChild = node.lastChild;
- lastChild;
- lastChild = node.lastChild) {
- node = lastChild;
- result = this._internalFilter(node);
- if (result === NodeFilter.FILTER_REJECT) {
- break;
- }
- }
- if (result === NodeFilter.FILTER_ACCEPT) {
- this._currentNode = node;
- return node;
- }
- }
- if (node === this.root || node.parentNode === null) {
- return null;
- }
- node = node.parentNode;
- if (this._internalFilter(node) === NodeFilter.FILTER_ACCEPT) {
- this._currentNode = node;
- return node;
- }
- }
- return null;
- }},
-
- /**
- * @spec https://dom.spec.whatwg.org/#dom-treewalker-nextnode
- * @based on WebKit's TreeWalker::nextNode
- * https://trac.webkit.org/browser/webkit/trunk/Source/WebCore/dom/TreeWalker.cpp?rev=220453#L228
- * @method
- * @return {Node|null}
- */
- nextNode: { value: function nextNode() {
- var node, result, firstChild, nextSibling;
- node = this._currentNode;
- result = NodeFilter.FILTER_ACCEPT;
-
- CHILDREN:
- while (true) {
- for (firstChild = node.firstChild;
- firstChild;
- firstChild = node.firstChild) {
- node = firstChild;
- result = this._internalFilter(node);
- if (result === NodeFilter.FILTER_ACCEPT) {
- this._currentNode = node;
- return node;
- } else if (result === NodeFilter.FILTER_REJECT) {
- break;
- }
- }
- for (nextSibling = NodeTraversal.nextSkippingChildren(node, this.root);
- nextSibling;
- nextSibling = NodeTraversal.nextSkippingChildren(node, this.root)) {
- node = nextSibling;
- result = this._internalFilter(node);
- if (result === NodeFilter.FILTER_ACCEPT) {
- this._currentNode = node;
- return node;
- } else if (result === NodeFilter.FILTER_SKIP) {
- continue CHILDREN;
- }
- }
- return null;
- }
- }},
-
- /** For compatibility with web-platform-tests. */
- toString: { value: function toString() {
- return "[object TreeWalker]";
- }},
-});
--- a/cmd/gojafs/domino/domino-lib/UIEvent.js
+++ /dev/null
@@ -1,19 +1,0 @@
-"use strict";
-var Event = require('./Event');
-
-module.exports = UIEvent;
-
-function UIEvent() {
- // Just use the superclass constructor to initialize
- Event.call(this);
- this.view = null; // FF uses the current window
- this.detail = 0;
-}
-UIEvent.prototype = Object.create(Event.prototype, {
- constructor: { value: UIEvent },
- initUIEvent: { value: function(type, bubbles, cancelable, view, detail) {
- this.initEvent(type, bubbles, cancelable);
- this.view = view;
- this.detail = detail;
- }}
-});
--- a/cmd/gojafs/domino/domino-lib/URL.js
+++ /dev/null
@@ -1,194 +1,0 @@
-"use strict";
-module.exports = URL;
-
-function URL(url) {
- if (!url) return Object.create(URL.prototype);
- // Can't use String.trim() since it defines whitespace differently than HTML
- this.url = url.replace(/^[ \t\n\r\f]+|[ \t\n\r\f]+$/g, "");
-
- // See http://tools.ietf.org/html/rfc3986#appendix-B
- // and https://url.spec.whatwg.org/#parsing
- var match = URL.pattern.exec(this.url);
- if (match) {
- if (match[2]) this.scheme = match[2];
- if (match[4]) {
- // parse username/password
- var userinfo = match[4].match(URL.userinfoPattern);
- if (userinfo) {
- this.username = userinfo[1];
- this.password = userinfo[3];
- match[4] = match[4].substring(userinfo[0].length);
- }
- if (match[4].match(URL.portPattern)) {
- var pos = match[4].lastIndexOf(':');
- this.host = match[4].substring(0, pos);
- this.port = match[4].substring(pos+1);
- }
- else {
- this.host = match[4];
- }
- }
- if (match[5]) this.path = match[5];
- if (match[6]) this.query = match[7];
- if (match[8]) this.fragment = match[9];
- }
-}
-
-URL.pattern = /^(([^:\/?#]+):)?(\/\/([^\/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?$/;
-URL.userinfoPattern = /^([^@:]*)(:([^@]*))?@/;
-URL.portPattern = /:\d+$/;
-URL.authorityPattern = /^[^:\/?#]+:\/\//;
-URL.hierarchyPattern = /^[^:\/?#]+:\//;
-
-// Return a percentEncoded version of s.
-// S should be a single-character string
-// XXX: needs to do utf-8 encoding?
-URL.percentEncode = function percentEncode(s) {
- var c = s.charCodeAt(0);
- if (c < 256) return "%" + c.toString(16);
- else throw Error("can't percent-encode codepoints > 255 yet");
-};
-
-URL.prototype = {
- constructor: URL,
-
- // XXX: not sure if this is the precise definition of absolute
- isAbsolute: function() { return !!this.scheme; },
- isAuthorityBased: function() {
- return URL.authorityPattern.test(this.url);
- },
- isHierarchical: function() {
- return URL.hierarchyPattern.test(this.url);
- },
-
- toString: function() {
- var s = "";
- if (this.scheme !== undefined) s += this.scheme + ":";
- if (this.isAbsolute()) {
- s += '//';
- if (this.username || this.password) {
- s += this.username || '';
- if (this.password) {
- s += ':' + this.password;
- }
- s += '@';
- }
- if (this.host) {
- s += this.host;
- }
- }
- if (this.port !== undefined) s += ":" + this.port;
- if (this.path !== undefined) s += this.path;
- if (this.query !== undefined) s += "?" + this.query;
- if (this.fragment !== undefined) s += "#" + this.fragment;
- return s;
- },
-
- // See: http://tools.ietf.org/html/rfc3986#section-5.2
- // and https://url.spec.whatwg.org/#constructors
- resolve: function(relative) {
- var base = this; // The base url we're resolving against
- var r = new URL(relative); // The relative reference url to resolve
- var t = new URL(); // The absolute target url we will return
-
- if (r.scheme !== undefined) {
- t.scheme = r.scheme;
- t.username = r.username;
- t.password = r.password;
- t.host = r.host;
- t.port = r.port;
- t.path = remove_dot_segments(r.path);
- t.query = r.query;
- }
- else {
- t.scheme = base.scheme;
- if (r.host !== undefined) {
- t.username = r.username;
- t.password = r.password;
- t.host = r.host;
- t.port = r.port;
- t.path = remove_dot_segments(r.path);
- t.query = r.query;
- }
- else {
- t.username = base.username;
- t.password = base.password;
- t.host = base.host;
- t.port = base.port;
- if (!r.path) { // undefined or empty
- t.path = base.path;
- if (r.query !== undefined)
- t.query = r.query;
- else
- t.query = base.query;
- }
- else {
- if (r.path.charAt(0) === "/") {
- t.path = remove_dot_segments(r.path);
- }
- else {
- t.path = merge(base.path, r.path);
- t.path = remove_dot_segments(t.path);
- }
- t.query = r.query;
- }
- }
- }
- t.fragment = r.fragment;
-
- return t.toString();
-
-
- function merge(basepath, refpath) {
- if (base.host !== undefined && !base.path)
- return "/" + refpath;
-
- var lastslash = basepath.lastIndexOf("/");
- if (lastslash === -1)
- return refpath;
- else
- return basepath.substring(0, lastslash+1) + refpath;
- }
-
- function remove_dot_segments(path) {
- if (!path) return path; // For "" or undefined
-
- var output = "";
- while(path.length > 0) {
- if (path === "." || path === "..") {
- path = "";
- break;
- }
-
- var twochars = path.substring(0,2);
- var threechars = path.substring(0,3);
- var fourchars = path.substring(0,4);
- if (threechars === "../") {
- path = path.substring(3);
- }
- else if (twochars === "./") {
- path = path.substring(2);
- }
- else if (threechars === "/./") {
- path = "/" + path.substring(3);
- }
- else if (twochars === "/." && path.length === 2) {
- path = "/";
- }
- else if (fourchars === "/../" ||
- (threechars === "/.." && path.length === 3)) {
- path = "/" + path.substring(4);
-
- output = output.replace(/\/?[^\/]*$/, "");
- }
- else {
- var segment = path.match(/(\/?([^\/]*))/)[0];
- output += segment;
- path = path.substring(segment.length);
- }
- }
-
- return output;
- }
- },
-};
--- a/cmd/gojafs/domino/domino-lib/URLUtils.js
+++ /dev/null
@@ -1,270 +1,0 @@
-"use strict";
-var URL = require('./URL');
-
-module.exports = URLUtils;
-
-// Allow the `x == null` pattern. This is eslint's "null: 'ignore'" option,
-// but jshint doesn't support this.
-/* jshint eqeqeq: false */
-
-// This is an abstract superclass for Location, HTMLAnchorElement and
-// other types that have the standard complement of "URL decomposition
-// IDL attributes". This is now standardized as URLUtils, see:
-// https://url.spec.whatwg.org/#urlutils
-// Subclasses must define a getter/setter on href.
-// The getter and setter methods parse and rebuild the URL on each
-// invocation; there is no attempt to cache the value and be more efficient
-function URLUtils() {}
-URLUtils.prototype = Object.create(Object.prototype, {
-
- _url: { get: function() {
- // XXX: this should do the "Reinitialize url" steps, and "null" should
- // be a valid return value.
- return new URL(this.href);
- } },
-
- protocol: {
- get: function() {
- var url = this._url;
- if (url && url.scheme) return url.scheme + ":";
- else return ":";
- },
- set: function(v) {
- var output = this.href;
- var url = new URL(output);
- if (url.isAbsolute()) {
- v = v.replace(/:+$/, "");
- v = v.replace(/[^-+\.a-zA-Z0-9]/g, URL.percentEncode);
- if (v.length > 0) {
- url.scheme = v;
- output = url.toString();
- }
- }
- this.href = output;
- },
- },
-
- host: {
- get: function() {
- var url = this._url;
- if (url.isAbsolute() && url.isAuthorityBased())
- return url.host + (url.port ? (":" + url.port) : "");
- else
- return "";
- },
- set: function(v) {
- var output = this.href;
- var url = new URL(output);
- if (url.isAbsolute() && url.isAuthorityBased()) {
- v = v.replace(/[^-+\._~!$&'()*,;:=a-zA-Z0-9]/g, URL.percentEncode);
- if (v.length > 0) {
- url.host = v;
- delete url.port;
- output = url.toString();
- }
- }
- this.href = output;
- },
- },
-
- hostname: {
- get: function() {
- var url = this._url;
- if (url.isAbsolute() && url.isAuthorityBased())
- return url.host;
- else
- return "";
- },
- set: function(v) {
- var output = this.href;
- var url = new URL(output);
- if (url.isAbsolute() && url.isAuthorityBased()) {
- v = v.replace(/^\/+/, "");
- v = v.replace(/[^-+\._~!$&'()*,;:=a-zA-Z0-9]/g, URL.percentEncode);
- if (v.length > 0) {
- url.host = v;
- output = url.toString();
- }
- }
- this.href = output;
- },
- },
-
- port: {
- get: function() {
- var url = this._url;
- if (url.isAbsolute() && url.isAuthorityBased() && url.port!==undefined)
- return url.port;
- else
- return "";
- },
- set: function(v) {
- var output = this.href;
- var url = new URL(output);
- if (url.isAbsolute() && url.isAuthorityBased()) {
- v = '' + v;
- v = v.replace(/[^0-9].*$/, "");
- v = v.replace(/^0+/, "");
- if (v.length === 0) v = "0";
- if (parseInt(v, 10) <= 65535) {
- url.port = v;
- output = url.toString();
- }
- }
- this.href = output;
- },
- },
-
- pathname: {
- get: function() {
- var url = this._url;
- if (url.isAbsolute() && url.isHierarchical())
- return url.path;
- else
- return "";
- },
- set: function(v) {
- var output = this.href;
- var url = new URL(output);
- if (url.isAbsolute() && url.isHierarchical()) {
- if (v.charAt(0) !== "/")
- v = "/" + v;
- v = v.replace(/[^-+\._~!$&'()*,;:=@\/a-zA-Z0-9]/g, URL.percentEncode);
- url.path = v;
- output = url.toString();
- }
- this.href = output;
- },
- },
-
- search: {
- get: function() {
- var url = this._url;
- if (url.isAbsolute() && url.isHierarchical() && url.query!==undefined)
- return "?" + url.query;
- else
- return "";
- },
- set: function(v) {
- var output = this.href;
- var url = new URL(output);
- if (url.isAbsolute() && url.isHierarchical()) {
- if (v.charAt(0) === "?") v = v.substring(1);
- v = v.replace(/[^-+\._~!$&'()*,;:=@\/?a-zA-Z0-9]/g, URL.percentEncode);
- url.query = v;
- output = url.toString();
- }
- this.href = output;
- },
- },
-
- hash: {
- get: function() {
- var url = this._url;
- if (url == null || url.fragment == null || url.fragment === '') {
- return "";
- } else {
- return "#" + url.fragment;
- }
- },
- set: function(v) {
- var output = this.href;
- var url = new URL(output);
-
- if (v.charAt(0) === "#") v = v.substring(1);
- v = v.replace(/[^-+\._~!$&'()*,;:=@\/?a-zA-Z0-9]/g, URL.percentEncode);
- url.fragment = v;
- output = url.toString();
-
- this.href = output;
- },
- },
-
- username: {
- get: function() {
- var url = this._url;
- return url.username || '';
- },
- set: function(v) {
- var output = this.href;
- var url = new URL(output);
- if (url.isAbsolute()) {
- v = v.replace(/[\x00-\x1F\x7F-\uFFFF "#<>?`\/@\\:]/g, URL.percentEncode);
- url.username = v;
- output = url.toString();
- }
- this.href = output;
- },
- },
-
- password: {
- get: function() {
- var url = this._url;
- return url.password || '';
- },
- set: function(v) {
- var output = this.href;
- var url = new URL(output);
- if (url.isAbsolute()) {
- if (v==='') {
- url.password = null;
- } else {
- v = v.replace(/[\x00-\x1F\x7F-\uFFFF "#<>?`\/@\\]/g, URL.percentEncode);
- url.password = v;
- }
- output = url.toString();
- }
- this.href = output;
- },
- },
-
- origin: { get: function() {
- var url = this._url;
- if (url == null) { return ''; }
- var originForPort = function(defaultPort) {
- var origin = [url.scheme, url.host, +url.port || defaultPort];
- // XXX should be "unicode serialization"
- return origin[0] + '://' + origin[1] +
- (origin[2] === defaultPort ? '' : (':' + origin[2]));
- };
- switch (url.scheme) {
- case 'ftp':
- return originForPort(21);
- case 'gopher':
- return originForPort(70);
- case 'http':
- case 'ws':
- return originForPort(80);
- case 'https':
- case 'wss':
- return originForPort(443);
- default:
- // this is what chrome does
- return url.scheme + '://';
- }
- } },
-
- /*
- searchParams: {
- get: function() {
- var url = this._url;
- // XXX
- },
- set: function(v) {
- var output = this.href;
- var url = new URL(output);
- // XXX
- this.href = output;
- },
- },
- */
-});
-
-URLUtils._inherit = function(proto) {
- // copy getters/setters from URLUtils to o.
- Object.getOwnPropertyNames(URLUtils.prototype).forEach(function(p) {
- if (p==='constructor' || p==='href') { return; }
- var desc = Object.getOwnPropertyDescriptor(URLUtils.prototype, p);
- Object.defineProperty(proto, p, desc);
- });
-};
--- a/cmd/gojafs/domino/domino-lib/Window.js
+++ /dev/null
@@ -1,62 +1,0 @@
-"use strict";
-var DOMImplementation = require('./DOMImplementation');
-var EventTarget = require('./EventTarget');
-var Location = require('./Location');
-var sloppy = require('./sloppy');
-var utils = require('./utils');
-
-module.exports = Window;
-
-function Window(document) {
- this.document = document || new DOMImplementation(null).createHTMLDocument("");
- this.document._scripting_enabled = true;
- this.document.defaultView = this;
- this.location = new Location(this, this.document._address || 'about:blank');
-}
-
-Window.prototype = Object.create(EventTarget.prototype, {
- _run: { value: sloppy.Window_run },
- console: { value: console },
- history: { value: {
- back: utils.nyi,
- forward: utils.nyi,
- go: utils.nyi
- }},
- navigator: { value: require("./NavigatorID") },
-
- // Self-referential properties
- window: { get: function() { return this; }},
- self: { get: function() { return this; }},
- frames: { get: function() { return this; }},
-
- // Self-referential properties for a top-level window
- parent: { get: function() { return this; }},
- top: { get: function() { return this; }},
-
- // We don't support any other windows for now
- length: { value: 0 }, // no frames
- frameElement: { value: null }, // not part of a frame
- opener: { value: null }, // not opened by another window
-
- // The onload event handler.
- // XXX: need to support a bunch of other event types, too,
- // and have them interoperate with document.body.
-
- onload: {
- get: function() {
- return this._getEventHandler("load");
- },
- set: function(v) {
- this._setEventHandler("load", v);
- }
- },
-
- // XXX This is a completely broken implementation
- getComputedStyle: { value: function getComputedStyle(elt) {
- return elt.style;
- }}
-
-});
-
-utils.expose(require('./WindowTimers'), Window);
-utils.expose(require('./impl'), Window);
--- a/cmd/gojafs/domino/domino-lib/WindowTimers.js
+++ /dev/null
@@ -1,11 +1,0 @@
-"use strict";
-
-// https://html.spec.whatwg.org/multipage/webappapis.html#windowtimers
-var WindowTimers = {
- setTimeout: setTimeout,
- clearTimeout: clearTimeout,
- setInterval: setInterval,
- clearInterval: clearInterval
-};
-
-module.exports = WindowTimers;
--- a/cmd/gojafs/domino/domino-lib/attributes.js
+++ /dev/null
@@ -1,152 +1,0 @@
-"use strict";
-var utils = require('./utils');
-
-exports.property = function(attr) {
- if (Array.isArray(attr.type)) {
- var valid = Object.create(null);
- attr.type.forEach(function(val) {
- valid[val.value || val] = val.alias || val;
- });
- var missingValueDefault = attr.missing;
- if (missingValueDefault===undefined) { missingValueDefault = null; }
- var invalidValueDefault = attr.invalid;
- if (invalidValueDefault===undefined) { invalidValueDefault = missingValueDefault; }
- return {
- get: function() {
- var v = this._getattr(attr.name);
- if (v === null) return missingValueDefault;
-
- v = valid[v.toLowerCase()];
- if (v !== undefined) return v;
- if (invalidValueDefault !== null) return invalidValueDefault;
- return v;
- },
- set: function(v) {
- this._setattr(attr.name, v);
- }
- };
- }
- else if (attr.type === Boolean) {
- return {
- get: function() {
- return this.hasAttribute(attr.name);
- },
- set: function(v) {
- if (v) {
- this._setattr(attr.name, '');
- }
- else {
- this.removeAttribute(attr.name);
- }
- }
- };
- }
- else if (attr.type === Number ||
- attr.type === "long" ||
- attr.type === "unsigned long" ||
- attr.type === "limited unsigned long with fallback") {
- return numberPropDesc(attr);
- }
- else if (!attr.type || attr.type === String) {
- return {
- get: function() { return this._getattr(attr.name) || ''; },
- set: function(v) {
- if (attr.treatNullAsEmptyString && v === null) { v = ''; }
- this._setattr(attr.name, v);
- }
- };
- }
- else if (typeof attr.type === 'function') {
- return attr.type(attr.name, attr);
- }
- throw new Error('Invalid attribute definition');
-};
-
-// See http://www.whatwg.org/specs/web-apps/current-work/#reflect
-//
-// defval is the default value. If it is a function, then that function
-// will be invoked as a method of the element to obtain the default.
-// If no default is specified for a given attribute, then the default
-// depends on the type of the attribute, but since this function handles
-// 4 integer cases, you must specify the default value in each call
-//
-// min and max define a valid range for getting the attribute.
-//
-// setmin defines a minimum value when setting. If the value is less
-// than that, then throw INDEX_SIZE_ERR.
-//
-// Conveniently, JavaScript's parseInt function appears to be
-// compatible with HTML's 'rules for parsing integers'
-function numberPropDesc(a) {
- var def;
- if(typeof a.default === 'function') {
- def = a.default;
- }
- else if(typeof a.default === 'number') {
- def = function() { return a.default; };
- }
- else {
- def = function() { utils.assert(false, typeof a.default); };
- }
- var unsigned_long = (a.type === 'unsigned long');
- var signed_long = (a.type === 'long');
- var unsigned_fallback = (a.type === 'limited unsigned long with fallback');
- var min = a.min, max = a.max, setmin = a.setmin;
- if (min === undefined) {
- if (unsigned_long) min = 0;
- if (signed_long) min = -0x80000000;
- if (unsigned_fallback) min = 1;
- }
- if (max === undefined) {
- if (unsigned_long || signed_long || unsigned_fallback) max = 0x7FFFFFFF;
- }
-
- return {
- get: function() {
- var v = this._getattr(a.name);
- var n = a.float ? parseFloat(v) : parseInt(v, 10);
- if (v === null || !isFinite(n) || (min !== undefined && n < min) || (max !== undefined && n > max)) {
- return def.call(this);
- }
- if (unsigned_long || signed_long || unsigned_fallback) {
- if (!/^[ \t\n\f\r]*[-+]?[0-9]/.test(v)) { return def.call(this); }
- n = n|0; // jshint ignore:line
- }
- return n;
- },
- set: function(v) {
- if (!a.float) { v = Math.floor(v); }
- if (setmin !== undefined && v < setmin) {
- utils.IndexSizeError(a.name + ' set to ' + v);
- }
- if (unsigned_long) {
- v = (v < 0 || v > 0x7FFFFFFF) ? def.call(this) :
- (v|0); // jshint ignore:line
- } else if (unsigned_fallback) {
- v = (v < 1 || v > 0x7FFFFFFF) ? def.call(this) :
- (v|0); // jshint ignore:line
- } else if (signed_long) {
- v = (v < -0x80000000 || v > 0x7FFFFFFF) ? def.call(this) :
- (v|0); // jshint ignore:line
- }
- this._setattr(a.name, String(v));
- }
- };
-}
-
-// This is a utility function for setting up change handler functions
-// for attributes like 'id' that require special handling when they change.
-exports.registerChangeHandler = function(c, name, handler) {
- var p = c.prototype;
-
- // If p does not already have its own _attributeChangeHandlers
- // then create one for it, inheriting from the inherited
- // _attributeChangeHandlers. At the top (for the Element class) the
- // _attributeChangeHandlers object will be created with a null prototype.
- if (!Object.prototype.hasOwnProperty.call(p, '_attributeChangeHandlers')) {
- p._attributeChangeHandlers =
- Object.create(p._attributeChangeHandlers || null);
- }
-
- p._attributeChangeHandlers[name] = handler;
-};
--- a/cmd/gojafs/domino/domino-lib/config.js
+++ /dev/null
@@ -1,7 +1,0 @@
-/*
- * This file defines Domino behaviour that can be externally configured.
- * To change these settings, set the relevant global property *before*
- * you call `require("domino")`.
- */
-
-exports.isApiWritable = !global.__domino_frozen__;
--- a/cmd/gojafs/domino/domino-lib/cssparser.js
+++ /dev/null
@@ -1,6654 +1,0 @@
-/* jshint node:true, latedef:false */
-"use strict"; // jshint ignore:line
-/*!
-Parser-Lib
-Copyright (c) 2009-2011 Nicholas C. Zakas. All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-*/
-/* Version v0.2.5+domino1, Build time: 30-January-2016 05:13:03 */
-var parserlib = Object.create(null);
-(function(){
-
-/**
- * A generic base to inherit from for any object
- * that needs event handling.
- * @class EventTarget
- * @constructor
- */
-function EventTarget(){
-
- /**
- * The array of listeners for various events.
- * @type Object
- * @property _listeners
- * @private
- */
- this._listeners = Object.create(null);
-}
-
-EventTarget.prototype = {
-
- //restore constructor
- constructor: EventTarget,
-
- /**
- * Adds a listener for a given event type.
- * @param {String} type The type of event to add a listener for.
- * @param {Function} listener The function to call when the event occurs.
- * @return {void}
- * @method addListener
- */
- addListener: function(type, listener){
- if (!this._listeners[type]){
- this._listeners[type] = [];
- }
-
- this._listeners[type].push(listener);
- },
-
- /**
- * Fires an event based on the passed-in object.
- * @param {Object|String} event An object with at least a 'type' attribute
- * or a string indicating the event name.
- * @return {void}
- * @method fire
- */
- fire: function(event){
- if (typeof event === "string"){
- event = { type: event };
- }
- if (typeof event.target !== "undefined"){
- event.target = this;
- }
-
- if (typeof event.type === "undefined"){
- throw new Error("Event object missing 'type' property.");
- }
-
- if (this._listeners[event.type]){
-
- //create a copy of the array and use that so listeners can't chane
- var listeners = this._listeners[event.type].concat();
- for (var i=0, len=listeners.length; i < len; i++){
- listeners[i].call(this, event);
- }
- }
- },
-
- /**
- * Removes a listener for a given event type.
- * @param {String} type The type of event to remove a listener from.
- * @param {Function} listener The function to remove from the event.
- * @return {void}
- * @method removeListener
- */
- removeListener: function(type, listener){
- if (this._listeners[type]){
- var listeners = this._listeners[type];
- for (var i=0, len=listeners.length; i < len; i++){
- if (listeners[i] === listener){
- listeners.splice(i, 1);
- break;
- }
- }
-
-
- }
- }
-};
-/**
- * Convenient way to read through strings.
- * @namespace parserlib.util
- * @class StringReader
- * @constructor
- * @param {String} text The text to read.
- */
-function StringReader(text){
-
- /**
- * The input text with line endings normalized.
- * @property _input
- * @type String
- * @private
- */
- this._input = text.replace(/(\r|\n){1,2}/g, "\n");
-
-
- /**
- * The row for the character to be read next.
- * @property _line
- * @type int
- * @private
- */
- this._line = 1;
-
-
- /**
- * The column for the character to be read next.
- * @property _col
- * @type int
- * @private
- */
- this._col = 1;
-
- /**
- * The index of the character in the input to be read next.
- * @property _cursor
- * @type int
- * @private
- */
- this._cursor = 0;
-}
-
-StringReader.prototype = {
-
- //restore constructor
- constructor: StringReader,
-
- //-------------------------------------------------------------------------
- // Position info
- //-------------------------------------------------------------------------
-
- /**
- * Returns the column of the character to be read next.
- * @return {int} The column of the character to be read next.
- * @method getCol
- */
- getCol: function(){
- return this._col;
- },
-
- /**
- * Returns the row of the character to be read next.
- * @return {int} The row of the character to be read next.
- * @method getLine
- */
- getLine: function(){
- return this._line ;
- },
-
- /**
- * Determines if you're at the end of the input.
- * @return {Boolean} True if there's no more input, false otherwise.
- * @method eof
- */
- eof: function(){
- return (this._cursor === this._input.length);
- },
-
- //-------------------------------------------------------------------------
- // Basic reading
- //-------------------------------------------------------------------------
-
- /**
- * Reads the next character without advancing the cursor.
- * @param {int} count How many characters to look ahead (default is 1).
- * @return {String} The next character or null if there is no next character.
- * @method peek
- */
- peek: function(count){
- var c = null;
- count = (typeof count === "undefined" ? 1 : count);
-
- //if we're not at the end of the input...
- if (this._cursor < this._input.length){
-
- //get character and increment cursor and column
- c = this._input.charAt(this._cursor + count - 1);
- }
-
- return c;
- },
-
- /**
- * Reads the next character from the input and adjusts the row and column
- * accordingly.
- * @return {String} The next character or null if there is no next character.
- * @method read
- */
- read: function(){
- var c = null;
-
- //if we're not at the end of the input...
- if (this._cursor < this._input.length){
-
- //if the last character was a newline, increment row count
- //and reset column count
- if (this._input.charAt(this._cursor) === "\n"){
- this._line++;
- this._col=1;
- } else {
- this._col++;
- }
-
- //get character and increment cursor and column
- c = this._input.charAt(this._cursor++);
- }
-
- return c;
- },
-
- //-------------------------------------------------------------------------
- // Misc
- //-------------------------------------------------------------------------
-
- /**
- * Saves the current location so it can be returned to later.
- * @method mark
- * @return {void}
- */
- mark: function(){
- this._bookmark = {
- cursor: this._cursor,
- line: this._line,
- col: this._col
- };
- },
-
- reset: function(){
- if (this._bookmark){
- this._cursor = this._bookmark.cursor;
- this._line = this._bookmark.line;
- this._col = this._bookmark.col;
- delete this._bookmark;
- }
- },
-
- //-------------------------------------------------------------------------
- // Advanced reading
- //-------------------------------------------------------------------------
-
- /**
- * Reads up to and including the given string. Throws an error if that
- * string is not found.
- * @param {String} pattern The string to read.
- * @return {String} The string when it is found.
- * @throws Error when the string pattern is not found.
- * @method readTo
- */
- readTo: function(pattern){
-
- var buffer = "",
- c;
-
- /*
- * First, buffer must be the same length as the pattern.
- * Then, buffer must end with the pattern or else reach the
- * end of the input.
- */
- while (buffer.length < pattern.length || buffer.lastIndexOf(pattern) !== buffer.length - pattern.length){
- c = this.read();
- if (c){
- buffer += c;
- } else {
- throw new Error("Expected \"" + pattern + "\" at line " + this._line + ", col " + this._col + ".");
- }
- }
-
- return buffer;
-
- },
-
- /**
- * Reads characters while each character causes the given
- * filter function to return true. The function is passed
- * in each character and either returns true to continue
- * reading or false to stop.
- * @param {Function} filter The function to read on each character.
- * @return {String} The string made up of all characters that passed the
- * filter check.
- * @method readWhile
- */
- readWhile: function(filter){
-
- var buffer = "",
- c = this.read();
-
- while(c !== null && filter(c)){
- buffer += c;
- c = this.read();
- }
-
- return buffer;
-
- },
-
- /**
- * Reads characters that match either text or a regular expression and
- * returns those characters. If a match is found, the row and column
- * are adjusted; if no match is found, the reader's state is unchanged.
- * reading or false to stop.
- * @param {String|RegExp} matchter If a string, then the literal string
- * value is searched for. If a regular expression, then any string
- * matching the pattern is search for.
- * @return {String} The string made up of all characters that matched or
- * null if there was no match.
- * @method readMatch
- */
- readMatch: function(matcher){
-
- var source = this._input.substring(this._cursor),
- value = null;
-
- //if it's a string, just do a straight match
- if (typeof matcher === "string"){
- if (source.indexOf(matcher) === 0){
- value = this.readCount(matcher.length);
- }
- } else if (matcher instanceof RegExp){
- if (matcher.test(source)){
- value = this.readCount(RegExp.lastMatch.length);
- }
- }
-
- return value;
- },
-
-
- /**
- * Reads a given number of characters. If the end of the input is reached,
- * it reads only the remaining characters and does not throw an error.
- * @param {int} count The number of characters to read.
- * @return {String} The string made up the read characters.
- * @method readCount
- */
- readCount: function(count){
- var buffer = "";
-
- while(count--){
- buffer += this.read();
- }
-
- return buffer;
- }
-
-};
-/**
- * Type to use when a syntax error occurs.
- * @class SyntaxError
- * @namespace parserlib.util
- * @constructor
- * @param {String} message The error message.
- * @param {int} line The line at which the error occurred.
- * @param {int} col The column at which the error occurred.
- */
-function SyntaxError(message, line, col){
- Error.call(this);
- this.name = this.constructor.name;
-
- /**
- * The column at which the error occurred.
- * @type int
- * @property col
- */
- this.col = col;
-
- /**
- * The line at which the error occurred.
- * @type int
- * @property line
- */
- this.line = line;
-
- /**
- * The text representation of the unit.
- * @type String
- * @property text
- */
- this.message = message;
-
-}
-
-//inherit from Error
-SyntaxError.prototype = Object.create(Error.prototype); // jshint ignore:line
-SyntaxError.prototype.constructor = SyntaxError; // jshint ignore:line
-/**
- * Base type to represent a single syntactic unit.
- * @class SyntaxUnit
- * @namespace parserlib.util
- * @constructor
- * @param {String} text The text of the unit.
- * @param {int} line The line of text on which the unit resides.
- * @param {int} col The column of text on which the unit resides.
- */
-function SyntaxUnit(text, line, col, type){
-
-
- /**
- * The column of text on which the unit resides.
- * @type int
- * @property col
- */
- this.col = col;
-
- /**
- * The line of text on which the unit resides.
- * @type int
- * @property line
- */
- this.line = line;
-
- /**
- * The text representation of the unit.
- * @type String
- * @property text
- */
- this.text = text;
-
- /**
- * The type of syntax unit.
- * @type int
- * @property type
- */
- this.type = type;
-}
-
-/**
- * Create a new syntax unit based solely on the given token.
- * Convenience method for creating a new syntax unit when
- * it represents a single token instead of multiple.
- * @param {Object} token The token object to represent.
- * @return {parserlib.util.SyntaxUnit} The object representing the token.
- * @static
- * @method fromToken
- */
-SyntaxUnit.fromToken = function(token){
- return new SyntaxUnit(token.value, token.startLine, token.startCol);
-};
-
-SyntaxUnit.prototype = {
-
- //restore constructor
- constructor: SyntaxUnit,
-
- /**
- * Returns the text representation of the unit.
- * @return {String} The text representation of the unit.
- * @method valueOf
- */
- valueOf: function(){
- return this.toString();
- },
-
- /**
- * Returns the text representation of the unit.
- * @return {String} The text representation of the unit.
- * @method toString
- */
- toString: function(){
- return this.text;
- }
-
-};
-
-/**
- * Generic TokenStream providing base functionality.
- * @class TokenStreamBase
- * @namespace parserlib.util
- * @constructor
- * @param {String|StringReader} input The text to tokenize or a reader from
- * which to read the input.
- */
-function TokenStreamBase(input, tokenData){
-
- /**
- * The string reader for easy access to the text.
- * @type StringReader
- * @property _reader
- * @private
- */
- this._reader = input ? new StringReader(input.toString()) : null;
-
- /**
- * Token object for the last consumed token.
- * @type Token
- * @property _token
- * @private
- */
- this._token = null;
-
- /**
- * The array of token information.
- * @type Array
- * @property _tokenData
- * @private
- */
- this._tokenData = tokenData;
-
- /**
- * Lookahead token buffer.
- * @type Array
- * @property _lt
- * @private
- */
- this._lt = [];
-
- /**
- * Lookahead token buffer index.
- * @type int
- * @property _ltIndex
- * @private
- */
- this._ltIndex = 0;
-
- this._ltIndexCache = [];
-}
-
-/**
- * Accepts an array of token information and outputs
- * an array of token data containing key-value mappings
- * and matching functions that the TokenStream needs.
- * @param {Array} tokens An array of token descriptors.
- * @return {Array} An array of processed token data.
- * @method createTokenData
- * @static
- */
-TokenStreamBase.createTokenData = function(tokens){
-
- var nameMap = [],
- typeMap = Object.create(null),
- tokenData = tokens.concat([]),
- i = 0,
- len = tokenData.length+1;
-
- tokenData.UNKNOWN = -1;
- tokenData.unshift({name:"EOF"});
-
- for (; i < len; i++){
- nameMap.push(tokenData[i].name);
- tokenData[tokenData[i].name] = i;
- if (tokenData[i].text){
- typeMap[tokenData[i].text] = i;
- }
- }
-
- tokenData.name = function(tt){
- return nameMap[tt];
- };
-
- tokenData.type = function(c){
- return typeMap[c];
- };
-
- return tokenData;
-};
-
-TokenStreamBase.prototype = {
-
- //restore constructor
- constructor: TokenStreamBase,
-
- //-------------------------------------------------------------------------
- // Matching methods
- //-------------------------------------------------------------------------
-
- /**
- * Determines if the next token matches the given token type.
- * If so, that token is consumed; if not, the token is placed
- * back onto the token stream. You can pass in any number of
- * token types and this will return true if any of the token
- * types is found.
- * @param {int|int[]} tokenTypes Either a single token type or an array of
- * token types that the next token might be. If an array is passed,
- * it's assumed that the token can be any of these.
- * @param {variant} channel (Optional) The channel to read from. If not
- * provided, reads from the default (unnamed) channel.
- * @return {Boolean} True if the token type matches, false if not.
- * @method match
- */
- match: function(tokenTypes, channel){
-
- //always convert to an array, makes things easier
- if (!(tokenTypes instanceof Array)){
- tokenTypes = [tokenTypes];
- }
-
- var tt = this.get(channel),
- i = 0,
- len = tokenTypes.length;
-
- while(i < len){
- if (tt === tokenTypes[i++]){
- return true;
- }
- }
-
- //no match found, put the token back
- this.unget();
- return false;
- },
-
- /**
- * Determines if the next token matches the given token type.
- * If so, that token is consumed; if not, an error is thrown.
- * @param {int|int[]} tokenTypes Either a single token type or an array of
- * token types that the next token should be. If an array is passed,
- * it's assumed that the token must be one of these.
- * @param {variant} channel (Optional) The channel to read from. If not
- * provided, reads from the default (unnamed) channel.
- * @return {void}
- * @method mustMatch
- */
- mustMatch: function(tokenTypes, channel){
-
- var token;
-
- //always convert to an array, makes things easier
- if (!(tokenTypes instanceof Array)){
- tokenTypes = [tokenTypes];
- }
-
- if (!this.match.apply(this, arguments)){
- token = this.LT(1);
- throw new SyntaxError("Expected " + this._tokenData[tokenTypes[0]].name +
- " at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol);
- }
- },
-
- //-------------------------------------------------------------------------
- // Consuming methods
- //-------------------------------------------------------------------------
-
- /**
- * Keeps reading from the token stream until either one of the specified
- * token types is found or until the end of the input is reached.
- * @param {int|int[]} tokenTypes Either a single token type or an array of
- * token types that the next token should be. If an array is passed,
- * it's assumed that the token must be one of these.
- * @param {variant} channel (Optional) The channel to read from. If not
- * provided, reads from the default (unnamed) channel.
- * @return {void}
- * @method advance
- */
- advance: function(tokenTypes, channel){
-
- while(this.LA(0) !== 0 && !this.match(tokenTypes, channel)){
- this.get();
- }
-
- return this.LA(0);
- },
-
- /**
- * Consumes the next token from the token stream.
- * @return {int} The token type of the token that was just consumed.
- * @method get
- */
- get: function(channel){
-
- var tokenInfo = this._tokenData,
- i =0,
- token,
- info;
-
- //check the lookahead buffer first
- if (this._lt.length && this._ltIndex >= 0 && this._ltIndex < this._lt.length){
-
- i++;
- this._token = this._lt[this._ltIndex++];
- info = tokenInfo[this._token.type];
-
- //obey channels logic
- while((info.channel !== undefined && channel !== info.channel) &&
- this._ltIndex < this._lt.length){
- this._token = this._lt[this._ltIndex++];
- info = tokenInfo[this._token.type];
- i++;
- }
-
- //here be dragons
- if ((info.channel === undefined || channel === info.channel) &&
- this._ltIndex <= this._lt.length){
- this._ltIndexCache.push(i);
- return this._token.type;
- }
- }
-
- //call token retriever method
- token = this._getToken();
-
- //if it should be hidden, don't save a token
- if (token.type > -1 && !tokenInfo[token.type].hide){
-
- //apply token channel
- token.channel = tokenInfo[token.type].channel;
-
- //save for later
- this._token = token;
- this._lt.push(token);
-
- //save space that will be moved (must be done before array is truncated)
- this._ltIndexCache.push(this._lt.length - this._ltIndex + i);
-
- //keep the buffer under 5 items
- if (this._lt.length > 5){
- this._lt.shift();
- }
-
- //also keep the shift buffer under 5 items
- if (this._ltIndexCache.length > 5){
- this._ltIndexCache.shift();
- }
-
- //update lookahead index
- this._ltIndex = this._lt.length;
- }
-
- /*
- * Skip to the next token if:
- * 1. The token type is marked as hidden.
- * 2. The token type has a channel specified and it isn't the current channel.
- */
- info = tokenInfo[token.type];
- if (info &&
- (info.hide ||
- (info.channel !== undefined && channel !== info.channel))){
- return this.get(channel);
- } else {
- //return just the type
- return token.type;
- }
- },
-
- /**
- * Looks ahead a certain number of tokens and returns the token type at
- * that position. This will throw an error if you lookahead past the
- * end of input, past the size of the lookahead buffer, or back past
- * the first token in the lookahead buffer.
- * @param {int} The index of the token type to retrieve. 0 for the
- * current token, 1 for the next, -1 for the previous, etc.
- * @return {int} The token type of the token in the given position.
- * @method LA
- */
- LA: function(index){
- var total = index,
- tt;
- if (index > 0){
- //TODO: Store 5 somewhere
- if (index > 5){
- throw new Error("Too much lookahead.");
- }
-
- //get all those tokens
- while(total){
- tt = this.get();
- total--;
- }
-
- //unget all those tokens
- while(total < index){
- this.unget();
- total++;
- }
- } else if (index < 0){
-
- if(this._lt[this._ltIndex+index]){
- tt = this._lt[this._ltIndex+index].type;
- } else {
- throw new Error("Too much lookbehind.");
- }
-
- } else {
- tt = this._token.type;
- }
-
- return tt;
-
- },
-
- /**
- * Looks ahead a certain number of tokens and returns the token at
- * that position. This will throw an error if you lookahead past the
- * end of input, past the size of the lookahead buffer, or back past
- * the first token in the lookahead buffer.
- * @param {int} The index of the token type to retrieve. 0 for the
- * current token, 1 for the next, -1 for the previous, etc.
- * @return {Object} The token of the token in the given position.
- * @method LA
- */
- LT: function(index){
-
- //lookahead first to prime the token buffer
- this.LA(index);
-
- //now find the token, subtract one because _ltIndex is already at the next index
- return this._lt[this._ltIndex+index-1];
- },
-
- /**
- * Returns the token type for the next token in the stream without
- * consuming it.
- * @return {int} The token type of the next token in the stream.
- * @method peek
- */
- peek: function(){
- return this.LA(1);
- },
-
- /**
- * Returns the actual token object for the last consumed token.
- * @return {Token} The token object for the last consumed token.
- * @method token
- */
- token: function(){
- return this._token;
- },
-
- /**
- * Returns the name of the token for the given token type.
- * @param {int} tokenType The type of token to get the name of.
- * @return {String} The name of the token or "UNKNOWN_TOKEN" for any
- * invalid token type.
- * @method tokenName
- */
- tokenName: function(tokenType){
- if (tokenType < 0 || tokenType > this._tokenData.length){
- return "UNKNOWN_TOKEN";
- } else {
- return this._tokenData[tokenType].name;
- }
- },
-
- /**
- * Returns the token type value for the given token name.
- * @param {String} tokenName The name of the token whose value should be returned.
- * @return {int} The token type value for the given token name or -1
- * for an unknown token.
- * @method tokenName
- */
- tokenType: function(tokenName){
- return this._tokenData[tokenName] || -1;
- },
-
- /**
- * Returns the last consumed token to the token stream.
- * @method unget
- */
- unget: function(){
- //if (this._ltIndex > -1){
- if (this._ltIndexCache.length){
- this._ltIndex -= this._ltIndexCache.pop();//--;
- this._token = this._lt[this._ltIndex - 1];
- } else {
- throw new Error("Too much lookahead.");
- }
- }
-
-};
-
-
-parserlib.util = {
-__proto__ : null,
-StringReader: StringReader,
-SyntaxError : SyntaxError,
-SyntaxUnit : SyntaxUnit,
-EventTarget : EventTarget,
-TokenStreamBase : TokenStreamBase
-};
-})();
-/*
-Parser-Lib
-Copyright (c) 2009-2011 Nicholas C. Zakas. All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-
-*/
-/* Version v0.2.5+domino1, Build time: 30-January-2016 05:13:03 */
-(function(){
-var EventTarget = parserlib.util.EventTarget,
-TokenStreamBase = parserlib.util.TokenStreamBase,
-StringReader = parserlib.util.StringReader, // jshint ignore:line
-SyntaxError = parserlib.util.SyntaxError,
-SyntaxUnit = parserlib.util.SyntaxUnit;
-
-var Colors = {
- __proto__ :null,
- aliceblue :"#f0f8ff",
- antiquewhite :"#faebd7",
- aqua :"#00ffff",
- aquamarine :"#7fffd4",
- azure :"#f0ffff",
- beige :"#f5f5dc",
- bisque :"#ffe4c4",
- black :"#000000",
- blanchedalmond :"#ffebcd",
- blue :"#0000ff",
- blueviolet :"#8a2be2",
- brown :"#a52a2a",
- burlywood :"#deb887",
- cadetblue :"#5f9ea0",
- chartreuse :"#7fff00",
- chocolate :"#d2691e",
- coral :"#ff7f50",
- cornflowerblue :"#6495ed",
- cornsilk :"#fff8dc",
- crimson :"#dc143c",
- cyan :"#00ffff",
- darkblue :"#00008b",
- darkcyan :"#008b8b",
- darkgoldenrod :"#b8860b",
- darkgray :"#a9a9a9",
- darkgrey :"#a9a9a9",
- darkgreen :"#006400",
- darkkhaki :"#bdb76b",
- darkmagenta :"#8b008b",
- darkolivegreen :"#556b2f",
- darkorange :"#ff8c00",
- darkorchid :"#9932cc",
- darkred :"#8b0000",
- darksalmon :"#e9967a",
- darkseagreen :"#8fbc8f",
- darkslateblue :"#483d8b",
- darkslategray :"#2f4f4f",
- darkslategrey :"#2f4f4f",
- darkturquoise :"#00ced1",
- darkviolet :"#9400d3",
- deeppink :"#ff1493",
- deepskyblue :"#00bfff",
- dimgray :"#696969",
- dimgrey :"#696969",
- dodgerblue :"#1e90ff",
- firebrick :"#b22222",
- floralwhite :"#fffaf0",
- forestgreen :"#228b22",
- fuchsia :"#ff00ff",
- gainsboro :"#dcdcdc",
- ghostwhite :"#f8f8ff",
- gold :"#ffd700",
- goldenrod :"#daa520",
- gray :"#808080",
- grey :"#808080",
- green :"#008000",
- greenyellow :"#adff2f",
- honeydew :"#f0fff0",
- hotpink :"#ff69b4",
- indianred :"#cd5c5c",
- indigo :"#4b0082",
- ivory :"#fffff0",
- khaki :"#f0e68c",
- lavender :"#e6e6fa",
- lavenderblush :"#fff0f5",
- lawngreen :"#7cfc00",
- lemonchiffon :"#fffacd",
- lightblue :"#add8e6",
- lightcoral :"#f08080",
- lightcyan :"#e0ffff",
- lightgoldenrodyellow :"#fafad2",
- lightgray :"#d3d3d3",
- lightgrey :"#d3d3d3",
- lightgreen :"#90ee90",
- lightpink :"#ffb6c1",
- lightsalmon :"#ffa07a",
- lightseagreen :"#20b2aa",
- lightskyblue :"#87cefa",
- lightslategray :"#778899",
- lightslategrey :"#778899",
- lightsteelblue :"#b0c4de",
- lightyellow :"#ffffe0",
- lime :"#00ff00",
- limegreen :"#32cd32",
- linen :"#faf0e6",
- magenta :"#ff00ff",
- maroon :"#800000",
- mediumaquamarine:"#66cdaa",
- mediumblue :"#0000cd",
- mediumorchid :"#ba55d3",
- mediumpurple :"#9370d8",
- mediumseagreen :"#3cb371",
- mediumslateblue :"#7b68ee",
- mediumspringgreen :"#00fa9a",
- mediumturquoise :"#48d1cc",
- mediumvioletred :"#c71585",
- midnightblue :"#191970",
- mintcream :"#f5fffa",
- mistyrose :"#ffe4e1",
- moccasin :"#ffe4b5",
- navajowhite :"#ffdead",
- navy :"#000080",
- oldlace :"#fdf5e6",
- olive :"#808000",
- olivedrab :"#6b8e23",
- orange :"#ffa500",
- orangered :"#ff4500",
- orchid :"#da70d6",
- palegoldenrod :"#eee8aa",
- palegreen :"#98fb98",
- paleturquoise :"#afeeee",
- palevioletred :"#d87093",
- papayawhip :"#ffefd5",
- peachpuff :"#ffdab9",
- peru :"#cd853f",
- pink :"#ffc0cb",
- plum :"#dda0dd",
- powderblue :"#b0e0e6",
- purple :"#800080",
- red :"#ff0000",
- rosybrown :"#bc8f8f",
- royalblue :"#4169e1",
- saddlebrown :"#8b4513",
- salmon :"#fa8072",
- sandybrown :"#f4a460",
- seagreen :"#2e8b57",
- seashell :"#fff5ee",
- sienna :"#a0522d",
- silver :"#c0c0c0",
- skyblue :"#87ceeb",
- slateblue :"#6a5acd",
- slategray :"#708090",
- slategrey :"#708090",
- snow :"#fffafa",
- springgreen :"#00ff7f",
- steelblue :"#4682b4",
- tan :"#d2b48c",
- teal :"#008080",
- thistle :"#d8bfd8",
- tomato :"#ff6347",
- turquoise :"#40e0d0",
- violet :"#ee82ee",
- wheat :"#f5deb3",
- white :"#ffffff",
- whitesmoke :"#f5f5f5",
- yellow :"#ffff00",
- yellowgreen :"#9acd32",
- //'currentColor' color keyword http://www.w3.org/TR/css3-color/#currentcolor
- currentColor :"The value of the 'color' property.",
- //CSS2 system colors http://www.w3.org/TR/css3-color/#css2-system
- activeBorder :"Active window border.",
- activecaption :"Active window caption.",
- appworkspace :"Background color of multiple document interface.",
- background :"Desktop background.",
- buttonface :"The face background color for 3-D elements that appear 3-D due to one layer of surrounding border.",
- buttonhighlight :"The color of the border facing the light source for 3-D elements that appear 3-D due to one layer of surrounding border.",
- buttonshadow :"The color of the border away from the light source for 3-D elements that appear 3-D due to one layer of surrounding border.",
- buttontext :"Text on push buttons.",
- captiontext :"Text in caption, size box, and scrollbar arrow box.",
- graytext :"Grayed (disabled) text. This color is set to #000 if the current display driver does not support a solid gray color.",
- greytext :"Greyed (disabled) text. This color is set to #000 if the current display driver does not support a solid grey color.",
- highlight :"Item(s) selected in a control.",
- highlighttext :"Text of item(s) selected in a control.",
- inactiveborder :"Inactive window border.",
- inactivecaption :"Inactive window caption.",
- inactivecaptiontext :"Color of text in an inactive caption.",
- infobackground :"Background color for tooltip controls.",
- infotext :"Text color for tooltip controls.",
- menu :"Menu background.",
- menutext :"Text in menus.",
- scrollbar :"Scroll bar gray area.",
- threeddarkshadow :"The color of the darker (generally outer) of the two borders away from the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.",
- threedface :"The face background color for 3-D elements that appear 3-D due to two concentric layers of surrounding border.",
- threedhighlight :"The color of the lighter (generally outer) of the two borders facing the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.",
- threedlightshadow :"The color of the darker (generally inner) of the two borders facing the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.",
- threedshadow :"The color of the lighter (generally inner) of the two borders away from the light source for 3-D elements that appear 3-D due to two concentric layers of surrounding border.",
- window :"Window background.",
- windowframe :"Window frame.",
- windowtext :"Text in windows."
-};
-/**
- * Represents a selector combinator (whitespace, +, >).
- * @namespace parserlib.css
- * @class Combinator
- * @extends parserlib.util.SyntaxUnit
- * @constructor
- * @param {String} text The text representation of the unit.
- * @param {int} line The line of text on which the unit resides.
- * @param {int} col The column of text on which the unit resides.
- */
-function Combinator(text, line, col){
-
- SyntaxUnit.call(this, text, line, col, Parser.COMBINATOR_TYPE);
-
- /**
- * The type of modifier.
- * @type String
- * @property type
- */
- this.type = "unknown";
-
- //pretty simple
- if (/^\s+$/.test(text)){
- this.type = "descendant";
- } else if (text === ">"){
- this.type = "child";
- } else if (text === "+"){
- this.type = "adjacent-sibling";
- } else if (text === "~"){
- this.type = "sibling";
- }
-
-}
-
-Combinator.prototype = new SyntaxUnit();
-Combinator.prototype.constructor = Combinator;
-
-/**
- * Represents a media feature, such as max-width:500.
- * @namespace parserlib.css
- * @class MediaFeature
- * @extends parserlib.util.SyntaxUnit
- * @constructor
- * @param {SyntaxUnit} name The name of the feature.
- * @param {SyntaxUnit} value The value of the feature or null if none.
- */
-function MediaFeature(name, value){
-
- SyntaxUnit.call(this, "(" + name + (value !== null ? ":" + value : "") + ")", name.startLine, name.startCol, Parser.MEDIA_FEATURE_TYPE);
-
- /**
- * The name of the media feature
- * @type String
- * @property name
- */
- this.name = name;
-
- /**
- * The value for the feature or null if there is none.
- * @type SyntaxUnit
- * @property value
- */
- this.value = value;
-}
-
-MediaFeature.prototype = new SyntaxUnit();
-MediaFeature.prototype.constructor = MediaFeature;
-
-/**
- * Represents an individual media query.
- * @namespace parserlib.css
- * @class MediaQuery
- * @extends parserlib.util.SyntaxUnit
- * @constructor
- * @param {String} modifier The modifier "not" or "only" (or null).
- * @param {String} mediaType The type of media (i.e., "print").
- * @param {Array} parts Array of selectors parts making up this selector.
- * @param {int} line The line of text on which the unit resides.
- * @param {int} col The column of text on which the unit resides.
- */
-function MediaQuery(modifier, mediaType, features, line, col){
-
- SyntaxUnit.call(this, (modifier ? modifier + " ": "") + (mediaType ? mediaType : "") + (mediaType && features.length > 0 ? " and " : "") + features.join(" and "), line, col, Parser.MEDIA_QUERY_TYPE);
-
- /**
- * The media modifier ("not" or "only")
- * @type String
- * @property modifier
- */
- this.modifier = modifier;
-
- /**
- * The mediaType (i.e., "print")
- * @type String
- * @property mediaType
- */
- this.mediaType = mediaType;
-
- /**
- * The parts that make up the selector.
- * @type Array
- * @property features
- */
- this.features = features;
-
-}
-
-MediaQuery.prototype = new SyntaxUnit();
-MediaQuery.prototype.constructor = MediaQuery;
-
-
-/**
- * A CSS3 parser.
- * @namespace parserlib.css
- * @class Parser
- * @constructor
- * @param {Object} options (Optional) Various options for the parser:
- * starHack (true|false) to allow IE6 star hack as valid,
- * underscoreHack (true|false) to interpret leading underscores
- * as IE6-7 targeting for known properties, ieFilters (true|false)
- * to indicate that IE < 8 filters should be accepted and not throw
- * syntax errors.
- */
-function Parser(options){
-
- //inherit event functionality
- EventTarget.call(this);
-
-
- this.options = options || {};
-
- this._tokenStream = null;
-}
-
-//Static constants
-Parser.DEFAULT_TYPE = 0;
-Parser.COMBINATOR_TYPE = 1;
-Parser.MEDIA_FEATURE_TYPE = 2;
-Parser.MEDIA_QUERY_TYPE = 3;
-Parser.PROPERTY_NAME_TYPE = 4;
-Parser.PROPERTY_VALUE_TYPE = 5;
-Parser.PROPERTY_VALUE_PART_TYPE = 6;
-Parser.SELECTOR_TYPE = 7;
-Parser.SELECTOR_PART_TYPE = 8;
-Parser.SELECTOR_SUB_PART_TYPE = 9;
-
-Parser.prototype = function(){
-
- var proto = new EventTarget(), //new prototype
- prop,
- additions = {
- __proto__: null,
-
- //restore constructor
- constructor: Parser,
-
- //instance constants - yuck
- DEFAULT_TYPE : 0,
- COMBINATOR_TYPE : 1,
- MEDIA_FEATURE_TYPE : 2,
- MEDIA_QUERY_TYPE : 3,
- PROPERTY_NAME_TYPE : 4,
- PROPERTY_VALUE_TYPE : 5,
- PROPERTY_VALUE_PART_TYPE : 6,
- SELECTOR_TYPE : 7,
- SELECTOR_PART_TYPE : 8,
- SELECTOR_SUB_PART_TYPE : 9,
-
- //-----------------------------------------------------------------
- // Grammar
- //-----------------------------------------------------------------
-
- _stylesheet: function(){
-
- /*
- * stylesheet
- * : [ CHARSET_SYM S* STRING S* ';' ]?
- * [S|CDO|CDC]* [ import [S|CDO|CDC]* ]*
- * [ namespace [S|CDO|CDC]* ]*
- * [ [ ruleset | media | page | font_face | keyframes ] [S|CDO|CDC]* ]*
- * ;
- */
-
- var tokenStream = this._tokenStream,
- count,
- token,
- tt;
-
- this.fire("startstylesheet");
-
- //try to read character set
- this._charset();
-
- this._skipCruft();
-
- //try to read imports - may be more than one
- while (tokenStream.peek() === Tokens.IMPORT_SYM){
- this._import();
- this._skipCruft();
- }
-
- //try to read namespaces - may be more than one
- while (tokenStream.peek() === Tokens.NAMESPACE_SYM){
- this._namespace();
- this._skipCruft();
- }
-
- //get the next token
- tt = tokenStream.peek();
-
- //try to read the rest
- while(tt > Tokens.EOF){
-
- try {
-
- switch(tt){
- case Tokens.MEDIA_SYM:
- this._media();
- this._skipCruft();
- break;
- case Tokens.PAGE_SYM:
- this._page();
- this._skipCruft();
- break;
- case Tokens.FONT_FACE_SYM:
- this._font_face();
- this._skipCruft();
- break;
- case Tokens.KEYFRAMES_SYM:
- this._keyframes();
- this._skipCruft();
- break;
- case Tokens.VIEWPORT_SYM:
- this._viewport();
- this._skipCruft();
- break;
- case Tokens.DOCUMENT_SYM:
- this._document();
- this._skipCruft();
- break;
- case Tokens.UNKNOWN_SYM: //unknown @ rule
- tokenStream.get();
- if (!this.options.strict){
-
- //fire error event
- this.fire({
- type: "error",
- error: null,
- message: "Unknown @ rule: " + tokenStream.LT(0).value + ".",
- line: tokenStream.LT(0).startLine,
- col: tokenStream.LT(0).startCol
- });
-
- //skip braces
- count=0;
- while (tokenStream.advance([Tokens.LBRACE, Tokens.RBRACE]) === Tokens.LBRACE){
- count++; //keep track of nesting depth
- }
-
- while(count){
- tokenStream.advance([Tokens.RBRACE]);
- count--;
- }
-
- } else {
- //not a syntax error, rethrow it
- throw new SyntaxError("Unknown @ rule.", tokenStream.LT(0).startLine, tokenStream.LT(0).startCol);
- }
- break;
- case Tokens.S:
- this._readWhitespace();
- break;
- default:
- if(!this._ruleset()){
-
- //error handling for known issues
- switch(tt){
- case Tokens.CHARSET_SYM:
- token = tokenStream.LT(1);
- this._charset(false);
- throw new SyntaxError("@charset not allowed here.", token.startLine, token.startCol);
- case Tokens.IMPORT_SYM:
- token = tokenStream.LT(1);
- this._import(false);
- throw new SyntaxError("@import not allowed here.", token.startLine, token.startCol);
- case Tokens.NAMESPACE_SYM:
- token = tokenStream.LT(1);
- this._namespace(false);
- throw new SyntaxError("@namespace not allowed here.", token.startLine, token.startCol);
- default:
- tokenStream.get(); //get the last token
- this._unexpectedToken(tokenStream.token());
- }
-
- }
- }
- } catch(ex) {
- if (ex instanceof SyntaxError && !this.options.strict){
- this.fire({
- type: "error",
- error: ex,
- message: ex.message,
- line: ex.line,
- col: ex.col
- });
- } else {
- throw ex;
- }
- }
-
- tt = tokenStream.peek();
- }
-
- if (tt !== Tokens.EOF){
- this._unexpectedToken(tokenStream.token());
- }
-
- this.fire("endstylesheet");
- },
-
- _charset: function(emit){
- var tokenStream = this._tokenStream,
- charset,
- token,
- line,
- col;
-
- if (tokenStream.match(Tokens.CHARSET_SYM)){
- line = tokenStream.token().startLine;
- col = tokenStream.token().startCol;
-
- this._readWhitespace();
- tokenStream.mustMatch(Tokens.STRING);
-
- token = tokenStream.token();
- charset = token.value;
-
- this._readWhitespace();
- tokenStream.mustMatch(Tokens.SEMICOLON);
-
- if (emit !== false){
- this.fire({
- type: "charset",
- charset:charset,
- line: line,
- col: col
- });
- }
- }
- },
-
- _import: function(emit){
- /*
- * import
- * : IMPORT_SYM S*
- * [STRING|URI] S* media_query_list? ';' S*
- */
-
- var tokenStream = this._tokenStream,
- uri,
- importToken,
- mediaList = [];
-
- //read import symbol
- tokenStream.mustMatch(Tokens.IMPORT_SYM);
- importToken = tokenStream.token();
- this._readWhitespace();
-
- tokenStream.mustMatch([Tokens.STRING, Tokens.URI]);
-
- //grab the URI value
- uri = tokenStream.token().value.replace(/^(?:url\()?["']?([^"']+?)["']?\)?$/, "$1");
-
- this._readWhitespace();
-
- mediaList = this._media_query_list();
-
- //must end with a semicolon
- tokenStream.mustMatch(Tokens.SEMICOLON);
- this._readWhitespace();
-
- if (emit !== false){
- this.fire({
- type: "import",
- uri: uri,
- media: mediaList,
- line: importToken.startLine,
- col: importToken.startCol
- });
- }
-
- },
-
- _namespace: function(emit){
- /*
- * namespace
- * : NAMESPACE_SYM S* [namespace_prefix S*]? [STRING|URI] S* ';' S*
- */
-
- var tokenStream = this._tokenStream,
- line,
- col,
- prefix,
- uri;
-
- //read import symbol
- tokenStream.mustMatch(Tokens.NAMESPACE_SYM);
- line = tokenStream.token().startLine;
- col = tokenStream.token().startCol;
- this._readWhitespace();
-
- //it's a namespace prefix - no _namespace_prefix() method because it's just an IDENT
- if (tokenStream.match(Tokens.IDENT)){
- prefix = tokenStream.token().value;
- this._readWhitespace();
- }
-
- tokenStream.mustMatch([Tokens.STRING, Tokens.URI]);
- /*if (!tokenStream.match(Tokens.STRING)){
- tokenStream.mustMatch(Tokens.URI);
- }*/
-
- //grab the URI value
- uri = tokenStream.token().value.replace(/(?:url\()?["']([^"']+)["']\)?/, "$1");
-
- this._readWhitespace();
-
- //must end with a semicolon
- tokenStream.mustMatch(Tokens.SEMICOLON);
- this._readWhitespace();
-
- if (emit !== false){
- this.fire({
- type: "namespace",
- prefix: prefix,
- uri: uri,
- line: line,
- col: col
- });
- }
-
- },
-
- _media: function(){
- /*
- * media
- * : MEDIA_SYM S* media_query_list S* '{' S* ruleset* '}' S*
- * ;
- */
- var tokenStream = this._tokenStream,
- line,
- col,
- mediaList;// = [];
-
- //look for @media
- tokenStream.mustMatch(Tokens.MEDIA_SYM);
- line = tokenStream.token().startLine;
- col = tokenStream.token().startCol;
-
- this._readWhitespace();
-
- mediaList = this._media_query_list();
-
- tokenStream.mustMatch(Tokens.LBRACE);
- this._readWhitespace();
-
- this.fire({
- type: "startmedia",
- media: mediaList,
- line: line,
- col: col
- });
-
- while(true) {
- if (tokenStream.peek() === Tokens.PAGE_SYM){
- this._page();
- } else if (tokenStream.peek() === Tokens.FONT_FACE_SYM){
- this._font_face();
- } else if (tokenStream.peek() === Tokens.VIEWPORT_SYM){
- this._viewport();
- } else if (tokenStream.peek() === Tokens.DOCUMENT_SYM){
- this._document();
- } else if (!this._ruleset()){
- break;
- }
- }
-
- tokenStream.mustMatch(Tokens.RBRACE);
- this._readWhitespace();
-
- this.fire({
- type: "endmedia",
- media: mediaList,
- line: line,
- col: col
- });
- },
-
-
- //CSS3 Media Queries
- _media_query_list: function(){
- /*
- * media_query_list
- * : S* [media_query [ ',' S* media_query ]* ]?
- * ;
- */
- var tokenStream = this._tokenStream,
- mediaList = [];
-
-
- this._readWhitespace();
-
- if (tokenStream.peek() === Tokens.IDENT || tokenStream.peek() === Tokens.LPAREN){
- mediaList.push(this._media_query());
- }
-
- while(tokenStream.match(Tokens.COMMA)){
- this._readWhitespace();
- mediaList.push(this._media_query());
- }
-
- return mediaList;
- },
-
- /*
- * Note: "expression" in the grammar maps to the _media_expression
- * method.
-
- */
- _media_query: function(){
- /*
- * media_query
- * : [ONLY | NOT]? S* media_type S* [ AND S* expression ]*
- * | expression [ AND S* expression ]*
- * ;
- */
- var tokenStream = this._tokenStream,
- type = null,
- ident = null,
- token = null,
- expressions = [];
-
- if (tokenStream.match(Tokens.IDENT)){
- ident = tokenStream.token().value.toLowerCase();
-
- //since there's no custom tokens for these, need to manually check
- if (ident !== "only" && ident !== "not"){
- tokenStream.unget();
- ident = null;
- } else {
- token = tokenStream.token();
- }
- }
-
- this._readWhitespace();
-
- if (tokenStream.peek() === Tokens.IDENT){
- type = this._media_type();
- if (token === null){
- token = tokenStream.token();
- }
- } else if (tokenStream.peek() === Tokens.LPAREN){
- if (token === null){
- token = tokenStream.LT(1);
- }
- expressions.push(this._media_expression());
- }
-
- if (type === null && expressions.length === 0){
- return null;
- } else {
- this._readWhitespace();
- while (tokenStream.match(Tokens.IDENT)){
- if (tokenStream.token().value.toLowerCase() !== "and"){
- this._unexpectedToken(tokenStream.token());
- }
-
- this._readWhitespace();
- expressions.push(this._media_expression());
- }
- }
-
- return new MediaQuery(ident, type, expressions, token.startLine, token.startCol);
- },
-
- //CSS3 Media Queries
- _media_type: function(){
- /*
- * media_type
- * : IDENT
- * ;
- */
- return this._media_feature();
- },
-
- /**
- * Note: in CSS3 Media Queries, this is called "expression".
- * Renamed here to avoid conflict with CSS3 Selectors
- * definition of "expression". Also note that "expr" in the
- * grammar now maps to "expression" from CSS3 selectors.
- * @method _media_expression
- * @private
- */
- _media_expression: function(){
- /*
- * expression
- * : '(' S* media_feature S* [ ':' S* expr ]? ')' S*
- * ;
- */
- var tokenStream = this._tokenStream,
- feature = null,
- token,
- expression = null;
-
- tokenStream.mustMatch(Tokens.LPAREN);
-
- feature = this._media_feature();
- this._readWhitespace();
-
- if (tokenStream.match(Tokens.COLON)){
- this._readWhitespace();
- token = tokenStream.LT(1);
- expression = this._expression();
- }
-
- tokenStream.mustMatch(Tokens.RPAREN);
- this._readWhitespace();
-
- return new MediaFeature(feature, (expression ? new SyntaxUnit(expression, token.startLine, token.startCol) : null));
- },
-
- //CSS3 Media Queries
- _media_feature: function(){
- /*
- * media_feature
- * : IDENT
- * ;
- */
- var tokenStream = this._tokenStream;
-
- this._readWhitespace();
-
- tokenStream.mustMatch(Tokens.IDENT);
-
- return SyntaxUnit.fromToken(tokenStream.token());
- },
-
- //CSS3 Paged Media
- _page: function(){
- /*
- * page:
- * PAGE_SYM S* IDENT? pseudo_page? S*
- * '{' S* [ declaration | margin ]? [ ';' S* [ declaration | margin ]? ]* '}' S*
- * ;
- */
- var tokenStream = this._tokenStream,
- line,
- col,
- identifier = null,
- pseudoPage = null;
-
- //look for @page
- tokenStream.mustMatch(Tokens.PAGE_SYM);
- line = tokenStream.token().startLine;
- col = tokenStream.token().startCol;
-
- this._readWhitespace();
-
- if (tokenStream.match(Tokens.IDENT)){
- identifier = tokenStream.token().value;
-
- //The value 'auto' may not be used as a page name and MUST be treated as a syntax error.
- if (identifier.toLowerCase() === "auto"){
- this._unexpectedToken(tokenStream.token());
- }
- }
-
- //see if there's a colon upcoming
- if (tokenStream.peek() === Tokens.COLON){
- pseudoPage = this._pseudo_page();
- }
-
- this._readWhitespace();
-
- this.fire({
- type: "startpage",
- id: identifier,
- pseudo: pseudoPage,
- line: line,
- col: col
- });
-
- this._readDeclarations(true, true);
-
- this.fire({
- type: "endpage",
- id: identifier,
- pseudo: pseudoPage,
- line: line,
- col: col
- });
-
- },
-
- //CSS3 Paged Media
- _margin: function(){
- /*
- * margin :
- * margin_sym S* '{' declaration [ ';' S* declaration? ]* '}' S*
- * ;
- */
- var tokenStream = this._tokenStream,
- line,
- col,
- marginSym = this._margin_sym();
-
- if (marginSym){
- line = tokenStream.token().startLine;
- col = tokenStream.token().startCol;
-
- this.fire({
- type: "startpagemargin",
- margin: marginSym,
- line: line,
- col: col
- });
-
- this._readDeclarations(true);
-
- this.fire({
- type: "endpagemargin",
- margin: marginSym,
- line: line,
- col: col
- });
- return true;
- } else {
- return false;
- }
- },
-
- //CSS3 Paged Media
- _margin_sym: function(){
-
- /*
- * margin_sym :
- * TOPLEFTCORNER_SYM |
- * TOPLEFT_SYM |
- * TOPCENTER_SYM |
- * TOPRIGHT_SYM |
- * TOPRIGHTCORNER_SYM |
- * BOTTOMLEFTCORNER_SYM |
- * BOTTOMLEFT_SYM |
- * BOTTOMCENTER_SYM |
- * BOTTOMRIGHT_SYM |
- * BOTTOMRIGHTCORNER_SYM |
- * LEFTTOP_SYM |
- * LEFTMIDDLE_SYM |
- * LEFTBOTTOM_SYM |
- * RIGHTTOP_SYM |
- * RIGHTMIDDLE_SYM |
- * RIGHTBOTTOM_SYM
- * ;
- */
-
- var tokenStream = this._tokenStream;
-
- if(tokenStream.match([Tokens.TOPLEFTCORNER_SYM, Tokens.TOPLEFT_SYM,
- Tokens.TOPCENTER_SYM, Tokens.TOPRIGHT_SYM, Tokens.TOPRIGHTCORNER_SYM,
- Tokens.BOTTOMLEFTCORNER_SYM, Tokens.BOTTOMLEFT_SYM,
- Tokens.BOTTOMCENTER_SYM, Tokens.BOTTOMRIGHT_SYM,
- Tokens.BOTTOMRIGHTCORNER_SYM, Tokens.LEFTTOP_SYM,
- Tokens.LEFTMIDDLE_SYM, Tokens.LEFTBOTTOM_SYM, Tokens.RIGHTTOP_SYM,
- Tokens.RIGHTMIDDLE_SYM, Tokens.RIGHTBOTTOM_SYM]))
- {
- return SyntaxUnit.fromToken(tokenStream.token());
- } else {
- return null;
- }
-
- },
-
- _pseudo_page: function(){
- /*
- * pseudo_page
- * : ':' IDENT
- * ;
- */
-
- var tokenStream = this._tokenStream;
-
- tokenStream.mustMatch(Tokens.COLON);
- tokenStream.mustMatch(Tokens.IDENT);
-
- //TODO: CSS3 Paged Media says only "left", "center", and "right" are allowed
-
- return tokenStream.token().value;
- },
-
- _font_face: function(){
- /*
- * font_face
- * : FONT_FACE_SYM S*
- * '{' S* declaration [ ';' S* declaration ]* '}' S*
- * ;
- */
- var tokenStream = this._tokenStream,
- line,
- col;
-
- //look for @page
- tokenStream.mustMatch(Tokens.FONT_FACE_SYM);
- line = tokenStream.token().startLine;
- col = tokenStream.token().startCol;
-
- this._readWhitespace();
-
- this.fire({
- type: "startfontface",
- line: line,
- col: col
- });
-
- this._readDeclarations(true);
-
- this.fire({
- type: "endfontface",
- line: line,
- col: col
- });
- },
-
- _viewport: function(){
- /*
- * viewport
- * : VIEWPORT_SYM S*
- * '{' S* declaration? [ ';' S* declaration? ]* '}' S*
- * ;
- */
- var tokenStream = this._tokenStream,
- line,
- col;
-
- tokenStream.mustMatch(Tokens.VIEWPORT_SYM);
- line = tokenStream.token().startLine;
- col = tokenStream.token().startCol;
-
- this._readWhitespace();
-
- this.fire({
- type: "startviewport",
- line: line,
- col: col
- });
-
- this._readDeclarations(true);
-
- this.fire({
- type: "endviewport",
- line: line,
- col: col
- });
-
- },
-
- _document: function(){
- /*
- * document
- * : DOCUMENT_SYM S*
- * _document_function [ ',' S* _document_function ]* S*
- * '{' S* ruleset* '}'
- * ;
- */
-
- var tokenStream = this._tokenStream,
- token,
- functions = [],
- prefix = "";
-
- tokenStream.mustMatch(Tokens.DOCUMENT_SYM);
- token = tokenStream.token();
- if (/^@\-([^\-]+)\-/.test(token.value)) {
- prefix = RegExp.$1;
- }
-
- this._readWhitespace();
- functions.push(this._document_function());
-
- while(tokenStream.match(Tokens.COMMA)) {
- this._readWhitespace();
- functions.push(this._document_function());
- }
-
- tokenStream.mustMatch(Tokens.LBRACE);
- this._readWhitespace();
-
- this.fire({
- type: "startdocument",
- functions: functions,
- prefix: prefix,
- line: token.startLine,
- col: token.startCol
- });
-
- while(true) {
- if (tokenStream.peek() === Tokens.PAGE_SYM){
- this._page();
- } else if (tokenStream.peek() === Tokens.FONT_FACE_SYM){
- this._font_face();
- } else if (tokenStream.peek() === Tokens.VIEWPORT_SYM){
- this._viewport();
- } else if (tokenStream.peek() === Tokens.MEDIA_SYM){
- this._media();
- } else if (!this._ruleset()){
- break;
- }
- }
-
- tokenStream.mustMatch(Tokens.RBRACE);
- this._readWhitespace();
-
- this.fire({
- type: "enddocument",
- functions: functions,
- prefix: prefix,
- line: token.startLine,
- col: token.startCol
- });
- },
-
- _document_function: function(){
- /*
- * document_function
- * : function | URI S*
- * ;
- */
-
- var tokenStream = this._tokenStream,
- value;
-
- if (tokenStream.match(Tokens.URI)) {
- value = tokenStream.token().value;
- this._readWhitespace();
- } else {
- value = this._function();
- }
-
- return value;
- },
-
- _operator: function(inFunction){
-
- /*
- * operator (outside function)
- * : '/' S* | ',' S* | /( empty )/
- * operator (inside function)
- * : '/' S* | '+' S* | '*' S* | '-' S* /( empty )/
- * ;
- */
-
- var tokenStream = this._tokenStream,
- token = null;
-
- if (tokenStream.match([Tokens.SLASH, Tokens.COMMA]) ||
- (inFunction && tokenStream.match([Tokens.PLUS, Tokens.STAR, Tokens.MINUS]))){
- token = tokenStream.token();
- this._readWhitespace();
- }
- return token ? PropertyValuePart.fromToken(token) : null;
-
- },
-
- _combinator: function(){
-
- /*
- * combinator
- * : PLUS S* | GREATER S* | TILDE S* | S+
- * ;
- */
-
- var tokenStream = this._tokenStream,
- value = null,
- token;
-
- if(tokenStream.match([Tokens.PLUS, Tokens.GREATER, Tokens.TILDE])){
- token = tokenStream.token();
- value = new Combinator(token.value, token.startLine, token.startCol);
- this._readWhitespace();
- }
-
- return value;
- },
-
- _unary_operator: function(){
-
- /*
- * unary_operator
- * : '-' | '+'
- * ;
- */
-
- var tokenStream = this._tokenStream;
-
- if (tokenStream.match([Tokens.MINUS, Tokens.PLUS])){
- return tokenStream.token().value;
- } else {
- return null;
- }
- },
-
- _property: function(){
-
- /*
- * property
- * : IDENT S*
- * ;
- */
-
- var tokenStream = this._tokenStream,
- value = null,
- hack = null,
- tokenValue,
- token,
- line,
- col;
-
- //check for star hack - throws error if not allowed
- if (tokenStream.peek() === Tokens.STAR && this.options.starHack){
- tokenStream.get();
- token = tokenStream.token();
- hack = token.value;
- line = token.startLine;
- col = token.startCol;
- }
-
- if(tokenStream.match(Tokens.IDENT)){
- token = tokenStream.token();
- tokenValue = token.value;
-
- //check for underscore hack - no error if not allowed because it's valid CSS syntax
- if (tokenValue.charAt(0) === "_" && this.options.underscoreHack){
- hack = "_";
- tokenValue = tokenValue.substring(1);
- }
-
- value = new PropertyName(tokenValue, hack, (line||token.startLine), (col||token.startCol));
- this._readWhitespace();
- }
-
- return value;
- },
-
- //Augmented with CSS3 Selectors
- _ruleset: function(){
- /*
- * ruleset
- * : selectors_group
- * '{' S* declaration? [ ';' S* declaration? ]* '}' S*
- * ;
- */
-
- var tokenStream = this._tokenStream,
- tt,
- selectors;
-
-
- /*
- * Error Recovery: If even a single selector fails to parse,
- * then the entire ruleset should be thrown away.
- */
- try {
- selectors = this._selectors_group();
- } catch (ex){
- if (ex instanceof SyntaxError && !this.options.strict){
-
- //fire error event
- this.fire({
- type: "error",
- error: ex,
- message: ex.message,
- line: ex.line,
- col: ex.col
- });
-
- //skip over everything until closing brace
- tt = tokenStream.advance([Tokens.RBRACE]);
- if (tt === Tokens.RBRACE){
- //if there's a right brace, the rule is finished so don't do anything
- } else {
- //otherwise, rethrow the error because it wasn't handled properly
- throw ex;
- }
-
- } else {
- //not a syntax error, rethrow it
- throw ex;
- }
-
- //trigger parser to continue
- return true;
- }
-
- //if it got here, all selectors parsed
- if (selectors){
-
- this.fire({
- type: "startrule",
- selectors: selectors,
- line: selectors[0].line,
- col: selectors[0].col
- });
-
- this._readDeclarations(true);
-
- this.fire({
- type: "endrule",
- selectors: selectors,
- line: selectors[0].line,
- col: selectors[0].col
- });
-
- }
-
- return selectors;
-
- },
-
- //CSS3 Selectors
- _selectors_group: function(){
-
- /*
- * selectors_group
- * : selector [ COMMA S* selector ]*
- * ;
- */
- var tokenStream = this._tokenStream,
- selectors = [],
- selector;
-
- selector = this._selector();
- if (selector !== null){
-
- selectors.push(selector);
- while(tokenStream.match(Tokens.COMMA)){
- this._readWhitespace();
- selector = this._selector();
- if (selector !== null){
- selectors.push(selector);
- } else {
- this._unexpectedToken(tokenStream.LT(1));
- }
- }
- }
-
- return selectors.length ? selectors : null;
- },
-
- //CSS3 Selectors
- _selector: function(){
- /*
- * selector
- * : simple_selector_sequence [ combinator simple_selector_sequence ]*
- * ;
- */
-
- var tokenStream = this._tokenStream,
- selector = [],
- nextSelector = null,
- combinator = null,
- ws = null;
-
- //if there's no simple selector, then there's no selector
- nextSelector = this._simple_selector_sequence();
- if (nextSelector === null){
- return null;
- }
-
- selector.push(nextSelector);
-
- do {
-
- //look for a combinator
- combinator = this._combinator();
-
- if (combinator !== null){
- selector.push(combinator);
- nextSelector = this._simple_selector_sequence();
-
- //there must be a next selector
- if (nextSelector === null){
- this._unexpectedToken(tokenStream.LT(1));
- } else {
-
- //nextSelector is an instance of SelectorPart
- selector.push(nextSelector);
- }
- } else {
-
- //if there's not whitespace, we're done
- if (this._readWhitespace()){
-
- //add whitespace separator
- ws = new Combinator(tokenStream.token().value, tokenStream.token().startLine, tokenStream.token().startCol);
-
- //combinator is not required
- combinator = this._combinator();
-
- //selector is required if there's a combinator
- nextSelector = this._simple_selector_sequence();
- if (nextSelector === null){
- if (combinator !== null){
- this._unexpectedToken(tokenStream.LT(1));
- }
- } else {
-
- if (combinator !== null){
- selector.push(combinator);
- } else {
- selector.push(ws);
- }
-
- selector.push(nextSelector);
- }
- } else {
- break;
- }
-
- }
- } while(true);
-
- return new Selector(selector, selector[0].line, selector[0].col);
- },
-
- //CSS3 Selectors
- _simple_selector_sequence: function(){
- /*
- * simple_selector_sequence
- * : [ type_selector | universal ]
- * [ HASH | class | attrib | pseudo | negation ]*
- * | [ HASH | class | attrib | pseudo | negation ]+
- * ;
- */
-
- var tokenStream = this._tokenStream,
-
- //parts of a simple selector
- elementName = null,
- modifiers = [],
-
- //complete selector text
- selectorText= "",
-
- //the different parts after the element name to search for
- components = [
- //HASH
- function(){
- return tokenStream.match(Tokens.HASH) ?
- new SelectorSubPart(tokenStream.token().value, "id", tokenStream.token().startLine, tokenStream.token().startCol) :
- null;
- },
- this._class,
- this._attrib,
- this._pseudo,
- this._negation
- ],
- i = 0,
- len = components.length,
- component = null,
- line,
- col;
-
-
- //get starting line and column for the selector
- line = tokenStream.LT(1).startLine;
- col = tokenStream.LT(1).startCol;
-
- elementName = this._type_selector();
- if (!elementName){
- elementName = this._universal();
- }
-
- if (elementName !== null){
- selectorText += elementName;
- }
-
- while(true){
-
- //whitespace means we're done
- if (tokenStream.peek() === Tokens.S){
- break;
- }
-
- //check for each component
- while(i < len && component === null){
- component = components[i++].call(this);
- }
-
- if (component === null){
-
- //we don't have a selector
- if (selectorText === ""){
- return null;
- } else {
- break;
- }
- } else {
- i = 0;
- modifiers.push(component);
- selectorText += component.toString();
- component = null;
- }
- }
-
-
- return selectorText !== "" ?
- new SelectorPart(elementName, modifiers, selectorText, line, col) :
- null;
- },
-
- //CSS3 Selectors
- _type_selector: function(){
- /*
- * type_selector
- * : [ namespace_prefix ]? element_name
- * ;
- */
-
- var tokenStream = this._tokenStream,
- ns = this._namespace_prefix(),
- elementName = this._element_name();
-
- if (!elementName){
- /*
- * Need to back out the namespace that was read due to both
- * type_selector and universal reading namespace_prefix
- * first. Kind of hacky, but only way I can figure out
- * right now how to not change the grammar.
- */
- if (ns){
- tokenStream.unget();
- if (ns.length > 1){
- tokenStream.unget();
- }
- }
-
- return null;
- } else {
- if (ns){
- elementName.text = ns + elementName.text;
- elementName.col -= ns.length;
- }
- return elementName;
- }
- },
-
- //CSS3 Selectors
- _class: function(){
- /*
- * class
- * : '.' IDENT
- * ;
- */
-
- var tokenStream = this._tokenStream,
- token;
-
- if (tokenStream.match(Tokens.DOT)){
- tokenStream.mustMatch(Tokens.IDENT);
- token = tokenStream.token();
- return new SelectorSubPart("." + token.value, "class", token.startLine, token.startCol - 1);
- } else {
- return null;
- }
-
- },
-
- //CSS3 Selectors
- _element_name: function(){
- /*
- * element_name
- * : IDENT
- * ;
- */
-
- var tokenStream = this._tokenStream,
- token;
-
- if (tokenStream.match(Tokens.IDENT)){
- token = tokenStream.token();
- return new SelectorSubPart(token.value, "elementName", token.startLine, token.startCol);
-
- } else {
- return null;
- }
- },
-
- //CSS3 Selectors
- _namespace_prefix: function(){
- /*
- * namespace_prefix
- * : [ IDENT | '*' ]? '|'
- * ;
- */
- var tokenStream = this._tokenStream,
- value = "";
-
- //verify that this is a namespace prefix
- if (tokenStream.LA(1) === Tokens.PIPE || tokenStream.LA(2) === Tokens.PIPE){
-
- if(tokenStream.match([Tokens.IDENT, Tokens.STAR])){
- value += tokenStream.token().value;
- }
-
- tokenStream.mustMatch(Tokens.PIPE);
- value += "|";
-
- }
-
- return value.length ? value : null;
- },
-
- //CSS3 Selectors
- _universal: function(){
- /*
- * universal
- * : [ namespace_prefix ]? '*'
- * ;
- */
- var tokenStream = this._tokenStream,
- value = "",
- ns;
-
- ns = this._namespace_prefix();
- if(ns){
- value += ns;
- }
-
- if(tokenStream.match(Tokens.STAR)){
- value += "*";
- }
-
- return value.length ? value : null;
-
- },
-
- //CSS3 Selectors
- _attrib: function(){
- /*
- * attrib
- * : '[' S* [ namespace_prefix ]? IDENT S*
- * [ [ PREFIXMATCH |
- * SUFFIXMATCH |
- * SUBSTRINGMATCH |
- * '=' |
- * INCLUDES |
- * DASHMATCH ] S* [ IDENT | STRING ] S*
- * ]? ']'
- * ;
- */
-
- var tokenStream = this._tokenStream,
- value = null,
- ns,
- token;
-
- if (tokenStream.match(Tokens.LBRACKET)){
- token = tokenStream.token();
- value = token.value;
- value += this._readWhitespace();
-
- ns = this._namespace_prefix();
-
- if (ns){
- value += ns;
- }
-
- tokenStream.mustMatch(Tokens.IDENT);
- value += tokenStream.token().value;
- value += this._readWhitespace();
-
- if(tokenStream.match([Tokens.PREFIXMATCH, Tokens.SUFFIXMATCH, Tokens.SUBSTRINGMATCH,
- Tokens.EQUALS, Tokens.INCLUDES, Tokens.DASHMATCH])){
-
- value += tokenStream.token().value;
- value += this._readWhitespace();
-
- tokenStream.mustMatch([Tokens.IDENT, Tokens.STRING]);
- value += tokenStream.token().value;
- value += this._readWhitespace();
- }
-
- tokenStream.mustMatch(Tokens.RBRACKET);
-
- return new SelectorSubPart(value + "]", "attribute", token.startLine, token.startCol);
- } else {
- return null;
- }
- },
-
- //CSS3 Selectors
- _pseudo: function(){
-
- /*
- * pseudo
- * : ':' ':'? [ IDENT | functional_pseudo ]
- * ;
- */
-
- var tokenStream = this._tokenStream,
- pseudo = null,
- colons = ":",
- line,
- col;
-
- if (tokenStream.match(Tokens.COLON)){
-
- if (tokenStream.match(Tokens.COLON)){
- colons += ":";
- }
-
- if (tokenStream.match(Tokens.IDENT)){
- pseudo = tokenStream.token().value;
- line = tokenStream.token().startLine;
- col = tokenStream.token().startCol - colons.length;
- } else if (tokenStream.peek() === Tokens.FUNCTION){
- line = tokenStream.LT(1).startLine;
- col = tokenStream.LT(1).startCol - colons.length;
- pseudo = this._functional_pseudo();
- }
-
- if (pseudo){
- pseudo = new SelectorSubPart(colons + pseudo, "pseudo", line, col);
- }
- }
-
- return pseudo;
- },
-
- //CSS3 Selectors
- _functional_pseudo: function(){
- /*
- * functional_pseudo
- * : FUNCTION S* expression ')'
- * ;
- */
-
- var tokenStream = this._tokenStream,
- value = null;
-
- if(tokenStream.match(Tokens.FUNCTION)){
- value = tokenStream.token().value;
- value += this._readWhitespace();
- value += this._expression();
- tokenStream.mustMatch(Tokens.RPAREN);
- value += ")";
- }
-
- return value;
- },
-
- //CSS3 Selectors
- _expression: function(){
- /*
- * expression
- * : [ [ PLUS | '-' | DIMENSION | NUMBER | STRING | IDENT ] S* ]+
- * ;
- */
-
- var tokenStream = this._tokenStream,
- value = "";
-
- while(tokenStream.match([Tokens.PLUS, Tokens.MINUS, Tokens.DIMENSION,
- Tokens.NUMBER, Tokens.STRING, Tokens.IDENT, Tokens.LENGTH,
- Tokens.FREQ, Tokens.ANGLE, Tokens.TIME,
- Tokens.RESOLUTION, Tokens.SLASH])){
-
- value += tokenStream.token().value;
- value += this._readWhitespace();
- }
-
- return value.length ? value : null;
-
- },
-
- //CSS3 Selectors
- _negation: function(){
- /*
- * negation
- * : NOT S* negation_arg S* ')'
- * ;
- */
-
- var tokenStream = this._tokenStream,
- line,
- col,
- value = "",
- arg,
- subpart = null;
-
- if (tokenStream.match(Tokens.NOT)){
- value = tokenStream.token().value;
- line = tokenStream.token().startLine;
- col = tokenStream.token().startCol;
- value += this._readWhitespace();
- arg = this._negation_arg();
- value += arg;
- value += this._readWhitespace();
- tokenStream.match(Tokens.RPAREN);
- value += tokenStream.token().value;
-
- subpart = new SelectorSubPart(value, "not", line, col);
- subpart.args.push(arg);
- }
-
- return subpart;
- },
-
- //CSS3 Selectors
- _negation_arg: function(){
- /*
- * negation_arg
- * : type_selector | universal | HASH | class | attrib | pseudo
- * ;
- */
-
- var tokenStream = this._tokenStream,
- args = [
- this._type_selector,
- this._universal,
- function(){
- return tokenStream.match(Tokens.HASH) ?
- new SelectorSubPart(tokenStream.token().value, "id", tokenStream.token().startLine, tokenStream.token().startCol) :
- null;
- },
- this._class,
- this._attrib,
- this._pseudo
- ],
- arg = null,
- i = 0,
- len = args.length,
- line,
- col,
- part;
-
- line = tokenStream.LT(1).startLine;
- col = tokenStream.LT(1).startCol;
-
- while(i < len && arg === null){
-
- arg = args[i].call(this);
- i++;
- }
-
- //must be a negation arg
- if (arg === null){
- this._unexpectedToken(tokenStream.LT(1));
- }
-
- //it's an element name
- if (arg.type === "elementName"){
- part = new SelectorPart(arg, [], arg.toString(), line, col);
- } else {
- part = new SelectorPart(null, [arg], arg.toString(), line, col);
- }
-
- return part;
- },
-
- _declaration: function(){
-
- /*
- * declaration
- * : property ':' S* expr prio?
- * | /( empty )/
- * ;
- */
-
- var tokenStream = this._tokenStream,
- property = null,
- expr = null,
- prio = null,
- invalid = null,
- propertyName= "";
-
- property = this._property();
- if (property !== null){
-
- tokenStream.mustMatch(Tokens.COLON);
- this._readWhitespace();
-
- expr = this._expr();
-
- //if there's no parts for the value, it's an error
- if (!expr || expr.length === 0){
- this._unexpectedToken(tokenStream.LT(1));
- }
-
- prio = this._prio();
-
- /*
- * If hacks should be allowed, then only check the root
- * property. If hacks should not be allowed, treat
- * _property or *property as invalid properties.
- */
- propertyName = property.toString();
- if (this.options.starHack && property.hack === "*" ||
- this.options.underscoreHack && property.hack === "_") {
-
- propertyName = property.text;
- }
-
- try {
- this._validateProperty(propertyName, expr);
- } catch (ex) {
- invalid = ex;
- }
-
- this.fire({
- type: "property",
- property: property,
- value: expr,
- important: prio,
- line: property.line,
- col: property.col,
- invalid: invalid
- });
-
- return true;
- } else {
- return false;
- }
- },
-
- _prio: function(){
- /*
- * prio
- * : IMPORTANT_SYM S*
- * ;
- */
-
- var tokenStream = this._tokenStream,
- result = tokenStream.match(Tokens.IMPORTANT_SYM);
-
- this._readWhitespace();
- return result;
- },
-
- _expr: function(inFunction){
- /*
- * expr
- * : term [ operator term ]*
- * ;
- */
-
- var values = [],
- //valueParts = [],
- value = null,
- operator = null;
-
- value = this._term(inFunction);
- if (value !== null){
-
- values.push(value);
-
- do {
- operator = this._operator(inFunction);
-
- //if there's an operator, keep building up the value parts
- if (operator){
- values.push(operator);
- } /*else {
- //if there's not an operator, you have a full value
- values.push(new PropertyValue(valueParts, valueParts[0].line, valueParts[0].col));
- valueParts = [];
- }*/
-
- value = this._term(inFunction);
-
- if (value === null){
- break;
- } else {
- values.push(value);
- }
- } while(true);
- }
-
- //cleanup
- /*if (valueParts.length){
- values.push(new PropertyValue(valueParts, valueParts[0].line, valueParts[0].col));
- }*/
-
- return values.length > 0 ? new PropertyValue(values, values[0].line, values[0].col) : null;
- },
-
- _term: function(inFunction){
-
- /*
- * term
- * : unary_operator?
- * [ NUMBER S* | PERCENTAGE S* | LENGTH S* | ANGLE S* |
- * TIME S* | FREQ S* | function | ie_function ]
- * | STRING S* | IDENT S* | URI S* | UNICODERANGE S* | hexcolor
- * ;
- */
-
- var tokenStream = this._tokenStream,
- unary = null,
- value = null,
- endChar = null,
- token,
- line,
- col;
-
- //returns the operator or null
- unary = this._unary_operator();
- if (unary !== null){
- line = tokenStream.token().startLine;
- col = tokenStream.token().startCol;
- }
-
- //exception for IE filters
- if (tokenStream.peek() === Tokens.IE_FUNCTION && this.options.ieFilters){
-
- value = this._ie_function();
- if (unary === null){
- line = tokenStream.token().startLine;
- col = tokenStream.token().startCol;
- }
-
- //see if it's a simple block
- } else if (inFunction && tokenStream.match([Tokens.LPAREN, Tokens.LBRACE, Tokens.LBRACKET])){
-
- token = tokenStream.token();
- endChar = token.endChar;
- value = token.value + this._expr(inFunction).text;
- if (unary === null){
- line = tokenStream.token().startLine;
- col = tokenStream.token().startCol;
- }
- tokenStream.mustMatch(Tokens.type(endChar));
- value += endChar;
- this._readWhitespace();
-
- //see if there's a simple match
- } else if (tokenStream.match([Tokens.NUMBER, Tokens.PERCENTAGE, Tokens.LENGTH,
- Tokens.ANGLE, Tokens.TIME,
- Tokens.FREQ, Tokens.STRING, Tokens.IDENT, Tokens.URI, Tokens.UNICODE_RANGE])){
-
- value = tokenStream.token().value;
- if (unary === null){
- line = tokenStream.token().startLine;
- col = tokenStream.token().startCol;
- }
- this._readWhitespace();
- } else {
-
- //see if it's a color
- token = this._hexcolor();
- if (token === null){
-
- //if there's no unary, get the start of the next token for line/col info
- if (unary === null){
- line = tokenStream.LT(1).startLine;
- col = tokenStream.LT(1).startCol;
- }
-
- //has to be a function
- if (value === null){
-
- /*
- * This checks for alpha(opacity=0) style of IE
- * functions. IE_FUNCTION only presents progid: style.
- */
- if (tokenStream.LA(3) === Tokens.EQUALS && this.options.ieFilters){
- value = this._ie_function();
- } else {
- value = this._function();
- }
- }
-
- /*if (value === null){
- return null;
- //throw new Error("Expected identifier at line " + tokenStream.token().startLine + ", character " + tokenStream.token().startCol + ".");
- }*/
-
- } else {
- value = token.value;
- if (unary === null){
- line = token.startLine;
- col = token.startCol;
- }
- }
-
- }
-
- return value !== null ?
- new PropertyValuePart(unary !== null ? unary + value : value, line, col) :
- null;
-
- },
-
- _function: function(){
-
- /*
- * function
- * : FUNCTION S* expr ')' S*
- * ;
- */
-
- var tokenStream = this._tokenStream,
- functionText = null,
- expr = null,
- lt;
-
- if (tokenStream.match(Tokens.FUNCTION)){
- functionText = tokenStream.token().value;
- this._readWhitespace();
- expr = this._expr(true);
- functionText += expr;
-
- //START: Horrible hack in case it's an IE filter
- if (this.options.ieFilters && tokenStream.peek() === Tokens.EQUALS){
- do {
-
- if (this._readWhitespace()){
- functionText += tokenStream.token().value;
- }
-
- //might be second time in the loop
- if (tokenStream.LA(0) === Tokens.COMMA){
- functionText += tokenStream.token().value;
- }
-
- tokenStream.match(Tokens.IDENT);
- functionText += tokenStream.token().value;
-
- tokenStream.match(Tokens.EQUALS);
- functionText += tokenStream.token().value;
-
- //functionText += this._term();
- lt = tokenStream.peek();
- while(lt !== Tokens.COMMA && lt !== Tokens.S && lt !== Tokens.RPAREN){
- tokenStream.get();
- functionText += tokenStream.token().value;
- lt = tokenStream.peek();
- }
- } while(tokenStream.match([Tokens.COMMA, Tokens.S]));
- }
-
- //END: Horrible Hack
-
- tokenStream.match(Tokens.RPAREN);
- functionText += ")";
- this._readWhitespace();
- }
-
- return functionText;
- },
-
- _ie_function: function(){
-
- /* (My own extension)
- * ie_function
- * : IE_FUNCTION S* IDENT '=' term [S* ','? IDENT '=' term]+ ')' S*
- * ;
- */
-
- var tokenStream = this._tokenStream,
- functionText = null,
- lt;
-
- //IE function can begin like a regular function, too
- if (tokenStream.match([Tokens.IE_FUNCTION, Tokens.FUNCTION])){
- functionText = tokenStream.token().value;
-
- do {
-
- if (this._readWhitespace()){
- functionText += tokenStream.token().value;
- }
-
- //might be second time in the loop
- if (tokenStream.LA(0) === Tokens.COMMA){
- functionText += tokenStream.token().value;
- }
-
- tokenStream.match(Tokens.IDENT);
- functionText += tokenStream.token().value;
-
- tokenStream.match(Tokens.EQUALS);
- functionText += tokenStream.token().value;
-
- //functionText += this._term();
- lt = tokenStream.peek();
- while(lt !== Tokens.COMMA && lt !== Tokens.S && lt !== Tokens.RPAREN){
- tokenStream.get();
- functionText += tokenStream.token().value;
- lt = tokenStream.peek();
- }
- } while(tokenStream.match([Tokens.COMMA, Tokens.S]));
-
- tokenStream.match(Tokens.RPAREN);
- functionText += ")";
- this._readWhitespace();
- }
-
- return functionText;
- },
-
- _hexcolor: function(){
- /*
- * There is a constraint on the color that it must
- * have either 3 or 6 hex-digits (i.e., [0-9a-fA-F])
- * after the "#"; e.g., "#000" is OK, but "#abcd" is not.
- *
- * hexcolor
- * : HASH S*
- * ;
- */
-
- var tokenStream = this._tokenStream,
- token = null,
- color;
-
- if(tokenStream.match(Tokens.HASH)){
-
- //need to do some validation here
-
- token = tokenStream.token();
- color = token.value;
- if (!/#[a-f0-9]{3,6}/i.test(color)){
- throw new SyntaxError("Expected a hex color but found '" + color + "' at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol);
- }
- this._readWhitespace();
- }
-
- return token;
- },
-
- //-----------------------------------------------------------------
- // Animations methods
- //-----------------------------------------------------------------
-
- _keyframes: function(){
-
- /*
- * keyframes:
- * : KEYFRAMES_SYM S* keyframe_name S* '{' S* keyframe_rule* '}' {
- * ;
- */
- var tokenStream = this._tokenStream,
- token,
- tt,
- name,
- prefix = "";
-
- tokenStream.mustMatch(Tokens.KEYFRAMES_SYM);
- token = tokenStream.token();
- if (/^@\-([^\-]+)\-/.test(token.value)) {
- prefix = RegExp.$1;
- }
-
- this._readWhitespace();
- name = this._keyframe_name();
-
- this._readWhitespace();
- tokenStream.mustMatch(Tokens.LBRACE);
-
- this.fire({
- type: "startkeyframes",
- name: name,
- prefix: prefix,
- line: token.startLine,
- col: token.startCol
- });
-
- this._readWhitespace();
- tt = tokenStream.peek();
-
- //check for key
- while(tt === Tokens.IDENT || tt === Tokens.PERCENTAGE) {
- this._keyframe_rule();
- this._readWhitespace();
- tt = tokenStream.peek();
- }
-
- this.fire({
- type: "endkeyframes",
- name: name,
- prefix: prefix,
- line: token.startLine,
- col: token.startCol
- });
-
- this._readWhitespace();
- tokenStream.mustMatch(Tokens.RBRACE);
-
- },
-
- _keyframe_name: function(){
-
- /*
- * keyframe_name:
- * : IDENT
- * | STRING
- * ;
- */
- var tokenStream = this._tokenStream;
-
- tokenStream.mustMatch([Tokens.IDENT, Tokens.STRING]);
- return SyntaxUnit.fromToken(tokenStream.token());
- },
-
- _keyframe_rule: function(){
-
- /*
- * keyframe_rule:
- * : key_list S*
- * '{' S* declaration [ ';' S* declaration ]* '}' S*
- * ;
- */
- var keyList = this._key_list();
-
- this.fire({
- type: "startkeyframerule",
- keys: keyList,
- line: keyList[0].line,
- col: keyList[0].col
- });
-
- this._readDeclarations(true);
-
- this.fire({
- type: "endkeyframerule",
- keys: keyList,
- line: keyList[0].line,
- col: keyList[0].col
- });
-
- },
-
- _key_list: function(){
-
- /*
- * key_list:
- * : key [ S* ',' S* key]*
- * ;
- */
- var tokenStream = this._tokenStream,
- keyList = [];
-
- //must be least one key
- keyList.push(this._key());
-
- this._readWhitespace();
-
- while(tokenStream.match(Tokens.COMMA)){
- this._readWhitespace();
- keyList.push(this._key());
- this._readWhitespace();
- }
-
- return keyList;
- },
-
- _key: function(){
- /*
- * There is a restriction that IDENT can be only "from" or "to".
- *
- * key
- * : PERCENTAGE
- * | IDENT
- * ;
- */
-
- var tokenStream = this._tokenStream,
- token;
-
- if (tokenStream.match(Tokens.PERCENTAGE)){
- return SyntaxUnit.fromToken(tokenStream.token());
- } else if (tokenStream.match(Tokens.IDENT)){
- token = tokenStream.token();
-
- if (/from|to/i.test(token.value)){
- return SyntaxUnit.fromToken(token);
- }
-
- tokenStream.unget();
- }
-
- //if it gets here, there wasn't a valid token, so time to explode
- this._unexpectedToken(tokenStream.LT(1));
- },
-
- //-----------------------------------------------------------------
- // Helper methods
- //-----------------------------------------------------------------
-
- /**
- * Not part of CSS grammar, but useful for skipping over
- * combination of white space and HTML-style comments.
- * @return {void}
- * @method _skipCruft
- * @private
- */
- _skipCruft: function(){
- while(this._tokenStream.match([Tokens.S, Tokens.CDO, Tokens.CDC])){
- //noop
- }
- },
-
- /**
- * Not part of CSS grammar, but this pattern occurs frequently
- * in the official CSS grammar. Split out here to eliminate
- * duplicate code.
- * @param {Boolean} checkStart Indicates if the rule should check
- * for the left brace at the beginning.
- * @param {Boolean} readMargins Indicates if the rule should check
- * for margin patterns.
- * @return {void}
- * @method _readDeclarations
- * @private
- */
- _readDeclarations: function(checkStart, readMargins){
- /*
- * Reads the pattern
- * S* '{' S* declaration [ ';' S* declaration ]* '}' S*
- * or
- * S* '{' S* [ declaration | margin ]? [ ';' S* [ declaration | margin ]? ]* '}' S*
- * Note that this is how it is described in CSS3 Paged Media, but is actually incorrect.
- * A semicolon is only necessary following a declaration if there's another declaration
- * or margin afterwards.
- */
- var tokenStream = this._tokenStream,
- tt;
-
-
- this._readWhitespace();
-
- if (checkStart){
- tokenStream.mustMatch(Tokens.LBRACE);
- }
-
- this._readWhitespace();
-
- try {
-
- while(true){
- if (tokenStream.match(Tokens.SEMICOLON) || (readMargins && this._margin())){
- //noop
- } else if (this._declaration()){
- if (!tokenStream.match(Tokens.SEMICOLON)){
- break;
- }
- } else {
- break;
- }
-
-
- //if ((!this._margin() && !this._declaration()) || !tokenStream.match(Tokens.SEMICOLON)){
- // break;
- //}
- this._readWhitespace();
- }
-
- tokenStream.mustMatch(Tokens.RBRACE);
- this._readWhitespace();
-
- } catch (ex) {
- if (ex instanceof SyntaxError && !this.options.strict){
-
- //fire error event
- this.fire({
- type: "error",
- error: ex,
- message: ex.message,
- line: ex.line,
- col: ex.col
- });
-
- //see if there's another declaration
- tt = tokenStream.advance([Tokens.SEMICOLON, Tokens.RBRACE]);
- if (tt === Tokens.SEMICOLON){
- //if there's a semicolon, then there might be another declaration
- this._readDeclarations(false, readMargins);
- } else if (tt !== Tokens.RBRACE){
- //if there's a right brace, the rule is finished so don't do anything
- //otherwise, rethrow the error because it wasn't handled properly
- throw ex;
- }
-
- } else {
- //not a syntax error, rethrow it
- throw ex;
- }
- }
-
- },
-
- /**
- * In some cases, you can end up with two white space tokens in a
- * row. Instead of making a change in every function that looks for
- * white space, this function is used to match as much white space
- * as necessary.
- * @method _readWhitespace
- * @return {String} The white space if found, empty string if not.
- * @private
- */
- _readWhitespace: function(){
-
- var tokenStream = this._tokenStream,
- ws = "";
-
- while(tokenStream.match(Tokens.S)){
- ws += tokenStream.token().value;
- }
-
- return ws;
- },
-
-
- /**
- * Throws an error when an unexpected token is found.
- * @param {Object} token The token that was found.
- * @method _unexpectedToken
- * @return {void}
- * @private
- */
- _unexpectedToken: function(token){
- throw new SyntaxError("Unexpected token '" + token.value + "' at line " + token.startLine + ", col " + token.startCol + ".", token.startLine, token.startCol);
- },
-
- /**
- * Helper method used for parsing subparts of a style sheet.
- * @return {void}
- * @method _verifyEnd
- * @private
- */
- _verifyEnd: function(){
- if (this._tokenStream.LA(1) !== Tokens.EOF){
- this._unexpectedToken(this._tokenStream.LT(1));
- }
- },
-
- //-----------------------------------------------------------------
- // Validation methods
- //-----------------------------------------------------------------
- _validateProperty: function(property, value){
- Validation.validate(property, value);
- },
-
- //-----------------------------------------------------------------
- // Parsing methods
- //-----------------------------------------------------------------
-
- parse: function(input){
- this._tokenStream = new TokenStream(input, Tokens);
- this._stylesheet();
- },
-
- parseStyleSheet: function(input){
- //just passthrough
- return this.parse(input);
- },
-
- parseMediaQuery: function(input){
- this._tokenStream = new TokenStream(input, Tokens);
- var result = this._media_query();
-
- //if there's anything more, then it's an invalid selector
- this._verifyEnd();
-
- //otherwise return result
- return result;
- },
-
- /**
- * Parses a property value (everything after the semicolon).
- * @return {parserlib.css.PropertyValue} The property value.
- * @throws parserlib.util.SyntaxError If an unexpected token is found.
- * @method parserPropertyValue
- */
- parsePropertyValue: function(input){
-
- this._tokenStream = new TokenStream(input, Tokens);
- this._readWhitespace();
-
- var result = this._expr();
-
- //okay to have a trailing white space
- this._readWhitespace();
-
- //if there's anything more, then it's an invalid selector
- this._verifyEnd();
-
- //otherwise return result
- return result;
- },
-
- /**
- * Parses a complete CSS rule, including selectors and
- * properties.
- * @param {String} input The text to parser.
- * @return {Boolean} True if the parse completed successfully, false if not.
- * @method parseRule
- */
- parseRule: function(input){
- this._tokenStream = new TokenStream(input, Tokens);
-
- //skip any leading white space
- this._readWhitespace();
-
- var result = this._ruleset();
-
- //skip any trailing white space
- this._readWhitespace();
-
- //if there's anything more, then it's an invalid selector
- this._verifyEnd();
-
- //otherwise return result
- return result;
- },
-
- /**
- * Parses a single CSS selector (no comma)
- * @param {String} input The text to parse as a CSS selector.
- * @return {Selector} An object representing the selector.
- * @throws parserlib.util.SyntaxError If an unexpected token is found.
- * @method parseSelector
- */
- parseSelector: function(input){
-
- this._tokenStream = new TokenStream(input, Tokens);
-
- //skip any leading white space
- this._readWhitespace();
-
- var result = this._selector();
-
- //skip any trailing white space
- this._readWhitespace();
-
- //if there's anything more, then it's an invalid selector
- this._verifyEnd();
-
- //otherwise return result
- return result;
- },
-
- /**
- * Parses an HTML style attribute: a set of CSS declarations
- * separated by semicolons.
- * @param {String} input The text to parse as a style attribute
- * @return {void}
- * @method parseStyleAttribute
- */
- parseStyleAttribute: function(input){
- input += "}"; // for error recovery in _readDeclarations()
- this._tokenStream = new TokenStream(input, Tokens);
- this._readDeclarations();
- }
- };
-
- //copy over onto prototype
- for (prop in additions){
- if (Object.prototype.hasOwnProperty.call(additions, prop)){
- proto[prop] = additions[prop];
- }
- }
-
- return proto;
-}();
-
-
-/*
-nth
- : S* [ ['-'|'+']? INTEGER? {N} [ S* ['-'|'+'] S* INTEGER ]? |
- ['-'|'+']? INTEGER | {O}{D}{D} | {E}{V}{E}{N} ] S*
- ;
-*/
-var Properties = {
- __proto__: null,
-
- //A
- "align-items" : "flex-start | flex-end | center | baseline | stretch",
- "align-content" : "flex-start | flex-end | center | space-between | space-around | stretch",
- "align-self" : "auto | flex-start | flex-end | center | baseline | stretch",
- "-webkit-align-items" : "flex-start | flex-end | center | baseline | stretch",
- "-webkit-align-content" : "flex-start | flex-end | center | space-between | space-around | stretch",
- "-webkit-align-self" : "auto | flex-start | flex-end | center | baseline | stretch",
- "alignment-adjust" : "auto | baseline | before-edge | text-before-edge | middle | central | after-edge | text-after-edge | ideographic | alphabetic | hanging | mathematical | <percentage> | <length>",
- "alignment-baseline" : "baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical",
- "animation" : 1,
- "animation-delay" : { multi: "<time>", comma: true },
- "animation-direction" : { multi: "normal | alternate", comma: true },
- "animation-duration" : { multi: "<time>", comma: true },
- "animation-fill-mode" : { multi: "none | forwards | backwards | both", comma: true },
- "animation-iteration-count" : { multi: "<number> | infinite", comma: true },
- "animation-name" : { multi: "none | <ident>", comma: true },
- "animation-play-state" : { multi: "running | paused", comma: true },
- "animation-timing-function" : 1,
-
- //vendor prefixed
- "-moz-animation-delay" : { multi: "<time>", comma: true },
- "-moz-animation-direction" : { multi: "normal | alternate", comma: true },
- "-moz-animation-duration" : { multi: "<time>", comma: true },
- "-moz-animation-iteration-count" : { multi: "<number> | infinite", comma: true },
- "-moz-animation-name" : { multi: "none | <ident>", comma: true },
- "-moz-animation-play-state" : { multi: "running | paused", comma: true },
-
- "-ms-animation-delay" : { multi: "<time>", comma: true },
- "-ms-animation-direction" : { multi: "normal | alternate", comma: true },
- "-ms-animation-duration" : { multi: "<time>", comma: true },
- "-ms-animation-iteration-count" : { multi: "<number> | infinite", comma: true },
- "-ms-animation-name" : { multi: "none | <ident>", comma: true },
- "-ms-animation-play-state" : { multi: "running | paused", comma: true },
-
- "-webkit-animation-delay" : { multi: "<time>", comma: true },
- "-webkit-animation-direction" : { multi: "normal | alternate", comma: true },
- "-webkit-animation-duration" : { multi: "<time>", comma: true },
- "-webkit-animation-fill-mode" : { multi: "none | forwards | backwards | both", comma: true },
- "-webkit-animation-iteration-count" : { multi: "<number> | infinite", comma: true },
- "-webkit-animation-name" : { multi: "none | <ident>", comma: true },
- "-webkit-animation-play-state" : { multi: "running | paused", comma: true },
-
- "-o-animation-delay" : { multi: "<time>", comma: true },
- "-o-animation-direction" : { multi: "normal | alternate", comma: true },
- "-o-animation-duration" : { multi: "<time>", comma: true },
- "-o-animation-iteration-count" : { multi: "<number> | infinite", comma: true },
- "-o-animation-name" : { multi: "none | <ident>", comma: true },
- "-o-animation-play-state" : { multi: "running | paused", comma: true },
-
- "appearance" : "icon | window | desktop | workspace | document | tooltip | dialog | button | push-button | hyperlink | radio | radio-button | checkbox | menu-item | tab | menu | menubar | pull-down-menu | pop-up-menu | list-menu | radio-group | checkbox-group | outline-tree | range | field | combo-box | signature | password | normal | none | inherit",
- "azimuth" : function (expression) {
- var simple = "<angle> | leftwards | rightwards | inherit",
- direction = "left-side | far-left | left | center-left | center | center-right | right | far-right | right-side",
- behind = false,
- valid = false,
- part;
-
- if (!ValidationTypes.isAny(expression, simple)) {
- if (ValidationTypes.isAny(expression, "behind")) {
- behind = true;
- valid = true;
- }
-
- if (ValidationTypes.isAny(expression, direction)) {
- valid = true;
- if (!behind) {
- ValidationTypes.isAny(expression, "behind");
- }
- }
- }
-
- if (expression.hasNext()) {
- part = expression.next();
- if (valid) {
- throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
- } else {
- throw new ValidationError("Expected (<'azimuth'>) but found '" + part + "'.", part.line, part.col);
- }
- }
- },
-
- //B
- "backface-visibility" : "visible | hidden",
- "background" : 1,
- "background-attachment" : { multi: "<attachment>", comma: true },
- "background-clip" : { multi: "<box>", comma: true },
- "background-color" : "<color> | inherit",
- "background-image" : { multi: "<bg-image>", comma: true },
- "background-origin" : { multi: "<box>", comma: true },
- "background-position" : { multi: "<bg-position>", comma: true },
- "background-repeat" : { multi: "<repeat-style>" },
- "background-size" : { multi: "<bg-size>", comma: true },
- "baseline-shift" : "baseline | sub | super | <percentage> | <length>",
- "behavior" : 1,
- "binding" : 1,
- "bleed" : "<length>",
- "bookmark-label" : "<content> | <attr> | <string>",
- "bookmark-level" : "none | <integer>",
- "bookmark-state" : "open | closed",
- "bookmark-target" : "none | <uri> | <attr>",
- "border" : "<border-width> || <border-style> || <color>",
- "border-bottom" : "<border-width> || <border-style> || <color>",
- "border-bottom-color" : "<color> | inherit",
- "border-bottom-left-radius" : "<x-one-radius>",
- "border-bottom-right-radius" : "<x-one-radius>",
- "border-bottom-style" : "<border-style>",
- "border-bottom-width" : "<border-width>",
- "border-collapse" : "collapse | separate | inherit",
- "border-color" : { multi: "<color> | inherit", max: 4 },
- "border-image" : 1,
- "border-image-outset" : { multi: "<length> | <number>", max: 4 },
- "border-image-repeat" : { multi: "stretch | repeat | round", max: 2 },
- "border-image-slice" : function(expression) {
-
- var valid = false,
- numeric = "<number> | <percentage>",
- fill = false,
- count = 0,
- max = 4,
- part;
-
- if (ValidationTypes.isAny(expression, "fill")) {
- fill = true;
- valid = true;
- }
-
- while (expression.hasNext() && count < max) {
- valid = ValidationTypes.isAny(expression, numeric);
- if (!valid) {
- break;
- }
- count++;
- }
-
-
- if (!fill) {
- ValidationTypes.isAny(expression, "fill");
- } else {
- valid = true;
- }
-
- if (expression.hasNext()) {
- part = expression.next();
- if (valid) {
- throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
- } else {
- throw new ValidationError("Expected ([<number> | <percentage>]{1,4} && fill?) but found '" + part + "'.", part.line, part.col);
- }
- }
- },
- "border-image-source" : "<image> | none",
- "border-image-width" : { multi: "<length> | <percentage> | <number> | auto", max: 4 },
- "border-left" : "<border-width> || <border-style> || <color>",
- "border-left-color" : "<color> | inherit",
- "border-left-style" : "<border-style>",
- "border-left-width" : "<border-width>",
- "border-radius" : function(expression) {
-
- var valid = false,
- simple = "<length> | <percentage> | inherit",
- slash = false,
- count = 0,
- max = 8,
- part;
-
- while (expression.hasNext() && count < max) {
- valid = ValidationTypes.isAny(expression, simple);
- if (!valid) {
-
- if (String(expression.peek()) === "/" && count > 0 && !slash) {
- slash = true;
- max = count + 5;
- expression.next();
- } else {
- break;
- }
- }
- count++;
- }
-
- if (expression.hasNext()) {
- part = expression.next();
- if (valid) {
- throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
- } else {
- throw new ValidationError("Expected (<'border-radius'>) but found '" + part + "'.", part.line, part.col);
- }
- }
- },
- "border-right" : "<border-width> || <border-style> || <color>",
- "border-right-color" : "<color> | inherit",
- "border-right-style" : "<border-style>",
- "border-right-width" : "<border-width>",
- "border-spacing" : { multi: "<length> | inherit", max: 2 },
- "border-style" : { multi: "<border-style>", max: 4 },
- "border-top" : "<border-width> || <border-style> || <color>",
- "border-top-color" : "<color> | inherit",
- "border-top-left-radius" : "<x-one-radius>",
- "border-top-right-radius" : "<x-one-radius>",
- "border-top-style" : "<border-style>",
- "border-top-width" : "<border-width>",
- "border-width" : { multi: "<border-width>", max: 4 },
- "bottom" : "<margin-width> | inherit",
- "-moz-box-align" : "start | end | center | baseline | stretch",
- "-moz-box-decoration-break" : "slice |clone",
- "-moz-box-direction" : "normal | reverse | inherit",
- "-moz-box-flex" : "<number>",
- "-moz-box-flex-group" : "<integer>",
- "-moz-box-lines" : "single | multiple",
- "-moz-box-ordinal-group" : "<integer>",
- "-moz-box-orient" : "horizontal | vertical | inline-axis | block-axis | inherit",
- "-moz-box-pack" : "start | end | center | justify",
- "-o-box-decoration-break" : "slice | clone",
- "-webkit-box-align" : "start | end | center | baseline | stretch",
- "-webkit-box-decoration-break" : "slice |clone",
- "-webkit-box-direction" : "normal | reverse | inherit",
- "-webkit-box-flex" : "<number>",
- "-webkit-box-flex-group" : "<integer>",
- "-webkit-box-lines" : "single | multiple",
- "-webkit-box-ordinal-group" : "<integer>",
- "-webkit-box-orient" : "horizontal | vertical | inline-axis | block-axis | inherit",
- "-webkit-box-pack" : "start | end | center | justify",
- "box-decoration-break" : "slice | clone",
- "box-shadow" : function (expression) {
- var part;
-
- if (!ValidationTypes.isAny(expression, "none")) {
- Validation.multiProperty("<shadow>", expression, true, Infinity);
- } else {
- if (expression.hasNext()) {
- part = expression.next();
- throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
- }
- }
- },
- "box-sizing" : "content-box | border-box | inherit",
- "break-after" : "auto | always | avoid | left | right | page | column | avoid-page | avoid-column",
- "break-before" : "auto | always | avoid | left | right | page | column | avoid-page | avoid-column",
- "break-inside" : "auto | avoid | avoid-page | avoid-column",
-
- //C
- "caption-side" : "top | bottom | inherit",
- "clear" : "none | right | left | both | inherit",
- "clip" : 1,
- "color" : "<color> | inherit",
- "color-profile" : 1,
- "column-count" : "<integer> | auto", //http://www.w3.org/TR/css3-multicol/
- "column-fill" : "auto | balance",
- "column-gap" : "<length> | normal",
- "column-rule" : "<border-width> || <border-style> || <color>",
- "column-rule-color" : "<color>",
- "column-rule-style" : "<border-style>",
- "column-rule-width" : "<border-width>",
- "column-span" : "none | all",
- "column-width" : "<length> | auto",
- "columns" : 1,
- "content" : 1,
- "counter-increment" : 1,
- "counter-reset" : 1,
- "crop" : "<shape> | auto",
- "cue" : "cue-after | cue-before | inherit",
- "cue-after" : 1,
- "cue-before" : 1,
- "cursor" : 1,
-
- //D
- "direction" : "ltr | rtl | inherit",
- "display" : "inline | block | list-item | inline-block | table | inline-table | table-row-group | table-header-group | table-footer-group | table-row | table-column-group | table-column | table-cell | table-caption | grid | inline-grid | run-in | ruby | ruby-base | ruby-text | ruby-base-container | ruby-text-container | contents | none | inherit | -moz-box | -moz-inline-block | -moz-inline-box | -moz-inline-grid | -moz-inline-stack | -moz-inline-table | -moz-grid | -moz-grid-group | -moz-grid-line | -moz-groupbox | -moz-deck | -moz-popup | -moz-stack | -moz-marker | -webkit-box | -webkit-inline-box | -ms-flexbox | -ms-inline-flexbox | flex | -webkit-flex | inline-flex | -webkit-inline-flex",
- "dominant-baseline" : 1,
- "drop-initial-after-adjust" : "central | middle | after-edge | text-after-edge | ideographic | alphabetic | mathematical | <percentage> | <length>",
- "drop-initial-after-align" : "baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical",
- "drop-initial-before-adjust" : "before-edge | text-before-edge | central | middle | hanging | mathematical | <percentage> | <length>",
- "drop-initial-before-align" : "caps-height | baseline | use-script | before-edge | text-before-edge | after-edge | text-after-edge | central | middle | ideographic | alphabetic | hanging | mathematical",
- "drop-initial-size" : "auto | line | <length> | <percentage>",
- "drop-initial-value" : "initial | <integer>",
-
- //E
- "elevation" : "<angle> | below | level | above | higher | lower | inherit",
- "empty-cells" : "show | hide | inherit",
-
- //F
- "filter" : 1,
- "fit" : "fill | hidden | meet | slice",
- "fit-position" : 1,
- "flex" : "<flex>",
- "flex-basis" : "<width>",
- "flex-direction" : "row | row-reverse | column | column-reverse",
- "flex-flow" : "<flex-direction> || <flex-wrap>",
- "flex-grow" : "<number>",
- "flex-shrink" : "<number>",
- "flex-wrap" : "nowrap | wrap | wrap-reverse",
- "-webkit-flex" : "<flex>",
- "-webkit-flex-basis" : "<width>",
- "-webkit-flex-direction" : "row | row-reverse | column | column-reverse",
- "-webkit-flex-flow" : "<flex-direction> || <flex-wrap>",
- "-webkit-flex-grow" : "<number>",
- "-webkit-flex-shrink" : "<number>",
- "-webkit-flex-wrap" : "nowrap | wrap | wrap-reverse",
- "-ms-flex" : "<flex>",
- "-ms-flex-align" : "start | end | center | stretch | baseline",
- "-ms-flex-direction" : "row | row-reverse | column | column-reverse | inherit",
- "-ms-flex-order" : "<number>",
- "-ms-flex-pack" : "start | end | center | justify",
- "-ms-flex-wrap" : "nowrap | wrap | wrap-reverse",
- "float" : "left | right | none | inherit",
- "float-offset" : 1,
- "font" : 1,
- "font-family" : 1,
- "font-feature-settings" : "<feature-tag-value> | normal | inherit",
- "font-kerning" : "auto | normal | none | initial | inherit | unset",
- "font-size" : "<absolute-size> | <relative-size> | <length> | <percentage> | inherit",
- "font-size-adjust" : "<number> | none | inherit",
- "font-stretch" : "normal | ultra-condensed | extra-condensed | condensed | semi-condensed | semi-expanded | expanded | extra-expanded | ultra-expanded | inherit",
- "font-style" : "normal | italic | oblique | inherit",
- "font-variant" : "normal | small-caps | inherit",
- "font-variant-caps" : "normal | small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps",
- "font-variant-position" : "normal | sub | super | inherit | initial | unset",
- "font-weight" : "normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit",
-
- //G
- "grid" : 1,
- "grid-area" : 1,
- "grid-auto-columns" : 1,
- "grid-auto-flow" : 1,
- "grid-auto-position" : 1,
- "grid-auto-rows" : 1,
- "grid-cell-stacking" : "columns | rows | layer",
- "grid-column" : 1,
- "grid-columns" : 1,
- "grid-column-align" : "start | end | center | stretch",
- "grid-column-sizing" : 1,
- "grid-column-start" : 1,
- "grid-column-end" : 1,
- "grid-column-span" : "<integer>",
- "grid-flow" : "none | rows | columns",
- "grid-layer" : "<integer>",
- "grid-row" : 1,
- "grid-rows" : 1,
- "grid-row-align" : "start | end | center | stretch",
- "grid-row-start" : 1,
- "grid-row-end" : 1,
- "grid-row-span" : "<integer>",
- "grid-row-sizing" : 1,
- "grid-template" : 1,
- "grid-template-areas" : 1,
- "grid-template-columns" : 1,
- "grid-template-rows" : 1,
-
- //H
- "hanging-punctuation" : 1,
- "height" : "<margin-width> | <content-sizing> | inherit",
- "hyphenate-after" : "<integer> | auto",
- "hyphenate-before" : "<integer> | auto",
- "hyphenate-character" : "<string> | auto",
- "hyphenate-lines" : "no-limit | <integer>",
- "hyphenate-resource" : 1,
- "hyphens" : "none | manual | auto",
-
- //I
- "icon" : 1,
- "image-orientation" : "angle | auto",
- "image-rendering" : 1,
- "image-resolution" : 1,
- "ime-mode" : "auto | normal | active | inactive | disabled | inherit",
- "inline-box-align" : "initial | last | <integer>",
-
- //J
- "justify-content" : "flex-start | flex-end | center | space-between | space-around",
- "-webkit-justify-content" : "flex-start | flex-end | center | space-between | space-around",
-
- //L
- "left" : "<margin-width> | inherit",
- "letter-spacing" : "<length> | normal | inherit",
- "line-height" : "<number> | <length> | <percentage> | normal | inherit",
- "line-break" : "auto | loose | normal | strict",
- "line-stacking" : 1,
- "line-stacking-ruby" : "exclude-ruby | include-ruby",
- "line-stacking-shift" : "consider-shifts | disregard-shifts",
- "line-stacking-strategy" : "inline-line-height | block-line-height | max-height | grid-height",
- "list-style" : 1,
- "list-style-image" : "<uri> | none | inherit",
- "list-style-position" : "inside | outside | inherit",
- "list-style-type" : "disc | circle | square | decimal | decimal-leading-zero | lower-roman | upper-roman | lower-greek | lower-latin | upper-latin | armenian | georgian | lower-alpha | upper-alpha | none | inherit",
-
- //M
- "margin" : { multi: "<margin-width> | inherit", max: 4 },
- "margin-bottom" : "<margin-width> | inherit",
- "margin-left" : "<margin-width> | inherit",
- "margin-right" : "<margin-width> | inherit",
- "margin-top" : "<margin-width> | inherit",
- "mark" : 1,
- "mark-after" : 1,
- "mark-before" : 1,
- "marks" : 1,
- "marquee-direction" : 1,
- "marquee-play-count" : 1,
- "marquee-speed" : 1,
- "marquee-style" : 1,
- "max-height" : "<length> | <percentage> | <content-sizing> | none | inherit",
- "max-width" : "<length> | <percentage> | <content-sizing> | none | inherit",
- "min-height" : "<length> | <percentage> | <content-sizing> | contain-floats | -moz-contain-floats | -webkit-contain-floats | inherit",
- "min-width" : "<length> | <percentage> | <content-sizing> | contain-floats | -moz-contain-floats | -webkit-contain-floats | inherit",
- "move-to" : 1,
-
- //N
- "nav-down" : 1,
- "nav-index" : 1,
- "nav-left" : 1,
- "nav-right" : 1,
- "nav-up" : 1,
-
- //O
- "object-fit" : "fill | contain | cover | none | scale-down",
- "object-position" : "<bg-position>",
- "opacity" : "<number> | inherit",
- "order" : "<integer>",
- "-webkit-order" : "<integer>",
- "orphans" : "<integer> | inherit",
- "outline" : 1,
- "outline-color" : "<color> | invert | inherit",
- "outline-offset" : 1,
- "outline-style" : "<border-style> | inherit",
- "outline-width" : "<border-width> | inherit",
- "overflow" : "visible | hidden | scroll | auto | inherit",
- "overflow-style" : 1,
- "overflow-wrap" : "normal | break-word",
- "overflow-x" : 1,
- "overflow-y" : 1,
-
- //P
- "padding" : { multi: "<padding-width> | inherit", max: 4 },
- "padding-bottom" : "<padding-width> | inherit",
- "padding-left" : "<padding-width> | inherit",
- "padding-right" : "<padding-width> | inherit",
- "padding-top" : "<padding-width> | inherit",
- "page" : 1,
- "page-break-after" : "auto | always | avoid | left | right | inherit",
- "page-break-before" : "auto | always | avoid | left | right | inherit",
- "page-break-inside" : "auto | avoid | inherit",
- "page-policy" : 1,
- "pause" : 1,
- "pause-after" : 1,
- "pause-before" : 1,
- "perspective" : 1,
- "perspective-origin" : 1,
- "phonemes" : 1,
- "pitch" : 1,
- "pitch-range" : 1,
- "play-during" : 1,
- "pointer-events" : "auto | none | visiblePainted | visibleFill | visibleStroke | visible | painted | fill | stroke | all | inherit",
- "position" : "static | relative | absolute | fixed | inherit",
- "presentation-level" : 1,
- "punctuation-trim" : 1,
-
- //Q
- "quotes" : 1,
-
- //R
- "rendering-intent" : 1,
- "resize" : 1,
- "rest" : 1,
- "rest-after" : 1,
- "rest-before" : 1,
- "richness" : 1,
- "right" : "<margin-width> | inherit",
- "rotation" : 1,
- "rotation-point" : 1,
- "ruby-align" : 1,
- "ruby-overhang" : 1,
- "ruby-position" : 1,
- "ruby-span" : 1,
-
- //S
- "size" : 1,
- "speak" : "normal | none | spell-out | inherit",
- "speak-header" : "once | always | inherit",
- "speak-numeral" : "digits | continuous | inherit",
- "speak-punctuation" : "code | none | inherit",
- "speech-rate" : 1,
- "src" : 1,
- "stress" : 1,
- "string-set" : 1,
-
- "table-layout" : "auto | fixed | inherit",
- "tab-size" : "<integer> | <length>",
- "target" : 1,
- "target-name" : 1,
- "target-new" : 1,
- "target-position" : 1,
- "text-align" : "left | right | center | justify | match-parent | start | end | inherit" ,
- "text-align-last" : 1,
- "text-decoration" : 1,
- "text-emphasis" : 1,
- "text-height" : 1,
- "text-indent" : "<length> | <percentage> | inherit",
- "text-justify" : "auto | none | inter-word | inter-ideograph | inter-cluster | distribute | kashida",
- "text-outline" : 1,
- "text-overflow" : 1,
- "text-rendering" : "auto | optimizeSpeed | optimizeLegibility | geometricPrecision | inherit",
- "text-shadow" : 1,
- "text-transform" : "capitalize | uppercase | lowercase | none | inherit",
- "text-wrap" : "normal | none | avoid",
- "top" : "<margin-width> | inherit",
- "-ms-touch-action" : "auto | none | pan-x | pan-y | pan-left | pan-right | pan-up | pan-down | manipulation",
- "touch-action" : "auto | none | pan-x | pan-y | pan-left | pan-right | pan-up | pan-down | manipulation",
- "transform" : 1,
- "transform-origin" : 1,
- "transform-style" : 1,
- "transition" : 1,
- "transition-delay" : 1,
- "transition-duration" : 1,
- "transition-property" : 1,
- "transition-timing-function" : 1,
-
- //U
- "unicode-bidi" : "normal | embed | isolate | bidi-override | isolate-override | plaintext | inherit",
- "user-modify" : "read-only | read-write | write-only | inherit",
- "user-select" : "none | text | toggle | element | elements | all | inherit",
-
- //V
- "vertical-align" : "auto | use-script | baseline | sub | super | top | text-top | central | middle | bottom | text-bottom | <percentage> | <length> | inherit",
- "visibility" : "visible | hidden | collapse | inherit",
- "voice-balance" : 1,
- "voice-duration" : 1,
- "voice-family" : 1,
- "voice-pitch" : 1,
- "voice-pitch-range" : 1,
- "voice-rate" : 1,
- "voice-stress" : 1,
- "voice-volume" : 1,
- "volume" : 1,
-
- //W
- "white-space" : "normal | pre | nowrap | pre-wrap | pre-line | inherit | -pre-wrap | -o-pre-wrap | -moz-pre-wrap | -hp-pre-wrap", //http://perishablepress.com/wrapping-content/
- "white-space-collapse" : 1,
- "widows" : "<integer> | inherit",
- "width" : "<length> | <percentage> | <content-sizing> | auto | inherit",
- "will-change" : { multi: "<ident>", comma: true },
- "word-break" : "normal | keep-all | break-all",
- "word-spacing" : "<length> | normal | inherit",
- "word-wrap" : "normal | break-word",
- "writing-mode" : "horizontal-tb | vertical-rl | vertical-lr | lr-tb | rl-tb | tb-rl | bt-rl | tb-lr | bt-lr | lr-bt | rl-bt | lr | rl | tb | inherit",
-
- //Z
- "z-index" : "<integer> | auto | inherit",
- "zoom" : "<number> | <percentage> | normal"
-};
-/**
- * Represents a selector combinator (whitespace, +, >).
- * @namespace parserlib.css
- * @class PropertyName
- * @extends parserlib.util.SyntaxUnit
- * @constructor
- * @param {String} text The text representation of the unit.
- * @param {String} hack The type of IE hack applied ("*", "_", or null).
- * @param {int} line The line of text on which the unit resides.
- * @param {int} col The column of text on which the unit resides.
- */
-function PropertyName(text, hack, line, col){
-
- SyntaxUnit.call(this, text, line, col, Parser.PROPERTY_NAME_TYPE);
-
- /**
- * The type of IE hack applied ("*", "_", or null).
- * @type String
- * @property hack
- */
- this.hack = hack;
-
-}
-
-PropertyName.prototype = new SyntaxUnit();
-PropertyName.prototype.constructor = PropertyName;
-PropertyName.prototype.toString = function(){
- return (this.hack ? this.hack : "") + this.text;
-};
-/**
- * Represents a single part of a CSS property value, meaning that it represents
- * just everything single part between ":" and ";". If there are multiple values
- * separated by commas, this type represents just one of the values.
- * @param {String[]} parts An array of value parts making up this value.
- * @param {int} line The line of text on which the unit resides.
- * @param {int} col The column of text on which the unit resides.
- * @namespace parserlib.css
- * @class PropertyValue
- * @extends parserlib.util.SyntaxUnit
- * @constructor
- */
-function PropertyValue(parts, line, col){
-
- SyntaxUnit.call(this, parts.join(" "), line, col, Parser.PROPERTY_VALUE_TYPE);
-
- /**
- * The parts that make up the selector.
- * @type Array
- * @property parts
- */
- this.parts = parts;
-
-}
-
-PropertyValue.prototype = new SyntaxUnit();
-PropertyValue.prototype.constructor = PropertyValue;
-
-/**
- * A utility class that allows for easy iteration over the various parts of a
- * property value.
- * @param {parserlib.css.PropertyValue} value The property value to iterate over.
- * @namespace parserlib.css
- * @class PropertyValueIterator
- * @constructor
- */
-function PropertyValueIterator(value){
-
- /**
- * Iterator value
- * @type int
- * @property _i
- * @private
- */
- this._i = 0;
-
- /**
- * The parts that make up the value.
- * @type Array
- * @property _parts
- * @private
- */
- this._parts = value.parts;
-
- /**
- * Keeps track of bookmarks along the way.
- * @type Array
- * @property _marks
- * @private
- */
- this._marks = [];
-
- /**
- * Holds the original property value.
- * @type parserlib.css.PropertyValue
- * @property value
- */
- this.value = value;
-
-}
-
-/**
- * Returns the total number of parts in the value.
- * @return {int} The total number of parts in the value.
- * @method count
- */
-PropertyValueIterator.prototype.count = function(){
- return this._parts.length;
-};
-
-/**
- * Indicates if the iterator is positioned at the first item.
- * @return {Boolean} True if positioned at first item, false if not.
- * @method isFirst
- */
-PropertyValueIterator.prototype.isFirst = function(){
- return this._i === 0;
-};
-
-/**
- * Indicates if there are more parts of the property value.
- * @return {Boolean} True if there are more parts, false if not.
- * @method hasNext
- */
-PropertyValueIterator.prototype.hasNext = function(){
- return (this._i < this._parts.length);
-};
-
-/**
- * Marks the current spot in the iteration so it can be restored to
- * later on.
- * @return {void}
- * @method mark
- */
-PropertyValueIterator.prototype.mark = function(){
- this._marks.push(this._i);
-};
-
-/**
- * Returns the next part of the property value or null if there is no next
- * part. Does not move the internal counter forward.
- * @return {parserlib.css.PropertyValuePart} The next part of the property value or null if there is no next
- * part.
- * @method peek
- */
-PropertyValueIterator.prototype.peek = function(count){
- return this.hasNext() ? this._parts[this._i + (count || 0)] : null;
-};
-
-/**
- * Returns the next part of the property value or null if there is no next
- * part.
- * @return {parserlib.css.PropertyValuePart} The next part of the property value or null if there is no next
- * part.
- * @method next
- */
-PropertyValueIterator.prototype.next = function(){
- return this.hasNext() ? this._parts[this._i++] : null;
-};
-
-/**
- * Returns the previous part of the property value or null if there is no
- * previous part.
- * @return {parserlib.css.PropertyValuePart} The previous part of the
- * property value or null if there is no previous part.
- * @method previous
- */
-PropertyValueIterator.prototype.previous = function(){
- return this._i > 0 ? this._parts[--this._i] : null;
-};
-
-/**
- * Restores the last saved bookmark.
- * @return {void}
- * @method restore
- */
-PropertyValueIterator.prototype.restore = function(){
- if (this._marks.length){
- this._i = this._marks.pop();
- }
-};
-
-/**
- * Represents a single part of a CSS property value, meaning that it represents
- * just one part of the data between ":" and ";".
- * @param {String} text The text representation of the unit.
- * @param {int} line The line of text on which the unit resides.
- * @param {int} col The column of text on which the unit resides.
- * @namespace parserlib.css
- * @class PropertyValuePart
- * @extends parserlib.util.SyntaxUnit
- * @constructor
- */
-function PropertyValuePart(text, line, col){
- SyntaxUnit.call(this, text, line, col, Parser.PROPERTY_VALUE_PART_TYPE);
-
- /**
- * Indicates the type of value unit.
- * @type String
- * @property type
- */
- this.type = "unknown";
-
- //figure out what type of data it is
-
- var temp;
- //it is a measurement?
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Deprecated_and_obsolete_features#RegExp_Propertiesa
- var match;
- if (match = /^([+\-]?[\d\.]+)([a-z]+)$/i.exec(text)){ //dimension
- this.type = "dimension";
- this.value = +match[1];
- this.units = match[2];
-
- //try to narrow down
- switch(this.units.toLowerCase()){
-
- case "em":
- case "rem":
- case "ex":
- case "px":
- case "cm":
- case "mm":
- case "in":
- case "pt":
- case "pc":
- case "ch":
- case "vh":
- case "vw":
- case "vmax":
- case "vmin":
- this.type = "length";
- break;
-
- case "fr":
- this.type = "grid";
- break;
-
- case "deg":
- case "rad":
- case "grad":
- this.type = "angle";
- break;
-
- case "ms":
- case "s":
- this.type = "time";
- break;
-
- case "hz":
- case "khz":
- this.type = "frequency";
- break;
-
- case "dpi":
- case "dpcm":
- this.type = "resolution";
- break;
-
- //default
-
- }
-
- } else if (/^([+\-]?[\d\.]+)%$/i.test(text)){ //percentage
- this.type = "percentage";
- this.value = +RegExp.$1;
- } else if (/^([+\-]?\d+)$/i.test(text)){ //integer
- this.type = "integer";
- this.value = +RegExp.$1;
- } else if (/^([+\-]?[\d\.]+)$/i.test(text)){ //number
- this.type = "number";
- this.value = +RegExp.$1;
-
- } else if (/^#([a-f0-9]{3,6})/i.test(text)){ //hexcolor
- this.type = "color";
- temp = RegExp.$1;
- if (temp.length === 3){
- this.red = parseInt(temp.charAt(0)+temp.charAt(0),16);
- this.green = parseInt(temp.charAt(1)+temp.charAt(1),16);
- this.blue = parseInt(temp.charAt(2)+temp.charAt(2),16);
- } else {
- this.red = parseInt(temp.substring(0,2),16);
- this.green = parseInt(temp.substring(2,4),16);
- this.blue = parseInt(temp.substring(4,6),16);
- }
- } else if (/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/i.test(text)){ //rgb() color with absolute numbers
- this.type = "color";
- this.red = +RegExp.$1;
- this.green = +RegExp.$2;
- this.blue = +RegExp.$3;
- } else if (/^rgb\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/i.test(text)){ //rgb() color with percentages
- this.type = "color";
- this.red = +RegExp.$1 * 255 / 100;
- this.green = +RegExp.$2 * 255 / 100;
- this.blue = +RegExp.$3 * 255 / 100;
- } else if (/^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*([\d\.]+)\s*\)/i.test(text)){ //rgba() color with absolute numbers
- this.type = "color";
- this.red = +RegExp.$1;
- this.green = +RegExp.$2;
- this.blue = +RegExp.$3;
- this.alpha = +RegExp.$4;
- } else if (/^rgba\(\s*(\d+)%\s*,\s*(\d+)%\s*,\s*(\d+)%\s*,\s*([\d\.]+)\s*\)/i.test(text)){ //rgba() color with percentages
- this.type = "color";
- this.red = +RegExp.$1 * 255 / 100;
- this.green = +RegExp.$2 * 255 / 100;
- this.blue = +RegExp.$3 * 255 / 100;
- this.alpha = +RegExp.$4;
- } else if (/^hsl\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*\)/i.test(text)){ //hsl()
- this.type = "color";
- this.hue = +RegExp.$1;
- this.saturation = +RegExp.$2 / 100;
- this.lightness = +RegExp.$3 / 100;
- } else if (/^hsla\(\s*(\d+)\s*,\s*(\d+)%\s*,\s*(\d+)%\s*,\s*([\d\.]+)\s*\)/i.test(text)){ //hsla() color with percentages
- this.type = "color";
- this.hue = +RegExp.$1;
- this.saturation = +RegExp.$2 / 100;
- this.lightness = +RegExp.$3 / 100;
- this.alpha = +RegExp.$4;
- } else if (/^url\(["']?([^\)"']+)["']?\)/i.test(text)){ //URI
- this.type = "uri";
- this.uri = RegExp.$1;
- } else if (/^([^\(]+)\(/i.test(text)){
- this.type = "function";
- this.name = RegExp.$1;
- this.value = text;
- } else if (/^"([^\n\r\f\\"]|\\\r\n|\\[^\r0-9a-f]|\\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?)*"/i.test(text)){ //double-quoted string
- this.type = "string";
- this.value = PropertyValuePart.parseString(text);
- } else if (/^'([^\n\r\f\\']|\\\r\n|\\[^\r0-9a-f]|\\[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?)*'/i.test(text)){ //single-quoted string
- this.type = "string";
- this.value = PropertyValuePart.parseString(text);
- } else if (Colors[text.toLowerCase()]){ //named color
- this.type = "color";
- temp = Colors[text.toLowerCase()].substring(1);
- this.red = parseInt(temp.substring(0,2),16);
- this.green = parseInt(temp.substring(2,4),16);
- this.blue = parseInt(temp.substring(4,6),16);
- } else if (/^[\,\/]$/.test(text)){
- this.type = "operator";
- this.value = text;
- } else if (/^[a-z\-_\u0080-\uFFFF][a-z0-9\-_\u0080-\uFFFF]*$/i.test(text)){
- this.type = "identifier";
- this.value = text;
- }
-
-}
-
-PropertyValuePart.prototype = new SyntaxUnit();
-PropertyValuePart.prototype.constructor = PropertyValuePart;
-
-/**
- * Helper method to parse a CSS string.
- */
-PropertyValuePart.parseString = function(str) {
- str = str.slice(1, -1); // Strip surrounding single/double quotes
- var replacer = function(match, esc) {
- if (/^(\n|\r\n|\r|\f)$/.test(esc)) { return ''; }
- var m = /^[0-9a-f]{1,6}/i.exec(esc);
- if (m) {
- var codePoint = parseInt(m[0], 16);
- if (String.fromCodePoint) {
- return String.fromCodePoint(codePoint);
- } else {
- // XXX No support for surrogates on old JavaScript engines.
- return String.fromCharCode(codePoint);
- }
- }
- return esc;
- };
- return str.replace(/\\(\r\n|[^\r0-9a-f]|[0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?)/ig,
- replacer);
-};
-
-/**
- * Helper method to serialize a CSS string.
- */
-PropertyValuePart.serializeString = function(value) {
- var replacer = function(match, c) {
- if (c === '"') {
- return "\\" + c;
- }
- var cp = String.codePointAt ? String.codePointAt(0) :
- // We only escape non-surrogate chars, so using charCodeAt
- // is harmless here.
- String.charCodeAt(0);
- return "\\" + cp.toString(16) + " ";
- };
- return '"' + value.replace(/["\r\n\f]/g, replacer) + '"';
-};
-
-/**
- * Create a new syntax unit based solely on the given token.
- * Convenience method for creating a new syntax unit when
- * it represents a single token instead of multiple.
- * @param {Object} token The token object to represent.
- * @return {parserlib.css.PropertyValuePart} The object representing the token.
- * @static
- * @method fromToken
- */
-PropertyValuePart.fromToken = function(token){
- return new PropertyValuePart(token.value, token.startLine, token.startCol);
-};
-var Pseudos = {
- __proto__: null,
- ":first-letter": 1,
- ":first-line": 1,
- ":before": 1,
- ":after": 1
-};
-
-Pseudos.ELEMENT = 1;
-Pseudos.CLASS = 2;
-
-Pseudos.isElement = function(pseudo){
- return pseudo.indexOf("::") === 0 || Pseudos[pseudo.toLowerCase()] === Pseudos.ELEMENT;
-};
-/**
- * Represents an entire single selector, including all parts but not
- * including multiple selectors (those separated by commas).
- * @namespace parserlib.css
- * @class Selector
- * @extends parserlib.util.SyntaxUnit
- * @constructor
- * @param {Array} parts Array of selectors parts making up this selector.
- * @param {int} line The line of text on which the unit resides.
- * @param {int} col The column of text on which the unit resides.
- */
-function Selector(parts, line, col){
-
- SyntaxUnit.call(this, parts.join(" "), line, col, Parser.SELECTOR_TYPE);
-
- /**
- * The parts that make up the selector.
- * @type Array
- * @property parts
- */
- this.parts = parts;
-
- /**
- * The specificity of the selector.
- * @type parserlib.css.Specificity
- * @property specificity
- */
- this.specificity = Specificity.calculate(this);
-
-}
-
-Selector.prototype = new SyntaxUnit();
-Selector.prototype.constructor = Selector;
-
-/**
- * Represents a single part of a selector string, meaning a single set of
- * element name and modifiers. This does not include combinators such as
- * spaces, +, >, etc.
- * @namespace parserlib.css
- * @class SelectorPart
- * @extends parserlib.util.SyntaxUnit
- * @constructor
- * @param {String} elementName The element name in the selector or null
- * if there is no element name.
- * @param {Array} modifiers Array of individual modifiers for the element.
- * May be empty if there are none.
- * @param {String} text The text representation of the unit.
- * @param {int} line The line of text on which the unit resides.
- * @param {int} col The column of text on which the unit resides.
- */
-function SelectorPart(elementName, modifiers, text, line, col){
-
- SyntaxUnit.call(this, text, line, col, Parser.SELECTOR_PART_TYPE);
-
- /**
- * The tag name of the element to which this part
- * of the selector affects.
- * @type String
- * @property elementName
- */
- this.elementName = elementName;
-
- /**
- * The parts that come after the element name, such as class names, IDs,
- * pseudo classes/elements, etc.
- * @type Array
- * @property modifiers
- */
- this.modifiers = modifiers;
-
-}
-
-SelectorPart.prototype = new SyntaxUnit();
-SelectorPart.prototype.constructor = SelectorPart;
-
-/**
- * Represents a selector modifier string, meaning a class name, element name,
- * element ID, pseudo rule, etc.
- * @namespace parserlib.css
- * @class SelectorSubPart
- * @extends parserlib.util.SyntaxUnit
- * @constructor
- * @param {String} text The text representation of the unit.
- * @param {String} type The type of selector modifier.
- * @param {int} line The line of text on which the unit resides.
- * @param {int} col The column of text on which the unit resides.
- */
-function SelectorSubPart(text, type, line, col){
-
- SyntaxUnit.call(this, text, line, col, Parser.SELECTOR_SUB_PART_TYPE);
-
- /**
- * The type of modifier.
- * @type String
- * @property type
- */
- this.type = type;
-
- /**
- * Some subparts have arguments, this represents them.
- * @type Array
- * @property args
- */
- this.args = [];
-
-}
-
-SelectorSubPart.prototype = new SyntaxUnit();
-SelectorSubPart.prototype.constructor = SelectorSubPart;
-
-/**
- * Represents a selector's specificity.
- * @namespace parserlib.css
- * @class Specificity
- * @constructor
- * @param {int} a Should be 1 for inline styles, zero for stylesheet styles
- * @param {int} b Number of ID selectors
- * @param {int} c Number of classes and pseudo classes
- * @param {int} d Number of element names and pseudo elements
- */
-function Specificity(a, b, c, d){
- this.a = a;
- this.b = b;
- this.c = c;
- this.d = d;
-}
-
-Specificity.prototype = {
- constructor: Specificity,
-
- /**
- * Compare this specificity to another.
- * @param {Specificity} other The other specificity to compare to.
- * @return {int} -1 if the other specificity is larger, 1 if smaller, 0 if equal.
- * @method compare
- */
- compare: function(other){
- var comps = ["a", "b", "c", "d"],
- i, len;
-
- for (i=0, len=comps.length; i < len; i++){
- if (this[comps[i]] < other[comps[i]]){
- return -1;
- } else if (this[comps[i]] > other[comps[i]]){
- return 1;
- }
- }
-
- return 0;
- },
-
- /**
- * Creates a numeric value for the specificity.
- * @return {int} The numeric value for the specificity.
- * @method valueOf
- */
- valueOf: function(){
- return (this.a * 1000) + (this.b * 100) + (this.c * 10) + this.d;
- },
-
- /**
- * Returns a string representation for specificity.
- * @return {String} The string representation of specificity.
- * @method toString
- */
- toString: function(){
- return this.a + "," + this.b + "," + this.c + "," + this.d;
- }
-
-};
-
-/**
- * Calculates the specificity of the given selector.
- * @param {parserlib.css.Selector} The selector to calculate specificity for.
- * @return {parserlib.css.Specificity} The specificity of the selector.
- * @static
- * @method calculate
- */
-Specificity.calculate = function(selector){
-
- var i, len,
- part,
- b=0, c=0, d=0;
-
- function updateValues(part){
-
- var i, j, len, num,
- elementName = part.elementName ? part.elementName.text : "",
- modifier;
-
- if (elementName && elementName.charAt(elementName.length-1) !== "*") {
- d++;
- }
-
- for (i=0, len=part.modifiers.length; i < len; i++){
- modifier = part.modifiers[i];
- switch(modifier.type){
- case "class":
- case "attribute":
- c++;
- break;
-
- case "id":
- b++;
- break;
-
- case "pseudo":
- if (Pseudos.isElement(modifier.text)){
- d++;
- } else {
- c++;
- }
- break;
-
- case "not":
- for (j=0, num=modifier.args.length; j < num; j++){
- updateValues(modifier.args[j]);
- }
- }
- }
- }
-
- for (i=0, len=selector.parts.length; i < len; i++){
- part = selector.parts[i];
-
- if (part instanceof SelectorPart){
- updateValues(part);
- }
- }
-
- return new Specificity(0, b, c, d);
-};
-
-var h = /^[0-9a-fA-F]$/,
- //nonascii = /^[\u0080-\uFFFF]$/,
- nl = /\n|\r\n|\r|\f/;
-
-//-----------------------------------------------------------------------------
-// Helper functions
-//-----------------------------------------------------------------------------
-
-
-function isHexDigit(c){
- return c !== null && h.test(c);
-}
-
-function isDigit(c){
- return c !== null && /\d/.test(c);
-}
-
-function isWhitespace(c){
- return c !== null && /\s/.test(c);
-}
-
-function isNewLine(c){
- return c !== null && nl.test(c);
-}
-
-function isNameStart(c){
- return c !== null && (/[a-z_\u0080-\uFFFF\\]/i.test(c));
-}
-
-function isNameChar(c){
- return c !== null && (isNameStart(c) || /[0-9\-\\]/.test(c));
-}
-
-function isIdentStart(c){
- return c !== null && (isNameStart(c) || /\-\\/.test(c));
-}
-
-function mix(receiver, supplier){
- for (var prop in supplier){
- if (Object.prototype.hasOwnProperty.call(supplier, prop)){
- receiver[prop] = supplier[prop];
- }
- }
- return receiver;
-}
-
-//-----------------------------------------------------------------------------
-// CSS Token Stream
-//-----------------------------------------------------------------------------
-
-
-/**
- * A token stream that produces CSS tokens.
- * @param {String|Reader} input The source of text to tokenize.
- * @constructor
- * @class TokenStream
- * @namespace parserlib.css
- */
-function TokenStream(input){
- TokenStreamBase.call(this, input, Tokens);
-}
-
-TokenStream.prototype = mix(new TokenStreamBase(), {
-
- /**
- * Overrides the TokenStreamBase method of the same name
- * to produce CSS tokens.
- * @param {variant} channel The name of the channel to use
- * for the next token.
- * @return {Object} A token object representing the next token.
- * @method _getToken
- * @private
- */
- _getToken: function(channel){
-
- var c,
- reader = this._reader,
- token = null,
- startLine = reader.getLine(),
- startCol = reader.getCol();
-
- c = reader.read();
-
-
- while(c){
- switch(c){
-
- /*
- * Potential tokens:
- * - COMMENT
- * - SLASH
- * - CHAR
- */
- case "/":
-
- if(reader.peek() === "*"){
- token = this.commentToken(c, startLine, startCol);
- } else {
- token = this.charToken(c, startLine, startCol);
- }
- break;
-
- /*
- * Potential tokens:
- * - DASHMATCH
- * - INCLUDES
- * - PREFIXMATCH
- * - SUFFIXMATCH
- * - SUBSTRINGMATCH
- * - CHAR
- */
- case "|":
- case "~":
- case "^":
- case "$":
- case "*":
- if(reader.peek() === "="){
- token = this.comparisonToken(c, startLine, startCol);
- } else {
- token = this.charToken(c, startLine, startCol);
- }
- break;
-
- /*
- * Potential tokens:
- * - STRING
- * - INVALID
- */
- case "\"":
- case "'":
- token = this.stringToken(c, startLine, startCol);
- break;
-
- /*
- * Potential tokens:
- * - HASH
- * - CHAR
- */
- case "#":
- if (isNameChar(reader.peek())){
- token = this.hashToken(c, startLine, startCol);
- } else {
- token = this.charToken(c, startLine, startCol);
- }
- break;
-
- /*
- * Potential tokens:
- * - DOT
- * - NUMBER
- * - DIMENSION
- * - PERCENTAGE
- */
- case ".":
- if (isDigit(reader.peek())){
- token = this.numberToken(c, startLine, startCol);
- } else {
- token = this.charToken(c, startLine, startCol);
- }
- break;
-
- /*
- * Potential tokens:
- * - CDC
- * - MINUS
- * - NUMBER
- * - DIMENSION
- * - PERCENTAGE
- */
- case "-":
- if (reader.peek() === "-"){ //could be closing HTML-style comment
- token = this.htmlCommentEndToken(c, startLine, startCol);
- } else if (isNameStart(reader.peek())){
- token = this.identOrFunctionToken(c, startLine, startCol);
- } else {
- token = this.charToken(c, startLine, startCol);
- }
- break;
-
- /*
- * Potential tokens:
- * - IMPORTANT_SYM
- * - CHAR
- */
- case "!":
- token = this.importantToken(c, startLine, startCol);
- break;
-
- /*
- * Any at-keyword or CHAR
- */
- case "@":
- token = this.atRuleToken(c, startLine, startCol);
- break;
-
- /*
- * Potential tokens:
- * - NOT
- * - CHAR
- */
- case ":":
- token = this.notToken(c, startLine, startCol);
- break;
-
- /*
- * Potential tokens:
- * - CDO
- * - CHAR
- */
- case "<":
- token = this.htmlCommentStartToken(c, startLine, startCol);
- break;
-
- /*
- * Potential tokens:
- * - UNICODE_RANGE
- * - URL
- * - CHAR
- */
- case "U":
- case "u":
- if (reader.peek() === "+"){
- token = this.unicodeRangeToken(c, startLine, startCol);
- break;
- }
- /* falls through */
- default:
-
- /*
- * Potential tokens:
- * - NUMBER
- * - DIMENSION
- * - LENGTH
- * - FREQ
- * - TIME
- * - EMS
- * - EXS
- * - ANGLE
- */
- if (isDigit(c)){
- token = this.numberToken(c, startLine, startCol);
- } else
-
- /*
- * Potential tokens:
- * - S
- */
- if (isWhitespace(c)){
- token = this.whitespaceToken(c, startLine, startCol);
- } else
-
- /*
- * Potential tokens:
- * - IDENT
- */
- if (isIdentStart(c)){
- token = this.identOrFunctionToken(c, startLine, startCol);
- } else
-
- /*
- * Potential tokens:
- * - CHAR
- * - PLUS
- */
- {
- token = this.charToken(c, startLine, startCol);
- }
-
-
-
-
-
-
- }
-
- //make sure this token is wanted
- //TODO: check channel
- break;
- }
-
- if (!token && c === null){
- token = this.createToken(Tokens.EOF,null,startLine,startCol);
- }
-
- return token;
- },
-
- //-------------------------------------------------------------------------
- // Methods to create tokens
- //-------------------------------------------------------------------------
-
- /**
- * Produces a token based on available data and the current
- * reader position information. This method is called by other
- * private methods to create tokens and is never called directly.
- * @param {int} tt The token type.
- * @param {String} value The text value of the token.
- * @param {int} startLine The beginning line for the character.
- * @param {int} startCol The beginning column for the character.
- * @param {Object} options (Optional) Specifies a channel property
- * to indicate that a different channel should be scanned
- * and/or a hide property indicating that the token should
- * be hidden.
- * @return {Object} A token object.
- * @method createToken
- */
- createToken: function(tt, value, startLine, startCol, options){
- var reader = this._reader;
- options = options || {};
-
- return {
- value: value,
- type: tt,
- channel: options.channel,
- endChar: options.endChar,
- hide: options.hide || false,
- startLine: startLine,
- startCol: startCol,
- endLine: reader.getLine(),
- endCol: reader.getCol()
- };
- },
-
- //-------------------------------------------------------------------------
- // Methods to create specific tokens
- //-------------------------------------------------------------------------
-
- /**
- * Produces a token for any at-rule. If the at-rule is unknown, then
- * the token is for a single "@" character.
- * @param {String} first The first character for the token.
- * @param {int} startLine The beginning line for the character.
- * @param {int} startCol The beginning column for the character.
- * @return {Object} A token object.
- * @method atRuleToken
- */
- atRuleToken: function(first, startLine, startCol){
- var rule = first,
- reader = this._reader,
- tt = Tokens.CHAR,
- ident;
-
- /*
- * First, mark where we are. There are only four @ rules,
- * so anything else is really just an invalid token.
- * Basically, if this doesn't match one of the known @
- * rules, just return '@' as an unknown token and allow
- * parsing to continue after that point.
- */
- reader.mark();
-
- //try to find the at-keyword
- ident = this.readName();
- rule = first + ident;
- tt = Tokens.type(rule.toLowerCase());
-
- //if it's not valid, use the first character only and reset the reader
- if (tt === Tokens.CHAR || tt === Tokens.UNKNOWN){
- if (rule.length > 1){
- tt = Tokens.UNKNOWN_SYM;
- } else {
- tt = Tokens.CHAR;
- rule = first;
- reader.reset();
- }
- }
-
- return this.createToken(tt, rule, startLine, startCol);
- },
-
- /**
- * Produces a character token based on the given character
- * and location in the stream. If there's a special (non-standard)
- * token name, this is used; otherwise CHAR is used.
- * @param {String} c The character for the token.
- * @param {int} startLine The beginning line for the character.
- * @param {int} startCol The beginning column for the character.
- * @return {Object} A token object.
- * @method charToken
- */
- charToken: function(c, startLine, startCol){
- var tt = Tokens.type(c);
- var opts = {};
-
- if (tt === -1){
- tt = Tokens.CHAR;
- } else {
- opts.endChar = Tokens[tt].endChar;
- }
-
- return this.createToken(tt, c, startLine, startCol, opts);
- },
-
- /**
- * Produces a character token based on the given character
- * and location in the stream. If there's a special (non-standard)
- * token name, this is used; otherwise CHAR is used.
- * @param {String} first The first character for the token.
- * @param {int} startLine The beginning line for the character.
- * @param {int} startCol The beginning column for the character.
- * @return {Object} A token object.
- * @method commentToken
- */
- commentToken: function(first, startLine, startCol){
- var comment = this.readComment(first);
-
- return this.createToken(Tokens.COMMENT, comment, startLine, startCol);
- },
-
- /**
- * Produces a comparison token based on the given character
- * and location in the stream. The next character must be
- * read and is already known to be an equals sign.
- * @param {String} c The character for the token.
- * @param {int} startLine The beginning line for the character.
- * @param {int} startCol The beginning column for the character.
- * @return {Object} A token object.
- * @method comparisonToken
- */
- comparisonToken: function(c, startLine, startCol){
- var reader = this._reader,
- comparison = c + reader.read(),
- tt = Tokens.type(comparison) || Tokens.CHAR;
-
- return this.createToken(tt, comparison, startLine, startCol);
- },
-
- /**
- * Produces a hash token based on the specified information. The
- * first character provided is the pound sign (#) and then this
- * method reads a name afterward.
- * @param {String} first The first character (#) in the hash name.
- * @param {int} startLine The beginning line for the character.
- * @param {int} startCol The beginning column for the character.
- * @return {Object} A token object.
- * @method hashToken
- */
- hashToken: function(first, startLine, startCol){
- var name = this.readName(first);
-
- return this.createToken(Tokens.HASH, name, startLine, startCol);
- },
-
- /**
- * Produces a CDO or CHAR token based on the specified information. The
- * first character is provided and the rest is read by the function to determine
- * the correct token to create.
- * @param {String} first The first character in the token.
- * @param {int} startLine The beginning line for the character.
- * @param {int} startCol The beginning column for the character.
- * @return {Object} A token object.
- * @method htmlCommentStartToken
- */
- htmlCommentStartToken: function(first, startLine, startCol){
- var reader = this._reader,
- text = first;
-
- reader.mark();
- text += reader.readCount(3);
-
- if (text === "<!--"){
- return this.createToken(Tokens.CDO, text, startLine, startCol);
- } else {
- reader.reset();
- return this.charToken(first, startLine, startCol);
- }
- },
-
- /**
- * Produces a CDC or CHAR token based on the specified information. The
- * first character is provided and the rest is read by the function to determine
- * the correct token to create.
- * @param {String} first The first character in the token.
- * @param {int} startLine The beginning line for the character.
- * @param {int} startCol The beginning column for the character.
- * @return {Object} A token object.
- * @method htmlCommentEndToken
- */
- htmlCommentEndToken: function(first, startLine, startCol){
- var reader = this._reader,
- text = first;
-
- reader.mark();
- text += reader.readCount(2);
-
- if (text === "-->"){
- return this.createToken(Tokens.CDC, text, startLine, startCol);
- } else {
- reader.reset();
- return this.charToken(first, startLine, startCol);
- }
- },
-
- /**
- * Produces an IDENT or FUNCTION token based on the specified information. The
- * first character is provided and the rest is read by the function to determine
- * the correct token to create.
- * @param {String} first The first character in the identifier.
- * @param {int} startLine The beginning line for the character.
- * @param {int} startCol The beginning column for the character.
- * @return {Object} A token object.
- * @method identOrFunctionToken
- */
- identOrFunctionToken: function(first, startLine, startCol){
- var reader = this._reader,
- ident = this.readName(first),
- tt = Tokens.IDENT,
- uriFns = ["url(", "url-prefix(", "domain("];
-
- //if there's a left paren immediately after, it's a URI or function
- if (reader.peek() === "("){
- ident += reader.read();
- if (uriFns.indexOf(ident.toLowerCase()) > -1){
- tt = Tokens.URI;
- ident = this.readURI(ident);
-
- //didn't find a valid URL or there's no closing paren
- if (uriFns.indexOf(ident.toLowerCase()) > -1){
- tt = Tokens.FUNCTION;
- }
- } else {
- tt = Tokens.FUNCTION;
- }
- } else if (reader.peek() === ":"){ //might be an IE function
-
- //IE-specific functions always being with progid:
- if (ident.toLowerCase() === "progid"){
- ident += reader.readTo("(");
- tt = Tokens.IE_FUNCTION;
- }
- }
-
- return this.createToken(tt, ident, startLine, startCol);
- },
-
- /**
- * Produces an IMPORTANT_SYM or CHAR token based on the specified information. The
- * first character is provided and the rest is read by the function to determine
- * the correct token to create.
- * @param {String} first The first character in the token.
- * @param {int} startLine The beginning line for the character.
- * @param {int} startCol The beginning column for the character.
- * @return {Object} A token object.
- * @method importantToken
- */
- importantToken: function(first, startLine, startCol){
- var reader = this._reader,
- important = first,
- tt = Tokens.CHAR,
- temp,
- c;
-
- reader.mark();
- c = reader.read();
-
- while(c){
-
- //there can be a comment in here
- if (c === "/"){
-
- //if the next character isn't a star, then this isn't a valid !important token
- if (reader.peek() !== "*"){
- break;
- } else {
- temp = this.readComment(c);
- if (temp === ""){ //broken!
- break;
- }
- }
- } else if (isWhitespace(c)){
- important += c + this.readWhitespace();
- } else if (/i/i.test(c)){
- temp = reader.readCount(8);
- if (/mportant/i.test(temp)){
- important += c + temp;
- tt = Tokens.IMPORTANT_SYM;
-
- }
- break; //we're done
- } else {
- break;
- }
-
- c = reader.read();
- }
-
- if (tt === Tokens.CHAR){
- reader.reset();
- return this.charToken(first, startLine, startCol);
- } else {
- return this.createToken(tt, important, startLine, startCol);
- }
-
-
- },
-
- /**
- * Produces a NOT or CHAR token based on the specified information. The
- * first character is provided and the rest is read by the function to determine
- * the correct token to create.
- * @param {String} first The first character in the token.
- * @param {int} startLine The beginning line for the character.
- * @param {int} startCol The beginning column for the character.
- * @return {Object} A token object.
- * @method notToken
- */
- notToken: function(first, startLine, startCol){
- var reader = this._reader,
- text = first;
-
- reader.mark();
- text += reader.readCount(4);
-
- if (text.toLowerCase() === ":not("){
- return this.createToken(Tokens.NOT, text, startLine, startCol);
- } else {
- reader.reset();
- return this.charToken(first, startLine, startCol);
- }
- },
-
- /**
- * Produces a number token based on the given character
- * and location in the stream. This may return a token of
- * NUMBER, EMS, EXS, LENGTH, ANGLE, TIME, FREQ, DIMENSION,
- * or PERCENTAGE.
- * @param {String} first The first character for the token.
- * @param {int} startLine The beginning line for the character.
- * @param {int} startCol The beginning column for the character.
- * @return {Object} A token object.
- * @method numberToken
- */
- numberToken: function(first, startLine, startCol){
- var reader = this._reader,
- value = this.readNumber(first),
- ident,
- tt = Tokens.NUMBER,
- c = reader.peek();
-
- if (isIdentStart(c)){
- ident = this.readName(reader.read());
- value += ident;
-
- if (/^em$|^ex$|^px$|^gd$|^rem$|^vw$|^vh$|^vmax$|^vmin$|^ch$|^cm$|^mm$|^in$|^pt$|^pc$/i.test(ident)){
- tt = Tokens.LENGTH;
- } else if (/^deg|^rad$|^grad$/i.test(ident)){
- tt = Tokens.ANGLE;
- } else if (/^ms$|^s$/i.test(ident)){
- tt = Tokens.TIME;
- } else if (/^hz$|^khz$/i.test(ident)){
- tt = Tokens.FREQ;
- } else if (/^dpi$|^dpcm$/i.test(ident)){
- tt = Tokens.RESOLUTION;
- } else {
- tt = Tokens.DIMENSION;
- }
-
- } else if (c === "%"){
- value += reader.read();
- tt = Tokens.PERCENTAGE;
- }
-
- return this.createToken(tt, value, startLine, startCol);
- },
-
- /**
- * Produces a string token based on the given character
- * and location in the stream. Since strings may be indicated
- * by single or double quotes, a failure to match starting
- * and ending quotes results in an INVALID token being generated.
- * The first character in the string is passed in and then
- * the rest are read up to and including the final quotation mark.
- * @param {String} first The first character in the string.
- * @param {int} startLine The beginning line for the character.
- * @param {int} startCol The beginning column for the character.
- * @return {Object} A token object.
- * @method stringToken
- */
- stringToken: function(first, startLine, startCol){
- var delim = first,
- string = first,
- reader = this._reader,
- prev = first,
- tt = Tokens.STRING,
- c = reader.read();
-
- while(c){
- string += c;
-
- //if the delimiter is found with an escapement, we're done.
- if (c === delim && prev !== "\\"){
- break;
- }
-
- //if there's a newline without an escapement, it's an invalid string
- if (isNewLine(reader.peek()) && c !== "\\"){
- tt = Tokens.INVALID;
- break;
- }
-
- //save previous and get next
- prev = c;
- c = reader.read();
- }
-
- //if c is null, that means we're out of input and the string was never closed
- if (c === null){
- tt = Tokens.INVALID;
- }
-
- return this.createToken(tt, string, startLine, startCol);
- },
-
- unicodeRangeToken: function(first, startLine, startCol){
- var reader = this._reader,
- value = first,
- temp,
- tt = Tokens.CHAR;
-
- //then it should be a unicode range
- if (reader.peek() === "+"){
- reader.mark();
- value += reader.read();
- value += this.readUnicodeRangePart(true);
-
- //ensure there's an actual unicode range here
- if (value.length === 2){
- reader.reset();
- } else {
-
- tt = Tokens.UNICODE_RANGE;
-
- //if there's a ? in the first part, there can't be a second part
- if (value.indexOf("?") === -1){
-
- if (reader.peek() === "-"){
- reader.mark();
- temp = reader.read();
- temp += this.readUnicodeRangePart(false);
-
- //if there's not another value, back up and just take the first
- if (temp.length === 1){
- reader.reset();
- } else {
- value += temp;
- }
- }
-
- }
- }
- }
-
- return this.createToken(tt, value, startLine, startCol);
- },
-
- /**
- * Produces a S token based on the specified information. Since whitespace
- * may have multiple characters, this consumes all whitespace characters
- * into a single token.
- * @param {String} first The first character in the token.
- * @param {int} startLine The beginning line for the character.
- * @param {int} startCol The beginning column for the character.
- * @return {Object} A token object.
- * @method whitespaceToken
- */
- whitespaceToken: function(first, startLine, startCol){
- var value = first + this.readWhitespace();
- return this.createToken(Tokens.S, value, startLine, startCol);
- },
-
-
-
-
- //-------------------------------------------------------------------------
- // Methods to read values from the string stream
- //-------------------------------------------------------------------------
-
- readUnicodeRangePart: function(allowQuestionMark){
- var reader = this._reader,
- part = "",
- c = reader.peek();
-
- //first read hex digits
- while(isHexDigit(c) && part.length < 6){
- reader.read();
- part += c;
- c = reader.peek();
- }
-
- //then read question marks if allowed
- if (allowQuestionMark){
- while(c === "?" && part.length < 6){
- reader.read();
- part += c;
- c = reader.peek();
- }
- }
-
- //there can't be any other characters after this point
-
- return part;
- },
-
- readWhitespace: function(){
- var reader = this._reader,
- whitespace = "",
- c = reader.peek();
-
- while(isWhitespace(c)){
- reader.read();
- whitespace += c;
- c = reader.peek();
- }
-
- return whitespace;
- },
- readNumber: function(first){
- var reader = this._reader,
- number = first,
- hasDot = (first === "."),
- c = reader.peek();
-
-
- while(c){
- if (isDigit(c)){
- number += reader.read();
- } else if (c === "."){
- if (hasDot){
- break;
- } else {
- hasDot = true;
- number += reader.read();
- }
- } else {
- break;
- }
-
- c = reader.peek();
- }
-
- return number;
- },
- readString: function(){
- var reader = this._reader,
- delim = reader.read(),
- string = delim,
- prev = delim,
- c = reader.peek();
-
- while(c){
- c = reader.read();
- string += c;
-
- //if the delimiter is found with an escapement, we're done.
- if (c === delim && prev !== "\\"){
- break;
- }
-
- //if there's a newline without an escapement, it's an invalid string
- if (isNewLine(reader.peek()) && c !== "\\"){
- string = "";
- break;
- }
-
- //save previous and get next
- prev = c;
- c = reader.peek();
- }
-
- //if c is null, that means we're out of input and the string was never closed
- if (c === null){
- string = "";
- }
-
- return string;
- },
- readURI: function(first){
- var reader = this._reader,
- uri = first,
- inner = "",
- c = reader.peek();
-
- reader.mark();
-
- //skip whitespace before
- while(c && isWhitespace(c)){
- reader.read();
- c = reader.peek();
- }
-
- //it's a string
- if (c === "'" || c === "\""){
- inner = this.readString();
- } else {
- inner = this.readURL();
- }
-
- c = reader.peek();
-
- //skip whitespace after
- while(c && isWhitespace(c)){
- reader.read();
- c = reader.peek();
- }
-
- //if there was no inner value or the next character isn't closing paren, it's not a URI
- if (inner === "" || c !== ")"){
- uri = first;
- reader.reset();
- } else {
- uri += inner + reader.read();
- }
-
- return uri;
- },
- readURL: function(){
- var reader = this._reader,
- url = "",
- c = reader.peek();
-
- //TODO: Check for escape and nonascii
- while (/^[!#$%&\\*-~]$/.test(c)){
- url += reader.read();
- c = reader.peek();
- }
-
- return url;
-
- },
- readName: function(first){
- var reader = this._reader,
- ident = first || "",
- c = reader.peek();
-
- while(true){
- if (c === "\\"){
- ident += this.readEscape(reader.read());
- c = reader.peek();
- } else if(c && isNameChar(c)){
- ident += reader.read();
- c = reader.peek();
- } else {
- break;
- }
- }
-
- return ident;
- },
-
- readEscape: function(first){
- var reader = this._reader,
- cssEscape = first || "",
- i = 0,
- c = reader.peek();
-
- if (isHexDigit(c)){
- do {
- cssEscape += reader.read();
- c = reader.peek();
- } while(c && isHexDigit(c) && ++i < 6);
- }
-
- if (cssEscape.length === 3 && /\s/.test(c) ||
- cssEscape.length === 7 || cssEscape.length === 1){
- reader.read();
- } else {
- c = "";
- }
-
- return cssEscape + c;
- },
-
- readComment: function(first){
- var reader = this._reader,
- comment = first || "",
- c = reader.read();
-
- if (c === "*"){
- while(c){
- comment += c;
-
- //look for end of comment
- if (comment.length > 2 && c === "*" && reader.peek() === "/"){
- comment += reader.read();
- break;
- }
-
- c = reader.read();
- }
-
- return comment;
- } else {
- return "";
- }
-
- }
-});
-
-var Tokens = [
-
- /*
- * The following token names are defined in CSS3 Grammar: http://www.w3.org/TR/css3-syntax/#lexical
- */
-
- //HTML-style comments
- { name: "CDO"},
- { name: "CDC"},
-
- //ignorables
- { name: "S", whitespace: true/*, channel: "ws"*/},
- { name: "COMMENT", comment: true, hide: true, channel: "comment" },
-
- //attribute equality
- { name: "INCLUDES", text: "~="},
- { name: "DASHMATCH", text: "|="},
- { name: "PREFIXMATCH", text: "^="},
- { name: "SUFFIXMATCH", text: "$="},
- { name: "SUBSTRINGMATCH", text: "*="},
-
- //identifier types
- { name: "STRING"},
- { name: "IDENT"},
- { name: "HASH"},
-
- //at-keywords
- { name: "IMPORT_SYM", text: "@import"},
- { name: "PAGE_SYM", text: "@page"},
- { name: "MEDIA_SYM", text: "@media"},
- { name: "FONT_FACE_SYM", text: "@font-face"},
- { name: "CHARSET_SYM", text: "@charset"},
- { name: "NAMESPACE_SYM", text: "@namespace"},
- { name: "VIEWPORT_SYM", text: ["@viewport", "@-ms-viewport", "@-o-viewport"]},
- { name: "DOCUMENT_SYM", text: ["@document", "@-moz-document"]},
- { name: "UNKNOWN_SYM" },
- //{ name: "ATKEYWORD"},
-
- //CSS3 animations
- { name: "KEYFRAMES_SYM", text: [ "@keyframes", "@-webkit-keyframes", "@-moz-keyframes", "@-o-keyframes" ] },
-
- //important symbol
- { name: "IMPORTANT_SYM"},
-
- //measurements
- { name: "LENGTH"},
- { name: "ANGLE"},
- { name: "TIME"},
- { name: "FREQ"},
- { name: "DIMENSION"},
- { name: "PERCENTAGE"},
- { name: "NUMBER"},
-
- //functions
- { name: "URI"},
- { name: "FUNCTION"},
-
- //Unicode ranges
- { name: "UNICODE_RANGE"},
-
- /*
- * The following token names are defined in CSS3 Selectors: http://www.w3.org/TR/css3-selectors/#selector-syntax
- */
-
- //invalid string
- { name: "INVALID"},
-
- //combinators
- { name: "PLUS", text: "+" },
- { name: "GREATER", text: ">"},
- { name: "COMMA", text: ","},
- { name: "TILDE", text: "~"},
-
- //modifier
- { name: "NOT"},
-
- /*
- * Defined in CSS3 Paged Media
- */
- { name: "TOPLEFTCORNER_SYM", text: "@top-left-corner"},
- { name: "TOPLEFT_SYM", text: "@top-left"},
- { name: "TOPCENTER_SYM", text: "@top-center"},
- { name: "TOPRIGHT_SYM", text: "@top-right"},
- { name: "TOPRIGHTCORNER_SYM", text: "@top-right-corner"},
- { name: "BOTTOMLEFTCORNER_SYM", text: "@bottom-left-corner"},
- { name: "BOTTOMLEFT_SYM", text: "@bottom-left"},
- { name: "BOTTOMCENTER_SYM", text: "@bottom-center"},
- { name: "BOTTOMRIGHT_SYM", text: "@bottom-right"},
- { name: "BOTTOMRIGHTCORNER_SYM", text: "@bottom-right-corner"},
- { name: "LEFTTOP_SYM", text: "@left-top"},
- { name: "LEFTMIDDLE_SYM", text: "@left-middle"},
- { name: "LEFTBOTTOM_SYM", text: "@left-bottom"},
- { name: "RIGHTTOP_SYM", text: "@right-top"},
- { name: "RIGHTMIDDLE_SYM", text: "@right-middle"},
- { name: "RIGHTBOTTOM_SYM", text: "@right-bottom"},
-
- /*
- * The following token names are defined in CSS3 Media Queries: http://www.w3.org/TR/css3-mediaqueries/#syntax
- */
- /*{ name: "MEDIA_ONLY", state: "media"},
- { name: "MEDIA_NOT", state: "media"},
- { name: "MEDIA_AND", state: "media"},*/
- { name: "RESOLUTION", state: "media"},
-
- /*
- * The following token names are not defined in any CSS specification but are used by the lexer.
- */
-
- //not a real token, but useful for stupid IE filters
- { name: "IE_FUNCTION" },
-
- //part of CSS3 grammar but not the Flex code
- { name: "CHAR" },
-
- //TODO: Needed?
- //Not defined as tokens, but might as well be
- {
- name: "PIPE",
- text: "|"
- },
- {
- name: "SLASH",
- text: "/"
- },
- {
- name: "MINUS",
- text: "-"
- },
- {
- name: "STAR",
- text: "*"
- },
-
- {
- name: "LBRACE",
- endChar: "}",
- text: "{"
- },
- {
- name: "RBRACE",
- text: "}"
- },
- {
- name: "LBRACKET",
- endChar: "]",
- text: "["
- },
- {
- name: "RBRACKET",
- text: "]"
- },
- {
- name: "EQUALS",
- text: "="
- },
- {
- name: "COLON",
- text: ":"
- },
- {
- name: "SEMICOLON",
- text: ";"
- },
-
- {
- name: "LPAREN",
- endChar: ")",
- text: "("
- },
- {
- name: "RPAREN",
- text: ")"
- },
- {
- name: "DOT",
- text: "."
- }
-];
-
-(function(){
-
- var nameMap = [],
- typeMap = Object.create(null);
-
- Tokens.UNKNOWN = -1;
- Tokens.unshift({name:"EOF"});
- for (var i=0, len = Tokens.length; i < len; i++){
- nameMap.push(Tokens[i].name);
- Tokens[Tokens[i].name] = i;
- if (Tokens[i].text){
- if (Tokens[i].text instanceof Array){
- for (var j=0; j < Tokens[i].text.length; j++){
- typeMap[Tokens[i].text[j]] = i;
- }
- } else {
- typeMap[Tokens[i].text] = i;
- }
- }
- }
-
- Tokens.name = function(tt){
- return nameMap[tt];
- };
-
- Tokens.type = function(c){
- return typeMap[c] || -1;
- };
-
-})();
-
-
-
-//This file will likely change a lot! Very experimental!
-var Validation = {
-
- validate: function(property, value){
-
- //normalize name
- var name = property.toString().toLowerCase(),
- expression = new PropertyValueIterator(value),
- spec = Properties[name];
-
- if (!spec) {
- if (name.indexOf("-") !== 0){ //vendor prefixed are ok
- throw new ValidationError("Unknown property '" + property + "'.", property.line, property.col);
- }
- } else if (typeof spec !== "number"){
-
- //initialization
- if (typeof spec === "string"){
- if (spec.indexOf("||") > -1) {
- this.groupProperty(spec, expression);
- } else {
- this.singleProperty(spec, expression, 1);
- }
-
- } else if (spec.multi) {
- this.multiProperty(spec.multi, expression, spec.comma, spec.max || Infinity);
- } else if (typeof spec === "function") {
- spec(expression);
- }
-
- }
-
- },
-
- singleProperty: function(types, expression, max, partial) {
-
- var result = false,
- value = expression.value,
- count = 0,
- part;
-
- while (expression.hasNext() && count < max) {
- result = ValidationTypes.isAny(expression, types);
- if (!result) {
- break;
- }
- count++;
- }
-
- if (!result) {
- if (expression.hasNext() && !expression.isFirst()) {
- part = expression.peek();
- throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
- } else {
- throw new ValidationError("Expected (" + types + ") but found '" + value + "'.", value.line, value.col);
- }
- } else if (expression.hasNext()) {
- part = expression.next();
- throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
- }
-
- },
-
- multiProperty: function (types, expression, comma, max) {
-
- var result = false,
- value = expression.value,
- count = 0,
- part;
-
- while(expression.hasNext() && !result && count < max) {
- if (ValidationTypes.isAny(expression, types)) {
- count++;
- if (!expression.hasNext()) {
- result = true;
-
- } else if (comma) {
- if (String(expression.peek()) === ",") {
- part = expression.next();
- } else {
- break;
- }
- }
- } else {
- break;
-
- }
- }
-
- if (!result) {
- if (expression.hasNext() && !expression.isFirst()) {
- part = expression.peek();
- throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
- } else {
- part = expression.previous();
- if (comma && String(part) === ",") {
- throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
- } else {
- throw new ValidationError("Expected (" + types + ") but found '" + value + "'.", value.line, value.col);
- }
- }
-
- } else if (expression.hasNext()) {
- part = expression.next();
- throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
- }
-
- },
-
- groupProperty: function (types, expression, comma) {
-
- var result = false,
- value = expression.value,
- typeCount = types.split("||").length,
- groups = { count: 0 },
- partial = false,
- name,
- part;
-
- while(expression.hasNext() && !result) {
- name = ValidationTypes.isAnyOfGroup(expression, types);
- if (name) {
-
- //no dupes
- if (groups[name]) {
- break;
- } else {
- groups[name] = 1;
- groups.count++;
- partial = true;
-
- if (groups.count === typeCount || !expression.hasNext()) {
- result = true;
- }
- }
- } else {
- break;
- }
- }
-
- if (!result) {
- if (partial && expression.hasNext()) {
- part = expression.peek();
- throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
- } else {
- throw new ValidationError("Expected (" + types + ") but found '" + value + "'.", value.line, value.col);
- }
- } else if (expression.hasNext()) {
- part = expression.next();
- throw new ValidationError("Expected end of value but found '" + part + "'.", part.line, part.col);
- }
- }
-
-
-
-};
-/**
- * Type to use when a validation error occurs.
- * @class ValidationError
- * @namespace parserlib.util
- * @constructor
- * @param {String} message The error message.
- * @param {int} line The line at which the error occurred.
- * @param {int} col The column at which the error occurred.
- */
-function ValidationError(message, line, col){
-
- /**
- * The column at which the error occurred.
- * @type int
- * @property col
- */
- this.col = col;
-
- /**
- * The line at which the error occurred.
- * @type int
- * @property line
- */
- this.line = line;
-
- /**
- * The text representation of the unit.
- * @type String
- * @property text
- */
- this.message = message;
-
-}
-
-//inherit from Error
-ValidationError.prototype = new Error();
-//This file will likely change a lot! Very experimental!
-var ValidationTypes = {
-
- isLiteral: function (part, literals) {
- var text = part.text.toString().toLowerCase(),
- args = literals.split(" | "),
- i, len, found = false;
-
- for (i=0,len=args.length; i < len && !found; i++){
- if (text === args[i].toLowerCase()){
- found = true;
- }
- }
-
- return found;
- },
-
- isSimple: function(type) {
- return !!this.simple[type];
- },
-
- isComplex: function(type) {
- return !!this.complex[type];
- },
-
- /**
- * Determines if the next part(s) of the given expression
- * are any of the given types.
- */
- isAny: function (expression, types) {
- var args = types.split(" | "),
- i, len, found = false;
-
- for (i=0,len=args.length; i < len && !found && expression.hasNext(); i++){
- found = this.isType(expression, args[i]);
- }
-
- return found;
- },
-
- /**
- * Determines if the next part(s) of the given expression
- * are one of a group.
- */
- isAnyOfGroup: function(expression, types) {
- var args = types.split(" || "),
- i, len, found = false;
-
- for (i=0,len=args.length; i < len && !found; i++){
- found = this.isType(expression, args[i]);
- }
-
- return found ? args[i-1] : false;
- },
-
- /**
- * Determines if the next part(s) of the given expression
- * are of a given type.
- */
- isType: function (expression, type) {
- var part = expression.peek(),
- result = false;
-
- if (type.charAt(0) !== "<") {
- result = this.isLiteral(part, type);
- if (result) {
- expression.next();
- }
- } else if (this.simple[type]) {
- result = this.simple[type](part);
- if (result) {
- expression.next();
- }
- } else {
- result = this.complex[type](expression);
- }
-
- return result;
- },
-
-
-
- simple: {
- __proto__: null,
-
- "<absolute-size>": function(part){
- return ValidationTypes.isLiteral(part, "xx-small | x-small | small | medium | large | x-large | xx-large");
- },
-
- "<attachment>": function(part){
- return ValidationTypes.isLiteral(part, "scroll | fixed | local");
- },
-
- "<attr>": function(part){
- return part.type === "function" && part.name === "attr";
- },
-
- "<bg-image>": function(part){
- return this["<image>"](part) || this["<gradient>"](part) || String(part) === "none";
- },
-
- "<gradient>": function(part) {
- return part.type === "function" && /^(?:\-(?:ms|moz|o|webkit)\-)?(?:repeating\-)?(?:radial\-|linear\-)?gradient/i.test(part);
- },
-
- "<box>": function(part){
- return ValidationTypes.isLiteral(part, "padding-box | border-box | content-box");
- },
-
- "<content>": function(part){
- return part.type === "function" && part.name === "content";
- },
-
- "<relative-size>": function(part){
- return ValidationTypes.isLiteral(part, "smaller | larger");
- },
-
- //any identifier
- "<ident>": function(part){
- return part.type === "identifier";
- },
-
- "<length>": function(part){
- if (part.type === "function" && /^(?:\-(?:ms|moz|o|webkit)\-)?calc/i.test(part)){
- return true;
- }else{
- return part.type === "length" || part.type === "number" || part.type === "integer" || String(part) === "0";
- }
- },
-
- "<color>": function(part){
- return part.type === "color" || String(part) === "transparent" || String(part) === "currentColor";
- },
-
- "<number>": function(part){
- return part.type === "number" || this["<integer>"](part);
- },
-
- "<integer>": function(part){
- return part.type === "integer";
- },
-
- "<line>": function(part){
- return part.type === "integer";
- },
-
- "<angle>": function(part){
- return part.type === "angle";
- },
-
- "<uri>": function(part){
- return part.type === "uri";
- },
-
- "<image>": function(part){
- return this["<uri>"](part);
- },
-
- "<percentage>": function(part){
- return part.type === "percentage" || String(part) === "0";
- },
-
- "<border-width>": function(part){
- return this["<length>"](part) || ValidationTypes.isLiteral(part, "thin | medium | thick");
- },
-
- "<border-style>": function(part){
- return ValidationTypes.isLiteral(part, "none | hidden | dotted | dashed | solid | double | groove | ridge | inset | outset");
- },
-
- "<content-sizing>": function(part){ // http://www.w3.org/TR/css3-sizing/#width-height-keywords
- return ValidationTypes.isLiteral(part, "fill-available | -moz-available | -webkit-fill-available | max-content | -moz-max-content | -webkit-max-content | min-content | -moz-min-content | -webkit-min-content | fit-content | -moz-fit-content | -webkit-fit-content");
- },
-
- "<margin-width>": function(part){
- return this["<length>"](part) || this["<percentage>"](part) || ValidationTypes.isLiteral(part, "auto");
- },
-
- "<padding-width>": function(part){
- return this["<length>"](part) || this["<percentage>"](part);
- },
-
- "<shape>": function(part){
- return part.type === "function" && (part.name === "rect" || part.name === "inset-rect");
- },
-
- "<time>": function(part) {
- return part.type === "time";
- },
-
- "<flex-grow>": function(part){
- return this["<number>"](part);
- },
-
- "<flex-shrink>": function(part){
- return this["<number>"](part);
- },
-
- "<width>": function(part){
- return this["<margin-width>"](part);
- },
-
- "<flex-basis>": function(part){
- return this["<width>"](part);
- },
-
- "<flex-direction>": function(part){
- return ValidationTypes.isLiteral(part, "row | row-reverse | column | column-reverse");
- },
-
- "<flex-wrap>": function(part){
- return ValidationTypes.isLiteral(part, "nowrap | wrap | wrap-reverse");
- },
-
- "<feature-tag-value>": function(part){
- return (part.type === "function" && /^[A-Z0-9]{4}$/i.test(part));
- }
- },
-
- complex: {
- __proto__: null,
-
- "<bg-position>": function(expression){
- var result = false,
- numeric = "<percentage> | <length>",
- xDir = "left | right",
- yDir = "top | bottom",
- count = 0;
-
- while (expression.peek(count) && expression.peek(count).text !== ",") {
- count++;
- }
-
-/*
-<position> = [
- [ left | center | right | top | bottom | <percentage> | <length> ]
-|
- [ left | center | right | <percentage> | <length> ]
- [ top | center | bottom | <percentage> | <length> ]
-|
- [ center | [ left | right ] [ <percentage> | <length> ]? ] &&
- [ center | [ top | bottom ] [ <percentage> | <length> ]? ]
-]
-*/
-
- if (count < 3) {
- if (ValidationTypes.isAny(expression, xDir + " | center | " + numeric)) {
- result = true;
- ValidationTypes.isAny(expression, yDir + " | center | " + numeric);
- } else if (ValidationTypes.isAny(expression, yDir)) {
- result = true;
- ValidationTypes.isAny(expression, xDir + " | center");
- }
- } else {
- if (ValidationTypes.isAny(expression, xDir)) {
- if (ValidationTypes.isAny(expression, yDir)) {
- result = true;
- ValidationTypes.isAny(expression, numeric);
- } else if (ValidationTypes.isAny(expression, numeric)) {
- if (ValidationTypes.isAny(expression, yDir)) {
- result = true;
- ValidationTypes.isAny(expression, numeric);
- } else if (ValidationTypes.isAny(expression, "center")) {
- result = true;
- }
- }
- } else if (ValidationTypes.isAny(expression, yDir)) {
- if (ValidationTypes.isAny(expression, xDir)) {
- result = true;
- ValidationTypes.isAny(expression, numeric);
- } else if (ValidationTypes.isAny(expression, numeric)) {
- if (ValidationTypes.isAny(expression, xDir)) {
- result = true;
- ValidationTypes.isAny(expression, numeric);
- } else if (ValidationTypes.isAny(expression, "center")) {
- result = true;
- }
- }
- } else if (ValidationTypes.isAny(expression, "center")) {
- if (ValidationTypes.isAny(expression, xDir + " | " + yDir)) {
- result = true;
- ValidationTypes.isAny(expression, numeric);
- }
- }
- }
-
- return result;
- },
-
- "<bg-size>": function(expression){
- //<bg-size> = [ <length> | <percentage> | auto ]{1,2} | cover | contain
- var result = false,
- numeric = "<percentage> | <length> | auto";
-
- if (ValidationTypes.isAny(expression, "cover | contain")) {
- result = true;
- } else if (ValidationTypes.isAny(expression, numeric)) {
- result = true;
- ValidationTypes.isAny(expression, numeric);
- }
-
- return result;
- },
-
- "<repeat-style>": function(expression){
- //repeat-x | repeat-y | [repeat | space | round | no-repeat]{1,2}
- var result = false,
- values = "repeat | space | round | no-repeat",
- part;
-
- if (expression.hasNext()){
- part = expression.next();
-
- if (ValidationTypes.isLiteral(part, "repeat-x | repeat-y")) {
- result = true;
- } else if (ValidationTypes.isLiteral(part, values)) {
- result = true;
-
- if (expression.hasNext() && ValidationTypes.isLiteral(expression.peek(), values)) {
- expression.next();
- }
- }
- }
-
- return result;
-
- },
-
- "<shadow>": function(expression) {
- //inset? && [ <length>{2,4} && <color>? ]
- var result = false,
- count = 0,
- inset = false,
- color = false;
-
- if (expression.hasNext()) {
-
- if (ValidationTypes.isAny(expression, "inset")){
- inset = true;
- }
-
- if (ValidationTypes.isAny(expression, "<color>")) {
- color = true;
- }
-
- while (ValidationTypes.isAny(expression, "<length>") && count < 4) {
- count++;
- }
-
-
- if (expression.hasNext()) {
- if (!color) {
- ValidationTypes.isAny(expression, "<color>");
- }
-
- if (!inset) {
- ValidationTypes.isAny(expression, "inset");
- }
-
- }
-
- result = (count >= 2 && count <= 4);
-
- }
-
- return result;
- },
-
- "<x-one-radius>": function(expression) {
- //[ <length> | <percentage> ] [ <length> | <percentage> ]?
- var result = false,
- simple = "<length> | <percentage> | inherit";
-
- if (ValidationTypes.isAny(expression, simple)){
- result = true;
- ValidationTypes.isAny(expression, simple);
- }
-
- return result;
- },
-
- "<flex>": function(expression) {
- // http://www.w3.org/TR/2014/WD-css-flexbox-1-20140325/#flex-property
- // none | [ <flex-grow> <flex-shrink>? || <flex-basis> ]
- // Valid syntaxes, according to https://developer.mozilla.org/en-US/docs/Web/CSS/flex#Syntax
- // * none
- // * <flex-grow>
- // * <flex-basis>
- // * <flex-grow> <flex-basis>
- // * <flex-grow> <flex-shrink>
- // * <flex-grow> <flex-shrink> <flex-basis>
- // * inherit
- var part,
- result = false;
- if (ValidationTypes.isAny(expression, "none | inherit")) {
- result = true;
- } else {
- if (ValidationTypes.isType(expression, "<flex-grow>")) {
- if (expression.peek()) {
- if (ValidationTypes.isType(expression, "<flex-shrink>")) {
- if (expression.peek()) {
- result = ValidationTypes.isType(expression, "<flex-basis>");
- } else {
- result = true;
- }
- } else if (ValidationTypes.isType(expression, "<flex-basis>")) {
- result = expression.peek() === null;
- }
- } else {
- result = true;
- }
- } else if (ValidationTypes.isType(expression, "<flex-basis>")) {
- result = true;
- }
- }
-
- if (!result) {
- // Generate a more verbose error than "Expected <flex>..."
- part = expression.peek();
- throw new ValidationError("Expected (none | [ <flex-grow> <flex-shrink>? || <flex-basis> ]) but found '" + expression.value.text + "'.", part.line, part.col);
- }
-
- return result;
- }
- }
-};
-
-parserlib.css = {
-__proto__ :null,
-Colors :Colors,
-Combinator :Combinator,
-Parser :Parser,
-PropertyName :PropertyName,
-PropertyValue :PropertyValue,
-PropertyValuePart :PropertyValuePart,
-MediaFeature :MediaFeature,
-MediaQuery :MediaQuery,
-Selector :Selector,
-SelectorPart :SelectorPart,
-SelectorSubPart :SelectorSubPart,
-Specificity :Specificity,
-TokenStream :TokenStream,
-Tokens :Tokens,
-ValidationError :ValidationError
-};
-})();
-
-(function(){
-/* jshint forin:false */
-for(var prop in parserlib){
-exports[prop] = parserlib[prop];
-}
-})();
--- a/cmd/gojafs/domino/domino-lib/defineElement.js
+++ /dev/null
@@ -1,70 +1,0 @@
-"use strict";
-
-var attributes = require('./attributes');
-var sloppy = require('./sloppy');
-var isApiWritable = require("./config").isApiWritable;
-
-module.exports = function(spec, defaultConstructor, tagList, tagNameToImpl) {
- var c = spec.ctor;
- if (c) {
- var props = spec.props || {};
-
- if (spec.attributes) {
- for (var n in spec.attributes) {
- var attr = spec.attributes[n];
- if (typeof attr !== 'object' || Array.isArray(attr)) attr = {type: attr};
- if (!attr.name) attr.name = n.toLowerCase();
- props[n] = attributes.property(attr);
- }
- }
-
- props.constructor = { value : c, writable: isApiWritable };
- c.prototype = Object.create((spec.superclass || defaultConstructor).prototype, props);
- if (spec.events) {
- addEventHandlers(c, spec.events);
- }
- tagList[c.name] = c;
- }
- else {
- c = defaultConstructor;
- }
-
- (spec.tags || spec.tag && [spec.tag] || []).forEach(function(tag) {
- tagNameToImpl[tag] = c;
- });
-
- return c;
-};
-
-function EventHandlerBuilder(body, document, form, element) {
- this.body = body;
- this.document = document;
- this.form = form;
- this.element = element;
-}
-
-EventHandlerBuilder.prototype.build = sloppy.EventHandlerBuilder_build;
-
-function EventHandlerChangeHandler(elt, name, oldval, newval) {
- var doc = elt.ownerDocument || Object.create(null);
- var form = elt.form || Object.create(null);
- elt[name] = new EventHandlerBuilder(newval, doc, form, elt).build();
-}
-
-function addEventHandlers(c, eventHandlerTypes) {
- var p = c.prototype;
- eventHandlerTypes.forEach(function(type) {
- // Define the event handler registration IDL attribute for this type
- Object.defineProperty(p, "on" + type, {
- get: function() {
- return this._getEventHandler(type);
- },
- set: function(v) {
- this._setEventHandler(type, v);
- },
- });
-
- // Define special behavior for the content attribute as well
- attributes.registerChangeHandler(c, "on" + type, EventHandlerChangeHandler);
- });
-}
--- a/cmd/gojafs/domino/domino-lib/events.js
+++ /dev/null
@@ -1,7 +1,0 @@
-"use strict";
-module.exports = {
- Event: require('./Event'),
- UIEvent: require('./UIEvent'),
- MouseEvent: require('./MouseEvent'),
- CustomEvent: require('./CustomEvent')
-};
--- a/cmd/gojafs/domino/domino-lib/htmlelts.js
+++ /dev/null
@@ -1,1428 +1,0 @@
-"use strict";
-var Node = require('./Node');
-var Element = require('./Element');
-var CSSStyleDeclaration = require('./CSSStyleDeclaration');
-var utils = require('./utils');
-var URLUtils = require('./URLUtils');
-var defineElement = require('./defineElement');
-
-var htmlElements = exports.elements = {};
-var htmlNameToImpl = Object.create(null);
-
-exports.createElement = function(doc, localName, prefix) {
- var impl = htmlNameToImpl[localName] || HTMLUnknownElement;
- return new impl(doc, localName, prefix);
-};
-
-function define(spec) {
- return defineElement(spec, HTMLElement, htmlElements, htmlNameToImpl);
-}
-
-function URL(attr) {
- return {
- get: function() {
- var v = this._getattr(attr);
- if (v === null) { return ''; }
- var url = this.doc._resolve(v);
- return (url === null) ? v : url;
- },
- set: function(value) {
- this._setattr(attr, value);
- }
- };
-}
-
-function CORS(attr) {
- return {
- get: function() {
- var v = this._getattr(attr);
- if (v === null) { return null; }
- if (v.toLowerCase() === 'use-credentials') { return 'use-credentials'; }
- return 'anonymous';
- },
- set: function(value) {
- if (value===null || value===undefined) {
- this.removeAttribute(attr);
- } else {
- this._setattr(attr, value);
- }
- }
- };
-}
-
-var REFERRER = {
- type: ["", "no-referrer", "no-referrer-when-downgrade", "same-origin", "origin", "strict-origin", "origin-when-cross-origin", "strict-origin-when-cross-origin", "unsafe-url"],
- missing: '',
-};
-
-
-// XXX: the default value for tabIndex should be 0 if the element is
-// focusable and -1 if it is not. But the full definition of focusable
-// is actually hard to compute, so for now, I'll follow Firefox and
-// just base the default value on the type of the element.
-var focusableElements = {
- "A":true, "LINK":true, "BUTTON":true, "INPUT":true,
- "SELECT":true, "TEXTAREA":true, "COMMAND":true
-};
-
-var HTMLFormElement = function(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- this._form = null; // Prevent later deoptimization
-};
-
-var HTMLElement = exports.HTMLElement = define({
- superclass: Element,
- ctor: function HTMLElement(doc, localName, prefix) {
- Element.call(this, doc, localName, utils.NAMESPACE.HTML, prefix);
- },
- props: {
- innerHTML: {
- get: function() {
- return this.serialize();
- },
- set: function(v) {
- var parser = this.ownerDocument.implementation.mozHTMLParser(
- this.ownerDocument._address,
- this);
- parser.parse(v===null ? '' : String(v), true);
-
- // Remove any existing children of this node
- var target = (this instanceof htmlNameToImpl.template) ?
- this.content : this;
- while(target.hasChildNodes())
- target.removeChild(target.firstChild);
-
- // Now copy newly parsed children to this node
- target.appendChild(parser._asDocumentFragment());
- }
- },
- style: { get: function() {
- if (!this._style)
- this._style = new CSSStyleDeclaration(this);
- return this._style;
- }, set: function(v) {
- if (v===null||v===undefined) { v = ''; }
- this._setattr('style', String(v));
- }},
-
- // These can't really be implemented server-side in a reasonable way.
- blur: { value: function() {}},
- focus: { value: function() {}},
- forceSpellCheck: { value: function() {}},
-
- click: { value: function() {
- if (this._click_in_progress) return;
- this._click_in_progress = true;
- try {
- if (this._pre_click_activation_steps)
- this._pre_click_activation_steps();
-
- var event = this.ownerDocument.createEvent("MouseEvent");
- event.initMouseEvent("click", true, true,
- this.ownerDocument.defaultView, 1,
- 0, 0, 0, 0,
- // These 4 should be initialized with
- // the actually current keyboard state
- // somehow...
- false, false, false, false,
- 0, null
- );
-
- // Dispatch this as an untrusted event since it is synthetic
- var success = this.dispatchEvent(event);
-
- if (success) {
- if (this._post_click_activation_steps)
- this._post_click_activation_steps(event);
- }
- else {
- if (this._cancelled_activation_steps)
- this._cancelled_activation_steps();
- }
- }
- finally {
- this._click_in_progress = false;
- }
- }},
- submit: { value: function(a, b, c) {
- ___opossumSubmit.bind(this)(a, b, c) }
- },
- },
- attributes: {
- title: String,
- lang: String,
- dir: {type: ["ltr", "rtl", "auto"], missing: ''},
- accessKey: String,
- hidden: Boolean,
- tabIndex: {type: "long", default: function() {
- if (this.tagName in focusableElements ||
- this.contentEditable)
- return 0;
- else
- return -1;
- }}
- },
- events: [
- "abort", "canplay", "canplaythrough", "change", "click", "contextmenu",
- "cuechange", "dblclick", "drag", "dragend", "dragenter", "dragleave",
- "dragover", "dragstart", "drop", "durationchange", "emptied", "ended",
- "input", "invalid", "keydown", "keypress", "keyup", "loadeddata",
- "loadedmetadata", "loadstart", "mousedown", "mousemove", "mouseout",
- "mouseover", "mouseup", "mousewheel", "pause", "play", "playing",
- "progress", "ratechange", "readystatechange", "reset", "seeked",
- "seeking", "select", "show", "stalled", "submit", "suspend",
- "timeupdate", "volumechange", "waiting",
-
- // These last 5 event types will be overriden by HTMLBodyElement
- "blur", "error", "focus", "load", "scroll"
- ]
-});
-
-
-// XXX: reflect contextmenu as contextMenu, with element type
-
-
-// style: the spec doesn't call this a reflected attribute.
-// may want to handle it manually.
-
-// contentEditable: enumerated, not clear if it is actually
-// reflected or requires custom getter/setter. Not listed as
-// "limited to known values". Raises syntax_err on bad setting,
-// so I think this is custom.
-
-// contextmenu: content is element id, idl type is an element
-// draggable: boolean, but not a reflected attribute
-// dropzone: reflected SettableTokenList, experimental, so don't
-// implement it right away.
-
-// data-* attributes: need special handling in setAttribute?
-// Or maybe that isn't necessary. Can I just scan the attribute list
-// when building the dataset? Liveness and caching issues?
-
-// microdata attributes: many are simple reflected attributes, but
-// I'm not going to implement this now.
-
-
-var HTMLUnknownElement = define({
- ctor: function HTMLUnknownElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- }
-});
-
-
-var formAssociatedProps = {
- // See http://www.w3.org/TR/html5/association-of-controls-and-forms.html#form-owner
- form: { get: function() {
- return this._form;
- }}
-};
-
-define({
- tag: 'a',
- ctor: function HTMLAnchorElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- props: {
- _post_click_activation_steps: { value: function(e) {
- if (this.href) {
- // Follow the link
- // XXX: this is just a quick hack
- // XXX: the HTML spec probably requires more than this
- this.ownerDocument.defaultView.location = this.href;
- }
- }},
- },
- attributes: {
- href: URL,
- ping: String,
- download: String,
- target: String,
- rel: String,
- media: String,
- hreflang: String,
- type: String,
- referrerPolicy: REFERRER,
- // Obsolete
- coords: String,
- charset: String,
- name: String,
- rev: String,
- shape: String,
- }
-});
-// Latest WhatWG spec says these methods come via HTMLHyperlinkElementUtils
-URLUtils._inherit(htmlNameToImpl.a.prototype);
-
-define({
- tag: 'area',
- ctor: function HTMLAreaElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- alt: String,
- target: String,
- download: String,
- rel: String,
- media: String,
- href: URL,
- hreflang: String,
- type: String,
- shape: String,
- coords: String,
- ping: String,
- // XXX: also reflect relList
- referrerPolicy: REFERRER,
- // Obsolete
- noHref: Boolean,
- }
-});
-// Latest WhatWG spec says these methods come via HTMLHyperlinkElementUtils
-URLUtils._inherit(htmlNameToImpl.area.prototype);
-
-define({
- tag: 'br',
- ctor: function HTMLBRElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- // Obsolete
- clear: String
- },
-});
-
-define({
- tag: 'base',
- ctor: function HTMLBaseElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- "target": String
- }
-});
-
-
-define({
- tag: 'body',
- ctor: function HTMLBodyElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- // Certain event handler attributes on a <body> tag actually set
- // handlers for the window rather than just that element. Define
- // getters and setters for those here. Note that some of these override
- // properties on HTMLElement.prototype.
- // XXX: If I add support for <frameset>, these have to go there, too
- // XXX
- // When the Window object is implemented, these attribute will have
- // to work with the same-named attributes on the Window.
- events: [
- "afterprint", "beforeprint", "beforeunload", "blur", "error",
- "focus","hashchange", "load", "message", "offline", "online",
- "pagehide", "pageshow","popstate","resize","scroll","storage","unload",
- ],
- attributes: {
- // Obsolete
- text: { type: String, treatNullAsEmptyString: true },
- link: { type: String, treatNullAsEmptyString: true },
- vLink: { type: String, treatNullAsEmptyString: true },
- aLink: { type: String, treatNullAsEmptyString: true },
- bgColor: { type: String, treatNullAsEmptyString: true },
- background: String,
- }
-});
-
-define({
- tag: 'button',
- ctor: function HTMLButtonElement(doc, localName, prefix) {
- HTMLFormElement.call(this, doc, localName, prefix);
- },
- props: formAssociatedProps,
- attributes: {
- name: String,
- value: String,
- disabled: Boolean,
- autofocus: Boolean,
- type: { type:["submit", "reset", "button", "menu"], missing: 'submit' },
- formTarget: String,
- formNoValidate: Boolean,
- formMethod: { type: ["get", "post", "dialog"], invalid: 'get', missing: '' },
- formEnctype: { type: ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"], invalid: "application/x-www-form-urlencoded", missing: '' },
- }
-});
-
-define({
- tag: 'dl',
- ctor: function HTMLDListElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- // Obsolete
- compact: Boolean,
- }
-});
-
-define({
- tag: 'data',
- ctor: function HTMLDataElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- value: String,
- }
-});
-
-define({
- tag: 'datalist',
- ctor: function HTMLDataListElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- }
-});
-
-define({
- tag: 'details',
- ctor: function HTMLDetailsElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- "open": Boolean
- }
-});
-
-define({
- tag: 'div',
- ctor: function HTMLDivElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- // Obsolete
- align: String
- }
-});
-
-define({
- tag: 'embed',
- ctor: function HTMLEmbedElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- src: URL,
- type: String,
- width: String,
- height: String,
- // Obsolete
- align: String,
- name: String,
- }
-});
-
-define({
- tag: 'fieldset',
- ctor: function HTMLFieldSetElement(doc, localName, prefix) {
- HTMLFormElement.call(this, doc, localName, prefix);
- },
- props: formAssociatedProps,
- attributes: {
- disabled: Boolean,
- name: String
- }
-});
-
-define({
- tag: 'form',
- ctor: function HTMLFormElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- action: String,
- autocomplete: {type:['on', 'off'], missing: 'on'},
- name: String,
- acceptCharset: {name: "accept-charset"},
- target: String,
- noValidate: Boolean,
- method: { type: ["get", "post", "dialog"], invalid: 'get', missing: 'get' },
- // Both enctype and encoding reflect the enctype content attribute
- enctype: { type: ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"], invalid: "application/x-www-form-urlencoded", missing: "application/x-www-form-urlencoded" },
- encoding: {name: 'enctype', type: ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"], invalid: "application/x-www-form-urlencoded", missing: "application/x-www-form-urlencoded" },
- }
-});
-
-define({
- tag: 'hr',
- ctor: function HTMLHRElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- // Obsolete
- align: String,
- color: String,
- noShade: Boolean,
- size: String,
- width: String,
- },
-});
-
-define({
- tag: 'head',
- ctor: function HTMLHeadElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- }
-});
-
-define({
- tags: ['h1','h2','h3','h4','h5','h6'],
- ctor: function HTMLHeadingElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- // Obsolete
- align: String,
- },
-});
-
-define({
- tag: 'html',
- ctor: function HTMLHtmlElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- // Obsolete
- version: String
- }
-});
-
-define({
- tag: 'iframe',
- ctor: function HTMLIFrameElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- var Window = require('./Window'); // Avoid circular dependencies.
- this._contentWindow = new Window();
- },
- props: {
- contentWindow: { get: function() {
- return this._contentWindow;
- } },
- contentDocument: { get: function() {
- return this.contentWindow.document;
- } },
- },
- attributes: {
- src: URL,
- srcdoc: String,
- name: String,
- width: String,
- height: String,
- // XXX: sandbox is a reflected settable token list
- seamless: Boolean,
- allowFullscreen: Boolean,
- allowUserMedia: Boolean,
- allowPaymentRequest: Boolean,
- referrerPolicy: REFERRER,
- // Obsolete
- align: String,
- scrolling: String,
- frameBorder: String,
- longDesc: URL,
- marginHeight: { type: String, treatNullAsEmptyString: true },
- marginWidth: { type: String, treatNullAsEmptyString: true },
- }
-});
-
-define({
- tag: 'img',
- ctor: function HTMLImageElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- alt: String,
- src: URL,
- srcset: String,
- crossOrigin: CORS,
- useMap: String,
- isMap: Boolean,
- height: { type: "unsigned long", default: 0 },
- width: { type: "unsigned long", default: 0 },
- referrerPolicy: REFERRER,
- // Obsolete:
- name: String,
- lowsrc: URL,
- align: String,
- hspace: { type: "unsigned long", default: 0 },
- vspace: { type: "unsigned long", default: 0 },
- longDesc: URL,
- border: { type: String, treatNullAsEmptyString: true },
- }
-});
-
-define({
- tag: 'input',
- ctor: function HTMLInputElement(doc, localName, prefix) {
- HTMLFormElement.call(this, doc, localName, prefix);
- },
- props: {
- form: formAssociatedProps.form,
- _post_click_activation_steps: { value: function(e) {
- if (this.type === 'checkbox') {
- this.checked = !this.checked;
- }
- else if (this.type === 'radio') {
- var group = this.form.getElementsByName(this.name);
- for (var i=group.length-1; i >= 0; i--) {
- var el = group[i];
- el.checked = (el === this);
- }
- }
- }},
- },
- attributes: {
- name: String,
- disabled: Boolean,
- autofocus: Boolean,
- accept: String,
- alt: String,
- max: String,
- min: String,
- pattern: String,
- placeholder: String,
- step: String,
- dirName: String,
- defaultValue: {name: 'value'},
- multiple: Boolean,
- required: Boolean,
- readOnly: Boolean,
- checked: Boolean,
- value: String,
- src: URL,
- defaultChecked: {name: 'checked', type: Boolean},
- size: {type: 'unsigned long', default: 20, min: 1, setmin: 1},
- width: {type: 'unsigned long', min: 0, setmin: 0, default: 0},
- height: {type: 'unsigned long', min: 0, setmin: 0, default: 0},
- minLength: {type: 'unsigned long', min: 0, setmin: 0, default: -1},
- maxLength: {type: 'unsigned long', min: 0, setmin: 0, default: -1},
- autocomplete: String, // It's complicated
- type: { type:
- ["text", "hidden", "search", "tel", "url", "email", "password",
- "datetime", "date", "month", "week", "time", "datetime-local",
- "number", "range", "color", "checkbox", "radio", "file", "submit",
- "image", "reset", "button"],
- missing: 'text' },
- formTarget: String,
- formNoValidate: Boolean,
- formMethod: { type: ["get", "post"], invalid: 'get', missing: '' },
- formEnctype: { type: ["application/x-www-form-urlencoded", "multipart/form-data", "text/plain"], invalid: "application/x-www-form-urlencoded", missing: '' },
- inputMode: { type: [ "verbatim", "latin", "latin-name", "latin-prose", "full-width-latin", "kana", "kana-name", "katakana", "numeric", "tel", "email", "url" ], missing: '' },
- // Obsolete
- align: String,
- useMap: String,
- }
-});
-
-define({
- tag: 'keygen',
- ctor: function HTMLKeygenElement(doc, localName, prefix) {
- HTMLFormElement.call(this, doc, localName, prefix);
- },
- props: formAssociatedProps,
- attributes: {
- name: String,
- disabled: Boolean,
- autofocus: Boolean,
- challenge: String,
- keytype: { type:["rsa"], missing: '' },
- }
-});
-
-define({
- tag: 'li',
- ctor: function HTMLLIElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- value: {type: "long", default: 0},
- // Obsolete
- type: String,
- }
-});
-
-define({
- tag: 'label',
- ctor: function HTMLLabelElement(doc, localName, prefix) {
- HTMLFormElement.call(this, doc, localName, prefix);
- },
- props: formAssociatedProps,
- attributes: {
- htmlFor: {name: 'for', type: String}
- }
-});
-
-define({
- tag: 'legend',
- ctor: function HTMLLegendElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- // Obsolete
- align: String
- },
-});
-
-define({
- tag: 'link',
- ctor: function HTMLLinkElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- // XXX Reflect DOMSettableTokenList sizes also DOMTokenList relList
- href: URL,
- rel: String,
- media: String,
- hreflang: String,
- type: String,
- crossOrigin: CORS,
- nonce: String,
- integrity: String,
- referrerPolicy: REFERRER,
- // Obsolete
- charset: String,
- rev: String,
- target: String,
- }
-});
-
-define({
- tag: 'map',
- ctor: function HTMLMapElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- name: String
- }
-});
-
-define({
- tag: 'menu',
- ctor: function HTMLMenuElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- // XXX: not quite right, default should be popup if parent element is
- // popup.
- type: { type: [ 'context', 'popup', 'toolbar' ], missing: 'toolbar' },
- label: String,
- // Obsolete
- compact: Boolean,
- }
-});
-
-define({
- tag: 'meta',
- ctor: function HTMLMetaElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- name: String,
- content: String,
- httpEquiv: {name: 'http-equiv', type: String},
- // Obsolete
- scheme: String,
- }
-});
-
-define({
- tag: 'meter',
- ctor: function HTMLMeterElement(doc, localName, prefix) {
- HTMLFormElement.call(this, doc, localName, prefix);
- },
- props: formAssociatedProps
-});
-
-define({
- tags: ['ins', 'del'],
- ctor: function HTMLModElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- cite: URL,
- dateTime: String
- }
-});
-
-define({
- tag: 'ol',
- ctor: function HTMLOListElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- props: {
- // Utility function (see the start attribute default value). Returns
- // the number of <li> children of this element
- _numitems: { get: function() {
- var items = 0;
- this.childNodes.forEach(function(n) {
- if (n.nodeType === Node.ELEMENT_NODE && n.tagName === "LI")
- items++;
- });
- return items;
- }}
- },
- attributes: {
- type: String,
- reversed: Boolean,
- start: {
- type: "long",
- default: function() {
- // The default value of the start attribute is 1 unless the list is
- // reversed. Then it is the # of li children
- if (this.reversed)
- return this._numitems;
- else
- return 1;
- }
- },
- // Obsolete
- compact: Boolean,
- }
-});
-
-define({
- tag: 'object',
- ctor: function HTMLObjectElement(doc, localName, prefix) {
- HTMLFormElement.call(this, doc, localName, prefix);
- },
- props: formAssociatedProps,
- attributes: {
- data: URL,
- type: String,
- name: String,
- useMap: String,
- typeMustMatch: Boolean,
- width: String,
- height: String,
- // Obsolete
- align: String,
- archive: String,
- code: String,
- declare: Boolean,
- hspace: { type: "unsigned long", default: 0 },
- standby: String,
- vspace: { type: "unsigned long", default: 0 },
- codeBase: URL,
- codeType: String,
- border: { type: String, treatNullAsEmptyString: true },
- }
-});
-
-define({
- tag: 'optgroup',
- ctor: function HTMLOptGroupElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- disabled: Boolean,
- label: String
- }
-});
-
-define({
- tag: 'option',
- ctor: function HTMLOptionElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- props: {
- form: { get: function() {
- var p = this.parentNode;
- while (p && p.nodeType === Node.ELEMENT_NODE) {
- if (p.localName === 'select') return p.form;
- p = p.parentNode;
- }
- }},
- value: {
- get: function() { return this._getattr('value') || this.text; },
- set: function(v) { this._setattr('value', v); },
- },
- text: {
- get: function() {
- // Strip and collapse whitespace
- return this.textContent.replace(/[ \t\n\f\r]+/g, ' ').trim();
- },
- set: function(v) { this.textContent = v; },
- },
- // missing: index
- },
- attributes: {
- disabled: Boolean,
- defaultSelected: {name: 'selected', type: Boolean},
- label: String,
- }
-});
-
-define({
- tag: 'output',
- ctor: function HTMLOutputElement(doc, localName, prefix) {
- HTMLFormElement.call(this, doc, localName, prefix);
- },
- props: formAssociatedProps,
- attributes: {
- // XXX Reflect for/htmlFor as a settable token list
- name: String
- }
-});
-
-define({
- tag: 'p',
- ctor: function HTMLParagraphElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- // Obsolete
- align: String
- }
-});
-
-define({
- tag: 'param',
- ctor: function HTMLParamElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- name: String,
- value: String,
- // Obsolete
- type: String,
- valueType: String,
- }
-});
-
-define({
- tags: ['pre',/*legacy elements:*/'listing','xmp'],
- ctor: function HTMLPreElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- // Obsolete
- width: { type: "long", default: 0 },
- }
-});
-
-define({
- tag: 'progress',
- ctor: function HTMLProgressElement(doc, localName, prefix) {
- HTMLFormElement.call(this, doc, localName, prefix);
- },
- props: formAssociatedProps,
- attributes: {
- max: {type: Number, float: true, default: 1.0, min: 0}
- }
-});
-
-define({
- tags: ['q', 'blockquote'],
- ctor: function HTMLQuoteElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- cite: URL
- }
-});
-
-define({
- tag: 'script',
- ctor: function HTMLScriptElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- props: {
- text: {
- get: function() {
- var s = "";
- for(var i = 0, n = this.childNodes.length; i < n; i++) {
- var child = this.childNodes[i];
- if (child.nodeType === Node.TEXT_NODE)
- s += child._data;
- }
- return s;
- },
- set: function(value) {
- this.removeChildren();
- if (value !== null && value !== "") {
- this.appendChild(this.ownerDocument.createTextNode(value));
- }
- }
- }
- },
- attributes: {
- src: URL,
- type: String,
- charset: String,
- defer: Boolean,
- async: Boolean,
- crossOrigin: CORS,
- nonce: String,
- integrity: String,
- }
-});
-
-define({
- tag: 'select',
- ctor: function HTMLSelectElement(doc, localName, prefix) {
- HTMLFormElement.call(this, doc, localName, prefix);
- },
- props: {
- form: formAssociatedProps.form,
- options: { get: function() {
- return this.getElementsByTagName('option');
- }}
- },
- attributes: {
- autocomplete: String, // It's complicated
- name: String,
- disabled: Boolean,
- autofocus: Boolean,
- multiple: Boolean,
- required: Boolean,
- size: {type: "unsigned long", default: 0}
- }
-});
-
-define({
- tag: 'source',
- ctor: function HTMLSourceElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- src: URL,
- type: String,
- media: String
- }
-});
-
-define({
- tag: 'span',
- ctor: function HTMLSpanElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- }
-});
-
-define({
- tag: 'style',
- ctor: function HTMLStyleElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- media: String,
- type: String,
- scoped: Boolean
- }
-});
-
-define({
- tag: 'caption',
- ctor: function HTMLTableCaptionElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- // Obsolete
- align: String,
- }
-});
-
-
-define({
- ctor: function HTMLTableCellElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- colSpan: {type: "unsigned long", default: 1},
- rowSpan: {type: "unsigned long", default: 1},
- //XXX Also reflect settable token list headers
- scope: { type: ['row','col','rowgroup','colgroup'], missing: '' },
- abbr: String,
- // Obsolete
- align: String,
- axis: String,
- height: String,
- width: String,
- ch: { name: 'char', type: String },
- chOff: { name: 'charoff', type: String },
- noWrap: Boolean,
- vAlign: String,
- bgColor: { type: String, treatNullAsEmptyString: true },
- }
-});
-
-define({
- tags: ['col', 'colgroup'],
- ctor: function HTMLTableColElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- span: {type: 'limited unsigned long with fallback', default: 1, min: 1},
- // Obsolete
- align: String,
- ch: { name: 'char', type: String },
- chOff: { name: 'charoff', type: String },
- vAlign: String,
- width: String,
- }
-});
-
-define({
- tag: 'table',
- ctor: function HTMLTableElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- props: {
- rows: { get: function() {
- return this.getElementsByTagName('tr');
- }}
- },
- attributes: {
- // Obsolete
- align: String,
- border: String,
- frame: String,
- rules: String,
- summary: String,
- width: String,
- bgColor: { type: String, treatNullAsEmptyString: true },
- cellPadding: { type: String, treatNullAsEmptyString: true },
- cellSpacing: { type: String, treatNullAsEmptyString: true },
- }
-});
-
-define({
- tag: 'template',
- ctor: function HTMLTemplateElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- this._contentFragment = doc._templateDoc.createDocumentFragment();
- },
- props: {
- content: { get: function() { return this._contentFragment; } },
- serialize: { value: function() { return this.content.serialize(); } }
- }
-});
-
-define({
- tag: 'tr',
- ctor: function HTMLTableRowElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- props: {
- cells: { get: function() {
- return this.querySelectorAll('td,th');
- }}
- },
- attributes: {
- // Obsolete
- align: String,
- ch: { name: 'char', type: String },
- chOff: { name: 'charoff', type: String },
- vAlign: String,
- bgColor: { type: String, treatNullAsEmptyString: true },
- },
-});
-
-define({
- tags: ['thead', 'tfoot', 'tbody'],
- ctor: function HTMLTableSectionElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- props: {
- rows: { get: function() {
- return this.getElementsByTagName('tr');
- }}
- },
- attributes: {
- // Obsolete
- align: String,
- ch: { name: 'char', type: String },
- chOff: { name: 'charoff', type: String },
- vAlign: String,
- }
-});
-
-define({
- tag: 'textarea',
- ctor: function HTMLTextAreaElement(doc, localName, prefix) {
- HTMLFormElement.call(this, doc, localName, prefix);
- },
- props: {
- form: formAssociatedProps.form,
- type: { get: function() { return 'textarea'; } },
- defaultValue: {
- get: function() { return this.textContent; },
- set: function(v) { this.textContent = v; },
- },
- value: {
- get: function() { return this.defaultValue; /* never dirty */ },
- set: function(v) {
- // This isn't completely correct: according to the spec, this
- // should "dirty" the API value, and result in
- // `this.value !== this.defaultValue`. But for most of what
- // folks want to do, this implementation should be fine:
- this.defaultValue = v;
- },
- },
- textLength: { get: function() { return this.value.length; } },
- },
- attributes: {
- autocomplete: String, // It's complicated
- name: String,
- disabled: Boolean,
- autofocus: Boolean,
- placeholder: String,
- wrap: String,
- dirName: String,
- required: Boolean,
- readOnly: Boolean,
- rows: {type: 'limited unsigned long with fallback', default: 2 },
- cols: {type: 'limited unsigned long with fallback', default: 20 },
- maxLength: {type: 'unsigned long', min: 0, setmin: 0, default: -1},
- minLength: {type: 'unsigned long', min: 0, setmin: 0, default: -1},
- inputMode: { type: [ "verbatim", "latin", "latin-name", "latin-prose", "full-width-latin", "kana", "kana-name", "katakana", "numeric", "tel", "email", "url" ], missing: '' },
- }
-});
-
-define({
- tag: 'time',
- ctor: function HTMLTimeElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- dateTime: String,
- pubDate: Boolean
- }
-});
-
-define({
- tag: 'title',
- ctor: function HTMLTitleElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- props: {
- text: { get: function() {
- return this.textContent;
- }}
- }
-});
-
-define({
- tag: 'ul',
- ctor: function HTMLUListElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- type: String,
- // Obsolete
- compact: Boolean,
- }
-});
-
-define({
- ctor: function HTMLMediaElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- src: URL,
- crossOrigin: CORS,
- preload: { type:["metadata", "none", "auto", {value: "", alias: "auto"}], missing: 'auto' },
- loop: Boolean,
- autoplay: Boolean,
- mediaGroup: String,
- controls: Boolean,
- defaultMuted: {name: "muted", type: Boolean}
- }
-});
-
-define({
- tag: 'audio',
- superclass: htmlElements.HTMLMediaElement,
- ctor: function HTMLAudioElement(doc, localName, prefix) {
- htmlElements.HTMLMediaElement.call(this, doc, localName, prefix);
- }
-});
-
-define({
- tag: 'video',
- superclass: htmlElements.HTMLMediaElement,
- ctor: function HTMLVideoElement(doc, localName, prefix) {
- htmlElements.HTMLMediaElement.call(this, doc, localName, prefix);
- },
- attributes: {
- poster: URL,
- width: {type: "unsigned long", min: 0, default: 0 },
- height: {type: "unsigned long", min: 0, default: 0 }
- }
-});
-
-define({
- tag: 'td',
- superclass: htmlElements.HTMLTableCellElement,
- ctor: function HTMLTableDataCellElement(doc, localName, prefix) {
- htmlElements.HTMLTableCellElement.call(this, doc, localName, prefix);
- }
-});
-
-define({
- tag: 'th',
- superclass: htmlElements.HTMLTableCellElement,
- ctor: function HTMLTableHeaderCellElement(doc, localName, prefix) {
- htmlElements.HTMLTableCellElement.call(this, doc, localName, prefix);
- },
-});
-
-define({
- tag: 'frameset',
- ctor: function HTMLFrameSetElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- }
-});
-
-define({
- tag: 'frame',
- ctor: function HTMLFrameElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- }
-});
-
-define({
- tag: 'canvas',
- ctor: function HTMLCanvasElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- props: {
- getContext: { value: utils.nyi },
- probablySupportsContext: { value: utils.nyi },
- setContext: { value: utils.nyi },
- transferControlToProxy: { value: utils.nyi },
- toDataURL: { value: utils.nyi },
- toBlob: { value: utils.nyi }
- },
- attributes: {
- width: { type: "unsigned long", default: 300},
- height: { type: "unsigned long", default: 150}
- }
-});
-
-define({
- tag: 'dialog',
- ctor: function HTMLDialogElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- props: {
- show: { value: utils.nyi },
- showModal: { value: utils.nyi },
- close: { value: utils.nyi }
- },
- attributes: {
- open: Boolean,
- returnValue: String
- }
-});
-
-define({
- tag: 'menuitem',
- ctor: function HTMLMenuItemElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- props: {
- // The menuitem's label
- _label: {
- get: function() {
- var val = this._getattr('label');
- if (val !== null && val !== '') { return val; }
- val = this.textContent;
- // Strip and collapse whitespace
- return val.replace(/[ \t\n\f\r]+/g, ' ').trim();
- }
- },
- // The menuitem label IDL attribute
- label: {
- get: function() {
- var val = this._getattr('label');
- if (val !== null) { return val; }
- return this._label;
- },
- set: function(v) {
- this._setattr('label', v);
- },
- }
- },
- attributes: {
- type: { type: ["command","checkbox","radio"], missing: 'command' },
- icon: URL,
- disabled: Boolean,
- checked: Boolean,
- radiogroup: String,
- default: Boolean
- }
-});
-
-define({
- tag: 'source',
- ctor: function HTMLSourceElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- srcset: String,
- sizes: String,
- media: String,
- src: URL,
- type: String
- }
-});
-
-define({
- tag: 'track',
- ctor: function HTMLTrackElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- src: URL,
- srclang: String,
- label: String,
- default: Boolean,
- kind: { type: ["subtitles", "captions", "descriptions", "chapters", "metadata"], missing: 'subtitles', invalid: 'metadata' },
- },
- props: {
- NONE: { get: function() { return 0; } },
- LOADING: { get: function() { return 1; } },
- LOADED: { get: function() { return 2; } },
- ERROR: { get: function() { return 3; } },
- readyState: { get: utils.nyi },
- track: { get: utils.nyi }
- }
-});
-
-define({
- // obsolete
- tag: 'font',
- ctor: function HTMLFontElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- color: { type: String, treatNullAsEmptyString: true },
- face: { type: String },
- size: { type: String },
- },
-});
-
-define({
- // obsolete
- tag: 'dir',
- ctor: function HTMLDirectoryElement(doc, localName, prefix) {
- HTMLElement.call(this, doc, localName, prefix);
- },
- attributes: {
- compact: Boolean,
- },
-});
-
-define({
- tags: [
- "abbr", "address", "article", "aside", "b", "bdi", "bdo",
- "cite", "code", "dd", "dfn", "dt", "em", "figcaption", "figure",
- "footer", "header", "hgroup", "i", "kbd", "main", "mark", "nav", "noscript",
- "rb", "rp", "rt", "rtc", "ruby", "s", "samp", "section", "small", "strong",
- "sub", "summary", "sup", "u", "var", "wbr",
- // Legacy elements
- "acronym", "basefont", "big", "center", "nobr", "noembed", "noframes",
- "plaintext", "strike", "tt"
- ]
-});
--- a/cmd/gojafs/domino/domino-lib/impl.js
+++ /dev/null
@@ -1,27 +1,0 @@
-"use strict";
-var utils = require('./utils');
-
-exports = module.exports = {
- CSSStyleDeclaration: require('./CSSStyleDeclaration'),
- CharacterData: require('./CharacterData'),
- Comment: require('./Comment'),
- DOMException: require('./DOMException'),
- DOMImplementation: require('./DOMImplementation'),
- DOMTokenList: require('./DOMTokenList'),
- Document: require('./Document'),
- DocumentFragment: require('./DocumentFragment'),
- DocumentType: require('./DocumentType'),
- Element: require('./Element'),
- HTMLParser: require('./HTMLParser'),
- NamedNodeMap: require('./NamedNodeMap'),
- Node: require('./Node'),
- NodeList: require('./NodeList'),
- NodeFilter: require('./NodeFilter'),
- ProcessingInstruction: require('./ProcessingInstruction'),
- Text: require('./Text'),
- Window: require('./Window')
-};
-
-utils.merge(exports, require('./events'));
-utils.merge(exports, require('./htmlelts').elements);
-utils.merge(exports, require('./svg').elements);
--- a/cmd/gojafs/domino/domino-lib/index.d.ts
+++ /dev/null
@@ -1,5 +1,0 @@
-declare module "domino" {
- function createDOMImplementation(): DOMImplementation;
- function createDocument(html?: string, force?: boolean): Document;
- function createWindow(html?: string, address?: string): Window;
-}
\ No newline at end of file
--- a/cmd/gojafs/domino/domino-lib/index.js
+++ /dev/null
@@ -1,79 +1,0 @@
-"use strict";
-var DOMImplementation = require('./DOMImplementation');
-var HTMLParser = require('./HTMLParser');
-var Window = require('./Window');
-
-exports.createDOMImplementation = function() {
- return new DOMImplementation(null);
-};
-
-exports.createDocument = function(html, force) {
- // Previous API couldn't let you pass '' as a document, and that
- // yields a slightly different document than createHTMLDocument('')
- // does. The new `force` parameter lets you pass '' if you want to.
- if (html || force) {
- var parser = new HTMLParser();
- parser.parse(html || '', true);
- return parser.document();
- }
- return new DOMImplementation(null).createHTMLDocument("");
-};
-
-exports.createIncrementalHTMLParser = function() {
- var parser = new HTMLParser();
- /** API for incremental parser. */
- return {
- /** Provide an additional chunk of text to be parsed. */
- write: function(s) {
- if (s.length > 0) {
- parser.parse(s, false, function() { return true; });
- }
- },
- /**
- * Signal that we are done providing input text, optionally
- * providing one last chunk as a parameter.
- */
- end: function(s) {
- parser.parse(s || '', true, function() { return true; });
- },
- /**
- * Performs a chunk of parsing work, returning at the end of
- * the next token as soon as shouldPauseFunc() returns true.
- * Returns true iff there is more work to do.
- *
- * For example:
- * ```
- * var incrParser = domino.createIncrementalHTMLParser();
- * incrParser.end('...long html document...');
- * while (true) {
- * // Pause every 10ms
- * var start = Date.now();
- * var pauseIn10 = function() { return (Date.now() - start) >= 10; };
- * if (!incrParser.process(pauseIn10)) {
- * break;
- * }
- * ...yield to other tasks, do other housekeeping, etc...
- * }
- * ```
- */
- process: function(shouldPauseFunc) {
- return parser.parse('', false, shouldPauseFunc);
- },
- /**
- * Returns the result of the incremental parse. Valid after
- * `this.end()` has been called and `this.process()` has returned
- * false.
- */
- document: function() {
- return parser.document();
- },
- };
-};
-
-exports.createWindow = function(html, address) {
- var document = exports.createDocument(html);
- if (address !== undefined) { document._address = address; }
- return new Window(document);
-};
-
-exports.impl = require('./impl');
--- a/cmd/gojafs/domino/domino-lib/select.js
+++ /dev/null
@@ -1,933 +1,0 @@
-"use strict";
-/* jshint eqnull: true */
-/**
- * Zest (https://github.com/chjj/zest)
- * A css selector engine.
- * Copyright (c) 2011-2012, Christopher Jeffrey. (MIT Licensed)
- * Domino version based on Zest v0.1.3 with bugfixes applied.
- */
-
-/**
- * Helpers
- */
-
-var window = Object.create(null, {
- location: { get: function() {
- throw new Error('window.location is not supported.');
- } }
-});
-
-var compareDocumentPosition = function(a, b) {
- return a.compareDocumentPosition(b);
-};
-
-var order = function(a, b) {
- /* jshint bitwise: false */
- return compareDocumentPosition(a, b) & 2 ? 1 : -1;
-};
-
-var next = function(el) {
- while ((el = el.nextSibling)
- && el.nodeType !== 1);
- return el;
-};
-
-var prev = function(el) {
- while ((el = el.previousSibling)
- && el.nodeType !== 1);
- return el;
-};
-
-var child = function(el) {
- /*jshint -W084 */
- if (el = el.firstChild) {
- while (el.nodeType !== 1
- && (el = el.nextSibling));
- }
- return el;
-};
-
-var lastChild = function(el) {
- /*jshint -W084 */
- if (el = el.lastChild) {
- while (el.nodeType !== 1
- && (el = el.previousSibling));
- }
- return el;
-};
-
-var parentIsElement = function(n) {
- if (!n.parentNode) { return false; }
- var nodeType = n.parentNode.nodeType;
- // The root `html` element can be a first- or last-child, too.
- return nodeType === 1 || nodeType === 9;
-};
-
-var unquote = function(str) {
- if (!str) return str;
- var ch = str[0];
- if (ch === '"' || ch === '\'') {
- if (str[str.length-1] === ch) {
- str = str.slice(1, -1);
- } else {
- // bad string.
- str = str.slice(1);
- }
- return str.replace(rules.str_escape, function(s) {
- var m = /^\\(?:([0-9A-Fa-f]+)|([\r\n\f]+))/.exec(s);
- if (!m) { return s.slice(1); }
- if (m[2]) { return ''; /* escaped newlines are ignored in strings. */ }
- var cp = parseInt(m[1], 16);
- return String.fromCodePoint ? String.fromCodePoint(cp) :
- // Not all JavaScript implementations have String.fromCodePoint yet.
- String.fromCharCode(cp);
- });
- } else if (rules.ident.test(str)) {
- return decodeid(str);
- } else {
- // NUMBER, PERCENTAGE, DIMENSION, etc
- return str;
- }
-};
-
-var decodeid = function(str) {
- return str.replace(rules.escape, function(s) {
- var m = /^\\([0-9A-Fa-f]+)/.exec(s);
- if (!m) { return s[1]; }
- var cp = parseInt(m[1], 16);
- return String.fromCodePoint ? String.fromCodePoint(cp) :
- // Not all JavaScript implementations have String.fromCodePoint yet.
- String.fromCharCode(cp);
- });
-};
-
-var indexOf = (function() {
- if (Array.prototype.indexOf) {
- return Array.prototype.indexOf;
- }
- return function(obj, item) {
- var i = this.length;
- while (i--) {
- if (this[i] === item) return i;
- }
- return -1;
- };
-})();
-
-var makeInside = function(start, end) {
- var regex = rules.inside.source
- .replace(/</g, start)
- .replace(/>/g, end);
-
- return new RegExp(regex);
-};
-
-var replace = function(regex, name, val) {
- regex = regex.source;
- regex = regex.replace(name, val.source || val);
- return new RegExp(regex);
-};
-
-var truncateUrl = function(url, num) {
- return url
- .replace(/^(?:\w+:\/\/|\/+)/, '')
- .replace(/(?:\/+|\/*#.*?)$/, '')
- .split('/', num)
- .join('/');
-};
-
-/**
- * Handle `nth` Selectors
- */
-
-var parseNth = function(param_, test) {
- var param = param_.replace(/\s+/g, '')
- , cap;
-
- if (param === 'even') {
- param = '2n+0';
- } else if (param === 'odd') {
- param = '2n+1';
- } else if (param.indexOf('n') === -1) {
- param = '0n' + param;
- }
-
- cap = /^([+-])?(\d+)?n([+-])?(\d+)?$/.exec(param);
-
- return {
- group: cap[1] === '-'
- ? -(cap[2] || 1)
- : +(cap[2] || 1),
- offset: cap[4]
- ? (cap[3] === '-' ? -cap[4] : +cap[4])
- : 0
- };
-};
-
-var nth = function(param_, test, last) {
- var param = parseNth(param_)
- , group = param.group
- , offset = param.offset
- , find = !last ? child : lastChild
- , advance = !last ? next : prev;
-
- return function(el) {
- if (!parentIsElement(el)) return;
-
- var rel = find(el.parentNode)
- , pos = 0;
-
- while (rel) {
- if (test(rel, el)) pos++;
- if (rel === el) {
- pos -= offset;
- return group && pos
- ? (pos % group) === 0 && (pos < 0 === group < 0)
- : !pos;
- }
- rel = advance(rel);
- }
- };
-};
-
-/**
- * Simple Selectors
- */
-
-var selectors = {
- '*': (function() {
- if (false/*function() {
- var el = document.createElement('div');
- el.appendChild(document.createComment(''));
- return !!el.getElementsByTagName('*')[0];
- }()*/) {
- return function(el) {
- if (el.nodeType === 1) return true;
- };
- }
- return function() {
- return true;
- };
- })(),
- 'type': function(type) {
- type = type.toLowerCase();
- return function(el) {
- return el.nodeName.toLowerCase() === type;
- };
- },
- 'attr': function(key, op, val, i) {
- op = operators[op];
- return function(el) {
- var attr;
- switch (key) {
- case 'for':
- attr = el.htmlFor;
- break;
- case 'class':
- // className is '' when non-existent
- // getAttribute('class') is null
- attr = el.className;
- if (attr === '' && el.getAttribute('class') == null) {
- attr = null;
- }
- break;
- case 'href':
- case 'src':
- attr = el.getAttribute(key, 2);
- break;
- case 'title':
- // getAttribute('title') can be '' when non-existent sometimes?
- attr = el.getAttribute('title') || null;
- break;
- // careful with attributes with special getter functions
- case 'id':
- case 'lang':
- case 'dir':
- case 'accessKey':
- case 'hidden':
- case 'tabIndex':
- case 'style':
- if (el.getAttribute) {
- attr = el.getAttribute(key);
- break;
- }
- /* falls through */
- default:
- if (el.hasAttribute && !el.hasAttribute(key)) {
- break;
- }
- attr = el[key] != null
- ? el[key]
- : el.getAttribute && el.getAttribute(key);
- break;
- }
- if (attr == null) return;
- attr = attr + '';
- if (i) {
- attr = attr.toLowerCase();
- val = val.toLowerCase();
- }
- return op(attr, val);
- };
- },
- ':first-child': function(el) {
- return !prev(el) && parentIsElement(el);
- },
- ':last-child': function(el) {
- return !next(el) && parentIsElement(el);
- },
- ':only-child': function(el) {
- return !prev(el) && !next(el) && parentIsElement(el);
- },
- ':nth-child': function(param, last) {
- return nth(param, function() {
- return true;
- }, last);
- },
- ':nth-last-child': function(param) {
- return selectors[':nth-child'](param, true);
- },
- ':root': function(el) {
- return el.ownerDocument.documentElement === el;
- },
- ':empty': function(el) {
- return !el.firstChild;
- },
- ':not': function(sel) {
- var test = compileGroup(sel);
- return function(el) {
- return !test(el);
- };
- },
- ':first-of-type': function(el) {
- if (!parentIsElement(el)) return;
- var type = el.nodeName;
- /*jshint -W084 */
- while (el = prev(el)) {
- if (el.nodeName === type) return;
- }
- return true;
- },
- ':last-of-type': function(el) {
- if (!parentIsElement(el)) return;
- var type = el.nodeName;
- /*jshint -W084 */
- while (el = next(el)) {
- if (el.nodeName === type) return;
- }
- return true;
- },
- ':only-of-type': function(el) {
- return selectors[':first-of-type'](el)
- && selectors[':last-of-type'](el);
- },
- ':nth-of-type': function(param, last) {
- return nth(param, function(rel, el) {
- return rel.nodeName === el.nodeName;
- }, last);
- },
- ':nth-last-of-type': function(param) {
- return selectors[':nth-of-type'](param, true);
- },
- ':checked': function(el) {
- return !!(el.checked || el.selected);
- },
- ':indeterminate': function(el) {
- return !selectors[':checked'](el);
- },
- ':enabled': function(el) {
- return !el.disabled && el.type !== 'hidden';
- },
- ':disabled': function(el) {
- return !!el.disabled;
- },
- ':target': function(el) {
- return el.id === window.location.hash.substring(1);
- },
- ':focus': function(el) {
- return el === el.ownerDocument.activeElement;
- },
- ':is': function(sel) {
- return compileGroup(sel);
- },
- // :matches is an older name for :is; see
- // https://github.com/w3c/csswg-drafts/issues/3258
- ':matches': function(sel) {
- return selectors[':is'](sel);
- },
- ':nth-match': function(param, last) {
- var args = param.split(/\s*,\s*/)
- , arg = args.shift()
- , test = compileGroup(args.join(','));
-
- return nth(arg, test, last);
- },
- ':nth-last-match': function(param) {
- return selectors[':nth-match'](param, true);
- },
- ':links-here': function(el) {
- return el + '' === window.location + '';
- },
- ':lang': function(param) {
- return function(el) {
- while (el) {
- if (el.lang) return el.lang.indexOf(param) === 0;
- el = el.parentNode;
- }
- };
- },
- ':dir': function(param) {
- return function(el) {
- while (el) {
- if (el.dir) return el.dir === param;
- el = el.parentNode;
- }
- };
- },
- ':scope': function(el, con) {
- var context = con || el.ownerDocument;
- if (context.nodeType === 9) {
- return el === context.documentElement;
- }
- return el === context;
- },
- ':any-link': function(el) {
- return typeof el.href === 'string';
- },
- ':local-link': function(el) {
- if (el.nodeName) {
- return el.href && el.host === window.location.host;
- }
- var param = +el + 1;
- return function(el) {
- if (!el.href) return;
-
- var url = window.location + ''
- , href = el + '';
-
- return truncateUrl(url, param) === truncateUrl(href, param);
- };
- },
- ':default': function(el) {
- return !!el.defaultSelected;
- },
- ':valid': function(el) {
- return el.willValidate || (el.validity && el.validity.valid);
- },
- ':invalid': function(el) {
- return !selectors[':valid'](el);
- },
- ':in-range': function(el) {
- return el.value > el.min && el.value <= el.max;
- },
- ':out-of-range': function(el) {
- return !selectors[':in-range'](el);
- },
- ':required': function(el) {
- return !!el.required;
- },
- ':optional': function(el) {
- return !el.required;
- },
- ':read-only': function(el) {
- if (el.readOnly) return true;
-
- var attr = el.getAttribute('contenteditable')
- , prop = el.contentEditable
- , name = el.nodeName.toLowerCase();
-
- name = name !== 'input' && name !== 'textarea';
-
- return (name || el.disabled) && attr == null && prop !== 'true';
- },
- ':read-write': function(el) {
- return !selectors[':read-only'](el);
- },
- ':hover': function() {
- throw new Error(':hover is not supported.');
- },
- ':active': function() {
- throw new Error(':active is not supported.');
- },
- ':link': function() {
- throw new Error(':link is not supported.');
- },
- ':visited': function() {
- throw new Error(':visited is not supported.');
- },
- ':column': function() {
- throw new Error(':column is not supported.');
- },
- ':nth-column': function() {
- throw new Error(':nth-column is not supported.');
- },
- ':nth-last-column': function() {
- throw new Error(':nth-last-column is not supported.');
- },
- ':current': function() {
- throw new Error(':current is not supported.');
- },
- ':past': function() {
- throw new Error(':past is not supported.');
- },
- ':future': function() {
- throw new Error(':future is not supported.');
- },
- // Non-standard, for compatibility purposes.
- ':contains': function(param) {
- return function(el) {
- var text = el.innerText || el.textContent || el.value || '';
- return text.indexOf(param) !== -1;
- };
- },
- ':has': function(param) {
- return function(el) {
- return find(param, el).length > 0;
- };
- }
- // Potentially add more pseudo selectors for
- // compatibility with sizzle and most other
- // selector engines (?).
-};
-
-/**
- * Attribute Operators
- */
-
-var operators = {
- '-': function() {
- return true;
- },
- '=': function(attr, val) {
- return attr === val;
- },
- '*=': function(attr, val) {
- return attr.indexOf(val) !== -1;
- },
- '~=': function(attr, val) {
- var i
- , s
- , f
- , l;
-
- for (s = 0; true; s = i + 1) {
- i = attr.indexOf(val, s);
- if (i === -1) return false;
- f = attr[i - 1];
- l = attr[i + val.length];
- if ((!f || f === ' ') && (!l || l === ' ')) return true;
- }
- },
- '|=': function(attr, val) {
- var i = attr.indexOf(val)
- , l;
-
- if (i !== 0) return;
- l = attr[i + val.length];
-
- return l === '-' || !l;
- },
- '^=': function(attr, val) {
- return attr.indexOf(val) === 0;
- },
- '$=': function(attr, val) {
- var i = attr.lastIndexOf(val);
- return i !== -1 && i + val.length === attr.length;
- },
- // non-standard
- '!=': function(attr, val) {
- return attr !== val;
- }
-};
-
-/**
- * Combinator Logic
- */
-
-var combinators = {
- ' ': function(test) {
- return function(el) {
- /*jshint -W084 */
- while (el = el.parentNode) {
- if (test(el)) return el;
- }
- };
- },
- '>': function(test) {
- return function(el) {
- /*jshint -W084 */
- if (el = el.parentNode) {
- return test(el) && el;
- }
- };
- },
- '+': function(test) {
- return function(el) {
- /*jshint -W084 */
- if (el = prev(el)) {
- return test(el) && el;
- }
- };
- },
- '~': function(test) {
- return function(el) {
- /*jshint -W084 */
- while (el = prev(el)) {
- if (test(el)) return el;
- }
- };
- },
- 'noop': function(test) {
- return function(el) {
- return test(el) && el;
- };
- },
- 'ref': function(test, name) {
- var node;
-
- function ref(el) {
- var doc = el.ownerDocument
- , nodes = doc.getElementsByTagName('*')
- , i = nodes.length;
-
- while (i--) {
- node = nodes[i];
- if (ref.test(el)) {
- node = null;
- return true;
- }
- }
-
- node = null;
- }
-
- ref.combinator = function(el) {
- if (!node || !node.getAttribute) return;
-
- var attr = node.getAttribute(name) || '';
- if (attr[0] === '#') attr = attr.substring(1);
-
- if (attr === el.id && test(node)) {
- return node;
- }
- };
-
- return ref;
- }
-};
-
-/**
- * Grammar
- */
-
-var rules = {
- escape: /\\(?:[^0-9A-Fa-f\r\n]|[0-9A-Fa-f]{1,6}[\r\n\t ]?)/g,
- str_escape: /(escape)|\\(\n|\r\n?|\f)/g,
- nonascii: /[\u00A0-\uFFFF]/,
- cssid: /(?:(?!-?[0-9])(?:escape|nonascii|[-_a-zA-Z0-9])+)/,
- qname: /^ *(cssid|\*)/,
- simple: /^(?:([.#]cssid)|pseudo|attr)/,
- ref: /^ *\/(cssid)\/ */,
- combinator: /^(?: +([^ \w*.#\\]) +|( )+|([^ \w*.#\\]))(?! *$)/,
- attr: /^\[(cssid)(?:([^\w]?=)(inside))?\]/,
- pseudo: /^(:cssid)(?:\((inside)\))?/,
- inside: /(?:"(?:\\"|[^"])*"|'(?:\\'|[^'])*'|<[^"'>]*>|\\["'>]|[^"'>])*/,
- ident: /^(cssid)$/
-};
-
-rules.cssid = replace(rules.cssid, 'nonascii', rules.nonascii);
-rules.cssid = replace(rules.cssid, 'escape', rules.escape);
-rules.qname = replace(rules.qname, 'cssid', rules.cssid);
-rules.simple = replace(rules.simple, 'cssid', rules.cssid);
-rules.ref = replace(rules.ref, 'cssid', rules.cssid);
-rules.attr = replace(rules.attr, 'cssid', rules.cssid);
-rules.pseudo = replace(rules.pseudo, 'cssid', rules.cssid);
-rules.inside = replace(rules.inside, '[^"\'>]*', rules.inside);
-rules.attr = replace(rules.attr, 'inside', makeInside('\\[', '\\]'));
-rules.pseudo = replace(rules.pseudo, 'inside', makeInside('\\(', '\\)'));
-rules.simple = replace(rules.simple, 'pseudo', rules.pseudo);
-rules.simple = replace(rules.simple, 'attr', rules.attr);
-rules.ident = replace(rules.ident, 'cssid', rules.cssid);
-rules.str_escape = replace(rules.str_escape, 'escape', rules.escape);
-
-/**
- * Compiling
- */
-
-var compile = function(sel_) {
- var sel = sel_.replace(/^\s+|\s+$/g, '')
- , test
- , filter = []
- , buff = []
- , subject
- , qname
- , cap
- , op
- , ref;
-
- /*jshint -W084 */
- while (sel) {
- if (cap = rules.qname.exec(sel)) {
- sel = sel.substring(cap[0].length);
- qname = decodeid(cap[1]);
- buff.push(tok(qname, true));
- } else if (cap = rules.simple.exec(sel)) {
- sel = sel.substring(cap[0].length);
- qname = '*';
- buff.push(tok(qname, true));
- buff.push(tok(cap));
- } else {
- throw new SyntaxError('Invalid selector.');
- }
-
- while (cap = rules.simple.exec(sel)) {
- sel = sel.substring(cap[0].length);
- buff.push(tok(cap));
- }
-
- if (sel[0] === '!') {
- sel = sel.substring(1);
- subject = makeSubject();
- subject.qname = qname;
- buff.push(subject.simple);
- }
-
- if (cap = rules.ref.exec(sel)) {
- sel = sel.substring(cap[0].length);
- ref = combinators.ref(makeSimple(buff), decodeid(cap[1]));
- filter.push(ref.combinator);
- buff = [];
- continue;
- }
-
- if (cap = rules.combinator.exec(sel)) {
- sel = sel.substring(cap[0].length);
- op = cap[1] || cap[2] || cap[3];
- if (op === ',') {
- filter.push(combinators.noop(makeSimple(buff)));
- break;
- }
- } else {
- op = 'noop';
- }
-
- if (!combinators[op]) { throw new SyntaxError('Bad combinator.'); }
- filter.push(combinators[op](makeSimple(buff)));
- buff = [];
- }
-
- test = makeTest(filter);
- test.qname = qname;
- test.sel = sel;
-
- if (subject) {
- subject.lname = test.qname;
-
- subject.test = test;
- subject.qname = subject.qname;
- subject.sel = test.sel;
- test = subject;
- }
-
- if (ref) {
- ref.test = test;
- ref.qname = test.qname;
- ref.sel = test.sel;
- test = ref;
- }
-
- return test;
-};
-
-var tok = function(cap, qname) {
- // qname
- if (qname) {
- return cap === '*'
- ? selectors['*']
- : selectors.type(cap);
- }
-
- // class/id
- if (cap[1]) {
- return cap[1][0] === '.'
- // XXX unescape here? or in attr?
- ? selectors.attr('class', '~=', decodeid(cap[1].substring(1)), false)
- : selectors.attr('id', '=', decodeid(cap[1].substring(1)), false);
- }
-
- // pseudo-name
- // inside-pseudo
- if (cap[2]) {
- return cap[3]
- ? selectors[decodeid(cap[2])](unquote(cap[3]))
- : selectors[decodeid(cap[2])];
- }
-
- // attr name
- // attr op
- // attr value
- if (cap[4]) {
- var value = cap[6];
- var i = /["'\s]\s*I$/i.test(value);
- if (i) {
- value = value.replace(/\s*I$/i, '');
- }
- return selectors.attr(decodeid(cap[4]), cap[5] || '-', unquote(value), i);
- }
-
- throw new SyntaxError('Unknown Selector.');
-};
-
-var makeSimple = function(func) {
- var l = func.length
- , i;
-
- // Potentially make sure
- // `el` is truthy.
- if (l < 2) return func[0];
-
- return function(el) {
- if (!el) return;
- for (i = 0; i < l; i++) {
- if (!func[i](el)) return;
- }
- return true;
- };
-};
-
-var makeTest = function(func) {
- if (func.length < 2) {
- return function(el) {
- return !!func[0](el);
- };
- }
- return function(el) {
- var i = func.length;
- while (i--) {
- if (!(el = func[i](el))) return;
- }
- return true;
- };
-};
-
-var makeSubject = function() {
- var target;
-
- function subject(el) {
- var node = el.ownerDocument
- , scope = node.getElementsByTagName(subject.lname)
- , i = scope.length;
-
- while (i--) {
- if (subject.test(scope[i]) && target === el) {
- target = null;
- return true;
- }
- }
-
- target = null;
- }
-
- subject.simple = function(el) {
- target = el;
- return true;
- };
-
- return subject;
-};
-
-var compileGroup = function(sel) {
- var test = compile(sel)
- , tests = [ test ];
-
- while (test.sel) {
- test = compile(test.sel);
- tests.push(test);
- }
-
- if (tests.length < 2) return test;
-
- return function(el) {
- var l = tests.length
- , i = 0;
-
- for (; i < l; i++) {
- if (tests[i](el)) return true;
- }
- };
-};
-
-/**
- * Selection
- */
-
-var find = function(sel, node) {
- var results = []
- , test = compile(sel)
- , scope = node.getElementsByTagName(test.qname)
- , i = 0
- , el;
-
- /*jshint -W084 */
- while (el = scope[i++]) {
- if (test(el)) results.push(el);
- }
-
- if (test.sel) {
- while (test.sel) {
- test = compile(test.sel);
- scope = node.getElementsByTagName(test.qname);
- i = 0;
- /*jshint -W084 */
- while (el = scope[i++]) {
- if (test(el) && indexOf.call(results, el) === -1) {
- results.push(el);
- }
- }
- }
- results.sort(order);
- }
-
- return results;
-};
-
-/**
- * Expose
- */
-
-module.exports = exports = function(sel, context) {
- /* when context isn't a DocumentFragment and the selector is simple: */
- var id, r;
- if (context.nodeType !== 11 && sel.indexOf(' ') === -1) {
- if (sel[0] === '#' && context.rooted && /^#[A-Z_][-A-Z0-9_]*$/i.test(sel)) {
- if (context.doc._hasMultipleElementsWithId) {
- id = sel.substring(1);
- if (!context.doc._hasMultipleElementsWithId(id)) {
- r = context.doc.getElementById(id);
- return r ? [r] : [];
- }
- }
- }
- if (sel[0] === '.' && /^\.\w+$/.test(sel)) {
- return context.getElementsByClassName(sel.substring(1));
- }
- if (/^\w+$/.test(sel)) {
- return context.getElementsByTagName(sel);
- }
- }
- /* do things the hard/slow way */
- return find(sel, context);
-};
-
-exports.selectors = selectors;
-exports.operators = operators;
-exports.combinators = combinators;
-
-exports.matches = function(el, sel) {
- var test = { sel: sel };
- do {
- test = compile(test.sel);
- if (test(el)) { return true; }
- } while (test.sel);
- return false;
-};
--- a/cmd/gojafs/domino/domino-lib/sloppy.js
+++ /dev/null
@@ -1,24 +1,0 @@
-/* Domino uses sloppy-mode features (in particular, `with`) for a few
- * minor things. This file encapsulates all the sloppiness; every
- * other module should be strict. */
-/* jshint strict: false */
-/* jshint evil: true */
-/* jshint -W085 */
-module.exports = {
- Window_run: function _run(code, file) {
- if (file) code += '\n//@ sourceURL=' + file;
- with(this) eval(code);
- },
- EventHandlerBuilder_build: function build() {
- try {
- with(this.document.defaultView || Object.create(null))
- with(this.document)
- with(this.form)
- with(this.element)
- return eval("(function(event){" + this.body + "})");
- }
- catch (err) {
- return function() { throw err; };
- }
- }
-};
--- a/cmd/gojafs/domino/domino-lib/svg.js
+++ /dev/null
@@ -1,57 +1,0 @@
-"use strict";
-var Element = require('./Element');
-var defineElement = require('./defineElement');
-var utils = require('./utils');
-var CSSStyleDeclaration = require('./CSSStyleDeclaration');
-
-var svgElements = exports.elements = {};
-var svgNameToImpl = Object.create(null);
-
-exports.createElement = function(doc, localName, prefix) {
- var impl = svgNameToImpl[localName] || SVGElement;
- return new impl(doc, localName, prefix);
-};
-
-function define(spec) {
- return defineElement(spec, SVGElement, svgElements, svgNameToImpl);
-}
-
-var SVGElement = define({
- superclass: Element,
- ctor: function SVGElement(doc, localName, prefix) {
- Element.call(this, doc, localName, utils.NAMESPACE.SVG, prefix);
- },
- props: {
- style: { get: function() {
- if (!this._style)
- this._style = new CSSStyleDeclaration(this);
- return this._style;
- }}
- }
-});
-
-define({
- ctor: function SVGSVGElement(doc, localName, prefix) {
- SVGElement.call(this, doc, localName, prefix);
- },
- tag: 'svg',
- props: {
- createSVGRect: { value: function () {
- return exports.createElement(this.ownerDocument, 'rect', null);
- } }
- }
-});
-
-define({
- tags: [
- 'a', 'altGlyph', 'altGlyphDef', 'altGlyphItem', 'animate', 'animateColor', 'animateMotion', 'animateTransform',
- 'circle', 'clipPath', 'color-profile', 'cursor', 'defs', 'desc', 'ellipse', 'feBlend', 'feColorMatrix',
- 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting', 'feDisplacementMap', 'feDistantLight',
- 'feFlood', 'feFuncA', 'feFuncB', 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode',
- 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting', 'feSpotLight', 'feTile', 'feTurbulence', 'filter',
- 'font', 'font-face', 'font-face-format', 'font-face-name', 'font-face-src', 'font-face-uri', 'foreignObject', 'g',
- 'glyph', 'glyphRef', 'hkern', 'image', 'line', 'linearGradient', 'marker', 'mask', 'metadata', 'missing-glyph',
- 'mpath', 'path', 'pattern', 'polygon', 'polyline', 'radialGradient', 'rect', 'script', 'set', 'stop', 'style',
- 'switch', 'symbol', 'text', 'textPath', 'title', 'tref', 'tspan', 'use', 'view', 'vkern'
- ]
-});
--- a/cmd/gojafs/domino/domino-lib/utils.js
+++ /dev/null
@@ -1,85 +1,0 @@
-"use strict";
-var DOMException = require('./DOMException');
-var ERR = DOMException;
-var isApiWritable = require("./config").isApiWritable;
-
-exports.NAMESPACE = {
- HTML: 'http://www.w3.org/1999/xhtml',
- XML: 'http://www.w3.org/XML/1998/namespace',
- XMLNS: 'http://www.w3.org/2000/xmlns/',
- MATHML: 'http://www.w3.org/1998/Math/MathML',
- SVG: 'http://www.w3.org/2000/svg',
- XLINK: 'http://www.w3.org/1999/xlink'
-};
-
-//
-// Shortcut functions for throwing errors of various types.
-//
-exports.IndexSizeError = function() { throw new DOMException(ERR.INDEX_SIZE_ERR); };
-exports.HierarchyRequestError = function() { throw new DOMException(ERR.HIERARCHY_REQUEST_ERR); };
-exports.WrongDocumentError = function() { throw new DOMException(ERR.WRONG_DOCUMENT_ERR); };
-exports.InvalidCharacterError = function() { throw new DOMException(ERR.INVALID_CHARACTER_ERR); };
-exports.NoModificationAllowedError = function() { throw new DOMException(ERR.NO_MODIFICATION_ALLOWED_ERR); };
-exports.NotFoundError = function() { throw new DOMException(ERR.NOT_FOUND_ERR); };
-exports.NotSupportedError = function() { throw new DOMException(ERR.NOT_SUPPORTED_ERR); };
-exports.InvalidStateError = function() { throw new DOMException(ERR.INVALID_STATE_ERR); };
-exports.SyntaxError = function() { throw new DOMException(ERR.SYNTAX_ERR); };
-exports.InvalidModificationError = function() { throw new DOMException(ERR.INVALID_MODIFICATION_ERR); };
-exports.NamespaceError = function() { throw new DOMException(ERR.NAMESPACE_ERR); };
-exports.InvalidAccessError = function() { throw new DOMException(ERR.INVALID_ACCESS_ERR); };
-exports.TypeMismatchError = function() { throw new DOMException(ERR.TYPE_MISMATCH_ERR); };
-exports.SecurityError = function() { throw new DOMException(ERR.SECURITY_ERR); };
-exports.NetworkError = function() { throw new DOMException(ERR.NETWORK_ERR); };
-exports.AbortError = function() { throw new DOMException(ERR.ABORT_ERR); };
-exports.UrlMismatchError = function() { throw new DOMException(ERR.URL_MISMATCH_ERR); };
-exports.QuotaExceededError = function() { throw new DOMException(ERR.QUOTA_EXCEEDED_ERR); };
-exports.TimeoutError = function() { throw new DOMException(ERR.TIMEOUT_ERR); };
-exports.InvalidNodeTypeError = function() { throw new DOMException(ERR.INVALID_NODE_TYPE_ERR); };
-exports.DataCloneError = function() { throw new DOMException(ERR.DATA_CLONE_ERR); };
-
-exports.nyi = function(what) {
- throw new Error("NotYetImplemented " + what);
-};
-
-exports.shouldOverride = function() {
- throw new Error("Abstract function; should be overriding in subclass.");
-};
-
-exports.assert = function(expr, msg) {
- if (!expr) {
- throw new Error("Assertion failed: " + (msg || "") + "\n" + new Error().stack);
- }
-};
-
-exports.expose = function(src, c) {
- for (var n in src) {
- Object.defineProperty(c.prototype, n, { value: src[n], writable: isApiWritable });
- }
-};
-
-exports.merge = function(a, b) {
- for (var n in b) {
- a[n] = b[n];
- }
-};
-
-// Compare two nodes based on their document order. This function is intended
-// to be passed to sort(). Assumes that the array being sorted does not
-// contain duplicates. And that all nodes are connected and comparable.
-// Clever code by ppk via jeresig.
-exports.documentOrder = function(n,m) {
- /* jshint bitwise: false */
- return 3 - (n.compareDocumentPosition(m) & 6);
-};
-
-exports.toASCIILowerCase = function(s) {
- return s.replace(/[A-Z]+/g, function(c) {
- return c.toLowerCase();
- });
-};
-
-exports.toASCIIUpperCase = function(s) {
- return s.replace(/[a-z]+/g, function(c) {
- return c.toUpperCase();
- });
-};
--- a/cmd/gojafs/domino/domino-lib/xmlnames.js
+++ /dev/null
@@ -1,91 +1,0 @@
-"use strict";
-// This grammar is from the XML and XML Namespace specs. It specifies whether
-// a string (such as an element or attribute name) is a valid Name or QName.
-//
-// Name ::= NameStartChar (NameChar)*
-// NameStartChar ::= ":" | [A-Z] | "_" | [a-z] |
-// [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x2FF] |
-// [#x370-#x37D] | [#x37F-#x1FFF] |
-// [#x200C-#x200D] | [#x2070-#x218F] |
-// [#x2C00-#x2FEF] | [#x3001-#xD7FF] |
-// [#xF900-#xFDCF] | [#xFDF0-#xFFFD] |
-// [#x10000-#xEFFFF]
-//
-// NameChar ::= NameStartChar | "-" | "." | [0-9] |
-// #xB7 | [#x0300-#x036F] | [#x203F-#x2040]
-//
-// QName ::= PrefixedName| UnprefixedName
-// PrefixedName ::= Prefix ':' LocalPart
-// UnprefixedName ::= LocalPart
-// Prefix ::= NCName
-// LocalPart ::= NCName
-// NCName ::= Name - (Char* ':' Char*)
-// # An XML Name, minus the ":"
-//
-
-exports.isValidName = isValidName;
-exports.isValidQName = isValidQName;
-
-// Most names will be ASCII only. Try matching against simple regexps first
-var simplename = /^[_:A-Za-z][-.:\w]+$/;
-var simpleqname = /^([_A-Za-z][-.\w]+|[_A-Za-z][-.\w]+:[_A-Za-z][-.\w]+)$/;
-
-// If the regular expressions above fail, try more complex ones that work
-// for any identifiers using codepoints from the Unicode BMP
-var ncnamestartchars = "_A-Za-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02ff\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD";
-var ncnamechars = "-._A-Za-z0-9\u00B7\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02ff\u0300-\u037D\u037F-\u1FFF\u200C\u200D\u203f\u2040\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD";
-
-var ncname = "[" + ncnamestartchars + "][" + ncnamechars + "]*";
-var namestartchars = ncnamestartchars + ":";
-var namechars = ncnamechars + ":";
-var name = new RegExp("^[" + namestartchars + "]" + "[" + namechars + "]*$");
-var qname = new RegExp("^(" + ncname + "|" + ncname + ":" + ncname + ")$");
-
-// XML says that these characters are also legal:
-// [#x10000-#xEFFFF]. So if the patterns above fail, and the
-// target string includes surrogates, then try the following
-// patterns that allow surrogates and then run an extra validation
-// step to make sure that the surrogates are in valid pairs and in
-// the right range. Note that since the characters \uf0000 to \u1f0000
-// are not allowed, it means that the high surrogate can only go up to
-// \uDB7f instead of \uDBFF.
-var hassurrogates = /[\uD800-\uDB7F\uDC00-\uDFFF]/;
-var surrogatechars = /[\uD800-\uDB7F\uDC00-\uDFFF]/g;
-var surrogatepairs = /[\uD800-\uDB7F][\uDC00-\uDFFF]/g;
-
-// Modify the variables above to allow surrogates
-ncnamestartchars += "\uD800-\uDB7F\uDC00-\uDFFF";
-ncnamechars += "\uD800-\uDB7F\uDC00-\uDFFF";
-ncname = "[" + ncnamestartchars + "][" + ncnamechars + "]*";
-namestartchars = ncnamestartchars + ":";
-namechars = ncnamechars + ":";
-
-// Build another set of regexps that include surrogates
-var surrogatename = new RegExp("^[" + namestartchars + "]" + "[" + namechars + "]*$");
-var surrogateqname = new RegExp("^(" + ncname + "|" + ncname + ":" + ncname + ")$");
-
-function isValidName(s) {
- if (simplename.test(s)) return true; // Plain ASCII
- if (name.test(s)) return true; // Unicode BMP
-
- // Maybe the tests above failed because s includes surrogate pairs
- // Most likely, though, they failed for some more basic syntax problem
- if (!hassurrogates.test(s)) return false;
-
- // Is the string a valid name if we allow surrogates?
- if (!surrogatename.test(s)) return false;
-
- // Finally, are the surrogates all correctly paired up?
- var chars = s.match(surrogatechars), pairs = s.match(surrogatepairs);
- return pairs !== null && 2*pairs.length === chars.length;
-}
-
-function isValidQName(s) {
- if (simpleqname.test(s)) return true; // Plain ASCII
- if (qname.test(s)) return true; // Unicode BMP
-
- if (!hassurrogates.test(s)) return false;
- if (!surrogateqname.test(s)) return false;
- var chars = s.match(surrogatechars), pairs = s.match(surrogatepairs);
- return pairs !== null && 2*pairs.length === chars.length;
-}
--- a/cmd/gojafs/domino/domino.go
+++ /dev/null
@@ -1,407 +1,0 @@
-package domino
-
-import (
- "bytes"
- "embed"
- "errors"
- "fmt"
- "github.com/dop251/goja"
- "github.com/dop251/goja/parser"
- "github.com/dop251/goja_nodejs/console"
- "github.com/dop251/goja_nodejs/eventloop"
- "github.com/dop251/goja_nodejs/require"
- "github.com/psilva261/opossum/logger"
- "io/ioutil"
- "net/http"
- "os"
- "os/exec"
- "path/filepath"
- "regexp"
- "strconv"
- "strings"
- "syscall"
- "time"
-)
-
-var timeout = 60 * time.Second
-
-//go:embed domino-lib/*js
-var lib embed.FS
-
-//go:embed domintf.js
-var domIntfJs embed.FS
-
-var domIntf string
-
-func init() {
- data, err := domIntfJs.ReadFile("domintf.js")
- if err != nil {
- panic(err.Error())
- }
- domIntf = string(data)
-}
-
-type Mutation struct {
- time.Time
- Type int
- Sel string
-}
-
-type Domino struct {
- loop *eventloop.EventLoop
- html string
- outputHtml string
- domChange chan Mutation
- query func(sel, prop string) (val string, err error)
- xhrq func(req *http.Request) (resp *http.Response, err error)
-}
-
-func NewDomino(
- html string,
- xhr func(req *http.Request) (resp *http.Response, err error),
- query func(sel, prop string) (val string, err error),
-) (d *Domino) {
- d = &Domino{
- html: html,
- xhrq: xhr,
- domChange: make(chan Mutation, 100),
- query: query,
- }
- return
-}
-
-func (d *Domino) Start() {
- log.Printf("Start event loop")
- d.loop = eventloop.NewEventLoop()
-
- d.loop.Start()
- log.Printf("event loop started")
-}
-
-func (d *Domino) Stop() {
- d.loop.Stop()
-}
-
-func IntrospectError(err error, script string) {
- prefix := "Line "
- i := strings.Index(err.Error(), prefix)
- if i > 0 {
- i += len(prefix)
- s := err.Error()[i:]
- yxStart := strings.Split(s, " ")[0]
- yx := strings.Split(yxStart, ":")
- y, _ := strconv.Atoi(yx[0])
- x, _ := strconv.Atoi(yx[1])
- lines := strings.Split(script, "\n")
-
- if y-1 > len(lines)-1 {
- y = len(lines)
- }
-
- if wholeLine := lines[y-1]; len(wholeLine) > 100 {
- from := x - 50
- to := x + 50
- if from < 0 {
- from = 0
- }
- if to >= len(wholeLine) {
- to = len(wholeLine) - 1
- }
- log.Printf("the line: %v", wholeLine[from:to])
- } else {
- if y > 0 && len(lines[y-1]) < 120 {
- log.Printf("%v: %v", y-1, lines[y-1])
- }
- if y < len(lines) {
- log.Printf("%v: %v", y, lines[y])
- }
- if y+1 < len(lines) && len(lines[y+1]) < 120 {
- log.Printf("%v: %v", y+1, lines[y+1])
- }
- }
- }
-}
-
-func printCode(code string, maxWidth int) {
- if maxWidth > len(code) {
- maxWidth = len(code)
- }
- log.Infof("js code: %v", code[:maxWidth])
-}
-
-func srcLoader(fn string) ([]byte, error) {
- path := filepath.FromSlash(fn)
- if !strings.Contains(path, "domino-lib/") || !strings.HasSuffix(path, ".js") {
- return nil, require.ModuleFileDoesNotExistError
- }
- data, err := lib.ReadFile(path)
- if err != nil {
- if os.IsNotExist(err) || errors.Is(err, syscall.EISDIR) {
- err = require.ModuleFileDoesNotExistError
- } else {
- log.Errorf("srcLoader: handling of require('%v') is not implemented", fn)
- }
- }
- return data, err
-}
-
-func (d *Domino) Exec(script string, initial bool) (res string, err error) {
- r := regexp.MustCompile(`^\s*<!--`)
- rr := regexp.MustCompile(`-->\s*$`)
- script = r.ReplaceAllString(script, "//")
- script = rr.ReplaceAllString(script, "//")
- SCRIPT := domIntf + script
- if !initial {
- SCRIPT = script
- }
-
- ready := make(chan goja.Value)
- errCh := make(chan error)
- intCh := make(chan int)
- go func() {
- d.loop.RunOnLoop(func(vm *goja.Runtime) {
- log.Printf("RunOnLoop")
-
- if initial {
- vm.SetParserOptions(parser.WithDisableSourceMaps)
-
- // find domino-lib folder
- registry := require.NewRegistry(
- require.WithGlobalFolders("."),
- require.WithLoader(
- require.SourceLoader(srcLoader),
- ),
- )
-
- console.Enable(vm)
- registry.Enable(vm)
-
- type S struct {
- Buf string `json:"buf"`
- HTML string `json:"html"`
- Referrer func() string `json:"referrer"`
- Style func(string, string, string, string) string `json:"style"`
- XHR func(string, string, map[string]string, string, func(string, string)) `json:"xhr"`
- Mutated func(int, string) `json:"mutated"`
- }
-
- vm.SetFieldNameMapper(goja.TagFieldNameMapper("json", true))
- vm.Set("opossum", S{
- HTML: d.html,
- Buf: "yolo",
- Referrer: func() string { return "https://example.com" },
- Style: func(sel, pseudo, prop, prop2 string) string {
- v, err := d.query(sel, prop)
- if err != nil {
- log.Errorf("devjs: domino: query %v: %v", sel, err)
- return ""
- }
- return v
- },
- XHR: d.xhr,
- Mutated: d.mutated,
- })
- }
-
- go func() {
- for _ = range intCh {
- vm.Interrupt("halt")
- }
- }()
-
- vv, err := vm.RunString(SCRIPT)
- if err != nil {
- IntrospectError(err, script)
- errCh <- fmt.Errorf("run program: %w", err)
- } else {
- ready <- vv
- }
- })
- }()
-
- for {
- select {
- case v := <-ready:
- log.Infof("ready")
- <-time.After(10 * time.Millisecond)
- if v != nil {
- res = v.String()
- }
- goto cleanup
- case er := <-errCh:
- log.Infof("err")
- <-time.After(10 * time.Millisecond)
- err = fmt.Errorf("event loop: %w", er)
- goto cleanup
- case <-time.After(timeout):
- log.Errorf("Interrupt JS after %v", timeout)
- intCh <- 1
- }
- }
-
-cleanup:
- close(ready)
- close(errCh)
- close(intCh)
-
- return
-}
-
-func (d *Domino) Exec6(script string, initial bool) (res string, err error) {
- cmd := exec.Command("6to5")
- cmd.Stdin = strings.NewReader(script)
- var out bytes.Buffer
- cmd.Stdout = &out
- if err = cmd.Run(); err != nil {
- return "", fmt.Errorf("6to5: %w", err)
- }
- return d.Exec(out.String(), initial)
-}
-
-// CloseDoc fires DOMContentLoaded to trigger $(document).ready(..)
-func (d *Domino) CloseDoc() (err error) {
- _, err = d.Exec("if (this.document) document.close();", false)
- return
-}
-
-// TriggerClick, and return the result html
-// ...then HTML5 parse it, diff the node tree
-// (probably faster and cleaner than anything else)
-func (d *Domino) TriggerClick(selector string) (newHTML string, ok bool, err error) {
- res, err := d.Exec(`
- var sel = '`+selector+`';
- var el = document.querySelector(sel);
-
- console.log('query ' + sel);
-
- if (!el) {
- console.log('el is null/undefined');
- null;
- } else if (el._listeners && el._listeners.click) {
- var fn = el.click.bind(el);
-
- if (fn) {
- console.log(' call click handler...');
- fn();
- }
-
- !!fn;
- } else if (el.type === 'submit' || el.type === 'button') {
- let p;
- let submitted = false;
- for (p = el; p = p.parentElement; p != null) {
- if (p.tagName && p.tagName === 'FORM') {
- const event = new Event('submit');
- event.cancelable = true;
- if (p.onsubmit) p.onsubmit(event);
- if (!event.defaultPrevented) {
- p.submit();
- }
- submitted = true;
- break;
- }
- }
- submitted;
- } else {
- false;
- }
- `, false)
-
- if ok = res == "true"; ok {
- newHTML, ok, err = d.TrackChanges()
- }
-
- return
-}
-
-// Put change into html (e.g. from input field mutation)
-func (d *Domino) PutAttr(selector, attr, val string) (ok bool, err error) {
- res, err := d.Exec(`
- var sel = '`+selector+`';
- var el = document.querySelector(sel);
- el.attr('`+attr+`', '`+val+`');
- !!el;
- `, false)
-
- ok = res == "true"
-
- return
-}
-
-func (d *Domino) TrackChanges() (html string, changed bool, err error) {
-outer:
- for {
- // TODO: either add other change types like ajax begin/end or
- // just have one channel for all events worth waiting for.
- select {
- case <-d.domChange:
- changed = true
- case <-time.After(time.Second):
- break outer
- }
- }
-
- if changed {
- html, err = d.Exec("document.querySelector('html').innerHTML;", false)
- if err != nil {
- return
- }
- }
- d.outputHtml = html
- return
-}
-
-func (d *Domino) xhr(method, uri string, h map[string]string, data string, cb func(data string, err string)) {
- req, err := http.NewRequest(method /*u.String()*/, uri, strings.NewReader(data))
- if err != nil {
- cb("", err.Error())
- return
- }
- for k, v := range h {
- req.Header.Add(k, v)
- }
- go func() {
- resp, err := d.xhrq(req)
- if err != nil {
- cb("", err.Error())
- return
- }
- //defer resp.Body.Close()
- bs, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- cb("", err.Error())
- return
- }
- d.loop.RunOnLoop(func(*goja.Runtime) {
- defer func() {
- if r := recover(); r != nil {
- log.Errorf("recovered in xhr: %v", r)
- }
- }()
- cb(string(bs), "")
- })
- }()
-}
-
-func (d *Domino) mutated(t int, q string) {
- m := Mutation{
- Time: time.Now(),
- Type: t,
- Sel: q,
- }
-
- select {
- case d.domChange <- m:
- default:
- log.Printf("dom changes backlog full")
- }
-}
-
-// AJAX:
-// https://stackoverflow.com/questions/7086858/loading-ajax-app-with-jsdom
-
-// Babel on Goja:
-// https://github.com/dop251/goja/issues/5#issuecomment-259996573
-
-// Goja supports ES5.1 which is essentially JS assembly:
-// https://github.com/dop251/goja/issues/76#issuecomment-399253779
--- a/cmd/gojafs/domino/domino_test.go
+++ /dev/null
@@ -1,706 +1,0 @@
-package domino
-
-import (
- "github.com/psilva261/opossum/logger"
- "io"
- "io/ioutil"
- "net/http"
- "net/http/httptest"
- "strings"
- "testing"
- "time"
-)
-
-const simpleHTML = `
-<html>
-<body>
-<h1 id="title">Hello</h1>
-</body>
-</html>
-`
-
-func init() {
- log.Debug = true
-}
-
-func TestSimple(t *testing.T) {
- d := NewDomino(simpleHTML, nil, nil)
- d.Start()
- s := `
- var state = 'empty';
- var a = 1;
- b = 2;
- `
- _, err := d.Exec(s, true)
- if err != nil {
- t.Fatalf("%v", err)
- }
- s2 := `
- (function() {
- if (state !== 'empty') throw new Exception(state);
-
- state = a + b;
- })()
- var a = 1;
- b = 2;
- `
- _, err = d.Exec(s2, false)
- if err != nil {
- t.Fatalf("%v", err)
- }
- d.Stop()
-}
-
-func TestGlobals(t *testing.T) {
- d := NewDomino(simpleHTML, nil, nil)
- d.Start()
-}
-
-func TestTrackChanges(t *testing.T) {
- d := NewDomino(simpleHTML, nil, nil)
- d.Start()
- _, err := d.Exec(``, true)
- if err != nil {
- t.Fatalf(err.Error())
- }
- // 0th time: init
- if _, _, err = d.TrackChanges(); err != nil {
- t.Fatalf(err.Error())
- }
- // 1st time: no change
- html, changed, err := d.TrackChanges()
- if err != nil {
- t.Fatalf(err.Error())
- }
- if changed == true {
- t.Fatal()
- }
- // 2nd time: no change
- html, changed, err = d.TrackChanges()
- if err != nil {
- t.Fatalf(err.Error())
- }
- if changed == true {
- t.Fatal()
- }
- _, err = d.Exec("document.getElementById('title').innerHTML='new title'; true;", false)
- if err != nil {
- t.Fatalf(err.Error())
- }
- // 3rd time: yes change
- html, changed, err = d.TrackChanges()
- if err != nil {
- t.Fatalf(err.Error())
- }
- if html == "" {
- t.Fatalf(err.Error())
- }
- if changed == false {
- t.Fatal()
- }
- if !strings.Contains(html, "new title") {
- t.Fatalf(html)
- }
- d.Stop()
-}
-
-/*func TestWindowEqualsGlobal(t *testing.T) {
- const h = `
- <html>
- <body>
- <script>
- a = 2;
- window.b = 5;
- </script>
- <script>
- console.log('window.a=', window.a);
- console.log('wot');
- console.log('window.b=', window.b);
- console.log('wit');
- window.a++;
- b++;
- </script>
- </body>
- </html>
- `
- d := NewDomino(h)
- d.Start()
- err := d.ExecInlinedScripts()
- if err != nil {
- t.Fatalf(err.Error())
- }
- res, err := d.Export("window.a")
- if err != nil {
- t.Fatalf(err.Error())
- }
- if !strings.Contains(res, "3") {
- t.Fatalf(res)
- }
- res, err = d.Export("window.b")
- if err != nil {
- t.Fatalf(err.Error())
- }
- if !strings.Contains(res, "6") {
- t.Fatalf(res)
- }
- d.Stop()
-}*/
-
-func TestES6(t *testing.T) {
- d := NewDomino(simpleHTML, nil, nil)
- d.Start()
- script := `
- var foo = function(data={}) {}
- var h = {
- a: 1,
- b: 11
- };
- var {a, b} = h;
- `
- _, err := d.Exec6(script, true)
- if err != nil {
- t.Fatalf("%v", err)
- }
- res, err := d.Exec("a+b", false)
- t.Logf("res=%v", res)
- if err != nil {
- t.Fatalf("%v", err)
- }
- if res != "12" {
- t.Fatal()
- }
- d.Stop()
-}
-
-func TestWindowParent(t *testing.T) {
- d := NewDomino(simpleHTML, nil, nil)
- d.Start()
- script := `
- console.log('Hello!!')
- `
- _, err := d.Exec(script, true)
- if err != nil {
- t.Fatalf("%v", err)
- }
- res, err := d.Exec("window === window.parent", false)
- t.Logf("res=%v", res)
- if err != nil {
- t.Fatalf("%v", err)
- }
- if res != "true" {
- t.Fatal()
- }
- d.Stop()
-}
-
-func TestReferrer(t *testing.T) {
- d := NewDomino(simpleHTML, nil, nil)
- d.Start()
- script := `
- document.referrer;
- `
- res, err := d.Exec(script, true)
- if err != nil {
- t.Fatalf("%v", err)
- }
- t.Logf("res=%v", res)
- if res != "https://example.com" {
- t.Fatal()
- }
- d.Stop()
-}
-
-func handler(w http.ResponseWriter, r *http.Request) {
- io.WriteString(w, "<html><body>Hello World!</body></html>")
-}
-
-func xhr(req *http.Request) (resp *http.Response, err error) {
- w := httptest.NewRecorder()
- handler(w, req)
- resp = w.Result()
- return resp, nil
-}
-
-func TestXMLHttpRequest(t *testing.T) {
- d := NewDomino(simpleHTML, xhr, nil)
- d.Start()
- script := `
- var oReq = new XMLHttpRequest();
- var loaded = false;
- oReq.addEventListener("load", function() {
- loaded = true;
- });
- oReq.open("GET", "http://www.example.org/example.txt");
- oReq.send();
- `
- _, err := d.Exec(script, true)
- if err != nil {
- t.Fatalf("%v", err)
- }
- <-time.After(time.Second)
- res, err := d.Exec("oReq.responseText;", false)
- if err != nil {
- t.Fatalf("%v", err)
- }
- t.Logf("res=%v", res)
- if !strings.Contains(res, "<html") {
- t.Fatal()
- }
- d.Stop()
-}
-
-func TestJQueryAjax(t *testing.T) {
- buf, err := ioutil.ReadFile("../../../js/jquery-3.5.1.js")
- if err != nil {
- t.Fatalf("%v", err)
- }
- d := NewDomino(simpleHTML, xhr, nil)
- d.Start()
- script := `
- var res;
- $.ajax({
- url: '/',
- success: function() {
- res = 'success';
- },
- error: function() {
- res = 'err';
- }
- });
- `
- _, err = d.Exec(string(buf)+";"+script, true)
- if err != nil {
- t.Fatalf("%v", err)
- }
- if err = d.CloseDoc(); err != nil {
- t.Fatalf("%v", err)
- }
- <-time.After(time.Second)
- res, err := d.Exec("res;", false)
- if err != nil {
- t.Fatalf("%v", err)
- }
- t.Logf("res=%v", res)
- if res != "success" {
- t.Fatalf(res)
- }
- d.Stop()
-}
-
-func TestJQueryAjax182(t *testing.T) {
- buf, err := ioutil.ReadFile("../../../js/godoc/jquery-1.8.2.js")
- if err != nil {
- t.Fatalf("%v", err)
- }
- d := NewDomino(simpleHTML, xhr, nil)
- d.Start()
- script := `
- var res;
- $.ajax({
- url: '/',
- success: function() {
- res = 'success';
- },
- error: function() {
- res = 'err';
- }
- });
- `
- _, err = d.Exec(string(buf)+";"+script, true)
- if err != nil {
- t.Fatalf("%v", err)
- }
- if err = d.CloseDoc(); err != nil {
- t.Fatalf("%v", err)
- }
- <-time.After(5 * time.Second)
- res, err := d.Exec("res;", false)
- if err != nil {
- t.Fatalf("%v", err)
- }
- t.Logf("res=%v", res)
- if res != "success" {
- t.Fatalf(res)
- }
- d.Stop()
-}
-
-func TestNoJsCompatComment(t *testing.T) {
- d := NewDomino(simpleHTML, nil, nil)
- d.Start()
- script := `
-
-<!-- This is an actual comment
-
- ''.replace(/^\s*<!--/g, '');
- const a = 1;
- a + 7;
--->
- `
- res, err := d.Exec(script, true)
- if err != nil {
- t.Fatalf("%v", err)
- }
- t.Logf("res=%v", res)
- if res != "8" {
- t.Fatal()
- }
- d.Stop()
-}
-
-func TestJQuery(t *testing.T) {
- buf, err := ioutil.ReadFile("../../../js/jquery-3.5.1.js")
- if err != nil {
- t.Fatalf("%v", err)
- }
- d := NewDomino(simpleHTML, nil, nil)
- d.Start()
- script := `
- $(document).ready(function() {
- undefinedExpr
- });
- setTimeout(function() {
- console.log("ok");
- }, 1000);
- var a = 1;
- `
- _, err = d.Exec(string(buf)+";"+script, true)
- if err != nil {
- t.Fatalf("%v", err)
- }
- res, err := d.Exec("a+1", false)
- t.Logf("res=%v", res)
- if err != nil {
- t.Fatalf("%v", err)
- }
- if res != "2" {
- t.Fatal()
- }
- d.Stop()
-}
-
-func TestJQueryCss(t *testing.T) {
- buf, err := ioutil.ReadFile("../../../js/jquery-3.5.1.js")
- if err != nil {
- t.Fatalf("%v", err)
- }
- h := `
- <html>
- <body>
- <h1 id="title" style="display: inline-block;">Hello</h1>
- </body>
- </html>
- `
- q := func(sel, prop string) (val string, err error) {
- if sel != "HTML > :nth-child(2) > :nth-child(1)" {
- panic(sel)
- }
- if prop != "display" {
- panic(prop)
- }
- return "inline-block", nil
- }
- d := NewDomino(h, nil, q)
- d.Start()
- _, err = d.Exec(string(buf), true)
- if err != nil {
- t.Fatalf("%v", err)
- }
- res, err := d.Exec("$('h1').css('display')", false)
- t.Logf("res=%v", res)
- if err != nil {
- t.Fatalf("%v", err)
- }
- if res != "inline-block" {
- t.Fatal()
- }
- d.Stop()
-}
-
-func TestGodoc(t *testing.T) {
- buf, err := ioutil.ReadFile("../../../js/godoc/pkg.html")
- if err != nil {
- t.Fatalf("%v", err)
- }
- d := NewDomino(string(buf), nil, nil)
- d.Start()
- for i, fn := range []string{"initfuncs.js", "jquery-1.8.2.js", "goversion.js", "godocs.js"} {
- buf, err := ioutil.ReadFile("../../../js/godoc/" + fn)
- if err != nil {
- t.Fatalf("%v", err)
- }
- _, err = d.Exec(string(buf), i == 0)
- if err != nil {
- t.Fatalf("%v", err)
- }
- }
- d.Stop()
-}
-
-func TestGoplayground(t *testing.T) {
- buf, err := ioutil.ReadFile("../../../js/godoc/golang.html")
- if err != nil {
- t.Fatalf("%v", err)
- }
- d := NewDomino(string(buf), nil, nil)
- d.Start()
- for i, fn := range []string{"initfuncs.js", "jquery-1.8.2.js", "playground.js", "goversion.js", "godocs.js", "golang.js"} {
- buf, err := ioutil.ReadFile("../../../js/godoc/" + fn)
- if err != nil {
- t.Fatalf("%v", err)
- }
- _, err = d.Exec(string(buf), i == 0)
- if err != nil {
- t.Fatalf("%v", err)
- }
- }
- res, err := d.Exec("window.playground", false)
- if err != nil {
- t.Fatalf("%v", err)
- }
- if !strings.Contains(res, "function playground(opts) {") {
- t.Fatalf("%v", res)
- }
-
- d.Stop()
-}
-
-func TestJqueryUI(t *testing.T) {
- buf, err := ioutil.ReadFile("../../../js/jqueryui/tabs.html")
- if err != nil {
- t.Fatalf("%v", err)
- }
- d := NewDomino(string(buf), nil, nil)
- d.Start()
- script := `
- Object.assign(this, window);
- `
- _ = script
- for i, fn := range []string{"jquery-1.12.4.js", "jquery-ui.js", "tabs.js"} {
- buf, err := ioutil.ReadFile("../../../js/jqueryui/" + fn)
- if err != nil {
- t.Fatalf("%v", err)
- }
- _, err = d.Exec(string(buf), i == 0)
- if err != nil {
- t.Fatalf("%v", err)
- }
- }
- d.Stop()
-}
-
-func TestRun(t *testing.T) {
- jQuery, err := ioutil.ReadFile("../../../js/jquery-3.5.1.js")
- if err != nil {
- t.Fatalf("%v", err)
- }
- SCRIPT := string(jQuery) + `
- setTimeout(function() {
- var h = document.querySelector('html');
- console.log(h.innerHTML);
- }, 1000);
- Object.assign(this, window);
- $(document).ready(function() {
- console.log('READDDYYYYY!!!!!!!');
- });
- console.log(window.location.href);
- `
- d := NewDomino(simpleHTML, nil, nil)
- d.Start()
- _, err = d.Exec(SCRIPT, true)
- if err != nil {
- t.Fatalf(err.Error())
- }
-
- res, err := d.Exec("$('h1').html()", false)
- if err != nil {
- t.Fatalf(err.Error())
- }
- if res != "Hello" {
- t.Fatalf(res)
- }
- d.Stop()
-}
-
-func TestTriggerClick(t *testing.T) {
- jQuery, err := ioutil.ReadFile("../../../js/jquery-3.5.1.js")
- if err != nil {
- t.Fatalf("%v", err)
- }
- SCRIPT := string(jQuery) + `
- var clicked = false;
- $(document).ready(function() {
- $('h1').click(function() {
- clicked = true;
- });
- });
- `
- d := NewDomino(simpleHTML, nil, nil)
- d.Start()
- _, err = d.Exec(SCRIPT, true)
- if err != nil {
- t.Fatalf(err.Error())
- }
- d.CloseDoc()
-
- res, err := d.Exec("$('h1').html()", false)
- if err != nil {
- t.Fatalf(err.Error())
- }
- if res != "Hello" {
- t.Fatalf(res)
- }
-
- if _, _, err = d.TrackChanges(); err != nil {
- t.Fatalf(err.Error())
- }
- _, changed, err := d.TriggerClick("h1")
- if err != nil {
- t.Fatalf(err.Error())
- }
- if changed {
- t.Fatal()
- }
- res, err = d.Exec("clicked", false)
- if err != nil {
- t.Fatalf(err.Error())
- }
- if res != "true" {
- t.Fatalf(res)
- }
- d.Stop()
-}
-
-func TestTriggerClickSubmit(t *testing.T) {
- for _, sel := range []string{"#btn", "#submit"} {
- jQuery, err := ioutil.ReadFile("../../../js/jquery-3.5.1.js")
- if err != nil {
- t.Fatalf("%v", err)
- }
- h := `
- <html>
- <body>
- <h1 id="title" style="display: inline-block;">Hello</h1>
- <form id="the-form">
- <input type="text" id="info">
- <input type="submit" id="submit">Submit</button>
- <button type="button" id="btn">Submit</button>
- </form>
- </body>
- </html>
- `
- SCRIPT := string(jQuery) + `
- var clicked = false;
- const form = document.getElementById('the-form');
- form.onsubmit = function(event) {
- clicked = true;
- event.preventDefault();
- };
- `
- d := NewDomino(h, nil, nil)
- d.Start()
- _, err = d.Exec(SCRIPT, true)
- if err != nil {
- t.Fatalf(err.Error())
- }
- d.CloseDoc()
-
- res, err := d.Exec("$('button').html()", false)
- if err != nil {
- t.Fatalf(err.Error())
- }
- if res != "Submit" {
- t.Fatalf(res)
- }
-
- if _, _, err = d.TrackChanges(); err != nil {
- t.Fatalf(err.Error())
- }
- _, changed, err := d.TriggerClick(sel)
- if err != nil {
- t.Fatalf(err.Error())
- }
- if changed {
- t.Fatal()
- }
- res, err = d.Exec("clicked", false)
- if err != nil {
- t.Fatalf(err.Error())
- }
- if res != "true" {
- t.Fatalf(res)
- }
- d.Stop()
- }
-}
-
-func TestDomChanged(t *testing.T) {
- jQuery, err := ioutil.ReadFile("../../../js/jquery-3.5.1.js")
- if err != nil {
- t.Fatalf("%v", err)
- }
- //t.Parallel()
- SCRIPT := string(jQuery) + `
- setTimeout(function() {
- var h = document.querySelector('html');
- console.log(h.innerHTML);
- }, 1000);
- Object.assign(this, window);
- $(document).ready(function() {
- console.log('READDDYYYYY!!!!!!!');
- });
- `
- d := NewDomino(simpleHTML, nil, nil)
- d.Start()
- _, err = d.Exec(SCRIPT, true)
- if err != nil {
- t.Fatalf(err.Error())
- }
-
- res, err := d.Exec("$('h1').html()", false)
- if err != nil {
- t.Fatalf(err.Error())
- }
- _ = res
- res, err = d.Exec("$('h1').html('minor updates :-)'); $('h1').html();", false)
- if err != nil {
- t.Fatalf(err.Error())
- }
- t.Logf("new res=%v", res)
- d.Stop()
-}
-
-func TestMutationEvents(t *testing.T) {
- buf, err := ioutil.ReadFile("../../../js/jquery-3.5.1.js")
- if err != nil {
- t.Fatalf("%v", err)
- }
- q := func(sel, prop string) (val string, err error) {
- if sel != "HTML > :nth-child(2) > :nth-child(1)" {
- panic(sel)
- }
- if prop != "display" {
- panic(prop)
- }
- return "inline-block", nil
- }
- d := NewDomino(simpleHTML, nil, q)
- d.Start()
- script := `
- $('h1').hide();
- $('h1').show();
- `
- _, err = d.Exec(string(buf)+";"+script, true)
- if err != nil {
- t.Fatalf("%v", err)
- }
- if err = d.CloseDoc(); err != nil {
- t.Fatalf("%v", err)
- }
- res, err := d.Exec("$('h1').attr('style')", false)
- t.Logf("res=%v", res)
- if err != nil {
- t.Fatalf("%v", err)
- }
- d.Stop()
-}
--- a/cmd/gojafs/domino/domintf.js
+++ /dev/null
@@ -1,208 +1,0 @@
-global = {};
-//global.__domino_frozen__ = true; // Must precede any require('domino')
-var domino = require('domino-lib/index');
-
-Object.assign(this, domino.createWindow(opossum.html, 'http://example.com'));
-window = this;
-window.self = window;
-window.parent = window;
-window.top = window;
-window.history = {
- replaceState: function() {}
-};
-window.location.href = 'http://example.com';
-window.screen = {
- width: 1280,
- height: 1024
-};
-window.screenX = 0;
-window.screenY = 25;
-window.getComputedStyle = function(el, pseudo) {
- this.el = el;
- this.getPropertyValue = function(prop) {
- return opossum.style(___fq('', el), pseudo, prop, arguments[2]);
- };
- return this;
-};
-(function() {
- var utils = require('domino-lib/utils');
- utils.merge(window, domino.impl);
-})()
-
-location = window.location;
-navigator = {
- platform: 'plan9(port)',
- userAgent: 'opossum'
-};
-Element.prototype.getClientRects = function() { /* I'm a stub */ return []; }
-
-document._setMutationHandler(function(a) {
- // a provides attributes type, target and node or attr
- // (cf Object.keys(a))
- opossum.mutated(a.type, ___fq('yolo', a.target));
-});
-
-___opossumSubmit = function(a, b, c) {
- if (this.tagName === 'BUTTON' || this.tagName === 'INPUT') {
- let p;
- for (p = el; p = p.parentElement; p != null) {
- if (p.tagName === 'FORM') {
- if (p.onsubmit) p.onsubmit()
- break;
- }
- }
- }
-}
-
-addEventListener = function() {};
-removeEventListener = function() {};
-
-function XMLHttpRequest() {
- var _method, _uri;
- var h = {};
- var ls = {};
-
- this.readyState = 0;
-
- var cb = function(data, err) {
- if (data !== '') {
- this.responseText = data;
- this.readyState = 4;
- this.state = 200;
- this.status = 200;
- if (ls['load']) ls['load'].bind(this)();
- if (this.onload) this.onload.bind(this)();
-
- if (this.onreadystatechange) this.onreadystatechange.bind(this)();
- }
- }.bind(this);
-
- this.addEventListener = function(k, fn) {
- ls[k] = fn;
- };
- this.open = function(method, uri) {
- _method = method;
- _uri = uri;
- };
- this.setRequestHeader = function(k, v) {
- h[k] = v;
- };
- this.send = function(data) {
- opossum.xhr(_method, _uri, h, data, cb);
- this.readyState = 2;
- };
- this.getAllResponseHeaders = function() {
- return '';
- };
-}
-
-var ___fq;
-___fq = function(pre, el) {
- var i, p;
-
- if (!el) {
- return undefined;
- }
- if (el.tagName === 'BODY') {
- return '/0';
- }
- p = el.parentElement;
-
- if (p) {
- for (i = 0; i < p.children.length; i++) {
- if (p.children[i] === el) {
- return ___fq('', p) + '/' + i;
- }
- }
- }
-};
-
-// https://developer.mozilla.org/en-US/docs/Web/API/TextEncoder
-// CC0
-if (typeof TextEncoder === "undefined") {
- TextEncoder=function TextEncoder(){};
- TextEncoder.prototype.encode = function encode(str) {
- "use strict";
- var Len = str.length, resPos = -1;
- // The Uint8Array's length must be at least 3x the length of the string because an invalid UTF-16
- // takes up the equivelent space of 3 UTF-8 characters to encode it properly. However, Array's
- // have an auto expanding length and 1.5x should be just the right balance for most uses.
- var resArr = typeof Uint8Array === "undefined" ? new Array(Len * 1.5) : new Uint8Array(Len * 3);
- for (var point=0, nextcode=0, i = 0; i !== Len; ) {
- point = str.charCodeAt(i), i += 1;
- if (point >= 0xD800 && point <= 0xDBFF) {
- if (i === Len) {
- resArr[resPos += 1] = 0xef/*0b11101111*/; resArr[resPos += 1] = 0xbf/*0b10111111*/;
- resArr[resPos += 1] = 0xbd/*0b10111101*/; break;
- }
- // https://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
- nextcode = str.charCodeAt(i);
- if (nextcode >= 0xDC00 && nextcode <= 0xDFFF) {
- point = (point - 0xD800) * 0x400 + nextcode - 0xDC00 + 0x10000;
- i += 1;
- if (point > 0xffff) {
- resArr[resPos += 1] = (0x1e/*0b11110*/<<3) | (point>>>18);
- resArr[resPos += 1] = (0x2/*0b10*/<<6) | ((point>>>12)&0x3f/*0b00111111*/);
- resArr[resPos += 1] = (0x2/*0b10*/<<6) | ((point>>>6)&0x3f/*0b00111111*/);
- resArr[resPos += 1] = (0x2/*0b10*/<<6) | (point&0x3f/*0b00111111*/);
- continue;
- }
- } else {
- resArr[resPos += 1] = 0xef/*0b11101111*/; resArr[resPos += 1] = 0xbf/*0b10111111*/;
- resArr[resPos += 1] = 0xbd/*0b10111101*/; continue;
- }
- }
- if (point <= 0x007f) {
- resArr[resPos += 1] = (0x0/*0b0*/<<7) | point;
- } else if (point <= 0x07ff) {
- resArr[resPos += 1] = (0x6/*0b110*/<<5) | (point>>>6);
- resArr[resPos += 1] = (0x2/*0b10*/<<6) | (point&0x3f/*0b00111111*/);
- } else {
- resArr[resPos += 1] = (0xe/*0b1110*/<<4) | (point>>>12);
- resArr[resPos += 1] = (0x2/*0b10*/<<6) | ((point>>>6)&0x3f/*0b00111111*/);
- resArr[resPos += 1] = (0x2/*0b10*/<<6) | (point&0x3f/*0b00111111*/);
- }
- }
- if (typeof Uint8Array !== "undefined") return resArr.subarray(0, resPos + 1);
- // else // IE 6-9
- resArr.length = resPos + 1; // trim off extra weight
- return resArr;
- };
- TextEncoder.prototype.toString = function(){return "[object TextEncoder]"};
- try { // Object.defineProperty only works on DOM prototypes in IE8
- Object.defineProperty(TextEncoder.prototype,"encoding",{
- get:function(){if(TextEncoder.prototype.isPrototypeOf(this)) return"utf-8";
- else throw TypeError("Illegal invocation");}
- });
- } catch(e) { /*IE6-8 fallback*/ TextEncoder.prototype.encoding = "utf-8"; }
- if(typeof Symbol!=="undefined")TextEncoder.prototype[Symbol.toStringTag]="TextEncoder";
-}
-
-function LocalStorage() {
- var data = {};
- this.setItem = function(id, val) {
- return data[id] = String(val);
- };
- this.getItem = function(id) {
- return data.hasOwnProperty(id) ? data[id] : undefined;
- };
- this.removeItem = function(id) {
- return delete data[id];
- };
- this.clear = function() {
- return data = {};
- };
-}
-window.localStorage = new LocalStorage();
-
-const imageHandler = {
- construct(target, args) {
- var el = document.createElement('img');
-
- if (args.length >= 1) el.width = args[0];
- if (args.length >= 2) el.height = args[1];
-
- return el;
- }
-};
-const Image = new Proxy(HTMLImageElement, imageHandler);
--- a/cmd/gojafs/main.go
+++ /dev/null
@@ -1,215 +1,0 @@
-// js package as separate program (very wip)
-package main
-
-import (
- "bufio"
- "fmt"
- "github.com/knusbaum/go9p/fs"
- "github.com/psilva261/opossum"
- "github.com/psilva261/opossum/cmd/gojafs/domino"
- "github.com/psilva261/opossum/logger"
- "io"
- "net"
- "net/http"
- "os"
- "os/user"
- "strings"
- "sync"
-)
-
-var (
- d *domino.Domino
- service string
- mtpt string
- htm string
- js []string
- mu sync.Mutex
-)
-
-func init() {
- log.SetQuiet()
-}
-
-func usage() {
- log.Printf("usage: gojafs [-s service] [-m mtpt] [-h htmlfile jsfile1 [jsfile2] [..]]")
- os.Exit(1)
-}
-
-func Main(r io.Reader, w io.Writer) (err error) {
- u, err := user.Current()
- if err != nil {
- return fmt.Errorf("get user: %v", err)
- }
- un := u.Username
- gn, err := opossum.Group(u)
- if err != nil {
- return fmt.Errorf("get group: %v", err)
- }
-
- gojafs, root := fs.NewFS(un, gn, 0500)
- c := fs.NewListenFile(gojafs.NewStat("ctl", un, gn, 0600))
- root.AddChild(c)
- lctl := (*fs.ListenFileListener)(c)
- go Ctl(lctl)
- log.Infof("post fs...\n")
- return post(gojafs.Server())
-}
-
-func Ctl(lctl *fs.ListenFileListener) {
- for {
- conn, err := lctl.Accept()
- if err != nil {
- log.Errorf("accept: %v", err)
- continue
- }
- go ctl(conn)
- }
-}
-
-func ctl(conn net.Conn) {
- r := bufio.NewReader(conn)
- w := bufio.NewWriter(conn)
- defer conn.Close()
-
- l, err := r.ReadString('\n')
- if err != nil {
- log.Errorf("gojafs: read string: %v", err)
- return
- }
- l = strings.TrimSpace(l)
-
- mu.Lock()
- defer mu.Unlock()
-
- switch l {
- case "start":
- d = domino.NewDomino(htm, xhr, query)
- d.Start()
- initialized := false
- for _, s := range js {
- if _, err := d.Exec(s, !initialized); err != nil {
- if strings.Contains(err.Error(), "halt at") {
- log.Errorf("execution halted: %v", err)
- return
- }
- log.Printf("exec <script>: %v", err)
- }
- initialized = true
- }
- if err := d.CloseDoc(); err != nil {
- log.Errorf("close doc: %v", err)
- return
- }
- resHtm, changed, err := d.TrackChanges()
- if err != nil {
- log.Errorf("track changes: %v", err)
- return
- }
- log.Printf("gojafs: processJS: changed = %v", changed)
- if changed {
- w.WriteString(resHtm)
- w.Flush()
- }
- case "stop":
- if d != nil {
- d.Stop()
- d = nil
- }
- case "click":
- sel, err := r.ReadString('\n')
- if err != nil {
- log.Errorf("gojafs: click: read string: %v", err)
- return
- }
- sel = strings.TrimSpace(sel)
- resHtm, changed, err := d.TriggerClick(sel)
- if err != nil {
- log.Errorf("track changes: %v", err)
- return
- }
- log.Printf("gojafs: processJS: changed = %v", changed)
- if changed {
- w.WriteString(resHtm)
- w.Flush()
- }
- default:
- log.Errorf("unknown cmd")
- }
-}
-
-func query(sel, prop string) (val string, err error) {
- log.Infof("gojajs: query: sel=%+v, prop=%+v\n", sel, prop)
- fn := sel+"/style/"+prop
- rwc, err := open(fn)
- if err != nil {
- return "", fmt.Errorf("open %v: %v", fn, err)
- }
- defer rwc.Close()
- bs, err := io.ReadAll(rwc)
- val = string(bs)
- return
-}
-
-func xhr(req *http.Request) (resp *http.Response, err error) {
- rwc, err := open("xhr")
- if err != nil {
- return nil, fmt.Errorf("open xhr: %w", err)
- }
- // defer rwc.Close()
- if err := req.Write(rwc); err != nil {
- return nil, fmt.Errorf("write: %v", err)
- }
- r := bufio.NewReader(rwc)
- if resp, err = http.ReadResponse(r, req); err != nil {
- return nil, fmt.Errorf("read: %v", err)
- }
- return
-}
-
-func main() {
- args := os.Args[1:]
- if len(args) == 0 {
- usage()
- }
-
- htmlfile := ""
- jsfiles := make([]string, 0, len(args))
-
- for len(args) > 0 {
- switch args[0] {
- case "-s":
- service, args = args[1], args[2:]
- case "-h":
- htmlfile, args = args[1], args[2:]
- default:
- var jsfile string
- jsfile, args = args[0], args[1:]
- jsfiles = append(jsfiles, jsfile)
- }
- }
-
- js = make([]string, 0, len(jsfiles))
- if htmlfile != "" {
- b, err := os.ReadFile(htmlfile)
- if err != nil {
- log.Fatalf(err.Error())
- }
- htm = string(b)
- }
- for _, jsfile := range jsfiles {
- b, err := os.ReadFile(jsfile)
- if err != nil {
- log.Fatalf(err.Error())
- }
- js = append(js, string(b))
- }
-
- if err := Init(); err != nil {
- log.Fatalf("Init: %+v", err)
- }
-
- if err := Main(os.Stdin, os.Stdout); err != nil {
- log.Fatalf("Main: %+v", err)
- }
- select{}
-}
--- a/cmd/gojafs/main_plan9.go
+++ /dev/null
@@ -1,64 +1,0 @@
-package main
-
-import (
- "fmt"
- "github.com/knusbaum/go9p"
- "github.com/psilva261/opossum/logger"
- "io"
- "os"
- "syscall"
-)
-
-func Init() (err error) {
- mtpt = "/mnt/opossum"
- if htm != "" || len(js) > 0 {
- log.Printf("not loading htm/js from mtpt")
- return
- }
- bs, err := os.ReadFile(mtpt + "/html")
- if err != nil {
- return
- }
- htm = string(bs)
- ds, err := os.ReadDir(mtpt + "/js")
- if err != nil {
- return
- }
- for i := 0; i < len(ds); i++ {
- fn := fmt.Sprintf(mtpt+"/js/%v.js", i)
- log.Infof("fn=%v", fn)
- bs, err := os.ReadFile(fn)
- if err != nil {
- return fmt.Errorf("read all: %w", err)
- }
- js = append(js, string(bs))
- }
- return
-}
-
-func open(fn string) (rwc io.ReadWriteCloser, err error) {
- return os.OpenFile(mtpt+"/"+fn, os.O_RDWR, 0600)
-}
-
-func post(srv go9p.Srv) (err error) {
- f1, f2, err := os.Pipe()
- if err != nil {
- return fmt.Errorf("pipe: %w", err)
- }
-
- go func() {
- err = go9p.ServeReadWriter(f1, f1, srv)
- if err != nil {
- log.Errorf("serve rw: %v", err)
- }
- }()
-
- if err = syscall.Mount(int(f2.Fd()), -1, "/mnt/goja", syscall.MCREATE, ""); err != nil {
- return fmt.Errorf("mount: %w", err)
- }
- return
-}
-
-func callGojaCtl() (rwc io.ReadWriteCloser, err error) {
- return os.OpenFile("/mnt/goja/ctl", os.O_RDWR, 0600)
-}
--- a/cmd/gojafs/main_test.go
+++ /dev/null
@@ -1,69 +1,0 @@
-package main
-
-import (
- "bufio"
- "bytes"
- "io"
- "net"
- "strings"
- "testing"
-)
-
-func call(fn, cmd string, args ...string) (resp string, err error) {
- conn, rwc := net.Pipe()
- go ctl(conn)
- defer rwc.Close()
- rwc.Write([]byte(cmd + "\n"))
- for _, arg := range args {
- rwc.Write([]byte(arg + "\n"))
- }
- r := bufio.NewReader(rwc)
- b := bytes.NewBuffer([]byte{})
- _, err = io.Copy(b, r)
- /*if !strings.Contains(err.Error(), io.ErrClosedPipe.Error()) {
- return "", fmt.Errorf("unexpected error: %v", err)
- }*/
- return b.String(), nil
-}
-
-func TestMain(t *testing.T) {
- htm = "<html><h1 id=title>hello</h1></html>"
- js = []string{
- "document.getElementById('title').innerHTML='world'",
- }
- t.Logf("call start...")
- resp, err := call("ctl", "start")
- if err != nil {
- t.Fatalf("%v", err)
- }
- t.Logf("%v", resp)
- if !strings.Contains(resp, `<h1 id="title">world</h1>`) {
- t.Fail()
- }
-}
-
-func TestClick(t *testing.T) {
- htm = "<html><h1 id=title>hello</h1></html>"
- js = []string{
- `var c = 1;
- document.getElementById('title').addEventListener('click', function(event) {
- c = 3;
- });`,
- }
- _, err := call("ctl", "start")
- if err != nil {
- t.Fatalf("%v", err)
- }
- _, err = call("ctl", "click", "#title")
- if err != nil {
- t.Fatalf("%v", err)
- }
- resp, err := d.Exec("c", false)
- if err != nil {
- t.Fatalf("%v", err)
- }
- t.Logf("%v", resp)
- if resp != "3" {
- t.Fail()
- }
-}
--- a/cmd/gojafs/main_unix.go
+++ /dev/null
@@ -1,86 +1,0 @@
-//go:build !plan9
-
-package main
-
-import (
- "9fans.net/go/plan9"
- "9fans.net/go/plan9/client"
- "fmt"
- "github.com/knusbaum/go9p"
- "github.com/psilva261/opossum/logger"
- "io"
- "os/user"
-)
-
-var fsys *client.Fsys
-
-func Init() (err error) {
- log.Infof("Init...")
- conn, err := client.DialService("opossum")
- if err != nil {
- log.Fatalf("dial: %v", err)
- }
- u, err := user.Current()
- if err != nil {
- return
- }
- un := u.Username
- fsys, err = conn.Attach(nil, un, "")
- if err != nil {
- log.Fatalf("attach: %v", err)
- }
- if htm != "" || len(js) > 0 {
- log.Infof("not loading htm/js from service")
- return
- }
- log.Infof("open html...")
- fid, err := fsys.Open("html", plan9.OREAD)
- if err != nil {
- return
- }
- defer fid.Close()
- bs, err := io.ReadAll(fid)
- if err != nil {
- return
- }
- htm = string(bs)
- log.Infof("htm: %v", htm)
- log.Infof("open js...")
- dfid, err := fsys.Open("js", plan9.OREAD)
- if err != nil {
- return
- }
- defer dfid.Close()
- ds, err := dfid.Dirreadall()
- if err != nil {
- return
- }
- log.Infof("ds=%+v", ds)
- for i := 0; i < len(ds); i++ {
- fn := fmt.Sprintf("js/%v.js", i)
- log.Infof("fn=%v", fn)
- fid, err := fsys.Open(fn, plan9.OREAD)
- if err != nil {
- return fmt.Errorf("open: %w", err)
- }
- bs, err := io.ReadAll(fid)
- if err != nil {
- fid.Close()
- return fmt.Errorf("read all: %w", err)
- }
- js = append(js, string(bs))
- fid.Close()
- }
- return
-}
-
-func open(fn string) (rwc io.ReadWriteCloser, err error) {
- return fsys.Open(fn, plan9.ORDWR)
-}
-
-func post(srv go9p.Srv) (err error) {
- if service == "" {
- return fmt.Errorf("no service specified")
- }
- return go9p.PostSrv(service, srv)
-}
--- a/go.mod
+++ b/go.mod
@@ -20,8 +20,6 @@
9fans.net/go v0.0.2
github.com/andybalholm/cascadia v1.1.0
github.com/chris-ramon/douceur v0.2.1-0.20160603235419-f3463056cd52
- github.com/dop251/goja v0.0.0-20210810150349-acd0507c3d6f
- github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7
github.com/gorilla/css v1.0.0 // indirect
github.com/knusbaum/go9p v1.18.0
github.com/mjl-/duit v0.0.0-20200330125617-580cb0b2843f
@@ -34,8 +32,7 @@
require (
github.com/Plan9-Archive/libauth v0.0.0-20180917063427-d1ca9e94969d // indirect
- github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 // indirect
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 // indirect
github.com/fhs/mux9p v0.3.1 // indirect
- github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect
+ gopkg.in/yaml.v2 v2.4.0 // indirect
)
--- a/go.sum
+++ b/go.sum
@@ -4,29 +4,16 @@
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
github.com/chris-ramon/douceur v0.2.1-0.20160603235419-f3463056cd52 h1:xJWyi77j4VQwdeo6bO3wQSQ7o7yVwEM0ZvwXpyKHZZ8=
github.com/chris-ramon/douceur v0.2.1-0.20160603235419-f3463056cd52/go.mod h1:wDW5xjJdeoMm1mRt4sD4c/LbF/mWdEpRXQKjTR8nIBE=
-github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91 h1:Izz0+t1Z5nI16/II7vuEo/nHjodOg0p7+OiDpjX5t1E=
-github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
-github.com/dop251/goja v0.0.0-20210810150349-acd0507c3d6f h1:mVrhVJhSSVE4RGV9PLwRsIQ1e6o0sGg0jim4Vj6OPs0=
-github.com/dop251/goja v0.0.0-20210810150349-acd0507c3d6f/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk=
-github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7 h1:tYwu/z8Y0NkkzGEh3z21mSWggMg4LwLRFucLS7TjARg=
-github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y=
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21 h1:OJyUGMJTzHTd1XQp98QTaHernxMYzRaOasRir9hUlFQ=
github.com/emersion/go-sasl v0.0.0-20200509203442-7bfe0ed36a21/go.mod h1:iL2twTeMvZnrg54ZoPDNfJaJaqy0xIQFuBdrLsmspwQ=
github.com/fhs/mux9p v0.3.1 h1:x1UswUWZoA9vrA02jfisndCq3xQm+wrQUxUt5N99E08=
github.com/fhs/mux9p v0.3.1/go.mod h1:F4hwdenmit0WDoNVT2VMWlLJrBVCp/8UhzJa7scfjEQ=
-github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU=
-github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg=
github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
github.com/knusbaum/go9p v1.18.0 h1:/Y67RNvNKX1ZV1IOdnO1lIetiF0X+CumOyvEc0011GI=
github.com/knusbaum/go9p v1.18.0/go.mod h1:HtMoJKqZUe1Oqag5uJqG5RKQ9gWPSP+wolsnLLv44r8=
-github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
-github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
-github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/psilva261/duit v0.0.0-20210802155600-7e8fedefa7ba h1:p8M5yp22QzefbIU3xGERHYnGxlfkcjWV6dh62xIO0U4=
@@ -51,12 +38,10 @@
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
--- a/nodes/experimental_test.go
+++ b/nodes/experimental_test.go
@@ -1,6 +1,7 @@
package nodes
import (
+ "github.com/psilva261/opossum"
"github.com/psilva261/opossum/style"
"golang.org/x/net/html"
"strings"
@@ -27,7 +28,7 @@
p := nt.Children[0].Children[1].Children[0]
a := p.Children[2]
fmt.Printf("%v\n", a.Data())
- if p, _ := a.Path(); p != PathPrefix+"/0/1/0/2" {
+ if p, _ := a.Path(); p != opossum.PathPrefix+"/0/1/0/2" {
t.Fatalf("%v", p)
}
}
--- a/package.rc
+++ b/package.rc
@@ -18,9 +18,9 @@
cd cmd/opossum
go build -ldflags '-s -w' -o $name
cd ../..
- cd cmd/gojafs
+ cd ../gojafs/cmd/gojafs
go build -ldflags '-s -w' -o gojafs
- cd ../..
+ cd ../../../opossum
mv cmd/opossum/$name cmd/gojafs/gojafs ./$name/
cp README.md ./$name/
cp opossum.jpg ./$name/