evercookie 0.0.6 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.rdoc +17 -7
- data/app/assets/javascripts/evercookie/evercookie.js.erb +1034 -644
- data/config/routes.rb +2 -0
- data/lib/evercookie.rb +5 -0
- data/lib/evercookie/controller.rb +19 -1
- data/lib/evercookie/version.rb +1 -1
- data/test/dummy/config/environments/production.rb +2 -2
- data/test/dummy/config/initializers/evercookie.rb +6 -6
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/production.sqlite3 +0 -0
- data/test/dummy/log/development.log +7509 -27817
- data/test/dummy/log/production.log +869 -0
- data/test/dummy/log/test.log +876 -936
- data/test/dummy/tmp/cache/assets/{D45/3C0/sprockets%2Fd45fb0f5f994f0c125db5e026ee65258 → CA6/C50/sprockets%2F1ff1b670b38042f5c89026631c36fa33} +0 -0
- data/test/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
- data/test/dummy/tmp/cache/assets/CE7/B90/sprockets%2F09c6831dd77d079a5a778b0d0744ee16 +0 -0
- data/test/dummy/tmp/cache/assets/CEC/FA0/sprockets%2Fcee8c6b09c33d2b276753e959712724e +0 -0
- data/test/dummy/tmp/cache/assets/D04/370/sprockets%2F0bfdc3134b37668ae9a63c753ef05021 +0 -0
- data/test/dummy/tmp/cache/assets/D19/B00/sprockets%2F28c67ae04b83f4f76d461c789d1236ad +0 -0
- data/test/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/test/dummy/tmp/cache/assets/D45/590/sprockets%2F3e0f6f496cd38bd4ea06614f7e10399a +0 -0
- data/test/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/test/dummy/tmp/cache/assets/D58/BF0/sprockets%2Fd2d743676d256ff903f78df59b43c7ec +0 -0
- data/test/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/test/dummy/tmp/cache/assets/D70/2D0/sprockets%2F2c853768baf811357d81d41bdfd05dcf +0 -0
- data/test/dummy/tmp/cache/assets/D84/180/sprockets%2F71efedfb555fe6a74750e5d579d363d5 +0 -0
- data/test/dummy/tmp/cache/assets/D8C/A10/sprockets%2Ffc7201c6cbef32453aa4175c520c8eae +0 -0
- data/test/dummy/tmp/cache/assets/D93/360/sprockets%2Fdf600f50f002512c95d93bcfbab891ed +0 -0
- data/test/dummy/tmp/cache/assets/DB2/E70/sprockets%2Fa25c858be7f39b1ce6854eb93ba77ef5 +0 -0
- data/test/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/test/dummy/tmp/cache/assets/{D70/D10/sprockets%2Fa0d37ff489ed0857f72233f5cb0b9c0b → DDF/EE0/sprockets%2F0b91ee26fcc3a08f74edf9ade38787e4} +0 -0
- data/test/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/test/dummy4/config/initializers/evercookie.rb +6 -6
- data/test/dummy4/db/development.sqlite3 +0 -0
- data/test/dummy4/log/development.log +773 -0
- data/test/dummy4/log/production.log +0 -0
- data/test/dummy4/tmp/cache/assets/development/sprockets/09c6831dd77d079a5a778b0d0744ee16 +0 -0
- data/test/dummy4/tmp/cache/assets/development/sprockets/0b91ee26fcc3a08f74edf9ade38787e4 +0 -0
- data/test/dummy4/tmp/cache/assets/development/sprockets/0bfdc3134b37668ae9a63c753ef05021 +0 -0
- data/test/dummy4/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/test/dummy4/tmp/cache/assets/development/sprockets/1ff1b670b38042f5c89026631c36fa33 +0 -0
- data/test/dummy4/tmp/cache/assets/development/sprockets/28c67ae04b83f4f76d461c789d1236ad +0 -0
- data/test/dummy4/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/test/dummy4/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/test/dummy4/tmp/cache/assets/development/sprockets/3e0f6f496cd38bd4ea06614f7e10399a +0 -0
- data/test/dummy4/tmp/cache/assets/development/sprockets/4b02b6e6070ec4638e7c6a9f9ecff6fb +0 -0
- data/test/dummy4/tmp/cache/assets/development/sprockets/6a810a0412e578254a540397a7b70f08 +0 -0
- data/test/dummy4/tmp/cache/assets/development/sprockets/71efedfb555fe6a74750e5d579d363d5 +0 -0
- data/test/dummy4/tmp/cache/assets/development/sprockets/772e790ccea45e8e96ee6d22061276f6 +0 -0
- data/test/dummy4/tmp/cache/assets/development/sprockets/7a52bc6747db430cf502b4bed0fa298d +0 -0
- data/test/dummy4/tmp/cache/assets/development/sprockets/83b76c8a28ae96c73c3cdc3df9887735 +0 -0
- data/test/dummy4/tmp/cache/assets/development/sprockets/84c8f54298cdbbdd246e0f9bd5f26ebc +0 -0
- data/test/dummy4/tmp/cache/assets/development/sprockets/8926b7221463ce523a79e492b466d9e2 +0 -0
- data/test/dummy4/tmp/cache/assets/development/sprockets/9f45c7d10a3f607b80476e3f791501bd +0 -0
- data/test/dummy4/tmp/cache/assets/development/sprockets/a25c858be7f39b1ce6854eb93ba77ef5 +0 -0
- data/test/dummy4/tmp/cache/assets/development/sprockets/a2c2ae4f525146e108d2be380ca73570 +0 -0
- data/test/dummy4/tmp/cache/assets/development/sprockets/bb7f0179d91d1103a39cf20660a9f092 +0 -0
- data/test/dummy4/tmp/cache/assets/development/sprockets/cbec6d2b8af02ca399bf300772f22560 +0 -0
- data/test/dummy4/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/test/dummy4/tmp/cache/assets/development/sprockets/d2d743676d256ff903f78df59b43c7ec +0 -0
- data/test/dummy4/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/test/dummy4/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/test/dummy4/tmp/cache/assets/production/sprockets/09c6831dd77d079a5a778b0d0744ee16 +0 -0
- data/test/dummy4/tmp/cache/assets/production/sprockets/0b91ee26fcc3a08f74edf9ade38787e4 +0 -0
- data/test/dummy4/tmp/cache/assets/production/sprockets/0bfdc3134b37668ae9a63c753ef05021 +0 -0
- data/test/dummy4/tmp/cache/assets/production/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/test/dummy4/tmp/cache/assets/production/sprockets/1ff1b670b38042f5c89026631c36fa33 +0 -0
- data/test/dummy4/tmp/cache/assets/production/sprockets/28c67ae04b83f4f76d461c789d1236ad +0 -0
- data/test/dummy4/tmp/cache/assets/production/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/test/dummy4/tmp/cache/assets/production/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/test/dummy4/tmp/cache/assets/production/sprockets/3e0f6f496cd38bd4ea06614f7e10399a +0 -0
- data/test/dummy4/tmp/cache/assets/production/sprockets/71efedfb555fe6a74750e5d579d363d5 +0 -0
- data/test/dummy4/tmp/cache/assets/production/sprockets/7a52bc6747db430cf502b4bed0fa298d +0 -0
- data/test/dummy4/tmp/cache/assets/production/sprockets/83b76c8a28ae96c73c3cdc3df9887735 +0 -0
- data/test/dummy4/tmp/cache/assets/production/sprockets/84c8f54298cdbbdd246e0f9bd5f26ebc +0 -0
- data/test/dummy4/tmp/cache/assets/production/sprockets/9f45c7d10a3f607b80476e3f791501bd +0 -0
- data/test/dummy4/tmp/cache/assets/production/sprockets/a25c858be7f39b1ce6854eb93ba77ef5 +0 -0
- data/test/dummy4/tmp/cache/assets/production/sprockets/a2c2ae4f525146e108d2be380ca73570 +0 -0
- data/test/dummy4/tmp/cache/assets/production/sprockets/cbec6d2b8af02ca399bf300772f22560 +0 -0
- data/test/dummy4/tmp/cache/assets/production/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/test/dummy4/tmp/cache/assets/production/sprockets/d2d743676d256ff903f78df59b43c7ec +0 -0
- data/test/dummy4/tmp/cache/assets/production/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/test/dummy4/tmp/cache/assets/production/sprockets/d7d5b37686831d37c4dd75e645f5e016 +0 -0
- data/test/dummy4/tmp/cache/assets/production/sprockets/de2fd9fd11c04a582cdbbe3d84a35ae6 +0 -0
- data/test/dummy4/tmp/cache/assets/production/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- metadata +291 -199
- data/test/dummy/tmp/cache/assets/D2F/760/sprockets%2F3b464ead21d28d0a1298357a3a7cbc18 +0 -0
- data/test/dummy/tmp/cache/assets/D45/C10/sprockets%2Fac34f7046872aba24b7375de608d8fe6 +0 -0
- data/test/dummy/tmp/cache/assets/D99/2F0/sprockets%2Fa2cf2651c63ecb32c21ea94fa84cd498 +0 -0
- data/test/dummy/tmp/cache/assets/DAA/C00/sprockets%2F9bddc9410e086be5f5efa982c5247c7b +0 -0
- data/test/dummy/tmp/cache/assets/DCF/EC0/sprockets%2Fe1f34cd8fd7ca6a9a01d26e47c923f1f +0 -0
- data/test/dummy/tmp/cache/assets/DEE/200/sprockets%2F2a3f3abddecb0467eb2d7d5cf5f52302 +0 -0
- data/test/dummy/tmp/cache/assets/DFF/960/sprockets%2Fe73aa53de71d957ef04bdfd2fba2e915 +0 -0
- data/test/dummy/tmp/cache/assets/E83/750/sprockets%2Fe0a4c2b9c4acf9bcfedbb42a8bd45e80 +0 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 235391144b34efd7ec9c96864bba5c491e5c265e
|
|
4
|
+
data.tar.gz: 29a256ede19d32ac91056b5cbbd54d6be69e70ba
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: d323fbcb0ccc533ae2fca746ad6a7967b9e188456261170d7139a43c010275a12372bbb584cf58f59f0f5cb8025a45b9f6d252a9ed85e7a7171473a959b4ee4a
|
|
7
|
+
data.tar.gz: e3f9a4f3f40baafb4931116f9551daf12d346cb247c3c7f178cfd99d4ff46276e67d8758d10befba005b619fc6edbfb56da84915e571adf32dec3cc8cb92b4ef
|
data/README.rdoc
CHANGED
|
@@ -10,18 +10,21 @@ Please note, that evercookie can't be fully reliable for detecting previous visi
|
|
|
10
10
|
|
|
11
11
|
As written on original javascript {site}[http://samy.pl/evercookie/], when creating a new cookie, it uses the following storage mechanisms when available:
|
|
12
12
|
* Standard {HTTP Cookies}[http://en.wikipedia.org/wiki/HTTP_cookie]
|
|
13
|
-
* {Local Shared Objects}[http://en.wikipedia.org/wiki/Local_Shared_Object] (Flash Cookies)
|
|
14
|
-
* {Isolated Storage}[http://www.silverlight.net/learn/quickstarts/isolatedstorage/]
|
|
15
|
-
*
|
|
16
|
-
* Storing cookies in and reading out {Web History}[http://samy.pl/csshack/] (removed in gem)
|
|
13
|
+
* Flash {Local Shared Objects}[http://en.wikipedia.org/wiki/Local_Shared_Object] (Flash Cookies)
|
|
14
|
+
* Silverlight {Isolated Storage}[http://www.silverlight.net/learn/quickstarts/isolatedstorage/] (disabled in gem, due to possible issues with different browsers)
|
|
15
|
+
* CSS {History Knocking}[http://samy.pl/csshack/] (turned off in gem due to network intensiveness)
|
|
17
16
|
* Storing cookies in HTTP {ETags}[http://en.wikipedia.org/wiki/HTTP_ETag]
|
|
18
17
|
* Storing cookies in {Web cache}[http://en.wikipedia.org/wiki/Web_cache]
|
|
19
18
|
* {window.name}[http://en.wikipedia.org/wiki/HTTP_cookie=window.name] caching
|
|
20
|
-
* Internet Explorer {userData}[http://msdn.microsoft.com/en-us/library/ms531424(VS.85).aspx]
|
|
19
|
+
* Internet Explorer {userData storage}[http://msdn.microsoft.com/en-us/library/ms531424(VS.85).aspx]
|
|
20
|
+
* HTML5 Canvas - Cookie values stored in RGB data of auto-generated, force-cached PNG images
|
|
21
21
|
* HTML5 {Session Storage}[http://dev.w3.org/html5/webstorage/=the-sessionstorage-attribute]
|
|
22
22
|
* HTML5 {Local Storage}[http://dev.w3.org/html5/webstorage/=dom-localstorage]
|
|
23
23
|
* HTML5 {Global Storage}[https://developer.mozilla.org/en/dom/storage=globalStorage]
|
|
24
24
|
* HTML5 {Database Storage}[http://dev.w3.org/html5/webdatabase] via SQLite
|
|
25
|
+
* HTML5 {IndexedDB}[http://www.w3.org/TR/IndexedDB/]
|
|
26
|
+
* Java {JNLP PersistenceService}[http://docs.oracle.com/javase/1.5.0/docs/guide/javaws/jnlp/index.html] (disabled in gem due to possible user permission request)
|
|
27
|
+
* Java exploit {CVE-2013-0422}[https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-0422] - Attempts to escape the applet sandbox and write cookie data directly to the user's hard drive. (disabled in gem due to possible user permission request)
|
|
25
28
|
|
|
26
29
|
== Information
|
|
27
30
|
|
|
@@ -41,7 +44,7 @@ You can see an example of evercookie working in test/dummy application of this g
|
|
|
41
44
|
|
|
42
45
|
== Getting started
|
|
43
46
|
|
|
44
|
-
Evercookie works was written and tested on Rails 3.2. You can add in to your Gemfile with:
|
|
47
|
+
Evercookie works was written and tested on Rails 3.2/4. You can add in to your Gemfile with:
|
|
45
48
|
|
|
46
49
|
gem 'evercookie'
|
|
47
50
|
|
|
@@ -114,4 +117,11 @@ You can create the initializer for evercookie gem in your Rails application init
|
|
|
114
117
|
|
|
115
118
|
# cookie name for etag storage
|
|
116
119
|
config.cookie_etag = :evercookie_etag
|
|
117
|
-
end
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
=== Hiding evercookie presence in your application
|
|
123
|
+
|
|
124
|
+
If you really want to hide that you are using evercookie you should do several things (as I see it):
|
|
125
|
+
* precompile assets with compression enabled, it will remove all comments and will change some variables of evercookie JS class
|
|
126
|
+
* configure the gem to use paths that don't have 'evercookie' name in them
|
|
127
|
+
* but remember, if someone wants to find presence of evercookie, he will
|
|
@@ -1,704 +1,1094 @@
|
|
|
1
|
+
/*jslint browser: true, nomen: false, plusplus: false, bitwise: false, maxerr: 50, indent: 2 */
|
|
1
2
|
/*
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
var ec = new <%= Evercookie.js_class %>();
|
|
4
|
+
|
|
5
|
+
// set a cookie "id" to "12345"
|
|
6
|
+
// usage: ec.set(key, value)
|
|
7
|
+
ec.set("id", "12345");
|
|
8
|
+
|
|
9
|
+
// retrieve a cookie called "id" (simply)
|
|
10
|
+
ec.get("id", function(value) { alert("Cookie value is " + value) });
|
|
11
|
+
|
|
12
|
+
// or use a more advanced callback function for getting our cookie
|
|
13
|
+
// the cookie value is the first param
|
|
14
|
+
// an object containing the different storage methods
|
|
15
|
+
// and returned cookie values is the second parameter
|
|
16
|
+
function getCookie(best_candidate, all_candidates)
|
|
17
|
+
{
|
|
18
|
+
alert("The retrieved cookie is: " + best_candidate + "\n" +
|
|
19
|
+
"You can see what each storage mechanism returned " +
|
|
20
|
+
"by looping through the all_candidates object.");
|
|
21
|
+
|
|
22
|
+
for (var item in all_candidates)
|
|
23
|
+
document.write("Storage mechanism " + item +
|
|
24
|
+
" returned " + all_candidates[item] + " votes<br>");
|
|
25
|
+
}
|
|
26
|
+
ec.get("id", getCookie);
|
|
7
27
|
*/
|
|
8
|
-
|
|
9
|
-
function
|
|
28
|
+
try{
|
|
29
|
+
(function (window) {
|
|
30
|
+
'use strict';
|
|
31
|
+
var document = window.document,
|
|
32
|
+
Image = window.Image,
|
|
33
|
+
globalStorage = window.globalStorage,
|
|
34
|
+
swfobject = window.swfobject;
|
|
35
|
+
|
|
36
|
+
try{
|
|
37
|
+
var localStore = window.localStorage
|
|
38
|
+
}catch(ex){}
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
var sessionStorage = window.sessionStorage;
|
|
42
|
+
} catch (e) { }
|
|
43
|
+
|
|
44
|
+
function newImage(src) {
|
|
45
|
+
var img = new Image();
|
|
46
|
+
img.style.visibility = "hidden";
|
|
47
|
+
img.style.position = "absolute";
|
|
48
|
+
img.src = src;
|
|
49
|
+
}
|
|
50
|
+
function _ec_replace(str, key, value) {
|
|
10
51
|
if (str.indexOf("&" + key + "=") > -1 || str.indexOf(key + "=") === 0) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
52
|
+
// find start
|
|
53
|
+
var idx = str.indexOf("&" + key + "="),
|
|
54
|
+
end, newstr;
|
|
55
|
+
if (idx === -1) {
|
|
56
|
+
idx = str.indexOf(key + "=");
|
|
57
|
+
}
|
|
58
|
+
// find end
|
|
59
|
+
end = str.indexOf("&", idx + 1);
|
|
60
|
+
if (end !== -1) {
|
|
61
|
+
newstr = str.substr(0, idx) + str.substr(end + (idx ? 0 : 1)) + "&" + key + "=" + value;
|
|
62
|
+
} else {
|
|
63
|
+
newstr = str.substr(0, idx) + "&" + key + "=" + value;
|
|
64
|
+
}
|
|
65
|
+
return newstr;
|
|
25
66
|
} else {
|
|
26
|
-
|
|
67
|
+
return str + "&" + key + "=" + value;
|
|
27
68
|
}
|
|
28
|
-
}
|
|
69
|
+
}
|
|
29
70
|
|
|
71
|
+
function idb() {
|
|
72
|
+
if ('indexedDB' in window) {
|
|
73
|
+
return true
|
|
74
|
+
} else if (window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB) {
|
|
75
|
+
return true
|
|
76
|
+
} else {
|
|
77
|
+
return false
|
|
78
|
+
}
|
|
79
|
+
}
|
|
30
80
|
|
|
31
|
-
// necessary for flash to communicate with js...
|
|
32
|
-
// please implement a better way
|
|
33
|
-
var _global_lso;
|
|
34
|
-
function
|
|
81
|
+
// necessary for flash to communicate with js...
|
|
82
|
+
// please implement a better way
|
|
83
|
+
var _global_lso;
|
|
84
|
+
function _<%= Evercookie.js_class %>_flash_var(cookie) {
|
|
35
85
|
_global_lso = cookie;
|
|
36
86
|
|
|
37
87
|
// remove the flash object now
|
|
38
88
|
var swf = document.getElementById("myswf");
|
|
39
89
|
if (swf && swf.parentNode) {
|
|
40
|
-
|
|
90
|
+
swf.parentNode.removeChild(swf);
|
|
41
91
|
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/*
|
|
95
|
+
* Again, ugly workaround....same problem as flash.
|
|
96
|
+
*/
|
|
97
|
+
var _global_isolated;
|
|
98
|
+
function onSilverlightLoad(sender, args) {
|
|
99
|
+
var control = sender.getHost();
|
|
100
|
+
_global_isolated = control.Content.App.getIsolatedStorage();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function onSilverlightError(sender, args) {
|
|
104
|
+
_global_isolated = "";
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
var defaultOptionMap = {
|
|
108
|
+
history: false, // CSS history knocking or not .. can be network intensive
|
|
109
|
+
java: false, // Java applet on/off... may prompt users for permission to run.
|
|
110
|
+
tests: 3, //1000 what is it, actually?
|
|
111
|
+
baseurl: '', // base url for php, flash and silverlight assets
|
|
112
|
+
silverlight: false, // you might want to turn it off https://github.com/samyk/evercookie/issues/45
|
|
113
|
+
domain: '.' + window.location.host.replace(/:\d+/, ''), // Get current domain
|
|
114
|
+
authPath: '<%= Evercookie.get_auth_path %>', // set to false to disable Basic Authentication cache
|
|
115
|
+
pngCookieName: '<%= Evercookie.cookie_png %>',
|
|
116
|
+
pngPath: '<%= Evercookie.get_png_path %>',
|
|
117
|
+
etagCookieName: '<%= Evercookie.cookie_etag %>',
|
|
118
|
+
etagPath: '<%= Evercookie.get_etag_path %>',
|
|
119
|
+
cacheCookieName: '<%= Evercookie.cookie_cache %>',
|
|
120
|
+
cachePath: '<%= Evercookie.get_cache_path %>'
|
|
121
|
+
};
|
|
122
|
+
var _baseKeyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
|
123
|
+
/**
|
|
124
|
+
* @class Evercookie
|
|
125
|
+
* @param {Object} options
|
|
126
|
+
* @param {Boolean} options.history CSS history knocking or not .. can be network intensive
|
|
127
|
+
* @param {Boolean} options.java Java applet on/off... may prompt users for permission to run.
|
|
128
|
+
* @param {Boolean} options.silverlight you might want to turn it off https://github.com/samyk/evercookie/issues/45
|
|
129
|
+
* @param {Number} options.tests
|
|
130
|
+
* @param {String} options.baseurl base url for php, flash and silverlight assets
|
|
131
|
+
* @param {String|Function} options.domain as a string, domain for cookie, as a function, accept window object and return domain string
|
|
132
|
+
* @param {String} options.pngCookieName
|
|
133
|
+
* @param {String} options.pngPath
|
|
134
|
+
* @param {String} options.etagCookieName:
|
|
135
|
+
* @param {String} options.etagPath
|
|
136
|
+
* @param {String} options.cacheCookieName
|
|
137
|
+
* @param {String} options.cachePath
|
|
138
|
+
*/
|
|
139
|
+
function <%= Evercookie.js_class %>(options) {
|
|
140
|
+
options = options || {};
|
|
141
|
+
var opts = {};
|
|
142
|
+
for (var key in defaultOptionMap) {
|
|
143
|
+
var optValue = options[key];
|
|
144
|
+
if(typeof optValue !== 'undefined') {
|
|
145
|
+
opts[key] = optValue
|
|
146
|
+
} else {
|
|
147
|
+
opts[key] = defaultOptionMap[key];
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if(typeof opts.domain === 'function'){
|
|
151
|
+
opts.domain = opts.domain(window);
|
|
152
|
+
}
|
|
153
|
+
var _ec_history = opts.history,
|
|
154
|
+
_ec_java = opts.java,
|
|
155
|
+
_ec_tests = opts.tests,
|
|
156
|
+
_ec_baseurl = opts.baseurl,
|
|
157
|
+
_ec_domain = opts.domain;
|
|
158
|
+
|
|
159
|
+
// private property
|
|
160
|
+
var self = this;
|
|
161
|
+
this._ec = {};
|
|
162
|
+
|
|
163
|
+
this.get = function (name, cb, dont_reset) {
|
|
164
|
+
self._<%= Evercookie.js_class %>(name, cb, undefined, undefined, dont_reset);
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
this.set = function (name, value) {
|
|
168
|
+
self._<%= Evercookie.js_class %>(name, function () {}, value);
|
|
169
|
+
};
|
|
170
|
+
|
|
171
|
+
this._<%= Evercookie.js_class %> = function (name, cb, value, i, dont_reset) {
|
|
172
|
+
if (self._<%= Evercookie.js_class %> === undefined) {
|
|
173
|
+
self = this;
|
|
174
|
+
}
|
|
175
|
+
if (i === undefined) {
|
|
176
|
+
i = 0;
|
|
177
|
+
}
|
|
178
|
+
// first run
|
|
179
|
+
if (i === 0) {
|
|
180
|
+
self.<%= Evercookie.js_class %>_database_storage(name, value);
|
|
181
|
+
self.<%= Evercookie.js_class %>_png(name, value);
|
|
182
|
+
self.<%= Evercookie.js_class %>_etag(name, value);
|
|
183
|
+
self.<%= Evercookie.js_class %>_cache(name, value);
|
|
184
|
+
self.<%= Evercookie.js_class %>_lso(name, value);
|
|
185
|
+
if (opts.silverlight) {
|
|
186
|
+
self.<%= Evercookie.js_class %>_silverlight(name, value);
|
|
187
|
+
}
|
|
188
|
+
if (opts.authPath) {
|
|
189
|
+
self.<%= Evercookie.js_class %>_auth(name, value);
|
|
190
|
+
}
|
|
191
|
+
if (_ec_java) {
|
|
192
|
+
self.<%= Evercookie.js_class %>_java(name, value);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
self._ec.userData = self.<%= Evercookie.js_class %>_userdata(name, value);
|
|
196
|
+
self._ec.cookieData = self.<%= Evercookie.js_class %>_cookie(name, value);
|
|
197
|
+
self._ec.localData = self.<%= Evercookie.js_class %>_local_storage(name, value);
|
|
198
|
+
self._ec.globalData = self.<%= Evercookie.js_class %>_global_storage(name, value);
|
|
199
|
+
self._ec.sessionData = self.<%= Evercookie.js_class %>_session_storage(name, value);
|
|
200
|
+
self._ec.windowData = self.<%= Evercookie.js_class %>_window(name, value);
|
|
201
|
+
|
|
202
|
+
if (_ec_history) {
|
|
203
|
+
self._ec.historyData = self.<%= Evercookie.js_class %>_history(name, value);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// when writing data, we need to make sure lso and silverlight object is there
|
|
208
|
+
if (value !== undefined) {
|
|
209
|
+
if ((typeof _global_lso === "undefined" ||
|
|
210
|
+
typeof _global_isolated === "undefined") &&
|
|
211
|
+
i++ < _ec_tests) {
|
|
212
|
+
setTimeout(function () {
|
|
213
|
+
self._<%= Evercookie.js_class %>(name, cb, value, i, dont_reset);
|
|
214
|
+
}, 200);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// when reading data, we need to wait for swf, db, silverlight, java and png
|
|
219
|
+
else
|
|
220
|
+
{
|
|
221
|
+
if (
|
|
222
|
+
(
|
|
223
|
+
// we support local db and haven't read data in yet
|
|
224
|
+
(window.openDatabase && typeof self._ec.dbData === "undefined") ||
|
|
225
|
+
(idb() && (typeof self._ec.idbData === "undefined" || self._ec.idbData === "")) ||
|
|
226
|
+
(typeof _global_lso === "undefined") ||
|
|
227
|
+
(typeof self._ec.etagData === "undefined") ||
|
|
228
|
+
(typeof self._ec.cacheData === "undefined") ||
|
|
229
|
+
(typeof self._ec.javaData === "undefined") ||
|
|
230
|
+
(document.createElement("canvas").getContext && (typeof self._ec.pngData === "undefined" || self._ec.pngData === "")) ||
|
|
231
|
+
(typeof _global_isolated === "undefined")
|
|
232
|
+
) &&
|
|
233
|
+
i++ < _ec_tests
|
|
234
|
+
)
|
|
235
|
+
{
|
|
236
|
+
setTimeout(function () {
|
|
237
|
+
self._<%= Evercookie.js_class %>(name, cb, value, i, dont_reset);
|
|
238
|
+
}, 200);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// we hit our max wait time or got all our data
|
|
242
|
+
else
|
|
243
|
+
{
|
|
244
|
+
// get just the piece of data we need from swf
|
|
245
|
+
self._ec.lsoData = self.getFromStr(name, _global_lso);
|
|
246
|
+
_global_lso = undefined;
|
|
247
|
+
|
|
248
|
+
// get just the piece of data we need from silverlight
|
|
249
|
+
self._ec.slData = self.getFromStr(name, _global_isolated);
|
|
250
|
+
_global_isolated = undefined;
|
|
251
|
+
|
|
252
|
+
var tmpec = self._ec,
|
|
253
|
+
candidates = [],
|
|
254
|
+
bestnum = 0,
|
|
255
|
+
candidate,
|
|
256
|
+
item;
|
|
257
|
+
self._ec = {};
|
|
258
|
+
|
|
259
|
+
// figure out which is the best candidate
|
|
260
|
+
for (item in tmpec) {
|
|
261
|
+
if (tmpec[item] && tmpec[item] !== "null" && tmpec[item] !== "undefined") {
|
|
262
|
+
candidates[tmpec[item]] = candidates[tmpec[item]] === undefined ? 1 : candidates[tmpec[item]] + 1;
|
|
90
263
|
}
|
|
264
|
+
}
|
|
91
265
|
|
|
92
|
-
|
|
93
|
-
if (
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
self._<%= Evercookie.js_class %>(name, cb, value, i, dont_reset);
|
|
97
|
-
}, 100);
|
|
98
|
-
}
|
|
266
|
+
for (item in candidates) {
|
|
267
|
+
if (candidates[item] > bestnum) {
|
|
268
|
+
bestnum = candidates[item];
|
|
269
|
+
candidate = item;
|
|
99
270
|
}
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// reset cookie everywhere
|
|
274
|
+
if (candidate !== undefined && (dont_reset === undefined || dont_reset !== 1)) {
|
|
275
|
+
self.set(name, candidate);
|
|
276
|
+
}
|
|
277
|
+
if (typeof cb === "function") {
|
|
278
|
+
cb(candidate, tmpec);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
self.ajax({
|
|
282
|
+
url: "<%= Evercookie.get_save_path %>?name=" + name,
|
|
283
|
+
success: function (data) { }
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
};
|
|
100
288
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
(typeof self._ec.cacheData === "undefined") ||
|
|
111
|
-
(document.createElement("canvas").getContext && (typeof self._ec.pngData === "undefined" || self._ec.pngData === ""))
|
|
112
|
-
) &&
|
|
113
|
-
i++ < _ec_tests
|
|
114
|
-
)
|
|
115
|
-
{
|
|
116
|
-
setTimeout(function () {
|
|
117
|
-
self._<%= Evercookie.js_class %>(name, cb, value, i, dont_reset);
|
|
118
|
-
}, 300);
|
|
119
|
-
}
|
|
289
|
+
this.<%= Evercookie.js_class %>_window = function (name, value) {
|
|
290
|
+
try {
|
|
291
|
+
if (value !== undefined) {
|
|
292
|
+
window.name = _ec_replace(window.name, name, value);
|
|
293
|
+
} else {
|
|
294
|
+
return this.getFromStr(name, window.name);
|
|
295
|
+
}
|
|
296
|
+
} catch (e) { }
|
|
297
|
+
};
|
|
120
298
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
self._ec.lsoData = self.getFromStr(name, _global_lso);
|
|
126
|
-
_global_lso = undefined;
|
|
127
|
-
|
|
128
|
-
var tmpec = self._ec,
|
|
129
|
-
candidates = [],
|
|
130
|
-
bestnum = 0,
|
|
131
|
-
candidate,
|
|
132
|
-
item;
|
|
133
|
-
self._ec = {};
|
|
134
|
-
|
|
135
|
-
// figure out which is the best candidate
|
|
136
|
-
for (item in tmpec) {
|
|
137
|
-
if (tmpec[item] && tmpec[item] !== "null" && tmpec[item] !== "undefined") {
|
|
138
|
-
candidates[tmpec[item]] = candidates[tmpec[item]] === undefined ? 1 : candidates[tmpec[item]] + 1;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
299
|
+
this.<%= Evercookie.js_class %>_userdata = function (name, value) {
|
|
300
|
+
try {
|
|
301
|
+
var elm = this.createElem("div", "userdata_el", 1);
|
|
302
|
+
elm.style.behavior = "url(#default#userData)";
|
|
141
303
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
304
|
+
if (value !== undefined) {
|
|
305
|
+
elm.setAttribute(name, value);
|
|
306
|
+
elm.save(name);
|
|
307
|
+
} else {
|
|
308
|
+
elm.load(name);
|
|
309
|
+
return elm.getAttribute(name);
|
|
310
|
+
}
|
|
311
|
+
} catch (e) {}
|
|
312
|
+
};
|
|
148
313
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
self.set(name, candidate);
|
|
152
|
-
}
|
|
153
|
-
if (typeof cb === "function") {
|
|
154
|
-
cb(candidate, tmpec);
|
|
155
|
-
}
|
|
314
|
+
this.ajax = function (settings) {
|
|
315
|
+
var headers, name, transports, transport, i, length;
|
|
156
316
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
};
|
|
317
|
+
headers = {
|
|
318
|
+
'X-Requested-With': 'XMLHttpRequest',
|
|
319
|
+
'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
|
|
320
|
+
};
|
|
164
321
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
return this.getFromStr(name, window.name);
|
|
171
|
-
}
|
|
172
|
-
} catch (e) { }
|
|
173
|
-
};
|
|
322
|
+
transports = [
|
|
323
|
+
function () { return new XMLHttpRequest(); },
|
|
324
|
+
function () { return new ActiveXObject('Msxml2.XMLHTTP'); },
|
|
325
|
+
function () { return new ActiveXObject('Microsoft.XMLHTTP'); }
|
|
326
|
+
];
|
|
174
327
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
328
|
+
for (i = 0, length = transports.length; i < length; i++) {
|
|
329
|
+
transport = transports[i];
|
|
330
|
+
try {
|
|
331
|
+
transport = transport();
|
|
332
|
+
break;
|
|
333
|
+
} catch (e) {
|
|
334
|
+
}
|
|
335
|
+
}
|
|
179
336
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
img.style.visibility = "hidden";
|
|
193
|
-
img.style.position = "absolute";
|
|
194
|
-
img.src = src;
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
this.ajax = function (settings) {
|
|
198
|
-
var headers, name, transports, transport, i, length;
|
|
199
|
-
|
|
200
|
-
headers = {
|
|
201
|
-
'X-Requested-With': 'XMLHttpRequest',
|
|
202
|
-
'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
|
|
203
|
-
};
|
|
204
|
-
|
|
205
|
-
transports = [
|
|
206
|
-
function () { return new XMLHttpRequest(); },
|
|
207
|
-
function () { return new ActiveXObject('Msxml2.XMLHTTP'); },
|
|
208
|
-
function () { return new ActiveXObject('Microsoft.XMLHTTP'); }
|
|
209
|
-
];
|
|
210
|
-
|
|
211
|
-
for (i = 0, length = transports.length; i < length; i++) {
|
|
212
|
-
transport = transports[i];
|
|
213
|
-
try {
|
|
214
|
-
transport = transport();
|
|
215
|
-
break;
|
|
216
|
-
} catch (e) {
|
|
217
|
-
}
|
|
218
|
-
}
|
|
337
|
+
transport.onreadystatechange = function () {
|
|
338
|
+
if (transport.readyState !== 4) {
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
settings.success(transport.responseText);
|
|
342
|
+
};
|
|
343
|
+
transport.open('get', settings.url, true);
|
|
344
|
+
for (name in headers) {
|
|
345
|
+
transport.setRequestHeader(name, headers[name]);
|
|
346
|
+
}
|
|
347
|
+
transport.send();
|
|
348
|
+
};
|
|
219
349
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
350
|
+
this.<%= Evercookie.js_class %>_cache = function (name, value) {
|
|
351
|
+
if (value !== undefined) {
|
|
352
|
+
// make sure we have evercookie session defined first
|
|
353
|
+
document.cookie = opts.cacheCookieName + "=" + value + "; path=/; domain=" + _ec_domain;
|
|
354
|
+
// {{ajax request to opts.cachePath}} handles caching
|
|
355
|
+
self.ajax({
|
|
356
|
+
url: _ec_baseurl + opts.cachePath + "?name=" + name,
|
|
357
|
+
success: function (data) {}
|
|
358
|
+
});
|
|
359
|
+
} else {
|
|
360
|
+
// interestingly enough, we want to erase our evercookie
|
|
361
|
+
// http cookie so the php will force a cached response
|
|
362
|
+
var origvalue = this.getFromStr(opts.cacheCookieName, document.cookie);
|
|
363
|
+
self._ec.cacheData = undefined;
|
|
364
|
+
document.cookie = opts.cacheCookieName + "=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/; domain=" + _ec_domain;
|
|
365
|
+
|
|
366
|
+
self.ajax({
|
|
367
|
+
url: _ec_baseurl + opts.cachePath + "?name=" + name,
|
|
368
|
+
success: function (data) {
|
|
369
|
+
// put our cookie back
|
|
370
|
+
document.cookie = opts.cacheCookieName + "=" + origvalue + "; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/; domain=" + _ec_domain;
|
|
371
|
+
|
|
372
|
+
self._ec.cacheData = data;
|
|
373
|
+
}
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
this.<%= Evercookie.js_class %>_auth = function (name, value) {
|
|
378
|
+
if (value !== undefined) {
|
|
379
|
+
// {{opts.authPath}} handles Basic Access Authentication
|
|
380
|
+
newImage('//' + value + '@' + location.host + _ec_baseurl + opts.authPath + "?name=" + name);
|
|
381
|
+
}
|
|
382
|
+
else {
|
|
383
|
+
self.ajax({
|
|
384
|
+
url: _ec_baseurl + opts.authPath + "?name=" + name,
|
|
385
|
+
success: function (data) {
|
|
386
|
+
self._ec.authData = data;
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
this.<%= Evercookie.js_class %>_etag = function (name, value) {
|
|
393
|
+
if (value !== undefined) {
|
|
394
|
+
// make sure we have evercookie session defined first
|
|
395
|
+
document.cookie = opts.etagCookieName + "=" + value + "; path=/; domain=" + _ec_domain;
|
|
396
|
+
// {{ajax request to opts.etagPath}} handles etagging
|
|
397
|
+
self.ajax({
|
|
398
|
+
url: _ec_baseurl + opts.etagPath + "?name=" + name,
|
|
399
|
+
success: function (data) {}
|
|
400
|
+
});
|
|
401
|
+
} else {
|
|
402
|
+
// interestingly enough, we want to erase our evercookie
|
|
403
|
+
// http cookie so the php will force a cached response
|
|
404
|
+
var origvalue = this.getFromStr(opts.etagCookieName, document.cookie);
|
|
405
|
+
self._ec.etagData = undefined;
|
|
406
|
+
document.cookie = opts.etagCookieName + "=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/; domain=" + _ec_domain;
|
|
407
|
+
|
|
408
|
+
self.ajax({
|
|
409
|
+
url: _ec_baseurl + opts.etagPath + "?name=" + name,
|
|
410
|
+
success: function (data) {
|
|
411
|
+
// put our cookie back
|
|
412
|
+
document.cookie = opts.etagCookieName + "=" + origvalue + "; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/; domain=" + _ec_domain;
|
|
413
|
+
|
|
414
|
+
self._ec.etagData = data;
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
|
|
420
|
+
this.<%= Evercookie.js_class %>_java = function (name, value) {
|
|
421
|
+
var div = document.getElementById("ecAppletContainer");
|
|
422
|
+
|
|
423
|
+
// Exit if dtjava.js was not included in the page header.
|
|
424
|
+
if (typeof dtjava === "undefined") {
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
// Create the container div if none exists.
|
|
429
|
+
if (div===null || div === undefined || !div.length) {
|
|
430
|
+
div = document.createElement("div");
|
|
431
|
+
div.setAttribute("id", "ecAppletContainer");
|
|
432
|
+
div.style.position = "absolute";
|
|
433
|
+
div.style.top = "-3000px";
|
|
434
|
+
div.style.left = "-3000px";
|
|
435
|
+
div.style.width = "1px";
|
|
436
|
+
div.style.height = "1px";
|
|
437
|
+
document.body.appendChild(div);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// If the Java applet is not yet defined, embed it.
|
|
441
|
+
if (typeof ecApplet === "undefined") {
|
|
442
|
+
dtjava.embed({
|
|
443
|
+
id: "ecApplet",
|
|
444
|
+
url: _ec_baseurl + "<%= Evercookie.js_class %>.jnlp",
|
|
445
|
+
width: "1px",
|
|
446
|
+
height: "1px",
|
|
447
|
+
placeholder: "ecAppletContainer"
|
|
448
|
+
}, {},{ onJavascriptReady: doSetOrGet });
|
|
449
|
+
// When the applet is loaded we will continue in doSetOrGet()
|
|
450
|
+
}
|
|
451
|
+
else {
|
|
452
|
+
// applet already running... call doGetOrSet() directly.
|
|
453
|
+
doSetOrGet("ecApplet");
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
function doSetOrGet(appletId) {
|
|
457
|
+
var applet = document.getElementById(appletId);
|
|
458
|
+
if (value !== undefined) {
|
|
459
|
+
applet.set(name,value);
|
|
460
|
+
}
|
|
461
|
+
else {
|
|
462
|
+
self._ec.javaData = applet.get(name);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
// The result of a get() is now in self._ec._javaData
|
|
467
|
+
};
|
|
468
|
+
|
|
469
|
+
this.<%= Evercookie.js_class %>_lso = function (name, value) {
|
|
470
|
+
var div = document.getElementById("swfcontainer"),
|
|
471
|
+
flashvars = {},
|
|
472
|
+
params = {},
|
|
473
|
+
attributes = {};
|
|
474
|
+
if (div===null || div === undefined || !div.length) {
|
|
475
|
+
div = document.createElement("div");
|
|
476
|
+
div.setAttribute("id", "swfcontainer");
|
|
477
|
+
document.body.appendChild(div);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
if (value !== undefined) {
|
|
481
|
+
flashvars.everdata = name + "=" + value;
|
|
482
|
+
}
|
|
483
|
+
params.swliveconnect = "true";
|
|
484
|
+
attributes.id = "myswf";
|
|
485
|
+
attributes.name = "myswf";
|
|
486
|
+
swfobject.embedSWF(_ec_baseurl + "<%= asset_path('ec.swf') %>", "swfcontainer", "1", "1", "9.0.0", false, flashvars, params, attributes);
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
this.<%= Evercookie.js_class %>_png = function (name, value) {
|
|
490
|
+
var canvas = document.createElement("canvas"),
|
|
491
|
+
img, ctx, origvalue;
|
|
492
|
+
canvas.style.visibility = "hidden";
|
|
493
|
+
canvas.style.position = "absolute";
|
|
494
|
+
canvas.width = 200;
|
|
495
|
+
canvas.height = 1;
|
|
496
|
+
if (canvas && canvas.getContext) {
|
|
497
|
+
// {{opts.pngPath}} handles the hard part of generating the image
|
|
498
|
+
// based off of the http cookie and returning it cached
|
|
499
|
+
img = new Image();
|
|
500
|
+
img.style.position = "absolute";
|
|
501
|
+
if (value !== undefined) {
|
|
502
|
+
// make sure we have evercookie session defined first
|
|
503
|
+
document.cookie = opts.pngCookieName + "=" + value + "; path=/; domain=" + _ec_domain;
|
|
504
|
+
} else {
|
|
505
|
+
self._ec.pngData = undefined;
|
|
506
|
+
ctx = canvas.getContext("2d");
|
|
507
|
+
|
|
508
|
+
// interestingly enough, we want to erase our evercookie
|
|
509
|
+
// http cookie so the php will force a cached response
|
|
510
|
+
origvalue = this.getFromStr(opts.pngCookieName, document.cookie);
|
|
511
|
+
document.cookie = opts.pngCookieName + "=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/; domain=" + _ec_domain;
|
|
512
|
+
|
|
513
|
+
img.onload = function () {
|
|
514
|
+
// put our cookie back
|
|
515
|
+
document.cookie = opts.pngCookieName + "=" + origvalue + "; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/; domain=" + _ec_domain;
|
|
516
|
+
|
|
517
|
+
self._ec.pngData = "";
|
|
518
|
+
ctx.drawImage(img, 0, 0);
|
|
519
|
+
|
|
520
|
+
// get CanvasPixelArray from given coordinates and dimensions
|
|
521
|
+
var imgd = ctx.getImageData(0, 0, 200, 1),
|
|
522
|
+
pix = imgd.data, i, n;
|
|
523
|
+
// loop over each pixel to get the "RGB" values (ignore alpha)
|
|
524
|
+
for (i = 0, n = pix.length; i < n; i += 4) {
|
|
525
|
+
if (pix[i] === 0) {
|
|
526
|
+
break;
|
|
527
|
+
}
|
|
528
|
+
self._ec.pngData += String.fromCharCode(pix[i]);
|
|
529
|
+
if (pix[i + 1] === 0) {
|
|
530
|
+
break;
|
|
531
|
+
}
|
|
532
|
+
self._ec.pngData += String.fromCharCode(pix[i + 1]);
|
|
533
|
+
if (pix[i + 2] === 0) {
|
|
534
|
+
break;
|
|
535
|
+
}
|
|
536
|
+
self._ec.pngData += String.fromCharCode(pix[i + 2]);
|
|
292
537
|
}
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
img.src = _ec_baseurl + opts.pngPath + "?name=" + name;
|
|
541
|
+
img.style.visibility = "hidden";
|
|
542
|
+
}
|
|
543
|
+
};
|
|
544
|
+
|
|
545
|
+
this.<%= Evercookie.js_class %>_local_storage = function (name, value) {
|
|
546
|
+
try {
|
|
547
|
+
if (localStore) {
|
|
548
|
+
if (value !== undefined) {
|
|
549
|
+
localStore.setItem(name, value);
|
|
550
|
+
} else {
|
|
551
|
+
return localStore.getItem(name);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
} catch (e) { }
|
|
555
|
+
};
|
|
556
|
+
|
|
557
|
+
this.<%= Evercookie.js_class %>_database_storage = function (name, value) {
|
|
558
|
+
try {
|
|
559
|
+
if (window.openDatabase) {
|
|
560
|
+
var database = window.openDatabase("sqlite_<%= Evercookie.js_class %>", "", "<%= Evercookie.js_class %>", 1024 * 1024);
|
|
561
|
+
|
|
562
|
+
if (value !== undefined) {
|
|
563
|
+
database.transaction(function (tx) {
|
|
564
|
+
tx.executeSql("CREATE TABLE IF NOT EXISTS cache(" +
|
|
565
|
+
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " +
|
|
566
|
+
"name TEXT NOT NULL, " +
|
|
567
|
+
"value TEXT NOT NULL, " +
|
|
568
|
+
"UNIQUE (name)" +
|
|
569
|
+
")", [], function (tx, rs) {}, function (tx, err) {});
|
|
570
|
+
tx.executeSql("INSERT OR REPLACE INTO cache(name, value) " +
|
|
571
|
+
"VALUES(?, ?)",
|
|
572
|
+
[name, value], function (tx, rs) {}, function (tx, err) {});
|
|
573
|
+
});
|
|
574
|
+
} else {
|
|
575
|
+
database.transaction(function (tx) {
|
|
576
|
+
tx.executeSql("SELECT value FROM cache WHERE name=?", [name],
|
|
577
|
+
function (tx, result1) {
|
|
578
|
+
if (result1.rows.length >= 1) {
|
|
579
|
+
self._ec.dbData = result1.rows.item(0).value;
|
|
580
|
+
} else {
|
|
581
|
+
self._ec.dbData = "";
|
|
582
|
+
}
|
|
583
|
+
}, function (tx, err) {});
|
|
584
|
+
});
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
} catch (e) { }
|
|
588
|
+
};
|
|
589
|
+
|
|
590
|
+
this.<%= Evercookie.js_class %>_indexdb_storage = function(name, value) {
|
|
591
|
+
try {
|
|
592
|
+
if (!('indexedDB' in window)) {
|
|
593
|
+
|
|
594
|
+
indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
|
|
595
|
+
IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;
|
|
596
|
+
IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange;
|
|
597
|
+
}
|
|
293
598
|
|
|
294
|
-
|
|
295
|
-
|
|
599
|
+
if (indexedDB) {
|
|
600
|
+
var ver = 1;
|
|
601
|
+
//FF incognito mode restricts indexedb access
|
|
602
|
+
var request = indexedDB.open("idb_<%= Evercookie.js_class %>", ver);
|
|
603
|
+
|
|
604
|
+
|
|
605
|
+
request.onerror = function(e) { ;
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
request.onupgradeneeded = function(event) {
|
|
609
|
+
var db = event.target.result;
|
|
610
|
+
|
|
611
|
+
var store = db.createObjectStore("<%= Evercookie.js_class %>", {
|
|
612
|
+
keyPath: "name",
|
|
613
|
+
unique: false
|
|
614
|
+
})
|
|
615
|
+
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
if (value !== undefined) {
|
|
619
|
+
|
|
620
|
+
|
|
621
|
+
request.onsuccess = function(event) {
|
|
622
|
+
var idb = event.target.result;
|
|
623
|
+
if (idb.objectStoreNames.contains("<%= Evercookie.js_class %>")) {
|
|
624
|
+
var tx = idb.transaction(["<%= Evercookie.js_class %>"], "readwrite");
|
|
625
|
+
var objst = tx.objectStore("<%= Evercookie.js_class %>");
|
|
626
|
+
var qr = objst.put({
|
|
627
|
+
"name": name,
|
|
628
|
+
"value": value
|
|
629
|
+
})
|
|
630
|
+
} idb.close();
|
|
296
631
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
canvas.style.position = "absolute";
|
|
308
|
-
canvas.width = 200;
|
|
309
|
-
canvas.height = 1;
|
|
310
|
-
if (canvas && canvas.getContext) {
|
|
311
|
-
// <%= Evercookie.get_png_path %> handles the hard part of generating the image
|
|
312
|
-
// based off of the http cookie and returning it cached
|
|
313
|
-
img = new Image();
|
|
314
|
-
img.style.visibility = "hidden";
|
|
315
|
-
img.style.position = "absolute";
|
|
316
|
-
if (value !== undefined) {
|
|
317
|
-
// make sure we have <%= Evercookie.js_class %> session defined first
|
|
318
|
-
document.cookie = "<%= Evercookie.cookie_png %>=" + value + "; path=<%= Evercookie.get_cookie_path %>";
|
|
632
|
+
|
|
633
|
+
} else {
|
|
634
|
+
|
|
635
|
+
request.onsuccess = function(event) {
|
|
636
|
+
|
|
637
|
+
var idb = event.target.result;
|
|
638
|
+
|
|
639
|
+
if (!idb.objectStoreNames.contains("<%= Evercookie.js_class %>")) {
|
|
640
|
+
|
|
641
|
+
self._ec.idbData = undefined;
|
|
319
642
|
} else {
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
// put our cookie back
|
|
330
|
-
document.cookie = "<%= Evercookie.cookie_png %>=" + origvalue + "; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=<%= Evercookie.get_cookie_path %>";
|
|
331
|
-
|
|
332
|
-
self._ec.pngData = "";
|
|
333
|
-
ctx.drawImage(img, 0, 0);
|
|
334
|
-
|
|
335
|
-
// get CanvasPixelArray from given coordinates and dimensions
|
|
336
|
-
var imgd = ctx.getImageData(0, 0, 200, 1),
|
|
337
|
-
pix = imgd.data, i, n;
|
|
338
|
-
|
|
339
|
-
// loop over each pixel to get the "RGB" values (ignore alpha)
|
|
340
|
-
for (i = 0, n = pix.length; i < n; i += 4) {
|
|
341
|
-
if (pix[i] === 0) {
|
|
342
|
-
break;
|
|
343
|
-
}
|
|
344
|
-
self._ec.pngData += String.fromCharCode(pix[i]);
|
|
345
|
-
if (pix[i + 1] === 0) {
|
|
346
|
-
break;
|
|
347
|
-
}
|
|
348
|
-
self._ec.pngData += String.fromCharCode(pix[i + 1]);
|
|
349
|
-
if (pix[i + 2] === 0) {
|
|
350
|
-
break;
|
|
351
|
-
}
|
|
352
|
-
self._ec.pngData += String.fromCharCode(pix[i + 2]);
|
|
643
|
+
var tx = idb.transaction(["<%= Evercookie.js_class %>"]);
|
|
644
|
+
var objst = tx.objectStore("<%= Evercookie.js_class %>");
|
|
645
|
+
var qr = objst.get(name);
|
|
646
|
+
|
|
647
|
+
qr.onsuccess = function(event) {
|
|
648
|
+
if (qr.result === undefined) {
|
|
649
|
+
self._ec.idbData = undefined
|
|
650
|
+
} else {
|
|
651
|
+
self._ec.idbData = qr.result.value;
|
|
353
652
|
}
|
|
354
|
-
};
|
|
355
|
-
}
|
|
356
|
-
img.src = "<%= Evercookie.get_png_path %>?name=" + name;
|
|
357
|
-
}
|
|
358
|
-
};
|
|
359
|
-
|
|
360
|
-
this.<%= Evercookie.js_class %>_local_storage = function (name, value) {
|
|
361
|
-
try {
|
|
362
|
-
if (localStorage) {
|
|
363
|
-
if (value !== undefined) {
|
|
364
|
-
localStorage.setItem(name, value);
|
|
365
|
-
} else {
|
|
366
|
-
return localStorage.getItem(name);
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
} catch (e) { }
|
|
370
|
-
};
|
|
371
|
-
|
|
372
|
-
this.<%= Evercookie.js_class %>_database_storage = function (name, value) {
|
|
373
|
-
try {
|
|
374
|
-
if (window.openDatabase) {
|
|
375
|
-
var database = window.openDatabase("sqlite_<%= Evercookie.js_class %>", "", "<%= Evercookie.js_class %>", 1024 * 1024);
|
|
376
|
-
|
|
377
|
-
if (value !== undefined) {
|
|
378
|
-
database.transaction(function (tx) {
|
|
379
|
-
tx.executeSql("CREATE TABLE IF NOT EXISTS cache(" +
|
|
380
|
-
"id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, " +
|
|
381
|
-
"name TEXT NOT NULL, " +
|
|
382
|
-
"value TEXT NOT NULL, " +
|
|
383
|
-
"UNIQUE (name)" +
|
|
384
|
-
")", [], function (tx, rs) {}, function (tx, err) {});
|
|
385
|
-
tx.executeSql("INSERT OR REPLACE INTO cache(name, value) " +
|
|
386
|
-
"VALUES(?, ?)",
|
|
387
|
-
[name, value], function (tx, rs) {}, function (tx, err) {});
|
|
388
|
-
});
|
|
389
|
-
} else {
|
|
390
|
-
database.transaction(function (tx) {
|
|
391
|
-
tx.executeSql("SELECT value FROM cache WHERE name=?", [name],
|
|
392
|
-
function (tx, result1) {
|
|
393
|
-
if (result1.rows.length >= 1) {
|
|
394
|
-
self._ec.dbData = result1.rows.item(0).value;
|
|
395
|
-
} else {
|
|
396
|
-
self._ec.dbData = "";
|
|
397
|
-
}
|
|
398
|
-
}, function (tx, err) {});
|
|
399
|
-
});
|
|
400
653
|
}
|
|
401
654
|
}
|
|
402
|
-
|
|
403
|
-
};
|
|
404
|
-
|
|
405
|
-
this.<%= Evercookie.js_class %>_session_storage = function (name, value) {
|
|
406
|
-
try {
|
|
407
|
-
if (sessionStorage) {
|
|
408
|
-
if (value !== undefined) {
|
|
409
|
-
sessionStorage.setItem(name, value);
|
|
410
|
-
} else {
|
|
411
|
-
return sessionStorage.getItem(name);
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
} catch (e) { }
|
|
415
|
-
};
|
|
416
|
-
|
|
417
|
-
this.<%= Evercookie.js_class %>_global_storage = function (name, value) {
|
|
418
|
-
if (globalStorage) {
|
|
419
|
-
var host = this.getHost();
|
|
420
|
-
try {
|
|
421
|
-
if (value !== undefined) {
|
|
422
|
-
globalStorage[host][name] = value;
|
|
423
|
-
} else {
|
|
424
|
-
return globalStorage[host][name];
|
|
425
|
-
}
|
|
426
|
-
} catch (e) { }
|
|
655
|
+
idb.close();
|
|
427
656
|
}
|
|
428
|
-
}
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
} catch (e) {}
|
|
660
|
+
};
|
|
661
|
+
|
|
662
|
+
this.<%= Evercookie.js_class %>_session_storage = function (name, value) {
|
|
663
|
+
try {
|
|
664
|
+
if (sessionStorage) {
|
|
665
|
+
if (value !== undefined) {
|
|
666
|
+
sessionStorage.setItem(name, value);
|
|
667
|
+
} else {
|
|
668
|
+
return sessionStorage.getItem(name);
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
} catch (e) { }
|
|
672
|
+
};
|
|
429
673
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
674
|
+
this.<%= Evercookie.js_class %>_global_storage = function (name, value) {
|
|
675
|
+
if (globalStorage) {
|
|
676
|
+
var host = this.getHost();
|
|
677
|
+
try {
|
|
678
|
+
if (value !== undefined) {
|
|
679
|
+
globalStorage[host][name] = value;
|
|
680
|
+
} else {
|
|
681
|
+
return globalStorage[host][name];
|
|
682
|
+
}
|
|
683
|
+
} catch (e) { }
|
|
684
|
+
}
|
|
685
|
+
};
|
|
435
686
|
|
|
436
|
-
|
|
687
|
+
this.<%= Evercookie.js_class %>_silverlight = function (name, value) {
|
|
688
|
+
/*
|
|
689
|
+
* Create silverlight embed
|
|
690
|
+
*
|
|
691
|
+
* Ok. so, I tried doing this the proper dom way, but IE chokes on appending anything in object tags (including params), so this
|
|
692
|
+
* is the best method I found. Someone really needs to find a less hack-ish way. I hate the look of this shit.
|
|
693
|
+
*/
|
|
694
|
+
var source = _ec_baseurl + "<%= Evercookie.js_class %>.xap",
|
|
695
|
+
minver = "4.0.50401.0",
|
|
696
|
+
initParam = "",
|
|
697
|
+
html;
|
|
698
|
+
if (value !== undefined) {
|
|
699
|
+
initParam = '<param name="initParams" value="' + name + '=' + value + '" />';
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
html =
|
|
703
|
+
'<object style="position:absolute;left:-500px;top:-500px" data="data:application/x-silverlight-2," type="application/x-silverlight-2" id="mysilverlight" width="0" height="0">' +
|
|
704
|
+
initParam +
|
|
705
|
+
'<param name="source" value="' + source + '"/>' +
|
|
706
|
+
'<param name="onLoad" value="onSilverlightLoad"/>' +
|
|
707
|
+
'<param name="onError" value="onSilverlightError"/>' +
|
|
708
|
+
'<param name="background" value="Transparent"/>' +
|
|
709
|
+
'<param name="windowless" value="true"/>' +
|
|
710
|
+
'<param name="minRuntimeVersion" value="' + minver + '"/>' +
|
|
711
|
+
'<param name="autoUpgrade" value="false"/>' +
|
|
712
|
+
'<a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=' + minver + '" style="display:none">' +
|
|
713
|
+
'Get Microsoft Silverlight' +
|
|
714
|
+
'</a>' +
|
|
715
|
+
'</object>';
|
|
716
|
+
try{
|
|
717
|
+
document.body.appendChild(html);
|
|
718
|
+
}catch(ex){
|
|
719
|
+
|
|
720
|
+
}
|
|
721
|
+
};
|
|
437
722
|
|
|
438
|
-
|
|
723
|
+
// public method for encoding
|
|
724
|
+
this.encode = function (input) {
|
|
725
|
+
var output = "",
|
|
726
|
+
chr1, chr2, chr3, enc1, enc2, enc3, enc4,
|
|
727
|
+
i = 0;
|
|
439
728
|
|
|
440
|
-
|
|
441
|
-
chr2 = input.charCodeAt(i++);
|
|
442
|
-
chr3 = input.charCodeAt(i++);
|
|
729
|
+
input = this._utf8_encode(input);
|
|
443
730
|
|
|
444
|
-
|
|
445
|
-
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
|
|
446
|
-
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
|
|
447
|
-
enc4 = chr3 & 63;
|
|
731
|
+
while (i < input.length) {
|
|
448
732
|
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
enc4 = 64;
|
|
453
|
-
}
|
|
733
|
+
chr1 = input.charCodeAt(i++);
|
|
734
|
+
chr2 = input.charCodeAt(i++);
|
|
735
|
+
chr3 = input.charCodeAt(i++);
|
|
454
736
|
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
737
|
+
enc1 = chr1 >> 2;
|
|
738
|
+
enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
|
|
739
|
+
enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
|
|
740
|
+
enc4 = chr3 & 63;
|
|
458
741
|
|
|
459
|
-
|
|
742
|
+
if (isNaN(chr2)) {
|
|
743
|
+
enc3 = enc4 = 64;
|
|
744
|
+
} else if (isNaN(chr3)) {
|
|
745
|
+
enc4 = 64;
|
|
746
|
+
}
|
|
460
747
|
|
|
461
|
-
|
|
462
|
-
|
|
748
|
+
output = output +
|
|
749
|
+
_baseKeyStr.charAt(enc1) + _baseKeyStr.charAt(enc2) +
|
|
750
|
+
_baseKeyStr.charAt(enc3) + _baseKeyStr.charAt(enc4);
|
|
463
751
|
|
|
464
|
-
|
|
465
|
-
this.decode = function (input) {
|
|
466
|
-
var output = "",
|
|
467
|
-
chr1, chr2, chr3,
|
|
468
|
-
enc1, enc2, enc3, enc4,
|
|
469
|
-
i = 0;
|
|
752
|
+
}
|
|
470
753
|
|
|
471
|
-
|
|
754
|
+
return output;
|
|
755
|
+
};
|
|
472
756
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
757
|
+
// public method for decoding
|
|
758
|
+
this.decode = function (input) {
|
|
759
|
+
var output = "",
|
|
760
|
+
chr1, chr2, chr3,
|
|
761
|
+
enc1, enc2, enc3, enc4,
|
|
762
|
+
i = 0;
|
|
478
763
|
|
|
479
|
-
|
|
480
|
-
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
|
|
481
|
-
chr3 = ((enc3 & 3) << 6) | enc4;
|
|
764
|
+
input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
|
|
482
765
|
|
|
483
|
-
|
|
766
|
+
while (i < input.length) {
|
|
767
|
+
enc1 = _baseKeyStr.indexOf(input.charAt(i++));
|
|
768
|
+
enc2 = _baseKeyStr.indexOf(input.charAt(i++));
|
|
769
|
+
enc3 = _baseKeyStr.indexOf(input.charAt(i++));
|
|
770
|
+
enc4 = _baseKeyStr.indexOf(input.charAt(i++));
|
|
484
771
|
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
if (enc4 !== 64) {
|
|
489
|
-
output = output + String.fromCharCode(chr3);
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
output = this._utf8_decode(output);
|
|
493
|
-
return output;
|
|
494
|
-
};
|
|
495
|
-
|
|
496
|
-
// private method for UTF-8 encoding
|
|
497
|
-
this._utf8_encode = function (str) {
|
|
498
|
-
str = str.replace(/\r\n/g, "\n");
|
|
499
|
-
var utftext = "", i = 0, n = str.length, c;
|
|
500
|
-
for (; i < n; i++) {
|
|
501
|
-
c = str.charCodeAt(i);
|
|
502
|
-
if (c < 128) {
|
|
503
|
-
utftext += String.fromCharCode(c);
|
|
504
|
-
} else if ((c > 127) && (c < 2048)) {
|
|
505
|
-
utftext += String.fromCharCode((c >> 6) | 192);
|
|
506
|
-
utftext += String.fromCharCode((c & 63) | 128);
|
|
507
|
-
} else {
|
|
508
|
-
utftext += String.fromCharCode((c >> 12) | 224);
|
|
509
|
-
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
|
|
510
|
-
utftext += String.fromCharCode((c & 63) | 128);
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
return utftext;
|
|
514
|
-
};
|
|
515
|
-
|
|
516
|
-
// private method for UTF-8 decoding
|
|
517
|
-
this._utf8_decode = function (utftext) {
|
|
518
|
-
var str = "",
|
|
519
|
-
i = 0, n = utftext.length,
|
|
520
|
-
c = 0, c1 = 0, c2 = 0, c3 = 0;
|
|
521
|
-
while (i < n) {
|
|
522
|
-
c = utftext.charCodeAt(i);
|
|
523
|
-
if (c < 128) {
|
|
524
|
-
str += String.fromCharCode(c);
|
|
525
|
-
i += 1;
|
|
526
|
-
} else if ((c > 191) && (c < 224)) {
|
|
527
|
-
c2 = utftext.charCodeAt(i + 1);
|
|
528
|
-
str += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
|
|
529
|
-
i += 2;
|
|
530
|
-
} else {
|
|
531
|
-
c2 = utftext.charCodeAt(i + 1);
|
|
532
|
-
c3 = utftext.charCodeAt(i + 2);
|
|
533
|
-
str += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
|
|
534
|
-
i += 3;
|
|
535
|
-
}
|
|
536
|
-
}
|
|
537
|
-
return str;
|
|
538
|
-
};
|
|
539
|
-
|
|
540
|
-
this.createElem = function (type, name, append) {
|
|
541
|
-
var el;
|
|
542
|
-
if (name !== undefined && document.getElementById(name)) {
|
|
543
|
-
el = document.getElementById(name);
|
|
544
|
-
} else {
|
|
545
|
-
el = document.createElement(type);
|
|
546
|
-
}
|
|
547
|
-
el.style.visibility = "hidden";
|
|
548
|
-
el.style.position = "absolute";
|
|
772
|
+
chr1 = (enc1 << 2) | (enc2 >> 4);
|
|
773
|
+
chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
|
|
774
|
+
chr3 = ((enc3 & 3) << 6) | enc4;
|
|
549
775
|
|
|
550
|
-
|
|
551
|
-
el.setAttribute("id", name);
|
|
552
|
-
}
|
|
776
|
+
output = output + String.fromCharCode(chr1);
|
|
553
777
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
};
|
|
565
|
-
|
|
566
|
-
// wait for our swfobject to appear (swfobject.js to load)
|
|
567
|
-
var waitForSwf = this.waitForSwf = function (i) {
|
|
568
|
-
if (i === undefined) {
|
|
569
|
-
i = 0;
|
|
570
|
-
} else {
|
|
571
|
-
i++;
|
|
572
|
-
}
|
|
778
|
+
if (enc3 !== 64) {
|
|
779
|
+
output = output + String.fromCharCode(chr2);
|
|
780
|
+
}
|
|
781
|
+
if (enc4 !== 64) {
|
|
782
|
+
output = output + String.fromCharCode(chr3);
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
output = this._utf8_decode(output);
|
|
786
|
+
return output;
|
|
787
|
+
};
|
|
573
788
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
789
|
+
// private method for UTF-8 encoding
|
|
790
|
+
this._utf8_encode = function (str) {
|
|
791
|
+
str = str.replace(/\r\n/g, "\n");
|
|
792
|
+
var utftext = "", i = 0, n = str.length, c;
|
|
793
|
+
for (; i < n; i++) {
|
|
794
|
+
c = str.charCodeAt(i);
|
|
795
|
+
if (c < 128) {
|
|
796
|
+
utftext += String.fromCharCode(c);
|
|
797
|
+
} else if ((c > 127) && (c < 2048)) {
|
|
798
|
+
utftext += String.fromCharCode((c >> 6) | 192);
|
|
799
|
+
utftext += String.fromCharCode((c & 63) | 128);
|
|
800
|
+
} else {
|
|
801
|
+
utftext += String.fromCharCode((c >> 12) | 224);
|
|
802
|
+
utftext += String.fromCharCode(((c >> 6) & 63) | 128);
|
|
803
|
+
utftext += String.fromCharCode((c & 63) | 128);
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
return utftext;
|
|
807
|
+
};
|
|
591
808
|
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
809
|
+
// private method for UTF-8 decoding
|
|
810
|
+
this._utf8_decode = function (utftext) {
|
|
811
|
+
var str = "",
|
|
812
|
+
i = 0, n = utftext.length,
|
|
813
|
+
c = 0, c1 = 0, c2 = 0, c3 = 0;
|
|
814
|
+
while (i < n) {
|
|
815
|
+
c = utftext.charCodeAt(i);
|
|
816
|
+
if (c < 128) {
|
|
817
|
+
str += String.fromCharCode(c);
|
|
818
|
+
i += 1;
|
|
819
|
+
} else if ((c > 191) && (c < 224)) {
|
|
820
|
+
c2 = utftext.charCodeAt(i + 1);
|
|
821
|
+
str += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
|
|
822
|
+
i += 2;
|
|
823
|
+
} else {
|
|
824
|
+
c2 = utftext.charCodeAt(i + 1);
|
|
825
|
+
c3 = utftext.charCodeAt(i + 2);
|
|
826
|
+
str += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
|
|
827
|
+
i += 3;
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
return str;
|
|
831
|
+
};
|
|
832
|
+
|
|
833
|
+
// this is crazy but it's 4am in dublin and i thought this would be hilarious
|
|
834
|
+
// blame the guinness
|
|
835
|
+
this.<%= Evercookie.js_class %>_history = function (name, value) {
|
|
836
|
+
// - is special
|
|
837
|
+
var baseElems = (_baseKeyStr + "-").split(""),
|
|
838
|
+
// sorry google.
|
|
839
|
+
url = "http://www.google.com/<%= Evercookie.js_class %>/cache/" + this.getHost() + "/" + name,
|
|
840
|
+
i, base,
|
|
841
|
+
letter = "",
|
|
842
|
+
val = "",
|
|
843
|
+
found = 1;
|
|
844
|
+
|
|
845
|
+
if (value !== undefined) {
|
|
846
|
+
// don't reset this if we already have it set once
|
|
847
|
+
// too much data and you can't clear previous values
|
|
848
|
+
if (this.hasVisited(url)) {
|
|
849
|
+
return;
|
|
850
|
+
}
|
|
851
|
+
|
|
852
|
+
this.createIframe(url, "if");
|
|
853
|
+
url = url + "/";
|
|
854
|
+
|
|
855
|
+
base = this.encode(value).split("");
|
|
856
|
+
for (i = 0; i < base.length; i++) {
|
|
857
|
+
url = url + base[i];
|
|
858
|
+
this.createIframe(url, "if" + i);
|
|
859
|
+
}
|
|
860
|
+
|
|
861
|
+
// - signifies the end of our data
|
|
862
|
+
url = url + "-";
|
|
863
|
+
this.createIframe(url, "if_");
|
|
864
|
+
} else {
|
|
865
|
+
// omg you got csspwn3d
|
|
866
|
+
if (this.hasVisited(url)) {
|
|
867
|
+
url = url + "/";
|
|
868
|
+
|
|
869
|
+
while (letter !== "-" && found === 1) {
|
|
870
|
+
found = 0;
|
|
871
|
+
for (i = 0; i < baseElems.length; i++) {
|
|
872
|
+
if (this.hasVisited(url + baseElems[i])) {
|
|
873
|
+
letter = baseElems[i];
|
|
874
|
+
if (letter !== "-") {
|
|
875
|
+
val = val + letter;
|
|
624
876
|
}
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
this.fromHex = function (str) {
|
|
631
|
-
var r = "",
|
|
632
|
-
e = str.length,
|
|
633
|
-
s;
|
|
634
|
-
while (e >= 0) {
|
|
635
|
-
s = e - 2;
|
|
636
|
-
r = String.fromCharCode("0x" + str.substring(s, e)) + r;
|
|
637
|
-
e = s;
|
|
638
|
-
}
|
|
639
|
-
return r;
|
|
640
|
-
};
|
|
641
|
-
|
|
642
|
-
/* create our anchor tag */
|
|
643
|
-
var _link = this.createElem("a", "_ec_rgb_link"),
|
|
644
|
-
/* for monitoring */
|
|
645
|
-
created_style,
|
|
646
|
-
/* create a custom style tag for the specific link. Set the CSS visited selector to a known value */
|
|
647
|
-
_cssText = "#_ec_rgb_link:visited{display:none;color:#FF0000}",
|
|
648
|
-
style;
|
|
649
|
-
|
|
650
|
-
/* Methods for IE6, IE7, FF, Opera, and Safari */
|
|
651
|
-
try {
|
|
652
|
-
created_style = 1;
|
|
653
|
-
style = document.createElement("style");
|
|
654
|
-
if (style.styleSheet) {
|
|
655
|
-
style.styleSheet.innerHTML = _cssText;
|
|
656
|
-
} else if (style.innerHTML) {
|
|
657
|
-
style.innerHTML = _cssText;
|
|
658
|
-
} else {
|
|
659
|
-
style.appendChild(document.createTextNode(_cssText));
|
|
877
|
+
url = url + letter;
|
|
878
|
+
found = 1;
|
|
879
|
+
break;
|
|
880
|
+
}
|
|
660
881
|
}
|
|
661
|
-
|
|
662
|
-
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
// lolz
|
|
885
|
+
return this.decode(val);
|
|
663
886
|
}
|
|
887
|
+
}
|
|
888
|
+
};
|
|
664
889
|
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
890
|
+
this.createElem = function (type, name, append) {
|
|
891
|
+
var el;
|
|
892
|
+
if (name !== undefined && document.getElementById(name)) {
|
|
893
|
+
el = document.getElementById(name);
|
|
894
|
+
} else {
|
|
895
|
+
el = document.createElement(type);
|
|
896
|
+
}
|
|
897
|
+
el.style.visibility = "hidden";
|
|
898
|
+
el.style.position = "absolute";
|
|
899
|
+
|
|
900
|
+
if (name) {
|
|
901
|
+
el.setAttribute("id", name);
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
if (append) {
|
|
905
|
+
document.body.appendChild(el);
|
|
906
|
+
}
|
|
907
|
+
return el;
|
|
908
|
+
};
|
|
670
909
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
document.body.appendChild(_link);
|
|
677
|
-
|
|
678
|
-
/* add the link to the DOM and save the visible computed color */
|
|
679
|
-
var color;
|
|
680
|
-
if (document.defaultView) {
|
|
681
|
-
color = document.defaultView.getComputedStyle(_link, null).getPropertyValue("color");
|
|
682
|
-
} else {
|
|
683
|
-
color = _link.currentStyle.color;
|
|
684
|
-
}
|
|
685
|
-
return color;
|
|
686
|
-
};
|
|
687
|
-
|
|
688
|
-
this._testURL = function (url, no_color) {
|
|
689
|
-
var color = this._getRGB(url);
|
|
690
|
-
|
|
691
|
-
/* check to see if the link has been visited if the computed color is red */
|
|
692
|
-
if (color === "rgb(255, 0, 0)" || color === "#ff0000") {
|
|
693
|
-
return 1;
|
|
694
|
-
} else if (no_color && color !== no_color) {
|
|
695
|
-
/* if our style trick didn't work, just compare default style colors */
|
|
696
|
-
return 1;
|
|
697
|
-
}
|
|
698
|
-
/* not found */
|
|
699
|
-
return 0;
|
|
700
|
-
};
|
|
910
|
+
this.createIframe = function (url, name) {
|
|
911
|
+
var el = this.createElem("iframe", name, 1);
|
|
912
|
+
el.setAttribute("src", url);
|
|
913
|
+
return el;
|
|
914
|
+
};
|
|
701
915
|
|
|
916
|
+
// wait for our swfobject to appear (swfobject.js to load)
|
|
917
|
+
var waitForSwf = this.waitForSwf = function (i) {
|
|
918
|
+
if (i === undefined) {
|
|
919
|
+
i = 0;
|
|
920
|
+
} else {
|
|
921
|
+
i++;
|
|
922
|
+
}
|
|
923
|
+
|
|
924
|
+
// wait for ~2 seconds for swfobject to appear
|
|
925
|
+
if (i < _ec_tests && typeof swfobject === "undefined") {
|
|
926
|
+
setTimeout(function () {
|
|
927
|
+
waitForSwf(i);
|
|
928
|
+
}, 200);
|
|
929
|
+
}
|
|
702
930
|
};
|
|
703
|
-
|
|
931
|
+
|
|
932
|
+
this.<%= Evercookie.js_class %>_cookie = function (name, value) {
|
|
933
|
+
if (value !== undefined) {
|
|
934
|
+
// expire the cookie first
|
|
935
|
+
document.cookie = name + "=; expires=Mon, 20 Sep 2010 00:00:00 UTC; path=/; domain=" + _ec_domain;
|
|
936
|
+
document.cookie = name + "=" + value + "; expires=Tue, 31 Dec 2030 00:00:00 UTC; path=/; domain=" + _ec_domain;
|
|
937
|
+
} else {
|
|
938
|
+
return this.getFromStr(name, document.cookie);
|
|
939
|
+
}
|
|
940
|
+
};
|
|
941
|
+
|
|
942
|
+
// get value from param-like string (eg, "x=y&name=VALUE")
|
|
943
|
+
this.getFromStr = function (name, text) {
|
|
944
|
+
if (typeof text !== "string") {
|
|
945
|
+
return;
|
|
946
|
+
}
|
|
947
|
+
var nameEQ = name + "=",
|
|
948
|
+
ca = text.split(/[;&]/),
|
|
949
|
+
i, c;
|
|
950
|
+
for (i = 0; i < ca.length; i++) {
|
|
951
|
+
c = ca[i];
|
|
952
|
+
while (c.charAt(0) === " ") {
|
|
953
|
+
c = c.substring(1, c.length);
|
|
954
|
+
}
|
|
955
|
+
if (c.indexOf(nameEQ) === 0) {
|
|
956
|
+
return c.substring(nameEQ.length, c.length);
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
};
|
|
960
|
+
|
|
961
|
+
this.getHost = function () {
|
|
962
|
+
return window.location.host.replace(/:\d+/, '');
|
|
963
|
+
};
|
|
964
|
+
|
|
965
|
+
this.toHex = function (str) {
|
|
966
|
+
var r = "",
|
|
967
|
+
e = str.length,
|
|
968
|
+
c = 0,
|
|
969
|
+
h;
|
|
970
|
+
while (c < e) {
|
|
971
|
+
h = str.charCodeAt(c++).toString(16);
|
|
972
|
+
while (h.length < 2) {
|
|
973
|
+
h = "0" + h;
|
|
974
|
+
}
|
|
975
|
+
r += h;
|
|
976
|
+
}
|
|
977
|
+
return r;
|
|
978
|
+
};
|
|
979
|
+
|
|
980
|
+
this.fromHex = function (str) {
|
|
981
|
+
var r = "",
|
|
982
|
+
e = str.length,
|
|
983
|
+
s;
|
|
984
|
+
while (e >= 0) {
|
|
985
|
+
s = e - 2;
|
|
986
|
+
r = String.fromCharCode("0x" + str.substring(s, e)) + r;
|
|
987
|
+
e = s;
|
|
988
|
+
}
|
|
989
|
+
return r;
|
|
990
|
+
};
|
|
991
|
+
|
|
992
|
+
/**
|
|
993
|
+
* css history knocker (determine what sites your visitors have been to)
|
|
994
|
+
*
|
|
995
|
+
* originally by Jeremiah Grossman
|
|
996
|
+
* http://jeremiahgrossman.blogspot.com/2006/08/i-know-where-youve-been.html
|
|
997
|
+
*
|
|
998
|
+
* ported to additional browsers by Samy Kamkar
|
|
999
|
+
*
|
|
1000
|
+
* compatible with ie6, ie7, ie8, ff1.5, ff2, ff3, opera, safari, chrome, flock
|
|
1001
|
+
*
|
|
1002
|
+
* - code@samy.pl
|
|
1003
|
+
*/
|
|
1004
|
+
this.hasVisited = function (url) {
|
|
1005
|
+
if (this.no_color === -1) {
|
|
1006
|
+
var no_style = this._getRGB("http://never-visited.com", -1);
|
|
1007
|
+
if (no_style === -1) {
|
|
1008
|
+
this.no_color = this._getRGB("http://this-" + Math.floor(Math.random() * 9999999) + "rand.com");
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
|
|
1012
|
+
// did we give full url?
|
|
1013
|
+
if (url.indexOf("https:") === 0 || url.indexOf("http:") === 0) {
|
|
1014
|
+
return this._testURL(url, this.no_color);
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
// if not, just test a few diff types if (exact)
|
|
1018
|
+
return this._testURL("http://" + url, this.no_color) ||
|
|
1019
|
+
this._testURL("https://" + url, this.no_color) ||
|
|
1020
|
+
this._testURL("http://www." + url, this.no_color) ||
|
|
1021
|
+
this._testURL("https://www." + url, this.no_color);
|
|
1022
|
+
};
|
|
1023
|
+
|
|
1024
|
+
/* create our anchor tag */
|
|
1025
|
+
var _link = this.createElem("a", "_ec_rgb_link"),
|
|
1026
|
+
/* for monitoring */
|
|
1027
|
+
created_style,
|
|
1028
|
+
/* create a custom style tag for the specific link. Set the CSS visited selector to a known value */
|
|
1029
|
+
_cssText = "#_ec_rgb_link:visited{display:none;color:#FF0000}",
|
|
1030
|
+
style;
|
|
1031
|
+
|
|
1032
|
+
/* Methods for IE6, IE7, FF, Opera, and Safari */
|
|
1033
|
+
try {
|
|
1034
|
+
created_style = 1;
|
|
1035
|
+
style = document.createElement("style");
|
|
1036
|
+
if (style.styleSheet) {
|
|
1037
|
+
style.styleSheet.innerHTML = _cssText;
|
|
1038
|
+
} else if (style.innerHTML) {
|
|
1039
|
+
style.innerHTML = _cssText;
|
|
1040
|
+
} else {
|
|
1041
|
+
style.appendChild(document.createTextNode(_cssText));
|
|
1042
|
+
}
|
|
1043
|
+
} catch (e) {
|
|
1044
|
+
created_style = 0;
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
/* if test_color, return -1 if we can't set a style */
|
|
1048
|
+
this._getRGB = function (u, test_color) {
|
|
1049
|
+
if (test_color && created_style === 0) {
|
|
1050
|
+
return -1;
|
|
1051
|
+
}
|
|
1052
|
+
|
|
1053
|
+
/* create the new anchor tag with the appropriate URL information */
|
|
1054
|
+
_link.href = u;
|
|
1055
|
+
_link.innerHTML = u;
|
|
1056
|
+
// not sure why, but the next two appendChilds always have to happen vs just once
|
|
1057
|
+
document.body.appendChild(style);
|
|
1058
|
+
document.body.appendChild(_link);
|
|
1059
|
+
|
|
1060
|
+
/* add the link to the DOM and save the visible computed color */
|
|
1061
|
+
var color;
|
|
1062
|
+
if (document.defaultView) {
|
|
1063
|
+
color = document.defaultView.getComputedStyle(_link, null).getPropertyValue("color");
|
|
1064
|
+
} else {
|
|
1065
|
+
color = _link.currentStyle.color;
|
|
1066
|
+
}
|
|
1067
|
+
return color;
|
|
1068
|
+
};
|
|
1069
|
+
|
|
1070
|
+
this._testURL = function (url, no_color) {
|
|
1071
|
+
var color = this._getRGB(url);
|
|
1072
|
+
|
|
1073
|
+
/* check to see if the link has been visited if the computed color is red */
|
|
1074
|
+
if (color === "rgb(255, 0, 0)" || color === "#ff0000") {
|
|
1075
|
+
return 1;
|
|
1076
|
+
} else if (no_color && color !== no_color) {
|
|
1077
|
+
/* if our style trick didn't work, just compare default style colors */
|
|
1078
|
+
return 1;
|
|
1079
|
+
}
|
|
1080
|
+
/* not found */
|
|
1081
|
+
return 0;
|
|
1082
|
+
};
|
|
1083
|
+
|
|
1084
|
+
};
|
|
1085
|
+
|
|
1086
|
+
window._<%= Evercookie.js_class %>_flash_var = _<%= Evercookie.js_class %>_flash_var;
|
|
1087
|
+
/**
|
|
1088
|
+
* Because Evercookie is a class, it should has first letter in capital
|
|
1089
|
+
* Keep first letter in small for legacy purpose
|
|
1090
|
+
* @expose Evercookie
|
|
1091
|
+
*/
|
|
1092
|
+
window.<%= Evercookie.js_class %> = <%= Evercookie.js_class %>;
|
|
704
1093
|
}(window));
|
|
1094
|
+
}catch(ex){}
|