Commit 363fd828 363fd8286f8e66b1d381573f7e4e9a9079d09af6 by Nicolas Perriault

there are two things funny with alzheimer: 1. you always encounter funny situati…

…ons and 2. you always encounter funny situations.
1 parent baafcfe2
1 /*!
2 * Casper is a navigation utility for PhantomJS.
3 *
4 * Documentation: http://casperjs.org/
5 * Repository: http://github.com/n1k0/casperjs
6 *
7 * Copyright (c) 2011-2012 Nicolas Perriault
8 *
9 * Part of source code is Copyright Joyent, Inc. and other Node contributors.
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included
19 * in all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 * DEALINGS IN THE SOFTWARE.
28 *
29 */
30
31 /*global CasperError console exports phantom require*/
32
33 var utils = require('utils');
34 var f = utils.format;
35
36 function create() {
37 "use strict";
38 return new Stack();
39 }
40 exports.create = create;
41
42 /**
43 * Popups container. Implements Array prototype.
44 *
45 */
46 var Stack = function Stack(){};
47 exports.Stack = Stack;
48
49 Stack.prototype = [];
50
51 /**
52 * Cleans the stack from closed popup.
53 *
54 * @param WebPage closed Closed popup page instance
55 * @return Number New stack length
56 */
57 Stack.prototype.clean = function clean(closed) {
58 "use strict";
59 var closedIndex = -1;
60 this.forEach(function(popup, index) {
61 if (closed === popup) {
62 closedIndex = index;
63 }
64 });
65 if (closedIndex > -1) {
66 this.splice(closedIndex, 1);
67 }
68 return this.length;
69 };
70
71 /**
72 * Finds a popup matching the provided information. Information can be:
73 *
74 * - RegExp: matching page url
75 * - String: strict page url value
76 * - WebPage: a direct WebPage instance
77 *
78 * @param Mixed popupInfo
79 * @return WebPage
80 */
81 Stack.prototype.find = function find(popupInfo) {
82 "use strict";
83 var popup, type = utils.betterTypeOf(popupInfo);
84 switch (type) {
85 case "regexp":
86 popup = this.findByRegExp(popupInfo);
87 break;
88 case "string":
89 popup = this.findByURL(popupInfo);
90 break;
91 case "qtruntimeobject": // WebPage
92 popup = popupInfo;
93 if (!utils.isWebPage(popup) || !this.some(function(popupPage) {
94 if (popupInfo.id && popupPage.id) {
95 return popupPage.id === popup.id;
96 }
97 return popupPage.url === popup.url;
98 })) {
99 throw new CasperError("Invalid or missing popup.");
100 }
101 break;
102 default:
103 throw new CasperError(f("Invalid popupInfo type: %s.", type));
104 }
105 return popup;
106 };
107
108 /**
109 * Finds the first popup which url matches a given RegExp.
110 *
111 * @param RegExp regexp
112 * @return WebPage
113 */
114 Stack.prototype.findByRegExp = function findByRegExp(regexp) {
115 "use strict";
116 var popup = this.filter(function(popupPage) {
117 return regexp.test(popupPage.url);
118 })[0];
119 if (!popup) {
120 throw new CasperError(f("Couldn't find popup with url matching pattern %s", regexp));
121 }
122 return popup;
123 };
124
125 /**
126 * Finds the first popup matching a given url.
127 *
128 * @param String url The child WebPage url
129 * @return WebPage
130 */
131 Stack.prototype.findByURL = function findByURL(string) {
132 "use strict";
133 var popup = this.filter(function(popupPage) {
134 return popupPage.url.indexOf(string) !== -1;
135 })[0];
136 if (!popup) {
137 throw new CasperError(f("Couldn't find popup with url containing '%s'", string));
138 }
139 return popup;
140 };
141
142 /**
143 * Returns a human readable list of current active popup urls.
144 *
145 * @return Array Mapped stack.
146 */
147 Stack.prototype.list = function list() {
148 "use strict";
149 return this.map(function(popup) {
150 try {
151 return popup.url;
152 } catch (e) {
153 return '<deleted>';
154 }
155 });
156 };
157
158 /**
159 * String representation of current instance.
160 *
161 * @return String
162 */
163 Stack.prototype.toString = function toString() {
164 "use strict";
165 return f("[Object Stack], having %d popup(s)" % this.length);
166 };