umberto 2.0.1 → 2.1.1
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/package.json +5 -4
- package/scripts/filter/before-post-render/add-project-info-to-page.js +4 -0
- package/scripts/utils/getreportissuewidgeturl.js +38 -0
- package/src/api-builder/api-builder.js +6 -0
- package/src/helpers/get-docsearch-config.js +5 -4
- package/src/hexo/filter/project-locals.js +1 -0
- package/src/sdk-builder/sdk-builder.js +1 -0
- package/src/tasks/get-project-config.js +30 -2
- package/themes/umberto/layout/_api-docs/api-base.pug +3 -0
- package/themes/umberto/layout/_partial/report-issue-widget.pug +22 -0
- package/themes/umberto/layout/api.pug +3 -0
- package/themes/umberto/layout/page.pug +3 -0
- package/themes/umberto/src/css/_notice.scss +4 -0
- package/themes/umberto/src/js/_apisearch.js +6 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "umberto",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"description": "CKSource Documentation builder",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"files": [
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"@babel/core": "^7.10.3",
|
|
17
17
|
"@babel/polyfill": "^7.10.1",
|
|
18
18
|
"@babel/preset-env": "^7.10.3",
|
|
19
|
-
"@ckeditor/jsdoc-plugins": "^
|
|
19
|
+
"@ckeditor/jsdoc-plugins": "^30.1.4",
|
|
20
20
|
"babel-loader": "^8.1.0",
|
|
21
21
|
"chalk": "^4.1.0",
|
|
22
22
|
"cheerio": "^0.22.0",
|
|
@@ -42,6 +42,7 @@
|
|
|
42
42
|
"medium-zoom": "^1.0.5",
|
|
43
43
|
"mkdirp": "^1.0.4",
|
|
44
44
|
"moment": "^2.27.0",
|
|
45
|
+
"minimatch": "^3.1.2",
|
|
45
46
|
"nyc": "15.1.0",
|
|
46
47
|
"pug": "^3.0.0",
|
|
47
48
|
"sass": "^1.43.4",
|
|
@@ -53,7 +54,7 @@
|
|
|
53
54
|
"webpack": "^5.58.1"
|
|
54
55
|
},
|
|
55
56
|
"devDependencies": {
|
|
56
|
-
"@ckeditor/ckeditor5-dev-env": "^
|
|
57
|
+
"@ckeditor/ckeditor5-dev-env": "^30.1.4",
|
|
57
58
|
"browser-sync": "^2.26.7",
|
|
58
59
|
"chai": "^4.3.4",
|
|
59
60
|
"chokidar": "^3.4.0",
|
|
@@ -75,7 +76,7 @@
|
|
|
75
76
|
"dev:serve": "node ./scripts-dev/serve.js",
|
|
76
77
|
"lint": "eslint --quiet '**/*.js'",
|
|
77
78
|
"test": "mocha tests --recursive",
|
|
78
|
-
"coverage": "nyc --reporter=lcov --reporter=text-summary
|
|
79
|
+
"coverage": "nyc --reporter=lcov --reporter=text-summary --cache false npm run test",
|
|
79
80
|
"changelog": "node ./scripts-dev/changelog.js",
|
|
80
81
|
"release:bump-version": "node ./scripts-dev/bump-version.js",
|
|
81
82
|
"release:publish": "node ./scripts-dev/publish.js"
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
const upath = require( 'upath' );
|
|
9
9
|
const shouldDisplayNewIndicator = require( '../../utils/shoulddisplaynewindicator' );
|
|
10
|
+
const getReportIssueWidgetUrl = require( '../../utils/getreportissuewidgeturl' );
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Adds project information (e.g. BASE_PATH, project name, group id) to each page.
|
|
@@ -42,6 +43,9 @@ hexo.extend.filter.register( 'before_post_render', page => {
|
|
|
42
43
|
|
|
43
44
|
page.shouldDisplayNewIndicator = shouldDisplayNewIndicator( page );
|
|
44
45
|
|
|
46
|
+
// This line needs to be sync with the `src/api-builder/api-builder.js` file.
|
|
47
|
+
page.reportIssueWidget = getReportIssueWidgetUrl( page, projectGlobals.config );
|
|
48
|
+
|
|
45
49
|
return page;
|
|
46
50
|
}, 3 );
|
|
47
51
|
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license Copyright (c) 2017-2022, CKSource Holding sp. z o.o. All rights reserved.
|
|
3
|
+
* For licensing, see LICENSE.md.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
'use strict';
|
|
7
|
+
|
|
8
|
+
const minimatch = require( 'minimatch' );
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @param {Object} page A page object.
|
|
12
|
+
* @param {String} page.path A relative path where a page will be stored.
|
|
13
|
+
* @param {Object} config The project configuration.
|
|
14
|
+
* @param {Object} config.reportIssueWidget The report issue widget configuration.
|
|
15
|
+
* @param {Boolean} config.reportIssueWidget.enabled Whether the report issue widget is enabled.
|
|
16
|
+
* @param {Array.<String>} config.reportIssueWidget.skipPages An array of glob patterns that define pages where
|
|
17
|
+
* the report issue widget should be disabled.
|
|
18
|
+
* @param {String} config.reportIssueWidget.issueUrl The URL that leads to a form where a user can create a new issue.
|
|
19
|
+
* @return {String|null}
|
|
20
|
+
*/
|
|
21
|
+
module.exports = function getReportIssueWidgetUrl( page, config ) {
|
|
22
|
+
if ( !config.reportIssueWidget.enabled ) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const isAllowedOnPage = !config.reportIssueWidget.skipPages.some( pattern => {
|
|
27
|
+
// Map a pattern to: `<slug>/<version>/<path>`.
|
|
28
|
+
const globPatern = config.slug + '/*/' + pattern;
|
|
29
|
+
|
|
30
|
+
return minimatch( page.path, globPatern );
|
|
31
|
+
} );
|
|
32
|
+
|
|
33
|
+
if ( !isAllowedOnPage ) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return config.reportIssueWidget.issueUrl;
|
|
38
|
+
};
|
|
@@ -18,6 +18,7 @@ const getShortModulePath = require( '../helpers/get-short-module-path' );
|
|
|
18
18
|
const getDocSearchConfig = require( '../helpers/get-docsearch-config' );
|
|
19
19
|
const splitLongname = require( '../helpers/split-longname' );
|
|
20
20
|
const githubUrlUtils = require( '../helpers/github-url' );
|
|
21
|
+
const getReportIssueWidgetUrl = require( '../../scripts/utils/getreportissuewidgeturl' );
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* Renders HTML for every module, class, mixin etc.
|
|
@@ -424,6 +425,10 @@ module.exports = class ApiBuilder {
|
|
|
424
425
|
'twitter-card': trimDescription( { min: 300, max: 600, text: metaDescription } ),
|
|
425
426
|
'dc-description': trimDescription( { min: 300, max: 600, text: metaDescription } )
|
|
426
427
|
};
|
|
428
|
+
|
|
429
|
+
// This line needs to be sync with the `scripts/filter/before-post-render/add-project-info-to-page.js` file.
|
|
430
|
+
page.reportIssueWidget = getReportIssueWidgetUrl( page, this._projectConfig );
|
|
431
|
+
|
|
427
432
|
// More locals to be used in templates. Matching locals used by hexo.
|
|
428
433
|
const projectLocals = {
|
|
429
434
|
latestBasePath: upath.join( this._projectSlug, 'latest' ),
|
|
@@ -432,6 +437,7 @@ module.exports = class ApiBuilder {
|
|
|
432
437
|
getLinkToSource: githubUrlUtils.getFullGithubLink.bind( this ),
|
|
433
438
|
docSearchConfig: getDocSearchConfig( this._docSearch, {
|
|
434
439
|
groups: this._groups,
|
|
440
|
+
slug: this._projectSlug,
|
|
435
441
|
customRanking: this._projectConfig.docsearch ? this._projectConfig.docsearch.customRanking : []
|
|
436
442
|
} )
|
|
437
443
|
};
|
|
@@ -10,6 +10,7 @@ const { cloneDeep } = require( 'lodash' );
|
|
|
10
10
|
|
|
11
11
|
module.exports = ( searchConfig, {
|
|
12
12
|
groups = [],
|
|
13
|
+
slug = '',
|
|
13
14
|
customRanking = []
|
|
14
15
|
} = {} ) => {
|
|
15
16
|
if ( !searchConfig ) {
|
|
@@ -53,7 +54,7 @@ module.exports = ( searchConfig, {
|
|
|
53
54
|
].join( '\n' )
|
|
54
55
|
};
|
|
55
56
|
|
|
56
|
-
const transformDataFunctions = getTransformDataFns( groups );
|
|
57
|
+
const transformDataFunctions = getTransformDataFns( groups, slug );
|
|
57
58
|
|
|
58
59
|
if ( transformDataFunctions ) {
|
|
59
60
|
for ( const tag of Object.keys( transformDataFunctions ) ) {
|
|
@@ -86,7 +87,7 @@ module.exports = ( searchConfig, {
|
|
|
86
87
|
return docSearchConfig;
|
|
87
88
|
};
|
|
88
89
|
|
|
89
|
-
function getTransformDataFns( groups ) {
|
|
90
|
+
function getTransformDataFns( groups, slug ) {
|
|
90
91
|
if ( !Array.isArray( groups ) || groups.length === 0 ) {
|
|
91
92
|
return null;
|
|
92
93
|
}
|
|
@@ -114,7 +115,7 @@ function getTransformDataFns( groups ) {
|
|
|
114
115
|
|
|
115
116
|
`hitsGrouped[ '${ g.slug }' ] = hits`,
|
|
116
117
|
'.filter( function( h ) {',
|
|
117
|
-
`return h.tags.includes( '${ g.slug }' );`,
|
|
118
|
+
`return h.tags.includes( '${ slug }' ) && h.tags.includes( '${ g.slug }' );`,
|
|
118
119
|
'} )',
|
|
119
120
|
'.slice( 0, 7 )',
|
|
120
121
|
'.map( function( item, idx ) {',
|
|
@@ -127,7 +128,7 @@ function getTransformDataFns( groups ) {
|
|
|
127
128
|
`if ( tag !== '${ g.slug }' ) {`,
|
|
128
129
|
'hitsGrouped[ tag ] = hits',
|
|
129
130
|
'.filter( function( h ) {',
|
|
130
|
-
|
|
131
|
+
`return h.tags.includes( '${ slug }' ) && h.tags.includes( tag );`,
|
|
131
132
|
'} )',
|
|
132
133
|
'.slice( 0, 10 )',
|
|
133
134
|
'.map( function( item, idx ) {',
|
|
@@ -63,6 +63,7 @@ module.exports = ( ctx, {
|
|
|
63
63
|
disableSearch: config.docsearch === false,
|
|
64
64
|
docSearchConfig: getDocSearchConfig( docSearch, {
|
|
65
65
|
groups: config.groups,
|
|
66
|
+
slug: config.slug,
|
|
66
67
|
customRanking: config.docsearch ? config.docsearch.customRanking : []
|
|
67
68
|
} ),
|
|
68
69
|
repoUrl: config.repoUrl,
|
|
@@ -156,6 +156,7 @@ module.exports = class SdkBuilder {
|
|
|
156
156
|
projectSlug,
|
|
157
157
|
docSearchConfig: getDocSearchConfig( this._docSearch, {
|
|
158
158
|
groups: this.projectConfig.groups,
|
|
159
|
+
slug: this.projectConfig.slug,
|
|
159
160
|
customRanking: this.projectConfig.docsearch ? this.projectConfig.docsearch.customRanking : []
|
|
160
161
|
} )
|
|
161
162
|
};
|
|
@@ -9,6 +9,8 @@ const upath = require( 'upath' );
|
|
|
9
9
|
const fs = require( 'fs' );
|
|
10
10
|
const glob = require( 'glob' );
|
|
11
11
|
|
|
12
|
+
const cache = new Map();
|
|
13
|
+
|
|
12
14
|
/**
|
|
13
15
|
* Reads project's umberto.json config, validates it and adds various properties.
|
|
14
16
|
*
|
|
@@ -18,7 +20,15 @@ const glob = require( 'glob' );
|
|
|
18
20
|
* @returns {Object}
|
|
19
21
|
*/
|
|
20
22
|
module.exports = ( rootPath, options = {} ) => {
|
|
23
|
+
// Let's normalize the root path to fix mixed slashes and backslashes. Root path should contain only slashes.
|
|
24
|
+
rootPath = rootPath.split( /[\\/]/g ).join( '/' );
|
|
25
|
+
|
|
21
26
|
const configPath = findConfigurationPath( rootPath );
|
|
27
|
+
|
|
28
|
+
if ( cache.has( configPath ) ) {
|
|
29
|
+
return cache.get( configPath );
|
|
30
|
+
}
|
|
31
|
+
|
|
22
32
|
const config = getConfigurationFile( configPath );
|
|
23
33
|
|
|
24
34
|
config.__configPath = configPath;
|
|
@@ -58,6 +68,22 @@ module.exports = ( rootPath, options = {} ) => {
|
|
|
58
68
|
} );
|
|
59
69
|
}
|
|
60
70
|
|
|
71
|
+
// If the "reportIssueWidget" is missing, let's add. Default values will be filled in next steps.
|
|
72
|
+
if ( !config.reportIssueWidget ) {
|
|
73
|
+
config.reportIssueWidget = {};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Prepare default values.
|
|
77
|
+
config.reportIssueWidget.enabled = config.reportIssueWidget.enabled || false;
|
|
78
|
+
config.reportIssueWidget.skipPages = config.reportIssueWidget.skipPages || [];
|
|
79
|
+
|
|
80
|
+
// And check whether the `issueUrl` is available if the widget is enabled.
|
|
81
|
+
if ( config.reportIssueWidget.enabled && !config.reportIssueWidget.issueUrl ) {
|
|
82
|
+
throw new Error(
|
|
83
|
+
`[${ config.name }]: The "reportIssueWidget.issueUrl" value must be specified if the report issue widget is enabled.`
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
61
87
|
validateConfiguration( config );
|
|
62
88
|
|
|
63
89
|
config.version = getProjectVersion( rootPath );
|
|
@@ -67,6 +93,9 @@ module.exports = ( rootPath, options = {} ) => {
|
|
|
67
93
|
// Packages of the project. Packages can have their own guides and they need to be included in the documentation.
|
|
68
94
|
config.items = config.items || getPackages( rootPath, config.slug, config.packagesDir );
|
|
69
95
|
|
|
96
|
+
// Store the configuration.
|
|
97
|
+
cache.set( configPath, config );
|
|
98
|
+
|
|
70
99
|
return config;
|
|
71
100
|
};
|
|
72
101
|
|
|
@@ -122,8 +151,7 @@ function loadScriptToConfig( config, options ) {
|
|
|
122
151
|
return;
|
|
123
152
|
}
|
|
124
153
|
|
|
125
|
-
const scriptKey = options
|
|
126
|
-
const configKey = options.configKey;
|
|
154
|
+
const { scriptKey, configKey } = options;
|
|
127
155
|
|
|
128
156
|
// Do not load anything if the script is not specified in the configuration file.
|
|
129
157
|
if ( !config.scripts[ scriptKey ] ) {
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
//- Remove the "project-slug/version/" from the path.
|
|
2
|
+
- const shortPageUrl = page.path.split( '/' ).slice( 2 ).join( '/' )
|
|
3
|
+
- const githubUrl = new URL( page.reportIssueWidget );
|
|
4
|
+
- githubUrl.searchParams.set( 'title', 'Docs issue report from "' + shortPageUrl + '"' );
|
|
5
|
+
|
|
6
|
+
div.info-box.notice.notice__feedback
|
|
7
|
+
p
|
|
8
|
+
| Every day, we work hard to keep our documentation complete. Have you spotted an outdated information? Is something missing?
|
|
9
|
+
| Please report it via our!{' '}
|
|
10
|
+
a( href=githubUrl.toString() id='report-widget-issue-tracker' ) issue tracker
|
|
11
|
+
| .
|
|
12
|
+
|
|
13
|
+
//- We need to inject some parameters to the URL from the `window` object on the user side.
|
|
14
|
+
//- Hence, we run a script that reads the user-agent and location and injects it into the issue URL.
|
|
15
|
+
script.
|
|
16
|
+
( () => {
|
|
17
|
+
const issueTracker = document.getElementById( 'report-widget-issue-tracker' );
|
|
18
|
+
const hrefUrl = new URL( issueTracker.href );
|
|
19
|
+
hrefUrl.searchParams.set( 'user-agent', navigator.userAgent )
|
|
20
|
+
hrefUrl.searchParams.set( 'origin-url', location.href )
|
|
21
|
+
issueTracker.href = hrefUrl.toString();
|
|
22
|
+
} )();
|
|
@@ -55,6 +55,10 @@ p.tip {
|
|
|
55
55
|
border-left: 3px solid u-color( 'hint-info' );
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
+
&__feedback {
|
|
59
|
+
border-left: 3px solid u-color( 'hint-hint' );
|
|
60
|
+
}
|
|
61
|
+
|
|
58
62
|
&__warning {
|
|
59
63
|
border-left: 3px solid u-color( 'hint-warning' );
|
|
60
64
|
background-color: rgba( u-color( 'hint-warning' ), .1 );
|
|
@@ -115,7 +115,12 @@ export function setUpFuse() {
|
|
|
115
115
|
|
|
116
116
|
function addHighlight( text, searchedQuery ) {
|
|
117
117
|
const highlightClass = 'algolia-docsearch-suggestion--highlight';
|
|
118
|
-
|
|
118
|
+
|
|
119
|
+
// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions.
|
|
120
|
+
// See: #984.
|
|
121
|
+
const escapedQuery = searchedQuery.replace( /[.*+?^${}()|[\]\\]/g, '\\$&' );
|
|
122
|
+
|
|
123
|
+
const queryRegex = new RegExp( `(${ escapedQuery })`, 'gi' );
|
|
119
124
|
|
|
120
125
|
return text.replace( queryRegex, `<span class="${ highlightClass }">$1</span>` );
|
|
121
126
|
}
|