Bug 339127: Add spellcheck attribute, branch version.

r+sr=sicking
a=dbaron


git-svn-id: svn://10.0.0.236/branches/MOZILLA_1_8_BRANCH@206364 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
pkasting%google.com
2006-08-02 01:38:48 +00:00
parent 1f300af86c
commit 1e4719682f
19 changed files with 338 additions and 185 deletions

View File

@@ -454,8 +454,10 @@ pref("browser.backspace_action", 0);
#endif
// this will automatically enable inline spellchecking (if it is available) for
// multi-line text entry controls <textarea>s in HTML
// 0 = spellcheck nothing, 1 = check multi-line controls, 2 = check multi/single line controls
// editable elements in HTML
// 0 = spellcheck nothing
// 1 = check multi-line controls [default]
// 2 = check multi/single line controls
pref("layout.spellcheckDefault", 1);
pref("view_source.editor.path", "");

View File

@@ -49,12 +49,14 @@
#include "nsCSSDeclaration.h"
#include "nsIDocument.h"
#include "nsIDocumentEncoder.h"
#include "nsIDOMHTMLBodyElement.h"
#include "nsIDOMHTMLDocument.h"
#include "nsIDOMAttr.h"
#include "nsIDOMEventReceiver.h"
#include "nsIDOMNamedNodeMap.h"
#include "nsIDOMNodeList.h"
#include "nsIDOMDocumentFragment.h"
#include "nsIDOMNSHTMLDocument.h"
#include "nsIDOMNSHTMLElement.h"
#include "nsIDOMElementCSSInlineStyle.h"
#include "nsIDOMWindow.h"
@@ -140,6 +142,8 @@
#include "nsCOMArray.h"
#include "nsNodeInfoManager.h"
#include "nsIEditor.h"
// XXX todo: add in missing out-of-memory checks
//----------------------------------------------------------------------
@@ -195,7 +199,7 @@ nsGenericHTMLElement::Init(nsINodeInfo *aNodeInfo)
#endif
class nsGenericHTMLElementTearoff : public nsIDOMNSHTMLElement,
class nsGenericHTMLElementTearoff : public nsIDOMNSHTMLElement_MOZILLA_1_8_BRANCH,
public nsIDOMElementCSSInlineStyle
{
NS_DECL_ISUPPORTS
@@ -212,6 +216,7 @@ class nsGenericHTMLElementTearoff : public nsIDOMNSHTMLElement,
}
NS_FORWARD_NSIDOMNSHTMLELEMENT(mElement->)
NS_FORWARD_NSIDOMNSHTMLELEMENT_MOZILLA_1_8_BRANCH(mElement->)
NS_FORWARD_NSIDOMELEMENTCSSINLINESTYLE(mElement->)
private:
@@ -224,6 +229,7 @@ NS_IMPL_RELEASE(nsGenericHTMLElementTearoff)
NS_INTERFACE_MAP_BEGIN(nsGenericHTMLElementTearoff)
NS_INTERFACE_MAP_ENTRY(nsIDOMNSHTMLElement)
NS_INTERFACE_MAP_ENTRY(nsIDOMNSHTMLElement_MOZILLA_1_8_BRANCH)
NS_INTERFACE_MAP_ENTRY(nsIDOMElementCSSInlineStyle)
NS_INTERFACE_MAP_END_AGGREGATED(mElement)
@@ -249,6 +255,10 @@ nsGenericHTMLElement::DOMQueryInterface(nsIDOMHTMLElement *aElement,
inst = NS_STATIC_CAST(nsIDOMNSHTMLElement *,
new nsGenericHTMLElementTearoff(this));
NS_ENSURE_TRUE(inst, NS_ERROR_OUT_OF_MEMORY);
} else if (aIID.Equals(NS_GET_IID(nsIDOMNSHTMLElement_MOZILLA_1_8_BRANCH))) {
inst = NS_STATIC_CAST(nsIDOMNSHTMLElement_MOZILLA_1_8_BRANCH *,
new nsGenericHTMLElementTearoff(this));
NS_ENSURE_TRUE(inst, NS_ERROR_OUT_OF_MEMORY);
} else if (aIID.Equals(NS_GET_IID(nsIDOMElementCSSInlineStyle))) {
inst = NS_STATIC_CAST(nsIDOMElementCSSInlineStyle *,
new nsGenericHTMLElementTearoff(this));
@@ -1310,6 +1320,89 @@ nsGenericHTMLElement::ScrollIntoView(PRBool aTop)
return NS_OK;
}
NS_IMETHODIMP
nsGenericHTMLElement::GetSpellcheck(PRBool* aSpellcheck)
{
NS_ENSURE_ARG_POINTER(aSpellcheck);
*aSpellcheck = PR_FALSE; // Default answer is to not spellcheck
// Has the state has been explicitly set?
nsIContent* content;
for (content = this; content; content = content->GetParent()) {
if (content->IsContentOfType(nsIContent::eHTML)) {
nsAutoString target;
content->GetAttr(kNameSpaceID_None, nsHTMLAtoms::spellcheck, target);
if (target.EqualsLiteral("true")) {
*aSpellcheck = PR_TRUE;
return NS_OK;
}
if (target.EqualsLiteral("false")) {
*aSpellcheck = PR_FALSE;
return NS_OK;
}
}
}
// Is this a chrome element?
if (nsContentUtils::IsChromeDoc(GetOwnerDoc())) {
return NS_OK; // Not spellchecked by default
}
// Is this the actual body of the current document?
if (IsCurrentBodyElement()) {
// Is designMode on?
nsCOMPtr<nsIDOMNSHTMLDocument> nsHTMLDocument =
do_QueryInterface(GetCurrentDoc());
if (!nsHTMLDocument) {
return PR_FALSE;
}
nsAutoString designMode;
nsHTMLDocument->GetDesignMode(designMode);
*aSpellcheck = designMode.EqualsLiteral("on");
return NS_OK;
}
// Is this element editable?
nsCOMPtr<nsIFormControl> formControl = do_QueryInterface(this);
if (!formControl) {
return NS_OK; // Not spellchecked by default
}
// Is this a multiline plaintext input?
PRInt32 controlType = formControl->GetType();
if (controlType == NS_FORM_TEXTAREA) {
*aSpellcheck = PR_TRUE; // Spellchecked by default
return NS_OK;
}
// Is this anything other than a single-line plaintext input?
if (controlType != NS_FORM_INPUT_TEXT) {
return NS_OK; // Not spellchecked by default
}
// Does the user want single-line inputs spellchecked by default?
// NOTE: Do not reflect a pref value of 0 back to the DOM getter.
// The web page should not know if the user has disabled spellchecking.
// We'll catch this in the editor itself.
PRInt32 spellcheckLevel =
nsContentUtils::GetIntPref("layout.spellcheckDefault", 1);
if (spellcheckLevel == 2) { // "Spellcheck multi- and single-line"
*aSpellcheck = PR_TRUE; // Spellchecked by default
}
return NS_OK;
}
NS_IMETHODIMP
nsGenericHTMLElement::SetSpellcheck(PRBool aSpellcheck)
{
if (aSpellcheck) {
return SetAttrHelper(nsHTMLAtoms::spellcheck, NS_LITERAL_STRING("true"));
}
return SetAttrHelper(nsHTMLAtoms::spellcheck, NS_LITERAL_STRING("false"));
}
PRBool
nsGenericHTMLElement::InNavQuirksMode(nsIDocument* aDoc)
@@ -1822,7 +1915,15 @@ nsGenericHTMLElement::SetAttrAndNotify(PRInt32 aNamespaceID,
}
}
if (aNamespaceID == kNameSpaceID_XMLEvents &&
if (aNotify && aNamespaceID == kNameSpaceID_None &&
aAttribute == nsHTMLAtoms::spellcheck) {
nsCOMPtr<nsIEditor> editor = GetAssociatedEditor();
nsCOMPtr<nsIEditor_MOZILLA_1_8_BRANCH> editor_1_8 =
do_QueryInterface(editor);
if (editor_1_8) {
editor_1_8->SyncRealTimeSpell();
}
} else if (aNamespaceID == kNameSpaceID_XMLEvents &&
aAttribute == nsHTMLAtoms::_event && mNodeInfo->GetDocument()) {
mNodeInfo->GetDocument()->AddXMLEventsContent(this);
}
@@ -4141,6 +4242,14 @@ nsGenericHTMLElement::GetEditor(nsIEditor** aEditor)
if (!nsContentUtils::IsCallerChrome())
return NS_ERROR_DOM_SECURITY_ERR;
return GetEditorInternal(aEditor);
}
nsresult
nsGenericHTMLElement::GetEditorInternal(nsIEditor** aEditor)
{
*aEditor = nsnull;
nsIFormControlFrame *fcFrame = GetFormControlFrame(PR_FALSE);
if (fcFrame) {
nsITextControlFrame *textFrame = nsnull;
@@ -4152,3 +4261,32 @@ nsGenericHTMLElement::GetEditor(nsIEditor** aEditor)
return NS_OK;
}
already_AddRefed<nsIEditor>
nsGenericHTMLElement::GetAssociatedEditor()
{
// If contenteditable is ever implemented, it might need to do something different here?
nsIEditor* editor = nsnull;
GetEditorInternal(&editor);
return editor;
}
PRBool
nsGenericHTMLElement::IsCurrentBodyElement()
{
nsCOMPtr<nsIDOMHTMLBodyElement> bodyElement = do_QueryInterface(this);
if (!bodyElement) {
return PR_FALSE;
}
nsCOMPtr<nsIDOMHTMLDocument> htmlDocument =
do_QueryInterface(GetCurrentDoc());
if (!htmlDocument) {
return PR_FALSE;
}
nsCOMPtr<nsIDOMHTMLElement> htmlElement;
htmlDocument->GetBody(getter_AddRefs(htmlElement));
return htmlElement == bodyElement;
}

View File

@@ -155,13 +155,15 @@ public:
nsresult GetClientHeight(PRInt32* aClientHeight);
nsresult GetClientWidth(PRInt32* aClientWidth);
nsresult ScrollIntoView(PRBool aTop);
// Declare Focus(), Blur(), GetTabIndex() and SetTabIndex() such
// that classes that inherit interfaces with those methods properly
// override them
// Declare Focus(), Blur(), GetTabIndex(), SetTabIndex(), GetSpellcheck() and
// SetSpellcheck() such that classes that inherit interfaces with those
// methods properly override them
NS_IMETHOD Focus();
NS_IMETHOD Blur();
NS_IMETHOD GetTabIndex(PRInt32 *aTabIndex);
NS_IMETHOD SetTabIndex(PRInt32 aTabIndex);
NS_IMETHOD GetSpellcheck(PRBool* aSpellcheck);
NS_IMETHOD SetSpellcheck(PRBool aSpellcheck);
/**
* Get the frame's offset information for offsetTop/Left/Width/Height.
@@ -803,6 +805,22 @@ protected:
* Locate an nsIEditor rooted at this content node, if there is one.
*/
NS_HIDDEN_(nsresult) GetEditor(nsIEditor** aEditor);
NS_HIDDEN_(nsresult) GetEditorInternal(nsIEditor** aEditor);
/**
* Locates the nsIEditor associated with this node. In general this is
* equivalent to GetEditorInternal(), but for designmode or contenteditable,
* this may need to get an editor that's not actually on this element's
* associated TextControlFrame. This is used by the spellchecking routines
* to get the editor affected by changing the spellcheck attribute on this
* node.
*/
virtual already_AddRefed<nsIEditor> GetAssociatedEditor();
/**
* Returns true if this is the current document's body element
*/
PRBool IsCurrentBodyElement();
};

