Bundle all CSS and Office UI Fabric in the part (#321)
* Updated to drop 1.3 * Changed to dynamic office ui fabric loading Bundled needed CSS, and depend on oob CSS for layout * Refactored from javascript to typescript.
This commit is contained in:
parent
5f9d97ca53
commit
2e629e111d
|
@ -48,7 +48,7 @@ If all you want is to add markup on the page, you can do that as well. Adding th
|
|||
```
|
||||
|
||||
## Used SharePoint Framework Version
|
||||
![drop](https://img.shields.io/badge/version-GA-green.svg)
|
||||
![drop](https://img.shields.io/badge/drop-1.3.0-green.svg)
|
||||
|
||||
## Applies to
|
||||
|
||||
|
@ -66,7 +66,8 @@ react-script-editor | Mikael Svenson ([@mikaelsvenson](http://www.twitter.com/mi
|
|||
Version|Date|Comments
|
||||
-------|----|--------
|
||||
1.0|March 10th, 2017|Initial release
|
||||
1.0.1|August 8th, 2017|Updated SPFx version and CSS loading
|
||||
1.0.0.1|August 8th, 2017|Updated SPFx version and CSS loading
|
||||
1.0.0.2|October 4th, 2017|Updated SPFx version, bundle Office UI Fabric and CSS in webpart
|
||||
|
||||
## 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.**
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
{
|
||||
"entries": [
|
||||
{
|
||||
"entry": "./lib/webparts/scriptEditor/ScriptEditorWebPart.js",
|
||||
"manifest": "./src/webparts/scriptEditor/ScriptEditorWebPart.manifest.json",
|
||||
"outputPath": "./dist/script-editor.bundle.js"
|
||||
"$schema": "https://dev.office.com/json-schemas/spfx-build/config.2.0.schema.json",
|
||||
"version": "2.0",
|
||||
"bundles": {
|
||||
"script-editor-bundle": {
|
||||
"components": [
|
||||
{
|
||||
"entrypoint": "./lib/webparts/scriptEditor/ScriptEditorWebPart.js",
|
||||
"manifest": "./src/webparts/scriptEditor/ScriptEditorWebPart.manifest.json"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"externals": {
|
||||
"office-ui-fabric-react": "https://publiccdn.sharepointonline.com/techmikael.sharepoint.com/11510075fe4212d19d3e6d07c91981263dd697bf111cb1e5f0efb15de0ec08b382cde399/2.34.2/office-ui-fabric-react.bundle.min.js"
|
||||
}
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
"solution": {
|
||||
"name": "Modern Script Editor web part by Puzzlepart",
|
||||
"id": "1425175f-3ed8-44d2-8fc4-dd1497191294",
|
||||
"version": "1.0.0.1"
|
||||
"version": "1.0.0.2"
|
||||
},
|
||||
"paths": {
|
||||
"zippedPackage": "solution/pzl-script-editor.sppkg"
|
||||
|
|
|
@ -6,23 +6,22 @@
|
|||
"node": ">=0.10.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@microsoft/sp-client-base": "~1.0.0",
|
||||
"@microsoft/sp-core-library": "~1.1.0",
|
||||
"@microsoft/sp-webpart-base": "~1.1.0",
|
||||
"@types/react": "0.14.46",
|
||||
"@microsoft/sp-core-library": "~1.3.0",
|
||||
"@microsoft/sp-webpart-base": "~1.3.0",
|
||||
"@types/react": "15.0.38",
|
||||
"@types/react-addons-shallow-compare": "0.14.17",
|
||||
"@types/react-addons-test-utils": "0.14.15",
|
||||
"@types/react-addons-update": "0.14.14",
|
||||
"@types/react-dom": "0.14.18",
|
||||
"@types/webpack-env": ">=1.12.1 <1.14.0",
|
||||
"office-ui-fabric-react": "2.34.2",
|
||||
"office-ui-fabric-react": "^4.40.1",
|
||||
"react": "15.4.2",
|
||||
"react-dom": "15.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@microsoft/sp-build-web": "~1.1.0",
|
||||
"@microsoft/sp-module-interfaces": "~1.1.0",
|
||||
"@microsoft/sp-webpart-workbench": "~1.1.0",
|
||||
"@microsoft/sp-build-web": "~1.3.0",
|
||||
"@microsoft/sp-module-interfaces": "~1.3.0",
|
||||
"@microsoft/sp-webpart-workbench": "~1.3.0",
|
||||
"gulp": "~3.9.1",
|
||||
"@types/chai": ">=3.4.34 <3.6.0",
|
||||
"@types/mocha": ">=2.2.33 <2.6.0"
|
||||
|
|
|
@ -68,6 +68,37 @@ export default class ScriptEditorWebPart extends BaseClientSideWebPart<IScriptEd
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
private evalScript(elem) {
|
||||
const data = (elem.text || elem.textContent || elem.innerHTML || "");
|
||||
const headTag = document.getElementsByTagName("head")[0] || document.documentElement;
|
||||
const scriptTag = document.createElement("script");
|
||||
|
||||
scriptTag.type = "text/javascript";
|
||||
if (elem.src && elem.src.length > 0) {
|
||||
return;
|
||||
}
|
||||
if (elem.onload && elem.onload.length > 0) {
|
||||
scriptTag.onload = elem.onload;
|
||||
}
|
||||
|
||||
try {
|
||||
// doesn't work on ie...
|
||||
scriptTag.appendChild(document.createTextNode(data));
|
||||
} catch (e) {
|
||||
// IE has funky script nodes
|
||||
scriptTag.text = data;
|
||||
}
|
||||
|
||||
headTag.insertBefore(scriptTag, headTag.firstChild);
|
||||
headTag.removeChild(scriptTag);
|
||||
}
|
||||
|
||||
private nodeName(elem, name) {
|
||||
return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
|
||||
}
|
||||
|
||||
|
||||
// Finds and executes scripts in a newly added element's body.
|
||||
// Needed since innerHTML does not run scripts.
|
||||
//
|
||||
|
@ -76,46 +107,13 @@ export default class ScriptEditorWebPart extends BaseClientSideWebPart<IScriptEd
|
|||
// Define global name to tack scripts on in case script to be loaded is not AMD/UMD
|
||||
(<any>window).ScriptGlobal = {};
|
||||
|
||||
function nodeName(elem, name) {
|
||||
return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase();
|
||||
}
|
||||
|
||||
function evalScript(elem) {
|
||||
var data = (elem.text || elem.textContent || elem.innerHTML || ""),
|
||||
head = document.getElementsByTagName("head")[0] ||
|
||||
document.documentElement,
|
||||
script = document.createElement("script");
|
||||
|
||||
script.type = "text/javascript";
|
||||
if (elem.src && elem.src.length > 0) {
|
||||
return;
|
||||
}
|
||||
if (elem.onload && elem.onload.length > 0) {
|
||||
script.onload = elem.onload;
|
||||
}
|
||||
|
||||
try {
|
||||
// doesn't work on ie...
|
||||
script.appendChild(document.createTextNode(data));
|
||||
} catch (e) {
|
||||
// IE has funky script nodes
|
||||
script.text = data;
|
||||
}
|
||||
|
||||
head.insertBefore(script, head.firstChild);
|
||||
head.removeChild(script);
|
||||
}
|
||||
|
||||
// main section of function
|
||||
var scripts = [],
|
||||
script,
|
||||
children_nodes = element.childNodes,
|
||||
child,
|
||||
i;
|
||||
const scripts = [];
|
||||
const children_nodes = element.childNodes;
|
||||
|
||||
for (i = 0; children_nodes[i]; i++) {
|
||||
child = children_nodes[i];
|
||||
if (nodeName(child, "script") &&
|
||||
for (var i = 0; children_nodes[i]; i++) {
|
||||
const child: any = children_nodes[i];
|
||||
if (this.nodeName(child, "script") &&
|
||||
(!child.type || child.type.toLowerCase() === "text/javascript")) {
|
||||
scripts.push(child);
|
||||
}
|
||||
|
@ -123,13 +121,13 @@ export default class ScriptEditorWebPart extends BaseClientSideWebPart<IScriptEd
|
|||
|
||||
const urls = [];
|
||||
const onLoads = [];
|
||||
for (i = 0; scripts[i]; i++) {
|
||||
script = scripts[i];
|
||||
if (script.src && script.src.length > 0) {
|
||||
urls.push(script.src);
|
||||
for (var j = 0; scripts[j]; j++) {
|
||||
const scriptTag = scripts[j];
|
||||
if (scriptTag.src && scriptTag.src.length > 0) {
|
||||
urls.push(scriptTag.src);
|
||||
}
|
||||
if (script.onload && script.onload.length > 0) {
|
||||
onLoads.push(script.onload);
|
||||
if (scriptTag.onload && scriptTag.onload.length > 0) {
|
||||
onLoads.push(scriptTag.onload);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,15 +144,15 @@ export default class ScriptEditorWebPart extends BaseClientSideWebPart<IScriptEd
|
|||
promiseSerial(allFuncs)
|
||||
.then(() => {
|
||||
// execute any onload people have added
|
||||
for (i = 0; onLoads[i]; i++) {
|
||||
onLoads[i]();
|
||||
for (j = 0; onLoads[j]; j++) {
|
||||
onLoads[j]();
|
||||
}
|
||||
// execute script blocks
|
||||
for (i = 0; scripts[i]; i++) {
|
||||
script = scripts[i];
|
||||
if (script.parentNode) { script.parentNode.removeChild(script); }
|
||||
evalScript(scripts[i]);
|
||||
for (j = 0; scripts[j]; j++) {
|
||||
const scriptTag = scripts[j];
|
||||
if (scriptTag.parentNode) { scriptTag.parentNode.removeChild(scriptTag); }
|
||||
this.evalScript(scripts[j]);
|
||||
}
|
||||
}).catch(console.error);
|
||||
};
|
||||
}
|
||||
}
|
|
@ -1,35 +1,26 @@
|
|||
import * as React from 'react';
|
||||
import styles from './ScriptEditor.module.scss';
|
||||
import { IScriptEditorProps } from './IScriptEditorProps';
|
||||
import { Dialog, DialogType, DialogFooter } from 'office-ui-fabric-react';
|
||||
import { DefaultButton, PrimaryButton } from 'office-ui-fabric-react';
|
||||
import { TextField } from 'office-ui-fabric-react';
|
||||
import { Dialog, DialogType, DialogFooter } from 'office-ui-fabric-react/lib/Dialog';
|
||||
import { DefaultButton, PrimaryButton } from 'office-ui-fabric-react/lib/Button';
|
||||
import { TextField } from 'office-ui-fabric-react/lib/TextField';
|
||||
import { loadStyles } from '@microsoft/load-themed-styles';
|
||||
require('./overrides.css');
|
||||
|
||||
export default class ScriptEditor extends React.Component<IScriptEditorProps, any> {
|
||||
constructor() {
|
||||
super();
|
||||
this.loadCss();
|
||||
const uiFabricCSS: string = `
|
||||
.pzl-bgColor-themeDark, .pzl-bgColor-themeDark--hover:hover {
|
||||
background-color: "[theme:themeDark, default:#005a9e]";
|
||||
}
|
||||
`;
|
||||
loadStyles(uiFabricCSS);
|
||||
this.state = {
|
||||
showDialog: false
|
||||
};
|
||||
}
|
||||
|
||||
public async loadCss() {
|
||||
if (window["UIFabricLoaded"]) {
|
||||
return;
|
||||
}
|
||||
const response = await fetch("https://publiccdn.sharepointonline.com/techmikael.sharepoint.com/11510075fe4212d19d3e6d07c91981263dd697bf111cb1e5f0efb15de0ec08b382cde399/5.0.1/office-ui-fabric.min.css");
|
||||
if (response.ok) {
|
||||
response.text().then((data: any) => {
|
||||
loadStyles(data);
|
||||
window["UIFabricLoaded"] = true;
|
||||
this.forceUpdate();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public componentDidMount(): void {
|
||||
this.setState({ script: this.props.script, loaded: this.props.script });
|
||||
}
|
||||
|
@ -52,19 +43,16 @@ export default class ScriptEditor extends React.Component<IScriptEditorProps, an
|
|||
}
|
||||
|
||||
public render(): React.ReactElement<IScriptEditorProps> {
|
||||
if (!window["UIFabricLoaded"]) {
|
||||
return <span />;
|
||||
}
|
||||
const viewMode = <span dangerouslySetInnerHTML={{ __html: this.state.script }}></span>;
|
||||
|
||||
return (
|
||||
<div >
|
||||
<div className={styles.scriptEditor}>
|
||||
<div className={styles.container}>
|
||||
<div className={`pzl-Grid-row pzl-bgColor-themeDark pzl-fontColor-white ${styles.row}`}>
|
||||
<div className="pzl-Grid-col pzl-u-lg10 pzl-u-xl8 pzl-u-xlPush2 pzl-u-lgPush1">
|
||||
<span className="pzl-font-xl pzl-fontColor-white">The Modern Script Editor web part!</span>
|
||||
<p className="pzl-font-l pzl-fontColor-white"></p>
|
||||
<div className={`ms-Grid-row pzl-bgColor-themeDark ms-fontColor-white ${styles.row}`}>
|
||||
<div className="ms-Grid-col ms-lg10 ms-xl8 ms-xlPush2 ms-lgPush1">
|
||||
<span className="ms-font-xl ms-fontColor-white">The Modern Script Editor web part!</span>
|
||||
<p className="ms-font-l ms-fontColor-white"></p>
|
||||
<DefaultButton description='Opens the Sample Dialog' onClick={this._showDialog.bind(this)}>Edit snippet</DefaultButton>
|
||||
</div>
|
||||
</div>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue