wysihtml-rails 0.5.0.beta3 → 0.5.0.beta4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
- }
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);
8354
+ } else {
8355
+ row.insertBefore(cell.el, row.firstChild);
8337
8356
  }
8338
- },
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
+ },
8339
8366
 
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};
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
+ },
8346
8385
 
8347
- if (newRowIdx < this.map.length) {
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
+ },
8348
8400
 
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
- },
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
+ },
8370
8414
 
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
- }
8381
- } 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
- }
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]);
8387
8427
  }
8388
- },
8428
+ }
8429
+ }
8430
+ removeElement(oldRow);
8431
+ }
8432
+ },
8389
8433
 
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
- },
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
+ },
8404
8445
 
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
- },
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
+ },
8418
8458
 
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
- },
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
+ },
8437
8473
 
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);
8447
- }
8448
- },
8474
+ addRow: function(where) {
8475
+ var doc = this.table.ownerDocument;
8449
8476
 
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
- },
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
+ }
8462
8482
 
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
- },
8483
+ if (this.idx !== false) {
8484
+ var modRow = this.map[this.idx.row],
8485
+ newRow = doc.createElement('tr');
8477
8486
 
8478
- addRow: function(where) {
8479
- var doc = this.table.ownerDocument;
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
+ }
8480
8493
 
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;
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);
8485
8502
  }
8503
+ break;
8504
+ }
8505
+ }
8506
+ },
8486
8507
 
8487
- if (this.idx !== false) {
8488
- var modRow = this.map[this.idx.row],
8489
- newRow = doc.createElement('tr');
8490
-
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
- }
8497
-
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
- },
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
+ },
8511
8524
 
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
- }
8526
- }
8527
- },
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
+ },
8528
8535
 
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
- },
8536
+ addColCell: function (cell, ridx, where) {
8537
+ var doAdd,
8538
+ cType = cell.el.tagName.toLowerCase();
8539
8539
 
8540
- addColCell: function (cell, ridx, where) {
8541
- var doAdd,
8542
- cType = cell.el.tagName.toLowerCase();
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
+ }
8543
8550
 
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
- }
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
+ }
8554
8561
 
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
- }
8562
+ // handles if cell has rowspan
8563
+ if (cell.isRowspan) {
8564
+ this.handleCellAddWithRowspan(cell, ridx+1, where);
8565
+ }
8565
8566
 
8566
- // handles if cell has rowspan
8567
- if (cell.isRowspan) {
8568
- this.handleCellAddWithRowspan(cell, ridx+1, where);
8569
- }
8567
+ } else {
8568
+ // expands cell
8569
+ cell.el.setAttribute('colspan', parseInt(api.getAttribute(cell.el, 'colspan'), 10) + 1);
8570
+ }
8571
+ },
8570
8572
 
8571
- } else {
8572
- // expands cell
8573
- cell.el.setAttribute('colspan', parseInt(api.getAttribute(cell.el, 'colspan'), 10) + 1);
8574
- }
8575
- },
8573
+ addColumn: function(where) {
8574
+ var row, modCell;
8576
8575
 
8577
- addColumn: function(where) {
8578
- var row, modCell;
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
+ }
8579
8581
 
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;
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);
8584
8590
  }
8591
+ }
8592
+ }
8593
+ }
8594
+ },
8585
8595
 
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
- }
8597
- }
8598
- },
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;
8599
8603
 
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
- }
8621
-
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
+ }
9105
+
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
+ }
9108
9115
 
9109
- return init();
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 = {
11736
+
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");
11715
11755
 
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);
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
+ },
12584
+
12585
+ state: function(composer, command) {
12586
+ return false;
12587
+ },
12543
12588
 
12544
- tryToPushLiLevel: function(liNodes, selection) {
12545
- var listTag, list, prevLi, liNode, prevLiList,
12546
- found = false;
12589
+ tryToPushLiLevel: function(liNodes, selection) {
12590
+ var listTag, list, prevLi, liNode, prevLiList,
12591
+ found = false;
12547
12592
 
12548
- selection.executeAndRestoreRangy(function() {
12593
+ selection.executeAndRestoreRangy(function() {
12549
12594
 
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;
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;
12556
12601
 
12557
- if (prevLi) {
12558
- if (prevLiList) {
12559
- prevLiList.appendChild(liNode);
12560
- } else {
12561
- list.appendChild(liNode);
12562
- prevLi.appendChild(list);
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
+ }
12665
+
12666
+ for (var j = liNode.childNodes.length; j--;) {
12667
+ listNode.parentNode.insertBefore(liNode.childNodes[j], listNode.nextSibling);
12668
+ }
12621
12669
 
12622
- listNode.parentNode.insertBefore(document.createElement('br'), listNode.nextSibling);
12623
- liNode.parentNode.removeChild(liNode);
12670
+ listNode.parentNode.insertBefore(document.createElement('br'), listNode.nextSibling);
12671
+ liNode.parentNode.removeChild(liNode);
12624
12672
 
12625
- }
12673
+ }
12626
12674
 
12627
- // cleanup
12628
- if (listNode.childNodes.length === 0) {
12629
- listNode.parentNode.removeChild(listNode);
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