mirror of
https://github.com/chinchang/web-maker.git
synced 2025-06-09 03:07:20 +02:00
misc fixes
This commit is contained in:
parent
0c128f0671
commit
15d65f30ea
16
src/auth.js
16
src/auth.js
@ -1,8 +1,6 @@
|
|||||||
import {
|
import { trackEvent } from './analytics';
|
||||||
trackEvent
|
import firebase from 'firebase/app';
|
||||||
} from './analytics';
|
import { log } from './utils';
|
||||||
|
|
||||||
import firebase from 'firebase/app'
|
|
||||||
|
|
||||||
export const auth = {
|
export const auth = {
|
||||||
logout() {
|
logout() {
|
||||||
@ -24,15 +22,15 @@ export const auth = {
|
|||||||
return firebase
|
return firebase
|
||||||
.auth()
|
.auth()
|
||||||
.signInWithPopup(provider)
|
.signInWithPopup(provider)
|
||||||
.then(function () {
|
.then(function() {
|
||||||
trackEvent('fn', 'loggedIn', providerName);
|
trackEvent('fn', 'loggedIn', providerName);
|
||||||
// Save to recommend next time
|
// Save to recommend next time
|
||||||
window.db.local.set({
|
window.db.local.set({
|
||||||
lastAuthProvider: providerName
|
lastAuthProvider: providerName
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(function (error) {
|
.catch(function(error) {
|
||||||
utils.log(error);
|
log(error);
|
||||||
if (error.code === 'auth/account-exists-with-different-credential') {
|
if (error.code === 'auth/account-exists-with-different-credential') {
|
||||||
alert(
|
alert(
|
||||||
'You have already signed up with the same email using different social login'
|
'You have already signed up with the same email using different social login'
|
||||||
@ -40,4 +38,4 @@ export const auth = {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
@ -81,7 +81,7 @@ export default class AddLibrary extends Component {
|
|||||||
<small>Powered by cdnjs</small>
|
<small>Powered by cdnjs</small>
|
||||||
</div>
|
</div>
|
||||||
<div style="margin:20px 0;">
|
<div style="margin:20px 0;">
|
||||||
Choose from popular libraries:
|
Choose from popular libraries:{' '}
|
||||||
<select
|
<select
|
||||||
name=""
|
name=""
|
||||||
id="js-add-library-select"
|
id="js-add-library-select"
|
||||||
|
@ -34,7 +34,7 @@ export function MainHeader(props) {
|
|||||||
class="flex-v-center hint--rounded hint--bottom-left"
|
class="flex-v-center hint--rounded hint--bottom-left"
|
||||||
aria-label="Add a JS/CSS library"
|
aria-label="Add a JS/CSS library"
|
||||||
>
|
>
|
||||||
Add library
|
Add library{' '}
|
||||||
<span
|
<span
|
||||||
id="js-external-lib-count"
|
id="js-external-lib-count"
|
||||||
style={`display:${props.externalLibCount ? 'inline' : 'none'}`}
|
style={`display:${props.externalLibCount ? 'inline' : 'none'}`}
|
||||||
|
@ -3,6 +3,7 @@ import { log, getHumanDate } 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';
|
||||||
|
|
||||||
export default class SavedItemPane extends Component {
|
export default class SavedItemPane extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
@ -23,6 +24,11 @@ export default class SavedItemPane extends Component {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
componentDidUpdate(prevProps) {
|
||||||
|
if (this.props.isOpen && !prevProps.isOpen) {
|
||||||
|
window.searchInput.value = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
onCloseIntent() {
|
onCloseIntent() {
|
||||||
this.props.closeHandler();
|
this.props.closeHandler();
|
||||||
}
|
}
|
||||||
@ -124,8 +130,7 @@ export default class SavedItemPane extends Component {
|
|||||||
} else {
|
} else {
|
||||||
d.resolve();
|
d.resolve();
|
||||||
}
|
}
|
||||||
// FIXME: Move from here
|
this.props.closeHandler();
|
||||||
// toggleSavedItemsPane(false);
|
|
||||||
|
|
||||||
return d.promise;
|
return d.promise;
|
||||||
}
|
}
|
||||||
@ -216,7 +221,6 @@ export default class SavedItemPane extends Component {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<input
|
<input
|
||||||
type=""
|
|
||||||
id="searchInput"
|
id="searchInput"
|
||||||
class="search-input"
|
class="search-input"
|
||||||
onInput={this.searchInputHandler.bind(this)}
|
onInput={this.searchInputHandler.bind(this)}
|
||||||
|
@ -19,7 +19,7 @@ function CheckboxSetting({
|
|||||||
checked={pref}
|
checked={pref}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
data-setting={name}
|
data-setting={name}
|
||||||
/>
|
/>{' '}
|
||||||
{label}
|
{label}
|
||||||
</label>
|
</label>
|
||||||
);
|
);
|
||||||
|
@ -234,6 +234,7 @@ export default class App extends Component {
|
|||||||
this.toggleLayout(
|
this.toggleLayout(
|
||||||
this.state.currentItem.layoutMode || this.state.prefs.layoutMode
|
this.state.currentItem.layoutMode || this.state.prefs.layoutMode
|
||||||
);
|
);
|
||||||
|
this.updateExternalLibCount();
|
||||||
this.contentWrap.refreshEditor();
|
this.contentWrap.refreshEditor();
|
||||||
}
|
}
|
||||||
// Creates a new item with passed item's contents
|
// Creates a new item with passed item's contents
|
||||||
@ -822,7 +823,9 @@ export default class App extends Component {
|
|||||||
}
|
}
|
||||||
codepenBtnClickHandler(e) {
|
codepenBtnClickHandler(e) {
|
||||||
if (this.state.currentItem.cssMode === CssModes.ACSS) {
|
if (this.state.currentItem.cssMode === CssModes.ACSS) {
|
||||||
alert("Oops! CodePen doesn't supports Atomic CSS currently.");
|
alert(
|
||||||
|
"Oops! CodePen doesn't supports Atomic CSS currently. \nHere is something you can still do -> https://medium.com/web-maker/sharing-your-atomic-css-work-on-codepen-a402001b26ab"
|
||||||
|
);
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -934,6 +937,9 @@ export default class App extends Component {
|
|||||||
editorFocusHandler(editor) {
|
editorFocusHandler(editor) {
|
||||||
this.editorWithFocus = editor;
|
this.editorWithFocus = editor;
|
||||||
}
|
}
|
||||||
|
modalOverlayClickHandler() {
|
||||||
|
this.closeAllOverlays();
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
@ -1103,7 +1109,10 @@ export default class App extends Component {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<Portal into="body">
|
<Portal into="body">
|
||||||
<div class="modal-overlay" />
|
<div
|
||||||
|
class="modal-overlay"
|
||||||
|
onClick={this.modalOverlayClickHandler.bind(this)}
|
||||||
|
/>
|
||||||
</Portal>
|
</Portal>
|
||||||
|
|
||||||
<Icons />
|
<Icons />
|
||||||
|
43
src/db.js
43
src/db.js
@ -1,13 +1,9 @@
|
|||||||
import './firebaseInit';
|
import './firebaseInit';
|
||||||
import firebase from 'firebase/app';
|
import firebase from 'firebase/app';
|
||||||
import 'firebase/firestore';
|
import 'firebase/firestore';
|
||||||
import {
|
import { deferred } from './deferred';
|
||||||
deferred
|
import { trackEvent } from './analytics';
|
||||||
} from './deferred';
|
import { log } from './utils';
|
||||||
import {
|
|
||||||
trackEvent
|
|
||||||
} from './analytics';
|
|
||||||
|
|
||||||
|
|
||||||
(() => {
|
(() => {
|
||||||
const FAUX_DELAY = 1;
|
const FAUX_DELAY = 1;
|
||||||
@ -54,7 +50,7 @@ import {
|
|||||||
if (dbPromise) {
|
if (dbPromise) {
|
||||||
return dbPromise;
|
return dbPromise;
|
||||||
}
|
}
|
||||||
utils.log('Initializing firestore');
|
log('Initializing firestore');
|
||||||
dbPromise = new Promise((resolve, reject) => {
|
dbPromise = new Promise((resolve, reject) => {
|
||||||
if (db) {
|
if (db) {
|
||||||
return resolve(db);
|
return resolve(db);
|
||||||
@ -62,17 +58,17 @@ import {
|
|||||||
return firebase
|
return firebase
|
||||||
.firestore()
|
.firestore()
|
||||||
.enablePersistence()
|
.enablePersistence()
|
||||||
.then(function () {
|
.then(function() {
|
||||||
// Initialize Cloud Firestore through firebase
|
// Initialize Cloud Firestore through firebase
|
||||||
db = firebase.firestore();
|
db = firebase.firestore();
|
||||||
// const settings = {
|
// const settings = {
|
||||||
// timestampsInSnapshots: true
|
// timestampsInSnapshots: true
|
||||||
// };
|
// };
|
||||||
// db.settings(settings);
|
// db.settings(settings);
|
||||||
utils.log('firebase db ready', db);
|
log('firebase db ready', db);
|
||||||
resolve(db);
|
resolve(db);
|
||||||
})
|
})
|
||||||
.catch(function (err) {
|
.catch(function(err) {
|
||||||
reject(err.code);
|
reject(err.code);
|
||||||
if (err.code === 'failed-precondition') {
|
if (err.code === 'failed-precondition') {
|
||||||
// Multiple tabs open, persistence can only be enabled
|
// Multiple tabs open, persistence can only be enabled
|
||||||
@ -95,7 +91,8 @@ import {
|
|||||||
const d = deferred();
|
const d = deferred();
|
||||||
// Will be chrome.storage.sync in extension environment,
|
// Will be chrome.storage.sync in extension environment,
|
||||||
// otherwise will fallback to localstorage
|
// otherwise will fallback to localstorage
|
||||||
dbSyncAlias.get({
|
dbSyncAlias.get(
|
||||||
|
{
|
||||||
lastSeenVersion: ''
|
lastSeenVersion: ''
|
||||||
},
|
},
|
||||||
result => {
|
result => {
|
||||||
@ -111,18 +108,17 @@ import {
|
|||||||
// Setting the `lastSeenVersion` in localStorage(sync for extension) always
|
// Setting the `lastSeenVersion` in localStorage(sync for extension) always
|
||||||
// because next time we need to fetch it irrespective of the user being
|
// because next time we need to fetch it irrespective of the user being
|
||||||
// logged in or out quickly from local storage.
|
// logged in or out quickly from local storage.
|
||||||
dbSyncAlias.set({
|
dbSyncAlias.set(
|
||||||
|
{
|
||||||
lastSeenVersion: version
|
lastSeenVersion: version
|
||||||
},
|
},
|
||||||
function () {}
|
function() {}
|
||||||
);
|
);
|
||||||
if (window.user) {
|
if (window.user) {
|
||||||
const remoteDb = await getDb();
|
const remoteDb = await getDb();
|
||||||
remoteDb
|
remoteDb.doc(`users/${window.user.uid}`).update({
|
||||||
.doc(`users/${window.user.uid}`)
|
lastSeenVersion: version
|
||||||
.update({
|
});
|
||||||
lastSeenVersion: version
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,9 +129,12 @@ import {
|
|||||||
.get()
|
.get()
|
||||||
.then(doc => {
|
.then(doc => {
|
||||||
if (!doc.exists)
|
if (!doc.exists)
|
||||||
return remoteDb.doc(`users/${userId}`).set({}, {
|
return remoteDb.doc(`users/${userId}`).set(
|
||||||
merge: true
|
{},
|
||||||
});
|
{
|
||||||
|
merge: true
|
||||||
|
}
|
||||||
|
);
|
||||||
const user = doc.data();
|
const user = doc.data();
|
||||||
Object.assign(window.user, user);
|
Object.assign(window.user, user);
|
||||||
return user;
|
return user;
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
import {
|
import { deferred } from './deferred';
|
||||||
deferred
|
import { log } from 'util';
|
||||||
} from './deferred';
|
|
||||||
|
|
||||||
export const itemService = {
|
export const itemService = {
|
||||||
|
|
||||||
async getItem(id) {
|
async getItem(id) {
|
||||||
var remoteDb = await window.db.getDb();
|
var remoteDb = await window.db.getDb();
|
||||||
return remoteDb
|
return remoteDb
|
||||||
@ -32,11 +30,11 @@ export const itemService = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
async getAllItems() {
|
async getAllItems() {
|
||||||
var t = Date.now()
|
var t = Date.now();
|
||||||
var d = deferred();
|
var d = deferred();
|
||||||
let itemIds = await this.getUserItemIds();
|
let itemIds = await this.getUserItemIds();
|
||||||
itemIds = Object.getOwnPropertyNames(itemIds || {});
|
itemIds = Object.getOwnPropertyNames(itemIds || {});
|
||||||
utils.log('itemids', itemIds);
|
log('itemids', itemIds);
|
||||||
|
|
||||||
if (!itemIds.length) {
|
if (!itemIds.length) {
|
||||||
d.resolve([]);
|
d.resolve([]);
|
||||||
@ -46,16 +44,19 @@ export const itemService = {
|
|||||||
remoteDb
|
remoteDb
|
||||||
.collection('items')
|
.collection('items')
|
||||||
.where('createdBy', '==', window.user.uid)
|
.where('createdBy', '==', window.user.uid)
|
||||||
.onSnapshot(function (querySnapshot) {
|
.onSnapshot(
|
||||||
querySnapshot.forEach(function (doc) {
|
function(querySnapshot) {
|
||||||
items.push(doc.data());
|
querySnapshot.forEach(function(doc) {
|
||||||
});
|
items.push(doc.data());
|
||||||
utils.log('Items fetched in ', Date.now() - t, 'ms')
|
});
|
||||||
|
log('Items fetched in ', Date.now() - t, 'ms');
|
||||||
|
|
||||||
d.resolve(items);
|
d.resolve(items);
|
||||||
}, function () {
|
},
|
||||||
d.resolve([])
|
function() {
|
||||||
});
|
d.resolve([]);
|
||||||
|
}
|
||||||
|
);
|
||||||
return d.promise;
|
return d.promise;
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -91,7 +92,7 @@ export const itemService = {
|
|||||||
}
|
}
|
||||||
if (window.user) {
|
if (window.user) {
|
||||||
var remoteDb = await window.db.getDb();
|
var remoteDb = await window.db.getDb();
|
||||||
utils.log(`Starting to save item ${id}`);
|
log(`Starting to save item ${id}`);
|
||||||
item.createdBy = window.user.uid;
|
item.createdBy = window.user.uid;
|
||||||
remotePromise = remoteDb
|
remotePromise = remoteDb
|
||||||
.collection('items')
|
.collection('items')
|
||||||
@ -100,7 +101,7 @@ export const itemService = {
|
|||||||
merge: true
|
merge: true
|
||||||
})
|
})
|
||||||
.then(arg => {
|
.then(arg => {
|
||||||
utils.log('Document written', arg);
|
log('Document written', arg);
|
||||||
d.resolve();
|
d.resolve();
|
||||||
})
|
})
|
||||||
.catch(d.reject);
|
.catch(d.reject);
|
||||||
@ -120,10 +121,11 @@ export const itemService = {
|
|||||||
// save new items
|
// save new items
|
||||||
window.db.local.set(items, d.resolve);
|
window.db.local.set(items, d.resolve);
|
||||||
// Push in new item IDs
|
// Push in new item IDs
|
||||||
window.db.local.get({
|
window.db.local.get(
|
||||||
|
{
|
||||||
items: {}
|
items: {}
|
||||||
},
|
},
|
||||||
function (result) {
|
function(result) {
|
||||||
/* eslint-disable guard-for-in */
|
/* eslint-disable guard-for-in */
|
||||||
for (var id in items) {
|
for (var id in items) {
|
||||||
result.items[id] = true;
|
result.items[id] = true;
|
||||||
@ -163,24 +165,25 @@ export const itemService = {
|
|||||||
return d.promise;
|
return d.promise;
|
||||||
}
|
}
|
||||||
const remoteDb = await window.db.getDb();
|
const remoteDb = await window.db.getDb();
|
||||||
utils.log(`Starting to save item ${id}`);
|
log(`Starting to save item ${id}`);
|
||||||
return remoteDb
|
return remoteDb
|
||||||
.collection('items')
|
.collection('items')
|
||||||
.doc(id)
|
.doc(id)
|
||||||
.delete()
|
.delete()
|
||||||
.then(arg => {
|
.then(arg => {
|
||||||
utils.log('Document removed', arg);
|
log('Document removed', arg);
|
||||||
})
|
})
|
||||||
.catch(error => utils.log(error));
|
.catch(error => log(error));
|
||||||
},
|
},
|
||||||
|
|
||||||
async setItemForUser(itemId) {
|
async setItemForUser(itemId) {
|
||||||
// When not logged in
|
// When not logged in
|
||||||
if (!window.user) {
|
if (!window.user) {
|
||||||
return window.db.local.get({
|
return window.db.local.get(
|
||||||
|
{
|
||||||
items: {}
|
items: {}
|
||||||
},
|
},
|
||||||
function (result) {
|
function(result) {
|
||||||
result.items[itemId] = true;
|
result.items[itemId] = true;
|
||||||
window.db.local.set({
|
window.db.local.set({
|
||||||
items: result.items
|
items: result.items
|
||||||
@ -196,20 +199,21 @@ export const itemService = {
|
|||||||
[`items.${itemId}`]: true
|
[`items.${itemId}`]: true
|
||||||
})
|
})
|
||||||
.then(arg => {
|
.then(arg => {
|
||||||
utils.log(`Item ${itemId} set for user`, arg);
|
log(`Item ${itemId} set for user`, arg);
|
||||||
window.user.items = window.user.items || {};
|
window.user.items = window.user.items || {};
|
||||||
window.user.items[itemId] = true;
|
window.user.items[itemId] = true;
|
||||||
})
|
})
|
||||||
.catch(error => utils.log(error));
|
.catch(error => log(error));
|
||||||
},
|
},
|
||||||
|
|
||||||
async unsetItemForUser(itemId) {
|
async unsetItemForUser(itemId) {
|
||||||
// When not logged in
|
// When not logged in
|
||||||
if (!window.user) {
|
if (!window.user) {
|
||||||
return window.db.local.get({
|
return window.db.local.get(
|
||||||
|
{
|
||||||
items: {}
|
items: {}
|
||||||
},
|
},
|
||||||
function (result) {
|
function(result) {
|
||||||
delete result.items[itemId];
|
delete result.items[itemId];
|
||||||
window.db.local.set({
|
window.db.local.set({
|
||||||
items: result.items
|
items: result.items
|
||||||
@ -226,8 +230,8 @@ export const itemService = {
|
|||||||
})
|
})
|
||||||
.then(arg => {
|
.then(arg => {
|
||||||
delete window.user.items[itemId];
|
delete window.user.items[itemId];
|
||||||
utils.log(`Item ${itemId} unset for user`, arg);
|
log(`Item ${itemId} unset for user`, arg);
|
||||||
})
|
})
|
||||||
.catch(error => utils.log(error));
|
.catch(error => log(error));
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { handleDownloadsPermission } from './utils';
|
import { handleDownloadsPermission, log } from './utils';
|
||||||
import { trackEvent } from './analytics';
|
import { trackEvent } from './analytics';
|
||||||
|
|
||||||
function saveScreenshot(dataURI) {
|
function saveScreenshot(dataURI) {
|
||||||
@ -59,7 +59,7 @@ function saveScreenshot(dataURI) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function errorHandler(e) {
|
function errorHandler(e) {
|
||||||
utils.log(e);
|
log(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// create a blob for writing to a file
|
// create a blob for writing to a file
|
||||||
|
102
src/utils.js
102
src/utils.js
@ -1,18 +1,8 @@
|
|||||||
import {
|
import { trackEvent } from './analytics';
|
||||||
trackEvent
|
|
||||||
} from './analytics';
|
|
||||||
|
|
||||||
import {
|
import { computeHtml, computeCss, computeJs } from './computes';
|
||||||
computeHtml,
|
import { JsModes } from './codeModes';
|
||||||
computeCss,
|
import { deferred } from './deferred';
|
||||||
computeJs
|
|
||||||
} from './computes';
|
|
||||||
import {
|
|
||||||
JsModes
|
|
||||||
} from './codeModes';
|
|
||||||
import {
|
|
||||||
deferred
|
|
||||||
} from './deferred';
|
|
||||||
const esprima = require('esprima');
|
const esprima = require('esprima');
|
||||||
|
|
||||||
window.DEBUG = document.cookie.indexOf('wmdebug') > -1;
|
window.DEBUG = document.cookie.indexOf('wmdebug') > -1;
|
||||||
@ -37,7 +27,7 @@ var alphaNum = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
|||||||
* @param Selector that should match for next siblings
|
* @param Selector that should match for next siblings
|
||||||
* @return element Next element that mathes `selector`
|
* @return element Next element that mathes `selector`
|
||||||
*/
|
*/
|
||||||
Node.prototype.nextUntil = function (selector) {
|
Node.prototype.nextUntil = function(selector) {
|
||||||
const siblings = Array.from(this.parentNode.querySelectorAll(selector));
|
const siblings = Array.from(this.parentNode.querySelectorAll(selector));
|
||||||
const index = siblings.indexOf(this);
|
const index = siblings.indexOf(this);
|
||||||
return siblings[index + 1];
|
return siblings[index + 1];
|
||||||
@ -47,7 +37,7 @@ Node.prototype.nextUntil = function (selector) {
|
|||||||
* @param Selector that should match for next siblings
|
* @param Selector that should match for next siblings
|
||||||
* @return element Next element that mathes `selector`
|
* @return element Next element that mathes `selector`
|
||||||
*/
|
*/
|
||||||
Node.prototype.previousUntil = function (selector) {
|
Node.prototype.previousUntil = function(selector) {
|
||||||
const siblings = Array.from(this.parentNode.querySelectorAll(selector));
|
const siblings = Array.from(this.parentNode.querySelectorAll(selector));
|
||||||
const index = siblings.indexOf(this);
|
const index = siblings.indexOf(this);
|
||||||
return siblings[index - 1];
|
return siblings[index - 1];
|
||||||
@ -56,7 +46,7 @@ Node.prototype.previousUntil = function (selector) {
|
|||||||
// Safari doesn't have this!
|
// Safari doesn't have this!
|
||||||
window.requestIdleCallback =
|
window.requestIdleCallback =
|
||||||
window.requestIdleCallback ||
|
window.requestIdleCallback ||
|
||||||
function (fn) {
|
function(fn) {
|
||||||
setTimeout(fn, 10);
|
setTimeout(fn, 10);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -86,7 +76,7 @@ export function semverCompare(a, b) {
|
|||||||
export function generateRandomId(len) {
|
export function generateRandomId(len) {
|
||||||
var length = len || 10;
|
var length = len || 10;
|
||||||
var id = '';
|
var id = '';
|
||||||
for (var i = length; i--;) {
|
for (var i = length; i--; ) {
|
||||||
id += alphaNum[~~(Math.random() * alphaNum.length)];
|
id += alphaNum[~~(Math.random() * alphaNum.length)];
|
||||||
}
|
}
|
||||||
return id;
|
return id;
|
||||||
@ -110,9 +100,7 @@ export function log() {
|
|||||||
* Contributed by Ariya Hidayat!
|
* Contributed by Ariya Hidayat!
|
||||||
* @param code {string} Code to be protected from infinite loops.
|
* @param code {string} Code to be protected from infinite loops.
|
||||||
*/
|
*/
|
||||||
export function addInfiniteLoopProtection(code, {
|
export function addInfiniteLoopProtection(code, { timeout }) {
|
||||||
timeout
|
|
||||||
}) {
|
|
||||||
var loopId = 1;
|
var loopId = 1;
|
||||||
var patches = [];
|
var patches = [];
|
||||||
var varPrefix = '_wmloopvar';
|
var varPrefix = '_wmloopvar';
|
||||||
@ -120,12 +108,13 @@ export function addInfiniteLoopProtection(code, {
|
|||||||
var checkStr = `\nif (Date.now() - %d > ${timeout}) { window.top.previewException(new Error("Infinite loop")); break;}\n`;
|
var checkStr = `\nif (Date.now() - %d > ${timeout}) { window.top.previewException(new Error("Infinite loop")); break;}\n`;
|
||||||
|
|
||||||
esprima.parse(
|
esprima.parse(
|
||||||
code, {
|
code,
|
||||||
|
{
|
||||||
tolerant: true,
|
tolerant: true,
|
||||||
range: true,
|
range: true,
|
||||||
jsx: true
|
jsx: true
|
||||||
},
|
},
|
||||||
function (node) {
|
function(node) {
|
||||||
switch (node.type) {
|
switch (node.type) {
|
||||||
case 'DoWhileStatement':
|
case 'DoWhileStatement':
|
||||||
case 'ForStatement':
|
case 'ForStatement':
|
||||||
@ -167,10 +156,10 @@ export function addInfiniteLoopProtection(code, {
|
|||||||
|
|
||||||
/* eslint-disable no-param-reassign */
|
/* eslint-disable no-param-reassign */
|
||||||
patches
|
patches
|
||||||
.sort(function (a, b) {
|
.sort(function(a, b) {
|
||||||
return b.pos - a.pos;
|
return b.pos - a.pos;
|
||||||
})
|
})
|
||||||
.forEach(function (patch) {
|
.forEach(function(patch) {
|
||||||
code = code.slice(0, patch.pos) + patch.str + code.slice(patch.pos);
|
code = code.slice(0, patch.pos) + patch.str + code.slice(patch.pos);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -182,7 +171,8 @@ export function getHumanDate(timestamp) {
|
|||||||
var d = new Date(timestamp);
|
var d = new Date(timestamp);
|
||||||
var retVal =
|
var retVal =
|
||||||
d.getDate() +
|
d.getDate() +
|
||||||
' ' + [
|
' ' +
|
||||||
|
[
|
||||||
'January',
|
'January',
|
||||||
'February',
|
'February',
|
||||||
'March',
|
'March',
|
||||||
@ -204,7 +194,7 @@ export function getHumanDate(timestamp) {
|
|||||||
// create a one-time event
|
// create a one-time event
|
||||||
export function once(node, type, callback) {
|
export function once(node, type, callback) {
|
||||||
// create event
|
// create event
|
||||||
node.addEventListener(type, function (e) {
|
node.addEventListener(type, function(e) {
|
||||||
// remove event
|
// remove event
|
||||||
e.target.removeEventListener(type, arguments.callee);
|
e.target.removeEventListener(type, arguments.callee);
|
||||||
// call handler
|
// call handler
|
||||||
@ -223,7 +213,8 @@ export function downloadFile(fileName, blob) {
|
|||||||
a.remove();
|
a.remove();
|
||||||
}
|
}
|
||||||
if (window.IS_EXTENSION) {
|
if (window.IS_EXTENSION) {
|
||||||
chrome.downloads.download({
|
chrome.downloads.download(
|
||||||
|
{
|
||||||
url: window.URL.createObjectURL(blob),
|
url: window.URL.createObjectURL(blob),
|
||||||
filename: fileName,
|
filename: fileName,
|
||||||
saveAs: true
|
saveAs: true
|
||||||
@ -244,13 +235,13 @@ export function writeFile(name, blob, cb) {
|
|||||||
var fileWritten = false;
|
var fileWritten = false;
|
||||||
|
|
||||||
function getErrorHandler(type) {
|
function getErrorHandler(type) {
|
||||||
return function () {
|
return function() {
|
||||||
log(arguments);
|
log(arguments);
|
||||||
trackEvent('fn', 'error', type);
|
trackEvent('fn', 'error', type);
|
||||||
// When there are too many write errors, show a message.
|
// When there are too many write errors, show a message.
|
||||||
writeFile.errorCount = (writeFile.errorCount || 0) + 1;
|
writeFile.errorCount = (writeFile.errorCount || 0) + 1;
|
||||||
if (writeFile.errorCount === 4) {
|
if (writeFile.errorCount === 4) {
|
||||||
setTimeout(function () {
|
setTimeout(function() {
|
||||||
alert(
|
alert(
|
||||||
"Oops! Seems like your preview isn't updating. It's recommended to switch to the web app: https://webmakerapp.com/app/.\n\n If you still want to get the extension working, please try the following steps until it fixes:\n - Refresh Web Maker\n - Restart browser\n - Update browser\n - Reinstall Web Maker (don't forget to export all your creations from saved items pane (click the OPEN button) before reinstalling)\n\nIf nothing works, please tweet out to @webmakerApp."
|
"Oops! Seems like your preview isn't updating. It's recommended to switch to the web app: https://webmakerapp.com/app/.\n\n If you still want to get the extension working, please try the following steps until it fixes:\n - Refresh Web Maker\n - Restart browser\n - Update browser\n - Reinstall Web Maker (don't forget to export all your creations from saved items pane (click the OPEN button) before reinstalling)\n\nIf nothing works, please tweet out to @webmakerApp."
|
||||||
);
|
);
|
||||||
@ -264,12 +255,13 @@ export function writeFile(name, blob, cb) {
|
|||||||
window.webkitRequestFileSystem(
|
window.webkitRequestFileSystem(
|
||||||
window.TEMPORARY,
|
window.TEMPORARY,
|
||||||
1024 * 1024 * 5,
|
1024 * 1024 * 5,
|
||||||
function (fs) {
|
function(fs) {
|
||||||
fs.root.getFile(
|
fs.root.getFile(
|
||||||
name, {
|
name,
|
||||||
|
{
|
||||||
create: true
|
create: true
|
||||||
},
|
},
|
||||||
function (fileEntry) {
|
function(fileEntry) {
|
||||||
fileEntry.createWriter(fileWriter => {
|
fileEntry.createWriter(fileWriter => {
|
||||||
function onWriteComplete() {
|
function onWriteComplete() {
|
||||||
if (fileWritten) {
|
if (fileWritten) {
|
||||||
@ -302,7 +294,7 @@ export function loadJS(src) {
|
|||||||
script.src = src;
|
script.src = src;
|
||||||
script.async = true;
|
script.async = true;
|
||||||
ref.parentNode.insertBefore(script, ref);
|
ref.parentNode.insertBefore(script, ref);
|
||||||
script.onload = function () {
|
script.onload = function() {
|
||||||
d.resolve();
|
d.resolve();
|
||||||
};
|
};
|
||||||
return d.promise;
|
return d.promise;
|
||||||
@ -314,12 +306,12 @@ export function getCompleteHtml(html, css, js, item, isForExport) {
|
|||||||
}
|
}
|
||||||
var externalJs = item.externalLibs.js
|
var externalJs = item.externalLibs.js
|
||||||
.split('\n')
|
.split('\n')
|
||||||
.reduce(function (scripts, url) {
|
.reduce(function(scripts, url) {
|
||||||
return scripts + (url ? '\n<script src="' + url + '"></script>' : '');
|
return scripts + (url ? '\n<script src="' + url + '"></script>' : '');
|
||||||
}, '');
|
}, '');
|
||||||
var externalCss = item.externalLibs.css
|
var externalCss = item.externalLibs.css
|
||||||
.split('\n')
|
.split('\n')
|
||||||
.reduce(function (links, url) {
|
.reduce(function(links, url) {
|
||||||
return (
|
return (
|
||||||
links +
|
links +
|
||||||
(url ? '\n<link rel="stylesheet" href="' + url + '"></link>' : '')
|
(url ? '\n<link rel="stylesheet" href="' + url + '"></link>' : '')
|
||||||
@ -344,29 +336,29 @@ export function getCompleteHtml(html, css, js, item, isForExport) {
|
|||||||
if (!isForExport) {
|
if (!isForExport) {
|
||||||
contents +=
|
contents +=
|
||||||
'<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}${BASE_PATH}/lib/screenlog.js`) +
|
||||||
'"></script>';
|
'"></script>';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.jsMode === JsModes.ES6) {
|
if (item.jsMode === JsModes.ES6) {
|
||||||
contents +=
|
contents +=
|
||||||
'<script src="' +
|
'<script src="' +
|
||||||
(chrome.extension ?
|
(chrome.extension
|
||||||
chrome.extension.getURL('lib/transpilers/babel-polyfill.min.js') :
|
? chrome.extension.getURL('lib/transpilers/babel-polyfill.min.js')
|
||||||
`${
|
: `${
|
||||||
location.origin
|
location.origin
|
||||||
}${BASE_PATH}/lib/transpilers/babel-polyfill.min.js`) +
|
}${BASE_PATH}/lib/transpilers/babel-polyfill.min.js`) +
|
||||||
'"></script>';
|
'"></script>';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof js === 'string') {
|
if (typeof js === 'string') {
|
||||||
contents += '<script>\n' + js + '\n//# sourceURL=userscript.js';
|
contents += '<script>\n' + js + '\n//# sourceURL=userscript.js';
|
||||||
} else {
|
} else {
|
||||||
var origin = chrome.i18n.getMessage() ?
|
var origin = chrome.i18n.getMessage()
|
||||||
`chrome-extension://${chrome.i18n.getMessage('@@extension_id')}` :
|
? `chrome-extension://${chrome.i18n.getMessage('@@extension_id')}`
|
||||||
`${location.origin}`;
|
: `${location.origin}`;
|
||||||
contents +=
|
contents +=
|
||||||
'<script src="' + `filesystem:${origin}/temporary/script.js` + '">';
|
'<script src="' + `filesystem:${origin}/temporary/script.js` + '">';
|
||||||
}
|
}
|
||||||
@ -379,10 +371,10 @@ 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(function(result) {
|
||||||
var html = result[0],
|
var html = result[0].code,
|
||||||
css = result[1],
|
css = result[1].code,
|
||||||
js = result[2];
|
js = result[2].code;
|
||||||
|
|
||||||
var fileContent = getCompleteHtml(html, css, js, item, true);
|
var fileContent = getCompleteHtml(html, css, js, item, true);
|
||||||
|
|
||||||
@ -417,17 +409,19 @@ export function handleDownloadsPermission() {
|
|||||||
d.resolve();
|
d.resolve();
|
||||||
return d.promise;
|
return d.promise;
|
||||||
}
|
}
|
||||||
chrome.permissions.contains({
|
chrome.permissions.contains(
|
||||||
|
{
|
||||||
permissions: ['downloads']
|
permissions: ['downloads']
|
||||||
},
|
},
|
||||||
function (result) {
|
function(result) {
|
||||||
if (result) {
|
if (result) {
|
||||||
d.resolve();
|
d.resolve();
|
||||||
} else {
|
} else {
|
||||||
chrome.permissions.request({
|
chrome.permissions.request(
|
||||||
|
{
|
||||||
permissions: ['downloads']
|
permissions: ['downloads']
|
||||||
},
|
},
|
||||||
function (granted) {
|
function(granted) {
|
||||||
if (granted) {
|
if (granted) {
|
||||||
trackEvent('fn', 'downloadsPermGiven');
|
trackEvent('fn', 'downloadsPermGiven');
|
||||||
d.resolve();
|
d.resolve();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user