Function: js--read-tab

js--read-tab is a byte-compiled function defined in js.el.gz.

Signature

(js--read-tab PROMPT)

Documentation

Read a Mozilla tab with prompt PROMPT.

Return a cons of (TYPE . OBJECT). TYPE is either window or tab, and OBJECT is a JavaScript handle to a ChromeWindow or a browser, respectively.

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/js.el.gz
(defun js--read-tab (prompt)
  "Read a Mozilla tab with prompt PROMPT.
Return a cons of (TYPE . OBJECT).  TYPE is either `window' or
`tab', and OBJECT is a JavaScript handle to a ChromeWindow or a
browser, respectively."

  ;; Prime IDO
  (unless ido-mode
    (ido-mode 1)
    (ido-mode -1))

  (with-js
   (let ((tabs (js--get-tabs)) selected-tab-cname
         selected-tab prev-hitab)

     ;; Disambiguate names
     (setq tabs
           (cl-loop with tab-names = (make-hash-table :test 'equal)
                    for tab in tabs
                    for cname = (format "%s (%s)"
                                        (cl-second tab) (cl-first tab))
                    for num = (cl-incf (gethash cname tab-names -1))
                    if (> num 0)
                    do (setq cname (format "%s <%d>" cname num))
                    collect (cons cname tab)))

     (cl-labels
         ((find-tab-by-cname
           (cname)
           (cl-loop for tab in tabs
                    if (equal (car tab) cname)
                    return (cdr tab)))

          (mogrify-highlighting
           (hitab unhitab)

           ;; Hack to reduce the number of
           ;; round-trips to mozilla
           (let (cmds)
             (cond
              ;; Highlighting tab
              ((cl-fourth hitab)
               (push '(js! ((cl-fourth hitab) "setAttribute")
                       "style"
                       "color: red; font-weight: bold")
                     cmds)

               ;; Highlight window proper
               (push '(js! ((cl-third hitab)
                            "setAttribute")
                       "style"
                       "border: 8px solid red")
                     cmds)

               ;; Select tab, when appropriate
               (when js-js-switch-tabs
                 (push
                  '(js> ((cl-fifth hitab) "selectedTab") (cl-fourth hitab))
                  cmds)))

              ;; Highlighting whole window
              ((cl-third hitab)
               (push '(js! ((cl-third hitab) "document"
                            "documentElement" "setAttribute")
                       "style"
                       (concat "-moz-appearance: none;"
                               "border: 8px solid red;"))
                     cmds)))

             (cond
              ;; Unhighlighting tab
              ((cl-fourth unhitab)
               (push '(js! ((cl-fourth unhitab) "setAttribute") "style" "")
                     cmds)
               (push '(js! ((cl-third unhitab) "setAttribute") "style" "")
                     cmds))

              ;; Unhighlighting window
              ((cl-third unhitab)
               (push '(js! ((cl-third unhitab) "document"
                            "documentElement" "setAttribute")
                       "style" "")
                     cmds)))

             (eval `(with-js
                        (js-list ,@(nreverse cmds)))
                   t)))

          (command-hook
           ()
           (let* ((tab (find-tab-by-cname (car ido-matches))))
             (mogrify-highlighting tab prev-hitab)
             (setq prev-hitab tab)))

          (setup-hook
           ()
           ;; Fiddle with the match list a bit: if our first match
           ;; is a tabbrowser window, rotate the match list until
           ;; the active tab comes up
           (let ((matched-tab (find-tab-by-cname (car ido-matches))))
             (when (and matched-tab
                        (null (cl-fourth matched-tab))
                        (equal "navigator:browser"
                               (js! ((cl-third matched-tab)
                                     "document"
                                     "documentElement"
                                     "getAttribute")
                                    "windowtype")))

               (cl-loop with tab-to-match = (js< (cl-third matched-tab)
                                                 "gBrowser"
                                                 "selectedTab")

                        for match in ido-matches
                        for candidate-tab = (find-tab-by-cname match)
                        if (eq (cl-fourth candidate-tab) tab-to-match)
                        do (setq ido-cur-list
                                 (ido-chop ido-cur-list match))
                        and return t)))

           (add-hook 'post-command-hook #'command-hook t t)))


       (unwind-protect
           ;; FIXME: Don't impose IDO on the user.
           (setq selected-tab-cname
                 (let ((ido-minibuffer-setup-hook
                        (cons #'setup-hook ido-minibuffer-setup-hook)))
                   (ido-completing-read
                    prompt
                    (mapcar #'car tabs)
                    nil t nil
                    'js-read-tab-history)))

         (when prev-hitab
           (mogrify-highlighting nil prev-hitab)
           (setq prev-hitab nil)))

       (add-to-history 'js-read-tab-history selected-tab-cname)

       (setq selected-tab (cl-loop for tab in tabs
                                   if (equal (car tab) selected-tab-cname)
                                   return (cdr tab)))

       (cons (if (cl-fourth selected-tab) 'browser 'window)
             (cl-third selected-tab))))))