View File

@@ -264,6 +264,7 @@ HTML_ATOM(size, "size")
HTML_ATOM(small, "small")
HTML_ATOM(spacer, "spacer")
HTML_ATOM(span, "span")
HTML_ATOM(spellcheck, "spellcheck")
HTML_ATOM(src, "src")
HTML_ATOM(standby, "standby")
HTML_ATOM(start, "start")

View File

@@ -56,6 +56,7 @@
#include "nsRuleData.h"
#include "nsIFrame.h"
#include "nsIDocShell.h"
#include "nsIEditorDocShell.h"
#include "nsCOMPtr.h"
#include "nsIView.h"
#include "nsLayoutAtoms.h"
@@ -114,6 +115,7 @@ public:
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
virtual already_AddRefed<nsIEditor> GetAssociatedEditor();
protected:
BodyRule* mContentStyleRule;
@@ -519,3 +521,32 @@ nsHTMLBodyElement::IsAttributeMapped(const nsIAtom* aAttribute) const
return FindAttributeDependence(aAttribute, map, NS_ARRAY_LENGTH(map));
}
already_AddRefed<nsIEditor>
nsHTMLBodyElement::GetAssociatedEditor()
{
nsIEditor* editor = nsnull;
if (NS_SUCCEEDED(GetEditorInternal(&editor)) && editor) {
return editor;
}
// Make sure this is the actual body of the document
if (!IsCurrentBodyElement()) {
return nsnull;
}
// For designmode, try to get document's editor
nsPresContext* presContext = GetPresContext();
if (!presContext) {
return nsnull;
}
nsCOMPtr<nsISupports> container = presContext->GetContainer();
nsCOMPtr<nsIEditorDocShell> editorDocShell = do_QueryInterface(container);
if (!editorDocShell) {
return nsnull;
}
editorDocShell->GetEditor(&editor);
return editor;
}

