зеркало из https://github.com/mozilla/slowparse.git
testpage back up
This commit is contained in:
Родитель
a3c7c26966
Коммит
984f829af5
24
index.html
24
index.html
|
@ -2,6 +2,7 @@
|
|||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Slowparse, a friendlier HTML5 parser</title>
|
||||
<link rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
|
@ -9,8 +10,25 @@
|
|||
</header>
|
||||
|
||||
<main>
|
||||
<p>Please see the <a href="http://github.com/mozilla/slowparse">github repository</a> for the README.md documentation.</p>
|
||||
<p>For the locale strings used by Slowparse, <a href="./locale">click here</a>.</p>
|
||||
</main>
|
||||
<textarea class="text pane">
|
||||
<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
</textarea>
|
||||
<textarea class="error pane" readonly></textarea>
|
||||
<div class="preview pane"></div>
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>Please see the <a href="http://github.com/mozilla/slowparse">github repository</a> for the README.md documentation.</p>
|
||||
<p>For the locale strings used by Slowparse, <a href="./locale">click here</a>.</p>
|
||||
</footer>
|
||||
|
||||
<script src="slowparse.js"></script>
|
||||
<script src="index.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
186
index.js
186
index.js
|
@ -1,130 +1,82 @@
|
|||
// Slowparse is a token stream parser for HTML and CSS text,
|
||||
// recording regions of interest during the parse run and
|
||||
// signaling any errors detected accompanied by relevant
|
||||
// regions in the text stream, to make debugging easy. Each
|
||||
// error type is documented in the [error specification][].
|
||||
//
|
||||
// Slowparse also builds a DOM as it goes, attaching metadata
|
||||
// to each node build that points to where it came from in
|
||||
// the original source.
|
||||
//
|
||||
// For more information on the rationale behind Slowparse, as
|
||||
// well as its design goals, see the [README][].
|
||||
//
|
||||
// If [RequireJS] is detected, this file is defined as a module via
|
||||
// `define()`. Otherwise, a global called `Slowparse` is exposed.
|
||||
//
|
||||
// ## Implementation
|
||||
//
|
||||
// Slowparse is effectively a finite state machine for
|
||||
// HTML and CSS strings, and will switch between the HTML
|
||||
// and CSS parsers while maintaining a single token stream.
|
||||
//
|
||||
// [RequireJS]: http://requirejs.org/
|
||||
// [error specification]: spec/
|
||||
// [README]: https://github.com/mozilla/slowparse#readme
|
||||
(function() {
|
||||
"use strict";
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", "locale/en_US.json", true);
|
||||
xhr.onreadystatechange = function() {
|
||||
if(xhr.readyState !== 4 || (xhr.status !== 0 && xhr.status !== 200)) return;
|
||||
|
||||
var Stream = require("./src/Stream");
|
||||
var CSSParser = require("./src/CSSParser");
|
||||
var HTMLParser = require("./src/HTMLParser");
|
||||
var DOMBuilder = require("./src/DOMBuilder");
|
||||
var strings = xhr.responseText;
|
||||
var stringmap = JSON.parse(strings);
|
||||
|
||||
// ### Exported Symbols
|
||||
//
|
||||
// `Slowparse` is the object that holds all exported symbols from
|
||||
// this library.
|
||||
var Slowparse = {
|
||||
// We export our list of recognized HTML elements and CSS properties
|
||||
// for clients to use if needed.
|
||||
HTML_ELEMENT_NAMES: HTMLParser.prototype.voidHtmlElements.concat(
|
||||
HTMLParser.prototype.htmlElements.concat(
|
||||
HTMLParser.prototype.obsoleteHtmlElements)),
|
||||
CSS_PROPERTY_NAMES: CSSParser.prototype.cssProperties,
|
||||
var input = document.querySelector(".text.pane"),
|
||||
errors = document.querySelector(".error.pane"),
|
||||
preview = document.querySelector(".preview.pane");
|
||||
|
||||
// We also export a few internal symbols for use by Slowparse's
|
||||
// testing suite.
|
||||
replaceEntityRefs: HTMLParser.replaceEntityRefs,
|
||||
Stream: Stream,
|
||||
var frame = document.createElement("iframe");
|
||||
preview.innerHTML = "";
|
||||
preview.appendChild(frame);
|
||||
var fdoc = frame.contentDocument;
|
||||
|
||||
// `Slowparse.HTML()` is the primary function we export. Given
|
||||
// a DOM document object (or a DOMBuilder instance) and a string
|
||||
// of HTML, we return an object with the following keys:
|
||||
//
|
||||
// * `document` is a DOM document fragment containing the DOM of
|
||||
// the parsed HTML. If an error occurred while parsing, this
|
||||
// document is incomplete, and represents what was built before
|
||||
// the error was encountered.
|
||||
//
|
||||
// * `error` is a JSON-serializable object representing any error
|
||||
// that occurred while parsing. If no errors occurred while parsing,
|
||||
// its value is `null`. For a list of the types of errors that
|
||||
// can be returned, see the [error specification][].
|
||||
//
|
||||
// An array of error detector functions can also be passed as a
|
||||
// third argument to this function. An error detector function takes
|
||||
// the HTML and generated document fragment as arguments and returns
|
||||
// an error object if an error is detected, or `undefined` otherwise.
|
||||
// This can be used for further error checking on the parsed document.
|
||||
//
|
||||
// [error specification]: spec/
|
||||
HTML: function(document, html, options) {
|
||||
options = options || {};
|
||||
var stream = new Stream(html),
|
||||
domBuilder,
|
||||
parser,
|
||||
warnings = null,
|
||||
error = null,
|
||||
errorDetectors = options.errorDetectors || [],
|
||||
disallowActiveAttributes = (typeof options.disallowActiveAttributes === "undefined") ? false : options.disallowActiveAttributes;
|
||||
var bePre = function(v) { return v.replace(/</g,'<').replace(/>/g,'>'); };
|
||||
var unPre = function(v) { return v.replace(/</g,'<').replace(/>/g,'>'); };
|
||||
|
||||
domBuilder = new DOMBuilder(document, disallowActiveAttributes);
|
||||
parser = new HTMLParser(stream, domBuilder);
|
||||
var hoverHandler = function(basedata) {
|
||||
return function(evt) {
|
||||
var target = evt.target;
|
||||
var hl = target.getAttribute("data-highlight");
|
||||
if(!hl) return;
|
||||
var values = hl.split(",").map(function(v) { return parseInt(v,10); });
|
||||
var start = values[0];
|
||||
var end = values[1];
|
||||
var pre = fdoc.querySelector("pre");
|
||||
var marked = basedata;
|
||||
var marked = bePre(marked.slice(0,start) + "<highlight>" + marked.slice(start, end) + "</highlight>" + marked.slice(end));
|
||||
marked = marked.replace("<highlight>", "<span class='highlight'>");
|
||||
marked = marked.replace("</highlight>", "</span>");
|
||||
pre.innerHTML = marked;
|
||||
};
|
||||
};
|
||||
|
||||
try {
|
||||
var _ = parser.parse();
|
||||
if (_.warnings) {
|
||||
warnings = _.warnings;
|
||||
}
|
||||
} catch (e) {
|
||||
if (e.parseInfo) {
|
||||
error = e.parseInfo;
|
||||
} else
|
||||
throw e;
|
||||
|
||||
var setPreview = function(data, original) {
|
||||
fdoc.open();
|
||||
fdoc.write(data);
|
||||
fdoc.write("<style>hr { border: solid grey; width: 100%; margin: 0; border-width: 1px 0 0 0; } span.highlight { background: pink; } em[data-highlight] { cursor: pointer; }</style>");
|
||||
fdoc.close();
|
||||
fdoc.addEventListener("mouseover", hoverHandler(original));
|
||||
};
|
||||
|
||||
var resolveError = function(data, error, map) {
|
||||
var template = map[error.type];
|
||||
var errorHTML = template.replace(/\[\[([^\]]+)\]\]/g, function(_, term) {
|
||||
var terms = term.indexOf(".") > -1 ? term.split(".") : [term];
|
||||
var value = error;
|
||||
while(terms.length > 0) {
|
||||
value = value[terms.splice(0,1)[0]];
|
||||
}
|
||||
return value;
|
||||
});
|
||||
var suffix = "\n<hr>\n<pre class='hl-target'>\n" + bePre(data) + "</pre>";
|
||||
errorHTML += suffix;
|
||||
return errorHTML
|
||||
};
|
||||
|
||||
errorDetectors.forEach(function(detector) {
|
||||
if (!error)
|
||||
error = detector(html, domBuilder.fragment) || null;
|
||||
});
|
||||
var timeout = false;
|
||||
|
||||
return {
|
||||
document: domBuilder.fragment,
|
||||
contexts: domBuilder.contexts,
|
||||
warnings: warnings,
|
||||
error: error
|
||||
};
|
||||
},
|
||||
// `Slowparse.findError()` just returns any error in the given HTML
|
||||
// string, or `null` if the HTML contains no errors.
|
||||
findError: function(html, errorDetectors) {
|
||||
return this.HTML(document, html, errorDetectors).error;
|
||||
var update = function() {
|
||||
var data = input.value;
|
||||
var result = Slowparse.HTML(document, data);
|
||||
if (result.error) {
|
||||
errors.textContent = JSON.stringify(result.error, false, 2);
|
||||
setPreview(resolveError(data, result.error, stringmap), data);
|
||||
} else {
|
||||
errors.textContent = '';
|
||||
setPreview(data);
|
||||
}
|
||||
};
|
||||
|
||||
// AMD context
|
||||
if (typeof define !== "undefined") {
|
||||
define(function() { return Slowparse; });
|
||||
}
|
||||
input.addEventListener("keyup", function(evt) {
|
||||
setTimeout(update, 100);
|
||||
});
|
||||
|
||||
// Node.js context
|
||||
else if(typeof module !== "undefined" && module.exports) {
|
||||
module.exports = Slowparse;
|
||||
}
|
||||
|
||||
// browser context
|
||||
else if (typeof window !== "undefined") {
|
||||
window.Slowparse = Slowparse;
|
||||
}
|
||||
}());
|
||||
update();
|
||||
}
|
||||
xhr.send(null);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
"INVALID_CSS_RULE": "<p><em data-highlight='[[cssRule.start]],[[cssRule.end]]'>This</em> CSS rule is not legal CSS.</p>",
|
||||
"INVALID_TAG_NAME": "<p>The <code><</code> character <em data-highlight='[[openTag.start]],[[openTag.end]]'>here</em> appears to be the beginning of a tag, but is not followed by a valid tag name.</p> <p>If you just want a <code><</code> to appear on your Web page, try using <code>&lt;</code> instead.</p> <p>Or, see a <a href='https://developer.mozilla.org/en/docs/Web/Guide/HTML/HTML5/HTML5_element_list'>list of HTML5 tags</a>.</p>",
|
||||
"JAVASCRIPT_URL_NOT_ALLOWED": "<p>Sorry, but security restrictions on this site prevent you from using the <code>javascript:</code> URL <em data-highlight='[[value.start]],[[value.end]]'>here</em>. If you really need to use JavaScript, consider using <a href='http://jsbin.com/'>jsbin</a> or <a href='http://jsfiddle.net/'>jsfiddle</a>.</p>",
|
||||
"MISMATCHED_CLOSE_TAG": "<p>The closing <code></[[closeTag.name]]></code> tag <em data-highlight='[[closeTag.start]],[[closeTag.end]]'>here</em> doesn't pair with the opening <code><[[openTag.name]]></code> tag <em data-highlight='[[openTag.start]],[[openTag.end]]'>here</em>. This is likely due to a missing, or misplaced <code></[[openTag.name]]></code> tag.",
|
||||
"MISMATCHED_CLOSE_TAG": "<p>The closing <code></[[closeTag.name]]></code> tag <em data-highlight='[[closeTag.start]],[[closeTag.end]]'>here</em> doesn't pair with the opening <code><[[openTag.name]]></code> tag <em data-highlight='[[openTag.start]],[[openTag.end]]'>here</em>. This is likely due to a missing or misplaced <code></[[openTag.name]]></code> tag.",
|
||||
"MISSING_CSS_BLOCK_CLOSER": "<p>Missing block closer or next property:value; pair following <em data-highlight='[[cssValue.start]],[[cssValue.end]]'>[[cssValue.value]]</em>.</p>",
|
||||
"MISSING_CSS_BLOCK_OPENER": "<p>Missing block opener after <em data-highlight='[[cssSelector.start]],[[cssSelector.end]]'>[[cssSelector.selector]]</em>.</p>",
|
||||
"MISSING_CSS_PROPERTY": "<p>Missing property for <em data-highlight='[[cssSelector.start]],[[cssSelector.end]]'>[[cssSelector.selector]]</em>.</p>",
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
"test": "test"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "browserify index.js -o slowparse.js --standalone Slowparse & node test.js"
|
||||
"test": "browserify ./src/index.js -o slowparse.js --standalone Slowparse & node test.js"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
|
278
slowparse.js
278
slowparse.js
|
@ -1,136 +1,4 @@
|
|||
!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Slowparse=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
|
||||
// Slowparse is a token stream parser for HTML and CSS text,
|
||||
// recording regions of interest during the parse run and
|
||||
// signaling any errors detected accompanied by relevant
|
||||
// regions in the text stream, to make debugging easy. Each
|
||||
// error type is documented in the [error specification][].
|
||||
//
|
||||
// Slowparse also builds a DOM as it goes, attaching metadata
|
||||
// to each node build that points to where it came from in
|
||||
// the original source.
|
||||
//
|
||||
// For more information on the rationale behind Slowparse, as
|
||||
// well as its design goals, see the [README][].
|
||||
//
|
||||
// If [RequireJS] is detected, this file is defined as a module via
|
||||
// `define()`. Otherwise, a global called `Slowparse` is exposed.
|
||||
//
|
||||
// ## Implementation
|
||||
//
|
||||
// Slowparse is effectively a finite state machine for
|
||||
// HTML and CSS strings, and will switch between the HTML
|
||||
// and CSS parsers while maintaining a single token stream.
|
||||
//
|
||||
// [RequireJS]: http://requirejs.org/
|
||||
// [error specification]: spec/
|
||||
// [README]: https://github.com/mozilla/slowparse#readme
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
var Stream = require("./src/Stream");
|
||||
var CSSParser = require("./src/CSSParser");
|
||||
var HTMLParser = require("./src/HTMLParser");
|
||||
var DOMBuilder = require("./src/DOMBuilder");
|
||||
|
||||
// ### Exported Symbols
|
||||
//
|
||||
// `Slowparse` is the object that holds all exported symbols from
|
||||
// this library.
|
||||
var Slowparse = {
|
||||
// We export our list of recognized HTML elements and CSS properties
|
||||
// for clients to use if needed.
|
||||
HTML_ELEMENT_NAMES: HTMLParser.prototype.voidHtmlElements.concat(
|
||||
HTMLParser.prototype.htmlElements.concat(
|
||||
HTMLParser.prototype.obsoleteHtmlElements)),
|
||||
CSS_PROPERTY_NAMES: CSSParser.prototype.cssProperties,
|
||||
|
||||
// We also export a few internal symbols for use by Slowparse's
|
||||
// testing suite.
|
||||
replaceEntityRefs: HTMLParser.replaceEntityRefs,
|
||||
Stream: Stream,
|
||||
|
||||
// `Slowparse.HTML()` is the primary function we export. Given
|
||||
// a DOM document object (or a DOMBuilder instance) and a string
|
||||
// of HTML, we return an object with the following keys:
|
||||
//
|
||||
// * `document` is a DOM document fragment containing the DOM of
|
||||
// the parsed HTML. If an error occurred while parsing, this
|
||||
// document is incomplete, and represents what was built before
|
||||
// the error was encountered.
|
||||
//
|
||||
// * `error` is a JSON-serializable object representing any error
|
||||
// that occurred while parsing. If no errors occurred while parsing,
|
||||
// its value is `null`. For a list of the types of errors that
|
||||
// can be returned, see the [error specification][].
|
||||
//
|
||||
// An array of error detector functions can also be passed as a
|
||||
// third argument to this function. An error detector function takes
|
||||
// the HTML and generated document fragment as arguments and returns
|
||||
// an error object if an error is detected, or `undefined` otherwise.
|
||||
// This can be used for further error checking on the parsed document.
|
||||
//
|
||||
// [error specification]: spec/
|
||||
HTML: function(document, html, options) {
|
||||
options = options || {};
|
||||
var stream = new Stream(html),
|
||||
domBuilder,
|
||||
parser,
|
||||
warnings = null,
|
||||
error = null,
|
||||
errorDetectors = options.errorDetectors || [],
|
||||
disallowActiveAttributes = (typeof options.disallowActiveAttributes === "undefined") ? false : options.disallowActiveAttributes;
|
||||
|
||||
domBuilder = new DOMBuilder(document, disallowActiveAttributes);
|
||||
parser = new HTMLParser(stream, domBuilder);
|
||||
|
||||
try {
|
||||
var _ = parser.parse();
|
||||
if (_.warnings) {
|
||||
warnings = _.warnings;
|
||||
}
|
||||
} catch (e) {
|
||||
if (e.parseInfo) {
|
||||
error = e.parseInfo;
|
||||
} else
|
||||
throw e;
|
||||
}
|
||||
|
||||
errorDetectors.forEach(function(detector) {
|
||||
if (!error)
|
||||
error = detector(html, domBuilder.fragment) || null;
|
||||
});
|
||||
|
||||
return {
|
||||
document: domBuilder.fragment,
|
||||
contexts: domBuilder.contexts,
|
||||
warnings: warnings,
|
||||
error: error
|
||||
};
|
||||
},
|
||||
// `Slowparse.findError()` just returns any error in the given HTML
|
||||
// string, or `null` if the HTML contains no errors.
|
||||
findError: function(html, errorDetectors) {
|
||||
return this.HTML(document, html, errorDetectors).error;
|
||||
}
|
||||
};
|
||||
|
||||
// AMD context
|
||||
if (typeof define !== "undefined") {
|
||||
define(function() { return Slowparse; });
|
||||
}
|
||||
|
||||
// Node.js context
|
||||
else if(typeof module !== "undefined" && module.exports) {
|
||||
module.exports = Slowparse;
|
||||
}
|
||||
|
||||
// browser context
|
||||
else if (typeof window !== "undefined") {
|
||||
window.Slowparse = Slowparse;
|
||||
}
|
||||
}());
|
||||
|
||||
},{"./src/CSSParser":2,"./src/DOMBuilder":3,"./src/HTMLParser":4,"./src/Stream":7}],2:[function(require,module,exports){
|
||||
// ### CSS Parsing
|
||||
//
|
||||
// `CSSParser` is our internal CSS token stream parser object. This object
|
||||
|
@ -669,7 +537,7 @@ module.exports = (function(){
|
|||
|
||||
}());
|
||||
|
||||
},{"./ParseError":5,"./checkMixedContent":8}],3:[function(require,module,exports){
|
||||
},{"./ParseError":4,"./checkMixedContent":7}],2:[function(require,module,exports){
|
||||
// ### The DOM Builder
|
||||
//
|
||||
// The DOM builder is used to construct a DOM representation of the
|
||||
|
@ -745,7 +613,7 @@ module.exports = (function(){
|
|||
|
||||
}());
|
||||
|
||||
},{}],4:[function(require,module,exports){
|
||||
},{}],3:[function(require,module,exports){
|
||||
// ### HTML Parsing
|
||||
//
|
||||
// The HTML token stream parser object has references to the stream,
|
||||
|
@ -1342,7 +1210,7 @@ module.exports = (function(){
|
|||
|
||||
return HTMLParser;
|
||||
}());
|
||||
},{"./CSSParser":2,"./ParseError":5,"./checkMixedContent":8}],5:[function(require,module,exports){
|
||||
},{"./CSSParser":1,"./ParseError":4,"./checkMixedContent":7}],4:[function(require,module,exports){
|
||||
// ### Errors
|
||||
//
|
||||
// `ParseError` is an internal error class used to indicate a parsing error.
|
||||
|
@ -1384,7 +1252,7 @@ module.exports = (function() {
|
|||
return ParseError;
|
||||
}());
|
||||
|
||||
},{"./ParseErrorBuilders":6}],6:[function(require,module,exports){
|
||||
},{"./ParseErrorBuilders":5}],5:[function(require,module,exports){
|
||||
// `ParseErrorBuilders` contains Factory functions for all our types of
|
||||
// parse errors, indexed by error type.
|
||||
//
|
||||
|
@ -1767,7 +1635,7 @@ module.exports = (function() {
|
|||
|
||||
}());
|
||||
|
||||
},{}],7:[function(require,module,exports){
|
||||
},{}],6:[function(require,module,exports){
|
||||
// ### Streams
|
||||
//
|
||||
// `Stream` is an internal class used for tokenization. The interface for
|
||||
|
@ -1962,11 +1830,143 @@ module.exports = (function(){
|
|||
return Stream;
|
||||
}());
|
||||
|
||||
},{"./ParseError":5,"./ParseErrorBuilders":6}],8:[function(require,module,exports){
|
||||
},{"./ParseError":4,"./ParseErrorBuilders":5}],7:[function(require,module,exports){
|
||||
//Define a property checker for https page
|
||||
module.exports = {
|
||||
mixedContent: (typeof window !== "undefined" ? (window.location.protocol === "https:") : false)
|
||||
};
|
||||
|
||||
},{}]},{},[1])(1)
|
||||
},{}],8:[function(require,module,exports){
|
||||
// Slowparse is a token stream parser for HTML and CSS text,
|
||||
// recording regions of interest during the parse run and
|
||||
// signaling any errors detected accompanied by relevant
|
||||
// regions in the text stream, to make debugging easy. Each
|
||||
// error type is documented in the [error specification][].
|
||||
//
|
||||
// Slowparse also builds a DOM as it goes, attaching metadata
|
||||
// to each node build that points to where it came from in
|
||||
// the original source.
|
||||
//
|
||||
// For more information on the rationale behind Slowparse, as
|
||||
// well as its design goals, see the [README][].
|
||||
//
|
||||
// If [RequireJS] is detected, this file is defined as a module via
|
||||
// `define()`. Otherwise, a global called `Slowparse` is exposed.
|
||||
//
|
||||
// ## Implementation
|
||||
//
|
||||
// Slowparse is effectively a finite state machine for
|
||||
// HTML and CSS strings, and will switch between the HTML
|
||||
// and CSS parsers while maintaining a single token stream.
|
||||
//
|
||||
// [RequireJS]: http://requirejs.org/
|
||||
// [error specification]: spec/
|
||||
// [README]: https://github.com/mozilla/slowparse#readme
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
var Stream = require("./Stream");
|
||||
var CSSParser = require("./CSSParser");
|
||||
var HTMLParser = require("./HTMLParser");
|
||||
var DOMBuilder = require("./DOMBuilder");
|
||||
|
||||
// ### Exported Symbols
|
||||
//
|
||||
// `Slowparse` is the object that holds all exported symbols from
|
||||
// this library.
|
||||
var Slowparse = {
|
||||
// We export our list of recognized HTML elements and CSS properties
|
||||
// for clients to use if needed.
|
||||
HTML_ELEMENT_NAMES: HTMLParser.prototype.voidHtmlElements.concat(
|
||||
HTMLParser.prototype.htmlElements.concat(
|
||||
HTMLParser.prototype.obsoleteHtmlElements)),
|
||||
CSS_PROPERTY_NAMES: CSSParser.prototype.cssProperties,
|
||||
|
||||
// We also export a few internal symbols for use by Slowparse's
|
||||
// testing suite.
|
||||
replaceEntityRefs: HTMLParser.replaceEntityRefs,
|
||||
Stream: Stream,
|
||||
|
||||
// `Slowparse.HTML()` is the primary function we export. Given
|
||||
// a DOM document object (or a DOMBuilder instance) and a string
|
||||
// of HTML, we return an object with the following keys:
|
||||
//
|
||||
// * `document` is a DOM document fragment containing the DOM of
|
||||
// the parsed HTML. If an error occurred while parsing, this
|
||||
// document is incomplete, and represents what was built before
|
||||
// the error was encountered.
|
||||
//
|
||||
// * `error` is a JSON-serializable object representing any error
|
||||
// that occurred while parsing. If no errors occurred while parsing,
|
||||
// its value is `null`. For a list of the types of errors that
|
||||
// can be returned, see the [error specification][].
|
||||
//
|
||||
// An array of error detector functions can also be passed as a
|
||||
// third argument to this function. An error detector function takes
|
||||
// the HTML and generated document fragment as arguments and returns
|
||||
// an error object if an error is detected, or `undefined` otherwise.
|
||||
// This can be used for further error checking on the parsed document.
|
||||
//
|
||||
// [error specification]: spec/
|
||||
HTML: function(document, html, options) {
|
||||
options = options || {};
|
||||
var stream = new Stream(html),
|
||||
domBuilder,
|
||||
parser,
|
||||
warnings = null,
|
||||
error = null,
|
||||
errorDetectors = options.errorDetectors || [],
|
||||
disallowActiveAttributes = (typeof options.disallowActiveAttributes === "undefined") ? false : options.disallowActiveAttributes;
|
||||
|
||||
domBuilder = new DOMBuilder(document, disallowActiveAttributes);
|
||||
parser = new HTMLParser(stream, domBuilder);
|
||||
|
||||
try {
|
||||
var _ = parser.parse();
|
||||
if (_.warnings) {
|
||||
warnings = _.warnings;
|
||||
}
|
||||
} catch (e) {
|
||||
if (e.parseInfo) {
|
||||
error = e.parseInfo;
|
||||
} else
|
||||
throw e;
|
||||
}
|
||||
|
||||
errorDetectors.forEach(function(detector) {
|
||||
if (!error)
|
||||
error = detector(html, domBuilder.fragment) || null;
|
||||
});
|
||||
|
||||
return {
|
||||
document: domBuilder.fragment,
|
||||
contexts: domBuilder.contexts,
|
||||
warnings: warnings,
|
||||
error: error
|
||||
};
|
||||
},
|
||||
// `Slowparse.findError()` just returns any error in the given HTML
|
||||
// string, or `null` if the HTML contains no errors.
|
||||
findError: function(html, errorDetectors) {
|
||||
return this.HTML(document, html, errorDetectors).error;
|
||||
}
|
||||
};
|
||||
|
||||
// AMD context
|
||||
if (typeof define !== "undefined") {
|
||||
define(function() { return Slowparse; });
|
||||
}
|
||||
|
||||
// Node.js context
|
||||
else if(typeof module !== "undefined" && module.exports) {
|
||||
module.exports = Slowparse;
|
||||
}
|
||||
|
||||
// browser context
|
||||
else if (typeof window !== "undefined") {
|
||||
window.Slowparse = Slowparse;
|
||||
}
|
||||
}());
|
||||
|
||||
},{"./CSSParser":1,"./DOMBuilder":2,"./HTMLParser":3,"./Stream":6}]},{},[8])(8)
|
||||
});
|
|
@ -0,0 +1,130 @@
|
|||
// Slowparse is a token stream parser for HTML and CSS text,
|
||||
// recording regions of interest during the parse run and
|
||||
// signaling any errors detected accompanied by relevant
|
||||
// regions in the text stream, to make debugging easy. Each
|
||||
// error type is documented in the [error specification][].
|
||||
//
|
||||
// Slowparse also builds a DOM as it goes, attaching metadata
|
||||
// to each node build that points to where it came from in
|
||||
// the original source.
|
||||
//
|
||||
// For more information on the rationale behind Slowparse, as
|
||||
// well as its design goals, see the [README][].
|
||||
//
|
||||
// If [RequireJS] is detected, this file is defined as a module via
|
||||
// `define()`. Otherwise, a global called `Slowparse` is exposed.
|
||||
//
|
||||
// ## Implementation
|
||||
//
|
||||
// Slowparse is effectively a finite state machine for
|
||||
// HTML and CSS strings, and will switch between the HTML
|
||||
// and CSS parsers while maintaining a single token stream.
|
||||
//
|
||||
// [RequireJS]: http://requirejs.org/
|
||||
// [error specification]: spec/
|
||||
// [README]: https://github.com/mozilla/slowparse#readme
|
||||
(function() {
|
||||
"use strict";
|
||||
|
||||
var Stream = require("./Stream");
|
||||
var CSSParser = require("./CSSParser");
|
||||
var HTMLParser = require("./HTMLParser");
|
||||
var DOMBuilder = require("./DOMBuilder");
|
||||
|
||||
// ### Exported Symbols
|
||||
//
|
||||
// `Slowparse` is the object that holds all exported symbols from
|
||||
// this library.
|
||||
var Slowparse = {
|
||||
// We export our list of recognized HTML elements and CSS properties
|
||||
// for clients to use if needed.
|
||||
HTML_ELEMENT_NAMES: HTMLParser.prototype.voidHtmlElements.concat(
|
||||
HTMLParser.prototype.htmlElements.concat(
|
||||
HTMLParser.prototype.obsoleteHtmlElements)),
|
||||
CSS_PROPERTY_NAMES: CSSParser.prototype.cssProperties,
|
||||
|
||||
// We also export a few internal symbols for use by Slowparse's
|
||||
// testing suite.
|
||||
replaceEntityRefs: HTMLParser.replaceEntityRefs,
|
||||
Stream: Stream,
|
||||
|
||||
// `Slowparse.HTML()` is the primary function we export. Given
|
||||
// a DOM document object (or a DOMBuilder instance) and a string
|
||||
// of HTML, we return an object with the following keys:
|
||||
//
|
||||
// * `document` is a DOM document fragment containing the DOM of
|
||||
// the parsed HTML. If an error occurred while parsing, this
|
||||
// document is incomplete, and represents what was built before
|
||||
// the error was encountered.
|
||||
//
|
||||
// * `error` is a JSON-serializable object representing any error
|
||||
// that occurred while parsing. If no errors occurred while parsing,
|
||||
// its value is `null`. For a list of the types of errors that
|
||||
// can be returned, see the [error specification][].
|
||||
//
|
||||
// An array of error detector functions can also be passed as a
|
||||
// third argument to this function. An error detector function takes
|
||||
// the HTML and generated document fragment as arguments and returns
|
||||
// an error object if an error is detected, or `undefined` otherwise.
|
||||
// This can be used for further error checking on the parsed document.
|
||||
//
|
||||
// [error specification]: spec/
|
||||
HTML: function(document, html, options) {
|
||||
options = options || {};
|
||||
var stream = new Stream(html),
|
||||
domBuilder,
|
||||
parser,
|
||||
warnings = null,
|
||||
error = null,
|
||||
errorDetectors = options.errorDetectors || [],
|
||||
disallowActiveAttributes = (typeof options.disallowActiveAttributes === "undefined") ? false : options.disallowActiveAttributes;
|
||||
|
||||
domBuilder = new DOMBuilder(document, disallowActiveAttributes);
|
||||
parser = new HTMLParser(stream, domBuilder);
|
||||
|
||||
try {
|
||||
var _ = parser.parse();
|
||||
if (_.warnings) {
|
||||
warnings = _.warnings;
|
||||
}
|
||||
} catch (e) {
|
||||
if (e.parseInfo) {
|
||||
error = e.parseInfo;
|
||||
} else
|
||||
throw e;
|
||||
}
|
||||
|
||||
errorDetectors.forEach(function(detector) {
|
||||
if (!error)
|
||||
error = detector(html, domBuilder.fragment) || null;
|
||||
});
|
||||
|
||||
return {
|
||||
document: domBuilder.fragment,
|
||||
contexts: domBuilder.contexts,
|
||||
warnings: warnings,
|
||||
error: error
|
||||
};
|
||||
},
|
||||
// `Slowparse.findError()` just returns any error in the given HTML
|
||||
// string, or `null` if the HTML contains no errors.
|
||||
findError: function(html, errorDetectors) {
|
||||
return this.HTML(document, html, errorDetectors).error;
|
||||
}
|
||||
};
|
||||
|
||||
// AMD context
|
||||
if (typeof define !== "undefined") {
|
||||
define(function() { return Slowparse; });
|
||||
}
|
||||
|
||||
// Node.js context
|
||||
else if(typeof module !== "undefined" && module.exports) {
|
||||
module.exports = Slowparse;
|
||||
}
|
||||
|
||||
// browser context
|
||||
else if (typeof window !== "undefined") {
|
||||
window.Slowparse = Slowparse;
|
||||
}
|
||||
}());
|
|
@ -0,0 +1,34 @@
|
|||
html, body {
|
||||
|
||||
}
|
||||
|
||||
main {
|
||||
display: -webkit-flex;
|
||||
display: flex;
|
||||
|
||||
width: 100%;
|
||||
background: lightgrey;
|
||||
}
|
||||
|
||||
.pane {
|
||||
-webkit-flex: 1;
|
||||
flex: 1;
|
||||
|
||||
min-height: 400px;
|
||||
flex: flex-grow;
|
||||
margin: 1px;
|
||||
padding: 0;
|
||||
border: none;
|
||||
}
|
||||
|
||||
textarea {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
iframe {
|
||||
min-height: 400px;
|
||||
width: 100%;
|
||||
border: none;
|
||||
margin: 0;
|
||||
background: white;
|
||||
}
|
Загрузка…
Ссылка в новой задаче