Updated script editor web part to 1.4 and minor updates (#396)
* Upgraded to drop 1.4 and asset bundling Bumped version to 1.0.0.3 * Clean up of CSS * Remove linting rule which caused warning on build * Added property to toggle web part container padding on/off * Refactored to have local function bindings at the top for better readability. Fixed readonly warning in cancel dialog as property was set directly instead of via setState * Replaced safeWithCustomScriptDisabled with requiresCustomScript Added removePadding property. Updated correct schema reference. Removed comments. * Added skipFeatureDeployment attribute for easier switch if needed. * Added missing ; * Fix for setting the default switch to require custom script enabled for the web part. Value got switched one the attribute changed. * Added hyperlink on Puzzlepart logo.
This commit is contained in:
parent
120af41c95
commit
d8e4df3aca
|
@ -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/drop-1.3.0-green.svg)
|
||||
![drop](https://img.shields.io/badge/drop-1.4.0-green.svg)
|
||||
|
||||
## Applies to
|
||||
|
||||
|
@ -68,6 +68,7 @@ Version|Date|Comments
|
|||
1.0|March 10th, 2017|Initial release
|
||||
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
|
||||
1.0.0.3|January 10th, 2018|Updated SPFx version, added remove padding property and 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,9 @@
|
|||
"solution": {
|
||||
"name": "Modern Script Editor web part by Puzzlepart",
|
||||
"id": "1425175f-3ed8-44d2-8fc4-dd1497191294",
|
||||
"version": "1.0.0.2"
|
||||
"version": "1.0.0.3",
|
||||
"includeClientSideAssets": true,
|
||||
"skipFeatureDeployment": false
|
||||
},
|
||||
"paths": {
|
||||
"zippedPackage": "solution/pzl-script-editor.sppkg"
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
"no-switch-case-fall-through": true,
|
||||
"no-unnecessary-semicolons": true,
|
||||
"no-unused-expression": true,
|
||||
"no-unused-imports": true,
|
||||
"no-use-before-declare": true,
|
||||
"no-with-statement": true,
|
||||
"semicolon": true,
|
||||
|
|
|
@ -6,25 +6,23 @@
|
|||
"node": ">=0.10.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@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",
|
||||
"@microsoft/sp-core-library": "~1.4.0",
|
||||
"@microsoft/sp-webpart-base": "~1.4.0",
|
||||
"@types/react": "15.6.6",
|
||||
"@types/react-dom": "15.5.6",
|
||||
"@types/webpack-env": ">=1.12.1 <1.14.0",
|
||||
"office-ui-fabric-react": "^4.40.1",
|
||||
"react": "15.4.2",
|
||||
"react-dom": "15.4.2"
|
||||
"react": "15.6.2",
|
||||
"react-dom": "15.6.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@microsoft/sp-build-web": "~1.3.0",
|
||||
"@microsoft/sp-module-interfaces": "~1.3.0",
|
||||
"@microsoft/sp-webpart-workbench": "~1.3.0",
|
||||
"@microsoft/sp-build-web": "~1.4.0",
|
||||
"@microsoft/sp-module-interfaces": "~1.4.0",
|
||||
"@microsoft/sp-webpart-workbench": "~1.4.0",
|
||||
"gulp": "~3.9.1",
|
||||
"@types/chai": ">=3.4.34 <3.6.0",
|
||||
"@types/mocha": ">=2.2.33 <2.6.0"
|
||||
"@types/mocha": ">=2.2.33 <2.6.0",
|
||||
"ajv": "~5.2.2"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "gulp bundle",
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
export interface IScriptEditorWebPartProps {
|
||||
script: string;
|
||||
removePadding: boolean;
|
||||
}
|
||||
|
|
|
@ -1,25 +1,28 @@
|
|||
{
|
||||
"$schema": "../../../node_modules/@microsoft/sp-module-interfaces/lib/manifestSchemas/jsonSchemas/clientSideComponentManifestSchema.json",
|
||||
"id": "3a328f0a-99c4-4b28-95ab-fe0847f657a3",
|
||||
"alias": "ScriptEditorWebPart",
|
||||
"componentType": "WebPart",
|
||||
"version": "*", // The "*" signifies that the version should be taken from the package.json
|
||||
"manifestVersion": 2,
|
||||
|
||||
/**
|
||||
* This property should only be set to true if it is certain that the webpart does not
|
||||
* allow arbitrary scripts to be called
|
||||
*/
|
||||
"safeWithCustomScriptDisabled": false,
|
||||
|
||||
"preconfiguredEntries": [{
|
||||
"groupId": "3a328f0a-99c4-4b28-95ab-fe0847f657a3",
|
||||
"group": { "default": "Puzzlepart" },
|
||||
"title": { "default": "Modern Script Editor" },
|
||||
"description": { "default": "Add arbitrary script to a page" },
|
||||
"officeFabricIconFontName": "JS",
|
||||
"properties": {
|
||||
"script": ""
|
||||
}
|
||||
}]
|
||||
}
|
||||
"$schema": "https://dev.office.com/json-schemas/spfx/client-side-web-part-manifest.schema.json",
|
||||
"id": "3a328f0a-99c4-4b28-95ab-fe0847f657a3",
|
||||
"alias": "ScriptEditorWebPart",
|
||||
"componentType": "WebPart",
|
||||
"version": "*",
|
||||
"manifestVersion": 2,
|
||||
"requiresCustomScript": true,
|
||||
"preconfiguredEntries": [
|
||||
{
|
||||
"groupId": "3a328f0a-99c4-4b28-95ab-fe0847f657a3",
|
||||
"group": {
|
||||
"default": "Puzzlepart"
|
||||
},
|
||||
"title": {
|
||||
"default": "Modern Script Editor"
|
||||
},
|
||||
"description": {
|
||||
"default": "Add arbitrary script to a page"
|
||||
},
|
||||
"officeFabricIconFontName": "JS",
|
||||
"properties": {
|
||||
"script": "",
|
||||
"removePadding": false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -3,156 +3,167 @@ import * as ReactDom from 'react-dom';
|
|||
import { Version, DisplayMode } from '@microsoft/sp-core-library';
|
||||
import { SPComponentLoader } from '@microsoft/sp-loader';
|
||||
import {
|
||||
BaseClientSideWebPart,
|
||||
IPropertyPaneConfiguration,
|
||||
PropertyPaneCustomField
|
||||
BaseClientSideWebPart,
|
||||
IPropertyPaneConfiguration,
|
||||
PropertyPaneCustomField
|
||||
} from '@microsoft/sp-webpart-base';
|
||||
import ScriptEditor from './components/ScriptEditor';
|
||||
import { IScriptEditorProps } from './components/IScriptEditorProps';
|
||||
import { IScriptEditorWebPartProps } from './IScriptEditorWebPartProps';
|
||||
import { PropertyPaneToggle } from '@microsoft/sp-webpart-base/lib/propertyPane/propertyPaneFields/propertyPaneToggle/PropertyPaneToggle';
|
||||
|
||||
export default class ScriptEditorWebPart extends BaseClientSideWebPart<IScriptEditorWebPartProps> {
|
||||
public save: (script: string) => void = (script: string) => {
|
||||
this.properties.script = script;
|
||||
this.render();
|
||||
}
|
||||
|
||||
public render(): void {
|
||||
const element: React.ReactElement<IScriptEditorProps> = React.createElement(
|
||||
ScriptEditor,
|
||||
{
|
||||
script: this.properties.script,
|
||||
save: this.save
|
||||
}
|
||||
);
|
||||
|
||||
if (this.displayMode == DisplayMode.Read) {
|
||||
this.domElement.innerHTML = this.properties.script;
|
||||
this.executeScript(this.domElement);
|
||||
} else {
|
||||
ReactDom.render(element, this.domElement);
|
||||
public save: (script: string) => void = (script: string) => {
|
||||
this.properties.script = script;
|
||||
this.render();
|
||||
}
|
||||
}
|
||||
|
||||
protected get dataVersion(): Version {
|
||||
return Version.parse('1.0');
|
||||
}
|
||||
public render(): void {
|
||||
const element: React.ReactElement<IScriptEditorProps> = React.createElement(
|
||||
ScriptEditor,
|
||||
{
|
||||
script: this.properties.script,
|
||||
save: this.save
|
||||
}
|
||||
);
|
||||
|
||||
protected renderLogo(domElement: HTMLElement) {
|
||||
domElement.innerHTML = `
|
||||
if (this.displayMode == DisplayMode.Read) {
|
||||
if (this.properties.removePadding) {
|
||||
this.domElement.parentElement.parentElement.parentElement.style.paddingTop = "0";
|
||||
this.domElement.parentElement.parentElement.parentElement.style.paddingBottom = "0";
|
||||
} else {
|
||||
this.domElement.parentElement.parentElement.parentElement.style.paddingTop = "";
|
||||
this.domElement.parentElement.parentElement.parentElement.style.paddingBottom = "";
|
||||
}
|
||||
this.domElement.innerHTML = this.properties.script;
|
||||
this.executeScript(this.domElement);
|
||||
} else {
|
||||
ReactDom.render(element, this.domElement);
|
||||
}
|
||||
}
|
||||
|
||||
protected get dataVersion(): Version {
|
||||
return Version.parse('1.0');
|
||||
}
|
||||
|
||||
protected renderLogo(domElement: HTMLElement) {
|
||||
domElement.innerHTML = `
|
||||
<div style="margin-top: 30px">
|
||||
<div style="float:right">Author: <a href="mailto:mikael.svenson@puzzlepart.com" tabindex="-1">Mikael Svenson</a></div>
|
||||
<div style="float:right"><img src="//www.puzzlepart.com/wp-content/uploads/2017/08/Pzl-LogoType-200.png" onerror="this.style.display = \'none\'";"></div>
|
||||
<div style="float:right"><a href="https://www.puzzlepart.com/" target="_blank"><img src="//www.puzzlepart.com/wp-content/uploads/2017/08/Pzl-LogoType-200.png" onerror="this.style.display = \'none\'";"></a></div>
|
||||
</div>`;
|
||||
}
|
||||
}
|
||||
|
||||
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
||||
return {
|
||||
pages: [
|
||||
{
|
||||
header: {
|
||||
description: 'No settings to change for this web part.'
|
||||
},
|
||||
groups: [
|
||||
{
|
||||
groupFields: [
|
||||
PropertyPaneCustomField({
|
||||
onRender: this.renderLogo,
|
||||
key: "logo"
|
||||
})
|
||||
]
|
||||
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
|
||||
return {
|
||||
pages: [
|
||||
{
|
||||
groups: [
|
||||
{
|
||||
groupFields: [
|
||||
PropertyPaneToggle("removePadding", {
|
||||
label: "Remove top/bottom padding of web part container",
|
||||
checked: this.properties.removePadding,
|
||||
onText: "Remove padding",
|
||||
offText: "Keep padding"
|
||||
}),
|
||||
PropertyPaneCustomField({
|
||||
onRender: this.renderLogo,
|
||||
key: "logo"
|
||||
})
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
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.
|
||||
//
|
||||
// Argument element is an element in the dom.
|
||||
private executeScript(element: HTMLElement) {
|
||||
// Define global name to tack scripts on in case script to be loaded is not AMD/UMD
|
||||
(<any>window).ScriptGlobal = {};
|
||||
|
||||
// main section of function
|
||||
const scripts = [];
|
||||
const children_nodes = element.childNodes;
|
||||
|
||||
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);
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
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.
|
||||
//
|
||||
// Argument element is an element in the dom.
|
||||
private executeScript(element: HTMLElement) {
|
||||
// Define global name to tack scripts on in case script to be loaded is not AMD/UMD
|
||||
(<any>window).ScriptGlobal = {};
|
||||
|
||||
// main section of function
|
||||
const scripts = [];
|
||||
const children_nodes = element.childNodes;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
const urls = [];
|
||||
const onLoads = [];
|
||||
for (var j = 0; scripts[j]; j++) {
|
||||
const scriptTag = scripts[j];
|
||||
if (scriptTag.src && scriptTag.src.length > 0) {
|
||||
urls.push(scriptTag.src);
|
||||
}
|
||||
if (scriptTag.onload && scriptTag.onload.length > 0) {
|
||||
onLoads.push(scriptTag.onload);
|
||||
}
|
||||
}
|
||||
|
||||
// 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([]));
|
||||
|
||||
// execute Promises in serial
|
||||
promiseSerial(allFuncs)
|
||||
.then(() => {
|
||||
// execute any onload people have added
|
||||
for (j = 0; onLoads[j]; j++) {
|
||||
onLoads[j]();
|
||||
const urls = [];
|
||||
const onLoads = [];
|
||||
for (var j = 0; scripts[j]; j++) {
|
||||
const scriptTag = scripts[j];
|
||||
if (scriptTag.src && scriptTag.src.length > 0) {
|
||||
urls.push(scriptTag.src);
|
||||
}
|
||||
if (scriptTag.onload && scriptTag.onload.length > 0) {
|
||||
onLoads.push(scriptTag.onload);
|
||||
}
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
|
||||
// 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([]));
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
//@import url(https://publiccdn.sharepointonline.com/techmikael.sharepoint.com/11510075fe4212d19d3e6d07c91981263dd697bf111cb1e5f0efb15de0ec08b382cde399/5.0.1/office-ui-fabric.min.css);
|
||||
@import '~office-ui-fabric-react/dist/sass/References.scss';
|
||||
|
||||
.scriptEditor {
|
||||
.container {
|
||||
|
@ -10,45 +10,4 @@
|
|||
.row {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.listItem {
|
||||
max-width: 715px;
|
||||
margin: 5px auto 5px auto;
|
||||
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.button {
|
||||
// Our button
|
||||
text-decoration: none;
|
||||
height: 32px;
|
||||
|
||||
// Primary Button
|
||||
min-width: 80px;
|
||||
background-color: #0078d7;
|
||||
border-color: #0078d7;
|
||||
color: #ffffff;
|
||||
|
||||
// Basic Button
|
||||
outline: transparent;
|
||||
position: relative;
|
||||
font-family: "Segoe UI WestEuropean","Segoe UI",-apple-system,BlinkMacSystemFont,Roboto,"Helvetica Neue",sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
border-width: 0;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
display: inline-block;
|
||||
padding: 0 16px;
|
||||
|
||||
.label {
|
||||
font-weight: 600;
|
||||
font-size: 14px;
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
margin: 0 4px;
|
||||
vertical-align: top;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -8,72 +8,78 @@ import { loadStyles } from '@microsoft/load-themed-styles';
|
|||
require('./overrides.css');
|
||||
|
||||
export default class ScriptEditor extends React.Component<IScriptEditorProps, any> {
|
||||
constructor() {
|
||||
super();
|
||||
const uiFabricCSS: string = `
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this._showDialog = this._showDialog.bind(this);
|
||||
this._closeDialog = this._closeDialog.bind(this);
|
||||
this._cancelDialog = this._cancelDialog.bind(this);
|
||||
this._onScriptEditorTextChanged = this._onScriptEditorTextChanged.bind(this);
|
||||
|
||||
const uiFabricCSS: string = `
|
||||
.pzl-bgColor-themeDark, .pzl-bgColor-themeDark--hover:hover {
|
||||
background-color: "[theme:themeDark, default:#005a9e]";
|
||||
}
|
||||
`;
|
||||
loadStyles(uiFabricCSS);
|
||||
this.state = {
|
||||
showDialog: false
|
||||
};
|
||||
}
|
||||
loadStyles(uiFabricCSS);
|
||||
this.state = {
|
||||
showDialog: false
|
||||
};
|
||||
}
|
||||
|
||||
public componentDidMount(): void {
|
||||
this.setState({ script: this.props.script, loaded: this.props.script });
|
||||
}
|
||||
private _showDialog() {
|
||||
this.setState({ showDialog: true });
|
||||
}
|
||||
public componentDidMount(): void {
|
||||
this.setState({ script: this.props.script, loaded: this.props.script });
|
||||
}
|
||||
private _showDialog() {
|
||||
this.setState({ showDialog: true });
|
||||
}
|
||||
|
||||
private _closeDialog() {
|
||||
this.setState({ showDialog: false });
|
||||
this.props.save(this.state.script);
|
||||
}
|
||||
private _closeDialog() {
|
||||
this.setState({ showDialog: false });
|
||||
this.props.save(this.state.script);
|
||||
}
|
||||
|
||||
private _cancelDialog() {
|
||||
this.setState({ showDialog: false });
|
||||
this.state.script = this.state.loaded;
|
||||
}
|
||||
private _cancelDialog() {
|
||||
this.props.save(this.state.loaded);
|
||||
this.setState({ showDialog: false, script: this.state.loaded });
|
||||
}
|
||||
|
||||
private _onScriptEditorTextChanged(text: string) {
|
||||
this.setState({ script: text });
|
||||
}
|
||||
private _onScriptEditorTextChanged(text: string) {
|
||||
this.setState({ script: text });
|
||||
}
|
||||
|
||||
public render(): React.ReactElement<IScriptEditorProps> {
|
||||
const viewMode = <span dangerouslySetInnerHTML={{ __html: this.state.script }}></span>;
|
||||
public render(): React.ReactElement<IScriptEditorProps> {
|
||||
const viewMode = <span dangerouslySetInnerHTML={{ __html: this.state.script }}></span>;
|
||||
|
||||
return (
|
||||
<div >
|
||||
<div className={styles.scriptEditor}>
|
||||
<div className={styles.container}>
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
<Dialog
|
||||
isOpen={this.state.showDialog}
|
||||
type={DialogType.normal}
|
||||
onDismiss={this._closeDialog.bind(this)}
|
||||
title='Embed'
|
||||
subText='Paste your script, markup or embed code below. Note that scripts will only run in view mode.'
|
||||
isBlocking={true}
|
||||
className={'ScriptPart'}
|
||||
>
|
||||
<TextField multiline rows={15} onChanged={this._onScriptEditorTextChanged.bind(this)} value={this.state.script} />
|
||||
<DialogFooter>
|
||||
<PrimaryButton onClick={this._closeDialog.bind(this)}>Save</PrimaryButton>
|
||||
<DefaultButton onClick={this._cancelDialog.bind(this)}>Cancel</DefaultButton>
|
||||
</DialogFooter>
|
||||
{viewMode}
|
||||
</Dialog>
|
||||
</div >);
|
||||
}
|
||||
return (
|
||||
<div >
|
||||
<div className={styles.scriptEditor}>
|
||||
<div className={styles.container}>
|
||||
<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 snippet dialog' onClick={this._showDialog}>Edit snippet</DefaultButton>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Dialog
|
||||
isOpen={this.state.showDialog}
|
||||
type={DialogType.normal}
|
||||
onDismiss={this._closeDialog}
|
||||
title='Embed'
|
||||
subText='Paste your script, markup or embed code below. Note that scripts will only run in view mode.'
|
||||
isBlocking={true}
|
||||
className={'ScriptPart'}
|
||||
>
|
||||
<TextField multiline rows={15} onChanged={this._onScriptEditorTextChanged} value={this.state.script} />
|
||||
<DialogFooter>
|
||||
<PrimaryButton onClick={this._closeDialog}>Save</PrimaryButton>
|
||||
<DefaultButton onClick={this._cancelDialog}>Cancel</DefaultButton>
|
||||
</DialogFooter>
|
||||
{viewMode}
|
||||
</Dialog>
|
||||
</div >);
|
||||
}
|
||||
}
|
|
@ -8,8 +8,12 @@
|
|||
"sourceMap": true,
|
||||
"types": [
|
||||
"es6-promise",
|
||||
"es6-collections",
|
||||
"webpack-env"
|
||||
],
|
||||
"lib": [
|
||||
"es5",
|
||||
"dom",
|
||||
"es2015.collection"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue