projects/booket

changeset 11:ef5d75bcac5e

Add Netscape bookmark file export function
author Guido Berhoerster <guido+booket@berhoerster.name>
date Wed Sep 17 21:12:38 2014 +0200 (2014-09-17)
parents 20902b548d9f
children 948048e40fab
files booket.html booket.js
line diff
     1.1 --- a/booket.html	Wed Sep 17 19:55:26 2014 +0200
     1.2 +++ b/booket.html	Wed Sep 17 21:12:38 2014 +0200
     1.3 @@ -89,6 +89,8 @@
     1.4          <dd>Select bookmark file to import</dd>
     1.5          <dt><kbd>Prefix</kbd>+<kbd>m</kbd></dt>
     1.6          <dd>Import selected file</dd>
     1.7 +        <dt><kbd>Prefix</kbd>+<kbd>x</kbd></dt>
     1.8 +        <dd>Export selected file</dd>
     1.9          <dt><kbd>Prefix</kbd>+<kbd>f</kbd></dt>
    1.10          <dd>Focus search field</dd>
    1.11        </dl>
    1.12 @@ -121,6 +123,16 @@
    1.13          <button type="submit" name="import-file" accesskey="m">Import</button>
    1.14        </fieldset>
    1.15      </form>
    1.16 +
    1.17 +    <form id="export-form">
    1.18 +      <fieldset>
    1.19 +        <legend>Export Bookmarks</legend>
    1.20 +        <a href="#" id="export-link" hidden="hidden"
    1.21 +        download="bookmarks.html"></a>
    1.22 +        <button type="submit" name="export-file"
    1.23 +        accesskey="x">Export&#8230;</button>
    1.24 +      </fieldset>
    1.25 +    </form>
    1.26    </section>
    1.27  
    1.28    <main>
     2.1 --- a/booket.js	Wed Sep 17 19:55:26 2014 +0200
     2.2 +++ b/booket.js	Wed Sep 17 21:12:38 2014 +0200
     2.3 @@ -807,6 +807,65 @@
     2.4      this.unsavedChanges = false;
     2.5  };
     2.6  
     2.7 +BookmarkModel.prototype.exportFile = function () {
     2.8 +    var htmlBlob;
     2.9 +    var bookmarkDoc;
    2.10 +    var commentNode;
    2.11 +    var metaElement;
    2.12 +    var titleElement;
    2.13 +    var headingElement;
    2.14 +    var bookmarkListElement;
    2.15 +    var bookmarkLinkElement;
    2.16 +    var bookmarkElement;
    2.17 +
    2.18 +    bookmarkDoc = document.implementation.createHTMLDocument();
    2.19 +
    2.20 +    // construct Netscape bookmarks format within body
    2.21 +    commentNode = bookmarkDoc.createComment('This is an automatically ' +
    2.22 +        'generated file.\nIt will be read and overwritten.\nDO NOT EDIT!');
    2.23 +    bookmarkDoc.body.appendChild(commentNode);
    2.24 +
    2.25 +    metaElement = bookmarkDoc.createElement('meta');
    2.26 +    metaElement.setAttribute('http-equiv', 'Content-Type');
    2.27 +    metaElement.setAttribute('content', 'text/html; charset=UTF-8');
    2.28 +    bookmarkDoc.body.appendChild(metaElement);
    2.29 +
    2.30 +    titleElement = bookmarkDoc.createElement('title');
    2.31 +    titleElement.textContent = 'Bookmarks';
    2.32 +    bookmarkDoc.body.appendChild(titleElement);
    2.33 +
    2.34 +    headingElement = bookmarkDoc.createElement('h1');
    2.35 +    headingElement.textContent = 'Bookmarks';
    2.36 +    bookmarkDoc.body.appendChild(headingElement);
    2.37 +
    2.38 +    bookmarkListElement = bookmarkDoc.createElement('dl');
    2.39 +    bookmarkDoc.body.appendChild(bookmarkListElement);
    2.40 +
    2.41 +    this._bookmarks.forEach(function (bookmark) {
    2.42 +        bookmarkElement = bookmarkDoc.createElement('dt');
    2.43 +
    2.44 +        bookmarkLinkElement = bookmarkDoc.createElement('a');
    2.45 +        bookmarkLinkElement.href = bookmark.url;
    2.46 +        bookmarkLinkElement.textContent = bookmark.title;
    2.47 +        bookmarkLinkElement.setAttribute('icon', bookmark.favicon);
    2.48 +        bookmarkLinkElement.setAttribute('tags',
    2.49 +            bookmark.tags.values().join(','));
    2.50 +        bookmarkLinkElement.setAttribute('add_date',
    2.51 +            Math.round(bookmark.ctime.getTime() / 1000));
    2.52 +        bookmarkLinkElement.setAttribute('last_modified',
    2.53 +            Math.round(bookmark.mtime.getTime() / 1000));
    2.54 +
    2.55 +        bookmarkElement.appendChild(bookmarkLinkElement);
    2.56 +
    2.57 +        bookmarkListElement.appendChild(bookmarkElement);
    2.58 +        bookmarkListElement.appendChild(bookmarkDoc.createElement('dd'));
    2.59 +    }, this);
    2.60 +
    2.61 +    htmlBlob = new Blob(['<!DOCTYPE NETSCAPE-Bookmark-file-1>\n' +
    2.62 +        bookmarkDoc.body.innerHTML], {type: 'text/html'});
    2.63 +    this.notify('export-file', htmlBlob);
    2.64 +};
    2.65 +
    2.66  BookmarkModel.prototype.handleEvent = function (e) {
    2.67      if (e.type === 'load') {
    2.68          if (e.target === this.loadFileReader) {
    2.69 @@ -948,6 +1007,7 @@
    2.70      var saveFormElement;
    2.71      var loadFormElement;
    2.72      var importFormElement;
    2.73 +    var exportFormElement;
    2.74      var newNode;
    2.75  
    2.76      ObservableMixin.call(this);
    2.77 @@ -964,6 +1024,9 @@
    2.78      importFormElement = document.querySelector('form#import-form');
    2.79      importFormElement.addEventListener('submit', this);
    2.80  
    2.81 +    exportFormElement = document.querySelector('form#export-form');
    2.82 +    exportFormElement.addEventListener('submit', this);
    2.83 +
    2.84      // create new editor form from template
    2.85      newNode = document.importNode(
    2.86          document.querySelector('#bookmark-editor-template').content, true);
    2.87 @@ -1074,6 +1137,11 @@
    2.88  
    2.89              this.notify('import-file', e.target.file.files[0]);
    2.90              e.target.reset();
    2.91 +        } else if (e.target.id === 'export-form') {
    2.92 +            e.preventDefault();
    2.93 +            e.target.blur();
    2.94 +
    2.95 +            this.notify('export-file');
    2.96          } else if (e.target.classList.contains('bookmark-editor-form')) {
    2.97              e.preventDefault();
    2.98              e.target.blur();
    2.99 @@ -1115,6 +1183,14 @@
   2.100      this.saveLinkElement.click();
   2.101  };
   2.102  
   2.103 +ActionsView.prototype.onExportFile = function (htmlBlob) {
   2.104 +    var exportLinkElement;
   2.105 +
   2.106 +    exportLinkElement = document.querySelector('a#export-link');
   2.107 +    exportLinkElement.href = URL.createObjectURL(htmlBlob);
   2.108 +    exportLinkElement.click();
   2.109 +};
   2.110 +
   2.111  ActionsView.prototype.confirmLoadFile = function () {
   2.112      return window.confirm('There are unsaved changes to your bookmarks.\n' +
   2.113          'Proceed loading the bookmark file?');
   2.114 @@ -1506,6 +1582,8 @@
   2.115          this.actionsView.onParseFileError.bind(this.actionsView));
   2.116      this.bookmarkModel.addObserver('save-file',
   2.117          this.actionsView.onSaveFile.bind(this.actionsView));
   2.118 +    this.bookmarkModel.addObserver('export-file',
   2.119 +        this.actionsView.onExportFile.bind(this.actionsView));
   2.120      this.bookmarkModel.addObserver('tag-added',
   2.121          this.tagView.onTagAdded.bind(this.tagView));
   2.122      this.bookmarkModel.addObserver('tag-count-changed',
   2.123 @@ -1522,6 +1600,8 @@
   2.124      window.addEventListener('beforeunload', this.onBeforeUnload.bind(this));
   2.125      this.actionsView.addObserver('save-file',
   2.126          this.bookmarkModel.saveFile.bind(this.bookmarkModel));
   2.127 +    this.actionsView.addObserver('export-file',
   2.128 +        this.bookmarkModel.exportFile.bind(this.bookmarkModel));
   2.129      this.actionsView.addObserver('load-file', this.onLoadFile.bind(this));
   2.130      this.actionsView.addObserver('import-file', this.onImportFile.bind(this));
   2.131      this.actionsView.addObserver('save-bookmark',