wysihtml-rails 0.5.0.beta3 → 0.5.0.beta4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -375,9 +375,8 @@ if ("document" in self) {
375
375
  }
376
376
 
377
377
  }
378
-
379
378
  ;/**
380
- * @license wysihtml5x v0.5.0-beta3
379
+ * @license wysihtml5x v0.5.0-beta4
381
380
  * https://github.com/Edicy/wysihtml5
382
381
  *
383
382
  * Author: Christopher Blum (https://github.com/tiff)
@@ -388,7 +387,7 @@ if ("document" in self) {
388
387
  *
389
388
  */
390
389
  var wysihtml5 = {
391
- version: "0.5.0-beta3",
390
+ version: "0.5.0-beta4",
392
391
 
393
392
  // namespaces
394
393
  commands: {},
@@ -4927,7 +4926,7 @@ wysihtml5.browser = (function() {
4927
4926
  },
4928
4927
 
4929
4928
  supportsMutationEvents: function() {
4930
- return ("MutationEvent" in window);
4929
+ return ("MutationEvent" in window);
4931
4930
  },
4932
4931
 
4933
4932
  /**
@@ -5878,7 +5877,8 @@ wysihtml5.dom.copyAttributes = function(attributesToCopy) {
5878
5877
 
5879
5878
  };
5880
5879
  };
5881
- })(wysihtml5);;/**
5880
+ })(wysihtml5);
5881
+ ;/**
5882
5882
  * Returns the given html wrapped in a div element
5883
5883
  *
5884
5884
  * Fixing IE's inability to treat unknown elements (HTML5 section, article, ...) correctly
@@ -5972,7 +5972,8 @@ wysihtml5.dom.getParentElement = (function() {
5972
5972
  return null;
5973
5973
  };
5974
5974
 
5975
- })();;/**
5975
+ })();
5976
+ ;/**
5976
5977
  * Get element's style for a specific css property
5977
5978
  *
5978
5979
  * @param {Element} element The element on which to retrieve the style
@@ -6057,7 +6058,8 @@ wysihtml5.dom.getStyle = (function() {
6057
6058
  }
6058
6059
  }
6059
6060
  return all;
6060
- };;/**
6061
+ };
6062
+ ;/**
6061
6063
  * High performant way to check whether an element with a specific tag name is in the given document
6062
6064
  * Optimized for being heavily executed
6063
6065
  * Unleashes the power of live node lists
@@ -7181,7 +7183,11 @@ wysihtml5.dom.renameElement = function(element, newNodeName) {
7181
7183
  newElement.appendChild(firstChild);
7182
7184
  }
7183
7185
  wysihtml5.dom.copyAttributes(["align", "className"]).from(element).to(newElement);
7184
- element.parentNode.replaceChild(newElement, element);
7186
+
7187
+ if (element.parentNode) {
7188
+ element.parentNode.replaceChild(newElement, element);
7189
+ }
7190
+
7185
7191
  return newElement;
7186
7192
  };
7187
7193
  ;/**
@@ -7567,7 +7573,7 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
7567
7573
  },
7568
7574
 
7569
7575
  getWindow: function() {
7570
- return this.element.ownerDocument.defaultView;
7576
+ return this.element.ownerDocument.defaultView || this.element.ownerDocument.parentWindow;
7571
7577
  },
7572
7578
 
7573
7579
  getDocument: function() {
@@ -7594,29 +7600,19 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
7594
7600
 
7595
7601
  // initiates an allready existent contenteditable
7596
7602
  _bindElement: function(contentEditable) {
7597
- contentEditable.className = (contentEditable.className && contentEditable.className != '') ? contentEditable.className + " wysihtml5-sandbox" : "wysihtml5-sandbox";
7603
+ contentEditable.className = (contentEditable.className && contentEditable.className !== '') ? contentEditable.className + " wysihtml5-sandbox" : "wysihtml5-sandbox";
7598
7604
  this._loadElement(contentEditable, true);
7599
7605
  return contentEditable;
7600
7606
  },
7601
7607
 
7602
7608
  _loadElement: function(element, contentExists) {
7603
- var that = this;
7609
+ var that = this;
7610
+
7604
7611
  if (!contentExists) {
7605
- var sandboxHtml = this._getHtml();
7606
- element.innerHTML = sandboxHtml;
7612
+ var innerHtml = this._getHtml();
7613
+ element.innerHTML = innerHtml;
7607
7614
  }
7608
7615
 
7609
- this.getWindow = function() { return element.ownerDocument.defaultView; };
7610
- this.getDocument = function() { return element.ownerDocument; };
7611
-
7612
- // Catch js errors and pass them to the parent's onerror event
7613
- // addEventListener("error") doesn't work properly in some browsers
7614
- // TODO: apparently this doesn't work in IE9!
7615
- // TODO: figure out and bind the errors logic for contenteditble mode
7616
- /*iframeWindow.onerror = function(errorMessage, fileName, lineNumber) {
7617
- throw new Error("wysihtml5.Sandbox: " + errorMessage, fileName, lineNumber);
7618
- }
7619
- */
7620
7616
  this.loaded = true;
7621
7617
  // Trigger the callback
7622
7618
  setTimeout(function() { that.callback(that); }, 0);
@@ -7741,7 +7737,6 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
7741
7737
  };
7742
7738
  }
7743
7739
  })(wysihtml5.dom);
7744
-
7745
7740
  ;/**
7746
7741
  * Get a set of attribute from one element
7747
7742
  *
@@ -7805,7 +7800,8 @@ wysihtml5.dom.getAttributes = function(node) {
7805
7800
  }
7806
7801
  }
7807
7802
  return attributes;
7808
- };;/**
7803
+ };
7804
+ ;/**
7809
7805
  * Check whether the given node is a proper loaded image
7810
7806
  * FIXME: Returns undefined when unknown (Chrome, Safari)
7811
7807
  */
@@ -7821,884 +7817,881 @@ wysihtml5.dom.isLoadedImage = function (node) {
7821
7817
  };
7822
7818
  ;(function(wysihtml5) {
7823
7819
 
7824
- var api = wysihtml5.dom;
7825
-
7826
- var MapCell = function(cell) {
7827
- this.el = cell;
7828
- this.isColspan= false;
7829
- this.isRowspan= false;
7830
- this.firstCol= true;
7831
- this.lastCol= true;
7832
- this.firstRow= true;
7833
- this.lastRow= true;
7834
- this.isReal= true;
7835
- this.spanCollection= [];
7836
- this.modified = false;
7837
- };
7820
+ var api = wysihtml5.dom;
7838
7821
 
7839
- var TableModifyerByCell = function (cell, table) {
7840
- if (cell) {
7841
- this.cell = cell;
7842
- this.table = api.getParentElement(cell, { query: "table" });
7843
- } else if (table) {
7844
- this.table = table;
7845
- this.cell = this.table.querySelectorAll('th, td')[0];
7846
- }
7847
- };
7822
+ var MapCell = function(cell) {
7823
+ this.el = cell;
7824
+ this.isColspan= false;
7825
+ this.isRowspan= false;
7826
+ this.firstCol= true;
7827
+ this.lastCol= true;
7828
+ this.firstRow= true;
7829
+ this.lastRow= true;
7830
+ this.isReal= true;
7831
+ this.spanCollection= [];
7832
+ this.modified = false;
7833
+ };
7848
7834
 
7849
- function queryInList(list, query) {
7850
- var ret = [],
7851
- q;
7852
- for (var e = 0, len = list.length; e < len; e++) {
7853
- q = list[e].querySelectorAll(query);
7854
- if (q) {
7855
- for(var i = q.length; i--; ret.unshift(q[i]));
7856
- }
7857
- }
7858
- return ret;
7835
+ var TableModifyerByCell = function (cell, table) {
7836
+ if (cell) {
7837
+ this.cell = cell;
7838
+ this.table = api.getParentElement(cell, { query: "table" });
7839
+ } else if (table) {
7840
+ this.table = table;
7841
+ this.cell = this.table.querySelectorAll('th, td')[0];
7859
7842
  }
7843
+ };
7860
7844
 
7861
- function removeElement(el) {
7862
- el.parentNode.removeChild(el);
7845
+ function queryInList(list, query) {
7846
+ var ret = [],
7847
+ q;
7848
+ for (var e = 0, len = list.length; e < len; e++) {
7849
+ q = list[e].querySelectorAll(query);
7850
+ if (q) {
7851
+ for(var i = q.length; i--; ret.unshift(q[i]));
7852
+ }
7863
7853
  }
7854
+ return ret;
7855
+ }
7864
7856
 
7865
- function insertAfter(referenceNode, newNode) {
7866
- referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
7867
- }
7857
+ function removeElement(el) {
7858
+ el.parentNode.removeChild(el);
7859
+ }
7868
7860
 
7869
- function nextNode(node, tag) {
7870
- var element = node.nextSibling;
7871
- while (element.nodeType !=1) {
7872
- element = element.nextSibling;
7873
- if (!tag || tag == element.tagName.toLowerCase()) {
7874
- return element;
7875
- }
7876
- }
7877
- return null;
7861
+ function insertAfter(referenceNode, newNode) {
7862
+ referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);
7863
+ }
7864
+
7865
+ function nextNode(node, tag) {
7866
+ var element = node.nextSibling;
7867
+ while (element.nodeType !=1) {
7868
+ element = element.nextSibling;
7869
+ if (!tag || tag == element.tagName.toLowerCase()) {
7870
+ return element;
7871
+ }
7878
7872
  }
7873
+ return null;
7874
+ }
7879
7875
 
7880
- TableModifyerByCell.prototype = {
7876
+ TableModifyerByCell.prototype = {
7881
7877
 
7882
- addSpannedCellToMap: function(cell, map, r, c, cspan, rspan) {
7883
- var spanCollect = [],
7884
- rmax = r + ((rspan) ? parseInt(rspan, 10) - 1 : 0),
7885
- cmax = c + ((cspan) ? parseInt(cspan, 10) - 1 : 0);
7878
+ addSpannedCellToMap: function(cell, map, r, c, cspan, rspan) {
7879
+ var spanCollect = [],
7880
+ rmax = r + ((rspan) ? parseInt(rspan, 10) - 1 : 0),
7881
+ cmax = c + ((cspan) ? parseInt(cspan, 10) - 1 : 0);
7886
7882
 
7887
- for (var rr = r; rr <= rmax; rr++) {
7888
- if (typeof map[rr] == "undefined") { map[rr] = []; }
7889
- for (var cc = c; cc <= cmax; cc++) {
7890
- map[rr][cc] = new MapCell(cell);
7891
- map[rr][cc].isColspan = (cspan && parseInt(cspan, 10) > 1);
7892
- map[rr][cc].isRowspan = (rspan && parseInt(rspan, 10) > 1);
7893
- map[rr][cc].firstCol = cc == c;
7894
- map[rr][cc].lastCol = cc == cmax;
7895
- map[rr][cc].firstRow = rr == r;
7896
- map[rr][cc].lastRow = rr == rmax;
7897
- map[rr][cc].isReal = cc == c && rr == r;
7898
- map[rr][cc].spanCollection = spanCollect;
7883
+ for (var rr = r; rr <= rmax; rr++) {
7884
+ if (typeof map[rr] == "undefined") { map[rr] = []; }
7885
+ for (var cc = c; cc <= cmax; cc++) {
7886
+ map[rr][cc] = new MapCell(cell);
7887
+ map[rr][cc].isColspan = (cspan && parseInt(cspan, 10) > 1);
7888
+ map[rr][cc].isRowspan = (rspan && parseInt(rspan, 10) > 1);
7889
+ map[rr][cc].firstCol = cc == c;
7890
+ map[rr][cc].lastCol = cc == cmax;
7891
+ map[rr][cc].firstRow = rr == r;
7892
+ map[rr][cc].lastRow = rr == rmax;
7893
+ map[rr][cc].isReal = cc == c && rr == r;
7894
+ map[rr][cc].spanCollection = spanCollect;
7899
7895
 
7900
- spanCollect.push(map[rr][cc]);
7901
- }
7902
- }
7903
- },
7896
+ spanCollect.push(map[rr][cc]);
7897
+ }
7898
+ }
7899
+ },
7904
7900
 
7905
- setCellAsModified: function(cell) {
7906
- cell.modified = true;
7907
- if (cell.spanCollection.length > 0) {
7908
- for (var s = 0, smax = cell.spanCollection.length; s < smax; s++) {
7909
- cell.spanCollection[s].modified = true;
7910
- }
7911
- }
7912
- },
7901
+ setCellAsModified: function(cell) {
7902
+ cell.modified = true;
7903
+ if (cell.spanCollection.length > 0) {
7904
+ for (var s = 0, smax = cell.spanCollection.length; s < smax; s++) {
7905
+ cell.spanCollection[s].modified = true;
7906
+ }
7907
+ }
7908
+ },
7913
7909
 
7914
- setTableMap: function() {
7915
- var map = [];
7916
- var tableRows = this.getTableRows(),
7917
- ridx, row, cells, cidx, cell,
7918
- c,
7919
- cspan, rspan;
7920
-
7921
- for (ridx = 0; ridx < tableRows.length; ridx++) {
7922
- row = tableRows[ridx];
7923
- cells = this.getRowCells(row);
7924
- c = 0;
7925
- if (typeof map[ridx] == "undefined") { map[ridx] = []; }
7926
- for (cidx = 0; cidx < cells.length; cidx++) {
7927
- cell = cells[cidx];
7928
-
7929
- // If cell allready set means it is set by col or rowspan,
7930
- // so increase cols index until free col is found
7931
- while (typeof map[ridx][c] != "undefined") { c++; }
7932
-
7933
- cspan = api.getAttribute(cell, 'colspan');
7934
- rspan = api.getAttribute(cell, 'rowspan');
7935
-
7936
- if (cspan || rspan) {
7937
- this.addSpannedCellToMap(cell, map, ridx, c, cspan, rspan);
7938
- c = c + ((cspan) ? parseInt(cspan, 10) : 1);
7939
- } else {
7940
- map[ridx][c] = new MapCell(cell);
7941
- c++;
7942
- }
7943
- }
7944
- }
7945
- this.map = map;
7946
- return map;
7947
- },
7910
+ setTableMap: function() {
7911
+ var map = [];
7912
+ var tableRows = this.getTableRows(),
7913
+ ridx, row, cells, cidx, cell,
7914
+ c,
7915
+ cspan, rspan;
7948
7916
 
7949
- getRowCells: function(row) {
7950
- var inlineTables = this.table.querySelectorAll('table'),
7951
- inlineCells = (inlineTables) ? queryInList(inlineTables, 'th, td') : [],
7952
- allCells = row.querySelectorAll('th, td'),
7953
- tableCells = (inlineCells.length > 0) ? wysihtml5.lang.array(allCells).without(inlineCells) : allCells;
7917
+ for (ridx = 0; ridx < tableRows.length; ridx++) {
7918
+ row = tableRows[ridx];
7919
+ cells = this.getRowCells(row);
7920
+ c = 0;
7921
+ if (typeof map[ridx] == "undefined") { map[ridx] = []; }
7922
+ for (cidx = 0; cidx < cells.length; cidx++) {
7923
+ cell = cells[cidx];
7954
7924
 
7955
- return tableCells;
7956
- },
7925
+ // If cell allready set means it is set by col or rowspan,
7926
+ // so increase cols index until free col is found
7927
+ while (typeof map[ridx][c] != "undefined") { c++; }
7957
7928
 
7958
- getTableRows: function() {
7959
- var inlineTables = this.table.querySelectorAll('table'),
7960
- inlineRows = (inlineTables) ? queryInList(inlineTables, 'tr') : [],
7961
- allRows = this.table.querySelectorAll('tr'),
7962
- tableRows = (inlineRows.length > 0) ? wysihtml5.lang.array(allRows).without(inlineRows) : allRows;
7929
+ cspan = api.getAttribute(cell, 'colspan');
7930
+ rspan = api.getAttribute(cell, 'rowspan');
7963
7931
 
7964
- return tableRows;
7965
- },
7932
+ if (cspan || rspan) {
7933
+ this.addSpannedCellToMap(cell, map, ridx, c, cspan, rspan);
7934
+ c = c + ((cspan) ? parseInt(cspan, 10) : 1);
7935
+ } else {
7936
+ map[ridx][c] = new MapCell(cell);
7937
+ c++;
7938
+ }
7939
+ }
7940
+ }
7941
+ this.map = map;
7942
+ return map;
7943
+ },
7966
7944
 
7967
- getMapIndex: function(cell) {
7968
- var r_length = this.map.length,
7969
- c_length = (this.map && this.map[0]) ? this.map[0].length : 0;
7945
+ getRowCells: function(row) {
7946
+ var inlineTables = this.table.querySelectorAll('table'),
7947
+ inlineCells = (inlineTables) ? queryInList(inlineTables, 'th, td') : [],
7948
+ allCells = row.querySelectorAll('th, td'),
7949
+ tableCells = (inlineCells.length > 0) ? wysihtml5.lang.array(allCells).without(inlineCells) : allCells;
7970
7950
 
7971
- for (var r_idx = 0;r_idx < r_length; r_idx++) {
7972
- for (var c_idx = 0;c_idx < c_length; c_idx++) {
7973
- if (this.map[r_idx][c_idx].el === cell) {
7974
- return {'row': r_idx, 'col': c_idx};
7975
- }
7976
- }
7977
- }
7978
- return false;
7979
- },
7951
+ return tableCells;
7952
+ },
7980
7953
 
7981
- getElementAtIndex: function(idx) {
7982
- this.setTableMap();
7983
- if (this.map[idx.row] && this.map[idx.row][idx.col] && this.map[idx.row][idx.col].el) {
7984
- return this.map[idx.row][idx.col].el;
7985
- }
7986
- return null;
7987
- },
7954
+ getTableRows: function() {
7955
+ var inlineTables = this.table.querySelectorAll('table'),
7956
+ inlineRows = (inlineTables) ? queryInList(inlineTables, 'tr') : [],
7957
+ allRows = this.table.querySelectorAll('tr'),
7958
+ tableRows = (inlineRows.length > 0) ? wysihtml5.lang.array(allRows).without(inlineRows) : allRows;
7988
7959
 
7989
- getMapElsTo: function(to_cell) {
7990
- var els = [];
7991
- this.setTableMap();
7992
- this.idx_start = this.getMapIndex(this.cell);
7993
- this.idx_end = this.getMapIndex(to_cell);
7960
+ return tableRows;
7961
+ },
7994
7962
 
7995
- // switch indexes if start is bigger than end
7996
- 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)) {
7997
- var temp_idx = this.idx_start;
7998
- this.idx_start = this.idx_end;
7999
- this.idx_end = temp_idx;
8000
- }
8001
- if (this.idx_start.col > this.idx_end.col) {
8002
- var temp_cidx = this.idx_start.col;
8003
- this.idx_start.col = this.idx_end.col;
8004
- this.idx_end.col = temp_cidx;
8005
- }
7963
+ getMapIndex: function(cell) {
7964
+ var r_length = this.map.length,
7965
+ c_length = (this.map && this.map[0]) ? this.map[0].length : 0;
8006
7966
 
8007
- if (this.idx_start != null && this.idx_end != null) {
8008
- for (var row = this.idx_start.row, maxr = this.idx_end.row; row <= maxr; row++) {
8009
- for (var col = this.idx_start.col, maxc = this.idx_end.col; col <= maxc; col++) {
8010
- els.push(this.map[row][col].el);
8011
- }
8012
- }
8013
- }
8014
- return els;
8015
- },
7967
+ for (var r_idx = 0;r_idx < r_length; r_idx++) {
7968
+ for (var c_idx = 0;c_idx < c_length; c_idx++) {
7969
+ if (this.map[r_idx][c_idx].el === cell) {
7970
+ return {'row': r_idx, 'col': c_idx};
7971
+ }
7972
+ }
7973
+ }
7974
+ return false;
7975
+ },
8016
7976
 
8017
- orderSelectionEnds: function(secondcell) {
8018
- this.setTableMap();
8019
- this.idx_start = this.getMapIndex(this.cell);
8020
- this.idx_end = this.getMapIndex(secondcell);
7977
+ getElementAtIndex: function(idx) {
7978
+ this.setTableMap();
7979
+ if (this.map[idx.row] && this.map[idx.row][idx.col] && this.map[idx.row][idx.col].el) {
7980
+ return this.map[idx.row][idx.col].el;
7981
+ }
7982
+ return null;
7983
+ },
8021
7984
 
8022
- // switch indexes if start is bigger than end
8023
- 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)) {
8024
- var temp_idx = this.idx_start;
8025
- this.idx_start = this.idx_end;
8026
- this.idx_end = temp_idx;
8027
- }
8028
- if (this.idx_start.col > this.idx_end.col) {
8029
- var temp_cidx = this.idx_start.col;
8030
- this.idx_start.col = this.idx_end.col;
8031
- this.idx_end.col = temp_cidx;
8032
- }
7985
+ getMapElsTo: function(to_cell) {
7986
+ var els = [];
7987
+ this.setTableMap();
7988
+ this.idx_start = this.getMapIndex(this.cell);
7989
+ this.idx_end = this.getMapIndex(to_cell);
8033
7990
 
8034
- return {
8035
- "start": this.map[this.idx_start.row][this.idx_start.col].el,
8036
- "end": this.map[this.idx_end.row][this.idx_end.col].el
8037
- };
8038
- },
7991
+ // switch indexes if start is bigger than end
7992
+ 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)) {
7993
+ var temp_idx = this.idx_start;
7994
+ this.idx_start = this.idx_end;
7995
+ this.idx_end = temp_idx;
7996
+ }
7997
+ if (this.idx_start.col > this.idx_end.col) {
7998
+ var temp_cidx = this.idx_start.col;
7999
+ this.idx_start.col = this.idx_end.col;
8000
+ this.idx_end.col = temp_cidx;
8001
+ }
8039
8002
 
8040
- createCells: function(tag, nr, attrs) {
8041
- var doc = this.table.ownerDocument,
8042
- frag = doc.createDocumentFragment(),
8043
- cell;
8044
- for (var i = 0; i < nr; i++) {
8045
- cell = doc.createElement(tag);
8046
-
8047
- if (attrs) {
8048
- for (var attr in attrs) {
8049
- if (attrs.hasOwnProperty(attr)) {
8050
- cell.setAttribute(attr, attrs[attr]);
8051
- }
8052
- }
8053
- }
8003
+ if (this.idx_start != null && this.idx_end != null) {
8004
+ for (var row = this.idx_start.row, maxr = this.idx_end.row; row <= maxr; row++) {
8005
+ for (var col = this.idx_start.col, maxc = this.idx_end.col; col <= maxc; col++) {
8006
+ els.push(this.map[row][col].el);
8007
+ }
8008
+ }
8009
+ }
8010
+ return els;
8011
+ },
8054
8012
 
8055
- // add non breaking space
8056
- cell.appendChild(document.createTextNode("\u00a0"));
8013
+ orderSelectionEnds: function(secondcell) {
8014
+ this.setTableMap();
8015
+ this.idx_start = this.getMapIndex(this.cell);
8016
+ this.idx_end = this.getMapIndex(secondcell);
8057
8017
 
8058
- frag.appendChild(cell);
8059
- }
8060
- return frag;
8061
- },
8018
+ // switch indexes if start is bigger than end
8019
+ 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)) {
8020
+ var temp_idx = this.idx_start;
8021
+ this.idx_start = this.idx_end;
8022
+ this.idx_end = temp_idx;
8023
+ }
8024
+ if (this.idx_start.col > this.idx_end.col) {
8025
+ var temp_cidx = this.idx_start.col;
8026
+ this.idx_start.col = this.idx_end.col;
8027
+ this.idx_end.col = temp_cidx;
8028
+ }
8062
8029
 
