[kune-commits] r1040 - in trunk/src/main: java/org/ourproject/kune/platf java/org/ourproject/kune/platf/client/ui java/org/ourproject/kune/platf/client/ui/rte java/org/ourproject/kune/platf/client/ui/rte/impl java/org/ourproject/kune/workspace java/org/ourproject/kune/workspace/client/editor java/org/ourproject/kune/workspace/client/editor/insert java/org/ourproject/kune/workspace/client/editor/insert/abstractlink rails/publicspace/public/templates/basic

vjrj vjrj at ourproject.org
Tue Jan 27 02:24:26 CET 2009


Author: vjrj
Date: 2009-01-27 02:24:24 +0100 (Tue, 27 Jan 2009)
New Revision: 1040

Added:
   trunk/src/main/java/org/ourproject/kune/platf/RichText.gwt.xml
   trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/
   trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/RichTextArea.java
   trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/impl/
   trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/impl/RichTextAreaImpl.java
   trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/impl/RichTextAreaImplIE6.java
   trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/impl/RichTextAreaImplMozilla.java
   trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/impl/RichTextAreaImplOpera.java
   trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/impl/RichTextAreaImplSafari.java
   trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/impl/RichTextAreaImplStandard.java
Modified:
   trunk/src/main/java/org/ourproject/kune/platf/Kune-Platform.gwt.xml
   trunk/src/main/java/org/ourproject/kune/workspace/Kune-Workspace.gwt.xml
   trunk/src/main/java/org/ourproject/kune/workspace/client/editor/TextEditorPanel.java
   trunk/src/main/java/org/ourproject/kune/workspace/client/editor/TextEditorToolbar.java
   trunk/src/main/java/org/ourproject/kune/workspace/client/editor/WrappedRichTextAreaImplIE6.java
   trunk/src/main/java/org/ourproject/kune/workspace/client/editor/WrappedRichTextAreaImplMozilla.java
   trunk/src/main/java/org/ourproject/kune/workspace/client/editor/WrappedRichTextAreaImplOpera.java
   trunk/src/main/java/org/ourproject/kune/workspace/client/editor/WrappedRichTextAreaImplSafari.java
   trunk/src/main/java/org/ourproject/kune/workspace/client/editor/insert/TextEditorInsertElement.java
   trunk/src/main/java/org/ourproject/kune/workspace/client/editor/insert/TextEditorInsertElementPresenter.java
   trunk/src/main/java/org/ourproject/kune/workspace/client/editor/insert/abstractlink/TextEditorInsertAbstractPresenter.java
   trunk/src/main/rails/publicspace/public/templates/basic/docs.liquid.html
Log:
RichTextArea copy and extension to add insertHtml

Modified: trunk/src/main/java/org/ourproject/kune/platf/Kune-Platform.gwt.xml
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/Kune-Platform.gwt.xml	2009-01-26 23:25:53 UTC (rev 1039)
+++ trunk/src/main/java/org/ourproject/kune/platf/Kune-Platform.gwt.xml	2009-01-27 01:24:24 UTC (rev 1040)
@@ -4,7 +4,7 @@
   <inherits name='com.google.gwt.user.User' />
   <inherits name='com.google.gwt.i18n.I18N' />
   <inherits name="com.google.gwt.user.UserAgent" />
-
+  <inherits name="org.ourproject.kune.platf.RichText" />
   <public path="public" />
 
 </module>

Added: trunk/src/main/java/org/ourproject/kune/platf/RichText.gwt.xml
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/RichText.gwt.xml	2009-01-26 23:25:53 UTC (rev 1039)
+++ trunk/src/main/java/org/ourproject/kune/platf/RichText.gwt.xml	2009-01-27 01:24:24 UTC (rev 1040)
@@ -0,0 +1,59 @@
+<!--                                                                        -->
+<!-- Copyright 2008 Google Inc.                                             -->
+<!-- Licensed under the Apache License, Version 2.0 (the "License"); you    -->
+<!-- may not use this file except in compliance with the License. You may   -->
+<!-- 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. License for the specific language governing permissions and   -->
+<!-- limitations under the License.                                         -->
+
+<!-- Deferred binding rules for browser selection.                          -->
+<!--                                                                        -->
+<module>
+	<inherits name="com.google.gwt.core.Core" />
+	<inherits name="com.google.gwt.user.UserAgent" />
+
+	<!-- IE-specific implementation -->
+	<replace-with
+		class="org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImplIE6">
+		<when-type-is
+			class="org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl" />
+		<when-property-is name="user.agent" value="ie6" />
+	</replace-with>
+
+	<!-- Mozilla-specific implementation -->
+	<replace-with
+		class="org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImplMozilla">
+		<when-type-is
+			class="org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl" />
+		<any>
+			<when-property-is name="user.agent" value="gecko1_8" />
+			<when-property-is name="user.agent" value="gecko" />
+		</any>
+	</replace-with>
+
+	<!-- Safari-specific implementation -->
+	<replace-with
+		class="org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImplSafari">
+		<when-type-is
+			class="org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl" />
+		<any>
+			<when-property-is name="user.agent" value="safari" />
+		</any>
+	</replace-with>
+
+	<!-- Opera-specific implementation -->
+	<replace-with
+		class="org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImplOpera">
+		<when-type-is
+			class="org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl" />
+		<any>
+			<when-property-is name="user.agent" value="opera" />
+		</any>
+	</replace-with>
+</module>

