Skip to content

Commit 55d378a

Browse files
committed
Cache and re-use iframe instead of inserting a new on on each call.
1 parent 5ddee01 commit 55d378a

File tree

1 file changed

+37
-28
lines changed

1 file changed

+37
-28
lines changed

index.js

Lines changed: 37 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
var indexOf = require('indexof');
22

3+
// cached iFrame instance, re-use for each runInContext Call.
4+
var iFrame = null;
5+
36
var Object_keys = function (obj) {
47
if (Object.keys) return Object.keys(obj)
58
else {
@@ -45,37 +48,43 @@ Context.prototype = {};
4548

4649
var Script = exports.Script = function NodeScript (code) {
4750
if (!(this instanceof Script)) return new Script(code);
51+
if(!iFrame) {
52+
iFrame = document.createElement('iframe');
53+
if (!iFrame.style) iFrame.style = {};
54+
iFrame.style.display = 'none';
55+
56+
document.body.appendChild(iFrame);
57+
}
4858
this.code = code;
59+
this.iFrame = iFrame;
4960
};
5061

5162
Script.prototype.runInContext = function (context) {
5263
if (!(context instanceof Context)) {
5364
throw new TypeError("needs a 'context' argument.");
5465
}
55-
56-
var iframe = document.createElement('iframe');
57-
if (!iframe.style) iframe.style = {};
58-
iframe.style.display = 'none';
59-
60-
document.body.appendChild(iframe);
61-
62-
var win = iframe.contentWindow;
66+
var win = this.iFrame.contentWindow;
67+
var winOriginal = Object_keys(win);
68+
let originalToRestore = [];
6369
var wEval = win.eval, wExecScript = win.execScript;
6470

65-
if (!wEval && wExecScript) {
66-
// win.eval() magically appears when this is called in IE:
67-
wExecScript.call(win, 'null');
68-
wEval = win.eval;
69-
}
70-
7171
forEach(Object_keys(context), function (key) {
72-
win[key] = context[key];
73-
});
74-
forEach(globals, function (key) {
75-
if (context[key]) {
76-
win[key] = context[key];
77-
}
72+
if(win[key] !== undefined) {
73+
let restore = {
74+
'key': key,
75+
'value': win[key]
76+
};
77+
originalToRestore.push(restore);
78+
}
79+
win[key] = context[key];
7880
});
81+
82+
if (!wEval && wExecScript) {
83+
// win.eval() magically appears when this is called in IE:
84+
wExecScript.call(win, 'null');
85+
wEval = win.eval;
86+
}
87+
7988

8089
var winKeys = Object_keys(win);
8190

@@ -86,18 +95,18 @@ Script.prototype.runInContext = function (context) {
8695
// updating existing context properties or new properties in the `win`
8796
// that was only introduced after the eval.
8897
if (key in context || indexOf(winKeys, key) === -1) {
89-
context[key] = win[key];
98+
if (indexOf(globals, key) === -1) context[key] = win[key];
99+
else defineProp(context, key, win[key]);
90100
}
101+
// delete win context of extra fields
102+
if (indexOf(winOriginal, key) === -1) delete win[key];
91103
});
92104

93-
forEach(globals, function (key) {
94-
if (!(key in context)) {
95-
defineProp(context, key, win[key]);
96-
}
105+
// restore context to original field values
106+
forEach(originalToRestore, function (orig) {
107+
win[orig.key] = orig.value;
97108
});
98-
99-
document.body.removeChild(iframe);
100-
109+
101110
return res;
102111
};
103112

0 commit comments

Comments
 (0)