Bug 733335 - dexpcom nsIEditableTextAccessible::GetAssociatedEditor, r=davidb

This commit is contained in:
Alexander Surkov
2012-03-08 12:28:38 +09:00
parent f0276c4f59
commit fd1ca8bf76
13 changed files with 98 additions and 103 deletions

View File

@@ -43,7 +43,7 @@
interface nsIEditor; interface nsIEditor;
[scriptable, uuid(52837507-202d-4e72-a482-5f068a1fd720)] [scriptable, uuid(e242d495-5cde-4b1c-8c84-2525b14939f5)]
interface nsIAccessibleEditableText : nsISupports interface nsIAccessibleEditableText : nsISupports
{ {
/** /**
@@ -103,19 +103,4 @@ interface nsIAccessibleEditableText : nsISupports
* clipboard into the text represented by this object. * clipboard into the text represented by this object.
*/ */
void pasteText (in long position); void pasteText (in long position);
/**
* Returns an editor associated with the accessible.
*/
[noscript] readonly attribute nsIEditor associatedEditor;
}; };
/*
Assumptions:
selectAttributes method takes an nsISupports parameter.
'set' methods throw exception on failure.
'wstring' inputs are potentially multibyte (UTF-16 for
instance); 'string' and UTF-8 may be a better choice.
*/

View File