Added: trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/RichTextArea.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/RichTextArea.java	2009-01-26 23:25:53 UTC (rev 1039)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/RichTextArea.java	2009-01-27 01:24:24 UTC (rev 1040)
@@ -0,0 +1,451 @@
+/*
+ * Copyright 2007 Google Inc.
+ *
+ * Licensed 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.
+ */
+package org.ourproject.kune.platf.client.ui.rte;
+
+import org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.ui.FocusWidget;
+import com.google.gwt.user.client.ui.HasHTML;
+import com.google.gwt.user.client.ui.MouseListener;
+import com.google.gwt.user.client.ui.MouseListenerCollection;
+import com.google.gwt.user.client.ui.SourcesMouseEvents;
+
+/**
+ * A rich text editor that allows complex styling and formatting.
+ * 
+ * Because some browsers do not support rich text editing, and others support
+ * only a limited subset of functionality, there are two formatter interfaces,
+ * accessed via {@link #getBasicFormatter()} and {@link #getExtendedFormatter()}
+ * . A browser that does not support rich text editing at all will return
+ * <code>null</code> for both of these, while one that supports only the basic
+ * functionality will return <code>null</code> for the latter.
+ * 
+ * <p>
+ * <img class='gallery' src='RichTextArea.png'/>
+ * </p>
+ * 
+ * <h3>CSS Style Rules</h3> <ul class="css"> <li>.gwt-RichTextArea { }</li>
+ * </ul>
+ */
+public class RichTextArea extends FocusWidget implements HasHTML, SourcesMouseEvents {
+
+    /**
+     * This interface is used to access basic formatting options, when
+     * available. If the implementation supports basic formatting, then
+     * {@link RichTextArea#getBasicFormatter()} will return an instance of this
+     * class.
+     */
+    public interface BasicFormatter {
+
+        /**
+         * Gets the background color.
+         * 
+         * @return the background color
+         */
+        String getBackColor();
+
+        /**
+         * Gets the foreground color.
+         * 
+         * @return the foreground color
+         */
+        String getForeColor();
+
+        /**
+         * Is the current region bold?
+         * 
+         * @return true if the current region is bold
+         */
+        boolean isBold();
+
+        /**
+         * Is the current region italic?
+         * 
+         * @return true if the current region is italic
+         */
+        boolean isItalic();
+
+        /**
+         * Is the current region subscript?
+         * 
+         * @return true if the current region is subscript
+         */
+        boolean isSubscript();
+
+        /**
+         * Is the current region superscript?
+         * 
+         * @return true if the current region is superscript
+         */
+        boolean isSuperscript();
+
+        /**
+         * Is the current region underlined?
+         * 
+         * @return true if the current region is underlined
+         */
+        boolean isUnderlined();
+
+        /**
+         * Selects all the text.
+         */
+        void selectAll();
+
+        /**
+         * Sets the background color.
+         * 
+         * @param color
+         *            the new background color
+         */
+        void setBackColor(String color);
+
+        /**
+         * Sets the font name.
+         * 
+         * @param name
+         *            the new font name
+         */
+        void setFontName(String name);
+
+        /**
+         * Sets the font size.
+         * 
+         * @param fontSize
+         *            the new font size
+         */
+        void setFontSize(FontSize fontSize);
+
+        /**
+         * Sets the foreground color.
+         * 
+         * @param color
+         *            the new foreground color
+         */
+        void setForeColor(String color);
+
+        /**
+         * Sets the justification.
+         * 
+         * @param justification
+         *            the new justification
+         */
+        void setJustification(Justification justification);
+
+        /**
+         * Toggles bold.
+         */
+        void toggleBold();
+
+        /**
+         * Toggles italic.
+         */
+        void toggleItalic();
+
+        /**
+         * Toggles subscript.
+         */
+        void toggleSubscript();
+
+        /**
+         * Toggles superscript.
+         */
+        void toggleSuperscript();
+
+        /**
+         * Toggles underline.
+         */
+        void toggleUnderline();
+    }
+
+    /**
+     * This interface is used to access full formatting options, when available.
+     * If the implementation supports full formatting, then
+     * {@link RichTextArea#getExtendedFormatter()} will return an instance of
+     * this class.
+     */
+    public interface ExtendedFormatter extends BasicFormatter {
+
+        /**
+         * Creates a link to the supplied URL.
+         * 
+         * @param url
+         *            the URL to be linked to
+         */
+        void createLink(String url);
+
+        /**
+         * Inserts a horizontal rule.
+         */
+        void insertHorizontalRule();
+
+        /**
+         * Inserts html
+         */
+        void insertHtml(String html);
+
+        /**
+         * Inserts an image element.
+         * 
+         * @param url
+         *            the url of the image to be inserted
+         */
+        void insertImage(String url);
+
+        /**
+         * Starts an numbered list. Indentation will create nested items.
+         */
+        void insertOrderedList();
+
+        /**
+         * Starts an bulleted list. Indentation will create nested items.
+         */
+        void insertUnorderedList();
+
+        /**
+         * Is the current region strikethrough?
+         * 
+         * @return true if the current region is strikethrough
+         */
+        boolean isStrikethrough();
+
+        /**
+         * Left indent.
+         */
+        void leftIndent();
+
+        /**
+         * Removes all formatting on the selected text.
+         */
+        void removeFormat();
+
+        /**
+         * Removes any link from the selected text.
+         */
+        void removeLink();
+
+        /**
+         * Right indent.
+         */
+        void rightIndent();
+
+        /**
+         * Toggles strikethrough.
+         */
+        void toggleStrikethrough();
+    }
+
+    /**
+     * Font size enumeration. Represents the seven basic HTML font sizes, as
+     * defined in CSS.
+     */
+    public static class FontSize {
+
+        /**
+         * Represents an XX-Small font.
+         */
+        public static final FontSize XX_SMALL = new FontSize(1);
+
+        /**
+         * Represents an X-Small font.
+         */
+        public static final FontSize X_SMALL = new FontSize(2);
+
+        /**
+         * Represents a Small font.
+         */
+        public static final FontSize SMALL = new FontSize(3);
+
+        /**
+         * Represents a Medium font.
+         */
+        public static final FontSize MEDIUM = new FontSize(4);
+
+        /**
+         * Represents a Large font.
+         */
+        public static final FontSize LARGE = new FontSize(5);
+
+        /**
+         * Represents an X-Large font.
+         */
+        public static final FontSize X_LARGE = new FontSize(6);
+
+        /**
+         * Represents an XX-Large font.
+         */
+        public static final FontSize XX_LARGE = new FontSize(7);
+
+        private final int number;
+
+        private FontSize(int number) {
+            this.number = number;
+        }
+
+        /**
+         * Gets the HTML font number associated with this font size.
+         * 
+         * @return an integer from 1 to 7 inclusive
+         */
+        public int getNumber() {
+            return number;
+        }
+
+        @Override
+        public String toString() {
+            return Integer.toString(number);
+        }
+    }
+
+    /**
+     * Justification enumeration. The three values are <code>left</code>,
+     * <code>right</code>, <code>center</code>.
+     */
+    public static class Justification {
+
+        /**
+         * Center justification.
+         */
+        public static final Justification CENTER = new Justification("Center");
+
+        /**
+         * Left justification.
+         */
+        public static final Justification LEFT = new Justification("Left");
+
+        /**
+         * Right justification.
+         */
+        public static final Justification RIGHT = new Justification("Right");
+
+        private final String tag;
+
+        private Justification(String tag) {
+            this.tag = tag;
+        }
+
+        @Override
+        public String toString() {
+            return "Justify " + tag;
+        }
+    }
+
+    private final RichTextAreaImpl impl = GWT.create(RichTextAreaImpl.class);
+    private MouseListenerCollection mouseListeners;
+
+    /**
+     * Creates a new, blank {@link RichTextArea} object with no stylesheet.
+     */
+    public RichTextArea() {
+        setElement(impl.getElement());
+        setStyleName("gwt-RichTextArea");
+    }
+
+    public void addMouseListener(MouseListener listener) {
+        if (mouseListeners == null) {
+            mouseListeners = new MouseListenerCollection();
+        }
+        mouseListeners.add(listener);
+    }
+
+    /**
+     * Gets the basic rich text formatting interface.
+     * 
+     * @return <code>null</code> if basic formatting is not supported
+     */
+    public BasicFormatter getBasicFormatter() {
+        if ((impl instanceof BasicFormatter) && (impl.isBasicEditingSupported())) {
+            return (BasicFormatter) impl;
+        }
+        return null;
+    }
+
+    /**
+     * Gets the full rich text formatting interface.
+     * 
+     * @return <code>null</code> if full formatting is not supported
+     */
+    public ExtendedFormatter getExtendedFormatter() {
+        if ((impl instanceof ExtendedFormatter) && (impl.isExtendedEditingSupported())) {
+            return (ExtendedFormatter) impl;
+        }
+        return null;
+    }
+
+    public String getHTML() {
+        return impl.getHTML();
+    }
+
+    public String getText() {
+        return impl.getText();
+    }
+
+    @Override
+    public void onBrowserEvent(Event event) {
+        switch (DOM.eventGetType(event)) {
+        case Event.ONMOUSEDOWN:
+        case Event.ONMOUSEUP:
+        case Event.ONMOUSEMOVE:
+        case Event.ONMOUSEOVER:
+        case Event.ONMOUSEOUT:
+            if (mouseListeners != null) {
+                mouseListeners.fireMouseEvent(this, event);
+            }
+            break;
+
+        default:
+            // ClickEvents, KeyboardEvents, and FocusEvents
+            super.onBrowserEvent(event);
+        }
+    }
+
+    public void removeMouseListener(MouseListener listener) {
+        if (mouseListeners != null) {
+            mouseListeners.remove(listener);
+        }
+    }
+
+    @Override
+    public void setFocus(boolean focused) {
+        // There are different problems on each browser when you try to focus an
+        // unattached rich text iframe, so just cut it off early.
+        if (isAttached()) {
+            impl.setFocus(focused);
+        }
+    }
+
+    public void setHTML(String html) {
+        impl.setHTML(html);
+    }
+
+    public void setText(String text) {
+        impl.setText(text);
+    }
+
+    @Override
+    protected void onAttach() {
+        super.onAttach();
+        impl.initElement();
+    }
+
+    @Override
+    protected void onDetach() {
+        super.onDetach();
+        impl.uninitElement();
+    }
+}

Added: trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/impl/RichTextAreaImpl.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/impl/RichTextAreaImpl.java	2009-01-26 23:25:53 UTC (rev 1039)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/impl/RichTextAreaImpl.java	2009-01-27 01:24:24 UTC (rev 1040)
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2007 Google Inc.
+ *
+ * Licensed 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.
+ */
+package org.ourproject.kune.platf.client.ui.rte.impl;
+
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+import com.google.gwt.user.client.Event;
+
+/**
+ * Base class for RichText platform implementations. The default version simply
+ * creates a text area with no rich text support.
+ * 
+ * This is not currently used by any user-agent, but will provide a
+ * &lt;textarea&gt; fallback in the event a future browser fails to implement
+ * rich text editing.
+ */
+public class RichTextAreaImpl {
+
+    protected Element elem;
+
+    public RichTextAreaImpl() {
+        elem = createElement();
+    }
+
+    public Element getElement() {
+        return elem;
+    }
+
+    public String getHTML() {
+        return DOM.getElementProperty(elem, "value");
+    }
+
+    public String getText() {
+        return DOM.getElementProperty(elem, "value");
+    }
+
+    public void initElement() {
+        onElementInitialized();
+    }
+
+    public boolean isBasicEditingSupported() {
+        return false;
+    }
+
+    public boolean isExtendedEditingSupported() {
+        return false;
+    }
+
+    public native void setFocus(boolean focused) /*-{
+       if (focused) {
+         this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem.focus();
+       } else {
+         this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem.blur();
+       }
+     }-*/;
+
+    public void setHTML(String html) {
+        DOM.setElementProperty(elem, "value", html);
+    }
+
+    public void setText(String text) {
+        DOM.setElementProperty(elem, "value", text);
+    }
+
+    public void uninitElement() {
+    }
+
+    protected Element createElement() {
+        return DOM.createTextArea();
+    }
+
+    protected void hookEvents() {
+        DOM.sinkEvents(elem, Event.MOUSEEVENTS | Event.KEYEVENTS | Event.ONCHANGE | Event.ONCLICK | Event.FOCUSEVENTS);
+    }
+
+    protected void onElementInitialized() {
+        hookEvents();
+    }
+}

Added: trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/impl/RichTextAreaImplIE6.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/impl/RichTextAreaImplIE6.java	2009-01-26 23:25:53 UTC (rev 1039)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/impl/RichTextAreaImplIE6.java	2009-01-27 01:24:24 UTC (rev 1040)
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2008 Google Inc.
+ *
+ * Licensed 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.
+ */
+package org.ourproject.kune.platf.client.ui.rte.impl;
+
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+
+/**
+ * IE6-specific implementation of rich-text editing.
+ */
+public class RichTextAreaImplIE6 extends RichTextAreaImplStandard {
+
+    @Override
+    public Element createElement() {
+        Element elem = super.createElement();
+        DOM.setElementProperty(elem, "src", "javascript:''");
+        return elem;
+    }
+
+    @Override
+    public native void initElement() /*-{
+       var _this = this;
+       _this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImplStandard::initializing = true;
+
+       setTimeout(function() {
+         if (_this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImplStandard::initializing == false) {
+           return;
+         }
+
+         // Attempt to set the iframe document's body to 'contentEditable' mode.
+         // There's no way to know when the body will actually be available, so
+         // keep trying every so often until it is.
+         // Note: The body seems to be missing only rarely, so please don't remove
+         // this retry loop just because it's hard to reproduce.
+         var elem = _this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem;
+         var doc = elem.contentWindow.document;
+         if (!doc.body) {
+             // Retry in 50 ms. Faster would run the risk of pegging the CPU. Slower
+             // would increase the probability of a user-visible delay.
+           setTimeout(arguments.callee, 50);
+           return;
+         }
+         doc.body.contentEditable = true;
+
+         // Send notification that the iframe has reached design mode.
+         _this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImplStandard::onElementInitialized()();
+       }, 1);
+     }-*/;
+
+    @Override
+    protected native String getTextImpl() /*-{
+       var elem = this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem;
+       return elem.contentWindow.document.body.innerText;
+     }-*/;
+
+    @Override
+    protected native void hookEvents() /*-{
+       var elem = this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem;
+       var body = elem.contentWindow.document.body;
+
+       var handler = function() {
+         if (elem.__listener) {
+           // Weird: this code has the context of the script frame, but we need the
+           // event from the edit iframe's window.
+           var evt = elem.contentWindow.event;
+           elem.__listener. at org.ourproject.kune.platf.client.ui.rte.RichTextArea::onBrowserEvent(Lcom/google/gwt/user/client/Event;)(evt);
+         }
+       };
+
+       body.onkeydown =
+       body.onkeyup =
+       body.onkeypress =
+       body.onmousedown =
+       body.onmouseup =
+       body.onmousemove =
+       body.onmouseover =
+       body.onmouseout =
+       body.onclick = handler;
+
+       elem.contentWindow.onfocus =
+       elem.contentWindow.onblur = handler;
+     }-*/;
+
+    @Override
+    protected native void setTextImpl(String text) /*-{
+       var elem = this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem;
+       elem.contentWindow.document.body.innerText = text;
+     }-*/;
+
+    @Override
+    protected native void unhookEvents() /*-{
+       var elem = this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem;
+       var body = elem.contentWindow.document.body;
+
+       if (body) {
+         // The body can be undefined in the relatively obscure case that the RTA
+         // is attached and detached before it has a chance to finish initializing.
+         body.onkeydown =
+         body.onkeyup =
+         body.onkeypress =
+         body.onmousedown =
+         body.onmouseup =
+         body.onmousemove =
+         body.onmouseover =
+         body.onmouseout =
+         body.onclick = null;
+
+         elem.contentWindow.onfocus =
+         elem.contentWindow.onblur = null;
+       }
+     }-*/;
+
+    @Override
+    boolean isRichEditingActive(Element elem) {
+        return true;
+    }
+}

Added: trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/impl/RichTextAreaImplMozilla.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/impl/RichTextAreaImplMozilla.java	2009-01-26 23:25:53 UTC (rev 1039)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/impl/RichTextAreaImplMozilla.java	2009-01-27 01:24:24 UTC (rev 1040)
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2008 Google Inc.
+ * 
+ * Licensed 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.
+ */
+package org.ourproject.kune.platf.client.ui.rte.impl;
+
+/**
+ * Mozilla-specific implementation of rich-text editing.
+ */
+public class RichTextAreaImplMozilla extends RichTextAreaImplStandard {
+
+    @Override
+    public native void initElement() /*-{
+       // Mozilla doesn't allow designMode to be set reliably until the iframe is
+       // fully loaded.
+       var _this = this;
+       var iframe = _this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem;
+       _this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImplStandard::initializing = true;
+
+       iframe.onload = function() {
+         // Some Mozillae have the nasty habit of calling onload again when you set
+         // designMode, so let's avoid doing it more than once.
+         iframe.onload = null;
+
+         // Send notification that the iframe has finished loading.
+         _this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImplStandard::onElementInitialized()();
+
+         // Don't set designMode until the RTA actually gets focused. This is
+         // necessary because editing won't work on Mozilla if the iframe is
+         // *hidden, but attached*. Waiting for focus gets around this issue.
+         //
+         // Note: This onfocus will not conflict with the addEventListener('focus',
+         // ...) // in RichTextAreaImplStandard.
+         iframe.contentWindow.onfocus = function() {
+           iframe.contentWindow.onfocus = null;
+           iframe.contentWindow.document.designMode = 'On';
+         };
+       };
+     }-*/;
+
+    @Override
+    public void setBackColor(String color) {
+        // Gecko uses 'BackColor' for the *entire area's* background.
+        // 'HiliteColor'
+        // does what we actually want.
+        execCommand("HiliteColor", color);
+    }
+}

Added: trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/impl/RichTextAreaImplOpera.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/impl/RichTextAreaImplOpera.java	2009-01-26 23:25:53 UTC (rev 1039)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/impl/RichTextAreaImplOpera.java	2009-01-27 01:24:24 UTC (rev 1040)
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2007 Google Inc.
+ * 
+ * Licensed 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.
+ */
+package org.ourproject.kune.platf.client.ui.rte.impl;
+
+/**
+ * Opera implementation of rich-text editing.
+ */
+public class RichTextAreaImplOpera extends RichTextAreaImplStandard {
+
+    @Override
+    public void setBackColor(String color) {
+        // Opera uses 'BackColor' for the *entire area's* background.
+        // 'HiliteColor'
+        // does what we actually want.
+        execCommand("HiliteColor", color);
+    }
+
+    @Override
+    public native void setFocus(boolean focused) /*-{
+       // Opera needs the *iframe* focused, not its window.
+       if (focused) {
+         this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem.focus();
+       } else {
+         this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem.blur();
+       }
+     }-*/;
+}

