1
0
mirror of https://github.com/chinchang/web-maker.git synced 2025-07-29 09:40:10 +02:00

port saveAsHtml

This commit is contained in:
Kushagra Gour
2018-06-07 11:05:59 +05:30
parent d3ba0534aa
commit 6794e309af
4 changed files with 373 additions and 350 deletions

View File

@@ -2,7 +2,7 @@ import { h, Component } from 'preact';
import UserCodeMirror from './UserCodeMirror.jsx'; import UserCodeMirror from './UserCodeMirror.jsx';
import { computeHtml, computeCss, computeJs } from '../computes'; import { computeHtml, computeCss, computeJs } from '../computes';
import { modes, HtmlModes, CssModes, JsModes } from '../codeModes'; import { modes, HtmlModes, CssModes, JsModes } from '../codeModes';
import { log, writeFile, loadJS } from '../utils'; import { log, writeFile, loadJS, getCompleteHtml } from '../utils';
import { SplitPane } from './SplitPane.jsx'; import { SplitPane } from './SplitPane.jsx';
import { trackEvent } from '../analytics'; import { trackEvent } from '../analytics';
import CodeMirror from '../CodeMirror'; import CodeMirror from '../CodeMirror';
@@ -76,78 +76,15 @@ export default class ContentWrap extends Component {
} }
clearConsole() {} clearConsole() {}
/* eslint max-params: ["error", 4] */
getCompleteHtml(html, css, js, isForExport) {
if (!this.props.currentItem) {
return '';
}
var externalJs = this.props.currentItem.externalLibs.js
.split('\n')
.reduce(function(scripts, url) {
return scripts + (url ? '\n<script src="' + url + '"></script>' : '');
}, '');
var externalCss = this.props.currentItem.externalLibs.css
.split('\n')
.reduce(function(links, url) {
return (
links +
(url ? '\n<link rel="stylesheet" href="' + url + '"></link>' : '')
);
}, '');
var contents =
'<!DOCTYPE html>\n' +
'<html>\n<head>\n' +
'<meta charset="UTF-8" />\n' +
externalCss +
'\n' +
'<style id="webmakerstyle">\n' +
css +
'\n</style>\n' +
'</head>\n' +
'<body>\n' +
html +
'\n' +
externalJs +
'\n';
if (!isForExport) {
contents +=
'<script src="' +
(chrome.extension
? chrome.extension.getURL('lib/screenlog.js')
: `${location.origin}${BASE_PATH}/lib/screenlog.js`) +
'"></script>';
}
if (this.jsMode === JsModes.ES6) {
contents +=
'<script src="' +
(chrome.extension
? chrome.extension.getURL('lib/transpilers/babel-polyfill.min.js')
: `${
location.origin
}${BASE_PATH}/lib/transpilers/babel-polyfill.min.js`) +
'"></script>';
}
if (typeof js === 'string') {
contents += '<script>\n' + js + '\n//# sourceURL=userscript.js';
} else {
var origin = chrome.i18n.getMessage()
? `chrome-extension://${chrome.i18n.getMessage('@@extension_id')}`
: `${location.origin}`;
contents +=
'<script src="' + `filesystem:${origin}/temporary/script.js` + '">';
}
contents += '\n</script>\n</body>\n</html>';
return contents;
}
createPreviewFile(html, css, js) { createPreviewFile(html, css, js) {
const shouldInlineJs = const shouldInlineJs =
!window.webkitRequestFileSystem || !window.IS_EXTENSION; !window.webkitRequestFileSystem || !window.IS_EXTENSION;
var contents = this.getCompleteHtml(html, css, shouldInlineJs ? js : null); var contents = getCompleteHtml(
html,
css,
shouldInlineJs ? js : null,
this.props.currentItem
);
var blob = new Blob([contents], { type: 'text/plain;charset=UTF-8' }); var blob = new Blob([contents], { type: 'text/plain;charset=UTF-8' });
var blobjs = new Blob([js], { type: 'text/plain;charset=UTF-8' }); var blobjs = new Blob([js], { type: 'text/plain;charset=UTF-8' });

View File

@@ -17,6 +17,7 @@ export default class Footer extends Component {
<div id="footer" class="footer"> <div id="footer" class="footer">
<div class="footer__right fr"> <div class="footer__right fr">
<a <a
onClick={this.props.saveHtmlBtnClickHandler}
id="saveHtmlBtn" id="saveHtmlBtn"
class="mode-btn hint--rounded hint--top-left hide-on-mobile" class="mode-btn hint--rounded hint--top-left hide-on-mobile"
data-hint="Save as HTML file" data-hint="Save as HTML file"

View File

@@ -9,7 +9,7 @@ import AddLibrary from './AddLibrary.jsx';
import Modal from './Modal.jsx'; import Modal from './Modal.jsx';
import HelpModal from './HelpModal.jsx'; import HelpModal from './HelpModal.jsx';
import Login from './Login.jsx'; import Login from './Login.jsx';
import { log, generateRandomId, semverCompare } from '../utils'; import { log, generateRandomId, semverCompare, saveAsHtml } from '../utils';
import { itemService } from '../itemService'; import { itemService } from '../itemService';
import '../db'; import '../db';
import Notifications from './Notifications'; import Notifications from './Notifications';
@@ -446,40 +446,6 @@ export default class App extends Component {
}); });
} }
saveFile() {
var htmlPromise = computeHtml();
var cssPromise = computeCss();
var jsPromise = computeJs(false);
Promise.all([htmlPromise, cssPromise, jsPromise]).then(function(result) {
var html = result[0],
css = result[1],
js = result[2];
var fileContent = getCompleteHtml(html, css, js, true);
var d = new Date();
var fileName = [
'web-maker',
d.getFullYear(),
d.getMonth() + 1,
d.getDate(),
d.getHours(),
d.getMinutes(),
d.getSeconds()
].join('-');
if (this.state.currentItem.title) {
fileName = this.state.currentItem.title;
}
fileName += '.html';
var blob = new Blob([fileContent], { type: 'text/html;charset=UTF-8' });
utils.downloadFile(fileName, blob);
trackEvent('fn', 'saveFileComplete');
});
}
closeAllOverlays() { closeAllOverlays() {
if (this.state.isSavedItemPaneOpen) { if (this.state.isSavedItemPaneOpen) {
this.setState({ isSavedItemPaneOpen: false }); this.setState({ isSavedItemPaneOpen: false });
@@ -833,6 +799,11 @@ export default class App extends Component {
trackEvent('ui', 'openInCodepen'); trackEvent('ui', 'openInCodepen');
e.preventDefault(); e.preventDefault();
} }
saveHtmlBtnClickHandler(e) {
saveAsHtml(this.state.currentItem);
trackEvent('ui', 'saveHtmlClick');
e.preventDefault();
}
render() { render() {
return ( return (
@@ -880,6 +851,7 @@ export default class App extends Component {
this this
)} )}
codepenBtnClickHandler={this.codepenBtnClickHandler.bind(this)} codepenBtnClickHandler={this.codepenBtnClickHandler.bind(this)}
saveHtmlBtnClickHandler={this.saveHtmlBtnClickHandler.bind(this)}
hasUnseenChangelog={this.state.hasUnseenChangelog} hasUnseenChangelog={this.state.hasUnseenChangelog}
/> />
</div> </div>

View File

@@ -2,15 +2,24 @@
trackEvent trackEvent
} from './analytics'; } from './analytics';
import {
computeHtml,
computeCss,
computeJs
} from './computes';
import {
JsModes
} from './codeModes';
import { import {
deferred deferred
} from './deferred'; } from './deferred';
window.DEBUG = document.cookie.indexOf('wmdebug') > -1;
window.DEBUG = document.cookie.indexOf('wmdebug') > -1;
window.$ = document.querySelector.bind(document); window.$ = document.querySelector.bind(document);
window.$all = selector => [...document.querySelectorAll(selector)]; window.$all = selector => [...document.querySelectorAll(selector)];
var alphaNum = const BASE_PATH = chrome.extension || window.DEBUG ? '/' : '/app';
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
var alphaNum = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
/** /**
* The following 2 functions are supposed to find the next/previous sibling until the * The following 2 functions are supposed to find the next/previous sibling until the
@@ -102,13 +111,13 @@
var varStr = 'var %d = Date.now();\n'; var varStr = 'var %d = Date.now();\n';
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(code, { esprima.parse(
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':
@@ -145,7 +154,8 @@
default: default:
break; break;
} }
}); }
);
/* eslint-disable no-param-reassign */ /* eslint-disable no-param-reassign */
patches patches
@@ -288,7 +298,110 @@
d.resolve(); d.resolve();
}; };
return d.promise; return d.promise;
}; }
export function getCompleteHtml(html, css, js, item, isForExport) {
if (!item) {
return '';
}
var externalJs = item.externalLibs.js
.split('\n')
.reduce(function (scripts, url) {
return scripts + (url ? '\n<script src="' + url + '"></script>' : '');
}, '');
var externalCss = item.externalLibs.css
.split('\n')
.reduce(function (links, url) {
return (
links +
(url ? '\n<link rel="stylesheet" href="' + url + '"></link>' : '')
);
}, '');
var contents =
'<!DOCTYPE html>\n' +
'<html>\n<head>\n' +
'<meta charset="UTF-8" />\n' +
externalCss +
'\n' +
'<style id="webmakerstyle">\n' +
css +
'\n</style>\n' +
'</head>\n' +
'<body>\n' +
html +
'\n' +
externalJs +
'\n';
if (!isForExport) {
contents +=
'<script src="' +
(chrome.extension ?
chrome.extension.getURL('lib/screenlog.js') :
`${location.origin}${BASE_PATH}/lib/screenlog.js`) +
'"></script>';
}
if (item.jsMode === JsModes.ES6) {
contents +=
'<script src="' +
(chrome.extension ?
chrome.extension.getURL('lib/transpilers/babel-polyfill.min.js') :
`${
location.origin
}${BASE_PATH}/lib/transpilers/babel-polyfill.min.js`) +
'"></script>';
}
if (typeof js === 'string') {
contents += '<script>\n' + js + '\n//# sourceURL=userscript.js';
} else {
var origin = chrome.i18n.getMessage() ?
`chrome-extension://${chrome.i18n.getMessage('@@extension_id')}` :
`${location.origin}`;
contents +=
'<script src="' + `filesystem:${origin}/temporary/script.js` + '">';
}
contents += '\n</script>\n</body>\n</html>';
return contents;
}
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) {
var html = result[0],
css = result[1],
js = result[2];
var fileContent = getCompleteHtml(html, css, js, item, true);
var d = new Date();
var fileName = [
'web-maker',
d.getFullYear(),
d.getMonth() + 1,
d.getDate(),
d.getHours(),
d.getMinutes(),
d.getSeconds()
].join('-');
if (item.title) {
fileName = item.title;
}
fileName += '.html';
var blob = new Blob([fileContent], {
type: 'text/html;charset=UTF-8'
});
downloadFile(fileName, blob);
trackEvent('fn', 'saveFileComplete');
});
}
window.chrome = window.chrome || {}; window.chrome = window.chrome || {};
window.chrome.i18n = { window.chrome.i18n = {