1. 1 : /**
  2. 2 : * A class for storing Notebook metadata
  3. 3 : * @memberof Spyral
  4. 4 : */
  5. 5 : class Metadata {
  6. 6 :
  7. 7 : /**
  8. 8 : * The metadata constructor.
  9. 9 : * @constructor
  10. 10 : * @param {Object} config The metadata config object
  11. 11 : * @param {String} config.title The title of the Notebook
  12. 12 : * @param {String} config.userId The user ID of the author of the Notebook
  13. 13 : * @param {String} config.author The name of the author of the Notebook
  14. 14 : * @param {Boolean} config.catalogue Whether to include the Notebook in the Catalogue
  15. 15 : * @param {String} config.description The description of the Notebook
  16. 16 : * @param {Array} config.keywords The keywords for the Notebook
  17. 17 : * @param {String} config.created When the Notebook was created
  18. 18 : * @param {String} config.language The language of the Notebook
  19. 19 : * @param {String} config.license The license for the Notebook
  20. 20 : * @returns {Spyral.Metadata}
  21. 21 : */
  22. 22 : constructor(config) {
  23. 23 : ['title', 'userId', 'author', 'description', 'catalogue', 'keywords', 'modified', 'created', 'language', 'license'].forEach(key => {
  24. 24 : if (key === 'keywords') {
  25. 25 : this[key] = [];
  26. 26 : } else if (key === 'catalogue') {
  27. 27 : this[key] = false;
  28. 28 : } else {
  29. 29 : this[key] = '';
  30. 30 : }
  31. 31 : })
  32. 32 : this.version = "0.1"; // may be changed by config
  33. 33 : if (config instanceof HTMLDocument) {
  34. 34 : config.querySelectorAll("meta").forEach(function(meta) {
  35. 35 : var name = meta.getAttribute("name");
  36. 36 : if (name && this.hasOwnProperty(name)) {
  37. 37 : var content = meta.getAttribute("content");
  38. 38 : if (content) {
  39. 39 : if (name === 'keywords') {
  40. 40 : var spaces = content.match(/\s+/g);
  41. 41 : if (content.search(',') === -1 && spaces !== null && spaces.length > 1) {
  42. 42 : // backwards compatibility: if there are no commas but multiple spaces then assume space delimited keywords
  43. 43 : content = content.split(/\s+/);
  44. 44 : } else {
  45. 45 : content = content.split(',');
  46. 46 : }
  47. 47 : } else if (name === 'catalogue') {
  48. 48 : content = content.toLowerCase() === 'true';
  49. 49 : }
  50. 50 : this[name] = content;
  51. 51 : }
  52. 52 : }
  53. 53 : }, this);
  54. 54 : } else {
  55. 55 : this.set(config);
  56. 56 : }
  57. 57 : if (!this.created) {this.setDateNow("created")}
  58. 58 : }
  59. 59 :
  60. 60 : /**
  61. 61 : * Set metadata properties.
  62. 62 : * @param {Object} config A config object
  63. 63 : */
  64. 64 : set(config) {
  65. 65 : for (var key in config) {
  66. 66 : if (this.hasOwnProperty(key)) {
  67. 67 : this[key] = config[key];
  68. 68 : }
  69. 69 : }
  70. 70 : }
  71. 71 :
  72. 72 : /**
  73. 73 : * Sets the specified field to the current date and time.
  74. 74 : * @param {String} field
  75. 75 : */
  76. 76 : setDateNow(field) {
  77. 77 : this[field] = new Date().toISOString();
  78. 78 : }
  79. 79 :
  80. 80 : /**
  81. 81 : * Gets the specified field as a short date.
  82. 82 : * @param {String} field
  83. 83 : * @returns {(String|undefined)}
  84. 84 : */
  85. 85 : shortDate(field) {
  86. 86 : return this[field] ? (new Date(Date.parse(this[field])).toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' })) : undefined;
  87. 87 : }
  88. 88 :
  89. 89 : /**
  90. 90 : * Gets the fields as a set of HTML meta tags.
  91. 91 : * @returns {String}
  92. 92 : */
  93. 93 : getHeaders() {
  94. 94 : var quotes = /"/g, newlines = /(\r\n|\r|\n)/g, tags = /<\/?\w+.*?>/g,
  95. 95 : headers = "<title>"+(this.title || "").replace(tags,"")+"</title>\n"
  96. 96 : for (var key in this) {
  97. 97 : if (this[key]) {
  98. 98 : if (Array.isArray(this[key])) {
  99. 99 : const array2string = this[key].join(',');
  100. 100 : headers+='<meta name="'+key+'" content="'+array2string.replace(quotes, "&quot;").replace(newlines, " ")+'">';
  101. 101 : } else if (typeof this[key] === 'boolean') {
  102. 102 : headers+='<meta name="'+key+'" content="'+this[key]+'">';
  103. 103 : } else {
  104. 104 : headers+='<meta name="'+key+'" content="'+this[key].replace(quotes, "&quot;").replace(newlines, " ")+'">';
  105. 105 : }
  106. 106 : }
  107. 107 : }
  108. 108 : return headers;
  109. 109 : }
  110. 110 :
  111. 111 : /**
  112. 112 : * Returns a clone of this Metadata
  113. 113 : * @returns {Spyral.Metadata}
  114. 114 : */
  115. 115 : clone() {
  116. 116 : let config = {};
  117. 117 : Object.assign(config, this);
  118. 118 : return new Metadata(config);
  119. 119 : }
  120. 120 :
  121. 121 :
  122. 122 : }
  123. 123 :
  124. 124 : export default Metadata