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

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

Issue 182193002: [polymer] interop with polymer-element and polymer.js (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 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 2012 The Polymer Authors. All rights reserved. 2 * Copyright 2012 The Polymer Authors. All rights reserved.
3 * Use of this source code is governed by a BSD-style 3 * Use of this source code is governed by a BSD-style
4 * license that can be found in the LICENSE file. 4 * license that can be found in the LICENSE file.
5 */ 5 */
6 6
7 if (typeof WeakMap === 'undefined') { 7 if (typeof WeakMap === 'undefined') {
8 (function() { 8 (function() {
9 var defineProperty = Object.defineProperty; 9 var defineProperty = Object.defineProperty;
10 var counter = Date.now() % 1e9; 10 var counter = Date.now() % 1e9;
(...skipping 476 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 objects.push(obj); 487 objects.push(obj);
488 } else if (objects.indexOf(obj) < 0) { 488 } else if (objects.indexOf(obj) < 0) {
489 objects.push(obj); 489 objects.push(obj);
490 Object.observe(obj, callback); 490 Object.observe(obj, callback);
491 } 491 }
492 492
493 observe(Object.getPrototypeOf(obj)); 493 observe(Object.getPrototypeOf(obj));
494 } 494 }
495 495
496 function reset() { 496 function reset() {
497 resetScheduled = false;
498 if (!resetNeeded)
499 return;
500
501 var objs = toRemove === emptyArray ? [] : toRemove; 497 var objs = toRemove === emptyArray ? [] : toRemove;
502 toRemove = objects; 498 toRemove = objects;
503 objects = objs; 499 objects = objs;
504 500
505 var observer; 501 var observer;
506 for (var id in observers) { 502 for (var id in observers) {
507 observer = observers[id]; 503 observer = observers[id];
508 if (!observer || observer.state_ != OPENED) 504 if (!observer || observer.state_ != OPENED)
509 continue; 505 continue;
510 506
511 observer.iterateObjects_(observe); 507 observer.iterateObjects_(observe);
512 } 508 }
513 509
514 for (var i = 0; i < toRemove.length; i++) { 510 for (var i = 0; i < toRemove.length; i++) {
515 var obj = toRemove[i]; 511 var obj = toRemove[i];
516 if (obj) 512 if (obj)
517 Object.unobserve(obj, callback); 513 Object.unobserve(obj, callback);
518 } 514 }
519 515
520 toRemove.length = 0; 516 toRemove.length = 0;
521 } 517 }
522 518
519 function scheduledReset() {
520 resetScheduled = false;
521 if (!resetNeeded)
522 return;
523
524 reset();
525 }
526
523 function scheduleReset() { 527 function scheduleReset() {
524 if (resetScheduled) 528 if (resetScheduled)
525 return; 529 return;
526 530
527 resetNeeded = true; 531 resetNeeded = true;
528 resetScheduled = true; 532 resetScheduled = true;
529 runEOM(reset); 533 runEOM(scheduledReset);
530 } 534 }
531 535
532 function callback() { 536 function callback() {
537 reset();
538
533 var observer; 539 var observer;
534 540
535 for (var id in observers) { 541 for (var id in observers) {
536 observer = observers[id]; 542 observer = observers[id];
537 if (!observer || observer.state_ != OPENED) 543 if (!observer || observer.state_ != OPENED)
538 continue; 544 continue;
539 545
540 observer.check_(); 546 observer.check_();
541 } 547 }
542
543 scheduleReset();
544 } 548 }
545 549
546 var record = { 550 var record = {
547 object: undefined, 551 object: undefined,
548 objects: objects, 552 objects: objects,
549 open: function(obs) { 553 open: function(obs) {
550 observers[obs.id_] = obs; 554 observers[obs.id_] = obs;
551 observerCount++; 555 observerCount++;
552 obs.iterateObjects_(observe); 556 obs.iterateObjects_(observe);
553 }, 557 },
(...skipping 1360 matching lines...) Expand 10 before | Expand all | Expand 10 after
1914 1918
1915 addForwardingProperties(nativePrototype, wrapperPrototype); 1919 addForwardingProperties(nativePrototype, wrapperPrototype);
1916 if (opt_instance) 1920 if (opt_instance)
1917 registerInstanceProperties(wrapperPrototype, opt_instance); 1921 registerInstanceProperties(wrapperPrototype, opt_instance);
1918 defineProperty(wrapperPrototype, 'constructor', { 1922 defineProperty(wrapperPrototype, 'constructor', {
1919 value: wrapperConstructor, 1923 value: wrapperConstructor,
1920 configurable: true, 1924 configurable: true,
1921 enumerable: false, 1925 enumerable: false,
1922 writable: true 1926 writable: true
1923 }); 1927 });
1928 // Set it again. Some VMs optimizes objects that are used as prototypes.
1929 wrapperConstructor.prototype = wrapperPrototype;
1924 } 1930 }
1925 1931
1926 function isWrapperFor(wrapperConstructor, nativeConstructor) { 1932 function isWrapperFor(wrapperConstructor, nativeConstructor) {
1927 return constructorTable.get(nativeConstructor.prototype) === 1933 return constructorTable.get(nativeConstructor.prototype) ===
1928 wrapperConstructor; 1934 wrapperConstructor;
1929 } 1935 }
1930 1936
1931 /** 1937 /**
1932 * Creates a generic wrapper constructor based on |object| and its 1938 * Creates a generic wrapper constructor based on |object| and its
1933 * constructor. 1939 * constructor.
1934 * @param {Node} object 1940 * @param {Node} object
1935 * @return {Function} The generated constructor. 1941 * @return {Function} The generated constructor.
1936 */ 1942 */
1937 function registerObject(object) { 1943 function registerObject(object) {
1938 var nativePrototype = Object.getPrototypeOf(object); 1944 var nativePrototype = Object.getPrototypeOf(object);
1939 1945
1940 var superWrapperConstructor = getWrapperConstructor(nativePrototype); 1946 var superWrapperConstructor = getWrapperConstructor(nativePrototype);
1941 var GeneratedWrapper = createWrapperConstructor(superWrapperConstructor); 1947 var GeneratedWrapper = createWrapperConstructor(superWrapperConstructor);
1942 registerInternal(nativePrototype, GeneratedWrapper, object); 1948 registerInternal(nativePrototype, GeneratedWrapper, object);
1943 1949
1944 return GeneratedWrapper; 1950 return GeneratedWrapper;
1945 } 1951 }
1946 1952
1947 function createWrapperConstructor(superWrapperConstructor) { 1953 function createWrapperConstructor(superWrapperConstructor) {
1948 function GeneratedWrapper(node) { 1954 function GeneratedWrapper(node) {
1949 superWrapperConstructor.call(this, node); 1955 superWrapperConstructor.call(this, node);
1950 } 1956 }
1951 GeneratedWrapper.prototype = 1957 var p = Object.create(superWrapperConstructor.prototype);
1952 Object.create(superWrapperConstructor.prototype); 1958 p.constructor = GeneratedWrapper;
1953 GeneratedWrapper.prototype.constructor = GeneratedWrapper; 1959 GeneratedWrapper.prototype = p;
1954 1960
1955 return GeneratedWrapper; 1961 return GeneratedWrapper;
1956 } 1962 }
1957 1963
1958 var OriginalDOMImplementation = window.DOMImplementation; 1964 var OriginalDOMImplementation = window.DOMImplementation;
1959 var OriginalEventTarget = window.EventTarget; 1965 var OriginalEventTarget = window.EventTarget;
1960 var OriginalEvent = window.Event; 1966 var OriginalEvent = window.Event;
1961 var OriginalNode = window.Node; 1967 var OriginalNode = window.Node;
1962 var OriginalWindow = window.Window; 1968 var OriginalWindow = window.Window;
1963 var OriginalRange = window.Range; 1969 var OriginalRange = window.Range;
(...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after
2517 } 2523 }
2518 }; 2524 };
2519 2525
2520 scope.enqueueMutation = enqueueMutation; 2526 scope.enqueueMutation = enqueueMutation;
2521 scope.registerTransientObservers = registerTransientObservers; 2527 scope.registerTransientObservers = registerTransientObservers;
2522 scope.wrappers.MutationObserver = MutationObserver; 2528 scope.wrappers.MutationObserver = MutationObserver;
2523 scope.wrappers.MutationRecord = MutationRecord; 2529 scope.wrappers.MutationRecord = MutationRecord;
2524 2530
2525 })(window.ShadowDOMPolyfill); 2531 })(window.ShadowDOMPolyfill);
2526 2532
2533 /**
2534 * Copyright 2014 The Polymer Authors. All rights reserved.
2535 * Use of this source code is goverened by a BSD-style
2536 * license that can be found in the LICENSE file.
2537 */
2538
2539 (function(scope) {
2540 'use strict';
2541
2542 /**
2543 * A tree scope represents the root of a tree. All nodes in a tree point to
2544 * the same TreeScope object. The tree scope of a node get set the first time
2545 * it is accessed or when a node is added or remove to a tree.
2546 * @constructor
2547 */
2548 function TreeScope(root, parent) {
2549 this.root = root;
2550 this.parent = parent;
2551 }
2552
2553 TreeScope.prototype = {
2554 get renderer() {
2555 if (this.root instanceof scope.wrappers.ShadowRoot) {
2556 return scope.getRendererForHost(this.root.host);
2557 }
2558 return null;
2559 },
2560
2561 contains: function(treeScope) {
2562 for (; treeScope; treeScope = treeScope.parent) {
2563 if (treeScope === this)
2564 return true;
2565 }
2566 return false;
2567 }
2568 };
2569
2570 function setTreeScope(node, treeScope) {
2571 if (node.treeScope_ !== treeScope) {
2572 node.treeScope_ = treeScope;
2573 for (var child = node.firstChild; child; child = child.nextSibling) {
2574 setTreeScope(child, treeScope);
2575 }
2576 }
2577 }
2578
2579 function getTreeScope(node) {
2580 if (node.treeScope_)
2581 return node.treeScope_;
2582 var parent = node.parentNode;
2583 var treeScope;
2584 if (parent)
2585 treeScope = getTreeScope(parent);
2586 else
2587 treeScope = new TreeScope(node, null);
2588 return node.treeScope_ = treeScope;
2589 }
2590
2591 scope.TreeScope = TreeScope;
2592 scope.getTreeScope = getTreeScope;
2593 scope.setTreeScope = setTreeScope;
2594
2595 })(window.ShadowDOMPolyfill);
2596
2527 // Copyright 2013 The Polymer Authors. All rights reserved. 2597 // Copyright 2013 The Polymer Authors. All rights reserved.
2528 // Use of this source code is goverened by a BSD-style 2598 // Use of this source code is goverened by a BSD-style
2529 // license that can be found in the LICENSE file. 2599 // license that can be found in the LICENSE file.
2530 2600
2531 (function(scope) { 2601 (function(scope) {
2532 'use strict'; 2602 'use strict';
2533 2603
2534 var forwardMethodsToWrapper = scope.forwardMethodsToWrapper; 2604 var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
2605 var getTreeScope = scope.getTreeScope;
2535 var mixin = scope.mixin; 2606 var mixin = scope.mixin;
2536 var registerWrapper = scope.registerWrapper; 2607 var registerWrapper = scope.registerWrapper;
2537 var unwrap = scope.unwrap; 2608 var unwrap = scope.unwrap;
2538 var wrap = scope.wrap; 2609 var wrap = scope.wrap;
2539 var wrappers = scope.wrappers; 2610 var wrappers = scope.wrappers;
2540 2611
2541 var wrappedFuns = new WeakMap(); 2612 var wrappedFuns = new WeakMap();
2542 var listenersTable = new WeakMap(); 2613 var listenersTable = new WeakMap();
2543 var handledEventsTable = new WeakMap(); 2614 var handledEventsTable = new WeakMap();
2544 var currentlyDispatchingEvents = new WeakMap(); 2615 var currentlyDispatchingEvents = new WeakMap();
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
2679 } 2750 }
2680 2751
2681 function getInsertionParent(node) { 2752 function getInsertionParent(node) {
2682 return scope.insertionParentTable.get(node); 2753 return scope.insertionParentTable.get(node);
2683 } 2754 }
2684 2755
2685 function isDistributed(node) { 2756 function isDistributed(node) {
2686 return getInsertionParent(node); 2757 return getInsertionParent(node);
2687 } 2758 }
2688 2759
2689 function rootOfNode(node) { 2760 function inSameTree(a, b) {
2690 var p; 2761 return getTreeScope(a) === getTreeScope(b);
2691 while (p = node.parentNode) {
2692 node = p;
2693 }
2694 return node;
2695 } 2762 }
2696 2763
2697 function inSameTree(a, b) {
2698 return rootOfNode(a) === rootOfNode(b);
2699 }
2700
2701 function enclosedBy(a, b) {
2702 if (a === b)
2703 return true;
2704 if (a instanceof wrappers.ShadowRoot)
2705 return enclosedBy(rootOfNode(a.host), b);
2706 return false;
2707 }
2708
2709
2710 function dispatchOriginalEvent(originalEvent) { 2764 function dispatchOriginalEvent(originalEvent) {
2711 // Make sure this event is only dispatched once. 2765 // Make sure this event is only dispatched once.
2712 if (handledEventsTable.get(originalEvent)) 2766 if (handledEventsTable.get(originalEvent))
2713 return; 2767 return;
2714 handledEventsTable.set(originalEvent, true); 2768 handledEventsTable.set(originalEvent, true);
2715 2769
2716 return dispatchEvent(wrap(originalEvent), wrap(originalEvent.target)); 2770 return dispatchEvent(wrap(originalEvent), wrap(originalEvent.target));
2717 } 2771 }
2718 2772
2719 function dispatchEvent(event, originalWrapperTarget) { 2773 function dispatchEvent(event, originalWrapperTarget) {
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
2914 }, 2968 },
2915 get eventPhase() { 2969 get eventPhase() {
2916 return eventPhaseTable.get(this); 2970 return eventPhaseTable.get(this);
2917 }, 2971 },
2918 get path() { 2972 get path() {
2919 var nodeList = new wrappers.NodeList(); 2973 var nodeList = new wrappers.NodeList();
2920 var eventPath = eventPathTable.get(this); 2974 var eventPath = eventPathTable.get(this);
2921 if (eventPath) { 2975 if (eventPath) {
2922 var index = 0; 2976 var index = 0;
2923 var lastIndex = eventPath.length - 1; 2977 var lastIndex = eventPath.length - 1;
2924 var baseRoot = rootOfNode(currentTargetTable.get(this)); 2978 var baseRoot = getTreeScope(currentTargetTable.get(this));
2925 2979
2926 for (var i = 0; i <= lastIndex; i++) { 2980 for (var i = 0; i <= lastIndex; i++) {
2927 var currentTarget = eventPath[i].currentTarget; 2981 var currentTarget = eventPath[i].currentTarget;
2928 var currentRoot = rootOfNode(currentTarget); 2982 var currentRoot = getTreeScope(currentTarget);
2929 if (enclosedBy(baseRoot, currentRoot) && 2983 if (currentRoot.contains(baseRoot) &&
2930 // Make sure we do not add Window to the path. 2984 // Make sure we do not add Window to the path.
2931 (i !== lastIndex || currentTarget instanceof wrappers.Node)) { 2985 (i !== lastIndex || currentTarget instanceof wrappers.Node)) {
2932 nodeList[index++] = currentTarget; 2986 nodeList[index++] = currentTarget;
2933 } 2987 }
2934 } 2988 }
2935 nodeList.length = index; 2989 nodeList.length = index;
2936 } 2990 }
2937 return nodeList; 2991 return nodeList;
2938 }, 2992 },
2939 stopPropagation: function() { 2993 stopPropagation: function() {
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
3387 (function(scope) { 3441 (function(scope) {
3388 'use strict'; 3442 'use strict';
3389 3443
3390 // TODO(arv): Implement. 3444 // TODO(arv): Implement.
3391 3445
3392 scope.wrapHTMLCollection = scope.wrapNodeList; 3446 scope.wrapHTMLCollection = scope.wrapNodeList;
3393 scope.wrappers.HTMLCollection = scope.wrappers.NodeList; 3447 scope.wrappers.HTMLCollection = scope.wrappers.NodeList;
3394 3448
3395 })(window.ShadowDOMPolyfill); 3449 })(window.ShadowDOMPolyfill);
3396 3450
3397 // Copyright 2012 The Polymer Authors. All rights reserved. 3451 /**
3398 // Use of this source code is goverened by a BSD-style 3452 * Copyright 2012 The Polymer Authors. All rights reserved.
3399 // license that can be found in the LICENSE file. 3453 * Use of this source code is goverened by a BSD-style
3454 * license that can be found in the LICENSE file.
3455 */
3400 3456
3401 (function(scope) { 3457 (function(scope) {
3402 'use strict'; 3458 'use strict';
3403 3459
3404 var EventTarget = scope.wrappers.EventTarget; 3460 var EventTarget = scope.wrappers.EventTarget;
3405 var NodeList = scope.wrappers.NodeList; 3461 var NodeList = scope.wrappers.NodeList;
3462 var TreeScope = scope.TreeScope;
3406 var assert = scope.assert; 3463 var assert = scope.assert;
3407 var defineWrapGetter = scope.defineWrapGetter; 3464 var defineWrapGetter = scope.defineWrapGetter;
3408 var enqueueMutation = scope.enqueueMutation; 3465 var enqueueMutation = scope.enqueueMutation;
3466 var getTreeScope = scope.getTreeScope;
3409 var isWrapper = scope.isWrapper; 3467 var isWrapper = scope.isWrapper;
3410 var mixin = scope.mixin; 3468 var mixin = scope.mixin;
3411 var registerTransientObservers = scope.registerTransientObservers; 3469 var registerTransientObservers = scope.registerTransientObservers;
3412 var registerWrapper = scope.registerWrapper; 3470 var registerWrapper = scope.registerWrapper;
3471 var setTreeScope = scope.setTreeScope;
3413 var unwrap = scope.unwrap; 3472 var unwrap = scope.unwrap;
3414 var wrap = scope.wrap; 3473 var wrap = scope.wrap;
3415 var wrapIfNeeded = scope.wrapIfNeeded; 3474 var wrapIfNeeded = scope.wrapIfNeeded;
3416 var wrappers = scope.wrappers; 3475 var wrappers = scope.wrappers;
3417 3476
3418 function assertIsNodeWrapper(node) { 3477 function assertIsNodeWrapper(node) {
3419 assert(node instanceof Node); 3478 assert(node instanceof Node);
3420 } 3479 }
3421 3480
3422 function createOneElementNodeList(node) { 3481 function createOneElementNodeList(node) {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
3519 enqueueRemovalForInsertedDocumentFragment(node, nodes); 3578 enqueueRemovalForInsertedDocumentFragment(node, nodes);
3520 return nodes; 3579 return nodes;
3521 } 3580 }
3522 3581
3523 function snapshotNodeList(nodeList) { 3582 function snapshotNodeList(nodeList) {
3524 // NodeLists are not live at the moment so just return the same object. 3583 // NodeLists are not live at the moment so just return the same object.
3525 return nodeList; 3584 return nodeList;
3526 } 3585 }
3527 3586
3528 // http://dom.spec.whatwg.org/#node-is-inserted 3587 // http://dom.spec.whatwg.org/#node-is-inserted
3529 function nodeWasAdded(node) { 3588 function nodeWasAdded(node, treeScope) {
3589 setTreeScope(node, treeScope);
3530 node.nodeIsInserted_(); 3590 node.nodeIsInserted_();
3531 } 3591 }
3532 3592
3533 function nodesWereAdded(nodes) { 3593 function nodesWereAdded(nodes, parent) {
3594 var treeScope = getTreeScope(parent);
3534 for (var i = 0; i < nodes.length; i++) { 3595 for (var i = 0; i < nodes.length; i++) {
3535 nodeWasAdded(nodes[i]); 3596 nodeWasAdded(nodes[i], treeScope);
3536 } 3597 }
3537 } 3598 }
3538 3599
3539 // http://dom.spec.whatwg.org/#node-is-removed 3600 // http://dom.spec.whatwg.org/#node-is-removed
3540 function nodeWasRemoved(node) { 3601 function nodeWasRemoved(node) {
3541 // Nothing at this point in time. 3602 setTreeScope(node, new TreeScope(node, null));
3542 } 3603 }
3543 3604
3544 function nodesWereRemoved(nodes) { 3605 function nodesWereRemoved(nodes) {
3545 // Nothing at this point in time. 3606 for (var i = 0; i < nodes.length; i++) {
3607 nodeWasRemoved(nodes[i]);
3608 }
3546 } 3609 }
3547 3610
3548 function ensureSameOwnerDocument(parent, child) { 3611 function ensureSameOwnerDocument(parent, child) {
3549 var ownerDoc = parent.nodeType === Node.DOCUMENT_NODE ? 3612 var ownerDoc = parent.nodeType === Node.DOCUMENT_NODE ?
3550 parent : parent.ownerDocument; 3613 parent : parent.ownerDocument;
3551 if (ownerDoc !== child.ownerDocument) 3614 if (ownerDoc !== child.ownerDocument)
3552 ownerDoc.adoptNode(child); 3615 ownerDoc.adoptNode(child);
3553 } 3616 }
3554 3617
3555 function adoptNodesIfNeeded(owner, nodes) { 3618 function adoptNodesIfNeeded(owner, nodes) {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
3653 child; 3716 child;
3654 child = child.nextSibling) { 3717 child = child.nextSibling) {
3655 cloneContent.appendChild(cloneNode(child, true, opt_doc)); 3718 cloneContent.appendChild(cloneNode(child, true, opt_doc));
3656 } 3719 }
3657 } 3720 }
3658 } 3721 }
3659 // TODO(arv): Some HTML elements also clone other data like value. 3722 // TODO(arv): Some HTML elements also clone other data like value.
3660 return clone; 3723 return clone;
3661 } 3724 }
3662 3725
3726 function contains(self, child) {
3727 if (!child || getTreeScope(self) !== getTreeScope(child))
3728 return false;
3729
3730 for (var node = child; node; node = node.parentNode) {
3731 if (node === self)
3732 return true;
3733 }
3734 return false;
3735 }
3736
3663 var OriginalNode = window.Node; 3737 var OriginalNode = window.Node;
3664 3738
3665 /** 3739 /**
3666 * This represents a wrapper of a native DOM node. 3740 * This represents a wrapper of a native DOM node.
3667 * @param {!Node} original The original DOM node, aka, the visual DOM node. 3741 * @param {!Node} original The original DOM node, aka, the visual DOM node.
3668 * @constructor 3742 * @constructor
3669 * @extends {EventTarget} 3743 * @extends {EventTarget}
3670 */ 3744 */
3671 function Node(original) { 3745 function Node(original) {
3672 assert(original instanceof OriginalNode); 3746 assert(original instanceof OriginalNode);
(...skipping 26 matching lines...) Expand all
3699 * @type {Node|undefined} 3773 * @type {Node|undefined}
3700 * @private 3774 * @private
3701 */ 3775 */
3702 this.nextSibling_ = undefined; 3776 this.nextSibling_ = undefined;
3703 3777
3704 /** 3778 /**
3705 * @type {Node|undefined} 3779 * @type {Node|undefined}
3706 * @private 3780 * @private
3707 */ 3781 */
3708 this.previousSibling_ = undefined; 3782 this.previousSibling_ = undefined;
3783
3784 this.treeScope_ = undefined;
3709 } 3785 }
3710 3786
3711 var OriginalDocumentFragment = window.DocumentFragment; 3787 var OriginalDocumentFragment = window.DocumentFragment;
3712 var originalAppendChild = OriginalNode.prototype.appendChild; 3788 var originalAppendChild = OriginalNode.prototype.appendChild;
3713 var originalCompareDocumentPosition = 3789 var originalCompareDocumentPosition =
3714 OriginalNode.prototype.compareDocumentPosition; 3790 OriginalNode.prototype.compareDocumentPosition;
3715 var originalInsertBefore = OriginalNode.prototype.insertBefore; 3791 var originalInsertBefore = OriginalNode.prototype.insertBefore;
3716 var originalRemoveChild = OriginalNode.prototype.removeChild; 3792 var originalRemoveChild = OriginalNode.prototype.removeChild;
3717 var originalReplaceChild = OriginalNode.prototype.replaceChild; 3793 var originalReplaceChild = OriginalNode.prototype.replaceChild;
3718 3794
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
3787 adoptNodesIfNeeded(this, nodes); 3863 adoptNodesIfNeeded(this, nodes);
3788 } 3864 }
3789 } 3865 }
3790 3866
3791 enqueueMutation(this, 'childList', { 3867 enqueueMutation(this, 'childList', {
3792 addedNodes: nodes, 3868 addedNodes: nodes,
3793 nextSibling: refWrapper, 3869 nextSibling: refWrapper,
3794 previousSibling: previousNode 3870 previousSibling: previousNode
3795 }); 3871 });
3796 3872
3797 nodesWereAdded(nodes); 3873 nodesWereAdded(nodes, this);
3798 3874
3799 return childWrapper; 3875 return childWrapper;
3800 }, 3876 },
3801 3877
3802 removeChild: function(childWrapper) { 3878 removeChild: function(childWrapper) {
3803 assertIsNodeWrapper(childWrapper); 3879 assertIsNodeWrapper(childWrapper);
3804 if (childWrapper.parentNode !== this) { 3880 if (childWrapper.parentNode !== this) {
3805 // IE has invalid DOM trees at times. 3881 // IE has invalid DOM trees at times.
3806 var found = false; 3882 var found = false;
3807 var childNodes = this.childNodes; 3883 var childNodes = this.childNodes;
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
3919 } 3995 }
3920 3996
3921 enqueueMutation(this, 'childList', { 3997 enqueueMutation(this, 'childList', {
3922 addedNodes: nodes, 3998 addedNodes: nodes,
3923 removedNodes: createOneElementNodeList(oldChildWrapper), 3999 removedNodes: createOneElementNodeList(oldChildWrapper),
3924 nextSibling: nextNode, 4000 nextSibling: nextNode,
3925 previousSibling: previousNode 4001 previousSibling: previousNode
3926 }); 4002 });
3927 4003
3928 nodeWasRemoved(oldChildWrapper); 4004 nodeWasRemoved(oldChildWrapper);
3929 nodesWereAdded(nodes); 4005 nodesWereAdded(nodes, this);
3930 4006
3931 return oldChildWrapper; 4007 return oldChildWrapper;
3932 }, 4008 },
3933 4009
3934 /** 4010 /**
3935 * Called after a node was inserted. Subclasses override this to invalidate 4011 * Called after a node was inserted. Subclasses override this to invalidate
3936 * the renderer as needed. 4012 * the renderer as needed.
3937 * @private 4013 * @private
3938 */ 4014 */
3939 nodeIsInserted_: function() { 4015 nodeIsInserted_: function() {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
4011 } 4087 }
4012 4088
4013 var addedNodes = snapshotNodeList(this.childNodes); 4089 var addedNodes = snapshotNodeList(this.childNodes);
4014 4090
4015 enqueueMutation(this, 'childList', { 4091 enqueueMutation(this, 'childList', {
4016 addedNodes: addedNodes, 4092 addedNodes: addedNodes,
4017 removedNodes: removedNodes 4093 removedNodes: removedNodes
4018 }); 4094 });
4019 4095
4020 nodesWereRemoved(removedNodes); 4096 nodesWereRemoved(removedNodes);
4021 nodesWereAdded(addedNodes); 4097 nodesWereAdded(addedNodes, this);
4022 }, 4098 },
4023 4099
4024 get childNodes() { 4100 get childNodes() {
4025 var wrapperList = new NodeList(); 4101 var wrapperList = new NodeList();
4026 var i = 0; 4102 var i = 0;
4027 for (var child = this.firstChild; child; child = child.nextSibling) { 4103 for (var child = this.firstChild; child; child = child.nextSibling) {
4028 wrapperList[i++] = child; 4104 wrapperList[i++] = child;
4029 } 4105 }
4030 wrapperList.length = i; 4106 wrapperList.length = i;
4031 return wrapperList; 4107 return wrapperList;
4032 }, 4108 },
4033 4109
4034 cloneNode: function(deep) { 4110 cloneNode: function(deep) {
4035 return cloneNode(this, deep); 4111 return cloneNode(this, deep);
4036 }, 4112 },
4037 4113
4038 contains: function(child) { 4114 contains: function(child) {
4039 if (!child) 4115 return contains(this, wrapIfNeeded(child));
4040 return false;
4041
4042 child = wrapIfNeeded(child);
4043
4044 // TODO(arv): Optimize using ownerDocument etc.
4045 if (child === this)
4046 return true;
4047 var parentNode = child.parentNode;
4048 if (!parentNode)
4049 return false;
4050 return this.contains(parentNode);
4051 }, 4116 },
4052 4117
4053 compareDocumentPosition: function(otherNode) { 4118 compareDocumentPosition: function(otherNode) {
4054 // This only wraps, it therefore only operates on the composed DOM and not 4119 // This only wraps, it therefore only operates on the composed DOM and not
4055 // the logical DOM. 4120 // the logical DOM.
4056 return originalCompareDocumentPosition.call(this.impl, unwrap(otherNode)); 4121 return originalCompareDocumentPosition.call(this.impl, unwrap(otherNode));
4057 }, 4122 },
4058 4123
4059 normalize: function() { 4124 normalize: function() {
4060 var nodes = snapshotNodeList(this.childNodes); 4125 var nodes = snapshotNodeList(this.childNodes);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
4097 defineWrapGetter(Node, 'ownerDocument'); 4162 defineWrapGetter(Node, 'ownerDocument');
4098 4163
4099 // We use a DocumentFragment as a base and then delete the properties of 4164 // We use a DocumentFragment as a base and then delete the properties of
4100 // DocumentFragment.prototype from the wrapper Node. Since delete makes 4165 // DocumentFragment.prototype from the wrapper Node. Since delete makes
4101 // objects slow in some JS engines we recreate the prototype object. 4166 // objects slow in some JS engines we recreate the prototype object.
4102 registerWrapper(OriginalNode, Node, document.createDocumentFragment()); 4167 registerWrapper(OriginalNode, Node, document.createDocumentFragment());
4103 delete Node.prototype.querySelector; 4168 delete Node.prototype.querySelector;
4104 delete Node.prototype.querySelectorAll; 4169 delete Node.prototype.querySelectorAll;
4105 Node.prototype = mixin(Object.create(EventTarget.prototype), Node.prototype); 4170 Node.prototype = mixin(Object.create(EventTarget.prototype), Node.prototype);
4106 4171
4172 scope.cloneNode = cloneNode;
4107 scope.nodeWasAdded = nodeWasAdded; 4173 scope.nodeWasAdded = nodeWasAdded;
4108 scope.nodeWasRemoved = nodeWasRemoved; 4174 scope.nodeWasRemoved = nodeWasRemoved;
4109 scope.nodesWereAdded = nodesWereAdded; 4175 scope.nodesWereAdded = nodesWereAdded;
4110 scope.nodesWereRemoved = nodesWereRemoved; 4176 scope.nodesWereRemoved = nodesWereRemoved;
4111 scope.snapshotNodeList = snapshotNodeList; 4177 scope.snapshotNodeList = snapshotNodeList;
4112 scope.wrappers.Node = Node; 4178 scope.wrappers.Node = Node;
4113 scope.cloneNode = cloneNode;
4114 4179
4115 })(window.ShadowDOMPolyfill); 4180 })(window.ShadowDOMPolyfill);
4116 4181
4117 // Copyright 2013 The Polymer Authors. All rights reserved. 4182 // Copyright 2013 The Polymer Authors. All rights reserved.
4118 // Use of this source code is governed by a BSD-style 4183 // Use of this source code is governed by a BSD-style
4119 // license that can be found in the LICENSE file. 4184 // license that can be found in the LICENSE file.
4120 4185
4121 (function(scope) { 4186 (function(scope) {
4122 'use strict'; 4187 'use strict';
4123 4188
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after
4675 } 4740 }
4676 4741
4677 var addedNodes = snapshotNodeList(this.childNodes); 4742 var addedNodes = snapshotNodeList(this.childNodes);
4678 4743
4679 enqueueMutation(this, 'childList', { 4744 enqueueMutation(this, 'childList', {
4680 addedNodes: addedNodes, 4745 addedNodes: addedNodes,
4681 removedNodes: removedNodes 4746 removedNodes: removedNodes
4682 }); 4747 });
4683 4748
4684 nodesWereRemoved(removedNodes); 4749 nodesWereRemoved(removedNodes);
4685 nodesWereAdded(addedNodes); 4750 nodesWereAdded(addedNodes, this);
4686 }, 4751 },
4687 4752
4688 get outerHTML() { 4753 get outerHTML() {
4689 return getOuterHTML(this, this.parentNode); 4754 return getOuterHTML(this, this.parentNode);
4690 }, 4755 },
4691 set outerHTML(value) { 4756 set outerHTML(value) {
4692 var p = this.parentNode; 4757 var p = this.parentNode;
4693 if (p) { 4758 if (p) {
4694 p.invalidateShadowRenderer(); 4759 p.invalidateShadowRenderer();
4695 var df = frag(p, value); 4760 var df = frag(p, value);
(...skipping 1020 matching lines...) Expand 10 before | Expand all | Expand 10 after
5716 })(window.ShadowDOMPolyfill); 5781 })(window.ShadowDOMPolyfill);
5717 5782
5718 // Copyright 2013 The Polymer Authors. All rights reserved. 5783 // Copyright 2013 The Polymer Authors. All rights reserved.
5719 // Use of this source code is goverened by a BSD-style 5784 // Use of this source code is goverened by a BSD-style
5720 // license that can be found in the LICENSE file. 5785 // license that can be found in the LICENSE file.
5721 5786
5722 (function(scope) { 5787 (function(scope) {
5723 'use strict'; 5788 'use strict';
5724 5789
5725 var DocumentFragment = scope.wrappers.DocumentFragment; 5790 var DocumentFragment = scope.wrappers.DocumentFragment;
5791 var TreeScope = scope.TreeScope;
5726 var elementFromPoint = scope.elementFromPoint; 5792 var elementFromPoint = scope.elementFromPoint;
5727 var getInnerHTML = scope.getInnerHTML; 5793 var getInnerHTML = scope.getInnerHTML;
5794 var getTreeScope = scope.getTreeScope;
5728 var mixin = scope.mixin; 5795 var mixin = scope.mixin;
5729 var rewrap = scope.rewrap; 5796 var rewrap = scope.rewrap;
5730 var setInnerHTML = scope.setInnerHTML; 5797 var setInnerHTML = scope.setInnerHTML;
5731 var unwrap = scope.unwrap; 5798 var unwrap = scope.unwrap;
5732 5799
5733 var shadowHostTable = new WeakMap(); 5800 var shadowHostTable = new WeakMap();
5734 var nextOlderShadowTreeTable = new WeakMap(); 5801 var nextOlderShadowTreeTable = new WeakMap();
5735 5802
5736 var spaceCharRe = /[ \t\n\r\f]/; 5803 var spaceCharRe = /[ \t\n\r\f]/;
5737 5804
5738 function ShadowRoot(hostWrapper) { 5805 function ShadowRoot(hostWrapper) {
5739 var node = unwrap(hostWrapper.impl.ownerDocument.createDocumentFragment()); 5806 var node = unwrap(hostWrapper.impl.ownerDocument.createDocumentFragment());
5740 DocumentFragment.call(this, node); 5807 DocumentFragment.call(this, node);
5741 5808
5742 // createDocumentFragment associates the node with a wrapper 5809 // createDocumentFragment associates the node with a wrapper
5743 // DocumentFragment instance. Override that. 5810 // DocumentFragment instance. Override that.
5744 rewrap(node, this); 5811 rewrap(node, this);
5745 5812
5813 this.treeScope_ = new TreeScope(this, getTreeScope(hostWrapper));
5814
5746 var oldShadowRoot = hostWrapper.shadowRoot; 5815 var oldShadowRoot = hostWrapper.shadowRoot;
5747 nextOlderShadowTreeTable.set(this, oldShadowRoot); 5816 nextOlderShadowTreeTable.set(this, oldShadowRoot);
5748 5817
5749 shadowHostTable.set(this, hostWrapper); 5818 shadowHostTable.set(this, hostWrapper);
5750 } 5819 }
5751 ShadowRoot.prototype = Object.create(DocumentFragment.prototype); 5820 ShadowRoot.prototype = Object.create(DocumentFragment.prototype);
5752 mixin(ShadowRoot.prototype, { 5821 mixin(ShadowRoot.prototype, {
5753 get innerHTML() { 5822 get innerHTML() {
5754 return getInnerHTML(this); 5823 return getInnerHTML(this);
5755 }, 5824 },
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
5791 5860
5792 (function(scope) { 5861 (function(scope) {
5793 'use strict'; 5862 'use strict';
5794 5863
5795 var Element = scope.wrappers.Element; 5864 var Element = scope.wrappers.Element;
5796 var HTMLContentElement = scope.wrappers.HTMLContentElement; 5865 var HTMLContentElement = scope.wrappers.HTMLContentElement;
5797 var HTMLShadowElement = scope.wrappers.HTMLShadowElement; 5866 var HTMLShadowElement = scope.wrappers.HTMLShadowElement;
5798 var Node = scope.wrappers.Node; 5867 var Node = scope.wrappers.Node;
5799 var ShadowRoot = scope.wrappers.ShadowRoot; 5868 var ShadowRoot = scope.wrappers.ShadowRoot;
5800 var assert = scope.assert; 5869 var assert = scope.assert;
5870 var getTreeScope = scope.getTreeScope;
5801 var mixin = scope.mixin; 5871 var mixin = scope.mixin;
5802 var oneOf = scope.oneOf; 5872 var oneOf = scope.oneOf;
5803 var unwrap = scope.unwrap; 5873 var unwrap = scope.unwrap;
5804 var wrap = scope.wrap; 5874 var wrap = scope.wrap;
5805 5875
5806 /** 5876 /**
5807 * Updates the fields of a wrapper to a snapshot of the logical DOM as needed. 5877 * Updates the fields of a wrapper to a snapshot of the logical DOM as needed.
5808 * Up means parentNode 5878 * Up means parentNode
5809 * Sideways means previous and next sibling. 5879 * Sideways means previous and next sibling.
5810 * @param {!Node} wrapper 5880 * @param {!Node} wrapper
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
6010 'setTimeout' 6080 'setTimeout'
6011 ]); 6081 ]);
6012 6082
6013 var pendingDirtyRenderers = []; 6083 var pendingDirtyRenderers = [];
6014 var renderTimer; 6084 var renderTimer;
6015 6085
6016 function renderAllPending() { 6086 function renderAllPending() {
6017 // TODO(arv): Order these in document order. That way we do not have to 6087 // TODO(arv): Order these in document order. That way we do not have to
6018 // render something twice. 6088 // render something twice.
6019 for (var i = 0; i < pendingDirtyRenderers.length; i++) { 6089 for (var i = 0; i < pendingDirtyRenderers.length; i++) {
6020 pendingDirtyRenderers[i].render(); 6090 var renderer = pendingDirtyRenderers[i];
6091 var parentRenderer = renderer.parentRenderer;
6092 if (parentRenderer && parentRenderer.dirty)
6093 continue;
6094 renderer.render();
6021 } 6095 }
6022 6096
6023 pendingDirtyRenderers = []; 6097 pendingDirtyRenderers = [];
6024 } 6098 }
6025 6099
6026 function handleRequestAnimationFrame() { 6100 function handleRequestAnimationFrame() {
6027 renderTimer = null; 6101 renderTimer = null;
6028 renderAllPending(); 6102 renderAllPending();
6029 } 6103 }
6030 6104
6031 /** 6105 /**
6032 * Returns existing shadow renderer for a host or creates it if it is needed. 6106 * Returns existing shadow renderer for a host or creates it if it is needed.
6033 * @params {!Element} host 6107 * @params {!Element} host
6034 * @return {!ShadowRenderer} 6108 * @return {!ShadowRenderer}
6035 */ 6109 */
6036 function getRendererForHost(host) { 6110 function getRendererForHost(host) {
6037 var renderer = rendererForHostTable.get(host); 6111 var renderer = rendererForHostTable.get(host);
6038 if (!renderer) { 6112 if (!renderer) {
6039 renderer = new ShadowRenderer(host); 6113 renderer = new ShadowRenderer(host);
6040 rendererForHostTable.set(host, renderer); 6114 rendererForHostTable.set(host, renderer);
6041 } 6115 }
6042 return renderer; 6116 return renderer;
6043 } 6117 }
6044 6118
6045 function getShadowRootAncestor(node) { 6119 function getShadowRootAncestor(node) {
6046 for (; node; node = node.parentNode) { 6120 var root = getTreeScope(node).root;
6047 if (node instanceof ShadowRoot) 6121 if (root instanceof ShadowRoot)
6048 return node; 6122 return root;
6049 }
6050 return null; 6123 return null;
6051 } 6124 }
6052 6125
6053 function getRendererForShadowRoot(shadowRoot) { 6126 function getRendererForShadowRoot(shadowRoot) {
6054 return getRendererForHost(shadowRoot.host); 6127 return getRendererForHost(shadowRoot.host);
6055 } 6128 }
6056 6129
6057 var spliceDiff = new ArraySplice(); 6130 var spliceDiff = new ArraySplice();
6058 spliceDiff.equals = function(renderNode, rawNode) { 6131 spliceDiff.equals = function(renderNode, rawNode) {
6059 return unwrap(renderNode.node) === rawNode; 6132 return unwrap(renderNode.node) === rawNode;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
6156 for (var node = shadowRoot.firstChild; node; node = node.nextSibling) { 6229 for (var node = shadowRoot.firstChild; node; node = node.nextSibling) {
6157 this.renderNode(shadowRoot, renderNode, node, false); 6230 this.renderNode(shadowRoot, renderNode, node, false);
6158 } 6231 }
6159 6232
6160 if (topMostRenderer) 6233 if (topMostRenderer)
6161 renderNode.sync(); 6234 renderNode.sync();
6162 6235
6163 this.dirty = false; 6236 this.dirty = false;
6164 }, 6237 },
6165 6238
6239 get parentRenderer() {
6240 return getTreeScope(this.host).renderer;
6241 },
6242
6166 invalidate: function() { 6243 invalidate: function() {
6167 if (!this.dirty) { 6244 if (!this.dirty) {
6168 this.dirty = true; 6245 this.dirty = true;
6169 pendingDirtyRenderers.push(this); 6246 pendingDirtyRenderers.push(this);
6170 if (renderTimer) 6247 if (renderTimer)
6171 return; 6248 return;
6172 renderTimer = window[request](handleRequestAnimationFrame, 0); 6249 renderTimer = window[request](handleRequestAnimationFrame, 0);
6173 } 6250 }
6174 }, 6251 },
6175 6252
(...skipping 10 matching lines...) Expand all
6186 } else { 6263 } else {
6187 this.renderAsAnyDomTree(shadowRoot, renderNode, node, isNested); 6264 this.renderAsAnyDomTree(shadowRoot, renderNode, node, isNested);
6188 } 6265 }
6189 }, 6266 },
6190 6267
6191 renderAsAnyDomTree: function(shadowRoot, renderNode, node, isNested) { 6268 renderAsAnyDomTree: function(shadowRoot, renderNode, node, isNested) {
6192 renderNode = renderNode.append(node); 6269 renderNode = renderNode.append(node);
6193 6270
6194 if (isShadowHost(node)) { 6271 if (isShadowHost(node)) {
6195 var renderer = getRendererForHost(node); 6272 var renderer = getRendererForHost(node);
6196 // renderNode.skip = !renderer.dirty; 6273 renderNode.skip = !renderer.dirty;
6197 renderer.invalidate();
6198 renderer.render(renderNode); 6274 renderer.render(renderNode);
6199 } else { 6275 } else {
6200 for (var child = node.firstChild; child; child = child.nextSibling) { 6276 for (var child = node.firstChild; child; child = child.nextSibling) {
6201 this.renderNode(shadowRoot, renderNode, child, isNested); 6277 this.renderNode(shadowRoot, renderNode, child, isNested);
6202 } 6278 }
6203 } 6279 }
6204 }, 6280 },
6205 6281
6206 renderInsertionPoint: function(shadowRoot, renderNode, insertionPoint, 6282 renderInsertionPoint: function(shadowRoot, renderNode, insertionPoint,
6207 isNested) { 6283 isNested) {
(...skipping 378 matching lines...) Expand 10 before | Expand all | Expand 10 after
6586 6662
6587 (function(scope) { 6663 (function(scope) {
6588 'use strict'; 6664 'use strict';
6589 6665
6590 var GetElementsByInterface = scope.GetElementsByInterface; 6666 var GetElementsByInterface = scope.GetElementsByInterface;
6591 var Node = scope.wrappers.Node; 6667 var Node = scope.wrappers.Node;
6592 var ParentNodeInterface = scope.ParentNodeInterface; 6668 var ParentNodeInterface = scope.ParentNodeInterface;
6593 var Selection = scope.wrappers.Selection; 6669 var Selection = scope.wrappers.Selection;
6594 var SelectorsInterface = scope.SelectorsInterface; 6670 var SelectorsInterface = scope.SelectorsInterface;
6595 var ShadowRoot = scope.wrappers.ShadowRoot; 6671 var ShadowRoot = scope.wrappers.ShadowRoot;
6672 var TreeScope = scope.TreeScope;
6596 var cloneNode = scope.cloneNode; 6673 var cloneNode = scope.cloneNode;
6597 var defineWrapGetter = scope.defineWrapGetter; 6674 var defineWrapGetter = scope.defineWrapGetter;
6598 var elementFromPoint = scope.elementFromPoint; 6675 var elementFromPoint = scope.elementFromPoint;
6599 var forwardMethodsToWrapper = scope.forwardMethodsToWrapper; 6676 var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
6600 var matchesNames = scope.matchesNames; 6677 var matchesNames = scope.matchesNames;
6601 var mixin = scope.mixin; 6678 var mixin = scope.mixin;
6602 var registerWrapper = scope.registerWrapper; 6679 var registerWrapper = scope.registerWrapper;
6603 var renderAllPending = scope.renderAllPending; 6680 var renderAllPending = scope.renderAllPending;
6604 var rewrap = scope.rewrap; 6681 var rewrap = scope.rewrap;
6605 var unwrap = scope.unwrap; 6682 var unwrap = scope.unwrap;
6606 var wrap = scope.wrap; 6683 var wrap = scope.wrap;
6607 var wrapEventTargetMethods = scope.wrapEventTargetMethods; 6684 var wrapEventTargetMethods = scope.wrapEventTargetMethods;
6608 var wrapNodeList = scope.wrapNodeList; 6685 var wrapNodeList = scope.wrapNodeList;
6609 6686
6610 var implementationTable = new WeakMap(); 6687 var implementationTable = new WeakMap();
6611 6688
6612 function Document(node) { 6689 function Document(node) {
6613 Node.call(this, node); 6690 Node.call(this, node);
6691 this.treeScope_ = new TreeScope(this, null);
6614 } 6692 }
6615 Document.prototype = Object.create(Node.prototype); 6693 Document.prototype = Object.create(Node.prototype);
6616 6694
6617 defineWrapGetter(Document, 'documentElement'); 6695 defineWrapGetter(Document, 'documentElement');
6618 6696
6619 // Conceptually both body and head can be in a shadow but suporting that seems 6697 // Conceptually both body and head can be in a shadow but suporting that seems
6620 // overkill at this point. 6698 // overkill at this point.
6621 defineWrapGetter(Document, 'body'); 6699 defineWrapGetter(Document, 'body');
6622 defineWrapGetter(Document, 'head'); 6700 defineWrapGetter(Document, 'head');
6623 6701
(...skipping 607 matching lines...) Expand 10 before | Expand all | Expand 10 after
7231 (function(scope) { 7309 (function(scope) {
7232 7310
7233 var ShadowCSS = { 7311 var ShadowCSS = {
7234 strictStyling: false, 7312 strictStyling: false,
7235 registry: {}, 7313 registry: {},
7236 // Shim styles for a given root associated with a name and extendsName 7314 // Shim styles for a given root associated with a name and extendsName
7237 // 1. cache root styles by name 7315 // 1. cache root styles by name
7238 // 2. optionally tag root nodes with scope name 7316 // 2. optionally tag root nodes with scope name
7239 // 3. shim polyfill directives /* @polyfill */ and /* @polyfill-rule */ 7317 // 3. shim polyfill directives /* @polyfill */ and /* @polyfill-rule */
7240 // 4. shim :host and scoping 7318 // 4. shim :host and scoping
7241 shimStyling: function(root, name, extendsName, ownSheet) { 7319 shimStyling: function(root, name, extendsName) {
7320 var scopeStyles = this.prepareRoot(root, name, extendsName);
7242 var typeExtension = this.isTypeExtension(extendsName); 7321 var typeExtension = this.isTypeExtension(extendsName);
7322 var scopeSelector = this.makeScopeSelector(name, typeExtension);
7243 // use caching to make working with styles nodes easier and to facilitate 7323 // use caching to make working with styles nodes easier and to facilitate
7244 // lookup of extendee 7324 // lookup of extendee
7245 var def = this.registerDefinition(root, name, extendsName); 7325 var cssText = stylesToCssText(scopeStyles, true);
7246 // find styles and apply shimming... 7326 cssText = this.scopeCssText(cssText, scopeSelector);
7327 // cache shimmed css on root for user extensibility
7328 if (root) {
7329 root.shimmedStyle = cssText;
7330 }
7331 // add style to document
7332 this.addCssToDocument(cssText, name);
7333 },
7334 /*
7335 * Shim a style element with the given selector. Returns cssText that can
7336 * be included in the document via Platform.ShadowCSS.addCssToDocument(css).
7337 */
7338 shimStyle: function(style, selector) {
7339 return this.shimCssText(style.textContent, selector);
7340 },
7341 /*
7342 * Shim some cssText with the given selector. Returns cssText that can
7343 * be included in the document via Platform.ShadowCSS.addCssToDocument(css).
7344 */
7345 shimCssText: function(cssText, selector) {
7346 cssText = this.insertDirectives(cssText);
7347 return this.scopeCssText(cssText, selector);
7348 },
7349 makeScopeSelector: function(name, typeExtension) {
7350 if (name) {
7351 return typeExtension ? '[is=' + name + ']' : name;
7352 }
7353 return '';
7354 },
7355 isTypeExtension: function(extendsName) {
7356 return extendsName && extendsName.indexOf('-') < 0;
7357 },
7358 prepareRoot: function(root, name, extendsName) {
7359 var def = this.registerRoot(root, name, extendsName);
7360 this.replaceTextInStyles(def.rootStyles, this.insertDirectives);
7361 // remove existing style elements
7362 this.removeStyles(root, def.rootStyles);
7363 // apply strict attr
7247 if (this.strictStyling) { 7364 if (this.strictStyling) {
7248 this.applyScopeToContent(root, name); 7365 this.applyScopeToContent(root, name);
7249 } 7366 }
7250 var cssText = this.stylesToShimmedCssText(def.rootStyles, def.scopeStyles, 7367 return def.scopeStyles;
7251 name, typeExtension); 7368 },
7252 // provide shimmedStyle for user extensibility 7369 removeStyles: function(root, styles) {
7253 def.shimmedStyle = cssTextToStyle(cssText); 7370 for (var i=0, l=styles.length, s; (i<l) && (s=styles[i]); i++) {
7254 if (root) {
7255 root.shimmedStyle = def.shimmedStyle;
7256 }
7257 // remove existing style elements
7258 for (var i=0, l=def.rootStyles.length, s; (i<l) && (s=def.rootStyles[i]);
7259 i++) {
7260 s.parentNode.removeChild(s); 7371 s.parentNode.removeChild(s);
7261 } 7372 }
7262 // add style to document
7263 if (ownSheet) {
7264 addOwnSheet(cssText, name);
7265 } else {
7266 addCssToDocument(cssText);
7267 }
7268 }, 7373 },
7269 // apply @polyfill rules + :host and scope shimming 7374 registerRoot: function(root, name, extendsName) {
7270 stylesToShimmedCssText: function(rootStyles, scopeStyles, name,
7271 typeExtension) {
7272 name = name || '';
7273 // insert @polyfill and @polyfill-rule rules into style elements
7274 // scoping process takes care of shimming these
7275 this.insertPolyfillDirectives(rootStyles);
7276 this.insertPolyfillRules(rootStyles);
7277 var cssText = this.shimScoping(scopeStyles, name, typeExtension);
7278 // note: we only need to do rootStyles since these are unscoped.
7279 cssText += this.extractPolyfillUnscopedRules(rootStyles);
7280 return cssText.trim();
7281 },
7282 registerDefinition: function(root, name, extendsName) {
7283 var def = this.registry[name] = { 7375 var def = this.registry[name] = {
7284 root: root, 7376 root: root,
7285 name: name, 7377 name: name,
7286 extendsName: extendsName 7378 extendsName: extendsName
7287 } 7379 }
7288 var styles = root ? root.querySelectorAll('style') : []; 7380 var styles = this.findStyles(root);
7289 styles = styles ? Array.prototype.slice.call(styles, 0) : [];
7290 def.rootStyles = styles; 7381 def.rootStyles = styles;
7291 def.scopeStyles = def.rootStyles; 7382 def.scopeStyles = def.rootStyles;
7292 var extendee = this.registry[def.extendsName]; 7383 var extendee = this.registry[def.extendsName];
7293 if (extendee && (!root || root.querySelector('shadow'))) { 7384 if (extendee && (!root || root.querySelector('shadow'))) {
7294 def.scopeStyles = extendee.scopeStyles.concat(def.scopeStyles); 7385 def.scopeStyles = extendee.scopeStyles.concat(def.scopeStyles);
7295 } 7386 }
7296 return def; 7387 return def;
7297 }, 7388 },
7298 isTypeExtension: function(extendsName) { 7389 findStyles: function(root) {
7299 return extendsName && extendsName.indexOf('-') < 0; 7390 if (!root) {
7391 return [];
7392 }
7393 var styles = root.querySelectorAll('style');
7394 return Array.prototype.filter.call(styles, function(s) {
7395 return !s.hasAttribute(NO_SHIM_ATTRIBUTE);
7396 });
7300 }, 7397 },
7301 applyScopeToContent: function(root, name) { 7398 applyScopeToContent: function(root, name) {
7302 if (root) { 7399 if (root) {
7303 // add the name attribute to each node in root. 7400 // add the name attribute to each node in root.
7304 Array.prototype.forEach.call(root.querySelectorAll('*'), 7401 Array.prototype.forEach.call(root.querySelectorAll('*'),
7305 function(node) { 7402 function(node) {
7306 node.setAttribute(name, ''); 7403 node.setAttribute(name, '');
7307 }); 7404 });
7308 // and template contents too 7405 // and template contents too
7309 Array.prototype.forEach.call(root.querySelectorAll('template'), 7406 Array.prototype.forEach.call(root.querySelectorAll('template'),
7310 function(template) { 7407 function(template) {
7311 this.applyScopeToContent(template.content, name); 7408 this.applyScopeToContent(template.content, name);
7312 }, 7409 },
7313 this); 7410 this);
7314 } 7411 }
7315 }, 7412 },
7413 insertDirectives: function(cssText) {
7414 cssText = this.insertPolyfillDirectivesInCssText(cssText);
7415 return this.insertPolyfillRulesInCssText(cssText);
7416 },
7316 /* 7417 /*
7317 * Process styles to convert native ShadowDOM rules that will trip 7418 * Process styles to convert native ShadowDOM rules that will trip
7318 * up the css parser; we rely on decorating the stylesheet with comments. 7419 * up the css parser; we rely on decorating the stylesheet with inert rules.
7319 * 7420 *
7320 * For example, we convert this rule: 7421 * For example, we convert this rule:
7321 * 7422 *
7322 * (comment start) @polyfill :host menu-item (comment end) 7423 * polyfill-next-selector { content: ':host menu-item'; }
7323 * shadow::-webkit-distributed(menu-item) { 7424 * ::content menu-item {
7324 * 7425 *
7325 * to this: 7426 * to this:
7326 * 7427 *
7327 * scopeName menu-item { 7428 * scopeName menu-item {
7328 * 7429 *
7329 **/ 7430 **/
7330 insertPolyfillDirectives: function(styles) {
7331 if (styles) {
7332 Array.prototype.forEach.call(styles, function(s) {
7333 s.textContent = this.insertPolyfillDirectivesInCssText(s.textContent);
7334 }, this);
7335 }
7336 },
7337 insertPolyfillDirectivesInCssText: function(cssText) { 7431 insertPolyfillDirectivesInCssText: function(cssText) {
7338 return cssText.replace(cssPolyfillCommentRe, function(match, p1) { 7432 // TODO(sorvell): remove either content or comment
7433 cssText = cssText.replace(cssCommentNextSelectorRe, function(match, p1) {
7339 // remove end comment delimiter and add block start 7434 // remove end comment delimiter and add block start
7340 return p1.slice(0, -2) + '{'; 7435 return p1.slice(0, -2) + '{';
7341 }); 7436 });
7437 return cssText.replace(cssContentNextSelectorRe, function(match, p1) {
7438 return p1 + ' {';
7439 });
7342 }, 7440 },
7343 /* 7441 /*
7344 * Process styles to add rules which will only apply under the polyfill 7442 * Process styles to add rules which will only apply under the polyfill
7345 * 7443 *
7346 * For example, we convert this rule: 7444 * For example, we convert this rule:
7347 * 7445 *
7348 * (comment start) @polyfill-rule :host menu-item { 7446 * polyfill-rule {
7349 * ... } (comment end) 7447 * content: ':host menu-item';
7448 * ...
7449 * }
7350 * 7450 *
7351 * to this: 7451 * to this:
7352 * 7452 *
7353 * scopeName menu-item {...} 7453 * scopeName menu-item {...}
7354 * 7454 *
7355 **/ 7455 **/
7356 insertPolyfillRules: function(styles) {
7357 if (styles) {
7358 Array.prototype.forEach.call(styles, function(s) {
7359 s.textContent = this.insertPolyfillRulesInCssText(s.textContent);
7360 }, this);
7361 }
7362 },
7363 insertPolyfillRulesInCssText: function(cssText) { 7456 insertPolyfillRulesInCssText: function(cssText) {
7364 return cssText.replace(cssPolyfillRuleCommentRe, function(match, p1) { 7457 // TODO(sorvell): remove either content or comment
7458 cssText = cssText.replace(cssCommentRuleRe, function(match, p1) {
7365 // remove end comment delimiter 7459 // remove end comment delimiter
7366 return p1.slice(0, -1); 7460 return p1.slice(0, -1);
7367 }); 7461 });
7368 }, 7462 return cssText.replace(cssContentRuleRe, function(match, p1, p2, p3) {
7369 /* 7463 var rule = match.replace(p1, '').replace(p2, '');
7370 * Process styles to add rules which will only apply under the polyfill 7464 return p3 + rule;
7371 * and do not process via CSSOM. (CSSOM is destructive to rules on rare 7465 });
7372 * occasions, e.g. -webkit-calc on Safari.)
7373 * For example, we convert this rule:
7374 *
7375 * (comment start) @polyfill-unscoped-rule menu-item {
7376 * ... } (comment end)
7377 *
7378 * to this:
7379 *
7380 * menu-item {...}
7381 *
7382 **/
7383 extractPolyfillUnscopedRules: function(styles) {
7384 var cssText = '';
7385 if (styles) {
7386 Array.prototype.forEach.call(styles, function(s) {
7387 cssText += this.extractPolyfillUnscopedRulesFromCssText(
7388 s.textContent) + '\n\n';
7389 }, this);
7390 }
7391 return cssText;
7392 },
7393 extractPolyfillUnscopedRulesFromCssText: function(cssText) {
7394 var r = '', matches;
7395 while (matches = cssPolyfillUnscopedRuleCommentRe.exec(cssText)) {
7396 r += matches[1].slice(0, -1) + '\n\n';
7397 }
7398 return r;
7399 }, 7466 },
7400 /* Ensure styles are scoped. Pseudo-scoping takes a rule like: 7467 /* Ensure styles are scoped. Pseudo-scoping takes a rule like:
7401 * 7468 *
7402 * .foo {... } 7469 * .foo {... }
7403 * 7470 *
7404 * and converts this to 7471 * and converts this to
7405 * 7472 *
7406 * scopeName .foo { ... } 7473 * scopeName .foo { ... }
7407 */ 7474 */
7408 shimScoping: function(styles, name, typeExtension) { 7475 scopeCssText: function(cssText, scopeSelector) {
7409 if (styles) { 7476 var unscoped = this.extractUnscopedRulesFromCssText(cssText);
7410 return this.convertScopedStyles(styles, name, typeExtension);
7411 }
7412 },
7413 convertScopedStyles: function(styles, name, typeExtension) {
7414 var cssText = stylesToCssText(styles);
7415 cssText = this.insertPolyfillHostInCssText(cssText); 7477 cssText = this.insertPolyfillHostInCssText(cssText);
7416 cssText = this.convertColonHost(cssText); 7478 cssText = this.convertColonHost(cssText);
7417 cssText = this.convertColonAncestor(cssText); 7479 cssText = this.convertColonAncestor(cssText);
7418 cssText = this.convertCombinators(cssText); 7480 cssText = this.convertCombinators(cssText);
7419 if (name) { 7481 if (scopeSelector) {
7420 var self = this, cssText; 7482 var self = this, cssText;
7421
7422 withCssRules(cssText, function(rules) { 7483 withCssRules(cssText, function(rules) {
7423 cssText = self.scopeRules(rules, name, typeExtension); 7484 cssText = self.scopeRules(rules, scopeSelector);
7424 }); 7485 });
7425 7486
7426 } 7487 }
7427 return cssText; 7488 cssText = cssText + '\n' + unscoped;
7489 return cssText.trim();
7490 },
7491 /*
7492 * Process styles to add rules which will only apply under the polyfill
7493 * and do not process via CSSOM. (CSSOM is destructive to rules on rare
7494 * occasions, e.g. -webkit-calc on Safari.)
7495 * For example, we convert this rule:
7496 *
7497 * (comment start) @polyfill-unscoped-rule menu-item {
7498 * ... } (comment end)
7499 *
7500 * to this:
7501 *
7502 * menu-item {...}
7503 *
7504 **/
7505 extractUnscopedRulesFromCssText: function(cssText) {
7506 // TODO(sorvell): remove either content or comment
7507 var r = '', m;
7508 while (m = cssCommentUnscopedRuleRe.exec(cssText)) {
7509 r += m[1].slice(0, -1) + '\n\n';
7510 }
7511 while (m = cssContentUnscopedRuleRe.exec(cssText)) {
7512 r += m[0].replace(m[2], '').replace(m[1], m[3]) + '\n\n';
7513 }
7514 return r;
7428 }, 7515 },
7429 /* 7516 /*
7430 * convert a rule like :host(.foo) > .bar { } 7517 * convert a rule like :host(.foo) > .bar { }
7431 * 7518 *
7432 * to 7519 * to
7433 * 7520 *
7434 * scopeName.foo > .bar 7521 * scopeName.foo > .bar
7435 */ 7522 */
7436 convertColonHost: function(cssText) { 7523 convertColonHost: function(cssText) {
7437 return this.convertColonRule(cssText, cssColonHostRe, 7524 return this.convertColonRule(cssText, cssColonHostRe,
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
7482 colonHostPartReplacer: function(host, part, suffix) { 7569 colonHostPartReplacer: function(host, part, suffix) {
7483 return host + part.replace(polyfillHost, '') + suffix; 7570 return host + part.replace(polyfillHost, '') + suffix;
7484 }, 7571 },
7485 /* 7572 /*
7486 * Convert ^ and ^^ combinators by replacing with space. 7573 * Convert ^ and ^^ combinators by replacing with space.
7487 */ 7574 */
7488 convertCombinators: function(cssText) { 7575 convertCombinators: function(cssText) {
7489 return cssText.replace(/\^\^/g, ' ').replace(/\^/g, ' '); 7576 return cssText.replace(/\^\^/g, ' ').replace(/\^/g, ' ');
7490 }, 7577 },
7491 // change a selector like 'div' to 'name div' 7578 // change a selector like 'div' to 'name div'
7492 scopeRules: function(cssRules, name, typeExtension) { 7579 scopeRules: function(cssRules, scopeSelector) {
7493 var cssText = ''; 7580 var cssText = '';
7494 if (cssRules) { 7581 if (cssRules) {
7495 Array.prototype.forEach.call(cssRules, function(rule) { 7582 Array.prototype.forEach.call(cssRules, function(rule) {
7496 if (rule.selectorText && (rule.style && rule.style.cssText)) { 7583 if (rule.selectorText && (rule.style && rule.style.cssText)) {
7497 cssText += this.scopeSelector(rule.selectorText, name, typeExtension, 7584 cssText += this.scopeSelector(rule.selectorText, scopeSelector,
7498 this.strictStyling) + ' {\n\t'; 7585 this.strictStyling) + ' {\n\t';
7499 cssText += this.propertiesFromRule(rule) + '\n}\n\n'; 7586 cssText += this.propertiesFromRule(rule) + '\n}\n\n';
7500 } else if (rule.type === CSSRule.MEDIA_RULE) { 7587 } else if (rule.type === CSSRule.MEDIA_RULE) {
7501 cssText += '@media ' + rule.media.mediaText + ' {\n'; 7588 cssText += '@media ' + rule.media.mediaText + ' {\n';
7502 cssText += this.scopeRules(rule.cssRules, name, typeExtension); 7589 cssText += this.scopeRules(rule.cssRules, scopeSelector);
7503 cssText += '\n}\n\n'; 7590 cssText += '\n}\n\n';
7504 } else if (rule.cssText) { 7591 } else if (rule.cssText) {
7505 cssText += rule.cssText + '\n\n'; 7592 cssText += rule.cssText + '\n\n';
7506 } 7593 }
7507 }, this); 7594 }, this);
7508 } 7595 }
7509 return cssText; 7596 return cssText;
7510 }, 7597 },
7511 scopeSelector: function(selector, name, typeExtension, strict) { 7598 scopeSelector: function(selector, scopeSelector, strict) {
7512 var r = [], parts = selector.split(','); 7599 var r = [], parts = selector.split(',');
7513 parts.forEach(function(p) { 7600 parts.forEach(function(p) {
7514 p = p.trim(); 7601 p = p.trim();
7515 if (this.selectorNeedsScoping(p, name, typeExtension)) { 7602 if (this.selectorNeedsScoping(p, scopeSelector)) {
7516 p = (strict && !p.match(polyfillHostNoCombinator)) ? 7603 p = (strict && !p.match(polyfillHostNoCombinator)) ?
7517 this.applyStrictSelectorScope(p, name) : 7604 this.applyStrictSelectorScope(p, scopeSelector) :
7518 this.applySimpleSelectorScope(p, name, typeExtension); 7605 this.applySimpleSelectorScope(p, scopeSelector);
7519 } 7606 }
7520 r.push(p); 7607 r.push(p);
7521 }, this); 7608 }, this);
7522 return r.join(', '); 7609 return r.join(', ');
7523 }, 7610 },
7524 selectorNeedsScoping: function(selector, name, typeExtension) { 7611 selectorNeedsScoping: function(selector, scopeSelector) {
7525 var re = this.makeScopeMatcher(name, typeExtension); 7612 var re = this.makeScopeMatcher(scopeSelector);
7526 return !selector.match(re); 7613 return !selector.match(re);
7527 }, 7614 },
7528 makeScopeMatcher: function(name, typeExtension) { 7615 makeScopeMatcher: function(scopeSelector) {
7529 var matchScope = typeExtension ? '\\[is=[\'"]?' + name + '[\'"]?\\]' : name; 7616 scopeSelector = scopeSelector.replace(/\[/g, '\\[').replace(/\[/g, '\\]');
7530 return new RegExp('^(' + matchScope + ')' + selectorReSuffix, 'm'); 7617 return new RegExp('^(' + scopeSelector + ')' + selectorReSuffix, 'm');
7531 }, 7618 },
7532 // scope via name and [is=name] 7619 // scope via name and [is=name]
7533 applySimpleSelectorScope: function(selector, name, typeExtension) { 7620 applySimpleSelectorScope: function(selector, scopeSelector) {
7534 var scoper = typeExtension ? '[is=' + name + ']' : name;
7535 if (selector.match(polyfillHostRe)) { 7621 if (selector.match(polyfillHostRe)) {
7536 selector = selector.replace(polyfillHostNoCombinator, scoper); 7622 selector = selector.replace(polyfillHostNoCombinator, scopeSelector);
7537 return selector.replace(polyfillHostRe, scoper + ' '); 7623 return selector.replace(polyfillHostRe, scopeSelector + ' ');
7538 } else { 7624 } else {
7539 return scoper + ' ' + selector; 7625 return scopeSelector + ' ' + selector;
7540 } 7626 }
7541 }, 7627 },
7542 // return a selector with [name] suffix on each simple selector 7628 // return a selector with [name] suffix on each simple selector
7543 // e.g. .foo.bar > .zot becomes .foo[name].bar[name] > .zot[name] 7629 // e.g. .foo.bar > .zot becomes .foo[name].bar[name] > .zot[name]
7544 applyStrictSelectorScope: function(selector, name) { 7630 applyStrictSelectorScope: function(selector, scopeSelector) {
7631 scopeSelector = scopeSelector.replace(/\[is=([^\]]*)\]/g, '$1');
7545 var splits = [' ', '>', '+', '~'], 7632 var splits = [' ', '>', '+', '~'],
7546 scoped = selector, 7633 scoped = selector,
7547 attrName = '[' + name + ']'; 7634 attrName = '[' + scopeSelector + ']';
7548 splits.forEach(function(sep) { 7635 splits.forEach(function(sep) {
7549 var parts = scoped.split(sep); 7636 var parts = scoped.split(sep);
7550 scoped = parts.map(function(p) { 7637 scoped = parts.map(function(p) {
7551 // remove :host since it should be unnecessary 7638 // remove :host since it should be unnecessary
7552 var t = p.trim().replace(polyfillHostRe, ''); 7639 var t = p.trim().replace(polyfillHostRe, '');
7553 if (t && (splits.indexOf(t) < 0) && (t.indexOf(attrName) < 0)) { 7640 if (t && (splits.indexOf(t) < 0) && (t.indexOf(attrName) < 0)) {
7554 p = t.replace(/([^:]*)(:*)(.*)/, '$1' + attrName + '$2$3') 7641 p = t.replace(/([^:]*)(:*)(.*)/, '$1' + attrName + '$2$3')
7555 } 7642 }
7556 return p; 7643 return p;
7557 }).join(sep); 7644 }).join(sep);
7558 }); 7645 });
7559 return scoped; 7646 return scoped;
7560 }, 7647 },
7561 insertPolyfillHostInCssText: function(selector) { 7648 insertPolyfillHostInCssText: function(selector) {
7562 return selector.replace(hostRe, polyfillHost).replace(colonHostRe, 7649 return selector.replace(hostRe, polyfillHost).replace(colonHostRe,
7563 polyfillHost).replace(colonAncestorRe, polyfillAncestor); 7650 polyfillHost).replace(colonAncestorRe, polyfillAncestor);
7564 }, 7651 },
7565 propertiesFromRule: function(rule) { 7652 propertiesFromRule: function(rule) {
7566 // TODO(sorvell): Safari cssom incorrectly removes quotes from the content 7653 // TODO(sorvell): Safari cssom incorrectly removes quotes from the content
7567 // property. (https://bugs.webkit.org/show_bug.cgi?id=118045) 7654 // property. (https://bugs.webkit.org/show_bug.cgi?id=118045)
7568 if (rule.style.content && !rule.style.content.match(/['"]+/)) { 7655 if (rule.style.content && !rule.style.content.match(/['"]+/)) {
7569 return rule.style.cssText.replace(/content:[^;]*;/g, 'content: \'' + 7656 return rule.style.cssText.replace(/content:[^;]*;/g, 'content: \'' +
7570 rule.style.content + '\';'); 7657 rule.style.content + '\';');
7571 } 7658 }
7572 return rule.style.cssText; 7659 return rule.style.cssText;
7660 },
7661 replaceTextInStyles: function(styles, action) {
7662 if (styles && action) {
7663 if (!(styles instanceof Array)) {
7664 styles = [styles];
7665 }
7666 Array.prototype.forEach.call(styles, function(s) {
7667 s.textContent = action.call(this, s.textContent);
7668 }, this);
7669 }
7670 },
7671 addCssToDocument: function(cssText, name) {
7672 if (cssText.match('@import')) {
7673 addOwnSheet(cssText, name);
7674 } else {
7675 addCssToDocument(cssText);
7676 }
7573 } 7677 }
7574 }; 7678 };
7575 7679
7576 var selectorRe = /([^{]*)({[\s\S]*?})/gim, 7680 var selectorRe = /([^{]*)({[\s\S]*?})/gim,
7577 cssCommentRe = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim, 7681 cssCommentRe = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim,
7578 cssPolyfillCommentRe = /\/\*\s*@polyfill ([^*]*\*+([^/*][^*]*\*+)*\/)([^{]*? ){/gim, 7682 // TODO(sorvell): remove either content or comment
7579 cssPolyfillRuleCommentRe = /\/\*\s@polyfill-rule([^*]*\*+([^/*][^*]*\*+)*)\/ /gim, 7683 cssCommentNextSelectorRe = /\/\*\s*@polyfill ([^*]*\*+([^/*][^*]*\*+)*\/)([^ {]*?){/gim,
7580 cssPolyfillUnscopedRuleCommentRe = /\/\*\s@polyfill-unscoped-rule([^*]*\*+([ ^/*][^*]*\*+)*)\//gim, 7684 cssContentNextSelectorRe = /polyfill-next-selector[^}]*content\:[\s]*'([^']* )'[^}]*}([^{]*?){/gim,
7685 // TODO(sorvell): remove either content or comment
7686 cssCommentRuleRe = /\/\*\s@polyfill-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim,
7687 cssContentRuleRe = /(polyfill-rule)[^}]*(content\:[\s]*'([^']*)'[^;]*;)[^}]* }/gim,
7688 // TODO(sorvell): remove either content or comment
7689 cssCommentUnscopedRuleRe = /\/\*\s@polyfill-unscoped-rule([^*]*\*+([^/*][^*] *\*+)*)\//gim,
7690 cssContentUnscopedRuleRe = /(polyfill-unscoped-rule)[^}]*(content\:[\s]*'([^ ']*)'[^;]*;)[^}]*}/gim,
7581 cssPseudoRe = /::(x-[^\s{,(]*)/gim, 7691 cssPseudoRe = /::(x-[^\s{,(]*)/gim,
7582 cssPartRe = /::part\(([^)]*)\)/gim, 7692 cssPartRe = /::part\(([^)]*)\)/gim,
7583 // note: :host pre-processed to -shadowcsshost. 7693 // note: :host pre-processed to -shadowcsshost.
7584 polyfillHost = '-shadowcsshost', 7694 polyfillHost = '-shadowcsshost',
7585 // note: :ancestor pre-processed to -shadowcssancestor. 7695 // note: :ancestor pre-processed to -shadowcssancestor.
7586 polyfillAncestor = '-shadowcssancestor', 7696 polyfillAncestor = '-shadowcssancestor',
7587 parenSuffix = ')(?:\\((' + 7697 parenSuffix = ')(?:\\((' +
7588 '(?:\\([^)(]*\\)|[^)(]*)+?' + 7698 '(?:\\([^)(]*\\)|[^)(]*)+?' +
7589 ')\\))?([^,{]*)'; 7699 ')\\))?([^,{]*)';
7590 cssColonHostRe = new RegExp('(' + polyfillHost + parenSuffix, 'gim'), 7700 cssColonHostRe = new RegExp('(' + polyfillHost + parenSuffix, 'gim'),
7591 cssColonAncestorRe = new RegExp('(' + polyfillAncestor + parenSuffix, 'gim') , 7701 cssColonAncestorRe = new RegExp('(' + polyfillAncestor + parenSuffix, 'gim') ,
7592 selectorReSuffix = '([>\\s~+\[.,{:][\\s\\S]*)?$', 7702 selectorReSuffix = '([>\\s~+\[.,{:][\\s\\S]*)?$',
7593 hostRe = /@host/gim, 7703 hostRe = /@host/gim,
7594 colonHostRe = /\:host/gim, 7704 colonHostRe = /\:host/gim,
7595 colonAncestorRe = /\:ancestor/gim, 7705 colonAncestorRe = /\:ancestor/gim,
7596 /* host name without combinator */ 7706 /* host name without combinator */
7597 polyfillHostNoCombinator = polyfillHost + '-no-combinator', 7707 polyfillHostNoCombinator = polyfillHost + '-no-combinator',
7598 polyfillHostRe = new RegExp(polyfillHost, 'gim'); 7708 polyfillHostRe = new RegExp(polyfillHost, 'gim'),
7599 polyfillAncestorRe = new RegExp(polyfillAncestor, 'gim'); 7709 polyfillAncestorRe = new RegExp(polyfillAncestor, 'gim');
7600 7710
7601 function stylesToCssText(styles, preserveComments) { 7711 function stylesToCssText(styles, preserveComments) {
7602 var cssText = ''; 7712 var cssText = '';
7603 Array.prototype.forEach.call(styles, function(s) { 7713 Array.prototype.forEach.call(styles, function(s) {
7604 cssText += s.textContent + '\n\n'; 7714 cssText += s.textContent + '\n\n';
7605 }); 7715 });
7606 // strip comments for easier processing 7716 // strip comments for easier processing
7607 if (!preserveComments) { 7717 if (!preserveComments) {
7608 cssText = cssText.replace(cssCommentRe, ''); 7718 cssText = cssText.replace(cssCommentRe, '');
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
7693 7803
7694 function addOwnSheet(cssText, name) { 7804 function addOwnSheet(cssText, name) {
7695 var style = cssTextToStyle(cssText); 7805 var style = cssTextToStyle(cssText);
7696 style.setAttribute(name, ''); 7806 style.setAttribute(name, '');
7697 style.setAttribute(SHIMMED_ATTRIBUTE, ''); 7807 style.setAttribute(SHIMMED_ATTRIBUTE, '');
7698 document.head.appendChild(style); 7808 document.head.appendChild(style);
7699 } 7809 }
7700 7810
7701 var SHIM_ATTRIBUTE = 'shim-shadowdom'; 7811 var SHIM_ATTRIBUTE = 'shim-shadowdom';
7702 var SHIMMED_ATTRIBUTE = 'shim-shadowdom-css'; 7812 var SHIMMED_ATTRIBUTE = 'shim-shadowdom-css';
7813 var NO_SHIM_ATTRIBUTE = 'no-shim';
7703 7814
7704 var sheet; 7815 var sheet;
7705 function getSheet() { 7816 function getSheet() {
7706 if (!sheet) { 7817 if (!sheet) {
7707 sheet = document.createElement("style"); 7818 sheet = document.createElement("style");
7708 sheet.setAttribute(SHIMMED_ATTRIBUTE, ''); 7819 sheet.setAttribute(SHIMMED_ATTRIBUTE, '');
7709 sheet[SHIMMED_ATTRIBUTE] = true; 7820 sheet[SHIMMED_ATTRIBUTE] = true;
7710 } 7821 }
7711 return sheet; 7822 return sheet;
7712 } 7823 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
7747 originalParseGeneric.call(this, elt); 7858 originalParseGeneric.call(this, elt);
7748 return; 7859 return;
7749 } 7860 }
7750 if (elt.__resource) { 7861 if (elt.__resource) {
7751 style = elt.ownerDocument.createElement('style'); 7862 style = elt.ownerDocument.createElement('style');
7752 style.textContent = urlResolver.resolveCssText( 7863 style.textContent = urlResolver.resolveCssText(
7753 elt.__resource, elt.href); 7864 elt.__resource, elt.href);
7754 } else { 7865 } else {
7755 urlResolver.resolveStyle(style); 7866 urlResolver.resolveStyle(style);
7756 } 7867 }
7757 var styles = [style]; 7868 style.textContent = ShadowCSS.shimStyle(style);
7758 style.textContent = ShadowCSS.stylesToShimmedCssText(styles, styles);
7759 style.removeAttribute(SHIM_ATTRIBUTE, ''); 7869 style.removeAttribute(SHIM_ATTRIBUTE, '');
7760 style.setAttribute(SHIMMED_ATTRIBUTE, ''); 7870 style.setAttribute(SHIMMED_ATTRIBUTE, '');
7761 style[SHIMMED_ATTRIBUTE] = true; 7871 style[SHIMMED_ATTRIBUTE] = true;
7762 // place in document 7872 // place in document
7763 if (style.parentNode !== head) { 7873 if (style.parentNode !== head) {
7764 // replace links in head 7874 // replace links in head
7765 if (elt.parentNode === head) { 7875 if (elt.parentNode === head) {
7766 head.replaceChild(style, elt); 7876 head.replaceChild(style, elt);
7767 } else { 7877 } else {
7768 head.appendChild(style); 7878 head.appendChild(style);
(...skipping 3936 matching lines...) Expand 10 before | Expand all | Expand 10 after
11705 * @return {Event} A new PointerEvent of type `inType` and initialized with prop erties from `inDict`. 11815 * @return {Event} A new PointerEvent of type `inType` and initialized with prop erties from `inDict`.
11706 */ 11816 */
11707 (function(scope) { 11817 (function(scope) {
11708 // test for DOM Level 4 Events 11818 // test for DOM Level 4 Events
11709 var NEW_MOUSE_EVENT = false; 11819 var NEW_MOUSE_EVENT = false;
11710 var HAS_BUTTONS = false; 11820 var HAS_BUTTONS = false;
11711 try { 11821 try {
11712 var ev = new MouseEvent('click', {buttons: 1}); 11822 var ev = new MouseEvent('click', {buttons: 1});
11713 NEW_MOUSE_EVENT = true; 11823 NEW_MOUSE_EVENT = true;
11714 HAS_BUTTONS = ev.buttons === 1; 11824 HAS_BUTTONS = ev.buttons === 1;
11825 ev = null;
11715 } catch(e) { 11826 } catch(e) {
11716 } 11827 }
11717 11828
11718 var MOUSE_PROPS = [ 11829 var MOUSE_PROPS = [
11719 'bubbles', 11830 'bubbles',
11720 'cancelable', 11831 'cancelable',
11721 'view', 11832 'view',
11722 'detail', 11833 'detail',
11723 'screenX', 11834 'screenX',
11724 'screenY', 11835 'screenY',
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
11765 // but initMouseEvent does not expose an argument with which to set 11876 // but initMouseEvent does not expose an argument with which to set
11766 // MouseEvent.which. Calling initMouseEvent with a buttonArg of 0 will set 11877 // MouseEvent.which. Calling initMouseEvent with a buttonArg of 0 will set
11767 // MouseEvent.button == 0 and MouseEvent.which == 1, breaking the expectatio ns 11878 // MouseEvent.button == 0 and MouseEvent.which == 1, breaking the expectatio ns
11768 // of app developers. 11879 // of app developers.
11769 // 11880 //
11770 // The only way to propagate the correct state of MouseEvent.which and 11881 // The only way to propagate the correct state of MouseEvent.which and
11771 // MouseEvent.button to a new MouseEvent.button == 0 and MouseEvent.which == 0 11882 // MouseEvent.button to a new MouseEvent.button == 0 and MouseEvent.which == 0
11772 // is to call initMouseEvent with a buttonArg value of -1. 11883 // is to call initMouseEvent with a buttonArg value of -1.
11773 // 11884 //
11774 // This is fixed with DOM Level 4's use of buttons 11885 // This is fixed with DOM Level 4's use of buttons
11775 var buttons; 11886 var buttons = inDict.buttons;
11776 if (inDict.buttons || HAS_BUTTONS) { 11887 // touch has two possible buttons state: 0 and 1, rely on being told the rig ht one
11777 buttons = inDict.buttons; 11888 if (!HAS_BUTTONS && !buttons && inType !== 'touch') {
11778 } else {
11779 switch (inDict.which) { 11889 switch (inDict.which) {
11780 case 1: buttons = 1; break; 11890 case 1: buttons = 1; break;
11781 case 2: buttons = 4; break; 11891 case 2: buttons = 4; break;
11782 case 3: buttons = 2; break; 11892 case 3: buttons = 2; break;
11783 default: buttons = 0; 11893 default: buttons = 0;
11784 } 11894 }
11785 } 11895 }
11786 11896
11787 var e; 11897 var e;
11788 if (NEW_MOUSE_EVENT) { 11898 if (NEW_MOUSE_EVENT) {
(...skipping 524 matching lines...) Expand 10 before | Expand all | Expand 10 after
12313 this.addCallback(el); 12423 this.addCallback(el);
12314 }, 12424 },
12315 elementChanged: function(el, oldValue) { 12425 elementChanged: function(el, oldValue) {
12316 this.changedCallback(el, oldValue); 12426 this.changedCallback(el, oldValue);
12317 }, 12427 },
12318 concatLists: function(accum, list) { 12428 concatLists: function(accum, list) {
12319 return accum.concat(toArray(list)); 12429 return accum.concat(toArray(list));
12320 }, 12430 },
12321 // register all touch-action = none nodes on document load 12431 // register all touch-action = none nodes on document load
12322 installOnLoad: function() { 12432 installOnLoad: function() {
12323 document.addEventListener('DOMContentLoaded', this.installNewSubtree.bind( this, document)); 12433 document.addEventListener('readystatechange', function() {
12434 if (document.readyState === 'complete') {
12435 this.installNewSubtree(document);
12436 }
12437 }.bind(this));
12324 }, 12438 },
12325 isElement: function(n) { 12439 isElement: function(n) {
12326 return n.nodeType === Node.ELEMENT_NODE; 12440 return n.nodeType === Node.ELEMENT_NODE;
12327 }, 12441 },
12328 flattenMutationTree: function(inNodes) { 12442 flattenMutationTree: function(inNodes) {
12329 // find children with touch-action 12443 // find children with touch-action
12330 var tree = map(inNodes, this.findElements, this); 12444 var tree = map(inNodes, this.findElements, this);
12331 // make sure the added nodes are accounted for 12445 // make sure the added nodes are accounted for
12332 tree.push(filter(inNodes, this.isElement)); 12446 tree.push(filter(inNodes, this.isElement));
12333 // flatten the list 12447 // flatten the list
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
12598 this.clickCount = 0; 12712 this.clickCount = 0;
12599 this.resetId = null; 12713 this.resetId = null;
12600 }.bind(this); 12714 }.bind(this);
12601 this.resetId = setTimeout(fn, CLICK_COUNT_TIMEOUT); 12715 this.resetId = setTimeout(fn, CLICK_COUNT_TIMEOUT);
12602 }, 12716 },
12603 cancelResetClickCount: function() { 12717 cancelResetClickCount: function() {
12604 if (this.resetId) { 12718 if (this.resetId) {
12605 clearTimeout(this.resetId); 12719 clearTimeout(this.resetId);
12606 } 12720 }
12607 }, 12721 },
12722 typeToButtons: function(type) {
12723 var ret = 0;
12724 if (type === 'touchstart' || type === 'touchmove') {
12725 ret = 1;
12726 }
12727 return ret;
12728 },
12608 touchToPointer: function(inTouch) { 12729 touchToPointer: function(inTouch) {
12609 var e = dispatcher.cloneEvent(inTouch); 12730 var e = dispatcher.cloneEvent(inTouch);
12610 // Spec specifies that pointerId 1 is reserved for Mouse. 12731 // Spec specifies that pointerId 1 is reserved for Mouse.
12611 // Touch identifiers can start at 0. 12732 // Touch identifiers can start at 0.
12612 // Add 2 to the touch identifier for compatibility. 12733 // Add 2 to the touch identifier for compatibility.
12613 e.pointerId = inTouch.identifier + 2; 12734 e.pointerId = inTouch.identifier + 2;
12614 e.target = findTarget(e); 12735 e.target = findTarget(e);
12615 e.bubbles = true; 12736 e.bubbles = true;
12616 e.cancelable = true; 12737 e.cancelable = true;
12617 e.detail = this.clickCount; 12738 e.detail = this.clickCount;
12618 e.button = 0; 12739 e.button = 0;
12619 e.buttons = 1; 12740 e.buttons = this.typeToButtons(this.currentTouchEvent);
12620 e.width = inTouch.webkitRadiusX || inTouch.radiusX || 0; 12741 e.width = inTouch.webkitRadiusX || inTouch.radiusX || 0;
12621 e.height = inTouch.webkitRadiusY || inTouch.radiusY || 0; 12742 e.height = inTouch.webkitRadiusY || inTouch.radiusY || 0;
12622 e.pressure = inTouch.webkitForce || inTouch.force || 0.5; 12743 e.pressure = inTouch.webkitForce || inTouch.force || 0.5;
12623 e.isPrimary = this.isPrimaryTouch(inTouch); 12744 e.isPrimary = this.isPrimaryTouch(inTouch);
12624 e.pointerType = this.POINTER_TYPE; 12745 e.pointerType = this.POINTER_TYPE;
12625 return e; 12746 return e;
12626 }, 12747 },
12627 processTouches: function(inEvent, inFunction) { 12748 processTouches: function(inEvent, inFunction) {
12628 var tl = inEvent.changedTouches; 12749 var tl = inEvent.changedTouches;
12750 this.currentTouchEvent = inEvent.type;
12629 var pointers = touchMap(tl, this.touchToPointer, this); 12751 var pointers = touchMap(tl, this.touchToPointer, this);
12630 // forward touch preventDefaults 12752 // forward touch preventDefaults
12631 pointers.forEach(function(p) { 12753 pointers.forEach(function(p) {
12632 p.preventDefault = function() { 12754 p.preventDefault = function() {
12633 this.scrolling = false; 12755 this.scrolling = false;
12634 this.firstXY = null; 12756 this.firstXY = null;
12635 inEvent.preventDefault(); 12757 inEvent.preventDefault();
12636 }; 12758 };
12637 }, this); 12759 }, this);
12638 pointers.forEach(inFunction, this); 12760 pointers.forEach(inFunction, this);
(...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after
13353 setTimeout(fn, 0); 13475 setTimeout(fn, 0);
13354 }, 13476 },
13355 preventTap: function(inPointerId) { 13477 preventTap: function(inPointerId) {
13356 var t = this.recognizers.tap; 13478 var t = this.recognizers.tap;
13357 if (t){ 13479 if (t){
13358 t.preventTap(inPointerId); 13480 t.preventTap(inPointerId);
13359 } 13481 }
13360 } 13482 }
13361 }; 13483 };
13362 dispatcher.boundHandler = dispatcher.eventHandler.bind(dispatcher); 13484 dispatcher.boundHandler = dispatcher.eventHandler.bind(dispatcher);
13485 // recognizers call into the dispatcher and load later
13486 // solve the chicken and egg problem by having registerScopes module run last
13487 dispatcher.registerQueue = [];
13488 dispatcher.immediateRegister = false;
13363 scope.dispatcher = dispatcher; 13489 scope.dispatcher = dispatcher;
13364 var registerQueue = [];
13365 var immediateRegister = false;
13366 /** 13490 /**
13367 * Enable gesture events for a given scope, typically 13491 * Enable gesture events for a given scope, typically
13368 * [ShadowRoots](https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow /index.html#shadow-root-object). 13492 * [ShadowRoots](https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow /index.html#shadow-root-object).
13369 * 13493 *
13370 * @for PointerGestures 13494 * @for PointerGestures
13371 * @method register 13495 * @method register
13372 * @param {ShadowRoot} scope A top level scope to enable gesture 13496 * @param {ShadowRoot} scope A top level scope to enable gesture
13373 * support on. 13497 * support on.
13374 */ 13498 */
13375 scope.register = function(inScope) { 13499 scope.register = function(inScope) {
13376 if (immediateRegister) { 13500 if (dispatcher.immediateRegister) {
13377 var pe = window.PointerEventsPolyfill; 13501 var pe = window.PointerEventsPolyfill;
13378 if (pe) { 13502 if (pe) {
13379 pe.register(inScope); 13503 pe.register(inScope);
13380 } 13504 }
13381 scope.dispatcher.registerTarget(inScope); 13505 scope.dispatcher.registerTarget(inScope);
13382 } else { 13506 } else {
13383 registerQueue.push(inScope); 13507 dispatcher.registerQueue.push(inScope);
13384 } 13508 }
13385 }; 13509 };
13386 // wait to register scopes until recognizers load 13510 scope.register(document);
13387 document.addEventListener('DOMContentLoaded', function() {
13388 immediateRegister = true;
13389 registerQueue.push(document);
13390 registerQueue.forEach(scope.register);
13391 });
13392 })(window.PointerGestures); 13511 })(window.PointerGestures);
13393 13512
13394 /* 13513 /*
13395 * Copyright 2013 The Polymer Authors. All rights reserved. 13514 * Copyright 2013 The Polymer Authors. All rights reserved.
13396 * Use of this source code is governed by a BSD-style 13515 * Use of this source code is governed by a BSD-style
13397 * license that can be found in the LICENSE file. 13516 * license that can be found in the LICENSE file.
13398 */ 13517 */
13399 13518
13400 /** 13519 /**
13401 * This event is fired when a pointer is held down for 200ms. 13520 * This event is fired when a pointer is held down for 200ms.
(...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after
14045 'pointerdown', 14164 'pointerdown',
14046 'pointermove', 14165 'pointermove',
14047 'pointerup', 14166 'pointerup',
14048 'pointercancel', 14167 'pointercancel',
14049 'keyup' 14168 'keyup'
14050 ], 14169 ],
14051 pointerdown: function(inEvent) { 14170 pointerdown: function(inEvent) {
14052 if (inEvent.isPrimary && !inEvent.tapPrevented) { 14171 if (inEvent.isPrimary && !inEvent.tapPrevented) {
14053 pointermap.set(inEvent.pointerId, { 14172 pointermap.set(inEvent.pointerId, {
14054 target: inEvent.target, 14173 target: inEvent.target,
14174 buttons: inEvent.buttons,
14055 x: inEvent.clientX, 14175 x: inEvent.clientX,
14056 y: inEvent.clientY 14176 y: inEvent.clientY
14057 }); 14177 });
14058 } 14178 }
14059 }, 14179 },
14060 pointermove: function(inEvent) { 14180 pointermove: function(inEvent) {
14061 if (inEvent.isPrimary) { 14181 if (inEvent.isPrimary) {
14062 var start = pointermap.get(inEvent.pointerId); 14182 var start = pointermap.get(inEvent.pointerId);
14063 if (start) { 14183 if (start) {
14064 if (inEvent.tapPrevented) { 14184 if (inEvent.tapPrevented) {
14065 pointermap.delete(inEvent.pointerId); 14185 pointermap.delete(inEvent.pointerId);
14066 } 14186 }
14067 } 14187 }
14068 } 14188 }
14069 }, 14189 },
14070 shouldTap: function(e) { 14190 shouldTap: function(e, downState) {
14071 if (!e.tapPrevented) { 14191 if (!e.tapPrevented) {
14072 // only allow left click to tap for mouse 14192 if (e.pointerType === 'mouse') {
14073 return e.pointerType === 'mouse' ? e.buttons === 1 : true; 14193 // only allow left click to tap for mouse
14194 return downState.buttons === 1;
14195 } else {
14196 return true;
14197 }
14074 } 14198 }
14075 }, 14199 },
14076 pointerup: function(inEvent) { 14200 pointerup: function(inEvent) {
14077 var start = pointermap.get(inEvent.pointerId); 14201 var start = pointermap.get(inEvent.pointerId);
14078 if (start && this.shouldTap(inEvent)) { 14202 if (start && this.shouldTap(inEvent, start)) {
14079 var t = scope.findLCA(start.target, inEvent.target); 14203 var t = scope.findLCA(start.target, inEvent.target);
14080 if (t) { 14204 if (t) {
14081 var e = dispatcher.makeEvent('tap', { 14205 var e = dispatcher.makeEvent('tap', {
14082 x: inEvent.clientX, 14206 x: inEvent.clientX,
14083 y: inEvent.clientY, 14207 y: inEvent.clientY,
14084 detail: inEvent.detail, 14208 detail: inEvent.detail,
14085 pointerType: inEvent.pointerType 14209 pointerType: inEvent.pointerType
14086 }); 14210 });
14087 dispatcher.dispatchEvent(e, t); 14211 dispatcher.dispatchEvent(e, t);
14088 } 14212 }
(...skipping 18 matching lines...) Expand all
14107 } 14231 }
14108 } 14232 }
14109 }, 14233 },
14110 preventTap: function(inPointerId) { 14234 preventTap: function(inPointerId) {
14111 pointermap.delete(inPointerId); 14235 pointermap.delete(inPointerId);
14112 } 14236 }
14113 }; 14237 };
14114 dispatcher.registerRecognizer('tap', tap); 14238 dispatcher.registerRecognizer('tap', tap);
14115 })(window.PointerGestures); 14239 })(window.PointerGestures);
14116 14240
14241 /*
14242 * Copyright 2014 The Polymer Authors. All rights reserved.
14243 * Use of this source code is governed by a BSD-style
14244 * license that can be found in the LICENSE file.
14245 */
14246
14247 /**
14248 * Because recognizers are loaded after dispatcher, we have to wait to register
14249 * scopes until after all the recognizers.
14250 */
14251 (function(scope) {
14252 var dispatcher = scope.dispatcher;
14253 function registerScopes() {
14254 dispatcher.immediateRegister = true;
14255 var rq = dispatcher.registerQueue;
14256 rq.forEach(scope.register);
14257 rq.length = 0;
14258 }
14259 if (document.readyState === 'complete') {
14260 registerScopes();
14261 } else {
14262 // register scopes after a steadystate is reached
14263 // less MutationObserver churn
14264 document.addEventListener('readystatechange', function() {
14265 if (document.readyState === 'complete') {
14266 registerScopes();
14267 }
14268 });
14269 }
14270 })(window.PointerGestures);
14271
14117 // Copyright 2011 Google Inc. 14272 // Copyright 2011 Google Inc.
14118 // 14273 //
14119 // Licensed under the Apache License, Version 2.0 (the "License"); 14274 // Licensed under the Apache License, Version 2.0 (the "License");
14120 // you may not use this file except in compliance with the License. 14275 // you may not use this file except in compliance with the License.
14121 // You may obtain a copy of the License at 14276 // You may obtain a copy of the License at
14122 // 14277 //
14123 // http://www.apache.org/licenses/LICENSE-2.0 14278 // http://www.apache.org/licenses/LICENSE-2.0
14124 // 14279 //
14125 // Unless required by applicable law or agreed to in writing, software 14280 // Unless required by applicable law or agreed to in writing, software
14126 // distributed under the License is distributed on an "AS IS" BASIS, 14281 // distributed under the License is distributed on an "AS IS" BASIS,
14127 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14282 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14128 // See the License for the specific language governing permissions and 14283 // See the License for the specific language governing permissions and
14129 // limitations under the License. 14284 // limitations under the License.
14130 14285
14131 (function(global) { 14286 (function(global) {
14132 'use strict'; 14287 'use strict';
14133 14288
14134 var filter = Array.prototype.filter.call.bind(Array.prototype.filter); 14289 var filter = Array.prototype.filter.call.bind(Array.prototype.filter);
14135 14290
14136 function getTreeScope(node) { 14291 function getTreeScope(node) {
14137 while (node.parentNode) { 14292 while (node.parentNode) {
14138 node = node.parentNode; 14293 node = node.parentNode;
14139 } 14294 }
14140 14295
14141 return typeof node.getElementById === 'function' ? node : null; 14296 return typeof node.getElementById === 'function' ? node : null;
14142 } 14297 }
14143 14298
14144 // JScript does not have __proto__. We wrap all object literals with
14145 // createObject which uses Object.create, Object.defineProperty and
14146 // Object.getOwnPropertyDescriptor to create a new object that does the exact
14147 // same thing. The main downside to this solution is that we have to extract
14148 // all those property descriptors for IE.
14149 var createObject = ('__proto__' in {}) ?
14150 function(obj) { return obj; } :
14151 function(obj) {
14152 var proto = obj.__proto__;
14153 if (!proto)
14154 return obj;
14155 var newObject = Object.create(proto);
14156 Object.getOwnPropertyNames(obj).forEach(function(name) {
14157 Object.defineProperty(newObject, name,
14158 Object.getOwnPropertyDescriptor(obj, name));
14159 });
14160 return newObject;
14161 };
14162
14163 // IE does not support have Document.prototype.contains.
14164 if (typeof document.contains != 'function') {
14165 Document.prototype.contains = function(node) {
14166 if (node === this || node.parentNode === this)
14167 return true;
14168 return this.documentElement.contains(node);
14169 }
14170 }
14171 14299
14172 Node.prototype.bind = function(name, observable) { 14300 Node.prototype.bind = function(name, observable) {
14173 console.error('Unhandled binding to Node: ', this, name, observable); 14301 console.error('Unhandled binding to Node: ', this, name, observable);
14174 }; 14302 };
14175 14303
14176 function unbind(node, name) { 14304 function unbind(node, name) {
14177 var bindings = node.bindings; 14305 var bindings = node.bindings;
14178 if (!bindings) { 14306 if (!bindings) {
14179 node.bindings = {}; 14307 node.bindings = {};
14180 return; 14308 return;
(...skipping 3295 matching lines...) Expand 10 before | Expand all | Expand 10 after
17476 } 17604 }
17477 } 17605 }
17478 17606
17479 // exports 17607 // exports
17480 scope.flush = flush; 17608 scope.flush = flush;
17481 17609
17482 })(window.Platform); 17610 })(window.Platform);
17483 17611
17484 17612
17485 //# sourceMappingURL=platform.concat.js.map 17613 //# 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