58

How does one detect a spelling mistake inside a textarea in JavaScript? Is there an event associated with this? How do I access Chrome's spell-check suggestions for a misspelled word?

Ninjakannon
  • 3,751
  • 7
  • 53
  • 76
  • 3
    I'm also almost sure it's not possible to access spelling check features using Javascript, on Chrome. But if your project allows it, you can use a third-party API, like this one: https://market.mashape.com/montanaflynn/spellcheck – Gustavo Straube Sep 16 '15 at 15:38
  • this might be a solution: http://stackoverflow.com/questions/1884829/force-spell-check-on-a-textarea-in-webkit – Johan Sep 16 '15 at 15:46
  • Okay, if you really need to do it through browser spellcheck engine for some reason, you could try to get a screenshot of page using webrtc stuff and then recognize red waves on that. But... you know. – Serge Seredenko Sep 17 '15 at 04:45
  • you could at least memorize the replacements and auto-apply them next time. – dandavis Sep 23 '15 at 09:41

4 Answers4

37

How do I access Chrome's spell-check suggestions for a misspelled word?

To the best of my knowledge, you cannot. To answer more fully, I'll also mention related issues:

Is there an event associated with this?

No, nor does the contextmenu event provide anything useful for this purpose: it has no spell-check information and you cannot read the list of context menu items (which may contain spelling suggestions). The change event also doesn't provide spell-check information.

How does one detect a spelling mistake inside a textarea in JavaScript?

You can either code this yourself or use a third party library. There are other Stack Overflow questions on this topic or you can search for yourself. Related Stack Overflow questions include:

approxiblue
  • 6,982
  • 16
  • 51
  • 59
Ninjakannon
  • 3,751
  • 7
  • 53
  • 76
  • 2
    Nicely answered, although I'm a little disappointed to discover I was right (that it's basically impossible). I'll not award the bounty until the last day, but you do have an up-vote in the interim. :) – David Thomas Sep 18 '15 at 17:39
  • 1
    Since this question was answered 5 years ago, I was wondering has anything being changed? Can we access browser's spellchecking now? On a separate note, how does websites like stackoverflow handle spell checking in their "Comments" field? – gameFrenzy07 Aug 19 '20 at 12:50
  • @gameFrenzy07 My understanding is that nothing substantial has changed. Stack Overflow does not do anything special; if you have spell checking turned on in your browser, it will spell check the comment `textarea` automatically. You can use the [`spellcheck`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/spellcheck) HTML attribute for further control. There is also a new experimental [`forceSpellCheck`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/forceSpellCheck) API with almost no support. – Ninjakannon Aug 20 '20 at 13:48
  • @Ninjakannon thanks for the reply. One more question I wanted to ask then is how might the desktop apps achieve this. For example I was seeing how let's say a Slack desktop app is catching misspelled words on the fly if their is no external support for it from the browser since it is on my computer? – gameFrenzy07 Aug 24 '20 at 10:07
  • @gameFrenzy07 The Slack desktop app uses Electron, which is built on top of Chromium; it's basically just running in a standalone browser, and is no different. Native desktop apps would have to be written for the OS or platform on which they're running, and is a separate question. – Ninjakannon Aug 24 '20 at 14:47
22

As the question seems a bit broad and open to interpretation (especially with the current bounty-'requirements'), I'll start by explaining how I interpret it and try to answer the subquestions in the process (Q/A style).

You seem to be asking:

"Google Chrome"/"Chromium" specific:

  1. Q: if browser "Google Chrome"/"Chromium" exposes a spellcheck-API that you can interact with through the use of javascript in a common webpage
    A: No, not really (at least not in the way you'd want).
    There is a Chromium-specific Spellcheck API Proposal (from dec 2012).

    Here are some parts of it:

    Could this API be part of the web platform?
    It is unlikely that spellchecking will become part of the web platform.

    More importantly, it has only one method called 'loadDictionary':

    loadDictionary( myDictionaryFile // string path or URL
                  , dictionaryFormat // enumerated string [ "hunspell" (concatentation of .aff and .dic files)
                                     //                   , "text"     (plain text)
                                     //                   ]
                  ) // returns int indicating success or an error code in loading the dictionary.      
    

    The point? Helping the community create custom dictionaries for Zulu, Klingon, etc. because approximately 20-30% of Spellcheck bugs-rapports were regarding unsupported languages.

    Now let's not confuse Chrome's SpellCheck API (above) with Chrome/Webkit's SpellCheck API (hu? say what?):
    Hironori Bono (a software engineer for Google Chrome) proposed an API around 2011 and some related bug rapports and a patch that was(/is still?) in Chrome.

    void addSpellcheckRange( unsigned long start
                           , unsigned long length
                           , DOMStringList suggestions
                       // [, unsigned short options]
                           );
    void removeSpellcheckRange(SpellcheckRange range);
    

    Usage example:

    var input = document.querySelector('input');
    input.addSpellcheckRange( 4
                            , 9
                            , [ 'Chrome'
                              , 'Firefox'
                              , 'Opera'
                              , 'Internet Explorer'
                              ]
                            );
    

    from http://peter.sh/experiments/spellcheck-api/
    Sources:
    http://html5-demos.appspot.com/static/html5-whats-new/template/index.html#42 ,
    http://peter.sh/experiments/spellcheck-api/ (you should be able to try it live there IF this API still works..)

    The point? After contemplating over this a couple of day's it suddenly clicked: custom spell-check integration with the browser - using the browser's context-menu instead of blocking it and providing your own. So one could link that with an existing external spell-check library.

    Above historical and experimental API's clearly never directly supported what you want to accomplish.

  2. Q: if "Google Chrome"/"Chromium" spellcheck-API exposes an 'onSpellError' (-like) event on (for example) a textarea
    A: As outlined above, it appears that Chrome doesn't have such an event.
    HTM5 currently only exposes the ability to enable or disable spell-checking on spellcheck supported elements.
  3. Q: how to access Chrome's spell-check suggestions for a misspelled word
    A: As outlined above: it appears that you can't. It appears to be the same answer as for the almost duplicate-question: How can I access Chrome's spell-check dictionary?
    It might be interesting to note that "TinyMCE's spellchecker was previously provided by 'hacking' a Chrome toolbar API owned by Google, against Google's own legal usage policies. This spellchecking service has been discontinued permanently.". Now if you search the web you probably can find how they did that, but it certainly doesn't seem the best way to go about it (and advocate it here).
    Using javascript spell-check libraries you could however use Chrome's dictionaries (so you wouldn't need to maintain the dictionaries) but you would have to supply and ship these files together with your web-app (instead of fetching the installed ones in the browser).