View File

@@ -75,7 +75,6 @@ REQUIRES = xpcom \
commandhandler \
composer \
editor \
txtsvc \
plugin \
$(NULL)

View File

@@ -107,8 +107,6 @@
#include "nsISelectElement.h"
#include "nsIFrameSelection.h"
#include "nsISelectionPrivate.h"//for toStringwithformat code
#include "nsIInlineSpellChecker.h"
#include "nsIEditor.h"
#include "nsICharsetDetector.h"
#include "nsICharsetDetectionAdaptor.h"
@@ -151,8 +149,6 @@ const PRInt32 kBackward = 1;
#define ID_NOT_IN_DOCUMENT ((nsIContent *)1)
#define NAME_NOT_VALID ((nsBaseContentList*)1)
#define PREF_DEFAULT_SPELLCHECK "layout.spellcheckDefault"
static NS_DEFINE_CID(kCookieServiceCID, NS_COOKIESERVICE_CID);
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
static NS_DEFINE_CID(kCharsetAliasCID, NS_CHARSETALIAS_CID);
@@ -299,9 +295,6 @@ nsHTMLDocument::~nsHTMLDocument()
if (mIdAndNameHashTable.ops) {
PL_DHashTableFinish(&mIdAndNameHashTable);
}
nsContentUtils::UnregisterPrefCallback(PREF_DEFAULT_SPELLCHECK,
nsHTMLDocument::RealTimeSpellCallback, this);
}
NS_IMPL_ADDREF_INHERITED(nsHTMLDocument, nsDocument)
@@ -3650,11 +3643,7 @@ nsHTMLDocument::SetDesignMode(const nsAString & aDesignMode)
rv = ExecCommand(NS_LITERAL_STRING("insertBrOnReturn"), PR_FALSE,
NS_LITERAL_STRING("false"), &unused);
if (NS_SUCCEEDED(rv)) {
nsContentUtils::RegisterPrefCallback(PREF_DEFAULT_SPELLCHECK,
nsHTMLDocument::RealTimeSpellCallback, this);
}
else {
if (NS_FAILED(rv)) {
// Editor setup failed. Editing is is not on after all.
editSession->TearDownEditorOnWindow(window);
@@ -3668,61 +3657,12 @@ nsHTMLDocument::SetDesignMode(const nsAString & aDesignMode)
if (NS_SUCCEEDED(rv)) {
mEditingIsOn = PR_FALSE;
nsContentUtils::UnregisterPrefCallback(PREF_DEFAULT_SPELLCHECK,
nsHTMLDocument::RealTimeSpellCallback, this);
}
}
SetEnableRealTimeSpell(window, editSession);
return rv;
}
void
nsHTMLDocument::SetEnableRealTimeSpell(nsIDOMWindow* window,
nsIEditingSession* editSession)
{
PRBool enabled = mEditingIsOn;
if (enabled) {
PRInt32 spellcheckLevel = nsContentUtils::GetIntPref(PREF_DEFAULT_SPELLCHECK, 0);
enabled = (spellcheckLevel != 0);
}
nsCOMPtr<nsIEditor> editor;
editSession->GetEditorForWindow(window, getter_AddRefs(editor));
nsCOMPtr<nsIEditor_MOZILLA_1_8_BRANCH> editorBranch = do_QueryInterface(editor);
if (editorBranch) {
nsCOMPtr<nsIInlineSpellChecker> inlineSpellChecker;
nsresult rv = editorBranch->GetInlineSpellCheckerOptionally(enabled,
getter_AddRefs(inlineSpellChecker));
if (NS_SUCCEEDED(rv) && inlineSpellChecker) {
inlineSpellChecker->SetEnableRealTimeSpell(enabled);
}
}
}
// PrefCallback for real time spell pref
// static
int PR_CALLBACK nsHTMLDocument::RealTimeSpellCallback(const char* aPref, void* aContext)
{
if (strcmp(aPref, PREF_DEFAULT_SPELLCHECK) == 0) {
nsHTMLDocument* doc = NS_STATIC_CAST(nsHTMLDocument*, aContext);
NS_ASSERTION(doc, "Pref callback: aContext was of an unexpected type");
nsCOMPtr<nsIDOMWindow> window(do_QueryInterface(doc->GetScriptGlobalObject()));
if (window) {
nsCOMPtr<nsISupports> container = doc->GetContainer();
nsCOMPtr<nsIEditingSession> editSession = do_GetInterface(container);
if (editSession)
doc->SetEnableRealTimeSpell(window, editSession);
}
}
return 0;
}
nsresult
nsHTMLDocument::GetMidasCommandManager(nsICommandManager** aCmdMgr)
{

View File

@@ -64,7 +64,6 @@ class nsIURI;
class nsIMarkupDocumentViewer;
class nsIDocumentCharsetInfo;
class nsICacheEntryDescriptor;
class nsIEditingSession;
class nsHTMLDocument : public nsDocument,
public nsIHTMLDocument,
@@ -315,11 +314,6 @@ protected:
nsCOMPtr<nsIWyciwygChannel> mWyciwygChannel;
void SetEnableRealTimeSpell(nsIDOMWindow* window,
nsIEditingSession* editSession);
static int PR_CALLBACK RealTimeSpellCallback(const char* aPref, void* aContext);
/* Midas implementation */
nsresult GetMidasCommandManager(nsICommandManager** aCommandManager);
PRBool ConvertToMidasInternalCommand(const nsAString & inCommandID,

View File

@@ -63,5 +63,11 @@ interface nsIDOMNSHTMLElement : nsISupports
// |top| is optional in JS, scriptability of this method is done in
// nsHTMLElementSH
void scrollIntoView(in boolean top);
void scrollIntoView(in boolean top);
};
[scriptable, uuid(91fdb05e-f1af-4857-a604-45448bc02471)]
interface nsIDOMNSHTMLElement_MOZILLA_1_8_BRANCH : nsIDOMNSHTMLElement
{
attribute boolean spellcheck;
};

View File

@@ -1674,7 +1674,7 @@ nsDOMClassInfo::RegisterExternalClasses()
DOM_CLASSINFO_MAP_ENTRY(nsIDOM3Node)
#define DOM_CLASSINFO_GENERIC_HTML_MAP_ENTRIES \
DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSHTMLElement) \
DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSHTMLElement_MOZILLA_1_8_BRANCH) \
DOM_CLASSINFO_MAP_ENTRY(nsIDOMElementCSSInlineStyle) \
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget) \
DOM_CLASSINFO_MAP_ENTRY(nsIDOM3Node)

