Skip to content
This repository has been archived by the owner on Nov 28, 2022. It is now read-only.

Commit

Permalink
🐛 Koenig - Fixed caption/embed inputs in Firefox & Safari
Browse files Browse the repository at this point in the history
refs TryGhost/Ghost#9623
- disable `contenteditable` on the main editor element when an input in a card gains focus
    - Firefox chokes on inputs inside a `contenteditable` element
    - use a MutationObserver inside `{{koenig-card}}` to automatically add event handlers for focus/blur events so that each card is not required to set up handlers and enable/disable content editable manually
- bump Spirit dependency
    - remove `user-select: none` styling from `.form-text` for text inputs
    - fixes captions and embed inputs in Safari and improves behaviour in Firefox
- add a guard around `getSelection(0)` in the `_scrollCursorIntoView()` method to avoid Safari throwing errors
  • Loading branch information
kevinansfield committed Jun 21, 2018
1 parent 5b369a9 commit fe840a2
Show file tree
Hide file tree
Showing 6 changed files with 95 additions and 6 deletions.
4 changes: 3 additions & 1 deletion lib/koenig-editor/addon/components/koenig-caption-input.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ export default Component.extend({
_keydownHandler: null,

update() {},
onDidInsertElement() {},
addParagraphAfterCard() {},
moveCursorToNextSection() {},
moveCursorToPrevSection() {},

figCaptionClass: computed(function () {
return `${kgStyle(['figcaption'])} w-100`;
Expand Down
1 change: 1 addition & 0 deletions lib/koenig-editor/addon/components/koenig-card-embed.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export default Component.extend({
}

if (event.key === 'Escape') {
event.target.blur();
this.deleteCard();
}
},
Expand Down
82 changes: 82 additions & 0 deletions lib/koenig-editor/addon/components/koenig-card.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,26 @@ export default Component.extend({
didInsertElement() {
this._super(...arguments);
this._setToolbarProperties();
this._createMutationObserver(
this.element,
run.bind(this, this._inputFocus),
run.bind(this, this._inputBlur)
);
},

willDestroyElement() {
this._super(...arguments);
window.removeEventListener('keydown', this._onKeydownHandler);
window.removeEventListener('click', this._onClickHandler);
this._removeMousemoveHandler();

if (this._mutationObserver) {
this._mutationObserver.disconnect();
}

if (this._hasDisabledContenteditable) {
this.editor.element.contentEditable = true;
}
},

mouseDown(event) {
Expand Down Expand Up @@ -280,5 +293,74 @@ export default Component.extend({
} else {
run.scheduleOnce('afterRender', this, method);
}
},

// Firefox can't handle inputs inside of a contenteditable element so we
// need to watch for any inputs being added so that we can attach focus/blur
// event handlers that can disable contenteditable on the editor element
_createMutationObserver(target, focusCallback, blurCallback) {
function addInputFocusListeners(mutation) {
function addInputFocusListener(element) {
if (!inputElements.includes(element)) {
inputElements.push(element);
element.addEventListener('focus', focusCallback, false);
element.addEventListener('blur', blurCallback, false);
}
}

if (mutation.type === 'childList') {
Array.prototype.forEach.call(
mutation.target.querySelectorAll('input[type="text"]'),
addInputFocusListener
);
}
}

function removeFromElements(element) {
inputElements.splice(inputElements.indexOf(element), 1);
}

function removeInputFocusListener(element) {
element.removeEventListener('focus', focusCallback, false);
element.removeEventListener('blur', blurCallback, false);
removeFromElements(element);
}

function mutationObserved(mutations) {
mutations.forEach(addInputFocusListeners);
}

function createMutationObserver(target) {
let config = {
childList: true,
subtree: true
};

let observer = new MutationObserver(mutationObserved);
observer.observe(target, config); // eslint-disable-line ghost/ember/no-observers
return observer;
}

let inputElements = [];
let observer = createMutationObserver(target);

return {
disconnect() {
if ('disconnect' in observer) {
observer.disconnect(); // eslint-disable-line ghost/ember/no-observers
inputElements.forEach(removeInputFocusListener);
}
}
};
},

_inputFocus() {
this._hasDisabledContenteditable = true;
this.editor.element.contentEditable = false;
},

_inputBlur() {
this._hasDisabledContenteditable = false;
this.editor.element.contentEditable = true;
}
});
6 changes: 5 additions & 1 deletion lib/koenig-editor/addon/components/koenig-editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -1065,7 +1065,11 @@ export default Component.extend({

let {range} = this.editor;
let selection = window.getSelection();
let windowRange = selection && selection.getRangeAt(0);
let windowRange;
// Safari can throw an IndexSizeError from selection.getRangeAt(0)
if (selection.type !== 'None') {
windowRange = selection && selection.getRangeAt(0);
}
let element = range.head && range.head.section && range.head.section.renderNode && range.head.section.renderNode.element;

// prevent scroll jumps when a card is selected
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
"eslint": "4.19.1",
"eslint-plugin-ghost": "0.0.25",
"fs-extra": "4.0.3",
"ghost-spirit": "0.0.24",
"ghost-spirit": "0.0.25",
"glob": "7.1.2",
"google-caja-bower": "https://github.com/acburdine/google-caja-bower#ghost",
"grunt": "1.0.3",
Expand Down
6 changes: 3 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5182,9 +5182,9 @@ ghost-ignition@^2.7.0:
prettyjson "^1.1.3"
uuid "^3.0.0"

[email protected].24:
version "0.0.24"
resolved "https://registry.yarnpkg.com/ghost-spirit/-/ghost-spirit-0.0.24.tgz#004ab09fcbc7b0ff3db6f769b66a5d6b892a4c90"
[email protected].25:
version "0.0.25"
resolved "https://registry.yarnpkg.com/ghost-spirit/-/ghost-spirit-0.0.25.tgz#dc9ff150b18002da2b554d71620d4f7ff1b911d7"
dependencies:
autoprefixer "8.2.0"
bluebird "^3.4.6"
Expand Down

0 comments on commit fe840a2

Please sign in to comment.