@@ -680,8 +680,7 @@ NotificationController::CreateTextChangeEventFor(AccMutationEvent* aEvent)
// Don't fire event for the first html:br in an editor. // Don't fire event for the first html:br in an editor.
if (aEvent->mAccessible->Role() == roles::WHITESPACE) { if (aEvent->mAccessible->Role() == roles::WHITESPACE) {
nsCOMPtr<nsIEditor> editor; nsCOMPtr<nsIEditor> editor = textAccessible->GetEditor();
textAccessible->GetAssociatedEditor(getter_AddRefs(editor));
if (editor) { if (editor) {
bool isEmpty = false; bool isEmpty = false;
editor->GetDocumentIsEmpty(&isEmpty); editor->GetDocumentIsEmpty(&isEmpty);

View File

@@ -214,6 +214,11 @@ public:
*/ */
virtual PRUint64 NativeState(); virtual PRUint64 NativeState();
/**
* Return bit set of invisible and offscreen states.
*/
PRUint64 VisibilityState();
/** /**
* Returns attributes for accessible without explicitly setted ARIA * Returns attributes for accessible without explicitly setted ARIA
* attributes. * attributes.
@@ -702,8 +707,6 @@ protected:
virtual nsIFrame* GetBoundsFrame(); virtual nsIFrame* GetBoundsFrame();
virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame); virtual void GetBoundsRect(nsRect& aRect, nsIFrame** aRelativeFrame);
PRUint64 VisibilityState();
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// Name helpers // Name helpers

View File

@@ -333,8 +333,7 @@ nsDocAccessible::NativeState()
state |= states::INVISIBLE | states::OFFSCREEN; state |= states::INVISIBLE | states::OFFSCREEN;
} }
nsCOMPtr<nsIEditor> editor; nsCOMPtr<nsIEditor> editor = GetEditor();
GetAssociatedEditor(getter_AddRefs(editor));
state |= editor ? states::EDITABLE : states::READONLY; state |= editor ? states::EDITABLE : states::READONLY;
return state; return state;
@@ -553,37 +552,32 @@ nsDocAccessible::GetVirtualCursor(nsIAccessiblePivot** aVirtualCursor)
return NS_OK; return NS_OK;
} }
// nsIAccessibleHyperText method // nsHyperTextAccessible method
NS_IMETHODIMP nsDocAccessible::GetAssociatedEditor(nsIEditor **aEditor) already_AddRefed<nsIEditor>
nsDocAccessible::GetEditor() const
{ {
NS_ENSURE_ARG_POINTER(aEditor);
*aEditor = nsnull;
if (IsDefunct())
return NS_ERROR_FAILURE;
// Check if document is editable (designMode="on" case). Otherwise check if // Check if document is editable (designMode="on" case). Otherwise check if
// the html:body (for HTML document case) or document element is editable. // the html:body (for HTML document case) or document element is editable.
if (!mDocument->HasFlag(NODE_IS_EDITABLE) && if (!mDocument->HasFlag(NODE_IS_EDITABLE) &&
!mContent->HasFlag(NODE_IS_EDITABLE)) !mContent->HasFlag(NODE_IS_EDITABLE))
return NS_OK; return nsnull;
nsCOMPtr<nsISupports> container = mDocument->GetContainer(); nsCOMPtr<nsISupports> container = mDocument->GetContainer();
nsCOMPtr<nsIEditingSession> editingSession(do_GetInterface(container)); nsCOMPtr<nsIEditingSession> editingSession(do_GetInterface(container));
if (!editingSession) if (!editingSession)
return NS_OK; // No editing session interface return nsnull; // No editing session interface
nsCOMPtr<nsIEditor> editor; nsCOMPtr<nsIEditor> editor;
editingSession->GetEditorForWindow(mDocument->GetWindow(), getter_AddRefs(editor)); editingSession->GetEditorForWindow(mDocument->GetWindow(), getter_AddRefs(editor));
if (!editor) { if (!editor)
return NS_OK; return nsnull;
}
bool isEditable; bool isEditable = false;
editor->GetIsDocumentEditable(&isEditable); editor->GetIsDocumentEditable(&isEditable);
if (isEditable) { if (isEditable)
NS_ADDREF(*aEditor = editor); return editor.forget();
}
return NS_OK; return nsnull;
} }
// nsDocAccessible public method // nsDocAccessible public method

View File

@@ -133,8 +133,8 @@ public:
virtual nsresult HandleAccEvent(AccEvent* aAccEvent); virtual nsresult HandleAccEvent(AccEvent* aAccEvent);
#endif #endif
// nsIAccessibleText // nsHyperTextAccessible
NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor); virtual already_AddRefed<nsIEditor> GetEditor() const;
// nsDocAccessible // nsDocAccessible

View File

@@ -544,11 +544,12 @@ NS_IMETHODIMP nsHTMLTextFieldAccessible::DoAction(PRUint8 index)
return NS_ERROR_INVALID_ARG; return NS_ERROR_INVALID_ARG;
} }
NS_IMETHODIMP nsHTMLTextFieldAccessible::GetAssociatedEditor(nsIEditor **aEditor) already_AddRefed<nsIEditor>
nsHTMLTextFieldAccessible::GetEditor() const
{ {
*aEditor = nsnull;
nsCOMPtr<nsIDOMNSEditableElement> editableElt(do_QueryInterface(mContent)); nsCOMPtr<nsIDOMNSEditableElement> editableElt(do_QueryInterface(mContent));
NS_ENSURE_TRUE(editableElt, NS_ERROR_FAILURE); if (!editableElt)
return nsnull;
// nsGenericHTMLElement::GetEditor has a security check. // nsGenericHTMLElement::GetEditor has a security check.
// Make sure we're not restricted by the permissions of // Make sure we're not restricted by the permissions of
@@ -558,7 +559,7 @@ NS_IMETHODIMP nsHTMLTextFieldAccessible::GetAssociatedEditor(nsIEditor **aEditor
bool pushed = stack && NS_SUCCEEDED(stack->Push(nsnull)); bool pushed = stack && NS_SUCCEEDED(stack->Push(nsnull));
nsCOMPtr<nsIEditor> editor; nsCOMPtr<nsIEditor> editor;
nsresult rv = editableElt->GetEditor(aEditor); editableElt->GetEditor(getter_AddRefs(editor));
if (pushed) { if (pushed) {
JSContext* cx; JSContext* cx;
@@ -566,7 +567,7 @@ NS_IMETHODIMP nsHTMLTextFieldAccessible::GetAssociatedEditor(nsIEditor **aEditor
NS_ASSERTION(!cx, "context should be null"); NS_ASSERTION(!cx, "context should be null");
} }
return rv; return editor.forget();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@@ -138,8 +138,8 @@ public:
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName); NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index); NS_IMETHOD DoAction(PRUint8 index);
// nsIAccessibleEditableText // nsHyperTextAccessible
NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor); virtual already_AddRefed<nsIEditor> GetEditor() const;
// nsAccessible // nsAccessible
virtual void ApplyARIAState(PRUint64* aState); virtual void ApplyARIAState(PRUint64* aState);

View File

@@ -166,8 +166,7 @@ nsHyperTextAccessible::NativeState()
{ {
PRUint64 states = nsAccessibleWrap::NativeState(); PRUint64 states = nsAccessibleWrap::NativeState();
nsCOMPtr<nsIEditor> editor; nsCOMPtr<nsIEditor> editor = GetEditor();
GetAssociatedEditor(getter_AddRefs(editor));
if (editor) { if (editor) {
PRUint32 flags; PRUint32 flags;
editor->GetFlags(&flags); editor->GetFlags(&flags);
@@ -711,8 +710,7 @@ nsHyperTextAccessible::HypertextOffsetsToDOMRange(PRInt32 aStartHTOffset,
// If the given offsets are 0 and associated editor is empty then return // If the given offsets are 0 and associated editor is empty then return
// collapsed range with editor root element as range container. // collapsed range with editor root element as range container.
if (aStartHTOffset == 0 && aEndHTOffset == 0) { if (aStartHTOffset == 0 && aEndHTOffset == 0) {
nsCOMPtr<nsIEditor> editor; nsCOMPtr<nsIEditor> editor = GetEditor();
GetAssociatedEditor(getter_AddRefs(editor));
if (editor) { if (editor) {
bool isEmpty = false; bool isEmpty = false;
editor->GetDocumentIsEmpty(&isEmpty); editor->GetDocumentIsEmpty(&isEmpty);
@@ -1455,8 +1453,10 @@ NS_IMETHODIMP nsHyperTextAccessible::SetTextContents(const nsAString &aText)
NS_IMETHODIMP NS_IMETHODIMP
nsHyperTextAccessible::InsertText(const nsAString &aText, PRInt32 aPosition) nsHyperTextAccessible::InsertText(const nsAString &aText, PRInt32 aPosition)
{ {
nsCOMPtr<nsIEditor> editor; if (IsDefunct())
GetAssociatedEditor(getter_AddRefs(editor)); return NS_ERROR_FAILURE;
nsCOMPtr<nsIEditor> editor = GetEditor();
nsCOMPtr<nsIPlaintextEditor> peditor(do_QueryInterface(editor)); nsCOMPtr<nsIPlaintextEditor> peditor(do_QueryInterface(editor));
NS_ENSURE_STATE(peditor); NS_ENSURE_STATE(peditor);
@@ -1470,8 +1470,10 @@ nsHyperTextAccessible::InsertText(const nsAString &aText, PRInt32 aPosition)
NS_IMETHODIMP NS_IMETHODIMP
nsHyperTextAccessible::CopyText(PRInt32 aStartPos, PRInt32 aEndPos) nsHyperTextAccessible::CopyText(PRInt32 aStartPos, PRInt32 aEndPos)
{ {
nsCOMPtr<nsIEditor> editor; if (IsDefunct())
GetAssociatedEditor(getter_AddRefs(editor)); return NS_ERROR_FAILURE;
nsCOMPtr<nsIEditor> editor = GetEditor();
NS_ENSURE_STATE(editor); NS_ENSURE_STATE(editor);
nsresult rv = SetSelectionRange(aStartPos, aEndPos); nsresult rv = SetSelectionRange(aStartPos, aEndPos);
@@ -1483,8 +1485,10 @@ nsHyperTextAccessible::CopyText(PRInt32 aStartPos, PRInt32 aEndPos)
NS_IMETHODIMP NS_IMETHODIMP
nsHyperTextAccessible::CutText(PRInt32 aStartPos, PRInt32 aEndPos) nsHyperTextAccessible::CutText(PRInt32 aStartPos, PRInt32 aEndPos)
{ {
nsCOMPtr<nsIEditor> editor; if (IsDefunct())
GetAssociatedEditor(getter_AddRefs(editor)); return NS_ERROR_FAILURE;
nsCOMPtr<nsIEditor> editor = GetEditor();
NS_ENSURE_STATE(editor); NS_ENSURE_STATE(editor);
nsresult rv = SetSelectionRange(aStartPos, aEndPos); nsresult rv = SetSelectionRange(aStartPos, aEndPos);
@@ -1496,8 +1500,10 @@ nsHyperTextAccessible::CutText(PRInt32 aStartPos, PRInt32 aEndPos)
NS_IMETHODIMP NS_IMETHODIMP
nsHyperTextAccessible::DeleteText(PRInt32 aStartPos, PRInt32 aEndPos) nsHyperTextAccessible::DeleteText(PRInt32 aStartPos, PRInt32 aEndPos)
{ {
nsCOMPtr<nsIEditor> editor; if (IsDefunct())
GetAssociatedEditor(getter_AddRefs(editor)); return NS_ERROR_FAILURE;
nsCOMPtr<nsIEditor> editor = GetEditor();
NS_ENSURE_STATE(editor); NS_ENSURE_STATE(editor);
nsresult rv = SetSelectionRange(aStartPos, aEndPos); nsresult rv = SetSelectionRange(aStartPos, aEndPos);
@@ -1509,8 +1515,10 @@ nsHyperTextAccessible::DeleteText(PRInt32 aStartPos, PRInt32 aEndPos)
NS_IMETHODIMP NS_IMETHODIMP
nsHyperTextAccessible::PasteText(PRInt32 aPosition) nsHyperTextAccessible::PasteText(PRInt32 aPosition)
{ {
nsCOMPtr<nsIEditor> editor; if (IsDefunct())
GetAssociatedEditor(getter_AddRefs(editor)); return NS_ERROR_FAILURE;
nsCOMPtr<nsIEditor> editor = GetEditor();
NS_ENSURE_STATE(editor); NS_ENSURE_STATE(editor);
nsresult rv = SetSelectionRange(aPosition, aPosition); nsresult rv = SetSelectionRange(aPosition, aPosition);
@@ -1519,44 +1527,37 @@ nsHyperTextAccessible::PasteText(PRInt32 aPosition)
return editor->Paste(nsIClipboard::kGlobalClipboard); return editor->Paste(nsIClipboard::kGlobalClipboard);
} }
NS_IMETHODIMP already_AddRefed<nsIEditor>
nsHyperTextAccessible::GetAssociatedEditor(nsIEditor **aEditor) nsHyperTextAccessible::GetEditor() const
{ {
NS_ENSURE_ARG_POINTER(aEditor);
*aEditor = nsnull;
if (IsDefunct())
return NS_ERROR_FAILURE;
if (!mContent->HasFlag(NODE_IS_EDITABLE)) { if (!mContent->HasFlag(NODE_IS_EDITABLE)) {
// If we're inside an editable container, then return that container's editor // If we're inside an editable container, then return that container's editor
nsCOMPtr<nsIAccessible> ancestor, current = this; nsAccessible* ancestor = Parent();
while (NS_SUCCEEDED(current->GetParent(getter_AddRefs(ancestor))) && ancestor) { while (ancestor) {
nsRefPtr<nsHyperTextAccessible> ancestorTextAccessible; nsHyperTextAccessible* hyperText = ancestor->AsHyperText();
ancestor->QueryInterface(NS_GET_IID(nsHyperTextAccessible), if (hyperText) {
getter_AddRefs(ancestorTextAccessible));
if (ancestorTextAccessible) {
// Recursion will stop at container doc because it has its own impl // Recursion will stop at container doc because it has its own impl
// of GetAssociatedEditor() // of GetEditor()
return ancestorTextAccessible->GetAssociatedEditor(aEditor); return hyperText->GetEditor();
} }
current = ancestor;
ancestor = ancestor->Parent();
} }
return NS_OK;
return nsnull;
} }
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem = nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
nsCoreUtils::GetDocShellTreeItemFor(mContent); nsCoreUtils::GetDocShellTreeItemFor(mContent);
nsCOMPtr<nsIEditingSession> editingSession(do_GetInterface(docShellTreeItem)); nsCOMPtr<nsIEditingSession> editingSession(do_GetInterface(docShellTreeItem));
if (!editingSession) if (!editingSession)
return NS_OK; // No editing session interface return nsnull; // No editing session interface
NS_ENSURE_TRUE(mDoc, NS_ERROR_FAILURE);
nsIDocument* docNode = mDoc->GetDocumentNode();
NS_ENSURE_TRUE(docNode, NS_ERROR_FAILURE);
nsCOMPtr<nsIEditor> editor; nsCOMPtr<nsIEditor> editor;
return editingSession->GetEditorForWindow(docNode->GetWindow(), aEditor); nsIDocument* docNode = mDoc->GetDocumentNode();
editingSession->GetEditorForWindow(docNode->GetWindow(),
getter_AddRefs(editor));
return editor.forget();
} }
/** /**
@@ -1770,8 +1771,7 @@ nsHyperTextAccessible::GetSelectionDOMRanges(PRInt16 aType,
nsCOMPtr<nsINode> startNode = GetNode(); nsCOMPtr<nsINode> startNode = GetNode();
nsCOMPtr<nsIEditor> editor; nsCOMPtr<nsIEditor> editor = GetEditor();
GetAssociatedEditor(getter_AddRefs(editor));
if (editor) { if (editor) {
nsCOMPtr<nsIDOMElement> editorRoot; nsCOMPtr<nsIDOMElement> editorRoot;
editor->GetRootElement(getter_AddRefs(editorRoot)); editor->GetRootElement(getter_AddRefs(editorRoot));

View File

@@ -264,6 +264,14 @@ public:
return GetChildAt(GetChildIndexAtOffset(aOffset)); return GetChildAt(GetChildIndexAtOffset(aOffset));
} }
//////////////////////////////////////////////////////////////////////////////
// EditableTextAccessible
/**
* Return the editor associated with the accessible.
*/
virtual already_AddRefed<nsIEditor> GetEditor() const;
protected: protected:
// nsHyperTextAccessible // nsHyperTextAccessible

View File

@@ -273,8 +273,7 @@ nsXFormsEditableAccessible::NativeState()
} }
} }
nsCOMPtr<nsIEditor> editor; nsCOMPtr<nsIEditor> editor = GetEditor();
GetAssociatedEditor(getter_AddRefs(editor));
NS_ENSURE_TRUE(editor, state); NS_ENSURE_TRUE(editor, state);
PRUint32 flags; PRUint32 flags;
editor->GetFlags(&flags); editor->GetFlags(&flags);
@@ -286,11 +285,14 @@ nsXFormsEditableAccessible::NativeState()
return state; return state;
} }
NS_IMETHODIMP already_AddRefed<nsIEditor>
nsXFormsEditableAccessible::GetAssociatedEditor(nsIEditor **aEditor) nsXFormsEditableAccessible::GetEditor() const
{ {
nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent)); nsCOMPtr<nsIDOMNode> DOMNode(do_QueryInterface(mContent));
return sXFormsService->GetEditor(DOMNode, aEditor);
nsCOMPtr<nsIEditor> editor;
sXFormsService->GetEditor(DOMNode, getter_AddRefs(editor));
return editor.forget();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@@ -144,8 +144,8 @@ class nsXFormsEditableAccessible : public nsXFormsAccessible
public: public:
nsXFormsEditableAccessible(nsIContent* aContent, nsDocAccessible* aDoc); nsXFormsEditableAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
// nsIAccessibleEditableText // nsHyperTextAccessible
NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor); virtual already_AddRefed<nsIEditor> GetEditor() const;
// nsAccessible // nsAccessible
virtual PRUint64 NativeState(); virtual PRUint64 NativeState();

