UNPKG

@microsoft/sp-webpart-base

Version:

SharePoint Framework support for building web parts

708 lines 42.2 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var sp_core_library_1 = require("@microsoft/sp-core-library"); var sp_diagnostics_1 = require("@microsoft/sp-diagnostics"); var sp_http_base_1 = require("@microsoft/sp-http-base"); var sp_loader_1 = require("@microsoft/sp-loader"); var lodash = tslib_1.__importStar(require("@microsoft/sp-lodash-subset")); var sp_component_base_1 = require("@microsoft/sp-component-base"); var Flights_1 = require("../../common/Flights"); var KillSwitches_1 = require("../../common/KillSwitches"); var IIframedWebPartMessage_1 = require("../../core/IIframedWebPartMessage"); var IframedPropertyPane_module_scss_1 = tslib_1.__importDefault(require("./IframedPropertyPane.module.scss")); var ReservedIframeQueryParamKeys_1 = require("./ReservedIframeQueryParamKeys"); var sp_lodash_subset_1 = require("@microsoft/sp-lodash-subset"); var IframedWebPart_1 = require("../../core/iframedInterfaces/IframedWebPart"); var IBaseIframedWebPart_1 = require("../../core/iframedInterfaces/IBaseIframedWebPart"); var IframedAdaptiveCardExtensionWebPart_1 = require("../../core/iframedInterfaces/IframedAdaptiveCardExtensionWebPart"); var Strings_resx_1 = tslib_1.__importDefault(require("../../core/loc/Strings.resx")); var LOG_SOURCE = sp_diagnostics_1._LogSource.create('IframedWebPartController'); var WEBPART_IFRAME_ID_PREFIX = 'dom-isolated-webpart'; var PROPERTYPANE_IFRAME_ID = 'dom-isolated-property-pane'; var IFRAMED_PROPERTYPANE_CONTAINER_ID = 'spIFramePropertyPaneContainer'; var IframedWebPartController = /** @class */ (function () { function IframedWebPartController(host) { this._iframeSrcUrl = undefined; this._iframedWebparts = new Map(); this._host = host; this._ppIframeElement = undefined; this._iframeContextMap = new Map(); this._updateWebPartData = this._updateWebPartData.bind(this); this._updateWebPartDisplayMode = this._updateWebPartDisplayMode.bind(this); this._iframeEventListener = this._iframeEventListener.bind(this); window.addEventListener('message', this._iframeEventListener); } /** * Delete references an iframed web part. */ IframedWebPartController.prototype.deleteWebPart = function (instanceId) { this._iframeContextMap.delete(instanceId); sp_core_library_1.Validate.isNonemptyString(instanceId, 'instanceId'); var webPart = this._iframedWebparts.get(instanceId); // Send message to the iframed property pane if it exists. var iframePropertyPaneElement = document.getElementById(PROPERTYPANE_IFRAME_ID); if (iframePropertyPaneElement && iframePropertyPaneElement.contentWindow) { var messageToPropertyPane = { instanceId: instanceId, action: IIframedWebPartMessage_1.IframedWebPartAction.DeleteWebPart }; iframePropertyPaneElement.contentWindow.postMessage(messageToPropertyPane, webPart.url); } this.requestPropertyPaneAction('Close'); webPart.dispose(); this._iframedWebparts.delete(instanceId); }; /** * Get the instanceId's of all the iframed webparts. */ IframedWebPartController.prototype.getAllInstanceIds = function () { var instanceIds = []; this._iframedWebparts.forEach(function (value, key) { instanceIds.push(key); }); return instanceIds; }; /** * Send a message to the iframed webpart to notify that their container * has been resized. */ IframedWebPartController.prototype.notifyContainerResize = function (instanceId) { // @todo #VS0:617678 Add support for "notifyContrainerResize" }; IframedWebPartController.prototype.startDirtyBitTimer = function (instanceId) { // This lifecycle event is manually handled when a web part property is changed. }; /** * @param domainUrl - the domain from which the web part should be loaded. * Returns an iframe that points to a SpWebApplication that loads the webpart. * @param pageContext - Page context reference. * @param webPartManagerContext - web part manager context. */ IframedWebPartController.prototype.loadWebPart = function (domainUrl, pageContext, webPartManagerContext, isIsolatedACEWP) { this._iframeContextMap.set(webPartManagerContext.instanceId, webPartManagerContext); this._iframeSrcUrl = this._generateIframeSrcUrl(domainUrl, pageContext, webPartManagerContext); sp_core_library_1.Validate.isNotNullOrUndefined(webPartManagerContext.webPartData, 'webPartData'); var metadata = { origin: domainUrl, url: this._iframeSrcUrl, webPartData: webPartManagerContext.webPartData, webPartElementId: "".concat(WEBPART_IFRAME_ID_PREFIX, "-").concat(webPartManagerContext.instanceId), displayMode: webPartManagerContext.displayMode, addedFromPersistedData: !!webPartManagerContext.addedFromPersistedData, theme: undefined }; // This instanceId appears twice if we are loading the property pane of an already rendered // webpart, in that case we do not need to write twice. if (!this._iframedWebparts.has(webPartManagerContext.instanceId)) { // Fill in the initial values on the web part data if we are creating the web part's instance. if (!webPartManagerContext.addedFromPersistedData) { metadata.webPartData.dataVersion = '1.0'; // Note: Same instance id should be passed as 'newWebPartInstanceId' to the iframe. metadata.webPartData.instanceId = webPartManagerContext.instanceId; } if (!(0, KillSwitches_1.isIsolatedAdaptiveCardExtensionIframedPropertyPaneKSActivated)() && isIsolatedACEWP) { this._iframedWebparts.set(webPartManagerContext.instanceId, new IframedAdaptiveCardExtensionWebPart_1.IframedAdaptiveCardExtensionWebPart(this, webPartManagerContext.serviceScope || this._host.serviceScope, metadata)); } else { this._iframedWebparts.set(webPartManagerContext.instanceId, new IframedWebPart_1.IframedWebPart(this, webPartManagerContext.serviceScope || this._host.serviceScope, metadata)); if (sp_loader_1._SPLoaderFlights._isSafariIsolationEnabled()) { var iframe_1 = document.createElement('iframe'); iframe_1.id = metadata.webPartElementId; iframe_1.src = this._addFilteredQueryParamsFromHostPage(metadata.url); iframe_1.classList.add(IframedPropertyPane_module_scss_1.default.iframeWebPart); iframe_1.scrolling = 'no'; iframe_1.title = metadata.webPartData.title; if (!sp_core_library_1._BrowserUtilities.isUsingSecureBroker()) { if (!(0, KillSwitches_1.isPreventLateIframeRedirectKSActivated)()) { void sp_loader_1._IframeLoadRedirector.instance; } iframe_1.onload = function () { return sp_loader_1._IframeLoadRedirector.instance.confirmLoadOrRedirect(iframe_1.src); }; } if (!(0, KillSwitches_1.isIsolatedWebPartTabStopKSActivated)()) { iframe_1.tabIndex = 0; } var div = document.createElement('div'); div.appendChild(iframe_1); webPartManagerContext.domElement.appendChild(div); } else { webPartManagerContext.domElement.innerHTML = "<div>\n <iframe\n id=".concat(metadata.webPartElementId, "\n src=").concat(this._addFilteredQueryParamsFromHostPage(metadata.url), "\n class=").concat(IframedPropertyPane_module_scss_1.default.iframeWebPart, "\n scrolling=\"no\"\n ").concat(!(0, KillSwitches_1.isIsolatedWebPartTabStopKSActivated)() ? 'tabindex="0"' : '', "\n title=\"").concat(metadata.webPartData.title, "\"\n ></iframe>\n </div>"); } } } }; IframedWebPartController.prototype.assignIsolatedACEWP = function (instanceId, isolatedACEWP) { if (this._iframedWebparts.has(instanceId)) { var webPart = this._iframedWebparts.get(instanceId); if (webPart.type === IBaseIframedWebPart_1.IFRAMED_WEB_PART.isolatedACEWebPart) { webPart.webPart = isolatedACEWP; } } }; /** * To open a property pane for a web part that has been loaded into an iframe, we create a sibling dom element on the * page and render the property pane into it. We use the same method of loading an iframe with the addition of a * query parameter, 'openPropertyPane=true'. By default 'openPropertyPane' is undefined and thus false. * @param propertyPaneState - the desired state of the property pane. * @param instanceId - the instanceId of the corresponding web part. */ IframedWebPartController.prototype.requestPropertyPaneAction = function (propertyPaneState, instanceId) { sp_core_library_1.Validate.isNotNullOrUndefined(propertyPaneState, 'propertyPaneState'); switch (propertyPaneState) { case 'Open': case 'OpenDetails': sp_core_library_1.Validate.isNonemptyString(instanceId, 'instanceId'); if ((!(0, KillSwitches_1.isDynamicIframedPropertyPaneHandlingKSActivated)() && this._iframedPropertyPaneWebPartInstanceId !== instanceId) || !this._ppIframeElement) { // No-Iframe element is present on the page this._createPropertyPaneElement(instanceId, propertyPaneState === 'OpenDetails'); } this._showPropertyPane(instanceId, propertyPaneState); break; case 'Close': if (this._ppIframeElement) { this._hidePropertyPane(instanceId); } break; case 'Toggle': sp_core_library_1.Validate.isNonemptyString(instanceId, 'instanceId'); if (this._iframedPropertyPaneContainer && this._iframedPropertyPaneContainer.classList.contains(IframedPropertyPane_module_scss_1.default.showPane)) { this._hidePropertyPane(instanceId); } else { // Create the iframed property pane element if none exists. if ((!(0, KillSwitches_1.isDynamicIframedPropertyPaneHandlingKSActivated)() && this._iframedPropertyPaneWebPartInstanceId !== instanceId) || !this._iframedPropertyPaneContainer) { this._createPropertyPaneElement(instanceId); } this._showPropertyPane(instanceId, 'Open'); } break; case 'Refresh': sp_core_library_1.Validate.isNonemptyString(instanceId, 'instanceId'); this._refreshPropertyPane(instanceId); break; case 'Default': break; } }; /** * Returns the most recently saved WebPartData for the web part associated * with the 'instanceId'. */ IframedWebPartController.prototype.serialize = function (instanceId) { sp_core_library_1.Validate.isNonemptyString(instanceId, 'instanceId'); var metadata = this._iframedWebparts.get(instanceId); return metadata.webPartData; }; /** * Handles the ClientSideWebPartManager's request to set the displayMode for a web part * in an iframe. (Saves the displayMode and sends a message to the iframe window). */ IframedWebPartController.prototype.setDisplayMode = function (displayMode, instanceId) { sp_core_library_1.Validate.isNotNullOrUndefined(displayMode, 'displayMode'); sp_core_library_1.Validate.isNonemptyString(instanceId, 'instanceId'); var messageToRenderedWebPart = { instanceId: instanceId, action: IIframedWebPartMessage_1.IframedWebPartAction.SetDisplayMode, displayMode: displayMode }; // Save the display mode in case the web part has not yet rendered, after rendering has completed // a message will be sent to the IframedWebPartController requesting the 'displayMode'. var metadata = this._iframedWebparts.get(instanceId); metadata.displayMode = displayMode; // Send a message to the iframed window containing the rendered web part // No need to validate the iframe exists because it may not have been rendered yet if // this is the first time the page is loaded. var targetWindow = this._getCurrentIframeWebPartContentWindow(metadata.webPartElementId); if (targetWindow) { targetWindow.postMessage(messageToRenderedWebPart, metadata.url); } }; /** * Handles requests to set the theme for a web part in an iframe. */ IframedWebPartController.prototype.setTheme = function (theme, instanceId) { var metadata = this._iframedWebparts.get(instanceId); if (metadata.theme && (0, sp_lodash_subset_1.isEqual)(metadata.theme, theme)) { // we don't want to send unnecessary messages return; } var messageToRenderedWebPart = { instanceId: instanceId, action: IIframedWebPartMessage_1.IframedWebPartAction.SetTheme, theme: theme }; // Save the theme in case the web part has not yet rendered, after rendering has completed // a message will be sent to the IframedWebPartController requesting the 'theme'. metadata.theme = theme; // Send a message to the iframed window containing the rendered web part // No need to validate the iframe exists because it may not have been rendered yet if // this is the first time the page is loaded. var targetWindow = this._getCurrentIframeWebPartContentWindow(metadata.webPartElementId); if (targetWindow) { targetWindow.postMessage(messageToRenderedWebPart, metadata.url); } }; /** * Returns the url that loads the webpart with instanceId and componentId on the 'webPartManagerContext'. * @param domainUrl - the domain from which the web part should be loaded. * @param pageContext - Page context reference. * @param webPartManagerContext - web part manager context. */ IframedWebPartController.prototype._generateIframeSrcUrl = function (domainUrl, pageContext, webPartManagerContext) { var _a, _b; var isTeamsApp = sp_core_library_1._BrowserUtilities.isTeamsHosted(); var isUsingSecureBroker = isTeamsApp && sp_core_library_1._BrowserUtilities.isUsingSecureBroker(); var iframeSrcUrl; if (!isUsingSecureBroker) { iframeSrcUrl = "".concat(domainUrl, "/_layouts/15/webpart.aspx?"); } else { var domainAndPath = new URL(domainUrl); iframeSrcUrl = domainAndPath.pathname; if (!domainAndPath.pathname.endsWith('/')) { iframeSrcUrl += '/'; } iframeSrcUrl += "/_layouts/15/webpart.aspx?"; } // If the web part is being added from the persisted data it means that the web part instance // already exists on the page otherwise we are creating a new instance for the web part. if (webPartManagerContext.addedFromPersistedData) { iframeSrcUrl += "".concat(ReservedIframeQueryParamKeys_1.ReservedIframeQueryParamKeys.List, "=%7B"); iframeSrcUrl += ((_a = webPartManagerContext.isolatedItemContext) === null || _a === void 0 ? void 0 : _a.list) || pageContext.list.id; iframeSrcUrl += "%7D&".concat(ReservedIframeQueryParamKeys_1.ReservedIframeQueryParamKeys.Id, "="); iframeSrcUrl += ((_b = webPartManagerContext.isolatedItemContext) === null || _b === void 0 ? void 0 : _b.id) || pageContext.listItem.id; iframeSrcUrl += "&".concat(ReservedIframeQueryParamKeys_1.ReservedIframeQueryParamKeys.WebPartInstanceId, "="); iframeSrcUrl += webPartManagerContext.instanceId; } else { iframeSrcUrl += "".concat(ReservedIframeQueryParamKeys_1.ReservedIframeQueryParamKeys.NewWebPartInstanceId, "="); iframeSrcUrl += webPartManagerContext.instanceId; } iframeSrcUrl += "&".concat(ReservedIframeQueryParamKeys_1.ReservedIframeQueryParamKeys.ParentWindowOrigin, "="); iframeSrcUrl += window.location.origin; iframeSrcUrl += "&".concat(ReservedIframeQueryParamKeys_1.ReservedIframeQueryParamKeys.ComponentId, "="); iframeSrcUrl += webPartManagerContext.manifest.id; iframeSrcUrl += "&".concat(ReservedIframeQueryParamKeys_1.ReservedIframeQueryParamKeys.HostedInCanvas); if (isTeamsApp) { iframeSrcUrl += "&".concat(ReservedIframeQueryParamKeys_1.ReservedIframeQueryParamKeys.HostedInTeams); if (isUsingSecureBroker) { iframeSrcUrl += "&".concat(sp_core_library_1._BROKER_IN_USE_KEY, "=true"); iframeSrcUrl = "".concat(domainUrl, "/_layouts/15/brokerlogon.aspx?").concat(sp_core_library_1._BROKER_IN_USE_KEY, "=true&") + // TODO: If we want to support testing in a simple way we need to pass the debug query string parameters to the iframe 'dest=' + encodeURIComponent(iframeSrcUrl); } } return iframeSrcUrl; }; /** * Creates an iframe HTML element, sets the source url to load an application that will * display the property pane associated with the given parameters, and add the iframed * element as a child to the page chrome. This method will not show the property pane by * default, 'showPropertyPane' should be called after. */ IframedWebPartController.prototype._createPropertyPaneElement = function (instanceId, openDetails) { if (!this._pageContentElement) { this._pageContentElement = document.getElementById('spPageChromeAppDiv'); } if (!this._iframedPropertyPaneContainer) { this._iframedPropertyPaneContainer = document.createElement('div'); this._iframedPropertyPaneContainer.id = IFRAMED_PROPERTYPANE_CONTAINER_ID; this._iframedPropertyPaneContainer.className = IframedPropertyPane_module_scss_1.default.spIFramePropertyPaneContainer; } var metadata = this._iframedWebparts.get(instanceId); if (!(0, KillSwitches_1.isDynamicIframedPropertyPaneHandlingKSActivated)()) { this._iframedPropertyPaneWebPartInstanceId = instanceId; } this._iframeSrcUrl = metadata.url; this._iframeSrcUrl += "&".concat(openDetails ? ReservedIframeQueryParamKeys_1.ReservedIframeQueryParamKeys.OpenDetailsPropertyPane : ReservedIframeQueryParamKeys_1.ReservedIframeQueryParamKeys.OpenPropertyPane, "=true"); this._iframedPropertyPaneContainer.innerHTML = "\n <iframe\n id=".concat(PROPERTYPANE_IFRAME_ID, "\n src=").concat(this._addFilteredQueryParamsFromHostPage(this._iframeSrcUrl), "\n class=").concat(IframedPropertyPane_module_scss_1.default.iframePropertyPane, "\n title=").concat(sp_core_library_1.Text.format(Strings_resx_1.default.IsolatedWebPartPropertiesIframeTitle, metadata.webPartData.title), "\n ></iframe>"); var parent = this._pageContentElement.parentElement; parent.appendChild(this._iframedPropertyPaneContainer); this._ppIframeElement = document.getElementById(PROPERTYPANE_IFRAME_ID); }; /** * Event listener that takes actions on behalf of iframed webparts. */ IframedWebPartController.prototype._iframeEventListener = function (event) { var _this = this; var _a, _b; if (this._iframedWebparts.has(event.data.instanceId)) { var metadata = this._iframedWebparts.get(event.data.instanceId); var currentOrigin = new URL(event.origin).origin; if (currentOrigin.toLowerCase() === event.origin.toLowerCase()) { var eventData_1 = event.data; sp_core_library_1.Validate.isNotNullOrUndefined(eventData_1.action, 'action'); switch (eventData_1.action) { case IIframedWebPartMessage_1.IframedWebPartAction.RequestDisplayMode: this._updateWebPartDisplayMode(eventData_1.instanceId); break; case IIframedWebPartMessage_1.IframedWebPartAction.GetOboToken: var _c = eventData_1.oboRequest, application = _c.application, claims = _c.claims; var tokenProvider = sp_http_base_1._AadTokenProviders.configurable; var tokenPromise = void 0; if (application === sp_http_base_1._AadConstants.PRE_AUTHORIZED_APP_PRINCIPAL_ID) { tokenPromise = tokenProvider._oboFirstPartyTokenCallback(claims); } else { tokenPromise = tokenProvider._oboThirdPartyTokenCallback(application, claims); } tokenPromise .then(function (token) { _this._setOboToken(eventData_1.instanceId, token); }) .catch(function () { // Notify the web part of a failed token fetch _this._setOboToken(eventData_1.instanceId, undefined); }); break; case IIframedWebPartMessage_1.IframedWebPartAction.SetDimensions: var iframeWebPartElement = document.getElementById(metadata.webPartElementId); sp_core_library_1.Validate.isNotNullOrUndefined(iframeWebPartElement, 'iframedWebPartElement'); if ((0, Flights_1.isIsolatedAceEnabled)()) { var height = eventData_1.height, instanceId = eventData_1.instanceId, isFullScreen = eventData_1.isFullScreen, width = eventData_1.width; if (isFullScreen) { var clientRect = iframeWebPartElement.getBoundingClientRect(); // Remove height/width, raise z priority, and stretch fullscreen iframeWebPartElement.style.cssText = 'bottom: 0; left: 0; position: fixed; top: 0; z-index: 99999'; if (iframeWebPartElement.parentElement) { if (this._isHostDashboardWebPart(instanceId)) { // The Dashboard Web Part needs the additional padding added for isolation added to the client height to avoid jank iframeWebPartElement.parentElement.style.height = "".concat(clientRect.height + 3, "px"); } else { // The Canvas does not hold the width so we set the parent element to the current width as a "placeholder" iframeWebPartElement.parentElement.style.width = "".concat(clientRect.width, "px"); } } // Notify the iframe of the old client size // In the case of ACEs, we use this info to place the ACE into its original position var targetWindow = this._getCurrentIframeWebPartContentWindow(metadata.webPartElementId); if (targetWindow) { targetWindow.postMessage({ instanceId: eventData_1.instanceId, clientRect: clientRect }, metadata.url); } } else { // Reset all potential modifications from previously being "fullscreen" (_a = iframeWebPartElement.parentElement) === null || _a === void 0 ? void 0 : _a.style.removeProperty('width'); (_b = iframeWebPartElement.parentElement) === null || _b === void 0 ? void 0 : _b.style.removeProperty('height'); iframeWebPartElement.style.removeProperty('position'); iframeWebPartElement.style.removeProperty('top'); iframeWebPartElement.style.removeProperty('left'); iframeWebPartElement.style.removeProperty('bottom'); if (height) { iframeWebPartElement.style.height = "".concat(height, "px"); } if (width && !this._isHostDashboardWebPart(instanceId)) { iframeWebPartElement.style.width = "".concat(width, "px"); } } } else { sp_core_library_1.Validate.isNotNullOrUndefined(eventData_1.height, 'height'); iframeWebPartElement.style.height = "".concat(eventData_1.height, "px"); } break; case IIframedWebPartMessage_1.IframedWebPartAction.UpdateWebPartData: sp_core_library_1.Validate.isNotNullOrUndefined(eventData_1.webPartData, 'webPartData'); this._updateWebPartData(eventData_1.instanceId, eventData_1.webPartData, IIframedWebPartMessage_1.IframedWebPartAction.UpdateWebPartData); break; case IIframedWebPartMessage_1.IframedWebPartAction.UpdatePropertyPaneData: sp_core_library_1.Validate.isNotNullOrUndefined(eventData_1.webPartData, 'webPartData'); this._updateWebPartData(eventData_1.instanceId, eventData_1.webPartData, IIframedWebPartMessage_1.IframedWebPartAction.UpdatePropertyPaneData); break; case IIframedWebPartMessage_1.IframedWebPartAction.UpdatePropertyPaneLifeCycle: switch (eventData_1.propertyPaneLifeCycleEvent) { case 'Closed': this._hidePropertyPane(event.data.instanceId); } break; case IIframedWebPartMessage_1.IframedWebPartAction.WebPartRenderedInPropertyPaneIframe: var data = { instanceId: event.data.instanceId, action: IIframedWebPartMessage_1.IframedWebPartAction.RequestPropertyPaneAction, propertyPaneAction: 'Refresh', webPartData: metadata.webPartData }; this._ppIframeElement.contentWindow.postMessage(data, metadata.url); break; case IIframedWebPartMessage_1.IframedWebPartAction.UpdateWebpartLifeCycle: this._updateParentHost(eventData_1); break; case IIframedWebPartMessage_1.IframedWebPartAction.RequestTheme: this._updateThemeInfo(eventData_1.instanceId); break; case IIframedWebPartMessage_1.IframedWebPartAction.RequestPropertyPaneAction: this.requestPropertyPaneAction(eventData_1.propertyPaneAction, eventData_1.instanceId); break; case IIframedWebPartMessage_1.IframedWebPartAction.UpdateAudiences: this._updateAudiences(eventData_1.instanceId, eventData_1.audiences || []); break; default: break; } } } }; IframedWebPartController.prototype._updateThemeInfo = function (instanceId) { var theme = this._tryGetTheme(instanceId); if (theme) { this.setTheme(theme, instanceId); } }; IframedWebPartController.prototype._tryGetTheme = function (instanceId) { var _a, _b; return (_b = (_a = this._iframeContextMap .get(instanceId)) === null || _a === void 0 ? void 0 : _a.serviceScope) === null || _b === void 0 ? void 0 : _b.consume(sp_component_base_1.ThemeProvider.serviceKey).tryGetTheme(); }; IframedWebPartController.prototype._updateParentHost = function (_a) { var instanceId = _a.instanceId, parentHostLifeCycle = _a.parentHostLifeCycle; var context = this._iframeContextMap.get(instanceId); var _b = parentHostLifeCycle, lifeCycleMethod = _b.lifeCycleMethod, error = _b.error; switch (lifeCycleMethod) { case 'onBeforeWebPartLoad': this._host.onBeforeWebPartLoad(context); break; case 'onAfterWebPartLoad': this._host.onAfterWebPartLoad(context); break; case 'onBeforeWebPartInitialize': this._host.onBeforeWebPartInitializeOld(context); break; case 'onAfterWebPartInitialize': this._host.onAfterWebPartInitialize(context); break; case 'onBeforeWebPartRender': this._host.onBeforeWebPartRender(context); break; case 'onAfterWebPartRender': this._host.onAfterWebPartRender(context); break; case 'onAfterWebPartLoadFailed': if (error) { this._host.onAfterWebPartLoadFailed(context, error); } break; case 'onAfterWebPartInitializeFailed': if (error) { this._host.onAfterWebPartInitializeFailed(context, error); } break; case 'onAfterWebPartRenderFailed': if (error) { this._host.onAfterWebPartRenderFailed(context, error); } break; } }; /** * Sends a message to an iframed webpart requesting the 'displayMode' set by the ClientSideWebPartManager. * * When an iframe loads a webpart in an iframe it has the context of the webpart's 'displayMode', but the * iframe does not. Thus, after a webpart loads in an iframed, we send a message to the IframedWebPartController * asking for the display mode, which is then sent to the iframe via a window message. * */ IframedWebPartController.prototype._updateWebPartDisplayMode = function (instanceId) { var metadata = this._iframedWebparts.get(instanceId); var messageToIframe = { instanceId: instanceId, displayMode: metadata.displayMode, action: IIframedWebPartMessage_1.IframedWebPartAction.SetDisplayMode }; var targetWindow = this._getCurrentIframeWebPartContentWindow(metadata.webPartElementId); if (targetWindow) { targetWindow.postMessage(messageToIframe, metadata.url); } }; /** * Sends a message to the iframed web part to update it's web part data if the incoming * webPartData differs from the currently saved reference. * There are two scenarios: * 1. the property pane has been updated and is sending a message to the rendered web part * 2. the rendered web part has been updated and is sending a message to the property pane * - we use the param 'action' to differentiate the difference and use the correct element id * of the property pane or the web part. * * @param instanceId - web part instance id * @param webPartData - the incoming web part data. */ IframedWebPartController.prototype._updateWebPartData = function (instanceId, webPartData, action) { var _a; var webPart = this._iframedWebparts.get(instanceId); // Only send a message if the webPartData differs from the last webPartData we sent if (!lodash.isEqual(webPartData, webPart.webPartData)) { webPart.webPartData = webPartData; this._iframedWebparts.set(instanceId, webPart); this._host.setDirty(instanceId); if (!(0, KillSwitches_1.isIsolatedAdaptiveCardExtensionIframedPropertyPaneKSActivated)() && webPart.type === IBaseIframedWebPart_1.IFRAMED_WEB_PART.isolatedACEWebPart) { (_a = webPart.webPart) === null || _a === void 0 ? void 0 : _a.updateACEData(instanceId, webPartData); // IframedWebPart content window does not exist with Isolated ACEs. return; } var message = { instanceId: instanceId, webPartData: webPartData, action: IIframedWebPartMessage_1.IframedWebPartAction.SetWebPartData }; switch (action) { case IIframedWebPartMessage_1.IframedWebPartAction.UpdatePropertyPaneData: // The propertyPane iframe may not be open var iframePropertyPaneElement = document.getElementById(PROPERTYPANE_IFRAME_ID); if (iframePropertyPaneElement && iframePropertyPaneElement.contentWindow) { iframePropertyPaneElement.contentWindow.postMessage(message, webPart.url); } break; case IIframedWebPartMessage_1.IframedWebPartAction.UpdateWebPartData: var targetWindow = this._getCurrentIframeWebPartContentWindow(webPart.webPartElementId); if (targetWindow) { targetWindow.postMessage(message, webPart.url); } break; default: sp_diagnostics_1._TraceLogger.logError(LOG_SOURCE, new Error('Invalid parameter "action"')); break; } } }; IframedWebPartController.prototype._updateAudiences = function (instanceId, audiences) { var _a, _b; (_b = (_a = this._host).onAudiencesChanged) === null || _b === void 0 ? void 0 : _b.call(_a, instanceId, audiences); }; IframedWebPartController.prototype._refreshPropertyPane = function (webPartInstanceId) { if (this._iframedPropertyPaneContainer && webPartInstanceId) { var eventData = { instanceId: webPartInstanceId, action: IIframedWebPartMessage_1.IframedWebPartAction.RequestPropertyPaneAction, propertyPaneAction: 'Refresh' }; var metadata = this._iframedWebparts.get(webPartInstanceId); if (this._ppIframeElement && this._ppIframeElement.contentWindow) { this._ppIframeElement.contentWindow.postMessage(eventData, metadata.url); } } }; IframedWebPartController.prototype._hidePropertyPane = function (webPartInstanceId) { if (this._iframedPropertyPaneContainer) { if (webPartInstanceId) { var eventData = { // Pass the instanceId so we know which web part to // configure when we the property pane is opened. instanceId: webPartInstanceId, action: IIframedWebPartMessage_1.IframedWebPartAction.RequestPropertyPaneAction, propertyPaneAction: 'Close' }; var metadata = this._iframedWebparts.get(webPartInstanceId); // This message is being listened for in SpWebPartApplication._openPropertyPaneListener if (this._ppIframeElement && this._ppIframeElement.contentWindow) { this._ppIframeElement.contentWindow.postMessage(eventData, metadata.url); } } this._iframedPropertyPaneContainer.classList.remove(IframedPropertyPane_module_scss_1.default.showPane); this._iframedPropertyPaneContainer.classList.add(IframedPropertyPane_module_scss_1.default.hidePane); this._pageContentElement.classList.remove(IframedPropertyPane_module_scss_1.default.shrinkContent); } }; /** * Adds and removes the neccessary styles to show the iframed property pane container. * Also posts a message to the window element so that the PropertyPaneController * can show the property pane content. * @param webPartInstanceId - instanceId so we know which property pane to open */ IframedWebPartController.prototype._showPropertyPane = function (webPartInstanceId, action) { var _this = this; var propertyPaneAction = action || 'Open'; if (propertyPaneAction !== 'Open' && propertyPaneAction !== 'OpenDetails') { return; } if (webPartInstanceId && this._iframedWebparts.has(webPartInstanceId)) { var metadata_1 = this._iframedWebparts.get(webPartInstanceId); // Update the src property in the iframe // (This is important if there are two iframed web parts on the page) var openDetailsPropertyPane = propertyPaneAction === 'OpenDetails'; var iframeSrc = new URL(this._ppIframeElement.src); if (openDetailsPropertyPane) { iframeSrc.searchParams.delete('openPropertyPane'); iframeSrc.searchParams.set('openDetailsPropertyPane', 'true'); } else { iframeSrc.searchParams.delete('openDetailsPropertyPane'); iframeSrc.searchParams.set('openPropertyPane', 'true'); } this._ppIframeElement.src = iframeSrc.toString(); var eventData_2 = { // Pass the instanceId so we know which web part to // configure when we the property pane is opened. instanceId: webPartInstanceId, action: IIframedWebPartMessage_1.IframedWebPartAction.RequestPropertyPaneAction, propertyPaneAction: propertyPaneAction }; // This message is being listened for in SpWebPartApplication._openPropertyPaneListener if (this._ppIframeElement && this._ppIframeElement.contentWindow && this._ppIframeElement.contentDocument) { this._ppIframeElement.contentDocument.onload = (function () { _this._ppIframeElement.contentWindow.postMessage(eventData_2, metadata_1.url); }).bind(this); } } this._iframedPropertyPaneContainer.classList.add(IframedPropertyPane_module_scss_1.default.showPane); this._iframedPropertyPaneContainer.classList.remove(IframedPropertyPane_module_scss_1.default.hidePane); this._pageContentElement.classList.add(IframedPropertyPane_module_scss_1.default.shrinkContent); }; IframedWebPartController.prototype._setOboToken = function (instanceId, oboToken) { var message = { instanceId: instanceId, oboToken: oboToken, action: IIframedWebPartMessage_1.IframedWebPartAction.SetOboToken }; var metadata = this._iframedWebparts.get(instanceId); var targetWindow = this._getCurrentIframeWebPartContentWindow(metadata.webPartElementId); if (targetWindow) { targetWindow.postMessage(message, metadata.url); } }; /** * Adds the non-reserved query params from the host page to the iframe url. * * @param url - current iframe url. */ IframedWebPartController.prototype._addFilteredQueryParamsFromHostPage = function (url) { var reservedKeys = Object.keys(ReservedIframeQueryParamKeys_1.ReservedIframeQueryParamKeys).map(function (key) { return ReservedIframeQueryParamKeys_1.ReservedIframeQueryParamKeys[key]; }); var searchParams = new URL(window.location.href).searchParams; for (var _i = 0, reservedKeys_1 = reservedKeys; _i < reservedKeys_1.length; _i++) { var param = reservedKeys_1[_i]; if (searchParams.has(param)) { searchParams.delete(param); } } return "".concat(url, "&").concat(searchParams.toString()); }; IframedWebPartController.prototype._getCurrentIframeWebPartContentWindow = function (elementId) { var iframeWebPartElement = document.getElementById(elementId); return iframeWebPartElement === null || iframeWebPartElement === void 0 ? void 0 : iframeWebPartElement.contentWindow; }; /** * @param instanceId - Web part to check * @returns - A boolean indicating whether the web part is being rendered in the Dashboard Web Part */ IframedWebPartController.prototype._isHostDashboardWebPart = function (instanceId) { var _a; var element = this._iframeContextMap.get(instanceId).domElement; return ((_a = element.parentElement) === null || _a === void 0 ? void 0 : _a.dataset.spFeatureTag) === 'DashboardWebPart'; }; return IframedWebPartController; }()); exports.default = IframedWebPartController; //# sourceMappingURL=IframedWebPartController.js.map