@microsoft/sp-webpart-base
Version:
SharePoint Framework support for building web parts
708 lines • 42.2 kB
JavaScript
"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