summaryrefslogtreecommitdiffstats
path: root/devtools/client/animationinspector/test/doc_frame_script.js
blob: 6846c9b299b6bc2b3f2c052646baec37bfb0ab77 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
 http://creativecommons.org/publicdomain/zero/1.0/ */
/* globals addMessageListener, sendAsyncMessage */

"use strict";

// A helper frame-script for brower/devtools/animationinspector tests.

/**
 * Toggle (play or pause) one of the animation players of a given node.
 * @param {Object} data
 * - {String} selector The CSS selector to get the node (can be a "super"
 *   selector).
 * - {Number} animationIndex The index of the node's animationPlayers to play
 *   or pause
 * - {Boolean} pause True to pause the animation, false to play.
 */
addMessageListener("Test:ToggleAnimationPlayer", function (msg) {
  let {selector, animationIndex, pause} = msg.data;
  let node = superQuerySelector(selector);
  if (!node) {
    return;
  }

  let animation = node.getAnimations()[animationIndex];
  if (pause) {
    animation.pause();
  } else {
    animation.play();
  }

  sendAsyncMessage("Test:ToggleAnimationPlayer");
});

/**
 * Change the currentTime of one of the animation players of a given node.
 * @param {Object} data
 * - {String} selector The CSS selector to get the node (can be a "super"
 *   selector).
 * - {Number} animationIndex The index of the node's animationPlayers to change.
 * - {Number} currentTime The current time to set.
 */
addMessageListener("Test:SetAnimationPlayerCurrentTime", function (msg) {
  let {selector, animationIndex, currentTime} = msg.data;
  let node = superQuerySelector(selector);
  if (!node) {
    return;
  }

  let animation = node.getAnimations()[animationIndex];
  animation.currentTime = currentTime;

  sendAsyncMessage("Test:SetAnimationPlayerCurrentTime");
});

/**
 * Change the playbackRate of one of the animation players of a given node.
 * @param {Object} data
 * - {String} selector The CSS selector to get the node (can be a "super"
 *   selector).
 * - {Number} animationIndex The index of the node's animationPlayers to change.
 * - {Number} playbackRate The rate to set.
 */
addMessageListener("Test:SetAnimationPlayerPlaybackRate", function (msg) {
  let {selector, animationIndex, playbackRate} = msg.data;
  let node = superQuerySelector(selector);
  if (!node) {
    return;
  }

  let player = node.getAnimations()[animationIndex];
  player.playbackRate = playbackRate;

  sendAsyncMessage("Test:SetAnimationPlayerPlaybackRate");
});

/**
 * Get the current playState of an animation player on a given node.
 * @param {Object} data
 * - {String} selector The CSS selector to get the node (can be a "super"
 *   selector).
 * - {Number} animationIndex The index of the node's animationPlayers to check
 */
addMessageListener("Test:GetAnimationPlayerState", function (msg) {
  let {selector, animationIndex} = msg.data;
  let node = superQuerySelector(selector);
  if (!node) {
    return;
  }

  let animation = node.getAnimations()[animationIndex];
  animation.ready.then(() => {
    sendAsyncMessage("Test:GetAnimationPlayerState", animation.playState);
  });
});

/**
 * Like document.querySelector but can go into iframes too.
 * ".container iframe || .sub-container div" will first try to find the node
 * matched by ".container iframe" in the root document, then try to get the
 * content document inside it, and then try to match ".sub-container div" inside
 * this document.
 * Any selector coming before the || separator *MUST* match a frame node.
 * @param {String} superSelector.
 * @return {DOMNode} The node, or null if not found.
 */
function superQuerySelector(superSelector, root = content.document) {
  let frameIndex = superSelector.indexOf("||");
  if (frameIndex === -1) {
    return root.querySelector(superSelector);
  }

  let rootSelector = superSelector.substring(0, frameIndex).trim();
  let childSelector = superSelector.substring(frameIndex + 2).trim();
  root = root.querySelector(rootSelector);
  if (!root || !root.contentWindow) {
    return null;
  }

  return superQuerySelector(childSelector, root.contentWindow.document);
}