wysihtml-rails 0.5.0.beta14 → 0.5.0

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: 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