src/Pure/System/web_app.scala
changeset 80256 df8fa0393127
parent 80249 58881e1e4a75
child 80257 96cb31f0bbdf
equal deleted inserted replaced
80255:1844c169e360 80256:df8fa0393127
   399 
   399 
   400     sealed abstract class API_Endpoint(path: Path, method: String = "GET")
   400     sealed abstract class API_Endpoint(path: Path, method: String = "GET")
   401       extends Endpoint(paths.api_path(path, external = false), method) {
   401       extends Endpoint(paths.api_path(path, external = false), method) {
   402 
   402 
   403       def html_content(content: XML.Body, auto_reload: Boolean = false): HTTP.Response = {
   403       def html_content(content: XML.Body, auto_reload: Boolean = false): HTTP.Response = {
   404         val head1 =
   404         val auto_reload_script = HTML.script("""
   405           if (!auto_reload) head
       
   406           else HTML.script("""
       
   407 var state = null
   405 var state = null
   408 function heartbeat() {
   406 function heartbeat() {
   409   fetch(window.location, { method: "HEAD" }).then((http_res) => {
   407   fetch(window.location, { method: "HEAD" }).then((http_res) => {
   410     if (http_res.status === 200) {
   408     if (http_res.status === 200) {
   411       const new_state = http_res.headers.get("Content-Digest")
   409       const new_state = http_res.headers.get("Content-Digest")
   413       else if (state !== new_state) window.location.reload()
   411       else if (state !== new_state) window.location.reload()
   414     }
   412     }
   415     setTimeout(heartbeat, 1000)
   413     setTimeout(heartbeat, 1000)
   416   })
   414   })
   417 }
   415 }
   418 heartbeat()""") :: head
   416 heartbeat()""")
   419 
   417 
   420         val on_load = "parent.postMessage(document.documentElement.scrollHeight, '*')"
   418         val resize_script = HTML.script("""
       
   419 function post_height() {
       
   420   const scroll_bar_height = window.innerHeight - document.documentElement.clientHeight
       
   421   parent.postMessage(document.documentElement.scrollHeight + scroll_bar_height, '*')
       
   422 }
       
   423 window.addEventListener("resize", (event) => { post_height() })
       
   424 """)
       
   425 
       
   426         val head1 = (if (auto_reload) List(auto_reload_script) else Nil) ::: resize_script :: head
   421 
   427 
   422         html(
   428         html(
   423           XML.elem("head", HTML.head_meta :: head1),
   429           XML.elem("head", HTML.head_meta :: head1),
   424           XML.Elem(Markup("body", List("onLoad" -> on_load)), content))
   430           XML.Elem(Markup("body", List("onLoad" -> "post_height()")), content))
   425       }
   431       }
   426     }
   432     }
   427 
   433 
   428     private def query_params(request: HTTP.Request): Properties.T = {
   434     private def query_params(request: HTTP.Request): Properties.T = {
   429       def decode(s: String): Option[Properties.Entry] =
   435       def decode(s: String): Option[Properties.Entry] =