@salesforcedevs/docs-components 1.3.221 → 1.3.228-version-picker1
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/lwc.config.json +1 -0
- package/package.json +2 -2
- package/src/modules/doc/amfReference/amfReference.css +0 -8
- package/src/modules/doc/amfReference/amfReference.html +11 -14
- package/src/modules/doc/amfReference/amfReference.ts +45 -7
- package/src/modules/doc/contentLayout/contentLayout.css +6 -1
- package/src/modules/doc/contentLayout/contentLayout.html +13 -2
- package/src/modules/doc/contentLayout/contentLayout.ts +5 -0
- package/src/modules/doc/header/header.css +23 -33
- package/src/modules/doc/header/header.html +2 -53
- package/src/modules/doc/header/header.ts +1 -92
- package/src/modules/doc/versionPicker/versionPicker.css +55 -0
- package/src/modules/doc/versionPicker/versionPicker.html +34 -0
- package/src/modules/doc/versionPicker/versionPicker.ts +49 -0
- package/src/modules/doc/xmlContent/types.ts +5 -2
- package/src/modules/doc/xmlContent/xmlContent.css +0 -5
- package/src/modules/doc/xmlContent/xmlContent.html +10 -10
- package/src/modules/doc/xmlContent/xmlContent.ts +26 -39
- package/LICENSE +0 -12
package/lwc.config.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforcedevs/docs-components",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.228-version-picker1",
|
|
4
4
|
"description": "Docs Lightning web components for DSC",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "index.js",
|
|
@@ -24,5 +24,5 @@
|
|
|
24
24
|
"@types/lodash.orderby": "^4.6.7",
|
|
25
25
|
"@types/lodash.uniqby": "^4.7.7"
|
|
26
26
|
},
|
|
27
|
-
"gitHead": "
|
|
27
|
+
"gitHead": "4629fdd9ca18a13480044ad43515b91945d16aad"
|
|
28
28
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<doc-content-layout
|
|
3
|
+
if:true={isVersionFetched}
|
|
3
4
|
use-old-sidebar={useOldSidebar}
|
|
4
5
|
class="content-type content-type-reference"
|
|
5
6
|
coveo-organization-id={coveoOrganizationId}
|
|
@@ -16,6 +17,8 @@
|
|
|
16
17
|
toc-title={tocTitle}
|
|
17
18
|
toc-options={tocOptions}
|
|
18
19
|
enable-slot-change="true"
|
|
20
|
+
languages={languages}
|
|
21
|
+
language={language}
|
|
19
22
|
>
|
|
20
23
|
<doc-phase
|
|
21
24
|
slot="doc-phase"
|
|
@@ -30,20 +33,14 @@
|
|
|
30
33
|
dismissible="true"
|
|
31
34
|
ondismissphase={handleDismissVersionBanner}
|
|
32
35
|
></doc-phase>
|
|
33
|
-
<div slot="sidebar-header"
|
|
34
|
-
<
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
>
|
|
42
|
-
<dx-button variant="inline" class="version-picker-text">
|
|
43
|
-
{selectedVersion.id}
|
|
44
|
-
</dx-button>
|
|
45
|
-
</dx-dropdown>
|
|
46
|
-
</template>
|
|
36
|
+
<div if:true={isVersionEnabled} slot="sidebar-header">
|
|
37
|
+
<doc-version-picker
|
|
38
|
+
onchange={handleVersionChange}
|
|
39
|
+
data-type="version"
|
|
40
|
+
versions={versions}
|
|
41
|
+
selected-version={selectedVersion}
|
|
42
|
+
latest-version={latestVersion}
|
|
43
|
+
></doc-version-picker>
|
|
47
44
|
</div>
|
|
48
45
|
<template if:false={showSpecBasedReference}>
|
|
49
46
|
<slot></slot>
|
|
@@ -3,7 +3,8 @@ import { noCase } from "no-case";
|
|
|
3
3
|
import { sentenceCase } from "sentence-case";
|
|
4
4
|
import qs from "query-string";
|
|
5
5
|
import { AmfModelParser } from "doc/amfModelParser";
|
|
6
|
-
import { normalizeBoolean } from "dxUtils/normalizers";
|
|
6
|
+
import { normalizeBoolean, toJson } from "dxUtils/normalizers";
|
|
7
|
+
import type { OptionWithLink } from "typings/custom";
|
|
7
8
|
import type {
|
|
8
9
|
AmfConfig,
|
|
9
10
|
AmfMetadataTopic,
|
|
@@ -43,14 +44,16 @@ export default class AmfReference extends LightningElement {
|
|
|
43
44
|
@api coveoOrganizationId!: string;
|
|
44
45
|
@api coveoPublicAccessToken!: string;
|
|
45
46
|
@api coveoAnalyticsToken!: string;
|
|
46
|
-
@api coveoAdvancedQueryConfig!: string;
|
|
47
47
|
@api coveoSearchHub!: string;
|
|
48
48
|
@api useOldSidebar: boolean = false;
|
|
49
49
|
@api tocTitle?: string;
|
|
50
50
|
@api tocOptions?: string;
|
|
51
|
+
@api languages!: OptionWithLink[];
|
|
52
|
+
@api language!: string;
|
|
51
53
|
@track navigation = [] as NavigationItem[];
|
|
52
54
|
@track versions: Array<ReferenceVersion> = [];
|
|
53
55
|
@track showVersionBanner = false;
|
|
56
|
+
@track _coveoAdvancedQueryConfig!: { [key: string]: any };
|
|
54
57
|
|
|
55
58
|
// Update this to update what component gets rendered in the content block
|
|
56
59
|
@track
|
|
@@ -114,12 +117,16 @@ export default class AmfReference extends LightningElement {
|
|
|
114
117
|
this.versions = this.getVersions();
|
|
115
118
|
}
|
|
116
119
|
this.selectedVersion = selectedVersion;
|
|
117
|
-
if (
|
|
118
|
-
this.
|
|
119
|
-
this.oldVersionInfo
|
|
120
|
-
|
|
121
|
-
|
|
120
|
+
if (this.isSpecBasedReference(this._currentReferenceId)) {
|
|
121
|
+
this.isVersionFetched = true;
|
|
122
|
+
if (this.oldVersionInfo) {
|
|
123
|
+
this.showVersionBanner = true;
|
|
124
|
+
} else {
|
|
125
|
+
this.latestVersion = true;
|
|
126
|
+
}
|
|
122
127
|
}
|
|
128
|
+
} else {
|
|
129
|
+
this.isVersionFetched = true;
|
|
123
130
|
}
|
|
124
131
|
|
|
125
132
|
// This is to check if the url is hash based and redirect if needed
|
|
@@ -152,6 +159,31 @@ export default class AmfReference extends LightningElement {
|
|
|
152
159
|
this._expandChildren = normalizeBoolean(value);
|
|
153
160
|
}
|
|
154
161
|
|
|
162
|
+
/*
|
|
163
|
+
* The get coveoAdvancedQueryConfig() method returns this._coveoAdvancedQueryConfig,
|
|
164
|
+
* but before returning it, it checks if there are multiple versions (this.versions.length > 1)
|
|
165
|
+
* and if a version is selected (this.selectedVersion). If both conditions are met,
|
|
166
|
+
* it updates the version property of this._coveoAdvancedQueryConfig with the selected version.
|
|
167
|
+
*/
|
|
168
|
+
@api
|
|
169
|
+
get coveoAdvancedQueryConfig(): { [key: string]: any } {
|
|
170
|
+
const coveoConfig = this._coveoAdvancedQueryConfig;
|
|
171
|
+
if (this.versions.length > 1 && this.selectedVersion) {
|
|
172
|
+
const currentGAVersionRef = this.versions[0];
|
|
173
|
+
if (this.selectedVersion.id !== currentGAVersionRef.id) {
|
|
174
|
+
// Currently Coveo only supports query without "v"
|
|
175
|
+
const version = this.selectedVersion.id.replace("v", "");
|
|
176
|
+
coveoConfig.version = version;
|
|
177
|
+
this._coveoAdvancedQueryConfig = coveoConfig;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return this._coveoAdvancedQueryConfig;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
set coveoAdvancedQueryConfig(config) {
|
|
184
|
+
this._coveoAdvancedQueryConfig = toJson(config);
|
|
185
|
+
}
|
|
186
|
+
|
|
155
187
|
// model
|
|
156
188
|
protected _amfConfigList: AmfConfig[] = [];
|
|
157
189
|
protected _amfConfigMap: Map<string, AmfConfig> = new Map();
|
|
@@ -172,6 +204,9 @@ export default class AmfReference extends LightningElement {
|
|
|
172
204
|
private isParentLevelDocPhaseEnabled = false;
|
|
173
205
|
private selectedReferenceDocPhase?: string | null = null;
|
|
174
206
|
private _expandChildren?: boolean = false;
|
|
207
|
+
private isVersionFetched = false;
|
|
208
|
+
@track
|
|
209
|
+
private latestVersion = false;
|
|
175
210
|
|
|
176
211
|
/**
|
|
177
212
|
* Key for storing the currently selected reference url. This will be used to save the
|
|
@@ -1282,8 +1317,11 @@ export default class AmfReference extends LightningElement {
|
|
|
1282
1317
|
this.versions = this.getVersions();
|
|
1283
1318
|
if (this.oldVersionInfo) {
|
|
1284
1319
|
this.showVersionBanner = true;
|
|
1320
|
+
} else {
|
|
1321
|
+
this.latestVersion = true;
|
|
1285
1322
|
}
|
|
1286
1323
|
|
|
1324
|
+
this.isVersionFetched = true;
|
|
1287
1325
|
this.updateDocPhase();
|
|
1288
1326
|
this.selectedSidebarValue = window.location.pathname;
|
|
1289
1327
|
}
|
|
@@ -61,12 +61,16 @@ dx-toc {
|
|
|
61
61
|
flex-direction: row;
|
|
62
62
|
justify-content: center;
|
|
63
63
|
max-width: var(--dx-g-doc-content-max-width);
|
|
64
|
+
|
|
65
|
+
/* Derived this manually by substracting (topHeader, doc header, banner and the content). */
|
|
66
|
+
min-height: 62vh;
|
|
64
67
|
margin: auto;
|
|
65
68
|
padding: 0 var(--dx-g-global-header-padding-horizontal);
|
|
69
|
+
margin-bottom: calc(2 * (var(--dx-g-spacing-5xl) + 4px));
|
|
66
70
|
}
|
|
67
71
|
|
|
68
72
|
.content-body {
|
|
69
|
-
margin: var(--dx-g-spacing-sm) 0
|
|
73
|
+
margin: var(--dx-g-spacing-sm) 0 0;
|
|
70
74
|
max-width: 900px;
|
|
71
75
|
flex: 1;
|
|
72
76
|
width: 0;
|
|
@@ -106,6 +110,7 @@ dx-toc {
|
|
|
106
110
|
.content-body-container {
|
|
107
111
|
padding-right: 0;
|
|
108
112
|
overflow-x: auto;
|
|
113
|
+
margin-bottom: calc(var(--dx-g-spacing-5xl) + 4px);
|
|
109
114
|
}
|
|
110
115
|
|
|
111
116
|
.left-nav-bar {
|
|
@@ -7,8 +7,12 @@
|
|
|
7
7
|
value={sidebarValue}
|
|
8
8
|
header={sidebarHeader}
|
|
9
9
|
ontogglesidebar={onToggleSidebar}
|
|
10
|
+
languages={languages}
|
|
11
|
+
language={language}
|
|
12
|
+
bail-href={bailHref}
|
|
13
|
+
bail-label={bailLabel}
|
|
10
14
|
>
|
|
11
|
-
<slot name="sidebar-header" slot="
|
|
15
|
+
<slot name="sidebar-header" slot="version-picker"></slot>
|
|
12
16
|
</dx-sidebar-old>
|
|
13
17
|
</template>
|
|
14
18
|
<template if:false={useOldSidebar}>
|
|
@@ -22,8 +26,12 @@
|
|
|
22
26
|
coveo-search-hub={coveoSearchHub}
|
|
23
27
|
coveo-advanced-query-config={coveoAdvancedQueryConfig}
|
|
24
28
|
ontogglesidebar={onToggleSidebar}
|
|
29
|
+
languages={languages}
|
|
30
|
+
language={language}
|
|
31
|
+
bail-href={bailHref}
|
|
32
|
+
bail-label={bailLabel}
|
|
25
33
|
>
|
|
26
|
-
<slot name="sidebar-header" slot="
|
|
34
|
+
<slot name="sidebar-header" slot="version-picker"></slot>
|
|
27
35
|
</dx-sidebar>
|
|
28
36
|
</template>
|
|
29
37
|
<div class="content-body-doc-phase-container">
|
|
@@ -48,6 +56,9 @@
|
|
|
48
56
|
></dx-toc>
|
|
49
57
|
</div>
|
|
50
58
|
</div>
|
|
59
|
+
<div class="footer-container">
|
|
60
|
+
<dx-footer variant="no-signup"></dx-footer>
|
|
61
|
+
</div>
|
|
51
62
|
</div>
|
|
52
63
|
</div>
|
|
53
64
|
</template>
|
|
@@ -4,6 +4,7 @@ import { closest } from "kagekiri";
|
|
|
4
4
|
import { toJson } from "dxUtils/normalizers";
|
|
5
5
|
import { highlightTerms } from "dxUtils/highlight";
|
|
6
6
|
import { SearchSyncer } from "docUtils/searchSyncer";
|
|
7
|
+
import type { OptionWithLink } from "typings/custom";
|
|
7
8
|
|
|
8
9
|
type AnchorMap = { [key: string]: { intersect: boolean; id: string } };
|
|
9
10
|
|
|
@@ -36,6 +37,10 @@ export default class ContentLayout extends LightningElement {
|
|
|
36
37
|
@api coveoSearchHub!: string;
|
|
37
38
|
@api coveoAdvancedQueryConfig!: string;
|
|
38
39
|
@api useOldSidebar?: boolean = false;
|
|
40
|
+
@api languages!: OptionWithLink[];
|
|
41
|
+
@api language!: string;
|
|
42
|
+
@api bailHref!: string;
|
|
43
|
+
@api bailLabel!: string;
|
|
39
44
|
|
|
40
45
|
@api
|
|
41
46
|
get breadcrumbs() {
|
|
@@ -7,6 +7,8 @@ dx-logo {
|
|
|
7
7
|
.header_l2 {
|
|
8
8
|
justify-content: space-between;
|
|
9
9
|
height: var(--dx-g-doc-header-main-nav-height);
|
|
10
|
+
padding-bottom: var(--dx-g-spacing-xs);
|
|
11
|
+
background: white;
|
|
10
12
|
}
|
|
11
13
|
|
|
12
14
|
.nav_menu-button {
|
|
@@ -16,44 +18,32 @@ dx-logo {
|
|
|
16
18
|
);
|
|
17
19
|
}
|
|
18
20
|
|
|
21
|
+
.has-brand.has-scoped-nav-items {
|
|
22
|
+
border-bottom: 1px solid var(--dx-g-gray-90);
|
|
23
|
+
border-top: 1px solid var(--dx-g-gray-90);
|
|
24
|
+
}
|
|
25
|
+
|
|
19
26
|
.nav_menu-ctas {
|
|
20
27
|
margin-right: var(--dx-g-spacing-sm);
|
|
21
28
|
}
|
|
22
29
|
|
|
23
30
|
header:not(.has-brand) > .header_l1 {
|
|
24
|
-
background:
|
|
31
|
+
background: white;
|
|
32
|
+
border-bottom: 1px solid var(--dx-g-gray-90);
|
|
25
33
|
}
|
|
26
34
|
|
|
27
35
|
header:not(.has-brand) > .header_l2 {
|
|
28
|
-
|
|
36
|
+
border-bottom: 1px solid var(--dx-g-gray-90);
|
|
37
|
+
border-top: 1px solid var(--dx-g-gray-90);
|
|
38
|
+
padding-bottom: var(--dx-g-spacing-lg);
|
|
29
39
|
}
|
|
30
40
|
|
|
31
41
|
.header_l2_group.header_l2_group-right-ctas {
|
|
32
42
|
align-items: baseline;
|
|
33
43
|
}
|
|
34
44
|
|
|
35
|
-
.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
margin-left: var(--dx-g-spacing-sm);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
.header_lang-dropdown {
|
|
42
|
-
--button-primary-color: var(--dx-g-blue-vibrant-40);
|
|
43
|
-
--button-primary-color-hover: var(--dx-g-blue-vibrant-30);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
.header_lang-dropdown > dx-button {
|
|
47
|
-
--dx-c-button-primary-color: var(--button-primary-color);
|
|
48
|
-
--dx-c-button-primary-color-hover: var(--button-primary-color-hover);
|
|
49
|
-
--dx-c-slot-empty-width: min-content;
|
|
50
|
-
--border-color: var(--button-primary-color);
|
|
51
|
-
|
|
52
|
-
border-bottom: 1px dashed var(--border-color);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
.header_lang-dropdown > dx-button:hover {
|
|
56
|
-
--border-color: var(--button-primary-color-hover);
|
|
45
|
+
.has-brand .header_l2_group-title {
|
|
46
|
+
padding-bottom: calc(var(--dx-g-spacing-md) + 2px);
|
|
57
47
|
}
|
|
58
48
|
|
|
59
49
|
@media (max-width: 768px) {
|
|
@@ -82,6 +72,10 @@ header:not(.has-brand) > .header_l2 {
|
|
|
82
72
|
margin-right: var(--dx-g-spacing-sm);
|
|
83
73
|
}
|
|
84
74
|
|
|
75
|
+
.has-brand .header_l2_group-title {
|
|
76
|
+
padding-bottom: var(--dx-g-spacing-smd);
|
|
77
|
+
}
|
|
78
|
+
|
|
85
79
|
.header_l2_group-title {
|
|
86
80
|
margin-right: 0;
|
|
87
81
|
padding: var(--dx-g-spacing-smd)
|
|
@@ -89,19 +83,15 @@ header:not(.has-brand) > .header_l2 {
|
|
|
89
83
|
min-height: var(--dx-g-doc-header-main-nav-height);
|
|
90
84
|
}
|
|
91
85
|
|
|
92
|
-
.header_l2_group-title .header_lang-dropdown {
|
|
93
|
-
margin-left: auto;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
.header_lang-dropdown > dx-button {
|
|
97
|
-
padding: var(--dx-g-spacing-2xs) 0;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
86
|
.has-scoped-nav-items > .header_l2 {
|
|
101
87
|
height: unset;
|
|
102
88
|
}
|
|
103
89
|
|
|
104
90
|
.has-scoped-nav-items .header_l2_group-title {
|
|
105
|
-
border-bottom: 1px solid var(--dx-g-
|
|
91
|
+
border-bottom: 1px solid var(--dx-g-gray-90);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
header:not(.has-brand) > .header_l2 {
|
|
95
|
+
padding-bottom: 0;
|
|
106
96
|
}
|
|
107
97
|
}
|
|
@@ -14,28 +14,12 @@
|
|
|
14
14
|
if:true={isValidBrand}
|
|
15
15
|
sprite="salesforcebrand"
|
|
16
16
|
symbol={brand}
|
|
17
|
-
size="
|
|
17
|
+
size="large"
|
|
18
18
|
></dx-icon>
|
|
19
|
-
<span class="subtitle dx-text-display-
|
|
19
|
+
<span class="subtitle dx-text-display-7">
|
|
20
20
|
{subtitle}
|
|
21
21
|
</span>
|
|
22
22
|
</a>
|
|
23
|
-
<dx-dropdown
|
|
24
|
-
if:true={showMobileLanguages}
|
|
25
|
-
class="header_lang-dropdown"
|
|
26
|
-
options={languages}
|
|
27
|
-
small
|
|
28
|
-
value={language}
|
|
29
|
-
value-path={langValuePath}
|
|
30
|
-
onchange={onLangChange}
|
|
31
|
-
>
|
|
32
|
-
<dx-button
|
|
33
|
-
aria-label="Select Language"
|
|
34
|
-
variant="inline"
|
|
35
|
-
icon-size="large"
|
|
36
|
-
icon-symbol="world"
|
|
37
|
-
></dx-button>
|
|
38
|
-
</dx-dropdown>
|
|
39
23
|
</div>
|
|
40
24
|
<div
|
|
41
25
|
if:true={hasScopedNavItems}
|
|
@@ -52,41 +36,6 @@
|
|
|
52
36
|
></dx-header-nav>
|
|
53
37
|
</div>
|
|
54
38
|
</div>
|
|
55
|
-
<div
|
|
56
|
-
if:false={smallMobile}
|
|
57
|
-
class="header_l2_group header_l2_group-right-ctas"
|
|
58
|
-
>
|
|
59
|
-
<dx-dropdown
|
|
60
|
-
if:true={hasLanguages}
|
|
61
|
-
class="header_lang-dropdown"
|
|
62
|
-
options={languages}
|
|
63
|
-
small
|
|
64
|
-
value-path={langValuePath}
|
|
65
|
-
value={language}
|
|
66
|
-
onchange={onLangChange}
|
|
67
|
-
>
|
|
68
|
-
<dx-button
|
|
69
|
-
aria-label="Select Language"
|
|
70
|
-
variant="inline"
|
|
71
|
-
icon-size="small"
|
|
72
|
-
icon-symbol="world"
|
|
73
|
-
>
|
|
74
|
-
{languageLabel}
|
|
75
|
-
</dx-button>
|
|
76
|
-
</dx-dropdown>
|
|
77
|
-
<dx-button
|
|
78
|
-
if:true={hasBailLink}
|
|
79
|
-
aria-label={bailLabel}
|
|
80
|
-
class="header_bail-link"
|
|
81
|
-
href={bailHref}
|
|
82
|
-
onclick={handleBailClick}
|
|
83
|
-
variant="tertiary"
|
|
84
|
-
icon-symbol="new_window"
|
|
85
|
-
target="_blank"
|
|
86
|
-
>
|
|
87
|
-
{bailLabel}
|
|
88
|
-
</dx-button>
|
|
89
|
-
</div>
|
|
90
39
|
</div>
|
|
91
40
|
</header>
|
|
92
41
|
</dx-brand-theme-provider>
|
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
import { api } from "lwc";
|
|
2
2
|
import cx from "classnames";
|
|
3
|
-
import type { OptionWithNested
|
|
3
|
+
import type { OptionWithNested } from "typings/custom";
|
|
4
4
|
import { HeaderBase } from "dxBaseElements/headerBase";
|
|
5
5
|
import { toJson } from "dxUtils/normalizers";
|
|
6
|
-
import get from "lodash.get";
|
|
7
|
-
import { track } from "dxUtils/analytics";
|
|
8
6
|
|
|
9
7
|
const TABLET_MATCH = "980px";
|
|
10
8
|
const MOBILE_MATCH = "880px";
|
|
11
|
-
const SMALL_MOBILE_MATCH = "768px";
|
|
12
9
|
|
|
13
10
|
export default class Header extends HeaderBase {
|
|
14
11
|
@api langValuePath: string = "id"; // allows to override how language property is interpreted, follows valuePath dropdown api.
|
|
@@ -23,31 +20,7 @@ export default class Header extends HeaderBase {
|
|
|
23
20
|
this._scopedNavItems = toJson(value);
|
|
24
21
|
}
|
|
25
22
|
|
|
26
|
-
@api
|
|
27
|
-
get languages() {
|
|
28
|
-
return this._languages;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
set languages(value) {
|
|
32
|
-
this._languages = toJson(value);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
@api
|
|
36
|
-
get language() {
|
|
37
|
-
return this._language;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
set language(value) {
|
|
41
|
-
if (this._language !== value) {
|
|
42
|
-
this._language = value;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
private _language: string | null = null;
|
|
47
|
-
private _languages!: OptionWithLink[];
|
|
48
23
|
private _scopedNavItems!: OptionWithNested[];
|
|
49
|
-
private smallMobile = false;
|
|
50
|
-
private smallMobileMatchMedia!: MediaQueryList;
|
|
51
24
|
private tablet = false;
|
|
52
25
|
private tabletMatchMedia!: MediaQueryList;
|
|
53
26
|
private shouldRender = false;
|
|
@@ -60,24 +33,6 @@ export default class Header extends HeaderBase {
|
|
|
60
33
|
return this.scopedNavItems && this.scopedNavItems.length > 0;
|
|
61
34
|
}
|
|
62
35
|
|
|
63
|
-
private get hasLanguages(): boolean {
|
|
64
|
-
return !!(this.languages && this.languages.length);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
private get showMobileLanguages(): boolean {
|
|
68
|
-
return this.smallMobile && this.hasLanguages;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
private get languageLabel(): string {
|
|
72
|
-
return (
|
|
73
|
-
(this.language &&
|
|
74
|
-
this.languages.find(
|
|
75
|
-
(lang) => get(lang, this.langValuePath) === this.language
|
|
76
|
-
)?.label) ||
|
|
77
|
-
this.languages[0].label
|
|
78
|
-
);
|
|
79
|
-
}
|
|
80
|
-
|
|
81
36
|
connectedCallback(): void {
|
|
82
37
|
super.connectedCallback();
|
|
83
38
|
this.tabletMatchMedia = window.matchMedia(
|
|
@@ -86,14 +41,6 @@ export default class Header extends HeaderBase {
|
|
|
86
41
|
this.onTabletChange(this.tabletMatchMedia);
|
|
87
42
|
this.tabletMatchMedia.addEventListener("change", this.onTabletChange);
|
|
88
43
|
|
|
89
|
-
this.smallMobileMatchMedia = window.matchMedia(
|
|
90
|
-
`(max-width: ${SMALL_MOBILE_MATCH})`
|
|
91
|
-
);
|
|
92
|
-
this.onSmallMobileChange(this.smallMobileMatchMedia);
|
|
93
|
-
this.smallMobileMatchMedia.addEventListener(
|
|
94
|
-
"change",
|
|
95
|
-
this.onSmallMobileChange
|
|
96
|
-
);
|
|
97
44
|
if (
|
|
98
45
|
(window.location.pathname.includes("/docs/") &&
|
|
99
46
|
window.location.pathname !== "/docs/apis") ||
|
|
@@ -112,53 +59,15 @@ export default class Header extends HeaderBase {
|
|
|
112
59
|
"change",
|
|
113
60
|
this.onTabletChange
|
|
114
61
|
);
|
|
115
|
-
|
|
116
|
-
this.smallMobileMatchMedia.removeEventListener(
|
|
117
|
-
"change",
|
|
118
|
-
this.onSmallMobileChange
|
|
119
|
-
);
|
|
120
62
|
}
|
|
121
63
|
|
|
122
64
|
private onTabletChange = (e: MediaQueryListEvent | MediaQueryList) =>
|
|
123
65
|
(this.tablet = e.matches);
|
|
124
66
|
|
|
125
|
-
private onSmallMobileChange = (e: MediaQueryListEvent | MediaQueryList) =>
|
|
126
|
-
(this.smallMobile = e.matches);
|
|
127
|
-
|
|
128
67
|
protected additionalClasses(): string {
|
|
129
68
|
return cx(
|
|
130
69
|
this.brand && "has-brand",
|
|
131
70
|
this.hasScopedNavItems && "has-scoped-nav-items"
|
|
132
71
|
);
|
|
133
72
|
}
|
|
134
|
-
|
|
135
|
-
private onLangChange(event: CustomEvent<string>): void {
|
|
136
|
-
const { detail } = event;
|
|
137
|
-
this._language = detail;
|
|
138
|
-
|
|
139
|
-
this.dispatchEvent(new CustomEvent("langchange", { detail }));
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
private handleBailClick(event: Event) {
|
|
143
|
-
const payload = {
|
|
144
|
-
click_text: "pdf",
|
|
145
|
-
click_url: this.bailHref,
|
|
146
|
-
element_title: "pdf",
|
|
147
|
-
element_type: "link",
|
|
148
|
-
content_category: "download"
|
|
149
|
-
};
|
|
150
|
-
track(event.target!, "custEv_pdfDownload", {
|
|
151
|
-
...payload,
|
|
152
|
-
file_name: this.getFilename(this.bailHref!),
|
|
153
|
-
file_extension: "pdf"
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
track(event.target!, "custEv_linkClick", {
|
|
157
|
-
...payload
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
private getFilename = function (path: string) {
|
|
162
|
-
return path.substring(path.lastIndexOf("/") + 1);
|
|
163
|
-
};
|
|
164
73
|
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
@import "dxHelpers/reset";
|
|
2
|
+
|
|
3
|
+
/* NOTE: doc-version-picker-width width variable is used by both dx-button and dx-dropdown to maintain a consistent width. */
|
|
4
|
+
:host {
|
|
5
|
+
--popover-container-open-transform: translateY(4px);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.version-picker-container {
|
|
9
|
+
padding: 8px var(--dx-g-spacing-lg) 8px
|
|
10
|
+
var(--dx-g-global-header-padding-horizontal);
|
|
11
|
+
border-top: 1px solid var(--dx-g-gray-90);
|
|
12
|
+
border-bottom: 1px solid var(--dx-g-gray-90);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
dx-button {
|
|
16
|
+
display: flex;
|
|
17
|
+
width: var(--doc-version-picker-width, 272px);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* NOTE: This CSS ensures the span inside the button stays within the parent's width, avoiding overflow.
|
|
22
|
+
* Not keeping this in common component to ensure that existing functionality works as it is.
|
|
23
|
+
*/
|
|
24
|
+
dx-button::part(content) {
|
|
25
|
+
width: inherit;
|
|
26
|
+
overflow: hidden;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.selected-version {
|
|
30
|
+
display: flex;
|
|
31
|
+
flex-direction: row;
|
|
32
|
+
align-items: center;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.selected-version-label {
|
|
36
|
+
flex: 1;
|
|
37
|
+
overflow: hidden;
|
|
38
|
+
text-align: left;
|
|
39
|
+
text-overflow: ellipsis;
|
|
40
|
+
white-space: nowrap;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
dx-type-badge.latest-badge {
|
|
44
|
+
--dx-c-type-badge-color: var(--dx-g-green-vibrant-40);
|
|
45
|
+
--dx-c-type-badge-background: var(--dx-g-green-vibrant-95);
|
|
46
|
+
|
|
47
|
+
margin-left: var(--dx-g-spacing-sm);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
dx-type-badge.not-latest-badge {
|
|
51
|
+
--dx-c-type-badge-color: var(--dx-g-red-vibrant-40);
|
|
52
|
+
--dx-c-type-badge-background: var(--dx-g-red-vibrant-95);
|
|
53
|
+
|
|
54
|
+
margin-left: var(--dx-g-spacing-sm);
|
|
55
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div if:true={showVersionPicker} class="version-picker-container">
|
|
3
|
+
<dx-dropdown
|
|
4
|
+
options={versions}
|
|
5
|
+
value={selectedVersion.id}
|
|
6
|
+
width="var(--doc-version-picker-width)"
|
|
7
|
+
>
|
|
8
|
+
<dx-button
|
|
9
|
+
variant="tertiary"
|
|
10
|
+
size="small"
|
|
11
|
+
icon-symbol="chevrondown"
|
|
12
|
+
icon-size="medium"
|
|
13
|
+
>
|
|
14
|
+
<div class="selected-version">
|
|
15
|
+
<p class="selected-version-label">
|
|
16
|
+
{selectedVersion.label}
|
|
17
|
+
</p>
|
|
18
|
+
<dx-type-badge
|
|
19
|
+
class="latest-badge"
|
|
20
|
+
if:true={latestVersion}
|
|
21
|
+
value="Latest"
|
|
22
|
+
size="small"
|
|
23
|
+
></dx-type-badge>
|
|
24
|
+
<dx-type-badge
|
|
25
|
+
class="not-latest-badge"
|
|
26
|
+
if:false={latestVersion}
|
|
27
|
+
value="Not Latest"
|
|
28
|
+
size="small"
|
|
29
|
+
></dx-type-badge>
|
|
30
|
+
</div>
|
|
31
|
+
</dx-button>
|
|
32
|
+
</dx-dropdown>
|
|
33
|
+
</div>
|
|
34
|
+
</template>
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { LightningElement, api, track } from "lwc";
|
|
2
|
+
|
|
3
|
+
import { AnalyticsPayload, OptionWithNested } from "typings/custom";
|
|
4
|
+
|
|
5
|
+
import { toJson, normalizeBoolean } from "dxUtils/normalizers";
|
|
6
|
+
|
|
7
|
+
export default class VersionPicker extends LightningElement {
|
|
8
|
+
@api analyticsEvent?: string;
|
|
9
|
+
@api analyticsPayload?: AnalyticsPayload;
|
|
10
|
+
|
|
11
|
+
@track
|
|
12
|
+
private _versions!: OptionWithNested[];
|
|
13
|
+
private _selectedVersion?: OptionWithNested;
|
|
14
|
+
@track
|
|
15
|
+
private _latestVersion: boolean = false;
|
|
16
|
+
|
|
17
|
+
@api
|
|
18
|
+
get versions() {
|
|
19
|
+
return this._versions;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
set versions(value: OptionWithNested[]) {
|
|
23
|
+
this._versions = toJson(value);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@api
|
|
27
|
+
get selectedVersion(): OptionWithNested | undefined {
|
|
28
|
+
return this._selectedVersion || this.versions[0];
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
set selectedVersion(value: OptionWithNested) {
|
|
32
|
+
this._selectedVersion = toJson(value);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@api
|
|
36
|
+
get latestVersion() {
|
|
37
|
+
return this._latestVersion;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
set latestVersion(value) {
|
|
41
|
+
if (value) {
|
|
42
|
+
this._latestVersion = normalizeBoolean(value);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private get showVersionPicker() {
|
|
47
|
+
return this._versions && this._versions.length !== 0;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
@@ -61,12 +61,15 @@ export type ApiDocLanguage = {
|
|
|
61
61
|
|
|
62
62
|
export interface Header extends Element {
|
|
63
63
|
subtitle: string;
|
|
64
|
+
headerHref: string;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export type SiderbarFooter = {
|
|
64
68
|
bailHref: string;
|
|
65
69
|
bailLabel: string;
|
|
66
70
|
languages: Array<DocLanguage>;
|
|
67
71
|
language?: string;
|
|
68
|
-
|
|
69
|
-
}
|
|
72
|
+
};
|
|
70
73
|
|
|
71
74
|
export type ApiNavItem = {
|
|
72
75
|
children: Array<ApiNavItem>;
|
|
@@ -40,11 +40,6 @@ dx-dropdown > dx-button:hover {
|
|
|
40
40
|
--border-color: var(--button-primary-color-hover);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
.document-pickers {
|
|
44
|
-
margin-left: auto;
|
|
45
|
-
margin-right: var(--dx-g-spacing-sm);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
43
|
doc-phase {
|
|
49
44
|
--doc-c-phase-top: calc(
|
|
50
45
|
var(--dx-g-global-header-height) + var(--dx-g-doc-header-height)
|
|
@@ -11,6 +11,10 @@
|
|
|
11
11
|
sidebar-value={sidebarValue}
|
|
12
12
|
onselect={handleSelect}
|
|
13
13
|
use-old-sidebar={useOldSidebar}
|
|
14
|
+
languages={sidebarFooterContent.languages}
|
|
15
|
+
language={sidebarFooterContent.language}
|
|
16
|
+
bail-href={sidebarFooterContent.bailHref}
|
|
17
|
+
bail-label={sidebarFooterContent.bailLabel}
|
|
14
18
|
>
|
|
15
19
|
<doc-phase
|
|
16
20
|
slot="version-banner"
|
|
@@ -20,19 +24,15 @@
|
|
|
20
24
|
dismissible="true"
|
|
21
25
|
ondismissphase={handleDismissVersionBanner}
|
|
22
26
|
></doc-phase>
|
|
23
|
-
<div slot="sidebar-header"
|
|
24
|
-
<
|
|
27
|
+
<div if:false={disableVersion} slot="sidebar-header">
|
|
28
|
+
<doc-version-picker
|
|
25
29
|
data-type="version"
|
|
26
30
|
analytics-event="custEv_ctaLinkClick"
|
|
27
31
|
analytics-payload={ANALYTICS_PAYLOAD}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
>
|
|
32
|
-
<dx-button variant="inline" disabled={disableVersion}>
|
|
33
|
-
{version.releaseVersion}
|
|
34
|
-
</dx-button>
|
|
35
|
-
</dx-dropdown>
|
|
32
|
+
versions={versionOptions}
|
|
33
|
+
selected-version={version}
|
|
34
|
+
latest-version={latestVersion}
|
|
35
|
+
></doc-version-picker>
|
|
36
36
|
</div>
|
|
37
37
|
<doc-breadcrumbs
|
|
38
38
|
if:true={showBreadcrumbs}
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
DocVersion,
|
|
9
9
|
TreeNode,
|
|
10
10
|
Header,
|
|
11
|
+
SiderbarFooter,
|
|
11
12
|
HistoryState,
|
|
12
13
|
PageReference,
|
|
13
14
|
TocMap
|
|
@@ -26,6 +27,12 @@ const PIXEL_PER_CHARACTER_MAP: { [key: string]: number } = {
|
|
|
26
27
|
"ja-jp": 12.5
|
|
27
28
|
};
|
|
28
29
|
|
|
30
|
+
const defaultSidebarFooter: SiderbarFooter = {
|
|
31
|
+
bailHref: "",
|
|
32
|
+
bailLabel: "",
|
|
33
|
+
languages: [],
|
|
34
|
+
language: ""
|
|
35
|
+
};
|
|
29
36
|
export default class DocXmlContent extends LightningElementWithState<{
|
|
30
37
|
isFetchingDocument: boolean;
|
|
31
38
|
isFetchingContent: boolean;
|
|
@@ -64,15 +71,18 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
64
71
|
private docContent = "";
|
|
65
72
|
private language?: DocLanguage | null = null;
|
|
66
73
|
private loaded = false;
|
|
74
|
+
private _pageHeader?: Header;
|
|
67
75
|
private pdfUrl = "";
|
|
68
76
|
private tocMap: TocMap = {};
|
|
69
77
|
private sidebarContent: Array<TreeNode> | null = null;
|
|
70
78
|
private version: DocVersion | null = null;
|
|
71
79
|
private docTitle = "";
|
|
72
80
|
private _pathName = "";
|
|
73
|
-
private _pageHeader?: Header;
|
|
74
81
|
private listenerAttached = false;
|
|
75
82
|
private _enableCoveo?: boolean = false;
|
|
83
|
+
private sidebarFooterContent: SiderbarFooter = { ...defaultSidebarFooter };
|
|
84
|
+
@track
|
|
85
|
+
private latestVersion = false;
|
|
76
86
|
|
|
77
87
|
private searchSyncer = new SearchSyncer({
|
|
78
88
|
callbacks: {
|
|
@@ -214,13 +224,6 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
214
224
|
disconnectedCallback(): void {
|
|
215
225
|
window.removeEventListener("popstate", this.handlePopState);
|
|
216
226
|
this.searchSyncer.dispose();
|
|
217
|
-
if (this.listenerAttached) {
|
|
218
|
-
this.pageHeader.removeEventListener(
|
|
219
|
-
"langchange",
|
|
220
|
-
this.handleLanguageChange
|
|
221
|
-
);
|
|
222
|
-
this.listenerAttached = false;
|
|
223
|
-
}
|
|
224
227
|
}
|
|
225
228
|
|
|
226
229
|
private get languageId(): string | undefined {
|
|
@@ -414,12 +417,8 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
414
417
|
}
|
|
415
418
|
|
|
416
419
|
getReferenceFromUrl(): PageReference {
|
|
417
|
-
const [
|
|
418
|
-
|
|
419
|
-
docId,
|
|
420
|
-
deliverable,
|
|
421
|
-
contentDocumentId
|
|
422
|
-
] = window.location.pathname.substr(1).split("/");
|
|
420
|
+
const [page, docId, deliverable, contentDocumentId] =
|
|
421
|
+
window.location.pathname.substr(1).split("/");
|
|
423
422
|
|
|
424
423
|
const { origin: domain, hash, search } = window.location;
|
|
425
424
|
|
|
@@ -469,7 +468,7 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
469
468
|
this.availableVersions = data.availableVersions;
|
|
470
469
|
this.pdfUrl = data.pdfUrl;
|
|
471
470
|
|
|
472
|
-
this.
|
|
471
|
+
this.updateHeaderAndSidebarFooter();
|
|
473
472
|
|
|
474
473
|
this.buildBreadcrumbs();
|
|
475
474
|
|
|
@@ -480,6 +479,8 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
480
479
|
|
|
481
480
|
if (this.oldVersionInfo) {
|
|
482
481
|
this.showVersionBanner = true;
|
|
482
|
+
} else {
|
|
483
|
+
this.latestVersion = true;
|
|
483
484
|
}
|
|
484
485
|
|
|
485
486
|
if (
|
|
@@ -533,7 +534,7 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
533
534
|
});
|
|
534
535
|
}
|
|
535
536
|
|
|
536
|
-
|
|
537
|
+
updateHeaderAndSidebarFooter(): void {
|
|
537
538
|
if (!this.pageHeader) {
|
|
538
539
|
return;
|
|
539
540
|
}
|
|
@@ -543,20 +544,12 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
543
544
|
}
|
|
544
545
|
|
|
545
546
|
if (this.pdfUrl) {
|
|
546
|
-
this.
|
|
547
|
-
this.
|
|
547
|
+
this.sidebarFooterContent.bailHref = this.pdfUrl;
|
|
548
|
+
this.sidebarFooterContent.bailLabel = "PDF";
|
|
548
549
|
}
|
|
549
550
|
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
"langchange",
|
|
553
|
-
this.handleLanguageChange
|
|
554
|
-
);
|
|
555
|
-
this.listenerAttached = true;
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
this.pageHeader.languages = this.availableLanguages;
|
|
559
|
-
this.pageHeader.language = this.language?.id;
|
|
551
|
+
this.sidebarFooterContent.languages = this.availableLanguages;
|
|
552
|
+
this.sidebarFooterContent.language = this.language?.id;
|
|
560
553
|
|
|
561
554
|
if (this.pageReference) {
|
|
562
555
|
const { docId, deliverable, page } = this.pageReference;
|
|
@@ -581,20 +574,14 @@ export default class DocXmlContent extends LightningElementWithState<{
|
|
|
581
574
|
}
|
|
582
575
|
|
|
583
576
|
private updateSearchInput(searchParam: string): void {
|
|
584
|
-
(
|
|
585
|
-
"doc-content-layout"
|
|
586
|
-
)
|
|
577
|
+
(
|
|
578
|
+
this.template.querySelector("doc-content-layout") as any
|
|
579
|
+
)?.setSidebarInputValue(searchParam);
|
|
587
580
|
}
|
|
588
581
|
|
|
589
582
|
private pageReferenceToString(reference: PageReference): string {
|
|
590
|
-
const {
|
|
591
|
-
|
|
592
|
-
docId,
|
|
593
|
-
deliverable,
|
|
594
|
-
contentDocumentId,
|
|
595
|
-
hash,
|
|
596
|
-
search
|
|
597
|
-
} = reference;
|
|
583
|
+
const { page, docId, deliverable, contentDocumentId, hash, search } =
|
|
584
|
+
reference;
|
|
598
585
|
return `/${page}/${docId}/${deliverable}/${contentDocumentId}${this.normalizeSearch(
|
|
599
586
|
search!
|
|
600
587
|
)}${this.normalizeHash(hash)}`;
|
package/LICENSE
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
Copyright (c) 2020, Salesforce.com, Inc.
|
|
2
|
-
All rights reserved.
|
|
3
|
-
|
|
4
|
-
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
|
5
|
-
|
|
6
|
-
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
|
7
|
-
|
|
8
|
-
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
|
9
|
-
|
|
10
|
-
* Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
11
|
-
|
|
12
|
-
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|