blob: 72ff98c7f3c54b1b6b2bc37f368d79bc70839744 [file] [log] [blame]
/*
* 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;
/**
* Mozilla-specific implementation of rich-text editing.
*/
public class RichTextAreaImplMozilla extends RichTextAreaImplStandard {
/**
* Indicates that the RichTextArea has never received focus after
* initialization.
*/
boolean isFirstFocus;
@Override
public String getBackColor() {
return queryCommandValue("HiliteColor");
}
@Override
@SuppressWarnings("deprecation")
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.@com.google.gwt.user.client.ui.impl.RichTextAreaImpl::elem;
_this.@com.google.gwt.user.client.ui.impl.RichTextAreaImplStandard::onElementInitializing()();
_this.@com.google.gwt.user.client.ui.impl.RichTextAreaImplMozilla::isFirstFocus = true;
iframe.onload = $entry(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;
// Don't set designMode until the RTA is targeted by an event. This is
// necessary because editing won't work on Mozilla if the iframe is
// *hidden, but attached*. Waiting for an event gets around this issue.
//
// Note: These events will not conflict with the
// addEventListener('oneventtype', ...) in RichTextAreaImplStandard.
iframe.contentWindow.onfocus = function() {
iframe.contentWindow.onfocus = null;
iframe.contentWindow.onmouseover = null;
iframe.contentWindow.document.designMode = 'On';
};
// Issue 1441: we also need to catch the onmouseover event because focus
// occurs after mouse down, so the cursor will not appear until the user
// clicks twice, making the RichTextArea look uneditable. Catching the
// mouseover event allows us to set design mode earlier. The focus event
// is still needed to handle tab selection.
iframe.contentWindow.onmouseover = iframe.contentWindow.onfocus;
// Send notification that the iframe has finished loading.
_this.@com.google.gwt.user.client.ui.impl.RichTextAreaImplStandard::onElementInitialized()();
});
}-*/;
@Override
public void setBackColor(String color) {
// Gecko uses 'BackColor' for the *entire area's* background. 'HiliteColor'
// does what we actually want.
execCommand("HiliteColor", color);
}
/**
* Firefox will not display the caret the first time a RichTextArea is
* programmatically focused, so we need to focus, blur, and refocus the
* RichTextArea. This only needs to be done the first time after the
* RichTextArea is initialized. See issue 3503.
*/
protected native void setFirstFocusImpl() /*-{
var elem = this.@com.google.gwt.user.client.ui.impl.RichTextAreaImpl::elem;
var wnd = elem.contentWindow;
// Remove event listeners so we don't generate extra focus and blur events.
wnd.removeEventListener('focus', elem.__gwt_focusHandler, true);
wnd.removeEventListener('blur', elem.__gwt_blurHandler, true);
wnd.focus();
wnd.blur();
wnd.focus();
// Add the event listeners now that we have focus and a caret.
wnd.addEventListener('focus', elem.__gwt_focusHandler, true);
wnd.addEventListener('blur', elem.__gwt_blurHandler, true);
// Fire a synthetic focus event. We can't move the last call to wnd.focus()
// here because firefox will not fire the focus event reliably.
var evt = document.createEvent('HTMLEvents');
evt.initEvent('focus', false, false);
wnd.dispatchEvent(evt);
}-*/;
@Override
protected void setFocusImpl(boolean focused) {
if (isFirstFocus) {
isFirstFocus = false;
setFirstFocusImpl();
} else {
super.setFocusImpl(focused);
}
}
}