@@ -3699,10 +3699,10 @@ index 0000000000000000000000000000000000000000..155d0770ddf704728829272a41a31ce8
3699
3699
+
3700
3700
diff --git a/juggler/content/PageAgent.js b/juggler/content/PageAgent.js
3701
3701
new file mode 100644
3702
- index 0000000000000000000000000000000000000000..63754937b3464794227fe894b3d6057fbf0ae582
3702
+ index 0000000000000000000000000000000000000000..73b6ee4d266ff648acd0a8dfb8909f9b0c76c28d
3703
3703
--- /dev/null
3704
3704
+++ b/juggler/content/PageAgent.js
3705
- @@ -0,0 +1,914 @@
3705
+ @@ -0,0 +1,992 @@
3706
3706
+ "use strict";
3707
3707
+ const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
3708
3708
+ const Ci = Components.interfaces;
@@ -3711,6 +3711,12 @@ index 0000000000000000000000000000000000000000..63754937b3464794227fe894b3d6057f
3711
3711
+
3712
3712
+ const {Helper} = ChromeUtils.import('chrome://juggler/content/Helper.js');
3713
3713
+ const {NetUtil} = ChromeUtils.import('resource://gre/modules/NetUtil.jsm');
3714
+ + const dragService = Cc["@mozilla.org/widget/dragservice;1"].getService(
3715
+ + Ci.nsIDragService
3716
+ + );
3717
+ + const obs = Cc["@mozilla.org/observer-service;1"].getService(
3718
+ + Ci.nsIObserverService
3719
+ + );
3714
3720
+
3715
3721
+ const helper = new Helper();
3716
3722
+
@@ -3862,6 +3868,7 @@ index 0000000000000000000000000000000000000000..63754937b3464794227fe894b3d6057f
3862
3868
+ this._docShell = docShell;
3863
3869
+ this._initialDPPX = docShell.contentViewer.overrideDPPX;
3864
3870
+ this._customScrollbars = null;
3871
+ + this._dataTransfer = null;
3865
3872
+ }
3866
3873
+
3867
3874
+ async _awaitViewportDimensions({width, height}) {
@@ -4369,6 +4376,12 @@ index 0000000000000000000000000000000000000000..63754937b3464794227fe894b3d6057f
4369
4376
+ }
4370
4377
+
4371
4378
+ async _dispatchKeyEvent({type, keyCode, code, key, repeat, location, text}) {
4379
+ + // key events don't fire if we are dragging.
4380
+ + if (this._dataTransfer) {
4381
+ + if (type === 'keydown' && key === 'Escape')
4382
+ + this._cancelDragIfNeeded();
4383
+ + return;
4384
+ + }
4372
4385
+ const frame = this._frameTree.mainFrame();
4373
4386
+ const tip = frame.textInputProcessor();
4374
4387
+ if (key === 'Meta' && Services.appinfo.OS !== 'Darwin')
@@ -4415,8 +4428,61 @@ index 0000000000000000000000000000000000000000..63754937b3464794227fe894b3d6057f
4415
4428
+ return {defaultPrevented};
4416
4429
+ }
4417
4430
+
4431
+ + _startDragSessionIfNeeded() {
4432
+ + const sess = dragService.getCurrentSession();
4433
+ + if (sess) return;
4434
+ + dragService.startDragSessionForTests(
4435
+ + Ci.nsIDragService.DRAGDROP_ACTION_MOVE |
4436
+ + Ci.nsIDragService.DRAGDROP_ACTION_COPY |
4437
+ + Ci.nsIDragService.DRAGDROP_ACTION_LINK
4438
+ + );
4439
+ + }
4440
+ +
4441
+ + _simulateDragEvent(type, x, y, modifiers) {
4442
+ + const window = this._frameTree.mainFrame().domWindow();
4443
+ + const element = window.windowUtils.elementFromPoint(x, y, false, false);
4444
+ + const event = window.document.createEvent('DragEvent');
4445
+ +
4446
+ + event.initDragEvent(
4447
+ + type,
4448
+ + true /* bubble */,
4449
+ + true /* cancelable */,
4450
+ + window,
4451
+ + 0 /* clickCount */,
4452
+ + window.mozInnerScreenX + x,
4453
+ + window.mozInnerScreenY + y,
4454
+ + x,
4455
+ + y,
4456
+ + modifiers & 2 /* ctrlkey */,
4457
+ + modifiers & 1 /* altKey */,
4458
+ + modifiers & 4 /* shiftKey */,
4459
+ + modifiers & 8 /* metaKey */,
4460
+ + 0 /* button */, // firefox always has the button as 0 on drops, regardless of which was pressed
4461
+ + null /* relatedTarget */,
4462
+ + this._dataTransfer
4463
+ + );
4464
+ +
4465
+ + window.windowUtils.dispatchDOMEventViaPresShellForTesting(element, event);
4466
+ + if (type === 'drop')
4467
+ + dragService.endDragSession(true);
4468
+ + }
4469
+ +
4470
+ + _cancelDragIfNeeded() {
4471
+ + this._dataTransfer = null;
4472
+ + const sess = dragService.getCurrentSession();
4473
+ + if (sess)
4474
+ + dragService.endDragSession(false);
4475
+ + }
4476
+ +
4418
4477
+ async _dispatchMouseEvent({type, x, y, button, clickCount, modifiers, buttons}) {
4478
+ + this._startDragSessionIfNeeded();
4479
+ + const trapDrag = subject => {
4480
+ + this._dataTransfer = subject.mozCloneForEvent('drop');
4481
+ + }
4482
+ +
4419
4483
+ const frame = this._frameTree.mainFrame();
4484
+ +
4485
+ + obs.addObserver(trapDrag, 'on-datatransfer-available');
4420
4486
+ frame.domWindow().windowUtils.sendMouseEvent(
4421
4487
+ type,
4422
4488
+ x,
@@ -4430,6 +4496,8 @@ index 0000000000000000000000000000000000000000..63754937b3464794227fe894b3d6057f
4430
4496
+ undefined /*isDOMEventSynthesized*/,
4431
4497
+ undefined /*isWidgetEventSynthesized*/,
4432
4498
+ buttons);
4499
+ + obs.removeObserver(trapDrag, 'on-datatransfer-available');
4500
+ +
4433
4501
+ if (type === 'mousedown' && button === 2) {
4434
4502
+ frame.domWindow().windowUtils.sendMouseEvent(
4435
4503
+ 'contextmenu',
@@ -4445,6 +4513,16 @@ index 0000000000000000000000000000000000000000..63754937b3464794227fe894b3d6057f
4445
4513
+ undefined /*isWidgetEventSynthesized*/,
4446
4514
+ buttons);
4447
4515
+ }
4516
+ +
4517
+ + // update drag state
4518
+ + if (this._dataTransfer) {
4519
+ + if (type === 'mousemove')
4520
+ + this._simulateDragEvent('dragover', x, y, modifiers);
4521
+ + else if (type === 'mouseup') // firefox will do drops when any mouse button is released
4522
+ + this._simulateDragEvent('drop', x, y, modifiers);
4523
+ + } else {
4524
+ + this._cancelDragIfNeeded();
4525
+ + }
4448
4526
+ }
4449
4527
+
4450
4528
+ async _insertText({text}) {
0 commit comments