www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | Submodules | README | LICENSE

commit 2e56e2f659c1254a80665ea9df0c62d139c0eadc
parent 4c94b05023567a2bfa1b1dae480ce87618d03b48
Author: Aurimas Vinckevicius <aurimas.dev@gmail.com>
Date:   Thu,  6 Nov 2014 22:12:12 -0600

Add feed button and Add Feed dialog

Diffstat:
Achrome/content/zotero/feedSettings.js | 188+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Achrome/content/zotero/feedSettings.xul | 51+++++++++++++++++++++++++++++++++++++++++++++++++++
Mchrome/content/zotero/zoteroPane.js | 13+++++++++++++
Mchrome/content/zotero/zoteroPane.xul | 2++
Mchrome/locale/en-US/zotero/zotero.dtd | 13+++++++++++++
Mchrome/skin/default/zotero/overlay.css | 5+++++
Achrome/skin/default/zotero/toolbar-feed-add.png | 0
Mchrome/skin/default/zotero/zotero.css | 8++++++++
8 files changed, 280 insertions(+), 0 deletions(-)

diff --git a/chrome/content/zotero/feedSettings.js 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 <http://www.gnu.org/licenses/>. + + ***** 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 @@ -0,0 +1,50 @@ +<?xml version="1.0"?> +<?xml-stylesheet href="chrome://global/skin/" type="text/css"?> +<?xml-stylesheet href="chrome://zotero/skin/zotero.css" type="text/css"?> +<!DOCTYPE window [ + <!ENTITY % zoteroDTD SYSTEM "chrome://zotero/locale/zotero.dtd" > %zoteroDTD; +]> +<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + title="&zotero.feedSettings.title;" buttons="cancel,accept" + buttonlabelaccept="&zotero.feedSettings.saveButton.label;" + ondialogaccept="Zotero_Feed_Settings.accept()" + ondialogcancel="Zotero_Feed_Settings.cancel()" + id="zotero-feed-settings" + onload="Zotero_Feed_Settings.init()"> + + <script src="include.js"/> + <script src="feedSettings.js"/> + + <vbox> + <hbox align="center"> + <label value="&zotero.feedSettings.url.label;" control="feed-url"/> + <textbox id="feed-url" flex="1" type="search" size="2" + oninput="Zotero_Feed_Settings.invalidateUrl()" + oncommand="Zotero_Feed_Settings.validateUrl()" + focused="true" newlines="replacewithspaces" + style="width: 30em; max-width: 30em"/> + </hbox> + <hbox align="center"> + <label value="&zotero.feedSettings.title.label;" control="feed-url"/> + <textbox id="feed-title" flex="1" newlines="replacewithspaces"/> + </hbox> + <vbox id="advanced-options" class="zotero-advanced-options"> + <hbox onclick="Zotero_Feed_Settings.toggleAdvancedOptions()" class="zotero-advanced-options-label"> + <dropmarker/> + <label value="&zotero.general.advancedOptions.label;"/> + </hbox> + <vbox id="advanced-options-togglable"> + <hbox align="center"> + <label value="&zotero.feedSettings.refresh.label1;" control="feed-ttl"/> + <textbox id="feed-ttl" type="number" min="0" increment="1" size="3"/> + <label value="&zotero.feedSettings.refresh.label2;" control="feed-ttl"/> + </hbox> + <hbox align="center"> + <label value="&zotero.feedSettings.cleanAfter.label1;" control="feed-cleanAfter"/> + <textbox id="feed-cleanAfter" type="number" min="0" increment="1" size="2"/> + <label value="&zotero.feedSettings.cleanAfter.label2;" control="feed-cleanAfter"/> + </hbox> + </vbox> + </vbox> + </vbox> +</dialog> +\ No newline at end of file diff --git a/chrome/content/zotero/zoteroPane.js b/chrome/content/zotero/zoteroPane.js @@ -839,6 +839,19 @@ var ZoteroPane = new function() return collection.saveTx(); }); + this.newFeed = function() { + let data = {}; + window.openDialog('chrome://zotero/content/feedSettings.xul', + null, 'centerscreen, modal', data); + if (!data.cancelled) { + let feed = new Zotero.Feed(); + feed.url = data.url; + feed.name = data.title; + feed.refreshInterval = data.ttl; + feed.cleanupAfter = data.cleanAfter; + feed.save({skipEditCheck: true}); + } + } this.newGroup = function () { this.loadURI(Zotero.Groups.addGroupURL); diff --git a/chrome/content/zotero/zoteroPane.xul b/chrome/content/zotero/zoteroPane.xul @@ -58,6 +58,7 @@ <command id="cmd_zotero_createTimeline" oncommand="Zotero_Timeline_Interface.loadTimeline();"/> <command id="cmd_zotero_rtfScan" oncommand="window.openDialog('chrome://zotero/content/rtfScan.xul', 'rtfScan', 'chrome,centerscreen')"/> <command id="cmd_zotero_newCollection" oncommand="ZoteroPane_Local.newCollection()"/> + <command id="cmd_zotero_newFeed" oncommand="ZoteroPane_Local.newFeed()"/> <command id="cmd_zotero_newSavedSearch" oncommand="ZoteroPane_Local.newSearch()"/> <command id="cmd_zotero_newStandaloneNote" oncommand="ZoteroPane_Local.newNote(event.shiftKey);"/> <command id="cmd_zotero_newChildNote" oncommand="ZoteroPane_Local.newChildNote(event.shiftKey);"/> @@ -102,6 +103,7 @@ <toolbar id="zotero-toolbar" class="toolbar toolbar-primary"> <hbox id="zotero-collections-toolbar" align="center"> <toolbarbutton id="zotero-tb-collection-add" class="zotero-tb-button" tooltiptext="&zotero.toolbar.newCollection.label;" command="cmd_zotero_newCollection"/> + <toolbarbutton id="zotero-tb-feed-add" class="zotero-tb-button" tooltiptext="&zotero.toolbar.newFeed.label;" command="cmd_zotero_newFeed"/> <toolbarbutton id="zotero-tb-group-add" class="zotero-tb-button" tooltiptext="&zotero.toolbar.newGroup;" oncommand="ZoteroPane_Local.newGroup()"/> <spacer flex="1"/> <toolbarbutton id="zotero-tb-actions-menu" class="zotero-tb-button" tooltiptext="&zotero.toolbar.actions.label;" type="menu"> diff --git a/chrome/locale/en-US/zotero/zotero.dtd b/chrome/locale/en-US/zotero/zotero.dtd @@ -10,6 +10,7 @@ <!ENTITY zotero.general.cancel "Cancel"> <!ENTITY zotero.general.refresh "Refresh"> <!ENTITY zotero.general.saveAs "Save As…"> +<!ENTITY zotero.general.advancedOptions.label "Advanced Options"> <!ENTITY zotero.errorReport.title "Zotero Error Report"> <!ENTITY zotero.errorReport.unrelatedMessages "This may include messages unrelated to Zotero."> @@ -103,6 +104,7 @@ <!ENTITY zotero.toolbar.lookup.label "Add Item(s) by Identifier"> <!ENTITY zotero.toolbar.removeItem.label "Remove Item…"> <!ENTITY zotero.toolbar.newCollection.label "New Collection…"> +<!ENTITY zotero.toolbar.newFeed.label "New Feed…"> <!ENTITY zotero.toolbar.newGroup "New Group…"> <!ENTITY zotero.toolbar.newSubcollection.label "New Subcollection…"> <!ENTITY zotero.toolbar.newSavedSearch.label "New Saved Search…"> @@ -254,6 +256,17 @@ <!ENTITY zotero.proxy.recognized.disable.label "Do not automatically redirect requests through previously recognized proxies"> <!ENTITY zotero.proxy.recognized.ignore.label "Ignore"> +<!ENTITY zotero.feedSettings.title "Feed Settings"> +<!ENTITY zotero.feedSettings.saveButton.label "Save"> +<!ENTITY zotero.feedSettings.url.label "URL"> +<!ENTITY zotero.feedSettings.title.label "Title"> +<!ENTITY zotero.feedSettings.refresh.label1 "Refresh Interval:"> +<!ENTITY zotero.feedSettings.refresh.label2 "hour(s)"> +<!ENTITY zotero.feedSettings.title.label "Title"> +<!ENTITY zotero.feedSettings.cleanAfter.label1 "Remove read articles after "> +<!ENTITY zotero.feedSettings.cleanAfter.label2 "day(s)"> + + <!ENTITY zotero.recognizePDF.recognizing.label "Retrieving Metadata…"> <!ENTITY zotero.recognizePDF.cancel.label "Cancel"> <!ENTITY zotero.recognizePDF.pdfName.label "PDF Name"> diff --git a/chrome/skin/default/zotero/overlay.css b/chrome/skin/default/zotero/overlay.css @@ -278,6 +278,11 @@ list-style-image: url('chrome://zotero/skin/toolbar-collection-add.png'); } +#zotero-tb-feed-add +{ + list-style-image: url('chrome://zotero/skin/toolbar-feed-add.png'); +} + #zotero-tb-group-add { list-style-image: url('chrome://zotero/skin/group_add.png'); diff --git a/chrome/skin/default/zotero/toolbar-feed-add.png b/chrome/skin/default/zotero/toolbar-feed-add.png Binary files differ. diff --git a/chrome/skin/default/zotero/zotero.css b/chrome/skin/default/zotero/zotero.css @@ -441,6 +441,14 @@ label.zotero-text-link { max-width: 29.5em; } +.zotero-advanced-options>.zotero-advanced-options-label>dropmarker { + list-style-image: url("chrome://browser/skin/toolbarbutton-dropdown-arrow.png"); + transform: rotate(270deg); +} + +.zotero-advanced-options[state=open]>.zotero-advanced-options-label>dropmarker { + transform: none; +} /* BEGIN 2X BLOCK -- DO NOT EDIT MANUALLY -- USE 2XIZE */ @media (min-resolution: 1.5dppx) {