Bug 1477669 - remove feed preview code and associated files/code, r=flod,mak,nika

Differential Revision: https://phabricator.services.mozilla.com/D8524

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Gijs Kruitbosch 2018-10-16 12:47:36 +00:00
Родитель 074a8bb5ea
Коммит 9048f58f8f
96 изменённых файлов: 14 добавлений и 4054 удалений

Просмотреть файл

@ -742,10 +742,6 @@ pref("layout.spellcheckDefault", 1);
pref("browser.send_pings", false);
pref("browser.feeds.handler", "ask");
pref("browser.videoFeeds.handler", "ask");
pref("browser.audioFeeds.handler", "ask");
// At startup, if the handler service notices that the version number in the
// region.properties file is newer than the version number in the handler
// service datastore, it will add any new handlers it finds in the prefs (as

Просмотреть файл

@ -1,409 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
ChromeUtils.defineModuleGetter(this, "DeferredTask",
"resource://gre/modules/DeferredTask.jsm");
const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
const TYPE_MAYBE_AUDIO_FEED = "application/vnd.mozilla.maybe.audio.feed";
const TYPE_MAYBE_VIDEO_FEED = "application/vnd.mozilla.maybe.video.feed";
const PREF_SHOW_FIRST_RUN_UI = "browser.feeds.showFirstRunUI";
const PREF_SELECTED_APP = "browser.feeds.handlers.application";
const PREF_SELECTED_ACTION = "browser.feeds.handler";
const PREF_SELECTED_READER = "browser.feeds.handler.default";
const PREF_VIDEO_SELECTED_APP = "browser.videoFeeds.handlers.application";
const PREF_VIDEO_SELECTED_ACTION = "browser.videoFeeds.handler";
const PREF_VIDEO_SELECTED_READER = "browser.videoFeeds.handler.default";
const PREF_AUDIO_SELECTED_APP = "browser.audioFeeds.handlers.application";
const PREF_AUDIO_SELECTED_ACTION = "browser.audioFeeds.handler";
const PREF_AUDIO_SELECTED_READER = "browser.audioFeeds.handler.default";
const PREF_UPDATE_DELAY = 2000;
const SETTABLE_PREFS = new Set([
PREF_VIDEO_SELECTED_ACTION,
PREF_AUDIO_SELECTED_ACTION,
PREF_SELECTED_ACTION,
PREF_VIDEO_SELECTED_READER,
PREF_AUDIO_SELECTED_READER,
PREF_SELECTED_READER,
]);
const EXECUTABLE_PREFS = new Set([
PREF_SELECTED_APP,
PREF_VIDEO_SELECTED_APP,
PREF_AUDIO_SELECTED_APP,
]);
const VALID_ACTIONS = new Set(["ask", "reader", "bookmarks"]);
const VALID_READERS = new Set(["client", "default", "bookmarks"]);
XPCOMUtils.defineLazyPreferenceGetter(this, "SHOULD_LOG",
"feeds.log", false);
function LOG(str) {
if (SHOULD_LOG)
dump("*** Feeds: " + str + "\n");
}
function getPrefActionForType(t) {
switch (t) {
case Ci.nsIFeed.TYPE_VIDEO:
return PREF_VIDEO_SELECTED_ACTION;
case Ci.nsIFeed.TYPE_AUDIO:
return PREF_AUDIO_SELECTED_ACTION;
default:
return PREF_SELECTED_ACTION;
}
}
function getPrefReaderForType(t) {
switch (t) {
case Ci.nsIFeed.TYPE_VIDEO:
return PREF_VIDEO_SELECTED_READER;
case Ci.nsIFeed.TYPE_AUDIO:
return PREF_AUDIO_SELECTED_READER;
default:
return PREF_SELECTED_READER;
}
}
function getPrefAppForType(t) {
switch (t) {
case Ci.nsIFeed.TYPE_VIDEO:
return PREF_VIDEO_SELECTED_APP;
case Ci.nsIFeed.TYPE_AUDIO:
return PREF_AUDIO_SELECTED_APP;
default:
return PREF_SELECTED_APP;
}
}
/**
* Maps a feed type to a maybe-feed mimetype.
*/
function getMimeTypeForFeedType(aFeedType) {
switch (aFeedType) {
case Ci.nsIFeed.TYPE_VIDEO:
return TYPE_MAYBE_VIDEO_FEED;
case Ci.nsIFeed.TYPE_AUDIO:
return TYPE_MAYBE_AUDIO_FEED;
default:
return TYPE_MAYBE_FEED;
}
}
/**
* The Feed Handler object manages discovery of RSS/ATOM feeds in web pages
* and shows UI when they are discovered.
*/
var FeedHandler = {
_prefChangeCallback: null,
/**
* Get the human-readable display name of a file. This could be the
* application name.
* @param file
* A nsIFile to look up the name of
* @return The display name of the application represented by the file.
*/
_getFileDisplayName(file) {
switch (AppConstants.platform) {
case "win":
if (file instanceof Ci.nsILocalFileWin) {
try {
return file.getVersionInfoField("FileDescription");
} catch (e) {}
}
break;
case "macosx":
if (file instanceof Ci.nsILocalFileMac) {
try {
return file.bundleDisplayName;
} catch (e) {}
}
break;
}
return file.leafName;
},
_chooseClientApp(aTitle, aTypeName, aBrowser) {
const prefName = getPrefAppForType(aTypeName);
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
fp.init(window, aTitle, Ci.nsIFilePicker.modeOpen);
fp.appendFilters(Ci.nsIFilePicker.filterApps);
fp.open((aResult) => {
if (aResult == Ci.nsIFilePicker.returnOK) {
let selectedApp = fp.file;
if (selectedApp) {
// XXXben - we need to compare this with the running instance
// executable just don't know how to do that via script
// XXXmano TBD: can probably add this to nsIShellService
let appName = "";
switch (AppConstants.platform) {
case "win":
appName = AppConstants.MOZ_APP_NAME + ".exe";
break;
case "macosx":
appName = AppConstants.MOZ_MACBUNDLE_NAME;
break;
default:
appName = AppConstants.MOZ_APP_NAME + "-bin";
break;
}
if (fp.file.leafName != appName) {
Services.prefs.setComplexValue(prefName, Ci.nsIFile, selectedApp);
aBrowser.messageManager.sendAsyncMessage("FeedWriter:SetApplicationLauncherMenuItem",
{ name: this._getFileDisplayName(selectedApp),
type: "SelectedAppMenuItem" });
}
}
}
});
},
executeClientApp(aSpec, aTitle, aSubtitle, aFeedHandler) {
// aFeedHandler is either "default", indicating the system default reader, or a pref-name containing
// an nsIFile pointing to the feed handler's executable.
let clientApp = null;
if (aFeedHandler == "default") {
clientApp = Cc["@mozilla.org/browser/shell-service;1"]
.getService(Ci.nsIShellService)
.defaultFeedReader;
} else {
clientApp = Services.prefs.getComplexValue(aFeedHandler, Ci.nsIFile);
}
// For the benefit of applications that might know how to deal with more
// URLs than just feeds, send feed: URLs in the following format:
//
// http urls: replace scheme with feed, e.g.
// http://foo.com/index.rdf -> feed://foo.com/index.rdf
// other urls: prepend feed: scheme, e.g.
// https://foo.com/index.rdf -> feed:https://foo.com/index.rdf
let feedURI = Services.io.newURI(aSpec);
if (feedURI.schemeIs("http")) {
feedURI = feedURI.mutate()
.setScheme("feed")
.finalize();
aSpec = feedURI.spec;
} else {
aSpec = "feed:" + aSpec;
}
// Retrieving the shell service might fail on some systems, most
// notably systems where GNOME is not installed.
try {
let ss = Cc["@mozilla.org/browser/shell-service;1"]
.getService(Ci.nsIShellService);
ss.openApplicationWithURI(clientApp, aSpec);
} catch (e) {
// If we couldn't use the shell service, fallback to using a
// nsIProcess instance
let p = Cc["@mozilla.org/process/util;1"]
.createInstance(Ci.nsIProcess);
p.init(clientApp);
p.run(false, [aSpec], 1);
}
},
// nsISupports
QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver,
Ci.nsISupportsWeakReference]),
init() {
window.messageManager.addMessageListener("FeedWriter:ChooseClientApp", this);
window.messageManager.addMessageListener("FeedWriter:GetSubscriptionUI", this);
window.messageManager.addMessageListener("FeedWriter:SetFeedPrefsAndSubscribe", this);
window.messageManager.addMessageListener("FeedWriter:ShownFirstRun", this);
Services.ppmm.addMessageListener("FeedConverter:ExecuteClientApp", this);
const prefs = Services.prefs;
prefs.addObserver(PREF_SELECTED_ACTION, this, true);
prefs.addObserver(PREF_SELECTED_READER, this, true);
prefs.addObserver(PREF_VIDEO_SELECTED_ACTION, this, true);
prefs.addObserver(PREF_VIDEO_SELECTED_READER, this, true);
prefs.addObserver(PREF_AUDIO_SELECTED_ACTION, this, true);
prefs.addObserver(PREF_AUDIO_SELECTED_READER, this, true);
},
uninit() {
Services.ppmm.removeMessageListener("FeedConverter:ExecuteClientApp", this);
this._prefChangeCallback = null;
},
// nsIObserver
observe(subject, topic, data) {
if (topic == "nsPref:changed") {
LOG(`Pref changed ${data}`);
if (this._prefChangeCallback) {
this._prefChangeCallback.disarm();
}
// Multiple prefs are set at the same time, debounce to reduce noise
// This can happen in one feed and we want to message all feed pages
this._prefChangeCallback = new DeferredTask(() => {
this._prefChanged(data);
}, PREF_UPDATE_DELAY);
this._prefChangeCallback.arm();
}
},
_prefChanged(prefName) {
// Don't observe for PREF_*SELECTED_APP as user likely just picked one
// That is also handled by SetApplicationLauncherMenuItem call
// Rather than the others which happen on subscription
switch (prefName) {
case PREF_SELECTED_READER:
case PREF_VIDEO_SELECTED_READER:
case PREF_AUDIO_SELECTED_READER:
case PREF_SELECTED_ACTION:
case PREF_VIDEO_SELECTED_ACTION:
case PREF_AUDIO_SELECTED_ACTION:
const response = {
default: this._getReaderForType(Ci.nsIFeed.TYPE_FEED),
[Ci.nsIFeed.TYPE_AUDIO]: this._getReaderForType(Ci.nsIFeed.TYPE_AUDIO),
[Ci.nsIFeed.TYPE_VIDEO]: this._getReaderForType(Ci.nsIFeed.TYPE_VIDEO),
};
Services.mm.broadcastAsyncMessage("FeedWriter:PreferenceUpdated",
response);
break;
}
},
_initSubscriptionUIResponse(feedType) {
let showFirstRunUI = Services.prefs.getBoolPref(PREF_SHOW_FIRST_RUN_UI, true);
const response = { showFirstRunUI };
let selectedClientApp;
const feedTypePref = getPrefAppForType(feedType);
try {
selectedClientApp = Services.prefs.getComplexValue(feedTypePref, Ci.nsIFile);
} catch (ex) {
// Just do nothing, then we won't bother populating
}
let defaultClientApp = null;
try {
// This can sometimes not exist
defaultClientApp = Cc["@mozilla.org/browser/shell-service;1"]
.getService(Ci.nsIShellService)
.defaultFeedReader;
} catch (ex) {
// Just do nothing, then we don't bother populating
}
if (selectedClientApp && selectedClientApp.exists()) {
if (defaultClientApp && selectedClientApp.path != defaultClientApp.path) {
// Only set the default menu item if it differs from the selected one
response.defaultMenuItem = this._getFileDisplayName(defaultClientApp);
}
response.selectedMenuItem = this._getFileDisplayName(selectedClientApp);
}
response.reader = this._getReaderForType(feedType);
return response;
},
_setPref(aPrefName, aPrefValue, aIsComplex = false) {
LOG(`FeedWriter._setPref ${aPrefName}`);
// Ensure we have a pref that is settable
if (aPrefName && SETTABLE_PREFS.has(aPrefName)) {
if (aIsComplex) {
Services.prefs.setStringPref(aPrefName, aPrefValue);
} else {
Services.prefs.setCharPref(aPrefName, aPrefValue);
}
} else {
LOG(`FeedWriter._setPref ${aPrefName} not allowed`);
}
},
_getReaderForType(feedType) {
let handler = Services.prefs.getCharPref(getPrefReaderForType(feedType), "bookmarks");
const alwaysUse = this._getAlwaysUseState(feedType);
const action = Services.prefs.getCharPref(getPrefActionForType(feedType));
return { handler, alwaysUse, action };
},
_getAlwaysUseState(feedType) {
try {
return Services.prefs.getCharPref(getPrefActionForType(feedType)) != "ask";
} catch (ex) { }
return false;
},
receiveMessage(msg) {
switch (msg.name) {
case "FeedWriter:GetSubscriptionUI":
const response = this._initSubscriptionUIResponse(msg.data.feedType);
msg.target.messageManager
.sendAsyncMessage("FeedWriter:GetSubscriptionUIResponse",
response);
break;
case "FeedWriter:ChooseClientApp":
this._chooseClientApp(msg.data.title, msg.data.feedType, msg.target);
break;
case "FeedWriter:ShownFirstRun":
Services.prefs.setBoolPref(PREF_SHOW_FIRST_RUN_UI, false);
break;
case "FeedWriter:SetFeedPrefsAndSubscribe":
const settings = msg.data;
if (!settings.action || !VALID_ACTIONS.has(settings.action)) {
LOG(`Invalid action ${settings.action}`);
return;
}
if (!settings.reader || !VALID_READERS.has(settings.reader)) {
LOG(`Invalid reader ${settings.reader}`);
return;
}
Services.telemetry.scalarAdd("browser.feeds.feed_subscribed", 1);
const actionPref = getPrefActionForType(settings.feedType);
this._setPref(actionPref, settings.action);
const readerPref = getPrefReaderForType(settings.feedType);
this._setPref(readerPref, settings.reader);
const feedService = Cc["@mozilla.org/browser/feeds/result-service;1"].
getService(Ci.nsIFeedResultService);
feedService.addToClientReader(settings.feedLocation,
settings.feedTitle,
settings.feedSubtitle,
settings.feedType,
settings.reader);
break;
case "FeedConverter:ExecuteClientApp":
// Always check feedHandler is from a set array of executable prefs
if (EXECUTABLE_PREFS.has(msg.data.feedHandler)) {
this.executeClientApp(msg.data.spec, msg.data.title,
msg.data.subtitle, msg.data.feedHandler);
} else {
LOG(`FeedConverter:ExecuteClientApp - Will not exec ${msg.data.feedHandler}`);
}
break;
}
},
};

Просмотреть файл

@ -489,10 +489,6 @@ toolbar:not(#TabsToolbar) > #personal-bookmarks {
-moz-box-flex: 1;
}
#PanelUI-feeds > .feed-toolbarbutton:-moz-locale-dir(rtl) {
direction: rtl;
}
#appMenu_historyMenu > .bookmark-item,
#appMenu-library-recentlyClosedTabs > .panel-subview-body > .bookmark-item,
#appMenu-library-recentlyClosedWindows > .panel-subview-body > .bookmark-item,

Просмотреть файл

@ -1352,7 +1352,6 @@ var gBrowserInit = {
gPageStyleMenu.init();
LanguageDetectionListener.init();
BrowserOnClick.init();
FeedHandler.init();
ContentBlocking.init();
CaptivePortalWatcher.init();
ZoomUI.init(window);
@ -1933,8 +1932,6 @@ var gBrowserInit = {
BrowserOnClick.uninit();
FeedHandler.uninit();
ContentBlocking.uninit();
CaptivePortalWatcher.uninit();

Просмотреть файл

@ -21,7 +21,6 @@ for (let script of [
"chrome://browser/content/browser-captivePortal.js",
"chrome://browser/content/browser-compacttheme.js",
"chrome://browser/content/browser-contentblocking.js",
"chrome://browser/content/browser-feeds.js",
"chrome://browser/content/browser-media.js",
"chrome://browser/content/browser-pageActions.js",
"chrome://browser/content/browser-places.js",

Просмотреть файл

@ -122,9 +122,6 @@ with Files("browser-compacttheme.js"):
with Files("browser-customization.js"):
BUG_COMPONENT = ("Firefox", "Toolbars and Customization")
with Files("browser-feeds.js"):
BUG_COMPONENT = ("Firefox", "Toolbars and Customization")
with Files("browser-fullZoom.js"):
BUG_COMPONENT = ("Firefox", "Tabbed Browsing")

Просмотреть файл

@ -37,8 +37,7 @@ var gTests = [
preventDefault: true,
},
// The next test was once handling feedService.forcePreview(). Now it should
// just be like Alt click.
// The next test should just be like Alt click.
{
desc: "Shift+Alt left click",
setup() {

Просмотреть файл

@ -1,6 +0,0 @@
<rss version="2.0">
<channel>
<link>http://example.org/</link>
<title>t</title>
</channel>
</rss>

Просмотреть файл

@ -1,17 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=458579
-->
<head>
<title>Test for page info feeds tab</title>
<!-- Straight up standard -->
<link rel="alternate" type="application/atom+xml" title="1" href="/1.atom" />
<link rel="alternate" type="application/rss+xml" title="2" href="/2.rss" />
<link rel="feed" title="3" href="/3.xml" />
</head>
<body>
</body>
</html>

Просмотреть файл

@ -1,27 +0,0 @@
function getTestPlugin(pluginName) {
var ph = SpecialPowers.Cc["@mozilla.org/plugin/host;1"]
.getService(SpecialPowers.Ci.nsIPluginHost);
var tags = ph.getPluginTags();
var name = pluginName || "Test Plug-in";
for (var tag of tags) {
if (tag.name == name) {
return tag;
}
}
ok(false, "Could not find plugin tag with plugin name '" + name + "'");
return null;
}
// call this to set the test plugin(s) initially expected enabled state.
// it will automatically be reset to it's previous value after the test
// ends
function setTestPluginEnabledState(newEnabledState, pluginName) {
var plugin = getTestPlugin(pluginName);
var oldEnabledState = plugin.enabledState;
plugin.enabledState = newEnabledState;
SimpleTest.registerCleanupFunction(function() {
getTestPlugin(pluginName).enabledState = oldEnabledState;
});
}

Просмотреть файл

@ -1,22 +0,0 @@
[DEFAULT]
support-files =
audio.ogg
bug395533-data.txt
contextmenu_common.js
ctxmenu-image.png
head_plain.js
offlineByDefault.js
offlineChild.cacheManifest
offlineChild.cacheManifest^headers^
offlineChild.html
offlineChild2.cacheManifest
offlineChild2.cacheManifest^headers^
offlineChild2.html
offlineEvent.cacheManifest
offlineEvent.cacheManifest^headers^
offlineEvent.html
subtst_contextmenu.html
video.ogg
!/image/test/mochitest/blue.png
[test_bug395533.html]

Просмотреть файл

@ -1,12 +0,0 @@
var offlineByDefault = {
defaultValue: false,
set(allow) {
this.defaultValue = SpecialPowers.Services.prefs.getBoolPref("offline-apps.allow_by_default", false);
SpecialPowers.Services.prefs.setBoolPref("offline-apps.allow_by_default", allow);
},
reset() {
SpecialPowers.Services.prefs.setBoolPref("offline-apps.allow_by_default", this.defaultValue);
},
};
offlineByDefault.set(false);

Просмотреть файл

@ -1,2 +0,0 @@
CACHE MANIFEST
offlineChild.html

Просмотреть файл

@ -1 +0,0 @@
Content-Type: text/cache-manifest

Просмотреть файл

@ -1,20 +0,0 @@
<html manifest="offlineChild.cacheManifest">
<head>
<title></title>
<script type="text/javascript">
function finish(success) {
window.parent.postMessage(success ? "success" : "failure", "*");
}
applicationCache.oncached = function() { finish(true); };
applicationCache.onnoupdate = function() { finish(true); };
applicationCache.onerror = function() { finish(false); };
</script>
</head>
<body>
<h1>Child</h1>
</body>
</html>

Просмотреть файл

@ -1,2 +0,0 @@
CACHE MANIFEST
offlineChild2.html

Просмотреть файл

@ -1 +0,0 @@
Content-Type: text/cache-manifest

Просмотреть файл

@ -1,20 +0,0 @@
<html manifest="offlineChild2.cacheManifest">
<head>
<title></title>
<script type="text/javascript">
function finish(success) {
window.parent.postMessage(success ? "success" : "failure", "*");
}
applicationCache.oncached = function() { finish(true); };
applicationCache.onnoupdate = function() { finish(true); };
applicationCache.onerror = function() { finish(false); };
</script>
</head>
<body>
<h1>Child</h1>
</body>
</html>

Просмотреть файл

@ -1,2 +0,0 @@
CACHE MANIFEST
offlineChild.html

Просмотреть файл

@ -1 +0,0 @@
Content-Type: text/cache-manifest

Просмотреть файл

@ -1,9 +0,0 @@
<html manifest="offlineEvent.cacheManifest">
<head>
<title></title>
</head>
<body>
<h1>Child</h1>
</body>
</html>

Просмотреть файл

@ -1,38 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=395533
-->
<head>
<title>Test for Bug 395533</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=395533">Mozilla Bug 395533</a>
<p id="display"><iframe id="testFrame" src="bug395533-data.txt"></iframe></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 395533 **/
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
// Need privs because the feed seems to have an about:feeds principal or some
// such. It's not same-origin with us in any case.
is(SpecialPowers.wrap($("testFrame")).contentDocument.documentElement.id, "",
"Text got sniffed as a feed?");
});
addLoadEvent(SimpleTest.finish);
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -44,7 +44,6 @@ browser.jar:
#ifndef MOZILLA_OFFICIAL
content/browser/browser-development-helpers.js (content/browser-development-helpers.js)
#endif
content/browser/browser-feeds.js (content/browser-feeds.js)
content/browser/browser-fullScreenAndPointerLock.js (content/browser-fullScreenAndPointerLock.js)
content/browser/browser-fullZoom.js (content/browser-fullZoom.js)
content/browser/browser-gestureSupport.js (content/browser-gestureSupport.js)

Просмотреть файл

@ -13,10 +13,6 @@ SPHINX_TREES['tabbrowser'] = 'content/docs/tabbrowser'
with Files('content/docs/sslerrorreport/**'):
SCHEDULES.exclusive = ['docs']
MOCHITEST_MANIFESTS += [
'content/test/general/mochitest.ini',
]
MOCHITEST_CHROME_MANIFESTS += [
'content/test/chrome/chrome.ini',
]

Просмотреть файл

@ -60,10 +60,6 @@ static const RedirEntry kRedirMap[] = {
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
nsIAboutModule::ALLOW_SCRIPT |
nsIAboutModule::HIDE_FROM_ABOUTABOUT },
{ "feeds", "chrome://browser/content/feeds/subscribe.xhtml",
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
nsIAboutModule::ALLOW_SCRIPT |
nsIAboutModule::HIDE_FROM_ABOUTABOUT },
{ "policies", "chrome://browser/content/policies/aboutPolicies.xhtml",
nsIAboutModule::ALLOW_SCRIPT },
{ "privatebrowsing", "chrome://browser/content/aboutPrivateBrowsing.xhtml",

Просмотреть файл

@ -21,7 +21,6 @@ FINAL_LIBRARY = 'xul'
LOCAL_INCLUDES += [
'../about',
'../dirprovider',
'../feeds',
'../migration',
'../sessionstore',
'../shell',

Просмотреть файл

@ -21,15 +21,6 @@
#define NS_RDF_FORWARDPROXY_INFER_DATASOURCE_CID \
{ 0x7a024bcf, 0xedd5, 0x4d9a, { 0x86, 0x14, 0xd4, 0x4b, 0xe1, 0xda, 0xda, 0xd3 } }
#define NS_FEEDSNIFFER_CID \
{ 0x6893e69, 0x71d8, 0x4b23, { 0x81, 0xeb, 0x80, 0x31, 0x4d, 0xaf, 0x3e, 0x66 } }
#define NS_FEEDSNIFFER_CONTRACTID \
"@mozilla.org/browser/feeds/sniffer;1"
#define NS_ABOUTFEEDS_CID \
{ 0x12ff56ec, 0x58be, 0x402c, { 0xb0, 0x57, 0x1, 0xf9, 0x61, 0xde, 0x96, 0x9b } }
// 136e2c4d-c5a4-477c-b131-d93d7d704f64
#define NS_PRIVATE_BROWSING_SERVICE_WRAPPER_CID \
{ 0x136e2c4d, 0xc5a4, 0x477c, { 0xb1, 0x31, 0xd9, 0x3d, 0x7d, 0x70, 0x4f, 0x64 } }

Просмотреть файл

@ -24,7 +24,6 @@
#include "nsIEHistoryEnumerator.h"
#endif
#include "nsFeedSniffer.h"
#include "AboutRedirector.h"
#include "nsIAboutModule.h"
@ -51,15 +50,12 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacAttributionService)
NS_GENERIC_FACTORY_CONSTRUCTOR(nsIEHistoryEnumerator)
#endif
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFeedSniffer)
NS_DEFINE_NAMED_CID(NS_BROWSERDIRECTORYPROVIDER_CID);
#if defined(XP_WIN)
NS_DEFINE_NAMED_CID(NS_SHELLSERVICE_CID);
#elif defined(MOZ_WIDGET_GTK)
NS_DEFINE_NAMED_CID(NS_SHELLSERVICE_CID);
#endif
NS_DEFINE_NAMED_CID(NS_FEEDSNIFFER_CID);
NS_DEFINE_NAMED_CID(NS_BROWSER_ABOUT_REDIRECTOR_CID);
#if defined(XP_WIN)
NS_DEFINE_NAMED_CID(NS_WINIEHISTORYENUMERATOR_CID);
@ -78,7 +74,6 @@ static const mozilla::Module::CIDEntry kBrowserCIDs[] = {
#elif defined(MOZ_WIDGET_GTK)
{ &kNS_SHELLSERVICE_CID, false, nullptr, nsGNOMEShellServiceConstructor },
#endif
{ &kNS_FEEDSNIFFER_CID, false, nullptr, nsFeedSnifferConstructor },
{ &kNS_BROWSER_ABOUT_REDIRECTOR_CID, false, nullptr, AboutRedirector::Create },
#if defined(XP_WIN)
{ &kNS_WINIEHISTORYENUMERATOR_CID, false, nullptr, nsIEHistoryEnumeratorConstructor },
@ -100,11 +95,9 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = {
#elif defined(MOZ_WIDGET_GTK)
{ NS_SHELLSERVICE_CONTRACTID, &kNS_SHELLSERVICE_CID },
#endif
{ NS_FEEDSNIFFER_CONTRACTID, &kNS_FEEDSNIFFER_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "blocked", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "certerror", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "tabcrashed", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "feeds", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "privatebrowsing", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "rights", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "robots", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
@ -134,7 +127,6 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = {
static const mozilla::Module::CategoryEntry kBrowserCategories[] = {
{ XPCOM_DIRECTORY_PROVIDER_CATEGORY, "browser-directory-provider", NS_BROWSERDIRECTORYPROVIDER_CONTRACTID },
{ NS_CONTENT_SNIFFER_CATEGORY, "Feed Sniffer", NS_FEEDSNIFFER_CONTRACTID },
{ nullptr }
};

Просмотреть файл

@ -571,9 +571,6 @@
onclick="PanelUI.hide();"/>
</panelview>
<panelview id="PanelUI-feeds" flex="1" oncommand="FeedHandler.subscribeToFeed(null, event);">
</panelview>
<panelview id="PanelUI-containers" flex="1">
<vbox id="PanelUI-containersItems"/>
</panelview>

Просмотреть файл

@ -1,10 +1,2 @@
component {229fa115-9412-4d32-baf3-2fc407f76fb1} FeedConverter.js
contract @mozilla.org/streamconv;1?from=application/vnd.mozilla.maybe.feed&to=*/* {229fa115-9412-4d32-baf3-2fc407f76fb1}
contract @mozilla.org/streamconv;1?from=application/vnd.mozilla.maybe.video.feed&to=*/* {229fa115-9412-4d32-baf3-2fc407f76fb1}
contract @mozilla.org/streamconv;1?from=application/vnd.mozilla.maybe.audio.feed&to=*/* {229fa115-9412-4d32-baf3-2fc407f76fb1}
component {2376201c-bbc6-472f-9b62-7548040a61c6} FeedConverter.js
contract @mozilla.org/browser/feeds/result-service;1 {2376201c-bbc6-472f-9b62-7548040a61c6}
component {49bb6593-3aff-4eb3-a068-2712c28bd58e} FeedWriter.js
contract @mozilla.org/browser/feeds/result-writer;1 {49bb6593-3aff-4eb3-a068-2712c28bd58e}
component {792a7e82-06a0-437c-af63-b2d12e808acc} WebContentConverter.js
contract @mozilla.org/embeddor.implemented/web-content-handler-registrar;1 {792a7e82-06a0-437c-af63-b2d12e808acc}

Просмотреть файл

@ -1,415 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
function LOG(str) {
dump("*** " + str + "\n");
}
const FS_CONTRACTID = "@mozilla.org/browser/feeds/result-service;1";
const FPH_CONTRACTID = "@mozilla.org/network/protocol;1?name=feed";
const PCPH_CONTRACTID = "@mozilla.org/network/protocol;1?name=pcast";
const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
const TYPE_MAYBE_VIDEO_FEED = "application/vnd.mozilla.maybe.video.feed";
const TYPE_MAYBE_AUDIO_FEED = "application/vnd.mozilla.maybe.audio.feed";
const TYPE_ANY = "*/*";
const PREF_SELECTED_APP = "browser.feeds.handlers.application";
const PREF_SELECTED_ACTION = "browser.feeds.handler";
const PREF_SELECTED_READER = "browser.feeds.handler.default";
const PREF_VIDEO_SELECTED_APP = "browser.videoFeeds.handlers.application";
const PREF_VIDEO_SELECTED_ACTION = "browser.videoFeeds.handler";
const PREF_VIDEO_SELECTED_READER = "browser.videoFeeds.handler.default";
const PREF_AUDIO_SELECTED_APP = "browser.audioFeeds.handlers.application";
const PREF_AUDIO_SELECTED_ACTION = "browser.audioFeeds.handler";
const PREF_AUDIO_SELECTED_READER = "browser.audioFeeds.handler.default";
function getPrefAppForType(t) {
switch (t) {
case Ci.nsIFeed.TYPE_VIDEO:
return PREF_VIDEO_SELECTED_APP;
case Ci.nsIFeed.TYPE_AUDIO:
return PREF_AUDIO_SELECTED_APP;
default:
return PREF_SELECTED_APP;
}
}
function getPrefActionForType(t) {
switch (t) {
case Ci.nsIFeed.TYPE_VIDEO:
return PREF_VIDEO_SELECTED_ACTION;
case Ci.nsIFeed.TYPE_AUDIO:
return PREF_AUDIO_SELECTED_ACTION;
default:
return PREF_SELECTED_ACTION;
}
}
function getPrefReaderForType(t) {
switch (t) {
case Ci.nsIFeed.TYPE_VIDEO:
return PREF_VIDEO_SELECTED_READER;
case Ci.nsIFeed.TYPE_AUDIO:
return PREF_AUDIO_SELECTED_READER;
default:
return PREF_SELECTED_READER;
}
}
XPCOMUtils.defineLazyPreferenceGetter(this, "gCanFrameFeeds",
"browser.feeds.unsafelyFrameFeeds", false);
function FeedConverter() {
}
FeedConverter.prototype = {
classID: Components.ID("{229fa115-9412-4d32-baf3-2fc407f76fb1}"),
/**
* This is the downloaded text data for the feed.
*/
_data: null,
/**
* This is the object listening to the conversion, which is ultimately the
* docshell for the load.
*/
_listener: null,
/**
* Records if the feed was sniffed
*/
_sniffed: false,
/**
* See nsIStreamConverter.idl
*/
convert(sourceStream, sourceType, destinationType,
context) {
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
},
/**
* See nsIStreamConverter.idl
*/
asyncConvertData(sourceType, destinationType,
listener, context) {
this._listener = listener;
},
/**
* Whether or not the preview page is being forced.
*/
_forcePreviewPage: false,
/**
* Release our references to various things once we're done using them.
*/
_releaseHandles() {
this._listener = null;
this._request = null;
this._processor = null;
},
/**
* See nsIFeedResultListener.idl
*/
handleResult(result) {
// Feeds come in various content types, which our feed sniffer coerces to
// the maybe.feed type. However, feeds are used as a transport for
// different data types, e.g. news/blogs (traditional feed), video/audio
// (podcasts) and photos (photocasts, photostreams). Each of these is
// different in that there's a different class of application suitable for
// handling feeds of that type, but without a content-type differentiation
// it is difficult for us to disambiguate.
//
// The other problem is that if the user specifies an auto-action handler
// for one feed application, the fact that the content type is shared means
// that all other applications will auto-load with that handler too,
// regardless of the content-type.
//
// This means that content-type alone is not enough to determine whether
// or not a feed should be auto-handled. This means that for feeds we need
// to always use this stream converter, even when an auto-action is
// specified, not the basic one provided by WebContentConverter. This
// converter needs to consume all of the data and parse it, and based on
// that determination make a judgment about type.
//
// Since there are no content types for this content, and I'm not going to
// invent any, the upshot is that while a user can set an auto-handler for
// generic feed content, the system will prevent them from setting an auto-
// handler for other stream types. In those cases, the user will always see
// the preview page and have to select a handler. We can guess and show
// a client handler.
//
// If this is just a feed, not some kind of specialized application, then
// auto-handlers can be set and we should obey them.
try {
let feedService =
Cc["@mozilla.org/browser/feeds/result-service;1"].
getService(Ci.nsIFeedResultService);
if (!this._forcePreviewPage && result.doc) {
let feed = result.doc.QueryInterface(Ci.nsIFeed);
let handler = Services.prefs.getCharPref(getPrefActionForType(feed.type), "ask");
if (handler != "ask") {
if (handler == "reader")
handler = Services.prefs.getCharPref(getPrefReaderForType(feed.type), "bookmarks");
try {
let title = feed.title ? feed.title.plainText() : "";
let desc = feed.subtitle ? feed.subtitle.plainText() : "";
feedService.addToClientReader(result.uri.spec, title, desc, feed.type, handler);
return;
} catch (ex) { /* fallback to preview mode */ }
}
}
let chromeChannel;
// handling a redirect, hence forwarding the loadInfo from the old channel
// to the newchannel.
let oldChannel = this._request.QueryInterface(Ci.nsIChannel);
let loadInfo = oldChannel.loadInfo;
// If there was no automatic handler, or this was a podcast,
// photostream or some other kind of application, show the preview page
// if the parser returned a document.
if (result.doc) {
// Store the result in the result service so that the display
// page can access it.
feedService.addFeedResult(result);
// Now load the actual XUL document.
let aboutFeedsURI = Services.io.newURI("about:feeds");
chromeChannel = Services.io.newChannelFromURIWithLoadInfo(aboutFeedsURI, loadInfo);
chromeChannel.originalURI = result.uri;
// carry the origin attributes from the channel that loaded the feed.
chromeChannel.owner =
Services.scriptSecurityManager.createCodebasePrincipal(aboutFeedsURI,
loadInfo.originAttributes);
} else {
chromeChannel = Services.io.newChannelFromURIWithLoadInfo(result.uri, loadInfo);
}
chromeChannel.loadGroup = this._request.loadGroup;
chromeChannel.asyncOpen2(this._listener);
} finally {
this._releaseHandles();
}
},
/**
* See nsIStreamListener.idl
*/
onDataAvailable(request, context, inputStream,
sourceOffset, count) {
if (this._processor)
this._processor.onDataAvailable(request, context, inputStream,
sourceOffset, count);
},
/**
* See nsIRequestObserver.idl
*/
onStartRequest(request, context) {
let channel = request.QueryInterface(Ci.nsIChannel);
let {loadInfo} = channel;
if ((loadInfo.frameOuterWindowID || loadInfo.outerWindowID) != loadInfo.topOuterWindowID &&
!gCanFrameFeeds) {
// We don't care about frame loads:
return;
}
// Check for a header that tells us there was no sniffing
// The value doesn't matter.
try {
let httpChannel = channel.QueryInterface(Ci.nsIHttpChannel);
// Make sure to check requestSucceeded before the potentially-throwing
// getResponseHeader.
if (!httpChannel.requestSucceeded) {
// Just give up, but don't forget to cancel the channel first!
request.cancel(Cr.NS_BINDING_ABORTED);
return;
}
// Note: this throws if the header is not set.
httpChannel.getResponseHeader("X-Moz-Is-Feed");
} catch (ex) {
this._sniffed = true;
}
this._request = request;
// Save and reset the forced state bit early, in case there's some kind of
// error.
let feedService =
Cc["@mozilla.org/browser/feeds/result-service;1"].
getService(Ci.nsIFeedResultService);
this._forcePreviewPage = feedService.forcePreviewPage;
feedService.forcePreviewPage = false;
// Parse feed data as it comes in
this._processor =
Cc["@mozilla.org/feed-processor;1"].
createInstance(Ci.nsIFeedProcessor);
this._processor.listener = this;
this._processor.parseAsync(null, channel.URI);
this._processor.onStartRequest(request, context);
},
/**
* See nsIRequestObserver.idl
*/
onStopRequest(request, context, status) {
if (this._processor)
this._processor.onStopRequest(request, context, status);
},
/**
* See nsISupports.idl
*/
QueryInterface: ChromeUtils.generateQI(["nsIFeedResultListener",
"nsIStreamConverter",
"nsIStreamListener",
"nsIRequestObserver"]),
};
/**
* Keeps parsed FeedResults around for use elsewhere in the UI after the stream
* converter completes.
*/
function FeedResultService() {
}
FeedResultService.prototype = {
classID: Components.ID("{2376201c-bbc6-472f-9b62-7548040a61c6}"),
/**
* A URI spec -> [nsIFeedResult] hash. We have to keep a list as the
* value in case the same URI is requested concurrently.
*/
_results: { },
/**
* See nsIFeedResultService.idl
*/
forcePreviewPage: false,
/**
* See nsIFeedResultService.idl
*/
addToClientReader(spec, title, subtitle, feedType, feedReader) {
if (!feedReader) {
feedReader = "default";
}
let handler = Services.prefs.getCharPref(getPrefActionForType(feedType), "bookmarks");
if (handler == "ask" || handler == "reader")
handler = feedReader;
switch (handler) {
case "client":
Services.cpmm.sendAsyncMessage("FeedConverter:ExecuteClientApp",
{ spec,
title,
subtitle,
feedHandler: getPrefAppForType(feedType) });
break;
case "default":
// Default system feed reader
Services.cpmm.sendAsyncMessage("FeedConverter:ExecuteClientApp",
{ spec,
title,
subtitle,
feedHandler: "default" });
break;
}
},
/**
* See nsIFeedResultService.idl
*/
addFeedResult(feedResult) {
if (feedResult.uri == null)
throw new Error("null URI!");
if (feedResult.uri == null)
throw new Error("null feedResult!");
let spec = feedResult.uri.spec;
if (!this._results[spec])
this._results[spec] = [];
this._results[spec].push(feedResult);
},
/**
* See nsIFeedResultService.idl
*/
getFeedResult(uri) {
if (uri == null)
throw new Error("null URI!");
let resultList = this._results[uri.spec];
for (let result of resultList) {
if (result.uri == uri)
return result;
}
return null;
},
/**
* See nsIFeedResultService.idl
*/
removeFeedResult(uri) {
if (uri == null)
throw new Error("null URI!");
let resultList = this._results[uri.spec];
if (!resultList)
return;
let deletions = 0;
for (let i = 0; i < resultList.length; ++i) {
if (resultList[i].uri == uri) {
delete resultList[i];
++deletions;
}
}
// send the holes to the end
resultList.sort();
// and trim the list
resultList.splice(resultList.length - deletions, deletions);
if (resultList.length == 0)
delete this._results[uri.spec];
},
createInstance(outer, iid) {
if (outer != null)
throw Cr.NS_ERROR_NO_AGGREGATION;
return this.QueryInterface(iid);
},
QueryInterface: ChromeUtils.generateQI(["nsIFeedResultService",
"nsIFactory"]),
};
var components = [FeedConverter,
FeedResultService];
this.NSGetFactory = XPCOMUtils.generateNSGetFactory(components);

Просмотреть файл

@ -1,528 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
const FEEDWRITER_CID = Components.ID("{49bb6593-3aff-4eb3-a068-2712c28bd58e}");
const FEEDWRITER_CONTRACTID = "@mozilla.org/browser/feeds/result-writer;1";
function LOG(str) {
let shouldLog = Services.prefs.getBoolPref("feeds.log", false);
if (shouldLog)
dump("*** Feeds: " + str + "\n");
}
/**
* Wrapper function for nsIIOService::newURI.
* @param aURLSpec
* The URL string from which to create an nsIURI.
* @returns an nsIURI object, or null if the creation of the URI failed.
*/
function makeURI(aURLSpec, aCharset) {
try {
return Services.io.newURI(aURLSpec, aCharset);
} catch (ex) { }
return null;
}
const XML_NS = "http://www.w3.org/XML/1998/namespace";
const HTML_NS = "http://www.w3.org/1999/xhtml";
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
const URI_BUNDLE = "chrome://browser/locale/feeds/subscribe.properties";
const TITLE_ID = "feedTitleText";
const SUBTITLE_ID = "feedSubtitleText";
/**
* Converts a number of bytes to the appropriate unit that results in a
* number that needs fewer than 4 digits
*
* @return a pair: [new value with 3 sig. figs., its unit]
*/
function convertByteUnits(aBytes) {
let units = ["bytes", "kilobyte", "megabyte", "gigabyte"];
let unitIndex = 0;
// convert to next unit if it needs 4 digits (after rounding), but only if
// we know the name of the next unit
while ((aBytes >= 999.5) && (unitIndex < units.length - 1)) {
aBytes /= 1024;
unitIndex++;
}
// Get rid of insignificant bits by truncating to 1 or 0 decimal points
// 0 -> 0; 1.2 -> 1.2; 12.3 -> 12.3; 123.4 -> 123; 234.5 -> 235
aBytes = aBytes.toFixed((aBytes > 0) && (aBytes < 100) ? 1 : 0);
return [aBytes, units[unitIndex]];
}
XPCOMUtils.defineLazyPreferenceGetter(this, "gCanFrameFeeds",
"browser.feeds.unsafelyFrameFeeds", false);
function FeedWriter() {
Services.telemetry.scalarAdd("browser.feeds.preview_loaded", 1);
}
FeedWriter.prototype = {
_getPropertyAsBag(container, property) {
return container.fields.getProperty(property).
QueryInterface(Ci.nsIPropertyBag2);
},
_getPropertyAsString(container, property) {
try {
return container.fields.getPropertyAsAString(property);
} catch (e) {
}
return "";
},
_setContentText(id, text) {
let element = this._document.getElementById(id);
let textNode = text.createDocumentFragment(element);
while (element.hasChildNodes())
element.firstChild.remove();
element.appendChild(textNode);
if (text.base) {
element.setAttributeNS(XML_NS, "base", text.base.spec);
}
},
/**
* Safely sets the href attribute on an anchor tag, providing the URI
* specified can be loaded according to rules.
* @param element
* The element to set a URI attribute on
* @param attribute
* The attribute of the element to set the URI to, e.g. href or src
* @param uri
* The URI spec to set as the href
*/
_safeSetURIAttribute(element, attribute, uri) {
const flags = Ci.nsIScriptSecurityManager.DISALLOW_INHERIT_PRINCIPAL;
try {
// TODO Is this necessary?
Services.scriptSecurityManager.checkLoadURIStrWithPrincipal(this._feedPrincipal, uri, flags);
// checkLoadURIStrWithPrincipal will throw if the link URI should not be
// loaded, either because our feedURI isn't allowed to load it or per
// the rules specified in |flags|, so we'll never "linkify" the link...
} catch (e) {
// Not allowed to load this link because secman.checkLoadURIStr threw
return;
}
element.setAttribute(attribute, uri);
},
__bundle: null,
get _bundle() {
if (!this.__bundle) {
this.__bundle = Services.strings.createBundle(URI_BUNDLE);
}
return this.__bundle;
},
_getFormattedString(key, params) {
return this._bundle.formatStringFromName(key, params, params.length);
},
_getString(key) {
return this._bundle.GetStringFromName(key);
},
/**
* Returns a date suitable for displaying in the feed preview.
* If the date cannot be parsed, the return value is "false".
* @param dateString
* A date as extracted from a feed entry. (entry.updated)
*/
_parseDate(dateString) {
// Convert the date into the user's local time zone
let dateObj = new Date(dateString);
// Make sure the date we're given is valid.
if (!dateObj.getTime())
return false;
return this._dateFormatter.format(dateObj);
},
__dateFormatter: null,
get _dateFormatter() {
if (!this.__dateFormatter) {
const dtOptions = {
timeStyle: "short",
dateStyle: "long",
};
this.__dateFormatter = new Services.intl.DateTimeFormat(undefined, dtOptions);
}
return this.__dateFormatter;
},
/**
* Writes the feed title into the preview document.
* @param container
* The feed container
*/
_setTitleText(container) {
if (container.title) {
let title = container.title.plainText();
this._setContentText(TITLE_ID, container.title);
this._document.title = title;
}
let feed = container.QueryInterface(Ci.nsIFeed);
if (feed && feed.subtitle)
this._setContentText(SUBTITLE_ID, container.subtitle);
},
/**
* Writes the title image into the preview document if one is present.
* @param container
* The feed container
*/
_setTitleImage(container) {
try {
let parts = container.image;
// Set up the title image (supplied by the feed)
let feedTitleImage = this._document.getElementById("feedTitleImage");
this._safeSetURIAttribute(feedTitleImage, "src",
parts.getPropertyAsAString("url"));
// Set up the title image link
let feedTitleLink = this._document.getElementById("feedTitleLink");
let titleText = this._getFormattedString("linkTitleTextFormat",
[parts.getPropertyAsAString("title")]);
let feedTitleText = this._document.getElementById("feedTitleText");
let titleImageWidth = parseInt(parts.getPropertyAsAString("width")) + 15;
// Fix the margin on the main title, so that the image doesn't run over
// the underline
feedTitleLink.setAttribute("title", titleText);
feedTitleText.style.marginRight = titleImageWidth + "px";
this._safeSetURIAttribute(feedTitleLink, "href",
parts.getPropertyAsAString("link"));
} catch (e) {
LOG("Failed to set Title Image (this is benign): " + e);
}
},
/**
* Writes all entries contained in the feed.
* @param container
* The container of entries in the feed
*/
_writeFeedContent(container) {
// Build the actual feed content
let feed = container.QueryInterface(Ci.nsIFeed);
if (feed.items.length == 0)
return;
let feedContent = this._document.getElementById("feedContent");
for (let i = 0; i < feed.items.length; ++i) {
let entry = feed.items.queryElementAt(i, Ci.nsIFeedEntry);
entry.QueryInterface(Ci.nsIFeedContainer);
let entryContainer = this._document.createElementNS(HTML_NS, "div");
entryContainer.className = "entry";
// If the entry has a title, make it a link
if (entry.title) {
let a = this._document.createElementNS(HTML_NS, "a");
let span = this._document.createElementNS(HTML_NS, "span");
a.appendChild(span);
if (entry.title.base)
span.setAttributeNS(XML_NS, "base", entry.title.base.spec);
span.appendChild(entry.title.createDocumentFragment(a));
// Entries are not required to have links, so entry.link can be null.
if (entry.link)
this._safeSetURIAttribute(a, "href", entry.link.spec);
let title = this._document.createElementNS(HTML_NS, "h3");
title.appendChild(a);
let lastUpdated = this._parseDate(entry.updated);
if (lastUpdated) {
let dateDiv = this._document.createElementNS(HTML_NS, "div");
dateDiv.className = "lastUpdated";
dateDiv.textContent = lastUpdated;
title.appendChild(dateDiv);
}
entryContainer.appendChild(title);
}
let body = this._document.createElementNS(HTML_NS, "div");
let summary = entry.summary || entry.content;
let docFragment = null;
if (summary) {
if (summary.base)
body.setAttributeNS(XML_NS, "base", summary.base.spec);
else
LOG("no base?");
docFragment = summary.createDocumentFragment(body);
if (docFragment)
body.appendChild(docFragment);
// If the entry doesn't have a title, append a # permalink
// See http://scripting.com/rss.xml for an example
if (!entry.title && entry.link) {
let a = this._document.createElementNS(HTML_NS, "a");
a.appendChild(this._document.createTextNode("#"));
this._safeSetURIAttribute(a, "href", entry.link.spec);
body.appendChild(this._document.createTextNode(" "));
body.appendChild(a);
}
}
body.className = "feedEntryContent";
entryContainer.appendChild(body);
if (entry.enclosures && entry.enclosures.length > 0) {
let enclosuresDiv = this._buildEnclosureDiv(entry);
entryContainer.appendChild(enclosuresDiv);
}
let clearDiv = this._document.createElementNS(HTML_NS, "div");
clearDiv.style.clear = "both";
feedContent.appendChild(entryContainer);
feedContent.appendChild(clearDiv);
}
},
/**
* Takes a url to a media item and returns the best name it can come up with.
* Frequently this is the filename portion (e.g. passing in
* http://example.com/foo.mpeg would return "foo.mpeg"), but in more complex
* cases, this will return the entire url (e.g. passing in
* http://example.com/somedirectory/ would return
* http://example.com/somedirectory/).
* @param aURL
* The URL string from which to create a display name
* @returns a string
*/
_getURLDisplayName(aURL) {
let url = makeURI(aURL);
url.QueryInterface(Ci.nsIURL);
if (url == null || url.fileName.length == 0)
return decodeURIComponent(aURL);
return decodeURIComponent(url.fileName);
},
/**
* Takes a FeedEntry with enclosures, generates the HTML code to represent
* them, and returns that.
* @param entry
* FeedEntry with enclosures
* @returns element
*/
_buildEnclosureDiv(entry) {
let enclosuresDiv = this._document.createElementNS(HTML_NS, "div");
enclosuresDiv.className = "enclosures";
enclosuresDiv.appendChild(this._document.createTextNode(this._getString("mediaLabel")));
for (let i_enc = 0; i_enc < entry.enclosures.length; ++i_enc) {
let enc = entry.enclosures.queryElementAt(i_enc, Ci.nsIWritablePropertyBag2);
if (!(enc.hasKey("url")))
continue;
let enclosureDiv = this._document.createElementNS(HTML_NS, "div");
enclosureDiv.setAttribute("class", "enclosure");
let mozicon = "moz-icon://.txt?size=16";
let type_text = null;
let size_text = null;
if (enc.hasKey("type")) {
type_text = enc.get("type");
if (enc.hasKey("typeDesc"))
type_text = enc.get("typeDesc");
if (type_text && type_text.length > 0)
mozicon = "moz-icon://goat?size=16&contentType=" + enc.get("type");
}
if (enc.hasKey("length") && /^[0-9]+$/.test(enc.get("length"))) {
let enc_size = convertByteUnits(parseInt(enc.get("length")));
size_text = this._getFormattedString("enclosureSizeText",
[enc_size[0],
this._getString(enc_size[1])]);
}
let iconimg = this._document.createElementNS(HTML_NS, "img");
iconimg.setAttribute("src", mozicon);
iconimg.setAttribute("class", "type-icon");
enclosureDiv.appendChild(iconimg);
enclosureDiv.appendChild(this._document.createTextNode( " " ));
let enc_href = this._document.createElementNS(HTML_NS, "a");
enc_href.appendChild(this._document.createTextNode(this._getURLDisplayName(enc.get("url"))));
this._safeSetURIAttribute(enc_href, "href", enc.get("url"));
enclosureDiv.appendChild(enc_href);
if (type_text && size_text)
enclosureDiv.appendChild(this._document.createTextNode( " (" + type_text + ", " + size_text + ")"));
else if (type_text)
enclosureDiv.appendChild(this._document.createTextNode( " (" + type_text + ")"));
else if (size_text)
enclosureDiv.appendChild(this._document.createTextNode( " (" + size_text + ")"));
enclosuresDiv.appendChild(enclosureDiv);
}
return enclosuresDiv;
},
/**
* Gets a valid nsIFeedContainer object from the parsed nsIFeedResult.
* Displays error information if there was one.
* @returns A valid nsIFeedContainer object containing the contents of
* the feed.
*/
_getContainer() {
let feedService =
Cc["@mozilla.org/browser/feeds/result-service;1"].
getService(Ci.nsIFeedResultService);
let result;
try {
result =
feedService.getFeedResult(this._getOriginalURI(this._window));
} catch (e) {
LOG("Subscribe Preview: feed not available?!");
}
if (result.bozo) {
LOG("Subscribe Preview: feed result is bozo?!");
}
let container;
try {
container = result.doc;
} catch (e) {
LOG("Subscribe Preview: no result.doc? Why didn't the original reload?");
return null;
}
return container;
},
/**
* Returns the original URI object of the feed and ensures that this
* component is only ever invoked from the preview document.
* @param aWindow
* The window of the document invoking the BrowserFeedWriter
*/
_getOriginalURI(aWindow) {
let docShell = aWindow.docShell;
let chan = docShell.currentDocumentChannel;
// We probably need to call Inherit() for this, but right now we can't call
// it from JS.
let attrs = docShell.getOriginAttributes();
let ssm = Services.scriptSecurityManager;
let nullPrincipal = ssm.createNullPrincipal(attrs);
// this channel is not going to be openend, use a nullPrincipal
// and the most restrctive securityFlag.
let resolvedURI = NetUtil.newChannel({
uri: "about:feeds",
loadingPrincipal: nullPrincipal,
securityFlags: Ci.nsILoadInfo.SEC_REQUIRE_SAME_ORIGIN_DATA_IS_BLOCKED,
contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER,
}).URI;
if (resolvedURI.equals(chan.URI))
return chan.originalURI;
return null;
},
_window: null,
_document: null,
_feedURI: null,
_feedPrincipal: null,
// BrowserFeedWriter WebIDL methods
init(aWindow) {
let window = aWindow;
if (window != window.top && !gCanFrameFeeds) {
return;
}
this._feedURI = this._getOriginalURI(window);
if (!this._feedURI)
return;
this._window = window;
this._document = window.document;
this._feedPrincipal = Services.scriptSecurityManager.createCodebasePrincipal(this._feedURI, {});
LOG("Subscribe Preview: feed uri = " + this._window.location.href);
},
writeContent() {
if (!this._window)
return;
try {
// Set up the feed content
let container = this._getContainer();
if (!container)
return;
this._setTitleText(container);
this._setTitleImage(container);
this._writeFeedContent(container);
} finally {
this._removeFeedFromCache();
}
},
close() {
if (!this._window) {
return;
}
this._document = null;
this._window = null;
this._removeFeedFromCache();
this.__bundle = null;
this._feedURI = null;
},
_removeFeedFromCache() {
if (this._window && this._feedURI) {
let feedService = Cc["@mozilla.org/browser/feeds/result-service;1"].
getService(Ci.nsIFeedResultService);
feedService.removeFeedResult(this._feedURI);
this._feedURI = null;
}
},
classID: FEEDWRITER_CID,
QueryInterface: ChromeUtils.generateQI([Ci.nsIObserver,
Ci.nsIDOMGlobalPropertyInitializer]),
};
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([FeedWriter]);

Просмотреть файл

@ -1,33 +0,0 @@
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var SubscribeHandler = {
/**
* The nsIFeedWriter object that produces the UI
*/
_feedWriter: null,
init: function SH_init() {
this._feedWriter = new BrowserFeedWriter();
},
writeContent: function SH_writeContent() {
this._feedWriter.writeContent();
},
uninit: function SH_uninit() {
this._feedWriter.close();
},
};
SubscribeHandler.init();
window.onload = function() {
SubscribeHandler.writeContent();
};
window.onunload = function() {
SubscribeHandler.uninit();
};

Просмотреть файл

@ -1,56 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!DOCTYPE html [
<!ENTITY % htmlDTD
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"DTD/xhtml1-strict.dtd">
%htmlDTD;
<!ENTITY % globalDTD
SYSTEM "chrome://global/locale/global.dtd">
%globalDTD;
<!ENTITY % feedDTD
SYSTEM "chrome://browser/locale/feeds/subscribe.dtd">
%feedDTD;
]>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<html id="feedHandler"
xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Security-Policy" content="default-src chrome:; img-src *; media-src *" />
<title>&feedPage.title;</title>
<link rel="stylesheet"
href="chrome://browser/skin/feeds/subscribe.css"
type="text/css"
media="all"/>
</head>
<body>
<div id="feedHeaderContainer">
<div id="feedHeader" dir="&locale.dir;">
<div id="feedIntroText">
<p id="feedSubscriptionInfo1" />
<p id="feedSubscriptionInfo2" />
</div>
</div>
<div id="feedHeaderContainerSpacer"/>
</div>
<div id="feedBody">
<div id="feedTitle">
<a id="feedTitleLink">
<img id="feedTitleImage"/>
</a>
<div id="feedTitleContainer">
<h1 id="feedTitleText"/>
<h2 id="feedSubtitleText"/>
</div>
</div>
<div id="feedContent"/>
</div>
</body>
<script type="application/javascript" src="chrome://browser/content/feeds/subscribe.js"/>
</html>

Просмотреть файл

@ -1,7 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
browser.jar:
content/browser/feeds/subscribe.xhtml (content/subscribe.xhtml)
content/browser/feeds/subscribe.js (content/subscribe.js)

Просмотреть файл

@ -4,37 +4,13 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
MOCHITEST_CHROME_MANIFESTS += ['test/chrome/chrome.ini']
MOCHITEST_MANIFESTS += ['test/mochitest.ini']
BROWSER_CHROME_MANIFESTS += ['test/browser/browser.ini']
JAR_MANIFESTS += ['jar.mn']
XPIDL_SOURCES += [
'nsIFeedResultService.idl',
]
XPIDL_MODULE = 'browser-feeds'
SOURCES += [
'nsFeedSniffer.cpp',
]
EXTRA_COMPONENTS += [
'BrowserFeeds.manifest',
'FeedConverter.js',
'FeedWriter.js',
'WebContentConverter.js',
]
FINAL_LIBRARY = 'browsercomps'
for var in ('MOZ_APP_NAME', 'MOZ_MACBUNDLE_NAME'):
DEFINES[var] = CONFIG[var]
LOCAL_INCLUDES += [
'../build',
]
with Files('**'):
BUG_COMPONENT = ('Firefox', 'RSS Discovery and Preview')

Просмотреть файл

@ -1,391 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsFeedSniffer.h"
#include "mozilla/Preferences.h"
#include "mozilla/Unused.h"
#include "nsNetCID.h"
#include "nsXPCOM.h"
#include "nsCOMPtr.h"
#include "nsStringStream.h"
#include "nsBrowserCompsCID.h"
#include "nsICategoryManager.h"
#include "nsIServiceManager.h"
#include "nsComponentManagerUtils.h"
#include "nsServiceManagerUtils.h"
#include "nsIStreamConverterService.h"
#include "nsIStreamConverter.h"
#include "nsIStreamListener.h"
#include "nsIHttpChannel.h"
#include "nsIMIMEHeaderParam.h"
#include "nsMimeTypes.h"
#include "nsIURI.h"
#include <algorithm>
#define TYPE_ATOM "application/atom+xml"
#define TYPE_RSS "application/rss+xml"
#define TYPE_MAYBE_FEED "application/vnd.mozilla.maybe.feed"
#define NS_RDF "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
#define NS_RSS "http://purl.org/rss/1.0/"
#define MAX_BYTES 512u
static bool sFramePrefCached = false;
static bool sFramingAllowed = false;
using namespace mozilla;
NS_IMPL_ISUPPORTS(nsFeedSniffer,
nsIContentSniffer,
nsIStreamListener,
nsIRequestObserver)
nsresult
nsFeedSniffer::ConvertEncodedData(nsIRequest* request,
const uint8_t* data,
uint32_t length)
{
nsresult rv = NS_OK;
mDecodedData = "";
nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(request));
if (!httpChannel)
return NS_ERROR_NO_INTERFACE;
nsAutoCString contentEncoding;
mozilla::Unused << httpChannel->GetResponseHeader(NS_LITERAL_CSTRING("Content-Encoding"),
contentEncoding);
if (!contentEncoding.IsEmpty()) {
nsCOMPtr<nsIStreamConverterService> converterService(do_GetService(NS_STREAMCONVERTERSERVICE_CONTRACTID));
if (converterService) {
ToLowerCase(contentEncoding);
nsCOMPtr<nsIStreamListener> converter;
rv = converterService->AsyncConvertData(contentEncoding.get(),
"uncompressed", this, nullptr,
getter_AddRefs(converter));
NS_ENSURE_SUCCESS(rv, rv);
converter->OnStartRequest(request, nullptr);
nsCOMPtr<nsIStringInputStream> rawStream =
do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID);
if (!rawStream)
return NS_ERROR_FAILURE;
rv = rawStream->SetData((const char*)data, length);
NS_ENSURE_SUCCESS(rv, rv);
rv = converter->OnDataAvailable(request, nullptr, rawStream, 0, length);
NS_ENSURE_SUCCESS(rv, rv);
converter->OnStopRequest(request, nullptr, NS_OK);
}
}
return rv;
}
template<int N>
static bool
StringBeginsWithLowercaseLiteral(nsAString& aString,
const char (&aSubstring)[N])
{
return StringHead(aString, N).LowerCaseEqualsLiteral(aSubstring);
}
bool
HasAttachmentDisposition(nsIHttpChannel* httpChannel)
{
if (!httpChannel)
return false;
uint32_t disp;
nsresult rv = httpChannel->GetContentDisposition(&disp);
if (NS_SUCCEEDED(rv) && disp == nsIChannel::DISPOSITION_ATTACHMENT)
return true;
return false;
}
/**
* @return the first occurrence of a character within a string buffer,
* or nullptr if not found
*/
static const char*
FindChar(char c, const char *begin, const char *end)
{
for (; begin < end; ++begin) {
if (*begin == c)
return begin;
}
return nullptr;
}
/**
*
* Determine if a substring is the "documentElement" in the document.
*
* All of our sniffed substrings: <rss, <feed, <rdf:RDF must be the "document"
* element within the XML DOM, i.e. the root container element. Otherwise,
* it's possible that someone embedded one of these tags inside a document of
* another type, e.g. a HTML document, and we don't want to show the preview
* page if the document isn't actually a feed.
*
* @param start
* The beginning of the data being sniffed
* @param end
* The end of the data being sniffed, right before the substring that
* was found.
* @returns true if the found substring is the documentElement, false
* otherwise.
*/
static bool
IsDocumentElement(const char *start, const char* end)
{
// For every tag in the buffer, check to see if it's a PI, Doctype or
// comment, our desired substring or something invalid.
while ( (start = FindChar('<', start, end)) ) {
++start;
if (start >= end)
return false;
// Check to see if the character following the '<' is either '?' or '!'
// (processing instruction or doctype or comment)... these are valid nodes
// to have in the prologue.
if (*start != '?' && *start != '!')
return false;
// Now advance the iterator until the '>' (We do this because we don't want
// to sniff indicator substrings that are embedded within other nodes, e.g.
// comments: <!-- <rdf:RDF .. > -->
start = FindChar('>', start, end);
if (!start)
return false;
++start;
}
return true;
}
/**
* Determines whether or not a string exists as the root element in an XML data
* string buffer.
* @param dataString
* The data being sniffed
* @param substring
* The substring being tested for existence and root-ness.
* @returns true if the substring exists and is the documentElement, false
* otherwise.
*/
static bool
ContainsTopLevelSubstring(nsACString& dataString, const char *substring)
{
nsACString::const_iterator start, end;
dataString.BeginReading(start);
dataString.EndReading(end);
if (!FindInReadable(nsCString(substring), start, end)){
return false;
}
auto offset = start.get() - dataString.Data();
const char *begin = dataString.BeginReading();
// Only do the validation when we find the substring.
return IsDocumentElement(begin, begin + offset);
}
NS_IMETHODIMP
nsFeedSniffer::GetMIMETypeFromContent(nsIRequest* request,
const uint8_t* data,
uint32_t length,
nsACString& sniffedType)
{
nsCOMPtr<nsIHttpChannel> channel(do_QueryInterface(request));
if (!channel)
return NS_ERROR_NO_INTERFACE;
// Check that this is a GET request, since you can't subscribe to a POST...
nsAutoCString method;
mozilla::Unused << channel->GetRequestMethod(method);
if (!method.EqualsLiteral("GET")) {
sniffedType.Truncate();
return NS_OK;
}
if (!sFramePrefCached) {
sFramePrefCached = true;
Preferences::AddBoolVarCache(&sFramingAllowed,
"browser.feeds.unsafelyFrameFeeds");
}
if (!sFramingAllowed) {
// Check that we're the toplevel frame:
nsCOMPtr<nsILoadInfo> loadInfo = channel->GetLoadInfo();
if (!loadInfo) {
sniffedType.Truncate();
return NS_OK;
}
auto frameID = loadInfo->GetFrameOuterWindowID();
if (!frameID) {
frameID = loadInfo->GetOuterWindowID();
}
if (loadInfo->GetTopOuterWindowID() != frameID) {
sniffedType.Truncate();
return NS_OK;
}
}
// We need to find out if this is a load of a view-source document. In this
// case we do not want to override the content type, since the source display
// does not need to be converted from feed format to XUL. More importantly,
// we don't want to change the content type from something
// nsContentDLF::CreateInstance knows about (e.g. application/xml, text/html
// etc) to something that only the application fe knows about (maybe.feed)
// thus deactivating syntax highlighting.
nsCOMPtr<nsIURI> originalURI;
channel->GetOriginalURI(getter_AddRefs(originalURI));
nsAutoCString scheme;
originalURI->GetScheme(scheme);
if (scheme.EqualsLiteral("view-source")) {
sniffedType.Truncate();
return NS_OK;
}
// Check the Content-Type to see if it is set correctly. If it is set to
// something specific that we think is a reliable indication of a feed, don't
// bother sniffing since we assume the site maintainer knows what they're
// doing.
nsAutoCString contentType;
channel->GetContentType(contentType);
bool noSniff = contentType.EqualsLiteral(TYPE_RSS) ||
contentType.EqualsLiteral(TYPE_ATOM);
if (noSniff) {
// check for an attachment after we have a likely feed.
if(HasAttachmentDisposition(channel)) {
sniffedType.Truncate();
return NS_OK;
}
// set the feed header as a response header, since we have good metadata
// telling us that the feed is supposed to be RSS or Atom
mozilla::DebugOnly<nsresult> rv =
channel->SetResponseHeader(NS_LITERAL_CSTRING("X-Moz-Is-Feed"),
NS_LITERAL_CSTRING("1"), false);
MOZ_ASSERT(NS_SUCCEEDED(rv));
sniffedType.AssignLiteral(TYPE_MAYBE_FEED);
return NS_OK;
}
// Don't sniff arbitrary types. Limit sniffing to situations that
// we think can reasonably arise.
if (!contentType.EqualsLiteral(TEXT_HTML) &&
!contentType.EqualsLiteral(APPLICATION_OCTET_STREAM) &&
// Same criterion as XMLHttpRequest. Should we be checking for "+xml"
// and check for text/xml and application/xml by hand instead?
contentType.Find("xml") == -1) {
sniffedType.Truncate();
return NS_OK;
}
// Now we need to potentially decompress data served with
// Content-Encoding: gzip
nsresult rv = ConvertEncodedData(request, data, length);
if (NS_FAILED(rv))
return rv;
// We cap the number of bytes to scan at MAX_BYTES to prevent picking up
// false positives by accidentally reading document content, e.g. a "how to
// make a feed" page.
const char* testData;
if (mDecodedData.IsEmpty()) {
testData = (const char*)data;
length = std::min(length, MAX_BYTES);
} else {
testData = mDecodedData.get();
length = std::min(mDecodedData.Length(), MAX_BYTES);
}
// The strategy here is based on that described in:
// http://blogs.msdn.com/rssteam/articles/PublishersGuide.aspx
// for interoperarbility purposes.
// Thus begins the actual sniffing.
nsDependentCSubstring dataString((const char*)testData, length);
bool isFeed = false;
// RSS 0.91/0.92/2.0
isFeed = ContainsTopLevelSubstring(dataString, "<rss");
// Atom 1.0
if (!isFeed)
isFeed = ContainsTopLevelSubstring(dataString, "<feed");
// RSS 1.0
if (!isFeed) {
bool foundNS_RDF = FindInReadable(NS_LITERAL_CSTRING(NS_RDF), dataString);
bool foundNS_RSS = FindInReadable(NS_LITERAL_CSTRING(NS_RSS), dataString);
isFeed = ContainsTopLevelSubstring(dataString, "<rdf:RDF") &&
foundNS_RDF && foundNS_RSS;
}
// If we sniffed a feed, coerce our internal type
if (isFeed && !HasAttachmentDisposition(channel))
sniffedType.AssignLiteral(TYPE_MAYBE_FEED);
else
sniffedType.Truncate();
return NS_OK;
}
NS_IMETHODIMP
nsFeedSniffer::OnStartRequest(nsIRequest* request, nsISupports* context)
{
return NS_OK;
}
nsresult
nsFeedSniffer::AppendSegmentToString(nsIInputStream* inputStream,
void* closure,
const char* rawSegment,
uint32_t toOffset,
uint32_t count,
uint32_t* writeCount)
{
nsCString* decodedData = static_cast<nsCString*>(closure);
decodedData->Append(rawSegment, count);
*writeCount = count;
return NS_OK;
}
NS_IMETHODIMP
nsFeedSniffer::OnDataAvailable(nsIRequest* request, nsISupports* context,
nsIInputStream* stream, uint64_t offset,
uint32_t count)
{
uint32_t read;
return stream->ReadSegments(AppendSegmentToString, &mDecodedData, count,
&read);
}
NS_IMETHODIMP
nsFeedSniffer::OnStopRequest(nsIRequest* request, nsISupports* context,
nsresult status)
{
return NS_OK;
}

Просмотреть файл

@ -1,37 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsIContentSniffer.h"
#include "nsIStreamListener.h"
#include "nsString.h"
#include "mozilla/Attributes.h"
class nsFeedSniffer final : public nsIContentSniffer,
nsIStreamListener
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSICONTENTSNIFFER
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSISTREAMLISTENER
static nsresult AppendSegmentToString(nsIInputStream* inputStream,
void* closure,
const char* rawSegment,
uint32_t toOffset,
uint32_t count,
uint32_t* writeCount);
protected:
~nsFeedSniffer() {}
nsresult ConvertEncodedData(nsIRequest* request, const uint8_t* data,
uint32_t length);
private:
nsCString mDecodedData;
};

Просмотреть файл

@ -1,70 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsISupports.idl"
interface nsIURI;
interface nsIRequest;
interface nsIFeedResult;
/**
* nsIFeedResultService provides a globally-accessible object for retrieving
* the results of feed processing.
*/
[scriptable, uuid(95309fd2-7b3a-47fb-97f3-5c460d9473cd)]
interface nsIFeedResultService : nsISupports
{
/**
* When set to true, forces the preview page to be displayed, regardless
* of the user's preferences.
*/
attribute boolean forcePreviewPage;
/**
* Adds a URI to the user's specified external feed handler, or live
* bookmarks.
* @param uri
* The uri of the feed to add.
* @param title
* The title of the feed to add.
* @param subtitle
* The subtitle of the feed to add.
* @param feedType
* The nsIFeed type of the feed. See nsIFeed.idl
* @param feedReader
* The type of feed reader we're using (client, bookmarks, default)
* If this parameter is null, the type is set to default
*/
void addToClientReader(in AUTF8String uri,
in AString title,
in AString subtitle,
in unsigned long feedType,
[optional] in AString feedReader);
/**
* Registers a Feed Result object with a globally accessible service
* so that it can be accessed by a singleton method outside the usual
* flow of control in document loading.
*
* @param feedResult
* An object implementing nsIFeedResult representing the feed.
*/
void addFeedResult(in nsIFeedResult feedResult);
/**
* Gets a Feed Handler object registered using addFeedResult.
*
* @param uri
* The URI of the feed a handler is being requested for
*/
nsIFeedResult getFeedResult(in nsIURI uri);
/**
* Unregisters a Feed Handler object registered using addFeedResult.
* @param uri
* The feed URI the handler was registered under. This must be
* the same *instance* the feed was registered under.
*/
void removeFeedResult(in nsIURI uri);
};

Просмотреть файл

@ -1,5 +0,0 @@
<rss version="2.0">
<channel>
<title>t</title>
</channel>
</rss>

Просмотреть файл

@ -1 +0,0 @@
Content-Type: text/xml

Просмотреть файл

@ -1,18 +0,0 @@
<?xml version="1.0"?>
<rdf:RDF
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://my.netscape.com/rdf/simple/0.9/">
<channel>
<title>Tinderbox - Firefox</title>
<description>Build bustages for Firefox</description>
<link>http://tinderbox.mozilla.org/showbuilds.cgi?tree=Firefox</link>
</channel>
<image>
<title>Bad</title>
<url>http://tinderbox.mozilla.org/channelflames.gif</url>
<link>http://tinderbox.mozilla.org/showbuilds.cgi?tree=Firefox</link>
</image>
<item><title>The tree is currently closed</title><link>http://tinderbox.mozilla.org/showbuilds.cgi?tree=Firefox</link></item>
<item><title>MacOSX Darwin 8.8.4 qm-xserve01 dep unit test is in flames</title><link>http://tinderbox.mozilla.org/showbuilds.cgi?tree=Firefox</link></item>
</rdf:RDF>

Просмотреть файл

@ -1,63 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Example Feed</title>
<link href="http://example.org/"/>
<updated>2003-12-13T18:30:02Z</updated>
<author>
<name>John Doe</name>
</author>
<id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
<entry>
<title>Good item</title>
<link href="http://example.org/first"/>
<id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
<updated>2003-12-13T18:30:02Z</updated>
<summary>Some text.</summary>
</entry>
<entry>
<title>data: link</title>
<link href="data:text/plain,Hi"/>
<id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6b</id>
<updated>2003-12-13T18:30:03Z</updated>
<summary>Some text.</summary>
</entry>
<entry>
<title>javascript: link</title>
<link href="javascript:alert('Hi')"/>
<id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6c</id>
<updated>2003-12-13T18:30:04Z</updated>
<summary>Some text.</summary>
</entry>
<entry>
<title>file: link</title>
<link href="file:///var/"/>
<id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6d</id>
<updated>2003-12-13T18:30:05Z</updated>
<summary>Some text.</summary>
</entry>
<entry>
<title>chrome: link</title>
<link href="chrome://browser/content/browser.js"/>
<id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6e</id>
<updated>2003-12-13T18:30:06Z</updated>
<summary>Some text.</summary>
</entry>
</feed>

Просмотреть файл

@ -1,44 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:base="http://www.example.com/">
<title type="xhtml" xml:base="/foo/bar/">
<div xmlns="http://www.w3.org/1999/xhtml">Example of a <em>special</em> feed (<img height="20px" src="baz.png" alt="base test sprite"/>)</div>
</title>
<subtitle type="html" xml:base="/foo/bar/">
<![CDATA[
With a <em>special</em> subtitle (<img height="20px" src="baz.png" alt="base test sprite"/>)
]]>
</subtitle>
<link href="http://example.org/"/>
<updated>2010-09-02T18:30:02Z</updated>
<author>
<name>John Doe</name>
</author>
<id>urn:uuid:22906062-ecbd-46e2-b6a7-3039506a398f</id>
<entry>
<title type="xhtml" xml:base="/foo/bar/">
<div xmlns="http://www.w3.org/1999/xhtml">Some <abbr title="Extensible Hyper-text Mark-up Language">XHTML</abbr> examples (<img height="20px" src="baz.png" alt="base test sprite"/>)</div>
</title>
<id>urn:uuid:b48083a7-71a7-4c9c-8515-b7c0d22955e7</id>
<updated>2010-09-02T18:30:02Z</updated>
<summary>Some text.</summary>
</entry>
<entry>
<title type="html" xml:base="/foo/bar/">
<![CDATA[
Some <abbr title="Hyper-text Mark-up Language">HTML</abbr> examples (<img height="20px" src="baz.png" alt="base test sprite"/>)
]]>
</title>
<id>urn:uuid:1424967a-280a-414d-b0ab-8b11c4ac1bb7</id>
<updated>2010-09-02T18:30:02Z</updated>
<summary>Some text.</summary>
</entry>
</feed>

Просмотреть файл

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
<channel>
<title>Channel title</title>
<description>Channel description</description>
<link>Channel link</link>
<item>
<title>Episode 1</title>
<enclosure url="http://www.example.com/podcasts/Episode%201" length="0" type="audio/x-m4a" />
</item>
<item>
<title>Episode 2</title>
<enclosure url="http://www.example.com/podcasts/Episode%20%232" length="0" type="audio/x-m4a" />
</item>
<item>
<title>Episode 3</title>
<enclosure url="http://www.example.com/podcasts/Episode%20%233/" length="0" type="audio/x-m4a" />
</item>
<item>
<title>Episode 4</title>
<enclosure url="http://www.example.com/podcasts/Is%20This%20Episode%20%234%3F" length="0" type="audio/x-m4a" />
</item>
</channel>
</rss>

Просмотреть файл

@ -1,7 +0,0 @@
"use strict";
module.exports = {
"extends": [
"plugin:mozilla/chrome-test"
]
};

Просмотреть файл

@ -1,12 +0,0 @@
[DEFAULT]
prefs =
browser.feeds.unsafelyFrameFeeds=true
support-files = sample_feed.atom
!/browser/components/feeds/test/bug408328-data.xml
!/browser/components/feeds/test/valid-feed.xml
!/browser/components/feeds/test/valid-unsniffable-feed.xml
[test_bug368464.html]
[test_bug408328.html]
[test_maxSniffing.html]

Просмотреть файл

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Example Feed</title>
<link href="http://example.org/"/>
<updated>2003-12-13T18:30:02Z</updated>
<author>
<name>John Doe</name>
</author>
<id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
<entry>
<title>Atom-Powered Robots Run Amok</title>
<link href="http://example.org/2003/12/13/atom03"/>
<id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
<updated>2003-12-13T18:30:02Z</updated>
<summary>Some text.</summary>
</entry>
</feed>

Просмотреть файл

@ -1,32 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=368464
-->
<head>
<title>Test that RSS 0.90 isn't sniffed</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=368464">Mozilla Bug 368464</a>
<p id="display"><iframe id="testFrame" src="http://mochi.test:8888/tests/browser/components/feeds/test/bug368464-data.xml"></iframe></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 368464 **/
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
ok($("testFrame").contentDocument.documentElement.id != "feedHandler",
"RSS 0.90 shouldn't be sniffed as a feed");
});
addLoadEvent(SimpleTest.finish);
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -1,37 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=408328
-->
<head>
<title>Test feed preview safe-linkification</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=408328">Mozilla Bug 408328</a>
<p id="display"><iframe id="testFrame" src="http://mochi.test:8888/tests/browser/components/feeds/test/bug408328-data.xml"></iframe></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 408328 **/
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
var links = $("testFrame").contentDocument.getElementById("feedContent").getElementsByTagName("a");
is(links.length, 5, "wrong number of linked items in feed preview");
for (var i = 0; i < links.length; i++) {
if (links[i].href)
is(links[i].href, "http://example.org/first", "bad linkified item");
}
});
addLoadEvent(SimpleTest.finish);
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -1,37 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=739040
-->
<head>
<title>Test that we only sniff 512 bytes</title>
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=739040">Mozilla Bug 739040</a>
<p id="display">
<iframe id="validTestFrame" src="http://mochi.test:8888/tests/browser/components/feeds/test/valid-feed.xml"></iframe>
<iframe id="unsniffableTestFrame" src="http://mochi.test:8888/tests/browser/components/feeds/test/valid-unsniffable-feed.xml"></iframe>
</p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 739040 **/
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
is($("validTestFrame").contentDocument.documentElement.id, "feedHandler",
"valid feed should be sniffed");
isnot($("unsniffableTestFrame").contentDocument.documentElement.id, "feedHandler",
"unsniffable feed should not be sniffed");
});
addLoadEvent(SimpleTest.finish);
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -1,20 +1,2 @@
[DEFAULT]
prefs =
browser.feeds.unsafelyFrameFeeds=true
support-files =
bug368464-data.xml
bug408328-data.xml
bug436801-data.xml
bug494328-data.xml
valid-feed.xml
valid-unsniffable-feed.xml
[test_bug364677.html]
support-files =
bug364677-data.xml
bug364677-data.xml^headers^
[test_bug436801.html]
[test_bug494328.html]
[test_registerHandler.html]
[test_registerHandler_disabled.html]

