-
-
Notifications
You must be signed in to change notification settings - Fork 4.1k
/
Copy pathstyleParser.js
130 lines (112 loc) · 3.02 KB
/
styleParser.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/**
* Utils for parsing style-like strings (e.g., "primitive: box; width: 5; height: 4.5").
* Some code adapted from `style-attr` (https://github.com/joshwnj/style-attr)
* by Josh Johnston (MIT License).
*/
var DASH_REGEX = /-([a-z])/g;
/**
* Deserialize style-like string into an object of properties.
*
* @param {string} value - HTML attribute value.
* @param {object} obj - Reused object for object pooling.
* @returns {object} Property data.
*/
export function parse (value, obj) {
var parsedData;
if (typeof value !== 'string') { return value; }
parsedData = styleParse(value, obj);
// The style parser returns an object { "" : "test"} when fed a string
if (parsedData['']) { return value; }
return parsedData;
}
/**
* Serialize an object of properties into a style-like string.
*
* @param {object} data - Property data.
* @returns {string}
*/
export function stringify (data) {
if (typeof data === 'string') { return data; }
return styleStringify(data);
}
/**
* Converts string from hyphen to camelCase.
*
* @param {string} str - String to camelCase.
* @returns {string} CamelCased string.
*/
export function toCamelCase (str) {
return str.replace(DASH_REGEX, upperCase);
}
/**
* Split a string into chunks matching `<key>: <value>`
*/
var getKeyValueChunks = (function () {
var chunks = [];
var hasUnclosedUrl = /url\([^)]+$/;
return function getKeyValueChunks (raw) {
var chunk = '';
var nextSplit;
var offset = 0;
var sep = ';';
chunks.length = 0;
while (offset < raw.length) {
nextSplit = raw.indexOf(sep, offset);
if (nextSplit === -1) { nextSplit = raw.length; }
chunk += raw.substring(offset, nextSplit);
// data URIs can contain semicolons, so make sure we get the whole thing
if (hasUnclosedUrl.test(chunk)) {
chunk += ';';
offset = nextSplit + 1;
continue;
}
chunks.push(chunk.trim());
chunk = '';
offset = nextSplit + 1;
}
return chunks;
};
})();
/**
* Convert a style attribute string to an object.
*
* @param {object} str - Attribute string.
* @param {object} obj - Object to reuse as a base, else a new one will be allocated.
*/
function styleParse (str, obj) {
var chunks;
var i;
var item;
var pos;
var key;
var val;
obj = obj || {};
chunks = getKeyValueChunks(str);
for (i = 0; i < chunks.length; i++) {
item = chunks[i];
if (!item) { continue; }
// Split with `.indexOf` rather than `.split` because the value may also contain colons.
pos = item.indexOf(':');
key = item.substr(0, pos).trim();
val = item.substr(pos + 1).trim();
obj[toCamelCase(key)] = val;
}
return obj;
}
/**
* Convert an object into an attribute string
**/
function styleStringify (obj) {
var key;
var keyCount = 0;
var i = 0;
var str = '';
for (key in obj) { keyCount++; }
for (key in obj) {
str += (key + ': ' + obj[key]);
if (i < keyCount - 1) { str += '; '; }
i++;
}
return str;
}
function upperCase (str) { return str[1].toUpperCase(); }