/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.xwiki.gwt.wysiwyg.client;
import org.xwiki.gwt.dom.client.Element;
import org.xwiki.gwt.user.client.BackForwardCache;
import org.xwiki.gwt.user.client.Config;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.Window.ClosingEvent;
import com.google.gwt.user.client.Window.ClosingHandler;
/**
* WYSIWYG Editor configuration. Use this class to access the WYSIWYG editor configuration in a strong-typed manner and
* to cache configuration values.
*
* @version $Id: 0b2ae0bedae4fd8af1bf8c98b8cf53178f465a47 $
*/
public class WysiwygEditorConfig implements ClosingHandler
{
/**
* The default storage syntax.
*/
public static final String DEFAULT_SYNTAX = "xhtml/1.0";
/**
* WYWISYWG tab index in the TabPanel.
*/
public static final int WYSIWYG_TAB_INDEX = 0;
/**
* Source tab index in the TabPanel.
*/
public static final int SOURCE_TAB_INDEX = 1;
/**
* The key used to cache the active text area, i.e. the text area that should be visible when the editor is loaded.
*/
private static final String CACHE_KEY_ACTIVE_TEXT_AREA = "editor.activeTextArea";
/**
* The key used to cache the type of WYSIWYG editor input value: {@code true} if the input value is HTML, {@code
* false} if the input value is in source syntax (it needs to be converted to HTML).
*/
private static final String CACHE_KEY_INPUT_CONVERTED = "editor.inputConverted";
/**
* The configuration source.
*/
private final Config config;
/**
* The object used to cache configuration options.
*/
private final BackForwardCache cache;
/**
* Creates a new WYSIWYG editor configuration object based on the given configuration source.
*
* @param config the configuration source
*/
public WysiwygEditorConfig(Config config)
{
this.config = config;
cache = new BackForwardCache(Element.as(DOM.getElementById(config.getParameter("cacheId", ""))));
Window.addWindowClosingHandler(this);
}
/**
* @return the syntax used to store the edited content
*/
public String getSyntax()
{
return config.getParameter("syntax", DEFAULT_SYNTAX);
}
/**
* @return {@code true} if the WYSIWYG editor input value is HTML (no conversion is required), {@code false}
* otherwise (the input value is in source syntax and needs to be converted to HTML)
*/
public boolean isInputConverted()
{
boolean inputConverted = !Boolean.valueOf(config.getParameter("convertInput", String.valueOf(false)));
return Boolean.valueOf(cache.get(CACHE_KEY_INPUT_CONVERTED, String.valueOf(inputConverted)));
}
/**
* Sets whether the WYSIWYG editor needs to convert its input from source syntax to HTML.
*
* @param inputConverted {@code true} if the WYSIWYG editor doesn't need to convert its input value because it's
* HTML, {@code false} otherwise (the editor needs to convert the input value from source syntax to HTML)
*/
public void setInputConverted(boolean inputConverted)
{
cache.put(CACHE_KEY_INPUT_CONVERTED, String.valueOf(inputConverted));
}
/**
* @return the element that is replaced by the WYSIWYG editor
*/
public Element getHook()
{
return Element.as(DOM.getElementById(config.getParameter("hookId")));
}
/**
* @return WYSIWYG editor input value
*/
public String getInputValue()
{
return getHook().getPropertyString("value");
}
/**
* @return {@code true} if the editor is enabled, {@code false} otherwise
*/
public boolean isEnabled()
{
Element hook = getHook();
return !hook.getPropertyBoolean("disabled") && !hook.getPropertyBoolean("readOnly");
}
/**
* @return {@code true} if the WYSIWYG/Source tabs are displayed, {@code false} otherwise
*/
public boolean isTabbed()
{
return Boolean.valueOf(config.getParameter("displayTabs", String.valueOf(false)));
}
/**
* @return the index of the tab that should be selected when the WYSIWYG editor is loaded
*/
public int getSelectedTabIndex()
{
String defaultEditor = config.getParameter("defaultEditor");
int defaultTabIndex = "wysiwyg".equals(defaultEditor) ? WYSIWYG_TAB_INDEX : SOURCE_TAB_INDEX;
return Integer.parseInt(cache.get(CACHE_KEY_ACTIVE_TEXT_AREA, String.valueOf(defaultTabIndex)));
}
/**
* Caches the active text area.
*
* @param selectedTabIndex the index of the selected tab
*/
public void setSelectedTabIndex(int selectedTabIndex)
{
cache.put(CACHE_KEY_ACTIVE_TEXT_AREA, String.valueOf(selectedTabIndex));
}
/**
* @return rich text area's template URL
*/
public String getTemplateURL()
{
return config.getParameter("inputURL");
}
/**
* @return {@code true} if the WYSIWYG editor is in debug mode, {@code false} otherwise
*/
public boolean isDebugMode()
{
return Boolean.valueOf(config.getParameter("debug", String.valueOf(false)));
}
/**
* @return the configuration source
*/
public Config getConfigurationSource()
{
return config;
}
@Override
public void onWindowClosing(ClosingEvent event)
{
// Make sure the cache is up to date before the page unloads. We have to do this because the queue of deferred
// commands is discarded when the page unloads and the cache update command might not get executed.
// NOTE: This is more of a hack since we shouldn't be aware of the internal cache implementation but there's no
// easy way to schedule the cache update after all the window closing handlers and before the first window
// closed handler.
cache.update();
}
}