Added: trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/impl/RichTextAreaImplSafari.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/impl/RichTextAreaImplSafari.java	2009-01-26 23:25:53 UTC (rev 1039)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/impl/RichTextAreaImplSafari.java	2009-01-27 01:24:24 UTC (rev 1040)
@@ -0,0 +1,227 @@
+/*
+ * Copyright 2007 Google Inc.
+ *
+ * Licensed 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.
+ */
+package org.ourproject.kune.platf.client.ui.rte.impl;
+
+import com.google.gwt.user.client.Element;
+import org.ourproject.kune.platf.client.ui.rte.RichTextArea.FontSize;
+
+/**
+ * Safari rich text platform implementation.
+ */
+public class RichTextAreaImplSafari extends RichTextAreaImplStandard {
+
+    private static final String[] sizeNumberCSSValues = new String[] { "medium", "xx-small", "x-small", "small",
+            "medium", "large", "x-large", "xx-large" };
+
+    private static int webKitVersion = getWebKitVersion();
+
+    /**
+     * WebKit v420 began suppporting full rich text editing.
+     */
+    private static boolean extendedEditingSupported = (webKitVersion >= 420);
+
+    /**
+     * WebKit v420 changed BackColor to HiliteColor.
+     */
+    private static boolean useHiliteColor = (webKitVersion >= 420);
+
+    /**
+     * WebKit version up to *and including* 420 require CSS font-size values
+     * (e.g. 'medium', 'x-large') rather than size numbers. All subsequent
+     * versions use size numbers like other browsers.
+     */
+    private static boolean oldSchoolSizeValues = (webKitVersion <= 420);
+
+    private static native int getWebKitVersion() /*-{
+       var exp = / AppleWebKit\/([\d]+)/;
+       var result = exp.exec(navigator.userAgent);
+       if (result) {
+         var version = parseInt(result[1]);
+         if (version) {
+           return version;
+         }
+       }
+
+       // Intentionally conservative fallback.
+       return 0;
+     }-*/;;
+
+    @Override
+    public Element createElement() {
+        return super.createElement();
+    }
+
+    @Override
+    public native boolean isBold() /*-{
+       return !!this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem.__gwt_isBold;
+     }-*/;
+
+    @Override
+    public boolean isExtendedEditingSupported() {
+        return extendedEditingSupported;
+    }
+
+    @Override
+    public native boolean isItalic() /*-{
+       return !!this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem.__gwt_isItalic;
+     }-*/;
+
+    @Override
+    public native boolean isUnderlined() /*-{
+       return !!this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem.__gwt_isUnderlined;
+     }-*/;
+
+    @Override
+    public void setBackColor(String color) {
+        if (useHiliteColor) {
+            execCommand("HiliteColor", color);
+        } else {
+            super.setBackColor(color);
+        }
+    }
+
+    @Override
+    public native void setFocus(boolean focused) /*-{
+       // Safari needs the *iframe* focused, not its window.
+       var elem = this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem;
+       if (focused) {
+         elem.focus();
+         if (elem.__gwt_restoreSelection) {
+           elem.__gwt_restoreSelection();
+         }
+       } else {
+         elem.blur();
+       }
+     }-*/;
+
+    @Override
+    public void setFontSize(FontSize fontSize) {
+        if (oldSchoolSizeValues) {
+            // Safari2 only accepts css-style 'small, medium, large, etc'
+            // values.
+            // Setting these doesn't seem to hurt Safari3.
+            int number = fontSize.getNumber();
+            if ((number >= 0) && (number <= 7)) {
+                execCommand("FontSize", sizeNumberCSSValues[number]);
+            }
+        } else {
+            super.setFontSize(fontSize);
+        }
+    }
+
+    @Override
+    protected native String getTextImpl() /*-{
+       return this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem.contentWindow.document.body.innerText;
+     }-*/;
+
+    @Override
+    protected native void hookEvents() /*-{
+       var elem = this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem;
+       var wnd = elem.contentWindow;
+       var doc = wnd.document;
+
+       // Create an expando on the element to hold the selection state.
+       elem.__gwt_selection = { baseOffset:0, extentOffset:0, baseNode:null,
+         extentNode:null };
+
+       // A function for restoring the selection state.
+       elem.__gwt_restoreSelection = function() {
+         var sel = elem.__gwt_selection;
+
+         // wnd.getSelection is not defined if the iframe isn't attached.
+         if (wnd.getSelection) {
+           wnd.getSelection().setBaseAndExtent(sel.baseNode, sel.baseOffset,
+             sel.extentNode, sel.extentOffset);
+         }
+       };
+
+       // Generic event dispatcher. Also stores selection state.
+       elem.__gwt_handler = function(evt) {
+         // Store the editor's selection state.
+         var s = wnd.getSelection();
+         elem.__gwt_selection = {
+           baseOffset:s.baseOffset,
+           extentOffset:s.extentOffset,
+
+           baseNode:s.baseNode,
+           extentNode:s.extentNode
+         };
+
+         // Hang on to bold/italic/underlined states.
+         elem.__gwt_isBold = doc.queryCommandState('Bold');
+         elem.__gwt_isItalic = doc.queryCommandState('Italic');
+         elem.__gwt_isUnderlined = doc.queryCommandState('Underline');
+
+         // Dispatch the event.
+         if (elem.__listener) {
+           elem.__listener. at org.ourproject.kune.platf.client.ui.rte.RichTextArea::onBrowserEvent(Lcom/google/gwt/user/client/Event;)(evt);
+         }
+       };
+
+       wnd.addEventListener('keydown', elem.__gwt_handler, true);
+       wnd.addEventListener('keyup', elem.__gwt_handler, true);
+       wnd.addEventListener('keypress', elem.__gwt_handler, true);
+       wnd.addEventListener('mousedown', elem.__gwt_handler, true);
+       wnd.addEventListener('mouseup', elem.__gwt_handler, true);
+       wnd.addEventListener('mousemove', elem.__gwt_handler, true);
+       wnd.addEventListener('mouseover', elem.__gwt_handler, true);
+       wnd.addEventListener('mouseout', elem.__gwt_handler, true);
+       wnd.addEventListener('click', elem.__gwt_handler, true);
+
+       // Focus/blur event handlers. For some reason, [add|remove]eventListener()
+       // doesn't work on the iframe element (at least not for focus/blur). Don't
+       // dispatch through the normal handler method, as some of the querying we do
+       // there interferes with focus.
+       elem.onfocus = function(evt) {
+         if (elem.__listener) {
+           elem.__listener. at org.ourproject.kune.platf.client.ui.rte.RichTextArea::onBrowserEvent(Lcom/google/gwt/user/client/Event;)(evt);
+         }
+       };
+
+       elem.onblur = function(evt) {
+         if (elem.__listener) {
+           elem.__listener. at org.ourproject.kune.platf.client.ui.rte.RichTextArea::onBrowserEvent(Lcom/google/gwt/user/client/Event;)(evt);
+         }
+       };
+     }-*/;
+
+    @Override
+    protected native void setTextImpl(String text) /*-{
+       this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem.contentWindow.document.body.innerText = text;
+     }-*/;
+
+    @Override
+    protected native void unhookEvents() /*-{
+       var elem = this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem;
+       var wnd = elem.contentWindow;
+
+       wnd.removeEventListener('keydown', elem.__gwt_handler, true);
+       wnd.removeEventListener('keyup', elem.__gwt_handler, true);
+       wnd.removeEventListener('keypress', elem.__gwt_handler, true);
+       wnd.removeEventListener('mousedown', elem.__gwt_handler, true);
+       wnd.removeEventListener('mouseup', elem.__gwt_handler, true);
+       wnd.removeEventListener('mousemove', elem.__gwt_handler, true);
+       wnd.removeEventListener('mouseover', elem.__gwt_handler, true);
+       wnd.removeEventListener('mouseout', elem.__gwt_handler, true);
+       wnd.removeEventListener('click', elem.__gwt_handler, true);
+
+       elem.__gwt_restoreSelection = null;
+       elem.__gwt_handler = null;
+
+       elem.onfocus = null;
+       elem.onblur = null;
+     }-*/;
+}

Added: trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/impl/RichTextAreaImplStandard.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/impl/RichTextAreaImplStandard.java	2009-01-26 23:25:53 UTC (rev 1039)
+++ trunk/src/main/java/org/ourproject/kune/platf/client/ui/rte/impl/RichTextAreaImplStandard.java	2009-01-27 01:24:24 UTC (rev 1040)
@@ -0,0 +1,406 @@
+/*
+ * Copyright 2008 Google Inc.
+ *
+ * Licensed 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.
+ */
+package org.ourproject.kune.platf.client.ui.rte.impl;
+
+import org.ourproject.kune.platf.client.ui.rte.RichTextArea;
+import org.ourproject.kune.platf.client.ui.rte.RichTextArea.FontSize;
+import org.ourproject.kune.platf.client.ui.rte.RichTextArea.Justification;
+
+import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
+
+/**
+ * Basic rich text platform implementation.
+ */
+public abstract class RichTextAreaImplStandard extends RichTextAreaImpl implements RichTextArea.BasicFormatter,
+        RichTextArea.ExtendedFormatter {
+
+    /**
+     * Holds a cached copy of any user setHTML/setText actions until the real
+     * text area is fully initialized. Becomes <code>null</code> after init.
+     */
+    private Element beforeInitPlaceholder = DOM.createDiv();
+
+    /**
+     * Set to true when the {@link RichTextArea} is attached to the page and
+     * {@link #initElement()} is called. If the {@link RichTextArea} is detached
+     * before {@link #onElementInitialized()} is called, this will be set to
+     * false. See issue 1897 for details.
+     */
+    protected boolean initializing;
+
+    @Override
+    public native Element createElement() /*-{
+          return $doc.createElement('iframe');
+        }-*/;
+
+    public void createLink(String url) {
+        execCommand("CreateLink", url);
+    }
+
+    public String getBackColor() {
+        return queryCommandValue("BackColor");
+    }
+
+    public String getForeColor() {
+        return queryCommandValue("ForeColor");
+    }
+
+    @Override
+    public final String getHTML() {
+        return beforeInitPlaceholder == null ? getHTMLImpl() : DOM.getInnerHTML(beforeInitPlaceholder);
+    }
+
+    @Override
+    public final String getText() {
+        return beforeInitPlaceholder == null ? getTextImpl() : DOM.getInnerText(beforeInitPlaceholder);
+    }
+
+    @Override
+    public native void initElement() /*-{
+         // Most browsers don't like setting designMode until slightly _after_
+         // the iframe becomes attached to the DOM. Any non-zero timeout will do
+         // just fine.
+         var _this = this;
+         _this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImplStandard::initializing = true;
+         setTimeout(function() {
+           // Turn on design mode.
+           _this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem.contentWindow.document.designMode = 'On';
+
+           // Send notification that the iframe has reached design mode.
+           _this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImplStandard::onElementInitialized()();
+         }, 1);
+       }-*/;
+
+    public void insertHorizontalRule() {
+        execCommand("InsertHorizontalRule", null);
+    }
+
+    public void insertHtml(String html) {
+        execCommand("InsertHtml", html);
+    }
+
+    public void insertImage(String url) {
+        execCommand("InsertImage", url);
+    }
+
+    public void insertOrderedList() {
+        execCommand("InsertOrderedList", null);
+    }
+
+    public void insertUnorderedList() {
+        execCommand("InsertUnorderedList", null);
+    }
+
+    @Override
+    public boolean isBasicEditingSupported() {
+        return true;
+    }
+
+    public boolean isBold() {
+        return queryCommandState("Bold");
+    }
+
+    @Override
+    public boolean isExtendedEditingSupported() {
+        return true;
+    }
+
+    public boolean isItalic() {
+        return queryCommandState("Italic");
+    }
+
+    public boolean isStrikethrough() {
+        return queryCommandState("Strikethrough");
+    }
+
+    public boolean isSubscript() {
+        return queryCommandState("Subscript");
+    }
+
+    public boolean isSuperscript() {
+        return queryCommandState("Superscript");
+    }
+
+    public boolean isUnderlined() {
+        return queryCommandState("Underline");
+    }
+
+    public void leftIndent() {
+        execCommand("Outdent", null);
+    }
+
+    public void removeFormat() {
+        execCommand("RemoveFormat", null);
+    }
+
+    public void removeLink() {
+        execCommand("Unlink", "false");
+    }
+
+    public void rightIndent() {
+        execCommand("Indent", null);
+    }
+
+    public void selectAll() {
+        execCommand("SelectAll", null);
+    }
+
+    public void setBackColor(String color) {
+        execCommand("BackColor", color);
+    }
+
+    @Override
+    public native void setFocus(boolean focused) /*-{
+          if (focused) {
+            this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem.contentWindow.focus();
+          } else {
+            this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem.contentWindow.blur();
+          }
+        }-*/;
+
+    public void setFontName(String name) {
+        execCommand("FontName", name);
+    }
+
+    public void setFontSize(FontSize fontSize) {
+        execCommand("FontSize", Integer.toString(fontSize.getNumber()));
+    }
+
+    public void setForeColor(String color) {
+        execCommand("ForeColor", color);
+    }
+
+    @Override
+    public final void setHTML(String html) {
+        if (beforeInitPlaceholder == null) {
+            setHTMLImpl(html);
+        } else {
+            DOM.setInnerHTML(beforeInitPlaceholder, html);
+        }
+    }
+
+    public void setJustification(Justification justification) {
+        if (justification == Justification.CENTER) {
+            execCommand("JustifyCenter", null);
+        } else if (justification == Justification.LEFT) {
+            execCommand("JustifyLeft", null);
+        } else if (justification == Justification.RIGHT) {
+            execCommand("JustifyRight", null);
+        }
+    }
+
+    @Override
+    public final void setText(String text) {
+        if (beforeInitPlaceholder == null) {
+            setTextImpl(text);
+        } else {
+            DOM.setInnerText(beforeInitPlaceholder, text);
+        }
+    }
+
+    public void toggleBold() {
+        execCommand("Bold", "false");
+    }
+
+    public void toggleItalic() {
+        execCommand("Italic", "false");
+    }
+
+    public void toggleStrikethrough() {
+        execCommand("Strikethrough", "false");
+    }
+
+    public void toggleSubscript() {
+        execCommand("Subscript", "false");
+    }
+
+    public void toggleSuperscript() {
+        execCommand("Superscript", "false");
+    }
+
+    public void toggleUnderline() {
+        execCommand("Underline", "False");
+    }
+
+    @Override
+    public void uninitElement() {
+        // Issue 1897: initElement uses a timeout, so its possible to call this
+        // method after calling initElement, but before the event system is in
+        // place.
+        if (initializing) {
+            initializing = false;
+            return;
+        }
+
+        // Unhook all custom event handlers when the element is detached.
+        unhookEvents();
+
+        // Recreate the placeholder element and store the iframe's contents in
+        // it.
+        // This is necessary because some browsers will wipe the iframe's
+        // contents
+        // when it is removed from the DOM.
+        String html = getHTML();
+        beforeInitPlaceholder = DOM.createDiv();
+        DOM.setInnerHTML(beforeInitPlaceholder, html);
+    }
+
+    protected native String getHTMLImpl() /*-{
+          return this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem.contentWindow.document.body.innerHTML;
+        }-*/;
+
+    protected native String getTextImpl() /*-{
+          return this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem.contentWindow.document.body.textContent;
+        }-*/;
+
+    @Override
+    protected native void hookEvents() /*-{
+          var elem = this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem;
+          var wnd = elem.contentWindow;
+
+          elem.__gwt_handler = function(evt) {
+            if (elem.__listener) {
+              elem.__listener. at org.ourproject.kune.platf.client.ui.rte.RichTextArea::onBrowserEvent(Lcom/google/gwt/user/client/Event;)(evt);
+            }
+          };
+
+          elem.__gwt_focusHandler = function(evt) {
+            if (elem.__gwt_isFocused) {
+              return;
+            }
+
+            elem.__gwt_isFocused = true;
+            elem.__gwt_handler(evt);
+          };
+
+          elem.__gwt_blurHandler = function(evt) {
+            if (!elem.__gwt_isFocused) {
+              return;
+            }
+
+            elem.__gwt_isFocused = false;
+            elem.__gwt_handler(evt);
+          };
+
+          wnd.addEventListener('keydown', elem.__gwt_handler, true);
+          wnd.addEventListener('keyup', elem.__gwt_handler, true);
+          wnd.addEventListener('keypress', elem.__gwt_handler, true);
+          wnd.addEventListener('mousedown', elem.__gwt_handler, true);
+          wnd.addEventListener('mouseup', elem.__gwt_handler, true);
+          wnd.addEventListener('mousemove', elem.__gwt_handler, true);
+          wnd.addEventListener('mouseover', elem.__gwt_handler, true);
+          wnd.addEventListener('mouseout', elem.__gwt_handler, true);
+          wnd.addEventListener('click', elem.__gwt_handler, true);
+
+          wnd.addEventListener('focus', elem.__gwt_focusHandler, true);
+          wnd.addEventListener('blur', elem.__gwt_blurHandler, true);
+        }-*/;
+
+    @Override
+    protected void onElementInitialized() {
+        // Issue 1897: This method is called after a timeout, during which time
+        // the
+        // element might by detached.
+        if (!initializing) {
+            return;
+        }
+        initializing = false;
+
+        super.onElementInitialized();
+
+        // When the iframe is ready, ensure cached content is set.
+        if (beforeInitPlaceholder != null) {
+            setHTMLImpl(DOM.getInnerHTML(beforeInitPlaceholder));
+            beforeInitPlaceholder = null;
+        }
+    }
+
+    protected native void setHTMLImpl(String html) /*-{
+          this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem.contentWindow.document.body.innerHTML = html;
+        }-*/;
+
+    protected native void setTextImpl(String text) /*-{
+          this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem.contentWindow.document.body.textContent = text;
+        }-*/;
+
+    protected native void unhookEvents() /*-{
+          var elem = this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem;
+          var wnd = elem.contentWindow;
+
+          wnd.removeEventListener('keydown', elem.__gwt_handler, true);
+          wnd.removeEventListener('keyup', elem.__gwt_handler, true);
+          wnd.removeEventListener('keypress', elem.__gwt_handler, true);
+          wnd.removeEventListener('mousedown', elem.__gwt_handler, true);
+          wnd.removeEventListener('mouseup', elem.__gwt_handler, true);
+          wnd.removeEventListener('mousemove', elem.__gwt_handler, true);
+          wnd.removeEventListener('mouseover', elem.__gwt_handler, true);
+          wnd.removeEventListener('mouseout', elem.__gwt_handler, true);
+          wnd.removeEventListener('click', elem.__gwt_handler, true);
+
+          wnd.removeEventListener('focus', elem.__gwt_focusHandler, true);
+          wnd.removeEventListener('blur', elem.__gwt_blurHandler, true);
+
+          elem.__gwt_handler = null;
+          elem.__gwt_focusHandler = null;
+          elem.__gwt_blurHandler = null;
+        }-*/;
+
+    void execCommand(String cmd, String param) {
+        if (isRichEditingActive(elem)) {
+            // When executing a command, focus the iframe first, since some
+            // commands
+            // don't take properly when it's not focused.
+            setFocus(true);
+            execCommandAssumingFocus(cmd, param);
+        }
+    }
+
+    native void execCommandAssumingFocus(String cmd, String param) /*-{
+          this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem.contentWindow.document.execCommand(cmd, false, param);
+        }-*/;
+
+    native boolean isRichEditingActive(Element e) /*-{
+          return ((e.contentWindow.document.designMode).toUpperCase()) == 'ON';
+        }-*/;
+
+    boolean queryCommandState(String cmd) {
+        if (isRichEditingActive(elem)) {
+            // When executing a command, focus the iframe first, since some
+            // commands
+            // don't take properly when it's not focused.
+            setFocus(true);
+            return queryCommandStateAssumingFocus(cmd);
+        } else {
+            return false;
+        }
+    }
+
+    native boolean queryCommandStateAssumingFocus(String cmd) /*-{
+          return !!this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem.contentWindow.document.queryCommandState(cmd);
+        }-*/;
+
+    String queryCommandValue(String cmd) {
+        // When executing a command, focus the iframe first, since some commands
+        // don't take properly when it's not focused.
+        setFocus(true);
+        return queryCommandValueAssumingFocus(cmd);
+    }
+
+    native String queryCommandValueAssumingFocus(String cmd) /*-{
+          return this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem.contentWindow.document.queryCommandValue(cmd);
+        }-*/;
+}