Просмотреть файл

@ -1,32 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=364677
-->
<head>
<title>Test for Bug 364677</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=364677">Mozilla Bug 364677</a>
<p id="display"><iframe id="testFrame" src="bug364677-data.xml"></iframe></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 364677 **/
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
is(SpecialPowers.wrap($("testFrame")).contentDocument.documentElement.id, "feedHandler",
"Feed served as text/xml without a channel/link should have been sniffed");
});
addLoadEvent(SimpleTest.finish);
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -1,117 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=436801
-->
<head>
<title>Test feed preview subscribe UI</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=436801">Mozilla Bug 436801</a>
<p id="display"><iframe id="testFrame" src="bug436801-data.xml"></iframe></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
var doc = SpecialPowers.wrap($("testFrame")).contentDocument;
checkNode(doc.getElementById("feedTitleText"), [
"ELEMENT", "h1", [
["TEXT", "Example of a "],
["ELEMENT", "em", [
["TEXT", "special"],
]],
["TEXT", " feed ("],
["ELEMENT", "img", { "src": "baz.png" }],
["TEXT", ")"],
],
]);
checkNode(doc.getElementById("feedSubtitleText"), [
"ELEMENT", "h2", [
["TEXT", "With a "],
["ELEMENT", "em", [
["TEXT", "special"],
]],
["TEXT", " subtitle ("],
["ELEMENT", "img", { "src": "baz.png" }],
["TEXT", ")"],
],
]);
checkNode(doc.querySelector(".entry").firstChild.firstChild.firstChild, [
"ELEMENT", "span", [
["TEXT", "Some "],
["ELEMENT", "abbr", { title: "Extensible Hyper-text Mark-up Language" }, [
["TEXT", "XHTML"],
]],
["TEXT", " examples ("],
["ELEMENT", "img", { "src": "baz.png" }],
["TEXT", ")"],
],
]);
checkNode(doc.querySelectorAll(".entry")[1].firstChild.firstChild.firstChild, [
"ELEMENT", "span", [
["TEXT", "Some "],
["ELEMENT", "abbr", { title: "Hyper-text Mark-up Language" }, [
["TEXT", "HTML"],
]],
["TEXT", " examples ("],
["ELEMENT", "img", { "src": "baz.png" }],
["TEXT", ")"],
],
]);
});
addLoadEvent(SimpleTest.finish);
function checkNode(node, schema) {
var typeName = schema.shift() + "_NODE";
var type = Node[typeName];
is(node.nodeType, type, "Node should be expected type " + typeName);
if (type == Node.TEXT_NODE) {
var text = schema.shift();
is(node.data, text, "Text should match");
return;
}
// type == Node.ELEMENT_NODE
var tag = schema.shift();
is(node.localName, tag, "Element should have expected tag");
while (schema.length) {
let val = schema.shift();
if (Array.isArray(val))
var childSchema = val;
else
var attrSchema = val;
}
if (attrSchema) {
var nsTable = {
xml: "http://www.w3.org/XML/1998/namespace",
};
for (var name in attrSchema) {
var [ns, nsName] = name.split(":");
let val = nsName ? node.getAttributeNS(nsTable[ns], nsName) :
node.getAttribute(name);
is(val, attrSchema[name], "Attribute " + name + " should match");
}
}
if (childSchema) {
var numChildren = node.childNodes.length;
is(childSchema.length, numChildren,
"Element should have expected number of children");
for (var i = 0; i < numChildren; i++)
checkNode(node.childNodes[i], childSchema[i]);
}
}
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -1,36 +0,0 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=494328
-->
<head>
<title>Test for bug 494328</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=494328">Mozilla Bug 494328</a>
<p id="display"><iframe id="testFrame" src="bug494328-data.xml"></iframe></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 494328 **/
SimpleTest.waitForExplicitFinish();
addLoadEvent(function() {
var links = SpecialPowers.wrap($("testFrame")).contentDocument.getElementById("feedContent").querySelectorAll("div.enclosure > a");
is(links[0].textContent, "Episode 1", "filename decoded incorrectly");
is(links[1].textContent, "Episode #2", "filename decoded incorrectly");
is(links[2].textContent, "http://www.example.com/podcasts/Episode #3/", "filename decoded incorrectly");
is(links[3].textContent, "Is This Episode #4?", "filename decoded incorrectly");
});
addLoadEvent(SimpleTest.finish);
</script>
</pre>
</body>
</html>

Просмотреть файл

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Example Feed</title>
<link href="http://example.org/"/>
<updated>2010-08-22T18:30:02Z</updated>
<author>
<name>John Doe</name>
</author>
<id>urn:uuid:e2df8375-99be-4848-b05e-b9d407555267</id>
<entry>
<title>Item</title>
<link href="http://example.org/first"/>
<id>urn:uuid:9e0f4bed-33d3-4a9d-97ab-ecaa31b3f14a</id>
<updated>2010-08-22T18:30:02Z</updated>
<summary>Some text.</summary>
</entry>
</feed>

Просмотреть файл

@ -1,32 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- 512 bytes!
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-->
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Example Feed</title>
<link href="http://example.org/"/>
<updated>2010-08-22T18:30:02Z</updated>
<author>
<name>John Doe</name>
</author>
<id>urn:uuid:e2df8375-99be-4848-b05e-b9d407555267</id>
<entry>
<title>Item</title>
<link href="http://example.org/first"/>
<id>urn:uuid:9e0f4bed-33d3-4a9d-97ab-ecaa31b3f14a</id>
<updated>2010-08-22T18:30:02Z</updated>
<summary>Some text.</summary>
</entry>
</feed>

Просмотреть файл

@ -500,7 +500,6 @@ const listeners = {
"AsyncPrefs:ResetPref": ["AsyncPrefs"],
// PLEASE KEEP THIS LIST IN SYNC WITH THE LISTENERS ADDED IN AsyncPrefs.init
"FeedConverter:addLiveBookmark": ["Feeds"],
"webrtc:UpdateGlobalIndicators": ["webrtcUI"],
"webrtc:UpdatingIndicators": ["webrtcUI"],
},

