mirror of
https://github.com/chinchang/web-maker.git
synced 2025-07-10 08:26:19 +02:00
Merge pull request #113 from chinchang/feat-console-56
Implement chrome like developer console
This commit is contained in:
@ -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>
|
||||
@ -577,6 +599,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>
|
||||
|
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);
|
||||
}
|
116
src/script.js
116
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
|
||||
@ -463,6 +465,8 @@ runBtn, searchInput
|
||||
scope.cm.css.refresh();
|
||||
scope.cm.js.refresh();
|
||||
|
||||
scope.clearConsole();
|
||||
|
||||
// To have the library count updated
|
||||
updateExternalLibUi();
|
||||
|
||||
@ -700,6 +704,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 +739,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 {
|
||||
@ -969,8 +977,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+).
|
||||
@ -1232,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;
|
||||
@ -1252,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 () {
|
||||
@ -1273,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;
|
||||
@ -1287,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) {
|
||||
@ -1300,6 +1374,7 @@ runBtn, searchInput
|
||||
attachListenerForEvent('click');
|
||||
attachListenerForEvent('change');
|
||||
attachListenerForEvent('input');
|
||||
attachListenerForEvent('keyup');
|
||||
}
|
||||
|
||||
function init () {
|
||||
@ -1321,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');
|
||||
@ -1440,6 +1513,7 @@ runBtn, searchInput
|
||||
});
|
||||
});
|
||||
|
||||
// Editor keyboard shortucuts
|
||||
window.addEventListener('keydown', function (event) {
|
||||
var selectedItemElement;
|
||||
// Ctrl/⌘ + S
|
||||
@ -1505,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);
|
||||
@ -1538,6 +1616,24 @@ 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';
|
||||
utils.log(e.pageY, consoleHeaderDragStartY)
|
||||
}
|
||||
$('.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.add('pointer-none');
|
||||
});
|
||||
|
||||
chrome.storage.local.get({
|
||||
layoutMode: 1,
|
||||
code: ''
|
||||
@ -1687,4 +1783,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