-
Notifications
You must be signed in to change notification settings - Fork 0
/
edirom-web-component-demo.js
278 lines (200 loc) · 7.62 KB
/
edirom-web-component-demo.js
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
/**
* Represents the EdiromWebComponentDemo custom element.
* @class
* @extends HTMLElement
*/
class EdiromWebComponentDemo extends HTMLElement {
/**
* Creates an instance of EdiromWebComponentDemo.
* @constructor
*/
constructor() {
super();
/** attach shadow root with mode "open" */
this.attachShadow({ mode: 'open' });
// set default properties
this.controlsAdded = false;
// append content
this.shadowRoot.innerHTML += `
<style>
h2 {
font-size: 1em;
}
#web-component-container {
height: 500px;
width: 500px;
border: 2px dashed #e0e0e0;
resize: both;
overflow: auto;
}
#wc-attribute-setters, #wc-custom-event-listeners {
max-width: 90%;
}
.setter {
display: inline-block;
margin: 0 20px 20px 0;
}
.setter span {
font-size: 0.9em;
font-family: Arial;
color: #333;
}
form {
display: inline-block;
}
</style>
<h2>Web Component Event Listeners</h2>
<div id="wc-custom-event-listeners">
<textarea rows="4" cols="50" readonly></textarea>
</div>
<h2>Web Component Attribute Setters</h2>
<div id="wc-attribute-setters"></div>
<hr/>
<div id="web-component-container">
<!-- PLACEHOLDER - embedded custom element -->
<slot></slot>
</div>
`;
// get slot element
this.slotElement = this.shadowRoot.querySelector('slot');
// add event listeners
this.addEventListeners();
}
/**
* Returns the list of observed attributes for the EdiromAudioPlayer custom element.
* @static
* @returns {Array<string>} The list of observed attributes.
*/
static get observedAttributes() {
return [ ];
}
/**
* Invoked when the custom element is connected from the document's DOM.
*/
connectedCallback() {
if(!this.controlsAdded) {
// now set controls added
this.controlsAdded = true;
// Listen for slot changes
this.slotElement.addEventListener('slotchange', () => {
const container = this.shadowRoot.querySelector('#web-component-container');
const assignedElements = this.slotElement.assignedElements();
// Access a specific custom element
assignedElements.forEach(childComponent => {
console.log("Child component found: ",childComponent);
// get web component name
const childComponentName = childComponent.tagName.toLowerCase();
const resizeObserver = new ResizeObserver(entries => {
for (let entry of entries) {
const {width, height} = entry.contentRect;
childComponent.setAttribute('width', width+'px');
childComponent.setAttribute('height', height+'px');
}
});
resizeObserver.observe(container);
// get HTML targets
const textarea = this.shadowRoot.querySelector('#wc-custom-event-listeners textarea');
const childComponentAttributeSetters = this.shadowRoot.querySelector('#wc-attribute-setters');
childComponentAttributeSetters.innerHTML = '';
// listen to event changes and provide setters for attributes of web component
childComponent.getAttributeNames().forEach(attribute => {
// Adding event listeners for changes in the web component
childComponent.addEventListener('communicate-'+attribute+'-update', (e) => {
textarea.textContent += 'Event "communicate-'+attribute+'-update"; '+attribute+'="'+e.detail[attribute]+'"\n';
textarea.scrollTop = textarea.scrollHeight;
});
// Creating setters for the web component attribute values
const setter = document.createElement('div');
setter.setAttribute('class', 'setter');
// setter label
const setterSpan = document.createElement('span');
setterSpan.textContent = attribute;
setter.appendChild(setterSpan);
// setter form
const setterForm = document.createElement('form');
const setterInput = document.createElement('input');
setterInput.setAttribute('type', 'text');
setterInput.setAttribute('name', attribute);
setterInput.setAttribute('id', 'input-'+attribute);
setterInput.setAttribute('value', childComponent.getAttribute(attribute));
setterForm.appendChild(setterInput);
const setterSubmit = document.createElement('input');
setterSubmit.setAttribute('type', 'submit');
setterSubmit.setAttribute('value', 'Set');
setterForm.appendChild(setterSubmit);
// setter event listener
setterForm.addEventListener('submit', (e) => {
e.preventDefault();
childComponent.setAttribute(attribute, setterInput.value);
});
setter.appendChild(setterForm);
childComponentAttributeSetters.appendChild(setter);
});
});
});
}
// set event listeners again
this.addEventListeners();
}
/**
* Invoked when the custom element is disconnected from the document's DOM.
*/
disconnectedCallback() { }
/**
* Invoked when the custom element is moved to a new document.
*/
adoptedCallback() { }
/**
* Invoked when one of the custom element's attributes is added, removed, or changed.
* @param {string} property - The name of the attribute that was changed.
* @param {*} oldValue - The previous value of the attribute.
* @param {*} newValue - The new value of the attribute.
*/
attributeChangedCallback(property, oldValue, newValue) {
// handle property change
this.set(property, newValue);
}
/**
* Sets the value of a global property and triggers property update events.
* @param {string} property - The name of the property to set.
* @param {*} newPropertyValue - The new value to set for the property.
*/
set(property, newPropertyValue) {
// set internal and html properties
this[property] = newPropertyValue;
// custom event for property update
const event = new CustomEvent('communicate-' + property + '-update', {
detail: { [property]: newPropertyValue },
bubbles: true
});
this.dispatchEvent(event);
// further handling of property change
this.handlePropertyChange(property, newPropertyValue);
}
/**
* Handles property changes for the audio player.
* @param {string} property - The name of the property being changed.
* @param {any} newPropertyValue - The new value of the property.
*/
handlePropertyChange(property, newPropertyValue) {
// handle property change
switch(property) {
// handle track setting
case '':
break;
// handle default
default:
console.log("Invalid property: '"+property+"'");
}
}
/**
* Adds event listeners to various elements in the audio player component.
* These event listeners handle play/pause button clicks, track toggler clicks,
* audio player events (duration change, time update), progress slider input,
* and playlist remove button clicks.
*/
addEventListeners() {
}
}
/** Define the custom element */
customElements.define('edirom-web-component-demo', EdiromWebComponentDemo);