123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648 |
- 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.dom.TagName');
- 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');
- goog.ui.PlainTextSpellChecker = function(handler, opt_domHelper) {
- goog.ui.AbstractSpellChecker.call(this, handler, opt_domHelper);
-
- this.overlay_ = this.getDomHelper().createDom(goog.dom.TagName.DIV);
- goog.style.setPreWrap(this.overlay_);
-
- this.boundContinueAsyncFn_ = goog.bind(this.continueAsync_, this);
-
- this.endOfLineMatcher_ = new RegExp('(.*)(\n|\r\n){0,1}', 'g');
- };
- goog.inherits(goog.ui.PlainTextSpellChecker, goog.ui.AbstractSpellChecker);
- goog.ui.PlainTextSpellChecker.prototype.invalidWordClassName =
- goog.getCssName('goog-spellcheck-invalidword');
- goog.ui.PlainTextSpellChecker.prototype.correctedWordClassName =
- goog.getCssName('goog-spellcheck-correctedword');
- goog.ui.PlainTextSpellChecker.prototype.correctionPaneClassName =
- goog.getCssName('goog-spellcheck-correctionpane');
- goog.ui.PlainTextSpellChecker.prototype.dictionaryPreScanSize_ = 1000;
- goog.ui.PlainTextSpellChecker.prototype.winSize_;
- goog.ui.PlainTextSpellChecker.prototype.eventHandler_;
- goog.ui.PlainTextSpellChecker.prototype.keyHandler_;
- goog.ui.PlainTextSpellChecker.prototype.textArrayIndex_;
- goog.ui.PlainTextSpellChecker.prototype.textArray_;
- goog.ui.PlainTextSpellChecker.prototype.textArrayProcess_;
- goog.ui.PlainTextSpellChecker.prototype.createDom = function() {
- this.setElementInternal(
- this.getDomHelper().createElement(goog.dom.TagName.TEXTAREA));
- };
- 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_();
- };
- 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;
- }
- };
- goog.ui.PlainTextSpellChecker.prototype.initSuggestionsMenu = function() {
- goog.ui.PlainTextSpellChecker.superClass_.initSuggestionsMenu.call(this);
- this.eventHandler_.listen(
- (this.getMenu()),
- goog.ui.Component.EventType.HIDE, this.onCorrectionHide_);
- };
- goog.ui.PlainTextSpellChecker.prototype.check = function() {
- var text = this.getElement().value;
- this.getElement().readOnly = true;
-
- goog.dom.removeChildren(this.overlay_);
- 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);
- };
- goog.ui.PlainTextSpellChecker.prototype.finishCheck_ = function() {
-
- 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(
- (this.keyHandler_),
- goog.events.KeyHandler.EventType.KEY, this.handleOverlayKeyEvent);
-
-
- 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);
- };
- 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_);
- };
- 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);
- };
- 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;
- };
- 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);
- }
- };
- 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_();
- };
- goog.ui.PlainTextSpellChecker.prototype.continueAsync_ = function() {
-
- 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_();
- };
- goog.ui.PlainTextSpellChecker.prototype.processWord = function(
- node, word, status) {
- node.appendChild(this.createWordElement(word, status));
- };
- 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(goog.dom.TagName.BR));
- }
- }
- };
- 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_);
- goog.dom.removeChildren(this.overlay_);
- var eh = this.eventHandler_;
- eh.unlisten(this.overlay_, goog.events.EventType.CLICK, this.onWordClick_);
- eh.unlisten(
- (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_);
- }
- };
- 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': ''};
- };
- goog.ui.PlainTextSpellChecker.prototype.onWordClick_ = function(event) {
- if (event.target.className == this.invalidWordClassName ||
- event.target.className == this.correctedWordClassName) {
- this.showSuggestionsMenu( (event.target), event);
-
- event.stopPropagation();
- }
- };
- 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);
-
- if (goog.userAgent.IE) {
- goog.Timer.callOnce(this.resizeOverlay_, 100, this);
- } else {
- this.resizeOverlay_();
- }
- this.winSize_ = size;
- }
- };
- goog.ui.PlainTextSpellChecker.prototype.resizeOverlay_ = function() {
- this.positionOverlay_();
- goog.style.setElementShown(this.getElement(), false);
- goog.style.setElementShown(this.overlay_, true);
- };
- 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()));
- };
- 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);
- };
- 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;
-
- var MSG_SPELLCHECKER_OVERLAY_TITLE = goog.getMsg('Spell Checker');
- this.overlay_.title = MSG_SPELLCHECKER_OVERLAY_TITLE;
- };
- 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.getFocusedElementIndex()) {
- var el = this.getDomHelper().getElement(
- this.makeElementId(this.getFocusedElementIndex()));
- 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 = true;
- }
- }
- break;
- }
- if (handled) {
- e.preventDefault();
- }
- return handled;
- };
- goog.ui.PlainTextSpellChecker.prototype.onCorrectionAction = function(event) {
- goog.ui.PlainTextSpellChecker.superClass_.onCorrectionAction.call(
- this, event);
-
-
- if (event.target != this.getMenuEdit()) {
- this.reFocus_();
- }
- };
- goog.ui.PlainTextSpellChecker.prototype.onCorrectionHide_ = function(event) {
- this.reFocus_();
- };
- goog.ui.PlainTextSpellChecker.prototype.reFocus_ = function() {
- var el = this.getElementByIndex(this.getFocusedElementIndex());
- if (el) {
- el.focus();
- } else {
- this.overlay_.focus();
- }
- };
|