1
0
mirror of https://github.com/chinchang/web-maker.git synced 2025-07-14 10:36:19 +02:00

add chrome like dev console! fixes #56

This commit is contained in:
Kushagra Gour
2017-05-07 16:59:47 +05:30
parent 5827cbe6c8
commit 88a49cd4c5
4 changed files with 261 additions and 4 deletions

View File

@ -101,6 +101,25 @@
</div> </div>
<div class="demo-side" id="js-demo-side"> <div class="demo-side" id="js-demo-side">
<iframe src="about://blank" frameborder="0" id="demo-frame"></iframe> <iframe src="about://blank" frameborder="0" id="demo-frame"></iframe>
<div id="consoleEl" class="console">
<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>
<div class="code-wrap__header-right-options">
<a class="code-wrap__header-btn" title="Clear console" d-click="clearConsole">
<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">
<input type="" name="" class="full-width" style="background: none;border:0;">
</div>
</div>
</div> </div>
</div> </div>
<div class="footer"> <div class="footer">
@ -577,6 +596,11 @@
<path d="M8,5.14V19.14L19,12.14L8,5.14Z" /> <path d="M8,5.14V19.14L19,12.14L8,5.14Z" />
</svg> </svg>
</symbol> </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>
</svg> </svg>
<script src="lib/codemirror/lib/codemirror.js"></script> <script src="lib/codemirror/lib/codemirror.js"></script>

174
src/screenlog.js Normal file
View File

@ -0,0 +1,174 @@
(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);
}
});

View File

