1
0
mirror of https://github.com/S2-/minifyfromhtml.git synced 2025-08-02 12:00:03 +02:00

use terser and clean-css directly

create a sourcemap as well by default
This commit is contained in:
s2
2020-02-13 15:39:37 +01:00
parent db9b32db65
commit a4b62da0ba
535 changed files with 33708 additions and 63052 deletions

29
node_modules/saxes/CHANGELOG.md generated vendored
View File

@@ -1,3 +1,32 @@
<a name="3.1.11"></a>
## [3.1.11](https://github.com/lddubeau/saxes/compare/v3.1.10...v3.1.11) (2019-06-25)
### Bug Fixes
* pay attention to comments and processing instructions in DTDs ([52ffd90](https://github.com/lddubeau/saxes/commit/52ffd90)), closes [#19](https://github.com/lddubeau/saxes/issues/19)
### Performance Improvements
* check the most common case first ([40a34d5](https://github.com/lddubeau/saxes/commit/40a34d5))
* improve some more the speed of ]]> detection ([a0216cd](https://github.com/lddubeau/saxes/commit/a0216cd))
* move more common/valid cases first ([a65586e](https://github.com/lddubeau/saxes/commit/a65586e))
* split sText into two specialized loops ([732325e](https://github.com/lddubeau/saxes/commit/732325e))
* use specialized code for sAttribValueQuoted ([6c484f3](https://github.com/lddubeau/saxes/commit/6c484f3))
<a name="3.1.10"></a>
## [3.1.10](https://github.com/lddubeau/saxes/compare/v3.1.9...v3.1.10) (2019-06-11)
### Performance Improvements
* improve the check for ]]> in character data ([21df9b5](https://github.com/lddubeau/saxes/commit/21df9b5))
<a name="3.1.9"></a>
## [3.1.9](https://github.com/lddubeau/saxes/compare/v3.1.7...v3.1.9) (2019-02-25)

564
node_modules/saxes/lib/saxes.js generated vendored
View File

@@ -1,8 +1,8 @@
"use strict";
const { isS, isChar, isNameStartChar, isNameChar, S_LIST } =
const { isS, isChar, isNameStartChar, isNameChar, S_LIST, NAME_RE } =
require("xmlchars/xml/1.0/ed5");
const { isNCNameStartChar, isNCNameChar } = require("xmlchars/xmlns/1.0/ed3");
const { isNCNameStartChar, isNCNameChar, NC_NAME_RE } = require("xmlchars/xmlns/1.0/ed3");
const XML_NAMESPACE = "http://www.w3.org/XML/1998/namespace";
const XMLNS_NAMESPACE = "http://www.w3.org/2000/xmlns/";
@@ -22,16 +22,23 @@ const XML_ENTITIES = {
apos: "'",
};
const S_INITIAL = "sInitial"; // initial state
const S_BEGIN_WHITESPACE = "sBeginWhitespace"; // leading whitespace
const S_DOCTYPE = "sDoctype"; // <!DOCTYPE
const S_DOCTYPE_QUOTE = "sDoctypeQuote"; // <!DOCTYPE "//blah
const S_DTD = "sDTD"; // <!DOCTYPE "//blah" [ ...
const S_DTD_QUOTED = "sDTDQuoted"; // <!DOCTYPE "//blah" [ "foo
const S_DTD_OPEN_WAKA = "sDTDOpenWaka";
const S_DTD_OPEN_WAKA_BANG = "sDTDOpenWakaBang";
const S_DTD_COMMENT = "sDTDComment"; // <!--
const S_DTD_COMMENT_ENDING = "sDTDCommentEnding"; // <!-- blah -
const S_DTD_COMMENT_ENDED = "sDTDCommentEnded"; // <!-- blah --
const S_DTD_PI = "sDTDPI"; // <?
const S_DTD_PI_ENDING = "sDTDPIEnding"; // <?hi "there" ?
const S_TEXT = "sText"; // general stuff
const S_ENTITY_FIRST_CHAR = "sEntityFirstChar"; // &amp and such, first char
const S_ENTITY_REST = "sEntityRest"; // &amp and such, rest of the name
const S_ENTITY = "sEntity"; // &amp and such
const S_OPEN_WAKA = "sOpenWaka"; // <
const S_OPEN_WAKA_BANG = "sOpenWakaBang"; // <!...
const S_DOCTYPE = "sDoctype"; // <!DOCTYPE
const S_DOCTYPE_QUOTED = "sDoctypeQuoted"; // <!DOCTYPE "//blah
const S_DOCTYPE_DTD = "sDoctypeDTD"; // <!DOCTYPE "//blah" [ ...
const S_DOCTYPE_DTD_QUOTED = "sDoctypeDTDQuoted"; // <!DOCTYPE "//blah" [ "foo
const S_COMMENT = "sComment"; // <!--
const S_COMMENT_ENDING = "sCommentEnding"; // <!-- blah -
const S_COMMENT_ENDED = "sCommentEnded"; // <!-- blah --
@@ -61,8 +68,6 @@ const S_XML_DECL_EQ = 3; // <?xml foo=
const S_XML_DECL_VALUE_START = 4; // <?xml foo=
const S_XML_DECL_VALUE = 5; // <?xml foo="bar"
const SPACE_SEPARATOR = "SPACE_SEPARATOR";
/**
* The list of supported events.
*/
@@ -85,7 +90,6 @@ const CR = 0xD;
const SPACE = 0x20;
const BANG = 0x21;
const DQUOTE = 0x22;
const HASH = 0x23;
const AMP = 0x26;
const SQUOTE = 0x27;
const MINUS = 0x2D;
@@ -104,9 +108,8 @@ function isQuote(c) {
const QUOTES = [DQUOTE, SQUOTE];
const TEXT_TERMINATOR = [LESS, AMP];
const DOCTYPE_TERMINATOR = [...QUOTES, OPEN_BRACKET, GREATER];
const DOCTYPE_DTD_TERMINATOR = [...QUOTES, CLOSE_BRACKET];
const DTD_TERMINATOR = [...QUOTES, LESS, CLOSE_BRACKET];
const XML_DECL_NAME_TERMINATOR = [EQUAL, QUESTION, ...S_LIST];
const ATTRIB_VALUE_UNQUOTED_TERMINATOR = [...S_LIST, GREATER, AMP, LESS];
@@ -155,6 +158,18 @@ function nsMappingCheck(parser, mapping) {
}
}
function isNCName(name) {
return NC_NAME_RE.test(name);
}
function isName(name) {
return NAME_RE.test(name);
}
const FORBIDDEN_START = 0;
const FORBIDDEN_BRACKET = 1;
const FORBIDDEN_BRACKET_BRACKET = 2;
/**
* Data structure for an XML tag.
*
@@ -301,12 +316,12 @@ class SaxesParser {
this.q = null;
this.tags = [];
this.initial = true;
this.tag = null;
this.chunk = "";
this.chunkPosition = 0;
this.i = 0;
this.trailingCR = false;
this.forbiddenState = FORBIDDEN_START;
/**
* A map of entity name to expansion.
*
@@ -319,7 +334,7 @@ class SaxesParser {
// this.opt.fragment while parsing.
const fragmentOpt = this.fragmentOpt = !!this.opt.fragment;
this.state = fragmentOpt ? S_TEXT : S_BEGIN_WHITESPACE;
this.state = fragmentOpt ? S_TEXT : S_INITIAL;
// We want these to be all true if we are dealing with a fragment.
this.reportedTextBeforeRoot = this.reportedTextAfterRoot = this.closedRoot =
this.sawRoot = fragmentOpt;
@@ -330,13 +345,8 @@ class SaxesParser {
this.piIsXMLDecl = false;
this.xmlDeclState = S_XML_DECL_NAME_START;
this.xmlDeclExpects = ["version"];
this.requiredSeparator = undefined;
this.requiredSeparator = false;
this.entityReturnState = undefined;
this.badEntityName = false;
// This records the index before which we don't have to check for the
// presence of ]]]>. The text before that index has been checked already,
// and should not be checked twice.
this.textCheckedBefore = 0;
const xmlnsOpt = this.xmlnsOpt = !!this.opt.xmlns;
if (xmlnsOpt) {
@@ -349,6 +359,7 @@ class SaxesParser {
//
this.nameStartCheck = isNCNameStartChar;
this.nameCheck = isNCNameChar;
this.isName = isNCName;
this.processAttribs = this.processAttribsNS;
this.pushAttrib = this.pushAttribNS;
@@ -362,6 +373,7 @@ class SaxesParser {
else {
this.nameStartCheck = isNameStartChar;
this.nameCheck = isNameChar;
this.isName = isName;
this.processAttribs = this.processAttribsPlain;
this.pushAttrib = this.pushAttribPlain;
}
@@ -569,7 +581,7 @@ class SaxesParser {
let skip = 1;
switch (code) {
case CR:
// We may get undefined if we read past the end of the chunk, which is
// We may get NaN if we read past the end of the chunk, which is
// fine.
if (chunk.charCodeAt(i + 1) === NL) {
// A \r\n sequence is converted to \n so we have to skip over the next
@@ -627,7 +639,7 @@ class SaxesParser {
*
* @param {string} buffer The name of the buffer to save into.
*
* @return {string|undefined} The character that made the capture end, or
* @return {number|undefined} The character code that made the capture end, or
* ``undefined`` if we hit the end of the chunk.
*/
captureTo(chars, buffer) {
@@ -682,7 +694,7 @@ class SaxesParser {
*
* @private
*
* @return {string|undefined} The character that made the test fail, or
* @return {number|undefined} The character code that made the test fail, or
* ``undefined`` if we hit the end of the chunk.
*/
captureNameChars() {
@@ -710,7 +722,7 @@ class SaxesParser {
*
* @param {string} buffer The name of the buffer to save into.
*
* @return {string|undefined} The character that made the test fail, or
* @return {number|undefined} The character code that made the test fail, or
* ``undefined`` if we hit the end of the chunk.
*/
captureWhileNameCheck(buffer) {
@@ -731,21 +743,18 @@ class SaxesParser {
}
/**
* Skip characters while a condition is true.
* Skip white spaces.
*
* @private
*
* @param {CharacterTest} test A test to perform on each character. The skip
* ends when the test returns false.
*
* @return {string|undefined} The character that made the test fail, or
* @return {string|undefined} The character that ended the skip, or
* ``undefined`` if we hit the end of the chunk.
*/
skipWhile(test) {
skipSpaces() {
const { limit } = this;
while (this.i < limit) {
const c = this.getCode();
if (!test(c)) {
if (!isS(c)) {
return c;
}
}
@@ -756,29 +765,34 @@ class SaxesParser {
// STATE HANDLERS
/** @private */
sBeginWhitespace() {
const { limit } = this;
let c = this.getCode();
if (this.initial && c === 0xFEFF) {
this.initial = false;
if (this.i >= limit) {
return;
}
c = this.getCode();
sInitial() {
// We are essentially peeking at the first character of the chunk. Since
// S_INITIAL can be in effect only when we start working on the first chunk,
// the index at which we must look is necessarily 0. Note also that the
// following tests do not depend on decoding surrogates.
const c = this.chunk.charCodeAt(0);
// If the initial character is 0xFEFF, ignore it.
if (c === 0xFEFF) {
this.i++;
this.column++;
}
else {
this.initial = false;
}
// We cannot use skipWhile here because we have to use the previously
// read character first.
while (this.i < limit && isS(c)) {
c = this.getCode();
else if (isS(c)) {
this.i++;
this.column++;
// An XML declaration cannot appear after initial spaces.
this.xmlDeclPossible = false;
}
this.state = S_BEGIN_WHITESPACE;
}
/** @private */
sBeginWhitespace() {
const c = this.skipSpaces();
if (c === LESS) {
this.state = S_OPEN_WAKA;
}
else {
else if (c) {
// have to process this as a text node.
// weird, but happens.
if (!this.reportedTextBeforeRoot) {
@@ -786,7 +800,6 @@ class SaxesParser {
this.reportedTextBeforeRoot = true;
}
this.text = String.fromCodePoint(c);
this.textCheckedBefore = 0;
this.state = S_TEXT;
this.xmlDeclPossible = false;
}
@@ -794,42 +807,148 @@ class SaxesParser {
/** @private */
sText() {
const c = this.captureTo(TEXT_TERMINATOR, "text");
//
// We did try a version of saxes where the S_TEXT state was split in two
// states: one for text inside the root element, and one for text
// outside. This was avoiding having to test this.tags.length to decide what
// implementation to actually use.
//
// Peformance testing on gigabyte-size files did not show any advantage to
// using the two states solution instead of the current one. Conversely, it
// made the code a bit more complicated elsewhere. For instance, a comment
// can appear before the root element so when a comment ended it was
// necessary to determine whether to return to the S_TEXT state or to the
// new text-outside-root state.
//
if (this.tags.length !== 0) {
this.handleTextInRoot();
}
else {
this.handleTextOutsideRoot();
}
}
if ((!this.sawRoot || this.closedRoot) &&
(/\S/.test(this.text) || c === AMP)) {
// We use the reportedTextBeforeRoot and reportedTextAfterRoot flags
// to avoid reporting errors for every single character that is out of
// place.
if (!this.sawRoot && !this.reportedTextBeforeRoot) {
this.fail("text data outside of root node.");
this.reportedTextBeforeRoot = true;
/** @private */
handleTextInRoot() {
// This is essentially a specialized version of captureTo which is optimized
// for performing the ]]> check. A previous version of this code, checked
// ``this.text`` for the presence of ]]>. It simplified the code but was
// very costly when character data contained a lot of entities to be parsed.
//
// Since we are using a specialized loop, we also keep track of the presence
// of ]]> in text data. The sequence ]]> is forbidden to appear as-is.
//
const { chunk, limit, i: start } = this;
let { forbiddenState } = this;
let c;
// eslint-disable-next-line no-labels, no-restricted-syntax
scanLoop:
while (this.i < limit) {
const code = this.getCode();
switch (code) {
case LESS:
this.state = S_OPEN_WAKA;
c = code;
forbiddenState = FORBIDDEN_START;
// eslint-disable-next-line no-labels
break scanLoop;
case AMP:
this.state = S_ENTITY;
this.entityReturnState = S_TEXT;
c = code;
forbiddenState = FORBIDDEN_START;
// eslint-disable-next-line no-labels
break scanLoop;
case CLOSE_BRACKET:
switch (forbiddenState) {
case FORBIDDEN_START:
forbiddenState = FORBIDDEN_BRACKET;
break;
case FORBIDDEN_BRACKET:
forbiddenState = FORBIDDEN_BRACKET_BRACKET;
break;
case FORBIDDEN_BRACKET_BRACKET:
break;
default:
throw new Error("impossible state");
}
break;
case GREATER:
if (forbiddenState === FORBIDDEN_BRACKET_BRACKET) {
this.fail("the string \"]]>\" is disallowed in char data.");
}
forbiddenState = FORBIDDEN_START;
break;
default:
forbiddenState = FORBIDDEN_START;
}
}
this.forbiddenState = forbiddenState;
if (this.closedRoot && !this.reportedTextAfterRoot) {
this.fail("text data outside of root node.");
this.reportedTextAfterRoot = true;
// This is faster than adding codepoints one by one.
this.text += chunk.substring(start,
c === undefined ? undefined :
(this.i - (c <= 0xFFFF ? 1 : 2)));
}
/** @private */
handleTextOutsideRoot() {
// This is essentially a specialized version of captureTo which is optimized
// for performing the ]]> check. A previous version of this code, checked
// ``this.text`` for the presence of ]]>. It simplified the code but was
// very costly when character data contained a lot of entities to be parsed.
//
// Since we are using a specialized loop, we also keep track of the presence
// of non-space characters in the text since these are errors when appearing
// outside the document root element.
//
const { chunk, limit, i: start } = this;
let nonSpace = false;
let c;
// eslint-disable-next-line no-labels, no-restricted-syntax
outRootLoop:
while (this.i < limit) {
const code = this.getCode();
switch (code) {
case LESS:
this.state = S_OPEN_WAKA;
c = code;
// eslint-disable-next-line no-labels
break outRootLoop;
case AMP:
this.state = S_ENTITY;
this.entityReturnState = S_TEXT;
c = code;
nonSpace = true;
// eslint-disable-next-line no-labels
break outRootLoop;
default:
if (!isS(code)) {
nonSpace = true;
}
}
}
if (this.text.includes("]]>", this.textCheckedBefore)) {
this.fail("the string \"]]>\" is disallowed in char data.");
// This is faster than adding codepoints one by one.
this.text += chunk.substring(start,
c === undefined ? undefined :
(this.i - (c <= 0xFFFF ? 1 : 2)));
if (!nonSpace) {
return;
}
// We have to go back two spaces so that we can catch the case where on a
// previous write call, the text buffer ended on ``]]`` and we started
// with ``>`` this time around.
this.textCheckedBefore = this.text.length - 2;
// We use the reportedTextBeforeRoot and reportedTextAfterRoot flags
// to avoid reporting errors for every single character that is out of
// place.
if (!this.sawRoot && !this.reportedTextBeforeRoot) {
this.fail("text data outside of root node.");
this.reportedTextBeforeRoot = true;
}
switch (c) {
case LESS:
this.state = S_OPEN_WAKA;
break;
case AMP:
this.state = S_ENTITY_FIRST_CHAR;
this.entityReturnState = S_TEXT;
break;
default:
if (this.closedRoot && !this.reportedTextAfterRoot) {
this.fail("text data outside of root node.");
this.reportedTextAfterRoot = true;
}
}
@@ -866,8 +985,7 @@ class SaxesParser {
/** @private */
sOpenWakaBang() {
const c = String.fromCodePoint(this.getCode());
this.openWakaBang += c;
this.openWakaBang += String.fromCodePoint(this.getCode());
switch (this.openWakaBang) {
case "[CDATA[":
if (!this.sawRoot && !this.reportedTextBeforeRoot) {
@@ -916,17 +1034,17 @@ class SaxesParser {
else if (c) {
this.doctype += String.fromCodePoint(c);
if (c === OPEN_BRACKET) {
this.state = S_DOCTYPE_DTD;
this.state = S_DTD;
}
else if (isQuote(c)) {
this.state = S_DOCTYPE_QUOTED;
this.state = S_DOCTYPE_QUOTE;
this.q = c;
}
}
}
/** @private */
sDoctypeQuoted() {
sDoctypeQuote() {
const { q } = this;
if (this.captureToChar(q, "doctype")) {
this.doctype += String.fromCodePoint(q);
@@ -936,8 +1054,8 @@ class SaxesParser {
}
/** @private */
sDoctypeDTD() {
const c = this.captureTo(DOCTYPE_DTD_TERMINATOR, "doctype");
sDTD() {
const c = this.captureTo(DTD_TERMINATOR, "doctype");
if (!c) {
return;
}
@@ -946,22 +1064,100 @@ class SaxesParser {
if (c === CLOSE_BRACKET) {
this.state = S_DOCTYPE;
}
else if (c === LESS) {
this.state = S_DTD_OPEN_WAKA;
}
else if (isQuote(c)) {
this.state = S_DOCTYPE_DTD_QUOTED;
this.state = S_DTD_QUOTED;
this.q = c;
}
}
/** @private */
sDoctypeDTDQuoted() {
sDTDQuoted() {
const { q } = this;
if (this.captureToChar(q, "doctype")) {
this.doctype += String.fromCodePoint(q);
this.state = S_DOCTYPE_DTD;
this.state = S_DTD;
this.q = null;
}
}
/** @private */
sDTDOpenWaka() {
const c = this.getCode();
this.doctype += String.fromCodePoint(c);
switch (c) {
case BANG:
this.state = S_DTD_OPEN_WAKA_BANG;
this.openWakaBang = "";
break;
case QUESTION:
this.state = S_DTD_PI;
break;
default:
this.state = S_DTD;
}
}
/** @private */
sDTDOpenWakaBang() {
const char = String.fromCodePoint(this.getCode());
const owb = this.openWakaBang += char;
this.doctype += char;
if (owb !== "-") {
this.state = owb === "--" ? S_DTD_COMMENT : S_DTD;
this.openWakaBang = "";
}
}
/** @private */
sDTDComment() {
if (this.captureToChar(MINUS, "doctype")) {
this.doctype += "-";
this.state = S_DTD_COMMENT_ENDING;
}
}
/** @private */
sDTDCommentEnding() {
const c = this.getCode();
this.doctype += String.fromCodePoint(c);
this.state = c === MINUS ? S_DTD_COMMENT_ENDED : S_DTD_COMMENT;
}
/** @private */
sDTDCommentEnded() {
const c = this.getCode();
this.doctype += String.fromCodePoint(c);
if (c === GREATER) {
this.state = S_DTD;
}
else {
this.fail("malformed comment.");
// <!-- blah -- bloo --> will be recorded as
// a comment of " blah -- bloo "
this.state = S_DTD_COMMENT;
}
}
/** @private */
sDTDPI() {
if (this.captureToChar(QUESTION, "doctype")) {
this.doctype += "?";
this.state = S_DTD_PI_ENDING;
}
}
/** @private */
sDTDPIEnding() {
const c = this.getCode();
this.doctype += String.fromCodePoint(c);
if (c === GREATER) {
this.state = S_DTD;
}
}
/** @private */
sComment() {
if (this.captureToChar(MINUS, "comment")) {
@@ -1001,6 +1197,7 @@ class SaxesParser {
}
}
/** @private */
sCData() {
if (this.captureToChar(CLOSE_BRACKET, "cdata")) {
this.state = S_CDATA_ENDING;
@@ -1051,7 +1248,7 @@ class SaxesParser {
this.fail("processing instruction without a target.");
this.state = c === QUESTION ? S_PI_ENDING : S_PI_BODY;
}
else if (c) {
else {
this.fail("disallowed character in processing instruction name.");
this.piTarget += String.fromCodePoint(c);
this.state = S_PI_REST;
@@ -1079,22 +1276,15 @@ class SaxesParser {
let c;
if (this.piIsXMLDecl) {
switch (this.xmlDeclState) {
case S_XML_DECL_NAME_START:
c = this.skipWhile((cx) => {
if (isS(cx)) {
this.requiredSeparator = undefined;
return true;
}
if (cx !== QUESTION && this.requiredSeparator === SPACE_SEPARATOR) {
this.fail("whitespace required.");
}
this.requiredSeparator = undefined;
return false;
});
case S_XML_DECL_NAME_START: {
c = this.getCode();
if (isS(c)) {
c = this.skipSpaces();
}
else if (this.requiredSeparator && c !== QUESTION) {
this.fail("whitespace required.");
}
this.requiredSeparator = false;
// The question mark character is not valid inside any of the XML
// declaration name/value pairs.
@@ -1108,6 +1298,7 @@ class SaxesParser {
this.xmlDeclName = String.fromCodePoint(c);
}
break;
}
case S_XML_DECL_NAME:
c = this.captureTo(XML_DECL_NAME_TERMINATOR, "xmlDeclName");
// The question mark character is not valid inside any of the XML
@@ -1143,7 +1334,7 @@ class SaxesParser {
return;
}
if (c && !isS(c)) {
if (!isS(c)) {
if (c !== EQUAL) {
this.fail("value required.");
}
@@ -1159,7 +1350,7 @@ class SaxesParser {
return;
}
if (c && !isS(c)) {
if (!isS(c)) {
if (!isQuote(c)) {
this.fail("value must be quoted.");
this.q = SPACE;
@@ -1210,7 +1401,7 @@ class SaxesParser {
}
this.xmlDeclName = this.xmlDeclValue = "";
this.xmlDeclState = S_XML_DECL_NAME_START;
this.requiredSeparator = SPACE_SEPARATOR;
this.requiredSeparator = true;
}
break;
default:
@@ -1223,7 +1414,7 @@ class SaxesParser {
if (c === QUESTION) {
this.state = S_PI_ENDING;
}
else if (c && !isS(c)) {
else if (!isS(c)) {
this.piBody = String.fromCodePoint(c);
}
}
@@ -1249,7 +1440,7 @@ class SaxesParser {
this.fail("XML declaration must contain a version.");
}
this.xmlDeclName = this.xmlDeclValue = "";
this.requiredSeparator = undefined;
this.requiredSeparator = false;
this.piTarget = this.piBody = "";
this.state = S_TEXT;
}
@@ -1343,8 +1534,8 @@ class SaxesParser {
/** @private */
sAttrib() {
const c = this.getCode();
if (!c || isS(c)) {
const c = this.skipSpaces();
if (!c) {
return;
}
if (isNameStartChar(c)) {
@@ -1405,15 +1596,15 @@ class SaxesParser {
/** @private */
sAttribNameSawWhite() {
const c = this.getCode();
if (isS(c)) {
const c = this.skipSpaces();
if (!c) {
return;
}
if (c === EQUAL) {
this.state = S_ATTRIB_VALUE;
}
else if (c) {
else {
this.fail("attribute without value.");
this.tag.attributes[this.name] = "";
this.text = "";
@@ -1439,7 +1630,7 @@ class SaxesParser {
this.q = c;
this.state = S_ATTRIB_VALUE_QUOTED;
}
else if (c && !isS(c)) {
else if (!isS(c)) {
this.fail("unquoted attribute value.");
this.state = S_ATTRIB_VALUE_UNQUOTED;
this.text = String.fromCodePoint(c);
@@ -1448,19 +1639,40 @@ class SaxesParser {
/** @private */
sAttribValueQuoted() {
const c = this.captureTo([this.q, AMP, LESS], "text");
if (c === AMP) {
this.state = S_ENTITY_FIRST_CHAR;
this.entityReturnState = S_ATTRIB_VALUE_QUOTED;
}
else if (c === LESS) {
this.fail("disallowed character.");
}
else if (c) {
this.pushAttrib(this.name, this.text);
this.name = this.text = "";
this.q = null;
this.state = S_ATTRIB_VALUE_CLOSED;
// We deliberately do not use captureTo here. The specialized code we use
// here is faster than using captureTo.
const { q } = this;
const { chunk, limit, i: start } = this;
// eslint-disable-next-line no-constant-condition
while (true) {
if (this.i >= limit) {
// This is faster than adding codepoints one by one.
this.text += chunk.substring(start);
return;
}
const code = this.getCode();
if (code === q || code === AMP || code === LESS) {
// This is faster than adding codepoints one by one.
const slice = chunk.substring(start,
this.i - (code <= 0xFFFF ? 1 : 2));
switch (code) {
case q:
this.pushAttrib(this.name, this.text + slice);
this.name = this.text = "";
this.q = null;
this.state = S_ATTRIB_VALUE_CLOSED;
return;
case AMP:
this.text += slice;
this.state = S_ENTITY;
this.entityReturnState = S_ATTRIB_VALUE_QUOTED;
return;
default:
this.text += slice;
this.fail("disallowed character.");
return;
}
}
}
}
@@ -1470,17 +1682,17 @@ class SaxesParser {
if (isS(c)) {
this.state = S_ATTRIB;
}
else if (isNameStartChar(c)) {
this.fail("no whitespace between attributes.");
this.name = String.fromCodePoint(c);
this.state = S_ATTRIB_NAME;
}
else if (c === GREATER) {
this.openTag();
}
else if (c === FORWARD_SLASH) {
this.state = S_OPEN_TAG_SLASH;
}
else if (isNameStartChar(c)) {
this.fail("no whitespace between attributes.");
this.name = String.fromCodePoint(c);
this.state = S_ATTRIB_NAME;
}
else {
this.fail("disallowed character in attribute name.");
}
@@ -1490,7 +1702,7 @@ class SaxesParser {
sAttribValueUnquoted() {
const c = this.captureTo(ATTRIB_VALUE_UNQUOTED_TERMINATOR, "text");
if (c === AMP) {
this.state = S_ENTITY_FIRST_CHAR;
this.state = S_ENTITY;
this.entityReturnState = S_ATTRIB_VALUE_UNQUOTED;
}
else if (c === LESS) {
@@ -1527,59 +1739,26 @@ class SaxesParser {
/** @private */
sCloseTagSawWhite() {
const c = this.getCode();
const c = this.skipSpaces();
if (c === GREATER) {
this.closeTag();
}
else if (c && !isS(c)) {
else if (c) {
this.fail("disallowed character in closing tag.");
}
}
/** @private */
sEntityFirstChar() {
const c = this.getCode();
if (this.nameStartCheck(c) || c === HASH) {
this.entity = String.fromCodePoint(c);
this.state = S_ENTITY_REST;
}
else if (c === SEMICOLON) {
this.fail("empty entity name.");
this.text += "&;";
sEntity() {
if (this.captureToChar(SEMICOLON, "entity")) {
this.state = this.entityReturnState;
}
else {
this.fail("disallowed first character in entity name.");
this.entity = String.fromCodePoint(c);
this.badEntityName = true;
this.state = S_ENTITY_REST;
}
}
/** @private */
sEntityRest() {
const c = this.captureWhileNameCheck("entity");
if (c === SEMICOLON) {
// Don't try to convert if the name was bad.
if (this.badEntityName) {
this.text += `&${this.entity}${String.fromCodePoint(c)}`;
if (this.entity === "") {
this.fail("empty entity name.");
this.text += "&;";
return;
}
else {
this.text += this.parseEntity(this.entity);
}
this.textCheckedBefore = this.text.length;
this.text += this.parseEntity(this.entity);
this.entity = "";
this.state = this.entityReturnState;
this.badEntityName = false;
}
else if (c) {
this.fail("disallowed character in entity name.");
this.text += `&${this.entity}${String.fromCodePoint(c)}`;
this.textCheckedBefore = this.text.length;
this.entity = "";
this.state = this.entityReturnState;
this.badEntityName = false;
}
}
@@ -1602,7 +1781,7 @@ class SaxesParser {
const tag = tags.pop();
this.fail(`unclosed tag: ${tag.name}`);
}
if ((this.state !== S_BEGIN_WHITESPACE) &&
if ((this.state !== S_INITIAL) &&
(this.state !== S_TEXT)) {
this.fail("unexpected end.");
}
@@ -1623,7 +1802,6 @@ class SaxesParser {
closeText() {
this.ontext(this.text);
this.text = "";
this.textCheckedBefore = 0;
}
/**
@@ -1668,7 +1846,7 @@ class SaxesParser {
*/
qname(name) {
const colon = name.indexOf(":");
if (colon < 0) {
if (colon === -1) {
return { prefix: "", local: name };
}
@@ -1705,6 +1883,10 @@ class SaxesParser {
}
}
if (attribList.length === 0) {
return;
}
const seen = new Set();
// Note: do not apply default ns to attributes:
// http://www.w3.org/TR/REC-xml-names/#defaulting
@@ -1851,19 +2033,23 @@ class SaxesParser {
* @returns {string} The parsed entity.
*/
parseEntity(entity) {
const defined = this.ENTITIES[entity];
if (defined) {
return defined;
if (entity[0] !== "#") {
const defined = this.ENTITIES[entity];
if (defined) {
return defined;
}
this.fail(this.isName(entity) ? "undefined entity." :
"disallowed character in entity name.");
return `&${entity};`;
}
let num = NaN;
if (entity[0] === "#") {
if (entity[1] === "x" && /^#x[0-9a-f]+$/i.test(entity)) {
num = parseInt(entity.slice(2), 16);
}
else if (/^#[0-9]+$/.test(entity)) {
num = parseInt(entity.slice(1), 10);
}
if (entity[1] === "x" && /^#x[0-9a-f]+$/i.test(entity)) {
num = parseInt(entity.slice(2), 16);
}
else if (/^#[0-9]+$/.test(entity)) {
num = parseInt(entity.slice(1), 10);
}
// The character reference is required to match the CHAR production.

38
node_modules/saxes/package.json generated vendored
View File

@@ -1,26 +1,26 @@
{
"_from": "saxes@^3.1.5",
"_id": "saxes@3.1.9",
"_from": "saxes@^3.1.9",
"_id": "saxes@3.1.11",
"_inBundle": false,
"_integrity": "sha512-FZeKhJglhJHk7eWG5YM0z46VHmI3KJpMBAQm3xa9meDvd+wevB5GuBB0wc0exPInZiBBHqi00DbS8AcvCGCFMw==",
"_integrity": "sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g==",
"_location": "/saxes",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "saxes@^3.1.5",
"raw": "saxes@^3.1.9",
"name": "saxes",
"escapedName": "saxes",
"rawSpec": "^3.1.5",
"rawSpec": "^3.1.9",
"saveSpec": null,
"fetchSpec": "^3.1.5"
"fetchSpec": "^3.1.9"
},
"_requiredBy": [
"/jsdom"
],
"_resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.9.tgz",
"_shasum": "c1c197cd54956d88c09f960254b999e192d7058b",
"_spec": "saxes@^3.1.5",
"_resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.11.tgz",
"_shasum": "d59d1fd332ec92ad98a2e0b2ee644702384b1c5b",
"_spec": "saxes@^3.1.9",
"_where": "F:\\projects\\p\\minifyfromhtml\\node_modules\\jsdom",
"author": {
"name": "Louis-Dominique Dubeau",
@@ -31,21 +31,21 @@
},
"bundleDependencies": false,
"dependencies": {
"xmlchars": "^1.3.1"
"xmlchars": "^2.1.1"
},
"deprecated": false,
"description": "An evented streaming XML parser in JavaScript",
"devDependencies": {
"@commitlint/cli": "^7.5.2",
"@commitlint/config-angular": "^7.5.0",
"@commitlint/cli": "^8.0.0",
"@commitlint/config-angular": "^8.0.0",
"chai": "^4.2.0",
"conventional-changelog-cli": "^2.0.12",
"eslint": "^5.14.1",
"eslint-config-lddubeau-base": "^3.0.1",
"husky": "^1.3.1",
"mocha": "^6.0.1",
"conventional-changelog-cli": "^2.0.21",
"eslint": "^5.16.0",
"eslint-config-lddubeau-base": "^3.0.5",
"husky": "^2.5.0",
"mocha": "^6.1.4",
"renovate-config-lddubeau": "^1.0.0",
"xml-conformance-suite": "^1.1.0"
"xml-conformance-suite": "^1.2.0"
},
"engines": {
"node": ">=8"
@@ -79,5 +79,5 @@
"version": "conventional-changelog -p angular -i CHANGELOG.md -s && git add CHANGELOG.md"
},
"types": "lib/saxes.d.ts",
"version": "3.1.9"
"version": "3.1.11"
}