123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122 |
- "use strict";
-
- const htmlparser = require("htmlparser2");
- const loadSyntax = require("postcss-syntax/load-syntax");
-
- function iterateCode (source, onStyleTag, onStyleAttribute) {
- const openTag = {};
- let disable;
- let style;
-
- const parser = new htmlparser.Parser({
- oncomment: (data) => {
- if (!/(?:^|\s+)postcss-(\w+)(?:\s+|$)/i.test(data)) {
- return;
- }
- data = RegExp.$1.toLowerCase();
- if (data === "enable") {
- disable = false;
- } else if (data === "disable") {
- disable = true;
- }
- },
- onopentag (name, attribute) {
- openTag[name] = true;
-
- // Test if current tag is a valid <style> tag.
- if (!/^style$/i.test(name)) {
- return;
- }
-
- style = {
- inXsls: openTag["xsl:stylesheet"],
- inXslt: openTag["xsl:template"],
- inHtml: openTag.html,
- tagName: name,
- attribute,
- startIndex: parser.endIndex + 1,
- };
- },
-
- onclosetag (name) {
- openTag[name] = false;
- if (disable || !style || name !== style.tagName) {
- return;
- }
-
- let content = source.slice(style.startIndex, parser.startIndex);
-
- const firstNewLine = /^[ \t]*\r?\n/.exec(content);
- if (firstNewLine) {
- const offset = firstNewLine[0].length;
- style.startIndex += offset;
- content = content.slice(offset);
- }
- style.content = content.replace(/[ \t]*$/, "");
-
- onStyleTag(style);
- style = null;
- },
-
- onattribute (name, content) {
- if (disable || name !== "style") {
- return;
- }
- const endIndex = parser._tokenizer._index;
- const startIndex = endIndex - content.length;
- if (source[startIndex - 1] !== source[endIndex] || !/\S/.test(source[endIndex])) {
- return;
- }
- onStyleAttribute({
- content,
- startIndex,
- inline: true,
- inTemplate: openTag.template,
- });
- },
- });
-
- parser.parseComplete(source);
- }
-
- function getSubString (str, regexp) {
- const subStr = str && regexp.exec(str);
- if (subStr) {
- return subStr[1].toLowerCase();
- }
- }
-
- function getLang (attribute) {
- return getSubString(attribute.type, /^\w+\/(?:x-)?(\w+)$/i) || getSubString(attribute.lang, /^(\w+)(?:\?.+)?$/) || "css";
- }
-
- function htmlParser (source, opts, styles) {
- styles = styles || [];
-
- const standard = opts.from && /\.(?:\w*html?|xht|xslt?|jsp|aspx?|ejs|php\d*|twig|liquid|m(?:ark)?d(?:ow)?n|mk?d)$/i.test(opts.from);
-
- function onStyleTag (style) {
- if (!(style.inHtml || style.inXsls || style.inXslt || standard) && (style.attribute.src || style.attribute.href) && !style.content.trim()) {
- return;
- }
- style.lang = getLang(style.attribute);
- styles.push(style);
- }
-
- function onStyleAttribute (style) {
- if (/{[\s\S]*?}/g.test(style.content)) {
- style.syntax = loadSyntax(opts, __dirname);
- style.lang = "custom-template";
- } else {
- // style.ignoreErrors = opts.from && /\.(?:jsp|aspx?|ejs|php\d*|twig)$/i.test(opts.from);
- style.lang = "css";
- }
- styles.push(style);
- }
-
- iterateCode(source, onStyleTag, onStyleAttribute);
-
- return styles;
- }
-
- module.exports = htmlParser;
|