зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1392281 - Pass window global to action module instead of container. r=automatedtester
Various functions in the action module take a container object such as {frame: <WindowProxy global>, shadowRoot: <Element>} when it in fact never uses the shadowRoot entry. As part of the new window tracking we will get rid of the container concept altogether. Because the action module is sufficiently self-contained, we can start with removing it from there already. MozReview-Commit-ID: KeeNF08mqnX --HG-- extra : rebase_source : 51eee50a648a994fab456adf4add46c91a6c82a3
This commit is contained in:
Родитель
dd1510aec5
Коммит
fca9551967
|
@ -961,21 +961,20 @@ action.Mouse = class {
|
|||
* actions for one tick.
|
||||
* @param {element.Store} seenEls
|
||||
* Element store.
|
||||
* @param {Object.<string, nsIDOMWindow>} container
|
||||
* Object with <code>frame</code> property of type
|
||||
* <code>nsIDOMWindow</code>.
|
||||
* @param {WindowProxy} window
|
||||
* Current window global.
|
||||
*
|
||||
* @return {Promise}
|
||||
* Promise for dispatching all actions in |chain|.
|
||||
*/
|
||||
action.dispatch = function(chain, seenEls, container) {
|
||||
action.dispatch = function(chain, seenEls, window) {
|
||||
let chainEvents = (async () => {
|
||||
for (let tickActions of chain) {
|
||||
await action.dispatchTickActions(
|
||||
tickActions,
|
||||
action.computeTickDuration(tickActions),
|
||||
seenEls,
|
||||
container);
|
||||
window);
|
||||
}
|
||||
})();
|
||||
return chainEvents;
|
||||
|
@ -998,19 +997,18 @@ action.dispatch = function(chain, seenEls, container) {
|
|||
* Duration in milliseconds of this tick.
|
||||
* @param {element.Store} seenEls
|
||||
* Element store.
|
||||
* @param {Object.<string, nsIDOMWindow>} container
|
||||
* Object with <code>frame</code> property of type
|
||||
* <code>nsIDOMWindow</code>.
|
||||
* @param {WindowProxy} window
|
||||
* Current window global.
|
||||
*
|
||||
* @return {Promise}
|
||||
* Promise for dispatching all tick-actions and pending DOM events.
|
||||
*/
|
||||
action.dispatchTickActions = function(
|
||||
tickActions, tickDuration, seenEls, container) {
|
||||
tickActions, tickDuration, seenEls, window) {
|
||||
let pendingEvents = tickActions.map(
|
||||
toEvents(tickDuration, seenEls, container));
|
||||
toEvents(tickDuration, seenEls, window));
|
||||
return Promise.all(pendingEvents).then(
|
||||
() => interaction.flushEventLoop(container.frame));
|
||||
() => interaction.flushEventLoop(window));
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1076,33 +1074,33 @@ action.computePointerDestination = function(
|
|||
* Duration in milliseconds of this tick.
|
||||
* @param {element.Store} seenEls
|
||||
* Element store.
|
||||
* @param {Object.<string, nsIDOMWindow>} container
|
||||
* Object with <code>frame</code> property of type
|
||||
* <code>nsIDOMWindow</code>.
|
||||
* @param {WindowProxy} window
|
||||
* Current window global.
|
||||
*
|
||||
* @return {function(action.Action): Promise}
|
||||
* Function that takes an action and returns a Promise for dispatching
|
||||
* the event that corresponds to that action.
|
||||
*/
|
||||
function toEvents(tickDuration, seenEls, container) {
|
||||
function toEvents(tickDuration, seenEls, window) {
|
||||
return a => {
|
||||
let inputState = action.inputStateMap.get(a.id);
|
||||
|
||||
switch (a.subtype) {
|
||||
case action.KeyUp:
|
||||
return dispatchKeyUp(a, inputState, container.frame);
|
||||
return dispatchKeyUp(a, inputState, window);
|
||||
|
||||
case action.KeyDown:
|
||||
return dispatchKeyDown(a, inputState, container.frame);
|
||||
return dispatchKeyDown(a, inputState, window);
|
||||
|
||||
case action.PointerDown:
|
||||
return dispatchPointerDown(a, inputState, container.frame);
|
||||
return dispatchPointerDown(a, inputState, window);
|
||||
|
||||
case action.PointerUp:
|
||||
return dispatchPointerUp(a, inputState, container.frame);
|
||||
return dispatchPointerUp(a, inputState, window);
|
||||
|
||||
case action.PointerMove:
|
||||
return dispatchPointerMove(
|
||||
a, inputState, tickDuration, seenEls, container);
|
||||
a, inputState, tickDuration, seenEls, window);
|
||||
|
||||
case action.PointerCancel:
|
||||
throw new UnsupportedOperationError();
|
||||
|
@ -1110,6 +1108,7 @@ function toEvents(tickDuration, seenEls, container) {
|
|||
case action.Pause:
|
||||
return dispatchPause(a, tickDuration);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
}
|
||||
|
@ -1287,36 +1286,37 @@ function dispatchPointerUp(a, inputState, win) {
|
|||
* Input state for this action's input source.
|
||||
* @param {element.Store} seenEls
|
||||
* Element store.
|
||||
* @param {Object.<string, nsIDOMWindow>} container
|
||||
* Object with <code>frame</code> property of type
|
||||
* <code>nsIDOMWindow</code>.
|
||||
* @param {WindowProxy} window
|
||||
* Current window global.
|
||||
*
|
||||
* @return {Promise}
|
||||
* Promise to dispatch at least one pointermove event, as well as
|
||||
* mousemove events as appropriate.
|
||||
*/
|
||||
function dispatchPointerMove(
|
||||
a, inputState, tickDuration, seenEls, container) {
|
||||
function dispatchPointerMove(a, inputState, tickDuration, seenEls, window) {
|
||||
const timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||
// interval between pointermove increments in ms, based on common vsync
|
||||
const fps60 = 17;
|
||||
|
||||
return new Promise(resolve => {
|
||||
const start = Date.now();
|
||||
const [startX, startY] = [inputState.x, inputState.y];
|
||||
|
||||
let target = action.computePointerDestination(a, inputState,
|
||||
getElementCenter(a.origin, seenEls, container));
|
||||
getElementCenter(a.origin, seenEls, window));
|
||||
const [targetX, targetY] = [target.x, target.y];
|
||||
if (!inViewPort(targetX, targetY, container.frame)) {
|
||||
|
||||
if (!inViewPort(targetX, targetY, window)) {
|
||||
throw new MoveTargetOutOfBoundsError(
|
||||
`(${targetX}, ${targetY}) is out of bounds of viewport ` +
|
||||
`width (${container.frame.innerWidth}) ` +
|
||||
`and height (${container.frame.innerHeight})`);
|
||||
`width (${window.innerWidth}) ` +
|
||||
`and height (${window.innerHeight})`);
|
||||
}
|
||||
|
||||
const duration = typeof a.duration == "undefined" ? tickDuration : a.duration;
|
||||
if (duration === 0) {
|
||||
// move pointer to destination in one step
|
||||
performOnePointerMove(inputState, targetX, targetY, container.frame);
|
||||
performOnePointerMove(inputState, targetX, targetY, window);
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
@ -1328,22 +1328,25 @@ function dispatchPointerMove(
|
|||
// wait |fps60| ms before performing first incremental pointer move
|
||||
await new Promise(resolveTimer =>
|
||||
timer.initWithCallback(resolveTimer, fps60, ONE_SHOT));
|
||||
|
||||
let durationRatio = Math.floor(Date.now() - start) / duration;
|
||||
const epsilon = fps60 / duration / 10;
|
||||
while ((1 - durationRatio) > epsilon) {
|
||||
let x = Math.floor(durationRatio * distanceX + startX);
|
||||
let y = Math.floor(durationRatio * distanceY + startY);
|
||||
performOnePointerMove(inputState, x, y, container.frame);
|
||||
performOnePointerMove(inputState, x, y, window);
|
||||
// wait |fps60| ms before performing next pointer move
|
||||
await new Promise(resolveTimer =>
|
||||
timer.initWithCallback(resolveTimer, fps60, ONE_SHOT));
|
||||
|
||||
durationRatio = Math.floor(Date.now() - start) / duration;
|
||||
}
|
||||
})();
|
||||
|
||||
// perform last pointer move after all incremental moves are resolved and
|
||||
// durationRatio is close enough to 1
|
||||
intermediatePointerEvents.then(() => {
|
||||
performOnePointerMove(inputState, targetX, targetY, container.frame);
|
||||
performOnePointerMove(inputState, targetX, targetY, window);
|
||||
resolve();
|
||||
});
|
||||
|
||||
|
@ -1409,11 +1412,11 @@ function inViewPort(x, y, win) {
|
|||
return !(x < 0 || y < 0 || x > win.innerWidth || y > win.innerHeight);
|
||||
}
|
||||
|
||||
function getElementCenter(elementReference, seenEls, container) {
|
||||
function getElementCenter(elementReference, seenEls, window) {
|
||||
if (element.isWebElementReference(elementReference)) {
|
||||
let uuid = elementReference[element.Key] ||
|
||||
elementReference[element.LegacyKey];
|
||||
let el = seenEls.get(uuid, container);
|
||||
let el = seenEls.get(uuid, {frame: window});
|
||||
return element.coordinates(el);
|
||||
}
|
||||
return {};
|
||||
|
|
|
@ -937,7 +937,7 @@ function createATouch(el, corx, cory, touchId) {
|
|||
*/
|
||||
async function performActions(msg) {
|
||||
let chain = action.Chain.fromJson(msg.actions);
|
||||
await action.dispatch(chain, seenEls, curContainer);
|
||||
await action.dispatch(chain, seenEls, curContainer.frame);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -948,7 +948,7 @@ async function performActions(msg) {
|
|||
*/
|
||||
async function releaseActions() {
|
||||
await action.dispatchTickActions(
|
||||
action.inputsToCancel.reverse(), 0, seenEls, curContainer);
|
||||
action.inputsToCancel.reverse(), 0, seenEls, curContainer.frame);
|
||||
action.inputsToCancel.length = 0;
|
||||
action.inputStateMap.clear();
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче