diff --git a/modules/editor/skins/xquared/editor.html b/modules/editor/skins/xquared/editor.html
index b2fc7718b..833d7d85a 100644
--- a/modules/editor/skins/xquared/editor.html
+++ b/modules/editor/skins/xquared/editor.html
@@ -7,8 +7,7 @@
-
-
+
@@ -16,8 +15,8 @@
var auto_saved_msg = "{$lang->msg_auto_saved}";
var xed_{$editor_sequence};
xAddEventListener(window, 'load', function() {
- if($("comment_{$editor_sequence}") == null || $("comment_{$editor_sequence}").style.display != 'none'){
- editorStart_xq(xed_{$editor_sequence}, $("xqEditor_{$editor_sequence}"), {$editor_sequence}, "{$editor_content_key_name}", "{$editor_height}px", "{$editor_primary_key_name}");
+ if(document.getElementById("comment_{$editor_sequence}") == null || document.getElementById("comment_{$editor_sequence}").style.display != 'none'){
+ editorStart_xq(xed_{$editor_sequence}, document.getElementById("xqEditor_{$editor_sequence}"), {$editor_sequence}, "{$editor_content_key_name}", "{$editor_height}px", "{$editor_primary_key_name}");
}});
//]]>
diff --git a/modules/editor/skins/xquared/examples/default.html b/modules/editor/skins/xquared/examples/default.html
index b91d29415..29debfdc1 100644
--- a/modules/editor/skins/xquared/examples/default.html
+++ b/modules/editor/skins/xquared/examples/default.html
@@ -4,13 +4,12 @@
Xquared example - Default
-
")
};
xq.loadOthers=function(){var A=xq.findXquaredScript();
-var C=A.src.match(/(.*\/)xquared\.js.*/i)[1];
-var B=["Editor.js","Browser.js","Shortcut.js","DomTree.js","RichDom.js","RichDomW3.js","RichDomGecko.js","RichDomWebkit.js","RichDomTrident.js","RichTable.js","Validator.js","ValidatorW3.js","ValidatorGecko.js","ValidatorWebkit.js","ValidatorTrident.js","EditHistory.js","Controls.js","_ui_templates.js"];
-B.each(function(D){xq.loadScript(C+D)
-})
-};
+var D=A.src.match(/(.*\/)xquared\.js.*/i)[1];
+var C=["Editor.js","Browser.js","Shortcut.js","DomTree.js","RichDom.js","RichDomW3.js","RichDomGecko.js","RichDomWebkit.js","RichDomTrident.js","RichTable.js","Validator.js","ValidatorW3.js","ValidatorGecko.js","ValidatorWebkit.js","ValidatorTrident.js","EditHistory.js","Controls.js","_ui_templates.js"];
+for(var B=0;
+B0?G[0]:null;
-if(E){this.toolbarButtons.set(F,E)
-}}.bind(this))
-}var B=this.toolbarButtons;
-var C=this.rdom.collectStructureAndStyle(A);
-this._updateToolbarButtonStatus("emphasis",C.em);
-this._updateToolbarButtonStatus("strongEmphasis",C.strong);
-this._updateToolbarButtonStatus("underline",C.underline);
-this._updateToolbarButtonStatus("strike",C.strike);
-this._updateToolbarButtonStatus("superscription",C.superscription);
-this._updateToolbarButtonStatus("subscription",C.subscription);
-this._updateToolbarButtonStatus("justifyLeft",C.justification=="left");
-this._updateToolbarButtonStatus("justifyCenter",C.justification=="center");
-this._updateToolbarButtonStatus("justifyRight",C.justification=="right");
-this._updateToolbarButtonStatus("justifyBoth",C.justification=="justify");
-this._updateToolbarButtonStatus("orderedList",C.list=="OL");
-this._updateToolbarButtonStatus("unorderedList",C.list=="UL");
-this._updateToolbarButtonStatus("code",C.list=="CODE");
-this._updateToolbarButtonStatus("paragraph",C.block=="P");
-this._updateToolbarButtonStatus("heading1",C.block=="H1");
-this._updateToolbarButtonStatus("heading2",C.block=="H2");
-this._updateToolbarButtonStatus("heading3",C.block=="H3");
-this._updateToolbarButtonStatus("heading4",C.block=="H4");
-this._updateToolbarButtonStatus("heading5",C.block=="H5");
-this._updateToolbarButtonStatus("heading6",C.block=="H6")
+}},updateAllToolbarButtonsStatus:function(C){if(!this.toolbarContainer){return
+}if(!this.toolbarButtons){var G=["emphasis","strongEmphasis","underline","strike","superscription","subscription","justifyLeft","justifyCenter","justifyRight","justifyBoth","unorderedList","orderedList","code","paragraph","heading1","heading2","heading3","heading4","heading5","heading6"];
+this.toolbarButtons={};
+for(var B=0;
+B0?E[0]:null;
+if(A){this.toolbarButtons[G[B]]=A
+}}}var D=this.toolbarButtons;
+var F=this.rdom.collectStructureAndStyle(C);
+this._updateToolbarButtonStatus("emphasis",F.em);
+this._updateToolbarButtonStatus("strongEmphasis",F.strong);
+this._updateToolbarButtonStatus("underline",F.underline);
+this._updateToolbarButtonStatus("strike",F.strike);
+this._updateToolbarButtonStatus("superscription",F.superscription);
+this._updateToolbarButtonStatus("subscription",F.subscription);
+this._updateToolbarButtonStatus("justifyLeft",F.justification=="left");
+this._updateToolbarButtonStatus("justifyCenter",F.justification=="center");
+this._updateToolbarButtonStatus("justifyRight",F.justification=="right");
+this._updateToolbarButtonStatus("justifyBoth",F.justification=="justify");
+this._updateToolbarButtonStatus("orderedList",F.list=="OL");
+this._updateToolbarButtonStatus("unorderedList",F.list=="UL");
+this._updateToolbarButtonStatus("code",F.list=="CODE");
+this._updateToolbarButtonStatus("paragraph",F.block=="P");
+this._updateToolbarButtonStatus("heading1",F.block=="H1");
+this._updateToolbarButtonStatus("heading2",F.block=="H2");
+this._updateToolbarButtonStatus("heading3",F.block=="H3");
+this._updateToolbarButtonStatus("heading4",F.block=="H4");
+this._updateToolbarButtonStatus("heading5",F.block=="H5");
+this._updateToolbarButtonStatus("heading6",F.block=="H6")
},removeUnnecessarySpaces:function(A){var C=this.rdom.tree.getBlockTags().join("|");
var B=new RegExp("\\s*<(/?)("+C+")>\\s*","img");
return A.replace(B,"<$1$2>")
@@ -331,6 +499,7 @@ this.editorBody=this.editorDoc.body;
this.editorBody.className="xed";
if(xq.Browser.isIE6){this.editorDoc.documentElement.style.overflowY="auto";
this.editorDoc.documentElement.style.overflowX="hidden"
+}if(this.config.generateDefaultToolbar){this._addStyleRules([{selector:".xquared div.toolbar",rule:"background-image: url("+this.config.imagePathForDefaultToobar+"toolbarBg.gif)"},{selector:".xquared ul.buttons li",rule:"background-image: url("+this.config.imagePathForDefaultToobar+"toolbarButtonBg.gif)"},{selector:".xquared ul.buttons li.xq_separator",rule:"background-image: url("+this.config.imagePathForDefaultToobar+"toolbarSeparator.gif)"}])
}this.rdom.setWin(this.editorWin);
this.rdom.setRoot(this.editorBody);
this.validator=xq.Validator.createInstance(this.doc.location.href,this.config.urlValidationMode,this.config.allowedTags,this.config.allowedAttributes);
@@ -339,67 +508,68 @@ this.contentElement.form.onsubmit=function(){this.contentElement.value=this.getC
if(A){return A()
}else{return true
}}.bind(this)
-}},_addStyleRule:function(A,C){if(!this.dynamicStyle){if(xq.Browser.isTrident){this.dynamicStyle=this.doc.createStyleSheet()
+}},_addStyleRules:function(D){if(!this.dynamicStyle){if(xq.Browser.isTrident){this.dynamicStyle=this.doc.createStyleSheet()
}else{var B=this.doc.createElement("style");
this.doc.body.appendChild(B);
-this.dynamicStyle=$A(this.doc.styleSheets).last()
-}}if(xq.Browser.isTrident){this.dynamicStyle.addRule(A,C)
-}else{this.dynamicStyle.insertRule(A+" {"+C+"}",this.dynamicStyle.cssRules.length)
-}},_generateDefaultToolbar:function(){this._addStyleRule(".xquared div.toolbar","background-image: url("+this.config.imagePathForDefaultToobar+"toolbarBg.gif)");
-this._addStyleRule(".xquared ul.buttons li","background-image: url("+this.config.imagePathForDefaultToobar+"toolbarButtonBg.gif)");
-this._addStyleRule(".xquared ul.buttons li.xq_separator","background-image: url("+this.config.imagePathForDefaultToobar+"toolbarSeparator.gif)");
-var container=this.doc.createElement("div");
-container.className="toolbar";
-var buttons=this.doc.createElement("ul");
-buttons.className="buttons";
-container.appendChild(buttons);
-var cancelMousedown=function(e){Event.stop(e);
+this.dynamicStyle=xq.$A(this.doc.styleSheets).last()
+}}for(var A=0;
+A0){this._contextMenuContainer.removeChild(this._contextMenuContainer.childNodes[0])
}}for(var B=0;
@@ -810,8 +993,9 @@ A.className="separator"
return A
},_contextMenuClicked:function(e){this.hideContextMenu();
if(!this._contextMenuContainer){return
-}var node=Event.findElement(e,"LI");
-if(!node||!this.rdom.tree.isDescendantOf(this._contextMenuContainer,node)){return
+}var node=e.srcElement||e.target;
+while(node&&node.nodeName!="LI"){node=node.parentNode
+}if(!node||!this.rdom.tree.isDescendantOf(this._contextMenuContainer,node)){return
}for(var i=0;
i-1,isGecko:navigator.userAgent.indexOf("Gecko")>-1&&navigator.userAgent.indexOf("KHTML")==-1,isKHTML:navigator.userAgent.indexOf("KHTML")!=-1,isPresto:navigator.appName=="Opera",isMac:navigator.userAgent.indexOf("Macintosh")!=-1,isUbuntu:navigator.userAgent.indexOf("Ubuntu")!=-1,isIE:navigator.appName=="Microsoft Internet Explorer",isIE6:navigator.userAgent.indexOf("MSIE 6")!=-1,isIE7:navigator.userAgent.indexOf("MSIE 7")!=-1};
-xq.Shortcut=Class.create({initialize:function(A){this.keymap=(typeof A=="string")?xq.Shortcut.interprete(A).keymap:A
+xq.Shortcut=xq.Class({initialize:function(A){xq.addToFinalizeQueue(this);
+this.keymap=(typeof A=="string")?xq.Shortcut.interprete(A).keymap:A
},matches:function(A){var B=xq.Browser.isGecko&&xq.Browser.isMac?(A.keyCode+"_"+A.charCode):A.keyCode;
var D=(this.keymap.which==B)||(this.keymap.which==32&&B==25);
if(typeof A.metaKey=="undefined"){A.metaKey=false
@@ -870,7 +1054,8 @@ if(typeof B=="undefined"){throw"Unknown special key name: ["+A+"]"
}return B
};
xq.Shortcut._keyNames=xq.Browser.isMac&&xq.Browser.isGecko?{BACKSPACE:"8_0",TAB:"9_0",RETURN:"13_0",ENTER:"13_0",ESC:"27_0",SPACE:"0_32",LEFT:"37_0",UP:"38_0",RIGHT:"39_0",DOWN:"40_0",DELETE:"46_0",HOME:"36_0",END:"35_0",PAGEUP:"33_0",PAGEDOWN:"34_0",COMMA:"0_44",HYPHEN:"0_45",EQUAL:"0_61",PERIOD:"0_46",SLASH:"0_47",F1:"112_0",F2:"113_0",F3:"114_0",F4:"115_0",F5:"116_0",F6:"117_0",F7:"118_0",F8:"119_0"}:{BACKSPACE:8,TAB:9,RETURN:13,ENTER:13,ESC:27,SPACE:32,LEFT:37,UP:38,RIGHT:39,DOWN:40,DELETE:46,HOME:36,END:35,PAGEUP:33,PAGEDOWN:34,COMMA:188,HYPHEN:xq.Browser.isTrident?189:109,EQUAL:xq.Browser.isTrident?187:61,PERIOD:190,SLASH:191,F1:112,F2:113,F3:114,F4:115,F5:116,F6:117,F7:118,F8:119,F9:120,F10:121,F11:122,F12:123};
-xq.DomTree=Class.create({initialize:function(){this._blockTags=["DIV","DD","LI","ADDRESS","CAPTION","DT","H1","H2","H3","H4","H5","H6","HR","P","BODY","BLOCKQUOTE","PRE","PARAM","DL","OL","UL","TABLE","THEAD","TBODY","TR","TH","TD"];
+xq.DomTree=xq.Class({initialize:function(){xq.addToFinalizeQueue(this);
+this._blockTags=["DIV","DD","LI","ADDRESS","CAPTION","DT","H1","H2","H3","H4","H5","H6","HR","P","BODY","BLOCKQUOTE","PRE","PARAM","DL","OL","UL","TABLE","THEAD","TBODY","TR","TH","TD"];
this._blockContainerTags=["DIV","DD","LI","BODY","BLOCKQUOTE","UL","OL","DL","TABLE","THEAD","TBODY","TR","TH","TD"];
this._listContainerTags=["OL","UL","DL"];
this._tableCellTags=["TH","TD"];
@@ -969,22 +1154,23 @@ if(!A&&this.isTextOrInlineNode(D)){A=true
}}if(!A||!E){return false
}return true
},isBlockOnlyContainer:function(A){if(!A){return false
-}return this._blockOnlyContainerTags.include(typeof A=="string"?A:A.nodeName)
+}return this._blockOnlyContainerTags.indexOf(typeof A=="string"?A:A.nodeName)!=-1
},isTableCell:function(A){if(!A){return false
-}return this._tableCellTags.include(typeof A=="string"?A:A.nodeName)
+}return this._tableCellTags.indexOf(typeof A=="string"?A:A.nodeName)!=-1
},isBlockContainer:function(A){if(!A){return false
-}return this._blockContainerTags.include(typeof A=="string"?A:A.nodeName)
+}return this._blockContainerTags.indexOf(typeof A=="string"?A:A.nodeName)!=-1
},isHeading:function(A){if(!A){return false
}return(typeof A=="string"?A:A.nodeName).match(/H\d/)
},isBlock:function(A){if(!A){return false
-}return this._blockTags.include(typeof A=="string"?A:A.nodeName)
+}return this._blockTags.indexOf(typeof A=="string"?A:A.nodeName)!=-1
},isAtomic:function(A){if(!A){return false
-}return this._atomicTags.include(typeof A=="string"?A:A.nodeName)
+}return this._atomicTags.indexOf(typeof A=="string"?A:A.nodeName)!=-1
},isListContainer:function(A){if(!A){return false
-}return this._listContainerTags.include(typeof A=="string"?A:A.nodeName)
+}return this._listContainerTags.indexOf(typeof A=="string"?A:A.nodeName)!=-1
},isTextOrInlineNode:function(A){return A&&(A.nodeType==3||!this.isBlock(A))
}});
-xq.RichDom=Class.create({initialize:function(){this.tree=new xq.DomTree();
+xq.RichDom=xq.Class({initialize:function(){xq.addToFinalizeQueue(this);
+this.tree=new xq.DomTree();
this._lastMarkerId=0
},setWin:function(A){if(!A){throw"[win] is null"
}this.win=A
@@ -1007,7 +1193,7 @@ while(true){if(!D||D==A){break
D=this.tree.walkForward(D);
this.deleteNode(B)
}else{D=this.tree.walkForward(D)
-}}},setAttributes:function(A,B){for(key in B){A.setAttribute(key,B[key])
+}}},setAttributes:function(B,C){for(var A in C){B.setAttribute(A,C[A])
}},createTextNode:function(A){return this.doc.createTextNode(A)
},createElement:function(A){return this.doc.createElement(A)
},createElementFromHtml:function(A){var B=this.createElement("div");
@@ -1026,7 +1212,7 @@ this.correctEmptyElement(B)
}},insertNode:function(A){throw"Not implemented"
},insertHtml:function(A){return this.insertNode(this.createElementFromHtml(A))
},insertText:function(A){this.insertNode(this.createTextNode(A))
-},insertNodeAt:function(B,F,E,D){if(["HTML","HEAD"].include(F.nodeName)||["BODY"].include(F.nodeName)&&["before","after"].include(E)){throw"Illegal argument. Cannot move node["+B.nodeName+"] to '"+E+"' of target["+F.nodeName+"]"
+},insertNodeAt:function(B,F,E,D){if(["HTML","HEAD"].indexOf(F.nodeName)!=-1||"BODY"==F.nodeName&&["before","after"].indexOf(E)!=-1){throw"Illegal argument. Cannot move node["+B.nodeName+"] to '"+E+"' of target["+F.nodeName+"]"
}var C;
var I;
var G;
@@ -1096,8 +1282,11 @@ return E
},function(T){return T.nodeType==3
});
var M=0;
-var Q=B.pluck("nodeValue");
-var P=Q.join("");
+var Q=[];
+for(var L=0;
+L"
@@ -1889,7 +2074,7 @@ if(C){return true
}}catch(A){}if(C){this.rng().selectNode(B)
}else{this.rng().selectNodeContents(B)
}}});
-xq.RichDomWebkit=Class.create(xq.RichDomW3,{makePlaceHolder:function(){var A=this.createElement("BR");
+xq.RichDomWebkit=xq.Class(xq.RichDomW3,{makePlaceHolder:function(){var A=this.createElement("BR");
A.className="webkit-block-placeholder";
return A
},makePlaceHolderString:function(){return"
"
@@ -1927,7 +2112,7 @@ this._anchorOffset=B.anchorOffset;
this._focusNode=B.focusNode;
this._focusOffset=B.focusOffset
}});
-xq.RichDomTrident=Class.create(xq.RichDom,{makePlaceHolder:function(){return this.createTextNode(" ")
+xq.RichDomTrident=xq.Class(xq.RichDom,{makePlaceHolder:function(){return this.createTextNode(" ")
},makePlaceHolderString:function(){return" "
},makeEmptyParagraph:function(){return this.createElementFromHtml("
")
},isPlaceHolder:function(A){return false
@@ -1943,7 +2128,7 @@ return B
}if(this.isEmptyBlock(E)){return
}var D=E.innerText;
var B=D.charCodeAt(D.length-1);
-if(D.length<=1||![32,160].include(B)){return
+if(D.length<=1||[32,160].indexOf(B)==-1){return
}var C=E;
while(C&&C.nodeType!=3){C=C.lastChild
}if(!C){return
@@ -1970,6 +2155,7 @@ this.placeCaretAtStartOf(C)
}.bind(this));
if(C){this.deleteNode(D);
this.placeCaretAtStartOf(C)
+}else{this.placeCaretAtStartOf(D)
}return true
}}else{D=this.getCurrentBlockElement();
if(D.nodeType==3){D=D.parentNode
@@ -2028,10 +2214,10 @@ return A&&A.text?A.text:""
},hasImportantAttributes:function(A){return !!(A.id||A.className||A.style.cssText)
},isEmptyBlock:function(A){if(!A.hasChildNodes()){return true
}if(A.nodeType==3&&!A.nodeValue){return true
-}if([" "," ",""].include(A.innerHTML)){return true
+}if([" "," ",""].indexOf(A.innerHTML)!=-1){return true
}return false
},getLastChild:function(C){if(!C||!C.hasChildNodes()){return null
-}var A=$A(C.childNodes).reverse();
+}var A=xq.$A(C.childNodes).reverse();
for(var B=0;
BA)?B[A]:null
}},getDom:function(){return this.table
},hasHeadingAtTop:function(){return !!(this.table.tHead&&this.table.tHead.rows[0])
},hasHeadingAtLeft:function(){return this.table.tBodies[0].rows[0].cells[0].nodeName=="TH"
-},correctEmptyCells:function(){var A=$A(this.table.getElementsByTagName("TH"));
-A.push($A(this.table.getElementsByTagName("TD")));
-A=A.flatten();
+},correctEmptyCells:function(){var A=xq.$A(this.table.getElementsByTagName("TH"));
+var C=xq.$A(this.table.getElementsByTagName("TD"));
for(var B=0;
+B");
if(I){F.push("");
@@ -2192,7 +2381,8 @@ var H=new xq.RichTable(E,A.firstChild);
H.correctEmptyCells();
return H
};
-xq.Validator=Class.create({initialize:function(C,A,D,B){this.allowedTags=(D||["a","abbr","acronym","address","blockquote","br","caption","cite","code","dd","dfn","div","dl","dt","em","h1","h2","h3","h4","h5","h6","hr","img","kbd","li","ol","p","pre","q","samp","span","sup","sub","strong","table","thead","tbody","td","th","tr","ul","var"]).join(" ")+" ";
+xq.Validator=xq.Class({initialize:function(C,A,D,B){xq.addToFinalizeQueue(this);
+this.allowedTags=(D||["a","abbr","acronym","address","blockquote","br","caption","cite","code","dd","dfn","div","dl","dt","em","h1","h2","h3","h4","h5","h6","hr","img","kbd","li","ol","p","pre","q","samp","span","sup","sub","strong","table","thead","tbody","td","th","tr","ul","var"]).join(" ")+" ";
this.allowedAttrs=(B||["alt","cite","class","datetime","height","href","id","rel","rev","src","style","title","width"]).join(" ")+" ";
this.curUrl=C;
this.curUrlParts=C?C.parseURL():null;
@@ -2209,7 +2399,7 @@ return A
},validateSelfClosingTags:function(A){return A.replace(/<(br|hr|img)([^>]*?)>/img,function(D,B,C){return"<"+B+C+" />"
})
},removeComments:function(A){return A.replace(//img,"")
-},removeDangerousElements:function(C){var A=$A(C.getElementsByTagName("SCRIPT")).reverse();
+},removeDangerousElements:function(C){var A=xq.$A(C.getElementsByTagName("SCRIPT")).reverse();
for(var B=0;
B\n$2");
return E
},invalidate:function(C){var F=xq.RichDom.createInstance();
F.setRoot(C);
-var E=F.findByAttribute("class","strike");
+var E=xq.getElementsByClassName(F.getRoot(),"strike");
for(var B=0;
B( )?("+D+")>","img");
var C=xq.RichDom.createInstance();
return B.replace(A,"<$1>"+C.makePlaceHolderString()+"$3>")
}});
-xq.ValidatorGecko=Class.create(xq.ValidatorW3,{});
-xq.ValidatorWebkit=Class.create(xq.ValidatorW3,{});
-xq.ValidatorTrident=Class.create(xq.Validator,{validate:function(C,B){C=C.cloneNode(true);
+xq.ValidatorGecko=xq.Class(xq.ValidatorW3,{});
+xq.ValidatorWebkit=xq.Class(xq.ValidatorW3,{});
+xq.ValidatorTrident=xq.Class(xq.Validator,{validate:function(C,B){C=C.cloneNode(true);
this.removeDangerousElements(C);
this.validateFontColor(C);
this.validateBackgroundColor(C);
@@ -2356,14 +2546,14 @@ if(B){D=this.performFullValidation(D)
F.setRoot(C);
this.invalidateFontColor(C);
this.invalidateBackgroundColor(C);
-var E=F.findByAttribute("className","strike");
+var E=xq.getElementsByClassName(F.getRoot(),"strike");
for(var B=0;
B0){D[0].focus()
-}if(C.cancelOnEsc){Event.observe(this.form,"keydown",function(F){if(F.keyCode==27){this.onCloseHandler();
+}if(C.cancelOnEsc){xq.observe(this.form,"keydown",function(F){if(F.keyCode==27){this.onCloseHandler();
this.close()
}return false
}.bind(this))
}this.onLoadHandler(this)
},close:function(){this.form.parentNode.removeChild(this.form)
-},setPosition:function(G){var D;
-if(G=="centerOfWindow"){D=document.documentElement
-}else{if(G=="centerOfEditor"){D=this.xed.getDoc()[xq.Browser.isTrident?"body":"documentElement"]
-}else{if(G=="nearbyCaret"){throw"Not implemented yet"
-}else{throw"Invalid argument: "+G
-}}}var E=D.clientWidth;
-var B=D.clientHeight;
-var F=this.form.clientWidth;
-var C=this.form.clientHeight;
-var A=parseInt((E-F)/2);
-var H=parseInt((B-C)/2);
-this.form.style.left=A+"px";
+},setPosition:function(E){var F=null;
+var B=0;
+var H=0;
+if(E=="centerOfWindow"){F=document.documentElement
+}else{if(E=="centerOfEditor"){F=this.xed.getFrame();
+var A=F;
+do{B+=A.offsetLeft;
+H+=A.offsetTop
+}while(A=A.offsetParent)
+}else{if(E=="nearbyCaret"){throw"Not implemented yet"
+}else{throw"Invalid argument: "+E
+}}}var I=F.clientWidth;
+var D=F.clientHeight;
+var C=this.form.clientWidth;
+var G=this.form.clientHeight;
+B+=parseInt((I-C)/2);
+H+=parseInt((D-G)/2);
+this.form.style.left=B+"px";
this.form.style.top=H+"px"
}});
-xq.controls.QuickSearchDialog=Class.create({initialize:function(A,B){this.xed=A;
+xq.controls.QuickSearchDialog=xq.Class({initialize:function(A,B){xq.addToFinalizeQueue(this);
+this.xed=A;
this.rdom=xq.RichDom.createInstance();
this.rdom.setRoot(document.body);
this.param=B;
@@ -2538,7 +2737,7 @@ if(!this.param.renderItem){this.param.renderItem=function(C){return this.rdom.ge
}return this._getInputField().value
},onSubmit:function(A){if(this.matchCount()>0){this.param.onSelect(this.xed,this.list[this._getSelectedIndex()])
}this.close();
-Event.stop(A);
+xq.stopEvent(A);
return false
},onCancel:function(A){if(this.param.onCancel){this.param.onCancel(this.xed)
}this.close()
@@ -2575,18 +2774,24 @@ this.updateList();
this.focus()
},close:function(){this.rdom.deleteNode(this.container)
},focus:function(){this._getInputField().focus()
-},setPosition:function(G){var D;
-if(G=="centerOfWindow"){D=document.documentElement
-}else{if(G=="centerOfEditor"){D=this.xed.getDoc().documentElement
-}else{if(G=="nearbyCaret"){throw"Not implemented yet"
-}else{throw"Invalid argument: "+G
-}}}var E=D.clientWidth;
-var B=D.clientHeight;
-var F=this.container.clientWidth;
-var C=this.container.clientHeight;
-var A=parseInt((E-F)/2);
-var H=parseInt((B-C)/2);
-this.container.style.left=A+"px";
+},setPosition:function(E){var F=null;
+var B=0;
+var H=0;
+if(E=="centerOfWindow"){F=document.documentElement
+}else{if(E=="centerOfEditor"){F=this.xed.getFrame();
+var A=F;
+do{B+=A.offsetLeft;
+H+=A.offsetTop
+}while(A=A.offsetParent)
+}else{if(E=="nearbyCaret"){throw"Not implemented yet"
+}else{throw"Invalid argument: "+E
+}}}var I=F.clientWidth;
+var D=F.clientHeight;
+var C=this.container.clientWidth;
+var G=this.container.clientHeight;
+B+=parseInt((I-C)/2);
+H+=parseInt((D-G)/2);
+this.container.style.left=B+"px";
this.container.style.top=H+"px"
},matchCount:function(){return this.list?this.list.length:0
},_create:function(){var A=this.rdom.createElement("DIV");
@@ -2604,11 +2809,11 @@ D.appendChild(B);
C.appendChild(D);
A.appendChild(C);
var E=this.rdom.createElement("OL");
-Event.observe(B,"blur",this.onBlur.bindAsEventListener(this));
-Event.observe(B,"keypress",this.onKey.bindAsEventListener(this));
-Event.observe(E,"click",this.onClick.bindAsEventListener(this),true);
-Event.observe(D,"submit",this.onSubmit.bindAsEventListener(this));
-Event.observe(D,"reset",this.onCancel.bindAsEventListener(this));
+xq.observe(B,"blur",this.onBlur.bindAsEventListener(this));
+xq.observe(B,"keypress",this.onKey.bindAsEventListener(this));
+xq.observe(E,"click",this.onClick.bindAsEventListener(this),true);
+xq.observe(D,"submit",this.onSubmit.bindAsEventListener(this));
+xq.observe(D,"reset",this.onCancel.bindAsEventListener(this));
A.appendChild(E);
return A
},_getInputField:function(){return this.container.getElementsByTagName("INPUT")[0]
diff --git a/modules/editor/skins/xquared/js/xquared.js b/modules/editor/skins/xquared/js/xquared.js
index 1e010f684..0bcf46524 100644
--- a/modules/editor/skins/xquared/js/xquared.js
+++ b/modules/editor/skins/xquared/js/xquared.js
@@ -2,10 +2,258 @@
* Namespace for entire Xquared classes
*/
var xq = {
- majorVersion: '0.1',
- minorVersion: '2007119'
+ majorVersion: '0.2',
+ minorVersion: '20071205'
};
+
+
+/**
+ * Add prototype.js like functions
+ */
+xq.Class = function() { // TODO
+ var parent = null, properties = xq.$A(arguments);
+ if (typeof properties[0] == "function")
+ parent = properties.shift();
+
+ function klass() {
+ this.initialize.apply(this, arguments);
+ }
+
+ if(parent) {
+ for (var key in parent.prototype)
+ klass.prototype[key] = parent.prototype[key];
+ }
+
+ for (var key in properties[0])
+ klass.prototype[key] = properties[0][key];
+
+ if (!klass.prototype.initialize)
+ klass.prototype.initialize = function() {};
+
+ klass.prototype.constructor = klass;
+
+ return klass;
+}
+
+xq.observe = function(element, eventName, handler) {
+ if (element.addEventListener) {
+ element.addEventListener(eventName, handler, false);
+ } else {
+ element.attachEvent('on' + eventName, handler);
+ }
+ element = null;
+}
+
+xq.stopObserving = function(element, eventName, handler) {
+ if (element.removeEventListener) {
+ element.removeEventListener(eventName, handler, false);
+ } else {
+ element.detachEvent("on" + eventName, handler);
+ }
+ element = null;
+}
+
+xq.cancelHandler = function(e) {xq.stopEvent(e); return false};
+
+xq.stopEvent = function(event) {
+ if(event.preventDefault) event.preventDefault();
+ if(event.stopPropagation) event.stopPropagation();
+ event.returnValue = false;
+ event.cancelBubble = true;
+ event.stopped = true;
+}
+
+xq.isButton = function(event, code) {
+ return event.which ? (event.which === code + 1) : (event.button === code);
+}
+xq.isLeftClick = function(event) {return isButton(event, 0);}
+xq.isMiddleClick = function(event) {return isButton(event, 1);}
+xq.isRightClick = function(event) {return isButton(event, 2);}
+
+xq.getEventPoint = function(event) {
+ return {
+ x: event.pageX || (event.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft)),
+ y: event.pageY || (event.clientY + (document.documentElement.scrollTop || document.body.scrollTop))
+ };
+}
+
+xq.getCumulativeOffset = function(element) {
+ var top = 0, left = 0;
+
+ do {
+ top += element.offsetTop || 0;
+ left += element.offsetLeft || 0;
+ element = element.offsetParent;
+ } while (element);
+
+ return {top:top, left:left};
+}
+
+xq.$ = function(id) {
+ return document.getElementById(id);
+}
+
+xq.isEmptyHash = function(h) {
+ for(var key in h) {
+ return false;
+ }
+ return true;
+}
+
+xq.$A = function(arraylike) {
+ var len = arraylike.length, a = new Array(len);
+ while (len--) a[len] = arraylike[len];
+ return a;
+}
+
+xq.hasClassName = function(element, className) {
+ var classNames = element.className;
+ return (classNames.length > 0 && (classNames == className || new RegExp("(^|\\s)" + className + "(\\s|$)").test(classNames)));
+}
+
+xq.serializeForm = function(f) {
+
+try{
+ var options = {hash: true};
+ var data = {};
+ var elements = f.getElementsByTagName("*");
+ for(var i = 0; i < elements.length; i++) {
+ var element = elements[i];
+ var tagName = element.tagName.toLowerCase();
+ if(element.disabled || !element.name || ['input', 'textarea', 'option', 'select'].indexOf(tagName) == -1) continue;
+
+ var key = element.name;
+ var value = xq.getValueOfElement(element);
+
+ if(value === undefined) continue;
+
+ if(key in data) {
+ if(data[key].constructor == Array) data[key] = [data[key]];
+ data[key].push(value);
+ } else {
+ data[key] = value;
+ }
+ }
+ return data;
+} catch(e) {alert(e)}
+}
+
+xq.getValueOfElement = function(e) {
+ var type = e.type.toLowerCase();
+ if(type == 'checkbox' || type == 'radio') return e.checked ? e.value : undefined;
+ return e.value;
+}
+
+xq.getElementsByClassName = function(element, className) {
+ if(element.getElementsByClassName) return element.getElementsByClassName(className);
+
+ var elements = element.getElementsByTagName("*");
+ var len = elements.length;
+ var result = [];
+ var p = new RegExp("(^|\\s)" + className + "($|\\s)");
+ for(var i = 0; i < len; i++) {
+ var cur = elements[i];
+ if(p.test(cur.className)) result.push(cur);
+ }
+ return result;
+}
+
+try {Prototype.version; __prototype = true;} catch(ignored) {__prototype = false;}
+
+if(!__prototype) {
+ if(!Function.prototype.bind) {
+ Function.prototype.bind = function() {
+ var __m = this, arg = xq.$A(arguments), o = arg.shift();
+ return function() {
+ return __m.apply(o, arg.concat(xq.$A(arguments)));
+ }
+ }
+ }
+
+ if(!Function.prototype.bindAsEventListener) {
+ Function.prototype.bindAsEventListener = function() {
+ var __m = this, arg = xq.$A(arguments), o = arg.shift();
+ return function(event) {
+ return __m.apply(o, [event || window.event].concat(arg));
+ }
+ }
+ }
+
+ Array.prototype.find = function(f) {
+ for(var i = 0; i < this.length; i++) {
+ if(f(this[i])) return this[i];
+ }
+ }
+
+ Array.prototype.findAll = function(f) {
+ var result = [];
+ for(var i = 0; i < this.length; i++) {
+ if(f(this[i])) result.push(this[i]);
+ }
+ return result;
+ }
+
+ Array.prototype.first = function() {return this[0]}
+
+ Array.prototype.last = function() {return this[this.length - 1]}
+
+ Array.prototype.include = function(o) {
+ if (this.indexOf(o) != -1) return true;
+
+ var found = false;
+ for(var i = 0; i < this.length; i++) {
+ if(this[i] == o) return true;
+ }
+
+ return false;
+ }
+
+ Array.prototype.flatten = function() {
+ var result = [];
+ var _flatten = function(array) {
+ for(var i = 0; i < array.length; i++) {
+ if(array[i].constructor === Array) {
+ _flatten(array[i]);
+ } else {
+ result.push(array[i]);
+ }
+ }
+ }
+ _flatten(this);
+
+ return result;
+ }
+
+ String.prototype.blank = function() {
+ return /^\s*$/.test(this);
+ }
+ String.prototype.stripTags = function() {
+ return this.replace(/<\/?[^>]+>/gi, '');
+ }
+ String.prototype.escapeHTML = function() {
+ xq._text.data = this;
+ return xq._div.innerHTML;
+ }
+ xq._text = document.createTextNode('');
+ xq._div = document.createElement('div');
+ xq._div.appendChild(xq._text);
+
+ String.prototype.strip = function() {
+ return this.replace(/^\s+/, '').replace(/\s+$/, '');
+ }
+
+ Array.prototype.indexOf = function(n) {
+ for(var i = 0; i < this.length; i++) {
+ if(this[i] == n) return i;
+ }
+
+ return -1;
+ }
+}
+
+
+
/**
* Make given object as event source
*
@@ -20,7 +268,7 @@ xq.asEventSource = function(object, prefix, events) {
for(var i = 0; i < this._listeners.length; i++) {
var listener = this._listeners[i];
var func = listener["on" + prefix + name];
- if(func) func.apply(listener, $A(arguments));
+ if(func) func.apply(listener, xq.$A(arguments));
}
}
}
@@ -33,18 +281,7 @@ xq.asEventSource = function(object, prefix, events) {
}
}
-/**
- * Returns the index of given element
- *
- * @returns {Number} index or -1
- */
-Array.prototype.indexOf = function(n) {
- for(var i = 0; i < this.length; i++) {
- if(this[i] == n) return i;
- }
-
- return -1;
-}
+
Date.preset = null;
Date.pass = function(msec) {
@@ -107,8 +344,37 @@ String.prototype.parseURL = function() {
};
}
+
+
+/**
+ * Automatic finalizer
+ */
+xq.autoFinalizeQueue = [];
+
+xq.addToFinalizeQueue = function(obj) {
+ xq.autoFinalizeQueue.push(obj);
+}
+
+xq.finalize = function(obj) {
+ if(typeof obj.finalize == "function") {
+ try {obj.finalize();} catch(ignored) {}
+ }
+
+ for(key in obj) obj[key] = null;
+}
+
+xq.observe(window, "unload", function() {
+ for(var i = 0; i < xq.autoFinalizeQueue.length; i++) xq.finalize(xq.autoFinalizeQueue[i]);
+ xq = null;
+});
+
+
+
+/**
+ * Script loader
+ */
xq.findXquaredScript = function() {
- return $A(document.getElementsByTagName("script")).find(function(script) {
+ return xq.$A(document.getElementsByTagName("script")).find(function(script) {
return script.src && script.src.match(/xquared\.js/i);
});
}
@@ -142,27 +408,32 @@ xq.loadOthers = function() {
'Controls.js',
'_ui_templates.js'
];
- others.each(function(name) {
- xq.loadScript(basePath + name);
- });
+ for(var i = 0; i < others.length; i++) {
+ xq.loadScript(basePath + others[i]);
+ };
}
if(xq.shouldLoadOthers()) xq.loadOthers();
/**
* @fileOverview xq.Editor manages configurations such as autocompletion and autocorrection, edit mode/normal mode switching, handles editing commands, keyboard shortcuts and other events.
*/
-xq.Editor = Class.create({
+xq.Editor = xq.Class({
/**
* Initialize editor but it doesn't automatically start designMode. setEditMode should be called after initialization.
*
* @constructor
- * @param {Element} contentElement HTML element(TEXTAREA or normal block element such as DIV) to be replaced with editable area
- * @param {Element} toolbarContainer HTML element which contains toolbar icons
+ * @param {Object} contentElement HTML element(TEXTAREA or normal block element such as DIV) to be replaced with editable area, or DOM ID string.
+ * @param {Object} toolbarContainer HTML element which contains toolbar icons, or DOM ID string.
*/
initialize: function(contentElement, toolbarContainer) {
+ xq.addToFinalizeQueue(this);
+
+ if(typeof contentElement == 'string') contentElement = xq.$(contentElement);
if(!contentElement) throw "[contentElement] is null";
if(contentElement.nodeType != 1) throw "[contentElement] is not an element";
+ if(typeof toolbarContainer == 'string') toolbarContainer = xq.$(toolbarContainer);
+
xq.asEventSource(this, "Editor", ["ElementChanged", "BeforeEvent", "AfterEvent", "CurrentContentChanged", "StaticContentChanged", "CurrentEditModeChanged"]);
/**
@@ -224,7 +495,8 @@ xq.Editor = Class.create({
]
];
- this.config.imagePathForDefaultToobar = request_uri+editor_path.substring(1)+'examples/img/toolbar/';
+ this.config.imagePathForDefaultToobar = 'img/toolbar/';
+ this.config.imagePathForContent = 'img/content/';
// relative | host_relative | absolute | browser_default
this.config.urlValidationMode = 'absolute';
@@ -335,6 +607,7 @@ xq.Editor = Class.create({
* @type Array
*/
this.toolbarButtons = null;
+ this._toolbarAnchorsCache = [];
/**
* Undo/redo manager
@@ -369,6 +642,15 @@ xq.Editor = Class.create({
});
},
+ finalize: function() {
+ for(var i = 0; i < this._toolbarAnchorsCache.length; i++) {
+ this._toolbarAnchorsCache[i].xed = null;
+ this._toolbarAnchorsCache[i].handler = null;
+ this._toolbarAnchorsCache[i] = null;
+ }
+ this._toolbarAnchorsCache = null;
+ },
+
/////////////////////////////////////////////
@@ -475,9 +757,9 @@ xq.Editor = Class.create({
* @param {Array} list of shortcuts. each element should have following structure: {event:"keymap expression", handler:handler}
*/
addShortcuts: function(list) {
- list.each(function(shortcut) {
- this.addShortcut(shortcut.event, shortcut.handler);
- }.bind(this));
+ for(var i = 0; i < list.length; i++) {
+ this.addShortcut(list[i].event, list[i].handler);
+ }
},
/**
@@ -520,9 +802,9 @@ xq.Editor = Class.create({
* @param {Array} list of autocorrection. each element should have following structure: {id:"identifier", criteria:criteria, handler:handler}
*/
addAutocorrections: function(list) {
- list.each(function(ac) {
- this.addAutocorrection(ac.id, ac.criteria, ac.handler);
- }.bind(this));
+ for(var i = 0; i < list.length; i++) {
+ this.addAutocorrection(list[i].id, list[i].criteria, list[i].handler);
+ }
},
/**
@@ -568,9 +850,9 @@ xq.Editor = Class.create({
* @param {Array} list of autocompletion. each element should have following structure: {id:"identifier", criteria:criteria, handler:handler}
*/
addAutocompletions: function(list) {
- list.each(function(ac) {
- this.addAutocompletion(ac.id, ac.criteria, ac.handler);
- }.bind(this));
+ for(var i = 0; i < list.length; i++) {
+ this.addAutocompletion(list[i].id, list[i].criteria, list[i].handler);
+ }
},
/**
@@ -608,9 +890,9 @@ xq.Editor = Class.create({
* @param {Array} list of template processors. Each element should have following structure: {id:"identifier", handler:handler}
*/
addTemplateProcessors: function(list) {
- list.each(function(tp) {
- this.addTemplateProcessor(tp.id, tp.handler);
- }.bind(this));
+ for(var i = 0; i < list.length; i++) {
+ this.addTemplateProcessor(list[i].id, list[i].handler);
+ }
},
/**
@@ -650,9 +932,9 @@ xq.Editor = Class.create({
* @param {Array} list of handlers. Each element should have following structure: {id:"identifier", handler:handler}
*/
addContextMenuHandlers: function(list) {
- list.each(function(mh) {
- this.addContextMenuHandler(mh.id, mh.handler);
- }.bind(this));
+ for(var i = 0; i < list.length; i++) {
+ this.addContextMenuHandler(list[i].id, list[i].handler);
+ }
},
/**
@@ -849,15 +1131,16 @@ xq.Editor = Class.create({
if(!this.toolbarContainer) return;
exceptions = exceptions || [];
- $(this.toolbarContainer).select('li').each(function(li) {
- var buttonsClassName = li.classNames().find(function(name) {return name != 'xq_separator'});
- var exception = exceptions.include(buttonsClassName);
- exec(li, exception);
- });
+ var lis = this.toolbarContainer.getElementsByTagName('LI');
+ for(var i = 0; i < lis.length; i++) {
+ var buttonsClassName = lis[i].className.split(" ").find(function(name) {return name != 'xq_separator'});
+ var exception = exceptions.indexOf(buttonsClassName) != -1;
+ exec(lis[i], exception);
+ }
},
_updateToolbarButtonStatus: function(buttonClassName, selected) {
- var button = this.toolbarButtons.get(buttonClassName);
+ var button = this.toolbarButtons[buttonClassName];
if(button) button.firstChild.firstChild.className = selected ? 'selected' : '';
},
@@ -871,13 +1154,13 @@ xq.Editor = Class.create({
"paragraph", "heading1", "heading2", "heading3", "heading4", "heading5", "heading6"
];
- this.toolbarButtons = $H({});
+ this.toolbarButtons = {};
- classNames.each(function(className) {
- var found = $(this.toolbarContainer).getElementsBySelector("." + className);
+ for(var i = 0; i < classNames.length; i++) {
+ var found = xq.getElementsByClassName(this.toolbarContainer, classNames[i]);
var button = found && found.length > 0 ? found[0] : null;
- if(button) this.toolbarButtons.set(className, button);
- }.bind(this));
+ if(button) this.toolbarButtons[classNames[i]] = button;
+ }
}
var buttons = this.toolbarButtons;
@@ -1128,6 +1411,15 @@ xq.Editor = Class.create({
this.editorDoc.documentElement.style.overflowX='hidden';
}
+ // override image path
+ if(this.config.generateDefaultToolbar) {
+ this._addStyleRules([
+ {selector:".xquared div.toolbar", rule:"background-image: url(" + this.config.imagePathForDefaultToobar + "toolbarBg.gif)"},
+ {selector:".xquared ul.buttons li", rule:"background-image: url(" + this.config.imagePathForDefaultToobar + "toolbarButtonBg.gif)"},
+ {selector:".xquared ul.buttons li.xq_separator", rule:"background-image: url(" + this.config.imagePathForDefaultToobar + "toolbarSeparator.gif)"}
+ ]);
+ }
+
this.rdom.setWin(this.editorWin);
this.rdom.setRoot(this.editorBody);
this.validator = xq.Validator.createInstance(this.doc.location.href, this.config.urlValidationMode, this.config.allowedTags, this.config.allowedAttributes);
@@ -1147,30 +1439,51 @@ xq.Editor = Class.create({
}
},
- _addStyleRule: function(selector, rule) {
+ _addStyleRules: function(rules) {
if(!this.dynamicStyle) {
if(xq.Browser.isTrident) {
this.dynamicStyle = this.doc.createStyleSheet();
} else {
var style = this.doc.createElement('style');
this.doc.body.appendChild(style);
- this.dynamicStyle = $A(this.doc.styleSheets).last();
+ this.dynamicStyle = xq.$A(this.doc.styleSheets).last();
}
}
- if(xq.Browser.isTrident) {
- this.dynamicStyle.addRule(selector, rule);
+ for(var i = 0; i < rules.length; i++) {
+ var rule = rules[i];
+ if(xq.Browser.isTrident) {
+ this.dynamicStyle.addRule(rules[i].selector, rules[i].rule);
+ } else {
+ this.dynamicStyle.insertRule(rules[i].selector + " {" + rules[i].rule + "}", this.dynamicStyle.cssRules.length);
+ }
+ }
+ },
+
+ _defaultToolbarClickHandler: function(e) {
+ var src = e.target || e.srcElement;
+ while(src.nodeName != "A") src = src.parentNode;
+
+ if(xq.hasClassName(src.parentNode, 'disabled') || xq.hasClassName(this.toolbarContainer, 'disabled')) {
+ xq.stopEvent(e);
+ return false;
+ }
+
+ if(xq.Browser.isTrident) this.focus();
+
+ var handler = src.handler;
+ var xed = this;
+ var stop = (typeof handler == "function") ? handler(this) : eval(handler);
+
+ if(stop) {
+ xq.stopEvent(e);
+ return false;
} else {
- this.dynamicStyle.insertRule(selector + " {" + rule + "}", this.dynamicStyle.cssRules.length);
- }
+ return true;
+ }
},
_generateDefaultToolbar: function() {
- // override image path
- this._addStyleRule(".xquared div.toolbar", "background-image: url(" + this.config.imagePathForDefaultToobar + "toolbarBg.gif)");
- this._addStyleRule(".xquared ul.buttons li", "background-image: url(" + this.config.imagePathForDefaultToobar + "toolbarButtonBg.gif)");
- this._addStyleRule(".xquared ul.buttons li.xq_separator", "background-image: url(" + this.config.imagePathForDefaultToobar + "toolbarSeparator.gif)");
-
// outmost container
var container = this.doc.createElement('div');
container.className = 'toolbar';
@@ -1181,7 +1494,6 @@ xq.Editor = Class.create({
container.appendChild(buttons);
// Generate buttons from map and append it to button container
- var cancelMousedown = function(e) {Event.stop(e); return false};
var map = this.config.defaultToolbarButtonMap;
for(var i = 0; i < map.length; i++) {
for(var j = 0; j < map[i].length; j++) {
@@ -1199,28 +1511,12 @@ xq.Editor = Class.create({
a.href = '#';
a.title = buttonConfig.title;
a.handler = buttonConfig.handler;
- a.xed = this;
- Event.observe(a, 'mousedown', cancelMousedown);
- Event.observe(a, 'click', function(e) {
- var xed = this.xed;
-
- if($(this.parentNode).hasClassName('disabled') || xed.toolbarContainer.hasClassName('disabled')) {
- Event.stop(e);
- return false;
- }
-
- if(xq.Browser.isTrident) xed.focus();
-
- var handler = this.handler;
- var stop = (typeof handler == "function") ? handler(xed) : eval(handler);
- if(stop) {
- Event.stop(e);
- return false;
- } else {
- return true;
- }
- }.bind(a));
+ this._toolbarAnchorsCache.push(a);
+
+ xq.observe(a, 'mousedown', xq.cancelHandler);
+ xq.observe(a, 'click', this._defaultToolbarClickHandler.bindAsEventListener(this));
+
var img = this.doc.createElement('img');
a.appendChild(img);
img.src = this.config.imagePathForDefaultToobar + buttonConfig.className + '.gif';
@@ -1238,13 +1534,13 @@ xq.Editor = Class.create({
// Event Management
_registerEventHandlers: function() {
- var events = ['keydown', 'click', 'keyup', 'mouseup', 'contextmenu', 'scroll'];
+ var events = ['keydown', 'click', 'keyup', 'mouseup', 'contextmenu'];
if(xq.Browser.isTrident && this.config.changeCursorOnLink) events.push('mousemove');
if(xq.Browser.isMac && xq.Browser.isGecko) events.push('keypress');
for(var i = 0; i < events.length; i++) {
- Event.observe(this.getDoc(), events[i], this._handleEvent.bindAsEventListener(this));
+ xq.observe(this.getDoc(), events[i], this._handleEvent.bindAsEventListener(this));
}
},
@@ -1258,7 +1554,11 @@ xq.Editor = Class.create({
if(e.type == 'mousemove' && this.config.changeCursorOnLink) {
// Trident only
var link = !!this.rdom.getParentElementOf(e.srcElement, ["A"]);
- if(this.editorBody.contentEditable != link && !this.rdom.hasSelection()) this.editorBody.contentEditable = !link;
+
+ var editable = this.editorBody.contentEditable;
+ editable = editable == 'inherit' ? false : editable;
+
+ if(editable != link && !this.rdom.hasSelection()) this.editorBody.contentEditable = !link;
} else if(e.type == 'click' && e.button == 0 && this.config.enableLinkClick) {
var a = this.rdom.getParentElementOf(e.target || e.srcElement, ["A"]);
if(a) stop = this.handleClick(e, a);
@@ -1275,13 +1575,13 @@ xq.Editor = Class.create({
if(key == "undo") undoPerformed = true;
}
- } else if(["mouseup", "keyup"].include(e.type)) {
+ } else if(["mouseup", "keyup"].indexOf(e.type) != -1) {
modifiedByCorrection = this.rdom.correctParagraph();
- } else if(["contextmenu"].include(e.type)) {
+ } else if(["contextmenu"].indexOf(e.type) != -1) {
this._handleContextMenu(e);
}
- if(stop) Event.stop(e);
+ if(stop) xq.stopEvent(e);
this._fireOnCurrentContentChanged(this);
this._fireOnAfterEvent(this, e);
@@ -1335,8 +1635,8 @@ xq.Editor = Class.create({
* TODO: remove dup with handleAutocorrection
*/
handleAutocompletion: function() {
- var acs = $H(this.config.autocompletions);
- if(acs.size() == 0) return;
+ var acs = this.config.autocompletions;
+ if(xq.isEmptyHash(acs)) return;
if(this.rdom.hasSelection()) {
var text = this.rdom.getSelectionAsText();
@@ -1345,41 +1645,58 @@ xq.Editor = Class.create({
wrapper.innerHTML = text;
var marker = this.rdom.pushMarker();
-
- var filtered =
- acs.map(function(pair) {
- return [pair.key, pair.value.criteria(text)];
- }.bind(this)).findAll(function(elem) {
- return elem[1] != -1;
- }).sortBy(function(elem) {
- return elem[1];
- });
+ var filtered = [];
+ for(var key in acs) {
+ filtered.push([key, acs[key].criteria(text)]);
+ }
+ filtered = filtered.findAll(function(elem) {
+ return elem[1] != -1;
+ });
+
if(filtered.length == 0) {
this.rdom.popMarker(true);
return;
}
- var ac = acs.get(filtered[0][0]);
+
+ var minIndex = 0;
+ var min = filtered[0][1];
+ for(var i = 0; i < filtered.length; i++) {
+ if(filtered[i][1] < min) {
+ minIndex = i;
+ min = filtered[i][1];
+ }
+ }
+
+ var ac = acs[filtered[minIndex][0]];
this.editHistory.disable();
} else {
var marker = this.rdom.pushMarker();
-
- var filtered =
- acs.map(function(pair) {
- return [pair.key, this.rdom.testSmartWrap(marker, pair.value.criteria).textIndex];
- }.bind(this)).findAll(function(elem) {
- return elem[1] != -1;
- }).sortBy(function(elem) {
- return elem[1];
- });
+
+ var filtered = [];
+ for(var key in acs) {
+ filtered.push([key, this.rdom.testSmartWrap(marker, acs[key].criteria).textIndex]);
+ }
+ filtered = filtered.findAll(function(elem) {
+ return elem[1] != -1;
+ });
if(filtered.length == 0) {
this.rdom.popMarker(true);
return;
}
- var ac = acs.get(filtered[0][0]);
+ var minIndex = 0;
+ var min = filtered[0][1];
+ for(var i = 0; i < filtered.length; i++) {
+ if(filtered[i][1] < min) {
+ minIndex = i;
+ min = filtered[i][1];
+ }
+ }
+
+ var ac = acs[filtered[minIndex][0]];
this.editHistory.disable();
@@ -1405,7 +1722,6 @@ xq.Editor = Class.create({
try {
this.rdom.unwrapElement(wrapper);
} catch(ignored) {}
-
if(this.rdom.isEmptyBlock(block)) this.rdom.correctEmptyElement(block);
@@ -1701,7 +2017,7 @@ xq.Editor = Class.create({
var rtable = new xq.RichTable(this.rdom, table);
var target = null;
- if(["next", "prev"].include(dir)) {
+ if(["next", "prev"].indexOf(dir) != -1) {
var toNext = dir == "next";
target = toNext ? rtable.getNextCellOf(cell) : rtable.getPreviousCellOf(cell);
} else {
@@ -1710,7 +2026,7 @@ xq.Editor = Class.create({
}
if(!target) {
- var finder = function(node) {return !['TD', 'TH'].include(node.nodeName) && this.tree.isBlock(node) && !this.tree.hasBlocks(node);}.bind(this.rdom);
+ var finder = function(node) {return ['TD', 'TH'].indexOf(node.nodeName) == -1 && this.tree.isBlock(node) && !this.tree.hasBlocks(node);}.bind(this.rdom);
var exitCondition = function(node) {return this.tree.isBlock(node) && !this.tree.isDescendantOf(this.getRoot(), node)}.bind(this.rdom);
target = (toNext || toBelow) ?
@@ -2161,24 +2477,26 @@ xq.Editor = Class.create({
_handleContextMenu: function(e) {
if (xq.Browser.isWebkit) {
- if (e.metaKey || Event.isLeftClick(e)) return false;
+ if (e.metaKey || xq.isLeftClick(e)) return false;
} else if (e.shiftKey || e.ctrlKey || e.altKey) {
return false;
}
- var x=Event.pointerX(e);
- var y=Event.pointerY(e);
- var pos=Position.cumulativeOffset(this.getFrame());
- x+=pos[0];
- y+=pos[1];
+ var point = xq.getEventPoint(e);
+ var x = point.x;
+ var y = point.y;
+
+ var pos = xq.getCumulativeOffset(this.getFrame());
+ x += pos.left;
+ y += pos.top;
this._contextMenuTargetElement = e.target || e.srcElement;
//TODO: Safari on Windows doesn't work with context key(app key)
if (!x || !y || xq.Browser.isTrident) {
- var pos = Position.cumulativeOffset(this._contextMenuTargetElement);
- var posFrame = Position.cumulativeOffset(this.getFrame());
- x = pos[0] + posFrame[0] - this.getDoc().documentElement.scrollLeft;
- y = pos[1] + posFrame[1] - this.getDoc().documentElement.scrollTop;
+ var pos = xq.getCumulativeOffset(this._contextMenuTargetElement);
+ var posFrame = xq.getCumulativeOffset(this.getFrame());
+ x = pos.left + posFrame.left - this.getDoc().documentElement.scrollLeft;
+ y = pos.top + posFrame.top - this.getDoc().documentElement.scrollTop;
}
if (!xq.Browser.isTrident) {
@@ -2197,7 +2515,7 @@ xq.Editor = Class.create({
for(var cmh in this.config.contextMenuHandlers) {
var stop = this.config.contextMenuHandlers[cmh].handler(this, this._contextMenuTargetElement, x, y);
if(stop) {
- Event.stop(e);
+ xq.stopEvent(e);
return true;
}
}
@@ -2213,8 +2531,8 @@ xq.Editor = Class.create({
this._contextMenuContainer.className = 'xqContextMenu';
this._contextMenuContainer.style.display='none';
- Event.observe(this.doc, 'click', this._contextMenuClicked.bindAsEventListener(this));
- Event.observe(this.rdom.getDoc(), 'click', this.hideContextMenu.bindAsEventListener(this));
+ xq.observe(this.doc, 'click', this._contextMenuClicked.bindAsEventListener(this));
+ xq.observe(this.rdom.getDoc(), 'click', this.hideContextMenu.bindAsEventListener(this));
this.body.appendChild(this._contextMenuContainer);
} else {
@@ -2267,7 +2585,10 @@ xq.Editor = Class.create({
if (!this._contextMenuContainer) return;
- var node = Event.findElement(e, 'LI');
+ var node = e.srcElement || e.target;
+ while(node && node.nodeName != "LI") {
+ node = node.parentNode;
+ }
if (!node || !this.rdom.tree.isDescendantOf(this._contextMenuContainer, node)) return;
for (var i=0; i < this._contextMenuItems.length; i++) {
@@ -2312,9 +2633,10 @@ xq.Editor = Class.create({
_processTemplate: function(html) {
// apply template processors
- var tps = $H(this.getTemplateProcessors()).values();
- for(var i = 0; i < tps.length; i++) {
- html = tps[i].handler(html);
+ var tps = this.getTemplateProcessors();
+ for(var key in tps) {
+ var value = tps[key];
+ html = value.handler(html);
}
// remove all whitespace characters between block tags
@@ -2374,8 +2696,10 @@ xq.Browser = {
isIE6: navigator.userAgent.indexOf('MSIE 6') != -1,
isIE7: navigator.userAgent.indexOf('MSIE 7') != -1
};
-xq.Shortcut = Class.create({
+xq.Shortcut = xq.Class({
initialize: function(keymapOrExpression) {
+ xq.addToFinalizeQueue(this);
+
this.keymap = (typeof keymapOrExpression == "string") ?
xq.Shortcut.interprete(keymapOrExpression).keymap :
keymapOrExpression;
@@ -2506,8 +2830,9 @@ xq.Shortcut._keyNames =
*
* TODO: Add specs
*/
-xq.DomTree = Class.create({
+xq.DomTree = xq.Class({
initialize: function() {
+ xq.addToFinalizeQueue(this);
this._blockTags = ["DIV", "DD", "LI", "ADDRESS", "CAPTION", "DT", "H1", "H2", "H3", "H4", "H5", "H6", "HR", "P", "BODY", "BLOCKQUOTE", "PRE", "PARAM", "DL", "OL", "UL", "TABLE", "THEAD", "TBODY", "TR", "TH", "TD"];
this._blockContainerTags = ["DIV", "DD", "LI", "BODY", "BLOCKQUOTE", "UL", "OL", "DL", "TABLE", "THEAD", "TBODY", "TR", "TH", "TD"];
this._listContainerTags = ["OL", "UL", "DL"];
@@ -2590,6 +2915,7 @@ xq.DomTree = Class.create({
var left = findLeft(element);
var right = findRight(element);
+
return [left == element ? null : left, right == element ? null : right];
},
@@ -2782,17 +3108,17 @@ xq.DomTree = Class.create({
isBlockOnlyContainer: function(element) {
if(!element) return false;
- return this._blockOnlyContainerTags.include(typeof element == 'string' ? element : element.nodeName);
+ return this._blockOnlyContainerTags.indexOf(typeof element == 'string' ? element : element.nodeName) != -1;
},
isTableCell: function(element) {
if(!element) return false;
- return this._tableCellTags.include(typeof element == 'string' ? element : element.nodeName);
+ return this._tableCellTags.indexOf(typeof element == 'string' ? element : element.nodeName) != -1;
},
isBlockContainer: function(element) {
if(!element) return false;
- return this._blockContainerTags.include(typeof element == 'string' ? element : element.nodeName);
+ return this._blockContainerTags.indexOf(typeof element == 'string' ? element : element.nodeName) != -1;
},
isHeading: function(element) {
@@ -2802,17 +3128,17 @@ xq.DomTree = Class.create({
isBlock: function(element) {
if(!element) return false;
- return this._blockTags.include(typeof element == 'string' ? element : element.nodeName);
+ return this._blockTags.indexOf(typeof element == 'string' ? element : element.nodeName) != -1;
},
isAtomic: function(element) {
if(!element) return false;
- return this._atomicTags.include(typeof element == 'string' ? element : element.nodeName);
+ return this._atomicTags.indexOf(typeof element == 'string' ? element : element.nodeName) != -1;
},
isListContainer: function(element) {
if(!element) return false;
- return this._listContainerTags.include(typeof element == 'string' ? element : element.nodeName);
+ return this._listContainerTags.indexOf(typeof element == 'string' ? element : element.nodeName) != -1;
},
isTextOrInlineNode: function(node) {
@@ -2824,13 +3150,15 @@ xq.DomTree = Class.create({
*
* RichDom provides basic CRUD + Advanced DOM manipulation API, various query methods and caret/selection management API
*/
-xq.RichDom = Class.create({
+xq.RichDom = xq.Class({
/**
* Initialize RichDom. Target window and root element should be set after initialization. See setWin and setRoot.
*
* @constructor
*/
initialize: function() {
+ xq.addToFinalizeQueue(this);
+
/**
* {xq.DomTree} instance of DomTree
*/
@@ -2921,7 +3249,7 @@ xq.RichDom = Class.create({
* @param {Object} map key-value pairs
*/
setAttributes: function(element, map) {
- for(key in map) element.setAttribute(key, map[key]);
+ for(var key in map) element.setAttribute(key, map[key]);
},
/**
@@ -3023,8 +3351,8 @@ xq.RichDom = Class.create({
*/
insertNodeAt: function(node, target, where, performValidation) {
if(
- ["HTML", "HEAD"].include(target.nodeName) ||
- ["BODY"].include(target.nodeName) && ["before", "after"].include(where)
+ ["HTML", "HEAD"].indexOf(target.nodeName) != -1 ||
+ "BODY" == target.nodeName && ["before", "after"].indexOf(where) != -1
) throw "Illegal argument. Cannot move node[" + node.nodeName + "] to '" + where + "' of target[" + target.nodeName + "]"
var object;
@@ -3217,7 +3545,10 @@ xq.RichDom = Class.create({
// find textnode and break-point
var nodeIndex = 0;
- var nodeValues = textNodes.pluck("nodeValue");
+ var nodeValues = [];
+ for(var i = 0; i < textNodes.length; i++) {
+ nodeValues.push(textNodes[i].nodeValue);
+ }
var textToWrap = nodeValues.join("");
var textIndex = criteria(textToWrap)
var breakPoint = textIndex;
@@ -3531,13 +3862,16 @@ xq.RichDom = Class.create({
var elements = this.getBlockElementsBetween(from, to);
for(var i = 0; i < elements.length; i++) {
if(this.tree.isBlockContainer(elements[i])) {
- applied.push(this.wrapAllInlineOrTextNodesAs(tagName, elements[i], true));
+ var wrappers = this.wrapAllInlineOrTextNodesAs(tagName, elements[i], true);
+ for(var j = 0; j < wrappers.length; j++) {
+ applied.push(wrappers[j]);
+ }
} else {
applied.push(this.replaceTag(tagName, elements[i]));
}
}
}
- return applied.flatten();
+ return applied;
},
/**
@@ -3564,7 +3898,7 @@ xq.RichDom = Class.create({
if(target) {
var singleNodeLi = target.nodeName == 'LI' && ((target.childNodes.length == 1 && this.tree.isBlock(target.firstChild)) || !this.tree.hasBlocks(target));
- var table = ['TABLE', 'TR'].include(target.nodeName);
+ var table = ['TABLE', 'TR'].indexOf(target.nodeName) != -1;
where = this.tree.isBlockContainer(target) && !singleNodeLi && !table ? "end" : "before";
} else if(block.parentNode != this.getRoot()) {
@@ -3576,7 +3910,7 @@ xq.RichDom = Class.create({
if(target) {
var singleNodeLi = target.nodeName == 'LI' && ((target.childNodes.length == 1 && this.tree.isBlock(target.firstChild)) || !this.tree.hasBlocks(target));
- var table = ['TABLE', 'TR'].include(target.nodeName);
+ var table = ['TABLE', 'TR'].indexOf(target.nodeName) != -1;
where = this.tree.isBlockContainer(target) && !singleNodeLi && !table ? "start" : "after";
} else if(block.parentNode != this.getRoot()) {
@@ -3588,7 +3922,7 @@ xq.RichDom = Class.create({
// no way to go?
if(!target) return null;
- if(["TBODY", "THEAD"].include(target.nodeName)) return null;
+ if(["TBODY", "THEAD"].indexOf(target.nodeName) != -1) return null;
// normalize
this.wrapAllInlineOrTextNodesAs("P", target, true);
@@ -3618,6 +3952,8 @@ xq.RichDom = Class.create({
}
}
+ this.correctEmptyElement(moved);
+
return moved;
},
@@ -3714,7 +4050,7 @@ xq.RichDom = Class.create({
* Split container of element into (maxium) three pieces.
*/
splitContainerOf: function(element, preserveElementItself, dir) {
- if([element, element.parentNode].include(this.getRoot())) return element;
+ if([element, element.parentNode].indexOf(this.getRoot()) != -1) return element;
var container = element.parentNode;
if(element.previousSibling && (!dir || dir.toLowerCase() == "prev")) {
@@ -3746,7 +4082,7 @@ xq.RichDom = Class.create({
*/
splitParentElement: function(seperator) {
var parent = seperator.parentNode;
- if(["HTML", "HEAD", "BODY"].include(parent.nodeName)) throw "Illegal argument. Cannot seperate element[" + parent.nodeName + "]";
+ if(["HTML", "HEAD", "BODY"].indexOf(parent.nodeName) != -1) throw "Illegal argument. Cannot seperate element[" + parent.nodeName + "]";
var previousSibling = seperator.previousSibling;
var nextSibling = seperator.nextSibling;
@@ -3824,8 +4160,8 @@ xq.RichDom = Class.create({
try {
var containersAreTableCell =
- prevContainer && (this.tree.isTableCell(prevContainer) || ['TR', 'THEAD', 'TBODY'].include(prevContainer.nodeName)) &&
- nextContainer && (this.tree.isTableCell(nextContainer) || ['TR', 'THEAD', 'TBODY'].include(nextContainer.nodeName));
+ prevContainer && (this.tree.isTableCell(prevContainer) || ['TR', 'THEAD', 'TBODY'].indexOf(prevContainer.nodeName) != -1) &&
+ nextContainer && (this.tree.isTableCell(nextContainer) || ['TR', 'THEAD', 'TBODY'].indexOf(nextContainer.nodeName) != -1);
if(containersAreTableCell && prevContainer != nextContainer) return null;
@@ -3964,7 +4300,7 @@ xq.RichDom = Class.create({
* @param {Elemet} to target element
*/
moveChildNodes: function(from, to) {
- if(this.tree.isDescendantOf(from, to) || ["HTML", "HEAD"].include(to.nodeName))
+ if(this.tree.isDescendantOf(from, to) || ["HTML", "HEAD"].indexOf(to.nodeName) != -1)
throw "Illegal argument. Cannot move children of element[" + from.nodeName + "] to element[" + to.nodeName + "]";
if(from == to) return;
@@ -3988,7 +4324,7 @@ xq.RichDom = Class.create({
for(var i = 0; i < attrs.length; i++) {
if(attrs[i].nodeName == "class" && attrs[i].nodeValue) {
to.className = attrs[i].nodeValue;
- } else if((copyId || !["id"].include(attrs[i].nodeName)) && attrs[i].nodeValue) {
+ } else if((copyId || "id" != attrs[i].nodeName) && attrs[i].nodeValue) {
to.setAttribute(attrs[i].nodeName, attrs[i].nodeValue);
}
}
@@ -4017,7 +4353,7 @@ xq.RichDom = Class.create({
}
}
- var children=$A(node.childNodes);
+ var children=xq.$A(node.childNodes);
for (var i=0; i < children.length; i++)
this._indentElements(children[i], blocks, affect);
return;
@@ -4036,7 +4372,7 @@ xq.RichDom = Class.create({
return [affected];
}
- var children = $A(top.parent.childNodes);
+ var children = xq.$A(top.parent.childNodes);
for (var i=0; i < children.length; i++) {
this._indentElements(children[i], blocks, affect);
}
@@ -4069,7 +4405,7 @@ xq.RichDom = Class.create({
}
if (blocks.include(node)) {
- var children = $A(node.parentNode.childNodes);
+ var children = xq.$A(node.parentNode.childNodes);
var isCode = this.outdentElementsCode(node);
var affected = this.outdentElement(node, true, isCode);
if (affected) {
@@ -4084,7 +4420,7 @@ xq.RichDom = Class.create({
}
}
- var children=$A(node.childNodes);
+ var children=xq.$A(node.childNodes);
for (var i=0; i < children.length; i++)
this._outdentElements(children[i], blocks, affect);
return;
@@ -4108,7 +4444,7 @@ xq.RichDom = Class.create({
return [affected];
}
- var children = $A(top.parent.childNodes);
+ var children = xq.$A(top.parent.childNodes);
for (var i=0; i < children.length; i++) {
this._outdentElements(children[i], blocks, affect);
}
@@ -4299,10 +4635,9 @@ xq.RichDom = Class.create({
},
justifyBlocks: function(blocks, dir) {
- blocks.each(function(block) {
- this.justifyBlock(block, dir);
- }.bind(this));
-
+ for(var i = 0; i < blocks.length; i++) {
+ this.justifyBlock(blocks[i], dir);
+ }
return blocks;
},
@@ -4466,7 +4801,7 @@ xq.RichDom = Class.create({
return null;
},
wrapBlock: function(tag, start, end) {
- if(!this.tree._blockTags.include(tag)) throw "Unsuppored block container: [" + tag + "]";
+ if(this.tree._blockTags.indexOf(tag) == -1) throw "Unsuppored block container: [" + tag + "]";
if(!start) start = this.getCurrentBlockElement();
if(!end) end = start;
@@ -4782,18 +5117,19 @@ xq.RichDom = Class.create({
if(!found) found = [];
var regexp = /^h[1-6]/ig;
-
- if (!element.childNodes) return [];
- $A(element.childNodes).each(function(child) {
- var isContainer = child && this.tree._blockContainerTags.include(child.nodeName);
- var isHeading = child && child.nodeName.match(regexp);
+ var nodes = element.childNodes;
+ if (!nodes) return [];
+
+ for(var i = 0; i < nodes.length; i++) {
+ var isContainer = nodes[i] && this.tree._blockContainerTags.indexOf(nodes[i].nodeName) != -1;
+ var isHeading = nodes[i] && nodes[i].nodeName.match(regexp);
if (isContainer) {
- this.searchHeadings(child, found);
+ this.searchHeadings(nodes[i], found);
} else if (isHeading) {
- found.push(child);
+ found.push(nodes[i]);
}
- }.bind(this));
+ }
return found;
},
@@ -4808,6 +5144,10 @@ xq.RichDom = Class.create({
if(!element || element.nodeName == "#document") return {};
var block = this.getParentBlockElementOf(element);
+
+ // IE���� ��Ȥ DOM�� �� ��: element�� ���ڷ� �Ѿ�4?��찡�?
+ if(block == null) return {};
+
var parents = this.tree.collectParentsOf(element, true, function(node) {return block.parentNode == node});
var blockName = block.nodeName;
@@ -4848,37 +5188,6 @@ xq.RichDom = Class.create({
};
},
- /**
- * Find elements by CSS selector.
- *
- * WARNING: Use this method carefully since prototype.js doesn't work well with designMode DOM.
- */
- findBySelector: function(selector) {
- return Element.getElementsBySelector(this.root, selector);
- },
-
- /**
- * Find elements by attribute.
- *
- * This method will be deprecated when findBySelector get stabilized.
- */
- findByAttribute: function(name, value) {
- var nodes = [];
- this._findByAttribute(nodes, this.root, name, value);
- return nodes;
- },
-
- /** @private */
- _findByAttribute: function(nodes, element, name, value) {
- if(element.getAttribute(name) == value) nodes.push(element);
- if(!element.hasChildNodes()) return;
-
- var children = element.childNodes;
- for(var i = 0; i < children.length; i++) {
- if(children[i].nodeType == 1) this._findByAttribute(nodes, children[i], name, value);
- }
- },
-
/**
* Checks if the element has one or more important attributes: id, class, style
*
@@ -4921,7 +5230,7 @@ xq.RichDom = Class.create({
*/
getParentBlockElementOf: function(element) {
while(element) {
- if(this.tree._blockTags.include(element.nodeName)) return element;
+ if(this.tree._blockTags.indexOf(element.nodeName) != -1) return element;
element = element.parentNode;
}
return null;
@@ -4938,7 +5247,7 @@ xq.RichDom = Class.create({
*/
getParentElementOf: function(element, tagNames) {
while(element) {
- if(tagNames.include(element.nodeName)) return element;
+ if(tagNames.indexOf(element.nodeName) != -1) return element;
element = element.parentNode;
}
return null;
@@ -5017,11 +5326,8 @@ xq.RichDom = Class.create({
getFirstChild: function(element) {
if(!element) return null;
- var nodes = $A(element.childNodes);
- for(var i = 0; i < nodes.length; i++) {
- if(!this.isEmptyTextNode(nodes[i])) return nodes[i];
- }
- return null;
+ var nodes = xq.$A(element.childNodes);
+ return nodes.find(function(node) {return !this.isEmptyTextNode(node)}.bind(this));
},
/**
@@ -5076,7 +5382,7 @@ xq.RichDom.createInstance = function() {
/**
* RichDom for W3C Standard Engine
*/
-xq.RichDomW3 = Class.create(xq.RichDom, {
+xq.RichDomW3 = xq.Class(xq.RichDom, {
insertNode: function(node) {
var rng = this.rng();
rng.insertNode(node);
@@ -5317,7 +5623,7 @@ xq.RichDomW3 = Class.create(xq.RichDom, {
getLastChild: function(element) {
if(!element || !element.hasChildNodes()) return null;
- var nodes = $A(element.childNodes).reverse();
+ var nodes = xq.$A(element.childNodes).reverse();
for(var i = 0; i < nodes.length; i++) {
if(!this.isPlaceHolder(nodes[i]) && !this.isEmptyTextNode(nodes[i])) return nodes[i];
@@ -5450,7 +5756,7 @@ xq.RichDomW3 = Class.create(xq.RichDom, {
/**
* RichDom for Gecko
*/
-xq.RichDomGecko = Class.create(xq.RichDomW3, {
+xq.RichDomGecko = xq.Class(xq.RichDomW3, {
makePlaceHolder: function() {
var holder = this.createElement("BR");
holder.setAttribute("type", "_moz");
@@ -5496,7 +5802,7 @@ xq.RichDomGecko = Class.create(xq.RichDomW3, {
/**
* RichDom for Webkit
*/
-xq.RichDomWebkit = Class.create(xq.RichDomW3, {
+xq.RichDomWebkit = xq.Class(xq.RichDomW3, {
makePlaceHolder: function() {
var holder = this.createElement("BR");
holder.className = "webkit-block-placeholder";
@@ -5580,7 +5886,7 @@ xq.RichDomWebkit = Class.create(xq.RichDomW3, {
/**
* RichDom for Internet Explorer 6 and 7
*/
-xq.RichDomTrident = Class.create(xq.RichDom, {
+xq.RichDomTrident = xq.Class(xq.RichDom, {
makePlaceHolder: function() {
return this.createTextNode(" ");
},
@@ -5621,7 +5927,7 @@ xq.RichDomTrident = Class.create(xq.RichDom, {
var text = block.innerText;
var lastCharCode = text.charCodeAt(text.length - 1);
- if(text.length <= 1 || ![32,160].include(lastCharCode)) return;
+ if(text.length <= 1 || [32,160].indexOf(lastCharCode) == -1) return;
var node = block;
@@ -5682,10 +5988,14 @@ xq.RichDomTrident = Class.create(xq.RichDom, {
block,
function(node) {return this.tree.isBlock(node) && !this.tree.isBlockOnlyContainer(node)}.bind(this)
);
+
if(nextBlock) {
this.deleteNode(block);
this.placeCaretAtStartOf(nextBlock);
+ } else {
+ this.placeCaretAtStartOf(block);
}
+
return true;
}
} else {
@@ -5837,7 +6147,7 @@ xq.RichDomTrident = Class.create(xq.RichDom, {
isEmptyBlock: function(element) {
if(!element.hasChildNodes()) return true;
if(element.nodeType == 3 && !element.nodeValue) return true;
- if([" ", " ", ""].include(element.innerHTML)) return true;
+ if([" ", " ", ""].indexOf(element.innerHTML) != -1) return true;
return false;
},
@@ -5845,7 +6155,7 @@ xq.RichDomTrident = Class.create(xq.RichDom, {
getLastChild: function(element) {
if(!element || !element.hasChildNodes()) return null;
- var nodes = $A(element.childNodes).reverse();
+ var nodes = xq.$A(element.childNodes).reverse();
for(var i = 0; i < nodes.length; i++) {
if(nodes[i].nodeType != 3 || nodes[i].nodeValue.length != 0) return nodes[i];
@@ -5938,8 +6248,10 @@ xq.RichDomTrident = Class.create(xq.RichDom, {
bookmark.select();
}
});
-xq.RichTable = Class.create({
+xq.RichTable = xq.Class({
initialize: function(rdom, table) {
+ xq.addToFinalizeQueue(this);
+
this.rdom = rdom;
this.table = table;
},
@@ -6087,9 +6399,11 @@ xq.RichTable = Class.create({
return this.table.tBodies[0].rows[0].cells[0].nodeName == "TH";
},
correctEmptyCells: function() {
- var cells = $A(this.table.getElementsByTagName("TH"));
- cells.push($A(this.table.getElementsByTagName("TD")));
- cells = cells.flatten();
+ var cells = xq.$A(this.table.getElementsByTagName("TH"));
+ var tds = xq.$A(this.table.getElementsByTagName("TD"));
+ for(var i = 0; i < tds.length; i++) {
+ cells.push(tds[i]);
+ }
for(var i = 0; i < cells.length; i++) {
if(this.rdom.isEmptyBlock(cells[i])) this.rdom.correctEmptyElement(cells[i])
@@ -6098,8 +6412,8 @@ xq.RichTable = Class.create({
});
xq.RichTable.create = function(rdom, cols, rows, headerPositions) {
- if(["t", "tl", "lt"].include(headerPositions)) var headingAtTop = true
- if(["l", "tl", "lt"].include(headerPositions)) var headingAtLeft = true
+ if(["t", "tl", "lt"].indexOf(headerPositions) != -1) var headingAtTop = true
+ if(["l", "tl", "lt"].indexOf(headerPositions) != -1) var headingAtLeft = true
var sb = []
sb.push('')
@@ -6143,8 +6457,10 @@ xq.RichTable.create = function(rdom, cols, rows, headerPositions) {
/**
* Validates and invalidates designmode contents
*/
-xq.Validator = Class.create({
+xq.Validator = xq.Class({
initialize: function(curUrl, urlValidationMode, allowedTags, allowedAttrs) {
+ xq.addToFinalizeQueue(this);
+
this.allowedTags = (allowedTags || ['a', 'abbr', 'acronym', 'address', 'blockquote', 'br', 'caption', 'cite', 'code', 'dd', 'dfn', 'div', 'dl', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'hr', 'img', 'kbd', 'li', 'ol', 'p', 'pre', 'q', 'samp', 'span', 'sup', 'sub', 'strong', 'table', 'thead', 'tbody', 'td', 'th', 'tr', 'ul', 'var']).join(' ') + ' ';
this.allowedAttrs = (allowedAttrs || ['alt', 'cite', 'class', 'datetime', 'height', 'href', 'id', 'rel', 'rev', 'src', 'style', 'title', 'width']).join(' ') + ' ';
@@ -6198,7 +6514,7 @@ xq.Validator = Class.create({
},
removeDangerousElements: function(element) {
- var scripts = $A(element.getElementsByTagName('SCRIPT')).reverse();
+ var scripts = xq.$A(element.getElementsByTagName('SCRIPT')).reverse();
for(var i = 0; i < scripts.length; i++) {
scripts[i].parentNode.removeChild(scripts[i]);
}
@@ -6370,7 +6686,7 @@ xq.Validator.createInstance = function(curUrl, urlValidationMode, allowedTags, a
/**
* Validator for W3C Standard Engine
*/
-xq.ValidatorW3 = Class.create(xq.Validator, {
+xq.ValidatorW3 = xq.Class(xq.Validator, {
validate: function(element, fullValidation) {
element = element.cloneNode(true);
@@ -6405,15 +6721,15 @@ xq.ValidatorW3 = Class.create(xq.Validator, {
rdom.setRoot(element);
// ->
- var strikes = rdom.findByAttribute("class", "strike");
+ var strikes = xq.getElementsByClassName(rdom.getRoot(), "strike");
for(var i = 0; i < strikes.length; i++) {
if("SPAN" == strikes[i].nodeName) rdom.replaceTag("strike", strikes[i]).removeAttribute("class");
}
// ->
- var underlines = rdom.findByAttribute("class", "underline");
+ var underlines = xq.getElementsByClassName(rdom.getRoot(), "underline");
for(var i = 0; i < underlines.length; i++) {
- if(["EM", "I"].include(underlines[i].nodeName)) rdom.replaceTag("u", underlines[i]).removeAttribute("class");
+ if(["EM", "I"].indexOf(underlines[i].nodeName) != -1) rdom.replaceTag("u", underlines[i]).removeAttribute("class");
}
var content = rdom.getRoot().innerHTML;
@@ -6445,7 +6761,7 @@ xq.ValidatorW3 = Class.create(xq.Validator, {
var rdom = xq.RichDom.createInstance();
rdom.setRoot(element);
- var fonts = $A(element.getElementsByTagName('FONT')).reverse();
+ var fonts = xq.$A(element.getElementsByTagName('FONT')).reverse();
for(var i = 0; i < fonts.length; i++) {
var font = fonts[i];
var color = font.getAttribute('color');
@@ -6474,12 +6790,12 @@ xq.ValidatorW3 = Class.create(xq.Validator, {
/**
* Validator for Gecko Engine
*/
-xq.ValidatorGecko = Class.create(xq.ValidatorW3, {
+xq.ValidatorGecko = xq.Class(xq.ValidatorW3, {
});
/**
* Validator for Webkit
*/
-xq.ValidatorWebkit = Class.create(xq.ValidatorW3, {
+xq.ValidatorWebkit = xq.Class(xq.ValidatorW3, {
});
/*
@@ -6493,7 +6809,7 @@ if(node.nodeName == "SPAN" && node.className == "Apple-style-span" && node.style
/**
* Validator for Internet Explorer 6 and 7
*/
-xq.ValidatorTrident = Class.create(xq.Validator, {
+xq.ValidatorTrident = xq.Class(xq.Validator, {
validate: function(element, fullValidation) {
element = element.cloneNode(true);
@@ -6521,15 +6837,15 @@ xq.ValidatorTrident = Class.create(xq.Validator, {
this.invalidateBackgroundColor(element);
// ->
- var strikes = rdom.findByAttribute("className", "strike");
+ var strikes = xq.getElementsByClassName(rdom.getRoot(), "strike");
for(var i = 0; i < strikes.length; i++) {
if("SPAN" == strikes[i].nodeName) rdom.replaceTag("strike", strikes[i]).removeAttribute("className");
}
// ->
- var underlines = rdom.findByAttribute("className", "underline");
+ var underlines = xq.getElementsByClassName(rdom.getRoot(), "underline");
for(var i = 0; i < underlines.length; i++) {
- if(["EM", "I"].include(underlines[i].nodeName)) rdom.replaceTag("u", underlines[i]).removeAttribute("className");
+ if(["EM", "I"].indexOf(underlines[i].nodeName) != -1) rdom.replaceTag("u", underlines[i]).removeAttribute("className");
}
var content = rdom.getRoot().innerHTML;
@@ -6562,7 +6878,7 @@ xq.ValidatorTrident = Class.create(xq.Validator, {
rdom.setRoot(element);
// It should be reversed to deal with nested elements
- var fonts = $A(element.getElementsByTagName('FONT')).reverse();
+ var fonts = xq.$A(element.getElementsByTagName('FONT')).reverse();
for(var i = 0; i < fonts.length; i++) {
var font = fonts[i];
var color = font.getAttribute('color');
@@ -6579,7 +6895,7 @@ xq.ValidatorTrident = Class.create(xq.Validator, {
var rdom = xq.RichDom.createInstance();
rdom.setRoot(element);
- var spans = $A(element.getElementsByTagName('SPAN')).reverse();
+ var spans = xq.$A(element.getElementsByTagName('SPAN')).reverse();
for(var i = 0; i < spans.length; i++) {
var span = spans[i];
var color = span.style.color;
@@ -6597,7 +6913,7 @@ xq.ValidatorTrident = Class.create(xq.Validator, {
rdom.setRoot(element);
// It should be reversed to deal with nested elements
- var fonts = $A(element.getElementsByTagName('FONT')).reverse();
+ var fonts = xq.$A(element.getElementsByTagName('FONT')).reverse();
for(var i = 0; i < fonts.length; i++) {
if(fonts[i].style.color || fonts[i].style.backgroundColor) rdom.replaceTag("span", fonts[i]);
}
@@ -6608,7 +6924,7 @@ xq.ValidatorTrident = Class.create(xq.Validator, {
rdom.setRoot(element);
// It should be reversed to deal with nested elements
- var spans = $A(element.getElementsByTagName('SPAN')).reverse();
+ var spans = xq.$A(element.getElementsByTagName('SPAN')).reverse();
for(var i = 0; i < spans.length; i++) {
if(spans[i].style.color || spans[i].style.backgroundColor) rdom.replaceTag("font", spans[i]);
}
@@ -6632,7 +6948,7 @@ xq.ValidatorTrident = Class.create(xq.Validator, {
/**
* @fileOverview xq.EditHistory manages editing history and performs UNDO/REDO.
*/
-xq.EditHistory = Class.create({
+xq.EditHistory = xq.Class({
/**
* Initializer
*
@@ -6641,6 +6957,7 @@ xq.EditHistory = Class.create({
* @param {Number} [max] maximum UNDO buffer size(default value is 100).
*/
initialize: function(rdom, max) {
+ xq.addToFinalizeQueue(this);
if (!rdom) throw "IllegalArgumentException";
this.disabled = false;
@@ -6698,11 +7015,11 @@ xq.EditHistory = Class.create({
// ignore normal keys
if('keydown' == event.type && !(event.ctrlKey || event.metaKey)) return false;
- if(['keydown', 'keyup', 'keypress'].include(event.type) && !event.ctrlKey && !event.altKey && !event.metaKey && ![33,34,35,36,37,38,39,40].include(event.keyCode)) return false;
- if(['keydown', 'keyup', 'keypress'].include(event.type) && (event.ctrlKey || event.metaKey) && [89,90].include(event.keyCode)) return false;
+ if(['keydown', 'keyup', 'keypress'].indexOf(event.type) != -1 && !event.ctrlKey && !event.altKey && !event.metaKey && [33,34,35,36,37,38,39,40].indexOf(event.keyCode) == -1) return false;
+ if(['keydown', 'keyup', 'keypress'].indexOf(event.type) != -1 && (event.ctrlKey || event.metaKey) && [89,90].indexOf(event.keyCode) != -1) return false;
// ignore ctrl/shift/alt/meta keys
- if([16,17,18,224].include(event.keyCode)) return false;
+ if([16,17,18,224].indexOf(event.keyCode) != -1) return false;
return this.pushContent();
},
@@ -6791,7 +7108,7 @@ xq.controls = {};
-xq.controls.FormDialog = Class.create({
+xq.controls.FormDialog = xq.Class({
/**
* @constructor
*
@@ -6799,6 +7116,8 @@ xq.controls.FormDialog = Class.create({
* @param {Function} [onLoadHandler] callback function to be called when the form is loaded
*/
initialize: function(xed, html, onLoadHandler, onCloseHandler) {
+ xq.addToFinalizeQueue(this);
+
this.xed = xed;
this.html = html;
this.onLoadHandler = onLoadHandler || function() {};
@@ -6819,21 +7138,21 @@ xq.controls.FormDialog = Class.create({
var self = this;
// create and append container
- var container = $(document.createElement('DIV'));
+ var container = document.createElement('DIV');
container.style.display = 'none';
document.body.appendChild(container);
// initialize form
container.innerHTML = this.html;
- this.form = $(container.getElementsByTagName('FORM')[0]);
+ this.form = container.getElementsByTagName('FORM')[0];
this.form.onsubmit = function() {
- self.onCloseHandler($(this).serialize(true));
+ self.onCloseHandler(xq.serializeForm(this));
self.close();
return false;
};
- var cancelButton = this.form.getElementsByClassName('cancel')[0];
+ var cancelButton = xq.getElementsByClassName(this.form, 'cancel')[0];
cancelButton.onclick = function() {
self.onCloseHandler();
self.close();
@@ -6847,12 +7166,12 @@ xq.controls.FormDialog = Class.create({
this.setPosition(options.position);
// give focus
- var elementToFocus = this.form.getElementsByClassName('initialFocus');
+ var elementToFocus = xq.getElementsByClassName(this.form, 'initialFocus');
if(elementToFocus.length > 0) elementToFocus[0].focus();
// handle cancelOnEsc option
if(options.cancelOnEsc) {
- Event.observe(this.form, 'keydown', function(e) {
+ xq.observe(this.form, 'keydown', function(e) {
if(e.keyCode == 27) {
this.onCloseHandler();
this.close();
@@ -6863,24 +7182,25 @@ xq.controls.FormDialog = Class.create({
this.onLoadHandler(this);
},
+
close: function() {
this.form.parentNode.removeChild(this.form);
},
+
setPosition: function(target) {
- var targetElement;
- var curleft = curtop = 0;
+ var targetElement = null;
+ var left = 0;
+ var top = 0;
if(target == 'centerOfWindow') {
targetElement = document.documentElement;
} else if(target == 'centerOfEditor') {
targetElement = this.xed.getFrame();
- var obj = targetElement;
- while( obj.offsetParent )
- {
- curleft += obj.offsetLeft;
- curtop += obj.offsetTop;
- obj = obj.offsetParent;
- }
+ var o = targetElement;
+ do {
+ left += o.offsetLeft;
+ top += o.offsetTop;
+ } while(o = o.offsetParent)
} else if(target == 'nearbyCaret') {
throw "Not implemented yet";
} else {
@@ -6892,21 +7212,22 @@ xq.controls.FormDialog = Class.create({
var dialogWidth = this.form.clientWidth;
var dialogHeight = this.form.clientHeight;
- var x = curleft + parseInt((targetWidth - dialogWidth) / 2);
- var y = curtop + parseInt((targetHeight - dialogHeight) / 2);
+ left += parseInt((targetWidth - dialogWidth) / 2);
+ top += parseInt((targetHeight - dialogHeight) / 2);
- this.form.style.left = x + "px";
- this.form.style.top = y + "px";
+ this.form.style.left = left + "px";
+ this.form.style.top = top + "px";
}
})
-xq.controls.QuickSearchDialog = Class.create({
+xq.controls.QuickSearchDialog = xq.Class({
/**
* @constructor
*/
initialize: function(xed, param) {
+ xq.addToFinalizeQueue(this);
this.xed = xed;
this.rdom = xq.RichDom.createInstance();
@@ -6931,7 +7252,7 @@ xq.controls.QuickSearchDialog = Class.create({
}
this.close();
- Event.stop(e);
+ xq.stopEvent(e);
return false;
},
@@ -7018,12 +7339,19 @@ xq.controls.QuickSearchDialog = Class.create({
},
setPosition: function(target) {
- var targetElement;
+ var targetElement = null;
+ var left = 0;
+ var top = 0;
if(target == 'centerOfWindow') {
targetElement = document.documentElement;
} else if(target == 'centerOfEditor') {
- targetElement = this.xed.getDoc().documentElement;
+ targetElement = this.xed.getFrame();
+ var o = targetElement;
+ do {
+ left += o.offsetLeft;
+ top += o.offsetTop;
+ } while(o = o.offsetParent)
} else if(target == 'nearbyCaret') {
throw "Not implemented yet";
} else {
@@ -7035,10 +7363,11 @@ xq.controls.QuickSearchDialog = Class.create({
var dialogWidth = this.container.clientWidth;
var dialogHeight = this.container.clientHeight;
- var x = parseInt((targetWidth - dialogWidth) / 2);
- var y = parseInt((targetHeight - dialogHeight) / 2);
- this.container.style.left = x + "px";
- this.container.style.top = y + "px";
+ left += parseInt((targetWidth - dialogWidth) / 2);
+ top += parseInt((targetHeight - dialogHeight) / 2);
+
+ this.container.style.left = left + "px";
+ this.container.style.top = top + "px";
},
matchCount: function() {
@@ -7071,11 +7400,11 @@ xq.controls.QuickSearchDialog = Class.create({
// make list
var list = this.rdom.createElement("OL");
- Event.observe(input, 'blur', this.onBlur.bindAsEventListener(this));
- Event.observe(input, 'keypress', this.onKey.bindAsEventListener(this));
- Event.observe(list, 'click', this.onClick.bindAsEventListener(this), true);
- Event.observe(form, 'submit', this.onSubmit.bindAsEventListener(this));
- Event.observe(form, 'reset', this.onCancel.bindAsEventListener(this));
+ xq.observe(input, 'blur', this.onBlur.bindAsEventListener(this));
+ xq.observe(input, 'keypress', this.onKey.bindAsEventListener(this));
+ xq.observe(list, 'click', this.onClick.bindAsEventListener(this), true);
+ xq.observe(form, 'submit', this.onSubmit.bindAsEventListener(this));
+ xq.observe(form, 'reset', this.onCancel.bindAsEventListener(this));
container.appendChild(list);
return container;
@@ -7122,7 +7451,7 @@ xq.controls.QuickSearchDialog = Class.create({
var index = this._getSelectedIndex();
var ol = this._getListContainer();
ol.childNodes[index].className = "";
-
+
index++;
if(index >= count) index = 0;