@@ -302,13 +302,13 @@ Options -Indexes
302302 settings : await globalThis . lb . getAllResultRows ( "settings" , db , null )
303303 } ;
304304
305- const jsonDbStr = JSON . stringify ( jsonDb ) ;
305+ const jsonDbStr = JSON . stringify ( jsonDb , null , 2 ) ;
306306 const blob = new Blob ( [ jsonDbStr ] , { type : "text/plain;charset=utf-8" } ) ;
307307 saveFile ( blob , "mydb.json" ) ;
308308 } ) ;
309309 }
310310
311- const insertThemeFromObject = async function ( db , theme , theme_uri ) {
311+ const insertThemeFromObject = async function ( db , theme , themeUri ) {
312312 let templates = structuredClone ( theme . templates ) ;
313313 templates . push ( {
314314 template_uri : "image" ,
@@ -339,7 +339,7 @@ Options -Indexes
339339 "contents, " +
340340 "created, " +
341341 "updated " +
342- ") VALUES ('" + theme_uri + "', ?, ?, ?, ?, ?, " +
342+ ") VALUES ('" + themeUri + "', ?, ?, ?, ?, ?, " +
343343 "STRFTIME('%Y-%m-%d %H:%M', DATETIME('now','localtime')), " +
344344 "STRFTIME('%Y-%m-%d %H:%M', DATETIME('now','localtime')))" ,
345345 bind : [
@@ -1267,7 +1267,7 @@ Options -Indexes
12671267 const exportTheme = function ( ) {
12681268 globalThis . lb . useSqlite ( async ( db ) => {
12691269 const resultRows = await db . exec ( {
1270- sql : "SELECT template_uri, template_type, content_type, contents FROM templates WHERE theme_uri = 'current'" ,
1270+ sql : "SELECT template_uri, template_set, template_type, content_type, contents FROM templates WHERE theme_uri = 'current'" ,
12711271 rowMode : 'object'
12721272 } ) ;
12731273
@@ -1282,24 +1282,62 @@ Options -Indexes
12821282 }
12831283
12841284 templates . push ( {
1285- "template_uri" : resultRows [ i ] [ "template_uri" ] ,
1286- "template_set" : resultRows [ i ] [ "template_set" ] ,
1287- "template_type" : resultRows [ i ] [ "template_type" ] ,
1288- "content_type" : resultRows [ i ] [ "content_type" ] ,
1289- "contents" : resultRows [ i ] [ "contents" ]
1285+ "template_uri" : resultRows [ i ] [ "template_uri" ] ? resultRows [ i ] [ "template_uri" ] : "" ,
1286+ "template_set" : resultRows [ i ] [ "template_set" ] ? resultRows [ i ] [ "template_set" ] : "" ,
1287+ "template_type" : resultRows [ i ] [ "template_type" ] ? resultRows [ i ] [ "template_type" ] : "" ,
1288+ "content_type" : resultRows [ i ] [ "content_type" ] ? resultRows [ i ] [ "content_type" ] : "" ,
1289+ "contents" : resultRows [ i ] [ "contents" ] ? resultRows [ i ] [ "contents" ] : ""
12901290 } ) ;
12911291 }
1292-
1292+
1293+ const randomUri = globalThis . lb . generateRandomId ( ) ;
12931294 let theme = {
1294- "theme_uri" : "current" ,
1295+ "theme_uri" : "theme_" + randomUri ,
12951296 "config" : globalThis . lb . getThemeConfig ( ) ,
12961297 "templates" : templates ,
12971298 "image" : image ? image : ""
12981299 } ;
12991300
1300- const themeStr = JSON . stringify ( theme ) ;
1301+ const themeStr = JSON . stringify ( theme , null , 2 ) ;
13011302 const blob = new Blob ( [ themeStr ] , { type : "text/plain;charset=utf-8" } ) ;
1302- saveFile ( blob , "mytheme.json" ) ;
1303+ saveFile ( blob , "theme_" + randomUri + ".json" ) ;
1304+ } ) ;
1305+ }
1306+
1307+ const exportThemeAsZipFolder = function ( event ) {
1308+ event . preventDefault ( ) ;
1309+
1310+ globalThis . lb . useSqlite ( async ( db ) => {
1311+ const resultRows = await db . exec ( {
1312+ sql : "SELECT template_uri, template_set, template_type, content_type, contents FROM templates WHERE theme_uri = 'current'" ,
1313+ rowMode : 'object'
1314+ } ) ;
1315+ let image = globalThis . window . prompt ( "If you want, insert a new screenshot of this theme in data URI code [data:image...]" ) ;
1316+
1317+ const zip = new JSZip ( ) ;
1318+ const templatesFolder = zip . folder ( "templates" ) ;
1319+
1320+ for ( let i = 0 ; i < resultRows . length ; i ++ ) {
1321+ if ( resultRows [ i ] [ "template_uri" ] === "config" ) continue ;
1322+ if ( resultRows [ i ] [ "template_uri" ] === "image" && ! image ) {
1323+ image = resultRows [ i ] [ "contents" ] ;
1324+ continue ;
1325+ }
1326+
1327+ const t = resultRows [ i ] ;
1328+ const folder = templatesFolder . folder ( t [ "template_type" ] ) . folder ( t [ "template_set" ] ) . folder ( t [ "content_type" ] ) ;
1329+ folder . file ( t [ "template_uri" ] + "." + t [ "content_type" ] , t [ "contents" ] ) ;
1330+ }
1331+
1332+ const configData = JSON . stringify ( globalThis . lb . getThemeConfig ( ) , null , 2 ) ;
1333+ const randomUri = globalThis . lb . generateRandomId ( ) ;
1334+
1335+ zip . file ( "theme_uri.txt" , "theme_" + randomUri ) ;
1336+ zip . file ( "config.json" , configData ) ;
1337+ zip . file ( "image.txt" , image ) ;
1338+ zip . generateAsync ( { type :"blob" } ) . then ( function ( content ) {
1339+ saveFile ( content , "theme_" + randomUri + ".zip" ) ;
1340+ } ) ;
13031341 } ) ;
13041342 }
13051343
@@ -2553,6 +2591,9 @@ Options -Indexes
25532591 const jsonDbBtn = globalThis . document . getElementById ( "download-json-db" ) ;
25542592 jsonDbBtn . addEventListener ( "click" , jsonDbBtnHandler ) ;
25552593
2594+ const exportThemeZip = globalThis . document . getElementById ( "export-theme-zip" ) ;
2595+ exportThemeZip . addEventListener ( "click" , exportThemeAsZipFolder ) ;
2596+
25562597 const persistentStorage = globalThis . document . getElementById ( "persistent-storage" ) ;
25572598 persistentStorage . addEventListener ( "click" , persistentStorageHandler ) ;
25582599
@@ -3543,31 +3584,35 @@ Options -Indexes
35433584 importThemeInput . click ( ) ;
35443585 }
35453586
3587+ const loadTheme = function ( theme ) {
3588+ const themeUri = globalThis . window . prompt ( "Choose a name for the theme." , theme [ "theme_uri" ] ) ;
3589+ globalThis . lb . useSqlite ( async ( db ) => {
3590+ await insertThemeFromObject ( db , theme , themeUri ? themeUri : theme [ "theme_uri" ] ) ;
3591+ reloadPage ( ) ;
3592+ } ) ;
3593+ }
3594+
35463595 const importThemeHandler = function ( event ) {
35473596 let file = event . target . files [ 0 ] ;
35483597 if ( ! file | ! file . name ) return ;
3549- if ( ! file . name . toUpperCase ( ) . endsWith ( '.JSON' ) ) {
3598+
3599+ if ( file . name . toUpperCase ( ) . endsWith ( '.JSON' ) ) {
3600+ const reader = new FileReader ( ) ;
3601+ reader . addEventListener ( 'load' , ( ) => {
3602+ if ( reader . result ) {
3603+ try {
3604+ const theme = JSON . parse ( reader . result ) ;
3605+ loadTheme ( theme ) ;
3606+ } catch ( e ) {
3607+ globalThis . window . alert ( "It was not possible to load this JSON file." ) ;
3608+ }
3609+ }
3610+ } ) ;
3611+
3612+ reader . readAsText ( file ) ;
3613+ } else {
35503614 globalThis . window . alert ( 'The only supported file extension is JSON.' ) ;
35513615 }
3552-
3553- const reader = new FileReader ( ) ;
3554- reader . addEventListener ( 'load' , ( ) => {
3555- let theme ;
3556- if ( reader . result ) {
3557- try {
3558- theme = JSON . parse ( reader . result ) ;
3559- const themeUri = globalThis . window . prompt ( "Choose a name for the theme." ) ;
3560- globalThis . lb . useSqlite ( async ( db ) => {
3561- await insertThemeFromObject ( db , theme , themeUri ) ;
3562- reloadPage ( ) ;
3563- } ) ;
3564- } catch ( e ) {
3565- globalThis . window . alert ( "It was not possible to load this JSON file." ) ;
3566- }
3567- }
3568- } ) ;
3569-
3570- reader . readAsText ( file ) ;
35713616 }
35723617
35733618 const deleteThemeHandler = function ( e ) {
@@ -4166,9 +4211,11 @@ Options -Indexes
41664211 const page = thisPage ( ) ;
41674212
41684213 if ( debug_mode === true || extensionEnvironment ( ) ) {
4169- if ( [ "index" ] . includes ( page ) ) {
4214+ if ( [ "index" , "settings" ] . includes ( page ) ) {
41704215 await import ( "../dependencies/jszip/jszip.min.js" ) ;
4171- } else if ( [ "article-edit" , "series-edit" , "section-edit" , "relation-edit" , "author-edit" , "settings" , "templates" ] . includes ( page ) ) {
4216+ }
4217+
4218+ if ( [ "article-edit" , "series-edit" , "section-edit" , "relation-edit" , "author-edit" , "settings" , "templates" ] . includes ( page ) ) {
41724219 await import ( "../dependencies/ace/ace.js" ) ;
41734220 await import ( "../dependencies/ace/ext-language_tools.js" ) ;
41744221 await import ( "../dependencies/ace/mode-markdown.js" ) ;
@@ -4181,9 +4228,11 @@ Options -Indexes
41814228 ace . config . set ( 'basePath' , '../dependencies/ace' ) ;
41824229 }
41834230 } else {
4184- if ( [ "index" ] . includes ( page ) ) {
4231+ if ( [ "index" , "settings" ] . includes ( page ) ) {
41854232 await importFromCDN ( "https://cdn.jsdelivr.net/npm/jszip@" + jszip_version + "/dist/jszip.min.js" , "../dependencies/jszip/jszip.min.js" ) ;
4186- } else if ( [ "article-edit" , "series-edit" , "section-edit" , "relation-edit" , "author-edit" , "settings" , "templates" ] . includes ( page ) ) {
4233+ }
4234+
4235+ if ( [ "article-edit" , "series-edit" , "section-edit" , "relation-edit" , "author-edit" , "settings" , "templates" ] . includes ( page ) ) {
41874236 await importFromCDN ( "https://cdn.jsdelivr.net/npm/ace-builds@" + ace_builds_version + "/src-min/ace.js" , "../dependencies/ace/ace.js" ) ;
41884237 await importFromCDN ( "https://cdn.jsdelivr.net/npm/ace-builds@" + ace_builds_version + "/src-min/ext-language_tools.js" , "../dependencies/ace/ext-language_tools.js" ) ;
41894238 await importFromCDN ( "https://cdn.jsdelivr.net/npm/ace-builds@" + ace_builds_version + "/src-min/mode-markdown.js" , "../dependencies/ace/mode-markdown.js" ) ;
0 commit comments