FCKeditor 修改日记

来源:互联网 发布:数控车床编程步骤 编辑:程序博客网 时间:2024/05/11 18:54

hcling97.NET 2006.06.26
FCKeditor Version 2.3b

[Installation and modify]

1.安装:将FCKeditor_2.3b.zip中的FCKeditor目录拷贝到更目录下,里面存放的主要是编辑器的js脚本。将其中的以"_"为开头的文件夹统统删除,这些文件夹里放的是范例或是一些其它工具。其实也就是只保留editor文件夹、fckconfig.js、fckeditor.asp、fckeditor.js、fckstyles.xml、fcktemplates.xml就可以了,最外层的精简化完毕,进入到editor文件夹内,先把"_source"文件夹删除,这里是一些源文件,对于使用来说没什么用处。将FCKeditor.Net_2.2.zip解压后的bin文件夹中的FredCK.FCKeditorV2.dll文件添加到项目的引用,添加工具栏控件,选择这个dll,将新增加一个控件FCKeditor。即可使用。

2.进入FCKeditor/filemanager文件夹,有browser和upload两个文件夹。进入browser/default/connectors,只保留aspx文件夹,其余的删掉;mcpuk目录亦可删除;upload也一样,只保留aspx文件夹。

3.编辑fckconfig.js文件修改FCKConfig.DefaultLanguage='en';为FCKConfig.DefaultLanguage='zh-cn';修改var _FileBrowserLanguage = 'asp';var _QuickUploadLanguage='asp';为var _FileBrowserLanguage='aspx';var _QuickUploadLanguage='aspx'。

4.修改web.config在<appSettings>添加节<add key="FCKeditor:BasePath" value="/FCKeditor/"/><add key="FCKeditor:UserFilesPath" value="/UserFiles"/>为了防止提交html代码出错的问题,还需在<system.web>要添加节<pages validateRequest="false"/>。

5.修改fckconfig.js中的FCKConfig.ToolbarSets["Default"]自定义工具栏显示情况。修改FCKConfig.TabSpaces= 1使可以在编辑区域内使用Tab键。

6.修改fckconfig.js设置字体FCKConfig.FontNames='Arial;Comic Sans MS;Courier New;Tahoma;Times New Roman;Verdana;宋体;黑体;隶书;楷体_GB2312';由于默认的字体是Arial,把中文添加在后面是最合理的。

7.上传修改FCKConfig.LinkBrowser=false;FCKConfig.ImageBrowser=false;FCKConfig.FlashBrowser=false;不需要其提供的目录方式管理,去除之。


[Problem]

a.文件上传没有,上传后直接引用没有。服务器文件浏览dialog希望屏蔽,屏蔽后需要上传文件。

b.上传的文件需要归类到不同的文件夹,需要修改dll文件。

--06.06.26 stop here


[analyze FckEditor .net source code,Find how to modify the toolbar]

1. FCKeditor.cs
writer.Write("<iframe id=/"{0}___Frame/" src=/"{1}/" width=/"{2}/" height=/"{3}/" frameborder=/"no/" scrolling=/"no/"></iframe>",this.ClientID,sLink,this.Width,this.Height ) ;
结论:实例化实际上是在页面中写入了一个<iframe>标签,打开客户端源代码看到:<iframe id="FCKeditor1___Frame" src="/FCKeditor/editor/fckeditor.html?InstanceName=FCKeditor1&Toolbar=Default" width="100%" height="600px" frameborder="no" scrolling="no"></iframe>依靠其中的InstanceName参数也就是ClientID的值来标识。

2. _fckviewstrips.html
搜索"包含fck_strip.gif"有三个结果(_fckviewstrips.html,fckeditorcode_ie.js,fckeditorcode_gecko.js)。
eCell.innerHTML = '<div class="TB_Button_Image"><img src="default/fck_strip.gif" style="top=-' + ( i * 16 ) + 'px;"></div>' ;
结论:可见一个个小图标是显示了fck_strip.gif中的一截,算法是自上而下一个一个加16px,然后只显示16px高的一个小方框。

3.fckeditorcode_ie.js
var FCKMenuBlock=function(A){this.Dir=A||'ltr';this.Items=new Array();if (FCK.IECleanup) FCK.IECleanup.AddItem(this,this._Cleanup);};FCKMenuBlock.prototype.AddItem=function(A,B,C,D){if (typeof(C)=='number') C=[FCKConfig.SkinPath+'fck_strip.gif',16,C];var E=new FCKMenuItem(A,B,C,D,this.Dir);E.Dir=this.Dir;E._FCKMenuBlock=this;E.OnClick=FCKMenuBlock_OnItemClick;this.Items[this.Items.length]=E;return E;};FCKMenuBlock.prototype.AddSeparator=function(){this.Items[this.Items.length]=new FCKMenuSeparator();};FCKMenuBlock.prototype.RemoveAllItems=function(){this.Items=new Array();};FCKMenuBlock.prototype.Create=function(A){if (this.MainElement){this.MainElement.parentNode.removeChild(this.MainElement);this._Cleanup();};var B=A.ownerDocument;var C=B.createElement('table');C.dir=this.Dir;C.cellPadding=0;C.cellSpacing=0;var D=this.MainElement=C.insertRow(-1).insertCell(-1);D.className='MN_Menu';var E=D.appendChild(B.createElement('table'));E.cellPadding=0;E.cellSpacing=0;for (var i=0;i<this.Items.length;i++){var F=this.Items[i];if (this.Panel) F.Panel=this.Panel;F.Create(E);};A.appendChild(C);FCKTools.DisableSelection(C);};FCKMenuBlock.prototype._Cleanup=function(){this.MainElement=null;};function FCKMenuBlock_OnItemClick(menuItem){var oMenuBlock=menuItem._FCKMenuBlock;if (oMenuBlock.OnItemClick) oMenuBlock.OnItemClick(oMenuBlock,menuItem);};var FCKMenuSeparator=function(){};FCKMenuSeparator.prototype.Create=function(A){var B=A.ownerDocument;var r=A.insertRow(-1);var C=r.insertCell(-1);C.className='MN_Separator MN_Icon';C=r.insertCell(-1);C.className='MN_Separator';C.appendChild(B.createElement('DIV')).className='MN_Separator_Line';C=r.insertCell(-1);C.className='MN_Separator';C.appendChild(B.createElement('DIV')).className='MN_Separator_Line';}
结论:发现E.OnClick=FCKMenuBlock_OnItemClick,继续搜索FCKMenuBlock_OnItemClick的prototype code。

function FCKMenuBlock_OnItemClick(menuItem){var oMenuBlock=menuItem._FCKMenuBlock;if (oMenuBlock.OnItemClick) oMenuBlock.OnItemClick(oMenuBlock,menuItem);}
结论:至此,不管下文,先修改图片。

4.fck_strip.gif
文件修改完毕,把falsh的图标换成了附件。 在_fckviewstrips.html中有所反应,fckeditor.html也能够正确显示咯,但是在具体的控件中的图标没有变化,看来真的需要分析具体代码咯。老子ft!
结论:原来是iframe内部页面刷新的问题,缓存了图片,用
http://IP/FCKeditor/editor/fckeditor.html?InstanceName=FCKeditor1&Toolbar=Default来访问,然后刷新就可以正确显示咯。

5.zh-cn.js
InsertFlash: "上传附件",lang目录下的语言文件,用于鼠标移动到原flash图标上的提示信息。修改后提示正常。
procedure:1.修改上传flash的界面到上传任意文件。 2.修改fckconfig.js来把扩展名扩大范围。 3.判断是不是falsh,如果是falsh就调用原来的页面来预览和引用,如果不是则在editor的value附加上上传的地址和点击查看字样。 4.修改dll来支持上传文件文件名及目录结构。

--06.06.27 stop here

