     "(" + textInputTypes.map((type) -> '@type="' + type + '"').join(" or ") + "or not(@type))" +
     " and not(@disabled or @readonly)]",
     "textarea", "*[@contenteditable='' or translate(@contenteditable, 'TRUE', 'true')='true']"]
-  DomUtils?.makeXPath(inputElements)
+  if DomUtils?
+    DomUtils.makeXPath(inputElements)
 )()
 
 # used by the findAndFollow* functions.

      else
        url = "view-source:" + url
      chrome.runtime.sendMessage {handler: "openUrlInNewTab", url}

  copyCurrentUrl: ->
    chrome.runtime.sendMessage { handler: "getCurrentTabUrl" }, (url) ->
      HUD.copyToClipboard url
      url = url[0..25] + "...." if 28 < url.length
      HUD.showForDuration("Yanked #{url}", 2000)

  openCopiedUrlInNewTab: (count) ->
    HUD.pasteFromClipboard (url) ->
      chrome.runtime.sendMessage { handler: "openUrlInNewTab", url, count }

  openCopiedUrlInCurrentTab: ->
    HUD.pasteFromClipboard (url) ->
      chrome.runtime.sendMessage { handler: "openUrlInCurrentTab", url }

  # Mode changes.
  enterInsertMode: ->

    linkMatches = false
    for linkString in linkStrings
      if link.innerText.toLowerCase().indexOf(linkString) != -1 ||
          (link.value && link.value.includes && link.value.includes(linkString))
        linkMatches = true
        break
    unless linkMatches
      continue

    candidateLinks.push(link)

  if (candidateLinks.length == 0)
    return

  for link in candidateLinks
    link.wordCount = link.innerText.trim().split(/\s+/).length
