table.js 129 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044
  1. /**
  2. * Created with JetBrains PhpStorm.
  3. * User: taoqili
  4. * Date: 12-10-12
  5. * Time: 上午10:05
  6. * To change this template use File | Settings | File Templates.
  7. */
  8. UE.plugins['table'] = function () {
  9. var me = this,
  10. debug = true;
  11. function showError(e) {
  12. if (debug) throw e;
  13. }
  14. //处理拖动及框选相关方法
  15. var startTd = null, //鼠标按下时的锚点td
  16. currentTd = null, //当前鼠标经过时的td
  17. onDrag = "", //指示当前拖动状态,其值可为"","h","v" ,分别表示未拖动状态,横向拖动状态,纵向拖动状态,用于鼠标移动过程中的判断
  18. onBorder = false, //检测鼠标按下时是否处在单元格边缘位置
  19. dragButton = null,
  20. dragOver = false,
  21. dragLine = null, //模拟的拖动线
  22. dragTd = null; //发生拖动的目标td
  23. var mousedown = false,
  24. //todo 判断混乱模式
  25. needIEHack = true;
  26. me.setOpt({
  27. 'maxColNum':20,
  28. 'maxRowNum':100,
  29. 'defaultCols':5,
  30. 'defaultRows':5,
  31. 'tdvalign':'top',
  32. 'cursorpath':me.options.UEDITOR_HOME_URL + "themes/default/images/cursor_",
  33. 'tableDragable':false
  34. });
  35. me.getUETable = getUETable;
  36. var commands = {
  37. 'deletetable':1,
  38. 'inserttable':1,
  39. 'cellvalign':1,
  40. 'insertcaption':1,
  41. 'deletecaption':1,
  42. 'inserttitle':1,
  43. 'deletetitle':1,
  44. "mergeright":1,
  45. "mergedown":1,
  46. "mergecells":1,
  47. "insertrow":1,
  48. "insertrownext":1,
  49. "deleterow":1,
  50. "insertcol":1,
  51. "insertcolnext":1,
  52. "deletecol":1,
  53. "splittocells":1,
  54. "splittorows":1,
  55. "splittocols":1,
  56. "adaptbytext":1,
  57. "adaptbywindow":1,
  58. "adaptbycustomer":1,
  59. "insertparagraph":1,
  60. "averagedistributecol":1,
  61. "averagedistributerow":1
  62. };
  63. me.ready(function () {
  64. utils.cssRule('table',
  65. //选中的td上的样式
  66. '.selectTdClass{background-color:#edf5fa !important}' +
  67. 'table.noBorderTable td,table.noBorderTable th,table.noBorderTable caption{border:1px dashed #ddd !important}' +
  68. //插入的表格的默认样式
  69. 'table{margin-bottom:10px;border-collapse:collapse;display:table;}' +
  70. 'td,th{ background:white; padding: 5px 10px;border: 1px solid #DDD;}' +
  71. 'caption{border:1px dashed #DDD;border-bottom:0;padding:3px;text-align:center;}' +
  72. 'th{border-top:2px solid #BBB;background:#F7F7F7;}' +
  73. 'td p{margin:0;padding:0;}', me.document);
  74. var tableCopyList, isFullCol, isFullRow;
  75. //注册del/backspace事件
  76. me.addListener('keydown', function (cmd, evt) {
  77. var me = this;
  78. var keyCode = evt.keyCode || evt.which;
  79. if (keyCode == 8) {
  80. var ut = getUETableBySelected(me);
  81. if (ut && ut.selectedTds.length) {
  82. me.fireEvent('saveScene');
  83. if (ut.isFullCol()) {
  84. me.execCommand('deletecol')
  85. } else if (ut.isFullRow()) {
  86. me.execCommand('deleterow')
  87. } else {
  88. me.fireEvent('delcells');
  89. }
  90. domUtils.preventDefault(evt);
  91. }
  92. var caption = domUtils.findParentByTagName(me.selection.getStart(), 'caption', true),
  93. range = me.selection.getRange();
  94. if (range.collapsed && caption && isEmptyBlock(caption)) {
  95. me.fireEvent('saveScene');
  96. var table = caption.parentNode;
  97. domUtils.remove(caption);
  98. if (table) {
  99. range.setStart(table.rows[0].cells[0], 0).setCursor(false, true);
  100. }
  101. }
  102. me.fireEvent('saveScene');
  103. }
  104. if (keyCode == 46) {
  105. ut = getUETableBySelected(me);
  106. if (ut) {
  107. me.fireEvent('saveScene');
  108. for (var i = 0, ci; ci = ut.selectedTds[i++];) {
  109. domUtils.fillNode(me.document, ci)
  110. }
  111. me.fireEvent('saveScene');
  112. domUtils.preventDefault(evt);
  113. }
  114. }
  115. if (keyCode == 13) {
  116. var rng = me.selection.getRange(),
  117. caption = domUtils.findParentByTagName(rng.startContainer, 'caption', true);
  118. if (caption) {
  119. var table = domUtils.findParentByTagName(caption, 'table');
  120. if (!rng.collapsed) {
  121. rng.deleteContents();
  122. me.fireEvent('saveScene');
  123. } else {
  124. if (caption) {
  125. rng.setStart(table.rows[0].cells[0], 0).setCursor(false, true);
  126. }
  127. }
  128. domUtils.preventDefault(evt);
  129. return;
  130. }
  131. if (rng.collapsed) {
  132. var table = domUtils.findParentByTagName(rng.startContainer, 'table');
  133. if (table) {
  134. var cell = table.rows[0].cells[0],
  135. start = domUtils.findParentByTagName(me.selection.getStart(), ['td', 'th'], true),
  136. preNode = table.previousSibling;
  137. if (cell === start && (!preNode || preNode.nodeType == 1 && preNode.tagName == 'TABLE' ) && domUtils.isStartInblock(rng)) {
  138. me.execCommand('insertparagraphbeforetable');
  139. domUtils.preventDefault(evt);
  140. }
  141. }
  142. }
  143. }
  144. if ((evt.ctrlKey || evt.metaKey) && evt.keyCode == '67') {
  145. tableCopyList = null;
  146. table = getUETableBySelected(me);
  147. if (table) {
  148. var tds = table.selectedTds;
  149. isFullCol = table.isFullCol();
  150. isFullRow = table.isFullRow();
  151. tableCopyList = [
  152. [cloneCell(tds[0])]
  153. ];
  154. for (var i = 1, ci; ci = tds[i]; i++) {
  155. if (ci.parentNode !== tds[i - 1].parentNode) {
  156. tableCopyList.push([cloneCell(ci)])
  157. } else {
  158. tableCopyList[tableCopyList.length - 1].push(cloneCell(ci))
  159. }
  160. }
  161. }
  162. }
  163. });
  164. me.addListener('beforepaste', function (cmd, html) {
  165. var me = this;
  166. var rng = me.selection.getRange();
  167. if (domUtils.findParentByTagName(rng.startContainer, 'caption', true)) {
  168. var div = me.document.createElement("div");
  169. div.innerHTML = html.html;
  170. html.html = div[browser.ie ? 'innerText' : 'textContent'];
  171. return;
  172. }
  173. var table = getUETableBySelected(me);
  174. if (tableCopyList) {
  175. me.fireEvent('saveScene');
  176. var rng = me.selection.getRange();
  177. var td = domUtils.findParentByTagName(rng.startContainer, ['td', 'th'], true), tmpNode, preNode;
  178. if (td) {
  179. var ut = getUETable(td);
  180. if (isFullRow) {
  181. var rowIndex = ut.getCellInfo(td).rowIndex;
  182. if (td.tagName == 'TH') {
  183. rowIndex++;
  184. }
  185. for (var i = 0, ci; ci = tableCopyList[i++];) {
  186. var tr = ut.insertRow(rowIndex++, "td");
  187. for (var j = 0, cj; cj = ci[j]; j++) {
  188. var cell = tr.cells[j];
  189. if (!cell) {
  190. cell = tr.insertCell(j)
  191. }
  192. cell.innerHTML = cj.innerHTML;
  193. cj.getAttribute('width') && cell.setAttribute('width', cj.getAttribute('width'));
  194. cj.getAttribute('vAlign') && cell.setAttribute('vAlign', cj.getAttribute('vAlign'));
  195. cj.getAttribute('align') && cell.setAttribute('align', cj.getAttribute('align'));
  196. cj.style.cssText && (cell.style.cssText = cj.style.cssText)
  197. }
  198. for (var j = 0, cj; cj = tr.cells[j]; j++) {
  199. if (!ci[j])
  200. break;
  201. cj.innerHTML = ci[j].innerHTML;
  202. ci[j].getAttribute('width') && cj.setAttribute('width', ci[j].getAttribute('width'));
  203. ci[j].getAttribute('vAlign') && cj.setAttribute('vAlign', ci[j].getAttribute('vAlign'));
  204. ci[j].getAttribute('align') && cj.setAttribute('align', ci[j].getAttribute('align'));
  205. ci[j].style.cssText && (cj.style.cssText = ci[j].style.cssText)
  206. }
  207. }
  208. } else {
  209. if (isFullCol) {
  210. cellInfo = ut.getCellInfo(td);
  211. var maxColNum = 0;
  212. for (var j = 0, ci = tableCopyList[0], cj; cj = ci[j++];) {
  213. maxColNum += cj.colSpan || 1;
  214. }
  215. me.__hasEnterExecCommand = true;
  216. for (i = 0; i < maxColNum; i++) {
  217. me.execCommand('insertcol');
  218. }
  219. me.__hasEnterExecCommand = false;
  220. td = ut.table.rows[0].cells[cellInfo.cellIndex];
  221. if (td.tagName == 'TH') {
  222. td = ut.table.rows[1].cells[cellInfo.cellIndex];
  223. }
  224. }
  225. for (var i = 0, ci; ci = tableCopyList[i++];) {
  226. tmpNode = td;
  227. for (var j = 0, cj; cj = ci[j++];) {
  228. if (td) {
  229. td.innerHTML = cj.innerHTML;
  230. //todo 定制处理
  231. cj.getAttribute('width') && td.setAttribute('width', cj.getAttribute('width'));
  232. cj.getAttribute('vAlign') && td.setAttribute('vAlign', cj.getAttribute('vAlign'));
  233. cj.getAttribute('align') && td.setAttribute('align', cj.getAttribute('align'));
  234. cj.style.cssText && (td.style.cssText = cj.style.cssText);
  235. preNode = td;
  236. td = td.nextSibling;
  237. } else {
  238. var cloneTd = cj.cloneNode(true);
  239. domUtils.removeAttributes(cloneTd, ['class', 'rowSpan', 'colSpan']);
  240. preNode.parentNode.appendChild(cloneTd)
  241. }
  242. }
  243. td = ut.getNextCell(tmpNode, true, true);
  244. if (!tableCopyList[i])
  245. break;
  246. if (!td) {
  247. var cellInfo = ut.getCellInfo(tmpNode);
  248. ut.table.insertRow(ut.table.rows.length);
  249. ut.update();
  250. td = ut.getVSideCell(tmpNode, true);
  251. }
  252. }
  253. }
  254. ut.update();
  255. } else {
  256. table = me.document.createElement('table');
  257. for (var i = 0, ci; ci = tableCopyList[i++];) {
  258. var tr = table.insertRow(table.rows.length);
  259. for (var j = 0, cj; cj = ci[j++];) {
  260. cloneTd = cloneCell(cj);
  261. domUtils.removeAttributes(cloneTd, ['class']);
  262. tr.appendChild(cloneTd)
  263. }
  264. if (j == 2 && cloneTd.rowSpan > 1) {
  265. cloneTd.rowSpan = 1;
  266. }
  267. }
  268. var defaultValue = getDefaultValue(me),
  269. width = me.body.offsetWidth -
  270. (needIEHack ? parseInt(domUtils.getComputedStyle(me.body, 'margin-left'), 10) * 2 : 0) - defaultValue.tableBorder * 2 - (me.options.offsetWidth || 0);
  271. me.execCommand('insertHTML', '<table ' +
  272. ( isFullCol && isFullRow ? 'width="' + width + '"' : '') +
  273. '>' + table.innerHTML.replace(/>\s*</g, '><').replace(/\bth\b/gi, "td") + '</table>')
  274. }
  275. me.fireEvent('contentchange');
  276. me.fireEvent('saveScene');
  277. html.html = '';
  278. } else {
  279. var div = me.document.createElement("div"), tables;
  280. div.innerHTML = html.html;
  281. tables = div.getElementsByTagName("table");
  282. if (domUtils.findParentByTagName(me.selection.getStart(), 'table')) {
  283. utils.each(tables, function (t) {
  284. domUtils.remove(t)
  285. });
  286. if (domUtils.findParentByTagName(me.selection.getStart(), 'caption', true)) {
  287. div.innerHTML = div[browser.ie ? 'innerText' : 'textContent'];
  288. }
  289. } else {
  290. utils.each(tables, function (table) {
  291. removeStyleSize(table, true);
  292. domUtils.removeAttributes(table, ['style', 'border']);
  293. utils.each(domUtils.getElementsByTagName(table, "td"), function (td) {
  294. if (isEmptyBlock(td)) {
  295. domUtils.fillNode(me.document, td);
  296. }
  297. removeStyleSize(td, true);
  298. // domUtils.removeAttributes(td, ['style'])
  299. });
  300. });
  301. }
  302. html.html = div.innerHTML;
  303. }
  304. });
  305. me.addListener('afterpaste', function () {
  306. utils.each(domUtils.getElementsByTagName(me.body, "table"), function (table) {
  307. if (table.offsetWidth > me.body.offsetWidth) {
  308. var defaultValue = getDefaultValue(me, table);
  309. table.style.width = me.body.offsetWidth - (needIEHack ? parseInt(domUtils.getComputedStyle(me.body, 'margin-left'), 10) * 2 : 0) - defaultValue.tableBorder * 2 - (me.options.offsetWidth || 0) + 'px'
  310. }
  311. })
  312. });
  313. me.addListener('blur', function () {
  314. tableCopyList = null;
  315. });
  316. var timer;
  317. me.addListener('keydown', function () {
  318. clearTimeout(timer);
  319. timer = setTimeout(function () {
  320. var rng = me.selection.getRange(),
  321. cell = domUtils.findParentByTagName(rng.startContainer, ['th', 'td'], true);
  322. if (cell) {
  323. var table = cell.parentNode.parentNode.parentNode;
  324. if (table.offsetWidth > table.getAttribute("width")) {
  325. cell.style.wordBreak = "break-all";
  326. }
  327. }
  328. }, 100);
  329. });
  330. me.addListener("selectionchange", function () {
  331. toggleDragableState(me, false, "", null);
  332. });
  333. //内容变化时触发索引更新
  334. //todo 可否考虑标记检测,如果不涉及表格的变化就不进行索引重建和更新
  335. me.addListener("contentchange", function () {
  336. var me = this;
  337. //尽可能排除一些不需要更新的状况
  338. hideDragLine(me);
  339. if (getUETableBySelected(me))return;
  340. var rng = me.selection.getRange();
  341. var start = rng.startContainer;
  342. start = domUtils.findParentByTagName(start, ['td', 'th'], true);
  343. utils.each(domUtils.getElementsByTagName(me.document, 'table'), function (table) {
  344. if (me.fireEvent("excludetable", table) === true) return;
  345. table.ueTable = new UETable(table);
  346. utils.each(domUtils.getElementsByTagName(me.document, 'td'), function (td) {
  347. if (domUtils.isEmptyBlock(td) && td !== start) {
  348. domUtils.fillNode(me.document, td);
  349. if (browser.ie && browser.version == 6) {
  350. td.innerHTML = '&nbsp;'
  351. }
  352. }
  353. });
  354. utils.each(domUtils.getElementsByTagName(me.document, 'th'), function (th) {
  355. if (domUtils.isEmptyBlock(th) && th !== start) {
  356. domUtils.fillNode(me.document, th);
  357. if (browser.ie && browser.version == 6) {
  358. th.innerHTML = '&nbsp;'
  359. }
  360. }
  361. });
  362. table.onmousemove = function () {
  363. me.options.tableDragable && toggleDragButton(true, this, me);
  364. };
  365. table.onmouseout = function () {
  366. toggleDragableState(me, false, "", null);
  367. hideDragLine(me);
  368. };
  369. table.onclick = function (evt) {
  370. evt = me.window.event || evt;
  371. var target = getParentTdOrTh(evt.target || evt.srcElement);
  372. if (!target)return;
  373. var ut = getUETable(target),
  374. table = ut.table,
  375. cellInfo = ut.getCellInfo(target),
  376. cellsRange,
  377. rng = me.selection.getRange();
  378. // if ("topLeft" == inPosition(table, mouseCoords(evt))) {
  379. // cellsRange = ut.getCellsRange(ut.table.rows[0].cells[0], ut.getLastCell());
  380. // ut.setSelected(cellsRange);
  381. // return;
  382. // }
  383. // if ("bottomRight" == inPosition(table, mouseCoords(evt))) {
  384. //
  385. // return;
  386. // }
  387. if (inTableSide(table, target, evt, true)) {
  388. var endTdCol = ut.getCell(ut.indexTable[ut.rowsNum - 1][cellInfo.colIndex].rowIndex, ut.indexTable[ut.rowsNum - 1][cellInfo.colIndex].cellIndex);
  389. if (evt.shiftKey && ut.selectedTds.length) {
  390. if (ut.selectedTds[0] !== endTdCol) {
  391. cellsRange = ut.getCellsRange(ut.selectedTds[0], endTdCol);
  392. ut.setSelected(cellsRange);
  393. } else {
  394. rng && rng.selectNodeContents(endTdCol).select();
  395. }
  396. } else {
  397. if (target !== endTdCol) {
  398. cellsRange = ut.getCellsRange(target, endTdCol);
  399. ut.setSelected(cellsRange);
  400. } else {
  401. rng && rng.selectNodeContents(endTdCol).select();
  402. }
  403. }
  404. return;
  405. }
  406. if (inTableSide(table, target, evt)) {
  407. var endTdRow = ut.getCell(ut.indexTable[cellInfo.rowIndex][ut.colsNum - 1].rowIndex, ut.indexTable[cellInfo.rowIndex][ut.colsNum - 1].cellIndex);
  408. if (evt.shiftKey && ut.selectedTds.length) {
  409. if (ut.selectedTds[0] !== endTdRow) {
  410. cellsRange = ut.getCellsRange(ut.selectedTds[0], endTdRow);
  411. ut.setSelected(cellsRange);
  412. } else {
  413. rng && rng.selectNodeContents(endTdRow).select();
  414. }
  415. } else {
  416. if (target !== endTdRow) {
  417. cellsRange = ut.getCellsRange(target, endTdRow);
  418. ut.setSelected(cellsRange);
  419. } else {
  420. rng && rng.selectNodeContents(endTdRow).select();
  421. }
  422. }
  423. }
  424. };
  425. table.ondblclick = function (evt) {
  426. evt = me.window.event || evt;
  427. var target = getParentTdOrTh(evt.target || evt.srcElement);
  428. if (target) {
  429. var h;
  430. if (h = getRelation(target, mouseCoords(evt))) {
  431. if (h == 'h1') {
  432. h = 'h';
  433. if (inTableSide(domUtils.findParentByTagName(target, "table"), target, evt)) {
  434. me.execCommand('adaptbywindow');
  435. } else {
  436. target = getUETable(target).getPreviewCell(target);
  437. if (target) {
  438. var rng = me.selection.getRange();
  439. rng.selectNodeContents(target).setCursor(true, true)
  440. }
  441. }
  442. }
  443. h == 'h' && me.execCommand('adaptbytext');
  444. }
  445. }
  446. }
  447. });
  448. switchBoderColor(true);
  449. });
  450. //仅IE8以上支持
  451. if (!browser.ie || (browser.ie && browser.version > 7)) {
  452. domUtils.on(me.document, "mousemove", mouseMoveEvent);
  453. }
  454. domUtils.on(me.document, "mouseout", function (evt) {
  455. var target = evt.target || evt.srcElement;
  456. if (target.tagName == "TABLE") {
  457. toggleDragableState(me, false, "", null);
  458. }
  459. });
  460. me.addListener("mousedown", mouseDownEvent);
  461. me.addListener("mouseup", mouseUpEvent);
  462. var currentRowIndex = 0;
  463. me.addListener("mousedown", function () {
  464. currentRowIndex = 0;
  465. });
  466. me.addListener('tabkeydown', function () {
  467. var range = this.selection.getRange(),
  468. common = range.getCommonAncestor(true, true),
  469. table = domUtils.findParentByTagName(common, 'table');
  470. if (table) {
  471. if (domUtils.findParentByTagName(common, 'caption', true)) {
  472. var cell = domUtils.getElementsByTagName(table, 'th td');
  473. if (cell && cell.length) {
  474. range.setStart(cell[0], 0).setCursor(false, true)
  475. }
  476. } else {
  477. var cell = domUtils.findParentByTagName(common, ['td', 'th'], true),
  478. ua = getUETable(cell);
  479. currentRowIndex = cell.rowSpan > 1 ? currentRowIndex : ua.getCellInfo(cell).rowIndex;
  480. var nextCell = ua.getTabNextCell(cell, currentRowIndex);
  481. if (nextCell) {
  482. if (isEmptyBlock(nextCell)) {
  483. range.setStart(nextCell, 0).setCursor(false, true)
  484. } else {
  485. range.selectNodeContents(nextCell).select()
  486. }
  487. } else {
  488. me.fireEvent('saveScene');
  489. me.__hasEnterExecCommand = true;
  490. this.execCommand('insertrownext');
  491. me.__hasEnterExecCommand = false;
  492. range = this.selection.getRange();
  493. range.setStart(table.rows[table.rows.length - 1].cells[0], 0).setCursor();
  494. me.fireEvent('saveScene');
  495. }
  496. }
  497. return true;
  498. }
  499. });
  500. browser.ie && me.addListener('selectionchange', function () {
  501. toggleDragableState(this, false, "", null);
  502. });
  503. me.addListener("keydown", function (type, evt) {
  504. var me = this;
  505. //处理在表格的最后一个输入tab产生新的表格
  506. var keyCode = evt.keyCode || evt.which;
  507. if (keyCode == 8 || keyCode == 46) {
  508. return;
  509. }
  510. var notCtrlKey = !evt.ctrlKey && !evt.metaKey && !evt.shiftKey && !evt.altKey;
  511. notCtrlKey && removeSelectedClass(domUtils.getElementsByTagName(me.body, "td"));
  512. var ut = getUETableBySelected(me);
  513. if (!ut) return;
  514. notCtrlKey && ut.clearSelected();
  515. });
  516. me.addListener("beforegetcontent", function () {
  517. switchBoderColor(false);
  518. browser.ie && utils.each(me.document.getElementsByTagName('caption'), function (ci) {
  519. if (domUtils.isEmptyNode(ci)) {
  520. ci.innerHTML = '&nbsp;'
  521. }
  522. });
  523. });
  524. me.addListener("aftergetcontent", function () {
  525. switchBoderColor(true);
  526. });
  527. me.addListener("getAllHtml", function () {
  528. removeSelectedClass(me.document.getElementsByTagName("td"));
  529. });
  530. //修正全屏状态下插入的表格宽度在非全屏状态下撑开编辑器的情况
  531. me.addListener("fullscreenchanged", function (type, fullscreen) {
  532. if (!fullscreen) {
  533. var ratio = this.body.offsetWidth / document.body.offsetWidth,
  534. tables = domUtils.getElementsByTagName(this.body, "table");
  535. utils.each(tables, function (table) {
  536. if (table.offsetWidth < me.body.offsetWidth) return false;
  537. var tds = domUtils.getElementsByTagName(table, "td"),
  538. backWidths = [];
  539. utils.each(tds, function (td) {
  540. backWidths.push(td.offsetWidth);
  541. });
  542. for (var i = 0, td; td = tds[i]; i++) {
  543. td.setAttribute("width", Math.floor(backWidths[i] * ratio));
  544. }
  545. table.setAttribute("width", Math.floor(getTableWidth(me, needIEHack, getDefaultValue(me))))
  546. });
  547. }
  548. });
  549. //重写execCommand命令,用于处理框选时的处理
  550. var oldExecCommand = me.execCommand;
  551. me.execCommand = function (cmd) {
  552. var me = this;
  553. cmd = cmd.toLowerCase();
  554. var ut = getUETableBySelected(me), tds,
  555. range = new dom.Range(me.document),
  556. cmdFun = me.commands[cmd] || UE.commands[cmd],
  557. result;
  558. if (!cmdFun) return;
  559. if (ut && !commands[cmd] && !cmdFun.notNeedUndo && !me.__hasEnterExecCommand) {
  560. me.__hasEnterExecCommand = true;
  561. me.fireEvent("beforeexeccommand", cmd);
  562. tds = ut.selectedTds;
  563. var lastState = -2, lastValue = -2, value, state;
  564. for (var i = 0, td; td = tds[i]; i++) {
  565. if (isEmptyBlock(td)) {
  566. range.setStart(td, 0).setCursor(false, true)
  567. } else {
  568. range.selectNodeContents(td).select(true);
  569. }
  570. state = me.queryCommandState(cmd);
  571. value = me.queryCommandValue(cmd);
  572. if (state != -1) {
  573. if (lastState !== state || lastValue !== value) {
  574. me._ignoreContentChange = true;
  575. result = oldExecCommand.apply(me, arguments);
  576. me._ignoreContentChange = false;
  577. }
  578. lastState = me.queryCommandState(cmd);
  579. lastValue = me.queryCommandValue(cmd);
  580. if (domUtils.isEmptyBlock(td)) {
  581. domUtils.fillNode(me.document, td)
  582. }
  583. }
  584. }
  585. range.setStart(tds[0], 0).shrinkBoundary(true).setCursor(false, true);
  586. me.fireEvent('contentchange');
  587. me.fireEvent("afterexeccommand", cmd);
  588. me.__hasEnterExecCommand = false;
  589. me._selectionChange();
  590. } else {
  591. result = oldExecCommand.apply(me, arguments);
  592. }
  593. return result;
  594. };
  595. });
  596. /**
  597. * 删除obj的宽高style,改成属性宽高
  598. * @param obj
  599. * @param replaceToProperty
  600. */
  601. function removeStyleSize(obj, replaceToProperty) {
  602. removeStyle(obj, "width", true);
  603. removeStyle(obj, "height", true);
  604. }
  605. function removeStyle(obj, styleName, replaceToProperty) {
  606. if (obj.style[styleName]) {
  607. replaceToProperty && obj.setAttribute(styleName, parseInt(obj.style[styleName], 10));
  608. obj.style[styleName] = "";
  609. }
  610. }
  611. function getParentTdOrTh(ele) {
  612. if (ele.tagName == "TD" || ele.tagName == "TH") return ele;
  613. var td;
  614. if (td = domUtils.findParentByTagName(ele, "td", true) || domUtils.findParentByTagName(ele, "th", true)) return td;
  615. return null;
  616. }
  617. function isEmptyBlock(node) {
  618. var reg = new RegExp(domUtils.fillChar, 'g');
  619. if (node[browser.ie ? 'innerText' : 'textContent'].replace(/^\s*$/, '').replace(reg, '').length > 0) {
  620. return 0;
  621. }
  622. for (var n in dtd.$isNotEmpty) {
  623. if (node.getElementsByTagName(n).length) {
  624. return 0;
  625. }
  626. }
  627. return 1;
  628. }
  629. function mouseCoords(evt) {
  630. if (evt.pageX || evt.pageY) {
  631. return { x:evt.pageX, y:evt.pageY };
  632. }
  633. return {
  634. x:evt.clientX + me.document.body.scrollLeft - me.document.body.clientLeft,
  635. y:evt.clientY + me.document.body.scrollTop - me.document.body.clientTop
  636. };
  637. }
  638. function mouseMoveEvent(evt) {
  639. try {
  640. //普通状态下鼠标移动
  641. var target = getParentTdOrTh(evt.target || evt.srcElement),
  642. pos;
  643. //修改单元格大小时的鼠标移动
  644. if (onDrag && dragTd) {
  645. me.document.body.style.webkitUserSelect = 'none';
  646. me.selection.getNative()[browser.ie ? 'empty' : 'removeAllRanges']();
  647. pos = mouseCoords(evt);
  648. toggleDragableState(me, true, "", pos, target);
  649. if (onDrag == "h") {
  650. dragLine.style.left = getPermissionX(dragTd, evt) + "px";
  651. } else if (onDrag == "v") {
  652. dragLine.style.top = getPermissionY(dragTd, evt) + "px";
  653. }
  654. return;
  655. }
  656. //当鼠标处于table上时,修改移动过程中的光标状态
  657. if (target) {
  658. //针对使用table作为容器的组件不触发拖拽效果
  659. if (me.fireEvent('excludetable', target) === true)
  660. return;
  661. pos = mouseCoords(evt);
  662. var state = getRelation(target, pos),
  663. table = domUtils.findParentByTagName(target, "table", true);
  664. if (inTableSide(table, target, evt, true)) {
  665. //toggleCursor(pos,true,"_h");
  666. if (me.fireEvent("excludetable", table) === true) return;
  667. me.body.style.cursor = "url(" + me.options.cursorpath + "h.png),pointer";
  668. } else if (inTableSide(table, target, evt)) {
  669. //toggleCursor(pos,true,"_v");
  670. if (me.fireEvent("excludetable", table) === true) return;
  671. me.body.style.cursor = "url(" + me.options.cursorpath + "v.png),pointer";
  672. } else {
  673. //toggleCursor(pos,false,"");
  674. me.body.style.cursor = "text";
  675. if (/\d/.test(state)) {
  676. state = state.replace(/\d/, '');
  677. target = getUETable(target).getPreviewCell(target, state == "v");
  678. }
  679. //位于第一行的顶部或者第一列的左边时不可拖动
  680. toggleDragableState(me, target ? !!state : false, target ? state : '', pos, target);
  681. }
  682. // toggleDragButton(inTable(pos,table),table);
  683. } else {
  684. toggleDragButton(false, table, me);
  685. }
  686. } catch (e) {
  687. showError(e);
  688. }
  689. }
  690. var dragButtomTimer;
  691. function toggleDragButton(show, table, editor) {
  692. if (!show) {
  693. if (dragOver)return;
  694. dragButtomTimer = setTimeout(function () {
  695. !dragOver && dragButton && dragButton.parentNode && dragButton.parentNode.removeChild(dragButton);
  696. }, 2000);
  697. } else {
  698. createDragButton(table, editor);
  699. }
  700. }
  701. function createDragButton(table, editor) {
  702. var pos = domUtils.getXY(table),
  703. doc = table.ownerDocument;
  704. if (dragButton && dragButton.parentNode)return dragButton;
  705. dragButton = doc.createElement("div");
  706. dragButton.contentEditable = false;
  707. dragButton.innerHTML = "";
  708. dragButton.style.cssText = "width:15px;height:15px;background-image:url(" + editor.options.UEDITOR_HOME_URL + "dialogs/table/dragicon.png);position: absolute;cursor:move;top:" + (pos.y - 15) + "px;left:" + (pos.x) + "px;";
  709. domUtils.unSelectable(dragButton);
  710. dragButton.onmouseover = function (evt) {
  711. dragOver = true;
  712. };
  713. dragButton.onmouseout = function (evt) {
  714. dragOver = false;
  715. };
  716. domUtils.on(dragButton, 'click', function (type, evt) {
  717. doClick(evt, this);
  718. });
  719. domUtils.on(dragButton, 'dblclick', function (type, evt) {
  720. doDblClick(evt);
  721. });
  722. domUtils.on(dragButton, 'dragstart', function (type, evt) {
  723. domUtils.preventDefault(evt);
  724. });
  725. var timer;
  726. function doClick(evt, button) {
  727. // 部分浏览器下需要清理
  728. clearTimeout(timer);
  729. timer = setTimeout(function () {
  730. editor.fireEvent("tableClicked", table, button);
  731. }, 300);
  732. }
  733. function doDblClick(evt) {
  734. clearTimeout(timer);
  735. var ut = getUETable(table),
  736. start = table.rows[0].cells[0],
  737. end = ut.getLastCell(),
  738. range = ut.getCellsRange(start, end);
  739. editor.selection.getRange().setStart(start, 0).setCursor(false, true);
  740. ut.setSelected(range);
  741. }
  742. doc.body.appendChild(dragButton);
  743. }
  744. // function inPosition(table, pos) {
  745. // var tablePos = domUtils.getXY(table),
  746. // width = table.offsetWidth,
  747. // height = table.offsetHeight;
  748. // if (pos.x - tablePos.x < 5 && pos.y - tablePos.y < 5) {
  749. // return "topLeft";
  750. // } else if (tablePos.x + width - pos.x < 5 && tablePos.y + height - pos.y < 5) {
  751. // return "bottomRight";
  752. // }
  753. // }
  754. function inTableSide(table, cell, evt, top) {
  755. var pos = mouseCoords(evt),
  756. state = getRelation(cell, pos);
  757. if (top) {
  758. var caption = table.getElementsByTagName("caption")[0],
  759. capHeight = caption ? caption.offsetHeight : 0;
  760. return (state == "v1") && ((pos.y - domUtils.getXY(table).y - capHeight) < 8);
  761. } else {
  762. return (state == "h1") && ((pos.x - domUtils.getXY(table).x) < 8);
  763. }
  764. }
  765. /**
  766. * 获取拖动时允许的X轴坐标
  767. * @param dragTd
  768. * @param evt
  769. */
  770. function getPermissionX(dragTd, evt) {
  771. var ut = getUETable(dragTd);
  772. if (ut) {
  773. var preTd = ut.getSameEndPosCells(dragTd, "x")[0],
  774. nextTd = ut.getSameStartPosXCells(dragTd)[0],
  775. mouseX = mouseCoords(evt).x,
  776. left = (preTd ? domUtils.getXY(preTd).x : domUtils.getXY(ut.table).x) + 20 ,
  777. right = nextTd ? domUtils.getXY(nextTd).x + nextTd.offsetWidth - 20 : (me.body.offsetWidth + 5 || parseInt(domUtils.getComputedStyle(me.body, "width"), 10));
  778. return mouseX < left ? left : mouseX > right ? right : mouseX;
  779. }
  780. }
  781. /**
  782. * 获取拖动时允许的Y轴坐标
  783. * @param dragTd
  784. * @param evt
  785. */
  786. function getPermissionY(dragTd, evt) {
  787. try {
  788. var top = domUtils.getXY(dragTd).y,
  789. mousePosY = mouseCoords(evt).y;
  790. return mousePosY < top ? top : mousePosY;
  791. } catch (e) {
  792. showError(e);
  793. }
  794. }
  795. /**
  796. * 移动状态切换
  797. * @param dragable
  798. * @param dir
  799. */
  800. function toggleDragableState(editor, dragable, dir, mousePos, cell) {
  801. try {
  802. editor.body.style.cursor = dir == "h" ? "col-resize" : dir == "v" ? "row-resize" : "text";
  803. if (browser.ie) {
  804. if (dir && !mousedown && !getUETableBySelected(editor)) {
  805. getDragLine(editor, editor.document);
  806. showDragLineAt(dir, cell);
  807. } else {
  808. hideDragLine(editor)
  809. }
  810. }
  811. onBorder = dragable;
  812. } catch (e) {
  813. showError(e);
  814. }
  815. }
  816. /**
  817. * 获取鼠标与当前单元格的相对位置
  818. * @param ele
  819. * @param mousePos
  820. */
  821. function getRelation(ele, mousePos) {
  822. var elePos = domUtils.getXY(ele);
  823. if (elePos.x + ele.offsetWidth - mousePos.x < 4) {
  824. return "h";
  825. }
  826. if (mousePos.x - elePos.x < 4) {
  827. return 'h1'
  828. }
  829. if (elePos.y + ele.offsetHeight - mousePos.y < 4) {
  830. return "v";
  831. }
  832. if (mousePos.y - elePos.y < 4) {
  833. return 'v1'
  834. }
  835. return '';
  836. }
  837. function mouseDownEvent(type, evt) {
  838. //右键菜单单独处理
  839. if (evt.button == 2) {
  840. var ut = getUETableBySelected(me),
  841. flag = false;
  842. if (ut) {
  843. var td = getTargetTd(me, evt);
  844. utils.each(ut.selectedTds, function (ti) {
  845. if (ti === td) {
  846. flag = true;
  847. }
  848. });
  849. if (!flag) {
  850. removeSelectedClass(domUtils.getElementsByTagName(me.body, "td"));
  851. removeSelectedClass(domUtils.getElementsByTagName(me.body, "th"));
  852. ut.clearSelected()
  853. } else {
  854. td = ut.selectedTds[0];
  855. setTimeout(function () {
  856. me.selection.getRange().setStart(td, 0).setCursor(false, true);
  857. }, 0);
  858. }
  859. }
  860. return;
  861. }
  862. if (evt.shiftKey) {
  863. return;
  864. }
  865. removeSelectedClass(domUtils.getElementsByTagName(me.body, "td"));
  866. removeSelectedClass(domUtils.getElementsByTagName(me.body, "th"));
  867. //trace:3113
  868. //选中单元格,点击table外部,不会清掉table上挂的ueTable,会引起getUETableBySelected方法返回值
  869. utils.each(me.document.getElementsByTagName('table'), function (t) {
  870. t.ueTable = null;
  871. });
  872. startTd = getTargetTd(me, evt);
  873. if (!startTd) return;
  874. var table = domUtils.findParentByTagName(startTd, "table", true);
  875. ut = getUETable(table);
  876. ut && ut.clearSelected();
  877. //判断当前鼠标状态
  878. if (!onBorder) {
  879. me.document.body.style.webkitUserSelect = '';
  880. mousedown = true;
  881. me.addListener('mouseover', mouseOverEvent);
  882. } else {
  883. if (browser.ie && browser.version < 8) return;
  884. var state = getRelation(startTd, mouseCoords(evt));
  885. if (/\d/.test(state)) {
  886. state = state.replace(/\d/, '');
  887. startTd = getUETable(startTd).getPreviewCell(startTd, state == 'v');
  888. }
  889. hideDragLine(me);
  890. getDragLine(me, me.document);
  891. showDragLineAt(state, startTd);
  892. mousedown = true;
  893. //拖动开始
  894. onDrag = state;
  895. dragTd = startTd;
  896. }
  897. }
  898. function removeSelectedClass(cells) {
  899. utils.each(cells, function (cell) {
  900. domUtils.removeClasses(cell, "selectTdClass");
  901. })
  902. }
  903. function addSelectedClass(cells) {
  904. utils.each(cells, function (cell) {
  905. domUtils.addClass(cell, "selectTdClass");
  906. })
  907. }
  908. function getWidth(cell) {
  909. if (!cell)return 0;
  910. return parseInt(domUtils.getComputedStyle(cell, "width"), 10);
  911. }
  912. function changeColWidth(cell, changeValue) {
  913. if (Math.abs(changeValue) < 10) return;
  914. var ut = getUETable(cell);
  915. if (ut) {
  916. var table = ut.table,
  917. backTableWidth = getWidth(table),
  918. defaultValue = getDefaultValue(me, table),
  919. //这里不考虑一个都没有情况,如果一个都没有,可以认为该表格的结构可以精简
  920. leftCells = ut.getSameEndPosCells(cell, "x"),
  921. backLeftWidth = getWidth(leftCells[0]) - defaultValue.tdPadding * 2 - defaultValue.tdBorder,
  922. rightCells = ut.getSameStartPosXCells(cell),
  923. backRightWidth = getWidth(rightCells[0]) - defaultValue.tdPadding * 2 - defaultValue.tdBorder;
  924. //整列被rowspan时存在
  925. utils.each(leftCells, function (cell) {
  926. if (cell.style.width) cell.style.width = "";
  927. if (changeValue < 0)cell.style.wordBreak = "break-all";
  928. cell.setAttribute("width", backLeftWidth + changeValue);
  929. });
  930. utils.each(rightCells, function (cell) {
  931. if (cell.style.width) cell.style.width = "";
  932. if (changeValue > 0)cell.style.wordBreak = "break-all";
  933. cell.setAttribute("width", backRightWidth - changeValue);
  934. });
  935. //如果是在表格最右边拖动,则还需要调整表格宽度,否则在合并过的单元格中输入文字,表格会被撑开
  936. if (!cell.nextSibling) {
  937. if (table.style.width) table.style.width = "";
  938. table.setAttribute("width", backTableWidth + changeValue);
  939. }
  940. }
  941. }
  942. function changeRowHeight(td, changeValue) {
  943. if (Math.abs(changeValue) < 10) return;
  944. var ut = getUETable(td);
  945. if (ut) {
  946. var cells = ut.getSameEndPosCells(td, "y"),
  947. //备份需要连带变化的td的原始高度,否则后期无法获取正确的值
  948. backHeight = cells[0] ? cells[0].offsetHeight : 0;
  949. for (var i = 0, cell; cell = cells[i++];) {
  950. setCellHeight(cell, changeValue, backHeight);
  951. }
  952. }
  953. }
  954. function setCellHeight(cell, height, backHeight) {
  955. var lineHight = parseInt(domUtils.getComputedStyle(cell, "line-height"), 10),
  956. tmpHeight = backHeight + height;
  957. height = tmpHeight < lineHight ? lineHight : tmpHeight;
  958. if (cell.style.height) cell.style.height = "";
  959. cell.rowSpan == 1 ? cell.setAttribute("height", height) : (cell.removeAttribute && cell.removeAttribute("height"));
  960. }
  961. function mouseUpEvent(type, evt) {
  962. if (evt.button == 2)return;
  963. var me = this;
  964. //清除表格上原生跨选问题
  965. var range = me.selection.getRange(),
  966. start = domUtils.findParentByTagName(range.startContainer, 'table', true),
  967. end = domUtils.findParentByTagName(range.endContainer, 'table', true);
  968. if (start || end) {
  969. if (start === end) {
  970. start = domUtils.findParentByTagName(range.startContainer, ['td', 'th', 'caption'], true);
  971. end = domUtils.findParentByTagName(range.endContainer, ['td', 'th', 'caption'], true);
  972. if (start !== end) {
  973. me.selection.clearRange()
  974. }
  975. } else {
  976. me.selection.clearRange()
  977. }
  978. }
  979. mousedown = false;
  980. me.document.body.style.webkitUserSelect = '';
  981. //拖拽状态下的mouseUP
  982. if ((!browser.ie || (browser.ie && browser.version > 7)) && onDrag && dragTd) {
  983. dragLine = me.document.getElementById('ue_tableDragLine');
  984. var dragTdPos = domUtils.getXY(dragTd),
  985. dragLinePos = domUtils.getXY(dragLine);
  986. switch (onDrag) {
  987. case "h":
  988. changeColWidth(dragTd, dragLinePos.x - dragTdPos.x - dragTd.offsetWidth);
  989. break;
  990. case "v":
  991. changeRowHeight(dragTd, dragLinePos.y - dragTdPos.y - dragTd.offsetHeight);
  992. break;
  993. default:
  994. }
  995. onDrag = "";
  996. dragTd = null;
  997. hideDragLine(me);
  998. return;
  999. }
  1000. //正常状态下的mouseup
  1001. if (!startTd) {
  1002. var target = domUtils.findParentByTagName(evt.target || evt.srcElement, "td", true);
  1003. if (!target) target = domUtils.findParentByTagName(evt.target || evt.srcElement, "th", true);
  1004. if (target && (target.tagName == "TD" || target.tagName == "TH")) {
  1005. if (me.fireEvent("excludetable", target) === true) return;
  1006. range = new dom.Range(me.document);
  1007. range.setStart(target, 0).setCursor(false, true);
  1008. }
  1009. } else {
  1010. var ut = getUETable(startTd),
  1011. cell = ut ? ut.selectedTds[0] : null;
  1012. if (cell) {
  1013. range = new dom.Range(me.document);
  1014. if (domUtils.isEmptyBlock(cell)) {
  1015. range.setStart(cell, 0).setCursor(false, true);
  1016. } else {
  1017. range.selectNodeContents(cell).shrinkBoundary().setCursor(false, true);
  1018. }
  1019. } else {
  1020. range = me.selection.getRange().shrinkBoundary();
  1021. if (!range.collapsed) {
  1022. var start = domUtils.findParentByTagName(range.startContainer, ['td', 'th'], true),
  1023. end = domUtils.findParentByTagName(range.endContainer, ['td', 'th'], true);
  1024. //在table里边的不能清除
  1025. if (start && !end || !start && end || start && end && start !== end) {
  1026. range.setCursor(false, true);
  1027. }
  1028. }
  1029. }
  1030. startTd = null;
  1031. me.removeListener('mouseover', mouseOverEvent);
  1032. }
  1033. me._selectionChange(250, evt);
  1034. }
  1035. function mouseOverEvent(type, evt) {
  1036. var me = this,
  1037. tar = evt.target || evt.srcElement;
  1038. currentTd = domUtils.findParentByTagName(tar, "td", true) || domUtils.findParentByTagName(tar, "th", true);
  1039. //需要判断两个TD是否位于同一个表格内
  1040. if (startTd && currentTd &&
  1041. ((startTd.tagName == "TD" && currentTd.tagName == "TD") || (startTd.tagName == "TH" && currentTd.tagName == "TH")) &&
  1042. domUtils.findParentByTagName(startTd, 'table') == domUtils.findParentByTagName(currentTd, 'table')) {
  1043. var ut = getUETable(currentTd);
  1044. if (startTd != currentTd) {
  1045. me.document.body.style.webkitUserSelect = 'none';
  1046. me.selection.getNative()[browser.ie ? 'empty' : 'removeAllRanges']();
  1047. var range = ut.getCellsRange(startTd, currentTd);
  1048. ut.setSelected(range);
  1049. } else {
  1050. me.document.body.style.webkitUserSelect = '';
  1051. ut.clearSelected();
  1052. }
  1053. }
  1054. evt.preventDefault ? evt.preventDefault() : (evt.returnValue = false);
  1055. }
  1056. /**
  1057. * 根据当前点击的td或者table获取索引对象
  1058. * @param tdOrTable
  1059. */
  1060. function getUETable(tdOrTable) {
  1061. var tag = tdOrTable.tagName.toLowerCase();
  1062. tdOrTable = (tag == "td" || tag == "th" || tag == 'caption') ? domUtils.findParentByTagName(tdOrTable, "table", true) : tdOrTable;
  1063. if (!tdOrTable.ueTable) {
  1064. tdOrTable.ueTable = new UETable(tdOrTable);
  1065. }
  1066. return tdOrTable.ueTable;
  1067. }
  1068. /**
  1069. * 根据当前框选的td来获取ueTable对象
  1070. */
  1071. function getUETableBySelected(editor) {
  1072. var table = getTableItemsByRange(editor).table;
  1073. if (table && table.ueTable && table.ueTable.selectedTds.length) {
  1074. return table.ueTable;
  1075. }
  1076. return null;
  1077. }
  1078. function getDragLine(editor, doc) {
  1079. if (mousedown)return;
  1080. dragLine = editor.document.createElement("div");
  1081. domUtils.setAttributes(dragLine, {
  1082. id:"ue_tableDragLine",
  1083. unselectable:'on',
  1084. contenteditable:false,
  1085. 'onresizestart':'return false',
  1086. 'ondragstart':'return false',
  1087. 'onselectstart':'return false',
  1088. style:"background-color:blue;position:absolute;padding:0;margin:0;background-image:none;border:0px none;opacity:0;filter:alpha(opacity=0)"
  1089. });
  1090. // domUtils.on(dragLine,['resizestart','dragstart','selectstart'],function(evt){
  1091. // domUtils.preventDefault(evt);
  1092. // });
  1093. editor.body.appendChild(dragLine);
  1094. }
  1095. function hideDragLine(editor) {
  1096. if (mousedown)return;
  1097. var line;
  1098. while (line = editor.document.getElementById('ue_tableDragLine')) {
  1099. domUtils.remove(line)
  1100. }
  1101. }
  1102. /**
  1103. * 依据state(v|h)在cell位置显示横线
  1104. * @param state
  1105. * @param cell
  1106. */
  1107. function showDragLineAt(state, cell) {
  1108. if (!cell) return;
  1109. var table = domUtils.findParentByTagName(cell, "table"),
  1110. caption = table.getElementsByTagName('caption'),
  1111. width = table.offsetWidth,
  1112. height = table.offsetHeight - (caption.length > 0 ? caption[0].offsetHeight : 0),
  1113. tablePos = domUtils.getXY(table),
  1114. cellPos = domUtils.getXY(cell), css;
  1115. switch (state) {
  1116. case "h":
  1117. css = 'height:' + height + 'px;top:' + (tablePos.y + (caption.length > 0 ? caption[0].offsetHeight : 0)) + 'px;left:' + (cellPos.x + cell.offsetWidth - 2);
  1118. dragLine.style.cssText = css + 'px;position: absolute;display:block;background-color:blue;width:1px;border:0; color:blue;opacity:.3;filter:alpha(opacity=30)';
  1119. break;
  1120. case "v":
  1121. css = 'width:' + width + 'px;left:' + tablePos.x + 'px;top:' + (cellPos.y + cell.offsetHeight - 2 );
  1122. //必须加上border:0和color:blue,否则低版ie不支持背景色显示
  1123. dragLine.style.cssText = css + 'px;overflow:hidden;position: absolute;display:block;background-color:blue;height:1px;border:0;color:blue;opacity:.2;filter:alpha(opacity=20)';
  1124. break;
  1125. default:
  1126. }
  1127. }
  1128. /**
  1129. * 当表格边框颜色为白色时设置为虚线,true为添加虚线
  1130. * @param flag
  1131. */
  1132. function switchBoderColor(flag) {
  1133. var tableArr = domUtils.getElementsByTagName(me.body, "table"), color;
  1134. for (var i = 0, node; node = tableArr[i++];) {
  1135. var td = domUtils.getElementsByTagName(node, "td");
  1136. if (td[0]) {
  1137. if (flag) {
  1138. color = (td[0].style.borderColor).replace(/\s/g, "");
  1139. if (/(#ffffff)|(rgb\(255,f55,255\))/ig.test(color))
  1140. domUtils.addClass(node, "noBorderTable")
  1141. } else {
  1142. domUtils.removeClasses(node, "noBorderTable")
  1143. }
  1144. }
  1145. }
  1146. }
  1147. function getTableWidth(editor, needIEHack, defaultValue) {
  1148. var body = editor.body;
  1149. return body.offsetWidth - (needIEHack ? parseInt(domUtils.getComputedStyle(body, 'margin-left'), 10) * 2 : 0) - defaultValue.tableBorder * 2 - (editor.options.offsetWidth || 0);
  1150. }
  1151. UE.commands['inserttable'] = {
  1152. queryCommandState:function () {
  1153. return getTableItemsByRange(this).table ? -1 : 0;
  1154. },
  1155. execCommand:function (cmd, opt) {
  1156. function createTable(opt, tableWidth, tdWidth) {
  1157. var html = [],
  1158. rowsNum = opt.numRows,
  1159. colsNum = opt.numCols;
  1160. for (var r = 0; r < rowsNum; r++) {
  1161. html.push('<tr>');
  1162. for (var c = 0; c < colsNum; c++) {
  1163. html.push('<td width="' + tdWidth + '" vAlign="' + opt.tdvalign + '" >' + (browser.ie ? domUtils.fillChar : '<br/>') + '</td>')
  1164. }
  1165. html.push('</tr>')
  1166. }
  1167. return '<table width="' + tableWidth + '" ><tbody>' + html.join('') + '</tbody></table>'
  1168. }
  1169. if (!opt) {
  1170. opt = utils.extend({}, {
  1171. numCols:this.options.defaultCols,
  1172. numRows:this.options.defaultRows,
  1173. tdvalign:this.options.tdvalign
  1174. })
  1175. }
  1176. var range = this.selection.getRange(),
  1177. start = range.startContainer,
  1178. firstParentBlock = domUtils.findParent(start, function (node) {
  1179. return domUtils.isBlockElm(node);
  1180. }, true);
  1181. var me = this,
  1182. defaultValue = getDefaultValue(me),
  1183. tableWidth = getTableWidth(me, needIEHack, defaultValue) - (firstParentBlock ? parseInt(domUtils.getXY(firstParentBlock).x, 10) : 0),
  1184. tdWidth = Math.floor(tableWidth / opt.numCols - defaultValue.tdPadding * 2 - defaultValue.tdBorder);
  1185. //todo其他属性
  1186. !opt.tdvalign && (opt.tdvalign = me.options.tdvalign);
  1187. me.execCommand("inserthtml", createTable(opt, tableWidth, tdWidth));
  1188. }
  1189. };
  1190. UE.commands['insertparagraphbeforetable'] = {
  1191. queryCommandState:function () {
  1192. return getTableItemsByRange(this).cell ? 0 : -1;
  1193. },
  1194. execCommand:function () {
  1195. var table = getTableItemsByRange(this).table;
  1196. if (table) {
  1197. var p = this.document.createElement("p");
  1198. p.innerHTML = browser.ie ? '&nbsp;' : '<br />';
  1199. table.parentNode.insertBefore(p, table);
  1200. this.selection.getRange().setStart(p, 0).setCursor();
  1201. }
  1202. }
  1203. };
  1204. UE.commands['deletetable'] = {
  1205. queryCommandState:function () {
  1206. var rng = this.selection.getRange();
  1207. return domUtils.findParentByTagName(rng.startContainer, 'table', true) ? 0 : -1;
  1208. },
  1209. execCommand:function (cmd, table) {
  1210. var rng = this.selection.getRange();
  1211. table = table || domUtils.findParentByTagName(rng.startContainer, 'table', true);
  1212. if (table) {
  1213. var next = table.nextSibling;
  1214. if (!next) {
  1215. next = domUtils.createElement(this.document, 'p', {
  1216. 'innerHTML':browser.ie ? domUtils.fillChar : '<br/>'
  1217. });
  1218. table.parentNode.insertBefore(next, table);
  1219. }
  1220. domUtils.remove(table);
  1221. rng = this.selection.getRange();
  1222. if (next.nodeType == 3) {
  1223. rng.setStartBefore(next)
  1224. } else {
  1225. rng.setStart(next, 0)
  1226. }
  1227. rng.setCursor(false, true)
  1228. toggleDragableState(this, false, "", null);
  1229. if (dragButton)domUtils.remove(dragButton);
  1230. }
  1231. }
  1232. };
  1233. UE.commands['cellalign'] = {
  1234. queryCommandState:function () {
  1235. return getSelectedArr(this).length ? 0 : -1
  1236. },
  1237. execCommand:function (cmd, align) {
  1238. var selectedTds = getSelectedArr(this);
  1239. if (selectedTds.length) {
  1240. for (var i = 0, ci; ci = selectedTds[i++];) {
  1241. ci.setAttribute('align', align);
  1242. }
  1243. }
  1244. }
  1245. };
  1246. UE.commands['cellvalign'] = {
  1247. queryCommandState:function () {
  1248. return getSelectedArr(this).length ? 0 : -1;
  1249. },
  1250. execCommand:function (cmd, valign) {
  1251. var selectedTds = getSelectedArr(this);
  1252. if (selectedTds.length) {
  1253. for (var i = 0, ci; ci = selectedTds[i++];) {
  1254. ci.setAttribute('vAlign', valign);
  1255. }
  1256. }
  1257. }
  1258. };
  1259. UE.commands['insertcaption'] = {
  1260. queryCommandState:function () {
  1261. var table = getTableItemsByRange(this).table;
  1262. if (table) {
  1263. return table.getElementsByTagName('caption').length == 0 ? 1 : -1;
  1264. }
  1265. return -1;
  1266. },
  1267. execCommand:function () {
  1268. var table = getTableItemsByRange(this).table;
  1269. if (table) {
  1270. var caption = this.document.createElement('caption');
  1271. caption.innerHTML = browser.ie ? domUtils.fillChar : '<br/>';
  1272. table.insertBefore(caption, table.firstChild);
  1273. var range = this.selection.getRange();
  1274. range.setStart(caption, 0).setCursor();
  1275. }
  1276. }
  1277. };
  1278. UE.commands['deletecaption'] = {
  1279. queryCommandState:function () {
  1280. var rng = this.selection.getRange(),
  1281. table = domUtils.findParentByTagName(rng.startContainer, 'table');
  1282. if (table) {
  1283. return table.getElementsByTagName('caption').length == 0 ? -1 : 1;
  1284. }
  1285. return -1;
  1286. },
  1287. execCommand:function () {
  1288. var rng = this.selection.getRange(),
  1289. table = domUtils.findParentByTagName(rng.startContainer, 'table');
  1290. if (table) {
  1291. domUtils.remove(table.getElementsByTagName('caption')[0]);
  1292. var range = this.selection.getRange();
  1293. range.setStart(table.rows[0].cells[0], 0).setCursor();
  1294. }
  1295. }
  1296. };
  1297. UE.commands['inserttitle'] = {
  1298. queryCommandState:function () {
  1299. var table = getTableItemsByRange(this).table;
  1300. if (table) {
  1301. var firstRow = table.rows[0];
  1302. return firstRow.getElementsByTagName('th').length == 0 ? 0 : -1
  1303. }
  1304. return -1;
  1305. },
  1306. execCommand:function () {
  1307. var table = getTableItemsByRange(this).table;
  1308. if (table) {
  1309. getUETable(table).insertRow(0, 'th');
  1310. }
  1311. var th = table.getElementsByTagName('th')[0];
  1312. this.selection.getRange().setStart(th, 0).setCursor(false, true);
  1313. }
  1314. };
  1315. UE.commands['deletetitle'] = {
  1316. queryCommandState:function () {
  1317. var table = getTableItemsByRange(this).table;
  1318. if (table) {
  1319. var firstRow = table.rows[0];
  1320. return firstRow.getElementsByTagName('th').length ? 0 : -1
  1321. }
  1322. return -1;
  1323. },
  1324. execCommand:function () {
  1325. var table = getTableItemsByRange(this).table;
  1326. if (table) {
  1327. domUtils.remove(table.rows[0])
  1328. }
  1329. var td = table.getElementsByTagName('td')[0];
  1330. this.selection.getRange().setStart(td, 0).setCursor(false, true);
  1331. }
  1332. };
  1333. UE.commands["mergeright"] = {
  1334. queryCommandState:function (cmd) {
  1335. var tableItems = getTableItemsByRange(this);
  1336. if (!tableItems.cell) return -1;
  1337. var ut = getUETable(tableItems.table);
  1338. if (ut.selectedTds.length) return -1;
  1339. var cellInfo = ut.getCellInfo(tableItems.cell),
  1340. rightColIndex = cellInfo.colIndex + cellInfo.colSpan;
  1341. if (rightColIndex >= ut.colsNum) return -1;
  1342. var rightCellInfo = ut.indexTable[cellInfo.rowIndex][rightColIndex];
  1343. return (rightCellInfo.rowIndex == cellInfo.rowIndex
  1344. && rightCellInfo.rowSpan == cellInfo.rowSpan) ? 0 : -1;
  1345. },
  1346. execCommand:function (cmd) {
  1347. var rng = this.selection.getRange(),
  1348. bk = rng.createBookmark(true);
  1349. var cell = getTableItemsByRange(this).cell,
  1350. ut = getUETable(cell);
  1351. ut.mergeRight(cell);
  1352. rng.moveToBookmark(bk).select();
  1353. }
  1354. };
  1355. UE.commands["mergedown"] = {
  1356. queryCommandState:function (cmd) {
  1357. var tableItems = getTableItemsByRange(this),
  1358. cell = tableItems.cell;
  1359. if (!cell || cell.tagName == "TH") return -1;
  1360. var ut = getUETable(tableItems.table);
  1361. if (ut.selectedTds.length)return -1;
  1362. var cellInfo = ut.getCellInfo(tableItems.cell),
  1363. downRowIndex = cellInfo.rowIndex + cellInfo.rowSpan;
  1364. // 如果处于最下边则不能f向右合并
  1365. if (downRowIndex >= ut.rowsNum) return -1;
  1366. var downCellInfo = ut.indexTable[downRowIndex][cellInfo.colIndex];
  1367. // 当且仅当两个Cell的开始列号和结束列号一致时能进行合并
  1368. return (downCellInfo.colIndex == cellInfo.colIndex
  1369. && downCellInfo.colSpan == cellInfo.colSpan) && tableItems.cell.tagName !== 'TH' ? 0 : -1;
  1370. },
  1371. execCommand:function () {
  1372. var rng = this.selection.getRange(),
  1373. bk = rng.createBookmark(true);
  1374. var cell = getTableItemsByRange(this).cell,
  1375. ut = getUETable(cell);
  1376. ut.mergeDown(cell);
  1377. rng.moveToBookmark(bk).select();
  1378. }
  1379. };
  1380. UE.commands["mergecells"] = {
  1381. queryCommandState:function () {
  1382. return getUETableBySelected(this) ? 0 : -1;
  1383. },
  1384. execCommand:function () {
  1385. var ut = getUETableBySelected(this);
  1386. if (ut && ut.selectedTds.length) {
  1387. var cell = ut.selectedTds[0];
  1388. getUETableBySelected(this).mergeRange();
  1389. var rng = this.selection.getRange();
  1390. if (domUtils.isEmptyBlock(cell)) {
  1391. rng.setStart(cell, 0).collapse(true)
  1392. } else {
  1393. rng.selectNodeContents(cell)
  1394. }
  1395. rng.select();
  1396. }
  1397. }
  1398. };
  1399. UE.commands["insertrow"] = {
  1400. queryCommandState:function () {
  1401. var tableItems = getTableItemsByRange(this),
  1402. cell = tableItems.cell;
  1403. return cell && cell.tagName == "TD" && getUETable(tableItems.table).rowsNum < this.options.maxRowNum ? 0 : -1;
  1404. },
  1405. execCommand:function () {
  1406. var rng = this.selection.getRange(),
  1407. bk = rng.createBookmark(true);
  1408. var cell = getTableItemsByRange(this).cell,
  1409. ut = getUETable(cell),
  1410. cellInfo = ut.getCellInfo(cell);
  1411. //ut.insertRow(!ut.selectedTds.length ? cellInfo.rowIndex:ut.cellsRange.beginRowIndex,'');
  1412. if (!ut.selectedTds.length) {
  1413. ut.insertRow(cellInfo.rowIndex, cell,true);
  1414. } else {
  1415. var range = ut.cellsRange;
  1416. for (var i = 0, len = range.endRowIndex - range.beginRowIndex + 1; i < len; i++) {
  1417. ut.insertRow(range.beginRowIndex, cell,true);
  1418. }
  1419. }
  1420. rng.moveToBookmark(bk).select();
  1421. }
  1422. };
  1423. //后插入行
  1424. UE.commands["insertrownext"] = {
  1425. queryCommandState:function () {
  1426. var tableItems = getTableItemsByRange(this),
  1427. cell = tableItems.cell;
  1428. return cell && (cell.tagName == "TD") && getUETable(tableItems.table).rowsNum < this.options.maxRowNum ? 0 : -1;
  1429. },
  1430. execCommand:function () {
  1431. var rng = this.selection.getRange(),
  1432. bk = rng.createBookmark(true);
  1433. var cell = getTableItemsByRange(this).cell,
  1434. ut = getUETable(cell),
  1435. cellInfo = ut.getCellInfo(cell);
  1436. //ut.insertRow(!ut.selectedTds.length? cellInfo.rowIndex + cellInfo.rowSpan : ut.cellsRange.endRowIndex + 1,'');
  1437. if (!ut.selectedTds.length) {
  1438. ut.insertRow(cellInfo.rowIndex + cellInfo.rowSpan, cell,false);
  1439. } else {
  1440. var range = ut.cellsRange;
  1441. for (var i = 0, len = range.endRowIndex - range.beginRowIndex + 1; i < len; i++) {
  1442. ut.insertRow(range.endRowIndex + 1, cell,false);
  1443. }
  1444. }
  1445. rng.moveToBookmark(bk).select();
  1446. }
  1447. };
  1448. UE.commands["deleterow"] = {
  1449. queryCommandState:function () {
  1450. var tableItems = getTableItemsByRange(this);
  1451. if (!tableItems.cell) {
  1452. return -1;
  1453. }
  1454. },
  1455. execCommand:function () {
  1456. var cell = getTableItemsByRange(this).cell,
  1457. ut = getUETable(cell),
  1458. cellsRange = ut.cellsRange,
  1459. cellInfo = ut.getCellInfo(cell),
  1460. preCell = ut.getVSideCell(cell),
  1461. nextCell = ut.getVSideCell(cell, true),
  1462. rng = this.selection.getRange();
  1463. if (utils.isEmptyObject(cellsRange)) {
  1464. ut.deleteRow(cellInfo.rowIndex);
  1465. } else {
  1466. for (var i = cellsRange.beginRowIndex; i < cellsRange.endRowIndex + 1; i++) {
  1467. ut.deleteRow(cellsRange.beginRowIndex);
  1468. }
  1469. }
  1470. var table = ut.table;
  1471. if (!table.getElementsByTagName('td').length) {
  1472. var nextSibling = table.nextSibling;
  1473. domUtils.remove(table);
  1474. if (nextSibling) {
  1475. rng.setStart(nextSibling, 0).setCursor(false, true);
  1476. }
  1477. } else {
  1478. if (cellInfo.rowSpan == 1 || cellInfo.rowSpan == cellsRange.endRowIndex - cellsRange.beginRowIndex + 1) {
  1479. if (nextCell || preCell) rng.selectNodeContents(nextCell || preCell).setCursor(false, true);
  1480. } else {
  1481. var newCell = ut.getCell(cellInfo.rowIndex, ut.indexTable[cellInfo.rowIndex][cellInfo.colIndex].cellIndex);
  1482. if (newCell) rng.selectNodeContents(newCell).setCursor(false, true);
  1483. }
  1484. }
  1485. }
  1486. };
  1487. UE.commands["insertcol"] = {
  1488. queryCommandState:function (cmd) {
  1489. var tableItems = getTableItemsByRange(this),
  1490. cell = tableItems.cell;
  1491. return cell && (cell.tagName == "TD" || cell.tagName == 'TH') && getUETable(tableItems.table).colsNum < this.options.maxColNum ? 0 : -1;
  1492. },
  1493. execCommand:function (cmd) {
  1494. var rng = this.selection.getRange(),
  1495. bk = rng.createBookmark(true);
  1496. if (this.queryCommandState(cmd) == -1)return;
  1497. var cell = getTableItemsByRange(this).cell,
  1498. ut = getUETable(cell),
  1499. cellInfo = ut.getCellInfo(cell);
  1500. //ut.insertCol(!ut.selectedTds.length ? cellInfo.colIndex:ut.cellsRange.beginColIndex);
  1501. if (!ut.selectedTds.length) {
  1502. ut.insertCol(cellInfo.colIndex, cell);
  1503. } else {
  1504. var range = ut.cellsRange;
  1505. for (var i = 0, len = range.endColIndex - range.beginColIndex + 1; i < len; i++) {
  1506. ut.insertCol(range.beginColIndex, cell);
  1507. }
  1508. }
  1509. rng.moveToBookmark(bk).select(true);
  1510. }
  1511. };
  1512. UE.commands["insertcolnext"] = {
  1513. queryCommandState:function () {
  1514. var tableItems = getTableItemsByRange(this),
  1515. cell = tableItems.cell;
  1516. return cell && getUETable(tableItems.table).colsNum < this.options.maxColNum ? 0 : -1;
  1517. },
  1518. execCommand:function () {
  1519. var rng = this.selection.getRange(),
  1520. bk = rng.createBookmark(true);
  1521. var cell = getTableItemsByRange(this).cell,
  1522. ut = getUETable(cell),
  1523. cellInfo = ut.getCellInfo(cell);
  1524. if (!ut.selectedTds.length) {
  1525. ut.insertCol(cellInfo.colIndex + cellInfo.colSpan, cell);
  1526. } else {
  1527. var range = ut.cellsRange;
  1528. for (var i = 0, len = range.endColIndex - range.beginColIndex + 1; i < len; i++) {
  1529. ut.insertCol(range.endColIndex + 1, cell);
  1530. }
  1531. }
  1532. rng.moveToBookmark(bk).select();
  1533. }
  1534. };
  1535. UE.commands["deletecol"] = {
  1536. queryCommandState:function () {
  1537. var tableItems = getTableItemsByRange(this);
  1538. if (!tableItems.cell) return -1;
  1539. },
  1540. execCommand:function () {
  1541. var cell = getTableItemsByRange(this).cell,
  1542. ut = getUETable(cell),
  1543. range = ut.cellsRange,
  1544. cellInfo = ut.getCellInfo(cell),
  1545. preCell = ut.getHSideCell(cell),
  1546. nextCell = ut.getHSideCell(cell, true);
  1547. if (utils.isEmptyObject(range)) {
  1548. ut.deleteCol(cellInfo.colIndex);
  1549. } else {
  1550. for (var i = range.beginColIndex; i < range.endColIndex + 1; i++) {
  1551. ut.deleteCol(range.beginColIndex);
  1552. }
  1553. }
  1554. var table = ut.table,
  1555. rng = this.selection.getRange();
  1556. if (!table.getElementsByTagName('td').length) {
  1557. var nextSibling = table.nextSibling;
  1558. domUtils.remove(table);
  1559. if (nextSibling) {
  1560. rng.setStart(nextSibling, 0).setCursor(false, true);
  1561. }
  1562. } else {
  1563. if (domUtils.inDoc(cell, this.document)) {
  1564. rng.setStart(cell, 0).setCursor(false, true);
  1565. } else {
  1566. if (nextCell && domUtils.inDoc(nextCell, this.document)) {
  1567. rng.selectNodeContents(nextCell).setCursor(false, true);
  1568. } else {
  1569. if (preCell && domUtils.inDoc(preCell, this.document)) {
  1570. rng.selectNodeContents(preCell).setCursor(true, true);
  1571. }
  1572. }
  1573. }
  1574. }
  1575. }
  1576. };
  1577. UE.commands["splittocells"] = {
  1578. queryCommandState:function () {
  1579. var tableItems = getTableItemsByRange(this),
  1580. cell = tableItems.cell;
  1581. if (!cell) return -1;
  1582. var ut = getUETable(tableItems.table);
  1583. if (ut.selectedTds.length > 0) return -1;
  1584. return cell && (cell.colSpan > 1 || cell.rowSpan > 1) ? 0 : -1;
  1585. },
  1586. execCommand:function () {
  1587. var rng = this.selection.getRange(),
  1588. bk = rng.createBookmark(true);
  1589. var cell = getTableItemsByRange(this).cell,
  1590. ut = getUETable(cell);
  1591. ut.splitToCells(cell);
  1592. rng.moveToBookmark(bk).select();
  1593. }
  1594. };
  1595. UE.commands["splittorows"] = {
  1596. queryCommandState:function () {
  1597. var tableItems = getTableItemsByRange(this),
  1598. cell = tableItems.cell;
  1599. if (!cell) return -1;
  1600. var ut = getUETable(tableItems.table);
  1601. if (ut.selectedTds.length > 0) return -1;
  1602. return cell && cell.rowSpan > 1 ? 0 : -1;
  1603. },
  1604. execCommand:function () {
  1605. var rng = this.selection.getRange(),
  1606. bk = rng.createBookmark(true);
  1607. var cell = getTableItemsByRange(this).cell,
  1608. ut = getUETable(cell);
  1609. ut.splitToRows(cell);
  1610. rng.moveToBookmark(bk).select();
  1611. }
  1612. };
  1613. UE.commands["splittocols"] = {
  1614. queryCommandState:function () {
  1615. var tableItems = getTableItemsByRange(this),
  1616. cell = tableItems.cell;
  1617. if (!cell) return -1;
  1618. var ut = getUETable(tableItems.table);
  1619. if (ut.selectedTds.length > 0) return -1;
  1620. return cell && cell.colSpan > 1 ? 0 : -1;
  1621. },
  1622. execCommand:function () {
  1623. var rng = this.selection.getRange(),
  1624. bk = rng.createBookmark(true);
  1625. var cell = getTableItemsByRange(this).cell,
  1626. ut = getUETable(cell);
  1627. ut.splitToCols(cell);
  1628. rng.moveToBookmark(bk).select();
  1629. }
  1630. };
  1631. function getDefaultValue(editor, table) {
  1632. var borderMap = {
  1633. thin:'0px',
  1634. medium:'1px',
  1635. thick:'2px'
  1636. },
  1637. tableBorder, tdPadding, tdBorder, tmpValue;
  1638. if (!table) {
  1639. table = editor.document.createElement('table');
  1640. table.insertRow(0).insertCell(0).innerHTML = 'xxx';
  1641. editor.body.appendChild(table);
  1642. var td = table.getElementsByTagName('td')[0];
  1643. tmpValue = domUtils.getComputedStyle(table, 'border-left-width');
  1644. tableBorder = parseInt(borderMap[tmpValue] || tmpValue, 10);
  1645. tmpValue = domUtils.getComputedStyle(td, 'padding-left');
  1646. tdPadding = parseInt(borderMap[tmpValue] || tmpValue, 10);
  1647. tmpValue = domUtils.getComputedStyle(td, 'border-left-width');
  1648. tdBorder = parseInt(borderMap[tmpValue] || tmpValue, 10);
  1649. domUtils.remove(table);
  1650. return {
  1651. tableBorder:tableBorder,
  1652. tdPadding:tdPadding,
  1653. tdBorder:tdBorder
  1654. };
  1655. } else {
  1656. td = table.getElementsByTagName('td')[0];
  1657. tmpValue = domUtils.getComputedStyle(table, 'border-left-width');
  1658. tableBorder = parseInt(borderMap[tmpValue] || tmpValue, 10);
  1659. tmpValue = domUtils.getComputedStyle(td, 'padding-left');
  1660. tdPadding = parseInt(borderMap[tmpValue] || tmpValue, 10);
  1661. tmpValue = domUtils.getComputedStyle(td, 'border-left-width');
  1662. tdBorder = parseInt(borderMap[tmpValue] || tmpValue, 10);
  1663. return {
  1664. tableBorder:tableBorder,
  1665. tdPadding:tdPadding,
  1666. tdBorder:tdBorder
  1667. };
  1668. }
  1669. }
  1670. UE.commands["adaptbytext"] =
  1671. UE.commands["adaptbywindow"] = {
  1672. queryCommandState:function () {
  1673. return getTableItemsByRange(this).table ? 0 : -1
  1674. },
  1675. execCommand:function (cmd) {
  1676. var tableItems = getTableItemsByRange(this),
  1677. table = tableItems.table;
  1678. if (table) {
  1679. var tds = table.getElementsByTagName("td");
  1680. utils.each(tds, function (td) {
  1681. td.removeAttribute("width");
  1682. });
  1683. if (cmd == 'adaptbywindow') {
  1684. table.setAttribute('width', getTableWidth(this, needIEHack, getDefaultValue(this, table)));
  1685. utils.each(tds, function (td) {
  1686. td.setAttribute("width", td.offsetWidth + "");
  1687. });
  1688. } else {
  1689. table.style.width = "";
  1690. table.removeAttribute("width");
  1691. var defaultValue = getDefaultValue(me, table);
  1692. var width = table.offsetWidth,
  1693. bodyWidth = me.body.offsetWidth;
  1694. if (width > bodyWidth) {
  1695. table.setAttribute('width', getTableWidth(me, needIEHack, defaultValue));
  1696. }
  1697. }
  1698. }
  1699. }
  1700. };
  1701. //平均分配各列
  1702. UE.commands['averagedistributecol'] = {
  1703. queryCommandState:function () {
  1704. var ut = getUETableBySelected(this);
  1705. if (!ut) return -1;
  1706. return ut.isFullRow() || ut.isFullCol() ? 0 : -1;
  1707. },
  1708. execCommand:function (cmd) {
  1709. var me = this,
  1710. ut = getUETableBySelected(me);
  1711. function getAverageWidth() {
  1712. var tb = ut.table,
  1713. averageWidth, sumWidth = 0, colsNum = 0,
  1714. tbAttr = getDefaultValue(me, tb);
  1715. if (ut.isFullRow()) {
  1716. sumWidth = tb.offsetWidth;
  1717. colsNum = ut.colsNum;
  1718. } else {
  1719. var begin = ut.cellsRange.beginColIndex,
  1720. end = ut.cellsRange.endColIndex,
  1721. node;
  1722. for (var i = begin; i <= end;) {
  1723. node = ut.selectedTds[i];
  1724. sumWidth += node.offsetWidth;
  1725. i += node.colSpan;
  1726. colsNum += 1;
  1727. }
  1728. }
  1729. averageWidth = Math.ceil(sumWidth / colsNum) - tbAttr.tdBorder * 2 - tbAttr.tdPadding * 2;
  1730. return averageWidth;
  1731. }
  1732. function setAverageWidth(averageWidth) {
  1733. utils.each(domUtils.getElementsByTagName(ut.table, "th"), function (node) {
  1734. node.setAttribute("width", "");
  1735. });
  1736. var cells = ut.isFullRow() ? domUtils.getElementsByTagName(ut.table, "td") : ut.selectedTds;
  1737. utils.each(cells, function (node) {
  1738. if (node.colSpan == 1) {
  1739. node.setAttribute("width", averageWidth);
  1740. }
  1741. });
  1742. }
  1743. if (ut && ut.selectedTds.length) {
  1744. setAverageWidth(getAverageWidth());
  1745. }
  1746. }
  1747. };
  1748. //平均分配各行
  1749. UE.commands['averagedistributerow'] = {
  1750. queryCommandState:function () {
  1751. var ut = getUETableBySelected(this);
  1752. if (!ut) return -1;
  1753. if (ut.selectedTds && /th/ig.test(ut.selectedTds[0].tagName)) return -1;
  1754. return ut.isFullRow() || ut.isFullCol() ? 0 : -1;
  1755. },
  1756. execCommand:function (cmd) {
  1757. var me = this,
  1758. ut = getUETableBySelected(me);
  1759. function getAverageHeight() {
  1760. var averageHeight, rowNum, sumHeight = 0,
  1761. tb = ut.table,
  1762. tbAttr = getDefaultValue(me, tb),
  1763. tdpadding = parseInt(domUtils.getComputedStyle(tb.getElementsByTagName('td')[0], "padding-top"));
  1764. if (ut.isFullCol()) {
  1765. var captionArr = domUtils.getElementsByTagName(tb, "caption"),
  1766. thArr = domUtils.getElementsByTagName(tb, "th"),
  1767. captionHeight, thHeight;
  1768. if (captionArr.length > 0) {
  1769. captionHeight = captionArr[0].offsetHeight;
  1770. }
  1771. if (thArr.length > 0) {
  1772. thHeight = thArr[0].offsetHeight;
  1773. }
  1774. sumHeight = tb.offsetHeight - (captionHeight || 0) - (thHeight || 0);
  1775. rowNum = thArr.length == 0 ? ut.rowsNum : (ut.rowsNum - 1);
  1776. } else {
  1777. var begin = ut.cellsRange.beginRowIndex,
  1778. end = ut.cellsRange.endRowIndex,
  1779. count = 0,
  1780. trs = domUtils.getElementsByTagName(tb, "tr");
  1781. for (var i = begin; i <= end; i++) {
  1782. sumHeight += trs[i].offsetHeight;
  1783. count += 1;
  1784. }
  1785. rowNum = count;
  1786. }
  1787. //ie8下是混杂模式
  1788. if (browser.ie && browser.version < 9) {
  1789. averageHeight = Math.ceil(sumHeight / rowNum);
  1790. } else {
  1791. averageHeight = Math.ceil(sumHeight / rowNum) - tbAttr.tdBorder * 2 - tdpadding * 2;
  1792. }
  1793. return averageHeight;
  1794. }
  1795. function setAverageHeight(averageHeight) {
  1796. var cells = ut.isFullCol() ? domUtils.getElementsByTagName(ut.table, "td") : ut.selectedTds;
  1797. utils.each(cells, function (node) {
  1798. if (node.rowSpan == 1) {
  1799. node.setAttribute("height", averageHeight);
  1800. }
  1801. });
  1802. }
  1803. if (ut && ut.selectedTds.length) {
  1804. setAverageHeight(getAverageHeight());
  1805. }
  1806. }
  1807. };
  1808. //单元格对齐方式
  1809. UE.commands['cellalignment'] = {
  1810. queryCommandState:function () {
  1811. return getTableItemsByRange(this).table ? 0 : -1
  1812. },
  1813. execCommand:function (cmd, data) {
  1814. var me = this,
  1815. ut = getUETableBySelected(me);
  1816. if (!ut) {
  1817. var start = me.selection.getStart(),
  1818. cell = start && domUtils.findParentByTagName(start, ["td", "th", "caption"], true);
  1819. if (!/caption/ig.test(cell.tagName)) {
  1820. domUtils.setAttributes(cell, data);
  1821. } else {
  1822. cell.style.textAlign = data.align;
  1823. cell.style.verticalAlign = data.vAlign;
  1824. }
  1825. me.selection.getRange().setCursor(true);
  1826. } else {
  1827. utils.each(ut.selectedTds, function (cell) {
  1828. domUtils.setAttributes(cell, data);
  1829. });
  1830. }
  1831. }
  1832. };
  1833. //表格对齐方式
  1834. UE.commands['tablealignment'] = {
  1835. queryCommandState:function () {
  1836. return getTableItemsByRange(this).table ? 0 : -1
  1837. },
  1838. execCommand:function (cmd, data) {
  1839. var me = this,
  1840. start = me.selection.getStart(),
  1841. table = start && domUtils.findParentByTagName(start, ["table"], true);
  1842. if (table) {
  1843. var obj = {};
  1844. obj[data[0]] = data[1];
  1845. table.style[utils.cssStyleToDomStyle("float")] = "";
  1846. table.style.margin = "";
  1847. domUtils.setStyles(table, obj);
  1848. }
  1849. }
  1850. };
  1851. //表格属性
  1852. UE.commands['edittable'] = {
  1853. queryCommandState:function () {
  1854. return getTableItemsByRange(this).table ? 0 : -1
  1855. },
  1856. execCommand:function (cmd, color) {
  1857. var rng = this.selection.getRange(),
  1858. table = domUtils.findParentByTagName(rng.startContainer, 'table');
  1859. if (table) {
  1860. var arr = domUtils.getElementsByTagName(table, "td").concat(
  1861. domUtils.getElementsByTagName(table, "th"),
  1862. domUtils.getElementsByTagName(table, "caption")
  1863. );
  1864. utils.each(arr, function (node) {
  1865. node.style.borderColor = color;
  1866. });
  1867. }
  1868. }
  1869. };
  1870. //单元格属性
  1871. UE.commands['edittd'] = {
  1872. queryCommandState:function () {
  1873. return getTableItemsByRange(this).table ? 0 : -1
  1874. },
  1875. execCommand:function (cmd, bkColor,boColor) {
  1876. var me = this,
  1877. ut = getUETableBySelected(me);
  1878. if (!ut) {
  1879. var start = me.selection.getStart(),
  1880. cell = start && domUtils.findParentByTagName(start, ["td", "th", "caption"], true);
  1881. if (cell) {
  1882. cell.style.backgroundColor = bkColor;
  1883. cell.style.borderColor = boColor;
  1884. cell.style.borderWidth = '2px';
  1885. }
  1886. } else {
  1887. utils.each(ut.selectedTds, function (cell) {
  1888. cell.style.backgroundColor = bkColor;
  1889. cell.style.borderColor = boColor;
  1890. cell.style.borderWidth = '2px';
  1891. });
  1892. }
  1893. }
  1894. };
  1895. /**
  1896. *应用单元格样式(在选择一个单元格以后,点击样式刷按钮后,再点击其他的单元格会触发,而且只触发一次)
  1897. */
  1898. me.commands['applytableformat']={
  1899. execCommand : function(t) {
  1900. if(!editor.tableFormatState)return;
  1901. var ut = getUETableBySelected(this);
  1902. if (ut && ut.selectedTds.length) {
  1903. if(ut.table.className!=editor.tableFormatState){
  1904. ut.table.className=editor.tableFormatState;
  1905. ut.table.style=undefined;
  1906. }
  1907. utils.each(ut.selectedTds, function (td) {
  1908. if(td.className!=editor.cellFormatState){
  1909. td.className=editor.cellFormatState;
  1910. }
  1911. });
  1912. editor.tableFormatState=null;
  1913. editor.cellFormatState=null;
  1914. }
  1915. else{
  1916. var range = this.selection.getRange(),
  1917. start = range.startContainer,
  1918. td = domUtils.findParentByTagName(start, ['td','th'], true),
  1919. table = domUtils.findParentByTagName(td, 'table');
  1920. if(td.className==editor.cellFormatState){
  1921. return;
  1922. }else{
  1923. if(table.className!=editor.tableFormatState){
  1924. table.className=editor.tableFormatState;
  1925. table.style=undefined;
  1926. }
  1927. td.className=editor.cellFormatState;
  1928. editor.tableFormatState=null;
  1929. editor.cellFormatState=null;
  1930. }
  1931. }
  1932. }
  1933. };
  1934. /**
  1935. * 单元格格式刷
  1936. */
  1937. me.commands['tableformat']={
  1938. queryCommandState : function() {
  1939. return getTableItemsByRange(this).table ? 0 : -1;
  1940. },
  1941. execCommand : function() {
  1942. var ut = getUETableBySelected(this),
  1943. cell = null;
  1944. if (!ut) {
  1945. var start = me.selection.getStart(),
  1946. cell = start && domUtils.findParentByTagName(start, ["td", "th", "caption"], true),
  1947. ut = domUtils.findParentByTagName(cell, 'table');
  1948. } else {
  1949. cell = ut.selectedTds[0];
  1950. }
  1951. if(cell&&cell.className){
  1952. editor.tableFormatState=ut.className;
  1953. editor.cellFormatState=cell.className;
  1954. }
  1955. }
  1956. };
  1957. /**
  1958. * 清空单元格
  1959. */
  1960. me.commands['clearcell'] = {
  1961. queryCommandState : function() {
  1962. var ut = getTableItemsByRange(this);
  1963. if(!ut)return -1;
  1964. if(!ut.cell)return -1;
  1965. editor.$curCell = ut.cell;
  1966. return 0;
  1967. },
  1968. execCommand : function() {
  1969. if(editor.$curCell){
  1970. editor.$curCell.innerHTML = '';
  1971. editor.$curCell = null;
  1972. }
  1973. }
  1974. };
  1975. /**
  1976. * UE表格操作类
  1977. * @param table
  1978. * @constructor
  1979. */
  1980. function UETable(table) {
  1981. this.table = table;
  1982. this.indexTable = [];
  1983. this.selectedTds = [];
  1984. this.cellsRange = {};
  1985. this.update(table);
  1986. }
  1987. UETable.prototype = {
  1988. getMaxRows:function () {
  1989. var rows = this.table.rows, maxLen = 1;
  1990. for (var i = 0, row; row = rows[i]; i++) {
  1991. var currentMax = 1;
  1992. for (var j = 0, cj; cj = row.cells[j++];) {
  1993. currentMax = Math.max(cj.rowSpan || 1, currentMax);
  1994. }
  1995. maxLen = Math.max(currentMax + i, maxLen);
  1996. }
  1997. return maxLen;
  1998. },
  1999. /**
  2000. * 获取当前表格的最大列数
  2001. */
  2002. getMaxCols:function () {
  2003. var rows = this.table.rows, maxLen = 0, cellRows = {};
  2004. for (var i = 0, row; row = rows[i]; i++) {
  2005. var cellsNum = 0;
  2006. for (var j = 0, cj; cj = row.cells[j++];) {
  2007. cellsNum += (cj.colSpan || 1);
  2008. if (cj.rowSpan && cj.rowSpan > 1) {
  2009. for (var k = 1; k < cj.rowSpan; k++) {
  2010. if (!cellRows['row_' + (i + k)]) {
  2011. cellRows['row_' + (i + k)] = (cj.colSpan || 1);
  2012. } else {
  2013. cellRows['row_' + (i + k)]++
  2014. }
  2015. }
  2016. }
  2017. }
  2018. cellsNum += cellRows['row_' + i] || 0;
  2019. maxLen = Math.max(cellsNum, maxLen);
  2020. }
  2021. return maxLen;
  2022. },
  2023. getCellColIndex:function (cell) {
  2024. },
  2025. /**
  2026. * 获取当前cell旁边的单元格,
  2027. * @param cell
  2028. * @param right
  2029. */
  2030. getHSideCell:function (cell, right) {
  2031. try {
  2032. var cellInfo = this.getCellInfo(cell),
  2033. previewRowIndex, previewColIndex;
  2034. var len = this.selectedTds.length,
  2035. range = this.cellsRange;
  2036. //首行或者首列没有前置单元格
  2037. if ((!right && (!len ? !cellInfo.colIndex : !range.beginColIndex)) || (right && (!len ? (cellInfo.colIndex == (this.colsNum - 1)) : (range.endColIndex == this.colsNum - 1)))) return null;
  2038. previewRowIndex = !len ? cellInfo.rowIndex : range.beginRowIndex;
  2039. previewColIndex = !right ? ( !len ? (cellInfo.colIndex < 1 ? 0 : (cellInfo.colIndex - 1)) : range.beginColIndex - 1)
  2040. : ( !len ? cellInfo.colIndex + 1 : range.endColIndex + 1);
  2041. return this.getCell(this.indexTable[previewRowIndex][previewColIndex].rowIndex, this.indexTable[previewRowIndex][previewColIndex].cellIndex);
  2042. } catch (e) {
  2043. showError(e);
  2044. }
  2045. },
  2046. getTabNextCell:function (cell, preRowIndex) {
  2047. var cellInfo = this.getCellInfo(cell),
  2048. rowIndex = preRowIndex || cellInfo.rowIndex,
  2049. colIndex = cellInfo.colIndex + 1 + (cellInfo.colSpan - 1),
  2050. nextCell;
  2051. try {
  2052. nextCell = this.getCell(this.indexTable[rowIndex][colIndex].rowIndex, this.indexTable[rowIndex][colIndex].cellIndex);
  2053. } catch (e) {
  2054. try {
  2055. rowIndex = rowIndex * 1 + 1;
  2056. colIndex = 0;
  2057. nextCell = this.getCell(this.indexTable[rowIndex][colIndex].rowIndex, this.indexTable[rowIndex][colIndex].cellIndex);
  2058. } catch (e) {
  2059. }
  2060. }
  2061. return nextCell;
  2062. },
  2063. /**
  2064. * 获取视觉上的后置单元格
  2065. * @param cell
  2066. * @param bottom
  2067. */
  2068. getVSideCell:function (cell, bottom, ignoreRange) {
  2069. try {
  2070. var cellInfo = this.getCellInfo(cell),
  2071. nextRowIndex, nextColIndex;
  2072. var len = this.selectedTds.length && !ignoreRange,
  2073. range = this.cellsRange;
  2074. //末行或者末列没有后置单元格
  2075. if ((!bottom && (cellInfo.rowIndex == 0)) || (bottom && (!len ? (cellInfo.rowIndex + cellInfo.rowSpan > this.rowsNum - 1) : (range.endRowIndex == this.rowsNum - 1)))) return null;
  2076. nextRowIndex = !bottom ? ( !len ? cellInfo.rowIndex - 1 : range.beginRowIndex - 1)
  2077. : ( !len ? (cellInfo.rowIndex + cellInfo.rowSpan) : range.endRowIndex + 1);
  2078. nextColIndex = !len ? cellInfo.colIndex : range.beginColIndex;
  2079. return this.getCell(this.indexTable[nextRowIndex][nextColIndex].rowIndex, this.indexTable[nextRowIndex][nextColIndex].cellIndex);
  2080. } catch (e) {
  2081. showError(e);
  2082. }
  2083. },
  2084. /**
  2085. * 获取相同结束位置的单元格,xOrY指代了是获取x轴相同还是y轴相同
  2086. */
  2087. getSameEndPosCells:function (cell, xOrY) {
  2088. try {
  2089. var flag = (xOrY.toLowerCase() === "x"),
  2090. end = domUtils.getXY(cell)[flag ? 'x' : 'y'] + cell["offset" + (flag ? 'Width' : 'Height')],
  2091. rows = this.table.rows,
  2092. cells = null, returns = [];
  2093. for (var i = 0; i < this.rowsNum; i++) {
  2094. cells = rows[i].cells;
  2095. for (var j = 0, tmpCell; tmpCell = cells[j++];) {
  2096. var tmpEnd = domUtils.getXY(tmpCell)[flag ? 'x' : 'y'] + tmpCell["offset" + (flag ? 'Width' : 'Height')];
  2097. //对应行的td已经被上面行rowSpan了
  2098. if (tmpEnd > end && flag) break;
  2099. if (cell == tmpCell || end == tmpEnd) {
  2100. //只获取单一的单元格
  2101. //todo 仅获取单一单元格在特定情况下会造成returns为空,从而影响后续的拖拽实现,修正这个。需考虑性能
  2102. if (tmpCell[flag ? "colSpan" : "rowSpan"] == 1) {
  2103. returns.push(tmpCell);
  2104. }
  2105. if (flag) break;
  2106. }
  2107. }
  2108. }
  2109. return returns;
  2110. } catch (e) {
  2111. showError(e);
  2112. }
  2113. },
  2114. setCellContent:function (cell, content) {
  2115. cell.innerHTML = content || (browser.ie ? domUtils.fillChar : "<br />");
  2116. },
  2117. cloneCell:cloneCell,
  2118. /**
  2119. * 获取跟当前单元格的右边竖线为左边的所有未合并单元格
  2120. */
  2121. getSameStartPosXCells:function (cell) {
  2122. try {
  2123. var start = domUtils.getXY(cell).x + cell.offsetWidth,
  2124. rows = this.table.rows, cells , returns = [];
  2125. for (var i = 0; i < this.rowsNum; i++) {
  2126. cells = rows[i].cells;
  2127. for (var j = 0, tmpCell; tmpCell = cells[j++];) {
  2128. var tmpStart = domUtils.getXY(tmpCell).x;
  2129. if (tmpStart > start) break;
  2130. if (tmpStart == start && tmpCell.colSpan == 1) {
  2131. returns.push(tmpCell);
  2132. break;
  2133. }
  2134. }
  2135. }
  2136. return returns;
  2137. } catch (e) {
  2138. showError(e);
  2139. }
  2140. },
  2141. /**
  2142. * 更新table对应的索引表
  2143. */
  2144. update:function (table) {
  2145. this.table = table || this.table;
  2146. this.selectedTds = [];
  2147. this.cellsRange = {};
  2148. this.indexTable = [];
  2149. var rows = this.table.rows,
  2150. //暂时采用rows Length,对残缺表格可能存在问题,
  2151. //todo 可以考虑取最大值
  2152. rowsNum = rows.length,
  2153. colsNum = this.getMaxCols();
  2154. this.rowsNum = rowsNum;
  2155. this.colsNum = colsNum;
  2156. for (var i = 0, len = rows.length; i < len; i++) {
  2157. this.indexTable[i] = new Array(colsNum);
  2158. }
  2159. //填充索引表
  2160. for (var rowIndex = 0, row; row = rows[rowIndex]; rowIndex++) {
  2161. for (var cellIndex = 0, cell, cells = row.cells; cell = cells[cellIndex]; cellIndex++) {
  2162. //修正整行被rowSpan时导致的行数计算错误
  2163. if (cell.rowSpan > rowsNum) {
  2164. cell.rowSpan = rowsNum;
  2165. }
  2166. var colIndex = cellIndex,
  2167. rowSpan = cell.rowSpan || 1,
  2168. colSpan = cell.colSpan || 1;
  2169. //当已经被上一行rowSpan或者被前一列colSpan了,则跳到下一个单元格进行
  2170. while (this.indexTable[rowIndex][colIndex]) colIndex++;
  2171. for (var j = 0; j < rowSpan; j++) {
  2172. for (var k = 0; k < colSpan; k++) {
  2173. this.indexTable[rowIndex + j][colIndex + k] = {
  2174. rowIndex:rowIndex,
  2175. cellIndex:cellIndex,
  2176. colIndex:colIndex,
  2177. rowSpan:rowSpan,
  2178. colSpan:colSpan
  2179. }
  2180. }
  2181. }
  2182. }
  2183. }
  2184. //修复残缺td
  2185. for (j = 0; j < rowsNum; j++) {
  2186. for (k = 0; k < colsNum; k++) {
  2187. if (this.indexTable[j][k] === undefined) {
  2188. row = rows[j];
  2189. cell = row.cells[row.cells.length - 1];
  2190. cell = cell ? cell.cloneNode(true) : this.table.ownerDocument.createElement("td");
  2191. this.setCellContent(cell);
  2192. if (cell.colSpan !== 1)cell.colSpan = 1;
  2193. if (cell.rowSpan !== 1)cell.rowSpan = 1;
  2194. row.appendChild(cell);
  2195. this.indexTable[j][k] = {
  2196. rowIndex:j,
  2197. cellIndex:cell.cellIndex,
  2198. colIndex:k,
  2199. rowSpan:1,
  2200. colSpan:1
  2201. }
  2202. }
  2203. }
  2204. }
  2205. //当框选后删除行或者列后撤销,需要重建选区。
  2206. var tds = domUtils.getElementsByTagName(this.table, "td"),
  2207. selectTds = [];
  2208. utils.each(tds, function (td) {
  2209. if (domUtils.hasClass(td, "selectTdClass")) {
  2210. selectTds.push(td);
  2211. }
  2212. });
  2213. if (selectTds.length) {
  2214. var start = selectTds[0],
  2215. end = selectTds[selectTds.length - 1],
  2216. startInfo = this.getCellInfo(start),
  2217. endInfo = this.getCellInfo(end);
  2218. this.selectedTds = selectTds;
  2219. this.cellsRange = {
  2220. beginRowIndex:startInfo.rowIndex,
  2221. beginColIndex:startInfo.colIndex,
  2222. endRowIndex:endInfo.rowIndex + endInfo.rowSpan - 1,
  2223. endColIndex:endInfo.colIndex + endInfo.colSpan - 1
  2224. };
  2225. }
  2226. },
  2227. /**
  2228. * 获取单元格的索引信息
  2229. */
  2230. getCellInfo:function (cell) {
  2231. if (!cell) return;
  2232. var cellIndex = cell.cellIndex,
  2233. rowIndex = cell.parentNode.rowIndex,
  2234. rowInfo = this.indexTable[rowIndex],
  2235. numCols = this.colsNum;
  2236. for (var colIndex = cellIndex; colIndex < numCols; colIndex++) {
  2237. var cellInfo = rowInfo[colIndex];
  2238. if (cellInfo.rowIndex === rowIndex && cellInfo.cellIndex === cellIndex) {
  2239. return cellInfo;
  2240. }
  2241. }
  2242. },
  2243. /**
  2244. * 根据行列号获取单元格
  2245. */
  2246. getCell:function (rowIndex, cellIndex) {
  2247. return rowIndex < this.rowsNum && this.table.rows[rowIndex].cells[cellIndex] || null;
  2248. },
  2249. /**
  2250. * 删除单元格
  2251. */
  2252. deleteCell:function (cell, rowIndex) {
  2253. rowIndex = typeof rowIndex == 'number' ? rowIndex : cell.parentNode.rowIndex;
  2254. var row = this.table.rows[rowIndex];
  2255. row.deleteCell(cell.cellIndex);
  2256. },
  2257. /**
  2258. * 根据始末两个单元格获取被框选的所有单元格范围
  2259. */
  2260. getCellsRange:function (cellA, cellB) {
  2261. function checkRange(beginRowIndex, beginColIndex, endRowIndex, endColIndex) {
  2262. var tmpBeginRowIndex = beginRowIndex,
  2263. tmpBeginColIndex = beginColIndex,
  2264. tmpEndRowIndex = endRowIndex,
  2265. tmpEndColIndex = endColIndex,
  2266. cellInfo, colIndex, rowIndex;
  2267. // 通过indexTable检查是否存在超出TableRange上边界的情况
  2268. if (beginRowIndex > 0) {
  2269. for (colIndex = beginColIndex; colIndex < endColIndex; colIndex++) {
  2270. cellInfo = me.indexTable[beginRowIndex][colIndex];
  2271. rowIndex = cellInfo.rowIndex;
  2272. if (rowIndex < beginRowIndex) {
  2273. tmpBeginRowIndex = Math.min(rowIndex, tmpBeginRowIndex);
  2274. }
  2275. }
  2276. }
  2277. // 通过indexTable检查是否存在超出TableRange右边界的情况
  2278. if (endColIndex < me.colsNum) {
  2279. for (rowIndex = beginRowIndex; rowIndex < endRowIndex; rowIndex++) {
  2280. cellInfo = me.indexTable[rowIndex][endColIndex];
  2281. colIndex = cellInfo.colIndex + cellInfo.colSpan - 1;
  2282. if (colIndex > endColIndex) {
  2283. tmpEndColIndex = Math.max(colIndex, tmpEndColIndex);
  2284. }
  2285. }
  2286. }
  2287. // 检查是否有超出TableRange下边界的情况
  2288. if (endRowIndex < me.rowsNum) {
  2289. for (colIndex = beginColIndex; colIndex < endColIndex; colIndex++) {
  2290. cellInfo = me.indexTable[endRowIndex][colIndex];
  2291. rowIndex = cellInfo.rowIndex + cellInfo.rowSpan - 1;
  2292. if (rowIndex > endRowIndex) {
  2293. tmpEndRowIndex = Math.max(rowIndex, tmpEndRowIndex);
  2294. }
  2295. }
  2296. }
  2297. // 检查是否有超出TableRange左边界的情况
  2298. if (beginColIndex > 0) {
  2299. for (rowIndex = beginRowIndex; rowIndex < endRowIndex; rowIndex++) {
  2300. cellInfo = me.indexTable[rowIndex][beginColIndex];
  2301. colIndex = cellInfo.colIndex;
  2302. if (colIndex < beginColIndex) {
  2303. tmpBeginColIndex = Math.min(cellInfo.colIndex, tmpBeginColIndex);
  2304. }
  2305. }
  2306. }
  2307. //递归调用直至所有完成所有框选单元格的扩展
  2308. if (tmpBeginRowIndex != beginRowIndex || tmpBeginColIndex != beginColIndex || tmpEndRowIndex != endRowIndex || tmpEndColIndex != endColIndex) {
  2309. return checkRange(tmpBeginRowIndex, tmpBeginColIndex, tmpEndRowIndex, tmpEndColIndex);
  2310. } else {
  2311. // 不需要扩展TableRange的情况
  2312. return {
  2313. beginRowIndex:beginRowIndex,
  2314. beginColIndex:beginColIndex,
  2315. endRowIndex:endRowIndex,
  2316. endColIndex:endColIndex
  2317. };
  2318. }
  2319. }
  2320. try {
  2321. var me = this,
  2322. cellAInfo = me.getCellInfo(cellA);
  2323. if (cellA === cellB) {
  2324. return {
  2325. beginRowIndex:cellAInfo.rowIndex,
  2326. beginColIndex:cellAInfo.colIndex,
  2327. endRowIndex:cellAInfo.rowIndex + cellAInfo.rowSpan - 1,
  2328. endColIndex:cellAInfo.colIndex + cellAInfo.colSpan - 1
  2329. };
  2330. }
  2331. var cellBInfo = me.getCellInfo(cellB);
  2332. // 计算TableRange的四个边
  2333. var beginRowIndex = Math.min(cellAInfo.rowIndex, cellBInfo.rowIndex),
  2334. beginColIndex = Math.min(cellAInfo.colIndex, cellBInfo.colIndex),
  2335. endRowIndex = Math.max(cellAInfo.rowIndex + cellAInfo.rowSpan - 1, cellBInfo.rowIndex + cellBInfo.rowSpan - 1),
  2336. endColIndex = Math.max(cellAInfo.colIndex + cellAInfo.colSpan - 1, cellBInfo.colIndex + cellBInfo.colSpan - 1);
  2337. return checkRange(beginRowIndex, beginColIndex, endRowIndex, endColIndex);
  2338. } catch (e) {
  2339. if (debug) throw e;
  2340. }
  2341. },
  2342. /**
  2343. * 依据cellsRange获取对应的单元格集合
  2344. */
  2345. getCells:function (range) {
  2346. //每次获取cells之前必须先清除上次的选择,否则会对后续获取操作造成影响
  2347. this.clearSelected();
  2348. var beginRowIndex = range.beginRowIndex,
  2349. beginColIndex = range.beginColIndex,
  2350. endRowIndex = range.endRowIndex,
  2351. endColIndex = range.endColIndex,
  2352. cellInfo, rowIndex, colIndex, tdHash = {}, returnTds = [];
  2353. for (var i = beginRowIndex; i <= endRowIndex; i++) {
  2354. for (var j = beginColIndex; j <= endColIndex; j++) {
  2355. cellInfo = this.indexTable[i][j];
  2356. rowIndex = cellInfo.rowIndex;
  2357. colIndex = cellInfo.colIndex;
  2358. // 如果Cells里已经包含了此Cell则跳过
  2359. var key = rowIndex + '|' + colIndex;
  2360. if (tdHash[key]) continue;
  2361. tdHash[key] = 1;
  2362. if (rowIndex < i || colIndex < j || rowIndex + cellInfo.rowSpan - 1 > endRowIndex || colIndex + cellInfo.colSpan - 1 > endColIndex) {
  2363. return null;
  2364. }
  2365. returnTds.push(this.getCell(rowIndex, cellInfo.cellIndex));
  2366. }
  2367. }
  2368. return returnTds;
  2369. },
  2370. /**
  2371. * 清理已经选中的单元格
  2372. */
  2373. clearSelected:function () {
  2374. removeSelectedClass(this.selectedTds);
  2375. this.selectedTds = [];
  2376. this.cellsRange = {};
  2377. },
  2378. /**
  2379. * 根据range设置已经选中的单元格
  2380. */
  2381. setSelected:function (range) {
  2382. var cells = this.getCells(range);
  2383. addSelectedClass(cells);
  2384. this.selectedTds = cells;
  2385. this.cellsRange = range;
  2386. },
  2387. isFullRow:function () {
  2388. var range = this.cellsRange;
  2389. return (range.endColIndex - range.beginColIndex + 1) == this.colsNum;
  2390. },
  2391. isFullCol:function () {
  2392. var range = this.cellsRange,
  2393. table = this.table,
  2394. ths = table.getElementsByTagName("th"),
  2395. rows = range.endRowIndex - range.beginRowIndex + 1;
  2396. return !ths.length ? rows == this.rowsNum : rows == this.rowsNum || (rows == this.rowsNum - 1);
  2397. },
  2398. /**
  2399. * 获取视觉上的前置单元格,默认是左边,top传入时
  2400. * @param cell
  2401. * @param top
  2402. */
  2403. getNextCell:function (cell, bottom, ignoreRange) {
  2404. try {
  2405. var cellInfo = this.getCellInfo(cell),
  2406. nextRowIndex, nextColIndex;
  2407. var len = this.selectedTds.length && !ignoreRange,
  2408. range = this.cellsRange;
  2409. //末行或者末列没有后置单元格
  2410. if ((!bottom && (cellInfo.rowIndex == 0)) || (bottom && (!len ? (cellInfo.rowIndex + cellInfo.rowSpan > this.rowsNum - 1) : (range.endRowIndex == this.rowsNum - 1)))) return null;
  2411. nextRowIndex = !bottom ? ( !len ? cellInfo.rowIndex - 1 : range.beginRowIndex - 1)
  2412. : ( !len ? (cellInfo.rowIndex + cellInfo.rowSpan) : range.endRowIndex + 1);
  2413. nextColIndex = !len ? cellInfo.colIndex : range.beginColIndex;
  2414. return this.getCell(this.indexTable[nextRowIndex][nextColIndex].rowIndex, this.indexTable[nextRowIndex][nextColIndex].cellIndex);
  2415. } catch (e) {
  2416. showError(e);
  2417. }
  2418. },
  2419. getPreviewCell:function (cell, top) {
  2420. try {
  2421. var cellInfo = this.getCellInfo(cell),
  2422. previewRowIndex, previewColIndex;
  2423. var len = this.selectedTds.length,
  2424. range = this.cellsRange;
  2425. //首行或者首列没有前置单元格
  2426. if ((!top && (!len ? !cellInfo.colIndex : !range.beginColIndex)) || (top && (!len ? (cellInfo.rowIndex > (this.colsNum - 1)) : (range.endColIndex == this.colsNum - 1)))) return null;
  2427. previewRowIndex = !top ? ( !len ? cellInfo.rowIndex : range.beginRowIndex )
  2428. : ( !len ? (cellInfo.rowIndex < 1 ? 0 : (cellInfo.rowIndex - 1)) : range.beginRowIndex);
  2429. previewColIndex = !top ? ( !len ? (cellInfo.colIndex < 1 ? 0 : (cellInfo.colIndex - 1)) : range.beginColIndex - 1)
  2430. : ( !len ? cellInfo.colIndex : range.endColIndex + 1);
  2431. return this.getCell(this.indexTable[previewRowIndex][previewColIndex].rowIndex, this.indexTable[previewRowIndex][previewColIndex].cellIndex);
  2432. } catch (e) {
  2433. showError(e);
  2434. }
  2435. },
  2436. /**
  2437. * 移动单元格中的内容
  2438. */
  2439. moveContent:function (cellTo, cellFrom) {
  2440. if (isEmptyBlock(cellFrom)) return;
  2441. if (isEmptyBlock(cellTo)) {
  2442. cellTo.innerHTML = cellFrom.innerHTML;
  2443. return;
  2444. }
  2445. var child = cellTo.lastChild;
  2446. if (child.nodeType == 3 || !dtd.$block[child.tagName]) {
  2447. cellTo.appendChild(cellTo.ownerDocument.createElement('br'))
  2448. }
  2449. while (child = cellFrom.firstChild) {
  2450. cellTo.appendChild(child);
  2451. }
  2452. },
  2453. /**
  2454. * 向右合并单元格
  2455. */
  2456. mergeRight:function (cell) {
  2457. var cellInfo = this.getCellInfo(cell),
  2458. rightColIndex = cellInfo.colIndex + cellInfo.colSpan,
  2459. rightCellInfo = this.indexTable[cellInfo.rowIndex][rightColIndex],
  2460. rightCell = this.getCell(rightCellInfo.rowIndex, rightCellInfo.cellIndex);
  2461. //合并
  2462. cell.colSpan = cellInfo.colSpan + rightCellInfo.colSpan;
  2463. //被合并的单元格不应存在宽度属性
  2464. cell.removeAttribute("width");
  2465. //移动内容
  2466. this.moveContent(cell, rightCell);
  2467. //删掉被合并的Cell
  2468. this.deleteCell(rightCell, rightCellInfo.rowIndex);
  2469. this.update();
  2470. },
  2471. /**
  2472. * 向下合并单元格
  2473. */
  2474. mergeDown:function (cell) {
  2475. var cellInfo = this.getCellInfo(cell),
  2476. downRowIndex = cellInfo.rowIndex + cellInfo.rowSpan,
  2477. downCellInfo = this.indexTable[downRowIndex][cellInfo.colIndex],
  2478. downCell = this.getCell(downCellInfo.rowIndex, downCellInfo.cellIndex);
  2479. cell.rowSpan = cellInfo.rowSpan + downCellInfo.rowSpan;
  2480. cell.removeAttribute("height");
  2481. this.moveContent(cell, downCell);
  2482. this.deleteCell(downCell, downCellInfo.rowIndex);
  2483. this.update();
  2484. },
  2485. /**
  2486. * 合并整个range中的内容
  2487. */
  2488. mergeRange:function () {
  2489. //由于合并操作可以在任意时刻进行,所以无法通过鼠标位置等信息实时生成range,只能通过缓存实例中的cellsRange对象来访问
  2490. var range = this.cellsRange,
  2491. leftTopCell = this.getCell(range.beginRowIndex, this.indexTable[range.beginRowIndex][range.beginColIndex].cellIndex);
  2492. if (leftTopCell.tagName == "TH" && range.endRowIndex !== range.beginRowIndex) {
  2493. var index = this.indexTable,
  2494. info = this.getCellInfo(leftTopCell);
  2495. leftTopCell = this.getCell(1, index[1][info.colIndex].cellIndex);
  2496. range = this.getCellsRange(leftTopCell, this.getCell(index[this.rowsNum - 1][info.colIndex].rowIndex, index[this.rowsNum - 1][info.colIndex].cellIndex));
  2497. }
  2498. // 删除剩余的Cells
  2499. var cells = this.getCells(range),
  2500. len = cells.length, cell;
  2501. while (len--) {
  2502. cell = cells[len];
  2503. if (cell !== leftTopCell) {
  2504. this.moveContent(leftTopCell, cell);
  2505. this.deleteCell(cell);
  2506. }
  2507. }
  2508. // 修改左上角Cell的rowSpan和colSpan,并调整宽度属性设置
  2509. leftTopCell.rowSpan = range.endRowIndex - range.beginRowIndex + 1;
  2510. leftTopCell.rowSpan > 1 && leftTopCell.removeAttribute("height");
  2511. leftTopCell.colSpan = range.endColIndex - range.beginColIndex + 1;
  2512. leftTopCell.colSpan > 1 && leftTopCell.removeAttribute("width");
  2513. if (leftTopCell.rowSpan == this.rowsNum && leftTopCell.colSpan != 1) {
  2514. leftTopCell.colSpan = 1;
  2515. }
  2516. if (leftTopCell.colSpan == this.colsNum && leftTopCell.rowSpan != 1) {
  2517. var rowIndex = leftTopCell.parentNode.rowIndex;
  2518. for (var i = 0; i < leftTopCell.rowSpan - 1; i++) {
  2519. var row = this.table.rows[rowIndex + 1];
  2520. row.parentNode.removeChild(row);
  2521. }
  2522. leftTopCell.rowSpan = 1;
  2523. }
  2524. this.update();
  2525. },
  2526. /**
  2527. * 插入一行单元格
  2528. */
  2529. insertRow:function (rowIndex, sourceCell,isBefore) {
  2530. var oldRowIndex = isBefore?rowIndex+1:rowIndex-1,
  2531. numCols = this.colsNum,
  2532. table = this.table,
  2533. row = table.insertRow(rowIndex), cell,
  2534. width = parseInt((table.offsetWidth - numCols * 20 - numCols - 1) / numCols, 10);
  2535. //首行直接插入,无需考虑部分单元格被rowspan的情况
  2536. if (rowIndex == 0 || rowIndex == this.rowsNum) {
  2537. for (var colIndex = 0; colIndex < numCols; colIndex++) {
  2538. var sc = this.getCell(oldRowIndex, colIndex);
  2539. cell = this.cloneCell(sc?sc:sourceCell, true);
  2540. this.setCellContent(cell);
  2541. cell.getAttribute('vAlign') && cell.setAttribute('vAlign', cell.getAttribute('vAlign'));
  2542. row.appendChild(cell);
  2543. }
  2544. } else {
  2545. var infoRow = this.indexTable[rowIndex],
  2546. cellIndex = 0;
  2547. for (colIndex = 0; colIndex < numCols; colIndex++) {
  2548. var cellInfo = infoRow[colIndex];
  2549. //如果存在某个单元格的rowspan穿过待插入行的位置,则修改该单元格的rowspan即可,无需插入单元格
  2550. if (cellInfo.rowIndex < rowIndex) {
  2551. cell = this.getCell(cellInfo.rowIndex, cellInfo.cellIndex);
  2552. cell.rowSpan = cellInfo.rowSpan + 1;
  2553. } else {
  2554. var sc = this.getCell(oldRowIndex, colIndex);
  2555. cell = this.cloneCell(sc?sc:sourceCell, true);
  2556. this.setCellContent(cell);
  2557. row.appendChild(cell);
  2558. }
  2559. }
  2560. }
  2561. //框选时插入不触发contentchange,需要手动更新索引。
  2562. this.update();
  2563. return row;
  2564. },
  2565. /**
  2566. * 删除一行单元格
  2567. * @param rowIndex
  2568. */
  2569. deleteRow:function (rowIndex) {
  2570. var row = this.table.rows[rowIndex],
  2571. infoRow = this.indexTable[rowIndex],
  2572. colsNum = this.colsNum,
  2573. count = 0; //处理计数
  2574. for (var colIndex = 0; colIndex < colsNum;) {
  2575. var cellInfo = infoRow[colIndex],
  2576. cell = this.getCell(cellInfo.rowIndex, cellInfo.cellIndex);
  2577. if (cell.rowSpan > 1) {
  2578. if (cellInfo.rowIndex == rowIndex) {
  2579. var clone = cell.cloneNode(true);
  2580. clone.rowSpan = cell.rowSpan - 1;
  2581. clone.innerHTML = "";
  2582. cell.rowSpan = 1;
  2583. var nextRowIndex = rowIndex + 1,
  2584. nextRow = this.table.rows[nextRowIndex],
  2585. insertCellIndex,
  2586. preMerged = this.getPreviewMergedCellsNum(nextRowIndex, colIndex) - count;
  2587. if (preMerged < colIndex) {
  2588. insertCellIndex = colIndex - preMerged - 1;
  2589. //nextRow.insertCell(insertCellIndex);
  2590. domUtils.insertAfter(nextRow.cells[insertCellIndex], clone);
  2591. } else {
  2592. if (nextRow.cells.length) nextRow.insertBefore(clone, nextRow.cells[0])
  2593. }
  2594. count += 1;
  2595. //cell.parentNode.removeChild(cell);
  2596. }
  2597. }
  2598. colIndex += cell.colSpan || 1;
  2599. }
  2600. var deleteTds = [], cacheMap = {};
  2601. for (colIndex = 0; colIndex < colsNum; colIndex++) {
  2602. var tmpRowIndex = infoRow[colIndex].rowIndex,
  2603. tmpCellIndex = infoRow[colIndex].cellIndex,
  2604. key = tmpRowIndex + "_" + tmpCellIndex;
  2605. if (cacheMap[key])continue;
  2606. cacheMap[key] = 1;
  2607. cell = this.getCell(tmpRowIndex, tmpCellIndex);
  2608. deleteTds.push(cell);
  2609. }
  2610. var mergeTds = [];
  2611. utils.each(deleteTds, function (td) {
  2612. if (td.rowSpan == 1) {
  2613. td.parentNode.removeChild(td);
  2614. } else {
  2615. mergeTds.push(td);
  2616. }
  2617. });
  2618. utils.each(mergeTds, function (td) {
  2619. td.rowSpan--;
  2620. });
  2621. row.parentNode.removeChild(row);
  2622. //浏览器方法本身存在bug,采用自定义方法删除
  2623. //this.table.deleteRow(rowIndex);
  2624. this.update();
  2625. },
  2626. insertCol:function (colIndex, sourceCell, defaultValue) {
  2627. var rowsNum = this.rowsNum,
  2628. rowIndex = 0,
  2629. tableRow, cell,
  2630. backWidth = parseInt((this.table.offsetWidth - (this.colsNum + 1) * 20 - (this.colsNum + 1)) / (this.colsNum + 1), 10);
  2631. function replaceTdToTh(rowIndex, cell, tableRow) {
  2632. if (rowIndex == 0) {
  2633. var th = cell.nextSibling || cell.previousSibling;
  2634. if (th.tagName == 'TH') {
  2635. th = cell.ownerDocument.createElement("th");
  2636. th.appendChild(cell.firstChild);
  2637. tableRow.insertBefore(th, cell);
  2638. domUtils.remove(cell)
  2639. }
  2640. }
  2641. }
  2642. var preCell;
  2643. if (colIndex == 0 || colIndex == this.colsNum) {
  2644. for (; rowIndex < rowsNum; rowIndex++) {
  2645. tableRow = this.table.rows[rowIndex];
  2646. preCell = tableRow.cells[colIndex == 0 ? colIndex : tableRow.cells.length];
  2647. cell = this.cloneCell(sourceCell, true); //tableRow.insertCell(colIndex == 0 ? colIndex : tableRow.cells.length);
  2648. this.setCellContent(cell);
  2649. cell.setAttribute('vAlign', cell.getAttribute('vAlign'));
  2650. preCell && cell.setAttribute('width', preCell.getAttribute('width'));
  2651. if (!colIndex) {
  2652. tableRow.insertBefore(cell, tableRow.cells[0]);
  2653. } else {
  2654. domUtils.insertAfter(tableRow.cells[tableRow.cells.length - 1], cell);
  2655. }
  2656. replaceTdToTh(rowIndex, cell, tableRow)
  2657. }
  2658. } else {
  2659. for (; rowIndex < rowsNum; rowIndex++) {
  2660. var cellInfo = this.indexTable[rowIndex][colIndex];
  2661. if (cellInfo.colIndex < colIndex) {
  2662. cell = this.getCell(cellInfo.rowIndex, cellInfo.cellIndex);
  2663. cell.colSpan = cellInfo.colSpan + 1;
  2664. } else {
  2665. tableRow = this.table.rows[rowIndex];
  2666. preCell = tableRow.cells[cellInfo.cellIndex];
  2667. cell = this.cloneCell(sourceCell, true);//tableRow.insertCell(cellInfo.cellIndex);
  2668. this.setCellContent(cell);
  2669. cell.setAttribute('vAlign', cell.getAttribute('vAlign'));
  2670. preCell && cell.setAttribute('width', preCell.getAttribute('width'))
  2671. tableRow.insertBefore(cell, preCell);
  2672. }
  2673. replaceTdToTh(rowIndex, cell, tableRow);
  2674. }
  2675. }
  2676. //框选时插入不触发contentchange,需要手动更新索引
  2677. this.update();
  2678. this.updateWidth(backWidth, defaultValue || {tdPadding:10, tdBorder:1});
  2679. },
  2680. updateWidth:function (width, defaultValue) {
  2681. var table = this.table,
  2682. tmpWidth = getWidth(table) - defaultValue.tdPadding * 2 - defaultValue.tdBorder + width;
  2683. if (tmpWidth < table.ownerDocument.body.offsetWidth) {
  2684. table.setAttribute("width", tmpWidth);
  2685. return;
  2686. }
  2687. var tds = domUtils.getElementsByTagName(this.table, "td");
  2688. utils.each(tds, function (td) {
  2689. td.setAttribute("width", width);
  2690. })
  2691. },
  2692. deleteCol:function (colIndex) {
  2693. var indexTable = this.indexTable,
  2694. tableRows = this.table.rows,
  2695. backTableWidth = this.table.getAttribute("width"),
  2696. backTdWidth = 0,
  2697. rowsNum = this.rowsNum,
  2698. cacheMap = {};
  2699. for (var rowIndex = 0; rowIndex < rowsNum;) {
  2700. var infoRow = indexTable[rowIndex],
  2701. cellInfo = infoRow[colIndex],
  2702. key = cellInfo.rowIndex + '_' + cellInfo.colIndex;
  2703. // 跳过已经处理过的Cell
  2704. if (cacheMap[key])continue;
  2705. cacheMap[key] = 1;
  2706. var cell = this.getCell(cellInfo.rowIndex, cellInfo.cellIndex);
  2707. if (!backTdWidth) backTdWidth = cell && parseInt(cell.offsetWidth / cell.colSpan, 10).toFixed(0);
  2708. // 如果Cell的colSpan大于1, 就修改colSpan, 否则就删掉这个Cell
  2709. if (cell.colSpan > 1) {
  2710. cell.colSpan--;
  2711. } else {
  2712. tableRows[rowIndex].deleteCell(cellInfo.cellIndex);
  2713. }
  2714. rowIndex += cellInfo.rowSpan || 1;
  2715. }
  2716. this.table.setAttribute("width", backTableWidth - backTdWidth);
  2717. this.update();
  2718. },
  2719. splitToCells:function (cell) {
  2720. var me = this,
  2721. cells = this.splitToRows(cell);
  2722. utils.each(cells, function (cell) {
  2723. me.splitToCols(cell);
  2724. })
  2725. },
  2726. splitToRows:function (cell) {
  2727. var cellInfo = this.getCellInfo(cell),
  2728. rowIndex = cellInfo.rowIndex,
  2729. colIndex = cellInfo.colIndex,
  2730. results = [];
  2731. // 修改Cell的rowSpan
  2732. cell.rowSpan = 1;
  2733. results.push(cell);
  2734. // 补齐单元格
  2735. for (var i = rowIndex, endRow = rowIndex + cellInfo.rowSpan; i < endRow; i++) {
  2736. if (i == rowIndex)continue;
  2737. var tableRow = this.table.rows[i],
  2738. tmpCell = tableRow.insertCell(colIndex - this.getPreviewMergedCellsNum(i, colIndex));
  2739. tmpCell.colSpan = cellInfo.colSpan;
  2740. this.setCellContent(tmpCell);
  2741. tmpCell.setAttribute('vAlign', cell.getAttribute('vAlign'));
  2742. tmpCell.setAttribute('align', cell.getAttribute('align'));
  2743. if (cell.style.cssText) {
  2744. tmpCell.style.cssText = cell.style.cssText;
  2745. }
  2746. results.push(tmpCell);
  2747. }
  2748. this.update();
  2749. return results;
  2750. },
  2751. getPreviewMergedCellsNum:function (rowIndex, colIndex) {
  2752. var indexRow = this.indexTable[rowIndex],
  2753. num = 0;
  2754. for (var i = 0; i < colIndex;) {
  2755. var colSpan = indexRow[i].colSpan,
  2756. tmpRowIndex = indexRow[i].rowIndex;
  2757. num += (colSpan - (tmpRowIndex == rowIndex ? 1 : 0));
  2758. i += colSpan;
  2759. }
  2760. return num;
  2761. },
  2762. splitToCols:function (cell) {
  2763. var backWidth = (cell.offsetWidth / cell.colSpan - 22).toFixed(0),
  2764. cellInfo = this.getCellInfo(cell),
  2765. rowIndex = cellInfo.rowIndex,
  2766. colIndex = cellInfo.colIndex,
  2767. results = [];
  2768. // 修改Cell的rowSpan
  2769. cell.colSpan = 1;
  2770. cell.setAttribute("width", backWidth);
  2771. results.push(cell);
  2772. // 补齐单元格
  2773. for (var j = colIndex, endCol = colIndex + cellInfo.colSpan; j < endCol; j++) {
  2774. if (j == colIndex)continue;
  2775. var tableRow = this.table.rows[rowIndex],
  2776. tmpCell = tableRow.insertCell(this.indexTable[rowIndex][j].cellIndex + 1);
  2777. tmpCell.rowSpan = cellInfo.rowSpan;
  2778. this.setCellContent(tmpCell);
  2779. tmpCell.setAttribute('vAlign', cell.getAttribute('vAlign'));
  2780. tmpCell.setAttribute('align', cell.getAttribute('align'));
  2781. tmpCell.setAttribute('width', backWidth);
  2782. if (cell.style.cssText) {
  2783. tmpCell.style.cssText = cell.style.cssText;
  2784. }
  2785. //处理th的情况
  2786. if (cell.tagName == 'TH') {
  2787. var th = cell.ownerDocument.createElement('th');
  2788. th.appendChild(tmpCell.firstChild);
  2789. th.setAttribute('vAlign', cell.getAttribute('vAlign'));
  2790. th.rowSpan = tmpCell.rowSpan;
  2791. tableRow.insertBefore(th, tmpCell);
  2792. domUtils.remove(tmpCell);
  2793. }
  2794. results.push(tmpCell);
  2795. }
  2796. this.update();
  2797. return results;
  2798. },
  2799. isLastCell:function (cell, rowsNum, colsNum) {
  2800. rowsNum = rowsNum || this.rowsNum;
  2801. colsNum = colsNum || this.colsNum;
  2802. var cellInfo = this.getCellInfo(cell);
  2803. return ((cellInfo.rowIndex + cellInfo.rowSpan) == rowsNum) &&
  2804. ((cellInfo.colIndex + cellInfo.colSpan) == colsNum);
  2805. },
  2806. getLastCell:function (cells) {
  2807. cells = cells || this.table.getElementsByTagName("td");
  2808. var firstInfo = this.getCellInfo(cells[0]);
  2809. var me = this, last = cells[0],
  2810. tr = last.parentNode,
  2811. cellsNum = 0, cols = 0, rows;
  2812. utils.each(cells, function (cell) {
  2813. if (cell.parentNode == tr)cols += cell.colSpan || 1;
  2814. cellsNum += cell.rowSpan * cell.colSpan || 1;
  2815. });
  2816. rows = cellsNum / cols;
  2817. utils.each(cells, function (cell) {
  2818. if (me.isLastCell(cell, rows, cols)) {
  2819. last = cell;
  2820. return false;
  2821. }
  2822. });
  2823. return last;
  2824. },
  2825. selectRow:function (rowIndex) {
  2826. var indexRow = this.indexTable[rowIndex],
  2827. start = this.getCell(indexRow[0].rowIndex, indexRow[0].cellIndex),
  2828. end = this.getCell(indexRow[this.colsNum - 1].rowIndex, indexRow[this.colsNum - 1].cellIndex),
  2829. range = this.getCellsRange(start, end);
  2830. this.setSelected(range);
  2831. },
  2832. selectTable:function () {
  2833. var tds = this.table.getElementsByTagName("td"),
  2834. range = this.getCellsRange(tds[0], tds[tds.length - 1]);
  2835. this.setSelected(range);
  2836. }
  2837. };
  2838. function getSelectedArr(editor) {
  2839. var ut = getTableItemsByRange(editor).cell || getUETableBySelected(editor);
  2840. return ut ? (ut.nodeType ? [ut] : ut.selectedTds) : [];
  2841. }
  2842. /**
  2843. * 根据当前选区获取相关的table信息
  2844. * @return {Object}
  2845. */
  2846. function getTableItemsByRange(editor) {
  2847. var start = editor.selection.getStart(),
  2848. //在table或者td边缘有可能存在选中tr的情况
  2849. cell = start && domUtils.findParentByTagName(start, ["td", "th"], true),
  2850. tr = cell && cell.parentNode,
  2851. caption = start && domUtils.findParentByTagName(start, 'caption', true),
  2852. table = caption ? caption.parentNode : tr && tr.parentNode.parentNode;
  2853. return {
  2854. cell:cell,
  2855. tr:tr,
  2856. table:table,
  2857. caption:caption
  2858. }
  2859. }
  2860. /**
  2861. * 获取需要触发对应点击或者move事件的td对象
  2862. * @param evt
  2863. */
  2864. function getTargetTd(editor, evt) {
  2865. var target = domUtils.findParentByTagName(evt.target || evt.srcElement, ["td", "th"], true);
  2866. //排除了非td内部以及用于代码高亮部分的td
  2867. return target && !(editor.fireEvent("excludetable", target) === true) ? target : null;
  2868. }
  2869. function cloneCell(cell, ingoreMerge) {
  2870. if (!cell || utils.isString(cell)) {
  2871. return this.table.ownerDocument.createElement(cell || 'td');
  2872. }
  2873. var flag = domUtils.hasClass(cell, "selectTdClass");
  2874. flag && domUtils.removeClasses(cell, "selectTdClass");
  2875. var tmpCell = cell.cloneNode(true);
  2876. if (ingoreMerge) {
  2877. tmpCell.rowSpan = tmpCell.colSpan = 1;
  2878. }
  2879. tmpCell.style.borderLeftStyle = "";
  2880. tmpCell.style.borderTopStyle = "";
  2881. tmpCell.style.width = "";
  2882. tmpCell.style.borderLeftColor = cell.style.borderRightColor;
  2883. tmpCell.style.borderLeftWidth = cell.style.borderRightWidth;
  2884. tmpCell.style.borderTopColor = cell.style.borderBottomColor;
  2885. tmpCell.style.borderTopWidth = cell.style.borderBottomWidth;
  2886. flag && domUtils.addClass(cell, "selectTdClass");
  2887. return tmpCell;
  2888. }
  2889. };