6.zh-cn.js
文件中查找//Flash Dialog下的DlgFlashTitle : "Flash 属性",修改为"文件上传",按照4中的刷新步骤刷新。dialog的标题就修正咯。

7.fckconfig.js
FCKConfig.LinkBrowser = false ;FCKConfig.ImageBrowser = false ;FCKConfig.FlashBrowser = false ;FCKConfig.LinkUpload = false ;FCKConfig.ImageUpload = true ;FCKConfig.FlashUpload = true ;
效果:这样就屏蔽了服务器端文件浏览界面。

FCKConfig.FlashUploadAllowedExtensions = "" ;// empty for all
FCKConfig.FlashUploadDeniedExtensions = ".(php|php3|php5|phtml|asp|aspx|ascx|jsp|cfm|cfc|pl|bat|exe|dll|reg|cgi|js)$" ;// empty for no one
效果:这样,在原falsh上传的界面里面可以上传除了DeniedExtensions里面规定的扩展名的所有的文件咯。下一步就真正需要修改程序流程咯。列表中追加一个js文件扩展名,防止上传js文件使用自己的config,上传任意文件。有问题的fckeditor客户端初始化javascript代码如下:
var oFCKeditor = new FCKeditor( 'FCKeditor1' ) ;
oFCKeditor.Config['CustomConfigurationsPath'] = '/myconfig.js' ;
oFCKeditor.Create() ;
在baidu搜索"fckblank.html",就会发现机器很多。

FCKConfig.LinkDlgHideAdvanced = true; FCKConfig.ImageDlgHideAdvanced = true ;FCKConfig.FlashDlgHideAdvanced = true ;
效果:屏蔽上传界面中的"高级"标签卡。这点是在第9条分析fck_flash.js文件内容的时候得出的。

8.fck_image_preview.html
fck_image.html 中<iframe class="ImagePreviewArea" src="fck_image/fck_image_preview.html" frameborder="0" marginheight="0" marginwidth="0"></iframe>表明了预览区域在fck_image_preview.html中。
效果:把其中的一大段不知道什么文字删掉,图片预览中的那一段阿里不大的冬冬就没有了,看着清净。删除缓存内容,刷新。

9.fck_flash.html
<div id="divUpload" style="DISPLAY: none">由此可知道几个页面之间的切换实际上是假象,真正的页面只有一个,所控制的是div的显示与否,害的我找了上传页面半天,代码还是要仔细看。
结论:显示与否的判断根据fckconfig.cs中的几个js参数来定的,就是第7条中的那几个参数。

<form id="frmUpload" method="post" target="UploadWindow" enctype="multipart/form-data" action="" onsubmit="return CheckUpload();">
继续CheckUpload()函数在引用的fck_flash.js文件中。用途是扩展名过滤,和错误处理信息弹出窗口。

target="UploadWindow",其中的UploadWindow是一个iframe代码在下面 <iframe name="UploadWindow" style="DISPLAY: none" src="../fckblank.html"></iframe>
再看fckblank.html。不要看了,不要被他的这个空白页迷惑咯,其实真正的action的地址在fck_flash.js中:
if ( FCKConfig.FlashUpload ) GetE('frmUpload').action = FCKConfig.FlashUploadURL ;
结论:实际上就是用fckconfig.js文件中的上传页面参数FlashUploadURL,对于我们.net版本的就是upload.aspx咯。终于弄通了,nnd。

10.fck_flash.js
添加 var oExtToPreviewRegex = new RegExp( ".(swf)$", 'i' ) ; 在UpdatePreview();外面添加if(oExtToPreviewRegex.test(url))条件。
效果:定义一个我们自己的对象,用系统一致的方法来实现扩展名的辨别,如果是swf文件就用他自带的预览来预览flash,如果不是就不预览。
此步骤后面有所改动,作废。

--06.06.28 stop here