Modified: trunk/src/main/java/org/ourproject/kune/workspace/Kune-Workspace.gwt.xml
===================================================================
--- trunk/src/main/java/org/ourproject/kune/workspace/Kune-Workspace.gwt.xml	2009-01-26 23:25:53 UTC (rev 1039)
+++ trunk/src/main/java/org/ourproject/kune/workspace/Kune-Workspace.gwt.xml	2009-01-27 01:24:24 UTC (rev 1040)
@@ -1,48 +1,48 @@
 <!DOCTYPE document SYSTEM "src/main/java/gwt-module.dtd">
 <module>
-	<inherits name='org.ourproject.kune.platf.Kune-Platform' />
-	<inherits name="com.google.gwt.core.Core" />
-	<inherits name="com.google.gwt.user.UserAgent" />
-	<!-- RTE css inject -->
-	<!-- See gwt-user: com/google/gwt/user/RichText.gwt.xml -->
+    <inherits name='org.ourproject.kune.platf.Kune-Platform' />
+    <inherits name="com.google.gwt.core.Core" />
+    <inherits name="com.google.gwt.user.UserAgent" />
+    <!-- RTE css inject -->
+    <!-- See gwt-user: com/google/gwt/user/RichText.gwt.xml -->
 
-	<!-- IE-specific implementation -->
-	<replace-with
-		class="org.ourproject.kune.workspace.client.editor.WrappedRichTextAreaImplIE6">
-		<when-type-is
-			class="com.google.gwt.user.client.ui.impl.RichTextAreaImpl" />
-		<when-property-is name="user.agent" value="ie6" />
-	</replace-with>
+    <!-- IE-specific implementation -->
+    <replace-with
+        class="org.ourproject.kune.workspace.client.editor.WrappedRichTextAreaImplIE6">
+        <when-type-is
+            class="org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl" />
+        <when-property-is name="user.agent" value="ie6" />
+    </replace-with>
 
-	<!-- Mozilla-specific implementation -->
-	<replace-with
-		class="org.ourproject.kune.workspace.client.editor.WrappedRichTextAreaImplMozilla">
-		<when-type-is
-			class="com.google.gwt.user.client.ui.impl.RichTextAreaImpl" />
-		<any>
-			<when-property-is name="user.agent" value="gecko1_8" />
-			<when-property-is name="user.agent" value="gecko" />
-		</any>
-	</replace-with>
+    <!-- Mozilla-specific implementation -->
+    <replace-with
+        class="org.ourproject.kune.workspace.client.editor.WrappedRichTextAreaImplMozilla">
+        <when-type-is
+            class="org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl" />
+        <any>
+            <when-property-is name="user.agent" value="gecko1_8" />
+            <when-property-is name="user.agent" value="gecko" />
+        </any>
+    </replace-with>
 
-	<!-- Safari-specific implementation -->
-	<replace-with
-		class="org.ourproject.kune.workspace.client.editor.WrappedRichTextAreaImplSafari">
-		<when-type-is
-			class="com.google.gwt.user.client.ui.impl.RichTextAreaImpl" />
-		<any>
-			<when-property-is name="user.agent" value="safari" />
-		</any>
-	</replace-with>
+    <!-- Safari-specific implementation -->
+    <replace-with
+        class="org.ourproject.kune.workspace.client.editor.WrappedRichTextAreaImplSafari">
+        <when-type-is
+            class="org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl" />
+        <any>
+            <when-property-is name="user.agent" value="safari" />
+        </any>
+    </replace-with>
 
-	<!-- Opera-specific implementation -->
-	<replace-with
-		class="org.ourproject.kune.workspace.client.editor.WrappedRichTextAreaImplOpera">
-		<when-type-is
-			class="com.google.gwt.user.client.ui.impl.RichTextAreaImpl" />
-		<any>
-			<when-property-is name="user.agent" value="opera" />
-		</any>
-	</replace-with>
+    <!-- Opera-specific implementation -->
+    <replace-with
+        class="org.ourproject.kune.workspace.client.editor.WrappedRichTextAreaImplOpera">
+        <when-type-is
+            class="org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl" />
+        <any>
+            <when-property-is name="user.agent" value="opera" />
+        </any>
+    </replace-with>
 
 </module>

Modified: trunk/src/main/java/org/ourproject/kune/workspace/client/editor/TextEditorPanel.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/workspace/client/editor/TextEditorPanel.java	2009-01-26 23:25:53 UTC (rev 1039)
+++ trunk/src/main/java/org/ourproject/kune/workspace/client/editor/TextEditorPanel.java	2009-01-27 01:24:24 UTC (rev 1040)
@@ -21,13 +21,13 @@
 
 import org.ourproject.kune.platf.client.services.I18nTranslationService;
 import org.ourproject.kune.platf.client.ui.palette.ColorWebSafePalette;
+import org.ourproject.kune.platf.client.ui.rte.RichTextArea;
 import org.ourproject.kune.workspace.client.editor.insert.TextEditorInsertElement;
 import org.ourproject.kune.workspace.client.skel.Toolbar;
 import org.ourproject.kune.workspace.client.skel.WorkspaceSkeleton;
 
 import com.google.gwt.user.client.DOM;
 import com.google.gwt.user.client.Timer;
-import com.google.gwt.user.client.ui.RichTextArea;
 import com.google.gwt.user.client.ui.VerticalPanel;
 import com.gwtext.client.widgets.BoxComponent;
 import com.gwtext.client.widgets.MessageBox;

Modified: trunk/src/main/java/org/ourproject/kune/workspace/client/editor/TextEditorToolbar.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/workspace/client/editor/TextEditorToolbar.java	2009-01-26 23:25:53 UTC (rev 1039)
+++ trunk/src/main/java/org/ourproject/kune/workspace/client/editor/TextEditorToolbar.java	2009-01-27 01:24:24 UTC (rev 1040)
@@ -22,6 +22,7 @@
 import org.ourproject.kune.platf.client.services.I18nTranslationService;
 import org.ourproject.kune.platf.client.ui.KuneUiUtils;
 import org.ourproject.kune.platf.client.ui.palette.ColorWebSafePalette;
+import org.ourproject.kune.platf.client.ui.rte.RichTextArea;
 import org.ourproject.kune.workspace.client.editor.insert.TextEditorInsertElement;
 
 import com.calclab.suco.client.events.Listener;
@@ -36,7 +37,6 @@
 import com.google.gwt.user.client.ui.KeyboardListener;
 import com.google.gwt.user.client.ui.MenuBar;
 import com.google.gwt.user.client.ui.PushButton;
-import com.google.gwt.user.client.ui.RichTextArea;
 import com.google.gwt.user.client.ui.ToggleButton;
 import com.google.gwt.user.client.ui.VerticalPanel;
 import com.google.gwt.user.client.ui.Widget;
