umberto 9.1.2 → 9.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/CHANGELOG.md +11 -15
  2. package/package.json +1 -1
  3. package/scripts/filter/after-post-render/time-end.js +1 -1
  4. package/scripts/filter/before-post-render/gloria/prerender-xml-pug-components.js +1 -1
  5. package/scripts/utils/execute-and-insert-function-results.js +1 -1
  6. package/scripts/utils/has-own-favicons.js +1 -1
  7. package/scripts/utils/inline-svg.js +2 -2
  8. package/scripts/utils/logcrossprojectreference.js +1 -1
  9. package/scripts/utils/parseicontag.js +1 -1
  10. package/scripts/utils/parselinks.js +1 -1
  11. package/scripts/utils/pug-renderer/render-pug-component.js +1 -1
  12. package/scripts/utils/random-id.js +1 -1
  13. package/scripts/utils/spritesheet-svg.js +2 -2
  14. package/scripts/utils/toc.js +46 -6
  15. package/src/api-builder/build-page-worker.js +1 -1
  16. package/src/api-builder/classes/description-parser.js +1 -1
  17. package/src/helpers/get-docsearch-config.js +1 -1
  18. package/src/helpers/github-url.js +1 -1
  19. package/src/helpers/import-module.js +1 -1
  20. package/src/helpers/log-with-time.js +1 -1
  21. package/src/hexo-manager.js +1 -1
  22. package/src/index.js +2 -2
  23. package/src/sdk-builder/get-sdk-sources.js +1 -1
  24. package/src/sdk-builder/sdk-builder.js +1 -1
  25. package/src/tasks/create-sitemap-index.js +1 -1
  26. package/src/tasks/create-sitemap-step.js +1 -1
  27. package/src/tasks/create-sitemap.js +2 -2
  28. package/src/tasks/create-sym-links.js +2 -2
  29. package/src/tasks/get-hexo-config.js +1 -1
  30. package/src/tasks/get-main-config.js +1 -1
  31. package/src/tasks/get-project-config.js +1 -1
  32. package/src/tasks/minify-html-worker.js +1 -1
  33. package/src/tasks/minify-html.js +3 -3
  34. package/src/tasks/read-doc-sources.js +1 -1
  35. package/src/tasks/run-webpack.js +1 -1
  36. package/src/tasks/validate-html-w3c.js +1 -1
  37. package/src/tasks/validate-links.js +1 -1
  38. package/src/tasks/watcher.js +1 -1
  39. package/src/template/template-collection.js +1 -1
  40. package/themes/umberto/layout/gloria/_modules/sentry/index.pug +7 -1
  41. package/themes/umberto/layout/gloria/_modules/toc/_style.scss +10 -1
  42. package/themes/umberto/src/gloria/js/modules/algolia-search.js +45 -0
package/CHANGELOG.md CHANGED
@@ -1,6 +1,17 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ ## [9.1.3](https://github.com/cksource/umberto/compare/v9.1.2...v9.1.3) (December 19, 2025)
5
+
6
+ ### Bug fixes
7
+
8
+ * Fixed the conflict where typing the forward slash in the Kapa widget would trigger the Algolia search.
9
+
10
+ ### Other changes
11
+
12
+ * Added CKBox (`CKBOX_VERSION`) and CKEditor 5 (`CKEDITOR_VERSION`) versions to events sent to Sentry integration.
13
+
14
+
4
15
  ## [9.1.2](https://github.com/cksource/umberto/compare/v9.1.1...v9.1.2) (December 8, 2025)
5
16
 
6
17
  ### Bug fixes
@@ -37,21 +48,6 @@ Changelog
37
48
 
38
49
  * Updated the required version of Node.js to **v24.11**.
39
50
 
40
-
41
- ## [8.4.0](https://github.com/cksource/umberto/compare/v8.3.5...v8.4.0) (October 30, 2025)
42
-
43
- ### Features
44
-
45
- * Minify output HTML to reduce file size and improve load performance.
46
-
47
- The output is automatically minified during production builds to remove unnecessary whitespace and comments.
48
-
49
- Minification is **disabled when using the `--dev` modifier**, ensuring the generated HTML remains readable for easier debugging and inspection.
50
-
51
- ### Other changes
52
-
53
- * Umberto reads a project configuration once and passes it through the pipeline. Thanks to that, hooks can modify it, which affects a project's build.
54
-
55
51
  ---
56
52
 
57
53
  To see all releases, visit the [release page](https://github.com/cksource/umberto/releases).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "umberto",
3
- "version": "9.1.2",
3
+ "version": "9.1.3",
4
4
  "description": "CKSource Documentation builder",
5
5
  "main": "src/index.js",
6
6
  "files": [
@@ -5,7 +5,7 @@
5
5
 
6
6
  'use strict';
7
7
 
8
- const { format, styleText } = require( 'util' );
8
+ const { format, styleText } = require( 'node:util' );
9
9
 
10
10
  hexo.extend.filter.register( 'after_post_render', page => {
11
11
  if ( !hexo.projectGlobals.common || !hexo.projectGlobals.common.verbose ) {
@@ -42,7 +42,7 @@
42
42
 
43
43
  'use strict';
44
44
 
45
- const path = require( 'path' );
45
+ const path = require( 'node:path' );
46
46
  const removeIndentation = require( '../../../utils/remove-indentation' );
47
47
  const createPrerenderPugTemplate = require( '../../../utils/pug-renderer/create-prerender-pug-template' );
48
48
  const {
@@ -6,7 +6,7 @@
6
6
  'use strict';
7
7
 
8
8
  const upath = require( 'upath' );
9
- const fs = require( 'fs' );
9
+ const fs = require( 'node:fs' );
10
10
 
11
11
  const EXEC_REGEXP = /\\?{@exec ([^}]+)\\?}/g;
12
12
  const PATH_REGEXP = /[\w.\\/-]+\.c?js$/;
@@ -6,7 +6,7 @@
6
6
  'use strict';
7
7
 
8
8
  const upath = require( 'upath' );
9
- const fs = require( 'fs' );
9
+ const fs = require( 'node:fs' );
10
10
 
11
11
  /**
12
12
  * Checks if the project has its own favicons. If so, they will be used when rendering meta tags (`<link rel="icon">`).
@@ -5,8 +5,8 @@
5
5
 
6
6
  'use strict';
7
7
 
8
- const fs = require( 'fs' );
9
- const path = require( 'path' );
8
+ const fs = require( 'node:fs' );
9
+ const path = require( 'node:path' );
10
10
  const { parseDocument } = require( 'htmlparser2' );
11
11
  const { Element, Text } = require( 'domhandler' );
12
12
  const { selectAll, selectOne } = require( 'css-select' );
@@ -5,7 +5,7 @@
5
5
 
6
6
  'use strict';
7
7
 
8
- const { styleText } = require( 'util' );
8
+ const { styleText } = require( 'node:util' );
9
9
 
10
10
  /**
11
11
  * Logs an error message about a cross-project reference found in the parsed expression.
@@ -5,7 +5,7 @@
5
5
 
6
6
  'use strict';
7
7
 
8
- const crypto = require( 'crypto' );
8
+ const crypto = require( 'node:crypto' );
9
9
  const upath = require( 'upath' );
10
10
  const logCrossProjectReference = require( './logcrossprojectreference' );
11
11
 
@@ -5,7 +5,7 @@
5
5
 
6
6
  'use strict';
7
7
 
8
- const { styleText } = require( 'util' );
8
+ const { styleText } = require( 'node:util' );
9
9
  const upath = require( 'upath' );
10
10
  const splitLongname = require( '../../src/helpers/split-longname' );
11
11
 
@@ -5,7 +5,7 @@
5
5
 
6
6
  'use strict';
7
7
 
8
- const path = require( 'path' );
8
+ const path = require( 'node:path' );
9
9
  const hexoManager = require( '../../../src/hexo-manager' );
10
10
 
11
11
  /**
@@ -5,7 +5,7 @@
5
5
 
6
6
  'use strict';
7
7
 
8
- const crypto = require( 'crypto' );
8
+ const crypto = require( 'node:crypto' );
9
9
 
10
10
  /**
11
11
  * Generates a random ID with a single segment. If a prefix is provided, it will be prepended to the ID.
@@ -5,8 +5,8 @@
5
5
 
6
6
  'use strict';
7
7
 
8
- const fs = require( 'fs' );
9
- const path = require( 'path' );
8
+ const fs = require( 'node:fs' );
9
+ const path = require( 'node:path' );
10
10
  const { parseDocument } = require( 'htmlparser2' );
11
11
  const { Element, cloneNode } = require( 'domhandler' );
12
12
  const { selectAll, selectOne } = require( 'css-select' );
@@ -43,14 +43,25 @@ module.exports = function toc( data, options = {} ) {
43
43
  for ( const heading of headings ) {
44
44
  const hLevel = Number( heading.name[ 1 ] ); // 'h2' -> 2
45
45
  const text = getHeadingText( heading ).trim();
46
+ const icons = getHeadingIcons( heading );
46
47
  const li = new Element( 'li', {} );
47
- const a = new Element( 'a', {
48
- class: 'a11y-focusable',
48
+ const aAttrs = {
49
+ class: icons.length > 0 ? 'a11y-focusable c-toc__link--with-icon' : 'a11y-focusable',
49
50
  href: '#' + getAttributeValue( heading, 'id' ),
50
51
  title: text
51
- } );
52
+ };
52
53
 
53
- appendChild( a, new Text( text ) );
54
+ const a = new Element( 'a', aAttrs );
55
+
56
+ // Append text first, then icons (only if icons exist)
57
+ if ( text ) {
58
+ appendChild( a, new Text( text ) );
59
+ }
60
+ if ( icons.length > 0 ) {
61
+ for ( const icon of icons ) {
62
+ appendChild( a, cloneNode( icon, true ) );
63
+ }
64
+ }
54
65
  appendChild( li, a );
55
66
 
56
67
  if ( tocLastLevels[ hLevel ] ) {
@@ -107,7 +118,7 @@ function hasAncestorWithClassIn( node, classNames ) {
107
118
  }
108
119
 
109
120
  /**
110
- * Returns the heading text without content from descendants with class "headerlink".
121
+ * Returns the heading text without content from descendants with class "headerlink", "editor-icon", or badge components.
111
122
  */
112
123
  function getHeadingText( root ) {
113
124
  if ( !root ) {
@@ -117,9 +128,38 @@ function getHeadingText( root ) {
117
128
  // Clone so we don't mutate the original AST.
118
129
  const clone = cloneNode( root, true );
119
130
 
120
- for ( const node of selectAll( '.headerlink', clone ) ) {
131
+ // Remove headerlinks, editor-icons, and badge components (which contain icons)
132
+ for ( const node of selectAll( '.headerlink, .editor-icon, .c-badge', clone ) ) {
121
133
  removeElement( node );
122
134
  }
123
135
 
124
136
  return textContent( clone );
125
137
  }
138
+
139
+ /**
140
+ * Returns icon elements from the heading.
141
+ * Looks for:
142
+ * - Elements with class "editor-icon" (legacy format)
143
+ * - Badge components with icons (c-badge with c-icon inside)
144
+ * - Direct icon elements (c-icon) within the heading
145
+ */
146
+ function getHeadingIcons( root ) {
147
+ if ( !root ) {
148
+ return [];
149
+ }
150
+
151
+ const icons = [];
152
+
153
+ const editorIcons = selectAll( '.editor-icon', root );
154
+ icons.push( ...editorIcons );
155
+
156
+ const badgesWithIcons = selectAll( '.c-badge .c-icon', root );
157
+ icons.push( ...badgesWithIcons );
158
+
159
+ const directIcons = selectAll( '.c-icon', root ).filter( icon => {
160
+ return !hasAncestorWithClassIn( icon, [ 'c-badge' ] );
161
+ } );
162
+ icons.push( ...directIcons );
163
+
164
+ return icons;
165
+ }
@@ -5,7 +5,7 @@
5
5
 
6
6
  'use strict';
7
7
 
8
- const fs = require( 'fs' );
8
+ const fs = require( 'node:fs' );
9
9
  const upath = require( 'upath' );
10
10
  const { parseDocument } = require( 'htmlparser2' );
11
11
  const { default: render } = require( 'dom-serializer' );
@@ -5,7 +5,7 @@
5
5
 
6
6
  'use strict';
7
7
 
8
- const { styleText } = require( 'util' );
8
+ const { styleText } = require( 'node:util' );
9
9
  const { parseDocument } = require( 'htmlparser2' );
10
10
  const { default: render } = require( 'dom-serializer' );
11
11
  const { selectAll, selectOne } = require( 'css-select' );
@@ -7,7 +7,7 @@
7
7
 
8
8
  const { cloneDeep } = require( 'lodash' );
9
9
  const { stringify } = require( 'javascript-stringify' );
10
- const fs = require( 'fs' );
10
+ const fs = require( 'node:fs' );
11
11
  const upath = require( 'upath' );
12
12
 
13
13
  const defaultScriptTemplate = fs.readFileSync( upath.join( __dirname, 'templates', 'scripts', 'default.js' ), 'utf-8' );
@@ -5,7 +5,7 @@
5
5
 
6
6
  'use strict';
7
7
 
8
- const { spawnSync } = require( 'child_process' );
8
+ const { spawnSync } = require( 'node:child_process' );
9
9
  const upath = require( 'upath' );
10
10
 
11
11
  const cachedGitPaths = new Set();
@@ -6,7 +6,7 @@
6
6
  'use strict';
7
7
 
8
8
  const upath = require( 'upath' );
9
- const { pathToFileURL } = require( 'url' );
9
+ const { pathToFileURL } = require( 'node:url' );
10
10
 
11
11
  /**
12
12
  * Loads the specified module using `import()` call.
@@ -5,7 +5,7 @@
5
5
 
6
6
  'use strict';
7
7
 
8
- const { styleText } = require( 'util' );
8
+ const { styleText } = require( 'node:util' );
9
9
 
10
10
  module.exports = function logWithTime( message ) {
11
11
  const lowercase = message.charAt( 0 ).toLowerCase() + message.slice( 1 );
@@ -5,7 +5,7 @@
5
5
 
6
6
  'use strict';
7
7
 
8
- const { styleText } = require( 'util' );
8
+ const { styleText } = require( 'node:util' );
9
9
  const upath = require( 'upath' );
10
10
  const fs = require( 'fs-extra' );
11
11
  const { globSync } = require( 'glob' );
package/src/index.js CHANGED
@@ -5,8 +5,8 @@
5
5
 
6
6
  'use strict';
7
7
 
8
- const { styleText } = require( 'util' );
9
- const path = require( 'path' );
8
+ const { styleText } = require( 'node:util' );
9
+ const path = require( 'node:path' );
10
10
  const compileSass = require( './tasks/compile-sass' );
11
11
  const runWebpack = require( './tasks/run-webpack' );
12
12
  const copyAssets = require( './tasks/copy-assets' );
@@ -5,7 +5,7 @@
5
5
 
6
6
  'use strict';
7
7
 
8
- const fs = require( 'fs' );
8
+ const fs = require( 'node:fs' );
9
9
  const upath = require( 'upath' );
10
10
  const { globSync } = require( 'glob' );
11
11
  const { parseDocument } = require( 'htmlparser2' );
@@ -7,7 +7,7 @@
7
7
 
8
8
  const HtmlFile = require( '../api-builder/classes/html-file' );
9
9
  const upath = require( 'upath' );
10
- const { URL, resolve: urlResolve } = require( 'url' );
10
+ const { URL, resolve: urlResolve } = require( 'node:url' );
11
11
  const beautifyHtml = require( 'js-beautify' ).html;
12
12
  const macroReplacer = require( '../tasks/macro-replacer' );
13
13
  const getDocSearchConfig = require( '../helpers/get-docsearch-config' );
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  const upath = require( 'upath' );
7
- const fs = require( 'fs/promises' );
7
+ const fs = require( 'node:fs/promises' );
8
8
 
9
9
  const XMLNS_STRINGS = [
10
10
  'xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"',
@@ -3,7 +3,7 @@
3
3
  * For licensing, see LICENSE.md.
4
4
  */
5
5
 
6
- const { styleText } = require( 'util' );
6
+ const { styleText } = require( 'node:util' );
7
7
  const createSitemap = require( './create-sitemap' );
8
8
  const createSitemapIndex = require( './create-sitemap-index' );
9
9
 
@@ -5,10 +5,10 @@
5
5
 
6
6
  'use strict';
7
7
 
8
- const fs = require( 'fs' );
8
+ const fs = require( 'node:fs' );
9
9
  const { globSync } = require( 'glob' );
10
10
  const upath = require( 'upath' );
11
- const { URL } = require( 'url' );
11
+ const { URL } = require( 'node:url' );
12
12
  const { SitemapStream, streamToPromise } = require( 'sitemap' );
13
13
 
14
14
  /**
@@ -5,8 +5,8 @@
5
5
 
6
6
  'use strict';
7
7
 
8
- const { styleText } = require( 'util' );
9
- const fs = require( 'fs' );
8
+ const { styleText } = require( 'node:util' );
9
+ const fs = require( 'node:fs' );
10
10
  const upath = require( 'upath' );
11
11
  const getProjectConfig = require( './get-project-config' );
12
12
 
@@ -6,7 +6,7 @@
6
6
  'use strict';
7
7
 
8
8
  const upath = require( 'upath' );
9
- const fs = require( 'fs' );
9
+ const fs = require( 'node:fs' );
10
10
 
11
11
  /**
12
12
  * Reads Umberto's hexo config file.
@@ -6,7 +6,7 @@
6
6
  'use strict';
7
7
 
8
8
  const upath = require( 'upath' );
9
- const fs = require( 'fs' );
9
+ const fs = require( 'node:fs' );
10
10
 
11
11
  module.exports = rootPath => {
12
12
  const configPath = upath.join( rootPath, 'umberto-main.json' );
@@ -6,7 +6,7 @@
6
6
  'use strict';
7
7
 
8
8
  const upath = require( 'upath' );
9
- const fs = require( 'fs' );
9
+ const fs = require( 'node:fs' );
10
10
  const { globSync } = require( 'glob' );
11
11
  const importModule = require( '../helpers/import-module' );
12
12
 
@@ -5,7 +5,7 @@
5
5
 
6
6
  'use strict';
7
7
 
8
- const { readFileSync, writeFileSync } = require( 'fs' );
8
+ const { readFileSync, writeFileSync } = require( 'node:fs' );
9
9
  const minifier = require( '@minify-html/node' );
10
10
 
11
11
  /**
@@ -5,9 +5,9 @@
5
5
 
6
6
  'use strict';
7
7
 
8
- const { join } = require( 'path' );
9
- const { globSync } = require( 'fs' );
10
- const { styleText } = require( 'util' );
8
+ const { join } = require( 'node:path' );
9
+ const { globSync } = require( 'node:fs' );
10
+ const { styleText } = require( 'node:util' );
11
11
  const { default: TinyPool } = require( 'tinypool' );
12
12
  const logWithTime = require( '../helpers/log-with-time' );
13
13
 
@@ -6,7 +6,7 @@
6
6
  'use strict';
7
7
 
8
8
  const upath = require( 'upath' );
9
- const fs = require( 'fs' );
9
+ const fs = require( 'node:fs' );
10
10
  const { globSync } = require( 'glob' );
11
11
  const DOC_FORMATS = require( '../helpers/doc-formats' );
12
12
 
@@ -5,7 +5,7 @@
5
5
 
6
6
  'use strict';
7
7
 
8
- const path = require( 'path' );
8
+ const path = require( 'node:path' );
9
9
  const webpack = require( 'webpack' );
10
10
 
11
11
  module.exports = ( sourceFile, destinationFile, {
@@ -3,7 +3,7 @@
3
3
  * For licensing, see LICENSE.md.
4
4
  */
5
5
 
6
- const { spawn } = require( 'child_process' );
6
+ const { spawn } = require( 'node:child_process' );
7
7
  const vnu = require( 'vnu-jar' );
8
8
 
9
9
  module.exports = ( buildPath, { verbose } = {} ) => new Promise( ( resolve, reject ) => {
@@ -11,7 +11,7 @@
11
11
  * especially for API documentation where the number of links can reach thousands.
12
12
  */
13
13
 
14
- const { styleText } = require( 'util' );
14
+ const { styleText } = require( 'node:util' );
15
15
  const fs = require( 'fs-extra' );
16
16
  const upath = require( 'upath' );
17
17
  const { globSync } = require( 'glob' );
@@ -5,7 +5,7 @@
5
5
 
6
6
  'use strict';
7
7
 
8
- const { styleText } = require( 'util' );
8
+ const { styleText } = require( 'node:util' );
9
9
  const upath = require( 'upath' );
10
10
  const chokidar = require( 'chokidar' );
11
11
  const { copy } = require( 'fs-extra' );
@@ -6,7 +6,7 @@
6
6
  'use strict';
7
7
 
8
8
  const pug = require( 'pug' );
9
- const fs = require( 'fs' );
9
+ const fs = require( 'node:fs' );
10
10
  const upath = require( 'upath' );
11
11
  const isNonEmptyArray = require( '../helpers/is-non-empty-array' );
12
12
  const createFilterAttribs = require( '../helpers/create-filtering-data-attribs' );
@@ -17,7 +17,13 @@ mixin load-sentry-script( sentry )
17
17
  'https://ckeditor5.github.io/docs/nightly'
18
18
  ],
19
19
  replaysSessionSampleRate: 0,
20
- replaysOnErrorSampleRate: 0
20
+ replaysOnErrorSampleRate: 0,
21
+ initialScope: scope => {
22
+ scope.setTags( {
23
+ CKEDITOR_VERSION: typeof CKEDITOR_VERSION !== 'undefined' ? CKEDITOR_VERSION : '(none)',
24
+ CKBOX_VERSION: typeof CKBox !== 'undefined' ? CKBox.version : '(none)',
25
+ } );
26
+ }
21
27
  } );
22
28
  };
23
29
 
@@ -183,12 +183,21 @@
183
183
  }
184
184
 
185
185
  ol a {
186
- display: block;
187
186
  padding: 0 var(--spacing-2);
188
187
  text-decoration: none;
189
188
  font-size: var(--font-size-sm);
190
189
  color: var(--color-secondary-700);
191
190
 
191
+ &:not(.c-toc__link--with-icon) {
192
+ display: block;
193
+ }
194
+
195
+ &.c-toc__link--with-icon {
196
+ display: flex;
197
+ align-items: center;
198
+ gap: var(--spacing-1);
199
+ }
200
+
192
201
  &:hover,
193
202
  &.is-active {
194
203
  color: var(--color-primary);
@@ -46,6 +46,11 @@ export class AlgoliaSearch extends BaseComponent {
46
46
  * Initializes the algolia search component.
47
47
  */
48
48
  async init() {
49
+ // IMPORTANT: Add the keyboard event interceptor BEFORE loading the DocSearch library
50
+ // It ensures our listener is registered first and can use `stopImmediatePropagation`
51
+ // to prevent DocSearch's listener from running when typing in the Kapa widget.
52
+ this._preventDocSearchShortcutInKapa();
53
+
49
54
  await injectScript( DOCSEARCH_JS_URL, {
50
55
  attributes: {
51
56
  crossorigin: 'anonymous'
@@ -88,6 +93,46 @@ export class AlgoliaSearch extends BaseComponent {
88
93
  }
89
94
  } );
90
95
  }
96
+
97
+ /**
98
+ * Prevents the DocSearch "/" keyboard shortcut from triggering when the user is typing in the Kapa widget.
99
+ * DocSearch library doesn't provide a configuration option to disable keyboard shortcuts,
100
+ * so we need to intercept the event and stop it completely before DocSearch's listener sees it.
101
+ *
102
+ * This listener is added in the capture phase BEFORE DocSearch is loaded, ensuring it runs first.
103
+ * We use stopImmediatePropagation() to prevent ALL other listeners (including DocSearch's) from running.
104
+ */
105
+ _preventDocSearchShortcutInKapa() {
106
+ document.addEventListener( 'keydown', event => {
107
+ // Only handle the "/" key
108
+ if ( event.key !== '/' ) {
109
+ return;
110
+ }
111
+
112
+ // Use `composedPath()` to check the entire event path, including through shadow DOM boundaries.
113
+ // This is more reliable than checking `document.activeElement` for shadow DOM content.
114
+ const path = event.composedPath();
115
+
116
+ const isTypingInInput = path.some( element => {
117
+ if ( !element || !element.tagName ) {
118
+ return false;
119
+ }
120
+
121
+ // Let's check different types of input fields.
122
+ // Kapa currently uses a textarea for the search input.
123
+ // But there's a chance that it will change in the future.
124
+ const isInputElement = element.tagName === 'TEXTAREA' ||
125
+ element.tagName === 'INPUT' ||
126
+ element.isContentEditable;
127
+
128
+ return isInputElement;
129
+ } );
130
+
131
+ if ( isTypingInInput ) {
132
+ event.stopImmediatePropagation();
133
+ }
134
+ }, true );
135
+ }
91
136
  }
92
137
 
93
138
  /**