Support attachements in metadata fields (fixes #77)
Change-Id: Ia5be6ec851ef318d89b115ac814663dc32da3484
diff --git a/dev/js/src/match/attachement.js b/dev/js/src/match/attachement.js
new file mode 100644
index 0000000..4548703
--- /dev/null
+++ b/dev/js/src/match/attachement.js
@@ -0,0 +1,86 @@
+/**
+ * Parse Data URI scheme for attachement fields
+ * Afterwards the object has the parameters
+ * - contentType (defaults to text/plain)
+ * - base64 (if the data was base64 encoded)
+ * - isLink (if the contentType is application/x.korap-link)
+ * - param (as a map of arbitrary parameters)
+ * - payload (the URI decoded data)
+ *
+ * @author Nils Diewald
+ */
+define(function () {
+ const uriRE = new RegExp("^data: *([^;,]+?(?: *; *[^,;]+?)*) *, *(.+)$");
+ const mapRE = new RegExp("^ *([^=]+?) *= *(.+?) *$");
+
+ return {
+
+ /**
+ * Constructor
+ */
+ create : function (url) {
+ return Object.create(this)._init(url);
+ },
+
+ // Parse URI scheme
+ _init : function (url) {
+
+ // Decode
+ url = decodeURIComponent(url);
+
+ if (!uriRE.exec(url))
+ return;
+
+ this.payload = RegExp.$2;
+
+ let map = {};
+ let start = 0;
+ this.base64 = false;
+ this.isLink = false;
+ this.contentType = "text/plain";
+
+ // Split parameter map
+ RegExp.$1.split(/ *; */).map(function (item) {
+
+ // Check first parameter
+ if (!start++ && item.match(/^[-a-z0-9]+?\/.+$/)) {
+ this.contentType = item;
+
+ if (item === "application/x.korap-link")
+ this.isLink = true;
+ }
+
+ // Decode b64
+ else if (item.toLowerCase() == "base64") {
+ this.base64 = true;
+ this.payload = window.atob(this.payload);
+ }
+
+ // Parse arbitrary metadata
+ else if (mapRE.exec(item)) {
+ map[RegExp.$1] = RegExp.$2;
+ };
+ }.bind(this));
+
+ this.param = map;
+ return this;
+ },
+
+ /**
+ * Inline the attachement
+ * This should optimally be plugin-treatable
+ */
+ inline : function () {
+ if (this.isLink) {
+ let title = this.param["title"] || this.payload;
+ let a = document.createElement('a');
+ a.setAttribute('href', this.payload);
+ a.setAttribute('rel', 'noopener noreferrer');
+ a.addT(title);
+ return a;
+ };
+
+ return document.createTextNode(this.payload);
+ }
+ }
+});
diff --git a/dev/js/src/match/corpusByMatch.js b/dev/js/src/match/corpusByMatch.js
index a405206..43048a3 100644
--- a/dev/js/src/match/corpusByMatch.js
+++ b/dev/js/src/match/corpusByMatch.js
@@ -106,7 +106,7 @@
};
// Ignore stored types
- if (type === "type:store")
+ if (type === "type:store" || type === "type:attachement")
return;
type = type || "type:string";
diff --git a/dev/js/src/match/meta.js b/dev/js/src/match/meta.js
index e273a39..c4cd63f 100644
--- a/dev/js/src/match/meta.js
+++ b/dev/js/src/match/meta.js
@@ -1,4 +1,4 @@
-define(['match/corpusByMatch','util'], function (cbmClass) {
+define(['match/corpusByMatch','match/attachement','util'], function (cbmClass, attClass) {
// Localization values
const loc = KorAP.Locale;
@@ -83,15 +83,30 @@
let metaDescr = field["value"];
metaDD = metaL.addE('dd');
metaDD.setAttribute('data-type', field["type"]);
-
+
if(metaDescr instanceof Array){
metaDD.classList.add("metakeyvalues");
- for(i = 0; i < metaDescr.length; i++){
- metaDD.addE('div').addT(metaDescr[i]);
+ for (i = 0; i < metaDescr.length; i++){
+
+ if (field["type"] === 'type:attachement') {
+ let att = attClass.create(metaDescr[i]);
+ if (att)
+ metaDD.addE('div').appendChild(att.inline());
+ }
+ else {
+ metaDD.addE('div').addT(metaDescr[i]);
+ }
}
}
else{
- metaDD.addT(field["value"]);
+ if (field["type"] === 'type:attachement') {
+ let att = attClass.create(field["value"]);
+ if (att)
+ metaDD.appendChild(att.inline());
+ }
+ else {
+ metaDD.addT(field["value"]);
+ };
}
metaDL.appendChild(metaL);