Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / third_party / polymer / v1_0 / components-chromium / iron-resizable-behavior / iron-resizable-behavior-extracted.js
blob37efb02d4aaf57c179cbb4afc7330d8969e38029
2   /**
3    * `IronResizableBehavior` is a behavior that can be used in Polymer elements to
4    * coordinate the flow of resize events between "resizers" (elements that control the
5    * size or hidden state of their children) and "resizables" (elements that need to be
6    * notified when they are resized or un-hidden by their parents in order to take
7    * action on their new measurements).
8    * Elements that perform measurement should add the `IronResizableBehavior` behavior to
9    * their element definition and listen for the `iron-resize` event on themselves.
10    * This event will be fired when they become showing after having been hidden,
11    * when they are resized explicitly by another resizable, or when the window has been
12    * resized.
13    * Note, the `iron-resize` event is non-bubbling.
14    *
15    * @polymerBehavior Polymer.IronResizableBehavior
16    * @demo demo/index.html
17    **/
18   Polymer.IronResizableBehavior = {
19     properties: {
20       /**
21        * The closest ancestor element that implements `IronResizableBehavior`.
22        */
23       _parentResizable: {
24         type: Object,
25         observer: '_parentResizableChanged'
26       },
28       /**
29        * True if this element is currently notifying its descedant elements of
30        * resize.
31        */
32       _notifyingDescendant: {
33         type: Boolean,
34         value: false
35       }
36     },
38     listeners: {
39       'iron-request-resize-notifications': '_onIronRequestResizeNotifications'
40     },
42     created: function() {
43       // We don't really need property effects on these, and also we want them
44       // to be created before the `_parentResizable` observer fires:
45       this._interestedResizables = [];
46       this._boundNotifyResize = this.notifyResize.bind(this);
47     },
49     attached: function() {
50       this.fire('iron-request-resize-notifications', null, {
51         node: this,
52         bubbles: true,
53         cancelable: true
54       });
56       if (!this._parentResizable) {
57         window.addEventListener('resize', this._boundNotifyResize);
58         this.notifyResize();
59       }
60     },
62     detached: function() {
63       if (this._parentResizable) {
64         this._parentResizable.stopResizeNotificationsFor(this);
65       } else {
66         window.removeEventListener('resize', this._boundNotifyResize);
67       }
69       this._parentResizable = null;
70     },
72     /**
73      * Can be called to manually notify a resizable and its descendant
74      * resizables of a resize change.
75      */
76     notifyResize: function() {
77       if (!this.isAttached) {
78         return;
79       }
81       this._interestedResizables.forEach(function(resizable) {
82         if (this.resizerShouldNotify(resizable)) {
83           this._notifyDescendant(resizable);
84         }
85       }, this);
87       this._fireResize();
88     },
90     /**
91      * Used to assign the closest resizable ancestor to this resizable
92      * if the ancestor detects a request for notifications.
93      */
94     assignParentResizable: function(parentResizable) {
95       this._parentResizable = parentResizable;
96     },
98     /**
99      * Used to remove a resizable descendant from the list of descendants
100      * that should be notified of a resize change.
101      */
102     stopResizeNotificationsFor: function(target) {
103       var index = this._interestedResizables.indexOf(target);
105       if (index > -1) {
106         this._interestedResizables.splice(index, 1);
107         this.unlisten(target, 'iron-resize', '_onDescendantIronResize');
108       }
109     },
111     /**
112      * This method can be overridden to filter nested elements that should or
113      * should not be notified by the current element. Return true if an element
114      * should be notified, or false if it should not be notified.
115      *
116      * @param {HTMLElement} element A candidate descendant element that
117      * implements `IronResizableBehavior`.
118      * @return {boolean} True if the `element` should be notified of resize.
119      */
120     resizerShouldNotify: function(element) { return true; },
122     _onDescendantIronResize: function(event) {
123       if (this._notifyingDescendant) {
124         event.stopPropagation();
125         return;
126       }
128       // NOTE(cdata): In ShadowDOM, event retargetting makes echoing of the
129       // otherwise non-bubbling event "just work." We do it manually here for
130       // the case where Polymer is not using shadow roots for whatever reason:
131       if (!Polymer.Settings.useShadow) {
132         this._fireResize();
133       }
134     },
136     _fireResize: function() {
137       this.fire('iron-resize', null, {
138         node: this,
139         bubbles: false
140       });
141     },
143     _onIronRequestResizeNotifications: function(event) {
144       var target = event.path ? event.path[0] : event.target;
146       if (target === this) {
147         return;
148       }
150       if (this._interestedResizables.indexOf(target) === -1) {
151         this._interestedResizables.push(target);
152         this.listen(target, 'iron-resize', '_onDescendantIronResize');
153       }
155       target.assignParentResizable(this);
156       this._notifyDescendant(target);
158       event.stopPropagation();
159     },
161     _parentResizableChanged: function(parentResizable) {
162       if (parentResizable) {
163         window.removeEventListener('resize', this._boundNotifyResize);
164       }
165     },
167     _notifyDescendant: function(descendant) {
168       // NOTE(cdata): In IE10, attached is fired on children first, so it's
169       // important not to notify them if the parent is not attached yet (or
170       // else they will get redundantly notified when the parent attaches).
171       if (!this.isAttached) {
172         return;
173       }
175       this._notifyingDescendant = true;
176       descendant.notifyResize();
177       this._notifyingDescendant = false;
178     }
179   };