@acemir/cssom 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,344 @@
1
+ //.CommonJS
2
+ var CSSOM = {
3
+ CSSValue: require('./CSSValue').CSSValue
4
+ };
5
+ ///CommonJS
6
+
7
+
8
+ /**
9
+ * @constructor
10
+ * @see http://msdn.microsoft.com/en-us/library/ms537634(v=vs.85).aspx
11
+ *
12
+ */
13
+ CSSOM.CSSValueExpression = function CSSValueExpression(token, idx) {
14
+ this._token = token;
15
+ this._idx = idx;
16
+ };
17
+
18
+ CSSOM.CSSValueExpression.prototype = new CSSOM.CSSValue();
19
+ CSSOM.CSSValueExpression.prototype.constructor = CSSOM.CSSValueExpression;
20
+
21
+ /**
22
+ * parse css expression() value
23
+ *
24
+ * @return {Object}
25
+ * - error:
26
+ * or
27
+ * - idx:
28
+ * - expression:
29
+ *
30
+ * Example:
31
+ *
32
+ * .selector {
33
+ * zoom: expression(documentElement.clientWidth > 1000 ? '1000px' : 'auto');
34
+ * }
35
+ */
36
+ CSSOM.CSSValueExpression.prototype.parse = function() {
37
+ var token = this._token,
38
+ idx = this._idx;
39
+
40
+ var character = '',
41
+ expression = '',
42
+ error = '',
43
+ info,
44
+ paren = [];
45
+
46
+
47
+ for (; ; ++idx) {
48
+ character = token.charAt(idx);
49
+
50
+ // end of token
51
+ if (character === '') {
52
+ error = 'css expression error: unfinished expression!';
53
+ break;
54
+ }
55
+
56
+ switch(character) {
57
+ case '(':
58
+ paren.push(character);
59
+ expression += character;
60
+ break;
61
+
62
+ case ')':
63
+ paren.pop(character);
64
+ expression += character;
65
+ break;
66
+
67
+ case '/':
68
+ if ((info = this._parseJSComment(token, idx))) { // comment?
69
+ if (info.error) {
70
+ error = 'css expression error: unfinished comment in expression!';
71
+ } else {
72
+ idx = info.idx;
73
+ // ignore the comment
74
+ }
75
+ } else if ((info = this._parseJSRexExp(token, idx))) { // regexp
76
+ idx = info.idx;
77
+ expression += info.text;
78
+ } else { // other
79
+ expression += character;
80
+ }
81
+ break;
82
+
83
+ case "'":
84
+ case '"':
85
+ info = this._parseJSString(token, idx, character);
86
+ if (info) { // string
87
+ idx = info.idx;
88
+ expression += info.text;
89
+ } else {
90
+ expression += character;
91
+ }
92
+ break;
93
+
94
+ default:
95
+ expression += character;
96
+ break;
97
+ }
98
+
99
+ if (error) {
100
+ break;
101
+ }
102
+
103
+ // end of expression
104
+ if (paren.length === 0) {
105
+ break;
106
+ }
107
+ }
108
+
109
+ var ret;
110
+ if (error) {
111
+ ret = {
112
+ error: error
113
+ };
114
+ } else {
115
+ ret = {
116
+ idx: idx,
117
+ expression: expression
118
+ };
119
+ }
120
+
121
+ return ret;
122
+ };
123
+
124
+
125
+ /**
126
+ *
127
+ * @return {Object|false}
128
+ * - idx:
129
+ * - text:
130
+ * or
131
+ * - error:
132
+ * or
133
+ * false
134
+ *
135
+ */
136
+ CSSOM.CSSValueExpression.prototype._parseJSComment = function(token, idx) {
137
+ var nextChar = token.charAt(idx + 1),
138
+ text;
139
+
140
+ if (nextChar === '/' || nextChar === '*') {
141
+ var startIdx = idx,
142
+ endIdx,
143
+ commentEndChar;
144
+
145
+ if (nextChar === '/') { // line comment
146
+ commentEndChar = '\n';
147
+ } else if (nextChar === '*') { // block comment
148
+ commentEndChar = '*/';
149
+ }
150
+
151
+ endIdx = token.indexOf(commentEndChar, startIdx + 1 + 1);
152
+ if (endIdx !== -1) {
153
+ endIdx = endIdx + commentEndChar.length - 1;
154
+ text = token.substring(idx, endIdx + 1);
155
+ return {
156
+ idx: endIdx,
157
+ text: text
158
+ };
159
+ } else {
160
+ var error = 'css expression error: unfinished comment in expression!';
161
+ return {
162
+ error: error
163
+ };
164
+ }
165
+ } else {
166
+ return false;
167
+ }
168
+ };
169
+
170
+
171
+ /**
172
+ *
173
+ * @return {Object|false}
174
+ * - idx:
175
+ * - text:
176
+ * or
177
+ * false
178
+ *
179
+ */
180
+ CSSOM.CSSValueExpression.prototype._parseJSString = function(token, idx, sep) {
181
+ var endIdx = this._findMatchedIdx(token, idx, sep),
182
+ text;
183
+
184
+ if (endIdx === -1) {
185
+ return false;
186
+ } else {
187
+ text = token.substring(idx, endIdx + sep.length);
188
+
189
+ return {
190
+ idx: endIdx,
191
+ text: text
192
+ };
193
+ }
194
+ };
195
+
196
+
197
+ /**
198
+ * parse regexp in css expression
199
+ *
200
+ * @return {Object|false}
201
+ * - idx:
202
+ * - regExp:
203
+ * or
204
+ * false
205
+ */
206
+
207
+ /*
208
+
209
+ all legal RegExp
210
+
211
+ /a/
212
+ (/a/)
213
+ [/a/]
214
+ [12, /a/]
215
+
216
+ !/a/
217
+
218
+ +/a/
219
+ -/a/
220
+ * /a/
221
+ / /a/
222
+ %/a/
223
+
224
+ ===/a/
225
+ !==/a/
226
+ ==/a/
227
+ !=/a/
228
+ >/a/
229
+ >=/a/
230
+ </a/
231
+ <=/a/
232
+
233
+ &/a/
234
+ |/a/
235
+ ^/a/
236
+ ~/a/
237
+ <</a/
238
+ >>/a/
239
+ >>>/a/
240
+
241
+ &&/a/
242
+ ||/a/
243
+ ?/a/
244
+ =/a/
245
+ ,/a/
246
+
247
+ delete /a/
248
+ in /a/
249
+ instanceof /a/
250
+ new /a/
251
+ typeof /a/
252
+ void /a/
253
+
254
+ */
255
+ CSSOM.CSSValueExpression.prototype._parseJSRexExp = function(token, idx) {
256
+ var before = token.substring(0, idx).replace(/\s+$/, ""),
257
+ legalRegx = [
258
+ /^$/,
259
+ /\($/,
260
+ /\[$/,
261
+ /\!$/,
262
+ /\+$/,
263
+ /\-$/,
264
+ /\*$/,
265
+ /\/\s+/,
266
+ /\%$/,
267
+ /\=$/,
268
+ /\>$/,
269
+ /<$/,
270
+ /\&$/,
271
+ /\|$/,
272
+ /\^$/,
273
+ /\~$/,
274
+ /\?$/,
275
+ /\,$/,
276
+ /delete$/,
277
+ /in$/,
278
+ /instanceof$/,
279
+ /new$/,
280
+ /typeof$/,
281
+ /void$/
282
+ ];
283
+
284
+ var isLegal = legalRegx.some(function(reg) {
285
+ return reg.test(before);
286
+ });
287
+
288
+ if (!isLegal) {
289
+ return false;
290
+ } else {
291
+ var sep = '/';
292
+
293
+ // same logic as string
294
+ return this._parseJSString(token, idx, sep);
295
+ }
296
+ };
297
+
298
+
299
+ /**
300
+ *
301
+ * find next sep(same line) index in `token`
302
+ *
303
+ * @return {Number}
304
+ *
305
+ */
306
+ CSSOM.CSSValueExpression.prototype._findMatchedIdx = function(token, idx, sep) {
307
+ var startIdx = idx,
308
+ endIdx;
309
+
310
+ var NOT_FOUND = -1;
311
+
312
+ while(true) {
313
+ endIdx = token.indexOf(sep, startIdx + 1);
314
+
315
+ if (endIdx === -1) { // not found
316
+ endIdx = NOT_FOUND;
317
+ break;
318
+ } else {
319
+ var text = token.substring(idx + 1, endIdx),
320
+ matched = text.match(/\\+$/);
321
+ if (!matched || matched[0] % 2 === 0) { // not escaped
322
+ break;
323
+ } else {
324
+ startIdx = endIdx;
325
+ }
326
+ }
327
+ }
328
+
329
+ // boundary must be in the same line(js sting or regexp)
330
+ var nextNewLineIdx = token.indexOf('\n', idx + 1);
331
+ if (nextNewLineIdx < endIdx) {
332
+ endIdx = NOT_FOUND;
333
+ }
334
+
335
+
336
+ return endIdx;
337
+ };
338
+
339
+
340
+
341
+
342
+ //.CommonJS
343
+ exports.CSSValueExpression = CSSOM.CSSValueExpression;
344
+ ///CommonJS
@@ -0,0 +1,62 @@
1
+ //.CommonJS
2
+ var CSSOM = {};
3
+ ///CommonJS
4
+
5
+
6
+ /**
7
+ * @constructor
8
+ * @see https://developer.mozilla.org/en/CSS/@-moz-document
9
+ */
10
+ CSSOM.MatcherList = function MatcherList(){
11
+ this.length = 0;
12
+ };
13
+
14
+ CSSOM.MatcherList.prototype = {
15
+
16
+ constructor: CSSOM.MatcherList,
17
+
18
+ /**
19
+ * @return {string}
20
+ */
21
+ get matcherText() {
22
+ return Array.prototype.join.call(this, ", ");
23
+ },
24
+
25
+ /**
26
+ * @param {string} value
27
+ */
28
+ set matcherText(value) {
29
+ // just a temporary solution, actually it may be wrong by just split the value with ',', because a url can include ','.
30
+ var values = value.split(",");
31
+ var length = this.length = values.length;
32
+ for (var i=0; i<length; i++) {
33
+ this[i] = values[i].trim();
34
+ }
35
+ },
36
+
37
+ /**
38
+ * @param {string} matcher
39
+ */
40
+ appendMatcher: function(matcher) {
41
+ if (Array.prototype.indexOf.call(this, matcher) === -1) {
42
+ this[this.length] = matcher;
43
+ this.length++;
44
+ }
45
+ },
46
+
47
+ /**
48
+ * @param {string} matcher
49
+ */
50
+ deleteMatcher: function(matcher) {
51
+ var index = Array.prototype.indexOf.call(this, matcher);
52
+ if (index !== -1) {
53
+ Array.prototype.splice.call(this, index, 1);
54
+ }
55
+ }
56
+
57
+ };
58
+
59
+
60
+ //.CommonJS
61
+ exports.MatcherList = CSSOM.MatcherList;
62
+ ///CommonJS
@@ -0,0 +1,61 @@
1
+ //.CommonJS
2
+ var CSSOM = {};
3
+ ///CommonJS
4
+
5
+
6
+ /**
7
+ * @constructor
8
+ * @see http://dev.w3.org/csswg/cssom/#the-medialist-interface
9
+ */
10
+ CSSOM.MediaList = function MediaList(){
11
+ this.length = 0;
12
+ };
13
+
14
+ CSSOM.MediaList.prototype = {
15
+
16
+ constructor: CSSOM.MediaList,
17
+
18
+ /**
19
+ * @return {string}
20
+ */
21
+ get mediaText() {
22
+ return Array.prototype.join.call(this, ", ");
23
+ },
24
+
25
+ /**
26
+ * @param {string} value
27
+ */
28
+ set mediaText(value) {
29
+ var values = value.split(",");
30
+ var length = this.length = values.length;
31
+ for (var i=0; i<length; i++) {
32
+ this[i] = values[i].trim();
33
+ }
34
+ },
35
+
36
+ /**
37
+ * @param {string} medium
38
+ */
39
+ appendMedium: function(medium) {
40
+ if (Array.prototype.indexOf.call(this, medium) === -1) {
41
+ this[this.length] = medium;
42
+ this.length++;
43
+ }
44
+ },
45
+
46
+ /**
47
+ * @param {string} medium
48
+ */
49
+ deleteMedium: function(medium) {
50
+ var index = Array.prototype.indexOf.call(this, medium);
51
+ if (index !== -1) {
52
+ Array.prototype.splice.call(this, index, 1);
53
+ }
54
+ }
55
+
56
+ };
57
+
58
+
59
+ //.CommonJS
60
+ exports.MediaList = CSSOM.MediaList;
61
+ ///CommonJS
@@ -0,0 +1,17 @@
1
+ //.CommonJS
2
+ var CSSOM = {};
3
+ ///CommonJS
4
+
5
+
6
+ /**
7
+ * @constructor
8
+ * @see http://dev.w3.org/csswg/cssom/#the-stylesheet-interface
9
+ */
10
+ CSSOM.StyleSheet = function StyleSheet() {
11
+ this.parentStyleSheet = null;
12
+ };
13
+
14
+
15
+ //.CommonJS
16
+ exports.StyleSheet = CSSOM.StyleSheet;
17
+ ///CommonJS
package/lib/clone.js ADDED
@@ -0,0 +1,81 @@
1
+ //.CommonJS
2
+ var CSSOM = {
3
+ CSSStyleSheet: require("./CSSStyleSheet").CSSStyleSheet,
4
+ CSSRule: require("./CSSRule").CSSRule,
5
+ CSSNestedDeclarations: require("./CSSNestedDeclarations").CSSNestedDeclarations,
6
+ CSSStyleRule: require("./CSSStyleRule").CSSStyleRule,
7
+ CSSGroupingRule: require("./CSSGroupingRule").CSSGroupingRule,
8
+ CSSConditionRule: require("./CSSConditionRule").CSSConditionRule,
9
+ CSSMediaRule: require("./CSSMediaRule").CSSMediaRule,
10
+ CSSContainerRule: require("./CSSContainerRule").CSSContainerRule,
11
+ CSSSupportsRule: require("./CSSSupportsRule").CSSSupportsRule,
12
+ CSSStyleDeclaration: require("./CSSStyleDeclaration").CSSStyleDeclaration,
13
+ CSSKeyframeRule: require('./CSSKeyframeRule').CSSKeyframeRule,
14
+ CSSKeyframesRule: require('./CSSKeyframesRule').CSSKeyframesRule,
15
+ CSSLayerBlockRule: require('./CSSLayerBlockRule').CSSLayerBlockRule
16
+ };
17
+ ///CommonJS
18
+
19
+
20
+ /**
21
+ * Produces a deep copy of stylesheet — the instance variables of stylesheet are copied recursively.
22
+ * @param {CSSStyleSheet|CSSOM.CSSStyleSheet} stylesheet
23
+ * @nosideeffects
24
+ * @return {CSSOM.CSSStyleSheet}
25
+ */
26
+ CSSOM.clone = function clone(stylesheet) {
27
+
28
+ var cloned = new CSSOM.CSSStyleSheet();
29
+
30
+ var rules = stylesheet.cssRules;
31
+ if (!rules) {
32
+ return cloned;
33
+ }
34
+
35
+ for (var i = 0, rulesLength = rules.length; i < rulesLength; i++) {
36
+ var rule = rules[i];
37
+ var ruleClone = cloned.cssRules[i] = new rule.constructor();
38
+
39
+ var style = rule.style;
40
+ if (style) {
41
+ var styleClone = ruleClone.style = new CSSOM.CSSStyleDeclaration();
42
+ for (var j = 0, styleLength = style.length; j < styleLength; j++) {
43
+ var name = styleClone[j] = style[j];
44
+ styleClone[name] = style[name];
45
+ styleClone._importants[name] = style.getPropertyPriority(name);
46
+ }
47
+ styleClone.length = style.length;
48
+ }
49
+
50
+ if (rule.hasOwnProperty('keyText')) {
51
+ ruleClone.keyText = rule.keyText;
52
+ }
53
+
54
+ if (rule.hasOwnProperty('selectorText')) {
55
+ ruleClone.selectorText = rule.selectorText;
56
+ }
57
+
58
+ if (rule.hasOwnProperty('mediaText')) {
59
+ ruleClone.mediaText = rule.mediaText;
60
+ }
61
+
62
+ if (rule.hasOwnProperty('conditionText')) {
63
+ ruleClone.conditionText = rule.conditionText;
64
+ }
65
+
66
+ if (rule.hasOwnProperty('layerName')) {
67
+ ruleClone.layerName = rule.layerName;
68
+ }
69
+
70
+ if (rule.hasOwnProperty('cssRules')) {
71
+ ruleClone.cssRules = clone(rule).cssRules;
72
+ }
73
+ }
74
+
75
+ return cloned;
76
+
77
+ };
78
+
79
+ //.CommonJS
80
+ exports.clone = CSSOM.clone;
81
+ ///CommonJS
package/lib/index.js ADDED
@@ -0,0 +1,27 @@
1
+ 'use strict';
2
+
3
+ exports.CSSStyleDeclaration = require('./CSSStyleDeclaration').CSSStyleDeclaration;
4
+ exports.CSSRule = require('./CSSRule').CSSRule;
5
+ exports.CSSNestedDeclarations = require('./CSSNestedDeclarations').CSSNestedDeclarations;
6
+ exports.CSSGroupingRule = require('./CSSGroupingRule').CSSGroupingRule;
7
+ exports.CSSConditionRule = require('./CSSConditionRule').CSSConditionRule;
8
+ exports.CSSStyleRule = require('./CSSStyleRule').CSSStyleRule;
9
+ exports.MediaList = require('./MediaList').MediaList;
10
+ exports.CSSMediaRule = require('./CSSMediaRule').CSSMediaRule;
11
+ exports.CSSContainerRule = require('./CSSContainerRule').CSSContainerRule;
12
+ exports.CSSSupportsRule = require('./CSSSupportsRule').CSSSupportsRule;
13
+ exports.CSSImportRule = require('./CSSImportRule').CSSImportRule;
14
+ exports.CSSFontFaceRule = require('./CSSFontFaceRule').CSSFontFaceRule;
15
+ exports.CSSHostRule = require('./CSSHostRule').CSSHostRule;
16
+ exports.CSSStartingStyleRule = require('./CSSStartingStyleRule').CSSStartingStyleRule;
17
+ exports.StyleSheet = require('./StyleSheet').StyleSheet;
18
+ exports.CSSStyleSheet = require('./CSSStyleSheet').CSSStyleSheet;
19
+ exports.CSSKeyframesRule = require('./CSSKeyframesRule').CSSKeyframesRule;
20
+ exports.CSSKeyframeRule = require('./CSSKeyframeRule').CSSKeyframeRule;
21
+ exports.MatcherList = require('./MatcherList').MatcherList;
22
+ exports.CSSDocumentRule = require('./CSSDocumentRule').CSSDocumentRule;
23
+ exports.CSSValue = require('./CSSValue').CSSValue;
24
+ exports.CSSValueExpression = require('./CSSValueExpression').CSSValueExpression;
25
+ exports.CSSLayerBlockRule = require('./CSSLayerBlockRule').CSSLayerBlockRule;
26
+ exports.parse = require('./parse').parse;
27
+ exports.clone = require('./clone').clone;