1
0
mirror of https://github.com/chinchang/web-maker.git synced 2025-06-08 18:54:49 +02:00

moreeee stuff

This commit is contained in:
Kushagra Gour 2018-06-08 02:11:19 +05:30
parent a3fae1e2d8
commit aaa9dc4c97
10 changed files with 237 additions and 114 deletions

View File

@ -0,0 +1,31 @@
import { h, Component } from 'preact';
import CodeMirror from '../CodeMirror';
import 'codemirror/mode/javascript/javascript.js';
export default class CodeMirrorBox extends Component {
componentDidMount() {
this.initEditor();
}
shouldComponentUpdate() {
return false;
}
initEditor() {
const options = this.props.options;
this.cm = CodeMirror.fromTextArea(this.textarea, this.props.options);
this.props.onCreation(this.cm);
}
render() {
return (
<textarea
ref={el => (this.textarea = el)}
name=""
id=""
cols="30"
rows="10"
/>
);
}
}

View File

@ -197,6 +197,9 @@ export default class ContentWrap extends Component {
isValidItem(item) { isValidItem(item) {
return !!item.title; return !!item.title;
} }
shouldComponentUpdate(nextProps, nextState) {
return this.state.isConsoleOpen !== nextState.isConsoleOpen;
}
componentDidUpdate() { componentDidUpdate() {
// HACK: becuase its a DOM manipulation // HACK: becuase its a DOM manipulation
window.logCountEl.textContent = this.logCount; window.logCountEl.textContent = this.logCount;
@ -241,8 +244,10 @@ export default class ContentWrap extends Component {
prefs.fontSize, prefs.fontSize,
10 10
)}px`; )}px`;
window.consoleEl.querySelector('.CodeMirror').style.fontSize = `${parseInt(
// consoleEl.querySelector('.CodeMirror').style.fontSize = prefs.fontSize; prefs.fontSize,
10
)}px`;
// Replace correct css file in LINK tags's href // Replace correct css file in LINK tags's href
window.editorThemeLinkTag.href = `lib/codemirror/theme/${ window.editorThemeLinkTag.href = `lib/codemirror/theme/${
@ -257,6 +262,7 @@ export default class ContentWrap extends Component {
// window.customEditorFontInput.classList[ // window.customEditorFontInput.classList[
// prefs.editorFont === 'other' ? 'remove' : 'add' // prefs.editorFont === 'other' ? 'remove' : 'add'
// ]('hide'); // ]('hide');
this.consoleCm.setOption('theme', prefs.editorTheme);
['html', 'js', 'css'].forEach(type => { ['html', 'js', 'css'].forEach(type => {
this.cm[type].setOption('indentWithTabs', prefs.indentWith !== 'spaces'); this.cm[type].setOption('indentWithTabs', prefs.indentWith !== 'spaces');
@ -527,7 +533,6 @@ export default class ContentWrap extends Component {
} }
onMessageFromConsole() { onMessageFromConsole() {
const self = this;
/* eslint-disable no-param-reassign */ /* eslint-disable no-param-reassign */
[...arguments].forEach(arg => { [...arguments].forEach(arg => {
if ( if (
@ -584,6 +589,24 @@ export default class ContentWrap extends Component {
trackEvent('ui', 'consoleClearBtnClick'); trackEvent('ui', 'consoleClearBtnClick');
} }
evalConsoleExpr(e) {
// Clear console on CTRL + L
if ((e.which === 76 || e.which === 12) && e.ctrlKey) {
this.clearConsole();
trackEvent('ui', 'consoleClearKeyboardShortcut');
} else if (e.which === 13) {
this.onMessageFromConsole('> ' + e.target.value);
/* eslint-disable no-underscore-dangle */
this.frame.contentWindow._wmEvaluate(e.target.value);
/* eslint-enable no-underscore-dangle */
e.target.value = '';
trackEvent('fn', 'evalConsoleExpr');
}
}
render() { render() {
return ( return (
<SplitPane <SplitPane
@ -826,7 +849,10 @@ export default class ContentWrap extends Component {
<svg width="18" height="18" fill="#346fd2"> <svg width="18" height="18" fill="#346fd2">
Chevron Chevron
</svg> </svg>
<input d-keyup="evalConsoleExpr" class="console-exec-input" /> <input
onKeyUp={this.evalConsoleExpr.bind(this)}
class="console-exec-input"
/>
</div> </div>
</div> </div>
</div> </div>

View File

@ -168,7 +168,7 @@ export default class Footer extends Component {
</svg> </svg>
</a> </a>
<a <a
onClick={() => this.setState({ isKeyboardShortcutsModalOpen: true })} onClick={this.props.keyboardShortcutsBtnClickHandler}
data-event-category="ui" data-event-category="ui"
data-event-action="keyboardShortcutButtonClick" data-event-action="keyboardShortcutButtonClick"
class="footer__link hint--rounded hint--top-right hide-on-mobile" class="footer__link hint--rounded hint--top-right hide-on-mobile"
@ -209,98 +209,6 @@ export default class Footer extends Component {
> >
Support the developer Support the developer
</a> </a>
<Modal
show={this.state.isKeyboardShortcutsModalOpen}
closeHandler={() =>
this.setState({ isKeyboardShortcutsModalOpen: false })
}
>
<h1>Keyboard Shortcuts</h1>
<div class="flex">
<div>
<h2>Global</h2>
<p>
<span class="kbd-shortcut__keys">Ctrl/ + Shift + ?</span>
<span class="kbd-shortcut__details">
See keyboard shortcuts
</span>
</p>
<p>
<span class="kbd-shortcut__keys">Ctrl/ + Shift + 5</span>
<span class="kbd-shortcut__details">Refresh preview</span>
</p>
<p>
<span class="kbd-shortcut__keys">Ctrl/ + S</span>
<span class="kbd-shortcut__details">
Save current creations
</span>
</p>
<p>
<span class="kbd-shortcut__keys">Ctrl/ + O</span>
<span class="kbd-shortcut__details">
Open list of saved creations
</span>
</p>
<p>
<span class="kbd-shortcut__keys">Ctrl + L</span>
<span class="kbd-shortcut__details">
Clear console (works when console input is focused)
</span>
</p>
<p>
<span class="kbd-shortcut__keys">Esc</span>
<span class="kbd-shortcut__details">
Close saved creations panel & modals
</span>
</p>
</div>
<div class="ml-2">
<h2>Editor</h2>
<p>
<span class="kbd-shortcut__keys">Ctrl/ + F</span>
<span class="kbd-shortcut__details">Find</span>
</p>
<p>
<span class="kbd-shortcut__keys">Ctrl/ + G</span>
<span class="kbd-shortcut__details">Select next match</span>
</p>
<p>
<span class="kbd-shortcut__keys">Ctrl/ + Shift + G</span>
<span class="kbd-shortcut__details">Select previous match</span>
</p>
<p>
<span class="kbd-shortcut__keys">Ctrl/ + Opt/Alt + F</span>
<span class="kbd-shortcut__details">Find & replace</span>
</p>
<p>
<span class="kbd-shortcut__keys">Shift + Tab</span>
<span class="kbd-shortcut__details">Realign code</span>
</p>
<p>
<span class="kbd-shortcut__keys">Ctrl/ + ]</span>
<span class="kbd-shortcut__details">Indent code right</span>
</p>
<p>
<span class="kbd-shortcut__keys">Ctrl/ + [</span>
<span class="kbd-shortcut__details">Indent code left</span>
</p>
<p>
<span class="kbd-shortcut__keys">Tab</span>
<span class="kbd-shortcut__details">
Emmet code completion{' '}
<a href="https://emmet.io/" target="_blank">
Read more
</a>
</span>
</p>
<p>
<span class="kbd-shortcut__keys">Ctrl/ + /</span>
<span class="kbd-shortcut__details">Single line comment</span>
</p>
</div>
</div>
</Modal>
</div> </div>
); );
} }

View File

@ -0,0 +1,92 @@
import { h, Component } from 'preact';
import Modal from './Modal';
export default class KeyboardShortcutsModal extends Component {
render() {
return (
<Modal show={this.props.show} closeHandler={this.props.closeHandler}>
<h1>Keyboard Shortcuts</h1>
<div class="flex">
<div>
<h2>Global</h2>
<p>
<span class="kbd-shortcut__keys">Ctrl/ + Shift + ?</span>
<span class="kbd-shortcut__details">See keyboard shortcuts</span>
</p>
<p>
<span class="kbd-shortcut__keys">Ctrl/ + Shift + 5</span>
<span class="kbd-shortcut__details">Refresh preview</span>
</p>
<p>
<span class="kbd-shortcut__keys">Ctrl/ + S</span>
<span class="kbd-shortcut__details">Save current creations</span>
</p>
<p>
<span class="kbd-shortcut__keys">Ctrl/ + O</span>
<span class="kbd-shortcut__details">
Open list of saved creations
</span>
</p>
<p>
<span class="kbd-shortcut__keys">Ctrl + L</span>
<span class="kbd-shortcut__details">
Clear console (works when console input is focused)
</span>
</p>
<p>
<span class="kbd-shortcut__keys">Esc</span>
<span class="kbd-shortcut__details">
Close saved creations panel & modals
</span>
</p>
</div>
<div class="ml-2">
<h2>Editor</h2>
<p>
<span class="kbd-shortcut__keys">Ctrl/ + F</span>
<span class="kbd-shortcut__details">Find</span>
</p>
<p>
<span class="kbd-shortcut__keys">Ctrl/ + G</span>
<span class="kbd-shortcut__details">Select next match</span>
</p>
<p>
<span class="kbd-shortcut__keys">Ctrl/ + Shift + G</span>
<span class="kbd-shortcut__details">Select previous match</span>
</p>
<p>
<span class="kbd-shortcut__keys">Ctrl/ + Opt/Alt + F</span>
<span class="kbd-shortcut__details">Find & replace</span>
</p>
<p>
<span class="kbd-shortcut__keys">Shift + Tab</span>
<span class="kbd-shortcut__details">Realign code</span>
</p>
<p>
<span class="kbd-shortcut__keys">Ctrl/ + ]</span>
<span class="kbd-shortcut__details">Indent code right</span>
</p>
<p>
<span class="kbd-shortcut__keys">Ctrl/ + [</span>
<span class="kbd-shortcut__details">Indent code left</span>
</p>
<p>
<span class="kbd-shortcut__keys">Tab</span>
<span class="kbd-shortcut__details">
Emmet code completion{' '}
<a href="https://emmet.io/" target="_blank">
Read more
</a>
</span>
</p>
<p>
<span class="kbd-shortcut__keys">Ctrl/ + /</span>
<span class="kbd-shortcut__details">Single line comment</span>
</p>
</div>
</div>
</Modal>
);
}
}

View File

@ -17,7 +17,7 @@ export default class Header extends Component {
id="runBtn" id="runBtn"
class="hide flex flex-v-center hint--rounded hint--bottom-left" class="hide flex flex-v-center hint--rounded hint--bottom-left"
aria-label="Run preview (Ctrl/⌘ + Shift + 5)" aria-label="Run preview (Ctrl/⌘ + Shift + 5)"
d-click="onRunBtnClick" onClick={this.props.runBtnClickHandler}
> >
<svg style="width: 14px; height: 14px;"> <svg style="width: 14px; height: 14px;">
<use xlinkHref="#play-icon" /> <use xlinkHref="#play-icon" />

View File

@ -16,11 +16,58 @@ export default class SavedItemPane extends Component {
e.stopPropagation(); e.stopPropagation();
this.props.itemForkBtnClickHandler(item); this.props.itemForkBtnClickHandler(item);
} }
keyDownHandler(event) {
if (!this.props.isOpen) {
return;
}
const isCtrlOrMetaPressed = event.ctrlKey || event.metaKey;
const isForkKeyPressed = isCtrlOrMetaPressed && event.keyCode === 70;
const isDownKeyPressed = event.keyCode === 40;
const isUpKeyPressed = event.keyCode === 38;
const isEnterKeyPressed = event.keyCode === 13;
const selectedItemElement = $('.js-saved-item-tile.selected');
const havePaneItems = $all('.js-saved-item-tile').length !== 0;
if ((isDownKeyPressed || isUpKeyPressed) && havePaneItems) {
const method = isDownKeyPressed ? 'nextUntil' : 'previousUntil';
if (selectedItemElement) {
selectedItemElement.classList.remove('selected');
selectedItemElement[method](
'.js-saved-item-tile:not(.hide)'
).classList.add('selected');
} else {
$('.js-saved-item-tile:not(.hide)').classList.add('selected');
}
$('.js-saved-item-tile.selected').scrollIntoView(false);
}
if (isEnterKeyPressed && selectedItemElement) {
const item = this.props.items.filter(
item => (item.id = selectedItemElement.dataset.itemId)
)[0];
this.props.itemClickHandler(item);
}
// Fork shortcut inside saved creations panel with Ctrl/ + F
if (isForkKeyPressed) {
event.preventDefault();
const item = this.props.items.filter(
item => (item.id = selectedItemElement.dataset.itemId)
)[0];
this.props.itemForkBtnClickHandler(item);
trackEvent('ui', 'forkKeyboardShortcut');
}
}
render() { render() {
return ( return (
<div <div
id="js-saved-items-pane" id="js-saved-items-pane"
class={`saved-items-pane ${this.props.isOpen ? 'is-open' : ''}`} class={`saved-items-pane ${this.props.isOpen ? 'is-open' : ''}`}
onKeyDown={this.keyDownHandler.bind(this)}
> >
<button <button
onClick={this.onCloseIntent.bind(this)} onClick={this.onCloseIntent.bind(this)}

View File

@ -4,7 +4,7 @@ import Modal from './Modal';
export default class SupportDeveloperModal extends Component { export default class SupportDeveloperModal extends Component {
render() { render() {
return ( return (
<Modal show={this.props.isOpen} closeHandler={this.props.closeHandler}> <Modal show={this.props.show} closeHandler={this.props.closeHandler}>
<div class="tac"> <div class="tac">
<h1>Support the Developer</h1> <h1>Support the Developer</h1>
<p> <p>

View File

@ -118,7 +118,9 @@ export default class UserCodeMirror extends Component {
) { ) {
return; return;
} }
CodeMirror.commands.autocomplete(cm, null, { completeSingle: false }); CodeMirror.commands.autocomplete(this.cm, null, {
completeSingle: false
});
}); });
} }
this.props.onCreation(this.cm); this.props.onCreation(this.cm);

View File

@ -23,6 +23,7 @@ import 'firebase/auth';
import Profile from './Profile'; import Profile from './Profile';
import { auth } from '../auth'; import { auth } from '../auth';
import SupportDeveloperModal from './SupportDeveloperModal'; import SupportDeveloperModal from './SupportDeveloperModal';
import KeyboardShortcutsModal from './KeyboardShortcutsModal';
if (module.hot) { if (module.hot) {
require('preact/debug'); require('preact/debug');
@ -49,6 +50,7 @@ export default class App extends Component {
isLoginModalOpen: false, isLoginModalOpen: false,
isProfileModalOpen: false, isProfileModalOpen: false,
isSupportDeveloperModalOpen: false, isSupportDeveloperModalOpen: false,
isKeyboardShortcutsModalOpen: false,
prefs: {}, prefs: {},
currentItem: { currentItem: {
title: '', title: '',
@ -438,7 +440,9 @@ export default class App extends Component {
) { ) {
// Ctrl/ + Shift + ? // Ctrl/ + Shift + ?
event.preventDefault(); event.preventDefault();
// scope.toggleModal(keyboardShortcutsModal); this.setState({
isKeyboardShortcutsModalOpen: !this.state.isKeyboardShortcutsModalOpen
});
trackEvent('ui', 'showKeyboardShortcutsShortcut'); trackEvent('ui', 'showKeyboardShortcutsShortcut');
} else if (event.keyCode === 27) { } else if (event.keyCode === 27) {
this.closeAllOverlays(); this.closeAllOverlays();
@ -668,7 +672,6 @@ export default class App extends Component {
this.contentWrap.applyCodemirrorSettings(this.state.prefs); this.contentWrap.applyCodemirrorSettings(this.state.prefs);
/* /*
scope.consoleCm.setOption('theme', $('[data-setting=editorTheme]').value);
scope.acssSettingsCm.setOption( scope.acssSettingsCm.setOption(
'theme', 'theme',
$('[data-setting=editorTheme]').value $('[data-setting=editorTheme]').value
@ -804,6 +807,10 @@ export default class App extends Component {
trackEvent('ui', 'saveHtmlClick'); trackEvent('ui', 'saveHtmlClick');
e.preventDefault(); e.preventDefault();
} }
runBtnClickHandler() {
this.contentWrap.setPreviewContent(true, true);
trackEvent('ui', 'runBtnClick');
}
render() { render() {
return ( return (
@ -817,6 +824,7 @@ export default class App extends Component {
loginBtnHandler={this.loginBtnClickHandler.bind(this)} loginBtnHandler={this.loginBtnClickHandler.bind(this)}
profileBtnHandler={this.profileBtnClickHandler.bind(this)} profileBtnHandler={this.profileBtnClickHandler.bind(this)}
addLibraryBtnHandler={this.openAddLibrary.bind(this)} addLibraryBtnHandler={this.openAddLibrary.bind(this)}
runBtnClickHandler={this.runBtnClickHandler.bind(this)}
isFetchingItems={this.state.isFetchingItems} isFetchingItems={this.state.isFetchingItems}
isSaving={this.state.isSaving} isSaving={this.state.isSaving}
title={this.state.currentItem.title} title={this.state.currentItem.title}
@ -852,6 +860,9 @@ export default class App extends Component {
)} )}
codepenBtnClickHandler={this.codepenBtnClickHandler.bind(this)} codepenBtnClickHandler={this.codepenBtnClickHandler.bind(this)}
saveHtmlBtnClickHandler={this.saveHtmlBtnClickHandler.bind(this)} saveHtmlBtnClickHandler={this.saveHtmlBtnClickHandler.bind(this)}
keyboardShortcutsBtnClickHandler={() =>
this.setState({ isKeyboardShortcutsModalOpen: true })
}
hasUnseenChangelog={this.state.hasUnseenChangelog} hasUnseenChangelog={this.state.hasUnseenChangelog}
/> />
</div> </div>
@ -934,11 +945,17 @@ export default class App extends Component {
closeHandler={() => this.setState({ isHelpModalOpen: false })} closeHandler={() => this.setState({ isHelpModalOpen: false })}
/> />
<SupportDeveloperModal <SupportDeveloperModal
isOpen={this.state.isSupportDeveloperModalOpen} show={this.state.isSupportDeveloperModalOpen}
closeHandler={() => closeHandler={() =>
this.setState({ isSupportDeveloperModalOpen: false }) this.setState({ isSupportDeveloperModalOpen: false })
} }
/> />
<KeyboardShortcutsModal
show={this.state.isKeyboardShortcutsModalOpen}
closeHandler={() =>
this.setState({ isKeyboardShortcutsModalOpen: false })
}
/>
<div class="modal-overlay" /> <div class="modal-overlay" />

View File

@ -30,28 +30,28 @@ var alphaNum = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
* @return element Next element that mathes `selector` * @return element Next element that mathes `selector`
*/ */
Node.prototype.nextUntil = function (selector) { Node.prototype.nextUntil = function (selector) {
const siblings = [...this.parentNode.querySelectorAll(selector)]; const siblings = Array.from(this.parentNode.querySelectorAll(selector));
const index = siblings.indexOf(this); const index = siblings.indexOf(this);
return siblings[index + 1]; return siblings[index + 1];
}; };
// Safari doesn't have this!
window.requestIdleCallback =
window.requestIdleCallback ||
function (fn) {
setTimeout(fn, 10);
};
/* /*
* @param Selector that should match for next siblings * @param Selector that should match for next siblings
* @return element Next element that mathes `selector` * @return element Next element that mathes `selector`
*/ */
Node.prototype.previousUntil = function (selector) { Node.prototype.previousUntil = function (selector) {
const siblings = [...this.parentNode.querySelectorAll(selector)]; const siblings = Array.from(this.parentNode.querySelectorAll(selector));
const index = siblings.indexOf(this); const index = siblings.indexOf(this);
return siblings[index - 1]; return siblings[index - 1];
}; };
// Safari doesn't have this!
window.requestIdleCallback =
window.requestIdleCallback ||
function (fn) {
setTimeout(fn, 10);
};
// https://github.com/substack/semver-compare/blob/master/index.js // https://github.com/substack/semver-compare/blob/master/index.js
export function semverCompare(a, b) { export function semverCompare(a, b) {
var pa = a.split('.'); var pa = a.split('.');