wysihtml5x-rails 0.4.9 → 0.4.10

Sign up to get free protection for your applications and to get access to all the features.
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