Skip to content

Instantly share code, notes, and snippets.

@ray007
Last active December 19, 2023 04:22
Show Gist options
  • Save ray007/a55ceac9c7ab538ac39189943fde870f to your computer and use it in GitHub Desktop.
Save ray007/a55ceac9c7ab538ac39189943fde870f to your computer and use it in GitHub Desktop.
URL polyfill for nativescript
// polyfill URL since that seems to not be done for nativescript
import { path } from "@nativescript/core";
import 'url-search-params-polyfill';
if (!global.URL) {
class URL {
constructor(sUrl, base) {
if (base) parse(this, base);
parse(this, sUrl);
}
toString() {
let p = this.protocol, h = "";
if (p) h = `${this.protocol}//${getAuth(this)}${this.host}`;
return `${h}${this.pathname}${this.search}${this.hash}`;
}
get href() {
return this.toString();
}
set href(value) {
parse(this, value);
}
get origin() {
return `${this.protocol}//${this.host}`;
}
set origin(v) {}
get host() {
let { protocol, hostname, port } = this, h = hostname;
if (port && (!protocol || port != dp[protocol])) h += `:${port}`;
return h;
}
set host(value) {
let m = value.match(/^([^:]*)(:\d+)?$/);
this.hostname = m[1] || "";
this.port = m[2] ? m[2].substr(1) : "";
}
get search() {
let s = `${this.searchParams}`;
return s && `?${s}`;
}
set search(value) {
this.searchParams = new URLSearchParams(value);
}
}
URL.prototype.protocol = "";
URL.prototype.username = "";
URL.prototype.password = "";
URL.prototype.host = "";
URL.prototype.port = "";
URL.prototype.pathname = "";
URL.prototype.hash = "";
const dp = URL.defaultProtocols = {
"http:": 80,
"https:": 443,
};
const rxUrl = /^(?:([\w-]+:)\/\/)?([^/]*)(\/[^?#]*)?(\?[^#]*)?(#.*)?$/;
function parse(url, str) {
let parts = str.match(rxUrl);
let [ _all, prot, hostAuth, pathname = "", search = "", hash = ""] = parts;
if (prot) url.protocol = prot;
if (hostAuth) setHostAuth(url, hostAuth);
if (pathname && pathname[0] != '/') {
let pn = url.pathname;
if (pn && !pn.endsWith('/')) {
let i = pn.lastIndexOf('/');
pn = (i >= 0) ? pn.substr(0, i+1) : "";
}
pathname = pn + pathname;
}
url.pathname = path.normalize(pathname || "");
url.search = search;
url.hash = hash;
}
function getAuth(url) {
var { username, password } = url, a = username || "";
if (username) {
if (password) a += `:${password}`;
a += '@';
}
return a;
}
function setHostAuth(url, hostAuth) {
let i = hostAuth.indexOf('@'), creds = "";
if (i > 0) {
creds = hostAuth.substr(0, i);
hostAuth = hostAuth.substr(i+1);
}
url.host = hostAuth;
creds = creds.split(':');
url.username = creds[0];
url.password = creds[1] || "";
}
global.URL = URL;
}
@cloudhx
Copy link

cloudhx commented Apr 20, 2023

Thanks for sharing this!

@NathanWalker
Copy link

This is super helpful 🤗 For those wondering how to use this in, for example, an Angular app, you can do the following:

  1. Create src/polyfills-custom.ts and copy/paste above into it.
  2. npm install url-search-params-polyfill -D
  3. Now import it into the src/polyfills.ts like this:
/**
 * NativeScript Polyfills
 */

// Install @nativescript/core polyfills (XHR, setTimeout, requestAnimationFrame)
import '@nativescript/core/globals';

import '@valor/nativescript-websockets';
// Install @nativescript/angular specific polyfills
import '@nativescript/angular/polyfills';

// IMPORT CUSTOM POLYFILLS HERE:
import './polyfills-custom';

/**
 * Zone.js and patches
 */
// Add pre-zone.js patches needed for the NativeScript platform
import '@nativescript/zone-js/dist/pre-zone-polyfills';

// Zone JS is required by default for Angular itself
import 'zone.js';

// Add NativeScript specific Zone JS patches
import '@nativescript/zone-js';

Noting that Url and UrlSearchParams will become optional automatic polyfills that a user can choose to polyfill likely through nativescript.config in the future. Reason being is that they can provide extra weight to bundle that when not used may be wasteful so the working group is aiming to allow easy automatic polyfiling of the most popular optionals via config option in future.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment