UNPKG

5.89 kBJavaScriptView Raw
1(function (global, factory) {
2 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
3 typeof define === 'function' && define.amd ? define(factory) :
4 (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.InlineStyleParser = factory());
5})(this, (function () { 'use strict';
6
7 function getDefaultExportFromCjs (x) {
8 return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
9 }
10
11 // http://www.w3.org/TR/CSS21/grammar.html
12 // https://github.com/visionmedia/css-parse/pull/49#issuecomment-30088027
13 var COMMENT_REGEX = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//g;
14
15 var NEWLINE_REGEX = /\n/g;
16 var WHITESPACE_REGEX = /^\s*/;
17
18 // declaration
19 var PROPERTY_REGEX = /^(\*?[-#/*\\\w]+(\[[0-9a-z_-]+\])?)\s*/;
20 var COLON_REGEX = /^:\s*/;
21 var VALUE_REGEX = /^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^)]*?\)|[^};])+)/;
22 var SEMICOLON_REGEX = /^[;\s]*/;
23
24 // https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/Trim#Polyfill
25 var TRIM_REGEX = /^\s+|\s+$/g;
26
27 // strings
28 var NEWLINE = '\n';
29 var FORWARD_SLASH = '/';
30 var ASTERISK = '*';
31 var EMPTY_STRING = '';
32
33 // types
34 var TYPE_COMMENT = 'comment';
35 var TYPE_DECLARATION = 'declaration';
36
37 /**
38 * @param {String} style
39 * @param {Object} [options]
40 * @return {Object[]}
41 * @throws {TypeError}
42 * @throws {Error}
43 */
44 var inlineStyleParser = function (style, options) {
45 if (typeof style !== 'string') {
46 throw new TypeError('First argument must be a string');
47 }
48
49 if (!style) return [];
50
51 options = options || {};
52
53 /**
54 * Positional.
55 */
56 var lineno = 1;
57 var column = 1;
58
59 /**
60 * Update lineno and column based on `str`.
61 *
62 * @param {String} str
63 */
64 function updatePosition(str) {
65 var lines = str.match(NEWLINE_REGEX);
66 if (lines) lineno += lines.length;
67 var i = str.lastIndexOf(NEWLINE);
68 column = ~i ? str.length - i : column + str.length;
69 }
70
71 /**
72 * Mark position and patch `node.position`.
73 *
74 * @return {Function}
75 */
76 function position() {
77 var start = { line: lineno, column: column };
78 return function (node) {
79 node.position = new Position(start);
80 whitespace();
81 return node;
82 };
83 }
84
85 /**
86 * Store position information for a node.
87 *
88 * @constructor
89 * @property {Object} start
90 * @property {Object} end
91 * @property {undefined|String} source
92 */
93 function Position(start) {
94 this.start = start;
95 this.end = { line: lineno, column: column };
96 this.source = options.source;
97 }
98
99 /**
100 * Non-enumerable source string.
101 */
102 Position.prototype.content = style;
103
104 /**
105 * Error `msg`.
106 *
107 * @param {String} msg
108 * @throws {Error}
109 */
110 function error(msg) {
111 var err = new Error(
112 options.source + ':' + lineno + ':' + column + ': ' + msg
113 );
114 err.reason = msg;
115 err.filename = options.source;
116 err.line = lineno;
117 err.column = column;
118 err.source = style;
119
120 if (options.silent) ; else {
121 throw err;
122 }
123 }
124
125 /**
126 * Match `re` and return captures.
127 *
128 * @param {RegExp} re
129 * @return {undefined|Array}
130 */
131 function match(re) {
132 var m = re.exec(style);
133 if (!m) return;
134 var str = m[0];
135 updatePosition(str);
136 style = style.slice(str.length);
137 return m;
138 }
139
140 /**
141 * Parse whitespace.
142 */
143 function whitespace() {
144 match(WHITESPACE_REGEX);
145 }
146
147 /**
148 * Parse comments.
149 *
150 * @param {Object[]} [rules]
151 * @return {Object[]}
152 */
153 function comments(rules) {
154 var c;
155 rules = rules || [];
156 while ((c = comment())) {
157 if (c !== false) {
158 rules.push(c);
159 }
160 }
161 return rules;
162 }
163
164 /**
165 * Parse comment.
166 *
167 * @return {Object}
168 * @throws {Error}
169 */
170 function comment() {
171 var pos = position();
172 if (FORWARD_SLASH != style.charAt(0) || ASTERISK != style.charAt(1)) return;
173
174 var i = 2;
175 while (
176 EMPTY_STRING != style.charAt(i) &&
177 (ASTERISK != style.charAt(i) || FORWARD_SLASH != style.charAt(i + 1))
178 ) {
179 ++i;
180 }
181 i += 2;
182
183 if (EMPTY_STRING === style.charAt(i - 1)) {
184 return error('End of comment missing');
185 }
186
187 var str = style.slice(2, i - 2);
188 column += 2;
189 updatePosition(str);
190 style = style.slice(i);
191 column += 2;
192
193 return pos({
194 type: TYPE_COMMENT,
195 comment: str
196 });
197 }
198
199 /**
200 * Parse declaration.
201 *
202 * @return {Object}
203 * @throws {Error}
204 */
205 function declaration() {
206 var pos = position();
207
208 // prop
209 var prop = match(PROPERTY_REGEX);
210 if (!prop) return;
211 comment();
212
213 // :
214 if (!match(COLON_REGEX)) return error("property missing ':'");
215
216 // val
217 var val = match(VALUE_REGEX);
218
219 var ret = pos({
220 type: TYPE_DECLARATION,
221 property: trim(prop[0].replace(COMMENT_REGEX, EMPTY_STRING)),
222 value: val
223 ? trim(val[0].replace(COMMENT_REGEX, EMPTY_STRING))
224 : EMPTY_STRING
225 });
226
227 // ;
228 match(SEMICOLON_REGEX);
229
230 return ret;
231 }
232
233 /**
234 * Parse declarations.
235 *
236 * @return {Object[]}
237 */
238 function declarations() {
239 var decls = [];
240
241 comments(decls);
242
243 // declarations
244 var decl;
245 while ((decl = declaration())) {
246 if (decl !== false) {
247 decls.push(decl);
248 comments(decls);
249 }
250 }
251
252 return decls;
253 }
254
255 whitespace();
256 return declarations();
257 };
258
259 /**
260 * Trim `str`.
261 *
262 * @param {String} str
263 * @return {String}
264 */
265 function trim(str) {
266 return str ? str.replace(TRIM_REGEX, EMPTY_STRING) : EMPTY_STRING;
267 }
268
269 var index = /*@__PURE__*/getDefaultExportFromCjs(inlineStyleParser);
270
271 return index;
272
273}));
274//# sourceMappingURL=inline-style-parser.js.map