blob: 45c4b2103ad1f752409c937319881b001b741de3 [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
Akrond7d3ceb2022-02-07 20:13:09 +010032 t.base64 = false;
33 t.isLink = false;
34 t.contentType = "text/plain";
35
Akrona0ea3c32018-12-14 18:33:48 +010036 // Decode
Akrond7d3ceb2022-02-07 20:13:09 +010037 var url;
38 try {
39 url = decodeURIComponent(url);
40 } catch (e) {
41 t.payload = '[INVALID URI]';
42 return t;
43 }
Akrona0ea3c32018-12-14 18:33:48 +010044
45 if (!uriRE.exec(url))
46 return;
47
Akronff1b1f32020-10-18 11:41:29 +020048 t.payload = RegExp.$2;
Akrona0ea3c32018-12-14 18:33:48 +010049
50 let map = {};
51 let start = 0;
Akrona0ea3c32018-12-14 18:33:48 +010052
53 // Split parameter map
54 RegExp.$1.split(/ *; */).map(function (item) {
Akronff1b1f32020-10-18 11:41:29 +020055 const t = this;
Akrona0ea3c32018-12-14 18:33:48 +010056
57 // Check first parameter
58 if (!start++ && item.match(/^[-a-z0-9]+?\/.+$/)) {
Akronff1b1f32020-10-18 11:41:29 +020059 t.contentType = item;
Akrona0ea3c32018-12-14 18:33:48 +010060
61 if (item === "application/x.korap-link")
Akronff1b1f32020-10-18 11:41:29 +020062 t.isLink = true;
Akrona0ea3c32018-12-14 18:33:48 +010063 }
64
65 // Decode b64
66 else if (item.toLowerCase() == "base64") {
Akronff1b1f32020-10-18 11:41:29 +020067 t.base64 = true;
68 t.payload = window.atob(t.payload);
Akrona0ea3c32018-12-14 18:33:48 +010069 }
70
71 // Parse arbitrary metadata
72 else if (mapRE.exec(item)) {
73 map[RegExp.$1] = RegExp.$2;
74 };
Akronff1b1f32020-10-18 11:41:29 +020075 }.bind(t));
Akrona0ea3c32018-12-14 18:33:48 +010076
Akronff1b1f32020-10-18 11:41:29 +020077 t.param = map;
78 return t;
Akrona0ea3c32018-12-14 18:33:48 +010079 },
80
81 /**
82 * Inline the attachement
83 * This should optimally be plugin-treatable
84 */
85 inline : function () {
86 if (this.isLink) {
Akronff1b1f32020-10-18 11:41:29 +020087 const title = this.param["title"] || this.payload;
88 const a = document.createElement('a');
Akrona0ea3c32018-12-14 18:33:48 +010089 a.setAttribute('href', this.payload);
90 a.setAttribute('rel', 'noopener noreferrer');
91 a.addT(title);
92 return a;
93 };
94
95 return document.createTextNode(this.payload);
96 }
97 }
98});