wysihtml5x-rails 0.4.9 → 0.4.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b3a2130d7224dcba4c3e6d98a379a394d4154769
4
- data.tar.gz: 652cb61fc14aa44d53cfbcf412015036fe6ec453
3
+ metadata.gz: 19746f9d353549d31664fc824b614eca58acf324
4
+ data.tar.gz: e3905fe82cc05f0801cfe508d0e510ac73591659
5
5
  SHA512:
6
- metadata.gz: 9120a099177dcb0fe653ad639afab5cb188dbb87af2f7c69f4b4c97a049ebbeafd8b255233a87411a335658b789c8c1d95dc17f0207c493fd9aaa9f12cb53c6a
7
- data.tar.gz: 9fe43031a37d2648e2b619db67c06684824c41f2d5435966bffc17df41bcb4b902467ac17ef44a9cc41f50d3f779d052d1a8cc9a394608315cdcb021c3a329c1
6
+ metadata.gz: 051414796cc17ad93affe186b5ee09efdd599eec5751da9f799fc086363c7291514fcb720eacf3e4f2b356bba59be7e389af2bd71f5ed587a9d719b25cf312d4
7
+ data.tar.gz: 4f69dd9cc72de56846c739cd50ddcdf51a2331c981be53938713322de015119a4a7b249e1087c58c09cdb1c44a9c1466b39dc745295e6ae59992ff49cde0f867
@@ -1,5 +1,5 @@
1
1
  module Wysihtml5x
2
2
  module Rails
3
- VERSION = "0.4.9"
3
+ VERSION = "0.4.10"
4
4
  end
5
5
  end
@@ -25,7 +25,7 @@ if(!Array.isArray) {
25
25
  return Object.prototype.toString.call(arg) === '[object Array]';
26
26
  };
27
27
  };/**
28
- * @license wysihtml5x v0.4.9
28
+ * @license wysihtml5x v0.4.10
29
29
  * https://github.com/Edicy/wysihtml5
30
30
  *
31
31
  * Author: Christopher Blum (https://github.com/tiff)
@@ -36,7 +36,7 @@ if(!Array.isArray) {
36
36
  *
37
37
  */
38
38
  var wysihtml5 = {
39
- version: "0.4.9",
39
+ version: "0.4.10",
40
40
 
41
41
  // namespaces
42
42
  commands: {},
@@ -5505,13 +5505,15 @@ wysihtml5.dom.getStyle = (function() {
5505
5505
  };
5506
5506
  };
5507
5507
  })();
