diff --git a/packages/ckeditor5-utils/src/env.js b/packages/ckeditor5-utils/src/env.js index 8fa34e2c639..f744436c6d1 100644 --- a/packages/ckeditor5-utils/src/env.js +++ b/packages/ckeditor5-utils/src/env.js @@ -5,6 +5,8 @@ /* globals navigator:false */ +import global from './dom/global'; + /** * @module utils/env */ @@ -71,7 +73,15 @@ const env = { * * @type {Boolean} */ - isRegExpUnicodePropertySupported: isRegExpUnicodePropertySupported() + isRegExpUnicodePropertySupported: isRegExpUnicodePropertySupported(), + + /** + * Indicates that the environment supports at least [Input Events Level 1](https://www.w3.org/TR/input-events-1/) + * (`input` and `beforeinput` events). + * + * @type {Boolean} + */ + isInputEventsLevel1Supported: isInputEventsLevel1Supported( global.window ) } }; @@ -151,3 +161,16 @@ export function isRegExpUnicodePropertySupported() { return isSupported; } + +/** + * Checks if the current environment supports at least [Input Events Level 1](https://www.w3.org/TR/input-events-1/) + * (`input` and `beforeinput` events). + * + * @param {Window} domWindow The DOM Window interface. + * @returns {Boolean} + */ +export function isInputEventsLevel1Supported( domWindow ) { + const inputEvent = new domWindow.InputEvent( 'input' ); + + return 'inputType' in inputEvent && 'getTargetRanges' in inputEvent; +} diff --git a/packages/ckeditor5-utils/tests/env.js b/packages/ckeditor5-utils/tests/env.js index cc66fa23fef..35eea3b2316 100644 --- a/packages/ckeditor5-utils/tests/env.js +++ b/packages/ckeditor5-utils/tests/env.js @@ -3,7 +3,15 @@ * For licensing, see LICENSE.md or https://ckeditor.com/legal/ckeditor-oss-license */ -import env, { isMac, isGecko, isSafari, isAndroid, isRegExpUnicodePropertySupported, isBlink } from '../src/env'; +import env, { + isMac, + isGecko, + isSafari, + isAndroid, + isBlink, + isRegExpUnicodePropertySupported, + isInputEventsLevel1Supported +} from '../src/env'; function toLowerCase( str ) { return str.toLowerCase(); @@ -54,6 +62,12 @@ describe( 'Env', () => { expect( env.features.isRegExpUnicodePropertySupported ).to.be.a( 'boolean' ); } ); } ); + + describe( 'isInputEventsLevel1Supported', () => { + it( 'is a boolean', () => { + expect( env.features.isInputEventsLevel1Supported ).to.be.a( 'boolean' ); + } ); + } ); } ); describe( 'isMac()', () => { @@ -201,4 +215,27 @@ describe( 'Env', () => { } } ); } ); + + describe( 'isInputEventsLevel1Supported()', () => { + it( 'should detect the Input Events Level 1 support', () => { + class InputEventStubWhenSupported { + constructor() { + this.inputType = ''; + this.getTargetRanges = () => {}; + } + } + + const DOMWindowStubWhenSupported = { + InputEvent: InputEventStubWhenSupported + }; + + const DOMWindowStubWhenUnsupported = { + // eslint-disable-next-line + InputEvent: function () {} + }; + + expect( isInputEventsLevel1Supported( DOMWindowStubWhenSupported ) ).to.be.true; + expect( isInputEventsLevel1Supported( DOMWindowStubWhenUnsupported ) ).to.be.false; + } ); + } ); } );