umberto 2.3.1 → 2.5.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/package.json +5 -5
- package/scripts/filter/after-post-render/fix-code-samples.js +12 -0
- package/scripts/utils/transforminfobox.js +12 -0
- package/src/api-builder/classes/description-parser.js +65 -1
- package/src/data-converter/converters/typedoc/constructorparser.js +5 -0
- package/src/data-converter/converters/typedoc/methodparser.js +18 -1
- package/src/data-converter/converters/typedoc/propertyparser.js +21 -0
- package/src/tasks/build-documentation.js +2 -2
- package/themes/umberto/layout/_partial/head.pug +4 -1
- package/themes/umberto/src/css/_notice.scss +6 -0
- package/themes/umberto/src/css/_prism.scss +0 -5
- package/themes/umberto/src/css/helpers/_color.scss +2 -1
- package/themes/umberto/src/js/_attachpermalinklistener.js +38 -0
- package/themes/umberto/src/js/app.js +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "umberto",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.5.0",
|
|
4
4
|
"description": "CKSource Documentation builder",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"files": [
|
|
@@ -56,10 +56,10 @@
|
|
|
56
56
|
"webpack": "^5.74.0"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
|
-
"@ckeditor/ckeditor5-dev-bump-year": "^
|
|
60
|
-
"@ckeditor/ckeditor5-dev-ci": "^
|
|
61
|
-
"@ckeditor/ckeditor5-dev-docs": "^
|
|
62
|
-
"@ckeditor/ckeditor5-dev-release-tools": "^
|
|
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
63
|
"browser-sync": "^2.27.10",
|
|
64
64
|
"chai": "^4.3.6",
|
|
65
65
|
"chokidar": "^3.5.3",
|
|
@@ -7,10 +7,22 @@
|
|
|
7
7
|
|
|
8
8
|
const { default: cheerio } = require( 'cheerio' );
|
|
9
9
|
|
|
10
|
+
const regexp = /(?<=>)utf8_encoded_content:([0-9,]+)(?=<\/code><\/pre>)/g;
|
|
11
|
+
const textDecoder = new TextDecoder();
|
|
12
|
+
|
|
10
13
|
/**
|
|
11
14
|
* Fixes some codeblocks issues.
|
|
12
15
|
*/
|
|
13
16
|
hexo.extend.filter.register( 'after_post_render', page => {
|
|
17
|
+
// Decoding codeblocks inside infobox from UTF-8. See #1122.
|
|
18
|
+
if ( regexp.test( page.content ) ) {
|
|
19
|
+
page.content = page.content.replace( regexp, ( match, encodedContent ) => {
|
|
20
|
+
const decodedContent = textDecoder.decode( new Uint8Array( encodedContent.split( ',' ) ) );
|
|
21
|
+
|
|
22
|
+
return decodedContent.replace( /^\n/, '' );
|
|
23
|
+
} );
|
|
24
|
+
}
|
|
25
|
+
|
|
14
26
|
const $ = cheerio.load( page.content, null, false );
|
|
15
27
|
|
|
16
28
|
// This is an attempt to automatically discover code blocks of HTML and add 'html' class if needed.
|
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
const INFO_BOX_REGEXP = /<info-box[^>]*>([\s\S]*?)<\/info-box>/g;
|
|
9
9
|
const INFO_BOX_TYPE_REGEXP = /<info-box\s*(\w*)[^>]*>/;
|
|
10
|
+
const CODEBLOCK_REGEXP_STRING = /```(\S+)?(\n[\s\S]*?)```/g;
|
|
11
|
+
|
|
12
|
+
const textEncoder = new TextEncoder();
|
|
10
13
|
|
|
11
14
|
/**
|
|
12
15
|
* Replaces the `<info-box>` element with the HTML `div` element. E.g.:
|
|
@@ -61,6 +64,15 @@ function processInfobox( content, hexo ) {
|
|
|
61
64
|
content = content.replace( /^\n/, '' );
|
|
62
65
|
content = content.replace( /\n$/, '' );
|
|
63
66
|
|
|
67
|
+
// Encoding codeblocks inside infobox into UTF-8. See #1122.
|
|
68
|
+
content = content.replace( CODEBLOCK_REGEXP_STRING, ( match, language, content ) => {
|
|
69
|
+
const encodedContent = textEncoder.encode( content );
|
|
70
|
+
|
|
71
|
+
return language ?
|
|
72
|
+
`<pre class="highlight"><code class="${ language }">utf8_encoded_content:${ encodedContent }</code></pre>` :
|
|
73
|
+
`<pre class="highlight"><code>utf8_encoded_content:${ encodedContent }</code></pre>`;
|
|
74
|
+
} );
|
|
75
|
+
|
|
64
76
|
let markdownOutput = hexo.render.renderSync( { text: content, engine: 'markdown' } );
|
|
65
77
|
markdownOutput = markdownOutput.replace( /<\/p>\n/g, '</p>' );
|
|
66
78
|
markdownOutput = markdownOutput.replace( /\n<p>/g, '<p>' );
|
|
@@ -177,9 +177,73 @@ module.exports = class DescriptionParser {
|
|
|
177
177
|
member = name;
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
-
|
|
180
|
+
let targetDoclet = findTargetDoclet( this._dataCollection, { module, structure, member, label, query } );
|
|
181
181
|
let replaceToPhrase;
|
|
182
182
|
|
|
183
|
+
if ( !targetDoclet && options.parentDoclet ) {
|
|
184
|
+
const augmentsNested = [
|
|
185
|
+
// If looking for a property, check if it is defined in a derived class, e.g.,
|
|
186
|
+
//
|
|
187
|
+
// ```ts
|
|
188
|
+
// class A {
|
|
189
|
+
// public foo: any;
|
|
190
|
+
//
|
|
191
|
+
// /**
|
|
192
|
+
// * See {@link ~A#foo}.
|
|
193
|
+
// */
|
|
194
|
+
// public getFoo(): void;
|
|
195
|
+
// }
|
|
196
|
+
// class B extends A {
|
|
197
|
+
// }
|
|
198
|
+
// ```
|
|
199
|
+
//
|
|
200
|
+
// `B` contains the property, so from its perspective, the link is valid.
|
|
201
|
+
// Let's try to parse it as it would be specified as `~B#foo`.
|
|
202
|
+
options.parentDoclet.longname,
|
|
203
|
+
|
|
204
|
+
// When looking for a structure withing the same module, check parent classes, e.g.,
|
|
205
|
+
//
|
|
206
|
+
// ```ts
|
|
207
|
+
// class A {
|
|
208
|
+
// /**
|
|
209
|
+
// * See {@link ~A}.
|
|
210
|
+
// */
|
|
211
|
+
// public getFoo(): void;
|
|
212
|
+
// }
|
|
213
|
+
// class B extends A {
|
|
214
|
+
// }
|
|
215
|
+
// ```
|
|
216
|
+
//
|
|
217
|
+
// `~A` seeing from a module containing the `B` class does not make sense.
|
|
218
|
+
// Let's try to find the proper doclet in parent classes.
|
|
219
|
+
...( options.parentDoclet.augmentsNested || [] )
|
|
220
|
+
];
|
|
221
|
+
|
|
222
|
+
targetDoclet = augmentsNested
|
|
223
|
+
.map( augmentName => {
|
|
224
|
+
const splitResult = splitLongname( augmentName );
|
|
225
|
+
|
|
226
|
+
let structure = [
|
|
227
|
+
`module:${ splitResult.packageName }`,
|
|
228
|
+
...splitResult.directoryNames,
|
|
229
|
+
splitResult.moduleName
|
|
230
|
+
].join( '/' );
|
|
231
|
+
|
|
232
|
+
// When `name` and `className` are equal, we look for a `member` in the `${ structure }~${ className }` doclet.
|
|
233
|
+
if ( splitResult.name === splitResult.className ) {
|
|
234
|
+
structure += `~${ splitResult.className }`;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
return findTargetDoclet( this._dataCollection, {
|
|
238
|
+
structure,
|
|
239
|
+
member,
|
|
240
|
+
label,
|
|
241
|
+
query
|
|
242
|
+
} );
|
|
243
|
+
} )
|
|
244
|
+
.find( Boolean );
|
|
245
|
+
}
|
|
246
|
+
|
|
183
247
|
if ( targetDoclet ) {
|
|
184
248
|
let href;
|
|
185
249
|
|
|
@@ -22,6 +22,11 @@ module.exports = class ConstructorParser extends MethodParser {
|
|
|
22
22
|
* @returns {Array.<Object>}
|
|
23
23
|
*/
|
|
24
24
|
parse( item, parentName ) {
|
|
25
|
+
// Absence of sources means that the actual class does not have a constructor.
|
|
26
|
+
if ( !item.sources ) {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
|
|
25
30
|
const results = super.parse( item, parentName );
|
|
26
31
|
|
|
27
32
|
for ( const item of results ) {
|
|
@@ -33,7 +33,7 @@ module.exports = class MethodParser extends AbstractParser {
|
|
|
33
33
|
|
|
34
34
|
scope: this.getScope( item ),
|
|
35
35
|
kind: this.getKind( item ),
|
|
36
|
-
access: this.
|
|
36
|
+
access: this.getVisibilityIncludingSignature( item, index ),
|
|
37
37
|
extraId: this.getExtraId( item ),
|
|
38
38
|
fires: this.getFiredEvents( signature, parentName ),
|
|
39
39
|
description: this.getComment( signature ),
|
|
@@ -60,4 +60,21 @@ module.exports = class MethodParser extends AbstractParser {
|
|
|
60
60
|
return doclet;
|
|
61
61
|
} );
|
|
62
62
|
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Returns the access type for the item based on its signatures.
|
|
66
|
+
*
|
|
67
|
+
* @param {TypedocReflection<ConstructorOrMethod>} item
|
|
68
|
+
* @param {Number} sourceIndex
|
|
69
|
+
* @returns {'public'|'internal'|'protected'|'private'}
|
|
70
|
+
*/
|
|
71
|
+
getVisibilityIncludingSignature( item, sourceIndex ) {
|
|
72
|
+
const signatureVisibility = this.getVisibility( item.signatures[ sourceIndex ] );
|
|
73
|
+
|
|
74
|
+
if ( signatureVisibility !== 'public' ) {
|
|
75
|
+
return signatureVisibility;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return this.getVisibility( item );
|
|
79
|
+
}
|
|
63
80
|
};
|
|
@@ -50,11 +50,32 @@ module.exports = class PropertyParser extends AbstractParser {
|
|
|
50
50
|
deprecated: this.isDeprecated( item ),
|
|
51
51
|
inherited: !!item.inheritedFrom,
|
|
52
52
|
see: this.getRelated( item, parentName ),
|
|
53
|
+
defaultvalue: this.getDefault( item ),
|
|
53
54
|
|
|
54
55
|
// This property will be filled in the post-processing phase.
|
|
55
56
|
type: null
|
|
56
57
|
};
|
|
57
58
|
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Returns the default value of an item defined by the `@defaultValue` or `@default` tags.
|
|
62
|
+
*
|
|
63
|
+
* @param {TypedocReflection} item
|
|
64
|
+
* @returns {String}
|
|
65
|
+
*/
|
|
66
|
+
getDefault( item ) {
|
|
67
|
+
if ( !item.comment || !item.comment.blockTags ) {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const defaultTag = item.comment.blockTags.find( blockTag => blockTag.tag === '@defaultValue' || blockTag.tag === '@default' );
|
|
72
|
+
|
|
73
|
+
if ( !defaultTag ) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return defaultTag.content[ 0 ].text;
|
|
78
|
+
}
|
|
58
79
|
};
|
|
59
80
|
|
|
60
81
|
/**
|
|
@@ -22,7 +22,7 @@ const cacheFiles = require( './cache-files' );
|
|
|
22
22
|
const overwriteApiGuides = require( './overwrite-api-guides' );
|
|
23
23
|
const cacheDir = upath.join( __dirname, '../../temp/cache' );
|
|
24
24
|
const validateLinks = require( './validate-links' );
|
|
25
|
-
const
|
|
25
|
+
const createSitemap = require( './create-sitemap' );
|
|
26
26
|
const buildSnippets = require( './build-snippets' );
|
|
27
27
|
const copyProjectIcons = require( './copy-project-icons' );
|
|
28
28
|
const executeHooks = require( './execute-hooks' );
|
|
@@ -269,7 +269,7 @@ module.exports = options => {
|
|
|
269
269
|
}
|
|
270
270
|
}
|
|
271
271
|
|
|
272
|
-
return
|
|
272
|
+
return createSitemap( 'build/docs', hostname, dst, {
|
|
273
273
|
excluded: excludedUrls,
|
|
274
274
|
extraUrlSettings
|
|
275
275
|
} );
|
|
@@ -17,6 +17,9 @@ if ( page[ 'twitter-card' ] || ogConfig.description )
|
|
|
17
17
|
|
|
18
18
|
meta( name= 'x-generated-at' content= Date() )
|
|
19
19
|
|
|
20
|
+
if ( projectLocals.projectVersion )
|
|
21
|
+
meta( name= 'project-version' content= projectLocals.projectVersion )
|
|
22
|
+
|
|
20
23
|
if ( mainOg || ( projectLocals && projectLocals.og ) || page[ 'og-description' ] )
|
|
21
24
|
meta( property='og:title' content= page[ 'og-title' ] || title )
|
|
22
25
|
if ( ogConfig.description || page[ 'og-description' ] )
|
|
@@ -60,7 +63,7 @@ if projectLocals
|
|
|
60
63
|
if page.isSnippetPage
|
|
61
64
|
//UMBERTO: SNIPPET: CSS
|
|
62
65
|
|
|
63
|
-
include google-optimize
|
|
66
|
+
include google-optimize
|
|
64
67
|
include google-tag-manager
|
|
65
68
|
include google-analytics
|
|
66
69
|
|
|
@@ -57,6 +57,7 @@ p.tip {
|
|
|
57
57
|
|
|
58
58
|
&__feedback {
|
|
59
59
|
border-left: 3px solid u-color( 'hint-hint' );
|
|
60
|
+
background-color: rgba( u-color( 'hint-hint' ), .1 );
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
&__warning {
|
|
@@ -64,6 +65,11 @@ p.tip {
|
|
|
64
65
|
background-color: rgba( u-color( 'hint-warning' ), .1 );
|
|
65
66
|
}
|
|
66
67
|
|
|
68
|
+
&__error {
|
|
69
|
+
border-left: 3px solid u-color( 'hint-error' );
|
|
70
|
+
background-color: rgba( u-color( 'hint-error' ), .1 );
|
|
71
|
+
}
|
|
72
|
+
|
|
67
73
|
&_menu-like {
|
|
68
74
|
ul, ol {
|
|
69
75
|
list-style: none;
|
|
@@ -125,11 +125,6 @@ div.code-toolbar {
|
|
|
125
125
|
position: relative;
|
|
126
126
|
|
|
127
127
|
& > .toolbar {
|
|
128
|
-
/* The toolbar does not look well on mobiles. There's not enough space. */
|
|
129
|
-
@include u-responsive-mobile {
|
|
130
|
-
display: none;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
128
|
position: absolute;
|
|
134
129
|
top: u-spacing( -2 );
|
|
135
130
|
right: u-spacing( -2 );
|
|
@@ -0,0 +1,38 @@
|
|
|
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
|
+
const latestRegexp = /(?<=\/)latest(?=\/)/;
|
|
7
|
+
|
|
8
|
+
export default function attachPermalinkListener() {
|
|
9
|
+
const projectVersionElement = document.querySelector( 'meta[name=project-version]' );
|
|
10
|
+
|
|
11
|
+
if ( !projectVersionElement ) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const projectVersion = projectVersionElement.getAttribute( 'content' );
|
|
16
|
+
|
|
17
|
+
document.addEventListener( 'keypress', event => {
|
|
18
|
+
if ( event.metaKey ) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if ( event.shiftKey ) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if ( event.key.toUpperCase() !== 'Y' ) {
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if ( !latestRegexp.test( location.href ) ) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const newUrl = location.href.replace( latestRegexp, projectVersion );
|
|
35
|
+
|
|
36
|
+
history.replaceState( history.state, document.title, newUrl );
|
|
37
|
+
} );
|
|
38
|
+
}
|
|
@@ -26,6 +26,7 @@ import { rwdButton } from './_rwdmenu';
|
|
|
26
26
|
import imageModal from './_imageModal';
|
|
27
27
|
import showWarningBanner from './_warningbanner';
|
|
28
28
|
import { enableBadgeTooltips, createTooltip } from './_tooltips';
|
|
29
|
+
import attachPermalinkListener from './_attachpermalinklistener';
|
|
29
30
|
|
|
30
31
|
// Changing documentation theme. To enable, type in the console: `localStorage.setItem( 'theme', 'theme-dark' )`.
|
|
31
32
|
if ( localStorage.getItem( 'theme' ) === 'theme-dark' ) {
|
|
@@ -54,6 +55,7 @@ $( document ).ready( () => {
|
|
|
54
55
|
scrollApiTree();
|
|
55
56
|
setUpFuse();
|
|
56
57
|
activateDevNames();
|
|
58
|
+
attachPermalinkListener();
|
|
57
59
|
sideNavigation();
|
|
58
60
|
rwdButton();
|
|
59
61
|
imageModal(); // lightbox for { @img } elements
|