mirror of
https://github.com/chinchang/web-maker.git
synced 2025-08-01 11:00:28 +02:00
@@ -4,6 +4,7 @@
|
||||
<title>Web Maker</title>
|
||||
<link rel="stylesheet" href="lib/codemirror/lib/codemirror.css">
|
||||
<link rel="stylesheet" href="lib/codemirror/theme/monokai.css">
|
||||
<link rel="stylesheet" href="lib/codemirror/addon/hint/show-hint.css">
|
||||
<link rel="stylesheet" href="lib/codemirror/addon/fold/foldgutter.css">
|
||||
<link rel="stylesheet" href="lib/hint.min.css">
|
||||
<link rel="stylesheet" href="lib/inlet.css">
|
||||
@@ -60,6 +61,7 @@
|
||||
<ul class="js-modes-menu dropdown__menu">
|
||||
<li><a data-type="css" data-mode="css">CSS</a></li>
|
||||
<li><a data-type="css" data-mode="scss">SCSS</a></li>
|
||||
<li><a data-type="css" data-mode="sass">SASS</a></li>
|
||||
<li><a data-type="css" data-mode="less">LESS</a></li>
|
||||
<li><a data-type="css" data-mode="stylus">Stylus</a></li>
|
||||
</ul>
|
||||
@@ -126,6 +128,11 @@
|
||||
<use xlink:href="#mode-icon" />
|
||||
</svg>
|
||||
</a>
|
||||
<a id="layoutBtn4" class="mode-btn hint--top-left hint--rounded" aria-label="Full Screen">
|
||||
<svg viewBox="0 0 100 100">
|
||||
<rect x="0" y="0" width="100" height="100" />
|
||||
</svg>
|
||||
</a>
|
||||
|
||||
<div class="footer__separator"></div>
|
||||
|
||||
@@ -187,7 +194,7 @@
|
||||
|
||||
<div class="modal" id="helpModal">
|
||||
<div class="modal__content">
|
||||
<h1>Web Maker<small style="font-size:14px;"> v2.1.0</small></h1>
|
||||
<h1>Web Maker<small style="font-size:14px;"> v2.2.0</small></h1>
|
||||
<div>
|
||||
<p>Made by <a href="https://twitter.com/chinchang457" target="_blank">Kushagra Gour</a></p>
|
||||
<p>Tweet out your feature requests, comments & suggestions to <a target="_blank" href="https://twitter.com/webmakerApp">@webmakerApp</a>.</p>
|
||||
@@ -281,6 +288,20 @@
|
||||
<div class="modal" id="notificationsModal">
|
||||
<div class="modal__content">
|
||||
<h1>Whats new?</h1>
|
||||
<div class="notification">
|
||||
<span class="notification__version">2.2.0</span>
|
||||
<ul>
|
||||
<li><strong>Code Autocompletion</strong> - See code suggestions while you type!</li>
|
||||
<li><strong>Full Screen Preview</strong> - Checkout your creation in a full-screen layout.</li>
|
||||
<li><strong>SASS</strong> - SASS support added for CSS.</li>
|
||||
<li><strong>Faster CSS update</strong> - Preview updates instantly without refresh when just CSS is changed.</li>
|
||||
<li><strong>Bugfix</strong> - Indentation fixed while going on new line.</li>
|
||||
<li><strong>Bugfix</strong> - Works even in Chrome Canary now. Though libraries can be added only through CDNs.</li>
|
||||
<li><a href="https://github.com/chinchang/web-maker/issues" target="_blank">Suggest a feature.</a></li>
|
||||
<li>Thank you for being a part of this awesome 4000+ developers community. If you find Web Maker helpful, <a href="https://chrome.google.com/webstore/detail/web-maker/lkfkkhfhhdkiemehlpkgjeojomhpccnh/reviews" target="_blank" class="btn">Please rate Web Maker <span class="star"></span></a> & <a href="http://twitter.com/share?url=https://kushagragour.in/lab/web-maker/&text=Web Maker - Convert your Chrome tabs into a blazing fast offline web playground! via @webmakerApp&related=webmakerApp&hashtags=web,editor" target="_blank" target="_blank" class="btn">share it</a>.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="notification">
|
||||
<span class="notification__version">2.1.0</span>
|
||||
<ul>
|
||||
@@ -289,7 +310,6 @@
|
||||
<li><strong>Code Folding</strong> - Collapse large code blocks for easy editing.</li>
|
||||
<li><strong>Bugfix</strong> - Support JSX in JavaScript.</li>
|
||||
<li>Better onboarding for first time users.</li>
|
||||
<li>Like it? <a href="https://chrome.google.com/webstore/detail/web-maker/lkfkkhfhhdkiemehlpkgjeojomhpccnh/reviews" target="_blank" class="btn">Please rate Web Maker <span class="star"></span></a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="notification">
|
||||
@@ -361,6 +381,11 @@
|
||||
<script src="lib/codemirror/addon/fold/comment-fold.js"></script>
|
||||
<script src="lib/codemirror/addon/fold/brace-fold.js"></script>
|
||||
<script src="lib/codemirror/addon/mode/loadmode.js"></script>
|
||||
<script src="lib/codemirror/addon/hint/show-hint.js"></script>
|
||||
<script src="lib/codemirror/addon/hint/javascript-hint.js"></script>
|
||||
<script src="lib/codemirror/addon/hint/xml-hint.js"></script>
|
||||
<script src="lib/codemirror/addon/hint/html-hint.js"></script>
|
||||
<script src="lib/codemirror/addon/hint/css-hint.js"></script>
|
||||
|
||||
<script src="lib/codemirror/mode/xml/xml.js"></script>
|
||||
<script src="lib/codemirror/mode/javascript/javascript.js"></script>
|
||||
|
148
src/lib/codemirror/mode/jsx/jsx.js
vendored
Normal file
148
src/lib/codemirror/mode/jsx/jsx.js
vendored
Normal file
@@ -0,0 +1,148 @@
|
||||
// CodeMirror, copyright (c) by Marijn Haverbeke and others
|
||||
// Distributed under an MIT license: http://codemirror.net/LICENSE
|
||||
|
||||
(function(mod) {
|
||||
if (typeof exports == "object" && typeof module == "object") // CommonJS
|
||||
mod(require("../../lib/codemirror"), require("../xml/xml"), require("../javascript/javascript"))
|
||||
else if (typeof define == "function" && define.amd) // AMD
|
||||
define(["../../lib/codemirror", "../xml/xml", "../javascript/javascript"], mod)
|
||||
else // Plain browser env
|
||||
mod(CodeMirror)
|
||||
})(function(CodeMirror) {
|
||||
"use strict"
|
||||
|
||||
// Depth means the amount of open braces in JS context, in XML
|
||||
// context 0 means not in tag, 1 means in tag, and 2 means in tag
|
||||
// and js block comment.
|
||||
function Context(state, mode, depth, prev) {
|
||||
this.state = state; this.mode = mode; this.depth = depth; this.prev = prev
|
||||
}
|
||||
|
||||
function copyContext(context) {
|
||||
return new Context(CodeMirror.copyState(context.mode, context.state),
|
||||
context.mode,
|
||||
context.depth,
|
||||
context.prev && copyContext(context.prev))
|
||||
}
|
||||
|
||||
CodeMirror.defineMode("jsx", function(config, modeConfig) {
|
||||
var xmlMode = CodeMirror.getMode(config, {name: "xml", allowMissing: true, multilineTagIndentPastTag: false})
|
||||
var jsMode = CodeMirror.getMode(config, modeConfig && modeConfig.base || "javascript")
|
||||
|
||||
function flatXMLIndent(state) {
|
||||
var tagName = state.tagName
|
||||
state.tagName = null
|
||||
var result = xmlMode.indent(state, "")
|
||||
state.tagName = tagName
|
||||
return result
|
||||
}
|
||||
|
||||
function token(stream, state) {
|
||||
if (state.context.mode == xmlMode)
|
||||
return xmlToken(stream, state, state.context)
|
||||
else
|
||||
return jsToken(stream, state, state.context)
|
||||
}
|
||||
|
||||
function xmlToken(stream, state, cx) {
|
||||
if (cx.depth == 2) { // Inside a JS /* */ comment
|
||||
if (stream.match(/^.*?\*\//)) cx.depth = 1
|
||||
else stream.skipToEnd()
|
||||
return "comment"
|
||||
}
|
||||
|
||||
if (stream.peek() == "{") {
|
||||
xmlMode.skipAttribute(cx.state)
|
||||
|
||||
var indent = flatXMLIndent(cx.state), xmlContext = cx.state.context
|
||||
// If JS starts on same line as tag
|
||||
if (xmlContext && stream.match(/^[^>]*>\s*$/, false)) {
|
||||
while (xmlContext.prev && !xmlContext.startOfLine)
|
||||
xmlContext = xmlContext.prev
|
||||
// If tag starts the line, use XML indentation level
|
||||
if (xmlContext.startOfLine) indent -= config.indentUnit
|
||||
// Else use JS indentation level
|
||||
else if (cx.prev.state.lexical) indent = cx.prev.state.lexical.indented
|
||||
// Else if inside of tag
|
||||
} else if (cx.depth == 1) {
|
||||
indent += config.indentUnit
|
||||
}
|
||||
|
||||
state.context = new Context(CodeMirror.startState(jsMode, indent),
|
||||
jsMode, 0, state.context)
|
||||
return null
|
||||
}
|
||||
|
||||
if (cx.depth == 1) { // Inside of tag
|
||||
if (stream.peek() == "<") { // Tag inside of tag
|
||||
xmlMode.skipAttribute(cx.state)
|
||||
state.context = new Context(CodeMirror.startState(xmlMode, flatXMLIndent(cx.state)),
|
||||
xmlMode, 0, state.context)
|
||||
return null
|
||||
} else if (stream.match("//")) {
|
||||
stream.skipToEnd()
|
||||
return "comment"
|
||||
} else if (stream.match("/*")) {
|
||||
cx.depth = 2
|
||||
return token(stream, state)
|
||||
}
|
||||
}
|
||||
|
||||
var style = xmlMode.token(stream, cx.state), cur = stream.current(), stop
|
||||
if (/\btag\b/.test(style)) {
|
||||
if (/>$/.test(cur)) {
|
||||
if (cx.state.context) cx.depth = 0
|
||||
else state.context = state.context.prev
|
||||
} else if (/^</.test(cur)) {
|
||||
cx.depth = 1
|
||||
}
|
||||
} else if (!style && (stop = cur.indexOf("{")) > -1) {
|
||||
stream.backUp(cur.length - stop)
|
||||
}
|
||||
return style
|
||||
}
|
||||
|
||||
function jsToken(stream, state, cx) {
|
||||
if (stream.peek() == "<" && jsMode.expressionAllowed(stream, cx.state)) {
|
||||
jsMode.skipExpression(cx.state)
|
||||
state.context = new Context(CodeMirror.startState(xmlMode, jsMode.indent(cx.state, "")),
|
||||
xmlMode, 0, state.context)
|
||||
return null
|
||||
}
|
||||
|
||||
var style = jsMode.token(stream, cx.state)
|
||||
if (!style && cx.depth != null) {
|
||||
var cur = stream.current()
|
||||
if (cur == "{") {
|
||||
cx.depth++
|
||||
} else if (cur == "}") {
|
||||
if (--cx.depth == 0) state.context = state.context.prev
|
||||
}
|
||||
}
|
||||
return style
|
||||
}
|
||||
|
||||
return {
|
||||
startState: function() {
|
||||
return {context: new Context(CodeMirror.startState(jsMode), jsMode)}
|
||||
},
|
||||
|
||||
copyState: function(state) {
|
||||
return {context: copyContext(state.context)}
|
||||
},
|
||||
|
||||
token: token,
|
||||
|
||||
indent: function(state, textAfter, fullLine) {
|
||||
return state.context.mode.indent(state.context.state, textAfter, fullLine)
|
||||
},
|
||||
|
||||
innerMode: function(state) {
|
||||
return state.context
|
||||
}
|
||||
}
|
||||
}, "xml", "javascript")
|
||||
|
||||
CodeMirror.defineMIME("text/jsx", "jsx")
|
||||
CodeMirror.defineMIME("text/typescript-jsx", {name: "jsx", base: {name: "javascript", typescript: true}})
|
||||
});
|
@@ -8,7 +8,7 @@
|
||||
"storage",
|
||||
"tabs"
|
||||
],
|
||||
"content_security_policy": "script-src 'self' https://www.google-analytics.com 'unsafe-eval'; object-src 'self'",
|
||||
"content_security_policy": "script-src 'self' https://ajax.googleapis.com https://code.jquery.com https://cdnjs.cloudflare.com https://unpkg.com https://maxcdn.bootstrapcdn.com https://cdn.jsdelivr.net/ https://www.google-analytics.com 'unsafe-eval'; object-src 'self'",
|
||||
"options_ui": {
|
||||
"page": "options.html",
|
||||
"chrome_style": true
|
||||
|
143
src/script.js
143
src/script.js
@@ -1,6 +1,6 @@
|
||||
/* global trackEvent */
|
||||
/* global layoutBtn1, layoutBtn2, layoutBtn3, helpModal, notificationsModal, addLibraryModal,
|
||||
onboardModal, layoutBtn1, layoutBtn2, layoutBtn3, helpBtn, onboardModal, onboardModal,
|
||||
onboardModal, layoutBtn1, layoutBtn2, layoutBtn3, layoutBtn4, helpBtn, onboardModal, onboardModal,
|
||||
addLibraryModal, addLibraryModal, notificationsBtn, notificationsModal, notificationsModal,
|
||||
notificationsModal, notificationsBtn, codepenBtn, saveHtmlBtn, openBtn, saveBtn, newBtn,
|
||||
settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardDontShowInTabOptionBtn */
|
||||
@@ -9,7 +9,7 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
|
||||
|
||||
/* eslint-enable no-extra-semi */
|
||||
var scope = scope || {};
|
||||
var version = '2.1.0';
|
||||
var version = '2.2.0';
|
||||
|
||||
if (window.DEBUG) {
|
||||
window.scope = scope;
|
||||
@@ -23,6 +23,7 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
|
||||
var CssModes = {
|
||||
CSS: 'css',
|
||||
SCSS: 'scss',
|
||||
SASS: 'sass',
|
||||
LESS: 'less',
|
||||
STYLUS: 'stylus'
|
||||
};
|
||||
@@ -39,10 +40,11 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
|
||||
modes[JsModes.JS] = { label: 'JS', cmMode: 'javascript', codepenVal: 'none' };
|
||||
modes[JsModes.COFFEESCRIPT] = { label: 'CoffeeScript', cmMode: 'coffeescript', codepenVal: 'coffeescript' };
|
||||
modes[JsModes.ES6] = { label: 'ES6 (Babel)', cmMode: 'jsx', codepenVal: 'babel' };
|
||||
modes[JsModes.TS] = { label: 'TypeScript', cmMode: 'javascript', codepenVal: 'typescript' };
|
||||
modes[CssModes.CSS] = { label: 'CSS', cmMode: 'css', codepenVal: 'none' };
|
||||
modes[CssModes.SCSS] = { label: 'SCSS', cmMode: 'sass', codepenVal: 'scss' };
|
||||
modes[CssModes.LESS] = { label: 'LESS', cmMode: 'text/x-less', codepenVal: 'less' };
|
||||
modes[JsModes.TS] = { label: 'TypeScript', cmPath: 'jsx', cmMode: 'text/typescript-jsx', codepenVal: 'typescript' };
|
||||
modes[CssModes.CSS] = { label: 'CSS', cmPath: 'css', cmMode: 'css', codepenVal: 'none' };
|
||||
modes[CssModes.SCSS] = { label: 'SCSS', cmPath: 'css', cmMode: 'text/x-scss', codepenVal: 'scss' };
|
||||
modes[CssModes.SASS] = { label: 'SASS', cmMode: 'sass', codepenVal: 'sass' };
|
||||
modes[CssModes.LESS] = { label: 'LESS', cmPath: 'css', cmMode: 'text/x-less', codepenVal: 'less' };
|
||||
modes[CssModes.STYLUS] = { label: 'Stylus', cmMode: 'stylus', codepenVal: 'stylus' };
|
||||
|
||||
var updateTimer
|
||||
@@ -60,6 +62,7 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
|
||||
, codeSplitInstance
|
||||
// TODO: for legacy reasons when. Will be refactored as global preferences.
|
||||
, prefs = {}
|
||||
, codeInPreview = { html: null, css: null, js: null }
|
||||
|
||||
// DOM nodes
|
||||
, frame = $('#demo-frame')
|
||||
@@ -137,7 +140,10 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
|
||||
mainSplitInstance = Split(['#js-code-side', '#js-demo-side' ], {
|
||||
direction: (currentLayoutMode === 2 ? 'vertical' : 'horizontal'),
|
||||
minSize: 34,
|
||||
gutterSize: 6
|
||||
gutterSize: 6,
|
||||
onDragEnd: function () {
|
||||
scope.setPreviewContent(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
function toggleLayout(mode) {
|
||||
@@ -151,19 +157,22 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
|
||||
layoutBtn1.classList.remove('selected');
|
||||
layoutBtn2.classList.remove('selected');
|
||||
layoutBtn3.classList.remove('selected');
|
||||
layoutBtn4.classList.remove('selected');
|
||||
$('#layoutBtn' + mode).classList.add('selected');
|
||||
document.body.classList.remove('layout-1');
|
||||
document.body.classList.remove('layout-2');
|
||||
document.body.classList.remove('layout-3');
|
||||
document.body.classList.remove('layout-4');
|
||||
document.body.classList.add('layout-' + mode);
|
||||
|
||||
resetSplitting();
|
||||
scope.setPreviewContent(true);
|
||||
}
|
||||
|
||||
function onExternalLibChange() {
|
||||
utils.log('onExternalLibChange');
|
||||
updateExternalLibUi();
|
||||
scope.setPreviewContent();
|
||||
scope.setPreviewContent(true);
|
||||
}
|
||||
|
||||
function updateExternalLibUi() {
|
||||
@@ -388,7 +397,7 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
|
||||
loadJS('lib/marked.js').then(setLoadedFlag);
|
||||
} else if (mode === CssModes.LESS) {
|
||||
loadJS('lib/less.min.js').then(setLoadedFlag);
|
||||
} else if (mode === CssModes.SCSS) {
|
||||
} else if (mode === CssModes.SCSS || mode === CssModes.SASS) {
|
||||
loadJS('lib/sass.js').then(function () {
|
||||
sass = new Sass('lib/sass.worker.js');
|
||||
setLoadedFlag();
|
||||
@@ -409,7 +418,7 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
|
||||
htmlModelLabel.textContent = modes[value].label;
|
||||
handleModeRequirements(value);
|
||||
scope.cm.html.setOption('mode', modes[value].cmMode);
|
||||
CodeMirror.autoLoadMode(scope.cm.html, modes[value].cmMode);
|
||||
CodeMirror.autoLoadMode(scope.cm.html, modes[value].cmPath || modes[value].cmMode);
|
||||
trackEvent('ui', 'updateCodeMode', 'html', value);
|
||||
}
|
||||
function updateCssMode(value) {
|
||||
@@ -417,7 +426,7 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
|
||||
cssModelLabel.textContent = modes[value].label;
|
||||
handleModeRequirements(value);
|
||||
scope.cm.css.setOption('mode', modes[value].cmMode);
|
||||
CodeMirror.autoLoadMode(scope.cm.css, modes[value].cmMode);
|
||||
CodeMirror.autoLoadMode(scope.cm.css, modes[value].cmPath || modes[value].cmMode);
|
||||
trackEvent('ui', 'updateCodeMode', 'css', value);
|
||||
}
|
||||
function updateJsMode(value) {
|
||||
@@ -425,7 +434,7 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
|
||||
jsModelLabel.textContent = modes[value].label;
|
||||
handleModeRequirements(value);
|
||||
scope.cm.js.setOption('mode', modes[value].cmMode);
|
||||
CodeMirror.autoLoadMode(scope.cm.js, modes[value].cmMode);
|
||||
CodeMirror.autoLoadMode(scope.cm.js, modes[value].cmPath || modes[value].cmMode);
|
||||
trackEvent('ui', 'updateCodeMode', 'js', value);
|
||||
// FIXME: Will be saved as part of scope settings
|
||||
/*
|
||||
@@ -457,9 +466,9 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
|
||||
|
||||
if (cssMode === CssModes.CSS) {
|
||||
d.resolve(code);
|
||||
} else if (cssMode === CssModes.SCSS) {
|
||||
sass.compile(code, function(result) {
|
||||
// Something as wrong
|
||||
} else if (cssMode === CssModes.SCSS || cssMode === CssModes.SASS) {
|
||||
sass.compile(code, { indentedSyntax: cssMode === CssModes.SASS }, function(result) {
|
||||
// Something was wrong
|
||||
if (result.line && result.message) {
|
||||
showErrors('css', [ { lineNumber: result.line - 1, message: result.message } ]);
|
||||
}
|
||||
@@ -598,7 +607,7 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
|
||||
});
|
||||
}
|
||||
|
||||
function getCompleteHtml(html, css, js) {
|
||||
function getCompleteHtml(html, css) {
|
||||
var externalJs = externalJsTextarea.value.split('\n').reduce(function (scripts, url) {
|
||||
return scripts + (url ? '\n<script src="' + url + '"></script>' : '');
|
||||
}, '');
|
||||
@@ -607,17 +616,47 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
|
||||
}, '');
|
||||
var contents = '<html>\n<head>\n'
|
||||
+ externalCss + '\n'
|
||||
+ '<style>\n' + css + '\n</style>\n'
|
||||
+ '<style id="webmakerstyle">\n' + css + '\n</style>\n'
|
||||
+ '</head>\n'
|
||||
+ '<body>\n' + html + '\n'
|
||||
+ externalJs + '\n<script>\n' + js + '\n//# sourceURL=userscript.js</script></body>\n</html>';
|
||||
+ externalJs + '\n<script src="'
|
||||
+ 'filesystem:chrome-extension://'
|
||||
+ chrome.i18n.getMessage('@@extension_id') + '/temporary/' + 'script.js' + '">\n'
|
||||
+ '</script></body>\n</html>';
|
||||
|
||||
return contents;
|
||||
}
|
||||
|
||||
function writeFile(name, blob, cb) {
|
||||
var fileWritten = false;
|
||||
function errorHandler() { utils.log(arguments); }
|
||||
|
||||
window.webkitRequestFileSystem(window.TEMPORARY, 1024 * 1024 * 5, function(fs){
|
||||
fs.root.getFile(name, { create: true }, function(fileEntry) {
|
||||
fileEntry.createWriter(function(fileWriter) {
|
||||
function onWriteComplete() {
|
||||
if (fileWritten) {
|
||||
return cb();
|
||||
}
|
||||
fileWritten = true;
|
||||
// Set the write pointer to starting of file
|
||||
fileWriter.seek(0);
|
||||
fileWriter.write(blob);
|
||||
return false;
|
||||
}
|
||||
fileWriter.onwriteend = onWriteComplete;
|
||||
// Empty the file contents
|
||||
fileWriter.truncate(0)
|
||||
}, errorHandler);
|
||||
}, errorHandler);
|
||||
}, errorHandler);
|
||||
|
||||
}
|
||||
|
||||
function createPreviewFile(html, css, js) {
|
||||
var contents = getCompleteHtml(html, css, js);
|
||||
var fileWritten = false;
|
||||
var blob = new Blob([ contents ], { type: "text/plain;charset=UTF-8" });
|
||||
var blobjs = new Blob([ js ], { type: "text/plain;charset=UTF-8" });
|
||||
|
||||
// Track if people have written code.
|
||||
if (!trackEvent.hasTrackedCode && (html || css || js)) {
|
||||
@@ -630,38 +669,41 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
|
||||
trackEvent('fn', 'usingPreview');
|
||||
}
|
||||
|
||||
function errorHandler() { utils.log(arguments); }
|
||||
// we need to store user script in external JS file to prevent inline-script
|
||||
// CSP from affecting it.
|
||||
writeFile('script.js', blobjs, function () {
|
||||
writeFile('preview.html', blob, function () {
|
||||
frame.src = 'filesystem:chrome-extension://'
|
||||
+ chrome.i18n.getMessage('@@extension_id') + '/temporary/' + 'preview.html';
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
window.webkitRequestFileSystem(window.TEMPORARY, 1024 * 1024 * 5, function(fs){
|
||||
fs.root.getFile('preview.html', { create: true }, function(fileEntry) {
|
||||
fileEntry.createWriter(function(fileWriter) {
|
||||
function onWriteComplete() {
|
||||
if (fileWritten) {
|
||||
frame.src = 'filesystem:chrome-extension://'
|
||||
+ chrome.i18n.getMessage('@@extension_id') + '/temporary/' + 'preview.html';
|
||||
}
|
||||
else {
|
||||
fileWritten = true;
|
||||
// Set the write pointer to starting of file
|
||||
fileWriter.seek(0);
|
||||
fileWriter.write(blob);
|
||||
}
|
||||
}
|
||||
fileWriter.onwriteend = onWriteComplete;
|
||||
// Empty the file contents
|
||||
fileWriter.truncate(0)
|
||||
}, errorHandler);
|
||||
}, errorHandler);
|
||||
}, errorHandler);
|
||||
}
|
||||
|
||||
scope.setPreviewContent = function () {
|
||||
var htmlPromise = computeHtml();
|
||||
var cssPromise = computeCss();
|
||||
var jsPromise = computeJs();
|
||||
Promise.all([htmlPromise, cssPromise, jsPromise]).then(function (result) {
|
||||
createPreviewFile(result[0], result[1], result[2]);
|
||||
});
|
||||
scope.setPreviewContent = function (isForced) {
|
||||
var currentCode = {
|
||||
html: scope.cm.html.getValue(),
|
||||
css: scope.cm.css.getValue(),
|
||||
js: scope.cm.js.getValue()
|
||||
};
|
||||
// If just CSS was changed (and everything shudn't be empty),
|
||||
// change the styles inside the iframe.
|
||||
if (!isForced && currentCode.html === codeInPreview.html && currentCode.js === codeInPreview.js) {
|
||||
computeCss().then(function (css) {
|
||||
frame.contentDocument.querySelector('#webmakerstyle').textContent = css;
|
||||
});
|
||||
} else {
|
||||
var htmlPromise = computeHtml();
|
||||
var cssPromise = computeCss();
|
||||
var jsPromise = computeJs();
|
||||
Promise.all([htmlPromise, cssPromise, jsPromise]).then(function (result) {
|
||||
createPreviewFile(result[0], result[1], result[2]);
|
||||
});
|
||||
}
|
||||
codeInPreview.html = currentCode.html;
|
||||
codeInPreview.css = currentCode.css;
|
||||
codeInPreview.js = currentCode.js;
|
||||
};
|
||||
|
||||
function saveFile() {
|
||||
@@ -714,6 +756,10 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
|
||||
scope.setPreviewContent();
|
||||
}, updateDelay);
|
||||
});
|
||||
cm.on('inputRead', function onChange(editor, input) {
|
||||
if (input.text[0] === ';') { return; }
|
||||
CodeMirror.commands.autocomplete(cm, null, { completeSingle: false })
|
||||
});
|
||||
return cm;
|
||||
}
|
||||
|
||||
@@ -790,6 +836,7 @@ settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardD
|
||||
layoutBtn1.addEventListener('click', getToggleLayoutButtonListener(1));
|
||||
layoutBtn2.addEventListener('click', getToggleLayoutButtonListener(2));
|
||||
layoutBtn3.addEventListener('click', getToggleLayoutButtonListener(3));
|
||||
layoutBtn4.addEventListener('click', getToggleLayoutButtonListener(4));
|
||||
|
||||
utils.onButtonClick(helpBtn, function () {
|
||||
helpModal.classList.toggle('is-modal-visible');
|
||||
|
@@ -8,6 +8,7 @@
|
||||
:root {
|
||||
--color-bg: #252637;
|
||||
--color-sidebar: #3A2B63;
|
||||
--code-font-size: 16px;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
@@ -106,6 +107,15 @@ select, input[type="text"], textarea {
|
||||
flex-direction: row;
|
||||
width: auto;
|
||||
}
|
||||
.layout-4 .code-side {
|
||||
display: none;
|
||||
}
|
||||
.layout-4 .code-side + .gutter {
|
||||
display: none;
|
||||
}
|
||||
.layout-4 .demo-side {
|
||||
width: 100% !important;
|
||||
}
|
||||
.code-wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -182,7 +192,7 @@ select, input[type="text"], textarea {
|
||||
.Codemirror {
|
||||
width: 100%;
|
||||
height: calc(100% - 25px); /* 25px for header */
|
||||
font-size: 16px;
|
||||
font-size: var(--code-font-size);
|
||||
}
|
||||
.layout-2 .is-minimized .Codemirror {
|
||||
height: calc(100%);
|
||||
@@ -206,7 +216,19 @@ select, input[type="text"], textarea {
|
||||
.CodeMirror-gutter-wrapper:hover .CodeMirror-guttermarker-subtle {
|
||||
/*visibility: visible;*/
|
||||
}
|
||||
|
||||
.CodeMirror-hints {
|
||||
font-size: var(--code-font-size);
|
||||
border: 0;
|
||||
background: #1e1e2c;
|
||||
}
|
||||
.CodeMirror-hint {
|
||||
color: #bbb;
|
||||
padding: 2px 4px;
|
||||
}
|
||||
li.CodeMirror-hint-active {
|
||||
background: #5b429d;
|
||||
/*color: white;*/
|
||||
}
|
||||
#demo-frame {
|
||||
border: 0;
|
||||
width: 100%;
|
||||
@@ -552,7 +574,7 @@ select, input[type="text"], textarea {
|
||||
}
|
||||
.dropdown__menu > li > a {
|
||||
display: block;
|
||||
padding: 15px;
|
||||
padding: 10px 15px;
|
||||
color: #333;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
Reference in New Issue
Block a user