/**
* A class for storing Notebook metadata
* @memberof Spyral
*/
class Metadata {
/**
* The metadata constructor.
* @constructor
* @param {Object} config The metadata config object
* @param {String} config.title The title of the Notebook
* @param {String} config.userId The user ID of the author of the Notebook
* @param {String} config.author The name of the author of the Notebook
* @param {Boolean} config.catalogue Whether to include the Notebook in the Catalogue
* @param {String} config.description The description of the Notebook
* @param {Array} config.keywords The keywords for the Notebook
* @param {String} config.created When the Notebook was created
* @param {String} config.language The language of the Notebook
* @param {String} config.license The license for the Notebook
* @returns {Spyral.Metadata}
*/
constructor(config) {
['title', 'userId', 'author', 'description', 'catalogue', 'keywords', 'modified', 'created', 'language', 'license'].forEach(key => {
if (key === 'keywords') {
this[key] = [];
} else if (key === 'catalogue') {
this[key] = false;
} else {
this[key] = '';
}
})
this.version = "0.1"; // may be changed by config
if (config instanceof HTMLDocument) {
config.querySelectorAll("meta").forEach(function(meta) {
var name = meta.getAttribute("name");
if (name && this.hasOwnProperty(name)) {
var content = meta.getAttribute("content");
if (content) {
if (name === 'keywords') {
var spaces = content.match(/\s+/g);
if (content.search(',') === -1 && spaces !== null && spaces.length > 1) {
// backwards compatibility: if there are no commas but multiple spaces then assume space delimited keywords
content = content.split(/\s+/);
} else {
content = content.split(',');
}
} else if (name === 'catalogue') {
content = content.toLowerCase() === 'true';
}
this[name] = content;
}
}
}, this);
} else {
this.set(config);
}
if (!this.created) {this.setDateNow("created")}
}
/**
* Set metadata properties.
* @param {Object} config A config object
*/
set(config) {
for (var key in config) {
if (this.hasOwnProperty(key)) {
this[key] = config[key];
}
}
}
/**
* Sets the specified field to the current date and time.
* @param {String} field
*/
setDateNow(field) {
this[field] = new Date().toISOString();
}
/**
* Gets the specified field as a short date.
* @param {String} field
* @returns {(String|undefined)}
*/
shortDate(field) {
return this[field] ? (new Date(Date.parse(this[field])).toLocaleDateString(undefined, { year: 'numeric', month: 'long', day: 'numeric' })) : undefined;
}
/**
* Gets the fields as a set of HTML meta tags.
* @returns {String}
*/
getHeaders() {
var quotes = /"/g, newlines = /(\r\n|\r|\n)/g, tags = /<\/?\w+.*?>/g,
headers = "<title>"+(this.title || "").replace(tags,"")+"</title>\n"
for (var key in this) {
if (this[key]) {
if (Array.isArray(this[key])) {
const array2string = this[key].join(',');
headers+='<meta name="'+key+'" content="'+array2string.replace(quotes, """).replace(newlines, " ")+'">';
} else if (typeof this[key] === 'boolean') {
headers+='<meta name="'+key+'" content="'+this[key]+'">';
} else {
headers+='<meta name="'+key+'" content="'+this[key].replace(quotes, """).replace(newlines, " ")+'">';
}
}
}
return headers;
}
/**
* Returns a clone of this Metadata
* @returns {Spyral.Metadata}
*/
clone() {
let config = {};
Object.assign(config, this);
return new Metadata(config);
}
}
export default Metadata