@@ -62,7 +62,7 @@
 
         public EventListener(TextEditorInsertElement insertElement) {
             this.insertElement = insertElement;
-            insertElement.onInsert(new Listener2<String, String>() {
+            insertElement.addOnCreateLink(new Listener2<String, String>() {
                 public void onEvent(String name, String url) {
                     extended.createLink(url);
                 }

Modified: trunk/src/main/java/org/ourproject/kune/workspace/client/editor/WrappedRichTextAreaImplIE6.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/workspace/client/editor/WrappedRichTextAreaImplIE6.java	2009-01-26 23:25:53 UTC (rev 1039)
+++ trunk/src/main/java/org/ourproject/kune/workspace/client/editor/WrappedRichTextAreaImplIE6.java	2009-01-27 01:24:24 UTC (rev 1040)
@@ -19,7 +19,7 @@
  */
 package org.ourproject.kune.workspace.client.editor;
 
-import com.google.gwt.user.client.ui.impl.RichTextAreaImplIE6;
+import org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImplIE6;
 
 /**
  * A wrapper used to inject css into RTA. As published in:
@@ -35,33 +35,33 @@
 
     @Override
     public native void initElement() /*-{
-                      var _this = this;
-                      _this. at com.google.gwt.user.client.ui.impl.RichTextAreaImplStandard::initializing = true;
+                         var _this = this;
+                         _this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImplStandard::initializing = true;
 
-                      setTimeout(function() {
-                        if (_this. at com.google.gwt.user.client.ui.impl.RichTextAreaImplStandard::initializing == false) {
-                          return;
-                        }
+                         setTimeout(function() {
+                           if (_this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImplStandard::initializing == false) {
+                             return;
+                           }
 
-                        // Attempt to set the iframe document's body to 'contentEditable' mode.
-                        // There's no way to know when the body will actually be available, so
-                        // keep trying every so often until it is.
-                        // Note: The body seems to be missing only rarely, so please don't remove
-                        // this retry loop just because it's hard to reproduce.
-                        var elem = _this. at com.google.gwt.user.client.ui.impl.RichTextAreaImpl::elem;
-                        var doc = elem.contentWindow.document;
-                        if (!doc.body) {
-                            // Retry in 50 ms. Faster would run the risk of pegging the CPU. Slower
-                            // would increase the probability of a user-visible delay.
-                          setTimeout(arguments.callee, 50);
-                          return;
-                        }
-                        var ct = "<html><head><style>@import url('" + "css/richtext.css" + "');</style></head><body CONTENTEDITABLE='true'></body></html>" ;
-                        doc.write( ct );
-                        doc.body.contentEditable = true;
+                           // Attempt to set the iframe document's body to 'contentEditable' mode.
+                           // There's no way to know when the body will actually be available, so
+                           // keep trying every so often until it is.
+                           // Note: The body seems to be missing only rarely, so please don't remove
+                           // this retry loop just because it's hard to reproduce.
+                           var elem = _this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem;
+                           var doc = elem.contentWindow.document;
+                           if (!doc.body) {
+                               // Retry in 50 ms. Faster would run the risk of pegging the CPU. Slower
+                               // would increase the probability of a user-visible delay.
+                             setTimeout(arguments.callee, 50);
+                             return;
+                           }
+                           var ct = "<html><head><style>@import url('" + "css/richtext.css" + "');</style></head><body CONTENTEDITABLE='true'></body></html>" ;
+                           doc.write( ct );
+                           doc.body.contentEditable = true;
 
-                        // Send notification that the iframe has reached design mode.
-                        _this. at com.google.gwt.user.client.ui.impl.RichTextAreaImplStandard::onElementInitialized()();
-                      }, 1);
-                    }-*/;
+                           // Send notification that the iframe has reached design mode.
+                           _this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImplStandard::onElementInitialized()();
+                         }, 1);
+                       }-*/;
 }

Modified: trunk/src/main/java/org/ourproject/kune/workspace/client/editor/WrappedRichTextAreaImplMozilla.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/workspace/client/editor/WrappedRichTextAreaImplMozilla.java	2009-01-26 23:25:53 UTC (rev 1039)
+++ trunk/src/main/java/org/ourproject/kune/workspace/client/editor/WrappedRichTextAreaImplMozilla.java	2009-01-27 01:24:24 UTC (rev 1040)
@@ -19,7 +19,7 @@
  */
 package org.ourproject.kune.workspace.client.editor;
 
-import com.google.gwt.user.client.ui.impl.RichTextAreaImplMozilla;
+import org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImplMozilla;
 
 /**
  * A wrapper used to inject css into RTA. As published in:
@@ -35,48 +35,48 @@
 
     @Override
     public native void initElement() /*-{
-                // Mozilla doesn't allow designMode to be set reliably until the iframe is
-                // fully loaded.
-                var _this = this;
-                var iframe = _this. at com.google.gwt.user.client.ui.impl.RichTextAreaImpl::elem;
-                _this. at com.google.gwt.user.client.ui.impl.RichTextAreaImplStandard::initializing = true;
+                   // Mozilla doesn't allow designMode to be set reliably until the iframe is
+                   // fully loaded.
+                   var _this = this;
+                   var iframe = _this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem;
+                   _this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImplStandard::initializing = true;
 
-                iframe.onload = function() {
-                  // Some Mozillae have the nasty habit of calling onload again when you set
-                  // designMode, so let's avoid doing it more than once.
-                  iframe.onload = null;
+                   iframe.onload = function() {
+                     // Some Mozillae have the nasty habit of calling onload again when you set
+                     // designMode, so let's avoid doing it more than once.
+                     iframe.onload = null;
 
-                  // patch ccs inject:
+                     // patch ccs inject:
 
-                  var doc = _this. at com.google.gwt.user.client.ui.impl.RichTextAreaImpl::elem.contentWindow.document;
-                  head=doc.getElementsByTagName('head')[0];
-                  link=document.createElement('link');
-                  link.setAttribute('rel',"stylesheet");
-                  link.setAttribute('type',"text/css");
-                  link.setAttribute('href',"css/richtext.css" );
-                  head.appendChild(link);
+                     var doc = _this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem.contentWindow.document;
+                     head=doc.getElementsByTagName('head')[0];
+                     link=document.createElement('link');
+                     link.setAttribute('rel',"stylesheet");
+                     link.setAttribute('type',"text/css");
+                     link.setAttribute('href',"css/richtext.css" );
+                     head.appendChild(link);
 
-                   var styles = document.createElement('style');
-                   styles.setAttribute('type', 'text/css');
-                   var newStyle = document.createTextNode('\n<!--\nbody{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:400;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:400;}q:before,q:after{content:\'\';}abbr,acronym{border:0;font-variant:normal;}sup,sub{line-height:-1px;vertical-align:text-top;}sub{vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}body{font:13px/1.22 arial,helvetica,clean,sans-serif;font-size:small;font:x-small;}table{font-size:inherit;font:100%;}pre,code,kbd,samp,tt{font-family:monospace;font-size:108%;line-height:99%;}h1{font-size:138.5%;}h2{font-size:123.1%;}h3{font-size:108%;}h1,h2,h3{margin:1em 0;}h1,h2,h3,h4,h5,h6,strong{font-weight:700;}abbr,acronym{border-bottom:1px dotted #000;cursor:help;}em{font-style:italic;}blockquote,ul,ol,dl{margin:1em;}ol,ul,dl{margin-left:2em;}ol li{list-style:decimal outside;}ul li{list-style:disc outside;}dl dd{margin-left:1em;}th,td{border:1px solid #000;padding:.5em;}th{font-weight:700;text-align:center;}caption{margin-bottom:.5em;text-align:center;}p,fieldset,table,pre{margin-bottom:1em;}input[type=text],input[type=password],textarea{width:12.25em;width:11.9em;}body{font-family:arial, sans;margin:5px}\n-->\n');
-                   styles.appendChild(newStyle);
-                   head.appendChild(styles);
+                      var styles = document.createElement('style');
+                      styles.setAttribute('type', 'text/css');
+                      var newStyle = document.createTextNode('\n<!--\nbody{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:400;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:400;}q:before,q:after{content:\'\';}abbr,acronym{border:0;font-variant:normal;}sup,sub{line-height:-1px;vertical-align:text-top;}sub{vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}body{font:13px/1.22 arial,helvetica,clean,sans-serif;font-size:small;font:x-small;}table{font-size:inherit;font:100%;}pre,code,kbd,samp,tt{font-family:monospace;font-size:108%;line-height:99%;}h1{font-size:138.5%;}h2{font-size:123.1%;}h3{font-size:108%;}h1,h2,h3{margin:1em 0;}h1,h2,h3,h4,h5,h6,strong{font-weight:700;}abbr,acronym{border-bottom:1px dotted #000;cursor:help;}em{font-style:italic;}blockquote,ul,ol,dl{margin:1em;}ol,ul,dl{margin-left:2em;}ol li{list-style:decimal outside;}ul li{list-style:disc outside;}dl dd{margin-left:1em;}th,td{border:1px solid #000;padding:.5em;}th{font-weight:700;text-align:center;}caption{margin-bottom:.5em;text-align:center;}p,fieldset,table,pre{margin-bottom:1em;}input[type=text],input[type=password],textarea{width:12.25em;width:11.9em;}body{font-family:arial, sans;margin:5px}\n-->\n');
+                      styles.appendChild(newStyle);
+                      head.appendChild(styles);
 
-                   // -- patch
+                      // -- patch
 
-                   // Send notification that the iframe has finished loading.
-                   _this. at com.google.gwt.user.client.ui.impl.RichTextAreaImplStandard::onElementInitialized()();
+                      // Send notification that the iframe has finished loading.
+                      _this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImplStandard::onElementInitialized()();
 
-                   // Don't set designMode until the RTA actually gets focused. This is
-                   // necessary because editing won't work on Mozilla if the iframe is
-                   // *hidden, but attached*. Waiting for focus gets around this issue.
-                   //
-                   // Note: This onfocus will not conflict with the addEventListener('focus',
-                   // ...) // in RichTextAreaImplStandard.
-                   iframe.contentWindow.onfocus = function() {
-                     iframe.contentWindow.onfocus = null;
-                     iframe.contentWindow.document.designMode = 'On';
-                   };
-                 };
-               }-*/;
+                      // Don't set designMode until the RTA actually gets focused. This is
+                      // necessary because editing won't work on Mozilla if the iframe is
+                      // *hidden, but attached*. Waiting for focus gets around this issue.
+                      //
+                      // Note: This onfocus will not conflict with the addEventListener('focus',
+                      // ...) // in RichTextAreaImplStandard.
+                      iframe.contentWindow.onfocus = function() {
+                        iframe.contentWindow.onfocus = null;
+                        iframe.contentWindow.document.designMode = 'On';
+                      };
+                    };
+                  }-*/;
 }

Modified: trunk/src/main/java/org/ourproject/kune/workspace/client/editor/WrappedRichTextAreaImplOpera.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/workspace/client/editor/WrappedRichTextAreaImplOpera.java	2009-01-26 23:25:53 UTC (rev 1039)
+++ trunk/src/main/java/org/ourproject/kune/workspace/client/editor/WrappedRichTextAreaImplOpera.java	2009-01-27 01:24:24 UTC (rev 1040)
@@ -18,30 +18,30 @@
  *
  */package org.ourproject.kune.workspace.client.editor;
 
