table.action.js 62 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023
  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. tabTimer = null,
  11. //拖动计时器
  12. tableDragTimer = null,
  13. //双击计时器
  14. tableResizeTimer = null,
  15. //单元格最小宽度
  16. cellMinWidth = 5,
  17. isInResizeBuffer = false,
  18. //单元格边框大小
  19. cellBorderWidth = 5,
  20. //鼠标偏移距离
  21. offsetOfTableCell = 10,
  22. //记录在有限时间内的点击状态, 共有3个取值, 0, 1, 2。 0代表未初始化, 1代表单击了1次,2代表2次
  23. singleClickState = 0,
  24. userActionStatus = null,
  25. //双击允许的时间范围
  26. dblclickTime = 360,
  27. UT = UE.UETable,
  28. getUETable = function(tdOrTable) {
  29. return UT.getUETable(tdOrTable);
  30. },
  31. getUETableBySelected = function(editor) {
  32. return UT.getUETableBySelected(editor);
  33. },
  34. getDefaultValue = function(editor, table) {
  35. return UT.getDefaultValue(editor, table);
  36. },
  37. removeSelectedClass = function(cells) {
  38. return UT.removeSelectedClass(cells);
  39. };
  40. function showError(e) {
  41. // throw e;
  42. }
  43. me.ready(function() {
  44. var me = this;
  45. var orgGetText = me.selection.getText;
  46. me.selection.getText = function() {
  47. var table = getUETableBySelected(me);
  48. if (table) {
  49. var str = "";
  50. utils.each(table.selectedTds, function(td) {
  51. str += td[browser.ie ? "innerText" : "textContent"];
  52. });
  53. return str;
  54. } else {
  55. return orgGetText.call(me.selection);
  56. }
  57. };
  58. });
  59. //处理拖动及框选相关方法
  60. var startTd = null, //鼠标按下时的锚点td
  61. currentTd = null, //当前鼠标经过时的td
  62. onDrag = "", //指示当前拖动状态,其值可为"","h","v" ,分别表示未拖动状态,横向拖动状态,纵向拖动状态,用于鼠标移动过程中的判断
  63. onBorder = false, //检测鼠标按下时是否处在单元格边缘位置
  64. dragButton = null,
  65. dragOver = false,
  66. dragLine = null, //模拟的拖动线
  67. dragTd = null; //发生拖动的目标td
  68. var mousedown = false,
  69. //todo 判断混乱模式
  70. needIEHack = true;
  71. me.setOpt({
  72. maxColNum: 20,
  73. maxRowNum: 100,
  74. defaultCols: 5,
  75. defaultRows: 5,
  76. tdvalign: "top",
  77. cursorpath: me.options.UEDITOR_HOME_URL + "themes/default/images/cursor_",
  78. tableDragable: false,
  79. classList: [
  80. "ue-table-interlace-color-single",
  81. "ue-table-interlace-color-double"
  82. ]
  83. });
  84. me.getUETable = getUETable;
  85. var commands = {
  86. deletetable: 1,
  87. inserttable: 1,
  88. cellvalign: 1,
  89. insertcaption: 1,
  90. deletecaption: 1,
  91. inserttitle: 1,
  92. deletetitle: 1,
  93. mergeright: 1,
  94. mergedown: 1,
  95. mergecells: 1,
  96. insertrow: 1,
  97. insertrownext: 1,
  98. deleterow: 1,
  99. insertcol: 1,
  100. insertcolnext: 1,
  101. deletecol: 1,
  102. splittocells: 1,
  103. splittorows: 1,
  104. splittocols: 1,
  105. adaptbytext: 1,
  106. adaptbywindow: 1,
  107. adaptbycustomer: 1,
  108. insertparagraph: 1,
  109. insertparagraphbeforetable: 1,
  110. averagedistributecol: 1,
  111. averagedistributerow: 1
  112. };
  113. me.ready(function() {
  114. utils.cssRule(
  115. "table",
  116. //选中的td上的样式
  117. ".selectTdClass{background-color:#edf5fa !important}" +
  118. "table.noBorderTable td,table.noBorderTable th,table.noBorderTable caption{border:1px dashed #ddd !important}" +
  119. //插入的表格的默认样式
  120. "table{margin-bottom:10px;border-collapse:collapse;display:table;}" +
  121. "td,th{padding: 5px 10px;border: 1px solid #DDD;}" +
  122. "caption{border:1px dashed #DDD;border-bottom:0;padding:3px;text-align:center;}" +
  123. "th{border-top:1px solid #BBB;background-color:#F7F7F7;}" +
  124. "table tr.firstRow th{border-top-width:2px;}" +
  125. ".ue-table-interlace-color-single{ background-color: #fcfcfc; } .ue-table-interlace-color-double{ background-color: #f7faff; }" +
  126. "td p{margin:0;padding:0;}",
  127. me.document
  128. );
  129. var tableCopyList, isFullCol, isFullRow;
  130. //注册del/backspace事件
  131. me.addListener("keydown", function(cmd, evt) {
  132. var me = this;
  133. var keyCode = evt.keyCode || evt.which;
  134. if (keyCode == 8) {
  135. var ut = getUETableBySelected(me);
  136. if (ut && ut.selectedTds.length) {
  137. if (ut.isFullCol()) {
  138. me.execCommand("deletecol");
  139. } else if (ut.isFullRow()) {
  140. me.execCommand("deleterow");
  141. } else {
  142. me.fireEvent("delcells");
  143. }
  144. domUtils.preventDefault(evt);
  145. }
  146. var caption = domUtils.findParentByTagName(
  147. me.selection.getStart(),
  148. "caption",
  149. true
  150. ),
  151. range = me.selection.getRange();
  152. if (range.collapsed && caption && isEmptyBlock(caption)) {
  153. me.fireEvent("saveScene");
  154. var table = caption.parentNode;
  155. domUtils.remove(caption);
  156. if (table) {
  157. range.setStart(table.rows[0].cells[0], 0).setCursor(false, true);
  158. }
  159. me.fireEvent("saveScene");
  160. }
  161. }
  162. if (keyCode == 46) {
  163. ut = getUETableBySelected(me);
  164. if (ut) {
  165. me.fireEvent("saveScene");
  166. for (var i = 0, ci; (ci = ut.selectedTds[i++]); ) {
  167. domUtils.fillNode(me.document, ci);
  168. }
  169. me.fireEvent("saveScene");
  170. domUtils.preventDefault(evt);
  171. }
  172. }
  173. if (keyCode == 13) {
  174. var rng = me.selection.getRange(),
  175. caption = domUtils.findParentByTagName(
  176. rng.startContainer,
  177. "caption",
  178. true
  179. );
  180. if (caption) {
  181. var table = domUtils.findParentByTagName(caption, "table");
  182. if (!rng.collapsed) {
  183. rng.deleteContents();
  184. me.fireEvent("saveScene");
  185. } else {
  186. if (caption) {
  187. rng.setStart(table.rows[0].cells[0], 0).setCursor(false, true);
  188. }
  189. }
  190. domUtils.preventDefault(evt);
  191. return;
  192. }
  193. if (rng.collapsed) {
  194. var table = domUtils.findParentByTagName(rng.startContainer, "table");
  195. if (table) {
  196. var cell = table.rows[0].cells[0],
  197. start = domUtils.findParentByTagName(
  198. me.selection.getStart(),
  199. ["td", "th"],
  200. true
  201. ),
  202. preNode = table.previousSibling;
  203. if (
  204. cell === start &&
  205. (!preNode ||
  206. (preNode.nodeType == 1 && preNode.tagName == "TABLE")) &&
  207. domUtils.isStartInblock(rng)
  208. ) {
  209. var first = domUtils.findParent(
  210. me.selection.getStart(),
  211. function(n) {
  212. return domUtils.isBlockElm(n);
  213. },
  214. true
  215. );
  216. if (
  217. first &&
  218. (/t(h|d)/i.test(first.tagName) || first === start.firstChild)
  219. ) {
  220. me.execCommand("insertparagraphbeforetable");
  221. domUtils.preventDefault(evt);
  222. }
  223. }
  224. }
  225. }
  226. }
  227. if ((evt.ctrlKey || evt.metaKey) && evt.keyCode == "67") {
  228. tableCopyList = null;
  229. var ut = getUETableBySelected(me);
  230. if (ut) {
  231. var tds = ut.selectedTds;
  232. isFullCol = ut.isFullCol();
  233. isFullRow = ut.isFullRow();
  234. tableCopyList = [[ut.cloneCell(tds[0], null, true)]];
  235. for (var i = 1, ci; (ci = tds[i]); i++) {
  236. if (ci.parentNode !== tds[i - 1].parentNode) {
  237. tableCopyList.push([ut.cloneCell(ci, null, true)]);
  238. } else {
  239. tableCopyList[tableCopyList.length - 1].push(
  240. ut.cloneCell(ci, null, true)
  241. );
  242. }
  243. }
  244. }
  245. }
  246. });
  247. me.addListener("tablehasdeleted", function() {
  248. toggleDraggableState(this, false, "", null);
  249. if (dragButton) domUtils.remove(dragButton);
  250. });
  251. me.addListener("beforepaste", function(cmd, html) {
  252. var me = this;
  253. var rng = me.selection.getRange();
  254. if (domUtils.findParentByTagName(rng.startContainer, "caption", true)) {
  255. var div = me.document.createElement("div");
  256. div.innerHTML = html.html;
  257. //trace:3729
  258. html.html = div[browser.ie9below ? "innerText" : "textContent"];
  259. return;
  260. }
  261. var table = getUETableBySelected(me);
  262. if (tableCopyList) {
  263. me.fireEvent("saveScene");
  264. var rng = me.selection.getRange();
  265. var td = domUtils.findParentByTagName(
  266. rng.startContainer,
  267. ["td", "th"],
  268. true
  269. ),
  270. tmpNode,
  271. preNode;
  272. if (td) {
  273. var ut = getUETable(td);
  274. if (isFullRow) {
  275. var rowIndex = ut.getCellInfo(td).rowIndex;
  276. if (td.tagName == "TH") {
  277. rowIndex++;
  278. }
  279. for (var i = 0, ci; (ci = tableCopyList[i++]); ) {
  280. var tr = ut.insertRow(rowIndex++, "td");
  281. for (var j = 0, cj; (cj = ci[j]); j++) {
  282. var cell = tr.cells[j];
  283. if (!cell) {
  284. cell = tr.insertCell(j);
  285. }
  286. cell.innerHTML = cj.innerHTML;
  287. cj.getAttribute("width") &&
  288. cell.setAttribute("width", cj.getAttribute("width"));
  289. cj.getAttribute("vAlign") &&
  290. cell.setAttribute("vAlign", cj.getAttribute("vAlign"));
  291. cj.getAttribute("align") &&
  292. cell.setAttribute("align", cj.getAttribute("align"));
  293. cj.style.cssText && (cell.style.cssText = cj.style.cssText);
  294. }
  295. for (var j = 0, cj; (cj = tr.cells[j]); j++) {
  296. if (!ci[j]) break;
  297. cj.innerHTML = ci[j].innerHTML;
  298. ci[j].getAttribute("width") &&
  299. cj.setAttribute("width", ci[j].getAttribute("width"));
  300. ci[j].getAttribute("vAlign") &&
  301. cj.setAttribute("vAlign", ci[j].getAttribute("vAlign"));
  302. ci[j].getAttribute("align") &&
  303. cj.setAttribute("align", ci[j].getAttribute("align"));
  304. ci[j].style.cssText && (cj.style.cssText = ci[j].style.cssText);
  305. }
  306. }
  307. } else {
  308. if (isFullCol) {
  309. cellInfo = ut.getCellInfo(td);
  310. var maxColNum = 0;
  311. for (var j = 0, ci = tableCopyList[0], cj; (cj = ci[j++]); ) {
  312. maxColNum += cj.colSpan || 1;
  313. }
  314. me.__hasEnterExecCommand = true;
  315. for (i = 0; i < maxColNum; i++) {
  316. me.execCommand("insertcol");
  317. }
  318. me.__hasEnterExecCommand = false;
  319. td = ut.table.rows[0].cells[cellInfo.cellIndex];
  320. if (td.tagName == "TH") {
  321. td = ut.table.rows[1].cells[cellInfo.cellIndex];
  322. }
  323. }
  324. for (var i = 0, ci; (ci = tableCopyList[i++]); ) {
  325. tmpNode = td;
  326. for (var j = 0, cj; (cj = ci[j++]); ) {
  327. if (td) {
  328. td.innerHTML = cj.innerHTML;
  329. //todo 定制处理
  330. cj.getAttribute("width") &&
  331. td.setAttribute("width", cj.getAttribute("width"));
  332. cj.getAttribute("vAlign") &&
  333. td.setAttribute("vAlign", cj.getAttribute("vAlign"));
  334. cj.getAttribute("align") &&
  335. td.setAttribute("align", cj.getAttribute("align"));
  336. cj.style.cssText && (td.style.cssText = cj.style.cssText);
  337. preNode = td;
  338. td = td.nextSibling;
  339. } else {
  340. var cloneTd = cj.cloneNode(true);
  341. domUtils.removeAttributes(cloneTd, [
  342. "class",
  343. "rowSpan",
  344. "colSpan"
  345. ]);
  346. preNode.parentNode.appendChild(cloneTd);
  347. }
  348. }
  349. td = ut.getNextCell(tmpNode, true, true);
  350. if (!tableCopyList[i]) break;
  351. if (!td) {
  352. var cellInfo = ut.getCellInfo(tmpNode);
  353. ut.table.insertRow(ut.table.rows.length);
  354. ut.update();
  355. td = ut.getVSideCell(tmpNode, true);
  356. }
  357. }
  358. }
  359. ut.update();
  360. } else {
  361. table = me.document.createElement("table");
  362. for (var i = 0, ci; (ci = tableCopyList[i++]); ) {
  363. var tr = table.insertRow(table.rows.length);
  364. for (var j = 0, cj; (cj = ci[j++]); ) {
  365. cloneTd = UT.cloneCell(cj, null, true);
  366. domUtils.removeAttributes(cloneTd, ["class"]);
  367. tr.appendChild(cloneTd);
  368. }
  369. if (j == 2 && cloneTd.rowSpan > 1) {
  370. cloneTd.rowSpan = 1;
  371. }
  372. }
  373. var defaultValue = getDefaultValue(me),
  374. width =
  375. me.body.offsetWidth -
  376. (needIEHack
  377. ? parseInt(
  378. domUtils.getComputedStyle(me.body, "margin-left"),
  379. 10
  380. ) * 2
  381. : 0) -
  382. defaultValue.tableBorder * 2 -
  383. (me.options.offsetWidth || 0);
  384. me.execCommand(
  385. "insertHTML",
  386. "<table " +
  387. (isFullCol && isFullRow ? 'width="' + width + '"' : "") +
  388. ">" +
  389. table.innerHTML
  390. .replace(/>\s*</g, "><")
  391. .replace(/\bth\b/gi, "td") +
  392. "</table>"
  393. );
  394. }
  395. me.fireEvent("contentchange");
  396. me.fireEvent("saveScene");
  397. html.html = "";
  398. return true;
  399. } else {
  400. var div = me.document.createElement("div"),
  401. tables;
  402. div.innerHTML = html.html;
  403. tables = div.getElementsByTagName("table");
  404. if (domUtils.findParentByTagName(me.selection.getStart(), "table")) {
  405. utils.each(tables, function(t) {
  406. domUtils.remove(t);
  407. });
  408. if (
  409. domUtils.findParentByTagName(
  410. me.selection.getStart(),
  411. "caption",
  412. true
  413. )
  414. ) {
  415. div.innerHTML = div[browser.ie ? "innerText" : "textContent"];
  416. }
  417. } else {
  418. utils.each(tables, function(table) {
  419. removeStyleSize(table, true);
  420. domUtils.removeAttributes(table, ["style", "border"]);
  421. utils.each(domUtils.getElementsByTagName(table, "td"), function(
  422. td
  423. ) {
  424. if (isEmptyBlock(td)) {
  425. domUtils.fillNode(me.document, td);
  426. }
  427. removeStyleSize(td, true);
  428. // domUtils.removeAttributes(td, ['style'])
  429. });
  430. });
  431. }
  432. html.html = div.innerHTML;
  433. }
  434. });
  435. me.addListener("afterpaste", function() {
  436. utils.each(domUtils.getElementsByTagName(me.body, "table"), function(
  437. table
  438. ) {
  439. if (table.offsetWidth > me.body.offsetWidth) {
  440. var defaultValue = getDefaultValue(me, table);
  441. table.style.width =
  442. me.body.offsetWidth -
  443. (needIEHack
  444. ? parseInt(
  445. domUtils.getComputedStyle(me.body, "margin-left"),
  446. 10
  447. ) * 2
  448. : 0) -
  449. defaultValue.tableBorder * 2 -
  450. (me.options.offsetWidth || 0) +
  451. "px";
  452. }
  453. });
  454. });
  455. me.addListener("blur", function() {
  456. tableCopyList = null;
  457. });
  458. var timer;
  459. me.addListener("keydown", function() {
  460. clearTimeout(timer);
  461. timer = setTimeout(function() {
  462. var rng = me.selection.getRange(),
  463. cell = domUtils.findParentByTagName(
  464. rng.startContainer,
  465. ["th", "td"],
  466. true
  467. );
  468. if (cell) {
  469. var table = cell.parentNode.parentNode.parentNode;
  470. if (table.offsetWidth > table.getAttribute("width")) {
  471. cell.style.wordBreak = "break-all";
  472. }
  473. }
  474. }, 100);
  475. });
  476. me.addListener("selectionchange", function() {
  477. toggleDraggableState(me, false, "", null);
  478. });
  479. //内容变化时触发索引更新
  480. //todo 可否考虑标记检测,如果不涉及表格的变化就不进行索引重建和更新
  481. me.addListener("contentchange", function() {
  482. var me = this;
  483. //尽可能排除一些不需要更新的状况
  484. hideDragLine(me);
  485. if (getUETableBySelected(me)) return;
  486. var rng = me.selection.getRange();
  487. var start = rng.startContainer;
  488. start = domUtils.findParentByTagName(start, ["td", "th"], true);
  489. utils.each(domUtils.getElementsByTagName(me.document, "table"), function(
  490. table
  491. ) {
  492. if (me.fireEvent("excludetable", table) === true) return;
  493. table.ueTable = new UT(table);
  494. //trace:3742
  495. // utils.each(domUtils.getElementsByTagName(me.document, 'td'), function (td) {
  496. //
  497. // if (domUtils.isEmptyBlock(td) && td !== start) {
  498. // domUtils.fillNode(me.document, td);
  499. // if (browser.ie && browser.version == 6) {
  500. // td.innerHTML = '&nbsp;'
  501. // }
  502. // }
  503. // });
  504. // utils.each(domUtils.getElementsByTagName(me.document, 'th'), function (th) {
  505. // if (domUtils.isEmptyBlock(th) && th !== start) {
  506. // domUtils.fillNode(me.document, th);
  507. // if (browser.ie && browser.version == 6) {
  508. // th.innerHTML = '&nbsp;'
  509. // }
  510. // }
  511. // });
  512. table.onmouseover = function() {
  513. me.fireEvent("tablemouseover", table);
  514. };
  515. table.onmousemove = function() {
  516. me.fireEvent("tablemousemove", table);
  517. me.options.tableDragable && toggleDragButton(true, this, me);
  518. utils.defer(function() {
  519. me.fireEvent("contentchange", 50);
  520. }, true);
  521. };
  522. table.onmouseout = function() {
  523. me.fireEvent("tablemouseout", table);
  524. toggleDraggableState(me, false, "", null);
  525. hideDragLine(me);
  526. };
  527. table.onclick = function(evt) {
  528. evt = me.window.event || evt;
  529. var target = getParentTdOrTh(evt.target || evt.srcElement);
  530. if (!target) return;
  531. var ut = getUETable(target),
  532. table = ut.table,
  533. cellInfo = ut.getCellInfo(target),
  534. cellsRange,
  535. rng = me.selection.getRange();
  536. // if ("topLeft" == inPosition(table, mouseCoords(evt))) {
  537. // cellsRange = ut.getCellsRange(ut.table.rows[0].cells[0], ut.getLastCell());
  538. // ut.setSelected(cellsRange);
  539. // return;
  540. // }
  541. // if ("bottomRight" == inPosition(table, mouseCoords(evt))) {
  542. //
  543. // return;
  544. // }
  545. if (inTableSide(table, target, evt, true)) {
  546. var endTdCol = ut.getCell(
  547. ut.indexTable[ut.rowsNum - 1][cellInfo.colIndex].rowIndex,
  548. ut.indexTable[ut.rowsNum - 1][cellInfo.colIndex].cellIndex
  549. );
  550. if (evt.shiftKey && ut.selectedTds.length) {
  551. if (ut.selectedTds[0] !== endTdCol) {
  552. cellsRange = ut.getCellsRange(ut.selectedTds[0], endTdCol);
  553. ut.setSelected(cellsRange);
  554. } else {
  555. rng && rng.selectNodeContents(endTdCol).select();
  556. }
  557. } else {
  558. if (target !== endTdCol) {
  559. cellsRange = ut.getCellsRange(target, endTdCol);
  560. ut.setSelected(cellsRange);
  561. } else {
  562. rng && rng.selectNodeContents(endTdCol).select();
  563. }
  564. }
  565. return;
  566. }
  567. if (inTableSide(table, target, evt)) {
  568. var endTdRow = ut.getCell(
  569. ut.indexTable[cellInfo.rowIndex][ut.colsNum - 1].rowIndex,
  570. ut.indexTable[cellInfo.rowIndex][ut.colsNum - 1].cellIndex
  571. );
  572. if (evt.shiftKey && ut.selectedTds.length) {
  573. if (ut.selectedTds[0] !== endTdRow) {
  574. cellsRange = ut.getCellsRange(ut.selectedTds[0], endTdRow);
  575. ut.setSelected(cellsRange);
  576. } else {
  577. rng && rng.selectNodeContents(endTdRow).select();
  578. }
  579. } else {
  580. if (target !== endTdRow) {
  581. cellsRange = ut.getCellsRange(target, endTdRow);
  582. ut.setSelected(cellsRange);
  583. } else {
  584. rng && rng.selectNodeContents(endTdRow).select();
  585. }
  586. }
  587. }
  588. };
  589. });
  590. switchBorderColor(me, true);
  591. });
  592. domUtils.on(me.document, "mousemove", mouseMoveEvent);
  593. domUtils.on(me.document, "mouseout", function(evt) {
  594. var target = evt.target || evt.srcElement;
  595. if (target.tagName == "TABLE") {
  596. toggleDraggableState(me, false, "", null);
  597. }
  598. });
  599. /**
  600. * 表格隔行变色
  601. */
  602. me.addListener("interlacetable", function(type, table, classList) {
  603. if (!table) return;
  604. var me = this,
  605. rows = table.rows,
  606. len = rows.length,
  607. getClass = function(list, index, repeat) {
  608. return list[index]
  609. ? list[index]
  610. : repeat ? list[index % list.length] : "";
  611. };
  612. for (var i = 0; i < len; i++) {
  613. rows[i].className = getClass(
  614. classList || me.options.classList,
  615. i,
  616. true
  617. );
  618. }
  619. });
  620. me.addListener("uninterlacetable", function(type, table) {
  621. if (!table) return;
  622. var me = this,
  623. rows = table.rows,
  624. classList = me.options.classList,
  625. len = rows.length;
  626. for (var i = 0; i < len; i++) {
  627. domUtils.removeClasses(rows[i], classList);
  628. }
  629. });
  630. me.addListener("mousedown", mouseDownEvent);
  631. me.addListener("mouseup", mouseUpEvent);
  632. //拖动的时候触发mouseup
  633. domUtils.on(me.body, "dragstart", function(evt) {
  634. mouseUpEvent.call(me, "dragstart", evt);
  635. });
  636. me.addOutputRule(function(root) {
  637. utils.each(root.getNodesByTagName("div"), function(n) {
  638. if (n.getAttr("id") == "ue_tableDragLine") {
  639. n.parentNode.removeChild(n);
  640. }
  641. });
  642. });
  643. var currentRowIndex = 0;
  644. me.addListener("mousedown", function() {
  645. currentRowIndex = 0;
  646. });
  647. me.addListener("tabkeydown", function() {
  648. var range = this.selection.getRange(),
  649. common = range.getCommonAncestor(true, true),
  650. table = domUtils.findParentByTagName(common, "table");
  651. if (table) {
  652. if (domUtils.findParentByTagName(common, "caption", true)) {
  653. var cell = domUtils.getElementsByTagName(table, "th td");
  654. if (cell && cell.length) {
  655. range.setStart(cell[0], 0).setCursor(false, true);
  656. }
  657. } else {
  658. var cell = domUtils.findParentByTagName(common, ["td", "th"], true),
  659. ua = getUETable(cell);
  660. currentRowIndex = cell.rowSpan > 1
  661. ? currentRowIndex
  662. : ua.getCellInfo(cell).rowIndex;
  663. var nextCell = ua.getTabNextCell(cell, currentRowIndex);
  664. if (nextCell) {
  665. if (isEmptyBlock(nextCell)) {
  666. range.setStart(nextCell, 0).setCursor(false, true);
  667. } else {
  668. range.selectNodeContents(nextCell).select();
  669. }
  670. } else {
  671. me.fireEvent("saveScene");
  672. me.__hasEnterExecCommand = true;
  673. this.execCommand("insertrownext");
  674. me.__hasEnterExecCommand = false;
  675. range = this.selection.getRange();
  676. range
  677. .setStart(table.rows[table.rows.length - 1].cells[0], 0)
  678. .setCursor();
  679. me.fireEvent("saveScene");
  680. }
  681. }
  682. return true;
  683. }
  684. });
  685. browser.ie &&
  686. me.addListener("selectionchange", function() {
  687. toggleDraggableState(this, false, "", null);
  688. });
  689. me.addListener("keydown", function(type, evt) {
  690. var me = this;
  691. //处理在表格的最后一个输入tab产生新的表格
  692. var keyCode = evt.keyCode || evt.which;
  693. if (keyCode == 8 || keyCode == 46) {
  694. return;
  695. }
  696. var notCtrlKey =
  697. !evt.ctrlKey && !evt.metaKey && !evt.shiftKey && !evt.altKey;
  698. notCtrlKey &&
  699. removeSelectedClass(domUtils.getElementsByTagName(me.body, "td"));
  700. var ut = getUETableBySelected(me);
  701. if (!ut) return;
  702. notCtrlKey && ut.clearSelected();
  703. });
  704. me.addListener("beforegetcontent", function() {
  705. switchBorderColor(this, false);
  706. browser.ie &&
  707. utils.each(this.document.getElementsByTagName("caption"), function(ci) {
  708. if (domUtils.isEmptyNode(ci)) {
  709. ci.innerHTML = "&nbsp;";
  710. }
  711. });
  712. });
  713. me.addListener("aftergetcontent", function() {
  714. switchBorderColor(this, true);
  715. });
  716. me.addListener("getAllHtml", function() {
  717. removeSelectedClass(me.document.getElementsByTagName("td"));
  718. });
  719. //修正全屏状态下插入的表格宽度在非全屏状态下撑开编辑器的情况
  720. me.addListener("fullscreenchanged", function(type, fullscreen) {
  721. if (!fullscreen) {
  722. var ratio = this.body.offsetWidth / document.body.offsetWidth,
  723. tables = domUtils.getElementsByTagName(this.body, "table");
  724. utils.each(tables, function(table) {
  725. if (table.offsetWidth < me.body.offsetWidth) return false;
  726. var tds = domUtils.getElementsByTagName(table, "td"),
  727. backWidths = [];
  728. utils.each(tds, function(td) {
  729. backWidths.push(td.offsetWidth);
  730. });
  731. for (var i = 0, td; (td = tds[i]); i++) {
  732. td.setAttribute("width", Math.floor(backWidths[i] * ratio));
  733. }
  734. table.setAttribute(
  735. "width",
  736. Math.floor(getTableWidth(me, needIEHack, getDefaultValue(me)))
  737. );
  738. });
  739. }
  740. });
  741. //重写execCommand命令,用于处理框选时的处理
  742. var oldExecCommand = me.execCommand;
  743. me.execCommand = function(cmd, datatat) {
  744. var me = this,
  745. args = arguments;
  746. cmd = cmd.toLowerCase();
  747. var ut = getUETableBySelected(me),
  748. tds,
  749. range = new dom.Range(me.document),
  750. cmdFun = me.commands[cmd] || UE.commands[cmd],
  751. result;
  752. if (!cmdFun) return;
  753. if (
  754. ut &&
  755. !commands[cmd] &&
  756. !cmdFun.notNeedUndo &&
  757. !me.__hasEnterExecCommand
  758. ) {
  759. me.__hasEnterExecCommand = true;
  760. me.fireEvent("beforeexeccommand", cmd);
  761. tds = ut.selectedTds;
  762. var lastState = -2,
  763. lastValue = -2,
  764. value,
  765. state;
  766. for (var i = 0, td; (td = tds[i]); i++) {
  767. if (isEmptyBlock(td)) {
  768. range.setStart(td, 0).setCursor(false, true);
  769. } else {
  770. range.selectNode(td).select(true);
  771. }
  772. state = me.queryCommandState(cmd);
  773. value = me.queryCommandValue(cmd);
  774. if (state != -1) {
  775. if (lastState !== state || lastValue !== value) {
  776. me._ignoreContentChange = true;
  777. result = oldExecCommand.apply(me, arguments);
  778. me._ignoreContentChange = false;
  779. }
  780. lastState = me.queryCommandState(cmd);
  781. lastValue = me.queryCommandValue(cmd);
  782. if (domUtils.isEmptyBlock(td)) {
  783. domUtils.fillNode(me.document, td);
  784. }
  785. }
  786. }
  787. range.setStart(tds[0], 0).shrinkBoundary(true).setCursor(false, true);
  788. me.fireEvent("contentchange");
  789. me.fireEvent("afterexeccommand", cmd);
  790. me.__hasEnterExecCommand = false;
  791. me._selectionChange();
  792. } else {
  793. result = oldExecCommand.apply(me, arguments);
  794. }
  795. return result;
  796. };
  797. });
  798. /**
  799. * 删除obj的宽高style,改成属性宽高
  800. * @param obj
  801. * @param replaceToProperty
  802. */
  803. function removeStyleSize(obj, replaceToProperty) {
  804. removeStyle(obj, "width", true);
  805. removeStyle(obj, "height", true);
  806. }
  807. function removeStyle(obj, styleName, replaceToProperty) {
  808. if (obj.style[styleName]) {
  809. replaceToProperty &&
  810. obj.setAttribute(styleName, parseInt(obj.style[styleName], 10));
  811. obj.style[styleName] = "";
  812. }
  813. }
  814. function getParentTdOrTh(ele) {
  815. if (ele.tagName == "TD" || ele.tagName == "TH") return ele;
  816. var td;
  817. if (
  818. (td =
  819. domUtils.findParentByTagName(ele, "td", true) ||
  820. domUtils.findParentByTagName(ele, "th", true))
  821. )
  822. return td;
  823. return null;
  824. }
  825. function isEmptyBlock(node) {
  826. var reg = new RegExp(domUtils.fillChar, "g");
  827. if (
  828. node[browser.ie ? "innerText" : "textContent"]
  829. .replace(/^\s*$/, "")
  830. .replace(reg, "").length > 0
  831. ) {
  832. return 0;
  833. }
  834. for (var n in dtd.$isNotEmpty) {
  835. if (node.getElementsByTagName(n).length) {
  836. return 0;
  837. }
  838. }
  839. return 1;
  840. }
  841. function mouseCoords(evt) {
  842. if (evt.pageX || evt.pageY) {
  843. return { x: evt.pageX, y: evt.pageY };
  844. }
  845. return {
  846. x:
  847. evt.clientX + me.document.body.scrollLeft - me.document.body.clientLeft,
  848. y: evt.clientY + me.document.body.scrollTop - me.document.body.clientTop
  849. };
  850. }
  851. function mouseMoveEvent(evt) {
  852. if (isEditorDisabled()) {
  853. return;
  854. }
  855. try {
  856. //普通状态下鼠标移动
  857. var target = getParentTdOrTh(evt.target || evt.srcElement),
  858. pos;
  859. //区分用户的行为是拖动还是双击
  860. if (isInResizeBuffer) {
  861. me.body.style.webkitUserSelect = "none";
  862. if (
  863. Math.abs(userActionStatus.x - evt.clientX) > offsetOfTableCell ||
  864. Math.abs(userActionStatus.y - evt.clientY) > offsetOfTableCell
  865. ) {
  866. clearTableDragTimer();
  867. isInResizeBuffer = false;
  868. singleClickState = 0;
  869. //drag action
  870. tableBorderDrag(evt);
  871. }
  872. }
  873. //修改单元格大小时的鼠标移动
  874. if (onDrag && dragTd) {
  875. singleClickState = 0;
  876. me.body.style.webkitUserSelect = "none";
  877. me.selection.getNative()[
  878. browser.ie9below ? "empty" : "removeAllRanges"
  879. ]();
  880. pos = mouseCoords(evt);
  881. toggleDraggableState(me, true, onDrag, pos, target);
  882. if (onDrag == "h") {
  883. dragLine.style.left = getPermissionX(dragTd, evt) + "px";
  884. } else if (onDrag == "v") {
  885. dragLine.style.top = getPermissionY(dragTd, evt) + "px";
  886. }
  887. return;
  888. }
  889. //当鼠标处于table上时,修改移动过程中的光标状态
  890. if (target) {
  891. //针对使用table作为容器的组件不触发拖拽效果
  892. if (me.fireEvent("excludetable", target) === true) return;
  893. pos = mouseCoords(evt);
  894. var state = getRelation(target, pos),
  895. table = domUtils.findParentByTagName(target, "table", true);
  896. if (inTableSide(table, target, evt, true)) {
  897. if (me.fireEvent("excludetable", table) === true) return;
  898. me.body.style.cursor =
  899. "url(" + me.options.cursorpath + "h.png),pointer";
  900. } else if (inTableSide(table, target, evt)) {
  901. if (me.fireEvent("excludetable", table) === true) return;
  902. me.body.style.cursor =
  903. "url(" + me.options.cursorpath + "v.png),pointer";
  904. } else {
  905. me.body.style.cursor = "text";
  906. var curCell = target;
  907. if (/\d/.test(state)) {
  908. state = state.replace(/\d/, "");
  909. target = getUETable(target).getPreviewCell(target, state == "v");
  910. }
  911. //位于第一行的顶部或者第一列的左边时不可拖动
  912. toggleDraggableState(
  913. me,
  914. target ? !!state : false,
  915. target ? state : "",
  916. pos,
  917. target
  918. );
  919. }
  920. } else {
  921. toggleDragButton(false, table, me);
  922. }
  923. } catch (e) {
  924. showError(e);
  925. }
  926. }
  927. var dragButtonTimer;
  928. function toggleDragButton(show, table, editor) {
  929. if (!show) {
  930. if (dragOver) return;
  931. dragButtonTimer = setTimeout(function() {
  932. !dragOver &&
  933. dragButton &&
  934. dragButton.parentNode &&
  935. dragButton.parentNode.removeChild(dragButton);
  936. }, 2000);
  937. } else {
  938. createDragButton(table, editor);
  939. }
  940. }
  941. function createDragButton(table, editor) {
  942. var pos = domUtils.getXY(table),
  943. doc = table.ownerDocument;
  944. if (dragButton && dragButton.parentNode) return dragButton;
  945. dragButton = doc.createElement("div");
  946. dragButton.contentEditable = false;
  947. dragButton.innerHTML = "";
  948. dragButton.style.cssText =
  949. "width:15px;height:15px;background-image:url(" +
  950. editor.options.UEDITOR_HOME_URL +
  951. "dialogs/table/dragicon.png);position: absolute;cursor:move;top:" +
  952. (pos.y - 15) +
  953. "px;left:" +
  954. pos.x +
  955. "px;";
  956. domUtils.unSelectable(dragButton);
  957. dragButton.onmouseover = function(evt) {
  958. dragOver = true;
  959. };
  960. dragButton.onmouseout = function(evt) {
  961. dragOver = false;
  962. };
  963. domUtils.on(dragButton, "click", function(type, evt) {
  964. doClick(evt, this);
  965. });
  966. domUtils.on(dragButton, "dblclick", function(type, evt) {
  967. doDblClick(evt);
  968. });
  969. domUtils.on(dragButton, "dragstart", function(type, evt) {
  970. domUtils.preventDefault(evt);
  971. });
  972. var timer;
  973. function doClick(evt, button) {
  974. // 部分浏览器下需要清理
  975. clearTimeout(timer);
  976. timer = setTimeout(function() {
  977. editor.fireEvent("tableClicked", table, button);
  978. }, 300);
  979. }
  980. function doDblClick(evt) {
  981. clearTimeout(timer);
  982. var ut = getUETable(table),
  983. start = table.rows[0].cells[0],
  984. end = ut.getLastCell(),
  985. range = ut.getCellsRange(start, end);
  986. editor.selection.getRange().setStart(start, 0).setCursor(false, true);
  987. ut.setSelected(range);
  988. }
  989. doc.body.appendChild(dragButton);
  990. }
  991. // function inPosition(table, pos) {
  992. // var tablePos = domUtils.getXY(table),
  993. // width = table.offsetWidth,
  994. // height = table.offsetHeight;
  995. // if (pos.x - tablePos.x < 5 && pos.y - tablePos.y < 5) {
  996. // return "topLeft";
  997. // } else if (tablePos.x + width - pos.x < 5 && tablePos.y + height - pos.y < 5) {
  998. // return "bottomRight";
  999. // }
  1000. // }
  1001. function inTableSide(table, cell, evt, top) {
  1002. var pos = mouseCoords(evt),
  1003. state = getRelation(cell, pos);
  1004. if (top) {
  1005. var caption = table.getElementsByTagName("caption")[0],
  1006. capHeight = caption ? caption.offsetHeight : 0;
  1007. return state == "v1" && pos.y - domUtils.getXY(table).y - capHeight < 8;
  1008. } else {
  1009. return state == "h1" && pos.x - domUtils.getXY(table).x < 8;
  1010. }
  1011. }
  1012. /**
  1013. * 获取拖动时允许的X轴坐标
  1014. * @param dragTd
  1015. * @param evt
  1016. */
  1017. function getPermissionX(dragTd, evt) {
  1018. var ut = getUETable(dragTd);
  1019. if (ut) {
  1020. var preTd = ut.getSameEndPosCells(dragTd, "x")[0],
  1021. nextTd = ut.getSameStartPosXCells(dragTd)[0],
  1022. mouseX = mouseCoords(evt).x,
  1023. left =
  1024. (preTd ? domUtils.getXY(preTd).x : domUtils.getXY(ut.table).x) + 20,
  1025. right = nextTd
  1026. ? domUtils.getXY(nextTd).x + nextTd.offsetWidth - 20
  1027. : me.body.offsetWidth + 5 ||
  1028. parseInt(domUtils.getComputedStyle(me.body, "width"), 10);
  1029. left += cellMinWidth;
  1030. right -= cellMinWidth;
  1031. return mouseX < left ? left : mouseX > right ? right : mouseX;
  1032. }
  1033. }
  1034. /**
  1035. * 获取拖动时允许的Y轴坐标
  1036. */
  1037. function getPermissionY(dragTd, evt) {
  1038. try {
  1039. var top = domUtils.getXY(dragTd).y,
  1040. mousePosY = mouseCoords(evt).y;
  1041. return mousePosY < top ? top : mousePosY;
  1042. } catch (e) {
  1043. showError(e);
  1044. }
  1045. }
  1046. /**
  1047. * 移动状态切换
  1048. */
  1049. function toggleDraggableState(editor, draggable, dir, mousePos, cell) {
  1050. try {
  1051. editor.body.style.cursor = dir == "h"
  1052. ? "col-resize"
  1053. : dir == "v" ? "row-resize" : "text";
  1054. if (browser.ie) {
  1055. if (dir && !mousedown && !getUETableBySelected(editor)) {
  1056. getDragLine(editor, editor.document);
  1057. showDragLineAt(dir, cell);
  1058. } else {
  1059. hideDragLine(editor);
  1060. }
  1061. }
  1062. onBorder = draggable;
  1063. } catch (e) {
  1064. showError(e);
  1065. }
  1066. }
  1067. /**
  1068. * 获取与UETable相关的resize line
  1069. * @param uetable UETable对象
  1070. */
  1071. function getResizeLineByUETable() {
  1072. var lineId = "_UETableResizeLine",
  1073. line = this.document.getElementById(lineId);
  1074. if (!line) {
  1075. line = this.document.createElement("div");
  1076. line.id = lineId;
  1077. line.contnetEditable = false;
  1078. line.setAttribute("unselectable", "on");
  1079. var styles = {
  1080. width: 2 * cellBorderWidth + 1 + "px",
  1081. position: "absolute",
  1082. "z-index": 100000,
  1083. cursor: "col-resize",
  1084. background: "red",
  1085. display: "none"
  1086. };
  1087. //切换状态
  1088. line.onmouseout = function() {
  1089. this.style.display = "none";
  1090. };
  1091. utils.extend(line.style, styles);
  1092. this.document.body.appendChild(line);
  1093. }
  1094. return line;
  1095. }
  1096. /**
  1097. * 更新resize-line
  1098. */
  1099. function updateResizeLine(cell, uetable) {
  1100. var line = getResizeLineByUETable.call(this),
  1101. table = uetable.table,
  1102. styles = {
  1103. top: domUtils.getXY(table).y + "px",
  1104. left:
  1105. domUtils.getXY(cell).x + cell.offsetWidth - cellBorderWidth + "px",
  1106. display: "block",
  1107. height: table.offsetHeight + "px"
  1108. };
  1109. utils.extend(line.style, styles);
  1110. }
  1111. /**
  1112. * 显示resize-line
  1113. */
  1114. function showResizeLine(cell) {
  1115. var uetable = getUETable(cell);
  1116. updateResizeLine.call(this, cell, uetable);
  1117. }
  1118. /**
  1119. * 获取鼠标与当前单元格的相对位置
  1120. * @param ele
  1121. * @param mousePos
  1122. */
  1123. function getRelation(ele, mousePos) {
  1124. var elePos = domUtils.getXY(ele);
  1125. if (!elePos) {
  1126. return "";
  1127. }
  1128. if (elePos.x + ele.offsetWidth - mousePos.x < cellBorderWidth) {
  1129. return "h";
  1130. }
  1131. if (mousePos.x - elePos.x < cellBorderWidth) {
  1132. return "h1";
  1133. }
  1134. if (elePos.y + ele.offsetHeight - mousePos.y < cellBorderWidth) {
  1135. return "v";
  1136. }
  1137. if (mousePos.y - elePos.y < cellBorderWidth) {
  1138. return "v1";
  1139. }
  1140. return "";
  1141. }
  1142. function mouseDownEvent(type, evt) {
  1143. if (isEditorDisabled()) {
  1144. return;
  1145. }
  1146. userActionStatus = {
  1147. x: evt.clientX,
  1148. y: evt.clientY
  1149. };
  1150. //右键菜单单独处理
  1151. if (evt.button == 2) {
  1152. var ut = getUETableBySelected(me),
  1153. flag = false;
  1154. if (ut) {
  1155. var td = getTargetTd(me, evt);
  1156. utils.each(ut.selectedTds, function(ti) {
  1157. if (ti === td) {
  1158. flag = true;
  1159. }
  1160. });
  1161. if (!flag) {
  1162. removeSelectedClass(domUtils.getElementsByTagName(me.body, "th td"));
  1163. ut.clearSelected();
  1164. } else {
  1165. td = ut.selectedTds[0];
  1166. setTimeout(function() {
  1167. me.selection.getRange().setStart(td, 0).setCursor(false, true);
  1168. }, 0);
  1169. }
  1170. }
  1171. } else {
  1172. tableClickHander(evt);
  1173. }
  1174. }
  1175. //清除表格的计时器
  1176. function clearTableTimer() {
  1177. tabTimer && clearTimeout(tabTimer);
  1178. tabTimer = null;
  1179. }
  1180. //双击收缩
  1181. function tableDbclickHandler(evt) {
  1182. singleClickState = 0;
  1183. evt = evt || me.window.event;
  1184. var target = getParentTdOrTh(evt.target || evt.srcElement);
  1185. if (target) {
  1186. var h;
  1187. if ((h = getRelation(target, mouseCoords(evt)))) {
  1188. hideDragLine(me);
  1189. if (h == "h1") {
  1190. h = "h";
  1191. if (
  1192. inTableSide(
  1193. domUtils.findParentByTagName(target, "table"),
  1194. target,
  1195. evt
  1196. )
  1197. ) {
  1198. me.execCommand("adaptbywindow");
  1199. } else {
  1200. target = getUETable(target).getPreviewCell(target);
  1201. if (target) {
  1202. var rng = me.selection.getRange();
  1203. rng.selectNodeContents(target).setCursor(true, true);
  1204. }
  1205. }
  1206. }
  1207. if (h == "h") {
  1208. var ut = getUETable(target),
  1209. table = ut.table,
  1210. cells = getCellsByMoveBorder(target, table, true);
  1211. cells = extractArray(cells, "left");
  1212. ut.width = ut.offsetWidth;
  1213. var oldWidth = [],
  1214. newWidth = [];
  1215. utils.each(cells, function(cell) {
  1216. oldWidth.push(cell.offsetWidth);
  1217. });
  1218. utils.each(cells, function(cell) {
  1219. cell.removeAttribute("width");
  1220. });
  1221. window.setTimeout(function() {
  1222. //是否允许改变
  1223. var changeable = true;
  1224. utils.each(cells, function(cell, index) {
  1225. var width = cell.offsetWidth;
  1226. if (width > oldWidth[index]) {
  1227. changeable = false;
  1228. return false;
  1229. }
  1230. newWidth.push(width);
  1231. });
  1232. var change = changeable ? newWidth : oldWidth;
  1233. utils.each(cells, function(cell, index) {
  1234. cell.width = change[index] - getTabcellSpace();
  1235. });
  1236. }, 0);
  1237. // minWidth -= cellMinWidth;
  1238. //
  1239. // table.removeAttribute("width");
  1240. // utils.each(cells, function (cell) {
  1241. // cell.style.width = "";
  1242. // cell.width -= minWidth;
  1243. // });
  1244. }
  1245. }
  1246. }
  1247. }
  1248. function tableClickHander(evt) {
  1249. removeSelectedClass(domUtils.getElementsByTagName(me.body, "td th"));
  1250. //trace:3113
  1251. //选中单元格,点击table外部,不会清掉table上挂的ueTable,会引起getUETableBySelected方法返回值
  1252. utils.each(me.document.getElementsByTagName("table"), function(t) {
  1253. t.ueTable = null;
  1254. });
  1255. startTd = getTargetTd(me, evt);
  1256. if (!startTd) return;
  1257. var table = domUtils.findParentByTagName(startTd, "table", true);
  1258. ut = getUETable(table);
  1259. ut && ut.clearSelected();
  1260. //判断当前鼠标状态
  1261. if (!onBorder) {
  1262. me.document.body.style.webkitUserSelect = "";
  1263. mousedown = true;
  1264. me.addListener("mouseover", mouseOverEvent);
  1265. } else {
  1266. //边框上的动作处理
  1267. borderActionHandler(evt);
  1268. }
  1269. }
  1270. //处理表格边框上的动作, 这里做延时处理,避免两种动作互相影响
  1271. function borderActionHandler(evt) {
  1272. if (browser.ie) {
  1273. evt = reconstruct(evt);
  1274. }
  1275. clearTableDragTimer();
  1276. //是否正在等待resize的缓冲中
  1277. isInResizeBuffer = true;
  1278. tableDragTimer = setTimeout(function() {
  1279. tableBorderDrag(evt);
  1280. }, dblclickTime);
  1281. }
  1282. function extractArray(originArr, key) {
  1283. var result = [],
  1284. tmp = null;
  1285. for (var i = 0, len = originArr.length; i < len; i++) {
  1286. tmp = originArr[i][key];
  1287. if (tmp) {
  1288. result.push(tmp);
  1289. }
  1290. }
  1291. return result;
  1292. }
  1293. function clearTableDragTimer() {
  1294. tableDragTimer && clearTimeout(tableDragTimer);
  1295. tableDragTimer = null;
  1296. }
  1297. function reconstruct(obj) {
  1298. var attrs = [
  1299. "pageX",
  1300. "pageY",
  1301. "clientX",
  1302. "clientY",
  1303. "srcElement",
  1304. "target"
  1305. ],
  1306. newObj = {};
  1307. if (obj) {
  1308. for (var i = 0, key, val; (key = attrs[i]); i++) {
  1309. val = obj[key];
  1310. val && (newObj[key] = val);
  1311. }
  1312. }
  1313. return newObj;
  1314. }
  1315. //边框拖动
  1316. function tableBorderDrag(evt) {
  1317. isInResizeBuffer = false;
  1318. startTd = evt.target || evt.srcElement;
  1319. if (!startTd) return;
  1320. var state = getRelation(startTd, mouseCoords(evt));
  1321. if (/\d/.test(state)) {
  1322. state = state.replace(/\d/, "");
  1323. startTd = getUETable(startTd).getPreviewCell(startTd, state == "v");
  1324. }
  1325. hideDragLine(me);
  1326. getDragLine(me, me.document);
  1327. me.fireEvent("saveScene");
  1328. showDragLineAt(state, startTd);
  1329. mousedown = true;
  1330. //拖动开始
  1331. onDrag = state;
  1332. dragTd = startTd;
  1333. }
  1334. function mouseUpEvent(type, evt) {
  1335. if (isEditorDisabled()) {
  1336. return;
  1337. }
  1338. clearTableDragTimer();
  1339. isInResizeBuffer = false;
  1340. if (onBorder) {
  1341. singleClickState = ++singleClickState % 3;
  1342. userActionStatus = {
  1343. x: evt.clientX,
  1344. y: evt.clientY
  1345. };
  1346. tableResizeTimer = setTimeout(function() {
  1347. singleClickState > 0 && singleClickState--;
  1348. }, dblclickTime);
  1349. if (singleClickState === 2) {
  1350. singleClickState = 0;
  1351. tableDbclickHandler(evt);
  1352. return;
  1353. }
  1354. }
  1355. if (evt.button == 2) return;
  1356. var me = this;
  1357. //清除表格上原生跨选问题
  1358. var range = me.selection.getRange(),
  1359. start = domUtils.findParentByTagName(range.startContainer, "table", true),
  1360. end = domUtils.findParentByTagName(range.endContainer, "table", true);
  1361. if (start || end) {
  1362. if (start === end) {
  1363. start = domUtils.findParentByTagName(
  1364. range.startContainer,
  1365. ["td", "th", "caption"],
  1366. true
  1367. );
  1368. end = domUtils.findParentByTagName(
  1369. range.endContainer,
  1370. ["td", "th", "caption"],
  1371. true
  1372. );
  1373. if (start !== end) {
  1374. me.selection.clearRange();
  1375. }
  1376. } else {
  1377. me.selection.clearRange();
  1378. }
  1379. }
  1380. mousedown = false;
  1381. me.document.body.style.webkitUserSelect = "";
  1382. //拖拽状态下的mouseUP
  1383. if (onDrag && dragTd) {
  1384. me.selection.getNative()[
  1385. browser.ie9below ? "empty" : "removeAllRanges"
  1386. ]();
  1387. singleClickState = 0;
  1388. dragLine = me.document.getElementById("ue_tableDragLine");
  1389. // trace 3973
  1390. if (dragLine) {
  1391. var dragTdPos = domUtils.getXY(dragTd),
  1392. dragLinePos = domUtils.getXY(dragLine);
  1393. switch (onDrag) {
  1394. case "h":
  1395. changeColWidth(dragTd, dragLinePos.x - dragTdPos.x);
  1396. break;
  1397. case "v":
  1398. changeRowHeight(
  1399. dragTd,
  1400. dragLinePos.y - dragTdPos.y - dragTd.offsetHeight
  1401. );
  1402. break;
  1403. default:
  1404. }
  1405. onDrag = "";
  1406. dragTd = null;
  1407. hideDragLine(me);
  1408. me.fireEvent("saveScene");
  1409. return;
  1410. }
  1411. }
  1412. //正常状态下的mouseup
  1413. if (!startTd) {
  1414. var target = domUtils.findParentByTagName(
  1415. evt.target || evt.srcElement,
  1416. "td",
  1417. true
  1418. );
  1419. if (!target)
  1420. target = domUtils.findParentByTagName(
  1421. evt.target || evt.srcElement,
  1422. "th",
  1423. true
  1424. );
  1425. if (target && (target.tagName == "TD" || target.tagName == "TH")) {
  1426. if (me.fireEvent("excludetable", target) === true) return;
  1427. range = new dom.Range(me.document);
  1428. range.setStart(target, 0).setCursor(false, true);
  1429. }
  1430. } else {
  1431. var ut = getUETable(startTd),
  1432. cell = ut ? ut.selectedTds[0] : null;
  1433. if (cell) {
  1434. range = new dom.Range(me.document);
  1435. if (domUtils.isEmptyBlock(cell)) {
  1436. range.setStart(cell, 0).setCursor(false, true);
  1437. } else {
  1438. range
  1439. .selectNodeContents(cell)
  1440. .shrinkBoundary()
  1441. .setCursor(false, true);
  1442. }
  1443. } else {
  1444. range = me.selection.getRange().shrinkBoundary();
  1445. if (!range.collapsed) {
  1446. var start = domUtils.findParentByTagName(
  1447. range.startContainer,
  1448. ["td", "th"],
  1449. true
  1450. ),
  1451. end = domUtils.findParentByTagName(
  1452. range.endContainer,
  1453. ["td", "th"],
  1454. true
  1455. );
  1456. //在table里边的不能清除
  1457. if (
  1458. (start && !end) ||
  1459. (!start && end) ||
  1460. (start && end && start !== end)
  1461. ) {
  1462. range.setCursor(false, true);
  1463. }
  1464. }
  1465. }
  1466. startTd = null;
  1467. me.removeListener("mouseover", mouseOverEvent);
  1468. }
  1469. me._selectionChange(250, evt);
  1470. }
  1471. function mouseOverEvent(type, evt) {
  1472. if (isEditorDisabled()) {
  1473. return;
  1474. }
  1475. var me = this,
  1476. tar = evt.target || evt.srcElement;
  1477. currentTd =
  1478. domUtils.findParentByTagName(tar, "td", true) ||
  1479. domUtils.findParentByTagName(tar, "th", true);
  1480. //需要判断两个TD是否位于同一个表格内
  1481. if (
  1482. startTd &&
  1483. currentTd &&
  1484. ((startTd.tagName == "TD" && currentTd.tagName == "TD") ||
  1485. (startTd.tagName == "TH" && currentTd.tagName == "TH")) &&
  1486. domUtils.findParentByTagName(startTd, "table") ==
  1487. domUtils.findParentByTagName(currentTd, "table")
  1488. ) {
  1489. var ut = getUETable(currentTd);
  1490. if (startTd != currentTd) {
  1491. me.document.body.style.webkitUserSelect = "none";
  1492. me.selection.getNative()[
  1493. browser.ie9below ? "empty" : "removeAllRanges"
  1494. ]();
  1495. var range = ut.getCellsRange(startTd, currentTd);
  1496. ut.setSelected(range);
  1497. } else {
  1498. me.document.body.style.webkitUserSelect = "";
  1499. ut.clearSelected();
  1500. }
  1501. }
  1502. evt.preventDefault ? evt.preventDefault() : (evt.returnValue = false);
  1503. }
  1504. function setCellHeight(cell, height, backHeight) {
  1505. var lineHight = parseInt(
  1506. domUtils.getComputedStyle(cell, "line-height"),
  1507. 10
  1508. ),
  1509. tmpHeight = backHeight + height;
  1510. height = tmpHeight < lineHight ? lineHight : tmpHeight;
  1511. if (cell.style.height) cell.style.height = "";
  1512. cell.rowSpan == 1
  1513. ? cell.setAttribute("height", height)
  1514. : cell.removeAttribute && cell.removeAttribute("height");
  1515. }
  1516. function getWidth(cell) {
  1517. if (!cell) return 0;
  1518. return parseInt(domUtils.getComputedStyle(cell, "width"), 10);
  1519. }
  1520. function changeColWidth(cell, changeValue) {
  1521. var ut = getUETable(cell);
  1522. if (ut) {
  1523. //根据当前移动的边框获取相关的单元格
  1524. var table = ut.table,
  1525. cells = getCellsByMoveBorder(cell, table);
  1526. table.style.width = "";
  1527. table.removeAttribute("width");
  1528. //修正改变量
  1529. changeValue = correctChangeValue(changeValue, cell, cells);
  1530. if (cell.nextSibling) {
  1531. var i = 0;
  1532. utils.each(cells, function(cellGroup) {
  1533. cellGroup.left.width = +cellGroup.left.width + changeValue;
  1534. cellGroup.right &&
  1535. (cellGroup.right.width = +cellGroup.right.width - changeValue);
  1536. });
  1537. } else {
  1538. utils.each(cells, function(cellGroup) {
  1539. cellGroup.left.width -= -changeValue;
  1540. });
  1541. }
  1542. }
  1543. }
  1544. function isEditorDisabled() {
  1545. return me.body.contentEditable === "false";
  1546. }
  1547. function changeRowHeight(td, changeValue) {
  1548. if (Math.abs(changeValue) < 10) return;
  1549. var ut = getUETable(td);
  1550. if (ut) {
  1551. var cells = ut.getSameEndPosCells(td, "y"),
  1552. //备份需要连带变化的td的原始高度,否则后期无法获取正确的值
  1553. backHeight = cells[0] ? cells[0].offsetHeight : 0;
  1554. for (var i = 0, cell; (cell = cells[i++]); ) {
  1555. setCellHeight(cell, changeValue, backHeight);
  1556. }
  1557. }
  1558. }
  1559. /**
  1560. * 获取调整单元格大小的相关单元格
  1561. * @isContainMergeCell 返回的结果中是否包含发生合并后的单元格
  1562. */
  1563. function getCellsByMoveBorder(cell, table, isContainMergeCell) {
  1564. if (!table) {
  1565. table = domUtils.findParentByTagName(cell, "table");
  1566. }
  1567. if (!table) {
  1568. return null;
  1569. }
  1570. //获取到该单元格所在行的序列号
  1571. var index = domUtils.getNodeIndex(cell),
  1572. temp = cell,
  1573. rows = table.rows,
  1574. colIndex = 0;
  1575. while (temp) {
  1576. //获取到当前单元格在未发生单元格合并时的序列
  1577. if (temp.nodeType === 1) {
  1578. colIndex += temp.colSpan || 1;
  1579. }
  1580. temp = temp.previousSibling;
  1581. }
  1582. temp = null;
  1583. //记录想关的单元格
  1584. var borderCells = [];
  1585. utils.each(rows, function(tabRow) {
  1586. var cells = tabRow.cells,
  1587. currIndex = 0;
  1588. utils.each(cells, function(tabCell) {
  1589. currIndex += tabCell.colSpan || 1;
  1590. if (currIndex === colIndex) {
  1591. borderCells.push({
  1592. left: tabCell,
  1593. right: tabCell.nextSibling || null
  1594. });
  1595. return false;
  1596. } else if (currIndex > colIndex) {
  1597. if (isContainMergeCell) {
  1598. borderCells.push({
  1599. left: tabCell
  1600. });
  1601. }
  1602. return false;
  1603. }
  1604. });
  1605. });
  1606. return borderCells;
  1607. }
  1608. /**
  1609. * 通过给定的单元格集合获取最小的单元格width
  1610. */
  1611. function getMinWidthByTableCells(cells) {
  1612. var minWidth = Number.MAX_VALUE;
  1613. for (var i = 0, curCell; (curCell = cells[i]); i++) {
  1614. minWidth = Math.min(
  1615. minWidth,
  1616. curCell.width || getTableCellWidth(curCell)
  1617. );
  1618. }
  1619. return minWidth;
  1620. }
  1621. function correctChangeValue(changeValue, relatedCell, cells) {
  1622. //为单元格的paading预留空间
  1623. changeValue -= getTabcellSpace();
  1624. if (changeValue < 0) {
  1625. return 0;
  1626. }
  1627. changeValue -= getTableCellWidth(relatedCell);
  1628. //确定方向
  1629. var direction = changeValue < 0 ? "left" : "right";
  1630. changeValue = Math.abs(changeValue);
  1631. //只关心非最后一个单元格就可以
  1632. utils.each(cells, function(cellGroup) {
  1633. var curCell = cellGroup[direction];
  1634. //为单元格保留最小空间
  1635. if (curCell) {
  1636. changeValue = Math.min(
  1637. changeValue,
  1638. getTableCellWidth(curCell) - cellMinWidth
  1639. );
  1640. }
  1641. });
  1642. //修正越界
  1643. changeValue = changeValue < 0 ? 0 : changeValue;
  1644. return direction === "left" ? -changeValue : changeValue;
  1645. }
  1646. function getTableCellWidth(cell) {
  1647. var width = 0,
  1648. //偏移纠正量
  1649. offset = 0,
  1650. width = cell.offsetWidth - getTabcellSpace();
  1651. //最后一个节点纠正一下
  1652. if (!cell.nextSibling) {
  1653. width -= getTableCellOffset(cell);
  1654. }
  1655. width = width < 0 ? 0 : width;
  1656. try {
  1657. cell.width = width;
  1658. } catch (e) {}
  1659. return width;
  1660. }
  1661. /**
  1662. * 获取单元格所在表格的最末单元格的偏移量
  1663. */
  1664. function getTableCellOffset(cell) {
  1665. tab = domUtils.findParentByTagName(cell, "table", false);
  1666. if (tab.offsetVal === undefined) {
  1667. var prev = cell.previousSibling;
  1668. if (prev) {
  1669. //最后一个单元格和前一个单元格的width diff结果 如果恰好为一个border width, 则条件成立
  1670. tab.offsetVal = cell.offsetWidth - prev.offsetWidth === UT.borderWidth
  1671. ? UT.borderWidth
  1672. : 0;
  1673. } else {
  1674. tab.offsetVal = 0;
  1675. }
  1676. }
  1677. return tab.offsetVal;
  1678. }
  1679. function getTabcellSpace() {
  1680. if (UT.tabcellSpace === undefined) {
  1681. var cell = null,
  1682. tab = me.document.createElement("table"),
  1683. tbody = me.document.createElement("tbody"),
  1684. trow = me.document.createElement("tr"),
  1685. tabcell = me.document.createElement("td"),
  1686. mirror = null;
  1687. tabcell.style.cssText = "border: 0;";
  1688. tabcell.width = 1;
  1689. trow.appendChild(tabcell);
  1690. trow.appendChild((mirror = tabcell.cloneNode(false)));
  1691. tbody.appendChild(trow);
  1692. tab.appendChild(tbody);
  1693. tab.style.cssText = "visibility: hidden;";
  1694. me.body.appendChild(tab);
  1695. UT.paddingSpace = tabcell.offsetWidth - 1;
  1696. var tmpTabWidth = tab.offsetWidth;
  1697. tabcell.style.cssText = "";
  1698. mirror.style.cssText = "";
  1699. UT.borderWidth = (tab.offsetWidth - tmpTabWidth) / 3;
  1700. UT.tabcellSpace = UT.paddingSpace + UT.borderWidth;
  1701. me.body.removeChild(tab);
  1702. }
  1703. getTabcellSpace = function() {
  1704. return UT.tabcellSpace;
  1705. };
  1706. return UT.tabcellSpace;
  1707. }
  1708. function getDragLine(editor, doc) {
  1709. if (mousedown) return;
  1710. dragLine = editor.document.createElement("div");
  1711. domUtils.setAttributes(dragLine, {
  1712. id: "ue_tableDragLine",
  1713. unselectable: "on",
  1714. contenteditable: false,
  1715. onresizestart: "return false",
  1716. ondragstart: "return false",
  1717. onselectstart: "return false",
  1718. style:
  1719. "background-color:blue;position:absolute;padding:0;margin:0;background-image:none;border:0px none;opacity:0;filter:alpha(opacity=0)"
  1720. });
  1721. editor.body.appendChild(dragLine);
  1722. }
  1723. function hideDragLine(editor) {
  1724. if (mousedown) return;
  1725. var line;
  1726. while ((line = editor.document.getElementById("ue_tableDragLine"))) {
  1727. domUtils.remove(line);
  1728. }
  1729. }
  1730. /**
  1731. * 依据state(v|h)在cell位置显示横线
  1732. * @param state
  1733. * @param cell
  1734. */
  1735. function showDragLineAt(state, cell) {
  1736. if (!cell) return;
  1737. var table = domUtils.findParentByTagName(cell, "table"),
  1738. caption = table.getElementsByTagName("caption"),
  1739. width = table.offsetWidth,
  1740. height =
  1741. table.offsetHeight - (caption.length > 0 ? caption[0].offsetHeight : 0),
  1742. tablePos = domUtils.getXY(table),
  1743. cellPos = domUtils.getXY(cell),
  1744. css;
  1745. switch (state) {
  1746. case "h":
  1747. css =
  1748. "height:" +
  1749. height +
  1750. "px;top:" +
  1751. (tablePos.y + (caption.length > 0 ? caption[0].offsetHeight : 0)) +
  1752. "px;left:" +
  1753. (cellPos.x + cell.offsetWidth);
  1754. dragLine.style.cssText =
  1755. css +
  1756. "px;position: absolute;display:block;background-color:blue;width:1px;border:0; color:blue;opacity:.3;filter:alpha(opacity=30)";
  1757. break;
  1758. case "v":
  1759. css =
  1760. "width:" +
  1761. width +
  1762. "px;left:" +
  1763. tablePos.x +
  1764. "px;top:" +
  1765. (cellPos.y + cell.offsetHeight);
  1766. //必须加上border:0和color:blue,否则低版ie不支持背景色显示
  1767. dragLine.style.cssText =
  1768. css +
  1769. "px;overflow:hidden;position: absolute;display:block;background-color:blue;height:1px;border:0;color:blue;opacity:.2;filter:alpha(opacity=20)";
  1770. break;
  1771. default:
  1772. }
  1773. }
  1774. /**
  1775. * 当表格边框颜色为白色时设置为虚线,true为添加虚线
  1776. * @param editor
  1777. * @param flag
  1778. */
  1779. function switchBorderColor(editor, flag) {
  1780. var tableArr = domUtils.getElementsByTagName(editor.body, "table"),
  1781. color;
  1782. for (var i = 0, node; (node = tableArr[i++]); ) {
  1783. var td = domUtils.getElementsByTagName(node, "td");
  1784. if (td[0]) {
  1785. if (flag) {
  1786. color = td[0].style.borderColor.replace(/\s/g, "");
  1787. if (/(#ffffff)|(rgb\(255,255,255\))/gi.test(color))
  1788. domUtils.addClass(node, "noBorderTable");
  1789. } else {
  1790. domUtils.removeClasses(node, "noBorderTable");
  1791. }
  1792. }
  1793. }
  1794. }
  1795. function getTableWidth(editor, needIEHack, defaultValue) {
  1796. var body = editor.body;
  1797. return (
  1798. body.offsetWidth -
  1799. (needIEHack
  1800. ? parseInt(domUtils.getComputedStyle(body, "margin-left"), 10) * 2
  1801. : 0) -
  1802. defaultValue.tableBorder * 2 -
  1803. (editor.options.offsetWidth || 0)
  1804. );
  1805. }
  1806. /**
  1807. * 获取当前拖动的单元格
  1808. */
  1809. function getTargetTd(editor, evt) {
  1810. var target = domUtils.findParentByTagName(
  1811. evt.target || evt.srcElement,
  1812. ["td", "th"],
  1813. true
  1814. ),
  1815. dir = null;
  1816. if (!target) {
  1817. return null;
  1818. }
  1819. dir = getRelation(target, mouseCoords(evt));
  1820. //如果有前一个节点, 需要做一个修正, 否则可能会得到一个错误的td
  1821. if (!target) {
  1822. return null;
  1823. }
  1824. if (dir === "h1" && target.previousSibling) {
  1825. var position = domUtils.getXY(target),
  1826. cellWidth = target.offsetWidth;
  1827. if (Math.abs(position.x + cellWidth - evt.clientX) > cellWidth / 3) {
  1828. target = target.previousSibling;
  1829. }
  1830. } else if (dir === "v1" && target.parentNode.previousSibling) {
  1831. var position = domUtils.getXY(target),
  1832. cellHeight = target.offsetHeight;
  1833. if (Math.abs(position.y + cellHeight - evt.clientY) > cellHeight / 3) {
  1834. target = target.parentNode.previousSibling.firstChild;
  1835. }
  1836. }
  1837. //排除了非td内部以及用于代码高亮部分的td
  1838. return target && !(editor.fireEvent("excludetable", target) === true)
  1839. ? target
  1840. : null;
  1841. }
  1842. };