UNPKG

ckeditor5-image-upload-base64

Version:

The development environment of CKEditor 5 – the best browser-based rich text editor.

118 lines (98 loc) 4.41 kB
/** * @license Copyright (c) 2003-2020, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ /** * @module typing/deleteobserver */ import Observer from '@ckeditor/ckeditor5-engine/src/view/observer/observer'; import DomEventData from '@ckeditor/ckeditor5-engine/src/view/observer/domeventdata'; import { keyCodes } from '@ckeditor/ckeditor5-utils/src/keyboard'; import env from '@ckeditor/ckeditor5-utils/src/env'; /** * Delete observer introduces the {@link module:engine/view/document~Document#event:delete} event. * * @extends module:engine/view/observer/observer~Observer */ export default class DeleteObserver extends Observer { constructor( view ) { super( view ); const document = view.document; let sequence = 0; document.on( 'keyup', ( evt, data ) => { if ( data.keyCode == keyCodes.delete || data.keyCode == keyCodes.backspace ) { sequence = 0; } } ); document.on( 'keydown', ( evt, data ) => { const deleteData = {}; if ( data.keyCode == keyCodes.delete ) { deleteData.direction = 'forward'; deleteData.unit = 'character'; } else if ( data.keyCode == keyCodes.backspace ) { deleteData.direction = 'backward'; deleteData.unit = 'codePoint'; } else { return; } const hasWordModifier = env.isMac ? data.altKey : data.ctrlKey; deleteData.unit = hasWordModifier ? 'word' : deleteData.unit; deleteData.sequence = ++sequence; fireViewDeleteEvent( evt, data.domEvent, deleteData ); } ); // `beforeinput` is handled only for Android devices. Desktop Chrome and iOS are skipped because they are working fine now. if ( env.isAndroid ) { document.on( 'beforeinput', ( evt, data ) => { // If event type is other than `deleteContentBackward` then this is not deleting. if ( data.domEvent.inputType != 'deleteContentBackward' ) { return; } const deleteData = { unit: 'codepoint', direction: 'backward', sequence: 1 }; // Android IMEs may change the DOM selection on `beforeinput` event so that the selection contains all the text // that the IME wants to remove. We will pass this information to `delete` event so proper part of the content is removed. // // Sometimes it is only expanding by a one character (in case of collapsed selection). In this case we don't need to // set a different selection to remove, it will work just fine. const domSelection = data.domTarget.ownerDocument.defaultView.getSelection(); if ( domSelection.anchorNode == domSelection.focusNode && domSelection.anchorOffset + 1 != domSelection.focusOffset ) { deleteData.selectionToRemove = view.domConverter.domSelectionToView( domSelection ); } fireViewDeleteEvent( evt, data.domEvent, deleteData ); } ); } function fireViewDeleteEvent( originalEvent, domEvent, deleteData ) { // Save the event object to check later if it was stopped or not. let event; document.once( 'delete', evt => ( event = evt ), { priority: Number.POSITIVE_INFINITY } ); document.fire( 'delete', new DomEventData( document, domEvent, deleteData ) ); // Stop the original event if `delete` event was stopped. // https://github.com/ckeditor/ckeditor5/issues/753 if ( event && event.stop.called ) { originalEvent.stop(); } } } /** * @inheritDoc */ observe() {} } /** * Event fired when the user tries to delete content (e.g. presses <kbd>Delete</kbd> or <kbd>Backspace</kbd>). * * Note: This event is fired by the {@link module:typing/deleteobserver~DeleteObserver observer} * (usually registered by the {@link module:typing/delete~Delete delete feature}). * * @event module:engine/view/document~Document#event:delete * @param {module:engine/view/observer/domeventdata~DomEventData} data * @param {'forward'|'delete'} data.direction The direction in which the deletion should happen. * @param {'character'|'word'} data.unit The "amount" of content that should be deleted. * @param {Number} data.sequence A number describing which subsequent delete event it is without the key being released. * If it's 2 or more it means that the key was pressed and hold. * @param {module:engine/view/selection~Selection} [data.selectionToRemove] View selection which content should be removed. If not set, * current selection should be used. */