001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.gwt.client.util;
029
030import org.opencms.gwt.client.CmsCoreProvider;
031import org.opencms.gwt.client.ui.CmsIFrame;
032import org.opencms.gwt.client.ui.css.I_CmsLayoutBundle;
033
034import com.google.gwt.user.client.Timer;
035import com.google.gwt.user.client.ui.RootPanel;
036
037/**
038 * Singleton that creates and manages access to the shared iframe used for embedded Vaadin dialogs, mainly in the page editor.
039 */
040public class CmsEmbeddedDialogFrame implements I_CmsEmbeddedDialogFrame {
041
042    /** The loader used to load dialogs - this is set by the Javascript code in the iframe. */
043    private I_CmsEmbeddedDialogLoader m_loader = null;
044
045    /** The actual iframe. */
046    private CmsIFrame m_frame;
047
048    private String m_frameName;
049
050    /**
051     * Hidden default constructor.
052     */
053    protected CmsEmbeddedDialogFrame() {
054
055    }
056
057    /**
058     * Gets the singleton instance.
059     *
060     * @return the instance
061     */
062    public static I_CmsEmbeddedDialogFrame get() {
063
064        CmsEmbeddedDialogFrameWrapper currentWindow = CmsEmbeddedDialogFrameWrapper.window;
065        if (currentWindow.embeddedDialogFrameInstance == null) {
066            currentWindow.embeddedDialogFrameInstance = new CmsEmbeddedDialogFrame();
067        }
068        I_CmsEmbeddedDialogFrame result = currentWindow.embeddedDialogFrameInstance;
069        return result;
070
071    }
072
073    /**
074     * @see org.opencms.gwt.client.util.I_CmsEmbeddedDialogFrame#hide()
075     */
076    @Override
077    public void hide() {
078
079        if (m_frame != null) {
080            setFrameVisible(false);
081        }
082
083    }
084
085    /**
086     * Sets the dialog loader.
087     *
088     * <p>This is called by the Javascript code in the iframe.
089     *
090     * @param loader the class used to load dialogs in the iframe itself
091     */
092    @Override
093    public void installEmbeddedDialogLoader(I_CmsEmbeddedDialogLoader loader) {
094
095        m_loader = loader;
096    }
097
098    /**
099     * @see org.opencms.gwt.client.util.I_CmsEmbeddedDialogFrame#loadDialog(java.lang.String, org.opencms.gwt.client.util.I_CmsEmbeddedDialogHandlerJsCallbacks)
100     */
101    @Override
102    public void loadDialog(String dialogInfoJson, I_CmsEmbeddedDialogHandlerJsCallbacks handler) {
103
104        waitUntilReady(() -> {
105            setDialogHandlerCallbacks(m_frameName, handler);
106            setFrameVisible(true);
107            m_loader.loadDialog(dialogInfoJson);
108        });
109    }
110
111    /**
112     * @see org.opencms.gwt.client.util.I_CmsEmbeddedDialogFrame#preload()
113     */
114    @Override
115    public void preload() {
116
117        waitUntilReady(() -> {/*do nothing*/});
118    }
119
120    /**
121     * Initializes the iframe if it isn't  already, and executes the given action afterwards.
122     *
123     * @param action the action to execute after the iframe is initialized
124     */
125    protected void waitUntilReady(Runnable action) {
126
127        if (m_loader != null) {
128            action.run();
129            return;
130        }
131        if (m_frame == null) {
132            String url = CmsCoreProvider.get().getEmbeddedDialogsUrl();
133            m_frameName = "embeddedDialogFrame-" + Math.random();
134            m_frame = new CmsIFrame(m_frameName, url);
135            m_frame.addStyleName(I_CmsLayoutBundle.INSTANCE.dialogCss().embeddedDialogFrame());
136            setFrameVisible(false);
137            RootPanel.get().add(m_frame);
138        }
139        Timer timer = new Timer() {
140
141            @Override
142            public void run() {
143
144                waitUntilReady(action);
145            }
146        };
147        timer.schedule(200);
148    }
149
150    /**
151     * Sets the dialog handler callbacks in the iframe context.
152     *
153     * @param handler the handler to set
154     */
155    private native void setDialogHandlerCallbacks(String frameName, I_CmsEmbeddedDialogHandlerJsCallbacks handler) /*-{
156        $wnd.frames[frameName].connector = handler;
157    }-*/;
158
159    /**
160     * Shows / hides the frame.
161     *
162     * @param visible true if the frame should be shown
163     */
164    private void setFrameVisible(boolean visible) {
165
166        if (m_frame != null) {
167            String className = I_CmsLayoutBundle.INSTANCE.dialogCss().embeddedDialogFrameHidden();
168            if (visible) {
169                m_frame.removeStyleName(className);
170            } else {
171                m_frame.addStyleName(className);
172            }
173        }
174    }
175
176}