function gotoIRCURL()

in suite/chatzilla/content/static.js [1492:1723]


function gotoIRCURL(url, e) {
  var urlspec = url;
  if (typeof url == "string") {
    url = parseIRCURL(url);
  }

  if (!url) {
    Services.prompt.alert(
      window,
      MSG_ALERT,
      getMsg(MSG_ERR_BAD_IRCURL, urlspec)
    );
    return;
  }

  if (!url.host) {
    /* focus the *client* view for irc:, irc:/, and irc:// (the only irc
     * urls that don't have a host.  (irc:/// implies a connect to the
     * default network.)
     */
    client.pendingViewContext = e;
    dispatch("client");
    delete client.pendingViewContext;
    return;
  }

  let isSecure = url.scheme == "ircs";
  let network;
  // Make sure host is in lower case.
  url.host = url.host.toLowerCase();

  // Convert a request for a server to a network if we know it.
  if (url.isserver) {
    for (var n in client.networks) {
      network = client.networks[n];
      for (var s in network.servers) {
        let server = network.servers[s];
        if (
          server.hostname == url.host &&
          server.isSecure == isSecure &&
          (!url.port || server.port == url.port)
        ) {
          url.isserver = false;
          url.host = network.canonicalName;
          if (!url.port) {
            url.port = server.port;
          }
          break;
        }
      }
      if (!url.isserver) {
        break;
      }
    }
  }

  let name = url.host;
  network = client.getNetwork(name);

  if (url.isserver) {
    let found = false;
    if (network) {
      for (let s in network.servers) {
        let server = network.servers[s];
        if (
          server.isSecure == isSecure &&
          (!url.port || server.port == url.port)
        ) {
          found = true;
          if (!url.port) {
            url.port = server.port;
          }
          break;
        }
      }
    }

    // If still no port set, use the default.
    if (!url.port) {
      url.port = isSecure ? 6697 : 6667;
    }

    if (!found) {
      name += ":" + url.port;

      // If there is no temporary network for this server:port, create one.
      if (!client.getNetwork(name)) {
        let server = { name: url.host, port: url.port, isSecure };
        client.addNetwork(name, [server], true);
      }
      network = client.getNetwork(name);
    }
  } else {
    // There is no network called this, sorry.
    if (!network) {
      display(getMsg(MSG_ERR_UNKNOWN_NETWORK, name));
      return;
    }
  }

  // We should only prompt for a password if we're not connected.
  if (network.state == NET_OFFLINE) {
    // Check for a network password.
    url.pass = client.tryToGetLogin(
      network.getURL(),
      "serv",
      "*",
      url.pass,
      url.needpass,
      getMsg(MSG_HOST_PASSWORD, network.getURL())
    );
  }

  // Adjust secure setting for temporary networks (so user can override).
  if (network.temporary) {
    network.serverList[0].isSecure = url.scheme == "ircs";
  }

  // Adjust password for all servers (so user can override).
  if (url.pass) {
    for (var s in network.servers) {
      network.servers[s].password = url.pass;
    }
  }

  // Start the connection and pend anything else if we're not ready.
  if (network.state != NET_ONLINE) {
    client.pendingViewContext = e;
    if (!network.isConnected()) {
      client.connectToNetwork(network, url.scheme == "ircs");
    } else {
      dispatch("create-tab-for-view", { view: network });
      dispatch("set-current-view", { view: network });
    }
    delete client.pendingViewContext;

    if (!url.target) {
      return;
    }

    // We're not completely online, so everything else is pending.
    if (!("pendingURLs" in network)) {
      network.pendingURLs = [];
    }
    network.pendingURLs.unshift({ url, e });
    return;
  }

  // We're connected now, process the target.
  if (url.target) {
    var targetObject;
    var ev;
    if (url.isnick) {
      /* url points to a person. */
      var nick = url.target;
      var ary = url.target.split("!");
      if (ary) {
        nick = ary[0];
      }

      client.pendingViewContext = e;
      targetObject = network.dispatch("query", { nickname: nick });
      delete client.pendingViewContext;
    } else {
      /* url points to a channel */
      var key;
      var serv = network.primServ;
      var target = url.target;
      if (url.charset) {
        var chan = new CIRCChannel(
          serv,
          target,
          fromUnicode(target, url.charset)
        );
        chan.prefs.charset = url.charset;
      } else {
        // Must do this the hard way... we have the server's format
        // for the channel name here, and all our commands only work
        // with the Unicode forms.

        /* If we don't have a valid prefix, stick a "#" on it.
         * NOTE: This is always a "#" so that URLs may be compared
         * properly without involving the server (e.g. off-line).
         */
        if (
          !["#", "&", "+", "!"].includes(target[0]) &&
          !serv.channelTypes.includes(target[0])
        ) {
          target = "#" + target;
        }

        var chan = new CIRCChannel(serv, null, target);
      }

      if (url.needkey && !chan.joined) {
        if (url.key) {
          key = url.key;
        } else {
          key = window.promptPassword(getMsg(MSG_URL_KEY, url.spec));
        }
      }
      client.pendingViewContext = e;
      let d = { channelToJoin: chan, key };
      targetObject = network.dispatch("join", d);
      delete client.pendingViewContext;

      if (!targetObject) {
        return;
      }
    }

    if (url.msg) {
      client.pendingViewContext = e;
      var msg;
      if (url.msg.startsWith("\01ACTION")) {
        msg = filterOutput(url.msg, "ACTION", targetObject);
        targetObject.display(msg, "ACTION", "ME!", client.currentObject);
      } else {
        msg = filterOutput(url.msg, "PRIVMSG", targetObject);
        targetObject.display(msg, "PRIVMSG", "ME!", client.currentObject);
      }
      targetObject.say(msg);
      dispatch("set-current-view", { view: targetObject });
      delete client.pendingViewContext;
    }
  } else {
    client.pendingViewContext = e;
    dispatch("create-tab-for-view", { view: network });
    dispatch("set-current-view", { view: network });
    delete client.pendingViewContext;
  }
}