Akron | a0ea3c3 | 2018-12-14 18:33:48 +0100 | [diff] [blame] | 1 | /** |
| 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 | */ |
| 12 | define(function () { |
Akron | ff1b1f3 | 2020-10-18 11:41:29 +0200 | [diff] [blame^] | 13 | |
| 14 | "use strict"; |
| 15 | |
Akron | d3bb85b | 2019-02-08 10:15:13 +0100 | [diff] [blame] | 16 | const uriRE = new RegExp("^data: *([^;,]*?(?: *; *[^,;]+?)*) *, *(.+)$"); |
Akron | a0ea3c3 | 2018-12-14 18:33:48 +0100 | [diff] [blame] | 17 | 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) { |
Akron | ff1b1f3 | 2020-10-18 11:41:29 +0200 | [diff] [blame^] | 30 | const t = this; |
Akron | a0ea3c3 | 2018-12-14 18:33:48 +0100 | [diff] [blame] | 31 | |
| 32 | // Decode |
| 33 | url = decodeURIComponent(url); |
| 34 | |
| 35 | if (!uriRE.exec(url)) |
| 36 | return; |
| 37 | |
Akron | ff1b1f3 | 2020-10-18 11:41:29 +0200 | [diff] [blame^] | 38 | t.payload = RegExp.$2; |
Akron | a0ea3c3 | 2018-12-14 18:33:48 +0100 | [diff] [blame] | 39 | |
| 40 | let map = {}; |
| 41 | let start = 0; |
Akron | ff1b1f3 | 2020-10-18 11:41:29 +0200 | [diff] [blame^] | 42 | t.base64 = false; |
| 43 | t.isLink = false; |
| 44 | t.contentType = "text/plain"; |
Akron | a0ea3c3 | 2018-12-14 18:33:48 +0100 | [diff] [blame] | 45 | |
| 46 | // Split parameter map |
| 47 | RegExp.$1.split(/ *; */).map(function (item) { |
Akron | ff1b1f3 | 2020-10-18 11:41:29 +0200 | [diff] [blame^] | 48 | const t = this; |
Akron | a0ea3c3 | 2018-12-14 18:33:48 +0100 | [diff] [blame] | 49 | |
| 50 | // Check first parameter |
| 51 | if (!start++ && item.match(/^[-a-z0-9]+?\/.+$/)) { |
Akron | ff1b1f3 | 2020-10-18 11:41:29 +0200 | [diff] [blame^] | 52 | t.contentType = item; |
Akron | a0ea3c3 | 2018-12-14 18:33:48 +0100 | [diff] [blame] | 53 | |
| 54 | if (item === "application/x.korap-link") |
Akron | ff1b1f3 | 2020-10-18 11:41:29 +0200 | [diff] [blame^] | 55 | t.isLink = true; |
Akron | a0ea3c3 | 2018-12-14 18:33:48 +0100 | [diff] [blame] | 56 | } |
| 57 | |
| 58 | // Decode b64 |
| 59 | else if (item.toLowerCase() == "base64") { |
Akron | ff1b1f3 | 2020-10-18 11:41:29 +0200 | [diff] [blame^] | 60 | t.base64 = true; |
| 61 | t.payload = window.atob(t.payload); |
Akron | a0ea3c3 | 2018-12-14 18:33:48 +0100 | [diff] [blame] | 62 | } |
| 63 | |
| 64 | // Parse arbitrary metadata |
| 65 | else if (mapRE.exec(item)) { |
| 66 | map[RegExp.$1] = RegExp.$2; |
| 67 | }; |
Akron | ff1b1f3 | 2020-10-18 11:41:29 +0200 | [diff] [blame^] | 68 | }.bind(t)); |
Akron | a0ea3c3 | 2018-12-14 18:33:48 +0100 | [diff] [blame] | 69 | |
Akron | ff1b1f3 | 2020-10-18 11:41:29 +0200 | [diff] [blame^] | 70 | t.param = map; |
| 71 | return t; |
Akron | a0ea3c3 | 2018-12-14 18:33:48 +0100 | [diff] [blame] | 72 | }, |
| 73 | |
| 74 | /** |
| 75 | * Inline the attachement |
| 76 | * This should optimally be plugin-treatable |
| 77 | */ |
| 78 | inline : function () { |
| 79 | if (this.isLink) { |
Akron | ff1b1f3 | 2020-10-18 11:41:29 +0200 | [diff] [blame^] | 80 | const title = this.param["title"] || this.payload; |
| 81 | const a = document.createElement('a'); |
Akron | a0ea3c3 | 2018-12-14 18:33:48 +0100 | [diff] [blame] | 82 | 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 | }); |