1 // Copyright (c) 2012 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.
5 // Common js for prerender loaders; defines the helper functions that put
6 // event handlers on prerenders and track the events for browser tests.
8 // TODO(gavinp): Put more common loader logic in here.
10 // Currently only errors with the ordering of Prerender events are caught.
11 var hadPrerenderEventErrors
= false;
13 var receivedPrerenderEvents
= {
14 'webkitprerenderstart': [],
15 'webkitprerenderdomcontentloaded': [],
16 'webkitprerenderload': [],
17 'webkitprerenderstop': [],
19 // A list of callbacks to be called on every prerender event. Each callback
20 // returns true if it should never be called again, or false to remain in the
21 // list and be called on future events. These are used to implement
22 // WaitForPrerenderEventCount.
23 var prerenderEventCallbacks
= [];
25 function GetPrerenderEventCount(index
, type
) {
26 return receivedPrerenderEvents
[type
][index
] || 0;
29 function PrerenderEventHandler(index
, ev
) {
31 if (ev
.type
== 'webkitprerenderstart') {
32 // No event may preceed start.
33 if (GetPrerenderEventCount(index
, 'webkitprerenderstart') ||
34 GetPrerenderEventCount(index
, 'webkitprerenderdomcontentloaded') ||
35 GetPrerenderEventCount(index
, 'webkitprerenderload') ||
36 GetPrerenderEventCount(index
, 'webkitprerenderstop')) {
37 hadPrerenderEventErrors
= true;
40 // There may be multiple load or domcontentloaded events, but they must not
41 // come after start and must come before stop. And there may be at most one
42 // start. Note that stop may be delivered without any load events.
43 if (!GetPrerenderEventCount(index
, 'webkitprerenderstart') ||
44 GetPrerenderEventCount(index
, 'webkitprerenderstop')) {
45 hadPrerenderEventErrors
= true;
50 receivedPrerenderEvents
[ev
.type
][index
] =
51 (receivedPrerenderEvents
[ev
.type
][index
] || 0) + 1;
53 // Run all callbacks. Remove the ones that are done.
54 prerenderEventCallbacks
= prerenderEventCallbacks
.filter(function(callback
) {
59 // Calls |callback| when at least |count| instances of event |type| have been
60 // observed for prerender |index|.
61 function WaitForPrerenderEventCount(index
, type
, count
, callback
) {
62 var checkCount = function() {
63 if (GetPrerenderEventCount(index
, type
) >= count
) {
70 prerenderEventCallbacks
.push(checkCount
);
73 function AddEventHandlersToLinkElement(link
, index
) {
74 link
.addEventListener('webkitprerenderstart',
75 PrerenderEventHandler
.bind(null, index
), false);
76 link
.addEventListener('webkitprerenderdomcontentloaded',
77 PrerenderEventHandler
.bind(null, index
), false);
78 link
.addEventListener('webkitprerenderload',
79 PrerenderEventHandler
.bind(null, index
), false);
80 link
.addEventListener('webkitprerenderstop',
81 PrerenderEventHandler
.bind(null, index
), false);
84 function AddPrerender(url
, index
) {
85 var link
= document
.createElement('link');
86 link
.id
= 'prerenderElement' + index
;
87 link
.rel
= 'prerender';
89 AddEventHandlersToLinkElement(link
, index
);
90 document
.body
.appendChild(link
);
94 function RemoveLinkElement(index
) {
95 var link
= document
.getElementById('prerenderElement' + index
);
96 link
.parentElement
.removeChild(link
);
99 function ExtractGetParameterBadlyAndInsecurely(param
, defaultValue
) {
100 var re
= RegExp('[&?]' + param
+ '=([^&?#]*)');
101 var result
= re
.exec(document
.location
);
107 function AddAnchor(href
, target
) {
108 var a
= document
.createElement('a');
112 document
.body
.appendChild(a
);
116 function Click(url
) {
117 AddAnchor(url
).dispatchEvent(new MouseEvent('click', {
125 function ClickTarget(url
) {
126 var eventObject
= new MouseEvent('click', {
132 AddAnchor(url
, '_blank').dispatchEvent(eventObject
);
135 function ClickPing(url
, pingUrl
) {
136 var a
= AddAnchor(url
);
138 a
.dispatchEvent(new MouseEvent('click', {
146 function ShiftClick(url
) {
147 AddAnchor(url
).dispatchEvent(new MouseEvent('click', {
156 function CtrlClick(url
) {
157 AddAnchor(url
).dispatchEvent(new MouseEvent('click', {
166 function CtrlShiftClick(url
) {
167 AddAnchor(url
).dispatchEvent(new MouseEvent('click', {
177 function MetaClick(url
) {
178 AddAnchor(url
).dispatchEvent(new MouseEvent('click', {
187 function MetaShiftClick(url
) {
188 AddAnchor(url
).dispatchEvent(new MouseEvent('click', {
198 function WindowOpen(url
) {