1// Copyright © 2023 650 Industries. 2// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. 3import URL from 'url-parse'; 4class DOMException extends Error { 5 constructor(message, name) { 6 super(message); 7 this.name = name; 8 } 9} 10// The differences between the definitions of `Location` and `WorkerLocation` 11// are because of the `LegacyUnforgeable` attribute only specified upon 12// `Location`'s properties. See: 13// - https://html.spec.whatwg.org/multipage/history.html#the-location-interface 14// - https://heycam.github.io/webidl/#LegacyUnforgeable 15class Location { 16 constructor(href = null) { 17 const url = new URL( 18 // @ts-expect-error 19 href); 20 // @ts-expect-error 21 url.username = ''; 22 // @ts-expect-error 23 url.password = ''; 24 Object.defineProperties(this, { 25 hash: { 26 get() { 27 return url.hash; 28 }, 29 set() { 30 throw new DOMException(`Cannot set "location.hash".`, 'NotSupportedError'); 31 }, 32 enumerable: true, 33 }, 34 host: { 35 get() { 36 return url.host; 37 }, 38 set() { 39 throw new DOMException(`Cannot set "location.host".`, 'NotSupportedError'); 40 }, 41 enumerable: true, 42 }, 43 hostname: { 44 get() { 45 return url.hostname; 46 }, 47 set() { 48 throw new DOMException(`Cannot set "location.hostname".`, 'NotSupportedError'); 49 }, 50 enumerable: true, 51 }, 52 href: { 53 get() { 54 return url.href; 55 }, 56 set() { 57 throw new DOMException(`Cannot set "location.href".`, 'NotSupportedError'); 58 }, 59 enumerable: true, 60 }, 61 origin: { 62 get() { 63 return url.origin; 64 }, 65 enumerable: true, 66 }, 67 pathname: { 68 get() { 69 return url.pathname; 70 }, 71 set() { 72 throw new DOMException(`Cannot set "location.pathname".`, 'NotSupportedError'); 73 }, 74 enumerable: true, 75 }, 76 port: { 77 get() { 78 return url.port; 79 }, 80 set() { 81 throw new DOMException(`Cannot set "location.port".`, 'NotSupportedError'); 82 }, 83 enumerable: true, 84 }, 85 protocol: { 86 get() { 87 return url.protocol; 88 }, 89 set() { 90 throw new DOMException(`Cannot set "location.protocol".`, 'NotSupportedError'); 91 }, 92 enumerable: true, 93 }, 94 search: { 95 get() { 96 // @ts-expect-error 97 return url.search; 98 }, 99 set() { 100 throw new DOMException(`Cannot set "location.search".`, 'NotSupportedError'); 101 }, 102 enumerable: true, 103 }, 104 ancestorOrigins: { 105 get() { 106 return { 107 length: 0, 108 item: () => null, 109 contains: () => false, 110 }; 111 }, 112 enumerable: true, 113 }, 114 assign: { 115 value: function assign() { 116 throw new DOMException(`Cannot call "location.assign()".`, 'NotSupportedError'); 117 }, 118 enumerable: true, 119 }, 120 reload: { 121 value: function reload() { 122 if (process.env.NODE_ENV !== 'production') { 123 // NOTE: This does change how native fast refresh works. The upstream metro-runtime will check 124 // if `location.reload` exists before falling back on an implementation that is nearly identical to 125 // this. The main difference is that on iOS there is a "reason" message sent, but at the time of writing 126 // this, that message is unused (ref: `RCTTriggerReloadCommandNotification`). 127 const DevSettings = require('react-native') 128 .DevSettings; 129 return DevSettings.reload(); 130 } 131 else { 132 throw new DOMException(`Cannot call "location.reload()".`, 'NotSupportedError'); 133 } 134 }, 135 enumerable: true, 136 }, 137 replace: { 138 value: function replace() { 139 throw new DOMException(`Cannot call "location.replace()".`, 'NotSupportedError'); 140 }, 141 enumerable: true, 142 }, 143 toString: { 144 value: function toString() { 145 return url.href; 146 }, 147 enumerable: true, 148 }, 149 [Symbol.for('Expo.privateCustomInspect')]: { 150 value(inspect) { 151 const object = { 152 hash: this.hash, 153 host: this.host, 154 hostname: this.hostname, 155 href: this.href, 156 origin: this.origin, 157 pathname: this.pathname, 158 port: this.port, 159 protocol: this.protocol, 160 search: this.search, 161 }; 162 return `${this.constructor.name} ${inspect(object)}`; 163 }, 164 }, 165 }); 166 } 167} 168Object.defineProperties(Location.prototype, { 169 [Symbol.toString()]: { 170 value: 'Location', 171 configurable: true, 172 }, 173}); 174let location = undefined; 175export function setLocationHref(href) { 176 location = new Location(href); 177} 178export function install() { 179 Object.defineProperty(global, 'Location', { 180 value: Location, 181 configurable: true, 182 writable: true, 183 }); 184 Object.defineProperty(window, 'location', { 185 get() { 186 return location; 187 }, 188 set() { 189 throw new DOMException(`Cannot set "location".`, 'NotSupportedError'); 190 }, 191 enumerable: true, 192 }); 193} 194//# sourceMappingURL=Location.native.js.map