Mercurial > 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, 02 Oct 2014 09:08:22 +0200 |
parents | 3642bb668af1 |
children | 55bc20390185 |
files | booket.css booket.html booket.js |
diffstat | 3 files changed, 68 insertions(+), 34 deletions(-) [+] |
line wrap: on
line diff
--- a/booket.css Tue Sep 30 21:32:39 2014 +0200 +++ b/booket.css Thu Oct 02 09:08:22 2014 +0200 @@ -140,9 +140,12 @@ display: block; } +#actions label.top-label { + font-weight: bold; +} + #actions label, .bookmark-editor-form label { - font-weight: bold; font-size: .75em; }
--- a/booket.html Tue Sep 30 21:32:39 2014 +0200 +++ b/booket.html Thu Oct 02 09:08:22 2014 +0200 @@ -39,8 +39,8 @@ <datalist id="tag-datalist"></datalist> <template id="tag-input-template"> - <li><label>Tag <input type="text" name="tag" pattern="[^,;]*" - size="20" list="tag-datalist" placeholder="tag"></input> + <li><label class="top-label">Tag <input type="text" name="tag" + pattern="[^,;]*" size="20" list="tag-datalist" placeholder="tag"></input> </label></li> </template> @@ -49,18 +49,18 @@ <fieldset> <legend></legend> <input type="hidden" name="original-url"></input> - <label>URL <input type="url" required="required" + <label class="top-label">URL <input type="url" required="required" name="url" size="60" placeholder="http://example.com/"></input></label> - <label>Title <input type="text" name="title" size="60" + <label class="top-label">Title <input type="text" name="title" size="60" placeholder="A Title"></input></label> - <label>Favicon <img width="16" height="16" src="missing-favicon.svg" - class="bookmark-favicon" alt=""></img><input type="hidden" - name="favicon"></input></label> + <label class="top-label">Favicon <img width="16" height="16" + src="missing-favicon.svg" class="bookmark-favicon" alt=""></img><input + type="hidden" name="favicon"></input></label> <div> <ul class="tag-input-list"></ul> <button type="button" name="more-tags">Add more tags</button> </div> - <label>Import from Bookmarklet + <label class="top-label">Import from Bookmarklet <textarea name="bookmarklet-import" cols="60" rows="4" spellcheck="false"></textarea></label> <button type="reset" name="cancel">Cancel</button><button type="submit" @@ -101,8 +101,11 @@ <form id="load-form"> <fieldset> <legend>Load Bookmarks</legend> - <label accesskey="i">File <input type="file" accept="application/json" - required="required" name="file"></input></label> + <label accesskey="i" class="top-label">File <input type="file" + accept="application/json" required="required" + name="file"></input></label> + <label><input type="checkbox" name="merge"></input> Merge with existing + bookmarks</label> <button type="submit" name="load-file" accesskey="l">Load</button> </fieldset> </form> @@ -122,8 +125,10 @@ <form id="import-form"> <fieldset> <legend>Import Bookmarks</legend> - <label accesskey="e">File <input type="file" accept="text/html" - required="required" name="file"></input></label> + <label accesskey="e" class="top-label">File <input type="file" + accept="text/html" required="required" name="file"></input></label> + <label><input type="checkbox" name="merge"></input> Merge with existing + bookmarks</label> <button type="submit" name="import-file" accesskey="m">Import</button> </fieldset> </form>
--- a/booket.js Tue Sep 30 21:32:39 2014 +0200 +++ b/booket.js Thu Oct 02 09:08:22 2014 +0200 @@ -705,8 +705,11 @@ }; BookmarkModel.prototype.parseLoadedBookmarks = function (data) { + var wasEmpty = !this._bookmarks.size; var parsedData; var bookmarks = []; + var bookmark; + var oldBookmark; try { parsedData = JSON.parse(data); @@ -724,9 +727,13 @@ // create a temporary list of valid bookmarks parsedData.bookmarks.forEach(function (bookmark) { if (isString(bookmark.url) && bookmark.url !== '') { - bookmarks.push(new Bookmark(bookmark.url, bookmark.title, - bookmark.favicon, bookmark.tags, bookmark.ctime, - bookmark.mtime)); + bookmark = new Bookmark(bookmark.url, bookmark.title, + bookmark.favicon, bookmark.tags, bookmark.ctime, bookmark.mtime) + oldBookmark = this.get(bookmark.url); + if (oldBookmark === undefined || + oldBookmark.mtime < bookmark.mtime) { + bookmarks.push(bookmark); + } } }, this); @@ -734,10 +741,14 @@ this.add(bookmarks.sort(function (bookmark1, bookmark2) { return bookmark1.ctime - bookmark2.ctime; })); - this.unsavedChanges = false; + if (wasEmpty) { + // if there were no bookmarks before there cannot be any unsaved changes + this.unsavedChanges = false; + } }; BookmarkModel.prototype.parseImportedBookmarks = function (data) { + var wasEmpty = (this._bookmarks.size > 0); var bookmarkDoc; var bookmarkElements; var i; @@ -748,6 +759,8 @@ var ctime; var mtime; var bookmarks = []; + var bookmark; + var oldBookmark; bookmarkDoc = document.implementation.createHTMLDocument(); bookmarkDoc.open(); @@ -769,7 +782,12 @@ mtime = !isNaN(mtime = parseInt(bookmarkElements[i].getAttribute('last_modified'), 10)) ? mtime * 1000 : undefined; - bookmarks.push(new Bookmark(url, title, favicon, tags, ctime, mtime)); + bookmark = new Bookmark(url, title, favicon, tags, ctime, mtime); + oldBookmark = this.get(bookmark.url); + if (oldBookmark === undefined || + oldBookmark.mtime < bookmark.mtime) { + bookmarks.push(bookmark); + } } } @@ -777,14 +795,18 @@ this.add(bookmarks.sort(function (bookmark1, bookmark2) { return bookmark1.ctime - bookmark2.ctime; })); - - this.unsavedChanges = false; + if (!wasEmpty) { + // if there were no bookmarks before there cannot be any unsaved changes + this.unsavedChanges = false; + } }; -BookmarkModel.prototype.loadFile = function (bookmarkFile) { - // delete all existing bookmarks first - this.delete(this._bookmarks.keys()); - this.unsavedChanges = false; +BookmarkModel.prototype.loadFile = function (bookmarkFile, merge) { + if (!merge) { + // delete all existing bookmarks first + this.delete(this._bookmarks.keys()); + this.unsavedChanges = false; + } this.loadFileReader = new FileReader(); this.loadFileReader.addEventListener('error', this); @@ -792,10 +814,12 @@ this.loadFileReader.readAsText(bookmarkFile); }; -BookmarkModel.prototype.importFile = function (bookmarkFile) { - // delete all existing bookmarks first - this.delete(this._bookmarks.keys()); - this.unsavedChanges = false; +BookmarkModel.prototype.importFile = function (bookmarkFile, merge) { + if (!merge) { + // delete all existing bookmarks first + this.delete(this._bookmarks.keys()); + this.unsavedChanges = false; + } this.importFileReader = new FileReader(); this.importFileReader.addEventListener('error', this); @@ -1183,13 +1207,15 @@ e.preventDefault(); e.target.blur(); - this.notify('load-file', e.target.file.files[0]); + this.notify('load-file', e.target.file.files[0], + e.target.merge.checked); e.target.reset(); } else if (e.target.id === 'import-form') { e.preventDefault(); e.target.blur(); - this.notify('import-file', e.target.file.files[0]); + this.notify('import-file', e.target.file.files[0], + e.target.merge.checked); e.target.reset(); } else if (e.target.id === 'export-form') { e.preventDefault(); @@ -1731,7 +1757,7 @@ history.pushState(null, null, serializeHash(url, hashData)); }; -BooketController.prototype.onLoadFile = function (bookmarkFile) { +BooketController.prototype.onLoadFile = function (bookmarkFile, merge) { if (this.bookmarkModel.unsavedChanges) { if (!this.actionsView.confirmLoadFile()) { return; @@ -1739,10 +1765,10 @@ this.bookmarkModel.unsavedChanges = false; } - this.bookmarkModel.loadFile(bookmarkFile); + this.bookmarkModel.loadFile(bookmarkFile, merge); }; -BooketController.prototype.onImportFile = function (bookmarkFile) { +BooketController.prototype.onImportFile = function (bookmarkFile, merge) { if (this.bookmarkModel.unsavedChanges) { if (!this.actionsView.confirmLoadFile()) { return; @@ -1750,7 +1776,7 @@ this.bookmarkModel.unsavedChanges = false; } - this.bookmarkModel.importFile(bookmarkFile); + this.bookmarkModel.importFile(bookmarkFile, merge); }; BooketController.prototype.onEditBookmark = function (bookmarkUrl) {