多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > web前端 > jscript > FCKeditor源碼分析(一):fckeditor.js中文注釋

FCKeditor源碼分析(一):fckeditor.js中文注釋

來源:程序員人生   發布時間:2014-03-30 18:23:13 閱讀次數:3158次

  這幾天都在研究FCKeditor的源代碼( 什么是FCKeditor?)幾乎搜遍了Internet,似乎對于fckconfig.js這個文件講解的很多,但對于fckeditor.js這個FCK的核心類文件的資料幾乎為0. 所以,花了整整一天的時間,以擠牙膏的方式,對fckeditor.js這個fck核心類文件作了自己力所能及的注釋,供同樣學習fck的網友一個參考。 注:本文基于FCKeditor2.6.5

1. /**
2. *
3. * ***********CopyRight**************
4. *-------Annotated by nileader-----
5. *-----Version 1.00 2009-10-18-----
6. *-----Once copied, marked http://www.nileader.cn
7. *
8. * FCKeditor 類 annotated by nileader
9. * @param {Object} instanceName 編輯器的唯一名稱(相當于ID) 是不可省參數,
10. * width,height,toolbarset,value 都是 可選參數
11. */
12. var FCKeditor = function( instanceName, width, height, toolbarSet, value )
13. {
14. //編輯器的基本屬性 注意:這些東西優先于FCKConfig.js中的配置
15.
16. this.InstanceName = instanceName ; //編輯器的唯一名稱(相當于ID)(必須有!)
17. this.Width = width || '100%' ; //寬度 默認是100%
18. this.Height = height || '200' ; //寬度 默認是200
19. this.ToolbarSet = toolbarSet || 'Default' ;//工具集名稱,默認值是Default
20. this.Value = value || '' ; //初始化編輯器的HTML代碼,默認值為空
21. //編輯器初始化的時候默認的根路徑, 其作用是編寫fck中,凡是用到的路徑,均從FCKeditor.BasePath目錄開始 默認為/Fckeditor/
22. this.BasePath = FCKeditor.BasePath ;
23. this.CheckBrowser = true ; //是否在顯示編輯器前檢查瀏覽器兼容性,默認為true
24. this.DisplayErrors = true ; //是否顯示提示錯誤,默為true
25. this.Config = new Object() ;
26. // Events
27. this.OnError = null ; // function( source, errorNumber, errorDescription )自定義的錯誤處理函數
28. }
29. FCKeditor.BasePath = '/fckeditor/' ; // fck默認的根目錄
30. FCKeditor.MinHeight = 200 ; //高和寬的限制
31. FCKeditor.MinWidth = 750 ;
32. FCKeditor.prototype.Version = '2.6.5' ; //版本號
33. FCKeditor.prototype.VersionBuild = '23959' ;
34. /**
35. * 調用CreateHtml()來生成編輯器的html代碼并在頁面上輸出編輯器
36. */
37. FCKeditor.prototype.Create = function()
38. {
39. //調用createhtml()方法
40. document.write( this.CreateHtml() ) ;
41. }
42. /**
43. * @return sHtml 用于生成編輯器的html代碼
44. */
45. FCKeditor.prototype.CreateHtml = function()
46. {
47. // 檢查有無InstanceName 如果沒有則不生成html代碼
48. if ( !this.InstanceName || this.InstanceName.length == 0 )
49. {
50. this._ThrowError( 701, 'You must specify an instance name.' ) ;
51. return '' ;
52. }
53. //函數的返回值
54. var sHtml = '' ;
55. /*
56. * 當用戶的瀏覽器符合預設的幾種瀏覽器時,
57. * 生成一個id="this.instancename" name="this.instancename"的文本框,事實上的內容儲存器
58. */
59. if ( !this.CheckBrowser || this._IsCompatibleBrowser() )
60. {
61. //將此時FCK初始值通過轉義之后放入這個input
62. sHtml += '<input type="hidden" id="' + this.InstanceName + '" name="' + this.InstanceName + '" value="' + this._HTMLEncode( this.Value ) + '" style="display:none" mce_style="display:none" />' ;
63. //生成一個隱藏的INPUT來放置this.config中的內容
64. sHtml += this._GetConfigHtml() ;
65. //生成編輯器的iframe的代碼
66. sHtml += this._GetIFrameHtml() ;
67. }
68. /**
69. * 如果用戶的瀏覽器不兼容FCK默認的幾種瀏覽器
70. * 只能有傳統的textarea了
71. */
72. else
73. {
74. var sWidth = this.Width.toString().indexOf('%') > 0 ? this.Width : this.Width + 'px' ;
75. var sHeight = this.Height.toString().indexOf('%') > 0 ? this.Height : this.Height + 'px' ;
76. sHtml += '<textarea name="' + this.InstanceName +
77. '" rows="4" cols="40" style="width:' + sWidth +
78. ';height:' + sHeight ;
79. if ( this.TabIndex )
80. sHtml += '" tabindex="' + this.TabIndex ;
81. sHtml += '">' +
82. this._HTMLEncode( this.Value ) +
83. '</textarea>' ;
84. }
85. return sHtml ;
86. }
87. /**
88. * 用編輯器來替換對應的文本框
89. */
90. FCKeditor.prototype.ReplaceTextarea = function()
91. {
92. //如果已經有了 id=THIS.INSTANCENAME___Frame 的標簽時,直接返回
93. if ( document.getElementById( this.InstanceName + '___Frame' ) )
94. return ;
95. //當用戶的瀏覽器符合預設的幾種瀏覽器時
96. if ( !this.CheckBrowser || this._IsCompatibleBrowser() )
97. {
98. // We must check the elements firstly using the Id and then the name.
99. //獲取id=this.InstanceName的html標簽
100. var oTextarea = document.getElementById( this.InstanceName ) ;
101. //獲取所有name=THIS.instancename的標簽
102. var colElementsByName = document.getElementsByName( this.InstanceName ) ;
103. var i = 0;
104. /*
105. * 考慮到用戶html標簽的命名不規范,所以進行以下編歷判斷 筆者指的是用戶在textarea標簽處用了name=this.instancename
106. * 在同個頁面的其它標簽上也用了name=this.instancename
107. */
108. while ( oTextarea || i == 0 )
109. {
110. //遍歷,直到找到name=this.instancename的textarea標簽,并賦給oTextarea
111. if ( oTextarea && oTextarea.tagName.toLowerCase() == 'textarea' )
112. break ;
113. oTextarea = colElementsByName[i++] ;
114. }
115. //如果不存在id或者name為this.instancename的標簽時,彈出錯誤框
116. if ( !oTextarea )
117. {
118. alert( 'Error: The TEXTAREA with id or name set to "' + this.InstanceName + '" was not found' ) ;
119. return ;
120. }
121. /*
122. * 確定存在name=this.instancename的textarea標簽后,將編輯器的代碼賦給它
123. */
124. oTextarea.style.display = 'none' ;
125. //如果頁面上對這樣的textarea標簽定義了tab鍵的順序,賦給this.TabIndex待用
126. if ( oTextarea.tabIndex )
127. this.TabIndex = oTextarea.tabIndex ;
128. this._InsertHtmlBefore( this._GetConfigHtml(), oTextarea ) ;
129. this._InsertHtmlBefore( this._GetIFrameHtml(), oTextarea ) ;
130. }
131. }
132.
133.
134.
135. /**
136. * 在指定的頁面標簽前面插入html代碼
137. * @param {Object} 待插入的html代碼
138. * @param {Object} 指定的頁面標簽(對象)
139. */
140. FCKeditor.prototype._InsertHtmlBefore = function( html, element )
141. {
142. if ( element.insertAdjacentHTML ) // IE 私有的 insertAdjacentHTML 方法
143. element.insertAdjacentHTML( 'beforeBegin', html ) ;
144. else // 非ie瀏覽器
145. {
146.
147. var oRange = document.createRange() ;
148. oRange.setStartBefore( element ) ;
149. var oFragment = oRange.createContextualFragment( html );
150. element.parentNode.insertBefore( oFragment, element ) ;
151. }
152. }
153.
154.
155. /*
156. * 通過編歷this.Config[]來生成一個隱藏域,
157. * 例如:
158. * this.Config['nileader']="1104",this.Config['leaderni']="nichao"……
159. * 那么,sConfig=…… &nileader=1104&leaderni=nichao ……
160. * 當然,最終,sConfig會被encodeURIComponent函數轉換成百分比編碼 放入隱藏的INPUT中去
161. */
162. FCKeditor.prototype._GetConfigHtml = function()
163. {
164. var sConfig = '' ;
165. for ( var o in this.Config )
166. {
167. if ( sConfig.length > 0 ) sConfig += '&' ;
168. //encodeURIComponent函數轉換成百分比編碼
169. sConfig += encodeURIComponent( o ) + '=' + encodeURIComponent( this.Config[o] ) ;
170. }
171. return '<input type="hidden" id="' + this.InstanceName + '___Config" value="' + sConfig + '" style="display:none" mce_style="display:none" />' ;
172. }
173.
174. /*
175. * 生成iframe的html 這里涉及到src的確定
176. */
177. FCKeditor.prototype._GetIFrameHtml = function()
178. {
179. var sFile = 'fckeditor.html' ;
180. //特殊情況 fckedito所在的窗口沒有嵌入在瀏覽器中
181. try
182. {
183. if ( (/fcksource=true/i).test( window.top.location.search ) )
184. sFile = 'fckeditor.original.html' ;
185. }
186. catch (e) { /* 忽略這個異常. 很多時候,fckedito所在的窗口嵌入在瀏覽器中. */ }
187. /*
188. * 這里注意的一點:
189. * iframe的工作原理: 當iframe處于可編輯狀態時,其實編輯的是src所在的頁面
190. * 這里合成一個sLink以放入iframe標簽中
191. */
192. //sLink就是這個事實上的頁面了,從fck的根目錄開始,例如 sLink=/fckeditor/editor/fckeditor.html?InstanceName=nileader&Toolbar=nileadersbar
193. var sLink = this.BasePath + 'editor/' + sFile + '?InstanceName=' + encodeURIComponent( this.InstanceName ) ;
194. if (this.ToolbarSet)
195. sLink += '&Toolbar=' + this.ToolbarSet ;
196. //生成一個真正的編輯iframer的html代碼 當然,放入了src=slink title="liehuo.net"
197. var html = '<iframe id="' + this.InstanceName +
198. '___Frame" src="' + sLink +
199. '" mce_src="' + sLink +
200. '" width="' + this.Width +
201. '" height="' + this.Height ;
202. //如果設定了使用"Tab"鍵的遍歷順序,則賦給iframe
203. if ( this.TabIndex )
204. html += '" tabindex="' + this.TabIndex ;
205. html += '" frameborder="0" scrolling="no"></iframe>' ;
206. return html ;
207. }
208.
209. /*
210. * 檢測用戶的bowser是否是fck的默認
211. * 這個方法只是fck公司追求oo,無意義
212. */
213. FCKeditor.prototype._IsCompatibleBrowser = function()
214. {
215. return FCKeditor_IsCompatibleBrowser() ;
216. }
217.
218. /**
219. * 拋出錯誤
220. * @param {Object} errorNumber 錯誤編號
221. * @param {Object} errorDescription 錯誤概述
222. */
223. FCKeditor.prototype._ThrowError = function( errorNumber, errorDescription )
224. {
225. this.ErrorNumber = errorNumber ;
226. this.ErrorDescription = errorDescription ;
227. //是否顯示提示錯誤,默為true
228. if ( this.DisplayErrors )
229. { //將錯誤編號和錯誤概述打印出來
230. document.write( '<div style="COLOR: #ff0000" mce_style="COLOR: #ff0000">' ) ;
231. document.write( '[ FCKeditor Error ' + this.ErrorNumber + ': ' + this.ErrorDescription + ' ]' ) ;
232. document.write( '</div>' ) ;
233. }
234. //OnError是否自定義了錯誤處理函數,若定義了,由其處理
235. if ( typeof( this.OnError ) == 'function' )
236. this.OnError( this, errorNumber, errorDescription ) ;
237. }
238.
239. /**
240. * 轉義文本
241. * @param {Object} text 待轉義的文本
242. * @return String text 轉義完后的文本
243. */
244. FCKeditor.prototype._HTMLEncode = function( text )
245. {
246. if ( typeof( text ) != "string" )
247. text = text.toString() ;
248. //將字符串中的所有 & " < > 用對應的轉義字符代換
249. text = text.replace(
250. /&/g, "&").replace(
251. /"/g, """).replace(
252. /</g, "<").replace(
253. />/g, ">") ;
254. return text ;
255. }
256.
257. ;(function()
258. {
259. //把頁面上的textarea元素賦給editor變量
260. var textareaToEditor = function( textarea )
261. {
262. var editor = new FCKeditor( textarea.name ) ;
263. editor.Width = Math.max( textarea.offsetWidth, FCKeditor.MinWidth ) ;
264. editor.Height = Math.max( textarea.offsetHeight, FCKeditor.MinHeight ) ;
265. return editor ;
266. }
267. /**
268. * Replace all <textarea> elements available in the document with FCKeditor
269. * instances.
270. *
271. * // Replace all <textarea> elements in the page.
272. * FCKeditor.ReplaceAllTextareas() ;
273. *
274. * // Replace all <textarea class="myClassName"> elements in the page.
275. * FCKeditor.ReplaceAllTextareas( 'myClassName' ) ;
276. *
277. * // Selectively replace <textarea> elements, based on custom assertions.
278. * FCKeditor.ReplaceAllTextareas( function( textarea, editor )
279. * {
280. * // Custom code to evaluate the replace, returning false if it
281. * // must not be done.
282. * // It also passes the "editor" parameter, so the developer can
283. * // customize the instance.
284. * } ) ;
285. */
286. FCKeditor.ReplaceAllTextareas = function()
287. {
288. //獲取所有的textarea元素
289. var textareas = document.getElementsByTagName( 'textarea' ) ;
290.
291. for ( var i = 0 ; i < textareas.length ; i++ )
292. {
293. var editor = null ;
294. var textarea = textareas[i] ;
295. var name = textarea.name ;
296. // The "name" attribute must exist.
297. if ( !name || name.length == 0 )
298. continue ;
299. if ( typeof arguments[0] == 'string' )
300. {
301. // The textarea class name could be passed as the function
302. // parameter.
303. var classRegex = new RegExp( '(?:^| )' + arguments[0] + '(?:$| )' ) ;
304. if ( !classRegex.test( textarea.className ) )
305. continue ;
306. }
307. else if ( typeof arguments[0] == 'function' )
308. {
309. // An assertion function could be passed as the function parameter.
310. // It must explicitly return "false" to ignore a specific <textarea>.
311. editor = textareaToEditor( textarea ) ;
312. if ( arguments[0]( textarea, editor ) === false )
313. continue ;
314. }
315. if ( !editor )
316. editor = textareaToEditor( textarea ) ;
317. editor.ReplaceTextarea() ;
318. }
319. }
320. })() ;
321.
322. /**
323. * 檢測瀏覽器的兼容性
324. * 利用了navigator對象返回的一些信息sAgent,判斷瀏覽器 返回包括 瀏覽器的碼名 瀏覽器名 瀏覽器版本 語言 等信息 并小寫
325. * 例如:
326. * mozilla/4.0 (compatible; msie 6.0; windows nt 5.2; sv1; .net clr 1.1.4322)
327. *
328. * 判斷IE瀏覽器的時候,運用了IE4.0之后支持的增加了對條件編譯,
329. * 由于只是IE支持,在W3C標準瀏覽器中,該屬性是不被支持的。因此,適當的利用該特性,判斷IE
330. */
331. function FCKeditor_IsCompatibleBrowser()
332. {
333. var sAgent = navigator.userAgent.toLowerCase() ;
334. // 當前瀏覽器是Internet Explorer 5.5+
335. //利用條件編譯判斷IE 在IE中,/*@cc_on!@*/false == !false == true,
336. //如果是非IE瀏覽器,則忽略,/*@cc_on!@*/false == false
337. if ( /*@cc_on!@*/false && sAgent.indexOf("mac") == -1 ) //不是apple mac os
338. {
339. var sBrowserVersion = navigator.appVersion.match(/MSIE (...)/)[1] ;
340. return ( sBrowserVersion >= 5.5 ) ;
341. }
342. // Gecko (Opera 9 tries to behave like Gecko at this point).
343. //檢測是否是OPERA 9 瀏覽器
344. if ( navigator.product == "Gecko" && navigator.productSub >= 20030210 && !( typeof(opera) == 'object' && opera.postError ) )
345. return true ;
346. // Opera 9.50+
347. if ( window.opera && window.opera.version && parseFloat( window.opera.version() ) >= 9.5 )
348. return true ;
349. // Adobe AIR
350. // Checked before Safari because AIR have the WebKit rich text editor
351. // features from Safari 3.0.4, but the version reported is 420.
352. if ( sAgent.indexOf( ' adobeair/' ) != -1 )
353. return ( sAgent.match( / adobeair/(d+)/ )[1] >= 1 ) ; // Build must be at least v1
354. // Safari 3+
355. if ( sAgent.indexOf( ' applewebkit/' ) != -1 )
356. return ( sAgent.match( / applewebkit/(d+)/ )[1] >= 522 ) ; // Build must be at least 522 (v3)
357. return false ;
358. }

   鑒于筆者水平有限,在此,請廣大高手指出我的注釋中不妥之處,以免誤導他人 。謝謝。建議copy到自己的IDE中查看 或者

  更多權威資料,請參見 FCK 官方Developers Guide

  轉自:http://www.cnblogs.com/nileaderblog/

生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關閉
程序員人生
主站蜘蛛池模板: 国产精彩视频 | v视界成人影院在线视频 | 欧美一区二区三区免费播放 | 欧美色欧美亚洲另类二区 | 亚洲精品推荐 | 免费网站在线视频美女被 | 亚洲欧美日韩国产色另类 | 成年人视频网站免费 | 亚洲男女一区二区三区出奶水了 | 亚洲国产女人aaa毛片在线 | 色综合久久久高清综合久久久 | 久久这里只有精品9 | 欧美日韩中文亚洲v在线综合 | 大片毛片 | 免费伦理片在线观看 | 国产精品福利网站 | 老王影院在线观看 | 国产成人精品一区 | 婷婷激情五月 | 成人α片 | 亚洲精品国产自在久久老牛 | 久久视频精品53在线观看 | 亚洲jizzjizz| 亚洲第九十七页 | 久久精品一区二区影院 | 校园春色亚洲欧美 | 毛片大全网站 | 77777亚洲午夜久久多人 | 久久国产三级 | 亚洲影院在线观看 | 337p日本大胆欧美人术艺术精品 | 精品国产日韩亚洲一区二区 | 羞羞视频免费入口 | 午夜影院啪啪 | 免费一级在线观看 | 欧美妇色 | 亚洲欧美偷拍视频 | 国产偷v国产偷v亚洲高清 | 亚洲男人的天堂久久精品 | 亚洲最大的黄色网址 | 国产三级精品三级在线专区1 |