Spell checking in Flex with Squiggly - Part 1
Posted on Mar 31, 2010
Last year Adobe released their Squiggly spell checking engine for Adobe Flex and Adobe AIR and on December 18th, they updated that library to work with Flex 4 Spark components. (UPDATED: Shortly after this was posted, adobe released a third prerelease of Squiggly that contains support for additional languages and a number of significant code changes. The code samples in this post have been updated to work with the latest version. Most of the more significant code changes apply to the examples in the upcoming part 2.). Where I work, spell checking is a core requirement for our application, and as we are looking to rebuild the Flex portion of our application in Flex 4, I decided to put Squiggly through some some basic testing to see if it could meet our requirements. In the end it mostly met them with some key drawbacks that hopefully are addressed in future releases.
In this post I will discuss the previously available options for spellchecking, how to get started with Squiggly and how to implement it using the provided SquigglyUI class. Part 2, which will be posted next week, will delve into the SpellingDictionary and UserDictionary and how they can be used to create custom spellchecking functionality. Keep in mind, this is all based upon a proof-of-concept that is still to be considered a "work in progress" - so feel free to share your ideas, suggestions and experiences.
Spell Checker Options in Flex
Up until recently, the only Flex spell checking
library I was aware of was Grant Skinner's SPL (http://www.gskinner.com/products/spl/about.php).
Without getting into the politics of it all, I know that Adobe's
release of Squiggly caused a bit of a stir since it mimicked the
features of SPL but, unlike SPL, was free. This appears to have
understandably caused Grant to decide not to develop SPL further, which
currently only supports Flex 3. A search for Flex spell checker also
shows a project by Bruce Deen called Flex:SpellCheck (http://www.flextendibles.com/) which I have not tried.
Getting Started with Squiggly
To
be clear, my specific requirement was to recreate the wizard style
spell checker that can be found in programs like Word and that typically
complements the spell-check-as-you-type option. I built a
skunkworks/proof-of-concept project where I got most of the complicated
issues around this worked out - such as jumping from word to word across
many potential text inputs that require spell checking. I wish I could
share the full code of this with you but it is a work product that my
employer has asked me not to share. I will, however, give you some of
the basics of how I decided to leverage Squiggly that form the
foundation of that project and will offer you a good getting started
guide for adding it to your project.
Squiggly is made up of several components separated into two core libraries (UI and engine) that, while interrelated, each serve their own purpose. If all you care about is the check-as-you-type spell checker, you'll only really be concerned about the SpellUI library. Adding this type of spell checking is incredibly simple.
Of course, the first step is simply to download the Squiggly SWC's and make sure you add it to the libs directory of your project or manually import them. After that we can add spell checking to any text element.
Spell-Check-As-You-Type with SpellUI
Adding check-as-you-type spell checking to any existing TextInput or TextArea in your Flex application is easy. The recent prerelease added the requirement of a configuration XML which simply points to the dictionaries for each language that you intend to support. Assuming you plan to support English as a start, once you have downloaded Squiggly, you can simply copy the dictionaries and AdobeSpellingConfig.xml contained in the /src folder of the download into your project's /src folder. Once this step is complete, adding the spell checking is pretty much a
matter of a two lines of code. First, of course, import the SpellUI class like so:
import com.adobe.linguistics.spelling.SpellUI;
Next, simply enable the spell checking on your text element (i.e. TextInput or TextArea) like the line below, where "en_US" is the language code for English as defined in AdobeSpellingConfig.xml:
SpellUI.enableSpelling(myTextArea,"en_US");
Now, your text area will place a red, "squiggly" underline beneath any word it doesn't find in your dictionary. In addition, right clicking on this word will bring up a context menu offering spelling suggestions, if there are any, and the ability to add words to your personal user dictionary (like your name for example).
One issue I ran into here when placing a demo of this functionality on our development server is that it appears to use a standard HTTP request to load the dictionary. This caused me problems since the request appeared to get blocked for credentials (standard Windows authentication in this case appeared to be the issue). Since Squiggly is not open source and doesn't provide another method for loading the dictionary (or to pass credentials), this meant it flat out wouldn't work in our development environment (locally it was fine of course). The workaround would be to put the dictionary in a place not behind the firewall even when working in your development environment.
In my application, I was going to have a number of text elements that would have check-as-you-type spell checking, both TextInput's and TextArea's. Due to requirements, I needed the misspelling highlights to turn off when you were not working in a particular element (so as not to inundate the screen with red). In order to handle this, I decided to extend both TextInput and TextArea and create custom classes that automatically had spell checking integrated which was enabled on focusIn and disabled on focusOut. We'll expand on this later, but here's a basic TextInput from my proof-of-concept that incorporates this functionality:
package com.views
{
import com.adobe.linguistics.spelling.SpellUI;
import spark.components.TextInput;
public class TextInputWithSpell extends TextInput
public function TextInputWithSpell()
{
super();
addEventListener("focusIn",enableSpell);
addEventListener("focusOut",disableSpell);
}
public function enableSpell(e:Event):void {
SpellUI.enableSpelling(this,"en_US");
}
public function disableSpell(e:Event):void {
try {
SpellUI.disableSpelling(this);
}
catch (error:Error) {
// do nothing. sometimes the disable seemed to occur before the enable if you clicked too quickly
}
}
}
}
Using this class was simple, of course.
<views:TextInputWithSpell id="aTextInput" />
Once you enable spellchecking with SpellUI on any TextInput or TextArea, mispelled words will automatically have a right click menu offering you several options including a list of suggestions and the ability to add the highlighted word to your dictionary. Items added to your dictionary are automatically persisted via a SharedObject I believe. Unfortunately, there is no easy way to customize the look and feel of the menu should it be required. In addition, I couldn't find a way to access the items you added to your dictionary should you want to either synchronize that with the UserDictionary object (which we'll discuss in the next section) and/or persist it in a database.
What's
Next
In part 2, I plan on exploring the other classes that come
with Squiggly such as the SpellingDictionary and UserDictionary that we
can use to create custom spellchecking functionality. We'll also explore
the limitations of interacting between those classes and the SpellUI
discussed here.
Comments
Posted By Ann / Posted on 05/14/2010 at 4:51 AM
Hello Remote Synthesis.
I really enjoyed the tutorial and include it in my project making
following settings:
1 - I've made the call creationComplete = "SpellUI.enableSpelling (transcricaoText, 'pt_BR');" along with its import on my .mxml.
2 - includes the lib folder (containing the engine) in the file actionScriptProperties with the tag libraryPathEntry.
3 - Includes adobeSpellingConfig.xml in the project root
4 - added the dictionary in the Data folder.
Still did not work, Do I need to do more to work?
ps. sorry for my English, I do not know if everything is correct.
att. Eduardo Cordeiro
Posted By Eduardo Cordeiro / Posted on 06/24/2010 at 12:36 PM
Based on the labs example (http://labs.adobe.com/technologies/squiggly/demo/srcview/index.html) and your description here, that sounds correct. What error are you receiving?
Posted By Brian Rinaldi / Posted on 06/25/2010 at 10:57 AM
yes, this error:
SecurityError: Error #2148: SWF file file:///C|/digitro/ambiente/workspaces/workspaceEduardoEupora/DGTPlayerWebFlex/bin%2Drelease/PlayerWebGuardiao2.swf cannot access local resource file:///C|/digitro/ambiente/workspaces/workspaceEduardoEupora/DGTPlayerWebFlex/bin%2Drelease/AdobeSpellingConfig.xml. Only local-with-filesystem and trusted local SWF files may access local resources.
at flash.net::URLStream/load()
at flash.net::URLLoader/load()
at com.adobe.linguistics.spelling::SpellUI/loadConfig()
at com.adobe.linguistics.spelling::SpellUI()
at com.adobe.linguistics.spelling::SpellUI$/enableSpelling()
at br.com.digitro.playerweb.view::TranscricaoTab/__transcricaoText_creationComplete()
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.core::UIComponent/dispatchEvent()
at mx.core::UIComponent/set initialized()
at mx.managers::LayoutManager/doPhasedInstantiation()
at Function/http://adobe.com/AS3/2006/builtin::apply()
at mx.core::UIComponent/callLaterDispatcher2()
at mx.core::UIComponent/callLaterDispatcher()
Posted By Eduardo Cordeiro / Posted on 06/28/2010 at 10:43 AM
Eduardo, The error states that it cannot find the AdobeSpellingConfig.xml in the release folder. Make sure that the XML is being exported to the /bin-release/ folder.
Posted By Brian Rinaldi / Posted on 06/28/2010 at 3:57 PM
Well, he is in the folder bin-release, but this error is appearing to be denied access. I'll try the idea of crossdomain. If successful I will warn.
Thank you for your help Brian.
Posted By Eduardo Cordeiro / Posted on 06/30/2010 at 11:44 AM
The idea of crossdomain file does not appear effect. I really do not
know what else to do. But anyway thanks for trying.
Att Edward Cordeiro.
Posted By Eduardo Cordeiro / Posted on 07/05/2010 at 9:40 AM
Hello again. I managed to fix the error # 2148 on this site:
http://www.macromedia.com/support/documentation/en/flashplayer/help/setti
ngs_manager04.html
But the spell checker does not appear to me. I believe I have to do the
settings in the build.xml. If you know how I would
grateful.
att. Edward Cordeiro.
Posted By Eduardo Cordeiro / Posted on 07/05/2010 at 10:12 AM
I noticed that it works locally, but not inside the server. Would you have any solution for this problem?
att. Eduardo Cordeiro
Posted By Eduardo Cordeiro / Posted on 07/06/2010 at 11:42 AM
I really can't say. My assumption would be that it is a permissions error on your production server. I would use something like the network monitor in Flash Builder or Charles to see what URL its trying to load the settings from perhaps.
Posted By Brian Rinaldi / Posted on 07/06/2010 at 12:29 PM
There were only the dictionary files and xml on the server.
Now is working, thanks.
Posted By Eduardo Cordeiro / Posted on 07/15/2010 at 11:34 PM
Great tutorial!
Have you come across any CPU issues? We have an application that has about 25 text fields (20 TextInputs and 5 Textarea). We have noticed that the CPU usage going up to 90-100%, and it remains there. After some debugging, we disabled the spellchecking, and found the CPU issue disappeared. Have you noticed any cpu issues in your application?.
Posted By Saju Abraham / Posted on 09/20/2010 at 2:35 PM
I didn't encounter any CPU issues but I never completed the full application - only the proof of concept (which I talk about a little more in the part 2 in this series). I no longer work for the company that I was creating this for so I wouldn't know if that happened in the end.
I would try contacting the Squiggly team at Adobe by posting to the forums or on Labs. If you don't have any success, please email me and I will see what I can do to help send you to the right channels (I now work for Adobe).
Posted By Brian Rinaldi / Posted on 09/20/2010 at 4:01 PM
Thanks Brian! I will try the squiggly forums.
Posted By Saju Abraham / Posted on 09/21/2010 at 5:22 AM