umberto 3.0.0 → 3.2.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.
Files changed (28) hide show
  1. package/CHANGELOG.md +1591 -0
  2. package/README.md +6 -6
  3. package/package.json +4 -34
  4. package/src/api-builder/classes/doc-data-factory.js +107 -34
  5. package/src/data-converter/converters/typedoc/abstractparser.js +11 -0
  6. package/src/data-converter/converters/typedoc/computedpropertyparser.js +30 -0
  7. package/src/data-converter/converters/typedoc/moduleparser.js +2 -1
  8. package/src/data-converter/converters/typedoc/typedocconverter.js +89 -27
  9. package/src/data-converter/converters/typedoc2umberto.js +2 -0
  10. package/src/hexo-manager.js +10 -1
  11. package/themes/umberto/layout/_api-docs/_mixin/_method.pug +2 -1
  12. package/themes/umberto/layout/_api-docs/_mixin/_params.pug +10 -1
  13. package/themes/umberto/layout/_api-docs/_mixin/type-parameter.pug +1 -1
  14. package/themes/umberto/layout/_api-docs/_partial/api-subheader.pug +3 -0
  15. package/themes/umberto/layout/_api-docs/_partial/type-parameters.pug +1 -1
  16. package/themes/umberto/layout/_api-docs/api-base.pug +0 -2
  17. package/themes/umberto/layout/_mixin/nav-tree-level.pug +1 -1
  18. package/themes/umberto/layout/_partial/nav-tree.pug +1 -1
  19. package/themes/umberto/src/css/_api-subheader.scss +2 -0
  20. package/themes/umberto/src/css/_badge.scss +1 -0
  21. package/themes/umberto/src/css/_tree.scss +9 -0
  22. package/themes/umberto/src/js/_apitree.js +12 -20
  23. package/themes/umberto/src/js/_sidenavigation.js +45 -4
  24. package/themes/umberto/src/js/app.js +3 -3
  25. package/.editorconfig +0 -12
  26. package/.eslintrc.js +0 -41
  27. package/scripts-dev/postinstall.js +0 -18
  28. package/themes/umberto/layout/_api-docs/_partial/types.pug +0 -5
package/README.md CHANGED
@@ -297,6 +297,10 @@ Use `category: none` for pages not belonging to any category, e.g. 404 page. 404
297
297
 
298
298
  If no `<h1>` heading is present in a guide, the title will be used to create the guide title automatically. It is recommended to put a `<h1>` heading in a guide and skip this option.
299
299
 
300
+ #### folded [optional]
301
+
302
+ If defined and set to `true`, the category will be folded.
303
+
300
304
  #### slug [optional]
301
305
 
302
306
  If `slug` is defined, the guide's file name after processing by Umberto will be changed to the slug.
@@ -701,15 +705,11 @@ After generating the changelog, you are able to release the package.
701
705
  First, you need to bump the version:
702
706
 
703
707
  ```bash
704
- npm run release:bump-version
708
+ npm run release:prepare-packages
705
709
  ```
706
710
 
707
- You can also use the `--dry-run` option in order to see what this task does.
708
-
709
711
  After bumping the version, you can publish the changes:
710
712
 
711
713
  ```bash
712
- npm run release:publish
714
+ npm run release:publish-packages
713
715
  ```
714
-
715
- As in the previous task, the `--dry-run` option is also available.
package/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "umberto",
3
- "version": "3.0.0",
3
+ "version": "3.2.0",
4
4
  "description": "CKSource Documentation builder",
5
5
  "main": "src/index.js",
6
6
  "files": [
7
7
  "scripts",
8
8
  "src",
9
9
  "themes",
10
- ".editorconfig",
11
- ".eslintrc.js",
12
10
  "hexo-config.json",
13
11
  "hexo-shim.js",
14
- "scripts-dev/postinstall.js"
12
+ "README.md",
13
+ "LICENSE.md",
14
+ "CHANGELOG.md"
15
15
  ],
16
16
  "dependencies": {
17
17
  "@babel/core": "^7.18.10",
@@ -55,40 +55,10 @@
55
55
  "vnu-jar": "^21.10.12",
56
56
  "webpack": "^5.74.0"
57
57
  },
