comparison 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
comparison
equal deleted inserted replaced
10:20902b548d9f 11:ef5d75bcac5e
805 'application/json'}); 805 'application/json'});
806 this.notify('save-file', jsonBlob); 806 this.notify('save-file', jsonBlob);
807 this.unsavedChanges = false; 807 this.unsavedChanges = false;
808 }; 808 };
809 809
810 BookmarkModel.prototype.exportFile = function () {
811 var htmlBlob;
812 var bookmarkDoc;
813 var commentNode;
814 var metaElement;
815 var titleElement;
816 var headingElement;
817 var bookmarkListElement;
818 var bookmarkLinkElement;
819 var bookmarkElement;
820
821 bookmarkDoc = document.implementation.createHTMLDocument();
822
823 // construct Netscape bookmarks format within body
824 commentNode = bookmarkDoc.createComment('This is an automatically ' +
825 'generated file.\nIt will be read and overwritten.\nDO NOT EDIT!');
826 bookmarkDoc.body.appendChild(commentNode);
827
828 metaElement = bookmarkDoc.createElement('meta');
829 metaElement.setAttribute('http-equiv', 'Content-Type');
830 metaElement.setAttribute('content', 'text/html; charset=UTF-8');
831 bookmarkDoc.body.appendChild(metaElement);
832
833 titleElement = bookmarkDoc.createElement('title');
834 titleElement.textContent = 'Bookmarks';
835 bookmarkDoc.body.appendChild(titleElement);
836
837 headingElement = bookmarkDoc.createElement('h1');
838 headingElement.textContent = 'Bookmarks';
839 bookmarkDoc.body.appendChild(headingElement);
840
841 bookmarkListElement = bookmarkDoc.createElement('dl');
842 bookmarkDoc.body.appendChild(bookmarkListElement);
843
844 this._bookmarks.forEach(function (bookmark) {
845 bookmarkElement = bookmarkDoc.createElement('dt');
846
847 bookmarkLinkElement = bookmarkDoc.createElement('a');
848 bookmarkLinkElement.href = bookmark.url;
849 bookmarkLinkElement.textContent = bookmark.title;
850 bookmarkLinkElement.setAttribute('icon', bookmark.favicon);
851 bookmarkLinkElement.setAttribute('tags',
852 bookmark.tags.values().join(','));
853 bookmarkLinkElement.setAttribute('add_date',
854 Math.round(bookmark.ctime.getTime() / 1000));
855 bookmarkLinkElement.setAttribute('last_modified',
856 Math.round(bookmark.mtime.getTime() / 1000));
857
858 bookmarkElement.appendChild(bookmarkLinkElement);
859
860 bookmarkListElement.appendChild(bookmarkElement);
861 bookmarkListElement.appendChild(bookmarkDoc.createElement('dd'));
862 }, this);
863
864 htmlBlob = new Blob(['<!DOCTYPE NETSCAPE-Bookmark-file-1>\n' +
865 bookmarkDoc.body.innerHTML], {type: 'text/html'});
866 this.notify('export-file', htmlBlob);
867 };
868
810 BookmarkModel.prototype.handleEvent = function (e) { 869 BookmarkModel.prototype.handleEvent = function (e) {
811 if (e.type === 'load') { 870 if (e.type === 'load') {
812 if (e.target === this.loadFileReader) { 871 if (e.target === this.loadFileReader) {
813 this.parseLoadedBookmarks(e.target.result); 872 this.parseLoadedBookmarks(e.target.result);
814 this.loadFileReader = null; 873 this.loadFileReader = null;
946 1005
947 var ActionsView = function () { 1006 var ActionsView = function () {
948 var saveFormElement; 1007 var saveFormElement;
949 var loadFormElement; 1008 var loadFormElement;
950 var importFormElement; 1009 var importFormElement;
1010 var exportFormElement;
951 var newNode; 1011 var newNode;
952 1012
953 ObservableMixin.call(this); 1013 ObservableMixin.call(this);
954 1014
955 this.tagInputTemplate = document.querySelector('#tag-input-template'); 1015 this.tagInputTemplate = document.querySelector('#tag-input-template');
961 loadFormElement = document.querySelector('form#load-form'); 1021 loadFormElement = document.querySelector('form#load-form');
962 loadFormElement.addEventListener('submit', this); 1022 loadFormElement.addEventListener('submit', this);
963 1023
964 importFormElement = document.querySelector('form#import-form'); 1024 importFormElement = document.querySelector('form#import-form');
965 importFormElement.addEventListener('submit', this); 1025 importFormElement.addEventListener('submit', this);
1026
1027 exportFormElement = document.querySelector('form#export-form');
1028 exportFormElement.addEventListener('submit', this);
966 1029
967 // create new editor form from template 1030 // create new editor form from template
968 newNode = document.importNode( 1031 newNode = document.importNode(
969 document.querySelector('#bookmark-editor-template').content, true); 1032 document.querySelector('#bookmark-editor-template').content, true);
970 1033
1072 e.preventDefault(); 1135 e.preventDefault();
1073 e.target.blur(); 1136 e.target.blur();
1074 1137
1075 this.notify('import-file', e.target.file.files[0]); 1138 this.notify('import-file', e.target.file.files[0]);
1076 e.target.reset(); 1139 e.target.reset();
1140 } else if (e.target.id === 'export-form') {
1141 e.preventDefault();
1142 e.target.blur();
1143
1144 this.notify('export-file');
1077 } else if (e.target.classList.contains('bookmark-editor-form')) { 1145 } else if (e.target.classList.contains('bookmark-editor-form')) {
1078 e.preventDefault(); 1146 e.preventDefault();
1079 e.target.blur(); 1147 e.target.blur();
1080 1148
1081 if (e.target.tag.length) { 1149 if (e.target.tag.length) {
1111 }; 1179 };
1112 1180
1113 ActionsView.prototype.onSaveFile = function (jsonBlob) { 1181 ActionsView.prototype.onSaveFile = function (jsonBlob) {
1114 this.saveLinkElement.href = URL.createObjectURL(jsonBlob); 1182 this.saveLinkElement.href = URL.createObjectURL(jsonBlob);
1115 this.saveLinkElement.click(); 1183 this.saveLinkElement.click();
1184 };
1185
1186 ActionsView.prototype.onExportFile = function (htmlBlob) {
1187 var exportLinkElement;
1188
1189 exportLinkElement = document.querySelector('a#export-link');
1190 exportLinkElement.href = URL.createObjectURL(htmlBlob);
1191 exportLinkElement.click();
1116 }; 1192 };
1117 1193
1118 ActionsView.prototype.confirmLoadFile = function () { 1194 ActionsView.prototype.confirmLoadFile = function () {
1119 return window.confirm('There are unsaved changes to your bookmarks.\n' + 1195 return window.confirm('There are unsaved changes to your bookmarks.\n' +
1120 'Proceed loading the bookmark file?'); 1196 'Proceed loading the bookmark file?');
1504 this.actionsView.onLoadFileError.bind(this.actionsView)); 1580 this.actionsView.onLoadFileError.bind(this.actionsView));
1505 this.bookmarkModel.addObserver('parse-file-error', 1581 this.bookmarkModel.addObserver('parse-file-error',
1506 this.actionsView.onParseFileError.bind(this.actionsView)); 1582 this.actionsView.onParseFileError.bind(this.actionsView));
1507 this.bookmarkModel.addObserver('save-file', 1583 this.bookmarkModel.addObserver('save-file',
1508 this.actionsView.onSaveFile.bind(this.actionsView)); 1584 this.actionsView.onSaveFile.bind(this.actionsView));
1585 this.bookmarkModel.addObserver('export-file',
1586 this.actionsView.onExportFile.bind(this.actionsView));
1509 this.bookmarkModel.addObserver('tag-added', 1587 this.bookmarkModel.addObserver('tag-added',
1510 this.tagView.onTagAdded.bind(this.tagView)); 1588 this.tagView.onTagAdded.bind(this.tagView));
1511 this.bookmarkModel.addObserver('tag-count-changed', 1589 this.bookmarkModel.addObserver('tag-count-changed',
1512 this.tagView.onTagCountChanged.bind(this.tagView)); 1590 this.tagView.onTagCountChanged.bind(this.tagView));
1513 this.bookmarkModel.addObserver('tag-deleted', 1591 this.bookmarkModel.addObserver('tag-deleted',
1520 /* handle input */ 1598 /* handle input */
1521 window.addEventListener('hashchange', this.onHashChange.bind(this)); 1599 window.addEventListener('hashchange', this.onHashChange.bind(this));
1522 window.addEventListener('beforeunload', this.onBeforeUnload.bind(this)); 1600 window.addEventListener('beforeunload', this.onBeforeUnload.bind(this));
1523 this.actionsView.addObserver('save-file', 1601 this.actionsView.addObserver('save-file',
1524 this.bookmarkModel.saveFile.bind(this.bookmarkModel)); 1602 this.bookmarkModel.saveFile.bind(this.bookmarkModel));
1603 this.actionsView.addObserver('export-file',
1604 this.bookmarkModel.exportFile.bind(this.bookmarkModel));
1525 this.actionsView.addObserver('load-file', this.onLoadFile.bind(this)); 1605 this.actionsView.addObserver('load-file', this.onLoadFile.bind(this));
1526 this.actionsView.addObserver('import-file', this.onImportFile.bind(this)); 1606 this.actionsView.addObserver('import-file', this.onImportFile.bind(this));
1527 this.actionsView.addObserver('save-bookmark', 1607 this.actionsView.addObserver('save-bookmark',
1528 this.onSaveBookmark.bind(this)); 1608 this.onSaveBookmark.bind(this));
1529 this.bookmarkView.addObserver('edit-bookmark', 1609 this.bookmarkView.addObserver('edit-bookmark',