Mercurial > projects > booket
changeset 10:20902b548d9f
Add Netscape bookmark file import function
author | Guido Berhoerster <guido+booket@berhoerster.name> |
---|---|
date | Wed, 17 Sep 2014 19:55:26 +0200 |
parents | 19900803f7d0 |
children | ef5d75bcac5e |
files | booket.html booket.js |
diffstat | 2 files changed, 103 insertions(+), 7 deletions(-) [+] |
line wrap: on
line diff
--- a/booket.html Sun Sep 14 23:14:02 2014 +0200 +++ b/booket.html Wed Sep 17 19:55:26 2014 +0200 @@ -85,6 +85,10 @@ <dd>Save bookmark file</dd> <dt><kbd>Prefix</kbd>+<kbd>a</kbd></dt> <dd>Focus bookmark editor</dd> + <dt><kbd>Prefix</kbd>+<kbd>e</kbd></dt> + <dd>Select bookmark file to import</dd> + <dt><kbd>Prefix</kbd>+<kbd>m</kbd></dt> + <dd>Import selected file</dd> <dt><kbd>Prefix</kbd>+<kbd>f</kbd></dt> <dd>Focus search field</dd> </dl> @@ -108,6 +112,15 @@ accesskey="s">Save…</button> </fieldset> </form> + + <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> + <button type="submit" name="import-file" accesskey="m">Import</button> + </fieldset> + </form> </section> <main>
--- a/booket.js Sun Sep 14 23:14:02 2014 +0200 +++ b/booket.js Wed Sep 17 19:55:26 2014 +0200 @@ -454,6 +454,8 @@ ObservableMixin.call(this); this.unsavedChanges = false; + this.loadFileReader = null; + this.importFileReader= null; this._bookmarks = new StringMap(); this._tagCount = new StringMap(); this._filterTags = new StringSet(); @@ -723,17 +725,70 @@ this.unsavedChanges = false; }; +BookmarkModel.prototype.parseImportedBookmarks = function (data) { + var bookmarkDoc; + var bookmarkElements; + var i; + var url; + var title; + var favicon; + var tags; + var ctime; + var mtime; + var bookmarks = []; + + bookmarkDoc = document.implementation.createHTMLDocument(); + bookmarkDoc.open(); + bookmarkDoc.write(data); + bookmarkDoc.close(); + + // create a temporary list of valid bookmarks + bookmarkElements = bookmarkDoc.querySelectorAll('dt > a[href]'); + for (i = 0; i < bookmarkElements.length; i++) { + url = bookmarkElements[i].href; + if (url !== '') { + title = bookmarkElements[i].textContent; + favicon = bookmarkElements[i].getAttribute('icon'); + tags = ((tags = bookmarkElements[i].getAttribute('tags')) !== + null) ? tags.split(',') : []; + ctime = !isNaN(ctime = + parseInt(bookmarkElements[i].getAttribute('add_date'), 10)) ? + ctime * 1000 : undefined; + mtime = !isNaN(mtime = + parseInt(bookmarkElements[i].getAttribute('last_modified'), + 10)) ? mtime * 1000 : undefined; + bookmarks.push(new Bookmark(url, title, favicon, tags, ctime, mtime)); + } + } + + // add each bookmark to the model ordered by the last modification time + this.add(bookmarks.sort(function (bookmark1, bookmark2) { + return bookmark1.ctime - bookmark2.ctime; + })); + + this.unsavedChanges = false; +}; + BookmarkModel.prototype.loadFile = function (bookmarkFile) { - var bookmarkFileReader; - // delete all existing bookmarks first this.delete(this._bookmarks.keys()); this.unsavedChanges = false; - bookmarkFileReader = new FileReader(); - bookmarkFileReader.addEventListener('error', this); - bookmarkFileReader.addEventListener('load', this); - bookmarkFileReader.readAsText(bookmarkFile); + this.loadFileReader = new FileReader(); + this.loadFileReader.addEventListener('error', this); + this.loadFileReader.addEventListener('load', this); + this.loadFileReader.readAsText(bookmarkFile); +}; + +BookmarkModel.prototype.importFile = function (bookmarkFile) { + // delete all existing bookmarks first + this.delete(this._bookmarks.keys()); + this.unsavedChanges = false; + + this.importFileReader = new FileReader(); + this.importFileReader.addEventListener('error', this); + this.importFileReader.addEventListener('load', this); + this.importFileReader.readAsText(bookmarkFile); }; BookmarkModel.prototype.saveFile = function () { @@ -754,7 +809,13 @@ BookmarkModel.prototype.handleEvent = function (e) { if (e.type === 'load') { - this.parseLoadedBookmarks(e.target.result); + if (e.target === this.loadFileReader) { + this.parseLoadedBookmarks(e.target.result); + this.loadFileReader = null; + } else if (e.target === this.importFileReader) { + this.parseImportedBookmarks(e.target.result); + this.importFileReader = null; + } } else if (e.type === 'error') { this.notify('load-file-error', e.target.error.message); } @@ -886,6 +947,7 @@ var ActionsView = function () { var saveFormElement; var loadFormElement; + var importFormElement; var newNode; ObservableMixin.call(this); @@ -899,6 +961,9 @@ loadFormElement = document.querySelector('form#load-form'); loadFormElement.addEventListener('submit', this); + importFormElement = document.querySelector('form#import-form'); + importFormElement.addEventListener('submit', this); + // create new editor form from template newNode = document.importNode( document.querySelector('#bookmark-editor-template').content, true); @@ -1003,6 +1068,12 @@ this.notify('load-file', e.target.file.files[0]); e.target.reset(); + } else if (e.target.id === 'import-form') { + e.preventDefault(); + e.target.blur(); + + this.notify('import-file', e.target.file.files[0]); + e.target.reset(); } else if (e.target.classList.contains('bookmark-editor-form')) { e.preventDefault(); e.target.blur(); @@ -1452,6 +1523,7 @@ this.actionsView.addObserver('save-file', this.bookmarkModel.saveFile.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', this.onSaveBookmark.bind(this)); this.bookmarkView.addObserver('edit-bookmark', @@ -1530,6 +1602,17 @@ this.bookmarkModel.loadFile(bookmarkFile); }; +BooketController.prototype.onImportFile = function (bookmarkFile) { + if (this.bookmarkModel.unsavedChanges) { + if (!this.actionsView.confirmLoadFile()) { + return; + } + this.bookmarkModel.unsavedChanges = false; + } + + this.bookmarkModel.importFile(bookmarkFile); +}; + BooketController.prototype.onEditBookmark = function (bookmarkUrl) { this.bookmarkView.displayBookmarkEditor( this.bookmarkModel.get(bookmarkUrl));