-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path_frame.js
139 lines (110 loc) · 3.75 KB
/
_frame.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/**
* Contains the code executed in the sandboxed frame under web-browser
*
* Tries to create a Web-Worker inside the frame and set up the
* communication between the worker and the parent window. Some
* browsers restrict creating a worker inside a sandboxed iframe - if
* this happens, the plugin initialized right inside the frame (in the
* same thread)
*/
var scripts = document.getElementsByTagName('script');
var thisScript = scripts[scripts.length-1];
var parentNode = thisScript.parentNode;
var __jailed__path__ = thisScript.src
.split('?')[0]
.split('/')
.slice(0, -1)
.join('/')+'/';
/**
* Initializes the plugin inside a webworker. May throw an exception
* in case this was not permitted by the browser.
*/
var initWebworkerPlugin = function() {
// creating worker as a blob enables import of local files
var blobCode = [
' self.addEventListener("message", function(m){ ',
' if (m.data.type == "initImport") { ',
' importScripts(m.data.url); ',
' self.postMessage({ ',
' type : "initialized", ',
' dedicatedThread : true ',
' }); ',
' } ',
' }); '
].join('\n');
var blobUrl = window.URL.createObjectURL(
new Blob([blobCode])
);
var worker = new Worker(blobUrl);
// telling worker to load _pluginWebWorker.js (see blob code above)
worker.postMessage({
type: 'initImport',
url: __jailed__path__ + '_pluginWebWorker.js'
});
// mixed content warning in Chrome silently skips worker
// initialization without exception, handling this with timeout
var fallbackTimeout = setTimeout(function() {
worker.terminate();
initIframePlugin();
}, 300);
// forwarding messages between the worker and parent window
worker.addEventListener('message', function(m) {
if (m.data.type == 'initialized') {
clearTimeout(fallbackTimeout);
}
parent.postMessage(m.data, '*');
});
window.addEventListener('message', function(m) {
worker.postMessage(m.data);
});
}
/**
* Creates plugin right in this iframe
*/
var initIframePlugin = function() {
// loads additional script into the frame
window.loadScript = function(path, sCb, fCb) {
var script = document.createElement('script');
script.src = path;
var clear = function() {
script.onload = null;
script.onerror = null;
script.onreadystatechange = null;
script.parentNode.removeChild(script);
currentErrorHandler = function(){};
}
var success = function() {
clear();
sCb();
}
var failure = function() {
clear();
fCb();
}
currentErrorHandler = failure;
script.onerror = failure;
script.onload = success;
script.onreadystatechange = function() {
var state = script.readyState;
if (state==='loaded' || state==='complete') {
success();
}
}
parentNode.appendChild(script);
}
// handles script loading error
// (assuming scripts are loaded one by one in the iframe)
var currentErrorHandler = function(){};
window.addEventListener('error', function(message) {
currentErrorHandler();
});
window.loadScript(
__jailed__path__ + '_pluginWebIframe.js',
function(){}, function(){}
);
}
try {
initWebworkerPlugin();
} catch(e) {
initIframePlugin();
}