1 /**
  2  * table dialog
  3  * @author yiminghe@gmail.com
  4  */
  5 KISSY.add("editor/plugin/table/dialog", function (S, Editor, Overlay4E, MenuButton) {
  6     var Node = S.Node,
  7         DOM = S.DOM,
  8         UA = S.UA,
  9         trim = S.trim,
 10         showBorderClassName = "ke_show_border",
 11         collapseTableClass = "k-e-collapse-table",
 12         Dialog = Overlay4E.Dialog,
 13         IN_SIZE = 6,
 14         alignStyle = 'margin-left:2px;',
 15         MIDDLE = "vertical-align:middle;",
 16         TABLE_HTML = "<div style='padding:20px 20px 10px 20px;'>" +
 17             "<table class='ks-editor-table-config' style='width:100%'>" +
 18             "<tr>" +
 19             "<td>" +
 20             "<label>行数: " +
 21             "<input " +
 22             " data-verify='^(?!0$)\\d+$' " +
 23             " data-warning='行数请输入正整数' " +
 24             " value='2' " +
 25             " class='ks-editor-table-rows ks-editor-table-create-only ks-editor-input' " +
 26             "style='" + alignStyle + MIDDLE + "'" +
 27             " size='" +
 28             IN_SIZE +
 29             "'" +
 30             " />" +
 31             "</label>" +
 32             "</td>" +
 33             "<td>" +
 34             "<label>宽   度: " +
 35             "<input " +
 36             " data-verify='^(?!0$)\\d+$' " +
 37             " data-warning='宽度请输入正整数' " +
 38             "value='200' " +
 39             "style='" +
 40             alignStyle + MIDDLE + "' " +
 41             "class='ks-editor-table-width ks-editor-input' " +
 42             "size='" + IN_SIZE + "'/>" +
 43             "</label> " +
 44             "<select class='ks-editor-table-width-unit' title='宽度单位'>" +
 45             "<option value='px'>像素</option>" +
 46             "<option value='%'>百分比</option>" +
 47             "</select>" +
 48             "</td>" +
 49             "</tr>" +
 50             "<tr>" +
 51             "<td>" +
 52             "<label>列数: " +
 53             "<input " +
 54             " data-verify='^(?!0$)\\d+$' " +
 55             " data-warning='列数请输入正整数' " +
 56             "class='ks-editor-table-cols ks-editor-table-create-only ks-editor-input' " +
 57             "style='" + alignStyle + MIDDLE + "'" +
 58             "value='3' " +
 59             "size='" +
 60             IN_SIZE + "'/>" +
 61             "</label>" +
 62             "</td>" +
 63             "<td>" +
 64             "<label>高   度: " +
 65             "<input " +
 66             " data-verify='^((?!0$)\\d+)?$' " +
 67             " data-warning='高度请输入正整数' " +
 68             "value='' " +
 69             "style='" +
 70             alignStyle + MIDDLE + "'" +
 71             "class='ks-editor-table-height ks-editor-input' " +
 72             "size='" + IN_SIZE + "'/>" +
 73             "</label>  像素" +
 74             "</td>" +
 75             "</tr>" +
 76             "<tr>" +
 77             "<td>" +
 78             "<label>对齐: </label>" +
 79             "<select class='ks-editor-table-align' title='对齐'>" +
 80             "<option value=''>无</option>" +
 81             "<option value='left'>左对齐</option>" +
 82             "<option value='right'>右对齐</option>" +
 83             "<option value='center'>中间对齐</option>" +
 84             "</select>" +
 85             "</td>" +
 86             "<td>" +
 87             "<label>标题格:</label> " +
 88             "<select class='ks-editor-table-head ks-editor-table-create-only' title='标题格'>" +
 89             "<option value=''>无</option>" +
 90             "<option value='1'>有</option>" +
 91             "</select>" +
 92             "</td>" +
 93             "</tr>" +
 94             "<tr>" +
 95             "<td>" +
 96             "<label>边框: " +
 97             "<input " +
 98             " data-verify='^\\d+$' " +
 99             " data-warning='边框请输入非负整数' " +
100             "value='1' " +
101             "style='" +
102             alignStyle + MIDDLE + "'" +
103             "class='ks-editor-table-border ks-editor-input' " +
104             "size='" + IN_SIZE + "'/>" +
105             "</label>  像素" +
106             " " +
107             '<label><input ' +
108             'type="checkbox" ' +
109             'style="vertical-align: middle; margin-left: 5px;" ' +
110             'class="ks-editor-table-collapse" ' +
111             '/> 合并边框' +
112             "</label>" +
113             "</td>" +
114             "<td>" +
115             "<label " +
116             "class='ks-editor-table-cellpadding-holder'" +
117             ">边   距: " +
118             "<input " +
119             " data-verify='^(\\d+)?$' " +
120             " data-warning='边框请输入非负整数' " +
121             "value='0' " +
122             "style='" +
123             alignStyle + MIDDLE + "'" +
124             "class='ks-editor-table-cellpadding ks-editor-input' " +
125             "size='" + IN_SIZE + "'/>" +
126             "  像素</label>" +
127             "</td>" +
128             "</tr>" +
129             "<tr>" +
130             "<td colspan='2'>" +
131             "<label>" +
132             "标题: " +
133             "<input " +
134             "class='ks-editor-table-caption ks-editor-input' " +
135             "style='width:380px;" +
136             alignStyle + MIDDLE + "'>" +
137             "</label>" +
138             "</td>" +
139             "</tr>" +
140             "</table>" +
141             "</div>",
142         footHtml = "<div style='padding:5px 20px 20px;'>" +
143             "<a " +
144             "class='ks-editor-table-ok ks-editor-button ks-inline-block' " +
145             "style='margin-right:20px;'>确定</a> " +
146             "<a " +
147             "class='ks-editor-table-cancel ks-editor-button ks-inline-block'>取消</a>" +
148             "</div>",
149         addRes = Editor.Utils.addRes,
150         destroyRes = Editor.Utils.destroyRes;
151 
152 
153     function valid(str) {
154         return trim(str).length != 0;
155     }
156 
157     function TableDialog(editor) {
158         var self = this;
159         self.editor = editor;
160         Editor.Utils.lazyRun(self, "_prepareTableShow", "_realTableShow");
161     }
162 
163     S.augment(TableDialog, {
164         _tableInit:function () {
165             var self = this,
166                 d = new Dialog({
167                     autoRender:true,
168                     width:"500px",
169                     mask:true,
170                     headerContent:"表格", //属性",
171                     bodyContent:TABLE_HTML,
172                     footerContent:footHtml
173                 }),
174                 dbody = d.get("body"),
175                 foot = d.get("footer");
176             d.twidth = dbody.one(".ks-editor-table-width");
177             d.theight = dbody.one(".ks-editor-table-height");
178             d.tborder = dbody.one(".ks-editor-table-border");
179             d.tcaption = dbody.one(".ks-editor-table-caption");
180             d.talign = MenuButton.Select.decorate(dbody.one(".ks-editor-table-align"), {
181                 prefixCls:'ks-editor-big-',
182                 elAttrs:{
183                     hideFocus:"hideFocus"
184                 },
185                 width:80,
186                 menuCfg:{
187                     prefixCls:'ks-editor-',
188                     render:dbody
189                 }
190             });
191             d.trows = dbody.one(".ks-editor-table-rows");
192             d.tcols = dbody.one(".ks-editor-table-cols");
193             d.thead = MenuButton.Select.decorate(dbody.one(".ks-editor-table-head"), {
194                 prefixCls:'ks-editor-big-',
195                 elAttrs:{
196                     hideFocus:"hideFocus"
197                 },
198                 width:80,
199                 menuCfg:{
200                     prefixCls:'ks-editor-',
201                     render:dbody
202                 }
203             });
204             d.cellpaddingHolder = dbody.one(".ks-editor-table-cellpadding-holder");
205             d.cellpadding = dbody.one(".ks-editor-table-cellpadding");
206             d.tcollapse = dbody.one(".ks-editor-table-collapse");
207             var tok = foot.one(".ks-editor-table-ok"),
208                 tclose = foot.one(".ks-editor-table-cancel");
209             d.twidthunit = MenuButton.Select.decorate(dbody.one(".ks-editor-table-width-unit"), {
210                 prefixCls:'ks-editor-big-',
211                 elAttrs:{
212                     hideFocus:"hideFocus"
213                 },
214                 width:80,
215                 menuCfg:{
216                     prefixCls:'ks-editor-',
217                     render:dbody
218                 }
219             });
220             self.dialog = d;
221             tok.on("click", self._tableOk, self);
222 
223             tclose.on("click", function (ev) {
224                 ev && ev.halt();
225                 d.hide();
226             });
227             addRes.call(self, d, d.twidthunit, tok, tclose);
228         },
229         _tableOk:function (ev) {
230             ev && ev.halt();
231             var self = this,
232                 tableDialog = self.dialog,
233                 inputs = tableDialog.get("el").all("input");
234 
235             if (tableDialog.twidthunit.get("value") == "%") {
236                 var tw = parseInt(tableDialog.twidth.val());
237                 if (
238                     !tw || (
239                         tw > 100 ||
240                             tw < 0
241                         )
242                     ) {
243                     alert("宽度百分比:" + "请输入1-100之间");
244                     return;
245                 }
246             }
247             var re = Editor.Utils.verifyInputs(inputs);
248             if (!re) return;
249             self.dialog.hide();
250             setTimeout(function () {
251                 if (!self.selectedTable) {
252                     self._genTable();
253                 } else {
254                     self._modifyTable();
255                 }
256             }, 0);
257         },
258         _modifyTable:function () {
259             var self = this,
260                 d = self.dialog,
261                 selectedTable = self.selectedTable,
262                 caption = selectedTable.one("caption"),
263                 talignVal = d.talign.get("value"),
264                 tborderVal = d.tborder.val();
265 
266             if (valid(talignVal))
267                 selectedTable.attr("align", trim(talignVal));
268             else
269                 selectedTable.removeAttr("align");
270 
271             if (valid(tborderVal)) {
272                 selectedTable.attr("border", trim(tborderVal));
273             } else {
274                 selectedTable.removeAttr("border");
275             }
276             if (!valid(tborderVal) || tborderVal == "0") {
277                 selectedTable.addClass(showBorderClassName, undefined);
278             } else {
279                 selectedTable.removeClass(showBorderClassName, undefined);
280             }
281 
282             if (valid(d.twidth.val()))
283                 selectedTable.css("width",
284                     trim(d.twidth.val()) + d.twidthunit.get("value"));
285             else
286                 selectedTable.css("width", "");
287             if (valid(d.theight.val()))
288                 selectedTable.css("height",
289                     trim(d.theight.val()));
290             else
291                 selectedTable.css("height", "");
292 
293             if (d.tcollapse[0].checked) {
294                 selectedTable.addClass(collapseTableClass, undefined);
295             } else {
296                 selectedTable.removeClass(collapseTableClass, undefined);
297             }
298 
299             d.cellpadding.val(parseInt(d.cellpadding.val()) || 0);
300             if (self.selectedTd)self.selectedTd.css("padding", d.cellpadding.val());
301             if (valid(d.tcaption.val())) {
302                 var tcv = Editor.Utils.htmlEncode(trim(d.tcaption.val()));
303                 if (caption && caption[0])
304                     caption.html(tcv);
305                 else {
306                     //不能使用dom操作了, ie6 table 报错
307                     //http://msdn.microsoft.com/en-us/library/ms532998(VS.85).aspx
308                     var c = selectedTable[0].createCaption();
309                     DOM.html(c, "<span>"
310                         + tcv
311                         + "</span>");
312                     // new Node("<caption><span>" + tcv + "</span></caption>");
313                     // .insertBefore(selectedTable[0].firstChild);
314                 }
315             } else if (caption) {
316                 caption.remove();
317             }
318 
319         },
320         _genTable:function () {
321             var self = this,
322                 d = self.dialog,
323                 html = "<table ",
324                 i,
325                 cols = parseInt(d.tcols.val()) || 1,
326                 rows = parseInt(d.trows.val()) || 1,
327             //firefox 需要 br 才能得以放置焦点
328                 cellpad = UA['ie'] ? " " : " <br/>",
329                 editor = self.editor;
330 
331             if (valid(d.talign.get("value")))
332                 html += "align='" + trim(d.talign.get("value")) + "' ";
333 
334             if (valid(d.tborder.val()))
335                 html += "border='" + trim(d.tborder.val()) + "' ";
336 
337             var styles = [];
338 
339 
340             if (valid(d.twidth.val())) {
341                 styles.push("width:" + trim(d.twidth.val())
342                     + d.twidthunit.get("value") + ";");
343             }
344 
345             if (valid(d.theight.val())) {
346                 styles.push("height:" + trim(d.theight.val()) + "px;");
347             }
348 
349             if (styles.length) {
350                 html += "style='" + styles.join("") + "' ";
351             }
352 
353             var classes = [];
354 
355             if (!valid(d.tborder.val())
356                 || String(trim(d.tborder.val())) == "0") {
357                 classes.push(showBorderClassName);
358             }
359 
360             if (d.tcollapse[0].checked) {
361                 classes.push(collapseTableClass);
362             }
363             if (classes.length) {
364                 html += "class='" + classes.join(" ") + "' ";
365             }
366 
367             html += ">";
368             if (valid(d.tcaption.val())) {
369                 html += "<caption><span>" + Editor.Utils.htmlEncode(trim(d.tcaption.val()))
370                     + "</span></caption>";
371             }
372             if (d.thead.get("value")) {
373                 html += "<thead>";
374                 html += "<tr>";
375                 for (i = 0; i < cols; i++)
376                     html += "<th>" + cellpad + "</th>";
377                 html += "</tr>";
378                 html += "</thead>";
379                 rows -= 1;
380             }
381 
382             html += "<tbody>";
383             for (var r = 0; r < rows; r++) {
384                 html += "<tr>";
385                 for (i = 0; i < cols; i++) {
386                     html += "<td>" + cellpad + "</td>";
387                 }
388                 html += "</tr>";
389             }
390             html += "</tbody>";
391             html += "</table>";
392 
393             var table = new Node(html, null, editor.get("document")[0]);
394             editor.insertElement(table);
395         },
396         _fillTableDialog:function () {
397             var self = this,
398                 d = self.dialog,
399                 selectedTable = self.selectedTable,
400                 caption = selectedTable.one("caption");
401             if (self.selectedTd) {
402                 d.cellpadding.val(
403                     parseInt(self.selectedTd.css("padding"))
404                         || "0");
405             }
406 
407             d.talign.set("value", selectedTable.attr("align") ||
408                 "");
409 
410 
411             d.tborder.val(selectedTable.attr("border") ||
412                 "0");
413             var w = selectedTable.style("width") ||
414                 ("" + selectedTable.width());
415 
416             d.tcollapse[0].checked = selectedTable.hasClass(collapseTableClass, undefined);
417 
418             //忽略pt单位
419             d.twidth.val(w.replace(/px|%|(.*pt)/i, ""));
420             if (w.indexOf("%") != -1) {
421                 d.twidthunit.set("value", "%");
422             } else {
423                 d.twidthunit.set("value", "px");
424             }
425 
426             d.theight.val((selectedTable.style("height") || "")
427                 .replace(/px|%/i, ""));
428             var c = "";
429             if (caption) {
430                 c = caption.text();
431             }
432             d.tcaption.val(c);
433             var head = selectedTable.first("thead"),
434                 rowLenth = (selectedTable.one("tbody") ?
435                     selectedTable.one("tbody").children().length : 0)
436                     + (head ? head.children("tr").length : 0);
437             d.trows.val(rowLenth);
438             d.tcols.val(selectedTable.one("tr") ?
439                 selectedTable.one("tr").children().length : 0);
440             d.thead.set("value", head ? '1' : '');
441         },
442         _realTableShow:function () {
443             var self = this,
444                 d = self.dialog;
445 
446             if (self.selectedTable) {
447                 self._fillTableDialog();
448                 d.get("el")
449                     .all(".ks-editor-table-create-only")
450                     .attr("disabled", "disabled");
451                 d.thead.set('disabled', true);
452             } else {
453                 d.get("el").all(".ks-editor-table-create-only")
454                     .removeAttr("disabled");
455                 d.thead.set('disabled', false);
456             }
457             if (self.selectedTd) {
458                 d.cellpaddingHolder.show();
459             } else {
460                 d.cellpaddingHolder.hide();
461             }
462             self.dialog.show();
463         },
464         _prepareTableShow:function () {
465             var self = this;
466             self._tableInit();
467         },
468         show:function (cfg) {
469             var self = this;
470             S.mix(self, cfg);
471             self._prepareTableShow();
472         },
473         destroy:function () {
474             destroyRes.call(this);
475         }
476     });
477 
478     return TableDialog;
479 }, {
480     requires:['editor', '../overlay/', '../menubutton/']
481 });