chrome-devtools-frontend 1.0.948445 → 1.0.948916
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/config/gni/devtools_grd_files.gni +0 -6
- package/front_end/core/i18n/locales/en-US.json +15 -30
- package/front_end/core/i18n/locales/en-XL.json +15 -30
- package/front_end/core/sdk/RemoteObject.ts +15 -1
- package/front_end/entrypoints/devtools_app/devtools_app.ts +0 -1
- package/front_end/entrypoints/visibility.gni +3 -1
- package/front_end/entrypoints/worker_app/worker_app.ts +0 -1
- package/front_end/generated/InspectorBackendCommands.js +8 -1
- package/front_end/generated/protocol-mapping.d.ts +4 -0
- package/front_end/generated/protocol-proxy-api.d.ts +6 -0
- package/front_end/generated/protocol.d.ts +9 -0
- package/front_end/models/issues_manager/AttributionReportingIssue.ts +27 -2
- package/front_end/panels/console/ConsolePrompt.ts +0 -4
- package/front_end/panels/elements/AccessibilityTreeUtils.ts +1 -7
- package/front_end/panels/elements/PropertiesWidget.ts +109 -4
- package/front_end/panels/elements/propertiesWidget.css +34 -0
- package/front_end/panels/emulation/DeviceModeToolbar.ts +5 -1
- package/package.json +1 -1
- package/scripts/eslint_rules/lib/ban_a_tags_in_lit_html.js +2 -11
- package/scripts/eslint_rules/lib/ban_literal_devtools_component_tag_names.js +2 -11
- package/scripts/eslint_rules/lib/ban_self_closing_custom_element_tagnames.js +2 -11
- package/scripts/eslint_rules/lib/ban_style_tags_in_lit_html.js +2 -11
- package/scripts/eslint_rules/lib/lit_html_data_as_type.js +2 -11
- package/scripts/eslint_rules/lib/lit_html_no_attribute_quotes.js +1 -13
- package/scripts/eslint_rules/lib/lit_no_style_interpolation.js +2 -11
- package/scripts/eslint_rules/lib/static_tag_must_be_static_property.js +2 -11
- package/scripts/eslint_rules/lib/utils.js +29 -0
- package/scripts/eslint_rules/tests/.eslintrc.js +4 -0
- package/scripts/eslint_rules/tests/utils_test.js +40 -0
- package/front_end/panels/help/HelpImpl.ts +0 -141
- package/front_end/panels/help/ReleaseNoteText.ts +0 -1496
- package/front_end/panels/help/ReleaseNoteView.ts +0 -107
- package/front_end/panels/help/help-meta.ts +0 -145
- package/front_end/panels/help/help.ts +0 -13
- package/front_end/panels/help/releaseNote.css +0 -115
|
@@ -3,16 +3,7 @@
|
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
'use strict';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
if (taggedTemplateExpression.name) {
|
|
8
|
-
// Call to html`` and we assume that html = LitHtml's html function.
|
|
9
|
-
return taggedTemplateExpression.name === 'html';
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// Match calls to LitHtml.html``
|
|
13
|
-
return taggedTemplateExpression.object && taggedTemplateExpression.object.name === 'LitHtml' &&
|
|
14
|
-
taggedTemplateExpression.property.name === 'html';
|
|
15
|
-
}
|
|
6
|
+
const {isLitHtmlTemplateCall} = require('./utils.js');
|
|
16
7
|
|
|
17
8
|
module.exports = {
|
|
18
9
|
meta: {
|
|
@@ -27,7 +18,7 @@ module.exports = {
|
|
|
27
18
|
create: function(context) {
|
|
28
19
|
return {
|
|
29
20
|
TaggedTemplateExpression(node) {
|
|
30
|
-
const isLitHtmlCall = isLitHtmlTemplateCall(node
|
|
21
|
+
const isLitHtmlCall = isLitHtmlTemplateCall(node);
|
|
31
22
|
if (!isLitHtmlCall) {
|
|
32
23
|
return;
|
|
33
24
|
}
|
|
@@ -3,16 +3,7 @@
|
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
'use strict';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
if (taggedTemplateExpression.name) {
|
|
8
|
-
// Call to html`` and we assume that html = LitHtml's html function.
|
|
9
|
-
return taggedTemplateExpression.name === 'html';
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// Match calls to LitHtml.html``
|
|
13
|
-
return taggedTemplateExpression.object && taggedTemplateExpression.object.name === 'LitHtml' &&
|
|
14
|
-
taggedTemplateExpression.property.name === 'html';
|
|
15
|
-
}
|
|
6
|
+
const {isLitHtmlTemplateCall} = require('./utils.js');
|
|
16
7
|
|
|
17
8
|
module.exports = {
|
|
18
9
|
meta: {
|
|
@@ -28,7 +19,7 @@ module.exports = {
|
|
|
28
19
|
create: function(context) {
|
|
29
20
|
return {
|
|
30
21
|
TaggedTemplateExpression(node) {
|
|
31
|
-
const isLitHtmlCall = isLitHtmlTemplateCall(node
|
|
22
|
+
const isLitHtmlCall = isLitHtmlTemplateCall(node);
|
|
32
23
|
if (!isLitHtmlCall) {
|
|
33
24
|
return;
|
|
34
25
|
}
|
|
@@ -3,16 +3,7 @@
|
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
'use strict';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
if (taggedTemplateExpression.name) {
|
|
8
|
-
// Call to html`` and we assume that html = LitHtml's html function.
|
|
9
|
-
return taggedTemplateExpression.name === 'html';
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// Match calls to LitHtml.html``
|
|
13
|
-
return taggedTemplateExpression.object && taggedTemplateExpression.object.name === 'LitHtml' &&
|
|
14
|
-
taggedTemplateExpression.property.name === 'html';
|
|
15
|
-
}
|
|
6
|
+
const {isLitHtmlTemplateCall} = require('./utils.js');
|
|
16
7
|
|
|
17
8
|
function findIndexOfDataSetterUsageForNode(taggedTemplateExpression) {
|
|
18
9
|
const dataSetterText = '.data=';
|
|
@@ -66,7 +57,7 @@ module.exports = {
|
|
|
66
57
|
create: function(context) {
|
|
67
58
|
return {
|
|
68
59
|
TaggedTemplateExpression(node) {
|
|
69
|
-
const isLitHtmlCall = isLitHtmlTemplateCall(node
|
|
60
|
+
const isLitHtmlCall = isLitHtmlTemplateCall(node);
|
|
70
61
|
if (!isLitHtmlCall) {
|
|
71
62
|
return;
|
|
72
63
|
}
|
|
@@ -3,19 +3,7 @@
|
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
'use strict';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
// Match LitHtml.html``
|
|
8
|
-
const {tag} = taggedTemplateExpressionNode;
|
|
9
|
-
if (!tag) {
|
|
10
|
-
return false;
|
|
11
|
-
}
|
|
12
|
-
// Match LitHtml.html``
|
|
13
|
-
const isLitHtmlDotHtmlCall = tag.object?.name === 'LitHtml' && tag.property?.name === 'html';
|
|
14
|
-
// Match html`` (and guess that it's Lit)
|
|
15
|
-
const isDestructuredHtmlCall = tag.type === 'Identifier' && tag.name === 'html';
|
|
16
|
-
|
|
17
|
-
return isLitHtmlDotHtmlCall || isDestructuredHtmlCall;
|
|
18
|
-
}
|
|
6
|
+
const {isLitHtmlTemplateCall} = require('./utils.js');
|
|
19
7
|
|
|
20
8
|
function templateElementPartStartsWithDoubleQuote(templateElementPartNode) {
|
|
21
9
|
return templateElementPartNode.value.raw.startsWith('"');
|
|
@@ -3,16 +3,7 @@
|
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
'use strict';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
if (taggedTemplateExpression.name) {
|
|
8
|
-
// Call to html`` and we assume that html = LitHtml's html function.
|
|
9
|
-
return taggedTemplateExpression.name === 'html';
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// Match calls to LitHtml.html``
|
|
13
|
-
return taggedTemplateExpression.object && taggedTemplateExpression.object.name === 'LitHtml' &&
|
|
14
|
-
taggedTemplateExpression.property.name === 'html';
|
|
15
|
-
}
|
|
6
|
+
const {isLitHtmlTemplateCall} = require('./utils.js');
|
|
16
7
|
|
|
17
8
|
function countOccurencesOfSubstring(string, subString) {
|
|
18
9
|
let count = 0;
|
|
@@ -71,7 +62,7 @@ module.exports = {
|
|
|
71
62
|
create: function(context) {
|
|
72
63
|
return {
|
|
73
64
|
TaggedTemplateExpression(node) {
|
|
74
|
-
const isLitHtmlCall = isLitHtmlTemplateCall(node
|
|
65
|
+
const isLitHtmlCall = isLitHtmlTemplateCall(node);
|
|
75
66
|
if (!isLitHtmlCall) {
|
|
76
67
|
return;
|
|
77
68
|
}
|
|
@@ -3,16 +3,7 @@
|
|
|
3
3
|
// found in the LICENSE file.
|
|
4
4
|
'use strict';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
if (taggedTemplateExpression.name) {
|
|
8
|
-
// Call to html`` and we assume that html = LitHtml's html function.
|
|
9
|
-
return taggedTemplateExpression.name === 'html';
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
// Match calls to LitHtml.html``
|
|
13
|
-
return taggedTemplateExpression.object && taggedTemplateExpression.object.name === 'LitHtml' &&
|
|
14
|
-
taggedTemplateExpression.property.name === 'html';
|
|
15
|
-
}
|
|
6
|
+
const {isLitHtmlTemplateCall} = require('./utils.js');
|
|
16
7
|
|
|
17
8
|
module.exports = {
|
|
18
9
|
meta: {
|
|
@@ -52,7 +43,7 @@ module.exports = {
|
|
|
52
43
|
|
|
53
44
|
return {
|
|
54
45
|
TaggedTemplateExpression(node) {
|
|
55
|
-
if (!isLitHtmlTemplateCall(node
|
|
46
|
+
if (!isLitHtmlTemplateCall(node)) {
|
|
56
47
|
return;
|
|
57
48
|
}
|
|
58
49
|
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Copyright 2021 The Chromium Authors. All rights reserved.
|
|
2
|
+
// Use of this source code is governed by a BSD-style license that can be
|
|
3
|
+
// found in the LICENSE file.
|
|
4
|
+
|
|
5
|
+
// This file contains utility functions that are commonly needed in ESLint
|
|
6
|
+
// rules. It does not contain any ESLint rules itself.
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @param taggedTemplateExpressionNode - a TaggedTemplateExpression node from the AST of the parsed code.
|
|
10
|
+
* @returns {boolean} - `true` if the code matches LitHtml.html`` or html``, and false otherwise.
|
|
11
|
+
*/
|
|
12
|
+
function isLitHtmlTemplateCall(taggedTemplateExpressionNode) {
|
|
13
|
+
if (taggedTemplateExpressionNode.type !== 'TaggedTemplateExpression') {
|
|
14
|
+
throw new Error('Node of type other than TaggedTemplateExpression passed to isLitHtmlTemplateCall.');
|
|
15
|
+
}
|
|
16
|
+
// Match LitHtml.html``
|
|
17
|
+
const {tag} = taggedTemplateExpressionNode;
|
|
18
|
+
if (!tag) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
// Match LitHtml.html``
|
|
22
|
+
const isLitHtmlDotHtmlCall = tag.object?.name === 'LitHtml' && tag.property?.name === 'html';
|
|
23
|
+
// Match html`` (and guess that it's Lit)
|
|
24
|
+
const isDestructuredHtmlCall = tag.type === 'Identifier' && tag.name === 'html';
|
|
25
|
+
|
|
26
|
+
return isLitHtmlDotHtmlCall || isDestructuredHtmlCall;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports = {isLitHtmlTemplateCall};
|
|
@@ -10,5 +10,9 @@ rulesDirPlugin.RULES_DIR = path.join(__dirname, '..', 'lib');
|
|
|
10
10
|
module.exports = {
|
|
11
11
|
'rules': {
|
|
12
12
|
'rulesdir/no_only_eslint_tests': 2,
|
|
13
|
+
// errors on it('test') with no body
|
|
14
|
+
'mocha/no-pending-tests': 2,
|
|
15
|
+
// errors on {describe, it}.only
|
|
16
|
+
'mocha/no-exclusive-tests': 2,
|
|
13
17
|
}
|
|
14
18
|
};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
// Copyright 2021 The Chromium Authors. All rights reserved.
|
|
2
|
+
// Use of this source code is governed by a BSD-style license that can be
|
|
3
|
+
// found in the LICENSE file.
|
|
4
|
+
|
|
5
|
+
const parser = require('@typescript-eslint/parser');
|
|
6
|
+
|
|
7
|
+
const utils = require('../lib/utils.js');
|
|
8
|
+
const {assert} = require('chai');
|
|
9
|
+
|
|
10
|
+
describe('eslint utils', () => {
|
|
11
|
+
describe('isLitHtmlTemplateCall', () => {
|
|
12
|
+
it('returns true if the code is LitHtml.html``', () => {
|
|
13
|
+
const code = 'LitHtml.html`<span>foo</span>`';
|
|
14
|
+
const parsed = parser.parse(code);
|
|
15
|
+
const result = utils.isLitHtmlTemplateCall(parsed.body[0].expression);
|
|
16
|
+
assert.strictEqual(result, true);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it('returns true if the code is html``', () => {
|
|
20
|
+
const code = 'html`<span>foo</span>`';
|
|
21
|
+
const parsed = parser.parse(code);
|
|
22
|
+
const result = utils.isLitHtmlTemplateCall(parsed.body[0].expression);
|
|
23
|
+
assert.strictEqual(result, true);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('returns false if the code is LitHtml.somethingElse``', () => {
|
|
27
|
+
const code = 'LitHtml.somethingElse`<span>foo</span>`';
|
|
28
|
+
const parsed = parser.parse(code);
|
|
29
|
+
const result = utils.isLitHtmlTemplateCall(parsed.body[0].expression);
|
|
30
|
+
assert.strictEqual(result, false);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('returns false if the code is another tagged template function``', () => {
|
|
34
|
+
const code = 'notLitHtml`<span>foo</span>`';
|
|
35
|
+
const parsed = parser.parse(code);
|
|
36
|
+
const result = utils.isLitHtmlTemplateCall(parsed.body[0].expression);
|
|
37
|
+
assert.strictEqual(result, false);
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
});
|
|
@@ -1,141 +0,0 @@
|
|
|
1
|
-
// Copyright 2017 The Chromium Authors. All rights reserved.
|
|
2
|
-
// Use of this source code is governed by a BSD-style license that can be
|
|
3
|
-
// found in the LICENSE file.
|
|
4
|
-
|
|
5
|
-
import * as Common from '../../core/common/common.js';
|
|
6
|
-
import * as Host from '../../core/host/host.js';
|
|
7
|
-
import * as UI from '../../ui/legacy/legacy.js';
|
|
8
|
-
|
|
9
|
-
import {releaseNoteText} from './ReleaseNoteText.js';
|
|
10
|
-
|
|
11
|
-
export const releaseVersionSeen = 'releaseNoteVersionSeen';
|
|
12
|
-
|
|
13
|
-
export const releaseNoteViewId: string = 'release-note';
|
|
14
|
-
|
|
15
|
-
let latestReleaseNoteInstance: ReleaseNote;
|
|
16
|
-
|
|
17
|
-
let releaseNotesForTest: ReleaseNote[];
|
|
18
|
-
|
|
19
|
-
let releaseNoteVersionSetting: Common.Settings.Setting<number>;
|
|
20
|
-
|
|
21
|
-
export function latestReleaseNote(): ReleaseNote {
|
|
22
|
-
if (!latestReleaseNoteInstance) {
|
|
23
|
-
latestReleaseNoteInstance =
|
|
24
|
-
(releaseNotesForTest || releaseNoteText).reduce((acc, note) => note.version > acc.version ? note : acc);
|
|
25
|
-
}
|
|
26
|
-
return latestReleaseNoteInstance;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function showReleaseNoteIfNeeded(): void {
|
|
30
|
-
const releaseNoteVersionSetting = Common.Settings.Settings.instance().createSetting(releaseVersionSeen, 0);
|
|
31
|
-
const releaseNoteVersionSettingValue = releaseNoteVersionSetting.get();
|
|
32
|
-
innerShowReleaseNoteIfNeeded(
|
|
33
|
-
releaseNoteVersionSettingValue, latestReleaseNote().version,
|
|
34
|
-
Common.Settings.Settings.instance().moduleSetting('help.show-release-note').get());
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function setReleaseNotesForTest(releaseNote: ReleaseNote[]): void {
|
|
38
|
-
releaseNotesForTest = releaseNote;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export function getReleaseNoteVersionSetting(): Common.Settings.Setting<number> {
|
|
42
|
-
if (!releaseNoteVersionSetting) {
|
|
43
|
-
releaseNoteVersionSetting = Common.Settings.Settings.instance().createSetting(releaseVersionSeen, 0);
|
|
44
|
-
}
|
|
45
|
-
return releaseNoteVersionSetting;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function innerShowReleaseNoteIfNeeded(
|
|
49
|
-
lastSeenVersion: number, latestVersion: number, showReleaseNote: boolean): boolean {
|
|
50
|
-
const releaseNoteVersionSetting = Common.Settings.Settings.instance().createSetting(releaseVersionSeen, 0);
|
|
51
|
-
if (!lastSeenVersion) {
|
|
52
|
-
releaseNoteVersionSetting.set(latestVersion);
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
if (!showReleaseNote) {
|
|
56
|
-
return false;
|
|
57
|
-
}
|
|
58
|
-
if (lastSeenVersion >= latestVersion) {
|
|
59
|
-
return false;
|
|
60
|
-
}
|
|
61
|
-
releaseNoteVersionSetting.set(latestVersion);
|
|
62
|
-
UI.ViewManager.ViewManager.instance().showView(releaseNoteViewId, true);
|
|
63
|
-
return true;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
let helpLateInitializationInstance: HelpLateInitialization;
|
|
67
|
-
export class HelpLateInitialization implements Common.Runnable.Runnable {
|
|
68
|
-
static instance(opts: {forceNew: boolean|null} = {forceNew: null}): HelpLateInitialization {
|
|
69
|
-
const {forceNew} = opts;
|
|
70
|
-
if (!helpLateInitializationInstance || forceNew) {
|
|
71
|
-
helpLateInitializationInstance = new HelpLateInitialization();
|
|
72
|
-
}
|
|
73
|
-
return helpLateInitializationInstance;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
async run(): Promise<void> {
|
|
77
|
-
if (!Host.InspectorFrontendHost.isUnderTest()) {
|
|
78
|
-
showReleaseNoteIfNeeded();
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
let releaseNotesActionDelegateInstance: ReleaseNotesActionDelegate;
|
|
84
|
-
export class ReleaseNotesActionDelegate implements UI.ActionRegistration.ActionDelegate {
|
|
85
|
-
handleAction(_context: UI.Context.Context, _actionId: string): boolean {
|
|
86
|
-
Host.InspectorFrontendHost.InspectorFrontendHostInstance.openInNewTab(latestReleaseNote().link);
|
|
87
|
-
return true;
|
|
88
|
-
}
|
|
89
|
-
static instance(opts: {forceNew: boolean|null} = {forceNew: null}): ReleaseNotesActionDelegate {
|
|
90
|
-
const {forceNew} = opts;
|
|
91
|
-
if (!releaseNotesActionDelegateInstance || forceNew) {
|
|
92
|
-
releaseNotesActionDelegateInstance = new ReleaseNotesActionDelegate();
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
return releaseNotesActionDelegateInstance;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
let reportIssueActionDelegateInstance: ReportIssueActionDelegate;
|
|
100
|
-
export class ReportIssueActionDelegate implements UI.ActionRegistration.ActionDelegate {
|
|
101
|
-
handleAction(_context: UI.Context.Context, _actionId: string): boolean {
|
|
102
|
-
Host.InspectorFrontendHost.InspectorFrontendHostInstance.openInNewTab(
|
|
103
|
-
'https://bugs.chromium.org/p/chromium/issues/entry?template=DevTools+issue');
|
|
104
|
-
return true;
|
|
105
|
-
}
|
|
106
|
-
static instance(opts: {forceNew: boolean|null} = {forceNew: null}): ReportIssueActionDelegate {
|
|
107
|
-
const {forceNew} = opts;
|
|
108
|
-
if (!reportIssueActionDelegateInstance || forceNew) {
|
|
109
|
-
reportIssueActionDelegateInstance = new ReportIssueActionDelegate();
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
return reportIssueActionDelegateInstance;
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
let reportTranslationIssueActionDelegateInstance: ReportTranslationIssueActionDelegate;
|
|
117
|
-
export class ReportTranslationIssueActionDelegate implements UI.ActionRegistration.ActionDelegate {
|
|
118
|
-
handleAction(_context: UI.Context.Context, _actionId: string): boolean {
|
|
119
|
-
Host.InspectorFrontendHost.InspectorFrontendHostInstance.openInNewTab('https://goo.gle/devtools-translate');
|
|
120
|
-
return true;
|
|
121
|
-
}
|
|
122
|
-
static instance(opts: {forceNew: boolean|null} = {forceNew: null}): ReportTranslationIssueActionDelegate {
|
|
123
|
-
const {forceNew} = opts;
|
|
124
|
-
if (!reportTranslationIssueActionDelegateInstance || forceNew) {
|
|
125
|
-
reportTranslationIssueActionDelegateInstance = new ReportTranslationIssueActionDelegate();
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
return reportTranslationIssueActionDelegateInstance;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
export interface ReleaseNoteHighlight {
|
|
132
|
-
title: string;
|
|
133
|
-
subtitle: string;
|
|
134
|
-
link: string;
|
|
135
|
-
}
|
|
136
|
-
export interface ReleaseNote {
|
|
137
|
-
version: number;
|
|
138
|
-
header: string;
|
|
139
|
-
highlights: {title: string, subtitle: string, link: string}[];
|
|
140
|
-
link: string;
|
|
141
|
-
}
|