blob: 70a2a20bac0e9a0c93fa7c52d5f32da0f4a20cfc [file] [log] [blame]
Akrona0ea3c32018-12-14 18:33:48 +01001/**
2 * Parse Data URI scheme for attachement fields
3 * Afterwards the object has the parameters
4 * - contentType (defaults to text/plain)
5 * - base64 (if the data was base64 encoded)
6 * - isLink (if the contentType is application/x.korap-link)
7 * - param (as a map of arbitrary parameters)
8 * - payload (the URI decoded data)
9 *
10 * @author Nils Diewald
11 */
Akrone51eaa32020-11-10 09:35:53 +010012"use strict";
Akronff1b1f32020-10-18 11:41:29 +020013
Akrone51eaa32020-11-10 09:35:53 +010014define(function () {
Akronff1b1f32020-10-18 11:41:29 +020015
Akrond3bb85b2019-02-08 10:15:13 +010016 const uriRE = new RegExp("^data: *([^;,]*?(?: *; *[^,;]+?)*) *, *(.+)$");
Akrona0ea3c32018-12-14 18:33:48 +010017 const mapRE = new RegExp("^ *([^=]+?) *= *(.+?) *$");
18
19 return {
20
21 /**
22 * Constructor
23 */
24 create : function (url) {
25 return Object.create(this)._init(url);
26 },
27
28 // Parse URI scheme
29 _init : function (url) {
Akronff1b1f32020-10-18 11:41:29 +020030 const t = this;
Akrona0ea3c32018-12-14 18:33:48 +010031
32 // Decode
33 url = decodeURIComponent(url);
34
35 if (!uriRE.exec(url))
36 return;
37
Akronff1b1f32020-10-18 11:41:29 +020038 t.payload = RegExp.$2;
Akrona0ea3c32018-12-14 18:33:48 +010039
40 let map = {};
41 let start = 0;
Akronff1b1f32020-10-18 11:41:29 +020042 t.base64 = false;
43 t.isLink = false;
44 t.contentType = "text/plain";
Akrona0ea3c32018-12-14 18:33:48 +010045
46 // Split parameter map
47 RegExp.$1.split(/ *; */).map(function (item) {
Akronff1b1f32020-10-18 11:41:29 +020048 const t = this;
Akrona0ea3c32018-12-14 18:33:48 +010049
50 // Check first parameter
51 if (!start++ && item.match(/^[-a-z0-9]+?\/.+$/)) {
Akronff1b1f32020-10-18 11:41:29 +020052 t.contentType = item;
Akrona0ea3c32018-12-14 18:33:48 +010053
54 if (item === "application/x.korap-link")
Akronff1b1f32020-10-18 11:41:29 +020055 t.isLink = true;
Akrona0ea3c32018-12-14 18:33:48 +010056 }
57
58 // Decode b64
59 else if (item.toLowerCase() == "base64") {
Akronff1b1f32020-10-18 11:41:29 +020060 t.base64 = true;
61 t.payload = window.atob(t.payload);
Akrona0ea3c32018-12-14 18:33:48 +010062 }
63
64 // Parse arbitrary metadata
65 else if (mapRE.exec(item)) {
66 map[RegExp.$1] = RegExp.$2;
67 };
Akronff1b1f32020-10-18 11:41:29 +020068 }.bind(t));
Akrona0ea3c32018-12-14 18:33:48 +010069
Akronff1b1f32020-10-18 11:41:29 +020070 t.param = map;
71 return t;
Akrona0ea3c32018-12-14 18:33:48 +010072 },
73
74 /**
75 * Inline the attachement
76 * This should optimally be plugin-treatable
77 */
78 inline : function () {
79 if (this.isLink) {
Akronff1b1f32020-10-18 11:41:29 +020080 const title = this.param["title"] || this.payload;
81 const a = document.createElement('a');
Akrona0ea3c32018-12-14 18:33:48 +010082 a.setAttribute('href', this.payload);
83 a.setAttribute('rel', 'noopener noreferrer');
84 a.addT(title);
85 return a;
86 };
87
88 return document.createTextNode(this.payload);
89 }
90 }
91});