58
- "devDependencies": {
59
- "@ckeditor/ckeditor5-dev-bump-year": "^35.0.0",
60
- "@ckeditor/ckeditor5-dev-ci": "^35.0.0",
61
- "@ckeditor/ckeditor5-dev-docs": "^35.0.0",
62
- "@ckeditor/ckeditor5-dev-release-tools": "^35.0.0",
63
- "browser-sync": "^2.27.10",
64
- "chai": "^4.3.6",
65
- "chokidar": "^3.5.3",
66
- "eslint": "^8.21.0",
67
- "eslint-config-ckeditor5": "^4.0.1",
68
- "husky": "^8.0.2",
69
- "lint-staged": "^13.0.3",
70
- "mocha": "^10.0.0",
71
- "mockery": "^2.1.0",
72
- "proxyquire": "^2.1.3",
73
- "sinon": "^14.0.0",
74
- "typescript": "^4.8.4"
75
- },
76
58
  "engines": {
77
59
  "node": ">=16.0.0",
78
60
  "npm": ">=5.7.1"
79
61
  },
80
- "scripts": {
81
- "postinstall": "node ./scripts-dev/postinstall.js",
82
- "dev:build-single": "node ./scripts-dev/build-single.js",
83
- "dev:build-multi": "node ./scripts-dev/build-multi.js",
84
- "dev:serve": "node ./scripts-dev/serve.js",
85
- "lint": "eslint --quiet '**/*.js'",
86
- "test": "mocha tests --recursive",
87
- "coverage": "nyc --reporter=lcov --reporter=text-summary --cache false npm run test",
88
- "changelog": "node ./scripts-dev/changelog.js",
89
- "release:bump-version": "node ./scripts-dev/bump-version.js",
90
- "release:publish": "node ./scripts-dev/publish.js"
91
- },
92
62
  "author": "CKSource (http://cksource.com/)",
93
63
  "license": "MIT",
94
64
  "homepage": "https://github.com/cksource/umberto",
