umberto 2.0.2 → 2.1.2

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "umberto",
3
- "version": "2.0.2",
3
+ "version": "2.1.2",
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": "^27.1.1",
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": "^27.3.0",
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 mocha tests/ -- --recursive",
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
- 'return h.tags.includes( tag );',
131
+ `return h.tags.includes( '${ slug }' ) && h.tags.includes( tag );`,
131
132
  '} )',
132
133
  '.slice( 0, 10 )',
133
134
  '.map( function( item, idx ) {',
@@ -188,7 +189,7 @@ function getTransformDataFns( groups ) {
188
189
  'tags.forEach( function( tag ) {',
189
190
  'hitsGrouped[ tag ] = hits',
190
191
  '.filter( function( h ) {',
191
- 'return h.tags.includes( tag );',
192
+ `return h.tags.includes( '${ slug }' ) && h.tags.includes( tag );`,
192
193
  '} )',
193
194
  '.slice( 0, 10 )',
194
195
  '.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.scriptKey;
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 ] ) {
@@ -33,5 +33,8 @@ block content
33
33
 
34
34
  include _partial/functions
35
35
 
36
+ if page.reportIssueWidget
37
+ include ../_partial/report-issue-widget
38
+
36
39
  block navtree
37
40
  != navTree
@@ -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
+ } )();
@@ -9,6 +9,9 @@ block content
9
9
 
10
10
  != split.content
11
11
 
12
+ if page.reportIssueWidget
13
+ include _partial/report-issue-widget
14
+
12
15
  block navtree
13
16
  if projectLocals && projectLocals.apiTree
14
17
  != projectLocals.apiTree
@@ -12,5 +12,8 @@ block content
12
12
 
13
13
  != split.content
14
14
 
15
+ if page.reportIssueWidget
16
+ include _partial/report-issue-widget
17
+
15
18
  block navtree
16
19
  include _partial/nav-tree
@@ -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 );