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) {