OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 if (top === window) { | |
6 testTop(); | |
7 } else { | |
8 testChild(); | |
9 } | |
10 | |
11 function testTop() { | |
12 var testMessage = {}; | |
13 function reportFrames() { | |
14 if (reportFrames.didRun) | |
15 return; | |
16 reportFrames.didRun = true; | |
17 testMessage.frameCount = frames.length; | |
18 testMessage.frameHTML = window.frameHTML; | |
19 chrome.runtime.sendMessage(testMessage); | |
20 } | |
21 window.onmessage = function(event) { | |
22 if (event.data === 'toBeRemoved') | |
Devlin
2016/03/15 16:34:34
Do we expect any other messages? Can this be an a
robwu
2016/03/16 22:03:32
Done.
| |
23 reportFrames(); | |
24 }; | |
25 window.onload = function() { | |
26 // Fall back, in case the content script never ran. | |
Devlin
2016/03/15 16:34:35
If the content script never runs, shouldn't this b
robwu
2016/03/16 22:03:32
This event was too defensive and is not necessary.
| |
27 setTimeout(reportFrames, 3000); | |
28 }; | |
29 | |
30 if (window.frameHTML) { // Set by child frame... | |
31 // about:blank frames are synchronously parsed, so their document_end script | |
32 // injection happens before the main frame's injection. | |
33 var expectChildBeforeMain = location.search.includes('?blankend'); | |
34 if (!expectChildBeforeMain) { | |
35 // Add a message to the test notification to cause the test to fail, | |
36 // with some useful information for diagnostics. | |
37 testMessage.warning = 'Content script in child frame was executed ' + | |
38 'before the main frame\'s content script!'; | |
Devlin
2016/03/15 00:53:32
nit: indentation
robwu
2016/03/16 22:03:32
Done.
| |
39 } | |
40 reportFrames(); | |
41 } | |
42 window.frameHTML = '(not set)'; | |
43 } | |
44 | |
45 function testChild() { | |
46 var TEST_HOST = parent.location.hostname; | |
47 | |
48 if (TEST_HOST === 'synchronous') { | |
49 doRemove(); | |
50 } else if (TEST_HOST === 'microtask') { | |
51 Promise.resolve().then(doRemove); | |
52 } else if (TEST_HOST === 'macrotask') { | |
53 setTimeout(doRemove, 0); | |
54 } else if (TEST_HOST.startsWith('domnodeinserted')) { | |
55 removeOnEvent('DOMNodeInserted'); | |
56 } else if (TEST_HOST.startsWith('domsubtreemodified')) { | |
57 removeOnEvent('DOMSubtreeModified'); | |
58 } else { | |
59 console.error('Unexpected test: ' + TEST_HOST); | |
60 chrome.test.fail(); | |
61 } | |
62 | |
63 function doRemove() { | |
64 parent.frameHTML = document.documentElement.outerHTML || '(no outerHTML)'; | |
65 parent.postMessage('toBeRemoved', '*'); | |
66 // frameElement = <iframe> element in parent document. | |
67 frameElement.remove(); | |
68 } | |
69 | |
70 function removeOnEvent(eventName) { | |
71 // For document_start scripts, DOM mutation events are likely, so pick a | |
72 // generous time-out delay to make sure that all parser-initiated DOM | |
73 // mutations have been processed. | |
74 // DOM mutation events are not really expected in document_end scripts, so | |
75 // use a very small time-out delay. | |
76 var delay = parent.location.search.includes('?start') ? 1000 : 50; | |
77 var expected = parseInt(TEST_HOST.match(/\d+/)[0]); | |
78 // Fallback in case the mutation events are not triggered. | |
79 setTimeout(function() { | |
80 if (expected > 0) { | |
81 expected = 0; | |
82 doRemove(); | |
Devlin
2016/03/15 16:34:34
I'm not quite sure I understand the reasoning here
robwu
2016/03/16 22:03:32
I replaced the timer with a window.onload notifica
| |
83 } | |
84 }, delay); | |
85 document.addEventListener(eventName, function() { | |
86 if (--expected === 0) | |
87 doRemove(); | |
88 }); | |
89 } | |
90 } | |
OLD | NEW |