20
.travis.yml
@@ -2,16 +2,12 @@ language: node_js
|
|||||||
node_js:
|
node_js:
|
||||||
- '10'
|
- '10'
|
||||||
install:
|
install:
|
||||||
- npm i -g npm@latest
|
- yarn add global eslint
|
||||||
- npm install -g eslint
|
- yarn add global babel-eslint
|
||||||
- npm install -g babel-eslint
|
- yarn add global eslint-plugin-react
|
||||||
- npm install -g eslint-plugin-react
|
- yarn add global eslint-plugin-mocha
|
||||||
- npm install -g eslint-plugin-mocha
|
- yarn add global eslint-config-synacor
|
||||||
- npm install -g eslint-config-synacor
|
|
||||||
script:
|
script:
|
||||||
- npm run lint
|
- yarn run lint
|
||||||
- npm ci
|
- yarn run test
|
||||||
- npm run test
|
cache: yarn
|
||||||
cache:
|
|
||||||
directories:
|
|
||||||
- '$HOME/.npm'
|
|
||||||
|
@@ -36,13 +36,14 @@ gulp.task('copyFiles', function() {
|
|||||||
gulp.src('src/lib/transpilers/*').pipe(gulp.dest('app/lib/transpilers')),
|
gulp.src('src/lib/transpilers/*').pipe(gulp.dest('app/lib/transpilers')),
|
||||||
gulp.src('src/lib/screenlog.js').pipe(gulp.dest('app/lib')),
|
gulp.src('src/lib/screenlog.js').pipe(gulp.dest('app/lib')),
|
||||||
gulp.src('icons/*').pipe(gulp.dest('app/icons')),
|
gulp.src('icons/*').pipe(gulp.dest('app/icons')),
|
||||||
|
gulp.src('src/assets/*').pipe(gulp.dest('app/assets')),
|
||||||
|
gulp.src('src/templates/*').pipe(gulp.dest('app/templates')),
|
||||||
gulp
|
gulp
|
||||||
.src([
|
.src([
|
||||||
'src/preview.html',
|
'src/preview.html',
|
||||||
'src/detached-window.js',
|
'src/detached-window.js',
|
||||||
'src/icon-48.png',
|
'src/icon-48.png',
|
||||||
'src/icon-128.png',
|
'src/icon-128.png',
|
||||||
'src/patreon.png',
|
|
||||||
'manifest.json'
|
'manifest.json'
|
||||||
])
|
])
|
||||||
.pipe(gulp.dest('app')),
|
.pipe(gulp.dest('app')),
|
||||||
|
21667
package-lock.json
generated
@@ -61,6 +61,7 @@
|
|||||||
"copy-webpack-plugin": "^4.5.1",
|
"copy-webpack-plugin": "^4.5.1",
|
||||||
"esprima": "^4.0.0",
|
"esprima": "^4.0.0",
|
||||||
"firebase": "^5.0.4",
|
"firebase": "^5.0.4",
|
||||||
|
"jszip": "^3.1.5",
|
||||||
"preact": "^8.2.6",
|
"preact": "^8.2.6",
|
||||||
"preact-compat": "^3.17.0",
|
"preact-compat": "^3.17.0",
|
||||||
"preact-portal": "^1.1.3",
|
"preact-portal": "^1.1.3",
|
||||||
|
23
src/assets/html5-logo.svg
Executable file
@@ -0,0 +1,23 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!-- Generator: Adobe Illustrator 15.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="2000px"
|
||||||
|
height="2000px" viewBox="0 0 2000 2000" enable-background="new 0 0 2000 2000" xml:space="preserve">
|
||||||
|
<g id="Logo_artwork">
|
||||||
|
</g>
|
||||||
|
<g id="Guides_to_delete">
|
||||||
|
<g>
|
||||||
|
<polygon fill="#E34E26" points="352.732,1718.4 208.627,101.984 1791.373,101.984 1647.093,1718.528 999.615,1898.016 "/>
|
||||||
|
<polygon fill="#EF662A" points="1000,234.108 1000,1760.716 1523.565,1615.585 1646.918,234.108 "/>
|
||||||
|
<polygon fill="#FFFFFF" points="503.468,432.378 556.906,1031.897 1244.048,1031.897 1220.988,1289.041 999.744,1348.857
|
||||||
|
778.919,1289.128 764.155,1124.017 565.155,1124.017 593.611,1442.302 999.697,1555.086 1406.296,1442.302 1460.806,833.669
|
||||||
|
738.229,833.669 720.086,630.648 1478.168,630.648 1478.773,630.648 1496.532,432.378 "/>
|
||||||
|
<g>
|
||||||
|
<polygon fill="#EBEBEB" points="1000,432.378 503.468,432.378 556.906,1031.897 1000,1031.897 1000,833.669 738.229,833.669
|
||||||
|
720.086,630.648 1000,630.648 "/>
|
||||||
|
<polygon fill="#EBEBEB" points="1000,1348.771 999.744,1348.857 778.919,1289.128 764.155,1124.017 565.155,1124.017
|
||||||
|
593.611,1442.302 999.697,1555.086 1000,1555.001 "/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 1.4 KiB |
BIN
src/assets/js13kgames-square-logo.png
Normal file
After Width: | Height: | Size: 4.2 KiB |
BIN
src/assets/js13kgames.png
Normal file
After Width: | Height: | Size: 5.7 KiB |
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.4 KiB |
9
src/assets/preact-logo.svg
Executable file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg width="256px" height="296px" viewBox="0 0 256 296" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" preserveAspectRatio="xMidYMid">
|
||||||
|
<g>
|
||||||
|
<polygon fill="#673AB8" points="128 0 256 73.8999491 256 221.699847 128 295.599796 0 221.699847 0 73.8999491"></polygon>
|
||||||
|
<path d="M34.8647584,220.478469 C51.8814262,242.25881 105.959701,225.662965 157.014868,185.774297 C208.070035,145.885628 237.255632,97.428608 220.238964,75.6482664 C203.222296,53.8679249 149.144022,70.4637701 98.0888543,110.352439 C47.0336869,150.241107 17.8480906,198.698127 34.8647584,220.478469 Z M42.1343351,214.798853 C36.4908625,207.575537 38.9565723,193.395881 49.7081913,175.544904 C61.0297348,156.747677 80.2490923,135.997367 103.76847,117.622015 C127.287848,99.2466634 152.071368,85.6181573 173.049166,79.1803727 C192.970945,73.066665 207.325915,74.1045667 212.969387,81.3278822 C218.61286,88.5511977 216.14715,102.730854 205.395531,120.581832 C194.073987,139.379058 174.85463,160.129368 151.335252,178.50472 C127.815874,196.880072 103.032354,210.508578 82.054556,216.946362 C62.1327769,223.06007 47.7778077,222.022168 42.1343351,214.798853 Z" fill="#FFFFFF"></path>
|
||||||
|
<path d="M220.238964,220.478469 C237.255632,198.698127 208.070035,150.241107 157.014868,110.352439 C105.959701,70.4637701 51.8814262,53.8679249 34.8647584,75.6482664 C17.8480906,97.428608 47.0336869,145.885628 98.0888543,185.774297 C149.144022,225.662965 203.222296,242.25881 220.238964,220.478469 Z M212.969387,214.798853 C207.325915,222.022168 192.970945,223.06007 173.049166,216.946362 C152.071368,210.508578 127.287848,196.880072 103.76847,178.50472 C80.2490923,160.129368 61.0297348,139.379058 49.7081913,120.581832 C38.9565723,102.730854 36.4908625,88.5511977 42.1343351,81.3278822 C47.7778077,74.1045667 62.1327769,73.066665 82.054556,79.1803727 C103.032354,85.6181573 127.815874,99.2466634 151.335252,117.622015 C174.85463,135.997367 194.073987,156.747677 205.395531,175.544904 C216.14715,193.395881 218.61286,207.575537 212.969387,214.798853 Z" fill="#FFFFFF"></path>
|
||||||
|
<path d="M127.551861,167.666971 C138.378632,167.666971 147.155465,158.890139 147.155465,148.063368 C147.155465,137.236596 138.378632,128.459764 127.551861,128.459764 C116.72509,128.459764 107.948257,137.236596 107.948257,148.063368 C107.948257,158.890139 116.72509,167.666971 127.551861,167.666971 L127.551861,167.666971 Z" fill="#FFFFFF"></path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
6
src/assets/react-logo.svg
Normal file
After Width: | Height: | Size: 7.7 KiB |
@@ -62,7 +62,7 @@ export default class AddLibrary extends Component {
|
|||||||
<h1>Add Library</h1>
|
<h1>Add Library</h1>
|
||||||
|
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<svg style="width: 30px; height: 30px;fill:#999">
|
<svg style="width: 30px; height: 30px;fill:rgb(255,255,255,0.2)">
|
||||||
<use xlinkHref="#search" />
|
<use xlinkHref="#search" />
|
||||||
</svg>
|
</svg>
|
||||||
<LibraryAutoSuggest
|
<LibraryAutoSuggest
|
||||||
@@ -123,7 +123,6 @@ export default class AddLibrary extends Component {
|
|||||||
id="externalJsTextarea"
|
id="externalJsTextarea"
|
||||||
cols="30"
|
cols="30"
|
||||||
rows="5"
|
rows="5"
|
||||||
placeholder="Put each library in new line"
|
|
||||||
value={this.state.js}
|
value={this.state.js}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@@ -136,7 +135,6 @@ export default class AddLibrary extends Component {
|
|||||||
id="externalCssTextarea"
|
id="externalCssTextarea"
|
||||||
cols="30"
|
cols="30"
|
||||||
rows="5"
|
rows="5"
|
||||||
placeholder="Put each library in new line"
|
|
||||||
value={this.state.css}
|
value={this.state.css}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -934,6 +934,7 @@ export default class ContentWrap extends Component {
|
|||||||
<use xlinkHref="#chevron-icon" />
|
<use xlinkHref="#chevron-icon" />
|
||||||
</svg>
|
</svg>
|
||||||
<input
|
<input
|
||||||
|
tabIndex={this.state.isConsoleOpen ? 0 : -1}
|
||||||
onKeyUp={this.evalConsoleExpr.bind(this)}
|
onKeyUp={this.evalConsoleExpr.bind(this)}
|
||||||
class="console-exec-input"
|
class="console-exec-input"
|
||||||
/>
|
/>
|
||||||
|
32
src/components/CreateNewModal.jsx
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import { h } from 'preact';
|
||||||
|
import Modal from './Modal';
|
||||||
|
import { ItemTile } from './ItemTile';
|
||||||
|
import templates from '../templateList';
|
||||||
|
|
||||||
|
export function CreateNewModal({
|
||||||
|
show,
|
||||||
|
closeHandler,
|
||||||
|
onBlankTemplateSelect,
|
||||||
|
onTemplateSelect
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Modal show={show} closeHandler={closeHandler} smll>
|
||||||
|
<div class="tac">
|
||||||
|
<button className="btn" onClick={onBlankTemplateSelect}>
|
||||||
|
Start a blank creation
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
|
Or choose from a template:
|
||||||
|
<div class="saved-items-pane__container">
|
||||||
|
{templates.map(template => (
|
||||||
|
<ItemTile
|
||||||
|
item={template}
|
||||||
|
focusable
|
||||||
|
onClick={onTemplateSelect.bind(null, template)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
@@ -1,21 +1,185 @@
|
|||||||
import { h, Component } from 'preact';
|
import { h, Component } from 'preact';
|
||||||
import { Button } from './common';
|
import { Button } from './common';
|
||||||
|
|
||||||
|
class JS13K extends Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
const compoDate = new Date('August 13 2018 11:00 GMT');
|
||||||
|
var now = new Date();
|
||||||
|
var daysLeft;
|
||||||
|
if (+compoDate > +now) {
|
||||||
|
daysLeft = Math.floor((compoDate - now) / 1000 / 3600 / 24);
|
||||||
|
}
|
||||||
|
this.setState({
|
||||||
|
daysLeft
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const codeSizeInKb = this.props.codeSize
|
||||||
|
? (this.props.codeSize / 1024).toFixed(2)
|
||||||
|
: 0;
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
role="button"
|
||||||
|
class="flex flex-v-center"
|
||||||
|
tabIndex="0"
|
||||||
|
onClick={this.props.onClick}
|
||||||
|
onBlur={this.props.onBlur}
|
||||||
|
>
|
||||||
|
<img src="assets/js13kgames.png" alt="JS13K Games logo" height="24" />{' '}
|
||||||
|
<div class="footer__js13k-days-left">
|
||||||
|
{this.state.daysLeft} days to go
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="footer__js13k-code-size"
|
||||||
|
style={{
|
||||||
|
color: codeSizeInKb > 10 ? 'crimson' : 'limegreen'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{codeSizeInKb} KB/ 13KB
|
||||||
|
</div>
|
||||||
|
<span
|
||||||
|
class="caret"
|
||||||
|
style={`transition:0.3s ease; transform-origin: center 2px; ${
|
||||||
|
this.props.isOpen ? 'transform:rotate(180deg);' : ''
|
||||||
|
}`}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export default class Footer extends Component {
|
export default class Footer extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = {
|
this.state = {
|
||||||
isKeyboardShortcutsModalOpen: false
|
isKeyboardShortcutsModalOpen: false,
|
||||||
|
isJs13kDropdownOpen: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
layoutBtnClickhandler(layoutId) {
|
layoutBtnClickhandler(layoutId) {
|
||||||
this.props.layoutBtnClickHandler(layoutId);
|
this.props.layoutBtnClickHandler(layoutId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
js13kClickHandler() {
|
||||||
|
// console.log(999);
|
||||||
|
this.setState({
|
||||||
|
isJs13kDropdownOpen: !this.state.isJs13kDropdownOpen
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div id="footer" class="footer">
|
<div id="footer" class="footer">
|
||||||
<div class="footer__right fr">
|
<div>
|
||||||
|
<a
|
||||||
|
href="https://webmakerapp.com/"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
<div class="logo" />
|
||||||
|
</a>
|
||||||
|
©
|
||||||
|
<span class="web-maker-with-tag">Web Maker</span>
|
||||||
|
<Button
|
||||||
|
onClick={this.props.helpBtnClickHandler}
|
||||||
|
data-event-category="ui"
|
||||||
|
data-event-action="helpButtonClick"
|
||||||
|
class="footer__link hint--rounded hint--top-right"
|
||||||
|
aria-label="Help"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
style="width:20px; height:20px; vertical-align:text-bottom"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path d="M15.07,11.25L14.17,12.17C13.45,12.89 13,13.5 13,15H11V14.5C11,13.39 11.45,12.39 12.17,11.67L13.41,10.41C13.78,10.05 14,9.55 14,9C14,7.89 13.1,7 12,7A2,2 0 0,0 10,9H8A4,4 0 0,1 12,5A4,4 0 0,1 16,9C16,9.88 15.64,10.67 15.07,11.25M13,19H11V17H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z" />
|
||||||
|
</svg>
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
onClick={this.props.keyboardShortcutsBtnClickHandler}
|
||||||
|
data-event-category="ui"
|
||||||
|
data-event-action="keyboardShortcutButtonClick"
|
||||||
|
class="footer__link hint--rounded hint--top-right hide-on-mobile"
|
||||||
|
aria-label="Keyboard shortcuts"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
style={{
|
||||||
|
width: '20px',
|
||||||
|
height: '20px',
|
||||||
|
verticalAlign: 'text-bottom'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<use xlinkHref="#keyboard-icon" />
|
||||||
|
</svg>
|
||||||
|
</Button>
|
||||||
|
<a
|
||||||
|
class="footer__link hint--rounded hint--top-right"
|
||||||
|
aria-label="Tweet about 'Web Maker'"
|
||||||
|
href="http://twitter.com/share?url=https://webmakerapp.com/&text=Web Maker - A blazing fast %26 offline web playground! via @webmakerApp&related=webmakerApp&hashtags=web,frontend,playground,offline"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
style={{
|
||||||
|
width: '20px',
|
||||||
|
height: '20px',
|
||||||
|
verticalAlign: 'text-bottom'
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<use xlinkHref="#twitter-icon" />
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
<Button
|
||||||
|
onClick={this.props.supportDeveloperBtnClickHandler}
|
||||||
|
data-event-category="ui"
|
||||||
|
data-event-action="supportDeveloperFooterBtnClick"
|
||||||
|
class="footer__link ml-1 hint--rounded hint--top-right hide-on-mobile support-link"
|
||||||
|
aria-label="Support the developer by pledging some amount"
|
||||||
|
>
|
||||||
|
Donate
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{this.props.prefs.isJs13kModeOn ? (
|
||||||
|
<div class="flex flex-v-center">
|
||||||
|
<JS13K
|
||||||
|
isOpen={this.state.isJs13kDropdownOpen}
|
||||||
|
codeSize={this.props.codeSize}
|
||||||
|
onClick={this.js13kClickHandler.bind(this)}
|
||||||
|
onBlur={() =>
|
||||||
|
setTimeout(
|
||||||
|
() => this.setState({ isJs13kDropdownOpen: false }),
|
||||||
|
300
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
{this.state.isJs13kDropdownOpen && (
|
||||||
|
<div className="js13k__dropdown">
|
||||||
|
<button
|
||||||
|
class="btn"
|
||||||
|
style={{
|
||||||
|
width: '200px',
|
||||||
|
display: 'block',
|
||||||
|
marginBottom: '16px'
|
||||||
|
}}
|
||||||
|
onClick={this.props.onJs13KDownloadBtnClick}
|
||||||
|
>
|
||||||
|
Download game as zip
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="btn"
|
||||||
|
style={{ width: '200px', display: 'block' }}
|
||||||
|
onClick={this.props.onJs13KHelpBtnClick}
|
||||||
|
>
|
||||||
|
Help
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
|
||||||
|
<div class="footer__right">
|
||||||
<button
|
<button
|
||||||
onClick={this.props.saveHtmlBtnClickHandler}
|
onClick={this.props.saveHtmlBtnClickHandler}
|
||||||
id="saveHtmlBtn"
|
id="saveHtmlBtn"
|
||||||
@@ -150,72 +314,6 @@ export default class Footer extends Component {
|
|||||||
</svg>
|
</svg>
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<a
|
|
||||||
href="https://webmakerapp.com/"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
<div class="logo" />
|
|
||||||
</a>
|
|
||||||
©
|
|
||||||
<span class="web-maker-with-tag">Web Maker</span>
|
|
||||||
<Button
|
|
||||||
onClick={this.props.helpBtnClickHandler}
|
|
||||||
data-event-category="ui"
|
|
||||||
data-event-action="helpButtonClick"
|
|
||||||
class="footer__link hint--rounded hint--top-right"
|
|
||||||
aria-label="Help"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
style="width:20px; height:20px; vertical-align:text-bottom"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path d="M15.07,11.25L14.17,12.17C13.45,12.89 13,13.5 13,15H11V14.5C11,13.39 11.45,12.39 12.17,11.67L13.41,10.41C13.78,10.05 14,9.55 14,9C14,7.89 13.1,7 12,7A2,2 0 0,0 10,9H8A4,4 0 0,1 12,5A4,4 0 0,1 16,9C16,9.88 15.64,10.67 15.07,11.25M13,19H11V17H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z" />
|
|
||||||
</svg>
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
onClick={this.props.keyboardShortcutsBtnClickHandler}
|
|
||||||
data-event-category="ui"
|
|
||||||
data-event-action="keyboardShortcutButtonClick"
|
|
||||||
class="footer__link hint--rounded hint--top-right hide-on-mobile"
|
|
||||||
aria-label="Keyboard shortcuts"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
style={{
|
|
||||||
width: '20px',
|
|
||||||
height: '20px',
|
|
||||||
verticalAlign: 'text-bottom'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<use xlinkHref="#keyboard-icon" />
|
|
||||||
</svg>
|
|
||||||
</Button>
|
|
||||||
<a
|
|
||||||
class="footer__link hint--rounded hint--top-right"
|
|
||||||
aria-label="Tweet about 'Web Maker'"
|
|
||||||
href="http://twitter.com/share?url=https://webmakerapp.com/&text=Web Maker - A blazing fast %26 offline web playground! via @webmakerApp&related=webmakerApp&hashtags=web,frontend,playground,offline"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
<svg
|
|
||||||
style={{
|
|
||||||
width: '20px',
|
|
||||||
height: '20px',
|
|
||||||
verticalAlign: 'text-bottom'
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<use xlinkHref="#twitter-icon" />
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
<Button
|
|
||||||
onClick={this.props.supportDeveloperBtnClickHandler}
|
|
||||||
data-event-category="ui"
|
|
||||||
data-event-action="supportDeveloperFooterBtnClick"
|
|
||||||
class="footer__link ml-1 hint--rounded hint--top-right hide-on-mobile support-link"
|
|
||||||
aria-label="Support the developer by pledging some amount"
|
|
||||||
>
|
|
||||||
Support the developer
|
|
||||||
</Button>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
60
src/components/ItemTile.jsx
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import { h } from 'preact';
|
||||||
|
import { getHumanDate } from '../utils';
|
||||||
|
import Modal from './Modal';
|
||||||
|
|
||||||
|
export function ItemTile({
|
||||||
|
item,
|
||||||
|
onClick,
|
||||||
|
onForkBtnClick,
|
||||||
|
onRemoveBtnClick,
|
||||||
|
focusable
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
role={focusable ? 'button' : null}
|
||||||
|
tabindex={focusable ? 0 : null}
|
||||||
|
class="js-saved-item-tile saved-item-tile"
|
||||||
|
data-item-id={item.id}
|
||||||
|
onClick={onClick}
|
||||||
|
>
|
||||||
|
<div class="saved-item-tile__btns">
|
||||||
|
{onForkBtnClick ? (
|
||||||
|
<a
|
||||||
|
class="js-saved-item-tile__fork-btn saved-item-tile__btn hint--left hint--medium"
|
||||||
|
aria-label="Creates a duplicate of this creation (Ctrl/⌘ + F)"
|
||||||
|
onClick={onForkBtnClick}
|
||||||
|
>
|
||||||
|
Fork<span class="show-when-selected">(Ctrl/⌘ + F)</span>
|
||||||
|
</a>
|
||||||
|
) : null}
|
||||||
|
{onRemoveBtnClick ? (
|
||||||
|
<a
|
||||||
|
class="js-saved-item-tile__remove-btn saved-item-tile__btn hint--left"
|
||||||
|
aria-label="Remove"
|
||||||
|
onClick={onRemoveBtnClick}
|
||||||
|
>
|
||||||
|
X
|
||||||
|
</a>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-v-center">
|
||||||
|
{item.img ? (
|
||||||
|
<div>
|
||||||
|
<img
|
||||||
|
class="saved-item-tile__img"
|
||||||
|
height="40"
|
||||||
|
src={item.img}
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
<h3 class="saved-item-tile__title">{item.title}</h3>
|
||||||
|
</div>
|
||||||
|
{item.updatedOn ? (
|
||||||
|
<div class="saved-item-tile__meta">
|
||||||
|
Last updated: {getHumanDate(item.updatedOn)}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
82
src/components/Js13KModal.jsx
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
import { h } from 'preact';
|
||||||
|
import Modal from './Modal';
|
||||||
|
|
||||||
|
export function Js13KModal({ show, closeHandler }) {
|
||||||
|
return (
|
||||||
|
<Modal show={show} closeHandler={closeHandler} small>
|
||||||
|
<div class="tac">
|
||||||
|
<div className="flex flex-v-center flex-h-center ">
|
||||||
|
<img
|
||||||
|
src="/icon-128.png"
|
||||||
|
alt="Web Maker logo"
|
||||||
|
height="100"
|
||||||
|
style="margin:0 0.5rem;"
|
||||||
|
/>
|
||||||
|
<h2>Web Maker</h2>
|
||||||
|
<span style="font-size:3rem;margin:0 1rem;">+</span>
|
||||||
|
<h2>JS13K Games</h2>
|
||||||
|
<img
|
||||||
|
src="assets/js13kgames-square-logo.png"
|
||||||
|
alt="JS13K Games logo"
|
||||||
|
height="100"
|
||||||
|
style="margin:0 0.5rem;"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
<strong>Js13kGames</strong> is a JavaScript coding competition for{' '}
|
||||||
|
<strong>HTML5 Game Developers</strong>. The fun part of the compo is
|
||||||
|
the file size limit set to <strong>13 kilobytes</strong>. The
|
||||||
|
competition will start at <strong>13:00 CEST, 13th August</strong> and
|
||||||
|
will end at <strong>13:00 CEST, 13th September 2018</strong>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
You have activated Web Maker's Js13kGames mode! This gives you some
|
||||||
|
extra support to build your awesome game right here. Constantly see
|
||||||
|
your game's zipped size in the footer. When you are done, download the
|
||||||
|
zip.{' '}
|
||||||
|
<a
|
||||||
|
href="https://medium.com/web-maker/js13kgames-jam-with-web-maker-a3389cf2cbb"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>
|
||||||
|
Read more about this collaboration
|
||||||
|
</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="https://gamedevelopment.tutsplus.com/articles/how-to-minify-your-html5-game-for-the-js13kgames-competition--cms-21883"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
Read Tuts+ Gamedev intro article
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="http://js13kgames.github.io/resources/"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>
|
||||||
|
Resources and useful tools
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href="http://2018.js13kgames.com/#rules"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>
|
||||||
|
Compo rules
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<p>Have fun building games!</p>
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
}
|
@@ -56,7 +56,9 @@ export default class Modal extends Component {
|
|||||||
return (
|
return (
|
||||||
<Portal into="body">
|
<Portal into="body">
|
||||||
<div
|
<div
|
||||||
class={`${this.props.extraClasses || ''} modal is-modal-visible`}
|
class={`${this.props.extraClasses || ''} modal is-modal-visible ${
|
||||||
|
this.props.small ? 'modal--small' : ''
|
||||||
|
}`}
|
||||||
ref={el => (this.overlayEl = el)}
|
ref={el => (this.overlayEl = el)}
|
||||||
onClick={this.onOverlayClick.bind(this)}
|
onClick={this.onOverlayClick.bind(this)}
|
||||||
>
|
>
|
||||||
|
@@ -7,6 +7,8 @@ function NotificationItem({ type, children }) {
|
|||||||
strongTag = <strong>🔧 Bugfix</strong>;
|
strongTag = <strong>🔧 Bugfix</strong>;
|
||||||
} else if (type === 'a11y') {
|
} else if (type === 'a11y') {
|
||||||
strongTag = <strong>♿️ Accessibility</strong>;
|
strongTag = <strong>♿️ Accessibility</strong>;
|
||||||
|
} else if (type === 'ui') {
|
||||||
|
strongTag = <strong>🖥 Interface</strong>;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<li>
|
<li>
|
||||||
@@ -101,7 +103,35 @@ export function Notifications(props) {
|
|||||||
<div>
|
<div>
|
||||||
<h1>Whats new?</h1>
|
<h1>Whats new?</h1>
|
||||||
|
|
||||||
<Notification version="3.3.2" isLatest={true} {...props}>
|
<Notification version="3.4.0" isLatest={true} {...props}>
|
||||||
|
<li>
|
||||||
|
<strong>🎉 Js13kGames Mode</strong>: For all you Js13kGames compo
|
||||||
|
participants out there. Turn it on from Settings.{' '}
|
||||||
|
<a
|
||||||
|
href="https://medium.com/web-maker/js13kgames-jam-with-web-maker-a3389cf2cbb"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener"
|
||||||
|
>
|
||||||
|
Read more about it here.
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>🎉 Templates</strong>: Presenting, templates for major
|
||||||
|
libraries and frameworks. Hit the "New" button to explore.
|
||||||
|
</li>
|
||||||
|
<NotificationItem type="a11y">
|
||||||
|
Add missing focus rings around focusable element.
|
||||||
|
</NotificationItem>
|
||||||
|
<NotificationItem type="ui">
|
||||||
|
Migrate remaining interface elements to dark theme. Now complete app
|
||||||
|
is in dark theme.
|
||||||
|
</NotificationItem>
|
||||||
|
<NotificationItem type="bug">
|
||||||
|
Fix "Save as HTML" and "Take Screenshot" features in Chrome extension.
|
||||||
|
</NotificationItem>
|
||||||
|
</Notification>
|
||||||
|
|
||||||
|
<Notification version="3.3.2" {...props}>
|
||||||
<NotificationItem type="a11y">
|
<NotificationItem type="a11y">
|
||||||
Improper links are now buttons with proper focus indication and
|
Improper links are now buttons with proper focus indication and
|
||||||
screen-reader support. Thanks{' '}
|
screen-reader support. Thanks{' '}
|
||||||
|
@@ -1,9 +1,10 @@
|
|||||||
import { h, Component } from 'preact';
|
import { h, Component } from 'preact';
|
||||||
import { log, getHumanDate } from '../utils';
|
import { log } from '../utils';
|
||||||
import { trackEvent } from '../analytics';
|
import { trackEvent } from '../analytics';
|
||||||
import { itemService } from '../itemService';
|
import { itemService } from '../itemService';
|
||||||
import { alertsService } from '../notifications';
|
import { alertsService } from '../notifications';
|
||||||
import { deferred } from '../deferred';
|
import { deferred } from '../deferred';
|
||||||
|
import { ItemTile } from './ItemTile';
|
||||||
|
|
||||||
export default class SavedItemPane extends Component {
|
export default class SavedItemPane extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@@ -230,32 +231,12 @@ export default class SavedItemPane extends Component {
|
|||||||
<div class="mt-1">No match found.</div>
|
<div class="mt-1">No match found.</div>
|
||||||
) : null}
|
) : null}
|
||||||
{this.state.filteredItems.map(item => (
|
{this.state.filteredItems.map(item => (
|
||||||
<div
|
<ItemTile
|
||||||
class="js-saved-item-tile saved-item-tile"
|
item={item}
|
||||||
data-item-id={item.id}
|
|
||||||
onClick={this.itemClickHandler.bind(this, item)}
|
onClick={this.itemClickHandler.bind(this, item)}
|
||||||
>
|
onForkBtnClick={this.itemForkBtnClickHandler.bind(this, item)}
|
||||||
<div class="saved-item-tile__btns">
|
onRemoveBtnClick={this.itemRemoveBtnClickHandler.bind(this, item)}
|
||||||
<a
|
/>
|
||||||
class="js-saved-item-tile__fork-btn saved-item-tile__btn hint--left hint--medium"
|
|
||||||
aria-label="Creates a duplicate of this creation (Ctrl/⌘ + F)"
|
|
||||||
onClick={this.itemForkBtnClickHandler.bind(this, item)}
|
|
||||||
>
|
|
||||||
Fork<span class="show-when-selected">(Ctrl/⌘ + F)</span>
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
class="js-saved-item-tile__remove-btn saved-item-tile__btn hint--left"
|
|
||||||
aria-label="Remove"
|
|
||||||
onClick={this.itemRemoveBtnClickHandler.bind(this, item)}
|
|
||||||
>
|
|
||||||
X
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
<h3 class="saved-item-tile__title">{item.title}</h3>
|
|
||||||
<span class="saved-item-tile__meta">
|
|
||||||
Last updated: {getHumanDate(item.updatedOn)}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
))}
|
))}
|
||||||
{!this.items.length ? (
|
{!this.items.length ? (
|
||||||
<h2 class="opacity--30">Nothing saved here.</h2>
|
<h2 class="opacity--30">Nothing saved here.</h2>
|
||||||
|
@@ -286,6 +286,14 @@ export default class Settings extends Component {
|
|||||||
pref={this.props.prefs.isCodeBlastOn}
|
pref={this.props.prefs.isCodeBlastOn}
|
||||||
onChange={this.updateSetting.bind(this)}
|
onChange={this.updateSetting.bind(this)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<CheckboxSetting
|
||||||
|
title="Get ready to build some games at JS13KGames"
|
||||||
|
label="Js13kGames Mode"
|
||||||
|
name="isJs13kModeOn"
|
||||||
|
pref={this.props.prefs.isJs13kModeOn}
|
||||||
|
onChange={this.updateSetting.bind(this)}
|
||||||
|
/>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<hr />
|
<hr />
|
||||||
@@ -296,7 +304,7 @@ export default class Settings extends Component {
|
|||||||
class="line"
|
class="line"
|
||||||
title="This timeout is used to indentify a possible infinite loop and prevent it."
|
title="This timeout is used to indentify a possible infinite loop and prevent it."
|
||||||
>
|
>
|
||||||
Maximum time allowed in a loop iteration
|
Maximum time allowed in a loop iteration{' '}
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
value={this.props.prefs.infiniteLoopTimeout}
|
value={this.props.prefs.infiniteLoopTimeout}
|
||||||
|
@@ -41,7 +41,11 @@ export function SupportDeveloperModal({ show, closeHandler }) {
|
|||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
aria-label="Make a monthly pledge on Patreon"
|
aria-label="Make a monthly pledge on Patreon"
|
||||||
>
|
>
|
||||||
<img src="patreon.png" height="60" alt="Become a patron image" />
|
<img
|
||||||
|
src="assets/patreon.png"
|
||||||
|
height="60"
|
||||||
|
alt="Become a patron image"
|
||||||
|
/>
|
||||||
<h3 class="onboard-selection-text">
|
<h3 class="onboard-selection-text">
|
||||||
Make a monthly pledge on Patreon
|
Make a monthly pledge on Patreon
|
||||||
</h3>
|
</h3>
|
||||||
|
@@ -10,13 +10,16 @@ import SavedItemPane from './SavedItemPane.jsx';
|
|||||||
import AddLibrary from './AddLibrary.jsx';
|
import AddLibrary from './AddLibrary.jsx';
|
||||||
import Modal from './Modal.jsx';
|
import Modal from './Modal.jsx';
|
||||||
import Login from './Login.jsx';
|
import Login from './Login.jsx';
|
||||||
|
import { computeHtml, computeCss, computeJs } from '../computes';
|
||||||
import {
|
import {
|
||||||
log,
|
log,
|
||||||
generateRandomId,
|
generateRandomId,
|
||||||
semverCompare,
|
semverCompare,
|
||||||
saveAsHtml,
|
saveAsHtml,
|
||||||
handleDownloadsPermission,
|
handleDownloadsPermission,
|
||||||
downloadFile
|
downloadFile,
|
||||||
|
getCompleteHtml,
|
||||||
|
getFilenameFromUrl
|
||||||
} from '../utils';
|
} from '../utils';
|
||||||
import { itemService } from '../itemService';
|
import { itemService } from '../itemService';
|
||||||
import '../db';
|
import '../db';
|
||||||
@@ -38,7 +41,10 @@ import { Alerts } from './Alerts';
|
|||||||
import Portal from 'preact-portal';
|
import Portal from 'preact-portal';
|
||||||
import { HelpModal } from './HelpModal';
|
import { HelpModal } from './HelpModal';
|
||||||
import { OnboardingModal } from './OnboardingModal';
|
import { OnboardingModal } from './OnboardingModal';
|
||||||
|
import { Js13KModal } from './Js13KModal';
|
||||||
|
import { CreateNewModal } from './CreateNewModal';
|
||||||
import { Icons } from './Icons';
|
import { Icons } from './Icons';
|
||||||
|
import JSZip from 'jszip';
|
||||||
|
|
||||||
if (module.hot) {
|
if (module.hot) {
|
||||||
require('preact/debug');
|
require('preact/debug');
|
||||||
@@ -55,8 +61,7 @@ export default class App extends Component {
|
|||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.AUTO_SAVE_INTERVAL = 15000; // 15 seconds
|
this.AUTO_SAVE_INTERVAL = 15000; // 15 seconds
|
||||||
this.state = {
|
this.modalDefaultStates = {
|
||||||
isSavedItemPaneOpen: false,
|
|
||||||
isModalOpen: false,
|
isModalOpen: false,
|
||||||
isAddLibraryModalOpen: false,
|
isAddLibraryModalOpen: false,
|
||||||
isSettingsModalOpen: false,
|
isSettingsModalOpen: false,
|
||||||
@@ -68,6 +73,12 @@ export default class App extends Component {
|
|||||||
isKeyboardShortcutsModalOpen: false,
|
isKeyboardShortcutsModalOpen: false,
|
||||||
isAskToImportModalOpen: false,
|
isAskToImportModalOpen: false,
|
||||||
isOnboardModalOpen: false,
|
isOnboardModalOpen: false,
|
||||||
|
isJs13KModalOpen: false,
|
||||||
|
isCreateNewModalOpen: false
|
||||||
|
};
|
||||||
|
this.state = {
|
||||||
|
isSavedItemPaneOpen: false,
|
||||||
|
...this.modalDefaultStates,
|
||||||
prefs: {},
|
prefs: {},
|
||||||
currentItem: {
|
currentItem: {
|
||||||
title: '',
|
title: '',
|
||||||
@@ -96,7 +107,8 @@ export default class App extends Component {
|
|||||||
lightVersion: false,
|
lightVersion: false,
|
||||||
lineWrap: true,
|
lineWrap: true,
|
||||||
infiniteLoopTimeout: 1000,
|
infiniteLoopTimeout: 1000,
|
||||||
layoutMode: 2
|
layoutMode: 2,
|
||||||
|
isJs13kModeOn: false
|
||||||
};
|
};
|
||||||
this.prefs = {};
|
this.prefs = {};
|
||||||
|
|
||||||
@@ -484,16 +496,7 @@ export default class App extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
isAddLibraryModalOpen: false,
|
...this.modalDefaultStates
|
||||||
isSettingsModalOpen: false,
|
|
||||||
isHelpModalOpen: false,
|
|
||||||
isNotificationsModalOpen: false,
|
|
||||||
isLoginModalOpen: false,
|
|
||||||
isProfileModalOpen: false,
|
|
||||||
isSupportDeveloperModalOpen: false,
|
|
||||||
isKeyboardShortcutsModalOpen: false,
|
|
||||||
isAskToImportModalOpen: false,
|
|
||||||
isOnboardModalOpen: false
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
onExternalLibChange(newValues) {
|
onExternalLibChange(newValues) {
|
||||||
@@ -697,6 +700,9 @@ export default class App extends Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (this.state.prefs.isJs13kModeOn) {
|
||||||
|
this.calculateCodeSize();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
onCodeSettingsChange(type, settings) {
|
onCodeSettingsChange(type, settings) {
|
||||||
this.state.currentItem[`${type}Settings`] = {
|
this.state.currentItem[`${type}Settings`] = {
|
||||||
@@ -824,10 +830,14 @@ export default class App extends Component {
|
|||||||
'You have unsaved changes. Do you still want to create something new?'
|
'You have unsaved changes. Do you still want to create something new?'
|
||||||
);
|
);
|
||||||
if (shouldDiscard) {
|
if (shouldDiscard) {
|
||||||
this.createNewItem();
|
this.setState({
|
||||||
|
isCreateNewModalOpen: true
|
||||||
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
this.createNewItem();
|
this.setState({
|
||||||
|
isCreateNewModalOpen: true
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
openBtnClickHandler() {
|
openBtnClickHandler() {
|
||||||
@@ -973,6 +983,160 @@ export default class App extends Component {
|
|||||||
this.state.currentItem.mainSizes = this.getMainPaneSizes();
|
this.state.currentItem.mainSizes = this.getMainPaneSizes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate byte size of a text snippet
|
||||||
|
* @author Lea Verou
|
||||||
|
* MIT License
|
||||||
|
*/
|
||||||
|
calculateTextSize(text) {
|
||||||
|
if (!text) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
var crlf = /(\r?\n|\r)/g,
|
||||||
|
whitespace = /(\r?\n|\r|\s+)/g;
|
||||||
|
|
||||||
|
const ByteSize = {
|
||||||
|
count: function(text, options) {
|
||||||
|
// Set option defaults
|
||||||
|
options = options || {};
|
||||||
|
options.lineBreaks = options.lineBreaks || 1;
|
||||||
|
options.ignoreWhitespace = options.ignoreWhitespace || false;
|
||||||
|
|
||||||
|
var length = text.length,
|
||||||
|
nonAscii = length - text.replace(/[\u0100-\uFFFF]/g, '').length,
|
||||||
|
lineBreaks = length - text.replace(crlf, '').length;
|
||||||
|
|
||||||
|
if (options.ignoreWhitespace) {
|
||||||
|
// Strip whitespace
|
||||||
|
text = text.replace(whitespace, '');
|
||||||
|
|
||||||
|
return text.length + nonAscii;
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
length +
|
||||||
|
nonAscii +
|
||||||
|
Math.max(0, options.lineBreaks * (lineBreaks - 1))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
format: function(count, plainText) {
|
||||||
|
var level = 0;
|
||||||
|
|
||||||
|
while (count > 1024) {
|
||||||
|
count /= 1024;
|
||||||
|
level++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Round to 2 decimals
|
||||||
|
count = Math.round(count * 100) / 100;
|
||||||
|
|
||||||
|
level = ['', 'K', 'M', 'G', 'T'][level];
|
||||||
|
|
||||||
|
return (
|
||||||
|
(plainText ? count : '<strong>' + count + '</strong>') +
|
||||||
|
' ' +
|
||||||
|
level +
|
||||||
|
'B'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return ByteSize.count(text);
|
||||||
|
}
|
||||||
|
getExternalLibCode() {
|
||||||
|
const item = this.state.currentItem;
|
||||||
|
var libs = (item.externalLibs && item.externalLibs.js) || '';
|
||||||
|
libs += ('\n' + item.externalLibs && item.externalLibs.css) || '';
|
||||||
|
libs = libs.split('\n').filter(lib => lib);
|
||||||
|
return libs.map(lib =>
|
||||||
|
fetch(lib)
|
||||||
|
.then(res => res.text())
|
||||||
|
.then(data => {
|
||||||
|
return {
|
||||||
|
code: data,
|
||||||
|
fileName: getFilenameFromUrl(lib)
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
calculateCodeSize() {
|
||||||
|
const item = this.state.currentItem;
|
||||||
|
var htmlPromise = computeHtml(item.html, item.htmlMode);
|
||||||
|
var cssPromise = computeCss(item.css, item.cssMode);
|
||||||
|
var jsPromise = computeJs(item.js, item.jsMode, false);
|
||||||
|
Promise.all([
|
||||||
|
htmlPromise,
|
||||||
|
cssPromise,
|
||||||
|
jsPromise,
|
||||||
|
...this.getExternalLibCode()
|
||||||
|
]).then(result => {
|
||||||
|
var html = result[0].code || '',
|
||||||
|
css = result[1].code || '',
|
||||||
|
js = result[2].code || '';
|
||||||
|
|
||||||
|
var fileContent = getCompleteHtml(html, css, js, item, true);
|
||||||
|
|
||||||
|
var zip = new JSZip();
|
||||||
|
zip.file('index.html', fileContent);
|
||||||
|
for (let i = 3; i < result.length; i++) {
|
||||||
|
const externalLib = result[i];
|
||||||
|
zip.file(externalLib.fileName, externalLib.code);
|
||||||
|
}
|
||||||
|
|
||||||
|
// console.log('ORIGINAL', this.calculateTextSize(fileContent));
|
||||||
|
|
||||||
|
var promise = null;
|
||||||
|
if (0 && JSZip.support.uint8array) {
|
||||||
|
promise = zip.generateAsync({ type: 'uint8array' });
|
||||||
|
} else {
|
||||||
|
promise = zip.generateAsync({
|
||||||
|
type: 'base64',
|
||||||
|
compression: 'DEFLATE',
|
||||||
|
compressionOptions: {
|
||||||
|
level: 9
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
promise.then(data => {
|
||||||
|
const zipContent = data;
|
||||||
|
const size = this.calculateTextSize(atob(data));
|
||||||
|
this.setState({
|
||||||
|
codeSize: size
|
||||||
|
});
|
||||||
|
this.currentItemZipBase64Data = data;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
js13KHelpBtnClickHandler() {
|
||||||
|
this.setState({
|
||||||
|
isJs13KModalOpen: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
js13KDownloadBtnClickHandler() {
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.setAttribute('download', this.state.currentItem.title);
|
||||||
|
a.href = 'data:application/zip;base64,' + this.currentItemZipBase64Data;
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
a.remove();
|
||||||
|
}
|
||||||
|
blankTemplateSelectHandler() {
|
||||||
|
this.createNewItem();
|
||||||
|
this.setState({ isCreateNewModalOpen: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
templateSelectHandler(template) {
|
||||||
|
fetch(`templates/template-${template.id}.json`)
|
||||||
|
.then(res => res.json())
|
||||||
|
.then(json => {
|
||||||
|
this.forkItem(json);
|
||||||
|
});
|
||||||
|
this.setState({ isCreateNewModalOpen: false });
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@@ -1006,6 +1170,7 @@ export default class App extends Component {
|
|||||||
/>
|
/>
|
||||||
<div class="global-console-container" id="globalConsoleContainerEl" />
|
<div class="global-console-container" id="globalConsoleContainerEl" />
|
||||||
<Footer
|
<Footer
|
||||||
|
prefs={this.state.prefs}
|
||||||
layoutBtnClickHandler={this.layoutBtnClickHandler.bind(this)}
|
layoutBtnClickHandler={this.layoutBtnClickHandler.bind(this)}
|
||||||
helpBtnClickHandler={() => this.setState({ isHelpModalOpen: true })}
|
helpBtnClickHandler={() => this.setState({ isHelpModalOpen: true })}
|
||||||
settingsBtnClickHandler={() =>
|
settingsBtnClickHandler={() =>
|
||||||
@@ -1028,7 +1193,12 @@ export default class App extends Component {
|
|||||||
screenshotBtnClickHandler={this.screenshotBtnClickHandler.bind(
|
screenshotBtnClickHandler={this.screenshotBtnClickHandler.bind(
|
||||||
this
|
this
|
||||||
)}
|
)}
|
||||||
|
onJs13KHelpBtnClick={this.js13KHelpBtnClickHandler.bind(this)}
|
||||||
|
onJs13KDownloadBtnClick={this.js13KDownloadBtnClickHandler.bind(
|
||||||
|
this
|
||||||
|
)}
|
||||||
hasUnseenChangelog={this.state.hasUnseenChangelog}
|
hasUnseenChangelog={this.state.hasUnseenChangelog}
|
||||||
|
codeSize={this.state.codeSize}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -1145,6 +1315,18 @@ export default class App extends Component {
|
|||||||
closeHandler={() => this.setState({ isOnboardModalOpen: false })}
|
closeHandler={() => this.setState({ isOnboardModalOpen: false })}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<Js13KModal
|
||||||
|
show={this.state.isJs13KModalOpen}
|
||||||
|
closeHandler={() => this.setState({ isJs13KModalOpen: false })}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<CreateNewModal
|
||||||
|
show={this.state.isCreateNewModalOpen}
|
||||||
|
closeHandler={() => this.setState({ isCreateNewModalOpen: false })}
|
||||||
|
onBlankTemplateSelect={this.blankTemplateSelectHandler.bind(this)}
|
||||||
|
onTemplateSelect={this.templateSelectHandler.bind(this)}
|
||||||
|
/>
|
||||||
|
|
||||||
<Portal into="body">
|
<Portal into="body">
|
||||||
<div
|
<div
|
||||||
class="modal-overlay"
|
class="modal-overlay"
|
||||||
|
131
src/style.css
@@ -1,8 +1,10 @@
|
|||||||
:root {
|
:root {
|
||||||
|
--color-text: #d4cde9;
|
||||||
--color-bg: #252637;
|
--color-bg: #252637;
|
||||||
--color-sidebar: #3a2b63;
|
--color-popup: #3a2b63;
|
||||||
--code-font-size: 16px;
|
--code-font-size: 16px;
|
||||||
--color-button: #0074d9;
|
--color-button: #d3a447;
|
||||||
|
--color-focus-outline: #d3a447;
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
@@ -23,12 +25,34 @@ h1 {
|
|||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
select,
|
||||||
|
input,
|
||||||
|
textarea {
|
||||||
|
font-size: inherit;
|
||||||
|
color: var(--color-text);
|
||||||
|
background: rgba(0, 0, 0, 0.24);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.09);
|
||||||
|
border-bottom-color: rgba(255, 255, 255, 0.17);
|
||||||
|
box-shadow: inset 0 2px 5px rgba(0, 0, 0, 0.2);
|
||||||
|
border-radius: 3px;
|
||||||
|
padding: 10px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
[role='button'] {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: #d61237;
|
color: #f7ae2d;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
line-height: 1.65;
|
line-height: 1.65;
|
||||||
}
|
}
|
||||||
@@ -131,7 +155,7 @@ button {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.support-link {
|
.support-link {
|
||||||
color: #d61237;
|
color: #f7ae2d;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 600px) {
|
@media screen and (max-width: 600px) {
|
||||||
@@ -158,7 +182,8 @@ button {
|
|||||||
hr {
|
hr {
|
||||||
background: 0;
|
background: 0;
|
||||||
border: 0;
|
border: 0;
|
||||||
border-bottom: 1px solid #dedede;
|
border-bottom: 1px solid rgba(255, 255, 255, 0.12);
|
||||||
|
margin: 20px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
label {
|
label {
|
||||||
@@ -192,14 +217,6 @@ a > svg {
|
|||||||
fill: rgba(255, 255, 255, 0.2);
|
fill: rgba(255, 255, 255, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
select,
|
|
||||||
input[type='text'],
|
|
||||||
input[type='number'],
|
|
||||||
textarea {
|
|
||||||
padding: 3px 5px;
|
|
||||||
font-size: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hidden-select {
|
.hidden-select {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -213,6 +230,7 @@ textarea {
|
|||||||
display: inline-block;
|
display: inline-block;
|
||||||
color: var(--color-button);
|
color: var(--color-button);
|
||||||
font-size: inherit;
|
font-size: inherit;
|
||||||
|
background: transparent;
|
||||||
border: 3px solid var(--color-button);
|
border: 3px solid var(--color-button);
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 9px 15px;
|
padding: 9px 15px;
|
||||||
@@ -244,9 +262,9 @@ textarea {
|
|||||||
box-shadow: 0 5px 5px 0 rgba(0, 0, 0, 0.25);
|
box-shadow: 0 5px 5px 0 rgba(0, 0, 0, 0.25);
|
||||||
}
|
}
|
||||||
|
|
||||||
[class*='btn']:focus {
|
*:focus {
|
||||||
outline-width: 4px;
|
outline-width: 4px;
|
||||||
outline-color: #b76b29;
|
outline-color: var(--color-button);
|
||||||
outline-style: solid;
|
outline-style: solid;
|
||||||
outline-offset: 1px;
|
outline-offset: 1px;
|
||||||
}
|
}
|
||||||
@@ -573,6 +591,8 @@ body > #demo-frame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.footer {
|
.footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
/* Because .console is 6 */
|
/* Because .console is 6 */
|
||||||
z-index: 6;
|
z-index: 6;
|
||||||
}
|
}
|
||||||
@@ -587,7 +607,8 @@ body > #demo-frame {
|
|||||||
.btn--dark,
|
.btn--dark,
|
||||||
.main-header__btn-wrap > button {
|
.main-header__btn-wrap > button {
|
||||||
box-sizing: content-box;
|
box-sizing: content-box;
|
||||||
font-size: 0.8em;
|
text-transform: uppercase;
|
||||||
|
font-size: 12px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
line-height: 20px;
|
line-height: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
@@ -605,7 +626,6 @@ body > #demo-frame {
|
|||||||
);
|
);
|
||||||
/*text-shadow: 0px 1px 1px rgba(0,0,0,1);*/
|
/*text-shadow: 0px 1px 1px rgba(0,0,0,1);*/
|
||||||
box-shadow: 0 -1px 0px 0 rgba(255, 255, 255, 0.15);
|
box-shadow: 0 -1px 0px 0 rgba(255, 255, 255, 0.15);
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn--dark > svg {
|
.btn--dark > svg {
|
||||||
@@ -721,19 +741,20 @@ body > #demo-frame {
|
|||||||
|
|
||||||
.item-title-input {
|
.item-title-input {
|
||||||
background: none;
|
background: none;
|
||||||
border: 0;
|
border: 0 !important;
|
||||||
color: rgba(255, 255, 255, 0.6);
|
color: rgba(255, 255, 255, 0.6);
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
padding: 3px 5px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-input {
|
.search-input {
|
||||||
background: rgba(255, 255, 255, 0.1);
|
/* background: rgba(255, 255, 255, 0.1); */
|
||||||
padding: 10px 20px;
|
/* padding: 10px 20px; */
|
||||||
border: 0;
|
/* border: 0; */
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
color: white;
|
/* color: white; */
|
||||||
border-radius: 4px;
|
/* border-radius: 4px; */
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal {
|
.modal {
|
||||||
@@ -787,10 +808,10 @@ body > #demo-frame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.modal__content {
|
.modal__content {
|
||||||
background: #fdfdfd;
|
background: var(--color-popup);
|
||||||
color: #444;
|
color: var(--color-text);
|
||||||
position: relative;
|
position: relative;
|
||||||
border-radius: 8px;
|
border-radius: 5px;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
padding: 3em;
|
padding: 3em;
|
||||||
font-size: 1.1em;
|
font-size: 1.1em;
|
||||||
@@ -852,7 +873,8 @@ body > #demo-frame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.pledge-modal .modal__content,
|
.pledge-modal .modal__content,
|
||||||
.ask-to-import-modal .modal__content {
|
.ask-to-import-modal .modal__content,
|
||||||
|
.modal--small .modal__content {
|
||||||
max-width: 800px;
|
max-width: 800px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -868,7 +890,7 @@ body > #demo-frame {
|
|||||||
width: 450px;
|
width: 450px;
|
||||||
padding: 20px 30px;
|
padding: 20px 30px;
|
||||||
z-index: 6;
|
z-index: 6;
|
||||||
background-color: var(--color-sidebar);
|
background-color: var(--color-popup);
|
||||||
transition: 0.3s cubic-bezier(1, 0.13, 0.21, 0.87);
|
transition: 0.3s cubic-bezier(1, 0.13, 0.21, 0.87);
|
||||||
transition-property: transform;
|
transition-property: transform;
|
||||||
will-change: transform;
|
will-change: transform;
|
||||||
@@ -1011,6 +1033,10 @@ body > #demo-frame {
|
|||||||
pointer-events: auto;
|
pointer-events: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.saved-item-tile__img {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
.saved-item-tile__btn {
|
.saved-item-tile__btn {
|
||||||
padding: 7px 10px;
|
padding: 7px 10px;
|
||||||
color: rgba(255, 255, 255, 0.3);
|
color: rgba(255, 255, 255, 0.3);
|
||||||
@@ -1028,11 +1054,12 @@ body > #demo-frame {
|
|||||||
.saved-item-tile__title {
|
.saved-item-tile__title {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
font-size: 1.4em;
|
font-size: 1.4em;
|
||||||
margin: 0 0 1em 0;
|
margin: 0;
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
|
|
||||||
.saved-item-tile__meta {
|
.saved-item-tile__meta {
|
||||||
|
margin-top: 8px;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
opacity: 0.3;
|
opacity: 0.3;
|
||||||
}
|
}
|
||||||
@@ -1087,10 +1114,10 @@ body > #demo-frame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.notification {
|
.notification {
|
||||||
border: 1px solid #f1f1f1;
|
/* border: 1px solid #f1f1f1; */
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
background: #f8f6f9;
|
background: rgba(248, 246, 249, 0.05);
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1103,7 +1130,7 @@ body > #demo-frame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.notification__version {
|
.notification__version {
|
||||||
background: #ff8c00;
|
background: #af6204;
|
||||||
color: white;
|
color: white;
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
@@ -1174,7 +1201,7 @@ body > #demo-frame {
|
|||||||
|
|
||||||
.dropdown__menu > li.selected > a,
|
.dropdown__menu > li.selected > a,
|
||||||
.dropdown__menu > li > a:hover {
|
.dropdown__menu > li > a:hover {
|
||||||
background: var(--color-sidebar);
|
background: var(--color-popup);
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1257,11 +1284,9 @@ body > #demo-frame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.onboard-step {
|
.onboard-step {
|
||||||
background: #f7f2f1;
|
|
||||||
border: 1px solid #ecdede;
|
|
||||||
margin: 15px;
|
margin: 15px;
|
||||||
padding: 20px 30px;
|
padding: 20px 30px;
|
||||||
background-color: white;
|
background-color: rgba(255, 255, 255, 0.1);
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
box-shadow: 0 16px 22px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 16px 22px rgba(0, 0, 0, 0.1);
|
||||||
flex: 1;
|
flex: 1;
|
||||||
@@ -1383,7 +1408,7 @@ body > #demo-frame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.kbd-shortcut__keys {
|
.kbd-shortcut__keys {
|
||||||
background: rgba(0, 0, 0, 0.1);
|
background: rgba(0, 0, 0, 0.3);
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
padding: 3px 8px;
|
padding: 3px 8px;
|
||||||
margin-right: 5px;
|
margin-right: 5px;
|
||||||
@@ -1434,7 +1459,7 @@ body > #demo-frame {
|
|||||||
.social-login-btn--google {
|
.social-login-btn--google {
|
||||||
background: white;
|
background: white;
|
||||||
border: 2px solid currentColor;
|
border: 2px solid currentColor;
|
||||||
color: inherit;
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
body.is-logged-in .hide-on-login,
|
body.is-logged-in .hide-on-login,
|
||||||
@@ -1476,12 +1501,12 @@ body:not(.is-app) .show-when-app {
|
|||||||
border: 1px #aaa solid;
|
border: 1px #aaa solid;
|
||||||
padding: 0 5px;
|
padding: 0 5px;
|
||||||
border-style: dashed;
|
border-style: dashed;
|
||||||
color: #333;
|
color: #f7f7f7;
|
||||||
}
|
}
|
||||||
|
|
||||||
.help-text {
|
.help-text {
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
color: #616465;
|
color: rgba(255, 255, 255, 0.5);
|
||||||
}
|
}
|
||||||
|
|
||||||
.social-login-btn:after,
|
.social-login-btn:after,
|
||||||
@@ -1506,6 +1531,32 @@ body:not(.is-app) .show-when-app {
|
|||||||
visibility: visible;
|
visibility: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.footer__js13k-days-left {
|
||||||
|
padding: 1px 9px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
background: #b12a34;
|
||||||
|
color: white;
|
||||||
|
border-radius: 3px;
|
||||||
|
letter-spacing: 0.7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer__js13k-code-size {
|
||||||
|
margin-left: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.js13k__dropdown {
|
||||||
|
position: fixed;
|
||||||
|
display: inline-block;
|
||||||
|
background: var(--color-popup);
|
||||||
|
color: var(--color-text);
|
||||||
|
bottom: 35px;
|
||||||
|
padding: 16px;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 -7px 13px 2px rgba(0, 0, 0, 0.2);
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -115px;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 600px) {
|
@media screen and (max-width: 600px) {
|
||||||
body {
|
body {
|
||||||
font-size: 70%;
|
font-size: 70%;
|
||||||
|
@@ -44,7 +44,11 @@ function saveScreenshot(dataURI) {
|
|||||||
'/temporary/' +
|
'/temporary/' +
|
||||||
fileName;
|
fileName;
|
||||||
|
|
||||||
chrome.downloads.download(
|
// HACK: because chrome.downloads isn't working on optional permissions
|
||||||
|
// anymore.
|
||||||
|
return window.open(filePath);
|
||||||
|
|
||||||
|
/* chrome.downloads.download(
|
||||||
{
|
{
|
||||||
url: filePath
|
url: filePath
|
||||||
},
|
},
|
||||||
@@ -55,7 +59,7 @@ function saveScreenshot(dataURI) {
|
|||||||
window.open(filePath);
|
window.open(filePath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
); */
|
||||||
}
|
}
|
||||||
|
|
||||||
function errorHandler(e) {
|
function errorHandler(e) {
|
||||||
|
17
src/templateList.js
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
export default [
|
||||||
|
{
|
||||||
|
id: 'preact',
|
||||||
|
title: 'Preact',
|
||||||
|
img: 'assets/preact-logo.svg'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'react',
|
||||||
|
title: 'React',
|
||||||
|
img: 'assets/react-logo.svg'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'kontra-game-engine',
|
||||||
|
title: 'Kontra Game Engine',
|
||||||
|
img: 'assets/html5-logo.svg'
|
||||||
|
}
|
||||||
|
];
|
18
src/templates/template-kontra-game-engine.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"title": "Kontra HTML5 game engine template",
|
||||||
|
"html": " <canvas></canvas>",
|
||||||
|
"css": "",
|
||||||
|
"js":
|
||||||
|
"// Learn More here -> https://straker.github.io/kontra/getting-started\nkontra.init();\n\nvar sprite = kontra.sprite({\n x: 100, // starting x,y position of the sprite\n y: 80,\n color: '#bad455', // fill color of the sprite rectangle\n width: 20, // width and height of the sprite rectangle\n height: 40,\n dx: 2, // move the sprite 2px to the right every frame\n});\n\nvar loop = kontra.gameLoop({ // create the main game loop\n update: function() { // update the game state\n sprite.update();\n\n // wrap the sprites position when it reaches\n // the edge of the screen\n if (sprite.x > kontra.canvas.width) {\n sprite.x = -sprite.width;\n }\n },\n render: function() { // render the game state\n sprite.render();\n }\n});\n\nloop.start(); // start the game",
|
||||||
|
"externalLibs": {
|
||||||
|
"js":
|
||||||
|
"https://unpkg.com/kontra@3.3.0/dist/core.js\nhttps://unpkg.com/kontra@3.3.0/dist/sprite.js\nhttps://unpkg.com/kontra@3.3.0/dist/gameLoop.js\nhttps://unpkg.com/kontra@3.3.0/dist/pointer.js",
|
||||||
|
"css": ""
|
||||||
|
},
|
||||||
|
"htmlMode": "html",
|
||||||
|
"cssMode": "css",
|
||||||
|
"jsMode": "js",
|
||||||
|
"sizes": ["33px", "33px", "calc(100% - 66px)"],
|
||||||
|
"mainSizes": [50, 50],
|
||||||
|
"layoutMode": 1
|
||||||
|
}
|
16
src/templates/template-preact.json
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"title": "Preact template",
|
||||||
|
"externalLibs": {
|
||||||
|
"js": "\nhttps://cdnjs.cloudflare.com/ajax/libs/preact/8.2.9/preact.min.js",
|
||||||
|
"css": ""
|
||||||
|
},
|
||||||
|
"sizes": ["calc(30% - 3px)", "30px", "calc(70% - 3px)"],
|
||||||
|
"mainSizes": [68.1051, 31.6949],
|
||||||
|
"htmlMode": "html",
|
||||||
|
"cssMode": "css",
|
||||||
|
"jsMode": "es6",
|
||||||
|
"layoutMode": 1,
|
||||||
|
"js":
|
||||||
|
"\nconst { h, Component, render, createElement } = window.preact;\nconst React = {createElement}\n\nclass App extends Component {\n constructor() {\n super();\n this.message = 'World';\n }\n render() {\n return (<div>Hello {this.message}</div>)\n }\n}\nrender(<App/>, window.root)\n\n",
|
||||||
|
"html": "<div id=\"root\"></div>\n"
|
||||||
|
}
|
18
src/templates/template-react.json
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{
|
||||||
|
"title": "React template",
|
||||||
|
"externalLibs": {
|
||||||
|
"js":
|
||||||
|
"\nhttps://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react.min.js\nhttps://cdnjs.cloudflare.com/ajax/libs/react/15.3.1/react-dom.min.js",
|
||||||
|
"css": ""
|
||||||
|
},
|
||||||
|
"updatedOn": 1531063870556,
|
||||||
|
"sizes": ["", "calc(17.4842% - 6px)", "calc(49.1221% - 3px)"],
|
||||||
|
"mainSizes": [68.1051, 31.6949],
|
||||||
|
"htmlMode": "html",
|
||||||
|
"cssMode": "css",
|
||||||
|
"jsMode": "es6",
|
||||||
|
"layoutMode": 1,
|
||||||
|
"js":
|
||||||
|
"class App extends React.Component {\n constructor() {\n super();\n this.message = 'World';\n }\n render() {\n return (<h1>Hello {this.message}</h1>);\n }\n}\nReactDOM.render(<App/>, window.root);\n\n\n",
|
||||||
|
"html": "<div id=\"root\"></div>\n"
|
||||||
|
}
|
@@ -6,7 +6,7 @@ import { shallow, deep } from 'preact-render-spy';
|
|||||||
|
|
||||||
describe('Initial Test of the Footer', () => {
|
describe('Initial Test of the Footer', () => {
|
||||||
test('Footer renders 1 link with an ID of notificationsBtn', () => {
|
test('Footer renders 1 link with an ID of notificationsBtn', () => {
|
||||||
const context = shallow(<Footer />);
|
const context = shallow(<Footer prefs={{}} />);
|
||||||
expect(context.find('#notificationsBtn').exists()).toBeTruthy();
|
expect(context.find('#notificationsBtn').exists()).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
29
src/utils.js
@@ -212,9 +212,13 @@ export function downloadFile(fileName, blob) {
|
|||||||
a.click();
|
a.click();
|
||||||
a.remove();
|
a.remove();
|
||||||
}
|
}
|
||||||
if (window.IS_EXTENSION) {
|
|
||||||
chrome.downloads.download(
|
// HACK: because chrome.downloads isn't working on optional permissions
|
||||||
{
|
// anymore.
|
||||||
|
downloadWithAnchor();
|
||||||
|
|
||||||
|
/* if (false && window.IS_EXTENSION) {
|
||||||
|
chrome.downloads.download({
|
||||||
url: window.URL.createObjectURL(blob),
|
url: window.URL.createObjectURL(blob),
|
||||||
filename: fileName,
|
filename: fileName,
|
||||||
saveAs: true
|
saveAs: true
|
||||||
@@ -228,7 +232,7 @@ export function downloadFile(fileName, blob) {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
downloadWithAnchor();
|
downloadWithAnchor();
|
||||||
}
|
} */
|
||||||
}
|
}
|
||||||
|
|
||||||
export function writeFile(name, blob, cb) {
|
export function writeFile(name, blob, cb) {
|
||||||
@@ -345,7 +349,9 @@ export function getCompleteHtml(html, css, js, item, isForExport) {
|
|||||||
'<script src="' +
|
'<script src="' +
|
||||||
(chrome.extension
|
(chrome.extension
|
||||||
? chrome.extension.getURL('lib/screenlog.js')
|
? chrome.extension.getURL('lib/screenlog.js')
|
||||||
: `${location.origin}${BASE_PATH}/lib/screenlog.js`) +
|
: `${location.origin}${
|
||||||
|
window.DEBUG ? '' : BASE_PATH
|
||||||
|
}/lib/screenlog.js`) +
|
||||||
'"></script>';
|
'"></script>';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -378,7 +384,7 @@ export function saveAsHtml(item) {
|
|||||||
var htmlPromise = computeHtml(item.html, item.htmlMode);
|
var htmlPromise = computeHtml(item.html, item.htmlMode);
|
||||||
var cssPromise = computeCss(item.css, item.cssMode);
|
var cssPromise = computeCss(item.css, item.cssMode);
|
||||||
var jsPromise = computeJs(item.js, item.jsMode, false);
|
var jsPromise = computeJs(item.js, item.jsMode, false);
|
||||||
Promise.all([htmlPromise, cssPromise, jsPromise]).then(function(result) {
|
Promise.all([htmlPromise, cssPromise, jsPromise]).then(result => {
|
||||||
var html = result[0].code,
|
var html = result[0].code,
|
||||||
css = result[1].code,
|
css = result[1].code,
|
||||||
js = result[2].code;
|
js = result[2].code;
|
||||||
@@ -443,6 +449,17 @@ export function handleDownloadsPermission() {
|
|||||||
return d.promise;
|
return d.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the filename from a passed url.
|
||||||
|
* http://a.com/path/file.png -> file.png
|
||||||
|
*/
|
||||||
|
export function getFilenameFromUrl(url) {
|
||||||
|
if (!url) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
return url.match(/\/([^/]*)$/)[1];
|
||||||
|
}
|
||||||
|
|
||||||
if (window.IS_EXTENSION) {
|
if (window.IS_EXTENSION) {
|
||||||
document.body.classList.add('is-extension');
|
document.body.classList.add('is-extension');
|
||||||
} else {
|
} else {
|
||||||
|
97
yarn.lock
@@ -1136,7 +1136,11 @@ babel-plugin-syntax-export-extensions@^6.8.0:
|
|||||||
version "6.13.0"
|
version "6.13.0"
|
||||||
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz#70a1484f0f9089a4e84ad44bac353c95b9b12721"
|
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz#70a1484f0f9089a4e84ad44bac353c95b9b12721"
|
||||||
|
|
||||||
babel-plugin-syntax-jsx@^6.0.0, babel-plugin-syntax-jsx@^6.8.0:
|
babel-plugin-syntax-flow@^6.18.0:
|
||||||
|
version "6.18.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d"
|
||||||
|
|
||||||
|
babel-plugin-syntax-jsx@^6.0.0, babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0:
|
||||||
version "6.18.0"
|
version "6.18.0"
|
||||||
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946"
|
resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946"
|
||||||
|
|
||||||
@@ -1356,6 +1360,13 @@ babel-plugin-transform-export-extensions@^6.22.0:
|
|||||||
babel-plugin-syntax-export-extensions "^6.8.0"
|
babel-plugin-syntax-export-extensions "^6.8.0"
|
||||||
babel-runtime "^6.22.0"
|
babel-runtime "^6.22.0"
|
||||||
|
|
||||||
|
babel-plugin-transform-flow-strip-types@^6.22.0:
|
||||||
|
version "6.22.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf"
|
||||||
|
dependencies:
|
||||||
|
babel-plugin-syntax-flow "^6.18.0"
|
||||||
|
babel-runtime "^6.22.0"
|
||||||
|
|
||||||
babel-plugin-transform-inline-consecutive-adds@^0.2.0:
|
babel-plugin-transform-inline-consecutive-adds@^0.2.0:
|
||||||
version "0.2.0"
|
version "0.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.2.0.tgz#15dae78921057f4004f8eafd79e15ddc5f12f426"
|
resolved "https://registry.yarnpkg.com/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.2.0.tgz#15dae78921057f4004f8eafd79e15ddc5f12f426"
|
||||||
@@ -1397,6 +1408,26 @@ babel-plugin-transform-react-constant-elements@^6.23.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
babel-runtime "^6.22.0"
|
babel-runtime "^6.22.0"
|
||||||
|
|
||||||
|
babel-plugin-transform-react-display-name@^6.23.0:
|
||||||
|
version "6.25.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz#67e2bf1f1e9c93ab08db96792e05392bf2cc28d1"
|
||||||
|
dependencies:
|
||||||
|
babel-runtime "^6.22.0"
|
||||||
|
|
||||||
|
babel-plugin-transform-react-jsx-self@^6.22.0:
|
||||||
|
version "6.22.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz#df6d80a9da2612a121e6ddd7558bcbecf06e636e"
|
||||||
|
dependencies:
|
||||||
|
babel-plugin-syntax-jsx "^6.8.0"
|
||||||
|
babel-runtime "^6.22.0"
|
||||||
|
|
||||||
|
babel-plugin-transform-react-jsx-source@^6.22.0:
|
||||||
|
version "6.22.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz#66ac12153f5cd2d17b3c19268f4bf0197f44ecd6"
|
||||||
|
dependencies:
|
||||||
|
babel-plugin-syntax-jsx "^6.8.0"
|
||||||
|
babel-runtime "^6.22.0"
|
||||||
|
|
||||||
babel-plugin-transform-react-jsx@^6.24.1:
|
babel-plugin-transform-react-jsx@^6.24.1:
|
||||||
version "6.24.1"
|
version "6.24.1"
|
||||||
resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz#840a028e7df460dfc3a2d29f0c0d91f6376e66a3"
|
resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz#840a028e7df460dfc3a2d29f0c0d91f6376e66a3"
|
||||||
@@ -1456,7 +1487,7 @@ babel-polyfill@^6.2.0:
|
|||||||
core-js "^2.5.0"
|
core-js "^2.5.0"
|
||||||
regenerator-runtime "^0.10.5"
|
regenerator-runtime "^0.10.5"
|
||||||
|
|
||||||
babel-preset-env@^1.3.3:
|
babel-preset-env@^1.3.3, babel-preset-env@^1.7.0:
|
||||||
version "1.7.0"
|
version "1.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a"
|
resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a"
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -1491,6 +1522,12 @@ babel-preset-env@^1.3.3:
|
|||||||
invariant "^2.2.2"
|
invariant "^2.2.2"
|
||||||
semver "^5.3.0"
|
semver "^5.3.0"
|
||||||
|
|
||||||
|
babel-preset-flow@^6.23.0:
|
||||||
|
version "6.23.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz#e71218887085ae9a24b5be4169affb599816c49d"
|
||||||
|
dependencies:
|
||||||
|
babel-plugin-transform-flow-strip-types "^6.22.0"
|
||||||
|
|
||||||
babel-preset-jest@^21.2.0:
|
babel-preset-jest@^21.2.0:
|
||||||
version "21.2.0"
|
version "21.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-21.2.0.tgz#ff9d2bce08abd98e8a36d9a8a5189b9173b85638"
|
resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-21.2.0.tgz#ff9d2bce08abd98e8a36d9a8a5189b9173b85638"
|
||||||
@@ -1526,6 +1563,17 @@ babel-preset-minify@^0.2.0:
|
|||||||
babel-plugin-transform-undefined-to-void "^6.8.3"
|
babel-plugin-transform-undefined-to-void "^6.8.3"
|
||||||
lodash.isplainobject "^4.0.6"
|
lodash.isplainobject "^4.0.6"
|
||||||
|
|
||||||
|
babel-preset-react@^6.24.1:
|
||||||
|
version "6.24.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/babel-preset-react/-/babel-preset-react-6.24.1.tgz#ba69dfaea45fc3ec639b6a4ecea6e17702c91380"
|
||||||
|
dependencies:
|
||||||
|
babel-plugin-syntax-jsx "^6.3.13"
|
||||||
|
babel-plugin-transform-react-display-name "^6.23.0"
|
||||||
|
babel-plugin-transform-react-jsx "^6.24.1"
|
||||||
|
babel-plugin-transform-react-jsx-self "^6.22.0"
|
||||||
|
babel-plugin-transform-react-jsx-source "^6.22.0"
|
||||||
|
babel-preset-flow "^6.23.0"
|
||||||
|
|
||||||
babel-register@^6.24.1, babel-register@^6.26.0:
|
babel-register@^6.24.1, babel-register@^6.26.0:
|
||||||
version "6.26.0"
|
version "6.26.0"
|
||||||
resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071"
|
resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071"
|
||||||
@@ -2467,6 +2515,10 @@ core-js@^2.4.0, core-js@^2.5.0:
|
|||||||
version "2.5.7"
|
version "2.5.7"
|
||||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e"
|
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e"
|
||||||
|
|
||||||
|
core-js@~2.3.0:
|
||||||
|
version "2.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.3.0.tgz#fab83fbb0b2d8dc85fa636c4b9d34c75420c6d65"
|
||||||
|
|
||||||
core-util-is@1.0.2, core-util-is@~1.0.0:
|
core-util-is@1.0.2, core-util-is@~1.0.0:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||||
@@ -3242,6 +3294,10 @@ es6-promise@^4.0.5:
|
|||||||
version "4.2.4"
|
version "4.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.4.tgz#dc4221c2b16518760bd8c39a52d8f356fc00ed29"
|
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.4.tgz#dc4221c2b16518760bd8c39a52d8f356fc00ed29"
|
||||||
|
|
||||||
|
es6-promise@~3.0.2:
|
||||||
|
version "3.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-3.0.2.tgz#010d5858423a5f118979665f46486a95c6ee2bb6"
|
||||||
|
|
||||||
es6-set@~0.1.5:
|
es6-set@~0.1.5:
|
||||||
version "0.1.5"
|
version "0.1.5"
|
||||||
resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1"
|
resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1"
|
||||||
@@ -4812,6 +4868,10 @@ ignore@^3.3.3, ignore@^3.3.5:
|
|||||||
version "3.3.8"
|
version "3.3.8"
|
||||||
resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.8.tgz#3f8e9c35d38708a3a7e0e9abb6c73e7ee7707b2b"
|
resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.8.tgz#3f8e9c35d38708a3a7e0e9abb6c73e7ee7707b2b"
|
||||||
|
|
||||||
|
immediate@~3.0.5:
|
||||||
|
version "3.0.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b"
|
||||||
|
|
||||||
immutability-helper@^2.1.2:
|
immutability-helper@^2.1.2:
|
||||||
version "2.7.0"
|
version "2.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/immutability-helper/-/immutability-helper-2.7.0.tgz#4ea9916cc8f45142ec3e3f0fce75fa5d66fa1b38"
|
resolved "https://registry.yarnpkg.com/immutability-helper/-/immutability-helper-2.7.0.tgz#4ea9916cc8f45142ec3e3f0fce75fa5d66fa1b38"
|
||||||
@@ -5752,6 +5812,16 @@ jsx-ast-utils@^2.0.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
array-includes "^3.0.3"
|
array-includes "^3.0.3"
|
||||||
|
|
||||||
|
jszip@^3.1.5:
|
||||||
|
version "3.1.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.1.5.tgz#e3c2a6c6d706ac6e603314036d43cd40beefdf37"
|
||||||
|
dependencies:
|
||||||
|
core-js "~2.3.0"
|
||||||
|
es6-promise "~3.0.2"
|
||||||
|
lie "~3.1.0"
|
||||||
|
pako "~1.0.2"
|
||||||
|
readable-stream "~2.0.6"
|
||||||
|
|
||||||
killable@^1.0.0:
|
killable@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.0.tgz#da8b84bd47de5395878f95d64d02f2449fe05e6b"
|
resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.0.tgz#da8b84bd47de5395878f95d64d02f2449fe05e6b"
|
||||||
@@ -5823,6 +5893,12 @@ levn@^0.3.0, levn@~0.3.0:
|
|||||||
prelude-ls "~1.1.2"
|
prelude-ls "~1.1.2"
|
||||||
type-check "~0.3.2"
|
type-check "~0.3.2"
|
||||||
|
|
||||||
|
lie@~3.1.0:
|
||||||
|
version "3.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e"
|
||||||
|
dependencies:
|
||||||
|
immediate "~3.0.5"
|
||||||
|
|
||||||
liftoff@^2.1.0:
|
liftoff@^2.1.0:
|
||||||
version "2.5.0"
|
version "2.5.0"
|
||||||
resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.5.0.tgz#2009291bb31cea861bbf10a7c15a28caf75c31ec"
|
resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.5.0.tgz#2009291bb31cea861bbf10a7c15a28caf75c31ec"
|
||||||
@@ -6993,7 +7069,7 @@ package-json@^4.0.0:
|
|||||||
registry-url "^3.0.3"
|
registry-url "^3.0.3"
|
||||||
semver "^5.1.0"
|
semver "^5.1.0"
|
||||||
|
|
||||||
pako@~1.0.5:
|
pako@~1.0.2, pako@~1.0.5:
|
||||||
version "1.0.6"
|
version "1.0.6"
|
||||||
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258"
|
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258"
|
||||||
|
|
||||||
@@ -7694,6 +7770,10 @@ process-nextick-args@^2.0.0, process-nextick-args@~2.0.0:
|
|||||||
version "2.0.0"
|
version "2.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"
|
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa"
|
||||||
|
|
||||||
|
process-nextick-args@~1.0.6:
|
||||||
|
version "1.0.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
|
||||||
|
|
||||||
process@^0.11.10:
|
process@^0.11.10:
|
||||||
version "0.11.10"
|
version "0.11.10"
|
||||||
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
|
resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
|
||||||
@@ -7960,6 +8040,17 @@ readable-stream@~1.1.9:
|
|||||||
isarray "0.0.1"
|
isarray "0.0.1"
|
||||||
string_decoder "~0.10.x"
|
string_decoder "~0.10.x"
|
||||||
|
|
||||||
|
readable-stream@~2.0.6:
|
||||||
|
version "2.0.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e"
|
||||||
|
dependencies:
|
||||||
|
core-util-is "~1.0.0"
|
||||||
|
inherits "~2.0.1"
|
||||||
|
isarray "~1.0.0"
|
||||||
|
process-nextick-args "~1.0.6"
|
||||||
|
string_decoder "~0.10.x"
|
||||||
|
util-deprecate "~1.0.1"
|
||||||
|
|
||||||
readdirp@^2.0.0:
|
readdirp@^2.0.0:
|
||||||
version "2.1.0"
|
version "2.1.0"
|
||||||
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78"
|
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78"
|
||||||
|