-import com.google.gwt.user.client.ui.impl.RichTextAreaImplOpera;
+import org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImplOpera;
 
 public class WrappedRichTextAreaImplOpera extends RichTextAreaImplOpera {
 
     @Override
     public native void initElement() /*-{
-                                // Most browsers don't like setting designMode until slightly _after_
-                                // the iframe becomes attached to the DOM. Any non-zero timeout will do
-                                // just fine.
-                                var _this = this;
-                                _this. at com.google.gwt.user.client.ui.impl.RichTextAreaImplStandard::initializing = true;
-                                setTimeout(function() {
-                                  // Turn on design mode.
-                                  _this. at com.google.gwt.user.client.ui.impl.RichTextAreaImpl::elem.contentWindow.document.designMode = 'On';
-                                       // patch css inject:
-                                       var elem = _this. at com.google.gwt.user.client.ui.impl.RichTextAreaImpl::elem;
-                                       var doc = elem.contentWindow.document;
-                                       var ct = "<html><head><style>@import url('" + "css/richtext.css" + "');</style></head><body CONTENTEDITABLE='true'></body></html>" ;
-                                       doc.write( ct );
-                                       // -- patch
+                                   // Most browsers don't like setting designMode until slightly _after_
+                                   // the iframe becomes attached to the DOM. Any non-zero timeout will do
+                                   // just fine.
+                                   var _this = this;
+                                   _this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImplStandard::initializing = true;
+                                   setTimeout(function() {
+                                     // Turn on design mode.
+                                     _this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem.contentWindow.document.designMode = 'On';
+                                          // patch css inject:
+                                          var elem = _this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem;
+                                          var doc = elem.contentWindow.document;
+                                          var ct = "<html><head><style>@import url('" + "css/richtext.css" + "');</style></head><body CONTENTEDITABLE='true'></body></html>" ;
+                                          doc.write( ct );
+                                          // -- patch
 
-                                  // Send notification that the iframe has reached design mode.
-                                  _this. at com.google.gwt.user.client.ui.impl.RichTextAreaImplStandard::onElementInitialized()();
-                                }, 1);
-                              }-*/;
+                                     // Send notification that the iframe has reached design mode.
+                                     _this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImplStandard::onElementInitialized()();
+                                   }, 1);
+                                 }-*/;
 
 }

Modified: trunk/src/main/java/org/ourproject/kune/workspace/client/editor/WrappedRichTextAreaImplSafari.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/workspace/client/editor/WrappedRichTextAreaImplSafari.java	2009-01-26 23:25:53 UTC (rev 1039)
+++ trunk/src/main/java/org/ourproject/kune/workspace/client/editor/WrappedRichTextAreaImplSafari.java	2009-01-27 01:24:24 UTC (rev 1040)
@@ -18,31 +18,31 @@
  *
  */package org.ourproject.kune.workspace.client.editor;
 
-import com.google.gwt.user.client.ui.impl.RichTextAreaImplSafari;
+import org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImplSafari;
 
 public class WrappedRichTextAreaImplSafari extends RichTextAreaImplSafari {
 
     @Override
     public native void initElement() /*-{
-                                      // Most browsers don't like setting designMode until slightly _after_
-                                      // the iframe becomes attached to the DOM. Any non-zero timeout will do
-                                      // just fine.
-                                      var _this = this;
-                                      _this. at com.google.gwt.user.client.ui.impl.RichTextAreaImplStandard::initializing = true;
-                                      setTimeout(function() {
-                                        // Turn on design mode.
-                                        _this. at com.google.gwt.user.client.ui.impl.RichTextAreaImpl::elem.contentWindow.document.designMode = 'On';
-                                        
-                                       // patch css inject:
-                                       var elem = _this. at com.google.gwt.user.client.ui.impl.RichTextAreaImpl::elem;
-                                       var doc = elem.contentWindow.document;
-                                       var ct = "<html><head><style>@import url('" + "css/richtext.css" + "');</style></head><body CONTENTEDITABLE='true'></body></html>" ;
-                                       doc.write( ct );
-                                       // -- patch
+                                         // Most browsers don't like setting designMode until slightly _after_
+                                         // the iframe becomes attached to the DOM. Any non-zero timeout will do
+                                         // just fine.
+                                         var _this = this;
+                                         _this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImplStandard::initializing = true;
+                                         setTimeout(function() {
+                                           // Turn on design mode.
+                                           _this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem.contentWindow.document.designMode = 'On';
 
-                                        // Send notification that the iframe has reached design mode.
-                                        _this. at com.google.gwt.user.client.ui.impl.RichTextAreaImplStandard::onElementInitialized()();
-                                      }, 1);
-                                    }-*/;
+                                          // patch css inject:
+                                          var elem = _this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImpl::elem;
+                                          var doc = elem.contentWindow.document;
+                                          var ct = "<html><head><style>@import url('" + "css/richtext.css" + "');</style></head><body CONTENTEDITABLE='true'></body></html>" ;
+                                          doc.write( ct );
+                                          // -- patch
 
+                                           // Send notification that the iframe has reached design mode.
+                                           _this. at org.ourproject.kune.platf.client.ui.rte.impl.RichTextAreaImplStandard::onElementInitialized()();
+                                         }, 1);
+                                       }-*/;
+
 }

Modified: trunk/src/main/java/org/ourproject/kune/workspace/client/editor/insert/TextEditorInsertElement.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/workspace/client/editor/insert/TextEditorInsertElement.java	2009-01-26 23:25:53 UTC (rev 1039)
+++ trunk/src/main/java/org/ourproject/kune/workspace/client/editor/insert/TextEditorInsertElement.java	2009-01-27 01:24:24 UTC (rev 1040)
@@ -6,8 +6,8 @@
 
 public interface TextEditorInsertElement extends AbstractOptions {
 
-    void fireOnInsert(String name, String link);
+    void addOnCreateLink(Listener2<String, String> slot);
 
-    void onInsert(Listener2<String, String> slot);
+    void fireOnCreateLink(String name, String link);
 
 }

Modified: trunk/src/main/java/org/ourproject/kune/workspace/client/editor/insert/TextEditorInsertElementPresenter.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/workspace/client/editor/insert/TextEditorInsertElementPresenter.java	2009-01-26 23:25:53 UTC (rev 1039)
+++ trunk/src/main/java/org/ourproject/kune/workspace/client/editor/insert/TextEditorInsertElementPresenter.java	2009-01-27 01:24:24 UTC (rev 1040)
@@ -7,22 +7,27 @@
 
 public class TextEditorInsertElementPresenter extends AbstractOptionsPresenter implements TextEditorInsertElement {
 
-    private final Event2<String, String> onInsert;
+    private final Event2<String, String> onCreateLink;
 
     public TextEditorInsertElementPresenter() {
-        this.onInsert = new Event2<String, String>("onInsert");
+        this.onCreateLink = new Event2<String, String>("onCreateLink");
     }
 
-    public void fireOnInsert(String name, String link) {
-        onInsert.fire(name, link);
+    public void addOnCreateLink(final Listener2<String, String> slot) {
+        onCreateLink.add(slot);
+    }
+
+    public void fireOnCreateLink(String name, String link) {
+        onCreateLink.fire(name, link);
         super.hide();
     }
 
+    public void fireOnInsertHtml(String name, String link) {
+        onCreateLink.fire(name, link);
+        super.hide();
+    }
+
     public void init(TextEditorInsertElementView view) {
         super.init(view);
     }
-
-    public void onInsert(final Listener2<String, String> slot) {
-        onInsert.add(slot);
-    }
 }
\ No newline at end of file

Modified: trunk/src/main/java/org/ourproject/kune/workspace/client/editor/insert/abstractlink/TextEditorInsertAbstractPresenter.java
===================================================================
--- trunk/src/main/java/org/ourproject/kune/workspace/client/editor/insert/abstractlink/TextEditorInsertAbstractPresenter.java	2009-01-26 23:25:53 UTC (rev 1039)
+++ trunk/src/main/java/org/ourproject/kune/workspace/client/editor/insert/abstractlink/TextEditorInsertAbstractPresenter.java	2009-01-27 01:24:24 UTC (rev 1040)
@@ -22,7 +22,7 @@
     }
 
     public void onInsert(String name, String link) {
-        editorInsertElement.fireOnInsert(name, link);
+        editorInsertElement.fireOnCreateLink(name, link);
         reset();
     }
 

Modified: trunk/src/main/rails/publicspace/public/templates/basic/docs.liquid.html
===================================================================
--- trunk/src/main/rails/publicspace/public/templates/basic/docs.liquid.html	2009-01-26 23:25:53 UTC (rev 1039)
+++ trunk/src/main/rails/publicspace/public/templates/basic/docs.liquid.html	2009-01-27 01:24:24 UTC (rev 1040)
@@ -4,7 +4,7 @@
   <head>
     <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
     <title>{{ content.group_short_name }}: {{ content.title }}</title>
-    <link rel="shortcut icon" href="/kune/servlets/EntityLogoDownloadManager?token={{ content.statetoken }} />
+    <link rel="shortcut icon" href="/kune/servlets/EntityLogoDownloadManager?token={{ content.statetoken }}" />
     <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.6.0/build/reset/reset-min.css">
     <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.6.0/build/fonts/fonts-min.css">
     <link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.6.0/build/base/base-min.css">




More information about the kune-commits mailing list