umberto 10.1.4 → 10.3.0
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.
- package/CHANGELOG.md +23 -16
- package/package.json +1 -1
- package/src/api-builder/classes/doc-data-factory.js +10 -2
- package/src/data-converter/converters/typedoc/abstractparser.js +14 -0
- package/src/data-converter/converters/typedoc/accessorparser.js +1 -0
- package/src/data-converter/converters/typedoc/classparser.js +1 -0
- package/src/data-converter/converters/typedoc/constantparser.js +1 -0
- package/src/data-converter/converters/typedoc/eventparser.js +1 -0
- package/src/data-converter/converters/typedoc/functionparser.js +1 -0
- package/src/data-converter/converters/typedoc/interfaceparser.js +1 -0
- package/src/data-converter/converters/typedoc/methodparser.js +1 -0
- package/src/data-converter/converters/typedoc/propertyparser.js +1 -0
- package/src/data-converter/converters/typedoc/typeparser.js +1 -0
- package/src/helpers/create-filtering-data-attribs.js +4 -0
- package/src/hexo/filter/project-locals.js +1 -1
- package/src/tasks/build-documentation.js +2 -2
- package/themes/umberto/layout/gloria/404.pug +1 -1
- package/themes/umberto/layout/gloria/_api-docs/_header/index.pug +2 -0
- package/themes/umberto/layout/gloria/_api-docs/_mixin/_badge-tag.pug +6 -0
- package/themes/umberto/layout/gloria/_api-docs/_mixin/_class-item.pug +2 -4
- package/themes/umberto/layout/gloria/_api-docs/_mixin/_method.pug +2 -4
- package/themes/umberto/layout/gloria/_api-docs/_mixin/_property.pug +2 -5
- package/themes/umberto/layout/gloria/_api-docs/_partial/filter.pug +4 -0
- package/themes/umberto/layout/gloria/_api-docs/_subheader/_style.scss +7 -0
- package/themes/umberto/layout/gloria/_api-docs/_subheader/index.pug +4 -0
- package/themes/umberto/layout/gloria/_components/tag/_style.scss +12 -0
- package/themes/umberto/layout/gloria/_modules/header-bar/_style.scss +59 -0
- package/themes/umberto/layout/gloria/_modules/header-lts-info/index.pug +69 -0
- package/themes/umberto/layout/gloria/_modules/header-nightly-info/index.pug +8 -9
- package/themes/umberto/layout/gloria/_modules/index.pug +1 -1
- package/themes/umberto/layout/gloria/_modules/kapa/index.pug +19 -0
- package/themes/umberto/layout/gloria/api.pug +1 -1
- package/themes/umberto/layout/gloria/base.pug +1 -1
- package/themes/umberto/layout/gloria/index.pug +1 -0
- package/themes/umberto/layout/gloria/theme.pug +2 -0
- package/themes/umberto/layout/umberto/_api-docs/_partial/filter.pug +4 -0
- package/themes/umberto/src/gloria/js/modules/api-filter.js +19 -10
- package/themes/umberto/src/gloria/js/modules/links-prefetch.js +4 -0
- package/themes/umberto/src/umberto/css/_badge.scss +1 -0
- package/themes/umberto/src/umberto/css/helpers/_color.scss +1 -0
- package/themes/umberto/src/umberto/js/_filtering.js +1 -0
- package/themes/umberto/layout/gloria/_modules/header-legacy-warning/index.pug +0 -11
package/CHANGELOG.md
CHANGED
|
@@ -1,44 +1,51 @@
|
|
|
1
1
|
Changelog
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
-
## [10.
|
|
4
|
+
## [10.3.0](https://github.com/cksource/umberto/compare/v10.2.0...v10.3.0) (April 3, 2026)
|
|
5
5
|
|
|
6
|
-
###
|
|
6
|
+
### Features
|
|
7
7
|
|
|
8
|
-
*
|
|
8
|
+
* Added support for displaying and filtering experimental API items in TypeDoc-based API docs.
|
|
9
9
|
|
|
10
|
+
Experimental annotations now appear in page headers and member listings, and can be toggled with the API filters.
|
|
10
11
|
|
|
11
|
-
|
|
12
|
+
|
|
13
|
+
## [10.2.0](https://github.com/cksource/umberto/compare/v10.1.4...v10.2.0) (April 2, 2026)
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* Added support for configuring Kapa AI source groups via the `sourceGroupIds` option. The option can be set globally in `kapa.default` or per project to filter the widget's knowledge base to specific source groups.
|
|
12
18
|
|
|
13
19
|
### Bug fixes
|
|
14
20
|
|
|
15
|
-
*
|
|
21
|
+
* Fixed a console error thrown when hovering over a CKEditor bookmark element. The `links-prefetch` module now silently ignores anchor elements with no `href` instead of calling `new URL( '' )` and logging a spurious error.
|
|
16
22
|
|
|
23
|
+
### Other changes
|
|
17
24
|
|
|
18
|
-
|
|
25
|
+
* Removed the legacy warning banner.
|
|
26
|
+
* Added cyan LTS banner at the top of the page on LTS branch.
|
|
27
|
+
* Updated the colour of nightly banner to yellow.
|
|
19
28
|
|
|
20
|
-
### Bug fixes
|
|
21
29
|
|
|
22
|
-
|
|
30
|
+
## [10.1.4](https://github.com/cksource/umberto/compare/v10.1.3...v10.1.4) (March 20, 2026)
|
|
23
31
|
|
|
32
|
+
### Other changes
|
|
24
33
|
|
|
25
|
-
|
|
34
|
+
* Filter search results from Algolia to match the current docs version: `latest` or `lts-v47`. Filtering remains backward-compatible: hits without the docs version are still allowed.
|
|
26
35
|
|
|
27
|
-
### Bug fixes
|
|
28
36
|
|
|
29
|
-
|
|
37
|
+
## [10.1.3](https://github.com/cksource/umberto/compare/v10.1.2...v10.1.3) (March 10, 2026)
|
|
30
38
|
|
|
39
|
+
### Bug fixes
|
|
31
40
|
|
|
32
|
-
|
|
41
|
+
* Fix regression introduced in `v10.1.2` affecting slugs generated for headings. Slugs generated now should be the same as in `v10.1.1` and previous versions of Umberto.
|
|
33
42
|
|
|
34
|
-
### Features
|
|
35
43
|
|
|
36
|
-
|
|
44
|
+
## [10.1.2](https://github.com/cksource/umberto/compare/v10.1.1...v10.1.2) (March 9, 2026)
|
|
37
45
|
|
|
38
46
|
### Bug fixes
|
|
39
47
|
|
|
40
|
-
*
|
|
41
|
-
* Disabled inserting a space between the anchor link and heading when converting a document from Markdown to HTML.
|
|
48
|
+
* Removed unmaintained `hexo-renderer-markdown-it-plus` and `@ckeditor/jsdoc-plugins` dependencies by replacing them with maintained and local implementations, resolving the reported `markdown-it`-related vulnerabilities in Umberto's dependency tree.
|
|
42
49
|
|
|
43
50
|
---
|
|
44
51
|
|
package/package.json
CHANGED
|
@@ -62,6 +62,7 @@ export class DocDataFactory {
|
|
|
62
62
|
access: doclet.access,
|
|
63
63
|
inherited: doclet.mixed ? false : doclet.inherited,
|
|
64
64
|
mixed: doclet.mixed,
|
|
65
|
+
experimental: doclet.experimental || false,
|
|
65
66
|
deprecated: doclet.deprecated,
|
|
66
67
|
since: doclet.since,
|
|
67
68
|
file: doclet.file,
|
|
@@ -264,6 +265,7 @@ export class DocDataFactory {
|
|
|
264
265
|
*/
|
|
265
266
|
getClassFull( doclet ) {
|
|
266
267
|
const classMembersCollection = this._dataCollection.get( `memberof:${ doclet.longname }` );
|
|
268
|
+
const base = this._getBase( doclet, { headingDecreaseLevel: 2 } );
|
|
267
269
|
const configOptions = classMembersCollection.get( 'cfg' );
|
|
268
270
|
const properties = classMembersCollection.get( 'member' );
|
|
269
271
|
const methods = classMembersCollection.get( 'function' );
|
|
@@ -328,7 +330,7 @@ export class DocDataFactory {
|
|
|
328
330
|
augmentsNested.unshift( doclet.longname );
|
|
329
331
|
augmentsNested.reverse();
|
|
330
332
|
|
|
331
|
-
return Object.assign(
|
|
333
|
+
return Object.assign( base, {
|
|
332
334
|
configOptions: configOptionsProcessed,
|
|
333
335
|
properties: propertiesProcessed,
|
|
334
336
|
staticProperties,
|
|
@@ -644,6 +646,13 @@ function prepareBadges( item, context ) {
|
|
|
644
646
|
badges.push( deprecatedBadge );
|
|
645
647
|
}
|
|
646
648
|
|
|
649
|
+
if ( item.experimental ) {
|
|
650
|
+
badges.push( {
|
|
651
|
+
class: 'cyan badge--experimental',
|
|
652
|
+
text: 'experimental'
|
|
653
|
+
} );
|
|
654
|
+
}
|
|
655
|
+
|
|
647
656
|
if ( item.chainable ) {
|
|
648
657
|
badges.push( {
|
|
649
658
|
class: 'green',
|
|
@@ -724,7 +733,6 @@ function prepareBadges( item, context ) {
|
|
|
724
733
|
|
|
725
734
|
return badges;
|
|
726
735
|
}
|
|
727
|
-
|
|
728
736
|
function sortLongnamesAlphabetically( arr ) {
|
|
729
737
|
if ( !arr || !arr.length ) {
|
|
730
738
|
return;
|
|
@@ -370,6 +370,20 @@ export class AbstractParser {
|
|
|
370
370
|
return false;
|
|
371
371
|
}
|
|
372
372
|
|
|
373
|
+
/**
|
|
374
|
+
* Checks if the member is marked as `experimental` one.
|
|
375
|
+
*
|
|
376
|
+
* @param {BaseReflection} item
|
|
377
|
+
* @returns {Boolean}
|
|
378
|
+
*/
|
|
379
|
+
isExperimental( item ) {
|
|
380
|
+
if ( item.comment && item.comment.modifierTags ) {
|
|
381
|
+
return item.comment.modifierTags.some( tag => tag === '@experimental' );
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
return false;
|
|
385
|
+
}
|
|
386
|
+
|
|
373
387
|
/**
|
|
374
388
|
* Checks if the member is marked by the `@deprecated` JSDoc tag.
|
|
375
389
|
*
|
|
@@ -53,6 +53,7 @@ export class AccessorParser extends AbstractParser {
|
|
|
53
53
|
description: this.getComment( getSignature || setSignature ),
|
|
54
54
|
file: this.getFile( item ),
|
|
55
55
|
skipSource: this.shouldSkipSource( getSignature || setSignature ),
|
|
56
|
+
experimental: this.isExperimental( getSignature || setSignature ),
|
|
56
57
|
deprecated: this.isDeprecated( getSignature || setSignature ),
|
|
57
58
|
inherited: !!item.inheritedFrom,
|
|
58
59
|
|
|
@@ -37,6 +37,7 @@ export class ClassParser extends AbstractParser {
|
|
|
37
37
|
description: this.getComment( item ),
|
|
38
38
|
file: this.getFile( item ),
|
|
39
39
|
skipSource: this.shouldSkipSource( item ),
|
|
40
|
+
experimental: this.isExperimental( item ),
|
|
40
41
|
deprecated: this.isDeprecated( item ),
|
|
41
42
|
|
|
42
43
|
// Properties specified below will be mapped to module names once the entire project is transformed.
|
|
@@ -35,6 +35,7 @@ export class ConstantParser extends AbstractParser {
|
|
|
35
35
|
extraId: `constant-${ item.name }`,
|
|
36
36
|
file: this.getFile( item ),
|
|
37
37
|
skipSource: this.shouldSkipSource( item ),
|
|
38
|
+
experimental: this.isExperimental( item ),
|
|
38
39
|
description: this.getComment( item ),
|
|
39
40
|
deprecated: this.isDeprecated( item ),
|
|
40
41
|
|
|
@@ -38,6 +38,7 @@ export class EventParser extends AbstractParser {
|
|
|
38
38
|
description: this.getComment( item ),
|
|
39
39
|
file: this.getFile( item ),
|
|
40
40
|
skipSource: this.shouldSkipSource( item ),
|
|
41
|
+
experimental: this.isExperimental( item ),
|
|
41
42
|
deprecated: this.isDeprecated( item ),
|
|
42
43
|
inherited: !!item.inheritedFrom,
|
|
43
44
|
see: this.getRelated( item, parentName ),
|
|
@@ -38,6 +38,7 @@ export class FunctionParser extends AbstractParser {
|
|
|
38
38
|
description: this.getComment( signature ),
|
|
39
39
|
file: this.getFile( item, index ),
|
|
40
40
|
skipSource: this.shouldSkipSource( signature ),
|
|
41
|
+
experimental: this.isExperimental( signature ),
|
|
41
42
|
deprecated: this.isDeprecated( signature ),
|
|
42
43
|
see: this.getRelated( signature, parentName ),
|
|
43
44
|
|
|
@@ -36,6 +36,7 @@ export class InterfaceParser extends AbstractParser {
|
|
|
36
36
|
description: this.getComment( item ),
|
|
37
37
|
file: this.getFile( item ),
|
|
38
38
|
skipSource: this.shouldSkipSource( item ),
|
|
39
|
+
experimental: this.isExperimental( item ),
|
|
39
40
|
deprecated: this.isDeprecated( item ),
|
|
40
41
|
|
|
41
42
|
typeParameters: null,
|
|
@@ -39,6 +39,7 @@ export class MethodParser extends AbstractParser {
|
|
|
39
39
|
description: this.getComment( signature ),
|
|
40
40
|
file: this.getFile( item, index ),
|
|
41
41
|
skipSource: this.shouldSkipSource( signature ),
|
|
42
|
+
experimental: this.isExperimental( signature ),
|
|
42
43
|
deprecated: this.isDeprecated( signature ),
|
|
43
44
|
inherited: !!signature.inheritedFrom,
|
|
44
45
|
see: this.getRelated( signature, parentName ),
|
|
@@ -40,6 +40,7 @@ export class PropertyParser extends AbstractParser {
|
|
|
40
40
|
description: this.getComment( item ),
|
|
41
41
|
file: this.getFile( item ),
|
|
42
42
|
skipSource: this.shouldSkipSource( item ),
|
|
43
|
+
experimental: this.isExperimental( item ),
|
|
43
44
|
deprecated: this.isDeprecated( item ),
|
|
44
45
|
inherited: !!item.inheritedFrom,
|
|
45
46
|
see: this.getRelated( item, parentName ),
|
|
@@ -32,6 +32,7 @@ export class TypeParser extends AbstractParser {
|
|
|
32
32
|
extraId: this.getExtraId( item ),
|
|
33
33
|
file: this.getFile( item ),
|
|
34
34
|
skipSource: this.shouldSkipSource( item ),
|
|
35
|
+
experimental: this.isExperimental( item ),
|
|
35
36
|
description: this.getComment( item ),
|
|
36
37
|
deprecated: this.isDeprecated( item ),
|
|
37
38
|
firedBy: this.getFiredBy( item, parentName ),
|
|
@@ -193,8 +193,8 @@ export const projectLocals = ( ctx, {
|
|
|
193
193
|
// `sitemap` entry is not consistent across building methods of Umberto.
|
|
194
194
|
// It's often defined in the API, but it's not always available in the hexo locals.
|
|
195
195
|
// In order to make it available, it's safer to use `docSearch.indexName` which is always defined.
|
|
196
|
-
locals.isLegacy = locals.path.includes( '/legacy/' );
|
|
197
196
|
locals.isNightly = docSearch.indexName?.includes( 'nightly' ) || false;
|
|
197
|
+
locals.isLts = /\/ckeditor5\/(lts-v\d+)(?:\/|$)/.test( `/${ locals.path }` );
|
|
198
198
|
|
|
199
199
|
locals.mainOg = og || {};
|
|
200
200
|
} );
|
|
@@ -510,8 +510,8 @@ async function buildApis( projectConfigs, options = {} ) {
|
|
|
510
510
|
feedbackWidget: options.feedbackWidget,
|
|
511
511
|
pathJoin: upath.join,
|
|
512
512
|
mainOg: options.og || {},
|
|
513
|
-
|
|
514
|
-
|
|
513
|
+
isNightly: options.docSearch?.indexName?.includes( 'nightly' ) || false,
|
|
514
|
+
isLts: /\/ckeditor5\/(lts-v\d+)(?:\/|$)/.test( `/${ BASE_PATH }` )
|
|
515
515
|
},
|
|
516
516
|
projectConfig: config,
|
|
517
517
|
canonicalUrlBeginning: getCanonicalBeginning( { config, options, hexoManager } )
|
|
@@ -37,6 +37,8 @@ mixin apiHeader( config )
|
|
|
37
37
|
+checkbox({ id:'f7', name: 'name4', className: 'js-api-filter-checkbox', label: 'Internal', value: 'internal', expanded: true })
|
|
38
38
|
+dropdown-item({ narrow: true })
|
|
39
39
|
+checkbox({ id:'f5', name: 'name7', className: 'js-api-filter-checkbox', label: 'Deprecated', value: 'deprecated', expanded: true, checked: true })
|
|
40
|
+
+dropdown-item({ narrow: true })
|
|
41
|
+
+checkbox({ id:'f8', name: 'name8', className: 'js-api-filter-checkbox', label: 'Experimental', value: 'experimental', expanded: true, checked: true })
|
|
40
42
|
|
|
41
43
|
+button({
|
|
42
44
|
icon: 'unordered-list',
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
mixin badgeTag( badge, options = {} )
|
|
2
|
+
- const iconNameByBadgeText = { private: 'lock', observable: 'eye', experimental: 'experiment' };
|
|
3
|
+
- const iconName = iconNameByBadgeText[ badge.text ] || null;
|
|
4
|
+
- const linkTo = badge && badge.linkTo ? badge.linkTo : false;
|
|
5
|
+
- const className = [ options.className || '', linkTo ? 'tag--link' : '', badge.text == 'experimental' ? 'tag--experimental' : '' ].filter( Boolean ).join( ' ' );
|
|
6
|
+
+tag({ label: badge.text, icon: iconName, iconSize: options.iconSize || 'base', href: linkTo, className })
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
include ./_link-or-text.pug
|
|
2
2
|
include ./_badge.pug
|
|
3
|
+
include ./_badge-tag.pug
|
|
3
4
|
include ./_dev-names.pug
|
|
4
5
|
include ./_api-see-source.pug
|
|
5
6
|
include ../../_components/icon/index
|
|
@@ -22,10 +23,7 @@ mixin classItem( item )
|
|
|
22
23
|
if isNonEmptyArray( item.badges )
|
|
23
24
|
+tagWrapper()
|
|
24
25
|
each badge in item.badges
|
|
25
|
-
|
|
26
|
-
- const linkTo = badge && badge.linkTo ? badge.linkTo : null;
|
|
27
|
-
- const linkClassName = linkTo ? 'tag--link' : '';
|
|
28
|
-
+tag({ label: badge.text, icon: iconName, iconSize: 'sm', href: linkTo, className: linkClassName })
|
|
26
|
+
+badgeTag( badge, { iconSize: 'sm' } )
|
|
29
27
|
|
|
30
28
|
+devNames( item.longname )
|
|
31
29
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
include _badge
|
|
2
|
+
include _badge-tag.pug
|
|
2
3
|
include _type
|
|
3
4
|
include _params
|
|
4
5
|
include _return
|
|
@@ -52,10 +53,7 @@ mixin method( met )
|
|
|
52
53
|
if isNonEmptyArray( met.badges )
|
|
53
54
|
+tagWrapper()
|
|
54
55
|
each badge in met.badges
|
|
55
|
-
|
|
56
|
-
- const linkTo = badge && badge.linkTo ? badge.linkTo : null;
|
|
57
|
-
- const linkClassName = linkTo ? 'tag--link' : '';
|
|
58
|
-
+tag({ label: badge.text, icon: iconName, iconSize: 'sm', href: linkTo, className: linkClassName })
|
|
56
|
+
+badgeTag( badge, { iconSize: 'sm' } )
|
|
59
57
|
|
|
60
58
|
+devNames( met.longname, met.label )
|
|
61
59
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
include _params
|
|
2
2
|
include ./_type.pug
|
|
3
3
|
include ./_badge.pug
|
|
4
|
+
include ./_badge-tag.pug
|
|
4
5
|
include ./_dev-names.pug
|
|
5
6
|
include ./_api-see-source.pug
|
|
6
7
|
include ./_related.pug
|
|
@@ -26,10 +27,7 @@ mixin property( prop )
|
|
|
26
27
|
if isNonEmptyArray( prop.badges )
|
|
27
28
|
+tagWrapper()
|
|
28
29
|
each badge in prop.badges
|
|
29
|
-
|
|
30
|
-
- const linkTo = badge && badge.linkTo ? badge.linkTo : null;
|
|
31
|
-
- const linkClassName = linkTo ? 'tag--link' : '';
|
|
32
|
-
+tag({ label: badge.text, icon: iconName, iconSize: 'sm', href: linkTo, className: linkClassName })
|
|
30
|
+
+badgeTag( badge, { iconSize: 'sm' } )
|
|
33
31
|
|
|
34
32
|
+devNames( prop.longname )
|
|
35
33
|
|
|
@@ -54,4 +52,3 @@ mixin property( prop )
|
|
|
54
52
|
|
|
55
53
|
if isNonEmptyArray( prop.see )
|
|
56
54
|
+related( prop.see )
|
|
57
|
-
|
|
@@ -38,3 +38,7 @@ div( class="notice notice__filter api-props-filter hidden-loading" )
|
|
|
38
38
|
input( type="checkbox" id="f5" value="deprecated" )
|
|
39
39
|
label( for="f5" )
|
|
40
40
|
span( class="badge badge--red" ) Deprecated
|
|
41
|
+
li
|
|
42
|
+
input( type="checkbox" id="f8" value="experimental" checked )
|
|
43
|
+
label( for="f8" )
|
|
44
|
+
span( class="badge badge--cyan" ) Experimental
|
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
include ../_mixin/_badge
|
|
2
|
+
include ../_mixin/_badge-tag.pug
|
|
2
3
|
|
|
3
4
|
mixin apiSubheader()
|
|
4
5
|
- const iconName = "api-" + data.kind.toLowerCase();
|
|
5
6
|
- const iconClassName = "api-icon api-icon--" + data.kind.toLowerCase();
|
|
6
7
|
- const tagClassName = "tag--api tag--api-" + data.kind.toLowerCase();
|
|
8
|
+
- const experimentalBadge = isNonEmptyArray( data.badges ) ? data.badges.find( badge => badge.text == 'experimental' ) : null;
|
|
7
9
|
|
|
8
10
|
div(class="api-subheader hidden-loading")
|
|
9
11
|
div.api-subheader__badges
|
|
10
12
|
+tag({ label: data.kind, icon : iconName, className: tagClassName })
|
|
13
|
+
if experimentalBadge
|
|
14
|
+
+badgeTag( experimentalBadge )
|
|
@@ -20,6 +20,18 @@
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
+
&--experimental {
|
|
24
|
+
color: var(--color-cyan-600);
|
|
25
|
+
border-color: var(--color-cyan-600);
|
|
26
|
+
background-color: var(--color-cyan-50);
|
|
27
|
+
|
|
28
|
+
&.tag--link {
|
|
29
|
+
&:hover {
|
|
30
|
+
background-color: var(--color-cyan-100);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
23
35
|
&__icon {
|
|
24
36
|
|
|
25
37
|
+ .tag__text {
|
|
@@ -27,6 +27,29 @@
|
|
|
27
27
|
color: var(--color-common-white);
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
&--lts {
|
|
31
|
+
--a11y-focus-ring-color: color-mix(in srgb, var(--color-cyan-500) 40%, transparent);
|
|
32
|
+
--a11y-focus-border-color: var(--color-common-white);
|
|
33
|
+
|
|
34
|
+
background-color: var(--color-cyan-500);
|
|
35
|
+
color: var(--color-common-white);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
&--warning,
|
|
39
|
+
&--lts {
|
|
40
|
+
font-size: var(--font-size-sm);
|
|
41
|
+
|
|
42
|
+
.c-icon-message {
|
|
43
|
+
line-height: 1;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.c-icon-message__content {
|
|
47
|
+
flex: none;
|
|
48
|
+
display: inline-flex;
|
|
49
|
+
align-items: center;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
30
53
|
&--info-gradient {
|
|
31
54
|
background: linear-gradient(240deg, var(--color-info-800), var(--color-info-500));
|
|
32
55
|
color: var(--color-common-white);
|
|
@@ -37,6 +60,42 @@
|
|
|
37
60
|
}
|
|
38
61
|
}
|
|
39
62
|
|
|
63
|
+
.b-prose a,
|
|
64
|
+
.b-link {
|
|
65
|
+
color: inherit;
|
|
66
|
+
text-decoration-color: currentColor;
|
|
67
|
+
|
|
68
|
+
&:hover,
|
|
69
|
+
&:focus,
|
|
70
|
+
&:active {
|
|
71
|
+
color: inherit;
|
|
72
|
+
text-decoration-color: currentColor;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
&__label {
|
|
77
|
+
flex-shrink: 0;
|
|
78
|
+
padding: 0.15rem 0.55rem;
|
|
79
|
+
border: 1px solid currentColor;
|
|
80
|
+
border-radius: 999px;
|
|
81
|
+
background-color: color-mix(in srgb, currentColor 12%, transparent);
|
|
82
|
+
font-size: var(--font-size-xs);
|
|
83
|
+
font-weight: var(--font-weight-bold);
|
|
84
|
+
letter-spacing: 0.08em;
|
|
85
|
+
text-transform: uppercase;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
&__label-text {
|
|
89
|
+
font-weight: inherit;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
&__message {
|
|
93
|
+
display: flex;
|
|
94
|
+
flex-wrap: wrap;
|
|
95
|
+
align-items: center;
|
|
96
|
+
font-weight: var(--font-weight-medium);
|
|
97
|
+
}
|
|
98
|
+
|
|
40
99
|
@include mobile {
|
|
41
100
|
gap: var(--spacing-2);
|
|
42
101
|
justify-content: flex-start;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
mixin header-lts-info()
|
|
2
|
+
+preload-svg-spritesheet-icon({ icon: 'exclamation-circle' })
|
|
3
|
+
if isLts
|
|
4
|
+
-
|
|
5
|
+
const latestUrl = `${ page.canonicalUrlBeginning }${ page.path }`
|
|
6
|
+
.replace('ckeditor5.github.io/', 'ckeditor.com/')
|
|
7
|
+
.replace(/\/ckeditor5\/lts-v\d+(?=\/|$)/, '/ckeditor5/latest')
|
|
8
|
+
.replace(projectLocals.projectVersion, 'latest')
|
|
9
|
+
.replace(/\/+$/, '');
|
|
10
|
+
|
|
11
|
+
+header-bar({ variant: 'lts', ariaLabel: 'LTS documentation' })
|
|
12
|
+
span.c-icon-message.u-font-weight--bold
|
|
13
|
+
span.c-icon-message__icon
|
|
14
|
+
+svg-icon({ icon: 'exclamation-circle', size: 'lg', ariaHidden: true })
|
|
15
|
+
span.c-icon-message__content LTS
|
|
16
|
+
|
|
17
|
+
span.c-header-bar__message
|
|
18
|
+
span You're in the Long Term Support Edition documentation.
|
|
19
|
+
|
|
|
20
|
+
a.b-link.u-text-decoration--underline(href=latestUrl) Go to the latest version of the standard edition.
|
|
21
|
+
|
|
22
|
+
script.
|
|
23
|
+
(function() {
|
|
24
|
+
document.addEventListener( 'DOMContentLoaded', () => {
|
|
25
|
+
if ( !/\/ckeditor5\/lts-v\d+(?:\/|$)/.test( window.location.pathname ) ) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if ( document.querySelector( '.c-header-bar--lts' ) ) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
document.querySelector( '.c-header-bar[aria-label="Legacy documentation warning"]' )?.remove();
|
|
34
|
+
|
|
35
|
+
const insertionPoint = document.querySelector( '.js-header-bar, .js-header' );
|
|
36
|
+
|
|
37
|
+
if ( !insertionPoint?.parentNode ) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const latestUrl = new URL( window.location.href );
|
|
42
|
+
|
|
43
|
+
latestUrl.pathname = latestUrl.pathname.replace( /\/ckeditor5\/lts-v\d+(?=\/|$)/, '/ckeditor5/latest' );
|
|
44
|
+
latestUrl.hash = '';
|
|
45
|
+
|
|
46
|
+
const banner = document.createElement( 'div' );
|
|
47
|
+
|
|
48
|
+
banner.innerHTML = `
|
|
49
|
+
<div class="c-header-bar c-header-bar--lts js-header-bar" role="region" aria-label="LTS documentation">
|
|
50
|
+
<span class="c-icon-message u-font-weight--bold">
|
|
51
|
+
<span class="c-icon-message__icon">
|
|
52
|
+
<svg-icon icon="exclamation-circle" size="lg" aria-hidden="true"></svg-icon>
|
|
53
|
+
</span>
|
|
54
|
+
<span class="c-icon-message__content">LTS</span>
|
|
55
|
+
</span>
|
|
56
|
+
<span class="c-header-bar__message">
|
|
57
|
+
<span>You're in the Long Term Support Edition documentation. </span>
|
|
58
|
+
<a class="b-link u-text-decoration--underline" href="${ latestUrl.toString() }">Go to the latest version of the standard edition.</a>
|
|
59
|
+
</span>
|
|
60
|
+
</div>
|
|
61
|
+
`.trim();
|
|
62
|
+
|
|
63
|
+
insertionPoint.parentNode.insertBefore( banner.firstElementChild, insertionPoint );
|
|
64
|
+
|
|
65
|
+
if ( window.umberto?.Header?.the ) {
|
|
66
|
+
window.umberto.Header.the.dispatchHeaderResizeEvent();
|
|
67
|
+
}
|
|
68
|
+
}, { once: true } );
|
|
69
|
+
})();
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
mixin header-nightly-info()
|
|
2
|
+
+preload-svg-spritesheet-icon({ icon: 'exclamation-circle' })
|
|
2
3
|
if isNightly
|
|
3
4
|
-
|
|
4
5
|
const stableUrl = `${ page.canonicalUrlBeginning }${ page.path }`
|
|
@@ -7,15 +8,13 @@ mixin header-nightly-info()
|
|
|
7
8
|
.replace(projectLocals.projectVersion, 'latest')
|
|
8
9
|
.replace(/\/+$/, '');
|
|
9
10
|
|
|
10
|
-
+header-bar({ variant: '
|
|
11
|
-
|
|
12
|
-
icon
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
})
|
|
16
|
-
| NIGHTLY
|
|
11
|
+
+header-bar({ variant: 'warning', ariaLabel: 'Nightly build documentation' })
|
|
12
|
+
span.c-icon-message.u-font-weight--bold
|
|
13
|
+
span.c-icon-message__icon
|
|
14
|
+
+svg-icon({ icon: 'exclamation-circle', size: 'lg', ariaHidden: true })
|
|
15
|
+
span.c-icon-message__content NIGHTLY
|
|
17
16
|
|
|
18
|
-
span
|
|
17
|
+
span.c-header-bar__message
|
|
19
18
|
span You're viewing the nightly build documentation.
|
|
20
19
|
|
|
|
21
|
-
a.b-link.u-
|
|
20
|
+
a.b-link.u-text-decoration--underline(href=stableUrl) Go to the stable version.
|
|
@@ -6,8 +6,8 @@ include ./sidebar/index
|
|
|
6
6
|
include ./sidebar-api/index
|
|
7
7
|
include ./mobile-nav/index
|
|
8
8
|
include ./header-bar/index
|
|
9
|
-
include ./header-legacy-warning/index
|
|
10
9
|
include ./header-nightly-info/index
|
|
10
|
+
include ./header-lts-info/index
|
|
11
11
|
include ./header-promobar/index
|
|
12
12
|
include ./breadcrumbs/index
|
|
13
13
|
include ./algolia-search/index
|
|
@@ -121,9 +121,28 @@ mixin load-kapa-script( kapa )
|
|
|
121
121
|
return projectConfig.exampleQuestions.join( ',' );
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
+
function getSourceGroupIds() {
|
|
125
|
+
const defaultSourceGroupIds = ( kapa.default.sourceGroupIds || [] ).join( ',' );
|
|
126
|
+
|
|
127
|
+
if ( !projectConfig ) {
|
|
128
|
+
return defaultSourceGroupIds;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
if ( !projectConfig.sourceGroupIds ) {
|
|
132
|
+
return defaultSourceGroupIds;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if ( !projectConfig.sourceGroupIds.length ) {
|
|
136
|
+
return defaultSourceGroupIds;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return projectConfig.sourceGroupIds.join( ',' );
|
|
140
|
+
}
|
|
141
|
+
|
|
124
142
|
attributes[ 'data-modal-title' ] = getModalTitle( projectConfig );
|
|
125
143
|
attributes[ 'data-modal-ask-ai-input-placeholder' ] = getQuestionPlaceholder();
|
|
126
144
|
attributes[ 'data-modal-example-questions' ] = getExampleQuestions();
|
|
145
|
+
attributes[ 'data-source-group-ids-include' ] = getSourceGroupIds();
|
|
127
146
|
|
|
128
147
|
script&attributes(attributes)
|
|
129
148
|
|
|
@@ -191,6 +191,8 @@ div
|
|
|
191
191
|
+checkbox({ id:'f5', name: 'name7', label: 'Deprecated', value: 'deprecated', expanded: true })
|
|
192
192
|
+dropdown-item()
|
|
193
193
|
+checkbox({ id:'f7', name: 'name4', label: 'Internal', value: 'internal', expanded: true })
|
|
194
|
+
+dropdown-item()
|
|
195
|
+
+checkbox({ id:'f8', name: 'name8', label: 'Experimental', value: 'experimental', expanded: true, checked: true })
|
|
194
196
|
+dropdown-item()
|
|
195
197
|
+checkbox({ id:'f6', name: 'name3', label: 'Mixed', value: 'mixed', expanded: true })
|
|
196
198
|
|
|
@@ -38,3 +38,7 @@ div( class="notice notice__filter api-props-filter hidden-loading" )
|
|
|
38
38
|
input( type="checkbox" id="f5" value="deprecated" )
|
|
39
39
|
label( for="f5" )
|
|
40
40
|
span( class="badge badge--red" ) Deprecated
|
|
41
|
+
li
|
|
42
|
+
input( type="checkbox" id="f8" value="experimental" checked )
|
|
43
|
+
label( for="f8" )
|
|
44
|
+
span( class="badge badge--cyan" ) Experimental
|
|
@@ -139,21 +139,23 @@ export class ApiFilter extends BaseComponent {
|
|
|
139
139
|
* Sets the initial state of the API filter into local storage when there is no set yet.
|
|
140
140
|
*/
|
|
141
141
|
setInitialApiFilterState() {
|
|
142
|
-
const { apiFilterState } = this.state;
|
|
143
142
|
const { filterDropdown } = this.elements;
|
|
143
|
+
const apiFilterState = { ...this.state.apiFilterState };
|
|
144
144
|
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
const filterType = input.value;
|
|
145
|
+
Array.from( filterDropdown.querySelectorAll( '.js-api-filter-checkbox input' ) ).forEach( input => {
|
|
146
|
+
const isChecked = input.checked;
|
|
147
|
+
const filterType = input.value;
|
|
149
148
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
149
|
+
if ( apiFilterState[ filterType ] === undefined ) {
|
|
150
|
+
apiFilterState[ filterType ] = isChecked;
|
|
151
|
+
}
|
|
152
|
+
} );
|
|
153
|
+
|
|
154
|
+
window.localStorage.setItem( API_FILTER_LOCAL_STORAGE_KEY, JSON.stringify( apiFilterState ) );
|
|
153
155
|
|
|
154
156
|
this.setState( {
|
|
155
|
-
apiFilterState
|
|
156
|
-
activeFilters: Object.keys(
|
|
157
|
+
apiFilterState,
|
|
158
|
+
activeFilters: Object.keys( apiFilterState ).filter( key => apiFilterState[ key ] )
|
|
157
159
|
} );
|
|
158
160
|
}
|
|
159
161
|
|
|
@@ -163,14 +165,21 @@ export class ApiFilter extends BaseComponent {
|
|
|
163
165
|
initialApplyApiFilterState() {
|
|
164
166
|
const { apiFilterState } = this.state;
|
|
165
167
|
const { filterDropdown } = this.elements;
|
|
168
|
+
const activeFilters = [];
|
|
166
169
|
|
|
167
170
|
Array.from( filterDropdown.querySelectorAll( '.js-api-filter-checkbox input' ) ).forEach( input => {
|
|
168
171
|
const isChecked = input.checked;
|
|
169
172
|
const filterType = input.value;
|
|
170
173
|
|
|
171
174
|
input.checked = apiFilterState[ filterType ] !== undefined ? apiFilterState[ filterType ] : isChecked;
|
|
175
|
+
|
|
176
|
+
if ( input.checked ) {
|
|
177
|
+
activeFilters.push( filterType );
|
|
178
|
+
}
|
|
172
179
|
} );
|
|
173
180
|
|
|
181
|
+
this.setState( { activeFilters } );
|
|
182
|
+
|
|
174
183
|
// this.dispatchInitialFolderStateDoneEvent();
|
|
175
184
|
}
|
|
176
185
|
|
|
@@ -124,6 +124,10 @@ export class LinksPrefetch {
|
|
|
124
124
|
* @returns Whether the URL should be preloaded
|
|
125
125
|
*/
|
|
126
126
|
function isPreloadable( url ) {
|
|
127
|
+
if ( !url ) {
|
|
128
|
+
return false;
|
|
129
|
+
}
|
|
130
|
+
|
|
127
131
|
try {
|
|
128
132
|
const urlObj = new URL( url );
|
|
129
133
|
const currentDomain = window.location.hostname;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
mixin header-legacy-warning()
|
|
2
|
-
if isLegacy && (!sitemap || !isNightly)
|
|
3
|
-
+header-bar({ variant: 'warning', ariaLabel: 'Legacy documentation warning' })
|
|
4
|
-
+icon-message({
|
|
5
|
-
icon: 'exclamation-circle',
|
|
6
|
-
iconSize: 'lg',
|
|
7
|
-
className: 'u-font-weight--bold'
|
|
8
|
-
})
|
|
9
|
-
| WARNING
|
|
10
|
-
|
|
11
|
-
span You're reading the legacy documentation.
|