;; -*- firestarter: "chicken-spock -o %s.js %f"; firestarter-type: failure -*- (define documents #f) (define last-place #f) (define index #f) (define frame #f) (define stylesheet #f) (define (init json) (let* ((data (%inline JSON.parse json))) (set! documents (.documents data)) (set! last-place (.lastPlace data)) (set! index (if last-place (vector-ref last-place 0) 0)) (set! frame (%inline document.getElementById "content")) (set! stylesheet (.stylesheet data)) (update-document!) (set! (.onload frame) (callback init-frame)) (%inline .focus frame))) (set! window.external.init (callback init)) (define (maybe-set-scroll!) (when last-place (%inline .contentWindow.scroll frame 0 (vector-ref last-place 1)) ;; HACK: restore the last location only once (set! last-place #f))) (define (update-document!) (let ((document (vector-ref documents index))) (set! (.src frame) (jstring (string-append "/documents/" document))))) (define (init-frame) (%inline .addEventListener (.contentDocument frame) "keydown" (callback key-handler)) (if stylesheet (inject-style! (.contentDocument.head frame) stylesheet) (maybe-set-scroll!))) (define (inject-style! element stylesheet) (let ((style (%inline "document.createElement" "style"))) (set! (.textContent style) stylesheet) ;; there is a custom stylesheet, so set scroll after it's loaded ;; in case it changed the iframe height (set! (.onload style) (callback maybe-set-scroll!)) (%inline ".appendChild" element style))) (define (prev-document!) (when (> index 0) (set! index (- index 1)) (update-document!))) (define (next-document!) (when (< index (- (.length documents) 1)) (set! index (+ index 1)) (update-document!))) (define (maybe-next-document! event) (let ((body (.contentDocument.body frame)) (window (.contentWindow frame))) (when (>= (+ (.scrollY window) (.scrollHeight frame)) (.scrollHeight body)) (.preventDefault event) (next-document!)))) (define (key-handler event) (let ((key-code (.keyCode event)) (shift? (.shiftKey event))) (cond ((or (= key-code 81) (= key-code 27)) ;; Q / ESC (let* ((scroll-offset (.contentWindow.scrollY frame)) (message (string-append "quit:" (number->string index) ":" (number->string scroll-offset)))) (%inline window.external.invoke (jstring message)))) ((and (= key-code 32) (not shift?)) ;; SPC (maybe-next-document! event)) ((= key-code 80) ;; P (prev-document!)) ((= key-code 78) ;; N (next-document!)))))