Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
1 /*
2 * Copyright (C) 2004 Baron Schwartz <baron at sequent dot org>
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as published by the
6 * Free Software Foundation, version 2.1.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10 * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
11 * details.
12 */
14 Date.parseFunctions = {count:0};
15 Date.parseRegexes = [];
16 Date.formatFunctions = {count:0};
18 Date.prototype.dateFormat = function(format) {
19 if (Date.formatFunctions[format] == null) {
20 Date.createNewFormat(format);
21 }
22 var func = Date.formatFunctions[format];
23 return this[func]();
24 }
26 Date.createNewFormat = function(format) {
27 var funcName = "format" + Date.formatFunctions.count++;
28 Date.formatFunctions[format] = funcName;
29 var code = "Date.prototype." + funcName + " = function(){return ";
30 var special = false;
31 var ch = '';
32 /* BEGIN LOOP */
33 for (var i = 0; i < format.length; ++i) {
34 ch = format.charAt(i);
35 if (!special && ch == "\\") {
36 special = true;
37 }
38 else if (special) {
39 special = false;
40 code += "'" + String.escape(ch) + "' + ";
41 }
42 else {
43 code += Date.getFormatCode(ch);
44 }
45 }
46 /* END LOOP */
47 eval(code.substring(0, code.length - 3) + ";}");
48 }
50 Date.getFormatCode = function(character) {
51 switch (character) {
52 case "d":
53 return "String.leftPad(this.getDate(), 2, '0') + ";
54 case "D":
55 return "Date.dayNames[this.getDay()].substring(0, 3) + ";
56 case "j":
57 return "this.getDate() + ";
58 case "l":
59 return "Date.dayNames[this.getDay()] + ";
60 case "S":
61 return "this.getSuffix() + ";
62 case "w":
63 return "this.getDay() + ";
64 case "z":
65 return "this.getDayOfYear() + ";
66 case "W":
67 return "this.getWeekOfYear() + ";
68 case "F":
69 return "Date.monthNames[this.getMonth()] + ";
70 case "m":
71 return "String.leftPad(this.getMonth() + 1, 2, '0') + ";
72 case "M":
73 return "Date.monthNames[this.getMonth()].substring(0, 3) + ";
74 case "n":
75 return "(this.getMonth() + 1) + ";
76 case "t":
77 return "this.getDaysInMonth() + ";
78 case "L":
79 return "(this.isLeapYear() ? 1 : 0) + ";
80 case "Y":
81 return "this.getFullYear() + ";
82 case "y":
83 return "('' + this.getFullYear()).substring(2, 4) + ";
84 case "a":
85 return "(this.getHours() < 12 ? 'am' : 'pm') + ";
86 case "A":
87 return "(this.getHours() < 12 ? 'AM' : 'PM') + ";
88 case "g":
89 return "((this.getHours() %12) ? this.getHours() % 12 : 12) + ";
90 case "G":
91 return "this.getHours() + ";
92 case "h":
93 return "String.leftPad((this.getHours() %12) ? this.getHours() % 12 : 12, 2, '0') + ";
94 case "H":
95 return "String.leftPad(this.getHours(), 2, '0') + ";
96 case "i":
97 return "String.leftPad(this.getMinutes(), 2, '0') + ";
98 case "s":
99 return "String.leftPad(this.getSeconds(), 2, '0') + ";
100 case "O":
101 return "this.getGMTOffset() + ";
102 case "T":
103 return "this.getTimezone() + ";
104 case "Z":
105 return "(this.getTimezoneOffset() * -60) + ";
106 default:
107 return "'" + String.escape(character) + "' + ";
108 }
109 }
111 Date.parseDate = function(input, format) {
112 if (Date.parseFunctions[format] == null) {
113 Date.createParser(format);
114 }
115 var func = Date.parseFunctions[format];
116 return Date[func](input);
117 }
119 Date.createParser = function(format) {
120 var funcName = "parse" + Date.parseFunctions.count++;
121 var regexNum = Date.parseRegexes.length;
122 var currentGroup = 1;
123 Date.parseFunctions[format] = funcName;
125 var code = "Date." + funcName + " = function(input){\n"
126 + "var y = -1, m = -1, d = -1, h = -1, i = -1, s = -1;\n"
127 + "var d = new Date();\n"
128 + "y = d.getFullYear();\n"
129 + "m = d.getMonth();\n"
130 + "d = d.getDate();\n"
131 + "var results = input.match(Date.parseRegexes[" + regexNum + "]);\n"
132 + "if (results && results.length > 0) {"
133 var regex = "";
135 var special = false;
136 var ch = '';
137 /* BEGIN LOOP */
138 for (var i = 0; i < format.length; ++i) {
139 ch = format.charAt(i);
140 if (!special && ch == "\\") {
141 special = true;
142 }
143 else if (special) {
144 special = false;
145 regex += String.escape(ch);
146 }
147 else {
148 obj = Date.formatCodeToRegex(ch, currentGroup);
149 currentGroup += obj.g;
150 regex += obj.s;
151 if (obj.g && obj.c) {
152 code += obj.c;
153 }
154 }
155 }
156 /* END LOOP */
158 code += "if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0 && s >= 0)\n"
159 + "{return new Date(y, m, d, h, i, s);}\n"
160 + "else if (y > 0 && m >= 0 && d > 0 && h >= 0 && i >= 0)\n"
161 + "{return new Date(y, m, d, h, i);}\n"
162 + "else if (y > 0 && m >= 0 && d > 0 && h >= 0)\n"
163 + "{return new Date(y, m, d, h);}\n"
164 + "else if (y > 0 && m >= 0 && d > 0)\n"
165 + "{return new Date(y, m, d);}\n"
166 + "else if (y > 0 && m >= 0)\n"
167 + "{return new Date(y, m);}\n"
168 + "else if (y > 0)\n"
169 + "{return new Date(y);}\n"
170 + "}return null;}";
172 Date.parseRegexes[regexNum] = new RegExp("^" + regex + "$");
173 eval(code);
174 }
176 Date.formatCodeToRegex = function(character, currentGroup) {
177 switch (character) {
178 case "D":
179 return {g:0,
180 c:null,
181 s:"(?:Sun|Mon|Tue|Wed|Thu|Fri|Sat)"};
182 case "j":
183 case "d":
184 return {g:1,
185 c:"d = parseInt(results[" + currentGroup + "], 10);\n",
186 s:"(\\d{1,2})"};
187 case "l":
188 return {g:0,
189 c:null,
190 s:"(?:" + Date.dayNames.join("|") + ")"};
191 case "S":
192 return {g:0,
193 c:null,
194 s:"(?:st|nd|rd|th)"};
195 case "w":
196 return {g:0,
197 c:null,
198 s:"\\d"};
199 case "z":
200 return {g:0,
201 c:null,
202 s:"(?:\\d{1,3})"};
203 case "W":
204 return {g:0,
205 c:null,
206 s:"(?:\\d{2})"};
207 case "F":
208 return {g:1,
209 c:"m = parseInt(Date.monthNumbers[results[" + currentGroup + "].substring(0, 3)], 10);\n",
210 s:"(" + Date.monthNames.join("|") + ")"};
211 case "M":
212 return {g:1,
213 c:"m = parseInt(Date.monthNumbers[results[" + currentGroup + "]], 10);\n",
214 s:"(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)"};
215 case "n":
216 case "m":
217 return {g:1,
218 c:"m = parseInt(results[" + currentGroup + "], 10) - 1;\n",
219 s:"(\\d{1,2})"};
220 case "t":
221 return {g:0,
222 c:null,
223 s:"\\d{1,2}"};
224 case "L":
225 return {g:0,
226 c:null,
227 s:"(?:1|0)"};
228 case "Y":
229 return {g:1,
230 c:"y = parseInt(results[" + currentGroup + "], 10);\n",
231 s:"(\\d{4})"};
232 case "y":
233 return {g:1,
234 c:"var ty = parseInt(results[" + currentGroup + "], 10);\n"
235 + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n",
236 s:"(\\d{1,2})"};
237 case "a":
238 return {g:1,
239 c:"if (results[" + currentGroup + "] == 'am') {\n"
240 + "if (h == 12) { h = 0; }\n"
241 + "} else { if (h < 12) { h += 12; }}",
242 s:"(am|pm)"};
243 case "A":
244 return {g:1,
245 c:"if (results[" + currentGroup + "] == 'AM') {\n"
246 + "if (h == 12) { h = 0; }\n"
247 + "} else { if (h < 12) { h += 12; }}",
248 s:"(AM|PM)"};
249 case "g":
250 case "G":
251 case "h":
252 case "H":
253 return {g:1,
254 c:"h = parseInt(results[" + currentGroup + "], 10);\n",
255 s:"(\\d{1,2})"};
256 case "i":
257 return {g:1,
258 c:"i = parseInt(results[" + currentGroup + "], 10);\n",
259 s:"(\\d{2})"};
260 case "s":
261 return {g:1,
262 c:"s = parseInt(results[" + currentGroup + "], 10);\n",
263 s:"(\\d{2})"};
264 case "O":
265 return {g:0,
266 c:null,
267 s:"[+-]\\d{4}"};
268 case "T":
269 return {g:0,
270 c:null,
271 s:"[A-Z]{3}"};
272 case "Z":
273 return {g:0,
274 c:null,
275 s:"[+-]\\d{1,5}"};
276 default:
277 return {g:0,
278 c:null,
279 s:String.escape(character)};
280 }
281 }
283 Date.prototype.getTimezone = function() {
284 return this.toString().replace(
285 /^.*? ([A-Z]{3}) [0-9]{4}.*$/, "$1").replace(
286 /^.*?\(([A-Z])[a-z]+ ([A-Z])[a-z]+ ([A-Z])[a-z]+\)$/, "$1$2$3");
287 }
289 Date.prototype.getGMTOffset = function() {
290 return (this.getTimezoneOffset() > 0 ? "-" : "+")
291 + String.leftPad(Math.floor(this.getTimezoneOffset() / 60), 2, "0")
292 + String.leftPad(this.getTimezoneOffset() % 60, 2, "0");
293 }
295 Date.prototype.getDayOfYear = function() {
296 var num = 0;
297 Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28;
298 /* BEGIN LOOP */
299 for (var i = 0; i < this.getMonth(); ++i) {
300 num += Date.daysInMonth[i];
301 }
302 /* END LOOP */
303 return num + this.getDate() - 1;
304 }
306 Date.prototype.getWeekOfYear = function() {
307 // Skip to Thursday of this week
308 var now = this.getDayOfYear() + (4 - this.getDay());
309 // Find the first Thursday of the year
310 var jan1 = new Date(this.getFullYear(), 0, 1);
311 var then = (7 - jan1.getDay() + 4);
312 document.write(then);
313 return String.leftPad(((now - then) / 7) + 1, 2, "0");
314 }
316 Date.prototype.isLeapYear = function() {
317 var year = this.getFullYear();
318 return ((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)));
319 }
321 Date.prototype.getFirstDayOfMonth = function() {
322 var day = (this.getDay() - (this.getDate() - 1)) % 7;
323 return (day < 0) ? (day + 7) : day;
324 }
326 Date.prototype.getLastDayOfMonth = function() {
327 var day = (this.getDay() + (Date.daysInMonth[this.getMonth()] - this.getDate())) % 7;
328 return (day < 0) ? (day + 7) : day;
329 }
331 Date.prototype.getDaysInMonth = function() {
332 Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28;
333 return Date.daysInMonth[this.getMonth()];
334 }
336 Date.prototype.getSuffix = function() {
337 switch (this.getDate()) {
338 case 1:
339 case 21:
340 case 31:
341 return "st";
342 case 2:
343 case 22:
344 return "nd";
345 case 3:
346 case 23:
347 return "rd";
348 default:
349 return "th";
350 }
351 }
353 String.escape = function(string) {
354 return string.replace(/('|\\)/g, "\\$1");
355 }
357 String.leftPad = function (val, size, ch) {
358 var result = new String(val);
359 if (ch == null) {
360 ch = " ";
361 }
362 /* BEGIN LOOP */
363 while (result.length < size) {
364 result = ch + result;
365 }
366 /* END LOOP */
367 return result;
368 }
370 Date.daysInMonth = [31,28,31,30,31,30,31,31,30,31,30,31];
371 Date.monthNames =
372 ["January",
373 "February",
374 "March",
375 "April",
376 "May",
377 "June",
378 "July",
379 "August",
380 "September",
381 "October",
382 "November",
383 "December"];
384 Date.dayNames =
385 ["Sunday",
386 "Monday",
387 "Tuesday",
388 "Wednesday",
389 "Thursday",
390 "Friday",
391 "Saturday"];
392 Date.y2kYear = 50;
393 Date.monthNumbers = {
394 Jan:0,
395 Feb:1,
396 Mar:2,
397 Apr:3,
398 May:4,
399 Jun:5,
400 Jul:6,
401 Aug:7,
402 Sep:8,
403 Oct:9,
404 Nov:10,
405 Dec:11};
406 Date.patterns = {
407 ISO8601LongPattern:"Y-m-d H:i:s",
408 ISO8601ShortPattern:"Y-m-d",
409 ShortDatePattern: "n/j/Y",
410 LongDatePattern: "l, F d, Y",
411 FullDateTimePattern: "l, F d, Y g:i:s A",
412 MonthDayPattern: "F d",
413 ShortTimePattern: "g:i A",
414 LongTimePattern: "g:i:s A",
415 SortableDateTimePattern: "Y-m-d\\TH:i:s",
416 UniversalSortableDateTimePattern: "Y-m-d H:i:sO",
417 YearMonthPattern: "F, Y"};
419 var date = new Date("1/1/2007 1:11:11");
421 /* BEGIN LOOP */
422 for (i = 0; i < 4000; ++i) {
423 var shortFormat = date.dateFormat("Y-m-d");
424 var longFormat = date.dateFormat("l, F d, Y g:i:s A");
425 date.setTime(date.getTime() + 84266956);
426 }
427 /* END LOOP */