diff --git a/chrome/content/zotero/feedSettings.js b/chrome/content/zotero/feedSettings.js new file mode 100644 index 000000000..41734c115 --- /dev/null +++ b/chrome/content/zotero/feedSettings.js @@ -0,0 +1,187 @@ +/* + ***** BEGIN LICENSE BLOCK ***** + + Copyright © 2015 Center for History and New Media + George Mason University, Fairfax, Virginia, USA + http://zotero.org + + This file is part of Zotero. + + Zotero is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Zotero is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with Zotero. If not, see . + + ***** END LICENSE BLOCK ***** +*/ + +////////////////////////////////////////////////////////////////////////////// +// +// Zotero_Feed_Settings +// +////////////////////////////////////////////////////////////////////////////// + +var Zotero_Feed_Settings = new function() { + let urlIsValid = true, + data = null, + feedReader = null, + urlTainted = false; + + let cleanURL = function(url) { + url = url.trim(); + if (!url) return; + + let ios = Components.classes["@mozilla.org/network/io-service;1"] + .getService(Components.interfaces.nsIIOService); + + let cleanUrl; + try { + let uri = ios.newURI(url, null, null); + if (uri.scheme != 'http' && uri.scheme != 'https') { + Zotero.debug(uri.scheme + " is not a supported protocol for feeds."); + } + + cleanUrl = uri.spec; + } catch (e) { + if (e.result == Components.results.NS_ERROR_MALFORMED_URI) { + // Assume it's a URL missing "http://" part + try { + cleanUrl = ios.newURI('http://' + url, null, null).spec; + } catch (e) {} + } + throw e; + } + + if (!cleanUrl) return; + + if (/^https?:\/\/[^\/\s]+\/\S/.test(cleanUrl)) return cleanUrl; + }; + + this.init = function() { + this.toggleAdvancedOptions(false); + + data = window.arguments[0]; + + if (data.url) { + document.getElementById('feed-url').value = data.url; + } + + if (!data.url) { + this.invalidateUrl(); + } else { + // Do not allow to change URL for existing feed + document.getElementById('feed-url').readOnly = true; + } + + if (data.title) { + document.getElementById('feed-title').value = data.title; + } + + let ttl; + if (data.ttl !== undefined) { + ttl = Math.floor(data.ttl / 60); + } else { + ttl = 1; + } + document.getElementById('feed-ttl').value = ttl; + + let cleanAfter = data.cleanAfter; + if (cleanAfter === undefined) cleanAfter = 2; + document.getElementById('feed-cleanAfter').value = cleanAfter; + + if (data.url && !data.urlIsValid) { + this.validateUrl(); + } + }; + + this.invalidateUrl = function() { + urlTainted = true; + if (feedReader) { + feedReader.terminate(); + feedReader = null; + } + + if (!urlIsValid) return; + + urlIsValid = false; + document.getElementById('feed-title').disabled = true; + document.getElementById('feed-ttl').disabled = true; + document.getElementById('feed-cleanAfter').disabled = true; + document.documentElement.getButton('accept').disabled = true; + }; + + this.validateUrl = function() { + if (feedReader) { + feedReader.terminate(); + feedReader = null; + } + + let url = cleanURL(document.getElementById('feed-url').value); + urlTainted = false; + if (!url) return; + + let fr = feedReader = new Zotero.FeedReader(url); + fr.feedProperties + .then( feed => { + if (feedReader !== fr || urlTainted) return; + + let title = document.getElementById('feed-title'); + if (!data.url && feed.title) { + title.value = feed.title; + } + + let ttl = document.getElementById('feed-ttl'); + if (!data.url && feed.ttl) { + ttl.value = Math.floor(feed.ttl / 60) || 1; + } + + document.getElementById('feed-url').value = url; + + urlIsValid = true; + title.disabled = false; + ttl.disabled = false; + document.getElementById('feed-cleanAfter').disabled = false; + document.documentElement.getButton('accept').disabled = false; + }) + .catch( e => { + Zotero.debug(e); + }) + .finally( () => { + if (feedReader === fr) feedReader = null; + }); + }; + + this.accept = function() { + data.url = document.getElementById('feed-url').value; + data.title = document.getElementById('feed-title').value; + data.ttl = document.getElementById('feed-ttl').value * 60; + data.cleanAfter = document.getElementById('feed-cleanAfter').value * 1; + return true; + }; + + this.cancel = function() { + data.cancelled = true; + return true; + }; + + /* + * Show/hide advanced options + * @param {Boolean} [show] If set, indicates whether the advanced + * options should be shown or not. If omitted, the options toggle + */ + this.toggleAdvancedOptions = function(show) { + var opts = document.getElementById("advanced-options-togglable"); + opts.hidden = show !== undefined ? !show : !opts.hidden; + document.getElementById("advanced-options") + .setAttribute("state", opts.hidden ? "closed" : "open"); + window.sizeToContent(); + }; +} \ No newline at end of file diff --git a/chrome/content/zotero/feedSettings.xul b/chrome/content/zotero/feedSettings.xul new file mode 100644 index 000000000..45ebf8014 --- /dev/null +++ b/chrome/content/zotero/feedSettings.xul @@ -0,0 +1,50 @@ + + + + %zoteroDTD; +]> + + +