mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-26 20:34:02 +03:00
Koenig - Backspace undoes code/strike text expansions
refs https://github.com/TryGhost/Ghost/issues/9505 - prevent typing at the end of a `code` or ~strike~ markup continuing the format - if <kbd>Backspace</kbd> is pressed at the end of a `code` or ~strike~ markup then undo the text expansion and remove the last char
This commit is contained in:
parent
d54172172d
commit
30a61226f8
@ -53,6 +53,13 @@ const CURSOR_BEFORE = -1;
|
|||||||
const CURSOR_AFTER = 1;
|
const CURSOR_AFTER = 1;
|
||||||
const NO_CURSOR_MOVEMENT = 0;
|
const NO_CURSOR_MOVEMENT = 0;
|
||||||
|
|
||||||
|
// markups that should not be continued when typing and reverted to their
|
||||||
|
// text expansion style when backspacing over findal char of markup
|
||||||
|
const SPECIAL_MARKUPS = {
|
||||||
|
S: '~~',
|
||||||
|
CODE: '`'
|
||||||
|
};
|
||||||
|
|
||||||
function arrayToMap(array) {
|
function arrayToMap(array) {
|
||||||
let map = Object.create(null);
|
let map = Object.create(null);
|
||||||
array.forEach((key) => {
|
array.forEach((key) => {
|
||||||
@ -490,6 +497,24 @@ export default Component.extend({
|
|||||||
this.deselectCard(this._selectedCard);
|
this.deselectCard(this._selectedCard);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if we have `code` or ~strike~ formatting to the left but not the right
|
||||||
|
// then toggle the formatting - these formats should only be creatable
|
||||||
|
// through the text expansions
|
||||||
|
// HACK: this is largely duplicated in `inputModeDidChange` to work
|
||||||
|
// around an event ordering bug - see comments there
|
||||||
|
if (isCollapsed && head.marker) {
|
||||||
|
Object.keys(SPECIAL_MARKUPS).forEach((tagName) => {
|
||||||
|
if (head.marker.hasMarkup(tagName)) {
|
||||||
|
let nextMarker = head.markerIn(1);
|
||||||
|
if (!nextMarker || !nextMarker.hasMarkup(tagName)) {
|
||||||
|
run.next(this, function () {
|
||||||
|
editor.toggleMarkup(tagName);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// pass the selected range through to the toolbar + menu components
|
// pass the selected range through to the toolbar + menu components
|
||||||
this.set('selectedRange', editor.range);
|
this.set('selectedRange', editor.range);
|
||||||
},
|
},
|
||||||
@ -507,6 +532,23 @@ export default Component.extend({
|
|||||||
let sectionParentTagNames = editor.activeSections.map(s => s.isNested ? s.parent.tagName : s.tagName);
|
let sectionParentTagNames = editor.activeSections.map(s => s.isNested ? s.parent.tagName : s.tagName);
|
||||||
let sectionTags = arrayToMap(sectionParentTagNames);
|
let sectionTags = arrayToMap(sectionParentTagNames);
|
||||||
|
|
||||||
|
// HACK: this is largly duplicated with our `cursorDidChange` handling.
|
||||||
|
// On keyboard cursor movement our `cursorDidChange` toggle for special
|
||||||
|
// formats happens before mobiledoc's readstate updates activeMarkups
|
||||||
|
// so we have to re-do it here
|
||||||
|
let {head, isCollapsed} = editor.range;
|
||||||
|
if (isCollapsed) {
|
||||||
|
let activeMarkupTagNames = editor.activeMarkups.mapBy('tagName');
|
||||||
|
Object.keys(SPECIAL_MARKUPS).forEach((tagName) => {
|
||||||
|
if (activeMarkupTagNames.includes(tagName.toLowerCase())) {
|
||||||
|
let nextMarker = head.markerIn(1);
|
||||||
|
if (!nextMarker || !nextMarker.hasMarkup(tagName)) {
|
||||||
|
return editor.toggleMarkup(tagName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Avoid updating this component's properties synchronously while
|
// Avoid updating this component's properties synchronously while
|
||||||
// rendering the editor (after rendering the component) because it
|
// rendering the editor (after rendering the component) because it
|
||||||
// causes Ember to display deprecation warnings
|
// causes Ember to display deprecation warnings
|
||||||
@ -522,7 +564,8 @@ export default Component.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
handleBackspaceKey() {
|
handleBackspaceKey() {
|
||||||
let {isCollapsed, head: {offset, section}} = this.editor.range;
|
let editor = this.get('editor');
|
||||||
|
let {head, isCollapsed, head: {marker, offset, section}} = editor.range;
|
||||||
|
|
||||||
// if a card is selected we should delete the card then place the cursor
|
// if a card is selected we should delete the card then place the cursor
|
||||||
// at the end of the previous section
|
// at the end of the previous section
|
||||||
@ -557,6 +600,39 @@ export default Component.extend({
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if the markup about to be deleted is a special format (code, strike)
|
||||||
|
// then undo the text expansion to allow it to be extended
|
||||||
|
if (isCollapsed && marker) {
|
||||||
|
let specialMarkupTagNames = Object.keys(SPECIAL_MARKUPS);
|
||||||
|
let hasReversed = false;
|
||||||
|
specialMarkupTagNames.forEach((tagName) => {
|
||||||
|
// only continue if we're about to delete a special markup
|
||||||
|
let markup = marker.markups.find(markup => markup.tagName.toUpperCase() === tagName);
|
||||||
|
if (markup) {
|
||||||
|
let nextMarker = head.markerIn(1);
|
||||||
|
// ensure we're at the end of the markup not inside it
|
||||||
|
if (!nextMarker || !nextMarker.hasMarkup(tagName)) {
|
||||||
|
// wrap with the text expansion, remove formatting, then delete the last char
|
||||||
|
editor.run((postEditor) => {
|
||||||
|
let markdown = SPECIAL_MARKUPS[tagName];
|
||||||
|
let range = editor.range.expandByMarker(marker => !!marker.markups.includes(markup));
|
||||||
|
postEditor.insertText(range.head, markdown);
|
||||||
|
range = range.extend(markdown.length);
|
||||||
|
let endPos = postEditor.insertText(range.tail, markdown);
|
||||||
|
range = range.extend(markdown.length);
|
||||||
|
postEditor.toggleMarkup(tagName, range);
|
||||||
|
endPos = postEditor.deleteAtPosition(endPos, -1);
|
||||||
|
postEditor.setRange(endPos);
|
||||||
|
});
|
||||||
|
hasReversed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (hasReversed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user