Search code examples
javascripthostnamewindow.location

Can I safely rely on hostname only ever being undefined for local files (i.e. navigating to a local file)?


I'm creating a web extension that runs on every page but only works in certain contexts. Here is the isSupported() method:

// return a boolean value that is true if the domain/page is supported, element name matches
// supported types, and content is marked as spell checkable
function isSupported (node, hostname) {
  const supportedNodeNames = ['TEXTAREA', 'DIV']
  const supportedDomains = ['mail.google.com', 'github.com']

  if (node.spellcheck && node.isContentEditable) {
    if (node.nodeName === 'TEXTAREA') {
      return true
    }

    if (supportedNodeNames.contains(node.nodeName) && supportedDomains.contains(hostname)) {
      return true
    }
  }

  return false
}

This code unfortunately stops the extension from running on my local test page, i.e. when the URI is file:///home/username/github/multi-dict/test_page/test-page.html

Can I safely rely on window.location.hostname being undefined* and allow the extension to run when it is? I checked the docs over at MDN and the spec but it wasn't quite clear to me under what exact contexts the hostname would be undefined.

Thanks in advance!

*It's actually an empty string, left in original description for reader/answer context. So the question is - can I safely rely on window.location.hostname only ever being empty for a local file the browser has opened - no local webserver is running.


Solution

  • hostname is defined as a string (MDN, spec), so it can't have the value undefined. It's an empty string (""), not undefined, on every browser I've tried (Chrome, Firefox, IE, Edge). If you think it's undefined on some browsers, you could just do a falsy check:

    if (location.hostname) {
        // It has a non-blank value
    } else {
        // Its value is falsy (probably "", perhaps undefined)
    }
    

    But I don't think it's ever undefined. From the spec:

    The hostname attribute's getter must run these steps:

    1. If this Location object's relevant Document is non-null and its origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.

    2. If this Location object's url's host is null, return the empty string.

    3. Return this Location object's url's host, serialized.

    (my emphasis)

    The host of local URLs is null, so the emphasized part of Step 2 applies.