@@ -6,56 +6,59 @@ if (typeof fdom === 'undefined') {
66fdom . link = fdom . link || { } ;
77
88/**
9- * A port providing message transport between two freedom contexts via iTabs .
10- * @class link.Tab
9+ * A port providing message transport between two freedom contexts via iBackgroundFrames .
10+ * @class link.BackgroundFrame
1111 * @extends Link
1212 * @uses handleEvents
1313 * @constructor
1414 */
15- fdom . link . Tab = function ( ) {
15+ fdom . link . BackgroundFrame = function ( ) {
1616 fdom . Link . call ( this ) ;
17+ if ( typeof hiddenWindow !== 'undefined' ) {
18+ this . document = hiddenWindow . document ;
19+ }
1720} ;
1821
1922/**
20- * Start this port by listening or creating a tab .
23+ * Start this port by listening or creating a frame .
2124 * @method start
2225 * @private
2326 */
24- fdom . link . Tab . prototype . start = function ( ) {
27+ fdom . link . BackgroundFrame . prototype . start = function ( ) {
2528 if ( this . config . moduleContext ) {
2629 this . config . global . DEBUG = true ;
2730 this . setupListener ( ) ;
2831 this . src = 'in' ;
2932 } else {
30- this . setupTab ( ) ;
33+ this . setupBackgroundFrame ( ) ;
3134 this . src = 'out' ;
3235 }
3336} ;
3437
3538/**
36- * Stop this port by deleting the tab .
39+ * Stop this port by deleting the frame .
3740 * @method stop
3841 * @private
3942 */
40- fdom . link . Tab . prototype . stop = function ( ) {
41- // Function is determined by setupListener or setupTab as appropriate.
43+ fdom . link . BackgroundFrame . prototype . stop = function ( ) {
44+ // Function is determined by setupListener or setupBackgroundFrame as appropriate.
4245} ;
4346
4447/**
4548 * Get the textual description of this port.
4649 * @method toString
4750 * @return {String } the description of this port.
4851 */
49- fdom . link . Tab . prototype . toString = function ( ) {
50- return "[Tab " + this . id + "]" ;
52+ fdom . link . BackgroundFrame . prototype . toString = function ( ) {
53+ return "[BackgroundFrame " + this . id + "]" ;
5154} ;
5255
5356/**
5457 * Set up a global listener to handle incoming messages to this
5558 * freedom.js context.
5659 * @method setupListener
5760 */
58- fdom . link . Tab . prototype . setupListener = function ( ) {
61+ fdom . link . BackgroundFrame . prototype . setupListener = function ( ) {
5962 var onMsg = function ( msg ) {
6063 if ( msg . data . src !== 'in' ) {
6164 this . emitMessage ( msg . data . flow , msg . data . message ) ;
@@ -71,72 +74,66 @@ fdom.link.Tab.prototype.setupListener = function() {
7174} ;
7275
7376/**
74- * Set up an iTab with an isolated freedom.js context inside.
75- * @method setupTab
77+ * Set up an iBackgroundFrame with an isolated freedom.js context inside.
78+ * @method setupBackgroundFrame
7679 */
77- fdom . link . Tab . prototype . setupTab = function ( ) {
78- var worker , onMsg ;
79- worker = this . makeTab ( this . config . src , this . config . inject ) ;
80+ fdom . link . BackgroundFrame . prototype . setupBackgroundFrame = function ( ) {
81+ var frame , onMsg ;
82+ frame = this . makeBackgroundFrame ( this . config . src , this . config . inject ) ;
8083
81- onMsg = function ( tab , msg ) {
84+ if ( ! this . document . body ) {
85+ this . document . appendChild ( this . document . createElement ( "body" ) ) ;
86+ }
87+ this . document . body . appendChild ( frame ) ;
88+
89+ onMsg = function ( frame , msg ) {
8290 if ( ! this . obj ) {
83- this . obj = tab ;
91+ this . obj = frame ;
8492 this . emit ( 'started' ) ;
8593 }
8694 if ( msg . data . src !== 'out' ) {
8795 this . emitMessage ( msg . data . flow , msg . data . message ) ;
8896 }
89- } . bind ( this , worker ) ;
97+ } . bind ( this , frame . contentWindow ) ;
9098
91- worker . port . on ( 'message' , onMsg ) ;
99+ frame . contentWindow . addEventListener ( 'message' , onMsg , true ) ;
92100 this . stop = function ( ) {
93- worker . destroy ( ) ;
101+ frame . contentWindow . removeEventListener ( 'message' , onMsg , true ) ;
94102 if ( this . obj ) {
95103 delete this . obj ;
96104 }
105+ frame . src = "about:blank" ;
106+ this . document . body . removeChild ( frame ) ;
97107 } ;
98108} ;
99109
100- // The toString version of this function will be used as a content script
101- fdom . link . contentScript = function contentScript ( ) {
102- var window = unsafeWindow ;
103- window . addEventListener ( "message" , self . port . emit . bind ( self . port , "message" ) ) ;
104- self . port . on ( "message" , function ( message ) {
105- window . postMessage ( message , "*" ) ;
106- } ) ;
107- } ;
108-
109110/**
110- * Make tabs to replicate freedom isolation without web-workers.
111- * iTab isolation is non-standardized, and access to the DOM within tabs
111+ * Make frames to replicate freedom isolation without web-workers.
112+ * iBackgroundFrame isolation is non-standardized, and access to the DOM within frames
112113 * means that they are insecure. However, debugging of webworkers is
113114 * painful enough that this mode of execution can be valuable for debugging.
114- * @method makeTab
115+ * @method makeBackgroundFrame
115116 */
116- fdom . link . Tab . prototype . makeTab = function ( src ) {
117- debugger ;
118- var tab ,
117+ fdom . link . BackgroundFrame . prototype . makeBackgroundFrame = function ( src , inject ) {
118+ var frame = this . document . createElement ( 'iframe' ) ,
119119 extra = '' ,
120120 loader ,
121- worker ,
122121 blob ;
123122 // TODO(willscott): add sandboxing protection.
124123
125124 // TODO(willscott): survive name mangling.
126- src = src . replace ( 'portType: "Worker"' , 'portType: "Tab"' ) ;
125+ src = src . replace ( 'portType: "Worker"' , 'portType: "BackgroundFrame"' ) ;
126+ if ( inject ) {
127+ extra = '<script src="' + inject + '" onerror="' +
128+ 'throw new Error(\'Injection of ' + inject + ' Failed!\');' +
129+ '"></script>' ;
130+ }
127131 loader = '<html>' + extra + '<script src="' +
128132 fdom . util . forceModuleContext ( src ) + '"></script></html>' ;
129133 blob = fdom . util . getBlob ( loader , 'text/html' ) ;
130- tab = fftabs . open ( { url : fdom . util . getURL ( blob ) ,
131- onLoad : function onLoad ( tab ) {
132- worker = tab . attach ( {
133- contentScript : "(" +
134- fdom . link . contentScript . toString ( ) +
135- ")()"
136- } ) ;
137- } } ) ;
138-
139- return worker ;
134+ frame . src = fdom . util . getURL ( blob ) ;
135+
136+ return frame ;
140137} ;
141138
142139/**
@@ -146,15 +143,9 @@ fdom.link.Tab.prototype.makeTab = function(src) {
146143 * @param {String } flow the channel/flow of the message.
147144 * @param {Object } message The Message.
148145 */
149- fdom . link . Tab . prototype . deliverMessage = function ( flow , message ) {
150- if ( this . obj . port ) { // We are in the root context
146+ fdom . link . BackgroundFrame . prototype . deliverMessage = function ( flow , message ) {
147+ if ( this . obj ) {
151148 //fdom.debug.log('message sent to worker: ', flow, message);
152- this . obj . port . emit ( "message" , {
153- src : this . src ,
154- flow : flow ,
155- message : message
156- } ) ;
157- } else if ( this . obj . postMessage ) { // We are in a module
158149 this . obj . postMessage ( {
159150 src : this . src ,
160151 flow : flow ,
@@ -164,3 +155,4 @@ fdom.link.Tab.prototype.deliverMessage = function(flow, message) {
164155 this . once ( 'started' , this . onMessage . bind ( this , flow , message ) ) ;
165156 }
166157} ;
158+
0 commit comments