General:

  1. Q: How to detect a spelling mistake inside a textarea in JavaScript
    A: Internet Explorer allows using the spellchecker integrated into Microsoft Word via ActiveX as listed in the following code snippet.

    function CheckText(text) {
      var result = new Array;
      var app = new ActiveXObject('Word.Application');
      var doc = app.Documents.Add();
      doc.Content = text;
      for (var i = 1; i <= doc.SpellingErrors.Count; i++) {
        var spellingError = doc.SpellingErrors.Item(i);
        for (var j = 1; j <= spellingError.Words.Count; j++) {
          var word = spellingError.Words.Item(j);
          var error = {};
          error.word = word.Text;
          error.start = word.Start;
          error.length = word.Text.length;
          error.suggestions = new Array;
          var suggestions = word.GetSpellingSuggestions();
          for (var k = 1; k <= suggestions.Count; k++) {
            error.suggestions.push(suggestions.Item(k).Name);
          }
          result.push(error);
        }
      }
      return result;
    }
    

    Source: https://lists.w3.org/Archives/Public/public-webapps/2011AprJun/0516.html

    But IE/ActiveX/MS-Word isn't really what you have asked for, neither is it very cross platform/browser, that leaves us with local javascript spell-check libraries:
    Javascript Spell Checking Methods
    http://code.google.com/p/bjspell/
    http://www.javascriptspellcheck.com/
    http://ejohn.org/blog/revised-javascript-dictionary-search/
    Etc.
    Comparing/explaining them is really outside the scope of this answer.
    It is worth noting what format of dictionary you wish to use!

    Alternatively one could use an external spellcheck API service (where a server handles the data and you'd communicate with it using AJAX).
    Obviously you'd need to take privacy matters into account!

The bounty-'requirements' ask for:

  1. Q: definitive proof
    A: I should have found something more regarding the subject than some esoteric experimental features. Neither do I see libraries that try to shim their functionality into some (upcoming) standardized method/event identifiers etc.
    As noted, popular libraries like TinyMCE also currently have no other solution.
    In the 'living standard'/'the world is our playground' mentality my answer could very well already be outdated when I press the 'submit'-button. But even then I wouldn't recommend such an experimental feature in the near future on a 'production' level website/interface.
  2. Q: and obtaining a good answer explaining how to achieve this
    (chrome specific or in general? Spell-check suggestions or detecting that there is a typo?)
    A: Other than the above, I can't think of anything (other than libraries that web-developers currently use (see 4)).

Hope this helps!

Community
  • 1
  • 1
GitaarLAB
  • 14,536
  • 11
  • 60
  • 80
5

There is not an API for accessing Chrome's spellcheck suggestions, nor are there natively any events fired when words are mistyped. However, events could be implemented.

I have no idea what your use-case is for this functionality, but I put together a demonstration using montanaflynn's Spellcheck API on MashApe. The demo watches a text area, and when the user pauses typing, it sends the text via the API to be tested. The API returns JSON containing the original string, the suggested corrected string, and an object containing the corrected words and their suggested replacements.

The suggestions are displayed below the textarea. When suggestions are hovered, the mistyped word is highlighted. When clicked, the typo is replaced with the suggestion.

I also added a shuffling function, that scrambles the words in the string before sending it, to add a layer of privacy to the use of the API (it uses SSL also). Neither the API nor Chrome use context-based suggestions, so the shuffling doesn't alter the results.

Here's a link to the CodePen: http://codepen.io/aecend/pen/rOebQq

And here is the code:

CSS

<style>

    * {
        font-family: sans-serif;
    }

    textarea {
        margin-bottom: 10px;
        width: 500px; 
        height: 300px;
        padding: 10px;
    }

    .words {
        width: 500px;
    }

    .word {
        display: inline-block;
        padding: 2px 5px 1px 5px;
        border-radius: 2px;
        background: #00B1E6;
        color: white;
        margin: 2px;
        cursor: pointer;
    }

</style>

HTML

<textarea id="text" placeholder="Type something here..."></textarea>
<div id="words"></div>

JavaScript

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>

<script>

    ;(function(){

        "use strict";

        var words = document.getElementById("words"),
            input = document.getElementById("text"),
            timeout, xhr;

        input.addEventListener("keyup", function(e){

            if (timeout) clearTimeout(timeout);

            if (!this.value.trim()) words.innerHTML = '';

            timeout = setTimeout(function() {

                var test_phrase = shuffle_words( input.value );

                spell_check(test_phrase);

                timeout = null;

            }, 500);

        });

        function shuffle_words(inp) {

            inp = inp.replace(/\s+/g, ' ');

            var arr = inp.split(" "),
                n = arr.length;

            while (n > 0) {
                var i = Math.floor(Math.random() * n--),
                    t = arr[n];
                arr[n] = arr[i];
                arr[i] = t;
            }

            return arr.join(' ');
        }

        function spell_check(text){

            if (xhr) xhr.abort();

            xhr = $.ajax({
                url: 'https://montanaflynn-spellcheck.p.mashape.com/check/',
                headers: {
                    'X-Mashape-Key': 'U3ogA8RAAMmshGOJkNxkTBbuYYRTp1gMAuGjsniThZuaoKIyaj',
                    'Accept': 'application/json'
                },
                data: { 
                    'text': text
                },
                cache: false,
                success: function(result){

                    xhr = null;
                    suggest_words(result);

                }
            });

        }

        function suggest_words(obj){

            if (!obj.corrections) return;

            words.innerHTML = '';

            for (var key in obj.corrections) {

                if (obj.corrections.hasOwnProperty(key)) {

                    var div = document.createElement("div");
                    div.className = "word";
                    div.innerHTML = obj.corrections[key][0];
                    div.orig = key;

                    div.onmouseover = function() {
                        var start = input.value.indexOf(this.orig);
                        input.selectionStart = start;
                        input.selectionEnd = start + this.orig.length;
                    };

                    div.onmouseout = function() {
                        var len = input.value.length;
                        input.selectionStart = len;
                        input.selectionEnd = len;
                    }

                    div.onclick = function() {
                        input.value = input.value.replace(this.orig, this.innerHTML);
                        this.parentNode.removeChild(this);
                    }

                    words.appendChild(div);

                }

            }

        }

    })();

</script>

I only used jQuery to simplify the AJAX request for this demonstration. This could easily be done in vanilla JS.

aecend
  • 2,432
  • 14
  • 16
0

You can disable internal browser spellcheck and integrate any other opensource spellcheck library, for example JavaScript SpellCheck. It contains all events you may need for deep integration, check the API page.

Eugene Tiurin
  • 4,019
  • 4
  • 33
  • 32