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 function negateDimension(dimension) { 18 var result = {}; 19 for (var k in dimension) { 20 result[k] = -dimension[k]; 21 } 22 return result; 23 } 24 25 function consumeOffset(string) { 26 return scope.consumeToken(/^(left|center|right|top|bottom)\b/i, string) || scope.consumeLengthOrPercent(string); 27 } 28 29 var offsetMap = { 30 left: {'%': 0}, 31 center: {'%': 50}, 32 right: {'%': 100}, 33 top: {'%': 0}, 34 bottom: {'%': 100}, 35 }; 36 37 function parseOrigin(slots, string) { 38 var result = scope.consumeRepeated(consumeOffset, /^/, string); 39 if (!result || result[1] != '') return; 40 var tokens = result[0]; 41 tokens[0] = tokens[0] || 'center'; 42 tokens[1] = tokens[1] || 'center'; 43 if (slots == 3) { 44 tokens[2] = tokens[2] || {px: 0}; 45 } 46 if (tokens.length != slots) { 47 return; 48 } 49 // Reorder so that the horizontal axis comes first. 50 if (/top|bottom/.test(tokens[0]) || /left|right/.test(tokens[1])) { 51 var tmp = tokens[0]; 52 tokens[0] = tokens[1]; 53 tokens[1] = tmp; 54 } 55 // Invalid if not horizontal then vertical. 56 if (!/left|right|center|Object/.test(tokens[0])) 57 return; 58 if (!/top|bottom|center|Object/.test(tokens[1])) 59 return; 60 return tokens.map(function(position) { 61 return typeof position == 'object' ? position : offsetMap[position]; 62 }); 63 } 64 65 var mergeOffsetList = scope.mergeNestedRepeated.bind(null, scope.mergeDimensions, ' '); 66 scope.addPropertiesHandler(parseOrigin.bind(null, 3), mergeOffsetList, ['transform-origin']); 67 scope.addPropertiesHandler(parseOrigin.bind(null, 2), mergeOffsetList, ['perspective-origin']); 68 69 function consumePosition(string) { 70 var result = scope.consumeRepeated(consumeOffset, /^/, string); 71 if (!result) { 72 return; 73 } 74 75 var tokens = result[0]; 76 var out = [{'%': 50}, {'%': 50}]; 77 var pos = 0; 78 var bottomOrRight = false; 79 80 for (var i = 0; i < tokens.length; i++) { 81 var token = tokens[i]; 82 if (typeof token == 'string') { 83 bottomOrRight = /bottom|right/.test(token); 84 pos = {left: 0, right: 0, center: pos, top: 1, bottom: 1}[token]; 85 out[pos] = offsetMap[token]; 86 if (token == 'center') { 87 // Center doesn't accept a length offset. 88 pos++; 89 } 90 } else { 91 if (bottomOrRight) { 92 // If bottom or right we need to subtract the length from 100% 93 token = negateDimension(token); 94 token['%'] = (token['%'] || 0) + 100; 95 } 96 out[pos] = token; 97 pos++; 98 bottomOrRight = false; 99 } 100 } 101 return [out, result[1]]; 102 } 103 104 function parsePositionList(string) { 105 var result = scope.consumeRepeated(consumePosition, /^,/, string); 106 if (result && result[1] == '') { 107 return result[0]; 108 } 109 } 110 111 scope.consumePosition = consumePosition; 112 scope.mergeOffsetList = mergeOffsetList; 113 114 var mergePositionList = scope.mergeNestedRepeated.bind(null, mergeOffsetList, ', '); 115 scope.addPropertiesHandler(parsePositionList, mergePositionList, ['background-position', 'object-position']); 116 117})(webAnimations1); 118