8063
- // 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
8064
- correctColIndexForUnreals: function(col, row) {
8065
- var r = this.map[row],
8066
- corrIdx = -1;
8067
- for (var i = 0, max = col; i < col; i++) {
8068
- if (r[i].isReal){
8069
- corrIdx++;
8070
- }
8071
- }
8072
- return corrIdx;
8073
- },
8030
+ return {
8031
+ "start": this.map[this.idx_start.row][this.idx_start.col].el,
8032
+ "end": this.map[this.idx_end.row][this.idx_end.col].el
8033
+ };
8034
+ },
8074
8035
 
8075
- getLastNewCellOnRow: function(row, rowLimit) {
8076
- var cells = this.getRowCells(row),
8077
- cell, idx;
8036
+ createCells: function(tag, nr, attrs) {
8037
+ var doc = this.table.ownerDocument,
8038
+ frag = doc.createDocumentFragment(),
8039
+ cell;
8040
+ for (var i = 0; i < nr; i++) {
8041
+ cell = doc.createElement(tag);
8078
8042
 
8079
- for (var cidx = 0, cmax = cells.length; cidx < cmax; cidx++) {
8080
- cell = cells[cidx];
8081
- idx = this.getMapIndex(cell);
8082
- if (idx === false || (typeof rowLimit != "undefined" && idx.row != rowLimit)) {
8083
- return cell;
8084
- }
8043
+ if (attrs) {
8044
+ for (var attr in attrs) {
8045
+ if (attrs.hasOwnProperty(attr)) {
8046
+ cell.setAttribute(attr, attrs[attr]);
8085
8047
  }
8086
- return null;
8087
- },
8048
+ }
8049
+ }
8088
8050
 
8089
- removeEmptyTable: function() {
8090
- var cells = this.table.querySelectorAll('td, th');
8091
- if (!cells || cells.length == 0) {
8092
- removeElement(this.table);
8093
- return true;
8094
- } else {
8095
- return false;
8096
- }
8097
- },
8051
+ // add non breaking space
8052
+ cell.appendChild(document.createTextNode("\u00a0"));
8053
+ frag.appendChild(cell);
8054
+ }
8055
+ return frag;
8056
+ },
8098
8057
 
8099
- // Splits merged cell on row to unique cells
8100
- splitRowToCells: function(cell) {
8101
- if (cell.isColspan) {
8102
- var colspan = parseInt(api.getAttribute(cell.el, 'colspan') || 1, 10),
8103
- cType = cell.el.tagName.toLowerCase();
8104
- if (colspan > 1) {
8105
- var newCells = this.createCells(cType, colspan -1);
8106
- insertAfter(cell.el, newCells);
8107
- }
8108
- cell.el.removeAttribute('colspan');
8109
- }
8110
- },
8058
+ // 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
8059
+ correctColIndexForUnreals: function(col, row) {
8060
+ var r = this.map[row],
8061
+ corrIdx = -1;
8062
+ for (var i = 0, max = col; i < col; i++) {
8063
+ if (r[i].isReal){
8064
+ corrIdx++;
8065
+ }
8066
+ }
8067
+ return corrIdx;
8068
+ },
8111
8069
 
8112
- getRealRowEl: function(force, idx) {
8113
- var r = null,
8114
- c = null;
8070
+ getLastNewCellOnRow: function(row, rowLimit) {
8071
+ var cells = this.getRowCells(row),
8072
+ cell, idx;
8115
8073
 
8116
- idx = idx || this.idx;
8074
+ for (var cidx = 0, cmax = cells.length; cidx < cmax; cidx++) {
8075
+ cell = cells[cidx];
8076
+ idx = this.getMapIndex(cell);
8077
+ if (idx === false || (typeof rowLimit != "undefined" && idx.row != rowLimit)) {
8078
+ return cell;
8079
+ }
8080
+ }
8081
+ return null;
8082
+ },
8117
8083
 
8118
- for (var cidx = 0, cmax = this.map[idx.row].length; cidx < cmax; cidx++) {
8119
- c = this.map[idx.row][cidx];
8120
- if (c.isReal) {
8121
- r = api.getParentElement(c.el, { query: "tr" });
8122
- if (r) {
8123
- return r;
8124
- }
8125
- }
8126
- }
8084
+ removeEmptyTable: function() {
8085
+ var cells = this.table.querySelectorAll('td, th');
8086
+ if (!cells || cells.length == 0) {
8087
+ removeElement(this.table);
8088
+ return true;
8089
+ } else {
8090
+ return false;
8091
+ }
8092
+ },
8127
8093
 
8128
- if (r === null && force) {
8129
- r = api.getParentElement(this.map[idx.row][idx.col].el, { query: "tr" }) || null;
8130
- }
8094
+ // Splits merged cell on row to unique cells
8095
+ splitRowToCells: function(cell) {
8096
+ if (cell.isColspan) {
8097
+ var colspan = parseInt(api.getAttribute(cell.el, 'colspan') || 1, 10),
8098
+ cType = cell.el.tagName.toLowerCase();
8099
+ if (colspan > 1) {
8100
+ var newCells = this.createCells(cType, colspan -1);
8101
+ insertAfter(cell.el, newCells);
8102
+ }
8103
+ cell.el.removeAttribute('colspan');
8104
+ }
8105
+ },
8106
+
8107
+ getRealRowEl: function(force, idx) {
8108
+ var r = null,
8109
+ c = null;
8131
8110
 
8111
+ idx = idx || this.idx;
8112
+
8113
+ for (var cidx = 0, cmax = this.map[idx.row].length; cidx < cmax; cidx++) {
8114
+ c = this.map[idx.row][cidx];
8115
+ if (c.isReal) {
8116
+ r = api.getParentElement(c.el, { query: "tr" });
8117
+ if (r) {
8132
8118
  return r;
8133
- },
8119
+ }
8120
+ }
8121
+ }
8134
8122
 
8135
- injectRowAt: function(row, col, colspan, cType, c) {
8136
- var r = this.getRealRowEl(false, {'row': row, 'col': col}),
8137
- new_cells = this.createCells(cType, colspan);
8123
+ if (r === null && force) {
8124
+ r = api.getParentElement(this.map[idx.row][idx.col].el, { query: "tr" }) || null;
8125
+ }
8138
8126
 
8139
- if (r) {
8140
- var n_cidx = this.correctColIndexForUnreals(col, row);
8141
- if (n_cidx >= 0) {
8142
- insertAfter(this.getRowCells(r)[n_cidx], new_cells);
8143
- } else {
8144
- r.insertBefore(new_cells, r.firstChild);
8145
- }
8146
- } else {
8147
- var rr = this.table.ownerDocument.createElement('tr');
8148
- rr.appendChild(new_cells);
8149
- insertAfter(api.getParentElement(c.el, { query: "tr" }), rr);
8150
- }
8151
- },
8127
+ return r;
8128
+ },
8129
+
8130
+ injectRowAt: function(row, col, colspan, cType, c) {
8131
+ var r = this.getRealRowEl(false, {'row': row, 'col': col}),
8132
+ new_cells = this.createCells(cType, colspan);
8133
+
8134
+ if (r) {
8135
+ var n_cidx = this.correctColIndexForUnreals(col, row);
8136
+ if (n_cidx >= 0) {
8137
+ insertAfter(this.getRowCells(r)[n_cidx], new_cells);
8138
+ } else {
8139
+ r.insertBefore(new_cells, r.firstChild);
8140
+ }
8141
+ } else {
8142
+ var rr = this.table.ownerDocument.createElement('tr');
8143
+ rr.appendChild(new_cells);
8144
+ insertAfter(api.getParentElement(c.el, { query: "tr" }), rr);
8145
+ }
8146
+ },
8147
+
8148
+ canMerge: function(to) {
8149
+ this.to = to;
8150
+ this.setTableMap();
8151
+ this.idx_start = this.getMapIndex(this.cell);
8152
+ this.idx_end = this.getMapIndex(this.to);
8153
+
8154
+ // switch indexes if start is bigger than end
8155
+ 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)) {
8156
+ var temp_idx = this.idx_start;
8157
+ this.idx_start = this.idx_end;
8158
+ this.idx_end = temp_idx;
8159
+ }
8160
+ if (this.idx_start.col > this.idx_end.col) {
8161
+ var temp_cidx = this.idx_start.col;
8162
+ this.idx_start.col = this.idx_end.col;
8163
+ this.idx_end.col = temp_cidx;
8164
+ }
8152
8165
 
8153
- canMerge: function(to) {
8154
- this.to = to;
8155
- this.setTableMap();
8156
- this.idx_start = this.getMapIndex(this.cell);
8157
- this.idx_end = this.getMapIndex(this.to);
8166
+ for (var row = this.idx_start.row, maxr = this.idx_end.row; row <= maxr; row++) {
8167
+ for (var col = this.idx_start.col, maxc = this.idx_end.col; col <= maxc; col++) {
8168
+ if (this.map[row][col].isColspan || this.map[row][col].isRowspan) {
8169
+ return false;
8170
+ }
8171
+ }
8172
+ }
8173
+ return true;
8174
+ },
8158
8175
 
