mirror of
https://github.com/chinchang/web-maker.git
synced 2025-08-06 05:17:31 +02:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
Web-Maker 
|
||||
======
|
||||
|
||||
**Web-Maker** is a chrome extension that converts your Chrome tabs into an offline playground for your web experiments. Something like CodePen or JSFiddle, but much more faster and works offline being local on your system.
|
||||
**Web-Maker** is a chrome extension that converts your Chrome tab into an offline playground for your web experiments. Something like CodePen or JSFiddle, but much more faster and works offline being local on your system.
|
||||
|
||||
### [INSTALL EXTENSION](https://chrome.google.com/webstore/detail/web-maker/lkfkkhfhhdkiemehlpkgjeojomhpccnh)
|
||||
|
||||
@@ -11,6 +11,7 @@ Web-Maker 
|
||||
|
||||
* Supports Preprocessors: HTML (Jade & Markdown), CSS (SCSS, LESS & Stylus) & JavaScript (ES6, TypeScript & CoffeeScript)
|
||||
* Works offline
|
||||
* Inbuilt Console
|
||||
* Save and load your creations
|
||||
* Code auto-completion
|
||||
* Easy addition of popular JS & CSS libraries
|
||||
@@ -24,6 +25,10 @@ Web-Maker 
|
||||
|
||||
Follow [@webmakerApp](https://twitter.com/intent/follow?screen_name=webmakerApp) for updates or tweet out feature requests and suggestions.
|
||||
|
||||
### Support Web Maker
|
||||
|
||||
Web Maker is completely free and open-source. If you find it useful, you can show your support by sharing it in your social network or by donating on [Gratipay](https://gratipay.com/Web-Maker/) or by simply letting me know how much you 💖 it by tweeting to [@webmakerapp](https://twitter.com/webmakerApp).
|
||||
|
||||
### License
|
||||
|
||||
MIT Licensed
|
||||
|
@@ -23,7 +23,7 @@
|
||||
</svg>Run
|
||||
</a>
|
||||
|
||||
<a id="js-add-library-btn" class="fleex-v-center hint--rounded hint--bottom-left" aria-label="Add a JS/CSS library">
|
||||
<a id="js-add-library-btn" class="flex-v-center hint--rounded hint--bottom-left" aria-label="Add a JS/CSS library">
|
||||
Add library <span id="js-external-lib-count" style="display:none;" class="count-label"></span>
|
||||
</a>
|
||||
|
||||
@@ -101,6 +101,28 @@
|
||||
</div>
|
||||
<div class="demo-side" id="js-demo-side">
|
||||
<iframe src="about://blank" frameborder="0" id="demo-frame"></iframe>
|
||||
<div id="consoleEl" class="console is-minimized">
|
||||
<div id="consoleLogEl" class="console__log" class="code">
|
||||
<div class="js-console__header code-wrap__header" title="Double click to toggle console">
|
||||
<span class="code-wrap__header-label">Console (<span id="logCountEl">0</span>)</span>
|
||||
<div class="code-wrap__header-right-options">
|
||||
<a class="code-wrap__header-btn" title="Clear console (CTRL + L)" d-click="onClearConsoleBtnClick">
|
||||
<svg>
|
||||
<use xlink:href="#cancel-icon"></use>
|
||||
</svg>
|
||||
</a>
|
||||
<a class="code-wrap__header-btn code-wrap__collapse-btn" title="Toggle console" d-click="toggleConsole">
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="consolePromptEl" class="console__prompt flex flex-v-center">
|
||||
<svg width="18" height="18" fill="#346fd2">
|
||||
<use xlink:href="#chevron-icon"></use>
|
||||
</svg>
|
||||
<input d-keyup="evalConsoleExpr" class="console-exec-input">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer">
|
||||
@@ -224,7 +246,7 @@
|
||||
<p>
|
||||
<h3>Awesome libraries used</h3>
|
||||
<ul>
|
||||
<li><a target="_blank" href="http://kushagragour.in/lab/hint/">Hint.css</a> - By me :)</li>
|
||||
<li><a target="_blank" href="https://kushagragour.in/lab/hint/">Hint.css</a> & <a target="_blank" href="https://github.com/chinchang/screenlog.js">Screenlog.js</a> - By me :)</li>
|
||||
<li><a target="_blank" href="https://nathancahill.github.io/Split.js/">Split.js</a> - Nathan Cahill</li>
|
||||
<li><a target="_blank" href="https://codemirror.net/">Codemirror</a> - Marijn Haverbeke</li>
|
||||
<li><a target="_blank" href="https://emmet.io/">Emmet</a> - Sergey Chikuyonok</li>
|
||||
@@ -400,6 +422,18 @@
|
||||
<div class="modal" id="notificationsModal">
|
||||
<div class="modal__content">
|
||||
<h1>Whats new?</h1>
|
||||
<div class="notification">
|
||||
<span class="notification__version">2.6.0</span>
|
||||
<ul>
|
||||
<li><strong>The "Console"</strong>: The most awaited feature is here! There is now an inbuilt console to see your logs, errors and for quickly evaluating JavaScript code inside your preview. Enjoy! I also a <a href="https://kushagragour.in/blog/2017/05/web-maker-console-is-here/?utm_source=webmakerapp&utm_medium=referral" target="_blank">blog post about it</a>.</li>
|
||||
<li>Number slider which popped on clicking any number in the code has been removed due to poor user experience.</li>
|
||||
<li>Minor usability improvements.</li>
|
||||
|
||||
<li><a href="https://github.com/chinchang/web-maker/issues" target="_blank">Suggest features or report bugs.</a></li>
|
||||
<li>Thank you for being a part of this community of thousands of awesome developers. 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://webmakerapp.com/&text=Web Maker - A blazing fast %26 offline web playground! via @webmakerApp&related=webmakerApp&hashtags=web,editor,chrome,extension" target="_blank" target="_blank" class="btn">share it</a>.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="notification">
|
||||
<span class="notification__version">2.5.0</span>
|
||||
<ul>
|
||||
@@ -408,9 +442,6 @@
|
||||
<li><strong>Configurable Auto-preview</strong> - You can turn off the auto preview in settings if you don't want the preview to update as you type.</li>
|
||||
<li><strong>Configurable refresh on resize</strong> - You can configure whether you want the preview to refresh when you resize the preview panel.</li>
|
||||
<li><strong>Bugfix</strong> - Fix indentation <a href="https://github.com/chinchang/web-maker/issues/104" target="_blank">issue</a> with custom indentation size.</li>
|
||||
|
||||
<li><a href="https://github.com/chinchang/web-maker/issues" target="_blank">Suggest features or report bugs.</a></li>
|
||||
<li>Thank you for being a part of this community of thousands of awesome developers. 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://webmakerapp.com/&text=Web Maker - A blazing fast %26 offline web playground! via @webmakerApp&related=webmakerApp&hashtags=web,editor,chrome,extension" target="_blank" target="_blank" class="btn">share it</a>.</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -521,9 +552,9 @@
|
||||
<h3>My Library <span id="savedItemCountEl"></span></h3>
|
||||
|
||||
<div class="main-header__btn-wrap">
|
||||
<a d-click="exportItems" href="" class="btn btn-icon">Export
|
||||
<a d-click="exportItems" href="" class="btn btn-icon hint--bottom-left hint--rounded hint--medium" aria-label="Export all your creations into a single importable file.">Export
|
||||
</a>
|
||||
<a d-click="onImportBtnClicked" href="" class="btn btn-icon">Import
|
||||
<a d-click="onImportBtnClicked" href="" class="btn btn-icon hint--bottom-left hint--rounded hint--medium" aria-label="Only the file that you export through the 'Export' button can be imported.">Import
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@@ -577,6 +608,16 @@
|
||||
<path d="M8,5.14V19.14L19,12.14L8,5.14Z" />
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="cancel-icon" viewBox="0 0 24 24">
|
||||
<svg>
|
||||
<path d="M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2M12,4A8,8 0 0,0 4,12C4,13.85 4.63,15.55 5.68,16.91L16.91,5.68C15.55,4.63 13.85,4 12,4M12,20A8,8 0 0,0 20,12C20,10.15 19.37,8.45 18.32,7.09L7.09,18.32C8.45,19.37 10.15,20 12,20Z" />
|
||||
</svg>
|
||||
</symbol>
|
||||
<symbol id="chevron-icon" viewBox="0 0 24 24">
|
||||
<svg>
|
||||
<path d="M8.59,16.58L13.17,12L8.59,7.41L10,6L16,12L10,18L8.59,16.58Z" />
|
||||
</svg>
|
||||
</symbol>
|
||||
</svg>
|
||||
|
||||
<script src="lib/codemirror/lib/codemirror.js"></script>
|
||||
|
2
src/lib/inlet.min.js
vendored
2
src/lib/inlet.min.js
vendored
File diff suppressed because one or more lines are too long
183
src/lib/screenlog.js
Normal file
183
src/lib/screenlog.js
Normal file
@@ -0,0 +1,183 @@
|
||||
(function () {
|
||||
|
||||
var logEl,
|
||||
isInitialized = false,
|
||||
_console = {}; // backup console obj to contain references of overridden fns.
|
||||
_options = {
|
||||
bgColor: 'black',
|
||||
logColor: 'lightgreen',
|
||||
infoColor: 'blue',
|
||||
warnColor: 'orange',
|
||||
errorColor: 'red',
|
||||
freeConsole: false,
|
||||
css: '',
|
||||
autoScroll: true,
|
||||
proxyCallback: null,
|
||||
noUi: false
|
||||
};
|
||||
|
||||
function createElement(tag, css) {
|
||||
var element = document.createElement(tag);
|
||||
element.style.cssText = css;
|
||||
return element;
|
||||
}
|
||||
|
||||
function createPanel() {
|
||||
var div = createElement('div', 'z-index:2147483647;font-family:Helvetica,Arial,sans-serif;font-size:10px;font-weight:bold;padding:5px;text-align:left;opacity:0.8;position:fixed;right:0;top:0;min-width:200px;max-height:50vh;overflow:auto;background:' + _options.bgColor + ';' + _options.css);
|
||||
return div;
|
||||
}
|
||||
|
||||
function genericLogger(color) {
|
||||
return function() {
|
||||
if (_options.proxyCallback) {
|
||||
_options.proxyCallback.apply(null, arguments);
|
||||
}
|
||||
if (_options.noUi) { return; }
|
||||
var el = createElement('div', 'line-height:18px;min-height:18px;background:' +
|
||||
(logEl.children.length % 2 ? 'rgba(255,255,255,0.1)' : '') + ';color:' + color); // zebra lines
|
||||
var val = [].slice.call(arguments).reduce(function(prev, arg) {
|
||||
return prev + ' ' + (typeof arg === "object" ? JSON.stringify(arg) : arg);
|
||||
}, '');
|
||||
el.textContent = val;
|
||||
|
||||
logEl.appendChild(el);
|
||||
|
||||
// Scroll to last element, if autoScroll option is set.
|
||||
if(_options.autoScroll) {
|
||||
logEl.scrollTop = logEl.scrollHeight - logEl.clientHeight;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function clear() {
|
||||
logEl.innerHTML = '';
|
||||
}
|
||||
|
||||
function log() {
|
||||
return genericLogger(_options.logColor).apply(null, arguments);
|
||||
}
|
||||
|
||||
function info() {
|
||||
return genericLogger(_options.infoColor).apply(null, arguments);
|
||||
}
|
||||
|
||||
function warn() {
|
||||
return genericLogger(_options.warnColor).apply(null, arguments);
|
||||
}
|
||||
|
||||
function error() {
|
||||
return genericLogger(_options.errorColor).apply(null, arguments);
|
||||
}
|
||||
|
||||
function setOptions(options) {
|
||||
for(var i in options)
|
||||
if(options.hasOwnProperty(i) && _options.hasOwnProperty(i)) {
|
||||
_options[i] = options[i];
|
||||
}
|
||||
}
|
||||
|
||||
function init(options) {
|
||||
if (isInitialized) { return; }
|
||||
|
||||
isInitialized = true;
|
||||
|
||||
if(options) {
|
||||
setOptions(options);
|
||||
}
|
||||
|
||||
if (!_options.noUi) {
|
||||
logEl = createPanel();
|
||||
document.body.appendChild(logEl);
|
||||
}
|
||||
|
||||
if (!_options.freeConsole) {
|
||||
// Backup actual fns to keep it working together
|
||||
_console.log = console.log;
|
||||
_console.clear = console.clear;
|
||||
_console.info = console.info;
|
||||
_console.warn = console.warn;
|
||||
_console.error = console.error;
|
||||
console.log = originalFnCallDecorator(log, 'log');
|
||||
console.clear = originalFnCallDecorator(clear, 'clear');
|
||||
console.info = originalFnCallDecorator(info, 'info');
|
||||
console.warn = originalFnCallDecorator(warn, 'warn');
|
||||
console.error = originalFnCallDecorator(error, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
function destroy() {
|
||||
isInitialized = false;
|
||||
console.log = _console.log;
|
||||
console.clear = _console.clear;
|
||||
console.info = _console.info;
|
||||
console.warn = _console.warn;
|
||||
console.error = _console.error;
|
||||
logEl.remove();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checking if isInitialized is set
|
||||
*/
|
||||
function checkInitialized() {
|
||||
if (!isInitialized) {
|
||||
throw 'You need to call `screenLog.init()` first.';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Decorator for checking if isInitialized is set
|
||||
* @param {Function} fn Fn to decorate
|
||||
* @return {Function} Decorated fn.
|
||||
*/
|
||||
function checkInitDecorator(fn) {
|
||||
return function() {
|
||||
checkInitialized();
|
||||
return fn.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Decorator for calling the original console's fn at the end of
|
||||
* our overridden fn definitions.
|
||||
* @param {Function} fn Fn to decorate
|
||||
* @param {string} fn Name of original function
|
||||
* @return {Function} Decorated fn.
|
||||
*/
|
||||
function originalFnCallDecorator(fn, fnName) {
|
||||
return function() {
|
||||
fn.apply(this, arguments);
|
||||
if (typeof _console[fnName] === 'function') {
|
||||
_console[fnName].apply(console, arguments);
|
||||
}
|
||||
};
|
||||
}
|
||||
window.addEventListener('error', function() {
|
||||
genericLogger(_options.errorColor).call(null, arguments[0].error.stack);
|
||||
});
|
||||
|
||||
// Public API
|
||||
window.screenLog = {
|
||||
init: init,
|
||||
log: originalFnCallDecorator(checkInitDecorator(log), 'log'),
|
||||
clear: originalFnCallDecorator(checkInitDecorator(clear), 'clear'),
|
||||
info: originalFnCallDecorator(checkInitDecorator(clear), 'info'),
|
||||
warn: originalFnCallDecorator(checkInitDecorator(warn), 'warn'),
|
||||
error: originalFnCallDecorator(checkInitDecorator(error), 'error'),
|
||||
destroy: checkInitDecorator(destroy)
|
||||
};
|
||||
})();
|
||||
screenLog.init({
|
||||
noUi: true,
|
||||
proxyCallback: function () {
|
||||
window.parent.onMessageFromConsole.apply(null, arguments);
|
||||
}
|
||||
});
|
||||
window._wmEvaluate = function _wmEvaluate(expr) {
|
||||
try {
|
||||
var result = eval(expr);
|
||||
} catch(e) {
|
||||
window.parent.onMessageFromConsole.call(null, e);
|
||||
return;
|
||||
}
|
||||
window.parent.onMessageFromConsole.call(null, result);
|
||||
}
|
120
src/script.js
120
src/script.js
@@ -5,7 +5,7 @@ addLibraryModal, addLibraryModal, notificationsBtn, notificationsModal, notifica
|
||||
notificationsModal, notificationsBtn, codepenBtn, saveHtmlBtn, saveBtn, settingsBtn,
|
||||
onboardModal, settingsModal, notificationsBtn, onboardShowInTabOptionBtn, editorThemeLinkTag,
|
||||
onboardDontShowInTabOptionBtn, TextareaAutoComplete, savedItemCountEl, indentationSizeValueEl,
|
||||
runBtn, searchInput
|
||||
runBtn, searchInput, consoleEl, consoleLogEl, logCountEl
|
||||
*/
|
||||
/* eslint-disable no-extra-semi */
|
||||
;(function (alertsService) {
|
||||
@@ -71,6 +71,7 @@ runBtn, searchInput
|
||||
, codeInPreview = { html: null, css: null, js: null }
|
||||
, isSavedItemsPaneOpen = false
|
||||
, editorWithFocus
|
||||
, logCount = 0
|
||||
|
||||
// DOM nodes
|
||||
, frame = $('#demo-frame')
|
||||
@@ -91,6 +92,7 @@ runBtn, searchInput
|
||||
;
|
||||
|
||||
scope.cm = {};
|
||||
scope.frame = frame;
|
||||
scope.demoFrameDocument = frame.contentDocument || frame.contentWindow.document;
|
||||
|
||||
// Check all the code wrap if they are minimized or not
|
||||
@@ -175,8 +177,6 @@ runBtn, searchInput
|
||||
}
|
||||
function toggleLayout(mode) {
|
||||
if (currentLayoutMode === mode) {
|
||||
utils.log('setMainsize', currentItem.mainSizes || [ 50, 50 ]);
|
||||
utils.log('setsize', currentItem.sizes || [ 33.33, 33.33, 33.33 ]);
|
||||
mainSplitInstance.setSizes(getMainSplitSizesToApply());
|
||||
codeSplitInstance.setSizes(currentItem.sizes || [ 33.33, 33.33, 33.33 ]);
|
||||
currentLayoutMode = mode;
|
||||
@@ -463,6 +463,8 @@ runBtn, searchInput
|
||||
scope.cm.css.refresh();
|
||||
scope.cm.js.refresh();
|
||||
|
||||
scope.clearConsole();
|
||||
|
||||
// To have the library count updated
|
||||
updateExternalLibUi();
|
||||
|
||||
@@ -700,6 +702,7 @@ runBtn, searchInput
|
||||
|
||||
window.previewException = function (error) {
|
||||
console.error('Possible infinite loop detected.', error.stack)
|
||||
window.onMessageFromConsole('Possible infinite loop detected.', error.stack);
|
||||
}
|
||||
window.onunload = function () {
|
||||
saveCode('code');
|
||||
@@ -734,6 +737,9 @@ runBtn, searchInput
|
||||
+ '<body>\n' + html + '\n'
|
||||
+ externalJs + '\n';
|
||||
|
||||
contents += '<script src="'
|
||||
+ chrome.extension.getURL('lib/screenlog.js') + '"></script>';
|
||||
|
||||
if (js) {
|
||||
contents += '<script>\n' + js + '\n//# sourceURL=userscript.js';
|
||||
} else {
|
||||
@@ -972,8 +978,18 @@ runBtn, searchInput
|
||||
});
|
||||
Inlet(scope.cm.js);
|
||||
|
||||
// Initialize codemirror in console
|
||||
scope.consoleCm = CodeMirror(consoleLogEl, {
|
||||
mode: 'javascript',
|
||||
lineWrapping: true,
|
||||
theme: 'monokai',
|
||||
foldGutter: true,
|
||||
readOnly: true,
|
||||
gutters: [ 'CodeMirror-foldgutter' ]
|
||||
});
|
||||
|
||||
function openSettings() {
|
||||
settingsModal.classList.toggle('is-modal-visible');
|
||||
scope.toggleModal(settingsModal);
|
||||
|
||||
/* if (chrome.runtime.openOptionsPage) {
|
||||
// New way to open options pages, if supported (Chrome 42+).
|
||||
@@ -1007,7 +1023,6 @@ runBtn, searchInput
|
||||
|
||||
scope.exportItems = function exportItems(e) {
|
||||
fetchItems().then(function (items) {
|
||||
utils.log(9, items);
|
||||
var d = new Date();
|
||||
var fileName = [ 'web-maker-export', d.getFullYear(), (d.getMonth() + 1), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds() ].join('-');
|
||||
fileName += '.json';
|
||||
@@ -1088,7 +1103,7 @@ runBtn, searchInput
|
||||
utils.log(items);
|
||||
mergeImportedItems(items);
|
||||
} catch (ex) {
|
||||
alert('Oops! Select file is corrupted.')
|
||||
alert('Oops! Selected file is corrupted. Please select a file that was generated by clicking the "Export" button.')
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1235,6 +1250,7 @@ runBtn, searchInput
|
||||
htmlCode.querySelector('.CodeMirror').style.fontSize = prefs.fontSize;
|
||||
cssCode.querySelector('.CodeMirror').style.fontSize = prefs.fontSize;
|
||||
jsCode.querySelector('.CodeMirror').style.fontSize = prefs.fontSize;
|
||||
consoleEl.querySelector('.CodeMirror').style.fontSize = prefs.fontSize;
|
||||
|
||||
// Update indentation count when slider is updated
|
||||
indentationSizeValueEl.textContent = $('[data-setting=indentSize]').value;
|
||||
@@ -1255,6 +1271,7 @@ runBtn, searchInput
|
||||
scope.cm[type].setOption('keyMap', $('[data-setting=keymap]:checked').value);
|
||||
scope.cm[type].refresh();
|
||||
});
|
||||
scope.consoleCm.setOption('theme', $('[data-setting=editorTheme]').value);
|
||||
};
|
||||
|
||||
scope.onNewBtnClick = function () {
|
||||
@@ -1276,6 +1293,15 @@ runBtn, searchInput
|
||||
trackEvent('ui', 'saveBtnClick', currentItem.id ? 'saved' : 'new');
|
||||
saveItem();
|
||||
};
|
||||
|
||||
/**
|
||||
* Toggles a modal and logs an event.
|
||||
* @param {Node} modal modal to be toggled
|
||||
*/
|
||||
scope.toggleModal = function (modal) {
|
||||
modal.classList.toggle('is-modal-visible');
|
||||
document.body.classList[modal.classList.contains('is-modal-visible') ? 'add' : 'remove']('overlay-visible');
|
||||
};
|
||||
scope.onSearchInputChange = function (e) {
|
||||
const text = e.target.value;
|
||||
let el;
|
||||
@@ -1290,8 +1316,53 @@ runBtn, searchInput
|
||||
trackEvent('ui', 'searchInputType');
|
||||
};
|
||||
|
||||
function compileNodes() {
|
||||
scope.toggleConsole = function () {
|
||||
consoleEl.classList.toggle('is-minimized');
|
||||
trackEvent('ui', 'consoleToggle');
|
||||
};
|
||||
scope.clearConsole = function () {
|
||||
scope.consoleCm.setValue('');
|
||||
logCount = 0;
|
||||
logCountEl.textContent = logCount;
|
||||
};
|
||||
scope.onClearConsoleBtnClick = function () {
|
||||
scope.clearConsole();
|
||||
trackEvent('ui', 'consoleClearBtnClick');
|
||||
};
|
||||
scope.evalConsoleExpr = function (e) {
|
||||
// Clear console on CTRL + L
|
||||
if (((e.which === 76 || e.which === 12) && e.ctrlKey)) {
|
||||
scope.clearConsole();
|
||||
trackEvent('ui', 'consoleClearKeyboardShortcut');
|
||||
} else if (e.which === 13) {
|
||||
window.onMessageFromConsole('> ' + e.target.value);
|
||||
|
||||
/* eslint-disable no-underscore-dangle */
|
||||
frame.contentWindow._wmEvaluate(e.target.value);
|
||||
|
||||
/* eslint-enable no-underscore-dangle */
|
||||
|
||||
e.target.value = '';
|
||||
trackEvent('fn', 'evalConsoleExpr');
|
||||
}
|
||||
};
|
||||
window.onMessageFromConsole = function() {
|
||||
|
||||
/* eslint-disable no-param-reassign */
|
||||
[...arguments].forEach(function(arg) {
|
||||
if (arg && arg.indexOf && arg.indexOf('filesystem:chrome-extension') !== -1) {
|
||||
arg = arg.replace(/filesystem:chrome-extension.*\.js:(\d+):*(\d*)/g, 'script $1:$2');
|
||||
}
|
||||
scope.consoleCm.replaceRange(arg + ' ' + ((arg + '').match(/\[object \w+]/) ? JSON.stringify(arg) : '') + '\n', { line: Infinity });
|
||||
scope.consoleCm.scrollTo(0, Infinity);
|
||||
logCount++;
|
||||
});
|
||||
logCountEl.textContent = logCount;
|
||||
|
||||
/* eslint-enable no-param-reassign */
|
||||
};
|
||||
|
||||
function compileNodes() {
|
||||
function attachListenerForEvent(eventName) {
|
||||
const nodes = $all(`[d-${eventName}]`);
|
||||
nodes.forEach(function (el) {
|
||||
@@ -1303,6 +1374,7 @@ runBtn, searchInput
|
||||
attachListenerForEvent('click');
|
||||
attachListenerForEvent('change');
|
||||
attachListenerForEvent('input');
|
||||
attachListenerForEvent('keyup');
|
||||
}
|
||||
|
||||
function init () {
|
||||
@@ -1324,19 +1396,17 @@ runBtn, searchInput
|
||||
layoutBtn4.addEventListener('click', getToggleLayoutButtonListener(4));
|
||||
|
||||
utils.onButtonClick(helpBtn, function () {
|
||||
helpModal.classList.toggle('is-modal-visible');
|
||||
document.body.classList[helpModal.classList.contains('is-modal-visible') ? 'add' : 'remove']('overlay-visible');
|
||||
scope.toggleModal(helpModal);
|
||||
trackEvent('ui', 'helpButtonClick');
|
||||
});
|
||||
utils.onButtonClick(addLibraryBtn, function () {
|
||||
addLibraryModal.classList.toggle('is-modal-visible');
|
||||
document.body.classList[addLibraryModal.classList.contains('is-modal-visible') ? 'add' : 'remove']('overlay-visible');
|
||||
scope.toggleModal(addLibraryModal);
|
||||
trackEvent('ui', 'addLibraryButtonClick');
|
||||
});
|
||||
|
||||
notificationsBtn.addEventListener('click', function () {
|
||||
notificationsModal.classList.toggle('is-modal-visible');
|
||||
document.body.classList[notificationsModal.classList.contains('is-modal-visible') ? 'add' : 'remove']('overlay-visible');
|
||||
scope.toggleModal(notificationsModal);
|
||||
|
||||
if (notificationsModal.classList.contains('is-modal-visible') && !hasSeenNotifications) {
|
||||
hasSeenNotifications = true;
|
||||
notificationsBtn.classList.remove('has-new');
|
||||
@@ -1443,6 +1513,7 @@ runBtn, searchInput
|
||||
});
|
||||
});
|
||||
|
||||
// Editor keyboard shortucuts
|
||||
window.addEventListener('keydown', function (event) {
|
||||
var selectedItemElement;
|
||||
// Ctrl/⌘ + S
|
||||
@@ -1508,6 +1579,10 @@ runBtn, searchInput
|
||||
});
|
||||
window.addEventListener('dblclick', function(e) {
|
||||
var target = e.target;
|
||||
if (target.classList.contains('js-console__header')) {
|
||||
scope.toggleConsole();
|
||||
trackEvent('ui', 'consoleToggleDblClick');
|
||||
}
|
||||
if (target.classList.contains('js-code-wrap__header')) {
|
||||
var codeWrapParent = target.parentElement;
|
||||
toggleCodeWrapCollapse(codeWrapParent);
|
||||
@@ -1541,6 +1616,23 @@ runBtn, searchInput
|
||||
new TextareaAutoComplete(externalJsTextarea, (obj) => obj.latest.match(/\.js$/));
|
||||
new TextareaAutoComplete(externalCssTextarea, (obj) => obj.latest.match(/\.css$/));
|
||||
|
||||
// Console header drag resize logic
|
||||
var consoleHeaderDragStartY;
|
||||
var consoleInitialHeight;
|
||||
function onConsoleHeaderDrag(e) {
|
||||
consoleEl.style.height = (consoleInitialHeight + consoleHeaderDragStartY - e.pageY) + 'px';
|
||||
}
|
||||
$('.js-console__header').addEventListener('mousedown', (e) => {
|
||||
consoleHeaderDragStartY = e.pageY;
|
||||
consoleInitialHeight = consoleEl.getBoundingClientRect().height;
|
||||
$('#demo-frame').classList.add('pointer-none');
|
||||
window.addEventListener('mousemove', onConsoleHeaderDrag);
|
||||
});
|
||||
$('.js-console__header').addEventListener('mouseup', () => {
|
||||
window.removeEventListener('mousemove', onConsoleHeaderDrag);
|
||||
$('#demo-frame').classList.remove('pointer-none');
|
||||
});
|
||||
|
||||
chrome.storage.local.get({
|
||||
layoutMode: 1,
|
||||
code: ''
|
||||
@@ -1690,4 +1782,4 @@ runBtn, searchInput
|
||||
|
||||
init();
|
||||
|
||||
})(window.alertsService);
|
||||
})(window.alertsService);
|
@@ -107,6 +107,7 @@ select, input[type="text"], input[type="number"], textarea {
|
||||
top: 0; bottom: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
will-change: -webkit-filter;
|
||||
transition: 0.10s ease 0.2s;
|
||||
}
|
||||
@@ -119,6 +120,7 @@ select, input[type="text"], input[type="number"], textarea {
|
||||
.demo-side {
|
||||
flex-basis: inherit;
|
||||
position: relative;
|
||||
width: 50%;
|
||||
}
|
||||
.layout-3 .content-wrap {
|
||||
flex-direction: row-reverse;
|
||||
@@ -126,7 +128,6 @@ select, input[type="text"], input[type="number"], textarea {
|
||||
.code-side {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 50%;
|
||||
}
|
||||
.layout-2 .content-wrap {
|
||||
flex-direction: column;
|
||||
@@ -135,6 +136,9 @@ select, input[type="text"], input[type="number"], textarea {
|
||||
flex-direction: row;
|
||||
width: auto;
|
||||
}
|
||||
.layout-2 .demo-side {
|
||||
width: auto;
|
||||
}
|
||||
.layout-4 .code-side {
|
||||
display: none;
|
||||
}
|
||||
@@ -182,6 +186,7 @@ select, input[type="text"], input[type="number"], textarea {
|
||||
color: #888;
|
||||
border-bottom: 1px solid rgba(0,0,0,0.3);
|
||||
font-weight: bold;
|
||||
user-select: none;
|
||||
}
|
||||
.code-wrap__header-label {
|
||||
/*transform: translate(0px) scale(1.2);*/
|
||||
@@ -190,7 +195,7 @@ select, input[type="text"], input[type="number"], textarea {
|
||||
opacity: 0.5;
|
||||
/*transform-origin: left center;*/
|
||||
}
|
||||
.layout-2 .is-minimized .code-wrap__header {
|
||||
.layout-2 .code-side .is-minimized .code-wrap__header {
|
||||
writing-mode: vertical-lr;
|
||||
padding: 10px 5px;
|
||||
}
|
||||
@@ -201,9 +206,14 @@ select, input[type="text"], input[type="number"], textarea {
|
||||
opacity: 0;
|
||||
}
|
||||
.code-wrap__header-btn {
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
margin-left: 8px;
|
||||
}
|
||||
.code-wrap__header-btn,
|
||||
.code-wrap__header-btn > svg {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
display: inline-block;
|
||||
}
|
||||
.code-wrap__collapse-btn:before {
|
||||
content: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" style="width:18px;height:18px" viewBox="0 0 24 24"><path fill="rgba(255,255,255,0.2)" d="M19.5,3.09L15,7.59V4H13V11H20V9H16.41L20.91,4.5L19.5,3.09M4,13V15H7.59L3.09,19.5L4.5,20.91L9,16.41V20H11V13H4Z" /></svg>');
|
||||
@@ -263,7 +273,7 @@ li.CodeMirror-hint-active {
|
||||
#demo-frame {
|
||||
border: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
height: calc(100% - 29px); /* minus minimized console height */
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
background: white;
|
||||
@@ -271,11 +281,14 @@ li.CodeMirror-hint-active {
|
||||
.main-header,
|
||||
.footer {
|
||||
padding: 5px 10px;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
background-color: rgb(18, 19, 27);
|
||||
color: rgba(255, 255, 255, 0.45);
|
||||
border-top: 1px solid rgba(255,255,255,0.14);
|
||||
/*line-height: 20px;*/
|
||||
}
|
||||
.footer {
|
||||
z-index: 1;
|
||||
}
|
||||
.main-header {
|
||||
border: 0;
|
||||
border-bottom: 1px solid rgba(255,255,255,0.14);
|
||||
@@ -810,3 +823,33 @@ li.CodeMirror-hint-active {
|
||||
.wobble {
|
||||
animation-name: wobble;
|
||||
}
|
||||
.console {
|
||||
background: var(--color-bg);
|
||||
z-index: 1; /* bring above iframe */
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
min-height: 80px;
|
||||
height: 35vh;
|
||||
left: 0;
|
||||
right: 0;
|
||||
transform: translateY(0);
|
||||
transition: transform 0.4s cubic-bezier(0.76, 0.01, 0.13, 0.9);
|
||||
}
|
||||
.console.is-minimized {
|
||||
transform: translateY(calc(100% - 29px));
|
||||
}
|
||||
.console .Codemirror {
|
||||
height: calc(100% - 55px);
|
||||
}
|
||||
.console-exec-input {
|
||||
padding: 5px;
|
||||
font-size: 1.3em;
|
||||
flex: 1;
|
||||
background: rgba(0,0,0,0.3);
|
||||
color: white;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
}
|
||||
.console:not(.is-minimized) .code-wrap__header {
|
||||
cursor: ns-resize;
|
||||
}
|
Reference in New Issue
Block a user