From 941b0a9ba4e673e292510d80a5a86806994b8ea6 Mon Sep 17 00:00:00 2001
From: Jason Woofenden
+ New features:
+ Fixed issues:
New features:
+ CKEditor 3.1
+
+
+
+
+
CKEditor 3.0.2
- Copyright © 2003-2009, CKSource - Frederico + Copyright © 2003-2010, CKSource - Frederico Knabben. All rights reserved.
diff --git a/INSTALL.html b/INSTALL.html index 65e12e3..8cf37f9 100644 --- a/INSTALL.html +++ b/INSTALL.html @@ -1,6 +1,6 @@ @@ -84,7 +84,7 @@ http://www.example.com/ckeditor/_samples/index.html CKEditor - The text editor for Internet - http://ckeditor.com- Copyright © 2003-2009, CKSource - Frederico + Copyright © 2003-2010, CKSource - Frederico Knabben. All rights reserved.
diff --git a/LICENSE.html b/LICENSE.html index 7d53df4..ecbe06e 100644 --- a/LICENSE.html +++ b/LICENSE.html @@ -7,7 +7,7 @@ Software License Agreement ========================== CKEditor - The text editor for Internet - http://ckeditor.com -Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. +Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. Licensed under the terms of any of the following licenses at your choice: @@ -1286,7 +1286,7 @@ EXHIBIT A -Mozilla Public License.
CKEditor™ - The text editor for Internet™ -
http://ckeditor.com
- Copyright © 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+ Copyright © 2003-2010, CKSource - Frederico Knabben. All rights reserved.
Licensed under the terms of any of the following licenses at your choice: diff --git a/_samples/ajax.html b/_samples/ajax.html index d2ce3bd..931f58b 100644 --- a/_samples/ajax.html +++ b/_samples/ajax.html @@ -1,16 +1,16 @@
-
+
+
+
+ +
+ diff --git a/_samples/replacebycode.html b/_samples/replacebycode.html index dfcafdc..bd3f54d 100644 --- a/_samples/replacebycode.html +++ b/_samples/replacebycode.html @@ -1,15 +1,15 @@ -+ +
+ diff --git a/_samples/sample.css b/_samples/sample.css index 3796509..cee85e8 100644 --- a/_samples/sample.css +++ b/_samples/sample.css @@ -1,5 +1,5 @@ /* -Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. +Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. For licensing, see LICENSE.html or http://ckeditor.com/license */ diff --git a/_samples/sample.js b/_samples/sample.js index 7c13452..f7c023c 100644 --- a/_samples/sample.js +++ b/_samples/sample.js @@ -1,5 +1,5 @@ /* -Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. +Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. For licensing, see LICENSE.html or http://ckeditor.com/license */ @@ -7,13 +7,6 @@ For licensing, see LICENSE.html or http://ckeditor.com/license // It is just a helper file that displays a red message about browser compatibility // at the top of the samples (if incompatible browser is detected). -// Firebug has been presented some bugs with console. It must be "initialized" -// before the page load to work. -// FIXME: Remove the following in the future, if Firebug gets fixed. -if ( typeof console != 'undefined' ) - console.log(); - - if ( window.CKEDITOR ) { (function() @@ -51,7 +44,8 @@ if ( window.CKEDITOR ) html += 'With non compatible browsers, you should still be able to see and edit the contents (HTML) in a plain text field.
'; - document.getElementById( 'alerts' ).innerHTML = html; + var alertsEl = document.getElementById( 'alerts' ); + alertsEl && ( alertsEl.innerHTML = html ); }; var onload = function() diff --git a/_samples/sample_posteddata.php b/_samples/sample_posteddata.php index 0776001..af20e89 100644 --- a/_samples/sample_posteddata.php +++ b/_samples/sample_posteddata.php @@ -1,7 +1,7 @@ @@ -52,7 +52,7 @@ foreach ( $postArray as $sForm => $value ) CKEditor - The text editor for Internet - http://ckeditor.com- Copyright © 2003-2009, CKSource - Frederico Knabben. All rights reserved. + Copyright © 2003-2010, CKSource - Frederico Knabben. All rights reserved.
diff --git a/_samples/sharedspaces.html b/_samples/sharedspaces.html new file mode 100644 index 0000000..7b32b9f --- /dev/null +++ b/_samples/sharedspaces.html @@ -0,0 +1,131 @@ + + + + +Click the UI Color Picker button to test your color preferences at runtime.
- + //]]> + + ++ +
+ diff --git a/_samples/ui_languages.html b/_samples/ui_languages.html index 69c3706..c610588 100644 --- a/_samples/ui_languages.html +++ b/_samples/ui_languages.html @@ -1,23 +1,16 @@ -W.height-V.height-Q)ac=W.height-V.height+R[2];else ac=N.y;L.move(ab,ac);U.data.preventDefault();};function T(U){a.document.removeListener('mousemove',S);a.document.removeListener('mouseup',T); -if(b.ie6Compat){var V=z.getChild(0).getFrameDocument();V.removeListener('mousemove',S);V.removeListener('mouseup',T);}};L.parts.title.on('mousedown',function(U){L._.updateSize=true;M={x:U.data.$.screenX,y:U.data.$.screenY};a.document.on('mousemove',S);a.document.on('mouseup',T);N=L.getPosition();if(b.ie6Compat){var V=z.getChild(0).getFrameDocument();V.on('mousemove',S);V.on('mouseup',T);}U.data.preventDefault();},L);};function x(L){var M=L.definition,N=M.minWidth||0,O=M.minHeight||0,P=M.resizable,Q=o[L.getParentEditor().skinName].margins||[0,0,0,0];function R(ac,ad){ac.y+=ad;};function S(ac,ad){ac.x2+=ad;};function T(ac,ad){ac.y2+=ad;};function U(ac,ad){ac.x+=ad;};var V=null,W=null,X=L._.editor.config.magnetDistance,Y=['tl','t','tr','l','r','bl','b','br'];function Z(ac){var ad=ac.listenerData.part,ae=L.getSize();W=L.getPosition();e.extend(W,{x2:W.x+ae.width,y2:W.y+ae.height});V={x:ac.data.$.screenX,y:ac.data.$.screenY};a.document.on('mousemove',aa,L,{part:ad});a.document.on('mouseup',ab,L,{part:ad});if(b.ie6Compat){var af=z.getChild(0).getFrameDocument();af.on('mousemove',aa,L,{part:ad});af.on('mouseup',ab,L,{part:ad});}ac.data.preventDefault();};function aa(ac){var ad=ac.data.$.screenX,ae=ac.data.$.screenY,af=ad-V.x,ag=ae-V.y,ah=a.document.getWindow().getViewPaneSize(),ai=ac.listenerData.part;if(ai.search('t')!=-1)R(W,ag);if(ai.search('l')!=-1)U(W,af);if(ai.search('b')!=-1)T(W,ag);if(ai.search('r')!=-1)S(W,af);V={x:ad,y:ae};var aj,ak,al,am;if(W.x+Q[3]ah.width-X)al=ah.width+Q[1];else if(ai.search('r')!=-1&&W.x2-W.x ah.height-X)am=ah.height+Q[2];else if(ai.search('b')!=-1&&W.y2-W.y '];if(b.ie6Compat){var P=b.isCustomDomain(),Q=""; -O.push('');}O.push('');z=h.createFromHtml(O.join(''));}var R=z,S=function(){var W=M.getViewPaneSize();R.setStyles({width:W.width+'px',height:W.height+'px'});},T=function(){var W=M.getScrollPosition(),X=a.dialog._.currentTop;R.setStyles({left:W.x+'px',top:W.y+'px'});do{var Y=X.getPosition();X.move(Y.x,Y.y);}while(X=X._.parentDialog)};y=S;M.on('resize',S);S();if(b.ie6Compat){var U=function(){T();arguments.callee.prevScrollHandler.apply(this,arguments);};M.$.setTimeout(function(){U.prevScrollHandler=window.onscroll||(function(){});window.onscroll=U;},0);T();}var V=L.config.dialog_backgroundCoverOpacity;R.setOpacity(typeof V!='undefined'?V:0.5);R.appendTo(a.document.getBody());},B=function(){if(!z)return;var L=a.document.getWindow();z.remove();L.removeListener('resize',y);if(b.ie6Compat)L.$.setTimeout(function(){var M=window.onscroll&&window.onscroll.prevScrollHandler;window.onscroll=M||null;},0);y=null;},C={},D=function(L){var M=L.data.$.ctrlKey||L.data.$.metaKey,N=L.data.$.altKey,O=L.data.$.shiftKey,P=String.fromCharCode(L.data.$.keyCode),Q=C[(M?'CTRL+':'')+(N?'ALT+':'')+(O?'SHIFT+':'')+P];if(!Q||!Q.length)return;Q=Q[Q.length-1];Q.keydown&&Q.keydown.call(Q.uiElement,Q.dialog,Q.key);L.data.preventDefault();},E=function(L){var M=L.data.$.ctrlKey||L.data.$.metaKey,N=L.data.$.altKey,O=L.data.$.shiftKey,P=String.fromCharCode(L.data.$.keyCode),Q=C[(M?'CTRL+':'')+(N?'ALT+':'')+(O?'SHIFT+':'')+P];if(!Q||!Q.length)return;Q=Q[Q.length-1];if(Q.keyup){Q.keyup.call(Q.uiElement,Q.dialog,Q.key);L.data.preventDefault();}},F=function(L,M,N,O,P){var Q=C[N]||(C[N]=[]);Q.push({uiElement:L,dialog:M,key:N,keyup:P||L.accessKeyUp,keydown:O||L.accessKeyDown});},G=function(L){for(var M in C){var N=C[M];for(var O=N.length-1;O>=0;O--){if(N[O].dialog==L||N[O].uiElement==L)N.splice(O,1);}if(N.length===0)delete C[M];}},H=function(L,M){if(L._.accessKeyMap[M])L.selectPage(L._.accessKeyMap[M]);},I=function(L,M){},J={27:1,13:1},K=function(L){if(L.data.getKeystroke() in J)L.data.stopPropagation();};(function(){k.dialog={uiElement:function(L,M,N,O,P,Q,R){if(arguments.length<4)return;var S=(O.call?O(M):O)||'div',T=['<',S,' '],U=(P&&P.call?P(M):P)||{},V=(Q&&Q.call?Q(M):Q)||{},W=(R&&R.call?R(L,M):R)||'',X=this.domId=V.id||e.getNextNumber()+'_uiElement',Y=this.id=M.id,Z; -V.id=X;var aa={};if(M.type)aa['cke_dialog_ui_'+M.type]=1;if(M.className)aa[M.className]=1;var ab=V['class']&&V['class'].split?V['class'].split(' '):[];for(Z=0;Z =0;Z--){if(ad[Z]==='')ad.splice(Z,1);}if(ad.length>0)V.style=(V.style?V.style+'; ':'')+ad.join('; ');for(Z in V)T.push(Z+'="'+e.htmlEncode(V[Z])+'" ');T.push('>',W,'',S,'>');N.push(T.join(''));(this._||(this._={})).dialog=L;if(typeof M.isChanged=='boolean')this.isChanged=function(){return M.isChanged;};if(typeof M.isChanged=='function')this.isChanged=M.isChanged;a.event.implementOn(this);this.registerEvents(M);if(this.accessKeyUp&&this.accessKeyDown&&M.accessKey)F(this,L,'CTRL+'+M.accessKey);var ae=this;L.on('load',function(){if(ae.getInputElement())ae.getInputElement().on('focus',function(){L._.tabBarMode=false;L._.hasFocus=true;ae.fire('focus');},ae);});if(this.keyboardFocusable){this.focusIndex=L._.focusList.push(this)-1;this.on('focus',function(){L._.currentFocusIndex=ae.focusIndex;});}e.extend(this,M);},hbox:function(L,M,N,O,P){if(arguments.length<4)return;this._||(this._={});var Q=this._.children=M,R=P&&P.widths||null,S=P&&P.height||null,T={},U,V=function(){var W=[' '];for(U=0;U ');return W.join('');};k.dialog.uiElement.call(this,L,P||{type:'hbox'},O,'table',T,P&&P.align&&{align:P.align}||null,V);},vbox:function(L,M,N,O,P){if(arguments.length<3)return;this._||(this._={});var Q=this._.children=M,R=P&&P.width||null,S=P&&P.heights||null,T=function(){var U=['0)W.push('style="'+Y.join('; ')+'" ');W.push('>',N[U],'');}W.push(' ');for(var V=0;V
');return U.join('');};k.dialog.uiElement.call(this,L,P||{type:'vbox'},O,'div',null,null,T);}};})();k.dialog.uiElement.prototype={getElement:function(){return a.document.getById(this.domId);},getInputElement:function(){return this.getElement();},getDialog:function(){return this._.dialog;},setValue:function(L){this.getInputElement().setValue(L);this.fire('change',{value:L});return this;},getValue:function(){return this.getInputElement().getValue();},isChanged:function(){return false;},selectParentTab:function(){var O=this;var L=O.getInputElement(),M=L,N;while((M=M.getParent())&&M.$.className.search('cke_dialog_page_contents')==-1){}if(!M)return O;N=M.getAttribute('name');if(O._.dialog._.currentTabId!=N)O._.dialog.selectPage(N);return O;},focus:function(){this.selectParentTab().getInputElement().focus();return this;},registerEvents:function(L){var M=/^on([A-Z]\w+)/,N,O=function(Q,R,S,T){R.on('load',function(){Q.getInputElement().on(S,T,Q);});};for(var P in L){if(!(N=P.match(M)))continue;if(this.eventProcessors[P])this.eventProcessors[P].call(this,this._.dialog,L[P]);else O(this,this._.dialog,N[1].toLowerCase(),L[P]);}return this;},eventProcessors:{onLoad:function(L,M){L.on('load',M,this);},onShow:function(L,M){L.on('show',M,this);},onHide:function(L,M){L.on('hide',M,this);}},accessKeyDown:function(L,M){this.focus();},accessKeyUp:function(L,M){},disable:function(){var L=this.getInputElement();L.setAttribute('disabled','true');L.addClass('cke_disabled');},enable:function(){var L=this.getInputElement();L.removeAttribute('disabled');L.removeClass('cke_disabled');},isEnabled:function(){return!this.getInputElement().getAttribute('disabled');},isVisible:function(){return this.getInputElement().isVisible();},isFocusable:function(){if(!this.isEnabled()||!this.isVisible())return false;return true;}};k.dialog.hbox.prototype=e.extend(new k.dialog.uiElement(),{getChild:function(L){var M=this;if(arguments.length<1)return M._.children.concat();if(!L.splice)L=[L];if(L.length<2)return M._.children[L[0]];else return M._.children[L[0]]&&M._.children[L[0]].getChild?M._.children[L[0]].getChild(L.slice(1,L.length)):null;}},true); -k.dialog.vbox.prototype=new k.dialog.hbox();(function(){var L={build:function(M,N,O){var P=N.children,Q,R=[],S=[];for(var T=0;T0)U.push('style="',W.join('; '),'" ');U.push(' class="cke_dialog_ui_vbox_child">',N[V],' ');}U.push('';});n.on('themeLoaded',function(){n.fireOnce('editingBlockReady');});n.on('uiReady',function(){n.setMode(n.config.startupMode);});n.on('afterSetData',function(){if(!m){function o(){m=true;l(n).loadData(n.getData());m=false;};if(n.mode)o();else n.on('mode',function(){o();n.removeListener('mode',arguments.callee);});}});n.on('beforeGetData',function(){if(!m&&n.mode){m=true;n.setData(l(n).getData());m=false;}});n.on('getSnapshot',function(o){if(n.mode)o.data=l(n).getSnapshotData();});n.on('loadSnapshot',function(o){if(n.mode)l(n).loadSnapshotData(o.data);});n.on('mode',function(o){o.removeListener();var p=n.container;if(b.webkit&&b.version<528){var q=n.config.tabIndex||n.element.getAttribute('tabindex')||0;p=p.append(h.createFromHtml(''));}p.on('focus',function(){n.focus();});if(n.config.startupFocus)n.focus();setTimeout(function(){n.fireOnce('instanceReady');a.fire('instanceReady',null,n);});});}});a.editor.prototype.mode='';a.editor.prototype.addMode=function(n,o){o.name=n;(this._.modes||(this._.modes={}))[n]=o;};a.editor.prototype.setMode=function(n){var o,p=this.getThemeSpace('contents'),q=this.checkDirty();if(this.mode){if(n==this.mode)return;this.fire('beforeModeUnload');var r=l(this);o=r.getData();r.unload(p);this.mode='';}p.setHtml('');var s=l(this,n);if(!s)throw '[CKEDITOR.editor.setMode] Unknown mode "'+n+'".';if(!q)this.on('mode',function(){this.resetDirty();this.removeListener('mode',arguments.callee);});s.load(p,typeof o!='string'?this.getData():o);};a.editor.prototype.focus=function(){var n=l(this);if(n)n.focus();};})();i.startupMode='wysiwyg';i.startupFocus=false;i.editingBlock=true;j.add('panel',{beforeInit:function(l){l.ui.addHandler(2,k.panel.handler);}});a.UI_PANEL=2;k.panel=function(l,m){var n=this;if(m)e.extend(n,m);e.extend(n,{className:'',css:[]});n.id=e.getNextNumber();n.document=l;n._={blocks:{}};};k.panel.handler={create:function(l){return new k.panel(l);}};k.panel.prototype={renderHtml:function(l){var m=[];this.render(l,m);return m.join('');},render:function(l,m){var o=this;var n='cke_'+o.id;m.push(' ');return n;},getHolderElement:function(){var l=this._.holder;if(!l){if(this.forceIFrame||this.css.length){var m=this.document.getById('cke_'+this.id+'_frame'),n=m.getParent(),o=n.getAttribute('dir'),p=n.getParent().getAttribute('class'),q=n.getParent().getAttribute('lang'),r=m.getFrameDocument();r.$.open();if(b.isCustomDomain())r.$.domain=document.domain;var s=e.addFunction(e.bind(function(u){this.isLoaded=true;if(this.onLoad)this.onLoad();},this));r.$.write(''+''+''+''+''+''+''+'');r.$.close();var t=r.getWindow();t.$.CKEDITOR=a;r.on('keydown',function(u){var w=this;var v=u.data.getKeystroke();if(w._.onKeyDown&&w._.onKeyDown(v)===false){u.data.preventDefault();return;}if(v==27)w.onEscape&&w.onEscape();},this);l=r.getBody();}else l=this.document.getById('cke_'+this.id);this._.holder=l;}return l;},addBlock:function(l,m){var n=this;m=n._.blocks[l]=m||new k.panel.block(n.getHolderElement());if(!n._.currentBlock)n.showBlock(l);return m;},getBlock:function(l){return this._.blocks[l];},showBlock:function(l){var p=this;var m=p._.blocks,n=m[l],o=p._.currentBlock;if(o)o.hide();p._.currentBlock=n;n._.focusIndex=-1;p._.onKeyDown=n.onKeyDown&&e.bind(n.onKeyDown,n);n.show();return n;},destroy:function(){this.element&&this.element.remove();}};k.panel.block=e.createClass({$:function(l){var m=this;m.element=l.append(l.getDocument().createElement('div',{attributes:{'class':'cke_panel_block'},styles:{display:'none'}}));m.keys={};m._.focusIndex=-1;m.element.disableContextMenu();},_:{},proto:{show:function(){this.element.setStyle('display','');},hide:function(){var l=this;if(!l.onHide||l.onHide.call(l)!==true)l.element.setStyle('display','none');},onKeyDown:function(l){var q=this;var m=q.keys[l];switch(m){case 'next':var n=q._.focusIndex,o=q.element.getElementsByTag('a'),p;while(p=o.getItem(++n)){if(p.getAttribute('_cke_focus')&&p.$.offsetWidth){q._.focusIndex=n;p.focus();break;}}return false; -case 'prev':n=q._.focusIndex;o=q.element.getElementsByTag('a');while(n>0&&(p=o.getItem(--n))){if(p.getAttribute('_cke_focus')&&p.$.offsetWidth){q._.focusIndex=n;p.focus();break;}}return false;case 'click':n=q._.focusIndex;p=n>=0&&q.element.getElementsByTag('a').getItem(n);if(p)p.$.click?p.$.click():p.$.onclick();return false;}return true;}}});j.add('listblock',{requires:['panel'],onLoad:function(){k.panel.prototype.addListBlock=function(l,m){return this.addBlock(l,new k.listBlock(this.getHolderElement(),m));};k.listBlock=e.createClass({base:k.panel.block,$:function(l,m){var o=this;o.base(l);o.multiSelect=!!m;var n=o.keys;n[40]='next';n[9]='next';n[38]='prev';n[2000+9]='prev';n[32]='click';o._.pendingHtml=[];o._.items={};o._.groups={};},_:{close:function(){if(this._.started){this._.pendingHtml.push('
',n.auto,' |
');}if(m.colorButton_enableMore)t.push(' | |||||||
",n.more,' | ');t.push('
';}),P=[];O.replace(/([\s\S]*?)<\/pre>/gi,function(Q,R){P.push(R);});return P;};function u(L,M,N){var O='',P='';L=L.replace(/(^]+_fck_bookmark.*?\/span>)|(]+_fck_bookmark.*?\/span>$)/gi,function(Q,R,S){R&&(O=R);S&&(P=S);return '';});return O+L.replace(M,N)+P;};function v(L,M){var N=new d.documentFragment(M.getDocument());for(var O=0;O');P=P.replace(/[ \t]{2,}/g,function(R){return e.repeat(' ',R.length-1)+' ';});var Q=M.clone();Q.setHtml(P);N.append(Q);}return N;};function w(L,M){var N=L.getHtml();N=u(N,/(?:^[ \t\n\r]+)|(?:[ \t\n\r]+$)/g,'');N=N.replace(/[ \t\r\n]*(
]*>)[ \t\r\n]*/gi,'$1');N=N.replace(/([ \t\n\r]+| )/g,' ');N=N.replace(/
]*>/gi,'\n');if(c){var O=L.getDocument().createElement('div');O.append(M);M.$.outerHTML=''+N+'
';M=O.getFirst().remove();}else M.setHtml(N);return M;};function x(L,M){var N=L._.definition,O=N.attributes,P=N.styles,Q=I(L);function R(){for(var T in O){if(T=='class'&&M.getAttribute(T)!=O[T])continue;M.removeAttribute(T);}};R();for(var S in P)M.removeStyle(S);O=Q[M.getName()];if(O)R();A(M);};function y(L,M){var N=L._.definition,O=N.attributes,P=N.styles,Q=I(L),R=M.getElementsByTag(L.element);for(var S=R.count();
+--S>=0;)x(L,R.getItem(S));for(var T in Q){if(T!=L.element){R=M.getElementsByTag(T);for(S=R.count()-1;S>=0;S--){var U=R.getItem(S);z(U,Q[T]);}}}};function z(L,M){var N=M&&M.attributes;if(N)for(var O=0;O0)F+=(E.$.offsetHeight||0)-(E.$.clientHeight||0);E.setStyle('height',F+'px');t._.currentBlock.element.setStyle('display','none').removeStyle('display');}else v.getFirst().removeStyle('height');var G=t.element,H=G.getWindow(),I=H.getScrollPosition(),J=H.getViewPaneSize(),K={height:G.$.offsetHeight,width:G.$.offsetWidth};if(z?A<0:A+K.width>J.width+I.x)A+=K.width*(z?1:-1);if(B+K.height>J.height+I.y)B-=K.height;v.setStyles({top:B+'px',left:A+'px',opacity:'1'});},this);t.isLoaded?D():t.onLoad=D;e.setTimeout(function(){if(x.voiceLabel)if(b.gecko){var E=w.getParent();E.setAttribute('role','region');E.setAttribute('title',x.voiceLabel);w.setAttribute('role','region');w.setAttribute('title',' ');}w.$.contentWindow.focus();this.allowBlur(true);},0,this);},0,this);this.visible=1;if(this.onShow)this.onShow.call(this);m=false;},hide:function(){var o=this;if(o.visible&&(!o.onHide||o.onHide.call(o)!==true)){o.hideChild();o.element.setStyle('display','none');o.visible=0;}},allowBlur:function(o){var p=this._.panel;if(o!=undefined)p.allowBlur=o;return p.allowBlur;},showAsChild:function(o,p,q,r,s,t){if(this._.activeChild==o&&o._.panel._.offsetParentId==q.getId())return;this.hideChild();o.onHide=e.bind(function(){e.setTimeout(function(){if(!this._.focused)this.hide();},0,this);},this);this._.activeChild=o;this._.focused=false;o.showBlock(p,q,r,s,t);if(b.ie7Compat||b.ie8&&b.ie6Compat)setTimeout(function(){o.element.getChild(0).$.style.cssText+='';
+},100);},hideChild:function(){var o=this._.activeChild;if(o){delete o.onHide;delete this._.activeChild;o.hide();}}}});a.on('instanceDestroyed',function(){var o=e.isEmpty(a.instances);for(var p in l){var q=l[p];if(o)q.destroy();else q.element.hide();}o&&(l={});});})();j.add('menu',{beforeInit:function(l){var m=l.config.menu_groups.split(','),n={};for(var o=0;o'],y=q.length,z=y&&q[0].group;for(var A=0;A');z=B.group;}B.render(this,A,x);}x.push('');t.setHtml(x.join(''));if(this.parent)this.parent._.panel.showAsChild(s,this.id,m,n,o,p);else s.showBlock(this.id,m,n,o,p);r.fire('menuShow',[s]);},hide:function(){this._.panel&&this._.panel.hide();}}});function l(m){m.sort(function(n,o){if(n.groupo.group)return 1;return n.ordero.order?1:0;});};})();a.menuItem=e.createClass({$:function(l,m,n){var o=this;e.extend(o,n,{order:0,className:'cke_button_'+m});o.group=l._.menuGroups[o.group];o.editor=l;o.name=m;},proto:{render:function(l,m,n){var t=this;var o=l.id+String(m),p=typeof t.state=='undefined'?2:t.state,q=' cke_'+(p==1?'on':p==0?'disabled':'off'),r=t.label;if(p==0)r=t.editor.lang.common.unavailable.replace('%1',r);if(t.className)q+=' '+t.className;n.push('
';});n.on('themeLoaded',function(){n.fireOnce('editingBlockReady');});n.on('uiReady',function(){n.setMode(n.config.startupMode);});n.on('afterSetData',function(){if(!m){function o(){m=true;
+l(n).loadData(n.getData());m=false;};if(n.mode)o();else n.on('mode',function(){o();n.removeListener('mode',arguments.callee);});}});n.on('beforeGetData',function(){if(!m&&n.mode){m=true;n.setData(l(n).getData());m=false;}});n.on('getSnapshot',function(o){if(n.mode)o.data=l(n).getSnapshotData();});n.on('loadSnapshot',function(o){if(n.mode)l(n).loadSnapshotData(o.data);});n.on('mode',function(o){o.removeListener();var p=n.container;if(b.webkit&&b.version<528){var q=n.config.tabIndex||n.element.getAttribute('tabindex')||0;p=p.append(h.createFromHtml(''));}p.on('focus',function(){n.focus();});if(n.config.startupFocus)n.focus();setTimeout(function(){n.fireOnce('instanceReady');a.fire('instanceReady',null,n);});});}});a.editor.prototype.mode='';a.editor.prototype.addMode=function(n,o){o.name=n;(this._.modes||(this._.modes={}))[n]=o;};a.editor.prototype.setMode=function(n){var o,p=this.getThemeSpace('contents'),q=this.checkDirty();if(this.mode){if(n==this.mode)return;this.fire('beforeModeUnload');var r=l(this);o=r.getData();r.unload(p);this.mode='';}p.setHtml('');var s=l(this,n);if(!s)throw '[CKEDITOR.editor.setMode] Unknown mode "'+n+'".';if(!q)this.on('mode',function(){this.resetDirty();this.removeListener('mode',arguments.callee);});s.load(p,typeof o!='string'?this.getData():o);};a.editor.prototype.focus=function(){var n=l(this);if(n)n.focus();};})();i.startupMode='wysiwyg';i.startupFocus=false;i.editingBlock=true;(function(){function l(){var v=this;try{var s=v.getSelection();if(!s)return;var t=s.getStartElement(),u=new d.elementPath(t);if(!u.compare(v._.selectionPreviousPath)){v._.selectionPreviousPath=u;v.fire('selectionChange',{selection:s,path:u,element:t});}}catch(w){}};var m,n;function o(){n=true;if(m)return;p.call(this);m=e.setTimeout(p,200,this);};function p(){m=null;if(n){e.setTimeout(l,0,this);n=false;}};var q={exec:function(s){switch(s.mode){case 'wysiwyg':s.document.$.execCommand('SelectAll',false,null);break;case 'source':}},canUndo:false};j.add('selection',{init:function(s){s.on('contentDom',function(){var t=s.document,u=t.getBody();if(c){var v,w;u.on('focusin',function(){if(v){try{v.select();}catch(z){}v=null;}});s.window.on('focus',function(){w=true;y();});u.on('beforedeactivate',function(){w=false;});u.on('mousedown',x);u.on('mouseup',function(){w=true;setTimeout(function(){y(true);},0);});u.on('keydown',x);u.on('keyup',function(){w=true;y();});t.on('selectionchange',y);function x(){w=false;
+};function y(z){if(w){var A=s.document,B=A&&A.$.selection;if(z&&B&&B.type=='None')if(!A.$.queryCommandEnabled('InsertImage')){e.setTimeout(y,50,this,true);return;}v=B&&B.createRange();o.call(s);}};}else{t.on('mouseup',o,s);t.on('keyup',o,s);}});s.addCommand('selectAll',q);s.ui.addButton('SelectAll',{label:s.lang.selectAll,command:'selectAll'});s.selectionChange=o;}});a.editor.prototype.getSelection=function(){return this.document&&this.document.getSelection();};a.editor.prototype.forceNextSelectionCheck=function(){delete this._.selectionPreviousPath;};g.prototype.getSelection=function(){var s=new d.selection(this);return!s||s.isInvalid?null:s;};a.SELECTION_NONE=1;a.SELECTION_TEXT=2;a.SELECTION_ELEMENT=3;d.selection=function(s){var v=this;var t=s.getCustomData('cke_locked_selection');if(t)return t;v.document=s;v.isLocked=false;v._={cache:{}};if(c){var u=v.getNative().createRange();if(!u||u.item&&u.item(0).ownerDocument!=v.document.$||u.parentElement&&u.parentElement().ownerDocument!=v.document.$)v.isInvalid=true;}return v;};var r={img:1,hr:1,li:1,table:1,tr:1,td:1,th:1,embed:1,object:1,ol:1,ul:1,a:1,input:1,form:1,select:1,textarea:1,button:1,fieldset:1,th:1,thead:1,tfoot:1};d.selection.prototype={getNative:c?function(){return this._.cache.nativeSel||(this._.cache.nativeSel=this.document.$.selection);}:function(){return this._.cache.nativeSel||(this._.cache.nativeSel=this.document.getWindow().$.getSelection());},getType:c?function(){var s=this._.cache;if(s.type)return s.type;var t=1;try{var u=this.getNative(),v=u.type;if(v=='Text')t=2;if(v=='Control')t=3;if(u.createRange().parentElement)t=2;}catch(w){}return s.type=t;}:function(){var s=this._.cache;if(s.type)return s.type;var t=2,u=this.getNative();if(!u)t=1;else if(u.rangeCount==1){var v=u.getRangeAt(0),w=v.startContainer;if(w==v.endContainer&&w.nodeType==1&&v.endOffset-v.startOffset==1&&r[w.childNodes[v.startOffset].nodeName.toLowerCase()])t=3;}return s.type=t;},getRanges:c?(function(){var s=function(t,u){t=t.duplicate();t.collapse(u);var v=t.parentElement(),w=v.childNodes,x;for(var y=0;y0)break;else if(A===0)return{container:v,offset:y};x=null;}}if(!x){x=t.duplicate();x.moveToElementText(v);x.collapse(false);}x.setEndPoint('StartToStart',t);var B=x.text.replace(/(\r\n|\r)/g,'\n').length;while(B>0)B-=w[--y].nodeValue.length;if(B===0)return{container:v,offset:y};else return{container:w[y],offset:-B};
+};return function(){var E=this;var t=E._.cache;if(t.ranges)return t.ranges;var u=E.getNative(),v=u&&u.createRange(),w=E.getType(),x;if(!u)return[];if(w==2){x=new d.range(E.document);var y=s(v,true);x.setStart(new d.node(y.container),y.offset);y=s(v);x.setEnd(new d.node(y.container),y.offset);return t.ranges=[x];}else if(w==3){var z=E._.cache.ranges=[];for(var A=0;A=0){q.collapse(true);o.setEnd(q.endContainer.$,q.endOffset);}else throw r;}var p=q.document.getSelection().getNative();p.removeAllRanges();p.addRange(o);};})();(function(){var l={elements:{$:function(m){var n=m.attributes,o=n&&n._cke_realelement,p=o&&new a.htmlParser.fragment.fromHtml(decodeURIComponent(o)),q=p&&p.children[0];if(q&&m.attributes._cke_resizable){var r=m.attributes.style;if(r){var s=/(?:^|\s)width\s*:\s*(\d+)/i.exec(r),t=s&&s[1];s=/(?:^|\s)height\s*:\s*(\d+)/i.exec(r);var u=s&&s[1];if(t)q.attributes.width=t;if(u)q.attributes.height=u;}}return q;}}};j.add('fakeobjects',{requires:['htmlwriter'],afterInit:function(m){var n=m.dataProcessor,o=n&&n.htmlFilter;if(o)o.addRules(l);}});})();a.editor.prototype.createFakeElement=function(l,m,n,o){var p=this.lang.fakeobjects,q={'class':m,src:a.getUrl('images/spacer.gif'),_cke_realelement:encodeURIComponent(l.getOuterHtml()),_cke_real_node_type:l.type,alt:p[n]||p.unknown};if(n)q._cke_real_element_type=n;if(o)q._cke_resizable=o;return this.document.createElement('img',{attributes:q});};a.editor.prototype.createFakeParserElement=function(l,m,n,o){var p=this.lang.fakeobjects,q,r=new a.htmlParser.basicWriter();l.writeHtml(r);q=r.getHtml();var s={'class':m,src:a.getUrl('images/spacer.gif'),_cke_realelement:encodeURIComponent(q),_cke_real_node_type:l.type,alt:p[n]||p.unknown};if(n)s._cke_real_element_type=n;if(o)s._cke_resizable=o;return new a.htmlParser.element('img',s);};a.editor.prototype.restoreRealElement=function(l){if(l.getAttribute('_cke_real_node_type')!=1)return null;return h.createFromHtml(decodeURIComponent(l.getAttribute('_cke_realelement')),this.document);};j.add('richcombo',{requires:['floatpanel','listblock','button'],beforeInit:function(l){l.ui.addHandler(3,k.richCombo.handler);}});a.UI_RICHCOMBO=3;k.richCombo=e.createClass({$:function(l){var n=this;
+e.extend(n,l,{title:l.label,modes:{wysiwyg:1}});var m=n.panel||{};delete n.panel;n.id=e.getNextNumber();n.document=m&&m.parent&&m.parent.getDocument()||a.document;m.className=(m.className||'')+' cke_rcombopanel';n._={panelDefinition:m,items:{},state:2};},statics:{handler:{create:function(l){return new k.richCombo(l);}}},proto:{renderHtml:function(l){var m=[];this.render(l,m);return m.join('');},render:function(l,m){var n='cke_'+this.id,o=e.addFunction(function(r){var u=this;var s=u._;if(s.state==0)return;u.createPanel(l);if(s.on){s.panel.hide();return;}if(!s.committed){s.list.commit();s.committed=1;}var t=u.getValue();if(t)s.list.mark(t);else s.list.unmarkAll();s.panel.showBlock(u.id,new h(r),4);},this),p={id:n,combo:this,focus:function(){var r=a.document.getById(n).getChild(1);r.focus();},execute:o};l.on('mode',function(){this.setState(this.modes[l.mode]?2:0);},this);var q=e.addFunction(function(r,s){r=new d.event(r);var t=r.getKeystroke();switch(t){case 13:case 32:case 40:e.callFunction(o,s);break;default:p.onkey(p,t);}r.preventDefault();});m.push('','',this.label,''+(this.voiceLabel?this.voiceLabel+' ':'')+''+''+this.label+''+''+''+''+''+'');if(this.onRender)this.onRender();return p;},createPanel:function(l){if(this._.panel)return;var m=this._.panelDefinition,n=m.parent||a.document.getBody(),o=new k.floatPanel(l,n,m),p=o.addListBlock(this.id,this.multiSelect),q=this;o.onShow=function(){if(q.className)this.element.getFirst().addClass(q.className+'_panel');q.setState(1);p.focus(!q.multiSelect&&q.getValue());q._.on=1;if(q.onOpen)q.onOpen();};o.onHide=function(){if(q.className)this.element.getFirst().removeClass(q.className+'_panel');q.setState(2);q._.on=0;if(q.onClose)q.onClose();};o.onEscape=function(){o.hide();q.document.getById('cke_'+q.id).getFirst().getNext().focus();};p.onClick=function(r,s){q.document.getWindow().focus();
+if(q.onClick)q.onClick.call(q,r,s);if(s)q.setValue(r,q._.items[r]);else q.setValue('');o.hide();};this._.panel=o;this._.list=p;o.getBlock(this.id).onHide=function(){q._.on=0;q.setState(2);};if(this.init)this.init();},setValue:function(l,m){var o=this;o._.value=l;var n=o.document.getById('cke_'+o.id+'_text');if(!(l||m)){m=o.label;n.addClass('cke_inline_label');}else n.removeClass('cke_inline_label');n.setHtml(typeof m!='undefined'?m:l);},getValue:function(){return this._.value||'';},unmarkAll:function(){this._.list.unmarkAll();},mark:function(l){this._.list.mark(l);},hideItem:function(l){this._.list.hideItem(l);},hideGroup:function(l){this._.list.hideGroup(l);},showAll:function(){this._.list.showAll();},add:function(l,m,n){this._.items[l]=n||l;this._.list.add(l,m,n);},startGroup:function(l){this._.list.startGroup(l);},commit:function(){this._.list.commit();},setState:function(l){var m=this;if(m._.state==l)return;m.document.getById('cke_'+m.id).setState(l);m._.state=l;}}});k.prototype.addRichCombo=function(l,m){this.add(l,3,m);};j.add('htmlwriter');a.htmlWriter=e.createClass({base:a.htmlParser.basicWriter,$:function(){var n=this;n.base();n.indentationChars='\t';n.selfClosingEnd=' />';n.lineBreakChars='\n';n.forceSimpleAmpersand=false;n.sortAttributes=true;n._.indent=false;n._.indentation='';n._.rules={};var l=f;for(var m in e.extend({},l.$nonBodyContent,l.$block,l.$listItem,l.$tableContent))n.setRules(m,{indent:true,breakBeforeOpen:true,breakAfterOpen:true,breakBeforeClose:!l[m]['#'],breakAfterClose:true});n.setRules('br',{breakAfterOpen:true});n.setRules('title',{indent:false,breakAfterOpen:false});n.setRules('style',{indent:false,breakBeforeClose:true});n.setRules('pre',{indent:false});},proto:{openTag:function(l,m){var o=this;var n=o._.rules[l];if(o._.indent)o.indentation();else if(n&&n.breakBeforeOpen){o.lineBreak();o.indentation();}o._.output.push('<',l);},openTagClose:function(l,m){var o=this;var n=o._.rules[l];if(m)o._.output.push(o.selfClosingEnd);else{o._.output.push('>');if(n&&n.indent)o._.indentation+=o.indentationChars;}if(n&&n.breakAfterOpen)o.lineBreak();},attribute:function(l,m){if(this.forceSimpleAmpersand)m=m.replace(/&/,'&');this._.output.push(' ',l,'="',m,'"');},closeTag:function(l){var n=this;var m=n._.rules[l];if(m&&m.indent)n._.indentation=n._.indentation.substr(n.indentationChars.length);if(n._.indent)n.indentation();else if(m&&m.breakBeforeClose){n.lineBreak();n.indentation();}n._.output.push('',l,'>');if(m&&m.breakAfterClose)n.lineBreak();
+},text:function(l){if(this._.indent){this.indentation();l=e.ltrim(l);}this._.output.push(l);},comment:function(l){if(this._.indent)this.indentation();this._.output.push('');},lineBreak:function(){var l=this;if(l._.output.length>0)l._.output.push(l.lineBreakChars);l._.indent=true;},indentation:function(){this._.output.push(this._.indentation);this._.indent=false;},setRules:function(l,m){var n=this._.rules[l];if(n)e.extend(n,m,true);else this._.rules[l]=m;}}});j.add('menubutton',{requires:['button','contextmenu'],beforeInit:function(l){l.ui.addHandler(5,k.menuButton.handler);}});a.UI_MENUBUTTON=5;(function(){var l=function(m){var n=this._;if(n.state===0)return;n.previousState=n.state;var o=n.menu;if(!o){o=n.menu=new j.contextMenu(m);o.onHide=e.bind(function(){this.setState(n.previousState);},this);if(this.onMenu)o.addListener(this.onMenu);}if(n.on){o.hide();return;}this.setState(1);o.show(a.document.getById(this._.id),4);};k.menuButton=e.createClass({base:k.button,$:function(m){var n=m.panel;delete m.panel;this.base(m);this.hasArrow=true;this.click=l;},statics:{handler:{create:function(m){return new k.menuButton(m);}}}});})();a.DIALOG_RESIZE_NONE=0;a.DIALOG_RESIZE_WIDTH=1;a.DIALOG_RESIZE_HEIGHT=2;a.DIALOG_RESIZE_BOTH=3;(function(){function l(K){return!!this._.tabs[K][0].$.offsetHeight;};function m(){var O=this;var K=O._.currentTabId,L=O._.tabIdList.length,M=e.indexOf(O._.tabIdList,K)+L;for(var N=M-1;N>M-L;N--){if(l.call(O,O._.tabIdList[N%L]))return O._.tabIdList[N%L];}return null;};function n(){var O=this;var K=O._.currentTabId,L=O._.tabIdList.length,M=e.indexOf(O._.tabIdList,K);for(var N=M+1;N0?L:0)+'px',top:(M>0?M:0)+'px'});};})(),getPosition:function(){return e.extend({},this._.position);},show:function(){var K=this._.editor;if(K.mode=='wysiwyg'&&c){var L=K.getSelection();L&&L.lock();}var M=this._.element,N=this.definition;if(!(M.getParent()&&M.getParent().equals(a.document.getBody())))M.appendTo(a.document.getBody());
+else return;if(b.gecko&&b.version<10900){var O=this.parts.dialog;O.setStyle('position','absolute');setTimeout(function(){O.setStyle('position','fixed');},0);}this.resize(N.minWidth,N.minHeight);this.selectPage(this.definition.contents[0].id);this.reset();if(a.dialog._.currentZIndex===null)a.dialog._.currentZIndex=this._.editor.config.baseFloatZIndex;this._.element.getFirst().setStyle('z-index',a.dialog._.currentZIndex+=10);if(a.dialog._.currentTop===null){a.dialog._.currentTop=this;this._.parentDialog=null;z(this._.editor);M.on('keydown',C);M.on(b.opera?'keypress':'keyup',D);for(var P in {keyup:1,keydown:1,keypress:1})M.on(P,J);}else{this._.parentDialog=a.dialog._.currentTop;var Q=this._.parentDialog.getElement().getFirst();Q.$.style.zIndex-=Math.floor(this._.editor.config.baseFloatZIndex/2);a.dialog._.currentTop=this;}E(this,this,'\x1b',null,function(){this.getButton('cancel')&&this.getButton('cancel').click();});this._.hasFocus=false;e.setTimeout(function(){var R=a.document.getWindow().getViewPaneSize(),S=this.getSize();this.move((R.width-N.minWidth)/2,(R.height-S.height)/2);this.parts.dialog.setStyle('visibility','');this.fireOnce('load',{});this.fire('show',{});this._.editor.fire('dialogShow',this);this.foreach(function(T){T.setInitValue&&T.setInitValue();});},100,this);},foreach:function(K){var N=this;for(var L in N._.contents)for(var M in N._.contents[L])K(N._.contents[L][M]);return N;},reset:(function(){var K=function(L){if(L.reset)L.reset();};return function(){this.foreach(K);return this;};})(),setupContent:function(){var K=arguments;this.foreach(function(L){if(L.setup)L.setup.apply(L,K);});},commitContent:function(){var K=arguments;this.foreach(function(L){if(L.commit)L.commit.apply(L,K);});},hide:function(){this.fire('hide',{});this._.editor.fire('dialogHide',this);var K=this._.element;if(!K.getParent())return;K.remove();this.parts.dialog.setStyle('visibility','hidden');F(this);if(!this._.parentDialog)A();else{var L=this._.parentDialog.getElement().getFirst();L.setStyle('z-index',parseInt(L.$.style.zIndex,10)+Math.floor(this._.editor.config.baseFloatZIndex/2));}a.dialog._.currentTop=this._.parentDialog;if(!this._.parentDialog){a.dialog._.currentZIndex=null;K.removeListener('keydown',C);K.removeListener(b.opera?'keypress':'keyup',D);for(var M in {keyup:1,keydown:1,keypress:1})K.removeListener(M,J);var N=this._.editor;N.focus();if(N.mode=='wysiwyg'&&c){var O=N.getSelection();O&&O.unlock(true);}}else a.dialog._.currentZIndex-=10;this.foreach(function(P){P.resetInitValue&&P.resetInitValue();
+});},addPage:function(K){var U=this;var L=[],M=K.label?' title="'+e.htmlEncode(K.label)+'"':'',N=K.elements,O=a.dialog._.uiElementBuilders.vbox.build(U,{type:'vbox',className:'cke_dialog_page_contents',children:K.elements,expand:!!K.expand,padding:K.padding,style:K.style||'width: 100%;'},L),P=h.createFromHtml(L.join('')),Q=h.createFromHtml(['0?' cke_last':'cke_first',M,!!K.hidden?' style="display:none"':'',' id="',K.id+'_',e.getNextNumber(),'" href="javascript:void(0)"',' hidefocus="true">',K.label,''].join(''));if(U._.pageCount===0)U.parts.dialog.addClass('cke_single_page');else U.parts.dialog.removeClass('cke_single_page');U._.tabs[K.id]=[Q,P];U._.tabIdList.push(K.id);U._.pageCount++;U._.lastTab=Q;var R=U._.contents[K.id]={},S,T=O.getChild();while(S=T.shift()){R[S.id]=S;if(typeof S.getChild=='function')T.push.apply(T,S.getChild());}P.setAttribute('name',K.id);P.appendTo(U.parts.contents);Q.unselectable();U.parts.tabs.append(Q);if(K.accessKey){E(U,U,'CTRL+'+K.accessKey,H,G);U._.accessKeyMap['CTRL+'+K.accessKey]=K.id;}},selectPage:function(K){var P=this;for(var L in P._.tabs){var M=P._.tabs[L][0],N=P._.tabs[L][1];if(L!=K){M.removeClass('cke_dialog_tab_selected');N.hide();}}var O=P._.tabs[K];O[0].addClass('cke_dialog_tab_selected');O[1].show();P._.currentTabId=K;P._.currentTabIndex=e.indexOf(P._.tabIdList,K);},hidePage:function(K){var L=this._.tabs[K]&&this._.tabs[K][0];if(!L)return;L.hide();},showPage:function(K){var L=this._.tabs[K]&&this._.tabs[K][0];if(!L)return;L.show();},getElement:function(){return this._.element;},getName:function(){return this._.name;},getContentElement:function(K,L){return this._.contents[K][L];},getValueOf:function(K,L){return this.getContentElement(K,L).getValue();},setValueOf:function(K,L,M){return this.getContentElement(K,L).setValue(M);},getButton:function(K){return this._.buttons[K];},click:function(K){return this._.buttons[K].click();},disableButton:function(K){return this._.buttons[K].disable();},enableButton:function(K){return this._.buttons[K].enable();},getPageCount:function(){return this._.pageCount;},getParentEditor:function(){return this._.editor;},getSelectedElement:function(){return this.getParentEditor().getSelection().getSelectedElement();},addFocusable:function(K,L){var N=this;if(typeof L=='undefined'){L=N._.focusList.length;N._.focusList.push(new o(N,K,L));}else{N._.focusList.splice(L,0,new o(N,K,L));for(var M=L+1;MV.width-U.width-P)aa=V.width-U.width+Q[1];else aa=M.x;if(M.y+Q[0]V.height-U.height-P)ab=V.height-U.height+Q[2];else ab=M.y;K.move(aa,ab);T.data.preventDefault();};function S(T){a.document.removeListener('mousemove',R);a.document.removeListener('mouseup',S);if(b.ie6Compat){var U=y.getChild(0).getFrameDocument();U.removeListener('mousemove',R);U.removeListener('mouseup',S);}};K.parts.title.on('mousedown',function(T){K._.updateSize=true;L={x:T.data.$.screenX,y:T.data.$.screenY};a.document.on('mousemove',R);a.document.on('mouseup',S);M=K.getPosition();if(b.ie6Compat){var U=y.getChild(0).getFrameDocument();U.on('mousemove',R);U.on('mouseup',S);}T.data.preventDefault();},K);};function w(K){var L=K.definition,M=L.minWidth||0,N=L.minHeight||0,O=L.resizable,P=K.getParentEditor().skin.margins||[0,0,0,0];function Q(ab,ac){ab.y+=ac;};function R(ab,ac){ab.x2+=ac;};function S(ab,ac){ab.y2+=ac;};function T(ab,ac){ab.x+=ac;};var U=null,V=null,W=K._.editor.config.magnetDistance,X=['tl','t','tr','l','r','bl','b','br'];function Y(ab){var ac=ab.listenerData.part,ad=K.getSize();V=K.getPosition();e.extend(V,{x2:V.x+ad.width,y2:V.y+ad.height});U={x:ab.data.$.screenX,y:ab.data.$.screenY};a.document.on('mousemove',Z,K,{part:ac});a.document.on('mouseup',aa,K,{part:ac});if(b.ie6Compat){var ae=y.getChild(0).getFrameDocument();ae.on('mousemove',Z,K,{part:ac});ae.on('mouseup',aa,K,{part:ac});}ab.data.preventDefault();};function Z(ab){var ac=ab.data.$.screenX,ad=ab.data.$.screenY,ae=ac-U.x,af=ad-U.y,ag=a.document.getWindow().getViewPaneSize(),ah=ab.listenerData.part;if(ah.search('t')!=-1)Q(V,af);if(ah.search('l')!=-1)T(V,ae);if(ah.search('b')!=-1)S(V,af);if(ah.search('r')!=-1)R(V,ae);U={x:ac,y:ad};var ai,aj,ak,al;if(V.x+P[3]ag.width-W)ak=ag.width+P[1];else if(ah.search('r')!=-1&&V.x2-V.xag.height-W)al=ag.height+P[2];else if(ah.search('b')!=-1&&V.y2-V.y'];if(b.ie6Compat){var O=b.isCustomDomain(),P="";N.push('');}N.push('');y=h.createFromHtml(N.join(''));}var Q=y,R=function(){var V=L.getViewPaneSize();Q.setStyles({width:V.width+'px',height:V.height+'px'});},S=function(){var V=L.getScrollPosition(),W=a.dialog._.currentTop;Q.setStyles({left:V.x+'px',top:V.y+'px'});do{var X=W.getPosition();W.move(X.x,X.y);}while(W=W._.parentDialog)};x=R;L.on('resize',R);R();if(b.ie6Compat){var T=function(){S();arguments.callee.prevScrollHandler.apply(this,arguments);};L.$.setTimeout(function(){T.prevScrollHandler=window.onscroll||(function(){});window.onscroll=T;},0);S();}var U=K.config.dialog_backgroundCoverOpacity;Q.setOpacity(typeof U!='undefined'?U:0.5);Q.appendTo(a.document.getBody());},A=function(){if(!y)return;var K=a.document.getWindow();y.remove();K.removeListener('resize',x);if(b.ie6Compat)K.$.setTimeout(function(){var L=window.onscroll&&window.onscroll.prevScrollHandler;window.onscroll=L||null;},0);x=null;},B={},C=function(K){var L=K.data.$.ctrlKey||K.data.$.metaKey,M=K.data.$.altKey,N=K.data.$.shiftKey,O=String.fromCharCode(K.data.$.keyCode),P=B[(L?'CTRL+':'')+(M?'ALT+':'')+(N?'SHIFT+':'')+O];if(!P||!P.length)return;P=P[P.length-1];P.keydown&&P.keydown.call(P.uiElement,P.dialog,P.key);K.data.preventDefault();},D=function(K){var L=K.data.$.ctrlKey||K.data.$.metaKey,M=K.data.$.altKey,N=K.data.$.shiftKey,O=String.fromCharCode(K.data.$.keyCode),P=B[(L?'CTRL+':'')+(M?'ALT+':'')+(N?'SHIFT+':'')+O];if(!P||!P.length)return;P=P[P.length-1];if(P.keyup){P.keyup.call(P.uiElement,P.dialog,P.key);K.data.preventDefault();}},E=function(K,L,M,N,O){var P=B[M]||(B[M]=[]);
+P.push({uiElement:K,dialog:L,key:M,keyup:O||K.accessKeyUp,keydown:N||K.accessKeyDown});},F=function(K){for(var L in B){var M=B[L];for(var N=M.length-1;N>=0;N--){if(M[N].dialog==K||M[N].uiElement==K)M.splice(N,1);}if(M.length===0)delete B[L];}},G=function(K,L){if(K._.accessKeyMap[L])K.selectPage(K._.accessKeyMap[L]);},H=function(K,L){},I={27:1,13:1},J=function(K){if(K.data.getKeystroke() in I)K.data.stopPropagation();};(function(){k.dialog={uiElement:function(K,L,M,N,O,P,Q){if(arguments.length<4)return;var R=(N.call?N(L):N)||'div',S=['<',R,' '],T=(O&&O.call?O(L):O)||{},U=(P&&P.call?P(L):P)||{},V=(Q&&Q.call?Q(K,L):Q)||'',W=this.domId=U.id||e.getNextNumber()+'_uiElement',X=this.id=L.id,Y;U.id=W;var Z={};if(L.type)Z['cke_dialog_ui_'+L.type]=1;if(L.className)Z[L.className]=1;var aa=U['class']&&U['class'].split?U['class'].split(' '):[];for(Y=0;Y=0;Y--){if(ac[Y]==='')ac.splice(Y,1);}if(ac.length>0)U.style=(U.style?U.style+'; ':'')+ac.join('; ');for(Y in U)S.push(Y+'="'+e.htmlEncode(U[Y])+'" ');S.push('>',V,'',R,'>');M.push(S.join(''));(this._||(this._={})).dialog=K;if(typeof L.isChanged=='boolean')this.isChanged=function(){return L.isChanged;};if(typeof L.isChanged=='function')this.isChanged=L.isChanged;a.event.implementOn(this);this.registerEvents(L);if(this.accessKeyUp&&this.accessKeyDown&&L.accessKey)E(this,K,'CTRL+'+L.accessKey);var ad=this;K.on('load',function(){if(ad.getInputElement())ad.getInputElement().on('focus',function(){K._.tabBarMode=false;K._.hasFocus=true;ad.fire('focus');},ad);});if(this.keyboardFocusable){this.focusIndex=K._.focusList.push(this)-1;this.on('focus',function(){K._.currentFocusIndex=ad.focusIndex;});}e.extend(this,L);},hbox:function(K,L,M,N,O){if(arguments.length<4)return;this._||(this._={});var P=this._.children=L,Q=O&&O.widths||null,R=O&&O.height||null,S={},T,U=function(){var V=[''];for(T=0;T0)V.push('style="'+X.join('; ')+'" ');V.push('>',M[T],'');}V.push(' ');return V.join('');};k.dialog.uiElement.call(this,K,O||{type:'hbox'},N,'table',S,O&&O.align&&{align:O.align}||null,U);},vbox:function(K,L,M,N,O){if(arguments.length<3)return;this._||(this._={});var P=this._.children=L,Q=O&&O.width||null,R=O&&O.heights||null,S=function(){var T=['');for(var U=0;U0)T.push('style="',V.join('; '),'" ');T.push(' class="cke_dialog_ui_vbox_child">',M[U],' ');}T.push('
');return T.join('');};k.dialog.uiElement.call(this,K,O||{type:'vbox'},N,'div',null,null,S);}};})();k.dialog.uiElement.prototype={getElement:function(){return a.document.getById(this.domId);},getInputElement:function(){return this.getElement();},getDialog:function(){return this._.dialog;},setValue:function(K){this.getInputElement().setValue(K);this.fire('change',{value:K});return this;},getValue:function(){return this.getInputElement().getValue();},isChanged:function(){return false;},selectParentTab:function(){var N=this;var K=N.getInputElement(),L=K,M;while((L=L.getParent())&&L.$.className.search('cke_dialog_page_contents')==-1){}if(!L)return N;M=L.getAttribute('name');if(N._.dialog._.currentTabId!=M)N._.dialog.selectPage(M);return N;},focus:function(){this.selectParentTab().getInputElement().focus();return this;},registerEvents:function(K){var L=/^on([A-Z]\w+)/,M,N=function(P,Q,R,S){Q.on('load',function(){P.getInputElement().on(R,S,P);});};for(var O in K){if(!(M=O.match(L)))continue;if(this.eventProcessors[O])this.eventProcessors[O].call(this,this._.dialog,K[O]);else N(this,this._.dialog,M[1].toLowerCase(),K[O]);}return this;},eventProcessors:{onLoad:function(K,L){K.on('load',L,this);},onShow:function(K,L){K.on('show',L,this);},onHide:function(K,L){K.on('hide',L,this);}},accessKeyDown:function(K,L){this.focus();},accessKeyUp:function(K,L){},disable:function(){var K=this.getInputElement();K.setAttribute('disabled','true');
+K.addClass('cke_disabled');},enable:function(){var K=this.getInputElement();K.removeAttribute('disabled');K.removeClass('cke_disabled');},isEnabled:function(){return!this.getInputElement().getAttribute('disabled');},isVisible:function(){return this.getInputElement().isVisible();},isFocusable:function(){if(!this.isEnabled()||!this.isVisible())return false;return true;}};k.dialog.hbox.prototype=e.extend(new k.dialog.uiElement(),{getChild:function(K){var L=this;if(arguments.length<1)return L._.children.concat();if(!K.splice)K=[K];if(K.length<2)return L._.children[K[0]];else return L._.children[K[0]]&&L._.children[K[0]].getChild?L._.children[K[0]].getChild(K.slice(1,K.length)):null;}},true);k.dialog.vbox.prototype=new k.dialog.hbox();(function(){var K={build:function(L,M,N){var O=M.children,P,Q=[],R=[];for(var S=0;S
');}}});i.menu_subMenuDelay=400;i.menu_groups='clipboard,form,tablecell,tablecellproperties,tablerow,tablecolumn,table,anchor,link,image,flash,checkbox,radio,textfield,hiddenfield,imagebutton,button,select,textarea,div';(function(){var l=function(n,o){return n._.modes&&n._.modes[o||n.mode];},m;j.add('editingblock',{init:function(n){if(!n.config.editingBlock)return;n.on('themeSpace',function(o){if(o.data.space=='contents')o.data.html+='
Initial value.
"); + * ?> + * @endcode + */ + +if ( !function_exists('version_compare') || version_compare( phpversion(), '5', '<' ) ) + include_once( 'ckeditor_php4.php' ) ; +else + include_once( 'ckeditor_php5.php' ) ; diff --git a/ckeditor_basic.js b/ckeditor_basic.js index 28249b7..667d956 100644 --- a/ckeditor_basic.js +++ b/ckeditor_basic.js @@ -1,8 +1,8 @@ /* -Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. +Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. For licensing, see LICENSE.html or http://ckeditor.com/license */ -(function(){if(!window.CKEDITOR)window.CKEDITOR=(function(){var a={timestamp:'9BIB',version:'3.0.2',revision:'4760',_:{},status:'unloaded',basePath:(function(){var d=window.CKEDITOR_BASEPATH||'';if(!d){var e=document.getElementsByTagName('script');for(var f=0;fInitial value.
"); + * @endcode + */ +class CKEditor +{ + /** + * The version of %CKEditor. + * \private + */ + var $version = '3.1'; + /** + * A constant string unique for each release of %CKEditor. + * \private + */ + var $_timestamp = 'A06B'; + + /** + * URL to the %CKEditor installation directory (absolute or relative to document root). + * If not set, CKEditor will try to guess it's path. + * + * Example usage: + * @code + * $CKEditor->basePath = '/ckeditor/'; + * @endcode + */ + var $basePath; + /** + * An array that holds the global %CKEditor configuration. + * For the list of available options, see http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html + * + * Example usage: + * @code + * $CKEditor->config['height'] = 400; + * // Use @@ at the beggining of a string to ouput it without surrounding quotes. + * $CKEditor->config['width'] = '@@screen.width * 0.8'; + * @endcode + */ + var $config = array(); + /** + * A boolean variable indicating whether CKEditor has been initialized. + * Set it to true only if you have already included + * <script> tag loading ckeditor.js in your website. + */ + var $initialized = false; + /** + * Boolean variable indicating whether created code should be printed out or returned by a function. + * + * Example 1: get the code creating %CKEditor instance and print it on a page with the "echo" function. + * @code + * $CKEditor = new CKEditor(); + * $CKEditor->returnOutput = true; + * $code = $CKEditor->editor("editor1", "Initial value.
"); + * echo "Editor 1:
"; + * echo $code; + * @endcode + */ + var $returnOutput = false; + /** + * An array with textarea attributes. + * + * When %CKEditor is created with the editor() method, a HTML <textarea> element is created, + * it will be displayed to anyone with JavaScript disabled or with incompatible browser. + */ + var $textareaAttributes = array( "rows" => 8, "cols" => 60 ); + /** + * A string indicating the creation date of %CKEditor. + * Do not change it unless you want to force browsers to not use previously cached version of %CKEditor. + */ + var $timestamp = "A06B"; + /** + * An array that holds event listeners. + * \private + */ + var $_events = array(); + /** + * An array that holds global event listeners. + * \private + */ + var $_globalEvents = array(); + + /** + * Main Constructor. + * + * @param $basePath (string) URL to the %CKEditor installation directory (optional). + */ + function CKEditor($basePath = null) { + if (!empty($basePath)) { + $this->basePath = $basePath; + } + } + + /** + * Creates a %CKEditor instance. + * In incompatible browsers %CKEditor will downgrade to plain HTML <textarea> element. + * + * @param $name (string) Name of the %CKEditor instance (this will be also the "name" attribute of textarea element). + * @param $value (string) Initial value (optional). + * @param $config (array) The specific configurations to apply to this editor instance (optional). + * @param $events (array) Event listeners for this editor instance (optional). + * + * Example usage: + * @code + * $CKEditor = new CKEditor(); + * $CKEditor->editor("field1", "Initial value.
"); + * @endcode + * + * Advanced example: + * @code + * $CKEditor = new CKEditor(); + * $config = array(); + * $config['toolbar'] = array( + * array( 'Source', '-', 'Bold', 'Italic', 'Underline', 'Strike' ), + * array( 'Image', 'Link', 'Unlink', 'Anchor' ) + * ); + * $events['instanceReady'] = 'function (ev) { + * alert("Loaded: " + ev.editor.name); + * }'; + * $CKEditor->editor("field1", "Initial value.
", $config, $events); + * @endcode + */ + function editor($name, $value = "", $config = array(), $events = array()) + { + $attr = ""; + foreach ($this->textareaAttributes as $key => $val) { + $attr.= " " . $key . '="' . str_replace('"', '"', $val) . '"'; + } + $out = "\n"; + if (!$this->initialized) { + $out .= $this->init(); + } + + $_config = $this->configSettings($config, $events); + + $js = $this->returnGlobalEvents(); + if (!empty($_config)) + $js .= "CKEDITOR.replace('".$name."', ".$this->jsEncode($_config).");"; + else + $js .= "CKEDITOR.replace('".$name."');"; + + $out .= $this->script($js); + + if (!$this->returnOutput) { + print $out; + $out = ""; + } + + return $out; + } + + /** + * Replaces a <textarea> with a %CKEditor instance. + * + * @param $id (string) The id or name of textarea element. + * @param $config (array) The specific configurations to apply to this editor instance (optional). + * @param $events (array) Event listeners for this editor instance (optional). + * + * Example 1: adding %CKEditor to <textarea name="article"></textarea> element: + * @code + * $CKEditor = new CKEditor(); + * $CKEditor->replace("article"); + * @endcode + */ + function replace($id, $config = array(), $events = array()) + { + $out = ""; + if (!$this->initialized) { + $out .= $this->init(); + } + + $_config = $this->configSettings($config, $events); + + $js = $this->returnGlobalEvents(); + if (!empty($_config)) { + $js .= "CKEDITOR.replace('".$id."', ".$this->jsEncode($_config).");"; + } + else { + $js .= "CKEDITOR.replace('".$id."');"; + } + $out .= $this->script($js); + + if (!$this->returnOutput) { + print $out; + $out = ""; + } + + return $out; + } + + /** + * Replace all <textarea> elements available in the document with editor instances. + * + * @param $className (string) If set, replace all textareas with class className in the page. + * + * Example 1: replace all <textarea> elements in the page. + * @code + * $CKEditor = new CKEditor(); + * $CKEditor->replaceAll(); + * @endcode + * + * Example 2: replace all <textarea class="myClassName"> elements in the page. + * @code + * $CKEditor = new CKEditor(); + * $CKEditor->replaceAll( 'myClassName' ); + * @endcode + */ + function replaceAll($className = null) + { + $out = ""; + if (!$this->initialized) { + $out .= $this->init(); + } + + $_config = $this->configSettings(); + + $js = $this->returnGlobalEvents(); + if (empty($_config)) { + if (empty($className)) { + $js .= "CKEDITOR.replaceAll();"; + } + else { + $js .= "CKEDITOR.replaceAll('".$className."');"; + } + } + else { + $classDetection = ""; + $js .= "CKEDITOR.replaceAll( function(textarea, config) {\n"; + if (!empty($className)) { + $js .= " var classRegex = new RegExp('(?:^| )' + '". $className ."' + '(?:$| )');\n"; + $js .= " if (!classRegex.test(textarea.className))\n"; + $js .= " return false;\n"; + } + $js .= " CKEDITOR.tools.extend(config, ". $this->jsEncode($_config) .", true);"; + $js .= "} );"; + + } + + $out .= $this->script($js); + + if (!$this->returnOutput) { + print $out; + $out = ""; + } + + return $out; + } + + /** + * Adds event listener. + * Events are fired by %CKEditor in various situations. + * + * @param $event (string) Event name. + * @param $javascriptCode (string) Javascript anonymous function or function name. + * + * Example usage: + * @code + * $CKEditor->addEventHandler('instanceReady', 'function (ev) { + * alert("Loaded: " + ev.editor.name); + * }'); + * @endcode + */ + function addEventHandler($event, $javascriptCode) + { + if (!isset($this->_events[$event])) { + $this->_events[$event] = array(); + } + // Avoid duplicates. + if (!in_array($javascriptCode, $this->_events[$event])) { + $this->_events[$event][] = $javascriptCode; + } + } + + /** + * Clear registered event handlers. + * Note: this function will have no effect on already created editor instances. + * + * @param $event (string) Event name, if not set all event handlers will be removed (optional). + */ + function clearEventHandlers($event = null) + { + if (!empty($event)) { + $this->_events[$event] = array(); + } + else { + $this->_events = array(); + } + } + + /** + * Adds global event listener. + * + * @param $event (string) Event name. + * @param $javascriptCode (string) Javascript anonymous function or function name. + * + * Example usage: + * @code + * $CKEditor->addGlobalEventHandler('dialogDefinition', 'function (ev) { + * alert("Loading dialog: " + ev.data.name); + * }'); + * @endcode + */ + function addGlobalEventHandler($event, $javascriptCode) + { + if (!isset($this->_globalEvents[$event])) { + $this->_globalEvents[$event] = array(); + } + // Avoid duplicates. + if (!in_array($javascriptCode, $this->_globalEvents[$event])) { + $this->_globalEvents[$event][] = $javascriptCode; + } + } + + /** + * Clear registered global event handlers. + * Note: this function will have no effect if the event handler has been already printed/returned. + * + * @param $event (string) Event name, if not set all event handlers will be removed (optional). + */ + function clearGlobalEventHandlers($event = null) + { + if (!empty($event)) { + $this->_globalEvents[$event] = array(); + } + else { + $this->_globalEvents = array(); + } + } + + /** + * Prints javascript code. + * \private + * + * @param string $js + */ + function script($js) + { + $out = "\n"; + + return $out; + } + + /** + * Returns the configuration array (global and instance specific settings are merged into one array). + * \private + * + * @param $config (array) The specific configurations to apply to editor instance. + * @param $events (array) Event listeners for editor instance. + */ + function configSettings($config = array(), $events = array()) + { + $_config = $this->config; + $_events = $this->_events; + + if (is_array($config) && !empty($config)) { + $_config = array_merge($_config, $config); + } + + if (is_array($events) && !empty($events)) { + foreach ($events as $eventName => $code) { + if (!isset($_events[$eventName])) { + $_events[$eventName] = array(); + } + if (!in_array($code, $_events[$eventName])) { + $_events[$eventName][] = $code; + } + } + } + + if (!empty($_events)) { + foreach($_events as $eventName => $handlers) { + if (empty($handlers)) { + continue; + } + else if (count($handlers) == 1) { + $_config['on'][$eventName] = '@@'.$handlers[0]; + } + else { + $_config['on'][$eventName] = '@@function (ev){'; + foreach ($handlers as $handler => $code) { + $_config['on'][$eventName] .= '('.$code.')(ev);'; + } + $_config['on'][$eventName] .= '}'; + } + } + } + + return $_config; + } + + /** + * Return global event handlers. + * \private + */ + function returnGlobalEvents() + { + static $returnedEvents; + $out = ""; + + if (!isset($returnedEvents)) { + $returnedEvents = array(); + } + + if (!empty($this->_globalEvents)) { + foreach ($this->_globalEvents as $eventName => $handlers) { + foreach ($handlers as $handler => $code) { + if (!isset($returnedEvents[$eventName])) { + $returnedEvents[$eventName] = array(); + } + // Return only new events + if (!in_array($code, $returnedEvents[$eventName])) { + $out .= ($code ? "\n" : "") . "CKEDITOR.on('". $eventName ."', $code);"; + $returnedEvents[$eventName][] = $code; + } + } + } + } + + return $out; + } + + /** + * Initializes CKEditor (executed only once). + * \private + */ + function init() + { + static $initComplete; + $out = ""; + + if (!empty($initComplete)) { + return ""; + } + + if ($this->initialized) { + $initComplete = true; + return ""; + } + + $args = ""; + $ckeditorPath = $this->ckeditorPath(); + + if (!empty($this->timestamp) && $this->timestamp != "%"."TIMESTAMP%") { + $args = '?t=' . $this->timestamp; + } + + // Skip relative paths... + if (strpos($ckeditorPath, '..') !== 0) { + $out .= $this->script("window.CKEDITOR_BASEPATH='". $ckeditorPath ."';"); + } + + $out .= "\n"; + + $extraCode = ""; + if ($this->timestamp != $this->_timestamp) { + $extraCode .= ($extraCode ? "\n" : "") . "CKEDITOR.timestamp = '". $this->timestamp ."';"; + } + if ($extraCode) { + $out .= $this->script($extraCode); + } + + $initComplete = $this->initialized = true; + + return $out; + } + + /** + * Return path to ckeditor.js. + * \private + */ + function ckeditorPath() + { + if (!empty($this->basePath)) { + return $this->basePath; + } + + /** + * The absolute pathname of the currently executing script. + * Note: If a script is executed with the CLI, as a relative path, such as file.php or ../file.php, + * $_SERVER['SCRIPT_FILENAME'] will contain the relative path specified by the user. + */ + if (isset($_SERVER['SCRIPT_FILENAME'])) { + $realPath = dirname($_SERVER['SCRIPT_FILENAME']); + } + else { + /** + * realpath â Returns canonicalized absolute pathname + */ + $realPath = realpath( './' ) ; + } + + /** + * The filename of the currently executing script, relative to the document root. + * For instance, $_SERVER['PHP_SELF'] in a script at the address http://example.com/test.php/foo.bar + * would be /test.php/foo.bar. + */ + $selfPath = dirname($_SERVER['PHP_SELF']); + $file = str_replace("\\", "/", __FILE__); + + if (!$selfPath || !$realPath || !$file) { + return "/ckeditor/"; + } + + $documentRoot = substr($realPath, 0, strlen($realPath) - strlen($selfPath)); + $fileUrl = substr($file, strlen($documentRoot)); + $ckeditorUrl = str_replace("ckeditor_php5.php", "", $fileUrl); + + return $ckeditorUrl; + } + + /** + * This little function provides a basic JSON support. + * http://php.net/manual/en/function.json-encode.php + * \private + * + * @param mixed $val + * @return string + */ + function jsEncode($val) + { + if (is_null($val)) { + return 'null'; + } + if ($val === false) { + return 'false'; + } + if ($val === true) { + return 'true'; + } + if (is_scalar($val)) + { + if (is_float($val)) + { + // Always use "." for floats. + $val = str_replace(",", ".", strval($val)); + } + + // Use @@ to not use quotes when outputting string value + if (strpos($val, '@@') === 0) { + return substr($val, 2); + } + else { + // All scalars are converted to strings to avoid indeterminism. + // PHP's "1" and 1 are equal for all PHP operators, but + // JS's "1" and 1 are not. So if we pass "1" or 1 from the PHP backend, + // we should get the same result in the JS frontend (string). + // Character replacements for JSON. + static $jsonReplaces = array(array("\\", "/", "\n", "\t", "\r", "\b", "\f", '"'), + array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"')); + + $val = str_replace($jsonReplaces[0], $jsonReplaces[1], $val); + + return '"' . $val . '"'; + } + } + $isList = true; + for ($i = 0, reset($val); $i < count($val); $i++, next($val)) + { + if (key($val) !== $i) + { + $isList = false; + break; + } + } + $result = array(); + if ($isList) + { + foreach ($val as $v) $result[] = $this->jsEncode($v); + return '[ ' . join(', ', $result) . ' ]'; + } + else + { + foreach ($val as $k => $v) $result[] = $this->jsEncode($k).': '.$this->jsEncode($v); + return '{ ' . join(', ', $result) . ' }'; + } + } +} diff --git a/ckeditor_php5.php b/ckeditor_php5.php new file mode 100644 index 0000000..ab1612d --- /dev/null +++ b/ckeditor_php5.php @@ -0,0 +1,583 @@ +editor("editor1", "Initial value.
"); + * @endcode + */ +class CKEditor +{ + /** + * The version of %CKEditor. + */ + const version = '3.1'; + /** + * A constant string unique for each release of %CKEditor. + */ + const timestamp = 'A06B'; + + /** + * URL to the %CKEditor installation directory (absolute or relative to document root). + * If not set, CKEditor will try to guess it's path. + * + * Example usage: + * @code + * $CKEditor->basePath = '/ckeditor/'; + * @endcode + */ + public $basePath; + /** + * An array that holds the global %CKEditor configuration. + * For the list of available options, see http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html + * + * Example usage: + * @code + * $CKEditor->config['height'] = 400; + * // Use @@ at the beggining of a string to ouput it without surrounding quotes. + * $CKEditor->config['width'] = '@@screen.width * 0.8'; + * @endcode + */ + public $config = array(); + /** + * A boolean variable indicating whether CKEditor has been initialized. + * Set it to true only if you have already included + * <script> tag loading ckeditor.js in your website. + */ + public $initialized = false; + /** + * Boolean variable indicating whether created code should be printed out or returned by a function. + * + * Example 1: get the code creating %CKEditor instance and print it on a page with the "echo" function. + * @code + * $CKEditor = new CKEditor(); + * $CKEditor->returnOutput = true; + * $code = $CKEditor->editor("editor1", "Initial value.
"); + * echo "Editor 1:
"; + * echo $code; + * @endcode + */ + public $returnOutput = false; + /** + * An array with textarea attributes. + * + * When %CKEditor is created with the editor() method, a HTML <textarea> element is created, + * it will be displayed to anyone with JavaScript disabled or with incompatible browser. + */ + public $textareaAttributes = array( "rows" => 8, "cols" => 60 ); + /** + * A string indicating the creation date of %CKEditor. + * Do not change it unless you want to force browsers to not use previously cached version of %CKEditor. + */ + public $timestamp = "A06B"; + /** + * An array that holds event listeners. + */ + private $events = array(); + /** + * An array that holds global event listeners. + */ + private $globalEvents = array(); + + /** + * Main Constructor. + * + * @param $basePath (string) URL to the %CKEditor installation directory (optional). + */ + function __construct($basePath = null) { + if (!empty($basePath)) { + $this->basePath = $basePath; + } + } + + /** + * Creates a %CKEditor instance. + * In incompatible browsers %CKEditor will downgrade to plain HTML <textarea> element. + * + * @param $name (string) Name of the %CKEditor instance (this will be also the "name" attribute of textarea element). + * @param $value (string) Initial value (optional). + * @param $config (array) The specific configurations to apply to this editor instance (optional). + * @param $events (array) Event listeners for this editor instance (optional). + * + * Example usage: + * @code + * $CKEditor = new CKEditor(); + * $CKEditor->editor("field1", "Initial value.
"); + * @endcode + * + * Advanced example: + * @code + * $CKEditor = new CKEditor(); + * $config = array(); + * $config['toolbar'] = array( + * array( 'Source', '-', 'Bold', 'Italic', 'Underline', 'Strike' ), + * array( 'Image', 'Link', 'Unlink', 'Anchor' ) + * ); + * $events['instanceReady'] = 'function (ev) { + * alert("Loaded: " + ev.editor.name); + * }'; + * $CKEditor->editor("field1", "Initial value.
", $config, $events); + * @endcode + */ + public function editor($name, $value = "", $config = array(), $events = array()) + { + $attr = ""; + foreach ($this->textareaAttributes as $key => $val) { + $attr.= " " . $key . '="' . str_replace('"', '"', $val) . '"'; + } + $out = "\n"; + if (!$this->initialized) { + $out .= $this->init(); + } + + $_config = $this->configSettings($config, $events); + + $js = $this->returnGlobalEvents(); + if (!empty($_config)) + $js .= "CKEDITOR.replace('".$name."', ".$this->jsEncode($_config).");"; + else + $js .= "CKEDITOR.replace('".$name."');"; + + $out .= $this->script($js); + + if (!$this->returnOutput) { + print $out; + $out = ""; + } + + return $out; + } + + /** + * Replaces a <textarea> with a %CKEditor instance. + * + * @param $id (string) The id or name of textarea element. + * @param $config (array) The specific configurations to apply to this editor instance (optional). + * @param $events (array) Event listeners for this editor instance (optional). + * + * Example 1: adding %CKEditor to <textarea name="article"></textarea> element: + * @code + * $CKEditor = new CKEditor(); + * $CKEditor->replace("article"); + * @endcode + */ + public function replace($id, $config = array(), $events = array()) + { + $out = ""; + if (!$this->initialized) { + $out .= $this->init(); + } + + $_config = $this->configSettings($config, $events); + + $js = $this->returnGlobalEvents(); + if (!empty($_config)) { + $js .= "CKEDITOR.replace('".$id."', ".$this->jsEncode($_config).");"; + } + else { + $js .= "CKEDITOR.replace('".$id."');"; + } + $out .= $this->script($js); + + if (!$this->returnOutput) { + print $out; + $out = ""; + } + + return $out; + } + + /** + * Replace all <textarea> elements available in the document with editor instances. + * + * @param $className (string) If set, replace all textareas with class className in the page. + * + * Example 1: replace all <textarea> elements in the page. + * @code + * $CKEditor = new CKEditor(); + * $CKEditor->replaceAll(); + * @endcode + * + * Example 2: replace all <textarea class="myClassName"> elements in the page. + * @code + * $CKEditor = new CKEditor(); + * $CKEditor->replaceAll( 'myClassName' ); + * @endcode + */ + public function replaceAll($className = null) + { + $out = ""; + if (!$this->initialized) { + $out .= $this->init(); + } + + $_config = $this->configSettings(); + + $js = $this->returnGlobalEvents(); + if (empty($_config)) { + if (empty($className)) { + $js .= "CKEDITOR.replaceAll();"; + } + else { + $js .= "CKEDITOR.replaceAll('".$className."');"; + } + } + else { + $classDetection = ""; + $js .= "CKEDITOR.replaceAll( function(textarea, config) {\n"; + if (!empty($className)) { + $js .= " var classRegex = new RegExp('(?:^| )' + '". $className ."' + '(?:$| )');\n"; + $js .= " if (!classRegex.test(textarea.className))\n"; + $js .= " return false;\n"; + } + $js .= " CKEDITOR.tools.extend(config, ". $this->jsEncode($_config) .", true);"; + $js .= "} );"; + + } + + $out .= $this->script($js); + + if (!$this->returnOutput) { + print $out; + $out = ""; + } + + return $out; + } + + /** + * Adds event listener. + * Events are fired by %CKEditor in various situations. + * + * @param $event (string) Event name. + * @param $javascriptCode (string) Javascript anonymous function or function name. + * + * Example usage: + * @code + * $CKEditor->addEventHandler('instanceReady', 'function (ev) { + * alert("Loaded: " + ev.editor.name); + * }'); + * @endcode + */ + public function addEventHandler($event, $javascriptCode) + { + if (!isset($this->events[$event])) { + $this->events[$event] = array(); + } + // Avoid duplicates. + if (!in_array($javascriptCode, $this->events[$event])) { + $this->events[$event][] = $javascriptCode; + } + } + + /** + * Clear registered event handlers. + * Note: this function will have no effect on already created editor instances. + * + * @param $event (string) Event name, if not set all event handlers will be removed (optional). + */ + public function clearEventHandlers($event = null) + { + if (!empty($event)) { + $this->events[$event] = array(); + } + else { + $this->events = array(); + } + } + + /** + * Adds global event listener. + * + * @param $event (string) Event name. + * @param $javascriptCode (string) Javascript anonymous function or function name. + * + * Example usage: + * @code + * $CKEditor->addGlobalEventHandler('dialogDefinition', 'function (ev) { + * alert("Loading dialog: " + ev.data.name); + * }'); + * @endcode + */ + public function addGlobalEventHandler($event, $javascriptCode) + { + if (!isset($this->globalEvents[$event])) { + $this->globalEvents[$event] = array(); + } + // Avoid duplicates. + if (!in_array($javascriptCode, $this->globalEvents[$event])) { + $this->globalEvents[$event][] = $javascriptCode; + } + } + + /** + * Clear registered global event handlers. + * Note: this function will have no effect if the event handler has been already printed/returned. + * + * @param $event (string) Event name, if not set all event handlers will be removed (optional). + */ + public function clearGlobalEventHandlers($event = null) + { + if (!empty($event)) { + $this->globalEvents[$event] = array(); + } + else { + $this->globalEvents = array(); + } + } + + /** + * Prints javascript code. + * + * @param string $js + */ + private function script($js) + { + $out = "\n"; + + return $out; + } + + /** + * Returns the configuration array (global and instance specific settings are merged into one array). + * + * @param $config (array) The specific configurations to apply to editor instance. + * @param $events (array) Event listeners for editor instance. + */ + private function configSettings($config = array(), $events = array()) + { + $_config = $this->config; + $_events = $this->events; + + if (is_array($config) && !empty($config)) { + $_config = array_merge($_config, $config); + } + + if (is_array($events) && !empty($events)) { + foreach ($events as $eventName => $code) { + if (!isset($_events[$eventName])) { + $_events[$eventName] = array(); + } + if (!in_array($code, $_events[$eventName])) { + $_events[$eventName][] = $code; + } + } + } + + if (!empty($_events)) { + foreach($_events as $eventName => $handlers) { + if (empty($handlers)) { + continue; + } + else if (count($handlers) == 1) { + $_config['on'][$eventName] = '@@'.$handlers[0]; + } + else { + $_config['on'][$eventName] = '@@function (ev){'; + foreach ($handlers as $handler => $code) { + $_config['on'][$eventName] .= '('.$code.')(ev);'; + } + $_config['on'][$eventName] .= '}'; + } + } + } + + return $_config; + } + + /** + * Return global event handlers. + */ + private function returnGlobalEvents() + { + static $returnedEvents; + $out = ""; + + if (!isset($returnedEvents)) { + $returnedEvents = array(); + } + + if (!empty($this->globalEvents)) { + foreach ($this->globalEvents as $eventName => $handlers) { + foreach ($handlers as $handler => $code) { + if (!isset($returnedEvents[$eventName])) { + $returnedEvents[$eventName] = array(); + } + // Return only new events + if (!in_array($code, $returnedEvents[$eventName])) { + $out .= ($code ? "\n" : "") . "CKEDITOR.on('". $eventName ."', $code);"; + $returnedEvents[$eventName][] = $code; + } + } + } + } + + return $out; + } + + /** + * Initializes CKEditor (executed only once). + */ + private function init() + { + static $initComplete; + $out = ""; + + if (!empty($initComplete)) { + return ""; + } + + if ($this->initialized) { + $initComplete = true; + return ""; + } + + $args = ""; + $ckeditorPath = $this->ckeditorPath(); + + if (!empty($this->timestamp) && $this->timestamp != "%"."TIMESTAMP%") { + $args = '?t=' . $this->timestamp; + } + + // Skip relative paths... + if (strpos($ckeditorPath, '..') !== 0) { + $out .= $this->script("window.CKEDITOR_BASEPATH='". $ckeditorPath ."';"); + } + + $out .= "\n"; + + $extraCode = ""; + if ($this->timestamp != self::timestamp) { + $extraCode .= ($extraCode ? "\n" : "") . "CKEDITOR.timestamp = '". $this->timestamp ."';"; + } + if ($extraCode) { + $out .= $this->script($extraCode); + } + + $initComplete = $this->initialized = true; + + return $out; + } + + /** + * Return path to ckeditor.js. + */ + private function ckeditorPath() + { + if (!empty($this->basePath)) { + return $this->basePath; + } + + /** + * The absolute pathname of the currently executing script. + * Note: If a script is executed with the CLI, as a relative path, such as file.php or ../file.php, + * $_SERVER['SCRIPT_FILENAME'] will contain the relative path specified by the user. + */ + if (isset($_SERVER['SCRIPT_FILENAME'])) { + $realPath = dirname($_SERVER['SCRIPT_FILENAME']); + } + else { + /** + * realpath â Returns canonicalized absolute pathname + */ + $realPath = realpath( './' ) ; + } + + /** + * The filename of the currently executing script, relative to the document root. + * For instance, $_SERVER['PHP_SELF'] in a script at the address http://example.com/test.php/foo.bar + * would be /test.php/foo.bar. + */ + $selfPath = dirname($_SERVER['PHP_SELF']); + $file = str_replace("\\", "/", __FILE__); + + if (!$selfPath || !$realPath || !$file) { + return "/ckeditor/"; + } + + $documentRoot = substr($realPath, 0, strlen($realPath) - strlen($selfPath)); + $fileUrl = substr($file, strlen($documentRoot)); + $ckeditorUrl = str_replace("ckeditor_php5.php", "", $fileUrl); + + return $ckeditorUrl; + } + + /** + * This little function provides a basic JSON support. + * http://php.net/manual/en/function.json-encode.php + * + * @param mixed $val + * @return string + */ + private function jsEncode($val) + { + if (is_null($val)) { + return 'null'; + } + if ($val === false) { + return 'false'; + } + if ($val === true) { + return 'true'; + } + if (is_scalar($val)) + { + if (is_float($val)) + { + // Always use "." for floats. + $val = str_replace(",", ".", strval($val)); + } + + // Use @@ to not use quotes when outputting string value + if (strpos($val, '@@') === 0) { + return substr($val, 2); + } + else { + // All scalars are converted to strings to avoid indeterminism. + // PHP's "1" and 1 are equal for all PHP operators, but + // JS's "1" and 1 are not. So if we pass "1" or 1 from the PHP backend, + // we should get the same result in the JS frontend (string). + // Character replacements for JSON. + static $jsonReplaces = array(array("\\", "/", "\n", "\t", "\r", "\b", "\f", '"'), + array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"')); + + $val = str_replace($jsonReplaces[0], $jsonReplaces[1], $val); + + return '"' . $val . '"'; + } + } + $isList = true; + for ($i = 0, reset($val); $i < count($val); $i++, next($val)) + { + if (key($val) !== $i) + { + $isList = false; + break; + } + } + $result = array(); + if ($isList) + { + foreach ($val as $v) $result[] = $this->jsEncode($v); + return '[ ' . join(', ', $result) . ' ]'; + } + else + { + foreach ($val as $k => $v) $result[] = $this->jsEncode($k).': '.$this->jsEncode($v); + return '{ ' . join(', ', $result) . ' }'; + } + } +} diff --git a/ckeditor_source.js b/ckeditor_source.js index 7eca88a..eab13f6 100644 --- a/ckeditor_source.js +++ b/ckeditor_source.js @@ -1,11 +1,11 @@ /* -Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. +Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved. For licensing, see LICENSE.html or http://ckeditor.com/license */ // Compressed version of core/ckeditor_base.js. See original for instructions. /*jsl:ignore*/ -if(!window.CKEDITOR)window.CKEDITOR=(function(){var a={timestamp:'',version:'3.0.2',revision:'4760',_:{},status:'unloaded',basePath:(function(){var d=window.CKEDITOR_BASEPATH||'';if(!d){var e=document.getElementsByTagName('script');for(var f=0;f