View File

@@ -565,4 +565,17 @@ interface nsIEditor_MOZILLA_1_8_BRANCH : nsIEditor
* WILL RETURN NULL.
*/
nsIInlineSpellChecker getInlineSpellCheckerOptionally(in boolean autoCreate);
/** Resyncs spellchecking state (enabled/disabled). This should be called
* when anything that affects spellchecking state changes, such as the
* spellcheck attribute value.
*/
void syncRealTimeSpell();
/** Called when the user manually overrides the spellchecking state for this
* editor.
* @param enable The new state of spellchecking in this editor, as
* requested by the user.
*/
void setSpellcheckUserOverride(in boolean enable);
};

View File

@@ -41,6 +41,7 @@
#include "nsIDOMDocument.h"
#include "nsIDOMHTMLDocument.h"
#include "nsIDOMHTMLElement.h"
#include "nsIDOMNSHTMLElement.h"
#include "nsIDOMEventReceiver.h"
#include "nsIEventListenerManager.h"
#include "nsIPrefBranch.h"
@@ -146,6 +147,7 @@ nsEditor::nsEditor()
, mPresShellWeak(nsnull)
, mViewManager(nsnull)
, mUpdateCount(0)
, mSpellcheckCheckboxState(eTriUnset)
, mPlaceHolderTxn(nsnull)
, mPlaceHolderName(nsnull)
, mPlaceHolderBatch(0)
@@ -332,7 +334,12 @@ nsEditor::Init(nsIDOMDocument *aDoc, nsIPresShell* aPresShell, nsIContent *aRoot
NS_IMETHODIMP
nsEditor::PostCreate()
{
nsresult rv = CreateEventListeners();
// Set up spellchecking
nsresult rv = SyncRealTimeSpell();
NS_ENSURE_SUCCESS(rv, rv);
// Set up listeners
rv = CreateEventListeners();
if (NS_FAILED(rv))
{
RemoveEventListeners();
@@ -473,25 +480,78 @@ nsEditor::RemoveEventListeners()
}
}
PRBool
nsEditor::GetDesiredSpellCheckState()
{
// Check user override on this element
if (mSpellcheckCheckboxState != eTriUnset) {
return (mSpellcheckCheckboxState == eTriTrue);
}
// Check user preferences
nsresult rv;
nsCOMPtr<nsIPrefBranch> prefBranch =
do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
PRInt32 spellcheckLevel = 1;
if (NS_SUCCEEDED(rv) && prefBranch) {
prefBranch->GetIntPref("layout.spellcheckDefault", &spellcheckLevel);
}
if (spellcheckLevel == 0) {
return PR_FALSE; // Spellchecking forced off globally
}
// Check for password/readonly/disabled, which are not spellchecked
// regardless of DOM
PRUint32 flags;
if (NS_SUCCEEDED(GetFlags(&flags)) &&
flags & (nsIPlaintextEditor::eEditorPasswordMask |
nsIPlaintextEditor::eEditorReadonlyMask |
nsIPlaintextEditor::eEditorDisabledMask)) {
return PR_FALSE;
}
// Check DOM state
nsCOMPtr<nsIContent> content = do_QueryInterface(GetRoot());
if (!content) {
return PR_FALSE;
}
if (content->IsNativeAnonymous()) {
content = content->GetParent();
}
nsCOMPtr<nsIDOMNSHTMLElement_MOZILLA_1_8_BRANCH> element =
do_QueryInterface(content);
if (!element) {
return PR_FALSE;
}
PRBool enable;
element->GetSpellcheck(&enable);
return enable;
}
NS_IMETHODIMP
nsEditor::PreDestroy()
{
if (!mDidPreDestroy) {
// Let spellchecker clean up its observers etc.
if (mInlineSpellChecker) {
mInlineSpellChecker->Cleanup();
mInlineSpellChecker = nsnull;
}
if (mDidPreDestroy)
return NS_OK;
// tell our listeners that the doc is going away
NotifyDocumentListeners(eDocumentToBeDestroyed);
// Unregister event listeners
RemoveEventListeners();
mDidPreDestroy = PR_TRUE;
// Let spellchecker clean up its observers etc.
if (mInlineSpellChecker) {
mInlineSpellChecker->Cleanup();
mInlineSpellChecker = nsnull;
}
// tell our listeners that the doc is going away
NotifyDocumentListeners(eDocumentToBeDestroyed);
// Unregister event listeners
RemoveEventListeners();
mDidPreDestroy = PR_TRUE;
return NS_OK;
}
@@ -506,6 +566,9 @@ NS_IMETHODIMP
nsEditor::SetFlags(PRUint32 aFlags)
{
mFlags = aFlags;
// Changing the flags can change whether spellchecking is on, so re-sync it
SyncRealTimeSpell();
return NS_OK;
}
@@ -1340,6 +1403,27 @@ NS_IMETHODIMP nsEditor::GetInlineSpellCheckerOptionally(PRBool autoCreate,
return NS_OK;
}
NS_IMETHODIMP nsEditor::SyncRealTimeSpell()
{
PRBool enable = GetDesiredSpellCheckState();
nsCOMPtr<nsIInlineSpellChecker> spellChecker;
GetInlineSpellCheckerOptionally(enable, getter_AddRefs(spellChecker));
if (spellChecker) {
spellChecker->SetEnableRealTimeSpell(enable);
}
return NS_OK;
}
NS_IMETHODIMP nsEditor::SetSpellcheckUserOverride(PRBool enable)
{
mSpellcheckCheckboxState = enable ? eTriTrue : eTriFalse;
return SyncRealTimeSpell();
}
#ifdef XP_MAC
#pragma mark -
#pragma mark main node manipulation routines

View File

@@ -343,6 +343,11 @@ protected:
// unregister and release our event listeners
virtual void RemoveEventListeners();
/**
* Return true if spellchecking should be enabled for this editor.
*/
PRBool GetDesiredSpellCheckState();
public:
/** All editor operations which alter the doc should be prefaced
@@ -591,7 +596,15 @@ protected:
nsWeakPtr mSelConWeak; // weak reference to the nsISelectionController
nsIViewManager *mViewManager;
PRInt32 mUpdateCount;
nsCOMPtr<nsIInlineSpellChecker> mInlineSpellChecker; // used for real-time spellchecking
// Spellchecking
enum Tristate {
eTriUnset,
eTriFalse,
eTriTrue
} mSpellcheckCheckboxState;
nsCOMPtr<nsIInlineSpellChecker> mInlineSpellChecker;
nsCOMPtr<nsITransactionManager> mTxnMgr;
nsWeakPtr mPlaceHolderTxn; // weak reference to placeholder for begin/end batch purposes
nsIAtom *mPlaceHolderName; // name of placeholder transaction
@@ -617,7 +630,7 @@ protected:
PRPackedBool mDidPreDestroy; // whether PreDestroy has been called
// various listeners
nsVoidArray* mActionListeners; // listens to all low level actions on the doc
nsVoidArray* mEditorObservers; // just notify once per high level change
nsVoidArray* mEditorObservers; // just notify once per high level change
nsCOMPtr<nsISupportsArray> mDocStateListeners;// listen to overall doc state (dirty or not, just created, etc)
PRInt8 mDocDirtyState; // -1 = not initialized

View File

@@ -52,7 +52,7 @@ var InlineSpellChecker =
{
this.editor = editor;
this.inlineSpellChecker = editor.inlineSpellChecker;
this.inlineSpellChecker.enableRealTimeSpell = enable;
this.editor.QueryInterface(Components.interfaces.nsIEditor_MOZILLA_1_8_BRANCH).setSpellcheckUserOverride(enable);
},
checkDocument : function(doc)

View File

@@ -67,7 +67,6 @@
#include "nsIScrollableFrame.h" //to turn off scroll bars
#include "nsFormControlFrame.h" //for registering accesskeys
#include "nsIDeviceContext.h" // to measure fonts
#include "nsIInlineSpellChecker.h"
#include "nsIContent.h"
#include "nsIAtom.h"
@@ -134,8 +133,6 @@
#define DEFAULT_COLUMN_WIDTH 20
#define PREF_DEFAULT_SPELLCHECK "layout.spellcheckDefault"
#include "nsContentCID.h"
static NS_DEFINE_IID(kRangeCID, NS_RANGE_CID);
@@ -1451,8 +1448,6 @@ nsTextControlFrame::PreDestroy(nsPresContext* aPresContext)
NS_IMETHODIMP
nsTextControlFrame::Destroy(nsPresContext* aPresContext)
{
nsContentUtils::UnregisterPrefCallback(PREF_DEFAULT_SPELLCHECK,
nsTextControlFrame::RealTimeSpellCallback, this);
if (!mDidPreDestroy) {
PreDestroy(aPresContext);
}
@@ -1683,71 +1678,6 @@ nsTextControlFrame::CreateFrameFor(nsPresContext* aPresContext,
return NS_ERROR_FAILURE;
}
void
nsTextControlFrame::SetEnableRealTimeSpell(PRBool aEnabled)
{
nsresult rv = NS_OK;
NS_ASSERTION(!aEnabled || !IsPasswordTextControl(),
"don't enable real time spell for password controls");
// The editor will lazily create the spell checker object if it has not been
// created. We only want one created if we are turning it on, since not
// created implies there's no spell checking yet.
nsCOMPtr<nsIInlineSpellChecker> inlineSpellChecker;
nsCOMPtr<nsIEditor_MOZILLA_1_8_BRANCH> editorBranch =
do_QueryInterface(mEditor);
if (NS_FAILED(rv)) {
rv = mEditor->GetInlineSpellChecker(getter_AddRefs(inlineSpellChecker));
} else {
rv = editorBranch->GetInlineSpellCheckerOptionally(aEnabled,
getter_AddRefs(inlineSpellChecker));
}
if (NS_SUCCEEDED(rv) && inlineSpellChecker) {
inlineSpellChecker->SetEnableRealTimeSpell(aEnabled);
}
}
void
nsTextControlFrame::SyncRealTimeSpell()
{
PRBool readOnly = PR_FALSE;
if (mEditor) {
PRUint32 flags;
mEditor->GetFlags(&flags);
if (flags & nsIPlaintextEditor::eEditorReadonlyMask)
readOnly = PR_TRUE;
}
PRBool enable = PR_FALSE;
if (!readOnly) {
// check the pref to see what the default should be, default is 0: never spellcheck
PRInt32 spellcheckLevel = nsContentUtils::GetIntPref(PREF_DEFAULT_SPELLCHECK, 0);
switch (spellcheckLevel) {
case SpellcheckAllTextFields:
enable = PR_TRUE;
break;
case SpellcheckMultiLineOnly:
enable = !IsSingleLineTextControl();
break;
}
}
SetEnableRealTimeSpell(enable);
}
// PrefCallback for real time spell pref
// static
int PR_CALLBACK nsTextControlFrame::RealTimeSpellCallback(const char* aPref, void* aContext)
{
if (strcmp(aPref, PREF_DEFAULT_SPELLCHECK) == 0) {
nsTextControlFrame* frame = NS_STATIC_CAST(nsTextControlFrame*, aContext);
NS_ASSERTION(frame, "Pref callback: aContext was of an unexpected type");
frame->SyncRealTimeSpell();
}
return 0;
}
nsresult
nsTextControlFrame::InitEditor()
{
@@ -1832,10 +1762,6 @@ nsTextControlFrame::InitEditor()
transMgr->SetMaxTransactionCount(DEFAULT_UNDO_CAP);
SyncRealTimeSpell();
nsContentUtils::RegisterPrefCallback(PREF_DEFAULT_SPELLCHECK,
nsTextControlFrame::RealTimeSpellCallback, this);
if (IsPasswordTextControl()) {
// Disable undo for password textfields. Note that we want to do this at
// the very end of InitEditor, so the calls to EnableUndo when setting the
@@ -2916,7 +2842,6 @@ nsTextControlFrame::AttributeChanged(nsIContent* aChild,
mSelCon->SetCaretEnabled(PR_TRUE);
}
mEditor->SetFlags(flags);
SyncRealTimeSpell();
}
else if (mEditor && nsHTMLAtoms::disabled == aAttribute)
{

View File

@@ -219,12 +219,6 @@ public: //for methods who access nsTextControlFrame directly
/* called to free up native keybinding services */
static NS_HIDDEN_(void) ShutDown();
enum SpellcheckDefaultState {
SpellcheckNone = 0,
SpellcheckMultiLineOnly = 1,
SpellcheckAllTextFields = 2
};
protected:
/**
@@ -304,10 +298,6 @@ private:
nsresult SelectAllContents();
nsresult SetSelectionEndPoints(PRInt32 aSelStart, PRInt32 aSelEnd);
void SetEnableRealTimeSpell(PRBool aEnabled);
void SyncRealTimeSpell();
static int PR_CALLBACK RealTimeSpellCallback(const char* aPref, void* aContext);
private:
nsCOMPtr<nsIEditor> mEditor;
nsCOMPtr<nsISelectionController> mSelCon;

View File

@@ -2178,7 +2178,7 @@ function ToggleInlineSpellChecker(target)
{
if (InlineSpellChecker.inlineSpellChecker)
{
InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell = !InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell;
InlineSpellChecker.editor.QueryInterface(Components.interfaces.nsIEditor_MOZILLA_1_8_BRANCH).setSpellcheckUserOverride(!InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell);
target.setAttribute('checked', InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell);
if (InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell)

View File

@@ -2099,14 +2099,14 @@ function addRecipientsToIgnoreList(aAddressesToAdd)
function StopInlineSpellChecker()
{
if (InlineSpellChecker.inlineSpellChecker)
InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell = false;
InlineSpellChecker.editor.QueryInterface(Components.interfaces.nsIEditor_MOZILLA_1_8_BRANCH).setSpellcheckUserOverride(false);
}
function ToggleInlineSpellChecker(target)
{
if (InlineSpellChecker.inlineSpellChecker)
{
InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell = !InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell;
InlineSpellChecker.editor.QueryInterface(Components.interfaces.nsIEditor_MOZILLA_1_8_BRANCH).setSpellcheckUserOverride(!InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell);
if (InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell)
InlineSpellChecker.checkDocument(window.content.document);

View File

@@ -118,7 +118,7 @@ var InlineSpellCheckerUI = {
set enabled(isEnabled)
{
if (this.mInlineSpellChecker)
this.mInlineSpellChecker.enableRealTimeSpell = isEnabled;
this.mEditor.QueryInterface(Components.interfaces.nsIEditor_MOZILLA_1_8_BRANCH).setSpellcheckUserOverride(isEnabled);
},
// returns true if the given event is over a misspelled word
@@ -273,8 +273,7 @@ var InlineSpellCheckerUI = {
// callback for enabling or disabling spellchecking
toggleEnabled: function()
{
this.mInlineSpellChecker.enableRealTimeSpell =
! this.mInlineSpellChecker.enableRealTimeSpell;
this.mEditor.QueryInterface(Components.interfaces.nsIEditor_MOZILLA_1_8_BRANCH).setSpellcheckUserOverride(!this.mInlineSpellChecker.enableRealTimeSpell);
},
// callback for adding the current misspelling to the user-defined dictionary