web-documentation 1.0.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/build/deploy.js +71 -0
- package/package.json +336 -0
- package/readme.md +37 -0
- package/source/deploy.ts +721 -0
- package/source/dummyDistributionBundle.zip +0 -0
- package/source/dummyReadme.md +266 -0
- package/source/image/arrowDown.png +0 -0
- package/source/image/blacktocat.png +0 -0
- package/source/image/favicon.png +0 -0
- package/source/image/folderBlue.png +0 -0
- package/source/image/folderGray.png +0 -0
- package/source/index.css +492 -0
- package/source/index.html.ejs +303 -0
- package/source/index.ts +431 -0
- package/source/renderMarkdown.mjs +31 -0
- package/source/test.ts +35 -0
- package/source/type.ts +39 -0
package/source/index.ts
ADDED
|
@@ -0,0 +1,431 @@
|
|
|
1
|
+
// #!/usr/bin/env babel-node
|
|
2
|
+
// -*- coding: utf-8 -*-
|
|
3
|
+
/** @module web-documentation */
|
|
4
|
+
'use strict'
|
|
5
|
+
/* !
|
|
6
|
+
region header
|
|
7
|
+
[Project page](https://github.com/web-documentation)
|
|
8
|
+
|
|
9
|
+
Copyright Torben Sickert (info["~at~"]torben.website) 16.12.2012
|
|
10
|
+
|
|
11
|
+
License
|
|
12
|
+
-------
|
|
13
|
+
|
|
14
|
+
This library written by Torben Sickert stand under a creative commons
|
|
15
|
+
naming 3.0 unported license.
|
|
16
|
+
See https://creativecommons.org/licenses/by/3.0/deed.de
|
|
17
|
+
endregion
|
|
18
|
+
*/
|
|
19
|
+
// region imports
|
|
20
|
+
import {
|
|
21
|
+
camelCaseToDelimited,
|
|
22
|
+
createDomNodes,
|
|
23
|
+
extend,
|
|
24
|
+
format,
|
|
25
|
+
getAll,
|
|
26
|
+
getParents,
|
|
27
|
+
getText,
|
|
28
|
+
globalContext,
|
|
29
|
+
Logger,
|
|
30
|
+
Mapping,
|
|
31
|
+
NOOP,
|
|
32
|
+
wrap
|
|
33
|
+
} from 'clientnode'
|
|
34
|
+
import {func, object} from 'clientnode/property-types'
|
|
35
|
+
import {property} from 'web-component-wrapper/decorator'
|
|
36
|
+
import {WebComponentAPI} from 'web-component-wrapper/type'
|
|
37
|
+
import {Web} from 'web-component-wrapper/Web'
|
|
38
|
+
import {api as websiteUtilitiesAPI} from 'website-utilities'
|
|
39
|
+
import {api as webInternationalizationAPI} from 'web-internationalization'
|
|
40
|
+
|
|
41
|
+
import {DefaultOptions, Options} from './type'
|
|
42
|
+
// endregion
|
|
43
|
+
export const log = new Logger({name: 'web-documentation'})
|
|
44
|
+
// region plugins/classes
|
|
45
|
+
/**
|
|
46
|
+
* This plugin holds all needed methods to extend a whole documentation site.
|
|
47
|
+
* @property _defaultOptions - Options extended by the options given to the
|
|
48
|
+
* initializer method.
|
|
49
|
+
* @property _defaultOptions.selectors - Object with a mapping of needed dom
|
|
50
|
+
* node descriptions to their corresponding selectors.
|
|
51
|
+
* @property _defaultOptions.showExample - Options object to configure code
|
|
52
|
+
* example representation.
|
|
53
|
+
* @property _defaultOptions.showExample.pattern - Regular expression to
|
|
54
|
+
* introduce a code example section.
|
|
55
|
+
* @property _defaultOptions.showExample.domNodeName - Dom node name to
|
|
56
|
+
* indicate a declarative example section.
|
|
57
|
+
* @property _defaultOptions.showExample.htmlWrapper - HTML example wrapper.
|
|
58
|
+
* @property _defaultOptions.section - Configuration object for section
|
|
59
|
+
* switches between the main page and legal notes descriptions.
|
|
60
|
+
* @property options - Finally configured given options.
|
|
61
|
+
*/
|
|
62
|
+
export class WebDocumentation<
|
|
63
|
+
TElement = HTMLElement,
|
|
64
|
+
ExternalProperties extends Mapping<unknown> = Mapping<unknown>,
|
|
65
|
+
InternalProperties extends Mapping<unknown> = Mapping<unknown>
|
|
66
|
+
> extends Web<TElement, ExternalProperties, InternalProperties> {
|
|
67
|
+
static content = `
|
|
68
|
+
<website-utilities
|
|
69
|
+
options="{sectionNames: ['home', 'about-this-website']}"
|
|
70
|
+
>
|
|
71
|
+
<web-internationalization>
|
|
72
|
+
<slot>Please provide a template to transclude.</slot>
|
|
73
|
+
</web-internationalization>
|
|
74
|
+
</website-utilities>
|
|
75
|
+
`
|
|
76
|
+
|
|
77
|
+
static _name = 'WebDocumentation'
|
|
78
|
+
|
|
79
|
+
static _defaultOptions: DefaultOptions = {
|
|
80
|
+
selectors: {
|
|
81
|
+
aboutThisWebsiteLink: 'a[href="#about-this-website"]',
|
|
82
|
+
aboutThisWebsiteSection: '.section__about-this-website',
|
|
83
|
+
|
|
84
|
+
codeWrapper: 'pre',
|
|
85
|
+
code: 'code',
|
|
86
|
+
|
|
87
|
+
headlines:
|
|
88
|
+
'.section__main h1, .section__main h2, ' +
|
|
89
|
+
'.section__main h3, .section__main h4, ' +
|
|
90
|
+
'.section__main h5, .section__main h6',
|
|
91
|
+
tableOfContent: '.doc-toc',
|
|
92
|
+
tableOfContentLinks: '.doc-toc ul li a[href^="#"]'
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
showExample: {
|
|
96
|
+
domNodeName: '#comment',
|
|
97
|
+
htmlWrapper: `
|
|
98
|
+
<div class="show-example-wrapper">
|
|
99
|
+
<h3>
|
|
100
|
+
Example:
|
|
101
|
+
<!--deDE:Beispiel:-->
|
|
102
|
+
<!--frFR:Exemple:-->
|
|
103
|
+
</h3>
|
|
104
|
+
{1}
|
|
105
|
+
</div>
|
|
106
|
+
`,
|
|
107
|
+
pattern: '^ *showExample(: *([^ ]+))? *$'
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
readonly self = WebDocumentation
|
|
112
|
+
// region api properties
|
|
113
|
+
@property({type: object})
|
|
114
|
+
options = {} as Options
|
|
115
|
+
// endregion
|
|
116
|
+
// region domNodes
|
|
117
|
+
aboutThisWebsiteLinkDomNodes: NodeListOf<HTMLElement> | null = null
|
|
118
|
+
aboutThisWebsiteSectionDomNode: HTMLDivElement | null = null
|
|
119
|
+
|
|
120
|
+
codeDomNodes: NodeListOf<HTMLElement> | null = null
|
|
121
|
+
|
|
122
|
+
headlineDomNodes: NodeListOf<HTMLElement> | null = null
|
|
123
|
+
tableOfContentDomNode: HTMLElement | null = null
|
|
124
|
+
tableOfContentLinkDomNodes: NodeListOf<HTMLAnchorElement> | null = null
|
|
125
|
+
// endregion
|
|
126
|
+
// region public
|
|
127
|
+
/// region live-cycle
|
|
128
|
+
/**
|
|
129
|
+
* Defines dynamic getter and setter interface and resolves configuration
|
|
130
|
+
* object. Initializes the map implementation.
|
|
131
|
+
*/
|
|
132
|
+
constructor() {
|
|
133
|
+
super()
|
|
134
|
+
/*
|
|
135
|
+
Babels property declaration transformation overwrites defined
|
|
136
|
+
properties at the end of an implicit constructor. So we have to
|
|
137
|
+
redefined them as long as we want to declare expected component
|
|
138
|
+
interface properties to enable static type checks.
|
|
139
|
+
*/
|
|
140
|
+
this.defineGetterAndSetterInterface()
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Triggered when ever a given attribute has changed and triggers to update
|
|
144
|
+
* configured dom content.
|
|
145
|
+
* @param name - Attribute name which was updates.
|
|
146
|
+
* @param newValue - New updated value.
|
|
147
|
+
*/
|
|
148
|
+
onUpdateAttribute(name: string, newValue: string) {
|
|
149
|
+
super.onUpdateAttribute(name, newValue)
|
|
150
|
+
|
|
151
|
+
if (name === 'options')
|
|
152
|
+
this.options = extend<Options>(
|
|
153
|
+
true,
|
|
154
|
+
{},
|
|
155
|
+
this.self._defaultOptions,
|
|
156
|
+
this.options
|
|
157
|
+
)
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Updates controlled dom elements.
|
|
161
|
+
* @param reason - Why an update has been triggered.
|
|
162
|
+
*/
|
|
163
|
+
async render(reason?: string): Promise<void> {
|
|
164
|
+
await super.render(reason)
|
|
165
|
+
|
|
166
|
+
if (Object.keys(this.options).length === 0)
|
|
167
|
+
this.onUpdateAttribute('options', '{}')
|
|
168
|
+
|
|
169
|
+
this.grabDomNodes()
|
|
170
|
+
|
|
171
|
+
/*
|
|
172
|
+
NOTE: We have to render examples first to avoid having dots in
|
|
173
|
+
example code.
|
|
174
|
+
*/
|
|
175
|
+
this._showExamples()
|
|
176
|
+
|
|
177
|
+
// TODO we may need to delay internationalization until this has been
|
|
178
|
+
// finished rendering
|
|
179
|
+
|
|
180
|
+
this._makeCodeEllipsis()
|
|
181
|
+
|
|
182
|
+
this._generateTableOfContentsLinks()
|
|
183
|
+
}
|
|
184
|
+
/// endregion
|
|
185
|
+
grabDomNodes(): void {
|
|
186
|
+
this.aboutThisWebsiteLinkDomNodes = this.root.querySelectorAll(
|
|
187
|
+
this.options.selectors.aboutThisWebsiteLink
|
|
188
|
+
)
|
|
189
|
+
this.aboutThisWebsiteSectionDomNode = this.root.querySelector(
|
|
190
|
+
this.options.selectors.aboutThisWebsiteSection
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
this.codeDomNodes =
|
|
194
|
+
this.root.querySelectorAll(this.options.selectors.code)
|
|
195
|
+
|
|
196
|
+
this.headlineDomNodes =
|
|
197
|
+
this.root.querySelectorAll(this.options.selectors.headlines)
|
|
198
|
+
this.tableOfContentDomNode =
|
|
199
|
+
this.root.querySelector(this.options.selectors.tableOfContent)
|
|
200
|
+
}
|
|
201
|
+
// endregion
|
|
202
|
+
// region protected methods
|
|
203
|
+
/// region event handler
|
|
204
|
+
/// endregion
|
|
205
|
+
/**
|
|
206
|
+
* Generates a table of contents via creating links referring to headlines.
|
|
207
|
+
*/
|
|
208
|
+
_generateTableOfContentsLinks(): void {
|
|
209
|
+
if (!this.tableOfContentDomNode)
|
|
210
|
+
return
|
|
211
|
+
|
|
212
|
+
let listItems = '<ul>'
|
|
213
|
+
let level = 0
|
|
214
|
+
let firstLevel = 0
|
|
215
|
+
let first = true
|
|
216
|
+
for (const domNode of this.headlineDomNodes ?? []) {
|
|
217
|
+
if (getParents(domNode).some((domNode: Node) =>
|
|
218
|
+
(domNode as Partial<Element>).classList?.contains(
|
|
219
|
+
'show-example-wrapper'
|
|
220
|
+
)
|
|
221
|
+
))
|
|
222
|
+
return
|
|
223
|
+
|
|
224
|
+
const newLevel: number =
|
|
225
|
+
parseInt(domNode.nodeName.replace(/\D/g, ''))
|
|
226
|
+
|
|
227
|
+
if (first)
|
|
228
|
+
firstLevel = newLevel
|
|
229
|
+
|
|
230
|
+
if (newLevel > level)
|
|
231
|
+
listItems += '<ul>'
|
|
232
|
+
else if (newLevel < level)
|
|
233
|
+
listItems += '</ul>'
|
|
234
|
+
|
|
235
|
+
listItems += `
|
|
236
|
+
<li>
|
|
237
|
+
<a href="#${domNode.getAttribute('id') ?? 'unknown'}">
|
|
238
|
+
${domNode.innerText}
|
|
239
|
+
</a>
|
|
240
|
+
</li>
|
|
241
|
+
`
|
|
242
|
+
|
|
243
|
+
level = newLevel
|
|
244
|
+
first = false
|
|
245
|
+
}
|
|
246
|
+
// Close remaining inner lists.
|
|
247
|
+
while (level < firstLevel) {
|
|
248
|
+
listItems += '</ul>'
|
|
249
|
+
level += 1
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
listItems += '</ul>'
|
|
253
|
+
|
|
254
|
+
this.tableOfContentDomNode.append(listItems)
|
|
255
|
+
|
|
256
|
+
this.tableOfContentLinkDomNodes =
|
|
257
|
+
this.tableOfContentDomNode.querySelectorAll<HTMLAnchorElement>('a')
|
|
258
|
+
|
|
259
|
+
this.tableOfContentDomNode.style.display = 'initial'
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* This method makes dotes after code lines which are too long. This
|
|
263
|
+
* prevents line wrapping.
|
|
264
|
+
*/
|
|
265
|
+
_makeCodeEllipsis(): void {
|
|
266
|
+
const lengthLimit = 89 // 79
|
|
267
|
+
|
|
268
|
+
for (const domNode of this.codeDomNodes ?? []) {
|
|
269
|
+
let newContent = ''
|
|
270
|
+
const codeLines: Array<string> = domNode.innerHTML.split('\n')
|
|
271
|
+
|
|
272
|
+
let subIndex = 0
|
|
273
|
+
for (const value of codeLines) {
|
|
274
|
+
/*
|
|
275
|
+
NOTE: Wrap a div object to grantee that $ will accept the
|
|
276
|
+
input.
|
|
277
|
+
*/
|
|
278
|
+
const excess: number =
|
|
279
|
+
getText(createDomNodes(`<div>${value}</div>`)).length -
|
|
280
|
+
lengthLimit
|
|
281
|
+
if (excess > 0)
|
|
282
|
+
newContent += this._replaceExcessWithDots(value, excess)
|
|
283
|
+
else
|
|
284
|
+
newContent += value
|
|
285
|
+
if (subIndex + 1 !== codeLines.length)
|
|
286
|
+
newContent += '\n'
|
|
287
|
+
|
|
288
|
+
subIndex += 1
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
domNode.innerHTML = newContent
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Replaces given html content with a shorter version trimmed by given
|
|
296
|
+
* amount of excess.
|
|
297
|
+
* @param content - String to trim.
|
|
298
|
+
* @param excess - Amount of excess.
|
|
299
|
+
* @returns Returns the trimmed content.
|
|
300
|
+
*/
|
|
301
|
+
_replaceExcessWithDots(content: string, excess: number): string {
|
|
302
|
+
// Add space for ending dots.
|
|
303
|
+
excess += '...'.length
|
|
304
|
+
let newContent = ''
|
|
305
|
+
const contentDomNodes =
|
|
306
|
+
getAll(createDomNodes(`<wrapper>${content}</wrapper>`))
|
|
307
|
+
contentDomNodes.reverse()
|
|
308
|
+
for (const domNode of contentDomNodes) {
|
|
309
|
+
const wrapper = createDomNodes<HTMLElement>('<wrapper><wrapper>')
|
|
310
|
+
wrap(domNode, wrapper)
|
|
311
|
+
|
|
312
|
+
const textContent = domNode.textContent || ''
|
|
313
|
+
|
|
314
|
+
let contentSnippet = wrapper.innerHTML
|
|
315
|
+
if (!contentSnippet)
|
|
316
|
+
contentSnippet = textContent
|
|
317
|
+
|
|
318
|
+
if (excess)
|
|
319
|
+
if (textContent.length < excess) {
|
|
320
|
+
excess -= textContent.length
|
|
321
|
+
contentSnippet = ''
|
|
322
|
+
} else if (textContent.length >= excess) {
|
|
323
|
+
/*
|
|
324
|
+
NOTE: We have to ensure that no HTML tag will be
|
|
325
|
+
shortened: We work on "textContent" property only.
|
|
326
|
+
*/
|
|
327
|
+
domNode.textContent =
|
|
328
|
+
textContent.substring(
|
|
329
|
+
0, textContent.length - excess - 1
|
|
330
|
+
) +
|
|
331
|
+
'...'
|
|
332
|
+
|
|
333
|
+
excess = 0
|
|
334
|
+
|
|
335
|
+
contentSnippet = wrapper.innerHTML
|
|
336
|
+
if (!contentSnippet)
|
|
337
|
+
contentSnippet = domNode.textContent
|
|
338
|
+
}
|
|
339
|
+
newContent = contentSnippet + newContent
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
return newContent
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Shows marked example codes directly in browser.
|
|
346
|
+
*/
|
|
347
|
+
_showExamples(): void {
|
|
348
|
+
for (const domNode of getAll(this.root))
|
|
349
|
+
if (domNode.nodeName === this.options.showExample.domNodeName) {
|
|
350
|
+
const match: null | RegExpMatchArray =
|
|
351
|
+
(domNode.textContent || '').match(
|
|
352
|
+
new RegExp(this.options.showExample.pattern)
|
|
353
|
+
)
|
|
354
|
+
const codeDomNode = domNode.nextSibling as HTMLElement | null
|
|
355
|
+
if (match && codeDomNode) {
|
|
356
|
+
const codeWrapper: HTMLElement | null =
|
|
357
|
+
codeDomNode.querySelector(
|
|
358
|
+
this.options.selectors.codeWrapper
|
|
359
|
+
)
|
|
360
|
+
let code = codeWrapper?.innerText
|
|
361
|
+
|
|
362
|
+
if (!code)
|
|
363
|
+
code = codeDomNode.innerText
|
|
364
|
+
|
|
365
|
+
try {
|
|
366
|
+
let domNode: HTMLElement | string = ''
|
|
367
|
+
if (match.length > 2 && match[2])
|
|
368
|
+
if (
|
|
369
|
+
['javascript', 'javascripts', 'js']
|
|
370
|
+
.includes(match[2].toLowerCase())
|
|
371
|
+
) {
|
|
372
|
+
domNode = (globalContext.document as Document)
|
|
373
|
+
.createElement('script')
|
|
374
|
+
domNode.setAttribute('type', 'text/javascript')
|
|
375
|
+
domNode.innerText = code
|
|
376
|
+
} else if ([
|
|
377
|
+
'css', 'cascadingstylesheet',
|
|
378
|
+
'cascadingstylesheets', 'stylesheet',
|
|
379
|
+
'stylesheets', 'sheet', 'sheets', 'style',
|
|
380
|
+
'styles'
|
|
381
|
+
].includes(match[2].toLowerCase())) {
|
|
382
|
+
domNode = (globalContext.document as Document)
|
|
383
|
+
.createElement('style')
|
|
384
|
+
domNode.setAttribute('type', 'text/css')
|
|
385
|
+
domNode.innerText = code
|
|
386
|
+
} else if (match[2].toLowerCase() === 'hidden')
|
|
387
|
+
domNode = code
|
|
388
|
+
else
|
|
389
|
+
domNode = createDomNodes(format(
|
|
390
|
+
this.options.showExample.htmlWrapper,
|
|
391
|
+
code
|
|
392
|
+
))
|
|
393
|
+
else
|
|
394
|
+
domNode = createDomNodes(format(
|
|
395
|
+
this.options.showExample.htmlWrapper,
|
|
396
|
+
code
|
|
397
|
+
))
|
|
398
|
+
|
|
399
|
+
codeDomNode.after(domNode)
|
|
400
|
+
} catch (error) {
|
|
401
|
+
log.critical(
|
|
402
|
+
`Error while integrating code "${code}":`,
|
|
403
|
+
String(error)
|
|
404
|
+
)
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
this.onExamplesLoaded.call(this)
|
|
411
|
+
}
|
|
412
|
+
// endregion
|
|
413
|
+
}
|
|
414
|
+
// endregion
|
|
415
|
+
export const api: WebComponentAPI<
|
|
416
|
+
HTMLElement, Mapping<unknown>, Mapping<unknown>, typeof Web
|
|
417
|
+
> = {
|
|
418
|
+
component: WebDocumentation,
|
|
419
|
+
register: (
|
|
420
|
+
tagName: string = camelCaseToDelimited(WebDocumentation._name)
|
|
421
|
+
) => {
|
|
422
|
+
websiteUtilitiesAPI.register()
|
|
423
|
+
webInternationalizationAPI.register()
|
|
424
|
+
|
|
425
|
+
customElements.define(tagName, WebDocumentation)
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
export default WebDocumentation
|
|
429
|
+
|
|
430
|
+
if ((globalContext as Mapping<boolean>).AUTO_DEFINE_WEB_DOCUMENTATION)
|
|
431
|
+
api.register()
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import {Marked} from 'marked'
|
|
2
|
+
import {gfmHeadingId} from 'marked-gfm-heading-id'
|
|
3
|
+
import {markedHighlight} from 'marked-highlight'
|
|
4
|
+
import highlightJSModule from 'highlight.js'
|
|
5
|
+
import {markedXhtml} from 'marked-xhtml'
|
|
6
|
+
|
|
7
|
+
const {getLanguage, highlight} = highlightJSModule
|
|
8
|
+
|
|
9
|
+
const marked = new Marked(
|
|
10
|
+
markedHighlight({
|
|
11
|
+
/*
|
|
12
|
+
A string to prefix the className in a <code> block. Useful for
|
|
13
|
+
syntax highlighting.
|
|
14
|
+
*/
|
|
15
|
+
langPrefix: 'language-',
|
|
16
|
+
highlight: (code, lang, info) =>
|
|
17
|
+
highlight(
|
|
18
|
+
code, {language: getLanguage(lang) ? lang : 'plaintext'}
|
|
19
|
+
).value
|
|
20
|
+
})
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
export default (options) => {
|
|
24
|
+
marked.setOptions(options)
|
|
25
|
+
// Include an id attribute when emitting headings (h1, h2, h3, etc).
|
|
26
|
+
marked.use(gfmHeadingId({prefix: 'doc-'}))
|
|
27
|
+
// Favors self-closing xhtml tags.
|
|
28
|
+
marked.use(markedXhtml())
|
|
29
|
+
|
|
30
|
+
return marked.parse
|
|
31
|
+
}
|
package/source/test.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// #!/usr/bin/env babel-node
|
|
2
|
+
// -*- coding: utf-8 -*-
|
|
3
|
+
'use strict'
|
|
4
|
+
/* !
|
|
5
|
+
region header
|
|
6
|
+
Copyright Torben Sickert (info["~at~"]torben.website) 16.12.2012
|
|
7
|
+
|
|
8
|
+
License
|
|
9
|
+
-------
|
|
10
|
+
|
|
11
|
+
This library written by Torben Sickert stand under a creative commons
|
|
12
|
+
naming 3.0 unported license.
|
|
13
|
+
See https://creativecommons.org/licenses/by/3.0/deed.de
|
|
14
|
+
endregion
|
|
15
|
+
*/
|
|
16
|
+
// region imports
|
|
17
|
+
import {beforeAll, describe, expect, test} from '@jest/globals'
|
|
18
|
+
import '@webcomponents/webcomponentsjs/custom-elements-es5-adapter'
|
|
19
|
+
|
|
20
|
+
import WebDocumentation, {api} from './index'
|
|
21
|
+
// endregion
|
|
22
|
+
describe('WebDocumentation', () => {
|
|
23
|
+
let root: WebDocumentation
|
|
24
|
+
|
|
25
|
+
beforeAll(() => {
|
|
26
|
+
api.register()
|
|
27
|
+
root = document.createElement('web-documentation') as WebDocumentation
|
|
28
|
+
document.body.appendChild(root)
|
|
29
|
+
})
|
|
30
|
+
// region tests
|
|
31
|
+
test('should be defined', () => {
|
|
32
|
+
expect(root).toBeDefined()
|
|
33
|
+
})
|
|
34
|
+
// endregion
|
|
35
|
+
})
|
package/source/type.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
// -*- coding: utf-8 -*-
|
|
2
|
+
/** @module type */
|
|
3
|
+
'use strict'
|
|
4
|
+
/* !
|
|
5
|
+
region header
|
|
6
|
+
[Project page](https://torben.website/website-utilities)
|
|
7
|
+
|
|
8
|
+
Copyright Torben Sickert (info["~at~"]torben.website) 16.12.2012
|
|
9
|
+
|
|
10
|
+
License
|
|
11
|
+
-------
|
|
12
|
+
|
|
13
|
+
This library written by Torben Sickert stand under a creative commons
|
|
14
|
+
naming 3.0 unported license.
|
|
15
|
+
See https://creativecommons.org/licenses/by/3.0/deed.de
|
|
16
|
+
endregion
|
|
17
|
+
*/
|
|
18
|
+
// region exports
|
|
19
|
+
export interface DefaultOptions {
|
|
20
|
+
selectors: {
|
|
21
|
+
aboutThisWebsiteLink: string
|
|
22
|
+
aboutThisWebsiteSection: string
|
|
23
|
+
|
|
24
|
+
codeWrapper: string
|
|
25
|
+
code: string
|
|
26
|
+
|
|
27
|
+
headlines: string
|
|
28
|
+
tableOfContent: string
|
|
29
|
+
tableOfContentLinks: string
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
showExample: {
|
|
33
|
+
domNodeName: string
|
|
34
|
+
htmlWrapper: string
|
|
35
|
+
pattern: string
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
export type Options = DefaultOptions
|
|
39
|
+
// endregion
|