ArcBees / GWTP-Samples

GWTP-Samples
54 stars 82 forks source link

GWT-POLYMER sample works fine with chrome, android but doesn't work with ios, safari, firefox #77

Open spirylics opened 9 years ago

spirylics commented 9 years ago

Firstly, thanks for this great job.

I would like to know if it exists a fix, a trick or an explanation to prevent this : capture d ecran 2015-03-16 a 11 51 21

I use directly this link : http://gwtp-sample-polymer.appspot.com/

Test: osx + chrome: ok osx + safari: nok android lolipop(nexus5) + chrome: ok ios8.1(iphone4s) + safari: nok ios8.1(iphone4s) + chrome: nok ios8.2(ipad air2) + safari: nok ios8.2(ipad air2) + chrome: nok

Thanks

Anthony2539 commented 9 years ago

I did some tests and I get these results :

Test: windows seven + chrome v41: Ok windows seven + firefox v36.0.1: NOK windows seven + IE v11: NOK ios7.1(iphone4) + safari: NOK ios7.1(iphone4) + chrome: NOK

christiangoudreau commented 9 years ago

Unfortunately, Polymer isn't usable on all browser. See: https://www.polymer-project.org/0.5/resources/compatibility.html

Chris-V commented 9 years ago

You need to add polyfills for web components (add the file in your .html). Have a look at https://www.polymer-project.org/0.5/docs/start/platform.html and http://webcomponents.org/

spirylics commented 9 years ago

Oddly, Polymer alone (without gwt) works fine (tested with core-scaffold, core-drawer-panel) on this browsers. For example, https://www.polymer-project.org/0.5/components/core-elements/demo.html#core-animation works fine.

I'm not sure, but gwt-polymer dependency must fetch webcomponent.js.

I've tried 3 methods to integrate GWT and polymer : 1 - I put directly webcomponent.js and html polymer import in my main html. It works, but when I put a widget from gwtp view in my polymer element, drawer panel doesn't work on chrome android (works on ios safari or osx chrome) 2 - I load webcomponent.js and html polymer import in my gwt code thanks to gwtquery. My gwtp view works on chrome & (osx or android), but not on firefox, safari, ios. 3 - I use gwt-polymer dependency like this sample and I have a similar behaviour at method 2.

Chris-V commented 9 years ago

Just looked back at the code and indeed, gwt-polymer loads webcomponent.js (making my last comment irrelevant).

I loaded the sample on IE and I get a similar experience than in your screenshot. Looking at the page source, all I see are web-components CSS. I wonder if it's not only a matter of writing fallback CSS.

meriouma commented 9 years ago

I think it's a timing issue. I'll work on a fix this week, Thanks for reporting

Anthony2539 commented 9 years ago

Thx for your feedback. When you say "it's a timing issue", you mean that the bug is due by a problem of libs synchronization ?

meriouma commented 9 years ago

I believe it might be because the polyfills are loaded too late

spirylics commented 9 years ago

I found a solution in using the method 2.

1 - I've made a custom polymer scaffold which raise an event when component is "domReady"

2 - In my gwt code, I bind this new event and I add my gwtp slots when this event is raised.

Glchriste commented 9 years ago

@spirylics Would you be willing to share you custom polymer scaffold and GWT event code?

spirylics commented 9 years ago

@Glchriste Actually, with polymer 1.x I have no more issue. So I advice you to use polymer 1.x even if scaffold component doesn't exist ; you can easily paper-drawer-panel, paper-header-panel, paper-toolbar directly.

If you want stil use polymer 0.5 :

<link rel="import" href="bower_components/core-toolbar/core-toolbar.html">
<link rel="import" href="bower_components/core-drawer-panel/core-drawer-panel.html">
<link rel="import" href="bower_components/core-header-panel/core-header-panel.html">
<link rel="import" href="bower_components/paper-icon-button/paper-icon-button.html">

