123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924 |
- goog.provide('goog.ui.CharPicker');
- goog.require('goog.a11y.aria');
- goog.require('goog.a11y.aria.State');
- goog.require('goog.array');
- goog.require('goog.asserts');
- goog.require('goog.dom');
- goog.require('goog.dom.TagName');
- goog.require('goog.dom.classlist');
- goog.require('goog.events');
- goog.require('goog.events.Event');
- goog.require('goog.events.EventHandler');
- goog.require('goog.events.EventType');
- goog.require('goog.events.InputHandler');
- goog.require('goog.events.KeyCodes');
- goog.require('goog.events.KeyHandler');
- goog.require('goog.i18n.CharListDecompressor');
- goog.require('goog.i18n.CharPickerData');
- goog.require('goog.i18n.uChar');
- goog.require('goog.i18n.uChar.NameFetcher');
- goog.require('goog.structs.Set');
- goog.require('goog.style');
- goog.require('goog.ui.Button');
- goog.require('goog.ui.Component');
- goog.require('goog.ui.ContainerScroller');
- goog.require('goog.ui.FlatButtonRenderer');
- goog.require('goog.ui.HoverCard');
- goog.require('goog.ui.LabelInput');
- goog.require('goog.ui.Menu');
- goog.require('goog.ui.MenuButton');
- goog.require('goog.ui.MenuItem');
- goog.require('goog.ui.Tooltip');
- goog.ui.CharPicker = function(
- charPickerData, charNameFetcher, opt_recents, opt_initCategory,
- opt_initSubcategory, opt_rowCount, opt_columnCount, opt_domHelper) {
- goog.ui.Component.call(this, opt_domHelper);
-
- this.charNameFetcher_ = charNameFetcher;
-
- this.data_ = charPickerData;
-
- this.initCategory_ = opt_initCategory || 0;
-
- this.initSubcategory_ = opt_initSubcategory || 0;
-
- this.columnCount_ = opt_columnCount || 10;
-
- this.gridsize_ = (opt_rowCount || 10) * this.columnCount_;
-
- this.recentwidth_ = this.columnCount_ + 1;
-
- this.recents_ = opt_recents || [];
-
- this.eventHandler_ = new goog.events.EventHandler(this);
-
- this.decompressor_ = new goog.i18n.CharListDecompressor();
- };
- goog.inherits(goog.ui.CharPicker, goog.ui.Component);
- goog.ui.CharPicker.prototype.selectedChar_ = null;
- goog.ui.CharPicker.prototype.layoutAlteringChars_ = null;
- goog.ui.CharPicker.prototype.menu_ = null;
- goog.ui.CharPicker.prototype.menubutton_ = null;
- goog.ui.CharPicker.prototype.submenu_ = null;
- goog.ui.CharPicker.prototype.submenubutton_ = null;
- goog.ui.CharPicker.prototype.itempos;
- goog.ui.CharPicker.prototype.items;
- goog.ui.CharPicker.prototype.keyHandler_;
- goog.ui.CharPicker.prototype.category;
- goog.ui.CharPicker.prototype.stick_ = null;
- goog.ui.CharPicker.prototype.stickwrap_ = null;
- goog.ui.CharPicker.prototype.grid_ = null;
- goog.ui.CharPicker.prototype.notice_ = null;
- goog.ui.CharPicker.prototype.recentgrid_ = null;
- goog.ui.CharPicker.prototype.input_ = null;
- goog.ui.CharPicker.prototype.okbutton_ = null;
- goog.ui.CharPicker.prototype.charNameEl_ = null;
- goog.ui.CharPicker.prototype.zoomEl_ = null;
- goog.ui.CharPicker.prototype.unicodeEl_ = null;
- goog.ui.CharPicker.prototype.hc_ = null;
- goog.ui.CharPicker.prototype.getSelectedChar = function() {
- return this.selectedChar_;
- };
- goog.ui.CharPicker.prototype.getRecentChars = function() {
- return this.recents_;
- };
- goog.ui.CharPicker.prototype.createDom = function() {
- goog.ui.CharPicker.superClass_.createDom.call(this);
- this.decorateInternal(
- this.getDomHelper().createElement(goog.dom.TagName.DIV));
- };
- goog.ui.CharPicker.prototype.disposeInternal = function() {
- goog.dispose(this.hc_);
- this.hc_ = null;
- goog.dispose(this.eventHandler_);
- this.eventHandler_ = null;
- goog.ui.CharPicker.superClass_.disposeInternal.call(this);
- };
- goog.ui.CharPicker.prototype.decorateInternal = function(element) {
- goog.ui.CharPicker.superClass_.decorateInternal.call(this, element);
-
-
- var chrs = this.decompressor_.toCharList(':2%C^O80V1H2s2G40Q%s0');
- this.layoutAlteringChars_ = new goog.structs.Set(chrs);
- this.menu_ = new goog.ui.Menu(this.getDomHelper());
- var categories = this.data_.categories;
- for (var i = 0; i < this.data_.categories.length; i++) {
- this.menu_.addChild(this.createMenuItem_(i, categories[i]), true);
- }
- this.menubutton_ = new goog.ui.MenuButton(
- 'Category Menu', this.menu_,
- undefined, this.getDomHelper());
- this.addChild(this.menubutton_, true);
- this.submenu_ = new goog.ui.Menu(this.getDomHelper());
- this.submenubutton_ = new goog.ui.MenuButton(
- 'Subcategory Menu', this.submenu_, undefined,
- this.getDomHelper());
- this.addChild(this.submenubutton_, true);
-
- var gridcontainer = new goog.ui.Component(this.getDomHelper());
- this.addChild(gridcontainer, true);
- var stickwrap = new goog.ui.Component(this.getDomHelper());
- gridcontainer.addChild(stickwrap, true);
- this.stickwrap_ = (stickwrap.getElement());
- var stick = new goog.ui.Component(this.getDomHelper());
- stickwrap.addChild(stick, true);
- this.stick_ = stick.getElement();
- this.grid_ = new goog.ui.Component(this.getDomHelper());
- gridcontainer.addChild(this.grid_, true);
- this.notice_ = new goog.ui.Component(this.getDomHelper());
- this.notice_.setElementInternal(
- this.getDomHelper().createDom(goog.dom.TagName.DIV));
- this.addChild(this.notice_, true);
-
-
- var MSG_CHAR_PICKER_RECENT_SELECTIONS = goog.getMsg('Recent Selections:');
- var recenttext = new goog.ui.Component(this.getDomHelper());
- recenttext.setElementInternal(
- this.getDomHelper().createDom(
- goog.dom.TagName.SPAN, null, MSG_CHAR_PICKER_RECENT_SELECTIONS));
- this.addChild(recenttext, true);
- this.recentgrid_ = new goog.ui.Component(this.getDomHelper());
- this.addChild(this.recentgrid_, true);
-
- var uplus = new goog.ui.Component(this.getDomHelper());
- uplus.setElementInternal(
- this.getDomHelper().createDom(goog.dom.TagName.SPAN, null, 'U+'));
- this.addChild(uplus, true);
-
- var MSG_CHAR_PICKER_HEX_INPUT = goog.getMsg('Hex Input');
- this.input_ =
- new goog.ui.LabelInput(MSG_CHAR_PICKER_HEX_INPUT, this.getDomHelper());
- this.addChild(this.input_, true);
- this.okbutton_ = new goog.ui.Button(
- 'OK', undefined, this.getDomHelper());
- this.addChild(this.okbutton_, true);
- this.okbutton_.setEnabled(false);
- this.zoomEl_ = this.getDomHelper().createDom(
- goog.dom.TagName.DIV,
- {id: 'zoom', className: goog.getCssName('goog-char-picker-char-zoom')});
- this.charNameEl_ = this.getDomHelper().createDom(
- goog.dom.TagName.DIV,
- {id: 'charName', className: goog.getCssName('goog-char-picker-name')});
- this.unicodeEl_ = this.getDomHelper().createDom(
- goog.dom.TagName.DIV,
- {id: 'unicode', className: goog.getCssName('goog-char-picker-unicode')});
- var card = this.getDomHelper().createDom(
- goog.dom.TagName.DIV, {'id': 'preview'}, this.zoomEl_, this.charNameEl_,
- this.unicodeEl_);
- goog.style.setElementShown(card, false);
- this.hc_ = new goog.ui.HoverCard(
- {'DIV': 'char'},
- undefined, this.getDomHelper());
- this.hc_.setElement(card);
- var self = this;
-
- function onBeforeShow() {
- var trigger = self.hc_.getAnchorElement();
- var ch = self.getChar_(trigger);
- if (ch) {
- goog.dom.setTextContent(self.zoomEl_, self.displayChar_(ch));
- goog.dom.setTextContent(self.unicodeEl_, goog.i18n.uChar.toHexString(ch));
-
-
- goog.dom.setTextContent(self.charNameEl_, '');
- self.charNameFetcher_.getName(ch, function(charName) {
- if (charName) {
- goog.dom.setTextContent(self.charNameEl_, charName);
- }
- });
- }
- }
- goog.events.listen(
- this.hc_, goog.ui.HoverCard.EventType.BEFORE_SHOW, onBeforeShow);
- goog.asserts.assert(element);
- goog.dom.classlist.add(element, goog.getCssName('goog-char-picker'));
- goog.dom.classlist.add(
- goog.asserts.assert(this.stick_), goog.getCssName('goog-stick'));
- goog.dom.classlist.add(
- goog.asserts.assert(this.stickwrap_), goog.getCssName('goog-stickwrap'));
- goog.dom.classlist.add(
- goog.asserts.assert(gridcontainer.getElement()),
- goog.getCssName('goog-char-picker-grid-container'));
- goog.dom.classlist.add(
- goog.asserts.assert(this.grid_.getElement()),
- goog.getCssName('goog-char-picker-grid'));
- goog.dom.classlist.add(
- goog.asserts.assert(this.recentgrid_.getElement()),
- goog.getCssName('goog-char-picker-grid'));
- goog.dom.classlist.add(
- goog.asserts.assert(this.recentgrid_.getElement()),
- goog.getCssName('goog-char-picker-recents'));
- goog.dom.classlist.add(
- goog.asserts.assert(this.notice_.getElement()),
- goog.getCssName('goog-char-picker-notice'));
- goog.dom.classlist.add(
- goog.asserts.assert(uplus.getElement()),
- goog.getCssName('goog-char-picker-uplus'));
- goog.dom.classlist.add(
- goog.asserts.assert(this.input_.getElement()),
- goog.getCssName('goog-char-picker-input-box'));
- goog.dom.classlist.add(
- goog.asserts.assert(this.okbutton_.getElement()),
- goog.getCssName('goog-char-picker-okbutton'));
- goog.dom.classlist.add(
- goog.asserts.assert(card), goog.getCssName('goog-char-picker-hovercard'));
- this.hc_.className = goog.getCssName('goog-char-picker-hovercard');
- this.grid_.buttoncount = this.gridsize_;
- this.recentgrid_.buttoncount = this.recentwidth_;
- this.populateGridWithButtons_(this.grid_);
- this.populateGridWithButtons_(this.recentgrid_);
- this.updateGrid_(this.recentgrid_, this.recents_);
- this.setSelectedCategory_(this.initCategory_, this.initSubcategory_);
- new goog.ui.ContainerScroller(this.menu_);
- new goog.ui.ContainerScroller(this.submenu_);
- goog.dom.classlist.add(
- goog.asserts.assert(this.menu_.getElement()),
- goog.getCssName('goog-char-picker-menu'));
- goog.dom.classlist.add(
- goog.asserts.assert(this.submenu_.getElement()),
- goog.getCssName('goog-char-picker-menu'));
- };
- goog.ui.CharPicker.prototype.enterDocument = function() {
- goog.ui.CharPicker.superClass_.enterDocument.call(this);
- var inputkh = new goog.events.InputHandler(this.input_.getElement());
- this.keyHandler_ = new goog.events.KeyHandler(this.input_.getElement());
-
-
-
-
-
- this.eventHandler_
- .listen(
- this.menubutton_, goog.ui.Component.EventType.ACTION,
- goog.events.Event.stopPropagation)
- .listen(
- this.submenubutton_, goog.ui.Component.EventType.ACTION,
- goog.events.Event.stopPropagation)
- .listen(
- this, goog.ui.Component.EventType.ACTION, this.handleSelectedItem_,
- true)
- .listen(
- inputkh, goog.events.InputHandler.EventType.INPUT, this.handleInput_)
- .listen(
- this.keyHandler_, goog.events.KeyHandler.EventType.KEY,
- this.handleEnter_)
- .listen(
- this.recentgrid_, goog.ui.Component.EventType.FOCUS,
- this.handleFocus_)
- .listen(this.grid_, goog.ui.Component.EventType.FOCUS, this.handleFocus_);
- goog.events.listen(
- this.okbutton_.getElement(), goog.events.EventType.MOUSEDOWN,
- this.handleOkClick_, true, this);
- goog.events.listen(
- this.stickwrap_, goog.events.EventType.SCROLL, this.handleScroll_, true,
- this);
- };
- goog.ui.CharPicker.prototype.handleFocus_ = function(e) {
- var button = e.target;
- var element = button.getElement();
- var ch = this.getChar_(element);
-
-
- goog.a11y.aria.setState(element, goog.a11y.aria.State.LABEL, '');
- if (ch) {
-
-
-
-
-
-
-
-
- this.charNameFetcher_.getName(ch, function(charName) {
- if (charName) {
- goog.a11y.aria.setState(element, goog.a11y.aria.State.LABEL, charName);
- }
- });
- }
- };
- goog.ui.CharPicker.prototype.handleScroll_ = function(e) {
- var height = e.target.scrollHeight;
- var top = e.target.scrollTop;
- var itempos =
- Math.ceil(top * this.items.length / (this.columnCount_ * height)) *
- this.columnCount_;
- if (this.itempos != itempos) {
- this.itempos = itempos;
- this.modifyGridWithItems_(this.grid_, this.items, itempos);
- }
- e.stopPropagation();
- };
- goog.ui.CharPicker.prototype.handleSelectedItem_ = function(e) {
- var parent = (e.target).getParent();
- if (parent == this.menu_) {
- this.menu_.setVisible(false);
- this.setSelectedCategory_(e.target.getValue());
- } else if (parent == this.submenu_) {
- this.submenu_.setVisible(false);
- this.setSelectedSubcategory_(e.target.getValue());
- } else if (parent == this.grid_) {
- var button = e.target.getElement();
- this.selectedChar_ = this.getChar_(button);
- this.updateRecents_(this.selectedChar_);
- } else if (parent == this.recentgrid_) {
- this.selectedChar_ = this.getChar_(e.target.getElement());
- }
- };
- goog.ui.CharPicker.prototype.handleInput_ = function(e) {
- var ch = this.getInputChar();
- if (ch) {
- goog.dom.setTextContent(this.zoomEl_, ch);
- goog.dom.setTextContent(this.unicodeEl_, goog.i18n.uChar.toHexString(ch));
- goog.dom.setTextContent(this.charNameEl_, '');
- var coord =
- new goog.ui.Tooltip.ElementTooltipPosition(this.input_.getElement());
- this.hc_.setPosition(coord);
- this.hc_.triggerForElement(this.input_.getElement());
- this.okbutton_.setEnabled(true);
- } else {
- this.hc_.cancelTrigger();
- this.hc_.setVisible(false);
- this.okbutton_.setEnabled(false);
- }
- };
- goog.ui.CharPicker.prototype.handleOkClick_ = function(opt_event) {
- var ch = this.getInputChar();
- if (ch && ch.charCodeAt(0)) {
- this.selectedChar_ = ch;
- this.updateRecents_(ch);
- return true;
- }
- return false;
- };
- goog.ui.CharPicker.prototype.handleEnter_ = function(e) {
- if (e.keyCode == goog.events.KeyCodes.ENTER) {
- return this.handleOkClick_() ?
- this.dispatchEvent(goog.ui.Component.EventType.ACTION) :
- false;
- }
- return false;
- };
- goog.ui.CharPicker.prototype.getChar_ = function(e) {
- return e.getAttribute('char');
- };
- goog.ui.CharPicker.prototype.createMenuItem_ = function(id, caption) {
- var item = new goog.ui.MenuItem(caption, id, this.getDomHelper());
- item.setVisible(true);
- return item;
- };
- goog.ui.CharPicker.prototype.setSelectedCategory_ = function(
- category, opt_subcategory) {
- this.category = category;
- this.menubutton_.setCaption(this.data_.categories[category]);
- while (this.submenu_.hasChildren()) {
- this.submenu_.removeChildAt(0, true).dispose();
- }
- var subcategories = this.data_.subcategories[category];
- for (var i = 0; i < subcategories.length; i++) {
- var item = this.createMenuItem_(i, subcategories[i]);
- this.submenu_.addChild(item, true);
- }
- this.setSelectedSubcategory_(opt_subcategory || 0);
- };
- goog.ui.CharPicker.prototype.setSelectedSubcategory_ = function(subcategory) {
- var subcategories = this.data_.subcategories;
- var name = subcategories[this.category][subcategory];
- this.submenubutton_.setCaption(name);
- this.setSelectedGrid_(this.category, subcategory);
- };
- goog.ui.CharPicker.prototype.setSelectedGrid_ = function(
- category, subcategory) {
- var charLists = this.data_.charList;
- var charListStr = charLists[category][subcategory];
- var content = this.decompressor_.toCharList(charListStr);
- this.charNameFetcher_.prefetch(charListStr);
- this.updateGrid_(this.grid_, content);
- };
- goog.ui.CharPicker.prototype.updateGrid_ = function(grid, items) {
- if (grid == this.grid_) {
-
- var MSG_PLEASE_HOVER =
- goog.getMsg('Please hover over each cell for the character name.');
- goog.dom.setTextContent(
- this.notice_.getElement(),
- this.charNameFetcher_.isNameAvailable(items[0]) ? MSG_PLEASE_HOVER :
- '');
- this.items = items;
- if (this.stickwrap_.offsetHeight > 0) {
- this.stick_.style.height =
- this.stickwrap_.offsetHeight * items.length / this.gridsize_ + 'px';
- } else {
-
-
-
- this.stick_.style.height =
- 3 * this.columnCount_ * items.length / this.gridsize_ + 'em';
- }
- this.stickwrap_.scrollTop = 0;
- }
- this.modifyGridWithItems_(grid, items, 0);
- };
- goog.ui.CharPicker.prototype.modifyGridWithItems_ = function(
- grid, items, start) {
- for (var buttonpos = 0, itempos = start;
- buttonpos < grid.buttoncount && itempos < items.length;
- buttonpos++, itempos++) {
- this.modifyCharNode_(
- (grid.getChildAt(buttonpos)),
- items[itempos]);
- }
- for (; buttonpos < grid.buttoncount; buttonpos++) {
- grid.getChildAt(buttonpos).setVisible(false);
- }
- };
- goog.ui.CharPicker.prototype.populateGridWithButtons_ = function(grid) {
- for (var i = 0; i < grid.buttoncount; i++) {
- var button = new goog.ui.Button(
- ' ', goog.ui.FlatButtonRenderer.getInstance(), this.getDomHelper());
-
-
- button.setDispatchTransitionEvents(goog.ui.Component.State.FOCUSED, true);
- grid.addChild(button, true);
- button.setVisible(false);
- var buttonEl = button.getElement();
- goog.asserts.assert(buttonEl, 'The button DOM element cannot be null.');
-
-
- goog.a11y.aria.removeRole(buttonEl);
- }
- };
- goog.ui.CharPicker.prototype.modifyCharNode_ = function(button, ch) {
- var text = this.displayChar_(ch);
- var buttonEl = button.getElement();
- goog.dom.setTextContent(buttonEl, text);
- buttonEl.setAttribute('char', ch);
- button.setVisible(true);
- };
- goog.ui.CharPicker.prototype.updateRecents_ = function(character) {
- if (character && character.charCodeAt(0) &&
- !goog.array.contains(this.recents_, character)) {
- this.recents_.unshift(character);
- if (this.recents_.length > this.recentwidth_) {
- this.recents_.pop();
- }
- this.updateGrid_(this.recentgrid_, this.recents_);
- }
- };
- goog.ui.CharPicker.prototype.getInputChar = function() {
- var text = this.input_.getValue();
- var code = parseInt(text, 16);
- return (goog.i18n.uChar.fromCharCode(code));
- };
- goog.ui.CharPicker.prototype.displayChar_ = function(ch) {
- return this.layoutAlteringChars_.contains(ch) ? '\u00A0' : ch;
- };
|