Просмотреть файл

@ -17,9 +17,7 @@ var gAppManagerDialog = {
window);
const appDescElem = document.getElementById("appDescription");
if (this.handlerInfo.type == TYPE_MAYBE_FEED) {
document.l10n.setAttributes(appDescElem, "app-manager-handle-webfeeds");
} else if (this.handlerInfo.wrappedHandlerInfo instanceof Ci.nsIMIMEInfo) {
if (this.handlerInfo.wrappedHandlerInfo instanceof Ci.nsIMIMEInfo) {
document.l10n.setAttributes(appDescElem, "app-manager-handle-file", {
type: this.handlerInfo.typeDescription,
});

Просмотреть файл

@ -25,9 +25,6 @@ XPCOMUtils.defineLazyServiceGetters(this, {
});
// Constants & Enumeration Values
const TYPE_MAYBE_FEED = "application/vnd.mozilla.maybe.feed";
const TYPE_MAYBE_VIDEO_FEED = "application/vnd.mozilla.maybe.video.feed";
const TYPE_MAYBE_AUDIO_FEED = "application/vnd.mozilla.maybe.audio.feed";
const TYPE_PDF = "application/pdf";
const PREF_PDFJS_DISABLED = "pdfjs.disabled";
@ -46,38 +43,6 @@ const PREF_HIDE_PLUGINS_WITHOUT_EXTENSIONS =
// Strings to identify ExtensionSettingsStore overrides
const CONTAINERS_KEY = "privacy.containers";
/*
* Preferences where we store handling information about the feed type.
*
* browser.feeds.handler
* - "bookmarks", "reader" (clarified further using the .default preference),
* or "ask" -- indicates the default handler being used to process feeds;
* "bookmarks" is obsolete; to specify that the handler is bookmarks,
* set browser.feeds.handler.default to "bookmarks";
*
* browser.feeds.handler.default
* - "bookmarks" or "client" -- indicates the chosen feed reader used
* to display feeds, either transiently (i.e., when the "use as default"
* checkbox is unchecked, corresponds to when browser.feeds.handler=="ask")
* or more permanently (i.e., the item displayed in the dropdown in Feeds
* preferences)
*
* browser.feeds.handlers.application
* - nsIFile, stores the current client-side feed reading app if one has
* been chosen
*/
const PREF_FEED_SELECTED_APP = "browser.feeds.handlers.application";
const PREF_FEED_SELECTED_ACTION = "browser.feeds.handler";
const PREF_FEED_SELECTED_READER = "browser.feeds.handler.default";
const PREF_VIDEO_FEED_SELECTED_APP = "browser.videoFeeds.handlers.application";
const PREF_VIDEO_FEED_SELECTED_ACTION = "browser.videoFeeds.handler";
const PREF_VIDEO_FEED_SELECTED_READER = "browser.videoFeeds.handler.default";
const PREF_AUDIO_FEED_SELECTED_APP = "browser.audioFeeds.handlers.application";
const PREF_AUDIO_FEED_SELECTED_ACTION = "browser.audioFeeds.handler";
const PREF_AUDIO_FEED_SELECTED_READER = "browser.audioFeeds.handler.default";
// The nsHandlerInfoAction enumeration values in nsIHandlerInfo identify
// the actions the application can take with content of various types.
// But since nsIHandlerInfo doesn't support plugins, there's no value
@ -88,7 +53,7 @@ const ICON_URL_APP = AppConstants.platform == "linux" ?
"moz-icon://dummy.exe?size=16" :
"chrome://browser/skin/preferences/application.png";
// For CSS. Can be one of "ask", "save", "plugin" or "feed". If absent, the icon URL
// For CSS. Can be one of "ask", "save" or "plugin". If absent, the icon URL
// was set by us to a custom handler icon and CSS should not try to override it.
const APP_ICON_ATTR_NAME = "appHandlerIcon";
@ -179,18 +144,6 @@ Preferences.addAll([
{ id: "layers.acceleration.disabled", type: "bool", inverted: true },
// Files and Applications
{ id: "browser.feeds.handler", type: "string" },
{ id: "browser.feeds.handler.default", type: "string" },
{ id: "browser.feeds.handlers.application", type: "file" },
{ id: "browser.videoFeeds.handler", type: "string" },
{ id: "browser.videoFeeds.handler.default", type: "string" },
{ id: "browser.videoFeeds.handlers.application", type: "file" },
{ id: "browser.audioFeeds.handler", type: "string" },
{ id: "browser.audioFeeds.handler.default", type: "string" },
{ id: "browser.audioFeeds.handlers.application", type: "file" },
{ id: "pref.downloads.disable_button.edit_actions", type: "bool" },
// DRM content
@ -549,17 +502,6 @@ var gMainPane = {
// the view when they change.
Services.prefs.addObserver(PREF_SHOW_PLUGINS_IN_LIST, this);
Services.prefs.addObserver(PREF_HIDE_PLUGINS_WITHOUT_EXTENSIONS, this);
Services.prefs.addObserver(PREF_FEED_SELECTED_APP, this);
Services.prefs.addObserver(PREF_FEED_SELECTED_ACTION, this);
Services.prefs.addObserver(PREF_FEED_SELECTED_READER, this);
Services.prefs.addObserver(PREF_VIDEO_FEED_SELECTED_APP, this);
Services.prefs.addObserver(PREF_VIDEO_FEED_SELECTED_ACTION, this);
Services.prefs.addObserver(PREF_VIDEO_FEED_SELECTED_READER, this);
Services.prefs.addObserver(PREF_AUDIO_FEED_SELECTED_APP, this);
Services.prefs.addObserver(PREF_AUDIO_FEED_SELECTED_ACTION, this);
Services.prefs.addObserver(PREF_AUDIO_FEED_SELECTED_READER, this);
setEventListener("filter", "command", gMainPane.filter);
setEventListener("typeColumn", "click", gMainPane.sort);
@ -1333,17 +1275,6 @@ var gMainPane = {
window.removeEventListener("unload", this);
Services.prefs.removeObserver(PREF_SHOW_PLUGINS_IN_LIST, this);
Services.prefs.removeObserver(PREF_HIDE_PLUGINS_WITHOUT_EXTENSIONS, this);
Services.prefs.removeObserver(PREF_FEED_SELECTED_APP, this);
Services.prefs.removeObserver(PREF_FEED_SELECTED_ACTION, this);
Services.prefs.removeObserver(PREF_FEED_SELECTED_READER, this);
Services.prefs.removeObserver(PREF_VIDEO_FEED_SELECTED_APP, this);
Services.prefs.removeObserver(PREF_VIDEO_FEED_SELECTED_ACTION, this);
Services.prefs.removeObserver(PREF_VIDEO_FEED_SELECTED_READER, this);
Services.prefs.removeObserver(PREF_AUDIO_FEED_SELECTED_APP, this);
Services.prefs.removeObserver(PREF_AUDIO_FEED_SELECTED_ACTION, this);
Services.prefs.removeObserver(PREF_AUDIO_FEED_SELECTED_READER, this);
Services.prefs.removeObserver(PREF_CONTAINERS_EXTENSION, this);
},
@ -1392,23 +1323,11 @@ var gMainPane = {
// Composed Model Construction
_loadData() {
this._loadFeedHandler();
this._loadInternalHandlers();
this._loadPluginHandlers();
this._loadApplicationHandlers();
},
_loadFeedHandler() {
this._handledTypes[TYPE_MAYBE_FEED] = feedHandlerInfo;
feedHandlerInfo.handledOnlyByPlugin = false;
this._handledTypes[TYPE_MAYBE_VIDEO_FEED] = videoFeedHandlerInfo;
videoFeedHandlerInfo.handledOnlyByPlugin = false;
this._handledTypes[TYPE_MAYBE_AUDIO_FEED] = audioFeedHandlerInfo;
audioFeedHandlerInfo.handledOnlyByPlugin = false;
},
/**
* Load higher level internal handlers so they can be turned on/off in the
* applications menu.
@ -1675,12 +1594,7 @@ var gMainPane = {
{
var askMenuItem = document.createXULElement("menuitem");
askMenuItem.setAttribute("action", Ci.nsIHandlerInfo.alwaysAsk);
let label;
if (isFeedType(handlerInfo.type))
label = gMainPane._prefsBundle.getFormattedString("previewInApp",
[this._brandShortName]);
else
label = gMainPane._prefsBundle.getString("alwaysAsk");
let label = gMainPane._prefsBundle.getString("alwaysAsk");
askMenuItem.setAttribute("label", label);
askMenuItem.setAttribute("tooltiptext", label);
askMenuItem.setAttribute(APP_ICON_ATTR_NAME, "ask");
@ -1689,10 +1603,8 @@ var gMainPane = {
// Create a menu item for saving to disk.
// Note: this option isn't available to protocol types, since we don't know
// what it means to save a URL having a certain scheme to disk, nor is it
// available to feeds, since the feed code doesn't implement the capability.
if ((handlerInfo.wrappedHandlerInfo instanceof Ci.nsIMIMEInfo) &&
!isFeedType(handlerInfo.type)) {
// what it means to save a URL having a certain scheme to disk.
if ((handlerInfo.wrappedHandlerInfo instanceof Ci.nsIMIMEInfo)) {
var saveMenuItem = document.createXULElement("menuitem");
saveMenuItem.setAttribute("action", Ci.nsIHandlerInfo.saveToDisk);
let label = gMainPane._prefsBundle.getString("saveFile");
@ -1702,18 +1614,6 @@ var gMainPane = {
menuPopup.appendChild(saveMenuItem);
}
// If this is the feed type, add a Live Bookmarks item.
if (isFeedType(handlerInfo.type)) {
internalMenuItem = document.createXULElement("menuitem");
internalMenuItem.setAttribute("action", Ci.nsIHandlerInfo.handleInternally);
let label = gMainPane._prefsBundle.getFormattedString("addLiveBookmarksInApp",
[this._brandShortName]);
internalMenuItem.setAttribute("label", label);
internalMenuItem.setAttribute("tooltiptext", label);
internalMenuItem.setAttribute(APP_ICON_ATTR_NAME, "feed");
menuPopup.appendChild(internalMenuItem);
}
// Add a separator to distinguish these items from the helper app items
// that follow them.
let menuseparator = document.createXULElement("menuseparator");
@ -1950,10 +1850,11 @@ var gMainPane = {
// Whether or not we are currently storing the action selected by the user.
// We use this to suppress notification-triggered updates to the list when
// we make changes that may spawn such updates, specifically when we change
// the action for the feed type, which results in feed preference updates,
// which spawn "pref changed" notifications that would otherwise cause us
// to rebuild the view unnecessarily.
// we make changes that may spawn such updates.
// XXXgijs: this was definitely necessary when we changed feed preferences
// from within _storeAction and its calltree. Now, it may still be
// necessary, either to avoid calling _rebuildView or to avoid the plugin-
// related prefs change code. bug 1499350 has more details.
_storingAction: false,
onSelectAction(aActionItem) {
@ -2058,14 +1959,7 @@ var gMainPane = {
var params = {};
var handlerInfo = this.selectedHandlerListItem.handlerInfoWrapper;
if (isFeedType(handlerInfo.type)) {
// MIME info will be null, create a temp object.
params.mimeInfo = gMIMEService.getFromTypeAndExtension(handlerInfo.type,
handlerInfo.primaryExtension);
} else {
params.mimeInfo = handlerInfo.wrappedHandlerInfo;
}
params.mimeInfo = handlerInfo.wrappedHandlerInfo;
params.title = gMainPane._prefsBundle.getString("fpTitleChooseApp");
params.description = handlerInfo.description;
params.filename = null;
@ -2454,10 +2348,6 @@ function getLocalHandlerApp(aFile) {
return localHandlerApp;
}
function isFeedType(t) {
return t == TYPE_MAYBE_FEED || t == TYPE_MAYBE_VIDEO_FEED || t == TYPE_MAYBE_AUDIO_FEED;
}
// eslint-disable-next-line no-undef
let gHandlerListItemFragment = MozXULElement.parseXULToFragment(`
<richlistitem>
@ -2618,12 +2508,8 @@ class HandlerInfoWrapper {
*/
get actionDescription() {
// alwaysAskBeforeHandling overrides the preferred action, so if that flag
// is set, then describe that behavior instead. For most types, this is
// the "alwaysAsk" string, but for the feed type we show something special.
// is set, then describe that behavior instead.
if (this.alwaysAskBeforeHandling) {
if (isFeedType(this.type))
return gMainPane._prefsBundle.getFormattedString("previewInApp",
[gMainPane._brandShortName]);
return gMainPane._prefsBundle.getString("alwaysAsk");
}
@ -2641,12 +2527,6 @@ class HandlerInfoWrapper {
return gMainPane._prefsBundle.getFormattedString("useApp", [name]);
case Ci.nsIHandlerInfo.handleInternally:
// For the feed type, handleInternally means live bookmarks.
if (isFeedType(this.type)) {
return gMainPane._prefsBundle.getFormattedString("addLiveBookmarksInApp",
[gMainPane._brandShortName]);
}
if (this instanceof InternalHandlerInfoWrapper) {
return gMainPane._prefsBundle.getFormattedString("previewInApp",
[gMainPane._brandShortName]);
@ -2688,9 +2568,7 @@ class HandlerInfoWrapper {
return "save";
case Ci.nsIHandlerInfo.handleInternally:
if (isFeedType(this.type)) {
return "feed";
} else if (this instanceof InternalHandlerInfoWrapper) {
if (this instanceof InternalHandlerInfoWrapper) {
return "ask";
}
@ -2944,269 +2822,6 @@ class HandlerInfoWrapper {
}
}
/**
* This object implements nsIHandlerInfo for the feed types. It's a separate
* object because we currently store handling information for the feed type
* in a set of preferences rather than the nsIHandlerService-managed datastore.
*
* This object inherits from HandlerInfoWrapper in order to get functionality
* that isn't special to the feed type.
*/
class FeedHandlerInfo extends HandlerInfoWrapper {
constructor(aMIMEType, properties) {
super(aMIMEType, null);
Object.assign(this, properties);
}
get description() {
return gMainPane._prefsBundle.getString(this._appPrefLabel);
}
get preferredApplicationHandler() {
switch (Preferences.get(this._prefSelectedReader).value) {
case "client":
var file = Preferences.get(this._prefSelectedApp).value;
if (file)
return getLocalHandlerApp(file);
return null;
case "bookmarks":
default:
// When the pref is set to bookmarks, we handle feeds internally,
// we don't forward them to a local or web handler app, so there is
// no preferred handler.
return null;
}
}
set preferredApplicationHandler(aNewValue) {
if (aNewValue instanceof Ci.nsILocalHandlerApp) {
Preferences.get(this._prefSelectedApp).value = aNewValue.executable;
Preferences.get(this._prefSelectedReader).value = "client";
}
}
get possibleApplicationHandlers() {
if (this._possibleApplicationHandlers)
return this._possibleApplicationHandlers;
// A minimal implementation of nsIMutableArray. It only supports the two
// methods its callers invoke, namely appendElement and nsIArray::enumerate.
this._possibleApplicationHandlers = {
_inner: [],
_removed: [],
QueryInterface: ChromeUtils.generateQI(["nsIMutableArray", "nsIArray"]),
get length() {
return this._inner.length;
},
enumerate() {
return this._inner.values();
},
appendElement(aHandlerApp, aWeak) {
this._inner.push(aHandlerApp);
},
removeElementAt(aIndex) {
this._removed.push(this._inner[aIndex]);
this._inner.splice(aIndex, 1);
},
queryElementAt(aIndex, aInterface) {
return this._inner[aIndex].QueryInterface(aInterface);
},
};
// Add the selected local app if it's different from the OS default handler.
// Unlike for other types, we can store only one local app at a time for the
// feed type, since we store it in a preference that historically stores
// only a single path. But we display all the local apps the user chooses
// while the prefpane is open, only dropping the list when the user closes
// the prefpane, for maximum usability and consistency with other types.
var preferredAppFile = Preferences.get(this._prefSelectedApp).value;
if (preferredAppFile) {
let preferredApp = getLocalHandlerApp(preferredAppFile);
let defaultApp = this._defaultApplicationHandler;
if (!defaultApp || !defaultApp.equals(preferredApp))
this._possibleApplicationHandlers.appendElement(preferredApp);
}
return this._possibleApplicationHandlers;
}
get _defaultApplicationHandler() {
if (typeof this.__defaultApplicationHandler != "undefined")
return this.__defaultApplicationHandler;
var defaultFeedReader = null;
if (AppConstants.HAVE_SHELL_SERVICE) {
try {
defaultFeedReader = getShellService().defaultFeedReader;
} catch (ex) {
// no default reader or getShellService() is null
}
}
if (defaultFeedReader) {
let handlerApp = Cc["@mozilla.org/uriloader/local-handler-app;1"].
createInstance(Ci.nsIHandlerApp);
handlerApp.name = getFileDisplayName(defaultFeedReader);
handlerApp.QueryInterface(Ci.nsILocalHandlerApp);
handlerApp.executable = defaultFeedReader;
this.__defaultApplicationHandler = handlerApp;
} else {
this.__defaultApplicationHandler = null;
}
return this.__defaultApplicationHandler;
}
get hasDefaultHandler() {
if (AppConstants.HAVE_SHELL_SERVICE) {
try {
if (getShellService().defaultFeedReader)
return true;
} catch (ex) {
// no default reader or getShellService() is null
}
}
return false;
}
get defaultDescription() {
if (this.hasDefaultHandler)
return this._defaultApplicationHandler.name;
// Should we instead return null?
return "";
}
// What to do with content of this type.
get preferredAction() {
switch (Preferences.get(this._prefSelectedAction).value) {
case "bookmarks":
return Ci.nsIHandlerInfo.handleInternally;
case "reader": {
let preferredApp = this.preferredApplicationHandler;
let defaultApp = this._defaultApplicationHandler;
// If we have a valid preferred app, return useSystemDefault if it's
// the default app; otherwise return useHelperApp.
if (gMainPane.isValidHandlerApp(preferredApp)) {
if (defaultApp && defaultApp.equals(preferredApp))
return Ci.nsIHandlerInfo.useSystemDefault;
return Ci.nsIHandlerInfo.useHelperApp;
}
// The pref is set to "reader", but we don't have a valid preferred app.
// What do we do now? Not sure this is the best option (perhaps we
// should direct the user to the default app, if any), but for now let's
// direct the user to live bookmarks.
return Ci.nsIHandlerInfo.handleInternally;
}
// If the action is "ask", then alwaysAskBeforeHandling will override
// the action, so it doesn't matter what we say it is, it just has to be
// something that doesn't cause the controller to hide the type.
case "ask":
default:
return Ci.nsIHandlerInfo.handleInternally;
}
}
set preferredAction(aNewValue) {
switch (aNewValue) {
case Ci.nsIHandlerInfo.handleInternally:
Preferences.get(this._prefSelectedReader).value = "bookmarks";
break;
case Ci.nsIHandlerInfo.useHelperApp:
Preferences.get(this._prefSelectedAction).value = "reader";
// The controller has already set preferredApplicationHandler
// to the new helper app.
break;
case Ci.nsIHandlerInfo.useSystemDefault:
Preferences.get(this._prefSelectedAction).value = "reader";
this.preferredApplicationHandler = this._defaultApplicationHandler;
break;
}
}
get alwaysAskBeforeHandling() {
return Preferences.get(this._prefSelectedAction).value == "ask";
}
set alwaysAskBeforeHandling(aNewValue) {
if (aNewValue)
Preferences.get(this._prefSelectedAction).value = "ask";
else
Preferences.get(this._prefSelectedAction).value = "reader";
}
get primaryExtension() {
return "xml";
}
// Changes to the preferred action and handler take effect immediately
// (we write them out to the preferences right as they happen),
// so we when the controller calls store() after modifying the handlers,
// the only thing we need to store is the removal of possible handlers
// XXX Should we hold off on making the changes until this method gets called?
store() {
for (let app of this._possibleApplicationHandlers._removed) {
if (app instanceof Ci.nsILocalHandlerApp) {
let pref = Preferences.get(PREF_FEED_SELECTED_APP);
var preferredAppFile = pref.value;
if (preferredAppFile) {
let preferredApp = getLocalHandlerApp(preferredAppFile);
if (app.equals(preferredApp))
pref.reset();
}
}
}
this._possibleApplicationHandlers._removed = [];
}
get smallIcon() {
return this._smallIcon;
}
}
var feedHandlerInfo = new FeedHandlerInfo(TYPE_MAYBE_FEED, {
_prefSelectedApp: PREF_FEED_SELECTED_APP,
_prefSelectedAction: PREF_FEED_SELECTED_ACTION,
_prefSelectedReader: PREF_FEED_SELECTED_READER,
_smallIcon: "chrome://browser/skin/feeds/feedIcon16.png",
_appPrefLabel: "webFeed",
});
var videoFeedHandlerInfo = new FeedHandlerInfo(TYPE_MAYBE_VIDEO_FEED, {
_prefSelectedApp: PREF_VIDEO_FEED_SELECTED_APP,
_prefSelectedAction: PREF_VIDEO_FEED_SELECTED_ACTION,
_prefSelectedReader: PREF_VIDEO_FEED_SELECTED_READER,
_smallIcon: "chrome://browser/skin/feeds/videoFeedIcon16.png",
_appPrefLabel: "videoPodcastFeed",
});
var audioFeedHandlerInfo = new FeedHandlerInfo(TYPE_MAYBE_AUDIO_FEED, {
_prefSelectedApp: PREF_AUDIO_FEED_SELECTED_APP,
_prefSelectedAction: PREF_AUDIO_FEED_SELECTED_ACTION,
_prefSelectedReader: PREF_AUDIO_FEED_SELECTED_READER,
_smallIcon: "chrome://browser/skin/feeds/audioFeedIcon16.png",
_appPrefLabel: "audioPodcastFeed",
});
/**
* InternalHandlerInfoWrapper provides a basic mechanism to create an internal
* mime type handler that can be enabled/disabled in the applications preference

Просмотреть файл

@ -684,9 +684,3 @@ nsGNOMEShellService::OpenApplicationWithURI(nsIFile* aApplication, const nsACStr
const char* specStr = spec.get();
return process->Run(false, &specStr, 1);
}
NS_IMETHODIMP
nsGNOMEShellService::GetDefaultFeedReader(nsIFile** _retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}

Просмотреть файл

@ -92,9 +92,4 @@ interface nsIShellService : nsISupports
* The uri to be loaded by the application
*/
void openApplicationWithURI(in nsIFile aApplication, in ACString aURI);
/**
* The default system handler for web feeds
*/
readonly attribute nsIFile defaultFeedReader;
};

Просмотреть файл

@ -383,42 +383,3 @@ nsMacShellService::OpenApplicationWithURI(nsIFile* aApplication, const nsACStrin
return err != noErr ? NS_ERROR_FAILURE : NS_OK;
}
NS_IMETHODIMP
nsMacShellService::GetDefaultFeedReader(nsIFile** _retval)
{
nsresult rv = NS_ERROR_FAILURE;
*_retval = nullptr;
CFStringRef defaultHandlerID = ::LSCopyDefaultHandlerForURLScheme(CFSTR("feed"));
if (!defaultHandlerID) {
defaultHandlerID = ::CFStringCreateWithCString(kCFAllocatorDefault,
SAFARI_BUNDLE_IDENTIFIER,
kCFStringEncodingASCII);
}
CFURLRef defaultHandlerURL = nullptr;
OSStatus status = ::LSFindApplicationForInfo(kLSUnknownCreator,
defaultHandlerID,
nullptr, // inName
nullptr, // outAppRef
&defaultHandlerURL);
if (status == noErr && defaultHandlerURL) {
nsCOMPtr<nsILocalFileMac> defaultReader =
do_CreateInstance("@mozilla.org/file/local;1", &rv);
if (NS_SUCCEEDED(rv)) {
rv = defaultReader->InitWithCFURL(defaultHandlerURL);
if (NS_SUCCEEDED(rv)) {
NS_ADDREF(*_retval = defaultReader);
rv = NS_OK;
}
}
::CFRelease(defaultHandlerURL);
}
::CFRelease(defaultHandlerID);
return rv;
}

Просмотреть файл

@ -760,50 +760,3 @@ nsWindowsShellService::OpenApplicationWithURI(nsIFile* aApplication,
const char* specStr = spec.get();
return process->Run(false, &specStr, 1);
}
NS_IMETHODIMP
nsWindowsShellService::GetDefaultFeedReader(nsIFile** _retval)
{
*_retval = nullptr;
nsresult rv;
nsCOMPtr<nsIWindowsRegKey> regKey =
do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_CLASSES_ROOT,
NS_LITERAL_STRING("feed\\shell\\open\\command"),
nsIWindowsRegKey::ACCESS_READ);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString path;
rv = regKey->ReadStringValue(EmptyString(), path);
NS_ENSURE_SUCCESS(rv, rv);
if (path.IsEmpty())
return NS_ERROR_FAILURE;
if (path.First() == '"') {
// Everything inside the quotes
path = Substring(path, 1, path.FindChar('"', 1) - 1);
}
else {
// Everything up to the first space
path = Substring(path, 0, path.FindChar(' '));
}
nsCOMPtr<nsIFile> defaultReader =
do_CreateInstance("@mozilla.org/file/local;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = defaultReader->InitWithPath(path);
NS_ENSURE_SUCCESS(rv, rv);
bool exists;
rv = defaultReader->Exists(&exists);
NS_ENSURE_SUCCESS(rv, rv);
if (!exists)
return NS_ERROR_FAILURE;
NS_ADDREF(*_retval = defaultReader);
return NS_OK;
}

Просмотреть файл

@ -28,7 +28,6 @@ MockShellService.prototype = {
openApplication(aApplication) {},
desktopBackgroundColor: 0,
openApplicationWithURI(aApplication, aURI) {},
defaultFeedReader: 0,
};
var mockShellService = new MockObjectRegisterer("@mozilla.org/browser/shell-service;1",

Просмотреть файл

@ -176,8 +176,6 @@
@BINPATH@/components/nsDNSServiceDiscovery.js
#endif
@RESPATH@/browser/components/BrowserFeeds.manifest
@RESPATH@/browser/components/FeedConverter.js
@RESPATH@/browser/components/FeedWriter.js
@RESPATH@/browser/components/WebContentConverter.js
@RESPATH@/browser/components/BrowserComponents.manifest
@RESPATH@/browser/components/nsBrowserContentHandler.js

Просмотреть файл

@ -10,8 +10,6 @@ app-manager-remove =
.label = Remove
.accesskey = R
app-manager-handle-webfeeds = The following applications can be used to handle Web Feeds.
# Variables:
# $type (String) - the URI scheme of the link (e.g. mailto:)
app-manager-handle-protocol = The following applications can be used to handle { $type } links.

Просмотреть файл

@ -1,10 +0,0 @@
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<!ENTITY feedPage.title
"Viewing Feed">
<!ENTITY feedSubscribeNow
"Subscribe Now">
<!ENTITY feedLiveBookmarks
"Live Bookmarks">

Просмотреть файл

@ -2,49 +2,6 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
linkTitleTextFormat=Go to %S
addHandler=Add “%S” (%S) as a Feed Reader?
addHandlerAddButton=Add Feed Reader
addHandlerAddButtonAccesskey=A
handlerRegistered=“%S” is already registered as a Feed Reader
liveBookmarks=Live Bookmarks
subscribeNow=Subscribe Now
chooseApplicationMenuItem=Choose Application…
chooseApplicationDialogTitle=Choose Application
alwaysUse=Always use %S to subscribe to feeds
mediaLabel=Media files
# LOCALIZATION NOTE: The next string is for the size of the enclosed media.
# e.g. enclosureSizeText : "50.23 MB"
# %1$S = size (in bytes or megabytes, ...)
# %2$S = unit of measure (bytes, KB, MB, ...)
enclosureSizeText=%1$S %2$S
bytes=bytes
kilobyte=KB
megabyte=MB
gigabyte=GB
# LOCALIZATION NOTE: The next three strings explains to the user what they're
# doing.
# e.g. alwaysUseForVideoPodcasts : "Always use Miro to subscribe to video podcasts."
# %S = application to use (Miro, iTunes, ...)
alwaysUseForFeeds=Always use %S to subscribe to feeds.
alwaysUseForAudioPodcasts=Always use %S to subscribe to podcasts.
alwaysUseForVideoPodcasts=Always use %S to subscribe to video podcasts.
subscribeFeedUsing=Subscribe to this feed using
subscribeAudioPodcastUsing=Subscribe to this podcast using
subscribeVideoPodcastUsing=Subscribe to this video podcast using
feedSubscriptionFeed1=This is a “feed” of frequently changing content on this site.
feedSubscriptionAudioPodcast1=This is a “podcast” of frequently changing content on this site.
feedSubscriptionVideoPodcast1=This is a “video podcast” of frequently changing content on this site.
feedSubscriptionFeed2=You can subscribe to this feed to receive updates when this content changes.
feedSubscriptionAudioPodcast2=You can subscribe to this podcast to receive updates when this content changes.
feedSubscriptionVideoPodcast2=You can subscribe to this video podcast to receive updates when this content changes.
# LOCALIZATION NOTE (addProtocolHandlerMessage):
# Message displayed when adding a protocol handler:
# %1$S is the application's domain, %2$S is the type of protocol

Просмотреть файл

@ -50,7 +50,6 @@
locale/browser/safebrowsing/phishing-afterload-warning-message.dtd (%chrome/browser/safebrowsing/phishing-afterload-warning-message.dtd)
locale/browser/safebrowsing/report-phishing.dtd (%chrome/browser/safebrowsing/report-phishing.dtd)
locale/browser/safebrowsing/safebrowsing.properties (%chrome/browser/safebrowsing/safebrowsing.properties)
locale/browser/feeds/subscribe.dtd (%chrome/browser/feeds/subscribe.dtd)
locale/browser/feeds/subscribe.properties (%chrome/browser/feeds/subscribe.properties)
locale/browser/migration/migration.dtd (%chrome/browser/migration/migration.dtd)
locale/browser/migration/migration.properties (%chrome/browser/migration/migration.properties)

Двоичные данные
browser/themes/linux/feeds/feedIcon.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.6 KiB

Двоичные данные
browser/themes/linux/feeds/feedIcon16.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 686 B

Просмотреть файл

@ -1,185 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
html {
background: -moz-Dialog;
font: 3mm tahoma,arial,helvetica,sans-serif;
}
#subscribeUsingDescription,
#subscribeButton {
display: block;
}
#subscribeUsingDescription {
margin-bottom: 0.5em;
}
#subscribeButton {
margin-top: 0.5em;
margin-inline-start: auto;
}
#feedBody {
border: 1px solid THreeDShadow;
padding: 3em;
padding-inline-start: 30px;
margin: 2em auto;
background: -moz-Field;
}
#feedHeaderContainer {
border: 1px solid ThreeDShadow;
border-radius: 10px;
margin: -4em auto 0 auto;
background-color: InfoBackground;
-moz-appearance: -moz-gtk-info-bar;
display: flex;
}
#feedHeaderContainerSpacer {
flex-grow: 1;
}
#feedHeader {
margin-top: 4.9em;
margin-bottom: 1em;
margin-inline-start: 1.4em;
margin-inline-end: 1em;
padding-inline-start: 2.9em;
font-size: 110%;
color: -moz-gtk-info-bar-text;
}
.feedBackground {
background: url("chrome://browser/skin/feeds/feedIcon.png") 0% 10% no-repeat;
}
.videoPodcastBackground {
background: url("chrome://browser/skin/feeds/videoFeedIcon.png") 0% 10% no-repeat;
}
.audioPodcastBackground {
background: url("chrome://browser/skin/feeds/audioFeedIcon.png") 0% 10% no-repeat;
}
#feedHeader[dir="rtl"] {
background-position: 100% 10%;
}
#feedIntroText {
display: none;
}
#feedHeader[firstrun="true"] #feedIntroText {
padding-top: 0.1em;
padding-inline-start: 0.6em;
display: block;
}
#feedHeader[firstrun="true"] > #feedSubscribeLine {
padding-inline-start: 1.8em;
}
#feedSubscribeLine {
padding-top: 0.2em;
padding-inline-start: 0.5em;
}
/* Don't print subscription UI */
@media print {
#feedHeaderContainer {
display: none;
}
}
body {
margin: 0;
padding: 0 3em;
color: -moz-fieldText;
font: message-box;
}
h1 {
font-size: 160%;
border-bottom: 2px solid ThreeDLightShadow;
margin: 0 0 .2em 0;
}
h2 {
color: GrayText;
font-size: 110%;
font-weight: normal;
margin: 0 0 .6em 0;
}
#feedTitleLink {
float: right;
margin-inline-start: .6em;
margin-inline-end: 0;
margin-top: 0;
margin-bottom: 0;
}
a[href] img {
border: none;
}
#feedTitleContainer {
margin-inline-start: 0;
margin-inline-end: .6em;
margin-top: 0;
margin-bottom: 0;
}
#feedTitleImage {
margin-inline-start: .6em;
margin-inline-end: 0;
margin-top: 0;
margin-bottom: 0;
max-width: 300px;
max-height: 150px;
}
.feedEntryContent {
font-size: 110%;
}
.link {
color: #0000FF;
text-decoration: underline;
cursor: pointer;
}
.link:hover:active {
color: #FF0000;
}
.lastUpdated {
font-size: 85%;
font-weight: normal;
}
.type-icon {
vertical-align: bottom;
height: 16px;
width: 16px;
}
.enclosures {
border: 1px solid THreeDShadow;
padding: 1em;
margin: 1em auto;
background: -moz-Dialog;
}
.enclosure {
vertical-align: middle;
margin-left: 2px;
}
.handlersMenuList > .menulist-label-box > .menulist-icon {
max-width: 16px;
max-height: 16px;
}

