Skip to content

Commit

Permalink
Normalize UI node selection
Browse files Browse the repository at this point in the history
  • Loading branch information
luin committed Nov 2, 2023
1 parent c35e6ba commit 322c39f
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 84 deletions.
4 changes: 0 additions & 4 deletions assets/core.styl
Original file line number Diff line number Diff line change
Expand Up @@ -204,10 +204,6 @@ resets(arr)
.ql-ui
position: absolute

li
> .ql-ui
position: static;

.ql-editor.ql-blank::before
color: rgba(0,0,0,0.6)
content: attr(data-placeholder)
Expand Down
2 changes: 2 additions & 0 deletions core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import Keyboard from './modules/keyboard';
import Uploader from './modules/uploader';
import Delta, { Op, OpIterator, AttributeMap } from 'quill-delta';
import Input from './modules/input';
import UINodeSelection from './modules/uiNodeSelection';

export { Delta, Op, OpIterator, AttributeMap };

Expand All @@ -34,6 +35,7 @@ Quill.register({
'modules/keyboard': Keyboard,
'modules/uploader': Uploader,
'modules/input': Input,
'modules/uiSelection': UINodeSelection,
});

export default Quill;
2 changes: 1 addition & 1 deletion e2e/list.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { expect } from '@playwright/test';
import { test } from './fixtures';
import { isMac } from './utils';

const listTypes = ['bullet']; //, 'ordered', 'checked', 'unchecked'];
const listTypes = ['bullet', 'ordered', 'checked', 'unchecked'];

test.describe('list', () => {
test.beforeEach(async ({ editorPage }) => {
Expand Down
81 changes: 2 additions & 79 deletions modules/keyboard.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import cloneDeep from 'lodash.clonedeep';
import isEqual from 'lodash.isequal';
import Delta, { AttributeMap } from 'quill-delta';
import { EmbedBlot, Scope, TextBlot } from 'parchment';
import { type Blot, BlockBlot } from 'parchment';
import { EmbedBlot, Scope, TextBlot, type Blot } from 'parchment';
import { type BlockBlot } from 'parchment';
import Quill from '../core/quill';
import logger from '../core/logger';
import Module from '../core/module';
Expand Down Expand Up @@ -629,83 +629,6 @@ const defaultOptions: KeyboardOptions = {
},
};

const jumpToLineBeginningHandler: BindingObject['handler'] = function (
range,
{ line, offset, event },
) {
console.log('=====1');
if (!(line instanceof BlockBlot)) return true;
const [leaf] = this.quill.getLeaf(range.index);
if (!(leaf instanceof TextBlot)) return true;
console.log('=====2');
const selection = document.getSelection();
const selectionBounds =
selection && selection.rangeCount > 0
? selection.getRangeAt(0).getBoundingClientRect()
: null;
if (!selectionBounds) return true;
console.log('=====3');

const selectionPosition = selectionBounds.top;
const targetPosition = line.domNode.getBoundingClientRect().top;
const linePadding = parseInt(getComputedStyle(line.domNode).paddingTop, 10);

console.log('=====4');
// Check the distance between the selection and the embed blot.
//
// If it is larger than one line height, it should be the case that
// the cursor is not in the last line of a paragraph.
// In this case we'll let browser handle the event
// so it can move the cursor to the next line.
const diff = selectionPosition - targetPosition - linePadding;

const lineHeight = parseInt(getComputedStyle(line.domNode).lineHeight, 10);

if (diff > lineHeight) return true;
console.log('=====5');

console.log({
index: range.index - offset,
length: event.shiftKey ? offset : 0,
});
this.quill.setSelection(
{ index: range.index - offset, length: event.shiftKey ? offset : 0 },
Quill.sources.USER,
);
};

console.log('@@@@@@@@@@@', isMac);
if (isMac) {
const macBindings: Record<string, Binding> = {
'jump to line beginning (CMD+ArrowLeft)': {
key: 'ArrowLeft',
shortKey: true,
shiftKey: null,
collapsed: null,
handler: jumpToLineBeginningHandler,
},
'jump to line beginning (CTRL+a)': {
key: 'a',
ctrlKey: true,
shiftKey: null,
collapsed: null,
handler: jumpToLineBeginningHandler,
},
};
console.log('!!!');
Object.assign(defaultOptions.bindings, macBindings);
} else {
const pcBindings: Record<string, Binding> = {
'line jump to beginning': {
key: 'Home',
shiftKey: null,
collapsed: null,
handler: jumpToLineBeginningHandler,
},
};
Object.assign(defaultOptions.bindings, pcBindings);
}

Keyboard.DEFAULTS = defaultOptions;

function makeCodeBlockHandler(indent: boolean): BindingObject {
Expand Down
30 changes: 30 additions & 0 deletions modules/uiNodeSelection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { ParentBlot } from 'parchment';
import Module from '../core/module';
import type Quill from '../core/quill';

class UINodeSelection extends Module {
constructor(quill: Quill, options: Record<string, never>) {
super(quill, options);

document.addEventListener('selectionchange', () => {
const selection = document.getSelection();
if (!selection) return;
const range = selection.getRangeAt(0);
console.log({ range });
if (range.collapsed !== true || range.startOffset !== 0) return;

const line = this.quill.scroll.find(range.startContainer);
if (!(line instanceof ParentBlot) || !line.uiNode) return;
console.log({ line });

const newRange = document.createRange();
newRange.setStartAfter(line.uiNode);
newRange.setEndAfter(line.uiNode);
console.log('newRange', newRange);
selection.removeAllRanges();
selection.addRange(newRange);
});
}
}

export default UINodeSelection;
1 change: 1 addition & 0 deletions website/src/components/standalone/FullEditor.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ const FullEditor = () => (
modules: {
syntax: true,
toolbar: '#toolbar-container',
uiNodeSelection: true,
},
placeholder: 'Compose an epic...',
theme: 'snow',
Expand Down

0 comments on commit 322c39f

Please sign in to comment.