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