8159
- // switch indexes if start is bigger than end
8160
- 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)) {
8161
- var temp_idx = this.idx_start;
8162
- this.idx_start = this.idx_end;
8163
- this.idx_end = temp_idx;
8176
+ decreaseCellSpan: function(cell, span) {
8177
+ var nr = parseInt(api.getAttribute(cell.el, span), 10) - 1;
8178
+ if (nr >= 1) {
8179
+ cell.el.setAttribute(span, nr);
8180
+ } else {
8181
+ cell.el.removeAttribute(span);
8182
+ if (span == 'colspan') {
8183
+ cell.isColspan = false;
8184
+ }
8185
+ if (span == 'rowspan') {
8186
+ cell.isRowspan = false;
8187
+ }
8188
+ cell.firstCol = true;
8189
+ cell.lastCol = true;
8190
+ cell.firstRow = true;
8191
+ cell.lastRow = true;
8192
+ cell.isReal = true;
8193
+ }
8194
+ },
8195
+
8196
+ removeSurplusLines: function() {
8197
+ var row, cell, ridx, rmax, cidx, cmax, allRowspan;
8198
+
8199
+ this.setTableMap();
8200
+ if (this.map) {
8201
+ ridx = 0;
8202
+ rmax = this.map.length;
8203
+ for (;ridx < rmax; ridx++) {
8204
+ row = this.map[ridx];
8205
+ allRowspan = true;
8206
+ cidx = 0;
8207
+ cmax = row.length;
8208
+ for (; cidx < cmax; cidx++) {
8209
+ cell = row[cidx];
8210
+ if (!(api.getAttribute(cell.el, "rowspan") && parseInt(api.getAttribute(cell.el, "rowspan"), 10) > 1 && cell.firstRow !== true)) {
8211
+ allRowspan = false;
8212
+ break;
8164
8213
  }
8165
- if (this.idx_start.col > this.idx_end.col) {
8166
- var temp_cidx = this.idx_start.col;
8167
- this.idx_start.col = this.idx_end.col;
8168
- this.idx_end.col = temp_cidx;
8214
+ }
8215
+ if (allRowspan) {
8216
+ cidx = 0;
8217
+ for (; cidx < cmax; cidx++) {
8218
+ this.decreaseCellSpan(row[cidx], 'rowspan');
8169
8219
  }
8220
+ }
8221
+ }
8170
8222
 
8171
- for (var row = this.idx_start.row, maxr = this.idx_end.row; row <= maxr; row++) {
8172
- for (var col = this.idx_start.col, maxc = this.idx_end.col; col <= maxc; col++) {
8173
- if (this.map[row][col].isColspan || this.map[row][col].isRowspan) {
8174
- return false;
8175
- }
8176
- }
8177
- }
8178
- return true;
8179
- },
8223
+ // remove rows without cells
8224
+ var tableRows = this.getTableRows();
8225
+ ridx = 0;
8226
+ rmax = tableRows.length;
8227
+ for (;ridx < rmax; ridx++) {
8228
+ row = tableRows[ridx];
8229
+ if (row.childNodes.length == 0 && (/^\s*$/.test(row.textContent || row.innerText))) {
8230
+ removeElement(row);
8231
+ }
8232
+ }
8233
+ }
8234
+ },
8180
8235
 
8181
- decreaseCellSpan: function(cell, span) {
8182
- var nr = parseInt(api.getAttribute(cell.el, span), 10) - 1;
8183
- if (nr >= 1) {
8184
- cell.el.setAttribute(span, nr);
8185
- } else {
8186
- cell.el.removeAttribute(span);
8187
- if (span == 'colspan') {
8188
- cell.isColspan = false;
8189
- }
8190
- if (span == 'rowspan') {
8191
- cell.isRowspan = false;
8192
- }
8193
- cell.firstCol = true;
8194
- cell.lastCol = true;
8195
- cell.firstRow = true;
8196
- cell.lastRow = true;
8197
- cell.isReal = true;
8198
- }
8199
- },
8236
+ fillMissingCells: function() {
8237
+ var r_max = 0,
8238
+ c_max = 0,
8239
+ prevcell = null;
8200
8240
 
8201
- removeSurplusLines: function() {
8202
- var row, cell, ridx, rmax, cidx, cmax, allRowspan;
8203
-
8204
- this.setTableMap();
8205
- if (this.map) {
8206
- ridx = 0;
8207
- rmax = this.map.length;
8208
- for (;ridx < rmax; ridx++) {
8209
- row = this.map[ridx];
8210
- allRowspan = true;
8211
- cidx = 0;
8212
- cmax = row.length;
8213
- for (; cidx < cmax; cidx++) {
8214
- cell = row[cidx];
8215
- if (!(api.getAttribute(cell.el, "rowspan") && parseInt(api.getAttribute(cell.el, "rowspan"), 10) > 1 && cell.firstRow !== true)) {
8216
- allRowspan = false;
8217
- break;
8218
- }
8219
- }
8220
- if (allRowspan) {
8221
- cidx = 0;
8222
- for (; cidx < cmax; cidx++) {
8223
- this.decreaseCellSpan(row[cidx], 'rowspan');
8224
- }
8225
- }
8226
- }
8241
+ this.setTableMap();
8242
+ if (this.map) {
8227
8243
 
8228
- // remove rows without cells
8229
- var tableRows = this.getTableRows();
8230
- ridx = 0;
8231
- rmax = tableRows.length;
8232
- for (;ridx < rmax; ridx++) {
8233
- row = tableRows[ridx];
8234
- if (row.childNodes.length == 0 && (/^\s*$/.test(row.textContent || row.innerText))) {
8235
- removeElement(row);
8236
- }
8244
+ // find maximal dimensions of broken table
8245
+ r_max = this.map.length;
8246
+ for (var ridx = 0; ridx < r_max; ridx++) {
8247
+ if (this.map[ridx].length > c_max) { c_max = this.map[ridx].length; }
8248
+ }
8249
+
8250
+ for (var row = 0; row < r_max; row++) {
8251
+ for (var col = 0; col < c_max; col++) {
8252
+ if (this.map[row] && !this.map[row][col]) {
8253
+ if (col > 0) {
8254
+ this.map[row][col] = new MapCell(this.createCells('td', 1));
8255
+ prevcell = this.map[row][col-1];
8256
+ if (prevcell && prevcell.el && prevcell.el.parent) { // if parent does not exist element is removed from dom
8257
+ insertAfter(this.map[row][col-1].el, this.map[row][col].el);
8237
8258
  }
8259
+ }
8238
8260
  }
8239
- },
8261
+ }
8262
+ }
8263
+ }
8264
+ },
8240
8265
 
8241
- fillMissingCells: function() {
8242
- var r_max = 0,
8243
- c_max = 0,
8244
- prevcell = null;
8266
+ rectify: function() {
8267
+ if (!this.removeEmptyTable()) {
8268
+ this.removeSurplusLines();
8269
+ this.fillMissingCells();
8270
+ return true;
8271
+ } else {
8272
+ return false;
8273
+ }
8274
+ },
8245
8275
 
8246
- this.setTableMap();
8247
- if (this.map) {
8276
+ unmerge: function() {
8277
+ if (this.rectify()) {
8278
+ this.setTableMap();
8279
+ this.idx = this.getMapIndex(this.cell);
8248
8280
 
8249
- // find maximal dimensions of broken table
8250
- r_max = this.map.length;
8251
- for (var ridx = 0; ridx < r_max; ridx++) {
8252
- if (this.map[ridx].length > c_max) { c_max = this.map[ridx].length; }
8253
- }
8281
+ if (this.idx) {
8282
+ var thisCell = this.map[this.idx.row][this.idx.col],
8283
+ colspan = (api.getAttribute(thisCell.el, "colspan")) ? parseInt(api.getAttribute(thisCell.el, "colspan"), 10) : 1,
8284
+ cType = thisCell.el.tagName.toLowerCase();
8254
8285
 
8255
- for (var row = 0; row < r_max; row++) {
8256
- for (var col = 0; col < c_max; col++) {
8257
- if (this.map[row] && !this.map[row][col]) {
8258
- if (col > 0) {
8259
- this.map[row][col] = new MapCell(this.createCells('td', 1));
8260
- prevcell = this.map[row][col-1];
8261
- if (prevcell && prevcell.el && prevcell.el.parent) { // if parent does not exist element is removed from dom
8262
- insertAfter(this.map[row][col-1].el, this.map[row][col].el);
8263
- }
8264
- }
8265
- }
8266
- }
8267
- }
8286
+ if (thisCell.isRowspan) {
8287
+ var rowspan = parseInt(api.getAttribute(thisCell.el, "rowspan"), 10);
8288
+ if (rowspan > 1) {
8289
+ for (var nr = 1, maxr = rowspan - 1; nr <= maxr; nr++){
8290
+ this.injectRowAt(this.idx.row + nr, this.idx.col, colspan, cType, thisCell);
8291
+ }
8268
8292
  }
8269
- },
8293
+ thisCell.el.removeAttribute('rowspan');
8294
+ }
8295
+ this.splitRowToCells(thisCell);
8296
+ }
8297
+ }
8298
+ },
8270
8299
 
8271
- rectify: function() {
8272
- if (!this.removeEmptyTable()) {
8273
- this.removeSurplusLines();
8274
- this.fillMissingCells();
8275
- return true;
8276
- } else {
8277
- return false;
8278
- }
8279
- },
8300
+ // merges cells from start cell (defined in creating obj) to "to" cell
8301
+ merge: function(to) {
8302
+ if (this.rectify()) {
8303
+ if (this.canMerge(to)) {
8304
+ var rowspan = this.idx_end.row - this.idx_start.row + 1,
8305
+ colspan = this.idx_end.col - this.idx_start.col + 1;
8280
8306
 
8281
- unmerge: function() {
8282
- if (this.rectify()) {
8283
- this.setTableMap();
8284
- this.idx = this.getMapIndex(this.cell);
8285
-
8286
- if (this.idx) {
8287
- var thisCell = this.map[this.idx.row][this.idx.col],
8288
- colspan = (api.getAttribute(thisCell.el, "colspan")) ? parseInt(api.getAttribute(thisCell.el, "colspan"), 10) : 1,
8289
- cType = thisCell.el.tagName.toLowerCase();
8290
-
8291
- if (thisCell.isRowspan) {
8292
- var rowspan = parseInt(api.getAttribute(thisCell.el, "rowspan"), 10);
8293
- if (rowspan > 1) {
8294
- for (var nr = 1, maxr = rowspan - 1; nr <= maxr; nr++){
8295
- this.injectRowAt(this.idx.row + nr, this.idx.col, colspan, cType, thisCell);
8296
- }
8297
- }
8298
- thisCell.el.removeAttribute('rowspan');
8299
- }
8300
- this.splitRowToCells(thisCell);
8307
+ for (var row = this.idx_start.row, maxr = this.idx_end.row; row <= maxr; row++) {
8308
+ for (var col = this.idx_start.col, maxc = this.idx_end.col; col <= maxc; col++) {
8309
+
8310
+ if (row == this.idx_start.row && col == this.idx_start.col) {
8311
+ if (rowspan > 1) {
8312
+ this.map[row][col].el.setAttribute('rowspan', rowspan);
8313
+ }
8314
+ if (colspan > 1) {
8315
+ this.map[row][col].el.setAttribute('colspan', colspan);
8301
8316
  }
8317
+ } else {
8318
+ // transfer content
8319
+ if (!(/^\s*<br\/?>\s*$/.test(this.map[row][col].el.innerHTML.toLowerCase()))) {
8320
+ this.map[this.idx_start.row][this.idx_start.col].el.innerHTML += ' ' + this.map[row][col].el.innerHTML;
8321
+ }
8322
+ removeElement(this.map[row][col].el);
8323
+ }
8324
+
8302
8325
  }
8303
- },
8326
+ }
8327
+ this.rectify();
8328
+ } else {
8329
+ if (window.console) {
8330
+ console.log('Do not know how to merge allready merged cells.');
8331
+ }
8332
+ }
8333
+ }
8334
+ },
8304
8335
 
8305
- // merges cells from start cell (defined in creating obj) to "to" cell
8306
- merge: function(to) {
8307
- if (this.rectify()) {
8308
- if (this.canMerge(to)) {
8309
- var rowspan = this.idx_end.row - this.idx_start.row + 1,
8310
- colspan = this.idx_end.col - this.idx_start.col + 1;
8336
+ // Decreases rowspan of a cell if it is done on first cell of rowspan row (real cell)
8337
+ // Cell is moved to next row (if it is real)
8338
+ collapseCellToNextRow: function(cell) {
8339
+ var cellIdx = this.getMapIndex(cell.el),
8340
+ newRowIdx = cellIdx.row + 1,
8341
+ newIdx = {'row': newRowIdx, 'col': cellIdx.col};
8311
8342
 
8312
- for (var row = this.idx_start.row, maxr = this.idx_end.row; row <= maxr; row++) {
8313
- for (var col = this.idx_start.col, maxc = this.idx_end.col; col <= maxc; col++) {
8343
+ if (newRowIdx < this.map.length) {
8314
8344
 
8315
- if (row == this.idx_start.row && col == this.idx_start.col) {
8316
- if (rowspan > 1) {
8317
- this.map[row][col].el.setAttribute('rowspan', rowspan);
8318
- }
8319
- if (colspan > 1) {
8320
- this.map[row][col].el.setAttribute('colspan', colspan);
8321
- }
8322
- } else {
8323
- // transfer content
8324
- if (!(/^\s*<br\/?>\s*$/.test(this.map[row][col].el.innerHTML.toLowerCase()))) {
8325
- this.map[this.idx_start.row][this.idx_start.col].el.innerHTML += ' ' + this.map[row][col].el.innerHTML;
8326
- }
8327
- removeElement(this.map[row][col].el);
8328
- }
8329
- }
8330
- }
8331
- this.rectify();
8332
- } else {
8333
- if (window.console) {
8334
- console.log('Do not know how to merge allready merged cells.');
8335
- }
8336
- }
8337
- }
8338
- },
8339
-
8340
- // Decreases rowspan of a cell if it is done on first cell of rowspan row (real cell)
8341
- // Cell is moved to next row (if it is real)
8342
- collapseCellToNextRow: function(cell) {
8343
- var cellIdx = this.getMapIndex(cell.el),
8344
- newRowIdx = cellIdx.row + 1,
8345
- newIdx = {'row': newRowIdx, 'col': cellIdx.col};
8346
-
8347
- if (newRowIdx < this.map.length) {
8348
-
8349
- var row = this.getRealRowEl(false, newIdx);
8350
- if (row !== null) {
8351
- var n_cidx = this.correctColIndexForUnreals(newIdx.col, newIdx.row);
8352
- if (n_cidx >= 0) {
8353
- insertAfter(this.getRowCells(row)[n_cidx], cell.el);
8354
- } else {
8355
- var lastCell = this.getLastNewCellOnRow(row, newRowIdx);
8356
- if (lastCell !== null) {
8357
- insertAfter(lastCell, cell.el);
8358
- } else {
8359
- row.insertBefore(cell.el, row.firstChild);
8360
- }
8361
- }
8362
- if (parseInt(api.getAttribute(cell.el, 'rowspan'), 10) > 2) {
8363
- cell.el.setAttribute('rowspan', parseInt(api.getAttribute(cell.el, 'rowspan'), 10) - 1);
8364
- } else {
8365
- cell.el.removeAttribute('rowspan');
8366
- }
8367
- }
8368
- }
8369
- },
8370
-
8371
- // Removes a cell when removing a row
8372
- // If is rowspan cell then decreases the rowspan
8373
- // and moves cell to next row if needed (is first cell of rowspan)
8374
- removeRowCell: function(cell) {
8375
- if (cell.isReal) {
8376
- if (cell.isRowspan) {
8377
- this.collapseCellToNextRow(cell);
8378
- } else {
8379
- removeElement(cell.el);
8380
- }
8345
+ var row = this.getRealRowEl(false, newIdx);
8346
+ if (row !== null) {
8347
+ var n_cidx = this.correctColIndexForUnreals(newIdx.col, newIdx.row);
8348
+ if (n_cidx >= 0) {
8349
+ insertAfter(this.getRowCells(row)[n_cidx], cell.el);
8350
+ } else {
8351
+ var lastCell = this.getLastNewCellOnRow(row, newRowIdx);
8352
+ if (lastCell !== null) {
8353
+ insertAfter(lastCell, cell.el);
8381
8354
  } else {
8382
- if (parseInt(api.getAttribute(cell.el, 'rowspan'), 10) > 2) {
8383
- cell.el.setAttribute('rowspan', parseInt(api.getAttribute(cell.el, 'rowspan'), 10) - 1);
8384
- } else {
8385
- cell.el.removeAttribute('rowspan');
8386
- }
8355
+ row.insertBefore(cell.el, row.firstChild);
8387
8356
  }
8388
- },
8357
+ }
8358
+ if (parseInt(api.getAttribute(cell.el, 'rowspan'), 10) > 2) {
8359
+ cell.el.setAttribute('rowspan', parseInt(api.getAttribute(cell.el, 'rowspan'), 10) - 1);
8360
+ } else {
8361
+ cell.el.removeAttribute('rowspan');
8362
+ }
8363
+ }
8364
+ }
8365
+ },
8389
8366
 
8390
- getRowElementsByCell: function() {
8391
- var cells = [];
8392
- this.setTableMap();
8393
- this.idx = this.getMapIndex(this.cell);
8394
- if (this.idx !== false) {
8395
- var modRow = this.map[this.idx.row];
8396
- for (var cidx = 0, cmax = modRow.length; cidx < cmax; cidx++) {
8397
- if (modRow[cidx].isReal) {
8398
- cells.push(modRow[cidx].el);
8399
- }
8400
- }
8401
- }
8402
- return cells;
8403
- },
8367
+ // Removes a cell when removing a row
8368
+ // If is rowspan cell then decreases the rowspan
8369
+ // and moves cell to next row if needed (is first cell of rowspan)
8370
+ removeRowCell: function(cell) {
8371
+ if (cell.isReal) {
8372
+ if (cell.isRowspan) {
8373
+ this.collapseCellToNextRow(cell);
8374
+ } else {
8375
+ removeElement(cell.el);
8376
+ }
8377
+ } else {
8378
+ if (parseInt(api.getAttribute(cell.el, 'rowspan'), 10) > 2) {
8379
+ cell.el.setAttribute('rowspan', parseInt(api.getAttribute(cell.el, 'rowspan'), 10) - 1);
8380
+ } else {
8381
+ cell.el.removeAttribute('rowspan');
8382
+ }
8383
+ }
8384
+ },
8404
8385
 
8405
- getColumnElementsByCell: function() {
8406
- var cells = [];
8407
- this.setTableMap();
8408
- this.idx = this.getMapIndex(this.cell);
8409
- if (this.idx !== false) {
8410
- for (var ridx = 0, rmax = this.map.length; ridx < rmax; ridx++) {
8411
- if (this.map[ridx][this.idx.col] && this.map[ridx][this.idx.col].isReal) {
8412
- cells.push(this.map[ridx][this.idx.col].el);
8413
- }
8414
- }
8415
- }
8416
- return cells;
8417
- },
8386
+ getRowElementsByCell: function() {
8387
+ var cells = [];
8388
+ this.setTableMap();
8389
+ this.idx = this.getMapIndex(this.cell);
8390
+ if (this.idx !== false) {
8391
+ var modRow = this.map[this.idx.row];
8392
+ for (var cidx = 0, cmax = modRow.length; cidx < cmax; cidx++) {
8393
+ if (modRow[cidx].isReal) {
8394
+ cells.push(modRow[cidx].el);
8395
+ }
8396
+ }
8397
+ }
8398
+ return cells;
8399
+ },
8418
8400
 
8419
- // Removes the row of selected cell
8420
- removeRow: function() {
8421
- var oldRow = api.getParentElement(this.cell, { query: "tr" });
8422
- if (oldRow) {
8423
- this.setTableMap();
8424
- this.idx = this.getMapIndex(this.cell);
8425
- if (this.idx !== false) {
8426
- var modRow = this.map[this.idx.row];
8427
- for (var cidx = 0, cmax = modRow.length; cidx < cmax; cidx++) {
8428
- if (!modRow[cidx].modified) {
8429
- this.setCellAsModified(modRow[cidx]);
8430
- this.removeRowCell(modRow[cidx]);
8431
- }
8432
- }
8433
- }
8434
- removeElement(oldRow);
8435
- }
8436
- },
8401
+ getColumnElementsByCell: function() {
8402
+ var cells = [];
8403
+ this.setTableMap();
8404
+ this.idx = this.getMapIndex(this.cell);
8405
+ if (this.idx !== false) {
8406
+ for (var ridx = 0, rmax = this.map.length; ridx < rmax; ridx++) {
8407
+ if (this.map[ridx][this.idx.col] && this.map[ridx][this.idx.col].isReal) {
8408
+ cells.push(this.map[ridx][this.idx.col].el);
8409
+ }
8410
+ }
8411
+ }
8412
+ return cells;
8413
+ },
8437
8414
 
8438
- removeColCell: function(cell) {
8439
- if (cell.isColspan) {
8440
- if (parseInt(api.getAttribute(cell.el, 'colspan'), 10) > 2) {
8441
- cell.el.setAttribute('colspan', parseInt(api.getAttribute(cell.el, 'colspan'), 10) - 1);
8442
- } else {
8443
- cell.el.removeAttribute('colspan');
8444
- }
8445
- } else if (cell.isReal) {
8446
- removeElement(cell.el);
8415
+ // Removes the row of selected cell
8416
+ removeRow: function() {
8417
+ var oldRow = api.getParentElement(this.cell, { query: "tr" });
8418
+ if (oldRow) {
8419
+ this.setTableMap();
8420
+ this.idx = this.getMapIndex(this.cell);
8421
+ if (this.idx !== false) {
8422
+ var modRow = this.map[this.idx.row];
8423
+ for (var cidx = 0, cmax = modRow.length; cidx < cmax; cidx++) {
8424
+ if (!modRow[cidx].modified) {
8425
+ this.setCellAsModified(modRow[cidx]);
8426
+ this.removeRowCell(modRow[cidx]);
8447
8427
  }
8448
- },
8428
+ }
8429
+ }
8430
+ removeElement(oldRow);
8431
+ }
8432
+ },
8449
8433
 
8450
- removeColumn: function() {
8451
- this.setTableMap();
8452
- this.idx = this.getMapIndex(this.cell);
8453
- if (this.idx !== false) {
8454
- for (var ridx = 0, rmax = this.map.length; ridx < rmax; ridx++) {
8455
- if (!this.map[ridx][this.idx.col].modified) {
8456
- this.setCellAsModified(this.map[ridx][this.idx.col]);
8457
- this.removeColCell(this.map[ridx][this.idx.col]);
8458
- }
8459
- }
8460
- }
8461
- },
8434
+ removeColCell: function(cell) {
8435
+ if (cell.isColspan) {
8436
+ if (parseInt(api.getAttribute(cell.el, 'colspan'), 10) > 2) {
8437
+ cell.el.setAttribute('colspan', parseInt(api.getAttribute(cell.el, 'colspan'), 10) - 1);
8438
+ } else {
8439
+ cell.el.removeAttribute('colspan');
8440
+ }
8441
+ } else if (cell.isReal) {
8442
+ removeElement(cell.el);
8443
+ }
8444
+ },
8462
8445
 
8463
- // removes row or column by selected cell element
8464
- remove: function(what) {
8465
- if (this.rectify()) {
8466
- switch (what) {
8467
- case 'row':
8468
- this.removeRow();
8469
- break;
8470
- case 'column':
8471
- this.removeColumn();
8472
- break;
8473
- }
8474
- this.rectify();
8475
- }
8476
- },
8446
+ removeColumn: function() {
8447
+ this.setTableMap();
8448
+ this.idx = this.getMapIndex(this.cell);
8449
+ if (this.idx !== false) {
8450
+ for (var ridx = 0, rmax = this.map.length; ridx < rmax; ridx++) {
8451
+ if (!this.map[ridx][this.idx.col].modified) {
8452
+ this.setCellAsModified(this.map[ridx][this.idx.col]);
8453
+ this.removeColCell(this.map[ridx][this.idx.col]);
8454
+ }
8455
+ }
8456
+ }
8457
+ },
8477
8458
 
8478
- addRow: function(where) {
8479
- var doc = this.table.ownerDocument;
8459
+ // removes row or column by selected cell element
8460
+ remove: function(what) {
8461
+ if (this.rectify()) {
8462
+ switch (what) {
8463
+ case 'row':
8464
+ this.removeRow();
8465
+ break;
8466
+ case 'column':
8467
+ this.removeColumn();
8468
+ break;
8469
+ }
8470
+ this.rectify();
8471
+ }
8472
+ },
8480
8473
 
8481
- this.setTableMap();
8482
- this.idx = this.getMapIndex(this.cell);
8483
- if (where == "below" && api.getAttribute(this.cell, 'rowspan')) {
8484
- this.idx.row = this.idx.row + parseInt(api.getAttribute(this.cell, 'rowspan'), 10) - 1;
8485
- }
8474
+ addRow: function(where) {
8475
+ var doc = this.table.ownerDocument;
8486
8476
 
8487
- if (this.idx !== false) {
8488
- var modRow = this.map[this.idx.row],
8489
- newRow = doc.createElement('tr');
8477
+ this.setTableMap();
8478
+ this.idx = this.getMapIndex(this.cell);
8479
+ if (where == "below" && api.getAttribute(this.cell, 'rowspan')) {
8480
+ this.idx.row = this.idx.row + parseInt(api.getAttribute(this.cell, 'rowspan'), 10) - 1;
8481
+ }
8490
8482
 
8491
- for (var ridx = 0, rmax = modRow.length; ridx < rmax; ridx++) {
8492
- if (!modRow[ridx].modified) {
8493
- this.setCellAsModified(modRow[ridx]);
8494
- this.addRowCell(modRow[ridx], newRow, where);
8495
- }
8496
- }
8483
+ if (this.idx !== false) {
8484
+ var modRow = this.map[this.idx.row],
8485
+ newRow = doc.createElement('tr');
8497
8486
 
8498
- switch (where) {
8499
- case 'below':
8500
- insertAfter(this.getRealRowEl(true), newRow);
8501
- break;
8502
- case 'above':
8503
- var cr = api.getParentElement(this.map[this.idx.row][this.idx.col].el, { query: "tr" });
8504
- if (cr) {
8505
- cr.parentNode.insertBefore(newRow, cr);
8506
- }
8507
- break;
8508
- }
8509
- }
8510
- },
8487
+ for (var ridx = 0, rmax = modRow.length; ridx < rmax; ridx++) {
8488
+ if (!modRow[ridx].modified) {
8489
+ this.setCellAsModified(modRow[ridx]);
8490
+ this.addRowCell(modRow[ridx], newRow, where);
8491
+ }
8492
+ }
8511
8493
 
8512
- addRowCell: function(cell, row, where) {
8513
- var colSpanAttr = (cell.isColspan) ? {"colspan" : api.getAttribute(cell.el, 'colspan')} : null;
8514
- if (cell.isReal) {
8515
- if (where != 'above' && cell.isRowspan) {
8516
- cell.el.setAttribute('rowspan', parseInt(api.getAttribute(cell.el,'rowspan'), 10) + 1);
8517
- } else {
8518
- row.appendChild(this.createCells('td', 1, colSpanAttr));
8519
- }
8520
- } else {
8521
- if (where != 'above' && cell.isRowspan && cell.lastRow) {
8522
- row.appendChild(this.createCells('td', 1, colSpanAttr));
8523
- } else if (c.isRowspan) {
8524
- cell.el.attr('rowspan', parseInt(api.getAttribute(cell.el, 'rowspan'), 10) + 1);
8525
- }
8494
+ switch (where) {
8495
+ case 'below':
8496
+ insertAfter(this.getRealRowEl(true), newRow);
8497
+ break;
8498
+ case 'above':
8499
+ var cr = api.getParentElement(this.map[this.idx.row][this.idx.col].el, { query: "tr" });
8500
+ if (cr) {
8501
+ cr.parentNode.insertBefore(newRow, cr);
8526
8502
  }
8527
- },
8503
+ break;
8504
+ }
8505
+ }
8506
+ },
8528
8507
 
8529
- add: function(where) {
8530
- if (this.rectify()) {
8531
- if (where == 'below' || where == 'above') {
8532
- this.addRow(where);
8533
- }
8534
- if (where == 'before' || where == 'after') {
8535
- this.addColumn(where);
8536
- }
8537
- }
8538
- },
8508
+ addRowCell: function(cell, row, where) {
8509
+ var colSpanAttr = (cell.isColspan) ? {"colspan" : api.getAttribute(cell.el, 'colspan')} : null;
8510
+ if (cell.isReal) {
8511
+ if (where != 'above' && cell.isRowspan) {
8512
+ cell.el.setAttribute('rowspan', parseInt(api.getAttribute(cell.el,'rowspan'), 10) + 1);
8513
+ } else {
8514
+ row.appendChild(this.createCells('td', 1, colSpanAttr));
8515
+ }
8516
+ } else {
8517
+ if (where != 'above' && cell.isRowspan && cell.lastRow) {
8518
+ row.appendChild(this.createCells('td', 1, colSpanAttr));
8519
+ } else if (c.isRowspan) {
8520
+ cell.el.attr('rowspan', parseInt(api.getAttribute(cell.el, 'rowspan'), 10) + 1);
8521
+ }
8522
+ }
8523
+ },
8539
8524
 
8540
- addColCell: function (cell, ridx, where) {
8541
- var doAdd,
8542
- cType = cell.el.tagName.toLowerCase();
8525
+ add: function(where) {
8526
+ if (this.rectify()) {
8527
+ if (where == 'below' || where == 'above') {
8528
+ this.addRow(where);
8529
+ }
8530
+ if (where == 'before' || where == 'after') {
8531
+ this.addColumn(where);
8532
+ }
8533
+ }
8534
+ },
8543
8535
 
8544
- // defines add cell vs expand cell conditions
8545
- // true means add
8546
- switch (where) {
8547
- case "before":
8548
- doAdd = (!cell.isColspan || cell.firstCol);
8549
- break;
8550
- case "after":
8551
- doAdd = (!cell.isColspan || cell.lastCol || (cell.isColspan && c.el == this.cell));
8552
- break;
8553
- }
8536
+ addColCell: function (cell, ridx, where) {
8537
+ var doAdd,
8538
+ cType = cell.el.tagName.toLowerCase();
8554
8539
 
8555
- if (doAdd){
8556
- // adds a cell before or after current cell element
8557
- switch (where) {
8558
- case "before":
8559
- cell.el.parentNode.insertBefore(this.createCells(cType, 1), cell.el);
8560
- break;
8561
- case "after":
8562
- insertAfter(cell.el, this.createCells(cType, 1));
8563
- break;
8564
- }
8540
+ // defines add cell vs expand cell conditions
8541
+ // true means add
8542
+ switch (where) {
8543
+ case "before":
8544
+ doAdd = (!cell.isColspan || cell.firstCol);
8545
+ break;
8546
+ case "after":
8547
+ doAdd = (!cell.isColspan || cell.lastCol || (cell.isColspan && c.el == this.cell));
8548
+ break;
8549
+ }
8565
8550
 
8566
- // handles if cell has rowspan
8567
- if (cell.isRowspan) {
8568
- this.handleCellAddWithRowspan(cell, ridx+1, where);
8569
- }
8551
+ if (doAdd){
8552
+ // adds a cell before or after current cell element
8553
+ switch (where) {
8554
+ case "before":
8555
+ cell.el.parentNode.insertBefore(this.createCells(cType, 1), cell.el);
8556
+ break;
8557
+ case "after":
8558
+ insertAfter(cell.el, this.createCells(cType, 1));
8559
+ break;
8560
+ }
8570
8561
 
8571
- } else {
8572
- // expands cell
8573
- cell.el.setAttribute('colspan', parseInt(api.getAttribute(cell.el, 'colspan'), 10) + 1);
8574
- }
8575
- },
8562
+ // handles if cell has rowspan
8563
+ if (cell.isRowspan) {
8564
+ this.handleCellAddWithRowspan(cell, ridx+1, where);
8565
+ }
8576
8566
 
8577
- addColumn: function(where) {
8578
- var row, modCell;
8567
+ } else {
8568
+ // expands cell
8569
+ cell.el.setAttribute('colspan', parseInt(api.getAttribute(cell.el, 'colspan'), 10) + 1);
8570
+ }
8571
+ },
8579
8572
 
8580
- this.setTableMap();
8581
- this.idx = this.getMapIndex(this.cell);
8582
- if (where == "after" && api.getAttribute(this.cell, 'colspan')) {
8583
- this.idx.col = this.idx.col + parseInt(api.getAttribute(this.cell, 'colspan'), 10) - 1;
8584
- }
8573
+ addColumn: function(where) {
8574
+ var row, modCell;
8585
8575
 
8586
- if (this.idx !== false) {
8587
- for (var ridx = 0, rmax = this.map.length; ridx < rmax; ridx++ ) {
8588
- row = this.map[ridx];
8589
- if (row[this.idx.col]) {
8590
- modCell = row[this.idx.col];
8591
- if (!modCell.modified) {
8592
- this.setCellAsModified(modCell);
8593
- this.addColCell(modCell, ridx , where);
8594
- }
8595
- }
8596
- }
8576
+ this.setTableMap();
8577
+ this.idx = this.getMapIndex(this.cell);
8578
+ if (where == "after" && api.getAttribute(this.cell, 'colspan')) {
8579
+ this.idx.col = this.idx.col + parseInt(api.getAttribute(this.cell, 'colspan'), 10) - 1;
8580
+ }
8581
+
8582
+ if (this.idx !== false) {
8583
+ for (var ridx = 0, rmax = this.map.length; ridx < rmax; ridx++ ) {
8584
+ row = this.map[ridx];
8585
+ if (row[this.idx.col]) {
8586
+ modCell = row[this.idx.col];
8587
+ if (!modCell.modified) {
8588
+ this.setCellAsModified(modCell);
8589
+ this.addColCell(modCell, ridx , where);
8597
8590
  }
8598
- },
8591
+ }
8592
+ }
8593
+ }
8594
+ },
8599
8595
 
8600
- handleCellAddWithRowspan: function (cell, ridx, where) {
8601
- var addRowsNr = parseInt(api.getAttribute(this.cell, 'rowspan'), 10) - 1,
8602
- crow = api.getParentElement(cell.el, { query: "tr" }),
8603
- cType = cell.el.tagName.toLowerCase(),
8604
- cidx, temp_r_cells,
8605
- doc = this.table.ownerDocument,
8606
- nrow;
8607
-
8608
- for (var i = 0; i < addRowsNr; i++) {
8609
- cidx = this.correctColIndexForUnreals(this.idx.col, (ridx + i));
8610
- crow = nextNode(crow, 'tr');
8611
- if (crow) {
8612
- if (cidx > 0) {
8613
- switch (where) {
8614
- case "before":
8615
- temp_r_cells = this.getRowCells(crow);
8616
- if (cidx > 0 && this.map[ridx + i][this.idx.col].el != temp_r_cells[cidx] && cidx == temp_r_cells.length - 1) {
8617
- insertAfter(temp_r_cells[cidx], this.createCells(cType, 1));
8618
- } else {
8619
- temp_r_cells[cidx].parentNode.insertBefore(this.createCells(cType, 1), temp_r_cells[cidx]);
8620
- }
8596
+ handleCellAddWithRowspan: function (cell, ridx, where) {
8597
+ var addRowsNr = parseInt(api.getAttribute(this.cell, 'rowspan'), 10) - 1,
8598
+ crow = api.getParentElement(cell.el, { query: "tr" }),
8599
+ cType = cell.el.tagName.toLowerCase(),
8600
+ cidx, temp_r_cells,
8601
+ doc = this.table.ownerDocument,
8602
+ nrow;
8621
8603
 
8622
- break;
8623
- case "after":
8624
- insertAfter(this.getRowCells(crow)[cidx], this.createCells(cType, 1));
8625
- break;
8626
- }
8627
- } else {
8628
- crow.insertBefore(this.createCells(cType, 1), crow.firstChild);
8629
- }
8604
+ for (var i = 0; i < addRowsNr; i++) {
8605
+ cidx = this.correctColIndexForUnreals(this.idx.col, (ridx + i));
8606
+ crow = nextNode(crow, 'tr');
8607
+ if (crow) {
8608
+ if (cidx > 0) {
8609
+ switch (where) {
8610
+ case "before":
8611
+ temp_r_cells = this.getRowCells(crow);
8612
+ if (cidx > 0 && this.map[ridx + i][this.idx.col].el != temp_r_cells[cidx] && cidx == temp_r_cells.length - 1) {
8613
+ insertAfter(temp_r_cells[cidx], this.createCells(cType, 1));
8630
8614
  } else {
8631
- nrow = doc.createElement('tr');
8632
- nrow.appendChild(this.createCells(cType, 1));
8633
- this.table.appendChild(nrow);
8615
+ temp_r_cells[cidx].parentNode.insertBefore(this.createCells(cType, 1), temp_r_cells[cidx]);
8634
8616
  }
8617
+
8618
+ break;
8619
+ case "after":
8620
+ insertAfter(this.getRowCells(crow)[cidx], this.createCells(cType, 1));
8621
+ break;
8635
8622
  }
8623
+ } else {
8624
+ crow.insertBefore(this.createCells(cType, 1), crow.firstChild);
8625
+ }
8626
+ } else {
8627
+ nrow = doc.createElement('tr');
8628
+ nrow.appendChild(this.createCells(cType, 1));
8629
+ this.table.appendChild(nrow);
8636
8630
  }
8637
- };
8638
-
8639
- api.table = {
8640
- getCellsBetween: function(cell1, cell2) {
8641
- var c1 = new TableModifyerByCell(cell1);
8642
- return c1.getMapElsTo(cell2);
8643
- },
8644
-
8645
- addCells: function(cell, where) {
8646
- var c = new TableModifyerByCell(cell);
8647
- c.add(where);
8648
- },
8631
+ }
8632
+ }
8633
+ };
8649
8634
 
8650
- removeCells: function(cell, what) {
8651
- var c = new TableModifyerByCell(cell);
8652
- c.remove(what);
8653
- },
8635
+ api.table = {
8636
+ getCellsBetween: function(cell1, cell2) {
8637
+ var c1 = new TableModifyerByCell(cell1);
8638
+ return c1.getMapElsTo(cell2);
8639
+ },
8654
8640
 
8655
- mergeCellsBetween: function(cell1, cell2) {
8656
- var c1 = new TableModifyerByCell(cell1);
8657
- c1.merge(cell2);
8658
- },
8641
+ addCells: function(cell, where) {
8642
+ var c = new TableModifyerByCell(cell);
8643
+ c.add(where);
8644
+ },
8659
8645
 
8660
- unmergeCell: function(cell) {
8661
- var c = new TableModifyerByCell(cell);
8662
- c.unmerge();
8663
- },
8646
+ removeCells: function(cell, what) {
8647
+ var c = new TableModifyerByCell(cell);
8648
+ c.remove(what);
8649
+ },
8664
8650
 
8665
- orderSelectionEnds: function(cell, cell2) {
8666
- var c = new TableModifyerByCell(cell);
8667
- return c.orderSelectionEnds(cell2);
8668
- },
8651
+ mergeCellsBetween: function(cell1, cell2) {
8652
+ var c1 = new TableModifyerByCell(cell1);
8653
+ c1.merge(cell2);
8654
+ },
8669
8655
 
8670
- indexOf: function(cell) {
8671
- var c = new TableModifyerByCell(cell);
8672
- c.setTableMap();
8673
- return c.getMapIndex(cell);
8674
- },
8656
+ unmergeCell: function(cell) {
8657
+ var c = new TableModifyerByCell(cell);
8658
+ c.unmerge();
8659
+ },
8675
8660
 
8676
- findCell: function(table, idx) {
8677
- var c = new TableModifyerByCell(null, table);
8678
- return c.getElementAtIndex(idx);
8679
- },
8661
+ orderSelectionEnds: function(cell, cell2) {
8662
+ var c = new TableModifyerByCell(cell);
8663
+ return c.orderSelectionEnds(cell2);
8664
+ },
8680
8665
 
8681
- findRowByCell: function(cell) {
8682
- var c = new TableModifyerByCell(cell);
8683
- return c.getRowElementsByCell();
8684
- },
8666
+ indexOf: function(cell) {
8667
+ var c = new TableModifyerByCell(cell);
8668
+ c.setTableMap();
8669
+ return c.getMapIndex(cell);
8670
+ },
8685
8671
 
8686
- findColumnByCell: function(cell) {
8687
- var c = new TableModifyerByCell(cell);
8688
- return c.getColumnElementsByCell();
8689
- },
8672
+ findCell: function(table, idx) {
8673
+ var c = new TableModifyerByCell(null, table);
8674
+ return c.getElementAtIndex(idx);
8675
+ },
8690
8676
 
8691
- canMerge: function(cell1, cell2) {
8692
- var c = new TableModifyerByCell(cell1);
8693
- return c.canMerge(cell2);
8694
- }
8695
- };
8677
+ findRowByCell: function(cell) {
8678
+ var c = new TableModifyerByCell(cell);
8679
+ return c.getRowElementsByCell();
8680
+ },
8696
8681
 
8682
+ findColumnByCell: function(cell) {
8683
+ var c = new TableModifyerByCell(cell);
8684
+ return c.getColumnElementsByCell();
8685
+ },
8697
8686
 
8687
+ canMerge: function(cell1, cell2) {
8688
+ var c = new TableModifyerByCell(cell1);
8689
+ return c.canMerge(cell2);
8690
+ }
8691
+ };
8698
8692
 
8699
8693
  })(wysihtml5);
8700
8694
  ;// does a selector query on element or array of elements
8701
-
8702
8695
  wysihtml5.dom.query = function(elements, query) {
8703
8696
  var ret = [],
8704
8697
  q;
@@ -8795,7 +8788,8 @@ wysihtml5.dom.unwrap = function(node) {
8795
8788
  node.parentNode.removeChild(node);
8796
8789
  }
8797
8790
  return children;
8798
- };;/*
8791
+ };
8792
+ ;/*
8799
8793
  * Methods for fetching pasted html before it gets inserted into content
8800
8794
  **/
8801
8795
 
@@ -8819,28 +8813,40 @@ wysihtml5.dom.getPastedHtml = function(event) {
8819
8813
  wysihtml5.dom.getPastedHtmlWithDiv = function (composer, f) {
8820
8814
  var selBookmark = composer.selection.getBookmark(),
8821
8815
  doc = composer.element.ownerDocument,
8822
- cleanerDiv = doc.createElement('DIV');
8816
+ cleanerDiv = doc.createElement('DIV'),
8817
+ scrollPos = composer.getScrollPos();
8823
8818
 
8824
8819
  doc.body.appendChild(cleanerDiv);
8825
8820
 
8826
8821
  cleanerDiv.style.width = "1px";
8827
8822
  cleanerDiv.style.height = "1px";
8828
8823
  cleanerDiv.style.overflow = "hidden";
8824
+ cleanerDiv.style.position = "absolute";
8825
+ cleanerDiv.style.top = scrollPos.y + "px";
8826
+ cleanerDiv.style.left = scrollPos.x + "px";
8829
8827
 
8830
8828
  cleanerDiv.setAttribute('contenteditable', 'true');
8831
8829
  cleanerDiv.focus();
8832
8830
 
8833
8831
  setTimeout(function () {
8832
+ var html;
8833
+
8834
8834
  composer.selection.setBookmark(selBookmark);
8835
- f(cleanerDiv.innerHTML);
8835
+ html = cleanerDiv.innerHTML;
8836
+ if (html && (/^<br\/?>$/i).test(html.trim())) {
8837
+ html = false;
8838
+ }
8839
+ f(html);
8836
8840
  cleanerDiv.parentNode.removeChild(cleanerDiv);
8837
8841
  }, 0);
8838
- };;wysihtml5.dom.removeInvisibleSpaces = function(node) {
8842
+ };
8843
+ ;wysihtml5.dom.removeInvisibleSpaces = function(node) {
8839
8844
  var textNodes = wysihtml5.dom.getTextNodes(node);
8840
8845
  for (var n = textNodes.length; n--;) {
8841
8846
  textNodes[n].nodeValue = textNodes[n].nodeValue.replace(wysihtml5.INVISIBLE_SPACE_REG_EXP, "");
8842
8847
  }
8843
- };;/**
8848
+ };
8849
+ ;/**
8844
8850
  * Fix most common html formatting misbehaviors of browsers implementation when inserting
8845
8851
  * content via copy & paste contentEditable
8846
8852
  *
@@ -8916,7 +8922,8 @@ wysihtml5.quirks.cleanPastedHTML = (function() {
8916
8922
  return newHtml;
8917
8923
  };
8918
8924
 
8919
- })();;/**
8925
+ })();
8926
+ ;/**
8920
8927
  * IE and Opera leave an empty paragraph in the contentEditable element after clearing it
8921
8928
  *
8922
8929
  * @param {Object} contentEditableElement The contentEditable element to observe for clearing events
@@ -8994,119 +9001,119 @@ wysihtml5.quirks.ensureProperClearing = (function() {
8994
9001
  })(wysihtml5);
8995
9002
  ;wysihtml5.quirks.tableCellsSelection = function(editable, editor) {
8996
9003
 
8997
- var dom = wysihtml5.dom,
8998
- select = {
8999
- table: null,
9000
- start: null,
9001
- end: null,
9002
- cells: null,
9003
- select: selectCells
9004
- },
9005
- selection_class = "wysiwyg-tmp-selected-cell";
9004
+ var dom = wysihtml5.dom,
9005
+ select = {
9006
+ table: null,
9007
+ start: null,
9008
+ end: null,
9009
+ cells: null,
9010
+ select: selectCells
9011
+ },
9012
+ selection_class = "wysiwyg-tmp-selected-cell";
9013
+
9014
+ function init () {
9015
+ editable.addEventListener("mousedown", handleMouseDown);
9016
+ return select;
9017
+ }
9006
9018
 
9007
- function init () {
9008
- editable.addEventListener("mousedown", handleMouseDown);
9009
- return select;
9019
+ var handleMouseDown = function(event) {
9020
+ var target = wysihtml5.dom.getParentElement(event.target, { query: "td, th" });
9021
+ if (target) {
9022
+ handleSelectionMousedown(target);
9010
9023
  }
9024
+ };
9011
9025
 
9012
- var handleMouseDown = function(event) {
9013
- var target = wysihtml5.dom.getParentElement(event.target, { query: "td, th" });
9014
- if (target) {
9015
- handleSelectionMousedown(target);
9016
- }
9017
- };
9018
-
9019
- function handleSelectionMousedown (target) {
9020
- select.start = target;
9021
- select.end = target;
9022
- select.cells = [target];
9023
- select.table = dom.getParentElement(select.start, { query: "table" });
9026
+ function handleSelectionMousedown (target) {
9027
+ select.start = target;
9028
+ select.end = target;
9029
+ select.cells = [target];
9030
+ select.table = dom.getParentElement(select.start, { query: "table" });
9024
9031
 
9025
- if (select.table) {
9026
- removeCellSelections();
9027
- dom.addClass(target, selection_class);
9028
- editable.addEventListener("mousemove", handleMouseMove);
9029
- editable.addEventListener("mouseup", handleMouseUp);
9030
- editor.fire("tableselectstart").fire("tableselectstart:composer");
9031
- }
9032
+ if (select.table) {
9033
+ removeCellSelections();
9034
+ dom.addClass(target, selection_class);
9035
+ editable.addEventListener("mousemove", handleMouseMove);
9036
+ editable.addEventListener("mouseup", handleMouseUp);
9037
+ editor.fire("tableselectstart").fire("tableselectstart:composer");
9032
9038
  }
9039
+ }
9033
9040
 
9034
- // remove all selection classes
9035
- function removeCellSelections () {
9036
- if (editable) {
9037
- var selectedCells = editable.querySelectorAll('.' + selection_class);
9038
- if (selectedCells.length > 0) {
9039
- for (var i = 0; i < selectedCells.length; i++) {
9040
- dom.removeClass(selectedCells[i], selection_class);
9041
- }
9042
- }
9041
+ // remove all selection classes
9042
+ function removeCellSelections () {
9043
+ if (editable) {
9044
+ var selectedCells = editable.querySelectorAll('.' + selection_class);
9045
+ if (selectedCells.length > 0) {
9046
+ for (var i = 0; i < selectedCells.length; i++) {
9047
+ dom.removeClass(selectedCells[i], selection_class);
9043
9048
  }
9049
+ }
9044
9050
  }
9051
+ }
9045
9052
 
9046
- function addSelections (cells) {
9047
- for (var i = 0; i < cells.length; i++) {
9048
- dom.addClass(cells[i], selection_class);
9049
- }
9053
+ function addSelections (cells) {
9054
+ for (var i = 0; i < cells.length; i++) {
9055
+ dom.addClass(cells[i], selection_class);
9050
9056
  }
9057
+ }
9051
9058
 
9052
- function handleMouseMove (event) {
9053
- var curTable = null,
9054
- cell = dom.getParentElement(event.target, { query: "td, th" }),
9055
- oldEnd;
9059
+ function handleMouseMove (event) {
9060
+ var curTable = null,
9061
+ cell = dom.getParentElement(event.target, { query: "td, th" }),
9062
+ oldEnd;
9056
9063
 
9057
- if (cell && select.table && select.start) {
9058
- curTable = dom.getParentElement(cell, { query: "table" });
9059
- if (curTable && curTable === select.table) {
9060
- removeCellSelections();
9061
- oldEnd = select.end;
9062
- select.end = cell;
9063
- select.cells = dom.table.getCellsBetween(select.start, cell);
9064
- if (select.cells.length > 1) {
9065
- editor.composer.selection.deselect();
9066
- }
9067
- addSelections(select.cells);
9068
- if (select.end !== oldEnd) {
9069
- editor.fire("tableselectchange").fire("tableselectchange:composer");
9070
- }
9064
+ if (cell && select.table && select.start) {
9065
+ curTable = dom.getParentElement(cell, { query: "table" });
9066
+ if (curTable && curTable === select.table) {
9067
+ removeCellSelections();
9068
+ oldEnd = select.end;
9069
+ select.end = cell;
9070
+ select.cells = dom.table.getCellsBetween(select.start, cell);
9071
+ if (select.cells.length > 1) {
9072
+ editor.composer.selection.deselect();
9073
+ }
9074
+ addSelections(select.cells);
9075
+ if (select.end !== oldEnd) {
9076
+ editor.fire("tableselectchange").fire("tableselectchange:composer");
9071
9077
  }
9072
9078
  }
9073
9079
  }
9080
+ }
9074
9081
 
9075
- function handleMouseUp (event) {
9076
- editable.removeEventListener("mousemove", handleMouseMove);
9077
- editable.removeEventListener("mouseup", handleMouseUp);
9078
- editor.fire("tableselect").fire("tableselect:composer");
9079
- setTimeout(function() {
9080
- bindSideclick();
9081
- },0);
9082
- }
9083
-
9084
- var sideClickHandler = function(event) {
9085
- editable.ownerDocument.removeEventListener("click", sideClickHandler);
9086
- if (dom.getParentElement(event.target, { query: "table" }) != select.table) {
9087
- removeCellSelections();
9088
- select.table = null;
9089
- select.start = null;
9090
- select.end = null;
9091
- editor.fire("tableunselect").fire("tableunselect:composer");
9092
- }
9093
- };
9082
+ function handleMouseUp (event) {
9083
+ editable.removeEventListener("mousemove", handleMouseMove);
9084
+ editable.removeEventListener("mouseup", handleMouseUp);
9085
+ editor.fire("tableselect").fire("tableselect:composer");
9086
+ setTimeout(function() {
9087
+ bindSideclick();
9088
+ },0);
9089
+ }
9094
9090
 
9095
- function bindSideclick () {
9096
- editable.ownerDocument.addEventListener("click", sideClickHandler);
9091
+ var sideClickHandler = function(event) {
9092
+ editable.ownerDocument.removeEventListener("click", sideClickHandler);
9093
+ if (dom.getParentElement(event.target, { query: "table" }) != select.table) {
9094
+ removeCellSelections();
9095
+ select.table = null;
9096
+ select.start = null;
9097
+ select.end = null;
9098
+ editor.fire("tableunselect").fire("tableunselect:composer");
9097
9099
  }
9100
+ };
9098
9101
 
9099
- function selectCells (start, end) {
9100
- select.start = start;
9101
- select.end = end;
9102
- select.table = dom.getParentElement(select.start, { query: "table" });
9103
- selectedCells = dom.table.getCellsBetween(select.start, select.end);
9104
- addSelections(selectedCells);
9105
- bindSideclick();
9106
- editor.fire("tableselect").fire("tableselect:composer");
9107
- }
9102
+ function bindSideclick () {
9103
+ editable.ownerDocument.addEventListener("click", sideClickHandler);
9104
+ }
9108
9105
 
9109
- return init();
9106
+ function selectCells (start, end) {
9107
+ select.start = start;
9108
+ select.end = end;
9109
+ select.table = dom.getParentElement(select.start, { query: "table" });
9110
+ selectedCells = dom.table.getCellsBetween(select.start, select.end);
9111
+ addSelections(selectedCells);
9112
+ bindSideclick();
9113
+ editor.fire("tableselect").fire("tableselect:composer");
9114
+ }
9115
+
9116
+ return init();
9110
9117
 
9111
9118
  };
9112
9119
  ;(function(wysihtml5) {
@@ -9257,6 +9264,7 @@ wysihtml5.quirks.ensureProperClearing = (function() {
9257
9264
  this.editor = editor;
9258
9265
  this.composer = editor.composer;
9259
9266
  this.doc = this.composer.doc;
9267
+ this.win = this.composer.win;
9260
9268
  this.contain = contain;
9261
9269
  this.unselectableClass = unselectableClass || false;
9262
9270
  },
@@ -9370,38 +9378,55 @@ wysihtml5.quirks.ensureProperClearing = (function() {
9370
9378
  * @param {Object} node The element or text node where to position the caret in front of
9371
9379
  * @example
9372
9380
  * selection.setBefore(myElement);
9381
+ * callback is an optional parameter accepting a function to execute when selection ahs been set
9373
9382
  */
9374
- setAfter: function(node, notVisual) {
9383
+ setAfter: function(node, notVisual, callback) {
9375
9384
  var range = rangy.createRange(this.doc),
9376
- originalScrollTop = this.doc.documentElement.scrollTop || this.doc.body.scrollTop || this.doc.defaultView.pageYOffset,
9377
- originalScrollLeft = this.doc.documentElement.scrollLeft || this.doc.body.scrollLeft || this.doc.defaultView.pageXOffset,
9385
+ fixWebkitSelection = function() {
9386
+ // Webkit fails to add selection if there are no textnodes in that region
9387
+ // (like an uneditable container at the end of content).
9388
+ if (!sel) {
9389
+ if (notVisual) {
9390
+ // If setAfter is used as internal between actions, self-removing caretPlaceholder has simpler implementation
9391
+ // and remove itself in call stack end instead on user interaction
9392
+ var caretPlaceholder = this.doc.createTextNode(wysihtml5.INVISIBLE_SPACE);
9393
+ node.parentNode.insertBefore(caretPlaceholder, node.nextSibling);
9394
+ this.selectNode(caretPlaceholder);
9395
+ setTimeout(function() {
9396
+ if (caretPlaceholder && caretPlaceholder.parentNode) {
9397
+ caretPlaceholder.parentNode.removeChild(caretPlaceholder);
9398
+ }
9399
+ }, 0);
9400
+ } else {
9401
+ this.createTemporaryCaretSpaceAfter(node);
9402
+ }
9403
+ }
9404
+ },
9378
9405
  sel;
9379
9406
 
9380
9407
  range.setStartAfter(node);
9381
9408
  range.setEndAfter(node);
9382
- this.composer.element.focus();
9383
- this.doc.defaultView.scrollTo(originalScrollLeft, originalScrollTop);
9384
- sel = this.setSelection(range);
9385
9409
 
9386
- // Webkit fails to add selection if there are no textnodes in that region
9387
- // (like an uneditable container at the end of content).
9388
- if (!sel) {
9389
- if (notVisual) {
9390
- // If setAfter is used as internal between actions, self-removing caretPlaceholder has simpler implementation
9391
- // and remove itself in call stack end instead on user interaction
9392
- var caretPlaceholder = this.doc.createTextNode(wysihtml5.INVISIBLE_SPACE);
9393
- node.parentNode.insertBefore(caretPlaceholder, node.nextSibling);
9394
- this.selectNode(caretPlaceholder);
9395
- setTimeout(function() {
9396
- if (caretPlaceholder && caretPlaceholder.parentNode) {
9397
- caretPlaceholder.parentNode.removeChild(caretPlaceholder);
9398
- }
9399
- }, 0);
9400
- } else {
9401
- this.createTemporaryCaretSpaceAfter(node);
9410
+ // In IE contenteditable must be focused before we can set selection
9411
+ // thus setting the focus if activeElement is not this composer
9412
+ if (!document.activeElement || document.activeElement !== this.composer.element) {
9413
+ var scrollPos = this.composer.getScrollPos();
9414
+ this.composer.element.focus();
9415
+ this.composer.setScrollPos(scrollPos);
9416
+ setTimeout(function() {
9417
+ sel = this.setSelection(range);
9418
+ fixWebkitSelection();
9419
+ if (callback) {
9420
+ callback(sel);
9421
+ }
9422
+ }.bind(this), 0);
9423
+ } else {
9424
+ sel = this.setSelection(range);
9425
+ fixWebkitSelection();
9426
+ if (callback) {
9427
+ callback(sel);
9402
9428
  }
9403
9429
  }
9404
- return sel;
9405
9430
  },
9406
9431
 
9407
9432
  /**
@@ -9704,9 +9729,7 @@ wysihtml5.quirks.ensureProperClearing = (function() {
9704
9729
 
9705
9730
  // TODO: Figure out a method from following 2 that would work universally
9706
9731
  executeAndRestoreRangy: function(method, restoreScrollPosition) {
9707
- var win = this.doc.defaultView || this.doc.parentWindow,
9708
- sel = rangy.saveSelection(win);
9709
-
9732
+ var sel = rangy.saveSelection(this.win);
9710
9733
  if (!sel) {
9711
9734
  method();
9712
9735
  } else {
@@ -9988,8 +10011,7 @@ wysihtml5.quirks.ensureProperClearing = (function() {
9988
10011
  * See https://developer.mozilla.org/en/DOM/Selection/modify
9989
10012
  */
9990
10013
  _selectLine_W3C: function() {
9991
- var win = this.doc.defaultView,
9992
- selection = win.getSelection();
10014
+ var selection = this.win.getSelection();
9993
10015
  selection.modify("move", "left", "lineboundary");
9994
10016
  selection.modify("extend", "right", "lineboundary");
9995
10017
  },
@@ -9998,8 +10020,7 @@ wysihtml5.quirks.ensureProperClearing = (function() {
9998
10020
  toLineBoundary: function (location, collapse) {
9999
10021
  collapse = (typeof collapse === 'undefined') ? false : collapse;
10000
10022
  if (wysihtml5.browser.supportsSelectionModify()) {
10001
- var win = this.doc.defaultView,
10002
- selection = win.getSelection();
10023
+ var selection = this.win.getSelection();
10003
10024
 
10004
10025
  selection.modify("extend", location, "lineboundary");
10005
10026
  if (collapse) {
@@ -10139,50 +10160,49 @@ wysihtml5.quirks.ensureProperClearing = (function() {
10139
10160
  if (r) { ranges.push(r); }
10140
10161
 
10141
10162
  if (this.unselectableClass && this.contain && r) {
10142
- var uneditables = this.getOwnUneditables(),
10143
- tmpRange;
10144
- if (uneditables.length > 0) {
10145
- for (var i = 0, imax = uneditables.length; i < imax; i++) {
10146
- tmpRanges = [];
10147
- for (var j = 0, jmax = ranges.length; j < jmax; j++) {
10148
- if (ranges[j]) {
10149
- switch (ranges[j].compareNode(uneditables[i])) {
10150
- case 2:
10151
- // all selection inside uneditable. remove
10152
- break;
10153
- case 3:
10154
- //section begins before and ends after uneditable. spilt
10155
- tmpRange = ranges[j].cloneRange();
10156
- tmpRange.setEndBefore(uneditables[i]);
10157
- tmpRanges.push(tmpRange);
10158
-
10159
- tmpRange = ranges[j].cloneRange();
10160
- tmpRange.setStartAfter(uneditables[i]);
10161
- tmpRanges.push(tmpRange);
10162
- break;
10163
- default:
10164
- // in all other cases uneditable does not touch selection. dont modify
10165
- tmpRanges.push(ranges[j]);
10166
- }
10163
+ var uneditables = this.getOwnUneditables(),
10164
+ tmpRange;
10165
+ if (uneditables.length > 0) {
10166
+ for (var i = 0, imax = uneditables.length; i < imax; i++) {
10167
+ tmpRanges = [];
10168
+ for (var j = 0, jmax = ranges.length; j < jmax; j++) {
10169
+ if (ranges[j]) {
10170
+ switch (ranges[j].compareNode(uneditables[i])) {
10171
+ case 2:
10172
+ // all selection inside uneditable. remove
10173
+ break;
10174
+ case 3:
10175
+ //section begins before and ends after uneditable. spilt
10176
+ tmpRange = ranges[j].cloneRange();
10177
+ tmpRange.setEndBefore(uneditables[i]);
10178
+ tmpRanges.push(tmpRange);
10179
+
10180
+ tmpRange = ranges[j].cloneRange();
10181
+ tmpRange.setStartAfter(uneditables[i]);
10182
+ tmpRanges.push(tmpRange);
10183
+ break;
10184
+ default:
10185
+ // in all other cases uneditable does not touch selection. dont modify
10186
+ tmpRanges.push(ranges[j]);
10167
10187
  }
10168
- ranges = tmpRanges;
10169
10188
  }
10189
+ ranges = tmpRanges;
10170
10190
  }
10171
10191
  }
10192
+ }
10172
10193
  }
10173
10194
  return ranges;
10174
10195
  },
10175
10196
 
10176
10197
  getSelection: function() {
10177
- return rangy.getSelection(this.doc.defaultView || this.doc.parentWindow);
10198
+ return rangy.getSelection(this.win);
10178
10199
  },
10179
10200
 
10180
10201
  // Sets selection in document to a given range
10181
10202
  // Set selection method detects if it fails to set any selection in document and returns null on fail
10182
10203
  // (especially needed in webkit where some ranges just can not create selection for no reason)
10183
10204
  setSelection: function(range) {
10184
- var win = this.doc.defaultView || this.doc.parentWindow,
10185
- selection = rangy.getSelection(win);
10205
+ var selection = rangy.getSelection(this.win);
10186
10206
  selection.setSingleRange(range);
10187
10207
  return (selection && selection.anchorNode && selection.focusNode) ? selection : null;
10188
10208
  },
@@ -10620,24 +10640,24 @@ wysihtml5.quirks.ensureProperClearing = (function() {
10620
10640
  },
10621
10641
 
10622
10642
  getAdjacentMergeableTextNode: function(node, forward) {
10623
- var isTextNode = (node.nodeType == wysihtml5.TEXT_NODE);
10624
- var el = isTextNode ? node.parentNode : node;
10625
- var adjacentNode;
10626
- var propName = forward ? "nextSibling" : "previousSibling";
10627
- if (isTextNode) {
10628
- // Can merge if the node's previous/next sibling is a text node
10629
- adjacentNode = node[propName];
10630
- if (adjacentNode && adjacentNode.nodeType == wysihtml5.TEXT_NODE) {
10631
- return adjacentNode;
10632
- }
10633
- } else {
10634
- // Compare element with its sibling
10635
- adjacentNode = el[propName];
10636
- if (adjacentNode && this.areElementsMergeable(node, adjacentNode)) {
10637
- return adjacentNode[forward ? "firstChild" : "lastChild"];
10638
- }
10643
+ var isTextNode = (node.nodeType == wysihtml5.TEXT_NODE);
10644
+ var el = isTextNode ? node.parentNode : node;
10645
+ var adjacentNode;
10646
+ var propName = forward ? "nextSibling" : "previousSibling";
10647
+ if (isTextNode) {
10648
+ // Can merge if the node's previous/next sibling is a text node
10649
+ adjacentNode = node[propName];
10650
+ if (adjacentNode && adjacentNode.nodeType == wysihtml5.TEXT_NODE) {
10651
+ return adjacentNode;
10639
10652
  }
10640
- return null;
10653
+ } else {
10654
+ // Compare element with its sibling
10655
+ adjacentNode = el[propName];
10656
+ if (adjacentNode && this.areElementsMergeable(node, adjacentNode)) {
10657
+ return adjacentNode[forward ? "firstChild" : "lastChild"];
10658
+ }
10659
+ }
10660
+ return null;
10641
10661
  },
10642
10662
 
10643
10663
  areElementsMergeable: function(el1, el2) {
@@ -10715,83 +10735,83 @@ wysihtml5.quirks.ensureProperClearing = (function() {
10715
10735
  },
10716
10736
 
10717
10737
  applyToRange: function(range) {
10718
- var textNodes;
10719
- for (var ri = range.length; ri--;) {
10720
- textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);
10721
-
10722
- if (!textNodes.length) {
10723
- try {
10724
- var node = this.createContainer(range[ri].endContainer.ownerDocument);
10725
- range[ri].surroundContents(node);
10726
- this.selectNode(range[ri], node);
10727
- return;
10728
- } catch(e) {}
10729
- }
10730
-
10731
- range[ri].splitBoundaries();
10732
- textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);
10733
- if (textNodes.length) {
10734
- var textNode;
10738
+ var textNodes;
10739
+ for (var ri = range.length; ri--;) {
10740
+ textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);
10735
10741
 
10736
- for (var i = 0, len = textNodes.length; i < len; ++i) {
10737
- textNode = textNodes[i];
10738
- if (!this.getMatchingAncestor(textNode).element) {
10739
- this.applyToTextNode(textNode);
10740
- }
10741
- }
10742
+ if (!textNodes.length) {
10743
+ try {
10744
+ var node = this.createContainer(range[ri].endContainer.ownerDocument);
10745
+ range[ri].surroundContents(node);
10746
+ this.selectNode(range[ri], node);
10747
+ return;
10748
+ } catch(e) {}
10749
+ }
10742
10750
 
10743
- range[ri].setStart(textNodes[0], 0);
10744
- textNode = textNodes[textNodes.length - 1];
10745
- range[ri].setEnd(textNode, textNode.length);
10751
+ range[ri].splitBoundaries();
10752
+ textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);
10753
+ if (textNodes.length) {
10754
+ var textNode;
10746
10755
 
10747
- if (this.normalize) {
10748
- this.postApply(textNodes, range[ri]);
10749
- }
10756
+ for (var i = 0, len = textNodes.length; i < len; ++i) {
10757
+ textNode = textNodes[i];
10758
+ if (!this.getMatchingAncestor(textNode).element) {
10759
+ this.applyToTextNode(textNode);
10750
10760
  }
10761
+ }
10762
+
10763
+ range[ri].setStart(textNodes[0], 0);
10764
+ textNode = textNodes[textNodes.length - 1];
10765
+ range[ri].setEnd(textNode, textNode.length);
10751
10766
 
10767
+ if (this.normalize) {
10768
+ this.postApply(textNodes, range[ri]);
10769
+ }
10752
10770
  }
10771
+
10772
+ }
10753
10773
  },
10754
10774
 
10755
10775
  undoToRange: function(range) {
10756
10776
  var textNodes, textNode, ancestorWithClass, ancestorWithStyle, ancestor;
10757
10777
  for (var ri = range.length; ri--;) {
10758
10778
 
10779
+ textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);
10780
+ if (textNodes.length) {
10781
+ range[ri].splitBoundaries();
10759
10782
  textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);
10760
- if (textNodes.length) {
10761
- range[ri].splitBoundaries();
10762
- textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);
10763
- } else {
10764
- var doc = range[ri].endContainer.ownerDocument,
10765
- node = doc.createTextNode(wysihtml5.INVISIBLE_SPACE);
10766
- range[ri].insertNode(node);
10767
- range[ri].selectNode(node);
10768
- textNodes = [node];
10769
- }
10783
+ } else {
10784
+ var doc = range[ri].endContainer.ownerDocument,
10785
+ node = doc.createTextNode(wysihtml5.INVISIBLE_SPACE);
10786
+ range[ri].insertNode(node);
10787
+ range[ri].selectNode(node);
10788
+ textNodes = [node];
10789
+ }
10770
10790
 
10771
- for (var i = 0, len = textNodes.length; i < len; ++i) {
10772
- if (range[ri].isValid()) {
10773
- textNode = textNodes[i];
10774
-
10775
- ancestor = this.getMatchingAncestor(textNode);
10776
- if (ancestor.type === "style") {
10777
- this.undoToTextNode(textNode, range[ri], false, ancestor.element);
10778
- } else if (ancestor.element) {
10779
- this.undoToTextNode(textNode, range[ri], ancestor.element);
10780
- }
10791
+ for (var i = 0, len = textNodes.length; i < len; ++i) {
10792
+ if (range[ri].isValid()) {
10793
+ textNode = textNodes[i];
10794
+
10795
+ ancestor = this.getMatchingAncestor(textNode);
10796
+ if (ancestor.type === "style") {
10797
+ this.undoToTextNode(textNode, range[ri], false, ancestor.element);
10798
+ } else if (ancestor.element) {
10799
+ this.undoToTextNode(textNode, range[ri], ancestor.element);
10781
10800
  }
10782
10801
  }
10802
+ }
10783
10803
 
10784
- if (len == 1) {
10785
- this.selectNode(range[ri], textNodes[0]);
10786
- } else {
10787
- range[ri].setStart(textNodes[0], 0);
10788
- textNode = textNodes[textNodes.length - 1];
10789
- range[ri].setEnd(textNode, textNode.length);
10804
+ if (len == 1) {
10805
+ this.selectNode(range[ri], textNodes[0]);
10806
+ } else {
10807
+ range[ri].setStart(textNodes[0], 0);
10808
+ textNode = textNodes[textNodes.length - 1];
10809
+ range[ri].setEnd(textNode, textNode.length);
10790
10810
 
10791
- if (this.normalize) {
10792
- this.postApply(textNodes, range[ri]);
10793
- }
10811
+ if (this.normalize) {
10812
+ this.postApply(textNodes, range[ri]);
10794
10813
  }
10814
+ }
10795
10815
 
10796
10816
  }
10797
10817
  },
@@ -10998,21 +11018,22 @@ wysihtml5.Commands = Base.extend(
10998
11018
  }
10999
11019
  }
11000
11020
  });
11001
- ;wysihtml5.commands.bold = {
11002
- exec: function(composer, command) {
11003
- wysihtml5.commands.formatInline.execWithToggle(composer, command, "b");
11004
- },
11005
-
11006
- state: function(composer, command) {
11007
- // element.ownerDocument.queryCommandState("bold") results:
11008
- // firefox: only <b>
11009
- // chrome: <b>, <strong>, <h1>, <h2>, ...
11010
- // ie: <b>, <strong>
11011
- // opera: <b>, <strong>
11012
- return wysihtml5.commands.formatInline.state(composer, command, "b");
11013
- }
11014
- };
11021
+ ;(function(wysihtml5){
11022
+ wysihtml5.commands.bold = {
11023
+ exec: function(composer, command) {
11024
+ wysihtml5.commands.formatInline.execWithToggle(composer, command, "b");
11025
+ },
11015
11026
 
11027
+ state: function(composer, command) {
11028
+ // element.ownerDocument.queryCommandState("bold") results:
11029
+ // firefox: only <b>
11030
+ // chrome: <b>, <strong>, <h1>, <h2>, ...
11031
+ // ie: <b>, <strong>
11032
+ // opera: <b>, <strong>
11033
+ return wysihtml5.commands.formatInline.state(composer, command, "b");
11034
+ }
11035
+ };
11036
+ }(wysihtml5));
11016
11037
  ;(function(wysihtml5) {
11017
11038
  var undef,
11018
11039
  NODE_NAME = "A",
@@ -11185,7 +11206,7 @@ wysihtml5.Commands = Base.extend(
11185
11206
 
11186
11207
  wysihtml5.commands.fontSize = {
11187
11208
  exec: function(composer, command, size) {
11188
- wysihtml5.commands.formatInline.execWithToggle(composer, command, "span", "wysiwyg-font-size-" + size, REG_EXP);
11209
+ wysihtml5.commands.formatInline.execWithToggle(composer, command, "span", "wysiwyg-font-size-" + size, REG_EXP);
11189
11210
  },
11190
11211
 
11191
11212
  state: function(composer, command, size) {
@@ -11237,7 +11258,7 @@ wysihtml5.Commands = Base.extend(
11237
11258
 
11238
11259
  wysihtml5.commands.foreColor = {
11239
11260
  exec: function(composer, command, color) {
11240
- wysihtml5.commands.formatInline.execWithToggle(composer, command, "span", "wysiwyg-color-" + color, REG_EXP);
11261
+ wysihtml5.commands.formatInline.execWithToggle(composer, command, "span", "wysiwyg-color-" + color, REG_EXP);
11241
11262
  },
11242
11263
 
11243
11264
  state: function(composer, command, color) {
@@ -11624,7 +11645,7 @@ wysihtml5.Commands = Base.extend(
11624
11645
  if (options && options.toggle) {
11625
11646
  state = this.state(composer, command, options);
11626
11647
  if (state) {
11627
- bookmark = rangy.saveSelection(composer.doc.defaultView || composer.doc.parentWindow);
11648
+ bookmark = rangy.saveSelection(composer.win);
11628
11649
  for (var j in state) {
11629
11650
  removeOptionsFromElement(state[j], options, composer);
11630
11651
  }
@@ -11639,12 +11660,12 @@ wysihtml5.Commands = Base.extend(
11639
11660
  query: BLOCK_ELEMENTS
11640
11661
  }, null, composer.element);
11641
11662
  if (parent) {
11642
- bookmark = rangy.saveSelection(composer.doc.defaultView || composer.doc.parentWindow);
11663
+ bookmark = rangy.saveSelection(composer.win);
11643
11664
  range = composer.selection.createRange();
11644
11665
  range.selectNode(parent);
11645
11666
  composer.selection.setSelection(range);
11646
11667
  } else if (!composer.isEmpty()) {
11647
- bookmark = rangy.saveSelection(composer.doc.defaultView || composer.doc.parentWindow);
11668
+ bookmark = rangy.saveSelection(composer.win);
11648
11669
  composer.selection.selectLine();
11649
11670
  }
11650
11671
  }
@@ -11700,7 +11721,6 @@ wysihtml5.Commands = Base.extend(
11700
11721
  return (nodes.length === 0) ? false : nodes;
11701
11722
  }
11702
11723
 
11703
-
11704
11724
  };
11705
11725
  })(wysihtml5);
11706
11726
  ;/* Formats block for as a <pre><code class="classname"></code></pre> block
@@ -11711,48 +11731,51 @@ wysihtml5.Commands = Base.extend(
11711
11731
  * editorInstance.composer.commands.exec("formatCode", "language-html");
11712
11732
  */
11713
11733
 
11714
- wysihtml5.commands.formatCode = {
11734
+ (function(wysihtml5){
11735
+ wysihtml5.commands.formatCode = {
11715
11736
 
11716
- exec: function(composer, command, classname) {
11717
- var pre = this.state(composer),
11718
- code, range, selectedNodes;
11719
- if (pre) {
11720
- // caret is already within a <pre><code>...</code></pre>
11721
- composer.selection.executeAndRestore(function() {
11722
- code = pre.querySelector("code");
11723
- wysihtml5.dom.replaceWithChildNodes(pre);
11724
- if (code) {
11725
- wysihtml5.dom.replaceWithChildNodes(code);
11737
+ exec: function(composer, command, classname) {
11738
+ var pre = this.state(composer),
11739
+ code, range, selectedNodes;
11740
+ if (pre) {
11741
+ // caret is already within a <pre><code>...</code></pre>
11742
+ composer.selection.executeAndRestore(function() {
11743
+ code = pre.querySelector("code");
11744
+ wysihtml5.dom.replaceWithChildNodes(pre);
11745
+ if (code) {
11746
+ wysihtml5.dom.replaceWithChildNodes(code);
11747
+ }
11748
+ });
11749
+ } else {
11750
+ // Wrap in <pre><code>...</code></pre>
11751
+ range = composer.selection.getRange();
11752
+ selectedNodes = range.extractContents();
11753
+ pre = composer.doc.createElement("pre");
11754
+ code = composer.doc.createElement("code");
11755
+
11756
+ if (classname) {
11757
+ code.className = classname;
11726
11758
  }
11727
- });
11728
- } else {
11729
- // Wrap in <pre><code>...</code></pre>
11730
- range = composer.selection.getRange();
11731
- selectedNodes = range.extractContents();
11732
- pre = composer.doc.createElement("pre");
11733
- code = composer.doc.createElement("code");
11734
11759
 
11735
- if (classname) {
11736
- code.className = classname;
11760
+ pre.appendChild(code);
11761
+ code.appendChild(selectedNodes);
11762
+ range.insertNode(pre);
11763
+ composer.selection.selectNode(pre);
11737
11764
  }
11765
+ },
11738
11766
 
11739
- pre.appendChild(code);
11740
- code.appendChild(selectedNodes);
11741
- range.insertNode(pre);
11742
- composer.selection.selectNode(pre);
11743
- }
11744
- },
11745
-
11746
- state: function(composer) {
11747
- var selectedNode = composer.selection.getSelectedNode();
11748
- if (selectedNode && selectedNode.nodeName && selectedNode.nodeName == "PRE"&&
11749
- selectedNode.firstChild && selectedNode.firstChild.nodeName && selectedNode.firstChild.nodeName == "CODE") {
11750
- return selectedNode;
11751
- } else {
11752
- return wysihtml5.dom.getParentElement(selectedNode, { query: "pre code" });
11767
+ state: function(composer) {
11768
+ var selectedNode = composer.selection.getSelectedNode();
11769
+ if (selectedNode && selectedNode.nodeName && selectedNode.nodeName == "PRE"&&
11770
+ selectedNode.firstChild && selectedNode.firstChild.nodeName && selectedNode.firstChild.nodeName == "CODE") {
11771
+ return selectedNode;
11772
+ } else {
11773
+ return wysihtml5.dom.getParentElement(selectedNode, { query: "pre code" });
11774
+ }
11753
11775
  }
11754
- }
11755
- };;/**
11776
+ };
11777
+ }(wysihtml5));
11778
+ ;/**
11756
11779
  * formatInline scenarios for tag "B" (| = caret, |foo| = selected text)
11757
11780
  *
11758
11781
  * #1 caret in unformatted text:
@@ -11920,19 +11943,21 @@ wysihtml5.commands.formatCode = {
11920
11943
  };
11921
11944
 
11922
11945
  })(wysihtml5);
11923
- ;wysihtml5.commands.insertHTML = {
11924
- exec: function(composer, command, html) {
11925
- if (composer.commands.support(command)) {
11926
- composer.doc.execCommand(command, false, html);
11927
- } else {
11928
- composer.selection.insertHTML(html);
11929
- }
11930
- },
11946
+ ;(function(wysihtml5){
11947
+ wysihtml5.commands.insertHTML = {
11948
+ exec: function(composer, command, html) {
11949
+ if (composer.commands.support(command)) {
11950
+ composer.doc.execCommand(command, false, html);
11951
+ } else {
11952
+ composer.selection.insertHTML(html);
11953
+ }
11954
+ },
11931
11955
 
11932
- state: function() {
11933
- return false;
11934
- }
11935
- };
11956
+ state: function() {
11957
+ return false;
11958
+ }
11959
+ };
11960
+ }(wysihtml5));
11936
11961
  ;(function(wysihtml5) {
11937
11962
  var NODE_NAME = "IMG";
11938
11963
 
@@ -12062,24 +12087,28 @@ wysihtml5.commands.formatCode = {
12062
12087
  }
12063
12088
  };
12064
12089
  })(wysihtml5);
12065
- ;wysihtml5.commands.insertOrderedList = {
12066
- exec: function(composer, command) {
12067
- wysihtml5.commands.insertList.exec(composer, command, "OL");
12068
- },
12090
+ ;(function(wysihtml5){
12091
+ wysihtml5.commands.insertOrderedList = {
12092
+ exec: function(composer, command) {
12093
+ wysihtml5.commands.insertList.exec(composer, command, "OL");
12094
+ },
12069
12095
 
12070
- state: function(composer, command) {
12071
- return wysihtml5.commands.insertList.state(composer, command, "OL");
12072
- }
12073
- };
12074
- ;wysihtml5.commands.insertUnorderedList = {
12075
- exec: function(composer, command) {
12076
- wysihtml5.commands.insertList.exec(composer, command, "UL");
12077
- },
12096
+ state: function(composer, command) {
12097
+ return wysihtml5.commands.insertList.state(composer, command, "OL");
12098
+ }
12099
+ };
12100
+ }(wysihtml5));
12101
+ ;(function(wysihtml5){
12102
+ wysihtml5.commands.insertUnorderedList = {
12103
+ exec: function(composer, command) {
12104
+ wysihtml5.commands.insertList.exec(composer, command, "UL");
12105
+ },
12078
12106
 
12079
- state: function(composer, command) {
12080
- return wysihtml5.commands.insertList.state(composer, command, "UL");
12081
- }
12082
- };
12107
+ state: function(composer, command) {
12108
+ return wysihtml5.commands.insertList.state(composer, command, "UL");
12109
+ }
12110
+ };
12111
+ }(wysihtml5));
12083
12112
  ;wysihtml5.commands.insertList = (function(wysihtml5) {
12084
12113
 
12085
12114
  var isNode = function(node, name) {
@@ -12196,10 +12225,10 @@ wysihtml5.commands.formatCode = {
12196
12225
  }),
12197
12226
  isEmpty, list;
12198
12227
 
12199
- // This space causes new lists to never break on enter
12228
+ // This space causes new lists to never break on enter
12200
12229
  var INVISIBLE_SPACE_REG_EXP = /\uFEFF/g;
12201
12230
  tempElement.innerHTML = tempElement.innerHTML.replace(wysihtml5.INVISIBLE_SPACE_REG_EXP, "");
12202
-
12231
+
12203
12232
  if (tempElement) {
12204
12233
  isEmpty = wysihtml5.lang.array(["", "<br>", wysihtml5.INVISIBLE_SPACE]).contains(tempElement.innerHTML);
12205
12234
  list = wysihtml5.dom.convertToList(tempElement, nodeName.toLowerCase(), composer.parent.config.uneditableContainerClassname);
@@ -12217,7 +12246,7 @@ wysihtml5.commands.formatCode = {
12217
12246
  selectedNode = composer.selection.getSelectedNode(),
12218
12247
  list = findListEl(selectedNode, nodeName, composer);
12219
12248
 
12220
- if (!list.el) {
12249
+ if (!list.el) {
12221
12250
  if (composer.commands.support(cmd)) {
12222
12251
  doc.execCommand(cmd, false, null);
12223
12252
  } else {
@@ -12238,20 +12267,23 @@ wysihtml5.commands.formatCode = {
12238
12267
  }
12239
12268
  };
12240
12269
 
12241
- })(wysihtml5);;wysihtml5.commands.italic = {
12242
- exec: function(composer, command) {
12243
- wysihtml5.commands.formatInline.execWithToggle(composer, command, "i");
12244
- },
12270
+ })(wysihtml5);
12271
+ ;(function(wysihtml5){
12272
+ wysihtml5.commands.italic = {
12273
+ exec: function(composer, command) {
12274
+ wysihtml5.commands.formatInline.execWithToggle(composer, command, "i");
12275
+ },
12245
12276
 
12246
- state: function(composer, command) {
12247
- // element.ownerDocument.queryCommandState("italic") results:
12248
- // firefox: only <i>
12249
- // chrome: <i>, <em>, <blockquote>, ...
12250
- // ie: <i>, <em>
12251
- // opera: only <i>
12252
- return wysihtml5.commands.formatInline.state(composer, command, "i");
12253
- }
12254
- };
12277
+ state: function(composer, command) {
12278
+ // element.ownerDocument.queryCommandState("italic") results:
12279
+ // firefox: only <i>
12280
+ // chrome: <i>, <em>, <blockquote>, ...
12281
+ // ie: <i>, <em>
12282
+ // opera: only <i>
12283
+ return wysihtml5.commands.formatInline.state(composer, command, "i");
12284
+ }
12285
+ };
12286
+ }(wysihtml5));
12255
12287
  ;(function(wysihtml5) {
12256
12288
 
12257
12289
  var nodeOptions = {
@@ -12381,272 +12413,312 @@ wysihtml5.commands.formatCode = {
12381
12413
  };
12382
12414
 
12383
12415
  })(wysihtml5);
12384
- ;wysihtml5.commands.redo = {
12385
- exec: function(composer) {
12386
- return composer.undoManager.redo();
12387
- },
12416
+ ;(function(wysihtml5){
12417
+ wysihtml5.commands.redo = {
12418
+ exec: function(composer) {
12419
+ return composer.undoManager.redo();
12420
+ },
12388
12421
 
12389
- state: function(composer) {
12390
- return false;
12391
- }
12392
- };
12393
- ;wysihtml5.commands.underline = {
12394
- exec: function(composer, command) {
12395
- wysihtml5.commands.formatInline.execWithToggle(composer, command, "u");
12396
- },
12422
+ state: function(composer) {
12423
+ return false;
12424
+ }
12425
+ };
12426
+ }(wysihtml5));
12427
+ ;(function(wysihtml5){
12428
+ wysihtml5.commands.underline = {
12429
+ exec: function(composer, command) {
12430
+ wysihtml5.commands.formatInline.execWithToggle(composer, command, "u");
12431
+ },
12397
12432
 
12398
- state: function(composer, command) {
12399
- return wysihtml5.commands.formatInline.state(composer, command, "u");
12400
- }
12401
- };
12402
- ;wysihtml5.commands.undo = {
12403
- exec: function(composer) {
12404
- return composer.undoManager.undo();
12405
- },
12433
+ state: function(composer, command) {
12434
+ return wysihtml5.commands.formatInline.state(composer, command, "u");
12435
+ }
12436
+ };
12437
+ }(wysihtml5));
12438
+ ;(function(wysihtml5){
12439
+ wysihtml5.commands.undo = {
12440
+ exec: function(composer) {
12441
+ return composer.undoManager.undo();
12442
+ },
12406
12443
 
12407
- state: function(composer) {
12408
- return false;
12409
- }
12410
- };
12411
- ;wysihtml5.commands.createTable = {
12412
- exec: function(composer, command, value) {
12444
+ state: function(composer) {
12445
+ return false;
12446
+ }
12447
+ };
12448
+ }(wysihtml5));
12449
+ ;(function(wysihtml5){
12450
+ wysihtml5.commands.createTable = {
12451
+ exec: function(composer, command, value) {
12413
12452
  var col, row, html;
12414
12453
  if (value && value.cols && value.rows && parseInt(value.cols, 10) > 0 && parseInt(value.rows, 10) > 0) {
12415
- if (value.tableStyle) {
12416
- html = "<table style=\"" + value.tableStyle + "\">";
12417
- } else {
12418
- html = "<table>";
12419
- }
12420
- html += "<tbody>";
12421
- for (row = 0; row < value.rows; row ++) {
12422
- html += '<tr>';
12423
- for (col = 0; col < value.cols; col ++) {
12424
- html += "<td>&nbsp;</td>";
12425
- }
12426
- html += '</tr>';
12454
+ if (value.tableStyle) {
12455
+ html = "<table style=\"" + value.tableStyle + "\">";
12456
+ } else {
12457
+ html = "<table>";
12458
+ }
12459
+ html += "<tbody>";
12460
+ for (row = 0; row < value.rows; row ++) {
12461
+ html += '<tr>';
12462
+ for (col = 0; col < value.cols; col ++) {
12463
+ html += "<td>&nbsp;</td>";
12427
12464
  }
12428
- html += "</tbody></table>";
12429
- composer.commands.exec("insertHTML", html);
12430
- //composer.selection.insertHTML(html);
12465
+ html += '</tr>';
12466
+ }
12467
+ html += "</tbody></table>";
12468
+ composer.commands.exec("insertHTML", html);
12469
+ //composer.selection.insertHTML(html);
12431
12470
  }
12471
+ },
12432
12472
 
12433
-
12434
- },
12435
-
12436
- state: function(composer, command) {
12473
+ state: function(composer, command) {
12437
12474
  return false;
12438
- }
12439
- };
12440
- ;wysihtml5.commands.mergeTableCells = {
12441
- exec: function(composer, command) {
12475
+ }
12476
+ };
12477
+
12478
+ }(wysihtml5));
12479
+ ;(function(wysihtml5){
12480
+ wysihtml5.commands.mergeTableCells = {
12481
+ exec: function(composer, command) {
12442
12482
  if (composer.tableSelection && composer.tableSelection.start && composer.tableSelection.end) {
12443
- if (this.state(composer, command)) {
12444
- wysihtml5.dom.table.unmergeCell(composer.tableSelection.start);
12445
- } else {
12446
- wysihtml5.dom.table.mergeCellsBetween(composer.tableSelection.start, composer.tableSelection.end);
12447
- }
12483
+ if (this.state(composer, command)) {
12484
+ wysihtml5.dom.table.unmergeCell(composer.tableSelection.start);
12485
+ } else {
12486
+ wysihtml5.dom.table.mergeCellsBetween(composer.tableSelection.start, composer.tableSelection.end);
12487
+ }
12448
12488
  }
12449
- },
12489
+ },
12450
12490
 
12451
- state: function(composer, command) {
12491
+ state: function(composer, command) {
12452
12492
  if (composer.tableSelection) {
12453
- var start = composer.tableSelection.start,
12454
- end = composer.tableSelection.end;
12455
- if (start && end && start == end &&
12456
- ((
12457
- wysihtml5.dom.getAttribute(start, "colspan") &&
12458
- parseInt(wysihtml5.dom.getAttribute(start, "colspan"), 10) > 1
12459
- ) || (
12460
- wysihtml5.dom.getAttribute(start, "rowspan") &&
12461
- parseInt(wysihtml5.dom.getAttribute(start, "rowspan"), 10) > 1
12462
- ))
12463
- ) {
12464
- return [start];
12465
- }
12493
+ var start = composer.tableSelection.start,
12494
+ end = composer.tableSelection.end;
12495
+ if (start && end && start == end &&
12496
+ ((
12497
+ wysihtml5.dom.getAttribute(start, "colspan") &&
12498
+ parseInt(wysihtml5.dom.getAttribute(start, "colspan"), 10) > 1
12499
+ ) || (
12500
+ wysihtml5.dom.getAttribute(start, "rowspan") &&
12501
+ parseInt(wysihtml5.dom.getAttribute(start, "rowspan"), 10) > 1
12502
+ ))
12503
+ ) {
12504
+ return [start];
12505
+ }
12466
12506
  }
12467
12507
  return false;
12468
- }
12469
- };
12470
- ;wysihtml5.commands.addTableCells = {
12471
- exec: function(composer, command, value) {
12508
+ }
12509
+ };
12510
+ }(wysihtml5));
12511
+ ;(function(wysihtml5){
12512
+ wysihtml5.commands.addTableCells = {
12513
+ exec: function(composer, command, value) {
12472
12514
  if (composer.tableSelection && composer.tableSelection.start && composer.tableSelection.end) {
12473
12515
 
12474
- // switches start and end if start is bigger than end (reverse selection)
12475
- var tableSelect = wysihtml5.dom.table.orderSelectionEnds(composer.tableSelection.start, composer.tableSelection.end);
12476
- if (value == "before" || value == "above") {
12477
- wysihtml5.dom.table.addCells(tableSelect.start, value);
12478
- } else if (value == "after" || value == "below") {
12479
- wysihtml5.dom.table.addCells(tableSelect.end, value);
12480
- }
12481
- setTimeout(function() {
12482
- composer.tableSelection.select(tableSelect.start, tableSelect.end);
12483
- },0);
12516
+ // switches start and end if start is bigger than end (reverse selection)
12517
+ var tableSelect = wysihtml5.dom.table.orderSelectionEnds(composer.tableSelection.start, composer.tableSelection.end);
12518
+ if (value == "before" || value == "above") {
12519
+ wysihtml5.dom.table.addCells(tableSelect.start, value);
12520
+ } else if (value == "after" || value == "below") {
12521
+ wysihtml5.dom.table.addCells(tableSelect.end, value);
12522
+ }
12523
+ setTimeout(function() {
12524
+ composer.tableSelection.select(tableSelect.start, tableSelect.end);
12525
+ },0);
12484
12526
  }
12485
- },
12527
+ },
12486
12528
 
12487
- state: function(composer, command) {
12529
+ state: function(composer, command) {
12488
12530
  return false;
12489
- }
12490
- };
12491
- ;wysihtml5.commands.deleteTableCells = {
12531
+ }
12532
+ };
12533
+ }(wysihtml5));
12534
+ ;(function(wysihtml5){
12535
+ wysihtml5.commands.deleteTableCells = {
12492
12536
  exec: function(composer, command, value) {
12493
- if (composer.tableSelection && composer.tableSelection.start && composer.tableSelection.end) {
12494
- var tableSelect = wysihtml5.dom.table.orderSelectionEnds(composer.tableSelection.start, composer.tableSelection.end),
12495
- idx = wysihtml5.dom.table.indexOf(tableSelect.start),
12496
- selCell,
12497
- table = composer.tableSelection.table;
12498
-
12499
- wysihtml5.dom.table.removeCells(tableSelect.start, value);
12500
- setTimeout(function() {
12501
- // move selection to next or previous if not present
12502
- selCell = wysihtml5.dom.table.findCell(table, idx);
12503
-
12504
- if (!selCell){
12505
- if (value == "row") {
12506
- selCell = wysihtml5.dom.table.findCell(table, {
12507
- "row": idx.row - 1,
12508
- "col": idx.col
12509
- });
12510
- }
12511
-
12512
- if (value == "column") {
12513
- selCell = wysihtml5.dom.table.findCell(table, {
12514
- "row": idx.row,
12515
- "col": idx.col - 1
12516
- });
12517
- }
12518
- }
12519
- if (selCell) {
12520
- composer.tableSelection.select(selCell, selCell);
12521
- }
12522
- }, 0);
12537
+ if (composer.tableSelection && composer.tableSelection.start && composer.tableSelection.end) {
12538
+ var tableSelect = wysihtml5.dom.table.orderSelectionEnds(composer.tableSelection.start, composer.tableSelection.end),
12539
+ idx = wysihtml5.dom.table.indexOf(tableSelect.start),
12540
+ selCell,
12541
+ table = composer.tableSelection.table;
12523
12542
 
12524
- }
12525
- },
12543
+ wysihtml5.dom.table.removeCells(tableSelect.start, value);
12544
+ setTimeout(function() {
12545
+ // move selection to next or previous if not present
12546
+ selCell = wysihtml5.dom.table.findCell(table, idx);
12547
+
12548
+ if (!selCell){
12549
+ if (value == "row") {
12550
+ selCell = wysihtml5.dom.table.findCell(table, {
12551
+ "row": idx.row - 1,
12552
+ "col": idx.col
12553
+ });
12554
+ }
12526
12555
 
12527
- state: function(composer, command) {
12528
- return false;
12529
- }
12530
- };
12531
- ;wysihtml5.commands.indentList = {
12532
- exec: function(composer, command, value) {
12533
- var listEls = composer.selection.getSelectionParentsByTag('LI');
12534
- if (listEls) {
12535
- return this.tryToPushLiLevel(listEls, composer.selection);
12556
+ if (value == "column") {
12557
+ selCell = wysihtml5.dom.table.findCell(table, {
12558
+ "row": idx.row,
12559
+ "col": idx.col - 1
12560
+ });
12561
+ }
12562
+ }
12563
+ if (selCell) {
12564
+ composer.tableSelection.select(selCell, selCell);
12565
+ }
12566
+ }, 0);
12536
12567
  }
12537
- return false;
12538
12568
  },
12539
12569
 
12540
12570
  state: function(composer, command) {
12571
+ return false;
12572
+ }
12573
+ };
12574
+ }(wysihtml5));
12575
+ ;(function(wysihtml5){
12576
+ wysihtml5.commands.indentList = {
12577
+ exec: function(composer, command, value) {
12578
+ var listEls = composer.selection.getSelectionParentsByTag('LI');
12579
+ if (listEls) {
12580
+ return this.tryToPushLiLevel(listEls, composer.selection);
12581
+ }
12541
12582
  return false;
12542
- },
12583
+ },
12543
12584
 
12544
- tryToPushLiLevel: function(liNodes, selection) {
12545
- var listTag, list, prevLi, liNode, prevLiList,
12546
- found = false;
12585
+ state: function(composer, command) {
12586
+ return false;
12587
+ },
12547
12588
 
12548
- selection.executeAndRestoreRangy(function() {
12589
+ tryToPushLiLevel: function(liNodes, selection) {
12590
+ var listTag, list, prevLi, liNode, prevLiList,
12591
+ found = false;
12549
12592
 
12550
- for (var i = liNodes.length; i--;) {
12551
- liNode = liNodes[i];
12552
- listTag = (liNode.parentNode.nodeName === 'OL') ? 'OL' : 'UL';
12553
- list = liNode.ownerDocument.createElement(listTag);
12554
- prevLi = wysihtml5.dom.domNode(liNode).prev({nodeTypes: [wysihtml5.ELEMENT_NODE]});
12555
- prevLiList = (prevLi) ? prevLi.querySelector('ul, ol') : null;
12593
+ selection.executeAndRestoreRangy(function() {
12556
12594
 
12557
- if (prevLi) {
12558
- if (prevLiList) {
12559
- prevLiList.appendChild(liNode);
12560
- } else {
12561
- list.appendChild(liNode);
12562
- prevLi.appendChild(list);
12595
+ for (var i = liNodes.length; i--;) {
12596
+ liNode = liNodes[i];
12597
+ listTag = (liNode.parentNode.nodeName === 'OL') ? 'OL' : 'UL';
12598
+ list = liNode.ownerDocument.createElement(listTag);
12599
+ prevLi = wysihtml5.dom.domNode(liNode).prev({nodeTypes: [wysihtml5.ELEMENT_NODE]});
12600
+ prevLiList = (prevLi) ? prevLi.querySelector('ul, ol') : null;
12601
+
12602
+ if (prevLi) {
12603
+ if (prevLiList) {
12604
+ prevLiList.appendChild(liNode);
12605
+ } else {
12606
+ list.appendChild(liNode);
12607
+ prevLi.appendChild(list);
12608
+ }
12609
+ found = true;
12563
12610
  }
12564
- found = true;
12565
12611
  }
12566
- }
12567
12612
 
12568
- });
12569
- return found;
12570
- }
12571
- };
12572
- ;wysihtml5.commands.outdentList = {
12573
- exec: function(composer, command, value) {
12574
- var listEls = composer.selection.getSelectionParentsByTag('LI');
12575
- if (listEls) {
12576
- return this.tryToPullLiLevel(listEls, composer);
12613
+ });
12614
+ return found;
12577
12615
  }
12578
- return false;
12579
- },
12616
+ };
12617
+ }(wysihtml5));
12618
+ ;(function(wysihtml5){
12580
12619
 
12581
- state: function(composer, command) {
12620
+ wysihtml5.commands.outdentList = {
12621
+ exec: function(composer, command, value) {
12622
+ var listEls = composer.selection.getSelectionParentsByTag('LI');
12623
+ if (listEls) {
12624
+ return this.tryToPullLiLevel(listEls, composer);
12625
+ }
12582
12626
  return false;
12583
- },
12627
+ },
12584
12628
 
12585
- tryToPullLiLevel: function(liNodes, composer) {
12586
- var listNode, outerListNode, outerLiNode, list, prevLi, liNode, afterList,
12587
- found = false,
12588
- that = this;
12629
+ state: function(composer, command) {
12630
+ return false;
12631
+ },
12589
12632
 
12590
- composer.selection.executeAndRestoreRangy(function() {
12633
+ tryToPullLiLevel: function(liNodes, composer) {
12634
+ var listNode, outerListNode, outerLiNode, list, prevLi, liNode, afterList,
12635
+ found = false,
12636
+ that = this;
12591
12637
 
12592
- for (var i = liNodes.length; i--;) {
12593
- liNode = liNodes[i];
12594
- if (liNode.parentNode) {
12595
- listNode = liNode.parentNode;
12638
+ composer.selection.executeAndRestoreRangy(function() {
12596
12639
 
12597
- if (listNode.tagName === 'OL' || listNode.tagName === 'UL') {
12598
- found = true;
12640
+ for (var i = liNodes.length; i--;) {
12641
+ liNode = liNodes[i];
12642
+ if (liNode.parentNode) {
12643
+ listNode = liNode.parentNode;
12599
12644
 
12600
- outerListNode = wysihtml5.dom.getParentElement(listNode.parentNode, { query: 'ol, ul' }, false, composer.element);
12601
- outerLiNode = wysihtml5.dom.getParentElement(listNode.parentNode, { query: 'li' }, false, composer.element);
12645
+ if (listNode.tagName === 'OL' || listNode.tagName === 'UL') {
12646
+ found = true;
12602
12647
 
12603
- if (outerListNode && outerLiNode) {
12648
+ outerListNode = wysihtml5.dom.getParentElement(listNode.parentNode, { query: 'ol, ul' }, false, composer.element);
12649
+ outerLiNode = wysihtml5.dom.getParentElement(listNode.parentNode, { query: 'li' }, false, composer.element);
12604
12650
 
12605
- if (liNode.nextSibling) {
12606
- afterList = that.getAfterList(listNode, liNode);
12607
- liNode.appendChild(afterList);
12608
- }
12609
- outerListNode.insertBefore(liNode, outerLiNode.nextSibling);
12651
+ if (outerListNode && outerLiNode) {
12610
12652
 
12611
- } else {
12653
+ if (liNode.nextSibling) {
12654
+ afterList = that.getAfterList(listNode, liNode);
12655
+ liNode.appendChild(afterList);
12656
+ }
12657
+ outerListNode.insertBefore(liNode, outerLiNode.nextSibling);
12612
12658
 
12613
- if (liNode.nextSibling) {
12614
- afterList = that.getAfterList(listNode, liNode);
12615
- liNode.appendChild(afterList);
12616
- }
12659
+ } else {
12617
12660
 
12618
- for (var j = liNode.childNodes.length; j--;) {
12619
- listNode.parentNode.insertBefore(liNode.childNodes[j], listNode.nextSibling);
12620
- }
12661
+ if (liNode.nextSibling) {
12662
+ afterList = that.getAfterList(listNode, liNode);
12663
+ liNode.appendChild(afterList);
12664
+ }
12621
12665
 
12622
- listNode.parentNode.insertBefore(document.createElement('br'), listNode.nextSibling);
12623
- liNode.parentNode.removeChild(liNode);
12666
+ for (var j = liNode.childNodes.length; j--;) {
12667
+ listNode.parentNode.insertBefore(liNode.childNodes[j], listNode.nextSibling);
12668
+ }
12624
12669
 
12625
- }
12670
+ listNode.parentNode.insertBefore(document.createElement('br'), listNode.nextSibling);
12671
+ liNode.parentNode.removeChild(liNode);
12626
12672
 
12627
- // cleanup
12628
- if (listNode.childNodes.length === 0) {
12629
- listNode.parentNode.removeChild(listNode);
12673
+ }
12674
+
12675
+ // cleanup
12676
+ if (listNode.childNodes.length === 0) {
12677
+ listNode.parentNode.removeChild(listNode);
12678
+ }
12630
12679
  }
12631
12680
  }
12632
12681
  }
12633
- }
12634
12682
 
12635
- });
12636
- return found;
12637
- },
12683
+ });
12684
+ return found;
12685
+ },
12638
12686
 
12639
- getAfterList: function(listNode, liNode) {
12640
- var nodeName = listNode.nodeName,
12641
- newList = document.createElement(nodeName);
12687
+ getAfterList: function(listNode, liNode) {
12688
+ var nodeName = listNode.nodeName,
12689
+ newList = document.createElement(nodeName);
12642
12690
 
12643
- while (liNode.nextSibling) {
12644
- newList.appendChild(liNode.nextSibling);
12691
+ while (liNode.nextSibling) {
12692
+ newList.appendChild(liNode.nextSibling);
12693
+ }
12694
+ return newList;
12645
12695
  }
12646
- return newList;
12647
- }
12648
12696
 
12649
- };;/**
12697
+ };
12698
+ }(wysihtml5));
12699
+ ;(function(wysihtml5){
12700
+ wysihtml5.commands.subscript = {
12701
+ exec: function(composer, command) {
12702
+ wysihtml5.commands.formatInline.execWithToggle(composer, command, "sub");
12703
+ },
12704
+
12705
+ state: function(composer, command) {
12706
+ return wysihtml5.commands.formatInline.state(composer, command, "sub");
12707
+ }
12708
+ };
12709
+ }(wysihtml5));
12710
+ ;(function(wysihtml5){
12711
+ wysihtml5.commands.superscript = {
12712
+ exec: function(composer, command) {
12713
+ wysihtml5.commands.formatInline.execWithToggle(composer, command, "sup");
12714
+ },
12715
+
12716
+ state: function(composer, command) {
12717
+ return wysihtml5.commands.formatInline.state(composer, command, "sup");
12718
+ }
12719
+ };
12720
+ }(wysihtml5));
12721
+ ;/**
12650
12722
  * Undo Manager for wysihtml5
12651
12723
  * slightly inspired by http://rniwa.com/editing/undomanager.html#the-undomanager-interface
12652
12724
  */
@@ -12968,7 +13040,7 @@ wysihtml5.views.View = Base.extend(
12968
13040
  cleanUp: function() {
12969
13041
  var bookmark;
12970
13042
  if (this.selection) {
12971
- bookmark = rangy.saveSelection(this.doc.defaultView || this.doc.parentWindow);
13043
+ bookmark = rangy.saveSelection(this.win);
12972
13044
  }
12973
13045
  this.parent.parse(this.element);
12974
13046
  if (bookmark) {
@@ -13024,6 +13096,32 @@ wysihtml5.views.View = Base.extend(
13024
13096
  }
13025
13097
  },
13026
13098
 
13099
+ getScrollPos: function() {
13100
+ if (this.doc && this.win) {
13101
+ var pos = {};
13102
+
13103
+ if (typeof this.win.pageYOffset !== "undefined") {
13104
+ pos.y = this.win.pageYOffset;
13105
+ } else {
13106
+ pos.y = (this.doc.documentElement || this.doc.body.parentNode || this.doc.body).scrollTop;
13107
+ }
13108
+
13109
+ if (typeof this.win.pageXOffset !== "undefined") {
13110
+ pos.x = this.win.pageXOffset;
13111
+ } else {
13112
+ pos.x = (this.doc.documentElement || this.doc.body.parentNode || this.doc.body).scrollLeft;
13113
+ }
13114
+
13115
+ return pos;
13116
+ }
13117
+ },
13118
+
13119
+ setScrollPos: function(pos) {
13120
+ if (pos && typeof pos.x !== "undefined" && typeof pos.y !== "undefined") {
13121
+ this.win.scrollTo(pos.x, pos.y);
13122
+ }
13123
+ },
13124
+
13027
13125
  getTextContent: function() {
13028
13126
  return dom.getTextContent(this.element);
13029
13127
  },
@@ -13089,6 +13187,7 @@ wysihtml5.views.View = Base.extend(
13089
13187
  _create: function() {
13090
13188
  var that = this;
13091
13189
  this.doc = this.sandbox.getDocument();
13190
+ this.win = this.sandbox.getWindow();
13092
13191
  this.element = (this.config.contentEditableMode) ? this.sandbox.getContentEditable() : this.doc.body;
13093
13192
  if (!this.config.noTextarea) {
13094
13193
  this.textarea = this.parent.textarea;
@@ -13628,22 +13727,34 @@ wysihtml5.views.View = Base.extend(
13628
13727
  } else if (selection.caretIsInTheBeginnig()) {
13629
13728
  event.preventDefault();
13630
13729
  } else {
13631
-
13632
13730
  if (selection.caretIsFirstInSelection() &&
13633
13731
  selection.getPreviousNode() &&
13634
13732
  selection.getPreviousNode().nodeName &&
13635
13733
  (/^H\d$/gi).test(selection.getPreviousNode().nodeName)
13636
13734
  ) {
13637
13735
  var prevNode = selection.getPreviousNode();
13638
- event.preventDefault();
13639
13736
  if ((/^\s*$/).test(prevNode.textContent || prevNode.innerText)) {
13640
13737
  // heading is empty
13738
+ event.preventDefault();
13641
13739
  prevNode.parentNode.removeChild(prevNode);
13642
13740
  } else {
13643
- var range = prevNode.ownerDocument.createRange();
13644
- range.selectNodeContents(prevNode);
13645
- range.collapse(false);
13646
- selection.setSelection(range);
13741
+ if (prevNode.lastChild) {
13742
+ var selNode = prevNode.lastChild,
13743
+ curNode = wysihtml5.dom.getParentElement(selection.getSelectedNode(), { query: "h1, h2, h3, h4, h5, h6, p, pre, div, blockquote" }, false, composer.element);
13744
+ if (prevNode) {
13745
+ if (curNode) {
13746
+ event.preventDefault();
13747
+ while (curNode.firstChild) {
13748
+ prevNode.appendChild(curNode.firstChild);
13749
+ }
13750
+ selection.setAfter(selNode);
13751
+ } else if (selection.getSelectedNode().nodeType === 3) {
13752
+ event.preventDefault();
13753
+ prevNode.appendChild(selection.getSelectedNode());
13754
+ selection.setAfter(selNode);
13755
+ }
13756
+ }
13757
+ }
13647
13758
  }
13648
13759
  }
13649
13760
 
@@ -14306,8 +14417,7 @@ wysihtml5.views.View = Base.extend(
14306
14417
  * - Observes for paste and drop
14307
14418
  */
14308
14419
  _initParser: function() {
14309
- var that = this,
14310
- oldHtml,
14420
+ var oldHtml,
14311
14421
  cleanHtml;
14312
14422
 
14313
14423
  if (wysihtml5.browser.supportsModenPaste()) {
@@ -14315,20 +14425,23 @@ wysihtml5.views.View = Base.extend(
14315
14425
  event.preventDefault();
14316
14426
  oldHtml = wysihtml5.dom.getPastedHtml(event);
14317
14427
  if (oldHtml) {
14318
- that._cleanAndPaste(oldHtml);
14428
+ this._cleanAndPaste(oldHtml);
14319
14429
  }
14320
- });
14430
+ }.bind(this));
14321
14431
 
14322
14432
  } else {
14323
14433
  this.on("beforepaste:composer", function(event) {
14324
14434
  event.preventDefault();
14325
- wysihtml5.dom.getPastedHtmlWithDiv(that.composer, function(pastedHTML) {
14435
+ var scrollPos = this.composer.getScrollPos();
14436
+
14437
+ wysihtml5.dom.getPastedHtmlWithDiv(this.composer, function(pastedHTML) {
14326
14438
  if (pastedHTML) {
14327
- that._cleanAndPaste(pastedHTML);
14439
+ this._cleanAndPaste(pastedHTML);
14328
14440
  }
14329
- });
14330
- });
14441
+ this.composer.setScrollPos(scrollPos);
14442
+ }.bind(this));
14331
14443
 
14444
+ }.bind(this));
14332
14445
  }
14333
14446
  },
14334
14447
 
@@ -14968,13 +15081,11 @@ wysihtml5.views.View = Base.extend(
14968
15081
 
14969
15082
  })(wysihtml5);
14970
15083
  ;(function(wysihtml5) {
14971
- wysihtml5.toolbar.Dialog_createTable = wysihtml5.toolbar.Dialog.extend({
14972
- show: function(elementToChange) {
14973
- this.base(elementToChange);
14974
-
14975
- }
14976
-
14977
- });
15084
+ wysihtml5.toolbar.Dialog_createTable = wysihtml5.toolbar.Dialog.extend({
15085
+ show: function(elementToChange) {
15086
+ this.base(elementToChange);
15087
+ }
15088
+ });
14978
15089
  })(wysihtml5);
14979
15090
  ;(function(wysihtml5) {
14980
15091
  var dom = wysihtml5.dom,