code.gitea.io/gitea@v1.21.7/web_src/js/utils.js (about)

     1  import {encode, decode} from 'uint8-to-base64';
     2  
     3  // transform /path/to/file.ext to file.ext
     4  export function basename(path = '') {
     5    const lastSlashIndex = path.lastIndexOf('/');
     6    return lastSlashIndex < 0 ? path : path.substring(lastSlashIndex + 1);
     7  }
     8  
     9  // transform /path/to/file.ext to .ext
    10  export function extname(path = '') {
    11    const lastPointIndex = path.lastIndexOf('.');
    12    return lastPointIndex < 0 ? '' : path.substring(lastPointIndex);
    13  }
    14  
    15  // test whether a variable is an object
    16  export function isObject(obj) {
    17    return Object.prototype.toString.call(obj) === '[object Object]';
    18  }
    19  
    20  // returns whether a dark theme is enabled
    21  export function isDarkTheme() {
    22    const style = window.getComputedStyle(document.documentElement);
    23    return style.getPropertyValue('--is-dark-theme').trim().toLowerCase() === 'true';
    24  }
    25  
    26  // strip <tags> from a string
    27  export function stripTags(text) {
    28    return text.replace(/<[^>]*>?/g, '');
    29  }
    30  
    31  export function parseIssueHref(href) {
    32    const path = (href || '').replace(/[#?].*$/, '');
    33    const [_, owner, repo, type, index] = /([^/]+)\/([^/]+)\/(issues|pulls)\/([0-9]+)/.exec(path) || [];
    34    return {owner, repo, type, index};
    35  }
    36  
    37  // parse a URL, either relative '/path' or absolute 'https://localhost/path'
    38  export function parseUrl(str) {
    39    return new URL(str, str.startsWith('http') ? undefined : window.location.origin);
    40  }
    41  
    42  // return current locale chosen by user
    43  export function getCurrentLocale() {
    44    return document.documentElement.lang;
    45  }
    46  
    47  // given a month (0-11), returns it in the documents language
    48  export function translateMonth(month) {
    49    return new Date(Date.UTC(2022, month, 12)).toLocaleString(getCurrentLocale(), {month: 'short', timeZone: 'UTC'});
    50  }
    51  
    52  // given a weekday (0-6, Sunday to Saturday), returns it in the documents language
    53  export function translateDay(day) {
    54    return new Date(Date.UTC(2022, 7, day)).toLocaleString(getCurrentLocale(), {weekday: 'short', timeZone: 'UTC'});
    55  }
    56  
    57  // convert a Blob to a DataURI
    58  export function blobToDataURI(blob) {
    59    return new Promise((resolve, reject) => {
    60      try {
    61        const reader = new FileReader();
    62        reader.addEventListener('load', (e) => {
    63          resolve(e.target.result);
    64        });
    65        reader.addEventListener('error', () => {
    66          reject(new Error('FileReader failed'));
    67        });
    68        reader.readAsDataURL(blob);
    69      } catch (err) {
    70        reject(err);
    71      }
    72    });
    73  }
    74  
    75  // convert image Blob to another mime-type format.
    76  export function convertImage(blob, mime) {
    77    return new Promise(async (resolve, reject) => {
    78      try {
    79        const img = new Image();
    80        const canvas = document.createElement('canvas');
    81        img.addEventListener('load', () => {
    82          try {
    83            canvas.width = img.naturalWidth;
    84            canvas.height = img.naturalHeight;
    85            const context = canvas.getContext('2d');
    86            context.drawImage(img, 0, 0);
    87            canvas.toBlob((blob) => {
    88              if (!(blob instanceof Blob)) return reject(new Error('imageBlobToPng failed'));
    89              resolve(blob);
    90            }, mime);
    91          } catch (err) {
    92            reject(err);
    93          }
    94        });
    95        img.addEventListener('error', () => {
    96          reject(new Error('imageBlobToPng failed'));
    97        });
    98        img.src = await blobToDataURI(blob);
    99      } catch (err) {
   100        reject(err);
   101      }
   102    });
   103  }
   104  
   105  export function toAbsoluteUrl(url) {
   106    if (url.startsWith('http://') || url.startsWith('https://')) {
   107      return url;
   108    }
   109    if (url.startsWith('//')) {
   110      return `${window.location.protocol}${url}`; // it's also a somewhat absolute URL (with the current scheme)
   111    }
   112    if (url && !url.startsWith('/')) {
   113      throw new Error('unsupported url, it should either start with / or http(s)://');
   114    }
   115    return `${window.location.origin}${url}`;
   116  }
   117  
   118  // Encode an ArrayBuffer into a URLEncoded base64 string.
   119  export function encodeURLEncodedBase64(arrayBuffer) {
   120    return encode(arrayBuffer)
   121      .replace(/\+/g, '-')
   122      .replace(/\//g, '_')
   123      .replace(/=/g, '');
   124  }
   125  
   126  // Decode a URLEncoded base64 to an ArrayBuffer string.
   127  export function decodeURLEncodedBase64(base64url) {
   128    return decode(base64url
   129      .replace(/_/g, '/')
   130      .replace(/-/g, '+'));
   131  }
   132  
   133  const domParser = new DOMParser();
   134  const xmlSerializer = new XMLSerializer();
   135  
   136  export function parseDom(text, contentType) {
   137    return domParser.parseFromString(text, contentType);
   138  }
   139  
   140  export function serializeXml(node) {
   141    return xmlSerializer.serializeToString(node);
   142  }