Bug 669026 Fix caret movement when contenteditable areas are present r=ehsan

This commit is contained in:
Neil Rashbrook 2011-12-24 00:11:30 +00:00
parent 7526912220
commit 985ba4520e
19 changed files with 306 additions and 177 deletions

View File

@ -2625,6 +2625,12 @@ nsHTMLInputElement::GetControllers(nsIControllers** aResult)
NS_ENSURE_SUCCESS(rv, rv);
mControllers->AppendController(controller);
controller = do_CreateInstance("@mozilla.org/editor/editingcontroller;1",
&rv);
NS_ENSURE_SUCCESS(rv, rv);
mControllers->AppendController(controller);
}
}

View File

@ -816,6 +816,12 @@ nsHTMLTextAreaElement::GetControllers(nsIControllers** aResult)
return rv;
mControllers->AppendController(controller);
controller = do_CreateInstance("@mozilla.org/editor/editingcontroller;1", &rv);
if (NS_FAILED(rv))
return rv;
mControllers->AppendController(controller);
}
*aResult = mControllers;

View File

@ -1,10 +1,10 @@
<handler event="keypress" key=" " modifiers="shift" command="cmd_scrollPageUp" />
<handler event="keypress" key=" " command="cmd_scrollPageDown" />
<handler event="keypress" keycode="VK_UP" command="cmd_scrollLineUp" />
<handler event="keypress" keycode="VK_DOWN" command="cmd_scrollLineDown" />
<handler event="keypress" keycode="VK_LEFT" command="cmd_scrollLeft" />
<handler event="keypress" keycode="VK_RIGHT" command="cmd_scrollRight" />
<handler event="keypress" keycode="VK_UP" command="cmd_linePrevious" />
<handler event="keypress" keycode="VK_DOWN" command="cmd_lineNext" />
<handler event="keypress" keycode="VK_LEFT" command="cmd_charPrevious" />
<handler event="keypress" keycode="VK_RIGHT" command="cmd_charNext" />
<handler event="keypress" key="x" command="cmd_cut" modifiers="accel"/>
<handler event="keypress" key="c" command="cmd_copy" modifiers="accel"/>

View File

@ -169,8 +169,8 @@
<handler event="keypress" keycode="VK_INSERT" modifiers="control" command="cmd_copy" />
<handler event="keypress" keycode="VK_HOME" command="cmd_beginLine"/>
<handler event="keypress" keycode="VK_END" command="cmd_endLine"/>
<handler event="keypress" keycode="VK_HOME" modifiers="control" command="cmd_scrollTop"/>
<handler event="keypress" keycode="VK_END" modifiers="control" command="cmd_scrollBottom"/>
<handler event="keypress" keycode="VK_HOME" modifiers="control" command="cmd_moveTop"/>
<handler event="keypress" keycode="VK_END" modifiers="control" command="cmd_moveBottom"/>
<handler event="keypress" keycode="VK_HOME" modifiers="shift,control" command="cmd_selectTop" />
<handler event="keypress" keycode="VK_END" modifiers="shift,control" command="cmd_selectBottom" />

View File

@ -106,8 +106,8 @@
<handler event="keypress" keycode="VK_RIGHT" modifiers="shift" command="cmd_selectCharNext" />
<handler event="keypress" keycode="VK_UP" modifiers="shift" command="cmd_selectLinePrevious" />
<handler event="keypress" keycode="VK_DOWN" modifiers="shift" command="cmd_selectLineNext" />
<handler event="keypress" keycode="VK_UP" modifiers="accel" command="cmd_scrollTop"/>
<handler event="keypress" keycode="VK_DOWN" modifiers="accel" command="cmd_scrollBottom"/>
<handler event="keypress" keycode="VK_UP" modifiers="accel" command="cmd_moveTop"/>
<handler event="keypress" keycode="VK_DOWN" modifiers="accel" command="cmd_moveBottom"/>
</handlers>
</binding>

View File

@ -41,8 +41,8 @@
<handler event="keypress" keycode="VK_INSERT" modifiers="control" command="cmd_copy" />
<handler event="keypress" keycode="VK_HOME" command="cmd_beginLine"/>
<handler event="keypress" keycode="VK_END" command="cmd_endLine"/>
<handler event="keypress" keycode="VK_HOME" modifiers="control" command="cmd_scrollTop"/>
<handler event="keypress" keycode="VK_END" modifiers="control" command="cmd_scrollBottom"/>
<handler event="keypress" keycode="VK_HOME" modifiers="control" command="cmd_moveTop"/>
<handler event="keypress" keycode="VK_END" modifiers="control" command="cmd_moveBottom"/>
<handler event="keypress" keycode="VK_HOME" modifiers="shift,control" command="cmd_selectTop" />
<handler event="keypress" keycode="VK_END" modifiers="shift,control" command="cmd_selectBottom" />

View File

@ -101,8 +101,8 @@
<handler event="keypress" keycode="VK_INSERT" modifiers="control" command="cmd_copy"/>
<handler event="keypress" keycode="VK_HOME" command="cmd_beginLine"/>
<handler event="keypress" keycode="VK_END" command="cmd_endLine"/>
<handler event="keypress" keycode="VK_HOME" modifiers="control" command="cmd_scrollTop"/>
<handler event="keypress" keycode="VK_END" modifiers="control" command="cmd_scrollBottom"/>
<handler event="keypress" keycode="VK_HOME" modifiers="control" command="cmd_moveTop"/>
<handler event="keypress" keycode="VK_END" modifiers="control" command="cmd_moveBottom"/>
<handler event="keypress" keycode="VK_HOME" modifiers="shift,control" command="cmd_selectTop" />
<handler event="keypress" keycode="VK_END" modifiers="shift,control" command="cmd_selectBottom" />

