You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-08-24 20:19:10 +02:00
iOS: Rich Text Editor: Fix the "edit" button for code blocks (#12924)
This commit is contained in:
@@ -1104,6 +1104,7 @@ packages/editor/ProseMirror/types.js
|
||||
packages/editor/ProseMirror/utils/UndoStackSynchronizer.js
|
||||
packages/editor/ProseMirror/utils/canReplaceSelectionWith.js
|
||||
packages/editor/ProseMirror/utils/computeSelectionFormatting.js
|
||||
packages/editor/ProseMirror/utils/dom/createButton.js
|
||||
packages/editor/ProseMirror/utils/dom/createTextArea.js
|
||||
packages/editor/ProseMirror/utils/dom/createTextNode.js
|
||||
packages/editor/ProseMirror/utils/dom/createUniqueId.js
|
||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1077,6 +1077,7 @@ packages/editor/ProseMirror/types.js
|
||||
packages/editor/ProseMirror/utils/UndoStackSynchronizer.js
|
||||
packages/editor/ProseMirror/utils/canReplaceSelectionWith.js
|
||||
packages/editor/ProseMirror/utils/computeSelectionFormatting.js
|
||||
packages/editor/ProseMirror/utils/dom/createButton.js
|
||||
packages/editor/ProseMirror/utils/dom/createTextArea.js
|
||||
packages/editor/ProseMirror/utils/dom/createTextNode.js
|
||||
packages/editor/ProseMirror/utils/dom/createUniqueId.js
|
||||
|
@@ -13,14 +13,16 @@ interface Options {
|
||||
doneLabel: string|Promise<string>;
|
||||
block: SourceBlockData;
|
||||
onSave: (newContent: SourceBlockData)=> void;
|
||||
onDismiss: ()=> void;
|
||||
}
|
||||
|
||||
const createEditorDialog = ({ editorLabel, doneLabel, block, onSave }: Options) => {
|
||||
const createEditorDialog = ({ editorLabel, doneLabel, block, onSave, onDismiss }: Options) => {
|
||||
const dialog = document.createElement('dialog');
|
||||
dialog.classList.add('editor-dialog', '-visible');
|
||||
document.body.appendChild(dialog);
|
||||
|
||||
dialog.onclose = () => {
|
||||
onDismiss();
|
||||
dialog.remove();
|
||||
};
|
||||
|
||||
|
@@ -5,8 +5,8 @@ import sanitizeHtml from '../../utils/sanitizeHtml';
|
||||
import createEditorDialog from './createEditorDialog';
|
||||
import { getEditorApi } from '../joplinEditorApiPlugin';
|
||||
import { msleep } from '@joplin/utils/time';
|
||||
import createTextNode from '../../utils/dom/createTextNode';
|
||||
import postProcessRenderedHtml from './postProcessRenderedHtml';
|
||||
import createButton from '../../utils/dom/createButton';
|
||||
import makeLinksClickableInElement from '../../utils/makeLinksClickableInElement';
|
||||
|
||||
// See the fold example for more information about
|
||||
@@ -117,6 +117,7 @@ export const nodeSpecs = {
|
||||
type GetPosition = ()=> number;
|
||||
|
||||
class EditableSourceBlockView implements NodeView {
|
||||
private editDialogVisible_ = false;
|
||||
public readonly dom: HTMLElement;
|
||||
public constructor(private node: Node, inline: boolean, private view: EditorView, private getPosition: GetPosition) {
|
||||
if ((node.attrs.contentHtml ?? undefined) === undefined) {
|
||||
@@ -134,6 +135,10 @@ class EditableSourceBlockView implements NodeView {
|
||||
}
|
||||
|
||||
private showEditDialog_() {
|
||||
if (this.editDialogVisible_) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { localize: _ } = getEditorApi(this.view.state);
|
||||
|
||||
let saveCounter = 0;
|
||||
@@ -177,6 +182,9 @@ class EditableSourceBlockView implements NodeView {
|
||||
),
|
||||
);
|
||||
},
|
||||
onDismiss: () => {
|
||||
this.editDialogVisible_ = false;
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -187,16 +195,10 @@ class EditableSourceBlockView implements NodeView {
|
||||
|
||||
const attrs = this.node.attrs as JoplinEditableAttributes;
|
||||
const addEditButton = () => {
|
||||
const editButton = document.createElement('button');
|
||||
editButton.classList.add('edit');
|
||||
|
||||
const { localize: _ } = getEditorApi(this.view.state);
|
||||
|
||||
editButton.appendChild(createTextNode(_('Edit')));
|
||||
editButton.onclick = (event) => {
|
||||
this.showEditDialog_();
|
||||
event.preventDefault();
|
||||
};
|
||||
const editButton = createButton(_('Edit'), () => this.showEditDialog_());
|
||||
editButton.classList.add('edit');
|
||||
|
||||
if (!attrs.readOnly) {
|
||||
this.dom.appendChild(editButton);
|
||||
|
41
packages/editor/ProseMirror/utils/dom/createButton.ts
Normal file
41
packages/editor/ProseMirror/utils/dom/createButton.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
import { LocalizationResult } from '../../../types';
|
||||
import createTextNode from './createTextNode';
|
||||
|
||||
type OnClick = ()=> void;
|
||||
|
||||
const createButton = (label: LocalizationResult, onClick: OnClick) => {
|
||||
const button = document.createElement('button');
|
||||
button.appendChild(createTextNode(label));
|
||||
|
||||
// Works around an issue on iOS in which certain <button> elements within the selected
|
||||
// region of a contenteditable container do not emit a "click" event when tapped with a touchscreen.
|
||||
const applyIOSClickWorkaround = () => {
|
||||
// touchend events can be received even when a touch is no longer contained within
|
||||
// the initial element.
|
||||
const buttonContainsTouch = (touch: Touch) => {
|
||||
return document.elementFromPoint(touch.clientX, touch.clientY) === button;
|
||||
};
|
||||
|
||||
let containedTouchStart = false;
|
||||
button.addEventListener('touchcancel', () => {
|
||||
containedTouchStart = false;
|
||||
});
|
||||
button.addEventListener('touchstart', () => {
|
||||
containedTouchStart = true;
|
||||
});
|
||||
button.addEventListener('touchend', (event) => {
|
||||
if (containedTouchStart && event.touches.length === 0 && buttonContainsTouch(event.changedTouches[0])) {
|
||||
onClick();
|
||||
event.preventDefault();
|
||||
}
|
||||
containedTouchStart = false;
|
||||
});
|
||||
};
|
||||
|
||||
applyIOSClickWorkaround();
|
||||
button.onclick = onClick;
|
||||
|
||||
return button;
|
||||
};
|
||||
|
||||
export default createButton;
|
Reference in New Issue
Block a user