import {
ButtonMarkupData,
ChannelMiniatureMarkupData,
+ ContainerMarkupData,
EmbedMarkupData,
PlaylistMiniatureMarkupData,
VideoMiniatureMarkupData,
VideosListMarkupComponent
} from './peertube-custom-tags'
-type BuilderFunction = (el: HTMLElement) => ComponentRef<any>
+type AngularBuilderFunction = (el: HTMLElement) => ComponentRef<any>
+type HTMLBuilderFunction = (el: HTMLElement) => HTMLElement
@Injectable()
export class CustomMarkupService {
- private builders: { [ selector: string ]: BuilderFunction } = {
+ private angularBuilders: { [ selector: string ]: AngularBuilderFunction } = {
'peertube-button': el => this.buttonBuilder(el),
'peertube-video-embed': el => this.embedBuilder(el, 'video'),
'peertube-playlist-embed': el => this.embedBuilder(el, 'playlist'),
'peertube-videos-list': el => this.videosListBuilder(el)
}
+ private htmlBuilders: { [ selector: string ]: HTMLBuilderFunction } = {
+ 'peertube-container': el => this.containerBuilder(el)
+ }
+
private customMarkdownRenderer: (text: string) => Promise<HTMLElement>
constructor (
const rootElement = document.createElement('div')
rootElement.innerHTML = html
- for (const selector of this.getSupportedTags()) {
+ for (const selector of Object.keys(this.htmlBuilders)) {
+ rootElement.querySelectorAll(selector)
+ .forEach((e: HTMLElement) => {
+ try {
+ const element = this.execHTMLBuilder(selector, e)
+ // Insert as first child
+ e.insertBefore(element, e.firstChild)
+ } catch (err) {
+ console.error('Cannot inject component %s.', selector, err)
+ }
+ })
+ }
+
+ for (const selector of Object.keys(this.angularBuilders)) {
rootElement.querySelectorAll(selector)
.forEach((e: HTMLElement) => {
try {
- const component = this.execBuilder(selector, e)
+ const component = this.execAngularBuilder(selector, e)
this.dynamicElementService.injectElement(e, component)
} catch (err) {
}
private getSupportedTags () {
- return Object.keys(this.builders)
+ return Object.keys(this.angularBuilders)
+ .concat(Object.keys(this.htmlBuilders))
}
- private execBuilder (selector: string, el: HTMLElement) {
- return this.builders[selector](el)
+ private execHTMLBuilder (selector: string, el: HTMLElement) {
+ return this.htmlBuilders[selector](el)
+ }
+
+ private execAngularBuilder (selector: string, el: HTMLElement) {
+ return this.angularBuilders[selector](el)
}
private embedBuilder (el: HTMLElement, type: 'video' | 'playlist') {
const component = this.dynamicElementService.createElement(VideosListMarkupComponent)
const model = {
- title: data.title,
- description: data.description,
sort: data.sort,
categoryOneOf: this.buildArrayNumber(data.categoryOneOf),
languageOneOf: this.buildArrayString(data.languageOneOf),
return component
}
+ private containerBuilder (el: HTMLElement) {
+ const data = el.dataset as ContainerMarkupData
+
+ const root = document.createElement('div')
+ root.classList.add('peertube-container')
+
+ if (data.width) {
+ root.setAttribute('width', data.width)
+ }
+
+ if (data.title) {
+ const titleElement = document.createElement('h4')
+ titleElement.innerText = data.title
+ root.appendChild(titleElement)
+ }
+
+ if (data.description) {
+ const descriptionElement = document.createElement('div')
+ descriptionElement.innerText = data.description
+ root.appendChild(descriptionElement)
+ }
+
+ return root
+ }
+
private buildNumber (value: string) {
if (!value) return undefined