| 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) { | |
| 16 | |
| 17 // consume* functions return a 2 value array of [parsed-data, '' or not-yet co
nsumed input] | |
| 18 | |
| 19 // Regex should be anchored with /^ | |
| 20 function consumeToken(regex, string) { | |
| 21 var result = regex.exec(string); | |
| 22 if (result) { | |
| 23 result = regex.ignoreCase ? result[0].toLowerCase() : result[0]; | |
| 24 return [result, string.substr(result.length)]; | |
| 25 } | |
| 26 } | |
| 27 | |
| 28 function consumeTrimmed(consumer, string) { | |
| 29 string = string.replace(/^\s*/, ''); | |
| 30 var result = consumer(string); | |
| 31 if (result) { | |
| 32 return [result[0], result[1].replace(/^\s*/, '')]; | |
| 33 } | |
| 34 } | |
| 35 | |
| 36 function consumeRepeated(consumer, separator, string) { | |
| 37 consumer = consumeTrimmed.bind(null, consumer); | |
| 38 var list = []; | |
| 39 while (true) { | |
| 40 var result = consumer(string); | |
| 41 if (!result) { | |
| 42 return [list, string]; | |
| 43 } | |
| 44 list.push(result[0]); | |
| 45 string = result[1]; | |
| 46 result = consumeToken(separator, string); | |
| 47 if (!result || result[1] == '') { | |
| 48 return [list, string]; | |
| 49 } | |
| 50 string = result[1]; | |
| 51 } | |
| 52 } | |
| 53 | |
| 54 // Consumes a token or expression with balanced parentheses | |
| 55 function consumeParenthesised(parser, string) { | |
| 56 var nesting = 0; | |
| 57 for (var n = 0; n < string.length; n++) { | |
| 58 if (/\s|,/.test(string[n]) && nesting == 0) { | |
| 59 break; | |
| 60 } else if (string[n] == '(') { | |
| 61 nesting++; | |
| 62 } else if (string[n] == ')') { | |
| 63 nesting--; | |
| 64 if (nesting == 0) | |
| 65 n++; | |
| 66 if (nesting <= 0) | |
| 67 break; | |
| 68 } | |
| 69 } | |
| 70 var parsed = parser(string.substr(0, n)); | |
| 71 return parsed == undefined ? undefined : [parsed, string.substr(n)]; | |
| 72 } | |
| 73 | |
| 74 function lcm(a, b) { | |
| 75 var c = a; | |
| 76 var d = b; | |
| 77 while (c && d) | |
| 78 c > d ? c %= d : d %= c; | |
| 79 c = (a * b) / (c + d); | |
| 80 return c; | |
| 81 } | |
| 82 | |
| 83 function ignore(value) { | |
| 84 return function(input) { | |
| 85 var result = value(input); | |
| 86 if (result) | |
| 87 result[0] = undefined; | |
| 88 return result; | |
| 89 } | |
| 90 } | |
| 91 | |
| 92 function optional(value, defaultValue) { | |
| 93 return function(input) { | |
| 94 var result = value(input); | |
| 95 if (result) | |
| 96 return result; | |
| 97 return [defaultValue, input]; | |
| 98 } | |
| 99 } | |
| 100 | |
| 101 function consumeList(list, input) { | |
| 102 var output = []; | |
| 103 for (var i = 0; i < list.length; i++) { | |
| 104 var result = scope.consumeTrimmed(list[i], input); | |
| 105 if (!result || result[0] == '') | |
| 106 return; | |
| 107 if (result[0] !== undefined) | |
| 108 output.push(result[0]); | |
| 109 input = result[1]; | |
| 110 } | |
| 111 if (input == '') { | |
| 112 return output; | |
| 113 } | |
| 114 } | |
| 115 | |
| 116 function mergeWrappedNestedRepeated(wrap, nestedMerge, separator, left, right)
{ | |
| 117 var matchingLeft = []; | |
| 118 var matchingRight = []; | |
| 119 var reconsititution = []; | |
| 120 var length = lcm(left.length, right.length); | |
| 121 for (var i = 0; i < length; i++) { | |
| 122 var thing = nestedMerge(left[i % left.length], right[i % right.length]); | |
| 123 if (!thing) { | |
| 124 return; | |
| 125 } | |
| 126 matchingLeft.push(thing[0]); | |
| 127 matchingRight.push(thing[1]); | |
| 128 reconsititution.push(thing[2]); | |
| 129 } | |
| 130 return [matchingLeft, matchingRight, function(positions) { | |
| 131 var result = positions.map(function(position, i) { | |
| 132 return reconsititution[i](position); | |
| 133 }).join(separator); | |
| 134 return wrap ? wrap(result) : result; | |
| 135 }]; | |
| 136 } | |
| 137 | |
| 138 function mergeList(left, right, list) { | |
| 139 var lefts = []; | |
| 140 var rights = []; | |
| 141 var functions = []; | |
| 142 var j = 0; | |
| 143 for (var i = 0; i < list.length; i++) { | |
| 144 if (typeof list[i] == 'function') { | |
| 145 var result = list[i](left[j], right[j++]); | |
| 146 lefts.push(result[0]); | |
| 147 rights.push(result[1]); | |
| 148 functions.push(result[2]); | |
| 149 } else { | |
| 150 (function(pos) { | |
| 151 lefts.push(false); | |
| 152 rights.push(false); | |
| 153 functions.push(function() { return list[pos]; }); | |
| 154 })(i); | |
| 155 } | |
| 156 } | |
| 157 return [lefts, rights, function(results) { | |
| 158 var result = ''; | |
| 159 for (var i = 0; i < results.length; i++) { | |
| 160 result += functions[i](results[i]); | |
| 161 } | |
| 162 return result; | |
| 163 }]; | |
| 164 } | |
| 165 | |
| 166 scope.consumeToken = consumeToken; | |
| 167 scope.consumeTrimmed = consumeTrimmed; | |
| 168 scope.consumeRepeated = consumeRepeated; | |
| 169 scope.consumeParenthesised = consumeParenthesised; | |
| 170 scope.ignore = ignore; | |
| 171 scope.optional = optional; | |
| 172 scope.consumeList = consumeList; | |
| 173 scope.mergeNestedRepeated = mergeWrappedNestedRepeated.bind(null, null); | |
| 174 scope.mergeWrappedNestedRepeated = mergeWrappedNestedRepeated; | |
| 175 scope.mergeList = mergeList; | |
| 176 | |
| 177 })(webAnimations1); | |
| OLD | NEW |