diff --git a/lib/wysihtml/rails/version.rb b/lib/wysihtml/rails/version.rb
index 91f6d9a..61f7829 100644
--- a/lib/wysihtml/rails/version.rb
+++ b/lib/wysihtml/rails/version.rb
@@ -1,5 +1,5 @@
module Wysihtml
module Rails
- VERSION = "0.5.0.beta3"
+ VERSION = "0.5.0.beta4"
end
end
diff --git a/vendor/assets/javascripts/parser_rules/advanced.js b/vendor/assets/javascripts/parser_rules/advanced.js
index 04c1cfd..73d2df6 100644
--- a/vendor/assets/javascripts/parser_rules/advanced.js
+++ b/vendor/assets/javascripts/parser_rules/advanced.js
@@ -223,9 +223,6 @@ var wysihtml5ParserRules = {
"bgsound": {
"remove": 1
},
- "sup": {
- "rename_tag": "span"
- },
"address": {
"rename_tag": "div"
},
@@ -543,9 +540,7 @@ var wysihtml5ParserRules = {
"align": "align_text"
}
},
- "sub": {
- "rename_tag": "span"
- },
+ "sub": {},
"comment": {
"remove": 1
},
@@ -557,6 +552,7 @@ var wysihtml5ParserRules = {
},
"header": {
"rename_tag": "div"
- }
+ },
+ "sup": {}
}
};
diff --git a/vendor/assets/javascripts/parser_rules/advanced_and_extended.js b/vendor/assets/javascripts/parser_rules/advanced_and_extended.js
index 43cf038..40cb3f2 100644
--- a/vendor/assets/javascripts/parser_rules/advanced_and_extended.js
+++ b/vendor/assets/javascripts/parser_rules/advanced_and_extended.js
@@ -277,9 +277,7 @@ var wysihtml5ParserRules = {
"bgsound": {
"remove": 1
},
- "sup": {
- "unwrap": 1
- },
+ "sup": {},
"address": {
"unwrap": 1
},
@@ -627,9 +625,7 @@ var wysihtml5ParserRules = {
"unwrap": 1
},
"p": wysihtml5ParserRulesDefaults.blockLevelEl,
- "sub": {
- "unwrap": 1
- },
+ "sub": {},
"comment": {
"remove": 1
},
diff --git a/vendor/assets/javascripts/parser_rules/advanced_unwrap.js b/vendor/assets/javascripts/parser_rules/advanced_unwrap.js
index 9b55ac7..4bcae64 100644
--- a/vendor/assets/javascripts/parser_rules/advanced_unwrap.js
+++ b/vendor/assets/javascripts/parser_rules/advanced_unwrap.js
@@ -304,9 +304,7 @@ var wysihtml5ParserRules = {
"bgsound": {
"remove": 1
},
- "sup": {
- "unwrap": 1
- },
+ "sup": {},
"address": {
"unwrap": 1
},
@@ -648,9 +646,7 @@ var wysihtml5ParserRules = {
"align": "align_text"
}
},
- "sub": {
- "unwrap": 1
- },
+ "sub": {},
"comment": {
"remove": 1
},
diff --git a/vendor/assets/javascripts/wysihtml-toolbar.js b/vendor/assets/javascripts/wysihtml-toolbar.js
index e7fb044..f3a7016 100644
--- a/vendor/assets/javascripts/wysihtml-toolbar.js
+++ b/vendor/assets/javascripts/wysihtml-toolbar.js
@@ -375,9 +375,8 @@ if ("document" in self) {
}
}
-
;/**
- * @license wysihtml5x v0.5.0-beta3
+ * @license wysihtml5x v0.5.0-beta4
* https://github.com/Edicy/wysihtml5
*
* Author: Christopher Blum (https://github.com/tiff)
@@ -388,7 +387,7 @@ if ("document" in self) {
*
*/
var wysihtml5 = {
- version: "0.5.0-beta3",
+ version: "0.5.0-beta4",
// namespaces
commands: {},
@@ -4927,7 +4926,7 @@ wysihtml5.browser = (function() {
},
supportsMutationEvents: function() {
- return ("MutationEvent" in window);
+ return ("MutationEvent" in window);
},
/**
@@ -5878,7 +5877,8 @@ wysihtml5.dom.copyAttributes = function(attributesToCopy) {
};
};
-})(wysihtml5);;/**
+})(wysihtml5);
+;/**
* Returns the given html wrapped in a div element
*
* Fixing IE's inability to treat unknown elements (HTML5 section, article, ...) correctly
@@ -5972,7 +5972,8 @@ wysihtml5.dom.getParentElement = (function() {
return null;
};
-})();;/**
+})();
+;/**
* Get element's style for a specific css property
*
* @param {Element} element The element on which to retrieve the style
@@ -6057,7 +6058,8 @@ wysihtml5.dom.getStyle = (function() {
}
}
return all;
-};;/**
+};
+;/**
* High performant way to check whether an element with a specific tag name is in the given document
* Optimized for being heavily executed
* Unleashes the power of live node lists
@@ -7181,7 +7183,11 @@ wysihtml5.dom.renameElement = function(element, newNodeName) {
newElement.appendChild(firstChild);
}
wysihtml5.dom.copyAttributes(["align", "className"]).from(element).to(newElement);
- element.parentNode.replaceChild(newElement, element);
+
+ if (element.parentNode) {
+ element.parentNode.replaceChild(newElement, element);
+ }
+
return newElement;
};
;/**
@@ -7567,7 +7573,7 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
},
getWindow: function() {
- return this.element.ownerDocument.defaultView;
+ return this.element.ownerDocument.defaultView || this.element.ownerDocument.parentWindow;
},
getDocument: function() {
@@ -7594,29 +7600,19 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
// initiates an allready existent contenteditable
_bindElement: function(contentEditable) {
- contentEditable.className = (contentEditable.className && contentEditable.className != '') ? contentEditable.className + " wysihtml5-sandbox" : "wysihtml5-sandbox";
+ contentEditable.className = (contentEditable.className && contentEditable.className !== '') ? contentEditable.className + " wysihtml5-sandbox" : "wysihtml5-sandbox";
this._loadElement(contentEditable, true);
return contentEditable;
},
_loadElement: function(element, contentExists) {
- var that = this;
+ var that = this;
+
if (!contentExists) {
- var sandboxHtml = this._getHtml();
- element.innerHTML = sandboxHtml;
+ var innerHtml = this._getHtml();
+ element.innerHTML = innerHtml;
}
- this.getWindow = function() { return element.ownerDocument.defaultView; };
- this.getDocument = function() { return element.ownerDocument; };
-
- // Catch js errors and pass them to the parent's onerror event
- // addEventListener("error") doesn't work properly in some browsers
- // TODO: apparently this doesn't work in IE9!
- // TODO: figure out and bind the errors logic for contenteditble mode
- /*iframeWindow.onerror = function(errorMessage, fileName, lineNumber) {
- throw new Error("wysihtml5.Sandbox: " + errorMessage, fileName, lineNumber);
- }
- */
this.loaded = true;
// Trigger the callback
setTimeout(function() { that.callback(that); }, 0);
@@ -7741,7 +7737,6 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
};
}
})(wysihtml5.dom);
-
;/**
* Get a set of attribute from one element
*
@@ -7805,7 +7800,8 @@ wysihtml5.dom.getAttributes = function(node) {
}
}
return attributes;
-};;/**
+};
+;/**
* Check whether the given node is a proper loaded image
* FIXME: Returns undefined when unknown (Chrome, Safari)
*/
@@ -7821,884 +7817,881 @@ wysihtml5.dom.isLoadedImage = function (node) {
};
;(function(wysihtml5) {
- var api = wysihtml5.dom;
-
- var MapCell = function(cell) {
- this.el = cell;
- this.isColspan= false;
- this.isRowspan= false;
- this.firstCol= true;
- this.lastCol= true;
- this.firstRow= true;
- this.lastRow= true;
- this.isReal= true;
- this.spanCollection= [];
- this.modified = false;
- };
+ var api = wysihtml5.dom;
- var TableModifyerByCell = function (cell, table) {
- if (cell) {
- this.cell = cell;
- this.table = api.getParentElement(cell, { query: "table" });
- } else if (table) {
- this.table = table;
- this.cell = this.table.querySelectorAll('th, td')[0];
- }
- };
+ var MapCell = function(cell) {
+ this.el = cell;
+ this.isColspan= false;
+ this.isRowspan= false;
+ this.firstCol= true;
+ this.lastCol= true;
+ this.firstRow= true;
+ this.lastRow= true;
+ this.isReal= true;
+ this.spanCollection= [];
+ this.modified = false;
+ };
- function queryInList(list, query) {
- var ret = [],
- q;
- for (var e = 0, len = list.length; e < len; e++) {
- q = list[e].querySelectorAll(query);
- if (q) {
- for(var i = q.length; i--; ret.unshift(q[i]));
- }
- }
- return ret;
+ var TableModifyerByCell = function (cell, table) {
+ if (cell) {
+ this.cell = cell;
+ this.table = api.getParentElement(cell, { query: "table" });
+ } else if (table) {
+ this.table = table;
+ this.cell = this.table.querySelectorAll('th, td')[0];
}
+ };
- function removeElement(el) {
- el.parentNode.removeChild(el);
+ function queryInList(list, query) {
+ var ret = [],
+ q;
+ for (var e = 0, len = list.length; e < len; e++) {
+ q = list[e].querySelectorAll(query);
+ if (q) {
+ for(var i = q.length; i--; ret.unshift(q[i]));
+ }
}
+ return ret;
+ }
- function insertAfter(referenceNode, newNode) {
- referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
- }
+ function removeElement(el) {
+ el.parentNode.removeChild(el);
+ }
- function nextNode(node, tag) {
- var element = node.nextSibling;
- while (element.nodeType !=1) {
- element = element.nextSibling;
- if (!tag || tag == element.tagName.toLowerCase()) {
- return element;
- }
- }
- return null;
+ function insertAfter(referenceNode, newNode) {
+ referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
+ }
+
+ function nextNode(node, tag) {
+ var element = node.nextSibling;
+ while (element.nodeType !=1) {
+ element = element.nextSibling;
+ if (!tag || tag == element.tagName.toLowerCase()) {
+ return element;
+ }
}
+ return null;
+ }
- TableModifyerByCell.prototype = {
+ TableModifyerByCell.prototype = {
- addSpannedCellToMap: function(cell, map, r, c, cspan, rspan) {
- var spanCollect = [],
- rmax = r + ((rspan) ? parseInt(rspan, 10) - 1 : 0),
- cmax = c + ((cspan) ? parseInt(cspan, 10) - 1 : 0);
+ addSpannedCellToMap: function(cell, map, r, c, cspan, rspan) {
+ var spanCollect = [],
+ rmax = r + ((rspan) ? parseInt(rspan, 10) - 1 : 0),
+ cmax = c + ((cspan) ? parseInt(cspan, 10) - 1 : 0);
- for (var rr = r; rr <= rmax; rr++) {
- if (typeof map[rr] == "undefined") { map[rr] = []; }
- for (var cc = c; cc <= cmax; cc++) {
- map[rr][cc] = new MapCell(cell);
- map[rr][cc].isColspan = (cspan && parseInt(cspan, 10) > 1);
- map[rr][cc].isRowspan = (rspan && parseInt(rspan, 10) > 1);
- map[rr][cc].firstCol = cc == c;
- map[rr][cc].lastCol = cc == cmax;
- map[rr][cc].firstRow = rr == r;
- map[rr][cc].lastRow = rr == rmax;
- map[rr][cc].isReal = cc == c && rr == r;
- map[rr][cc].spanCollection = spanCollect;
+ for (var rr = r; rr <= rmax; rr++) {
+ if (typeof map[rr] == "undefined") { map[rr] = []; }
+ for (var cc = c; cc <= cmax; cc++) {
+ map[rr][cc] = new MapCell(cell);
+ map[rr][cc].isColspan = (cspan && parseInt(cspan, 10) > 1);
+ map[rr][cc].isRowspan = (rspan && parseInt(rspan, 10) > 1);
+ map[rr][cc].firstCol = cc == c;
+ map[rr][cc].lastCol = cc == cmax;
+ map[rr][cc].firstRow = rr == r;
+ map[rr][cc].lastRow = rr == rmax;
+ map[rr][cc].isReal = cc == c && rr == r;
+ map[rr][cc].spanCollection = spanCollect;
- spanCollect.push(map[rr][cc]);
- }
- }
- },
+ spanCollect.push(map[rr][cc]);
+ }
+ }
+ },
- setCellAsModified: function(cell) {
- cell.modified = true;
- if (cell.spanCollection.length > 0) {
- for (var s = 0, smax = cell.spanCollection.length; s < smax; s++) {
- cell.spanCollection[s].modified = true;
- }
- }
- },
+ setCellAsModified: function(cell) {
+ cell.modified = true;
+ if (cell.spanCollection.length > 0) {
+ for (var s = 0, smax = cell.spanCollection.length; s < smax; s++) {
+ cell.spanCollection[s].modified = true;
+ }
+ }
+ },
- setTableMap: function() {
- var map = [];
- var tableRows = this.getTableRows(),
- ridx, row, cells, cidx, cell,
- c,
- cspan, rspan;
-
- for (ridx = 0; ridx < tableRows.length; ridx++) {
- row = tableRows[ridx];
- cells = this.getRowCells(row);
- c = 0;
- if (typeof map[ridx] == "undefined") { map[ridx] = []; }
- for (cidx = 0; cidx < cells.length; cidx++) {
- cell = cells[cidx];
-
- // If cell allready set means it is set by col or rowspan,
- // so increase cols index until free col is found
- while (typeof map[ridx][c] != "undefined") { c++; }
-
- cspan = api.getAttribute(cell, 'colspan');
- rspan = api.getAttribute(cell, 'rowspan');
-
- if (cspan || rspan) {
- this.addSpannedCellToMap(cell, map, ridx, c, cspan, rspan);
- c = c + ((cspan) ? parseInt(cspan, 10) : 1);
- } else {
- map[ridx][c] = new MapCell(cell);
- c++;
- }
- }
- }
- this.map = map;
- return map;
- },
+ setTableMap: function() {
+ var map = [];
+ var tableRows = this.getTableRows(),
+ ridx, row, cells, cidx, cell,
+ c,
+ cspan, rspan;
- getRowCells: function(row) {
- var inlineTables = this.table.querySelectorAll('table'),
- inlineCells = (inlineTables) ? queryInList(inlineTables, 'th, td') : [],
- allCells = row.querySelectorAll('th, td'),
- tableCells = (inlineCells.length > 0) ? wysihtml5.lang.array(allCells).without(inlineCells) : allCells;
+ for (ridx = 0; ridx < tableRows.length; ridx++) {
+ row = tableRows[ridx];
+ cells = this.getRowCells(row);
+ c = 0;
+ if (typeof map[ridx] == "undefined") { map[ridx] = []; }
+ for (cidx = 0; cidx < cells.length; cidx++) {
+ cell = cells[cidx];
- return tableCells;
- },
+ // If cell allready set means it is set by col or rowspan,
+ // so increase cols index until free col is found
+ while (typeof map[ridx][c] != "undefined") { c++; }
- getTableRows: function() {
- var inlineTables = this.table.querySelectorAll('table'),
- inlineRows = (inlineTables) ? queryInList(inlineTables, 'tr') : [],
- allRows = this.table.querySelectorAll('tr'),
- tableRows = (inlineRows.length > 0) ? wysihtml5.lang.array(allRows).without(inlineRows) : allRows;
+ cspan = api.getAttribute(cell, 'colspan');
+ rspan = api.getAttribute(cell, 'rowspan');
- return tableRows;
- },
+ if (cspan || rspan) {
+ this.addSpannedCellToMap(cell, map, ridx, c, cspan, rspan);
+ c = c + ((cspan) ? parseInt(cspan, 10) : 1);
+ } else {
+ map[ridx][c] = new MapCell(cell);
+ c++;
+ }
+ }
+ }
+ this.map = map;
+ return map;
+ },
- getMapIndex: function(cell) {
- var r_length = this.map.length,
- c_length = (this.map && this.map[0]) ? this.map[0].length : 0;
+ getRowCells: function(row) {
+ var inlineTables = this.table.querySelectorAll('table'),
+ inlineCells = (inlineTables) ? queryInList(inlineTables, 'th, td') : [],
+ allCells = row.querySelectorAll('th, td'),
+ tableCells = (inlineCells.length > 0) ? wysihtml5.lang.array(allCells).without(inlineCells) : allCells;
- for (var r_idx = 0;r_idx < r_length; r_idx++) {
- for (var c_idx = 0;c_idx < c_length; c_idx++) {
- if (this.map[r_idx][c_idx].el === cell) {
- return {'row': r_idx, 'col': c_idx};
- }
- }
- }
- return false;
- },
+ return tableCells;
+ },
- getElementAtIndex: function(idx) {
- this.setTableMap();
- if (this.map[idx.row] && this.map[idx.row][idx.col] && this.map[idx.row][idx.col].el) {
- return this.map[idx.row][idx.col].el;
- }
- return null;
- },
+ getTableRows: function() {
+ var inlineTables = this.table.querySelectorAll('table'),
+ inlineRows = (inlineTables) ? queryInList(inlineTables, 'tr') : [],
+ allRows = this.table.querySelectorAll('tr'),
+ tableRows = (inlineRows.length > 0) ? wysihtml5.lang.array(allRows).without(inlineRows) : allRows;
- getMapElsTo: function(to_cell) {
- var els = [];
- this.setTableMap();
- this.idx_start = this.getMapIndex(this.cell);
- this.idx_end = this.getMapIndex(to_cell);
+ return tableRows;
+ },
- // switch indexes if start is bigger than end
- if (this.idx_start.row > this.idx_end.row || (this.idx_start.row == this.idx_end.row && this.idx_start.col > this.idx_end.col)) {
- var temp_idx = this.idx_start;
- this.idx_start = this.idx_end;
- this.idx_end = temp_idx;
- }
- if (this.idx_start.col > this.idx_end.col) {
- var temp_cidx = this.idx_start.col;
- this.idx_start.col = this.idx_end.col;
- this.idx_end.col = temp_cidx;
- }
+ getMapIndex: function(cell) {
+ var r_length = this.map.length,
+ c_length = (this.map && this.map[0]) ? this.map[0].length : 0;
- if (this.idx_start != null && this.idx_end != null) {
- for (var row = this.idx_start.row, maxr = this.idx_end.row; row <= maxr; row++) {
- for (var col = this.idx_start.col, maxc = this.idx_end.col; col <= maxc; col++) {
- els.push(this.map[row][col].el);
- }
- }
- }
- return els;
- },
+ for (var r_idx = 0;r_idx < r_length; r_idx++) {
+ for (var c_idx = 0;c_idx < c_length; c_idx++) {
+ if (this.map[r_idx][c_idx].el === cell) {
+ return {'row': r_idx, 'col': c_idx};
+ }
+ }
+ }
+ return false;
+ },
- orderSelectionEnds: function(secondcell) {
- this.setTableMap();
- this.idx_start = this.getMapIndex(this.cell);
- this.idx_end = this.getMapIndex(secondcell);
+ getElementAtIndex: function(idx) {
+ this.setTableMap();
+ if (this.map[idx.row] && this.map[idx.row][idx.col] && this.map[idx.row][idx.col].el) {
+ return this.map[idx.row][idx.col].el;
+ }
+ return null;
+ },
- // switch indexes if start is bigger than end
- if (this.idx_start.row > this.idx_end.row || (this.idx_start.row == this.idx_end.row && this.idx_start.col > this.idx_end.col)) {
- var temp_idx = this.idx_start;
- this.idx_start = this.idx_end;
- this.idx_end = temp_idx;
- }
- if (this.idx_start.col > this.idx_end.col) {
- var temp_cidx = this.idx_start.col;
- this.idx_start.col = this.idx_end.col;
- this.idx_end.col = temp_cidx;
- }
+ getMapElsTo: function(to_cell) {
+ var els = [];
+ this.setTableMap();
+ this.idx_start = this.getMapIndex(this.cell);
+ this.idx_end = this.getMapIndex(to_cell);
- return {
- "start": this.map[this.idx_start.row][this.idx_start.col].el,
- "end": this.map[this.idx_end.row][this.idx_end.col].el
- };
- },
+ // switch indexes if start is bigger than end
+ if (this.idx_start.row > this.idx_end.row || (this.idx_start.row == this.idx_end.row && this.idx_start.col > this.idx_end.col)) {
+ var temp_idx = this.idx_start;
+ this.idx_start = this.idx_end;
+ this.idx_end = temp_idx;
+ }
+ if (this.idx_start.col > this.idx_end.col) {
+ var temp_cidx = this.idx_start.col;
+ this.idx_start.col = this.idx_end.col;
+ this.idx_end.col = temp_cidx;
+ }
- createCells: function(tag, nr, attrs) {
- var doc = this.table.ownerDocument,
- frag = doc.createDocumentFragment(),
- cell;
- for (var i = 0; i < nr; i++) {
- cell = doc.createElement(tag);
-
- if (attrs) {
- for (var attr in attrs) {
- if (attrs.hasOwnProperty(attr)) {
- cell.setAttribute(attr, attrs[attr]);
- }
- }
- }
+ if (this.idx_start != null && this.idx_end != null) {
+ for (var row = this.idx_start.row, maxr = this.idx_end.row; row <= maxr; row++) {
+ for (var col = this.idx_start.col, maxc = this.idx_end.col; col <= maxc; col++) {
+ els.push(this.map[row][col].el);
+ }
+ }
+ }
+ return els;
+ },
- // add non breaking space
- cell.appendChild(document.createTextNode("\u00a0"));
+ orderSelectionEnds: function(secondcell) {
+ this.setTableMap();
+ this.idx_start = this.getMapIndex(this.cell);
+ this.idx_end = this.getMapIndex(secondcell);
- frag.appendChild(cell);
- }
- return frag;
- },
+ // switch indexes if start is bigger than end
+ if (this.idx_start.row > this.idx_end.row || (this.idx_start.row == this.idx_end.row && this.idx_start.col > this.idx_end.col)) {
+ var temp_idx = this.idx_start;
+ this.idx_start = this.idx_end;
+ this.idx_end = temp_idx;
+ }
+ if (this.idx_start.col > this.idx_end.col) {
+ var temp_cidx = this.idx_start.col;
+ this.idx_start.col = this.idx_end.col;
+ this.idx_end.col = temp_cidx;
+ }
- // Returns next real cell (not part of spanned cell unless first) on row if selected index is not real. I no real cells -1 will be returned
- correctColIndexForUnreals: function(col, row) {
- var r = this.map[row],
- corrIdx = -1;
- for (var i = 0, max = col; i < col; i++) {
- if (r[i].isReal){
- corrIdx++;
- }
- }
- return corrIdx;
- },
+ return {
+ "start": this.map[this.idx_start.row][this.idx_start.col].el,
+ "end": this.map[this.idx_end.row][this.idx_end.col].el
+ };
+ },
- getLastNewCellOnRow: function(row, rowLimit) {
- var cells = this.getRowCells(row),
- cell, idx;
+ createCells: function(tag, nr, attrs) {
+ var doc = this.table.ownerDocument,
+ frag = doc.createDocumentFragment(),
+ cell;
+ for (var i = 0; i < nr; i++) {
+ cell = doc.createElement(tag);
- for (var cidx = 0, cmax = cells.length; cidx < cmax; cidx++) {
- cell = cells[cidx];
- idx = this.getMapIndex(cell);
- if (idx === false || (typeof rowLimit != "undefined" && idx.row != rowLimit)) {
- return cell;
- }
+ if (attrs) {
+ for (var attr in attrs) {
+ if (attrs.hasOwnProperty(attr)) {
+ cell.setAttribute(attr, attrs[attr]);
}
- return null;
- },
+ }
+ }
- removeEmptyTable: function() {
- var cells = this.table.querySelectorAll('td, th');
- if (!cells || cells.length == 0) {
- removeElement(this.table);
- return true;
- } else {
- return false;
- }
- },
+ // add non breaking space
+ cell.appendChild(document.createTextNode("\u00a0"));
+ frag.appendChild(cell);
+ }
+ return frag;
+ },
- // Splits merged cell on row to unique cells
- splitRowToCells: function(cell) {
- if (cell.isColspan) {
- var colspan = parseInt(api.getAttribute(cell.el, 'colspan') || 1, 10),
- cType = cell.el.tagName.toLowerCase();
- if (colspan > 1) {
- var newCells = this.createCells(cType, colspan -1);
- insertAfter(cell.el, newCells);
- }
- cell.el.removeAttribute('colspan');
- }
- },
+ // Returns next real cell (not part of spanned cell unless first) on row if selected index is not real. I no real cells -1 will be returned
+ correctColIndexForUnreals: function(col, row) {
+ var r = this.map[row],
+ corrIdx = -1;
+ for (var i = 0, max = col; i < col; i++) {
+ if (r[i].isReal){
+ corrIdx++;
+ }
+ }
+ return corrIdx;
+ },
- getRealRowEl: function(force, idx) {
- var r = null,
- c = null;
+ getLastNewCellOnRow: function(row, rowLimit) {
+ var cells = this.getRowCells(row),
+ cell, idx;
- idx = idx || this.idx;
+ for (var cidx = 0, cmax = cells.length; cidx < cmax; cidx++) {
+ cell = cells[cidx];
+ idx = this.getMapIndex(cell);
+ if (idx === false || (typeof rowLimit != "undefined" && idx.row != rowLimit)) {
+ return cell;
+ }
+ }
+ return null;
+ },
- for (var cidx = 0, cmax = this.map[idx.row].length; cidx < cmax; cidx++) {
- c = this.map[idx.row][cidx];
- if (c.isReal) {
- r = api.getParentElement(c.el, { query: "tr" });
- if (r) {
- return r;
- }
- }
- }
+ removeEmptyTable: function() {
+ var cells = this.table.querySelectorAll('td, th');
+ if (!cells || cells.length == 0) {
+ removeElement(this.table);
+ return true;
+ } else {
+ return false;
+ }
+ },
- if (r === null && force) {
- r = api.getParentElement(this.map[idx.row][idx.col].el, { query: "tr" }) || null;
- }
+ // Splits merged cell on row to unique cells
+ splitRowToCells: function(cell) {
+ if (cell.isColspan) {
+ var colspan = parseInt(api.getAttribute(cell.el, 'colspan') || 1, 10),
+ cType = cell.el.tagName.toLowerCase();
+ if (colspan > 1) {
+ var newCells = this.createCells(cType, colspan -1);
+ insertAfter(cell.el, newCells);
+ }
+ cell.el.removeAttribute('colspan');
+ }
+ },
+
+ getRealRowEl: function(force, idx) {
+ var r = null,
+ c = null;
+ idx = idx || this.idx;
+
+ for (var cidx = 0, cmax = this.map[idx.row].length; cidx < cmax; cidx++) {
+ c = this.map[idx.row][cidx];
+ if (c.isReal) {
+ r = api.getParentElement(c.el, { query: "tr" });
+ if (r) {
return r;
- },
+ }
+ }
+ }
- injectRowAt: function(row, col, colspan, cType, c) {
- var r = this.getRealRowEl(false, {'row': row, 'col': col}),
- new_cells = this.createCells(cType, colspan);
+ if (r === null && force) {
+ r = api.getParentElement(this.map[idx.row][idx.col].el, { query: "tr" }) || null;
+ }
- if (r) {
- var n_cidx = this.correctColIndexForUnreals(col, row);
- if (n_cidx >= 0) {
- insertAfter(this.getRowCells(r)[n_cidx], new_cells);
- } else {
- r.insertBefore(new_cells, r.firstChild);
- }
- } else {
- var rr = this.table.ownerDocument.createElement('tr');
- rr.appendChild(new_cells);
- insertAfter(api.getParentElement(c.el, { query: "tr" }), rr);
- }
- },
+ return r;
+ },
+
+ injectRowAt: function(row, col, colspan, cType, c) {
+ var r = this.getRealRowEl(false, {'row': row, 'col': col}),
+ new_cells = this.createCells(cType, colspan);
+
+ if (r) {
+ var n_cidx = this.correctColIndexForUnreals(col, row);
+ if (n_cidx >= 0) {
+ insertAfter(this.getRowCells(r)[n_cidx], new_cells);
+ } else {
+ r.insertBefore(new_cells, r.firstChild);
+ }
+ } else {
+ var rr = this.table.ownerDocument.createElement('tr');
+ rr.appendChild(new_cells);
+ insertAfter(api.getParentElement(c.el, { query: "tr" }), rr);
+ }
+ },
+
+ canMerge: function(to) {
+ this.to = to;
+ this.setTableMap();
+ this.idx_start = this.getMapIndex(this.cell);
+ this.idx_end = this.getMapIndex(this.to);
+
+ // switch indexes if start is bigger than end
+ if (this.idx_start.row > this.idx_end.row || (this.idx_start.row == this.idx_end.row && this.idx_start.col > this.idx_end.col)) {
+ var temp_idx = this.idx_start;
+ this.idx_start = this.idx_end;
+ this.idx_end = temp_idx;
+ }
+ if (this.idx_start.col > this.idx_end.col) {
+ var temp_cidx = this.idx_start.col;
+ this.idx_start.col = this.idx_end.col;
+ this.idx_end.col = temp_cidx;
+ }
- canMerge: function(to) {
- this.to = to;
- this.setTableMap();
- this.idx_start = this.getMapIndex(this.cell);
- this.idx_end = this.getMapIndex(this.to);
+ for (var row = this.idx_start.row, maxr = this.idx_end.row; row <= maxr; row++) {
+ for (var col = this.idx_start.col, maxc = this.idx_end.col; col <= maxc; col++) {
+ if (this.map[row][col].isColspan || this.map[row][col].isRowspan) {
+ return false;
+ }
+ }
+ }
+ return true;
+ },
- // switch indexes if start is bigger than end
- if (this.idx_start.row > this.idx_end.row || (this.idx_start.row == this.idx_end.row && this.idx_start.col > this.idx_end.col)) {
- var temp_idx = this.idx_start;
- this.idx_start = this.idx_end;
- this.idx_end = temp_idx;
+ decreaseCellSpan: function(cell, span) {
+ var nr = parseInt(api.getAttribute(cell.el, span), 10) - 1;
+ if (nr >= 1) {
+ cell.el.setAttribute(span, nr);
+ } else {
+ cell.el.removeAttribute(span);
+ if (span == 'colspan') {
+ cell.isColspan = false;
+ }
+ if (span == 'rowspan') {
+ cell.isRowspan = false;
+ }
+ cell.firstCol = true;
+ cell.lastCol = true;
+ cell.firstRow = true;
+ cell.lastRow = true;
+ cell.isReal = true;
+ }
+ },
+
+ removeSurplusLines: function() {
+ var row, cell, ridx, rmax, cidx, cmax, allRowspan;
+
+ this.setTableMap();
+ if (this.map) {
+ ridx = 0;
+ rmax = this.map.length;
+ for (;ridx < rmax; ridx++) {
+ row = this.map[ridx];
+ allRowspan = true;
+ cidx = 0;
+ cmax = row.length;
+ for (; cidx < cmax; cidx++) {
+ cell = row[cidx];
+ if (!(api.getAttribute(cell.el, "rowspan") && parseInt(api.getAttribute(cell.el, "rowspan"), 10) > 1 && cell.firstRow !== true)) {
+ allRowspan = false;
+ break;
}
- if (this.idx_start.col > this.idx_end.col) {
- var temp_cidx = this.idx_start.col;
- this.idx_start.col = this.idx_end.col;
- this.idx_end.col = temp_cidx;
+ }
+ if (allRowspan) {
+ cidx = 0;
+ for (; cidx < cmax; cidx++) {
+ this.decreaseCellSpan(row[cidx], 'rowspan');
}
+ }
+ }
- for (var row = this.idx_start.row, maxr = this.idx_end.row; row <= maxr; row++) {
- for (var col = this.idx_start.col, maxc = this.idx_end.col; col <= maxc; col++) {
- if (this.map[row][col].isColspan || this.map[row][col].isRowspan) {
- return false;
- }
- }
- }
- return true;
- },
+ // remove rows without cells
+ var tableRows = this.getTableRows();
+ ridx = 0;
+ rmax = tableRows.length;
+ for (;ridx < rmax; ridx++) {
+ row = tableRows[ridx];
+ if (row.childNodes.length == 0 && (/^\s*$/.test(row.textContent || row.innerText))) {
+ removeElement(row);
+ }
+ }
+ }
+ },
- decreaseCellSpan: function(cell, span) {
- var nr = parseInt(api.getAttribute(cell.el, span), 10) - 1;
- if (nr >= 1) {
- cell.el.setAttribute(span, nr);
- } else {
- cell.el.removeAttribute(span);
- if (span == 'colspan') {
- cell.isColspan = false;
- }
- if (span == 'rowspan') {
- cell.isRowspan = false;
- }
- cell.firstCol = true;
- cell.lastCol = true;
- cell.firstRow = true;
- cell.lastRow = true;
- cell.isReal = true;
- }
- },
+ fillMissingCells: function() {
+ var r_max = 0,
+ c_max = 0,
+ prevcell = null;
- removeSurplusLines: function() {
- var row, cell, ridx, rmax, cidx, cmax, allRowspan;
-
- this.setTableMap();
- if (this.map) {
- ridx = 0;
- rmax = this.map.length;
- for (;ridx < rmax; ridx++) {
- row = this.map[ridx];
- allRowspan = true;
- cidx = 0;
- cmax = row.length;
- for (; cidx < cmax; cidx++) {
- cell = row[cidx];
- if (!(api.getAttribute(cell.el, "rowspan") && parseInt(api.getAttribute(cell.el, "rowspan"), 10) > 1 && cell.firstRow !== true)) {
- allRowspan = false;
- break;
- }
- }
- if (allRowspan) {
- cidx = 0;
- for (; cidx < cmax; cidx++) {
- this.decreaseCellSpan(row[cidx], 'rowspan');
- }
- }
- }
+ this.setTableMap();
+ if (this.map) {
- // remove rows without cells
- var tableRows = this.getTableRows();
- ridx = 0;
- rmax = tableRows.length;
- for (;ridx < rmax; ridx++) {
- row = tableRows[ridx];
- if (row.childNodes.length == 0 && (/^\s*$/.test(row.textContent || row.innerText))) {
- removeElement(row);
- }
+ // find maximal dimensions of broken table
+ r_max = this.map.length;
+ for (var ridx = 0; ridx < r_max; ridx++) {
+ if (this.map[ridx].length > c_max) { c_max = this.map[ridx].length; }
+ }
+
+ for (var row = 0; row < r_max; row++) {
+ for (var col = 0; col < c_max; col++) {
+ if (this.map[row] && !this.map[row][col]) {
+ if (col > 0) {
+ this.map[row][col] = new MapCell(this.createCells('td', 1));
+ prevcell = this.map[row][col-1];
+ if (prevcell && prevcell.el && prevcell.el.parent) { // if parent does not exist element is removed from dom
+ insertAfter(this.map[row][col-1].el, this.map[row][col].el);
}
+ }
}
- },
+ }
+ }
+ }
+ },
- fillMissingCells: function() {
- var r_max = 0,
- c_max = 0,
- prevcell = null;
+ rectify: function() {
+ if (!this.removeEmptyTable()) {
+ this.removeSurplusLines();
+ this.fillMissingCells();
+ return true;
+ } else {
+ return false;
+ }
+ },
- this.setTableMap();
- if (this.map) {
+ unmerge: function() {
+ if (this.rectify()) {
+ this.setTableMap();
+ this.idx = this.getMapIndex(this.cell);
- // find maximal dimensions of broken table
- r_max = this.map.length;
- for (var ridx = 0; ridx < r_max; ridx++) {
- if (this.map[ridx].length > c_max) { c_max = this.map[ridx].length; }
- }
+ if (this.idx) {
+ var thisCell = this.map[this.idx.row][this.idx.col],
+ colspan = (api.getAttribute(thisCell.el, "colspan")) ? parseInt(api.getAttribute(thisCell.el, "colspan"), 10) : 1,
+ cType = thisCell.el.tagName.toLowerCase();
- for (var row = 0; row < r_max; row++) {
- for (var col = 0; col < c_max; col++) {
- if (this.map[row] && !this.map[row][col]) {
- if (col > 0) {
- this.map[row][col] = new MapCell(this.createCells('td', 1));
- prevcell = this.map[row][col-1];
- if (prevcell && prevcell.el && prevcell.el.parent) { // if parent does not exist element is removed from dom
- insertAfter(this.map[row][col-1].el, this.map[row][col].el);
- }
- }
- }
- }
- }
+ if (thisCell.isRowspan) {
+ var rowspan = parseInt(api.getAttribute(thisCell.el, "rowspan"), 10);
+ if (rowspan > 1) {
+ for (var nr = 1, maxr = rowspan - 1; nr <= maxr; nr++){
+ this.injectRowAt(this.idx.row + nr, this.idx.col, colspan, cType, thisCell);
+ }
}
- },
+ thisCell.el.removeAttribute('rowspan');
+ }
+ this.splitRowToCells(thisCell);
+ }
+ }
+ },
- rectify: function() {
- if (!this.removeEmptyTable()) {
- this.removeSurplusLines();
- this.fillMissingCells();
- return true;
- } else {
- return false;
- }
- },
+ // merges cells from start cell (defined in creating obj) to "to" cell
+ merge: function(to) {
+ if (this.rectify()) {
+ if (this.canMerge(to)) {
+ var rowspan = this.idx_end.row - this.idx_start.row + 1,
+ colspan = this.idx_end.col - this.idx_start.col + 1;
- unmerge: function() {
- if (this.rectify()) {
- this.setTableMap();
- this.idx = this.getMapIndex(this.cell);
-
- if (this.idx) {
- var thisCell = this.map[this.idx.row][this.idx.col],
- colspan = (api.getAttribute(thisCell.el, "colspan")) ? parseInt(api.getAttribute(thisCell.el, "colspan"), 10) : 1,
- cType = thisCell.el.tagName.toLowerCase();
-
- if (thisCell.isRowspan) {
- var rowspan = parseInt(api.getAttribute(thisCell.el, "rowspan"), 10);
- if (rowspan > 1) {
- for (var nr = 1, maxr = rowspan - 1; nr <= maxr; nr++){
- this.injectRowAt(this.idx.row + nr, this.idx.col, colspan, cType, thisCell);
- }
- }
- thisCell.el.removeAttribute('rowspan');
- }
- this.splitRowToCells(thisCell);
+ for (var row = this.idx_start.row, maxr = this.idx_end.row; row <= maxr; row++) {
+ for (var col = this.idx_start.col, maxc = this.idx_end.col; col <= maxc; col++) {
+
+ if (row == this.idx_start.row && col == this.idx_start.col) {
+ if (rowspan > 1) {
+ this.map[row][col].el.setAttribute('rowspan', rowspan);
+ }
+ if (colspan > 1) {
+ this.map[row][col].el.setAttribute('colspan', colspan);
}
+ } else {
+ // transfer content
+ if (!(/^\s*
\s*$/.test(this.map[row][col].el.innerHTML.toLowerCase()))) {
+ this.map[this.idx_start.row][this.idx_start.col].el.innerHTML += ' ' + this.map[row][col].el.innerHTML;
+ }
+ removeElement(this.map[row][col].el);
+ }
+
}
- },
+ }
+ this.rectify();
+ } else {
+ if (window.console) {
+ console.log('Do not know how to merge allready merged cells.');
+ }
+ }
+ }
+ },
- // merges cells from start cell (defined in creating obj) to "to" cell
- merge: function(to) {
- if (this.rectify()) {
- if (this.canMerge(to)) {
- var rowspan = this.idx_end.row - this.idx_start.row + 1,
- colspan = this.idx_end.col - this.idx_start.col + 1;
+ // Decreases rowspan of a cell if it is done on first cell of rowspan row (real cell)
+ // Cell is moved to next row (if it is real)
+ collapseCellToNextRow: function(cell) {
+ var cellIdx = this.getMapIndex(cell.el),
+ newRowIdx = cellIdx.row + 1,
+ newIdx = {'row': newRowIdx, 'col': cellIdx.col};
- for (var row = this.idx_start.row, maxr = this.idx_end.row; row <= maxr; row++) {
- for (var col = this.idx_start.col, maxc = this.idx_end.col; col <= maxc; col++) {
+ if (newRowIdx < this.map.length) {
- if (row == this.idx_start.row && col == this.idx_start.col) {
- if (rowspan > 1) {
- this.map[row][col].el.setAttribute('rowspan', rowspan);
- }
- if (colspan > 1) {
- this.map[row][col].el.setAttribute('colspan', colspan);
- }
- } else {
- // transfer content
- if (!(/^\s*
\s*$/.test(this.map[row][col].el.innerHTML.toLowerCase()))) {
- this.map[this.idx_start.row][this.idx_start.col].el.innerHTML += ' ' + this.map[row][col].el.innerHTML;
- }
- removeElement(this.map[row][col].el);
- }
- }
- }
- this.rectify();
- } else {
- if (window.console) {
- console.log('Do not know how to merge allready merged cells.');
- }
- }
- }
- },
-
- // Decreases rowspan of a cell if it is done on first cell of rowspan row (real cell)
- // Cell is moved to next row (if it is real)
- collapseCellToNextRow: function(cell) {
- var cellIdx = this.getMapIndex(cell.el),
- newRowIdx = cellIdx.row + 1,
- newIdx = {'row': newRowIdx, 'col': cellIdx.col};
-
- if (newRowIdx < this.map.length) {
-
- var row = this.getRealRowEl(false, newIdx);
- if (row !== null) {
- var n_cidx = this.correctColIndexForUnreals(newIdx.col, newIdx.row);
- if (n_cidx >= 0) {
- insertAfter(this.getRowCells(row)[n_cidx], cell.el);
- } else {
- var lastCell = this.getLastNewCellOnRow(row, newRowIdx);
- if (lastCell !== null) {
- insertAfter(lastCell, cell.el);
- } else {
- row.insertBefore(cell.el, row.firstChild);
- }
- }
- if (parseInt(api.getAttribute(cell.el, 'rowspan'), 10) > 2) {
- cell.el.setAttribute('rowspan', parseInt(api.getAttribute(cell.el, 'rowspan'), 10) - 1);
- } else {
- cell.el.removeAttribute('rowspan');
- }
- }
- }
- },
-
- // Removes a cell when removing a row
- // If is rowspan cell then decreases the rowspan
- // and moves cell to next row if needed (is first cell of rowspan)
- removeRowCell: function(cell) {
- if (cell.isReal) {
- if (cell.isRowspan) {
- this.collapseCellToNextRow(cell);
- } else {
- removeElement(cell.el);
- }
+ var row = this.getRealRowEl(false, newIdx);
+ if (row !== null) {
+ var n_cidx = this.correctColIndexForUnreals(newIdx.col, newIdx.row);
+ if (n_cidx >= 0) {
+ insertAfter(this.getRowCells(row)[n_cidx], cell.el);
+ } else {
+ var lastCell = this.getLastNewCellOnRow(row, newRowIdx);
+ if (lastCell !== null) {
+ insertAfter(lastCell, cell.el);
} else {
- if (parseInt(api.getAttribute(cell.el, 'rowspan'), 10) > 2) {
- cell.el.setAttribute('rowspan', parseInt(api.getAttribute(cell.el, 'rowspan'), 10) - 1);
- } else {
- cell.el.removeAttribute('rowspan');
- }
+ row.insertBefore(cell.el, row.firstChild);
}
- },
+ }
+ if (parseInt(api.getAttribute(cell.el, 'rowspan'), 10) > 2) {
+ cell.el.setAttribute('rowspan', parseInt(api.getAttribute(cell.el, 'rowspan'), 10) - 1);
+ } else {
+ cell.el.removeAttribute('rowspan');
+ }
+ }
+ }
+ },
- getRowElementsByCell: function() {
- var cells = [];
- this.setTableMap();
- this.idx = this.getMapIndex(this.cell);
- if (this.idx !== false) {
- var modRow = this.map[this.idx.row];
- for (var cidx = 0, cmax = modRow.length; cidx < cmax; cidx++) {
- if (modRow[cidx].isReal) {
- cells.push(modRow[cidx].el);
- }
- }
- }
- return cells;
- },
+ // Removes a cell when removing a row
+ // If is rowspan cell then decreases the rowspan
+ // and moves cell to next row if needed (is first cell of rowspan)
+ removeRowCell: function(cell) {
+ if (cell.isReal) {
+ if (cell.isRowspan) {
+ this.collapseCellToNextRow(cell);
+ } else {
+ removeElement(cell.el);
+ }
+ } else {
+ if (parseInt(api.getAttribute(cell.el, 'rowspan'), 10) > 2) {
+ cell.el.setAttribute('rowspan', parseInt(api.getAttribute(cell.el, 'rowspan'), 10) - 1);
+ } else {
+ cell.el.removeAttribute('rowspan');
+ }
+ }
+ },
- getColumnElementsByCell: function() {
- var cells = [];
- this.setTableMap();
- this.idx = this.getMapIndex(this.cell);
- if (this.idx !== false) {
- for (var ridx = 0, rmax = this.map.length; ridx < rmax; ridx++) {
- if (this.map[ridx][this.idx.col] && this.map[ridx][this.idx.col].isReal) {
- cells.push(this.map[ridx][this.idx.col].el);
- }
- }
- }
- return cells;
- },
+ getRowElementsByCell: function() {
+ var cells = [];
+ this.setTableMap();
+ this.idx = this.getMapIndex(this.cell);
+ if (this.idx !== false) {
+ var modRow = this.map[this.idx.row];
+ for (var cidx = 0, cmax = modRow.length; cidx < cmax; cidx++) {
+ if (modRow[cidx].isReal) {
+ cells.push(modRow[cidx].el);
+ }
+ }
+ }
+ return cells;
+ },
- // Removes the row of selected cell
- removeRow: function() {
- var oldRow = api.getParentElement(this.cell, { query: "tr" });
- if (oldRow) {
- this.setTableMap();
- this.idx = this.getMapIndex(this.cell);
- if (this.idx !== false) {
- var modRow = this.map[this.idx.row];
- for (var cidx = 0, cmax = modRow.length; cidx < cmax; cidx++) {
- if (!modRow[cidx].modified) {
- this.setCellAsModified(modRow[cidx]);
- this.removeRowCell(modRow[cidx]);
- }
- }
- }
- removeElement(oldRow);
- }
- },
+ getColumnElementsByCell: function() {
+ var cells = [];
+ this.setTableMap();
+ this.idx = this.getMapIndex(this.cell);
+ if (this.idx !== false) {
+ for (var ridx = 0, rmax = this.map.length; ridx < rmax; ridx++) {
+ if (this.map[ridx][this.idx.col] && this.map[ridx][this.idx.col].isReal) {
+ cells.push(this.map[ridx][this.idx.col].el);
+ }
+ }
+ }
+ return cells;
+ },
- removeColCell: function(cell) {
- if (cell.isColspan) {
- if (parseInt(api.getAttribute(cell.el, 'colspan'), 10) > 2) {
- cell.el.setAttribute('colspan', parseInt(api.getAttribute(cell.el, 'colspan'), 10) - 1);
- } else {
- cell.el.removeAttribute('colspan');
- }
- } else if (cell.isReal) {
- removeElement(cell.el);
+ // Removes the row of selected cell
+ removeRow: function() {
+ var oldRow = api.getParentElement(this.cell, { query: "tr" });
+ if (oldRow) {
+ this.setTableMap();
+ this.idx = this.getMapIndex(this.cell);
+ if (this.idx !== false) {
+ var modRow = this.map[this.idx.row];
+ for (var cidx = 0, cmax = modRow.length; cidx < cmax; cidx++) {
+ if (!modRow[cidx].modified) {
+ this.setCellAsModified(modRow[cidx]);
+ this.removeRowCell(modRow[cidx]);
}
- },
+ }
+ }
+ removeElement(oldRow);
+ }
+ },
- removeColumn: function() {
- this.setTableMap();
- this.idx = this.getMapIndex(this.cell);
- if (this.idx !== false) {
- for (var ridx = 0, rmax = this.map.length; ridx < rmax; ridx++) {
- if (!this.map[ridx][this.idx.col].modified) {
- this.setCellAsModified(this.map[ridx][this.idx.col]);
- this.removeColCell(this.map[ridx][this.idx.col]);
- }
- }
- }
- },
+ removeColCell: function(cell) {
+ if (cell.isColspan) {
+ if (parseInt(api.getAttribute(cell.el, 'colspan'), 10) > 2) {
+ cell.el.setAttribute('colspan', parseInt(api.getAttribute(cell.el, 'colspan'), 10) - 1);
+ } else {
+ cell.el.removeAttribute('colspan');
+ }
+ } else if (cell.isReal) {
+ removeElement(cell.el);
+ }
+ },
- // removes row or column by selected cell element
- remove: function(what) {
- if (this.rectify()) {
- switch (what) {
- case 'row':
- this.removeRow();
- break;
- case 'column':
- this.removeColumn();
- break;
- }
- this.rectify();
- }
- },
+ removeColumn: function() {
+ this.setTableMap();
+ this.idx = this.getMapIndex(this.cell);
+ if (this.idx !== false) {
+ for (var ridx = 0, rmax = this.map.length; ridx < rmax; ridx++) {
+ if (!this.map[ridx][this.idx.col].modified) {
+ this.setCellAsModified(this.map[ridx][this.idx.col]);
+ this.removeColCell(this.map[ridx][this.idx.col]);
+ }
+ }
+ }
+ },
- addRow: function(where) {
- var doc = this.table.ownerDocument;
+ // removes row or column by selected cell element
+ remove: function(what) {
+ if (this.rectify()) {
+ switch (what) {
+ case 'row':
+ this.removeRow();
+ break;
+ case 'column':
+ this.removeColumn();
+ break;
+ }
+ this.rectify();
+ }
+ },
- this.setTableMap();
- this.idx = this.getMapIndex(this.cell);
- if (where == "below" && api.getAttribute(this.cell, 'rowspan')) {
- this.idx.row = this.idx.row + parseInt(api.getAttribute(this.cell, 'rowspan'), 10) - 1;
- }
+ addRow: function(where) {
+ var doc = this.table.ownerDocument;
- if (this.idx !== false) {
- var modRow = this.map[this.idx.row],
- newRow = doc.createElement('tr');
+ this.setTableMap();
+ this.idx = this.getMapIndex(this.cell);
+ if (where == "below" && api.getAttribute(this.cell, 'rowspan')) {
+ this.idx.row = this.idx.row + parseInt(api.getAttribute(this.cell, 'rowspan'), 10) - 1;
+ }
- for (var ridx = 0, rmax = modRow.length; ridx < rmax; ridx++) {
- if (!modRow[ridx].modified) {
- this.setCellAsModified(modRow[ridx]);
- this.addRowCell(modRow[ridx], newRow, where);
- }
- }
+ if (this.idx !== false) {
+ var modRow = this.map[this.idx.row],
+ newRow = doc.createElement('tr');
- switch (where) {
- case 'below':
- insertAfter(this.getRealRowEl(true), newRow);
- break;
- case 'above':
- var cr = api.getParentElement(this.map[this.idx.row][this.idx.col].el, { query: "tr" });
- if (cr) {
- cr.parentNode.insertBefore(newRow, cr);
- }
- break;
- }
- }
- },
+ for (var ridx = 0, rmax = modRow.length; ridx < rmax; ridx++) {
+ if (!modRow[ridx].modified) {
+ this.setCellAsModified(modRow[ridx]);
+ this.addRowCell(modRow[ridx], newRow, where);
+ }
+ }
- addRowCell: function(cell, row, where) {
- var colSpanAttr = (cell.isColspan) ? {"colspan" : api.getAttribute(cell.el, 'colspan')} : null;
- if (cell.isReal) {
- if (where != 'above' && cell.isRowspan) {
- cell.el.setAttribute('rowspan', parseInt(api.getAttribute(cell.el,'rowspan'), 10) + 1);
- } else {
- row.appendChild(this.createCells('td', 1, colSpanAttr));
- }
- } else {
- if (where != 'above' && cell.isRowspan && cell.lastRow) {
- row.appendChild(this.createCells('td', 1, colSpanAttr));
- } else if (c.isRowspan) {
- cell.el.attr('rowspan', parseInt(api.getAttribute(cell.el, 'rowspan'), 10) + 1);
- }
+ switch (where) {
+ case 'below':
+ insertAfter(this.getRealRowEl(true), newRow);
+ break;
+ case 'above':
+ var cr = api.getParentElement(this.map[this.idx.row][this.idx.col].el, { query: "tr" });
+ if (cr) {
+ cr.parentNode.insertBefore(newRow, cr);
}
- },
+ break;
+ }
+ }
+ },
- add: function(where) {
- if (this.rectify()) {
- if (where == 'below' || where == 'above') {
- this.addRow(where);
- }
- if (where == 'before' || where == 'after') {
- this.addColumn(where);
- }
- }
- },
+ addRowCell: function(cell, row, where) {
+ var colSpanAttr = (cell.isColspan) ? {"colspan" : api.getAttribute(cell.el, 'colspan')} : null;
+ if (cell.isReal) {
+ if (where != 'above' && cell.isRowspan) {
+ cell.el.setAttribute('rowspan', parseInt(api.getAttribute(cell.el,'rowspan'), 10) + 1);
+ } else {
+ row.appendChild(this.createCells('td', 1, colSpanAttr));
+ }
+ } else {
+ if (where != 'above' && cell.isRowspan && cell.lastRow) {
+ row.appendChild(this.createCells('td', 1, colSpanAttr));
+ } else if (c.isRowspan) {
+ cell.el.attr('rowspan', parseInt(api.getAttribute(cell.el, 'rowspan'), 10) + 1);
+ }
+ }
+ },
- addColCell: function (cell, ridx, where) {
- var doAdd,
- cType = cell.el.tagName.toLowerCase();
+ add: function(where) {
+ if (this.rectify()) {
+ if (where == 'below' || where == 'above') {
+ this.addRow(where);
+ }
+ if (where == 'before' || where == 'after') {
+ this.addColumn(where);
+ }
+ }
+ },
- // defines add cell vs expand cell conditions
- // true means add
- switch (where) {
- case "before":
- doAdd = (!cell.isColspan || cell.firstCol);
- break;
- case "after":
- doAdd = (!cell.isColspan || cell.lastCol || (cell.isColspan && c.el == this.cell));
- break;
- }
+ addColCell: function (cell, ridx, where) {
+ var doAdd,
+ cType = cell.el.tagName.toLowerCase();
- if (doAdd){
- // adds a cell before or after current cell element
- switch (where) {
- case "before":
- cell.el.parentNode.insertBefore(this.createCells(cType, 1), cell.el);
- break;
- case "after":
- insertAfter(cell.el, this.createCells(cType, 1));
- break;
- }
+ // defines add cell vs expand cell conditions
+ // true means add
+ switch (where) {
+ case "before":
+ doAdd = (!cell.isColspan || cell.firstCol);
+ break;
+ case "after":
+ doAdd = (!cell.isColspan || cell.lastCol || (cell.isColspan && c.el == this.cell));
+ break;
+ }
- // handles if cell has rowspan
- if (cell.isRowspan) {
- this.handleCellAddWithRowspan(cell, ridx+1, where);
- }
+ if (doAdd){
+ // adds a cell before or after current cell element
+ switch (where) {
+ case "before":
+ cell.el.parentNode.insertBefore(this.createCells(cType, 1), cell.el);
+ break;
+ case "after":
+ insertAfter(cell.el, this.createCells(cType, 1));
+ break;
+ }
- } else {
- // expands cell
- cell.el.setAttribute('colspan', parseInt(api.getAttribute(cell.el, 'colspan'), 10) + 1);
- }
- },
+ // handles if cell has rowspan
+ if (cell.isRowspan) {
+ this.handleCellAddWithRowspan(cell, ridx+1, where);
+ }
- addColumn: function(where) {
- var row, modCell;
+ } else {
+ // expands cell
+ cell.el.setAttribute('colspan', parseInt(api.getAttribute(cell.el, 'colspan'), 10) + 1);
+ }
+ },
- this.setTableMap();
- this.idx = this.getMapIndex(this.cell);
- if (where == "after" && api.getAttribute(this.cell, 'colspan')) {
- this.idx.col = this.idx.col + parseInt(api.getAttribute(this.cell, 'colspan'), 10) - 1;
- }
+ addColumn: function(where) {
+ var row, modCell;
- if (this.idx !== false) {
- for (var ridx = 0, rmax = this.map.length; ridx < rmax; ridx++ ) {
- row = this.map[ridx];
- if (row[this.idx.col]) {
- modCell = row[this.idx.col];
- if (!modCell.modified) {
- this.setCellAsModified(modCell);
- this.addColCell(modCell, ridx , where);
- }
- }
- }
+ this.setTableMap();
+ this.idx = this.getMapIndex(this.cell);
+ if (where == "after" && api.getAttribute(this.cell, 'colspan')) {
+ this.idx.col = this.idx.col + parseInt(api.getAttribute(this.cell, 'colspan'), 10) - 1;
+ }
+
+ if (this.idx !== false) {
+ for (var ridx = 0, rmax = this.map.length; ridx < rmax; ridx++ ) {
+ row = this.map[ridx];
+ if (row[this.idx.col]) {
+ modCell = row[this.idx.col];
+ if (!modCell.modified) {
+ this.setCellAsModified(modCell);
+ this.addColCell(modCell, ridx , where);
}
- },
+ }
+ }
+ }
+ },
- handleCellAddWithRowspan: function (cell, ridx, where) {
- var addRowsNr = parseInt(api.getAttribute(this.cell, 'rowspan'), 10) - 1,
- crow = api.getParentElement(cell.el, { query: "tr" }),
- cType = cell.el.tagName.toLowerCase(),
- cidx, temp_r_cells,
- doc = this.table.ownerDocument,
- nrow;
-
- for (var i = 0; i < addRowsNr; i++) {
- cidx = this.correctColIndexForUnreals(this.idx.col, (ridx + i));
- crow = nextNode(crow, 'tr');
- if (crow) {
- if (cidx > 0) {
- switch (where) {
- case "before":
- temp_r_cells = this.getRowCells(crow);
- if (cidx > 0 && this.map[ridx + i][this.idx.col].el != temp_r_cells[cidx] && cidx == temp_r_cells.length - 1) {
- insertAfter(temp_r_cells[cidx], this.createCells(cType, 1));
- } else {
- temp_r_cells[cidx].parentNode.insertBefore(this.createCells(cType, 1), temp_r_cells[cidx]);
- }
+ handleCellAddWithRowspan: function (cell, ridx, where) {
+ var addRowsNr = parseInt(api.getAttribute(this.cell, 'rowspan'), 10) - 1,
+ crow = api.getParentElement(cell.el, { query: "tr" }),
+ cType = cell.el.tagName.toLowerCase(),
+ cidx, temp_r_cells,
+ doc = this.table.ownerDocument,
+ nrow;
- break;
- case "after":
- insertAfter(this.getRowCells(crow)[cidx], this.createCells(cType, 1));
- break;
- }
- } else {
- crow.insertBefore(this.createCells(cType, 1), crow.firstChild);
- }
+ for (var i = 0; i < addRowsNr; i++) {
+ cidx = this.correctColIndexForUnreals(this.idx.col, (ridx + i));
+ crow = nextNode(crow, 'tr');
+ if (crow) {
+ if (cidx > 0) {
+ switch (where) {
+ case "before":
+ temp_r_cells = this.getRowCells(crow);
+ if (cidx > 0 && this.map[ridx + i][this.idx.col].el != temp_r_cells[cidx] && cidx == temp_r_cells.length - 1) {
+ insertAfter(temp_r_cells[cidx], this.createCells(cType, 1));
} else {
- nrow = doc.createElement('tr');
- nrow.appendChild(this.createCells(cType, 1));
- this.table.appendChild(nrow);
+ temp_r_cells[cidx].parentNode.insertBefore(this.createCells(cType, 1), temp_r_cells[cidx]);
}
+
+ break;
+ case "after":
+ insertAfter(this.getRowCells(crow)[cidx], this.createCells(cType, 1));
+ break;
}
+ } else {
+ crow.insertBefore(this.createCells(cType, 1), crow.firstChild);
+ }
+ } else {
+ nrow = doc.createElement('tr');
+ nrow.appendChild(this.createCells(cType, 1));
+ this.table.appendChild(nrow);
}
- };
-
- api.table = {
- getCellsBetween: function(cell1, cell2) {
- var c1 = new TableModifyerByCell(cell1);
- return c1.getMapElsTo(cell2);
- },
-
- addCells: function(cell, where) {
- var c = new TableModifyerByCell(cell);
- c.add(where);
- },
+ }
+ }
+ };
- removeCells: function(cell, what) {
- var c = new TableModifyerByCell(cell);
- c.remove(what);
- },
+ api.table = {
+ getCellsBetween: function(cell1, cell2) {
+ var c1 = new TableModifyerByCell(cell1);
+ return c1.getMapElsTo(cell2);
+ },
- mergeCellsBetween: function(cell1, cell2) {
- var c1 = new TableModifyerByCell(cell1);
- c1.merge(cell2);
- },
+ addCells: function(cell, where) {
+ var c = new TableModifyerByCell(cell);
+ c.add(where);
+ },
- unmergeCell: function(cell) {
- var c = new TableModifyerByCell(cell);
- c.unmerge();
- },
+ removeCells: function(cell, what) {
+ var c = new TableModifyerByCell(cell);
+ c.remove(what);
+ },
- orderSelectionEnds: function(cell, cell2) {
- var c = new TableModifyerByCell(cell);
- return c.orderSelectionEnds(cell2);
- },
+ mergeCellsBetween: function(cell1, cell2) {
+ var c1 = new TableModifyerByCell(cell1);
+ c1.merge(cell2);
+ },
- indexOf: function(cell) {
- var c = new TableModifyerByCell(cell);
- c.setTableMap();
- return c.getMapIndex(cell);
- },
+ unmergeCell: function(cell) {
+ var c = new TableModifyerByCell(cell);
+ c.unmerge();
+ },
- findCell: function(table, idx) {
- var c = new TableModifyerByCell(null, table);
- return c.getElementAtIndex(idx);
- },
+ orderSelectionEnds: function(cell, cell2) {
+ var c = new TableModifyerByCell(cell);
+ return c.orderSelectionEnds(cell2);
+ },
- findRowByCell: function(cell) {
- var c = new TableModifyerByCell(cell);
- return c.getRowElementsByCell();
- },
+ indexOf: function(cell) {
+ var c = new TableModifyerByCell(cell);
+ c.setTableMap();
+ return c.getMapIndex(cell);
+ },
- findColumnByCell: function(cell) {
- var c = new TableModifyerByCell(cell);
- return c.getColumnElementsByCell();
- },
+ findCell: function(table, idx) {
+ var c = new TableModifyerByCell(null, table);
+ return c.getElementAtIndex(idx);
+ },
- canMerge: function(cell1, cell2) {
- var c = new TableModifyerByCell(cell1);
- return c.canMerge(cell2);
- }
- };
+ findRowByCell: function(cell) {
+ var c = new TableModifyerByCell(cell);
+ return c.getRowElementsByCell();
+ },
+ findColumnByCell: function(cell) {
+ var c = new TableModifyerByCell(cell);
+ return c.getColumnElementsByCell();
+ },
+ canMerge: function(cell1, cell2) {
+ var c = new TableModifyerByCell(cell1);
+ return c.canMerge(cell2);
+ }
+ };
})(wysihtml5);
;// does a selector query on element or array of elements
-
wysihtml5.dom.query = function(elements, query) {
var ret = [],
q;
@@ -8795,7 +8788,8 @@ wysihtml5.dom.unwrap = function(node) {
node.parentNode.removeChild(node);
}
return children;
-};;/*
+};
+;/*
* Methods for fetching pasted html before it gets inserted into content
**/
@@ -8819,28 +8813,40 @@ wysihtml5.dom.getPastedHtml = function(event) {
wysihtml5.dom.getPastedHtmlWithDiv = function (composer, f) {
var selBookmark = composer.selection.getBookmark(),
doc = composer.element.ownerDocument,
- cleanerDiv = doc.createElement('DIV');
+ cleanerDiv = doc.createElement('DIV'),
+ scrollPos = composer.getScrollPos();
doc.body.appendChild(cleanerDiv);
cleanerDiv.style.width = "1px";
cleanerDiv.style.height = "1px";
cleanerDiv.style.overflow = "hidden";
+ cleanerDiv.style.position = "absolute";
+ cleanerDiv.style.top = scrollPos.y + "px";
+ cleanerDiv.style.left = scrollPos.x + "px";
cleanerDiv.setAttribute('contenteditable', 'true');
cleanerDiv.focus();
setTimeout(function () {
+ var html;
+
composer.selection.setBookmark(selBookmark);
- f(cleanerDiv.innerHTML);
+ html = cleanerDiv.innerHTML;
+ if (html && (/^
$/i).test(html.trim())) {
+ html = false;
+ }
+ f(html);
cleanerDiv.parentNode.removeChild(cleanerDiv);
}, 0);
-};;wysihtml5.dom.removeInvisibleSpaces = function(node) {
+};
+;wysihtml5.dom.removeInvisibleSpaces = function(node) {
var textNodes = wysihtml5.dom.getTextNodes(node);
for (var n = textNodes.length; n--;) {
textNodes[n].nodeValue = textNodes[n].nodeValue.replace(wysihtml5.INVISIBLE_SPACE_REG_EXP, "");
}
-};;/**
+};
+;/**
* Fix most common html formatting misbehaviors of browsers implementation when inserting
* content via copy & paste contentEditable
*
@@ -8916,7 +8922,8 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
return newHtml;
};
-})();;/**
+})();
+;/**
* IE and Opera leave an empty paragraph in the contentEditable element after clearing it
*
* @param {Object} contentEditableElement The contentEditable element to observe for clearing events
@@ -8994,119 +9001,119 @@ wysihtml5.quirks.ensureProperClearing = (function() {
})(wysihtml5);
;wysihtml5.quirks.tableCellsSelection = function(editable, editor) {
- var dom = wysihtml5.dom,
- select = {
- table: null,
- start: null,
- end: null,
- cells: null,
- select: selectCells
- },
- selection_class = "wysiwyg-tmp-selected-cell";
+ var dom = wysihtml5.dom,
+ select = {
+ table: null,
+ start: null,
+ end: null,
+ cells: null,
+ select: selectCells
+ },
+ selection_class = "wysiwyg-tmp-selected-cell";
+
+ function init () {
+ editable.addEventListener("mousedown", handleMouseDown);
+ return select;
+ }
- function init () {
- editable.addEventListener("mousedown", handleMouseDown);
- return select;
+ var handleMouseDown = function(event) {
+ var target = wysihtml5.dom.getParentElement(event.target, { query: "td, th" });
+ if (target) {
+ handleSelectionMousedown(target);
}
+ };
- var handleMouseDown = function(event) {
- var target = wysihtml5.dom.getParentElement(event.target, { query: "td, th" });
- if (target) {
- handleSelectionMousedown(target);
- }
- };
-
- function handleSelectionMousedown (target) {
- select.start = target;
- select.end = target;
- select.cells = [target];
- select.table = dom.getParentElement(select.start, { query: "table" });
+ function handleSelectionMousedown (target) {
+ select.start = target;
+ select.end = target;
+ select.cells = [target];
+ select.table = dom.getParentElement(select.start, { query: "table" });
- if (select.table) {
- removeCellSelections();
- dom.addClass(target, selection_class);
- editable.addEventListener("mousemove", handleMouseMove);
- editable.addEventListener("mouseup", handleMouseUp);
- editor.fire("tableselectstart").fire("tableselectstart:composer");
- }
+ if (select.table) {
+ removeCellSelections();
+ dom.addClass(target, selection_class);
+ editable.addEventListener("mousemove", handleMouseMove);
+ editable.addEventListener("mouseup", handleMouseUp);
+ editor.fire("tableselectstart").fire("tableselectstart:composer");
}
+ }
- // remove all selection classes
- function removeCellSelections () {
- if (editable) {
- var selectedCells = editable.querySelectorAll('.' + selection_class);
- if (selectedCells.length > 0) {
- for (var i = 0; i < selectedCells.length; i++) {
- dom.removeClass(selectedCells[i], selection_class);
- }
- }
+ // remove all selection classes
+ function removeCellSelections () {
+ if (editable) {
+ var selectedCells = editable.querySelectorAll('.' + selection_class);
+ if (selectedCells.length > 0) {
+ for (var i = 0; i < selectedCells.length; i++) {
+ dom.removeClass(selectedCells[i], selection_class);
}
+ }
}
+ }
- function addSelections (cells) {
- for (var i = 0; i < cells.length; i++) {
- dom.addClass(cells[i], selection_class);
- }
+ function addSelections (cells) {
+ for (var i = 0; i < cells.length; i++) {
+ dom.addClass(cells[i], selection_class);
}
+ }
- function handleMouseMove (event) {
- var curTable = null,
- cell = dom.getParentElement(event.target, { query: "td, th" }),
- oldEnd;
+ function handleMouseMove (event) {
+ var curTable = null,
+ cell = dom.getParentElement(event.target, { query: "td, th" }),
+ oldEnd;
- if (cell && select.table && select.start) {
- curTable = dom.getParentElement(cell, { query: "table" });
- if (curTable && curTable === select.table) {
- removeCellSelections();
- oldEnd = select.end;
- select.end = cell;
- select.cells = dom.table.getCellsBetween(select.start, cell);
- if (select.cells.length > 1) {
- editor.composer.selection.deselect();
- }
- addSelections(select.cells);
- if (select.end !== oldEnd) {
- editor.fire("tableselectchange").fire("tableselectchange:composer");
- }
+ if (cell && select.table && select.start) {
+ curTable = dom.getParentElement(cell, { query: "table" });
+ if (curTable && curTable === select.table) {
+ removeCellSelections();
+ oldEnd = select.end;
+ select.end = cell;
+ select.cells = dom.table.getCellsBetween(select.start, cell);
+ if (select.cells.length > 1) {
+ editor.composer.selection.deselect();
+ }
+ addSelections(select.cells);
+ if (select.end !== oldEnd) {
+ editor.fire("tableselectchange").fire("tableselectchange:composer");
}
}
}
+ }
- function handleMouseUp (event) {
- editable.removeEventListener("mousemove", handleMouseMove);
- editable.removeEventListener("mouseup", handleMouseUp);
- editor.fire("tableselect").fire("tableselect:composer");
- setTimeout(function() {
- bindSideclick();
- },0);
- }
-
- var sideClickHandler = function(event) {
- editable.ownerDocument.removeEventListener("click", sideClickHandler);
- if (dom.getParentElement(event.target, { query: "table" }) != select.table) {
- removeCellSelections();
- select.table = null;
- select.start = null;
- select.end = null;
- editor.fire("tableunselect").fire("tableunselect:composer");
- }
- };
+ function handleMouseUp (event) {
+ editable.removeEventListener("mousemove", handleMouseMove);
+ editable.removeEventListener("mouseup", handleMouseUp);
+ editor.fire("tableselect").fire("tableselect:composer");
+ setTimeout(function() {
+ bindSideclick();
+ },0);
+ }
- function bindSideclick () {
- editable.ownerDocument.addEventListener("click", sideClickHandler);
+ var sideClickHandler = function(event) {
+ editable.ownerDocument.removeEventListener("click", sideClickHandler);
+ if (dom.getParentElement(event.target, { query: "table" }) != select.table) {
+ removeCellSelections();
+ select.table = null;
+ select.start = null;
+ select.end = null;
+ editor.fire("tableunselect").fire("tableunselect:composer");
}
+ };
- function selectCells (start, end) {
- select.start = start;
- select.end = end;
- select.table = dom.getParentElement(select.start, { query: "table" });
- selectedCells = dom.table.getCellsBetween(select.start, select.end);
- addSelections(selectedCells);
- bindSideclick();
- editor.fire("tableselect").fire("tableselect:composer");
- }
+ function bindSideclick () {
+ editable.ownerDocument.addEventListener("click", sideClickHandler);
+ }
- return init();
+ function selectCells (start, end) {
+ select.start = start;
+ select.end = end;
+ select.table = dom.getParentElement(select.start, { query: "table" });
+ selectedCells = dom.table.getCellsBetween(select.start, select.end);
+ addSelections(selectedCells);
+ bindSideclick();
+ editor.fire("tableselect").fire("tableselect:composer");
+ }
+
+ return init();
};
;(function(wysihtml5) {
@@ -9257,6 +9264,7 @@ wysihtml5.quirks.ensureProperClearing = (function() {
this.editor = editor;
this.composer = editor.composer;
this.doc = this.composer.doc;
+ this.win = this.composer.win;
this.contain = contain;
this.unselectableClass = unselectableClass || false;
},
@@ -9370,38 +9378,55 @@ wysihtml5.quirks.ensureProperClearing = (function() {
* @param {Object} node The element or text node where to position the caret in front of
* @example
* selection.setBefore(myElement);
+ * callback is an optional parameter accepting a function to execute when selection ahs been set
*/
- setAfter: function(node, notVisual) {
+ setAfter: function(node, notVisual, callback) {
var range = rangy.createRange(this.doc),
- originalScrollTop = this.doc.documentElement.scrollTop || this.doc.body.scrollTop || this.doc.defaultView.pageYOffset,
- originalScrollLeft = this.doc.documentElement.scrollLeft || this.doc.body.scrollLeft || this.doc.defaultView.pageXOffset,
+ fixWebkitSelection = function() {
+ // Webkit fails to add selection if there are no textnodes in that region
+ // (like an uneditable container at the end of content).
+ if (!sel) {
+ if (notVisual) {
+ // If setAfter is used as internal between actions, self-removing caretPlaceholder has simpler implementation
+ // and remove itself in call stack end instead on user interaction
+ var caretPlaceholder = this.doc.createTextNode(wysihtml5.INVISIBLE_SPACE);
+ node.parentNode.insertBefore(caretPlaceholder, node.nextSibling);
+ this.selectNode(caretPlaceholder);
+ setTimeout(function() {
+ if (caretPlaceholder && caretPlaceholder.parentNode) {
+ caretPlaceholder.parentNode.removeChild(caretPlaceholder);
+ }
+ }, 0);
+ } else {
+ this.createTemporaryCaretSpaceAfter(node);
+ }
+ }
+ },
sel;
range.setStartAfter(node);
range.setEndAfter(node);
- this.composer.element.focus();
- this.doc.defaultView.scrollTo(originalScrollLeft, originalScrollTop);
- sel = this.setSelection(range);
- // Webkit fails to add selection if there are no textnodes in that region
- // (like an uneditable container at the end of content).
- if (!sel) {
- if (notVisual) {
- // If setAfter is used as internal between actions, self-removing caretPlaceholder has simpler implementation
- // and remove itself in call stack end instead on user interaction
- var caretPlaceholder = this.doc.createTextNode(wysihtml5.INVISIBLE_SPACE);
- node.parentNode.insertBefore(caretPlaceholder, node.nextSibling);
- this.selectNode(caretPlaceholder);
- setTimeout(function() {
- if (caretPlaceholder && caretPlaceholder.parentNode) {
- caretPlaceholder.parentNode.removeChild(caretPlaceholder);
- }
- }, 0);
- } else {
- this.createTemporaryCaretSpaceAfter(node);
+ // In IE contenteditable must be focused before we can set selection
+ // thus setting the focus if activeElement is not this composer
+ if (!document.activeElement || document.activeElement !== this.composer.element) {
+ var scrollPos = this.composer.getScrollPos();
+ this.composer.element.focus();
+ this.composer.setScrollPos(scrollPos);
+ setTimeout(function() {
+ sel = this.setSelection(range);
+ fixWebkitSelection();
+ if (callback) {
+ callback(sel);
+ }
+ }.bind(this), 0);
+ } else {
+ sel = this.setSelection(range);
+ fixWebkitSelection();
+ if (callback) {
+ callback(sel);
}
}
- return sel;
},
/**
@@ -9704,9 +9729,7 @@ wysihtml5.quirks.ensureProperClearing = (function() {
// TODO: Figure out a method from following 2 that would work universally
executeAndRestoreRangy: function(method, restoreScrollPosition) {
- var win = this.doc.defaultView || this.doc.parentWindow,
- sel = rangy.saveSelection(win);
-
+ var sel = rangy.saveSelection(this.win);
if (!sel) {
method();
} else {
@@ -9988,8 +10011,7 @@ wysihtml5.quirks.ensureProperClearing = (function() {
* See https://developer.mozilla.org/en/DOM/Selection/modify
*/
_selectLine_W3C: function() {
- var win = this.doc.defaultView,
- selection = win.getSelection();
+ var selection = this.win.getSelection();
selection.modify("move", "left", "lineboundary");
selection.modify("extend", "right", "lineboundary");
},
@@ -9998,8 +10020,7 @@ wysihtml5.quirks.ensureProperClearing = (function() {
toLineBoundary: function (location, collapse) {
collapse = (typeof collapse === 'undefined') ? false : collapse;
if (wysihtml5.browser.supportsSelectionModify()) {
- var win = this.doc.defaultView,
- selection = win.getSelection();
+ var selection = this.win.getSelection();
selection.modify("extend", location, "lineboundary");
if (collapse) {
@@ -10139,50 +10160,49 @@ wysihtml5.quirks.ensureProperClearing = (function() {
if (r) { ranges.push(r); }
if (this.unselectableClass && this.contain && r) {
- var uneditables = this.getOwnUneditables(),
- tmpRange;
- if (uneditables.length > 0) {
- for (var i = 0, imax = uneditables.length; i < imax; i++) {
- tmpRanges = [];
- for (var j = 0, jmax = ranges.length; j < jmax; j++) {
- if (ranges[j]) {
- switch (ranges[j].compareNode(uneditables[i])) {
- case 2:
- // all selection inside uneditable. remove
- break;
- case 3:
- //section begins before and ends after uneditable. spilt
- tmpRange = ranges[j].cloneRange();
- tmpRange.setEndBefore(uneditables[i]);
- tmpRanges.push(tmpRange);
-
- tmpRange = ranges[j].cloneRange();
- tmpRange.setStartAfter(uneditables[i]);
- tmpRanges.push(tmpRange);
- break;
- default:
- // in all other cases uneditable does not touch selection. dont modify
- tmpRanges.push(ranges[j]);
- }
+ var uneditables = this.getOwnUneditables(),
+ tmpRange;
+ if (uneditables.length > 0) {
+ for (var i = 0, imax = uneditables.length; i < imax; i++) {
+ tmpRanges = [];
+ for (var j = 0, jmax = ranges.length; j < jmax; j++) {
+ if (ranges[j]) {
+ switch (ranges[j].compareNode(uneditables[i])) {
+ case 2:
+ // all selection inside uneditable. remove
+ break;
+ case 3:
+ //section begins before and ends after uneditable. spilt
+ tmpRange = ranges[j].cloneRange();
+ tmpRange.setEndBefore(uneditables[i]);
+ tmpRanges.push(tmpRange);
+
+ tmpRange = ranges[j].cloneRange();
+ tmpRange.setStartAfter(uneditables[i]);
+ tmpRanges.push(tmpRange);
+ break;
+ default:
+ // in all other cases uneditable does not touch selection. dont modify
+ tmpRanges.push(ranges[j]);
}
- ranges = tmpRanges;
}
+ ranges = tmpRanges;
}
}
+ }
}
return ranges;
},
getSelection: function() {
- return rangy.getSelection(this.doc.defaultView || this.doc.parentWindow);
+ return rangy.getSelection(this.win);
},
// Sets selection in document to a given range
// Set selection method detects if it fails to set any selection in document and returns null on fail
// (especially needed in webkit where some ranges just can not create selection for no reason)
setSelection: function(range) {
- var win = this.doc.defaultView || this.doc.parentWindow,
- selection = rangy.getSelection(win);
+ var selection = rangy.getSelection(this.win);
selection.setSingleRange(range);
return (selection && selection.anchorNode && selection.focusNode) ? selection : null;
},
@@ -10620,24 +10640,24 @@ wysihtml5.quirks.ensureProperClearing = (function() {
},
getAdjacentMergeableTextNode: function(node, forward) {
- var isTextNode = (node.nodeType == wysihtml5.TEXT_NODE);
- var el = isTextNode ? node.parentNode : node;
- var adjacentNode;
- var propName = forward ? "nextSibling" : "previousSibling";
- if (isTextNode) {
- // Can merge if the node's previous/next sibling is a text node
- adjacentNode = node[propName];
- if (adjacentNode && adjacentNode.nodeType == wysihtml5.TEXT_NODE) {
- return adjacentNode;
- }
- } else {
- // Compare element with its sibling
- adjacentNode = el[propName];
- if (adjacentNode && this.areElementsMergeable(node, adjacentNode)) {
- return adjacentNode[forward ? "firstChild" : "lastChild"];
- }
+ var isTextNode = (node.nodeType == wysihtml5.TEXT_NODE);
+ var el = isTextNode ? node.parentNode : node;
+ var adjacentNode;
+ var propName = forward ? "nextSibling" : "previousSibling";
+ if (isTextNode) {
+ // Can merge if the node's previous/next sibling is a text node
+ adjacentNode = node[propName];
+ if (adjacentNode && adjacentNode.nodeType == wysihtml5.TEXT_NODE) {
+ return adjacentNode;
}
- return null;
+ } else {
+ // Compare element with its sibling
+ adjacentNode = el[propName];
+ if (adjacentNode && this.areElementsMergeable(node, adjacentNode)) {
+ return adjacentNode[forward ? "firstChild" : "lastChild"];
+ }
+ }
+ return null;
},
areElementsMergeable: function(el1, el2) {
@@ -10715,83 +10735,83 @@ wysihtml5.quirks.ensureProperClearing = (function() {
},
applyToRange: function(range) {
- var textNodes;
- for (var ri = range.length; ri--;) {
- textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);
-
- if (!textNodes.length) {
- try {
- var node = this.createContainer(range[ri].endContainer.ownerDocument);
- range[ri].surroundContents(node);
- this.selectNode(range[ri], node);
- return;
- } catch(e) {}
- }
-
- range[ri].splitBoundaries();
- textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);
- if (textNodes.length) {
- var textNode;
+ var textNodes;
+ for (var ri = range.length; ri--;) {
+ textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);
- for (var i = 0, len = textNodes.length; i < len; ++i) {
- textNode = textNodes[i];
- if (!this.getMatchingAncestor(textNode).element) {
- this.applyToTextNode(textNode);
- }
- }
+ if (!textNodes.length) {
+ try {
+ var node = this.createContainer(range[ri].endContainer.ownerDocument);
+ range[ri].surroundContents(node);
+ this.selectNode(range[ri], node);
+ return;
+ } catch(e) {}
+ }
- range[ri].setStart(textNodes[0], 0);
- textNode = textNodes[textNodes.length - 1];
- range[ri].setEnd(textNode, textNode.length);
+ range[ri].splitBoundaries();
+ textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);
+ if (textNodes.length) {
+ var textNode;
- if (this.normalize) {
- this.postApply(textNodes, range[ri]);
- }
+ for (var i = 0, len = textNodes.length; i < len; ++i) {
+ textNode = textNodes[i];
+ if (!this.getMatchingAncestor(textNode).element) {
+ this.applyToTextNode(textNode);
}
+ }
+
+ range[ri].setStart(textNodes[0], 0);
+ textNode = textNodes[textNodes.length - 1];
+ range[ri].setEnd(textNode, textNode.length);
+ if (this.normalize) {
+ this.postApply(textNodes, range[ri]);
+ }
}
+
+ }
},
undoToRange: function(range) {
var textNodes, textNode, ancestorWithClass, ancestorWithStyle, ancestor;
for (var ri = range.length; ri--;) {
+ textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);
+ if (textNodes.length) {
+ range[ri].splitBoundaries();
textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);
- if (textNodes.length) {
- range[ri].splitBoundaries();
- textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);
- } else {
- var doc = range[ri].endContainer.ownerDocument,
- node = doc.createTextNode(wysihtml5.INVISIBLE_SPACE);
- range[ri].insertNode(node);
- range[ri].selectNode(node);
- textNodes = [node];
- }
+ } else {
+ var doc = range[ri].endContainer.ownerDocument,
+ node = doc.createTextNode(wysihtml5.INVISIBLE_SPACE);
+ range[ri].insertNode(node);
+ range[ri].selectNode(node);
+ textNodes = [node];
+ }
- for (var i = 0, len = textNodes.length; i < len; ++i) {
- if (range[ri].isValid()) {
- textNode = textNodes[i];
-
- ancestor = this.getMatchingAncestor(textNode);
- if (ancestor.type === "style") {
- this.undoToTextNode(textNode, range[ri], false, ancestor.element);
- } else if (ancestor.element) {
- this.undoToTextNode(textNode, range[ri], ancestor.element);
- }
+ for (var i = 0, len = textNodes.length; i < len; ++i) {
+ if (range[ri].isValid()) {
+ textNode = textNodes[i];
+
+ ancestor = this.getMatchingAncestor(textNode);
+ if (ancestor.type === "style") {
+ this.undoToTextNode(textNode, range[ri], false, ancestor.element);
+ } else if (ancestor.element) {
+ this.undoToTextNode(textNode, range[ri], ancestor.element);
}
}
+ }
- if (len == 1) {
- this.selectNode(range[ri], textNodes[0]);
- } else {
- range[ri].setStart(textNodes[0], 0);
- textNode = textNodes[textNodes.length - 1];
- range[ri].setEnd(textNode, textNode.length);
+ if (len == 1) {
+ this.selectNode(range[ri], textNodes[0]);
+ } else {
+ range[ri].setStart(textNodes[0], 0);
+ textNode = textNodes[textNodes.length - 1];
+ range[ri].setEnd(textNode, textNode.length);
- if (this.normalize) {
- this.postApply(textNodes, range[ri]);
- }
+ if (this.normalize) {
+ this.postApply(textNodes, range[ri]);
}
+ }
}
},
@@ -10998,21 +11018,22 @@ wysihtml5.Commands = Base.extend(
}
}
});
-;wysihtml5.commands.bold = {
- exec: function(composer, command) {
- wysihtml5.commands.formatInline.execWithToggle(composer, command, "b");
- },
-
- state: function(composer, command) {
- // element.ownerDocument.queryCommandState("bold") results:
- // firefox: only
- // chrome: , , , , ...
- // ie: ,
- // opera: ,
- return wysihtml5.commands.formatInline.state(composer, command, "b");
- }
-};
+;(function(wysihtml5){
+ wysihtml5.commands.bold = {
+ exec: function(composer, command) {
+ wysihtml5.commands.formatInline.execWithToggle(composer, command, "b");
+ },
+ state: function(composer, command) {
+ // element.ownerDocument.queryCommandState("bold") results:
+ // firefox: only
+ // chrome: , , , , ...
+ // ie: ,
+ // opera: ,
+ return wysihtml5.commands.formatInline.state(composer, command, "b");
+ }
+ };
+}(wysihtml5));
;(function(wysihtml5) {
var undef,
NODE_NAME = "A",
@@ -11185,7 +11206,7 @@ wysihtml5.Commands = Base.extend(
wysihtml5.commands.fontSize = {
exec: function(composer, command, size) {
- wysihtml5.commands.formatInline.execWithToggle(composer, command, "span", "wysiwyg-font-size-" + size, REG_EXP);
+ wysihtml5.commands.formatInline.execWithToggle(composer, command, "span", "wysiwyg-font-size-" + size, REG_EXP);
},
state: function(composer, command, size) {
@@ -11237,7 +11258,7 @@ wysihtml5.Commands = Base.extend(
wysihtml5.commands.foreColor = {
exec: function(composer, command, color) {
- wysihtml5.commands.formatInline.execWithToggle(composer, command, "span", "wysiwyg-color-" + color, REG_EXP);
+ wysihtml5.commands.formatInline.execWithToggle(composer, command, "span", "wysiwyg-color-" + color, REG_EXP);
},
state: function(composer, command, color) {
@@ -11624,7 +11645,7 @@ wysihtml5.Commands = Base.extend(
if (options && options.toggle) {
state = this.state(composer, command, options);
if (state) {
- bookmark = rangy.saveSelection(composer.doc.defaultView || composer.doc.parentWindow);
+ bookmark = rangy.saveSelection(composer.win);
for (var j in state) {
removeOptionsFromElement(state[j], options, composer);
}
@@ -11639,12 +11660,12 @@ wysihtml5.Commands = Base.extend(
query: BLOCK_ELEMENTS
}, null, composer.element);
if (parent) {
- bookmark = rangy.saveSelection(composer.doc.defaultView || composer.doc.parentWindow);
+ bookmark = rangy.saveSelection(composer.win);
range = composer.selection.createRange();
range.selectNode(parent);
composer.selection.setSelection(range);
} else if (!composer.isEmpty()) {
- bookmark = rangy.saveSelection(composer.doc.defaultView || composer.doc.parentWindow);
+ bookmark = rangy.saveSelection(composer.win);
composer.selection.selectLine();
}
}
@@ -11700,7 +11721,6 @@ wysihtml5.Commands = Base.extend(
return (nodes.length === 0) ? false : nodes;
}
-
};
})(wysihtml5);
;/* Formats block for as a
block
@@ -11711,48 +11731,51 @@ wysihtml5.Commands = Base.extend(
* editorInstance.composer.commands.exec("formatCode", "language-html");
*/
-wysihtml5.commands.formatCode = {
+(function(wysihtml5){
+ wysihtml5.commands.formatCode = {
- exec: function(composer, command, classname) {
- var pre = this.state(composer),
- code, range, selectedNodes;
- if (pre) {
- // caret is already within a ...
- composer.selection.executeAndRestore(function() {
- code = pre.querySelector("code");
- wysihtml5.dom.replaceWithChildNodes(pre);
- if (code) {
- wysihtml5.dom.replaceWithChildNodes(code);
+ exec: function(composer, command, classname) {
+ var pre = this.state(composer),
+ code, range, selectedNodes;
+ if (pre) {
+ // caret is already within a ...
+ composer.selection.executeAndRestore(function() {
+ code = pre.querySelector("code");
+ wysihtml5.dom.replaceWithChildNodes(pre);
+ if (code) {
+ wysihtml5.dom.replaceWithChildNodes(code);
+ }
+ });
+ } else {
+ // Wrap in ...
+ range = composer.selection.getRange();
+ selectedNodes = range.extractContents();
+ pre = composer.doc.createElement("pre");
+ code = composer.doc.createElement("code");
+
+ if (classname) {
+ code.className = classname;
}
- });
- } else {
- // Wrap in ...
- range = composer.selection.getRange();
- selectedNodes = range.extractContents();
- pre = composer.doc.createElement("pre");
- code = composer.doc.createElement("code");
- if (classname) {
- code.className = classname;
+ pre.appendChild(code);
+ code.appendChild(selectedNodes);
+ range.insertNode(pre);
+ composer.selection.selectNode(pre);
}
+ },
- pre.appendChild(code);
- code.appendChild(selectedNodes);
- range.insertNode(pre);
- composer.selection.selectNode(pre);
- }
- },
-
- state: function(composer) {
- var selectedNode = composer.selection.getSelectedNode();
- if (selectedNode && selectedNode.nodeName && selectedNode.nodeName == "PRE"&&
- selectedNode.firstChild && selectedNode.firstChild.nodeName && selectedNode.firstChild.nodeName == "CODE") {
- return selectedNode;
- } else {
- return wysihtml5.dom.getParentElement(selectedNode, { query: "pre code" });
+ state: function(composer) {
+ var selectedNode = composer.selection.getSelectedNode();
+ if (selectedNode && selectedNode.nodeName && selectedNode.nodeName == "PRE"&&
+ selectedNode.firstChild && selectedNode.firstChild.nodeName && selectedNode.firstChild.nodeName == "CODE") {
+ return selectedNode;
+ } else {
+ return wysihtml5.dom.getParentElement(selectedNode, { query: "pre code" });
+ }
}
- }
-};;/**
+ };
+}(wysihtml5));
+;/**
* formatInline scenarios for tag "B" (| = caret, |foo| = selected text)
*
* #1 caret in unformatted text:
@@ -11920,19 +11943,21 @@ wysihtml5.commands.formatCode = {
};
})(wysihtml5);
-;wysihtml5.commands.insertHTML = {
- exec: function(composer, command, html) {
- if (composer.commands.support(command)) {
- composer.doc.execCommand(command, false, html);
- } else {
- composer.selection.insertHTML(html);
- }
- },
+;(function(wysihtml5){
+ wysihtml5.commands.insertHTML = {
+ exec: function(composer, command, html) {
+ if (composer.commands.support(command)) {
+ composer.doc.execCommand(command, false, html);
+ } else {
+ composer.selection.insertHTML(html);
+ }
+ },
- state: function() {
- return false;
- }
-};
+ state: function() {
+ return false;
+ }
+ };
+}(wysihtml5));
;(function(wysihtml5) {
var NODE_NAME = "IMG";
@@ -12062,24 +12087,28 @@ wysihtml5.commands.formatCode = {
}
};
})(wysihtml5);
-;wysihtml5.commands.insertOrderedList = {
- exec: function(composer, command) {
- wysihtml5.commands.insertList.exec(composer, command, "OL");
- },
+;(function(wysihtml5){
+ wysihtml5.commands.insertOrderedList = {
+ exec: function(composer, command) {
+ wysihtml5.commands.insertList.exec(composer, command, "OL");
+ },
- state: function(composer, command) {
- return wysihtml5.commands.insertList.state(composer, command, "OL");
- }
-};
-;wysihtml5.commands.insertUnorderedList = {
- exec: function(composer, command) {
- wysihtml5.commands.insertList.exec(composer, command, "UL");
- },
+ state: function(composer, command) {
+ return wysihtml5.commands.insertList.state(composer, command, "OL");
+ }
+ };
+}(wysihtml5));
+;(function(wysihtml5){
+ wysihtml5.commands.insertUnorderedList = {
+ exec: function(composer, command) {
+ wysihtml5.commands.insertList.exec(composer, command, "UL");
+ },
- state: function(composer, command) {
- return wysihtml5.commands.insertList.state(composer, command, "UL");
- }
-};
+ state: function(composer, command) {
+ return wysihtml5.commands.insertList.state(composer, command, "UL");
+ }
+ };
+}(wysihtml5));
;wysihtml5.commands.insertList = (function(wysihtml5) {
var isNode = function(node, name) {
@@ -12196,10 +12225,10 @@ wysihtml5.commands.formatCode = {
}),
isEmpty, list;
- // This space causes new lists to never break on enter
+ // This space causes new lists to never break on enter
var INVISIBLE_SPACE_REG_EXP = /\uFEFF/g;
tempElement.innerHTML = tempElement.innerHTML.replace(wysihtml5.INVISIBLE_SPACE_REG_EXP, "");
-
+
if (tempElement) {
isEmpty = wysihtml5.lang.array(["", "
", wysihtml5.INVISIBLE_SPACE]).contains(tempElement.innerHTML);
list = wysihtml5.dom.convertToList(tempElement, nodeName.toLowerCase(), composer.parent.config.uneditableContainerClassname);
@@ -12217,7 +12246,7 @@ wysihtml5.commands.formatCode = {
selectedNode = composer.selection.getSelectedNode(),
list = findListEl(selectedNode, nodeName, composer);
- if (!list.el) {
+ if (!list.el) {
if (composer.commands.support(cmd)) {
doc.execCommand(cmd, false, null);
} else {
@@ -12238,20 +12267,23 @@ wysihtml5.commands.formatCode = {
}
};
-})(wysihtml5);;wysihtml5.commands.italic = {
- exec: function(composer, command) {
- wysihtml5.commands.formatInline.execWithToggle(composer, command, "i");
- },
+})(wysihtml5);
+;(function(wysihtml5){
+ wysihtml5.commands.italic = {
+ exec: function(composer, command) {
+ wysihtml5.commands.formatInline.execWithToggle(composer, command, "i");
+ },
- state: function(composer, command) {
- // element.ownerDocument.queryCommandState("italic") results:
- // firefox: only
- // chrome: , , , ...
- // ie: ,
- // opera: only
- return wysihtml5.commands.formatInline.state(composer, command, "i");
- }
-};
+ state: function(composer, command) {
+ // element.ownerDocument.queryCommandState("italic") results:
+ // firefox: only
+ // chrome: , , , ...
+ // ie: ,
+ // opera: only
+ return wysihtml5.commands.formatInline.state(composer, command, "i");
+ }
+ };
+}(wysihtml5));
;(function(wysihtml5) {
var nodeOptions = {
@@ -12381,272 +12413,312 @@ wysihtml5.commands.formatCode = {
};
})(wysihtml5);
-;wysihtml5.commands.redo = {
- exec: function(composer) {
- return composer.undoManager.redo();
- },
+;(function(wysihtml5){
+ wysihtml5.commands.redo = {
+ exec: function(composer) {
+ return composer.undoManager.redo();
+ },
- state: function(composer) {
- return false;
- }
-};
-;wysihtml5.commands.underline = {
- exec: function(composer, command) {
- wysihtml5.commands.formatInline.execWithToggle(composer, command, "u");
- },
+ state: function(composer) {
+ return false;
+ }
+ };
+}(wysihtml5));
+;(function(wysihtml5){
+ wysihtml5.commands.underline = {
+ exec: function(composer, command) {
+ wysihtml5.commands.formatInline.execWithToggle(composer, command, "u");
+ },
- state: function(composer, command) {
- return wysihtml5.commands.formatInline.state(composer, command, "u");
- }
-};
-;wysihtml5.commands.undo = {
- exec: function(composer) {
- return composer.undoManager.undo();
- },
+ state: function(composer, command) {
+ return wysihtml5.commands.formatInline.state(composer, command, "u");
+ }
+ };
+}(wysihtml5));
+;(function(wysihtml5){
+ wysihtml5.commands.undo = {
+ exec: function(composer) {
+ return composer.undoManager.undo();
+ },
- state: function(composer) {
- return false;
- }
-};
-;wysihtml5.commands.createTable = {
- exec: function(composer, command, value) {
+ state: function(composer) {
+ return false;
+ }
+ };
+}(wysihtml5));
+;(function(wysihtml5){
+ wysihtml5.commands.createTable = {
+ exec: function(composer, command, value) {
var col, row, html;
if (value && value.cols && value.rows && parseInt(value.cols, 10) > 0 && parseInt(value.rows, 10) > 0) {
- if (value.tableStyle) {
- html = "";
- } else {
- html = "";
- }
- html += "";
- for (row = 0; row < value.rows; row ++) {
- html += '';
- for (col = 0; col < value.cols; col ++) {
- html += " | ";
- }
- html += '
';
+ if (value.tableStyle) {
+ html = "";
+ } else {
+ html = "";
+ }
+ html += "";
+ for (row = 0; row < value.rows; row ++) {
+ html += '';
+ for (col = 0; col < value.cols; col ++) {
+ html += " | ";
}
- html += "
";
- composer.commands.exec("insertHTML", html);
- //composer.selection.insertHTML(html);
+ html += '';
+ }
+ html += "
";
+ composer.commands.exec("insertHTML", html);
+ //composer.selection.insertHTML(html);
}
+ },
-
- },
-
- state: function(composer, command) {
+ state: function(composer, command) {
return false;
- }
-};
-;wysihtml5.commands.mergeTableCells = {
- exec: function(composer, command) {
+ }
+ };
+
+}(wysihtml5));
+;(function(wysihtml5){
+ wysihtml5.commands.mergeTableCells = {
+ exec: function(composer, command) {
if (composer.tableSelection && composer.tableSelection.start && composer.tableSelection.end) {
- if (this.state(composer, command)) {
- wysihtml5.dom.table.unmergeCell(composer.tableSelection.start);
- } else {
- wysihtml5.dom.table.mergeCellsBetween(composer.tableSelection.start, composer.tableSelection.end);
- }
+ if (this.state(composer, command)) {
+ wysihtml5.dom.table.unmergeCell(composer.tableSelection.start);
+ } else {
+ wysihtml5.dom.table.mergeCellsBetween(composer.tableSelection.start, composer.tableSelection.end);
+ }
}
- },
+ },
- state: function(composer, command) {
+ state: function(composer, command) {
if (composer.tableSelection) {
- var start = composer.tableSelection.start,
- end = composer.tableSelection.end;
- if (start && end && start == end &&
- ((
- wysihtml5.dom.getAttribute(start, "colspan") &&
- parseInt(wysihtml5.dom.getAttribute(start, "colspan"), 10) > 1
- ) || (
- wysihtml5.dom.getAttribute(start, "rowspan") &&
- parseInt(wysihtml5.dom.getAttribute(start, "rowspan"), 10) > 1
- ))
- ) {
- return [start];
- }
+ var start = composer.tableSelection.start,
+ end = composer.tableSelection.end;
+ if (start && end && start == end &&
+ ((
+ wysihtml5.dom.getAttribute(start, "colspan") &&
+ parseInt(wysihtml5.dom.getAttribute(start, "colspan"), 10) > 1
+ ) || (
+ wysihtml5.dom.getAttribute(start, "rowspan") &&
+ parseInt(wysihtml5.dom.getAttribute(start, "rowspan"), 10) > 1
+ ))
+ ) {
+ return [start];
+ }
}
return false;
- }
-};
-;wysihtml5.commands.addTableCells = {
- exec: function(composer, command, value) {
+ }
+ };
+}(wysihtml5));
+;(function(wysihtml5){
+ wysihtml5.commands.addTableCells = {
+ exec: function(composer, command, value) {
if (composer.tableSelection && composer.tableSelection.start && composer.tableSelection.end) {
- // switches start and end if start is bigger than end (reverse selection)
- var tableSelect = wysihtml5.dom.table.orderSelectionEnds(composer.tableSelection.start, composer.tableSelection.end);
- if (value == "before" || value == "above") {
- wysihtml5.dom.table.addCells(tableSelect.start, value);
- } else if (value == "after" || value == "below") {
- wysihtml5.dom.table.addCells(tableSelect.end, value);
- }
- setTimeout(function() {
- composer.tableSelection.select(tableSelect.start, tableSelect.end);
- },0);
+ // switches start and end if start is bigger than end (reverse selection)
+ var tableSelect = wysihtml5.dom.table.orderSelectionEnds(composer.tableSelection.start, composer.tableSelection.end);
+ if (value == "before" || value == "above") {
+ wysihtml5.dom.table.addCells(tableSelect.start, value);
+ } else if (value == "after" || value == "below") {
+ wysihtml5.dom.table.addCells(tableSelect.end, value);
+ }
+ setTimeout(function() {
+ composer.tableSelection.select(tableSelect.start, tableSelect.end);
+ },0);
}
- },
+ },
- state: function(composer, command) {
+ state: function(composer, command) {
return false;
- }
-};
-;wysihtml5.commands.deleteTableCells = {
+ }
+ };
+}(wysihtml5));
+;(function(wysihtml5){
+ wysihtml5.commands.deleteTableCells = {
exec: function(composer, command, value) {
- if (composer.tableSelection && composer.tableSelection.start && composer.tableSelection.end) {
- var tableSelect = wysihtml5.dom.table.orderSelectionEnds(composer.tableSelection.start, composer.tableSelection.end),
- idx = wysihtml5.dom.table.indexOf(tableSelect.start),
- selCell,
- table = composer.tableSelection.table;
-
- wysihtml5.dom.table.removeCells(tableSelect.start, value);
- setTimeout(function() {
- // move selection to next or previous if not present
- selCell = wysihtml5.dom.table.findCell(table, idx);
-
- if (!selCell){
- if (value == "row") {
- selCell = wysihtml5.dom.table.findCell(table, {
- "row": idx.row - 1,
- "col": idx.col
- });
- }
-
- if (value == "column") {
- selCell = wysihtml5.dom.table.findCell(table, {
- "row": idx.row,
- "col": idx.col - 1
- });
- }
- }
- if (selCell) {
- composer.tableSelection.select(selCell, selCell);
- }
- }, 0);
+ if (composer.tableSelection && composer.tableSelection.start && composer.tableSelection.end) {
+ var tableSelect = wysihtml5.dom.table.orderSelectionEnds(composer.tableSelection.start, composer.tableSelection.end),
+ idx = wysihtml5.dom.table.indexOf(tableSelect.start),
+ selCell,
+ table = composer.tableSelection.table;
- }
- },
+ wysihtml5.dom.table.removeCells(tableSelect.start, value);
+ setTimeout(function() {
+ // move selection to next or previous if not present
+ selCell = wysihtml5.dom.table.findCell(table, idx);
+
+ if (!selCell){
+ if (value == "row") {
+ selCell = wysihtml5.dom.table.findCell(table, {
+ "row": idx.row - 1,
+ "col": idx.col
+ });
+ }
- state: function(composer, command) {
- return false;
- }
-};
-;wysihtml5.commands.indentList = {
- exec: function(composer, command, value) {
- var listEls = composer.selection.getSelectionParentsByTag('LI');
- if (listEls) {
- return this.tryToPushLiLevel(listEls, composer.selection);
+ if (value == "column") {
+ selCell = wysihtml5.dom.table.findCell(table, {
+ "row": idx.row,
+ "col": idx.col - 1
+ });
+ }
+ }
+ if (selCell) {
+ composer.tableSelection.select(selCell, selCell);
+ }
+ }, 0);
}
- return false;
},
state: function(composer, command) {
+ return false;
+ }
+ };
+}(wysihtml5));
+;(function(wysihtml5){
+ wysihtml5.commands.indentList = {
+ exec: function(composer, command, value) {
+ var listEls = composer.selection.getSelectionParentsByTag('LI');
+ if (listEls) {
+ return this.tryToPushLiLevel(listEls, composer.selection);
+ }
return false;
- },
+ },
- tryToPushLiLevel: function(liNodes, selection) {
- var listTag, list, prevLi, liNode, prevLiList,
- found = false;
+ state: function(composer, command) {
+ return false;
+ },
- selection.executeAndRestoreRangy(function() {
+ tryToPushLiLevel: function(liNodes, selection) {
+ var listTag, list, prevLi, liNode, prevLiList,
+ found = false;
- for (var i = liNodes.length; i--;) {
- liNode = liNodes[i];
- listTag = (liNode.parentNode.nodeName === 'OL') ? 'OL' : 'UL';
- list = liNode.ownerDocument.createElement(listTag);
- prevLi = wysihtml5.dom.domNode(liNode).prev({nodeTypes: [wysihtml5.ELEMENT_NODE]});
- prevLiList = (prevLi) ? prevLi.querySelector('ul, ol') : null;
+ selection.executeAndRestoreRangy(function() {
- if (prevLi) {
- if (prevLiList) {
- prevLiList.appendChild(liNode);
- } else {
- list.appendChild(liNode);
- prevLi.appendChild(list);
+ for (var i = liNodes.length; i--;) {
+ liNode = liNodes[i];
+ listTag = (liNode.parentNode.nodeName === 'OL') ? 'OL' : 'UL';
+ list = liNode.ownerDocument.createElement(listTag);
+ prevLi = wysihtml5.dom.domNode(liNode).prev({nodeTypes: [wysihtml5.ELEMENT_NODE]});
+ prevLiList = (prevLi) ? prevLi.querySelector('ul, ol') : null;
+
+ if (prevLi) {
+ if (prevLiList) {
+ prevLiList.appendChild(liNode);
+ } else {
+ list.appendChild(liNode);
+ prevLi.appendChild(list);
+ }
+ found = true;
}
- found = true;
}
- }
- });
- return found;
- }
-};
-;wysihtml5.commands.outdentList = {
- exec: function(composer, command, value) {
- var listEls = composer.selection.getSelectionParentsByTag('LI');
- if (listEls) {
- return this.tryToPullLiLevel(listEls, composer);
+ });
+ return found;
}
- return false;
- },
+ };
+}(wysihtml5));
+;(function(wysihtml5){
- state: function(composer, command) {
+ wysihtml5.commands.outdentList = {
+ exec: function(composer, command, value) {
+ var listEls = composer.selection.getSelectionParentsByTag('LI');
+ if (listEls) {
+ return this.tryToPullLiLevel(listEls, composer);
+ }
return false;
- },
+ },
- tryToPullLiLevel: function(liNodes, composer) {
- var listNode, outerListNode, outerLiNode, list, prevLi, liNode, afterList,
- found = false,
- that = this;
+ state: function(composer, command) {
+ return false;
+ },
- composer.selection.executeAndRestoreRangy(function() {
+ tryToPullLiLevel: function(liNodes, composer) {
+ var listNode, outerListNode, outerLiNode, list, prevLi, liNode, afterList,
+ found = false,
+ that = this;
- for (var i = liNodes.length; i--;) {
- liNode = liNodes[i];
- if (liNode.parentNode) {
- listNode = liNode.parentNode;
+ composer.selection.executeAndRestoreRangy(function() {
- if (listNode.tagName === 'OL' || listNode.tagName === 'UL') {
- found = true;
+ for (var i = liNodes.length; i--;) {
+ liNode = liNodes[i];
+ if (liNode.parentNode) {
+ listNode = liNode.parentNode;
- outerListNode = wysihtml5.dom.getParentElement(listNode.parentNode, { query: 'ol, ul' }, false, composer.element);
- outerLiNode = wysihtml5.dom.getParentElement(listNode.parentNode, { query: 'li' }, false, composer.element);
+ if (listNode.tagName === 'OL' || listNode.tagName === 'UL') {
+ found = true;
- if (outerListNode && outerLiNode) {
+ outerListNode = wysihtml5.dom.getParentElement(listNode.parentNode, { query: 'ol, ul' }, false, composer.element);
+ outerLiNode = wysihtml5.dom.getParentElement(listNode.parentNode, { query: 'li' }, false, composer.element);
- if (liNode.nextSibling) {
- afterList = that.getAfterList(listNode, liNode);
- liNode.appendChild(afterList);
- }
- outerListNode.insertBefore(liNode, outerLiNode.nextSibling);
+ if (outerListNode && outerLiNode) {
- } else {
+ if (liNode.nextSibling) {
+ afterList = that.getAfterList(listNode, liNode);
+ liNode.appendChild(afterList);
+ }
+ outerListNode.insertBefore(liNode, outerLiNode.nextSibling);
- if (liNode.nextSibling) {
- afterList = that.getAfterList(listNode, liNode);
- liNode.appendChild(afterList);
- }
+ } else {
- for (var j = liNode.childNodes.length; j--;) {
- listNode.parentNode.insertBefore(liNode.childNodes[j], listNode.nextSibling);
- }
+ if (liNode.nextSibling) {
+ afterList = that.getAfterList(listNode, liNode);
+ liNode.appendChild(afterList);
+ }
- listNode.parentNode.insertBefore(document.createElement('br'), listNode.nextSibling);
- liNode.parentNode.removeChild(liNode);
+ for (var j = liNode.childNodes.length; j--;) {
+ listNode.parentNode.insertBefore(liNode.childNodes[j], listNode.nextSibling);
+ }
- }
+ listNode.parentNode.insertBefore(document.createElement('br'), listNode.nextSibling);
+ liNode.parentNode.removeChild(liNode);
- // cleanup
- if (listNode.childNodes.length === 0) {
- listNode.parentNode.removeChild(listNode);
+ }
+
+ // cleanup
+ if (listNode.childNodes.length === 0) {
+ listNode.parentNode.removeChild(listNode);
+ }
}
}
}
- }
- });
- return found;
- },
+ });
+ return found;
+ },
- getAfterList: function(listNode, liNode) {
- var nodeName = listNode.nodeName,
- newList = document.createElement(nodeName);
+ getAfterList: function(listNode, liNode) {
+ var nodeName = listNode.nodeName,
+ newList = document.createElement(nodeName);
- while (liNode.nextSibling) {
- newList.appendChild(liNode.nextSibling);
+ while (liNode.nextSibling) {
+ newList.appendChild(liNode.nextSibling);
+ }
+ return newList;
}
- return newList;
- }
-};;/**
+ };
+}(wysihtml5));
+;(function(wysihtml5){
+ wysihtml5.commands.subscript = {
+ exec: function(composer, command) {
+ wysihtml5.commands.formatInline.execWithToggle(composer, command, "sub");
+ },
+
+ state: function(composer, command) {
+ return wysihtml5.commands.formatInline.state(composer, command, "sub");
+ }
+ };
+}(wysihtml5));
+;(function(wysihtml5){
+ wysihtml5.commands.superscript = {
+ exec: function(composer, command) {
+ wysihtml5.commands.formatInline.execWithToggle(composer, command, "sup");
+ },
+
+ state: function(composer, command) {
+ return wysihtml5.commands.formatInline.state(composer, command, "sup");
+ }
+ };
+}(wysihtml5));
+;/**
* Undo Manager for wysihtml5
* slightly inspired by http://rniwa.com/editing/undomanager.html#the-undomanager-interface
*/
@@ -12968,7 +13040,7 @@ wysihtml5.views.View = Base.extend(
cleanUp: function() {
var bookmark;
if (this.selection) {
- bookmark = rangy.saveSelection(this.doc.defaultView || this.doc.parentWindow);
+ bookmark = rangy.saveSelection(this.win);
}
this.parent.parse(this.element);
if (bookmark) {
@@ -13024,6 +13096,32 @@ wysihtml5.views.View = Base.extend(
}
},
+ getScrollPos: function() {
+ if (this.doc && this.win) {
+ var pos = {};
+
+ if (typeof this.win.pageYOffset !== "undefined") {
+ pos.y = this.win.pageYOffset;
+ } else {
+ pos.y = (this.doc.documentElement || this.doc.body.parentNode || this.doc.body).scrollTop;
+ }
+
+ if (typeof this.win.pageXOffset !== "undefined") {
+ pos.x = this.win.pageXOffset;
+ } else {
+ pos.x = (this.doc.documentElement || this.doc.body.parentNode || this.doc.body).scrollLeft;
+ }
+
+ return pos;
+ }
+ },
+
+ setScrollPos: function(pos) {
+ if (pos && typeof pos.x !== "undefined" && typeof pos.y !== "undefined") {
+ this.win.scrollTo(pos.x, pos.y);
+ }
+ },
+
getTextContent: function() {
return dom.getTextContent(this.element);
},
@@ -13089,6 +13187,7 @@ wysihtml5.views.View = Base.extend(
_create: function() {
var that = this;
this.doc = this.sandbox.getDocument();
+ this.win = this.sandbox.getWindow();
this.element = (this.config.contentEditableMode) ? this.sandbox.getContentEditable() : this.doc.body;
if (!this.config.noTextarea) {
this.textarea = this.parent.textarea;
@@ -13628,22 +13727,34 @@ wysihtml5.views.View = Base.extend(
} else if (selection.caretIsInTheBeginnig()) {
event.preventDefault();
} else {
-
if (selection.caretIsFirstInSelection() &&
selection.getPreviousNode() &&
selection.getPreviousNode().nodeName &&
(/^H\d$/gi).test(selection.getPreviousNode().nodeName)
) {
var prevNode = selection.getPreviousNode();
- event.preventDefault();
if ((/^\s*$/).test(prevNode.textContent || prevNode.innerText)) {
// heading is empty
+ event.preventDefault();
prevNode.parentNode.removeChild(prevNode);
} else {
- var range = prevNode.ownerDocument.createRange();
- range.selectNodeContents(prevNode);
- range.collapse(false);
- selection.setSelection(range);
+ if (prevNode.lastChild) {
+ var selNode = prevNode.lastChild,
+ curNode = wysihtml5.dom.getParentElement(selection.getSelectedNode(), { query: "h1, h2, h3, h4, h5, h6, p, pre, div, blockquote" }, false, composer.element);
+ if (prevNode) {
+ if (curNode) {
+ event.preventDefault();
+ while (curNode.firstChild) {
+ prevNode.appendChild(curNode.firstChild);
+ }
+ selection.setAfter(selNode);
+ } else if (selection.getSelectedNode().nodeType === 3) {
+ event.preventDefault();
+ prevNode.appendChild(selection.getSelectedNode());
+ selection.setAfter(selNode);
+ }
+ }
+ }
}
}
@@ -14306,8 +14417,7 @@ wysihtml5.views.View = Base.extend(
* - Observes for paste and drop
*/
_initParser: function() {
- var that = this,
- oldHtml,
+ var oldHtml,
cleanHtml;
if (wysihtml5.browser.supportsModenPaste()) {
@@ -14315,20 +14425,23 @@ wysihtml5.views.View = Base.extend(
event.preventDefault();
oldHtml = wysihtml5.dom.getPastedHtml(event);
if (oldHtml) {
- that._cleanAndPaste(oldHtml);
+ this._cleanAndPaste(oldHtml);
}
- });
+ }.bind(this));
} else {
this.on("beforepaste:composer", function(event) {
event.preventDefault();
- wysihtml5.dom.getPastedHtmlWithDiv(that.composer, function(pastedHTML) {
+ var scrollPos = this.composer.getScrollPos();
+
+ wysihtml5.dom.getPastedHtmlWithDiv(this.composer, function(pastedHTML) {
if (pastedHTML) {
- that._cleanAndPaste(pastedHTML);
+ this._cleanAndPaste(pastedHTML);
}
- });
- });
+ this.composer.setScrollPos(scrollPos);
+ }.bind(this));
+ }.bind(this));
}
},
@@ -14968,13 +15081,11 @@ wysihtml5.views.View = Base.extend(
})(wysihtml5);
;(function(wysihtml5) {
- wysihtml5.toolbar.Dialog_createTable = wysihtml5.toolbar.Dialog.extend({
- show: function(elementToChange) {
- this.base(elementToChange);
-
- }
-
- });
+ wysihtml5.toolbar.Dialog_createTable = wysihtml5.toolbar.Dialog.extend({
+ show: function(elementToChange) {
+ this.base(elementToChange);
+ }
+ });
})(wysihtml5);
;(function(wysihtml5) {
var dom = wysihtml5.dom,
diff --git a/vendor/assets/javascripts/wysihtml.js b/vendor/assets/javascripts/wysihtml.js
index 7dd462d..3b76a14 100644
--- a/vendor/assets/javascripts/wysihtml.js
+++ b/vendor/assets/javascripts/wysihtml.js
@@ -375,9 +375,8 @@ if ("document" in self) {
}
}
-
;/**
- * @license wysihtml5x v0.5.0-beta3
+ * @license wysihtml5x v0.5.0-beta4
* https://github.com/Edicy/wysihtml5
*
* Author: Christopher Blum (https://github.com/tiff)
@@ -388,7 +387,7 @@ if ("document" in self) {
*
*/
var wysihtml5 = {
- version: "0.5.0-beta3",
+ version: "0.5.0-beta4",
// namespaces
commands: {},
@@ -4927,7 +4926,7 @@ wysihtml5.browser = (function() {
},
supportsMutationEvents: function() {
- return ("MutationEvent" in window);
+ return ("MutationEvent" in window);
},
/**
@@ -5878,7 +5877,8 @@ wysihtml5.dom.copyAttributes = function(attributesToCopy) {
};
};
-})(wysihtml5);;/**
+})(wysihtml5);
+;/**
* Returns the given html wrapped in a div element
*
* Fixing IE's inability to treat unknown elements (HTML5 section, article, ...) correctly
@@ -5972,7 +5972,8 @@ wysihtml5.dom.getParentElement = (function() {
return null;
};
-})();;/**
+})();
+;/**
* Get element's style for a specific css property
*
* @param {Element} element The element on which to retrieve the style
@@ -6057,7 +6058,8 @@ wysihtml5.dom.getStyle = (function() {
}
}
return all;
-};;/**
+};
+;/**
* High performant way to check whether an element with a specific tag name is in the given document
* Optimized for being heavily executed
* Unleashes the power of live node lists
@@ -7181,7 +7183,11 @@ wysihtml5.dom.renameElement = function(element, newNodeName) {
newElement.appendChild(firstChild);
}
wysihtml5.dom.copyAttributes(["align", "className"]).from(element).to(newElement);
- element.parentNode.replaceChild(newElement, element);
+
+ if (element.parentNode) {
+ element.parentNode.replaceChild(newElement, element);
+ }
+
return newElement;
};
;/**
@@ -7567,7 +7573,7 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
},
getWindow: function() {
- return this.element.ownerDocument.defaultView;
+ return this.element.ownerDocument.defaultView || this.element.ownerDocument.parentWindow;
},
getDocument: function() {
@@ -7594,29 +7600,19 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
// initiates an allready existent contenteditable
_bindElement: function(contentEditable) {
- contentEditable.className = (contentEditable.className && contentEditable.className != '') ? contentEditable.className + " wysihtml5-sandbox" : "wysihtml5-sandbox";
+ contentEditable.className = (contentEditable.className && contentEditable.className !== '') ? contentEditable.className + " wysihtml5-sandbox" : "wysihtml5-sandbox";
this._loadElement(contentEditable, true);
return contentEditable;
},
_loadElement: function(element, contentExists) {
- var that = this;
+ var that = this;
+
if (!contentExists) {
- var sandboxHtml = this._getHtml();
- element.innerHTML = sandboxHtml;
+ var innerHtml = this._getHtml();
+ element.innerHTML = innerHtml;
}
- this.getWindow = function() { return element.ownerDocument.defaultView; };
- this.getDocument = function() { return element.ownerDocument; };
-
- // Catch js errors and pass them to the parent's onerror event
- // addEventListener("error") doesn't work properly in some browsers
- // TODO: apparently this doesn't work in IE9!
- // TODO: figure out and bind the errors logic for contenteditble mode
- /*iframeWindow.onerror = function(errorMessage, fileName, lineNumber) {
- throw new Error("wysihtml5.Sandbox: " + errorMessage, fileName, lineNumber);
- }
- */
this.loaded = true;
// Trigger the callback
setTimeout(function() { that.callback(that); }, 0);
@@ -7741,7 +7737,6 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
};
}
})(wysihtml5.dom);
-
;/**
* Get a set of attribute from one element
*
@@ -7805,7 +7800,8 @@ wysihtml5.dom.getAttributes = function(node) {
}
}
return attributes;
-};;/**
+};
+;/**
* Check whether the given node is a proper loaded image
* FIXME: Returns undefined when unknown (Chrome, Safari)
*/
@@ -7821,884 +7817,881 @@ wysihtml5.dom.isLoadedImage = function (node) {
};
;(function(wysihtml5) {
- var api = wysihtml5.dom;
-
- var MapCell = function(cell) {
- this.el = cell;
- this.isColspan= false;
- this.isRowspan= false;
- this.firstCol= true;
- this.lastCol= true;
- this.firstRow= true;
- this.lastRow= true;
- this.isReal= true;
- this.spanCollection= [];
- this.modified = false;
- };
+ var api = wysihtml5.dom;
- var TableModifyerByCell = function (cell, table) {
- if (cell) {
- this.cell = cell;
- this.table = api.getParentElement(cell, { query: "table" });
- } else if (table) {
- this.table = table;
- this.cell = this.table.querySelectorAll('th, td')[0];
- }
- };
+ var MapCell = function(cell) {
+ this.el = cell;
+ this.isColspan= false;
+ this.isRowspan= false;
+ this.firstCol= true;
+ this.lastCol= true;
+ this.firstRow= true;
+ this.lastRow= true;
+ this.isReal= true;
+ this.spanCollection= [];
+ this.modified = false;
+ };
- function queryInList(list, query) {
- var ret = [],
- q;
- for (var e = 0, len = list.length; e < len; e++) {
- q = list[e].querySelectorAll(query);
- if (q) {
- for(var i = q.length; i--; ret.unshift(q[i]));
- }
- }
- return ret;
+ var TableModifyerByCell = function (cell, table) {
+ if (cell) {
+ this.cell = cell;
+ this.table = api.getParentElement(cell, { query: "table" });
+ } else if (table) {
+ this.table = table;
+ this.cell = this.table.querySelectorAll('th, td')[0];
}
+ };
- function removeElement(el) {
- el.parentNode.removeChild(el);
+ function queryInList(list, query) {
+ var ret = [],
+ q;
+ for (var e = 0, len = list.length; e < len; e++) {
+ q = list[e].querySelectorAll(query);
+ if (q) {
+ for(var i = q.length; i--; ret.unshift(q[i]));
+ }
}
+ return ret;
+ }
- function insertAfter(referenceNode, newNode) {
- referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
- }
+ function removeElement(el) {
+ el.parentNode.removeChild(el);
+ }
- function nextNode(node, tag) {
- var element = node.nextSibling;
- while (element.nodeType !=1) {
- element = element.nextSibling;
- if (!tag || tag == element.tagName.toLowerCase()) {
- return element;
- }
- }
- return null;
+ function insertAfter(referenceNode, newNode) {
+ referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
+ }
+
+ function nextNode(node, tag) {
+ var element = node.nextSibling;
+ while (element.nodeType !=1) {
+ element = element.nextSibling;
+ if (!tag || tag == element.tagName.toLowerCase()) {
+ return element;
+ }
}
+ return null;
+ }
- TableModifyerByCell.prototype = {
+ TableModifyerByCell.prototype = {
- addSpannedCellToMap: function(cell, map, r, c, cspan, rspan) {
- var spanCollect = [],
- rmax = r + ((rspan) ? parseInt(rspan, 10) - 1 : 0),
- cmax = c + ((cspan) ? parseInt(cspan, 10) - 1 : 0);
+ addSpannedCellToMap: function(cell, map, r, c, cspan, rspan) {
+ var spanCollect = [],
+ rmax = r + ((rspan) ? parseInt(rspan, 10) - 1 : 0),
+ cmax = c + ((cspan) ? parseInt(cspan, 10) - 1 : 0);
- for (var rr = r; rr <= rmax; rr++) {
- if (typeof map[rr] == "undefined") { map[rr] = []; }
- for (var cc = c; cc <= cmax; cc++) {
- map[rr][cc] = new MapCell(cell);
- map[rr][cc].isColspan = (cspan && parseInt(cspan, 10) > 1);
- map[rr][cc].isRowspan = (rspan && parseInt(rspan, 10) > 1);
- map[rr][cc].firstCol = cc == c;
- map[rr][cc].lastCol = cc == cmax;
- map[rr][cc].firstRow = rr == r;
- map[rr][cc].lastRow = rr == rmax;
- map[rr][cc].isReal = cc == c && rr == r;
- map[rr][cc].spanCollection = spanCollect;
+ for (var rr = r; rr <= rmax; rr++) {
+ if (typeof map[rr] == "undefined") { map[rr] = []; }
+ for (var cc = c; cc <= cmax; cc++) {
+ map[rr][cc] = new MapCell(cell);
+ map[rr][cc].isColspan = (cspan && parseInt(cspan, 10) > 1);
+ map[rr][cc].isRowspan = (rspan && parseInt(rspan, 10) > 1);
+ map[rr][cc].firstCol = cc == c;
+ map[rr][cc].lastCol = cc == cmax;
+ map[rr][cc].firstRow = rr == r;
+ map[rr][cc].lastRow = rr == rmax;
+ map[rr][cc].isReal = cc == c && rr == r;
+ map[rr][cc].spanCollection = spanCollect;
- spanCollect.push(map[rr][cc]);
- }
- }
- },
+ spanCollect.push(map[rr][cc]);
+ }
+ }
+ },
- setCellAsModified: function(cell) {
- cell.modified = true;
- if (cell.spanCollection.length > 0) {
- for (var s = 0, smax = cell.spanCollection.length; s < smax; s++) {
- cell.spanCollection[s].modified = true;
- }
- }
- },
+ setCellAsModified: function(cell) {
+ cell.modified = true;
+ if (cell.spanCollection.length > 0) {
+ for (var s = 0, smax = cell.spanCollection.length; s < smax; s++) {
+ cell.spanCollection[s].modified = true;
+ }
+ }
+ },
- setTableMap: function() {
- var map = [];
- var tableRows = this.getTableRows(),
- ridx, row, cells, cidx, cell,
- c,
- cspan, rspan;
-
- for (ridx = 0; ridx < tableRows.length; ridx++) {
- row = tableRows[ridx];
- cells = this.getRowCells(row);
- c = 0;
- if (typeof map[ridx] == "undefined") { map[ridx] = []; }
- for (cidx = 0; cidx < cells.length; cidx++) {
- cell = cells[cidx];
-
- // If cell allready set means it is set by col or rowspan,
- // so increase cols index until free col is found
- while (typeof map[ridx][c] != "undefined") { c++; }
-
- cspan = api.getAttribute(cell, 'colspan');
- rspan = api.getAttribute(cell, 'rowspan');
-
- if (cspan || rspan) {
- this.addSpannedCellToMap(cell, map, ridx, c, cspan, rspan);
- c = c + ((cspan) ? parseInt(cspan, 10) : 1);
- } else {
- map[ridx][c] = new MapCell(cell);
- c++;
- }
- }
- }
- this.map = map;
- return map;
- },
+ setTableMap: function() {
+ var map = [];
+ var tableRows = this.getTableRows(),
+ ridx, row, cells, cidx, cell,
+ c,
+ cspan, rspan;
- getRowCells: function(row) {
- var inlineTables = this.table.querySelectorAll('table'),
- inlineCells = (inlineTables) ? queryInList(inlineTables, 'th, td') : [],
- allCells = row.querySelectorAll('th, td'),
- tableCells = (inlineCells.length > 0) ? wysihtml5.lang.array(allCells).without(inlineCells) : allCells;
+ for (ridx = 0; ridx < tableRows.length; ridx++) {
+ row = tableRows[ridx];
+ cells = this.getRowCells(row);
+ c = 0;
+ if (typeof map[ridx] == "undefined") { map[ridx] = []; }
+ for (cidx = 0; cidx < cells.length; cidx++) {
+ cell = cells[cidx];
- return tableCells;
- },
+ // If cell allready set means it is set by col or rowspan,
+ // so increase cols index until free col is found
+ while (typeof map[ridx][c] != "undefined") { c++; }
- getTableRows: function() {
- var inlineTables = this.table.querySelectorAll('table'),
- inlineRows = (inlineTables) ? queryInList(inlineTables, 'tr') : [],
- allRows = this.table.querySelectorAll('tr'),
- tableRows = (inlineRows.length > 0) ? wysihtml5.lang.array(allRows).without(inlineRows) : allRows;
+ cspan = api.getAttribute(cell, 'colspan');
+ rspan = api.getAttribute(cell, 'rowspan');
- return tableRows;
- },
+ if (cspan || rspan) {
+ this.addSpannedCellToMap(cell, map, ridx, c, cspan, rspan);
+ c = c + ((cspan) ? parseInt(cspan, 10) : 1);
+ } else {
+ map[ridx][c] = new MapCell(cell);
+ c++;
+ }
+ }
+ }
+ this.map = map;
+ return map;
+ },
- getMapIndex: function(cell) {
- var r_length = this.map.length,
- c_length = (this.map && this.map[0]) ? this.map[0].length : 0;
+ getRowCells: function(row) {
+ var inlineTables = this.table.querySelectorAll('table'),
+ inlineCells = (inlineTables) ? queryInList(inlineTables, 'th, td') : [],
+ allCells = row.querySelectorAll('th, td'),
+ tableCells = (inlineCells.length > 0) ? wysihtml5.lang.array(allCells).without(inlineCells) : allCells;
- for (var r_idx = 0;r_idx < r_length; r_idx++) {
- for (var c_idx = 0;c_idx < c_length; c_idx++) {
- if (this.map[r_idx][c_idx].el === cell) {
- return {'row': r_idx, 'col': c_idx};
- }
- }
- }
- return false;
- },
+ return tableCells;
+ },
- getElementAtIndex: function(idx) {
- this.setTableMap();
- if (this.map[idx.row] && this.map[idx.row][idx.col] && this.map[idx.row][idx.col].el) {
- return this.map[idx.row][idx.col].el;
- }
- return null;
- },
+ getTableRows: function() {
+ var inlineTables = this.table.querySelectorAll('table'),
+ inlineRows = (inlineTables) ? queryInList(inlineTables, 'tr') : [],
+ allRows = this.table.querySelectorAll('tr'),
+ tableRows = (inlineRows.length > 0) ? wysihtml5.lang.array(allRows).without(inlineRows) : allRows;
- getMapElsTo: function(to_cell) {
- var els = [];
- this.setTableMap();
- this.idx_start = this.getMapIndex(this.cell);
- this.idx_end = this.getMapIndex(to_cell);
+ return tableRows;
+ },
- // switch indexes if start is bigger than end
- if (this.idx_start.row > this.idx_end.row || (this.idx_start.row == this.idx_end.row && this.idx_start.col > this.idx_end.col)) {
- var temp_idx = this.idx_start;
- this.idx_start = this.idx_end;
- this.idx_end = temp_idx;
- }
- if (this.idx_start.col > this.idx_end.col) {
- var temp_cidx = this.idx_start.col;
- this.idx_start.col = this.idx_end.col;
- this.idx_end.col = temp_cidx;
- }
+ getMapIndex: function(cell) {
+ var r_length = this.map.length,
+ c_length = (this.map && this.map[0]) ? this.map[0].length : 0;
- if (this.idx_start != null && this.idx_end != null) {
- for (var row = this.idx_start.row, maxr = this.idx_end.row; row <= maxr; row++) {
- for (var col = this.idx_start.col, maxc = this.idx_end.col; col <= maxc; col++) {
- els.push(this.map[row][col].el);
- }
- }
- }
- return els;
- },
+ for (var r_idx = 0;r_idx < r_length; r_idx++) {
+ for (var c_idx = 0;c_idx < c_length; c_idx++) {
+ if (this.map[r_idx][c_idx].el === cell) {
+ return {'row': r_idx, 'col': c_idx};
+ }
+ }
+ }
+ return false;
+ },
- orderSelectionEnds: function(secondcell) {
- this.setTableMap();
- this.idx_start = this.getMapIndex(this.cell);
- this.idx_end = this.getMapIndex(secondcell);
+ getElementAtIndex: function(idx) {
+ this.setTableMap();
+ if (this.map[idx.row] && this.map[idx.row][idx.col] && this.map[idx.row][idx.col].el) {
+ return this.map[idx.row][idx.col].el;
+ }
+ return null;
+ },
- // switch indexes if start is bigger than end
- if (this.idx_start.row > this.idx_end.row || (this.idx_start.row == this.idx_end.row && this.idx_start.col > this.idx_end.col)) {
- var temp_idx = this.idx_start;
- this.idx_start = this.idx_end;
- this.idx_end = temp_idx;
- }
- if (this.idx_start.col > this.idx_end.col) {
- var temp_cidx = this.idx_start.col;
- this.idx_start.col = this.idx_end.col;
- this.idx_end.col = temp_cidx;
- }
+ getMapElsTo: function(to_cell) {
+ var els = [];
+ this.setTableMap();
+ this.idx_start = this.getMapIndex(this.cell);
+ this.idx_end = this.getMapIndex(to_cell);
- return {
- "start": this.map[this.idx_start.row][this.idx_start.col].el,
- "end": this.map[this.idx_end.row][this.idx_end.col].el
- };
- },
+ // switch indexes if start is bigger than end
+ if (this.idx_start.row > this.idx_end.row || (this.idx_start.row == this.idx_end.row && this.idx_start.col > this.idx_end.col)) {
+ var temp_idx = this.idx_start;
+ this.idx_start = this.idx_end;
+ this.idx_end = temp_idx;
+ }
+ if (this.idx_start.col > this.idx_end.col) {
+ var temp_cidx = this.idx_start.col;
+ this.idx_start.col = this.idx_end.col;
+ this.idx_end.col = temp_cidx;
+ }
- createCells: function(tag, nr, attrs) {
- var doc = this.table.ownerDocument,
- frag = doc.createDocumentFragment(),
- cell;
- for (var i = 0; i < nr; i++) {
- cell = doc.createElement(tag);
-
- if (attrs) {
- for (var attr in attrs) {
- if (attrs.hasOwnProperty(attr)) {
- cell.setAttribute(attr, attrs[attr]);
- }
- }
- }
+ if (this.idx_start != null && this.idx_end != null) {
+ for (var row = this.idx_start.row, maxr = this.idx_end.row; row <= maxr; row++) {
+ for (var col = this.idx_start.col, maxc = this.idx_end.col; col <= maxc; col++) {
+ els.push(this.map[row][col].el);
+ }
+ }
+ }
+ return els;
+ },
- // add non breaking space
- cell.appendChild(document.createTextNode("\u00a0"));
+ orderSelectionEnds: function(secondcell) {
+ this.setTableMap();
+ this.idx_start = this.getMapIndex(this.cell);
+ this.idx_end = this.getMapIndex(secondcell);
- frag.appendChild(cell);
- }
- return frag;
- },
+ // switch indexes if start is bigger than end
+ if (this.idx_start.row > this.idx_end.row || (this.idx_start.row == this.idx_end.row && this.idx_start.col > this.idx_end.col)) {
+ var temp_idx = this.idx_start;
+ this.idx_start = this.idx_end;
+ this.idx_end = temp_idx;
+ }
+ if (this.idx_start.col > this.idx_end.col) {
+ var temp_cidx = this.idx_start.col;
+ this.idx_start.col = this.idx_end.col;
+ this.idx_end.col = temp_cidx;
+ }
- // Returns next real cell (not part of spanned cell unless first) on row if selected index is not real. I no real cells -1 will be returned
- correctColIndexForUnreals: function(col, row) {
- var r = this.map[row],
- corrIdx = -1;
- for (var i = 0, max = col; i < col; i++) {
- if (r[i].isReal){
- corrIdx++;
- }
- }
- return corrIdx;
- },
+ return {
+ "start": this.map[this.idx_start.row][this.idx_start.col].el,
+ "end": this.map[this.idx_end.row][this.idx_end.col].el
+ };
+ },
- getLastNewCellOnRow: function(row, rowLimit) {
- var cells = this.getRowCells(row),
- cell, idx;
+ createCells: function(tag, nr, attrs) {
+ var doc = this.table.ownerDocument,
+ frag = doc.createDocumentFragment(),
+ cell;
+ for (var i = 0; i < nr; i++) {
+ cell = doc.createElement(tag);
- for (var cidx = 0, cmax = cells.length; cidx < cmax; cidx++) {
- cell = cells[cidx];
- idx = this.getMapIndex(cell);
- if (idx === false || (typeof rowLimit != "undefined" && idx.row != rowLimit)) {
- return cell;
- }
+ if (attrs) {
+ for (var attr in attrs) {
+ if (attrs.hasOwnProperty(attr)) {
+ cell.setAttribute(attr, attrs[attr]);
}
- return null;
- },
+ }
+ }
- removeEmptyTable: function() {
- var cells = this.table.querySelectorAll('td, th');
- if (!cells || cells.length == 0) {
- removeElement(this.table);
- return true;
- } else {
- return false;
- }
- },
+ // add non breaking space
+ cell.appendChild(document.createTextNode("\u00a0"));
+ frag.appendChild(cell);
+ }
+ return frag;
+ },
- // Splits merged cell on row to unique cells
- splitRowToCells: function(cell) {
- if (cell.isColspan) {
- var colspan = parseInt(api.getAttribute(cell.el, 'colspan') || 1, 10),
- cType = cell.el.tagName.toLowerCase();
- if (colspan > 1) {
- var newCells = this.createCells(cType, colspan -1);
- insertAfter(cell.el, newCells);
- }
- cell.el.removeAttribute('colspan');
- }
- },
+ // Returns next real cell (not part of spanned cell unless first) on row if selected index is not real. I no real cells -1 will be returned
+ correctColIndexForUnreals: function(col, row) {
+ var r = this.map[row],
+ corrIdx = -1;
+ for (var i = 0, max = col; i < col; i++) {
+ if (r[i].isReal){
+ corrIdx++;
+ }
+ }
+ return corrIdx;
+ },
- getRealRowEl: function(force, idx) {
- var r = null,
- c = null;
+ getLastNewCellOnRow: function(row, rowLimit) {
+ var cells = this.getRowCells(row),
+ cell, idx;
- idx = idx || this.idx;
+ for (var cidx = 0, cmax = cells.length; cidx < cmax; cidx++) {
+ cell = cells[cidx];
+ idx = this.getMapIndex(cell);
+ if (idx === false || (typeof rowLimit != "undefined" && idx.row != rowLimit)) {
+ return cell;
+ }
+ }
+ return null;
+ },
- for (var cidx = 0, cmax = this.map[idx.row].length; cidx < cmax; cidx++) {
- c = this.map[idx.row][cidx];
- if (c.isReal) {
- r = api.getParentElement(c.el, { query: "tr" });
- if (r) {
- return r;
- }
- }
- }
+ removeEmptyTable: function() {
+ var cells = this.table.querySelectorAll('td, th');
+ if (!cells || cells.length == 0) {
+ removeElement(this.table);
+ return true;
+ } else {
+ return false;
+ }
+ },
- if (r === null && force) {
- r = api.getParentElement(this.map[idx.row][idx.col].el, { query: "tr" }) || null;
- }
+ // Splits merged cell on row to unique cells
+ splitRowToCells: function(cell) {
+ if (cell.isColspan) {
+ var colspan = parseInt(api.getAttribute(cell.el, 'colspan') || 1, 10),
+ cType = cell.el.tagName.toLowerCase();
+ if (colspan > 1) {
+ var newCells = this.createCells(cType, colspan -1);
+ insertAfter(cell.el, newCells);
+ }
+ cell.el.removeAttribute('colspan');
+ }
+ },
+
+ getRealRowEl: function(force, idx) {
+ var r = null,
+ c = null;
+ idx = idx || this.idx;
+
+ for (var cidx = 0, cmax = this.map[idx.row].length; cidx < cmax; cidx++) {
+ c = this.map[idx.row][cidx];
+ if (c.isReal) {
+ r = api.getParentElement(c.el, { query: "tr" });
+ if (r) {
return r;
- },
+ }
+ }
+ }
- injectRowAt: function(row, col, colspan, cType, c) {
- var r = this.getRealRowEl(false, {'row': row, 'col': col}),
- new_cells = this.createCells(cType, colspan);
+ if (r === null && force) {
+ r = api.getParentElement(this.map[idx.row][idx.col].el, { query: "tr" }) || null;
+ }
- if (r) {
- var n_cidx = this.correctColIndexForUnreals(col, row);
- if (n_cidx >= 0) {
- insertAfter(this.getRowCells(r)[n_cidx], new_cells);
- } else {
- r.insertBefore(new_cells, r.firstChild);
- }
- } else {
- var rr = this.table.ownerDocument.createElement('tr');
- rr.appendChild(new_cells);
- insertAfter(api.getParentElement(c.el, { query: "tr" }), rr);
- }
- },
+ return r;
+ },
+
+ injectRowAt: function(row, col, colspan, cType, c) {
+ var r = this.getRealRowEl(false, {'row': row, 'col': col}),
+ new_cells = this.createCells(cType, colspan);
+
+ if (r) {
+ var n_cidx = this.correctColIndexForUnreals(col, row);
+ if (n_cidx >= 0) {
+ insertAfter(this.getRowCells(r)[n_cidx], new_cells);
+ } else {
+ r.insertBefore(new_cells, r.firstChild);
+ }
+ } else {
+ var rr = this.table.ownerDocument.createElement('tr');
+ rr.appendChild(new_cells);
+ insertAfter(api.getParentElement(c.el, { query: "tr" }), rr);
+ }
+ },
+
+ canMerge: function(to) {
+ this.to = to;
+ this.setTableMap();
+ this.idx_start = this.getMapIndex(this.cell);
+ this.idx_end = this.getMapIndex(this.to);
+
+ // switch indexes if start is bigger than end
+ if (this.idx_start.row > this.idx_end.row || (this.idx_start.row == this.idx_end.row && this.idx_start.col > this.idx_end.col)) {
+ var temp_idx = this.idx_start;
+ this.idx_start = this.idx_end;
+ this.idx_end = temp_idx;
+ }
+ if (this.idx_start.col > this.idx_end.col) {
+ var temp_cidx = this.idx_start.col;
+ this.idx_start.col = this.idx_end.col;
+ this.idx_end.col = temp_cidx;
+ }
- canMerge: function(to) {
- this.to = to;
- this.setTableMap();
- this.idx_start = this.getMapIndex(this.cell);
- this.idx_end = this.getMapIndex(this.to);
+ for (var row = this.idx_start.row, maxr = this.idx_end.row; row <= maxr; row++) {
+ for (var col = this.idx_start.col, maxc = this.idx_end.col; col <= maxc; col++) {
+ if (this.map[row][col].isColspan || this.map[row][col].isRowspan) {
+ return false;
+ }
+ }
+ }
+ return true;
+ },
- // switch indexes if start is bigger than end
- if (this.idx_start.row > this.idx_end.row || (this.idx_start.row == this.idx_end.row && this.idx_start.col > this.idx_end.col)) {
- var temp_idx = this.idx_start;
- this.idx_start = this.idx_end;
- this.idx_end = temp_idx;
+ decreaseCellSpan: function(cell, span) {
+ var nr = parseInt(api.getAttribute(cell.el, span), 10) - 1;
+ if (nr >= 1) {
+ cell.el.setAttribute(span, nr);
+ } else {
+ cell.el.removeAttribute(span);
+ if (span == 'colspan') {
+ cell.isColspan = false;
+ }
+ if (span == 'rowspan') {
+ cell.isRowspan = false;
+ }
+ cell.firstCol = true;
+ cell.lastCol = true;
+ cell.firstRow = true;
+ cell.lastRow = true;
+ cell.isReal = true;
+ }
+ },
+
+ removeSurplusLines: function() {
+ var row, cell, ridx, rmax, cidx, cmax, allRowspan;
+
+ this.setTableMap();
+ if (this.map) {
+ ridx = 0;
+ rmax = this.map.length;
+ for (;ridx < rmax; ridx++) {
+ row = this.map[ridx];
+ allRowspan = true;
+ cidx = 0;
+ cmax = row.length;
+ for (; cidx < cmax; cidx++) {
+ cell = row[cidx];
+ if (!(api.getAttribute(cell.el, "rowspan") && parseInt(api.getAttribute(cell.el, "rowspan"), 10) > 1 && cell.firstRow !== true)) {
+ allRowspan = false;
+ break;
}
- if (this.idx_start.col > this.idx_end.col) {
- var temp_cidx = this.idx_start.col;
- this.idx_start.col = this.idx_end.col;
- this.idx_end.col = temp_cidx;
+ }
+ if (allRowspan) {
+ cidx = 0;
+ for (; cidx < cmax; cidx++) {
+ this.decreaseCellSpan(row[cidx], 'rowspan');
}
+ }
+ }
- for (var row = this.idx_start.row, maxr = this.idx_end.row; row <= maxr; row++) {
- for (var col = this.idx_start.col, maxc = this.idx_end.col; col <= maxc; col++) {
- if (this.map[row][col].isColspan || this.map[row][col].isRowspan) {
- return false;
- }
- }
- }
- return true;
- },
+ // remove rows without cells
+ var tableRows = this.getTableRows();
+ ridx = 0;
+ rmax = tableRows.length;
+ for (;ridx < rmax; ridx++) {
+ row = tableRows[ridx];
+ if (row.childNodes.length == 0 && (/^\s*$/.test(row.textContent || row.innerText))) {
+ removeElement(row);
+ }
+ }
+ }
+ },
- decreaseCellSpan: function(cell, span) {
- var nr = parseInt(api.getAttribute(cell.el, span), 10) - 1;
- if (nr >= 1) {
- cell.el.setAttribute(span, nr);
- } else {
- cell.el.removeAttribute(span);
- if (span == 'colspan') {
- cell.isColspan = false;
- }
- if (span == 'rowspan') {
- cell.isRowspan = false;
- }
- cell.firstCol = true;
- cell.lastCol = true;
- cell.firstRow = true;
- cell.lastRow = true;
- cell.isReal = true;
- }
- },
+ fillMissingCells: function() {
+ var r_max = 0,
+ c_max = 0,
+ prevcell = null;
- removeSurplusLines: function() {
- var row, cell, ridx, rmax, cidx, cmax, allRowspan;
-
- this.setTableMap();
- if (this.map) {
- ridx = 0;
- rmax = this.map.length;
- for (;ridx < rmax; ridx++) {
- row = this.map[ridx];
- allRowspan = true;
- cidx = 0;
- cmax = row.length;
- for (; cidx < cmax; cidx++) {
- cell = row[cidx];
- if (!(api.getAttribute(cell.el, "rowspan") && parseInt(api.getAttribute(cell.el, "rowspan"), 10) > 1 && cell.firstRow !== true)) {
- allRowspan = false;
- break;
- }
- }
- if (allRowspan) {
- cidx = 0;
- for (; cidx < cmax; cidx++) {
- this.decreaseCellSpan(row[cidx], 'rowspan');
- }
- }
- }
+ this.setTableMap();
+ if (this.map) {
- // remove rows without cells
- var tableRows = this.getTableRows();
- ridx = 0;
- rmax = tableRows.length;
- for (;ridx < rmax; ridx++) {
- row = tableRows[ridx];
- if (row.childNodes.length == 0 && (/^\s*$/.test(row.textContent || row.innerText))) {
- removeElement(row);
- }
+ // find maximal dimensions of broken table
+ r_max = this.map.length;
+ for (var ridx = 0; ridx < r_max; ridx++) {
+ if (this.map[ridx].length > c_max) { c_max = this.map[ridx].length; }
+ }
+
+ for (var row = 0; row < r_max; row++) {
+ for (var col = 0; col < c_max; col++) {
+ if (this.map[row] && !this.map[row][col]) {
+ if (col > 0) {
+ this.map[row][col] = new MapCell(this.createCells('td', 1));
+ prevcell = this.map[row][col-1];
+ if (prevcell && prevcell.el && prevcell.el.parent) { // if parent does not exist element is removed from dom
+ insertAfter(this.map[row][col-1].el, this.map[row][col].el);
}
+ }
}
- },
+ }
+ }
+ }
+ },
- fillMissingCells: function() {
- var r_max = 0,
- c_max = 0,
- prevcell = null;
+ rectify: function() {
+ if (!this.removeEmptyTable()) {
+ this.removeSurplusLines();
+ this.fillMissingCells();
+ return true;
+ } else {
+ return false;
+ }
+ },
- this.setTableMap();
- if (this.map) {
+ unmerge: function() {
+ if (this.rectify()) {
+ this.setTableMap();
+ this.idx = this.getMapIndex(this.cell);
- // find maximal dimensions of broken table
- r_max = this.map.length;
- for (var ridx = 0; ridx < r_max; ridx++) {
- if (this.map[ridx].length > c_max) { c_max = this.map[ridx].length; }
- }
+ if (this.idx) {
+ var thisCell = this.map[this.idx.row][this.idx.col],
+ colspan = (api.getAttribute(thisCell.el, "colspan")) ? parseInt(api.getAttribute(thisCell.el, "colspan"), 10) : 1,
+ cType = thisCell.el.tagName.toLowerCase();
- for (var row = 0; row < r_max; row++) {
- for (var col = 0; col < c_max; col++) {
- if (this.map[row] && !this.map[row][col]) {
- if (col > 0) {
- this.map[row][col] = new MapCell(this.createCells('td', 1));
- prevcell = this.map[row][col-1];
- if (prevcell && prevcell.el && prevcell.el.parent) { // if parent does not exist element is removed from dom
- insertAfter(this.map[row][col-1].el, this.map[row][col].el);
- }
- }
- }
- }
- }
+ if (thisCell.isRowspan) {
+ var rowspan = parseInt(api.getAttribute(thisCell.el, "rowspan"), 10);
+ if (rowspan > 1) {
+ for (var nr = 1, maxr = rowspan - 1; nr <= maxr; nr++){
+ this.injectRowAt(this.idx.row + nr, this.idx.col, colspan, cType, thisCell);
+ }
}
- },
+ thisCell.el.removeAttribute('rowspan');
+ }
+ this.splitRowToCells(thisCell);
+ }
+ }
+ },
- rectify: function() {
- if (!this.removeEmptyTable()) {
- this.removeSurplusLines();
- this.fillMissingCells();
- return true;
- } else {
- return false;
- }
- },
+ // merges cells from start cell (defined in creating obj) to "to" cell
+ merge: function(to) {
+ if (this.rectify()) {
+ if (this.canMerge(to)) {
+ var rowspan = this.idx_end.row - this.idx_start.row + 1,
+ colspan = this.idx_end.col - this.idx_start.col + 1;
- unmerge: function() {
- if (this.rectify()) {
- this.setTableMap();
- this.idx = this.getMapIndex(this.cell);
-
- if (this.idx) {
- var thisCell = this.map[this.idx.row][this.idx.col],
- colspan = (api.getAttribute(thisCell.el, "colspan")) ? parseInt(api.getAttribute(thisCell.el, "colspan"), 10) : 1,
- cType = thisCell.el.tagName.toLowerCase();
-
- if (thisCell.isRowspan) {
- var rowspan = parseInt(api.getAttribute(thisCell.el, "rowspan"), 10);
- if (rowspan > 1) {
- for (var nr = 1, maxr = rowspan - 1; nr <= maxr; nr++){
- this.injectRowAt(this.idx.row + nr, this.idx.col, colspan, cType, thisCell);
- }
- }
- thisCell.el.removeAttribute('rowspan');
- }
- this.splitRowToCells(thisCell);
+ for (var row = this.idx_start.row, maxr = this.idx_end.row; row <= maxr; row++) {
+ for (var col = this.idx_start.col, maxc = this.idx_end.col; col <= maxc; col++) {
+
+ if (row == this.idx_start.row && col == this.idx_start.col) {
+ if (rowspan > 1) {
+ this.map[row][col].el.setAttribute('rowspan', rowspan);
+ }
+ if (colspan > 1) {
+ this.map[row][col].el.setAttribute('colspan', colspan);
}
+ } else {
+ // transfer content
+ if (!(/^\s*
\s*$/.test(this.map[row][col].el.innerHTML.toLowerCase()))) {
+ this.map[this.idx_start.row][this.idx_start.col].el.innerHTML += ' ' + this.map[row][col].el.innerHTML;
+ }
+ removeElement(this.map[row][col].el);
+ }
+
}
- },
+ }
+ this.rectify();
+ } else {
+ if (window.console) {
+ console.log('Do not know how to merge allready merged cells.');
+ }
+ }
+ }
+ },
- // merges cells from start cell (defined in creating obj) to "to" cell
- merge: function(to) {
- if (this.rectify()) {
- if (this.canMerge(to)) {
- var rowspan = this.idx_end.row - this.idx_start.row + 1,
- colspan = this.idx_end.col - this.idx_start.col + 1;
+ // Decreases rowspan of a cell if it is done on first cell of rowspan row (real cell)
+ // Cell is moved to next row (if it is real)
+ collapseCellToNextRow: function(cell) {
+ var cellIdx = this.getMapIndex(cell.el),
+ newRowIdx = cellIdx.row + 1,
+ newIdx = {'row': newRowIdx, 'col': cellIdx.col};
- for (var row = this.idx_start.row, maxr = this.idx_end.row; row <= maxr; row++) {
- for (var col = this.idx_start.col, maxc = this.idx_end.col; col <= maxc; col++) {
+ if (newRowIdx < this.map.length) {
- if (row == this.idx_start.row && col == this.idx_start.col) {
- if (rowspan > 1) {
- this.map[row][col].el.setAttribute('rowspan', rowspan);
- }
- if (colspan > 1) {
- this.map[row][col].el.setAttribute('colspan', colspan);
- }
- } else {
- // transfer content
- if (!(/^\s*
\s*$/.test(this.map[row][col].el.innerHTML.toLowerCase()))) {
- this.map[this.idx_start.row][this.idx_start.col].el.innerHTML += ' ' + this.map[row][col].el.innerHTML;
- }
- removeElement(this.map[row][col].el);
- }
- }
- }
- this.rectify();
- } else {
- if (window.console) {
- console.log('Do not know how to merge allready merged cells.');
- }
- }
+ var row = this.getRealRowEl(false, newIdx);
+ if (row !== null) {
+ var n_cidx = this.correctColIndexForUnreals(newIdx.col, newIdx.row);
+ if (n_cidx >= 0) {
+ insertAfter(this.getRowCells(row)[n_cidx], cell.el);
+ } else {
+ var lastCell = this.getLastNewCellOnRow(row, newRowIdx);
+ if (lastCell !== null) {
+ insertAfter(lastCell, cell.el);
+ } else {
+ row.insertBefore(cell.el, row.firstChild);
}
- },
+ }
+ if (parseInt(api.getAttribute(cell.el, 'rowspan'), 10) > 2) {
+ cell.el.setAttribute('rowspan', parseInt(api.getAttribute(cell.el, 'rowspan'), 10) - 1);
+ } else {
+ cell.el.removeAttribute('rowspan');
+ }
+ }
+ }
+ },
- // Decreases rowspan of a cell if it is done on first cell of rowspan row (real cell)
- // Cell is moved to next row (if it is real)
- collapseCellToNextRow: function(cell) {
- var cellIdx = this.getMapIndex(cell.el),
- newRowIdx = cellIdx.row + 1,
- newIdx = {'row': newRowIdx, 'col': cellIdx.col};
+ // Removes a cell when removing a row
+ // If is rowspan cell then decreases the rowspan
+ // and moves cell to next row if needed (is first cell of rowspan)
+ removeRowCell: function(cell) {
+ if (cell.isReal) {
+ if (cell.isRowspan) {
+ this.collapseCellToNextRow(cell);
+ } else {
+ removeElement(cell.el);
+ }
+ } else {
+ if (parseInt(api.getAttribute(cell.el, 'rowspan'), 10) > 2) {
+ cell.el.setAttribute('rowspan', parseInt(api.getAttribute(cell.el, 'rowspan'), 10) - 1);
+ } else {
+ cell.el.removeAttribute('rowspan');
+ }
+ }
+ },
- if (newRowIdx < this.map.length) {
+ getRowElementsByCell: function() {
+ var cells = [];
+ this.setTableMap();
+ this.idx = this.getMapIndex(this.cell);
+ if (this.idx !== false) {
+ var modRow = this.map[this.idx.row];
+ for (var cidx = 0, cmax = modRow.length; cidx < cmax; cidx++) {
+ if (modRow[cidx].isReal) {
+ cells.push(modRow[cidx].el);
+ }
+ }
+ }
+ return cells;
+ },
- var row = this.getRealRowEl(false, newIdx);
- if (row !== null) {
- var n_cidx = this.correctColIndexForUnreals(newIdx.col, newIdx.row);
- if (n_cidx >= 0) {
- insertAfter(this.getRowCells(row)[n_cidx], cell.el);
- } else {
- var lastCell = this.getLastNewCellOnRow(row, newRowIdx);
- if (lastCell !== null) {
- insertAfter(lastCell, cell.el);
- } else {
- row.insertBefore(cell.el, row.firstChild);
- }
- }
- if (parseInt(api.getAttribute(cell.el, 'rowspan'), 10) > 2) {
- cell.el.setAttribute('rowspan', parseInt(api.getAttribute(cell.el, 'rowspan'), 10) - 1);
- } else {
- cell.el.removeAttribute('rowspan');
- }
- }
- }
- },
+ getColumnElementsByCell: function() {
+ var cells = [];
+ this.setTableMap();
+ this.idx = this.getMapIndex(this.cell);
+ if (this.idx !== false) {
+ for (var ridx = 0, rmax = this.map.length; ridx < rmax; ridx++) {
+ if (this.map[ridx][this.idx.col] && this.map[ridx][this.idx.col].isReal) {
+ cells.push(this.map[ridx][this.idx.col].el);
+ }
+ }
+ }
+ return cells;
+ },
- // Removes a cell when removing a row
- // If is rowspan cell then decreases the rowspan
- // and moves cell to next row if needed (is first cell of rowspan)
- removeRowCell: function(cell) {
- if (cell.isReal) {
- if (cell.isRowspan) {
- this.collapseCellToNextRow(cell);
- } else {
- removeElement(cell.el);
- }
- } else {
- if (parseInt(api.getAttribute(cell.el, 'rowspan'), 10) > 2) {
- cell.el.setAttribute('rowspan', parseInt(api.getAttribute(cell.el, 'rowspan'), 10) - 1);
- } else {
- cell.el.removeAttribute('rowspan');
- }
+ // Removes the row of selected cell
+ removeRow: function() {
+ var oldRow = api.getParentElement(this.cell, { query: "tr" });
+ if (oldRow) {
+ this.setTableMap();
+ this.idx = this.getMapIndex(this.cell);
+ if (this.idx !== false) {
+ var modRow = this.map[this.idx.row];
+ for (var cidx = 0, cmax = modRow.length; cidx < cmax; cidx++) {
+ if (!modRow[cidx].modified) {
+ this.setCellAsModified(modRow[cidx]);
+ this.removeRowCell(modRow[cidx]);
}
- },
+ }
+ }
+ removeElement(oldRow);
+ }
+ },
- getRowElementsByCell: function() {
- var cells = [];
- this.setTableMap();
- this.idx = this.getMapIndex(this.cell);
- if (this.idx !== false) {
- var modRow = this.map[this.idx.row];
- for (var cidx = 0, cmax = modRow.length; cidx < cmax; cidx++) {
- if (modRow[cidx].isReal) {
- cells.push(modRow[cidx].el);
- }
- }
- }
- return cells;
- },
+ removeColCell: function(cell) {
+ if (cell.isColspan) {
+ if (parseInt(api.getAttribute(cell.el, 'colspan'), 10) > 2) {
+ cell.el.setAttribute('colspan', parseInt(api.getAttribute(cell.el, 'colspan'), 10) - 1);
+ } else {
+ cell.el.removeAttribute('colspan');
+ }
+ } else if (cell.isReal) {
+ removeElement(cell.el);
+ }
+ },
- getColumnElementsByCell: function() {
- var cells = [];
- this.setTableMap();
- this.idx = this.getMapIndex(this.cell);
- if (this.idx !== false) {
- for (var ridx = 0, rmax = this.map.length; ridx < rmax; ridx++) {
- if (this.map[ridx][this.idx.col] && this.map[ridx][this.idx.col].isReal) {
- cells.push(this.map[ridx][this.idx.col].el);
- }
- }
- }
- return cells;
- },
+ removeColumn: function() {
+ this.setTableMap();
+ this.idx = this.getMapIndex(this.cell);
+ if (this.idx !== false) {
+ for (var ridx = 0, rmax = this.map.length; ridx < rmax; ridx++) {
+ if (!this.map[ridx][this.idx.col].modified) {
+ this.setCellAsModified(this.map[ridx][this.idx.col]);
+ this.removeColCell(this.map[ridx][this.idx.col]);
+ }
+ }
+ }
+ },
- // Removes the row of selected cell
- removeRow: function() {
- var oldRow = api.getParentElement(this.cell, { query: "tr" });
- if (oldRow) {
- this.setTableMap();
- this.idx = this.getMapIndex(this.cell);
- if (this.idx !== false) {
- var modRow = this.map[this.idx.row];
- for (var cidx = 0, cmax = modRow.length; cidx < cmax; cidx++) {
- if (!modRow[cidx].modified) {
- this.setCellAsModified(modRow[cidx]);
- this.removeRowCell(modRow[cidx]);
- }
- }
- }
- removeElement(oldRow);
- }
- },
+ // removes row or column by selected cell element
+ remove: function(what) {
+ if (this.rectify()) {
+ switch (what) {
+ case 'row':
+ this.removeRow();
+ break;
+ case 'column':
+ this.removeColumn();
+ break;
+ }
+ this.rectify();
+ }
+ },
- removeColCell: function(cell) {
- if (cell.isColspan) {
- if (parseInt(api.getAttribute(cell.el, 'colspan'), 10) > 2) {
- cell.el.setAttribute('colspan', parseInt(api.getAttribute(cell.el, 'colspan'), 10) - 1);
- } else {
- cell.el.removeAttribute('colspan');
- }
- } else if (cell.isReal) {
- removeElement(cell.el);
- }
- },
+ addRow: function(where) {
+ var doc = this.table.ownerDocument;
- removeColumn: function() {
- this.setTableMap();
- this.idx = this.getMapIndex(this.cell);
- if (this.idx !== false) {
- for (var ridx = 0, rmax = this.map.length; ridx < rmax; ridx++) {
- if (!this.map[ridx][this.idx.col].modified) {
- this.setCellAsModified(this.map[ridx][this.idx.col]);
- this.removeColCell(this.map[ridx][this.idx.col]);
- }
- }
- }
- },
+ this.setTableMap();
+ this.idx = this.getMapIndex(this.cell);
+ if (where == "below" && api.getAttribute(this.cell, 'rowspan')) {
+ this.idx.row = this.idx.row + parseInt(api.getAttribute(this.cell, 'rowspan'), 10) - 1;
+ }
- // removes row or column by selected cell element
- remove: function(what) {
- if (this.rectify()) {
- switch (what) {
- case 'row':
- this.removeRow();
- break;
- case 'column':
- this.removeColumn();
- break;
- }
- this.rectify();
- }
- },
+ if (this.idx !== false) {
+ var modRow = this.map[this.idx.row],
+ newRow = doc.createElement('tr');
- addRow: function(where) {
- var doc = this.table.ownerDocument;
+ for (var ridx = 0, rmax = modRow.length; ridx < rmax; ridx++) {
+ if (!modRow[ridx].modified) {
+ this.setCellAsModified(modRow[ridx]);
+ this.addRowCell(modRow[ridx], newRow, where);
+ }
+ }
- this.setTableMap();
- this.idx = this.getMapIndex(this.cell);
- if (where == "below" && api.getAttribute(this.cell, 'rowspan')) {
- this.idx.row = this.idx.row + parseInt(api.getAttribute(this.cell, 'rowspan'), 10) - 1;
+ switch (where) {
+ case 'below':
+ insertAfter(this.getRealRowEl(true), newRow);
+ break;
+ case 'above':
+ var cr = api.getParentElement(this.map[this.idx.row][this.idx.col].el, { query: "tr" });
+ if (cr) {
+ cr.parentNode.insertBefore(newRow, cr);
}
+ break;
+ }
+ }
+ },
- if (this.idx !== false) {
- var modRow = this.map[this.idx.row],
- newRow = doc.createElement('tr');
-
- for (var ridx = 0, rmax = modRow.length; ridx < rmax; ridx++) {
- if (!modRow[ridx].modified) {
- this.setCellAsModified(modRow[ridx]);
- this.addRowCell(modRow[ridx], newRow, where);
- }
- }
-
- switch (where) {
- case 'below':
- insertAfter(this.getRealRowEl(true), newRow);
- break;
- case 'above':
- var cr = api.getParentElement(this.map[this.idx.row][this.idx.col].el, { query: "tr" });
- if (cr) {
- cr.parentNode.insertBefore(newRow, cr);
- }
- break;
- }
- }
- },
+ addRowCell: function(cell, row, where) {
+ var colSpanAttr = (cell.isColspan) ? {"colspan" : api.getAttribute(cell.el, 'colspan')} : null;
+ if (cell.isReal) {
+ if (where != 'above' && cell.isRowspan) {
+ cell.el.setAttribute('rowspan', parseInt(api.getAttribute(cell.el,'rowspan'), 10) + 1);
+ } else {
+ row.appendChild(this.createCells('td', 1, colSpanAttr));
+ }
+ } else {
+ if (where != 'above' && cell.isRowspan && cell.lastRow) {
+ row.appendChild(this.createCells('td', 1, colSpanAttr));
+ } else if (c.isRowspan) {
+ cell.el.attr('rowspan', parseInt(api.getAttribute(cell.el, 'rowspan'), 10) + 1);
+ }
+ }
+ },
- addRowCell: function(cell, row, where) {
- var colSpanAttr = (cell.isColspan) ? {"colspan" : api.getAttribute(cell.el, 'colspan')} : null;
- if (cell.isReal) {
- if (where != 'above' && cell.isRowspan) {
- cell.el.setAttribute('rowspan', parseInt(api.getAttribute(cell.el,'rowspan'), 10) + 1);
- } else {
- row.appendChild(this.createCells('td', 1, colSpanAttr));
- }
- } else {
- if (where != 'above' && cell.isRowspan && cell.lastRow) {
- row.appendChild(this.createCells('td', 1, colSpanAttr));
- } else if (c.isRowspan) {
- cell.el.attr('rowspan', parseInt(api.getAttribute(cell.el, 'rowspan'), 10) + 1);
- }
- }
- },
+ add: function(where) {
+ if (this.rectify()) {
+ if (where == 'below' || where == 'above') {
+ this.addRow(where);
+ }
+ if (where == 'before' || where == 'after') {
+ this.addColumn(where);
+ }
+ }
+ },
- add: function(where) {
- if (this.rectify()) {
- if (where == 'below' || where == 'above') {
- this.addRow(where);
- }
- if (where == 'before' || where == 'after') {
- this.addColumn(where);
- }
- }
- },
+ addColCell: function (cell, ridx, where) {
+ var doAdd,
+ cType = cell.el.tagName.toLowerCase();
- addColCell: function (cell, ridx, where) {
- var doAdd,
- cType = cell.el.tagName.toLowerCase();
+ // defines add cell vs expand cell conditions
+ // true means add
+ switch (where) {
+ case "before":
+ doAdd = (!cell.isColspan || cell.firstCol);
+ break;
+ case "after":
+ doAdd = (!cell.isColspan || cell.lastCol || (cell.isColspan && c.el == this.cell));
+ break;
+ }
- // defines add cell vs expand cell conditions
- // true means add
- switch (where) {
- case "before":
- doAdd = (!cell.isColspan || cell.firstCol);
- break;
- case "after":
- doAdd = (!cell.isColspan || cell.lastCol || (cell.isColspan && c.el == this.cell));
- break;
- }
+ if (doAdd){
+ // adds a cell before or after current cell element
+ switch (where) {
+ case "before":
+ cell.el.parentNode.insertBefore(this.createCells(cType, 1), cell.el);
+ break;
+ case "after":
+ insertAfter(cell.el, this.createCells(cType, 1));
+ break;
+ }
- if (doAdd){
- // adds a cell before or after current cell element
- switch (where) {
- case "before":
- cell.el.parentNode.insertBefore(this.createCells(cType, 1), cell.el);
- break;
- case "after":
- insertAfter(cell.el, this.createCells(cType, 1));
- break;
- }
+ // handles if cell has rowspan
+ if (cell.isRowspan) {
+ this.handleCellAddWithRowspan(cell, ridx+1, where);
+ }
- // handles if cell has rowspan
- if (cell.isRowspan) {
- this.handleCellAddWithRowspan(cell, ridx+1, where);
- }
+ } else {
+ // expands cell
+ cell.el.setAttribute('colspan', parseInt(api.getAttribute(cell.el, 'colspan'), 10) + 1);
+ }
+ },
- } else {
- // expands cell
- cell.el.setAttribute('colspan', parseInt(api.getAttribute(cell.el, 'colspan'), 10) + 1);
- }
- },
+ addColumn: function(where) {
+ var row, modCell;
- addColumn: function(where) {
- var row, modCell;
+ this.setTableMap();
+ this.idx = this.getMapIndex(this.cell);
+ if (where == "after" && api.getAttribute(this.cell, 'colspan')) {
+ this.idx.col = this.idx.col + parseInt(api.getAttribute(this.cell, 'colspan'), 10) - 1;
+ }
- this.setTableMap();
- this.idx = this.getMapIndex(this.cell);
- if (where == "after" && api.getAttribute(this.cell, 'colspan')) {
- this.idx.col = this.idx.col + parseInt(api.getAttribute(this.cell, 'colspan'), 10) - 1;
+ if (this.idx !== false) {
+ for (var ridx = 0, rmax = this.map.length; ridx < rmax; ridx++ ) {
+ row = this.map[ridx];
+ if (row[this.idx.col]) {
+ modCell = row[this.idx.col];
+ if (!modCell.modified) {
+ this.setCellAsModified(modCell);
+ this.addColCell(modCell, ridx , where);
}
+ }
+ }
+ }
+ },
- if (this.idx !== false) {
- for (var ridx = 0, rmax = this.map.length; ridx < rmax; ridx++ ) {
- row = this.map[ridx];
- if (row[this.idx.col]) {
- modCell = row[this.idx.col];
- if (!modCell.modified) {
- this.setCellAsModified(modCell);
- this.addColCell(modCell, ridx , where);
- }
- }
- }
- }
- },
+ handleCellAddWithRowspan: function (cell, ridx, where) {
+ var addRowsNr = parseInt(api.getAttribute(this.cell, 'rowspan'), 10) - 1,
+ crow = api.getParentElement(cell.el, { query: "tr" }),
+ cType = cell.el.tagName.toLowerCase(),
+ cidx, temp_r_cells,
+ doc = this.table.ownerDocument,
+ nrow;
- handleCellAddWithRowspan: function (cell, ridx, where) {
- var addRowsNr = parseInt(api.getAttribute(this.cell, 'rowspan'), 10) - 1,
- crow = api.getParentElement(cell.el, { query: "tr" }),
- cType = cell.el.tagName.toLowerCase(),
- cidx, temp_r_cells,
- doc = this.table.ownerDocument,
- nrow;
-
- for (var i = 0; i < addRowsNr; i++) {
- cidx = this.correctColIndexForUnreals(this.idx.col, (ridx + i));
- crow = nextNode(crow, 'tr');
- if (crow) {
- if (cidx > 0) {
- switch (where) {
- case "before":
- temp_r_cells = this.getRowCells(crow);
- if (cidx > 0 && this.map[ridx + i][this.idx.col].el != temp_r_cells[cidx] && cidx == temp_r_cells.length - 1) {
- insertAfter(temp_r_cells[cidx], this.createCells(cType, 1));
- } else {
- temp_r_cells[cidx].parentNode.insertBefore(this.createCells(cType, 1), temp_r_cells[cidx]);
- }
-
- break;
- case "after":
- insertAfter(this.getRowCells(crow)[cidx], this.createCells(cType, 1));
- break;
- }
- } else {
- crow.insertBefore(this.createCells(cType, 1), crow.firstChild);
- }
+ for (var i = 0; i < addRowsNr; i++) {
+ cidx = this.correctColIndexForUnreals(this.idx.col, (ridx + i));
+ crow = nextNode(crow, 'tr');
+ if (crow) {
+ if (cidx > 0) {
+ switch (where) {
+ case "before":
+ temp_r_cells = this.getRowCells(crow);
+ if (cidx > 0 && this.map[ridx + i][this.idx.col].el != temp_r_cells[cidx] && cidx == temp_r_cells.length - 1) {
+ insertAfter(temp_r_cells[cidx], this.createCells(cType, 1));
} else {
- nrow = doc.createElement('tr');
- nrow.appendChild(this.createCells(cType, 1));
- this.table.appendChild(nrow);
+ temp_r_cells[cidx].parentNode.insertBefore(this.createCells(cType, 1), temp_r_cells[cidx]);
}
+
+ break;
+ case "after":
+ insertAfter(this.getRowCells(crow)[cidx], this.createCells(cType, 1));
+ break;
}
+ } else {
+ crow.insertBefore(this.createCells(cType, 1), crow.firstChild);
+ }
+ } else {
+ nrow = doc.createElement('tr');
+ nrow.appendChild(this.createCells(cType, 1));
+ this.table.appendChild(nrow);
}
- };
-
- api.table = {
- getCellsBetween: function(cell1, cell2) {
- var c1 = new TableModifyerByCell(cell1);
- return c1.getMapElsTo(cell2);
- },
-
- addCells: function(cell, where) {
- var c = new TableModifyerByCell(cell);
- c.add(where);
- },
+ }
+ }
+ };
- removeCells: function(cell, what) {
- var c = new TableModifyerByCell(cell);
- c.remove(what);
- },
+ api.table = {
+ getCellsBetween: function(cell1, cell2) {
+ var c1 = new TableModifyerByCell(cell1);
+ return c1.getMapElsTo(cell2);
+ },
- mergeCellsBetween: function(cell1, cell2) {
- var c1 = new TableModifyerByCell(cell1);
- c1.merge(cell2);
- },
+ addCells: function(cell, where) {
+ var c = new TableModifyerByCell(cell);
+ c.add(where);
+ },
- unmergeCell: function(cell) {
- var c = new TableModifyerByCell(cell);
- c.unmerge();
- },
+ removeCells: function(cell, what) {
+ var c = new TableModifyerByCell(cell);
+ c.remove(what);
+ },
- orderSelectionEnds: function(cell, cell2) {
- var c = new TableModifyerByCell(cell);
- return c.orderSelectionEnds(cell2);
- },
+ mergeCellsBetween: function(cell1, cell2) {
+ var c1 = new TableModifyerByCell(cell1);
+ c1.merge(cell2);
+ },
- indexOf: function(cell) {
- var c = new TableModifyerByCell(cell);
- c.setTableMap();
- return c.getMapIndex(cell);
- },
+ unmergeCell: function(cell) {
+ var c = new TableModifyerByCell(cell);
+ c.unmerge();
+ },
- findCell: function(table, idx) {
- var c = new TableModifyerByCell(null, table);
- return c.getElementAtIndex(idx);
- },
+ orderSelectionEnds: function(cell, cell2) {
+ var c = new TableModifyerByCell(cell);
+ return c.orderSelectionEnds(cell2);
+ },
- findRowByCell: function(cell) {
- var c = new TableModifyerByCell(cell);
- return c.getRowElementsByCell();
- },
+ indexOf: function(cell) {
+ var c = new TableModifyerByCell(cell);
+ c.setTableMap();
+ return c.getMapIndex(cell);
+ },
- findColumnByCell: function(cell) {
- var c = new TableModifyerByCell(cell);
- return c.getColumnElementsByCell();
- },
+ findCell: function(table, idx) {
+ var c = new TableModifyerByCell(null, table);
+ return c.getElementAtIndex(idx);
+ },
- canMerge: function(cell1, cell2) {
- var c = new TableModifyerByCell(cell1);
- return c.canMerge(cell2);
- }
- };
+ findRowByCell: function(cell) {
+ var c = new TableModifyerByCell(cell);
+ return c.getRowElementsByCell();
+ },
+ findColumnByCell: function(cell) {
+ var c = new TableModifyerByCell(cell);
+ return c.getColumnElementsByCell();
+ },
+ canMerge: function(cell1, cell2) {
+ var c = new TableModifyerByCell(cell1);
+ return c.canMerge(cell2);
+ }
+ };
})(wysihtml5);
;// does a selector query on element or array of elements
-
wysihtml5.dom.query = function(elements, query) {
var ret = [],
q;
@@ -8795,7 +8788,8 @@ wysihtml5.dom.unwrap = function(node) {
node.parentNode.removeChild(node);
}
return children;
-};;/*
+};
+;/*
* Methods for fetching pasted html before it gets inserted into content
**/
@@ -8819,28 +8813,40 @@ wysihtml5.dom.getPastedHtml = function(event) {
wysihtml5.dom.getPastedHtmlWithDiv = function (composer, f) {
var selBookmark = composer.selection.getBookmark(),
doc = composer.element.ownerDocument,
- cleanerDiv = doc.createElement('DIV');
+ cleanerDiv = doc.createElement('DIV'),
+ scrollPos = composer.getScrollPos();
doc.body.appendChild(cleanerDiv);
cleanerDiv.style.width = "1px";
cleanerDiv.style.height = "1px";
cleanerDiv.style.overflow = "hidden";
+ cleanerDiv.style.position = "absolute";
+ cleanerDiv.style.top = scrollPos.y + "px";
+ cleanerDiv.style.left = scrollPos.x + "px";
cleanerDiv.setAttribute('contenteditable', 'true');
cleanerDiv.focus();
setTimeout(function () {
+ var html;
+
composer.selection.setBookmark(selBookmark);
- f(cleanerDiv.innerHTML);
+ html = cleanerDiv.innerHTML;
+ if (html && (/^
$/i).test(html.trim())) {
+ html = false;
+ }
+ f(html);
cleanerDiv.parentNode.removeChild(cleanerDiv);
}, 0);
-};;wysihtml5.dom.removeInvisibleSpaces = function(node) {
+};
+;wysihtml5.dom.removeInvisibleSpaces = function(node) {
var textNodes = wysihtml5.dom.getTextNodes(node);
for (var n = textNodes.length; n--;) {
textNodes[n].nodeValue = textNodes[n].nodeValue.replace(wysihtml5.INVISIBLE_SPACE_REG_EXP, "");
}
-};;/**
+};
+;/**
* Fix most common html formatting misbehaviors of browsers implementation when inserting
* content via copy & paste contentEditable
*
@@ -8916,7 +8922,8 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
return newHtml;
};
-})();;/**
+})();
+;/**
* IE and Opera leave an empty paragraph in the contentEditable element after clearing it
*
* @param {Object} contentEditableElement The contentEditable element to observe for clearing events
@@ -8994,119 +9001,119 @@ wysihtml5.quirks.ensureProperClearing = (function() {
})(wysihtml5);
;wysihtml5.quirks.tableCellsSelection = function(editable, editor) {
- var dom = wysihtml5.dom,
- select = {
- table: null,
- start: null,
- end: null,
- cells: null,
- select: selectCells
- },
- selection_class = "wysiwyg-tmp-selected-cell";
+ var dom = wysihtml5.dom,
+ select = {
+ table: null,
+ start: null,
+ end: null,
+ cells: null,
+ select: selectCells
+ },
+ selection_class = "wysiwyg-tmp-selected-cell";
+
+ function init () {
+ editable.addEventListener("mousedown", handleMouseDown);
+ return select;
+ }
- function init () {
- editable.addEventListener("mousedown", handleMouseDown);
- return select;
+ var handleMouseDown = function(event) {
+ var target = wysihtml5.dom.getParentElement(event.target, { query: "td, th" });
+ if (target) {
+ handleSelectionMousedown(target);
}
+ };
- var handleMouseDown = function(event) {
- var target = wysihtml5.dom.getParentElement(event.target, { query: "td, th" });
- if (target) {
- handleSelectionMousedown(target);
- }
- };
-
- function handleSelectionMousedown (target) {
- select.start = target;
- select.end = target;
- select.cells = [target];
- select.table = dom.getParentElement(select.start, { query: "table" });
+ function handleSelectionMousedown (target) {
+ select.start = target;
+ select.end = target;
+ select.cells = [target];
+ select.table = dom.getParentElement(select.start, { query: "table" });
- if (select.table) {
- removeCellSelections();
- dom.addClass(target, selection_class);
- editable.addEventListener("mousemove", handleMouseMove);
- editable.addEventListener("mouseup", handleMouseUp);
- editor.fire("tableselectstart").fire("tableselectstart:composer");
- }
+ if (select.table) {
+ removeCellSelections();
+ dom.addClass(target, selection_class);
+ editable.addEventListener("mousemove", handleMouseMove);
+ editable.addEventListener("mouseup", handleMouseUp);
+ editor.fire("tableselectstart").fire("tableselectstart:composer");
}
+ }
- // remove all selection classes
- function removeCellSelections () {
- if (editable) {
- var selectedCells = editable.querySelectorAll('.' + selection_class);
- if (selectedCells.length > 0) {
- for (var i = 0; i < selectedCells.length; i++) {
- dom.removeClass(selectedCells[i], selection_class);
- }
- }
+ // remove all selection classes
+ function removeCellSelections () {
+ if (editable) {
+ var selectedCells = editable.querySelectorAll('.' + selection_class);
+ if (selectedCells.length > 0) {
+ for (var i = 0; i < selectedCells.length; i++) {
+ dom.removeClass(selectedCells[i], selection_class);
}
+ }
}
+ }
- function addSelections (cells) {
- for (var i = 0; i < cells.length; i++) {
- dom.addClass(cells[i], selection_class);
- }
+ function addSelections (cells) {
+ for (var i = 0; i < cells.length; i++) {
+ dom.addClass(cells[i], selection_class);
}
+ }
- function handleMouseMove (event) {
- var curTable = null,
- cell = dom.getParentElement(event.target, { query: "td, th" }),
- oldEnd;
+ function handleMouseMove (event) {
+ var curTable = null,
+ cell = dom.getParentElement(event.target, { query: "td, th" }),
+ oldEnd;
- if (cell && select.table && select.start) {
- curTable = dom.getParentElement(cell, { query: "table" });
- if (curTable && curTable === select.table) {
- removeCellSelections();
- oldEnd = select.end;
- select.end = cell;
- select.cells = dom.table.getCellsBetween(select.start, cell);
- if (select.cells.length > 1) {
- editor.composer.selection.deselect();
- }
- addSelections(select.cells);
- if (select.end !== oldEnd) {
- editor.fire("tableselectchange").fire("tableselectchange:composer");
- }
+ if (cell && select.table && select.start) {
+ curTable = dom.getParentElement(cell, { query: "table" });
+ if (curTable && curTable === select.table) {
+ removeCellSelections();
+ oldEnd = select.end;
+ select.end = cell;
+ select.cells = dom.table.getCellsBetween(select.start, cell);
+ if (select.cells.length > 1) {
+ editor.composer.selection.deselect();
+ }
+ addSelections(select.cells);
+ if (select.end !== oldEnd) {
+ editor.fire("tableselectchange").fire("tableselectchange:composer");
}
}
}
+ }
- function handleMouseUp (event) {
- editable.removeEventListener("mousemove", handleMouseMove);
- editable.removeEventListener("mouseup", handleMouseUp);
- editor.fire("tableselect").fire("tableselect:composer");
- setTimeout(function() {
- bindSideclick();
- },0);
- }
-
- var sideClickHandler = function(event) {
- editable.ownerDocument.removeEventListener("click", sideClickHandler);
- if (dom.getParentElement(event.target, { query: "table" }) != select.table) {
- removeCellSelections();
- select.table = null;
- select.start = null;
- select.end = null;
- editor.fire("tableunselect").fire("tableunselect:composer");
- }
- };
+ function handleMouseUp (event) {
+ editable.removeEventListener("mousemove", handleMouseMove);
+ editable.removeEventListener("mouseup", handleMouseUp);
+ editor.fire("tableselect").fire("tableselect:composer");
+ setTimeout(function() {
+ bindSideclick();
+ },0);
+ }
- function bindSideclick () {
- editable.ownerDocument.addEventListener("click", sideClickHandler);
+ var sideClickHandler = function(event) {
+ editable.ownerDocument.removeEventListener("click", sideClickHandler);
+ if (dom.getParentElement(event.target, { query: "table" }) != select.table) {
+ removeCellSelections();
+ select.table = null;
+ select.start = null;
+ select.end = null;
+ editor.fire("tableunselect").fire("tableunselect:composer");
}
+ };
- function selectCells (start, end) {
- select.start = start;
- select.end = end;
- select.table = dom.getParentElement(select.start, { query: "table" });
- selectedCells = dom.table.getCellsBetween(select.start, select.end);
- addSelections(selectedCells);
- bindSideclick();
- editor.fire("tableselect").fire("tableselect:composer");
- }
+ function bindSideclick () {
+ editable.ownerDocument.addEventListener("click", sideClickHandler);
+ }
+
+ function selectCells (start, end) {
+ select.start = start;
+ select.end = end;
+ select.table = dom.getParentElement(select.start, { query: "table" });
+ selectedCells = dom.table.getCellsBetween(select.start, select.end);
+ addSelections(selectedCells);
+ bindSideclick();
+ editor.fire("tableselect").fire("tableselect:composer");
+ }
- return init();
+ return init();
};
;(function(wysihtml5) {
@@ -9257,6 +9264,7 @@ wysihtml5.quirks.ensureProperClearing = (function() {
this.editor = editor;
this.composer = editor.composer;
this.doc = this.composer.doc;
+ this.win = this.composer.win;
this.contain = contain;
this.unselectableClass = unselectableClass || false;
},
@@ -9370,38 +9378,55 @@ wysihtml5.quirks.ensureProperClearing = (function() {
* @param {Object} node The element or text node where to position the caret in front of
* @example
* selection.setBefore(myElement);
+ * callback is an optional parameter accepting a function to execute when selection ahs been set
*/
- setAfter: function(node, notVisual) {
+ setAfter: function(node, notVisual, callback) {
var range = rangy.createRange(this.doc),
- originalScrollTop = this.doc.documentElement.scrollTop || this.doc.body.scrollTop || this.doc.defaultView.pageYOffset,
- originalScrollLeft = this.doc.documentElement.scrollLeft || this.doc.body.scrollLeft || this.doc.defaultView.pageXOffset,
+ fixWebkitSelection = function() {
+ // Webkit fails to add selection if there are no textnodes in that region
+ // (like an uneditable container at the end of content).
+ if (!sel) {
+ if (notVisual) {
+ // If setAfter is used as internal between actions, self-removing caretPlaceholder has simpler implementation
+ // and remove itself in call stack end instead on user interaction
+ var caretPlaceholder = this.doc.createTextNode(wysihtml5.INVISIBLE_SPACE);
+ node.parentNode.insertBefore(caretPlaceholder, node.nextSibling);
+ this.selectNode(caretPlaceholder);
+ setTimeout(function() {
+ if (caretPlaceholder && caretPlaceholder.parentNode) {
+ caretPlaceholder.parentNode.removeChild(caretPlaceholder);
+ }
+ }, 0);
+ } else {
+ this.createTemporaryCaretSpaceAfter(node);
+ }
+ }
+ },
sel;
range.setStartAfter(node);
range.setEndAfter(node);
- this.composer.element.focus();
- this.doc.defaultView.scrollTo(originalScrollLeft, originalScrollTop);
- sel = this.setSelection(range);
- // Webkit fails to add selection if there are no textnodes in that region
- // (like an uneditable container at the end of content).
- if (!sel) {
- if (notVisual) {
- // If setAfter is used as internal between actions, self-removing caretPlaceholder has simpler implementation
- // and remove itself in call stack end instead on user interaction
- var caretPlaceholder = this.doc.createTextNode(wysihtml5.INVISIBLE_SPACE);
- node.parentNode.insertBefore(caretPlaceholder, node.nextSibling);
- this.selectNode(caretPlaceholder);
- setTimeout(function() {
- if (caretPlaceholder && caretPlaceholder.parentNode) {
- caretPlaceholder.parentNode.removeChild(caretPlaceholder);
- }
- }, 0);
- } else {
- this.createTemporaryCaretSpaceAfter(node);
+ // In IE contenteditable must be focused before we can set selection
+ // thus setting the focus if activeElement is not this composer
+ if (!document.activeElement || document.activeElement !== this.composer.element) {
+ var scrollPos = this.composer.getScrollPos();
+ this.composer.element.focus();
+ this.composer.setScrollPos(scrollPos);
+ setTimeout(function() {
+ sel = this.setSelection(range);
+ fixWebkitSelection();
+ if (callback) {
+ callback(sel);
+ }
+ }.bind(this), 0);
+ } else {
+ sel = this.setSelection(range);
+ fixWebkitSelection();
+ if (callback) {
+ callback(sel);
}
}
- return sel;
},
/**
@@ -9704,9 +9729,7 @@ wysihtml5.quirks.ensureProperClearing = (function() {
// TODO: Figure out a method from following 2 that would work universally
executeAndRestoreRangy: function(method, restoreScrollPosition) {
- var win = this.doc.defaultView || this.doc.parentWindow,
- sel = rangy.saveSelection(win);
-
+ var sel = rangy.saveSelection(this.win);
if (!sel) {
method();
} else {
@@ -9988,8 +10011,7 @@ wysihtml5.quirks.ensureProperClearing = (function() {
* See https://developer.mozilla.org/en/DOM/Selection/modify
*/
_selectLine_W3C: function() {
- var win = this.doc.defaultView,
- selection = win.getSelection();
+ var selection = this.win.getSelection();
selection.modify("move", "left", "lineboundary");
selection.modify("extend", "right", "lineboundary");
},
@@ -9998,8 +10020,7 @@ wysihtml5.quirks.ensureProperClearing = (function() {
toLineBoundary: function (location, collapse) {
collapse = (typeof collapse === 'undefined') ? false : collapse;
if (wysihtml5.browser.supportsSelectionModify()) {
- var win = this.doc.defaultView,
- selection = win.getSelection();
+ var selection = this.win.getSelection();
selection.modify("extend", location, "lineboundary");
if (collapse) {
@@ -10139,50 +10160,49 @@ wysihtml5.quirks.ensureProperClearing = (function() {
if (r) { ranges.push(r); }
if (this.unselectableClass && this.contain && r) {
- var uneditables = this.getOwnUneditables(),
- tmpRange;
- if (uneditables.length > 0) {
- for (var i = 0, imax = uneditables.length; i < imax; i++) {
- tmpRanges = [];
- for (var j = 0, jmax = ranges.length; j < jmax; j++) {
- if (ranges[j]) {
- switch (ranges[j].compareNode(uneditables[i])) {
- case 2:
- // all selection inside uneditable. remove
- break;
- case 3:
- //section begins before and ends after uneditable. spilt
- tmpRange = ranges[j].cloneRange();
- tmpRange.setEndBefore(uneditables[i]);
- tmpRanges.push(tmpRange);
-
- tmpRange = ranges[j].cloneRange();
- tmpRange.setStartAfter(uneditables[i]);
- tmpRanges.push(tmpRange);
- break;
- default:
- // in all other cases uneditable does not touch selection. dont modify
- tmpRanges.push(ranges[j]);
- }
+ var uneditables = this.getOwnUneditables(),
+ tmpRange;
+ if (uneditables.length > 0) {
+ for (var i = 0, imax = uneditables.length; i < imax; i++) {
+ tmpRanges = [];
+ for (var j = 0, jmax = ranges.length; j < jmax; j++) {
+ if (ranges[j]) {
+ switch (ranges[j].compareNode(uneditables[i])) {
+ case 2:
+ // all selection inside uneditable. remove
+ break;
+ case 3:
+ //section begins before and ends after uneditable. spilt
+ tmpRange = ranges[j].cloneRange();
+ tmpRange.setEndBefore(uneditables[i]);
+ tmpRanges.push(tmpRange);
+
+ tmpRange = ranges[j].cloneRange();
+ tmpRange.setStartAfter(uneditables[i]);
+ tmpRanges.push(tmpRange);
+ break;
+ default:
+ // in all other cases uneditable does not touch selection. dont modify
+ tmpRanges.push(ranges[j]);
}
- ranges = tmpRanges;
}
+ ranges = tmpRanges;
}
}
+ }
}
return ranges;
},
getSelection: function() {
- return rangy.getSelection(this.doc.defaultView || this.doc.parentWindow);
+ return rangy.getSelection(this.win);
},
// Sets selection in document to a given range
// Set selection method detects if it fails to set any selection in document and returns null on fail
// (especially needed in webkit where some ranges just can not create selection for no reason)
setSelection: function(range) {
- var win = this.doc.defaultView || this.doc.parentWindow,
- selection = rangy.getSelection(win);
+ var selection = rangy.getSelection(this.win);
selection.setSingleRange(range);
return (selection && selection.anchorNode && selection.focusNode) ? selection : null;
},
@@ -10620,24 +10640,24 @@ wysihtml5.quirks.ensureProperClearing = (function() {
},
getAdjacentMergeableTextNode: function(node, forward) {
- var isTextNode = (node.nodeType == wysihtml5.TEXT_NODE);
- var el = isTextNode ? node.parentNode : node;
- var adjacentNode;
- var propName = forward ? "nextSibling" : "previousSibling";
- if (isTextNode) {
- // Can merge if the node's previous/next sibling is a text node
- adjacentNode = node[propName];
- if (adjacentNode && adjacentNode.nodeType == wysihtml5.TEXT_NODE) {
- return adjacentNode;
- }
- } else {
- // Compare element with its sibling
- adjacentNode = el[propName];
- if (adjacentNode && this.areElementsMergeable(node, adjacentNode)) {
- return adjacentNode[forward ? "firstChild" : "lastChild"];
- }
+ var isTextNode = (node.nodeType == wysihtml5.TEXT_NODE);
+ var el = isTextNode ? node.parentNode : node;
+ var adjacentNode;
+ var propName = forward ? "nextSibling" : "previousSibling";
+ if (isTextNode) {
+ // Can merge if the node's previous/next sibling is a text node
+ adjacentNode = node[propName];
+ if (adjacentNode && adjacentNode.nodeType == wysihtml5.TEXT_NODE) {
+ return adjacentNode;
}
- return null;
+ } else {
+ // Compare element with its sibling
+ adjacentNode = el[propName];
+ if (adjacentNode && this.areElementsMergeable(node, adjacentNode)) {
+ return adjacentNode[forward ? "firstChild" : "lastChild"];
+ }
+ }
+ return null;
},
areElementsMergeable: function(el1, el2) {
@@ -10715,83 +10735,83 @@ wysihtml5.quirks.ensureProperClearing = (function() {
},
applyToRange: function(range) {
- var textNodes;
- for (var ri = range.length; ri--;) {
- textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);
-
- if (!textNodes.length) {
- try {
- var node = this.createContainer(range[ri].endContainer.ownerDocument);
- range[ri].surroundContents(node);
- this.selectNode(range[ri], node);
- return;
- } catch(e) {}
- }
-
- range[ri].splitBoundaries();
- textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);
- if (textNodes.length) {
- var textNode;
+ var textNodes;
+ for (var ri = range.length; ri--;) {
+ textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);
- for (var i = 0, len = textNodes.length; i < len; ++i) {
- textNode = textNodes[i];
- if (!this.getMatchingAncestor(textNode).element) {
- this.applyToTextNode(textNode);
- }
- }
+ if (!textNodes.length) {
+ try {
+ var node = this.createContainer(range[ri].endContainer.ownerDocument);
+ range[ri].surroundContents(node);
+ this.selectNode(range[ri], node);
+ return;
+ } catch(e) {}
+ }
- range[ri].setStart(textNodes[0], 0);
- textNode = textNodes[textNodes.length - 1];
- range[ri].setEnd(textNode, textNode.length);
+ range[ri].splitBoundaries();
+ textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);
+ if (textNodes.length) {
+ var textNode;
- if (this.normalize) {
- this.postApply(textNodes, range[ri]);
- }
+ for (var i = 0, len = textNodes.length; i < len; ++i) {
+ textNode = textNodes[i];
+ if (!this.getMatchingAncestor(textNode).element) {
+ this.applyToTextNode(textNode);
}
+ }
+
+ range[ri].setStart(textNodes[0], 0);
+ textNode = textNodes[textNodes.length - 1];
+ range[ri].setEnd(textNode, textNode.length);
+ if (this.normalize) {
+ this.postApply(textNodes, range[ri]);
+ }
}
+
+ }
},
undoToRange: function(range) {
var textNodes, textNode, ancestorWithClass, ancestorWithStyle, ancestor;
for (var ri = range.length; ri--;) {
+ textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);
+ if (textNodes.length) {
+ range[ri].splitBoundaries();
textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);
- if (textNodes.length) {
- range[ri].splitBoundaries();
- textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);
- } else {
- var doc = range[ri].endContainer.ownerDocument,
- node = doc.createTextNode(wysihtml5.INVISIBLE_SPACE);
- range[ri].insertNode(node);
- range[ri].selectNode(node);
- textNodes = [node];
- }
+ } else {
+ var doc = range[ri].endContainer.ownerDocument,
+ node = doc.createTextNode(wysihtml5.INVISIBLE_SPACE);
+ range[ri].insertNode(node);
+ range[ri].selectNode(node);
+ textNodes = [node];
+ }
- for (var i = 0, len = textNodes.length; i < len; ++i) {
- if (range[ri].isValid()) {
- textNode = textNodes[i];
-
- ancestor = this.getMatchingAncestor(textNode);
- if (ancestor.type === "style") {
- this.undoToTextNode(textNode, range[ri], false, ancestor.element);
- } else if (ancestor.element) {
- this.undoToTextNode(textNode, range[ri], ancestor.element);
- }
+ for (var i = 0, len = textNodes.length; i < len; ++i) {
+ if (range[ri].isValid()) {
+ textNode = textNodes[i];
+
+ ancestor = this.getMatchingAncestor(textNode);
+ if (ancestor.type === "style") {
+ this.undoToTextNode(textNode, range[ri], false, ancestor.element);
+ } else if (ancestor.element) {
+ this.undoToTextNode(textNode, range[ri], ancestor.element);
}
}
+ }
- if (len == 1) {
- this.selectNode(range[ri], textNodes[0]);
- } else {
- range[ri].setStart(textNodes[0], 0);
- textNode = textNodes[textNodes.length - 1];
- range[ri].setEnd(textNode, textNode.length);
+ if (len == 1) {
+ this.selectNode(range[ri], textNodes[0]);
+ } else {
+ range[ri].setStart(textNodes[0], 0);
+ textNode = textNodes[textNodes.length - 1];
+ range[ri].setEnd(textNode, textNode.length);
- if (this.normalize) {
- this.postApply(textNodes, range[ri]);
- }
+ if (this.normalize) {
+ this.postApply(textNodes, range[ri]);
}
+ }
}
},
@@ -10998,21 +11018,22 @@ wysihtml5.Commands = Base.extend(
}
}
});
-;wysihtml5.commands.bold = {
- exec: function(composer, command) {
- wysihtml5.commands.formatInline.execWithToggle(composer, command, "b");
- },
-
- state: function(composer, command) {
- // element.ownerDocument.queryCommandState("bold") results:
- // firefox: only
- // chrome: , , , , ...
- // ie: ,
- // opera: ,
- return wysihtml5.commands.formatInline.state(composer, command, "b");
- }
-};
+;(function(wysihtml5){
+ wysihtml5.commands.bold = {
+ exec: function(composer, command) {
+ wysihtml5.commands.formatInline.execWithToggle(composer, command, "b");
+ },
+ state: function(composer, command) {
+ // element.ownerDocument.queryCommandState("bold") results:
+ // firefox: only
+ // chrome: , , , , ...
+ // ie: ,
+ // opera: ,
+ return wysihtml5.commands.formatInline.state(composer, command, "b");
+ }
+ };
+}(wysihtml5));
;(function(wysihtml5) {
var undef,
NODE_NAME = "A",
@@ -11185,7 +11206,7 @@ wysihtml5.Commands = Base.extend(
wysihtml5.commands.fontSize = {
exec: function(composer, command, size) {
- wysihtml5.commands.formatInline.execWithToggle(composer, command, "span", "wysiwyg-font-size-" + size, REG_EXP);
+ wysihtml5.commands.formatInline.execWithToggle(composer, command, "span", "wysiwyg-font-size-" + size, REG_EXP);
},
state: function(composer, command, size) {
@@ -11237,7 +11258,7 @@ wysihtml5.Commands = Base.extend(
wysihtml5.commands.foreColor = {
exec: function(composer, command, color) {
- wysihtml5.commands.formatInline.execWithToggle(composer, command, "span", "wysiwyg-color-" + color, REG_EXP);
+ wysihtml5.commands.formatInline.execWithToggle(composer, command, "span", "wysiwyg-color-" + color, REG_EXP);
},
state: function(composer, command, color) {
@@ -11624,7 +11645,7 @@ wysihtml5.Commands = Base.extend(
if (options && options.toggle) {
state = this.state(composer, command, options);
if (state) {
- bookmark = rangy.saveSelection(composer.doc.defaultView || composer.doc.parentWindow);
+ bookmark = rangy.saveSelection(composer.win);
for (var j in state) {
removeOptionsFromElement(state[j], options, composer);
}
@@ -11639,12 +11660,12 @@ wysihtml5.Commands = Base.extend(
query: BLOCK_ELEMENTS
}, null, composer.element);
if (parent) {
- bookmark = rangy.saveSelection(composer.doc.defaultView || composer.doc.parentWindow);
+ bookmark = rangy.saveSelection(composer.win);
range = composer.selection.createRange();
range.selectNode(parent);
composer.selection.setSelection(range);
} else if (!composer.isEmpty()) {
- bookmark = rangy.saveSelection(composer.doc.defaultView || composer.doc.parentWindow);
+ bookmark = rangy.saveSelection(composer.win);
composer.selection.selectLine();
}
}
@@ -11700,7 +11721,6 @@ wysihtml5.Commands = Base.extend(
return (nodes.length === 0) ? false : nodes;
}
-
};
})(wysihtml5);
;/* Formats block for as a
block
@@ -11711,48 +11731,51 @@ wysihtml5.Commands = Base.extend(
* editorInstance.composer.commands.exec("formatCode", "language-html");
*/
-wysihtml5.commands.formatCode = {
+(function(wysihtml5){
+ wysihtml5.commands.formatCode = {
+
+ exec: function(composer, command, classname) {
+ var pre = this.state(composer),
+ code, range, selectedNodes;
+ if (pre) {
+ // caret is already within a ...
+ composer.selection.executeAndRestore(function() {
+ code = pre.querySelector("code");
+ wysihtml5.dom.replaceWithChildNodes(pre);
+ if (code) {
+ wysihtml5.dom.replaceWithChildNodes(code);
+ }
+ });
+ } else {
+ // Wrap in ...
+ range = composer.selection.getRange();
+ selectedNodes = range.extractContents();
+ pre = composer.doc.createElement("pre");
+ code = composer.doc.createElement("code");
- exec: function(composer, command, classname) {
- var pre = this.state(composer),
- code, range, selectedNodes;
- if (pre) {
- // caret is already within a ...
- composer.selection.executeAndRestore(function() {
- code = pre.querySelector("code");
- wysihtml5.dom.replaceWithChildNodes(pre);
- if (code) {
- wysihtml5.dom.replaceWithChildNodes(code);
+ if (classname) {
+ code.className = classname;
}
- });
- } else {
- // Wrap in ...
- range = composer.selection.getRange();
- selectedNodes = range.extractContents();
- pre = composer.doc.createElement("pre");
- code = composer.doc.createElement("code");
- if (classname) {
- code.className = classname;
+ pre.appendChild(code);
+ code.appendChild(selectedNodes);
+ range.insertNode(pre);
+ composer.selection.selectNode(pre);
}
+ },
- pre.appendChild(code);
- code.appendChild(selectedNodes);
- range.insertNode(pre);
- composer.selection.selectNode(pre);
- }
- },
-
- state: function(composer) {
- var selectedNode = composer.selection.getSelectedNode();
- if (selectedNode && selectedNode.nodeName && selectedNode.nodeName == "PRE"&&
- selectedNode.firstChild && selectedNode.firstChild.nodeName && selectedNode.firstChild.nodeName == "CODE") {
- return selectedNode;
- } else {
- return wysihtml5.dom.getParentElement(selectedNode, { query: "pre code" });
+ state: function(composer) {
+ var selectedNode = composer.selection.getSelectedNode();
+ if (selectedNode && selectedNode.nodeName && selectedNode.nodeName == "PRE"&&
+ selectedNode.firstChild && selectedNode.firstChild.nodeName && selectedNode.firstChild.nodeName == "CODE") {
+ return selectedNode;
+ } else {
+ return wysihtml5.dom.getParentElement(selectedNode, { query: "pre code" });
+ }
}
- }
-};;/**
+ };
+}(wysihtml5));
+;/**
* formatInline scenarios for tag "B" (| = caret, |foo| = selected text)
*
* #1 caret in unformatted text:
@@ -11920,19 +11943,21 @@ wysihtml5.commands.formatCode = {
};
})(wysihtml5);
-;wysihtml5.commands.insertHTML = {
- exec: function(composer, command, html) {
- if (composer.commands.support(command)) {
- composer.doc.execCommand(command, false, html);
- } else {
- composer.selection.insertHTML(html);
- }
- },
+;(function(wysihtml5){
+ wysihtml5.commands.insertHTML = {
+ exec: function(composer, command, html) {
+ if (composer.commands.support(command)) {
+ composer.doc.execCommand(command, false, html);
+ } else {
+ composer.selection.insertHTML(html);
+ }
+ },
- state: function() {
- return false;
- }
-};
+ state: function() {
+ return false;
+ }
+ };
+}(wysihtml5));
;(function(wysihtml5) {
var NODE_NAME = "IMG";
@@ -12062,24 +12087,28 @@ wysihtml5.commands.formatCode = {
}
};
})(wysihtml5);
-;wysihtml5.commands.insertOrderedList = {
- exec: function(composer, command) {
- wysihtml5.commands.insertList.exec(composer, command, "OL");
- },
+;(function(wysihtml5){
+ wysihtml5.commands.insertOrderedList = {
+ exec: function(composer, command) {
+ wysihtml5.commands.insertList.exec(composer, command, "OL");
+ },
- state: function(composer, command) {
- return wysihtml5.commands.insertList.state(composer, command, "OL");
- }
-};
-;wysihtml5.commands.insertUnorderedList = {
- exec: function(composer, command) {
- wysihtml5.commands.insertList.exec(composer, command, "UL");
- },
+ state: function(composer, command) {
+ return wysihtml5.commands.insertList.state(composer, command, "OL");
+ }
+ };
+}(wysihtml5));
+;(function(wysihtml5){
+ wysihtml5.commands.insertUnorderedList = {
+ exec: function(composer, command) {
+ wysihtml5.commands.insertList.exec(composer, command, "UL");
+ },
- state: function(composer, command) {
- return wysihtml5.commands.insertList.state(composer, command, "UL");
- }
-};
+ state: function(composer, command) {
+ return wysihtml5.commands.insertList.state(composer, command, "UL");
+ }
+ };
+}(wysihtml5));
;wysihtml5.commands.insertList = (function(wysihtml5) {
var isNode = function(node, name) {
@@ -12196,10 +12225,10 @@ wysihtml5.commands.formatCode = {
}),
isEmpty, list;
- // This space causes new lists to never break on enter
+ // This space causes new lists to never break on enter
var INVISIBLE_SPACE_REG_EXP = /\uFEFF/g;
tempElement.innerHTML = tempElement.innerHTML.replace(wysihtml5.INVISIBLE_SPACE_REG_EXP, "");
-
+
if (tempElement) {
isEmpty = wysihtml5.lang.array(["", "
", wysihtml5.INVISIBLE_SPACE]).contains(tempElement.innerHTML);
list = wysihtml5.dom.convertToList(tempElement, nodeName.toLowerCase(), composer.parent.config.uneditableContainerClassname);
@@ -12217,7 +12246,7 @@ wysihtml5.commands.formatCode = {
selectedNode = composer.selection.getSelectedNode(),
list = findListEl(selectedNode, nodeName, composer);
- if (!list.el) {
+ if (!list.el) {
if (composer.commands.support(cmd)) {
doc.execCommand(cmd, false, null);
} else {
@@ -12238,20 +12267,23 @@ wysihtml5.commands.formatCode = {
}
};
-})(wysihtml5);;wysihtml5.commands.italic = {
- exec: function(composer, command) {
- wysihtml5.commands.formatInline.execWithToggle(composer, command, "i");
- },
+})(wysihtml5);
+;(function(wysihtml5){
+ wysihtml5.commands.italic = {
+ exec: function(composer, command) {
+ wysihtml5.commands.formatInline.execWithToggle(composer, command, "i");
+ },
- state: function(composer, command) {
- // element.ownerDocument.queryCommandState("italic") results:
- // firefox: only
- // chrome: , , , ...
- // ie: ,
- // opera: only
- return wysihtml5.commands.formatInline.state(composer, command, "i");
- }
-};
+ state: function(composer, command) {
+ // element.ownerDocument.queryCommandState("italic") results:
+ // firefox: only
+ // chrome: , , , ...
+ // ie: ,
+ // opera: only
+ return wysihtml5.commands.formatInline.state(composer, command, "i");
+ }
+ };
+}(wysihtml5));
;(function(wysihtml5) {
var nodeOptions = {
@@ -12381,272 +12413,312 @@ wysihtml5.commands.formatCode = {
};
})(wysihtml5);
-;wysihtml5.commands.redo = {
- exec: function(composer) {
- return composer.undoManager.redo();
- },
+;(function(wysihtml5){
+ wysihtml5.commands.redo = {
+ exec: function(composer) {
+ return composer.undoManager.redo();
+ },
- state: function(composer) {
- return false;
- }
-};
-;wysihtml5.commands.underline = {
- exec: function(composer, command) {
- wysihtml5.commands.formatInline.execWithToggle(composer, command, "u");
- },
+ state: function(composer) {
+ return false;
+ }
+ };
+}(wysihtml5));
+;(function(wysihtml5){
+ wysihtml5.commands.underline = {
+ exec: function(composer, command) {
+ wysihtml5.commands.formatInline.execWithToggle(composer, command, "u");
+ },
- state: function(composer, command) {
- return wysihtml5.commands.formatInline.state(composer, command, "u");
- }
-};
-;wysihtml5.commands.undo = {
- exec: function(composer) {
- return composer.undoManager.undo();
- },
+ state: function(composer, command) {
+ return wysihtml5.commands.formatInline.state(composer, command, "u");
+ }
+ };
+}(wysihtml5));
+;(function(wysihtml5){
+ wysihtml5.commands.undo = {
+ exec: function(composer) {
+ return composer.undoManager.undo();
+ },
- state: function(composer) {
- return false;
- }
-};
-;wysihtml5.commands.createTable = {
- exec: function(composer, command, value) {
+ state: function(composer) {
+ return false;
+ }
+ };
+}(wysihtml5));
+;(function(wysihtml5){
+ wysihtml5.commands.createTable = {
+ exec: function(composer, command, value) {
var col, row, html;
if (value && value.cols && value.rows && parseInt(value.cols, 10) > 0 && parseInt(value.rows, 10) > 0) {
- if (value.tableStyle) {
- html = "";
- } else {
- html = "";
- }
- html += "";
- for (row = 0; row < value.rows; row ++) {
- html += '';
- for (col = 0; col < value.cols; col ++) {
- html += " | ";
- }
- html += '
';
+ if (value.tableStyle) {
+ html = "";
+ } else {
+ html = "";
+ }
+ html += "";
+ for (row = 0; row < value.rows; row ++) {
+ html += '';
+ for (col = 0; col < value.cols; col ++) {
+ html += " | ";
}
- html += "
";
- composer.commands.exec("insertHTML", html);
- //composer.selection.insertHTML(html);
+ html += '';
+ }
+ html += "
";
+ composer.commands.exec("insertHTML", html);
+ //composer.selection.insertHTML(html);
}
+ },
-
- },
-
- state: function(composer, command) {
+ state: function(composer, command) {
return false;
- }
-};
-;wysihtml5.commands.mergeTableCells = {
- exec: function(composer, command) {
+ }
+ };
+
+}(wysihtml5));
+;(function(wysihtml5){
+ wysihtml5.commands.mergeTableCells = {
+ exec: function(composer, command) {
if (composer.tableSelection && composer.tableSelection.start && composer.tableSelection.end) {
- if (this.state(composer, command)) {
- wysihtml5.dom.table.unmergeCell(composer.tableSelection.start);
- } else {
- wysihtml5.dom.table.mergeCellsBetween(composer.tableSelection.start, composer.tableSelection.end);
- }
+ if (this.state(composer, command)) {
+ wysihtml5.dom.table.unmergeCell(composer.tableSelection.start);
+ } else {
+ wysihtml5.dom.table.mergeCellsBetween(composer.tableSelection.start, composer.tableSelection.end);
+ }
}
- },
+ },
- state: function(composer, command) {
+ state: function(composer, command) {
if (composer.tableSelection) {
- var start = composer.tableSelection.start,
- end = composer.tableSelection.end;
- if (start && end && start == end &&
- ((
- wysihtml5.dom.getAttribute(start, "colspan") &&
- parseInt(wysihtml5.dom.getAttribute(start, "colspan"), 10) > 1
- ) || (
- wysihtml5.dom.getAttribute(start, "rowspan") &&
- parseInt(wysihtml5.dom.getAttribute(start, "rowspan"), 10) > 1
- ))
- ) {
- return [start];
- }
+ var start = composer.tableSelection.start,
+ end = composer.tableSelection.end;
+ if (start && end && start == end &&
+ ((
+ wysihtml5.dom.getAttribute(start, "colspan") &&
+ parseInt(wysihtml5.dom.getAttribute(start, "colspan"), 10) > 1
+ ) || (
+ wysihtml5.dom.getAttribute(start, "rowspan") &&
+ parseInt(wysihtml5.dom.getAttribute(start, "rowspan"), 10) > 1
+ ))
+ ) {
+ return [start];
+ }
}
return false;
- }
-};
-;wysihtml5.commands.addTableCells = {
- exec: function(composer, command, value) {
+ }
+ };
+}(wysihtml5));
+;(function(wysihtml5){
+ wysihtml5.commands.addTableCells = {
+ exec: function(composer, command, value) {
if (composer.tableSelection && composer.tableSelection.start && composer.tableSelection.end) {
- // switches start and end if start is bigger than end (reverse selection)
- var tableSelect = wysihtml5.dom.table.orderSelectionEnds(composer.tableSelection.start, composer.tableSelection.end);
- if (value == "before" || value == "above") {
- wysihtml5.dom.table.addCells(tableSelect.start, value);
- } else if (value == "after" || value == "below") {
- wysihtml5.dom.table.addCells(tableSelect.end, value);
- }
- setTimeout(function() {
- composer.tableSelection.select(tableSelect.start, tableSelect.end);
- },0);
+ // switches start and end if start is bigger than end (reverse selection)
+ var tableSelect = wysihtml5.dom.table.orderSelectionEnds(composer.tableSelection.start, composer.tableSelection.end);
+ if (value == "before" || value == "above") {
+ wysihtml5.dom.table.addCells(tableSelect.start, value);
+ } else if (value == "after" || value == "below") {
+ wysihtml5.dom.table.addCells(tableSelect.end, value);
+ }
+ setTimeout(function() {
+ composer.tableSelection.select(tableSelect.start, tableSelect.end);
+ },0);
}
- },
+ },
- state: function(composer, command) {
+ state: function(composer, command) {
return false;
- }
-};
-;wysihtml5.commands.deleteTableCells = {
+ }
+ };
+}(wysihtml5));
+;(function(wysihtml5){
+ wysihtml5.commands.deleteTableCells = {
exec: function(composer, command, value) {
- if (composer.tableSelection && composer.tableSelection.start && composer.tableSelection.end) {
- var tableSelect = wysihtml5.dom.table.orderSelectionEnds(composer.tableSelection.start, composer.tableSelection.end),
- idx = wysihtml5.dom.table.indexOf(tableSelect.start),
- selCell,
- table = composer.tableSelection.table;
-
- wysihtml5.dom.table.removeCells(tableSelect.start, value);
- setTimeout(function() {
- // move selection to next or previous if not present
- selCell = wysihtml5.dom.table.findCell(table, idx);
-
- if (!selCell){
- if (value == "row") {
- selCell = wysihtml5.dom.table.findCell(table, {
- "row": idx.row - 1,
- "col": idx.col
- });
- }
-
- if (value == "column") {
- selCell = wysihtml5.dom.table.findCell(table, {
- "row": idx.row,
- "col": idx.col - 1
- });
- }
- }
- if (selCell) {
- composer.tableSelection.select(selCell, selCell);
- }
- }, 0);
+ if (composer.tableSelection && composer.tableSelection.start && composer.tableSelection.end) {
+ var tableSelect = wysihtml5.dom.table.orderSelectionEnds(composer.tableSelection.start, composer.tableSelection.end),
+ idx = wysihtml5.dom.table.indexOf(tableSelect.start),
+ selCell,
+ table = composer.tableSelection.table;
- }
- },
+ wysihtml5.dom.table.removeCells(tableSelect.start, value);
+ setTimeout(function() {
+ // move selection to next or previous if not present
+ selCell = wysihtml5.dom.table.findCell(table, idx);
+
+ if (!selCell){
+ if (value == "row") {
+ selCell = wysihtml5.dom.table.findCell(table, {
+ "row": idx.row - 1,
+ "col": idx.col
+ });
+ }
- state: function(composer, command) {
- return false;
- }
-};
-;wysihtml5.commands.indentList = {
- exec: function(composer, command, value) {
- var listEls = composer.selection.getSelectionParentsByTag('LI');
- if (listEls) {
- return this.tryToPushLiLevel(listEls, composer.selection);
+ if (value == "column") {
+ selCell = wysihtml5.dom.table.findCell(table, {
+ "row": idx.row,
+ "col": idx.col - 1
+ });
+ }
+ }
+ if (selCell) {
+ composer.tableSelection.select(selCell, selCell);
+ }
+ }, 0);
}
- return false;
},
state: function(composer, command) {
+ return false;
+ }
+ };
+}(wysihtml5));
+;(function(wysihtml5){
+ wysihtml5.commands.indentList = {
+ exec: function(composer, command, value) {
+ var listEls = composer.selection.getSelectionParentsByTag('LI');
+ if (listEls) {
+ return this.tryToPushLiLevel(listEls, composer.selection);
+ }
return false;
- },
+ },
+
+ state: function(composer, command) {
+ return false;
+ },
- tryToPushLiLevel: function(liNodes, selection) {
- var listTag, list, prevLi, liNode, prevLiList,
- found = false;
+ tryToPushLiLevel: function(liNodes, selection) {
+ var listTag, list, prevLi, liNode, prevLiList,
+ found = false;
- selection.executeAndRestoreRangy(function() {
+ selection.executeAndRestoreRangy(function() {
- for (var i = liNodes.length; i--;) {
- liNode = liNodes[i];
- listTag = (liNode.parentNode.nodeName === 'OL') ? 'OL' : 'UL';
- list = liNode.ownerDocument.createElement(listTag);
- prevLi = wysihtml5.dom.domNode(liNode).prev({nodeTypes: [wysihtml5.ELEMENT_NODE]});
- prevLiList = (prevLi) ? prevLi.querySelector('ul, ol') : null;
+ for (var i = liNodes.length; i--;) {
+ liNode = liNodes[i];
+ listTag = (liNode.parentNode.nodeName === 'OL') ? 'OL' : 'UL';
+ list = liNode.ownerDocument.createElement(listTag);
+ prevLi = wysihtml5.dom.domNode(liNode).prev({nodeTypes: [wysihtml5.ELEMENT_NODE]});
+ prevLiList = (prevLi) ? prevLi.querySelector('ul, ol') : null;
- if (prevLi) {
- if (prevLiList) {
- prevLiList.appendChild(liNode);
- } else {
- list.appendChild(liNode);
- prevLi.appendChild(list);
+ if (prevLi) {
+ if (prevLiList) {
+ prevLiList.appendChild(liNode);
+ } else {
+ list.appendChild(liNode);
+ prevLi.appendChild(list);
+ }
+ found = true;
}
- found = true;
}
- }
- });
- return found;
- }
-};
-;wysihtml5.commands.outdentList = {
- exec: function(composer, command, value) {
- var listEls = composer.selection.getSelectionParentsByTag('LI');
- if (listEls) {
- return this.tryToPullLiLevel(listEls, composer);
+ });
+ return found;
}
- return false;
- },
+ };
+}(wysihtml5));
+;(function(wysihtml5){
- state: function(composer, command) {
+ wysihtml5.commands.outdentList = {
+ exec: function(composer, command, value) {
+ var listEls = composer.selection.getSelectionParentsByTag('LI');
+ if (listEls) {
+ return this.tryToPullLiLevel(listEls, composer);
+ }
return false;
- },
+ },
- tryToPullLiLevel: function(liNodes, composer) {
- var listNode, outerListNode, outerLiNode, list, prevLi, liNode, afterList,
- found = false,
- that = this;
+ state: function(composer, command) {
+ return false;
+ },
- composer.selection.executeAndRestoreRangy(function() {
+ tryToPullLiLevel: function(liNodes, composer) {
+ var listNode, outerListNode, outerLiNode, list, prevLi, liNode, afterList,
+ found = false,
+ that = this;
- for (var i = liNodes.length; i--;) {
- liNode = liNodes[i];
- if (liNode.parentNode) {
- listNode = liNode.parentNode;
+ composer.selection.executeAndRestoreRangy(function() {
- if (listNode.tagName === 'OL' || listNode.tagName === 'UL') {
- found = true;
+ for (var i = liNodes.length; i--;) {
+ liNode = liNodes[i];
+ if (liNode.parentNode) {
+ listNode = liNode.parentNode;
- outerListNode = wysihtml5.dom.getParentElement(listNode.parentNode, { query: 'ol, ul' }, false, composer.element);
- outerLiNode = wysihtml5.dom.getParentElement(listNode.parentNode, { query: 'li' }, false, composer.element);
+ if (listNode.tagName === 'OL' || listNode.tagName === 'UL') {
+ found = true;
- if (outerListNode && outerLiNode) {
+ outerListNode = wysihtml5.dom.getParentElement(listNode.parentNode, { query: 'ol, ul' }, false, composer.element);
+ outerLiNode = wysihtml5.dom.getParentElement(listNode.parentNode, { query: 'li' }, false, composer.element);
- if (liNode.nextSibling) {
- afterList = that.getAfterList(listNode, liNode);
- liNode.appendChild(afterList);
- }
- outerListNode.insertBefore(liNode, outerLiNode.nextSibling);
+ if (outerListNode && outerLiNode) {
- } else {
+ if (liNode.nextSibling) {
+ afterList = that.getAfterList(listNode, liNode);
+ liNode.appendChild(afterList);
+ }
+ outerListNode.insertBefore(liNode, outerLiNode.nextSibling);
- if (liNode.nextSibling) {
- afterList = that.getAfterList(listNode, liNode);
- liNode.appendChild(afterList);
- }
+ } else {
- for (var j = liNode.childNodes.length; j--;) {
- listNode.parentNode.insertBefore(liNode.childNodes[j], listNode.nextSibling);
- }
+ if (liNode.nextSibling) {
+ afterList = that.getAfterList(listNode, liNode);
+ liNode.appendChild(afterList);
+ }
+
+ for (var j = liNode.childNodes.length; j--;) {
+ listNode.parentNode.insertBefore(liNode.childNodes[j], listNode.nextSibling);
+ }
- listNode.parentNode.insertBefore(document.createElement('br'), listNode.nextSibling);
- liNode.parentNode.removeChild(liNode);
+ listNode.parentNode.insertBefore(document.createElement('br'), listNode.nextSibling);
+ liNode.parentNode.removeChild(liNode);
- }
+ }
- // cleanup
- if (listNode.childNodes.length === 0) {
- listNode.parentNode.removeChild(listNode);
+ // cleanup
+ if (listNode.childNodes.length === 0) {
+ listNode.parentNode.removeChild(listNode);
+ }
}
}
}
- }
- });
- return found;
- },
+ });
+ return found;
+ },
- getAfterList: function(listNode, liNode) {
- var nodeName = listNode.nodeName,
- newList = document.createElement(nodeName);
+ getAfterList: function(listNode, liNode) {
+ var nodeName = listNode.nodeName,
+ newList = document.createElement(nodeName);
- while (liNode.nextSibling) {
- newList.appendChild(liNode.nextSibling);
+ while (liNode.nextSibling) {
+ newList.appendChild(liNode.nextSibling);
+ }
+ return newList;
}
- return newList;
- }
-};;/**
+ };
+}(wysihtml5));
+;(function(wysihtml5){
+ wysihtml5.commands.subscript = {
+ exec: function(composer, command) {
+ wysihtml5.commands.formatInline.execWithToggle(composer, command, "sub");
+ },
+
+ state: function(composer, command) {
+ return wysihtml5.commands.formatInline.state(composer, command, "sub");
+ }
+ };
+}(wysihtml5));
+;(function(wysihtml5){
+ wysihtml5.commands.superscript = {
+ exec: function(composer, command) {
+ wysihtml5.commands.formatInline.execWithToggle(composer, command, "sup");
+ },
+
+ state: function(composer, command) {
+ return wysihtml5.commands.formatInline.state(composer, command, "sup");
+ }
+ };
+}(wysihtml5));
+;/**
* Undo Manager for wysihtml5
* slightly inspired by http://rniwa.com/editing/undomanager.html#the-undomanager-interface
*/
@@ -12968,7 +13040,7 @@ wysihtml5.views.View = Base.extend(
cleanUp: function() {
var bookmark;
if (this.selection) {
- bookmark = rangy.saveSelection(this.doc.defaultView || this.doc.parentWindow);
+ bookmark = rangy.saveSelection(this.win);
}
this.parent.parse(this.element);
if (bookmark) {
@@ -13024,6 +13096,32 @@ wysihtml5.views.View = Base.extend(
}
},
+ getScrollPos: function() {
+ if (this.doc && this.win) {
+ var pos = {};
+
+ if (typeof this.win.pageYOffset !== "undefined") {
+ pos.y = this.win.pageYOffset;
+ } else {
+ pos.y = (this.doc.documentElement || this.doc.body.parentNode || this.doc.body).scrollTop;
+ }
+
+ if (typeof this.win.pageXOffset !== "undefined") {
+ pos.x = this.win.pageXOffset;
+ } else {
+ pos.x = (this.doc.documentElement || this.doc.body.parentNode || this.doc.body).scrollLeft;
+ }
+
+ return pos;
+ }
+ },
+
+ setScrollPos: function(pos) {
+ if (pos && typeof pos.x !== "undefined" && typeof pos.y !== "undefined") {
+ this.win.scrollTo(pos.x, pos.y);
+ }
+ },
+
getTextContent: function() {
return dom.getTextContent(this.element);
},
@@ -13089,6 +13187,7 @@ wysihtml5.views.View = Base.extend(
_create: function() {
var that = this;
this.doc = this.sandbox.getDocument();
+ this.win = this.sandbox.getWindow();
this.element = (this.config.contentEditableMode) ? this.sandbox.getContentEditable() : this.doc.body;
if (!this.config.noTextarea) {
this.textarea = this.parent.textarea;
@@ -13628,22 +13727,34 @@ wysihtml5.views.View = Base.extend(
} else if (selection.caretIsInTheBeginnig()) {
event.preventDefault();
} else {
-
if (selection.caretIsFirstInSelection() &&
selection.getPreviousNode() &&
selection.getPreviousNode().nodeName &&
(/^H\d$/gi).test(selection.getPreviousNode().nodeName)
) {
var prevNode = selection.getPreviousNode();
- event.preventDefault();
if ((/^\s*$/).test(prevNode.textContent || prevNode.innerText)) {
// heading is empty
+ event.preventDefault();
prevNode.parentNode.removeChild(prevNode);
} else {
- var range = prevNode.ownerDocument.createRange();
- range.selectNodeContents(prevNode);
- range.collapse(false);
- selection.setSelection(range);
+ if (prevNode.lastChild) {
+ var selNode = prevNode.lastChild,
+ curNode = wysihtml5.dom.getParentElement(selection.getSelectedNode(), { query: "h1, h2, h3, h4, h5, h6, p, pre, div, blockquote" }, false, composer.element);
+ if (prevNode) {
+ if (curNode) {
+ event.preventDefault();
+ while (curNode.firstChild) {
+ prevNode.appendChild(curNode.firstChild);
+ }
+ selection.setAfter(selNode);
+ } else if (selection.getSelectedNode().nodeType === 3) {
+ event.preventDefault();
+ prevNode.appendChild(selection.getSelectedNode());
+ selection.setAfter(selNode);
+ }
+ }
+ }
}
}
@@ -14306,8 +14417,7 @@ wysihtml5.views.View = Base.extend(
* - Observes for paste and drop
*/
_initParser: function() {
- var that = this,
- oldHtml,
+ var oldHtml,
cleanHtml;
if (wysihtml5.browser.supportsModenPaste()) {
@@ -14315,20 +14425,23 @@ wysihtml5.views.View = Base.extend(
event.preventDefault();
oldHtml = wysihtml5.dom.getPastedHtml(event);
if (oldHtml) {
- that._cleanAndPaste(oldHtml);
+ this._cleanAndPaste(oldHtml);
}
- });
+ }.bind(this));
} else {
this.on("beforepaste:composer", function(event) {
event.preventDefault();
- wysihtml5.dom.getPastedHtmlWithDiv(that.composer, function(pastedHTML) {
+ var scrollPos = this.composer.getScrollPos();
+
+ wysihtml5.dom.getPastedHtmlWithDiv(this.composer, function(pastedHTML) {
if (pastedHTML) {
- that._cleanAndPaste(pastedHTML);
+ this._cleanAndPaste(pastedHTML);
}
- });
- });
+ this.composer.setScrollPos(scrollPos);
+ }.bind(this));
+ }.bind(this));
}
},