forked from microsoft/PowerBI-JavaScript
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathembed.ts
More file actions
156 lines (126 loc) · 5.14 KB
/
Copy pathembed.ts
File metadata and controls
156 lines (126 loc) · 5.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
import { Utils } from './util';
declare global {
interface Document {
// Mozilla Fullscreen
mozCancelFullScreen: Function;
// Ms Fullscreen
msExitFullscreen: Function;
}
interface HTMLIFrameElement {
// Mozilla Fullscreen
mozRequestFullScreen: Function;
// Ms Fullscreen
msRequestFullscreen: Function;
}
}
export interface ILoadMessage {
action: string;
accessToken: string;
}
export interface IEmbedOptions {
type?: string;
id?: string;
accessToken?: string;
embedUrl?: string;
webUrl?: string;
name?: string;
filterPaneEnabled?: boolean;
getGlobalAccessToken?: () => string;
}
export interface IEmbedConstructor {
new(...args: any[]): Embed;
}
export abstract class Embed {
public static embedUrlAttribute = 'powerbi-embed-url';
public static accessTokenAttribute = 'powerbi-access-token';
public static typeAttribute = 'powerbi-type';
/**
* Attribute used to specify type of visual.
* Example: `<div powerbi-type="report"></div>`
*/
public static name: string;
/**
* Default options for embeddable component.
*/
private static defaultOptions: IEmbedOptions = {
filterPaneEnabled: true
};
element: HTMLElement;
iframe: HTMLIFrameElement;
options: IEmbedOptions;
constructor(element: HTMLElement, options: IEmbedOptions) {
this.element = element;
// TODO: Change when Object.assign is available.
this.options = Utils.assign({}, Embed.defaultOptions, options);
this.options.accessToken = this.getAccessToken();
this.options.embedUrl = this.getEmbedUrl();
const iframeHtml = `<iframe style="width:100%;height:100%;" src="${this.options.embedUrl}" scrolling="no" allowfullscreen="true"></iframe>`;
this.element.innerHTML = iframeHtml;
this.iframe = <HTMLIFrameElement>this.element.childNodes[0];
this.iframe.addEventListener('load', () => this.load(this.options, false), false);
}
/**
* Handler for when the iframe has finished loading the powerbi placeholder page.
* This is used to inject configuration options such as access token, loadAction, etc
* which allow iframe to load the actual report with authentication.
*/
load(options: IEmbedOptions, requireId: boolean = false, message: ILoadMessage = null) {
if(!message) {
throw new Error(`You called load without providing message properties from the concrete embeddable class.`);
}
const baseMessage = <ILoadMessage>{
accessToken: options.accessToken
};
Utils.assign(message, baseMessage);
const event = {
message
};
Utils.raiseCustomEvent(this.element, event.message.action, event);
this.iframe.contentWindow.postMessage(JSON.stringify(event.message), '*');
}
/**
* Get access token from first available location: options, attribute, global.
*/
private getAccessToken(): string {
const accessToken = this.options.accessToken || this.element.getAttribute(Embed.accessTokenAttribute) || this.options.getGlobalAccessToken();
if (!accessToken) {
throw new Error(`No access token was found for element. You must specify an access token directly on the element using attribute '${Embed.accessTokenAttribute}' or specify a global token at: powerbi.accessToken.`);
}
return accessToken;
}
/**
* Get embed url from first available location: options, attribute.
*/
protected getEmbedUrl(): string {
const embedUrl = this.options.embedUrl || this.element.getAttribute(Embed.embedUrlAttribute);
if(typeof embedUrl !== 'string' || embedUrl.length === 0) {
throw new Error(`Embed Url is required, but it was not found. You must provide an embed url either as part of embed configuration or as attribute '${Embed.embedUrlAttribute}'.`);
}
return embedUrl;
}
/**
* Request the browser to make the components iframe fullscreen.
*/
fullscreen(): void {
const requestFullScreen = this.iframe.requestFullscreen || this.iframe.msRequestFullscreen || this.iframe.mozRequestFullScreen || this.iframe.webkitRequestFullscreen;
requestFullScreen.call(this.iframe);
}
/**
* Exit fullscreen.
*/
exitFullscreen(): void {
if (!this.isFullscreen(this.iframe)) {
return;
}
const exitFullscreen = document.exitFullscreen || document.mozCancelFullScreen || document.webkitExitFullscreen || document.msExitFullscreen;
exitFullscreen.call(document);
}
/**
* Return true if iframe is fullscreen,
* otherwise return false
*/
private isFullscreen(iframe: HTMLIFrameElement): boolean {
const options = ['fullscreenElement', 'webkitFullscreenElement', 'mozFullscreenScreenElement', 'msFullscreenElement'];
return options.some(option => document[option] === iframe);
}
}