Просмотреть файл

@ -13,7 +13,6 @@ browser.jar:
skin/classic/browser/monitor_16-10.png
* skin/classic/browser/pageInfo.css
skin/classic/browser/pageInfo.png
skin/classic/browser/page-livemarks.png
* skin/classic/browser/searchbar.css
skin/classic/browser/setDesktopBackground.css
skin/classic/browser/slowStartup-16.png
@ -22,9 +21,6 @@ browser.jar:
* skin/classic/browser/customizableui/panelUI.css (customizableui/panelUI.css)
* skin/classic/browser/downloads/allDownloadsView.css (downloads/allDownloadsView.css)
* skin/classic/browser/downloads/downloads.css (downloads/downloads.css)
skin/classic/browser/feeds/feedIcon.png (feeds/feedIcon.png)
skin/classic/browser/feeds/feedIcon16.png (feeds/feedIcon16.png)
skin/classic/browser/feeds/subscribe.css (feeds/subscribe.css)
skin/classic/browser/notification-icons/geo-blocked.svg (notification-icons/geo-blocked.svg)
skin/classic/browser/notification-icons/geo-detailed.svg (notification-icons/geo-detailed.svg)
skin/classic/browser/notification-icons/geo.svg (notification-icons/geo.svg)
@ -46,8 +42,3 @@ browser.jar:
skin/classic/browser/window-controls/restore.svg (window-controls/restore.svg)
skin/classic/browser/e10s-64@2x.png (../shared/e10s-64@2x.png)
% override chrome://browser/skin/feeds/audioFeedIcon.png chrome://browser/skin/feeds/feedIcon.png
% override chrome://browser/skin/feeds/audioFeedIcon16.png chrome://browser/skin/feeds/feedIcon16.png
% override chrome://browser/skin/feeds/videoFeedIcon.png chrome://browser/skin/feeds/feedIcon.png
% override chrome://browser/skin/feeds/videoFeedIcon16.png chrome://browser/skin/feeds/feedIcon16.png