@@ -192,16 +192,23 @@ module.exports = class DocDataFactory {
192
192
  // "member-" as a static string must be the same as defined in `addTypedefProperties()` helper in the `@ckeditor/jsdoc-plugins` package.
193
193
  // See: https://github.com/ckeditor/ckeditor5-dev/blob/aa905a702d337db001445efc1036ab2b33069d44/packages/jsdoc-plugins/lib/relation-fixer/addtypedefproperties.js#L95
194
194
  /* eslint-enable max-len */
195
- for ( const property of properties ) {
196
- if ( doclet.kind == 'typedef' && !property.id ) {
197
- property.id = 'member-' + property.name;
198
- property.longname = `${ doclet.longname }#${ property.name }`;
195
+ if ( doclet.kind == 'typedef' ) {
196
+ for ( const property of properties ) {
197
+ if ( !property.id ) {
198
+ property.id = 'member-' + property.name;
199
+ }
200
+
201
+ if ( !property.longname ) {
202
+ const [ name ] = property.id.split( 'member-' ).filter( Boolean );
203
+
204
+ property.longname = `${ doclet.longname }#${ name }`;
205
+ }
199
206
  }
200
207
  }
201
208
 
202
209
  const itemData = {
203
210
  types: getTypes( doclet ),
204
- properties: properties.sort( ( a, b ) => a.name <= b.name ? -1 : 1 ),
211
+ properties: properties.sort( ( a, b ) => sorter( a.name, b.name ) ),
205
212
  augments: augmentsNested
206
213
  };
207
214
 
@@ -513,20 +520,26 @@ module.exports = class DocDataFactory {
513
520
  */
514
521
  _processParams( data = [] ) {
515
522
  const resultParams = data.slice(); // copy data array
516
- const parentParams = []; // params which have sub-params; e.g. options
517
523
 
518
- for ( const item of resultParams ) {
524
+ // Find properties that may contain nested properties.
525
+ const parentParams = resultParams.filter( item => {
519
526
  if ( item.params ) {
520
- continue;
527
+ return true;
521
528
  }
522
529
 
523
- // Parent params are of type 'Object'.
524
- for ( const type of item.types ) {
525
- if ( type === 'Object' ) {
526
- parentParams.push( item );
530
+ return item.types.some( type => {
531
+ // An inline callback.
532
+ if ( type.type && type.type === 'function' ) {
533
+ return true;
534
+ }
535
+
536
+ if ( typeof type !== 'string' ) {
537
+ return false;
527
538
  }
528
- }
529
- }
539
+
540
+ return type.toLowerCase() === 'object';
541
+ } );
542
+ } );
530
543
 
531
544
  // For every parentParam gather its subparams.
532
545
  for ( const parent of parentParams ) {
@@ -535,7 +548,7 @@ module.exports = class DocDataFactory {
535
548
  for ( let i = 0; i < resultParams.length; i++ ) {
536
549
  const item = resultParams[ i ];
537
550
 
538
- if ( item.name && item.name.indexOf( `${ parent.name }.` ) !== -1 ) {
551
+ if ( item.name && item.name.includes( `${ parent.name }.` ) ) {
539
552
  subParams.push( item );
540
553
  // remove sub-params from main array, they will be kept under parentParam
541
554
  resultParams.splice( i--, 1 );
@@ -549,8 +562,24 @@ module.exports = class DocDataFactory {
549
562
  if ( parent.params.length > 0 ) {
550
563
  parent.subParamsString = ' = { ';
551
564
 
565
+ if ( parent.types.length === 1 && parent.types[ 0 ].type === 'function' ) {
566
+ parent.subParamsString += renderInlineCallbackAsObjectProperty( parent.types[ 0 ] );
567
+
568
+ if ( subParams.length ) {
569
+ parent.subParamsString += ', ';
570
+ }
571
+ }
572
+
552
573
  subParams.forEach( ( sub, index ) => {
553
- parent.subParamsString += sub.optional ? `[${ sub.name }]` : sub.name;
574
+ const isComputedProperty = sub.id === 'member-__index';
575
+
576
+ if ( isComputedProperty ) {
577
+ const [ parentParam, nestedParam ] = sub.name.split( '.' );
578
+
579
+ parent.subParamsString += `${ parentParam }<i>${ nestedParam }</i>`;
580
+ } else {
581
+ parent.subParamsString += sub.optional ? `[${ sub.name }]` : sub.name;
582
+ }
554
583
 
555
584
  if ( index < subParams.length - 1 ) {
556
585
  parent.subParamsString += ', ';
@@ -710,15 +739,7 @@ function sortLongnamesAlphabetically( arr ) {
710
739
  split: splitLongname( item ).name
711
740
  };
712
741
  } )
713
- .sort( ( a, b ) => {
714
- if ( a.split < b.split ) {
715
- return -1;
716
- } else if ( a.split > b.split ) {
717
- return 1;
718
- } else {
719
- return 0;
720
- }
721
- } )
742
+ .sort( ( a, b ) => sorter( a.split, b.split ) )
722
743
  .map( item => item.entry );
723
744
  }
724
745
 
@@ -732,15 +753,7 @@ function sortPartsAlphabetically( arr, criteria = [ {} ] ) {
732
753
  for ( const crit of criteria ) {
733
754
  const tmp = arr
734
755
  .filter( item => item[ crit.key ] === crit.value )
735
- .sort( ( a, b ) => {
736
- if ( a.name < b.name ) {
737
- return -1;
738
- } else if ( a.name > b.name ) {
739
- return 1;
740
- } else {
741
- return 0;
742
- }
743
- } );
756
+ .sort( ( a, b ) => sorter( a.name, b.name ) );
744
757
 
745
758
  tmp.forEach( item => {
746
759
  const index = arr.indexOf( item );
@@ -752,3 +765,63 @@ function sortPartsAlphabetically( arr, criteria = [ {} ] ) {
752
765
 
753
766
  return result;
754
767
  }
768
+
769
+ function sorter( a, b ) {
770
+ // Computed property name starts with the "[" character. We want to show them on the top, so let's prepend the name
771
+ // (only for the sorting purposes) with a space, which ASCII code is less than any other alphanumeric character.
772
+ if ( a.startsWith( '[' ) ) {
773
+ a = ' ' + a;
774
+ }
775
+
776
+ if ( b.startsWith( '[' ) ) {
777
+ b = ' ' + b;
778
+ }
779
+
780
+ return a <= b ? -1 : 1;
781
+ }
782
+
783
+ /**
784
+ * This is a JavaScript version of the `renderInlineFunction()` pug mixin.
785
+ *
786
+ * See: themes/umberto/layout/_api-docs/_mixin/_type.pug.
787
+ *
788
+ * The goal is to render an inline object describing a callable type.
789
+ *
790
+ * @param {Object} type
791
+ * @param {Array.<String>} type.params
792
+ * @param {Array.<String>|String} type.returns
793
+ * @param {Boolean} type.isClass
794
+ * @returns {String}
795
+ */
796
+ function renderInlineCallbackAsObjectProperty( type ) {
797
+ const { params, returns, isClass } = type;
798
+
799
+ return [
800
+ // Indicate if a function returns a class.
801
+ isClass ? 'new' : '',
802
+
803
+ // Parameters section.
804
+ '(',
805
+ params.map( mapToDocletCallback ).join( ', ' ),
806
+ ')',
807
+
808
+ // Returns section.
809
+ ' =&gt; ',
810
+
811
+ // Wraps an union in brackets.
812
+ Array.isArray( returns ) ? '(' : '',
813
+ Array.isArray( returns ) ? returns.map( mapToDocletCallback ).join( ' | ' ) : mapToDocletCallback( returns ),
814
+ Array.isArray( returns ) ? ')' : ''
815
+ ].join( '' );
816
+
817
+ function mapToDocletCallback( param ) {
818
+ if ( !param.startsWith( 'module:' ) ) {
819
+ return param;
820
+ }
821
+
822
+ const href = param.replace( /:|\//g, '_' ).replace( '~', '-' ) + '.html';
823
+ const value = param.split( '~' )[ 1 ];
824
+
825
+ return `<a href="${ href }">${ value }</a>`;
826
+ }
827
+ }
@@ -73,6 +73,16 @@ module.exports = class AbstractParser {
73
73
  return `${ parentName }${ separator }${ item.name }`;
74
74
  }
75
75
 
76
+ /**
77
+ * Prepares the name for the computed property.
78
+ *
79
+ * @param {TypedocReflection<'Index signature'>} item
80
+ * @returns {String}
81
+ */
82
+ getComputedName( item ) {
83
+ return TypedocConverter.getComputedName( item );
84
+ }
85
+
76
86
  /**
77
87
  * Returns the access type for the item.
78
88
  *
@@ -121,6 +131,7 @@ module.exports = class AbstractParser {
121
131
 
122
132
  case 'Accessor':
123
133
  case 'Property':
134
+ case 'Index signature':
124
135
  return 'member';
125
136
 
126
137
  case 'Variable':
@@ -0,0 +1,30 @@
1
+ /**
2
+ * @license Copyright (c) 2017-2023, CKSource Holding sp. z o.o. All rights reserved.
3
+ * For licensing, see LICENSE.md.
4
+ */
5
+
6
+ 'use strict';
7
+
8
+ const PropertyParser = require( './propertyparser' );
9
+
10
+ module.exports = class ComputedPropertyParser extends PropertyParser {
11
+ /**
12
+ * @param {TypedocReflectionMeta} item
13
+ * @returns {Boolean}
14
+ */
15
+ canParse( item ) {
16
+ return item.kindString === 'Index signature';
17
+ }
18
+
19
+ /**
20
+ * @param {TypedocReflection<'Index signature'>} item
21
+ * @param {String} parentName
22
+ * @returns {Object}
23
+ */
24
+ parse( item, parentName ) {
25
+ return {
26
+ ...super.parse( item, parentName ),
27
+ name: this.getComputedName( item )
28
+ };
29
+ }
30
+ };
@@ -25,7 +25,8 @@ module.exports = class ModuleParser extends AbstractParser {
25
25
  name: item.name,
26
26
  longname: this.getLongName( item ),
27
27
  kind: this.getKind( item ),
28
- extraId: this.getExtraId( item )
28
+ extraId: this.getExtraId( item ),
29
+ file: this.getFile( item )
29
30
  };
30
31
  }
31
32
  };
@@ -61,6 +61,26 @@ class TypedocConverter {
61
61
  return markdown.render( value ).trim();
62
62
  }
63
63
 
64
+ /**
65
+ * Prepares the name for the computed property.
66
+ *
67
+ * @param {TypedocReflection<'Index signature'>} item
68
+ * @returns {String}
69
+ */
70
+ static getComputedName( item ) {
71
+ if ( item.kindString !== 'Index signature' ) {
72
+ return item.name;
73
+ }
74
+
75
+ // TypeDoc is able to handle only one (the first found one) index signature.
76
+ // See: https://github.com/TypeStrong/typedoc/blob/af63d9e4e1/src/lib/converter/factories/index-signature.ts#L20
77
+ const [ firstParam ] = item.parameters;
78
+ const paramName = firstParam.name;
79
+ const paramType = firstParam.type.name;
80
+
81
+ return `[${ paramName }: ${ paramType }]`;
82
+ }
83
+
64
84
  /**
65
85
  * @param {Object} projectReflection
66
86
  * @param {Array.<TypedocReflection>} projectReflection.children
@@ -127,7 +147,7 @@ class TypedocConverter {
127
147
  }
128
148
 
129
149
  if ( 'properties' in doclet ) {
130
- doclet.properties = this._convertProperties( doclet, setSignature );
150
+ doclet.properties = this._convertProperties( setSignature );
131
151
  }
132
152
 
133
153
  if ( 'typeParameters' in doclet ) {
@@ -177,16 +197,21 @@ class TypedocConverter {
177
197
  }
178
198
  }
179
199
 
180
- if ( reflection.children ) {
181
- if ( doclets ) {
182
- parentName = doclets[ 0 ].longname;
183
- } else {
184
- parentName = '';
200
+ // A computed property is stored in the `indexSignature` key, but we want to convert it in the same way as we do for a "normal"
201
+ // property. Hence, let's just treat the `indexSignature` as it would be a doclet's child, so the dedicated parser for the
202
+ // `indexSignature` can prepare a doclet for the computed property.
203
+ if ( reflection.children || reflection.indexSignature ) {
204
+ parentName = doclets ? doclets[ 0 ].longname : '';
205
+
206
+ if ( reflection.children ) {
207
+ reflection.children.forEach( subItem => {
208
+ this._convertChild( subItem, parentName );
209
+ } );
185
210
  }
186
211
 
187
- reflection.children.forEach( subItem => {
188
- this._convertChild( subItem, parentName );
189
- } );
212
+ if ( reflection.indexSignature ) {
213
+ this._convertChild( reflection.indexSignature, parentName );
214
+ }
190
215
  }
191
216
  }
192
217
 
@@ -202,7 +227,7 @@ class TypedocConverter {
202
227
  }
203
228
 
204
229
  return signature.parameters
205
- .map( item => {
230
+ .flatMap( item => {
206
231
  const response = this._convertTypeToJsDoc( item );
207
232
 
208
233
  response.name = item.name;
@@ -219,47 +244,80 @@ class TypedocConverter {
219
244
  response.defaultvalue = item.defaultValue;
220
245
  }
221
246
 
222
- return response;
247
+ const nestedProperties = this._convertProperties( item );
248
+
249
+ if ( !nestedProperties ) {
250
+ return response;
251
+ }
252
+
253
+ return [
254
+ response,
255
+ ...nestedProperties.map( nestedProperty => {
256
+ nestedProperty.name = `${ item.name }.${ nestedProperty.name }`;
257
+
258
+ return nestedProperty;
259
+ } )
260
+ ];
223
261
  } );
224
262
  }
225
263
 
226
264
  /**
227
265
  * @protected
228
- * @param {Object} doclet
229
266
  * @param {TypedocCallSignature} signature
230
267
  * @returns {Array|null}
231
268
  */
232
- _convertProperties( doclet, signature ) {
269
+ _convertProperties( signature ) {
233
270
  const types = signature.type.type === 'union' ? signature.type.types : [ signature.type ];
234
- const type = types.find( type => type.declaration && type.declaration.children );
235
271
 
236
- if ( !type ) {
237
- return null;
238
- }
272
+ const properties = types
273
+ .filter( type => type.declaration )
274
+ .flatMap( type => {
275
+ const result = [];
239
276
 
240
- return type.declaration.children.map( child => {
241
- const response = this._convertTypeToJsDoc( child );
277
+ if ( type.declaration.children ) {
278
+ result.push( ...type.declaration.children );
279
+ }
242
280
 
243
- response.name = child.name;
281
+ if ( type.declaration.indexSignature ) {
282
+ result.push( type.declaration.indexSignature );
283
+ }
284
+
285
+ return result;
286
+ } );
287
+
288
+ return properties.map( child => {
289
+ // Nested properties cannot be duplicated so we can take the first signature when processing functions.
290
+ const childSignature = child.kindString === 'Method' ? child.signatures[ 0 ] : child;
291
+ const response = this._convertTypeToJsDoc( childSignature );
292
+
293
+ 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
+ response.name = TypedocConverter.getComputedName( childSignature );
299
+ } else {
300
+ response.name = childSignature.name;
301
+ }
244
302
 
245
303
  if ( signature.comment && signature.comment.blockTags ) {
246
304
  const atProperty = signature.comment.blockTags.find( blockTag => {
247
- return blockTag.tag === '@property' && blockTag.name === child.name;
305
+ return blockTag.tag === '@property' && blockTag.name === childSignature.name;
248
306
  } );
249
307
 
250
308
  if ( atProperty ) {
251
309
  response.description = TypedocConverter.convertComment( atProperty.content );
252
310
  }
253
- } else if ( child.comment && child.comment.summary ) {
254
- response.description = TypedocConverter.convertComment( child.comment.summary );
311
+ } else if ( childSignature.comment && childSignature.comment.summary ) {
312
+ response.description = TypedocConverter.convertComment( childSignature.comment.summary );
255
313
  }
256
314
 
257
- if ( child.flags.isOptional ) {
315
+ if ( childSignature.flags.isOptional ) {
258
316
  response.optional = true;
259
317
  }
260
318
 
261
- if ( child.defaultValue ) {
262
- response.defaultvalue = child.defaultValue;
319
+ if ( childSignature.defaultValue ) {
320
+ response.defaultvalue = childSignature.defaultValue;
263
321
  }
264
322
 
265
323
  return response;
@@ -436,7 +494,7 @@ class TypeConverter {
436
494
  };
437
495
  }
438
496
 
439
- const type = this.convert( parameter.type );
497
+ let type = this.convert( parameter.type );
440
498
 
441
499
  // To avoid complex type parameters (they are available in typings provided by TypeScript),
442
500
  // let's ignore unions.
@@ -447,6 +505,10 @@ class TypeConverter {
447
505
  };
448
506
  }
449
507
 
508
+ if ( parameter.default ) {
509
+ type += ` = ${ this.convertIntrinsicType( parameter.default ) }`;
510
+ }
511
+
450
512
  return {
451
513
  name: parameter.name,
452
514
  isExtending: true,
@@ -14,6 +14,7 @@ const ConstantParser = require( './typedoc/constantparser' );
14
14
  const TypeParser = require( './typedoc/typeparser' );
15
15
  const FunctionParser = require( './typedoc/functionparser' );
16
16
  const PropertyParser = require( './typedoc/propertyparser' );
17
+ const ComputedPropertyParser = require( './typedoc/computedpropertyparser' );
17
18
  const MethodParser = require( './typedoc/methodparser' );
18
19
  const ConstructorParser = require( './typedoc/constructorparser' );
19
20
  const ErrorParser = require( './typedoc/errorparser' );
@@ -45,6 +46,7 @@ module.exports = data => {
45
46
  MethodParser,
46
47
  AccessorParser,
47
48
  PropertyParser,
49
+ ComputedPropertyParser,
48
50
  EventParser
49
51
  ] );
50
52
 
@@ -85,7 +85,16 @@ class HexoManager {
85
85
  hexoInit() {
86
86
  this.isReady = true;
87
87
 
88
- return this.hexo.init();
88
+ return this.hexo.init().then( () => {
89
+ const renderer = this.hexo.render.renderer.get( 'md' );
90
+
91
+ // Disable Nunjucks templating language in the Markdown renderer.
92
+ // See https://github.com/ckeditor/ckeditor5/issues/14189.
93
+ if ( renderer ) {
94
+ renderer.disableNunjucks = true;
95
+ this.hexo.extend.renderer.register( 'md', 'html', renderer );
96
+ }
97
+ } );
89
98
  }
90
99
 
91
100
  /**
@@ -35,7 +35,8 @@ mixin method( met )
35
35
  else
36
36
  | #{ param.name }
37
37
  if ( param.subParamsString )
38
- | #{ param.subParamsString }
38
+ //- Allow rendering HTML from the `subParamsString` as it may contain links to other pages.
39
+ | !{ param.subParamsString }
39
40
  if index < met.params.length - 1
40
41
  |,
41
42
  else
@@ -10,12 +10,21 @@ mixin paramsMixin ( params, level, title )
10
10
 
11
11
  dl
12
12
  each param in params
13
+ - const isComputedProperty = param.id === 'member-__index';
14
+
13
15
  dt
14
16
  code
15
- if param.optional
17
+ if isComputedProperty
18
+ - const [ parentParam, nestedParam ] = param.name.split( '.' );
19
+
20
+ | #{ parentParam }
21
+ i
22
+ | #{ nestedParam }
23
+ else if param.optional
16
24
  | [ #{ param.name } ]
17
25
  else
18
26
  | #{ param.name }
27
+
19
28
  if isNonEmptyArray( param.types )
20
29
  | :
21
30
  | !{ ' ' }
@@ -5,7 +5,7 @@ mixin typeParameter( type )
5
5
  code
6
6
  span !{ type.name }
7
7
 
8
- //- Most TypeScript types we mark as `object`, as they structure is complex.
8
+ //- We mark most TypeScript types as `object`, as their structure is complex.
9
9
  //- Hence, it does not really make sense to show that a type extends an unknown `object`.
10
10
  if ( type.value && type.value[ 0 ] !== 'object' )
11
11
  | !{' : '}
@@ -6,6 +6,9 @@ div(class="api-subheader hidden-loading")
6
6
  if isNonEmptyArray( data.badges )
7
7
  each badge in data.badges
8
8
  +badge( badge )
9
+ if isNonEmptyArray( data.types )
10
+ code
11
+ +type( data.types )
9
12
  nav.api-subheader__navigation
10
13
  if ( isNonEmptyArray( data.configOptions ) || isNonEmptyArray( data.properties ) || isNonEmptyArray( data.methods ) || isNonEmptyArray( data.events ) )
11
14
  ul
@@ -12,7 +12,7 @@ if isNonEmptyArray( data.typeParameters )
12
12
  code
13
13
  span( class="member-name" ) #{ type.name }
14
14
 
15
- //- Most TypeScript types we mark as `object`, as they structure is complex.
15
+ //- We mark most TypeScript types as `object`, as their structure is complex.
16
16
  //- Hence, it does not really make sense to show that a type extends an unknown `object`.
17
17
  if ( type.value && type.value[ 0 ] !== 'object' )
18
18
  | !{' : '}
@@ -7,8 +7,6 @@ block content
7
7
 
8
8
  include _partial/api-info-box
9
9
 
10
- include _partial/types
11
-
12
10
  include _partial/description
13
11
 
14
12
  != filter
@@ -29,7 +29,7 @@ mixin navTreeLevel( data, isRoot )
29
29
  each badge in normalizeBadges( data )
30
30
  span( class="tree__item__badge tree__item__badge_" + badge.name data-badge-tooltip=badge.label )
31
31
  span( class="tree__item__badge__text" ) #{ badge.label }
32
- ul.tree__item-nested-list
32
+ ul( class={ "tree__item-nested-list": true, "tree__item-nested-list--hidden": data.folded } data-id=data.id )
33
33
  each item in dataArr
34
34
  //- Categories have a property 'name', guides don't have property 'name'.
35
35
  if item.name
@@ -5,5 +5,5 @@ include ../_mixin/nav-tree-level
5
5
  .side-navigation
6
6
  .side-navigation__wrapper
7
7
  nav.side-navigation__inner
8
- ul( class="tree guide-tree" )
8
+ ul( class="tree guide-tree", id="guidetree" )
9
9
  +navTreeLevel( pageGroup, true )