wysihtml-rails 0.5.0.beta14 → 0.5.0

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: 79b9d17d508350d2026a68b4290a18f50cf80f86
4
- data.tar.gz: 258e583602cb8db2d76294344b1d4e30360e2cf0
3
+ metadata.gz: 1433246fbe1120226d24d24cb6106c9f1d8d971b
4
+ data.tar.gz: 8e29ce8a0c663d5bdcfd82087ecad8e84e19eb74
5
5
  SHA512:
6
- metadata.gz: 079c292c5b9ac8de4dd6cb8f93f4e52d8d341bbdd7f5c58cb438f38293fb47398b46472372e241bcf56fd70f9777603a4ac48b8b7cfa9e07bd940ac254be6ad1
7
- data.tar.gz: 1c4fff75b28fdfa298e9d37b8e657bb908f0bc088df289673bd43ec1890d717b4b987f23ddd61d685c00cf356393e5b4cc2b4b841809c33f24f4cd6c74a9fdd8
6
+ metadata.gz: 3e10a13b4417d81fcf6618285902a64232de9a4755a4a6787062bb2904eac0641c775de088a1764aee4b8de4335528193c1f94f5766745cabd997fa6770ab966
7
+ data.tar.gz: 6f04bfec384aeba9cd3e210a9e4332e83053885c8a2e96650911d55e9aaa8c15231c3d1461512ca737a0d97d8604c87e6cbe36ecde797529eb7b2432197a64bf
@@ -1,5 +1,5 @@
1
1
  module Wysihtml
2
2
  module Rails
3
- VERSION = "0.5.0.beta14"
3
+ VERSION = "0.5.0"
4
4
  end
5
5
  end
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license wysihtml v0.5.0-beta14
2
+ * @license wysihtml v0.5.0
3
3
  * https://github.com/Voog/wysihtml
4
4
  *
