UNPKG

five-bells-visualization

Version:
248 lines (216 loc) 8.57 kB
<!-- Copyright (c) 2014 The Polymer Project Authors. All rights reserved. This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt Code distributed by Google as part of the polymer project is also subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt --> <!-- * @group Polymer Mixins --> <link rel="import" href="../polymer/polymer.html"> <script> (function(scope) { /** `Polymer.CoreResizable` and `Polymer.CoreResizer` are a set of mixins that can be used in Polymer elements to coordinate the flow of resize events between "resizers" (elements that control the size or hidden state of their children) and "resizables" (elements that need to be notified when they are resized or un-hidden by their parents in order to take action on their new measurements). Elements that perform measurement should add the `Core.Resizable` mixin to their Polymer prototype definition and listen for the `core-resize` event on themselves. This event will be fired when they become showing after having been hidden, when they are resized explicitly by a `CoreResizer`, or when the window has been resized. Note, the `core-resize` event is non-bubbling. `CoreResizable`'s must manually call the `resizableAttachedHandler` from the element's `attached` callback and `resizableDetachedHandler` from the element's `detached` callback. @element CoreResizable @status beta @homepage github.io */ scope.CoreResizable = { /** * User must call from `attached` callback * * @method resizableAttachedHandler */ resizableAttachedHandler: function(cb) { cb = cb || this._notifyResizeSelf; this.async(function() { var detail = {callback: cb, hasParentResizer: false}; this.fire('core-request-resize', detail); if (!detail.hasParentResizer) { this._boundWindowResizeHandler = cb.bind(this); // log('adding window resize handler', null, this); window.addEventListener('resize', this._boundWindowResizeHandler); } }.bind(this)); }, /** * User must call from `detached` callback * * @method resizableDetachedHandler */ resizableDetachedHandler: function() { this.fire('core-request-resize-cancel', null, this, false); if (this._boundWindowResizeHandler) { window.removeEventListener('resize', this._boundWindowResizeHandler); } }, // Private: fire non-bubbling resize event to self; returns whether // preventDefault was called, indicating that children should not // be resized _notifyResizeSelf: function() { return this.fire('core-resize', null, this, false).defaultPrevented; } }; /** `Polymer.CoreResizable` and `Polymer.CoreResizer` are a set of mixins that can be used in Polymer elements to coordinate the flow of resize events between "resizers" (elements that control the size or hidden state of their children) and "resizables" (elements that need to be notified when they are resized or un-hidden by their parents in order to take action on their new measurements). Elements that cause their children to be resized (e.g. a splitter control) or hide/show their children (e.g. overlay) should add the `Core.CoreResizer` mixin to their Polymer prototype definition and then call `this.notifyResize()` any time the element resizes or un-hides its children. `CoreResizer`'s must manually call the `resizerAttachedHandler` from the element's `attached` callback and `resizerDetachedHandler` from the element's `detached` callback. Note: `CoreResizer` extends `CoreResizable`, and can listen for the `core-resize` event on itself if it needs to perform resize work on itself before notifying children. In this case, returning `false` from the `core-resize` event handler (or calling `preventDefault` on the event) will prevent notification of children if required. @element CoreResizer @extends CoreResizable @status beta @homepage github.io */ scope.CoreResizer = Polymer.mixin({ /** * User must call from `attached` callback * * @method resizerAttachedHandler */ resizerAttachedHandler: function() { this.resizableAttachedHandler(this.notifyResize); this._boundResizeRequested = this._boundResizeRequested || this._handleResizeRequested.bind(this); var listener; if (this.resizerIsPeer) { listener = this.parentElement || (this.parentNode && this.parentNode.host); listener._resizerPeers = listener._resizerPeers || []; listener._resizerPeers.push(this); } else { listener = this; } listener.addEventListener('core-request-resize', this._boundResizeRequested); this._resizerListener = listener; }, /** * User must call from `detached` callback * * @method resizerDetachedHandler */ resizerDetachedHandler: function() { this.resizableDetachedHandler(); this._resizerListener.removeEventListener('core-request-resize', this._boundResizeRequested); }, /** * User should call when resizing or un-hiding children * * @method notifyResize */ notifyResize: function() { // Notify self if (!this._notifyResizeSelf()) { // Notify requestors if default was not prevented var r = this.resizeRequestors; if (r) { for (var i=0; i<r.length; i++) { var ri = r[i]; if (!this.resizerShouldNotify || this.resizerShouldNotify(ri.target)) { // log('notifying resize', null, ri.target, true); ri.callback.apply(ri.target); // logEnd(); } } } } }, /** * User should implement to introduce filtering when notifying children. * Generally, children that are hidden by the CoreResizer (e.g. non-active * pages) need not be notified during resize, since they will be notified * again when becoming un-hidden. * * Return `true` if CoreResizable passed as argument should be notified of * resize. * * @method resizeerShouldNotify * @param {Element} el */ // resizeerShouldNotify: function(el) { } // User to implement if needed /** * Set to `true` if the resizer is actually a peer to the elements it * resizes (e.g. splitter); in this case it will listen for resize requests * events from its peers on its parent. * * @property resizerIsPeer * @type Boolean * @default false */ // Private: Handle requests for resize _handleResizeRequested: function(e) { var target = e.path[0]; if ((target == this) || (target == this._resizerListener) || (this._resizerPeers && this._resizerPeers.indexOf(target) < 0)) { return; } // log('resize requested', target, this); if (!this.resizeRequestors) { this.resizeRequestors = []; } this.resizeRequestors.push({target: target, callback: e.detail.callback}); target.addEventListener('core-request-resize-cancel', this._cancelResizeRequested.bind(this)); e.detail.hasParentResizer = true; e.stopPropagation(); }, // Private: Handle cancellation requests for resize _cancelResizeRequested: function(e) { // Exit early if we're already out of the DOM (resizeRequestors will already be null) if (this.resizeRequestors) { for (var i=0; i<this.resizeRequestors.length; i++) { if (this.resizeRequestors[i].target == e.target) { // log('resizeCanceled', e.target, this); this.resizeRequestors.splice(i, 1); break; } } } } }, Polymer.CoreResizable); // function prettyName(el) { // return el.localName + (el.id ? '#' : '') + el.id; // } // function log(what, from, to, group) { // var args = [what]; // if (from) { // args.push('from ' + prettyName(from)); // } // if (to) { // args.push('to ' + prettyName(to)); // } // if (group) { // console.group.apply(console, args); // } else { // console.log.apply(console, args); // } // } // function logEnd() { // console.groupEnd(); // } })(Polymer); </script>