umberto 8.0.3 → 8.1.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 +11 -7
- package/package.json +1 -1
- package/scripts/filter/after-post-render/gloria/apply-design-doc-classes.js +6 -55
- package/scripts/filter/after-post-render/gloria/wrap-table-into-wrappers.js +11 -5
- package/scripts/utils/apply-design-doc-classes.js +82 -0
- package/scripts/utils/{pipe.js → compose.js} +1 -1
- package/scripts/utils/concat-url-parts.js +2 -2
- package/src/helpers/resolve-path.js +13 -0
- package/src/hexo/get-repo-urls.js +1 -1
- package/src/tasks/copy-project-docs.js +4 -4
- package/src/tasks/copy-project-icons.js +4 -1
- package/themes/umberto/src/gloria/js/components/iframe.js +1 -10
- package/themes/umberto/src/gloria/js/helpers/{pipe.js → compose.js} +1 -1
- package/themes/umberto/src/gloria/js/modules/algolia-search.js +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
Changelog
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
+
## [8.1.0](https://github.com/cksource/umberto/compare/v8.0.3...v8.1.0) (August 12, 2025)
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* Added support for relative paths in `packagesDir` option.
|
|
9
|
+
|
|
10
|
+
### Bug fixes
|
|
11
|
+
|
|
12
|
+
* Updated how `<iframe>` elements are created to fix issues with automated tests using Chrome v139.
|
|
13
|
+
|
|
14
|
+
|
|
4
15
|
## [8.0.3](https://github.com/cksource/umberto/compare/v8.0.2...v8.0.3) (August 5, 2025)
|
|
5
16
|
|
|
6
17
|
### Bug fixes
|
|
@@ -54,13 +65,6 @@ Changelog
|
|
|
54
65
|
* The repository now uses ESLint v9. Therefore, the required Node.js version has been upgraded to 22 to match the ESLint requirements.
|
|
55
66
|
* Update `LICENSE.md` file to include licenses of direct dependencies
|
|
56
67
|
|
|
57
|
-
|
|
58
|
-
## [7.0.2](https://github.com/cksource/umberto/compare/v7.0.1...v7.0.2) (2025-05-20)
|
|
59
|
-
|
|
60
|
-
### Bug fixes
|
|
61
|
-
|
|
62
|
-
* Fixed an invalid protocol (should be `https://` instead of `https:/`) in the generated index sitemap file. Closes [#1277](https://github.com/cksource/umberto/issues/1277). ([commit](https://github.com/cksource/umberto/commit/6f59654e85b1230fbfe029efe68f708755ec6342))
|
|
63
|
-
|
|
64
68
|
---
|
|
65
69
|
|
|
66
70
|
To see all releases, visit the [release page](https://github.com/cksource/umberto/releases).
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
|
|
6
6
|
'use strict';
|
|
7
7
|
|
|
8
|
-
const
|
|
8
|
+
const applyDesignDocClasses = require( '../../../utils/apply-design-doc-classes' );
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Global mapping of HTML elements to their corresponding design system classes.
|
|
@@ -86,60 +86,11 @@ hexo.extend.filter.register( 'after_post_render', page => {
|
|
|
86
86
|
return page;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
$elements.each( ( _, element ) => {
|
|
96
|
-
const $element = $( element );
|
|
97
|
-
|
|
98
|
-
if ( hasClassOrParentWithClass( $element, 'no-transform' ) ) {
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
// Add the 'doc' class to each element that gets styled
|
|
103
|
-
$element.addClass( 'doc' );
|
|
104
|
-
|
|
105
|
-
const classList = ( $element.attr( 'class' )?.split( /\s+/ ) || [] ).filter(
|
|
106
|
-
className => !ELEMENTS_WITH_WHITELIST_CLASSES.includes( className )
|
|
107
|
-
);
|
|
108
|
-
|
|
109
|
-
// Avoid applying classes to elements that already have one.
|
|
110
|
-
if ( classList.length > 1 ) {
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
// Add the specified classes
|
|
115
|
-
if ( typeof classesOrCallback === 'function' ) {
|
|
116
|
-
const elementClasses = classesOrCallback( $element );
|
|
117
|
-
|
|
118
|
-
if ( Array.isArray( elementClasses ) ) {
|
|
119
|
-
$element.addClass( elementClasses.join( ' ' ) );
|
|
120
|
-
} else if ( typeof elementClasses === 'string' ) {
|
|
121
|
-
$element.addClass( elementClasses );
|
|
122
|
-
}
|
|
123
|
-
} else if ( Array.isArray( classesOrCallback ) ) {
|
|
124
|
-
$element.addClass( classesOrCallback.join( ' ' ) );
|
|
125
|
-
} else {
|
|
126
|
-
$element.addClass( classesOrCallback );
|
|
127
|
-
}
|
|
128
|
-
} );
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
page.content = $.html();
|
|
89
|
+
page.content = applyDesignDocClasses( {
|
|
90
|
+
elementsClassesMappings: ELEMENTS_CLASSES_MAPPINGS,
|
|
91
|
+
elementsWithWhitelistClasses: ELEMENTS_WITH_WHITELIST_CLASSES,
|
|
92
|
+
content: page.content
|
|
93
|
+
} );
|
|
132
94
|
|
|
133
95
|
return page;
|
|
134
96
|
}, 40 );
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Checks if the element itself or any of its parents has the specified class.
|
|
138
|
-
*
|
|
139
|
-
* @param $element - The jQuery element to check.
|
|
140
|
-
* @param className - The class name to look for.
|
|
141
|
-
* @returns True if the element or any parent has the class, false otherwise.
|
|
142
|
-
*/
|
|
143
|
-
function hasClassOrParentWithClass( $element, className ) {
|
|
144
|
-
return $element.hasClass( className ) || $element.parents( `.${ className }` ).length > 0;
|
|
145
|
-
}
|
|
@@ -7,10 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
const cheerio = require( 'cheerio' );
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
* Enforce priority 30 to run it after apply design doc classes filter.
|
|
12
|
-
*/
|
|
13
|
-
hexo.extend.filter.register( 'after_post_render', page => {
|
|
10
|
+
function wrapTableIntoWrappers( page ) {
|
|
14
11
|
if ( page.projectTheme !== 'gloria' ) {
|
|
15
12
|
return page;
|
|
16
13
|
}
|
|
@@ -27,4 +24,13 @@ hexo.extend.filter.register( 'after_post_render', page => {
|
|
|
27
24
|
page.content = $.html();
|
|
28
25
|
|
|
29
26
|
return page;
|
|
30
|
-
}
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Enforce priority 30 to run it after apply design doc classes filter.
|
|
31
|
+
*/
|
|
32
|
+
if ( typeof hexo !== 'undefined' ) {
|
|
33
|
+
hexo.extend.filter.register( 'after_post_render', wrapTableIntoWrappers, 30 );
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
module.exports = wrapTableIntoWrappers;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2017-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
const cheerio = require( 'cheerio' );
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Add design system classes to the parsed document elements. If element has 0 CSS classes
|
|
12
|
+
* it'll be considered as not styled and the design system classes will be applied.
|
|
13
|
+
|
|
14
|
+
* @param options - Options for applying design classes.
|
|
15
|
+
* @param options.elementsClassesMappings - Mappings of elements to their classes or
|
|
16
|
+
* functions that return classes.
|
|
17
|
+
* @param options.elementsWithWhitelistClasses - List of classes that are
|
|
18
|
+
* considered as transparent in checks for amount of the classes.
|
|
19
|
+
* @param options.content - The HTML content to process.
|
|
20
|
+
*/
|
|
21
|
+
module.exports = function applyDesignDocClasses(
|
|
22
|
+
{
|
|
23
|
+
elementsClassesMappings,
|
|
24
|
+
elementsWithWhitelistClasses,
|
|
25
|
+
content
|
|
26
|
+
}
|
|
27
|
+
) {
|
|
28
|
+
const $ = cheerio.load( content, null, false );
|
|
29
|
+
|
|
30
|
+
// Apply classes based on the global mapping
|
|
31
|
+
for ( const [ element, classesOrCallback ] of Object.entries( elementsClassesMappings ) ) {
|
|
32
|
+
const $elements = $( element );
|
|
33
|
+
|
|
34
|
+
$elements.each( ( _, element ) => {
|
|
35
|
+
const $element = $( element );
|
|
36
|
+
|
|
37
|
+
if ( hasClassOrParentWithClass( $element, 'no-transform' ) ) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Add the 'doc' class to each element that gets styled
|
|
42
|
+
$element.addClass( 'doc' );
|
|
43
|
+
|
|
44
|
+
const classList = ( $element.attr( 'class' )?.split( /\s+/ ) || [] ).filter(
|
|
45
|
+
className => !elementsWithWhitelistClasses.includes( className )
|
|
46
|
+
);
|
|
47
|
+
|
|
48
|
+
// Avoid applying classes to elements that already have one.
|
|
49
|
+
if ( classList.length > 1 ) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Add the specified classes
|
|
54
|
+
if ( typeof classesOrCallback === 'function' ) {
|
|
55
|
+
const elementClasses = classesOrCallback( $element );
|
|
56
|
+
|
|
57
|
+
if ( Array.isArray( elementClasses ) ) {
|
|
58
|
+
$element.addClass( elementClasses.join( ' ' ) );
|
|
59
|
+
} else if ( typeof elementClasses === 'string' ) {
|
|
60
|
+
$element.addClass( elementClasses );
|
|
61
|
+
}
|
|
62
|
+
} else if ( Array.isArray( classesOrCallback ) ) {
|
|
63
|
+
$element.addClass( classesOrCallback.join( ' ' ) );
|
|
64
|
+
} else {
|
|
65
|
+
$element.addClass( classesOrCallback );
|
|
66
|
+
}
|
|
67
|
+
} );
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return $.html();
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Checks if the element itself or any of its parents has the specified class.
|
|
75
|
+
*
|
|
76
|
+
* @param $element - The jQuery element to check.
|
|
77
|
+
* @param className - The class name to look for.
|
|
78
|
+
* @returns True if the element or any parent has the class, false otherwise.
|
|
79
|
+
*/
|
|
80
|
+
function hasClassOrParentWithClass( $element, className ) {
|
|
81
|
+
return $element.hasClass( className ) || $element.parents( `.${ className }` ).length > 0;
|
|
82
|
+
}
|
|
@@ -12,6 +12,6 @@
|
|
|
12
12
|
* @param {*} value - The initial value to be processed by the functions.
|
|
13
13
|
* @returns {*} The final result after all functions have been applied.
|
|
14
14
|
*/
|
|
15
|
-
module.exports = function
|
|
15
|
+
module.exports = function compose( ...fns ) {
|
|
16
16
|
return value => fns.reduce( ( acc, fn ) => fn( acc ), value );
|
|
17
17
|
};
|
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
|
|
8
8
|
const dropInitSlash = require( './drop-init-slash' );
|
|
9
9
|
const dropTrailingSlash = require( './drop-trailing-slash' );
|
|
10
|
-
const
|
|
10
|
+
const compose = require( './compose' );
|
|
11
11
|
|
|
12
12
|
module.exports = function concatUrlParts( ...urls ) {
|
|
13
13
|
return (
|
|
14
14
|
urls
|
|
15
15
|
.filter( Boolean )
|
|
16
|
-
.map(
|
|
16
|
+
.map( compose( dropTrailingSlash, dropInitSlash ) )
|
|
17
17
|
.join( '/' )
|
|
18
18
|
);
|
|
19
19
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2017-2025, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Wrapper around `require.resolve()` to allow mocking it in tests.
|
|
10
|
+
*/
|
|
11
|
+
module.exports = function resolvePath( path, options ) {
|
|
12
|
+
return require.resolve( path, options );
|
|
13
|
+
};
|
|
@@ -17,7 +17,7 @@ module.exports = ( {
|
|
|
17
17
|
guidesToRepos.default = defaultRepoUrl;
|
|
18
18
|
|
|
19
19
|
for ( const item of packages ) {
|
|
20
|
-
const packageRepoUrl = getRepoUrl( upath.
|
|
20
|
+
const packageRepoUrl = getRepoUrl( upath.resolve( rootPath, item.path ) );
|
|
21
21
|
globSync( upath.join( rootPath, item.path, 'docs', '**', '*.md' ) )
|
|
22
22
|
.map( p => upath.normalize( p ) )
|
|
23
23
|
.map( p => p.replace( upath.join( rootPath, item.path, 'docs' ), '' ) )
|
|
@@ -58,13 +58,13 @@ module.exports = ( rootPath, config, options ) => {
|
|
|
58
58
|
if ( config.items && Array.isArray( config.items ) ) {
|
|
59
59
|
for ( const item of config.items ) {
|
|
60
60
|
hexoManager.addOriginPath(
|
|
61
|
-
upath.
|
|
62
|
-
upath.
|
|
61
|
+
upath.resolve( rootPath, item.path, config.path ),
|
|
62
|
+
upath.resolve( hexoManager.getSourceDir(), BASE_PATH )
|
|
63
63
|
);
|
|
64
64
|
|
|
65
65
|
promises.push( copyDocFiles(
|
|
66
|
-
upath.
|
|
67
|
-
upath.
|
|
66
|
+
upath.resolve( rootPath, item.path, config.path ),
|
|
67
|
+
upath.resolve( hexoManager.getSourceDir(), BASE_PATH ),
|
|
68
68
|
{
|
|
69
69
|
match,
|
|
70
70
|
allOutputPaths,
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
const upath = require( 'upath' );
|
|
9
9
|
const fs = require( 'fs-extra' );
|
|
10
|
+
const resolvePath = require( '../helpers/resolve-path' );
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* @returns {Promise<void>}
|
|
@@ -19,7 +20,9 @@ module.exports = async function copyProjectIcons( projectGlobals, buildDirectory
|
|
|
19
20
|
const destinationIconsPath = upath.join( buildDirectory, projectDetails.BASE_PATH, 'assets', 'icons' );
|
|
20
21
|
|
|
21
22
|
for ( const [ sourceFile, destinationName ] of projectDetails._icons ) {
|
|
22
|
-
const fullSourcePath =
|
|
23
|
+
const fullSourcePath = resolvePath( sourceFile, {
|
|
24
|
+
paths: [ projectDetails.config.projectRootPath ]
|
|
25
|
+
} );
|
|
23
26
|
const fullDestinationPath = upath.join( destinationIconsPath, destinationName );
|
|
24
27
|
|
|
25
28
|
try {
|
|
@@ -71,10 +71,7 @@ export class IFrame extends BaseComponent {
|
|
|
71
71
|
* @param content - HTML content to load
|
|
72
72
|
*/
|
|
73
73
|
setContent( content ) {
|
|
74
|
-
|
|
75
|
-
const iframeDocument = iframe.contentDocument || iframe.contentWindow?.document;
|
|
76
|
-
|
|
77
|
-
const wrappedHTML = `
|
|
74
|
+
this.elements.iframe.srcdoc = `
|
|
78
75
|
<!DOCTYPE html>
|
|
79
76
|
${ content }
|
|
80
77
|
${ this.config.autoResize ? `
|
|
@@ -91,12 +88,6 @@ export class IFrame extends BaseComponent {
|
|
|
91
88
|
</script>
|
|
92
89
|
` : '' }
|
|
93
90
|
`;
|
|
94
|
-
|
|
95
|
-
if ( iframeDocument ) {
|
|
96
|
-
iframeDocument.open();
|
|
97
|
-
iframeDocument.write( wrappedHTML );
|
|
98
|
-
iframeDocument.close();
|
|
99
|
-
}
|
|
100
91
|
}
|
|
101
92
|
|
|
102
93
|
/**
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
import { BaseComponent } from '../components/base-component';
|
|
7
7
|
import { identity } from '../helpers/identity';
|
|
8
8
|
import { injectScript } from '../helpers/inject-script';
|
|
9
|
-
import {
|
|
9
|
+
import { compose } from '../helpers/compose';
|
|
10
10
|
|
|
11
11
|
const DOCSEARCH_JS_URL = 'https://cdn.jsdelivr.net/npm/@docsearch/js@3.9.0/dist/umd/index.min.js';
|
|
12
12
|
|
|
@@ -67,7 +67,7 @@ export class AlgoliaSearch extends BaseComponent {
|
|
|
67
67
|
|
|
68
68
|
client.search = async ( options, ...rest ) => {
|
|
69
69
|
const { results: [ firstResult ] } = await originalSearch( options, ...rest );
|
|
70
|
-
const mappedResults =
|
|
70
|
+
const mappedResults = compose(
|
|
71
71
|
filterByTags( { slug, tags } ),
|
|
72
72
|
boostByTags( boost.tags )
|
|
73
73
|
)( firstResult.hits );
|
|
@@ -110,7 +110,7 @@ function boostByTags( tags ) {
|
|
|
110
110
|
return identity;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
return
|
|
113
|
+
return compose(
|
|
114
114
|
groupByTag,
|
|
115
115
|
sortObjectKeysByIndices( tags ),
|
|
116
116
|
Object.values,
|