If you don't mind some ugly code, I whipped up something that seems to work:
(Disclaimer: I don't know Javascript, but it works on what I've tested)
(defun my/js2-indent () "If a period is found on the previous line and it's not in a comment or a string, then indent the current line to the last period on that line, else indent normally." (interactive) ;; find column of . if any (let ((col (catch 'found (save-excursion (back-to-indentation) ;; if the start of the line is not a period (46) ;; or is in a comment then indent normally (when (or (not (eq (char-after) 46)) (nth 4 (syntax-ppss))) (throw 'found nil)) (end-of-line 0) (backward-char) ;; if the previous line ends with a comment ;; then skip the comment (if (nth 4 (syntax-ppss (1- (point)))) (progn (forward-line) (forward-comment -1)) ;; syntax-ppss moved point backward ;; so go forward a char (forward-char)) ;; while the char isn't a newline (10) (while (not (eq (char-after) 10)) ;; break if it's a period (46) ;; and not in a string (if (and (eq (char-after) 46) (not (nth 3 (syntax-ppss)))) (throw 'found (current-column)) (backward-char))) nil)))) ;; indent to the found column, otherwise indent normally (if col (indent-line-to col) (js2-indent-line))))
Then to set the indenting so that indent-region or electric-indent-mode don't undo the changes, set the variable indent-line-function to it:
(add-hook 'js2-mode-hook (lambda () (setq indent-line-function #'my/js2-indent)))