View File

@@ -850,14 +850,17 @@ nsXULTextFieldAccessible::CanHaveAnonChildren()
return false; return false;
} }
NS_IMETHODIMP nsXULTextFieldAccessible::GetAssociatedEditor(nsIEditor **aEditor) already_AddRefed<nsIEditor>
nsXULTextFieldAccessible::GetEditor() const
{ {
*aEditor = nsnull;
nsCOMPtr<nsIContent> inputField = GetInputField(); nsCOMPtr<nsIContent> inputField = GetInputField();
nsCOMPtr<nsIDOMNSEditableElement> editableElt(do_QueryInterface(inputField)); nsCOMPtr<nsIDOMNSEditableElement> editableElt(do_QueryInterface(inputField));
NS_ENSURE_TRUE(editableElt, NS_ERROR_FAILURE); if (!editableElt)
return editableElt->GetEditor(aEditor); return nsnull;
nsCOMPtr<nsIEditor> editor;
editableElt->GetEditor(getter_AddRefs(editor));
return editor.forget();
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////

View File

@@ -260,8 +260,8 @@ public:
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName); NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index); NS_IMETHOD DoAction(PRUint8 index);
// nsIAccessibleEditableText // nsHyperTextAccessible
NS_IMETHOD GetAssociatedEditor(nsIEditor **aEditor); virtual already_AddRefed<nsIEditor> GetEditor() const;
// nsAccessible // nsAccessible
virtual void ApplyARIAState(PRUint64* aState); virtual void ApplyARIAState(PRUint64* aState);