umberto 4.0.1 → 4.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 CHANGED
@@ -1,6 +1,17 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ ## [4.1.0](https://github.com/cksource/umberto/compare/v4.0.1...v4.1.0) (2023-11-10)
5
+
6
+ ### Features
7
+
8
+ * Umberto config file now allows `permalinkDisableDomains` array that can specify domains for which the perm-link feature should not work. Closes [#1168](https://github.com/cksource/umberto/issues/1168). ([commit](https://github.com/cksource/umberto/commit/f1370bbdb38deae3b99fb4277352bdb84cacf809))
9
+
10
+ ### Bug fixes
11
+
12
+ * Generate a link (`{@link ...}`) to an existing type's property, resulting in a proper markup instead of displaying an error that the given structure (doclet) could not be found. Closes [#1182](https://github.com/cksource/umberto/issues/1182). ([commit](https://github.com/cksource/umberto/commit/972cb27cd81c6f1c83e1fc7cb42187782a60a58f))
13
+
14
+
4
15
  ## [4.0.1](https://github.com/cksource/umberto/compare/v4.0.0...v4.0.1) (2023-10-16)
5
16
 
6
17
  ### Bug fixes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "umberto",
3
- "version": "4.0.1",
3
+ "version": "4.1.0",
4
4
  "description": "CKSource Documentation builder",
5
5
  "main": "src/index.js",
6
6
  "files": [
@@ -36,6 +36,7 @@ hexo.extend.filter.register( 'before_post_render', page => {
36
36
  page.groupId = category ? category.groupId : null;
37
37
  page.groupSlug = category ? category.groupSlug : null;
38
38
  page.shortName = upath.basename( page.source ).replace( upath.extname( page.source ), '' );
39
+ page.permalinkDisableDomains = projectGlobals.config.permalinkDisableDomains.join( ',' );
39
40
 
40
41
  if ( hexo.projectGlobals.common.isSingleProject && projectGlobals.config.canonicalUrlBeginning ) {
41
42
  page.canonicalUrlBeginning = projectGlobals.config.canonicalUrlBeginning;
@@ -147,7 +147,15 @@ function linkToApi( str, data, hexo, { relativeUrlHelper, isSilentError } ) {
147
147
  }
148
148
 
149
149
  if ( hasDedicatedApiPages( targetDoclet ) ) {
150
- href = relativeUrlHelper( data.path, upath.join( basePath, apiSlug, getFileName( itemName ) ) );
150
+ let propertyName = itemName;
151
+
152
+ // Properties of `type` do not have own doclets. Instead, they are specified as `properties` in the `type`
153
+ // (parent) doclet. Hence, we must link to it manually. See: #1182.
154
+ if ( targetDoclet.kind === 'typedef' ) {
155
+ propertyName = propertyName.replace( '#', '#member-' );
156
+ }
157
+
158
+ href = relativeUrlHelper( data.path, upath.join( basePath, apiSlug, getFileName( propertyName ) ) );
151
159
  } else {
152
160
  href = [
153
161
  relativeUrlHelper( data.path, upath.join( basePath, apiSlug, fileName ) ),
@@ -189,7 +197,15 @@ function getBaseItemName( itemName ) {
189
197
  }
190
198
 
191
199
  function getFileName( itemName ) {
192
- return itemName.replace( /[/:.]/g, '_' ).replace( '~', '-' ) + '.html';
200
+ const output = itemName.replace( /[/:.]/g, '_' ).replace( '~', '-' );
201
+ const [ fileNameWithHash, extension = 'html' ] = output.split( '.' );
202
+ const [ fileName, hash ] = fileNameWithHash.split( '#' );
203
+
204
+ if ( hash ) {
205
+ return `${ fileName }.${ extension }#${ hash }`;
206
+ }
207
+
208
+ return `${ fileName }.${ extension }`;
193
209
  }
194
210
 
195
211
  function getOutputLink( href, description, isCustomDescription ) {
@@ -249,6 +249,12 @@ module.exports = class DescriptionParser {
249
249
 
250
250
  if ( hasDedicatedApiPages( targetDoclet ) ) {
251
251
  href = this._fileNameManager.getUrl( targetDoclet.longname );
252
+
253
+ // Properties of `type` do not have own doclets. Instead, they are specified as `properties` in the `type`
254
+ // (parent) doclet. Hence, we must link to it manually. See: #1182.
255
+ if ( this._hasMember( targetDoclet, member ) ) {
256
+ href += `#member-${ member }`;
257
+ }
252
258
  } else {
253
259
  href = [
254
260
  this._fileNameManager.getUrl( targetDoclet.memberof ),
@@ -289,6 +295,26 @@ module.exports = class DescriptionParser {
289
295
  return result;
290
296
  }
291
297
 
298
+ /**
299
+ * @protected
300
+ * @param {Object} typedef
301
+ * @param {String} typedef.kind
302
+ * @param {Array.<Object>} [typedef.properties]
303
+ * @param {String} propertyName
304
+ * @returns {Boolean}
305
+ */
306
+ _hasMember( typedef, propertyName ) {
307
+ if ( typedef.kind !== 'typedef' ) {
308
+ return false;
309
+ }
310
+
311
+ if ( !Array.isArray( typedef.properties ) ) {
312
+ return false;
313
+ }
314
+
315
+ return !!typedef.properties.find( item => item.name === propertyName );
316
+ }
317
+
292
318
  /**
293
319
  * Changes headings in description to smaller. Allowed headings are h3-h6.
294
320
  * If in source code commments h1, h2 heading are used, they need to be lowered.
@@ -67,7 +67,21 @@ module.exports = function findTargetDoclet( docletCollection, options ) {
67
67
  }
68
68
 
69
69
  if ( collection.isEmpty ) {
70
- return null;
70
+ const typedefCollection = collection = docletCollection.get( `ln:${ structure }` );
71
+
72
+ if ( typedefCollection.isEmpty ) {
73
+ return null;
74
+ }
75
+
76
+ const typedefItem = typedefCollection.getFirst();
77
+
78
+ if ( typedefItem.kind !== 'typedef' ) {
79
+ return null;
80
+ }
81
+
82
+ const { properties = [] } = typedefItem;
83
+
84
+ return properties.find( item => item.name === member ) ? typedefItem : null;
71
85
  }
72
86
 
73
87
  let targetDoclet;
@@ -290,11 +290,12 @@ class TypedocConverter {
290
290
  const childSignature = child.kindString === 'Method' ? child.signatures[ 0 ] : child;
291
291
  const response = this._convertTypeToJsDoc( childSignature );
292
292
 
293
+ // For all properties, explicitly create the `id` key (as `extraId` key).
294
+ // The `id` is then used to create the `longname` key. Unfortunately, nested properties are processed manually,
295
+ // so part of the parser's job must be done here.
296
+ response.extraId = `member-${ childSignature.name }`;
297
+
293
298
  if ( child.kindString === 'Index signature' ) {
294
- // For computed property (stored as index signature by TypeDoc), explicitly create the `id` key (as `extraId` key).
295
- // The `id` is then used to created the `longname` key. Otherwise, the `id` and `longname` keys would be created
296
- // automatically later and they would contain computed name in their values.
297
- response.extraId = `member-${ childSignature.name }`;
298
299
  response.name = TypedocConverter.getComputedName( childSignature );
299
300
  } else {
300
301
  response.name = childSignature.name;
@@ -37,6 +37,8 @@ block navtree
37
37
  != navTree
38
38
 
39
39
  block projectVersion
40
+ meta( name= 'permalink-disable-domains' content=page.permalinkDisableDomains )
41
+
40
42
  if projectLocals
41
43
  meta( name= 'project-version' content= projectLocals.projectVersion )
42
44
  meta( name= 'project-slug' content= projectLocals.projectSlug )
@@ -19,6 +19,8 @@ block append content
19
19
  include _partial/report-issue-widget
20
20
 
21
21
  block projectVersion
22
+ meta( name= 'permalink-disable-domains' content=page.permalinkDisableDomains )
23
+
22
24
  if projectLocals
23
25
  meta( name= 'project-version' content= projectLocals.projectVersion )
24
26
  meta( name= 'project-slug' content= projectLocals.projectSlug )
@@ -21,6 +21,8 @@ block navtree
21
21
  include _partial/nav-tree
22
22
 
23
23
  block projectVersion
24
+ meta( name= 'permalink-disable-domains' content=page.permalinkDisableDomains )
25
+
24
26
  if projectLocals
25
27
  meta( name= 'project-version' content= projectLocals.projectVersion )
26
28
  meta( name= 'project-slug' content= projectLocals.projectSlug )
@@ -21,6 +21,8 @@ block navtree
21
21
  != projectLocals.sdkNavTree
22
22
 
23
23
  block projectVersion
24
+ meta( name= 'permalink-disable-domains' content=page.permalinkDisableDomains )
25
+
24
26
  if projectLocals
25
27
  meta( name= 'project-version' content= projectLocals.projectVersion )
26
28
  meta( name= 'project-slug' content= projectLocals.projectSlug )
@@ -11,6 +11,16 @@ export default function attachPermalinkListener() {
11
11
  return;
12
12
  }
13
13
 
14
+ const permalinkDisableDomainsElement = document.querySelector( 'meta[name=permalink-disable-domains]' );
15
+
16
+ if ( permalinkDisableDomainsElement ) {
17
+ const permalinkDisableDomains = permalinkDisableDomainsElement.getAttribute( 'content' ).split( ',' );
18
+
19
+ if ( permalinkDisableDomains.includes( location.hostname ) ) {
20
+ return;
21
+ }
22
+ }
23
+
14
24
  const projectVersion = projectVersionElement.getAttribute( 'content' );
15
25
  const projectSlug = projectSlugElement.getAttribute( 'content' );
16
26