mappers.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. import { Tools } from 'babylonjs';
  2. import { ViewerConfiguration } from './configuration';
  3. import { kebabToCamel } from '../helper';
  4. import * as merge from 'lodash.merge';
  5. export interface IMapper {
  6. map(rawSource: any): ViewerConfiguration;
  7. }
  8. class HTMLMapper implements IMapper {
  9. map(element: HTMLElement): ViewerConfiguration {
  10. let config = {};
  11. for (let attrIdx = 0; attrIdx < element.attributes.length; ++attrIdx) {
  12. let attr = element.attributes.item(attrIdx);
  13. // map "object.property" to the right configuration place.
  14. let split = attr.nodeName.split('.');
  15. split.reduce((currentConfig, key, idx) => {
  16. //convert html-style to json-style
  17. let camelKey = kebabToCamel(key);
  18. if (idx === split.length - 1) {
  19. let val: any = attr.nodeValue;
  20. if (val === "true") {
  21. val = true;
  22. } else if (val === "false") {
  23. val = false;
  24. } else {
  25. let number = parseFloat(val);
  26. if (!isNaN(number)) {
  27. val = number;
  28. }
  29. }
  30. currentConfig[camelKey] = val;
  31. } else {
  32. currentConfig[camelKey] = currentConfig[camelKey] || {};
  33. }
  34. return currentConfig[camelKey];
  35. }, config);
  36. }
  37. return config;
  38. }
  39. }
  40. class JSONMapper implements IMapper {
  41. map(rawSource: any) {
  42. return JSON.parse(rawSource);
  43. }
  44. }
  45. // TODO - Dom configuration mapper.
  46. class DOMMapper implements IMapper {
  47. map(baseElement: HTMLElement): ViewerConfiguration {
  48. let htmlMapper = new HTMLMapper();
  49. let config = htmlMapper.map(baseElement);
  50. let traverseChildren = function (element: HTMLElement, partConfig) {
  51. let children = element.children;
  52. if (children.length) {
  53. for (let i = 0; i < children.length; ++i) {
  54. let item = <HTMLElement>children.item(i);
  55. let configMapped = htmlMapper.map(item);
  56. let key = kebabToCamel(item.nodeName.toLowerCase());
  57. if (item.attributes.getNamedItem('array') && item.attributes.getNamedItem('array').nodeValue === 'true') {
  58. partConfig[key] = [];
  59. } else {
  60. if (element.attributes.getNamedItem('array') && element.attributes.getNamedItem('array').nodeValue === 'true') {
  61. partConfig.push(configMapped)
  62. } else if (partConfig[key]) {
  63. //exists already! problem... probably an array
  64. element.setAttribute('array', 'true');
  65. let oldItem = partConfig[key];
  66. partConfig = [oldItem, configMapped]
  67. } else {
  68. partConfig[key] = configMapped;
  69. }
  70. }
  71. traverseChildren(item, partConfig[key] || configMapped);
  72. }
  73. }
  74. return partConfig;
  75. }
  76. traverseChildren(baseElement, config);
  77. return config;
  78. }
  79. }
  80. export class MapperManager {
  81. private mappers: { [key: string]: IMapper };
  82. public static DefaultMapper = 'json';
  83. constructor() {
  84. this.mappers = {
  85. "html": new HTMLMapper(),
  86. "json": new JSONMapper(),
  87. "dom": new DOMMapper()
  88. }
  89. }
  90. public getMapper(type: string) {
  91. if (!this.mappers[type]) {
  92. Tools.Error("No mapper defined for " + type);
  93. }
  94. return this.mappers[type] || this.mappers[MapperManager.DefaultMapper];
  95. }
  96. public registerMapper(type: string, mapper: IMapper) {
  97. this.mappers[type] = mapper;
  98. }
  99. }
  100. export let mapperManager = new MapperManager();
  101. export default mapperManager;