| // Copyright 2007 The Closure Library Authors. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS-IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| /** |
| * @fileoverview Popup Emoji Picker implementation. This provides a UI widget |
| * for choosing an emoji from a grid of possible choices. The widget is a popup, |
| * so it is suitable for a toolbar, for instance the TrogEdit toolbar. |
| * |
| * @see ../demos/popupemojipicker.html for an example of how to instantiate |
| * an emoji picker. |
| * |
| * See goog.ui.emoji.EmojiPicker in emojipicker.js for more details. |
| * |
| * Based on goog.ui.PopupColorPicker (popupcolorpicker.js). |
| * |
| * @see ../../demos/popupemojipicker.html |
| */ |
| |
| goog.provide('goog.ui.emoji.PopupEmojiPicker'); |
| |
| goog.require('goog.events.EventType'); |
| goog.require('goog.positioning.AnchoredPosition'); |
| goog.require('goog.positioning.Corner'); |
| goog.require('goog.ui.Component'); |
| goog.require('goog.ui.Popup'); |
| goog.require('goog.ui.emoji.EmojiPicker'); |
| |
| |
| |
| /** |
| * Constructs a popup emoji picker widget. |
| * |
| * @param {string} defaultImgUrl Url of the img that should be used to fill up |
| * the cells in the emoji table, to prevent jittering. Should be the same |
| * size as the emoji. |
| * @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper. |
| * @extends {goog.ui.Component} |
| * @constructor |
| * @final |
| */ |
| goog.ui.emoji.PopupEmojiPicker = |
| function(defaultImgUrl, opt_domHelper) { |
| goog.ui.Component.call(this, opt_domHelper); |
| |
| this.emojiPicker_ = new goog.ui.emoji.EmojiPicker(defaultImgUrl, |
| opt_domHelper); |
| this.addChild(this.emojiPicker_); |
| |
| this.getHandler().listen(this.emojiPicker_, |
| goog.ui.Component.EventType.ACTION, this.onEmojiPicked_); |
| }; |
| goog.inherits(goog.ui.emoji.PopupEmojiPicker, goog.ui.Component); |
| |
| |
| /** |
| * Instance of an emoji picker control. |
| * @type {goog.ui.emoji.EmojiPicker} |
| * @private |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.emojiPicker_ = null; |
| |
| |
| /** |
| * Instance of goog.ui.Popup used to manage the behavior of the emoji picker. |
| * @type {goog.ui.Popup} |
| * @private |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.popup_ = null; |
| |
| |
| /** |
| * Reference to the element that triggered the last popup. |
| * @type {Element} |
| * @private |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.lastTarget_ = null; |
| |
| |
| /** |
| * Whether the emoji picker can accept focus. |
| * @type {boolean} |
| * @private |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.focusable_ = true; |
| |
| |
| /** |
| * If true, then the emojipicker will toggle off if it is already visible. |
| * Default is true. |
| * @type {boolean} |
| * @private |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.toggleMode_ = true; |
| |
| |
| /** |
| * Adds a group of emoji to the picker. |
| * |
| * @param {string|Element} title Title for the group. |
| * @param {Array<Array<?>>} emojiGroup A new group of emoji to be added. Each |
| * internal array contains [emojiUrl, emojiId]. |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.addEmojiGroup = |
| function(title, emojiGroup) { |
| this.emojiPicker_.addEmojiGroup(title, emojiGroup); |
| }; |
| |
| |
| /** |
| * Sets whether the emoji picker should toggle if it is already open. |
| * @param {boolean} toggle The toggle mode to use. |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.setToggleMode = function(toggle) { |
| this.toggleMode_ = toggle; |
| }; |
| |
| |
| /** |
| * Gets whether the emojipicker is in toggle mode |
| * @return {boolean} toggle. |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.getToggleMode = function() { |
| return this.toggleMode_; |
| }; |
| |
| |
| /** |
| * Sets whether loading of images should be delayed until after dom creation. |
| * Thus, this function must be called before {@link #createDom}. If set to true, |
| * the client must call {@link #loadImages} when they wish the images to be |
| * loaded. |
| * |
| * @param {boolean} shouldDelay Whether to delay loading the images. |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.setDelayedLoad = |
| function(shouldDelay) { |
| if (this.emojiPicker_) { |
| this.emojiPicker_.setDelayedLoad(shouldDelay); |
| } |
| }; |
| |
| |
| /** |
| * Sets whether the emoji picker can accept focus. |
| * @param {boolean} focusable Whether the emoji picker should accept focus. |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.setFocusable = function(focusable) { |
| this.focusable_ = focusable; |
| if (this.emojiPicker_) { |
| // TODO(user): In next revision sort the behavior of passing state to |
| // children correctly |
| this.emojiPicker_.setFocusable(focusable); |
| } |
| }; |
| |
| |
| /** |
| * Sets the URL prefix for the emoji URLs. |
| * |
| * @param {string} urlPrefix Prefix that should be prepended to all URLs. |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.setUrlPrefix = function(urlPrefix) { |
| this.emojiPicker_.setUrlPrefix(urlPrefix); |
| }; |
| |
| |
| /** |
| * Sets the location of the tabs in relation to the emoji grids. This should |
| * only be called before the picker has been rendered. |
| * |
| * @param {goog.ui.TabPane.TabLocation} tabLocation The location of the tabs. |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.setTabLocation = |
| function(tabLocation) { |
| this.emojiPicker_.setTabLocation(tabLocation); |
| }; |
| |
| |
| /** |
| * Sets the number of rows per grid in the emoji picker. This should only be |
| * called before the picker has been rendered. |
| * |
| * @param {number} numRows Number of rows per grid. |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.setNumRows = function(numRows) { |
| this.emojiPicker_.setNumRows(numRows); |
| }; |
| |
| |
| /** |
| * Sets the number of columns per grid in the emoji picker. This should only be |
| * called before the picker has been rendered. |
| * |
| * @param {number} numCols Number of columns per grid. |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.setNumColumns = function(numCols) { |
| this.emojiPicker_.setNumColumns(numCols); |
| }; |
| |
| |
| /** |
| * Sets the progressive rendering aspect of this emojipicker. Must be called |
| * before createDom to have an effect. |
| * |
| * @param {boolean} progressive Whether the picker should render progressively. |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.setProgressiveRender = |
| function(progressive) { |
| if (this.emojiPicker_) { |
| this.emojiPicker_.setProgressiveRender(progressive); |
| } |
| }; |
| |
| |
| /** |
| * Returns the number of emoji groups in this picker. |
| * |
| * @return {number} The number of emoji groups in this picker. |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.getNumEmojiGroups = function() { |
| return this.emojiPicker_.getNumEmojiGroups(); |
| }; |
| |
| |
| /** |
| * Causes the emoji imgs to be loaded into the picker. Used for delayed loading. |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.loadImages = function() { |
| if (this.emojiPicker_) { |
| this.emojiPicker_.loadImages(); |
| } |
| }; |
| |
| |
| /** @override */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.createDom = function() { |
| goog.ui.emoji.PopupEmojiPicker.superClass_.createDom.call(this); |
| |
| this.emojiPicker_.createDom(); |
| |
| this.getElement().className = goog.getCssName('goog-ui-popupemojipicker'); |
| this.getElement().appendChild(this.emojiPicker_.getElement()); |
| |
| this.popup_ = new goog.ui.Popup(this.getElement()); |
| this.getElement().unselectable = 'on'; |
| }; |
| |
| |
| /** @override */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.disposeInternal = function() { |
| goog.ui.emoji.PopupEmojiPicker.superClass_.disposeInternal.call(this); |
| this.emojiPicker_ = null; |
| this.lastTarget_ = null; |
| if (this.popup_) { |
| this.popup_.dispose(); |
| this.popup_ = null; |
| } |
| }; |
| |
| |
| /** |
| * Attaches the popup emoji picker to an element. |
| * |
| * @param {Element} element The element to attach to. |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.attach = function(element) { |
| // TODO(user): standardize event type, popups should use MOUSEDOWN, but |
| // currently apps are using click. |
| this.getHandler().listen(element, goog.events.EventType.CLICK, this.show_); |
| }; |
| |
| |
| /** |
| * Detatches the popup emoji picker from an element. |
| * |
| * @param {Element} element The element to detach from. |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.detach = function(element) { |
| this.getHandler().unlisten(element, goog.events.EventType.CLICK, this.show_); |
| }; |
| |
| |
| /** |
| * @return {goog.ui.emoji.EmojiPicker} The emoji picker instance. |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.getEmojiPicker = function() { |
| return this.emojiPicker_; |
| }; |
| |
| |
| /** |
| * Returns whether the Popup dismisses itself when the user clicks outside of |
| * it. |
| * @return {boolean} Whether the Popup autohides on an external click. |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.getAutoHide = function() { |
| return !!this.popup_ && this.popup_.getAutoHide(); |
| }; |
| |
| |
| /** |
| * Sets whether the Popup dismisses itself when the user clicks outside of it - |
| * must be called after the Popup has been created (in createDom()), |
| * otherwise it does nothing. |
| * |
| * @param {boolean} autoHide Whether to autohide on an external click. |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.setAutoHide = function(autoHide) { |
| if (this.popup_) { |
| this.popup_.setAutoHide(autoHide); |
| } |
| }; |
| |
| |
| /** |
| * Returns the region inside which the Popup dismisses itself when the user |
| * clicks, or null if it was not set. Null indicates the entire document is |
| * the autohide region. |
| * @return {Element} The DOM element for autohide, or null if it hasn't been |
| * set. |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.getAutoHideRegion = function() { |
| return this.popup_ && this.popup_.getAutoHideRegion(); |
| }; |
| |
| |
| /** |
| * Sets the region inside which the Popup dismisses itself when the user |
| * clicks - must be called after the Popup has been created (in createDom()), |
| * otherwise it does nothing. |
| * |
| * @param {Element} element The DOM element for autohide. |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.setAutoHideRegion = function(element) { |
| if (this.popup_) { |
| this.popup_.setAutoHideRegion(element); |
| } |
| }; |
| |
| |
| /** |
| * Returns the {@link goog.ui.PopupBase} from this picker. Returns null if the |
| * popup has not yet been created. |
| * |
| * NOTE: This should *ONLY* be called from tests. If called before createDom(), |
| * this should return null. |
| * |
| * @return {goog.ui.PopupBase?} The popup, or null if it hasn't been created. |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.getPopup = function() { |
| return this.popup_; |
| }; |
| |
| |
| /** |
| * @return {Element} The last element that triggered the popup. |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.getLastTarget = function() { |
| return this.lastTarget_; |
| }; |
| |
| |
| /** |
| * @return {goog.ui.emoji.Emoji} The currently selected emoji. |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.getSelectedEmoji = function() { |
| return this.emojiPicker_.getSelectedEmoji(); |
| }; |
| |
| |
| /** |
| * Handles click events on the element this picker is attached to and shows the |
| * emoji picker in a popup. |
| * |
| * @param {goog.events.BrowserEvent} e The browser event. |
| * @private |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.show_ = function(e) { |
| if (this.popup_.isOrWasRecentlyVisible() && this.toggleMode_ && |
| this.lastTarget_ == e.currentTarget) { |
| this.popup_.setVisible(false); |
| return; |
| } |
| |
| this.lastTarget_ = /** @type {Element} */ (e.currentTarget); |
| this.popup_.setPosition(new goog.positioning.AnchoredPosition( |
| this.lastTarget_, goog.positioning.Corner.BOTTOM_LEFT)); |
| this.popup_.setVisible(true); |
| }; |
| |
| |
| /** |
| * Handles selection of an emoji. |
| * |
| * @param {goog.events.Event} e The event object. |
| * @private |
| */ |
| goog.ui.emoji.PopupEmojiPicker.prototype.onEmojiPicked_ = function(e) { |
| this.popup_.setVisible(false); |
| }; |