Coverage Report

Created: 2018-09-25 14:53

/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
}