Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Merged PR 178588: Side channel JS SDK
From the end user's perspective, they will need to provide a third parameter to `powerbi.embed()` request.
The new input may be extended in the future to support other event hooks.

```javascript
powerbi.embed(..., config, { preQueryCallback: provideContext })
```
The code in `service.ts` is similar to the event listeners we set in the [constructor](https://powerbi.visualstudio.com/Embedded/_git/powerbi-javascript?path=%2Fsrc%2Fservice.ts&version=GBmaster&line=168&lineEnd=168&lineStartColumn=5&lineEndColumn=21&lineStyle=plain&_a=contents)
  • Loading branch information
Shahak Yosef committed Jul 29, 2021
commit 2a689943d471ad6a07afd6008796f48720fe1dff
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ dist/powerbi.js.map
*.js.map
package-lock.json
demo/package-lock.json
.vscode
6 changes: 0 additions & 6 deletions .vscode/settings.json

This file was deleted.

29 changes: 0 additions & 29 deletions .vscode/tasks.json

This file was deleted.

6 changes: 5 additions & 1 deletion dist/powerbi-client.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// powerbi-client v2.18.3
// powerbi-client v2.18.4
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
declare module "config" {
Expand Down Expand Up @@ -2127,6 +2127,10 @@ declare module "service" {
* @hidden
*/
private embedExisting;
/**
* @hidden
*/
private registerApplicationContextHook;
/**
* Adds an event handler for DOMContentLoaded, which searches the DOM for elements that have the 'powerbi-embed-url' attribute,
* and automatically attempts to embed a powerbi component based on information from other powerbi-* attributes.
Expand Down
89 changes: 83 additions & 6 deletions dist/powerbi.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions dist/powerbi.min.js

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "powerbi-client",
"version": "2.18.3",
"version": "2.18.4",
"description": "JavaScript library for embedding Power BI into your apps. Provides service which makes it easy to embed different types of components and an object model which allows easy interaction with these components such as changing pages, applying filters, and responding to data selection.",
"main": "dist/powerbi.js",
"types": "dist/powerbi-client.d.ts",
Expand Down Expand Up @@ -81,7 +81,7 @@
},
"dependencies": {
"http-post-message": "^0.2",
"powerbi-models": "^1.9.2",
"powerbi-models": "^1.9.3",
"powerbi-router": "^0.1",
"window-post-message-proxy": "^0.2"
},
Expand Down
2 changes: 1 addition & 1 deletion src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

/** @ignore *//** */
const config = {
version: '2.18.3',
version: '2.18.4',
type: 'js'
};

Expand Down
15 changes: 11 additions & 4 deletions src/embed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,12 +227,15 @@ export abstract class Embed {
this.commands = [];
this.groups = [];

const registerQueryCallback = !!(<IEmbedConfiguration>config).eventHooks?.applicationContextProvider;
delete (<IEmbedConfiguration>config).eventHooks;

this.populateConfig(config, isBootstrap);

if (this.embedtype === 'create') {
this.setIframe(false /* set EventListener to call create() on 'load' event*/, phasedRender, isBootstrap);
this.setIframe(false /* set EventListener to call create() on 'load' event*/, phasedRender, isBootstrap, registerQueryCallback);
} else {
this.setIframe(true /* set EventListener to call load() on 'load' event*/, phasedRender, isBootstrap);
this.setIframe(true /* set EventListener to call load() on 'load' event*/, phasedRender, isBootstrap, registerQueryCallback);
}
}

Expand Down Expand Up @@ -702,10 +705,14 @@ export abstract class Embed {
*
* @hidden
*/
private setIframe(isLoad: boolean, phasedRender?: boolean, isBootstrap?: boolean): void {
private setIframe(isLoad: boolean, phasedRender?: boolean, isBootstrap?: boolean, registerQueryCallback?: boolean): void {
if (!this.iframe) {
const iframeContent = document.createElement("iframe");
const embedUrl = this.config.uniqueId ? addParamToUrl(this.config.embedUrl, 'uid', this.config.uniqueId) : this.config.embedUrl;
let embedUrl = this.config.uniqueId ? addParamToUrl(this.config.embedUrl, 'uid', this.config.uniqueId) : this.config.embedUrl;

if (!isBootstrap && registerQueryCallback)
embedUrl = addParamToUrl(embedUrl, "registerQueryCallback", "true");

iframeContent.style.width = '100%';
iframeContent.style.height = '100%';
iframeContent.setAttribute("src", embedUrl);
Expand Down
26 changes: 26 additions & 0 deletions src/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,7 @@ export class Service implements IService {
* @returns {Embed}
*/
embed(element: HTMLElement, config: IComponentEmbedConfiguration | IEmbedConfigurationBase = {}): Embed {
this.registerApplicationContextHook(config as IEmbedConfiguration);
return this.embedInternal(element, config);
}

Expand All @@ -314,6 +315,7 @@ export class Service implements IService {
* @returns {Embed}
*/
load(element: HTMLElement, config: IComponentEmbedConfiguration | IEmbedConfigurationBase = {}): Embed {
this.registerApplicationContextHook(config as IEmbedConfiguration);
return this.embedInternal(element, config, /* phasedRender */ true, /* isBootstrap */ false);
}

Expand Down Expand Up @@ -440,6 +442,30 @@ export class Service implements IService {
return component;
}

/**
* @hidden
*/
private registerApplicationContextHook(config: IEmbedConfiguration): void {
const applicationContextProvider = config?.eventHooks?.applicationContextProvider;
if (!applicationContextProvider) {
return;
}

if (typeof applicationContextProvider !== 'function') {
throw new Error("applicationContextProvider must be a function");
}

this.router.post(`preQuery`, async (req, _res) => {
try {
let result = await applicationContextProvider(req.body);
_res.send(200, result);
} catch (error) {
_res.send(400, null);
console.error(error);
}
});
}

/**
* Adds an event handler for DOMContentLoaded, which searches the DOM for elements that have the 'powerbi-embed-url' attribute,
* and automatically attempts to embed a powerbi component based on information from other powerbi-* attributes.
Expand Down