View File

@ -2457,14 +2457,6 @@ nsFocusManager::DetermineElementToMoveFocus(nsPIDOMWindow* aWindow,
if (startContent == rootContent) {
startContent = nsnull;
}
else if (startContent && startContent->HasFlag(NODE_IS_EDITABLE)) {
// Don't start from the selection if the selection is in a
// contentEditable region.
nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(doc);
if (htmlDoc &&
htmlDoc->GetEditingState() == nsIHTMLDocument::eContentEditable)
startContent = nsnull;
}
if (aType == MOVEFOCUS_CARET) {
// GetFocusInSelection finds a focusable link near the caret.

View File

@ -76,12 +76,14 @@ const char * const sScrollTopString = "cmd_scrollTop";
const char * const sScrollBottomString = "cmd_scrollBottom";
const char * const sScrollPageUpString = "cmd_scrollPageUp";
const char * const sScrollPageDownString = "cmd_scrollPageDown";
const char * const sMoveTopString = "cmd_moveTop";
const char * const sMoveBottomString = "cmd_moveBottom";
const char * const sMovePageUpString = "cmd_movePageUp";
const char * const sMovePageDownString = "cmd_movePageDown";
const char * const sScrollLineUpString = "cmd_scrollLineUp";
const char * const sScrollLineDownString = "cmd_scrollLineDown";
const char * const sScrollLeftString = "cmd_scrollLeft";
const char * const sScrollRightString = "cmd_scrollRight";
const char * const sLinePreviousString = "cmd_linePrevious";
const char * const sLineNextString = "cmd_lineNext";
const char * const sCharPreviousString = "cmd_charPrevious";
const char * const sCharNextString = "cmd_charNext";
// These are so the browser can use editor navigation key bindings
// helps with accessibility (boolean pref accessibility.browsewithcaret)
@ -102,8 +104,8 @@ const char * const sSelectEndLineString = "cmd_selectEndLine";
const char * const sSelectLinePreviousString = "cmd_selectLinePrevious";
const char * const sSelectLineNextString = "cmd_selectLineNext";
const char * const sSelectPagePreviousString = "cmd_selectPagePrevious";
const char * const sSelectPageNextString = "cmd_selectPageNext";
const char * const sSelectPageUpString = "cmd_selectPageUp";
const char * const sSelectPageDownString = "cmd_selectPageDown";
const char * const sSelectTopString = "cmd_selectTop";
const char * const sSelectBottomString = "cmd_selectBottom";
@ -277,10 +279,18 @@ nsSelectMoveScrollCommand::DoCommandBrowseWithCaretOn(const char *aCommandName,
{
nsresult rv = NS_ERROR_NOT_IMPLEMENTED;
if (!nsCRT::strcmp(aCommandName, sScrollTopString))
// cmd_MoveTop/Bottom are used on Window/Unix. They move the caret
// in caret browsing mode.
if (!nsCRT::strcmp(aCommandName, sMoveTopString))
rv = aSelectionController->CompleteMove(false, false);
else if (!nsCRT::strcmp(aCommandName,sScrollBottomString))
else if (!nsCRT::strcmp(aCommandName,sMoveBottomString))
rv = aSelectionController->CompleteMove(true, false);
// cmd_ScrollTop/Bottom are used on Mac. They do not move the
// caret in caret browsing mode.
else if (!nsCRT::strcmp(aCommandName, sScrollTopString))
rv = aSelectionController->CompleteScroll(false);
else if (!nsCRT::strcmp(aCommandName,sScrollBottomString))
rv = aSelectionController->CompleteScroll(true);
// cmd_MovePageUp/Down are used on Window/Unix. They move the caret
// in caret browsing mode.
else if (!nsCRT::strcmp(aCommandName, sMovePageUpString))
@ -293,17 +303,17 @@ nsSelectMoveScrollCommand::DoCommandBrowseWithCaretOn(const char *aCommandName,
rv = aSelectionController->ScrollPage(false);
else if (!nsCRT::strcmp(aCommandName, sScrollPageDownString))
rv = aSelectionController->ScrollPage(true);
else if (!nsCRT::strcmp(aCommandName, sScrollLineUpString))
else if (!nsCRT::strcmp(aCommandName, sLinePreviousString))
rv = aSelectionController->LineMove(false, false);
else if (!nsCRT::strcmp(aCommandName, sScrollLineDownString))
else if (!nsCRT::strcmp(aCommandName, sLineNextString))
rv = aSelectionController->LineMove(true, false);
else if (!nsCRT::strcmp(aCommandName, sWordPreviousString))
rv = aSelectionController->WordMove(false, false);
else if (!nsCRT::strcmp(aCommandName, sWordNextString))
rv = aSelectionController->WordMove(true, false);
else if (!nsCRT::strcmp(aCommandName, sScrollLeftString))
else if (!nsCRT::strcmp(aCommandName, sCharPreviousString))
rv = aSelectionController->CharacterMove(false, false);
else if (!nsCRT::strcmp(aCommandName, sScrollRightString))
else if (!nsCRT::strcmp(aCommandName, sCharNextString))
rv = aSelectionController->CharacterMove(true, false);
else if (!nsCRT::strcmp(aCommandName, sBeginLineString))
rv = aSelectionController->IntraLineMove(false, false);
@ -330,7 +340,15 @@ nsSelectMoveScrollCommand::DoCommandBrowseWithCaretOff(const char *aCommandName,
{
nsresult rv = NS_ERROR_NOT_IMPLEMENTED;
if (!nsCRT::strcmp(aCommandName, sScrollTopString))
// cmd_MoveTop/Bottom are used on Window/Unix. They move the caret
// in caret browsing mode.
if (!nsCRT::strcmp(aCommandName, sMoveTopString))
rv = aSelectionController->CompleteScroll(false);
else if (!nsCRT::strcmp(aCommandName,sMoveBottomString))
rv = aSelectionController->CompleteScroll(true);
// cmd_ScrollTop/Bottom are used on Mac. They do not move the
// caret in caret browsing mode.
else if (!nsCRT::strcmp(aCommandName, sScrollTopString))
rv = aSelectionController->CompleteScroll(false);
else if (!nsCRT::strcmp(aCommandName,sScrollBottomString))
rv = aSelectionController->CompleteScroll(true);
@ -348,16 +366,16 @@ nsSelectMoveScrollCommand::DoCommandBrowseWithCaretOff(const char *aCommandName,
else if (!nsCRT::strcmp(aCommandName, sScrollPageDownString))
rv = aSelectionController->ScrollPage(true);
else if (!nsCRT::strcmp(aCommandName, sScrollLineUpString))
else if (!nsCRT::strcmp(aCommandName, sLinePreviousString))
rv = aSelectionController->ScrollLine(false);
else if (!nsCRT::strcmp(aCommandName, sScrollLineDownString))
else if (!nsCRT::strcmp(aCommandName, sLineNextString))
rv = aSelectionController->ScrollLine(true);
else if (!nsCRT::strcmp(aCommandName, sScrollLeftString))
else if (!nsCRT::strcmp(aCommandName, sCharPreviousString))
rv = aSelectionController->ScrollHorizontal(true);
else if (!nsCRT::strcmp(aCommandName, sScrollRightString))
else if (!nsCRT::strcmp(aCommandName, sCharNextString))
rv = aSelectionController->ScrollHorizontal(false);
// cmd_beginLine/endLine with caret browsing off
// will act as cmd_scrollTop/Bottom
// will act as cmd_moveTop/Bottom
else if (!nsCRT::strcmp(aCommandName, sBeginLineString))
rv = aSelectionController->CompleteScroll(false);
else if (!nsCRT::strcmp(aCommandName, sEndLineString))
@ -398,6 +416,10 @@ nsSelectCommand::DoSelectCommand(const char *aCommandName, nsIDOMWindow *aWindow
rv = selCont->LineMove(false, true);
else if (!nsCRT::strcmp(aCommandName, sSelectLineNextString))
rv = selCont->LineMove(true, true);
else if (!nsCRT::strcmp(aCommandName, sSelectPageUpString))
rv = selCont->PageMove(false, true);
else if (!nsCRT::strcmp(aCommandName, sSelectPageDownString))
rv = selCont->PageMove(true, true);
else if (!nsCRT::strcmp(aCommandName, sSelectTopString))
rv = selCont->CompleteMove(false, true);
else if (!nsCRT::strcmp(aCommandName, sSelectBottomString))
@ -946,6 +968,8 @@ nsWindowCommandRegistration::RegisterWindowCommands(
// this set of commands is affected by the 'browse with caret' setting
NS_REGISTER_FIRST_COMMAND(nsSelectMoveScrollCommand, sScrollTopString);
NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sScrollBottomString);
NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sMoveTopString);
NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sMoveBottomString);
NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sWordPreviousString);
NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sWordNextString);
NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sBeginLineString);
@ -954,10 +978,10 @@ nsWindowCommandRegistration::RegisterWindowCommands(
NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sMovePageDownString);
NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sScrollPageUpString);
NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sScrollPageDownString);
NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sScrollLineUpString);
NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sScrollLineDownString);
NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sScrollLeftString);
NS_REGISTER_LAST_COMMAND(nsSelectMoveScrollCommand, sScrollRightString);
NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sLinePreviousString);
NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sLineNextString);
NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sCharPreviousString);
NS_REGISTER_LAST_COMMAND(nsSelectMoveScrollCommand, sCharNextString);
NS_REGISTER_FIRST_COMMAND(nsSelectCommand, sSelectCharPreviousString);
NS_REGISTER_NEXT_COMMAND(nsSelectCommand, sSelectCharNextString);
@ -967,9 +991,8 @@ nsWindowCommandRegistration::RegisterWindowCommands(
NS_REGISTER_NEXT_COMMAND(nsSelectCommand, sSelectEndLineString);
NS_REGISTER_NEXT_COMMAND(nsSelectCommand, sSelectLinePreviousString);
NS_REGISTER_NEXT_COMMAND(nsSelectCommand, sSelectLineNextString);
// XXX these commands were never implemented. fix me.
// NS_REGISTER_NEXT_COMMAND(nsSelectCommand, sSelectPagePreviousString);
// NS_REGISTER_NEXT_COMMAND(nsSelectCommand, sSelectPageNextString);
NS_REGISTER_NEXT_COMMAND(nsSelectCommand, sSelectPageUpString);
NS_REGISTER_NEXT_COMMAND(nsSelectCommand, sSelectPageDownString);
NS_REGISTER_NEXT_COMMAND(nsSelectCommand, sSelectTopString);
NS_REGISTER_LAST_COMMAND(nsSelectCommand, sSelectBottomString);

View File

@ -184,8 +184,8 @@ nsEditingSession::MakeWindowEditable(nsIDOMWindow *aWindow,
// Setup commands common to plaintext and html editors,
// including the document creation observers
// the first is an editor controller
rv = SetupEditorCommandController("@mozilla.org/editor/editorcontroller;1",
// the first is an editing controller
rv = SetupEditorCommandController("@mozilla.org/editor/editingcontroller;1",
aWindow,
static_cast<nsIEditingSession*>(this),
&mBaseCommandControllerId);
@ -1435,7 +1435,7 @@ nsEditingSession::ReattachToWindow(nsIDOMWindow* aWindow)
NS_ENSURE_SUCCESS(rv, rv);
// Setup the command controllers again.
rv = SetupEditorCommandController("@mozilla.org/editor/editorcontroller;1",
rv = SetupEditorCommandController("@mozilla.org/editor/editingcontroller;1",
aWindow,
static_cast<nsIEditingSession*>(this),
&mBaseCommandControllerId);

View File

@ -71,7 +71,7 @@
// static
nsresult nsEditorController::RegisterEditorCommands(nsIControllerCommandTable *inCommandTable)
nsresult nsEditorController::RegisterEditingCommands(nsIControllerCommandTable *inCommandTable)
{
nsresult rv;
@ -101,6 +101,21 @@ nsresult nsEditorController::RegisterEditorCommands(nsIControllerCommandTable *i
NS_REGISTER_NEXT_COMMAND(nsDeleteCommand, "cmd_deleteToBeginningOfLine");
NS_REGISTER_LAST_COMMAND(nsDeleteCommand, "cmd_deleteToEndOfLine");
// Insert content
NS_REGISTER_ONE_COMMAND(nsInsertPlaintextCommand, "cmd_insertText");
NS_REGISTER_ONE_COMMAND(nsPasteQuotationCommand, "cmd_pasteQuote");
return NS_OK;
}
// static
nsresult nsEditorController::RegisterEditorCommands(nsIControllerCommandTable *inCommandTable)
{
nsresult rv;
// These are commands that will be used in text widgets only.
NS_REGISTER_FIRST_COMMAND(nsSelectionMoveCommands, "cmd_scrollTop");
NS_REGISTER_NEXT_COMMAND(nsSelectionMoveCommands, "cmd_scrollBottom");
NS_REGISTER_NEXT_COMMAND(nsSelectionMoveCommands, "cmd_moveTop");
@ -131,11 +146,6 @@ nsresult nsEditorController::RegisterEditorCommands(nsIControllerCommandTable *i
NS_REGISTER_NEXT_COMMAND(nsSelectionMoveCommands, "cmd_movePageDown");
NS_REGISTER_NEXT_COMMAND(nsSelectionMoveCommands, "cmd_selectPageUp");
NS_REGISTER_LAST_COMMAND(nsSelectionMoveCommands, "cmd_selectPageDown");
// Insert content
NS_REGISTER_ONE_COMMAND(nsInsertPlaintextCommand, "cmd_insertText");
NS_REGISTER_ONE_COMMAND(nsPasteQuotationCommand, "cmd_pasteQuote");
return NS_OK;
}

View File

@ -41,6 +41,9 @@
#define NS_EDITORCONTROLLER_CID \
{ 0x26fb965c, 0x9de6, 0x11d3, { 0xbc, 0xcc, 0x0, 0x60, 0xb0, 0xfc, 0x76, 0xbd } }
#define NS_EDITINGCONTROLLER_CID \
{ 0x2c5a5cdd, 0xe742, 0x4dfe, { 0x86, 0xb8, 0x06, 0x93, 0x09, 0xbf, 0x6c, 0x91 } }
class nsIControllerCommandTable;
@ -51,6 +54,7 @@ class nsEditorController
{
public:
static nsresult RegisterEditorCommands(nsIControllerCommandTable* inCommandTable);
static nsresult RegisterEditingCommands(nsIControllerCommandTable* inCommandTable);
};
#endif /* nsEditorController_h__ */

View File

@ -38,6 +38,7 @@ function execTests() {
doc.designMode='on';
body.innerHTML = "1<br>2<br>3<br>4<br>5<br>6<br>7<br>8<br>9<br>10<br>11<br>12<br>";
win.focus();
yield;
function doCommand(cmd) {
var controller = document.commandDispatcher.getControllerForCommand(cmd);
@ -122,16 +123,6 @@ function execTests() {
yield;
testScrollCommand("cmd_scrollPageUp", root.scrollHeight - 100 - pageHeight);
doCommand("cmd_scrollTop");
doCommand("cmd_scrollLineDown");
yield;
var lineHeight = -root.getBoundingClientRect().top;
ok(lineHeight > 0, "Can scroll by lines");
doCommand("cmd_scrollBottom");
doCommand("cmd_scrollLineUp");
yield;
testScrollCommand("cmd_scrollLineUp", root.scrollHeight - 100 - lineHeight);
var runSelectionTests = function(selectWordNextNode, selectWordNextOffset) {
testMoveCommand("cmd_moveBottom", body, 23);
testMoveCommand("cmd_moveTop", node(0), 0);

View File

@ -21,7 +21,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=549262
SimpleTest.waitForExplicitFinish();
var win = window.open("file_bug549262.html", "_blank",
"width=600,height=600");
"width=600,height=600,scrollbars=yes");
SimpleTest.waitForFocus(function() {
// Make sure that pressing Space when a contenteditable element is not focused
// will scroll the page.
@ -58,8 +58,44 @@ SimpleTest.waitForFocus(function() {
isnot(win.scrollY, 0, "Page is not scrolled up");
is(ed.textContent, "a b c", "The content of the editable element has changed");
win.close();
SimpleTest.finish();
// Now let's test the down/up keys
sc = document.body;
setTimeout(function() {
ed.blur();
sc.focus();
var oldY = win.scrollY;
synthesizeKey("VK_UP", {}, win);
setTimeout(function() {
ok(win.scrollY < oldY, "Page is scrolled up");
oldY = win.scrollY;
ed.focus();
win.getSelection().collapse(ed.firstChild, 3);
synthesizeKey("VK_UP", {}, win);
setTimeout(function() {
is(win.scrollY, oldY, "Page is not scrolled up");
is(win.getSelection().focusNode, ed.firstChild, "Correct element selected");
is(win.getSelection().focusOffset, 0, "Selection should be moved to the beginning");
win.getSelection().removeAllRanges();
synthesizeMouse(sc, 300, 300, {}, win);
synthesizeKey("VK_DOWN", {}, win);
setTimeout(function() {
ok(win.scrollY > oldY, "Page is scrolled down");
ed.focus();
win.getSelection().collapse(ed.firstChild, 3);
oldY = win.scrollY;
synthesizeKey("VK_DOWN", {}, win);
setTimeout(function() {
is(win.scrollY, oldY, "Page is not scrolled down");
is(win.getSelection().focusNode, ed.firstChild, "Correct element selected");
is(win.getSelection().focusOffset, ed.textContent.length, "Selection should be moved to the end");
win.close();
SimpleTest.finish();
}, 0);
}, 0);
}, 0);
}, 0);
}, 0);
}, 0);
}, 0);
}, 0);

View File

@ -2408,7 +2408,12 @@ PresShell::CharacterExtendForBackspace()
NS_IMETHODIMP
PresShell::WordMove(bool aForward, bool aExtend)
{
return mSelection->WordMove(aForward, aExtend);
nsresult result = mSelection->WordMove(aForward, aExtend);
// if we can't go down/up any more we must then move caret completely to
// end/beginning respectively.
if (NS_FAILED(result))
result = CompleteMove(aForward, aExtend);
return result;
}
NS_IMETHODIMP

View File

@ -164,60 +164,15 @@ using mozilla::dom::telephony::AudioManager;
#define NS_EDITORCOMMANDTABLE_CID \
{ 0x4f5e62b8, 0xd659, 0x4156, { 0x84, 0xfc, 0x2f, 0x60, 0x99, 0x40, 0x03, 0x69 }}
#define NS_EDITINGCOMMANDTABLE_CID \
{ 0xcb38a746, 0xbeb8, 0x43f3, { 0x94, 0x29, 0x77, 0x96, 0xe1, 0xa9, 0x3f, 0xb4 }}
#define NS_HAPTICFEEDBACK_CID \
{ 0x1f15dbc8, 0xbfaa, 0x45de, \
{ 0x8a, 0x46, 0x08, 0xe2, 0xe2, 0x63, 0x26, 0xb0 } }
static NS_DEFINE_CID(kEditorCommandTableCID, NS_EDITORCOMMANDTABLE_CID);
NS_GENERIC_FACTORY_CONSTRUCTOR(nsPlaintextEditor)
// Constructor of a controller which is set up to use, internally, a
// singleton command-table pre-filled with editor commands.
static nsresult
nsEditorControllerConstructor(nsISupports *aOuter, REFNSIID aIID,
void **aResult)
{
nsresult rv;
nsCOMPtr<nsIController> controller = do_CreateInstance("@mozilla.org/embedcomp/base-command-controller;1", &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIControllerCommandTable> editorCommandTable = do_GetService(kEditorCommandTableCID, &rv);
if (NS_FAILED(rv)) return rv;
// this guy is a singleton, so make it immutable
editorCommandTable->MakeImmutable();
nsCOMPtr<nsIControllerContext> controllerContext = do_QueryInterface(controller, &rv);
if (NS_FAILED(rv)) return rv;
rv = controllerContext->Init(editorCommandTable);
if (NS_FAILED(rv)) return rv;
return controller->QueryInterface(aIID, aResult);
}
// Constructor for a command-table pref-filled with editor commands
static nsresult
nsEditorCommandTableConstructor(nsISupports *aOuter, REFNSIID aIID,
void **aResult)
{
nsresult rv;
nsCOMPtr<nsIControllerCommandTable> commandTable =
do_CreateInstance(NS_CONTROLLERCOMMANDTABLE_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
rv = nsEditorController::RegisterEditorCommands(commandTable);
if (NS_FAILED(rv)) return rv;
// we don't know here whether we're being created as an instance,
// or a service, so we can't become immutable
return commandTable->QueryInterface(aIID, aResult);
}
NS_GENERIC_FACTORY_CONSTRUCTOR(nsTextServicesDocument)
#ifdef ENABLE_EDITOR_API_LOG
#include "nsHTMLEditorLog.h"
@ -254,8 +209,6 @@ class nsIDocumentLoaderFactory;
{ /* 0DE2FBFA-6B7F-11D7-BBBA-0003938A9D96 */ \
0x0DE2FBFA, 0x6B7F, 0x11D7, {0xBB, 0xBA, 0x00, 0x03, 0x93, 0x8A, 0x9D, 0x96} }
static NS_DEFINE_CID(kWindowCommandTableCID, NS_WINDOWCOMMANDTABLE_CID);
#include "nsIBoxObject.h"
#ifdef MOZ_XUL
@ -683,46 +636,6 @@ CreateHTMLAudioElement(nsISupports* aOuter, REFNSIID aIID, void** aResult)
}
#endif
static nsresult
CreateWindowCommandTableConstructor(nsISupports *aOuter,
REFNSIID aIID, void **aResult)
{
nsresult rv;
nsCOMPtr<nsIControllerCommandTable> commandTable =
do_CreateInstance(NS_CONTROLLERCOMMANDTABLE_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
rv = nsWindowCommandRegistration::RegisterWindowCommands(commandTable);
if (NS_FAILED(rv)) return rv;
return commandTable->QueryInterface(aIID, aResult);
}
static nsresult
CreateWindowControllerWithSingletonCommandTable(nsISupports *aOuter,
REFNSIID aIID, void **aResult)
{
nsresult rv;
nsCOMPtr<nsIController> controller =
do_CreateInstance("@mozilla.org/embedcomp/base-command-controller;1", &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIControllerCommandTable> windowCommandTable = do_GetService(kWindowCommandTableCID, &rv);
if (NS_FAILED(rv)) return rv;
// this is a singleton; make it immutable
windowCommandTable->MakeImmutable();
nsCOMPtr<nsIControllerContext> controllerContext = do_QueryInterface(controller, &rv);
if (NS_FAILED(rv)) return rv;
controllerContext->Init(windowCommandTable);
if (NS_FAILED(rv)) return rv;
return controller->QueryInterface(aIID, aResult);
}
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDOMScriptObjectFactory)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsBaseDOMException)
@ -870,7 +783,9 @@ NS_DEFINE_NAMED_CID(NS_HTMLEDITOR_CID);
NS_DEFINE_NAMED_CID(NS_HTMLEDITOR_CID);
#endif
NS_DEFINE_NAMED_CID(NS_EDITORCONTROLLER_CID);
NS_DEFINE_NAMED_CID(NS_EDITINGCONTROLLER_CID);
NS_DEFINE_NAMED_CID(NS_EDITORCOMMANDTABLE_CID);
NS_DEFINE_NAMED_CID(NS_EDITINGCOMMANDTABLE_CID);
NS_DEFINE_NAMED_CID(NS_TEXTSERVICESDOCUMENT_CID);
NS_DEFINE_NAMED_CID(NS_GEOLOCATION_SERVICE_CID);
NS_DEFINE_NAMED_CID(NS_GEOLOCATION_CID);
@ -902,6 +817,135 @@ NS_DEFINE_NAMED_CID(NS_HAPTICFEEDBACK_CID);
#endif
NS_DEFINE_NAMED_CID(NS_SMSSERVICE_CID);
static nsresult
CreateWindowCommandTableConstructor(nsISupports *aOuter,
REFNSIID aIID, void **aResult)
{
nsresult rv;
nsCOMPtr<nsIControllerCommandTable> commandTable =
do_CreateInstance(NS_CONTROLLERCOMMANDTABLE_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
rv = nsWindowCommandRegistration::RegisterWindowCommands(commandTable);
if (NS_FAILED(rv)) return rv;
return commandTable->QueryInterface(aIID, aResult);
}
static nsresult
CreateWindowControllerWithSingletonCommandTable(nsISupports *aOuter,
REFNSIID aIID, void **aResult)
{
nsresult rv;
nsCOMPtr<nsIController> controller =
do_CreateInstance("@mozilla.org/embedcomp/base-command-controller;1", &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIControllerCommandTable> windowCommandTable = do_GetService(kNS_WINDOWCOMMANDTABLE_CID, &rv);
if (NS_FAILED(rv)) return rv;
// this is a singleton; make it immutable
windowCommandTable->MakeImmutable();
nsCOMPtr<nsIControllerContext> controllerContext = do_QueryInterface(controller, &rv);
if (NS_FAILED(rv)) return rv;
controllerContext->Init(windowCommandTable);
if (NS_FAILED(rv)) return rv;
return controller->QueryInterface(aIID, aResult);
}
// Constructor of a controller which is set up to use, internally, a
// singleton command-table pre-filled with editor commands.
static nsresult
nsEditorControllerConstructor(nsISupports *aOuter, REFNSIID aIID,
void **aResult)
{
nsresult rv;
nsCOMPtr<nsIController> controller = do_CreateInstance("@mozilla.org/embedcomp/base-command-controller;1", &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIControllerCommandTable> editorCommandTable = do_GetService(kNS_EDITORCOMMANDTABLE_CID, &rv);
if (NS_FAILED(rv)) return rv;
// this guy is a singleton, so make it immutable
editorCommandTable->MakeImmutable();
nsCOMPtr<nsIControllerContext> controllerContext = do_QueryInterface(controller, &rv);
if (NS_FAILED(rv)) return rv;
rv = controllerContext->Init(editorCommandTable);
if (NS_FAILED(rv)) return rv;
return controller->QueryInterface(aIID, aResult);
}
// Constructor of a controller which is set up to use, internally, a
// singleton command-table pre-filled with editing commands.
static nsresult
nsEditingControllerConstructor(nsISupports *aOuter, REFNSIID aIID,
void **aResult)
{
nsresult rv;
nsCOMPtr<nsIController> controller = do_CreateInstance("@mozilla.org/embedcomp/base-command-controller;1", &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIControllerCommandTable> editingCommandTable = do_GetService(kNS_EDITINGCOMMANDTABLE_CID, &rv);
if (NS_FAILED(rv)) return rv;
// this guy is a singleton, so make it immutable
editingCommandTable->MakeImmutable();
nsCOMPtr<nsIControllerContext> controllerContext = do_QueryInterface(controller, &rv);
if (NS_FAILED(rv)) return rv;
rv = controllerContext->Init(editingCommandTable);
if (NS_FAILED(rv)) return rv;
return controller->QueryInterface(aIID, aResult);
}
// Constructor for a command-table pre-filled with editor commands
static nsresult
nsEditorCommandTableConstructor(nsISupports *aOuter, REFNSIID aIID,
void **aResult)
{
nsresult rv;
nsCOMPtr<nsIControllerCommandTable> commandTable =
do_CreateInstance(NS_CONTROLLERCOMMANDTABLE_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
rv = nsEditorController::RegisterEditorCommands(commandTable);
if (NS_FAILED(rv)) return rv;
// we don't know here whether we're being created as an instance,
// or a service, so we can't become immutable
return commandTable->QueryInterface(aIID, aResult);
}
// Constructor for a command-table pre-filled with editing commands
static nsresult
nsEditingCommandTableConstructor(nsISupports *aOuter, REFNSIID aIID,
void **aResult)
{
nsresult rv;
nsCOMPtr<nsIControllerCommandTable> commandTable =
do_CreateInstance(NS_CONTROLLERCOMMANDTABLE_CONTRACTID, &rv);
if (NS_FAILED(rv)) return rv;
rv = nsEditorController::RegisterEditingCommands(commandTable);
if (NS_FAILED(rv)) return rv;
// we don't know here whether we're being created as an instance,
// or a service, so we can't become immutable
return commandTable->QueryInterface(aIID, aResult);
}
static const mozilla::Module::CIDEntry kLayoutCIDs[] = {
XPCONNECT_CIDENTRIES
#ifdef DEBUG
@ -1012,7 +1056,9 @@ static const mozilla::Module::CIDEntry kLayoutCIDs[] = {
{ &kNS_HTMLEDITOR_CID, false, NULL, nsHTMLEditorConstructor },
#endif
{ &kNS_EDITORCONTROLLER_CID, false, NULL, nsEditorControllerConstructor },
{ &kNS_EDITINGCONTROLLER_CID, false, NULL, nsEditingControllerConstructor },
{ &kNS_EDITORCOMMANDTABLE_CID, false, NULL, nsEditorCommandTableConstructor },
{ &kNS_EDITINGCOMMANDTABLE_CID, false, NULL, nsEditingCommandTableConstructor },
{ &kNS_TEXTSERVICESDOCUMENT_CID, false, NULL, nsTextServicesDocumentConstructor },
{ &kNS_GEOLOCATION_SERVICE_CID, false, NULL, nsGeolocationServiceConstructor },
{ &kNS_GEOLOCATION_CID, false, NULL, nsGeolocationConstructor },
@ -1148,7 +1194,7 @@ static const mozilla::Module::ContractIDEntry kLayoutContracts[] = {
{ "@mozilla.org/editor/htmleditor;1", &kNS_HTMLEDITOR_CID },
#endif
{ "@mozilla.org/editor/editorcontroller;1", &kNS_EDITORCONTROLLER_CID },
{ "", &kNS_EDITORCOMMANDTABLE_CID },
{ "@mozilla.org/editor/editingcontroller;1", &kNS_EDITINGCONTROLLER_CID },
{ "@mozilla.org/textservices/textservicesdocument;1", &kNS_TEXTSERVICESDOCUMENT_CID },
{ "@mozilla.org/geolocation/service;1", &kNS_GEOLOCATION_SERVICE_CID },
{ "@mozilla.org/geolocation;1", &kNS_GEOLOCATION_CID },

View File

@ -16,8 +16,13 @@
SimpleTest.waitForExplicitFinish();
// This seems to be necessary because the selection is not set up properly otherwise
setTimeout(test, 0);
setTimeout(focusing, 0);
function focusing() {
document.getElementById("editor").focus();
// This seems to be necessary because the selection is not set up properly otherwise
setTimeout(test, 0);
}
function test() {
var sel = window.getSelection();

View File

@ -18,8 +18,13 @@
SimpleTest.waitForExplicitFinish();
// This seems to be necessary because the selection is not set up properly otherwise
setTimeout(test, 0);
setTimeout(focusing, 0);
function focusing() {
document.getElementById("editor").focus();
// This seems to be necessary because the selection is not set up properly otherwise
setTimeout(test, 0);
}
var eatSpace;
@ -191,21 +196,21 @@ function test() {
editor.innerHTML = "Hello Kitty";
sel.collapse(editor.firstChild, 0);
testRight(editor.firstChild, 6);
testRight(afterEditorNode, 0);
testRight(editor.firstChild, 11);
testLeft(editor.firstChild, 6);
testLeft(editor.firstChild, 0);
editor.innerHTML = "<b>Hello</b> Kitty";
sel.collapse(editor.firstChild.firstChild, 0);
testRight(editor.firstChild.nextSibling, 1);
testRight(afterEditorNode, 0);
testRight(editor.firstChild.nextSibling, 6);
testLeft(editor.firstChild.nextSibling, 1);
testLeft(editor.firstChild.firstChild, 0);
editor.innerHTML = "<b>Hello </b>Kitty";
sel.collapse(editor.firstChild.firstChild, 0);
testRight(editor.firstChild.nextSibling, 0);
testRight(afterEditorNode, 0);
testRight(editor.firstChild.nextSibling, 5);
testLeft(editor.firstChild.firstChild, 6);
testLeft(editor.firstChild.firstChild, 0);
@ -213,7 +218,7 @@ function test() {
sel.collapse(editor.firstChild.firstChild, 0);
testRight(editor.firstChild.firstChild, 4);
testRight(editor.firstChild.nextSibling, 2);
testRight(afterEditorNode, 0);
testRight(editor.firstChild.nextSibling, 5);
testLeft(editor.firstChild.nextSibling, 1);
testLeft(editor.firstChild.firstChild, 4);
testLeft(editor.firstChild.firstChild, 0);
@ -232,7 +237,7 @@ function test() {
testRight(editor.firstChild, 4);
testRight(editor.firstChild, 8);
testRight(editor.firstChild.nextSibling.firstChild, 0);
testRight(afterEditorNode, 0);
testRight(editor.firstChild.nextSibling.nextSibling, 5);
testLeft(editor.firstChild.nextSibling.firstChild, 1);
testLeft(editor.firstChild, 10);
testLeft(editor.firstChild, 8);
@ -244,7 +249,7 @@ function test() {
sel.collapse(editor.firstChild, 0);
testRight(editor.firstChild, 2);
testRight(editor.firstChild, 6);
testRight(afterEditorNode, 0);
testRight(editor.firstChild, 8);
testLeft(editor.firstChild, 6);
testLeft(editor.firstChild, 2);
testLeft(editor.firstChild, 0);
@ -253,7 +258,7 @@ function test() {
sel.collapse(editor.firstChild, 0);
testRight(editor.firstChild, 2);
testRight(editor.firstChild, 6);
testRight(afterEditorNode, 0);
testRight(editor.firstChild, 8);
testLeft(editor.firstChild, 6);
testLeft(editor.firstChild, 2);
testLeft(editor.firstChild, 0);
@ -262,7 +267,7 @@ function test() {
sel.collapse(editor.firstChild, 0);
testRight(editor.firstChild, 4);
testRight(editor.firstChild, 8);
testRight(afterEditorNode, 0);
testRight(editor.firstChild, 12);
testLeft(editor.firstChild, 8);
testLeft(editor.firstChild, 4);
testLeft(editor.firstChild, 0);
@ -271,7 +276,7 @@ function test() {
sel.collapse(editor.firstChild, 0);
testRight(editor.firstChild, 5);
testRight(editor.firstChild, 10);
testRight(afterEditorNode, 0);
testRight(editor.firstChild, 14);
testLeft(editor.firstChild, 10);
testLeft(editor.firstChild, 5);
testLeft(editor.firstChild, 0);
@ -280,7 +285,7 @@ function test() {
sel.collapse(editor.firstChild, 0);
testRight(editor.firstChild, 5);
testRight(editor.firstChild, 10);
testRight(afterEditorNode, 0);
testRight(editor.firstChild, 14);
testLeft(editor.firstChild, 10);
testLeft(editor.firstChild, 5);
testLeft(editor.firstChild, 0);
@ -289,7 +294,7 @@ function test() {
sel.collapse(editor.firstChild, 0);
testRight(editor.firstChild, 3);
testRight(editor.firstChild, 6);
testRight(afterEditorNode, 0);
testRight(editor.firstChild, 8);
testLeft(editor.firstChild, 6);
testLeft(editor.firstChild, 3);
testLeft(editor.firstChild, 0);

View File

@ -32,14 +32,14 @@ function runTest()
sel2.collapse(frames[1].document.body, 0);
window.frames[0].focus();
document.commandDispatcher.getControllerForCommand("cmd_scrollBottom").doCommand("cmd_scrollBottom");
document.commandDispatcher.getControllerForCommand("cmd_moveBottom").doCommand("cmd_moveBottom");
ok(frames[0].scrollY > 0, "scrollY for non-showcaret");
is(sel1.focusNode, frames[0].document.body, "focusNode for non-showcaret");
is(sel1.focusOffset, 0, "focusOffset for non-showcaret");
window.frames[1].focus();
document.commandDispatcher.getControllerForCommand("cmd_scrollBottom").doCommand("cmd_scrollBottom");
document.commandDispatcher.getControllerForCommand("cmd_moveBottom").doCommand("cmd_moveBottom");
ok(frames[1].scrollY <
frames[1].document.getElementById('s').getBoundingClientRect().top,
@ -64,7 +64,7 @@ function otherWindowFocused()
hbox.focus();
is(otherWindow.document.activeElement, hbox, "hbox in other window is focused");
document.commandDispatcher.getControllerForCommand("cmd_scrollLineDown").doCommand("cmd_scrollLineDown");
document.commandDispatcher.getControllerForCommand("cmd_lineNext").doCommand("cmd_lineNext");
is(otherWindow.document.activeElement, hbox, "hbox still focused in other window after down movement");
prefs.setBoolPref("accessibility.browsewithcaret", false);