From b89a7ee8b956c96a1dcee995ea840feddc5d4b27 Mon Sep 17 00:00:00 2001 From: Pierre Frisch Date: Thu, 22 Dec 2011 07:25:50 -0800 Subject: First commit of Ninja to ninja-internal Signed-off-by: Valerio Virgillito --- node_modules/montage/ui/popup/popup.reel/popup.css | 70 +++ .../montage/ui/popup/popup.reel/popup.html | 54 +++ node_modules/montage/ui/popup/popup.reel/popup.js | 519 +++++++++++++++++++++ 3 files changed, 643 insertions(+) create mode 100755 node_modules/montage/ui/popup/popup.reel/popup.css create mode 100755 node_modules/montage/ui/popup/popup.reel/popup.html create mode 100755 node_modules/montage/ui/popup/popup.reel/popup.js (limited to 'node_modules/montage/ui/popup/popup.reel') diff --git a/node_modules/montage/ui/popup/popup.reel/popup.css b/node_modules/montage/ui/popup/popup.reel/popup.css new file mode 100755 index 00000000..a0af52ba --- /dev/null +++ b/node_modules/montage/ui/popup/popup.reel/popup.css @@ -0,0 +1,70 @@ +/* + This file contains proprietary software owned by Motorola Mobility, Inc.
+ No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.
+ (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. +
*/ +/* these need to be moved to montage.css when that is created */ +.montage-hide { + display: none; +} +.clearfix:after { + visibility: hidden; + display: block; + font-size: 0; + content: " "; + clear: both; + height: 0; +} + + +.montage-off-left { + position: absolute; + top: 0px; + left: -10000px; +} + +.montage-popup-modal-mask { + position: fixed; + background-color: #000; + left: 0; + top: 0; + right: 0; + bottom: 0; + opacity: 0.8; + z-index: 9000; +} + +.montage-popup-container { + background-color: #fff; + border-radius: 5px; + border: 3px solid #000; + +} + +.montage-popup-noborder { + border: 0px; +} + +.montage-modal { + border: 3px solid #ccc; +} + +.montage-popup-container *:focus { + outline: none; +} + +.montage-popup-wrapper { + +} + +.montage-popup-header { + background-color: whitesmoke; + border-bottom: 1px solid #eee; + padding: 5px 15px; +} +.montage-popup-footer { + background-color: whitesmoke; + padding: 10px 15px; + border-top: 1px solid #ddd; + +} diff --git a/node_modules/montage/ui/popup/popup.reel/popup.html b/node_modules/montage/ui/popup/popup.reel/popup.html new file mode 100755 index 00000000..69bf075c --- /dev/null +++ b/node_modules/montage/ui/popup/popup.reel/popup.html @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + diff --git a/node_modules/montage/ui/popup/popup.reel/popup.js b/node_modules/montage/ui/popup/popup.reel/popup.js new file mode 100755 index 00000000..fdfb0ef9 --- /dev/null +++ b/node_modules/montage/ui/popup/popup.reel/popup.js @@ -0,0 +1,519 @@ +/* + This file contains proprietary software owned by Motorola Mobility, Inc.
+ No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.
+ (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. +
*/ + +/** + @module "montage/ui/popup/popup.reel" + @requires montage/core/core + @requires montage/ui/component +*/ +var Montage = require("montage").Montage, + Component = require("ui/component").Component; + +/** + @class module:"montage/ui/popup.reel".Popup + @extends module:montage/ui/component.Component +*/ + +var Popup = exports.Popup = Montage.create(Component, { /** @lends module:"module/ui/popup/popup.reel".Popup */ + + hasTemplate: {value: true}, + + // anchor element to which this popup must be anchored to + anchor: {value: null}, + + // A Delegate to control positioning (and other features, in future) of the popup in a custom manner + delegate: {value: null}, + + contentEl: { + value: null + }, +/** + Description TODO + @type {Property} + @default {Container} null + */ + containerEl: { + value: null + }, + +/** + Description TODO + @private +*/ + _pointer: { + value: true + }, +/** + Description TODO + @type {Function} + @default {Boolean} true + */ + pointer: { + get: function() { + return this._pointer; + }, + set: function(value) { + if (this._pointer !== value) { + this._pointer = value; + this.needsDraw = true; + } + } + }, +/** + Description TODO + @private +*/ + _boxed: { + value: true + }, +/** + Description TODO + @type {Function} + @default {Boolean} true + */ + boxed: { + get: function() { + return this._boxed; + }, + set: function(value) { + if (this._boxed !== value) { + this._boxed = value; + this.needsDraw = true; + } + } + }, +/** + Description TODO + @private +*/ + _slot: {value: null}, +/** + Description TODO + @type {Function} + @default null + */ + slot: { + get: function() { + return this._slot; + }, + set: function(val) { + this._slot = val; + if (this.content) { + this._slot.content = this.content; + } + } + }, +/** + Description TODO + @private +*/ + _content: {value: null}, +/** + Description TODO + @type {Function} + @default null + */ + content: { + serializable: true, + get: function() { + return this._content; + }, + set: function(value) { + if (this._content !== value && this.slot) { + this.slot.content = value; + } + this._content = value; + // set the popup property of the content. + this._content.popup = this; + this.needsDraw = true; + } + }, +/** + Description TODO + @private +*/ + _modal: { value: false }, +/** + Description TODO + @type {Function} + @default {Boolean} false + */ + modal: { + get: function() { + return this._modal; + }, + set: function(value) { + // force this to be a boolean + value = !!value; + + if (this._modal !== value) { + this._modal = value; + this.needsDraw = true; + } + } + }, + + // An Object wtih values {top, left}. Set it only if the popup should display at a + // given location instead of anchoring it to a anchor element or at the center of the screen. + _position: {value: null}, + position: { + get: function() { + return this._position; + }, + set: function(pos) { + this._position = pos; + //this.needsDraw = true; + } + }, + + autoDismiss: { value: 0 }, + + _displayed: { value: false }, + displayed: { + get: function() { + return this._displayed; + }, + set: function(value) { + if (this._displayed !== value) { + this.needsDraw = true; + } + this._displayed = value; + + } + }, +/** + Description TODO + @function + */ + prepareForDraw: { + value: function() { + + } + }, + + _popupSlot: { + value: null + }, + + _modalDialogMask: { + value: null + }, + + + /** + @private + */ + _getPosition: { + value: function(obj) { + var curleft = 0, curtop = 0, curHt = 0, curWd = 0; + if (obj.offsetParent) { + do { + curleft += obj.offsetLeft; + curtop += obj.offsetTop; + curHt += obj.offsetHeight; + curWd += obj.offsetWidth; + } while ((obj = obj.offsetParent)); + } + return [curleft,curtop, curHt, curWd]; + + } + }, + + _calculatePosition: { + value: function() { + var pos, delegate = this.delegate, anchor = this.anchor, type = (this.type || 'custom'); + + if(delegate && (typeof delegate.positionPopup === 'function')) { + var anchorPosition; + if(anchor) { + anchorPosition = this._getPosition(anchor); + } + pos = delegate.positionPopup(this, anchor, anchorPosition); + } else { + // @todo - advanced positioning support + var $el = this.contentEl || this.content.element; + var elHeight = parseFloat($el.style.height || 0) || $el.offsetHeight || 0; + var elWidth = parseFloat($el.style.width || 0) || $el.offsetWidth || 0; + + // @todo - to get the window from application + var viewportHeight = window.innerHeight; + var viewportWidth = window.innerWidth; + + if (anchor) { + if (anchor.nodeName) { + // if anchor is an element + var elPosition = this._getPosition(anchor); + var tgtHeight = parseFloat(anchor.style.height || 0) || anchor.offsetHeight || 0; + var tgtWidth = parseFloat(anchor.style.width || 0) || anchor.offsetWidth || 0; + + pos = { + top: elPosition[1] + tgtHeight + 20 /* pointer */, + left: elPosition[0] + (tgtWidth / 2) - (elWidth / 2) + }; + + if (pos.left < 0) { + pos.left = elPosition[0]; + this._showHidePointer(false); + // dont show the pointer - @todo - support pointer arrow at different parts of the popup + } + } else { + // anchor is absolute position {top, left} + pos = anchor; + } + } else { + // position it at top or center + // for now, just show it at center + pos = { + top: (viewportHeight / 2 - (elHeight / 2)), + left: (viewportWidth / 2 - (elWidth / 2)) + }; + } + } + return pos; + } + }, + + _positionPopup: { + value: function() { + //console.log('--> position popup'); + var pos = this.position; + var popupSlot = this._popupSlot; + + if(pos) { + if (pos.top) { + popupSlot.element.style.top = pos.top + 'px'; + } + if (pos.left) { + popupSlot.element.style.left = pos.left + 'px'; + } + if (pos.right) { + popupSlot.element.style.right = pos.right + 'px'; + } + if (pos.bottom) { + popupSlot.element.style.bottom = pos.bottom + 'px'; + } + } + } + }, + + _createModalMask: { + value: function() { + var el = document.createElement('div'); + el.classList.add('montage-popup-modal-mask'); + el.style['z-index'] = 9000; + el.classList.add('montage-hide'); + document.body.appendChild(el); + return el; + } + }, + + _showHidePointer: { + value: function(showTip) { + } + }, + + _addEventListeners: { + value: function() { + if (window.Touch) { + this.element.ownerDocument.addEventListener('touchstart', this, false); + } else { + this.element.ownerDocument.addEventListener('mousedown', this, false); + this.element.ownerDocument.addEventListener('keyup', this, false); + } + window.addEventListener('resize', this); + } + }, + + _removeEventListeners: { + value: function() { + if (window.Touch) { + this.element.ownerDocument.removeEventListener('touchstart', this, false); + } else { + this.element.ownerDocument.removeEventListener('mousedown', this, false); + this.element.ownerDocument.removeEventListener('keyup', this, false); + } + window.removeEventListener('resize', this); + } + }, + + show: { + value: function() { + var type = this.type || "custom", + self = this; + this.application.getPopupSlot(type, this, function(slot) { + self._popupSlot = slot; + self.displayed = true; + self._addEventListeners(); + }); + } + }, + + hide: { + value: function() { + this._removeEventListeners(); + + var type = this.type || "custom", + self = this; + this.application.getPopupSlot(type, null, function() { + self.displayed = false; + }); + } + }, + + + draw: { + value: function() { + if (this.displayed) { + // custom, alert, confirm, notify + // only one popup of each type can be displayed at the same time + // kishore - does the above restriction make sense ? should we restrict it ? + + if(this.modal === true) { + this._modalDialogMask = document.querySelector('.montage-popup-modal-mask'); + this._modalDialogMask = this._modalDialogMask || this._createModalMask(); + this.element.classList.add('montage-modal'); + } else { + this.element.classList.remove('montage-modal'); + } + + // @todo - positioning should happen inside the draw. Looks like this is only possible + // with a double draw where we calculate the position on didDraw and position it in draw(). + // For the first release, we position inside the didDraw + //this._positionPopup(); + + this.element.classList.remove('montage-hide'); + this.content.element.style.display = 'block'; + this.content.element.classList.remove('montage-hide'); + // TODO do we want the panel to be focusable? + // this.content.element.setAttribute("tabindex", "0"); // Make the alert focusable + + if (this.autoDismiss) { + var self = this; + setTimeout(function() { + self.hide(); + }, this.autoDismiss); + } + } else { + if (!this.element.classList.contains('montage-hide')) { + this.element.classList.add('montage-hide'); + } + this.content.element.classList.add('montage-hide'); + if(this._popupSlot) { + this._popupSlot.content = null; + } + } + } + }, +/** + Description TODO + @function + */ + didDraw: { + value: function() { + if (this._displayed) { + this.content.element.focus(); + if(this.modal === true) { + this._modalDialogMask.classList.remove('montage-hide'); + } + + this.position = this.position || this._calculatePosition(); + this._positionPopup(); + + } else { + if(this.modal === true) { + this._modalDialogMask.classList.add('montage-hide'); + } + } + // kishore: invoking this event in didDraw as we need the dimensions of the content. + // Inside the draw(), the display is set to none at the top level and hence + // offsetWidth and Height are always 0 + var evt = document.createEvent("CustomEvent"); + evt.initCustomEvent((this._displayed === true ? 'show' : 'hide'), true, true, this); + this.dispatchEvent(evt); + + } + }, + + getZIndex: { + value: function(elem) { + + var position, value, zIndex; + while (elem && elem !== document) { + position = elem.style.position; + if (position === "absolute" || position === "relative" || position === "fixed") { + // webkit returns a string for zindex value and "" if zindex is not available + zIndex = elem.style['z-index']; + value = parseInt(zIndex, 10); + if (!isNaN(value) && value !== 0) { + return value; + } + } + elem = elem.parentNode; + } + return 0; + } + }, +/** + Description TODO + @private +*/ + _handleTouchMouseup: { + value: function(event) { + var targetzIndex = this.getZIndex(event.target), + zIndex = this.getZIndex(this.element); + + if (this.displayed === true && targetzIndex < zIndex) { + if (this.modal === true) { + + } else { + // hide the dialog when user clicks outside it + this.displayed = false; + } + } + } + }, + + _timeoutId: {value: null}, + handleResize: { + value: function(e) { + //console.log('window resize'); + var self = this; + if(this.displayed === true) { + // an optimization to call positionPopup fewer times + window.clearTimeout(this._timeoutId); + this._timeoutId = setTimeout(function() { + //self._positionPopup(); + self.position = self._calculatePosition(); + self._positionPopup(); + }, 100); + } + } + }, + handleMousedown: { + value: function(event) { + this._handleTouchMouseup(event); + } + }, +/** + Description TODO + @function + @param {Event} event The event. + */ + handleTouchstart: { + value: function(event) { + this._handleTouchMouseup(event); + } + }, + handleKeyup: { + value: function(e) { + // default handling of the keyup event. Content inside the popup could + // handle the event optionally for custom behavior + if(this.displayed === true && !this.modal && e.keyCode === 27 /* ESC key */) { + this.hide(); + } + } + } +}); -- cgit v1.2.3