зеркало из https://github.com/mozilla/gecko-dev.git
Bug 339127: Add "spellcheck" attribute to control spellchecking.
r=brettw sr=sicking
This commit is contained in:
Родитель
2cdfdf7ea9
Коммит
2070e797b8
|
@ -459,8 +459,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", "");
|
||||
|
|
|
@ -720,6 +720,7 @@ GK_ATOM(sortStaticsLast, "sortStaticsLast")
|
|||
GK_ATOM(space, "space")
|
||||
GK_ATOM(spacer, "spacer")
|
||||
GK_ATOM(span, "span")
|
||||
GK_ATOM(spellcheck, "spellcheck")
|
||||
GK_ATOM(spinner, "spinner")
|
||||
GK_ATOM(splitter, "splitter")
|
||||
GK_ATOM(spring, "spring")
|
||||
|
|
|
@ -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"
|
||||
|
@ -1272,6 +1274,90 @@ 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?
|
||||
nsINode* node;
|
||||
for (node = this; node; node = node->GetNodeParent()) {
|
||||
if (node->IsNodeOfType(nsINode::eHTML)) {
|
||||
static nsIContent::AttrValuesArray strings[] =
|
||||
{&nsHTMLAtoms::_true, &nsHTMLAtoms::_false, nsnull};
|
||||
switch (NS_STATIC_CAST(nsIContent*, node)->
|
||||
FindAttrValueIn(kNameSpaceID_None, nsHTMLAtoms::spellcheck,
|
||||
strings, eCaseMatters)) {
|
||||
case 0: // spellcheck = "true"
|
||||
*aSpellcheck = PR_TRUE;
|
||||
// Fall through
|
||||
case 1: // spellcheck = "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)
|
||||
|
@ -1609,9 +1695,17 @@ nsresult
|
|||
nsGenericHTMLElement::AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify)
|
||||
{
|
||||
if (aNamespaceID == kNameSpaceID_None && IsEventName(aName) && aValue) {
|
||||
nsresult rv = AddScriptEventListener(aName, *aValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (aNamespaceID == kNameSpaceID_None) {
|
||||
if (IsEventName(aName) && aValue) {
|
||||
nsresult rv = AddScriptEventListener(aName, *aValue);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else if (aName == nsHTMLAtoms::spellcheck) {
|
||||
nsCOMPtr<nsIEditor> editor = GetAssociatedEditor();
|
||||
if (editor) {
|
||||
editor->SyncRealTimeSpell();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nsGenericElement::AfterSetAttr(aNamespaceID, aName,
|
||||
|
@ -3994,3 +4088,32 @@ nsGenericHTMLElement::GetEditorInternal(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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
@ -749,6 +751,21 @@ protected:
|
|||
*/
|
||||
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();
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
@ -115,6 +116,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;
|
||||
|
@ -517,3 +519,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;
|
||||
}
|
||||
|
|
|
@ -75,7 +75,6 @@ REQUIRES = xpcom \
|
|||
commandhandler \
|
||||
composer \
|
||||
editor \
|
||||
txtsvc \
|
||||
plugin \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -107,8 +107,6 @@
|
|||
#include "nsISelectElement.h"
|
||||
#include "nsFrameSelection.h"
|
||||
#include "nsISelectionPrivate.h"//for toStringwithformat code
|
||||
#include "nsIInlineSpellChecker.h"
|
||||
#include "nsIEditor.h"
|
||||
|
||||
#include "nsICharsetDetector.h"
|
||||
#include "nsICharsetDetectionAdaptor.h"
|
||||
|
@ -156,8 +154,6 @@ const PRInt32 kBackward = 1;
|
|||
#define ID_NOT_IN_DOCUMENT ((nsIContent *)2)
|
||||
#define NAME_NOT_VALID ((nsBaseContentList*)1)
|
||||
|
||||
#define PREF_DEFAULT_SPELLCHECK "layout.spellcheckDefault"
|
||||
|
||||
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
|
||||
|
||||
// Returns the name atom of aContent, if the content is a named item
|
||||
|
@ -344,9 +340,6 @@ nsHTMLDocument::~nsHTMLDocument()
|
|||
if (mIdAndNameHashTable.ops) {
|
||||
PL_DHashTableFinish(&mIdAndNameHashTable);
|
||||
}
|
||||
|
||||
nsContentUtils::UnregisterPrefCallback(PREF_DEFAULT_SPELLCHECK,
|
||||
nsHTMLDocument::RealTimeSpellCallback, this);
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsHTMLDocument, nsDocument)
|
||||
|
@ -3707,11 +3700,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);
|
||||
|
@ -3725,68 +3714,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(nsPIDOMWindow* aWindow,
|
||||
nsIEditingSession* aEditSession)
|
||||
{
|
||||
// enable inline spelling for design mode documents unless the
|
||||
// pref disables it. Otherwise, disable inline spelling.
|
||||
PRBool enabled = mEditingIsOn;
|
||||
|
||||
if (aWindow) {
|
||||
if (enabled) {
|
||||
// check if the spellchecking is enabled as long as the level is not 0
|
||||
PRInt32 spellcheckLevel = nsContentUtils::GetIntPref(PREF_DEFAULT_SPELLCHECK, 0);
|
||||
enabled = (spellcheckLevel != 0);
|
||||
}
|
||||
|
||||
// get the editor for the window and enable inline spellchecking
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
aEditSession->GetEditorForWindow(aWindow, getter_AddRefs(editor));
|
||||
if (editor) {
|
||||
nsCOMPtr<nsIInlineSpellChecker> inlineSpellChecker;
|
||||
nsresult rv = editor->GetInlineSpellChecker(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");
|
||||
|
||||
nsPIDOMWindow *window = doc->GetWindow();
|
||||
if (window) {
|
||||
nsIDocShell *docshell = window->GetDocShell();
|
||||
if (docshell) {
|
||||
nsCOMPtr<nsIEditingSession> editSession = do_GetInterface(docshell);
|
||||
if (editSession)
|
||||
doc->SetEnableRealTimeSpell(window, editSession);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLDocument::GetMidasCommandManager(nsICommandManager** aCmdMgr)
|
||||
{
|
||||
|
|
|
@ -66,7 +66,6 @@ class nsIURI;
|
|||
class nsIMarkupDocumentViewer;
|
||||
class nsIDocumentCharsetInfo;
|
||||
class nsICacheEntryDescriptor;
|
||||
class nsIEditingSession;
|
||||
|
||||
class nsHTMLDocument : public nsDocument,
|
||||
public nsIHTMLDocument,
|
||||
|
@ -365,11 +364,6 @@ protected:
|
|||
|
||||
nsCOMPtr<nsIWyciwygChannel> mWyciwygChannel;
|
||||
|
||||
void SetEnableRealTimeSpell(nsPIDOMWindow* aWindow,
|
||||
nsIEditingSession* aEditSession);
|
||||
|
||||
static int PR_CALLBACK RealTimeSpellCallback(const char* aPref, void* aContext);
|
||||
|
||||
/* Midas implementation */
|
||||
nsresult GetMidasCommandManager(nsICommandManager** aCommandManager);
|
||||
PRBool ConvertToMidasInternalCommand(const nsAString & inCommandID,
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
#include "domstubs.idl"
|
||||
|
||||
[scriptable, uuid(da83b2ec-8264-4410-8496-ada3acd2ae42)]
|
||||
[scriptable, uuid(f58dd59c-a4b3-418e-9d10-f5ba0316da22)]
|
||||
interface nsIDOMNSHTMLElement : nsISupports
|
||||
{
|
||||
readonly attribute long offsetTop;
|
||||
|
@ -63,5 +63,7 @@ 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);
|
||||
|
||||
attribute boolean spellcheck;
|
||||
};
|
||||
|
|
|
@ -295,6 +295,19 @@ interface nsIEditor : nsISupports
|
|||
*/
|
||||
nsIInlineSpellChecker getInlineSpellChecker(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);
|
||||
|
||||
/* ------------ Clipboard methods -------------- */
|
||||
|
||||
/** cut the currently selected text, putting it into the OS clipboard
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsIDOMHTMLElement.h"
|
||||
#include "nsIDOMNSHTMLElement.h"
|
||||
#include "nsIDOMEventReceiver.h"
|
||||
#include "nsIEventListenerManager.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
|
@ -140,6 +141,7 @@ nsEditor::nsEditor()
|
|||
, mPresShellWeak(nsnull)
|
||||
, mViewManager(nsnull)
|
||||
, mUpdateCount(0)
|
||||
, mSpellcheckCheckboxState(eTriUnset)
|
||||
, mPlaceHolderTxn(nsnull)
|
||||
, mPlaceHolderName(nsnull)
|
||||
, mPlaceHolderBatch(0)
|
||||
|
@ -307,7 +309,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();
|
||||
|
@ -450,25 +457,77 @@ 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> 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;
|
||||
}
|
||||
|
||||
|
@ -483,6 +542,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;
|
||||
}
|
||||
|
||||
|
@ -1290,6 +1352,27 @@ NS_IMETHODIMP nsEditor::GetInlineSpellChecker(PRBool autoCreate,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsEditor::SyncRealTimeSpell()
|
||||
{
|
||||
PRBool enable = GetDesiredSpellCheckState();
|
||||
|
||||
nsCOMPtr<nsIInlineSpellChecker> spellChecker;
|
||||
GetInlineSpellChecker(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
|
||||
|
|
|
@ -340,6 +340,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
|
||||
|
@ -585,7 +590,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
|
||||
|
@ -610,7 +623,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
|
||||
|
|
|
@ -52,7 +52,7 @@ var InlineSpellChecker =
|
|||
{
|
||||
this.editor = editor;
|
||||
this.inlineSpellChecker = editor.getInlineSpellChecker(true);
|
||||
this.inlineSpellChecker.enableRealTimeSpell = enable;
|
||||
this.editor.setSpellcheckUserOverride(enable);
|
||||
},
|
||||
|
||||
checkDocument : function(doc)
|
||||
|
|
|
@ -66,7 +66,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"
|
||||
|
@ -127,8 +126,6 @@
|
|||
|
||||
#define DEFAULT_COLUMN_WIDTH 20
|
||||
|
||||
#define PREF_DEFAULT_SPELLCHECK "layout.spellcheckDefault"
|
||||
|
||||
#include "nsContentCID.h"
|
||||
static NS_DEFINE_IID(kRangeCID, NS_RANGE_CID);
|
||||
|
||||
|
@ -1197,8 +1194,6 @@ nsTextControlFrame::PreDestroy()
|
|||
void
|
||||
nsTextControlFrame::Destroy()
|
||||
{
|
||||
nsContentUtils::UnregisterPrefCallback(PREF_DEFAULT_SPELLCHECK,
|
||||
nsTextControlFrame::RealTimeSpellCallback, this);
|
||||
if (!mDidPreDestroy) {
|
||||
PreDestroy();
|
||||
}
|
||||
|
@ -1625,81 +1620,6 @@ nsTextControlFrame::CreateFrameFor(nsPresContext* aPresContext,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsTextControlFrame::SetEnableRealTimeSpell
|
||||
//
|
||||
// This enables or disables the spellchecker based on the given flag. It
|
||||
// will only create a spellcheck object if necessary.
|
||||
|
||||
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;
|
||||
rv = mEditor->GetInlineSpellChecker(aEnabled,
|
||||
getter_AddRefs(inlineSpellChecker));
|
||||
|
||||
if (NS_SUCCEEDED(rv) && inlineSpellChecker) {
|
||||
inlineSpellChecker->SetEnableRealTimeSpell(aEnabled);
|
||||
}
|
||||
}
|
||||
|
||||
// nsTextControlFrame::SyncRealTimeSpell
|
||||
//
|
||||
// This function is called to update whether inline spell checking is enabled
|
||||
// for the control. It is called on initialization and when things happen
|
||||
// that might affect spellchecking (for example, if it gets enabled or
|
||||
// disabled).
|
||||
//
|
||||
// Multi-line text controls are spellchecked when the preference is set.
|
||||
// Everything else (including read-only textareas) are not spellchecked by
|
||||
// default.
|
||||
|
||||
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()
|
||||
{
|
||||
|
@ -1784,10 +1704,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
|
||||
|
@ -2543,7 +2459,6 @@ nsTextControlFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
|||
mSelCon->SetCaretEnabled(PR_TRUE);
|
||||
}
|
||||
mEditor->SetFlags(flags);
|
||||
SyncRealTimeSpell();
|
||||
}
|
||||
else if (mEditor && nsHTMLAtoms::disabled == aAttribute)
|
||||
{
|
||||
|
|
|
@ -191,12 +191,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:
|
||||
/**
|
||||
* Find out whether this control is scrollable (i.e. if it is not a single
|
||||
|
@ -270,10 +264,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;
|
||||
|
||||
|
|
|
@ -2185,7 +2185,7 @@ function ToggleInlineSpellChecker(target)
|
|||
{
|
||||
if (InlineSpellChecker.inlineSpellChecker)
|
||||
{
|
||||
InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell = !InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell;
|
||||
InlineSpellChecker.editor.setSpellcheckUserOverride(!InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell);
|
||||
target.setAttribute('checked', InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell);
|
||||
|
||||
if (InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell)
|
||||
|
|
|
@ -2106,14 +2106,14 @@ function addRecipientsToIgnoreList(aAddressesToAdd)
|
|||
function StopInlineSpellChecker()
|
||||
{
|
||||
if (InlineSpellChecker.inlineSpellChecker)
|
||||
InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell = false;
|
||||
InlineSpellChecker.editor.setSpellcheckUserOverride(false);
|
||||
}
|
||||
|
||||
function ToggleInlineSpellChecker(target)
|
||||
{
|
||||
if (InlineSpellChecker.inlineSpellChecker)
|
||||
{
|
||||
InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell = !InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell;
|
||||
InlineSpellChecker.editor.setSpellcheckUserOverride(!InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell);
|
||||
|
||||
if (InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell)
|
||||
InlineSpellChecker.checkDocument(window.content.document);
|
||||
|
|
|
@ -118,7 +118,7 @@ var InlineSpellCheckerUI = {
|
|||
set enabled(isEnabled)
|
||||
{
|
||||
if (this.mInlineSpellChecker)
|
||||
this.mInlineSpellChecker.enableRealTimeSpell = isEnabled;
|
||||
this.mEditor.setSpellcheckUserOverride(isEnabled);
|
||||
},
|
||||
|
||||
// returns true if the given event is over a misspelled word
|
||||
|
@ -272,8 +272,7 @@ var InlineSpellCheckerUI = {
|
|||
// callback for enabling or disabling spellchecking
|
||||
toggleEnabled: function()
|
||||
{
|
||||
this.mInlineSpellChecker.enableRealTimeSpell =
|
||||
! this.mInlineSpellChecker.enableRealTimeSpell;
|
||||
this.mEditor.setSpellcheckUserOverride(!this.mInlineSpellChecker.enableRealTimeSpell);
|
||||
},
|
||||
|
||||
// callback for adding the current misspelling to the user-defined dictionary
|
||||
|
|
Загрузка…
Ссылка в новой задаче