Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Error: Chromote: timed out waiting for event Page.loadEventFired #76

Open
beausoleilmo opened this issue May 13, 2024 · 5 comments
Open

Comments

@beausoleilmo
Copy link

beausoleilmo commented May 13, 2024

I'm using renderthis::to_pdf to print a pdf from an HTML file. However, I get Error: Chromote: timed out waiting for event Page.loadEventFired. Is there a way to fix this? The HTML file is 33.9MB.

library(pdftools)    # version 3.4.0 
library(renderthis) # version 0.2.1
library(chromote)   # version 0.2.0.9

renderthis::to_pdf(from = "presentation/my_pres.html",
                   to = "presentation/my_pres.pdf",
                   delay = 1, 
                   complex_slides = TRUE,
                   partial_slides = TRUE)
R version 4.3.1 (2023-06-16)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Sonoma 14.3.1

Chrome (Version 124.0.6367.201 (Official Build) (arm64)) is installed on my computer.

When setting complex_slides = FALSE and partial_slides = FALSE, I only get the first slide.

@jhelvy
Copy link
Owner

jhelvy commented May 13, 2024

I sometimes get this as well with larger files. Can you check that things work with a relatively simple and small html page? Often times I just quit RStudio and restart and try again and it works.

@beausoleilmo
Copy link
Author

I restarted my computer, RStudio but still no luck.

This is an attempt at making it work and probably not a fix. I commented a bunch of lines (e.g., b$Page$loadEventFired()) to diagnose the problem and now I'm able to make it work. Don't know why specifically, but I'm glad I'm able to export the slides now. Also, it appeared that the get.ratio() command was reading the information too fast and so wasn't returning the ratio of the presentation. So I added a wait time of 10 seconds for the presentation to load Sys.sleep(10).

to_pdf_complex_mod = function (input, output_file, partial_slides, delay) 
{
  if (!requireNamespace("chromote", quietly = TRUE)) {
    stop("`chromote` is required: devtools::install_github('rstudio/chromote')")
  }
  if (!requireNamespace("pdftools", quietly = TRUE)) {
    stop("`pdftools` is required: install.packages('pdftools')")
  }
  b <- chromote::ChromoteSession$new()
  on.exit(b$close(), add = TRUE)
  b$Page$navigate(input, wait_ = TRUE)
  # b$Page$loadEventFired()
  has_remark <- b$Runtime$evaluate("typeof slideshow !== 'undefined'")$result$value
  # if (!has_remark) {
  #   stop("Input does not appear to be xaringan or quarto slides: ", 
  #        input)
  # }
  current_slide <- function() {
    x <- b$Runtime$evaluate("slideshow.getCurrentSlideIndex()")$result$value
    as.integer(x) + 1L
  }
  slide_is_continuation <- function() {
    b$Runtime$evaluate("document.querySelector('.remark-visible').matches('.has-continuation')")$result$value
  }
  hash_current_slide <- function() {
    digest::digest(b$Runtime$evaluate("document.querySelector('.remark-visible').innerHTML")$result$value)
  }
  get_ratio <- function() {
    r <- b$Runtime$evaluate("slideshow.getRatio()")$result$value
    r <- lapply(strsplit(r, ":"), as.integer)
    width <- r[[1]][1]
    height <- r[[1]][2]
    page_width <- 8/width * width
    list(width = as.integer(908 * width/height), height = 681L, 
         page = list(width = page_width, height = page_width * 
                       height/width))
  }
  message("Waiting to load...") # ADDED 
  Sys.sleep(10)                 # ADDED 
  slide_size <- get_ratio()
  expected_slides <- as.integer(b$Runtime$evaluate("slideshow.getSlideCount()")$result$value)
  max_slides <- expected_slides * 4
  # b$Browser$setWindowBounds(1, bounds = list(width = slide_size$width,
  #                                            height = slide_size$height))
  b$Emulation$setEmulatedMedia("print")
  b$Runtime$evaluate(paste0("let style = document.createElement('style')\n", 
                            "style.innerText = '@media print { ", ".remark-slide-container:not(.remark-visible){ display:none; }", 
                            if (partial_slides) 
                              " .has-continuation { display: block }", "}'\n", 
                            "document.head.appendChild(style)"))
  # proc <- cli_build_start(input, output_file)
  pb <- progress::progress_bar$new(format = "Slide :slide (:part) [:bar] Eta: :eta", 
                                   total = expected_slides)
  idx_slide <- current_slide()
  last_hash <- ""
  idx_part <- 0L
  pdf_files <- c()
  for (i in seq_len(max_slides)) {
    if (i > 1) {
      b$Input$dispatchKeyEvent("rawKeyDown", windowsVirtualKeyCode = 39, 
                               code = "ArrowRight", key = "ArrowRight", wait_ = TRUE)
    }
    if (current_slide() == idx_slide) {
      step <- 0L
      idx_part <- idx_part + 1L
    }
    else {
      step <- 1L
      idx_part <- 1L
    }
    idx_slide <- current_slide()
    pb$tick(step, tokens = list(slide = idx_slide, part = idx_part))
    if (!isTRUE(partial_slides) && slide_is_continuation()) 
      next
    Sys.sleep(delay)
    this_hash <- hash_current_slide()
    if (identical(last_hash, this_hash)) 
      break
    last_hash <- this_hash
    pdf_file_promise <- b$Page$printToPDF(landscape = TRUE, 
                                          printBackground = TRUE, paperWidth = 12, paperHeight = 9, 
                                          marginTop = 0, marginRight = 0, marginBottom = 0, 
                                          marginLeft = 0, pageRanges = "1", preferCSSPageSize = TRUE, 
                                          wait_ = FALSE)$then(function(value) {
                                            filename <- tempfile(fileext = ".pdf")
                                            writeBin(jsonlite::base64_dec(value$data), filename)
                                            filename
                                          })
    pdf_files <- c(pdf_files, b$wait_for(pdf_file_promise))
  }
  pdftools::pdf_combine(pdf_files, output = output_file)
  fs::file_delete(pdf_files)
  # cli::cli_process_done(proc)
  invisible(output_file)
  message("Done!") # ADDED 
}

I used the input "file:///pathto/presentation/my_pres.html#1". I hope this can help in finding a solution.

@jhelvy
Copy link
Owner

jhelvy commented May 13, 2024

It works! @gadenbuie what do you think about adding an argument like sleep = 0 or load_sleep = 0 so users can optionally provide a sleep delay to allow the slides to load? Either that or perhaps we could find some way of checking that the page has loaded before going forward. That's probably the better solution as the sleep thing is a bit hacky, but I don't readily know how to confirm that a page has loaded.

@beausoleilmo
Copy link
Author

Good! Actually, I tried a bunch of values for sleep time. 8 was working, but I went for 10 to be sure. I was wondering if there was a function that could indeed confirm that the page is loaded... but im not aware of any. Also, not sure why b$Page$loadEventFired() is causing the Error: Chromote: timed out waiting for event Page.loadEventFired and if it's needed for the function to work.

@gadenbuie
Copy link
Collaborator

I added an option in chromote called chromote.timeout, but unfortunately it doesn't set the timeout in the right place to affect this call. I think it should though, so I'll look into fixing that.

Even then, you probably don't want to elevate every timeout, just the page load timeout. The easiest way to do that would be to add an argument like timeout_page_load to to_pdf_complex() that gets passed to b$Page$LoadEventFired(timeout_ = timeout_page_load).

@beausoleilmo if you could try that out and let us know if it works, that'd be great! I'd also be very happy to review a PR 😉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants