.gitignore added
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-prettier / node_modules / postcss-html / lib / html-parser.js
1 "use strict";
2
3 const htmlparser = require("htmlparser2");
4
5 function iterateCode (source, onStyleTag, onStyleAttribute) {
6         let currentStyle = null;
7         let level = 0;
8         let isFirstTag = true;
9
10         function onFirstTag () {
11                 // Found a tag, the structure is now confirmed as HTML
12                 if (isFirstTag) {
13                         if (parser.startIndex <= 0 || !source.slice(0, parser.startIndex).trim()) {
14                                 level = 2;
15                         }
16                         isFirstTag = false;
17                 }
18         }
19
20         const parser = new htmlparser.Parser({
21                 oncomment: onFirstTag,
22                 onprocessinginstruction: onFirstTag,
23                 onopentag (name, attribute) {
24                         onFirstTag();
25
26                         if (!level) {
27                                 level = 1;
28                         }
29
30                         // Test if current tag is a valid <style> tag.
31                         if (name !== "style") {
32                                 return;
33                         }
34                         currentStyle = {
35                                 attribute,
36                                 startIndex: parser.endIndex + 1,
37                         };
38                 },
39
40                 onclosetag (name) {
41                         if (name !== "style" || currentStyle === null) {
42                                 return;
43                         }
44                         currentStyle.content = source.slice(currentStyle.startIndex, parser.startIndex);
45                         onStyleTag(currentStyle);
46                         currentStyle = null;
47                 },
48
49                 onattribute (name, value) {
50                         if (name !== "style") {
51                                 return;
52                         }
53                         onStyleAttribute(value, parser.endIndex);
54                 },
55         });
56
57         parser.parseComplete(source);
58
59         return level;
60 }
61
62 function getSubString (str, regexp) {
63         const subStr = str && regexp.exec(str);
64         if (subStr) {
65                 return subStr[1].toLowerCase();
66         }
67 }
68
69 function getLang (attribute) {
70         return getSubString(attribute.type, /^\w+\/(?:x-)?(\w+)$/i) || getSubString(attribute.lang, /^(\w+)(?:\?.+)?$/) || "css";
71 }
72
73 function htmlParser (source, opts) {
74         const styles = [];
75         function onStyleTag (style) {
76                 const firstNewLine = /^[ \t]*\r?\n/.exec(style.content);
77                 style.lang = getLang(style.attribute);
78                 if (firstNewLine) {
79                         const offset = firstNewLine[0].length;
80                         style.startIndex += offset;
81                         style.content = style.content.slice(offset);
82                 }
83                 style.content = style.content.replace(/[ \t]*$/, "");
84                 style.isHTMLTag = true;
85                 styles.push(style);
86         }
87         function onStyleAttribute (content, index) {
88                 styles.push({
89                         content: content,
90                         startIndex: source.indexOf(content, index),
91                         isHTMLAttribute: true,
92                 });
93         }
94         const level = iterateCode(source, onStyleTag, onStyleAttribute);
95
96         if (opts.from ? !level : level < 2) {
97                 return;
98         }
99
100         return styles;
101 }
102
103 module.exports = htmlParser;