Author: ehillenius
Date: Sat Nov 25 13:53:27 2006
New Revision: 479209

URL: http://svn.apache.org/viewvc?view=rev&rev=479209
Log:
WICKET-100

Modified:
    
incubator/wicket/trunk/wicket-extensions/src/main/java/wicket/extensions/ajax/markup/html/modal/ModalWindow.java

Modified: 
incubator/wicket/trunk/wicket-extensions/src/main/java/wicket/extensions/ajax/markup/html/modal/ModalWindow.java
URL: 
http://svn.apache.org/viewvc/incubator/wicket/trunk/wicket-extensions/src/main/java/wicket/extensions/ajax/markup/html/modal/ModalWindow.java?view=diff&rev=479209&r1=479208&r2=479209
==============================================================================
--- 
incubator/wicket/trunk/wicket-extensions/src/main/java/wicket/extensions/ajax/markup/html/modal/ModalWindow.java
 (original)
+++ 
incubator/wicket/trunk/wicket-extensions/src/main/java/wicket/extensions/ajax/markup/html/modal/ModalWindow.java
 Sat Nov 25 13:53:27 2006
@@ -1,948 +1,943 @@
 /*
  * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
+ * contributor license agreements. See the NOTICE file distributed with this
+ * work for additional information regarding copyright ownership. The ASF
+ * licenses this file to You under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
  * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations 
under
+ * the License.
  */
