enonic / xp

Enonic XP
https://enonic.com
GNU General Public License v3.0
201 stars 34 forks source link

Scripts injected via pageContributions require page reload in PageEditor #7301

Open Slideshow776 opened 5 years ago

Slideshow776 commented 5 years ago

Bug

Contributed style is not included in preview when apply is clicked in layout. Contributed style is included, however, upon a refresh.

Controller code is shown below.

var thymeleaf = require("/lib/xp/thymeleaf");
var portal = require("/lib/xp/portal");
var util = require("/lib/enonic/util");
var view = resolve("banner.html");

exports.get = function () {
    var component = portal.getComponent();

    var backgroundClass =  "";   

    if (component.config.bgVariant) { backgroundClass = component.config.bgVariant+"-bg"; }

    var model = {
        mainRegion: component.regions['main'],
        title: component.config.title || '',
        description: component.config.description || '',
        backgroundClass: backgroundClass,
    };

    var cssUrl = portal.assetUrl({ path: "css/extentionsMain.css" });

    return {
        body: thymeleaf.render(view, model),
        pageContributions: {
            headEnd: [
                "<link rel='stylesheet' href='" + cssUrl + "'>",
            ],
        },
    };
};
sigdestad commented 5 years ago

Contributions are not injected when adding New components to the page editor, it would require a full Page reload

alansemenov commented 5 years ago

This is not simply when adding a new component, this is after applying changes in the component which trigger save of the content and reload of the page. Looks like a bug to me.

sigdestad commented 4 years ago

Solution to this problem is:

alansemenov commented 4 years ago

Related task: https://github.com/enonic/app-contentstudio/issues/2034

sigdestad commented 4 years ago

It would be really nice to get this fixed, as it is severly affecting usability in the case where a component needs more JS available. This is increasingly relevant with frameworks such as React and friends.

Bellfalasch commented 3 years ago

What's the status on this one? When using React we need to refresh the pages since our assets (js-files) changes for each edit inside a part. We serve them using pageContributions.

rymsha commented 3 years ago

the idea is to send some info via http headers from renderer in EDIT mode. In this case: inform that component introduces pageContributions. CS can read custom headers and decide to reload entire page, instead of injecting the component's html.

sigdestad commented 3 years ago

Feedback from customers indicates we can often inject javascripts directly within the Page in such cases, and the browser will be able to handle it, Even if the same files already exist

alansemenov commented 3 years ago

We don't know which javascripts to inject. We will only be able to get a flag from the backend that a component to be rendered is using page contributions. In this case we will re-render the entire page.

sigdestad commented 3 years ago

I guess the idea was to inject everything from the page contribution into the page along with the component markup?

sigdestad commented 3 years ago

Also, re-rendering page is ok if it is returned with focus on the selected compoent I guess?

Bellfalasch commented 3 years ago

Thanks for the updates here. So, a dream would be seamless loading of scripts and other dependencies, as a page reload will always be like watching Netflix and getting a sudden buffering for a few seconds. However, if we analyze the action the user is performing they are saving a form by clicking the Apply-button, and as such some delay is not unexpected. But it will be important, like Thomas mentions, that the component is given focus again after reload is done (scroll back down to it in the Page Editor, keep the form open, and all that).

We tried to "fool" the browser by just putting all css and js <script/> directly in the part's returning body, but this works only for css, not js (and we didn't find out about JS not working until recently). So trying to piggyback the js scripts with the body is not possible. It is only a full page reload that works - or some frontend JS ninja magic to load scripts runtime but have not investigated possibilites there.

So, yeah we're happy with full page reload if page contributions exists on a part that is being edited or added. It is not the most elegant solutions in the universe, but browser limitations and security kind of sets the rules. Feel free to investigate all this yourselves too. One optimization would be if it is possible for Content Studio to see if the page contributions are different than before, and then reload, otherwise not.