als-layout 5.2.0 → 6.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/docs/0-change-log.md +8 -35
- package/docs/1-basic-usage.md +0 -10
- package/docs/4-res-and-status.md +10 -0
- package/docs/{4-api.md → 5-api.md} +13 -4
- package/lib/elements/index.js +38 -0
- package/lib/elements/keywords.js +19 -0
- package/lib/elements/link.js +13 -0
- package/lib/elements/meta.js +12 -0
- package/lib/elements/url.js +18 -0
- package/lib/layout.js +26 -96
- package/package.json +4 -4
- package/readme.md +32 -50
- package/{build-readme.js → scripts/build-readme.js} +2 -2
- package/tests/integrative.test.js +1 -7
- package/lib/onload.js +0 -11
- /package/lib/{script.js → elements/script.js} +0 -0
- /package/lib/{style.js → elements/style.js} +0 -0
package/docs/0-change-log.md
CHANGED
|
@@ -1,37 +1,10 @@
|
|
|
1
|
-
## Change Log
|
|
2
|
-
* V5.2.0
|
|
3
|
-
* options object on clone, cloned too (remove the reference and deep cloning the object)
|
|
4
|
-
* V5.1.0
|
|
5
|
-
* status and end methods removed
|
|
6
|
-
* status and end methods added to als-view
|
|
7
|
-
* V5.0.0
|
|
8
|
-
* constructor changed
|
|
9
|
-
* options object parameter instead separated parameters
|
|
10
|
-
* options.logger
|
|
11
|
-
* bugs fixed
|
|
12
|
-
* some refactoring
|
|
13
|
-
* minifiying error catching
|
|
14
|
-
* status and end methods added
|
|
15
|
-
* V4.2.0
|
|
16
|
-
* link method changed
|
|
17
|
-
* `link(href, attributes = { rel: "stylesheet", type: "text/css" })`
|
|
18
|
-
* no version method
|
|
19
|
-
* no version parameter in image, link,script
|
|
20
|
-
* script
|
|
21
|
-
* script in footer added one after other in right order
|
|
1
|
+
## Change Log for V6
|
|
22
2
|
|
|
23
|
-
|
|
24
|
-
* Render removed
|
|
25
|
-
|
|
26
|
-
* V4.0.0
|
|
27
|
-
* All code rebuilded and refactored
|
|
28
|
-
* No als-simple-css for style
|
|
29
|
-
* No charset method
|
|
30
|
-
* minifying for style and inner scripts
|
|
31
|
-
* updated render version
|
|
32
|
-
* render as element's method instead layout's method
|
|
33
|
-
|
|
34
|
-
* V3.0.0
|
|
35
|
-
* render switched to als-render
|
|
36
|
-
* updated bug with meta tags after body
|
|
3
|
+
The code refactored.
|
|
37
4
|
|
|
5
|
+
### Removed
|
|
6
|
+
* no deepclone for options, using { ...Layout.options, ...options } instead
|
|
7
|
+
* no onload method
|
|
8
|
+
### Added
|
|
9
|
+
* status
|
|
10
|
+
* end(res)
|
package/docs/1-basic-usage.md
CHANGED
|
@@ -35,13 +35,3 @@ layout.rawHtml // raw HTML of the document
|
|
|
35
35
|
layout.clone // creates a new layout object clone for current object
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
### onload
|
|
39
|
-
|
|
40
|
-
By adding onload attribute, you can run scripts for each element after dom content has loaded.
|
|
41
|
-
|
|
42
|
-
Example how it works:
|
|
43
|
-
```js
|
|
44
|
-
const layout = new Layout().viewport().title('On load').onload()
|
|
45
|
-
layout.body.innerHTML = /*html*/`<div onload="this.innerHTML = 'new content'">original content</div>`
|
|
46
|
-
```
|
|
47
|
-
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
## Response with status
|
|
2
|
+
|
|
3
|
+
In version 6, added two methods:
|
|
4
|
+
1. `status(statusCode)` - adds the statusCode to `__status` property
|
|
5
|
+
2. `end(res)`
|
|
6
|
+
1. writes head with `__status, { 'Content-Type': 'text/html' }`
|
|
7
|
+
2. runs `res.end(this.rawHtml)`
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
The main idea, is to add quick way to response with layout.
|
|
@@ -23,16 +23,17 @@ Returns the inner HTML of the document.
|
|
|
23
23
|
|
|
24
24
|
Creates a clone of the current layout instance, preserving `options`.
|
|
25
25
|
|
|
26
|
+
|
|
27
|
+
#### `__status`
|
|
28
|
+
|
|
29
|
+
Stores the statusCode for `end` method.
|
|
30
|
+
|
|
26
31
|
### Methods
|
|
27
32
|
|
|
28
33
|
#### `lang(lang: string): this`
|
|
29
34
|
|
|
30
35
|
Sets the `lang` attribute on the `<html>` element.
|
|
31
36
|
|
|
32
|
-
#### `onload(): this`
|
|
33
|
-
|
|
34
|
-
Adds an `onload` script to the document. If called multiple times, the script is only added once.
|
|
35
|
-
|
|
36
37
|
#### `title(title: string): this`
|
|
37
38
|
|
|
38
39
|
Sets the document title and creates an Open Graph title meta tag.
|
|
@@ -86,3 +87,11 @@ Adds a `<script>` tag to the document.
|
|
|
86
87
|
#### `link(href: string, attributes: object = { rel: "stylesheet", type: "text/css" }): this`
|
|
87
88
|
|
|
88
89
|
Adds a `<link>` tag for external stylesheets.
|
|
90
|
+
|
|
91
|
+
#### `status(statusCode:number): this`
|
|
92
|
+
|
|
93
|
+
Adds the statusCode to `__status` property
|
|
94
|
+
|
|
95
|
+
#### `end(res):undefined`
|
|
96
|
+
|
|
97
|
+
Response with res(rawHtml)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const meta = require('./meta')
|
|
2
|
+
const script = require('./script')
|
|
3
|
+
const style = require('./style')
|
|
4
|
+
const addKeywords = require('./keywords')
|
|
5
|
+
const addLink = require('./link')
|
|
6
|
+
const addUrl = require('./url')
|
|
7
|
+
|
|
8
|
+
const { SingleNode } = require('als-document');
|
|
9
|
+
|
|
10
|
+
function getDescription(description,layout) {
|
|
11
|
+
meta({ name: 'description', content: description },layout)
|
|
12
|
+
meta({ property: 'og:description', content: description },layout)
|
|
13
|
+
meta({ property: 'twitter:description', content: description },layout)
|
|
14
|
+
return layout
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function getFavicon(href,layout) {
|
|
18
|
+
const faviconElement = layout.root.$('link[rel=icon][type=image/x-icon]')
|
|
19
|
+
if (faviconElement) faviconElement.setAttribute('href', href)
|
|
20
|
+
else layout.head.insert(2, new SingleNode('link', { rel: 'icon', href, type: 'image/x-icon' }))
|
|
21
|
+
return layout
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function getViewport(viewport = 'width=device-width, initial-scale=1.0',layout) {
|
|
25
|
+
const element = layout.root.$('meta[name="viewport"]')
|
|
26
|
+
if (element) element.setAttribute('content', viewport)
|
|
27
|
+
else layout.head.insert(2, new SingleNode('meta', { name: 'viewport', content: viewport }))
|
|
28
|
+
return layout
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function getImage(image,layout) {
|
|
32
|
+
meta({ property: 'og:image', content: image },layout)
|
|
33
|
+
meta({ name: 'twitter:image', content: image },layout)
|
|
34
|
+
meta({ name: 'twitter:card', content: 'summary_large_image' },layout)
|
|
35
|
+
return layout
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
module.exports = { meta, getDescription, getFavicon, getViewport, getImage, script, style, addKeywords, addLink, addUrl }
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
const { SingleNode } = require('als-document');
|
|
2
|
+
|
|
3
|
+
function keywords(keywords = [],layout) {
|
|
4
|
+
let keywordsElement = layout.root.$('meta[name=keywords]')
|
|
5
|
+
if (!keywordsElement) keywordsElement = new SingleNode('meta', { name: 'keywords' })
|
|
6
|
+
const content = keywordsElement.getAttribute('content')
|
|
7
|
+
const existingKeywords = content ? content.split(',') : []
|
|
8
|
+
keywords.forEach(keyword => {
|
|
9
|
+
keyword = keyword.trim()
|
|
10
|
+
if (!existingKeywords.includes(keyword)) existingKeywords.push(keyword)
|
|
11
|
+
});
|
|
12
|
+
if (existingKeywords.length) {
|
|
13
|
+
keywordsElement.setAttribute('content', existingKeywords.join())
|
|
14
|
+
layout.head.insert(2, keywordsElement)
|
|
15
|
+
}
|
|
16
|
+
return layout
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
module.exports = keywords
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const { SingleNode } = require('als-document');
|
|
2
|
+
|
|
3
|
+
function link(href, attributes = { rel: "stylesheet", type: "text/css" },layout) {
|
|
4
|
+
if (!href || typeof href !== 'string') return layout
|
|
5
|
+
const selector = `link[rel=stylesheet][href^="${href}"]`
|
|
6
|
+
let linkElement = layout.root.$(selector)
|
|
7
|
+
if (linkElement) return
|
|
8
|
+
linkElement = new SingleNode('link', { href, ...attributes })
|
|
9
|
+
layout.head.insert(2, linkElement)
|
|
10
|
+
return layout
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
module.exports = link
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const { SingleNode } = require('als-document');
|
|
2
|
+
|
|
3
|
+
function meta(props,layout) {
|
|
4
|
+
const entries = Object.entries(props)
|
|
5
|
+
const [name, value] = entries[0]
|
|
6
|
+
const selector = `meta[${name}="${value}"]`
|
|
7
|
+
const metaElement = layout.root.$(selector)
|
|
8
|
+
if (metaElement) entries.forEach(([name, v]) => metaElement.setAttribute(name, props[name]))
|
|
9
|
+
else layout.head.insert(2, new SingleNode('meta', props))
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
module.exports = meta
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const meta = require('./meta');
|
|
2
|
+
const { SingleNode } = require('als-document');
|
|
3
|
+
|
|
4
|
+
function addUrl(url, host,layout) {
|
|
5
|
+
try {
|
|
6
|
+
url = (host ? new URL(url, host) : new URL(url)).href.replace(/\/$/, '')
|
|
7
|
+
meta({ property: 'og:url', content: url },layout)
|
|
8
|
+
const canonicalElement = layout.root.$('link[rel="canonical"]')
|
|
9
|
+
if (canonicalElement) canonicalElement.setAttribute('href', url)
|
|
10
|
+
else layout.head.insert(2, new SingleNode('link', { rel: 'canonical', href: url }))
|
|
11
|
+
} catch (error) {
|
|
12
|
+
console.log(error)
|
|
13
|
+
layout.logger.log(`url "${url}" with host "${host}" is not valid url`)
|
|
14
|
+
}
|
|
15
|
+
return layout
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
module.exports = addUrl
|
package/lib/layout.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
const { Document
|
|
2
|
-
const script = require('./
|
|
3
|
-
const style = require('./style');
|
|
4
|
-
const onloadScript = require('./onload');
|
|
5
|
-
const deepClone = require('als-deep-clone')
|
|
1
|
+
const { Document } = require('als-document');
|
|
2
|
+
const { meta, getDescription, getFavicon, getViewport, getImage, script, style, addKeywords, addLink, addUrl } = require('./elements/index')
|
|
6
3
|
|
|
7
4
|
class Layout extends Document {
|
|
5
|
+
static propsToClone = [];
|
|
6
|
+
static options = { logger: console, host: '', minified: false }
|
|
7
|
+
|
|
8
8
|
constructor(html, options = {}) {
|
|
9
|
+
options = { ...Layout.options, ...options }
|
|
9
10
|
super(html, options.host);
|
|
10
11
|
this.options = options
|
|
11
12
|
this.logger = options.logger || console
|
|
@@ -13,14 +14,27 @@ class Layout extends Document {
|
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
get rawHtml() { return this.innerHTML }
|
|
16
|
-
get clone() { return new this.constructor(new Document(this, this.URL),
|
|
17
|
-
lang(lang) { this.html.setAttribute('lang', lang); return this }
|
|
17
|
+
get clone() { return new this.constructor(new Document(this, this.URL), this.options) }
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
this.
|
|
23
|
-
|
|
19
|
+
__status = 200;
|
|
20
|
+
status(status) { this.__status = status; return this }
|
|
21
|
+
end(res) {
|
|
22
|
+
res.writeHead(this.__status, { 'Content-Type': 'text/html' })
|
|
23
|
+
res.end(this.rawHtml)
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
lang(lang) { this.html.setAttribute('lang', lang); return this }
|
|
27
|
+
link(href, attributes) { return addLink(href, attributes, this) }
|
|
28
|
+
keywords(keywords = []) { return addKeywords(keywords, this) }
|
|
29
|
+
style(styles, minified = this.options.minified) { return style(styles, minified, this) }
|
|
30
|
+
url(url, host = this.URL) { return addUrl(url, host, this) }
|
|
31
|
+
meta(props) { return meta(props, this) }
|
|
32
|
+
description(description) { return getDescription(description,this) }
|
|
33
|
+
favicon(href) { return getFavicon(href,this) }
|
|
34
|
+
viewport(viewport) { return getViewport(viewport,this) }
|
|
35
|
+
image(image) { return getImage(image,this) }
|
|
36
|
+
script(attrs = {}, innerHTML = '', head = true, minified = this.options.minified) {
|
|
37
|
+
return script(attrs, innerHTML, head, minified, this)
|
|
24
38
|
}
|
|
25
39
|
|
|
26
40
|
title(title) {
|
|
@@ -29,90 +43,6 @@ class Layout extends Document {
|
|
|
29
43
|
this.meta({ property: 'og:title', content: title })
|
|
30
44
|
return this
|
|
31
45
|
}
|
|
32
|
-
|
|
33
|
-
description(description) {
|
|
34
|
-
this.meta({ name: 'description', content: description })
|
|
35
|
-
this.meta({ property: 'og:description', content: description })
|
|
36
|
-
this.meta({ property: 'twitter:description', content: description })
|
|
37
|
-
return this
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
favicon(href) {
|
|
41
|
-
const faviconElement = this.root.$('link[rel=icon][type=image/x-icon]')
|
|
42
|
-
if (faviconElement) faviconElement.setAttribute('href', href)
|
|
43
|
-
else this.head.insert(2, new SingleNode('link', { rel: 'icon', href, type: 'image/x-icon' }))
|
|
44
|
-
return this
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
meta(props) {
|
|
48
|
-
const entries = Object.entries(props)
|
|
49
|
-
const [name, value] = entries[0]
|
|
50
|
-
const selector = `meta[${name}="${value}"]`
|
|
51
|
-
const metaElement = this.root.$(selector)
|
|
52
|
-
if (metaElement) entries.forEach(([name, v]) => metaElement.setAttribute(name, props[name]))
|
|
53
|
-
else this.head.insert(2, new SingleNode('meta', props))
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
keywords(keywords = []) {
|
|
57
|
-
let keywordsElement = this.root.$('meta[name=keywords]')
|
|
58
|
-
if (!keywordsElement) keywordsElement = new SingleNode('meta', { name: 'keywords' })
|
|
59
|
-
const content = keywordsElement.getAttribute('content')
|
|
60
|
-
const existingKeywords = content ? content.split(',') : []
|
|
61
|
-
keywords.forEach(keyword => {
|
|
62
|
-
keyword = keyword.trim()
|
|
63
|
-
if (!existingKeywords.includes(keyword)) existingKeywords.push(keyword)
|
|
64
|
-
});
|
|
65
|
-
if (existingKeywords.length) {
|
|
66
|
-
keywordsElement.setAttribute('content', existingKeywords.join())
|
|
67
|
-
this.head.insert(2, keywordsElement)
|
|
68
|
-
}
|
|
69
|
-
return this
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
viewport(viewport = 'width=device-width, initial-scale=1.0') {
|
|
73
|
-
const element = this.root.$('meta[name="viewport"]')
|
|
74
|
-
if (element) element.setAttribute('content', viewport)
|
|
75
|
-
else this.head.insert(2, new SingleNode('meta', { name: 'viewport', content: viewport }))
|
|
76
|
-
return this
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
image(image) {
|
|
80
|
-
this.meta({ property: 'og:image', content: image })
|
|
81
|
-
this.meta({ name: 'twitter:image', content: image })
|
|
82
|
-
this.meta({ name: 'twitter:card', content: 'summary_large_image' })
|
|
83
|
-
return this
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
style(styles, minified = this.options.minified) {
|
|
87
|
-
return style(styles,minified,this)
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
url(url, host = this.URL) {
|
|
91
|
-
try {
|
|
92
|
-
url = new URL(url, host).href.replace(/\/$/, '')
|
|
93
|
-
this.meta({ property: 'og:url', content: url })
|
|
94
|
-
const canonicalElement = this.root.$('link[rel="canonical"]')
|
|
95
|
-
if (canonicalElement) canonicalElement.setAttribute('href', url)
|
|
96
|
-
else this.head.insert(2, new SingleNode('link', { rel: 'canonical', href: url }))
|
|
97
|
-
} catch (error) {
|
|
98
|
-
this.logger.log(`url ${url} with host ${host} is not valid url`)
|
|
99
|
-
}
|
|
100
|
-
return this
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
script(attrs = {}, innerHTML = '', head = true, minified = this.options.minified) {
|
|
104
|
-
return script(attrs,innerHTML,head,minified,this)
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
link(href, attributes = { rel: "stylesheet", type: "text/css" }) {
|
|
108
|
-
if (!href || typeof href !== 'string') return this
|
|
109
|
-
const selector = `link[rel=stylesheet][href^="${href}"]`
|
|
110
|
-
let linkElement = this.root.$(selector)
|
|
111
|
-
if (linkElement) return
|
|
112
|
-
linkElement = new SingleNode('link', { href, ...attributes })
|
|
113
|
-
this.head.insert(2, linkElement)
|
|
114
|
-
return this
|
|
115
|
-
}
|
|
116
46
|
}
|
|
117
47
|
|
|
118
48
|
module.exports = Layout
|
package/package.json
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "als-layout",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"scripts": {
|
|
6
|
-
"test": "node --test --experimental-test-coverage",
|
|
7
|
-
"report": "node --test --experimental-test-coverage --test-reporter=lcov --test-reporter-destination=lcov.info"
|
|
6
|
+
"test": "node --test --experimental-test-coverage ./tests/**.*",
|
|
7
|
+
"report": "node --test --experimental-test-coverage --test-reporter=lcov --test-reporter-destination=lcov.info",
|
|
8
|
+
"docs":"node ./scripts/build-readme.js"
|
|
8
9
|
},
|
|
9
10
|
"keywords": [],
|
|
10
11
|
"author": "Alex Sorkin",
|
|
11
12
|
"license": "MIT",
|
|
12
13
|
"description": "Html layout constructor",
|
|
13
14
|
"dependencies": {
|
|
14
|
-
"als-deep-clone": "^1.0.0",
|
|
15
15
|
"als-document": "^1.4.0",
|
|
16
16
|
"uglify-js": "^3.19.2",
|
|
17
17
|
"uglifycss": "^0.0.29"
|
package/readme.md
CHANGED
|
@@ -18,43 +18,16 @@ npm i als-layout
|
|
|
18
18
|
const Layout = require('als-layout')
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
## Change Log
|
|
22
|
-
* V5.2.0
|
|
23
|
-
* options object on clone, cloned too (remove the reference and deep cloning the object)
|
|
24
|
-
* V5.1.0
|
|
25
|
-
* status and end methods removed
|
|
26
|
-
* status and end methods added to als-view
|
|
27
|
-
* V5.0.0
|
|
28
|
-
* constructor changed
|
|
29
|
-
* options object parameter instead separated parameters
|
|
30
|
-
* options.logger
|
|
31
|
-
* bugs fixed
|
|
32
|
-
* some refactoring
|
|
33
|
-
* minifiying error catching
|
|
34
|
-
* status and end methods added
|
|
35
|
-
* V4.2.0
|
|
36
|
-
* link method changed
|
|
37
|
-
* `link(href, attributes = { rel: "stylesheet", type: "text/css" })`
|
|
38
|
-
* no version method
|
|
39
|
-
* no version parameter in image, link,script
|
|
40
|
-
* script
|
|
41
|
-
* script in footer added one after other in right order
|
|
42
|
-
|
|
43
|
-
* V4.1.0
|
|
44
|
-
* Render removed
|
|
45
|
-
|
|
46
|
-
* V4.0.0
|
|
47
|
-
* All code rebuilded and refactored
|
|
48
|
-
* No als-simple-css for style
|
|
49
|
-
* No charset method
|
|
50
|
-
* minifying for style and inner scripts
|
|
51
|
-
* updated render version
|
|
52
|
-
* render as element's method instead layout's method
|
|
53
|
-
|
|
54
|
-
* V3.0.0
|
|
55
|
-
* render switched to als-render
|
|
56
|
-
* updated bug with meta tags after body
|
|
21
|
+
## Change Log for V6
|
|
57
22
|
|
|
23
|
+
The code refactored.
|
|
24
|
+
|
|
25
|
+
### Removed
|
|
26
|
+
* no deepclone for options, using { ...Layout.options, ...options } instead
|
|
27
|
+
* no onload method
|
|
28
|
+
### Added
|
|
29
|
+
* status
|
|
30
|
+
* end(res)
|
|
58
31
|
|
|
59
32
|
## Basic Usage
|
|
60
33
|
|
|
@@ -93,16 +66,6 @@ layout.rawHtml // raw HTML of the document
|
|
|
93
66
|
layout.clone // creates a new layout object clone for current object
|
|
94
67
|
```
|
|
95
68
|
|
|
96
|
-
### onload
|
|
97
|
-
|
|
98
|
-
By adding onload attribute, you can run scripts for each element after dom content has loaded.
|
|
99
|
-
|
|
100
|
-
Example how it works:
|
|
101
|
-
```js
|
|
102
|
-
const layout = new Layout().viewport().title('On load').onload()
|
|
103
|
-
layout.body.innerHTML = /*html*/`<div onload="this.innerHTML = 'new content'">original content</div>`
|
|
104
|
-
```
|
|
105
|
-
|
|
106
69
|
|
|
107
70
|
## Cloning Functionality
|
|
108
71
|
|
|
@@ -173,6 +136,16 @@ In this example:
|
|
|
173
136
|
This advanced example illustrates how `als-layout` can be used to handle complex scenarios and requirements in web development, enhancing the flexibility and power at your disposal.
|
|
174
137
|
|
|
175
138
|
|
|
139
|
+
## Response with status
|
|
140
|
+
|
|
141
|
+
In version 6, added two methods:
|
|
142
|
+
1. `status(statusCode)` - adds the statusCode to `__status` property
|
|
143
|
+
2. `end(res)`
|
|
144
|
+
1. writes head with `__status, { 'Content-Type': 'text/html' }`
|
|
145
|
+
2. runs `res.end(this.rawHtml)`
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
The main idea, is to add quick way to response with layout.
|
|
176
149
|
## API
|
|
177
150
|
|
|
178
151
|
### Constructor
|
|
@@ -198,16 +171,17 @@ Returns the inner HTML of the document.
|
|
|
198
171
|
|
|
199
172
|
Creates a clone of the current layout instance, preserving `options`.
|
|
200
173
|
|
|
174
|
+
|
|
175
|
+
#### `__status`
|
|
176
|
+
|
|
177
|
+
Stores the statusCode for `end` method.
|
|
178
|
+
|
|
201
179
|
### Methods
|
|
202
180
|
|
|
203
181
|
#### `lang(lang: string): this`
|
|
204
182
|
|
|
205
183
|
Sets the `lang` attribute on the `<html>` element.
|
|
206
184
|
|
|
207
|
-
#### `onload(): this`
|
|
208
|
-
|
|
209
|
-
Adds an `onload` script to the document. If called multiple times, the script is only added once.
|
|
210
|
-
|
|
211
185
|
#### `title(title: string): this`
|
|
212
186
|
|
|
213
187
|
Sets the document title and creates an Open Graph title meta tag.
|
|
@@ -261,3 +235,11 @@ Adds a `<script>` tag to the document.
|
|
|
261
235
|
#### `link(href: string, attributes: object = { rel: "stylesheet", type: "text/css" }): this`
|
|
262
236
|
|
|
263
237
|
Adds a `<link>` tag for external stylesheets.
|
|
238
|
+
|
|
239
|
+
#### `status(statusCode:number): this`
|
|
240
|
+
|
|
241
|
+
Adds the statusCode to `__status` property
|
|
242
|
+
|
|
243
|
+
#### `end(res):undefined`
|
|
244
|
+
|
|
245
|
+
Response with res(rawHtml)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
const { readFileSync, writeFileSync, readdirSync } = require('fs')
|
|
2
2
|
const { join } = require('path')
|
|
3
3
|
|
|
4
|
-
const docsDir = join(__dirname, 'docs')
|
|
4
|
+
const docsDir = join(__dirname, '..','docs')
|
|
5
5
|
const files = readdirSync(docsDir)
|
|
6
6
|
const content = files.map(file => readFileSync(join(docsDir, file), 'utf-8')).join('\n');
|
|
7
|
-
writeFileSync(join(__dirname, 'readme.md'), content, 'utf-8')
|
|
7
|
+
writeFileSync(join(__dirname, '..','readme.md'), content, 'utf-8')
|
|
8
8
|
|
|
@@ -30,12 +30,6 @@ describe('Layout Integrative tests', () => {
|
|
|
30
30
|
assert(layout.root.$('title') === null, 'Title element was not removed correctly');
|
|
31
31
|
});
|
|
32
32
|
|
|
33
|
-
it('onload', () => {
|
|
34
|
-
layout.onload()
|
|
35
|
-
const script = layout.root.$('script')
|
|
36
|
-
assert(script.innerHTML.includes(`document.addEventListener('DOMContentLoaded'`))
|
|
37
|
-
})
|
|
38
|
-
|
|
39
33
|
});
|
|
40
34
|
|
|
41
35
|
describe('HTML Structure Initialization', () => {
|
|
@@ -81,7 +75,7 @@ describe('Clone Testing', () => {
|
|
|
81
75
|
|
|
82
76
|
it('should clone the layout correctly', () => {
|
|
83
77
|
const clone = layout.clone;
|
|
84
|
-
console.log(clone.constructor.name)
|
|
78
|
+
// console.log(clone.constructor.name)
|
|
85
79
|
assert(clone instanceof Layout, 'Clone should be an instance of Layout');
|
|
86
80
|
assert.notStrictEqual(clone, layout, 'Clone should not be the same instance as the original');
|
|
87
81
|
});
|
package/lib/onload.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
const onloadScript = /*js*/`document.addEventListener('DOMContentLoaded', function() {
|
|
2
|
-
const elements = document.querySelectorAll('[onload]');
|
|
3
|
-
elements.forEach(element => {
|
|
4
|
-
const onloadCode = element.getAttribute('onload');
|
|
5
|
-
const func = Function('"use strict"; return function() { ' + onloadCode + ' }');
|
|
6
|
-
func().call(element);
|
|
7
|
-
element.removeAttribute('onload');
|
|
8
|
-
});
|
|
9
|
-
});`;
|
|
10
|
-
|
|
11
|
-
module.exports = onloadScript
|
|
File without changes
|
|
File without changes
|