-package wicket.extensions.ajax.markup.html.modal;
-
-import java.io.Serializable;
-
-import wicket.Application;
-import wicket.Component;
-import wicket.MarkupContainer;
-import wicket.Page;
-import wicket.PageMap;
-import wicket.RequestCycle;
-import wicket.ResourceReference;
-import wicket.Session;
-import wicket.WicketRuntimeException;
-import wicket.ajax.AbstractDefaultAjaxBehavior;
-import wicket.ajax.AjaxRequestTarget;
-import wicket.ajax.IAjaxCallDecorator;
-import wicket.ajax.calldecorator.CancelEventIfNoAjaxDecorator;
-import wicket.behavior.HeaderContributor;
-import wicket.markup.ComponentTag;
-import wicket.markup.html.WebMarkupContainer;
-import wicket.markup.html.panel.Panel;
-import wicket.markup.html.resources.CompressedResourceReference;
-import wicket.request.RequestParameters;
-import wicket.settings.IPageSettings;
-import wicket.util.string.AppendingStringBuffer;
-
-/**
- * Modal window component.
- * <p>
- * Modal window is a draggable window (with either div or iframe content) that
- * prevent user from interacting the rest of page (using a mask) until the
- * window is closed.
- * <p>
- * The window is draggable and optionally resizable. The content can be either
- * <ul>
- * <li><b>a component</b> - you need to add the component to modal window
- * (with id obtained using <code>[EMAIL PROTECTED] #getContentId()}</code>, or
- * <li><b>a page</b> - you need to pass a <code>[EMAIL PROTECTED] 
PageCreator}</code>
- * instance to a <code>[EMAIL PROTECTED] 
#setPageCreator(ModalWindow.PageCreator)}</code>
- * method.
- * </ul>
- * In case the content is a component, it is not rendered until the window is
- * shown (method <code>[EMAIL PROTECTED] #show(AjaxRequestTarget)})</code>. In 
case the
- * content is another page, you can set the desired pagemap name using
- * <code>[EMAIL PROTECTED] #setPageMapName(String)}</code>. Setting pagemap is 
only
- * needed when wicket multiwindow support is on.
- * <p>
- * The window can be made visible from an ajax handler using
- * <code>[EMAIL PROTECTED] #show(AjaxRequestTarget)}</code>.
- * <p>
- * To close the window there are multiple options. Static method
- * <code>[EMAIL PROTECTED] #close(AjaxRequestTarget)}</code> can be used to 
close the
- * window from a handler of ajax link inside the window. By default the close
- * button in the upper right corner of the window closes it. This behavior can
- * be altered using
- * <code>[EMAIL PROTECTED] 
#setCloseButtonCallback(ModalWindow.CloseButtonCallback)}</code>.
- * If you want to be notified when the window is closed (either using the close
- * button or calling <code>[EMAIL PROTECTED] 
#close(AjaxRequestTarget)})</code>, you
- * can use
- * <code>[EMAIL PROTECTED] 
#setWindowClosedCallback(ModalWindow.WindowClosedCallback)}</code>.
- * <p>
- * Title is specified using [EMAIL PROTECTED] #setTitle(String)}. If the 
content is a page
- * (iframe), the title can remain unset, in that case title from the page 
inside
- * window will be shown.
- * <p>
- * There are several options to specify the visual properties of the window. In
- * all methods where size is expected, width refers to width of entire window
- * (including frame), height refers to the height of window content (without
- * frame).
- * <p>
- * <ul>
- * <li><code>[EMAIL PROTECTED] #setResizable(boolean)}</code> specifies, 
whether the
- * window can be resized.
- * <li><code>[EMAIL PROTECTED] #setInitialWidth(int)}</code> and
- * <code>[EMAIL PROTECTED] #setInitialHeight(int)}</code> specify the initial 
width and
- * height of window. If the window is resizable, the unit of these dimensions 
is
- * always "px". If the window is not resizable, the unit can be specified using
- * <code>[EMAIL PROTECTED] #setWidthUnit(String)}</code> and
- * <code>[EMAIL PROTECTED] #setHeightUnit(String)}</code>. If the window is not
- * resizable and the content is a component (not a page), the initial height
- * value can be ignored and the actual height can be determined from the height
- * of the content. To enable this behavior use
- * <code>[EMAIL PROTECTED] #setUseInitialHeight(boolean)}</code>.
- * <li>The window position (and size if the window is resizable) can be stored
- * in a cookie, so that it is preserved when window is close. The name of the
- * cookie is specified via <code>[EMAIL PROTECTED] 
#setCookieName(String)}</code>. If
- * the name is <code>null</code>, position is not stored (initial width and
- * height are always used). Default cookie name is generated using
- * <code>getClassRelativePath()</code>.
- * <li><code>[EMAIL PROTECTED] #setMinimalWidth(int)}</code> and
- * <code>[EMAIL PROTECTED] #setMinimalHeight(int)}</code> set the minimal 
dimensions of
- * resizable window.
- * <li>Modal window can chose between two colors of frame.
- * <code>[EMAIL PROTECTED] #setCssClassName(String)}</code> sets the dialog 
css class,
- * possible values are <code>[EMAIL PROTECTED] #CSS_CLASS_BLUE}</code> for 
blue frame and
- * <code>[EMAIL PROTECTED] #CSS_CLASS_GRAY}</code> for gray frame.
- * <li>Mask (element that prevents user from interacting the rest of the page)
- * can be either transparent or semitransparent.
- * <code>[EMAIL PROTECTED] #setMaskType(ModalWindow.MaskType)}</code> alters 
this.
- * </ul>
- * 
- * @see IPageSettings#setAutomaticMultiWindowSupport(boolean)
- * @author Matej Knopp
- */
-public class ModalWindow extends Panel<Object>
-{
-       private static final long serialVersionUID = 1L;
-
-       private static ResourceReference JAVASCRIPT = new 
CompressedResourceReference(
-                       ModalWindow.class, "res/modal.js");
-
-       private static ResourceReference CSS = new CompressedResourceReference(
-                       ModalWindow.class, "res/modal.css");
-
-       /**
-        * Creates a new modal window component.
-        * 
-        * @param parent
-        *            Parent component
-        * @param id
-        *            Id of component
-        */
-       public ModalWindow(MarkupContainer parent, String id)
-       {
-               super(parent, id);
-               empty = new WebMarkupContainer(this, getContentId());
-
-               this.cookieName = "modal-window-" + getClassRelativePath();     
        
-               
-               add(new CloseButtonBehavior());
-               add(new WindowClosedBehavior());
-               add(HeaderContributor.forJavaScript(JAVASCRIPT));
-               add(HeaderContributor.forCss(CSS));
-       }
-
-       /**
-        * Interface for lazy page creation. The advantage of creating page 
using
-        * this interface over just passing a page instance is that page 
created in
-        * <code>[EMAIL PROTECTED] #createPage()}</code> will have the pagemap 
automatically
-        * set to the pagemap specified for <code>[EMAIL PROTECTED] 
ModalWindow}</code>.
-        * 
-        * @author Matej Knopp
-        */
-       public static interface PageCreator extends Serializable
-       {
-               /**
-                * Creates a new instance of content page.
-                * 
-                * @return new page instance
-                */
-               public Page createPage();
-       }
-
-       /**
-        * Callback for close button that contains a method that is invoked 
after
-        * the button has been clicked. If no callback instance is specified 
using
-        * <code>[EMAIL PROTECTED] 
#setCloseButtonCallback(ModalWindow.CloseButtonCallback)}</code>,
-        * no ajax request will be fired. Clicking the button will just close 
the
-        * window.
-        * 
-        * @author Matej Knopp
-        */
-       public static interface CloseButtonCallback extends Serializable
-       {
-               /**
-                * Methods invoked after the button has been clicked. The 
invokation is
-                * done using an ajax call, so <code>[EMAIL PROTECTED] 
AjaxRequestTarget}</code>
-                * instance is available.
-                * 
-                * @param target
-                *            <code>[EMAIL PROTECTED] AjaxRequestTarget}</code> 
instance bound
-                *            with the ajax reuqest.
-                * 
-                * @return True if the window can be closed (will close the 
window),
-                *         false otherwise
-                */
-               public boolean onCloseButtonClicked(AjaxRequestTarget target);
-       }
-
-       /**
-        * Callback called after the window has been closed. If no callback 
instance
-        * is specified using
-        * [EMAIL PROTECTED] 
ModalWindow#setWindowClosedCallback(ModalWindow.WindowClosedCallback)},
-        * no ajax request will be fired.
-        * 
-        * @author Matej Knopp
-        */
-       public static interface WindowClosedCallback extends Serializable
-       {
-               /**
-                * Called after the window has been closed.
-                * 
-                * @param target
-                *            <code>[EMAIL PROTECTED] AjaxRequestTarget}</code> 
instance bound
-                *            with the ajax reuqest.
-                */
-               public void onClose(AjaxRequestTarget target);
-       }
-
-       /**
-        * Sets the name of the page ma for the content page. This makes only 
sense
-        * when the content is a page, not a component and if wicket multiwindow
-        * support is turned on.
-        * 
-        * @param pageMapName
-        *            Name of the page map
-        */
-       public void setPageMapName(String pageMapName)
-       {
-               this.pageMapName = pageMapName;
-       }
-
-       /**
-        * Returns the page map name.
-        * 
-        * @return The page map name.
-        */
-       public String getPageMapName()
-       {
-               return pageMapName;
-       }
-
-       /**
-        * Sets the <code>[EMAIL PROTECTED] PageCreator}</code> instance. The 
instance is
-        * only used when no custom component has been added to the dialog.
-        * 
-        * @param creator
-        *            <code>[EMAIL PROTECTED] PageCreator}</code> instance
-        */
-       public void setPageCreator(PageCreator creator)
-       {
-               this.pageCreator = creator;
-       }
-
-       /**
-        * Sets the <code>[EMAIL PROTECTED] CloseButtonCallback}</code> 
instance.
-        * 
-        * @param callback
-        *            Callback instance
-        */
-       public void setCloseButtonCallback(CloseButtonCallback callback)
-       {
-               this.closeButtonCallback = callback;
-       }
-
-       /**
-        * Sets the <code>@{link [EMAIL PROTECTED] WindowClosedCallback}</code> 
instance.
-        * 
-        * @param callback
-        *            Callback instance
-        */
-       public void setWindowClosedCallback(WindowClosedCallback callback)
-       {
-               this.windowClosedCallback = callback;
-       }
-
-       /**
-        * Shows the modal window.
-        * 
-        * @param target
-        *            Request target associated with current ajax request.
-        */
-       public void show(AjaxRequestTarget target)
-       {
-               target.addComponent(this);
-               target.appendJavascript(getWindowOpenJavascript());
-               shown = true;
-       }
-
-       /**
-        * Hides the modal window.
-        * 
-        * @param target
-        *            Request target associated with current ajax request.
-        */
-       public static final void close(AjaxRequestTarget target)
-       {               
-               target.appendJavascript(getCloseJavacript());
-       }
-       
-       /**
-        * @return javascript that closes current modal window
-        */
-       private static String getCloseJavacript() 
-       {
-               return
-                       "var win;\n" +
-                       "try {\n" +             
-                       "       win = window.parent.Wicket.Window;\n" + 
-                       "} catch (ignore) {\n" +
-                       "}\n" +                 
-                       "if (typeof(win) != \"undefined\" && 
typeof(win.current) != \"undefined\") {\n" +
-                       "       window.parent.setTimeout(function() {\n" +
-                       "               win.current.close();\n" +       
-                       "       }, 0);\n" +
-                       "}";
-       }
-
-       /**
-        * Returns the id of content component.
-        * 
-        * <pre>
-        * ModalWindow window = new ModalWindow(parent, &quot;window&quot;);
-        * new MyPanel(window, window.getContentId());
-        * </pre>
-        * 
-        * @return Id of content component.
-        */
-       public String getContentId()
-       {
-               return "content";
-       }
-
-       /**
-        * Sets the minimal width of window. This value is only used if the 
window
-        * is resizable. The width is specified in pixels and it is the width of
-        * entire window (including frame).
-        * 
-        * @param minimalWidth
-        *            Minimal window width.
-        */
-       public void setMinimalWidth(int minimalWidth)
-       {
-               this.minimalWidth = minimalWidth;
-       }
-
-       /**
-        * Returns the minimal width of window (in pixels).
-        * 
-        * @return Minimal width of window
-        */
-       public int getMinimalWidth()
-       {
-               return minimalWidth;
-       }
-
-       /**
-        * Sets the minimal height of window. This value is only used if window 
is
-        * resizable. The height is specified in pixels and it is the height of
-        * window content (without frame).
-        * 
-        * @param minimalHeight
-        *            Minimal height
-        */
-       public void setMinimalHeight(int minimalHeight)
-       {
-               this.minimalHeight = minimalHeight;
-       }
-
-       /**
-        * Returns the minimal height of window (in pixels).
-        * 
-        * @return Minimal height of window
-        */
-       public int getMinimalHeight()
-       {
-               return minimalHeight;
-       }
-
-       /**
-        * CSS class for window with blue border.
-        */
-       public final static String CSS_CLASS_BLUE = "w_blue";
-
-       /**
-        * CSS class for window with gray border.
-        */
-       public final static String CSS_CLASS_GRAY = "w_silver";
-
-       /**
-        * Sets the CSS class name for this window. This class affects the look 
of
-        * window frame. Possible values (if you don't make your style sheet) 
are
-        * <code>[EMAIL PROTECTED] #CSS_CLASS_BLUE}</code> and
-        * <code>[EMAIL PROTECTED] #CSS_CLASS_GRAY}</code>.
-        * 
-        * @param cssClassName
-        */
-       public void setCssClassName(String cssClassName)
-       {
-               this.cssClassName = cssClassName;
-       }
-
-       /**
-        * Returns the CSS class name for this window.
-        * 
-        * @return CSS class name
-        */
-       public String getCssClassName()
-       {
-               return cssClassName;
-       }
-
-       /**
-        * Sets the initial width of the window. The width refers to the width 
of
-        * entire window (including frame). If the window is resizable, the 
width
-        * unit is always "px". If the window is not resizable, the unit can be
-        * specified using [EMAIL PROTECTED] #setWidthUnit(String)}. If cookie 
name is set and
-        * window is resizable, the initial width may be ignored in favor of 
width
-        * stored in cookie.
-        * 
-        * @param initialWidth
-        *            Initial width of the window
-        */
-       public void setInitialWidth(int initialWidth)
-       {
-               this.initialWidth = initialWidth;
-       }
-
-       /**
-        * Returns the initial width of the window.
-        * 
-        * @return Initial height of the window
-        */
-       public int getInitialWidth()
-       {
-               return initialWidth;
-       }
-
-       /**
-        * Sets the initial height of the window. The height refers to the 
height of
-        * window content (without frame). If the window is resizable, the 
height
-        * unit is always "px". If the window is not resizable, the unit can be
-        * specified using [EMAIL PROTECTED] #setHeightUnit(String)}. If cookie 
name is set
-        * and window is resizable, the initial height may be ignred in favor of
-        * height stored in cookie.
-        * 
-        * @param initialHeight
-        *            Initial height of the window
-        */
-       public void setInitialHeight(int initialHeight)
-       {
-               this.initialHeight = initialHeight;
-       }
-
-       /**
-        * Returns the initial height of the window.
-        * 
-        * @return Initial height of the window
-        */
-       public int getInitialHeight()
-       {
-               return initialHeight;
-       }
-
-       /**
-        * Sets whether to use initial height or preserve the real content 
height.
-        * This can only be used if the content is a component (not a page) and 
the
-        * window is not resizable.
-        * 
-        * @param useInitialHeight
-        *            Whether to use initial height instead of preserving 
content
-        *            height instead of using initial height
-        */
-       public void setUseInitialHeight(boolean useInitialHeight)
-       {
-               this.useInitialHeight = useInitialHeight;
-       }
-
-       /**
-        * Returns true if the initial height should be used (in favour of
-        * preserving real content height).
-        * 
-        * @return True if initial height should be used, false is real content
-        *         height should be preserved (valid only if the window is not
-        *         resizable and the content is a component (not a page)
-        */
-       public boolean isUseInitialHeight()
-       {
-               return useInitialHeight;
-       }
-
-       /**
-        * Sets whether the user will be able to resize the window.
-        * 
-        * @param resizable
-        *            Whether the window is resizable
-        */
-       public void setResizable(boolean resizable)
-       {
-               this.resizable = resizable;
-       }
-
-       /**
-        * Returns whether the window is resizable.
-        * 
-        * @return True if the window is resizable, false otherwise
-        */
-       public boolean isResizable()
-       {
-               return resizable;
-       }
-
-       /**
-        * Sets the CSS unit used for initial window width. This is only 
applicable
-        * when the window is not resizable.
-        * 
-        * @param widthUnit
-        *            CSS unit for initial window width.
-        */
-       public void setWidthUnit(String widthUnit)
-       {
-               this.widthUnit = widthUnit;
-       }
-
-       /**
-        * Returns the CSS unit for initial window width.
-        * 
-        * @return CSS unit for initial window width.
-        */
-       public String getWidthUnit()
-       {
-               return widthUnit;
-       }
-
-       /**
-        * Sets the CSS unit used for initial window height. This is only 
applicable
-        * when the window is not resizable.
-        * 
-        * @param heightUnit
-        *            CSS unit for initial window height.
-        */
-       public void setHeightUnit(String heightUnit)
-       {
-               this.heightUnit = heightUnit;
-       }
-
-       /**
-        * Retrns the CSS unit for initial window height.
-        * 
-        * @return CSS unit for initial window height.
-        */
-       public String getHeightUnit()
-       {
-               return heightUnit;
-       }
-
-       /**
-        * Sets the name of the cookie that is used to remeber window position 
(and
-        * size if the window is resizable).
-        * 
-        * @param cookieName
-        *            Name of the cookie
-        */
-       public void setCookieName(String cookieName)
-       {
-               this.cookieName = cookieName;
-       }
-
-       /**
-        * Returns the name of cookie that is used to remebember window position
-        * (and size if the window is resizable).
-        * 
-        * @return Name of the cookie
-        */
-       public String getCookieName()
-       {
-               return cookieName;
-       }
-
-       /**
-        * Sets the title of window. If the window is a page, title can be
-        * <code>null</code>. In that case it will display the title document
-        * inside the window.
-        * 
-        * @param title
-        *            Title of the window
-        */
-       public void setTitle(String title)
-       {
-               this.title = title;
-       }
-
-       /**
-        * Returns the title of the window.
-        * 
-        * @return Title of the window
-        */
-       public String getTitle()
-       {
-               return title;
-       }
-
-       /**
-        * Mask is the element behind the window, that prevents user from
-        * interacting the rest of page. Mask can be either
-        * <ul>
-        * <li><code>[EMAIL PROTECTED] #TRANSPARENT}</code> - the mask is 
invisible
-        * <li><code>[EMAIL PROTECTED] #SEMI_TRANSPARENT}</code> - the mask is 
black with
-        * small opacity (10%)
-        * </ul>
-        * 
-        * @author Matej Knopp
-        */
-       public enum MaskType {
-               /**
-                * Transparent mask (not visible).
-                */
-               TRANSPARENT,
-
-               /**
-                * Visible mask (black with low opacity).
-                */
-               SEMI_TRANSPARENT
-       };
-
-       /**
-        * Sets the mask type of the window.
-        * 
-        * @param mask
-        *            The mask type
-        */
-       public void setMaskType(MaskType mask)
-       {
-               this.maskType = mask;
-       }
-
-       /**
-        * Returns the mask type of the window
-        * 
-        * @return The mask type
-        */
-       public MaskType getMaskType()
-       {
-               return maskType;
-       }
-
-       /**
-        * Creates the page.
-        * 
-        * @return Page instance or null if page couldn't be created.
-        */
-       private Page createPage()
-       {
-               if (pageCreator == null)
-               {
-                       return null;
-               }
-               else
-               {
-                       RequestParameters parameters = 
RequestCycle.get().getRequest().getRequestParameters();
-                       String oldPageMapName = parameters.getPageMapName();
-
-                       // if there is a pagemap name specified and multiwindow 
support is
-                       // on
-                       if (getPageMapName() != null
-                                       && 
Application.get().getPageSettings().getAutomaticMultiWindowSupport() == true)
-                       {
-                               // try to find out whether the pagemap already 
exists
-                               Session session = Session.get();
-                               if (session.pageMapForName(getPageMapName(), 
false) == null)
-                               {
-                                       deletePageMap = true;
-                               }
-                               parameters.setPageMapName(getPageMapName());
-                       }
-                       try
-                       {
-                               Page page = pageCreator.createPage();
-                               return page;
-                       }
-                       finally
-                       {
-                               parameters.setPageMapName(oldPageMapName);
-                       }
-               }
-       }
-
-       /**
-        * @see wicket.Component#onAttach()
-        */
-       @Override
-       protected void onAttach()
-       {
-               getContent().setOutputMarkupId(true);
-               getContent().setVisible(shown);
-       }
-
-       /**
-        * @see 
wicket.markup.html.panel.Panel#onComponentTag(wicket.markup.ComponentTag)
-        */
-       @Override
-       protected void onComponentTag(ComponentTag tag)
-       {
-               super.onComponentTag(tag);
-               tag.put("style", "display:none");
-       }
-
-
-       /**
-        * Returns a content component. In case user haven't specified any 
content
-        * component, it returns an empty WebMarkupContainer.
-        * 
-        * @return Content component
-        */
-       private Component getContent()
-       {
-               return get(getContentId());
-       }
-
-       /**
-        * Returns true if user has added own component to the window.
-        * 
-        * @return True if user has added own component to the window, false
-        *         otherwise.
-        */
-       private boolean isCustomComponent()
-       {
-               return getContent() != empty;
-       }
-
-       /**
-        * @see wicket.MarkupContainer#remove(wicket.Component)
-        */
-       @Override
-       public void remove(Component component)
-       {
-               super.remove(component);
-               if (component.getId().equals(getContentId()))
-                       empty = new WebMarkupContainer(this, getContentId());
-       }
-
-       /**
-        * @author Matej Knopp
-        */
-       private class WindowClosedBehavior extends AbstractDefaultAjaxBehavior
-       {
-               private static final long serialVersionUID = 1L;
-
-               @Override
-               protected void respond(AjaxRequestTarget target)
-               {
-                       shown = false;
-
-                       // should we cleanup the pagemap?
-                       if (deletePageMap == true)
-                       {
-                               // get the pagemap
-                               Session session = Session.get();
-                               PageMap pageMap = 
session.pageMapForName(getPageMapName(), false);
-
-                               // if there is any remove it
-                               if (pageMap != null)
-                               {
-                                       session.removePageMap(pageMap);
-                                       deletePageMap = false;
-                               }
-                       }
-
-                       if (windowClosedCallback != null)
-                       {
-                               windowClosedCallback.onClose(target);
-                       }
-               }
-
-               @Override
-               public CharSequence getCallbackScript()
-               {
-                       return super.getCallbackScript();
-               }
-       };
-
-       /**
-        * @author Matej Knopp
-        */
-       private class CloseButtonBehavior extends AbstractDefaultAjaxBehavior
-       {
-               private static final long serialVersionUID = 1L;
-
-               @Override
-               protected void respond(AjaxRequestTarget target)
-               {
-                       if (closeButtonCallback == null
-                                       || 
closeButtonCallback.onCloseButtonClicked(target) == true)
-                       {
-                               
target.appendJavascript("Wicket.Window.get().close();");
-                       }
-               }
-
-               @Override
-               protected IAjaxCallDecorator getAjaxCallDecorator()
-               {
-                       return new 
CancelEventIfNoAjaxDecorator(super.getAjaxCallDecorator());
-               }
-
-               @Override
-               public CharSequence getCallbackScript()
-               {
-                       return super.getCallbackScript();
-               }
-       }
-
-       /**
-        * Returns the markup id of the component.
-        * 
-        * @return component id
-        */
-       private String getContentMarkupId()
-       {
-               return getContent().getMarkupId();
-       }
-
-       /**
-        * Replaces all occurences of " in string with \".
-        * 
-        * @param string 
-        *                      String to be escaped.
-        * 
-        * @return escaped string
-        */
-       private String escapeQuotes(String string)
-       {
-               if (string.indexOf('"') != -1)
-               {
-                       string = string.replace("\"", "\\\"");
-               }
-               return string;
-       }
-
-       /**
-        * Returns the javascript used to open the window.
-        * 
-        * @return javascript that opens the window
-        */
-       private String getWindowOpenJavascript()
-       {
-               AppendingStringBuffer buffer = new AppendingStringBuffer();
-
-               if (isCustomComponent() == true)
-               {
-                       buffer.append("var element = 
document.getElementById(\"" + getContentMarkupId() + "\");\n");
-               }
-
-               buffer.append("var settings = new Object();\n");
-               buffer.append("settings.minWidth=" + getMinimalWidth() + ";\n");
-               buffer.append("settings.minHeight=" + getMinimalHeight() + 
";\n");
-               buffer.append("settings.className=\"" + getCssClassName() + 
"\";\n");
-               buffer.append("settings.width=\"" + getInitialWidth() + 
"\";\n");
-
-               if (isUseInitialHeight() == true || isCustomComponent() == 
false)
-                       buffer.append("settings.height=\"" + getInitialHeight() 
+ "\";\n");
-               else
-                       buffer.append("settings.height=null;\n");
-
-               buffer.append("settings.resizable=" + 
Boolean.toString(isResizable()) + ";\n");
-
-               if (isResizable() == false)
-               {
-                       buffer.append("settings.widthUnit=\"" + getWidthUnit() 
+ "\";\n");
-                       buffer.append("settings.heightUnit=\"" + 
getHeightUnit() + "\";\n");
-               }
-
-               if (isCustomComponent() == false)
-               {
-                       Page page = createPage();
-                       if (page == null)
-                       {
-                               throw new WicketRuntimeException("Error 
creating page for modal dialog.");
-                       }
-                       buffer.append("settings.src=\"" + 
RequestCycle.get().urlFor(page) + "\";\n");
-
-                       if (getPageMapName() != null)
-                       {
-                               buffer.append("settings.iframeName=\"" + 
getPageMapName() + "\";\n");
-                       }
-               }
-               else
-               {
-                       buffer.append("settings.element = element;\n");
-               }
-
-               if (getCookieName() != null)
-               {
-                       buffer.append("settings.cookieId=\"" + getCookieName() 
+ "\";\n");
-               }
-
-               if (getTitle() != null)
-               {
-                       buffer.append("settings.title=\"" + 
escapeQuotes(getTitle()) + "\";\n");
-               }
-
-               if (getMaskType() == MaskType.TRANSPARENT)
-               {
-                       buffer.append("settings.mask=\"transparent\";\n");
-               }
-               else if (getMaskType() == MaskType.SEMI_TRANSPARENT)
-               {
-                       buffer.append("settings.mask=\"semi-transparent\";\n");
-               }
-
-               if (closeButtonCallback != null)
-               {
-                       CloseButtonBehavior behavior = 
(CloseButtonBehavior)getBehaviors(
-                                       CloseButtonBehavior.class).get(0);
-                       buffer.append("settings.onCloseButton = function() { " 
+ behavior.getCallbackScript()
-                                       + "};\n");
-               }
-
-               WindowClosedBehavior behavior = 
(WindowClosedBehavior)getBehaviors(
-                               WindowClosedBehavior.class).get(0);
-               buffer.append("settings.onClose = function() { " + 
behavior.getCallbackScript() + " };\n");
-
-               buffer.append("Wicket.Window.create(settings).show();\n");
-
-               return buffer.toString();
-       }
-
-
-       private boolean deletePageMap = false;
-       private boolean shown = false;
-
-       // empty container - used when no component is added
-       private WebMarkupContainer empty;
-
-       private int minimalWidth = 200;
-       private int minimalHeight = 200;
-       private String cssClassName = CSS_CLASS_BLUE;
-       private int initialWidth = 600;
-       private int initialHeight = 400;
-       private boolean useInitialHeight = true;
-       private boolean resizable = true;
-       private String widthUnit = "px";
-       private String heightUnit = "px";
-       private String cookieName;
-       private String title = null;
-       private MaskType maskType = MaskType.SEMI_TRANSPARENT;
-
-       private String pageMapName = "modal-dialog-pagemap";
-
-       private PageCreator pageCreator = null;
-       private CloseButtonCallback closeButtonCallback = null;
-       private WindowClosedCallback windowClosedCallback = null;
-}
+package wicket.extensions.ajax.markup.html.modal;
+
+import java.io.Serializable;
+
+import wicket.Application;
+import wicket.Component;
+import wicket.IPageMap;
+import wicket.MarkupContainer;
+import wicket.Page;
+import wicket.RequestCycle;
+import wicket.ResourceReference;
+import wicket.Session;
+import wicket.WicketRuntimeException;
+import wicket.ajax.AbstractDefaultAjaxBehavior;
+import wicket.ajax.AjaxRequestTarget;
+import wicket.ajax.IAjaxCallDecorator;
+import wicket.ajax.calldecorator.CancelEventIfNoAjaxDecorator;
+import wicket.behavior.HeaderContributor;
+import wicket.markup.ComponentTag;
+import wicket.markup.html.WebMarkupContainer;
+import wicket.markup.html.panel.Panel;
+import wicket.markup.html.resources.CompressedResourceReference;
+import wicket.request.RequestParameters;
+import wicket.settings.IPageSettings;
+import wicket.util.string.AppendingStringBuffer;
+
+/**
+ * Modal window component.
+ * <p>
+ * Modal window is a draggable window (with either div or iframe content) that
+ * prevent user from interacting the rest of page (using a mask) until the
+ * window is closed.
+ * <p>
+ * The window is draggable and optionally resizable. The content can be either
+ * <ul>
+ * <li><b>a component</b> - you need to add the component to modal window
+ * (with id obtained using <code>[EMAIL PROTECTED] #getContentId()}</code>, or
+ * <li><b>a page</b> - you need to pass a <code>[EMAIL PROTECTED] 
PageCreator}</code>
+ * instance to a <code>[EMAIL PROTECTED] 
#setPageCreator(ModalWindow.PageCreator)}</code>
+ * method.
+ * </ul>
+ * In case the content is a component, it is not rendered until the window is
+ * shown (method <code>[EMAIL PROTECTED] #show(AjaxRequestTarget)})</code>. In 
case the
+ * content is another page, you can set the desired pagemap name using
+ * <code>[EMAIL PROTECTED] #setPageMapName(String)}</code>. Setting pagemap is 
only
+ * needed when wicket multiwindow support is on.
+ * <p>
+ * The window can be made visible from an ajax handler using
+ * <code>[EMAIL PROTECTED] #show(AjaxRequestTarget)}</code>.
+ * <p>
+ * To close the window there are multiple options. Static method
+ * <code>[EMAIL PROTECTED] #close(AjaxRequestTarget)}</code> can be used to 
close the
+ * window from a handler of ajax link inside the window. By default the close
+ * button in the upper right corner of the window closes it. This behavior can
+ * be altered using
+ * <code>[EMAIL PROTECTED] 
#setCloseButtonCallback(ModalWindow.CloseButtonCallback)}</code>.
+ * If you want to be notified when the window is closed (either using the close
+ * button or calling <code>[EMAIL PROTECTED] 
#close(AjaxRequestTarget)})</code>, you
+ * can use
+ * <code>[EMAIL PROTECTED] 
#setWindowClosedCallback(ModalWindow.WindowClosedCallback)}</code>.
+ * <p>
+ * Title is specified using [EMAIL PROTECTED] #setTitle(String)}. If the 
content is a page
+ * (iframe), the title can remain unset, in that case title from the page 
inside
+ * window will be shown.
+ * <p>
+ * There are several options to specify the visual properties of the window. In
+ * all methods where size is expected, width refers to width of entire window
+ * (including frame), height refers to the height of window content (without
+ * frame).
+ * <p>
+ * <ul>
+ * <li><code>[EMAIL PROTECTED] #setResizable(boolean)}</code> specifies, 
whether the
+ * window can be resized.
+ * <li><code>[EMAIL PROTECTED] #setInitialWidth(int)}</code> and
+ * <code>[EMAIL PROTECTED] #setInitialHeight(int)}</code> specify the initial 
width and
+ * height of window. If the window is resizable, the unit of these dimensions 
is
+ * always "px". If the window is not resizable, the unit can be specified using
+ * <code>[EMAIL PROTECTED] #setWidthUnit(String)}</code> and
+ * <code>[EMAIL PROTECTED] #setHeightUnit(String)}</code>. If the window is not
+ * resizable and the content is a component (not a page), the initial height
+ * value can be ignored and the actual height can be determined from the height
+ * of the content. To enable this behavior use
+ * <code>[EMAIL PROTECTED] #setUseInitialHeight(boolean)}</code>.
+ * <li>The window position (and size if the window is resizable) can be stored
+ * in a cookie, so that it is preserved when window is close. The name of the
+ * cookie is specified via <code>[EMAIL PROTECTED] 
#setCookieName(String)}</code>. If
+ * the name is <code>null</code>, position is not stored (initial width and
+ * height are always used). Default cookie name is generated using
+ * <code>getClassRelativePath()</code>.
+ * <li><code>[EMAIL PROTECTED] #setMinimalWidth(int)}</code> and
+ * <code>[EMAIL PROTECTED] #setMinimalHeight(int)}</code> set the minimal 
dimensions of
+ * resizable window.
+ * <li>Modal window can chose between two colors of frame.
+ * <code>[EMAIL PROTECTED] #setCssClassName(String)}</code> sets the dialog 
css class,
+ * possible values are <code>[EMAIL PROTECTED] #CSS_CLASS_BLUE}</code> for 
blue frame and
+ * <code>[EMAIL PROTECTED] #CSS_CLASS_GRAY}</code> for gray frame.
+ * <li>Mask (element that prevents user from interacting the rest of the page)
+ * can be either transparent or semitransparent.
+ * <code>[EMAIL PROTECTED] #setMaskType(ModalWindow.MaskType)}</code> alters 
this.
+ * </ul>
+ * 
+ * @see IPageSettings#setAutomaticMultiWindowSupport(boolean)
+ * @author Matej Knopp
+ */
+public class ModalWindow extends Panel<Object>
+{
+       private static final long serialVersionUID = 1L;
+
+       private static ResourceReference JAVASCRIPT = new 
CompressedResourceReference(
+                       ModalWindow.class, "res/modal.js");
+
+       private static ResourceReference CSS = new 
CompressedResourceReference(ModalWindow.class,
+                       "res/modal.css");
+
+       /**
+        * Creates a new modal window component.
+        * 
+        * @param parent
+        *            Parent component
+        * @param id
+        *            Id of component
+        */
+       public ModalWindow(MarkupContainer parent, String id)
+       {
+               super(parent, id);
+               empty = new WebMarkupContainer(this, getContentId());
+
+               this.cookieName = "modal-window-" + getClassRelativePath();
+
+               add(new CloseButtonBehavior());
+               add(new WindowClosedBehavior());
+               add(HeaderContributor.forJavaScript(JAVASCRIPT));
+               add(HeaderContributor.forCss(CSS));
+       }
+
+       /**
+        * Interface for lazy page creation. The advantage of creating page 
using
+        * this interface over just passing a page instance is that page 
created in
+        * <code>[EMAIL PROTECTED] #createPage()}</code> will have the pagemap 
automatically
+        * set to the pagemap specified for <code>[EMAIL PROTECTED] 
ModalWindow}</code>.
+        * 
+        * @author Matej Knopp
+        */
+       public static interface PageCreator extends Serializable
+       {
+               /**
+                * Creates a new instance of content page.
+                * 
+                * @return new page instance
+                */
+               public Page createPage();
+       }
+
+       /**
+        * Callback for close button that contains a method that is invoked 
after
+        * the button has been clicked. If no callback instance is specified 
using
+        * <code>[EMAIL PROTECTED] 
#setCloseButtonCallback(ModalWindow.CloseButtonCallback)}</code>,
+        * no ajax request will be fired. Clicking the button will just close 
the
+        * window.
+        * 
+        * @author Matej Knopp
+        */
+       public static interface CloseButtonCallback extends Serializable
+       {
+               /**
+                * Methods invoked after the button has been clicked. The 
invokation is
+                * done using an ajax call, so <code>[EMAIL PROTECTED] 
AjaxRequestTarget}</code>
+                * instance is available.
+                * 
+                * @param target
+                *            <code>[EMAIL PROTECTED] AjaxRequestTarget}</code> 
instance bound
+                *            with the ajax reuqest.
+                * 
+                * @return True if the window can be closed (will close the 
window),
+                *         false otherwise
+                */
+               public boolean onCloseButtonClicked(AjaxRequestTarget target);
+       }
+
+       /**
+        * Callback called after the window has been closed. If no callback 
instance
+        * is specified using
+        * [EMAIL PROTECTED] 
ModalWindow#setWindowClosedCallback(ModalWindow.WindowClosedCallback)},
+        * no ajax request will be fired.
+        * 
+        * @author Matej Knopp
+        */
+       public static interface WindowClosedCallback extends Serializable
+       {
+               /**
+                * Called after the window has been closed.
+                * 
+                * @param target
+                *            <code>[EMAIL PROTECTED] AjaxRequestTarget}</code> 
instance bound
+                *            with the ajax reuqest.
+                */
+               public void onClose(AjaxRequestTarget target);
+       }
+
+       /**
+        * Sets the name of the page ma for the content page. This makes only 
sense
+        * when the content is a page, not a component and if wicket multiwindow
+        * support is turned on.
+        * 
+        * @param pageMapName
+        *            Name of the page map
+        */
+       public void setPageMapName(String pageMapName)
+       {
+               this.pageMapName = pageMapName;
+       }
+
+       /**
+        * Returns the page map name.
+        * 
+        * @return The page map name.
+        */
+       public String getPageMapName()
+       {
+               return pageMapName;
+       }
+
+       /**
+        * Sets the <code>[EMAIL PROTECTED] PageCreator}</code> instance. The 
instance is
+        * only used when no custom component has been added to the dialog.
+        * 
+        * @param creator
+        *            <code>[EMAIL PROTECTED] PageCreator}</code> instance
+        */
+       public void setPageCreator(PageCreator creator)
+       {
+               this.pageCreator = creator;
+       }
+
+       /**
+        * Sets the <code>[EMAIL PROTECTED] CloseButtonCallback}</code> 
instance.
+        * 
+        * @param callback
+        *            Callback instance
+        */
+       public void setCloseButtonCallback(CloseButtonCallback callback)
+       {
+               this.closeButtonCallback = callback;
+       }
+
+       /**
+        * Sets the <code>@{link [EMAIL PROTECTED] WindowClosedCallback}</code> 
instance.
+        * 
+        * @param callback
+        *            Callback instance
+        */
+       public void setWindowClosedCallback(WindowClosedCallback callback)
+       {
+               this.windowClosedCallback = callback;
+       }
+
+       /**
+        * Shows the modal window.
+        * 
+        * @param target
+        *            Request target associated with current ajax request.
+        */
+       public void show(AjaxRequestTarget target)
+       {
+               target.addComponent(this);
+               target.appendJavascript(getWindowOpenJavascript());
+               shown = true;
+       }
+
+       /**
+        * Hides the modal window.
+        * 
+        * @param target
+        *            Request target associated with current ajax request.
+        */
+       public static final void close(AjaxRequestTarget target)
+       {
+               target.appendJavascript(getCloseJavacript());
+       }
+
+       /**
+        * @return javascript that closes current modal window
+        */
+       private static String getCloseJavacript()
+       {
+               return "var win;\n" + "try {\n" + "     win = 
window.parent.Wicket.Window;\n"
+                               + "} catch (ignore) {\n" + "}\n"
+                               + "if (typeof(win) != \"undefined\" && 
typeof(win.current) != \"undefined\") {\n"
+                               + "     window.parent.setTimeout(function() 
{\n" + "            win.current.close();\n"
+                               + "     }, 0);\n" + "}";
+       }
+
+       /**
+        * Returns the id of content component.
+        * 
+        * <pre>
+        * ModalWindow window = new ModalWindow(parent, &quot;window&quot;);
+        * new MyPanel(window, window.getContentId());
+        * </pre>
+        * 
+        * @return Id of content component.
+        */
+       public String getContentId()
+       {
+               return "content";
+       }
+
+       /**
+        * Sets the minimal width of window. This value is only used if the 
window
+        * is resizable. The width is specified in pixels and it is the width of
+        * entire window (including frame).
+        * 
+        * @param minimalWidth
+        *            Minimal window width.
+        */
+       public void setMinimalWidth(int minimalWidth)
+       {
+               this.minimalWidth = minimalWidth;
+       }
+
+       /**
+        * Returns the minimal width of window (in pixels).
+        * 
+        * @return Minimal width of window
+        */
+       public int getMinimalWidth()
+       {
+               return minimalWidth;
+       }
+
+       /**
+        * Sets the minimal height of window. This value is only used if window 
is
+        * resizable. The height is specified in pixels and it is the height of
+        * window content (without frame).
+        * 
+        * @param minimalHeight
+        *            Minimal height
+        */
+       public void setMinimalHeight(int minimalHeight)
+       {
+               this.minimalHeight = minimalHeight;
+       }
+
+       /**
+        * Returns the minimal height of window (in pixels).
+        * 
+        * @return Minimal height of window
+        */
+       public int getMinimalHeight()
+       {
+               return minimalHeight;
+       }
+
+       /**
+        * CSS class for window with blue border.
+        */
+       public final static String CSS_CLASS_BLUE = "w_blue";
+
+       /**
+        * CSS class for window with gray border.
+        */
+       public final static String CSS_CLASS_GRAY = "w_silver";
+
+       /**
+        * Sets the CSS class name for this window. This class affects the look 
of
+        * window frame. Possible values (if you don't make your style sheet) 
are
+        * <code>[EMAIL PROTECTED] #CSS_CLASS_BLUE}</code> and
+        * <code>[EMAIL PROTECTED] #CSS_CLASS_GRAY}</code>.
+        * 
+        * @param cssClassName
+        */
+       public void setCssClassName(String cssClassName)
+       {
+               this.cssClassName = cssClassName;
+       }
+
+       /**
+        * Returns the CSS class name for this window.
+        * 
+        * @return CSS class name
+        */
+       public String getCssClassName()
+       {
+               return cssClassName;
+       }
+
+       /**
+        * Sets the initial width of the window. The width refers to the width 
of
+        * entire window (including frame). If the window is resizable, the 
width
+        * unit is always "px". If the window is not resizable, the unit can be
+        * specified using [EMAIL PROTECTED] #setWidthUnit(String)}. If cookie 
name is set and
+        * window is resizable, the initial width may be ignored in favor of 
width
+        * stored in cookie.
+        * 
+        * @param initialWidth
+        *            Initial width of the window
+        */
+       public void setInitialWidth(int initialWidth)
+       {
+               this.initialWidth = initialWidth;
+       }
+
+       /**
+        * Returns the initial width of the window.
+        * 
+        * @return Initial height of the window
+        */
+       public int getInitialWidth()
+       {
+               return initialWidth;
+       }
+
+       /**
+        * Sets the initial height of the window. The height refers to the 
height of
+        * window content (without frame). If the window is resizable, the 
height
+        * unit is always "px". If the window is not resizable, the unit can be
+        * specified using [EMAIL PROTECTED] #setHeightUnit(String)}. If cookie 
name is set
+        * and window is resizable, the initial height may be ignred in favor of
+        * height stored in cookie.
+        * 
+        * @param initialHeight
+        *            Initial height of the window
+        */
+       public void setInitialHeight(int initialHeight)
+       {
+               this.initialHeight = initialHeight;
+       }
+
+       /**
+        * Returns the initial height of the window.
+        * 
+        * @return Initial height of the window
+        */
+       public int getInitialHeight()
+       {
+               return initialHeight;
+       }
+
+       /**
+        * Sets whether to use initial height or preserve the real content 
height.
+        * This can only be used if the content is a component (not a page) and 
the
+        * window is not resizable.
+        * 
+        * @param useInitialHeight
+        *            Whether to use initial height instead of preserving 
content
+        *            height instead of using initial height
+        */
+       public void setUseInitialHeight(boolean useInitialHeight)
+       {
+               this.useInitialHeight = useInitialHeight;
+       }
+
+       /**
+        * Returns true if the initial height should be used (in favour of
+        * preserving real content height).
+        * 
+        * @return True if initial height should be used, false is real content
+        *         height should be preserved (valid only if the window is not
+        *         resizable and the content is a component (not a page)
+        */
+       public boolean isUseInitialHeight()
+       {
+               return useInitialHeight;
+       }
+
+       /**
+        * Sets whether the user will be able to resize the window.
+        * 
+        * @param resizable
+        *            Whether the window is resizable
+        */
+       public void setResizable(boolean resizable)
+       {
+               this.resizable = resizable;
+       }
+
+       /**
+        * Returns whether the window is resizable.
+        * 
+        * @return True if the window is resizable, false otherwise
+        */
+       public boolean isResizable()
+       {
+               return resizable;
+       }
+
+       /**
+        * Sets the CSS unit used for initial window width. This is only 
applicable
+        * when the window is not resizable.
+        * 
+        * @param widthUnit
+        *            CSS unit for initial window width.
+        */
+       public void setWidthUnit(String widthUnit)
+       {
+               this.widthUnit = widthUnit;
+       }
+
+       /**
+        * Returns the CSS unit for initial window width.
+        * 
+        * @return CSS unit for initial window width.
+        */
+       public String getWidthUnit()
+       {
+               return widthUnit;
+       }
+
+       /**
+        * Sets the CSS unit used for initial window height. This is only 
applicable
+        * when the window is not resizable.
+        * 
+        * @param heightUnit
+        *            CSS unit for initial window height.
+        */
+       public void setHeightUnit(String heightUnit)
+       {
+               this.heightUnit = heightUnit;
+       }
+
+       /**
+        * Retrns the CSS unit for initial window height.
+        * 
+        * @return CSS unit for initial window height.
+        */
+       public String getHeightUnit()
+       {
+               return heightUnit;
+       }
+
+       /**
+        * Sets the name of the cookie that is used to remeber window position 
(and
+        * size if the window is resizable).
+        * 
+        * @param cookieName
+        *            Name of the cookie
+        */
+       public void setCookieName(String cookieName)
+       {
+               this.cookieName = cookieName;
+       }
+
+       /**
+        * Returns the name of cookie that is used to remebember window position
+        * (and size if the window is resizable).
+        * 
+        * @return Name of the cookie
+        */
+       public String getCookieName()
+       {
+               return cookieName;
+       }
+
+       /**
+        * Sets the title of window. If the window is a page, title can be
+        * <code>null</code>. In that case it will display the title document
+        * inside the window.
+        * 
+        * @param title
+        *            Title of the window
+        */
+       public void setTitle(String title)
+       {
+               this.title = title;
+       }
+
+       /**
+        * Returns the title of the window.
+        * 
+        * @return Title of the window
+        */
+       public String getTitle()
+       {
+               return title;
+       }
+
+       /**
+        * Mask is the element behind the window, that prevents user from
+        * interacting the rest of page. Mask can be either
+        * <ul>
+        * <li><code>[EMAIL PROTECTED] #TRANSPARENT}</code> - the mask is 
invisible
+        * <li><code>[EMAIL PROTECTED] #SEMI_TRANSPARENT}</code> - the mask is 
black with
+        * small opacity (10%)
+        * </ul>
+        * 
+        * @author Matej Knopp
+        */
+       public enum MaskType {
+               /**
+                * Transparent mask (not visible).
+                */
+               TRANSPARENT,
+
+               /**
+                * Visible mask (black with low opacity).
+                */
+               SEMI_TRANSPARENT
+       };
+
+       /**
+        * Sets the mask type of the window.
+        * 
+        * @param mask
+        *            The mask type
+        */
+       public void setMaskType(MaskType mask)
+       {
+               this.maskType = mask;
+       }
+
+       /**
+        * Returns the mask type of the window
+        * 
+        * @return The mask type
+        */
+       public MaskType getMaskType()
+       {
+               return maskType;
+       }
+
+       /**
+        * Creates the page.
+        * 
+        * @return Page instance or null if page couldn't be created.
+        */
+       private Page createPage()
+       {
+               if (pageCreator == null)
+               {
+                       return null;
+               }
+               else
+               {
+                       RequestParameters parameters = 
RequestCycle.get().getRequest().getRequestParameters();
+                       String oldPageMapName = parameters.getPageMapName();
+
+                       // if there is a pagemap name specified and multiwindow 
support is
+                       // on
+                       if (getPageMapName() != null
+                                       && 
Application.get().getPageSettings().getAutomaticMultiWindowSupport() == true)
+                       {
+                               // try to find out whether the pagemap already 
exists
+                               Session session = Session.get();
+                               if (session.pageMapForName(getPageMapName(), 
false) == null)
+                               {
+                                       deletePageMap = true;
+                               }
+                               parameters.setPageMapName(getPageMapName());
+                       }
+                       try
+                       {
+                               Page page = pageCreator.createPage();
+                               return page;
+                       }
+                       finally
+                       {
+                               parameters.setPageMapName(oldPageMapName);
+                       }
+               }
+       }
+
+       /**
+        * @see wicket.Component#onAttach()
+        */
+       @Override
+       protected void onAttach()
+       {
+               getContent().setOutputMarkupId(true);
+               getContent().setVisible(shown);
+       }
+
+       /**
+        * @see 
wicket.markup.html.panel.Panel#onComponentTag(wicket.markup.ComponentTag)
+        */
+       @Override
+       protected void onComponentTag(ComponentTag tag)
+       {
+               super.onComponentTag(tag);
+               tag.put("style", "display:none");
+       }
+
+
+       /**
+        * Returns a content component. In case user haven't specified any 
content
+        * component, it returns an empty WebMarkupContainer.
+        * 
+        * @return Content component
+        */
+       private Component getContent()
+       {
+               return get(getContentId());
+       }
+
+       /**
+        * Returns true if user has added own component to the window.
+        * 
+        * @return True if user has added own component to the window, false
+        *         otherwise.
+        */
+       private boolean isCustomComponent()
+       {
+               return getContent() != empty;
+       }
+
+       /**
+        * @see wicket.MarkupContainer#remove(wicket.Component)
+        */
+       @Override
+       public void remove(Component component)
+       {
+               super.remove(component);
+               if (component.getId().equals(getContentId()))
+                       empty = new WebMarkupContainer(this, getContentId());
+       }
+
+       /**
+        * @author Matej Knopp
+        */
+       private class WindowClosedBehavior extends AbstractDefaultAjaxBehavior
+       {
+               private static final long serialVersionUID = 1L;
+
+               @Override
+               protected void respond(AjaxRequestTarget target)
+               {
+                       shown = false;
+
+                       // should we cleanup the pagemap?
+                       if (deletePageMap == true)
+                       {
+                               // get the pagemap
+                               Session session = Session.get();
+                               IPageMap pageMap = 
session.pageMapForName(getPageMapName(), false);
+
+                               // if there is any remove it
+                               if (pageMap != null)
+                               {
+                                       session.removePageMap(pageMap);
+                                       deletePageMap = false;
+                               }
+                       }
+
+                       if (windowClosedCallback != null)
+                       {
+                               windowClosedCallback.onClose(target);
+                       }
+               }
+
+               @Override
+               public CharSequence getCallbackScript()
+               {
+                       return super.getCallbackScript();
+               }
+       };
+
+       /**
+        * @author Matej Knopp
+        */
+       private class CloseButtonBehavior extends AbstractDefaultAjaxBehavior
+       {
+               private static final long serialVersionUID = 1L;
+
+               @Override
+               protected void respond(AjaxRequestTarget target)
+               {
+                       if (closeButtonCallback == null
+                                       || 
closeButtonCallback.onCloseButtonClicked(target) == true)
+                       {
+                               
target.appendJavascript("Wicket.Window.get().close();");
+                       }
+               }
+
+               @Override
+               protected IAjaxCallDecorator getAjaxCallDecorator()
+               {
+                       return new 
CancelEventIfNoAjaxDecorator(super.getAjaxCallDecorator());
+               }
+
+               @Override
+               public CharSequence getCallbackScript()
+               {
+                       return super.getCallbackScript();
+               }
+       }
+
+       /**
+        * Returns the markup id of the component.
+        * 
+        * @return component id
+        */
+       private String getContentMarkupId()
+       {
+               return getContent().getMarkupId();
+       }
+
+       /**
+        * Replaces all occurences of " in string with \".
+        * 
+        * @param string
+        *            String to be escaped.
+        * 
+        * @return escaped string
+        */
+       private String escapeQuotes(String string)
+       {
+               if (string.indexOf('"') != -1)
+               {
+                       string = string.replace("\"", "\\\"");
+               }
+               return string;
+       }
+
+       /**
+        * Returns the javascript used to open the window.
+        * 
+        * @return javascript that opens the window
+        */
+       private String getWindowOpenJavascript()
+       {
+               AppendingStringBuffer buffer = new AppendingStringBuffer();
+
+               if (isCustomComponent() == true)
+               {
+                       buffer.append("var element = 
document.getElementById(\"" + getContentMarkupId()
+                                       + "\");\n");
+               }
+
+               buffer.append("var settings = new Object();\n");
+               buffer.append("settings.minWidth=" + getMinimalWidth() + ";\n");
+               buffer.append("settings.minHeight=" + getMinimalHeight() + 
";\n");
+               buffer.append("settings.className=\"" + getCssClassName() + 
"\";\n");
+               buffer.append("settings.width=\"" + getInitialWidth() + 
"\";\n");
+
+               if (isUseInitialHeight() == true || isCustomComponent() == 
false)
+                       buffer.append("settings.height=\"" + getInitialHeight() 
+ "\";\n");
+               else
+                       buffer.append("settings.height=null;\n");
+
+               buffer.append("settings.resizable=" + 
Boolean.toString(isResizable()) + ";\n");
+
+               if (isResizable() == false)
+               {
+                       buffer.append("settings.widthUnit=\"" + getWidthUnit() 
+ "\";\n");
+                       buffer.append("settings.heightUnit=\"" + 
getHeightUnit() + "\";\n");
+               }
+
+               if (isCustomComponent() == false)
+               {
+                       Page page = createPage();
+                       if (page == null)
+                       {
+                               throw new WicketRuntimeException("Error 
creating page for modal dialog.");
+                       }
+                       buffer.append("settings.src=\"" + 
RequestCycle.get().urlFor(page) + "\";\n");
+
+                       if (getPageMapName() != null)
+                       {
+                               buffer.append("settings.iframeName=\"" + 
getPageMapName() + "\";\n");
+                       }
+               }
+               else
+               {
+                       buffer.append("settings.element = element;\n");
+               }
+
+               if (getCookieName() != null)
+               {
+                       buffer.append("settings.cookieId=\"" + getCookieName() 
+ "\";\n");
+               }
+
+               if (getTitle() != null)
+               {
+                       buffer.append("settings.title=\"" + 
escapeQuotes(getTitle()) + "\";\n");
+               }
+
+               if (getMaskType() == MaskType.TRANSPARENT)
+               {
+                       buffer.append("settings.mask=\"transparent\";\n");
+               }
+               else if (getMaskType() == MaskType.SEMI_TRANSPARENT)
+               {
+                       buffer.append("settings.mask=\"semi-transparent\";\n");
+               }
+
+               if (closeButtonCallback != null)
+               {
+                       CloseButtonBehavior behavior = 
(CloseButtonBehavior)getBehaviors(
+                                       CloseButtonBehavior.class).get(0);
+                       buffer.append("settings.onCloseButton = function() { " 
+ behavior.getCallbackScript()
+                                       + "};\n");
+               }
+
+               WindowClosedBehavior behavior = 
(WindowClosedBehavior)getBehaviors(
+                               WindowClosedBehavior.class).get(0);
+               buffer.append("settings.onClose = function() { " + 
behavior.getCallbackScript() + " };\n");
+
+               buffer.append("Wicket.Window.create(settings).show();\n");
+
+               return buffer.toString();
+       }
+
+
+       private boolean deletePageMap = false;
+       private boolean shown = false;
+
+       // empty container - used when no component is added
+       private WebMarkupContainer empty;
+
+       private int minimalWidth = 200;
+       private int minimalHeight = 200;
+       private String cssClassName = CSS_CLASS_BLUE;
+       private int initialWidth = 600;
+       private int initialHeight = 400;
+       private boolean useInitialHeight = true;
+       private boolean resizable = true;
+       private String widthUnit = "px";
+       private String heightUnit = "px";
+       private String cookieName;
+       private String title = null;
+       private MaskType maskType = MaskType.SEMI_TRANSPARENT;
+
+       private String pageMapName = "modal-dialog-pagemap";
+
+       private PageCreator pageCreator = null;
+       private CloseButtonCallback closeButtonCallback = null;
+       private WindowClosedCallback windowClosedCallback = null;
+}


Reply via email to