browser(firefox): support internal drag and drop (#2243)
This commit is contained in:
parent
a38ac3fb62
commit
5a883a5877
|
|
@ -1 +1 @@
|
||||||
1094
|
1095
|
||||||
|
|
|
||||||
|
|
@ -3699,10 +3699,10 @@ index 0000000000000000000000000000000000000000..155d0770ddf704728829272a41a31ce8
|
||||||
+
|
+
|
||||||
diff --git a/juggler/content/PageAgent.js b/juggler/content/PageAgent.js
|
diff --git a/juggler/content/PageAgent.js b/juggler/content/PageAgent.js
|
||||||
new file mode 100644
|
new file mode 100644
|
||||||
index 0000000000000000000000000000000000000000..63754937b3464794227fe894b3d6057fbf0ae582
|
index 0000000000000000000000000000000000000000..73b6ee4d266ff648acd0a8dfb8909f9b0c76c28d
|
||||||
--- /dev/null
|
--- /dev/null
|
||||||
+++ b/juggler/content/PageAgent.js
|
+++ b/juggler/content/PageAgent.js
|
||||||
@@ -0,0 +1,914 @@
|
@@ -0,0 +1,992 @@
|
||||||
+"use strict";
|
+"use strict";
|
||||||
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
+const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||||
+const Ci = Components.interfaces;
|
+const Ci = Components.interfaces;
|
||||||
|
|
@ -3711,6 +3711,12 @@ index 0000000000000000000000000000000000000000..63754937b3464794227fe894b3d6057f
|
||||||
+
|
+
|
||||||
+const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
|
+const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
|
||||||
+const {NetUtil} = ChromeUtils.import('resource://gre/modules/NetUtil.jsm');
|
+const {NetUtil} = ChromeUtils.import('resource://gre/modules/NetUtil.jsm');
|
||||||
|
+const dragService = Cc["@mozilla.org/widget/dragservice;1"].getService(
|
||||||
|
+ Ci.nsIDragService
|
||||||
|
+);
|
||||||
|
+const obs = Cc["@mozilla.org/observer-service;1"].getService(
|
||||||
|
+ Ci.nsIObserverService
|
||||||
|
+);
|
||||||
+
|
+
|
||||||
+const helper = new Helper();
|
+const helper = new Helper();
|
||||||
+
|
+
|
||||||
|
|
@ -3862,6 +3868,7 @@ index 0000000000000000000000000000000000000000..63754937b3464794227fe894b3d6057f
|
||||||
+ this._docShell = docShell;
|
+ this._docShell = docShell;
|
||||||
+ this._initialDPPX = docShell.contentViewer.overrideDPPX;
|
+ this._initialDPPX = docShell.contentViewer.overrideDPPX;
|
||||||
+ this._customScrollbars = null;
|
+ this._customScrollbars = null;
|
||||||
|
+ this._dataTransfer = null;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ async _awaitViewportDimensions({width, height}) {
|
+ async _awaitViewportDimensions({width, height}) {
|
||||||
|
|
@ -4369,6 +4376,12 @@ index 0000000000000000000000000000000000000000..63754937b3464794227fe894b3d6057f
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ async _dispatchKeyEvent({type, keyCode, code, key, repeat, location, text}) {
|
+ async _dispatchKeyEvent({type, keyCode, code, key, repeat, location, text}) {
|
||||||
|
+ // key events don't fire if we are dragging.
|
||||||
|
+ if (this._dataTransfer) {
|
||||||
|
+ if (type === 'keydown' && key === 'Escape')
|
||||||
|
+ this._cancelDragIfNeeded();
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
+ const frame = this._frameTree.mainFrame();
|
+ const frame = this._frameTree.mainFrame();
|
||||||
+ const tip = frame.textInputProcessor();
|
+ const tip = frame.textInputProcessor();
|
||||||
+ if (key === 'Meta' && Services.appinfo.OS !== 'Darwin')
|
+ if (key === 'Meta' && Services.appinfo.OS !== 'Darwin')
|
||||||
|
|
@ -4415,8 +4428,61 @@ index 0000000000000000000000000000000000000000..63754937b3464794227fe894b3d6057f
|
||||||
+ return {defaultPrevented};
|
+ return {defaultPrevented};
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
|
+ _startDragSessionIfNeeded() {
|
||||||
|
+ const sess = dragService.getCurrentSession();
|
||||||
|
+ if (sess) return;
|
||||||
|
+ dragService.startDragSessionForTests(
|
||||||
|
+ Ci.nsIDragService.DRAGDROP_ACTION_MOVE |
|
||||||
|
+ Ci.nsIDragService.DRAGDROP_ACTION_COPY |
|
||||||
|
+ Ci.nsIDragService.DRAGDROP_ACTION_LINK
|
||||||
|
+ );
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ _simulateDragEvent(type, x, y, modifiers) {
|
||||||
|
+ const window = this._frameTree.mainFrame().domWindow();
|
||||||
|
+ const element = window.windowUtils.elementFromPoint(x, y, false, false);
|
||||||
|
+ const event = window.document.createEvent('DragEvent');
|
||||||
|
+
|
||||||
|
+ event.initDragEvent(
|
||||||
|
+ type,
|
||||||
|
+ true /* bubble */,
|
||||||
|
+ true /* cancelable */,
|
||||||
|
+ window,
|
||||||
|
+ 0 /* clickCount */,
|
||||||
|
+ window.mozInnerScreenX + x,
|
||||||
|
+ window.mozInnerScreenY + y,
|
||||||
|
+ x,
|
||||||
|
+ y,
|
||||||
|
+ modifiers & 2 /* ctrlkey */,
|
||||||
|
+ modifiers & 1 /* altKey */,
|
||||||
|
+ modifiers & 4 /* shiftKey */,
|
||||||
|
+ modifiers & 8 /* metaKey */,
|
||||||
|
+ 0 /* button */, // firefox always has the button as 0 on drops, regardless of which was pressed
|
||||||
|
+ null /* relatedTarget */,
|
||||||
|
+ this._dataTransfer
|
||||||
|
+ );
|
||||||
|
+
|
||||||
|
+ window.windowUtils.dispatchDOMEventViaPresShellForTesting(element, event);
|
||||||
|
+ if (type === 'drop')
|
||||||
|
+ dragService.endDragSession(true);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ _cancelDragIfNeeded() {
|
||||||
|
+ this._dataTransfer = null;
|
||||||
|
+ const sess = dragService.getCurrentSession();
|
||||||
|
+ if (sess)
|
||||||
|
+ dragService.endDragSession(false);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
+ async _dispatchMouseEvent({type, x, y, button, clickCount, modifiers, buttons}) {
|
+ async _dispatchMouseEvent({type, x, y, button, clickCount, modifiers, buttons}) {
|
||||||
|
+ this._startDragSessionIfNeeded();
|
||||||
|
+ const trapDrag = subject => {
|
||||||
|
+ this._dataTransfer = subject.mozCloneForEvent('drop');
|
||||||
|
+ }
|
||||||
|
+
|
||||||
+ const frame = this._frameTree.mainFrame();
|
+ const frame = this._frameTree.mainFrame();
|
||||||
|
+
|
||||||
|
+ obs.addObserver(trapDrag, 'on-datatransfer-available');
|
||||||
+ frame.domWindow().windowUtils.sendMouseEvent(
|
+ frame.domWindow().windowUtils.sendMouseEvent(
|
||||||
+ type,
|
+ type,
|
||||||
+ x,
|
+ x,
|
||||||
|
|
@ -4430,6 +4496,8 @@ index 0000000000000000000000000000000000000000..63754937b3464794227fe894b3d6057f
|
||||||
+ undefined /*isDOMEventSynthesized*/,
|
+ undefined /*isDOMEventSynthesized*/,
|
||||||
+ undefined /*isWidgetEventSynthesized*/,
|
+ undefined /*isWidgetEventSynthesized*/,
|
||||||
+ buttons);
|
+ buttons);
|
||||||
|
+ obs.removeObserver(trapDrag, 'on-datatransfer-available');
|
||||||
|
+
|
||||||
+ if (type === 'mousedown' && button === 2) {
|
+ if (type === 'mousedown' && button === 2) {
|
||||||
+ frame.domWindow().windowUtils.sendMouseEvent(
|
+ frame.domWindow().windowUtils.sendMouseEvent(
|
||||||
+ 'contextmenu',
|
+ 'contextmenu',
|
||||||
|
|
@ -4445,6 +4513,16 @@ index 0000000000000000000000000000000000000000..63754937b3464794227fe894b3d6057f
|
||||||
+ undefined /*isWidgetEventSynthesized*/,
|
+ undefined /*isWidgetEventSynthesized*/,
|
||||||
+ buttons);
|
+ buttons);
|
||||||
+ }
|
+ }
|
||||||
|
+
|
||||||
|
+ // update drag state
|
||||||
|
+ if (this._dataTransfer) {
|
||||||
|
+ if (type === 'mousemove')
|
||||||
|
+ this._simulateDragEvent('dragover', x, y, modifiers);
|
||||||
|
+ else if (type === 'mouseup') // firefox will do drops when any mouse button is released
|
||||||
|
+ this._simulateDragEvent('drop', x, y, modifiers);
|
||||||
|
+ } else {
|
||||||
|
+ this._cancelDragIfNeeded();
|
||||||
|
+ }
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ async _insertText({text}) {
|
+ async _insertText({text}) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue