diff booket.js @ 11:ef5d75bcac5e

Add Netscape bookmark file export function
author Guido Berhoerster <guido+booket@berhoerster.name>
date Wed, 17 Sep 2014 21:12:38 +0200
parents 20902b548d9f
children 948048e40fab
line wrap: on
line diff
--- a/booket.js	Wed Sep 17 19:55:26 2014 +0200
+++ b/booket.js	Wed Sep 17 21:12:38 2014 +0200
@@ -807,6 +807,65 @@
     this.unsavedChanges = false;
 };
 
+BookmarkModel.prototype.exportFile = function () {
+    var htmlBlob;
+    var bookmarkDoc;
+    var commentNode;
+    var metaElement;
+    var titleElement;
+    var headingElement;
+    var bookmarkListElement;
+    var bookmarkLinkElement;
+    var bookmarkElement;
+
+    bookmarkDoc = document.implementation.createHTMLDocument();
+
+    // construct Netscape bookmarks format within body
+    commentNode = bookmarkDoc.createComment('This is an automatically ' +
+        'generated file.\nIt will be read and overwritten.\nDO NOT EDIT!');
+    bookmarkDoc.body.appendChild(commentNode);
+
+    metaElement = bookmarkDoc.createElement('meta');
+    metaElement.setAttribute('http-equiv', 'Content-Type');
+    metaElement.setAttribute('content', 'text/html; charset=UTF-8');
+    bookmarkDoc.body.appendChild(metaElement);
+
+    titleElement = bookmarkDoc.createElement('title');
+    titleElement.textContent = 'Bookmarks';
+    bookmarkDoc.body.appendChild(titleElement);
+
+    headingElement = bookmarkDoc.createElement('h1');
+    headingElement.textContent = 'Bookmarks';
+    bookmarkDoc.body.appendChild(headingElement);
+
+    bookmarkListElement = bookmarkDoc.createElement('dl');
+    bookmarkDoc.body.appendChild(bookmarkListElement);
+
+    this._bookmarks.forEach(function (bookmark) {
+        bookmarkElement = bookmarkDoc.createElement('dt');
+
+        bookmarkLinkElement = bookmarkDoc.createElement('a');
+        bookmarkLinkElement.href = bookmark.url;
+        bookmarkLinkElement.textContent = bookmark.title;
+        bookmarkLinkElement.setAttribute('icon', bookmark.favicon);
+        bookmarkLinkElement.setAttribute('tags',
+            bookmark.tags.values().join(','));
+        bookmarkLinkElement.setAttribute('add_date',
+            Math.round(bookmark.ctime.getTime() / 1000));
+        bookmarkLinkElement.setAttribute('last_modified',
+            Math.round(bookmark.mtime.getTime() / 1000));
+
+        bookmarkElement.appendChild(bookmarkLinkElement);
+
+        bookmarkListElement.appendChild(bookmarkElement);
+        bookmarkListElement.appendChild(bookmarkDoc.createElement('dd'));
+    }, this);
+
+    htmlBlob = new Blob(['<!DOCTYPE NETSCAPE-Bookmark-file-1>\n' +
+        bookmarkDoc.body.innerHTML], {type: 'text/html'});
+    this.notify('export-file', htmlBlob);
+};
+
 BookmarkModel.prototype.handleEvent = function (e) {
     if (e.type === 'load') {
         if (e.target === this.loadFileReader) {
@@ -948,6 +1007,7 @@
     var saveFormElement;
     var loadFormElement;
     var importFormElement;
+    var exportFormElement;
     var newNode;
 
     ObservableMixin.call(this);
@@ -964,6 +1024,9 @@
     importFormElement = document.querySelector('form#import-form');
     importFormElement.addEventListener('submit', this);
 
+    exportFormElement = document.querySelector('form#export-form');
+    exportFormElement.addEventListener('submit', this);
+
     // create new editor form from template
     newNode = document.importNode(
         document.querySelector('#bookmark-editor-template').content, true);
@@ -1074,6 +1137,11 @@
 
             this.notify('import-file', e.target.file.files[0]);
             e.target.reset();
+        } else if (e.target.id === 'export-form') {
+            e.preventDefault();
+            e.target.blur();
+
+            this.notify('export-file');
         } else if (e.target.classList.contains('bookmark-editor-form')) {
             e.preventDefault();
             e.target.blur();
@@ -1115,6 +1183,14 @@
     this.saveLinkElement.click();
 };
 
+ActionsView.prototype.onExportFile = function (htmlBlob) {
+    var exportLinkElement;
+
+    exportLinkElement = document.querySelector('a#export-link');
+    exportLinkElement.href = URL.createObjectURL(htmlBlob);
+    exportLinkElement.click();
+};
+
 ActionsView.prototype.confirmLoadFile = function () {
     return window.confirm('There are unsaved changes to your bookmarks.\n' +
         'Proceed loading the bookmark file?');
@@ -1506,6 +1582,8 @@
         this.actionsView.onParseFileError.bind(this.actionsView));
     this.bookmarkModel.addObserver('save-file',
         this.actionsView.onSaveFile.bind(this.actionsView));
+    this.bookmarkModel.addObserver('export-file',
+        this.actionsView.onExportFile.bind(this.actionsView));
     this.bookmarkModel.addObserver('tag-added',
         this.tagView.onTagAdded.bind(this.tagView));
     this.bookmarkModel.addObserver('tag-count-changed',
@@ -1522,6 +1600,8 @@
     window.addEventListener('beforeunload', this.onBeforeUnload.bind(this));
     this.actionsView.addObserver('save-file',
         this.bookmarkModel.saveFile.bind(this.bookmarkModel));
+    this.actionsView.addObserver('export-file',
+        this.bookmarkModel.exportFile.bind(this.bookmarkModel));
     this.actionsView.addObserver('load-file', this.onLoadFile.bind(this));
     this.actionsView.addObserver('import-file', this.onImportFile.bind(this));
     this.actionsView.addObserver('save-bookmark',