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

com.google.gwt.user.client.ui.impl.RichTextAreaImplStandard Maven / Gradle / Ivy

The newest version!
/*
 * 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 com.google.gwt.user.client.ui.impl;

import com.google.gwt.core.client.JavaScriptException;
import com.google.gwt.dom.client.Element;
import com.google.gwt.safehtml.shared.annotations.IsSafeHtml;
import com.google.gwt.safehtml.shared.annotations.SuppressIsSafeHtmlCastCheck;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.ui.RichTextArea;
import com.google.gwt.user.client.ui.RichTextArea.FontSize;
import com.google.gwt.user.client.ui.RichTextArea.Justification;

/**
 * Basic rich text platform implementation.
 *
 * 

Deprecated, may be flattened into RichTextAreaImpl as it has no other * direct subclasses.

*/ @Deprecated public abstract class RichTextAreaImplStandard extends RichTextAreaImpl implements RichTextArea.Formatter { /** * The message displayed when the formatter is used before the RichTextArea * is initialized. */ private static final String INACTIVE_MESSAGE = "RichTextArea formatters " + "cannot be used until the RichTextArea is attached and focused."; /** * Holds a cached copy of any user setHTML/setText/setEnabled actions until * the real text area is fully initialized. Becomes null 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; /** * Indicates that the text area should be focused as soon as it is loaded. */ private boolean isPendingFocus; /** * True when the element has been attached. */ private boolean isReady; @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() : beforeInitPlaceholder.getInnerHTML(); } @Override public final String getText() { return beforeInitPlaceholder == null ? getTextImpl() : beforeInitPlaceholder.getInnerText(); } @Override @SuppressWarnings("deprecation") 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.@com.google.gwt.user.client.ui.impl.RichTextAreaImplStandard::onElementInitializing()(); setTimeout($entry(function() { // We need to check to see if the content window still is there. It might not be if the RTA // first was attached to the DOM and then quickly was removed before the timeout fired. if ([email protected]::elem.contentWindow != null) { // Turn on design mode. [email protected]::elem.contentWindow.document.designMode = 'On'; // Send notification that the iframe has reached design mode. _this.@com.google.gwt.user.client.ui.impl.RichTextAreaImplStandard::onElementInitialized()(); } }), 1); }-*/; public void insertHorizontalRule() { execCommand("InsertHorizontalRule", null); } public void insertHTML(@IsSafeHtml 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); } public boolean isBold() { return queryCommandState("Bold"); } @Override public boolean isEnabled() { return beforeInitPlaceholder == null ? isEnabledImpl() : !beforeInitPlaceholder.getPropertyBoolean("disabled"); } 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 redo() { execCommand("Redo", "false"); } 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 void setEnabled(boolean enabled) { if (beforeInitPlaceholder == null) { setEnabledImpl(enabled); } else { beforeInitPlaceholder.setPropertyBoolean("disabled", !enabled); } } @Override public void setFocus(boolean focused) { if (initializing) { // Issue 3503: if we focus before the iframe is in design mode, the text // caret will not appear. isPendingFocus = focused; } else { setFocusImpl(focused); } } 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(@IsSafeHtml String html) { if (beforeInitPlaceholder == null) { setHTMLImpl(html); } else { beforeInitPlaceholder.setInnerHTML(html); } } public void setJustification(Justification justification) { if (justification == Justification.CENTER) { execCommand("JustifyCenter", null); } else if (justification == Justification.FULL) { execCommand("JustifyFull", 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 { beforeInitPlaceholder.setInnerText(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"); } public void undo() { execCommand("Undo", "false"); } @Override @SuppressIsSafeHtmlCastCheck public void uninitElement() { isReady = false; // 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 and the // enabled status in it. This is necessary because some browsers will wipe // the iframe's contents when it is removed from the DOM. @IsSafeHtml String html = getHTML(); // TODO: mXSS boolean enabled = isEnabled(); beforeInitPlaceholder = DOM.createDiv(); beforeInitPlaceholder.setInnerHTML(html); setEnabled(enabled); } protected native String getHTMLImpl() /*-{ return [email protected]::elem.contentWindow.document.body.innerHTML; }-*/; protected native String getTextImpl() /*-{ return [email protected]::elem.contentWindow.document.body.textContent; }-*/; @Override protected native void hookEvents() /*-{ var elem = [email protected]::elem; var wnd = elem.contentWindow; elem.__gwt_handler = $entry(function(evt) { @com.google.gwt.user.client.DOM::dispatchEvent(Lcom/google/gwt/user/client/Event;Lcom/google/gwt/dom/client/Element;)(evt, elem); }); 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); }-*/; protected native boolean isEnabledImpl() /*-{ var elem = [email protected]::elem; return elem.contentWindow.document.designMode.toUpperCase() == 'ON'; }-*/; @Override @SuppressIsSafeHtmlCastCheck 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; isReady = true; // When the iframe is ready, ensure cached content is set. if (beforeInitPlaceholder != null) { setHTMLImpl(beforeInitPlaceholder.getInnerHTML()); setEnabledImpl(isEnabled()); beforeInitPlaceholder = null; } super.onElementInitialized(); // Focus on the element now that it is initialized if (isPendingFocus) { isPendingFocus = false; setFocus(true); } } protected void onElementInitializing() { initializing = true; isPendingFocus = false; } protected native void setEnabledImpl(boolean enabled) /*-{ var elem = [email protected]::elem; elem.contentWindow.document.designMode = enabled ? 'On' : 'Off'; }-*/; protected native void setFocusImpl(boolean focused) /*-{ if (focused) { [email protected]::elem.contentWindow.focus(); } else { [email protected]::elem.contentWindow.blur(); } }-*/; protected native void setHTMLImpl(@IsSafeHtml String html) /*-{ [email protected]::elem.contentWindow.document.body.innerHTML = html; }-*/; protected native void setTextImpl(String text) /*-{ [email protected]::elem.contentWindow.document.body.textContent = text; }-*/; protected native void unhookEvents() /*-{ var elem = [email protected]::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) { assert isReady : INACTIVE_MESSAGE; if (isReady) { // When executing a command, focus the iframe first, since some commands // don't take properly when it's not focused. setFocus(true); try { execCommandAssumingFocus(cmd, param); } catch (JavaScriptException e) { // In mozilla, editing throws a JS exception if the iframe is // *hidden, but attached*. } } } native void execCommandAssumingFocus(String cmd, String param) /*-{ [email protected]::elem.contentWindow.document.execCommand(cmd, false, param); }-*/; boolean queryCommandState(String cmd) { if (isReady) { // When executing a command, focus the iframe first, since some commands // don't take properly when it's not focused. setFocus(true); try { return queryCommandStateAssumingFocus(cmd); } catch (JavaScriptException e) { return false; } } return false; } native boolean queryCommandStateAssumingFocus(String cmd) /*-{ return [email protected]::elem.contentWindow.document.queryCommandState(cmd); }-*/; String queryCommandValue(String cmd) { if (isReady) { // When executing a command, focus the iframe first, since some commands // don't take properly when it's not focused. setFocus(true); try { return queryCommandValueAssumingFocus(cmd); } catch (JavaScriptException e) { return ""; } } return ""; } native String queryCommandValueAssumingFocus(String cmd) /*-{ return [email protected]::elem.contentWindow.document.queryCommandValue(cmd); }-*/; }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy