enhanced the table editing in the extended wiki editor (medium-editor-tables)
disabled firefox object resizing and inline table editing
This commit is contained in:
parent
b3cbcf09ab
commit
06aa8bff25
@ -28,8 +28,8 @@
|
|||||||
<link type="text/css" rel="stylesheet" href="<?php print base_url_make('/css/medium-editor.min.css')?>" />
|
<link type="text/css" rel="stylesheet" href="<?php print base_url_make('/css/medium-editor.min.css')?>" />
|
||||||
<link type="text/css" rel="stylesheet" href="<?php print base_url_make('/css/medium-editor-theme.min.css')?>" />
|
<link type="text/css" rel="stylesheet" href="<?php print base_url_make('/css/medium-editor-theme.min.css')?>" />
|
||||||
|
|
||||||
<script type="text/javascript" src="<?php print base_url_make('/js/medium-editor-tables.min.js')?>"></script>
|
<script type="text/javascript" src="<?php print base_url_make('/js/medium-editor-tables.js')?>"></script>
|
||||||
<link type="text/css" rel="stylesheet" href="<?php print base_url_make('/css/medium-editor-tables.min.css')?>" />
|
<link type="text/css" rel="stylesheet" href="<?php print base_url_make('/css/medium-editor-tables.min.css')?>" />
|
||||||
|
|
||||||
<?php
|
<?php
|
||||||
$hex_wikiname = $this->converter->AsciiToHex ($wiki->name);
|
$hex_wikiname = $this->converter->AsciiToHex ($wiki->name);
|
||||||
@ -365,7 +365,8 @@ $(function () {
|
|||||||
|
|
||||||
toolbar: {
|
toolbar: {
|
||||||
allowMultiParagraphSelection: true,
|
allowMultiParagraphSelection: true,
|
||||||
buttons: ['bold', 'italic', 'underline', 'strikethrough',
|
buttons: ['fontname', 'fontsize',
|
||||||
|
'bold', 'italic', 'underline', 'strikethrough',
|
||||||
'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
|
'h1', 'h2', 'h3', 'h4', 'h5', 'h6',
|
||||||
'subscript', 'superscript', 'removeFormat',
|
'subscript', 'superscript', 'removeFormat',
|
||||||
'pre', 'anchor', 'image',
|
'pre', 'anchor', 'image',
|
||||||
@ -526,6 +527,14 @@ $(function () {
|
|||||||
// quirkiness of medium editor's toolbar
|
// quirkiness of medium editor's toolbar
|
||||||
resize_editor ();
|
resize_editor ();
|
||||||
resize_editor ();
|
resize_editor ();
|
||||||
|
|
||||||
|
// to diable firefox's object resizing.
|
||||||
|
try
|
||||||
|
{
|
||||||
|
document.execCommand("enableInlineTableEditing", false, false);
|
||||||
|
document.execCommand("enableObjectResizing", false, false);
|
||||||
|
}
|
||||||
|
catch (err) { }
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
<html>
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
|
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
@ -952,11 +952,13 @@ pre.codepot-line-numbered span.codepot-line-number-clear {
|
|||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
|
||||||
margin: 0.1em 0 0.1em 0;
|
padding: 0.3em 1em 0.3em 1em;
|
||||||
padding: 0;
|
margin: 0;
|
||||||
|
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
border: 1px solid #DFDFDF;
|
border: 1px solid #DFDFDF;
|
||||||
|
|
||||||
|
table-layout: auto !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.codepot-styled-text-view table tr,
|
.codepot-styled-text-view table tr,
|
||||||
|
@ -25,7 +25,7 @@ www_DATA = \
|
|||||||
jquery.flot.tickrotor.js \
|
jquery.flot.tickrotor.js \
|
||||||
jqueryui-editable.min.js \
|
jqueryui-editable.min.js \
|
||||||
medium-editor.min.js \
|
medium-editor.min.js \
|
||||||
medium-editor-tables.min.js \
|
medium-editor-tables.js \
|
||||||
showdown.js \
|
showdown.js \
|
||||||
d3.min.js \
|
d3.min.js \
|
||||||
CodeFlower.js
|
CodeFlower.js
|
||||||
|
@ -178,7 +178,7 @@ www_DATA = \
|
|||||||
jquery.flot.tickrotor.js \
|
jquery.flot.tickrotor.js \
|
||||||
jqueryui-editable.min.js \
|
jqueryui-editable.min.js \
|
||||||
medium-editor.min.js \
|
medium-editor.min.js \
|
||||||
medium-editor-tables.min.js \
|
medium-editor-tables.js \
|
||||||
showdown.js \
|
showdown.js \
|
||||||
d3.min.js \
|
d3.min.js \
|
||||||
CodeFlower.js
|
CodeFlower.js
|
||||||
|
732
codepot/src/js/medium-editor-tables.js
Normal file
732
codepot/src/js/medium-editor-tables.js
Normal file
@ -0,0 +1,732 @@
|
|||||||
|
(function (root, factory) {
|
||||||
|
'use strict';
|
||||||
|
if (typeof module === 'object') {
|
||||||
|
module.exports = factory;
|
||||||
|
} else if (typeof define === 'function' && define.amd) {
|
||||||
|
define(factory);
|
||||||
|
} else {
|
||||||
|
root.MediumEditorTable = factory;
|
||||||
|
}
|
||||||
|
}(this, function () {
|
||||||
|
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
function extend(dest, source) {
|
||||||
|
var prop;
|
||||||
|
dest = dest || {};
|
||||||
|
for (prop in source) {
|
||||||
|
if (source.hasOwnProperty(prop) && !dest.hasOwnProperty(prop)) {
|
||||||
|
dest[prop] = source[prop];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSelectionText(doc) {
|
||||||
|
if (doc.getSelection) {
|
||||||
|
return doc.getSelection().toString();
|
||||||
|
}
|
||||||
|
if (doc.selection && doc.selection.type !== 'Control') {
|
||||||
|
return doc.selection.createRange().text;
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
function getSelectionStart(doc) {
|
||||||
|
var node = doc.getSelection().anchorNode,
|
||||||
|
startNode = (node && node.nodeType === 3 ? node.parentNode : node);
|
||||||
|
|
||||||
|
return startNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
function placeCaretAtNode(doc, node, before) {
|
||||||
|
if (doc.getSelection !== undefined && node) {
|
||||||
|
var range = doc.createRange(),
|
||||||
|
selection = doc.getSelection();
|
||||||
|
|
||||||
|
if (before) {
|
||||||
|
range.setStartBefore(node);
|
||||||
|
} else {
|
||||||
|
range.setStartAfter(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
range.collapse(true);
|
||||||
|
|
||||||
|
selection.removeAllRanges();
|
||||||
|
selection.addRange(range);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function isInsideElementOfTag(node, tag) {
|
||||||
|
if (!node) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var parentNode = node.parentNode,
|
||||||
|
tagName = parentNode.tagName.toLowerCase();
|
||||||
|
|
||||||
|
while (tagName !== 'body') {
|
||||||
|
if (tagName === tag) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
parentNode = parentNode.parentNode;
|
||||||
|
|
||||||
|
if (parentNode && parentNode.tagName) {
|
||||||
|
tagName = parentNode.tagName.toLowerCase();
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getParentOf(el, tagTarget) {
|
||||||
|
var tagName = el && el.tagName ? el.tagName.toLowerCase() : false;
|
||||||
|
|
||||||
|
if (!tagName) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
while (tagName && tagName !== 'body') {
|
||||||
|
if (tagName === tagTarget) {
|
||||||
|
return el;
|
||||||
|
}
|
||||||
|
el = el.parentNode;
|
||||||
|
tagName = el && el.tagName ? el.tagName.toLowerCase() : false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Grid(el, callback, rows, columns) {
|
||||||
|
return this.init(el, callback, rows, columns);
|
||||||
|
}
|
||||||
|
|
||||||
|
Grid.prototype = {
|
||||||
|
init: function (el, callback, rows, columns) {
|
||||||
|
this._root = el;
|
||||||
|
this._callback = callback;
|
||||||
|
this.rows = rows;
|
||||||
|
this.columns = columns;
|
||||||
|
return this._render();
|
||||||
|
},
|
||||||
|
|
||||||
|
setCurrentCell: function (cell) {
|
||||||
|
this._currentCell = cell;
|
||||||
|
},
|
||||||
|
|
||||||
|
markCells: function () {
|
||||||
|
[].forEach.call(this._cellsElements, function (el) {
|
||||||
|
var cell = {
|
||||||
|
column: parseInt(el.dataset.column, 10),
|
||||||
|
row: parseInt(el.dataset.row, 10)
|
||||||
|
},
|
||||||
|
active = this._currentCell &&
|
||||||
|
cell.row <= this._currentCell.row &&
|
||||||
|
cell.column <= this._currentCell.column;
|
||||||
|
|
||||||
|
if (active === true) {
|
||||||
|
el.classList.add('active');
|
||||||
|
} else {
|
||||||
|
el.classList.remove('active');
|
||||||
|
}
|
||||||
|
}.bind(this));
|
||||||
|
},
|
||||||
|
|
||||||
|
_generateCells: function () {
|
||||||
|
this._cells = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < this.rows * this.columns; i++) {
|
||||||
|
var column = i % this.columns,
|
||||||
|
row = Math.floor(i / this.rows);
|
||||||
|
|
||||||
|
this._cells.push({
|
||||||
|
column: column,
|
||||||
|
row: row,
|
||||||
|
active: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_html: function () {
|
||||||
|
var html = '<div class="medium-editor-table-builder-grid clearfix">';
|
||||||
|
html += this._cellsHTML();
|
||||||
|
html += '</div>';
|
||||||
|
return html;
|
||||||
|
},
|
||||||
|
|
||||||
|
_cellsHTML: function () {
|
||||||
|
var html = '';
|
||||||
|
this._generateCells();
|
||||||
|
this._cells.map(function (cell) {
|
||||||
|
html += '<a href="#" class="medium-editor-table-builder-cell' +
|
||||||
|
(cell.active === true ? ' active' : '') +
|
||||||
|
'" ' + 'data-row="' + cell.row +
|
||||||
|
'" data-column="' + cell.column + '">';
|
||||||
|
html += '</a>';
|
||||||
|
});
|
||||||
|
return html;
|
||||||
|
},
|
||||||
|
|
||||||
|
_render: function () {
|
||||||
|
this._root.innerHTML = this._html();
|
||||||
|
this._cellsElements = this._root.querySelectorAll('a');
|
||||||
|
this._bindEvents();
|
||||||
|
},
|
||||||
|
|
||||||
|
_bindEvents: function () {
|
||||||
|
[].forEach.call(this._cellsElements, function (el) {
|
||||||
|
this._onMouseEnter(el);
|
||||||
|
this._onClick(el);
|
||||||
|
}.bind(this));
|
||||||
|
},
|
||||||
|
|
||||||
|
_onMouseEnter: function (el) {
|
||||||
|
var self = this,
|
||||||
|
timer;
|
||||||
|
|
||||||
|
el.addEventListener('mouseenter', function () {
|
||||||
|
clearTimeout(timer);
|
||||||
|
|
||||||
|
var dataset = this.dataset;
|
||||||
|
|
||||||
|
timer = setTimeout(function () {
|
||||||
|
self._currentCell = {
|
||||||
|
column: parseInt(dataset.column, 10),
|
||||||
|
row: parseInt(dataset.row, 10)
|
||||||
|
};
|
||||||
|
self.markCells();
|
||||||
|
}, 50);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_onClick: function (el) {
|
||||||
|
var self = this;
|
||||||
|
el.addEventListener('click', function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
self._callback(this.dataset.row, this.dataset.column);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function Builder(options) {
|
||||||
|
return this.init(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
Builder.prototype = {
|
||||||
|
init: function (options) {
|
||||||
|
this.options = options;
|
||||||
|
this._doc = options.ownerDocument || document;
|
||||||
|
this._root = this._doc.createElement('div');
|
||||||
|
this._root.className = 'medium-editor-table-builder';
|
||||||
|
this.grid = new Grid(
|
||||||
|
this._root,
|
||||||
|
this.options.onClick,
|
||||||
|
this.options.rows,
|
||||||
|
this.options.columns
|
||||||
|
);
|
||||||
|
|
||||||
|
this._range = null;
|
||||||
|
this._toolbar = this._doc.createElement('div');
|
||||||
|
this._toolbar.className = 'medium-editor-table-builder-toolbar';
|
||||||
|
|
||||||
|
var spanRow = this._doc.createElement('span');
|
||||||
|
spanRow.innerHTML = 'Row:';
|
||||||
|
this._toolbar.appendChild(spanRow);
|
||||||
|
var addRowBefore = this._doc.createElement('button');
|
||||||
|
addRowBefore.title = 'Add row before';
|
||||||
|
addRowBefore.innerHTML = '<i class="fa fa-long-arrow-up"></i>';
|
||||||
|
addRowBefore.onclick = this.addRow.bind(this, true);
|
||||||
|
this._toolbar.appendChild(addRowBefore);
|
||||||
|
|
||||||
|
var addRowAfter = this._doc.createElement('button');
|
||||||
|
addRowAfter.title = 'Add row after';
|
||||||
|
addRowAfter.innerHTML = '<i class="fa fa-long-arrow-down"></i>';
|
||||||
|
addRowAfter.onclick = this.addRow.bind(this, false);
|
||||||
|
this._toolbar.appendChild(addRowAfter);
|
||||||
|
|
||||||
|
var remRow = this._doc.createElement('button');
|
||||||
|
remRow.title = 'Remove row';
|
||||||
|
remRow.innerHTML = '<i class="fa fa-close"></i>';
|
||||||
|
remRow.onclick = this.removeRow.bind(this);
|
||||||
|
this._toolbar.appendChild(remRow);
|
||||||
|
|
||||||
|
var spanCol = this._doc.createElement('span');
|
||||||
|
spanCol.innerHTML = 'Column:';
|
||||||
|
this._toolbar.appendChild(spanCol);
|
||||||
|
var addColumnBefore = this._doc.createElement('button');
|
||||||
|
addColumnBefore.title = 'Add column before';
|
||||||
|
addColumnBefore.innerHTML = '<i class="fa fa-long-arrow-left"></i>';
|
||||||
|
addColumnBefore.onclick = this.addColumn.bind(this, true);
|
||||||
|
this._toolbar.appendChild(addColumnBefore);
|
||||||
|
|
||||||
|
var addColumnAfter = this._doc.createElement('button');
|
||||||
|
addColumnAfter.title = 'Add column after';
|
||||||
|
addColumnAfter.innerHTML = '<i class="fa fa-long-arrow-right"></i>';
|
||||||
|
addColumnAfter.onclick = this.addColumn.bind(this, false);
|
||||||
|
this._toolbar.appendChild(addColumnAfter);
|
||||||
|
|
||||||
|
var remColumn = this._doc.createElement('button');
|
||||||
|
remColumn.title = 'Remove column';
|
||||||
|
remColumn.innerHTML = '<i class="fa fa-close"></i>';
|
||||||
|
remColumn.onclick = this.removeColumn.bind(this);
|
||||||
|
this._toolbar.appendChild(remColumn);
|
||||||
|
|
||||||
|
var remTable = this._doc.createElement('button');
|
||||||
|
remTable.title = 'Remove table';
|
||||||
|
remTable.innerHTML = '<i class="fa fa-trash-o"></i>';
|
||||||
|
remTable.onclick = this.removeTable.bind(this);
|
||||||
|
this._toolbar.appendChild(remTable);
|
||||||
|
|
||||||
|
var grid = this._root.childNodes[0];
|
||||||
|
this._root.insertBefore(this._toolbar, grid);
|
||||||
|
//console.log(this._root);
|
||||||
|
},
|
||||||
|
|
||||||
|
getElement: function () {
|
||||||
|
return this._root;
|
||||||
|
},
|
||||||
|
|
||||||
|
hide: function () {
|
||||||
|
this._root.style.display = '';
|
||||||
|
this.grid.setCurrentCell({ column: -1, row: -1 });
|
||||||
|
this.grid.markCells();
|
||||||
|
},
|
||||||
|
|
||||||
|
show: function (left) {
|
||||||
|
this._root.style.display = 'block';
|
||||||
|
this._root.style.left = left + 'px';
|
||||||
|
},
|
||||||
|
|
||||||
|
setEditor: function (range) {
|
||||||
|
this._range = range;
|
||||||
|
this._doc.getElementsByClassName('medium-editor-table-builder-toolbar')[0].style.display = 'block';
|
||||||
|
},
|
||||||
|
|
||||||
|
setBuilder: function () {
|
||||||
|
this._range = null;
|
||||||
|
this._doc.getElementsByClassName('medium-editor-table-builder-toolbar')[0].style.display = 'none';
|
||||||
|
var elements = this._doc.getElementsByClassName('medium-editor-table-builder-grid');
|
||||||
|
for (var i = 0; i < elements.length; i++) {
|
||||||
|
// TODO: what is 16 and what is 2?
|
||||||
|
elements[i].style.height = (16 * this.rows + 2) + 'px';
|
||||||
|
elements[i].style.width = (16 * this.columns + 2) + 'px';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
addRow: function (before, e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
// codepot
|
||||||
|
//var tbody = this._range.parentNode.parentNode,
|
||||||
|
// tr = this._doc.createElement('tr'),
|
||||||
|
// td;
|
||||||
|
var num_cols;
|
||||||
|
var tbody, tr, td;
|
||||||
|
|
||||||
|
tr = this._doc.createElement('tr');
|
||||||
|
|
||||||
|
var in_thead = this._range.parentNode.parentNode.tagName.toLowerCase() == 'thead';
|
||||||
|
if (in_thead)
|
||||||
|
{
|
||||||
|
// the current cell is the header.
|
||||||
|
var thead = this._range.parentNode.parentNode;
|
||||||
|
var table = thead.parentNode;
|
||||||
|
tbody = table.childNodes[1];
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tbody = this._range.parentNode.parentNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tbody.childNodes[0] && tbody.childNodes[0].childNodes[0] && tbody.childNodes[0].childNodes[0].tagName.toLowerCase() == 'th')
|
||||||
|
{
|
||||||
|
td = this._doc.createElement('th');
|
||||||
|
tr.appendChild(td);
|
||||||
|
num_cols = this._range.parentNode.childNodes.length - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
num_cols = this._range.parentNode.childNodes.length;
|
||||||
|
}
|
||||||
|
// end codepot
|
||||||
|
|
||||||
|
for (var i = 0; i < num_cols /*this._range.parentNode.childNodes.length*/; i++) {
|
||||||
|
td = this._doc.createElement('td');
|
||||||
|
td.appendChild(this._doc.createElement('br'));
|
||||||
|
tr.appendChild(td);
|
||||||
|
}
|
||||||
|
|
||||||
|
// codepot
|
||||||
|
if (in_thead) tbody.appendChild(tr);
|
||||||
|
// end codepot
|
||||||
|
else if (before !== true && this._range.parentNode.nextSibling) {
|
||||||
|
tbody.insertBefore(tr, this._range.parentNode.nextSibling);
|
||||||
|
} else if (before === true) {
|
||||||
|
tbody.insertBefore(tr, this._range.parentNode);
|
||||||
|
} else {
|
||||||
|
tbody.appendChild(tr);
|
||||||
|
}
|
||||||
|
// codepot
|
||||||
|
//this.options.onClick(0, 0);
|
||||||
|
this.options.onClick(-1, -1);
|
||||||
|
// end codepot
|
||||||
|
},
|
||||||
|
|
||||||
|
removeRow: function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
// codepot
|
||||||
|
if (this._range.parentNode.parentNode.tagName.toLowerCase() == 'thead') // remove the whole thead
|
||||||
|
this._range.parentNode.parentNode.parentNode.removeChild(this._range.parentNode.parentNode);
|
||||||
|
else
|
||||||
|
// end codepot
|
||||||
|
this._range.parentNode.parentNode.removeChild(this._range.parentNode);
|
||||||
|
|
||||||
|
// codepot
|
||||||
|
//this.options.onClick(0, 0);
|
||||||
|
this.options.onClick(-1, -1);
|
||||||
|
// end codepot
|
||||||
|
},
|
||||||
|
|
||||||
|
addColumn: function (before, e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
var cell = Array.prototype.indexOf.call(this._range.parentNode.childNodes, this._range);
|
||||||
|
var td;
|
||||||
|
|
||||||
|
// codepot
|
||||||
|
//var tbody = this._range.parentNode.parentNode;
|
||||||
|
var tbody;
|
||||||
|
|
||||||
|
var table = this._range.parentNode.parentNode.parentNode;
|
||||||
|
if (table.childNodes[0].tagName.toLowerCase() == 'thead')
|
||||||
|
{
|
||||||
|
var thead = table.childNodes[0];
|
||||||
|
if (thead.childNodes[0])
|
||||||
|
{
|
||||||
|
// tr is expected inside thead. if no <tr> exists, don't add a column
|
||||||
|
td = this._doc.createElement('th');
|
||||||
|
if (before)
|
||||||
|
thead.childNodes[0].insertBefore(td, thead.childNodes[0].childNodes[cell]);
|
||||||
|
else if (thead.childNodes[0].childNodes[cell].nextSibling)
|
||||||
|
thead.childNodes[0].insertBefore(td, thead.childNodes[0].childNodes[cell].nextSibling);
|
||||||
|
else
|
||||||
|
thead.childNodes[0].appendChild(td);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var in_thead = this._range.parentNode.parentNode.tagName.toLowerCase() == 'thead';
|
||||||
|
if (in_thead)
|
||||||
|
{
|
||||||
|
// the current cell is the header.
|
||||||
|
var thead = this._range.parentNode.parentNode;
|
||||||
|
var table = thead.parentNode;
|
||||||
|
tbody = table.childNodes[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tbody = this._range.parentNode.parentNode;
|
||||||
|
}
|
||||||
|
// end codepot
|
||||||
|
|
||||||
|
for (var i = 0; i < tbody.childNodes.length; i++) {
|
||||||
|
td = this._doc.createElement('td');
|
||||||
|
td.appendChild(this._doc.createElement('br'));
|
||||||
|
if (before === true) {
|
||||||
|
tbody.childNodes[i].insertBefore(td, tbody.childNodes[i].childNodes[cell]);
|
||||||
|
// codepot
|
||||||
|
//} else if (this._range.parentNode.parentNode.childNodes[i].childNodes[cell].nextSibling) {
|
||||||
|
} else if (tbody.childNodes[i].childNodes[cell].nextSibling) {
|
||||||
|
// end codepot
|
||||||
|
tbody.childNodes[i].insertBefore(td, tbody.childNodes[i].childNodes[cell].nextSibling);
|
||||||
|
} else {
|
||||||
|
tbody.childNodes[i].appendChild(td);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// codepot
|
||||||
|
//this.options.onClick(0, 0);
|
||||||
|
this.options.onClick(-1, -1);
|
||||||
|
// end codepot
|
||||||
|
},
|
||||||
|
|
||||||
|
removeColumn: function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
// codepot
|
||||||
|
//var cell = Array.prototype.indexOf.call(this._range.parentNode.childNodes, this._range),
|
||||||
|
// tbody = this._range.parentNode.parentNode,
|
||||||
|
// rows = tbody.childNodes.length;
|
||||||
|
|
||||||
|
var table, thead, tbody, rows;
|
||||||
|
var cell = Array.prototype.indexOf.call(this._range.parentNode.childNodes, this._range);
|
||||||
|
|
||||||
|
if (this._range.parentNode.parentNode.tagName.toLowerCase() == 'thead')
|
||||||
|
{
|
||||||
|
// the current cell is the header.
|
||||||
|
thead = this._range.parentNode.parentNode;
|
||||||
|
table = thead.parentNode;
|
||||||
|
tbody = table.childNodes[1];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tbody = this._range.parentNode.parentNode;
|
||||||
|
table = tbody.parentNode;
|
||||||
|
}
|
||||||
|
rows = tbody.childNodes.length;
|
||||||
|
|
||||||
|
if (table.childNodes[0].tagName.toLowerCase() == 'thead')
|
||||||
|
{
|
||||||
|
var thead = table.childNodes[0];
|
||||||
|
if (thead.childNodes[0])
|
||||||
|
{
|
||||||
|
// if no <tr> is inside <thead>, don't delete any.
|
||||||
|
thead.childNodes[0].removeChild (thead.childNodes[0].childNodes[cell]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// end codepot
|
||||||
|
|
||||||
|
for (var i = 0; i < rows; i++) {
|
||||||
|
tbody.childNodes[i].removeChild(tbody.childNodes[i].childNodes[cell]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// codepot
|
||||||
|
//this.options.onClick(0, 0);
|
||||||
|
this.options.onClick(-1, -1);
|
||||||
|
// end codepot
|
||||||
|
},
|
||||||
|
|
||||||
|
removeTable: function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
var cell = Array.prototype.indexOf.call(this._range.parentNode.childNodes, this._range),
|
||||||
|
table = this._range.parentNode.parentNode.parentNode;
|
||||||
|
|
||||||
|
table.parentNode.removeChild(table);
|
||||||
|
this.options.onClick(0, 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
function Table(editor) {
|
||||||
|
return this.init(editor);
|
||||||
|
}
|
||||||
|
|
||||||
|
var TAB_KEY_CODE = 9;
|
||||||
|
|
||||||
|
Table.prototype = {
|
||||||
|
init: function (editor) {
|
||||||
|
this._editor = editor;
|
||||||
|
this._doc = this._editor.options.ownerDocument;
|
||||||
|
this._bindTabBehavior();
|
||||||
|
},
|
||||||
|
|
||||||
|
insert: function (rows, cols) {
|
||||||
|
|
||||||
|
var html = this._html(rows, cols);
|
||||||
|
// codepot
|
||||||
|
var header = this._header(rows, cols);
|
||||||
|
// end codepot
|
||||||
|
|
||||||
|
this._editor.pasteHTML(
|
||||||
|
'<table class="medium-editor-table" id="medium-editor-table"' +
|
||||||
|
' >' +
|
||||||
|
// codepot
|
||||||
|
'<thead>' +
|
||||||
|
header +
|
||||||
|
'</thead>' +
|
||||||
|
// end codepot
|
||||||
|
'<tbody>' +
|
||||||
|
html +
|
||||||
|
'</tbody>' +
|
||||||
|
'</table>', {
|
||||||
|
cleanAttrs: [],
|
||||||
|
cleanTags: []
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
var table = this._doc.getElementById('medium-editor-table');
|
||||||
|
table.removeAttribute('id');
|
||||||
|
placeCaretAtNode(this._doc, table.querySelector('td'), true);
|
||||||
|
|
||||||
|
this._editor.checkSelection();
|
||||||
|
},
|
||||||
|
|
||||||
|
// codepot
|
||||||
|
_header: function (rows, cols) {
|
||||||
|
var html = '', x, y;
|
||||||
|
|
||||||
|
for (x = 0; x < 1; x++) {
|
||||||
|
html += '<tr><th></th>';
|
||||||
|
for (y = 0; y <= cols; y++) {
|
||||||
|
html += '<th>' + y + '</th>';
|
||||||
|
}
|
||||||
|
html += '</tr>';
|
||||||
|
}
|
||||||
|
return html;
|
||||||
|
},
|
||||||
|
// end codepot
|
||||||
|
|
||||||
|
_html: function (rows, cols) {
|
||||||
|
var html = '',
|
||||||
|
x, y,
|
||||||
|
text = getSelectionText(this._doc);
|
||||||
|
|
||||||
|
for (x = 0; x <= rows; x++) {
|
||||||
|
// codepot
|
||||||
|
html += '<tr><th>' + x + '</th>';
|
||||||
|
// end codepot
|
||||||
|
for (y = 0; y <= cols; y++) {
|
||||||
|
html += '<td>' + (x === 0 && y === 0 ? text : '<br />') + '</td>';
|
||||||
|
}
|
||||||
|
html += '</tr>';
|
||||||
|
}
|
||||||
|
return html;
|
||||||
|
},
|
||||||
|
|
||||||
|
_bindTabBehavior: function () {
|
||||||
|
var self = this;
|
||||||
|
[].forEach.call(this._editor.elements, function (el) {
|
||||||
|
el.addEventListener('keydown', function (e) {
|
||||||
|
self._onKeyDown(e);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
_onKeyDown: function (e) {
|
||||||
|
var el = getSelectionStart(this._doc),
|
||||||
|
table;
|
||||||
|
|
||||||
|
if (e.which === TAB_KEY_CODE && isInsideElementOfTag(el, 'table')) {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
table = this._getTableElements(el);
|
||||||
|
if (e.shiftKey) {
|
||||||
|
this._tabBackwards(el.previousSibling, table.row);
|
||||||
|
} else {
|
||||||
|
// codepot - note table.row or table.cell tends to become null in firefox
|
||||||
|
// when moving between cells with a tab key. the el passed
|
||||||
|
// seems to get wrong in firefox.
|
||||||
|
if (this._isLastCell(el, table.row, table.root)) {
|
||||||
|
// codepot
|
||||||
|
if (table.row.cells[0].tagName.toLowerCase() == 'th')
|
||||||
|
this._insertRow(getParentOf(el, 'tbody'), table.row.cells.length - 1, 1);
|
||||||
|
else
|
||||||
|
// end codepot
|
||||||
|
this._insertRow(getParentOf(el, 'tbody'), table.row.cells.length, 0);
|
||||||
|
}
|
||||||
|
placeCaretAtNode(this._doc, el);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_getTableElements: function (el) {
|
||||||
|
return {
|
||||||
|
// codepot
|
||||||
|
//cell: getParentOf(el, 'td'),
|
||||||
|
cell: getParentOf(el, el.tagName.toLowerCase()),
|
||||||
|
// end codepot
|
||||||
|
row: getParentOf(el, 'tr'),
|
||||||
|
root: getParentOf(el, 'table')
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
_tabBackwards: function (el, row) {
|
||||||
|
el = el || this._getPreviousRowLastCell(row);
|
||||||
|
placeCaretAtNode(this._doc, el, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
_insertRow: function (tbody, cols, prepend_th) {
|
||||||
|
var tr = document.createElement('tr'),
|
||||||
|
html = '',
|
||||||
|
i;
|
||||||
|
|
||||||
|
if (prepend_th) html += '<th><br /></th>';
|
||||||
|
for (i = 0; i < cols; i += 1) {
|
||||||
|
html += '<td><br /></td>';
|
||||||
|
}
|
||||||
|
tr.innerHTML = html;
|
||||||
|
tbody.appendChild(tr);
|
||||||
|
},
|
||||||
|
|
||||||
|
_isLastCell: function (el, row, table) {
|
||||||
|
return (
|
||||||
|
(row.cells.length - 1) === el.cellIndex &&
|
||||||
|
(table.rows.length - 1) === row.rowIndex
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
_getPreviousRowLastCell: function (row) {
|
||||||
|
row = row.previousSibling;
|
||||||
|
if (row) {
|
||||||
|
return row.cells[row.cells.length - 1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var MediumEditorTable = MediumEditor.extensions.form.extend({
|
||||||
|
name: 'table',
|
||||||
|
|
||||||
|
aria: 'create table',
|
||||||
|
action: 'table',
|
||||||
|
contentDefault: 'TBL',
|
||||||
|
contentFA: '<i class="fa fa-table"></i>',
|
||||||
|
|
||||||
|
handleClick: function (event) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
this[this.isActive() === true ? 'hide' : 'show']();
|
||||||
|
},
|
||||||
|
|
||||||
|
hide: function () {
|
||||||
|
this.setInactive();
|
||||||
|
this.builder.hide();
|
||||||
|
},
|
||||||
|
|
||||||
|
show: function () {
|
||||||
|
this.setActive();
|
||||||
|
|
||||||
|
var range = MediumEditor.selection.getSelectionRange(this.document);
|
||||||
|
if (range.startContainer.nodeName.toLowerCase() === 'td' ||
|
||||||
|
range.endContainer.nodeName.toLowerCase() === 'td' ||
|
||||||
|
MediumEditor.util.getClosestTag(MediumEditor.selection.getSelectedParentElement(range), 'td')) {
|
||||||
|
this.builder.setEditor(MediumEditor.selection.getSelectedParentElement(range));
|
||||||
|
// codepot
|
||||||
|
} else if (range.startContainer.nodeName.toLowerCase() === 'th' ||
|
||||||
|
range.endContainer.nodeName.toLowerCase() === 'th' ||
|
||||||
|
MediumEditor.util.getClosestTag(MediumEditor.selection.getSelectedParentElement(range), 'th')) {
|
||||||
|
this.builder.setEditor(MediumEditor.selection.getSelectedParentElement(range));
|
||||||
|
// end codepot
|
||||||
|
} else {
|
||||||
|
this.builder.setBuilder();
|
||||||
|
}
|
||||||
|
this.builder.show(this.button.offsetLeft);
|
||||||
|
},
|
||||||
|
|
||||||
|
getForm: function () {
|
||||||
|
this.builder = new Builder({
|
||||||
|
onClick: function (rows, columns) {
|
||||||
|
// codepot
|
||||||
|
//if (rows > 0 && columns > 0) {
|
||||||
|
if (rows >= 0 && columns >= 0) {
|
||||||
|
// end codepot
|
||||||
|
this.table.insert(rows, columns);
|
||||||
|
}
|
||||||
|
this.hide();
|
||||||
|
}.bind(this),
|
||||||
|
ownerDocument: this.document,
|
||||||
|
rows: this.rows || 10,
|
||||||
|
columns: this.columns || 10
|
||||||
|
});
|
||||||
|
|
||||||
|
this.table = new Table(this.base);
|
||||||
|
|
||||||
|
return this.builder.getElement();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return MediumEditorTable;
|
||||||
|
}()));
|
1
codepot/src/js/medium-editor-tables.min.js
vendored
1
codepot/src/js/medium-editor-tables.min.js
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user