2019-02-03 12:51:15 +00:00
/ * \
title : $ : / p l u g i n s / t i d d l y w i k i / b r o w s e r - s t o r a g e / s t a r t u p . j s
type : application / javascript
module - type : startup
Startup initialisation
\ * /
( function ( ) {
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict" ;
// Export name and synchronous status
exports . name = "browser-storage" ;
exports . platforms = [ "browser" ] ;
2020-08-11 11:32:39 +00:00
exports . after = [ "startup" ] ;
2019-02-03 12:51:15 +00:00
exports . synchronous = true ;
2019-03-01 22:06:14 +00:00
var ENABLED _TITLE = "$:/config/BrowserStorage/Enabled" ,
2023-06-13 09:50:00 +00:00
SAVE _FILTER _TITLE = "$:/config/BrowserStorage/SaveFilter" ,
PERSISTED _STATE _TITLE = "$:/info/browser/storage/persisted" ;
2023-01-17 22:12:18 +00:00
var BrowserStorageUtil = require ( "$:/plugins/tiddlywiki/browser-storage/util.js" ) . BrowserStorageUtil ;
2019-02-07 14:35:25 +00:00
2019-02-03 12:51:15 +00:00
exports . startup = function ( ) {
2019-02-07 14:35:25 +00:00
var self = this ;
2024-08-20 15:33:07 +00:00
// If not exists, add ENABLED tiddler with default value "yes"
if ( ! $tw . wiki . getTiddler ( ENABLED _TITLE ) ) {
$tw . wiki . addTiddler ( { title : ENABLED _TITLE , text : "yes" } ) ;
}
2019-02-03 12:51:15 +00:00
// Compute our prefix for local storage keys
2019-02-08 15:19:20 +00:00
var prefix = "tw5#" + window . location . pathname + "#" ;
2019-02-03 17:29:32 +00:00
// Make a logger
var logger = new $tw . utils . Logger ( "browser-storage" , {
colour : "cyan"
} ) ;
2023-01-17 22:12:18 +00:00
// Add browserStorage object to $tw
$tw . browserStorage = new BrowserStorageUtil ( $tw . wiki , {
enabledTitle : ENABLED _TITLE ,
prefix : prefix ,
logger : logger
} ) ;
2019-02-07 14:35:25 +00:00
// Function to compile the filter
var filterFn ,
compileFilter = function ( ) {
filterFn = $tw . wiki . compileFilter ( $tw . wiki . getTiddlerText ( SAVE _FILTER _TITLE ) ) ;
}
compileFilter ( ) ;
2019-03-01 22:06:14 +00:00
// Listen for tm-clear-browser-storage messages
$tw . rootWidget . addEventListener ( "tm-clear-browser-storage" , function ( event ) {
$tw . wiki . addTiddler ( { title : ENABLED _TITLE , text : "no" } ) ;
2023-01-17 22:12:18 +00:00
$tw . browserStorage . clearLocalStorage ( ) ;
2019-03-01 22:06:14 +00:00
} ) ;
2024-09-15 09:48:08 +00:00
// Seperate clear cookie and disable action
$tw . rootWidget . addEventListener ( "tm-delete-browser-storage" , function ( event ) {
$tw . browserStorage . clearLocalStorage ( ) ;
} ) ;
$tw . rootWidget . addEventListener ( "tm-disable-browser-storage" , function ( event ) {
$tw . wiki . addTiddler ( { title : ENABLED _TITLE , text : "no" } ) ;
} ) ;
2023-06-13 09:50:00 +00:00
// Helpers for protecting storage from eviction
var setPersistedState = function ( state ) {
$tw . wiki . addTiddler ( { title : PERSISTED _STATE _TITLE , text : state } ) ;
} ,
requestPersistence = function ( ) {
setPersistedState ( "requested" ) ;
navigator . storage . persist ( ) . then ( function ( persisted ) {
console . log ( "Request for persisted storage " + ( persisted ? "granted" : "denied" ) ) ;
setPersistedState ( persisted ? "granted" : "denied" ) ;
} ) ;
} ,
persistPermissionRequested = false ,
requestPersistenceOnFirstSave = function ( ) {
$tw . hooks . addHook ( "th-saving-tiddler" , function ( tiddler ) {
2024-08-20 15:33:07 +00:00
if ( ! persistPermissionRequested ) {
2023-06-13 09:50:00 +00:00
var filteredChanges = filterFn . call ( $tw . wiki , function ( iterator ) {
iterator ( tiddler , tiddler . getFieldString ( "title" ) ) ;
} ) ;
2024-08-20 15:33:07 +00:00
if ( filteredChanges . length > 0 ) {
2023-06-13 09:50:00 +00:00
// The tiddler will be saved to local storage, so request persistence
requestPersistence ( ) ;
persistPermissionRequested = true ;
}
}
return tiddler ;
} ) ;
} ;
// Request the browser to never evict the localstorage. Some browsers such as firefox
// will prompt the user. To make the decision easier for the user only prompt them
// when they click the save button on a tiddler which will be stored to localstorage.
2024-08-20 15:33:07 +00:00
if ( navigator . storage && navigator . storage . persist ) {
2023-06-13 09:50:00 +00:00
navigator . storage . persisted ( ) . then ( function ( isPersisted ) {
2024-08-20 15:33:07 +00:00
if ( ! isPersisted ) {
2023-06-13 09:50:00 +00:00
setPersistedState ( "not requested yet" ) ;
requestPersistenceOnFirstSave ( ) ;
} else {
setPersistedState ( "granted" ) ;
}
} ) ;
} else {
setPersistedState ( "feature not available" ) ;
}
2019-02-03 12:51:15 +00:00
// Track tiddler changes
$tw . wiki . addEventListener ( "change" , function ( changes ) {
2019-03-01 22:06:14 +00:00
// Bail if browser storage is disabled
if ( $tw . wiki . getTiddlerText ( ENABLED _TITLE ) === "no" ) {
return ;
}
2019-02-07 14:35:25 +00:00
// Recompile the filter if it has changed
if ( changes [ SAVE _FILTER _TITLE ] ) {
compileFilter ( ) ;
}
// Filter the changes
var filteredChanges = filterFn . call ( $tw . wiki , function ( iterator ) {
$tw . utils . each ( changes , function ( change , title ) {
var tiddler = $tw . wiki . getTiddler ( title ) ;
iterator ( tiddler , title ) ;
} ) ;
} ) ;
$tw . utils . each ( filteredChanges , function ( title ) {
2019-03-01 22:06:14 +00:00
// Don't try to save changes to our enabled status
// (If it were enabled in the file but disabled in local storage then we might not realise that distributing a copy of the file would have local storage enabled for other users)
if ( title === ENABLED _TITLE ) {
return ;
}
2023-06-13 09:50:00 +00:00
// This should always be queried from the browser, so don't store it in local storage
if ( title === PERSISTED _STATE _TITLE ) {
return ;
}
2019-03-03 11:30:14 +00:00
// Save the tiddler
2023-01-17 22:12:18 +00:00
$tw . browserStorage . saveTiddlerToLocalStorage ( title ) ;
2019-02-03 12:51:15 +00:00
} ) ;
} ) ;
} ;
} ) ( ) ;