5508
- ;wysihtml5.dom.getTextNodes = function(node){
5508
+ ;wysihtml5.dom.getTextNodes = function(node, ingoreEmpty){
5509
5509
  var all = [];
5510
5510
  for (node=node.firstChild;node;node=node.nextSibling){
5511
- if (node.nodeType==3) {
5511
+ if (node.nodeType == 3) {
5512
+ if (!ingoreEmpty || !(/^\s*$/).test(node.innerText || node.textContent)) {
5512
5513
  all.push(node);
5514
+ }
5513
5515
  } else {
5514
- all = all.concat(wysihtml5.dom.getTextNodes(node));
5516
+ all = all.concat(wysihtml5.dom.getTextNodes(node, ingoreEmpty));
5515
5517
  }
5516
5518
  }
5517
5519
  return all;
@@ -8608,6 +8610,12 @@ wysihtml5.quirks.ensureProperClearing = (function() {
8608
8610
  }
8609
8611
  },
8610
8612
 
8613
+ fixSelBorders: function() {
8614
+ var range = this.getRange();
8615
+ expandRangeToSurround(range);
8616
+ this.setSelection(range);
8617
+ },
8618
+
8611
8619
  getSelectedOwnNodes: function(controlRange) {
8612
8620
  var selection,
8613
8621
  ranges = this.getOwnRanges(),
@@ -8726,12 +8734,17 @@ wysihtml5.quirks.ensureProperClearing = (function() {
8726
8734
 
8727
8735
  caretIsFirstInSelection: function() {
8728
8736
  var r = rangy.createRange(this.doc),
8729
- s = this.getSelection();
8730
-
8731
- r.selectNodeContents(this.getRange().commonAncestorContainer);
8732
- r.collapse(true);
8733
-
8734
- return (this.isCollapsed() && (r.startContainer === s.anchorNode || r.endContainer === s.anchorNode) && r.startOffset === s.anchorOffset);
8737
+ s = this.getSelection(),
8738
+ range = this.getRange(),
8739
+ startNode = range.startContainer;
8740
+
8741
+ if (startNode.nodeType === wysihtml5.TEXT_NODE) {
8742
+ return this.isCollapsed() && (startNode.nodeType === wysihtml5.TEXT_NODE && (/^\s*$/).test(startNode.data.substr(0,range.startOffset)));
8743
+ } else {
8744
+ r.selectNodeContents(this.getRange().commonAncestorContainer);
8745
+ r.collapse(true);
8746
+ return (this.isCollapsed() && (r.startContainer === s.anchorNode || r.endContainer === s.anchorNode) && r.startOffset === s.anchorOffset);
8747
+ }
8735
8748
  },
8736
8749
 
8737
8750
  caretIsInTheBeginnig: function(ofNode) {
@@ -9106,8 +9119,8 @@ wysihtml5.quirks.ensureProperClearing = (function() {
9106
9119
  },
9107
9120
 
9108
9121
  _endOffsetForNode: function(node) {
9109
- var range = document.createRange()
9110
- range.selectNodeContents(node)
9122
+ var range = document.createRange();
9123
+ range.selectNodeContents(node);
9111
9124
  return range.endOffset;
9112
9125
  },
9113
9126
 
@@ -9349,6 +9362,25 @@ wysihtml5.quirks.ensureProperClearing = (function() {
9349
9362
  return false;
9350
9363
  }
9351
9364
 
9365
+ function isMatchingAllready(node, tags, style, className) {
9366
+ if (style) {
9367
+ return getMatchingStyleRegexp(node, style);
9368
+ } else if (className) {
9369
+ return wysihtml5.dom.hasClass(node, className);
9370
+ } else {
9371
+ return rangy.dom.arrayContains(tags, node.tagName.toLowerCase());
9372
+ }
9373
+ }
9374
+
9375
+ function areMatchingAllready(nodes, tags, style, className) {
9376
+ for (var i = nodes.length; i--;) {
9377
+ if (!isMatchingAllready(nodes[i], tags, style, className)) {
9378
+ return false;
9379
+ }
9380
+ }
9381
+ return nodes.length ? true : false;
9382
+ }
9383
+
9352
9384
  function removeOrChangeStyle(el, style, regExp) {
9353
9385
 
9354
9386
  var exactRegex = getMatchingStyleRegexp(el, style);
@@ -9372,9 +9404,6 @@ wysihtml5.quirks.ensureProperClearing = (function() {
9372
9404
  while (el.firstChild) {
9373
9405
  parent.insertBefore(el.firstChild, el);
9374
9406
  }
9375
- if (parent.normalize) {
9376
- parent.normalize();
9377
- }
9378
9407
  parent.removeChild(el);
9379
9408
  }
9380
9409
 
@@ -9522,6 +9551,27 @@ wysihtml5.quirks.ensureProperClearing = (function() {
9522
9551
  return false;
9523
9552
  },
9524
9553
 
9554
+ getMatchingAncestor: function(node) {
9555
+ var ancestor = this.getAncestorWithClass(node),
9556
+ matchType = false;
9557
+
9558
+ if (!ancestor) {
9559
+ ancestor = this.getAncestorWithStyle(node);
9560
+ if (ancestor) {
9561
+ matchType = "style";
9562
+ }
9563
+ } else {
9564
+ if (this.cssStyle) {
9565
+ matchType = "class";
9566
+ }
9567
+ }
9568
+
9569
+ return {
9570
+ "element": ancestor,
9571
+ "type": matchType
9572
+ };
9573
+ },
9574
+
9525
9575
  // Normalizes nodes after applying a CSS class to a Range.
9526
9576
  postApply: function(textNodes, range) {
9527
9577
  var firstNode = textNodes[0], lastNode = textNodes[textNodes.length - 1];
@@ -9695,10 +9745,7 @@ wysihtml5.quirks.ensureProperClearing = (function() {
9695
9745
 
9696
9746
  for (var i = 0, len = textNodes.length; i < len; ++i) {
9697
9747
  textNode = textNodes[i];
9698
- if (!this.getAncestorWithClass(textNode)) {
9699
- this.applyToTextNode(textNode);
9700
- }
9701
- if (!this.getAncestorWithStyle(textNode)) {
9748
+ if (!this.getMatchingAncestor(textNode).element) {
9702
9749
  this.applyToTextNode(textNode);
9703
9750
  }
9704
9751
  }
@@ -9717,8 +9764,8 @@ wysihtml5.quirks.ensureProperClearing = (function() {
9717
9764
 
9718
9765
  undoToRange: function(range) {
9719
9766
  var textNodes, textNode, ancestorWithClass, ancestorWithStyle;
9720
-
9721
9767
  for (var ri = range.length; ri--;) {
9768
+
9722
9769
  textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);
9723
9770
  if (textNodes.length) {
9724
9771
  range[ri].splitBoundaries();
@@ -9731,16 +9778,15 @@ wysihtml5.quirks.ensureProperClearing = (function() {
9731
9778
  textNodes = [node];
9732
9779
  }
9733
9780
 
9734
-
9735
9781
  for (var i = 0, len = textNodes.length; i < len; ++i) {
9736
9782
  if (range[ri].isValid()) {
9737
9783
  textNode = textNodes[i];
9738
- ancestorWithClass = this.getAncestorWithClass(textNode);
9739
- ancestorWithStyle = this.getAncestorWithStyle(textNode);
9740
- if (ancestorWithClass) {
9741
- this.undoToTextNode(textNode, range[ri], ancestorWithClass);
9742
- } else if (ancestorWithStyle) {
9743
- this.undoToTextNode(textNode, range[ri], false, ancestorWithStyle);
9784
+
9785
+ ancestor = this.getMatchingAncestor(textNode);
9786
+ if (ancestor.type === "style") {
9787
+ this.undoToTextNode(textNode, range[ri], false, ancestor.element);
9788
+ } else if (ancestor.element) {
9789
+ this.undoToTextNode(textNode, range[ri], ancestor.element);
9744
9790
  }
9745
9791
  }
9746
9792
  }
@@ -9792,38 +9838,65 @@ wysihtml5.quirks.ensureProperClearing = (function() {
9792
9838
 
9793
9839
  isAppliedToRange: function(range) {
9794
9840
  var ancestors = [],
9841
+ appliedType = "full",
9795
9842
  ancestor, styleAncestor, textNodes;
9796
9843
 
9797
9844
  for (var ri = range.length; ri--;) {
9798
9845
 
9799
9846
  textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);
9800
9847
  if (!textNodes.length) {
9801
- ancestor = this.getAncestorWithClass(range[ri].startContainer);
9802
- if (!ancestor) {
9803
- ancestor = this.getAncestorWithStyle(range[ri].startContainer);
9804
- }
9805
- return ancestor ? [ancestor] : false;
9848
+ ancestor = this.getMatchingAncestor(range[ri].startContainer).element;
9849
+
9850
+ return (ancestor) ? {
9851
+ "elements": [ancestor],
9852
+ "coverage": appliedType
9853
+ } : false;
9806
9854
  }
9807
9855
 
9808
9856
  for (var i = 0, len = textNodes.length, selectedText; i < len; ++i) {
9809
9857
  selectedText = this.getTextSelectedByRange(textNodes[i], range[ri]);
9810
- ancestor = this.getAncestorWithClass(textNodes[i]);
9811
- if (!ancestor) {
9812
- ancestor = this.getAncestorWithStyle(textNodes[i]);
9813
- }
9858
+ ancestor = this.getMatchingAncestor(textNodes[i]).element;
9814
9859
  if (ancestor && selectedText != "") {
9815
9860
  ancestors.push(ancestor);
9861
+
9862
+ if (wysihtml5.dom.getTextNodes(ancestor, true).length === 1) {
9863
+ appliedType = "full";
9864
+ } else if (appliedType === "full") {
9865
+ appliedType = "inline";
9866
+ }
9867
+ } else if (!ancestor) {
9868
+ appliedType = "partial";
9816
9869
  }
9817
9870
  }
9818
9871
 
9819
9872
  }
9820
9873
 
9821
- return (ancestors.length) ? ancestors : false;
9874
+ return (ancestors.length) ? {
9875
+ "elements": ancestors,
9876
+ "coverage": appliedType
9877
+ } : false;
9822
9878
  },
9823
9879
 
9824
9880
  toggleRange: function(range) {
9825
- if (this.isAppliedToRange(range)) {
9826
- this.undoToRange(range);
9881
+ var isApplied = this.isAppliedToRange(range),
9882
+ parentsExactMatch;
9883
+
9884
+ if (isApplied) {
9885
+ if (isApplied.coverage === "full") {
9886
+ this.undoToRange(range);
9887
+ } else if (isApplied.coverage === "inline") {
9888
+ parentsExactMatch = areMatchingAllready(isApplied.elements, this.tagNames, this.cssStyle, this.cssClass);
9889
+ this.undoToRange(range);
9890
+ if (!parentsExactMatch) {
9891
+ this.applyToRange(range);
9892
+ }
9893
+ } else {
9894
+ // partial
9895
+ if (!areMatchingAllready(isApplied.elements, this.tagNames, this.cssStyle, this.cssClass)) {
9896
+ this.undoToRange(range);
9897
+ }
9898
+ this.applyToRange(range);
9899
+ }
9827
9900
  } else {
9828
9901
  this.applyToRange(range);
9829
9902
  }
@@ -10651,7 +10724,7 @@ wysihtml5.commands.formatCode = {
10651
10724
  state: function(composer, command, tagName, className, classRegExp, cssStyle, styleRegExp) {
10652
10725
  var doc = composer.doc,
10653
10726
  aliasTagName = ALIAS_MAPPING[tagName] || tagName,
10654
- ownRanges;
10727
+ ownRanges, isApplied;
10655
10728
 
10656
10729
  // Check whether the document contains a node with the desired tagName
10657
10730
  if (!wysihtml5.dom.hasElementWithTagName(doc, tagName) &&
@@ -10670,7 +10743,9 @@ wysihtml5.commands.formatCode = {
10670
10743
  return false;
10671
10744
  }
10672
10745
 
10673
- return _getApplier(tagName, className, classRegExp, cssStyle, styleRegExp, composer.element).isAppliedToRange(ownRanges);
10746
+ isApplied = _getApplier(tagName, className, classRegExp, cssStyle, styleRegExp, composer.element).isAppliedToRange(ownRanges);
10747
+
10748
+ return (isApplied && isApplied.elements) ? isApplied.elements : false;
10674
10749
  }
10675
10750
  };
10676
10751
  })(wysihtml5);
@@ -12379,17 +12454,37 @@ wysihtml5.views.View = Base.extend(
12379
12454
  } else if (selection.caretIsInTheBeginnig()) {
12380
12455
  event.preventDefault();
12381
12456
  } else {
12382
- var beforeUneditable = selection.caretIsBeforeUneditable();
12383
12457
 
12458
+ if (selection.caretIsFirstInSelection() &&
12459
+ selection.getPreviousNode() &&
12460
+ selection.getPreviousNode().nodeName &&
12461
+ (/^H\d$/gi).test(selection.getPreviousNode().nodeName)
12462
+ ) {
12463
+ var prevNode = selection.getPreviousNode();
12464
+ event.preventDefault();
12465
+ if ((/^\s*$/).test(prevNode.textContent || prevNode.innerText)) {
12466
+ // heading is empty
12467
+ prevNode.parentNode.removeChild(prevNode);
12468
+ } else {
12469
+ var range = prevNode.ownerDocument.createRange();
12470
+ range.selectNodeContents(prevNode);
12471
+ range.collapse(false);
12472
+ selection.setSelection(range);
12473
+ }
12474
+ }
12475
+
12476
+ var beforeUneditable = selection.caretIsBeforeUneditable();
12384
12477
  // Do a special delete if caret would delete uneditable
12385
12478
  if (beforeUneditable) {
12386
12479
  event.preventDefault();
12387
12480
  deleteAroundEditable(selection, beforeUneditable, element);
12388
12481
  }
12389
12482
  }
12390
- } else if (selection.containsUneditable()) {
12391
- event.preventDefault();
12392
- selection.deleteContents();
12483
+ } else {
12484
+ if (selection.containsUneditable()) {
12485
+ event.preventDefault();
12486
+ selection.deleteContents();
12487
+ }
12393
12488
  }
12394
12489
  };
12395
12490
 
@@ -25,7 +25,7 @@ if(!Array.isArray) {
25
25
  return Object.prototype.toString.call(arg) === '[object Array]';
26
26
  };
27
27
  };/**
28
- * @license wysihtml5x v0.4.9
28
+ * @license wysihtml5x v0.4.10
29
29
  * https://github.com/Edicy/wysihtml5
30
30
  *
31
31
  * Author: Christopher Blum (https://github.com/tiff)
@@ -36,7 +36,7 @@ if(!Array.isArray) {
36
36
  *
37
37
  */
38
38
  var wysihtml5 = {
39
- version: "0.4.9",
39
+ version: "0.4.10",
40
40
 
41
41
  // namespaces
42
42
  commands: {},
@@ -5505,13 +5505,15 @@ wysihtml5.dom.getStyle = (function() {
5505
5505
  };
5506
5506
  };
5507
5507
  })();
5508
- ;wysihtml5.dom.getTextNodes = function(node){
5508
+ ;wysihtml5.dom.getTextNodes = function(node, ingoreEmpty){
5509
5509
  var all = [];
5510
5510
  for (node=node.firstChild;node;node=node.nextSibling){
5511
- if (node.nodeType==3) {
5511
+ if (node.nodeType == 3) {
5512
+ if (!ingoreEmpty || !(/^\s*$/).test(node.innerText || node.textContent)) {
5512
5513
  all.push(node);
5514
+ }
5513
5515
  } else {
5514
- all = all.concat(wysihtml5.dom.getTextNodes(node));
5516
+ all = all.concat(wysihtml5.dom.getTextNodes(node, ingoreEmpty));
5515
5517
  }
5516
5518
  }
5517
5519
  return all;
@@ -8608,6 +8610,12 @@ wysihtml5.quirks.ensureProperClearing = (function() {
8608
8610
  }
8609
8611
  },
8610
8612
 
8613
+ fixSelBorders: function() {
8614
+ var range = this.getRange();
8615
+ expandRangeToSurround(range);
8616
+ this.setSelection(range);
8617
+ },
8618
+
8611
8619
  getSelectedOwnNodes: function(controlRange) {
8612
8620
  var selection,
8613
8621
  ranges = this.getOwnRanges(),
@@ -8726,12 +8734,17 @@ wysihtml5.quirks.ensureProperClearing = (function() {
8726
8734
 
8727
8735
  caretIsFirstInSelection: function() {
8728
8736
  var r = rangy.createRange(this.doc),
8729
- s = this.getSelection();
8730
-
8731
- r.selectNodeContents(this.getRange().commonAncestorContainer);
8732
- r.collapse(true);
8733
-
8734
- return (this.isCollapsed() && (r.startContainer === s.anchorNode || r.endContainer === s.anchorNode) && r.startOffset === s.anchorOffset);
8737
+ s = this.getSelection(),
8738
+ range = this.getRange(),
8739
+ startNode = range.startContainer;
8740
+
8741
+ if (startNode.nodeType === wysihtml5.TEXT_NODE) {
8742
+ return this.isCollapsed() && (startNode.nodeType === wysihtml5.TEXT_NODE && (/^\s*$/).test(startNode.data.substr(0,range.startOffset)));
8743
+ } else {
8744
+ r.selectNodeContents(this.getRange().commonAncestorContainer);
8745
+ r.collapse(true);
8746
+ return (this.isCollapsed() && (r.startContainer === s.anchorNode || r.endContainer === s.anchorNode) && r.startOffset === s.anchorOffset);
8747
+ }
8735
8748
  },
8736
8749
 
8737
8750
  caretIsInTheBeginnig: function(ofNode) {
@@ -9106,8 +9119,8 @@ wysihtml5.quirks.ensureProperClearing = (function() {
9106
9119
  },
9107
9120
 
9108
9121
  _endOffsetForNode: function(node) {
9109
- var range = document.createRange()
9110
- range.selectNodeContents(node)
9122
+ var range = document.createRange();
9123
+ range.selectNodeContents(node);
9111
9124
  return range.endOffset;
9112
9125
  },
9113
9126
 
@@ -9349,6 +9362,25 @@ wysihtml5.quirks.ensureProperClearing = (function() {
9349
9362
  return false;
9350
9363
  }
9351
9364
 
9365
+ function isMatchingAllready(node, tags, style, className) {
9366
+ if (style) {
9367
+ return getMatchingStyleRegexp(node, style);
9368
+ } else if (className) {
9369
+ return wysihtml5.dom.hasClass(node, className);
9370
+ } else {
9371
+ return rangy.dom.arrayContains(tags, node.tagName.toLowerCase());
9372
+ }
9373
+ }
9374
+
9375
+ function areMatchingAllready(nodes, tags, style, className) {
9376
+ for (var i = nodes.length; i--;) {
9377
+ if (!isMatchingAllready(nodes[i], tags, style, className)) {
9378
+ return false;
9379
+ }
9380
+ }
9381
+ return nodes.length ? true : false;
9382
+ }
9383
+
9352
9384
  function removeOrChangeStyle(el, style, regExp) {
9353
9385
 
9354
9386
  var exactRegex = getMatchingStyleRegexp(el, style);
@@ -9372,9 +9404,6 @@ wysihtml5.quirks.ensureProperClearing = (function() {
9372
9404
  while (el.firstChild) {
9373
9405
  parent.insertBefore(el.firstChild, el);
9374
9406
  }
9375
- if (parent.normalize) {
9376
- parent.normalize();
9377
- }
9378
9407
  parent.removeChild(el);
9379
9408
  }
9380
9409
 
@@ -9522,6 +9551,27 @@ wysihtml5.quirks.ensureProperClearing = (function() {
9522
9551
  return false;
9523
9552
  },
9524
9553
 
9554
+ getMatchingAncestor: function(node) {
9555
+ var ancestor = this.getAncestorWithClass(node),
9556
+ matchType = false;
9557
+
9558
+ if (!ancestor) {
9559
+ ancestor = this.getAncestorWithStyle(node);
9560
+ if (ancestor) {
9561
+ matchType = "style";
9562
+ }
9563
+ } else {
9564
+ if (this.cssStyle) {
9565
+ matchType = "class";
9566
+ }
9567
+ }
9568
+
9569
+ return {
9570
+ "element": ancestor,
9571
+ "type": matchType
9572
+ };
9573
+ },
9574
+
9525
9575
  // Normalizes nodes after applying a CSS class to a Range.
9526
9576
  postApply: function(textNodes, range) {
9527
9577
  var firstNode = textNodes[0], lastNode = textNodes[textNodes.length - 1];
@@ -9695,10 +9745,7 @@ wysihtml5.quirks.ensureProperClearing = (function() {
9695
9745
 
9696
9746
  for (var i = 0, len = textNodes.length; i < len; ++i) {
9697
9747
  textNode = textNodes[i];
9698
- if (!this.getAncestorWithClass(textNode)) {
9699
- this.applyToTextNode(textNode);
9700
- }
9701
- if (!this.getAncestorWithStyle(textNode)) {
9748
+ if (!this.getMatchingAncestor(textNode).element) {
9702
9749
  this.applyToTextNode(textNode);
9703
9750
  }
9704
9751
  }
@@ -9717,8 +9764,8 @@ wysihtml5.quirks.ensureProperClearing = (function() {
9717
9764
 
9718
9765
  undoToRange: function(range) {
9719
9766
  var textNodes, textNode, ancestorWithClass, ancestorWithStyle;
9720
-
9721
9767
  for (var ri = range.length; ri--;) {
9768
+
9722
9769
  textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);
9723
9770
  if (textNodes.length) {
9724
9771
  range[ri].splitBoundaries();
@@ -9731,16 +9778,15 @@ wysihtml5.quirks.ensureProperClearing = (function() {
9731
9778
  textNodes = [node];
9732
9779
  }
9733
9780
 
9734
-
9735
9781
  for (var i = 0, len = textNodes.length; i < len; ++i) {
9736
9782
  if (range[ri].isValid()) {
9737
9783
  textNode = textNodes[i];
9738
- ancestorWithClass = this.getAncestorWithClass(textNode);
9739
- ancestorWithStyle = this.getAncestorWithStyle(textNode);
9740
- if (ancestorWithClass) {
9741
- this.undoToTextNode(textNode, range[ri], ancestorWithClass);
9742
- } else if (ancestorWithStyle) {
9743
- this.undoToTextNode(textNode, range[ri], false, ancestorWithStyle);
9784
+
9785
+ ancestor = this.getMatchingAncestor(textNode);
9786
+ if (ancestor.type === "style") {
9787
+ this.undoToTextNode(textNode, range[ri], false, ancestor.element);
9788
+ } else if (ancestor.element) {
9789
+ this.undoToTextNode(textNode, range[ri], ancestor.element);
9744
9790
  }
9745
9791
  }
9746
9792
  }
@@ -9792,38 +9838,65 @@ wysihtml5.quirks.ensureProperClearing = (function() {
9792
9838
 
9793
9839
  isAppliedToRange: function(range) {
9794
9840
  var ancestors = [],
9841
+ appliedType = "full",
9795
9842
  ancestor, styleAncestor, textNodes;
9796
9843
 
9797
9844
  for (var ri = range.length; ri--;) {
9798
9845
 
9799
9846
  textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);
9800
9847
  if (!textNodes.length) {
9801
- ancestor = this.getAncestorWithClass(range[ri].startContainer);
9802
- if (!ancestor) {
9803
- ancestor = this.getAncestorWithStyle(range[ri].startContainer);
9804
- }
9805
- return ancestor ? [ancestor] : false;
9848
+ ancestor = this.getMatchingAncestor(range[ri].startContainer).element;
9849
+
9850
+ return (ancestor) ? {
9851
+ "elements": [ancestor],
9852
+ "coverage": appliedType
9853
+ } : false;
9806
9854
  }
9807
9855
 
9808
9856
  for (var i = 0, len = textNodes.length, selectedText; i < len; ++i) {
9809
9857
  selectedText = this.getTextSelectedByRange(textNodes[i], range[ri]);
9810
- ancestor = this.getAncestorWithClass(textNodes[i]);
9811
- if (!ancestor) {
9812
- ancestor = this.getAncestorWithStyle(textNodes[i]);
9813
- }
9858
+ ancestor = this.getMatchingAncestor(textNodes[i]).element;
9814
9859
  if (ancestor && selectedText != "") {
9815
9860
  ancestors.push(ancestor);
9861
+
9862
+ if (wysihtml5.dom.getTextNodes(ancestor, true).length === 1) {
9863
+ appliedType = "full";
9864
+ } else if (appliedType === "full") {
9865
+ appliedType = "inline";
9866
+ }
9867
+ } else if (!ancestor) {
9868
+ appliedType = "partial";
9816
9869
  }
9817
9870
  }
9818
9871
 
9819
9872
  }
9820
9873
 
9821
- return (ancestors.length) ? ancestors : false;
9874
+ return (ancestors.length) ? {
9875
+ "elements": ancestors,
9876
+ "coverage": appliedType
9877
+ } : false;
9822
9878
  },
9823
9879
 
9824
9880
  toggleRange: function(range) {
9825
- if (this.isAppliedToRange(range)) {
9826
- this.undoToRange(range);
9881
+ var isApplied = this.isAppliedToRange(range),
9882
+ parentsExactMatch;
9883
+
9884
+ if (isApplied) {
9885
+ if (isApplied.coverage === "full") {
9886
+ this.undoToRange(range);
9887
+ } else if (isApplied.coverage === "inline") {
9888
+ parentsExactMatch = areMatchingAllready(isApplied.elements, this.tagNames, this.cssStyle, this.cssClass);
9889
+ this.undoToRange(range);
9890
+ if (!parentsExactMatch) {
9891
+ this.applyToRange(range);
9892
+ }
9893
+ } else {
9894
+ // partial
9895
+ if (!areMatchingAllready(isApplied.elements, this.tagNames, this.cssStyle, this.cssClass)) {
9896
+ this.undoToRange(range);
9897
+ }
9898
+ this.applyToRange(range);
9899
+ }
9827
9900
  } else {
9828
9901
  this.applyToRange(range);
9829
9902
  }
@@ -10651,7 +10724,7 @@ wysihtml5.commands.formatCode = {
10651
10724
  state: function(composer, command, tagName, className, classRegExp, cssStyle, styleRegExp) {
10652
10725
  var doc = composer.doc,
10653
10726
  aliasTagName = ALIAS_MAPPING[tagName] || tagName,
10654
- ownRanges;
10727
+ ownRanges, isApplied;
10655
10728
 
10656
10729
  // Check whether the document contains a node with the desired tagName
10657
10730
  if (!wysihtml5.dom.hasElementWithTagName(doc, tagName) &&
@@ -10670,7 +10743,9 @@ wysihtml5.commands.formatCode = {
10670
10743
  return false;
10671
10744
  }
10672
10745
 
10673
- return _getApplier(tagName, className, classRegExp, cssStyle, styleRegExp, composer.element).isAppliedToRange(ownRanges);
10746
+ isApplied = _getApplier(tagName, className, classRegExp, cssStyle, styleRegExp, composer.element).isAppliedToRange(ownRanges);
10747
+
10748
+ return (isApplied && isApplied.elements) ? isApplied.elements : false;
10674
10749
  }
10675
10750
  };
10676
10751
  })(wysihtml5);
@@ -12379,17 +12454,37 @@ wysihtml5.views.View = Base.extend(
12379
12454
  } else if (selection.caretIsInTheBeginnig()) {
12380
12455
  event.preventDefault();
12381
12456
  } else {
12382
- var beforeUneditable = selection.caretIsBeforeUneditable();
12383
12457
 
12458
+ if (selection.caretIsFirstInSelection() &&
12459
+ selection.getPreviousNode() &&
12460
+ selection.getPreviousNode().nodeName &&
12461
+ (/^H\d$/gi).test(selection.getPreviousNode().nodeName)
12462
+ ) {
12463
+ var prevNode = selection.getPreviousNode();
12464
+ event.preventDefault();
12465
+ if ((/^\s*$/).test(prevNode.textContent || prevNode.innerText)) {
12466
+ // heading is empty
12467
+ prevNode.parentNode.removeChild(prevNode);
12468
+ } else {
12469
+ var range = prevNode.ownerDocument.createRange();
12470
+ range.selectNodeContents(prevNode);
12471
+ range.collapse(false);
12472
+ selection.setSelection(range);
12473
+ }
12474
+ }
12475
+
12476
+ var beforeUneditable = selection.caretIsBeforeUneditable();
12384
12477
  // Do a special delete if caret would delete uneditable
12385
12478
  if (beforeUneditable) {
12386
12479
  event.preventDefault();
12387
12480
  deleteAroundEditable(selection, beforeUneditable, element);
12388
12481
  }
12389
12482
  }
12390
- } else if (selection.containsUneditable()) {
12391
- event.preventDefault();
12392
- selection.deleteContents();
12483
+ } else {
12484
+ if (selection.containsUneditable()) {
12485
+ event.preventDefault();
12486
+ selection.deleteContents();
12487
+ }
12393
12488
  }
12394
12489
  };
12395
12490
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wysihtml5x-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.9
4
+ version: 0.4.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tanel Jakobsoo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-06-17 00:00:00.000000000 Z
11
+ date: 2014-06-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties