20
.travis.yml
@@ -2,16 +2,12 @@ language: node_js
|
||||
node_js:
|
||||
- '10'
|
||||
install:
|
||||
- npm i -g npm@latest
|
||||
- npm install -g eslint
|
||||
- npm install -g babel-eslint
|
||||
- npm install -g eslint-plugin-react
|
||||
- npm install -g eslint-plugin-mocha
|
||||
- npm install -g eslint-config-synacor
|
||||
- yarn add global eslint
|
||||
- yarn add global babel-eslint
|
||||
- yarn add global eslint-plugin-react
|
||||
- yarn add global eslint-plugin-mocha
|
||||
- yarn add global eslint-config-synacor
|
||||
script:
|
||||
- npm run lint
|
||||
- npm ci
|
||||
- npm run test
|
||||
cache:
|
||||
directories:
|
||||
- '$HOME/.npm'
|
||||
- yarn run lint
|
||||
- yarn run test
|
||||
cache: yarn
|
||||
|
@@ -36,13 +36,14 @@ gulp.task('copyFiles', function() {
|
||||
gulp.src('src/lib/transpilers/*').pipe(gulp.dest('app/lib/transpilers')),
|
||||
gulp.src('src/lib/screenlog.js').pipe(gulp.dest('app/lib')),
|
||||
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
|
||||
.src([
|
||||
'src/preview.html',
|
||||
'src/detached-window.js',
|
||||
'src/icon-48.png',
|
||||
'src/icon-128.png',
|
||||
'src/patreon.png',
|
||||
'manifest.json'
|
||||
])
|
||||
.pipe(gulp.dest('app')),
|
||||
|
21667
package-lock.json
generated
@@ -61,6 +61,7 @@
|
||||
"copy-webpack-plugin": "^4.5.1",
|
||||
"esprima": "^4.0.0",
|
||||
"firebase": "^5.0.4",
|
||||
"jszip": "^3.1.5",
|
||||
"preact": "^8.2.6",
|
||||
"preact-compat": "^3.17.0",
|
||||
"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>
|
||||
|
||||
<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" />
|
||||
</svg>
|
||||
<LibraryAutoSuggest
|
||||
@@ -123,7 +123,6 @@ export default class AddLibrary extends Component {
|
||||
id="externalJsTextarea"
|
||||
cols="30"
|
||||
rows="5"
|
||||
placeholder="Put each library in new line"
|
||||
value={this.state.js}
|
||||
/>
|
||||
|
||||
@@ -136,7 +135,6 @@ export default class AddLibrary extends Component {
|
||||
id="externalCssTextarea"
|
||||
cols="30"
|
||||
rows="5"
|
||||
placeholder="Put each library in new line"
|
||||
value={this.state.css}
|
||||
/>
|
||||
</div>
|
||||
|
@@ -934,6 +934,7 @@ export default class ContentWrap extends Component {
|
||||
<use xlinkHref="#chevron-icon" />
|
||||
</svg>
|
||||
<input
|
||||
tabIndex={this.state.isConsoleOpen ? 0 : -1}
|
||||
onKeyUp={this.evalConsoleExpr.bind(this)}
|
||||
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 { 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 {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
isKeyboardShortcutsModalOpen: false
|
||||
isKeyboardShortcutsModalOpen: false,
|
||||
isJs13kDropdownOpen: false
|
||||
};
|
||||
}
|
||||
layoutBtnClickhandler(layoutId) {
|
||||
this.props.layoutBtnClickHandler(layoutId);
|
||||
}
|
||||
|
||||
js13kClickHandler() {
|
||||
// console.log(999);
|
||||
this.setState({
|
||||
isJs13kDropdownOpen: !this.state.isJs13kDropdownOpen
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<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
|
||||
onClick={this.props.saveHtmlBtnClickHandler}
|
||||
id="saveHtmlBtn"
|
||||
@@ -150,72 +314,6 @@ export default class Footer extends Component {
|
||||
</svg>
|
||||
</Button>
|
||||
</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>
|
||||
);
|
||||
}
|
||||
|
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 (
|
||||
<Portal into="body">
|
||||
<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)}
|
||||
onClick={this.onOverlayClick.bind(this)}
|
||||
>
|
||||
|
@@ -7,6 +7,8 @@ function NotificationItem({ type, children }) {
|
||||
strongTag = <strong>🔧 Bugfix</strong>;
|
||||
} else if (type === 'a11y') {
|
||||
strongTag = <strong>♿️ Accessibility</strong>;
|
||||
} else if (type === 'ui') {
|
||||
strongTag = <strong>🖥 Interface</strong>;
|
||||
}
|
||||
return (
|
||||
<li>
|
||||
@@ -101,7 +103,35 @@ export function Notifications(props) {
|
||||
<div>
|
||||
<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">
|
||||
Improper links are now buttons with proper focus indication and
|
||||
screen-reader support. Thanks{' '}
|
||||
|
@@ -1,9 +1,10 @@
|
||||
import { h, Component } from 'preact';
|
||||
import { log, getHumanDate } from '../utils';
|
||||
import { log } from '../utils';
|
||||
import { trackEvent } from '../analytics';
|
||||
import { itemService } from '../itemService';
|
||||
import { alertsService } from '../notifications';
|
||||
import { deferred } from '../deferred';
|
||||
import { ItemTile } from './ItemTile';
|
||||
|
||||
export default class SavedItemPane extends Component {
|
||||
constructor(props) {
|
||||
@@ -230,32 +231,12 @@ export default class SavedItemPane extends Component {
|
||||
<div class="mt-1">No match found.</div>
|
||||
) : null}
|
||||
{this.state.filteredItems.map(item => (
|
||||
<div
|
||||
class="js-saved-item-tile saved-item-tile"
|
||||
data-item-id={item.id}
|
||||
<ItemTile
|
||||
item={item}
|
||||
onClick={this.itemClickHandler.bind(this, item)}
|
||||
>
|
||||
<div class="saved-item-tile__btns">
|
||||
<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>
|
||||
onForkBtnClick={this.itemForkBtnClickHandler.bind(this, item)}
|
||||
onRemoveBtnClick={this.itemRemoveBtnClickHandler.bind(this, item)}
|
||||
/>
|
||||
))}
|
||||
{!this.items.length ? (
|
||||
<h2 class="opacity--30">Nothing saved here.</h2>
|
||||
|
@@ -286,6 +286,14 @@ export default class Settings extends Component {
|
||||
pref={this.props.prefs.isCodeBlastOn}
|
||||
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>
|
||||
|
||||
<hr />
|
||||
@@ -296,7 +304,7 @@ export default class Settings extends Component {
|
||||
class="line"
|
||||
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
|
||||
type="number"
|
||||
value={this.props.prefs.infiniteLoopTimeout}
|
||||
|
@@ -41,7 +41,11 @@ export function SupportDeveloperModal({ show, closeHandler }) {
|
||||
rel="noopener noreferrer"
|
||||
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">
|
||||
Make a monthly pledge on Patreon
|
||||
</h3>
|
||||
|
@@ -10,13 +10,16 @@ import SavedItemPane from './SavedItemPane.jsx';
|
||||
import AddLibrary from './AddLibrary.jsx';
|
||||
import Modal from './Modal.jsx';
|
||||
import Login from './Login.jsx';
|
||||
import { computeHtml, computeCss, computeJs } from '../computes';
|
||||
import {
|
||||
log,
|
||||
generateRandomId,
|
||||
semverCompare,
|
||||
saveAsHtml,
|
||||
handleDownloadsPermission,
|
||||
downloadFile
|
||||
downloadFile,
|
||||
getCompleteHtml,
|
||||
getFilenameFromUrl
|
||||
} from '../utils';
|
||||
import { itemService } from '../itemService';
|
||||
import '../db';
|
||||
@@ -38,7 +41,10 @@ import { Alerts } from './Alerts';
|
||||
import Portal from 'preact-portal';
|
||||
import { HelpModal } from './HelpModal';
|
||||
import { OnboardingModal } from './OnboardingModal';
|
||||
import { Js13KModal } from './Js13KModal';
|
||||
import { CreateNewModal } from './CreateNewModal';
|
||||
import { Icons } from './Icons';
|
||||
import JSZip from 'jszip';
|
||||
|
||||
if (module.hot) {
|
||||
require('preact/debug');
|
||||
@@ -55,8 +61,7 @@ export default class App extends Component {
|
||||
constructor() {
|
||||
super();
|
||||
this.AUTO_SAVE_INTERVAL = 15000; // 15 seconds
|
||||
this.state = {
|
||||
isSavedItemPaneOpen: false,
|
||||
this.modalDefaultStates = {
|
||||
isModalOpen: false,
|
||||
isAddLibraryModalOpen: false,
|
||||
isSettingsModalOpen: false,
|
||||
@@ -68,6 +73,12 @@ export default class App extends Component {
|
||||
isKeyboardShortcutsModalOpen: false,
|
||||
isAskToImportModalOpen: false,
|
||||
isOnboardModalOpen: false,
|
||||
isJs13KModalOpen: false,
|
||||
isCreateNewModalOpen: false
|
||||
};
|
||||
this.state = {
|
||||
isSavedItemPaneOpen: false,
|
||||
...this.modalDefaultStates,
|
||||
prefs: {},
|
||||
currentItem: {
|
||||
title: '',
|
||||
@@ -96,7 +107,8 @@ export default class App extends Component {
|
||||
lightVersion: false,
|
||||
lineWrap: true,
|
||||
infiniteLoopTimeout: 1000,
|
||||
layoutMode: 2
|
||||
layoutMode: 2,
|
||||
isJs13kModeOn: false
|
||||
};
|
||||
this.prefs = {};
|
||||
|
||||
@@ -484,16 +496,7 @@ export default class App extends Component {
|
||||
}
|
||||
|
||||
this.setState({
|
||||
isAddLibraryModalOpen: false,
|
||||
isSettingsModalOpen: false,
|
||||
isHelpModalOpen: false,
|
||||
isNotificationsModalOpen: false,
|
||||
isLoginModalOpen: false,
|
||||
isProfileModalOpen: false,
|
||||
isSupportDeveloperModalOpen: false,
|
||||
isKeyboardShortcutsModalOpen: false,
|
||||
isAskToImportModalOpen: false,
|
||||
isOnboardModalOpen: false
|
||||
...this.modalDefaultStates
|
||||
});
|
||||
}
|
||||
onExternalLibChange(newValues) {
|
||||
@@ -697,6 +700,9 @@ export default class App extends Component {
|
||||
});
|
||||
}
|
||||
}
|
||||
if (this.state.prefs.isJs13kModeOn) {
|
||||
this.calculateCodeSize();
|
||||
}
|
||||
}
|
||||
onCodeSettingsChange(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?'
|
||||
);
|
||||
if (shouldDiscard) {
|
||||
this.createNewItem();
|
||||
this.setState({
|
||||
isCreateNewModalOpen: true
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.createNewItem();
|
||||
this.setState({
|
||||
isCreateNewModalOpen: true
|
||||
});
|
||||
}
|
||||
}
|
||||
openBtnClickHandler() {
|
||||
@@ -973,6 +983,160 @@ export default class App extends Component {
|
||||
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() {
|
||||
return (
|
||||
<div>
|
||||
@@ -1006,6 +1170,7 @@ export default class App extends Component {
|
||||
/>
|
||||
<div class="global-console-container" id="globalConsoleContainerEl" />
|
||||
<Footer
|
||||
prefs={this.state.prefs}
|
||||
layoutBtnClickHandler={this.layoutBtnClickHandler.bind(this)}
|
||||
helpBtnClickHandler={() => this.setState({ isHelpModalOpen: true })}
|
||||
settingsBtnClickHandler={() =>
|
||||
@@ -1028,7 +1193,12 @@ export default class App extends Component {
|
||||
screenshotBtnClickHandler={this.screenshotBtnClickHandler.bind(
|
||||
this
|
||||
)}
|
||||
onJs13KHelpBtnClick={this.js13KHelpBtnClickHandler.bind(this)}
|
||||
onJs13KDownloadBtnClick={this.js13KDownloadBtnClickHandler.bind(
|
||||
this
|
||||
)}
|
||||
hasUnseenChangelog={this.state.hasUnseenChangelog}
|
||||
codeSize={this.state.codeSize}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -1145,6 +1315,18 @@ export default class App extends Component {
|
||||
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">
|
||||
<div
|
||||
class="modal-overlay"
|
||||
|
131
src/style.css
@@ -1,8 +1,10 @@
|
||||
:root {
|
||||
--color-text: #d4cde9;
|
||||
--color-bg: #252637;
|
||||
--color-sidebar: #3a2b63;
|
||||
--color-popup: #3a2b63;
|
||||
--code-font-size: 16px;
|
||||
--color-button: #0074d9;
|
||||
--color-button: #d3a447;
|
||||
--color-focus-outline: #d3a447;
|
||||
}
|
||||
|
||||
body {
|
||||
@@ -23,12 +25,34 @@ h1 {
|
||||
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 {
|
||||
text-decoration: none;
|
||||
color: #d61237;
|
||||
color: #f7ae2d;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
p {
|
||||
line-height: 1.65;
|
||||
}
|
||||
@@ -131,7 +155,7 @@ button {
|
||||
}
|
||||
|
||||
.support-link {
|
||||
color: #d61237;
|
||||
color: #f7ae2d;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 600px) {
|
||||
@@ -158,7 +182,8 @@ button {
|
||||
hr {
|
||||
background: 0;
|
||||
border: 0;
|
||||
border-bottom: 1px solid #dedede;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.12);
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
label {
|
||||
@@ -192,14 +217,6 @@ a > svg {
|
||||
fill: rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
select,
|
||||
input[type='text'],
|
||||
input[type='number'],
|
||||
textarea {
|
||||
padding: 3px 5px;
|
||||
font-size: inherit;
|
||||
}
|
||||
|
||||
.hidden-select {
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
@@ -213,6 +230,7 @@ textarea {
|
||||
display: inline-block;
|
||||
color: var(--color-button);
|
||||
font-size: inherit;
|
||||
background: transparent;
|
||||
border: 3px solid var(--color-button);
|
||||
border-radius: 5px;
|
||||
padding: 9px 15px;
|
||||
@@ -244,9 +262,9 @@ textarea {
|
||||
box-shadow: 0 5px 5px 0 rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
|
||||
[class*='btn']:focus {
|
||||
*:focus {
|
||||
outline-width: 4px;
|
||||
outline-color: #b76b29;
|
||||
outline-color: var(--color-button);
|
||||
outline-style: solid;
|
||||
outline-offset: 1px;
|
||||
}
|
||||
@@ -573,6 +591,8 @@ body > #demo-frame {
|
||||
}
|
||||
|
||||
.footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
/* Because .console is 6 */
|
||||
z-index: 6;
|
||||
}
|
||||
@@ -587,7 +607,8 @@ body > #demo-frame {
|
||||
.btn--dark,
|
||||
.main-header__btn-wrap > button {
|
||||
box-sizing: content-box;
|
||||
font-size: 0.8em;
|
||||
text-transform: uppercase;
|
||||
font-size: 12px;
|
||||
font-weight: bold;
|
||||
line-height: 20px;
|
||||
height: 20px;
|
||||
@@ -605,7 +626,6 @@ body > #demo-frame {
|
||||
);
|
||||
/*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;
|
||||
}
|
||||
|
||||
.btn--dark > svg {
|
||||
@@ -721,19 +741,20 @@ body > #demo-frame {
|
||||
|
||||
.item-title-input {
|
||||
background: none;
|
||||
border: 0;
|
||||
border: 0 !important;
|
||||
color: rgba(255, 255, 255, 0.6);
|
||||
flex: 1;
|
||||
padding: 3px 5px !important;
|
||||
}
|
||||
|
||||
.search-input {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
padding: 10px 20px;
|
||||
border: 0;
|
||||
/* background: rgba(255, 255, 255, 0.1); */
|
||||
/* padding: 10px 20px; */
|
||||
/* border: 0; */
|
||||
width: 100%;
|
||||
font-size: 16px;
|
||||
color: white;
|
||||
border-radius: 4px;
|
||||
/* color: white; */
|
||||
/* border-radius: 4px; */
|
||||
}
|
||||
|
||||
.modal {
|
||||
@@ -787,10 +808,10 @@ body > #demo-frame {
|
||||
}
|
||||
|
||||
.modal__content {
|
||||
background: #fdfdfd;
|
||||
color: #444;
|
||||
background: var(--color-popup);
|
||||
color: var(--color-text);
|
||||
position: relative;
|
||||
border-radius: 8px;
|
||||
border-radius: 5px;
|
||||
opacity: 0;
|
||||
padding: 3em;
|
||||
font-size: 1.1em;
|
||||
@@ -852,7 +873,8 @@ body > #demo-frame {
|
||||
}
|
||||
|
||||
.pledge-modal .modal__content,
|
||||
.ask-to-import-modal .modal__content {
|
||||
.ask-to-import-modal .modal__content,
|
||||
.modal--small .modal__content {
|
||||
max-width: 800px;
|
||||
}
|
||||
|
||||
@@ -868,7 +890,7 @@ body > #demo-frame {
|
||||
width: 450px;
|
||||
padding: 20px 30px;
|
||||
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-property: transform;
|
||||
will-change: transform;
|
||||
@@ -1011,6 +1033,10 @@ body > #demo-frame {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.saved-item-tile__img {
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.saved-item-tile__btn {
|
||||
padding: 7px 10px;
|
||||
color: rgba(255, 255, 255, 0.3);
|
||||
@@ -1028,11 +1054,12 @@ body > #demo-frame {
|
||||
.saved-item-tile__title {
|
||||
pointer-events: none;
|
||||
font-size: 1.4em;
|
||||
margin: 0 0 1em 0;
|
||||
margin: 0;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.saved-item-tile__meta {
|
||||
margin-top: 8px;
|
||||
pointer-events: none;
|
||||
opacity: 0.3;
|
||||
}
|
||||
@@ -1087,10 +1114,10 @@ body > #demo-frame {
|
||||
}
|
||||
|
||||
.notification {
|
||||
border: 1px solid #f1f1f1;
|
||||
/* border: 1px solid #f1f1f1; */
|
||||
border-radius: 5px;
|
||||
padding: 20px;
|
||||
background: #f8f6f9;
|
||||
background: rgba(248, 246, 249, 0.05);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
@@ -1103,7 +1130,7 @@ body > #demo-frame {
|
||||
}
|
||||
|
||||
.notification__version {
|
||||
background: #ff8c00;
|
||||
background: #af6204;
|
||||
color: white;
|
||||
padding: 3px;
|
||||
border-radius: 5px;
|
||||
@@ -1174,7 +1201,7 @@ body > #demo-frame {
|
||||
|
||||
.dropdown__menu > li.selected > a,
|
||||
.dropdown__menu > li > a:hover {
|
||||
background: var(--color-sidebar);
|
||||
background: var(--color-popup);
|
||||
color: white;
|
||||
}
|
||||
|
||||
@@ -1257,11 +1284,9 @@ body > #demo-frame {
|
||||
}
|
||||
|
||||
.onboard-step {
|
||||
background: #f7f2f1;
|
||||
border: 1px solid #ecdede;
|
||||
margin: 15px;
|
||||
padding: 20px 30px;
|
||||
background-color: white;
|
||||
background-color: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 10px;
|
||||
box-shadow: 0 16px 22px rgba(0, 0, 0, 0.1);
|
||||
flex: 1;
|
||||
@@ -1383,7 +1408,7 @@ body > #demo-frame {
|
||||
}
|
||||
|
||||
.kbd-shortcut__keys {
|
||||
background: rgba(0, 0, 0, 0.1);
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
border-radius: 3px;
|
||||
padding: 3px 8px;
|
||||
margin-right: 5px;
|
||||
@@ -1434,7 +1459,7 @@ body > #demo-frame {
|
||||
.social-login-btn--google {
|
||||
background: white;
|
||||
border: 2px solid currentColor;
|
||||
color: inherit;
|
||||
color: black;
|
||||
}
|
||||
|
||||
body.is-logged-in .hide-on-login,
|
||||
@@ -1476,12 +1501,12 @@ body:not(.is-app) .show-when-app {
|
||||
border: 1px #aaa solid;
|
||||
padding: 0 5px;
|
||||
border-style: dashed;
|
||||
color: #333;
|
||||
color: #f7f7f7;
|
||||
}
|
||||
|
||||
.help-text {
|
||||
font-size: 0.9em;
|
||||
color: #616465;
|
||||
color: rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
.social-login-btn:after,
|
||||
@@ -1506,6 +1531,32 @@ body:not(.is-app) .show-when-app {
|
||||
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) {
|
||||
body {
|
||||
font-size: 70%;
|
||||
|
@@ -44,7 +44,11 @@ function saveScreenshot(dataURI) {
|
||||
'/temporary/' +
|
||||
fileName;
|
||||
|
||||
chrome.downloads.download(
|
||||
// HACK: because chrome.downloads isn't working on optional permissions
|
||||
// anymore.
|
||||
return window.open(filePath);
|
||||
|
||||
/* chrome.downloads.download(
|
||||
{
|
||||
url: filePath
|
||||
},
|
||||
@@ -55,7 +59,7 @@ function saveScreenshot(dataURI) {
|
||||
window.open(filePath);
|
||||
}
|
||||
}
|
||||
);
|
||||
); */
|
||||
}
|
||||
|
||||
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', () => {
|
||||
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();
|
||||
});
|
||||
});
|
||||
|
29
src/utils.js
@@ -212,9 +212,13 @@ export function downloadFile(fileName, blob) {
|
||||
a.click();
|
||||
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),
|
||||
filename: fileName,
|
||||
saveAs: true
|
||||
@@ -228,7 +232,7 @@ export function downloadFile(fileName, blob) {
|
||||
);
|
||||
} else {
|
||||
downloadWithAnchor();
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
||||
export function writeFile(name, blob, cb) {
|
||||
@@ -345,7 +349,9 @@ export function getCompleteHtml(html, css, js, item, isForExport) {
|
||||
'<script src="' +
|
||||
(chrome.extension
|
||||
? chrome.extension.getURL('lib/screenlog.js')
|
||||
: `${location.origin}${BASE_PATH}/lib/screenlog.js`) +
|
||||
: `${location.origin}${
|
||||
window.DEBUG ? '' : BASE_PATH
|
||||
}/lib/screenlog.js`) +
|
||||
'"></script>';
|
||||
}
|
||||
|
||||
@@ -378,7 +384,7 @@ export function saveAsHtml(item) {
|
||||
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]).then(function(result) {
|
||||
Promise.all([htmlPromise, cssPromise, jsPromise]).then(result => {
|
||||
var html = result[0].code,
|
||||
css = result[1].code,
|
||||
js = result[2].code;
|
||||
@@ -443,6 +449,17 @@ export function handleDownloadsPermission() {
|
||||
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) {
|
||||
document.body.classList.add('is-extension');
|
||||
} else {
|
||||
|
97
yarn.lock
@@ -1136,7 +1136,11 @@ babel-plugin-syntax-export-extensions@^6.8.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"
|
||||
|
||||
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"
|
||||
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-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:
|
||||
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"
|
||||
@@ -1397,6 +1408,26 @@ babel-plugin-transform-react-constant-elements@^6.23.0:
|
||||
dependencies:
|
||||
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:
|
||||
version "6.24.1"
|
||||
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"
|
||||
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"
|
||||
resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a"
|
||||
dependencies:
|
||||
@@ -1491,6 +1522,12 @@ babel-preset-env@^1.3.3:
|
||||
invariant "^2.2.2"
|
||||
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:
|
||||
version "21.2.0"
|
||||
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"
|
||||
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:
|
||||
version "6.26.0"
|
||||
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"
|
||||
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:
|
||||
version "1.0.2"
|
||||
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"
|
||||
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:
|
||||
version "0.1.5"
|
||||
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"
|
||||
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:
|
||||
version "2.7.0"
|
||||
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:
|
||||
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:
|
||||
version "1.0.0"
|
||||
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"
|
||||
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:
|
||||
version "2.5.0"
|
||||
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"
|
||||
semver "^5.1.0"
|
||||
|
||||
pako@~1.0.5:
|
||||
pako@~1.0.2, pako@~1.0.5:
|
||||
version "1.0.6"
|
||||
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"
|
||||
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:
|
||||
version "0.11.10"
|
||||
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"
|
||||
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:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78"
|
||||
|