OLD | NEW |
| (Empty) |
1 // Copyright 2014 Google Inc. All rights reserved. | |
2 // | |
3 // Licensed under the Apache License, Version 2.0 (the "License"); | |
4 // you may not use this file except in compliance with the License. | |
5 // You may obtain a copy of the License at | |
6 // | |
7 // http://www.apache.org/licenses/LICENSE-2.0 | |
8 // | |
9 // Unless required by applicable law or agreed to in writing, software | |
10 // distributed under the License is distributed on an "AS IS" BASIS, | |
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
12 // See the License for the specific language governing permissions and | |
13 // limitations under the License. | |
14 | |
15 (function(scope, testing) { | |
16 | |
17 function parseDimension(unitRegExp, string) { | |
18 string = string.trim().toLowerCase(); | |
19 | |
20 if (string == '0' && 'px'.search(unitRegExp) >= 0) | |
21 return {px: 0}; | |
22 | |
23 // If we have parenthesis, we're a calc and need to start with 'calc'. | |
24 if (!/^[^(]*$|^calc/.test(string)) | |
25 return; | |
26 string = string.replace(/calc\(/g, '('); | |
27 | |
28 // We tag units by prefixing them with 'U' (note that we are already | |
29 // lowercase) to prevent problems with types which are substrings of | |
30 // each other (although prefixes may be problematic!) | |
31 var matchedUnits = {}; | |
32 string = string.replace(unitRegExp, function(match) { | |
33 matchedUnits[match] = null; | |
34 return 'U' + match; | |
35 }); | |
36 var taggedUnitRegExp = 'U(' + unitRegExp.source + ')'; | |
37 | |
38 // Validating input is simply applying as many reductions as we can. | |
39 var typeCheck = string.replace(/[-+]?(\d*\.)?\d+/g, 'N') | |
40 .replace(new RegExp('N' + taggedUnitRegExp, 'g'), 'D') | |
41 .replace(/\s[+-]\s/g, 'O') | |
42 .replace(/\s/g, ''); | |
43 var reductions = [/N\*(D)/g, /(N|D)[*/]N/g, /(N|D)O\1/g, /\((N|D)\)/g]; | |
44 var i = 0; | |
45 while (i < reductions.length) { | |
46 if (reductions[i].test(typeCheck)) { | |
47 typeCheck = typeCheck.replace(reductions[i], '$1'); | |
48 i = 0; | |
49 } else { | |
50 i++; | |
51 } | |
52 } | |
53 if (typeCheck != 'D') | |
54 return; | |
55 | |
56 for (var unit in matchedUnits) { | |
57 var result = eval(string.replace(new RegExp('U' + unit, 'g'), '').replace(
new RegExp(taggedUnitRegExp, 'g'), '*0')); | |
58 if (!isFinite(result)) | |
59 return; | |
60 matchedUnits[unit] = result; | |
61 } | |
62 return matchedUnits; | |
63 } | |
64 | |
65 function mergeDimensionsNonNegative(left, right) { | |
66 return mergeDimensions(left, right, true); | |
67 } | |
68 | |
69 function mergeDimensions(left, right, nonNegative) { | |
70 var units = [], unit; | |
71 for (unit in left) | |
72 units.push(unit); | |
73 for (unit in right) { | |
74 if (units.indexOf(unit) < 0) | |
75 units.push(unit); | |
76 } | |
77 | |
78 left = units.map(function(unit) { return left[unit] || 0; }); | |
79 right = units.map(function(unit) { return right[unit] || 0; }); | |
80 return [left, right, function(values) { | |
81 var result = values.map(function(value, i) { | |
82 if (values.length == 1 && nonNegative) { | |
83 value = Math.max(value, 0); | |
84 } | |
85 // Scientific notation (e.g. 1e2) is not yet widely supported by browser
vendors. | |
86 return scope.numberToString(value) + units[i]; | |
87 }).join(' + '); | |
88 return values.length > 1 ? 'calc(' + result + ')' : result; | |
89 }]; | |
90 } | |
91 | |
92 var lengthUnits = 'px|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc'; | |
93 var parseLength = parseDimension.bind(null, new RegExp(lengthUnits, 'g')); | |
94 var parseLengthOrPercent = parseDimension.bind(null, new RegExp(lengthUnits +
'|%', 'g')); | |
95 var parseAngle = parseDimension.bind(null, /deg|rad|grad|turn/g); | |
96 | |
97 scope.parseLength = parseLength; | |
98 scope.parseLengthOrPercent = parseLengthOrPercent; | |
99 scope.consumeLengthOrPercent = scope.consumeParenthesised.bind(null, parseLeng
thOrPercent); | |
100 scope.parseAngle = parseAngle; | |
101 scope.mergeDimensions = mergeDimensions; | |
102 | |
103 var consumeLength = scope.consumeParenthesised.bind(null, parseLength); | |
104 var consumeSizePair = scope.consumeRepeated.bind(undefined, consumeLength, /^/
); | |
105 var consumeSizePairList = scope.consumeRepeated.bind(undefined, consumeSizePai
r, /^,/); | |
106 scope.consumeSizePairList = consumeSizePairList; | |
107 | |
108 var parseSizePairList = function(input) { | |
109 var result = consumeSizePairList(input); | |
110 if (result && result[1] == '') { | |
111 return result[0]; | |
112 } | |
113 }; | |
114 | |
115 var mergeNonNegativeSizePair = scope.mergeNestedRepeated.bind(undefined, merge
DimensionsNonNegative, ' '); | |
116 var mergeNonNegativeSizePairList = scope.mergeNestedRepeated.bind(undefined, m
ergeNonNegativeSizePair, ','); | |
117 scope.mergeNonNegativeSizePair = mergeNonNegativeSizePair; | |
118 | |
119 scope.addPropertiesHandler(parseSizePairList, mergeNonNegativeSizePairList, [ | |
120 'background-size' | |
121 ]); | |
122 | |
123 scope.addPropertiesHandler(parseLengthOrPercent, mergeDimensionsNonNegative, [ | |
124 'border-bottom-width', | |
125 'border-image-width', | |
126 'border-left-width', | |
127 'border-right-width', | |
128 'border-top-width', | |
129 'flex-basis', | |
130 'font-size', | |
131 'height', | |
132 'line-height', | |
133 'max-height', | |
134 'max-width', | |
135 'outline-width', | |
136 'width', | |
137 ]); | |
138 | |
139 scope.addPropertiesHandler(parseLengthOrPercent, mergeDimensions, [ | |
140 'border-bottom-left-radius', | |
141 'border-bottom-right-radius', | |
142 'border-top-left-radius', | |
143 'border-top-right-radius', | |
144 'bottom', | |
145 'left', | |
146 'letter-spacing', | |
147 'margin-bottom', | |
148 'margin-left', | |
149 'margin-right', | |
150 'margin-top', | |
151 'min-height', | |
152 'min-width', | |
153 'outline-offset', | |
154 'padding-bottom', | |
155 'padding-left', | |
156 'padding-right', | |
157 'padding-top', | |
158 'perspective', | |
159 'right', | |
160 'shape-margin', | |
161 'text-indent', | |
162 'top', | |
163 'vertical-align', | |
164 'word-spacing', | |
165 ]); | |
166 | |
167 })(webAnimations1, webAnimationsTesting); | |
OLD | NEW |