mirror of
https://github.com/chinchang/web-maker.git
synced 2025-07-13 18:16:19 +02:00
detached mode
This commit is contained in:
@ -159,8 +159,8 @@ export default class ContentWrap extends Component {
|
|||||||
|
|
||||||
if (shouldInlineJs) {
|
if (shouldInlineJs) {
|
||||||
if (this.detachedWindow) {
|
if (this.detachedWindow) {
|
||||||
utils.log('✉️ Sending message to detached window');
|
log('✉️ Sending message to detached window');
|
||||||
scope.detachedWindow.postMessage({ contents }, '*');
|
this.detachedWindow.postMessage({ contents }, '*');
|
||||||
} else {
|
} else {
|
||||||
this.frame.src = this.frame.src;
|
this.frame.src = this.frame.src;
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -251,8 +251,7 @@ export default class ContentWrap extends Component {
|
|||||||
return !!item.title;
|
return !!item.title;
|
||||||
}
|
}
|
||||||
componentDidUpdate() {
|
componentDidUpdate() {
|
||||||
log('🚀', 'didupdate', this.props.currentItem);
|
// log('🚀', 'didupdate', this.props.currentItem);
|
||||||
|
|
||||||
// if (this.isValidItem(this.props.currentItem)) {
|
// if (this.isValidItem(this.props.currentItem)) {
|
||||||
// this.refreshEditor();
|
// this.refreshEditor();
|
||||||
// }
|
// }
|
||||||
@ -535,6 +534,40 @@ export default class ContentWrap extends Component {
|
|||||||
trackEvent('ui', 'updateCodeMode', mode);
|
trackEvent('ui', 'updateCodeMode', mode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
detachPreview() {
|
||||||
|
if (this.detachedWindow) {
|
||||||
|
this.detachedWindow.focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const iframeBounds = this.frame.getBoundingClientRect();
|
||||||
|
const iframeWidth = iframeBounds.width;
|
||||||
|
const iframeHeight = iframeBounds.height;
|
||||||
|
document.body.classList.add('is-detached-mode');
|
||||||
|
window.globalConsoleContainerEl.insertBefore(window.consoleEl, null);
|
||||||
|
|
||||||
|
this.detachedWindow = window.open(
|
||||||
|
'./preview.html',
|
||||||
|
'Web Maker',
|
||||||
|
`width=${iframeWidth},height=${iframeHeight},resizable,scrollbars=yes,status=1`
|
||||||
|
);
|
||||||
|
// Trigger initial render in detached window
|
||||||
|
setTimeout(() => {
|
||||||
|
this.setPreviewContent(true);
|
||||||
|
}, 1500);
|
||||||
|
function checkWindow() {
|
||||||
|
if (this.detachedWindow && this.detachedWindow.closed) {
|
||||||
|
clearInterval(intervalID);
|
||||||
|
document.body.classList.remove('is-detached-mode');
|
||||||
|
$('#js-demo-side').insertBefore(window.consoleEl, null);
|
||||||
|
this.detachedWindow = null;
|
||||||
|
// Update main frame preview to get latest changes (which were not
|
||||||
|
// getting reflected while detached window was open)
|
||||||
|
this.setPreviewContent(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var intervalID = window.setInterval(checkWindow.bind(this), 500);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<SplitPane
|
<SplitPane
|
||||||
|
@ -112,7 +112,7 @@ export default class Footer extends Component {
|
|||||||
<a
|
<a
|
||||||
class="mode-btn hint--top-left hint--rounded hide-on-mobile"
|
class="mode-btn hint--top-left hint--rounded hide-on-mobile"
|
||||||
aria-label="Detach Preview"
|
aria-label="Detach Preview"
|
||||||
d-click="openDetachedPreview"
|
onClick={this.props.detachedPreviewBtnHandler}
|
||||||
>
|
>
|
||||||
<svg viewBox="0 0 24 24">
|
<svg viewBox="0 0 24 24">
|
||||||
<path d="M22,17V7H6V17H22M22,5A2,2 0 0,1 24,7V17C24,18.11 23.1,19 22,19H16V21H18V23H10V21H12V19H6C4.89,19 4,18.11 4,17V7A2,2 0 0,1 6,5H22M2,3V15H0V3A2,2 0 0,1 2,1H20V3H2Z" />
|
<path d="M22,17V7H6V17H22M22,5A2,2 0 0,1 24,7V17C24,18.11 23.1,19 22,19H16V21H18V23H10V21H12V19H6C4.89,19 4,18.11 4,17V7A2,2 0 0,1 6,5H22M2,3V15H0V3A2,2 0 0,1 2,1H20V3H2Z" />
|
||||||
|
@ -144,7 +144,7 @@ export default class App extends Component {
|
|||||||
db.getSettings(this.defaultSettings).then(result => {
|
db.getSettings(this.defaultSettings).then(result => {
|
||||||
if (result.preserveLastCode && lastCode) {
|
if (result.preserveLastCode && lastCode) {
|
||||||
this.setState({ unsavedEditCount: 0 });
|
this.setState({ unsavedEditCount: 0 });
|
||||||
log('🚀', 'unsaededitcount setstate');
|
|
||||||
// For web app environment we don't fetch item from localStorage,
|
// For web app environment we don't fetch item from localStorage,
|
||||||
// because the item isn't stored in the localStorage.
|
// because the item isn't stored in the localStorage.
|
||||||
if (lastCode.id && window.IS_EXTENSION) {
|
if (lastCode.id && window.IS_EXTENSION) {
|
||||||
@ -261,7 +261,6 @@ export default class App extends Component {
|
|||||||
item.jsMode = item.jsMode || this.state.prefs.jsMode || JsModes.JS;
|
item.jsMode = item.jsMode || this.state.prefs.jsMode || JsModes.JS;
|
||||||
|
|
||||||
this.setState({ currentItem: item }, d.resolve);
|
this.setState({ currentItem: item }, d.resolve);
|
||||||
log('🚀', 'currentItem setstate', item);
|
|
||||||
|
|
||||||
// Reset auto-saving flag
|
// Reset auto-saving flag
|
||||||
this.isAutoSavingEnabled = false;
|
this.isAutoSavingEnabled = false;
|
||||||
@ -595,9 +594,9 @@ export default class App extends Component {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
onCodeModeChange(ofWhat, mode) {
|
onCodeModeChange(ofWhat, mode) {
|
||||||
const item = {...this.state.currentItem}
|
const item = { ...this.state.currentItem };
|
||||||
item[`${ofWhat}Mode`] = mode;
|
item[`${ofWhat}Mode`] = mode;
|
||||||
this.setState({currentItem: item});
|
this.setState({ currentItem: item });
|
||||||
}
|
}
|
||||||
onCodeChange(type, code, isUserChange) {
|
onCodeChange(type, code, isUserChange) {
|
||||||
this.state.currentItem[type] = code;
|
this.state.currentItem[type] = code;
|
||||||
@ -742,6 +741,11 @@ export default class App extends Component {
|
|||||||
this.createNewItem();
|
this.createNewItem();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
detachedPreviewBtnHandler() {
|
||||||
|
trackEvent('ui', 'detachPreviewBtnClick');
|
||||||
|
|
||||||
|
this.contentWrap.detachPreview()
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
@ -780,6 +784,9 @@ export default class App extends Component {
|
|||||||
notificationsBtnClickHandler={() =>
|
notificationsBtnClickHandler={() =>
|
||||||
this.setState({ isNotificationsModalOpen: true })
|
this.setState({ isNotificationsModalOpen: true })
|
||||||
}
|
}
|
||||||
|
detachedPreviewBtnHandler={this.detachedPreviewBtnHandler.bind(
|
||||||
|
this
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
13
webmaker/src/detached-window.js
Normal file
13
webmaker/src/detached-window.js
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
window.addEventListener('message', e => {
|
||||||
|
if (e.data && e.data.contents) {
|
||||||
|
const frame = document.querySelector('iframe');
|
||||||
|
frame.src = frame.src;
|
||||||
|
setTimeout(() => {
|
||||||
|
frame.contentDocument.open();
|
||||||
|
frame.contentDocument.write(e.data.contents);
|
||||||
|
frame.contentDocument.close();
|
||||||
|
}, 10);
|
||||||
|
} else {
|
||||||
|
document.querySelector('iframe').src = e.data;
|
||||||
|
}
|
||||||
|
});
|
8
webmaker/src/preview.html
Normal file
8
webmaker/src/preview.html
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<link rel="stylesheet" href="style.css">
|
||||||
|
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<iframe src="about://blank" frameborder="0" id="demo-frame" allowfullscreen></iframe>
|
||||||
|
|
||||||
|
<script src="detached-window.js"></script>
|
||||||
|
</body>
|
Reference in New Issue
Block a user