Data + Code Medien + Internet

MacOS: Firefox Browser with Real Fullscreen

On a Mac, the Firefox Browser can’t be used in a real fullscreen. This means: Even when you use the default fullscreen option with cmd+shift+f, the address bar and tabs remain visible. The internet says, this is a Firefox bug on MacOS.

The solution is to use UserChrome.css, a way to customize a modern Firefox Browser.

Four steps:

  • Find your profile folder by typing about:support into the address bar. There you can find the path.
  • Inside this folder, create a subfolder calles chrome and inside a file userChrome.css.
  • Copy the following CSS code into userChrome.css:
#navigator-toolbox[inFullscreen] {
    height: 0.5rem;
    margin-bottom: -0.5rem;
    opacity: 0;
    overflow: hidden;

#navigator-toolbox[inFullscreen]:focus-within {
     * Add some padding between the navbar and the top screen edge 
     * to be more visible while the macOS hidden menu bar shows up. 
     * The macOS menubar will hide after a few seconds.
    padding-top: 1rem;
    height: auto;
    margin-bottom: 0rem;
    opacity: 1;
    overflow: visible;
  • Close and restart Firefox.


Data + Code

How to Export Your Mozilla Firefox History as a Dataframe in R

The goal of this post is to export a Mozilla Firefox Browser history and import in R as a dataframe.

Browser history data

Firefox saves your browsing history in a file called places.sqlite. This file contains several tables, like bookmarks, favicons or the history.

To get a dataframe with visited websites, you need two tables from the sqlite file:

  1. moz_historyvisits: it contains all websites you visited with time and date. All websites have an id instead of a readable URL.
  2. moz_places: it contains the translation of the websites id and its actual URL.

More on the database schema:

Import the data into R

sqlite files can be imported with the package RSQLite.

First, find the places.sqlite on your computer. You can get the path, by visiting about:support in Firefox and looking for the Profiles directory.


# connect to database
con <- dbConnect(drv = RSQLite::SQLite(), 
                 dbname = "path/to/places.sqlite",

# get all tables
tables <- dbListTables(con)

# remove internal tables
tables <- tables[tables != "sqlite_sequence"]
# create a list of dataframes
list_of_df <- purrr::map(tables, ~{
  dbGetQuery(conn = con, statement=paste0("SELECT * FROM '", .x, "'"))
# get the list of dataframes some names
names(list_of_df) <- tables

Extract browser history

Next, we extract the two tables with the information we need, join them and keep only the visited url, the time and the URL id.

There are two caveats:

  1. The timestamps are saved in the PRTime format, which is basically an unix timestamp and you have to convert it in a human-readable format
  2. Extract the domain of a URL using the urltools package, e.g. getting twitter.com instead of twitter.com/cutterkom
# get the two dataframes 
history <- list_of_df[["moz_historyvisits"]]
urls <- list_of_df[["moz_places"]]

df <- left_join(history, urls, by = c("place_id" = "id")) %>% 
  select(place_id, url, visit_date) %>% 
  # convert the unix timestamp
  mutate(date = as.POSIXct(as.numeric(visit_date)/1000000, origin = '1970-01-01', tz = 'GMT'),
  # extract the domains from the URL, e.g. `twitter.com` instead of `twitter.com/cutterkom`
         domain = str_remove(urltools::domain(url), "www\\."))