BrowserElementCopyPaste.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. /* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- /
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  4. * You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. "use strict";
  6. function debug(msg) {
  7. // dump("BrowserElementCopyPaste - " + msg + "\n");
  8. }
  9. debug("loaded");
  10. var { classes: Cc, interfaces: Ci, results: Cr, utils: Cu } = Components;
  11. var CopyPasteAssistent = {
  12. COMMAND_MAP: {
  13. 'cut': 'cmd_cut',
  14. 'copy': 'cmd_copyAndCollapseToEnd',
  15. 'paste': 'cmd_paste',
  16. 'selectall': 'cmd_selectAll'
  17. },
  18. init: function() {
  19. addEventListener("mozcaretstatechanged", this,
  20. /* useCapture = */ true, /* wantsUntrusted = */ false);
  21. addMessageListener("browser-element-api:call", this);
  22. },
  23. destroy: function() {
  24. removeEventListener("mozcaretstatechanged", this,
  25. /* useCapture = */ true, /* wantsUntrusted = */ false);
  26. removeMessageListener("browser-element-api:call", this);
  27. },
  28. handleEvent: function(event) {
  29. switch (event.type) {
  30. case "mozcaretstatechanged":
  31. this._caretStateChangedHandler(event);
  32. break;
  33. }
  34. },
  35. receiveMessage: function(message) {
  36. switch (message.name) {
  37. case "browser-element-api:call":
  38. this._browserAPIHandler(message);
  39. break;
  40. }
  41. },
  42. _browserAPIHandler: function(e) {
  43. switch (e.data.msg_name) {
  44. case 'copypaste-do-command':
  45. if (this._isCommandEnabled(e.data.command)) {
  46. docShell.doCommand(this.COMMAND_MAP[e.data.command]);
  47. }
  48. break;
  49. }
  50. },
  51. _isCommandEnabled: function(cmd) {
  52. let command = this.COMMAND_MAP[cmd];
  53. if (!command) {
  54. return false;
  55. }
  56. return docShell.isCommandEnabled(command);
  57. },
  58. _caretStateChangedHandler: function(e) {
  59. e.stopPropagation();
  60. let boundingClientRect = e.boundingClientRect;
  61. let canPaste = this._isCommandEnabled("paste");
  62. let zoomFactor = content.innerWidth == 0 ? 1 : content.screen.width / content.innerWidth;
  63. let detail = {
  64. rect: {
  65. width: boundingClientRect ? boundingClientRect.width : 0,
  66. height: boundingClientRect ? boundingClientRect.height : 0,
  67. top: boundingClientRect ? boundingClientRect.top : 0,
  68. bottom: boundingClientRect ? boundingClientRect.bottom : 0,
  69. left: boundingClientRect ? boundingClientRect.left : 0,
  70. right: boundingClientRect ? boundingClientRect.right : 0,
  71. },
  72. commands: {
  73. canSelectAll: this._isCommandEnabled("selectall"),
  74. canCut: this._isCommandEnabled("cut"),
  75. canCopy: this._isCommandEnabled("copy"),
  76. canPaste: this._isCommandEnabled("paste"),
  77. },
  78. zoomFactor: zoomFactor,
  79. reason: e.reason,
  80. collapsed: e.collapsed,
  81. caretVisible: e.caretVisible,
  82. selectionVisible: e.selectionVisible,
  83. selectionEditable: e.selectionEditable,
  84. selectedTextContent: e.selectedTextContent
  85. };
  86. // Get correct geometry information if we have nested iframe.
  87. let currentWindow = e.target.defaultView;
  88. while (currentWindow.realFrameElement) {
  89. let currentRect = currentWindow.realFrameElement.getBoundingClientRect();
  90. detail.rect.top += currentRect.top;
  91. detail.rect.bottom += currentRect.top;
  92. detail.rect.left += currentRect.left;
  93. detail.rect.right += currentRect.left;
  94. currentWindow = currentWindow.realFrameElement.ownerDocument.defaultView;
  95. let targetDocShell = currentWindow
  96. .QueryInterface(Ci.nsIInterfaceRequestor)
  97. .getInterface(Ci.nsIWebNavigation);
  98. if(targetDocShell.isMozBrowserOrApp) {
  99. break;
  100. }
  101. }
  102. sendAsyncMsg('caretstatechanged', detail);
  103. },
  104. };
  105. CopyPasteAssistent.init();