table.js 63 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516
  1. ///import core
  2. ///commands 表格
  3. ///commandsName InsertTable,DeleteTable,InsertParagraphBeforeTable,InsertRow,DeleteRow,InsertCol,DeleteCol,MergeCells,MergeRight,MergeDown,SplittoCells,SplittoRows,SplittoCols
  4. ///commandsTitle 表格,删除表格,表格前插行,前插入行,删除行,前插入列,删除列,合并多个单元格,右合并单元格,下合并单元格,完全拆分单元格,拆分成行,拆分成列
  5. ///commandsDialog dialogs\table\table.html
  6. /**
  7. * Created by .
  8. * User: taoqili
  9. * Date: 11-5-5
  10. * Time: 下午2:06
  11. * To change this template use File | Settings | File Templates.
  12. */
  13. /**
  14. * table操作插件
  15. */
  16. UE.plugins['table'] = function () {
  17. var me = this,
  18. keys = domUtils.keys,
  19. clearSelectedTd = domUtils.clearSelectedArr;
  20. //框选时用到的几个全局变量
  21. var anchorTd,
  22. tableOpt,
  23. _isEmpty = domUtils.isEmptyNode;
  24. function getIndex( cell ) {
  25. var cells = cell.parentNode.cells;
  26. for ( var i = 0, ci; ci = cells[i]; i++ ) {
  27. if ( ci === cell ) {
  28. return i;
  29. }
  30. }
  31. }
  32. function deleteTable( table, range ) {
  33. var p = table.ownerDocument.createElement( 'p' );
  34. domUtils.fillNode( me.document, p );
  35. var pN = table.parentNode;
  36. if ( pN && pN.getAttribute( 'dropdrag' ) ) {
  37. table = pN;
  38. }
  39. table.parentNode.insertBefore( p, table );
  40. domUtils.remove( table );
  41. range.setStart( p, 0 ).setCursor();
  42. }
  43. /**
  44. * 判断当前单元格是否处于隐藏状态
  45. * @param cell 待判断的单元格
  46. * @return {Boolean} 隐藏时返回true,否则返回false
  47. */
  48. function _isHide( cell ) {
  49. return cell.style.display == "none";
  50. }
  51. function getCount( arr ) {
  52. var count = 0;
  53. for ( var i = 0, ti; ti = arr[i++]; ) {
  54. if ( !_isHide( ti ) ) {
  55. count++
  56. }
  57. }
  58. return count;
  59. }
  60. me.currentSelectedArr = [];
  61. me.addListener( 'mousedown', _mouseDownEvent );
  62. me.addListener( 'keydown', function ( type, evt ) {
  63. var keyCode = evt.keyCode || evt.which;
  64. if ( !keys[keyCode] && !evt.ctrlKey && !evt.metaKey && !evt.shiftKey && !evt.altKey ) {
  65. clearSelectedTd( me.currentSelectedArr )
  66. }
  67. } );
  68. me.addListener( 'mouseup', function () {
  69. anchorTd = null;
  70. me.removeListener( 'mouseover', _mouseDownEvent );
  71. var td = me.currentSelectedArr[0];
  72. if ( td ) {
  73. me.document.body.style.webkitUserSelect = '';
  74. var range = new dom.Range( me.document );
  75. if ( _isEmpty( td ) ) {
  76. range.setStart( me.currentSelectedArr[0], 0 ).setCursor();
  77. } else {
  78. range.selectNodeContents( me.currentSelectedArr[0] ).select();
  79. }
  80. } else {
  81. //浏览器能从table外边选到里边导致currentSelectedArr为空,清掉当前选区回到选区的最开始
  82. var range = me.selection.getRange().shrinkBoundary();
  83. if ( !range.collapsed ) {
  84. var start = domUtils.findParentByTagName( range.startContainer, 'td', true ),
  85. end = domUtils.findParentByTagName( range.endContainer, 'td', true );
  86. //在table里边的不能清除
  87. if ( start && !end || !start && end || start && end && start !== end ) {
  88. range.collapse( true ).select( true )
  89. }
  90. }
  91. }
  92. } );
  93. function reset() {
  94. me.currentSelectedArr = [];
  95. anchorTd = null;
  96. }
  97. /**
  98. * 插入表格
  99. * @param numRows 行数
  100. * @param numCols 列数
  101. * @param height 列数
  102. * @param width 列数
  103. * @param heightUnit 列数
  104. * @param widthUnit 列数
  105. * @param bgColor 表格背景
  106. * @param border 边框大小
  107. * @param borderColor 边框颜色
  108. * @param cellSpacing 单元格间距
  109. * @param cellPadding 单元格边距
  110. */
  111. me.commands['inserttable'] = {
  112. queryCommandState:function () {
  113. if ( this.highlight ) {
  114. return -1;
  115. }
  116. var range = this.selection.getRange();
  117. return domUtils.findParentByTagName( range.startContainer, 'table', true )
  118. || domUtils.findParentByTagName( range.endContainer, 'table', true )
  119. || me.currentSelectedArr.length > 0 ? -1 : 0;
  120. },
  121. execCommand:function ( cmdName, opt ) {
  122. opt = opt || {numRows:5, numCols:5,border:1};
  123. var html = ['<table ' + (opt.border == "0" ? ' class="noBorderTable"' : '') + ' _innerCreateTable = "true" '];
  124. if ( opt.cellSpacing && opt.cellSpacing != '0' || opt.cellPadding && opt.cellPadding != '0' ) {
  125. html.push( ' style="border-collapse:separate;" ' )
  126. }
  127. opt.cellSpacing && opt.cellSpacing != '0' && html.push( ' cellSpacing="' + opt.cellSpacing + '" ' );
  128. opt.cellPadding && opt.cellPadding != '0' && html.push( ' cellPadding="' + opt.cellPadding + '" ' );
  129. html.push( ' width="' + (opt.width || 100) + (typeof opt.widthUnit == "undefined" ? '%' : opt.widthUnit) + '" ' );
  130. opt.height && html.push( ' height="' + opt.height + (typeof opt.heightUnit == "undefined" ? '%' : opt.heightUnit) + '" ' );
  131. opt.align && (html.push( ' align="' + opt.align + '" ' ));
  132. html.push( ' border="' + (opt.border || 0) + '" borderColor="' + (opt.borderColor || '#000000') + '"' );
  133. opt.borderType == "1" && html.push( ' borderType="1" ' );
  134. opt.bgColor && html.push( ' bgColor="' + opt.bgColor + '"' );
  135. html.push( ' ><tbody>' );
  136. opt.width = Math.floor( (opt.width || '100') / opt.numCols );
  137. for ( var i = 0; i < opt.numRows; i++ ) {
  138. html.push( '<tr>' )
  139. for ( var j = 0; j < opt.numCols; j++ ) {
  140. html.push( '<td style="width:' + opt.width + (typeof opt.widthUnit == "undefined" ? '%' : opt.widthUnit) + ';'
  141. + (opt.borderType == '1' ? 'border:' + opt.border + 'px solid ' + (opt.borderColor || '#000000') : '')
  142. + '">'
  143. + (browser.ie ? domUtils.fillChar : '<br/>') + '</td>' )
  144. }
  145. html.push( '</tr>' )
  146. }
  147. me.execCommand( 'insertHtml', html.join( '' ) + '</tbody></table>' );
  148. reset();
  149. //如果表格的align不是默认,将不占位,给后边的block元素设置clear:both
  150. if ( opt.align ) {
  151. var range = me.selection.getRange(),
  152. bk = range.createBookmark(),
  153. start = range.startContainer;
  154. while ( start && !domUtils.isBody( start ) ) {
  155. if ( domUtils.isBlockElm( start ) ) {
  156. start.style.clear = 'both';
  157. range.moveToBookmark( bk ).select();
  158. break;
  159. }
  160. start = start.parentNode;
  161. }
  162. }
  163. }
  164. };
  165. me.commands['edittable'] = {
  166. queryCommandState:function () {
  167. var range = this.selection.getRange();
  168. if ( this.highlight ) {
  169. return -1;
  170. }
  171. return domUtils.findParentByTagName( range.startContainer, 'table', true )
  172. || me.currentSelectedArr.length > 0 ? 0 : -1;
  173. },
  174. execCommand:function ( cmdName, opt ) {
  175. var start = me.selection.getStart(),
  176. table = domUtils.findParentByTagName( start, 'table', true );
  177. if ( table ) {
  178. table.style.cssText = table.style.cssText.replace( /border[^;]+/gi, '' );
  179. table.style.borderCollapse = opt.cellSpacing && opt.cellSpacing != '0' || opt.cellPadding && opt.cellPadding != '0' ? 'separate' : 'collapse';
  180. opt.cellSpacing && opt.cellSpacing != '0' ? table.setAttribute( 'cellSpacing', opt.cellSpacing ) : table.removeAttribute( 'cellSpacing' );
  181. opt.cellPadding && opt.cellPadding != '0' ? table.setAttribute( 'cellPadding', opt.cellPadding ) : table.removeAttribute( 'cellPadding' );
  182. opt.height && table.setAttribute( 'height', opt.height + opt.heightUnit );
  183. opt.align && table.setAttribute( 'align', opt.align );
  184. opt.width && table.setAttribute( 'width', opt.width + opt.widthUnit );
  185. opt.bgColor && table.setAttribute( 'bgColor', opt.bgColor );
  186. opt.borderColor && table.setAttribute( 'borderColor', opt.borderColor );
  187. table.setAttribute( 'border', opt.border );
  188. table.className = opt.border == "0" ? "noBorderTable" : "";
  189. if ( opt.borderType == "1" ) {
  190. for ( var i = 0, ti, tds = table.getElementsByTagName( 'td' ); ti = tds[i++]; ) {
  191. ti.style.border = opt.border + 'px solid ' + (opt.borderColor || '#000000')
  192. }
  193. table.setAttribute( 'borderType', '1' )
  194. } else {
  195. for ( var i = 0, ti, tds = table.getElementsByTagName( 'td' ); ti = tds[i++]; ) {
  196. if ( browser.ie ) {
  197. ti.style.cssText = ti.style.cssText.replace( /border[^;]+/gi, '' );
  198. } else {
  199. domUtils.removeStyle( ti, 'border' );
  200. domUtils.removeStyle( ti, 'border-image' )
  201. }
  202. }
  203. table.removeAttribute( 'borderType' )
  204. }
  205. }
  206. }
  207. };
  208. me.commands['edittd'] = {
  209. queryCommandState:function () {
  210. if ( this.highlight ) {
  211. return -1;
  212. }
  213. var range = this.selection.getRange();
  214. return (domUtils.findParentByTagName( range.startContainer, 'table', true )
  215. && domUtils.findParentByTagName( range.endContainer, 'table', true )) || me.currentSelectedArr.length > 0 ? 0 : -1;
  216. },
  217. /**
  218. * 单元格属性编辑
  219. * @param cmdName
  220. * @param tdItems
  221. */
  222. execCommand:function ( cmdName, tdItems ) {
  223. var range = this.selection.getRange(),
  224. tds = !me.currentSelectedArr.length ? [domUtils.findParentByTagName( range.startContainer, ['td', 'th'], true )] : me.currentSelectedArr;
  225. for ( var i = 0, td; td = tds[i++]; ) {
  226. domUtils.setAttributes( td, {
  227. "bgColor":tdItems.bgColor,
  228. "align":tdItems.align,
  229. "vAlign":tdItems.vAlign
  230. } );
  231. }
  232. }
  233. };
  234. /**
  235. * 删除表格
  236. */
  237. me.commands['deletetable'] = {
  238. queryCommandState:function () {
  239. if ( this.highlight ) {
  240. return -1;
  241. }
  242. var range = this.selection.getRange();
  243. return (domUtils.findParentByTagName( range.startContainer, 'table', true )
  244. && domUtils.findParentByTagName( range.endContainer, 'table', true )) || me.currentSelectedArr.length > 0 ? 0 : -1;
  245. },
  246. execCommand:function () {
  247. var range = this.selection.getRange(),
  248. table = domUtils.findParentByTagName( me.currentSelectedArr.length > 0 ? me.currentSelectedArr[0] : range.startContainer, 'table', true );
  249. deleteTable( table, range );
  250. reset();
  251. }
  252. };
  253. /**
  254. * 添加表格标题
  255. */
  256. me.commands['addcaption'] = {
  257. queryCommandState:function () {
  258. if ( this.highlight ) {
  259. return -1;
  260. }
  261. var range = this.selection.getRange();
  262. return (domUtils.findParentByTagName( range.startContainer, 'table', true )
  263. && domUtils.findParentByTagName( range.endContainer, 'table', true )) || me.currentSelectedArr.length > 0 ? 0 : -1;
  264. },
  265. execCommand:function ( cmdName, opt ) {
  266. var range = this.selection.getRange(),
  267. table = domUtils.findParentByTagName( me.currentSelectedArr.length > 0 ? me.currentSelectedArr[0] : range.startContainer, 'table', true );
  268. if ( opt == "on" ) {
  269. var c = table.createCaption();
  270. c.innerHTML = "请在此输入表格标题";
  271. } else {
  272. table.removeChild( table.caption );
  273. }
  274. }
  275. };
  276. /**
  277. * 向右合并单元格
  278. */
  279. me.commands['mergeright'] = {
  280. queryCommandState:function () {
  281. if ( this.highlight ) {
  282. return -1;
  283. }
  284. var range = this.selection.getRange(),
  285. start = range.startContainer,
  286. td = domUtils.findParentByTagName( start, ['td', 'th'], true );
  287. if ( !td || this.currentSelectedArr.length > 1 )return -1;
  288. var tr = td.parentNode;
  289. //最右边行不能向右合并
  290. var rightCellIndex = getIndex( td ) + td.colSpan;
  291. if ( rightCellIndex >= tr.cells.length ) {
  292. return -1;
  293. }
  294. //单元格不在同一行不能向右合并
  295. var rightCell = tr.cells[rightCellIndex];
  296. if ( _isHide( rightCell ) ) {
  297. return -1;
  298. }
  299. return td.rowSpan == rightCell.rowSpan ? 0 : -1;
  300. },
  301. execCommand:function () {
  302. var range = this.selection.getRange(),
  303. start = range.startContainer,
  304. td = domUtils.findParentByTagName( start, ['td', 'th'], true ) || me.currentSelectedArr[0],
  305. tr = td.parentNode,
  306. rows = tr.parentNode.parentNode.rows;
  307. //找到当前单元格右边的未隐藏单元格
  308. var rightCellRowIndex = tr.rowIndex,
  309. rightCellCellIndex = getIndex( td ) + td.colSpan,
  310. rightCell = rows[rightCellRowIndex].cells[rightCellCellIndex];
  311. //在隐藏的原生td对象上增加两个属性,分别表示当前td对应的真实td坐标
  312. for ( var i = rightCellRowIndex; i < rightCellRowIndex + rightCell.rowSpan; i++ ) {
  313. for ( var j = rightCellCellIndex; j < rightCellCellIndex + rightCell.colSpan; j++ ) {
  314. var tmpCell = rows[i].cells[j];
  315. tmpCell.setAttribute( 'rootRowIndex', tr.rowIndex );
  316. tmpCell.setAttribute( 'rootCellIndex', getIndex( td ) );
  317. }
  318. }
  319. //合并单元格
  320. td.colSpan += rightCell.colSpan || 1;
  321. //合并内容
  322. _moveContent( td, rightCell );
  323. //删除被合并的单元格,此处用隐藏方式实现来提升性能
  324. rightCell.style.display = "none";
  325. //重新让单元格获取焦点
  326. //trace:1565
  327. if ( domUtils.isEmptyBlock( td ) ) {
  328. range.setStart( td, 0 ).setCursor();
  329. } else {
  330. range.selectNodeContents( td ).setCursor( true, true );
  331. }
  332. //处理有寛高,导致ie的文字不能输入占满
  333. browser.ie && domUtils.removeAttributes( td, ['width', 'height'] );
  334. }
  335. };
  336. /**
  337. * 向下合并单元格
  338. */
  339. me.commands['mergedown'] = {
  340. queryCommandState:function () {
  341. if ( this.highlight ) {
  342. return -1;
  343. }
  344. var range = this.selection.getRange(),
  345. start = range.startContainer,
  346. td = domUtils.findParentByTagName( start, 'td', true );
  347. if ( !td || getCount( me.currentSelectedArr ) > 1 )return -1;
  348. var tr = td.parentNode,
  349. table = tr.parentNode.parentNode,
  350. rows = table.rows;
  351. //已经是最底行,不能向下合并
  352. var downCellRowIndex = tr.rowIndex + td.rowSpan;
  353. if ( downCellRowIndex >= rows.length ) {
  354. return -1;
  355. }
  356. //如果下一个单元格是隐藏的,表明他是由左边span过来的,不能向下合并
  357. var downCell = rows[downCellRowIndex].cells[getIndex( td )];
  358. if ( _isHide( downCell ) ) {
  359. return -1;
  360. }
  361. //只有列span都相等时才能合并
  362. return td.colSpan == downCell.colSpan ? 0 : -1;
  363. },
  364. execCommand:function () {
  365. var range = this.selection.getRange(),
  366. start = range.startContainer,
  367. td = domUtils.findParentByTagName( start, ['td', 'th'], true ) || me.currentSelectedArr[0];
  368. var tr = td.parentNode,
  369. rows = tr.parentNode.parentNode.rows;
  370. var downCellRowIndex = tr.rowIndex + td.rowSpan,
  371. downCellCellIndex = getIndex( td ),
  372. downCell = rows[downCellRowIndex].cells[downCellCellIndex];
  373. //找到当前列的下一个未被隐藏的单元格
  374. for ( var i = downCellRowIndex; i < downCellRowIndex + downCell.rowSpan; i++ ) {
  375. for ( var j = downCellCellIndex; j < downCellCellIndex + downCell.colSpan; j++ ) {
  376. var tmpCell = rows[i].cells[j];
  377. tmpCell.setAttribute( 'rootRowIndex', tr.rowIndex );
  378. tmpCell.setAttribute( 'rootCellIndex', getIndex( td ) );
  379. }
  380. }
  381. //合并单元格
  382. td.rowSpan += downCell.rowSpan || 1;
  383. //合并内容
  384. _moveContent( td, downCell );
  385. //删除被合并的单元格,此处用隐藏方式实现来提升性能
  386. downCell.style.display = "none";
  387. //重新让单元格获取焦点
  388. if ( domUtils.isEmptyBlock( td ) ) {
  389. range.setStart( td, 0 ).setCursor();
  390. } else {
  391. range.selectNodeContents( td ).setCursor( true, true );
  392. }
  393. //处理有寛高,导致ie的文字不能输入占满
  394. browser.ie && domUtils.removeAttributes( td, ['width', 'height'] );
  395. }
  396. };
  397. /**
  398. * 删除行
  399. */
  400. me.commands['deleterow'] = {
  401. queryCommandState:function () {
  402. if ( this.highlight ) {
  403. return -1;
  404. }
  405. var range = this.selection.getRange(),
  406. start = range.startContainer,
  407. td = domUtils.findParentByTagName( start, ['td', 'th'], true );
  408. if ( !td && me.currentSelectedArr.length == 0 )return -1;
  409. },
  410. execCommand:function () {
  411. var range = this.selection.getRange(),
  412. start = range.startContainer,
  413. td = domUtils.findParentByTagName( start, ['td', 'th'], true ),
  414. tr,
  415. table,
  416. cells,
  417. rows ,
  418. rowIndex ,
  419. cellIndex;
  420. if ( td && me.currentSelectedArr.length == 0 ) {
  421. var count = (td.rowSpan || 1) - 1;
  422. me.currentSelectedArr.push( td );
  423. tr = td.parentNode,
  424. table = tr.parentNode.parentNode;
  425. rows = table.rows,
  426. rowIndex = tr.rowIndex + 1,
  427. cellIndex = getIndex( td );
  428. while ( count ) {
  429. me.currentSelectedArr.push( rows[rowIndex].cells[cellIndex] );
  430. count--;
  431. rowIndex++
  432. }
  433. }
  434. while ( td = me.currentSelectedArr.pop() ) {
  435. if ( !domUtils.findParentByTagName( td, 'table' ) ) {//|| _isHide(td)
  436. continue;
  437. }
  438. tr = td.parentNode,
  439. table = tr.parentNode.parentNode;
  440. cells = tr.cells,
  441. rows = table.rows,
  442. rowIndex = tr.rowIndex,
  443. cellIndex = getIndex( td );
  444. /*
  445. * 从最左边开始扫描并隐藏当前行的所有单元格
  446. * 若当前单元格的display为none,往上找到它所在的真正单元格,获取colSpan和rowSpan,
  447. * 将rowspan减一,并跳转到cellIndex+colSpan列继续处理
  448. * 若当前单元格的display不为none,分两种情况:
  449. * 1、rowspan == 1 ,直接设置display为none,跳转到cellIndex+colSpan列继续处理
  450. * 2、rowspan > 1 , 修改当前单元格的下一个单元格的display为"",
  451. * 并将当前单元格的rowspan-1赋给下一个单元格的rowspan,当前单元格的colspan赋给下一个单元格的colspan,
  452. * 然后隐藏当前单元格,跳转到cellIndex+colSpan列继续处理
  453. */
  454. for ( var currentCellIndex = 0; currentCellIndex < cells.length; ) {
  455. var currentNode = cells[currentCellIndex];
  456. if ( _isHide( currentNode ) ) {
  457. var topNode = rows[currentNode.getAttribute( 'rootRowIndex' )].cells[currentNode.getAttribute( 'rootCellIndex' )];
  458. topNode.rowSpan--;
  459. currentCellIndex += topNode.colSpan;
  460. } else {
  461. if ( currentNode.rowSpan == 1 ) {
  462. currentCellIndex += currentNode.colSpan;
  463. } else {
  464. var downNode = rows[rowIndex + 1].cells[currentCellIndex];
  465. downNode.style.display = "";
  466. downNode.rowSpan = currentNode.rowSpan - 1;
  467. downNode.colSpan = currentNode.colSpan;
  468. currentCellIndex += currentNode.colSpan;
  469. }
  470. }
  471. }
  472. //完成更新后再删除外层包裹的tr
  473. domUtils.remove( tr );
  474. //重新定位焦点
  475. var topRowTd, focusTd, downRowTd;
  476. if ( rowIndex == rows.length ) { //如果被删除的行是最后一行,这里之所以没有-1是因为已经删除了一行
  477. //如果删除的行也是第一行,那么表格总共只有一行,删除整个表格
  478. if ( rowIndex == 0 ) {
  479. deleteTable( table, range );
  480. return;
  481. }
  482. //如果上一单元格未隐藏,则直接定位,否则定位到最近的上一个非隐藏单元格
  483. var preRowIndex = rowIndex - 1;
  484. topRowTd = rows[preRowIndex].cells[ cellIndex];
  485. focusTd = _isHide( topRowTd ) ? rows[topRowTd.getAttribute( 'rootRowIndex' )].cells[topRowTd.getAttribute( 'rootCellIndex' )] : topRowTd;
  486. } else { //如果被删除的不是最后一行,则光标定位到下一行,此处未加1是因为已经删除了一行
  487. downRowTd = rows[rowIndex].cells[cellIndex];
  488. focusTd = _isHide( downRowTd ) ? rows[downRowTd.getAttribute( 'rootRowIndex' )].cells[downRowTd.getAttribute( 'rootCellIndex' )] : downRowTd;
  489. }
  490. }
  491. range.setStart( focusTd, 0 ).setCursor();
  492. update( table )
  493. }
  494. };
  495. /**
  496. * 删除列
  497. */
  498. me.commands['deletecol'] = {
  499. queryCommandState:function () {
  500. if ( this.highlight ) {
  501. return -1;
  502. }
  503. var range = this.selection.getRange(),
  504. start = range.startContainer,
  505. td = domUtils.findParentByTagName( start, ['td', 'th'], true );
  506. if ( !td && me.currentSelectedArr.length == 0 )return -1;
  507. },
  508. execCommand:function () {
  509. var range = this.selection.getRange(),
  510. start = range.startContainer,
  511. td = domUtils.findParentByTagName( start, ['td', 'th'], true );
  512. if ( td && me.currentSelectedArr.length == 0 ) {
  513. var count = (td.colSpan || 1) - 1;
  514. me.currentSelectedArr.push( td );
  515. while ( count ) {
  516. do {
  517. td = td.nextSibling
  518. } while ( td.nodeType == 3 );
  519. me.currentSelectedArr.push( td );
  520. count--;
  521. }
  522. }
  523. while ( td = me.currentSelectedArr.pop() ) {
  524. if ( !domUtils.findParentByTagName( td, 'table' ) ) { //|| _isHide(td)
  525. continue;
  526. }
  527. var tr = td.parentNode,
  528. table = tr.parentNode.parentNode,
  529. cellIndex = getIndex( td ),
  530. rows = table.rows,
  531. cells = tr.cells,
  532. rowIndex = tr.rowIndex;
  533. /*
  534. * 从第一行开始扫描并隐藏当前列的所有单元格
  535. * 若当前单元格的display为none,表明它是由左边Span过来的,
  536. * 将左边第一个非none单元格的colSpan减去1并删去对应的单元格后跳转到rowIndex + rowspan行继续处理;
  537. * 若当前单元格的display不为none,分两种情况,
  538. * 1、当前单元格的colspan == 1 , 则直接删除该节点,跳转到rowIndex + rowspan行继续处理
  539. * 2、当前单元格的colsapn > 1, 修改当前单元格右边单元格的display为"",
  540. * 并将当前单元格的colspan-1赋给它的colspan,当前单元格的rolspan赋给它的rolspan,
  541. * 然后删除当前单元格,跳转到rowIndex+rowSpan行继续处理
  542. */
  543. var rowSpan;
  544. for ( var currentRowIndex = 0; currentRowIndex < rows.length; ) {
  545. var currentNode = rows[currentRowIndex].cells[cellIndex];
  546. if ( _isHide( currentNode ) ) {
  547. var leftNode = rows[currentNode.getAttribute( 'rootRowIndex' )].cells[currentNode.getAttribute( 'rootCellIndex' )];
  548. //依次删除对应的单元格
  549. rowSpan = leftNode.rowSpan;
  550. for ( var i = 0; i < leftNode.rowSpan; i++ ) {
  551. var delNode = rows[currentRowIndex + i].cells[cellIndex];
  552. domUtils.remove( delNode );
  553. }
  554. //修正被删后的单元格信息
  555. leftNode.colSpan--;
  556. currentRowIndex += rowSpan;
  557. } else {
  558. if ( currentNode.colSpan == 1 ) {
  559. rowSpan = currentNode.rowSpan;
  560. for ( var i = currentRowIndex, l = currentRowIndex + currentNode.rowSpan; i < l; i++ ) {
  561. domUtils.remove( rows[i].cells[cellIndex] );
  562. }
  563. currentRowIndex += rowSpan;
  564. } else {
  565. var rightNode = rows[currentRowIndex].cells[cellIndex + 1];
  566. rightNode.style.display = "";
  567. rightNode.rowSpan = currentNode.rowSpan;
  568. rightNode.colSpan = currentNode.colSpan - 1;
  569. currentRowIndex += currentNode.rowSpan;
  570. domUtils.remove( currentNode );
  571. }
  572. }
  573. }
  574. //重新定位焦点
  575. var preColTd, focusTd, nextColTd;
  576. if ( cellIndex == cells.length ) { //如果当前列是最后一列,光标定位到当前列的前一列,同样,这里没有减去1是因为已经被删除了一列
  577. //如果当前列也是第一列,则删除整个表格
  578. if ( cellIndex == 0 ) {
  579. deleteTable( table, range );
  580. return;
  581. }
  582. //找到当前单元格前一列中和本单元格最近的一个未隐藏单元格
  583. var preCellIndex = cellIndex - 1;
  584. preColTd = rows[rowIndex].cells[preCellIndex];
  585. focusTd = _isHide( preColTd ) ? rows[preColTd.getAttribute( 'rootRowIndex' )].cells[preColTd.getAttribute( 'rootCellIndex' )] : preColTd;
  586. } else { //如果当前列不是最后一列,则光标定位到当前列的后一列
  587. nextColTd = rows[rowIndex].cells[cellIndex];
  588. focusTd = _isHide( nextColTd ) ? rows[nextColTd.getAttribute( 'rootRowIndex' )].cells[nextColTd.getAttribute( 'rootCellIndex' )] : nextColTd;
  589. }
  590. }
  591. range.setStart( focusTd, 0 ).setCursor();
  592. update( table )
  593. }
  594. };
  595. /**
  596. * 完全拆分单元格
  597. */
  598. me.commands['splittocells'] = {
  599. queryCommandState:function () {
  600. if ( this.highlight ) {
  601. return -1;
  602. }
  603. var range = this.selection.getRange(),
  604. start = range.startContainer,
  605. td = domUtils.findParentByTagName( start, ['td', 'th'], true );
  606. return td && ( td.rowSpan > 1 || td.colSpan > 1 ) && (!me.currentSelectedArr.length || getCount( me.currentSelectedArr ) == 1) ? 0 : -1;
  607. },
  608. execCommand:function () {
  609. var range = this.selection.getRange(),
  610. start = range.startContainer,
  611. td = domUtils.findParentByTagName( start, ['td', 'th'], true ),
  612. tr = td.parentNode,
  613. table = tr.parentNode.parentNode;
  614. var rowIndex = tr.rowIndex,
  615. cellIndex = getIndex( td ),
  616. rowSpan = td.rowSpan,
  617. colSpan = td.colSpan;
  618. for ( var i = 0; i < rowSpan; i++ ) {
  619. for ( var j = 0; j < colSpan; j++ ) {
  620. var cell = table.rows[rowIndex + i].cells[cellIndex + j];
  621. cell.rowSpan = 1;
  622. cell.colSpan = 1;
  623. if ( _isHide( cell ) ) {
  624. cell.style.display = "";
  625. cell.innerHTML = browser.ie ? '' : "<br/>";
  626. }
  627. }
  628. }
  629. }
  630. };
  631. /**
  632. * 将单元格拆分成行
  633. */
  634. me.commands['splittorows'] = {
  635. queryCommandState:function () {
  636. if ( this.highlight ) {
  637. return -1;
  638. }
  639. var range = this.selection.getRange(),
  640. start = range.startContainer,
  641. td = domUtils.findParentByTagName( start, 'td', true ) || me.currentSelectedArr[0];
  642. return td && ( td.rowSpan > 1) && (!me.currentSelectedArr.length || getCount( me.currentSelectedArr ) == 1) ? 0 : -1;
  643. },
  644. execCommand:function () {
  645. var range = this.selection.getRange(),
  646. start = range.startContainer,
  647. td = domUtils.findParentByTagName( start, 'td', true ) || me.currentSelectedArr[0],
  648. tr = td.parentNode,
  649. rows = tr.parentNode.parentNode.rows;
  650. var rowIndex = tr.rowIndex,
  651. cellIndex = getIndex( td ),
  652. rowSpan = td.rowSpan,
  653. colSpan = td.colSpan;
  654. for ( var i = 0; i < rowSpan; i++ ) {
  655. var cells = rows[rowIndex + i],
  656. cell = cells.cells[cellIndex];
  657. cell.rowSpan = 1;
  658. cell.colSpan = colSpan;
  659. if ( _isHide( cell ) ) {
  660. cell.style.display = "";
  661. //原有的内容要清除掉
  662. cell.innerHTML = browser.ie ? '' : '<br/>'
  663. }
  664. //修正被隐藏单元格中存储的rootRowIndex和rootCellIndex信息
  665. for ( var j = cellIndex + 1; j < cellIndex + colSpan; j++ ) {
  666. cell = cells.cells[j];
  667. cell.setAttribute( 'rootRowIndex', rowIndex + i )
  668. }
  669. }
  670. clearSelectedTd( me.currentSelectedArr );
  671. this.selection.getRange().setStart( td, 0 ).setCursor();
  672. }
  673. };
  674. /**
  675. * 在表格前插入行
  676. */
  677. me.commands['insertparagraphbeforetable'] = {
  678. queryCommandState:function () {
  679. if ( this.highlight ) {
  680. return -1;
  681. }
  682. var range = this.selection.getRange(),
  683. start = range.startContainer,
  684. td = domUtils.findParentByTagName( start, 'td', true ) || me.currentSelectedArr[0];
  685. return td && domUtils.findParentByTagName( td, 'table' ) ? 0 : -1;
  686. },
  687. execCommand:function () {
  688. var range = this.selection.getRange(),
  689. start = range.startContainer,
  690. table = domUtils.findParentByTagName( start, 'table', true );
  691. start = me.document.createElement( me.options.enterTag );
  692. table.parentNode.insertBefore( start, table );
  693. clearSelectedTd( me.currentSelectedArr );
  694. if ( start.tagName == 'P' ) {
  695. //trace:868
  696. start.innerHTML = browser.ie ? '' : '<br/>';
  697. range.setStart( start, 0 )
  698. } else {
  699. range.setStartBefore( start )
  700. }
  701. range.setCursor();
  702. }
  703. };
  704. /**
  705. * 将单元格拆分成列
  706. */
  707. me.commands['splittocols'] = {
  708. queryCommandState:function () {
  709. if ( this.highlight ) {
  710. return -1;
  711. }
  712. var range = this.selection.getRange(),
  713. start = range.startContainer,
  714. td = domUtils.findParentByTagName( start, ['td', 'th'], true ) || me.currentSelectedArr[0];
  715. return td && ( td.colSpan > 1) && (!me.currentSelectedArr.length || getCount( me.currentSelectedArr ) == 1) ? 0 : -1;
  716. },
  717. execCommand:function () {
  718. var range = this.selection.getRange(),
  719. start = range.startContainer,
  720. td = domUtils.findParentByTagName( start, ['td', 'th'], true ) || me.currentSelectedArr[0],
  721. tr = td.parentNode,
  722. rows = tr.parentNode.parentNode.rows;
  723. var rowIndex = tr.rowIndex,
  724. cellIndex = getIndex( td ),
  725. rowSpan = td.rowSpan,
  726. colSpan = td.colSpan;
  727. for ( var i = 0; i < colSpan; i++ ) {
  728. var cell = rows[rowIndex].cells[cellIndex + i];
  729. cell.rowSpan = rowSpan;
  730. cell.colSpan = 1;
  731. if ( _isHide( cell ) ) {
  732. cell.style.display = "";
  733. cell.innerHTML = browser.ie ? '' : '<br/>'
  734. }
  735. for ( var j = rowIndex + 1; j < rowIndex + rowSpan; j++ ) {
  736. var tmpCell = rows[j].cells[cellIndex + i];
  737. tmpCell.setAttribute( 'rootCellIndex', cellIndex + i );
  738. }
  739. }
  740. clearSelectedTd( me.currentSelectedArr );
  741. this.selection.getRange().setStart( td, 0 ).setCursor();
  742. }
  743. };
  744. /**
  745. * 插入行
  746. */
  747. me.commands['insertrow'] = {
  748. queryCommandState:function () {
  749. if ( this.highlight ) {
  750. return -1;
  751. }
  752. var range = this.selection.getRange();
  753. return domUtils.findParentByTagName( range.startContainer, 'table', true )
  754. || domUtils.findParentByTagName( range.endContainer, 'table', true ) || me.currentSelectedArr.length != 0 ? 0 : -1;
  755. },
  756. execCommand:function () {
  757. var range = this.selection.getRange(),
  758. start = range.startContainer,
  759. tr = domUtils.findParentByTagName( start, 'tr', true ) || me.currentSelectedArr[0].parentNode,
  760. table = tr.parentNode.parentNode,
  761. rows = table.rows;
  762. //记录插入位置原来所有的单元格
  763. var rowIndex = tr.rowIndex,
  764. cells = rows[rowIndex].cells;
  765. //插入新的一行
  766. var newRow = table.insertRow( rowIndex );
  767. var newCell;
  768. //遍历表格中待插入位置中的所有单元格,检查其状态,并据此修正新插入行的单元格状态
  769. for ( var cellIndex = 0; cellIndex < cells.length; ) {
  770. var tmpCell = cells[cellIndex];
  771. if ( _isHide( tmpCell ) ) { //如果当前单元格是隐藏的,表明当前单元格由其上部span过来,找到其上部单元格
  772. //找到被隐藏单元格真正所属的单元格
  773. var topCell = rows[tmpCell.getAttribute( 'rootRowIndex' )].cells[tmpCell.getAttribute( 'rootCellIndex' )];
  774. //增加一行,并将所有新插入的单元格隐藏起来
  775. topCell.rowSpan++;
  776. for ( var i = 0; i < topCell.colSpan; i++ ) {
  777. newCell = tmpCell.cloneNode( false );
  778. domUtils.removeAttributes( newCell, ["bgColor", "valign", "align"] );
  779. newCell.rowSpan = newCell.colSpan = 1;
  780. newCell.innerHTML = browser.ie ? '' : "<br/>";
  781. newCell.className = '';
  782. if ( newRow.children[cellIndex + i] ) {
  783. newRow.insertBefore( newCell, newRow.children[cellIndex + i] );
  784. } else {
  785. newRow.appendChild( newCell )
  786. }
  787. newCell.style.display = "none";
  788. }
  789. cellIndex += topCell.colSpan;
  790. } else {//若当前单元格未隐藏,则在其上行插入colspan个单元格
  791. for ( var j = 0; j < tmpCell.colSpan; j++ ) {
  792. newCell = tmpCell.cloneNode( false );
  793. domUtils.removeAttributes( newCell, ["bgColor", "valign", "align"] );
  794. newCell.rowSpan = newCell.colSpan = 1;
  795. newCell.innerHTML = browser.ie ? '' : "<br/>";
  796. newCell.className = '';
  797. if ( newRow.children[cellIndex + j] ) {
  798. newRow.insertBefore( newCell, newRow.children[cellIndex + j] );
  799. } else {
  800. newRow.appendChild( newCell )
  801. }
  802. }
  803. cellIndex += tmpCell.colSpan;
  804. }
  805. }
  806. update( table );
  807. range.setStart( newRow.cells[0], 0 ).setCursor();
  808. clearSelectedTd( me.currentSelectedArr );
  809. }
  810. };
  811. /**
  812. * 插入列
  813. */
  814. me.commands['insertcol'] = {
  815. queryCommandState:function () {
  816. if ( this.highlight ) {
  817. return -1;
  818. }
  819. var range = this.selection.getRange();
  820. return domUtils.findParentByTagName( range.startContainer, 'table', true )
  821. || domUtils.findParentByTagName( range.endContainer, 'table', true ) || me.currentSelectedArr.length != 0 ? 0 : -1;
  822. },
  823. execCommand:function () {
  824. var range = this.selection.getRange(),
  825. start = range.startContainer,
  826. td = domUtils.findParentByTagName( start, ['td', 'th'], true ) || me.currentSelectedArr[0],
  827. table = domUtils.findParentByTagName( td, 'table' ),
  828. rows = table.rows;
  829. var cellIndex = getIndex( td ),
  830. newCell;
  831. //遍历当前列中的所有单元格,检查其状态,并据此修正新插入列的单元格状态
  832. for ( var rowIndex = 0; rowIndex < rows.length; ) {
  833. var tmpCell = rows[rowIndex].cells[cellIndex], tr;
  834. if ( _isHide( tmpCell ) ) {//如果当前单元格是隐藏的,表明当前单元格由其左边span过来,找到其左边单元格
  835. var leftCell = rows[tmpCell.getAttribute( 'rootRowIndex' )].cells[tmpCell.getAttribute( 'rootCellIndex' )];
  836. leftCell.colSpan++;
  837. for ( var i = 0; i < leftCell.rowSpan; i++ ) {
  838. newCell = td.cloneNode( false );
  839. domUtils.removeAttributes( newCell, ["bgColor", "valign", "align"] );
  840. newCell.rowSpan = newCell.colSpan = 1;
  841. newCell.innerHTML = browser.ie ? '' : "<br/>";
  842. newCell.className = '';
  843. tr = rows[rowIndex + i];
  844. if ( tr.children[cellIndex] ) {
  845. tr.insertBefore( newCell, tr.children[cellIndex] );
  846. } else {
  847. tr.appendChild( newCell )
  848. }
  849. newCell.style.display = "none";
  850. }
  851. rowIndex += leftCell.rowSpan;
  852. } else { //若当前单元格未隐藏,则在其左边插入rowspan个单元格
  853. for ( var j = 0; j < tmpCell.rowSpan; j++ ) {
  854. newCell = td.cloneNode( false );
  855. domUtils.removeAttributes( newCell, ["bgColor", "valign", "align"] );
  856. newCell.rowSpan = newCell.colSpan = 1;
  857. newCell.innerHTML = browser.ie ? '' : "<br/>";
  858. newCell.className = '';
  859. tr = rows[rowIndex + j];
  860. if ( tr.children[cellIndex] ) {
  861. tr.insertBefore( newCell, tr.children[cellIndex] );
  862. } else {
  863. tr.appendChild( newCell )
  864. }
  865. newCell.innerHTML = browser.ie ? '' : "<br/>";
  866. }
  867. rowIndex += tmpCell.rowSpan;
  868. }
  869. }
  870. update( table );
  871. range.setStart( rows[0].cells[cellIndex], 0 ).setCursor();
  872. clearSelectedTd( me.currentSelectedArr );
  873. }
  874. };
  875. /**
  876. * 合并多个单元格,通过两个cell将当前包含的所有横纵单元格进行合并
  877. */
  878. me.commands['mergecells'] = {
  879. queryCommandState:function () {
  880. if ( this.highlight ) {
  881. return -1;
  882. }
  883. var count = 0;
  884. for ( var i = 0, ti; ti = this.currentSelectedArr[i++]; ) {
  885. if ( !_isHide( ti ) )
  886. count++;
  887. }
  888. return count > 1 ? 0 : -1;
  889. },
  890. execCommand:function () {
  891. var start = me.currentSelectedArr[0],
  892. end = me.currentSelectedArr[me.currentSelectedArr.length - 1],
  893. table = domUtils.findParentByTagName( start, 'table' ),
  894. rows = table.rows,
  895. cellsRange = {
  896. beginRowIndex:start.parentNode.rowIndex,
  897. beginCellIndex:getIndex( start ),
  898. endRowIndex:end.parentNode.rowIndex,
  899. endCellIndex:getIndex( end )
  900. },
  901. beginRowIndex = cellsRange.beginRowIndex,
  902. beginCellIndex = cellsRange.beginCellIndex,
  903. rowsLength = cellsRange.endRowIndex - cellsRange.beginRowIndex + 1,
  904. cellLength = cellsRange.endCellIndex - cellsRange.beginCellIndex + 1,
  905. tmp = rows[beginRowIndex].cells[beginCellIndex];
  906. for ( var i = 0, ri; (ri = rows[beginRowIndex + i++]) && i <= rowsLength; ) {
  907. for ( var j = 0, ci; (ci = ri.cells[beginCellIndex + j++]) && j <= cellLength; ) {
  908. if ( i == 1 && j == 1 ) {
  909. ci.style.display = "";
  910. ci.rowSpan = rowsLength;
  911. ci.colSpan = cellLength;
  912. } else {
  913. ci.style.display = "none";
  914. ci.rowSpan = 1;
  915. ci.colSpan = 1;
  916. ci.setAttribute( 'rootRowIndex', beginRowIndex );
  917. ci.setAttribute( 'rootCellIndex', beginCellIndex );
  918. //传递内容
  919. _moveContent( tmp, ci );
  920. }
  921. }
  922. }
  923. this.selection.getRange().setStart( tmp, 0 ).setCursor();
  924. //处理有寛高,导致ie的文字不能输入占满
  925. browser.ie && domUtils.removeAttributes( tmp, ['width', 'height'] );
  926. clearSelectedTd( me.currentSelectedArr );
  927. }
  928. };
  929. /**
  930. * 将cellFrom单元格中的内容移动到cellTo中
  931. * @param cellTo 目标单元格
  932. * @param cellFrom 源单元格
  933. */
  934. function _moveContent( cellTo, cellFrom ) {
  935. if ( _isEmpty( cellFrom ) ) return;
  936. if ( _isEmpty( cellTo ) ) {
  937. cellTo.innerHTML = cellFrom.innerHTML;
  938. return;
  939. }
  940. var child = cellTo.lastChild;
  941. if ( child.nodeType != 1 || child.tagName != 'BR' ) {
  942. cellTo.appendChild( cellTo.ownerDocument.createElement( 'br' ) )
  943. }
  944. //依次移动内容
  945. while ( child = cellFrom.firstChild ) {
  946. cellTo.appendChild( child );
  947. }
  948. }
  949. /**
  950. * 根据两个单元格来获取中间包含的所有单元格集合选区
  951. * @param cellA
  952. * @param cellB
  953. * @return {Object} 选区的左上和右下坐标
  954. */
  955. function _getCellsRange( cellA, cellB ) {
  956. var trA = cellA.parentNode,
  957. trB = cellB.parentNode,
  958. aRowIndex = trA.rowIndex,
  959. bRowIndex = trB.rowIndex,
  960. rows = trA.parentNode.parentNode.rows,
  961. rowsNum = rows.length,
  962. cellsNum = rows[0].cells.length,
  963. cellAIndex = getIndex( cellA ),
  964. cellBIndex = getIndex( cellB );
  965. if ( cellA == cellB ) {
  966. return {
  967. beginRowIndex:aRowIndex,
  968. beginCellIndex:cellAIndex,
  969. endRowIndex:aRowIndex + cellA.rowSpan - 1,
  970. endCellIndex:cellBIndex + cellA.colSpan - 1
  971. }
  972. }
  973. var
  974. beginRowIndex = Math.min( aRowIndex, bRowIndex ),
  975. beginCellIndex = Math.min( cellAIndex, cellBIndex ),
  976. endRowIndex = Math.max( aRowIndex + cellA.rowSpan - 1, bRowIndex + cellB.rowSpan - 1 ),
  977. endCellIndex = Math.max( cellAIndex + cellA.colSpan - 1, cellBIndex + cellB.colSpan - 1 );
  978. while ( 1 ) {
  979. var tmpBeginRowIndex = beginRowIndex,
  980. tmpBeginCellIndex = beginCellIndex,
  981. tmpEndRowIndex = endRowIndex,
  982. tmpEndCellIndex = endCellIndex;
  983. // 检查是否有超出TableRange上边界的情况
  984. if ( beginRowIndex > 0 ) {
  985. for ( cellIndex = beginCellIndex; cellIndex <= endCellIndex; ) {
  986. var currentTopTd = rows[beginRowIndex].cells[cellIndex];
  987. if ( _isHide( currentTopTd ) ) {
  988. //overflowRowIndex = beginRowIndex == currentTopTd.rootRowIndex ? 1:0;
  989. beginRowIndex = currentTopTd.getAttribute( 'rootRowIndex' );
  990. currentTopTd = rows[currentTopTd.getAttribute( 'rootRowIndex' )].cells[currentTopTd.getAttribute( 'rootCellIndex' )];
  991. }
  992. cellIndex = getIndex( currentTopTd ) + (currentTopTd.colSpan || 1);
  993. }
  994. }
  995. //检查是否有超出左边界的情况
  996. if ( beginCellIndex > 0 ) {
  997. for ( var rowIndex = beginRowIndex; rowIndex <= endRowIndex; ) {
  998. var currentLeftTd = rows[rowIndex].cells[beginCellIndex];
  999. if ( _isHide( currentLeftTd ) ) {
  1000. // overflowCellIndex = beginCellIndex== currentLeftTd.rootCellIndex ? 1:0;
  1001. beginCellIndex = currentLeftTd.getAttribute( 'rootCellIndex' );
  1002. currentLeftTd = rows[currentLeftTd.getAttribute( 'rootRowIndex' )].cells[currentLeftTd.getAttribute( 'rootCellIndex' )];
  1003. }
  1004. rowIndex = currentLeftTd.parentNode.rowIndex + (currentLeftTd.rowSpan || 1);
  1005. }
  1006. }
  1007. // 检查是否有超出TableRange下边界的情况
  1008. if ( endRowIndex < rowsNum ) {
  1009. for ( var cellIndex = beginCellIndex; cellIndex <= endCellIndex; ) {
  1010. var currentDownTd = rows[endRowIndex].cells[cellIndex];
  1011. if ( _isHide( currentDownTd ) ) {
  1012. currentDownTd = rows[currentDownTd.getAttribute( 'rootRowIndex' )].cells[currentDownTd.getAttribute( 'rootCellIndex' )];
  1013. }
  1014. endRowIndex = currentDownTd.parentNode.rowIndex + currentDownTd.rowSpan - 1;
  1015. cellIndex = getIndex( currentDownTd ) + (currentDownTd.colSpan || 1);
  1016. }
  1017. }
  1018. //检查是否有超出右边界的情况
  1019. if ( endCellIndex < cellsNum ) {
  1020. for ( rowIndex = beginRowIndex; rowIndex <= endRowIndex; ) {
  1021. var currentRightTd = rows[rowIndex].cells[endCellIndex];
  1022. if ( _isHide( currentRightTd ) ) {
  1023. currentRightTd = rows[currentRightTd.getAttribute( 'rootRowIndex' )].cells[currentRightTd.getAttribute( 'rootCellIndex' )];
  1024. }
  1025. endCellIndex = getIndex( currentRightTd ) + currentRightTd.colSpan - 1;
  1026. rowIndex = currentRightTd.parentNode.rowIndex + (currentRightTd.rowSpan || 1);
  1027. }
  1028. }
  1029. if ( tmpBeginCellIndex == beginCellIndex && tmpEndCellIndex == endCellIndex && tmpEndRowIndex == endRowIndex && tmpBeginRowIndex == beginRowIndex ) {
  1030. break;
  1031. }
  1032. }
  1033. //返回选区的起始和结束坐标
  1034. return {
  1035. beginRowIndex:beginRowIndex,
  1036. beginCellIndex:beginCellIndex,
  1037. endRowIndex:endRowIndex,
  1038. endCellIndex:endCellIndex
  1039. }
  1040. }
  1041. /**
  1042. * 鼠标按下事件
  1043. * @param type
  1044. * @param evt
  1045. */
  1046. function _mouseDownEvent( type, evt ) {
  1047. anchorTd = evt.target || evt.srcElement;
  1048. if ( me.queryCommandState( 'highlightcode' ) || domUtils.findParent( anchorTd, function ( node ) {
  1049. return node.tagName == "DIV" && /highlighter/.test( node.id );
  1050. } ) ) {
  1051. return;
  1052. }
  1053. if ( evt.button == 2 )return;
  1054. me.document.body.style.webkitUserSelect = '';
  1055. clearSelectedTd( me.currentSelectedArr );
  1056. domUtils.clearSelectedArr( me.currentSelectedArr );
  1057. //在td里边点击,anchorTd不是td
  1058. if ( anchorTd.tagName !== 'TD' ) {
  1059. anchorTd = domUtils.findParentByTagName( anchorTd, 'td' ) || anchorTd;
  1060. }
  1061. if ( anchorTd.tagName == 'TD' ) {
  1062. me.addListener( 'mouseover', function ( type, evt ) {
  1063. var tmpTd = evt.target || evt.srcElement;
  1064. _mouseOverEvent.call( me, tmpTd );
  1065. evt.preventDefault ? evt.preventDefault() : (evt.returnValue = false);
  1066. } );
  1067. } else {
  1068. reset();
  1069. }
  1070. }
  1071. /**
  1072. * 鼠标移动事件
  1073. * @param tmpTd
  1074. */
  1075. function _mouseOverEvent( tmpTd ) {
  1076. if ( anchorTd && tmpTd.tagName == "TD" ) {
  1077. me.document.body.style.webkitUserSelect = 'none';
  1078. var table = tmpTd.parentNode.parentNode.parentNode;
  1079. me.selection.getNative()[browser.ie ? 'empty' : 'removeAllRanges']();
  1080. var range = _getCellsRange( anchorTd, tmpTd );
  1081. _toggleSelect( table, range );
  1082. }
  1083. }
  1084. /**
  1085. * 切换选区状态
  1086. * @param table
  1087. * @param cellsRange
  1088. */
  1089. function _toggleSelect( table, cellsRange ) {
  1090. var rows = table.rows;
  1091. clearSelectedTd( me.currentSelectedArr );
  1092. for ( var i = cellsRange.beginRowIndex; i <= cellsRange.endRowIndex; i++ ) {
  1093. for ( var j = cellsRange.beginCellIndex; j <= cellsRange.endCellIndex; j++ ) {
  1094. var td = rows[i].cells[j];
  1095. td.className = "selectTdClass";
  1096. me.currentSelectedArr.push( td );
  1097. }
  1098. }
  1099. }
  1100. //更新rootRowIndxe,rootCellIndex
  1101. function update( table ) {
  1102. var tds = table.getElementsByTagName( 'td' ),
  1103. rowIndex, cellIndex, rows = table.rows;
  1104. for ( var j = 0, tj; tj = tds[j++]; ) {
  1105. if ( !_isHide( tj ) ) {
  1106. rowIndex = tj.parentNode.rowIndex;
  1107. cellIndex = getIndex( tj );
  1108. for ( var r = 0; r < tj.rowSpan; r++ ) {
  1109. var c = r == 0 ? 1 : 0;
  1110. for ( ; c < tj.colSpan; c++ ) {
  1111. var tmp = rows[rowIndex + r].children[cellIndex + c];
  1112. tmp.setAttribute( 'rootRowIndex', rowIndex );
  1113. tmp.setAttribute( 'rootCellIndex', cellIndex );
  1114. }
  1115. }
  1116. }
  1117. if ( !_isHide( tj ) ) {
  1118. domUtils.removeAttributes( tj, ['rootRowIndex', 'rootCellIndex'] );
  1119. }
  1120. if ( tj.colSpan && tj.colSpan == 1 ) {
  1121. tj.removeAttribute( 'colSpan' )
  1122. }
  1123. if ( tj.rowSpan && tj.rowSpan == 1 ) {
  1124. tj.removeAttribute( 'rowSpan' )
  1125. }
  1126. var width;
  1127. if ( !_isHide( tj ) && (width = tj.style.width) && /%/.test( width ) ) {
  1128. tj.style.width = Math.floor( 100 / tj.parentNode.cells.length ) + '%'
  1129. }
  1130. }
  1131. }
  1132. me.adjustTable = function ( cont ) {
  1133. var table = cont.getElementsByTagName( 'table' );
  1134. for ( var i = 0, ti; ti = table[i++]; ) {
  1135. //如果表格的align不是默认,将不占位,给后边的block元素设置clear:both
  1136. if ( ti.getAttribute( 'align' ) ) {
  1137. var next = ti.nextSibling;
  1138. while ( next ) {
  1139. if ( domUtils.isBlockElm( next ) ) {
  1140. break;
  1141. }
  1142. next = next.nextSibling;
  1143. }
  1144. if ( next ) {
  1145. next.style.clear = 'both';
  1146. }
  1147. }
  1148. ti.removeAttribute( '_innerCreateTable' );
  1149. var tds = domUtils.getElementsByTagName( ti, 'td' ),
  1150. td, tmpTd;
  1151. for ( var j = 0, tj; tj = tds[j++]; ) {
  1152. if ( domUtils.isEmptyNode( tj ) ) {
  1153. tj.innerHTML = browser.ie ? domUtils.fillChar : '<br/>';
  1154. }
  1155. var index = getIndex( tj ),
  1156. rowIndex = tj.parentNode.rowIndex,
  1157. rows = domUtils.findParentByTagName( tj, 'table' ).rows;
  1158. for ( var r = 0; r < tj.rowSpan; r++ ) {
  1159. var c = r == 0 ? 1 : 0;
  1160. for ( ; c < tj.colSpan; c++ ) {
  1161. if ( !td ) {
  1162. td = tj.cloneNode( false );
  1163. td.rowSpan = td.colSpan = 1;
  1164. td.style.display = 'none';
  1165. td.innerHTML = browser.ie ? '' : '<br/>';
  1166. } else {
  1167. td = td.cloneNode( true )
  1168. }
  1169. td.setAttribute( 'rootRowIndex', tj.parentNode.rowIndex );
  1170. td.setAttribute( 'rootCellIndex', index );
  1171. if ( r == 0 ) {
  1172. if ( tj.nextSibling ) {
  1173. tj.parentNode.insertBefore( td, tj.nextSibling );
  1174. } else {
  1175. tj.parentNode.appendChild( td )
  1176. }
  1177. } else {
  1178. tmpTd = rows[rowIndex + r].children[index];
  1179. if ( tmpTd ) {
  1180. tmpTd.parentNode.insertBefore( td, tmpTd )
  1181. } else {
  1182. //trace:1032
  1183. rows[rowIndex + r].appendChild( td )
  1184. }
  1185. }
  1186. }
  1187. }
  1188. }
  1189. var bw = domUtils.getComputedStyle( ti, "border-width" );
  1190. if ( bw == '0px' || (bw == "" && ti.getAttribute( "border" ) === "0") ) {
  1191. ti.className = "noBorderTable";
  1192. }
  1193. }
  1194. me.fireEvent( "afteradjusttable", cont );
  1195. };
  1196. // me.addListener('beforegetcontent',function(){
  1197. // for(var i=0,ti,ts=me.document.getElementsByTagName('table');ti=ts[i++];){
  1198. // var pN = ti.parentNode;
  1199. // if(pN && pN.getAttribute('dropdrag')){
  1200. // domUtils.remove(pN,true)
  1201. // }
  1202. // }
  1203. // });
  1204. //
  1205. // me.addListener('aftergetcontent',function(){
  1206. // if(!me.queryCommandState('source'))
  1207. // me.fireEvent('afteradjusttable',me.document)
  1208. // });
  1209. // //table拖拽
  1210. // me.addListener("afteradjusttable",function(type,cont){
  1211. // var table = cont.getElementsByTagName("table"),
  1212. // dragCont = me.document.createElement("div");
  1213. // domUtils.setAttributes(dragCont,{
  1214. // style:'margin:0;padding:5px;border:0;',
  1215. // dropdrag:true
  1216. // });
  1217. // for (var i = 0,ti; ti = table[i++];) {
  1218. // if(ti.parentNode && ti.parentNode.nodeType == 1){
  1219. //
  1220. //
  1221. // (function(ti){
  1222. // var div = dragCont.cloneNode(false);
  1223. // ti.parentNode.insertBefore(div,ti);
  1224. // div.appendChild(ti);
  1225. // var borderStyle;
  1226. // domUtils.on(div,'mousemove',function(evt){
  1227. // var tag = evt.srcElement || evt.target;
  1228. // if(tag.tagName.toLowerCase()=="div"){
  1229. // if(ie && me.body.getAttribute("contentEditable") == 'true')
  1230. // me.body.setAttribute("contentEditable","false");
  1231. // borderStyle = clickPosition(ti,this,evt)
  1232. //
  1233. // }
  1234. // });
  1235. // if(ie){
  1236. // domUtils.on(div,'mouseleave',function(evt){
  1237. //
  1238. // if(evt.srcElement.tagName.toLowerCase()=="div" && ie && me.body.getAttribute("contentEditable") == 'false'){
  1239. //
  1240. // me.body.setAttribute("contentEditable","true");
  1241. // }
  1242. //
  1243. //
  1244. // });
  1245. // }
  1246. //
  1247. // domUtils.on(div,"mousedown",function(evt){
  1248. // var tag = evt.srcElement || evt.target;
  1249. //
  1250. // if(tag.tagName.toLowerCase()=="div"){
  1251. // if(ie && me.body.getAttribute("contentEditable") == 'true')
  1252. // me.body.setAttribute("contentEditable","false");
  1253. // var tWidth = ti.offsetWidth,
  1254. // tHeight = ti.offsetHeight,
  1255. // align = ti.getAttribute('align');
  1256. //
  1257. //
  1258. // try{
  1259. // baidu.editor.ui.uiUtils.startDrag(evt, {
  1260. // ondragstart:function(){},
  1261. // ondragmove: function (x, y){
  1262. //
  1263. // if(align && align!="left" && /\w?w-/.test(borderStyle)){
  1264. // x = -x;
  1265. // }
  1266. // if(/^s?[we]/.test(borderStyle)){
  1267. // ti.setAttribute("width",(tWidth+x)>0?tWidth+x: 0);
  1268. // }
  1269. // if(/^s/.test(borderStyle)){
  1270. // ti.setAttribute("height",(tHeight+y)>0?tHeight+y:0);
  1271. // }
  1272. // },
  1273. // ondragstop: function (){}
  1274. // },me.document);
  1275. // }catch(e){
  1276. // alert("您没有引入uiUtils,无法拖动table");
  1277. // }
  1278. //
  1279. // }
  1280. // });
  1281. //
  1282. // domUtils.on(ti,"mouseover",function(){
  1283. // var div = ti.parentNode;
  1284. // if(div && div.parentNode && div.getAttribute('dropdrag')){
  1285. // domUtils.setStyle(div,"cursor","text");
  1286. // if(ie && me.body.getAttribute("contentEditable") == 'false')
  1287. // me.body.setAttribute("contentEditable","true");
  1288. // }
  1289. //
  1290. //
  1291. // });
  1292. // })(ti);
  1293. //
  1294. // }
  1295. // }
  1296. // });
  1297. // function clickPosition(table,div,evt){
  1298. // var pos = domUtils.getXY(table),
  1299. // tWidth = table.offsetWidth,
  1300. // tHeight = table.offsetHeight,
  1301. // evtPos = {
  1302. // top : evt.clientY,
  1303. // left : evt.clientX
  1304. // },
  1305. // borderStyle = "";
  1306. //
  1307. // if(Math.abs(pos.x-evtPos.left)<15){
  1308. //
  1309. // //左,左下
  1310. // borderStyle = Math.abs(evtPos.top-pos.y-tHeight)<15 ? "sw-resize" : "w-resize";
  1311. // }else if(Math.abs(evtPos.left-pos.x-tWidth)<15){
  1312. // //右,右下
  1313. // borderStyle = Math.abs(evtPos.top-pos.y-tHeight)<15 ? "se-resize" : "e-resize";
  1314. // }else if(Math.abs(evtPos.top-pos.y-tHeight)<15 && Math.abs(evtPos.left-pos.x)<tWidth){
  1315. // //下
  1316. // borderStyle = "s-resize";
  1317. // }
  1318. // domUtils.setStyle(div,"cursor",borderStyle||'text');
  1319. // return borderStyle;
  1320. // }
  1321. };