define(["lib/jquery", "lib/underscore", "common/util/check", "common/network/dispatcher", "common/util/binding_list"], function($, _, check, Dispatcher, BindingList) { "use strict"; var postInitCallbacks = BindingList(); /** * @privconstructor * @class * Lens.Embed allows you to embed a Lens app inside another Lens app. You * can then pass messages to the embedded app. * * @property {HTMLIFrameElement} iframe * The IFrame that contains the embedded app. Insert this into the DOM. * Do not use `postMessage` to send messages to the embedded Lens app. * Instead, use the dispatcher for this Embed. * * @property {Dispatcher} dispatcher * A {@link Dispatcher} that allows for communication between this app * and the embedded app. * * @memberOf Lens */ var Embed = function(iframe) { /** @alias Lens.MyClass.prototype */ var self = {}; iframe = $(iframe).data("lens-embed", self)[0]; var dispatcher = Dispatcher(Dispatcher._PostMessageTransport(iframe)); Object.defineProperty(self, "iframe", { get: function() { return iframe; } }); Object.defineProperty(self, "dispatcher", { get: function() { return dispatcher; } }); Object.freeze(self); postInitCallbacks.callAll(self); return self; }; _.extend(Embed, /** @lends Lens.Embed */ { /** * Embeds another Lens app inside this one, given the name of an app. * * @param {String} name Name of the app, such as `scrapbook` or * `look-and-feel.demos` * * @return {Embed} * */ app: function(name) { check(name, String); return Embed.url("http://" + name + ".lens"); }, /** * Embeds another Lens app inside this one, given the URL of an app. * * @param {String} name URL of the app, such as `http://launcher.lens/` * * @return {Embed} */ url: function(url) { check(url, String); return Embed($("<iframe />", {src: url})); }, /** * Connects to a Lens app already running in an iframe. * * @param {HTMLIFrameElement | String | jQuery} el * An iFrame element, CSS selector, or jQuery object. * * @return {Embed} */ iframe: function(el) { el = $(el); if((el.length === 0) || !(el[0] instanceof HTMLIFrameElement)) { throw "Argument error: argument to Lens.Embed.iframe() was not an iFrame"; } return Embed(el); }, /** * A {@link Dispatcher} that allows communication with this * app's parent app. Returns null if this app is not embedded. * @type {Dispatcher} */ parentDispatcher: null, /** * Adds a callback to be called on each newly-created embedded lens. * This can be used to ensure that all embedded Lenses have access * to a particular RPC on the parent. * @param {Function} fn The function to call. * @return {Binding} A binding that can be cleared to cancel the callback. * @private */ _addPostInitCallback: function(fn) { return postInitCallbacks.add(fn); } }); if(window.parent !== window.self) { Embed.parentDispatcher = Dispatcher(Dispatcher._PostMessageTransport(window.parent)); } Object.freeze(Embed); Lens._addMember(Embed, "Embed"); return Embed; });