You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by sv...@apache.org on 2006/11/10 10:15:40 UTC
svn commit: r473277 [35/45] - in
/myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource:
./ src/ src/animation/ src/cal/ src/charting/ src/charting/svg/
src/charting/vml/ src/collections/ src/crypto/ src/data/ src/data/...
Modified: myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/RichText.js
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/RichText.js?view=diff&rev=473277&r1=473276&r2=473277
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/RichText.js (original)
+++ myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/RichText.js Fri Nov 10 01:15:01 2006
@@ -10,96 +10,103 @@
/* -*- tab-width: 4 -*- */
dojo.provide("dojo.widget.RichText");
-dojo.provide("dojo.widget.html.RichText");
dojo.require("dojo.widget.*");
-dojo.require("dojo.dom");
-dojo.require("dojo.html");
+dojo.require("dojo.html.*");
+dojo.require("dojo.html.layout");
dojo.require("dojo.event.*");
-dojo.require("dojo.style");
-dojo.require("dojo.string");
+dojo.require("dojo.string.extras");
+dojo.require("dojo.uri.Uri");
// used to save content
-try {
- document.write('<textarea id="dojo.widget.RichText.savedContent" ' +
- 'style="display:none;position:absolute;top:-100px;left:-100px;height:3px;width:3px;overflow:hidden;"></textarea>');
-}catch(e){ }
-
+if(dojo.hostenv.post_load_){
+ (function(){
+ var savetextarea = dojo.doc().createElement('textarea');
+ savetextarea.id = "dojo.widget.RichText.savedContent";
+ savetextarea.style = "display:none;position:absolute;top:-100px;left:-100px;height:3px;width:3px;overflow:hidden;";
+ dojo.body().appendChild(savetextarea);
+ })();
+}else{
+ //dojo.body() is not available before onLoad is fired
+ try {
+ dojo.doc().write('<textarea id="dojo.widget.RichText.savedContent" ' +
+ 'style="display:none;position:absolute;top:-100px;left:-100px;height:3px;width:3px;overflow:hidden;"></textarea>');
+ }catch(e){ }
+}
+
+// summary:
+// dojo.widget.RichText is the core of the WYSIWYG editor in dojo, which
+// provides the basic editing features. It also encapsulates the differences
+// of different js engines for various browsers
dojo.widget.defineWidget(
- "dojo.widget.html.RichText",
+ "dojo.widget.RichText",
dojo.widget.HtmlWidget,
{
- /** whether to inherit the parent's width or simply use 100% */
+ // Boolean:
+ // whether to inherit the parent's width or simply use 100%
inheritWidth: false,
+
+ // Boolean:
+ // whether focusing into this instance of richtext when page onload
focusOnLoad: true,
-
- /**
- * If a save name is specified the content is saved and restored if the
- * editor is not properly closed after editing has started.
- */
+
+ // String:
+ // If a save name is specified the content is saved and restored if the
+ // editor is not properly closed after editing has started.
saveName: "",
+
+ // String:
+ // temporary content storage
_content: "",
-
- /* set height to fix the editor at a specific height, with scrolling */
- height: null,
- /** The minimum height that the editor should have */
+ // String:
+ // set height to fix the editor at a specific height, with scrolling
+ height: "",
+
+ // String:
+ // The minimum height that the editor should have
minHeight: "1em",
-
+
+ // Boolean:
isClosed: true,
+ // Boolean:
isLoaded: false,
-
- /** whether to use the active-x object in IE */
+
+ // Boolean:
+ // whether to use the active-x object in IE
useActiveX: false,
- /* whether to use relative URLs for images - if this is enabled
- images will be given absolute URLs when inside the editor but
- will be changed to use relative URLs (to the current page) on save
- */
+ // Boolean:
+ // whether to use relative URLs for images - if this is enabled
+ // images will be given absolute URLs when inside the editor but
+ // will be changed to use relative URLs (to the current page) on save
relativeImageUrls: false,
-
- _SEPARATOR: "@@**%%__RICHTEXTBOUNDRY__%%**@@",
-
- // contentFilters: [],
-
- /*
- defaultContentCleaner: function(content){
- if(!dojo.render.html.ie){
- return content;
- }
- content = content.replace(/\x20/g, " ");
- // alert(content);
- return content;
- },
- */
+ // String:
+ // used to concat contents from multiple textareas into a single string
+ _SEPARATOR: "@@**%%__RICHTEXTBOUNDRY__%%**@@",
/* Init
*******/
fillInTemplate: function(){
+ // summary: see dojo.widget.DomWidget
+ dojo.event.topic.publish("dojo.widget.RichText::init", this);
this.open();
- // add the formatting functions
- var funcs = ["queryCommandEnabled", "queryCommandState",
- "queryCommandValue", "execCommand"];
- for(var i = 0; i < funcs.length; i++){
- dojo.event.connect("around", this, funcs[i], this, "_normalizeCommand");
- }
-
// backwards compatibility, needs to be removed
dojo.event.connect(this, "onKeyPressed", this, "afterKeyPress");
dojo.event.connect(this, "onKeyPress", this, "keyPress");
dojo.event.connect(this, "onKeyDown", this, "keyDown");
dojo.event.connect(this, "onKeyUp", this, "keyUp");
- // add default some key handlers
+ // add default some key handlers
var ctrl = this.KEY_CTRL;
var exec = function (cmd, arg) {
return arguments.length == 1 ? function () { this.execCommand(cmd); } :
function () { this.execCommand(cmd, arg); }
}
-
+
this.addKeyHandler("b", ctrl, exec("bold"));
this.addKeyHandler("i", ctrl, exec("italic"));
this.addKeyHandler("u", ctrl, exec("underline"));
@@ -107,12 +114,12 @@
//this.addKeyHandler("k", ctrl, exec("createlink", ""));
//this.addKeyHandler("K", ctrl, exec("unlink"));
this.addKeyHandler("s", ctrl, function () { this.save(true); });
-
+
this.addKeyHandler("1", ctrl, exec("formatblock", "h1"));
this.addKeyHandler("2", ctrl, exec("formatblock", "h2"));
this.addKeyHandler("3", ctrl, exec("formatblock", "h3"));
this.addKeyHandler("4", ctrl, exec("formatblock", "h4"));
-
+
this.addKeyHandler("\\", ctrl, exec("insertunorderedlist"));
if(!dojo.render.html.ie){
this.addKeyHandler("Z", ctrl, exec("redo"));
@@ -120,6 +127,7 @@
},
+ // Array: events which should be connected to the underlying editing area
events: ["onBlur", "onFocus", "onKeyPress", "onKeyDown", "onKeyUp", "onClick"],
/**
@@ -128,7 +136,13 @@
* designMode is used, an <object> and active-x component if inside of IE or
* a reguler element if contentEditable is available.
*/
- open: function (element) {
+ open: function (/*DomNode, optional*/element) {
+ // summary:
+ // Transforms the node referenced in this.domNode into a rich text editing
+ // node. This can result in the creation and replacement with an <iframe> if
+ // designMode is used, an <object> and active-x component if inside of IE or
+ // a reguler element if contentEditable is available.
+ var h = dojo.render.html;
dojo.event.topic.publish("dojo.widget.RichText::open", this);
if (!this.isClosed) { this.close(); }
@@ -140,61 +154,79 @@
this.textarea = this.domNode;
var html = dojo.string.trim(this.textarea.value);
if(html == ""){ html = " "; }
- this.domNode = document.createElement("div");
- with(this.textarea.style){
- display = "block";
- position = "absolute";
- width = "1px";
- height = "1px";
- border = margin = padding = "0px";
- visiblity = "hidden";
- if(dojo.render.html.ie){
- overflow = "hidden";
+ this.domNode = dojo.doc().createElement("div");
+ dojo.html.copyStyle(this.domNode, this.textarea);
+ var tmpFunc = dojo.lang.hitch(this, function(){
+ //some browsers refuse to submit display=none textarea, so
+ //move the textarea out of screen instead
+ with(this.textarea.style){
+ display = "block";
+ position = "absolute";
+ left = top = "-1000px";
+
+ if(h.ie){ //nasty IE bug: abnormal formatting if overflow is not hidden
+ this.__overflow = overflow;
+ overflow = "hidden";
+ }
}
+ });
+ if(h.ie){
+ setTimeout(tmpFunc, 10);
+ }else{
+ tmpFunc();
}
- dojo.dom.insertBefore(this.domNode, this.textarea);
- this.domNode.innerHTML = html;
-
+ if(!h.safari){
+ // FIXME: VERY STRANGE safari 2.0.4 behavior here caused by
+ // moving the textarea. Often crashed the browser!!! Seems
+ // fixed on webkit nightlies.
+ dojo.html.insertBefore(this.domNode, this.textarea);
+ }
+ // this.domNode.innerHTML = html;
+
if(this.textarea.form){
- dojo.event.connect(this.textarea.form, "onsubmit",
+ dojo.event.connect(this.textarea.form, "onsubmit",
// FIXME: should we be calling close() here instead?
dojo.lang.hitch(this, function(){
this.textarea.value = this.getEditorContent();
})
);
}
-
+
// dojo plucks our original domNode from the document so we need
// to go back and put ourselves back in
var editor = this;
dojo.event.connect(this, "postCreate", function (){
- dojo.dom.insertAfter(editor.textarea, editor.domNode);
+ dojo.html.insertAfter(editor.textarea, editor.domNode);
});
}else{
- var html = dojo.string.trim(this.domNode.innerHTML);
+ var html = this._preFilterContent(dojo.string.trim(this.domNode.innerHTML));
if(html == ""){ html = " "; }
}
-
- this._oldHeight = dojo.style.getContentHeight(this.domNode);
- this._oldWidth = dojo.style.getContentWidth(this.domNode);
+
+ var content = dojo.html.getContentBox(this.domNode);
+ this._oldHeight = content.height;
+ this._oldWidth = content.width;
this._firstChildContributingMargin = this._getContributingMargin(this.domNode, "top");
this._lastChildContributingMargin = this._getContributingMargin(this.domNode, "bottom");
- this.savedContent = document.createElement("div");
+ this.savedContent = dojo.doc().createElement("div");
while (this.domNode.hasChildNodes()) {
this.savedContent.appendChild(this.domNode.firstChild);
}
-
+
+ this.editingArea = dojo.doc().createElement("div");
+ this.domNode.appendChild(this.editingArea);
+
// If we're a list item we have to put in a blank line to force the
// bullet to nicely align at the top of text
if( (this.domNode["nodeName"])&&
(this.domNode.nodeName == "LI")){
this.domNode.innerHTML = " <br>";
}
-
+
if(this.saveName != ""){
- var saveTextarea = document.getElementById("dojo.widget.RichText.savedContent");
+ var saveTextarea = dojo.doc().getElementById("dojo.widget.RichText.savedContent");
if (saveTextarea.value != "") {
var datas = saveTextarea.value.split(this._SEPARATOR);
for (var i = 0; i < datas.length; i++) {
@@ -204,65 +236,128 @@
datas.splice(i, 1);
break;
}
- }
+ }
}
dojo.event.connect("before", window, "onunload", this, "_saveContent");
// dojo.event.connect(window, "onunload", this, "_saveContent");
}
+ if(h.ie70 && this.useActiveX){
+ dojo.debug("activeX in ie70 is not currently supported, useActiveX is ignored for now.");
+ this.useActiveX = false;
+ }
// Safari's selections go all out of whack if we do it inline,
// so for now IE is our only hero
//if (typeof document.body.contentEditable != "undefined") {
- if (this.useActiveX && dojo.render.html.ie) { // active-x
- this._drawObject(html);
- // dojo.debug(this.object.document);
- } else if (dojo.render.html.ie) { // contentEditable, easy
- this.editNode = document.createElement("div");
- with (this.editNode) {
- innerHTML = html;
- contentEditable = true;
- style.height = this.height ? this.height : this.minHeight;
+ if(this.useActiveX && h.ie){ // active-x
+ var self = this;
+ //if call _drawObject directly here, textarea replacement
+ //won't work: no content is shown. However, add a delay
+ //can workaround this. No clue why.
+ setTimeout(function(){self._drawObject(html);}, 0);
+ }else if(h.ie){ // contentEditable, easy
+ this.iframe = dojo.doc().createElement( 'iframe' ) ;
+ this.iframe.src = 'javascript:void(0)';
+ this.editorObject = this.iframe;
+ with(this.iframe.style){
+ border = '0';
+ width = "100%";
+ }
+ this.iframe.frameBorder = 0;
+ this.editingArea.appendChild(this.iframe)
+ this.window = this.iframe.contentWindow;
+ this.document = this.window.document;
+ this.document.open();
+ this.document.write("<html><head></head><body style='margin: 0; padding: 0;border: 0; overflow: hidden;'><div></div></body></html>");
+ this.document.close();
+ this.editNode = this.document.body.firstChild;//document.createElement("div");
+ this.editNode.contentEditable = true;
+ with (this.iframe.style) {
+ if(h.ie70){
+ if(this.height){
+ height = this.height;
+ }
+ if(this.minHeight){
+ minHeight = this.minHeight;
+ }
+ }else{
+ height = this.height ? this.height : this.minHeight;
+ }
}
- if(this.height){ this.editNode.style.overflowY="scroll"; }
// FIXME: setting contentEditable on switches this element to
// IE's hasLayout mode, triggering weird margin collapsing
// behavior. It's particularly bad if the element you're editing
// contains childnodes that don't have margin: defined in local
// css rules. It would be nice if it was possible to hack around
- // this. Sadly _firstChildContributingMargin and
+ // this. Sadly _firstChildContributingMargin and
// _lastChildContributingMargin don't work on IE unless all
// elements have margins set in CSS :-(
- this.domNode.appendChild(this.editNode);
+ //if the normal way fails, we try the hard way to get the list
+ if(!this._cacheLocalBlockFormatNames()){
+ //in the array below, ul can not come directly after ol, otherwise the queryCommandValue returns Normal for it
+ var formats = ['p', 'pre', 'address', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ol', 'div', 'ul'];
+ var localhtml = "";
+ for(var i in formats){
+ if(formats[i].charAt(1) != 'l'){
+ localhtml += "<"+formats[i]+"><span>content</span></"+formats[i]+">";
+ }else{
+ localhtml += "<"+formats[i]+"><li>content</li></"+formats[i]+">";
+ }
+ }
+ //queryCommandValue returns empty if we hide editNode, so move it out of screen temporary
+ with(this.editNode.style){
+ position = "absolute";
+ left = "-2000px";
+ top = "-2000px";
+ }
+ this.editNode.innerHTML = localhtml;
+ var node = this.editNode.firstChild;
+ while(node){
+ dojo.withGlobal(this.window, "selectElement", dojo.html.selection, [node.firstChild]);
+ var nativename = node.tagName.toLowerCase();
+ this._local2NativeFormatNames[nativename] = this.queryCommandValue("formatblock");
+// dojo.debug([nativename,this._local2NativeFormatNames[nativename]]);
+ this._native2LocalFormatNames[this._local2NativeFormatNames[nativename]] = nativename;
+ node = node.nextSibling;
+ }
+ with(this.editNode.style){
+ position = "";
+ left = "";
+ top = "";
+ }
+ }
+
+ this.editNode.innerHTML = html;
+ if(this.height){ this.document.body.style.overflowY="scroll"; }
dojo.lang.forEach(this.events, function(e){
dojo.event.connect(this.editNode, e.toLowerCase(), this, e);
}, this);
-
- this.window = window;
- this.document = document;
-
+
this.onLoad();
} else { // designMode in iframe
this._drawIframe(html);
+ this.editorObject = this.iframe;
}
// TODO: this is a guess at the default line-height, kinda works
if (this.domNode.nodeName == "LI") { this.domNode.lastChild.style.marginTop = "-1.2em"; }
dojo.html.addClass(this.domNode, "RichTextEditable");
-
+
this.isClosed = false;
},
- _hasCollapseableMargin: function(element, side) {
- // check if an element has padding or borders on the given side
- // which would prevent it from collapsing margins
- if (dojo.style.getPixelValue(element,
- 'border-'+side+'-width',
+ _hasCollapseableMargin: function(/*DomNode*/element, /*String*/side) {
+ // summary:
+ // check if an element has padding or borders on the given side
+ // which would prevent it from collapsing margins
+ if (dojo.html.getPixelValue(element,
+ 'border-'+side+'-width',
false)) {
return false;
- } else if (dojo.style.getPixelValue(element,
+ } else if (dojo.html.getPixelValue(element,
'padding-'+side,
false)) {
return false;
@@ -271,11 +366,12 @@
}
},
- _getContributingMargin: function(element, topOrBottom) {
- // calculate how much margin this element and its first or last
- // child are contributing to the total margin between this element
- // and the adjacent node. CSS border collapsing makes this
- // necessary.
+ _getContributingMargin: function(/*DomNode*/element, /*String*/topOrBottom) {
+ // summary:
+ // calculate how much margin this element and its first or last
+ // child are contributing to the total margin between this element
+ // and the adjacent node. CSS border collapsing makes this
+ // necessary.
if (topOrBottom == "top") {
var siblingAttr = "previousSibling";
@@ -291,14 +387,14 @@
var siblingMarginProp = "margin-top";
}
- var elementMargin = dojo.style.getPixelValue(element, marginProp, false);
+ var elementMargin = dojo.html.getPixelValue(element, marginProp, false);
function isSignificantNode(element) {
// see if an node is significant in the current context
// for calulating margins
- return !(element.nodeType==3 && dojo.string.isBlank(element.data))
- && dojo.style.getStyle(element, "display") != "none"
- && !dojo.style.isPositionAbsolute(element);
+ return !(element.nodeType==3 && dojo.string.isBlank(element.data))
+ && dojo.html.getStyle(element, "display") != "none"
+ && !dojo.html.isPositionAbsolute(element);
}
// walk throuh first/last children to find total collapsed margin size
@@ -309,11 +405,11 @@
while ((!isSignificantNode(child)) && child[childSiblingAttr]) {
child = child[childSiblingAttr];
}
-
- childMargin = Math.max(childMargin, dojo.style.getPixelValue(child, marginProp, false));
+
+ childMargin = Math.max(childMargin, dojo.html.getPixelValue(child, marginProp, false));
// stop if we hit a bordered/padded element
if (!this._hasCollapseableMargin(child, topOrBottom)) break;
- child = child[childAttr];
+ child = child[childAttr];
}
// if this element has a border, return full child margin immediately
@@ -325,15 +421,15 @@
var sibling = element[siblingAttr];
while (sibling) {
if (isSignificantNode(sibling)) {
- contextMargin = dojo.style.getPixelValue(sibling,
- siblingMarginProp,
+ contextMargin = dojo.html.getPixelValue(sibling,
+ siblingMarginProp,
false);
break;
}
sibling = sibling[siblingAttr];
}
if (!sibling) { // no sibling, look at parent's margin instead
- contextMargin = dojo.style.getPixelValue(element.parentNode,
+ contextMargin = dojo.html.getPixelValue(element.parentNode,
marginProp, false);
}
@@ -342,58 +438,60 @@
} else {
return 0;
}
-
+
},
-
- /** Draws an iFrame using the existing one if one exists.
- Used by Mozilla, Safari, and Opera */
- _drawIframe: function (html) {
+
+ _drawIframe: function (/*String*/html){
+ // summary:
+ // Draws an iFrame using the existing one if one exists.
+ // Used by Mozilla, Safari, and Opera
// detect firefox < 1.5, which has some iframe loading issues
var oldMoz = Boolean(dojo.render.html.moz && (
typeof window.XML == 'undefined'))
- if (!this.iframe) {
- var currentDomain = (new dojo.uri.Uri(document.location)).host;
- this.iframe = document.createElement("iframe");
- with (this.iframe) {
- scrolling = this.height ? "auto" : "no";
+ if(!this.iframe){
+ var currentDomain = (new dojo.uri.Uri(dojo.doc().location)).host;
+ this.iframe = dojo.doc().createElement("iframe");
+ // dojo.body().appendChild(this.iframe);
+ with(this.iframe){
style.border = "none";
style.lineHeight = "0"; // squash line height
style.verticalAlign = "bottom";
+ scrolling = this.height ? "auto" : "no";
}
}
// opera likes this to be outside the with block
- this.iframe.src = dojo.uri.dojoUri("src/widget/templates/richtextframe.html") + "#" + ((document.domain != currentDomain) ? document.domain : "");
+ this.iframe.src = dojo.uri.dojoUri("src/widget/templates/richtextframe.html") + ((dojo.doc().domain != currentDomain) ? ("#"+dojo.doc().domain) : "");
this.iframe.width = this.inheritWidth ? this._oldWidth : "100%";
- if (this.height) {
+ if(this.height){
this.iframe.style.height = this.height;
- } else {
+ }else{
var height = this._oldHeight;
- if (this._hasCollapseableMargin(this.domNode, 'top')) {
+ if(this._hasCollapseableMargin(this.domNode, 'top')){
height += this._firstChildContributingMargin;
}
- if (this._hasCollapseableMargin(this.domNode, 'bottom')) {
+ if(this._hasCollapseableMargin(this.domNode, 'bottom')){
height += this._lastChildContributingMargin;
}
this.iframe.height = height;
}
- var tmpContent = document.createElement('div');
+ var tmpContent = dojo.doc().createElement('div');
tmpContent.innerHTML = html;
// make relative image urls absolute
- if (this.relativeImageUrls) {
+ if(this.relativeImageUrls){
var imgs = tmpContent.getElementsByTagName('img');
- for (var i=0; i<imgs.length; i++) {
- imgs[i].src = (new dojo.uri.Uri(window.location, imgs[i].src)).toString();
+ for(var i=0; i<imgs.length; i++){
+ imgs[i].src = (new dojo.uri.Uri(dojo.global().location, imgs[i].src)).toString();
}
html = tmpContent.innerHTML;
}
// fix margins on tmpContent
- var firstChild = dojo.dom.firstElement(tmpContent);
- var lastChild = dojo.dom.lastElement(tmpContent);
+ var firstChild = dojo.html.firstElement(tmpContent);
+ var lastChild = dojo.html.lastElement(tmpContent);
if(firstChild){
firstChild.style.marginTop = this._firstChildContributingMargin+"px";
}
@@ -403,8 +501,11 @@
// show existing content behind iframe for now
tmpContent.style.position = "absolute";
- this.domNode.appendChild(tmpContent);
- this.domNode.appendChild(this.iframe);
+ this.editingArea.appendChild(tmpContent);
+ this.editingArea.appendChild(this.iframe);
+ if(dojo.render.html.safari){
+ this.iframe.src = this.iframe.src;
+ }
var _iframeInitialized = false;
@@ -416,41 +517,38 @@
if(!this.editNode){
if(this.iframe.contentWindow){
this.window = this.iframe.contentWindow;
- }else{
+ this.document = this.iframe.contentWindow.document
+ }else if(this.iframe.contentDocument){
// for opera
this.window = this.iframe.contentDocument.window;
- }
- if(dojo.render.html.moz){
- this.document = this.iframe.contentWindow.document
- }else{
this.document = this.iframe.contentDocument;
}
// curry the getStyle function
var getStyle = (function (domNode) { return function (style) {
- return dojo.style.getStyle(domNode, style);
+ return dojo.html.getStyle(domNode, style);
}; })(this.domNode);
var font =
getStyle('font-weight') + " " +
getStyle('font-size') + " " +
getStyle('font-family');
-
+
// line height is tricky - applying a units value will mess things up.
// if we can't get a non-units value, bail out.
var lineHeight = "1.0";
- var lineHeightStyle = dojo.style.getUnitValue(this.domNode, 'line-height');
+ var lineHeightStyle = dojo.html.getUnitValue(this.domNode, 'line-height');
if (lineHeightStyle.value && lineHeightStyle.units=="") {
lineHeight = lineHeightStyle.value;
}
- dojo.style.insertCssText(
+ dojo.html.insertCssText(
' body,html { background: transparent; padding: 0; margin: 0; }\n' +
// TODO: left positioning will case contents to disappear out of view
// if it gets too wide for the visible area
' body { top: 0; left: 0; right: 0;' +
- (this.height ? '' : ' position: fixed; ') +
- ' font: ' + font + ';\n' +
+ (((this.height)||(dojo.render.html.opera)) ? '' : ' position: fixed; ') +
+ ' font: ' + font + ';\n' +
' min-height: ' + this.minHeight + '; \n' +
' line-height: ' + lineHeight + '} \n' +
' p { margin: 1em 0 !important; }\n' +
@@ -458,12 +556,12 @@
' body > *:last-child { padding-bottom: 0 !important; margin-bottom: ' + this._lastChildContributingMargin + 'px !important; }\n' +
' li > ul:-moz-first-node, li > ol:-moz-first-node { padding-top: 1.2em; }\n' +
' li { min-height: 1.2em; }\n' +
- //' p,ul,li { padding-top: 0; padding-bottom: 0; margin-top:0; margin-bottom: 0; }\n' +
+ //' p,ul,li { padding-top: 0; padding-bottom: 0; margin-top:0; margin-bottom: 0; }\n' +
'', this.document);
tmpContent.parentNode.removeChild(tmpContent);
this.document.body.innerHTML = html;
- if(oldMoz){
+ if(oldMoz||dojo.render.html.safari){
this.document.designMode = "on";
}
this.onLoad();
@@ -486,10 +584,86 @@
this.iframe.onload = ifrFunc;
}
},
-
- /** Draws an active x object, used by IE */
- _drawObject: function (html) {
- this.object = document.createElement("object");
+
+ _applyEditingAreaStyleSheets: function(){
+ // summary:
+ // apply the specified css files in styleSheets
+ var files = [];
+ if(this.styleSheets){
+ files = this.styleSheets.split(';');
+ }
+
+ //empty this.editingAreaStyleSheets here, as it will be filled in addStyleSheet
+ files = files.concat(this.editingAreaStyleSheets);
+ this.editingAreaStyleSheets = [];
+
+ if(files.length>0){
+ for(var i=0;i<files.length;i++){
+ var url = files[i];
+ if(url){
+ this.addStyleSheet(new dojo.uri.Uri(url));
+ }
+ }
+ }
+ },
+
+ addStyleSheet: function(/*dojo.uri.Uri*/uri) {
+ // summary:
+ // add an external stylesheet for the editing area
+ // uri: a dojo.uri.Uri pointing to the url of the external css file
+ var url=uri.toString();
+ if(dojo.lang.find(this.editingAreaStyleSheets, url) > -1){
+ dojo.debug("dojo.widget.RichText.addStyleSheet: Style sheet "+url+" is already applied to the editing area!");
+ return;
+ }
+
+ //if uri is relative, then convert it to absolute so that it can be resolved correctly in iframe
+ if(url.charAt(0) == '.' || (url.charAt(0) != '/' && !uri.host)){
+ url = (new dojo.uri.Uri(dojo.global().location, url)).toString();
+ }
+
+ this.editingAreaStyleSheets.push(url);
+ if(this.document.createStyleSheet){ //IE
+ this.document.createStyleSheet(url);
+ }else{ //other browser
+ var head = this.document.getElementsByTagName("head")[0];
+ var stylesheet = this.document.createElement("link");
+ with(stylesheet){
+ rel="stylesheet";
+ type="text/css";
+ href=url;
+ }
+ head.appendChild(stylesheet);
+ }
+ },
+
+ removeStyleSheet: function (/*dojo.uri.Uri*/uri) {
+ // summary:
+ // remove an external stylesheet for the editing area
+ var url=uri.toString();
+ var index = dojo.lang.find(this.editingAreaStyleSheets, url);
+ if(index == -1){
+ dojo.debug("dojo.widget.RichText.removeStyleSheet: Style sheet "+url+" is not applied to the editing area so it can not be removed!");
+ return;
+ }
+ delete this.editingAreaStyleSheets[index];
+
+ var links = this.document.getElementsByTagName("link");
+ for(var i=0;i<links.length;i++){
+ if(links[i].href == url){
+ if(dojo.render.html.ie){//we need to empty the href first, to get IE to remove the rendered styles
+ links[i].href="";
+ }
+ dojo.html.removeNode(links[i]);
+ break;
+ }
+ }
+ },
+
+ _drawObject: function (/*String*/html) {
+ // summary:
+ // Draws an active x object, used by IE
+ this.object = dojo.html.createExternalElement(dojo.doc(), "object");
with (this.object) {
classid = "clsid:2D360201-FFF5-11D1-8D03-00A0C959BC0A";
@@ -498,50 +672,99 @@
Scrollbars = this.height ? true : false;
Appearance = this._activeX.appearance.flat;
}
- this.domNode.appendChild(this.object);
+ this.editorObject = this.object;
+ this.editingArea.appendChild(this.object);
this.object.attachEvent("DocumentComplete", dojo.lang.hitch(this, "onLoad"));
- this.object.attachEvent("DisplayChanged", dojo.lang.hitch(this, "_updateHeight"));
- this.object.attachEvent("DisplayChanged", dojo.lang.hitch(this, "onDisplayChanged"));
+ //DisplayChanged is fired too often even no change is made, so we ignore it
+ //and call onDisplayChanged manually in execCommand instead
+// this.object.attachEvent("DisplayChanged", dojo.lang.hitch(this, "onDisplayChanged"));
dojo.lang.forEach(this.events, function(e){
this.object.attachEvent(e.toLowerCase(), dojo.lang.hitch(this, e));
}, this);
this.object.DocumentHTML = '<!doctype HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">' +
- '<title></title>' +
+ '<html><title></title>' +
'<style type="text/css">' +
' body,html { padding: 0; margin: 0; }' + //font: ' + font + '; }' +
- (this.height ? '' : ' body { overflow: hidden; }') +
- //' #bodywrapper { }' +
+ (this.height ? '' : ' body, { overflow: hidden; }') +
'</style>' +
- //'<base href="' + window.location + '">' +
- '<body><div id="bodywrapper">' + html + '</div></body>';
+ //'<base href="' + dojo.global().location + '">' +
+ '<body><div>' + html + '<div></body></html>';
+
+ this._cacheLocalBlockFormatNames();
},
+ //static cache variables shared among all instance of this class
+ _local2NativeFormatNames: {},
+ _native2LocalFormatNames: {},
+ //in IE, names for blockformat is locale dependent, so we cache the values here
+ //we use activeX to obtain the list, if success or the names are already cached,
+ //return true
+ _cacheLocalBlockFormatNames: function(){
+ // summary:
+ // in IE, names for blockformat is locale dependent, so we cache the values here
+ // we use activeX to obtain the list, if success or the names are already cached,
+ // return true
+ if(!this._native2LocalFormatNames['p']){
+ var obj = this.object;
+ if(!obj){
+ //create obj temporarily
+ try{
+ obj = dojo.html.createExternalElement(dojo.doc(), "object");
+ obj.classid = "clsid:2D360201-FFF5-11D1-8D03-00A0C959BC0A";
+ dojo.body().appendChild(obj);
+ obj.DocumentHTML = "<html><head></head><body></body></html>";
+ }catch(e){
+ return false;
+ }
+ }
+ var oNamesParm = new ActiveXObject("DEGetBlockFmtNamesParam.DEGetBlockFmtNamesParam");
+ obj.ExecCommand(this._activeX.command['getblockformatnames'], 0, oNamesParm);
+ var vbNamesArray = new VBArray(oNamesParm.Names);
+ var localFormats = vbNamesArray.toArray();
+ var nativeFormats = ['p', 'pre', 'address', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ol', 'ul', '', '', '','','div'];
+ for(var i=0;i<nativeFormats.length;++i){
+ if(nativeFormats[i].length>0){
+ this._local2NativeFormatNames[localFormats[i]] = nativeFormats[i];
+ this._native2LocalFormatNames[nativeFormats[i]] = localFormats[i];
+ }
+ }
+ if(!this.object){
+ //delete the temporary obj
+ dojo.body().removeChild(obj);
+ }
+ }
+ return true;
+ },
/* Event handlers
*****************/
- _isResized: function(){ return false; },
+ _isResized: function(){ return false; },
onLoad: function(e){
+ // summary: handler after the content of the document finishes loading
this.isLoaded = true;
if (this.object){
this.document = this.object.DOM;
this.window = this.document.parentWindow;
this.editNode = this.document.body.firstChild;
- this.domNode.style.height = this.height ? this.height : this.minHeight;
+ this.editingArea.style.height = this.height ? this.height : this.minHeight;
this.connect(this, "onDisplayChanged", "_updateHeight");
- }else if (this.iframe){
+ //pretend the object as an iframe, so that the context menu for the
+ //editor can be placed correctly when shown
+ this.window._frameElement = this.object;
+ }else if (this.iframe && !dojo.render.html.ie){
this.editNode = this.document.body;
this.connect(this, "onDisplayChanged", "_updateHeight");
-
+
try { // sanity check for Mozilla
this.document.execCommand("useCSS", false, true); // old moz call
this.document.execCommand("styleWithCSS", false, false); // new moz call
//this.document.execCommand("insertBrOnReturn", false, false); // new moz call
}catch(e2){ }
-
+
if (dojo.render.html.safari) {
/*
this.iframe.style.visiblity = "visible";
@@ -552,49 +775,49 @@
// this.onDisplayChanged();
this.connect(this.editNode, "onblur", "onBlur");
this.connect(this.editNode, "onfocus", "onFocus");
-
+ this.connect(this.editNode, "onclick", "onFocus");
+
this.interval = setInterval(dojo.lang.hitch(this, "onDisplayChanged"), 750);
// dojo.raise("onload");
// dojo.debug(this.editNode.parentNode.parentNode.parentNode.nodeName);
} else if (dojo.render.html.mozilla || dojo.render.html.opera) {
-
- // We need to unhook the blur event listener on close as we
- // can encounter a garunteed crash in FF if another event is
- // also fired
var doc = this.document;
- var blurfp = dojo.event.browser.addListener(this.document, "blur", dojo.lang.hitch(this, "onBlur"));
- var unBlur = { unBlur: function(e){
- dojo.event.browser.removeListener(doc, "blur", blurfp);
- } };
- dojo.event.connect("before", this, "close", unBlur, "unBlur");
- dojo.event.browser.addListener(this.document, "focus", dojo.lang.hitch(this, "onFocus"));
-
- // safari can't handle key listeners, it kills the speed
var addListener = dojo.event.browser.addListener;
- addListener(this.document, "keypress", dojo.lang.hitch(this, "onKeyPress"));
- addListener(this.document, "keydown", dojo.lang.hitch(this, "onKeyDown"));
- addListener(this.document, "keyup", dojo.lang.hitch(this, "onKeyUp"));
- addListener(this.document, "click", dojo.lang.hitch(this, "onClick"));
+ var self = this;
+ dojo.lang.forEach(this.events, function(e){
+ var l = addListener(self.document, e.substr(2).toLowerCase(), dojo.lang.hitch(self, e));
+ if(e=="onBlur"){
+ // We need to unhook the blur event listener on close as we
+ // can encounter a garunteed crash in FF if another event is
+ // also fired
+ var unBlur = { unBlur: function(e){
+ dojo.event.browser.removeListener(doc, "blur", l);
+ } };
+ dojo.event.connect("before", self, "close", unBlur, "unBlur");
+ }
+ });
}
-
- // FIXME: when scrollbars appear/disappear this needs to be fired
+ // FIXME: when scrollbars appear/disappear this needs to be fired
}else if(dojo.render.html.ie){
// IE contentEditable
+ this.connect(this, "onDisplayChanged", "_updateHeight");
this.editNode.style.zoom = 1.0;
}
-
+
+ this._applyEditingAreaStyleSheets();
+
if(this.focusOnLoad){
this.focus();
}
this.onDisplayChanged(e);
},
- /** Fired on keydown */
onKeyDown: function(e){
+ // summary: Fired on keydown
if((!e)&&(this.object)){
e = dojo.event.browser.fixEvent(this.window.event);
}
- dojo.debug("onkeydown:", e.keyCode);
+ // dojo.debug("onkeydown:", e.keyCode);
// we need this event at the moment to get the events from control keys
// such as the backspace. It might be possible to add this to Dojo, so that
// keyPress events can be emulated by the keyDown and keyUp detection.
@@ -603,7 +826,7 @@
e.stopPropagation();
// FIXME: this is a poor-man's indent/outdent. It would be
// better if it added 4 " " chars in an undoable way.
- // Unfortuantly pasteHTML does not prove to be undoable
+ // Unfortuantly pasteHTML does not prove to be undoable
this.execCommand((e.shiftKey ? "outdent" : "indent"));
}else if(dojo.render.html.ie){
if((65 <= e.keyCode)&&(e.keyCode <= 90)){
@@ -616,29 +839,26 @@
// this.onKeyPress(e);
}
},
-
- /** Fired on keyup */
+
onKeyUp: function(e){
+ // summary: Fired on keyup
return;
},
-
+
KEY_CTRL: 1,
-
- /** Fired on keypress. */
+
onKeyPress: function(e){
+ // summary: Fired on keypress
if((!e)&&(this.object)){
e = dojo.event.browser.fixEvent(this.window.event);
}
// handle the various key events
- var character = e.charCode > 0 ? String.fromCharCode(e.charCode) : null;
- var code = e.keyCode;
-
var modifiers = e.ctrlKey ? this.KEY_CTRL : 0;
- if (this._keyHandlers[character]) {
- dojo.debug("char:", character);
- var handlers = this._keyHandlers[character], i = 0, handler;
+ if (this._keyHandlers[e.key]) {
+ // dojo.debug("char:", e.key);
+ var handlers = this._keyHandlers[e.key], i = 0, handler;
while (handler = handlers[i++]) {
if (modifiers == handler.modifiers) {
handler.handler.call(this);
@@ -647,70 +867,25 @@
}
}
}
-
- /*
- // define some key combos
- if (e.ctrlKey || e.metaKey) { // modifier pressed
- switch (character) {
- case "b": this.execCommand("bold"); break;
- case "i": this.execCommand("italic"); break;
- case "u": this.execCommand("underline"); break;
- //case "a": this.execCommand("selectall"); break;
- //case "k": this.execCommand("createlink", ""); break;
- //case "K": this.execCommand("unlink"); break;
- case "Z": this.execCommand("redo"); break;
- case "s": this.close(true); break; // saves
-
- case "1": this.execCommand("formatblock", "h1"); break;
- case "2": this.execCommand("formatblock", "h2"); break;
- case "3": this.execCommand("formatblock", "h3"); break;
- case "4": this.execCommand("formatblock", "h4"); break;
-
- case "\\": this.execCommand("insertunorderedlist"); break;
-
- default: switch (code) {
- case e.KEY_LEFT_ARROW:
- case e.KEY_RIGHT_ARROW:
- //break; // preventDefault stops the browser
- // going through its history
- default:
- preventDefault = false; break; // didn't handle here
- }
- }
- } else {
- switch (code) {
- case e.KEY_TAB:
- // commenting out bcs it's crashing FF
- // this.execCommand(e.shiftKey ? "unindent" : "indent");
- // break;
- default:
- preventDefault = false; break; // didn't handle here
- }
- }
-
- if (preventDefault) { e.preventDefault(); }
- */
// function call after the character has been inserted
dojo.lang.setTimeout(this, this.onKeyPressed, 1, e);
},
-
- addKeyHandler: function (key, modifiers, handler) {
+
+ addKeyHandler: function (/*String*/key, /*Int*/modifiers, /*Function*/handler) {
+ // summary: add a handler for a keyboard shortcut
if (!(this._keyHandlers[key] instanceof Array)) { this._keyHandlers[key] = []; }
this._keyHandlers[key].push({
modifiers: modifiers || 0,
handler: handler
});
},
-
-
-
- /**
- * Fired after a keypress event has occured and it's action taken. This
- * is useful if action needs to be taken after text operations have
- * finished
- */
+
onKeyPressed: function (e) {
+ // summary:
+ // Fired after a keypress event has occured and it's action taken. This
+ // is useful if action needs to be taken after text operations have finished
+
// Mozilla adds a single <p> with an embedded <br> when you hit enter once:
// <p><br>\n</p>
// when you hit enter again it adds another <br> inside your enter
@@ -721,7 +896,7 @@
// and so we need to remove the <p>s to ensure the position of the cursor
// changes from the users perspective when they hit enter, as the second two
// html snippets render the same when margins are set to 0.
-
+
// TODO: doesn't really work; is this really needed?
//if (dojo.render.html.moz) {
// for (var i = 0; i < this.document.getElementsByTagName("p").length; i++) {
@@ -734,42 +909,49 @@
//}
this.onDisplayChanged(/*e*/); // can't pass in e
},
-
+
onClick: function(e){ this.onDisplayChanged(e); },
onBlur: function(e){ },
_initialFocus: true,
- onFocus: function(e){
+ onFocus: function(e){
+ // summary: Fired on focus
if( (dojo.render.html.mozilla)&&(this._initialFocus) ){
this._initialFocus = false;
if(dojo.string.trim(this.editNode.innerHTML) == " "){
- this.execCommand("selectall");
- this.window.getSelection().collapseToStart();
+ this.placeCursorAtStart();
+// this.execCommand("selectall");
+// this.window.getSelection().collapseToStart();
}
}
},
blur: function () {
- if (this.iframe) { this.window.blur(); }
- else if (this.editNode) { this.editNode.blur(); }
+ // summary: remove focus from this instance
+ if(this.iframe) { this.window.blur(); }
+ else if(this.object) { this.document.body.blur(); }
+ else if(this.editNode) { this.editNode.blur(); }
},
-
+
focus: function () {
- if(this.iframe){
- this.window.focus();
- }else if(this.editNode){
- this.editNode.focus();
+ // summary: move focus to this instance
+ if(this.iframe && !dojo.render.html.ie) { this.window.focus(); }
+ else if(this.object) { this.document.focus(); }
+ // editNode may be hidden in display:none div, lets just punt in this case
+ else if(this.editNode && this.editNode.focus) { this.editNode.focus(); }
+ else{
+ dojo.debug("Have no idea how to focus into the editor!");
}
},
-
+
/** this event will be fired everytime the display context changes and the
result needs to be reflected in the UI */
onDisplayChanged: function (e){ },
-
+
/* Formatting commands
**********************/
-
- /** IE's Active X codes */
+
+ // Object: IE's Active X codes: see http://www.computerbytesman.com/js/activex/dhtmledit.htm
_activeX: {
command: {
bold: 5000,
@@ -808,7 +990,7 @@
deleterows: 5007,
mergecells: 5029,
splitcell: 5047,
-
+
// the command need mapping, they don't translate directly
// to the contentEditable commands
setblockformat: 5043,
@@ -822,12 +1004,12 @@
getbackcolor: 5010,
setforecolor: 5046,
getforecolor: 5015,
-
+
findtext: 5008,
font: 5009,
hyperlink: 5016,
image: 5017,
-
+
lockelement: 5027,
makeabsolute: 5028,
sendbackward: 5036,
@@ -836,16 +1018,16 @@
bringabovetext: 5039,
sendtoback: 5040,
bringtofront: 5041,
-
+
properties: 5052
},
-
+
ui: {
"default": 0,
prompt: 1,
noprompt: 2
},
-
+
status: {
notsupported: 0,
disabled: 1,
@@ -853,180 +1035,203 @@
latched: 7,
ninched: 11
},
-
+
appearance: {
flat: 0,
inset: 1
},
-
+
state: {
unchecked: 0,
checked: 1,
gray: 2
}
},
-
- /**
- * Used as the advice function by dojo.event.connect to map our
- * normalized set of commands to those supported by the target
- * browser
- *
- * @param arugments The arguments Array, containing at least one
- * item, the command and an optional second item,
- * an argument.
- */
- _normalizeCommand: function (joinObject){
+
+ _normalizeCommand: function (/*String*/cmd){
+ // summary:
+ // Used as the advice function by dojo.event.connect to map our
+ // normalized set of commands to those supported by the target
+ // browser
var drh = dojo.render.html;
-
- var command = joinObject.args[0].toLowerCase();
+
+ var command = cmd.toLowerCase();
if(command == "formatblock"){
if(drh.safari){ command = "heading"; }
- if(drh.ie){ joinObject.args[1] = "<"+joinObject.args[1]+">"; }
- }
- if (command == "hilitecolor" && !drh.mozilla) { command = "backcolor"; }
- joinObject.args[0] = command;
-
- if (joinObject.args.length > 1) { // a command was specified
- var argument = joinObject.args[1];
- if (command == "heading") { throw new Error("unimplemented"); }
- joinObject.args[1] = argument;
+ }else if(this.object){
+ switch(command){
+ case "createlink":
+ command = "hyperlink";
+ break;
+ case "insertimage":
+ command = "image";
+ break;
+ }
+ }else if(command == "hilitecolor" && !drh.mozilla){
+ command = "backcolor";
}
-
- return joinObject.proceed();
+
+ return command;
},
-
- /**
- * Tests whether a command is supported by the host. Clients SHOULD check
- * whether a command is supported before attempting to use it, behaviour
- * for unsupported commands is undefined.
- *
- * @param command The command to test for
- * @return true if the command is supported, false otherwise
- */
- queryCommandAvailable: function (command) {
+
+ queryCommandAvailable: function (/*String*/command) {
+ // summary:
+ // Tests whether a command is supported by the host. Clients SHOULD check
+ // whether a command is supported before attempting to use it, behaviour
+ // for unsupported commands is undefined.
+ // command: The command to test for
var ie = 1;
var mozilla = 1 << 1;
var safari = 1 << 2;
var opera = 1 << 3;
+ var safari420 = 1 << 4;
+
+ var gt420 = false;
+ if(dojo.render.html.safari){
+ var tmp = dojo.render.html.UA.split("AppleWebKit/")[1];
+ var ver = parseFloat(tmp.split(" ")[0]);
+ if(ver >= 420){ gt420 = true; }
+ }
+
function isSupportedBy (browsers) {
return {
ie: Boolean(browsers & ie),
mozilla: Boolean(browsers & mozilla),
safari: Boolean(browsers & safari),
+ safari420: Boolean(browsers & safari420),
opera: Boolean(browsers & opera)
}
}
var supportedBy = null;
-
+
switch (command.toLowerCase()) {
case "bold": case "italic": case "underline":
case "subscript": case "superscript":
case "fontname": case "fontsize":
case "forecolor": case "hilitecolor":
- case "justifycenter": case "justifyfull": case "justifyleft":
- case "justifyright": case "delete": case "undo": case "redo":
+ case "justifycenter": case "justifyfull": case "justifyleft":
+ case "justifyright": case "delete": case "selectall":
supportedBy = isSupportedBy(mozilla | ie | safari | opera);
break;
-
+
case "createlink": case "unlink": case "removeformat":
case "inserthorizontalrule": case "insertimage":
case "insertorderedlist": case "insertunorderedlist":
- case "indent": case "outdent": case "formatblock":
- case "inserthtml":
- supportedBy = isSupportedBy(mozilla | ie | opera);
- break;
-
- case "strikethrough":
- supportedBy = isSupportedBy(mozilla | opera | (this.object ? 0 : ie));
+ case "indent": case "outdent": case "formatblock":
+ case "inserthtml": case "undo": case "redo": case "strikethrough":
+ supportedBy = isSupportedBy(mozilla | ie | opera | safari420);
break;
case "blockdirltr": case "blockdirrtl":
case "dirltr": case "dirrtl":
case "inlinedirltr": case "inlinedirrtl":
- case "cut": case "copy": case "paste":
supportedBy = isSupportedBy(ie);
break;
-
+ case "cut": case "copy": case "paste":
+ supportedBy = isSupportedBy( ie | mozilla | safari420);
+ break;
+
case "inserttable":
supportedBy = isSupportedBy(mozilla | (this.object ? ie : 0));
break;
-
+
case "insertcell": case "insertcol": case "insertrow":
case "deletecells": case "deletecols": case "deleterows":
case "mergecells": case "splitcell":
supportedBy = isSupportedBy(this.object ? ie : 0);
break;
-
+
default: return false;
}
-
+
return (dojo.render.html.ie && supportedBy.ie) ||
(dojo.render.html.mozilla && supportedBy.mozilla) ||
(dojo.render.html.safari && supportedBy.safari) ||
- (dojo.render.html.opera && supportedBy.opera);
+ (gt420 && supportedBy.safari420) ||
+ (dojo.render.html.opera && supportedBy.opera); // Boolean: return true if the command is supported, false otherwise
},
- /**
- * Executes a command in the Rich Text area
- *
- * @param command The command to execute
- * @param argument An optional argument to the command
- */
- execCommand: function (command, argument){
+ execCommand: function (/*String*/command, argument){
+ // summary: Executes a command in the Rich Text area
+ // command: The command to execute
+ // argument: An optional argument to the command
var returnValue;
+
+ //focus() is required for IE (none-activeX mode) to work
+ //In addition, focus() makes sure after the execution of
+ //the command, the editor receives the focus as expected
+ this.focus();
+
+ command = this._normalizeCommand(command);
+ if (argument != undefined) {
+ if(command == "heading") { throw new Error("unimplemented"); }
+ else if(command == "formatblock"){
+ if(this.object){ //IE activeX mode
+ argument = this._native2LocalFormatNames[argument];
+ }
+ else if(drh.ie){ argument = '<'+argument+'>'; }
+ }
+ }
if(this.object){
- if(command == "forecolor"){
- command = "setforecolor";
- }else if(command == "backcolor"){
- command = "setbackcolor";
+ switch (command) {
+ case "hilitecolor":
+ command = "setbackcolor";
+ break;
+ case "forecolor":
+ case "backcolor":
+ case "fontsize":
+ case "fontname":
+ command = "set" + command;
+ break;
+ case "formatblock":
+ command = "setblockformat";
}
-
- //if (typeof this._activeX.command[command] == "undefined") { return null; }
-
- if(command == "inserttable"){
- var tableInfo = this.constructor._tableInfo;
- if(!tableInfo){
- tableInfo = document.createElement("object");
- tableInfo.classid = "clsid:47B0DFC7-B7A3-11D1-ADC5-006008A5848C";
- document.body.appendChild(tableInfo);
- this.constructor._table = tableInfo;
+
+ if(command == "strikethrough"){
+ command = "inserthtml";
+ var range = this.document.selection.createRange();
+ if(!range.htmlText){
+ return;
}
-
- tableInfo.NumRows = argument["rows"];
- tableInfo.NumCols = argument["cols"];
- tableInfo.TableAttrs = argument["TableAttrs"];
- tableInfo.CellAttrs = argument["CellAttrs"];
- tableInfo.Caption = argument["Caption"];
+ argument=range.htmlText.strike();
+ }else if(command == "inserthorizontalrule"){
+ command = "inserthtml";
+ argument="<hr>";
}
-
+
if(command == "inserthtml"){
- var insertRange = this.document.selection.createRange();
- insertRange.select();
- insertRange.pasteHTML(argument);
- insertRange.collapse(true);
- return true;
+ var range = this.document.selection.createRange();
+ if(this.document.selection.type.toUpperCase() == "CONTROL"){
+ //if selection is controlrange, no pasteHTML is available,
+ //we replace the outerHTML directly
+ for(var i=0;i<range.length;i++){
+ range.item(i).outerHTML = argument;
+ }
+ }else{
+ // on IE, we can use the pasteHTML method of the textRange object
+ // to get an undo-able innerHTML modification
+ range.pasteHTML(argument);
+ range.select();
+ }
+ returnValue = true;
}else if(arguments.length == 1){
- return this.object.ExecCommand(this._activeX.command[command],
+ returnValue = this.object.ExecCommand(this._activeX.command[command],
this._activeX.ui.noprompt);
}else{
- return this.object.ExecCommand(this._activeX.command[command],
+ returnValue = this.object.ExecCommand(this._activeX.command[command],
this._activeX.ui.noprompt, argument);
}
-
- /* */
}else if(command == "inserthtml"){
- // on IE, we can use the pasteHTML method of the textRange object
- // to get an undo-able innerHTML modification
if(dojo.render.html.ie){
- dojo.debug("inserthtml breaks the undo stack when not using the ActiveX version of the control!");
+ //dojo.debug("inserthtml breaks the undo stack when not using the ActiveX version of the control!");
var insertRange = this.document.selection.createRange();
- insertRange.select();
insertRange.pasteHTML(argument);
- insertRange.collapse(true);
+ insertRange.select();
+ //insertRange.collapse(true);
return true;
}else{
- return this.document.execCommand(command, false, argument);
+ return this.document.execCommand(command, false, argument);
}
/* */
// fix up unlink in Mozilla to unlink the link and not just the selection
@@ -1042,92 +1247,93 @@
var selectionStartOffset = selectionRange.startOffset;
var selectionEndContainer = selectionRange.endContainer;
var selectionEndOffset = selectionRange.endOffset;
-
+
// select our link and unlink
- var range = document.createRange();
- var a = this.getSelectedNode();
- while(a.nodeName != "A"){ a = a.parentNode; }
- range.selectNode(a);
- selection.removeAllRanges();
- selection.addRange(range);
-
+ var a = dojo.withGlobal(this.window, "getAncestorElement", dojo.html.selection, ['a']);
+ dojo.withGlobal(this.window, "selectElement", dojo.html.selection, [a]);
+
returnValue = this.document.execCommand("unlink", false, null);
-
+
// restore original selection
- var selectionRange = document.createRange();
+ var selectionRange = this.document.createRange();
selectionRange.setStart(selectionStartContainer, selectionStartOffset);
selectionRange.setEnd(selectionEndContainer, selectionEndOffset);
selection.removeAllRanges();
selection.addRange(selectionRange);
-
- return returnValue;
- }else if((command == "inserttable")&&(dojo.render.html.mozilla)){
-
- var cols = "<tr>";
- for (var i = 0; i < argument.cols; i++) { cols += "<td></td>"; }
- cols += "</tr>";
-
- var table = "<table><tbody>";
- for (var i = 0; i < argument.rows; i++) { table += cols; }
- table += "</tbody></table>";
- returnValue = this.document.execCommand("inserthtml", false, table);
+ return returnValue;
}else if((command == "hilitecolor")&&(dojo.render.html.mozilla)){
// mozilla doesn't support hilitecolor properly when useCSS is
// set to false (bugzilla #279330)
-
+
this.document.execCommand("useCSS", false, false);
- returnValue = this.document.execCommand(command, false, argument);
+ returnValue = this.document.execCommand(command, false, argument);
this.document.execCommand("useCSS", false, true);
-
+
}else if((dojo.render.html.ie)&&( (command == "backcolor")||(command == "forecolor") )){
- // IE weirdly collapses ranges when we exec these commands, so prevent it
- var tr = this.document.selection.createRange();
+ // Tested under IE 6 XP2, no problem here, comment out
+ // IE weirdly collapses ranges when we exec these commands, so prevent it
+// var tr = this.document.selection.createRange();
argument = arguments.length > 1 ? argument : null;
returnValue = this.document.execCommand(command, false, argument);
+
// timeout is workaround for weird IE behavior were the text
// selection gets correctly re-created, but subsequent input
// apparently isn't bound to it
- setTimeout(function(){tr.select();}, 1);
+// setTimeout(function(){tr.select();}, 1);
}else{
// dojo.debug("command:", command, "arg:", argument);
argument = arguments.length > 1 ? argument : null;
- if(dojo.render.html.moz){
- this.document = this.iframe.contentWindow.document
- }
- returnValue = this.document.execCommand(command, false, argument);
+// if(dojo.render.html.moz){
+// this.document = this.iframe.contentWindow.document
+// }
- // try{
- // }catch(e){
- // dojo.debug(e);
- // }
+ if(argument || command!="createlink") {
+ returnValue = this.document.execCommand(command, false, argument);
+ }
}
-
+
this.onDisplayChanged();
return returnValue;
},
- queryCommandEnabled: function(command, argument){
+ queryCommandEnabled: function(/*String*/command){
+ // summary: check whether a command is enabled or not
+ command = this._normalizeCommand(command);
if(this.object){
- if(command == "forecolor"){
- command = "setforecolor";
- }else if(command == "backcolor"){
- command = "setbackcolor";
+ switch (command) {
+ case "hilitecolor":
+ command = "setbackcolor";
+ break;
+ case "forecolor":
+ case "backcolor":
+ case "fontsize":
+ case "fontname":
+ command = "set" + command;
+ break;
+ case "formatblock":
+ command = "setblockformat";
+ break;
+ //below are not natively supported commands, we fake them
+ case "strikethrough":
+ command = "bold"; //whenever bold is enabled, strikethrough should be so as well
+ break;
+ case "inserthorizontalrule":
+ return true;
}
if(typeof this._activeX.command[command] == "undefined"){ return false; }
var status = this.object.QueryStatus(this._activeX.command[command]);
- return ((status != this.activeX.status.notsupported)&&
- (status != this.activeX.status.diabled));
+ return ((status != this._activeX.status.notsupported)&&
+ (status != this._activeX.status.disabled));
}else{
- // mozilla returns true always
- if(command == "unlink" && dojo.render.html.mozilla){
- var node = this.getSelectedNode();
- while (node.parentNode && node.nodeName != "A") { node = node.parentNode; }
- return node.nodeName == "A";
- } else if (command == "inserttable" && dojo.render.html.mozilla) {
- return true;
+ if(dojo.render.html.mozilla){
+ if(command == "unlink"){ // mozilla returns true always
+ return dojo.withGlobal(this.window, "hasAncestorElement", dojo.html.selection, ['a']);
+ } else if (command == "inserttable") {
+ return true;
+ }
}
// return this.document.queryCommandEnabled(command);
@@ -1136,194 +1342,200 @@
}
},
- queryCommandState: function(command, argument){
+ queryCommandState: function(command){
+ // summary: check the state of a given command
+ command = this._normalizeCommand(command);
if(this.object){
if(command == "forecolor"){
command = "setforecolor";
}else if(command == "backcolor"){
command = "setbackcolor";
+ }else if(command == "strikethrough"){
+ //check whether we are under a <strike>
+ return dojo.withGlobal(this.window, "hasAncestorElement", dojo.html.selection, ['strike']);
+ }else if(command == "inserthorizontalrule"){
+ return false;
}
if(typeof this._activeX.command[command] == "undefined"){ return null; }
var status = this.object.QueryStatus(this._activeX.command[command]);
- return ((status == this._activeX.status.enabled)||
+ return ((status == this._activeX.status.latched)||
(status == this._activeX.status.ninched));
}else{
return this.document.queryCommandState(command);
}
},
- queryCommandValue: function (command, argument) {
+ queryCommandValue: function (command) {
+ // summary: check the value of a given command
+ command = this._normalizeCommand(command);
if (this.object) {
switch (command) {
case "forecolor":
case "backcolor":
case "fontsize":
case "fontname":
- case "blockformat":
command = "get" + command;
return this.object.execCommand(
this._activeX.command[command],
this._activeX.ui.noprompt);
- }
-
- //var status = this.object.QueryStatus(this._activeX.command[command]);
+ case "formatblock":
+ var retvalue = this.object.execCommand(
+ this._activeX.command["getblockformat"],
+ this._activeX.ui.noprompt);
+ if(retvalue){
+ return this._local2NativeFormatNames[retvalue];
+ }
+ }
} else {
+ if(dojo.render.html.ie && command == "formatblock"){
+ return this._local2NativeFormatNames[this.document.queryCommandValue(command)] || this.document.queryCommandValue(command);
+ }
return this.document.queryCommandValue(command);
}
},
-
-
+
+
/* Misc.
********/
- getSelectedNode: function(){
- if(!this.isLoaded){ return; }
- if(this.document.selection){
- return this.document.selection.createRange().parentElement();
- }else if(dojo.render.html.mozilla){
- return this.window.getSelection().getRangeAt(0).commonAncestorContainer;
- }
- return this.editNode;
- },
-
placeCursorAtStart: function(){
- if(!this.isLoaded){
- dojo.event.connect(this, "onLoad", this, "placeCursorAtEnd");
- return;
+ // summary:
+ // place the cursor at the start of the editing area
+ this.focus();
+ //see comments in placeCursorAtEnd
+ if(dojo.render.html.moz && this.editNode.firstChild &&
+ this.editNode.firstChild.nodeType != dojo.dom.TEXT_NODE){
+ dojo.withGlobal(this.window, "selectElementChildren", dojo.html.selection, [this.editNode.firstChild]);
+ }else{
+ dojo.withGlobal(this.window, "selectElementChildren", dojo.html.selection, [this.editNode]);
}
- dojo.event.disconnect(this, "onLoad", this, "placeCursorAtEnd");
- if(this.window.getSelection){
- var selection = this.window.getSelection;
- if(selection.removeAllRanges){ // Mozilla
- var range = this.document.createRange();
- range.selectNode(this.editNode.firstChild);
- range.collapse(true);
- var selection = this.window.getSelection();
- selection.removeAllRanges();
- selection.addRange(range);
- }else{ // Safari
- // not a great deal we can do
- }
- }else if(this.document.selection){ // IE
- var range = this.document.body.createTextRange();
- range.moveToElementText(this.editNode);
- range.collapse(true);
- range.select();
+ dojo.withGlobal(this.window, "collapse", dojo.html.selection, [true]);
+ },
+
+ placeCursorAtEnd: function(){
+ // summary:
+ // place the cursor at the end of the editing area
+ this.focus();
+ //In mozilla, if last child is not a text node, we have to use selectElementChildren on this.editNode.lastChild
+ //otherwise the cursor would be placed at the end of the closing tag of this.editNode.lastChild
+ if(dojo.render.html.moz && this.editNode.lastChild &&
+ this.editNode.lastChild.nodeType != dojo.dom.TEXT_NODE){
+ dojo.withGlobal(this.window, "selectElementChildren", dojo.html.selection, [this.editNode.lastChild]);
+ }else{
+ dojo.withGlobal(this.window, "selectElementChildren", dojo.html.selection, [this.editNode]);
}
+ dojo.withGlobal(this.window, "collapse", dojo.html.selection, [false]);
},
- replaceEditorContent: function(html){
- if(this.window.getSelection){
- var selection = this.window.getSelection;
- // if(selection.removeAllRanges){ // Mozilla
- if(dojo.render.html.moz){ // Mozilla
- var range = this.document.createRange();
- range.selectNodeContents(this.editNode);
- var selection = this.window.getSelection();
- selection.removeAllRanges();
- selection.addRange(range);
- this.execCommand("inserthtml", html);
- }else{ // Safari
- // look ma! it's a totally f'd browser!
- this.editNode.innerHTML = html;
- }
- }else if(this.document.selection){ // IE
- var range = this.document.body.createTextRange();
- range.moveToElementText(this.editNode);
- range.select();
+ replaceEditorContent: function(/*String*/html){
+ // summary:
+ // this function set the content while trying to maintain the undo stack
+ html = this._preFilterContent(html);
+ if(this.isClosed){
+ this.domNode.innerHTML = html;
+ }else if(this.window && this.window.getSelection && !dojo.render.html.moz){ // Safari
+ // look ma! it's a totally f'd browser!
+ this.editNode.innerHTML = html;
+ }else if((this.window && this.window.getSelection) || (this.document && this.document.selection)){ // Moz/IE
+ this.execCommand("selectall");
this.execCommand("inserthtml", html);
}
},
-
- placeCursorAtEnd: function(){
- if(!this.isLoaded){
- dojo.event.connect(this, "onLoad", this, "placeCursorAtEnd");
- return;
+
+ _preFilterContent: function(/*String*/html){
+ // summary:
+ // filter the input before setting the content of the editing area
+ var ec = html;
+ dojo.lang.forEach(this.contentPreFilters, function(ef){
+ ec = ef(ec);
+ });
+ if(this.contentDomPreFilters.length>0){
+ var dom = dojo.doc().createElement('div');
+ dom.style.display = "none";
+ dojo.body().appendChild(dom);
+ dom.innerHTML = ec;
+ dojo.lang.forEach(this.contentDomPreFilters, function(ef){
+ dom = ef(dom);
+ });
+ ec = dom.innerHTML;
+ dojo.body().removeChild(dom);
}
- dojo.event.disconnect(this, "onLoad", this, "placeCursorAtEnd");
- if(this.window.getSelection){
- var selection = this.window.getSelection;
- if(selection.removeAllRanges){ // Mozilla
- var range = this.document.createRange();
- range.selectNode(this.editNode.lastChild);
- range.collapse(false);
- var selection = this.window.getSelection();
- selection.removeAllRanges();
- selection.addRange(range);
- }else{ // Safari
- // not a great deal we can do
- }
- }else if(this.document.selection){ // IE
- var range = this.document.body.createTextRange();
- range.moveToElementText(this.editNode);
- range.collapse(true);
- range.select();
+ return ec;
+ },
+ _postFilterContent: function(/*String*/html){
+ // summary:
+ // filter the output after getting the content of the editing area
+ var ec = html;
+ if(this.contentDomPostFilters.length>0){
+ var dom = this.document.createElement('div');
+ dom.innerHTML = ec;
+ dojo.lang.forEach(this.contentDomPostFilters, function(ef){
+ dom = ef(dom);
+ });
+ ec = dom.innerHTML;
}
+ dojo.lang.forEach(this.contentPostFilters, function(ef){
+ ec = ef(ec);
+ });
+ return ec;
},
+ //Int: stored last time height
_lastHeight: 0,
- /** Updates the height of the iframe to fit the contents. */
_updateHeight: function(){
+ // summary:
+ // Updates the height of the editor area to fit the contents.
if(!this.isLoaded){ return; }
if(this.height){ return; }
- if(this.iframe){
- /*
- if(!this.document.body["offsetHeight"]){
- return;
- }
- */
- // The height includes the padding, borders and margins so these
- // need to be added on
- var heights = ["margin-top", "margin-bottom",
- "padding-bottom", "padding-top",
- "border-width-bottom", "border-width-top"];
- for(var i = 0, chromeheight = 0; i < heights.length; i++){
- var height = dojo.style.getStyle(this.iframe, heights[i]);
- // Safari doesn't have all the heights so we have to test
- if(height){
- chromeheight += Number(height.replace(/[^0-9]/g, ""));
- }
- }
- if(this.document.body["offsetHeight"]){
- this._lastHeight = Math.max(this.document.body.scrollHeight, this.document.body.offsetHeight) + chromeheight;
- this.iframe.height = this._lastHeight + "px";
- this.window.scrollTo(0, 0);
- }
- // dojo.debug(this.iframe.height);
- }else if(this.object){
- this.object.style.height = dojo.style.getInnerHeight(this.editNode)+"px";
- }
+ var height = dojo.html.getBorderBox(this.editNode).height;
+ //height maybe zero in some cases even though the content is not empty,
+ //we try the height of body instead
+ if(!height){
+ height = dojo.html.getBorderBox(this.document.body).height;
+ }
+ if(height == 0){
+ dojo.debug("Can not figure out the height of the editing area!");
+ return; //prevent setting height to 0
+ }
+ this._lastHeight = height;
+ this.editorObject.style.height = this._lastHeight + "px";
+ this.window.scrollTo(0, 0);
},
-
- /**
- * Saves the content in an onunload event if the editor has not been closed
- */
+
_saveContent: function(e){
- var saveTextarea = document.getElementById("dojo.widget.RichText.savedContent");
+ // summary:
+ // Saves the content in an onunload event if the editor has not been closed
+ var saveTextarea = dojo.doc().getElementById("dojo.widget.RichText.savedContent");
saveTextarea.value += this._SEPARATOR + this.saveName + ":" + this.getEditorContent();
},
getEditorContent: function(){
+ // summary:
+ // return the current content of the editing area (post filters are applied)
var ec = "";
try{
ec = (this._content.length > 0) ? this._content : this.editNode.innerHTML;
if(dojo.string.trim(ec) == " "){ ec = ""; }
}catch(e){ /* squelch */ }
- dojo.lang.forEach(this.contentFilters, function(ef){
- ec = ef(ec);
- });
+ if(dojo.render.html.ie && !this.object){
+ //removing appended <P> </P> for IE in none-activeX mode
+ var re = new RegExp("(?:<p> </p>[\n\r]*)+$", "i");
+ ec = ec.replace(re,"");
+ }
+
+ ec = this._postFilterContent(ec);
if (this.relativeImageUrls) {
- // why use a regexp instead of dom? because IE is stupid
+ // why use a regexp instead of dom? because IE is stupid
// and won't let us set img.src to a relative URL
- // this comes after contentFilters because once content
+ // this comes after contentPostFilters because once content
// gets innerHTML'd img urls will be fully qualified
- var siteBase = window.location.protocol + "//" + window.location.host;
- var pathBase = window.location.pathname;
+ var siteBase = dojo.global().location.protocol + "//" + dojo.global().location.host;
+ var pathBase = dojo.global().location.pathname;
if (pathBase.match(/\/$/)) {
// ends with slash, match full path
} else {
@@ -1335,48 +1547,61 @@
pathBase = pathParts.join("/") + "/";
}
-
+
var sameSite = new RegExp("(<img[^>]*\ src=[\"'])("+siteBase+"("+pathBase+")?)", "ig");
ec = ec.replace(sameSite, "$1");
}
return ec;
},
-
- /**
- * Kills the editor and optionally writes back the modified contents to the
- * element from which it originated.
- *
- * @param save Whether or not to save the changes. If false, the changes are
- * discarded.
- * @return true if the contents has been modified, false otherwise
- */
- close: function(save, force){
+
+ close: function(/*Boolean*/save, /*Boolean*/force){
+ // summery:
+ // Kills the editor and optionally writes back the modified contents to the
+ // element from which it originated.
+ // save:
+ // Whether or not to save the changes. If false, the changes are discarded.
+ // force:
if(this.isClosed){return false; }
if (arguments.length == 0) { save = true; }
- this._content = this.editNode.innerHTML;
+ this._content = this._postFilterContent(this.editNode.innerHTML);
var changed = (this.savedContent.innerHTML != this._content);
-
+
// line height is squashed for iframes
// FIXME: why was this here? if (this.iframe){ this.domNode.style.lineHeight = null; }
if(this.interval){ clearInterval(this.interval); }
-
+
if(dojo.render.html.ie && !this.object){
dojo.event.browser.clean(this.editNode);
}
-
+
if (this.iframe) {
// FIXME: should keep iframe around for later re-use
delete this.iframe;
}
- this.domNode.innerHTML = "";
+
+ if(this.textarea){
+ with(this.textarea.style){
+ position = "";
+ left = top = "";
+ if(dojo.render.html.ie){
+ overflow = this.__overflow;
+ this.__overflow = null;
+ }
+ }
+
+ this.domNode.parentNode.removeChild(this.domNode);
+ this.domNode = this.textarea;
+ }else{
+ this.domNode.innerHTML = "";
+ }
if(save){
// kill listeners on the saved content
dojo.event.browser.clean(this.savedContent);
if(dojo.render.html.moz){
- var nc = document.createElement("span");
+ var nc = dojo.doc().createElement("span");
this.domNode.appendChild(nc);
nc.innerHTML = this.editNode.innerHTML;
}else{
@@ -1388,64 +1613,80 @@
}
}
delete this.savedContent;
-
+
dojo.html.removeClass(this.domNode, "RichTextEditable");
this.isClosed = true;
this.isLoaded = false;
// FIXME: is this always the right thing to do?
delete this.editNode;
- return changed;
+ if(this.window._frameElement){
+ this.window._frameElement = null;
+ }
+
+ this.window = null;
+ this.document = null;
+ this.object = null;
+ this.editingArea = null;
+ this.editorObject = null;
+
+ return changed; // Boolean: whether the content has been modified
},
destroyRendering: function(){}, // stub!
-
+
destroy: function (){
this.destroyRendering();
if(!this.isClosed){ this.close(false); }
-
- // disconnect those listeners.
- while(this._connected.length){
- this.disconnect(this._connected[0],
- this._connected[1], this._connected[2]);
- }
+
+ dojo.widget.RichText.superclass.destroy.call(this);
},
- _connected: [],
connect: function (targetObj, targetFunc, thisFunc) {
+ // summary: convenient method for dojo.event.connect
dojo.event.connect(targetObj, targetFunc, this, thisFunc);
- // this._connected.push([targetObj, targetFunc, thisFunc]);
},
-
- // FIXME: below two functions do not work with the above line commented out
+
disconnect: function (targetObj, targetFunc, thisFunc) {
- for (var i = 0; i < this._connected.length; i++) {
- if (this._connected[0] == targetObj &&
- this._connected[1] == targetFunc &&
- this._connected[2] == thisFunc) {
- dojo.event.disconnect(targetObj, targetFunc, this, thisFunc);
- this._connected.splice(i, 1);
- break;
- }
- }
+ // summary: convenient method for dojo.event.disconnect
+ dojo.event.disconnect(targetObj, targetFunc, this, thisFunc);
},
-
+
disconnectAllWithRoot: function (targetObj) {
- for (var i = 0; i < this._connected.length; i++) {
- if (this._connected[0] == targetObj) {
- dojo.event.disconnect(targetObj,
- this._connected[1], this, this._connected[2]);
- this._connected.splice(i, 1);
- }
- }
+ dojo.deprecated("disconnectAllWithRoot", "is deprecated. No need to disconnect manually", "0.5");
+ },
+
+ _fixContentForMoz: function(html){
+ // summary:
+ // Moz can not handle strong/em tags correctly, correct them here
+ html = html.replace(/<strong([ \>])/gi, '<b$1' );
+ html = html.replace(/<\/strong>/gi, '<\/b>' );
+ html = html.replace(/<em([ \>])/gi, '<i$1' );
+ html = html.replace(/<\/em>/gi, '<\/i>' );
+ return html;
}
-
},
"html",
function(){
- this.contentFilters = [];
- // this.contentFilters.push(this.defaultContentCleaner);
-
+ // summary:
+ // Constructor for this widget, initialize per-instance variables
+
+ // Array: pre content filter function register array
+ this.contentPreFilters = [];
+ // Array: post content filter function register array
+ this.contentPostFilters = [];
+ // Array: pre content dom filter function register array
+ this.contentDomPreFilters = [];
+ // Array: post content dom filter function register array
+ this.contentDomPostFilters = [];
+ // String: semicolon (";") separated list of css files for the editing area
+ this.styleSheets = "";
+ // Array: array to store all the stylesheets applied to the editing area
+ this.editingAreaStyleSheets=[];
+ if(dojo.render.html.moz){
+ this.contentPreFilters.push(this._fixContentForMoz);
+ }
+
this._keyHandlers = {};
}
);
Modified: myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/Rounded.js
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/Rounded.js?view=diff&rev=473277&r1=473276&r2=473277
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/Rounded.js (original)
+++ myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/Rounded.js Fri Nov 10 01:15:01 2006
@@ -12,9 +12,12 @@
dojo.widget.tags.addParseTreeHandler("dojo:rounded");
dojo.require("dojo.widget.*");
-dojo.require("dojo.widget.html.ContentPane");
-dojo.require("dojo.html");
-dojo.require("dojo.style");
+dojo.require("dojo.widget.ContentPane");
+dojo.require("dojo.html.style");
+dojo.require("dojo.html.display");
+dojo.require("dojo.gfx.color");
+
+dojo.deprecated("dojo.widget.Rounded will be removed in version 0.5; you can now apply rounded corners to any block element using dojo.lfx.rounded.", "0.5");
/*
* The following script is derived (with permission) from curvyCorners,
@@ -22,15 +25,12 @@
* Lucas (CLA on file)
*/
-dojo.widget.Rounded = function() {
- dojo.widget.html.ContentPane.call(this);
-}
-
-dojo.inherits(dojo.widget.Rounded, dojo.widget.html.ContentPane);
-
-dojo.lang.extend(dojo.widget.Rounded, {
+dojo.widget.defineWidget(
+ "dojo.widget.Rounded",
+ dojo.widget.ContentPane,
+{
isSafari: dojo.render.html.safari,
- widgetType: "Rounded",
+
boxMargin: "50px", // margin outside rounded corner box
radius: 14, // radius of corners
domNode: "",
@@ -40,7 +40,7 @@
fillInTemplate: function(args, frag) {
dojo.widget.Rounded.superclass.fillInTemplate.call(this, args, frag);
- dojo.style.insertCssFile(this.templateCssPath);
+ dojo.html.insertCssFile(this.templateCssPath);
// Magic to automatically calculate the box height/width if not supplied
if (this.domNode.style.height<=0) {
@@ -86,20 +86,20 @@
this.masterCorners = [];
// Get box formatting details
- var boxHeight = dojo.style.getStyle(this.box, "height");
+ var boxHeight = dojo.html.getStyle(this.box, "height");
if(boxHeight=="") boxHeight="0px";
- var boxWidth = dojo.style.getStyle(this.box, "width");
- var borderWidth = dojo.style.getStyle(this.box, "borderTopWidth");
+ var boxWidth = dojo.html.getStyle(this.box, "width");
+ var borderWidth = dojo.html.getStyle(this.box, "borderTopWidth");
if(borderWidth=="") borderWidth="0px";
//alert(borderWidth);
- var borderColour = dojo.style.getStyle(this.box, "borderTopColor");
+ var borderColour = dojo.html.getStyle(this.box, "borderTopColor");
// Set to true if we have a border
if(borderWidth>0) this.antiAlias=true;
- var boxColour = dojo.style.getStyle(this.box, "backgroundColor");
- var backgroundImage = dojo.style.getStyle(this.box, "backgroundImage");
- var boxPosition = dojo.style.getStyle(this.box, "position");
+ var boxColour = dojo.html.getStyle(this.box, "backgroundColor");
+ var backgroundImage = dojo.html.getStyle(this.box, "backgroundImage");
+ var boxPosition = dojo.html.getStyle(this.box, "position");
// Set formatting propertes
this.boxHeight = parseInt(((boxHeight != "" && boxHeight != "auto" && boxHeight.indexOf("%") == -1)? boxHeight.substring(0, boxHeight.indexOf("px")) : this.box.scrollHeight));
@@ -109,7 +109,7 @@
// DEBUG ME?
//dojo.debug(this.rgb2Hex(boxColour));
- var test = new dojo.graphics.color.Color(boxColour);
+ var test = new dojo.gfx.color.Color(boxColour);
//dojo.debug(test.toHex());
this.boxColour = ((boxColour != "" && boxColour != "transparent")? ((boxColour.substr(0, 3) == "rgb")? this.rgb2Hex(boxColour) : boxColour) : "#ffffff");
@@ -329,7 +329,7 @@
this.drawPixel(intx, inty, this.borderColour, 100, 1, newCorner, -1, this.settings[cc].radius);
}
} else {
- var pixelcolour = dojo.graphics.color.blend(this.boxColour, this.borderColour, this.pixelFraction(intx, inty, borderRadius));
+ var pixelcolour = dojo.gfx.color.blend(this.boxColour, this.borderColour, this.pixelFraction(intx, inty, borderRadius));
this.drawPixel(intx, inty, pixelcolour, 100, 1, newCorner, 0, this.settings[cc].radius);
}
}
@@ -569,7 +569,7 @@
// Set opacity if the transparency is anything other than 100
if (transAmount != 100) {
- dojo.style.setOpacity(pixel, transAmount);
+ dojo.html.setOpacity(pixel, transAmount);
}
// Set the pixels position
pixel.style.top = inty + "px";
Modified: myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/Select.js
URL: http://svn.apache.org/viewvc/myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/Select.js?view=diff&rev=473277&r1=473276&r2=473277
==============================================================================
--- myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/Select.js (original)
+++ myfaces/tomahawk/trunk/core/src/main/resources/org/apache/myfaces/custom/dojo/resource/src/widget/Select.js Fri Nov 10 01:15:01 2006
@@ -8,69 +8,69 @@
http://dojotoolkit.org/community/licensing.shtml
*/
-dojo.provide("dojo.widget.Select");
-dojo.provide("dojo.widget.html.Select");
-
-dojo.require("dojo.widget.html.ComboBox");
-dojo.require("dojo.widget.*");
-dojo.require("dojo.widget.html.stabile");
-
-/*
- * The Select widget is an enhanced version of HTML's <select> tag.
- *
- * Similar features:
- * - There is a drop down list of possible values.
- * - You can only enter a value from the drop down list. (You can't enter an arbitrary value.)
- * - The value submitted with the form is the hidden value (ex: CA),
- not the displayed value a.k.a. label (ex: California)
- *
- * Enhancements over plain HTML version:
- * - If you type in some text then it will filter down the list of possible values in the drop down list.
- * - List can be specified either as a static list or via a javascript function (that can get the list from a server)
- */
-
-dojo.widget.defineWidget(
- "dojo.widget.html.Select",
- dojo.widget.html.ComboBox,
- {
- widgetType: "Select",
- forceValidOption: true,
-
- setValue: function(value) {
- this.comboBoxValue.value = value;
- dojo.widget.html.stabile.setState(this.widgetId, this.getState(), true);
- },
-
- setLabel: function(value){
- // FIXME, not sure what to do here!
- this.comboBoxSelectionValue.value = value;
- if (this.textInputNode.value != value) { // prevent mucking up of selection
- this.textInputNode.value = value;
- }
- },
-
- getLabel: function(){
- return this.comboBoxSelectionValue.value;
- },
-
- getState: function() {
- return {
- value: this.getValue(),
- label: this.getLabel()
- };
- },
-
- onKeyUp: function(evt){
- this.setLabel(this.textInputNode.value);
- },
-
- setState: function(state) {
- this.setValue(state.value);
- this.setLabel(state.label);
- },
-
- setAllValues: function(value1, value2){
- this.setValue(value2);
- this.setLabel(value1);
- }
- });
+dojo.provide("dojo.widget.Select");
+
+dojo.require("dojo.widget.ComboBox");
+dojo.require("dojo.widget.*");
+dojo.require("dojo.widget.html.stabile");
+
+/*
+ * The Select widget is an enhanced version of HTML's <select> tag.
+ *
+ * Similar features:
+ * - There is a drop down list of possible values.
+ * - You can only enter a value from the drop down list. (You can't enter an arbitrary value.)
+ * - The value submitted with the form is the hidden value (ex: CA),
+ not the displayed value a.k.a. label (ex: California)
+ *
+ * Enhancements over plain HTML version:
+ * - If you type in some text then it will filter down the list of possible values in the drop down list.
+ * - List can be specified either as a static list or via a javascript function (that can get the list from a server)
+ */
+
+dojo.widget.defineWidget(
+ "dojo.widget.Select",
+ dojo.widget.ComboBox,
+ {
+ forceValidOption: true,
+
+ setValue: function(value) {
+ this.comboBoxValue.value = value;
+ dojo.widget.html.stabile.setState(this.widgetId, this.getState(), true);
+ this.onValueChanged(value);
+ },
+
+ setLabel: function(value){
+ // FIXME, not sure what to do here!
+ this.comboBoxSelectionValue.value = value;
+ if (this.textInputNode.value != value) { // prevent mucking up of selection
+ this.textInputNode.value = value;
+ }
+ },
+
+ getLabel: function(){
+ return this.comboBoxSelectionValue.value;
+ },
+
+ getState: function() {
+ return {
+ value: this.getValue(),
+ label: this.getLabel()
+ };
+ },
+
+ onKeyUp: function(evt){
+ this.setLabel(this.textInputNode.value);
+ },
+
+ setState: function(state) {
+ this.setValue(state.value);
+ this.setLabel(state.label);
+ },
+
+ setAllValues: function(value1, value2){
+ this.setLabel(value1);
+ this.setValue(value2);
+ }
+ }
+);