@ -5,7 +5,7 @@ addLibraryModal, addLibraryModal, notificationsBtn, notificationsModal, notifica
notificationsModal, notificationsBtn, codepenBtn, saveHtmlBtn, saveBtn, settingsBtn, notificationsModal, notificationsBtn, codepenBtn, saveHtmlBtn, saveBtn, settingsBtn,
onboardModal, settingsModal, notificationsBtn, onboardShowInTabOptionBtn, editorThemeLinkTag, onboardModal, settingsModal, notificationsBtn, onboardShowInTabOptionBtn, editorThemeLinkTag,
onboardDontShowInTabOptionBtn, TextareaAutoComplete, savedItemCountEl, indentationSizeValueEl, onboardDontShowInTabOptionBtn, TextareaAutoComplete, savedItemCountEl, indentationSizeValueEl,
runBtn, searchInput runBtn, searchInput, consoleEl, consoleLogEl
*/ */
/* eslint-disable no-extra-semi */ /* eslint-disable no-extra-semi */
;(function (alertsService) { ;(function (alertsService) {
@ -91,6 +91,7 @@ runBtn, searchInput
; ;
scope.cm = {}; scope.cm = {};
scope.consoleCm;
scope.demoFrameDocument = frame.contentDocument || frame.contentWindow.document; scope.demoFrameDocument = frame.contentDocument || frame.contentWindow.document;
// Check all the code wrap if they are minimized or not // Check all the code wrap if they are minimized or not
@ -734,6 +735,9 @@ runBtn, searchInput
+ '<body>\n' + html + '\n' + '<body>\n' + html + '\n'
+ externalJs + '\n'; + externalJs + '\n';
contents += '<script src="'
+ chrome.extension.getURL('screenlog.js') + '"></script>';
if (js) { if (js) {
contents += '<script>\n' + js + '\n//# sourceURL=userscript.js'; contents += '<script>\n' + js + '\n//# sourceURL=userscript.js';
} else { } else {
@ -969,6 +973,17 @@ runBtn, searchInput
}); });
Inlet(scope.cm.js); Inlet(scope.cm.js);
// Initialize codemirror in console
scope.consoleCm = CodeMirror(consoleLogEl, {
mode: 'javascript',
lineWrapping: true,
theme: 'monokai',
foldGutter: true,
readOnly: true,
viewportMargin: Infinity,
gutters: [ 'CodeMirror-foldgutter' ]
});
function openSettings() { function openSettings() {
settingsModal.classList.toggle('is-modal-visible'); settingsModal.classList.toggle('is-modal-visible');
@ -1252,6 +1267,7 @@ runBtn, searchInput
scope.cm[type].setOption('keyMap', $('[data-setting=keymap]:checked').value); scope.cm[type].setOption('keyMap', $('[data-setting=keymap]:checked').value);
scope.cm[type].refresh(); scope.cm[type].refresh();
}); });
scope.consoleCm.setOption('theme', $('[data-setting=editorTheme]').value);
}; };
scope.onNewBtnClick = function () { scope.onNewBtnClick = function () {
@ -1287,6 +1303,22 @@ runBtn, searchInput
trackEvent('ui', 'searchInputType'); trackEvent('ui', 'searchInputType');
}; };
scope.toggleConsole = function () {
consoleEl.classList.toggle('is-open');
};
scope.clearConsole = function () {
scope.consoleCm.setValue('');
};
window.onMessageFromConsole = function() {
[...arguments].forEach(function(arg) {
if (arg.indexOf && arg.indexOf('filesystem:chrome-extension') !== -1) {
arg = arg.replace(/filesystem:chrome-extension.*\.js:(\d+):(\d+)/g, 'script $1:$2');
}
scope.consoleCm.replaceRange('\n' + arg + ((arg + '').match(/\[object \w+\]/) ? JSON.stringify(arg) : '') + ' ', {line: Infinity});
});
}
function compileNodes() { function compileNodes() {
function attachListenerForEvent(eventName) { function attachListenerForEvent(eventName) {
@ -1505,6 +1537,9 @@ runBtn, searchInput
}); });
window.addEventListener('dblclick', function(e) { window.addEventListener('dblclick', function(e) {
var target = e.target; var target = e.target;
if (target.classList.contains('js-console__header')) {
scope.toggleConsole();
}
if (target.classList.contains('js-code-wrap__header')) { if (target.classList.contains('js-code-wrap__header')) {
var codeWrapParent = target.parentElement; var codeWrapParent = target.parentElement;
toggleCodeWrapCollapse(codeWrapParent); toggleCodeWrapCollapse(codeWrapParent);

View File

@ -107,6 +107,7 @@ select, input[type="text"], input[type="number"], textarea {
top: 0; bottom: 0; top: 0; bottom: 0;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden;
will-change: -webkit-filter; will-change: -webkit-filter;
transition: 0.10s ease 0.2s; transition: 0.10s ease 0.2s;
} }
@ -201,9 +202,13 @@ select, input[type="text"], input[type="number"], textarea {
opacity: 0; opacity: 0;
} }
.code-wrap__header-btn { .code-wrap__header-btn {
display: inline-block;
vertical-align: top;
}
.code-wrap__header-btn,
.code-wrap__header-btn > svg {
width: 18px; width: 18px;
height: 18px; height: 18px;
display: inline-block;
} }
.code-wrap__collapse-btn:before { .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>'); 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>');
@ -271,9 +276,10 @@ li.CodeMirror-hint-active {
.main-header, .main-header,
.footer { .footer {
padding: 5px 10px; padding: 5px 10px;
background-color: rgba(0, 0, 0, 0.5); background-color: rgb(18, 19, 27);
color: rgba(255, 255, 255, 0.45); color: rgba(255, 255, 255, 0.45);
border-top: 1px solid rgba(255,255,255,0.14); border-top: 1px solid rgba(255,255,255,0.14);
z-index: 1;
/*line-height: 20px;*/ /*line-height: 20px;*/
} }
.main-header { .main-header {
@ -810,3 +816,21 @@ li.CodeMirror-hint-active {
.wobble { .wobble {
animation-name: wobble; animation-name: wobble;
} }
.console {
background: var(--color-bg);
z-index: 1; /* bring above iframe */
position: absolute;
bottom: 0;
height: 30vh;
left: 0;
right: 0;
transform: translateY(calc(100% - 30px));
transition: transform 0.4s cubic-bezier(0.77,-0.1,0.13,0.9);
}
.console.is-open {
transform: translateY(0);
}
.console .Codemirror {
height: auto;
max-height: calc(100% - 50px);
}