Двоичные данные
browser/themes/linux/page-livemarks.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 638 B

Просмотреть файл

@ -40,10 +40,6 @@
-moz-image-region: rect(0px, 64px, 32px, 32px)
}
#feedTab {
-moz-image-region: rect(0px, 96px, 32px, 64px)
}
#permTab {
-moz-image-region: rect(0px, 128px, 32px, 96px)
}
@ -136,39 +132,6 @@ treechildren::-moz-tree-cell-text(broken) {
color: graytext;
}
/* Feeds Tab */
#feedPanel {
margin-left: 2px;
margin-right: 2px;
}
#feedtree {
margin-bottom: 0px;
}
#feedListbox richlistitem {
padding-top: 6px;
padding-bottom: 6px;
padding-inline-start: 7px;
padding-inline-end: 7px;
min-height: 25px;
border-bottom: 1px dotted ThreeDShadow;
color: -moz-FieldText;
}
#feedListbox richlistitem[selected="true"] {
background-color: -moz-Dialog;
color: -moz-DialogText;
}
#feedListbox {
margin-bottom: 0;
}
.feedTitle {
font-weight: bold;
}
/* Permissions Tab */
#permList {

Просмотреть файл

@ -40,11 +40,6 @@ menuitem[appHandlerIcon="save"] {
list-style-image: url("moz-icon://stock/gtk-save?size=menu");
}
richlistitem[appHandlerIcon="feed"],
menuitem[appHandlerIcon="feed"] {
list-style-image: url("chrome://browser/skin/page-livemarks.png");
}
richlistitem[appHandlerIcon="plugin"],
menuitem[appHandlerIcon="plugin"] {
list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.svg");

Двоичные данные
browser/themes/osx/feeds/feedIcon.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.6 KiB

Двоичные данные
browser/themes/osx/feeds/feedIcon16.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 762 B

Просмотреть файл

@ -1,178 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
html {
background: -moz-Dialog;
font: 3mm tahoma,arial,helvetica,sans-serif;
}
#subscribeUsingDescription,
#subscribeButton {
display: block;
}
#subscribeUsingDescription {
margin-bottom: 0.5em;
}
#subscribeButton {
margin-top: 0.5em;
margin-inline-start: auto;
}
#feedBody {
border: 1px solid THreeDShadow;
padding: 3em;
padding-inline-start: 30px;
margin: 2em auto;
background: -moz-Field;
}
#feedHeaderContainer {
display: flex;
}
#feedHeaderContainerSpacer {
flex-grow: 1;
}
#feedHeader {
border: 1px solid ThreeDShadow;
border-radius: 10px;
padding-top: 4em;
padding-bottom: .3em;
padding-inline-start: .3em;
padding-inline-end: .3em;
margin: -4em auto 0 auto;
font-size: 110%;
color: InfoText;
padding: 5em 3em 0 3em;
}
.feedBackground {
background: url("chrome://browser/skin/feeds/feedIcon.png") 1.4em 5.9em no-repeat rgb(255,255,225);
}
.videoPodcastBackground {
background: url("chrome://browser/skin/feeds/videoFeedIcon.png") 1.4em 5.9em no-repeat rgb(255,255,225);
}
.audioPodcastBackground {
background: url("chrome://browser/skin/feeds/audioFeedIcon.png") 1.4em 5.9em no-repeat rgb(255,255,225);
}
#feedHeader[firstrun="true"] #feedIntroText {
display: block;
}
#feedIntroText {
display: none;
margin-inline-start: 2em;
}
#feedSubscribeLine {
padding: 0 1em 1em 2em;
}
#feedHeader[firstrun="true"] #feedSubscribeLine {
padding-left: 3.7em;
}
/* Don't print subscription UI */
@media print {
#feedHeaderContainer {
display: none;
}
}
body {
margin: 0;
padding: 0 3em;
color: -moz-fieldText;
font: message-box;
}
h1 {
font-size: 160%;
border-bottom: 2px solid ThreeDLightShadow;
margin: 0 0 .2em 0;
}
h2 {
color: #C0C0C0;
font-size: 110%;
font-weight: normal;
margin: 0 0 .6em 0;
}
#feedTitleLink {
float: right;
margin-inline-start: .6em;
margin-inline-end: 0;
margin-top: 0;
margin-bottom: 0;
}
a[href] img {
border: none;
}
#feedTitleContainer {
margin-inline-start: 0;
margin-inline-end: .6em;
margin-top: 0;
margin-bottom: 0;
}
#feedTitleImage {
margin-inline-start: .6em;
margin-inline-end: 0;
margin-top: 0;
margin-bottom: 0;
max-width: 300px;
max-height: 150px;
}
.feedEntryContent {
font-size: 110%;
}
.link {
color: #0000FF;
text-decoration: underline;
cursor: pointer;
margin-top: -2px;
}
.link:hover:active {
color: #FF0000;
}
.lastUpdated {
font-size: 85%;
font-weight: normal;
}
.type-icon {
vertical-align: bottom;
height: 16px;
width: 16px;
}
.enclosures {
border: 1px solid THreeDShadow;
padding: 1em;
margin: 1em auto;
background: -moz-Dialog;
}
.enclosure {
vertical-align: middle;
margin-left: 2px;
}
.handlersMenuList > .menulist-label-box > .menulist-icon {
max-width: 16px;
max-height: 16px;
}

