All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.alkacon.acacia.client.widgets.TinyMCEWidget Maven / Gradle / Ivy

Go to download

A GWT based resource editor. This component is used as a part of OpenCms, an enterprise-ready, easy to use website content management system based on Java and XML technology. Offering a complete set of features, OpenCms helps content managers worldwide to create and maintain beautiful websites fast and efficiently.

There is a newer version: 2.1
Show newest version
/*
 * This library is part of the Acacia Editor -
 * an open source inline and form based content editor for GWT.
 *
 * Copyright (c) Alkacon Software GmbH (http://www.alkacon.com)
 *
 * This library 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 library 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.
 *
 * For further information about Alkacon Software, please see the
 * company website: http://www.alkacon.com
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package com.alkacon.acacia.client.widgets;

import com.alkacon.acacia.client.css.I_LayoutBundle;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.RepeatingCommand;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.DomEvent;
import com.google.gwt.event.logical.shared.HasResizeHandlers;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;

/**
 * This class is used to start TinyMCE for editing the content of an element.

* * After constructing the instance, the actual editor is opened using the init() method, and destroyed with the close() * method. While the editor is opened, the edited contents can be accessed using the methods of the HasValue interface. */ public final class TinyMCEWidget extends A_EditWidget implements HasResizeHandlers { /** The minimum editor height. */ private static final int MIN_EDITOR_HEIGHT = 70; /** A flag which indicates whether the editor is currently active. */ protected boolean m_active; /** The current content. */ protected String m_currentContent; /** The TinyMCE editor instance. */ protected JavaScriptObject m_editor; /** The DOM ID of the editable element. */ protected String m_id; /** The original HTML content of the editable element. */ protected String m_originalContent; /** The maximal width of the widget. */ protected int m_width; /** The editor height to set. */ int m_editorHeight; /** Indicating if the widget has been attached yet. */ private boolean m_hasBeenAttached; /** Flag indicating the editor has been initialized. */ private boolean m_initialized; /** The editor options. */ private JavaScriptObject m_options; /** * Creates a new instance for the given element.

* * @param element the DOM element * @param options the tinyMCE editor options to extend the default settings */ public TinyMCEWidget(Element element, JavaScriptObject options) { super(element); m_originalContent = ""; m_options = options; m_active = true; } /** * Constructor.

* * @param options the tinyMCE editor options to extend the default settings */ public TinyMCEWidget(JavaScriptObject options) { this(DOM.createDiv(), options); } /** * @see com.google.gwt.event.logical.shared.HasResizeHandlers#addResizeHandler(com.google.gwt.event.logical.shared.ResizeHandler) */ public HandlerRegistration addResizeHandler(ResizeHandler handler) { return addHandler(handler, ResizeEvent.getType()); } /** * @see com.alkacon.acacia.client.widgets.A_EditWidget#addValueChangeHandler(com.google.gwt.event.logical.shared.ValueChangeHandler) */ @Override public HandlerRegistration addValueChangeHandler(ValueChangeHandler handler) { return addHandler(handler, ValueChangeEvent.getType()); } /** * Gets the main editable element.

* * @return the editable element */ public native Element getMainElement() /*-{ var elementId = [email protected]::m_id; var mainElement = $wnd.document.getElementById(elementId); return mainElement; }-*/; /** * @see com.google.gwt.user.client.ui.HasValue#getValue() */ @Override public String getValue() { if (m_editor != null) { return getContent().trim(); } return m_originalContent.trim(); } /** * @see com.alkacon.acacia.client.widgets.I_EditWidget#isActive() */ public boolean isActive() { return m_active; } /** * @see com.alkacon.acacia.client.widgets.I_EditWidget#setActive(boolean) */ public void setActive(boolean active) { if (m_active == active) { return; } m_active = active; if (m_editor != null) { if (m_active) { getEditorParentElement().removeClassName(I_LayoutBundle.INSTANCE.form().inActive()); // getElement().focus(); fireValueChange(true); } else { getEditorParentElement().addClassName(I_LayoutBundle.INSTANCE.form().inActive()); } } } /** * @see com.alkacon.acacia.client.widgets.I_EditWidget#setName(java.lang.String) */ public void setName(String name) { // no input field so nothing to do } /** * @see com.google.gwt.user.client.ui.HasValue#setValue(java.lang.Object) */ public void setValue(String value) { setValue(value, false); } /** * @see com.google.gwt.user.client.ui.HasValue#setValue(java.lang.Object, boolean) */ public void setValue(String value, boolean fireEvents) { if (value != null) { value = value.trim(); } setPreviousValue(value); if (m_editor == null) { // editor has not been initialized yet m_originalContent = value; } else { setContent(value); } if (fireEvents) { fireValueChange(true); } } /** * Checks whether the necessary Javascript libraries are available by accessing them. */ protected native void checkLibraries() /*-{ // fail early if tinymce is not available var w = $wnd; var init = w.tinyMCE.init; }-*/; /** * Gives an element an id if it doesn't already have an id, and then returns the element's id.

* * @param element the element for which we want to add the id * * @return the id */ protected String ensureId(Element element) { String id = element.getId(); if ((id == null) || "".equals(id)) { id = Document.get().createUniqueId(); element.setId(id); } return id; } /** * Fixes the styling of the editor widget.

*/ protected void fixStyles() { // it may take some time until the editor has been initialized, repeat until layout fix can be applied Scheduler.get().scheduleFixedDelay(new RepeatingCommand() { /** * @see com.google.gwt.core.client.Scheduler.RepeatingCommand#execute() */ public boolean execute() { Element parent = getEditorParentElement(); if (parent != null) { String cssClass = getMainElement().getClassName(); if ((cssClass != null) && (cssClass.trim().length() > 0)) { parent.addClassName(cssClass); } parent.getStyle().setDisplay(Display.BLOCK); getEditorTableElement().getStyle().setWidth(100, Unit.PCT); return false; } return true; } }, 100); } /** * Returns the editor parent element.

* * @return the editor parent element */ protected native Element getEditorParentElement() /*-{ var elementId = [email protected]::m_id; var parentId = elementId + "_parent"; return $doc.getElementById(parentId); }-*/; /** * Returns the editor table element.

* * @return the editor table element */ protected native Element getEditorTableElement() /*-{ var elementId = [email protected]::m_id; var tableId = elementId + "_tbl"; return $doc.getElementById(tableId); }-*/; /** * Returns the editor parent element.

* * @return the editor parent element */ protected native int getFrameContentHeight() /*-{ var elementId = [email protected]::m_id; var parentId = elementId + "_parent"; return $doc.getElementById(parentId); }-*/; /** * Gets the toolbar element.

* * @return the toolbar element */ protected native Element getToolbarElement() /*-{ var elementId = [email protected]::m_id; var toolbarId = elementId + "_external"; return $doc.getElementById(toolbarId); }-*/; /** * @see com.google.gwt.user.client.ui.FocusWidget#onAttach() */ @Override protected void onAttach() { super.onAttach(); if (!m_hasBeenAttached) { m_hasBeenAttached = true; Scheduler.get().scheduleDeferred(new ScheduledCommand() { public void execute() { if (isAttached()) { m_editorHeight = calculateEditorHeight(); m_id = ensureId(getElement()); m_width = getElement().getOffsetWidth() - 2; checkLibraries(); initNative(); if (!m_active) { Element parent = getEditorParentElement(); if (parent != null) { parent.addClassName(I_LayoutBundle.INSTANCE.form().inActive()); } } } else { resetAtachedFlag(); } } }); } } /** * Propagates the a focus event.

*/ protected void propagateFocusEvent() { NativeEvent nativeEvent = Document.get().createFocusEvent(); DomEvent.fireNativeEvent(nativeEvent, this, this.getElement()); } /** * Propagates a native mouse event.

* * @param eventType the mouse event type * @param eventSource the event source */ protected native void propagateMouseEvent(String eventType, Element eventSource) /*-{ var doc = $wnd.document; var event; if (doc.createEvent) { event = doc.createEvent("MouseEvents"); event.initEvent(eventType, true, true); eventSource.dispatchEvent(event); } else { eventSource.fireEvent("on" + eventType); } }-*/; /** * Removes the editor instance.

*/ protected native void removeEditor() /*-{ var editor = [email protected]::m_editor; editor.remove(); }-*/; /** * Sets the main content of the element which is inline editable.

* * @param html the new content html */ protected native void setMainElementContent(String html) /*-{ var instance = this; var elementId = [email protected]::m_id; var mainElement = $wnd.document.getElementById(elementId); mainElement.innerHTML = html; }-*/; /** * Calculates the needed editor height.

* * @return the calculated editor height */ int calculateEditorHeight() { int result = getElement().getOffsetHeight() + 30; return result > MIN_EDITOR_HEIGHT ? result : MIN_EDITOR_HEIGHT; } /** * Initializes the TinyMCE instance. */ native void initNative() /*-{ var self = this; var elementId = [email protected]::m_id; var iframeId = elementId + "_ifr"; var mainElement = $wnd.document.getElementById(elementId); var editorHeight = [email protected]::m_editorHeight + "px"; [email protected]::m_currentContent = [email protected]::m_originalContent; var fireChange = function() { [email protected]::fireChangeFromNative()(); }; // default options: var defaults = { onchange_callback : fireChange, theme_advanced_resize_horizontal : true, theme_advanced_resizing_max_width : [email protected]::m_width, relative_urls : false, remove_script_host : false, entity_encoding : "raw", skin_variant : 'ocms', mode : "exact", theme : "advanced", plugins : "autolink,lists,pagebreak,style,layer,table,save,advhr,advimage,advlink,emotions,iespell,inlinepopups,insertdatetime,preview,media,searchreplace,print,contextmenu,paste,directionality,noneditable,visualchars,nonbreaking,xhtmlxtras,template,wordcount,advlist", theme_advanced_toolbar_location : "external", theme_advanced_toolbar_align : "right", theme_advanced_statusbar_location : "bottom", width : '100%', theme_advanced_resizing : true, theme_advanced_resizing_use_cookie : false }; var options = [email protected]::m_options; if (options != null && options.editorHeight) { editorHeight = options.editorHeight + "px"; delete options.editorHeight; } // extend the defaults with any given options if (options != null) { var vie = @com.alkacon.vie.client.Vie::getInstance()(); vie.jQuery.extend(defaults, options); } // add the setup function defaults.setup = function(ed) { [email protected]::m_editor = ed; ed.onSetContent.add(fireChange); ed.onKeyDown.add(fireChange); ed.onLoadContent .add(function() { $wnd.document.getElementById(iframeId).style.minHeight = editorHeight; // firing resize event on resize of the editor iframe ed.dom .bind( ed.getWin(), 'resize', function() { [email protected]::fireResizeEvent()(); }); var content = [email protected]::m_originalContent; if (content != null) { ed.setContent(content); } [email protected]::m_initialized = true; }); ed.onClick .add(function(event) { if ([email protected]::isActive()()) { // this may be the case if the mouse-down event has not been triggered correctly yet (IE), // trigger activation through new mouse-down [email protected]::propagateMouseEvent(Ljava/lang/String;Lcom/google/gwt/user/client/Element;)('mousedown', mainElement); } [email protected]::propagateMouseEvent(Ljava/lang/String;Lcom/google/gwt/user/client/Element;)('click', mainElement); }); }; // add event handlers defaults.init_instance_callback = function(ed) { $wnd.tinyMCE.dom.Event .add( ed.getWin(), 'focus', function(event) { [email protected]::propagateFocusEvent()(); }); $wnd.tinyMCE.dom.Event .add( ed.getWin(), 'mousedown', function(event) { [email protected]::propagateMouseEvent(Ljava/lang/String;Lcom/google/gwt/user/client/Element;)('mousedown', mainElement); }); $wnd.tinyMCE.dom.Event .add( ed.getWin(), 'mouseup', function(event) { [email protected]::propagateMouseEvent(Ljava/lang/String;Lcom/google/gwt/user/client/Element;)('mouseup', mainElement); }); // $wnd.tinyMCE.dom.Event // .add( // ed.getWin(), // 'mousemove', // function(event) { // [email protected]::propagateMouseEvent(Ljava/lang/String;Lcom/google/gwt/user/client/Element;)('mousemove', mainElement); // }); }; // set the edited element id defaults.elements = [email protected]::m_id; // initialize tinyMCE $wnd.tinyMCE.init(defaults); [email protected]::fixStyles()(); }-*/; /** * Resets the attached flag.

*/ void resetAtachedFlag() { m_hasBeenAttached = false; } /** * Used to fire the value changed event from native code.

*/ private void fireChangeFromNative() { if (m_initialized) { Scheduler.get().scheduleDeferred(new ScheduledCommand() { public void execute() { try { fireValueChange(false); } catch (Throwable t) { // this may happen when returning from full screen mode, nothing to be done } } }); } } /** * Fires the resize event.

*/ private void fireResizeEvent() { ResizeEvent.fire(this, getOffsetWidth(), getOffsetHeight()); } /** * Returns the editor content.

* * @return the editor content */ private native String getContent() /*-{ var editor = [email protected]::m_editor; return editor.getContent(); }-*/; /** * Sets the content of the TinyMCE editor.

* * @param newContent the new content */ private native void setContent(String newContent) /*-{ var editor = [email protected]::m_editor; editor.setContent(newContent); }-*/; }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy