|
1 <!DOCTYPE HTML> |
|
2 <html> |
|
3 <!-- |
|
4 https://bugzilla.mozilla.org/show_bug.cgi?id= |
|
5 --> |
|
6 <head> |
|
7 <meta charset="utf-8"> |
|
8 <title>Test for Bug </title> |
|
9 |
|
10 <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> |
|
11 <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"> |
|
12 <script type="application/javascript;version=1.8" src="inspector-helpers.js"></script> |
|
13 <script type="application/javascript;version=1.8"> |
|
14 Components.utils.import("resource://gre/modules/devtools/Loader.jsm"); |
|
15 const {Promise: promise} = Components.utils.import("resource://gre/modules/Promise.jsm", {}); |
|
16 |
|
17 const inspector = devtools.require("devtools/server/actors/inspector"); |
|
18 const DOMUtils = Components.classes["@mozilla.org/inspector/dom-utils;1"]. |
|
19 getService(Components.interfaces.inIDOMUtils); |
|
20 |
|
21 const KNOWN_PSEUDOCLASSES = [':hover', ':active', ':focus'] |
|
22 |
|
23 window.onload = function() { |
|
24 SimpleTest.waitForExplicitFinish(); |
|
25 runNextTest(); |
|
26 } |
|
27 |
|
28 var gInspectee = null; |
|
29 var gWalker = null; |
|
30 var gClient = null; |
|
31 var gCleanupConnection = null; |
|
32 |
|
33 function setup(callback) { |
|
34 let url = document.getElementById("inspectorContent").href; |
|
35 gCleanupConnection = attachURL(url, function(err, client, tab, doc) { |
|
36 gInspectee = doc; |
|
37 let {InspectorFront} = devtools.require("devtools/server/actors/inspector"); |
|
38 let inspector = InspectorFront(client, tab); |
|
39 promiseDone(inspector.getWalker().then(walker => { |
|
40 gClient = client; |
|
41 gWalker = walker; |
|
42 }).then(callback)); |
|
43 }); |
|
44 } |
|
45 |
|
46 function teardown() { |
|
47 gWalker = null; |
|
48 gClient = null; |
|
49 gInspectee = null; |
|
50 if (gCleanupConnection) { |
|
51 gCleanupConnection(); |
|
52 gCleanupConnection = null; |
|
53 } |
|
54 } |
|
55 |
|
56 function checkChange(change, expectation) { |
|
57 is(change.type, "pseudoClassLock", "Expect a pseudoclass lock change."); |
|
58 let target = change.target; |
|
59 if (expectation.id) |
|
60 is(target.id, expectation.id, "Expect a change on node id " + expectation.id); |
|
61 if (expectation.nodeName) |
|
62 is(target.nodeName, expectation.nodeName, "Expect a change on node name " + expectation.nodeName); |
|
63 |
|
64 is(target.pseudoClassLocks.length, expectation.pseudos.length, |
|
65 "Expect " + expectation.pseudos.length + " pseudoclass locks."); |
|
66 for (let pseudo of expectation.pseudos) { |
|
67 ok(target.hasPseudoClassLock(pseudo), "Expect lock: " + pseudo); |
|
68 ok(DOMUtils.hasPseudoClassLock(target.rawNode(), pseudo), "Expect lock in dom: " + pseudo); |
|
69 } |
|
70 |
|
71 for (let pseudo of KNOWN_PSEUDOCLASSES) { |
|
72 if (!expectation.pseudos.some(expected => pseudo === expected)) { |
|
73 ok(!target.hasPseudoClassLock(pseudo), "Don't expect lock: " + pseudo); |
|
74 ok(!DOMUtils.hasPseudoClassLock(target.rawNode(), pseudo), "Don't expect lock in dom: " + pseudo); |
|
75 |
|
76 } |
|
77 } |
|
78 } |
|
79 |
|
80 function checkMutations(mutations, expectations) { |
|
81 is(mutations.length, expectations.length, "Should get the right number of mutations."); |
|
82 for (let i = 0; i < mutations.length; i++) { |
|
83 checkChange(mutations[i] , expectations[i]); |
|
84 } |
|
85 } |
|
86 |
|
87 addTest(function testPseudoClassLock() { |
|
88 let contentNode; |
|
89 let nodeFront; |
|
90 setup(() => { |
|
91 contentNode = gInspectee.querySelector("#b"); |
|
92 return promiseDone(gWalker.querySelector(gWalker.rootNode, "#b").then(front => { |
|
93 nodeFront = front; |
|
94 // Lock the pseudoclass alone, no parents. |
|
95 gWalker.addPseudoClassLock(nodeFront, ':active'); |
|
96 // Expect a single pseudoClassLock mutation. |
|
97 return promiseOnce(gWalker, "mutations"); |
|
98 }).then(mutations => { |
|
99 is(mutations.length, 1, "Should get one mutations"); |
|
100 is(mutations[0].target, nodeFront, "Should be the node we tried to apply to"); |
|
101 checkChange(mutations[0], { |
|
102 id: "b", |
|
103 nodeName: "DIV", |
|
104 pseudos: [":active"] |
|
105 }); |
|
106 }).then(() => { |
|
107 // Now add :hover, this time with parents. |
|
108 gWalker.addPseudoClassLock(nodeFront, ':hover', {parents: true}); |
|
109 return promiseOnce(gWalker, "mutations"); |
|
110 }).then(mutations => { |
|
111 let expectedMutations = [{ |
|
112 id: 'b', |
|
113 nodeName: 'DIV', |
|
114 pseudos: [':hover', ':active'], |
|
115 }, |
|
116 { |
|
117 id: 'longlist', |
|
118 nodeName: 'DIV', |
|
119 pseudos: [':hover'] |
|
120 }, |
|
121 { |
|
122 nodeName: 'BODY', |
|
123 pseudos: [':hover'] |
|
124 }, |
|
125 { |
|
126 nodeName: 'HTML', |
|
127 pseudos: [':hover'] |
|
128 }]; |
|
129 checkMutations(mutations, expectedMutations); |
|
130 }).then(() => { |
|
131 // Now remove the :hover on all parents |
|
132 gWalker.removePseudoClassLock(nodeFront, ':hover', {parents: true}); |
|
133 return promiseOnce(gWalker, "mutations"); |
|
134 }).then(mutations => { |
|
135 let expectedMutations = [{ |
|
136 id: 'b', |
|
137 nodeName: 'DIV', |
|
138 // Should still have :active on the original node. |
|
139 pseudos: [':active'] |
|
140 }, |
|
141 { |
|
142 id: 'longlist', |
|
143 nodeName: 'DIV', |
|
144 pseudos: [] |
|
145 }, |
|
146 { |
|
147 nodeName: 'BODY', |
|
148 pseudos: [] |
|
149 }, |
|
150 { |
|
151 nodeName: 'HTML', |
|
152 pseudos: [] |
|
153 }]; |
|
154 checkMutations(mutations, expectedMutations); |
|
155 }).then(() => { |
|
156 // Now shut down the walker and make sure that clears up the remaining lock. |
|
157 return gWalker.release(); |
|
158 }).then(() => { |
|
159 ok(!DOMUtils.hasPseudoClassLock(contentNode, ':active'), "Pseudoclass should have been removed during destruction."); |
|
160 teardown(); |
|
161 }).then(runNextTest)); |
|
162 }); |
|
163 }); |
|
164 |
|
165 </script> |
|
166 </head> |
|
167 <body> |
|
168 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug </a> |
|
169 <a id="inspectorContent" target="_blank" href="inspector-traversal-data.html">Test Document</a> |
|
170 <p id="display"></p> |
|
171 <div id="content" style="display: none"> |
|
172 |
|
173 </div> |
|
174 <pre id="test"> |
|
175 </pre> |
|
176 </body> |
|
177 </html> |