a558b439b743a689a0a984047454ecbf656169b8
[Packages/TYPO3.CMS.git] / typo3 / sysext / backend / Resources / Public / JavaScript / GridEditor.js
1 /*
2 * This file is part of the TYPO3 CMS project.
3 *
4 * It is free software; you can redistribute it and/or modify it under
5 * the terms of the GNU General Public License, either version 2
6 * of the License, or any later version.
7 *
8 * For the full copyright and license information, please read the
9 * LICENSE.txt file that was distributed with this source code.
10 *
11 * The TYPO3 project - inspiring people to share!
12 */
13
14 /**
15 * Module: TYPO3/CMS/Backend/GridEditor
16 */
17 define(['jquery', 'TYPO3/CMS/Backend/Modal', 'TYPO3/CMS/Backend/Severity', 'bootstrap'], function($, Modal, Severity) {
18 'use strict';
19
20 /**
21 * The main ContextHelp object
22 *
23 * @type {{selectorEditor: string, selectorAddColumn: string, selectorRemoveColumn: string, selectorAddRow: string, selectorRemoveRow: string, selectorLinkEditor: string, selectorLinkExpandRight: string, selectorLinkShrinkLeft: string, selectorLinkExpandDown: string, selectorLinkShrinkUp: string, selectorDocHeaderSave: string, selectorDocHeaderSaveClose: string, selectorConfigPreview: string, selectorConfigPreviewButton: string, colCount: number, rowCount: number, field: string, data: Array, nameLabel: string, columnLabel: string, targetElement: null}}
24 * @exports TYPO3/CMS/Backend/GridEditor
25 */
26 var GridEditor = {
27 selectorEditor: '.t3js-grideditor',
28 selectorAddColumn: '.t3js-grideditor-addcolumn',
29 selectorRemoveColumn: '.t3js-grideditor-removecolumn',
30 selectorAddRow: '.t3js-grideditor-addrow',
31 selectorRemoveRow: '.t3js-grideditor-removerow',
32 selectorLinkEditor: '.t3js-grideditor-link-editor',
33 selectorLinkExpandRight: '.t3js-grideditor-link-expand-right',
34 selectorLinkShrinkLeft: '.t3js-grideditor-link-shrink-left',
35 selectorLinkExpandDown: '.t3js-grideditor-link-expand-down',
36 selectorLinkShrinkUp: '.t3js-grideditor-link-shrink-up',
37 selectorDocHeaderSave: '.t3js-grideditor-savedok',
38 selectorDocHeaderSaveClose: '.t3js-grideditor-savedokclose',
39 selectorConfigPreview: '.t3js-grideditor-preview-config',
40 selectorConfigPreviewButton: '.t3js-grideditor-preview-button',
41 colCount: 1,
42 rowCount: 1,
43 field: '',
44 data: [],
45 nameLabel: 'name',
46 columnLabel: 'columen label',
47 targetElement: null
48 };
49
50 /**
51 *
52 * @param {Object} config
53 */
54 GridEditor.initialize = function(config) {
55 config = config || {};
56 var $element = $(GridEditor.selectorEditor);
57 GridEditor.colCount = $element.data('colcount');
58 GridEditor.rowCount = $element.data('rowcount');
59 GridEditor.field = $('input[name="' + $element.data('field') + '"]');
60 GridEditor.data = $element.data('data');
61 GridEditor.nameLabel = config.nameLabel || 'Name';
62 GridEditor.columnLabel = config.columnLabel || 'Column';
63 GridEditor.targetElement = $(GridEditor.selectorEditor);
64 $(GridEditor.selectorConfigPreview).hide();
65
66 $(document).on('click', GridEditor.selectorAddColumn, function(e) {
67 e.preventDefault();
68 GridEditor.addColumn();
69 GridEditor.drawTable();
70 GridEditor.writeConfig(GridEditor.export2LayoutRecord());
71 });
72 $(document).on('click', GridEditor.selectorRemoveColumn, function(e) {
73 e.preventDefault();
74 GridEditor.removeColumn();
75 GridEditor.drawTable();
76 GridEditor.writeConfig(GridEditor.export2LayoutRecord());
77 });
78 $(document).on('click', GridEditor.selectorAddRow, function(e) {
79 e.preventDefault();
80 GridEditor.addRow();
81 GridEditor.drawTable();
82 GridEditor.writeConfig(GridEditor.export2LayoutRecord());
83 });
84 $(document).on('click', GridEditor.selectorRemoveRow, function(e) {
85 e.preventDefault();
86 GridEditor.removeRow();
87 GridEditor.drawTable();
88 GridEditor.writeConfig(GridEditor.export2LayoutRecord());
89 });
90 $(document).on('click', GridEditor.selectorLinkEditor, function(e) {
91 e.preventDefault();
92 var $element = $(this);
93 var col = $element.data('col');
94 var row = $element.data('row');
95 GridEditor.showOptions(col, row);
96 });
97 $(document).on('click', GridEditor.selectorLinkExpandRight, function(e) {
98 e.preventDefault();
99 var $element = $(this);
100 var col = $element.data('col');
101 var row = $element.data('row');
102 GridEditor.addColspan(col, row);
103 GridEditor.drawTable();
104 GridEditor.writeConfig(GridEditor.export2LayoutRecord());
105 });
106 $(document).on('click', GridEditor.selectorLinkShrinkLeft, function(e) {
107 e.preventDefault();
108 var $element = $(this);
109 var col = $element.data('col');
110 var row = $element.data('row');
111 GridEditor.removeColspan(col, row);
112 GridEditor.drawTable();
113 GridEditor.writeConfig(GridEditor.export2LayoutRecord());
114 });
115 $(document).on('click', GridEditor.selectorLinkExpandDown, function(e) {
116 e.preventDefault();
117 var $element = $(this);
118 var col = $element.data('col');
119 var row = $element.data('row');
120 GridEditor.addRowspan(col, row);
121 GridEditor.drawTable();
122 GridEditor.writeConfig(GridEditor.export2LayoutRecord());
123 });
124 $(document).on('click', GridEditor.selectorLinkShrinkUp, function(e) {
125 e.preventDefault();
126 var $element = $(this);
127 var col = $element.data('col');
128 var row = $element.data('row');
129 GridEditor.removeRowspan(col, row);
130 GridEditor.drawTable();
131 GridEditor.writeConfig(GridEditor.export2LayoutRecord());
132 });
133
134 $(GridEditor.selectorConfigPreviewButton).empty().append(TYPO3.lang['button.showPageTsConfig']);
135 $(document).on('click', GridEditor.selectorConfigPreviewButton, function(e) {
136 e.preventDefault();
137 var $preview = $(GridEditor.selectorConfigPreview);
138 var $button = $(GridEditor.selectorConfigPreviewButton);
139 if ($preview.is(':visible')) {
140 $button.empty().append(TYPO3.lang['button.showPageTsConfig']);
141 $(GridEditor.selectorConfigPreview).slideUp();
142 } else {
143 $button.empty().append(TYPO3.lang['button.hidePageTsConfig']);
144 $(GridEditor.selectorConfigPreview).slideDown();
145 }
146
147 });
148
149 GridEditor.drawTable();
150 GridEditor.writeConfig(GridEditor.export2LayoutRecord());
151 };
152
153 /**
154 * write data back to hidden field
155 *
156 * @param data
157 */
158 GridEditor.writeConfig = function(data) {
159 GridEditor.field.val(data);
160 var configLines = data.split('\n');
161 var config = '';
162 for (var i=0; i<configLines.length; i++) {
163 if (configLines[i].length) {
164 config += '\t\t\t' + configLines[i] + '\n';
165 }
166 }
167 $(GridEditor.selectorConfigPreview).find('code').empty().append(
168 'mod.web_layout.BackendLayouts {\n' +
169 ' exampleKey {\n' +
170 ' title = Example\n' +
171 ' icon = EXT:example_extension/Resources/Public/Images/BackendLayouts/default.gif\n' +
172 ' config {\n' +
173 config.replace(new RegExp('\t', 'g'), ' ') +
174 ' }\n' +
175 ' }\n' +
176 '}\n'
177 );
178 };
179
180 /**
181 * Add a new row
182 */
183 GridEditor.addRow = function() {
184 var newRow = [];
185 for (var i = 0; i < GridEditor.colCount; i++) {
186 newRow[i] = {spanned: false, rowspan: 1, colspan: 1};
187 }
188 GridEditor.data.push(newRow);
189 GridEditor.rowCount++;
190 };
191
192 /**
193 * Removes the last row of the grid and adjusts all cells that might be effected
194 * by that change. (Removing colspans)
195 */
196 GridEditor.removeRow = function() {
197 if (GridEditor.rowCount <= 1) {
198 return false;
199 }
200 var newData = [];
201 for (var rowIndex = 0; rowIndex < GridEditor.rowCount - 1; rowIndex++) {
202 newData.push(GridEditor.data[rowIndex]);
203 }
204
205 // fix rowspan in former last row
206 for (var colIndex = 0; colIndex < GridEditor.colCount; colIndex++) {
207 if (GridEditor.data[GridEditor.rowCount - 1][colIndex].spanned == true) {
208 GridEditor.findUpperCellWidthRowspanAndDecreaseByOne(colIndex, GridEditor.rowCount - 1);
209 }
210 }
211
212 GridEditor.data = newData;
213 GridEditor.rowCount--;
214 };
215
216 /**
217 * Takes a cell and looks above it if there are any cells that have colspans that
218 * spans into the given cell. This is used when a row was removed from the grid
219 * to make sure that no cell with wrong colspans exists in the grid.
220 *
221 * @param {Integer} col
222 * @param {Integer} row integer
223 */
224 GridEditor.findUpperCellWidthRowspanAndDecreaseByOne = function(col, row) {
225 var upperCell = GridEditor.getCell(col, row - 1);
226 if (!upperCell) {
227 return false;
228 }
229
230 if (upperCell.spanned == true) {
231 GridEditor.findUpperCellWidthRowspanAndDecreaseByOne(col, row - 1);
232 } else {
233 if (upperCell.rowspan > 1) {
234 GridEditor.removeRowspan(col, row - 1);
235 }
236 }
237 };
238
239 /**
240 * Removes the outermost right column from the grid.
241 */
242 GridEditor.removeColumn = function() {
243 if (GridEditor.colCount <= 1) {
244 return false;
245 }
246 var newData = [];
247
248 for (var rowIndex = 0; rowIndex < GridEditor.rowCount; rowIndex++) {
249 var newRow = [];
250 for (var colIndex = 0; colIndex < GridEditor.colCount - 1; colIndex++) {
251 newRow.push(GridEditor.data[rowIndex][colIndex]);
252 }
253 if (GridEditor.data[rowIndex][GridEditor.colCount - 1].spanned == true) {
254 GridEditor.findLeftCellWidthColspanAndDecreaseByOne(GridEditor.colCount - 1, rowIndex);
255 }
256 newData.push(newRow);
257 }
258
259 GridEditor.data = newData;
260 GridEditor.colCount--;
261 };
262
263 /**
264 * Checks if there are any cells on the left side of a given cell with a
265 * rowspan that spans over the given cell.
266 *
267 * @param {Integer} col
268 * @param {Integer} row
269 */
270 GridEditor.findLeftCellWidthColspanAndDecreaseByOne = function(col, row) {
271 var leftCell = GridEditor.getCell(col - 1, row);
272 if (!leftCell) {
273 return false;
274 }
275
276 if (leftCell.spanned == true) {
277 GridEditor.findLeftCellWidthColspanAndDecreaseByOne(col - 1, row);
278 } else {
279 if (leftCell.colspan > 1) {
280 GridEditor.removeColspan(col - 1, row);
281 }
282 }
283 };
284
285 /**
286 * Adds a column at the right side of the grid.
287 */
288 GridEditor.addColumn = function() {
289 for (var rowIndex = 0; rowIndex < GridEditor.rowCount; rowIndex++) {
290 GridEditor.data[rowIndex].push({
291 spanned: false,
292 rowspan: 1,
293 colspan: 1,
294 name: GridEditor.colCount + 'x' + rowIndex
295 });
296 }
297 GridEditor.colCount++;
298 };
299
300 /**
301 * Draws the grid as table into a given container.
302 * It also adds all needed links and bindings to the cells to make it editable.
303 */
304 GridEditor.drawTable = function() {
305 var col;
306 var $colgroup = $('<colgroup>');
307 for (col = 0; col < GridEditor.colCount; col++) {
308 $colgroup.append($('<col>').css({
309 width: parseInt(100 / GridEditor.colCount, 10) + '%'
310 }));
311 }
312 var $table = $('<table id="base" class="table editor">');
313 $table.append($colgroup);
314
315 for (var row = 0; row < GridEditor.rowCount; row++) {
316 var rowData = GridEditor.data[row];
317 if (rowData.length == 0) {
318 continue;
319 }
320
321 var $row = $('<tr>');
322
323 for (col = 0; col < GridEditor.colCount; col++) {
324 var cell = GridEditor.data[row][col];
325 if (cell.spanned == true) {
326 continue;
327 }
328 var $cell = $('<td>').css({
329 height: parseInt(100 / GridEditor.rowCount, 10) * cell.rowspan + '%',
330 width: parseInt(100 / GridEditor.colCount, 10) * cell.colspan + '%'
331 });
332 var $container = $('<div class="cell_container">');
333 $cell.append($container);
334 var dataString = ' data-col="' + col + '" data-row="' + row + '"';
335 $container.append($('<a class="t3js-grideditor-link-editor link link_editor" title="' + TYPO3.lang['grid_editCell'] + '" ' + dataString + ' href="#"><!-- --></a>'));
336 if (GridEditor.cellCanSpanRight(col, row)) {
337 $container.append($('<a class="t3js-grideditor-link-expand-right link link_expand_right" href="#" title="' + TYPO3.lang['grid_mergeCell'] + '" ' + dataString + '><!-- --></a>'));
338 }
339 if (GridEditor.cellCanShrinkLeft(col, row)) {
340 $container.append('<a class="t3js-grideditor-link-shrink-left link link_shrink_left" href="#" title="' + TYPO3.lang['grid_splitCell'] + '" ' + dataString + '><!-- --></a>');
341 }
342 if (GridEditor.cellCanSpanDown(col, row)) {
343 $container.append('<a class="t3js-grideditor-link-expand-down link link_expand_down" href="#" title="' + TYPO3.lang['grid_mergeCell'] + '" ' + dataString + '><!-- --></a>');
344 }
345 if (GridEditor.cellCanShrinkUp(col, row)) {
346 $container.append('<a class="t3js-grideditor-link-shrink-up link link_shrink_up" href="#" title="' + TYPO3.lang['grid_splitCell'] + '" ' + dataString + '><!-- --></a>');
347 }
348 $cell.append('<div class="cell_data">' + TYPO3.lang['grid_name'] + ': ' + (cell.name ? GridEditor.stripMarkup(cell.name) : TYPO3.lang['grid_notSet'])
349 + '<br />' + TYPO3.lang['grid_column'] + ': '
350 + (cell.column === undefined ? TYPO3.lang['grid_notSet'] : parseInt(cell.column, 10)) + '</div>');
351
352 if (cell.colspan > 1) {
353 $cell.attr('colspan', cell.colspan);
354 }
355 if (cell.rowspan > 1) {
356 $cell.attr('rowspan', cell.rowspan);
357 }
358 $row.append($cell);
359 }
360 $table.append($row);
361 }
362 $(GridEditor.targetElement).empty().append($table);
363 };
364
365 /**
366 * Sets the name of a certain grid element.
367 *
368 * @param {String} newName
369 * @param {Integer} col
370 * @param {Integer} row
371 *
372 * @returns {Boolean}
373 */
374 GridEditor.setName = function(newName, col, row) {
375 var cell = GridEditor.getCell(col, row);
376 if (!cell) {
377 return false;
378 }
379 cell.name = GridEditor.stripMarkup(newName);
380 return true;
381 };
382
383 /**
384 * Sets the column field for a certain grid element. This is NOT the column of the
385 * element itself.
386 *
387 * @param {Integer} newColumn
388 * @param {Integer} col
389 * @param {Integer} row
390 *
391 * @returns {Boolean}
392 */
393 GridEditor.setColumn = function(newColumn, col, row) {
394 var cell = GridEditor.getCell(col, row);
395 if (!cell) {
396 return false;
397 }
398 cell.column = parseInt(GridEditor.stripMarkup(newColumn), 10);
399 return true;
400 };
401
402 /**
403 * Creates an ExtJs Window with two input fields and shows it. On save, the data
404 * is written into the grid element.
405 *
406 * @param {Integer} col
407 * @param {Integer} row
408 *
409 * @returns {Boolean}
410 */
411 GridEditor.showOptions = function(col, row) {
412 var cell = GridEditor.getCell(col, row);
413 if (!cell) {
414 return false;
415 }
416
417 var colPos;
418 if (cell.column === 0) {
419 colPos = 0;
420 } else if(parseInt(cell.column, 10)) {
421 colPos = parseInt(cell.column, 10);
422 } else {
423 colPos = '';
424 }
425
426 var $markup = $('<div>');
427 $markup.append(
428 '<div>' +
429 '<div class="form-group">' +
430 '<label>' + TYPO3.lang['grid_nameHelp'] + '</label>' +
431 '<input type="text" class="t3js-grideditor-field-name form-control" name="name" value="' + (GridEditor.stripMarkup(cell.name) || '') + '">' +
432 '</div>' +
433 '<div class="form-group">' +
434 '<label>' + TYPO3.lang['grid_columnHelp'] + '</label>' +
435 '<input type="text" class="t3js-grideditor-field-colpos form-control" name="name" value="' + colPos + '">' +
436 '</div>' +
437 '</div>'
438 );
439 var $modal = Modal.show(TYPO3.lang['grid_windowTitle'], $markup, Severity.notice, [
440 {
441 text: $(this).data('button-close-text') || TYPO3.lang['button.cancel'] || 'Cancel',
442 active: true,
443 btnClass: 'btn-default',
444 name: 'cancel'
445 },
446 {
447 text: $(this).data('button-ok-text') || TYPO3.lang['button.ok'] || 'OK',
448 btnClass: 'btn-' + Severity.getCssClass(Severity.notice),
449 name: 'ok'
450 }
451 ]);
452 $modal.data('col', col);
453 $modal.data('row', row);
454 $modal.on('button.clicked', function(e) {
455 if (e.target.name === 'cancel') {
456 Modal.currentModal.trigger('modal-dismiss');
457 } else if (e.target.name === 'ok') {
458 GridEditor.setName($modal.find('.t3js-grideditor-field-name').val(), $modal.data('col'), $modal.data('row'));
459 GridEditor.setColumn($modal.find('.t3js-grideditor-field-colpos').val(), $modal.data('col'), $modal.data('row'));
460 GridEditor.drawTable();
461 GridEditor.writeConfig(GridEditor.export2LayoutRecord());
462 Modal.currentModal.trigger('modal-dismiss');
463 }
464 });
465 };
466
467 /**
468 * Returns a cell element from the grid.
469 *
470 * @param {Integer} col
471 * @param {Integer} row
472 * @returns {Object}
473 */
474 GridEditor.getCell = function(col, row) {
475 if (col > GridEditor.colCount - 1) {
476 return false;
477 }
478 if (row > GridEditor.rowCount - 1) {
479 return false;
480 }
481 return GridEditor.data[row][col];
482 };
483
484 /**
485 * Checks whether a cell can span to the right or not. A cell can span to the right
486 * if it is not in the last column and if there is no cell beside it that is
487 * already overspanned by some other cell.
488 *
489 * @param {Integer} col
490 * @param {Integer} row
491 * @returns {Boolean}
492 */
493 GridEditor.cellCanSpanRight = function(col, row) {
494 if (col == GridEditor.colCount - 1) {
495 return false;
496 }
497
498 var cell = GridEditor.getCell(col, row);
499 var checkCell;
500 if (cell.rowspan > 1) {
501 for (var rowIndex = row; rowIndex < row + cell.rowspan; rowIndex++) {
502 checkCell = GridEditor.getCell(col + cell.colspan, rowIndex);
503 if (!checkCell || checkCell.spanned == true || checkCell.colspan > 1 || checkCell.rowspan > 1) {
504 return false;
505 }
506 }
507 } else {
508 checkCell = GridEditor.getCell(col + cell.colspan, row);
509 if (!checkCell || cell.spanned == true || checkCell.spanned == true || checkCell.colspan > 1 || checkCell.rowspan > 1) {
510 return false;
511 }
512 }
513
514 return true;
515 };
516
517 /**
518 * Checks whether a cell can span down or not.
519 *
520 * @param {Integer} col
521 * @param {Integer} row
522 * @returns {Boolean}
523 */
524 GridEditor.cellCanSpanDown = function(col, row) {
525 if (row == GridEditor.rowCount - 1) {
526 return false;
527 }
528
529 var cell = GridEditor.getCell(col, row);
530 var checkCell;
531 if (cell.colspan > 1) {
532 // we have to check all cells on the right side for the complete colspan
533 for (var colIndex = col; colIndex < col + cell.colspan; colIndex++) {
534 checkCell = GridEditor.getCell(colIndex, row + cell.rowspan);
535 if (!checkCell || checkCell.spanned == true || checkCell.colspan > 1 || checkCell.rowspan > 1) {
536 return false;
537 }
538 }
539 } else {
540 checkCell = GridEditor.getCell(col, row + cell.rowspan);
541 if (!checkCell || cell.spanned == true || checkCell.spanned == true || checkCell.colspan > 1 || checkCell.rowspan > 1) {
542 return false;
543 }
544 }
545
546 return true;
547 };
548
549 /**
550 * Checks if a cell can shrink to the left. It can shrink if the colspan of the
551 * cell is bigger than 1.
552 *
553 * @param {Integer} col
554 * @param {Integer} row
555 * @returns {Boolean}
556 */
557 GridEditor.cellCanShrinkLeft = function(col, row) {
558 return (GridEditor.data[row][col].colspan > 1);
559 };
560
561 /**
562 * Returns if a cell can shrink up. This is the case if a cell has at least
563 * a rowspan of 2.
564 *
565 * @param {Integer} col
566 * @param {Integer} row
567 * @returns {Boolean}
568 */
569 GridEditor.cellCanShrinkUp = function(col, row) {
570 return (GridEditor.data[row][col].rowspan > 1);
571 };
572
573 /**
574 * Adds a colspan to a grid element.
575 *
576 * @param {Integer} col
577 * @param {Integer} row
578 * @returns {Boolean}
579 */
580 GridEditor.addColspan = function(col, row) {
581 var cell = GridEditor.getCell(col, row);
582 if (!cell || !GridEditor.cellCanSpanRight(col, row)) {
583 return false;
584 }
585
586 for (var rowIndex = row; rowIndex < row + cell.rowspan; rowIndex++) {
587 GridEditor.data[rowIndex][col + cell.colspan].spanned = true;
588 }
589 cell.colspan += 1;
590 };
591
592 /**
593 * Adds a rowspan to grid element.
594 *
595 * @param {Integer} col
596 * @param {Integer} row
597 * @returns {Boolean}
598 */
599 GridEditor.addRowspan = function(col, row) {
600 var cell = GridEditor.getCell(col, row);
601 if (!cell || !GridEditor.cellCanSpanDown(col, row)) {
602 return false;
603 }
604
605 for (var colIndex = col; colIndex < col + cell.colspan; colIndex++) {
606 GridEditor.data[row + cell.rowspan][colIndex].spanned = true;
607 }
608 cell.rowspan += 1;
609 };
610
611 /**
612 * Removes a colspan from a grid element.
613 *
614 * @param {Integer} col
615 * @param {Integer} row
616 * @returns {Boolean}
617 */
618 GridEditor.removeColspan = function(col, row) {
619 var cell = GridEditor.getCell(col, row);
620 if (!cell || !GridEditor.cellCanShrinkLeft(col, row)) {
621 return false;
622 }
623
624 cell.colspan -= 1;
625 for (var rowIndex = row; rowIndex < row + cell.rowspan; rowIndex++) {
626 GridEditor.data[rowIndex][col + cell.colspan].spanned = false;
627 }
628 };
629
630 /**
631 * Removes a rowspan from a grid element.
632 *
633 * @param {Integer} col
634 * @param {Integer} row
635 * @returns {Boolean}
636 */
637 GridEditor.removeRowspan = function(col, row) {
638 var cell = GridEditor.getCell(col, row);
639 if (!cell || !GridEditor.cellCanShrinkUp(col, row)) {
640 return false;
641 }
642
643 cell.rowspan -= 1;
644 for (var colIndex = col; colIndex < col + cell.colspan; colIndex++) {
645 GridEditor.data[row + cell.rowspan][colIndex].spanned = false;
646 }
647 };
648
649 /**
650 * Exports the current grid to a TypoScript notation that can be read by the
651 * page module and is human readable.
652 *
653 * @returns {String}
654 */
655 GridEditor.export2LayoutRecord = function() {
656 var result = "backend_layout {\n\tcolCount = " + GridEditor.colCount + "\n\trowCount = " + GridEditor.rowCount + "\n\trows {\n";
657 for (var row = 0; row < GridEditor.rowCount; row++) {
658 result += "\t\t" + (row + 1) + " {\n";
659 result += "\t\t\tcolumns {\n";
660 var colIndex = 0;
661 for (var col = 0; col < GridEditor.colCount; col++) {
662 var cell = GridEditor.getCell(col, row);
663 if (cell && !cell.spanned) {
664 colIndex++;
665 result += "\t\t\t\t" + (colIndex) + " {\n";
666 result += "\t\t\t\t\tname = " + ((!cell.name) ? col + "x" + row : cell.name) + "\n";
667 if (cell.colspan > 1) {
668 result += "\t\t\t\t\tcolspan = " + cell.colspan + "\n";
669 }
670 if (cell.rowspan > 1) {
671 result += "\t\t\t\t\trowspan = " + cell.rowspan + "\n";
672 }
673 if (typeof(cell.column) === 'number') {
674 result += "\t\t\t\t\tcolPos = " + cell.column + "\n";
675 }
676 result += "\t\t\t\t}\n";
677 }
678
679 }
680 result += "\t\t\t}\n";
681 result += "\t\t}\n";
682 }
683
684 result += "\t}\n}\n";
685 return result;
686 };
687
688 /**
689 *
690 * @param {String} input
691 * @returns {*|jQuery}
692 */
693 GridEditor.stripMarkup = function(input) {
694 return $('<p>' + input + '</p>').text();
695 };
696
697 GridEditor.initialize();
698 return GridEditor;
699 });