forked from cloudinary/cloudinary_angular
-
Notifications
You must be signed in to change notification settings - Fork 0
/
cloudinary-video.component.ts
106 lines (91 loc) · 3.2 KB
/
cloudinary-video.component.ts
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
import {
Component,
ElementRef,
Input,
ContentChildren,
QueryList,
AfterViewInit,
OnInit,
OnChanges,
SimpleChanges,
OnDestroy,
PLATFORM_ID,
Inject,
} from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { Cloudinary } from './cloudinary.service';
import { CloudinaryTransformationDirective } from './cloudinary-transformation.directive';
@Component({
selector: 'cl-video',
template: '<video></video>'
})
// See also video reference - http://cloudinary.com/documentation/video_manipulation_and_delivery#video_transformations_reference
export class CloudinaryVideo
implements AfterViewInit, OnInit, OnChanges, OnDestroy {
@Input('public-id') publicId: string;
@ContentChildren(CloudinaryTransformationDirective)
transformations: QueryList<CloudinaryTransformationDirective>;
observer: MutationObserver;
constructor(private el: ElementRef, private cloudinary: Cloudinary, @Inject(PLATFORM_ID) private platformId: Object) {}
ngOnInit(): void {
if (typeof MutationObserver !== 'undefined') {
// Create an observer instance
this.observer = new MutationObserver(() => {
this.loadVideo(this.publicId);
});
// Observe changes to attributes or child transformations to re-render the image
const config = { attributes: true, childList: true };
// pass in the target node, as well as the observer options
this.observer.observe(this.el.nativeElement, config);
}
}
ngOnChanges(changes: SimpleChanges) {
// Listen to changes on the data-bound property 'publicId'.
// Update component unless this is the first value assigned.
if (changes.publicId && !changes.publicId.isFirstChange()) {
this.loadVideo(changes.publicId.currentValue);
}
}
ngOnDestroy(): void {
if (this.observer && this.observer.disconnect) {
this.observer.disconnect();
}
}
ngAfterViewInit() {
if (!this.publicId) {
throw new Error(
'You must set the public id of the video to load, e.g. <cl-video public-id={{video.public_id}}...></cl-video>'
);
}
this.loadVideo(this.publicId);
}
loadVideo(publicId: string) {
// https://github.com/angular/universal#universal-gotchas
if (isPlatformBrowser(this.platformId)) {
const nativeElement = this.el.nativeElement;
const video = nativeElement.children[0];
const options = this.cloudinary.toCloudinaryAttributes(
nativeElement.attributes,
this.transformations
);
const videoTag = this.cloudinary.videoTag(publicId, options);
// Replace template with the custom video tag created by Cloudinary
this.appendSourceElements(video, videoTag.content());
// Add attributes
this.setElementAttributes(video, videoTag.attributes());
}
}
setElementAttributes(element, attributesLiteral) {
Object.keys(attributesLiteral).forEach(attrName => {
element.setAttribute(attrName, attributesLiteral[attrName]);
});
}
appendSourceElements(element, html) {
const fragment = document.createDocumentFragment();
element.innerHTML = html;
while (element.childNodes[0]) {
fragment.appendChild(element.childNodes[0]);
}
element.appendChild(fragment);
}
}