projects/booket

changeset 19:4a4d9527c06f

Add merge options

Allow to merge loaded or imported bookmarks with the existing ones
author Guido Berhoerster <guido+booket@berhoerster.name>
date Thu Oct 02 09:08:22 2014 +0200 (2014-10-02)
parents 3642bb668af1
children 55bc20390185
files booket.css booket.html booket.js
line diff
     1.1 --- a/booket.css	Tue Sep 30 21:32:39 2014 +0200
     1.2 +++ b/booket.css	Thu Oct 02 09:08:22 2014 +0200
     1.3 @@ -140,9 +140,12 @@
     1.4      display: block;
     1.5  }
     1.6  
     1.7 +#actions label.top-label {
     1.8 +    font-weight: bold;
     1.9 +}
    1.10 +
    1.11  #actions label,
    1.12  .bookmark-editor-form label {
    1.13 -    font-weight: bold;
    1.14      font-size: .75em;
    1.15  }
    1.16  
     2.1 --- a/booket.html	Tue Sep 30 21:32:39 2014 +0200
     2.2 +++ b/booket.html	Thu Oct 02 09:08:22 2014 +0200
     2.3 @@ -39,8 +39,8 @@
     2.4    <datalist id="tag-datalist"></datalist>
     2.5  
     2.6    <template id="tag-input-template">
     2.7 -    <li><label>Tag <input type="text" name="tag" pattern="[^,;]*"
     2.8 -    size="20" list="tag-datalist" placeholder="tag"></input>
     2.9 +    <li><label class="top-label">Tag <input type="text" name="tag"
    2.10 +    pattern="[^,;]*" size="20" list="tag-datalist" placeholder="tag"></input>
    2.11      </label></li>
    2.12    </template>
    2.13  
    2.14 @@ -49,18 +49,18 @@
    2.15        <fieldset>
    2.16          <legend></legend>
    2.17          <input type="hidden" name="original-url"></input>
    2.18 -        <label>URL <input type="url" required="required"
    2.19 +        <label class="top-label">URL <input type="url" required="required"
    2.20          name="url" size="60" placeholder="http://example.com/"></input></label>
    2.21 -        <label>Title <input type="text" name="title" size="60"
    2.22 +        <label class="top-label">Title <input type="text" name="title" size="60"
    2.23          placeholder="A Title"></input></label>
    2.24 -        <label>Favicon <img width="16" height="16" src="missing-favicon.svg"
    2.25 -        class="bookmark-favicon" alt=""></img><input type="hidden"
    2.26 -        name="favicon"></input></label>
    2.27 +        <label class="top-label">Favicon <img width="16" height="16"
    2.28 +        src="missing-favicon.svg" class="bookmark-favicon" alt=""></img><input
    2.29 +        type="hidden" name="favicon"></input></label>
    2.30          <div>
    2.31            <ul class="tag-input-list"></ul>
    2.32            <button type="button" name="more-tags">Add more tags</button>
    2.33          </div>
    2.34 -        <label>Import from Bookmarklet
    2.35 +        <label class="top-label">Import from Bookmarklet
    2.36          <textarea name="bookmarklet-import" cols="60" rows="4"
    2.37          spellcheck="false"></textarea></label>
    2.38          <button type="reset" name="cancel">Cancel</button><button type="submit"
    2.39 @@ -101,8 +101,11 @@
    2.40      <form id="load-form">
    2.41        <fieldset>
    2.42          <legend>Load Bookmarks</legend>
    2.43 -        <label accesskey="i">File <input type="file" accept="application/json"
    2.44 -        required="required" name="file"></input></label>
    2.45 +        <label accesskey="i" class="top-label">File <input type="file"
    2.46 +        accept="application/json" required="required"
    2.47 +        name="file"></input></label>
    2.48 +        <label><input type="checkbox" name="merge"></input> Merge with existing
    2.49 +        bookmarks</label>
    2.50          <button type="submit" name="load-file" accesskey="l">Load</button>
    2.51        </fieldset>
    2.52      </form>
    2.53 @@ -122,8 +125,10 @@
    2.54      <form id="import-form">
    2.55        <fieldset>
    2.56          <legend>Import Bookmarks</legend>
    2.57 -        <label accesskey="e">File <input type="file" accept="text/html"
    2.58 -        required="required" name="file"></input></label>
    2.59 +        <label accesskey="e" class="top-label">File <input type="file"
    2.60 +        accept="text/html" required="required" name="file"></input></label>
    2.61 +        <label><input type="checkbox" name="merge"></input> Merge with existing
    2.62 +        bookmarks</label>
    2.63          <button type="submit" name="import-file" accesskey="m">Import</button>
    2.64        </fieldset>
    2.65      </form>
     3.1 --- a/booket.js	Tue Sep 30 21:32:39 2014 +0200
     3.2 +++ b/booket.js	Thu Oct 02 09:08:22 2014 +0200
     3.3 @@ -705,8 +705,11 @@
     3.4  };
     3.5  
     3.6  BookmarkModel.prototype.parseLoadedBookmarks = function (data) {
     3.7 +    var wasEmpty = !this._bookmarks.size;
     3.8      var parsedData;
     3.9      var bookmarks = [];
    3.10 +    var bookmark;
    3.11 +    var oldBookmark;
    3.12  
    3.13      try {
    3.14          parsedData = JSON.parse(data);
    3.15 @@ -724,9 +727,13 @@
    3.16      // create a temporary list of valid bookmarks
    3.17      parsedData.bookmarks.forEach(function (bookmark) {
    3.18          if (isString(bookmark.url) && bookmark.url !== '') {
    3.19 -            bookmarks.push(new Bookmark(bookmark.url, bookmark.title,
    3.20 -                bookmark.favicon, bookmark.tags, bookmark.ctime,
    3.21 -                bookmark.mtime));
    3.22 +            bookmark = new Bookmark(bookmark.url, bookmark.title,
    3.23 +                bookmark.favicon, bookmark.tags, bookmark.ctime, bookmark.mtime)
    3.24 +            oldBookmark = this.get(bookmark.url);
    3.25 +            if (oldBookmark === undefined ||
    3.26 +                    oldBookmark.mtime < bookmark.mtime) {
    3.27 +                bookmarks.push(bookmark);
    3.28 +            }
    3.29          }
    3.30      }, this);
    3.31  
    3.32 @@ -734,10 +741,14 @@
    3.33      this.add(bookmarks.sort(function (bookmark1, bookmark2) {
    3.34          return bookmark1.ctime - bookmark2.ctime;
    3.35      }));
    3.36 -    this.unsavedChanges = false;
    3.37 +    if (wasEmpty) {
    3.38 +        // if there were no bookmarks before there cannot be any unsaved changes
    3.39 +        this.unsavedChanges = false;
    3.40 +    }
    3.41  };
    3.42  
    3.43  BookmarkModel.prototype.parseImportedBookmarks = function (data) {
    3.44 +    var wasEmpty = (this._bookmarks.size > 0);
    3.45      var bookmarkDoc;
    3.46      var bookmarkElements;
    3.47      var i;
    3.48 @@ -748,6 +759,8 @@
    3.49      var ctime;
    3.50      var mtime;
    3.51      var bookmarks = [];
    3.52 +    var bookmark;
    3.53 +    var oldBookmark;
    3.54  
    3.55      bookmarkDoc = document.implementation.createHTMLDocument();
    3.56      bookmarkDoc.open();
    3.57 @@ -769,7 +782,12 @@
    3.58              mtime = !isNaN(mtime =
    3.59                  parseInt(bookmarkElements[i].getAttribute('last_modified'),
    3.60                  10)) ?  mtime * 1000 : undefined;
    3.61 -            bookmarks.push(new Bookmark(url, title, favicon, tags, ctime, mtime));
    3.62 +            bookmark = new Bookmark(url, title, favicon, tags, ctime, mtime);
    3.63 +            oldBookmark = this.get(bookmark.url);
    3.64 +            if (oldBookmark === undefined ||
    3.65 +                    oldBookmark.mtime < bookmark.mtime) {
    3.66 +                bookmarks.push(bookmark);
    3.67 +            }
    3.68          }
    3.69      }
    3.70  
    3.71 @@ -777,14 +795,18 @@
    3.72      this.add(bookmarks.sort(function (bookmark1, bookmark2) {
    3.73          return bookmark1.ctime - bookmark2.ctime;
    3.74      }));
    3.75 -
    3.76 -    this.unsavedChanges = false;
    3.77 +    if (!wasEmpty) {
    3.78 +        // if there were no bookmarks before there cannot be any unsaved changes
    3.79 +        this.unsavedChanges = false;
    3.80 +    }
    3.81  };
    3.82  
    3.83 -BookmarkModel.prototype.loadFile = function (bookmarkFile) {
    3.84 -    // delete all existing bookmarks first
    3.85 -    this.delete(this._bookmarks.keys());
    3.86 -    this.unsavedChanges = false;
    3.87 +BookmarkModel.prototype.loadFile = function (bookmarkFile, merge) {
    3.88 +    if (!merge) {
    3.89 +        // delete all existing bookmarks first
    3.90 +        this.delete(this._bookmarks.keys());
    3.91 +        this.unsavedChanges = false;
    3.92 +    }
    3.93  
    3.94      this.loadFileReader = new FileReader();
    3.95      this.loadFileReader.addEventListener('error', this);
    3.96 @@ -792,10 +814,12 @@
    3.97      this.loadFileReader.readAsText(bookmarkFile);
    3.98  };
    3.99  
   3.100 -BookmarkModel.prototype.importFile = function (bookmarkFile) {
   3.101 -    // delete all existing bookmarks first
   3.102 -    this.delete(this._bookmarks.keys());
   3.103 -    this.unsavedChanges = false;
   3.104 +BookmarkModel.prototype.importFile = function (bookmarkFile, merge) {
   3.105 +    if (!merge) {
   3.106 +        // delete all existing bookmarks first
   3.107 +        this.delete(this._bookmarks.keys());
   3.108 +        this.unsavedChanges = false;
   3.109 +    }
   3.110  
   3.111      this.importFileReader = new FileReader();
   3.112      this.importFileReader.addEventListener('error', this);
   3.113 @@ -1183,13 +1207,15 @@
   3.114              e.preventDefault();
   3.115              e.target.blur();
   3.116  
   3.117 -            this.notify('load-file', e.target.file.files[0]);
   3.118 +            this.notify('load-file', e.target.file.files[0],
   3.119 +                e.target.merge.checked);
   3.120              e.target.reset();
   3.121          } else if (e.target.id === 'import-form') {
   3.122              e.preventDefault();
   3.123              e.target.blur();
   3.124  
   3.125 -            this.notify('import-file', e.target.file.files[0]);
   3.126 +            this.notify('import-file', e.target.file.files[0],
   3.127 +                e.target.merge.checked);
   3.128              e.target.reset();
   3.129          } else if (e.target.id === 'export-form') {
   3.130              e.preventDefault();
   3.131 @@ -1731,7 +1757,7 @@
   3.132      history.pushState(null, null, serializeHash(url, hashData));
   3.133  };
   3.134  
   3.135 -BooketController.prototype.onLoadFile = function (bookmarkFile) {
   3.136 +BooketController.prototype.onLoadFile = function (bookmarkFile, merge) {
   3.137      if (this.bookmarkModel.unsavedChanges) {
   3.138          if (!this.actionsView.confirmLoadFile()) {
   3.139              return;
   3.140 @@ -1739,10 +1765,10 @@
   3.141          this.bookmarkModel.unsavedChanges = false;
   3.142      }
   3.143  
   3.144 -    this.bookmarkModel.loadFile(bookmarkFile);
   3.145 +    this.bookmarkModel.loadFile(bookmarkFile, merge);
   3.146  };
   3.147  
   3.148 -BooketController.prototype.onImportFile = function (bookmarkFile) {
   3.149 +BooketController.prototype.onImportFile = function (bookmarkFile, merge) {
   3.150      if (this.bookmarkModel.unsavedChanges) {
   3.151          if (!this.actionsView.confirmLoadFile()) {
   3.152              return;
   3.153 @@ -1750,7 +1776,7 @@
   3.154          this.bookmarkModel.unsavedChanges = false;
   3.155      }
   3.156  
   3.157 -    this.bookmarkModel.importFile(bookmarkFile);
   3.158 +    this.bookmarkModel.importFile(bookmarkFile, merge);
   3.159  };
   3.160  
   3.161  BooketController.prototype.onEditBookmark = function (bookmarkUrl) {