mirror of
https://github.com/chinchang/web-maker.git
synced 2025-06-03 16:15:03 +02:00
commit
6fe592fa88
@ -37,4 +37,6 @@ chrome.runtime.onInstalled.addListener(function callback (details) {
|
|||||||
openApp();
|
openApp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
chrome.runtime.setUninstallURL('https://kushagragour.in/lab/web-maker/uninstall/');
|
142
src/index.html
142
src/index.html
@ -3,7 +3,9 @@
|
|||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Web Maker</title>
|
<title>Web Maker</title>
|
||||||
<link rel="stylesheet" href="lib/codemirror/lib/codemirror.css">
|
<link rel="stylesheet" href="lib/codemirror/lib/codemirror.css">
|
||||||
<link rel="stylesheet" href="lib/codemirror/theme/monokai.css">
|
|
||||||
|
<link rel="stylesheet" id="editorThemeLinkTag" href="/lib/codemirror/theme/monokai.css"></link>
|
||||||
|
|
||||||
<link rel="stylesheet" href="lib/codemirror/addon/hint/show-hint.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/codemirror/addon/fold/foldgutter.css">
|
||||||
<link rel="stylesheet" href="lib/hint.min.css">
|
<link rel="stylesheet" href="lib/hint.min.css">
|
||||||
@ -19,16 +21,16 @@
|
|||||||
Add library <span id="js-external-lib-count" style="display:none;" class="count-label"></span>
|
Add library <span id="js-external-lib-count" style="display:none;" class="count-label"></span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a id="newBtn" class="flex flex-v-center hint--bottom-left" aria-label="Start a new creation">
|
<a class="flex flex-v-center hint--bottom-left" aria-label="Start a new creation" d-click="onNewBtnClick">
|
||||||
<svg style="vertical-align:middle;width:14px;height:14px" viewBox="0 0 24 24">
|
<svg style="vertical-align:middle;width:14px;height:14px" viewBox="0 0 24 24">
|
||||||
<path d="M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z" />
|
<path d="M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z" />
|
||||||
</svg>New
|
</svg>New
|
||||||
</a>
|
</a>
|
||||||
<a id="saveBtn" class="flex flex-v-center hint--bottom-left" aria-label="Save current creation (Ctrl/⌘ + S)">
|
<a id="saveBtn" class="flex flex-v-center hint--bottom-left" aria-label="Save current creation (Ctrl/⌘ + S)" d-click="onSaveBtnClick">
|
||||||
<svg style="vertical-align:middle;width:14px;height:14px" viewBox="0 0 24 24">
|
<svg style="vertical-align:middle;width:14px;height:14px" viewBox="0 0 24 24">
|
||||||
<path d="M15,9H5V5H15M12,19A3,3 0 0,1 9,16A3,3 0 0,1 12,13A3,3 0 0,1 15,16A3,3 0 0,1 12,19M17,3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V7L17,3Z" />
|
<path d="M15,9H5V5H15M12,19A3,3 0 0,1 9,16A3,3 0 0,1 12,13A3,3 0 0,1 15,16A3,3 0 0,1 12,19M17,3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V7L17,3Z" />
|
||||||
</svg>Save</a>
|
</svg>Save</a>
|
||||||
<a id="openBtn" class="flex flex-v-center hint--bottom-left" aria-label="Open a saved creation (Ctrl/⌘ + O)">
|
<a class="flex flex-v-center hint--bottom-left" aria-label="Open a saved creation (Ctrl/⌘ + O)" d-click="onOpenBtnClick">
|
||||||
<svg style="width:14px;height:14px;vertical-align:middle;" viewBox="0 0 24 24">
|
<svg style="width:14px;height:14px;vertical-align:middle;" viewBox="0 0 24 24">
|
||||||
<path d="M13,9V3.5L18.5,9M6,2C4.89,2 4,2.89 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2H6Z" />
|
<path d="M13,9V3.5L18.5,9M6,2C4.89,2 4,2.89 4,4V20A2,2 0 0,0 6,22H18A2,2 0 0,0 20,20V8L14,2H6Z" />
|
||||||
</svg>Open
|
</svg>Open
|
||||||
@ -45,7 +47,7 @@
|
|||||||
<ul class="js-modes-menu dropdown__menu">
|
<ul class="js-modes-menu dropdown__menu">
|
||||||
<li><a data-type="html" data-mode="html">HTML</a></li>
|
<li><a data-type="html" data-mode="html">HTML</a></li>
|
||||||
<li><a data-type="html" data-mode="markdown">Markdown</a></li>
|
<li><a data-type="html" data-mode="markdown">Markdown</a></li>
|
||||||
<li><a data-type="html" data-mode="jade">Jade</a></li>
|
<li><a data-type="html" data-mode="jade">Pug</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="code-wrap__header-right-options">
|
<div class="code-wrap__header-right-options">
|
||||||
@ -175,9 +177,10 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="modal" id="addLibraryModal">
|
<div class="modal" id="addLibraryModal">
|
||||||
<div class="modal__content" id="app">
|
<div class="modal__content">
|
||||||
<h1>Add Library</h1>
|
<h1>Add Library</h1>
|
||||||
<h3>JavaScript</h3>
|
<h3>JavaScript</h3>
|
||||||
|
<p style="font-size: 0.8em;opacity: 0.7;">Note: You can load external scripts from following domains: localhost, https://ajax.googleapis.com, https://code.jquery.com, https://cdnjs.cloudflare.com, https://unpkg.com, https://maxcdn.com, https://cdn77.com, https://maxcdn.bootstrapcdn.com, https://cdn.jsdelivr.net/</p>
|
||||||
<textarea id="js-external-js" class="full-width" id="" cols="30" rows="5" placeholder="Start typing name of a library. Put each library in new line"></textarea>
|
<textarea id="js-external-js" class="full-width" id="" cols="30" rows="5" placeholder="Start typing name of a library. Put each library in new line"></textarea>
|
||||||
|
|
||||||
<h3>CSS</h3>
|
<h3>CSS</h3>
|
||||||
@ -200,12 +203,13 @@
|
|||||||
|
|
||||||
<div class="modal" id="helpModal">
|
<div class="modal" id="helpModal">
|
||||||
<div class="modal__content">
|
<div class="modal__content">
|
||||||
<h1>Web Maker<small style="font-size:14px;"> v2.3.2</small></h1>
|
<h1>Web Maker<small style="font-size:14px;"> v2.4.0</small></h1>
|
||||||
<div>
|
<div>
|
||||||
<p>Made with <span style="margin-right: 8px;">💖</span> & <span style="margin-right: 8px;">🙌</span> by <a href="https://twitter.com/chinchang457" target="_blank">Kushagra Gour</a></p>
|
<p>Made with <span style="margin-right: 8px;">💖</span> & <span style="margin-right: 8px;">🙌</span> 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>
|
<p>Tweet out your feature requests, comments & suggestions to <a target="_blank" href="https://twitter.com/webmakerApp">@webmakerApp</a>.</p>
|
||||||
<p>Like this extension? Please <a href="https://chrome.google.com/webstore/detail/web-maker/lkfkkhfhhdkiemehlpkgjeojomhpccnh/reviews" target="_blank">rate it here</a>.</p>
|
<p>Like this extension? Please <a href="https://chrome.google.com/webstore/detail/web-maker/lkfkkhfhhdkiemehlpkgjeojomhpccnh/reviews" target="_blank">rate it here</a>.</p>
|
||||||
<p>
|
<p>
|
||||||
|
<a aria-label="Rate Web Maker" href="https://chrome.google.com/webstore/detail/web-maker/lkfkkhfhhdkiemehlpkgjeojomhpccnh/reviews" target="_blank" class="btn btn-icon"><svg><use xlink:href="#heart-icon"></use></svg>Show some love</a>
|
||||||
<a aria-label="Report a Bug" href="https://github.com/chinchang/web-maker/issues" target="_blank" class="btn btn-icon"><svg><use xlink:href="#bug-icon"></use></svg>Report a Bug</a>
|
<a aria-label="Report a Bug" href="https://github.com/chinchang/web-maker/issues" target="_blank" class="btn btn-icon"><svg><use xlink:href="#bug-icon"></use></svg>Report a Bug</a>
|
||||||
<a aria-label="Contribute on Github" href="https://github.com/chinchang/web-maker" target="_blank" class="btn btn-icon"><svg><use xlink:href="#github-icon"></use></svg>Contribute on Github</a>.
|
<a aria-label="Contribute on Github" href="https://github.com/chinchang/web-maker" target="_blank" class="btn btn-icon"><svg><use xlink:href="#github-icon"></use></svg>Contribute on Github</a>.
|
||||||
</p>
|
</p>
|
||||||
@ -291,16 +295,120 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="modal" id="settingsModal">
|
||||||
|
<div class="modal__content">
|
||||||
|
<h1>Settings</h1>
|
||||||
|
|
||||||
|
<h3>Indentation</h3>
|
||||||
|
<p>
|
||||||
|
<div class="line">
|
||||||
|
<label>
|
||||||
|
<input type="radio" checked="true" name="indentation" value="spaces" d-change="updateSetting" data-setting="indentWith"> Spaces
|
||||||
|
</label>
|
||||||
|
<label class="ml-1">
|
||||||
|
<input type="radio" name="indentation" value="tabs" d-change="updateSetting" data-setting="indentWith"> Tabs
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<label class="line">
|
||||||
|
Indentation Size <input type="range" class="va-m ml-1" value="2" min="1" max="7" list="indentationSizeList" data-setting="indentSize" d-change="updateSetting">
|
||||||
|
<datalist id="indentationSizeList">
|
||||||
|
<option>1</option>
|
||||||
|
<option>2</option>
|
||||||
|
<option>3</option>
|
||||||
|
<option>4</option>
|
||||||
|
<option>5</option>
|
||||||
|
<option>6</option>
|
||||||
|
<option>7</option>
|
||||||
|
</datalist>
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h3>Editor</h3>
|
||||||
|
<p>
|
||||||
|
<label class="line">
|
||||||
|
Default Preprocessors
|
||||||
|
</label>
|
||||||
|
<div class="flex line">
|
||||||
|
<select style="flex:1;margin:0 20px" data-setting="htmlMode" d-change="updateSetting">
|
||||||
|
<option value="html">HTML</option>
|
||||||
|
<option value="markdown">Markdown</option>
|
||||||
|
<option value="jade">Pug</option>
|
||||||
|
</select>
|
||||||
|
<select style="flex:1;margin:0 20px" data-setting="cssMode" d-change="updateSetting">
|
||||||
|
<option value="css">CSS</option>
|
||||||
|
<option value="scss">SCSS</option>
|
||||||
|
<option value="sass">SASS</option>
|
||||||
|
<option value="less">LESS</option>
|
||||||
|
<option value="stylus">Stylus</option>
|
||||||
|
</select>
|
||||||
|
<select style="flex:1;margin:0 20px" data-setting="jsMode" d-change="updateSetting">
|
||||||
|
<option value="js">JS</option>
|
||||||
|
<option value="coffee">CoffeeScript</option>
|
||||||
|
<option value="es6">ES6 (Babel)</option>
|
||||||
|
<option value="typescript">TypeScript</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<label class="line">
|
||||||
|
Theme
|
||||||
|
<select style="flex:1;margin:0 20px" data-setting="editorTheme" d-change="updateSetting"></select>
|
||||||
|
</label>
|
||||||
|
<label class="line">
|
||||||
|
Font Size <input type="number" value="16" data-setting="fontSize" d-change="updateSetting"> px
|
||||||
|
|
||||||
|
</label>
|
||||||
|
<div class="line">
|
||||||
|
Key bindings
|
||||||
|
<label class="ml-1">
|
||||||
|
<input type="radio" checked="true" name="keymap" value="sublime" d-change="updateSetting" data-setting="keymap"> Sublime
|
||||||
|
</label>
|
||||||
|
<label class="ml-1">
|
||||||
|
<input type="radio" name="keymap" value="vim" d-change="updateSetting" data-setting="keymap"> Vim
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<label class="line">
|
||||||
|
<input type="checkbox" d-change="updateSetting" data-setting="preserveLastCode"> Preserve last written code
|
||||||
|
</label>
|
||||||
|
<label class="line">
|
||||||
|
<input type="checkbox" d-change="updateSetting" data-setting="replaceNewTab"> Replace new tab page
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h3>Fun</h3>
|
||||||
|
<p>
|
||||||
|
<label class="line">
|
||||||
|
<input type="checkbox" d-change="updateSetting" data-setting="isCodeBlastOn"> Code blast!
|
||||||
|
</label>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="modal" id="notificationsModal">
|
<div class="modal" id="notificationsModal">
|
||||||
<div class="modal__content">
|
<div class="modal__content">
|
||||||
<h1>Whats new?</h1>
|
<h1>Whats new?</h1>
|
||||||
|
<div class="notification">
|
||||||
|
<span class="notification__version">2.4.0</span>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Import/Export</strong>: Your creations are most important. Now export all your creations into a single file as a backup that can be imported anytime & anywhere.</li>
|
||||||
|
<li><strong>Editor themes</strong>: You have been heard. Now you can choose from a huge list of wonderful editor themes!</li>
|
||||||
|
<li><strong>Identation settings</strong>: Not a spaces fan? Switch to tabs and set your indentation size.</li>
|
||||||
|
<li><strong>Vim key bindings</strong>: Rejoice Vim lovers!</li>
|
||||||
|
<li><strong>Code blast</strong>: Why don't you try coding with this switched on from the settings? Go on...</li>
|
||||||
|
<li><strong>Important</strong>: Due to security policy changes from Chrome 57 onwards, Web Maker now allows loading external JavaScript libraries only from certain whitelisted domains (localhost, https://ajax.googleapis.com, https://code.jquery.com, https://cdnjs.cloudflare.com, https://unpkg.com, https://maxcdn.com, https://cdn77.com, https://maxcdn.bootstrapcdn.com, https://cdn.jsdelivr.net/)</li>
|
||||||
|
<li>Save button now highlights when you have unsaved changes.</li>
|
||||||
|
<li>Jade is now called Pug. Just a name change.</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://kushagragour.in/lab/web-maker/&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">
|
<div class="notification">
|
||||||
<span class="notification__version">2.3.2</span>
|
<span class="notification__version">2.3.2</span>
|
||||||
<ul>
|
<ul>
|
||||||
<li>Update Babel to support latest and coolest ES6 features.</li>
|
<li>Update Babel to support latest and coolest ES6 features.</li>
|
||||||
<li>Improve onboarding experience at first install.</li>
|
<li>Improve onboarding experience at first install.</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://kushagragour.in/lab/web-maker/&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>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="notification">
|
<div class="notification">
|
||||||
@ -377,7 +485,16 @@
|
|||||||
|
|
||||||
<div id="js-saved-items-pane" class="saved-items-pane">
|
<div id="js-saved-items-pane" class="saved-items-pane">
|
||||||
<button class="btn saved-items-pane__close-btn" id="js-saved-items-pane-close-btn">X</button>
|
<button class="btn saved-items-pane__close-btn" id="js-saved-items-pane-close-btn">X</button>
|
||||||
<h3>My Library</h3>
|
<div class="flex flex-v-center" style="justify-content: space-between;">
|
||||||
|
|
||||||
|
<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>
|
||||||
|
<a d-click="onImportBtnClicked" href="" class="btn btn-icon">Import
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div id="js-saved-items-wrap" class="saved-items-pane__container">
|
<div id="js-saved-items-wrap" class="saved-items-pane__container">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
@ -419,6 +536,9 @@
|
|||||||
<symbol id="settings-icon" viewBox="0 0 24 24">
|
<symbol id="settings-icon" viewBox="0 0 24 24">
|
||||||
<path d="M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z"></path>
|
<path d="M12,15.5A3.5,3.5 0 0,1 8.5,12A3.5,3.5 0 0,1 12,8.5A3.5,3.5 0 0,1 15.5,12A3.5,3.5 0 0,1 12,15.5M19.43,12.97C19.47,12.65 19.5,12.33 19.5,12C19.5,11.67 19.47,11.34 19.43,11L21.54,9.37C21.73,9.22 21.78,8.95 21.66,8.73L19.66,5.27C19.54,5.05 19.27,4.96 19.05,5.05L16.56,6.05C16.04,5.66 15.5,5.32 14.87,5.07L14.5,2.42C14.46,2.18 14.25,2 14,2H10C9.75,2 9.54,2.18 9.5,2.42L9.13,5.07C8.5,5.32 7.96,5.66 7.44,6.05L4.95,5.05C4.73,4.96 4.46,5.05 4.34,5.27L2.34,8.73C2.21,8.95 2.27,9.22 2.46,9.37L4.57,11C4.53,11.34 4.5,11.67 4.5,12C4.5,12.33 4.53,12.65 4.57,12.97L2.46,14.63C2.27,14.78 2.21,15.05 2.34,15.27L4.34,18.73C4.46,18.95 4.73,19.03 4.95,18.95L7.44,17.94C7.96,18.34 8.5,18.68 9.13,18.93L9.5,21.58C9.54,21.82 9.75,22 10,22H14C14.25,22 14.46,21.82 14.5,21.58L14.87,18.93C15.5,18.67 16.04,18.34 16.56,17.94L19.05,18.95C19.27,19.03 19.54,18.95 19.66,18.73L21.66,15.27C21.78,15.05 21.73,14.78 21.54,14.63L19.43,12.97Z"></path>
|
||||||
</symbol>
|
</symbol>
|
||||||
|
<symbol id="heart-icon" viewBox="0 0 24 24">
|
||||||
|
<path d="M12,21.35L10.55,20.03C5.4,15.36 2,12.27 2,8.5C2,5.41 4.42,3 7.5,3C9.24,3 10.91,3.81 12,5.08C13.09,3.81 14.76,3 16.5,3C19.58,3 22,5.41 22,8.5C22,12.27 18.6,15.36 13.45,20.03L12,21.35Z" />
|
||||||
|
</symbol>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
<script src="lib/codemirror/lib/codemirror.js"></script>
|
<script src="lib/codemirror/lib/codemirror.js"></script>
|
||||||
@ -445,7 +565,9 @@
|
|||||||
<script src="lib/codemirror/mode/css/css.js"></script>
|
<script src="lib/codemirror/mode/css/css.js"></script>
|
||||||
<script src="lib/codemirror/mode/htmlmixed/htmlmixed.js"></script>
|
<script src="lib/codemirror/mode/htmlmixed/htmlmixed.js"></script>
|
||||||
<script src="lib/codemirror/keymap/sublime.js"></script>
|
<script src="lib/codemirror/keymap/sublime.js"></script>
|
||||||
|
<script src="lib/codemirror/keymap/vim.js"></script>
|
||||||
<script src="lib/emmet.js"></script>
|
<script src="lib/emmet.js"></script>
|
||||||
|
<script src="lib/code-blast.js"></script>
|
||||||
|
|
||||||
<script src="lib/split.js"></script>
|
<script src="lib/split.js"></script>
|
||||||
<script src="lib/inlet.min.js"></script>
|
<script src="lib/inlet.min.js"></script>
|
||||||
|
222
src/lib/code-blast.js
Normal file
222
src/lib/code-blast.js
Normal file
@ -0,0 +1,222 @@
|
|||||||
|
/*
|
||||||
|
Based on Joel Besada's lovely experiment
|
||||||
|
https://twitter.com/JoelBesada/status/670343885655293952
|
||||||
|
*/
|
||||||
|
|
||||||
|
;(function () {
|
||||||
|
var shakeTime = 0,
|
||||||
|
shakeTimeMax = 0,
|
||||||
|
shakeIntensity = 5,
|
||||||
|
lastTime = 0,
|
||||||
|
particles = [],
|
||||||
|
particlePointer = 0,
|
||||||
|
MAX_PARTICLES = 100,
|
||||||
|
PARTICLE_NUM_RANGE = { min: 2, max: 7 },
|
||||||
|
PARTICLE_GRAVITY = 0.08,
|
||||||
|
PARTICLE_ALPHA_FADEOUT = 0.96,
|
||||||
|
PARTICLE_VELOCITY_RANGE = {
|
||||||
|
x: [-1, 1],
|
||||||
|
y: [-3.5, -1.5]
|
||||||
|
},
|
||||||
|
w = window.innerWidth,
|
||||||
|
h = window.innerHeight,
|
||||||
|
effect,
|
||||||
|
isActive = false;
|
||||||
|
|
||||||
|
var codemirrors = [], cmNode;
|
||||||
|
var canvas, ctx;
|
||||||
|
var current_time, dt, magnitude, shakeX, shakeY; // loop vars
|
||||||
|
var throttledShake = throttle(shake, 100);
|
||||||
|
var throttledSpawnParticles = throttle(spawnParticles, 100);
|
||||||
|
|
||||||
|
function getRGBComponents(node) {
|
||||||
|
var color = getComputedStyle(node).color;
|
||||||
|
if (color) {
|
||||||
|
try {
|
||||||
|
return color.match(/(\d+), (\d+), (\d+)/).slice(1);
|
||||||
|
} catch(e) {
|
||||||
|
return [255, 255, 255];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return [255, 255, 255];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function spawnParticles(cm, type) {
|
||||||
|
var cursorPos = cm.getCursor();
|
||||||
|
var pos = cm.cursorCoords();
|
||||||
|
var node = document.elementFromPoint(pos.left - 5, pos.top + 5);
|
||||||
|
type = cm.getTokenAt(cursorPos);
|
||||||
|
if (type) { type = type.type; };
|
||||||
|
var numParticles = random(PARTICLE_NUM_RANGE.min, PARTICLE_NUM_RANGE.max);
|
||||||
|
var color = getRGBComponents(node);
|
||||||
|
for (var i = numParticles; i--;) {
|
||||||
|
particles[particlePointer] = createParticle(pos.left + 10, pos.top, color);
|
||||||
|
particlePointer = (particlePointer + 1) % MAX_PARTICLES;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createParticle(x, y, color) {
|
||||||
|
var p = {
|
||||||
|
x: x,
|
||||||
|
y: y + 10,
|
||||||
|
alpha: 1,
|
||||||
|
color: color
|
||||||
|
};
|
||||||
|
if (effect === 1) {
|
||||||
|
p.size = random(2, 4);
|
||||||
|
p.vx = PARTICLE_VELOCITY_RANGE.x[0] + Math.random() *
|
||||||
|
(PARTICLE_VELOCITY_RANGE.x[1] - PARTICLE_VELOCITY_RANGE.x[0]);
|
||||||
|
p.vy = PARTICLE_VELOCITY_RANGE.y[0] + Math.random() *
|
||||||
|
(PARTICLE_VELOCITY_RANGE.y[1] - PARTICLE_VELOCITY_RANGE.y[0]);
|
||||||
|
} else if (effect === 2) {
|
||||||
|
p.size = random(2, 8);
|
||||||
|
p.drag = 0.92;
|
||||||
|
p.vx = random(-3, 3);
|
||||||
|
p.vy = random(-3, 3);
|
||||||
|
p.wander = 0.15;
|
||||||
|
p.theta = random(0, 360) * Math.PI / 180;
|
||||||
|
}
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
function effect1(particle) {
|
||||||
|
particle.vy += PARTICLE_GRAVITY;
|
||||||
|
particle.x += particle.vx;
|
||||||
|
particle.y += particle.vy;
|
||||||
|
|
||||||
|
particle.alpha *= PARTICLE_ALPHA_FADEOUT;
|
||||||
|
|
||||||
|
ctx.fillStyle = 'rgba('+ particle.color[0] +','+ particle.color[1] +','+ particle.color[2] + ',' + particle.alpha + ')';
|
||||||
|
ctx.fillRect(Math.round(particle.x - 1), Math.round(particle.y - 1), particle.size, particle.size);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Effect based on Soulwire's demo: http://codepen.io/soulwire/pen/foktm
|
||||||
|
function effect2(particle) {
|
||||||
|
particle.x += particle.vx;
|
||||||
|
particle.y += particle.vy;
|
||||||
|
particle.vx *= particle.drag;
|
||||||
|
particle.vy *= particle.drag;
|
||||||
|
particle.theta += random( -0.5, 0.5 );
|
||||||
|
particle.vx += Math.sin( particle.theta ) * 0.1;
|
||||||
|
particle.vy += Math.cos( particle.theta ) * 0.1;
|
||||||
|
particle.size *= 0.96;
|
||||||
|
|
||||||
|
ctx.fillStyle = 'rgba('+ particle.color[0] +','+ particle.color[1] +','+ particle.color[2] + ',' + particle.alpha + ')';
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.arc(Math.round(particle.x - 1), Math.round(particle.y - 1), particle.size, 0, 2 * Math.PI);
|
||||||
|
ctx.fill();
|
||||||
|
}
|
||||||
|
|
||||||
|
function drawParticles(timeDelta) {
|
||||||
|
var particle;
|
||||||
|
for (var i = particles.length; i--;) {
|
||||||
|
particle = particles[i];
|
||||||
|
if (!particle || particle.alpha < 0.01 || particle.size <= 0.5) { continue; }
|
||||||
|
|
||||||
|
if (effect === 1) { effect1(particle); }
|
||||||
|
else if (effect === 2) { effect2(particle); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function shake(editor, time) {
|
||||||
|
cmNode = editor.getWrapperElement();
|
||||||
|
shakeTime = shakeTimeMax = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
function random(min, max) {
|
||||||
|
if (!max) { max = min; min = 0; }
|
||||||
|
return min + ~~(Math.random() * (max - min + 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
function throttle (callback, limit) {
|
||||||
|
var wait = false;
|
||||||
|
return function () {
|
||||||
|
if (!wait) {
|
||||||
|
callback.apply(this, arguments);
|
||||||
|
wait = true;
|
||||||
|
setTimeout(function () {
|
||||||
|
wait = false;
|
||||||
|
}, limit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function loop() {
|
||||||
|
if (!isActive) { return; }
|
||||||
|
|
||||||
|
ctx.clearRect(0, 0, w, h);
|
||||||
|
|
||||||
|
// get the time past the previous frame
|
||||||
|
current_time = new Date().getTime();
|
||||||
|
if(!lastTime) lastTime = current_time;
|
||||||
|
dt = (current_time - lastTime) / 1000;
|
||||||
|
lastTime = current_time;
|
||||||
|
|
||||||
|
if (shakeTime > 0) {
|
||||||
|
shakeTime -= dt;
|
||||||
|
magnitude = (shakeTime / shakeTimeMax) * shakeIntensity;
|
||||||
|
shakeX = random(-magnitude, magnitude);
|
||||||
|
shakeY = random(-magnitude, magnitude);
|
||||||
|
cmNode.style.transform = 'translate(' + shakeX + 'px,' + shakeY + 'px)';
|
||||||
|
}
|
||||||
|
drawParticles();
|
||||||
|
requestAnimationFrame(loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onCodeMirrorChange(editor, change) {
|
||||||
|
if (change.origin !== '+input' && change.origin !== '+delete') { return; }
|
||||||
|
|
||||||
|
if (editor.getOption('blastCode') === true || editor.getOption('blastCode').shake === undefined) {
|
||||||
|
throttledShake(editor, 0.3);
|
||||||
|
}
|
||||||
|
throttledSpawnParticles(editor);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function init(editor) {
|
||||||
|
isActive = true;
|
||||||
|
|
||||||
|
if (!canvas) {
|
||||||
|
canvas = document.createElement('canvas');
|
||||||
|
ctx = canvas.getContext('2d'),
|
||||||
|
|
||||||
|
canvas.id = 'code-blast-canvas'
|
||||||
|
canvas.style.position = 'absolute';
|
||||||
|
canvas.style.top = 0;
|
||||||
|
canvas.style.left = 0;
|
||||||
|
canvas.style.zIndex = 1;
|
||||||
|
canvas.style.pointerEvents = 'none';
|
||||||
|
canvas.width = w;
|
||||||
|
canvas.height = h;
|
||||||
|
|
||||||
|
document.body.appendChild(canvas);
|
||||||
|
loop();
|
||||||
|
}
|
||||||
|
|
||||||
|
editor.on("change", onCodeMirrorChange);
|
||||||
|
}
|
||||||
|
|
||||||
|
function destroy(editor) {
|
||||||
|
editor.off('change', onCodeMirrorChange);
|
||||||
|
codemirrors.splice(codemirrors.indexOf(editor), 1);
|
||||||
|
if (!codemirrors.length) {
|
||||||
|
isActive = false;
|
||||||
|
if (canvas) {
|
||||||
|
canvas.remove();
|
||||||
|
canvas = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CodeMirror.defineOption('blastCode', false, function(editor, val, old) {
|
||||||
|
if (val) {
|
||||||
|
codemirrors.push(editor);
|
||||||
|
effect = val.effect || 2;
|
||||||
|
init(editor);
|
||||||
|
} else {
|
||||||
|
destroy(editor);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
})();
|
5117
src/lib/codemirror/keymap/vim.js
vendored
Normal file
5117
src/lib/codemirror/keymap/vim.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -11,7 +11,7 @@
|
|||||||
})(function(CodeMirror) {
|
})(function(CodeMirror) {
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
CodeMirror.defineMode('jade', function (config) {
|
CodeMirror.defineMode("pug", function (config) {
|
||||||
// token types
|
// token types
|
||||||
var KEYWORD = 'keyword';
|
var KEYWORD = 'keyword';
|
||||||
var DOCTYPE = 'meta';
|
var DOCTYPE = 'meta';
|
||||||
@ -36,7 +36,7 @@ CodeMirror.defineMode('jade', function (config) {
|
|||||||
this.isInterpolating = false;
|
this.isInterpolating = false;
|
||||||
this.interpolationNesting = 0;
|
this.interpolationNesting = 0;
|
||||||
|
|
||||||
this.jsState = jsMode.startState();
|
this.jsState = CodeMirror.startState(jsMode);
|
||||||
|
|
||||||
this.restOfLine = '';
|
this.restOfLine = '';
|
||||||
|
|
||||||
@ -386,7 +386,7 @@ CodeMirror.defineMode('jade', function (config) {
|
|||||||
if (state.inAttributeName && stream.match(/^[^=,\)!]+/)) {
|
if (state.inAttributeName && stream.match(/^[^=,\)!]+/)) {
|
||||||
if (stream.peek() === '=' || stream.peek() === '!') {
|
if (stream.peek() === '=' || stream.peek() === '!') {
|
||||||
state.inAttributeName = false;
|
state.inAttributeName = false;
|
||||||
state.jsState = jsMode.startState();
|
state.jsState = CodeMirror.startState(jsMode);
|
||||||
if (state.lastTag === 'script' && stream.current().trim().toLowerCase() === 'type') {
|
if (state.lastTag === 'script' && stream.current().trim().toLowerCase() === 'type') {
|
||||||
state.attributeIsType = true;
|
state.attributeIsType = true;
|
||||||
} else {
|
} else {
|
||||||
@ -492,7 +492,7 @@ CodeMirror.defineMode('jade', function (config) {
|
|||||||
if (stream.indentation() > state.indentOf || (state.innerModeForLine && !stream.sol()) || force) {
|
if (stream.indentation() > state.indentOf || (state.innerModeForLine && !stream.sol()) || force) {
|
||||||
if (state.innerMode) {
|
if (state.innerMode) {
|
||||||
if (!state.innerState) {
|
if (!state.innerState) {
|
||||||
state.innerState = state.innerMode.startState ? state.innerMode.startState(stream.indentation()) : {};
|
state.innerState = state.innerMode.startState ? CodeMirror.startState(state.innerMode, stream.indentation()) : {};
|
||||||
}
|
}
|
||||||
return stream.hideFirstChars(state.indentOf + 2, function () {
|
return stream.hideFirstChars(state.indentOf + 2, function () {
|
||||||
return state.innerMode.token(stream, state.innerState) || true;
|
return state.innerMode.token(stream, state.innerState) || true;
|
||||||
@ -585,6 +585,7 @@ CodeMirror.defineMode('jade', function (config) {
|
|||||||
};
|
};
|
||||||
}, 'javascript', 'css', 'htmlmixed');
|
}, 'javascript', 'css', 'htmlmixed');
|
||||||
|
|
||||||
CodeMirror.defineMIME('text/x-jade', 'jade');
|
CodeMirror.defineMIME('text/x-pug', 'pug');
|
||||||
|
CodeMirror.defineMIME('text/x-jade', 'pug');
|
||||||
|
|
||||||
});
|
});
|
7
src/lib/codemirror/theme/dracula.css
vendored
7
src/lib/codemirror/theme/dracula.css
vendored
@ -16,7 +16,7 @@
|
|||||||
.cm-s-dracula .CodeMirror-gutters { color: #282a36; }
|
.cm-s-dracula .CodeMirror-gutters { color: #282a36; }
|
||||||
.cm-s-dracula .CodeMirror-cursor { border-left: solid thin #f8f8f0; }
|
.cm-s-dracula .CodeMirror-cursor { border-left: solid thin #f8f8f0; }
|
||||||
.cm-s-dracula .CodeMirror-linenumber { color: #6D8A88; }
|
.cm-s-dracula .CodeMirror-linenumber { color: #6D8A88; }
|
||||||
.cm-s-dracula.CodeMirror-focused div.CodeMirror-selected { background: rgba(255, 255, 255, 0.10); }
|
.cm-s-dracula .CodeMirror-selected { background: rgba(255, 255, 255, 0.10); }
|
||||||
.cm-s-dracula .CodeMirror-line::selection, .cm-s-dracula .CodeMirror-line > span::selection, .cm-s-dracula .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); }
|
.cm-s-dracula .CodeMirror-line::selection, .cm-s-dracula .CodeMirror-line > span::selection, .cm-s-dracula .CodeMirror-line > span > span::selection { background: rgba(255, 255, 255, 0.10); }
|
||||||
.cm-s-dracula .CodeMirror-line::-moz-selection, .cm-s-dracula .CodeMirror-line > span::-moz-selection, .cm-s-dracula .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); }
|
.cm-s-dracula .CodeMirror-line::-moz-selection, .cm-s-dracula .CodeMirror-line > span::-moz-selection, .cm-s-dracula .CodeMirror-line > span > span::-moz-selection { background: rgba(255, 255, 255, 0.10); }
|
||||||
.cm-s-dracula span.cm-comment { color: #6272a4; }
|
.cm-s-dracula span.cm-comment { color: #6272a4; }
|
||||||
@ -24,8 +24,7 @@
|
|||||||
.cm-s-dracula span.cm-number { color: #bd93f9; }
|
.cm-s-dracula span.cm-number { color: #bd93f9; }
|
||||||
.cm-s-dracula span.cm-variable { color: #50fa7b; }
|
.cm-s-dracula span.cm-variable { color: #50fa7b; }
|
||||||
.cm-s-dracula span.cm-variable-2 { color: white; }
|
.cm-s-dracula span.cm-variable-2 { color: white; }
|
||||||
.cm-s-dracula span.cm-def { color: #ffb86c; }
|
.cm-s-dracula span.cm-def { color: #50fa7b; }
|
||||||
.cm-s-dracula span.cm-keyword { color: #ff79c6; }
|
|
||||||
.cm-s-dracula span.cm-operator { color: #ff79c6; }
|
.cm-s-dracula span.cm-operator { color: #ff79c6; }
|
||||||
.cm-s-dracula span.cm-keyword { color: #ff79c6; }
|
.cm-s-dracula span.cm-keyword { color: #ff79c6; }
|
||||||
.cm-s-dracula span.cm-atom { color: #bd93f9; }
|
.cm-s-dracula span.cm-atom { color: #bd93f9; }
|
||||||
@ -35,7 +34,7 @@
|
|||||||
.cm-s-dracula span.cm-qualifier { color: #50fa7b; }
|
.cm-s-dracula span.cm-qualifier { color: #50fa7b; }
|
||||||
.cm-s-dracula span.cm-property { color: #66d9ef; }
|
.cm-s-dracula span.cm-property { color: #66d9ef; }
|
||||||
.cm-s-dracula span.cm-builtin { color: #50fa7b; }
|
.cm-s-dracula span.cm-builtin { color: #50fa7b; }
|
||||||
.cm-s-dracula span.cm-variable-3 { color: #50fa7b; }
|
.cm-s-dracula span.cm-variable-3 { color: #ffb86c; }
|
||||||
|
|
||||||
.cm-s-dracula .CodeMirror-activeline-background { background: rgba(255,255,255,0.1); }
|
.cm-s-dracula .CodeMirror-activeline-background { background: rgba(255,255,255,0.1); }
|
||||||
.cm-s-dracula .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
|
.cm-s-dracula .CodeMirror-matchingbracket { text-decoration: underline; color: white !important; }
|
||||||
|
35
src/lib/codemirror/theme/duotone-dark.css
vendored
Normal file
35
src/lib/codemirror/theme/duotone-dark.css
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
Name: DuoTone-Dark
|
||||||
|
Author: by Bram de Haan, adapted from DuoTone themes by Simurai (http://simurai.com/projects/2016/01/01/duotone-themes)
|
||||||
|
|
||||||
|
CodeMirror template by Jan T. Sott (https://github.com/idleberg), adapted by Bram de Haan (https://github.com/atelierbram/)
|
||||||
|
*/
|
||||||
|
|
||||||
|
.cm-s-duotone-dark.CodeMirror { background: #2a2734; color: #6c6783; }
|
||||||
|
.cm-s-duotone-dark div.CodeMirror-selected { background: #545167!important; }
|
||||||
|
.cm-s-duotone-dark .CodeMirror-gutters { background: #2a2734; border-right: 0px; }
|
||||||
|
.cm-s-duotone-dark .CodeMirror-linenumber { color: #545167; }
|
||||||
|
|
||||||
|
/* begin cursor */
|
||||||
|
.cm-s-duotone-dark .CodeMirror-cursor { border-left: 1px solid #ffad5c; /* border-left: 1px solid #ffad5c80; */ border-right: .5em solid #ffad5c; /* border-right: .5em solid #ffad5c80; */ opacity: .5; }
|
||||||
|
.cm-s-duotone-dark .CodeMirror-activeline-background { background: #363342; /* background: #36334280; */ opacity: .5;}
|
||||||
|
.cm-s-duotone-dark .cm-fat-cursor .CodeMirror-cursor { background: #ffad5c; /* background: #ffad5c80; */ opacity: .5;}
|
||||||
|
/* end cursor */
|
||||||
|
|
||||||
|
.cm-s-duotone-dark span.cm-atom, .cm-s-duotone-dark span.cm-number, .cm-s-duotone-dark span.cm-keyword, .cm-s-duotone-dark span.cm-variable, .cm-s-duotone-dark span.cm-attribute, .cm-s-duotone-dark span.cm-quote, .cm-s-duotone-dark span.cm-hr, .cm-s-duotone-dark span.cm-link { color: #ffcc99; }
|
||||||
|
|
||||||
|
.cm-s-duotone-dark span.cm-property { color: #9a86fd; }
|
||||||
|
.cm-s-duotone-dark span.cm-punctuation, .cm-s-duotone-dark span.cm-unit, .cm-s-duotone-dark span.cm-negative { color: #e09142; }
|
||||||
|
.cm-s-duotone-dark span.cm-string { color: #ffb870; }
|
||||||
|
.cm-s-duotone-dark span.cm-operator { color: #ffad5c; }
|
||||||
|
.cm-s-duotone-dark span.cm-positive { color: #6a51e6; }
|
||||||
|
|
||||||
|
.cm-s-duotone-dark span.cm-variable-2, .cm-s-duotone-dark span.cm-variable-3, .cm-s-duotone-dark span.cm-string-2, .cm-s-duotone-dark span.cm-url { color: #7a63ee; }
|
||||||
|
.cm-s-duotone-dark span.cm-def, .cm-s-duotone-dark span.cm-tag, .cm-s-duotone-dark span.cm-builtin, .cm-s-duotone-dark span.cm-qualifier, .cm-s-duotone-dark span.cm-header, .cm-s-duotone-dark span.cm-em { color: #eeebff; }
|
||||||
|
.cm-s-duotone-dark span.cm-bracket, .cm-s-duotone-dark span.cm-comment { color: #6c6783; }
|
||||||
|
|
||||||
|
/* using #f00 red for errors, don't think any of the colorscheme variables will stand out enough, ... maybe by giving it a background-color ... */
|
||||||
|
.cm-s-duotone-dark span.cm-error, .cm-s-duotone-dark span.cm-invalidchar { color: #f00; }
|
||||||
|
|
||||||
|
.cm-s-duotone-dark span.cm-header { font-weight: normal; }
|
||||||
|
.cm-s-duotone-dark .CodeMirror-matchingbracket { text-decoration: underline; color: #eeebff !important; }
|
36
src/lib/codemirror/theme/duotone-light.css
vendored
Normal file
36
src/lib/codemirror/theme/duotone-light.css
vendored
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
Name: DuoTone-Light
|
||||||
|
Author: by Bram de Haan, adapted from DuoTone themes by Simurai (http://simurai.com/projects/2016/01/01/duotone-themes)
|
||||||
|
|
||||||
|
CodeMirror template by Jan T. Sott (https://github.com/idleberg), adapted by Bram de Haan (https://github.com/atelierbram/)
|
||||||
|
*/
|
||||||
|
|
||||||
|
.cm-s-duotone-light.CodeMirror { background: #faf8f5; color: #b29762; }
|
||||||
|
.cm-s-duotone-light div.CodeMirror-selected { background: #e3dcce !important; }
|
||||||
|
.cm-s-duotone-light .CodeMirror-gutters { background: #faf8f5; border-right: 0px; }
|
||||||
|
.cm-s-duotone-light .CodeMirror-linenumber { color: #cdc4b1; }
|
||||||
|
|
||||||
|
/* begin cursor */
|
||||||
|
.cm-s-duotone-light .CodeMirror-cursor { border-left: 1px solid #93abdc; /* border-left: 1px solid #93abdc80; */ border-right: .5em solid #93abdc; /* border-right: .5em solid #93abdc80; */ opacity: .5; }
|
||||||
|
.cm-s-duotone-light .CodeMirror-activeline-background { background: #e3dcce; /* background: #e3dcce80; */ opacity: .5; }
|
||||||
|
.cm-s-duotone-light .cm-fat-cursor .CodeMirror-cursor { background: #93abdc; /* #93abdc80; */ opacity: .5; }
|
||||||
|
/* end cursor */
|
||||||
|
|
||||||
|
.cm-s-duotone-light span.cm-atom, .cm-s-duotone-light span.cm-number, .cm-s-duotone-light span.cm-keyword, .cm-s-duotone-light span.cm-variable, .cm-s-duotone-light span.cm-attribute, .cm-s-duotone-light span.cm-quote, .cm-s-duotone-light-light span.cm-hr, .cm-s-duotone-light-light span.cm-link { color: #063289; }
|
||||||
|
|
||||||
|
.cm-s-duotone-light span.cm-property { color: #b29762; }
|
||||||
|
.cm-s-duotone-light span.cm-punctuation, .cm-s-duotone-light span.cm-unit, .cm-s-duotone-light span.cm-negative { color: #063289; }
|
||||||
|
.cm-s-duotone-light span.cm-string, .cm-s-duotone-light span.cm-operator { color: #1659df; }
|
||||||
|
.cm-s-duotone-light span.cm-positive { color: #896724; }
|
||||||
|
|
||||||
|
.cm-s-duotone-light span.cm-variable-2, .cm-s-duotone-light span.cm-variable-3, .cm-s-duotone-light span.cm-string-2, .cm-s-duotone-light span.cm-url { color: #896724; }
|
||||||
|
.cm-s-duotone-light span.cm-def, .cm-s-duotone-light span.cm-tag, .cm-s-duotone-light span.cm-builtin, .cm-s-duotone-light span.cm-qualifier, .cm-s-duotone-light span.cm-header, .cm-s-duotone-light span.cm-em { color: #2d2006; }
|
||||||
|
.cm-s-duotone-light span.cm-bracket, .cm-s-duotone-light span.cm-comment { color: #b6ad9a; }
|
||||||
|
|
||||||
|
/* using #f00 red for errors, don't think any of the colorscheme variables will stand out enough, ... maybe by giving it a background-color ... */
|
||||||
|
/* .cm-s-duotone-light span.cm-error { background: #896724; color: #728fcb; } */
|
||||||
|
.cm-s-duotone-light span.cm-error, .cm-s-duotone-light span.cm-invalidchar { color: #f00; }
|
||||||
|
|
||||||
|
.cm-s-duotone-light span.cm-header { font-weight: normal; }
|
||||||
|
.cm-s-duotone-light .CodeMirror-matchingbracket { text-decoration: underline; color: #faf8f5 !important; }
|
||||||
|
|
2
src/lib/codemirror/theme/material.css
vendored
2
src/lib/codemirror/theme/material.css
vendored
@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.cm-s-material {
|
.cm-s-material.CodeMirror {
|
||||||
background-color: #263238;
|
background-color: #263238;
|
||||||
color: rgba(233, 237, 237, 1);
|
color: rgba(233, 237, 237, 1);
|
||||||
}
|
}
|
||||||
|
85
src/lib/codemirror/theme/panda-syntax.css
vendored
Normal file
85
src/lib/codemirror/theme/panda-syntax.css
vendored
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
Name: Panda Syntax
|
||||||
|
Author: Siamak Mokhtari (http://github.com/siamak/)
|
||||||
|
CodeMirror template by Siamak Mokhtari (https://github.com/siamak/atom-panda-syntax)
|
||||||
|
*/
|
||||||
|
.cm-s-panda-syntax {
|
||||||
|
background: #292A2B;
|
||||||
|
color: #E6E6E6;
|
||||||
|
line-height: 1.5;
|
||||||
|
font-family: 'Operator Mono', 'Source Sans Pro', Menlo, Monaco, Consolas, Courier New, monospace;
|
||||||
|
}
|
||||||
|
.cm-s-panda-syntax .CodeMirror-cursor { border-color: #ff2c6d; }
|
||||||
|
.cm-s-panda-syntax .CodeMirror-activeline-background {
|
||||||
|
background: rgba(99, 123, 156, 0.1);
|
||||||
|
}
|
||||||
|
.cm-s-panda-syntax .CodeMirror-selected {
|
||||||
|
background: #FFF;
|
||||||
|
}
|
||||||
|
.cm-s-panda-syntax .cm-comment {
|
||||||
|
font-style: italic;
|
||||||
|
color: #676B79;
|
||||||
|
}
|
||||||
|
.cm-s-panda-syntax .cm-operator {
|
||||||
|
color: #f3f3f3;
|
||||||
|
}
|
||||||
|
.cm-s-panda-syntax .cm-string {
|
||||||
|
color: #19F9D8;
|
||||||
|
}
|
||||||
|
.cm-s-panda-syntax .cm-string-2 {
|
||||||
|
color: #FFB86C;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-s-panda-syntax .cm-tag {
|
||||||
|
color: #ff2c6d;
|
||||||
|
}
|
||||||
|
.cm-s-panda-syntax .cm-meta {
|
||||||
|
color: #b084eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-s-panda-syntax .cm-number {
|
||||||
|
color: #FFB86C;
|
||||||
|
}
|
||||||
|
.cm-s-panda-syntax .cm-atom {
|
||||||
|
color: #ff2c6d;
|
||||||
|
}
|
||||||
|
.cm-s-panda-syntax .cm-keyword {
|
||||||
|
color: #FF75B5;
|
||||||
|
}
|
||||||
|
.cm-s-panda-syntax .cm-variable {
|
||||||
|
color: #ffb86c;
|
||||||
|
}
|
||||||
|
.cm-s-panda-syntax .cm-variable-2 {
|
||||||
|
color: #ff9ac1;
|
||||||
|
}
|
||||||
|
.cm-s-panda-syntax .cm-variable-3 {
|
||||||
|
color: #ff9ac1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-s-panda-syntax .cm-def {
|
||||||
|
color: #e6e6e6;
|
||||||
|
}
|
||||||
|
.cm-s-panda-syntax .cm-property {
|
||||||
|
color: #f3f3f3;
|
||||||
|
}
|
||||||
|
.cm-s-panda-syntax .cm-unit {
|
||||||
|
color: #ffb86c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-s-panda-syntax .cm-attribute {
|
||||||
|
color: #ffb86c;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-s-panda-syntax .CodeMirror-matchingbracket {
|
||||||
|
border-bottom: 1px dotted #19F9D8;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
color: #e6e6e6;
|
||||||
|
}
|
||||||
|
.cm-s-panda-syntax .CodeMirror-gutters {
|
||||||
|
background: #292a2b;
|
||||||
|
border-right-color: rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
.cm-s-panda-syntax .CodeMirror-linenumber {
|
||||||
|
color: #e6e6e6;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
1
src/lib/codemirror/theme/pastel-on-dark.css
vendored
1
src/lib/codemirror/theme/pastel-on-dark.css
vendored
@ -11,7 +11,6 @@
|
|||||||
background: #2c2827;
|
background: #2c2827;
|
||||||
color: #8F938F;
|
color: #8F938F;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
font-size: 14px;
|
|
||||||
}
|
}
|
||||||
.cm-s-pastel-on-dark div.CodeMirror-selected { background: rgba(221,240,255,0.2); }
|
.cm-s-pastel-on-dark div.CodeMirror-selected { background: rgba(221,240,255,0.2); }
|
||||||
.cm-s-pastel-on-dark .CodeMirror-line::selection, .cm-s-pastel-on-dark .CodeMirror-line > span::selection, .cm-s-pastel-on-dark .CodeMirror-line > span > span::selection { background: rgba(221,240,255,0.2); }
|
.cm-s-pastel-on-dark .CodeMirror-line::selection, .cm-s-pastel-on-dark .CodeMirror-line > span::selection, .cm-s-pastel-on-dark .CodeMirror-line > span > span::selection { background: rgba(221,240,255,0.2); }
|
||||||
|
@ -4,7 +4,7 @@ http://ethanschoonover.com/solarized
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Solarized color pallet
|
Solarized color palette
|
||||||
http://ethanschoonover.com/solarized/img/solarized-palette.png
|
http://ethanschoonover.com/solarized/img/solarized-palette.png
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -34,7 +34,7 @@ http://ethanschoonover.com/solarized/img/solarized-palette.png
|
|||||||
}
|
}
|
||||||
.cm-s-solarized.cm-s-dark {
|
.cm-s-solarized.cm-s-dark {
|
||||||
color: #839496;
|
color: #839496;
|
||||||
background-color: #002b36;
|
background-color: #002b36;
|
||||||
text-shadow: #002b36 0 1px;
|
text-shadow: #002b36 0 1px;
|
||||||
}
|
}
|
||||||
.cm-s-solarized.cm-s-light {
|
.cm-s-solarized.cm-s-light {
|
||||||
@ -113,32 +113,34 @@ http://ethanschoonover.com/solarized/img/solarized-palette.png
|
|||||||
box-shadow: inset 7px 0 12px -6px #000;
|
box-shadow: inset 7px 0 12px -6px #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Gutter border and some shadow from it */
|
/* Remove gutter border */
|
||||||
.cm-s-solarized .CodeMirror-gutters {
|
.cm-s-solarized .CodeMirror-gutters {
|
||||||
border-right: 1px solid;
|
border-right: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Gutter colors and line number styling based of color scheme (dark / light) */
|
/* Gutter colors and line number styling based of color scheme (dark / light) */
|
||||||
|
|
||||||
/* Dark */
|
/* Dark */
|
||||||
.cm-s-solarized.cm-s-dark .CodeMirror-gutters {
|
.cm-s-solarized.cm-s-dark .CodeMirror-gutters {
|
||||||
background-color: #002b36;
|
background-color: #073642;
|
||||||
border-color: #00232c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.cm-s-solarized.cm-s-dark .CodeMirror-linenumber {
|
.cm-s-solarized.cm-s-dark .CodeMirror-linenumber {
|
||||||
|
color: #586e75;
|
||||||
text-shadow: #021014 0 -1px;
|
text-shadow: #021014 0 -1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Light */
|
/* Light */
|
||||||
.cm-s-solarized.cm-s-light .CodeMirror-gutters {
|
.cm-s-solarized.cm-s-light .CodeMirror-gutters {
|
||||||
background-color: #fdf6e3;
|
background-color: #eee8d5;
|
||||||
border-color: #eee8d5;
|
}
|
||||||
|
|
||||||
|
.cm-s-solarized.cm-s-light .CodeMirror-linenumber {
|
||||||
|
color: #839496;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Common */
|
/* Common */
|
||||||
.cm-s-solarized .CodeMirror-linenumber {
|
.cm-s-solarized .CodeMirror-linenumber {
|
||||||
color: #586e75;
|
|
||||||
padding: 0 5px;
|
padding: 0 5px;
|
||||||
}
|
}
|
||||||
.cm-s-solarized .CodeMirror-guttermarker-subtle { color: #586e75; }
|
.cm-s-solarized .CodeMirror-guttermarker-subtle { color: #586e75; }
|
||||||
@ -149,15 +151,19 @@ http://ethanschoonover.com/solarized/img/solarized-palette.png
|
|||||||
color: #586e75;
|
color: #586e75;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Cursor */
|
||||||
.cm-s-solarized .CodeMirror-cursor { border-left: 1px solid #819090; }
|
.cm-s-solarized .CodeMirror-cursor { border-left: 1px solid #819090; }
|
||||||
|
|
||||||
/*
|
/* Fat cursor */
|
||||||
Active line. Negative margin compensates left padding of the text in the
|
.cm-s-solarized.cm-s-light.cm-fat-cursor .CodeMirror-cursor { background: #77ee77; }
|
||||||
view-port
|
.cm-s-solarized.cm-s-light .cm-animate-fat-cursor { background-color: #77ee77; }
|
||||||
*/
|
.cm-s-solarized.cm-s-dark.cm-fat-cursor .CodeMirror-cursor { background: #586e75; }
|
||||||
|
.cm-s-solarized.cm-s-dark .cm-animate-fat-cursor { background-color: #586e75; }
|
||||||
|
|
||||||
|
/* Active line */
|
||||||
.cm-s-solarized.cm-s-dark .CodeMirror-activeline-background {
|
.cm-s-solarized.cm-s-dark .CodeMirror-activeline-background {
|
||||||
background: rgba(255, 255, 255, 0.10);
|
background: rgba(255, 255, 255, 0.06);
|
||||||
}
|
}
|
||||||
.cm-s-solarized.cm-s-light .CodeMirror-activeline-background {
|
.cm-s-solarized.cm-s-light .CodeMirror-activeline-background {
|
||||||
background: rgba(0, 0, 0, 0.10);
|
background: rgba(0, 0, 0, 0.06);
|
||||||
}
|
}
|
169
src/lib/codemirror/theme/solarized light.css
vendored
Normal file
169
src/lib/codemirror/theme/solarized light.css
vendored
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
/*
|
||||||
|
Solarized theme for code-mirror
|
||||||
|
http://ethanschoonover.com/solarized
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Solarized color palette
|
||||||
|
http://ethanschoonover.com/solarized/img/solarized-palette.png
|
||||||
|
*/
|
||||||
|
|
||||||
|
.solarized.base03 { color: #002b36; }
|
||||||
|
.solarized.base02 { color: #073642; }
|
||||||
|
.solarized.base01 { color: #586e75; }
|
||||||
|
.solarized.base00 { color: #657b83; }
|
||||||
|
.solarized.base0 { color: #839496; }
|
||||||
|
.solarized.base1 { color: #93a1a1; }
|
||||||
|
.solarized.base2 { color: #eee8d5; }
|
||||||
|
.solarized.base3 { color: #fdf6e3; }
|
||||||
|
.solarized.solar-yellow { color: #b58900; }
|
||||||
|
.solarized.solar-orange { color: #cb4b16; }
|
||||||
|
.solarized.solar-red { color: #dc322f; }
|
||||||
|
.solarized.solar-magenta { color: #d33682; }
|
||||||
|
.solarized.solar-violet { color: #6c71c4; }
|
||||||
|
.solarized.solar-blue { color: #268bd2; }
|
||||||
|
.solarized.solar-cyan { color: #2aa198; }
|
||||||
|
.solarized.solar-green { color: #859900; }
|
||||||
|
|
||||||
|
/* Color scheme for code-mirror */
|
||||||
|
|
||||||
|
.cm-s-solarized {
|
||||||
|
line-height: 1.45em;
|
||||||
|
color-profile: sRGB;
|
||||||
|
rendering-intent: auto;
|
||||||
|
}
|
||||||
|
.cm-s-solarized.cm-s-dark {
|
||||||
|
color: #839496;
|
||||||
|
background-color: #002b36;
|
||||||
|
text-shadow: #002b36 0 1px;
|
||||||
|
}
|
||||||
|
.cm-s-solarized.cm-s-light {
|
||||||
|
background-color: #fdf6e3;
|
||||||
|
color: #657b83;
|
||||||
|
text-shadow: #eee8d5 0 1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-s-solarized .CodeMirror-widget {
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-s-solarized .cm-header { color: #586e75; }
|
||||||
|
.cm-s-solarized .cm-quote { color: #93a1a1; }
|
||||||
|
|
||||||
|
.cm-s-solarized .cm-keyword { color: #cb4b16; }
|
||||||
|
.cm-s-solarized .cm-atom { color: #d33682; }
|
||||||
|
.cm-s-solarized .cm-number { color: #d33682; }
|
||||||
|
.cm-s-solarized .cm-def { color: #2aa198; }
|
||||||
|
|
||||||
|
.cm-s-solarized .cm-variable { color: #839496; }
|
||||||
|
.cm-s-solarized .cm-variable-2 { color: #b58900; }
|
||||||
|
.cm-s-solarized .cm-variable-3 { color: #6c71c4; }
|
||||||
|
|
||||||
|
.cm-s-solarized .cm-property { color: #2aa198; }
|
||||||
|
.cm-s-solarized .cm-operator { color: #6c71c4; }
|
||||||
|
|
||||||
|
.cm-s-solarized .cm-comment { color: #586e75; font-style:italic; }
|
||||||
|
|
||||||
|
.cm-s-solarized .cm-string { color: #859900; }
|
||||||
|
.cm-s-solarized .cm-string-2 { color: #b58900; }
|
||||||
|
|
||||||
|
.cm-s-solarized .cm-meta { color: #859900; }
|
||||||
|
.cm-s-solarized .cm-qualifier { color: #b58900; }
|
||||||
|
.cm-s-solarized .cm-builtin { color: #d33682; }
|
||||||
|
.cm-s-solarized .cm-bracket { color: #cb4b16; }
|
||||||
|
.cm-s-solarized .CodeMirror-matchingbracket { color: #859900; }
|
||||||
|
.cm-s-solarized .CodeMirror-nonmatchingbracket { color: #dc322f; }
|
||||||
|
.cm-s-solarized .cm-tag { color: #93a1a1; }
|
||||||
|
.cm-s-solarized .cm-attribute { color: #2aa198; }
|
||||||
|
.cm-s-solarized .cm-hr {
|
||||||
|
color: transparent;
|
||||||
|
border-top: 1px solid #586e75;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.cm-s-solarized .cm-link { color: #93a1a1; cursor: pointer; }
|
||||||
|
.cm-s-solarized .cm-special { color: #6c71c4; }
|
||||||
|
.cm-s-solarized .cm-em {
|
||||||
|
color: #999;
|
||||||
|
text-decoration: underline;
|
||||||
|
text-decoration-style: dotted;
|
||||||
|
}
|
||||||
|
.cm-s-solarized .cm-strong { color: #eee; }
|
||||||
|
.cm-s-solarized .cm-error,
|
||||||
|
.cm-s-solarized .cm-invalidchar {
|
||||||
|
color: #586e75;
|
||||||
|
border-bottom: 1px dotted #dc322f;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-s-solarized.cm-s-dark div.CodeMirror-selected { background: #073642; }
|
||||||
|
.cm-s-solarized.cm-s-dark.CodeMirror ::selection { background: rgba(7, 54, 66, 0.99); }
|
||||||
|
.cm-s-solarized.cm-s-dark .CodeMirror-line::-moz-selection, .cm-s-dark .CodeMirror-line > span::-moz-selection, .cm-s-dark .CodeMirror-line > span > span::-moz-selection { background: rgba(7, 54, 66, 0.99); }
|
||||||
|
|
||||||
|
.cm-s-solarized.cm-s-light div.CodeMirror-selected { background: #eee8d5; }
|
||||||
|
.cm-s-solarized.cm-s-light .CodeMirror-line::selection, .cm-s-light .CodeMirror-line > span::selection, .cm-s-light .CodeMirror-line > span > span::selection { background: #eee8d5; }
|
||||||
|
.cm-s-solarized.cm-s-light .CodeMirror-line::-moz-selection, .cm-s-ligh .CodeMirror-line > span::-moz-selection, .cm-s-ligh .CodeMirror-line > span > span::-moz-selection { background: #eee8d5; }
|
||||||
|
|
||||||
|
/* Editor styling */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Little shadow on the view-port of the buffer view */
|
||||||
|
.cm-s-solarized.CodeMirror {
|
||||||
|
-moz-box-shadow: inset 7px 0 12px -6px #000;
|
||||||
|
-webkit-box-shadow: inset 7px 0 12px -6px #000;
|
||||||
|
box-shadow: inset 7px 0 12px -6px #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove gutter border */
|
||||||
|
.cm-s-solarized .CodeMirror-gutters {
|
||||||
|
border-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Gutter colors and line number styling based of color scheme (dark / light) */
|
||||||
|
|
||||||
|
/* Dark */
|
||||||
|
.cm-s-solarized.cm-s-dark .CodeMirror-gutters {
|
||||||
|
background-color: #073642;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-s-solarized.cm-s-dark .CodeMirror-linenumber {
|
||||||
|
color: #586e75;
|
||||||
|
text-shadow: #021014 0 -1px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Light */
|
||||||
|
.cm-s-solarized.cm-s-light .CodeMirror-gutters {
|
||||||
|
background-color: #eee8d5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-s-solarized.cm-s-light .CodeMirror-linenumber {
|
||||||
|
color: #839496;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Common */
|
||||||
|
.cm-s-solarized .CodeMirror-linenumber {
|
||||||
|
padding: 0 5px;
|
||||||
|
}
|
||||||
|
.cm-s-solarized .CodeMirror-guttermarker-subtle { color: #586e75; }
|
||||||
|
.cm-s-solarized.cm-s-dark .CodeMirror-guttermarker { color: #ddd; }
|
||||||
|
.cm-s-solarized.cm-s-light .CodeMirror-guttermarker { color: #cb4b16; }
|
||||||
|
|
||||||
|
.cm-s-solarized .CodeMirror-gutter .CodeMirror-gutter-text {
|
||||||
|
color: #586e75;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cursor */
|
||||||
|
.cm-s-solarized .CodeMirror-cursor { border-left: 1px solid #819090; }
|
||||||
|
|
||||||
|
/* Fat cursor */
|
||||||
|
.cm-s-solarized.cm-s-light.cm-fat-cursor .CodeMirror-cursor { background: #77ee77; }
|
||||||
|
.cm-s-solarized.cm-s-light .cm-animate-fat-cursor { background-color: #77ee77; }
|
||||||
|
.cm-s-solarized.cm-s-dark.cm-fat-cursor .CodeMirror-cursor { background: #586e75; }
|
||||||
|
.cm-s-solarized.cm-s-dark .cm-animate-fat-cursor { background-color: #586e75; }
|
||||||
|
|
||||||
|
/* Active line */
|
||||||
|
.cm-s-solarized.cm-s-dark .CodeMirror-activeline-background {
|
||||||
|
background: rgba(255, 255, 255, 0.06);
|
||||||
|
}
|
||||||
|
.cm-s-solarized.cm-s-light .CodeMirror-activeline-background {
|
||||||
|
background: rgba(0, 0, 0, 0.06);
|
||||||
|
}
|
@ -10,7 +10,7 @@
|
|||||||
"<all_urls>",
|
"<all_urls>",
|
||||||
"downloads"
|
"downloads"
|
||||||
],
|
],
|
||||||
"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'",
|
"content_security_policy": "script-src 'self' filesystem: http://localhost:* https://localhost:* https://ajax.googleapis.com https://code.jquery.com https://cdnjs.cloudflare.com https://unpkg.com https://maxcdn.com https://cdn77.com https://maxcdn.bootstrapcdn.com https://cdn.jsdelivr.net/ https://www.google-analytics.com 'unsafe-eval'; object-src 'self'",
|
||||||
"options_ui": {
|
"options_ui": {
|
||||||
"page": "options.html",
|
"page": "options.html",
|
||||||
"chrome_style": true
|
"chrome_style": true
|
||||||
|
492
src/script.js
492
src/script.js
@ -2,9 +2,9 @@
|
|||||||
/* global layoutBtn1, layoutBtn2, layoutBtn3, helpModal, notificationsModal, addLibraryModal,
|
/* global layoutBtn1, layoutBtn2, layoutBtn3, helpModal, notificationsModal, addLibraryModal,
|
||||||
onboardModal, layoutBtn1, layoutBtn2, layoutBtn3, layoutBtn4, helpBtn, onboardModal, onboardModal,
|
onboardModal, layoutBtn1, layoutBtn2, layoutBtn3, layoutBtn4, helpBtn, onboardModal, onboardModal,
|
||||||
addLibraryModal, addLibraryModal, notificationsBtn, notificationsModal, notificationsModal,
|
addLibraryModal, addLibraryModal, notificationsBtn, notificationsModal, notificationsModal,
|
||||||
notificationsModal, notificationsBtn, codepenBtn, saveHtmlBtn, openBtn, saveBtn, newBtn,
|
notificationsModal, notificationsBtn, codepenBtn, saveHtmlBtn, saveBtn, settingsBtn,
|
||||||
settingsBtn, onboardModal, notificationsBtn, onboardShowInTabOptionBtn, onboardDontShowInTabOptionBtn
|
onboardModal, settingsModal, notificationsBtn, onboardShowInTabOptionBtn, editorThemeLinkTag,
|
||||||
TextareaAutoComplete */
|
onboardDontShowInTabOptionBtn, TextareaAutoComplete, savedItemCountEl */
|
||||||
/* eslint-disable no-extra-semi */
|
/* eslint-disable no-extra-semi */
|
||||||
;(function (alertsService) {
|
;(function (alertsService) {
|
||||||
|
|
||||||
@ -37,7 +37,7 @@ TextareaAutoComplete */
|
|||||||
var modes = {};
|
var modes = {};
|
||||||
modes[HtmlModes.HTML] = { label: 'HTML', cmMode: 'htmlmixed', codepenVal: 'none' };
|
modes[HtmlModes.HTML] = { label: 'HTML', cmMode: 'htmlmixed', codepenVal: 'none' };
|
||||||
modes[HtmlModes.MARKDOWN] = { label: 'Markdown', cmMode: 'markdown', codepenVal: 'markdown' };
|
modes[HtmlModes.MARKDOWN] = { label: 'Markdown', cmMode: 'markdown', codepenVal: 'markdown' };
|
||||||
modes[HtmlModes.JADE] = { label: 'Jade', cmMode: 'jade', codepenVal: 'jade' };
|
modes[HtmlModes.JADE] = { label: 'Pug', cmMode: 'pug', codepenVal: 'pug' };
|
||||||
modes[JsModes.JS] = { label: 'JS', cmMode: 'javascript', codepenVal: 'none' };
|
modes[JsModes.JS] = { label: 'JS', cmMode: 'javascript', codepenVal: 'none' };
|
||||||
modes[JsModes.COFFEESCRIPT] = { label: 'CoffeeScript', cmMode: 'coffeescript', codepenVal: 'coffeescript' };
|
modes[JsModes.COFFEESCRIPT] = { label: 'CoffeeScript', cmMode: 'coffeescript', codepenVal: 'coffeescript' };
|
||||||
modes[JsModes.ES6] = { label: 'ES6 (Babel)', cmMode: 'jsx', codepenVal: 'babel' };
|
modes[JsModes.ES6] = { label: 'ES6 (Babel)', cmMode: 'jsx', codepenVal: 'babel' };
|
||||||
@ -50,6 +50,7 @@ TextareaAutoComplete */
|
|||||||
|
|
||||||
var updateTimer
|
var updateTimer
|
||||||
, updateDelay = 500
|
, updateDelay = 500
|
||||||
|
, unsavedEditWarningCount = 15
|
||||||
, currentLayoutMode
|
, currentLayoutMode
|
||||||
, hasSeenNotifications = true
|
, hasSeenNotifications = true
|
||||||
, htmlMode = HtmlModes.HTML
|
, htmlMode = HtmlModes.HTML
|
||||||
@ -57,11 +58,11 @@ TextareaAutoComplete */
|
|||||||
, cssMode = CssModes.CSS
|
, cssMode = CssModes.CSS
|
||||||
, sass
|
, sass
|
||||||
, currentItem
|
, currentItem
|
||||||
|
, unsavedEditCount
|
||||||
, savedItems
|
, savedItems
|
||||||
, minCodeWrapSize = 33
|
, minCodeWrapSize = 33
|
||||||
, mainSplitInstance
|
, mainSplitInstance
|
||||||
, codeSplitInstance
|
, codeSplitInstance
|
||||||
// TODO: for legacy reasons when. Will be refactored as global preferences.
|
|
||||||
, prefs = {}
|
, prefs = {}
|
||||||
, codeInPreview = { html: null, css: null, js: null }
|
, codeInPreview = { html: null, css: null, js: null }
|
||||||
, isSavedItemsPaneOpen = false
|
, isSavedItemsPaneOpen = false
|
||||||
@ -149,7 +150,6 @@ TextareaAutoComplete */
|
|||||||
} else {
|
} else {
|
||||||
options.sizes = [ 33.33, 33.33, 33.33 ];
|
options.sizes = [ 33.33, 33.33, 33.33 ];
|
||||||
}
|
}
|
||||||
utils.log('reset splitting', currentItem);
|
|
||||||
|
|
||||||
codeSplitInstance = Split(['#js-html-code', '#js-css-code', '#js-js-code'], options);
|
codeSplitInstance = Split(['#js-html-code', '#js-css-code', '#js-js-code'], options);
|
||||||
mainSplitInstance = Split(['#js-code-side', '#js-demo-side' ], {
|
mainSplitInstance = Split(['#js-code-side', '#js-demo-side' ], {
|
||||||
@ -294,6 +294,8 @@ TextareaAutoComplete */
|
|||||||
utils.log('saving key', key || currentItem.id, currentItem)
|
utils.log('saving key', key || currentItem.id, currentItem)
|
||||||
saveSetting(key || currentItem.id, currentItem, function () {
|
saveSetting(key || currentItem.id, currentItem, function () {
|
||||||
alertsService.add('Item saved.');
|
alertsService.add('Item saved.');
|
||||||
|
unsavedEditCount = 0;
|
||||||
|
saveBtn.classList.remove('is-marked');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -309,8 +311,11 @@ TextareaAutoComplete */
|
|||||||
+ '<a class="js-saved-item-tile__close-btn saved-item-tile__close-btn hint--left" aria-label="Remove">X</a>'
|
+ '<a class="js-saved-item-tile__close-btn saved-item-tile__close-btn hint--left" aria-label="Remove">X</a>'
|
||||||
+ '<h3 class="saved-item-tile__title">' + item.title + '</h3><span class="saved-item-tile__meta">Last updated: ' + utils.getHumanDate(item.updatedOn) + '</span></div>';
|
+ '<h3 class="saved-item-tile__title">' + item.title + '</h3><span class="saved-item-tile__meta">Last updated: ' + utils.getHumanDate(item.updatedOn) + '</span></div>';
|
||||||
});
|
});
|
||||||
|
savedItemCountEl.textContent = '(' + items.length + ')';
|
||||||
|
savedItemCountEl.style.display = 'inline';
|
||||||
} else {
|
} else {
|
||||||
html += '<h2 class="opacity--30">Nothing saved here.</h2>';
|
html += '<h2 class="opacity--30">Nothing saved here.</h2>';
|
||||||
|
savedItemCountEl.style.display = 'none';
|
||||||
}
|
}
|
||||||
savedItemsPane.querySelector('#js-saved-items-wrap').innerHTML = html;
|
savedItemsPane.querySelector('#js-saved-items-wrap').innerHTML = html;
|
||||||
toggleSavedItemsPane();
|
toggleSavedItemsPane();
|
||||||
@ -327,13 +332,19 @@ TextareaAutoComplete */
|
|||||||
isSavedItemsPaneOpen = savedItemsPane.classList.contains('is-open');
|
isSavedItemsPaneOpen = savedItemsPane.classList.contains('is-open');
|
||||||
document.body.classList[isSavedItemsPaneOpen ? 'add' : 'remove']('overlay-visible');
|
document.body.classList[isSavedItemsPaneOpen ? 'add' : 'remove']('overlay-visible');
|
||||||
}
|
}
|
||||||
function openSavedItemsPane() {
|
|
||||||
|
/**
|
||||||
|
* Fetches all items from storage
|
||||||
|
* @param {boolean} shouldSaveGlobally Whether to store the fetched items in global arr for later use.
|
||||||
|
* @return {promise} Promise.
|
||||||
|
*/
|
||||||
|
function fetchItems(shouldSaveGlobally) {
|
||||||
|
var d = deferred();
|
||||||
chrome.storage.local.get('items', function (result) {
|
chrome.storage.local.get('items', function (result) {
|
||||||
var itemIds = Object.getOwnPropertyNames(result.items || {}),
|
var itemIds = Object.getOwnPropertyNames(result.items || {}),
|
||||||
items = [];
|
items = [];
|
||||||
if (!itemIds.length) {
|
if (!itemIds.length) {
|
||||||
populateItemsInSavedPane([]);
|
d.resolve([]);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
savedItems = savedItems || [];
|
savedItems = savedItems || [];
|
||||||
@ -342,35 +353,48 @@ TextareaAutoComplete */
|
|||||||
|
|
||||||
/* eslint-disable no-loop-func */
|
/* eslint-disable no-loop-func */
|
||||||
chrome.storage.local.get(itemIds[i], function (itemResult) {
|
chrome.storage.local.get(itemIds[i], function (itemResult) {
|
||||||
savedItems[itemIds[i]] = itemResult[itemIds[i]];
|
if (shouldSaveGlobally) {
|
||||||
|
savedItems[itemIds[i]] = itemResult[itemIds[i]];
|
||||||
|
}
|
||||||
items.push(itemResult[itemIds[i]]);
|
items.push(itemResult[itemIds[i]]);
|
||||||
// Check if we have all items now.
|
// Check if we have all items now.
|
||||||
if (itemIds.length === items.length) {
|
if (itemIds.length === items.length) {
|
||||||
populateItemsInSavedPane(items);
|
d.resolve(items)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/* eslint-enable no-loop-func */
|
/* eslint-enable no-loop-func */
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
return d.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openSavedItemsPane() {
|
||||||
|
fetchItems(true).then(function (items) {
|
||||||
|
populateItemsInSavedPane(items);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function setCurrentItem(item) {
|
||||||
|
currentItem = item;
|
||||||
|
// Reset unsaved count, in UI also.
|
||||||
|
unsavedEditCount = 0;
|
||||||
|
saveBtn.classList.remove('is-marked');
|
||||||
|
}
|
||||||
function createNewItem() {
|
function createNewItem() {
|
||||||
var d = new Date();
|
var d = new Date();
|
||||||
currentItem = {
|
setCurrentItem({
|
||||||
title: 'Untitled ' + d.getDate() + '-' + (d.getMonth() + 1) + '-' + d.getHours() + ':' + d.getMinutes(),
|
title: 'Untitled ' + d.getDate() + '-' + (d.getMonth() + 1) + '-' + d.getHours() + ':' + d.getMinutes(),
|
||||||
html: '',
|
html: '',
|
||||||
css: '',
|
css: '',
|
||||||
js: '',
|
js: '',
|
||||||
externalLibs: { js: '', css: '' },
|
externalLibs: { js: '', css: '' },
|
||||||
layoutMode: currentLayoutMode
|
layoutMode: currentLayoutMode
|
||||||
};
|
});
|
||||||
alertsService.add('New item created');
|
|
||||||
refreshEditor();
|
refreshEditor();
|
||||||
|
alertsService.add('New item created');
|
||||||
}
|
}
|
||||||
function openItem(itemId) {
|
function openItem(itemId) {
|
||||||
currentItem = savedItems[itemId];
|
setCurrentItem(savedItems[itemId]);
|
||||||
// codeSplitInstance.setSizes([ 33.3, 33.3, 33.3 ]);
|
|
||||||
refreshEditor();
|
refreshEditor();
|
||||||
alertsService.add('Saved item loaded');
|
alertsService.add('Saved item loaded');
|
||||||
}
|
}
|
||||||
@ -398,6 +422,9 @@ TextareaAutoComplete */
|
|||||||
createNewItem();
|
createNewItem();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// Remove from cached list
|
||||||
|
delete savedItems[itemId];
|
||||||
|
|
||||||
trackEvent('fn', 'itemRemoved');
|
trackEvent('fn', 'itemRemoved');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -405,7 +432,13 @@ TextareaAutoComplete */
|
|||||||
titleInput.value = currentItem.title || 'Untitled';
|
titleInput.value = currentItem.title || 'Untitled';
|
||||||
externalJsTextarea.value = (currentItem.externalLibs && currentItem.externalLibs.js) || '';
|
externalJsTextarea.value = (currentItem.externalLibs && currentItem.externalLibs.js) || '';
|
||||||
externalCssTextarea.value = (currentItem.externalLibs && currentItem.externalLibs.css) || '';
|
externalCssTextarea.value = (currentItem.externalLibs && currentItem.externalLibs.css) || '';
|
||||||
externalJsTextarea.dispatchEvent(new Event('change'));
|
|
||||||
|
utils.log('refresh editor')
|
||||||
|
// Set the modes manually here, so that the preview refresh triggered by the `setValue`
|
||||||
|
// statements below, operate on correct modes.
|
||||||
|
htmlMode = currentItem.htmlMode || prefs.htmlMode || HtmlModes.HTML;
|
||||||
|
cssMode = currentItem.cssMode || prefs.cssMode || CssModes.CSS;
|
||||||
|
jsMode = currentItem.jsMode || prefs.jsMode || JsModes.JS;
|
||||||
|
|
||||||
scope.cm.html.setValue(currentItem.html);
|
scope.cm.html.setValue(currentItem.html);
|
||||||
scope.cm.css.setValue(currentItem.css);
|
scope.cm.css.setValue(currentItem.css);
|
||||||
@ -414,9 +447,16 @@ TextareaAutoComplete */
|
|||||||
scope.cm.css.refresh();
|
scope.cm.css.refresh();
|
||||||
scope.cm.js.refresh();
|
scope.cm.js.refresh();
|
||||||
|
|
||||||
updateHtmlMode(currentItem.htmlMode || prefs.htmlMode || HtmlModes.HTML);
|
// To have the library count updated
|
||||||
updateJsMode(currentItem.jsMode || prefs.jsMode || JsModes.JS);
|
updateExternalLibUi();
|
||||||
updateCssMode(currentItem.cssMode || prefs.cssMode || CssModes.CSS);
|
|
||||||
|
// Set preview only when all modes are updated so that preview doesn't generate on partially
|
||||||
|
// correct modes and also doesn't happen 3 times.
|
||||||
|
Promise.all([
|
||||||
|
updateHtmlMode(htmlMode),
|
||||||
|
updateCssMode(cssMode),
|
||||||
|
updateJsMode(jsMode)
|
||||||
|
]).then(() => scope.setPreviewContent(true));
|
||||||
|
|
||||||
toggleLayout(currentItem.layoutMode || prefs.layoutMode);
|
toggleLayout(currentItem.layoutMode || prefs.layoutMode);
|
||||||
}
|
}
|
||||||
@ -426,6 +466,7 @@ TextareaAutoComplete */
|
|||||||
notificationsModal.classList.remove('is-modal-visible');
|
notificationsModal.classList.remove('is-modal-visible');
|
||||||
addLibraryModal.classList.remove('is-modal-visible');
|
addLibraryModal.classList.remove('is-modal-visible');
|
||||||
onboardModal.classList.remove('is-modal-visible');
|
onboardModal.classList.remove('is-modal-visible');
|
||||||
|
settingsModal.classList.remove('is-modal-visible');
|
||||||
toggleSavedItemsPane(false);
|
toggleSavedItemsPane(false);
|
||||||
document.dispatchEvent(new Event('overlaysClosed'));
|
document.dispatchEvent(new Event('overlaysClosed'));
|
||||||
}
|
}
|
||||||
@ -435,10 +476,15 @@ TextareaAutoComplete */
|
|||||||
*/
|
*/
|
||||||
function handleModeRequirements(mode) {
|
function handleModeRequirements(mode) {
|
||||||
// Exit if already loaded
|
// Exit if already loaded
|
||||||
if (modes[mode].hasLoaded) { return; }
|
var d = deferred();
|
||||||
|
if (modes[mode].hasLoaded) {
|
||||||
|
d.resolve();
|
||||||
|
return d.promise;
|
||||||
|
}
|
||||||
|
|
||||||
function setLoadedFlag() {
|
function setLoadedFlag() {
|
||||||
modes[mode].hasLoaded = true;
|
modes[mode].hasLoaded = true;
|
||||||
|
d.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode === HtmlModes.JADE) {
|
if (mode === HtmlModes.JADE) {
|
||||||
@ -460,35 +506,33 @@ TextareaAutoComplete */
|
|||||||
loadJS('lib/babel.min.js').then(setLoadedFlag);
|
loadJS('lib/babel.min.js').then(setLoadedFlag);
|
||||||
} else if (mode === JsModes.TS) {
|
} else if (mode === JsModes.TS) {
|
||||||
loadJS('lib/typescript.js').then(setLoadedFlag);
|
loadJS('lib/typescript.js').then(setLoadedFlag);
|
||||||
|
} else {
|
||||||
|
d.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return d.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateHtmlMode(value) {
|
function updateHtmlMode(value) {
|
||||||
htmlMode = value;
|
htmlMode = value;
|
||||||
htmlModelLabel.textContent = modes[value].label;
|
htmlModelLabel.textContent = modes[value].label;
|
||||||
handleModeRequirements(value);
|
|
||||||
scope.cm.html.setOption('mode', modes[value].cmMode);
|
scope.cm.html.setOption('mode', modes[value].cmMode);
|
||||||
CodeMirror.autoLoadMode(scope.cm.html, modes[value].cmPath || modes[value].cmMode);
|
CodeMirror.autoLoadMode(scope.cm.html, modes[value].cmPath || modes[value].cmMode);
|
||||||
|
return handleModeRequirements(value);
|
||||||
}
|
}
|
||||||
function updateCssMode(value) {
|
function updateCssMode(value) {
|
||||||
cssMode = value;
|
cssMode = value;
|
||||||
cssModelLabel.textContent = modes[value].label;
|
cssModelLabel.textContent = modes[value].label;
|
||||||
handleModeRequirements(value);
|
|
||||||
scope.cm.css.setOption('mode', modes[value].cmMode);
|
scope.cm.css.setOption('mode', modes[value].cmMode);
|
||||||
CodeMirror.autoLoadMode(scope.cm.css, modes[value].cmPath || modes[value].cmMode);
|
CodeMirror.autoLoadMode(scope.cm.css, modes[value].cmPath || modes[value].cmMode);
|
||||||
|
return handleModeRequirements(value);
|
||||||
}
|
}
|
||||||
function updateJsMode(value) {
|
function updateJsMode(value) {
|
||||||
jsMode = value;
|
jsMode = value;
|
||||||
jsModelLabel.textContent = modes[value].label;
|
jsModelLabel.textContent = modes[value].label;
|
||||||
handleModeRequirements(value);
|
|
||||||
scope.cm.js.setOption('mode', modes[value].cmMode);
|
scope.cm.js.setOption('mode', modes[value].cmMode);
|
||||||
CodeMirror.autoLoadMode(scope.cm.js, modes[value].cmPath || modes[value].cmMode);
|
CodeMirror.autoLoadMode(scope.cm.js, modes[value].cmPath || modes[value].cmMode);
|
||||||
// FIXME: Will be saved as part of scope settings
|
return handleModeRequirements(value);
|
||||||
/*
|
|
||||||
chrome.storage.sync.set({
|
|
||||||
jsMode: value
|
|
||||||
}, function () {});
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// computeHtml, computeCss & computeJs evaluate the final code according
|
// computeHtml, computeCss & computeJs evaluate the final code according
|
||||||
@ -499,9 +543,9 @@ TextareaAutoComplete */
|
|||||||
if (htmlMode === HtmlModes.HTML) {
|
if (htmlMode === HtmlModes.HTML) {
|
||||||
d.resolve(code);
|
d.resolve(code);
|
||||||
} else if (htmlMode === HtmlModes.MARKDOWN) {
|
} else if (htmlMode === HtmlModes.MARKDOWN) {
|
||||||
d.resolve(marked(code));
|
d.resolve(marked ? marked(code) : code);
|
||||||
} else if (htmlMode === HtmlModes.JADE) {
|
} else if (htmlMode === HtmlModes.JADE) {
|
||||||
d.resolve(jade.render(code));
|
d.resolve(window.jade ? jade.render(code) : code);
|
||||||
}
|
}
|
||||||
|
|
||||||
return d.promise;
|
return d.promise;
|
||||||
@ -514,13 +558,17 @@ TextareaAutoComplete */
|
|||||||
if (cssMode === CssModes.CSS) {
|
if (cssMode === CssModes.CSS) {
|
||||||
d.resolve(code);
|
d.resolve(code);
|
||||||
} else if (cssMode === CssModes.SCSS || cssMode === CssModes.SASS) {
|
} else if (cssMode === CssModes.SCSS || cssMode === CssModes.SASS) {
|
||||||
sass.compile(code, { indentedSyntax: cssMode === CssModes.SASS }, function(result) {
|
if (sass && code) {
|
||||||
// Something was wrong
|
sass.compile(code, { indentedSyntax: cssMode === CssModes.SASS }, function(result) {
|
||||||
if (result.line && result.message) {
|
// Something was wrong
|
||||||
showErrors('css', [ { lineNumber: result.line - 1, message: result.message } ]);
|
if (result.line && result.message) {
|
||||||
}
|
showErrors('css', [ { lineNumber: result.line - 1, message: result.message } ]);
|
||||||
d.resolve(result.text);
|
}
|
||||||
});
|
d.resolve(result.text);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
d.resolve(code);
|
||||||
|
}
|
||||||
} else if (cssMode === CssModes.LESS) {
|
} else if (cssMode === CssModes.LESS) {
|
||||||
less.render(code).then(function (result) {
|
less.render(code).then(function (result) {
|
||||||
d.resolve(result.css);
|
d.resolve(result.css);
|
||||||
@ -547,6 +595,10 @@ TextareaAutoComplete */
|
|||||||
var code = scope.cm.js.getValue();
|
var code = scope.cm.js.getValue();
|
||||||
|
|
||||||
cleanupErrors('js');
|
cleanupErrors('js');
|
||||||
|
if (!code) {
|
||||||
|
d.resolve('');
|
||||||
|
return d.promise;
|
||||||
|
}
|
||||||
var ast;
|
var ast;
|
||||||
|
|
||||||
if (jsMode === JsModes.JS) {
|
if (jsMode === JsModes.JS) {
|
||||||
@ -564,6 +616,10 @@ TextareaAutoComplete */
|
|||||||
}
|
}
|
||||||
} else if (jsMode === JsModes.COFFEESCRIPT) {
|
} else if (jsMode === JsModes.COFFEESCRIPT) {
|
||||||
var coffeeCode;
|
var coffeeCode;
|
||||||
|
if (!window.CoffeeScript) {
|
||||||
|
d.resolve('');
|
||||||
|
return d.promise;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
coffeeCode = CoffeeScript.compile(code, { bare: true });
|
coffeeCode = CoffeeScript.compile(code, { bare: true });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
@ -578,6 +634,10 @@ TextareaAutoComplete */
|
|||||||
d.resolve(escodegen.generate(ast));
|
d.resolve(escodegen.generate(ast));
|
||||||
}
|
}
|
||||||
} else if (jsMode === JsModes.ES6) {
|
} else if (jsMode === JsModes.ES6) {
|
||||||
|
if (!window.Babel) {
|
||||||
|
d.resolve('');
|
||||||
|
return d.promise;
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
ast = esprima.parse(code, {
|
ast = esprima.parse(code, {
|
||||||
tolerant: true,
|
tolerant: true,
|
||||||
@ -607,6 +667,10 @@ TextareaAutoComplete */
|
|||||||
}
|
}
|
||||||
} else if (jsMode === JsModes.TS) {
|
} else if (jsMode === JsModes.TS) {
|
||||||
try {
|
try {
|
||||||
|
if (!window.ts) {
|
||||||
|
d.resolve('');
|
||||||
|
return d.promise;
|
||||||
|
}
|
||||||
code = ts.transpileModule(code, { reportDiagnostics: true, compilerOptions: { noEmitOnError: true, diagnostics: true, module: ts.ModuleKind.ES2015 } });
|
code = ts.transpileModule(code, { reportDiagnostics: true, compilerOptions: { noEmitOnError: true, diagnostics: true, module: ts.ModuleKind.ES2015 } });
|
||||||
if (code.diagnostics.length) {
|
if (code.diagnostics.length) {
|
||||||
|
|
||||||
@ -684,11 +748,13 @@ TextareaAutoComplete */
|
|||||||
var fileWritten = false;
|
var fileWritten = false;
|
||||||
function errorHandler() { utils.log(arguments); }
|
function errorHandler() { utils.log(arguments); }
|
||||||
|
|
||||||
|
// utils.log('writing file ', name);
|
||||||
window.webkitRequestFileSystem(window.TEMPORARY, 1024 * 1024 * 5, function(fs){
|
window.webkitRequestFileSystem(window.TEMPORARY, 1024 * 1024 * 5, function(fs){
|
||||||
fs.root.getFile(name, { create: true }, function(fileEntry) {
|
fs.root.getFile(name, { create: true }, function(fileEntry) {
|
||||||
fileEntry.createWriter(function(fileWriter) {
|
fileEntry.createWriter(function(fileWriter) {
|
||||||
function onWriteComplete() {
|
function onWriteComplete() {
|
||||||
if (fileWritten) {
|
if (fileWritten) {
|
||||||
|
// utils.log('file written ', name);
|
||||||
return cb();
|
return cb();
|
||||||
}
|
}
|
||||||
fileWritten = true;
|
fileWritten = true;
|
||||||
@ -699,7 +765,9 @@ TextareaAutoComplete */
|
|||||||
}
|
}
|
||||||
fileWriter.onwriteend = onWriteComplete;
|
fileWriter.onwriteend = onWriteComplete;
|
||||||
// Empty the file contents
|
// Empty the file contents
|
||||||
fileWriter.truncate(0)
|
fileWriter.truncate(0);
|
||||||
|
// utils.log('truncating file ', name);
|
||||||
|
|
||||||
}, errorHandler);
|
}, errorHandler);
|
||||||
}, errorHandler);
|
}, errorHandler);
|
||||||
}, errorHandler);
|
}, errorHandler);
|
||||||
@ -716,11 +784,6 @@ TextareaAutoComplete */
|
|||||||
trackEvent('fn', 'hasCode');
|
trackEvent('fn', 'hasCode');
|
||||||
trackEvent.hasTrackedCode = true;
|
trackEvent.hasTrackedCode = true;
|
||||||
}
|
}
|
||||||
// Track when people actually are working.
|
|
||||||
trackEvent.previewCount = (trackEvent.previewCount || 0) + 1;
|
|
||||||
if (trackEvent.previewCount === 4) {
|
|
||||||
trackEvent('fn', 'usingPreview');
|
|
||||||
}
|
|
||||||
|
|
||||||
// we need to store user script in external JS file to prevent inline-script
|
// we need to store user script in external JS file to prevent inline-script
|
||||||
// CSP from affecting it.
|
// CSP from affecting it.
|
||||||
@ -730,8 +793,6 @@ TextareaAutoComplete */
|
|||||||
+ chrome.i18n.getMessage('@@extension_id') + '/temporary/' + 'preview.html';
|
+ chrome.i18n.getMessage('@@extension_id') + '/temporary/' + 'preview.html';
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.setPreviewContent = function (isForced) {
|
scope.setPreviewContent = function (isForced) {
|
||||||
@ -740,11 +801,14 @@ TextareaAutoComplete */
|
|||||||
css: scope.cm.css.getValue(),
|
css: scope.cm.css.getValue(),
|
||||||
js: scope.cm.js.getValue()
|
js: scope.cm.js.getValue()
|
||||||
};
|
};
|
||||||
|
utils.log('🔎 setPreviewContent', isForced)
|
||||||
// If just CSS was changed (and everything shudn't be empty),
|
// If just CSS was changed (and everything shudn't be empty),
|
||||||
// change the styles inside the iframe.
|
// change the styles inside the iframe.
|
||||||
if (!isForced && currentCode.html === codeInPreview.html && currentCode.js === codeInPreview.js) {
|
if (!isForced && currentCode.html === codeInPreview.html && currentCode.js === codeInPreview.js) {
|
||||||
computeCss().then(function (css) {
|
computeCss().then(function (css) {
|
||||||
frame.contentDocument.querySelector('#webmakerstyle').textContent = css;
|
if (frame.contentDocument.querySelector('#webmakerstyle')) {
|
||||||
|
frame.contentDocument.querySelector('#webmakerstyle').textContent = css;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
var htmlPromise = computeHtml();
|
var htmlPromise = computeHtml();
|
||||||
@ -754,6 +818,7 @@ TextareaAutoComplete */
|
|||||||
createPreviewFile(result[0], result[1], result[2]);
|
createPreviewFile(result[0], result[1], result[2]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
codeInPreview.html = currentCode.html;
|
codeInPreview.html = currentCode.html;
|
||||||
codeInPreview.css = currentCode.css;
|
codeInPreview.css = currentCode.css;
|
||||||
codeInPreview.js = currentCode.js;
|
codeInPreview.js = currentCode.js;
|
||||||
@ -771,7 +836,7 @@ TextareaAutoComplete */
|
|||||||
var fileContent = getCompleteHtml(html, css, js);
|
var fileContent = getCompleteHtml(html, css, js);
|
||||||
|
|
||||||
var d = new Date();
|
var d = new Date();
|
||||||
var fileName = [ 'web-maker', d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds() ].join('-');
|
var fileName = [ 'web-maker', d.getFullYear(), (d.getMonth() + 1), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds() ].join('-');
|
||||||
fileName += '.html';
|
fileName += '.html';
|
||||||
|
|
||||||
if (currentItem.title) {
|
if (currentItem.title) {
|
||||||
@ -803,6 +868,7 @@ TextareaAutoComplete */
|
|||||||
keyMap: 'sublime',
|
keyMap: 'sublime',
|
||||||
theme: 'monokai',
|
theme: 'monokai',
|
||||||
lint: !!options.lint,
|
lint: !!options.lint,
|
||||||
|
tabSize: 2,
|
||||||
foldGutter: true,
|
foldGutter: true,
|
||||||
styleActiveLine: true,
|
styleActiveLine: true,
|
||||||
gutters: options.gutters || [],
|
gutters: options.gutters || [],
|
||||||
@ -820,13 +886,46 @@ TextareaAutoComplete */
|
|||||||
},
|
},
|
||||||
'Shift-Tab': function(editor) {
|
'Shift-Tab': function(editor) {
|
||||||
CodeMirror.commands.indentAuto(editor);
|
CodeMirror.commands.indentAuto(editor);
|
||||||
|
},
|
||||||
|
'Tab': function(editor) {
|
||||||
|
var input = $('[data-setting=indentWith]:checked');
|
||||||
|
if (!editor.somethingSelected() && (!input || input.value === 'spaces')) {
|
||||||
|
// softtabs adds spaces. This is required because by default tab key will put tab, but we want
|
||||||
|
// to indent with spaces if `spaces` is preferred mode of indentation.
|
||||||
|
// `somethingSelected` needs to be checked otherwise, all selected code is replaced with softtab.
|
||||||
|
CodeMirror.commands.insertSoftTab(editor);
|
||||||
|
} else {
|
||||||
|
CodeMirror.commands.defaultTab(editor);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
cm.on('change', function onChange() {
|
cm.on('change', function onChange(editor, change) {
|
||||||
clearTimeout(updateTimer);
|
clearTimeout(updateTimer);
|
||||||
|
|
||||||
updateTimer = setTimeout(function () {
|
updateTimer = setTimeout(function () {
|
||||||
scope.setPreviewContent();
|
// This is done so that multiple simultaneous setValue don't trigger too many preview refreshes
|
||||||
|
// and in turn too many file writes on a single file (eg. preview.html).
|
||||||
|
if (change.origin !== 'setValue') {
|
||||||
|
scope.setPreviewContent();
|
||||||
|
|
||||||
|
saveBtn.classList.add('is-marked');
|
||||||
|
unsavedEditCount += 1;
|
||||||
|
if (unsavedEditCount % unsavedEditWarningCount === 0 && unsavedEditCount >= unsavedEditWarningCount) {
|
||||||
|
saveBtn.classList.add('animated');
|
||||||
|
saveBtn.classList.add('wobble');
|
||||||
|
saveBtn.addEventListener('animationend', () => {
|
||||||
|
saveBtn.classList.remove('animated');
|
||||||
|
saveBtn.classList.remove('wobble');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Track when people actually are working.
|
||||||
|
trackEvent.previewCount = (trackEvent.previewCount || 0) + 1;
|
||||||
|
if (trackEvent.previewCount === 4) {
|
||||||
|
trackEvent('fn', 'usingPreview');
|
||||||
|
}
|
||||||
|
}
|
||||||
}, updateDelay);
|
}, updateDelay);
|
||||||
});
|
});
|
||||||
if (options.noAutocomplete) {
|
if (options.noAutocomplete) {
|
||||||
@ -853,6 +952,7 @@ TextareaAutoComplete */
|
|||||||
mode: 'css',
|
mode: 'css',
|
||||||
gutters: [ 'error-gutter', 'CodeMirror-linenumbers', 'CodeMirror-foldgutter' ]
|
gutters: [ 'error-gutter', 'CodeMirror-linenumbers', 'CodeMirror-foldgutter' ]
|
||||||
});
|
});
|
||||||
|
emmetCodeMirror(scope.cm.css);
|
||||||
Inlet(scope.cm.css);
|
Inlet(scope.cm.css);
|
||||||
scope.cm.js = initEditor(jsCode, {
|
scope.cm.js = initEditor(jsCode, {
|
||||||
mode: 'javascript',
|
mode: 'javascript',
|
||||||
@ -861,7 +961,9 @@ TextareaAutoComplete */
|
|||||||
Inlet(scope.cm.js);
|
Inlet(scope.cm.js);
|
||||||
|
|
||||||
function openSettings() {
|
function openSettings() {
|
||||||
if (chrome.runtime.openOptionsPage) {
|
settingsModal.classList.toggle('is-modal-visible');
|
||||||
|
|
||||||
|
/* if (chrome.runtime.openOptionsPage) {
|
||||||
// New way to open options pages, if supported (Chrome 42+).
|
// New way to open options pages, if supported (Chrome 42+).
|
||||||
// Bug: https://bugs.chromium.org/p/chromium/issues/detail?id=601997
|
// Bug: https://bugs.chromium.org/p/chromium/issues/detail?id=601997
|
||||||
// Until this bug fixes, use the
|
// Until this bug fixes, use the
|
||||||
@ -872,25 +974,125 @@ TextareaAutoComplete */
|
|||||||
chrome.tabs.create({
|
chrome.tabs.create({
|
||||||
url: 'chrome://extensions?options=' + chrome.i18n.getMessage('@@extension_id')
|
url: 'chrome://extensions?options=' + chrome.i18n.getMessage('@@extension_id')
|
||||||
});
|
});
|
||||||
}
|
} */
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.onModalSettingsLinkClick = function () {
|
scope.onModalSettingsLinkClick = function onModalSettingsLinkClick() {
|
||||||
openSettings();
|
openSettings();
|
||||||
trackEvent('ui', 'onboardSettingsBtnClick');
|
trackEvent('ui', 'onboardSettingsBtnClick');
|
||||||
}
|
}
|
||||||
|
|
||||||
scope.onShowInTabClicked = function () {
|
scope.onShowInTabClicked = function onShowInTabClicked() {
|
||||||
onboardDontShowInTabOptionBtn.classList.remove('selected');
|
onboardDontShowInTabOptionBtn.classList.remove('selected');
|
||||||
onboardShowInTabOptionBtn.classList.add('selected');
|
onboardShowInTabOptionBtn.classList.add('selected');
|
||||||
trackEvent('ui', 'onboardShowInTabClick');
|
trackEvent('ui', 'onboardShowInTabClick');
|
||||||
}
|
}
|
||||||
scope.onDontShowInTabClicked = function () {
|
scope.onDontShowInTabClicked = function onDontShowInTabClicked() {
|
||||||
onboardDontShowInTabOptionBtn.classList.add('selected');
|
onboardDontShowInTabOptionBtn.classList.add('selected');
|
||||||
onboardShowInTabOptionBtn.classList.remove('selected');
|
onboardShowInTabOptionBtn.classList.remove('selected');
|
||||||
trackEvent('ui', 'onboardDontShowInTabClick');
|
trackEvent('ui', 'onboardDontShowInTabClick');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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';
|
||||||
|
var blob = new Blob([ JSON.stringify(items,false,2) ], { type: "application/json;charset=UTF-8" });
|
||||||
|
var a = document.createElement('a');
|
||||||
|
a.href = window.URL.createObjectURL(blob);
|
||||||
|
a.download = fileName;
|
||||||
|
a.style.display = 'none';
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
a.remove();
|
||||||
|
trackEvent('ui', 'exportBtnClicked');
|
||||||
|
});
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
function mergeImportedItems(items) {
|
||||||
|
var existingItemIds = [];
|
||||||
|
var toMergeItems = {};
|
||||||
|
items.forEach((item) => {
|
||||||
|
if (savedItems[item.id]) {
|
||||||
|
// Item already exists
|
||||||
|
existingItemIds.push(item.id);
|
||||||
|
} else {
|
||||||
|
utils.log('merging', item.id);
|
||||||
|
toMergeItems[item.id] = item;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
var mergedItemCount = items.length - existingItemIds.length;
|
||||||
|
if (existingItemIds.length) {
|
||||||
|
var shouldReplace = confirm(existingItemIds.length + ' creations already exist. Do you want to replace them?');
|
||||||
|
if (shouldReplace) {
|
||||||
|
utils.log('shouldreplace', shouldReplace);
|
||||||
|
items.forEach((item) => {
|
||||||
|
toMergeItems[item.id] = item;
|
||||||
|
});
|
||||||
|
mergedItemCount = items.length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mergedItemCount) {
|
||||||
|
// save new items
|
||||||
|
chrome.storage.local.set(toMergeItems, function () {
|
||||||
|
alertsService.add(mergedItemCount + ' creations imported successfully.');
|
||||||
|
});
|
||||||
|
// Push in new item IDs
|
||||||
|
chrome.storage.local.get({
|
||||||
|
items: {}
|
||||||
|
}, function (result) {
|
||||||
|
|
||||||
|
/* eslint-disable guard-for-in */
|
||||||
|
for (var id in toMergeItems) {
|
||||||
|
result.items[id] = true;
|
||||||
|
}
|
||||||
|
chrome.storage.local.set({
|
||||||
|
items: result.items
|
||||||
|
});
|
||||||
|
|
||||||
|
/* eslint-enable guard-for-in */
|
||||||
|
});
|
||||||
|
alertsService.add(mergedItemCount + ' creations imported successfully.');
|
||||||
|
}
|
||||||
|
// FIXME: Move from here
|
||||||
|
toggleSavedItemsPane(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onImportFileChange(e) {
|
||||||
|
var file = e.target.files[0];
|
||||||
|
// if (!f.type.match('image.*')) {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
|
||||||
|
var reader = new FileReader();
|
||||||
|
reader.onload = function(progressEvent) {
|
||||||
|
var items;
|
||||||
|
try {
|
||||||
|
items = JSON.parse(progressEvent.target.result);
|
||||||
|
utils.log(items);
|
||||||
|
mergeImportedItems(items);
|
||||||
|
} catch (ex) {
|
||||||
|
alert('Oops! Select file is corrupted.')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
reader.readAsText(file, 'utf-8');
|
||||||
|
}
|
||||||
|
|
||||||
|
scope.onImportBtnClicked = function exportItems(e) {
|
||||||
|
var input = document.createElement('input');
|
||||||
|
input.type = 'file';
|
||||||
|
input.style.display = 'none';
|
||||||
|
input.accept = 'accept="application/json';
|
||||||
|
document.body.appendChild(input)
|
||||||
|
input.addEventListener('change', onImportFileChange);
|
||||||
|
input.click();
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
function saveScreenshot(dataURI) {
|
function saveScreenshot(dataURI) {
|
||||||
// convert base64 to raw binary data held in a string
|
// convert base64 to raw binary data held in a string
|
||||||
// doesn't handle URLEncoded DataURIs
|
// doesn't handle URLEncoded DataURIs
|
||||||
@ -911,7 +1113,7 @@ TextareaAutoComplete */
|
|||||||
var size = blob.size + (1024 / 2);
|
var size = blob.size + (1024 / 2);
|
||||||
|
|
||||||
var d = new Date();
|
var d = new Date();
|
||||||
var fileName = [ 'web-maker-screenshot', d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds() ].join('-');
|
var fileName = [ 'web-maker-screenshot', d.getFullYear(), (d.getMonth() + 1), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds() ].join('-');
|
||||||
fileName += '.png';
|
fileName += '.png';
|
||||||
|
|
||||||
function onWriteEnd() {
|
function onWriteEnd() {
|
||||||
@ -977,12 +1179,92 @@ TextareaAutoComplete */
|
|||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Populate the settings in the settings UI
|
||||||
|
function updateSettingsInUi() {
|
||||||
|
$('[data-setting=preserveLastCode]').checked = prefs.preserveLastCode;
|
||||||
|
$('[data-setting=replaceNewTab]').checked = prefs.replaceNewTab;
|
||||||
|
$('[data-setting=htmlMode]').value = prefs.htmlMode;
|
||||||
|
$('[data-setting=cssMode]').value = prefs.cssMode;
|
||||||
|
$('[data-setting=jsMode]').value = prefs.jsMode;
|
||||||
|
$('[data-setting=indentSize]').value = prefs.indentSize;
|
||||||
|
$('[data-setting=indentWith][value=' + (prefs.indentWith || 'spaces') + ']').checked = true;
|
||||||
|
$('[data-setting=isCodeBlastOn]').checked = prefs.isCodeBlastOn;
|
||||||
|
$('[data-setting=editorTheme]').value = prefs.editorTheme;
|
||||||
|
$('[data-setting=keymap][value=' + (prefs.keymap || 'sublime') + ']').checked = true;
|
||||||
|
$('[data-setting=fontSize]').value = prefs.fontSize || 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles all user triggered preference changes in the UI.
|
||||||
|
*/
|
||||||
|
scope.updateSetting = function updateSetting(e) {
|
||||||
|
// If this was triggered from user interaction, save the setting
|
||||||
|
if (e) {
|
||||||
|
var settingName = e.target.dataset.setting;
|
||||||
|
var obj = {};
|
||||||
|
var el = e.target;
|
||||||
|
utils.log(settingName, (el.type === 'checkbox') ? el.checked : el.value);
|
||||||
|
prefs[settingName] = el.type === 'checkbox' ? el.checked : el.value;
|
||||||
|
obj[settingName] = prefs[settingName];
|
||||||
|
chrome.storage.sync.set(obj, function() {
|
||||||
|
alertsService.add('setting saved');
|
||||||
|
});
|
||||||
|
trackEvent('ui', 'updatePref-' + settingName, prefs[settingName]);
|
||||||
|
}
|
||||||
|
|
||||||
|
htmlCode.querySelector('.CodeMirror').style.fontSize = prefs.fontSize;
|
||||||
|
cssCode.querySelector('.CodeMirror').style.fontSize = prefs.fontSize;
|
||||||
|
jsCode.querySelector('.CodeMirror').style.fontSize = prefs.fontSize;
|
||||||
|
['html', 'js', 'css'].forEach((type) => {
|
||||||
|
scope.cm[type].setOption(
|
||||||
|
'indentWithTabs',
|
||||||
|
$('[data-setting=indentWith]:checked').value !== 'spaces'
|
||||||
|
);
|
||||||
|
|
||||||
|
scope.cm[type].setOption('blastCode', $('[data-setting=isCodeBlastOn]').checked ? { effect: 2, shake: false } : false);
|
||||||
|
scope.cm[type].setOption('indentUnit', $('[data-setting=indentSize]').value);
|
||||||
|
scope.cm[type].setOption('tabSize', $('[data-setting=indentSize]').value);
|
||||||
|
scope.cm[type].setOption('theme', $('[data-setting=editorTheme]').value);
|
||||||
|
// Replace correct css file in LINK tags's href
|
||||||
|
editorThemeLinkTag.href = '/lib/codemirror/theme/' + prefs.editorTheme + '.css';
|
||||||
|
|
||||||
|
scope.cm[type].setOption('keyMap', $('[data-setting=keymap]').value);
|
||||||
|
scope.cm[type].refresh();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
scope.onNewBtnClick = function () {
|
||||||
|
trackEvent('ui', 'newBtnClick');
|
||||||
|
if (unsavedEditCount) {
|
||||||
|
var shouldDiscard = confirm('You have unsaved changes. Do you still want to create something new?');
|
||||||
|
if (shouldDiscard) {
|
||||||
|
createNewItem();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
createNewItem();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
scope.onOpenBtnClick = function () {
|
||||||
|
trackEvent('ui', 'openBtnClick');
|
||||||
|
openSavedItemsPane();
|
||||||
|
};
|
||||||
|
scope.onSaveBtnClick = function () {
|
||||||
|
trackEvent('ui', 'saveBtnClick', currentItem.id ? 'saved' : 'new');
|
||||||
|
saveItem();
|
||||||
|
};
|
||||||
|
|
||||||
function compileNodes() {
|
function compileNodes() {
|
||||||
var nodes = [].slice.call($all('[d-click]'));
|
var nodes = [].slice.call($all('[d-click]'));
|
||||||
nodes.forEach(function (el) {
|
nodes.forEach(function (el) {
|
||||||
el.addEventListener('click', function (e) {
|
el.addEventListener('click', function (e) {
|
||||||
scope[el.getAttribute('d-click')].call(window, e)
|
scope[el.getAttribute('d-click')].call(window, e)
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
nodes = [].slice.call($all('[d-change]'));
|
||||||
|
nodes.forEach(function (el) {
|
||||||
|
el.addEventListener('change', function (e) {
|
||||||
|
scope[el.getAttribute('d-change')].call(window, e)
|
||||||
|
});
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1059,18 +1341,7 @@ TextareaAutoComplete */
|
|||||||
saveFile();
|
saveFile();
|
||||||
trackEvent('ui', 'saveHtmlClick');
|
trackEvent('ui', 'saveHtmlClick');
|
||||||
});
|
});
|
||||||
utils.onButtonClick(openBtn, function () {
|
|
||||||
openSavedItemsPane();
|
|
||||||
trackEvent('ui', 'openBtnClick');
|
|
||||||
});
|
|
||||||
utils.onButtonClick(saveBtn, function () {
|
|
||||||
trackEvent('ui', 'saveBtnClick', currentItem.id ? 'saved' : 'new');
|
|
||||||
saveItem();
|
|
||||||
});
|
|
||||||
utils.onButtonClick(newBtn, function () {
|
|
||||||
createNewItem();
|
|
||||||
trackEvent('ui', 'newBtnClick');
|
|
||||||
});
|
|
||||||
utils.onButtonClick(savedItemsPaneCloseBtn, toggleSavedItemsPane);
|
utils.onButtonClick(savedItemsPaneCloseBtn, toggleSavedItemsPane);
|
||||||
utils.onButtonClick(savedItemsPane, function (e) {
|
utils.onButtonClick(savedItemsPane, function (e) {
|
||||||
if (e.target.classList.contains('js-saved-item-tile')) {
|
if (e.target.classList.contains('js-saved-item-tile')) {
|
||||||
@ -1080,7 +1351,6 @@ TextareaAutoComplete */
|
|||||||
toggleSavedItemsPane();
|
toggleSavedItemsPane();
|
||||||
}
|
}
|
||||||
if (e.target.classList.contains('js-saved-item-tile__close-btn')) {
|
if (e.target.classList.contains('js-saved-item-tile__close-btn')) {
|
||||||
utils.log('removing', e.target.parentElement)
|
|
||||||
removeItem(e.target.parentElement.dataset.itemId);
|
removeItem(e.target.parentElement.dataset.itemId);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -1101,11 +1371,11 @@ TextareaAutoComplete */
|
|||||||
var currentMode = type === 'html' ? htmlMode : (type === 'css' ? cssMode : jsMode);
|
var currentMode = type === 'html' ? htmlMode : (type === 'css' ? cssMode : jsMode);
|
||||||
if (currentMode !== mode) {
|
if (currentMode !== mode) {
|
||||||
if (type === 'html') {
|
if (type === 'html') {
|
||||||
updateHtmlMode(mode);
|
updateHtmlMode(mode).then(() => scope.setPreviewContent(true));
|
||||||
} else if (type === 'js') {
|
} else if (type === 'js') {
|
||||||
updateJsMode(mode);
|
updateJsMode(mode).then(() => scope.setPreviewContent(true));
|
||||||
} else if (type === 'css') {
|
} else if (type === 'css') {
|
||||||
updateCssMode(mode);
|
updateCssMode(mode).then(() => scope.setPreviewContent(true));
|
||||||
}
|
}
|
||||||
trackEvent('ui', 'updateCodeMode', mode);
|
trackEvent('ui', 'updateCodeMode', mode);
|
||||||
}
|
}
|
||||||
@ -1229,11 +1499,19 @@ TextareaAutoComplete */
|
|||||||
// Get synced `preserveLastCode` setting to get back last code (or not).
|
// Get synced `preserveLastCode` setting to get back last code (or not).
|
||||||
chrome.storage.sync.get({
|
chrome.storage.sync.get({
|
||||||
preserveLastCode: true,
|
preserveLastCode: true,
|
||||||
|
replaceNewTab: false,
|
||||||
htmlMode: 'html',
|
htmlMode: 'html',
|
||||||
jsMode: 'js',
|
jsMode: 'js',
|
||||||
cssMode: 'css'
|
cssMode: 'css',
|
||||||
|
isCodeBlastOn: false,
|
||||||
|
indentWith: 'spaces',
|
||||||
|
indentSize: 2,
|
||||||
|
editorTheme: 'monokai',
|
||||||
|
keymap: 'sublime',
|
||||||
|
fontSize: 16
|
||||||
}, function syncGetCallback(result) {
|
}, function syncGetCallback(result) {
|
||||||
if (result.preserveLastCode && lastCode) {
|
if (result.preserveLastCode && lastCode) {
|
||||||
|
unsavedEditCount = 0;
|
||||||
if (lastCode.id) {
|
if (lastCode.id) {
|
||||||
chrome.storage.local.get(lastCode.id, function (itemResult) {
|
chrome.storage.local.get(lastCode.id, function (itemResult) {
|
||||||
utils.log('Load item ', lastCode.id)
|
utils.log('Load item ', lastCode.id)
|
||||||
@ -1248,9 +1526,20 @@ TextareaAutoComplete */
|
|||||||
} else {
|
} else {
|
||||||
createNewItem();
|
createNewItem();
|
||||||
}
|
}
|
||||||
prefs.htmlMode = result.htmlmode;
|
prefs.preserveLastCode = result.preserveLastCode;
|
||||||
|
prefs.replaceNewTab = result.replaceNewTab;
|
||||||
|
prefs.htmlMode = result.htmlMode;
|
||||||
prefs.cssMode = result.cssMode;
|
prefs.cssMode = result.cssMode;
|
||||||
prefs.jsMode = result.jsMode;
|
prefs.jsMode = result.jsMode;
|
||||||
|
prefs.isCodeBlastOn = result.isCodeBlastOn;
|
||||||
|
prefs.indentSize = result.indentSize;
|
||||||
|
prefs.indentWith = result.indentWith;
|
||||||
|
prefs.editorTheme = result.editorTheme;
|
||||||
|
prefs.keymap = result.keymap;
|
||||||
|
prefs.fontSize = result.fontSize;
|
||||||
|
|
||||||
|
updateSettingsInUi();
|
||||||
|
scope.updateSetting();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Check for new version notifications
|
// Check for new version notifications
|
||||||
@ -1280,6 +1569,59 @@ TextareaAutoComplete */
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var options = '';
|
||||||
|
[
|
||||||
|
'3024-day',
|
||||||
|
'3024-night',
|
||||||
|
'abcdef',
|
||||||
|
'ambiance',
|
||||||
|
'base16-dark',
|
||||||
|
'base16-light',
|
||||||
|
'bespin',
|
||||||
|
'blackboard',
|
||||||
|
'cobalt',
|
||||||
|
'colorforth',
|
||||||
|
'dracula',
|
||||||
|
'duotone-dark',
|
||||||
|
'duotone-light',
|
||||||
|
'eclipse',
|
||||||
|
'elegant',
|
||||||
|
'erlang-dark',
|
||||||
|
'hopscotch',
|
||||||
|
'icecoder',
|
||||||
|
'isotope',
|
||||||
|
'lesser-dark',
|
||||||
|
'liquibyte',
|
||||||
|
'material',
|
||||||
|
'mbo',
|
||||||
|
'mdn-like',
|
||||||
|
'midnight',
|
||||||
|
'monokai',
|
||||||
|
'neat',
|
||||||
|
'neo',
|
||||||
|
'night',
|
||||||
|
'panda-syntax',
|
||||||
|
'paraiso-dark',
|
||||||
|
'paraiso-light',
|
||||||
|
'pastel-on-dark',
|
||||||
|
'railscasts',
|
||||||
|
'rubyblue',
|
||||||
|
'seti',
|
||||||
|
'solarized dark',
|
||||||
|
'solarized light',
|
||||||
|
'the-matrix',
|
||||||
|
'tomorrow-night-bright',
|
||||||
|
'tomorrow-night-eighties',
|
||||||
|
'ttcn',
|
||||||
|
'twilight',
|
||||||
|
'vibrant-ink',
|
||||||
|
'xq-dark',
|
||||||
|
'xq-light',
|
||||||
|
'yeti',
|
||||||
|
'zenburn'
|
||||||
|
].forEach((theme) => { options += '<option value="' + theme + '">' + theme + '</option>'; });
|
||||||
|
document.querySelector('[data-setting="editorTheme"]').innerHTML = options;
|
||||||
|
|
||||||
requestAnimationFrame(compileNodes);
|
requestAnimationFrame(compileNodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,12 +31,27 @@ a { text-decoration: none; color: crimson; cursor: pointer; }
|
|||||||
.fr { float: right; }
|
.fr { float: right; }
|
||||||
.relative { position: relative; }
|
.relative { position: relative; }
|
||||||
.tac { text-align: center; }
|
.tac { text-align: center; }
|
||||||
|
.va-m { vertical-align: middle; }
|
||||||
.full-width { width: 100%; }
|
.full-width { width: 100%; }
|
||||||
.opacity--30 { opacity: 0.3; }
|
.opacity--30 { opacity: 0.3; }
|
||||||
.pointer-none { pointer-events: none; }
|
.pointer-none { pointer-events: none; }
|
||||||
|
.ml-1 { margin-left: 1rem; }
|
||||||
|
hr {
|
||||||
|
background: 0;
|
||||||
|
border: 0;
|
||||||
|
border-bottom: 1px solid #dedede;
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
[class*="hint--"]:after {
|
[class*="hint--"]:after {
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
|
font-weight: normal;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
}
|
||||||
|
.line {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
.caret {
|
.caret {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
@ -51,7 +66,7 @@ a { text-decoration: none; color: crimson; cursor: pointer; }
|
|||||||
a > svg {
|
a > svg {
|
||||||
fill: rgba(255, 255, 255, 0.2)
|
fill: rgba(255, 255, 255, 0.2)
|
||||||
}
|
}
|
||||||
select, input[type="text"], textarea {
|
select, input[type="text"], input[type="number"], textarea {
|
||||||
padding: 3px 5px;
|
padding: 3px 5px;
|
||||||
font-size: inherit;
|
font-size: inherit;
|
||||||
}
|
}
|
||||||
@ -222,7 +237,7 @@ select, input[type="text"], textarea {
|
|||||||
.cm-s-monokai .CodeMirror-guttermarker-subtle {
|
.cm-s-monokai .CodeMirror-guttermarker-subtle {
|
||||||
opacity: 0.4;
|
opacity: 0.4;
|
||||||
}
|
}
|
||||||
.CodeMirror-activeline-background, .CodeMirror-activeline-gutter {
|
.cm-s-monokai .CodeMirror-activeline-background, .cm-s-monokai .CodeMirror-activeline-gutter {
|
||||||
background: rgba(0,0,0,0.1) !important;
|
background: rgba(0,0,0,0.1) !important;
|
||||||
}
|
}
|
||||||
.CodeMirror-guttermarker-subtle {
|
.CodeMirror-guttermarker-subtle {
|
||||||
@ -258,7 +273,7 @@ li.CodeMirror-hint-active {
|
|||||||
background-color: rgba(0, 0, 0, 0.5);
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
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);
|
||||||
line-height: 20px;
|
/*line-height: 20px;*/
|
||||||
}
|
}
|
||||||
.main-header {
|
.main-header {
|
||||||
border: 0;
|
border: 0;
|
||||||
@ -266,17 +281,27 @@ li.CodeMirror-hint-active {
|
|||||||
}
|
}
|
||||||
.main-header__btn-wrap > a {
|
.main-header__btn-wrap > a {
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 20px;
|
||||||
|
height: 20px;
|
||||||
|
letter-spacing: 0.6px;
|
||||||
color: #9297B3;
|
color: #9297B3;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
border: 1px solid rgba(146, 151, 179, 0.33);
|
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
padding: 0px 5px;
|
padding: 0px 8px;
|
||||||
|
border: 1px solid rgba(0,0,0,.9);
|
||||||
|
background: linear-gradient(180deg, rgba(0,0,0,0.5) 0, rgba(255,255,255,0.1) 100%);
|
||||||
|
/*text-shadow: 0px 1px 1px rgba(0,0,0,1);*/
|
||||||
|
box-shadow: 0 -1px 0px 0 rgba(255,255,255,0.15);
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
.main-header__btn-wrap > a > svg {
|
.main-header__btn-wrap > a > svg {
|
||||||
fill: #9297B3;
|
fill: #9297B3;
|
||||||
margin-right: 4px;
|
margin-right: 4px;
|
||||||
}
|
}
|
||||||
|
.main-header__btn-wrap > a.is-marked > svg {
|
||||||
|
fill: crimson;
|
||||||
|
}
|
||||||
.main-header__btn-wrap > a:hover {
|
.main-header__btn-wrap > a:hover {
|
||||||
border-color: rgba(146, 151, 179, 0.5);
|
border-color: rgba(146, 151, 179, 0.5);
|
||||||
}
|
}
|
||||||
@ -290,9 +315,11 @@ li.CodeMirror-hint-active {
|
|||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
-webkit-filter: grayscale(0.9);
|
-webkit-filter: grayscale(0.9);
|
||||||
transition: 0.4s ease;
|
transition: 0.4s ease;
|
||||||
|
opacity: 0.3;
|
||||||
}
|
}
|
||||||
.footer:hover .logo {
|
.footer:hover .logo {
|
||||||
-webkit-filter: grayscale(0);
|
-webkit-filter: grayscale(0);
|
||||||
|
opacity: 1;
|
||||||
}
|
}
|
||||||
.footer__right {
|
.footer__right {
|
||||||
font-size: 0;
|
font-size: 0;
|
||||||
@ -351,8 +378,8 @@ li.CodeMirror-hint-active {
|
|||||||
position: fixed;
|
position: fixed;
|
||||||
top: 5vh;
|
top: 5vh;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
width: 60vw;
|
width: 68vw;
|
||||||
margin-left: -30vw;
|
margin-left: -34vw;
|
||||||
max-width: 90vw;
|
max-width: 90vw;
|
||||||
height: auto;
|
height: auto;
|
||||||
z-index: 2000;
|
z-index: 2000;
|
||||||
@ -373,6 +400,7 @@ li.CodeMirror-hint-active {
|
|||||||
opacity: 0;
|
opacity: 0;
|
||||||
padding: 2em;
|
padding: 2em;
|
||||||
font-size: 1.3em;
|
font-size: 1.3em;
|
||||||
|
line-height: 1.4;
|
||||||
max-height: 90vh;
|
max-height: 90vh;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
@ -736,3 +764,39 @@ li.CodeMirror-hint-active {
|
|||||||
right: 10px;
|
right: 10px;
|
||||||
bottom: 10px;
|
bottom: 10px;
|
||||||
}
|
}
|
||||||
|
@keyframes wobble {
|
||||||
|
from {
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
15% {
|
||||||
|
transform: translate3d(-25%, 0, 0) rotate3d(0, 0, 1, -5deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
30% {
|
||||||
|
transform: translate3d(20%, 0, 0) rotate3d(0, 0, 1, 3deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
45% {
|
||||||
|
transform: translate3d(-15%, 0, 0) rotate3d(0, 0, 1, -3deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
60% {
|
||||||
|
transform: translate3d(10%, 0, 0) rotate3d(0, 0, 1, 2deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
75% {
|
||||||
|
transform: translate3d(-5%, 0, 0) rotate3d(0, 0, 1, -1deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.animated {
|
||||||
|
animation-duration: 1s;
|
||||||
|
animation-fill-mode: both;
|
||||||
|
}
|
||||||
|
.wobble {
|
||||||
|
animation-name: wobble;
|
||||||
|
}
|
||||||
|
28
test-scenarios.md
Normal file
28
test-scenarios.md
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
## Editor
|
||||||
|
|
||||||
|
- Tab should insert tab when nothing selected,
|
||||||
|
- Tab should indent when something is selected.
|
||||||
|
|
||||||
|
## Logic
|
||||||
|
|
||||||
|
- `for`, `while` & `dowhile` loops should be instrumented in the generated JavaScript code.
|
||||||
|
- Import should confirm the overriding of existing items.
|
||||||
|
- Opening a smaller DOM item shouldn't show left over HTML from a previously open bigger DOM item.
|
||||||
|
|
||||||
|
## Interface
|
||||||
|
|
||||||
|
- 'New' button should create a new item if no unsaved changes present, otherwise ask confirmation.
|
||||||
|
- 'Save' button click should save the current work with a notification.
|
||||||
|
- Ctrl/Cmd+S should save the current work with a notification.
|
||||||
|
- 'Open' button click should open saved creations panel.
|
||||||
|
- Ctrl/Cmd+O should open saved creations panel.
|
||||||
|
- Clicking on an item in saved items pane should open that item in the editor.
|
||||||
|
- Clicking the close button in the saved item tile should confirm first, and then remove that item from DOM & storage.
|
||||||
|
- If the item being removed is open in the editor, a new item should be created & opened after removal.
|
||||||
|
- Clicking the *export* button should download a JSON formatted export file of saved items.
|
||||||
|
- Clicking on *import* button should ask to select a JSON file to import.
|
||||||
|
|
||||||
|
## Settings
|
||||||
|
|
||||||
|
- Each setting change should update the corresponding key in chrome sync storage
|
||||||
|
- Changing fontSize, theme should reflect in the editor as soon as it is changed and focused out.
|
Loading…
x
Reference in New Issue
Block a user