about summary refs log tree commit diff
path: root/src/platform/polyfills.ts
blob: a64c2c33a650a47c61b6f9670b86fbc678d9254c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import 'fast-text-encoding'
import Graphemer from 'graphemer'
export {}

/**
https://github.com/MaxArt2501/base64-js
The MIT License (MIT)
Copyright (c) 2014 MaxArt2501
 */

const b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
// Regular expression to check formal correctness of base64 encoded strings
const b64re =
  /^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/

globalThis.atob = (str: string): string => {
  // atob can work with strings with whitespaces, even inside the encoded part,
  // but only \t, \n, \f, \r and ' ', which can be stripped.
  str = String(str).replace(/[\t\n\f\r ]+/g, '')
  if (!b64re.test(str)) {
    throw new TypeError(
      "Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.",
    )
  }

  // Adding the padding if missing, for semplicity
  str += '=='.slice(2 - (str.length & 3))
  var bitmap,
    result = '',
    r1,
    r2,
    i = 0
  for (; i < str.length; ) {
    bitmap =
      (b64.indexOf(str.charAt(i++)) << 18) |
      (b64.indexOf(str.charAt(i++)) << 12) |
      ((r1 = b64.indexOf(str.charAt(i++))) << 6) |
      (r2 = b64.indexOf(str.charAt(i++)))

    result +=
      r1 === 64
        ? String.fromCharCode((bitmap >> 16) & 255)
        : r2 === 64
        ? String.fromCharCode((bitmap >> 16) & 255, (bitmap >> 8) & 255)
        : String.fromCharCode(
            (bitmap >> 16) & 255,
            (bitmap >> 8) & 255,
            bitmap & 255,
          )
  }
  return result
}

const splitter = new Graphemer()
globalThis.Intl = globalThis.Intl || {}

// @ts-ignore we're polyfilling -prf
globalThis.Intl.Segmenter =
  // @ts-ignore we're polyfilling -prf
  globalThis.Intl.Segmenter ||
  class Segmenter {
    constructor() {}
    // NOTE
    // this is not a precisely correct polyfill but it's sufficient for our needs
    // -prf
    segment = splitter.iterateGraphemes
  }