Update wmts-hidpi, add nicer-api-docs
This commit is contained in:
@@ -0,0 +1,672 @@
|
||||
// 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 Plain text spell checker implementation.
|
||||
*
|
||||
* @author eae@google.com (Emil A Eklund)
|
||||
* @author sergeys@google.com (Sergey Solyanik)
|
||||
* @see ../demos/plaintextspellchecker.html
|
||||
*/
|
||||
|
||||
goog.provide('goog.ui.PlainTextSpellChecker');
|
||||
|
||||
goog.require('goog.Timer');
|
||||
goog.require('goog.a11y.aria');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.events.EventHandler');
|
||||
goog.require('goog.events.EventType');
|
||||
goog.require('goog.events.KeyCodes');
|
||||
goog.require('goog.events.KeyHandler');
|
||||
goog.require('goog.spell.SpellCheck');
|
||||
goog.require('goog.style');
|
||||
goog.require('goog.ui.AbstractSpellChecker');
|
||||
goog.require('goog.ui.Component');
|
||||
goog.require('goog.userAgent');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Plain text spell checker implementation.
|
||||
*
|
||||
* @param {goog.spell.SpellCheck} handler Instance of the SpellCheckHandler
|
||||
* support object to use. A single instance can be shared by multiple
|
||||
* editor components.
|
||||
* @param {goog.dom.DomHelper=} opt_domHelper Optional DOM helper.
|
||||
* @constructor
|
||||
* @extends {goog.ui.AbstractSpellChecker}
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker = function(handler, opt_domHelper) {
|
||||
goog.ui.AbstractSpellChecker.call(this, handler, opt_domHelper);
|
||||
|
||||
/**
|
||||
* Correction UI container.
|
||||
* @type {HTMLDivElement}
|
||||
* @private
|
||||
*/
|
||||
this.overlay_ = /** @type {HTMLDivElement} */
|
||||
(this.getDomHelper().createDom('div'));
|
||||
goog.style.setPreWrap(this.overlay_);
|
||||
|
||||
/**
|
||||
* Bound async function (to avoid rebinding it on every call).
|
||||
* @type {Function}
|
||||
* @private
|
||||
*/
|
||||
this.boundContinueAsyncFn_ = goog.bind(this.continueAsync_, this);
|
||||
|
||||
/**
|
||||
* Regular expression for matching line breaks.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
this.endOfLineMatcher_ = new RegExp('(.*)(\n|\r\n){0,1}', 'g');
|
||||
};
|
||||
goog.inherits(goog.ui.PlainTextSpellChecker, goog.ui.AbstractSpellChecker);
|
||||
|
||||
|
||||
/**
|
||||
* Class name for invalid words.
|
||||
* @type {string}
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.invalidWordClassName =
|
||||
goog.getCssName('goog-spellcheck-invalidword');
|
||||
|
||||
|
||||
/**
|
||||
* Class name for corrected words.
|
||||
* @type {string}
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.correctedWordClassName =
|
||||
goog.getCssName('goog-spellcheck-correctedword');
|
||||
|
||||
|
||||
/**
|
||||
* Class name for correction pane.
|
||||
* @type {string}
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.correctionPaneClassName =
|
||||
goog.getCssName('goog-spellcheck-correctionpane');
|
||||
|
||||
|
||||
/**
|
||||
* Number of words to scan to precharge the dictionary.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.dictionaryPreScanSize_ = 1000;
|
||||
|
||||
|
||||
/**
|
||||
* Size of window. Used to check if a resize operation actually changed the size
|
||||
* of the window.
|
||||
* @type {goog.math.Size|undefined}
|
||||
* @private
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.winSize_;
|
||||
|
||||
|
||||
/**
|
||||
* Numeric Id of the element that has focus. 0 when not set.
|
||||
*
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.ui.AbstractSpellChecker.prototype.focusedElementId_ = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Event handler for listening to events without leaking.
|
||||
* @type {goog.events.EventHandler|undefined}
|
||||
* @private
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.eventHandler_;
|
||||
|
||||
|
||||
/**
|
||||
* The object handling keyboard events.
|
||||
* @type {goog.events.KeyHandler|undefined}
|
||||
* @private
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.keyHandler_;
|
||||
|
||||
|
||||
/**
|
||||
* Creates the initial DOM representation for the component.
|
||||
* @override
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.createDom = function() {
|
||||
this.setElementInternal(this.getDomHelper().createElement('textarea'));
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.ui.PlainTextSpellChecker.prototype.enterDocument = function() {
|
||||
goog.ui.PlainTextSpellChecker.superClass_.enterDocument.call(this);
|
||||
|
||||
this.eventHandler_ = new goog.events.EventHandler(this);
|
||||
this.keyHandler_ = new goog.events.KeyHandler(this.overlay_);
|
||||
|
||||
this.initSuggestionsMenu();
|
||||
this.initAccessibility_();
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.ui.PlainTextSpellChecker.prototype.exitDocument = function() {
|
||||
goog.ui.PlainTextSpellChecker.superClass_.exitDocument.call(this);
|
||||
|
||||
if (this.eventHandler_) {
|
||||
this.eventHandler_.dispose();
|
||||
this.eventHandler_ = undefined;
|
||||
}
|
||||
if (this.keyHandler_) {
|
||||
this.keyHandler_.dispose();
|
||||
this.keyHandler_ = undefined;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Initializes suggestions menu. Populates menu with separator and ignore option
|
||||
* that are always valid. Suggestions are later added above the separator.
|
||||
* @override
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.initSuggestionsMenu = function() {
|
||||
goog.ui.PlainTextSpellChecker.superClass_.initSuggestionsMenu.call(this);
|
||||
this.eventHandler_.listen(/** @type {goog.ui.PopupMenu} */ (this.getMenu()),
|
||||
goog.ui.Component.EventType.BLUR, this.onCorrectionBlur_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks spelling for all text and displays correction UI.
|
||||
* @override
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.check = function() {
|
||||
var text = this.getElement().value;
|
||||
this.getElement().readOnly = true;
|
||||
|
||||
// Prepare and position correction UI.
|
||||
this.overlay_.innerHTML = '';
|
||||
this.overlay_.className = this.correctionPaneClassName;
|
||||
if (this.getElement().parentNode != this.overlay_.parentNode) {
|
||||
this.getElement().parentNode.appendChild(this.overlay_);
|
||||
}
|
||||
goog.style.setElementShown(this.overlay_, false);
|
||||
|
||||
this.preChargeDictionary_(text);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Final stage of spell checking - displays the correction UI.
|
||||
* @private
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.finishCheck_ = function() {
|
||||
// Show correction UI.
|
||||
this.positionOverlay_();
|
||||
goog.style.setElementShown(this.getElement(), false);
|
||||
goog.style.setElementShown(this.overlay_, true);
|
||||
|
||||
var eh = this.eventHandler_;
|
||||
eh.listen(this.overlay_, goog.events.EventType.CLICK, this.onWordClick_);
|
||||
eh.listen(/** @type {goog.events.KeyHandler} */ (this.keyHandler_),
|
||||
goog.events.KeyHandler.EventType.KEY, this.handleOverlayKeyEvent);
|
||||
|
||||
// The position and size of the overlay element needs to be recalculated if
|
||||
// the browser window is resized.
|
||||
var win = goog.dom.getWindow(this.getDomHelper().getDocument()) || window;
|
||||
this.winSize_ = goog.dom.getViewportSize(win);
|
||||
eh.listen(win, goog.events.EventType.RESIZE, this.onWindowResize_);
|
||||
|
||||
goog.ui.PlainTextSpellChecker.superClass_.check.call(this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Start the scan after the dictionary was loaded.
|
||||
*
|
||||
* @param {string} text text to process.
|
||||
* @private
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.preChargeDictionary_ = function(text) {
|
||||
this.eventHandler_.listen(this.spellCheck,
|
||||
goog.spell.SpellCheck.EventType.READY, this.onDictionaryCharged_, true);
|
||||
|
||||
this.populateDictionary(text, this.dictionaryPreScanSize_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Loads few initial dictionary words into the cache.
|
||||
*
|
||||
* @param {goog.events.Event} e goog.spell.SpellCheck.EventType.READY event.
|
||||
* @private
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.onDictionaryCharged_ = function(e) {
|
||||
e.stopPropagation();
|
||||
this.eventHandler_.unlisten(this.spellCheck,
|
||||
goog.spell.SpellCheck.EventType.READY, this.onDictionaryCharged_, true);
|
||||
this.checkAsync_(this.getElement().value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Processes the included and skips the excluded text ranges.
|
||||
* @return {goog.ui.AbstractSpellChecker.AsyncResult} Whether the spell
|
||||
* checking is pending or done.
|
||||
* @private
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.spellCheckLoop_ = function() {
|
||||
for (var i = this.textArrayIndex_; i < this.textArray_.length; ++i) {
|
||||
var text = this.textArray_[i];
|
||||
if (this.textArrayProcess_[i]) {
|
||||
var result = this.processTextAsync(this.overlay_, text);
|
||||
if (result == goog.ui.AbstractSpellChecker.AsyncResult.PENDING) {
|
||||
this.textArrayIndex_ = i + 1;
|
||||
goog.Timer.callOnce(this.boundContinueAsyncFn_);
|
||||
return result;
|
||||
}
|
||||
} else {
|
||||
this.processRange(this.overlay_, text);
|
||||
}
|
||||
}
|
||||
|
||||
this.textArray_ = [];
|
||||
this.textArrayProcess_ = [];
|
||||
|
||||
return goog.ui.AbstractSpellChecker.AsyncResult.DONE;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Breaks text into included and excluded ranges using the marker RegExp
|
||||
* supplied by the caller.
|
||||
*
|
||||
* @param {string} text text to process.
|
||||
* @private
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.initTextArray_ = function(text) {
|
||||
if (!this.excludeMarker) {
|
||||
this.textArray_ = [text];
|
||||
this.textArrayProcess_ = [true];
|
||||
return;
|
||||
}
|
||||
|
||||
this.textArray_ = [];
|
||||
this.textArrayProcess_ = [];
|
||||
this.excludeMarker.lastIndex = 0;
|
||||
var stringSegmentStart = 0;
|
||||
var result;
|
||||
while (result = this.excludeMarker.exec(text)) {
|
||||
if (result[0].length == 0) {
|
||||
break;
|
||||
}
|
||||
var excludedRange = result[0];
|
||||
var includedRange = text.substr(stringSegmentStart, result.index -
|
||||
stringSegmentStart);
|
||||
if (includedRange) {
|
||||
this.textArray_.push(includedRange);
|
||||
this.textArrayProcess_.push(true);
|
||||
}
|
||||
this.textArray_.push(excludedRange);
|
||||
this.textArrayProcess_.push(false);
|
||||
stringSegmentStart = this.excludeMarker.lastIndex;
|
||||
}
|
||||
|
||||
var leftoverText = text.substr(stringSegmentStart);
|
||||
if (leftoverText) {
|
||||
this.textArray_.push(leftoverText);
|
||||
this.textArrayProcess_.push(true);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Starts asynchrnonous spell checking.
|
||||
*
|
||||
* @param {string} text text to process.
|
||||
* @private
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.checkAsync_ = function(text) {
|
||||
this.initializeAsyncMode();
|
||||
this.initTextArray_(text);
|
||||
this.textArrayIndex_ = 0;
|
||||
if (this.spellCheckLoop_() ==
|
||||
goog.ui.AbstractSpellChecker.AsyncResult.PENDING) {
|
||||
return;
|
||||
}
|
||||
this.finishAsyncProcessing();
|
||||
this.finishCheck_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Continues asynchrnonous spell checking.
|
||||
* @private
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.continueAsync_ = function() {
|
||||
// First finish with the current segment.
|
||||
var result = this.continueAsyncProcessing();
|
||||
if (result == goog.ui.AbstractSpellChecker.AsyncResult.PENDING) {
|
||||
goog.Timer.callOnce(this.boundContinueAsyncFn_);
|
||||
return;
|
||||
}
|
||||
if (this.spellCheckLoop_() ==
|
||||
goog.ui.AbstractSpellChecker.AsyncResult.PENDING) {
|
||||
return;
|
||||
}
|
||||
this.finishAsyncProcessing();
|
||||
this.finishCheck_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Processes word.
|
||||
*
|
||||
* @param {Node} node Node containing word.
|
||||
* @param {string} word Word to process.
|
||||
* @param {goog.spell.SpellCheck.WordStatus} status Status of word.
|
||||
* @override
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.processWord = function(node, word,
|
||||
status) {
|
||||
node.appendChild(this.createWordElement(word, status));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Processes range of text - recognized words and separators.
|
||||
*
|
||||
* @param {Node} node Node containing separator.
|
||||
* @param {string} text text to process.
|
||||
* @override
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.processRange = function(node, text) {
|
||||
this.endOfLineMatcher_.lastIndex = 0;
|
||||
var result;
|
||||
while (result = this.endOfLineMatcher_.exec(text)) {
|
||||
if (result[0].length == 0) {
|
||||
break;
|
||||
}
|
||||
node.appendChild(this.getDomHelper().createTextNode(result[1]));
|
||||
if (result[2]) {
|
||||
node.appendChild(this.getDomHelper().createElement('br'));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Hides correction UI.
|
||||
* @override
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.resume = function() {
|
||||
var wasVisible = this.isVisible();
|
||||
|
||||
goog.ui.PlainTextSpellChecker.superClass_.resume.call(this);
|
||||
|
||||
goog.style.setElementShown(this.overlay_, false);
|
||||
goog.style.setElementShown(this.getElement(), true);
|
||||
this.getElement().readOnly = false;
|
||||
|
||||
if (wasVisible) {
|
||||
this.getElement().value = goog.dom.getRawTextContent(this.overlay_);
|
||||
this.overlay_.innerHTML = '';
|
||||
|
||||
var eh = this.eventHandler_;
|
||||
eh.unlisten(this.overlay_, goog.events.EventType.CLICK, this.onWordClick_);
|
||||
eh.unlisten(/** @type {goog.events.KeyHandler} */ (this.keyHandler_),
|
||||
goog.events.KeyHandler.EventType.KEY, this.handleOverlayKeyEvent);
|
||||
|
||||
var win = goog.dom.getWindow(this.getDomHelper().getDocument()) || window;
|
||||
eh.unlisten(win, goog.events.EventType.RESIZE, this.onWindowResize_);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns desired element properties for the specified status.
|
||||
*
|
||||
* @param {goog.spell.SpellCheck.WordStatus} status Status of word.
|
||||
* @return {Object} Properties to apply to word element.
|
||||
* @override
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.getElementProperties =
|
||||
function(status) {
|
||||
if (status == goog.spell.SpellCheck.WordStatus.INVALID) {
|
||||
return {'class': this.invalidWordClassName};
|
||||
} else if (status == goog.spell.SpellCheck.WordStatus.CORRECTED) {
|
||||
return {'class': this.correctedWordClassName};
|
||||
}
|
||||
return {'class': ''};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handles the click events.
|
||||
*
|
||||
* @param {goog.events.BrowserEvent} event Event object.
|
||||
* @private
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.onWordClick_ = function(event) {
|
||||
if (event.target.className == this.invalidWordClassName ||
|
||||
event.target.className == this.correctedWordClassName) {
|
||||
this.showSuggestionsMenu(/** @type {Element} */ (event.target), event);
|
||||
|
||||
// Prevent document click handler from closing the menu.
|
||||
event.stopPropagation();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handles window resize events.
|
||||
*
|
||||
* @param {goog.events.BrowserEvent} event Event object.
|
||||
* @private
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.onWindowResize_ = function(event) {
|
||||
var win = goog.dom.getWindow(this.getDomHelper().getDocument()) || window;
|
||||
var size = goog.dom.getViewportSize(win);
|
||||
|
||||
if (size.width != this.winSize_.width ||
|
||||
size.height != this.winSize_.height) {
|
||||
goog.style.setElementShown(this.overlay_, false);
|
||||
goog.style.setElementShown(this.getElement(), true);
|
||||
|
||||
// IE requires a slight delay, allowing the resize operation to take effect.
|
||||
if (goog.userAgent.IE) {
|
||||
goog.Timer.callOnce(this.resizeOverlay_, 100, this);
|
||||
} else {
|
||||
this.resizeOverlay_();
|
||||
}
|
||||
this.winSize_ = size;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Resizes overlay to match the size of the bound element then displays the
|
||||
* overlay. Helper for {@link #onWindowResize_}.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.resizeOverlay_ = function() {
|
||||
this.positionOverlay_();
|
||||
goog.style.setElementShown(this.getElement(), false);
|
||||
goog.style.setElementShown(this.overlay_, true);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Updates the position and size of the overlay to match the original element.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.positionOverlay_ = function() {
|
||||
goog.style.setPosition(
|
||||
this.overlay_, goog.style.getPosition(this.getElement()));
|
||||
goog.style.setSize(this.overlay_, goog.style.getSize(this.getElement()));
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.ui.PlainTextSpellChecker.prototype.disposeInternal = function() {
|
||||
this.getDomHelper().removeNode(this.overlay_);
|
||||
delete this.overlay_;
|
||||
delete this.boundContinueAsyncFn_;
|
||||
delete this.endOfLineMatcher_;
|
||||
goog.ui.PlainTextSpellChecker.superClass_.disposeInternal.call(this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Specify ARIA roles and states as appropriate.
|
||||
* @private
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.initAccessibility_ = function() {
|
||||
goog.asserts.assert(this.overlay_,
|
||||
'The plain text spell checker DOM element cannot be null.');
|
||||
goog.a11y.aria.setRole(this.overlay_, 'region');
|
||||
goog.a11y.aria.setState(this.overlay_, 'live', 'assertive');
|
||||
this.overlay_.tabIndex = 0;
|
||||
|
||||
/** @desc Title for Spell Checker's overlay.*/
|
||||
var MSG_SPELLCHECKER_OVERLAY_TITLE = goog.getMsg('Spell Checker');
|
||||
this.overlay_.title = MSG_SPELLCHECKER_OVERLAY_TITLE;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handles key down for overlay.
|
||||
* @param {goog.events.BrowserEvent} e The browser event.
|
||||
* @return {boolean|undefined} The handled value.
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.handleOverlayKeyEvent = function(e) {
|
||||
var handled = false;
|
||||
switch (e.keyCode) {
|
||||
case goog.events.KeyCodes.RIGHT:
|
||||
if (e.ctrlKey) {
|
||||
handled = this.navigate_(goog.ui.AbstractSpellChecker.Direction.NEXT);
|
||||
}
|
||||
break;
|
||||
|
||||
case goog.events.KeyCodes.LEFT:
|
||||
if (e.ctrlKey) {
|
||||
handled = this.navigate_(
|
||||
goog.ui.AbstractSpellChecker.Direction.PREVIOUS);
|
||||
}
|
||||
break;
|
||||
|
||||
case goog.events.KeyCodes.DOWN:
|
||||
if (this.focusedElementId_) {
|
||||
var el = this.getDomHelper().getElement(this.makeElementId(
|
||||
this.focusedElementId_));
|
||||
if (el) {
|
||||
var position = goog.style.getPosition(el);
|
||||
var size = goog.style.getSize(el);
|
||||
position.x += size.width / 2;
|
||||
position.y += size.height / 2;
|
||||
this.showSuggestionsMenu(el, position);
|
||||
handled = undefined;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (handled) {
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
return handled;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Navigate keyboard focus in the given direction.
|
||||
*
|
||||
* @param {goog.ui.AbstractSpellChecker.Direction} direction The direction to
|
||||
* navigate in.
|
||||
* @return {boolean} Whether the action is handled here. If not handled
|
||||
* here, the initiating event may be propagated.
|
||||
* @private
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.navigate_ = function(direction) {
|
||||
var handled = false;
|
||||
var previous = direction == goog.ui.AbstractSpellChecker.Direction.PREVIOUS;
|
||||
var lastId = goog.ui.AbstractSpellChecker.getNextId();
|
||||
var focusedId = this.focusedElementId_;
|
||||
|
||||
var el;
|
||||
do {
|
||||
focusedId += previous ? -1 : 1;
|
||||
if (focusedId < 1 || focusedId > lastId) {
|
||||
focusedId = 0;
|
||||
break;
|
||||
}
|
||||
} while (!(el = this.getElementById(focusedId)));
|
||||
|
||||
if (el) {
|
||||
el.focus();
|
||||
this.focusedElementId_ = focusedId;
|
||||
handled = true;
|
||||
}
|
||||
|
||||
return handled;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handles correction menu actions.
|
||||
*
|
||||
* @param {goog.events.Event} event Action event.
|
||||
* @override
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.onCorrectionAction = function(event) {
|
||||
goog.ui.PlainTextSpellChecker.superClass_.onCorrectionAction.call(this,
|
||||
event);
|
||||
|
||||
// In case of editWord base class has already set the focus (on the input),
|
||||
// otherwise set the focus back on the word.
|
||||
if (event.target != this.getMenuEdit()) {
|
||||
this.reFocus_();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handles blur on the menu.
|
||||
* @param {goog.events.BrowserEvent} event Blur event.
|
||||
* @private
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.onCorrectionBlur_ = function(event) {
|
||||
this.reFocus_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the focus back on the previously focused word element.
|
||||
* @private
|
||||
*/
|
||||
goog.ui.PlainTextSpellChecker.prototype.reFocus_ = function() {
|
||||
var el = this.getElementById(this.focusedElementId_);
|
||||
if (el) {
|
||||
el.focus();
|
||||
} else {
|
||||
this.overlay_.focus();
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user