Bug 401153: Provide resource:// substitutions for installed add-ons.
r=bsmedberg, a=beltzner git-svn-id: svn://10.0.0.236/trunk@241961 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -99,6 +99,8 @@
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIPrefBranch2.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIProtocolHandler.h"
|
||||
#include "nsIResProtocolHandler.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsISimpleEnumerator.h"
|
||||
@@ -2099,6 +2101,13 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
|
||||
nsCOMPtr<nsIIOService> io (do_GetIOService());
|
||||
if (!io) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIProtocolHandler> ph;
|
||||
rv = io->GetProtocolHandler("resource", getter_AddRefs(ph));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIResProtocolHandler> rph (do_QueryInterface(ph));
|
||||
if (!rph) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIURI> manifestURI;
|
||||
rv = io->NewFileURI(aManifest, getter_AddRefs(manifestURI));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
@@ -2515,6 +2524,72 @@ nsChromeRegistry::ProcessManifestBuffer(char *buf, PRInt32 length,
|
||||
|
||||
mOverrideTable.Put(chromeuri, resolveduri);
|
||||
}
|
||||
else if (!strcmp(token, "resource")) {
|
||||
if (aSkinOnly) {
|
||||
LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
|
||||
"Warning: Ignoring resource registration in skin-only manifest.");
|
||||
continue;
|
||||
}
|
||||
|
||||
char *package = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
|
||||
char *uri = nsCRT::strtok(whitespace, kWhitespace, &whitespace);
|
||||
if (!package || !uri) {
|
||||
LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
|
||||
"Warning: Malformed resource registration.");
|
||||
continue;
|
||||
}
|
||||
|
||||
EnsureLowerCase(package);
|
||||
|
||||
TriState stAppVersion = eUnspecified;
|
||||
TriState stApp = eUnspecified;
|
||||
TriState stOsVersion = eUnspecified;
|
||||
TriState stOs = eUnspecified;
|
||||
|
||||
PRBool badFlag = PR_FALSE;
|
||||
|
||||
while (nsnull != (token = nsCRT::strtok(whitespace, kWhitespace, &whitespace)) &&
|
||||
!badFlag) {
|
||||
NS_ConvertASCIItoUTF16 wtoken(token);
|
||||
ToLowerCase(wtoken);
|
||||
|
||||
if (CheckStringFlag(kApplication, wtoken, appID, stApp) ||
|
||||
CheckStringFlag(kOs, wtoken, osTarget, stOs) ||
|
||||
CheckVersionFlag(kOsVersion, wtoken, osVersion, vc, stOsVersion) ||
|
||||
CheckVersionFlag(kAppVersion, wtoken, appVersion, vc, stAppVersion))
|
||||
continue;
|
||||
|
||||
LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
|
||||
"Warning: Unrecognized chrome registration modifier '%s'.",
|
||||
token);
|
||||
badFlag = PR_TRUE;
|
||||
}
|
||||
|
||||
if (badFlag || stApp == eBad || stAppVersion == eBad ||
|
||||
stOs == eBad || stOsVersion == eBad)
|
||||
continue;
|
||||
|
||||
nsDependentCString host(package);
|
||||
|
||||
PRBool exists;
|
||||
rv = rph->HasSubstitution(host, &exists);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (exists) {
|
||||
LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
|
||||
"Warning: Duplicate resource declaration for '%s' ignored.",
|
||||
package);
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> resolved;
|
||||
rv = io->NewURI(nsDependentCString(uri), nsnull, manifestURI,
|
||||
getter_AddRefs(resolved));
|
||||
if (NS_FAILED(rv))
|
||||
continue;
|
||||
|
||||
rv = rph->SetSubstitution(host, resolved);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else {
|
||||
LogMessageWithContext(manifestURI, line, nsIScriptError::warningFlag,
|
||||
"Warning: Ignoring unrecognized chrome manifest instruction.");
|
||||
|
||||
17
mozilla/chrome/test/unit/data/test_bug401153.manifest
Normal file
17
mozilla/chrome/test/unit/data/test_bug401153.manifest
Normal file
@@ -0,0 +1,17 @@
|
||||
# Should work
|
||||
resource test1 test1/
|
||||
|
||||
# Duplicates should be ignored
|
||||
resource test1 foo/
|
||||
|
||||
# Mapping off file system should work
|
||||
resource test2 http://www.mozilla.org/
|
||||
|
||||
# Mapping into jar files should work
|
||||
resource test3 jar:test3.jar!/resources/
|
||||
|
||||
# Invalid line
|
||||
resource test4
|
||||
|
||||
# Check we made it through the whole manifest
|
||||
resource test5 test5/
|
||||
173
mozilla/chrome/test/unit/test_bug401153.js
Normal file
173
mozilla/chrome/test/unit/test_bug401153.js
Normal file
@@ -0,0 +1,173 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Dave Townsend <dtownsend@oxymoronical.com>.
|
||||
*
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
const XULAPPINFO_CONTRACTID = "@mozilla.org/xre/app-info;1";
|
||||
const XULAPPINFO_CID = Components.ID("{48a4e946-1f9f-4224-b4b0-9a54183cb81e}");
|
||||
|
||||
const NS_CHROME_MANIFESTS_FILE_LIST = "ChromeML";
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
var MANIFESTS = [
|
||||
do_get_file("chrome/test/unit/data/test_bug401153.manifest")
|
||||
];
|
||||
|
||||
function ArrayEnumerator(array)
|
||||
{
|
||||
this.array = array;
|
||||
}
|
||||
|
||||
ArrayEnumerator.prototype = {
|
||||
pos: 0,
|
||||
|
||||
hasMoreElements: function() {
|
||||
return this.pos < this.array.length;
|
||||
},
|
||||
|
||||
getNext: function() {
|
||||
if (this.pos < this.array.length)
|
||||
return this.array[this.pos++];
|
||||
throw Components.results.NS_ERROR_FAILURE;
|
||||
},
|
||||
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsISimpleEnumerator)
|
||||
|| iid.equals(Ci.nsISupports))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
};
|
||||
|
||||
var ChromeProvider = {
|
||||
getFile: function(prop, persistent) {
|
||||
throw Components.results.NS_ERROR_FAILURE
|
||||
},
|
||||
|
||||
getFiles: function(prop) {
|
||||
if (prop == NS_CHROME_MANIFESTS_FILE_LIST) {
|
||||
return new ArrayEnumerator(MANIFESTS);
|
||||
}
|
||||
throw Components.results.NS_ERROR_FAILURE
|
||||
},
|
||||
|
||||
QueryInterface: function(iid) {
|
||||
if (iid.equals(Ci.nsIDirectoryServiceProvider)
|
||||
|| iid.equals(Ci.nsIDirectoryServiceProvider2)
|
||||
|| iid.equals(Ci.nsISupports))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
};
|
||||
var dirSvc = Cc["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Ci.nsIDirectoryService);
|
||||
dirSvc.registerProvider(ChromeProvider);
|
||||
|
||||
var XULAppInfo = {
|
||||
vendor: "Mozilla",
|
||||
name: "XPCShell",
|
||||
ID: "{39885e5f-f6b4-4e2a-87e5-6259ecf79011}",
|
||||
version: "5",
|
||||
appBuildID: "2007010101",
|
||||
platformVersion: "1.9",
|
||||
platformBuildID: "2007010101",
|
||||
inSafeMode: false,
|
||||
logConsoleErrors: true,
|
||||
OS: "XPCShell",
|
||||
XPCOMABI: "noarch-spidermonkey",
|
||||
|
||||
QueryInterface: function QueryInterface(iid) {
|
||||
if (iid.equals(Ci.nsIXULAppInfo)
|
||||
|| iid.equals(Ci.nsIXULRuntime)
|
||||
|| iid.equals(Ci.nsISupports))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
};
|
||||
|
||||
var XULAppInfoFactory = {
|
||||
createInstance: function (outer, iid) {
|
||||
if (outer != null)
|
||||
throw Components.results.NS_ERROR_NO_AGGREGATION;
|
||||
return XULAppInfo.QueryInterface(iid);
|
||||
}
|
||||
};
|
||||
var registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar);
|
||||
registrar.registerFactory(XULAPPINFO_CID, "XULAppInfo",
|
||||
XULAPPINFO_CONTRACTID, XULAppInfoFactory);
|
||||
|
||||
var gIOS = Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Ci.nsIIOService);
|
||||
var chromeReg = Cc["@mozilla.org/chrome/chrome-registry;1"]
|
||||
.getService(Ci.nsIChromeRegistry);
|
||||
chromeReg.checkForNewChrome();
|
||||
|
||||
var rph = gIOS.getProtocolHandler("resource")
|
||||
.QueryInterface(Ci.nsIResProtocolHandler);
|
||||
|
||||
function test_succeeded_mapping(namespace, target)
|
||||
{
|
||||
try {
|
||||
do_check_true(rph.hasSubstitution(namespace));
|
||||
var thistarget = target + "/test.js";
|
||||
var uri = gIOS.newURI("resource://" + namespace + "/test.js",
|
||||
null, null);
|
||||
do_check_eq(rph.resolveURI(uri), thistarget);
|
||||
}
|
||||
catch (ex) {
|
||||
do_throw(namespace);
|
||||
}
|
||||
}
|
||||
|
||||
function test_failed_mapping(namespace)
|
||||
{
|
||||
do_check_false(rph.hasSubstitution(namespace));
|
||||
}
|
||||
|
||||
function run_test()
|
||||
{
|
||||
var data = gIOS.newFileURI(do_get_file("chrome/test/unit/data")).spec;
|
||||
test_succeeded_mapping("test1", data + "test1");
|
||||
test_succeeded_mapping("test2", "http://www.mozilla.org");
|
||||
test_succeeded_mapping("test3", "jar:" + data + "test3.jar!/resources");
|
||||
test_failed_mapping("test4");
|
||||
test_succeeded_mapping("test5", data + "test5");
|
||||
}
|
||||
Reference in New Issue
Block a user