155 lines
4.1 KiB
JavaScript
155 lines
4.1 KiB
JavaScript
window.common = (function(global) {
|
|
const {
|
|
Rx: { BehaviorSubject, Observable },
|
|
common = { init: [] }
|
|
} = global;
|
|
|
|
// the first script tag here is to proxy jQuery
|
|
// We use the same jQuery on the main window but we change the
|
|
// context to that of the iframe.
|
|
var libraryIncludes = `
|
|
<script>
|
|
window.loopProtect = parent.loopProtect;
|
|
window.__err = null;
|
|
window.loopProtect.hit = function(line) {
|
|
window.__err = new Error(
|
|
'Potential infinite loop at line ' +
|
|
line +
|
|
'. To disable loop protection, write:' +
|
|
' \\n\\/\\/ noprotect\\nas the first' +
|
|
' line. Beware that if you do have an infinite loop in your code' +
|
|
' this will crash your browser.'
|
|
);
|
|
};
|
|
</script>
|
|
<link
|
|
rel='stylesheet'
|
|
href='//cdnjs.cloudflare.com/ajax/libs/animate.css/3.2.0/animate.min.css'
|
|
/>
|
|
<link
|
|
rel='stylesheet'
|
|
href='//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css'
|
|
/>
|
|
|
|
<link
|
|
rel='stylesheet'
|
|
href='//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css'
|
|
/>
|
|
<style>
|
|
body { padding: 0px 3px 0px 3px; }
|
|
/* FORM RESET: */
|
|
textarea,
|
|
select,
|
|
input[type="date"],
|
|
input[type="datetime"],
|
|
input[type="datetime-local"],
|
|
input[type="email"],
|
|
input[type="month"],
|
|
input[type="number"],
|
|
input[type="password"],
|
|
input[type="search"],
|
|
input[type="tel"],
|
|
input[type="text"],
|
|
input[type="time"],
|
|
input[type="url"],
|
|
input[type="week"] {
|
|
-webkit-box-sizing: border-box;
|
|
-moz-box-sizing: border-box;
|
|
box-sizing: border-box;
|
|
-webkit-background-clip: padding;
|
|
-moz-background-clip: padding;
|
|
background-clip:padding-box;
|
|
-webkit-border-radius:0;
|
|
-moz-border-radius:0;
|
|
-ms-border-radius:0;
|
|
-o-border-radius:0;
|
|
border-radius:0;
|
|
-webkit-appearance:none;
|
|
background-color:#fff;
|
|
color:#000;
|
|
outline:0;
|
|
margin:0;
|
|
padding:0;
|
|
text-align: left;
|
|
font-size:1em;
|
|
height: 1.8em;
|
|
vertical-align: middle;
|
|
}
|
|
select, select, select {
|
|
background:#fff
|
|
url('data:image/png;base64,\
|
|
R0lGODlhDQAEAIAAAAAAAP8A/yH5BAEHAAEAL\
|
|
AAAAAANAAQAAAILhA+hG5jMDpxvhgIAOw==');
|
|
background-repeat: no-repeat;
|
|
background-position: 97% center;
|
|
padding:0 25px 0 8px;
|
|
font-size: .875em;
|
|
}
|
|
|
|
// ! FORM RESET
|
|
</style>
|
|
`;
|
|
const codeDisabledError = `
|
|
<script>
|
|
window.__err = new Error('code has been disabled');
|
|
</script>
|
|
`;
|
|
|
|
const iFrameScript$ =
|
|
common.getScriptContent$('/js/iFrameScripts.js').shareReplay();
|
|
const jQueryScript$ = common.getScriptContent$(
|
|
'/bower_components/jquery/dist/jquery.js'
|
|
).shareReplay();
|
|
|
|
// behavior subject allways remembers the last value
|
|
// we use this to determine if runPreviewTest$ is defined
|
|
// and prime it with false
|
|
common.previewReady$ = new BehaviorSubject(false);
|
|
|
|
// These should be set up in the preview window
|
|
// if this error is seen it is because the function tried to run
|
|
// before the iframe has completely loaded
|
|
common.runPreviewTests$ =
|
|
common.checkPreview$ =
|
|
() => Observable.throw(new Error('Preview not fully loaded'));
|
|
|
|
|
|
common.updatePreview$ = function updatePreview$(code = '') {
|
|
const preview = common.getIframe('preview');
|
|
|
|
return Observable.combineLatest(
|
|
iFrameScript$,
|
|
jQueryScript$,
|
|
(iframe, jQuery) => ({
|
|
iframeScript: `<script>${iframe}</script>`,
|
|
jQuery: `<script>${jQuery}</script>`
|
|
})
|
|
)
|
|
.first()
|
|
.flatMap(({ iframeScript, jQuery }) => {
|
|
// we make sure to override the last value in the
|
|
// subject to false here.
|
|
common.previewReady$.onNext(false);
|
|
preview.open();
|
|
preview.write(
|
|
libraryIncludes +
|
|
jQuery +
|
|
(common.shouldRun() ? code : codeDisabledError) +
|
|
'<!-- -->' +
|
|
iframeScript
|
|
);
|
|
preview.close();
|
|
// now we filter false values and wait for the first true
|
|
return common.previewReady$
|
|
.filter(ready => ready)
|
|
.first()
|
|
// the delay here is to give code within the iframe
|
|
// control to run
|
|
.delay(400);
|
|
})
|
|
.map(() => code);
|
|
};
|
|
|
|
return common;
|
|
}(window));
|