Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(272)

Side by Side Diff: pkg/web_components/lib/platform.concat.js

Issue 349313005: update polymer and platform.js (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/web_components/lib/platform.js ('k') | pkg/web_components/lib/platform.concat.js.map » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /** 1 /**
2 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. 2 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
3 * This code may only be used under the BSD style license found at http://polyme r.github.io/LICENSE.txt 3 * This code may only be used under the BSD style license found at http://polyme r.github.io/LICENSE.txt
4 * The complete set of authors may be found at http://polymer.github.io/AUTHORS. txt 4 * The complete set of authors may be found at http://polymer.github.io/AUTHORS. txt
5 * The complete set of contributors may be found at http://polymer.github.io/CON TRIBUTORS.txt 5 * The complete set of contributors may be found at http://polymer.github.io/CON TRIBUTORS.txt
6 * Code distributed by Google as part of the polymer project is also 6 * Code distributed by Google as part of the polymer project is also
7 * subject to an additional IP rights grant found at http://polymer.github.io/PA TENTS.txt 7 * subject to an additional IP rights grant found at http://polymer.github.io/PA TENTS.txt
8 */ 8 */
9 9
10 window.Platform = window.Platform || {}; 10 window.Platform = window.Platform || {};
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
185 } 185 }
186 186
187 function toNumber(s) { 187 function toNumber(s) {
188 return +s; 188 return +s;
189 } 189 }
190 190
191 function isObject(obj) { 191 function isObject(obj) {
192 return obj === Object(obj); 192 return obj === Object(obj);
193 } 193 }
194 194
195 var numberIsNaN = global.Number.isNaN || function isNaN(value) { 195 var numberIsNaN = global.Number.isNaN || function(value) {
196 return typeof value === 'number' && global.isNaN(value); 196 return typeof value === 'number' && global.isNaN(value);
197 } 197 }
198 198
199 function areSameValue(left, right) { 199 function areSameValue(left, right) {
200 if (left === right) 200 if (left === right)
201 return left !== 0 || 1 / left === 1 / right; 201 return left !== 0 || 1 / left === 1 / right;
202 if (numberIsNaN(left) && numberIsNaN(right)) 202 if (numberIsNaN(left) && numberIsNaN(right))
203 return true; 203 return true;
204 204
205 return left !== left && right !== right; 205 return left !== left && right !== right;
206 } 206 }
207 207
208 var createObject = ('__proto__' in {}) ? 208 var createObject = ('__proto__' in {}) ?
209 function(obj) { return obj; } : 209 function(obj) { return obj; } :
210 function(obj) { 210 function(obj) {
211 var proto = obj.__proto__; 211 var proto = obj.__proto__;
212 if (!proto) 212 if (!proto)
213 return obj; 213 return obj;
214 var newObject = Object.create(proto); 214 var newObject = Object.create(proto);
215 Object.getOwnPropertyNames(obj).forEach(function(name) { 215 Object.getOwnPropertyNames(obj).forEach(function(name) {
216 Object.defineProperty(newObject, name, 216 Object.defineProperty(newObject, name,
217 Object.getOwnPropertyDescriptor(obj, name)); 217 Object.getOwnPropertyDescriptor(obj, name));
218 }); 218 });
219 return newObject; 219 return newObject;
220 }; 220 };
221 221
222 var identStart = '[\$_a-zA-Z]'; 222 var identStart = '[\$_a-zA-Z]';
223 var identPart = '[\$_a-zA-Z0-9]'; 223 var identPart = '[\$_a-zA-Z0-9]';
224 var ident = identStart + '+' + identPart + '*'; 224 var identRegExp = new RegExp('^' + identStart + '+' + identPart + '*' + '$');
225 var elementIndex = '(?:[0-9]|[1-9]+[0-9]+)';
226 var identOrElementIndex = '(?:' + ident + '|' + elementIndex + ')';
227 var path = '(?:' + identOrElementIndex + ')(?:\\s*\\.\\s*' + identOrElementInd ex + ')*';
228 var pathRegExp = new RegExp('^' + path + '$');
229 225
230 function isPathValid(s) { 226 function getPathCharType(char) {
231 if (typeof s != 'string') 227 if (char === undefined)
232 return false; 228 return 'eof';
233 s = s.trim();
234 229
235 if (s == '') 230 var code = char.charCodeAt(0);
236 return true;
237 231
238 if (s[0] == '.') 232 switch(code) {
239 return false; 233 case 0x5B: // [
234 case 0x5D: // ]
235 case 0x2E: // .
236 case 0x22: // "
237 case 0x27: // '
238 case 0x30: // 0
239 return char;
240 240
241 return pathRegExp.test(s); 241 case 0x5F: // _
242 case 0x24: // $
243 return 'ident';
244
245 case 0x20: // Space
246 case 0x09: // Tab
247 case 0x0A: // Newline
248 case 0x0D: // Return
249 case 0xA0: // No-break space
250 case 0xFEFF: // Byte Order Mark
251 case 0x2028: // Line Separator
252 case 0x2029: // Paragraph Separator
253 return 'ws';
254 }
255
256 // a-z, A-Z
257 if ((0x61 <= code && code <= 0x7A) || (0x41 <= code && code <= 0x5A))
258 return 'ident';
259
260 // 1-9
261 if (0x31 <= code && code <= 0x39)
262 return 'number';
263
264 return 'else';
265 }
266
267 var pathStateMachine = {
268 'beforePath': {
269 'ws': ['beforePath'],
270 'ident': ['inIdent', 'append'],
271 '[': ['beforeElement'],
272 'eof': ['afterPath']
273 },
274
275 'inPath': {
276 'ws': ['inPath'],
277 '.': ['beforeIdent'],
278 '[': ['beforeElement'],
279 'eof': ['afterPath']
280 },
281
282 'beforeIdent': {
283 'ws': ['beforeIdent'],
284 'ident': ['inIdent', 'append']
285 },
286
287 'inIdent': {
288 'ident': ['inIdent', 'append'],
289 '0': ['inIdent', 'append'],
290 'number': ['inIdent', 'append'],
291 'ws': ['inPath', 'push'],
292 '.': ['beforeIdent', 'push'],
293 '[': ['beforeElement', 'push'],
294 'eof': ['afterPath', 'push']
295 },
296
297 'beforeElement': {
298 'ws': ['beforeElement'],
299 '0': ['afterZero', 'append'],
300 'number': ['inIndex', 'append'],
301 "'": ['inSingleQuote', 'append', ''],
302 '"': ['inDoubleQuote', 'append', '']
303 },
304
305 'afterZero': {
306 'ws': ['afterElement', 'push'],
307 ']': ['inPath', 'push']
308 },
309
310 'inIndex': {
311 '0': ['inIndex', 'append'],
312 'number': ['inIndex', 'append'],
313 'ws': ['afterElement'],
314 ']': ['inPath', 'push']
315 },
316
317 'inSingleQuote': {
318 "'": ['afterElement'],
319 'eof': ['error'],
320 'else': ['inSingleQuote', 'append']
321 },
322
323 'inDoubleQuote': {
324 '"': ['afterElement'],
325 'eof': ['error'],
326 'else': ['inDoubleQuote', 'append']
327 },
328
329 'afterElement': {
330 'ws': ['afterElement'],
331 ']': ['inPath', 'push']
332 }
333 }
334
335 function noop() {}
336
337 function parsePath(path) {
338 var keys = [];
339 var index = -1;
340 var c, newChar, key, type, transition, action, typeMap, mode = 'beforePath';
341
342 var actions = {
343 push: function() {
344 if (key === undefined)
345 return;
346
347 keys.push(key);
348 key = undefined;
349 },
350
351 append: function() {
352 if (key === undefined)
353 key = newChar
354 else
355 key += newChar;
356 }
357 };
358
359 function maybeUnescapeQuote() {
360 if (index >= path.length)
361 return;
362
363 var nextChar = path[index + 1];
364 if ((mode == 'inSingleQuote' && nextChar == "'") ||
365 (mode == 'inDoubleQuote' && nextChar == '"')) {
366 index++;
367 newChar = nextChar;
368 actions.append();
369 return true;
370 }
371 }
372
373 while (mode) {
374 index++;
375 c = path[index];
376
377 if (c == '\\' && maybeUnescapeQuote(mode))
378 continue;
379
380 type = getPathCharType(c);
381 typeMap = pathStateMachine[mode];
382 transition = typeMap[type] || typeMap['else'] || 'error';
383
384 if (transition == 'error')
385 return; // parse error;
386
387 mode = transition[0];
388 action = actions[transition[1]] || noop;
389 newChar = transition[2] === undefined ? c : transition[2];
390 action();
391
392 if (mode === 'afterPath') {
393 return keys;
394 }
395 }
396
397 return; // parse error
398 }
399
400 function isIdent(s) {
401 return identRegExp.test(s);
242 } 402 }
243 403
244 var constructorIsPrivate = {}; 404 var constructorIsPrivate = {};
245 405
246 function Path(s, privateToken) { 406 function Path(parts, privateToken) {
247 if (privateToken !== constructorIsPrivate) 407 if (privateToken !== constructorIsPrivate)
248 throw Error('Use Path.get to retrieve path objects'); 408 throw Error('Use Path.get to retrieve path objects');
249 409
250 if (s.trim() == '') 410 if (parts.length)
251 return this; 411 Array.prototype.push.apply(this, parts.slice());
252
253 if (isIndex(s)) {
254 this.push(s);
255 return this;
256 }
257
258 s.split(/\s*\.\s*/).filter(function(part) {
259 return part;
260 }).forEach(function(part) {
261 this.push(part);
262 }, this);
263 412
264 if (hasEval && this.length) { 413 if (hasEval && this.length) {
265 this.getValueFrom = this.compiledGetValueFromFn(); 414 this.getValueFrom = this.compiledGetValueFromFn();
266 } 415 }
267 } 416 }
268 417
269 // TODO(rafaelw): Make simple LRU cache 418 // TODO(rafaelw): Make simple LRU cache
270 var pathCache = {}; 419 var pathCache = {};
271 420
272 function getPath(pathString) { 421 function getPath(pathString) {
273 if (pathString instanceof Path) 422 if (pathString instanceof Path)
274 return pathString; 423 return pathString;
275 424
276 if (pathString == null) 425 if (pathString == null || pathString.length == 0)
277 pathString = ''; 426 pathString = '';
278 427
279 if (typeof pathString !== 'string') 428 if (typeof pathString != 'string') {
429 if (isIndex(pathString.length)) {
430 // Constructed with array-like (pre-parsed) keys
431 return new Path(pathString, constructorIsPrivate);
432 }
433
280 pathString = String(pathString); 434 pathString = String(pathString);
435 }
281 436
282 var path = pathCache[pathString]; 437 var path = pathCache[pathString];
283 if (path) 438 if (path)
284 return path; 439 return path;
285 if (!isPathValid(pathString)) 440
441 var parts = parsePath(pathString);
442 if (!parts)
286 return invalidPath; 443 return invalidPath;
287 var path = new Path(pathString, constructorIsPrivate); 444
445 var path = new Path(parts, constructorIsPrivate);
288 pathCache[pathString] = path; 446 pathCache[pathString] = path;
289 return path; 447 return path;
290 } 448 }
291 449
292 Path.get = getPath; 450 Path.get = getPath;
293 451
452 function formatAccessor(key) {
453 if (isIndex(key)) {
454 return '[' + key + ']';
455 } else {
456 return '["' + key.replace(/"/g, '\\"') + '"]';
457 }
458 }
459
294 Path.prototype = createObject({ 460 Path.prototype = createObject({
295 __proto__: [], 461 __proto__: [],
296 valid: true, 462 valid: true,
297 463
298 toString: function() { 464 toString: function() {
299 return this.join('.'); 465 var pathString = '';
466 for (var i = 0; i < this.length; i++) {
467 var key = this[i];
468 if (isIdent(key)) {
469 pathString += i ? '.' + key : key;
470 } else {
471 pathString += formatAccessor(key);
472 }
473 }
474
475 return pathString;
300 }, 476 },
301 477
302 getValueFrom: function(obj, directObserver) { 478 getValueFrom: function(obj, directObserver) {
303 for (var i = 0; i < this.length; i++) { 479 for (var i = 0; i < this.length; i++) {
304 if (obj == null) 480 if (obj == null)
305 return; 481 return;
306 obj = obj[this[i]]; 482 obj = obj[this[i]];
307 } 483 }
308 return obj; 484 return obj;
309 }, 485 },
310 486
311 iterateObjects: function(obj, observe) { 487 iterateObjects: function(obj, observe) {
312 for (var i = 0; i < this.length; i++) { 488 for (var i = 0; i < this.length; i++) {
313 if (i) 489 if (i)
314 obj = obj[this[i - 1]]; 490 obj = obj[this[i - 1]];
315 if (!isObject(obj)) 491 if (!isObject(obj))
316 return; 492 return;
317 observe(obj, this[0]); 493 observe(obj, this[0]);
318 } 494 }
319 }, 495 },
320 496
321 compiledGetValueFromFn: function() { 497 compiledGetValueFromFn: function() {
322 var accessors = this.map(function(ident) {
323 return isIndex(ident) ? '["' + ident + '"]' : '.' + ident;
324 });
325
326 var str = ''; 498 var str = '';
327 var pathString = 'obj'; 499 var pathString = 'obj';
328 str += 'if (obj != null'; 500 str += 'if (obj != null';
329 var i = 0; 501 var i = 0;
502 var key;
330 for (; i < (this.length - 1); i++) { 503 for (; i < (this.length - 1); i++) {
331 var ident = this[i]; 504 key = this[i];
332 pathString += accessors[i]; 505 pathString += isIdent(key) ? '.' + key : formatAccessor(key);
333 str += ' &&\n ' + pathString + ' != null'; 506 str += ' &&\n ' + pathString + ' != null';
334 } 507 }
335 str += ')\n'; 508 str += ')\n';
336 509
337 pathString += accessors[i]; 510 var key = this[i];
511 pathString += isIdent(key) ? '.' + key : formatAccessor(key);
338 512
339 str += ' return ' + pathString + ';\nelse\n return undefined;'; 513 str += ' return ' + pathString + ';\nelse\n return undefined;';
340 return new Function('obj', str); 514 return new Function('obj', str);
341 }, 515 },
342 516
343 setValueFrom: function(obj, value) { 517 setValueFrom: function(obj, value) {
344 if (!this.length) 518 if (!this.length)
345 return false; 519 return false;
346 520
347 for (var i = 0; i < this.length - 1; i++) { 521 for (var i = 0; i < this.length - 1; i++) {
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after
928 Observer.call(this); 1102 Observer.call(this);
929 1103
930 this.object_ = object; 1104 this.object_ = object;
931 this.path_ = getPath(path); 1105 this.path_ = getPath(path);
932 this.directObserver_ = undefined; 1106 this.directObserver_ = undefined;
933 } 1107 }
934 1108
935 PathObserver.prototype = createObject({ 1109 PathObserver.prototype = createObject({
936 __proto__: Observer.prototype, 1110 __proto__: Observer.prototype,
937 1111
1112 get path() {
1113 return this.path_;
1114 },
1115
938 connect_: function() { 1116 connect_: function() {
939 if (hasObserve) 1117 if (hasObserve)
940 this.directObserver_ = getObservedSet(this, this.object_); 1118 this.directObserver_ = getObservedSet(this, this.object_);
941 1119
942 this.check_(undefined, true); 1120 this.check_(undefined, true);
943 }, 1121 },
944 1122
945 disconnect_: function() { 1123 disconnect_: function() {
946 this.value_ = undefined; 1124 this.value_ = undefined;
947 1125
948 if (this.directObserver_) { 1126 if (this.directObserver_) {
949 this.directObserver_.close(this); 1127 this.directObserver_.close(this);
950 this.directObserver_ = undefined; 1128 this.directObserver_ = undefined;
951 } 1129 }
952 }, 1130 },
953 1131
954 iterateObjects_: function(observe) { 1132 iterateObjects_: function(observe) {
955 this.path_.iterateObjects(this.object_, observe); 1133 this.path_.iterateObjects(this.object_, observe);
956 }, 1134 },
957 1135
958 check_: function(changeRecords, skipChanges) { 1136 check_: function(changeRecords, skipChanges) {
959 var oldValue = this.value_; 1137 var oldValue = this.value_;
960 this.value_ = this.path_.getValueFrom(this.object_); 1138 this.value_ = this.path_.getValueFrom(this.object_);
961 if (skipChanges || areSameValue(this.value_, oldValue)) 1139 if (skipChanges || areSameValue(this.value_, oldValue))
962 return false; 1140 return false;
963 1141
964 this.report_([this.value_, oldValue]); 1142 this.report_([this.value_, oldValue, this]);
965 return true; 1143 return true;
966 }, 1144 },
967 1145
968 setValue: function(newValue) { 1146 setValue: function(newValue) {
969 if (this.path_) 1147 if (this.path_)
970 this.path_.setValueFrom(this.object_, newValue); 1148 this.path_.setValueFrom(this.object_, newValue);
971 } 1149 }
972 }); 1150 });
973 1151
974 function CompoundObserver(reportChangesOnOpen) { 1152 function CompoundObserver(reportChangesOnOpen) {
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
1164 this.setValueFn_ = undefined; 1342 this.setValueFn_ = undefined;
1165 } 1343 }
1166 } 1344 }
1167 1345
1168 var expectedRecordTypes = { 1346 var expectedRecordTypes = {
1169 add: true, 1347 add: true,
1170 update: true, 1348 update: true,
1171 delete: true 1349 delete: true
1172 }; 1350 };
1173 1351
1174 var updateRecord = {
1175 object: undefined,
1176 type: 'update',
1177 name: undefined,
1178 oldValue: undefined
1179 };
1180
1181 function notify(object, name, value, oldValue) {
1182 if (areSameValue(value, oldValue))
1183 return;
1184
1185 // TODO(rafaelw): Hack hack hack. This entire code really needs to move
1186 // out of observe-js into polymer.
1187 if (typeof object.propertyChanged_ == 'function')
1188 object.propertyChanged_(name, value, oldValue);
1189
1190 if (!hasObserve)
1191 return;
1192
1193 var notifier = object.notifier_;
1194 if (!notifier)
1195 notifier = object.notifier_ = Object.getNotifier(object);
1196
1197 updateRecord.object = object;
1198 updateRecord.name = name;
1199 updateRecord.oldValue = oldValue;
1200
1201 notifier.notify(updateRecord);
1202 }
1203
1204 Observer.createBindablePrototypeAccessor = function(proto, name) {
1205 var privateName = name + '_';
1206 var privateObservable = name + 'Observable_';
1207
1208 proto[privateName] = proto[name];
1209
1210 Object.defineProperty(proto, name, {
1211 get: function() {
1212 var observable = this[privateObservable];
1213 if (observable)
1214 observable.deliver();
1215
1216 return this[privateName];
1217 },
1218 set: function(value) {
1219 var observable = this[privateObservable];
1220 if (observable) {
1221 observable.setValue(value);
1222 return;
1223 }
1224
1225 var oldValue = this[privateName];
1226 this[privateName] = value;
1227 notify(this, name, value, oldValue);
1228
1229 return value;
1230 },
1231 configurable: true
1232 });
1233 }
1234
1235 Observer.bindToInstance = function(instance, name, observable, resolveFn) {
1236 var privateName = name + '_';
1237 var privateObservable = name + 'Observable_';
1238
1239 instance[privateObservable] = observable;
1240 var oldValue = instance[privateName];
1241 var value = observable.open(function(value, oldValue) {
1242 instance[privateName] = value;
1243 notify(instance, name, value, oldValue);
1244 });
1245
1246 if (resolveFn && !areSameValue(oldValue, value)) {
1247 var resolvedValue = resolveFn(oldValue, value);
1248 if (!areSameValue(value, resolvedValue)) {
1249 value = resolvedValue;
1250 if (observable.setValue)
1251 observable.setValue(value);
1252 }
1253 }
1254
1255 instance[privateName] = value;
1256 notify(instance, name, value, oldValue);
1257
1258 return {
1259 close: function() {
1260 observable.close();
1261 instance[privateObservable] = undefined;
1262 }
1263 };
1264 }
1265
1266 function diffObjectFromChangeRecords(object, changeRecords, oldValues) { 1352 function diffObjectFromChangeRecords(object, changeRecords, oldValues) {
1267 var added = {}; 1353 var added = {};
1268 var removed = {}; 1354 var removed = {};
1269 1355
1270 for (var i = 0; i < changeRecords.length; i++) { 1356 for (var i = 0; i < changeRecords.length; i++) {
1271 var record = changeRecords[i]; 1357 var record = changeRecords[i];
1272 if (!expectedRecordTypes[record.type]) { 1358 if (!expectedRecordTypes[record.type]) {
1273 console.error('Unknown changeRecord type: ' + record.type); 1359 console.error('Unknown changeRecord type: ' + record.type);
1274 console.error(record); 1360 console.error(record);
1275 continue; 1361 continue;
(...skipping 1761 matching lines...) Expand 10 before | Expand all | Expand 10 after
3037 } 3123 }
3038 3124
3039 eventPhaseTable.set(event, phase); 3125 eventPhaseTable.set(event, phase);
3040 var type = event.type; 3126 var type = event.type;
3041 3127
3042 var anyRemoved = false; 3128 var anyRemoved = false;
3043 // targetTable.set(event, target); 3129 // targetTable.set(event, target);
3044 targetTable.set(event, target); 3130 targetTable.set(event, target);
3045 currentTargetTable.set(event, currentTarget); 3131 currentTargetTable.set(event, currentTarget);
3046 3132
3047 for (var i = 0; i < listeners.length; i++) { 3133 // Keep track of the invoke depth so that we only clean up the removed
3134 // listeners if we are in the outermost invoke.
3135 listeners.depth++;
3136
3137 for (var i = 0, len = listeners.length; i < len; i++) {
3048 var listener = listeners[i]; 3138 var listener = listeners[i];
3049 if (listener.removed) { 3139 if (listener.removed) {
3050 anyRemoved = true; 3140 anyRemoved = true;
3051 continue; 3141 continue;
3052 } 3142 }
3053 3143
3054 if (listener.type !== type || 3144 if (listener.type !== type ||
3055 !listener.capture && phase === CAPTURING_PHASE || 3145 !listener.capture && phase === CAPTURING_PHASE ||
3056 listener.capture && phase === BUBBLING_PHASE) { 3146 listener.capture && phase === BUBBLING_PHASE) {
3057 continue; 3147 continue;
3058 } 3148 }
3059 3149
3060 try { 3150 try {
3061 if (typeof listener.handler === 'function') 3151 if (typeof listener.handler === 'function')
3062 listener.handler.call(currentTarget, event); 3152 listener.handler.call(currentTarget, event);
3063 else 3153 else
3064 listener.handler.handleEvent(event); 3154 listener.handler.handleEvent(event);
3065 3155
3066 if (stopImmediatePropagationTable.get(event)) 3156 if (stopImmediatePropagationTable.get(event))
3067 return false; 3157 return false;
3068 3158
3069 } catch (ex) { 3159 } catch (ex) {
3070 if (!pendingError) 3160 if (!pendingError)
3071 pendingError = ex; 3161 pendingError = ex;
3072 } 3162 }
3073 } 3163 }
3074 3164
3075 if (anyRemoved) { 3165 listeners.depth--;
3166
3167 if (anyRemoved && listeners.depth === 0) {
3076 var copy = listeners.slice(); 3168 var copy = listeners.slice();
3077 listeners.length = 0; 3169 listeners.length = 0;
3078 for (var i = 0; i < copy.length; i++) { 3170 for (var i = 0; i < copy.length; i++) {
3079 if (!copy[i].removed) 3171 if (!copy[i].removed)
3080 listeners.push(copy[i]); 3172 listeners.push(copy[i]);
3081 } 3173 }
3082 } 3174 }
3083 3175
3084 return !stopPropagationTable.get(event); 3176 return !stopPropagationTable.get(event);
3085 } 3177 }
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
3130 get target() { 3222 get target() {
3131 return targetTable.get(this); 3223 return targetTable.get(this);
3132 }, 3224 },
3133 get currentTarget() { 3225 get currentTarget() {
3134 return currentTargetTable.get(this); 3226 return currentTargetTable.get(this);
3135 }, 3227 },
3136 get eventPhase() { 3228 get eventPhase() {
3137 return eventPhaseTable.get(this); 3229 return eventPhaseTable.get(this);
3138 }, 3230 },
3139 get path() { 3231 get path() {
3140 var nodeList = new wrappers.NodeList();
3141 var eventPath = eventPathTable.get(this); 3232 var eventPath = eventPathTable.get(this);
3142 if (eventPath) { 3233 if (!eventPath)
3143 var index = 0; 3234 return [];
3144 var lastIndex = eventPath.length - 1; 3235 // TODO(arv): Event path should contain window.
3145 var baseRoot = getTreeScope(currentTargetTable.get(this)); 3236 return eventPath.slice();
3146
3147 for (var i = 0; i <= lastIndex; i++) {
3148 var currentTarget = eventPath[i];
3149 var currentRoot = getTreeScope(currentTarget);
3150 if (currentRoot.contains(baseRoot) &&
3151 // Make sure we do not add Window to the path.
3152 (i !== lastIndex || currentTarget instanceof wrappers.Node)) {
3153 nodeList[index++] = currentTarget;
3154 }
3155 }
3156 nodeList.length = index;
3157 }
3158 return nodeList;
3159 }, 3237 },
3160 stopPropagation: function() { 3238 stopPropagation: function() {
3161 stopPropagationTable.set(this, true); 3239 stopPropagationTable.set(this, true);
3162 }, 3240 },
3163 stopImmediatePropagation: function() { 3241 stopImmediatePropagation: function() {
3164 stopPropagationTable.set(this, true); 3242 stopPropagationTable.set(this, true);
3165 stopImmediatePropagationTable.set(this, true); 3243 stopImmediatePropagationTable.set(this, true);
3166 } 3244 }
3167 }; 3245 };
3168 registerWrapper(OriginalEvent, Event, document.createEvent('Event')); 3246 registerWrapper(OriginalEvent, Event, document.createEvent('Event'));
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
3376 3454
3377 EventTarget.prototype = { 3455 EventTarget.prototype = {
3378 addEventListener: function(type, fun, capture) { 3456 addEventListener: function(type, fun, capture) {
3379 if (!isValidListener(fun) || isMutationEvent(type)) 3457 if (!isValidListener(fun) || isMutationEvent(type))
3380 return; 3458 return;
3381 3459
3382 var listener = new Listener(type, fun, capture); 3460 var listener = new Listener(type, fun, capture);
3383 var listeners = listenersTable.get(this); 3461 var listeners = listenersTable.get(this);
3384 if (!listeners) { 3462 if (!listeners) {
3385 listeners = []; 3463 listeners = [];
3464 listeners.depth = 0;
3386 listenersTable.set(this, listeners); 3465 listenersTable.set(this, listeners);
3387 } else { 3466 } else {
3388 // Might have a duplicate. 3467 // Might have a duplicate.
3389 for (var i = 0; i < listeners.length; i++) { 3468 for (var i = 0; i < listeners.length; i++) {
3390 if (listener.equals(listeners[i])) 3469 if (listener.equals(listeners[i]))
3391 return; 3470 return;
3392 } 3471 }
3393 } 3472 }
3394 3473
3395 listeners.push(listener); 3474 listeners.push(listener);
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
3484 3563
3485 var originalElementFromPoint = document.elementFromPoint; 3564 var originalElementFromPoint = document.elementFromPoint;
3486 3565
3487 function elementFromPoint(self, document, x, y) { 3566 function elementFromPoint(self, document, x, y) {
3488 scope.renderAllPending(); 3567 scope.renderAllPending();
3489 3568
3490 var element = wrap(originalElementFromPoint.call(document.impl, x, y)); 3569 var element = wrap(originalElementFromPoint.call(document.impl, x, y));
3491 if (!element) 3570 if (!element)
3492 return null; 3571 return null;
3493 var path = getEventPath(element, null); 3572 var path = getEventPath(element, null);
3573
3574 // scope the path to this TreeScope
3575 var idx = path.lastIndexOf(self);
3576 if (idx == -1)
3577 return null;
3578 else
3579 path = path.slice(0, idx);
3580
3581 // TODO(dfreedm): pass idx to eventRetargetting to avoid array copy
3494 return eventRetargetting(path, self); 3582 return eventRetargetting(path, self);
3495 } 3583 }
3496 3584
3497 /** 3585 /**
3498 * Returns a function that is to be used as a getter for `onfoo` properties. 3586 * Returns a function that is to be used as a getter for `onfoo` properties.
3499 * @param {string} name 3587 * @param {string} name
3500 * @return {Function} 3588 * @return {Function}
3501 */ 3589 */
3502 function getEventHandlerGetter(name) { 3590 function getEventHandlerGetter(name) {
3503 return function() { 3591 return function() {
(...skipping 937 matching lines...) Expand 10 before | Expand all | Expand 10 after
4441 this.removeNode(n); 4529 this.removeNode(n);
4442 else if (!modNode) 4530 else if (!modNode)
4443 modNode = n; 4531 modNode = n;
4444 else { 4532 else {
4445 s += n.data; 4533 s += n.data;
4446 remNodes.push(n); 4534 remNodes.push(n);
4447 } 4535 }
4448 } else { 4536 } else {
4449 if (modNode && remNodes.length) { 4537 if (modNode && remNodes.length) {
4450 modNode.data += s; 4538 modNode.data += s;
4451 cleanUpNodes(remNodes); 4539 cleanupNodes(remNodes);
4452 } 4540 }
4453 remNodes = []; 4541 remNodes = [];
4454 s = ''; 4542 s = '';
4455 modNode = null; 4543 modNode = null;
4456 if (n.childNodes.length) 4544 if (n.childNodes.length)
4457 n.normalize(); 4545 n.normalize();
4458 } 4546 }
4459 } 4547 }
4460 4548
4461 // handle case where >1 text nodes are the last children 4549 // handle case where >1 text nodes are the last children
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
4759 this.parentNode.insertBefore(newTextNode, this.nextSibling); 4847 this.parentNode.insertBefore(newTextNode, this.nextSibling);
4760 return newTextNode; 4848 return newTextNode;
4761 } 4849 }
4762 }); 4850 });
4763 4851
4764 registerWrapper(OriginalText, Text, document.createTextNode('')); 4852 registerWrapper(OriginalText, Text, document.createTextNode(''));
4765 4853
4766 scope.wrappers.Text = Text; 4854 scope.wrappers.Text = Text;
4767 })(window.ShadowDOMPolyfill); 4855 })(window.ShadowDOMPolyfill);
4768 4856
4857 // Copyright 2014 The Polymer Authors. All rights reserved.
4858 // Use of this source code is goverened by a BSD-style
4859 // license that can be found in the LICENSE file.
4860
4861 (function(scope) {
4862 'use strict';
4863
4864 function invalidateClass(el) {
4865 scope.invalidateRendererBasedOnAttribute(el, 'class');
4866 }
4867
4868 function DOMTokenList(impl, ownerElement) {
4869 this.impl = impl;
4870 this.ownerElement_ = ownerElement;
4871 }
4872
4873 DOMTokenList.prototype = {
4874 get length() {
4875 return this.impl.length;
4876 },
4877 item: function(index) {
4878 return this.impl.item(index);
4879 },
4880 contains: function(token) {
4881 return this.impl.contains(token);
4882 },
4883 add: function() {
4884 this.impl.add.apply(this.impl, arguments);
4885 invalidateClass(this.ownerElement_);
4886 },
4887 remove: function() {
4888 this.impl.remove.apply(this.impl, arguments);
4889 invalidateClass(this.ownerElement_);
4890 },
4891 toggle: function(token) {
4892 var rv = this.impl.toggle.apply(this.impl, arguments);
4893 invalidateClass(this.ownerElement_);
4894 return rv;
4895 },
4896 toString: function() {
4897 return this.impl.toString();
4898 }
4899 };
4900
4901 scope.wrappers.DOMTokenList = DOMTokenList;
4902 })(window.ShadowDOMPolyfill);
4903
4769 // Copyright 2013 The Polymer Authors. All rights reserved. 4904 // Copyright 2013 The Polymer Authors. All rights reserved.
4770 // Use of this source code is goverened by a BSD-style 4905 // Use of this source code is goverened by a BSD-style
4771 // license that can be found in the LICENSE file. 4906 // license that can be found in the LICENSE file.
4772 4907
4773 (function(scope) { 4908 (function(scope) {
4774 'use strict'; 4909 'use strict';
4775 4910
4776 var ChildNodeInterface = scope.ChildNodeInterface; 4911 var ChildNodeInterface = scope.ChildNodeInterface;
4777 var GetElementsByInterface = scope.GetElementsByInterface; 4912 var GetElementsByInterface = scope.GetElementsByInterface;
4778 var Node = scope.wrappers.Node; 4913 var Node = scope.wrappers.Node;
4914 var DOMTokenList = scope.wrappers.DOMTokenList;
4779 var ParentNodeInterface = scope.ParentNodeInterface; 4915 var ParentNodeInterface = scope.ParentNodeInterface;
4780 var SelectorsInterface = scope.SelectorsInterface; 4916 var SelectorsInterface = scope.SelectorsInterface;
4781 var addWrapNodeListMethod = scope.addWrapNodeListMethod; 4917 var addWrapNodeListMethod = scope.addWrapNodeListMethod;
4782 var enqueueMutation = scope.enqueueMutation; 4918 var enqueueMutation = scope.enqueueMutation;
4783 var mixin = scope.mixin; 4919 var mixin = scope.mixin;
4784 var oneOf = scope.oneOf; 4920 var oneOf = scope.oneOf;
4785 var registerWrapper = scope.registerWrapper; 4921 var registerWrapper = scope.registerWrapper;
4922 var unwrap = scope.unwrap;
4786 var wrappers = scope.wrappers; 4923 var wrappers = scope.wrappers;
4787 4924
4788 var OriginalElement = window.Element; 4925 var OriginalElement = window.Element;
4789 4926
4790 var matchesNames = [ 4927 var matchesNames = [
4791 'matches', // needs to come first. 4928 'matches', // needs to come first.
4792 'mozMatchesSelector', 4929 'mozMatchesSelector',
4793 'msMatchesSelector', 4930 'msMatchesSelector',
4794 'webkitMatchesSelector', 4931 'webkitMatchesSelector',
4795 ].filter(function(name) { 4932 ].filter(function(name) {
(...skipping 19 matching lines...) Expand all
4815 // This is not fully spec compliant. We should use localName (which might 4952 // This is not fully spec compliant. We should use localName (which might
4816 // have a different case than name) and the namespace (which requires us 4953 // have a different case than name) and the namespace (which requires us
4817 // to get the Attr object). 4954 // to get the Attr object).
4818 enqueueMutation(element, 'attributes', { 4955 enqueueMutation(element, 'attributes', {
4819 name: name, 4956 name: name,
4820 namespace: null, 4957 namespace: null,
4821 oldValue: oldValue 4958 oldValue: oldValue
4822 }); 4959 });
4823 } 4960 }
4824 4961
4962 var classListTable = new WeakMap();
4963
4825 function Element(node) { 4964 function Element(node) {
4826 Node.call(this, node); 4965 Node.call(this, node);
4827 } 4966 }
4828 Element.prototype = Object.create(Node.prototype); 4967 Element.prototype = Object.create(Node.prototype);
4829 mixin(Element.prototype, { 4968 mixin(Element.prototype, {
4830 createShadowRoot: function() { 4969 createShadowRoot: function() {
4831 var newShadowRoot = new wrappers.ShadowRoot(this); 4970 var newShadowRoot = new wrappers.ShadowRoot(this);
4832 this.impl.polymerShadowRoot_ = newShadowRoot; 4971 this.impl.polymerShadowRoot_ = newShadowRoot;
4833 4972
4834 var renderer = scope.getRendererForHost(this); 4973 var renderer = scope.getRendererForHost(this);
(...skipping 17 matching lines...) Expand all
4852 4991
4853 removeAttribute: function(name) { 4992 removeAttribute: function(name) {
4854 var oldValue = this.impl.getAttribute(name); 4993 var oldValue = this.impl.getAttribute(name);
4855 this.impl.removeAttribute(name); 4994 this.impl.removeAttribute(name);
4856 enqueAttributeChange(this, name, oldValue); 4995 enqueAttributeChange(this, name, oldValue);
4857 invalidateRendererBasedOnAttribute(this, name); 4996 invalidateRendererBasedOnAttribute(this, name);
4858 }, 4997 },
4859 4998
4860 matches: function(selector) { 4999 matches: function(selector) {
4861 return originalMatches.call(this.impl, selector); 5000 return originalMatches.call(this.impl, selector);
5001 },
5002
5003 get classList() {
5004 var list = classListTable.get(this);
5005 if (!list) {
5006 classListTable.set(this,
5007 list = new DOMTokenList(unwrap(this).classList, this));
5008 }
5009 return list;
5010 },
5011
5012 get className() {
5013 return unwrap(this).className;
5014 },
5015
5016 set className(v) {
5017 this.setAttribute('class', v);
5018 },
5019
5020 get id() {
5021 return unwrap(this).id;
5022 },
5023
5024 set id(v) {
5025 this.setAttribute('id', v);
4862 } 5026 }
4863 }); 5027 });
4864 5028
4865 matchesNames.forEach(function(name) { 5029 matchesNames.forEach(function(name) {
4866 if (name !== 'matches') { 5030 if (name !== 'matches') {
4867 Element.prototype[name] = function(selector) { 5031 Element.prototype[name] = function(selector) {
4868 return this.matches(selector); 5032 return this.matches(selector);
4869 }; 5033 };
4870 } 5034 }
4871 }); 5035 });
4872 5036
4873 if (OriginalElement.prototype.webkitCreateShadowRoot) { 5037 if (OriginalElement.prototype.webkitCreateShadowRoot) {
4874 Element.prototype.webkitCreateShadowRoot = 5038 Element.prototype.webkitCreateShadowRoot =
4875 Element.prototype.createShadowRoot; 5039 Element.prototype.createShadowRoot;
4876 } 5040 }
4877 5041
4878 /**
4879 * Useful for generating the accessor pair for a property that reflects an
4880 * attribute.
4881 */
4882 function setterDirtiesAttribute(prototype, propertyName, opt_attrName) {
4883 var attrName = opt_attrName || propertyName;
4884 Object.defineProperty(prototype, propertyName, {
4885 get: function() {
4886 return this.impl[propertyName];
4887 },
4888 set: function(v) {
4889 this.impl[propertyName] = v;
4890 invalidateRendererBasedOnAttribute(this, attrName);
4891 },
4892 configurable: true,
4893 enumerable: true
4894 });
4895 }
4896
4897 setterDirtiesAttribute(Element.prototype, 'id');
4898 setterDirtiesAttribute(Element.prototype, 'className', 'class');
4899
4900 mixin(Element.prototype, ChildNodeInterface); 5042 mixin(Element.prototype, ChildNodeInterface);
4901 mixin(Element.prototype, GetElementsByInterface); 5043 mixin(Element.prototype, GetElementsByInterface);
4902 mixin(Element.prototype, ParentNodeInterface); 5044 mixin(Element.prototype, ParentNodeInterface);
4903 mixin(Element.prototype, SelectorsInterface); 5045 mixin(Element.prototype, SelectorsInterface);
4904 5046
4905 registerWrapper(OriginalElement, Element, 5047 registerWrapper(OriginalElement, Element,
4906 document.createElementNS(null, 'x')); 5048 document.createElementNS(null, 'x'));
4907 5049
4908 // TODO(arv): Export setterDirtiesAttribute and apply it to more bindings 5050 scope.invalidateRendererBasedOnAttribute = invalidateRendererBasedOnAttribute;
4909 // that reflect attributes.
4910 scope.matchesNames = matchesNames; 5051 scope.matchesNames = matchesNames;
4911 scope.wrappers.Element = Element; 5052 scope.wrappers.Element = Element;
4912 })(window.ShadowDOMPolyfill); 5053 })(window.ShadowDOMPolyfill);
4913 5054
4914 // Copyright 2013 The Polymer Authors. All rights reserved. 5055 // Copyright 2013 The Polymer Authors. All rights reserved.
4915 // Use of this source code is goverened by a BSD-style 5056 // Use of this source code is goverened by a BSD-style
4916 // license that can be found in the LICENSE file. 5057 // license that can be found in the LICENSE file.
4917 5058
4918 (function(scope) { 5059 (function(scope) {
4919 'use strict'; 5060 'use strict';
(...skipping 875 matching lines...) Expand 10 before | Expand all | Expand 10 after
5795 scope.wrappers.HTMLUnknownElement = HTMLUnknownElement; 5936 scope.wrappers.HTMLUnknownElement = HTMLUnknownElement;
5796 })(window.ShadowDOMPolyfill); 5937 })(window.ShadowDOMPolyfill);
5797 5938
5798 // Copyright 2014 The Polymer Authors. All rights reserved. 5939 // Copyright 2014 The Polymer Authors. All rights reserved.
5799 // Use of this source code is goverened by a BSD-style 5940 // Use of this source code is goverened by a BSD-style
5800 // license that can be found in the LICENSE file. 5941 // license that can be found in the LICENSE file.
5801 5942
5802 (function(scope) { 5943 (function(scope) {
5803 'use strict'; 5944 'use strict';
5804 5945
5946 var Element = scope.wrappers.Element;
5947 var HTMLElement = scope.wrappers.HTMLElement;
5805 var registerObject = scope.registerObject; 5948 var registerObject = scope.registerObject;
5806 5949
5807 var SVG_NS = 'http://www.w3.org/2000/svg'; 5950 var SVG_NS = 'http://www.w3.org/2000/svg';
5808 var svgTitleElement = document.createElementNS(SVG_NS, 'title'); 5951 var svgTitleElement = document.createElementNS(SVG_NS, 'title');
5809 var SVGTitleElement = registerObject(svgTitleElement); 5952 var SVGTitleElement = registerObject(svgTitleElement);
5810 var SVGElement = Object.getPrototypeOf(SVGTitleElement.prototype).constructor; 5953 var SVGElement = Object.getPrototypeOf(SVGTitleElement.prototype).constructor;
5811 5954
5955 // IE11 does not have classList for SVG elements. The spec says that classList
5956 // is an accessor on Element, but IE11 puts classList on HTMLElement, leaving
5957 // SVGElement without a classList property. We therefore move the accessor for
5958 // IE11.
5959 if (!('classList' in svgTitleElement)) {
5960 var descr = Object.getOwnPropertyDescriptor(Element.prototype, 'classList');
5961 Object.defineProperty(HTMLElement.prototype, 'classList', descr);
5962 delete Element.prototype.classList;
5963 }
5964
5812 scope.wrappers.SVGElement = SVGElement; 5965 scope.wrappers.SVGElement = SVGElement;
5813 })(window.ShadowDOMPolyfill); 5966 })(window.ShadowDOMPolyfill);
5814 5967
5815 // Copyright 2014 The Polymer Authors. All rights reserved. 5968 // Copyright 2014 The Polymer Authors. All rights reserved.
5816 // Use of this source code is goverened by a BSD-style 5969 // Use of this source code is goverened by a BSD-style
5817 // license that can be found in the LICENSE file. 5970 // license that can be found in the LICENSE file.
5818 5971
5819 (function(scope) { 5972 (function(scope) {
5820 'use strict'; 5973 'use strict';
5821 5974
(...skipping 1271 matching lines...) Expand 10 before | Expand all | Expand 10 after
7093 }, 7246 },
7094 elementFromPoint: function(x, y) { 7247 elementFromPoint: function(x, y) {
7095 return elementFromPoint(this, this, x, y); 7248 return elementFromPoint(this, this, x, y);
7096 }, 7249 },
7097 importNode: function(node, deep) { 7250 importNode: function(node, deep) {
7098 return cloneNode(node, deep, this.impl); 7251 return cloneNode(node, deep, this.impl);
7099 }, 7252 },
7100 getSelection: function() { 7253 getSelection: function() {
7101 renderAllPending(); 7254 renderAllPending();
7102 return new Selection(originalGetSelection.call(unwrap(this))); 7255 return new Selection(originalGetSelection.call(unwrap(this)));
7256 },
7257 getElementsByName: function(name) {
7258 return SelectorsInterface.querySelectorAll.call(this,
7259 '[name=' + JSON.stringify(String(name)) + ']');
7103 } 7260 }
7104 }); 7261 });
7105 7262
7106 if (document.registerElement) { 7263 if (document.registerElement) {
7107 var originalRegisterElement = document.registerElement; 7264 var originalRegisterElement = document.registerElement;
7108 Document.prototype.registerElement = function(tagName, object) { 7265 Document.prototype.registerElement = function(tagName, object) {
7109 var prototype, extendsOption; 7266 var prototype, extendsOption;
7110 if (object !== undefined) { 7267 if (object !== undefined) {
7111 prototype = object.prototype; 7268 prototype = object.prototype;
7112 extendsOption = object.extends; 7269 extendsOption = object.extends;
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
7237 'createComment', 7394 'createComment',
7238 'createDocumentFragment', 7395 'createDocumentFragment',
7239 'createElement', 7396 'createElement',
7240 'createElementNS', 7397 'createElementNS',
7241 'createEvent', 7398 'createEvent',
7242 'createEventNS', 7399 'createEventNS',
7243 'createRange', 7400 'createRange',
7244 'createTextNode', 7401 'createTextNode',
7245 'elementFromPoint', 7402 'elementFromPoint',
7246 'getElementById', 7403 'getElementById',
7404 'getElementsByName',
7247 'getSelection', 7405 'getSelection',
7248 ]); 7406 ]);
7249 7407
7250 mixin(Document.prototype, GetElementsByInterface); 7408 mixin(Document.prototype, GetElementsByInterface);
7251 mixin(Document.prototype, ParentNodeInterface); 7409 mixin(Document.prototype, ParentNodeInterface);
7252 mixin(Document.prototype, SelectorsInterface); 7410 mixin(Document.prototype, SelectorsInterface);
7253 7411
7254 mixin(Document.prototype, { 7412 mixin(Document.prototype, {
7255 get implementation() { 7413 get implementation() {
7256 var implementation = implementationTable.get(this); 7414 var implementation = implementationTable.get(this);
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
7527 7685
7528 /* 7686 /*
7529 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. 7687 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
7530 * This code may only be used under the BSD style license found at http://polyme r.github.io/LICENSE.txt 7688 * This code may only be used under the BSD style license found at http://polyme r.github.io/LICENSE.txt
7531 * The complete set of authors may be found at http://polymer.github.io/AUTHORS. txt 7689 * The complete set of authors may be found at http://polymer.github.io/AUTHORS. txt
7532 * The complete set of contributors may be found at http://polymer.github.io/CON TRIBUTORS.txt 7690 * The complete set of contributors may be found at http://polymer.github.io/CON TRIBUTORS.txt
7533 * Code distributed by Google as part of the polymer project is also 7691 * Code distributed by Google as part of the polymer project is also
7534 * subject to an additional IP rights grant found at http://polymer.github.io/PA TENTS.txt 7692 * subject to an additional IP rights grant found at http://polymer.github.io/PA TENTS.txt
7535 */ 7693 */
7536 7694
7537 (function() { 7695 (function(scope) {
7538 7696
7539 // convenient global 7697 // convenient global
7540 window.wrap = ShadowDOMPolyfill.wrapIfNeeded; 7698 window.wrap = ShadowDOMPolyfill.wrapIfNeeded;
7541 window.unwrap = ShadowDOMPolyfill.unwrapIfNeeded; 7699 window.unwrap = ShadowDOMPolyfill.unwrapIfNeeded;
7542 7700
7543 // users may want to customize other types 7701 // users may want to customize other types
7544 // TODO(sjmiles): 'button' is now supported by ShadowDOMPolyfill, but 7702 // TODO(sjmiles): 'button' is now supported by ShadowDOMPolyfill, but
7545 // I've left this code here in case we need to temporarily patch another 7703 // I've left this code here in case we need to temporarily patch another
7546 // type 7704 // type
7547 /* 7705 /*
(...skipping 12 matching lines...) Expand all
7560 Object.getOwnPropertyDescriptor(Element.prototype, 'shadowRoot')); 7718 Object.getOwnPropertyDescriptor(Element.prototype, 'shadowRoot'));
7561 7719
7562 var originalCreateShadowRoot = Element.prototype.createShadowRoot; 7720 var originalCreateShadowRoot = Element.prototype.createShadowRoot;
7563 Element.prototype.createShadowRoot = function() { 7721 Element.prototype.createShadowRoot = function() {
7564 var root = originalCreateShadowRoot.call(this); 7722 var root = originalCreateShadowRoot.call(this);
7565 CustomElements.watchShadow(this); 7723 CustomElements.watchShadow(this);
7566 return root; 7724 return root;
7567 }; 7725 };
7568 7726
7569 Element.prototype.webkitCreateShadowRoot = Element.prototype.createShadowRoot; 7727 Element.prototype.webkitCreateShadowRoot = Element.prototype.createShadowRoot;
7570 })(); 7728
7729 function queryShadow(node, selector) {
7730 var m, el = node.firstElementChild;
7731 var shadows, sr, i;
7732 shadows = [];
7733 sr = node.shadowRoot;
7734 while(sr) {
7735 shadows.push(sr);
7736 sr = sr.olderShadowRoot;
7737 }
7738 for(i = shadows.length - 1; i >= 0; i--) {
7739 m = shadows[i].querySelector(selector);
7740 if (m) {
7741 return m;
7742 }
7743 }
7744 while(el) {
7745 m = queryShadow(el, selector);
7746 if (m) {
7747 return m;
7748 }
7749 el = el.nextElementSibling;
7750 }
7751 return null;
7752 }
7753
7754 function queryAllShadows(node, selector, results) {
7755 var el = node.firstElementChild;
7756 var temp, sr, shadows, i, j;
7757 shadows = [];
7758 sr = node.shadowRoot;
7759 while(sr) {
7760 shadows.push(sr);
7761 sr = sr.olderShadowRoot;
7762 }
7763 for (i = shadows.length - 1; i >= 0; i--) {
7764 temp = shadows[i].querySelectorAll(selector);
7765 for(j = 0; j < temp.length; j++) {
7766 results.push(temp[j]);
7767 }
7768 }
7769 while (el) {
7770 queryAllShadows(el, selector, results);
7771 el = el.nextElementSibling;
7772 }
7773 return results;
7774 }
7775
7776 scope.queryAllShadows = function(node, selector, all) {
7777 if (all) {
7778 return queryAllShadows(node, selector, []);
7779 } else {
7780 return queryShadow(node, selector);
7781 }
7782 };
7783 })(window.Platform);
7571 7784
7572 /* 7785 /*
7573 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. 7786 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
7574 * This code may only be used under the BSD style license found at http://polyme r.github.io/LICENSE.txt 7787 * This code may only be used under the BSD style license found at http://polyme r.github.io/LICENSE.txt
7575 * The complete set of authors may be found at http://polymer.github.io/AUTHORS. txt 7788 * The complete set of authors may be found at http://polymer.github.io/AUTHORS. txt
7576 * The complete set of contributors may be found at http://polymer.github.io/CON TRIBUTORS.txt 7789 * The complete set of contributors may be found at http://polymer.github.io/CON TRIBUTORS.txt
7577 * Code distributed by Google as part of the polymer project is also 7790 * Code distributed by Google as part of the polymer project is also
7578 * subject to an additional IP rights grant found at http://polymer.github.io/PA TENTS.txt 7791 * subject to an additional IP rights grant found at http://polymer.github.io/PA TENTS.txt
7579 */ 7792 */
7580 7793
(...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after
7962 for (var i=0; i < combinatorsRe.length; i++) { 8175 for (var i=0; i < combinatorsRe.length; i++) {
7963 cssText = cssText.replace(combinatorsRe[i], ' '); 8176 cssText = cssText.replace(combinatorsRe[i], ' ');
7964 } 8177 }
7965 return cssText; 8178 return cssText;
7966 }, 8179 },
7967 // change a selector like 'div' to 'name div' 8180 // change a selector like 'div' to 'name div'
7968 scopeRules: function(cssRules, scopeSelector) { 8181 scopeRules: function(cssRules, scopeSelector) {
7969 var cssText = ''; 8182 var cssText = '';
7970 if (cssRules) { 8183 if (cssRules) {
7971 Array.prototype.forEach.call(cssRules, function(rule) { 8184 Array.prototype.forEach.call(cssRules, function(rule) {
7972 if (rule.selectorText && (rule.style && rule.style.cssText)) { 8185 if (rule.selectorText && (rule.style && rule.style.cssText !== undefined )) {
7973 cssText += this.scopeSelector(rule.selectorText, scopeSelector, 8186 cssText += this.scopeSelector(rule.selectorText, scopeSelector,
7974 this.strictStyling) + ' {\n\t'; 8187 this.strictStyling) + ' {\n\t';
7975 cssText += this.propertiesFromRule(rule) + '\n}\n\n'; 8188 cssText += this.propertiesFromRule(rule) + '\n}\n\n';
7976 } else if (rule.type === CSSRule.MEDIA_RULE) { 8189 } else if (rule.type === CSSRule.MEDIA_RULE) {
7977 cssText += '@media ' + rule.media.mediaText + ' {\n'; 8190 cssText += '@media ' + rule.media.mediaText + ' {\n';
7978 cssText += this.scopeRules(rule.cssRules, scopeSelector); 8191 cssText += this.scopeRules(rule.cssRules, scopeSelector);
7979 cssText += '\n}\n\n'; 8192 cssText += '\n}\n\n';
7980 } else if (rule.cssText) { 8193 } else {
7981 cssText += rule.cssText + '\n\n'; 8194 // TODO(sjmiles): KEYFRAMES_RULE in IE11 throws when we query cssText
8195 // 'cssText' in rule returns true, but rule.cssText throws anyway
8196 // We can test the rule type, e.g.
8197 // else if (rule.type !== CSSRule.KEYFRAMES_RULE && rule.cssText) {
8198 // but this will prevent cssText propagation in other browsers which
8199 // support it.
8200 // KEYFRAMES_RULE has a CSSRuleSet, so the text can probably be recons tructed
8201 // from that collection; this would be a proper fix.
8202 // For now, I'm trapping the exception so IE11 is unblocked in other a reas.
8203 try {
8204 if (rule.cssText) {
8205 cssText += rule.cssText + '\n\n';
8206 }
8207 } catch(x) {
8208 // squelch
8209 }
7982 } 8210 }
7983 }, this); 8211 }, this);
7984 } 8212 }
7985 return cssText; 8213 return cssText;
7986 }, 8214 },
7987 scopeSelector: function(selector, scopeSelector, strict) { 8215 scopeSelector: function(selector, scopeSelector, strict) {
7988 var r = [], parts = selector.split(','); 8216 var r = [], parts = selector.split(',');
7989 parts.forEach(function(p) { 8217 parts.forEach(function(p) {
7990 p = p.trim(); 8218 p = p.trim();
7991 if (this.selectorNeedsScoping(p, scopeSelector)) { 8219 if (this.selectorNeedsScoping(p, scopeSelector)) {
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
8299 if (style.parentNode !== head) { 8527 if (style.parentNode !== head) {
8300 // replace links in head 8528 // replace links in head
8301 if (elt.parentNode === head) { 8529 if (elt.parentNode === head) {
8302 head.replaceChild(style, elt); 8530 head.replaceChild(style, elt);
8303 } else { 8531 } else {
8304 head.appendChild(style); 8532 head.appendChild(style);
8305 } 8533 }
8306 } 8534 }
8307 style.__importParsed = true; 8535 style.__importParsed = true;
8308 this.markParsingComplete(elt); 8536 this.markParsingComplete(elt);
8537 this.parseNext();
8309 } 8538 }
8310 8539
8311 var hasResource = HTMLImports.parser.hasResource; 8540 var hasResource = HTMLImports.parser.hasResource;
8312 HTMLImports.parser.hasResource = function(node) { 8541 HTMLImports.parser.hasResource = function(node) {
8313 if (node.localName === 'link' && node.rel === 'stylesheet' && 8542 if (node.localName === 'link' && node.rel === 'stylesheet' &&
8314 node.hasAttribute(SHIM_ATTRIBUTE)) { 8543 node.hasAttribute(SHIM_ATTRIBUTE)) {
8315 return (node.__resource); 8544 return (node.__resource);
8316 } else { 8545 } else {
8317 return hasResource.call(this, node); 8546 return hasResource.call(this, node);
8318 } 8547 }
(...skipping 1094 matching lines...) Expand 10 before | Expand all | Expand 10 after
9413 9642
9414 function module(name, dependsOrFactory, moduleFactory) { 9643 function module(name, dependsOrFactory, moduleFactory) {
9415 var module; 9644 var module;
9416 switch (arguments.length) { 9645 switch (arguments.length) {
9417 case 0: 9646 case 0:
9418 return; 9647 return;
9419 case 1: 9648 case 1:
9420 module = null; 9649 module = null;
9421 break; 9650 break;
9422 case 2: 9651 case 2:
9652 // dependsOrFactory is `factory` in this case
9423 module = dependsOrFactory.apply(this); 9653 module = dependsOrFactory.apply(this);
9424 break; 9654 break;
9425 default: 9655 default:
9656 // dependsOrFactory is `depends` in this case
9426 module = withDependencies(moduleFactory, dependsOrFactory); 9657 module = withDependencies(moduleFactory, dependsOrFactory);
9427 break; 9658 break;
9428 } 9659 }
9429 modules[name] = module; 9660 modules[name] = module;
9430 }; 9661 };
9431 9662
9432 function marshal(name) { 9663 function marshal(name) {
9433 return modules[name]; 9664 return modules[name];
9434 } 9665 }
9435 9666
9436 var modules = {}; 9667 var modules = {};
9437 9668
9438 function using(depends, task) { 9669 function using(depends, task) {
9439 HTMLImports.whenImportsReady(function() { 9670 HTMLImports.whenImportsReady(function() {
9440 withDependencies(task, depends); 9671 withDependencies(task, depends);
9441 }); 9672 });
9442 }; 9673 };
9443 9674
9444 // exports 9675 // exports
9445 9676
9446 scope.marshal = marshal; 9677 scope.marshal = marshal;
9447 scope.module = module; 9678 // `module` confuses commonjs detectors
9679 scope.modularize = module;
9448 scope.using = using; 9680 scope.using = using;
9449 9681
9450 })(window); 9682 })(window);
9451 9683
9452 /* 9684 /*
9453 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved. 9685 * Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
9454 * This code may only be used under the BSD style license found at http://polyme r.github.io/LICENSE.txt 9686 * This code may only be used under the BSD style license found at http://polyme r.github.io/LICENSE.txt
9455 * The complete set of authors may be found at http://polymer.github.io/AUTHORS. txt 9687 * The complete set of authors may be found at http://polymer.github.io/AUTHORS. txt
9456 * The complete set of contributors may be found at http://polymer.github.io/CON TRIBUTORS.txt 9688 * The complete set of contributors may be found at http://polymer.github.io/CON TRIBUTORS.txt
9457 * Code distributed by Google as part of the polymer project is also 9689 * Code distributed by Google as part of the polymer project is also
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
9544 } 9776 }
9545 }, 9777 },
9546 resolveElementAttributes: function(node, url) { 9778 resolveElementAttributes: function(node, url) {
9547 url = url || node.ownerDocument.baseURI; 9779 url = url || node.ownerDocument.baseURI;
9548 URL_ATTRS.forEach(function(v) { 9780 URL_ATTRS.forEach(function(v) {
9549 var attr = node.attributes[v]; 9781 var attr = node.attributes[v];
9550 var value = attr && attr.value; 9782 var value = attr && attr.value;
9551 var replacement; 9783 var replacement;
9552 if (value && value.search(URL_TEMPLATE_SEARCH) < 0) { 9784 if (value && value.search(URL_TEMPLATE_SEARCH) < 0) {
9553 if (v === 'style') { 9785 if (v === 'style') {
9554 replacement = replaceUrlsInCssText(value, url, CSS_URL_REGEXP); 9786 replacement = replaceUrlsInCssText(value, url, false, CSS_URL_REGEXP);
9555 } else { 9787 } else {
9556 replacement = resolveRelativeUrl(url, value); 9788 replacement = resolveRelativeUrl(url, value);
9557 } 9789 }
9558 attr.value = replacement; 9790 attr.value = replacement;
9559 } 9791 }
9560 }); 9792 });
9561 } 9793 }
9562 }; 9794 };
9563 9795
9564 var CSS_URL_REGEXP = /(url\()([^)]*)(\))/g; 9796 var CSS_URL_REGEXP = /(url\()([^)]*)(\))/g;
9565 var CSS_IMPORT_REGEXP = /(@import[\s]+(?!url\())([^;]*)(;)/g; 9797 var CSS_IMPORT_REGEXP = /(@import[\s]+(?!url\())([^;]*)(;)/g;
9566 var URL_ATTRS = ['href', 'src', 'action', 'style']; 9798 var URL_ATTRS = ['href', 'src', 'action', 'style', 'url'];
9567 var URL_ATTRS_SELECTOR = '[' + URL_ATTRS.join('],[') + ']'; 9799 var URL_ATTRS_SELECTOR = '[' + URL_ATTRS.join('],[') + ']';
9568 var URL_TEMPLATE_SEARCH = '{{.*}}'; 9800 var URL_TEMPLATE_SEARCH = '{{.*}}';
9569 9801
9570 function replaceUrlsInCssText(cssText, baseUrl, keepAbsolute, regexp) { 9802 function replaceUrlsInCssText(cssText, baseUrl, keepAbsolute, regexp) {
9571 return cssText.replace(regexp, function(m, pre, url, post) { 9803 return cssText.replace(regexp, function(m, pre, url, post) {
9572 var urlPath = url.replace(/["']/g, ''); 9804 var urlPath = url.replace(/["']/g, '');
9573 urlPath = resolveRelativeUrl(baseUrl, urlPath, keepAbsolute); 9805 urlPath = resolveRelativeUrl(baseUrl, urlPath, keepAbsolute);
9574 return pre + '\'' + urlPath + '\'' + post; 9806 return pre + '\'' + urlPath + '\'' + post;
9575 }); 9807 });
9576 } 9808 }
(...skipping 677 matching lines...) Expand 10 before | Expand all | Expand 10 after
10254 var body = pieces[1]; 10486 var body = pieces[1];
10255 if(header.indexOf(';base64') > -1) { 10487 if(header.indexOf(';base64') > -1) {
10256 body = atob(body); 10488 body = atob(body);
10257 } else { 10489 } else {
10258 body = decodeURIComponent(body); 10490 body = decodeURIComponent(body);
10259 } 10491 }
10260 setTimeout(function() { 10492 setTimeout(function() {
10261 this.receive(url, elt, null, body); 10493 this.receive(url, elt, null, body);
10262 }.bind(this), 0); 10494 }.bind(this), 0);
10263 } else { 10495 } else {
10264 var receiveXhr = function(err, resource) { 10496 var receiveXhr = function(err, resource, redirectedUrl) {
10265 this.receive(url, elt, err, resource); 10497 this.receive(url, elt, err, resource, redirectedUrl);
10266 }.bind(this); 10498 }.bind(this);
10267 xhr.load(url, receiveXhr); 10499 xhr.load(url, receiveXhr);
10268 // TODO(sorvell): blocked on) 10500 // TODO(sorvell): blocked on)
10269 // https://code.google.com/p/chromium/issues/detail?id=257221 10501 // https://code.google.com/p/chromium/issues/detail?id=257221
10270 // xhr'ing for a document makes scripts in imports runnable; otherwise 10502 // xhr'ing for a document makes scripts in imports runnable; otherwise
10271 // they are not; however, it requires that we have doctype=html in 10503 // they are not; however, it requires that we have doctype=html in
10272 // the import which is unacceptable. This is only needed on Chrome 10504 // the import which is unacceptable. This is only needed on Chrome
10273 // to avoid the bug above. 10505 // to avoid the bug above.
10274 /* 10506 /*
10275 if (isDocumentLink(elt)) { 10507 if (isDocumentLink(elt)) {
10276 xhr.loadDocument(url, receiveXhr); 10508 xhr.loadDocument(url, receiveXhr);
10277 } else { 10509 } else {
10278 xhr.load(url, receiveXhr); 10510 xhr.load(url, receiveXhr);
10279 } 10511 }
10280 */ 10512 */
10281 } 10513 }
10282 }, 10514 },
10283 receive: function(url, elt, err, resource) { 10515 receive: function(url, elt, err, resource, redirectedUrl) {
10284 this.cache[url] = resource; 10516 this.cache[url] = resource;
10285 var $p = this.pending[url]; 10517 var $p = this.pending[url];
10518 if ( redirectedUrl && redirectedUrl !== url ) {
10519 this.cache[redirectedUrl] = resource;
10520 $p = $p.concat(this.pending[redirectedUrl]);
10521 }
10286 for (var i=0, l=$p.length, p; (i<l) && (p=$p[i]); i++) { 10522 for (var i=0, l=$p.length, p; (i<l) && (p=$p[i]); i++) {
10287 //if (!err) { 10523 //if (!err) {
10288 this.onload(url, p, resource); 10524 // If url was redirected, use the redirected location so paths are
10525 // calculated relative to that.
10526 this.onload(redirectedUrl || url, p, resource);
10289 //} 10527 //}
10290 this.tail(); 10528 this.tail();
10291 } 10529 }
10292 this.pending[url] = null; 10530 this.pending[url] = null;
10531 if ( redirectedUrl && redirectedUrl !== url ) {
10532 this.pending[redirectedUrl] = null;
10533 }
10293 }, 10534 },
10294 tail: function() { 10535 tail: function() {
10295 --this.inflight; 10536 --this.inflight;
10296 this.checkDone(); 10537 this.checkDone();
10297 }, 10538 },
10298 checkDone: function() { 10539 checkDone: function() {
10299 if (!this.inflight) { 10540 if (!this.inflight) {
10300 this.oncomplete(); 10541 this.oncomplete();
10301 } 10542 }
10302 } 10543 }
10303 }; 10544 };
10304 10545
10305 xhr = xhr || { 10546 xhr = xhr || {
10306 async: true, 10547 async: true,
10307 ok: function(request) { 10548 ok: function(request) {
10308 return (request.status >= 200 && request.status < 300) 10549 return (request.status >= 200 && request.status < 300)
10309 || (request.status === 304) 10550 || (request.status === 304)
10310 || (request.status === 0); 10551 || (request.status === 0);
10311 }, 10552 },
10312 load: function(url, next, nextContext) { 10553 load: function(url, next, nextContext) {
10313 var request = new XMLHttpRequest(); 10554 var request = new XMLHttpRequest();
10314 if (scope.flags.debug || scope.flags.bust) { 10555 if (scope.flags.debug || scope.flags.bust) {
10315 url += '?' + Math.random(); 10556 url += '?' + Math.random();
10316 } 10557 }
10317 request.open('GET', url, xhr.async); 10558 request.open('GET', url, xhr.async);
10318 request.addEventListener('readystatechange', function(e) { 10559 request.addEventListener('readystatechange', function(e) {
10319 if (request.readyState === 4) { 10560 if (request.readyState === 4) {
10561 // Servers redirecting an import can add a Location header to help us
10562 // polyfill correctly.
10563 var locationHeader = request.getResponseHeader("Location");
10564 var redirectedUrl = null;
10565 if (locationHeader) {
10566 var redirectedUrl = (locationHeader.substr( 0, 1 ) === "/")
10567 ? location.origin + locationHeader // Location is a relative path
10568 : redirectedUrl; // Full path
10569 }
10320 next.call(nextContext, !xhr.ok(request) && request, 10570 next.call(nextContext, !xhr.ok(request) && request,
10321 request.response || request.responseText, url); 10571 request.response || request.responseText, redirectedUrl);
10322 } 10572 }
10323 }); 10573 });
10324 request.send(); 10574 request.send();
10325 return request; 10575 return request;
10326 }, 10576 },
10327 loadDocument: function(url, next, nextContext) { 10577 loadDocument: function(url, next, nextContext) {
10328 this.load(url, next, nextContext).responseType = 'document'; 10578 this.load(url, next, nextContext).responseType = 'document';
10329 } 10579 }
10330 }; 10580 };
10331 10581
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
10385 if (this.isParsed(elt)) { 10635 if (this.isParsed(elt)) {
10386 flags.parse && console.log('[%s] is already parsed', elt.localName); 10636 flags.parse && console.log('[%s] is already parsed', elt.localName);
10387 return; 10637 return;
10388 } 10638 }
10389 var fn = this[this.map[elt.localName]]; 10639 var fn = this[this.map[elt.localName]];
10390 if (fn) { 10640 if (fn) {
10391 this.markParsing(elt); 10641 this.markParsing(elt);
10392 fn.call(this, elt); 10642 fn.call(this, elt);
10393 } 10643 }
10394 }, 10644 },
10395 // only 1 element may be parsed at a time; parsing is async so, each 10645 // only 1 element may be parsed at a time; parsing is async so each
10396 // parsing implementation must inform the system that parsing is complete 10646 // parsing implementation must inform the system that parsing is complete
10397 // via markParsingComplete. 10647 // via markParsingComplete.
10648 // To prompt the system to parse the next element, parseNext should then be
10649 // called.
10650 // Note, parseNext used to be included at the end of markParsingComplete, but
10651 // we must not do this so that, for example, we can (1) mark parsing complete
10652 // then (2) fire an import load event, and then (3) parse the next resource.
10398 markParsing: function(elt) { 10653 markParsing: function(elt) {
10399 flags.parse && console.log('parsing', elt); 10654 flags.parse && console.log('parsing', elt);
10400 this.parsingElement = elt; 10655 this.parsingElement = elt;
10401 }, 10656 },
10402 markParsingComplete: function(elt) { 10657 markParsingComplete: function(elt) {
10403 elt.__importParsed = true; 10658 elt.__importParsed = true;
10404 if (elt.__importElement) { 10659 if (elt.__importElement) {
10405 elt.__importElement.__importParsed = true; 10660 elt.__importElement.__importParsed = true;
10406 } 10661 }
10407 this.parsingElement = null; 10662 this.parsingElement = null;
10408 flags.parse && console.log('completed', elt); 10663 flags.parse && console.log('completed', elt);
10409 this.parseNext(); 10664 },
10665 invalidateParse: function(doc) {
10666 if (doc && doc.__importLink) {
10667 doc.__importParsed = doc.__importLink.__importParsed = false;
10668 this.parseSoon();
10669 }
10670 },
10671 parseSoon: function() {
10672 if (this._parseSoon) {
10673 cancelAnimationFrame(this._parseDelay);
10674 }
10675 var parser = this;
10676 this._parseSoon = requestAnimationFrame(function() {
10677 parser.parseNext();
10678 });
10410 }, 10679 },
10411 parseImport: function(elt) { 10680 parseImport: function(elt) {
10412 elt.import.__importParsed = true;
10413 // TODO(sorvell): consider if there's a better way to do this; 10681 // TODO(sorvell): consider if there's a better way to do this;
10414 // expose an imports parsing hook; this is needed, for example, by the 10682 // expose an imports parsing hook; this is needed, for example, by the
10415 // CustomElements polyfill. 10683 // CustomElements polyfill.
10416 if (HTMLImports.__importsParsingHook) { 10684 if (HTMLImports.__importsParsingHook) {
10417 HTMLImports.__importsParsingHook(elt); 10685 HTMLImports.__importsParsingHook(elt);
10418 } 10686 }
10687 elt.import.__importParsed = true;
10688 this.markParsingComplete(elt);
10419 // fire load event 10689 // fire load event
10420 if (elt.__resource) { 10690 if (elt.__resource) {
10421 elt.dispatchEvent(new CustomEvent('load', {bubbles: false})); 10691 elt.dispatchEvent(new CustomEvent('load', {bubbles: false}));
10422 } else { 10692 } else {
10423 elt.dispatchEvent(new CustomEvent('error', {bubbles: false})); 10693 elt.dispatchEvent(new CustomEvent('error', {bubbles: false}));
10424 } 10694 }
10425 // TODO(sorvell): workaround for Safari addEventListener not working 10695 // TODO(sorvell): workaround for Safari addEventListener not working
10426 // for elements not in the main document. 10696 // for elements not in the main document.
10427 if (elt.__pending) { 10697 if (elt.__pending) {
10428 var fn; 10698 var fn;
10429 while (elt.__pending.length) { 10699 while (elt.__pending.length) {
10430 fn = elt.__pending.shift(); 10700 fn = elt.__pending.shift();
10431 if (fn) { 10701 if (fn) {
10432 fn({target: elt}); 10702 fn({target: elt});
10433 } 10703 }
10434 } 10704 }
10435 } 10705 }
10436 this.markParsingComplete(elt); 10706 this.parseNext();
10437 }, 10707 },
10438 parseLink: function(linkElt) { 10708 parseLink: function(linkElt) {
10439 if (nodeIsImport(linkElt)) { 10709 if (nodeIsImport(linkElt)) {
10440 this.parseImport(linkElt); 10710 this.parseImport(linkElt);
10441 } else { 10711 } else {
10442 // make href absolute 10712 // make href absolute
10443 linkElt.href = linkElt.href; 10713 linkElt.href = linkElt.href;
10444 this.parseGeneric(linkElt); 10714 this.parseGeneric(linkElt);
10445 } 10715 }
10446 }, 10716 },
10447 parseStyle: function(elt) { 10717 parseStyle: function(elt) {
10448 // TODO(sorvell): style element load event can just not fire so clone styles 10718 // TODO(sorvell): style element load event can just not fire so clone styles
10449 var src = elt; 10719 var src = elt;
10450 elt = cloneStyle(elt); 10720 elt = cloneStyle(elt);
10451 elt.__importElement = src; 10721 elt.__importElement = src;
10452 this.parseGeneric(elt); 10722 this.parseGeneric(elt);
10453 }, 10723 },
10454 parseGeneric: function(elt) { 10724 parseGeneric: function(elt) {
10455 this.trackElement(elt); 10725 this.trackElement(elt);
10456 document.head.appendChild(elt); 10726 document.head.appendChild(elt);
10457 }, 10727 },
10458 // tracks when a loadable element has loaded 10728 // tracks when a loadable element has loaded
10459 trackElement: function(elt, callback) { 10729 trackElement: function(elt, callback) {
10460 var self = this; 10730 var self = this;
10461 var done = function(e) { 10731 var done = function(e) {
10462 if (callback) { 10732 if (callback) {
10463 callback(e); 10733 callback(e);
10464 } 10734 }
10465 self.markParsingComplete(elt); 10735 self.markParsingComplete(elt);
10736 self.parseNext();
10466 }; 10737 };
10467 elt.addEventListener('load', done); 10738 elt.addEventListener('load', done);
10468 elt.addEventListener('error', done); 10739 elt.addEventListener('error', done);
10469 10740
10470 // NOTE: IE does not fire "load" event for styles that have already loaded 10741 // NOTE: IE does not fire "load" event for styles that have already loaded
10471 // This is in violation of the spec, so we try our hardest to work around it 10742 // This is in violation of the spec, so we try our hardest to work around it
10472 if (isIe && elt.localName === 'style') { 10743 if (isIe && elt.localName === 'style') {
10473 var fakeLoad = false; 10744 var fakeLoad = false;
10474 // If there's not @import in the textContent, assume it has loaded 10745 // If there's not @import in the textContent, assume it has loaded
10475 if (elt.textContent.indexOf('@import') == -1) { 10746 if (elt.textContent.indexOf('@import') == -1) {
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
10927 Copyright 2013 The Polymer Authors. All rights reserved. 11198 Copyright 2013 The Polymer Authors. All rights reserved.
10928 Use of this source code is governed by a BSD-style 11199 Use of this source code is governed by a BSD-style
10929 license that can be found in the LICENSE file. 11200 license that can be found in the LICENSE file.
10930 */ 11201 */
10931 11202
10932 (function(scope){ 11203 (function(scope){
10933 11204
10934 var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE; 11205 var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
10935 var importSelector = 'link[rel=' + IMPORT_LINK_TYPE + ']'; 11206 var importSelector = 'link[rel=' + IMPORT_LINK_TYPE + ']';
10936 var importer = scope.importer; 11207 var importer = scope.importer;
11208 var parser = scope.parser;
10937 11209
10938 // we track mutations for addedNodes, looking for imports 11210 // we track mutations for addedNodes, looking for imports
10939 function handler(mutations) { 11211 function handler(mutations) {
10940 for (var i=0, l=mutations.length, m; (i<l) && (m=mutations[i]); i++) { 11212 for (var i=0, l=mutations.length, m; (i<l) && (m=mutations[i]); i++) {
10941 if (m.type === 'childList' && m.addedNodes.length) { 11213 if (m.type === 'childList' && m.addedNodes.length) {
10942 addedNodes(m.addedNodes); 11214 addedNodes(m.addedNodes);
10943 } 11215 }
10944 } 11216 }
10945 } 11217 }
10946 11218
10947 // find loadable elements and add them to the importer 11219 // find loadable elements and add them to the importer
10948 function addedNodes(nodes) { 11220 function addedNodes(nodes) {
11221 var owner;
10949 for (var i=0, l=nodes.length, n; (i<l) && (n=nodes[i]); i++) { 11222 for (var i=0, l=nodes.length, n; (i<l) && (n=nodes[i]); i++) {
11223 owner = owner || n.ownerDocument;
10950 if (shouldLoadNode(n)) { 11224 if (shouldLoadNode(n)) {
10951 importer.loadNode(n); 11225 importer.loadNode(n);
10952 } 11226 }
10953 if (n.children && n.children.length) { 11227 if (n.children && n.children.length) {
10954 addedNodes(n.children); 11228 addedNodes(n.children);
10955 } 11229 }
10956 } 11230 }
11231 // TODO(sorvell): This is not the right approach here. We shouldn't need to
11232 // invalidate parsing when an element is added. Disabling this code
11233 // until a better approach is found.
11234 /*
11235 if (owner) {
11236 parser.invalidateParse(owner);
11237 }
11238 */
10957 } 11239 }
10958 11240
10959 function shouldLoadNode(node) { 11241 function shouldLoadNode(node) {
10960 return (node.nodeType === 1) && matches.call(node, 11242 return (node.nodeType === 1) && matches.call(node,
10961 importer.loadSelectorsForNode(node)); 11243 importer.loadSelectorsForNode(node));
10962 } 11244 }
10963 11245
10964 // x-plat matches 11246 // x-plat matches
10965 var matches = HTMLElement.prototype.matches || 11247 var matches = HTMLElement.prototype.matches ||
10966 HTMLElement.prototype.matchesSelector || 11248 HTMLElement.prototype.matchesSelector ||
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
11411 // imports 11693 // imports
11412 11694
11413 if (!scope) { 11695 if (!scope) {
11414 scope = window.CustomElements = {flags:{}}; 11696 scope = window.CustomElements = {flags:{}};
11415 } 11697 }
11416 var flags = scope.flags; 11698 var flags = scope.flags;
11417 11699
11418 // native document.registerElement? 11700 // native document.registerElement?
11419 11701
11420 var hasNative = Boolean(document.registerElement); 11702 var hasNative = Boolean(document.registerElement);
11421 // TODO(sorvell): See https://github.com/Polymer/polymer/issues/399 11703 // For consistent timing, use native custom elements only when not polyfilling
11422 // we'll address this by defaulting to CE polyfill in the presence of the SD 11704 // other key related web components features.
11423 // polyfill. This will avoid spamming excess attached/detached callbacks. 11705 var useNative = !flags.register && hasNative && !window.ShadowDOMPolyfill && (!w indow.HTMLImports || HTMLImports.useNative);
11424 // If there is a compelling need to run CE native with SD polyfill,
11425 // we'll need to fix this issue.
11426 var useNative = !flags.register && hasNative && !window.ShadowDOMPolyfill;
11427 11706
11428 if (useNative) { 11707 if (useNative) {
11429 11708
11430 // stub 11709 // stub
11431 var nop = function() {}; 11710 var nop = function() {};
11432 11711
11433 // exports 11712 // exports
11434 scope.registry = {}; 11713 scope.registry = {};
11435 scope.upgradeElement = nop; 11714 scope.upgradeElement = nop;
11436 11715
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
11706 var removeAttribute = prototype.removeAttribute; 11985 var removeAttribute = prototype.removeAttribute;
11707 prototype.removeAttribute = function(name) { 11986 prototype.removeAttribute = function(name) {
11708 changeAttribute.call(this, name, null, removeAttribute); 11987 changeAttribute.call(this, name, null, removeAttribute);
11709 } 11988 }
11710 prototype.setAttribute._polyfilled = true; 11989 prototype.setAttribute._polyfilled = true;
11711 } 11990 }
11712 11991
11713 // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/ 11992 // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/
11714 // index.html#dfn-attribute-changed-callback 11993 // index.html#dfn-attribute-changed-callback
11715 function changeAttribute(name, value, operation) { 11994 function changeAttribute(name, value, operation) {
11995 name = name.toLowerCase();
11716 var oldValue = this.getAttribute(name); 11996 var oldValue = this.getAttribute(name);
11717 operation.apply(this, arguments); 11997 operation.apply(this, arguments);
11718 var newValue = this.getAttribute(name); 11998 var newValue = this.getAttribute(name);
11719 if (this.attributeChangedCallback 11999 if (this.attributeChangedCallback
11720 && (newValue !== oldValue)) { 12000 && (newValue !== oldValue)) {
11721 this.attributeChangedCallback(name, oldValue, newValue); 12001 this.attributeChangedCallback(name, oldValue, newValue);
11722 } 12002 }
11723 } 12003 }
11724 12004
11725 // element registry (maps tag names to definitions) 12005 // element registry (maps tag names to definitions)
(...skipping 1460 matching lines...) Expand 10 before | Expand all | Expand 10 after
13186 return { 13466 return {
13187 bindingMaps: {}, 13467 bindingMaps: {},
13188 raw: bindingDelegate, 13468 raw: bindingDelegate,
13189 prepareBinding: delegateFn('prepareBinding'), 13469 prepareBinding: delegateFn('prepareBinding'),
13190 prepareInstanceModel: delegateFn('prepareInstanceModel'), 13470 prepareInstanceModel: delegateFn('prepareInstanceModel'),
13191 prepareInstancePositionChanged: 13471 prepareInstancePositionChanged:
13192 delegateFn('prepareInstancePositionChanged') 13472 delegateFn('prepareInstancePositionChanged')
13193 }; 13473 };
13194 }, 13474 },
13195 13475
13196 // TODO(rafaelw): Assigning .bindingDelegate always succeeds. It may
13197 // make sense to issue a warning or even throw if the template is already
13198 // "activated", since this would be a strange thing to do.
13199 set bindingDelegate(bindingDelegate) { 13476 set bindingDelegate(bindingDelegate) {
13200 if (this.delegate_) { 13477 if (this.delegate_) {
13201 throw Error('Template must be cleared before a new bindingDelegate ' + 13478 throw Error('Template must be cleared before a new bindingDelegate ' +
13202 'can be assigned'); 13479 'can be assigned');
13203 } 13480 }
13204 13481
13205 this.setDelegate_(this.newDelegate_(bindingDelegate)); 13482 this.setDelegate_(this.newDelegate_(bindingDelegate));
13206 }, 13483 },
13207 13484
13208 get ref_() { 13485 get ref_() {
(...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after
13879 } 14156 }
13880 } 14157 }
13881 14158
13882 // exports 14159 // exports
13883 scope.flush = flush; 14160 scope.flush = flush;
13884 14161
13885 })(window.Platform); 14162 })(window.Platform);
13886 14163
13887 14164
13888 //# sourceMappingURL=platform.concat.js.map 14165 //# sourceMappingURL=platform.concat.js.map
OLDNEW
« no previous file with comments | « pkg/web_components/lib/platform.js ('k') | pkg/web_components/lib/platform.concat.js.map » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698