[IMP] website, web_editor: add mobile preview
See merge commit for more information. task-2687506
This commit is contained in:
@@ -1349,6 +1349,7 @@ var SnippetsMenu = Widget.extend({
|
||||
}, 50);
|
||||
this.$window.on('resize.snippets_menu', debouncedCoverUpdate);
|
||||
this.$body.on('content_changed.snippets_menu', debouncedCoverUpdate);
|
||||
$(this.$body[0].ownerDocument.defaultView).on('resize.snippets_menu', debouncedCoverUpdate);
|
||||
|
||||
// On keydown add a class on the active overlay to hide it and show it
|
||||
// again when the mouse moves
|
||||
@@ -3390,8 +3391,8 @@ var SnippetsMenu = Widget.extend({
|
||||
/**
|
||||
* Preview on mobile.
|
||||
*/
|
||||
_onMobilePreviewClick: async function () {
|
||||
throw new Error('implement me');
|
||||
_onMobilePreviewClick: function () {
|
||||
this.trigger_up('request_mobile_preview');
|
||||
},
|
||||
/**
|
||||
* Undo..
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
@mixin o-iframe-position($height) {
|
||||
// TODO review this, this should not be needed as we want the iframe to
|
||||
// be centered and potentially respect its aspect ratio whatever the size.
|
||||
$width: $height * (9 / 16);
|
||||
height: $height;
|
||||
width: $width;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.o_website_preview {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
@@ -7,11 +18,32 @@
|
||||
margin-right: $o-we-sidebar-width !important;
|
||||
}
|
||||
|
||||
> iframe {
|
||||
@include o-position-absolute(0, 0, 0, 0);
|
||||
width: 100%;
|
||||
.o_iframe_container {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
border: none;
|
||||
width: 100%;
|
||||
|
||||
iframe {
|
||||
position: absolute;
|
||||
border: none;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&.o_is_mobile {
|
||||
@include media-breakpoint-up(md) {
|
||||
@include o-iframe-position(720px);
|
||||
|
||||
@media(max-height: calc(720px + #{$o-navbar-height})) {
|
||||
@include o-iframe-position(520px);
|
||||
}
|
||||
|
||||
iframe {
|
||||
border-radius: 25px;
|
||||
box-shadow: 0 0 3px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,16 +2,18 @@
|
||||
<templates xml:space="preserve">
|
||||
<t t-name="website.WebsitePreview" owl="1">
|
||||
<div class="o_website_preview" t-att-class="{ 'editor_enable editor_has_snippets': this.websiteContext.snippetsLoaded }">
|
||||
<iframe t-att-src="iframeFallbackUrl"
|
||||
t-att-class="{ 'd-none': this.websiteContext.edition }"
|
||||
t-ref="iframefallback"/>
|
||||
<iframe t-att-src="initialUrl"
|
||||
class="o_iframe"
|
||||
t-ref="iframe"
|
||||
t-on-load="_onPageLoaded"/>
|
||||
<div class="o_iframe_container" t-att-class="{ 'o_is_mobile': this.websiteContext.isMobile }">
|
||||
<iframe t-att-src="iframeFallbackUrl"
|
||||
t-att-class="{ 'd-none': this.websiteContext.edition }"
|
||||
t-ref="iframefallback"/>
|
||||
<iframe t-att-src="initialUrl"
|
||||
class="o_iframe"
|
||||
t-ref="iframe"
|
||||
t-on-load="_onPageLoaded"/>
|
||||
</div>
|
||||
<WebsiteEditorComponent t-if="websiteContext.edition"
|
||||
reloadIframe.bind="this.reloadIframe"/>
|
||||
</div>
|
||||
<WebsiteEditorComponent t-if="websiteContext.edition"
|
||||
reloadIframe.bind="this.reloadIframe"/>
|
||||
</t>
|
||||
|
||||
<div t-name="website.homepage_editor_welcome_message" class="container text-center o_homepage_editor_welcome_message">
|
||||
|
||||
@@ -633,6 +633,13 @@ export class WysiwygAdapterComponent extends ComponentAdapter {
|
||||
iframeClone.remove();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Update the context to trigger a mobile view.
|
||||
* @private
|
||||
*/
|
||||
_onMobilePreviewRequest() {
|
||||
this.websiteService.context.isMobile = !this.websiteService.context.isMobile;
|
||||
}
|
||||
}
|
||||
WysiwygAdapterComponent.prototype.events = {
|
||||
'widgets_start_request': '_onRootEventRequest',
|
||||
@@ -649,4 +656,5 @@ WysiwygAdapterComponent.prototype.events = {
|
||||
'reload_bundles': '_reloadBundles',
|
||||
'menu_dialog': '_onMenuDialogRequest',
|
||||
'update_color_previews': '_onColorPreviewsUpdate',
|
||||
'request_mobile_preview': '_onMobilePreviewRequest',
|
||||
};
|
||||
|
||||
@@ -39,6 +39,7 @@ export const websiteService = {
|
||||
edition: false,
|
||||
isPublicRootReady: false,
|
||||
snippetsLoaded: false,
|
||||
isMobile: false,
|
||||
});
|
||||
const bus = new EventBus();
|
||||
|
||||
|
||||
@@ -1,72 +1,19 @@
|
||||
odoo.define('website.mobile', function (require) {
|
||||
'use strict';
|
||||
/** @odoo-module **/
|
||||
|
||||
const {_t} = require('web.core');
|
||||
const {Markup} = require('web.utils');
|
||||
var Dialog = require('web.Dialog');
|
||||
var websiteNavbarData = require('website.navbar');
|
||||
import { registry } from "@web/core/registry";
|
||||
import { useService } from "@web/core/utils/hooks";
|
||||
|
||||
const { registry } = require("@web/core/registry");
|
||||
const { Component } = owl;
|
||||
|
||||
var MobilePreviewDialog = Dialog.extend({
|
||||
/**
|
||||
* Tweaks the modal so that it appears as a phone and modifies the iframe
|
||||
* rendering to show more accurate mobile view.
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
start: function () {
|
||||
var self = this;
|
||||
this.$modal.addClass('oe_mobile_preview');
|
||||
this.$modal.on('click', '.modal-header', function () {
|
||||
self.$el.toggleClass('o_invert_orientation');
|
||||
});
|
||||
this.$iframe = $('<iframe/>', {
|
||||
id: 'mobile-viewport',
|
||||
src: $.param.querystring(window.location.href, 'mobilepreview'),
|
||||
});
|
||||
this.$iframe.on('load', function (e) {
|
||||
self.$iframe.contents().find('body').removeClass('o_connected_user');
|
||||
self.$iframe.contents().find('#oe_main_menu_navbar').remove();
|
||||
});
|
||||
this.$iframe.appendTo(this.$el);
|
||||
class MobilePreviewSystray extends Component {
|
||||
setup() {
|
||||
this.websiteService = useService('website');
|
||||
}
|
||||
}
|
||||
MobilePreviewSystray.template = "website.MobilePreviewSystray";
|
||||
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
|
||||
var MobileMenu = websiteNavbarData.WebsiteNavbarActionWidget.extend({
|
||||
actions: _.extend({}, websiteNavbarData.WebsiteNavbarActionWidget.prototype.actions || {}, {
|
||||
'show-mobile-preview': '_onMobilePreviewClick',
|
||||
}),
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Called when the mobile action is triggered -> instantiate the mobile
|
||||
* preview dialog.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_onMobilePreviewClick: function () {
|
||||
if (this.mobilePreview && !this.mobilePreview.isDestroyed()) {
|
||||
return this.mobilePreview.close();
|
||||
}
|
||||
this.mobilePreview = new MobilePreviewDialog(this, {
|
||||
title: Markup(_.escape(_t('Mobile preview')) + ' <span class="fa fa-refresh"/>'),
|
||||
}).open();
|
||||
},
|
||||
});
|
||||
|
||||
registry.category("website_navbar_widgets").add("MobileMenu", {
|
||||
Widget: MobileMenu,
|
||||
selector: '#mobile-menu',
|
||||
});
|
||||
|
||||
return {
|
||||
MobileMenu: MobileMenu,
|
||||
MobilePreviewDialog: MobilePreviewDialog,
|
||||
export const systrayItem = {
|
||||
Component: MobilePreviewSystray,
|
||||
};
|
||||
});
|
||||
|
||||
registry.category("website_systray").add("MobilePreview", systrayItem, { sequence: 12 });
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
<t t-name="website.MobilePreviewSystray" owl="1">
|
||||
<div class="o_mobile_preview o_menu_systray_item" t-on-click="() => this.websiteService.context.isMobile = !this.websiteService.context.isMobile">
|
||||
<a href="#" accesskey="v"><span title="Mobile preview" role="img" aria-label="Mobile preview" class="fa fa-lg fa-mobile"/></a>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
@@ -3,6 +3,9 @@
|
||||
|
||||
<!-- Snippets menu -->
|
||||
<template id="snippets" inherit_id="web_editor.snippets" primary="True" groups="base.group_user">
|
||||
<xpath expr="//button[@data-action='cancel']" position="before">
|
||||
<button type="button" class="btn btn-secondary" data-action="mobile" title="Mobile Preview" accesskey="v"><span class="fa fa-mobile" style="font-size: 18px;"/></button>
|
||||
</xpath>
|
||||
<xpath expr="//div[@id='snippets_menu']" position="inside">
|
||||
<button type="button" tabindex="3" class="o_we_customize_theme_btn text-uppercase"
|
||||
groups="website.group_website_designer" accesskey="2">
|
||||
|
||||
Reference in New Issue
Block a user