als-layout 6.1.0 → 7.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.js ADDED
@@ -0,0 +1,8 @@
1
+ const { writeFileSync, readFileSync } = require('fs')
2
+ const Layout = require('./src/layout.js');
3
+ const content = Layout.toString()
4
+
5
+ writeFileSync('index.mjs',`import { Document, SingleNode, Node } from 'als-document';\n`+'export '+content,'utf8' )
6
+ const document = readFileSync('./node_modules/als-document/document.js','utf8')
7
+
8
+ writeFileSync('layout.js',[document,`const { Document, SingleNode, Node } = alsDocument`,content].join('\n'))
package/index.mjs ADDED
@@ -0,0 +1,83 @@
1
+ import { Document, SingleNode, Node } from 'als-document';
2
+ export class Layout extends Document {
3
+ constructor(html, host) { super(html, host); this.root = this.html; }
4
+ get rawHtml() { return this.innerHTML }
5
+ get clone() { return new this.constructor(new Document(this, this.URL), this.host) }
6
+ lang(lang) { this.html.setAttribute('lang', lang); return this }
7
+ link(href, attributes = { rel: "stylesheet", type: "text/css" }) {
8
+ if (!href || typeof href !== 'string') throw new Error(`href attribute must be a string`)
9
+ if (!this.root.querySelector(`link[rel=stylesheet][href^="${href}"]`))
10
+ this.head.insert(2, new SingleNode('link', { href, ...attributes }))
11
+ return this
12
+ }
13
+ keywords(keywords = []) {
14
+ let el = this.root.$('meta[name=keywords]') || new SingleNode('meta', { name: 'keywords' })
15
+ keywords = new Set([...(el.getAttribute('content') || '').split(','),...keywords.map(k => k.trim())].filter(Boolean))
16
+ if (keywords.size) el.setAttribute('content', Array.from(keywords).join(','))
17
+ if(keywords.size && !el.parent) this.head.insert(2, el)
18
+ return this
19
+ }
20
+ style(styles) {
21
+ if (typeof styles !== 'string') throw 'styles parameter should be string';
22
+ let el = this.root.$('style') || this.head.insert(2, new Node('style'))
23
+ el.innerHTML = el.innerHTML + '\n' + styles;
24
+ return this
25
+ }
26
+ url(url, host = this.URL) {
27
+ try {
28
+ url = (host ? new URL(url, host) : new URL(url)).href.replace(/\/$/, '')
29
+ this.meta({ property: 'og:url', content: url })
30
+ const el = this.root.$('link[rel="canonical"]') || this.head.insert(2, new SingleNode('link', { rel: 'canonical', href: url }))
31
+ el.setAttribute('href', url)
32
+ } catch (error) { error.info = `url "${url}" with host "${host}" is not valid url`; throw error; }
33
+ return this
34
+ }
35
+ meta(props) {
36
+ const entries = Object.entries(props)
37
+ const [name, value] = entries[0]
38
+ const metaElement = this.root.querySelector(`meta[${name}="${value}"]`) || this.head.insert(2, new SingleNode('meta', props))
39
+ entries.forEach(([name, v]) => metaElement.setAttribute(name, props[name]))
40
+ return this
41
+ }
42
+ script(attrs = {}, innerHTML = '', head = true) {
43
+ if (typeof attrs !== 'object' || attrs === null || Array.isArray(attrs)) attrs = {}
44
+ if (attrs.src && this.root.querySelector(`script[src="${attrs.src}"]`)) return this
45
+ if (Object.keys(attrs).length || innerHTML) {
46
+ const script = new Node('script', attrs)
47
+ if (innerHTML) script.innerHTML = innerHTML
48
+ if (head) this.head.insert(2, script)
49
+ else this.html.insert(2, script)
50
+ }
51
+ return this
52
+ }
53
+ description(description) {
54
+ this.meta({ name: 'description', content: description })
55
+ this.meta({ property: 'og:description', content: description })
56
+ this.meta({ property: 'twitter:description', content: description })
57
+ return this
58
+ }
59
+ favicon(href) {
60
+ const el = this.root.$('link[rel=icon][type=image/x-icon]')
61
+ if (el) el.setAttribute('href', href)
62
+ else this.head.insert(2, new SingleNode('link', { rel: 'icon', href, type: 'image/x-icon' }))
63
+ return this
64
+ }
65
+ viewport(viewport = 'width=device-width, initial-scale=1.0') {
66
+ const el = this.root.$('meta[name="viewport"]')
67
+ if (el) el.setAttribute('content', viewport)
68
+ else this.head.insert(2, new SingleNode('meta', { name: 'viewport', content: viewport }))
69
+ return this
70
+ }
71
+ image(image) {
72
+ this.meta({ property: 'og:image', content: image })
73
+ this.meta({ name: 'twitter:image', content: image })
74
+ this.meta({ name: 'twitter:card', content: 'summary_large_image' })
75
+ return this
76
+ }
77
+ title(title) {
78
+ super.title // create title tag if not exists
79
+ super.title = title
80
+ this.meta({ property: 'og:title', content: title })
81
+ return this
82
+ }
83
+ }