11.fck_flash.html
打开DW编辑html文件,width旁边增加一列,里面增加一个table,增加<span fcklang="LinkText">Link Label</span><br><input id="linktext" onblur="UpdatePreview();" type="text">
不用自己重新创建,从fck_link里面把select控件拷贝出来,加到这个页面里面去,<span fckLang="DlgLnkTarget">Target</span><br><select id="cmbTarget">删除中间一些category,剩下几个常用的,删除原来的onSelectChange事件。
修改一下zh-cn.js,添加一下语言项目:LinkText : "链接标签",注意最后的逗号不能少。
效果:我们需要的几个控件都有咯,上方的Link Label被正确翻译为"链接标签"。

12.fck_flash.js

>> CODE

//tips by hcling97 06.06.29
if(oExtToPreviewRegex.test(GetE('txtUrl').value)) //这样,是swf文件,我们就提供预览,不是就算。
{
var oDoc = ePreview.ownerDocument || ePreview.document ;
var e = oDoc.createElement( 'EMBED' ) ;

e.src = GetE('txtUrl').value ;
e.type = 'application/x-shockwave-flash' ;
e.width = '100%' ;
e.height = '100%' ;

ePreview.appendChild( e ) ;
}
else
{
var targetAttr = GetE('cmbTarget').value.length==0 ? '' : 'target="'+GetE('cmbTarget').value+'"' ;
var linkTextLabel = GetE('linktext').value.length==0 ? 'Default link label' : GetE('linktext').value ;
ePreview.innerHTML = '<br><a href="'+GetE('txtUrl').value+'" '+targetAttr+'>'+linkTextLabel+'</a>';
}




--06.06.29 stop here


13.fckconfig.js
FCKConfig.ImageDlgHideLink = true ;
效果:屏蔽image窗口里面的链接标签栏。

14.zh_cn.js
搜索"超链接信息",发现是翻译自"DlgLnkInfoTab" 再仔细分析fck_link.js 发现自己原来走了那么多的弯弯路。link按钮是被我自己取消掉的,实际上上传文件在link按钮里面,功能还相当不错。要改变的只是一个工作习惯问题,先编辑字符,高亮选择以后再上传文件编辑链接就可以了。so,现在剩下的工作就是.net uploader.cs的修改咯。
重新来过,旧的文件夹打包,重新修改。

15.uploader.cs

>> CODE

修改程序段以下部分:
string[] fileExt = new string[11] {"xls","jpeg","jpg","gif","doc","swf","png","txt","rar","zip","bmp"};
if(this.CheckAllowFileExt(sFileName,fileExt))//这里判断一下扩展名比较安全。
{
while ( true )
{
string sFilePath = System.IO.Path.Combine( this.UserFilesDirectory, sFileName ) ;

if ( System.IO.File.Exists( sFilePath ) ) //虽然我们用自己的方法不会造成重名,但是改动程序小一点比较好。
{
iCounter++ ;
sFileName =
System.IO.Path.GetFileNameWithoutExtension( oFile.FileName ) +
"(" + iCounter + ")" +
System.IO.Path.GetExtension( oFile.FileName ) ;

iErrorNumber = 201 ;
}
else
{
oFile.SaveAs( sFilePath ) ;

sFileUrl = this.UserFilesPath + sFileName ;
break ;
}
}
}
else
{
SendResults( 202 ) ; //我们还是利用他的js来报错,这样最合理。
return ;
}

增加扩展名判断函数

/// <summary>
/// 判断扩展名是否合法
/// </summary>
/// <param name="filename">文件名</param>
/// <param name="allowExt">扩展名列表</param>
/// <returns>true or false</returns>
private bool CheckAllowFileExt(string filename,string[] allowExt)
{
string fileExt = System.IO.Path.GetExtension(filename).Remove(0,1).Trim();
for(int i=0;i<allowExt.Length;i++)
{
if(string.Equals(fileExt.ToLower(),allowExt[i].ToLower()))
{
return true;
}
}
return false;
}




重新编译以后在主项目中的引用还需要编译,否则会出现"程序集清单定义与程序集引用不匹配"的错误。

--2006.07.03 stop here