Bug Tracker

Opened 7 years ago

Closed 6 years ago

#14001 closed feature (notabug)

Easy context switching (temporarily load in an iFrame)

Reported by: timmywil Owned by:
Priority: low Milestone: None
Component: core Version: 1.10.1
Keywords: 1.11-discuss Cc:
Blocked by: Blocking:

Description (last modified by timmywil)

From Mr. Diego Perini =>

For ages I have been wanting to load jQuery in a temporary IFRAME then moving it to the main browsing context and finally remove the IFRAME used for loading.

Since the IFRAME is going to disappear all the method calls executed in that context or not explicitly scoped will fail and return errors (for example setTimeout => window.setTimeout and parseFloat => window.parseFloat etc.).

To make this work I need the patches you can see in the attached file.

It seems to me none of these changes will introduce incompatibilities.

Can you have a look and tell me if this would be possible?

Attachments (1)

jquery-iframe-patch.diff (6.4 KB) - added by timmywil 7 years ago.

Download all attachments as: .zip

Change History (12)

Changed 7 years ago by timmywil

Attachment: jquery-iframe-patch.diff added

comment:1 Changed 7 years ago by timmywil

Component: unfiledcore
Keywords: 1.11-discuss added
Priority: undecidedlow
Status: newopen

I've recommended Diego make a pull request. Just wanted to get the team's thoughts. I think it's plausible, but it would be good to see a use case in action.

comment:2 Changed 7 years ago by timmywil

Description: modified (diff)

comment:3 Changed 7 years ago by timmywil

Description: modified (diff)

comment:4 Changed 7 years ago by dmethvin

If jQuery is loaded in an iframe, all the constructors such as Array or Object will belong to the iframe. That will cause issues if there are checks such as thing.constructor === Array when thing was created in the parent. I don't know if that may affect our code or client code, especially for oldIE which is very cranky about those things. Did all unit tests pass after this patch?

There was a thread going on at http://forum.jquery.com/topic/save-the-jquery-factory-reuse-it-in-frames-no-2nd-network-request to get the unit tests working in a similar situation but it seems to have stalled.

I think it may be a good idea to explicitly scope things to our internal window, especially for non-browser environments, but that is only part of the proposal.

Last edited 7 years ago by dmethvin (previous) (diff)

comment:5 Changed 7 years ago by gibson042

Sending the top level IIFE frameElement && /^loader/.test(frameElement.name) ? parent : this instead of window, aside from the obvious concerns like "frameElement is not defined" and "WTF is 'loader'?", will screw with non-browser environments like jsdom.

comment:6 Changed 7 years ago by jaubourg

I don't wanna raise the deads but wouldn't it be time to give newInstance another go? For those who never heard of it, the main jQuery closure was referenced as a newInstance method. So we had something like:

window.jQuery = ( function newInstance( window ) {

    var jQuery = { /*...*/ };

    jQuery.newInstance = newInstance;

    return jQuery;

} )( window );

It always creates a fresh new instance of jQuery (no plugins) and it was faster than sub while re-performing the support tests.

Bonus point: we could publish the newInstance main closure as an official npm module which would solve a lot of problems we have in that env.

comment:7 Changed 7 years ago by diego.perini@…

@dave, thank your for that link, it shows there is a demand for that, very similar in scope to the changes proposed in this patch. As you have noticed these are simple scoping changes that will probably also benefit headless environments, and they are innocuous (tests always needed though).

Maybe there are others like those that I couldn't find during my tests.

The last diff line in that patch, related to the "frameELement" property, was unintentionally left in and should not be considered part of this request. It was just part of my testing and not yet part of this proposal.

@gibson042, can you tell me more about the "frameElement is not defined" error you get related to this standard property of the host browsing context ?

That line (pass "parent" instead of "window") would have effect only when explicitly loaded in an iframe having its name string starting with "loader".

My request was limited to explicitly scoping methods to the internal "window".

Though, since it slipped in, it would be good for me to have some feedback on that "frameElement" trickery, I currently have other alternatives and ideas for that.

comment:8 Changed 7 years ago by anonymous

@jaubourg

that's the way I am currently using to retrieve the original source code by explicitly naming the IFE and saving it internally or externally somewhere.

The same could be achieve by getting the "arguments.callee" but that would be a violation when "use strict"; is enforced in user code.

Also in my current testing I am saving names, references and strings of code in an two level deeper property of the host context, namely I use "window.navigator.modules" as my namespace. This also leads to 0 globals.

While I am not sure this is everybody's objective, I swear I am trying to do my best to avoid breaking jQuery for others. I am sure both objectives are possible without too much effort.

comment:9 Changed 7 years ago by diego.perini@…

Just wanted to say that the previous anonymous comment to @jaubourg is from me. I forgot to set the user name and I am not able to change it.

-- Diego

comment:10 Changed 6 years ago by diego

Here are the list of object types, global/window properties and methods that need to be explicitly scoped in code to allow new instances to work across browser contexts.

object_types = 'Boolean|Number|String|Function|Object|Array|RegExp|Date|Math|Error';

global_props = 'Infinity|NaN|undefined';

global_methods = 'eval|escape|unescape|decodeURI|decodeURIComponent|encodeURI|encodeURIComponent|parseInt|parseFloat|isFinite|isNaN';

window_props = 'closed|defaultStatus|document|frames|history|length|location|name|navigator|opener|parent|screen|self|status|top|innerHeight|innerWidth|outerHeight|outerWidth|pageXOffset|pageYOffset|screenLeft|screenTop|screenX|screenY';

window_methods = 'alert|blur|focus|open|close|confirm|prompt|print|moveBy|moveTo|resizeBy|resizeTo|scroll|scrollBy|ScrollTo|clearTimeout|setTimeout|clearInterval|setInterval';

If we had access to the original source of the generating Javascript code we would not need to explicitly scope each method/property, however explicitly scoping will allow extending jQuery with plugin/modules and have new instances include the needed plugin/modules.

comment:11 Changed 6 years ago by dmethvin

Resolution: notabug
Status: openclosed

It's interesting, but nobody's taken it up as a cause and I can also see possible issues with use in environments like node.js. Probably better if someone could experiment a bit and come up with compelling use cases.

Note: See TracTickets for help on using tickets.