<polymer-element name="u-scaffold">
    <template>

        <style>

            :host {
                display: block;
            }

            [drawer] {
                background-color: #fff;
                box-shadow: 1px 0 1px rgba(0, 0, 0, 0.1);
            }

            [main] {
                height: 100%;
                background-color: #eee;
            }

            core-toolbar {
                background-color: #526E9C;
                color: #fff;
            }

            #drawerPanel:not([narrow]) #menuButton {
                display: none;
            }

        </style>

        <core-drawer-panel id="drawerPanel" narrow="{{narrow}}" drawerWidth="{{drawerWidth}}" rightDrawer="{{rightDrawer}}" responsiveWidth="{{responsiveWidth}}" disableSwipe="{{disableSwipe}}">

            <div vertical layout drawer>

                <content select="[navigation], nav"></content>

            </div>

            <core-header-panel id="headerPanel" main mode="{{mode}}">

                <core-toolbar>
                    <template if="{{!rightDrawer}}">
                        <paper-icon-button id="menuButton" icon="menu" on-tap="{{togglePanel}}"></paper-icon-button>
                    </template>
                    <content select="[tool]"></content>
                    <template if="{{rightDrawer}}">
                        <paper-icon-button id="menuButton" icon="menu" on-tap="{{togglePanel}}"></paper-icon-button>
                    </template>
                </core-toolbar>

                <content select="*"></content>

            </core-header-panel>

        </core-drawer-panel>

    </template>
    <script>

        Polymer('u-scaffold', {

            /**
             * Fired when the main content has been scrolled.  `event.detail.target` returns
             * the scrollable element which you can use to access scroll info such as
             * `scrollTop`.
             *
             *     <u-scaffold on-scroll="{{scrollHandler}}">
             *       ...
             *     </u-scaffold>
             *
             *
             *     scrollHandler: function(event) {
     *       var scroller = event.detail.target;
     *       console.log(scroller.scrollTop);
     *     }
             *
             * @event scroll
             */

            publish: {

                /**
                 * Width of the drawer panel.
                 *
                 * @attribute drawerWidth
                 * @type string
                 * @default '256px'
                 */
                drawerWidth: '256px',

                /**
                 * When the browser window size is smaller than the `responsiveWidth`,
                 * `core-drawer-panel` changes to a narrow layout. In narrow layout,
                 * the drawer will be stacked on top of the main panel.
                 *
                 * @attribute responsiveWidth
                 * @type string
                 * @default '600px'
                 */
                responsiveWidth: '600px',

                /**
                 * If true, position the drawer to the right. Also place menu icon to
                 * the right of the content instead of left.
                 *
                 * @attribute rightDrawer
                 * @type boolean
                 * @default false
                 */
                rightDrawer: false,

                /**
                 * If true, swipe to open/close the drawer is disabled.
                 *
                 * @attribute disableSwipe
                 * @type boolean
                 * @default false
                 */
                disableSwipe: false,

                /**
                 * Used to control the header and scrolling behaviour of `core-header-panel`
                 *
                 * @attribute mode
                 * @type string
                 * @default 'seamed'
                 */
                mode: {value: 'seamed', reflect: true}
            },

            init: false,

            ready: function() {
                this._scrollHandler = this.scroll.bind(this);
                this._selectHandler = this.select.bind(this);
                this.$.headerPanel.addEventListener('scroll', this._scrollHandler);
                this.$.drawerPanel.addEventListener('core-select', this._selectHandler);
            },

            domReady: function() {
                this.init = true;
                this.fire('init');
            },

            detached: function() {
                this.$.headerPanel.removeEventListener('scroll', this._scrollHandler);
            },

            /**
             * Toggle the drawer panel
             * @method togglePanel
             */
            togglePanel: function() {
                this.$.drawerPanel.togglePanel();
            },

            /**
             * Open the drawer panel
             * @method openDrawer
             */
            openDrawer: function() {
                this.$.drawerPanel.openDrawer();
            },

            /**
             * Close the drawer panel
             * @method closeDrawer
             */
            closeDrawer: function() {
                this.$.drawerPanel.closeDrawer();
            },

            drawerIsOpen: function() {
                return !this.$.drawerPanel.isMainSelected();
            },

            /**
             * Returns the scrollable element on the main area.
             *
             * @property scroller
             * @type Object
             */
            get scroller() {
                return this.$.headerPanel.scroller;
            },

            scroll: function(e) {
                this.fire('scroll', {target: e.detail.target}, this, false);
            },

            select: function(e) {
                this.fire('select', {target: e.detail.target}, this, false);
            }

        });

    </script>
</polymer-element>
public class ApplicationView extends ViewWithUiHandlers<ApplicationUiHandlers> implements ApplicationPresenter.MyView {
    @UiField
    HTMLPanel root;
    Element scaffold;

    interface Binder extends UiBinder<Widget, ApplicationView> {
    }

    @Inject
    ApplicationView(Binder uiBinder, Toaster toaster) {
        this.toaster = toaster;
        initWidget(uiBinder.createAndBindUi(this));
        this.scaffold = $(root).find("u-scaffold").get(0);
    }

    boolean scaffoldIsInitialized() {
        Boolean init = JsUtils.prop(scaffold, "init");
        return init != null && init;
    }

    void onScaffoldInitialized(Function function) {
        if (scaffoldIsInitialized()) {
            function.f();
        } else {
            $(scaffold).on("init", function);
        }
    }

    @Override
    public void setInSlot(final Object slot, final IsWidget content) {
        onScaffoldInitialized(new Function() {
            @Override
            public void f() {
                if (slot == ApplicationPresenter.SLOT_HEADER_CONTENT) {
                    Element contentEl = content.asWidget().getElement();
                    contentEl.setId("u-top-bar");
                    contentEl.setAttribute("tool", "");
                    root.addAndReplaceElement(content, contentEl.getId());
                } else if (slot == ApplicationPresenter.SLOT_MENU_CONTENT) {
                    Element contentEl = content.asWidget().getElement();
                    contentEl.setId("u-menu");
                    root.addAndReplaceElement(content, contentEl.getId());
                } else if (slot == ApplicationPresenter.SLOT_MAIN_CONTENT) {
                    Element contentEl = content.asWidget().getElement();
                    contentEl.setId("u-content");
                    root.addAndReplaceElement(content, contentEl.getId());
                } else {
                    throw new IllegalStateException("Unknown slot");
                }
            }
        });
    }
}
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
             xmlns:g="urn:import:com.google.gwt.user.client.ui">
    <g:HTMLPanel ui:field="root">
        <u-scaffold mode="standard">
            <core-header-panel navigation="" flex="" mode="standard">
                <div id="u-menu"/>
            </core-header-panel>

            <div id="u-top-bar" tool=""/>

            <div id="u-content"/>
        </u-scaffold>
    </g:HTMLPanel>
</ui:UiBinder>
Glchriste commented 9 years ago

@spirylics Thank you very much!

spirylics commented 9 years ago

@Glchriste if you want to known when a polymer element is attached (ie dom ready) with GWT, you can do that:

Element el;
JsUtils.export(el, "attached", new Function() {
  @Override
  public void f() {
    //here my element is attached
  });

JsUtils comes from GQuery library.