Merge pull request #445 from wobba/ModernScriptImproveLoading
Support for AMD/UMD modules
This commit is contained in:
commit
de679bcfa3
|
@ -47,8 +47,47 @@ If all you want is to add markup on the page, you can do that as well. Adding th
|
|||
</ul>
|
||||
```
|
||||
|
||||
You may add CSS via style tags or `link` tags.
|
||||
```html
|
||||
<!-- Latest compiled and minified CSS -->
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
|
||||
<style>
|
||||
#container h1 {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
<div id="container">
|
||||
<h1>Headline</h1>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-8">.col-md-8</div>
|
||||
<div class="col-md-4">.col-md-4</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-4">.col-md-4</div>
|
||||
<div class="col-md-4">.col-md-4</div>
|
||||
<div class="col-md-4">.col-md-4</div>
|
||||
</div>
|
||||
```
|
||||
|
||||
## Notes for AMD/UMD modules
|
||||
If the library you load is an AMD/UMD module you have to add the custom attribute `module` on the script tag, specifying the global name which should hold the module.
|
||||
|
||||
```html
|
||||
<div id="time"></div>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js" module="mymoment"></script>
|
||||
<script>
|
||||
var m = mymoment();
|
||||
document.getElementById("time").innerHTML = m.format('MMMM Do YYYY, HH:mm:ss');
|
||||
</script>
|
||||
```
|
||||
## Support for classic _spPageContextInfo
|
||||
|
||||
If your scripts rely on the classic _spPageContextInfo, you can enable that in the web part property pane.
|
||||
|
||||
|
||||
## Used SharePoint Framework Version
|
||||
![drop](https://img.shields.io/badge/drop-1.4.0-green.svg)
|
||||
![drop](https://img.shields.io/badge/drop-1.4.1-green.svg)
|
||||
|
||||
## Applies to
|
||||
|
||||
|
@ -70,6 +109,7 @@ Version|Date|Comments
|
|||
1.0.0.2|October 4th, 2017|Updated SPFx version, bundle Office UI Fabric and CSS in webpart
|
||||
1.0.0.3|January 10th, 2018|Updated SPFx version, added remove padding property and refactoring
|
||||
1.0.0.4|February 14th, 2018|Added title property for edit mode and documentation for enabling the web part on Group sites / tenant wide
|
||||
1.0.0.5|March 8th, 2018|Added support for loading scripts which are AMD/UMD modules. Added support for classic _spPageContextInfo. Refactoring.
|
||||
|
||||
## Disclaimer
|
||||
**THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.**
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"solution": {
|
||||
"name": "Modern Script Editor web part by Puzzlepart",
|
||||
"id": "1425175f-3ed8-44d2-8fc4-dd1497191294",
|
||||
"version": "1.0.0.4",
|
||||
"version": "1.0.0.5",
|
||||
"includeClientSideAssets": true,
|
||||
"skipFeatureDeployment": false
|
||||
},
|
||||
|
|
|
@ -2,4 +2,5 @@ export interface IScriptEditorWebPartProps {
|
|||
script: string;
|
||||
title: string;
|
||||
removePadding: boolean;
|
||||
spPageContextInfo: boolean;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,8 @@
|
|||
"properties": {
|
||||
"script": "",
|
||||
"title" : "The Modern Script Editor web part!",
|
||||
"removePadding": false
|
||||
"removePadding": false,
|
||||
"spPageContextInfo" : false
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
|
@ -63,7 +63,7 @@ export default class ScriptEditorWebPart extends BaseClientSideWebPart<IScriptEd
|
|||
groups: [
|
||||
{
|
||||
groupFields: [
|
||||
PropertyPaneTextField("title",{
|
||||
PropertyPaneTextField("title", {
|
||||
label: "Title to show in edit mode",
|
||||
value: this.properties.title
|
||||
}),
|
||||
|
@ -73,6 +73,12 @@ export default class ScriptEditorWebPart extends BaseClientSideWebPart<IScriptEd
|
|||
onText: "Remove padding",
|
||||
offText: "Keep padding"
|
||||
}),
|
||||
PropertyPaneToggle("spPageContextInfo", {
|
||||
label: "Enable classic _spPageContextInfo",
|
||||
checked: this.properties.spPageContextInfo,
|
||||
onText: "Enabled",
|
||||
offText: "Disabled"
|
||||
}),
|
||||
PropertyPaneCustomField({
|
||||
onRender: this.renderLogo,
|
||||
key: "logo"
|
||||
|
@ -120,8 +126,13 @@ export default class ScriptEditorWebPart extends BaseClientSideWebPart<IScriptEd
|
|||
// Needed since innerHTML does not run scripts.
|
||||
//
|
||||
// Argument element is an element in the dom.
|
||||
private executeScript(element: HTMLElement) {
|
||||
private async executeScript(element: HTMLElement) {
|
||||
// Define global name to tack scripts on in case script to be loaded is not AMD/UMD
|
||||
|
||||
if(this.properties.spPageContextInfo && !window["_spPageContextInfo"]){
|
||||
window["_spPageContextInfo"] = this.context.pageContext.legacyPageContext;
|
||||
}
|
||||
|
||||
(<any>window).ScriptGlobal = {};
|
||||
|
||||
// main section of function
|
||||
|
@ -138,10 +149,14 @@ export default class ScriptEditorWebPart extends BaseClientSideWebPart<IScriptEd
|
|||
|
||||
const urls = [];
|
||||
const onLoads = [];
|
||||
const moduleMap = [];
|
||||
for (var j = 0; scripts[j]; j++) {
|
||||
const scriptTag = scripts[j];
|
||||
if (scriptTag.src && scriptTag.src.length > 0) {
|
||||
urls.push(scriptTag.src);
|
||||
if (scriptTag.attributes["module"] && scriptTag.attributes["module"].value.length > 0) {
|
||||
moduleMap[scriptTag.src] = scriptTag.attributes["module"].value;
|
||||
}
|
||||
}
|
||||
if (scriptTag.onload && scriptTag.onload.length > 0) {
|
||||
onLoads.push(scriptTag.onload);
|
||||
|
@ -150,26 +165,28 @@ export default class ScriptEditorWebPart extends BaseClientSideWebPart<IScriptEd
|
|||
|
||||
// Execute promises in sequentially - https://hackernoon.com/functional-javascript-resolving-promises-sequentially-7aac18c4431e
|
||||
// Use "ScriptGlobal" as the global namein case script is AMD/UMD
|
||||
const allFuncs = urls.map(url => () => SPComponentLoader.loadScript(url, { globalExportsName: "ScriptGlobal" }));
|
||||
|
||||
const promiseSerial = funcs =>
|
||||
funcs.reduce((promise, func) =>
|
||||
promise.then(result => func().then(Array.prototype.concat.bind(result))),
|
||||
Promise.resolve([]));
|
||||
for (let i = 0; i < urls.length; i++) {
|
||||
try {
|
||||
let m: any = await SPComponentLoader.loadScript(urls[i], { globalExportsName: "ScriptGlobal" });
|
||||
let moduleName = moduleMap[urls[i]];
|
||||
if (moduleName) {
|
||||
//If it's a AMD/UMD module, then assign to that global variable
|
||||
window[moduleName] = m;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
}
|
||||
}
|
||||
|
||||
// execute Promises in serial
|
||||
promiseSerial(allFuncs)
|
||||
.then(() => {
|
||||
// execute any onload people have added
|
||||
for (j = 0; onLoads[j]; j++) {
|
||||
onLoads[j]();
|
||||
}
|
||||
// execute script blocks
|
||||
for (j = 0; scripts[j]; j++) {
|
||||
const scriptTag = scripts[j];
|
||||
if (scriptTag.parentNode) { scriptTag.parentNode.removeChild(scriptTag); }
|
||||
this.evalScript(scripts[j]);
|
||||
}
|
||||
}).catch(console.error);
|
||||
for (j = 0; scripts[j]; j++) {
|
||||
const scriptTag = scripts[j];
|
||||
if (scriptTag.parentNode) { scriptTag.parentNode.removeChild(scriptTag); }
|
||||
this.evalScript(scripts[j]);
|
||||
}
|
||||
// execute any onload people have added
|
||||
for (j = 0; onLoads[j]; j++) {
|
||||
onLoads[j]();
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue