3 const htmlparser = require("htmlparser2");
5 function iterateCode (source, onStyleTag, onStyleAttribute) {
6 let currentStyle = null;
10 function onFirstTag () {
11 // Found a tag, the structure is now confirmed as HTML
13 if (parser.startIndex <= 0 || !source.slice(0, parser.startIndex).trim()) {
20 const parser = new htmlparser.Parser({
21 oncomment: onFirstTag,
22 onprocessinginstruction: onFirstTag,
23 onopentag (name, attribute) {
30 // Test if current tag is a valid <style> tag.
31 if (name !== "style") {
36 startIndex: parser.endIndex + 1,
41 if (name !== "style" || currentStyle === null) {
44 currentStyle.content = source.slice(currentStyle.startIndex, parser.startIndex);
45 onStyleTag(currentStyle);
49 onattribute (name, value) {
50 if (name !== "style") {
53 onStyleAttribute(value, parser.endIndex);
57 parser.parseComplete(source);
62 function getSubString (str, regexp) {
63 const subStr = str && regexp.exec(str);
65 return subStr[1].toLowerCase();
69 function getLang (attribute) {
70 return getSubString(attribute.type, /^\w+\/(?:x-)?(\w+)$/i) || getSubString(attribute.lang, /^(\w+)(?:\?.+)?$/) || "css";
73 function htmlParser (source, opts) {
75 function onStyleTag (style) {
76 const firstNewLine = /^[ \t]*\r?\n/.exec(style.content);
77 style.lang = getLang(style.attribute);
79 const offset = firstNewLine[0].length;
80 style.startIndex += offset;
81 style.content = style.content.slice(offset);
83 style.content = style.content.replace(/[ \t]*$/, "");
84 style.isHTMLTag = true;
87 function onStyleAttribute (content, index) {
90 startIndex: source.indexOf(content, index),
91 isHTMLAttribute: true,
94 const level = iterateCode(source, onStyleTag, onStyleAttribute);
96 if (opts.from ? !level : level < 2) {
103 module.exports = htmlParser;