Repository navigation
Expand file tree
/
Copy pathpull-quote.js
More file actions
98 lines (88 loc) · 3.71 KB
/
Copy pathpull-quote.js
File metadata and controls
98 lines (88 loc) · 3.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
const CSS = `
:host { display: inline; }
.pullquote {
display: block;
inline-size: var(--pullquote-inline-size, 25%);
font-size: var(--pullquote-font-size, 1.5em);
margin-block: var(--pullquote-margin-block-start, 0) var(--pullquote-margin-block-end, 1.5em);
margin-inline: var(--pullquote-margin-inline-start, 0) var(--pullquote-margin-inline-end, 1.5em);
padding-block: var(--pullquote-padding-block, 1em);
padding-inline: var(--pullquote-padding-inline, 1.25em);
float: var(--pullquote-float, left);
border-inline-end: var(--pullquote-border-inline-end, 4px solid #666);
color: var(--pullquote-color, #666);
background-color: var(--pullquote-background, #f9f9f9);
clear: var(--pullquote-clear, none);
}
:host([right]) .pullquote {
float: right;
border-inline-start: var(--pullquote-right-border-inline-start, 4px solid #e74c3c);
border-inline-end: none;
margin-inline: var(--pullquote-right-margin-inline-start, 1.5em) var(--pullquote-right-margin-inline-end, 0);
color: var(--pullquote-right-color, #fff);
background-color: var(--pullquote-right-background, #e74c3c);
}
:host([center]) .pullquote {
float: none;
clear: both;
margin-inline: var(--pullquote-center-margin-inline, auto);
margin-block: var(--pullquote-center-margin-block-start, 2em) var(--pullquote-center-margin-block-end, 2em);
text-align: var(--pullquote-center-text-align, center);
border-inline: none;
border-block-start: var(--pullquote-center-border-block-start, 3px solid #3498db);
border-block-end: var(--pullquote-center-border-block-end, 3px solid #3498db);
color: var(--pullquote-center-color, #2c3e50);
background-color: var(--pullquote-center-background, #ecf0f1);
font-style: var(--pullquote-center-font-style, italic);
inline-size: var(--pullquote-center-inline-size, min(90%, 40em));
}
slot {
display: contents;
}
`;
// One CSSStyleSheet shared across every <pull-quote> on the page via
// adoptedStyleSheets, instead of each instance parsing its own <style> tag.
// Falls back to a per-instance <style> element on engines that predate
// adoptedStyleSheets (Safari < 16.4) so styling still works there.
let sharedSheet;
function getSheet() {
if (typeof CSSStyleSheet === 'undefined' || !('adoptedStyleSheets' in Document.prototype)) return null;
if (!sharedSheet) {
sharedSheet = new CSSStyleSheet();
sharedSheet.replaceSync(CSS);
}
return sharedSheet;
}
class PullQuote extends HTMLElement {
constructor () {
super();
// Creates a shadow root
this.root = this.attachShadow({mode: 'open'});
}
connectedCallback() {
if (this.root.hasChildNodes()) return; // guard re-entry if the node moves in the DOM
const sheet = getSheet();
if (sheet) {
this.root.adoptedStyleSheets = [sheet];
} else {
const style = document.createElement('style');
style.textContent = CSS;
this.root.append(style);
}
// Build the visible duplicate via DOM APIs and a textContent assignment
// rather than interpolating into an innerHTML string — the previous
// approach re-parsed a literal "<" in the quoted text as markup (e.g. a
// pasted-in "<b>" would silently become a real element in the shadow
// tree). textContent never gets re-parsed as HTML.
const aside = document.createElement('aside');
aside.className = 'pullquote';
aside.setAttribute('aria-hidden', 'true');
aside.setAttribute('role', 'presentation');
aside.textContent = this.textContent;
this.root.append(aside, document.createElement('slot'));
}
}
// Define the new element
if ('customElements' in window && !customElements.get('pull-quote')) {
customElements.define('pull-quote', PullQuote);
}