5
5
  * Author: Christopher Blum (https://github.com/tiff)
@@ -10,7 +10,7 @@
10
10
  *
11
11
  */
12
12
  var wysihtml5 = {
13
- version: "0.5.0-beta14",
13
+ version: "0.5.0",
14
14
 
15
15
  // namespaces
16
16
  commands: {},
@@ -7040,7 +7040,7 @@ wysihtml5.browser = (function() {
7040
7040
  Should actually check for clipboardData on paste event, but cannot in firefox
7041
7041
  */
7042
7042
  supportsModernPaste: function () {
7043
- return !("clipboardData" in window);
7043
+ return !isIE();
7044
7044
  },
7045
7045
 
7046
7046
  // Unifies the property names of element.style by returning the suitable property name for current browser
@@ -9140,27 +9140,31 @@ wysihtml5.dom.parse = function(elementOrHtml_current, config_current) {
9140
9140
  }
9141
9141
 
9142
9142
 
9143
- if (typeof(allowedClasses) === "string" && allowedClasses === "any" && oldNode.getAttribute("class")) {
9144
- if (currentRules.classes_blacklist) {
9145
- oldClasses = oldNode.getAttribute("class");
9146
- if (oldClasses) {
9147
- classes = classes.concat(oldClasses.split(WHITE_SPACE_REG_EXP));
9148
- }
9143
+ if (typeof(allowedClasses) === "string" && allowedClasses === "any") {
9144
+ if (oldNode.getAttribute("class")) {
9145
+ if (currentRules.classes_blacklist) {
9146
+ oldClasses = oldNode.getAttribute("class");
9147
+ if (oldClasses) {
9148
+ classes = classes.concat(oldClasses.split(WHITE_SPACE_REG_EXP));
9149
+ }
9149
9150
 
9150
- classesLength = classes.length;
9151
- for (; i<classesLength; i++) {
9152
- currentClass = classes[i];
9153
- if (!currentRules.classes_blacklist[currentClass]) {
9154
- newClasses.push(currentClass);
9151
+ classesLength = classes.length;
9152
+ for (; i<classesLength; i++) {
9153
+ currentClass = classes[i];
9154
+ if (!currentRules.classes_blacklist[currentClass]) {
9155
+ newClasses.push(currentClass);
9156
+ }
9155
9157
  }
9156
- }
9157
9158
 
9158
- if (newClasses.length) {
9159
- attributes["class"] = wysihtml5.lang.array(newClasses).unique().join(" ");
9160
- }
9159
+ if (newClasses.length) {
9160
+ attributes["class"] = wysihtml5.lang.array(newClasses).unique().join(" ");
9161
+ }
9161
9162
 
9163
+ } else {
9164
+ attributes["class"] = oldNode.getAttribute("class");
9165
+ }
9162
9166
  } else {
9163
- attributes["class"] = oldNode.getAttribute("class");
9167
+ attributes["class"] = wysihtml5.lang.array(classes).unique().join(" ");
9164
9168
  }
9165
9169
  } else {
9166
9170
  // make sure that wysihtml5 temp class doesn't get stripped out
@@ -10015,7 +10019,7 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
10015
10019
  set = function() {
10016
10020
  if (view.isEmpty() && !view.placeholderSet) {
10017
10021
  view.placeholderSet = true;
10018
- view.setValue(placeholderText);
10022
+ view.setValue(placeholderText, false);
10019
10023
  dom.addClass(view.element, CLASS_NAME);
10020
10024
  }
10021
10025
  };
@@ -11120,7 +11124,7 @@ wysihtml5.dom.unwrap = function(node) {
11120
11124
  **/
11121
11125
  wysihtml5.dom.getPastedHtml = function(event) {
11122
11126
  var html;
11123
- if (event.clipboardData) {
11127
+ if (wysihtml5.browser.supportsModernPaste() && event.clipboardData) {
11124
11128
  if (wysihtml5.lang.array(event.clipboardData.types).contains('text/html')) {
11125
11129
  html = event.clipboardData.getData('text/html');
11126
11130
  } else if (wysihtml5.lang.array(event.clipboardData.types).contains('text/plain')) {
@@ -11990,9 +11994,15 @@ wysihtml5.quirks.ensureProperClearing = (function() {
11990
11994
  // Deletes selection contents making sure uneditables/unselectables are not partially deleted
11991
11995
  // Triggers wysihtml5:uneditable:delete custom event on all deleted uneditables if customevents suppoorted
11992
11996
  deleteContents: function() {
11993
- var range = this.getRange(),
11994
- startParent, endParent, uneditables, ev;
11995
-
11997
+ var range = this.getRange();
11998
+ this.deleteRangeContents(range);
11999
+ this.setSelection(range);
12000
+ },
12001
+
12002
+ // Makes sure all uneditable sare notified before deleting contents
12003
+ deleteRangeContents: function (range) {
12004
+ var startParent, endParent, uneditables, ev;
12005
+
11996
12006
  if (this.unselectableClass) {
11997
12007
  if ((startParent = wysihtml5.dom.getParentElement(range.startContainer, { query: "." + this.unselectableClass }, false, this.contain))) {
11998
12008
  range.setStartBefore(startParent);
@@ -12011,10 +12021,8 @@ wysihtml5.quirks.ensureProperClearing = (function() {
12011
12021
  uneditables[i].dispatchEvent(ev);
12012
12022
  } catch (err) {}
12013
12023
  }
12014
-
12015
12024
  }
12016
12025
  range.deleteContents();
12017
- this.setSelection(range);
12018
12026
  },
12019
12027
 
12020
12028
  getPreviousNode: function(node, ignoreEmpty) {
@@ -12301,28 +12309,41 @@ wysihtml5.quirks.ensureProperClearing = (function() {
12301
12309
  },
12302
12310
 
12303
12311
  /**
12304
- * Insert html at the caret position and move the cursor after the inserted html
12312
+ * Insert html at the caret or selection position and move the cursor after the inserted html
12313
+ * Replaces selection content if present
12305
12314
  *
12306
12315
  * @param {String} html HTML string to insert
12307
12316
  * @example
12308
12317
  * selection.insertHTML("<p>foobar</p>");
12309
12318
  */
12310
12319
  insertHTML: function(html) {
12311
- var range = rangy.createRange(this.doc),
12320
+ var range = this.getRange(),
12312
12321
  node = this.doc.createElement('DIV'),
12313
12322
  fragment = this.doc.createDocumentFragment(),
12314
- lastChild;
12315
-
12316
- node.innerHTML = html;
12317
- lastChild = node.lastChild;
12323
+ lastChild, lastEditorElement;
12324
+
12325
+ if (range) {
12326
+ range.deleteContents();
12327
+ node.innerHTML = html;
12328
+ lastChild = node.lastChild;
12318
12329
 
12319
- while (node.firstChild) {
12320
- fragment.appendChild(node.firstChild);
12321
- }
12322
- this.insertNode(fragment);
12330
+ while (node.firstChild) {
12331
+ fragment.appendChild(node.firstChild);
12332
+ }
12333
+ range.insertNode(fragment);
12334
+
12335
+ lastEditorElement = this.contain.lastChild;
12336
+ while (lastEditorElement && lastEditorElement.nodeType === 3 && lastEditorElement.previousSibling && (/^\s*$/).test(lastEditorElement.data)) {
12337
+ lastEditorElement = lastEditorElement.previousSibling;
12338
+ }
12323
12339
 
12324
- if (lastChild) {
12325
- this.setAfter(lastChild);
12340
+ if (lastChild) {
12341
+ // fixes some pad cases mostly on webkit where last nr is needed
12342
+ if (lastEditorElement && lastChild === lastEditorElement && lastChild.nodeType === 1) {
12343
+ this.contain.appendChild(this.doc.createElement('br'));
12344
+ }
12345
+ this.setAfter(lastChild);
12346
+ }
12326
12347
  }
12327
12348
  },
12328
12349
 
@@ -15100,11 +15121,7 @@ wysihtml5.Commands = Base.extend(
15100
15121
  ;(function(wysihtml5){
15101
15122
  wysihtml5.commands.insertHTML = {
15102
15123
  exec: function(composer, command, html) {
15103
- if (composer.commands.support(command)) {
15104
- composer.doc.execCommand(command, false, html);
15105
- } else {
15106
15124
  composer.selection.insertHTML(html);
15107
- }
15108
15125
  },
15109
15126
 
15110
15127
  state: function() {
@@ -15226,14 +15243,7 @@ wysihtml5.Commands = Base.extend(
15226
15243
 
15227
15244
  wysihtml5.commands.insertLineBreak = {
15228
15245
  exec: function(composer, command) {
15229
- if (composer.commands.support(command)) {
15230
- composer.doc.execCommand(command, false, null);
15231
- if (!wysihtml5.browser.autoScrollsToCaret()) {
15232
- composer.selection.scrollIntoView();
15233
- }
15234
- } else {
15235
- composer.commands.exec("insertHTML", LINE_BREAK);
15236
- }
15246
+ composer.selection.insertHTML(LINE_BREAK);
15237
15247
  },
15238
15248
 
15239
15249
  state: function() {
@@ -16195,9 +16205,6 @@ wysihtml5.views.View = Base.extend(
16195
16205
  /** @scope wysihtml5.views.Composer.prototype */ {
16196
16206
  name: "composer",
16197
16207
 
16198
- // Needed for firefox in order to display a proper caret in an empty contentEditable
16199
- CARET_HACK: "<br>",
16200
-
16201
16208
  constructor: function(parent, editableElement, config) {
16202
16209
  this.base(parent, editableElement, config);
16203
16210
  if (!this.config.noTextarea) {
@@ -16213,7 +16220,7 @@ wysihtml5.views.View = Base.extend(
16213
16220
  },
16214
16221
 
16215
16222
  clear: function() {
16216
- this.element.innerHTML = browser.displaysCaretInEmptyContentEditableCorrectly() ? "" : this.CARET_HACK;
16223
+ this.element.innerHTML = browser.displaysCaretInEmptyContentEditableCorrectly() ? "" : "<br>";
16217
16224
  },
16218
16225
 
16219
16226
  getValue: function(parse, clearInternals) {
@@ -16221,12 +16228,11 @@ wysihtml5.views.View = Base.extend(
16221
16228
  if (parse !== false) {
16222
16229
  value = this.parent.parse(value, (clearInternals === false) ? false : true);
16223
16230
  }
16224
-
16225
16231
  return value;
16226
16232
  },
16227
16233
 
16228
16234
  setValue: function(html, parse) {
16229
- if (parse) {
16235
+ if (parse !== false) {
16230
16236
  html = this.parent.parse(html);
16231
16237
  }
16232
16238
 
@@ -16237,12 +16243,12 @@ wysihtml5.views.View = Base.extend(
16237
16243
  }
16238
16244
  },
16239
16245
 
16240
- cleanUp: function() {
16246
+ cleanUp: function(rules) {
16241
16247
  var bookmark;
16242
16248
  if (this.selection) {
16243
16249
  bookmark = rangy.saveSelection(this.win);
16244
16250
  }
16245
- this.parent.parse(this.element);
16251
+ this.parent.parse(this.element, undefined, rules);
16246
16252
  if (bookmark) {
16247
16253
  rangy.restoreSelection(bookmark);
16248
16254
  }
@@ -16630,17 +16636,6 @@ wysihtml5.views.View = Base.extend(
16630
16636
  });
16631
16637
  }
16632
16638
 
16633
- // Under certain circumstances Chrome + Safari create nested <p> or <hX> tags after paste
16634
- // Inserting an invisible white space in front of it fixes the issue
16635
- // This is too hacky and causes selection not to replace content on paste in chrome
16636
- /* if (browser.createsNestedInvalidMarkupAfterPaste()) {
16637
- dom.observe(this.element, "paste", function(event) {
16638
- var invisibleSpace = that.doc.createTextNode(wysihtml5.INVISIBLE_SPACE);
16639
- that.selection.insertNode(invisibleSpace);
16640
- });
16641
- }*/
16642
-
16643
-
16644
16639
  dom.observe(this.element, "keydown", function(event) {
16645
16640
  var keyCode = event.keyCode;
16646
16641
 
@@ -17087,7 +17082,7 @@ wysihtml5.views.View = Base.extend(
17087
17082
  if (this.config.copyedFromMarking) {
17088
17083
  // If supported the copied source can be based directly on selection
17089
17084
  // Very useful for webkit based browsers where copy will otherwise contain a lot of code and styles based on whatever and not actually in selection.
17090
- if (event.clipboardData) {
17085
+ if (wysihtml5.browser.supportsModernPaste()) {
17091
17086
  event.clipboardData.setData("text/html", this.config.copyedFromMarking + this.selection.getHtml());
17092
17087
  event.clipboardData.setData("text/plain", this.selection.getPlainText());
17093
17088
  event.preventDefault();
@@ -17466,14 +17461,14 @@ wysihtml5.views.View = Base.extend(
17466
17461
  },
17467
17462
 
17468
17463
  setValue: function(html, parse) {
17469
- if (parse) {
17464
+ if (parse !== false) {
17470
17465
  html = this.parent.parse(html);
17471
17466
  }
17472
17467
  this.element.value = html;
17473
17468
  },
17474
17469
 
17475
- cleanUp: function() {
17476
- var html = this.parent.parse(this.element.value);
17470
+ cleanUp: function(rules) {
17471
+ var html = this.parent.parse(this.element.value, undefined, rules);
17477
17472
  this.element.value = html;
17478
17473
  },
17479
17474
 
@@ -17568,7 +17563,7 @@ wysihtml5.views.View = Base.extend(
17568
17563
  handleTabKey: true,
17569
17564
  // Object which includes parser rules to apply when html gets cleaned
17570
17565
  // See parser_rules/*.js for examples
17571
- parserRules: { tags: { br: {}, span: {}, div: {}, p: {} }, classes: {} },
17566
+ parserRules: { tags: { br: {}, span: {}, div: {}, p: {}, b: {}, i: {}, u: {} }, classes: {} },
17572
17567
  // Object which includes parser when the user inserts content via copy & paste. If null parserRules will be used instead
17573
17568
  pasteParserRulesets: null,
17574
17569
  // Parser method to use when the user inserts content
@@ -17680,8 +17675,8 @@ wysihtml5.views.View = Base.extend(
17680
17675
  return this;
17681
17676
  },
17682
17677
 
17683
- cleanUp: function() {
17684
- this.currentView.cleanUp();
17678
+ cleanUp: function(rules) {
17679
+ this.currentView.cleanUp(rules);
17685
17680
  },
17686
17681
 
17687
17682
  focus: function(setToEnd) {
@@ -17723,10 +17718,10 @@ wysihtml5.views.View = Base.extend(
17723
17718
  this.off();
17724
17719
  },
17725
17720
 
17726
- parse: function(htmlOrElement, clearInternals) {
17721
+ parse: function(htmlOrElement, clearInternals, customRules) {
17727
17722
  var parseContext = (this.config.contentEditableMode) ? document : ((this.composer) ? this.composer.sandbox.getDocument() : null);
17728
17723
  var returnValue = this.config.parser(htmlOrElement, {
17729
- "rules": this.config.parserRules,
17724
+ "rules": customRules || this.config.parserRules,
17730
17725
  "cleanUp": this.config.cleanUp,
17731
17726
  "context": parseContext,
17732
17727
  "uneditableClass": this.config.classNames.uneditableContainer,
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @license wysihtml v0.5.0-beta14
2
+ * @license wysihtml v0.5.0
3
3
  * https://github.com/Voog/wysihtml
4
4
  *
5
5
  * Author: Christopher Blum (https://github.com/tiff)
@@ -10,7 +10,7 @@
10
10
  *
11
11
  */
12
12
  var wysihtml5 = {
13
- version: "0.5.0-beta14",
13
+ version: "0.5.0",
14
14
 
15
15
  // namespaces
16
16
  commands: {},
@@ -7040,7 +7040,7 @@ wysihtml5.browser = (function() {
7040
7040
  Should actually check for clipboardData on paste event, but cannot in firefox
7041
7041
  */
7042
7042
  supportsModernPaste: function () {
7043
- return !("clipboardData" in window);
7043
+ return !isIE();
7044
7044
  },
7045
7045
 
7046
7046
  // Unifies the property names of element.style by returning the suitable property name for current browser
@@ -9140,27 +9140,31 @@ wysihtml5.dom.parse = function(elementOrHtml_current, config_current) {
9140
9140
  }
9141
9141
 
9142
9142
 
9143
- if (typeof(allowedClasses) === "string" && allowedClasses === "any" && oldNode.getAttribute("class")) {
9144
- if (currentRules.classes_blacklist) {
9145
- oldClasses = oldNode.getAttribute("class");
9146
- if (oldClasses) {
9147
- classes = classes.concat(oldClasses.split(WHITE_SPACE_REG_EXP));
9148
- }
9143
+ if (typeof(allowedClasses) === "string" && allowedClasses === "any") {
9144
+ if (oldNode.getAttribute("class")) {
9145
+ if (currentRules.classes_blacklist) {
9146
+ oldClasses = oldNode.getAttribute("class");
9147
+ if (oldClasses) {
9148
+ classes = classes.concat(oldClasses.split(WHITE_SPACE_REG_EXP));
9149
+ }
9149
9150
 
9150
- classesLength = classes.length;
9151
- for (; i<classesLength; i++) {
9152
- currentClass = classes[i];
9153
- if (!currentRules.classes_blacklist[currentClass]) {
9154
- newClasses.push(currentClass);
9151
+ classesLength = classes.length;
9152
+ for (; i<classesLength; i++) {
9153
+ currentClass = classes[i];
9154
+ if (!currentRules.classes_blacklist[currentClass]) {
9155
+ newClasses.push(currentClass);
9156
+ }
9155
9157
  }
9156
- }
9157
9158
 
9158
- if (newClasses.length) {
9159
- attributes["class"] = wysihtml5.lang.array(newClasses).unique().join(" ");
9160
- }
9159
+ if (newClasses.length) {
9160
+ attributes["class"] = wysihtml5.lang.array(newClasses).unique().join(" ");
9161
+ }
9161
9162
 
9163
+ } else {
9164
+ attributes["class"] = oldNode.getAttribute("class");
9165
+ }
9162
9166
  } else {
9163
- attributes["class"] = oldNode.getAttribute("class");
9167
+ attributes["class"] = wysihtml5.lang.array(classes).unique().join(" ");
9164
9168
  }
9165
9169
  } else {
9166
9170
  // make sure that wysihtml5 temp class doesn't get stripped out
@@ -10015,7 +10019,7 @@ wysihtml5.dom.replaceWithChildNodes = function(node) {
10015
10019
  set = function() {
10016
10020
  if (view.isEmpty() && !view.placeholderSet) {
10017
10021
  view.placeholderSet = true;
10018
- view.setValue(placeholderText);
10022
+ view.setValue(placeholderText, false);
10019
10023
  dom.addClass(view.element, CLASS_NAME);
10020
10024
  }
10021
10025
  };
@@ -11120,7 +11124,7 @@ wysihtml5.dom.unwrap = function(node) {
11120
11124
  **/
11121
11125
  wysihtml5.dom.getPastedHtml = function(event) {
11122
11126
  var html;
11123
- if (event.clipboardData) {
11127
+ if (wysihtml5.browser.supportsModernPaste() && event.clipboardData) {
11124
11128
  if (wysihtml5.lang.array(event.clipboardData.types).contains('text/html')) {
11125
11129
  html = event.clipboardData.getData('text/html');
11126
11130
  } else if (wysihtml5.lang.array(event.clipboardData.types).contains('text/plain')) {
@@ -11990,9 +11994,15 @@ wysihtml5.quirks.ensureProperClearing = (function() {
11990
11994
  // Deletes selection contents making sure uneditables/unselectables are not partially deleted
11991
11995
  // Triggers wysihtml5:uneditable:delete custom event on all deleted uneditables if customevents suppoorted
11992
11996
  deleteContents: function() {
11993
- var range = this.getRange(),
11994
- startParent, endParent, uneditables, ev;
11995
-
11997
+ var range = this.getRange();
11998
+ this.deleteRangeContents(range);
11999
+ this.setSelection(range);
12000
+ },
12001
+
12002
+ // Makes sure all uneditable sare notified before deleting contents
12003
+ deleteRangeContents: function (range) {
12004
+ var startParent, endParent, uneditables, ev;
12005
+
11996
12006
  if (this.unselectableClass) {
11997
12007
  if ((startParent = wysihtml5.dom.getParentElement(range.startContainer, { query: "." + this.unselectableClass }, false, this.contain))) {
11998
12008
  range.setStartBefore(startParent);
@@ -12011,10 +12021,8 @@ wysihtml5.quirks.ensureProperClearing = (function() {
12011
12021
  uneditables[i].dispatchEvent(ev);
12012
12022
  } catch (err) {}
12013
12023
  }
12014
-
12015
12024
  }
12016
12025
  range.deleteContents();
12017
- this.setSelection(range);
12018
12026
  },
12019
12027
 
12020
12028
  getPreviousNode: function(node, ignoreEmpty) {
@@ -12301,28 +12309,41 @@ wysihtml5.quirks.ensureProperClearing = (function() {
12301
12309
  },
12302
12310
 
12303
12311
  /**
12304
- * Insert html at the caret position and move the cursor after the inserted html
12312
+ * Insert html at the caret or selection position and move the cursor after the inserted html
12313
+ * Replaces selection content if present
12305
12314
  *
12306
12315
  * @param {String} html HTML string to insert
12307
12316
  * @example
12308
12317
  * selection.insertHTML("<p>foobar</p>");
12309
12318
  */
12310
12319
  insertHTML: function(html) {
12311
- var range = rangy.createRange(this.doc),
12320
+ var range = this.getRange(),
12312
12321
  node = this.doc.createElement('DIV'),
12313
12322
  fragment = this.doc.createDocumentFragment(),
12314
- lastChild;
12315
-
12316
- node.innerHTML = html;
12317
- lastChild = node.lastChild;
12323
+ lastChild, lastEditorElement;
12324
+
12325
+ if (range) {
12326
+ range.deleteContents();
12327
+ node.innerHTML = html;
12328
+ lastChild = node.lastChild;
12318
12329
 
12319
- while (node.firstChild) {
12320
- fragment.appendChild(node.firstChild);
12321
- }
12322
- this.insertNode(fragment);
12330
+ while (node.firstChild) {
12331
+ fragment.appendChild(node.firstChild);
12332
+ }
12333
+ range.insertNode(fragment);
12334
+
12335
+ lastEditorElement = this.contain.lastChild;
12336
+ while (lastEditorElement && lastEditorElement.nodeType === 3 && lastEditorElement.previousSibling && (/^\s*$/).test(lastEditorElement.data)) {
12337
+ lastEditorElement = lastEditorElement.previousSibling;
12338
+ }
12323
12339
 
12324
- if (lastChild) {
12325
- this.setAfter(lastChild);
12340
+ if (lastChild) {
12341
+ // fixes some pad cases mostly on webkit where last nr is needed
12342
+ if (lastEditorElement && lastChild === lastEditorElement && lastChild.nodeType === 1) {
12343
+ this.contain.appendChild(this.doc.createElement('br'));
12344
+ }
12345
+ this.setAfter(lastChild);
12346
+ }
12326
12347
  }
12327
12348
  },
12328
12349
 
@@ -15100,11 +15121,7 @@ wysihtml5.Commands = Base.extend(
15100
15121
  ;(function(wysihtml5){
15101
15122
  wysihtml5.commands.insertHTML = {
15102
15123
  exec: function(composer, command, html) {
15103
- if (composer.commands.support(command)) {
15104
- composer.doc.execCommand(command, false, html);
15105
- } else {
15106
15124
  composer.selection.insertHTML(html);
15107
- }
15108
15125
  },
15109
15126
 
15110
15127
  state: function() {
@@ -15226,14 +15243,7 @@ wysihtml5.Commands = Base.extend(
15226
15243
 
15227
15244
  wysihtml5.commands.insertLineBreak = {
15228
15245
  exec: function(composer, command) {
15229
- if (composer.commands.support(command)) {
15230
- composer.doc.execCommand(command, false, null);
15231
- if (!wysihtml5.browser.autoScrollsToCaret()) {
15232
- composer.selection.scrollIntoView();
15233
- }
15234
- } else {
15235
- composer.commands.exec("insertHTML", LINE_BREAK);
15236
- }
15246
+ composer.selection.insertHTML(LINE_BREAK);
15237
15247
  },
15238
15248
 
15239
15249
  state: function() {
@@ -16195,9 +16205,6 @@ wysihtml5.views.View = Base.extend(
16195
16205
  /** @scope wysihtml5.views.Composer.prototype */ {
16196
16206
  name: "composer",
16197
16207
 
16198
- // Needed for firefox in order to display a proper caret in an empty contentEditable
16199
- CARET_HACK: "<br>",
16200
-
16201
16208
  constructor: function(parent, editableElement, config) {
16202
16209
  this.base(parent, editableElement, config);
16203
16210
  if (!this.config.noTextarea) {
@@ -16213,7 +16220,7 @@ wysihtml5.views.View = Base.extend(
16213
16220
  },
16214
16221
 
16215
16222
  clear: function() {
16216
- this.element.innerHTML = browser.displaysCaretInEmptyContentEditableCorrectly() ? "" : this.CARET_HACK;
16223
+ this.element.innerHTML = browser.displaysCaretInEmptyContentEditableCorrectly() ? "" : "<br>";
16217
16224
  },
16218
16225
 
16219
16226
  getValue: function(parse, clearInternals) {
@@ -16221,12 +16228,11 @@ wysihtml5.views.View = Base.extend(
16221
16228
  if (parse !== false) {
16222
16229
  value = this.parent.parse(value, (clearInternals === false) ? false : true);
16223
16230
  }
16224
-
16225
16231
  return value;
16226
16232
  },
16227
16233
 
16228
16234
  setValue: function(html, parse) {
16229
- if (parse) {
16235
+ if (parse !== false) {
16230
16236
  html = this.parent.parse(html);
16231
16237
  }
16232
16238
 
@@ -16237,12 +16243,12 @@ wysihtml5.views.View = Base.extend(
16237
16243
  }
16238
16244
  },
16239
16245
 
16240
- cleanUp: function() {
16246
+ cleanUp: function(rules) {
16241
16247
  var bookmark;
16242
16248
  if (this.selection) {
16243
16249
  bookmark = rangy.saveSelection(this.win);
16244
16250
  }
16245
- this.parent.parse(this.element);
16251
+ this.parent.parse(this.element, undefined, rules);
16246
16252
  if (bookmark) {
16247
16253
  rangy.restoreSelection(bookmark);
16248
16254
  }
@@ -16630,17 +16636,6 @@ wysihtml5.views.View = Base.extend(
16630
16636
  });
16631
16637
  }
16632
16638
 
16633
- // Under certain circumstances Chrome + Safari create nested <p> or <hX> tags after paste
16634
- // Inserting an invisible white space in front of it fixes the issue
16635
- // This is too hacky and causes selection not to replace content on paste in chrome
16636
- /* if (browser.createsNestedInvalidMarkupAfterPaste()) {
16637
- dom.observe(this.element, "paste", function(event) {
16638
- var invisibleSpace = that.doc.createTextNode(wysihtml5.INVISIBLE_SPACE);
16639
- that.selection.insertNode(invisibleSpace);
16640
- });
16641
- }*/
16642
-
16643
-
16644
16639
  dom.observe(this.element, "keydown", function(event) {
16645
16640
  var keyCode = event.keyCode;
16646
16641
 
@@ -17087,7 +17082,7 @@ wysihtml5.views.View = Base.extend(
17087
17082
  if (this.config.copyedFromMarking) {
17088
17083
  // If supported the copied source can be based directly on selection
17089
17084
  // Very useful for webkit based browsers where copy will otherwise contain a lot of code and styles based on whatever and not actually in selection.
17090
- if (event.clipboardData) {
17085
+ if (wysihtml5.browser.supportsModernPaste()) {
17091
17086
  event.clipboardData.setData("text/html", this.config.copyedFromMarking + this.selection.getHtml());
17092
17087
  event.clipboardData.setData("text/plain", this.selection.getPlainText());
17093
17088
  event.preventDefault();
@@ -17466,14 +17461,14 @@ wysihtml5.views.View = Base.extend(
17466
17461
  },
17467
17462
 
17468
17463
  setValue: function(html, parse) {
17469
- if (parse) {
17464
+ if (parse !== false) {
17470
17465
  html = this.parent.parse(html);
17471
17466
  }
17472
17467
  this.element.value = html;
17473
17468
  },
17474
17469
 
17475
- cleanUp: function() {
17476
- var html = this.parent.parse(this.element.value);
17470
+ cleanUp: function(rules) {
17471
+ var html = this.parent.parse(this.element.value, undefined, rules);
17477
17472
  this.element.value = html;
17478
17473
  },
17479
17474
 
@@ -17568,7 +17563,7 @@ wysihtml5.views.View = Base.extend(
17568
17563
  handleTabKey: true,
17569
17564
  // Object which includes parser rules to apply when html gets cleaned
17570
17565
  // See parser_rules/*.js for examples
17571
- parserRules: { tags: { br: {}, span: {}, div: {}, p: {} }, classes: {} },
17566
+ parserRules: { tags: { br: {}, span: {}, div: {}, p: {}, b: {}, i: {}, u: {} }, classes: {} },
17572
17567
  // Object which includes parser when the user inserts content via copy & paste. If null parserRules will be used instead
17573
17568
  pasteParserRulesets: null,
17574
17569
  // Parser method to use when the user inserts content
@@ -17680,8 +17675,8 @@ wysihtml5.views.View = Base.extend(
17680
17675
  return this;
17681
17676
  },
17682
17677
 
17683
- cleanUp: function() {
17684
- this.currentView.cleanUp();
17678
+ cleanUp: function(rules) {
17679
+ this.currentView.cleanUp(rules);
17685
17680
  },
17686
17681
 
17687
17682
  focus: function(setToEnd) {
@@ -17723,10 +17718,10 @@ wysihtml5.views.View = Base.extend(
17723
17718
  this.off();
17724
17719
  },
17725
17720
 
17726
- parse: function(htmlOrElement, clearInternals) {
17721
+ parse: function(htmlOrElement, clearInternals, customRules) {
17727
17722
  var parseContext = (this.config.contentEditableMode) ? document : ((this.composer) ? this.composer.sandbox.getDocument() : null);
17728
17723
  var returnValue = this.config.parser(htmlOrElement, {
17729
- "rules": this.config.parserRules,
17724
+ "rules": customRules || this.config.parserRules,
17730
17725
  "cleanUp": this.config.cleanUp,
17731
17726
  "context": parseContext,
17732
17727
  "uneditableClass": this.config.classNames.uneditableContainer,
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wysihtml-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0.beta14
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tanel Jakobsoo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-20 00:00:00.000000000 Z
11
+ date: 2015-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -89,9 +89,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
89
89
  version: '0'
90
90
  required_rubygems_version: !ruby/object:Gem::Requirement
91
91
  requirements:
92
- - - ">"
92
+ - - ">="
93
93
  - !ruby/object:Gem::Version
94
- version: 1.3.1
94
+ version: '0'
95
95
  requirements: []
96
96
  rubyforge_project:
97
97
  rubygems_version: 2.2.2