@dosgato/templating 1.1.15 → 1.1.16

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.
@@ -18,7 +18,7 @@ export interface ValidationFeedback {
18
18
  * API to make sure it hasn't been used already.
19
19
  */
20
20
  export interface PageExtras<DataType = PageData> {
21
- /** A function for executing a graphql query to acquire more information than is already at hand. */
21
+ /** A function for executing a graphql query to acquire more information than is already at hand. Queries are executed by the system user, so be careful with it. */
22
22
  query: GraphQLQueryFn;
23
23
  /** The site id in which the page lives or is being created. Null if we are validating creation of a site. */
24
24
  siteId?: string;
@@ -331,10 +331,3 @@ export type AnyMigration = ComponentMigration | PageMigration | DataMigration;
331
331
  export type LinkGatheringFn<DataType> = (data: DataType) => (LinkDefinition | string | undefined)[];
332
332
  export type FulltextGatheringFn<DataType> = (data: DataType) => (string | undefined)[];
333
333
  export type GraphQLQueryFn = <T>(query: string, variables?: any) => Promise<T>;
334
- /**
335
- * This function is used by API template definitions to help them identify all the searchable
336
- * words in a large block of text and return them for indexing.
337
- */
338
- export declare function getKeywords(text?: string, options?: {
339
- stopwords?: boolean;
340
- }): string[];
@@ -1,21 +1,6 @@
1
- import { stopwordSet } from './stopwords.js';
2
1
  export var ValidationMessageType;
3
2
  (function (ValidationMessageType) {
4
3
  ValidationMessageType["ERROR"] = "error";
5
4
  ValidationMessageType["WARNING"] = "warning";
6
5
  ValidationMessageType["SUCCESS"] = "success";
7
6
  })(ValidationMessageType || (ValidationMessageType = {}));
8
- /**
9
- * This function is used by API template definitions to help them identify all the searchable
10
- * words in a large block of text and return them for indexing.
11
- */
12
- export function getKeywords(text, options) {
13
- if (!text)
14
- return [];
15
- return Array.from(new Set(text
16
- .normalize('NFD').replace(/\p{Diacritic}/gu, '')
17
- .toLocaleLowerCase()
18
- .split(/[^\w-]+/)
19
- .flatMap(word => word.includes('-') ? word.split('-').concat(word.replace('-', '')) : [word])
20
- .filter(word => word.length > 2 && (options?.stopwords === false || !stopwordSet.has(word)) && isNaN(Number(word)))));
21
- }
package/dist/component.js CHANGED
@@ -9,6 +9,44 @@ function defaultWrap(info) { return info.output; }
9
9
  * parent and child components linked.
10
10
  */
11
11
  export class Component extends ResourceProvider {
12
+ /**
13
+ * Provide this when you create a template to identify what you are defining.
14
+ */
15
+ static templateKey;
16
+ /**
17
+ * The rendering server will provide an instance of the APIClient interface so that
18
+ * you can run any API GraphQL query you like in your `fetch` function. There are also
19
+ * some useful methods there like processRich to help you convert links in rich text
20
+ * strings.
21
+ *
22
+ * Do NOT mutate data received from the API as it may be cached and given to other
23
+ * Component instances that run the same type of query.
24
+ */
25
+ api;
26
+ /**
27
+ * This property will be set during page render and you may refer to it at any time to
28
+ * determine whether you are doing your work in edit mode or regular rendering mode.
29
+ * The editBar and newBar methods will automatically use it to blank out the editing UI.
30
+ */
31
+ editMode;
32
+ /**
33
+ * The extension of the variation currently being rendered.
34
+ *
35
+ * See 'renderVariation' and 'variationsToFetch' for more discussion of variations.
36
+ */
37
+ extension;
38
+ /**
39
+ * When hydrating an inherited component, the renderer will set this to the id of the page it
40
+ * came from. You may use this information in any of the phases to alter your behavior if needed.
41
+ *
42
+ * For instance, you may decide that your fetch function needs some extra information from the
43
+ * originating page instead of the page you're being inherited into (your `this.page` will
44
+ * be the page currently being rendered, NOT the page the inheritable component came from).
45
+ *
46
+ * This property is also used to alter the edit bar. Inherited components may never be edited
47
+ * except on their original page, so the edit bar will render with a link to the original page.
48
+ */
49
+ inheritedFrom;
12
50
  /**
13
51
  * The first phase of rendering a component is the fetch phase. Each component may
14
52
  * provide a fetch method that looks up data it needs from external sources. This step
@@ -51,6 +89,17 @@ export class Component extends ResourceProvider {
51
89
  * '.js.map', you should receive 'js.map'.
52
90
  */
53
91
  shouldFetchVariation(extension) { return extension === 'html'; }
92
+ /**
93
+ * Some components may be inheritable to subpages within the same site. For instance, a site's
94
+ * social media links may appear on every page's footer. To accomplish this in your template,
95
+ * you need to fetch ancestor page data in your fetch phase, identify the component data you want
96
+ * to inherit, and then call this function within your fetch to let the renderer know it needs to
97
+ * process those components (hydrate them, call their fetch functions, and include them in the render).
98
+ *
99
+ * The inherited components will be added to the appropriate area's array in the renderedAreas
100
+ * parameter of your render function.
101
+ */
102
+ registerInherited;
54
103
  /**
55
104
  * Inherit components from another page with matching area
56
105
  *
@@ -85,6 +134,44 @@ export class Component extends ResourceProvider {
85
134
  setContext(renderCtxFromParent, areaName) {
86
135
  return renderCtxFromParent;
87
136
  }
137
+ /**
138
+ * This function will be provided by the rendering server and should be used inside your fetch
139
+ * method to prepare editor-provided HTML for later rendering. It will do things like find and
140
+ * resolve link definitions in the internal dosgato format.
141
+ */
142
+ fetchRichText;
143
+ /**
144
+ * This function will be provided by the rendering server and should be used during the render
145
+ * phase to clean up editor-provided HTML. It will do things like clean up tags that were accidentally
146
+ * left open to protect overall page integrity, and fix header levels for accessibility.
147
+ *
148
+ * For instance, an editor supplies a title to be placed above some rich editor content. The
149
+ * title uses an <h2>, so the headers inside the rich editor content should start at <h3> and
150
+ * should not use <h1> or <h2>.
151
+ *
152
+ * Setting headerLevel: 3 instructs the renderRichText function to analyze and rebalance the header
153
+ * structure of the content so that if it had an h2, it woud be replaced with an h3. Additionally,
154
+ * if the user skipped a header level (a WCAG violation) that situation will be repaired as well
155
+ * as possible.
156
+ *
157
+ * If you do not provide a headerLevel, the one from `this.renderCtx` will be used. However, if you
158
+ * provide a non-blank value for `advanceHeader`, the headerLevel from `this.renderCtx` + 1 will be used.
159
+ *
160
+ * This way you can easily render a piece of rich text in a component that has an optional title:
161
+ *
162
+ * this.renderRichText(this.data.richtext, { advanceHeader: this.data.title })
163
+ *
164
+ * If this.data.title is non-blank, the rich text will be balanced below it, but if it is blank,
165
+ * it will be balanced at the level the title would have had.
166
+ */
167
+ renderRichText;
168
+ /**
169
+ * When we give editors the ability to enter raw HTML, we still need to minimally process it to
170
+ * protect the rest of the page from unclosed tags and other syntax problems, but we don't want
171
+ * to muck around with headers or links, so this function will be provided by the render server
172
+ * and will only do the parsing and reconstruction part
173
+ */
174
+ renderRawHTML;
88
175
  /**
89
176
  * If you are rendering a variation for a component that has areas and children,
90
177
  * you can call Component.renderVariation(extension, this.renderedAreas) to help you easily
@@ -207,6 +294,17 @@ export class Component extends ResourceProvider {
207
294
  * CSS class
208
295
  */
209
296
  editClass() { return undefined; }
297
+ /**
298
+ * Override with `true` to indicate that this template never accepts data from editors
299
+ *
300
+ * Its edit bar will not have a pencil icon.
301
+ */
302
+ noData = false;
303
+ /**
304
+ * Override with `true` to indicate that this template renders its own edit bar
305
+ * so that the parent component will avoid rendering it
306
+ */
307
+ renderIncludesEditBar = false;
210
308
  /**
211
309
  * Components may override this function to give their new bars a custom
212
310
  * label
@@ -227,10 +325,10 @@ export class Component extends ResourceProvider {
227
325
  */
228
326
  editBar(opts = {}) {
229
327
  const options = { ...opts };
230
- options.label ?? (options.label = this.editLabel() ?? this.autoLabel);
328
+ options.label ??= this.editLabel() ?? this.autoLabel;
231
329
  options.extraClass = [options.extraClass, this.editClass()].filter(isNotBlank).join(' ');
232
- options.editMode ?? (options.editMode = this.editMode);
233
- options.inheritedFrom ?? (options.inheritedFrom = this.inheritedFrom);
330
+ options.editMode ??= this.editMode;
331
+ options.inheritedFrom ??= this.inheritedFrom;
234
332
  options.hideEdit = this.noData || options.hideEdit;
235
333
  return Component.editBar(this.path, options);
236
334
  }
@@ -241,29 +339,21 @@ export class Component extends ResourceProvider {
241
339
  */
242
340
  newBar(areaName, opts = {}) {
243
341
  const options = { ...opts };
244
- options.label ?? (options.label = this.newLabel(areaName) ?? (this.areas.size > 1 ? `Add ${areaName} Content` : `Add ${this.autoLabel} Content`));
342
+ options.label ??= this.newLabel(areaName) ?? (this.areas.size > 1 ? `Add ${areaName} Content` : `Add ${this.autoLabel} Content`);
245
343
  options.extraClass = [options.extraClass, this.newClass(areaName)].filter(isNotBlank).join(' ');
246
- options.editMode ?? (options.editMode = this.editMode);
344
+ options.editMode ??= this.editMode;
247
345
  return Component.newBar([this.path, 'areas', areaName].filter(isNotBlank).join('.'), options);
248
346
  }
347
+ /**
348
+ * These functions will be provided by the rendering server to assist in the
349
+ * rendering process.
350
+ */
351
+ static editBar;
352
+ static newBar;
249
353
  // the constructor is part of the recursive hydration mechanism: constructing
250
354
  // a Component will also construct/hydrate all its child components
251
355
  constructor(data, path, parent, editMode, extension) {
252
356
  super();
253
- /**
254
- * Override with `true` to indicate that this template never accepts data from editors
255
- *
256
- * Its edit bar will not have a pencil icon.
257
- */
258
- this.noData = false;
259
- /**
260
- * Override with `true` to indicate that this template renders its own edit bar
261
- * so that the parent component will avoid rendering it
262
- */
263
- this.renderIncludesEditBar = false;
264
- // Properties provided during the rendering process. You do not have to provide these when
265
- // building a template, but you can use them in the functions you do provide
266
- this.areas = new Map(); // a Map of area names and the array of hydrated components in each
267
357
  this.editMode = editMode;
268
358
  this.extension = extension;
269
359
  this.parent = parent;
@@ -278,6 +368,35 @@ export class Component extends ResourceProvider {
278
368
  throw new Error('Hydration failed, could not map component back to its page.');
279
369
  this.page = tmpParent;
280
370
  }
371
+ // Properties provided during the rendering process. You do not have to provide these when
372
+ // building a template, but you can use them in the functions you do provide
373
+ areas = new Map(); // a Map of area names and the array of hydrated components in each
374
+ data; // the component data
375
+ fetched; // where we store the output from your `fetched` method
376
+ renderCtx; // where we store the output from your `setContext` method
377
+ path; // the dot-separated path to this component within the page data
378
+ parent; // the hydrated parent component of this component
379
+ page; // the hydrated page component this component lives in
380
+ renderedAreas; // render server sets this just before `render` is called
381
+ hadError; // will be true if the fetch encountered an error, render will be skipped
382
+ autoLabel; // the rendering server will fetch template names and fill this
383
+ reqHeaders; // the HTTP headers of the request being processed, in case it would change the render
384
+ reqQuery; // the URL of the request being processed, so you can access the query or do routing work
385
+ // the index of this component in its area, after inheritance has occurred
386
+ // because we are waiting for inheritance, this will be undefined until the render phase
387
+ // it's also undefined for page templates but I'm intentionally making it non-optional
388
+ // because it would be non-sensical to try to use in a page template anyway
389
+ indexInArea;
390
+ /**
391
+ * the full array of components in the same area as this component, including self
392
+ *
393
+ * empty for page component
394
+ */
395
+ siblings;
396
+ /** the component before this one inside the area, null if this component is first */
397
+ prevSibling;
398
+ /** the component after this one inside the area, null if this component is last */
399
+ nextSibling;
281
400
  /**
282
401
  * For logging errors during rendering without crashing the render. If your fetch, setContext,
283
402
  * render, or renderVariation functions throw, the error will be logged but the page render will
@@ -293,6 +412,15 @@ export class Component extends ResourceProvider {
293
412
  }
294
413
  }
295
414
  export class Page extends Component {
415
+ /**
416
+ * The page id in case you need to pass it to the API, e.g. this.api.getRootPage(this.id)
417
+ * in a page template or this.api.getRootPage(this.page.id) in a component template.
418
+ */
419
+ id;
420
+ /**
421
+ * Other data we've already collected about the page being rendered, in case it's needed.
422
+ */
423
+ pageInfo;
296
424
  /**
297
425
  * A convenience to get the page title.
298
426
  *
@@ -301,6 +429,43 @@ export class Page extends Component {
301
429
  get title() {
302
430
  return this.pageInfo.data.title ?? titleCase(this.pageInfo.name);
303
431
  }
432
+ /**
433
+ * This will be filled by the rendering server. The template properties are described
434
+ * over in apitemplate.ts in the comment for APIPageTemplate.templateProperties.
435
+ *
436
+ * The properties will appear in the GraphQL API and the rendering server will automatically
437
+ * download them and provide them here so all you need to do as a template developer is
438
+ * reference the values in your fetch/setContext/render functions.
439
+ */
440
+ templateProperties;
441
+ /**
442
+ * This is a bunch of javascript and CSS and meta tags managed by the DosGato engine. It will
443
+ * be filled by the rendering server and your render function for your page template
444
+ * should place include it in the <head> element
445
+ */
446
+ headContent;
447
+ /**
448
+ * This method will be provided to page templates by the render server. You may call it
449
+ * at any time during fetch, context, or render, to set an HTTP header on the response
450
+ */
451
+ addHeader;
452
+ /**
453
+ * This method will be provided to page templates by the render server. You may call it to set
454
+ * the HTTP response status at any time during the fetch, context, or render.
455
+ */
456
+ setStatus;
457
+ /**
458
+ * URL for the currently rendering page
459
+ *
460
+ * The URL currently being rendered. For instance, if we are in edit mode it would begin
461
+ * with /.edit/ or in preview mode, /.preview/. Useful for referencing variations of the
462
+ * current page.
463
+ *
464
+ * Does not include hash or querystring.
465
+ *
466
+ * Also see `variationUrl` below.
467
+ */
468
+ url;
304
469
  /**
305
470
  * Get a URL for the current page with a different extension
306
471
  */
package/dist/index.d.ts CHANGED
@@ -3,5 +3,4 @@ export * from './component.js';
3
3
  export * from './links.js';
4
4
  export * from './provider.js';
5
5
  export * from './render.js';
6
- export * from './stopwords.js';
7
6
  export * from './uitemplate.js';
package/dist/index.js CHANGED
@@ -3,5 +3,4 @@ export * from './component.js';
3
3
  export * from './links.js';
4
4
  export * from './provider.js';
5
5
  export * from './render.js';
6
- export * from './stopwords.js';
7
6
  export * from './uitemplate.js';
package/dist/provider.js CHANGED
@@ -9,80 +9,80 @@
9
9
  * If you do this, don't forget to register the provider along with your templates!
10
10
  */
11
11
  export class ResourceProvider {
12
+ /**
13
+ * Each template should provide a map of CSS blocks where the map key is the unique name for
14
+ * the CSS and the value is the CSS itself. For instance, if a template needs CSS from a
15
+ * standard library like jquery-ui, it could include the full CSS for jquery-ui with 'jquery-ui'
16
+ * as the key. Other templates that depend on jquery-ui would also provide the CSS, but
17
+ * a page with both components would only include the CSS once, because they both called it
18
+ * 'jquery-ui'.
19
+ *
20
+ * A version string (e.g. '1.2.5') may be provided for each block. The block with the highest
21
+ * version number of any given name will be used. Other versions of that name will be ignored.
22
+ *
23
+ * For convenience you can either provide the `css` property with the CSS as a string, or the
24
+ * `path` property with the full server path (NOT URL) to a CSS file (node's __dirname function will
25
+ * help you determine it). You MUST provide one or the other.
26
+ *
27
+ * You may also set `async` to true if a css block is not needed for the initial render of
28
+ * the page. For instance, if your component has a modal that the user can trigger, you can
29
+ * defer the CSS for that modal since it will not be needed until the page has gone interactive
30
+ * and the user has clicked something.
31
+ */
32
+ static cssBlocks = new Map();
33
+ /**
34
+ * A template can provide SASS mixins and functions for use by other SASS-based CSS
35
+ * blocks.
36
+ *
37
+ * These includes can be utilized by other SASS with the SASS `@use` and `@include`
38
+ * commands, e.g.
39
+ * ```
40
+ * @use 'my-mixin-name' as mx;
41
+ * .someclass { @include mx.somemixin(); }
42
+ * ```
43
+ * In this case `my-mixin-name` is the key used for this Map.
44
+ */
45
+ static scssIncludes = new Map();
46
+ /**
47
+ * Same as cssBlocks() but for javascript.
48
+ *
49
+ * In this case `async` is much more useful, as most javascript is interactive and could run
50
+ * after the page renders. Any code that adds event observers or the like should be marked with
51
+ * async to improve the initial render time.
52
+ */
53
+ static jsBlocks = new Map();
54
+ /**
55
+ * If your template needs to serve any files, like fonts or images, you can provide
56
+ * a filesystem path in this static property and the files will be served by the rendering
57
+ * server. Use the provided `webpaths` map to obtain the proper resource URLs. They will be
58
+ * available as soon as your template has been registered to the rendering server's templateRegistry.
59
+ *
60
+ * The map name you pick should be globally unique and only collide with other templates as
61
+ * intended. For instance, the fontawesome font only needs to be provided once, even though
62
+ * several templates might depend on it. Setting the name as 'fontawesome5' on all three
63
+ * templates would ensure that the file would only be served once. Including the major version
64
+ * number is a good idea only if the major versions can coexist.
65
+ *
66
+ * Include a version number if applicable for the file you've included with your source. If
67
+ * multiple templates have a common file, the one that provides the highest version number will
68
+ * have its file served, while the others will be ignored.
69
+ *
70
+ * DO NOT change the mime type without changing the name. Other templates could end up with
71
+ * the wrong file extension.
72
+ */
73
+ static files = new Map();
74
+ /**
75
+ * Template code will need to generate HTML and CSS that points at the static files
76
+ * provided above. In order to do so, we need information from the template registry (since
77
+ * we have to deduplicate with other registered templates at startup time, and the structure
78
+ * of the webpath in general is the render server's concern).
79
+ *
80
+ * In order to avoid an ES6 dependency on the registry, we will have the registry write
81
+ * back to this map as templates are registered.
82
+ *
83
+ * Now when a template needs a web path to a resource to put into its HTML, it can do
84
+ * `<img src="${TemplateClass.webpath('keyname')}">`
85
+ */
86
+ static webpaths = new Map();
12
87
  static webpath(name) { return this.webpaths.get(name); }
13
88
  }
14
- /**
15
- * Each template should provide a map of CSS blocks where the map key is the unique name for
16
- * the CSS and the value is the CSS itself. For instance, if a template needs CSS from a
17
- * standard library like jquery-ui, it could include the full CSS for jquery-ui with 'jquery-ui'
18
- * as the key. Other templates that depend on jquery-ui would also provide the CSS, but
19
- * a page with both components would only include the CSS once, because they both called it
20
- * 'jquery-ui'.
21
- *
22
- * A version string (e.g. '1.2.5') may be provided for each block. The block with the highest
23
- * version number of any given name will be used. Other versions of that name will be ignored.
24
- *
25
- * For convenience you can either provide the `css` property with the CSS as a string, or the
26
- * `path` property with the full server path (NOT URL) to a CSS file (node's __dirname function will
27
- * help you determine it). You MUST provide one or the other.
28
- *
29
- * You may also set `async` to true if a css block is not needed for the initial render of
30
- * the page. For instance, if your component has a modal that the user can trigger, you can
31
- * defer the CSS for that modal since it will not be needed until the page has gone interactive
32
- * and the user has clicked something.
33
- */
34
- ResourceProvider.cssBlocks = new Map();
35
- /**
36
- * A template can provide SASS mixins and functions for use by other SASS-based CSS
37
- * blocks.
38
- *
39
- * These includes can be utilized by other SASS with the SASS `@use` and `@include`
40
- * commands, e.g.
41
- * ```
42
- * @use 'my-mixin-name' as mx;
43
- * .someclass { @include mx.somemixin(); }
44
- * ```
45
- * In this case `my-mixin-name` is the key used for this Map.
46
- */
47
- ResourceProvider.scssIncludes = new Map();
48
- /**
49
- * Same as cssBlocks() but for javascript.
50
- *
51
- * In this case `async` is much more useful, as most javascript is interactive and could run
52
- * after the page renders. Any code that adds event observers or the like should be marked with
53
- * async to improve the initial render time.
54
- */
55
- ResourceProvider.jsBlocks = new Map();
56
- /**
57
- * If your template needs to serve any files, like fonts or images, you can provide
58
- * a filesystem path in this static property and the files will be served by the rendering
59
- * server. Use the provided `webpaths` map to obtain the proper resource URLs. They will be
60
- * available as soon as your template has been registered to the rendering server's templateRegistry.
61
- *
62
- * The map name you pick should be globally unique and only collide with other templates as
63
- * intended. For instance, the fontawesome font only needs to be provided once, even though
64
- * several templates might depend on it. Setting the name as 'fontawesome5' on all three
65
- * templates would ensure that the file would only be served once. Including the major version
66
- * number is a good idea only if the major versions can coexist.
67
- *
68
- * Include a version number if applicable for the file you've included with your source. If
69
- * multiple templates have a common file, the one that provides the highest version number will
70
- * have its file served, while the others will be ignored.
71
- *
72
- * DO NOT change the mime type without changing the name. Other templates could end up with
73
- * the wrong file extension.
74
- */
75
- ResourceProvider.files = new Map();
76
- /**
77
- * Template code will need to generate HTML and CSS that points at the static files
78
- * provided above. In order to do so, we need information from the template registry (since
79
- * we have to deduplicate with other registered templates at startup time, and the structure
80
- * of the webpath in general is the render server's concern).
81
- *
82
- * In order to avoid an ES6 dependency on the registry, we will have the registry write
83
- * back to this map as templates are registered.
84
- *
85
- * Now when a template needs a web path to a resource to put into its HTML, it can do
86
- * `<img src="${TemplateClass.webpath('keyname')}">`
87
- */
88
- ResourceProvider.webpaths = new Map();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dosgato/templating",
3
- "version": "1.1.15",
3
+ "version": "1.1.16",
4
4
  "description": "A library to support building templates for dosgato CMS.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -1,2 +0,0 @@
1
- export declare const stopwords: Record<string, boolean>;
2
- export declare const stopwordSet: Set<string>;
package/dist/stopwords.js DELETED
@@ -1,154 +0,0 @@
1
- export const stopwords = {
2
- myself: true,
3
- our: true,
4
- ours: true,
5
- ourselves: true,
6
- you: true,
7
- your: true,
8
- yours: true,
9
- yourself: true,
10
- yourselves: true,
11
- him: true,
12
- his: true,
13
- himself: true,
14
- she: true,
15
- her: true,
16
- hers: true,
17
- herself: true,
18
- its: true,
19
- itself: true,
20
- they: true,
21
- them: true,
22
- their: true,
23
- theirs: true,
24
- themselves: true,
25
- what: true,
26
- which: true,
27
- who: true,
28
- whom: true,
29
- this: true,
30
- that: true,
31
- these: true,
32
- those: true,
33
- are: true,
34
- was: true,
35
- were: true,
36
- been: true,
37
- being: true,
38
- have: true,
39
- has: true,
40
- had: true,
41
- having: true,
42
- does: true,
43
- did: true,
44
- doing: true,
45
- the: true,
46
- and: true,
47
- but: true,
48
- because: true,
49
- until: true,
50
- while: true,
51
- for: true,
52
- with: true,
53
- about: true,
54
- against: true,
55
- between: true,
56
- into: true,
57
- through: true,
58
- during: true,
59
- before: true,
60
- after: true,
61
- above: true,
62
- below: true,
63
- from: true,
64
- down: true,
65
- out: true,
66
- off: true,
67
- over: true,
68
- under: true,
69
- again: true,
70
- further: true,
71
- then: true,
72
- once: true,
73
- here: true,
74
- there: true,
75
- when: true,
76
- where: true,
77
- why: true,
78
- how: true,
79
- all: true,
80
- any: true,
81
- both: true,
82
- each: true,
83
- few: true,
84
- more: true,
85
- most: true,
86
- other: true,
87
- some: true,
88
- such: true,
89
- nor: true,
90
- not: true,
91
- only: true,
92
- own: true,
93
- same: true,
94
- than: true,
95
- too: true,
96
- very: true,
97
- can: true,
98
- will: true,
99
- just: true,
100
- don: true,
101
- should: true,
102
- now: true,
103
- // HTML
104
- div: true,
105
- span: true,
106
- img: true,
107
- abbr: true,
108
- area: true,
109
- main: true,
110
- aside: true,
111
- blockquote: true,
112
- button: true,
113
- caption: true,
114
- code: true,
115
- del: true,
116
- strong: true,
117
- font: true,
118
- embed: true,
119
- fieldset: true,
120
- form: true,
121
- figure: true,
122
- iframe: true,
123
- label: true,
124
- input: true,
125
- script: true,
126
- nav: true,
127
- select: true,
128
- option: true,
129
- picture: true,
130
- pre: true,
131
- small: true,
132
- style: true,
133
- svg: true,
134
- sub: true,
135
- table: true,
136
- tbody: true,
137
- href: true,
138
- src: true,
139
- srcset: true,
140
- class: true,
141
- textarea: true,
142
- title: true,
143
- onclick: true,
144
- www: true,
145
- com: true,
146
- // LinkDefinition
147
- siteId: true,
148
- path: true,
149
- type: true,
150
- assetId: true,
151
- linkId: true,
152
- url: true
153
- };
154
- export const stopwordSet = new Set(Object.keys(stopwords));