viewerTemplatePlugin.ts 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. import { EventCallback, Template } from "./templateManager";
  2. import * as Handlebars from 'handlebars/dist/handlebars';
  3. export interface IViewerTemplatePlugin {
  4. readonly templateName: string;
  5. readonly eventsToAttach?: Array<string>;
  6. interactionPredicate(event: EventCallback): boolean;
  7. onEvent?(event: EventCallback): void;
  8. addHTMLTemplate?(template: Template): void;
  9. }
  10. export abstract class AbstractViewerNavbarButton implements IViewerTemplatePlugin {
  11. public readonly templateName: string = "navBar";
  12. public readonly eventsToAttach: Array<string> = ['pointerdown'];
  13. protected _prepend: boolean = true;
  14. protected _buttonName: string;
  15. protected _buttonClass: string;
  16. protected _htmlTemplate: string;
  17. constructor(buttonName: string, buttonClass?: string, htmlTemplate?: string) {
  18. this._buttonName = buttonName;
  19. if (buttonClass) {
  20. this._buttonClass = buttonClass;
  21. } else {
  22. this._buttonClass = buttonName + '-button';
  23. }
  24. if (htmlTemplate) { this._htmlTemplate = htmlTemplate }
  25. else {
  26. this._htmlTemplate = `
  27. <button class="${this._buttonClass}">
  28. <span class="icon ${this._buttonName}-icon"></span>
  29. </button>
  30. `;
  31. }
  32. }
  33. interactionPredicate(event: EventCallback): boolean {
  34. let pointerDown = <PointerEvent>event.event;
  35. if (pointerDown.button !== 0) return false;
  36. var element = (<HTMLElement>event.event.target);
  37. if (!element) {
  38. return false;
  39. }
  40. let elementClasses = element.classList;
  41. for (let i = 0; i < elementClasses.length; ++i) {
  42. let className = elementClasses[i];
  43. if (className.indexOf(this._buttonClass) !== -1) {
  44. return true;
  45. }
  46. }
  47. return false;
  48. }
  49. abstract onEvent(event: EventCallback): void;
  50. public addHTMLTemplate(template: Template): void {
  51. let element = this._generateHTMLElement(template);
  52. let container = template.parent.querySelector("div.default-control");
  53. if (container) {
  54. if (this._prepend) {
  55. container.insertBefore(element, container.firstChild);
  56. } else {
  57. container.appendChild(element);
  58. }
  59. }
  60. }
  61. protected _generateHTMLElement(template: Template): Element | DocumentFragment {
  62. let compiledTemplate = Handlebars.compile(this._htmlTemplate, { noEscape: (template.configuration.params && !!template.configuration.params.noEscape) });
  63. let config = template.configuration.params || {};
  64. let rawHtml = compiledTemplate(config);
  65. let fragment: Element | DocumentFragment;
  66. try {
  67. fragment = document.createRange().createContextualFragment(rawHtml);
  68. } catch (e) {
  69. let test = document.createElement(this._buttonClass);
  70. test.innerHTML = rawHtml;
  71. fragment = test;
  72. }
  73. return fragment;
  74. }
  75. }