Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 :
8 : #include "nsGlobalWindowCommands.h"
9 :
10 : #include "nsIComponentManager.h"
11 : #include "nsIDOMElement.h"
12 : #include "nsIInterfaceRequestor.h"
13 : #include "nsIInterfaceRequestorUtils.h"
14 : #include "nsCRT.h"
15 : #include "nsString.h"
16 : #include "mozilla/ArrayUtils.h"
17 : #include "mozilla/Preferences.h"
18 :
19 : #include "nsIControllerCommandTable.h"
20 : #include "nsICommandParams.h"
21 :
22 : #include "nsPIDOMWindow.h"
23 : #include "nsIPresShell.h"
24 : #include "nsIDocShell.h"
25 : #include "nsISelectionController.h"
26 : #include "nsIWebNavigation.h"
27 : #include "nsIContentViewerEdit.h"
28 : #include "nsIContentViewer.h"
29 : #include "nsFocusManager.h"
30 : #include "nsCopySupport.h"
31 : #include "nsIClipboard.h"
32 : #include "ContentEventHandler.h"
33 : #include "nsContentUtils.h"
34 : #include "nsIWordBreaker.h"
35 : #include "mozilla/Attributes.h"
36 : #include "mozilla/BasicEvents.h"
37 : #include "mozilla/TextEvents.h"
38 : #include "mozilla/dom/Selection.h"
39 : #include "mozilla/layers/KeyboardMap.h"
40 :
41 : #include "nsIClipboardDragDropHooks.h"
42 : #include "nsIClipboardDragDropHookList.h"
43 :
44 : using namespace mozilla;
45 : using namespace mozilla::layers;
46 :
47 : constexpr const char * sSelectAllString = "cmd_selectAll";
48 : constexpr const char * sSelectNoneString = "cmd_selectNone";
49 : constexpr const char * sCopyImageLocationString = "cmd_copyImageLocation";
50 : constexpr const char * sCopyImageContentsString = "cmd_copyImageContents";
51 : constexpr const char * sCopyImageString = "cmd_copyImage";
52 :
53 : constexpr const char * sScrollTopString = "cmd_scrollTop";
54 : constexpr const char * sScrollBottomString = "cmd_scrollBottom";
55 : constexpr const char * sScrollPageUpString = "cmd_scrollPageUp";
56 : constexpr const char * sScrollPageDownString = "cmd_scrollPageDown";
57 : constexpr const char * sScrollLineUpString = "cmd_scrollLineUp";
58 : constexpr const char * sScrollLineDownString = "cmd_scrollLineDown";
59 : constexpr const char * sScrollLeftString = "cmd_scrollLeft";
60 : constexpr const char * sScrollRightString = "cmd_scrollRight";
61 : constexpr const char * sMoveTopString = "cmd_moveTop";
62 : constexpr const char * sMoveBottomString = "cmd_moveBottom";
63 : constexpr const char * sMovePageUpString = "cmd_movePageUp";
64 : constexpr const char * sMovePageDownString = "cmd_movePageDown";
65 : constexpr const char * sLinePreviousString = "cmd_linePrevious";
66 : constexpr const char * sLineNextString = "cmd_lineNext";
67 : constexpr const char * sCharPreviousString = "cmd_charPrevious";
68 : constexpr const char * sCharNextString = "cmd_charNext";
69 :
70 : // These are so the browser can use editor navigation key bindings
71 : // helps with accessibility (boolean pref accessibility.browsewithcaret)
72 :
73 : constexpr const char * sSelectCharPreviousString = "cmd_selectCharPrevious";
74 : constexpr const char * sSelectCharNextString = "cmd_selectCharNext";
75 :
76 : constexpr const char * sWordPreviousString = "cmd_wordPrevious";
77 : constexpr const char * sWordNextString = "cmd_wordNext";
78 : constexpr const char * sSelectWordPreviousString = "cmd_selectWordPrevious";
79 : constexpr const char * sSelectWordNextString = "cmd_selectWordNext";
80 :
81 : constexpr const char * sBeginLineString = "cmd_beginLine";
82 : constexpr const char * sEndLineString = "cmd_endLine";
83 : constexpr const char * sSelectBeginLineString = "cmd_selectBeginLine";
84 : constexpr const char * sSelectEndLineString = "cmd_selectEndLine";
85 :
86 : constexpr const char * sSelectLinePreviousString = "cmd_selectLinePrevious";
87 : constexpr const char * sSelectLineNextString = "cmd_selectLineNext";
88 :
89 : constexpr const char * sSelectPageUpString = "cmd_selectPageUp";
90 : constexpr const char * sSelectPageDownString = "cmd_selectPageDown";
91 :
92 : constexpr const char * sSelectTopString = "cmd_selectTop";
93 : constexpr const char * sSelectBottomString = "cmd_selectBottom";
94 :
95 : // Physical-direction movement and selection commands
96 : constexpr const char * sMoveLeftString = "cmd_moveLeft";
97 : constexpr const char * sMoveRightString = "cmd_moveRight";
98 : constexpr const char * sMoveUpString = "cmd_moveUp";
99 : constexpr const char * sMoveDownString = "cmd_moveDown";
100 : constexpr const char * sMoveLeft2String = "cmd_moveLeft2";
101 : constexpr const char * sMoveRight2String = "cmd_moveRight2";
102 : constexpr const char * sMoveUp2String = "cmd_moveUp2";
103 : constexpr const char * sMoveDown2String = "cmd_moveDown2";
104 :
105 : constexpr const char * sSelectLeftString = "cmd_selectLeft";
106 : constexpr const char * sSelectRightString = "cmd_selectRight";
107 : constexpr const char * sSelectUpString = "cmd_selectUp";
108 : constexpr const char * sSelectDownString = "cmd_selectDown";
109 : constexpr const char * sSelectLeft2String = "cmd_selectLeft2";
110 : constexpr const char * sSelectRight2String = "cmd_selectRight2";
111 : constexpr const char * sSelectUp2String = "cmd_selectUp2";
112 : constexpr const char * sSelectDown2String = "cmd_selectDown2";
113 :
114 : #if 0
115 : #pragma mark -
116 : #endif
117 :
118 : // a base class for selection-related commands, for code sharing
119 8 : class nsSelectionCommandsBase : public nsIControllerCommand
120 : {
121 : public:
122 : NS_DECL_ISUPPORTS
123 : NS_IMETHOD IsCommandEnabled(const char* aCommandName, nsISupports* aCommandContext, bool* _retval) override;
124 : NS_IMETHOD GetCommandStateParams(const char* aCommandName, nsICommandParams* aParams, nsISupports* aCommandContext) override;
125 : NS_IMETHOD DoCommandParams(const char* aCommandName, nsICommandParams* aParams, nsISupports* aCommandContext) override;
126 :
127 : protected:
128 0 : virtual ~nsSelectionCommandsBase() {}
129 :
130 : static nsresult GetPresShellFromWindow(nsPIDOMWindowOuter *aWindow, nsIPresShell **aPresShell);
131 : static nsresult GetSelectionControllerFromWindow(nsPIDOMWindowOuter *aWindow, nsISelectionController **aSelCon);
132 :
133 : // no member variables, please, we're stateless!
134 : };
135 :
136 : // this class implements commands whose behavior depends on the 'browse with caret' setting
137 2 : class nsSelectMoveScrollCommand : public nsSelectionCommandsBase
138 : {
139 : public:
140 :
141 : NS_IMETHOD DoCommand(const char * aCommandName, nsISupports *aCommandContext);
142 :
143 : // no member variables, please, we're stateless!
144 : };
145 :
146 : // this class implements physical-movement versions of the above
147 2 : class nsPhysicalSelectMoveScrollCommand : public nsSelectionCommandsBase
148 : {
149 : public:
150 :
151 : NS_IMETHOD DoCommand(const char * aCommandName, nsISupports *aCommandContext);
152 :
153 : // no member variables, please, we're stateless!
154 : };
155 :
156 : // this class implements other selection commands
157 2 : class nsSelectCommand : public nsSelectionCommandsBase
158 : {
159 : public:
160 :
161 : NS_IMETHOD DoCommand(const char * aCommandName, nsISupports *aCommandContext);
162 :
163 : // no member variables, please, we're stateless!
164 : };
165 :
166 : // this class implements physical-movement versions of selection commands
167 2 : class nsPhysicalSelectCommand : public nsSelectionCommandsBase
168 : {
169 : public:
170 :
171 : NS_IMETHOD DoCommand(const char * aCommandName, nsISupports *aCommandContext);
172 :
173 : // no member variables, please, we're stateless!
174 : };
175 :
176 : #if 0
177 : #pragma mark -
178 : #endif
179 :
180 :
181 1152 : NS_IMPL_ISUPPORTS(nsSelectionCommandsBase, nsIControllerCommand)
182 :
183 : NS_IMETHODIMP
184 96 : nsSelectionCommandsBase::IsCommandEnabled(const char * aCommandName,
185 : nsISupports *aCommandContext,
186 : bool *outCmdEnabled)
187 : {
188 : // XXX this needs fixing. e.g. you can't scroll up if you're already at the top of
189 : // the document.
190 96 : *outCmdEnabled = true;
191 96 : return NS_OK;
192 : }
193 :
194 : NS_IMETHODIMP
195 0 : nsSelectionCommandsBase::GetCommandStateParams(const char *aCommandName,
196 : nsICommandParams *aParams, nsISupports *aCommandContext)
197 : {
198 : // XXX we should probably return the enabled state
199 0 : return NS_ERROR_NOT_IMPLEMENTED;
200 : }
201 :
202 : NS_IMETHODIMP
203 0 : nsSelectionCommandsBase::DoCommandParams(const char *aCommandName,
204 : nsICommandParams *aParams, nsISupports *aCommandContext)
205 : {
206 0 : return DoCommand(aCommandName, aCommandContext);
207 : }
208 :
209 : // protected methods
210 :
211 : nsresult
212 0 : nsSelectionCommandsBase::GetPresShellFromWindow(nsPIDOMWindowOuter *aWindow, nsIPresShell **aPresShell)
213 : {
214 0 : *aPresShell = nullptr;
215 0 : NS_ENSURE_TRUE(aWindow, NS_ERROR_FAILURE);
216 :
217 0 : nsIDocShell *docShell = aWindow->GetDocShell();
218 0 : NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
219 :
220 0 : NS_IF_ADDREF(*aPresShell = docShell->GetPresShell());
221 0 : return NS_OK;
222 : }
223 :
224 : nsresult
225 0 : nsSelectionCommandsBase::GetSelectionControllerFromWindow(nsPIDOMWindowOuter *aWindow, nsISelectionController **aSelCon)
226 : {
227 0 : *aSelCon = nullptr;
228 :
229 0 : nsCOMPtr<nsIPresShell> presShell;
230 0 : GetPresShellFromWindow(aWindow, getter_AddRefs(presShell));
231 0 : if (presShell)
232 0 : return CallQueryInterface(presShell, aSelCon);
233 :
234 0 : return NS_ERROR_FAILURE;
235 : }
236 :
237 : #if 0
238 : #pragma mark -
239 : #endif
240 :
241 : // Helpers for nsSelectMoveScrollCommand and nsPhysicalSelectMoveScrollCommand
242 : static void
243 0 : AdjustFocusAfterCaretMove(nsPIDOMWindowOuter* aWindow)
244 : {
245 : // adjust the focus to the new caret position
246 0 : nsIFocusManager* fm = nsFocusManager::GetFocusManager();
247 0 : if (fm) {
248 0 : nsCOMPtr<nsIDOMElement> result;
249 0 : fm->MoveFocus(aWindow, nullptr, nsIFocusManager::MOVEFOCUS_CARET,
250 0 : nsIFocusManager::FLAG_NOSCROLL, getter_AddRefs(result));
251 : }
252 0 : }
253 :
254 : static bool
255 0 : IsCaretOnInWindow(nsPIDOMWindowOuter* aWindow, nsISelectionController* aSelCont)
256 : {
257 : // We allow the caret to be moved with arrow keys on any window for which
258 : // the caret is enabled. In particular, this includes caret-browsing mode
259 : // in non-chrome documents.
260 0 : bool caretOn = false;
261 0 : aSelCont->GetCaretEnabled(&caretOn);
262 0 : if (!caretOn) {
263 0 : caretOn = Preferences::GetBool("accessibility.browsewithcaret");
264 0 : if (caretOn) {
265 0 : nsCOMPtr<nsIDocShell> docShell = aWindow->GetDocShell();
266 0 : if (docShell && docShell->ItemType() == nsIDocShellTreeItem::typeChrome) {
267 0 : caretOn = false;
268 : }
269 : }
270 : }
271 0 : return caretOn;
272 : }
273 :
274 : static constexpr struct BrowseCommand {
275 : const char *reverse, *forward;
276 : KeyboardScrollAction::KeyboardScrollActionType scrollAction;
277 : nsresult (NS_STDCALL nsISelectionController::*scroll)(bool);
278 : nsresult (NS_STDCALL nsISelectionController::*move)(bool, bool);
279 : } browseCommands[] = {
280 : { sScrollTopString, sScrollBottomString,
281 : KeyboardScrollAction::eScrollComplete,
282 : &nsISelectionController::CompleteScroll },
283 : { sScrollPageUpString, sScrollPageDownString,
284 : KeyboardScrollAction::eScrollPage,
285 : &nsISelectionController::ScrollPage },
286 : { sScrollLineUpString, sScrollLineDownString,
287 : KeyboardScrollAction::eScrollLine,
288 : &nsISelectionController::ScrollLine },
289 : { sScrollLeftString, sScrollRightString,
290 : KeyboardScrollAction::eScrollCharacter,
291 : &nsISelectionController::ScrollCharacter },
292 : { sMoveTopString, sMoveBottomString,
293 : KeyboardScrollAction::eScrollComplete,
294 : &nsISelectionController::CompleteScroll,
295 : &nsISelectionController::CompleteMove },
296 : { sMovePageUpString, sMovePageDownString,
297 : KeyboardScrollAction::eScrollPage,
298 : &nsISelectionController::ScrollPage,
299 : &nsISelectionController::PageMove },
300 : { sLinePreviousString, sLineNextString,
301 : KeyboardScrollAction::eScrollLine,
302 : &nsISelectionController::ScrollLine,
303 : &nsISelectionController::LineMove },
304 : { sWordPreviousString, sWordNextString,
305 : KeyboardScrollAction::eScrollCharacter,
306 : &nsISelectionController::ScrollCharacter,
307 : &nsISelectionController::WordMove },
308 : { sCharPreviousString, sCharNextString,
309 : KeyboardScrollAction::eScrollCharacter,
310 : &nsISelectionController::ScrollCharacter,
311 : &nsISelectionController::CharacterMove },
312 : { sBeginLineString, sEndLineString,
313 : KeyboardScrollAction::eScrollComplete,
314 : &nsISelectionController::CompleteScroll,
315 : &nsISelectionController::IntraLineMove }
316 : };
317 :
318 : nsresult
319 0 : nsSelectMoveScrollCommand::DoCommand(const char *aCommandName, nsISupports *aCommandContext)
320 : {
321 0 : nsCOMPtr<nsPIDOMWindowOuter> piWindow(do_QueryInterface(aCommandContext));
322 0 : nsCOMPtr<nsISelectionController> selCont;
323 0 : GetSelectionControllerFromWindow(piWindow, getter_AddRefs(selCont));
324 0 : NS_ENSURE_TRUE(selCont, NS_ERROR_NOT_INITIALIZED);
325 :
326 0 : bool caretOn = IsCaretOnInWindow(piWindow, selCont);
327 :
328 0 : for (size_t i = 0; i < ArrayLength(browseCommands); i++) {
329 0 : bool forward = !strcmp(aCommandName, browseCommands[i].forward);
330 0 : if (forward || !strcmp(aCommandName, browseCommands[i].reverse)) {
331 0 : if (caretOn && browseCommands[i].move &&
332 0 : NS_SUCCEEDED((selCont->*(browseCommands[i].move))(forward, false))) {
333 0 : AdjustFocusAfterCaretMove(piWindow);
334 0 : return NS_OK;
335 : }
336 0 : return (selCont->*(browseCommands[i].scroll))(forward);
337 : }
338 : }
339 :
340 0 : return NS_ERROR_NOT_IMPLEMENTED;
341 : }
342 :
343 : // XXX It's not clear to me yet how we should handle the "scroll" option
344 : // for these commands; for now, I'm mapping them back to ScrollCharacter,
345 : // ScrollLine, etc., as if for horizontal-mode content, but this may need
346 : // to be reconsidered once we have more experience with vertical content.
347 : static const struct PhysicalBrowseCommand {
348 : const char *command;
349 : int16_t direction, amount;
350 : KeyboardScrollAction::KeyboardScrollActionType scrollAction;
351 : nsresult (NS_STDCALL nsISelectionController::*scroll)(bool);
352 : } physicalBrowseCommands[] = {
353 : { sMoveLeftString, nsISelectionController::MOVE_LEFT, 0,
354 : KeyboardScrollAction::eScrollCharacter,
355 : &nsISelectionController::ScrollCharacter },
356 : { sMoveRightString, nsISelectionController::MOVE_RIGHT, 0,
357 : KeyboardScrollAction::eScrollCharacter,
358 : &nsISelectionController::ScrollCharacter },
359 : { sMoveUpString, nsISelectionController::MOVE_UP, 0,
360 : KeyboardScrollAction::eScrollLine,
361 : &nsISelectionController::ScrollLine },
362 : { sMoveDownString, nsISelectionController::MOVE_DOWN, 0,
363 : KeyboardScrollAction::eScrollLine,
364 : &nsISelectionController::ScrollLine },
365 : { sMoveLeft2String, nsISelectionController::MOVE_LEFT, 1,
366 : KeyboardScrollAction::eScrollCharacter,
367 : &nsISelectionController::ScrollCharacter },
368 : { sMoveRight2String, nsISelectionController::MOVE_RIGHT, 1,
369 : KeyboardScrollAction::eScrollCharacter,
370 : &nsISelectionController::ScrollCharacter },
371 : { sMoveUp2String, nsISelectionController::MOVE_UP, 1,
372 : KeyboardScrollAction::eScrollComplete,
373 : &nsISelectionController::CompleteScroll },
374 : { sMoveDown2String, nsISelectionController::MOVE_DOWN, 1,
375 : KeyboardScrollAction::eScrollComplete,
376 : &nsISelectionController::CompleteScroll },
377 : };
378 :
379 : nsresult
380 0 : nsPhysicalSelectMoveScrollCommand::DoCommand(const char *aCommandName,
381 : nsISupports *aCommandContext)
382 : {
383 0 : nsCOMPtr<nsPIDOMWindowOuter> piWindow(do_QueryInterface(aCommandContext));
384 0 : nsCOMPtr<nsISelectionController> selCont;
385 0 : GetSelectionControllerFromWindow(piWindow, getter_AddRefs(selCont));
386 0 : NS_ENSURE_TRUE(selCont, NS_ERROR_NOT_INITIALIZED);
387 :
388 0 : bool caretOn = IsCaretOnInWindow(piWindow, selCont);
389 :
390 0 : for (size_t i = 0; i < ArrayLength(physicalBrowseCommands); i++) {
391 0 : const PhysicalBrowseCommand& cmd = physicalBrowseCommands[i];
392 0 : if (!strcmp(aCommandName, cmd.command)) {
393 0 : int16_t dir = cmd.direction;
394 0 : if (caretOn &&
395 0 : NS_SUCCEEDED(selCont->PhysicalMove(dir, cmd.amount, false))) {
396 0 : AdjustFocusAfterCaretMove(piWindow);
397 0 : return NS_OK;
398 : }
399 :
400 0 : bool forward = (dir == nsISelectionController::MOVE_RIGHT ||
401 0 : dir == nsISelectionController::MOVE_DOWN);
402 0 : return (selCont->*(cmd.scroll))(forward);
403 : }
404 : }
405 :
406 0 : return NS_ERROR_NOT_IMPLEMENTED;
407 : }
408 :
409 : #if 0
410 : #pragma mark -
411 : #endif
412 :
413 : static const struct SelectCommand {
414 : const char *reverse, *forward;
415 : nsresult (NS_STDCALL nsISelectionController::*select)(bool, bool);
416 : } selectCommands[] = {
417 : { sSelectCharPreviousString, sSelectCharNextString,
418 : &nsISelectionController::CharacterMove },
419 : { sSelectWordPreviousString, sSelectWordNextString,
420 : &nsISelectionController::WordMove },
421 : { sSelectBeginLineString, sSelectEndLineString,
422 : &nsISelectionController::IntraLineMove },
423 : { sSelectLinePreviousString, sSelectLineNextString,
424 : &nsISelectionController::LineMove },
425 : { sSelectPageUpString, sSelectPageDownString,
426 : &nsISelectionController::PageMove },
427 : { sSelectTopString, sSelectBottomString,
428 : &nsISelectionController::CompleteMove }
429 : };
430 :
431 : nsresult
432 0 : nsSelectCommand::DoCommand(const char *aCommandName,
433 : nsISupports *aCommandContext)
434 : {
435 0 : nsCOMPtr<nsPIDOMWindowOuter> piWindow(do_QueryInterface(aCommandContext));
436 0 : nsCOMPtr<nsISelectionController> selCont;
437 0 : GetSelectionControllerFromWindow(piWindow, getter_AddRefs(selCont));
438 0 : NS_ENSURE_TRUE(selCont, NS_ERROR_NOT_INITIALIZED);
439 :
440 : // These commands are so the browser can use caret navigation key bindings -
441 : // Helps with accessibility - aaronl@netscape.com
442 0 : for (size_t i = 0; i < ArrayLength(selectCommands); i++) {
443 0 : bool forward = !strcmp(aCommandName, selectCommands[i].forward);
444 0 : if (forward || !strcmp(aCommandName, selectCommands[i].reverse)) {
445 0 : return (selCont->*(selectCommands[i].select))(forward, true);
446 : }
447 : }
448 0 : return NS_ERROR_NOT_IMPLEMENTED;
449 : }
450 :
451 : #if 0
452 : #pragma mark -
453 : #endif
454 :
455 : static const struct PhysicalSelectCommand {
456 : const char *command;
457 : int16_t direction, amount;
458 : } physicalSelectCommands[] = {
459 : { sSelectLeftString, nsISelectionController::MOVE_LEFT, 0 },
460 : { sSelectRightString, nsISelectionController::MOVE_RIGHT, 0 },
461 : { sSelectUpString, nsISelectionController::MOVE_UP, 0 },
462 : { sSelectDownString, nsISelectionController::MOVE_DOWN, 0 },
463 : { sSelectLeft2String, nsISelectionController::MOVE_LEFT, 1 },
464 : { sSelectRight2String, nsISelectionController::MOVE_RIGHT, 1 },
465 : { sSelectUp2String, nsISelectionController::MOVE_UP, 1 },
466 : { sSelectDown2String, nsISelectionController::MOVE_DOWN, 1 }
467 : };
468 :
469 : nsresult
470 0 : nsPhysicalSelectCommand::DoCommand(const char *aCommandName,
471 : nsISupports *aCommandContext)
472 : {
473 0 : nsCOMPtr<nsPIDOMWindowOuter> piWindow(do_QueryInterface(aCommandContext));
474 0 : nsCOMPtr<nsISelectionController> selCont;
475 0 : GetSelectionControllerFromWindow(piWindow, getter_AddRefs(selCont));
476 0 : NS_ENSURE_TRUE(selCont, NS_ERROR_NOT_INITIALIZED);
477 :
478 0 : for (size_t i = 0; i < ArrayLength(physicalSelectCommands); i++) {
479 0 : if (!strcmp(aCommandName, physicalSelectCommands[i].command)) {
480 0 : return selCont->PhysicalMove(physicalSelectCommands[i].direction,
481 0 : physicalSelectCommands[i].amount,
482 0 : true);
483 : }
484 : }
485 :
486 0 : return NS_ERROR_NOT_IMPLEMENTED;
487 : }
488 :
489 : #if 0
490 : #pragma mark -
491 : #endif
492 :
493 8 : class nsClipboardCommand final : public nsIControllerCommand
494 : {
495 0 : ~nsClipboardCommand() {}
496 :
497 : public:
498 :
499 : NS_DECL_ISUPPORTS
500 : NS_DECL_NSICONTROLLERCOMMAND
501 : };
502 :
503 144 : NS_IMPL_ISUPPORTS(nsClipboardCommand, nsIControllerCommand)
504 :
505 : nsresult
506 11 : nsClipboardCommand::IsCommandEnabled(const char* aCommandName, nsISupports *aContext, bool *outCmdEnabled)
507 : {
508 11 : NS_ENSURE_ARG_POINTER(outCmdEnabled);
509 11 : *outCmdEnabled = false;
510 :
511 19 : if (strcmp(aCommandName, "cmd_copy") &&
512 14 : strcmp(aCommandName, "cmd_copyAndCollapseToEnd") &&
513 9 : strcmp(aCommandName, "cmd_cut") &&
514 3 : strcmp(aCommandName, "cmd_paste"))
515 0 : return NS_OK;
516 :
517 22 : nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryInterface(aContext);
518 11 : NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
519 :
520 22 : nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
521 11 : if (doc->IsHTMLOrXHTML()) {
522 : // In HTML and XHTML documents, we always want the cut, copy and paste
523 : // commands to be enabled.
524 8 : *outCmdEnabled = true;
525 : } else {
526 : // Cut isn't enabled in xul documents which use nsClipboardCommand
527 5 : if (strcmp(aCommandName, "cmd_copy") == 0 ||
528 2 : strcmp(aCommandName, "cmd_copyAndCollapseToEnd") == 0) {
529 1 : *outCmdEnabled = nsCopySupport::CanCopy(doc);
530 : }
531 : }
532 11 : return NS_OK;
533 : }
534 :
535 : nsresult
536 0 : nsClipboardCommand::DoCommand(const char *aCommandName, nsISupports *aContext)
537 : {
538 0 : if (strcmp(aCommandName, "cmd_cut") &&
539 0 : strcmp(aCommandName, "cmd_copy") &&
540 0 : strcmp(aCommandName, "cmd_copyAndCollapseToEnd") &&
541 0 : strcmp(aCommandName, "cmd_paste"))
542 0 : return NS_OK;
543 :
544 0 : nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryInterface(aContext);
545 0 : NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
546 :
547 0 : nsIDocShell *docShell = window->GetDocShell();
548 0 : NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
549 :
550 0 : nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
551 0 : NS_ENSURE_TRUE(presShell, NS_ERROR_FAILURE);
552 :
553 0 : EventMessage eventMessage = eCopy;
554 0 : if (strcmp(aCommandName, "cmd_cut") == 0) {
555 0 : eventMessage = eCut;
556 0 : } else if (strcmp(aCommandName, "cmd_paste") == 0) {
557 0 : eventMessage = ePaste;
558 : }
559 :
560 0 : bool actionTaken = false;
561 : bool notCancelled =
562 0 : nsCopySupport::FireClipboardEvent(eventMessage,
563 : nsIClipboard::kGlobalClipboard,
564 0 : presShell, nullptr, &actionTaken);
565 :
566 0 : if (notCancelled && !strcmp(aCommandName, "cmd_copyAndCollapseToEnd")) {
567 : dom::Selection *sel =
568 0 : presShell->GetCurrentSelection(SelectionType::eNormal);
569 0 : NS_ENSURE_TRUE(sel, NS_ERROR_FAILURE);
570 0 : sel->CollapseToEnd();
571 : }
572 :
573 0 : if (actionTaken) {
574 0 : return NS_OK;
575 : }
576 0 : return NS_ERROR_FAILURE;
577 : }
578 :
579 : NS_IMETHODIMP
580 0 : nsClipboardCommand::GetCommandStateParams(const char *aCommandName,
581 : nsICommandParams *aParams, nsISupports *aCommandContext)
582 : {
583 0 : return NS_ERROR_NOT_IMPLEMENTED;
584 : }
585 :
586 : nsresult
587 0 : nsClipboardCommand::DoCommandParams(const char *aCommandName, nsICommandParams* aParams, nsISupports *aContext)
588 : {
589 0 : return DoCommand(aCommandName, aContext);
590 : }
591 :
592 : #if 0
593 : #pragma mark -
594 : #endif
595 :
596 8 : class nsSelectionCommand : public nsIControllerCommand
597 : {
598 : public:
599 : NS_DECL_ISUPPORTS
600 : NS_DECL_NSICONTROLLERCOMMAND
601 :
602 : protected:
603 0 : virtual ~nsSelectionCommand() {}
604 :
605 : virtual nsresult IsClipboardCommandEnabled(const char * aCommandName, nsIContentViewerEdit* aEdit, bool *outCmdEnabled) = 0;
606 : virtual nsresult DoClipboardCommand(const char *aCommandName, nsIContentViewerEdit* aEdit, nsICommandParams* aParams) = 0;
607 :
608 : static nsresult GetContentViewerEditFromContext(nsISupports *aContext, nsIContentViewerEdit **aEditInterface);
609 :
610 : // no member variables, please, we're stateless!
611 : };
612 :
613 :
614 184 : NS_IMPL_ISUPPORTS(nsSelectionCommand, nsIControllerCommand)
615 :
616 :
617 : /*---------------------------------------------------------------------------
618 :
619 : nsSelectionCommand
620 :
621 : ----------------------------------------------------------------------------*/
622 :
623 : NS_IMETHODIMP
624 15 : nsSelectionCommand::IsCommandEnabled(const char * aCommandName,
625 : nsISupports *aCommandContext,
626 : bool *outCmdEnabled)
627 : {
628 15 : NS_ENSURE_ARG_POINTER(outCmdEnabled);
629 15 : *outCmdEnabled = false;
630 :
631 30 : nsCOMPtr<nsIContentViewerEdit> contentEdit;
632 15 : GetContentViewerEditFromContext(aCommandContext, getter_AddRefs(contentEdit));
633 15 : NS_ENSURE_TRUE(contentEdit, NS_ERROR_NOT_INITIALIZED);
634 :
635 15 : return IsClipboardCommandEnabled(aCommandName, contentEdit, outCmdEnabled);
636 : }
637 :
638 : NS_IMETHODIMP
639 0 : nsSelectionCommand::DoCommand(const char *aCommandName,
640 : nsISupports *aCommandContext)
641 : {
642 0 : nsCOMPtr<nsIContentViewerEdit> contentEdit;
643 0 : GetContentViewerEditFromContext(aCommandContext, getter_AddRefs(contentEdit));
644 0 : NS_ENSURE_TRUE(contentEdit, NS_ERROR_NOT_INITIALIZED);
645 :
646 0 : return DoClipboardCommand(aCommandName, contentEdit, nullptr);
647 : }
648 :
649 : NS_IMETHODIMP
650 0 : nsSelectionCommand::GetCommandStateParams(const char *aCommandName,
651 : nsICommandParams *aParams,
652 : nsISupports *aCommandContext)
653 : {
654 0 : return NS_ERROR_NOT_IMPLEMENTED;
655 : }
656 :
657 : NS_IMETHODIMP
658 0 : nsSelectionCommand::DoCommandParams(const char *aCommandName,
659 : nsICommandParams *aParams,
660 : nsISupports *aCommandContext)
661 : {
662 0 : nsCOMPtr<nsIContentViewerEdit> contentEdit;
663 0 : GetContentViewerEditFromContext(aCommandContext, getter_AddRefs(contentEdit));
664 0 : NS_ENSURE_TRUE(contentEdit, NS_ERROR_NOT_INITIALIZED);
665 :
666 0 : return DoClipboardCommand(aCommandName, contentEdit, aParams);
667 : }
668 :
669 : nsresult
670 15 : nsSelectionCommand::GetContentViewerEditFromContext(nsISupports *aContext,
671 : nsIContentViewerEdit **aEditInterface)
672 : {
673 15 : NS_ENSURE_ARG(aEditInterface);
674 15 : *aEditInterface = nullptr;
675 :
676 30 : nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryInterface(aContext);
677 15 : NS_ENSURE_TRUE(window, NS_ERROR_INVALID_ARG);
678 :
679 15 : nsIDocShell *docShell = window->GetDocShell();
680 15 : NS_ENSURE_TRUE(docShell, NS_ERROR_FAILURE);
681 :
682 30 : nsCOMPtr<nsIContentViewer> viewer;
683 15 : docShell->GetContentViewer(getter_AddRefs(viewer));
684 30 : nsCOMPtr<nsIContentViewerEdit> edit(do_QueryInterface(viewer));
685 15 : NS_ENSURE_TRUE(edit, NS_ERROR_FAILURE);
686 :
687 15 : edit.forget(aEditInterface);
688 15 : return NS_OK;
689 : }
690 :
691 : #if 0
692 : #pragma mark -
693 : #endif
694 :
695 : #define NS_DECL_CLIPBOARD_COMMAND(_cmd) \
696 : class _cmd : public nsSelectionCommand \
697 : { \
698 : protected: \
699 : \
700 : virtual nsresult IsClipboardCommandEnabled(const char* aCommandName, \
701 : nsIContentViewerEdit* aEdit, bool *outCmdEnabled); \
702 : virtual nsresult DoClipboardCommand(const char* aCommandName, \
703 : nsIContentViewerEdit* aEdit, nsICommandParams* aParams); \
704 : /* no member variables, please, we're stateless! */ \
705 : };
706 :
707 2 : NS_DECL_CLIPBOARD_COMMAND(nsClipboardCopyLinkCommand)
708 2 : NS_DECL_CLIPBOARD_COMMAND(nsClipboardImageCommands)
709 2 : NS_DECL_CLIPBOARD_COMMAND(nsClipboardSelectAllNoneCommands)
710 2 : NS_DECL_CLIPBOARD_COMMAND(nsClipboardGetContentsCommand)
711 :
712 : nsresult
713 2 : nsClipboardCopyLinkCommand::IsClipboardCommandEnabled(const char* aCommandName, nsIContentViewerEdit* aEdit, bool *outCmdEnabled)
714 : {
715 2 : return aEdit->GetInLink(outCmdEnabled);
716 : }
717 :
718 : nsresult
719 0 : nsClipboardCopyLinkCommand::DoClipboardCommand(const char *aCommandName, nsIContentViewerEdit* aEdit, nsICommandParams* aParams)
720 : {
721 0 : return aEdit->CopyLinkLocation();
722 : }
723 :
724 : #if 0
725 : #pragma mark -
726 : #endif
727 :
728 : nsresult
729 6 : nsClipboardImageCommands::IsClipboardCommandEnabled(const char* aCommandName, nsIContentViewerEdit* aEdit, bool *outCmdEnabled)
730 : {
731 6 : return aEdit->GetInImage(outCmdEnabled);
732 : }
733 :
734 : nsresult
735 0 : nsClipboardImageCommands::DoClipboardCommand(const char *aCommandName, nsIContentViewerEdit* aEdit, nsICommandParams* aParams)
736 : {
737 0 : if (!nsCRT::strcmp(sCopyImageLocationString, aCommandName))
738 0 : return aEdit->CopyImage(nsIContentViewerEdit::COPY_IMAGE_TEXT);
739 0 : if (!nsCRT::strcmp(sCopyImageContentsString, aCommandName))
740 0 : return aEdit->CopyImage(nsIContentViewerEdit::COPY_IMAGE_DATA);
741 : int32_t copyFlags = nsIContentViewerEdit::COPY_IMAGE_DATA |
742 0 : nsIContentViewerEdit::COPY_IMAGE_HTML;
743 0 : if (aParams)
744 0 : aParams->GetLongValue("imageCopy", ©Flags);
745 0 : return aEdit->CopyImage(copyFlags);
746 : }
747 :
748 : #if 0
749 : #pragma mark -
750 : #endif
751 :
752 : nsresult
753 5 : nsClipboardSelectAllNoneCommands::IsClipboardCommandEnabled(const char* aCommandName, nsIContentViewerEdit* aEdit, bool *outCmdEnabled)
754 : {
755 5 : *outCmdEnabled = true;
756 5 : return NS_OK;
757 : }
758 :
759 : nsresult
760 0 : nsClipboardSelectAllNoneCommands::DoClipboardCommand(const char *aCommandName, nsIContentViewerEdit* aEdit, nsICommandParams* aParams)
761 : {
762 0 : if (!nsCRT::strcmp(sSelectAllString, aCommandName))
763 0 : return aEdit->SelectAll();
764 :
765 0 : return aEdit->ClearSelection();
766 : }
767 :
768 :
769 : #if 0
770 : #pragma mark -
771 : #endif
772 :
773 : nsresult
774 2 : nsClipboardGetContentsCommand::IsClipboardCommandEnabled(const char* aCommandName, nsIContentViewerEdit* aEdit, bool *outCmdEnabled)
775 : {
776 2 : return aEdit->GetCanGetContents(outCmdEnabled);
777 : }
778 :
779 : nsresult
780 0 : nsClipboardGetContentsCommand::DoClipboardCommand(const char *aCommandName, nsIContentViewerEdit* aEdit, nsICommandParams* aParams)
781 : {
782 0 : NS_ENSURE_ARG(aParams);
783 :
784 0 : nsAutoCString mimeType("text/plain");
785 :
786 0 : nsXPIDLCString format; // nsICommandParams needs to use nsACString
787 0 : if (NS_SUCCEEDED(aParams->GetCStringValue("format", getter_Copies(format))))
788 0 : mimeType.Assign(format);
789 :
790 0 : bool selectionOnly = false;
791 0 : aParams->GetBooleanValue("selection_only", &selectionOnly);
792 :
793 0 : nsAutoString contents;
794 0 : nsresult rv = aEdit->GetContents(mimeType.get(), selectionOnly, contents);
795 0 : if (NS_FAILED(rv))
796 0 : return rv;
797 :
798 0 : return aParams->SetStringValue("result", contents);
799 : }
800 :
801 : #if 0 // Remove unless needed again, bug 204777
802 : class nsWebNavigationBaseCommand : public nsIControllerCommand
803 : {
804 : public:
805 : virtual ~nsWebNavigationBaseCommand() {}
806 :
807 : NS_DECL_ISUPPORTS
808 : NS_DECL_NSICONTROLLERCOMMAND
809 :
810 : protected:
811 :
812 : virtual nsresult IsWebNavCommandEnabled(const char * aCommandName, nsIWebNavigation* aWebNavigation, bool *outCmdEnabled) = 0;
813 : virtual nsresult DoWebNavCommand(const char *aCommandName, nsIWebNavigation* aWebNavigation) = 0;
814 :
815 : static nsresult GetWebNavigationFromContext(nsISupports *aContext, nsIWebNavigation **aWebNavigation);
816 :
817 : // no member variables, please, we're stateless!
818 : };
819 :
820 : class nsGoForwardCommand : public nsWebNavigationBaseCommand
821 : {
822 : protected:
823 :
824 : virtual nsresult IsWebNavCommandEnabled(const char * aCommandName, nsIWebNavigation* aWebNavigation, bool *outCmdEnabled);
825 : virtual nsresult DoWebNavCommand(const char *aCommandName, nsIWebNavigation* aWebNavigation);
826 : // no member variables, please, we're stateless!
827 : };
828 :
829 : class nsGoBackCommand : public nsWebNavigationBaseCommand
830 : {
831 : protected:
832 :
833 : virtual nsresult IsWebNavCommandEnabled(const char * aCommandName, nsIWebNavigation* aWebNavigation, bool *outCmdEnabled);
834 : virtual nsresult DoWebNavCommand(const char *aCommandName, nsIWebNavigation* aWebNavigation);
835 : // no member variables, please, we're stateless!
836 : };
837 :
838 : /*---------------------------------------------------------------------------
839 :
840 : nsWebNavigationCommands
841 : no params
842 : ----------------------------------------------------------------------------*/
843 :
844 : NS_IMPL_ISUPPORTS(nsWebNavigationBaseCommand, nsIControllerCommand)
845 :
846 : NS_IMETHODIMP
847 : nsWebNavigationBaseCommand::IsCommandEnabled(const char * aCommandName,
848 : nsISupports *aCommandContext,
849 : bool *outCmdEnabled)
850 : {
851 : NS_ENSURE_ARG_POINTER(outCmdEnabled);
852 : *outCmdEnabled = false;
853 :
854 : nsCOMPtr<nsIWebNavigation> webNav;
855 : GetWebNavigationFromContext(aCommandContext, getter_AddRefs(webNav));
856 : NS_ENSURE_TRUE(webNav, NS_ERROR_INVALID_ARG);
857 :
858 : return IsCommandEnabled(aCommandName, webNav, outCmdEnabled);
859 : }
860 :
861 : NS_IMETHODIMP
862 : nsWebNavigationBaseCommand::GetCommandStateParams(const char *aCommandName,
863 : nsICommandParams *aParams, nsISupports *aCommandContext)
864 : {
865 : // XXX we should probably return the enabled state
866 : return NS_ERROR_NOT_IMPLEMENTED;
867 : }
868 :
869 : NS_IMETHODIMP
870 : nsWebNavigationBaseCommand::DoCommand(const char *aCommandName,
871 : nsISupports *aCommandContext)
872 : {
873 : nsCOMPtr<nsIWebNavigation> webNav;
874 : GetWebNavigationFromContext(aCommandContext, getter_AddRefs(webNav));
875 : NS_ENSURE_TRUE(webNav, NS_ERROR_INVALID_ARG);
876 :
877 : return DoWebNavCommand(aCommandName, webNav);
878 : }
879 :
880 : NS_IMETHODIMP
881 : nsWebNavigationBaseCommand::DoCommandParams(const char *aCommandName,
882 : nsICommandParams *aParams, nsISupports *aCommandContext)
883 : {
884 : return DoCommand(aCommandName, aCommandContext);
885 : }
886 :
887 : nsresult
888 : nsWebNavigationBaseCommand::GetWebNavigationFromContext(nsISupports *aContext, nsIWebNavigation **aWebNavigation)
889 : {
890 : nsCOMPtr<nsIInterfaceRequestor> windowReq = do_QueryInterface(aContext);
891 : CallGetInterface(windowReq.get(), aWebNavigation);
892 : return (*aWebNavigation) ? NS_OK : NS_ERROR_FAILURE;
893 : }
894 :
895 : nsresult
896 : nsGoForwardCommand::IsWebNavCommandEnabled(const char * aCommandName, nsIWebNavigation* aWebNavigation, bool *outCmdEnabled)
897 : {
898 : return aWebNavigation->GetCanGoForward(outCmdEnabled);
899 : }
900 :
901 : nsresult
902 : nsGoForwardCommand::DoWebNavCommand(const char *aCommandName, nsIWebNavigation* aWebNavigation)
903 : {
904 : return aWebNavigation->GoForward();
905 : }
906 :
907 : nsresult
908 : nsGoBackCommand::IsWebNavCommandEnabled(const char * aCommandName, nsIWebNavigation* aWebNavigation, bool *outCmdEnabled)
909 : {
910 : return aWebNavigation->GetCanGoBack(outCmdEnabled);
911 : }
912 :
913 : nsresult
914 : nsGoBackCommand::DoWebNavCommand(const char *aCommandName, nsIWebNavigation* aWebNavigation)
915 : {
916 : return aWebNavigation->GoBack();
917 : }
918 : #endif
919 :
920 : /*---------------------------------------------------------------------------
921 :
922 : nsClipboardDragDropHookCommand
923 : params value type possible values
924 : "addhook" isupports nsIClipboardDragDropHooks as nsISupports
925 : "removehook" isupports nsIClipboardDragDropHooks as nsISupports
926 :
927 : ----------------------------------------------------------------------------*/
928 :
929 2 : class nsClipboardDragDropHookCommand final : public nsIControllerCommand
930 : {
931 0 : ~nsClipboardDragDropHookCommand() {}
932 :
933 : public:
934 :
935 : NS_DECL_ISUPPORTS
936 : NS_DECL_NSICONTROLLERCOMMAND
937 :
938 : protected:
939 : // no member variables, please, we're stateless!
940 : };
941 :
942 :
943 24 : NS_IMPL_ISUPPORTS(nsClipboardDragDropHookCommand, nsIControllerCommand)
944 :
945 : NS_IMETHODIMP
946 2 : nsClipboardDragDropHookCommand::IsCommandEnabled(const char * aCommandName,
947 : nsISupports *aCommandContext,
948 : bool *outCmdEnabled)
949 : {
950 2 : *outCmdEnabled = true;
951 2 : return NS_OK;
952 : }
953 :
954 : NS_IMETHODIMP
955 0 : nsClipboardDragDropHookCommand::DoCommand(const char *aCommandName,
956 : nsISupports *aCommandContext)
957 : {
958 0 : return NS_ERROR_FAILURE;
959 : }
960 :
961 : NS_IMETHODIMP
962 0 : nsClipboardDragDropHookCommand::DoCommandParams(const char *aCommandName,
963 : nsICommandParams *aParams,
964 : nsISupports *aCommandContext)
965 : {
966 0 : NS_ENSURE_ARG(aParams);
967 :
968 0 : nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryInterface(aCommandContext);
969 0 : NS_ENSURE_TRUE(window, NS_ERROR_FAILURE);
970 :
971 0 : nsIDocShell *docShell = window->GetDocShell();
972 :
973 0 : nsCOMPtr<nsIClipboardDragDropHookList> obj = do_GetInterface(docShell);
974 0 : if (!obj) return NS_ERROR_INVALID_ARG;
975 :
976 0 : nsCOMPtr<nsISupports> isuppHook;
977 :
978 0 : nsresult returnValue = NS_OK;
979 0 : nsresult rv = aParams->GetISupportsValue("addhook", getter_AddRefs(isuppHook));
980 0 : if (NS_SUCCEEDED(rv))
981 : {
982 0 : nsCOMPtr<nsIClipboardDragDropHooks> hook = do_QueryInterface(isuppHook);
983 0 : if (hook)
984 0 : returnValue = obj->AddClipboardDragDropHooks(hook);
985 : else
986 0 : returnValue = NS_ERROR_INVALID_ARG;
987 : }
988 :
989 0 : rv = aParams->GetISupportsValue("removehook", getter_AddRefs(isuppHook));
990 0 : if (NS_SUCCEEDED(rv))
991 : {
992 0 : nsCOMPtr<nsIClipboardDragDropHooks> hook = do_QueryInterface(isuppHook);
993 0 : if (hook)
994 : {
995 0 : rv = obj->RemoveClipboardDragDropHooks(hook);
996 0 : if (NS_FAILED(rv) && NS_SUCCEEDED(returnValue))
997 0 : returnValue = rv;
998 : }
999 : else
1000 0 : returnValue = NS_ERROR_INVALID_ARG;
1001 : }
1002 :
1003 0 : return returnValue;
1004 : }
1005 :
1006 : NS_IMETHODIMP
1007 0 : nsClipboardDragDropHookCommand::GetCommandStateParams(const char *aCommandName,
1008 : nsICommandParams *aParams,
1009 : nsISupports *aCommandContext)
1010 : {
1011 0 : NS_ENSURE_ARG_POINTER(aParams);
1012 0 : return aParams->SetBooleanValue("state_enabled", true);
1013 : }
1014 :
1015 2 : class nsLookUpDictionaryCommand final : public nsIControllerCommand
1016 : {
1017 : public:
1018 : NS_DECL_ISUPPORTS
1019 : NS_DECL_NSICONTROLLERCOMMAND
1020 :
1021 : private:
1022 0 : virtual ~nsLookUpDictionaryCommand()
1023 0 : {
1024 0 : }
1025 : };
1026 :
1027 24 : NS_IMPL_ISUPPORTS(nsLookUpDictionaryCommand, nsIControllerCommand)
1028 :
1029 : NS_IMETHODIMP
1030 2 : nsLookUpDictionaryCommand::IsCommandEnabled(
1031 : const char* aCommandName,
1032 : nsISupports* aCommandContext,
1033 : bool* aRetval)
1034 : {
1035 2 : *aRetval = true;
1036 2 : return NS_OK;
1037 : }
1038 :
1039 : NS_IMETHODIMP
1040 0 : nsLookUpDictionaryCommand::GetCommandStateParams(const char* aCommandName,
1041 : nsICommandParams* aParams,
1042 : nsISupports* aCommandContext)
1043 : {
1044 0 : return NS_ERROR_NOT_IMPLEMENTED;
1045 : }
1046 :
1047 : NS_IMETHODIMP
1048 0 : nsLookUpDictionaryCommand::DoCommand(const char* aCommandName,
1049 : nsISupports *aCommandContext)
1050 : {
1051 0 : return NS_ERROR_NOT_IMPLEMENTED;
1052 : }
1053 :
1054 : NS_IMETHODIMP
1055 0 : nsLookUpDictionaryCommand::DoCommandParams(const char* aCommandName,
1056 : nsICommandParams* aParams,
1057 : nsISupports* aCommandContext)
1058 : {
1059 0 : if (NS_WARN_IF(!nsContentUtils::IsSafeToRunScript())) {
1060 0 : return NS_ERROR_NOT_AVAILABLE;
1061 : }
1062 :
1063 : int32_t x;
1064 : int32_t y;
1065 :
1066 0 : nsresult rv = aParams->GetLongValue("x", &x);
1067 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
1068 0 : return rv;
1069 : }
1070 :
1071 0 : rv = aParams->GetLongValue("y", &y);
1072 0 : if (NS_WARN_IF(NS_FAILED(rv))) {
1073 0 : return rv;
1074 : }
1075 :
1076 0 : LayoutDeviceIntPoint point(x, y);
1077 :
1078 0 : nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryInterface(aCommandContext);
1079 0 : if (NS_WARN_IF(!window)) {
1080 0 : return NS_ERROR_FAILURE;
1081 : }
1082 :
1083 0 : nsIDocShell* docShell = window->GetDocShell();
1084 0 : if (NS_WARN_IF(!docShell)) {
1085 0 : return NS_ERROR_FAILURE;
1086 : }
1087 :
1088 0 : nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
1089 0 : if (NS_WARN_IF(!presShell)) {
1090 0 : return NS_ERROR_FAILURE;
1091 : }
1092 :
1093 0 : nsPresContext* presContext = presShell->GetPresContext();
1094 0 : if (NS_WARN_IF(!presContext)) {
1095 0 : return NS_ERROR_FAILURE;
1096 : }
1097 :
1098 0 : nsCOMPtr<nsIWidget> widget = presContext->GetRootWidget();
1099 0 : if (NS_WARN_IF(!widget)) {
1100 0 : return NS_ERROR_FAILURE;
1101 : }
1102 :
1103 0 : WidgetQueryContentEvent charAt(true, eQueryCharacterAtPoint, widget);
1104 0 : charAt.mRefPoint.x = x;
1105 0 : charAt.mRefPoint.y = y;
1106 0 : ContentEventHandler handler(presContext);
1107 0 : handler.OnQueryCharacterAtPoint(&charAt);
1108 :
1109 0 : if (NS_WARN_IF(!charAt.mSucceeded) ||
1110 0 : charAt.mReply.mOffset == WidgetQueryContentEvent::NOT_FOUND) {
1111 0 : return NS_ERROR_FAILURE;
1112 : }
1113 :
1114 0 : WidgetQueryContentEvent textContent(true, eQueryTextContent, widget);
1115 : // OSX 10.7 queries 50 characters before/after current point. So we fetch
1116 : // same length.
1117 0 : uint32_t offset = charAt.mReply.mOffset;
1118 0 : if (offset > 50) {
1119 0 : offset -= 50;
1120 : } else {
1121 0 : offset = 0;
1122 : }
1123 0 : textContent.InitForQueryTextContent(offset, 100);
1124 0 : handler.OnQueryTextContent(&textContent);
1125 0 : if (NS_WARN_IF(!textContent.mSucceeded ||
1126 : textContent.mReply.mString.IsEmpty())) {
1127 0 : return NS_ERROR_FAILURE;
1128 : }
1129 :
1130 : // XXX nsIWordBreaker doesn't use contextual breaker.
1131 : // If OS provides it, widget should use it if contextual breaker is needed.
1132 0 : nsCOMPtr<nsIWordBreaker> wordBreaker = nsContentUtils::WordBreaker();
1133 0 : if (NS_WARN_IF(!wordBreaker)) {
1134 0 : return NS_ERROR_FAILURE;
1135 : }
1136 :
1137 : nsWordRange range =
1138 0 : wordBreaker->FindWord(textContent.mReply.mString.get(),
1139 : textContent.mReply.mString.Length(),
1140 0 : charAt.mReply.mOffset - offset);
1141 0 : if (range.mEnd == range.mBegin) {
1142 0 : return NS_ERROR_FAILURE;
1143 : }
1144 0 : range.mBegin += offset;
1145 0 : range.mEnd += offset;
1146 :
1147 0 : WidgetQueryContentEvent lookUpContent(true, eQueryTextContent, widget);
1148 0 : lookUpContent.InitForQueryTextContent(range.mBegin,
1149 0 : range.mEnd - range.mBegin);
1150 0 : lookUpContent.RequestFontRanges();
1151 0 : handler.OnQueryTextContent(&lookUpContent);
1152 0 : if (NS_WARN_IF(!lookUpContent.mSucceeded ||
1153 : lookUpContent.mReply.mString.IsEmpty())) {
1154 0 : return NS_ERROR_FAILURE;
1155 : }
1156 :
1157 0 : WidgetQueryContentEvent charRect(true, eQueryTextRect, widget);
1158 0 : charRect.InitForQueryTextRect(range.mBegin, range.mEnd - range.mBegin);
1159 0 : handler.OnQueryTextRect(&charRect);
1160 0 : if (NS_WARN_IF(!charRect.mSucceeded)) {
1161 0 : return NS_ERROR_FAILURE;
1162 : }
1163 :
1164 0 : widget->LookUpDictionary(lookUpContent.mReply.mString,
1165 : lookUpContent.mReply.mFontRanges,
1166 0 : charRect.mReply.mWritingMode.IsVertical(),
1167 0 : charRect.mReply.mRect.TopLeft());
1168 :
1169 0 : return NS_OK;
1170 : }
1171 :
1172 : /*---------------------------------------------------------------------------
1173 :
1174 : RegisterWindowCommands
1175 :
1176 : ----------------------------------------------------------------------------*/
1177 :
1178 : #define NS_REGISTER_ONE_COMMAND(_cmdClass, _cmdName) \
1179 : { \
1180 : _cmdClass* theCmd = new _cmdClass(); \
1181 : rv = inCommandTable->RegisterCommand(_cmdName, \
1182 : static_cast<nsIControllerCommand *>(theCmd)); \
1183 : }
1184 :
1185 : #define NS_REGISTER_FIRST_COMMAND(_cmdClass, _cmdName) \
1186 : { \
1187 : _cmdClass* theCmd = new _cmdClass(); \
1188 : rv = inCommandTable->RegisterCommand(_cmdName, \
1189 : static_cast<nsIControllerCommand *>(theCmd));
1190 :
1191 : #define NS_REGISTER_NEXT_COMMAND(_cmdClass, _cmdName) \
1192 : rv = inCommandTable->RegisterCommand(_cmdName, \
1193 : static_cast<nsIControllerCommand *>(theCmd));
1194 :
1195 : #define NS_REGISTER_LAST_COMMAND(_cmdClass, _cmdName) \
1196 : rv = inCommandTable->RegisterCommand(_cmdName, \
1197 : static_cast<nsIControllerCommand *>(theCmd)); \
1198 : }
1199 :
1200 :
1201 : // static
1202 : nsresult
1203 2 : nsWindowCommandRegistration::RegisterWindowCommands(
1204 : nsIControllerCommandTable *inCommandTable)
1205 : {
1206 : nsresult rv;
1207 :
1208 : // XXX rework the macros to use a loop is possible, reducing code size
1209 :
1210 : // this set of commands is affected by the 'browse with caret' setting
1211 2 : NS_REGISTER_FIRST_COMMAND(nsSelectMoveScrollCommand, sScrollTopString);
1212 2 : NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sScrollBottomString);
1213 2 : NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sScrollPageUpString);
1214 2 : NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sScrollPageDownString);
1215 2 : NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sScrollLineUpString);
1216 2 : NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sScrollLineDownString);
1217 2 : NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sScrollLeftString);
1218 2 : NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sScrollRightString);
1219 2 : NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sMoveTopString);
1220 2 : NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sMoveBottomString);
1221 2 : NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sWordPreviousString);
1222 2 : NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sWordNextString);
1223 2 : NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sBeginLineString);
1224 2 : NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sEndLineString);
1225 2 : NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sMovePageUpString);
1226 2 : NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sMovePageDownString);
1227 2 : NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sLinePreviousString);
1228 2 : NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sLineNextString);
1229 2 : NS_REGISTER_NEXT_COMMAND(nsSelectMoveScrollCommand, sCharPreviousString);
1230 2 : NS_REGISTER_LAST_COMMAND(nsSelectMoveScrollCommand, sCharNextString);
1231 :
1232 2 : NS_REGISTER_FIRST_COMMAND(nsPhysicalSelectMoveScrollCommand, sMoveLeftString);
1233 2 : NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectMoveScrollCommand, sMoveRightString);
1234 2 : NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectMoveScrollCommand, sMoveUpString);
1235 2 : NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectMoveScrollCommand, sMoveDownString);
1236 2 : NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectMoveScrollCommand, sMoveLeft2String);
1237 2 : NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectMoveScrollCommand, sMoveRight2String);
1238 2 : NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectMoveScrollCommand, sMoveUp2String);
1239 2 : NS_REGISTER_LAST_COMMAND(nsPhysicalSelectMoveScrollCommand, sMoveDown2String);
1240 :
1241 2 : NS_REGISTER_FIRST_COMMAND(nsSelectCommand, sSelectCharPreviousString);
1242 2 : NS_REGISTER_NEXT_COMMAND(nsSelectCommand, sSelectCharNextString);
1243 2 : NS_REGISTER_NEXT_COMMAND(nsSelectCommand, sSelectWordPreviousString);
1244 2 : NS_REGISTER_NEXT_COMMAND(nsSelectCommand, sSelectWordNextString);
1245 2 : NS_REGISTER_NEXT_COMMAND(nsSelectCommand, sSelectBeginLineString);
1246 2 : NS_REGISTER_NEXT_COMMAND(nsSelectCommand, sSelectEndLineString);
1247 2 : NS_REGISTER_NEXT_COMMAND(nsSelectCommand, sSelectLinePreviousString);
1248 2 : NS_REGISTER_NEXT_COMMAND(nsSelectCommand, sSelectLineNextString);
1249 2 : NS_REGISTER_NEXT_COMMAND(nsSelectCommand, sSelectPageUpString);
1250 2 : NS_REGISTER_NEXT_COMMAND(nsSelectCommand, sSelectPageDownString);
1251 2 : NS_REGISTER_NEXT_COMMAND(nsSelectCommand, sSelectTopString);
1252 2 : NS_REGISTER_LAST_COMMAND(nsSelectCommand, sSelectBottomString);
1253 :
1254 2 : NS_REGISTER_FIRST_COMMAND(nsPhysicalSelectCommand, sSelectLeftString);
1255 2 : NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectCommand, sSelectRightString);
1256 2 : NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectCommand, sSelectUpString);
1257 2 : NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectCommand, sSelectDownString);
1258 2 : NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectCommand, sSelectLeft2String);
1259 2 : NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectCommand, sSelectRight2String);
1260 2 : NS_REGISTER_NEXT_COMMAND(nsPhysicalSelectCommand, sSelectUp2String);
1261 2 : NS_REGISTER_LAST_COMMAND(nsPhysicalSelectCommand, sSelectDown2String);
1262 :
1263 2 : NS_REGISTER_ONE_COMMAND(nsClipboardCommand, "cmd_cut");
1264 2 : NS_REGISTER_ONE_COMMAND(nsClipboardCommand, "cmd_copy");
1265 2 : NS_REGISTER_ONE_COMMAND(nsClipboardCommand, "cmd_copyAndCollapseToEnd");
1266 2 : NS_REGISTER_ONE_COMMAND(nsClipboardCommand, "cmd_paste");
1267 2 : NS_REGISTER_ONE_COMMAND(nsClipboardCopyLinkCommand, "cmd_copyLink");
1268 2 : NS_REGISTER_FIRST_COMMAND(nsClipboardImageCommands, sCopyImageLocationString);
1269 2 : NS_REGISTER_NEXT_COMMAND(nsClipboardImageCommands, sCopyImageContentsString);
1270 2 : NS_REGISTER_LAST_COMMAND(nsClipboardImageCommands, sCopyImageString);
1271 2 : NS_REGISTER_FIRST_COMMAND(nsClipboardSelectAllNoneCommands, sSelectAllString);
1272 2 : NS_REGISTER_LAST_COMMAND(nsClipboardSelectAllNoneCommands, sSelectNoneString);
1273 :
1274 2 : NS_REGISTER_ONE_COMMAND(nsClipboardGetContentsCommand, "cmd_getContents");
1275 :
1276 : #if 0 // Remove unless needed again, bug 204777
1277 : NS_REGISTER_ONE_COMMAND(nsGoBackCommand, "cmd_browserBack");
1278 : NS_REGISTER_ONE_COMMAND(nsGoForwardCommand, "cmd_browserForward");
1279 : #endif
1280 :
1281 2 : NS_REGISTER_ONE_COMMAND(nsClipboardDragDropHookCommand, "cmd_clipboardDragDropHook");
1282 :
1283 2 : NS_REGISTER_ONE_COMMAND(nsLookUpDictionaryCommand, "cmd_lookUpDictionary");
1284 :
1285 2 : return rv;
1286 : }
1287 :
1288 : /* static */ bool
1289 0 : nsGlobalWindowCommands::FindScrollCommand(const char* aCommandName,
1290 : KeyboardScrollAction* aOutAction)
1291 : {
1292 : // Search for a keyboard scroll action to do for this command in browseCommands
1293 : // and physicalBrowseCommands. Each command exists in only one of them, so the
1294 : // order we examine browseCommands and physicalBrowseCommands doesn't matter.
1295 :
1296 0 : for (size_t i = 0; i < ArrayLength(browseCommands); i++) {
1297 0 : const BrowseCommand& cmd = browseCommands[i];
1298 0 : bool forward = !strcmp(aCommandName, cmd.forward);
1299 0 : bool reverse = !strcmp(aCommandName, cmd.reverse);
1300 0 : if (forward || reverse) {
1301 0 : *aOutAction = KeyboardScrollAction(cmd.scrollAction, forward);
1302 0 : return true;
1303 : }
1304 : }
1305 :
1306 0 : for (size_t i = 0; i < ArrayLength(physicalBrowseCommands); i++) {
1307 0 : const PhysicalBrowseCommand& cmd = physicalBrowseCommands[i];
1308 0 : if (!strcmp(aCommandName, cmd.command)) {
1309 0 : int16_t dir = cmd.direction;
1310 0 : bool forward = (dir == nsISelectionController::MOVE_RIGHT ||
1311 0 : dir == nsISelectionController::MOVE_DOWN);
1312 :
1313 0 : *aOutAction = KeyboardScrollAction(cmd.scrollAction, forward);
1314 0 : return true;
1315 : }
1316 : }
1317 :
1318 0 : return false;
1319 : }
|