Просмотреть файл

@ -14,7 +14,6 @@ browser.jar:
skin/classic/browser/panel-expander-open.png
skin/classic/browser/panel-expander-open@2x.png
skin/classic/browser/panel-plus-sign.png
skin/classic/browser/page-livemarks.png
* skin/classic/browser/pageInfo.css
* skin/classic/browser/searchbar.css
skin/classic/browser/slowStartup-16.png
@ -25,9 +24,6 @@ browser.jar:
* skin/classic/browser/customizableui/panelUI.css (customizableui/panelUI.css)
* skin/classic/browser/downloads/allDownloadsView.css (downloads/allDownloadsView.css)
* skin/classic/browser/downloads/downloads.css (downloads/downloads.css)
skin/classic/browser/feeds/subscribe.css (feeds/subscribe.css)
skin/classic/browser/feeds/feedIcon.png (feeds/feedIcon.png)
skin/classic/browser/feeds/feedIcon16.png (feeds/feedIcon16.png)
skin/classic/browser/setDesktopBackground.css
skin/classic/browser/monitor.png
skin/classic/browser/monitor_16-10.png
@ -52,8 +48,4 @@ browser.jar:
skin/classic/browser/tabbrowser/tabDragIndicator@2x.png (tabbrowser/tabDragIndicator@2x.png)
skin/classic/browser/e10s-64@2x.png (../shared/e10s-64@2x.png)
% override chrome://browser/skin/feeds/audioFeedIcon.png chrome://browser/skin/feeds/feedIcon.png
% override chrome://browser/skin/feeds/audioFeedIcon16.png chrome://browser/skin/feeds/feedIcon16.png
% override chrome://browser/skin/feeds/videoFeedIcon.png chrome://browser/skin/feeds/feedIcon.png
% override chrome://browser/skin/feeds/videoFeedIcon16.png chrome://browser/skin/feeds/feedIcon16.png
% override chrome://browser/skin/notification-icons/geo-detailed.svg chrome://browser/skin/notification-icons/geo.svg

Двоичные данные
browser/themes/osx/page-livemarks.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 606 B

Просмотреть файл

@ -109,29 +109,6 @@ treechildren::-moz-tree-cell-text(broken) {
color: graytext;
}
/* Feeds Tab */
#feedtree {
margin-bottom: 0px;
}
#feedListbox richlistitem {
padding-top: 6px;
padding-bottom: 6px;
padding-inline-start: 7px;
padding-inline-end: 7px;
min-height: 25px;
border-bottom: 1px dotted ThreeDShadow;
}
#feedListbox richlistitem[selected="true"] {
background-color: -moz-Dialog;
color: -moz-DialogText;
}
.feedTitle {
font-weight: bold;
}
/* Permissions Tab */
#permList {
margin: .5em;

Просмотреть файл

@ -51,11 +51,6 @@ menuitem[appHandlerIcon="save"] {
list-style-image: url("chrome://browser/skin/preferences/saveFile.png");
}
richlistitem[appHandlerIcon="feed"],
menuitem[appHandlerIcon="feed"] {
list-style-image: url("chrome://browser/skin/page-livemarks.png");
}
richlistitem[appHandlerIcon="plugin"],
menuitem[appHandlerIcon="plugin"] {
list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.svg");

Просмотреть файл

@ -882,11 +882,6 @@ notification[value="translation"] {
}
/* Bookmarks roots menu-items */
#subscribeToPageMenuitem:not([disabled]),
#subscribeToPageMenupopup {
list-style-image: url("chrome://browser/skin/feeds/feedIcon16.png");
}
#bookmarksToolbarFolderMenu,
#BMB_bookmarksToolbar,
#panelMenu_bookmarksToolbar {

Двоичные данные
browser/themes/windows/feeds/feedIcon.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 1.7 KiB

Двоичные данные
browser/themes/windows/feeds/feedIcon16.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 743 B

Просмотреть файл

@ -1,184 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
html {
background: -moz-Dialog;
font: 3mm tahoma,arial,helvetica,sans-serif;
}
#subscribeUsingDescription,
#subscribeButton {
display: block;
}
#subscribeUsingDescription {
margin-bottom: 0.5em;
}
#subscribeButton {
margin-top: 0.5em;
margin-inline-start: auto;
}
#feedBody {
border: 1px solid THreeDShadow;
padding: 3em;
padding-inline-start: 30px;
margin: 2em auto;
background: -moz-Field;
}
#feedHeaderContainer {
border: 1px solid ThreeDShadow;
border-radius: 10px;
margin: -4em auto 0 auto;
background-color: InfoBackground;
display: flex;
}
#feedHeaderContainerSpacer {
flex-grow: 1;
}
#feedHeader {
margin-top: 4.9em;
margin-bottom: 1em;
margin-inline-start: 1.4em;
margin-inline-end: 1em;
padding-inline-start: 2.9em;
font-size: 110%;
color: InfoText;
}
#feedIntroText {
display: none;
}
.feedBackground {
background: url("chrome://browser/skin/feeds/feedIcon.png") 0% 10% no-repeat InfoBackground;
}
.videoPodcastBackground {
background: url("chrome://browser/skin/feeds/videoFeedIcon.png") 0% 10% no-repeat InfoBackground;
}
.audioPodcastBackground {
background: url("chrome://browser/skin/feeds/audioFeedIcon.png") 0% 10% no-repeat InfoBackground;
}
#feedHeader[dir="rtl"] {
background-position: 100% 10%;
}
#feedHeader[firstrun="true"] #feedIntroText {
padding-top: 0.1em;
padding-inline-start: 0.6em;
display: block;
}
#feedHeader[firstrun="true"] > #feedSubscribeLine {
padding-inline-start: 1.8em;
}
#feedSubscribeLine {
padding-top: 0.2em;
padding-inline-start: 0.5em;
}
/* Don't print subscription UI */
@media print {
#feedHeaderContainer {
display: none;
}
}
body {
margin: 0;
padding: 0 3em;
color: -moz-fieldText;
font: message-box;
}
h1 {
font-size: 160%;
border-bottom: 2px solid ThreeDLightShadow;
margin: 0 0 .2em 0;
}
h2 {
color: GrayText;
font-size: 110%;
font-weight: normal;
margin: 0 0 .6em 0;
}
#feedTitleLink {
float: right;
margin-inline-start: .6em;
margin-inline-end: 0;
margin-top: 0;
margin-bottom: 0;
}
a[href] img {
border: none;
}
#feedTitleContainer {
margin-inline-start: 0;
margin-inline-end: .6em;
margin-top: 0;
margin-bottom: 0;
}
#feedTitleImage {
margin-inline-start: .6em;
margin-inline-end: 0;
margin-top: 0;
margin-bottom: 0;
max-width: 300px;
max-height: 150px;
}
.feedEntryContent {
font-size: 110%;
}
.link {
color: #0000FF;
text-decoration: underline;
cursor: pointer;
}
.link:hover:active {
color: #FF0000;
}
.lastUpdated {
font-size: 85%;
font-weight: normal;
}
.type-icon {
vertical-align: bottom;
height: 16px;
width: 16px;
}
.enclosures {
border: 1px solid THreeDShadow;
padding: 1em;
margin: 1em auto;
background: -moz-Dialog;
}
.enclosure {
vertical-align: middle;
margin-left: 2px;
}
.handlersMenuList > .menulist-label-box > .menulist-icon {
max-width: 16px;
max-height: 16px;
}

Просмотреть файл

@ -21,9 +21,6 @@ browser.jar:
* skin/classic/browser/customizableui/panelUI.css (customizableui/panelUI.css)
* skin/classic/browser/downloads/allDownloadsView.css (downloads/allDownloadsView.css)
* skin/classic/browser/downloads/downloads.css (downloads/downloads.css)
skin/classic/browser/feeds/feedIcon.png (feeds/feedIcon.png)
skin/classic/browser/feeds/feedIcon16.png (feeds/feedIcon16.png)
skin/classic/browser/feeds/subscribe.css (feeds/subscribe.css)
skin/classic/browser/notification-icons/geo-blocked.svg (notification-icons/geo-blocked.svg)
skin/classic/browser/notification-icons/geo-detailed.svg (notification-icons/geo-detailed.svg)
skin/classic/browser/notification-icons/geo.svg (notification-icons/geo.svg)
@ -55,9 +52,3 @@ browser.jar:
skin/classic/browser/window-controls/restore-highcontrast.svg (window-controls/restore-highcontrast.svg)
skin/classic/browser/window-controls/restore-themes.svg (window-controls/restore-themes.svg)
skin/classic/browser/e10s-64@2x.png (../shared/e10s-64@2x.png)
% override chrome://browser/skin/page-livemarks.png chrome://browser/skin/feeds/feedIcon16.png
% override chrome://browser/skin/feeds/audioFeedIcon.png chrome://browser/skin/feeds/feedIcon.png
% override chrome://browser/skin/feeds/audioFeedIcon16.png chrome://browser/skin/feeds/feedIcon16.png
% override chrome://browser/skin/feeds/videoFeedIcon.png chrome://browser/skin/feeds/feedIcon.png
% override chrome://browser/skin/feeds/videoFeedIcon16.png chrome://browser/skin/feeds/feedIcon16.png

Просмотреть файл

@ -58,15 +58,6 @@
-moz-image-region: rect(32px, 64px, 64px, 32px)
}
#feedTab {
-moz-image-region: rect(0px, 96px, 32px, 64px)
}
#feedTab:hover,
#feedTab[selected="true"] {
-moz-image-region: rect(32px, 96px, 64px, 64px)
}
#permTab {
-moz-image-region: rect(0px, 128px, 32px, 96px)
}
@ -161,29 +152,6 @@ treechildren::-moz-tree-cell-text(broken) {
color: graytext;
}
/* Feeds Tab */
#feedtree {
margin-bottom: 0px;
}
#feedListbox richlistitem {
padding-top: 6px;
padding-bottom: 6px;
padding-inline-start: 7px;
padding-inline-end: 7px;
min-height: 25px;
border-bottom: 1px dotted ThreeDShadow;
}
#feedListbox richlistitem[selected="true"] {
background-color: -moz-Dialog;
color: -moz-DialogText;
}
.feedTitle {
font-weight: bold;
}
/* Permissions Tab */
#permList {
margin: .5em;

Просмотреть файл

@ -40,11 +40,6 @@ menuitem[appHandlerIcon="save"] {
list-style-image: url("chrome://browser/skin/preferences/saveFile.png");
}
richlistitem[appHandlerIcon="feed"],
menuitem[appHandlerIcon="feed"] {
list-style-image: url("chrome://browser/skin/page-livemarks.png");
}
richlistitem[appHandlerIcon="plugin"],
menuitem[appHandlerIcon="plugin"] {
list-style-image: url("chrome://mozapps/skin/plugins/pluginGeneric.svg");

Просмотреть файл

@ -1,19 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "js/TypeDecls.h"
#include "nsContentUtils.h"
namespace mozilla {
struct FeedWriterEnabled {
static bool IsEnabled(JSContext* cx, JSObject* aGlobal)
{
return nsContentUtils::IsSpecificAboutPage(aGlobal, "about:feeds");
}
};
}

Просмотреть файл

@ -129,7 +129,6 @@ if CONFIG['MOZ_WEBRTC']:
EXPORTS.mozilla += [
'CORSMode.h',
'FeedWriterEnabled.h',
'FlushType.h',
'FullscreenChange.h',
'RangeBoundary.h',

Просмотреть файл

@ -1,20 +0,0 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*/
[JSImplementation="@mozilla.org/browser/feeds/result-writer;1",
Func="mozilla::FeedWriterEnabled::IsEnabled",
Constructor]
interface BrowserFeedWriter {
/**
* Writes the feed content, assumes that the feed writer is initialized.
*/
void writeContent();
/**
* Uninitialize the feed writer.
*/
void close();
};

Просмотреть файл

@ -1091,11 +1091,6 @@ if CONFIG['MOZ_WEBSPEECH']:
'SpeechSynthesisEvent.webidl',
]
if CONFIG['MOZ_BUILD_APP'] in ['browser', 'xulrunner'] or CONFIG['MOZ_SUITE']:
WEBIDL_FILES += [
'BrowserFeedWriter.webidl',
]
if CONFIG['MOZ_BUILD_APP'] in ['browser', 'mobile/android', 'xulrunner']:
WEBIDL_FILES += [
'External.webidl',

Просмотреть файл

@ -20,7 +20,6 @@ module.exports = {
"globals": {
"AddonManagerPermissions": false,
"BroadcastChannel": false,
"BrowserFeedWriter": false,
"CSSAnimation": false,
"CSSPrimitiveValue": false,
"CSSValueList": false,