Last modified: 2014-02-25 19:29:22 UTC
Currently MediaHandlers add JS using the method parserTransformHook, which one could either directly add modules to the $parser object, or add an OuputHook, to mess with $wgOut later on. This is not that good an interface. Besides being rather indirect way to add resource loader modules, its (almost) impossible to trigger this from a special page where we call transform directly, and don't have a $parser object that is parsing something. I'm not sure what a better interface would be. My first thought would be that responsibility for this should not be in MediaHandler, but instead be in the MediaTransformObject. The mto could at least have a method getModules() which special pages could call, or perhaps something like $mto->addModulesToOutput( $this->getOutput() ); Still less then ideal since people will be bound to forget to call it as most media types don't need js, but still would be much better than current situation.
A couple possible scenarios: 1) Always load just enough code to check for if you need to do runtime JS transformations In this scenario, every page that can show wikitext should have at least a tiny JS module loaded that hooks into an event that is called on load and again every time new parsed wikitext output is added to a page (such as by a preview, or a dialog box, or whatever). This might be a very tiny piece of code that just asynchronously fires off a load of a fuller module, such as something that adds player controls to a video or sets up interactive rendering of a molecule on a canvas, or whatever, when it encounters its targets (and otherwise does nothing). Advantages: * can use same code & event for initial load and new loads? * defers extra media modules until use * doesn't require recording modules used per page 2) Implement any media viewers more complicated than a simple element without scripting via an <iframe> Advantages: * the iframe content rendering worries about module loading, the parent page can ignore it totally * makes exposing those media for external embedding trivial, as we'd be doing the exact same thing we do in our content context
Using iframes would also decrease our attack surface significantly, if we use a separate domain for them. Plus it would make it simple to treat local and external files in a uniform way. That would restrict what the JS code is allowed to do, but a player probably doesn't need access to anything outside its own frame anyway.
(In reply to comment #2) > Using iframes would also decrease our attack surface significantly, if we > use a > separate domain for them. Plus it would make it simple to treat local and > external files in a uniform way. That would restrict what the JS code is > allowed to do, but a player probably doesn't need access to anything outside > its own frame anyway. Hmm, that might get in the way of our current click the video and get a pop up dialog that has the video on it
Within kaltura proper we do sandbox the player in an iframe, but we still make use of parent javascript access for synchronous api ( postMessage is asynchronous ) Also HTML fullscreen on iPads and IE's we need parent page access to adjust the iframe layout to take up full browser page space. The kaltura player uses a friendly ( same domain ) iframe, but this does not reduce attack surface, since you can just jump up to the parent frame and run any JS you want, furthermore you would have to structure things to server the player iframe from another domain, to have any effect on 'attack surface'. Also, you need to do tricky iframe injection strategies [1] to support one click play on mobile chrome and iOS ( assuming we ever care about single click to play user experience ) [1] https://github.com/kaltura/mwEmbed/blob/master/kWidget/kWidget.js#L935 Thouse injection strategies only work for same domain iframes. And finally safari blocks cross domain iframe cookies, so any personalization / customization / private media playback has to be structured post "click" in iframe, or via url parameterization. Having a separate rendering / entry point, has its own sets of risks, that probably outweigh advantages of cross domain iframing the player. I recommend we use normal precautions of localization string and api based playback ( no more video payload injection )
(In reply to comment #4) > Within kaltura proper we do sandbox the player in an iframe, but we still > make > use of parent javascript access for synchronous api ( postMessage is > asynchronous ) Also HTML fullscreen on iPads and IE's we need parent page > access to adjust the iframe layout to take up full browser page space. > > The kaltura player uses a friendly ( same domain ) iframe, but this does not > reduce attack surface, since you can just jump up to the parent frame and run > any JS you want, furthermore you would have to structure things to server the > player iframe from another domain, to have any effect on 'attack surface'. The point here is more to centralize js - js gets loaded with the iframe so that we could avoid including the TMH loader js on all page loads, well at the same time not have to keep track of which pages have a video on them.