mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Merge mozilla-central into electrolysis.
This commit is contained in:
commit
83b97480d2
@ -408,6 +408,17 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
||||
eARIASelectable,
|
||||
eARIAReadonly
|
||||
},
|
||||
{
|
||||
"scrollbar",
|
||||
nsIAccessibleRole::ROLE_SCROLLBAR,
|
||||
kUseMapRole,
|
||||
eHasValueMinMax,
|
||||
eNoAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates,
|
||||
eARIAOrientation,
|
||||
eARIAReadonly
|
||||
},
|
||||
{
|
||||
"separator",
|
||||
nsIAccessibleRole::ROLE_SEPARATOR,
|
||||
@ -628,6 +639,11 @@ nsStateMapEntry nsARIAMap::gWAIStateMap[] = {
|
||||
nsStateMapEntry(&nsAccessibilityAtoms::aria_multiselectable, kBoolType, 0,
|
||||
nsIAccessibleStates::STATE_MULTISELECTABLE | nsIAccessibleStates::STATE_EXTSELECTABLE, 0),
|
||||
|
||||
// eARIAOrientation
|
||||
nsStateMapEntry(&nsAccessibilityAtoms::aria_orientation, eUseFirstState,
|
||||
"vertical", 0, nsIAccessibleStates::EXT_STATE_VERTICAL,
|
||||
"horizontal", 0, nsIAccessibleStates::EXT_STATE_HORIZONTAL),
|
||||
|
||||
// eARIAPressed
|
||||
nsStateMapEntry(&nsAccessibilityAtoms::aria_pressed, kMixedType,
|
||||
nsIAccessibleStates::STATE_CHECKABLE,
|
||||
@ -693,6 +709,7 @@ nsAttributeCharacteristics nsARIAMap::gWAIUnivAttrMap[] = {
|
||||
{&nsAccessibilityAtoms::aria_multiline, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
|
||||
{&nsAccessibilityAtoms::aria_multiselectable, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
|
||||
{&nsAccessibilityAtoms::aria_owns, ATTR_BYPASSOBJ },
|
||||
{&nsAccessibilityAtoms::aria_orientation, ATTR_VALTOKEN },
|
||||
{&nsAccessibilityAtoms::aria_pressed, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
|
||||
{&nsAccessibilityAtoms::aria_readonly, ATTR_BYPASSOBJ | ATTR_VALTOKEN },
|
||||
{&nsAccessibilityAtoms::aria_relevant, ATTR_BYPASSOBJ },
|
||||
@ -749,6 +766,26 @@ nsStateMapEntry::nsStateMapEntry(nsIAtom **aAttrName,
|
||||
{
|
||||
}
|
||||
|
||||
nsStateMapEntry::nsStateMapEntry(nsIAtom **aAttrName,
|
||||
EDefaultStateRule aDefaultStateRule,
|
||||
const char *aValue1,
|
||||
PRUint32 aState1, PRUint32 aExtraState1,
|
||||
const char *aValue2,
|
||||
PRUint32 aState2, PRUint32 aExtraState2,
|
||||
const char *aValue3,
|
||||
PRUint32 aState3, PRUint32 aExtraState3) :
|
||||
attributeName(aAttrName), isToken(PR_TRUE), permanentState(0),
|
||||
value1(aValue1), state1(aState1), extraState1(aExtraState1),
|
||||
value2(aValue2), state2(aState2), extraState2(aExtraState2),
|
||||
value3(aValue3), state3(aState3), extraState3(aExtraState3),
|
||||
defaultState(0), defaultExtraState(0), definedIfAbsent(PR_TRUE)
|
||||
{
|
||||
if (aDefaultStateRule == eUseFirstState) {
|
||||
defaultState = aState1;
|
||||
defaultExtraState = aExtraState1;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsStateMapEntry::MapToStates(nsIContent *aContent,
|
||||
PRUint32 *aState, PRUint32 *aExtraState,
|
||||
|
@ -157,6 +157,12 @@ enum eStateValueType
|
||||
kMixedType
|
||||
};
|
||||
|
||||
enum EDefaultStateRule
|
||||
{
|
||||
//eNoDefaultState,
|
||||
eUseFirstState
|
||||
};
|
||||
|
||||
/**
|
||||
* ID for state map entry, used in nsRoleMapEntry.
|
||||
*/
|
||||
@ -174,6 +180,7 @@ enum eStateMapEntryID
|
||||
eARIAInvalid,
|
||||
eARIAMultiline,
|
||||
eARIAMultiSelectable,
|
||||
eARIAOrientation,
|
||||
eARIAPressed,
|
||||
eARIAReadonly,
|
||||
eARIAReadonlyOrEditable,
|
||||
@ -207,6 +214,17 @@ public:
|
||||
const char *aValue3 = 0, PRUint32 aState3 = 0,
|
||||
PRUint32 aExtraState3 = 0);
|
||||
|
||||
/**
|
||||
* Used for ARIA attributes having enumerated values, and where a default
|
||||
* attribute state should be assumed when not supplied by the author.
|
||||
*/
|
||||
nsStateMapEntry(nsIAtom **aAttrName,
|
||||
EDefaultStateRule aDefaultStateRule,
|
||||
const char *aValue1, PRUint32 aState1, PRUint32 aExtraState1,
|
||||
const char *aValue2, PRUint32 aState2, PRUint32 aExtraState2,
|
||||
const char *aValue3 = 0, PRUint32 aState3 = 0,
|
||||
PRUint32 aExtraState3 = 0);
|
||||
|
||||
/**
|
||||
* Maps ARIA state map pointed by state map entry ID to accessible states.
|
||||
*
|
||||
|
@ -241,6 +241,7 @@ ACCESSIBILITY_ATOM(aria_level, "aria-level")
|
||||
ACCESSIBILITY_ATOM(aria_live, "aria-live")
|
||||
ACCESSIBILITY_ATOM(aria_multiline, "aria-multiline")
|
||||
ACCESSIBILITY_ATOM(aria_multiselectable, "aria-multiselectable")
|
||||
ACCESSIBILITY_ATOM(aria_orientation, "aria-orientation")
|
||||
ACCESSIBILITY_ATOM(aria_owns, "aria-owns")
|
||||
ACCESSIBILITY_ATOM(aria_posinset, "aria-posinset")
|
||||
ACCESSIBILITY_ATOM(aria_pressed, "aria-pressed")
|
||||
|
@ -79,6 +79,7 @@ const EXT_STATE_MULTI_LINE = nsIAccessibleStates.EXT_STATE_MULTI_LINE;
|
||||
const EXT_STATE_SINGLE_LINE = nsIAccessibleStates.EXT_STATE_SINGLE_LINE;
|
||||
const EXT_STATE_SUPPORTS_AUTOCOMPLETION =
|
||||
nsIAccessibleStates.EXT_STATE_SUPPORTS_AUTOCOMPLETION;
|
||||
const EXT_STATE_VERTICAL = nsIAccessibleStates.EXT_STATE_VERTICAL;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// OS detect
|
||||
|
@ -44,6 +44,7 @@ const ROLE_PUSHBUTTON = nsIAccessibleRole.ROLE_PUSHBUTTON;
|
||||
const ROLE_RADIOBUTTON = nsIAccessibleRole.ROLE_RADIOBUTTON;
|
||||
const ROLE_ROW = nsIAccessibleRole.ROLE_ROW;
|
||||
const ROLE_ROWHEADER = nsIAccessibleRole.ROLE_ROWHEADER;
|
||||
const ROLE_SCROLLBAR = nsIAccessibleRole.ROLE_SCROLLBAR;
|
||||
const ROLE_SECTION = nsIAccessibleRole.ROLE_SECTION;
|
||||
const ROLE_SEPARATOR = nsIAccessibleRole.ROLE_SEPARATOR;
|
||||
const ROLE_SLIDER = nsIAccessibleRole.ROLE_SLIDER;
|
||||
|
@ -3,6 +3,7 @@
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=481114
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=469688
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=529289
|
||||
-->
|
||||
<head>
|
||||
<title>Test weak ARIA roles</title>
|
||||
@ -63,6 +64,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=469688
|
||||
for (a in abstract_roles)
|
||||
testRole(abstract_roles[a], ROLE_SECTION);
|
||||
|
||||
// aria scrollbar
|
||||
testRole("scrollbar", ROLE_SCROLLBAR);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
@ -74,6 +77,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=469688
|
||||
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=481114">Mozilla Bug 481114</a>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=469688">Mozilla Bug 469688</a>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=529289">Mozilla Bug 529289</a>
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
@ -134,5 +139,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=469688
|
||||
<div role="section" id="section">section</div>
|
||||
<div role="sectionhead" id="sectionhead">sectionhead</div>
|
||||
|
||||
<!-- aria scrollbar -->
|
||||
<div role="scrollbar" id="scrollbar">scrollbar</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -66,6 +66,7 @@
|
||||
testValue("slider_vn", "5", 5, 0, 1000, 0);
|
||||
testValue("slider_vnvt", "plain", 0, 0, 5, 0);
|
||||
testValue("slider_vt", "hi", 0, 0, 3, 0);
|
||||
testValue("scrollbar", "5", 5, 0, 1000, 0);
|
||||
|
||||
// Test value change events
|
||||
gQueue = new eventQueue(nsIAccessibleEvent.EVENT_VALUE_CHANGE);
|
||||
@ -73,6 +74,7 @@
|
||||
gQueue.push(new changeValue("slider_vn", "6", undefined));
|
||||
gQueue.push(new changeValue("slider_vt", undefined, "hey!"));
|
||||
gQueue.push(new changeValue("slider_vnvt", "3", "sweet"));
|
||||
gQueue.push(new changeValue("scrollbar", "6", undefined));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
@ -89,6 +91,11 @@
|
||||
title=" Fire delayed value changed event for aria-valuetext changes">
|
||||
Mozilla Bug 478032
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=529289"
|
||||
title="We dont expose new aria role 'scrollbar' and property aria-orientation">
|
||||
Mozilla Bug 529289
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
@ -98,12 +105,16 @@
|
||||
|
||||
<!-- ARIA sliders -->
|
||||
<div id="slider_vn" role="slider" aria-valuenow="5"
|
||||
aria-valuemin="0" aria-valuemax="1000">slider</div>
|
||||
aria-valuemin="0" aria-valuemax="1000">slider</div>
|
||||
|
||||
<div id="slider_vt" role="slider" aria-valuetext="hi"
|
||||
aria-valuemin="0" aria-valuemax="3">greeting slider</div>
|
||||
aria-valuemin="0" aria-valuemax="3">greeting slider</div>
|
||||
|
||||
<div id="slider_vnvt" role="slider" aria-valuenow="0" aria-valuetext="plain"
|
||||
aria-valuemin="0" aria-valuemax="5">sweetness slider</div>
|
||||
aria-valuemin="0" aria-valuemax="5">sweetness slider</div>
|
||||
|
||||
<!-- ARIA scrollbar -->
|
||||
<div id="scrollbar" role="scrollbar" aria-valuenow="5"
|
||||
aria-valuemin="0" aria-valuemax="1000">slider</div>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -93,6 +93,11 @@
|
||||
testStates("aria_main_anchor", STATE_SELECTABLE);
|
||||
testStates("aria_navigation_anchor", STATE_SELECTABLE);
|
||||
|
||||
// scrollbar
|
||||
testStates("aria_scrollbar", 0, EXT_STATE_VERTICAL);
|
||||
testStates("aria_hscrollbar", 0, EXT_STATE_HORIZONTAL);
|
||||
testStates("aria_vscrollbar", 0, EXT_STATE_VERTICAL);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
@ -183,5 +188,9 @@
|
||||
<a id="aria_main_anchor" role="main" name="main_anchor">main</a>
|
||||
<a id="aria_navigation_anchor" role="navigation" name="nav_anchor">nav</a>
|
||||
|
||||
<!-- scrollbar -->
|
||||
<div id="aria_scrollbar" role="scrollbar">scrollbar</a>
|
||||
<div id="aria_hscrollbar" role="scrollbar" aria-orientation="horizontal">horizontal scrollbar</a>
|
||||
<div id="aria_vscrollbar" role="scrollbar" aria-orientation="vertical">vertical scrollbar</a>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -311,8 +311,13 @@ pref("browser.microsummary.updateGenerators", true);
|
||||
pref("browser.search.suggest.enabled", true);
|
||||
|
||||
pref("browser.sessionhistory.max_entries", 50);
|
||||
#ifndef WINCE
|
||||
pref("browser.history_expire_days", 180);
|
||||
pref("browser.history_expire_days_min", 90);
|
||||
#else
|
||||
pref("browser.history_expire_days", 90);
|
||||
pref("browser.history_expire_days_min", 45);
|
||||
#endif
|
||||
pref("browser.history_expire_sites", 40000);
|
||||
|
||||
// handle links targeting new windows
|
||||
|
@ -2292,7 +2292,7 @@ function SetPageProxyState(aState)
|
||||
gLastValidURLStr = gURLBar.value;
|
||||
gURLBar.addEventListener("input", UpdatePageProxyState, false);
|
||||
|
||||
PageProxySetIcon(gBrowser.selectedBrowser.mIconURL);
|
||||
PageProxySetIcon(gBrowser.getIcon());
|
||||
} else if (aState == "invalid") {
|
||||
gURLBar.removeEventListener("input", UpdatePageProxyState, false);
|
||||
PageProxyClearIcon();
|
||||
@ -3913,9 +3913,9 @@ var XULBrowserWindow = {
|
||||
}
|
||||
},
|
||||
|
||||
onLinkIconAvailable: function (aBrowser) {
|
||||
onLinkIconAvailable: function (aBrowser, aIconURL) {
|
||||
if (gProxyFavIcon && gBrowser.userTypedValue === null)
|
||||
PageProxySetIcon(aBrowser.mIconURL); // update the favicon in the URL bar
|
||||
PageProxySetIcon(aIconURL); // update the favicon in the URL bar
|
||||
},
|
||||
|
||||
onProgressChange: function (aWebProgress, aRequest,
|
||||
@ -3980,7 +3980,7 @@ var XULBrowserWindow = {
|
||||
if (aWebProgress.DOMWindow == content) {
|
||||
if (aRequest)
|
||||
this.endDocumentLoad(aRequest, aStatus);
|
||||
if (!gBrowser.mTabbedMode && !gBrowser.selectedBrowser.mIconURL)
|
||||
if (!gBrowser.mTabbedMode && !gBrowser.getIcon())
|
||||
gBrowser.useDefaultIcon(gBrowser.selectedTab);
|
||||
}
|
||||
}
|
||||
|
@ -700,7 +700,7 @@
|
||||
let p = this.mProgressListeners[i];
|
||||
if ('onLinkIconAvailable' in p)
|
||||
try {
|
||||
p.onLinkIconAvailable(browser);
|
||||
p.onLinkIconAvailable(browser, browser.mIconURL);
|
||||
} catch (e) {
|
||||
// don't inhibit other listeners
|
||||
Components.utils.reportError(e);
|
||||
@ -712,7 +712,7 @@
|
||||
let p = this.mTabsProgressListeners[i];
|
||||
if ('onLinkIconAvailable' in p)
|
||||
try {
|
||||
p.onLinkIconAvailable(browser);
|
||||
p.onLinkIconAvailable(browser, browser.mIconURL);
|
||||
} catch (e) {
|
||||
// don't inhibit other listeners
|
||||
Components.utils.reportError(e);
|
||||
@ -722,6 +722,16 @@
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="getIcon">
|
||||
<parameter name="aTab"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
let browser = aTab ? this.getBrowserForTab(aTab) : this.selectedBrowser;
|
||||
return browser.mIconURL;
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="updateIcon">
|
||||
<parameter name="aTab"/>
|
||||
<body>
|
||||
|
@ -76,7 +76,7 @@ function test() {
|
||||
}
|
||||
|
||||
is(newWindow.gBrowser.selectedTab.hasAttribute("busy"), true);
|
||||
is(newWindow.gBrowser.selectedTab.linkedBrowser.mIconURL,iconURLSpec);
|
||||
is(newWindow.gBrowser.getIcon(), iconURLSpec);
|
||||
newWindow.close();
|
||||
finish();
|
||||
}
|
||||
|
@ -316,6 +316,18 @@ BrowserGlue.prototype = {
|
||||
// profile shutdown handler (contains profile cleanup routines)
|
||||
_onProfileShutdown: function()
|
||||
{
|
||||
#ifdef WINCE
|
||||
// If there's a pending update, clear cache to free up disk space.
|
||||
try {
|
||||
let um = Cc["@mozilla.org/updates/update-manager;1"].
|
||||
getService(Ci.nsIUpdateManager);
|
||||
if (um.activeUpdate && um.activeUpdate.state == "pending") {
|
||||
let cacheService = Cc["@mozilla.org/network/cache-service;1"].
|
||||
getService(Ci.nsICacheService);
|
||||
cacheService.evictEntries(Ci.nsICache.STORE_ANYWHERE);
|
||||
}
|
||||
} catch (e) { }
|
||||
#endif
|
||||
this._shutdownPlaces();
|
||||
this._idleService.removeIdleObserver(this, BOOKMARKS_BACKUP_IDLE_TIME);
|
||||
this._isIdleObserver = false;
|
||||
|
@ -102,7 +102,6 @@ function test() {
|
||||
onSecurityChange: function() {},
|
||||
onStatusChange: function() {},
|
||||
onRefreshAttempted: function() {},
|
||||
onLinkIconAvailable: function() {},
|
||||
onStateChange: function(aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||
if (aStateFlags & (Ci.nsIWebProgressListener.STATE_STOP |
|
||||
Ci.nsIWebProgressListener.STATE_IS_WINDOW)) {
|
||||
|
@ -226,7 +226,7 @@ var gEngineManagerDialog = {
|
||||
|
||||
function onDragEngineStart(event) {
|
||||
var selectedIndex = gEngineView.selectedIndex;
|
||||
if (selectedIndex > 0) {
|
||||
if (selectedIndex >= 0) {
|
||||
event.dataTransfer.setData(ENGINE_FLAVOR, selectedIndex.toString());
|
||||
event.dataTransfer.effectAllowed = "move";
|
||||
}
|
||||
|
@ -443,7 +443,29 @@ function test() {
|
||||
newWin.BrowserTryToCloseWindow();
|
||||
newWin2.BrowserTryToCloseWindow();
|
||||
|
||||
browserWindowsCount([0, 1], "browser windows while running testOpenCloseRestoreFromPopup");
|
||||
|
||||
newWin = undoCloseWindow(0);
|
||||
newWin.addEventListener("load", function () {
|
||||
info(["testOpenCloseRestoreFromPopup: newWin loaded", newWin.closed, newWin.document]);
|
||||
var ds = newWin.delayedStartup;
|
||||
newWin.delayedStartup = function () {
|
||||
info(["testOpenCloseRestoreFromPopup: newWin delayedStartup", newWin.closed, newWin.document]);
|
||||
ds.apply(newWin, arguments);
|
||||
};
|
||||
}, false);
|
||||
newWin.addEventListener("unload", function () {
|
||||
info("testOpenCloseRestoreFromPopup: newWin unloaded");
|
||||
/*
|
||||
var data;
|
||||
try {
|
||||
data = Cc["@mozilla.org/browser/sessionstore;1"]
|
||||
.getService(Ci.nsISessionStore)
|
||||
.getWindowState(newWin);
|
||||
} catch (e) { }
|
||||
ok(!data, "getWindowState should not have data about newWin");
|
||||
*/
|
||||
}, false);
|
||||
|
||||
newWin2 = openDialog(location, "_blank", CHROME_FEATURES);
|
||||
newWin2.addEventListener("load", function() {
|
||||
@ -454,10 +476,14 @@ function test() {
|
||||
is(TEST_URLS.indexOf(newWin2.gBrowser.browsers[0].currentURI.spec), -1,
|
||||
"Did not restore, as undoCloseWindow() was last called (2)");
|
||||
|
||||
browserWindowsCount([2, 3], "browser windows while running testOpenCloseRestoreFromPopup");
|
||||
|
||||
// Cleanup
|
||||
newWin.close();
|
||||
newWin2.close();
|
||||
|
||||
browserWindowsCount([0, 1], "browser windows while running testOpenCloseRestoreFromPopup");
|
||||
|
||||
// Next please
|
||||
executeSoon(nextFn);
|
||||
});
|
||||
@ -536,7 +562,7 @@ function test() {
|
||||
browserWindowsCount([0, 1], "browser windows after testOpenCloseWindowAndPopup");
|
||||
testOpenCloseOnlyPopup(function () {
|
||||
browserWindowsCount([0, 1], "browser windows after testOpenCloseOnlyPopup");
|
||||
testOpenCloseRestoreFromPopup (function () {
|
||||
testOpenCloseRestoreFromPopup(function () {
|
||||
browserWindowsCount([0, 1], "browser windows after testOpenCloseRestoreFromPopup");
|
||||
testNotificationCount(function () {
|
||||
cleanupTestsuite();
|
||||
|
@ -341,7 +341,7 @@ var WinTaskbarJumpList =
|
||||
createInstance(Ci.nsILocalHandlerApp);
|
||||
handlerApp.executable = file;
|
||||
// handlers default to the leaf name if a name is not specified
|
||||
if (name.length != 0)
|
||||
if (name && name.length != 0)
|
||||
handlerApp.name = name;
|
||||
handlerApp.detailedDescription = description;
|
||||
handlerApp.appendParameter(args);
|
||||
|
@ -517,9 +517,9 @@ TabWindow.prototype = {
|
||||
},
|
||||
onStatusChange: function () {
|
||||
},
|
||||
onLinkIconAvailable: function (aBrowser) {
|
||||
onLinkIconAvailable: function (aBrowser, aIconURL) {
|
||||
let self = this;
|
||||
getFaviconAsImage(aBrowser.mIconURL, function (img) {
|
||||
getFaviconAsImage(aIconURL, function (img) {
|
||||
let index = self.tabbrowser.browsers.indexOf(aBrowser);
|
||||
// Only add it if we've found the index. The tab could have closed!
|
||||
if (index != -1)
|
||||
|
@ -90,7 +90,7 @@
|
||||
#elifdef XP_OS2
|
||||
@BINPATH@/plugins/npnulos2.dll
|
||||
#endif
|
||||
@BINPATH@/@DLL_PREFIX@sqlite3@DLL_SUFFIX@
|
||||
@BINPATH@/@DLL_PREFIX@mozsqlite3@DLL_SUFFIX@
|
||||
@BINPATH@/README.txt
|
||||
@BINPATH@/LICENSE
|
||||
@BINPATH@/blocklist.xml
|
||||
|
@ -843,4 +843,5 @@ components/brwsrcmp.dll
|
||||
components/nsUpdateService.js
|
||||
components/nsUpdateServiceStub.js
|
||||
#endif
|
||||
@DLL_PREFIX@sqlite3@DLL_SUFFIX@
|
||||
old-homepage-default.properties
|
||||
|
@ -74,7 +74,7 @@ _LEAKTEST_DIR = $(DEPTH)/_leaktest
|
||||
|
||||
_LEAKTEST_FILES = \
|
||||
automation.py \
|
||||
$(CURDIR)/automationutils.py \
|
||||
automationutils.py \
|
||||
leaktest.py \
|
||||
bloatcycle.html \
|
||||
$(topsrcdir)/build/pgo/server-locations.txt \
|
||||
|
@ -74,11 +74,6 @@ else
|
||||
AUTOMATION_PPARGS += -DCRASHREPORTER=0
|
||||
endif
|
||||
|
||||
$(CURDIR)/automationutils.py: $(MOZILLA_DIR)/build/automationutils.py
|
||||
$(INSTALL) $< .
|
||||
|
||||
automation.py: $(MOZILLA_DIR)/build/automation.py.in $(MOZILLA_DIR)/build/automation-build.mk $(CURDIR)/automationutils.py
|
||||
automation.py: $(MOZILLA_DIR)/build/automation.py.in $(MOZILLA_DIR)/build/automation-build.mk
|
||||
$(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py \
|
||||
$(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $< > $@
|
||||
|
||||
GARBAGE += automation.py $(CURDIR)/automationutils.py
|
||||
|
@ -59,7 +59,7 @@ include $(topsrcdir)/build/automation-build.mk
|
||||
|
||||
_PGO_FILES = \
|
||||
automation.py \
|
||||
$(CURDIR)/automationutils.py \
|
||||
$(topsrcdir)/build/automationutils.py \
|
||||
profileserver.py \
|
||||
genpgocert.py \
|
||||
index.html \
|
||||
|
@ -6182,7 +6182,7 @@ MOZ_NATIVE_SQLITE= )
|
||||
if test -z "$MOZ_NATIVE_SQLITE"
|
||||
then
|
||||
SQLITE_CFLAGS=
|
||||
SQLITE_LIBS='$(call EXPAND_LIBNAME_PATH,sqlite3,$(DIST)/lib)'
|
||||
SQLITE_LIBS='$(call EXPAND_LIBNAME_PATH,mozsqlite3,$(DIST)/lib)'
|
||||
else
|
||||
PKG_CHECK_MODULES(SQLITE, sqlite3 >= $SQLITE_VERSION)
|
||||
fi
|
||||
|
@ -245,7 +245,13 @@ nsCrossSiteListenerProxy::CheckRequestApproved(nsIRequest* aRequest,
|
||||
PRBool succeeded;
|
||||
rv = http->GetRequestSucceeded(&succeeded);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(succeeded, NS_ERROR_DOM_BAD_URI);
|
||||
if (!succeeded) {
|
||||
PRUint32 responseStatus;
|
||||
rv = http->GetResponseStatus(&responseStatus);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(mAllowedHTTPErrors.Contains(responseStatus),
|
||||
NS_ERROR_DOM_BAD_URI);
|
||||
}
|
||||
}
|
||||
|
||||
// Check the Access-Control-Allow-Origin header
|
||||
|
@ -81,6 +81,11 @@ public:
|
||||
// Must be called at startup.
|
||||
static void Startup();
|
||||
|
||||
void AllowHTTPResult(PRUint32 aResultCode)
|
||||
{
|
||||
mAllowedHTTPErrors.AppendElement(aResultCode);
|
||||
}
|
||||
|
||||
private:
|
||||
nsresult UpdateChannel(nsIChannel* aChannel);
|
||||
nsresult CheckRequestApproved(nsIRequest* aRequest, PRBool aIsRedirect);
|
||||
@ -94,6 +99,7 @@ private:
|
||||
PRBool mIsPreflight;
|
||||
nsCString mPreflightMethod;
|
||||
nsTArray<nsCString> mPreflightHeaders;
|
||||
nsTArray<PRUint32> mAllowedHTTPErrors;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -631,13 +631,16 @@ nsresult nsHTMLMediaElement::LoadResource(nsIURI* aURI)
|
||||
|
||||
nsCOMPtr<nsIStreamListener> listener;
|
||||
if (ShouldCheckAllowOrigin()) {
|
||||
listener = new nsCrossSiteListenerProxy(loadListener,
|
||||
NodePrincipal(),
|
||||
mChannel,
|
||||
PR_FALSE,
|
||||
&rv);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
if (!listener) return NS_ERROR_OUT_OF_MEMORY;
|
||||
nsCrossSiteListenerProxy* crossSiteListener =
|
||||
new nsCrossSiteListenerProxy(loadListener,
|
||||
NodePrincipal(),
|
||||
mChannel,
|
||||
PR_FALSE,
|
||||
&rv);
|
||||
listener = crossSiteListener;
|
||||
NS_ENSURE_TRUE(crossSiteListener, NS_ERROR_OUT_OF_MEMORY);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
crossSiteListener->AllowHTTPResult(HTTP_REQUESTED_RANGE_NOT_SATISFIABLE_CODE);
|
||||
} else {
|
||||
rv = nsContentUtils::GetSecurityManager()->
|
||||
CheckLoadURIWithPrincipal(NodePrincipal(),
|
||||
|
@ -59,7 +59,6 @@
|
||||
|
||||
#define HTTP_OK_CODE 200
|
||||
#define HTTP_PARTIAL_RESPONSE_CODE 206
|
||||
#define HTTP_REQUESTED_RANGE_NOT_SATISFIABLE_CODE 416
|
||||
|
||||
using mozilla::TimeStamp;
|
||||
|
||||
@ -425,13 +424,16 @@ nsresult nsMediaChannelStream::OpenChannel(nsIStreamListener** aStreamListener)
|
||||
NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);
|
||||
if (element->ShouldCheckAllowOrigin()) {
|
||||
nsresult rv;
|
||||
listener = new nsCrossSiteListenerProxy(mListener,
|
||||
element->NodePrincipal(),
|
||||
mChannel,
|
||||
PR_FALSE,
|
||||
&rv);
|
||||
NS_ENSURE_TRUE(listener, NS_ERROR_OUT_OF_MEMORY);
|
||||
nsCrossSiteListenerProxy* crossSiteListener =
|
||||
new nsCrossSiteListenerProxy(mListener,
|
||||
element->NodePrincipal(),
|
||||
mChannel,
|
||||
PR_FALSE,
|
||||
&rv);
|
||||
listener = crossSiteListener;
|
||||
NS_ENSURE_TRUE(crossSiteListener, NS_ERROR_OUT_OF_MEMORY);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
crossSiteListener->AllowHTTPResult(HTTP_REQUESTED_RANGE_NOT_SATISFIABLE_CODE);
|
||||
} else {
|
||||
nsresult rv = nsContentUtils::GetSecurityManager()->
|
||||
CheckLoadURIWithPrincipal(element->NodePrincipal(),
|
||||
|
@ -53,6 +53,8 @@
|
||||
// done rather than a byte range request.
|
||||
#define SEEK_VS_READ_THRESHOLD (32*1024)
|
||||
|
||||
#define HTTP_REQUESTED_RANGE_NOT_SATISFIABLE_CODE 416
|
||||
|
||||
class nsMediaDecoder;
|
||||
|
||||
/**
|
||||
|
@ -179,6 +179,7 @@ ifdef MOZ_OGG
|
||||
_TEST_FILES += \
|
||||
dynamic_redirect.sjs \
|
||||
file_access_controls.html \
|
||||
test_access_control.html \
|
||||
test_bug448534.html \
|
||||
test_bug468190.html \
|
||||
test_bug486646.html \
|
||||
@ -227,7 +228,6 @@ ifneq ($(OS_ARCH),WINNT)
|
||||
# figure out the random failures. See bug 475369 and bug 526323
|
||||
_TEST_FILES += \
|
||||
test_timeupdate3.html \
|
||||
test_access_control.html \
|
||||
$(NULL)
|
||||
endif
|
||||
endif
|
||||
|
@ -15,7 +15,7 @@ var gTests = [
|
||||
},{
|
||||
// Test 1
|
||||
url: "redirect.sjs?http://example.com/tests/content/media/test/320x240.allow-origin.ogv",
|
||||
result: "loaded",
|
||||
result: "loadeddata",
|
||||
description: "Can load when redirected to different domain with allow-origin",
|
||||
},{
|
||||
// Test 2
|
||||
@ -25,17 +25,17 @@ var gTests = [
|
||||
},{
|
||||
// Test 3
|
||||
url: "redirect.sjs?http://test1.example.org/tests/content/media/test/320x240.allow-origin.ogv",
|
||||
result: "loaded",
|
||||
result: "loadeddata",
|
||||
description: "Can load when redirected to subdomain with allow-origin",
|
||||
},{
|
||||
// Test 4
|
||||
url: "redirect.sjs?http://example.org/tests/content/media/test/320x240.ogv",
|
||||
result: "loaded",
|
||||
result: "loadeddata",
|
||||
description: "Can load when redirected to same domain",
|
||||
},{
|
||||
// Test 5
|
||||
url: "http://example.org/tests/content/media/test/320x240.ogv",
|
||||
result: "loaded",
|
||||
result: "loadeddata",
|
||||
description: "Can load from same domain"
|
||||
},{
|
||||
// Test 6
|
||||
@ -45,7 +45,7 @@ var gTests = [
|
||||
},{
|
||||
// Test 7
|
||||
url: "http://example.org:8000/tests/content/media/test/320x240.allow-origin.ogv",
|
||||
result: "loaded",
|
||||
result: "loadeddata",
|
||||
description: "Can load from different port on same domain with allow-origin",
|
||||
},{
|
||||
// Test 8
|
||||
@ -55,12 +55,12 @@ var gTests = [
|
||||
},{
|
||||
// Test 9
|
||||
url: "http://example.com/tests/content/media/test/320x240.allow-origin.ogv",
|
||||
result: "loaded",
|
||||
result: "loadeddata",
|
||||
description: "Can load cross domain with allow-origin",
|
||||
},{
|
||||
// Test 10
|
||||
url: "http://test1.example.org/tests/content/media/test/320x240.allow-origin.ogv",
|
||||
result: "loaded",
|
||||
result: "loadeddata",
|
||||
description: "Can load from subdomain with allow-origin",
|
||||
},{
|
||||
// Test 11
|
||||
@ -71,24 +71,25 @@ var gTests = [
|
||||
];
|
||||
|
||||
var gTestNum = 0;
|
||||
var gExpectedResult = null;
|
||||
var gTestDescription = null;
|
||||
var gVideo = null;
|
||||
var gTestedRemoved = false;
|
||||
var gOldPref;
|
||||
|
||||
function result(code) {
|
||||
//dump((gTestNum - 1) + ": " + code + "\n");
|
||||
function eventHandler(event) {
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
opener.is(code, gExpectedResult, gTestDescription);
|
||||
//dump((gTestNum - 1) + ": " + event.type + "\n");
|
||||
var video = event.target;
|
||||
opener.is(event.type, video.expectedResult, video.testDescription +
|
||||
(gTestedRemoved ? " (element not in document)" : " (element in document)"));
|
||||
// Make sure any extra events cause an error
|
||||
video.expectedResult = "<none>";
|
||||
nextTest();
|
||||
}
|
||||
|
||||
function createVideo() {
|
||||
var v = document.createElement('video');
|
||||
v.addEventListener('loadeddata', function(){result('loaded');}, false);
|
||||
v.addEventListener('error', function(){result('error');}, false);
|
||||
v.id = 'video';
|
||||
v.addEventListener('loadeddata', eventHandler, false);
|
||||
v.addEventListener('error', eventHandler, false);
|
||||
return v;
|
||||
}
|
||||
|
||||
@ -112,7 +113,6 @@ function load() {
|
||||
|
||||
function nextTest() {
|
||||
//dump("nextTest() called, gTestNum="+gTestNum+" gTestedRemoved="+gTestedRemoved+"\n");
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
if (gTestNum == gTests.length) {
|
||||
//dump("gTestNum == gTests.length\n");
|
||||
if (!gTestedRemoved) {
|
||||
@ -126,15 +126,15 @@ function nextTest() {
|
||||
return;
|
||||
}
|
||||
}
|
||||
gExpectedResult = gTests[gTestNum].result;
|
||||
gTestDescription = gTests[gTestNum].description;
|
||||
//dump("Starting test " + gTestNum + " at " + gTests[gTestNum].url + " expecting:" + gExpectedResult + "\n");
|
||||
|
||||
if (gVideo && gVideo.parentNode)
|
||||
gVideo.parentNode.removeChild(gVideo);
|
||||
|
||||
gVideo = createVideo();
|
||||
gVideo.expectedResult = gTests[gTestNum].result;
|
||||
gVideo.testDescription = gTests[gTestNum].description;
|
||||
gVideo.src = gTests[gTestNum].url;
|
||||
//dump("Starting test " + gTestNum + " at " + gVideo.src + " expecting:" + gVideo.expectedResult + "\n");
|
||||
if (!gTestedRemoved) {
|
||||
document.body.appendChild(gVideo);
|
||||
// Will cause load() to be invoked.
|
||||
|
@ -1870,9 +1870,11 @@ nsXULTemplateBuilder::CompileTemplate(nsIContent* aTemplate,
|
||||
getter_AddRefs(action));
|
||||
|
||||
if (action){
|
||||
nsCOMPtr<nsIAtom> memberVariable;
|
||||
DetermineMemberVariable(action, getter_AddRefs(memberVariable));
|
||||
if (! memberVariable) continue;
|
||||
nsCOMPtr<nsIAtom> memberVariable = mMemberVariable;
|
||||
if (!memberVariable) {
|
||||
memberVariable = DetermineMemberVariable(action);
|
||||
if (!memberVariable) continue;
|
||||
}
|
||||
|
||||
if (hasQuery) {
|
||||
nsCOMPtr<nsIAtom> tag;
|
||||
@ -1994,9 +1996,11 @@ nsXULTemplateBuilder::CompileTemplate(nsIContent* aTemplate,
|
||||
if (tag)
|
||||
aQuerySet->SetTag(tag);
|
||||
|
||||
nsCOMPtr<nsIAtom> memberVariable;
|
||||
DetermineMemberVariable(rulenode, getter_AddRefs(memberVariable));
|
||||
if (! memberVariable) continue;
|
||||
nsCOMPtr<nsIAtom> memberVariable = mMemberVariable;
|
||||
if (!memberVariable) {
|
||||
memberVariable = DetermineMemberVariable(rulenode);
|
||||
if (!memberVariable) continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNode> query(do_QueryInterface(aQuerySet->mQueryNode));
|
||||
|
||||
@ -2077,53 +2081,26 @@ nsXULTemplateBuilder::CompileExtendedQuery(nsIContent* aRuleElement,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXULTemplateBuilder::DetermineMemberVariable(nsIContent* aActionElement,
|
||||
nsIAtom** aMemberVariable)
|
||||
already_AddRefed<nsIAtom>
|
||||
nsXULTemplateBuilder::DetermineMemberVariable(nsIContent* aElement)
|
||||
{
|
||||
// If the member variable hasn't already been specified, then
|
||||
// grovel over <action> to find it. We'll use the first one
|
||||
// that we find in a breadth-first search.
|
||||
// recursively iterate over the children looking for an element
|
||||
// with uri="?..."
|
||||
for (nsINode::ChildIterator iter(aElement); !iter.IsDone(); iter.Next()) {
|
||||
nsAutoString uri;
|
||||
nsIContent *child = iter;
|
||||
child->GetAttr(kNameSpaceID_None, nsGkAtoms::uri, uri);
|
||||
if (!uri.IsEmpty() && uri[0] == PRUnichar('?')) {
|
||||
return NS_NewAtom(uri);
|
||||
}
|
||||
|
||||
if (mMemberVariable) {
|
||||
*aMemberVariable = mMemberVariable;
|
||||
NS_IF_ADDREF(*aMemberVariable);
|
||||
}
|
||||
else {
|
||||
*aMemberVariable = nsnull;
|
||||
|
||||
nsCOMArray<nsIContent> unvisited;
|
||||
|
||||
if (!unvisited.AppendObject(aActionElement))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
while (unvisited.Count()) {
|
||||
nsIContent* next = unvisited[0];
|
||||
unvisited.RemoveObjectAt(0);
|
||||
|
||||
nsAutoString uri;
|
||||
next->GetAttr(kNameSpaceID_None, nsGkAtoms::uri, uri);
|
||||
|
||||
if (!uri.IsEmpty() && uri[0] == PRUnichar('?')) {
|
||||
// Found it.
|
||||
*aMemberVariable = NS_NewAtom(uri);
|
||||
break;
|
||||
}
|
||||
|
||||
// otherwise, append the children to the unvisited list: this
|
||||
// results in a breadth-first search.
|
||||
PRUint32 count = next->GetChildCount();
|
||||
|
||||
for (PRUint32 i = 0; i < count; ++i) {
|
||||
nsIContent *child = next->GetChildAt(i);
|
||||
|
||||
if (!unvisited.AppendObject(child))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
nsCOMPtr<nsIAtom> result = DetermineMemberVariable(child);
|
||||
if (result) {
|
||||
return result.forget();
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -212,8 +212,7 @@ public:
|
||||
* Determine the member variable from inside an action body. It will be
|
||||
* the value of the uri attribute on a node.
|
||||
*/
|
||||
nsresult
|
||||
DetermineMemberVariable(nsIContent* aActionElement, nsIAtom** aMemberVariable);
|
||||
already_AddRefed<nsIAtom> DetermineMemberVariable(nsIContent* aElement);
|
||||
|
||||
/**
|
||||
* Compile a simple query. A simple query is one that doesn't have a
|
||||
|
@ -46,7 +46,7 @@ VPATH = @srcdir@
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = sqlite3
|
||||
LIBRARY_NAME = sqlite3
|
||||
LIBRARY_NAME = mozsqlite3
|
||||
FORCE_SHARED_LIB = 1
|
||||
VISIBILITY_FLAGS =
|
||||
LIB_IS_C_ONLY = 1
|
||||
|
@ -33,7 +33,7 @@
|
||||
;
|
||||
; ***** END LICENSE BLOCK *****
|
||||
|
||||
LIBRARY sqlite3.dll
|
||||
LIBRARY mozsqlite3.dll
|
||||
|
||||
EXPORTS
|
||||
sqlite3_aggregate_context
|
||||
|
@ -63,7 +63,7 @@
|
||||
toolkit/components/places/src/nsFaviconService.h should be updated. -->
|
||||
<link rel="icon" type="image/png" id="favicon" href="chrome://global/skin/icons/warning-16.png"/>
|
||||
|
||||
<script type="application/x-javascript"><![CDATA[
|
||||
<script type="application/javascript"><![CDATA[
|
||||
// Error url MUST be formatted like this:
|
||||
// moz-neterror:page?e=error&u=url&d=desc
|
||||
//
|
||||
@ -376,7 +376,7 @@
|
||||
- an onload handler. This is because error pages are loaded as
|
||||
- LOAD_BACKGROUND, which means that onload handlers will not be executed.
|
||||
-->
|
||||
<script type="application/x-javascript">initPage();</script>
|
||||
<script type="application/javascript">initPage();</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -419,6 +419,7 @@ public:
|
||||
NPError ShowNativeContextMenu(NPMenu* menu, void* event);
|
||||
NPBool ConvertPoint(double sourceX, double sourceY, NPCoordinateSpace sourceSpace,
|
||||
double *destX, double *destY, NPCoordinateSpace destSpace);
|
||||
void SendIdleEvent();
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(nsDummyJavaPluginOwner)
|
||||
|
||||
@ -563,6 +564,11 @@ nsDummyJavaPluginOwner::SetEventModel(PRInt32 eventModel)
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
void
|
||||
nsDummyJavaPluginOwner::SendIdleEvent()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* An indirect observer object that means we don't have to implement nsIObserver
|
||||
* on nsGlobalWindow, where any script could see it.
|
||||
|
@ -1,6 +1,10 @@
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
let secMan = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
|
||||
.getService(Components.interfaces
|
||||
.nsIScriptSecurityManager);
|
||||
|
||||
let fm = Components.classes["@mozilla.org/focus-manager;1"]
|
||||
.getService(Components.interfaces.nsIFocusManager);
|
||||
|
||||
@ -136,6 +140,32 @@ function test() {
|
||||
return;
|
||||
}
|
||||
|
||||
// XXX puts some useful information for bug 534420
|
||||
let activeWindow = fm.activeWindow;
|
||||
let focusedWindow = fm.focusedWindow;
|
||||
ok(activeWindow, "We're not active");
|
||||
ok(focusedWindow, "There is no focused window");
|
||||
is(activeWindow, window.top, "our window isn't active");
|
||||
let searchbar = BrowserSearch.searchBar;
|
||||
let focusedElement = fm.focusedElement;
|
||||
if (searchbar) {
|
||||
let principal = searchbar.nodePrincipal;
|
||||
ok(principal, "principal is null");
|
||||
info("search bar: tagName=" + searchbar.tagName + " id=" + searchbar.id);
|
||||
ok(secMan.isSystemPrincipal(principal), "search bar isn't chrome");
|
||||
} else {
|
||||
info("search bar is NULL!!");
|
||||
}
|
||||
if (focusedElement) {
|
||||
let principal = focusedElement.nodePrincipal;
|
||||
ok(principal, "principal is null");
|
||||
info("focusedElement: tagName=" + focusedElement.tagName +
|
||||
" id=" + focusedElement.id);
|
||||
ok(secMan.isSystemPrincipal(principal), "focusedElement isn't chrome");
|
||||
} else {
|
||||
info("focusedElement is NULL!!");
|
||||
}
|
||||
|
||||
// The contents shouldn't be able to steal the focus from chrome.
|
||||
|
||||
// in foreground tab
|
||||
|
@ -315,6 +315,11 @@ nsAuthSSPI::GetNextToken(const void *inToken,
|
||||
|
||||
LOG(("entering nsAuthSSPI::GetNextToken()\n"));
|
||||
|
||||
if (!mCtxt.dwLower && !mCtxt.dwUpper) {
|
||||
LOG(("nsAuthSSPI::GetNextToken(), not initialized. exiting."));
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
if (mServiceFlags & REQ_DELEGATE)
|
||||
ctxReq |= ISC_REQ_DELEGATE;
|
||||
if (mServiceFlags & REQ_MUTUAL_AUTH)
|
||||
|
89
extensions/cookie/test/unit/test_eviction.js
Normal file
89
extensions/cookie/test/unit/test_eviction.js
Normal file
@ -0,0 +1,89 @@
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
|
||||
function run_test()
|
||||
{
|
||||
var cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService);
|
||||
var cm = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager2);
|
||||
var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
|
||||
var prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
|
||||
|
||||
// twiddle prefs to convenient values for this test
|
||||
prefs.setIntPref("network.cookie.purgeAge", 1);
|
||||
prefs.setIntPref("network.cookie.maxNumber", 1000);
|
||||
|
||||
// eviction is performed based on two limits: when the total number of cookies
|
||||
// exceeds maxNumber + 10% (1100), and when cookies are older than purgeAge
|
||||
// (1 second). purging is done when both conditions are satisfied, and only
|
||||
// those cookies are purged.
|
||||
|
||||
// we test the following cases of eviction:
|
||||
// 1) excess and age are satisfied, but only some of the excess are old enough
|
||||
// to be purged.
|
||||
do_check_eq(testEviction(cm, 1101, 2, 50, 1051), 1051);
|
||||
|
||||
// 2) excess and age are satisfied, and all of the excess are old enough
|
||||
// to be purged.
|
||||
do_check_eq(testEviction(cm, 1101, 2, 100, 1001), 1001);
|
||||
|
||||
// 3) excess and age are satisfied, and more than the excess are old enough
|
||||
// to be purged.
|
||||
do_check_eq(testEviction(cm, 1101, 2, 500, 1001), 1001);
|
||||
|
||||
// 4) excess but not age are satisfied.
|
||||
do_check_eq(testEviction(cm, 2000, 0, 0, 2000), 2000);
|
||||
|
||||
// 5) age but not excess are satisfied.
|
||||
do_check_eq(testEviction(cm, 1100, 2, 200, 1100), 1100);
|
||||
|
||||
cm.removeAll();
|
||||
|
||||
// reset prefs to defaults
|
||||
prefs.setIntPref("network.cookie.purgeAge", 30 * 24 * 60 * 60);
|
||||
prefs.setIntPref("network.cookie.maxNumber", 2000);
|
||||
}
|
||||
|
||||
// test that cookies are evicted by order of lastAccessed time, if both the limit
|
||||
// on total cookies (maxNumber + 10%) and the purge age are exceeded
|
||||
function
|
||||
testEviction(aCM, aNumberTotal, aSleepDuration, aNumberOld, aNumberToExpect)
|
||||
{
|
||||
aCM.removeAll();
|
||||
var expiry = (Date.now() + 1e6) * 1000;
|
||||
|
||||
var i;
|
||||
for (i = 0; i < aNumberTotal; ++i) {
|
||||
var host = "eviction." + i + ".tests";
|
||||
aCM.add(host, "", "test", "eviction", false, false, false, expiry);
|
||||
|
||||
if ((i == aNumberOld - 1) && aSleepDuration) {
|
||||
// sleep a while, to make sure the first batch of cookies is older than
|
||||
// the second (timer resolution varies on different platforms).
|
||||
sleep(aSleepDuration * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
var enumerator = aCM.enumerator;
|
||||
|
||||
i = 0;
|
||||
while (enumerator.hasMoreElements()) {
|
||||
var cookie = enumerator.getNext().QueryInterface(Ci.nsICookie2);
|
||||
++i;
|
||||
|
||||
if (aNumberTotal != aNumberToExpect) {
|
||||
// make sure the cookie is one of the batch we expect was purged.
|
||||
var hostNumber = new Number(cookie.rawHost.split(".")[1]);
|
||||
if (hostNumber < (aNumberOld - aNumberToExpect)) break;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
// delay for a number of milliseconds
|
||||
function sleep(delay)
|
||||
{
|
||||
var start = Date.now();
|
||||
while (Date.now() < start + delay);
|
||||
}
|
||||
|
@ -68,7 +68,6 @@ var reporterListener = {
|
||||
onProgressChange: function() { },
|
||||
onStatusChange: function() { },
|
||||
onSecurityChange: function() { },
|
||||
onLinkIconAvailable: function() { },
|
||||
onProgressChange64: function() { },
|
||||
onRefreshAttempted: function() { return true; }
|
||||
}
|
||||
|
@ -646,11 +646,12 @@ nsThebesDeviceContext::SetDPI()
|
||||
break;
|
||||
#ifdef XP_WIN
|
||||
case gfxASurface::SurfaceTypeWin32:
|
||||
case gfxASurface::SurfaceTypeWin32Printing:
|
||||
case gfxASurface::SurfaceTypeWin32Printing: {
|
||||
PRInt32 OSVal = GetDeviceCaps(GetPrintHDC(), LOGPIXELSY);
|
||||
dpi = 144;
|
||||
mPrintingScale = float(OSVal) / dpi;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef XP_OS2
|
||||
case gfxASurface::SurfaceTypeOS2:
|
||||
@ -659,6 +660,9 @@ nsThebesDeviceContext::SetDPI()
|
||||
dpi = lDPI;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
NS_NOTREACHED("Unexpected printing surface type");
|
||||
break;
|
||||
}
|
||||
dotsArePixels = PR_FALSE;
|
||||
} else {
|
||||
|
@ -63,7 +63,11 @@ public:
|
||||
// this is in points!
|
||||
const gfxSize& GetSize() const { return mSize; }
|
||||
|
||||
virtual PRInt32 GetDefaultContextFlags() const { return gfxContext::FLAG_DISABLE_SNAPPING; }
|
||||
virtual PRInt32 GetDefaultContextFlags() const
|
||||
{
|
||||
return gfxContext::FLAG_SIMPLIFY_OPERATORS |
|
||||
gfxContext::FLAG_DISABLE_SNAPPING;
|
||||
}
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIOutputStream> mStream;
|
||||
|
@ -63,7 +63,11 @@ public:
|
||||
// this is in points!
|
||||
const gfxSize& GetSize() const { return mSize; }
|
||||
|
||||
virtual PRInt32 GetDefaultContextFlags() const { return gfxContext::FLAG_DISABLE_SNAPPING; }
|
||||
virtual PRInt32 GetDefaultContextFlags() const
|
||||
{
|
||||
return gfxContext::FLAG_SIMPLIFY_OPERATORS |
|
||||
gfxContext::FLAG_DISABLE_SNAPPING;
|
||||
}
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIOutputStream> mStream;
|
||||
|
@ -70,7 +70,9 @@ public:
|
||||
ATSFontRef GetFontRef();
|
||||
nsresult ReadCMAP();
|
||||
|
||||
#ifndef __LP64__
|
||||
PRBool UseLiGothicAtsuiHack() { return mUseLiGothicAtsuiHack; }
|
||||
#endif
|
||||
|
||||
protected:
|
||||
// for use with data fonts
|
||||
@ -82,7 +84,9 @@ protected:
|
||||
|
||||
ATSFontRef mATSFontRef;
|
||||
PRPackedBool mATSFontRefInitialized;
|
||||
#ifndef __LP64__
|
||||
PRPackedBool mUseLiGothicAtsuiHack;
|
||||
#endif
|
||||
};
|
||||
|
||||
class gfxMacPlatformFontList : public gfxPlatformFontList {
|
||||
|
@ -117,8 +117,10 @@ MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName,
|
||||
PRBool aIsStandardFace)
|
||||
: gfxFontEntry(aPostscriptName, aFamily, aIsStandardFace),
|
||||
mATSFontRef(0),
|
||||
mATSFontRefInitialized(PR_FALSE),
|
||||
mUseLiGothicAtsuiHack(PR_FALSE)
|
||||
mATSFontRefInitialized(PR_FALSE)
|
||||
#ifndef __LP64__
|
||||
, mUseLiGothicAtsuiHack(PR_FALSE)
|
||||
#endif
|
||||
{
|
||||
mWeight = aWeight;
|
||||
}
|
||||
@ -128,8 +130,10 @@ MacOSFontEntry::MacOSFontEntry(const nsAString& aPostscriptName, ATSFontRef aFon
|
||||
gfxUserFontData *aUserFontData)
|
||||
: gfxFontEntry(aPostscriptName),
|
||||
mATSFontRef(aFontRef),
|
||||
mATSFontRefInitialized(PR_TRUE),
|
||||
mUseLiGothicAtsuiHack(PR_FALSE)
|
||||
mATSFontRefInitialized(PR_TRUE)
|
||||
#ifndef __LP64__
|
||||
, mUseLiGothicAtsuiHack(PR_FALSE)
|
||||
#endif
|
||||
{
|
||||
// xxx - stretch is basically ignored for now
|
||||
|
||||
@ -265,6 +269,8 @@ MacOSFontEntry::ReadCMAP()
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef __LP64__ /* ATSUI not available on 64-bit */
|
||||
|
||||
if ((gfxPlatformMac::GetPlatform()->OSXVersion() &
|
||||
MAC_OS_X_MAJOR_VERSION_MASK) == MAC_OS_X_VERSION_10_6_HEX) {
|
||||
// even ruder hack - LiGothic font on 10.6 has a bad glyph for U+775B
|
||||
@ -281,6 +287,8 @@ MacOSFontEntry::ReadCMAP()
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* not __LP64__ */
|
||||
|
||||
PR_LOG(gFontInfoLog, PR_LOG_DEBUG, ("(fontinit-cmap) psname: %s, size: %d\n",
|
||||
NS_ConvertUTF16toUTF8(mName).get(), mCharacterMap.GetSize()));
|
||||
|
||||
|
@ -40,7 +40,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <zlib.h>
|
||||
#include "zlib.h"
|
||||
|
||||
#ifdef WOFF_MOZILLA_CLIENT /* define this when building as part of Gecko */
|
||||
# include "prmem.h"
|
||||
|
@ -43,10 +43,5 @@
|
||||
*/
|
||||
|
||||
MSG_DEF(CTYPESMSG_PLACEHOLDER_0, 0, 0, JSEXN_NONE, NULL)
|
||||
MSG_DEF(CTYPESMSG_PLACEHOLDER_1, 1, 0, JSEXN_NONE, NULL)
|
||||
MSG_DEF(CTYPESMSG_PLACEHOLDER_2, 2, 0, JSEXN_NONE, NULL)
|
||||
|
||||
// This error has to be number 3 in order to be a TypeError,
|
||||
// due to a bug in the js engine.
|
||||
MSG_DEF(CTYPESMSG_TYPE_ERROR, 3, 2, JSEXN_TYPEERR, "expected type {0}, got {1}")
|
||||
MSG_DEF(CTYPESMSG_TYPE_ERROR, 1, 2, JSEXN_TYPEERR, "expected type {0}, got {1}")
|
||||
|
||||
|
@ -1041,6 +1041,9 @@ jsd_InitObjectManager(JSDContext* jsdc);
|
||||
extern void
|
||||
jsd_DestroyObjectManager(JSDContext* jsdc);
|
||||
|
||||
extern void
|
||||
jsd_DestroyObjects(JSDContext* jsdc);
|
||||
|
||||
extern void
|
||||
jsd_ObjectHook(JSContext *cx, JSObject *obj, JSBool isNew, void *closure);
|
||||
|
||||
|
@ -238,11 +238,19 @@ jsd_InitObjectManager(JSDContext* jsdc)
|
||||
|
||||
void
|
||||
jsd_DestroyObjectManager(JSDContext* jsdc)
|
||||
{
|
||||
jsd_DestroyObjects(jsdc);
|
||||
JSD_LOCK_OBJECTS(jsdc);
|
||||
JS_HashTableDestroy(jsdc->objectsTable);
|
||||
JSD_UNLOCK_OBJECTS(jsdc);
|
||||
}
|
||||
|
||||
void
|
||||
jsd_DestroyObjects(JSDContext* jsdc)
|
||||
{
|
||||
JSD_LOCK_OBJECTS(jsdc);
|
||||
while( !JS_CLIST_IS_EMPTY(&jsdc->objectsList) )
|
||||
_destroyJSDObject(jsdc, (JSDObject*)JS_NEXT_LINK(&jsdc->objectsList));
|
||||
JS_HashTableDestroy(jsdc->objectsTable);
|
||||
JSD_UNLOCK_OBJECTS(jsdc);
|
||||
}
|
||||
|
||||
|
@ -140,18 +140,17 @@ JSD_SetContextFlags(JSDContext *jsdc, uint32 flags)
|
||||
jsdc->flags = flags;
|
||||
if ((flags & JSD_COLLECT_PROFILE_DATA) ||
|
||||
!(flags & JSD_DISABLE_OBJECT_TRACE)) {
|
||||
// Need to reenable our call hooks now
|
||||
/* Need to reenable our call hooks now */
|
||||
JS_SetExecuteHook(jsdc->jsrt, jsd_TopLevelCallHook, jsdc);
|
||||
JS_SetCallHook(jsdc->jsrt, jsd_FunctionCallHook, jsdc);
|
||||
}
|
||||
if ((oldFlags ^ flags) & JSD_DISABLE_OBJECT_TRACE) {
|
||||
// Changing our JSD_DISABLE_OBJECT_TRACE flag
|
||||
/* Changing our JSD_DISABLE_OBJECT_TRACE flag */
|
||||
if (!(flags & JSD_DISABLE_OBJECT_TRACE)) {
|
||||
// Need to reenable our object hooks now
|
||||
if (jsd_InitObjectManager(jsdc))
|
||||
JS_SetObjectHook(jsdc->jsrt, jsd_ObjectHook, jsdc);
|
||||
/* Need to reenable our object hooks now */
|
||||
JS_SetObjectHook(jsdc->jsrt, jsd_ObjectHook, jsdc);
|
||||
} else {
|
||||
jsd_DestroyObjectManager(jsdc);
|
||||
jsd_DestroyObjects(jsdc);
|
||||
JS_SetObjectHook(jsdc->jsrt, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
@ -5827,7 +5827,8 @@ JS_PUBLIC_API(JSBool)
|
||||
JS_ThrowReportedError(JSContext *cx, const char *message,
|
||||
JSErrorReport *reportp)
|
||||
{
|
||||
return JS_IsRunning(cx) && js_ErrorToException(cx, message, reportp);
|
||||
return JS_IsRunning(cx) &&
|
||||
js_ErrorToException(cx, message, reportp, NULL, NULL);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
|
@ -1281,7 +1281,8 @@ MarkLocalRoots(JSTracer *trc, JSLocalRootStack *lrs)
|
||||
}
|
||||
|
||||
static void
|
||||
ReportError(JSContext *cx, const char *message, JSErrorReport *reportp)
|
||||
ReportError(JSContext *cx, const char *message, JSErrorReport *reportp,
|
||||
JSErrorCallback callback, void *userRef)
|
||||
{
|
||||
/*
|
||||
* Check the error report, and set a JavaScript-catchable exception
|
||||
@ -1290,7 +1291,8 @@ ReportError(JSContext *cx, const char *message, JSErrorReport *reportp)
|
||||
* on the error report, and exception-aware hosts should ignore it.
|
||||
*/
|
||||
JS_ASSERT(reportp);
|
||||
if (reportp->errorNumber == JSMSG_UNCAUGHT_EXCEPTION)
|
||||
if ((!callback || callback == js_GetErrorMessage) &&
|
||||
reportp->errorNumber == JSMSG_UNCAUGHT_EXCEPTION)
|
||||
reportp->flags |= JSREPORT_EXCEPTION;
|
||||
|
||||
/*
|
||||
@ -1301,7 +1303,8 @@ ReportError(JSContext *cx, const char *message, JSErrorReport *reportp)
|
||||
* propagates out of scope. This is needed for compatability
|
||||
* with the old scheme.
|
||||
*/
|
||||
if (!JS_IsRunning(cx) || !js_ErrorToException(cx, message, reportp)) {
|
||||
if (!JS_IsRunning(cx) ||
|
||||
!js_ErrorToException(cx, message, reportp, callback, userRef)) {
|
||||
js_ReportErrorAgain(cx, message, reportp);
|
||||
} else if (cx->debugHooks->debugErrorHook && cx->errorReporter) {
|
||||
JSDebugErrorHook hook = cx->debugHooks->debugErrorHook;
|
||||
@ -1457,7 +1460,7 @@ js_ReportErrorVA(JSContext *cx, uintN flags, const char *format, va_list ap)
|
||||
|
||||
warning = JSREPORT_IS_WARNING(report.flags);
|
||||
|
||||
ReportError(cx, message, &report);
|
||||
ReportError(cx, message, &report, NULL, NULL);
|
||||
js_free(message);
|
||||
cx->free(ucmessage);
|
||||
return warning;
|
||||
@ -1651,7 +1654,7 @@ js_ReportErrorNumberVA(JSContext *cx, uintN flags, JSErrorCallback callback,
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
ReportError(cx, message, &report);
|
||||
ReportError(cx, message, &report, callback, userRef);
|
||||
|
||||
if (message)
|
||||
cx->free(message);
|
||||
|
@ -1104,7 +1104,8 @@ static struct exnname { char *name; char *exception; } errortoexnname[] = {
|
||||
#endif /* DEBUG */
|
||||
|
||||
JSBool
|
||||
js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp)
|
||||
js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp,
|
||||
JSErrorCallback callback, void *userRef)
|
||||
{
|
||||
JSErrNum errorNumber;
|
||||
const JSErrorFormatString *errorString;
|
||||
@ -1124,7 +1125,10 @@ js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp)
|
||||
|
||||
/* Find the exception index associated with this error. */
|
||||
errorNumber = (JSErrNum) reportp->errorNumber;
|
||||
errorString = js_GetLocalizedErrorMessage(cx, NULL, NULL, errorNumber);
|
||||
if (!callback || callback == js_GetErrorMessage)
|
||||
errorString = js_GetLocalizedErrorMessage(cx, NULL, NULL, errorNumber);
|
||||
else
|
||||
errorString = callback(userRef, NULL, errorNumber);
|
||||
exn = errorString ? (JSExnType) errorString->exnType : JSEXN_NONE;
|
||||
JS_ASSERT(exn < JSEXN_LIMIT);
|
||||
|
||||
|
@ -63,7 +63,8 @@ js_InitExceptionClasses(JSContext *cx, JSObject *obj);
|
||||
* found and set, JS_FALSE otherwise.
|
||||
*/
|
||||
extern JSBool
|
||||
js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp);
|
||||
js_ErrorToException(JSContext *cx, const char *message, JSErrorReport *reportp,
|
||||
JSErrorCallback callback, void *userRef);
|
||||
|
||||
/*
|
||||
* Called if a JS API call to js_Execute or js_InternalCall fails; calls the
|
||||
|
@ -607,7 +607,7 @@ ReportCompileErrorNumberVA(JSContext *cx, JSTokenStream *ts, JSParseNode *pn,
|
||||
* which is likely spurious.
|
||||
*/
|
||||
if (!(ts->flags & TSF_ERROR)) {
|
||||
if (js_ErrorToException(cx, message, &report))
|
||||
if (js_ErrorToException(cx, message, &report, NULL, NULL))
|
||||
onError = NULL;
|
||||
}
|
||||
|
||||
|
@ -3254,7 +3254,9 @@ Scatter(JSContext *cx, uintN argc, jsval *vp)
|
||||
);
|
||||
if (!newcx)
|
||||
goto fail;
|
||||
JS_BeginRequest(newcx);
|
||||
JS_SetGlobalObject(newcx, JS_GetGlobalObject(cx));
|
||||
JS_EndRequest(newcx);
|
||||
JS_ClearContextThread(newcx);
|
||||
sd.threads[i].cx = newcx;
|
||||
}
|
||||
|
@ -1010,6 +1010,7 @@ nsFirstLineFrame::Reflow(nsPresContext* aPresContext,
|
||||
InlineReflowState irs;
|
||||
irs.mPrevFrame = nsnull;
|
||||
irs.mLineContainer = lineContainer;
|
||||
irs.mLineLayout = aReflowState.mLineLayout;
|
||||
irs.mNextInFlow = (nsInlineFrame*) GetNextInFlow();
|
||||
|
||||
nsresult rv;
|
||||
|
@ -224,9 +224,9 @@ enum { XKeyPress = KeyPress };
|
||||
static PRLogModuleInfo *nsObjectFrameLM = PR_NewLogModule("nsObjectFrame");
|
||||
#endif /* PR_LOGGING */
|
||||
|
||||
#define NORMAL_PLUGIN_DELAY 20
|
||||
// must avoid audio skipping/delays
|
||||
#define HIDDEN_PLUGIN_DELAY 125
|
||||
#if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
|
||||
#define MAC_CARBON_PLUGINS
|
||||
#endif
|
||||
|
||||
// special class for handeling DOM context menu events because for
|
||||
// some reason it starves other mouse events if implemented on the
|
||||
@ -257,7 +257,6 @@ public:
|
||||
|
||||
class nsPluginInstanceOwner : public nsIPluginInstanceOwner,
|
||||
public nsIPluginTagInfo,
|
||||
public nsITimerCallback,
|
||||
public nsIDOMMouseListener,
|
||||
public nsIDOMMouseMotionListener,
|
||||
public nsIDOMKeyListener,
|
||||
@ -325,11 +324,11 @@ public:
|
||||
void Paint(const nsRect& aDirtyRect, HPS aHPS);
|
||||
#endif
|
||||
|
||||
// nsITimerCallback interface
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
|
||||
#ifdef MAC_CARBON_PLUGINS
|
||||
void CancelTimer();
|
||||
void StartTimer(unsigned int aDelay);
|
||||
void StartTimer(PRBool isVisible);
|
||||
#endif
|
||||
void SendIdleEvent();
|
||||
|
||||
// nsIScrollPositionListener interface
|
||||
NS_IMETHOD ScrollPositionWillChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY);
|
||||
@ -432,7 +431,6 @@ private:
|
||||
nsCString mDocumentBase;
|
||||
char *mTagText;
|
||||
nsCOMPtr<nsIWidget> mWidget;
|
||||
nsCOMPtr<nsITimer> mPluginTimer;
|
||||
nsCOMPtr<nsIPluginHost> mPluginHost;
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
@ -452,7 +450,6 @@ private:
|
||||
// If true, destroy the widget on destruction. Used when plugin stop
|
||||
// is being delayed to a safer point in time.
|
||||
PRPackedBool mDestroyWidget;
|
||||
PRPackedBool mTimerCanceled;
|
||||
PRUint16 mNumCachedAttrs;
|
||||
PRUint16 mNumCachedParams;
|
||||
char **mCachedAttrParamNames;
|
||||
@ -1368,7 +1365,7 @@ nsObjectFrame::PrintPlugin(nsIRenderingContext& aRenderingContext,
|
||||
window.clipRect.left = 0; window.clipRect.right = 0;
|
||||
|
||||
// platform specific printing code
|
||||
#if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
|
||||
#ifdef MAC_CARBON_PLUGINS
|
||||
nsSize contentSize = GetContentRect().Size();
|
||||
window.x = 0;
|
||||
window.y = 0;
|
||||
@ -1933,7 +1930,9 @@ nsObjectFrame::HandleEvent(nsPresContext* aPresContext,
|
||||
#endif
|
||||
|
||||
if (anEvent->message == NS_DESTROY) {
|
||||
#ifdef MAC_CARBON_PLUGINS
|
||||
mInstanceOwner->CancelTimer();
|
||||
#endif
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -2433,7 +2432,6 @@ nsPluginInstanceOwner::nsPluginInstanceOwner()
|
||||
mCachedAttrParamNames = nsnull;
|
||||
mCachedAttrParamValues = nsnull;
|
||||
mDestroyWidget = PR_FALSE;
|
||||
mTimerCanceled = PR_TRUE;
|
||||
|
||||
#ifdef MOZ_COMPOSITED_PLUGINS
|
||||
mLastPoint = nsIntPoint(0,0);
|
||||
@ -2464,8 +2462,9 @@ nsPluginInstanceOwner::~nsPluginInstanceOwner()
|
||||
PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG,
|
||||
("nsPluginInstanceOwner %p deleted\n", this));
|
||||
|
||||
// shut off the timer.
|
||||
#ifdef MAC_CARBON_PLUGINS
|
||||
CancelTimer();
|
||||
#endif
|
||||
|
||||
mObjectFrame = nsnull;
|
||||
|
||||
@ -2522,7 +2521,6 @@ NS_IMPL_RELEASE(nsPluginInstanceOwner)
|
||||
NS_INTERFACE_MAP_BEGIN(nsPluginInstanceOwner)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIPluginInstanceOwner)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIPluginTagInfo)
|
||||
NS_INTERFACE_MAP_ENTRY(nsITimerCallback)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMMouseListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMMouseMotionListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMKeyListener)
|
||||
@ -3572,7 +3570,7 @@ nsPluginInstanceOwner::GetEventloopNestingLevel()
|
||||
|
||||
nsresult nsPluginInstanceOwner::ScrollPositionWillChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY)
|
||||
{
|
||||
#if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
|
||||
#ifdef MAC_CARBON_PLUGINS
|
||||
if (GetEventModel() != NPEventModelCarbon)
|
||||
return NS_OK;
|
||||
|
||||
@ -3599,7 +3597,7 @@ nsresult nsPluginInstanceOwner::ScrollPositionWillChange(nsIScrollableView* aScr
|
||||
|
||||
nsresult nsPluginInstanceOwner::ScrollPositionDidChange(nsIScrollableView* aScrollable, nscoord aX, nscoord aY)
|
||||
{
|
||||
#if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
|
||||
#ifdef MAC_CARBON_PLUGINS
|
||||
if (GetEventModel() != NPEventModelCarbon)
|
||||
return NS_OK;
|
||||
|
||||
@ -3618,9 +3616,9 @@ nsresult nsPluginInstanceOwner::ScrollPositionDidChange(nsIScrollableView* aScro
|
||||
pluginWidget->EndDrawPlugin();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
StartTimer(NORMAL_PLUGIN_DELAY);
|
||||
StartTimer(PR_TRUE);
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -3680,7 +3678,7 @@ nsresult nsPluginInstanceOwner::KeyUp(nsIDOMEvent* aKeyEvent)
|
||||
|
||||
nsresult nsPluginInstanceOwner::KeyPress(nsIDOMEvent* aKeyEvent)
|
||||
{
|
||||
#if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
|
||||
#ifdef MAC_CARBON_PLUGINS
|
||||
// send KeyPress events only for Mac OS X Carbon event model
|
||||
if (GetEventModel() != NPEventModelCarbon)
|
||||
return aKeyEvent->PreventDefault();
|
||||
@ -4635,8 +4633,10 @@ nsEventStatus nsPluginInstanceOwner::ProcessEvent(const nsGUIEvent& anEvent)
|
||||
nsresult
|
||||
nsPluginInstanceOwner::Destroy()
|
||||
{
|
||||
#ifdef MAC_CARBON_PLUGINS
|
||||
// stop the timer explicitly to reduce reference count.
|
||||
CancelTimer();
|
||||
#endif
|
||||
|
||||
// unregister context menu listener
|
||||
if (mCXMenuListener) {
|
||||
@ -5362,14 +5362,9 @@ nsPluginInstanceOwner::Renderer::NativeDraw(QWidget * drawable,
|
||||
}
|
||||
#endif
|
||||
|
||||
// Here's how we give idle time to plugins.
|
||||
|
||||
NS_IMETHODIMP nsPluginInstanceOwner::Notify(nsITimer* timer)
|
||||
void nsPluginInstanceOwner::SendIdleEvent()
|
||||
{
|
||||
#if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
|
||||
if (GetEventModel() != NPEventModelCarbon)
|
||||
return NS_OK;
|
||||
|
||||
#ifdef MAC_CARBON_PLUGINS
|
||||
// validate the plugin clipping information by syncing the plugin window info to
|
||||
// reflect the current widget location. This makes sure that everything is updated
|
||||
// correctly in the event of scrolling in the window.
|
||||
@ -5395,36 +5390,22 @@ NS_IMETHODIMP nsPluginInstanceOwner::Notify(nsITimer* timer)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsPluginInstanceOwner::StartTimer(unsigned int aDelay)
|
||||
#ifdef MAC_CARBON_PLUGINS
|
||||
void nsPluginInstanceOwner::StartTimer(PRBool isVisible)
|
||||
{
|
||||
#if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
|
||||
if (GetEventModel() != NPEventModelCarbon)
|
||||
return;
|
||||
|
||||
if (!mTimerCanceled)
|
||||
return;
|
||||
|
||||
// start a periodic timer to provide null events to the plugin instance.
|
||||
if (!mPluginTimer) {
|
||||
mPluginTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
}
|
||||
if (mPluginTimer) {
|
||||
mTimerCanceled = PR_FALSE;
|
||||
mPluginTimer->InitWithCallback(this, aDelay, nsITimer::TYPE_REPEATING_SLACK);
|
||||
}
|
||||
#endif
|
||||
mPluginHost->AddIdleTimeTarget(this, isVisible);
|
||||
}
|
||||
|
||||
void nsPluginInstanceOwner::CancelTimer()
|
||||
{
|
||||
if (mPluginTimer) {
|
||||
mPluginTimer->Cancel();
|
||||
}
|
||||
mTimerCanceled = PR_TRUE;
|
||||
mPluginHost->RemoveIdleTimeTarget(this);
|
||||
}
|
||||
#endif
|
||||
|
||||
nsresult nsPluginInstanceOwner::Init(nsPresContext* aPresContext,
|
||||
nsObjectFrame* aFrame,
|
||||
@ -5597,8 +5578,10 @@ NS_IMETHODIMP nsPluginInstanceOwner::CreateWidget(void)
|
||||
mPluginWindow->type = NPWindowTypeWindow;
|
||||
mPluginWindow->window = GetPluginPort();
|
||||
|
||||
#ifdef MAC_CARBON_PLUGINS
|
||||
// start the idle timer.
|
||||
StartTimer(NORMAL_PLUGIN_DELAY);
|
||||
StartTimer(PR_TRUE);
|
||||
#endif
|
||||
|
||||
// tell the plugin window about the widget
|
||||
mPluginWindow->SetPluginWidget(mWidget);
|
||||
@ -5639,7 +5622,7 @@ PRBool nsPluginInstanceOwner::UpdateVisibility()
|
||||
}
|
||||
#endif
|
||||
|
||||
// Mac specific code to fix up the port location and clipping region
|
||||
// Mac specific code to fix up the port location and clipping region
|
||||
#ifdef XP_MACOSX
|
||||
|
||||
void* nsPluginInstanceOwner::FixUpPluginWindow(PRInt32 inPaintState)
|
||||
@ -5735,15 +5718,17 @@ void* nsPluginInstanceOwner::FixUpPluginWindow(PRInt32 inPaintState)
|
||||
{
|
||||
mInstance->SetWindow(mPluginWindow);
|
||||
mPluginPortChanged = PR_FALSE;
|
||||
#ifdef MAC_CARBON_PLUGINS
|
||||
// if the clipRect is of size 0, make the null timer fire less often
|
||||
CancelTimer();
|
||||
if (mPluginWindow->clipRect.left == mPluginWindow->clipRect.right ||
|
||||
mPluginWindow->clipRect.top == mPluginWindow->clipRect.bottom) {
|
||||
StartTimer(HIDDEN_PLUGIN_DELAY);
|
||||
StartTimer(PR_FALSE);
|
||||
}
|
||||
else {
|
||||
StartTimer(NORMAL_PLUGIN_DELAY);
|
||||
StartTimer(PR_TRUE);
|
||||
}
|
||||
#endif
|
||||
} else if (mPluginPortChanged) {
|
||||
mInstance->SetWindow(mPluginWindow);
|
||||
mPluginPortChanged = PR_FALSE;
|
||||
|
@ -67,33 +67,37 @@ function makeResult() {
|
||||
};
|
||||
}
|
||||
|
||||
function waitInterrupt(result, gen, timewait) {
|
||||
function makeListener(result, eventGen) {
|
||||
return function(ev) {
|
||||
result.success = true;
|
||||
result.event = ev;
|
||||
setTimeout(function() { eventGen.next(); }, 0);
|
||||
};
|
||||
}
|
||||
|
||||
function waitInterrupt(result, gen) {
|
||||
result.event = null;
|
||||
result.success = false;
|
||||
setTimeout(function() { if (!result.success) gen.next(); }, (timewait || 2000));
|
||||
setTimeout(function() { if (!result.success) gen.next(); }, 3500);
|
||||
}
|
||||
|
||||
function testPhoom(isCapturing, x, y, expectEvent) {
|
||||
var result;
|
||||
|
||||
var eventGen = (function() {
|
||||
var innerdoc = document.getElementById('testframe').contentDocument;
|
||||
|
||||
for each (var doc in [document, innerdoc]) {
|
||||
var inner = (doc == innerdoc);
|
||||
var w, h;
|
||||
var listener = function(ev) {
|
||||
result.success = true;
|
||||
result.event = ev;
|
||||
setTimeout(function() { eventGen.next(); }, 0);
|
||||
};
|
||||
var w, h, result, listener;
|
||||
|
||||
/* --- EXPANSION --- */
|
||||
|
||||
result = makeResult();
|
||||
listener = makeListener(result, eventGen);
|
||||
|
||||
doc.addEventListener("MozScrolledAreaChanged", listener, isCapturing);
|
||||
|
||||
result = makeResult();
|
||||
waitInterrupt(result, eventGen, 1200);
|
||||
if (!expectEvent) waitInterrupt(result, eventGen);
|
||||
phoom(doc, x, y);
|
||||
yield;
|
||||
|
||||
@ -103,7 +107,7 @@ function testPhoom(isCapturing, x, y, expectEvent) {
|
||||
one can still arrive, but we don't complain if it did not. In either case, any event
|
||||
that arrives will have its data checked below. */
|
||||
if (expectEvent) {
|
||||
ok(result.success, "Received expected expansion event");
|
||||
ok(result.success, "Received expected " + (inner ? "inner" : "") + " expansion event");
|
||||
}
|
||||
|
||||
if (result.success) {
|
||||
@ -129,17 +133,19 @@ function testPhoom(isCapturing, x, y, expectEvent) {
|
||||
|
||||
/* --- CONTRACTION --- */
|
||||
|
||||
result = makeResult();
|
||||
listener = makeListener(result, eventGen);
|
||||
|
||||
doc.addEventListener("MozScrolledAreaChanged", listener, isCapturing);
|
||||
|
||||
result = makeResult();
|
||||
waitInterrupt(result, eventGen, 1200);
|
||||
if (!expectEvent) waitInterrupt(result, eventGen);
|
||||
unphoom(doc);
|
||||
yield;
|
||||
|
||||
doc.removeEventListener("MozScrolledAreaChanged", listener, isCapturing);
|
||||
|
||||
if (expectEvent) {
|
||||
ok(result.success, "Received expected contraction event");
|
||||
ok(result.success, "Received expected " + (inner ? "inner" : "") + " contraction event");
|
||||
}
|
||||
|
||||
if (result.success) {
|
||||
|
@ -1878,8 +1878,10 @@ nsPrintEngine::ReflowPrintObject(nsPrintObject * aPO)
|
||||
}
|
||||
// Without a frame, this document can't be displayed; therefore, there is no
|
||||
// point to reflowing it
|
||||
if (!frame)
|
||||
if (!frame) {
|
||||
aPO->mDontPrint = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
adjSize = frame->GetContentRect().Size();
|
||||
documentIsTopLevel = PR_FALSE;
|
||||
|
42
layout/reftests/css-gradients/height-dependence-1-ref.html
Normal file
42
layout/reftests/css-gradients/height-dependence-1-ref.html
Normal file
@ -0,0 +1,42 @@
|
||||
<!doctype html>
|
||||
<html><head>
|
||||
<style>
|
||||
html {
|
||||
background-image: -moz-linear-gradient(black, white 20%)
|
||||
}
|
||||
body {
|
||||
font-size: 1em;
|
||||
padding: 2em;
|
||||
margin: 50px auto;
|
||||
width: 14em;
|
||||
border: 1px solid black;
|
||||
background-color: white;
|
||||
}
|
||||
</style>
|
||||
</head><body>
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
</body>
|
||||
</html>
|
52
layout/reftests/css-gradients/height-dependence-1.html
Normal file
52
layout/reftests/css-gradients/height-dependence-1.html
Normal file
@ -0,0 +1,52 @@
|
||||
<!doctype html>
|
||||
<html class="reftest-wait"><head>
|
||||
<style>
|
||||
html {
|
||||
background-image: -moz-linear-gradient(black, white 20%)
|
||||
}
|
||||
body {
|
||||
font-size: 1em;
|
||||
padding: 2em;
|
||||
margin: 50px auto;
|
||||
width: 28em;
|
||||
border: 1px solid black;
|
||||
background-color: white;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
setTimeout(function() {
|
||||
document.body.style.width = "14em";
|
||||
setTimeout(function() {
|
||||
document.documentElement.removeAttribute("class");
|
||||
}, 100);
|
||||
}, 100);
|
||||
}
|
||||
</script>
|
||||
</head><body>
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
</body>
|
||||
</html>
|
43
layout/reftests/css-gradients/height-dependence-2-ref.html
Normal file
43
layout/reftests/css-gradients/height-dependence-2-ref.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!doctype html>
|
||||
<html><head>
|
||||
<style>
|
||||
html {
|
||||
background-image: -moz-linear-gradient(black, white 20%);
|
||||
-moz-background-size: 400px 400px;
|
||||
}
|
||||
body {
|
||||
font-size: 1em;
|
||||
padding: 2em;
|
||||
margin: 50px auto;
|
||||
width: 14em;
|
||||
border: 1px solid black;
|
||||
background-color: white;
|
||||
}
|
||||
</style>
|
||||
</head><body>
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
</body>
|
||||
</html>
|
53
layout/reftests/css-gradients/height-dependence-2.html
Normal file
53
layout/reftests/css-gradients/height-dependence-2.html
Normal file
@ -0,0 +1,53 @@
|
||||
<!doctype html>
|
||||
<html class="reftest-wait"><head>
|
||||
<style>
|
||||
html {
|
||||
background-image: -moz-linear-gradient(black, white 20%);
|
||||
-moz-background-size: 400px 400px;
|
||||
}
|
||||
body {
|
||||
font-size: 1em;
|
||||
padding: 2em;
|
||||
margin: 50px auto;
|
||||
width: 28em;
|
||||
border: 1px solid black;
|
||||
background-color: white;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
setTimeout(function() {
|
||||
document.body.style.width = "14em";
|
||||
setTimeout(function() {
|
||||
document.documentElement.removeAttribute("class");
|
||||
}, 100);
|
||||
}, 100);
|
||||
}
|
||||
</script>
|
||||
</head><body>
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
</body>
|
||||
</html>
|
44
layout/reftests/css-gradients/height-dependence-3-ref.html
Normal file
44
layout/reftests/css-gradients/height-dependence-3-ref.html
Normal file
@ -0,0 +1,44 @@
|
||||
<!doctype html>
|
||||
<html><head>
|
||||
<style>
|
||||
html {
|
||||
background-image: -moz-linear-gradient(black, white 20%);
|
||||
background-repeat: repeat-x;
|
||||
-moz-background-size: 1px 80%;
|
||||
}
|
||||
body {
|
||||
font-size: 1em;
|
||||
padding: 2em;
|
||||
margin: 50px auto;
|
||||
width: 14em;
|
||||
border: 1px solid black;
|
||||
background-color: white;
|
||||
}
|
||||
</style>
|
||||
</head><body>
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
</body>
|
||||
</html>
|
54
layout/reftests/css-gradients/height-dependence-3.html
Normal file
54
layout/reftests/css-gradients/height-dependence-3.html
Normal file
@ -0,0 +1,54 @@
|
||||
<!doctype html>
|
||||
<html class="reftest-wait"><head>
|
||||
<style>
|
||||
html {
|
||||
background-image: -moz-linear-gradient(black, white 20%);
|
||||
background-repeat: repeat-x;
|
||||
-moz-background-size: 1px 80%;
|
||||
}
|
||||
body {
|
||||
font-size: 1em;
|
||||
padding: 2em;
|
||||
margin: 50px auto;
|
||||
width: 28em;
|
||||
border: 1px solid black;
|
||||
background-color: white;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
window.onload = function() {
|
||||
setTimeout(function() {
|
||||
document.body.style.width = "14em";
|
||||
setTimeout(function() {
|
||||
document.documentElement.removeAttribute("class");
|
||||
}, 100);
|
||||
}, 100);
|
||||
}
|
||||
</script>
|
||||
</head><body>
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
pad pad pad pad pad pad pad pad
|
||||
</body>
|
||||
</html>
|
@ -85,4 +85,6 @@ fails == aja-linear-2d.html aja-linear-2-ref.html # bug 526694
|
||||
== aja-linear-5a.html aja-linear-5-ref.html
|
||||
fails-if(MOZ_WIDGET_TOOLKIT=="cocoa") == aja-linear-6a.html aja-linear-6-ref.html # bug 526708
|
||||
fails == aja-linear-6b.html aja-linear-6-ref.html # bug 522607
|
||||
|
||||
== height-dependence-1.html height-dependence-1-ref.html
|
||||
== height-dependence-2.html height-dependence-2-ref.html
|
||||
== height-dependence-3.html height-dependence-3-ref.html
|
||||
|
@ -876,6 +876,12 @@ nsCSSDeclaration::GetValue(nsCSSProperty aProperty,
|
||||
const nsCSSValuePairList *size =
|
||||
* data->ValuePairListStorageFor(eCSSProperty__moz_background_size);
|
||||
for (;;) {
|
||||
if (size->mXValue.GetUnit() != eCSSUnit_Auto ||
|
||||
size->mYValue.GetUnit() != eCSSUnit_Auto) {
|
||||
// Non-default background-size, so can't be serialized as shorthand.
|
||||
aValue.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
AppendCSSValueToString(eCSSProperty_background_image,
|
||||
image->mValue, aValue);
|
||||
aValue.Append(PRUnichar(' '));
|
||||
|
@ -413,10 +413,19 @@ struct nsStyleBackground {
|
||||
};
|
||||
PRUint8 mWidthType, mHeightType;
|
||||
|
||||
// True if the effective image size described by this depends on the size
|
||||
// of the corresponding frame.
|
||||
PRBool DependsOnFrameSize() const {
|
||||
return mWidthType <= ePercentage || mHeightType <= ePercentage;
|
||||
// True if the effective image size described by this depends on
|
||||
// the size of the corresponding frame. Gradients depend on the
|
||||
// frame size when their dimensions are 'auto', images don't; both
|
||||
// types depend on the frame size when their dimensions are
|
||||
// 'contain', 'cover', or a percentage.
|
||||
PRBool DependsOnFrameSize(nsStyleImageType aType) const {
|
||||
if (aType == eStyleImageType_Image) {
|
||||
return mWidthType <= ePercentage || mHeightType <= ePercentage;
|
||||
} else if (aType == eStyleImageType_Gradient) {
|
||||
return mWidthType <= eAuto || mHeightType <= eAuto;
|
||||
} else {
|
||||
NS_NOTREACHED("unrecognized image type");
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize nothing
|
||||
@ -448,12 +457,16 @@ struct nsStyleBackground {
|
||||
|
||||
void SetInitialValues();
|
||||
|
||||
// True if the rendering of this layer might change when the size of the
|
||||
// corresponding frame changes (if its position or size is a percentage of
|
||||
// the frame's dimensions).
|
||||
// True if the rendering of this layer might change when the size
|
||||
// of the corresponding frame changes. This is true for any
|
||||
// non-solid-color background whose position or size depends on
|
||||
// the frame size (that is, was specified with percentages) and is
|
||||
// also true for nearly all gradients. We don't currently bother
|
||||
// trying to identify gradients that don't depend on the frame size.
|
||||
PRBool RenderingMightDependOnFrameSize() const {
|
||||
return !mImage.IsEmpty() &&
|
||||
(mPosition.DependsOnFrameSize() || mSize.DependsOnFrameSize());
|
||||
return (!mImage.IsEmpty() &&
|
||||
(mPosition.DependsOnFrameSize() ||
|
||||
mSize.DependsOnFrameSize(mImage.GetType())));
|
||||
}
|
||||
|
||||
// An equality operator that compares the images using URL-equality
|
||||
|
@ -122,29 +122,35 @@ is(e.style.background, "", "should not have background shorthand (origin:content
|
||||
//is(e.style.background, "", "should not have background shorthand (clip:content)");
|
||||
//e.setAttribute("style", "background: red; -moz-background-clip: content; -moz-background-origin: content;");
|
||||
//isnot(e.style.background, "", "should have background shorthand (clip:content;origin:content)");
|
||||
e.setAttribute("style", "background: red; -moz-background-size: 100% 100%");
|
||||
is(e.style.background, "", "should not have background shorthand (size:100% 100%)");
|
||||
e.setAttribute("style", "background: red; -moz-background-size: 100% auto");
|
||||
is(e.style.background, "", "should not have background shorthand (size:100% auto)");
|
||||
e.setAttribute("style", "background: red; -moz-background-size: auto 100%");
|
||||
is(e.style.background, "", "should not have background shorthand (size:auto 100%)");
|
||||
e.setAttribute("style", "background: red; -moz-background-inline-policy: each-box");
|
||||
isnot(e.style.background, "", "should have background shorthand (-moz-background-inline-policy not relevant)");
|
||||
|
||||
// Check that we only serialize background when the lists (of layers) for
|
||||
// the subproperties are the same length.
|
||||
// XXX Should change background-clip to border,padding,border and
|
||||
// background-origin to border,padding,padding once serialization does
|
||||
// clip/origin.
|
||||
e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: cover, auto, contain; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
|
||||
// background-origin to border,padding,padding and background-size to
|
||||
// cover,auto,contain once serialization does clip/origin/size.
|
||||
e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
|
||||
isnot(e.style.background, "", "should have background shorthand (all lists length 3)");
|
||||
e.setAttribute("style", "-moz-background-clip: border, border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: cover, auto, contain; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
|
||||
e.setAttribute("style", "-moz-background-clip: border, border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
|
||||
is(e.style.background, "", "should not have background shorthand (background-clip too long)");
|
||||
e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: border, padding; -moz-background-size: cover, auto, contain; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
|
||||
e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: padding, padding; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
|
||||
is(e.style.background, "", "should not have background shorthand (background-origin too short)");
|
||||
e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: cover, auto, contain; background-color: blue; background-image: url(404.png), none, url(404-2.png), none; background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
|
||||
e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png), none; background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
|
||||
is(e.style.background, "", "should not have background shorthand (background-image too long)");
|
||||
e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: cover, auto, contain; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
|
||||
e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
|
||||
is(e.style.background, "", "should not have background shorthand (background-attachment too short)");
|
||||
e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: cover, auto, contain; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px, bottom; background-repeat: repeat-x, repeat, no-repeat");
|
||||
e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px, bottom; background-repeat: repeat-x, repeat, no-repeat");
|
||||
is(e.style.background, "", "should not have background shorthand (background-position too long)");
|
||||
e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: cover, auto, contain; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat");
|
||||
e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat");
|
||||
is(e.style.background, "", "should not have background shorthand (background-repeat too short)");
|
||||
e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: cover, auto, contain, cover; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
|
||||
e.setAttribute("style", "-moz-background-clip: border, border, border; -moz-background-origin: padding, padding, padding; -moz-background-size: auto, auto, auto, auto; background-color: blue; background-image: url(404.png), none, url(404-2.png); background-attachment: fixed, scroll, scroll; background-position: top left, center, 30px 50px; background-repeat: repeat-x, repeat, no-repeat");
|
||||
is(e.style.background, "", "should not have background shorthand (-moz-background-size too long)");
|
||||
|
||||
// Check that we only serialize transition when the lists are the same length.
|
||||
|
@ -75,7 +75,7 @@ endif
|
||||
_HARNESS_FILES = \
|
||||
$(srcdir)/runreftest.py \
|
||||
automation.py \
|
||||
$(CURDIR)/automationutils.py \
|
||||
$(topsrcdir)/build/automationutils.py \
|
||||
$(NULL)
|
||||
|
||||
$(_DEST_DIR):
|
||||
|
@ -702,8 +702,11 @@ function OnDocumentLoad(event)
|
||||
// above causes 2 assertions. So that we don't have to annotate
|
||||
// the manifests for every reftest-print reftest, bump the
|
||||
// assertion count by two right here.
|
||||
gURLs[0].minAsserts += 2;
|
||||
gURLs[0].maxAsserts += 2;
|
||||
// And on Mac, it causes *three* assertions.
|
||||
var xr = CC[NS_XREAPPINFO_CONTRACTID].getService(CI.nsIXULRuntime);
|
||||
var count = (xr.widgetToolkit == "cocoa") ? 3 : 2;
|
||||
gURLs[0].minAsserts += count;
|
||||
gURLs[0].maxAsserts += count;
|
||||
}
|
||||
|
||||
setupZoom(contentRootElement);
|
||||
|
@ -77,7 +77,12 @@ protected:
|
||||
nsButtonBoxFrame(aPresShell, aContext) {}
|
||||
|
||||
void StartRepeat() {
|
||||
nsRepeatService::GetInstance()->Start(Notify, this, 0);
|
||||
if (IsActivatedOnHover()) {
|
||||
// No initial delay on hover.
|
||||
nsRepeatService::GetInstance()->Start(Notify, this, 0);
|
||||
} else {
|
||||
nsRepeatService::GetInstance()->Start(Notify, this);
|
||||
}
|
||||
}
|
||||
void StopRepeat() {
|
||||
nsRepeatService::GetInstance()->Stop(Notify, this);
|
||||
|
@ -59,7 +59,11 @@ pref("general.warnOnAboutConfig", true);
|
||||
pref("browser.bookmarks.max_backups", 5);
|
||||
|
||||
pref("browser.cache.disk.enable", true);
|
||||
#ifndef WINCE
|
||||
pref("browser.cache.disk.capacity", 51200);
|
||||
#else
|
||||
pref("browser.cache.disk.capacity", 20000);
|
||||
#endif
|
||||
pref("browser.cache.memory.enable", true);
|
||||
//pref("browser.cache.memory.capacity", -1);
|
||||
// -1 = determine dynamically, 0 = none, n = memory capacity in kilobytes
|
||||
@ -68,6 +72,7 @@ pref("browser.cache.disk_cache_ssl", false);
|
||||
pref("browser.cache.check_doc_frequency", 3);
|
||||
|
||||
pref("browser.cache.offline.enable", true);
|
||||
#ifndef WINCE
|
||||
// offline cache capacity in kilobytes
|
||||
pref("browser.cache.offline.capacity", 512000);
|
||||
|
||||
@ -78,6 +83,12 @@ pref("offline-apps.quota.max", 204800);
|
||||
// the user should be warned if offline app disk usage exceeds this amount
|
||||
// (in kilobytes)
|
||||
pref("offline-apps.quota.warn", 51200);
|
||||
#else
|
||||
// Limited disk space on WinCE, tighten limits.
|
||||
pref("browser.cache.offline.capacity", 15000);
|
||||
pref("offline-apps.quota.max", 7000);
|
||||
pref("offline-apps.quota.warn", 4000);
|
||||
#endif
|
||||
|
||||
// Fastback caching - if this pref is negative, then we calculate the number
|
||||
// of content viewers to cache based on the amount of available memory.
|
||||
|
@ -67,6 +67,7 @@ struct PrefCallbackData {
|
||||
nsPrefBranch *pBranch;
|
||||
nsIObserver *pObserver;
|
||||
nsIWeakReference *pWeakRef;
|
||||
char pDomain[1];
|
||||
};
|
||||
|
||||
|
||||
@ -591,7 +592,7 @@ NS_IMETHODIMP nsPrefBranch::AddObserver(const char *aDomain, nsIObserver *aObser
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
pCallback = (PrefCallbackData *)nsMemory::Alloc(sizeof(PrefCallbackData));
|
||||
pCallback = (PrefCallbackData *)NS_Alloc(sizeof(PrefCallbackData) + strlen(aDomain));
|
||||
if (nsnull == pCallback)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
@ -613,8 +614,8 @@ NS_IMETHODIMP nsPrefBranch::AddObserver(const char *aDomain, nsIObserver *aObser
|
||||
NS_ADDREF(pCallback->pObserver);
|
||||
}
|
||||
|
||||
strcpy(pCallback->pDomain, aDomain);
|
||||
mObservers->AppendElement(pCallback);
|
||||
mObserverDomains.AppendElement(nsCString(aDomain));
|
||||
|
||||
// We must pass a fully qualified preference name to the callback
|
||||
pref = getPrefName(aDomain); // aDomain == nsnull only possible failure, trapped above
|
||||
@ -644,28 +645,24 @@ NS_IMETHODIMP nsPrefBranch::RemoveObserver(const char *aDomain, nsIObserver *aOb
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
pCallback = (PrefCallbackData *)mObservers->ElementAt(i);
|
||||
if (pCallback) {
|
||||
if (pCallback->pObserver == aObserver) {
|
||||
domain = mObserverDomains[i];
|
||||
if (domain.Equals(aDomain)) {
|
||||
// We must pass a fully qualified preference name to remove the callback
|
||||
pref = getPrefName(aDomain); // aDomain == nsnull only possible failure, trapped above
|
||||
rv = PREF_UnregisterCallback(pref, NotifyObserver, pCallback);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Remove this observer from our array so that nobody else can remove
|
||||
// what we're trying to remove ourselves right now.
|
||||
mObservers->RemoveElementAt(i);
|
||||
mObserverDomains.RemoveElementAt(i);
|
||||
if (pCallback->pWeakRef) {
|
||||
NS_RELEASE(pCallback->pWeakRef);
|
||||
} else {
|
||||
NS_RELEASE(pCallback->pObserver);
|
||||
}
|
||||
nsMemory::Free(pCallback);
|
||||
}
|
||||
return rv;
|
||||
if (pCallback &&
|
||||
pCallback->pObserver == aObserver &&
|
||||
!strcmp(pCallback->pDomain, aDomain)) {
|
||||
// We must pass a fully qualified preference name to remove the callback
|
||||
pref = getPrefName(aDomain); // aDomain == nsnull only possible failure, trapped above
|
||||
rv = PREF_UnregisterCallback(pref, NotifyObserver, pCallback);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
// Remove this observer from our array so that nobody else can remove
|
||||
// what we're trying to remove ourselves right now.
|
||||
mObservers->RemoveElementAt(i);
|
||||
if (pCallback->pWeakRef) {
|
||||
NS_RELEASE(pCallback->pWeakRef);
|
||||
} else {
|
||||
NS_RELEASE(pCallback->pObserver);
|
||||
}
|
||||
NS_Free(pCallback);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
@ -695,7 +692,7 @@ static nsresult NotifyObserver(const char *newpref, void *data)
|
||||
observer = do_QueryReferent(pData->pWeakRef);
|
||||
if (!observer) {
|
||||
// this weak referenced observer went away, remove them from the list
|
||||
pData->pBranch->RemoveObserver(newpref, pData->pObserver);
|
||||
pData->pBranch->RemoveObserver(pData->pDomain, pData->pObserver);
|
||||
return NS_OK;
|
||||
}
|
||||
} else {
|
||||
@ -725,9 +722,8 @@ void nsPrefBranch::freeObserverList(void)
|
||||
for (i = 0; i < count; ++i) {
|
||||
pCallback = (PrefCallbackData *)mObservers->ElementAt(i);
|
||||
if (pCallback) {
|
||||
domain = mObserverDomains[i];
|
||||
// We must pass a fully qualified preference name to remove the callback
|
||||
pref = getPrefName(domain.get()); // can't fail because domain must be valid
|
||||
pref = getPrefName(pCallback->pDomain);
|
||||
// Remove this observer from our array so that nobody else can remove
|
||||
// what we're trying to remove right now.
|
||||
mObservers->ReplaceElementAt(nsnull, i);
|
||||
@ -740,9 +736,6 @@ void nsPrefBranch::freeObserverList(void)
|
||||
nsMemory::Free(pCallback);
|
||||
}
|
||||
}
|
||||
|
||||
// now empty the observer domains array in bulk
|
||||
mObserverDomains.Clear();
|
||||
}
|
||||
delete mObservers;
|
||||
mObservers = 0;
|
||||
|
@ -83,7 +83,6 @@ private:
|
||||
PRInt32 mPrefRootLength;
|
||||
nsAutoVoidArray *mObservers;
|
||||
nsCString mPrefRoot;
|
||||
nsTArray<nsCString> mObserverDomains;
|
||||
PRBool mIsDefault;
|
||||
|
||||
};
|
||||
|
@ -64,7 +64,7 @@ interface nsIPluginStreamListener;
|
||||
[ref] native nsIStreamListenerRef(nsIStreamListener *);
|
||||
[ptr] native nsPluginNativeWindowPtr(nsPluginNativeWindow);
|
||||
|
||||
[scriptable, uuid(30C7C529-B05C-4950-B5B8-9AF673E46521)]
|
||||
[scriptable, uuid(AA13B116-2AFC-4F23-8395-913C0475D173)]
|
||||
interface nsIPluginHost : nsISupports
|
||||
{
|
||||
[noscript] void init();
|
||||
@ -285,6 +285,11 @@ interface nsIPluginHost : nsISupports
|
||||
* @return plugin tag object
|
||||
*/
|
||||
[noscript] nsIPluginTag getPluginTagForInstance(in nsIPluginInstance aInstance);
|
||||
|
||||
%{C++
|
||||
virtual void AddIdleTimeTarget(nsIPluginInstanceOwner* objectFrame, PRBool isVisible) = 0;
|
||||
virtual void RemoveIdleTimeTarget(nsIPluginInstanceOwner* objectFrame) = 0;
|
||||
%}
|
||||
};
|
||||
|
||||
%{C++
|
||||
|
@ -49,7 +49,7 @@ class nsPluginEvent;
|
||||
|
||||
[ref] native nsIPluginInstanceRef(nsIPluginInstance*);
|
||||
|
||||
[uuid(8080E717-7261-4707-B8B4-48250F47055F)]
|
||||
[uuid(D8776CDC-00DF-4395-A432-2E78EBCC12B6)]
|
||||
interface nsIPluginInstanceOwner : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -137,4 +137,8 @@ interface nsIPluginInstanceOwner : nsISupports
|
||||
%}
|
||||
|
||||
void setEventModel(in PRInt32 eventModel);
|
||||
|
||||
%{C++
|
||||
virtual void SendIdleEvent() = 0;
|
||||
%}
|
||||
};
|
||||
|
@ -57,6 +57,7 @@ CPPSRCS = \
|
||||
nsPluginHost.cpp \
|
||||
nsPluginModule.cpp \
|
||||
nsJSNPRuntime.cpp \
|
||||
nsPluginTags.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifeq ($(OS_ARCH), BeOS)
|
||||
|
@ -92,7 +92,6 @@
|
||||
#include "nsEnumeratorUtils.h"
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsXPCOMCID.h"
|
||||
#include "nsICategoryManager.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
|
||||
// for the dialog
|
||||
@ -226,8 +225,6 @@ PRLogModuleInfo* nsPluginLogging::gPluginLog = nsnull;
|
||||
|
||||
#define MAGIC_REQUEST_CONTEXT 0x01020304
|
||||
|
||||
nsresult PostPluginUnloadEvent(PRLibrary * aLibrary);
|
||||
|
||||
static nsPluginInstanceTagList *gActivePluginList;
|
||||
|
||||
#ifdef CALL_SAFETY_ON
|
||||
@ -309,619 +306,6 @@ NS_IMETHODIMP nsPluginDocReframeEvent::Run() {
|
||||
return mDocs->Clear();
|
||||
}
|
||||
|
||||
nsPluginInstanceTag::nsPluginInstanceTag(nsPluginTag* aPluginTag,
|
||||
nsIPluginInstance* aInstance,
|
||||
const char * url,
|
||||
PRBool aDefaultPlugin)
|
||||
{
|
||||
mNext = nsnull;
|
||||
mPluginTag = aPluginTag;
|
||||
|
||||
mURL = PL_strdup(url);
|
||||
mInstance = aInstance;
|
||||
if (aInstance)
|
||||
NS_ADDREF(aInstance);
|
||||
mXPConnected = PR_FALSE;
|
||||
mDefaultPlugin = aDefaultPlugin;
|
||||
mStopped = PR_FALSE;
|
||||
mllStopTime = LL_ZERO;
|
||||
}
|
||||
|
||||
nsPluginInstanceTag::~nsPluginInstanceTag()
|
||||
{
|
||||
mPluginTag = nsnull;
|
||||
if (mInstance) {
|
||||
nsCOMPtr<nsIPluginInstanceOwner> owner;
|
||||
mInstance->GetOwner(getter_AddRefs(owner));
|
||||
if (owner)
|
||||
owner->SetInstance(nsnull);
|
||||
mInstance->InvalidateOwner();
|
||||
|
||||
NS_RELEASE(mInstance);
|
||||
}
|
||||
PL_strfree(mURL);
|
||||
}
|
||||
|
||||
void nsPluginInstanceTag::setStopped(PRBool stopped)
|
||||
{
|
||||
mStopped = stopped;
|
||||
if (mStopped) // plugin instance is told to stop
|
||||
mllStopTime = PR_Now();
|
||||
else
|
||||
mllStopTime = LL_ZERO;
|
||||
}
|
||||
|
||||
nsPluginInstanceTagList::nsPluginInstanceTagList()
|
||||
{
|
||||
mFirst = nsnull;
|
||||
mLast = nsnull;
|
||||
mCount = 0;
|
||||
}
|
||||
|
||||
nsPluginInstanceTagList::~nsPluginInstanceTagList()
|
||||
{
|
||||
if (!mFirst)
|
||||
return;
|
||||
shutdown();
|
||||
}
|
||||
|
||||
void nsPluginInstanceTagList::shutdown()
|
||||
{
|
||||
if (!mFirst)
|
||||
return;
|
||||
|
||||
for (nsPluginInstanceTag * plugin = mFirst; plugin != nsnull;) {
|
||||
nsPluginInstanceTag * next = plugin->mNext;
|
||||
remove(plugin);
|
||||
plugin = next;
|
||||
}
|
||||
mFirst = nsnull;
|
||||
mLast = nsnull;
|
||||
}
|
||||
|
||||
PRInt32 nsPluginInstanceTagList::add(nsPluginInstanceTag * plugin)
|
||||
{
|
||||
if (!mFirst) {
|
||||
mFirst = plugin;
|
||||
mLast = plugin;
|
||||
mFirst->mNext = nsnull;
|
||||
}
|
||||
else {
|
||||
mLast->mNext = plugin;
|
||||
mLast = plugin;
|
||||
}
|
||||
mLast->mNext = nsnull;
|
||||
mCount++;
|
||||
return mCount;
|
||||
}
|
||||
|
||||
PRBool nsPluginInstanceTagList::IsLastInstance(nsPluginInstanceTag * plugin)
|
||||
{
|
||||
if (!plugin)
|
||||
return PR_FALSE;
|
||||
|
||||
if (!plugin->mPluginTag)
|
||||
return PR_FALSE;
|
||||
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
if ((p->mPluginTag == plugin->mPluginTag) && (p != plugin))
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool nsPluginInstanceTagList::remove(nsPluginInstanceTag * plugin)
|
||||
{
|
||||
if (!mFirst)
|
||||
return PR_FALSE;
|
||||
|
||||
nsPluginInstanceTag * prev = nsnull;
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
if (p == plugin) {
|
||||
PRBool lastInstance = IsLastInstance(p);
|
||||
|
||||
if (p == mFirst)
|
||||
mFirst = p->mNext;
|
||||
else
|
||||
prev->mNext = p->mNext;
|
||||
|
||||
if (prev && !prev->mNext)
|
||||
mLast = prev;
|
||||
|
||||
if (lastInstance) {
|
||||
nsRefPtr<nsPluginTag> pluginTag = p->mPluginTag;
|
||||
|
||||
delete p;
|
||||
|
||||
if (pluginTag) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrefBranch> pref(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool unloadPluginsASAP = PR_FALSE;
|
||||
rv = pref->GetBoolPref("plugins.unloadASAP", &unloadPluginsASAP);
|
||||
if (NS_SUCCEEDED(rv) && unloadPluginsASAP)
|
||||
pluginTag->TryUnloadPlugin();
|
||||
} else {
|
||||
NS_ASSERTION(pluginTag, "pluginTag was not set, plugin not shutdown");
|
||||
}
|
||||
} else {
|
||||
delete p;
|
||||
}
|
||||
|
||||
mCount--;
|
||||
return PR_TRUE;
|
||||
}
|
||||
prev = p;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// This method terminates all running instances of plugins and collects their
|
||||
// documents to be returned through an array. This method is used
|
||||
// when we are shutting down or when a plugins.refresh(1) happens.
|
||||
// If aPluginTag is given, then only that plugin is terminated
|
||||
void nsPluginInstanceTagList::stopRunning(nsISupportsArray* aReloadDocs,
|
||||
nsPluginTag* aPluginTag)
|
||||
{
|
||||
if (!mFirst)
|
||||
return;
|
||||
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
if (!p->mStopped && p->mInstance &&
|
||||
(!aPluginTag || aPluginTag == p->mPluginTag)) {
|
||||
p->mInstance->SetWindow(nsnull);
|
||||
p->mInstance->Stop();
|
||||
p->setStopped(PR_TRUE);
|
||||
|
||||
// If we've been passed an array to return, lets collect all our documents,
|
||||
// removing duplicates. These will be reframed (embedded) or reloaded (full-page) later
|
||||
// to kickstart our instances.
|
||||
if (aReloadDocs && p->mInstance) {
|
||||
nsCOMPtr<nsIPluginInstanceOwner> owner;
|
||||
p->mInstance->GetOwner(getter_AddRefs(owner));
|
||||
if (owner) {
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
owner->GetDocument(getter_AddRefs(doc));
|
||||
if (doc && aReloadDocs->IndexOf(doc) == -1) // don't allow for duplicates
|
||||
aReloadDocs->AppendElement(doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nsPluginInstanceTagList::removeAllStopped()
|
||||
{
|
||||
if (!mFirst)
|
||||
return;
|
||||
|
||||
nsPluginInstanceTag * next = nsnull;
|
||||
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull;) {
|
||||
next = p->mNext;
|
||||
|
||||
if (p->mStopped)
|
||||
remove(p);
|
||||
|
||||
p = next;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
nsPluginInstanceTag * nsPluginInstanceTagList::find(nsIPluginInstance* instance)
|
||||
{
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
if (p->mInstance == instance)
|
||||
return p;
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsPluginInstanceTag * nsPluginInstanceTagList::find(const char * mimetype)
|
||||
{
|
||||
PRBool defaultplugin = (PL_strcmp(mimetype, "*") == 0);
|
||||
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
// give it some special treatment for the default plugin first
|
||||
// because we cannot tell the default plugin by asking instance for a mime type
|
||||
if (defaultplugin && p->mDefaultPlugin)
|
||||
return p;
|
||||
|
||||
if (!p->mInstance)
|
||||
continue;
|
||||
|
||||
const char* mt;
|
||||
nsresult rv = p->mInstance->GetMIMEType(&mt);
|
||||
if (NS_FAILED(rv))
|
||||
continue;
|
||||
|
||||
if (PL_strcasecmp(mt, mimetype) == 0)
|
||||
return p;
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsPluginInstanceTag * nsPluginInstanceTagList::findStopped(const char * url)
|
||||
{
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
if (!PL_strcmp(url, p->mURL) && p->mStopped)
|
||||
return p;
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
PRUint32 nsPluginInstanceTagList::getStoppedCount()
|
||||
{
|
||||
PRUint32 stoppedCount = 0;
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
if (p->mStopped)
|
||||
stoppedCount++;
|
||||
}
|
||||
return stoppedCount;
|
||||
}
|
||||
|
||||
nsPluginInstanceTag * nsPluginInstanceTagList::findOldestStopped()
|
||||
{
|
||||
nsPluginInstanceTag * res = nsnull;
|
||||
PRInt64 llTime = LL_MAXINT;
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
if (!p->mStopped)
|
||||
continue;
|
||||
|
||||
if (LL_CMP(p->mllStopTime, <, llTime)) {
|
||||
llTime = p->mllStopTime;
|
||||
res = p;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
inline char* new_str(const char* str)
|
||||
{
|
||||
if (str == nsnull)
|
||||
return nsnull;
|
||||
|
||||
char* result = new char[strlen(str) + 1];
|
||||
if (result != nsnull)
|
||||
return strcpy(result, str);
|
||||
return result;
|
||||
}
|
||||
|
||||
nsPluginTag::nsPluginTag(nsPluginTag* aPluginTag)
|
||||
: mPluginHost(nsnull),
|
||||
mName(aPluginTag->mName),
|
||||
mDescription(aPluginTag->mDescription),
|
||||
mVariants(aPluginTag->mVariants),
|
||||
mMimeTypeArray(nsnull),
|
||||
mMimeDescriptionArray(aPluginTag->mMimeDescriptionArray),
|
||||
mExtensionsArray(nsnull),
|
||||
mLibrary(nsnull),
|
||||
mCanUnloadLibrary(PR_TRUE),
|
||||
mXPConnected(PR_FALSE),
|
||||
mIsJavaPlugin(aPluginTag->mIsJavaPlugin),
|
||||
mIsNPRuntimeEnabledJavaPlugin(aPluginTag->mIsNPRuntimeEnabledJavaPlugin),
|
||||
mFileName(aPluginTag->mFileName),
|
||||
mFullPath(aPluginTag->mFullPath),
|
||||
mVersion(aPluginTag->mVersion),
|
||||
mLastModifiedTime(0),
|
||||
mFlags(NS_PLUGIN_FLAG_ENABLED)
|
||||
{
|
||||
if (aPluginTag->mMimeTypeArray != nsnull) {
|
||||
mMimeTypeArray = new char*[mVariants];
|
||||
for (int i = 0; i < mVariants; i++)
|
||||
mMimeTypeArray[i] = new_str(aPluginTag->mMimeTypeArray[i]);
|
||||
}
|
||||
|
||||
if (aPluginTag->mExtensionsArray != nsnull) {
|
||||
mExtensionsArray = new char*[mVariants];
|
||||
for (int i = 0; i < mVariants; i++)
|
||||
mExtensionsArray[i] = new_str(aPluginTag->mExtensionsArray[i]);
|
||||
}
|
||||
}
|
||||
|
||||
nsPluginTag::nsPluginTag(nsPluginInfo* aPluginInfo)
|
||||
: mPluginHost(nsnull),
|
||||
mName(aPluginInfo->fName),
|
||||
mDescription(aPluginInfo->fDescription),
|
||||
mVariants(aPluginInfo->fVariantCount),
|
||||
mMimeTypeArray(nsnull),
|
||||
mExtensionsArray(nsnull),
|
||||
mLibrary(nsnull),
|
||||
#ifdef XP_MACOSX
|
||||
mCanUnloadLibrary(!aPluginInfo->fBundle),
|
||||
#else
|
||||
mCanUnloadLibrary(PR_TRUE),
|
||||
#endif
|
||||
mXPConnected(PR_FALSE),
|
||||
mIsJavaPlugin(PR_FALSE),
|
||||
mIsNPRuntimeEnabledJavaPlugin(PR_FALSE),
|
||||
mFileName(aPluginInfo->fFileName),
|
||||
mFullPath(aPluginInfo->fFullPath),
|
||||
mVersion(aPluginInfo->fVersion),
|
||||
mLastModifiedTime(0),
|
||||
mFlags(NS_PLUGIN_FLAG_ENABLED)
|
||||
{
|
||||
if (aPluginInfo->fMimeTypeArray != nsnull) {
|
||||
mMimeTypeArray = new char*[mVariants];
|
||||
for (int i = 0; i < mVariants; i++) {
|
||||
if (mIsJavaPlugin && aPluginInfo->fMimeTypeArray[i] &&
|
||||
strcmp(aPluginInfo->fMimeTypeArray[i],
|
||||
"application/x-java-vm-npruntime") == 0) {
|
||||
mIsNPRuntimeEnabledJavaPlugin = PR_TRUE;
|
||||
|
||||
// Stop processing here, any mimetypes after the magic "I'm a
|
||||
// NPRuntime enabled Java plugin" mimetype will be ignored.
|
||||
mVariants = i;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
mMimeTypeArray[i] = new_str(aPluginInfo->fMimeTypeArray[i]);
|
||||
if (nsPluginHost::IsJavaMIMEType(mMimeTypeArray[i]))
|
||||
mIsJavaPlugin = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (aPluginInfo->fMimeDescriptionArray != nsnull) {
|
||||
for (int i = 0; i < mVariants; i++) {
|
||||
// we should cut off the list of suffixes which the mime
|
||||
// description string may have, see bug 53895
|
||||
// it is usually in form "some description (*.sf1, *.sf2)"
|
||||
// so we can search for the opening round bracket
|
||||
char cur = '\0';
|
||||
char pre = '\0';
|
||||
char * p = PL_strrchr(aPluginInfo->fMimeDescriptionArray[i], '(');
|
||||
if (p && (p != aPluginInfo->fMimeDescriptionArray[i])) {
|
||||
if ((p - 1) && *(p - 1) == ' ') {
|
||||
pre = *(p - 1);
|
||||
*(p - 1) = '\0';
|
||||
} else {
|
||||
cur = *p;
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
}
|
||||
mMimeDescriptionArray.AppendElement(
|
||||
aPluginInfo->fMimeDescriptionArray[i]);
|
||||
// restore the original string
|
||||
if (cur != '\0')
|
||||
*p = cur;
|
||||
if (pre != '\0')
|
||||
*(p - 1) = pre;
|
||||
}
|
||||
} else {
|
||||
mMimeDescriptionArray.SetLength(mVariants);
|
||||
}
|
||||
|
||||
if (aPluginInfo->fExtensionArray != nsnull) {
|
||||
mExtensionsArray = new char*[mVariants];
|
||||
for (int i = 0; i < mVariants; i++)
|
||||
mExtensionsArray[i] = new_str(aPluginInfo->fExtensionArray[i]);
|
||||
}
|
||||
|
||||
EnsureMembersAreUTF8();
|
||||
}
|
||||
|
||||
nsPluginTag::nsPluginTag(const char* aName,
|
||||
const char* aDescription,
|
||||
const char* aFileName,
|
||||
const char* aFullPath,
|
||||
const char* aVersion,
|
||||
const char* const* aMimeTypes,
|
||||
const char* const* aMimeDescriptions,
|
||||
const char* const* aExtensions,
|
||||
PRInt32 aVariants,
|
||||
PRInt64 aLastModifiedTime,
|
||||
PRBool aCanUnload,
|
||||
PRBool aArgsAreUTF8)
|
||||
: mPluginHost(nsnull),
|
||||
mName(aName),
|
||||
mDescription(aDescription),
|
||||
mVariants(aVariants),
|
||||
mMimeTypeArray(nsnull),
|
||||
mExtensionsArray(nsnull),
|
||||
mLibrary(nsnull),
|
||||
mCanUnloadLibrary(aCanUnload),
|
||||
mXPConnected(PR_FALSE),
|
||||
mIsJavaPlugin(PR_FALSE),
|
||||
mIsNPRuntimeEnabledJavaPlugin(PR_FALSE),
|
||||
mFileName(aFileName),
|
||||
mFullPath(aFullPath),
|
||||
mVersion(aVersion),
|
||||
mLastModifiedTime(aLastModifiedTime),
|
||||
mFlags(0) // Caller will read in our flags from cache
|
||||
{
|
||||
if (aVariants) {
|
||||
mMimeTypeArray = new char*[mVariants];
|
||||
mExtensionsArray = new char*[mVariants];
|
||||
|
||||
for (PRInt32 i = 0; i < aVariants; ++i) {
|
||||
if (mIsJavaPlugin && aMimeTypes[i] &&
|
||||
strcmp(aMimeTypes[i], "application/x-java-vm-npruntime") == 0) {
|
||||
mIsNPRuntimeEnabledJavaPlugin = PR_TRUE;
|
||||
|
||||
// Stop processing here, any mimetypes after the magic "I'm a
|
||||
// NPRuntime enabled Java plugin" mimetype will be ignored.
|
||||
mVariants = i;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
mMimeTypeArray[i] = new_str(aMimeTypes[i]);
|
||||
mMimeDescriptionArray.AppendElement(aMimeDescriptions[i]);
|
||||
mExtensionsArray[i] = new_str(aExtensions[i]);
|
||||
if (nsPluginHost::IsJavaMIMEType(mMimeTypeArray[i]))
|
||||
mIsJavaPlugin = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!aArgsAreUTF8)
|
||||
EnsureMembersAreUTF8();
|
||||
}
|
||||
|
||||
nsPluginTag::~nsPluginTag()
|
||||
{
|
||||
NS_ASSERTION(!mNext, "Risk of exhausting the stack space, bug 486349");
|
||||
|
||||
if (mMimeTypeArray) {
|
||||
for (int i = 0; i < mVariants; i++)
|
||||
delete[] mMimeTypeArray[i];
|
||||
|
||||
delete[] (mMimeTypeArray);
|
||||
mMimeTypeArray = nsnull;
|
||||
}
|
||||
|
||||
if (mExtensionsArray) {
|
||||
for (int i = 0; i < mVariants; i++)
|
||||
delete[] mExtensionsArray[i];
|
||||
|
||||
delete[] (mExtensionsArray);
|
||||
mExtensionsArray = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsPluginTag, nsIPluginTag)
|
||||
|
||||
static nsresult ConvertToUTF8(nsIUnicodeDecoder *aUnicodeDecoder,
|
||||
nsAFlatCString& aString)
|
||||
{
|
||||
PRInt32 numberOfBytes = aString.Length();
|
||||
PRInt32 outUnicodeLen;
|
||||
nsAutoString buffer;
|
||||
nsresult rv = aUnicodeDecoder->GetMaxLength(aString.get(), numberOfBytes,
|
||||
&outUnicodeLen);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!EnsureStringLength(buffer, outUnicodeLen))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
rv = aUnicodeDecoder->Convert(aString.get(), &numberOfBytes,
|
||||
buffer.BeginWriting(), &outUnicodeLen);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
buffer.SetLength(outUnicodeLen);
|
||||
CopyUTF16toUTF8(buffer, aString);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsPluginTag::EnsureMembersAreUTF8()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIPlatformCharset> pcs =
|
||||
do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsIUnicodeDecoder> decoder;
|
||||
nsCOMPtr<nsICharsetConverterManager> ccm =
|
||||
do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCAutoString charset;
|
||||
rv = pcs->GetCharset(kPlatformCharsetSel_FileName, charset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!charset.LowerCaseEqualsLiteral("utf-8")) {
|
||||
rv = ccm->GetUnicodeDecoderRaw(charset.get(), getter_AddRefs(decoder));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
ConvertToUTF8(decoder, mFileName);
|
||||
ConvertToUTF8(decoder, mFullPath);
|
||||
}
|
||||
|
||||
// The description of the plug-in and the various MIME type descriptions
|
||||
// should be encoded in the standard plain text file encoding for this system.
|
||||
// XXX should we add kPlatformCharsetSel_PluginResource?
|
||||
rv = pcs->GetCharset(kPlatformCharsetSel_PlainTextInFile, charset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!charset.LowerCaseEqualsLiteral("utf-8")) {
|
||||
rv = ccm->GetUnicodeDecoderRaw(charset.get(), getter_AddRefs(decoder));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
ConvertToUTF8(decoder, mName);
|
||||
ConvertToUTF8(decoder, mDescription);
|
||||
for (PRUint32 i = 0; i < mMimeDescriptionArray.Length(); ++i) {
|
||||
ConvertToUTF8(decoder, mMimeDescriptionArray[i]);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsPluginTag::SetHost(nsPluginHost * aHost)
|
||||
{
|
||||
mPluginHost = aHost;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginTag::GetDescription(nsACString& aDescription)
|
||||
{
|
||||
aDescription = mDescription;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginTag::GetFilename(nsACString& aFileName)
|
||||
{
|
||||
aFileName = mFileName;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginTag::GetVersion(nsACString& aVersion)
|
||||
{
|
||||
aVersion = mVersion;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginTag::GetName(nsACString& aName)
|
||||
{
|
||||
aName = mName;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginTag::GetDisabled(PRBool* aDisabled)
|
||||
{
|
||||
*aDisabled = !HasFlag(NS_PLUGIN_FLAG_ENABLED);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginTag::SetDisabled(PRBool aDisabled)
|
||||
{
|
||||
if (HasFlag(NS_PLUGIN_FLAG_ENABLED) == !aDisabled)
|
||||
return NS_OK;
|
||||
|
||||
if (aDisabled)
|
||||
UnMark(NS_PLUGIN_FLAG_ENABLED);
|
||||
else
|
||||
Mark(NS_PLUGIN_FLAG_ENABLED);
|
||||
|
||||
mPluginHost->UpdatePluginInfo(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginTag::GetBlocklisted(PRBool* aBlocklisted)
|
||||
{
|
||||
*aBlocklisted = HasFlag(NS_PLUGIN_FLAG_BLOCKLISTED);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginTag::SetBlocklisted(PRBool aBlocklisted)
|
||||
{
|
||||
if (HasFlag(NS_PLUGIN_FLAG_BLOCKLISTED) == aBlocklisted)
|
||||
return NS_OK;
|
||||
|
||||
if (aBlocklisted)
|
||||
Mark(NS_PLUGIN_FLAG_BLOCKLISTED);
|
||||
else
|
||||
UnMark(NS_PLUGIN_FLAG_BLOCKLISTED);
|
||||
|
||||
mPluginHost->UpdatePluginInfo(nsnull);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// helper struct for asynchronous handling of plugin unloading
|
||||
class nsPluginUnloadEvent : public nsRunnable {
|
||||
public:
|
||||
@ -946,7 +330,7 @@ NS_IMETHODIMP nsPluginUnloadEvent::Run()
|
||||
}
|
||||
|
||||
// unload plugin asynchronously if possible, otherwise just unload now
|
||||
nsresult PostPluginUnloadEvent(PRLibrary* aLibrary)
|
||||
nsresult nsPluginHost::PostPluginUnloadEvent(PRLibrary* aLibrary)
|
||||
{
|
||||
nsCOMPtr<nsIRunnable> ev = new nsPluginUnloadEvent(aLibrary);
|
||||
if (ev && NS_SUCCEEDED(NS_DispatchToCurrentThread(ev)))
|
||||
@ -958,99 +342,6 @@ nsresult PostPluginUnloadEvent(PRLibrary* aLibrary)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
void nsPluginTag::TryUnloadPlugin()
|
||||
{
|
||||
if (mEntryPoint) {
|
||||
mEntryPoint->Shutdown();
|
||||
mEntryPoint = nsnull;
|
||||
}
|
||||
|
||||
// before we unload check if we are allowed to, see bug #61388
|
||||
if (mLibrary && mCanUnloadLibrary) {
|
||||
// NPAPI plugins can be unloaded now if they don't use XPConnect
|
||||
if (!mXPConnected) {
|
||||
// unload the plugin asynchronously by posting a PLEvent
|
||||
PostPluginUnloadEvent(mLibrary);
|
||||
}
|
||||
else {
|
||||
// add library to the unused library list to handle it later
|
||||
if (mPluginHost)
|
||||
mPluginHost->AddUnusedLibrary(mLibrary);
|
||||
}
|
||||
}
|
||||
|
||||
// we should zero it anyway, it is going to be unloaded by
|
||||
// CleanUnsedLibraries before we need to call the library
|
||||
// again so the calling code should not be fooled and reload
|
||||
// the library fresh
|
||||
mLibrary = nsnull;
|
||||
|
||||
// Remove mime types added to the category manager
|
||||
// only if we were made 'active' by setting the host
|
||||
if (mPluginHost) {
|
||||
RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginUnregister);
|
||||
}
|
||||
}
|
||||
|
||||
void nsPluginTag::Mark(PRUint32 mask)
|
||||
{
|
||||
PRBool wasEnabled = IsEnabled();
|
||||
mFlags |= mask;
|
||||
// Update entries in the category manager if necessary.
|
||||
if (mPluginHost && wasEnabled != IsEnabled()) {
|
||||
if (wasEnabled)
|
||||
RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginUnregister);
|
||||
else
|
||||
RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginRegister);
|
||||
}
|
||||
}
|
||||
|
||||
void nsPluginTag::UnMark(PRUint32 mask)
|
||||
{
|
||||
PRBool wasEnabled = IsEnabled();
|
||||
mFlags &= ~mask;
|
||||
// Update entries in the category manager if necessary.
|
||||
if (mPluginHost && wasEnabled != IsEnabled()) {
|
||||
if (wasEnabled)
|
||||
RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginUnregister);
|
||||
else
|
||||
RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginRegister);
|
||||
}
|
||||
}
|
||||
|
||||
PRBool nsPluginTag::HasFlag(PRUint32 flag)
|
||||
{
|
||||
return (mFlags & flag) != 0;
|
||||
}
|
||||
|
||||
PRUint32 nsPluginTag::Flags()
|
||||
{
|
||||
return mFlags;
|
||||
}
|
||||
|
||||
PRBool nsPluginTag::IsEnabled()
|
||||
{
|
||||
return HasFlag(NS_PLUGIN_FLAG_ENABLED) && !HasFlag(NS_PLUGIN_FLAG_BLOCKLISTED);
|
||||
}
|
||||
|
||||
PRBool nsPluginTag::Equals(nsPluginTag *aPluginTag)
|
||||
{
|
||||
NS_ENSURE_TRUE(aPluginTag, PR_FALSE);
|
||||
|
||||
if ((!mName.Equals(aPluginTag->mName)) ||
|
||||
(!mDescription.Equals(aPluginTag->mDescription)) ||
|
||||
(mVariants != aPluginTag->mVariants))
|
||||
return PR_FALSE;
|
||||
|
||||
if (mVariants && mMimeTypeArray && aPluginTag->mMimeTypeArray) {
|
||||
for (PRInt32 i = 0; i < mVariants; i++) {
|
||||
if (PL_strcmp(mMimeTypeArray[i], aPluginTag->mMimeTypeArray[i]) != 0)
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
class nsPluginStreamListenerPeer;
|
||||
|
||||
class nsPluginStreamInfo : public nsINPAPIPluginStreamInfo
|
||||
@ -2448,6 +1739,11 @@ nsPluginHost::nsPluginHost()
|
||||
PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("nsPluginHost::ctor\n"));
|
||||
PR_LogFlush();
|
||||
#endif
|
||||
|
||||
#ifdef MAC_CARBON_PLUGINS
|
||||
mVisiblePluginTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
mHiddenPluginTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||
#endif
|
||||
}
|
||||
|
||||
nsPluginHost::~nsPluginHost()
|
||||
@ -2997,7 +2293,7 @@ NS_IMETHODIMP nsPluginHost::InstantiatePluginForChannel(nsIChannel* aChannel,
|
||||
return NewEmbeddedPluginStreamListener(uri, aOwner, nsnull, aListener);
|
||||
}
|
||||
|
||||
// Called by nsPluginInstanceOwner (nsObjectFrame.cpp - embedded case)
|
||||
// Called by nsPluginInstanceOwner
|
||||
NS_IMETHODIMP nsPluginHost::InstantiateEmbeddedPlugin(const char *aMimeType,
|
||||
nsIURI* aURL,
|
||||
nsIPluginInstanceOwner *aOwner)
|
||||
@ -3340,80 +2636,6 @@ nsresult nsPluginHost::AddInstanceToActiveList(nsCOMPtr<nsIPlugin> aPlugin,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsPluginTag::RegisterWithCategoryManager(PRBool aOverrideInternalTypes,
|
||||
nsPluginTag::nsRegisterType aType)
|
||||
{
|
||||
if (!mMimeTypeArray)
|
||||
return;
|
||||
|
||||
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
||||
("nsPluginTag::RegisterWithCategoryManager plugin=%s, removing = %s\n",
|
||||
mFileName.get(), aType == ePluginUnregister ? "yes" : "no"));
|
||||
|
||||
nsCOMPtr<nsICategoryManager> catMan = do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
|
||||
if (!catMan)
|
||||
return;
|
||||
|
||||
const char *contractId = "@mozilla.org/content/plugin/document-loader-factory;1";
|
||||
|
||||
nsCOMPtr<nsIPrefBranch> psvc(do_GetService(NS_PREFSERVICE_CONTRACTID));
|
||||
if (!psvc)
|
||||
return; // NS_ERROR_OUT_OF_MEMORY
|
||||
|
||||
// A preference controls whether or not the full page plugin is disabled for
|
||||
// a particular type. The string must be in the form:
|
||||
// type1,type2,type3,type4
|
||||
// Note: need an actual interface to control this and subsequent disabling
|
||||
// (and other plugin host settings) so applications can reliably disable
|
||||
// plugins - without relying on implementation details such as prefs/category
|
||||
// manager entries.
|
||||
nsXPIDLCString overrideTypes;
|
||||
psvc->GetCharPref("plugin.disable_full_page_plugin_for_types", getter_Copies(overrideTypes));
|
||||
nsCAutoString overrideTypesFormatted;
|
||||
overrideTypesFormatted.Assign(',');
|
||||
overrideTypesFormatted += overrideTypes;
|
||||
overrideTypesFormatted.Append(',');
|
||||
|
||||
nsACString::const_iterator start, end;
|
||||
for (int i = 0; i < mVariants; i++) {
|
||||
if (aType == ePluginUnregister) {
|
||||
nsXPIDLCString value;
|
||||
if (NS_SUCCEEDED(catMan->GetCategoryEntry("Gecko-Content-Viewers",
|
||||
mMimeTypeArray[i],
|
||||
getter_Copies(value)))) {
|
||||
// Only delete the entry if a plugin registered for it
|
||||
if (strcmp(value, contractId) == 0) {
|
||||
catMan->DeleteCategoryEntry("Gecko-Content-Viewers",
|
||||
mMimeTypeArray[i],
|
||||
PR_TRUE);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
overrideTypesFormatted.BeginReading(start);
|
||||
overrideTypesFormatted.EndReading(end);
|
||||
|
||||
nsDependentCString mimeType(mMimeTypeArray[i]);
|
||||
nsCAutoString commaSeparated;
|
||||
commaSeparated.Assign(',');
|
||||
commaSeparated += mimeType;
|
||||
commaSeparated.Append(',');
|
||||
if (!FindInReadable(commaSeparated, start, end)) {
|
||||
catMan->AddCategoryEntry("Gecko-Content-Viewers",
|
||||
mMimeTypeArray[i],
|
||||
contractId,
|
||||
PR_FALSE, /* persist: broken by bug 193031 */
|
||||
aOverrideInternalTypes, /* replace if we're told to */
|
||||
nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
PLUGIN_LOG(PLUGIN_LOG_NOISY,
|
||||
("nsPluginTag::RegisterWithCategoryManager mime=%s, plugin=%s\n",
|
||||
mMimeTypeArray[i], mFileName.get()));
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPluginHost::SetUpPluginInstance(const char *aMimeType,
|
||||
nsIURI *aURL,
|
||||
nsIPluginInstanceOwner *aOwner)
|
||||
@ -3536,9 +2758,14 @@ nsPluginHost::TrySetUpPluginInstance(const char *aMimeType,
|
||||
// it is adreffed here
|
||||
aOwner->SetInstance(instance);
|
||||
|
||||
result = instance->Initialize(aOwner, mimetype); // this should not addref the instance or owner
|
||||
if (NS_FAILED(result)) // except in some cases not Java, see bug 140931
|
||||
return result; // our COM pointer will free the peer
|
||||
// this should not addref the instance or owner
|
||||
// except in some cases not Java, see bug 140931
|
||||
// our COM pointer will free the peer
|
||||
result = instance->Initialize(aOwner, mimetype);
|
||||
if (NS_FAILED(result)) {
|
||||
aOwner->SetInstance(nsnull);
|
||||
return result;
|
||||
}
|
||||
|
||||
// instance and peer will be addreffed here
|
||||
result = AddInstanceToActiveList(plugin, instance, aURL, PR_FALSE);
|
||||
@ -3600,8 +2827,10 @@ nsPluginHost::SetUpDefaultPluginInstance(const char *aMimeType,
|
||||
|
||||
// this should not addref the instance or owner
|
||||
result = instance->Initialize(aOwner, mimetype);
|
||||
if (NS_FAILED(result))
|
||||
if (NS_FAILED(result)) {
|
||||
aOwner->SetInstance(nsnull);
|
||||
return result;
|
||||
}
|
||||
|
||||
// instance will be addreffed here
|
||||
result = AddInstanceToActiveList(plugin, instance, aURL, PR_TRUE);
|
||||
@ -5881,6 +5110,76 @@ nsresult nsPluginHost::AddUnusedLibrary(PRLibrary * aLibrary)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef MAC_CARBON_PLUGINS
|
||||
// Flash requires a minimum of 8 events per second to avoid audio skipping.
|
||||
// Since WebKit uses a hidden plugin event rate of 4 events per second Flash
|
||||
// uses a Carbon timer for WebKit which fires at 8 events per second.
|
||||
#define HIDDEN_PLUGIN_DELAY 125
|
||||
#define VISIBLE_PLUGIN_DELAY 20
|
||||
#endif
|
||||
|
||||
void nsPluginHost::AddIdleTimeTarget(nsIPluginInstanceOwner* objectFrame, PRBool isVisible)
|
||||
{
|
||||
#ifdef MAC_CARBON_PLUGINS
|
||||
nsTObserverArray<nsIPluginInstanceOwner*> *targetArray;
|
||||
if (isVisible) {
|
||||
targetArray = &mVisibleTimerTargets;
|
||||
} else {
|
||||
targetArray = &mHiddenTimerTargets;
|
||||
}
|
||||
|
||||
if (targetArray->Contains(objectFrame)) {
|
||||
return;
|
||||
}
|
||||
|
||||
targetArray->AppendElement(objectFrame);
|
||||
if (targetArray->Length() == 1) {
|
||||
if (isVisible) {
|
||||
mVisiblePluginTimer->InitWithCallback(this, VISIBLE_PLUGIN_DELAY, nsITimer::TYPE_REPEATING_SLACK);
|
||||
} else {
|
||||
mHiddenPluginTimer->InitWithCallback(this, HIDDEN_PLUGIN_DELAY, nsITimer::TYPE_REPEATING_SLACK);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void nsPluginHost::RemoveIdleTimeTarget(nsIPluginInstanceOwner* objectFrame)
|
||||
{
|
||||
#ifdef MAC_CARBON_PLUGINS
|
||||
PRBool visibleRemoved = mVisibleTimerTargets.RemoveElement(objectFrame);
|
||||
if (visibleRemoved && mVisibleTimerTargets.IsEmpty()) {
|
||||
mVisiblePluginTimer->Cancel();
|
||||
}
|
||||
|
||||
PRBool hiddenRemoved = mHiddenTimerTargets.RemoveElement(objectFrame);
|
||||
if (hiddenRemoved && mHiddenTimerTargets.IsEmpty()) {
|
||||
mHiddenPluginTimer->Cancel();
|
||||
}
|
||||
|
||||
NS_ASSERTION(!(hiddenRemoved && visibleRemoved), "Plugin instance received visible and hidden idle event notifications");
|
||||
#endif
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsPluginHost::Notify(nsITimer* timer)
|
||||
{
|
||||
#ifdef MAC_CARBON_PLUGINS
|
||||
if (timer == mVisiblePluginTimer) {
|
||||
nsTObserverArray<nsIPluginInstanceOwner*>::ForwardIterator iter(mVisibleTimerTargets);
|
||||
while (iter.HasMore()) {
|
||||
iter.GetNext()->SendIdleEvent();
|
||||
}
|
||||
return NS_OK;
|
||||
} else if (timer == mHiddenPluginTimer) {
|
||||
nsTObserverArray<nsIPluginInstanceOwner*>::ForwardIterator iter(mHiddenTimerTargets);
|
||||
while (iter.HasMore()) {
|
||||
iter.GetNext()->SendIdleEvent();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult nsPluginStreamListenerPeer::ServeStreamAsFile(nsIRequest *request,
|
||||
nsISupports* aContext)
|
||||
{
|
||||
|
@ -58,132 +58,22 @@
|
||||
#include "nsWeakReference.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsTObserverArray.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsPluginTags.h"
|
||||
|
||||
class nsNPAPIPlugin;
|
||||
class nsIComponentManager;
|
||||
class nsIFile;
|
||||
class nsIChannel;
|
||||
class nsPluginHost;
|
||||
|
||||
// Remember that flags are written out to pluginreg.dat, be careful
|
||||
// changing their meaning.
|
||||
#define NS_PLUGIN_FLAG_ENABLED 0x0001 // is this plugin enabled?
|
||||
// no longer used 0x0002 // reuse only if regenerating pluginreg.dat
|
||||
#define NS_PLUGIN_FLAG_FROMCACHE 0x0004 // this plugintag info was loaded from cache
|
||||
#define NS_PLUGIN_FLAG_UNWANTED 0x0008 // this is an unwanted plugin
|
||||
#define NS_PLUGIN_FLAG_BLOCKLISTED 0x0010 // this is a blocklisted plugin
|
||||
|
||||
// A linked-list of plugin information that is used for instantiating plugins
|
||||
// and reflecting plugin information into JavaScript.
|
||||
class nsPluginTag : public nsIPluginTag
|
||||
{
|
||||
public:
|
||||
enum nsRegisterType {
|
||||
ePluginRegister,
|
||||
ePluginUnregister
|
||||
};
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPLUGINTAG
|
||||
|
||||
nsPluginTag(nsPluginTag* aPluginTag);
|
||||
nsPluginTag(nsPluginInfo* aPluginInfo);
|
||||
nsPluginTag(const char* aName,
|
||||
const char* aDescription,
|
||||
const char* aFileName,
|
||||
const char* aFullPath,
|
||||
const char* aVersion,
|
||||
const char* const* aMimeTypes,
|
||||
const char* const* aMimeDescriptions,
|
||||
const char* const* aExtensions,
|
||||
PRInt32 aVariants,
|
||||
PRInt64 aLastModifiedTime = 0,
|
||||
PRBool aCanUnload = PR_TRUE,
|
||||
PRBool aArgsAreUTF8 = PR_FALSE);
|
||||
~nsPluginTag();
|
||||
|
||||
void SetHost(nsPluginHost * aHost);
|
||||
void TryUnloadPlugin();
|
||||
void Mark(PRUint32 mask);
|
||||
void UnMark(PRUint32 mask);
|
||||
PRBool HasFlag(PRUint32 flag);
|
||||
PRUint32 Flags();
|
||||
PRBool Equals(nsPluginTag* aPluginTag);
|
||||
PRBool IsEnabled();
|
||||
void RegisterWithCategoryManager(PRBool aOverrideInternalTypes,
|
||||
nsRegisterType aType = ePluginRegister);
|
||||
|
||||
nsRefPtr<nsPluginTag> mNext;
|
||||
nsPluginHost *mPluginHost;
|
||||
nsCString mName; // UTF-8
|
||||
nsCString mDescription; // UTF-8
|
||||
PRInt32 mVariants;
|
||||
char **mMimeTypeArray;
|
||||
nsTArray<nsCString> mMimeDescriptionArray; // UTF-8
|
||||
char **mExtensionsArray;
|
||||
PRLibrary *mLibrary;
|
||||
nsCOMPtr<nsIPlugin> mEntryPoint;
|
||||
PRPackedBool mCanUnloadLibrary;
|
||||
PRPackedBool mXPConnected;
|
||||
PRPackedBool mIsJavaPlugin;
|
||||
PRPackedBool mIsNPRuntimeEnabledJavaPlugin;
|
||||
nsCString mFileName; // UTF-8
|
||||
nsCString mFullPath; // UTF-8
|
||||
nsCString mVersion; // UTF-8
|
||||
PRInt64 mLastModifiedTime;
|
||||
private:
|
||||
PRUint32 mFlags;
|
||||
|
||||
nsresult EnsureMembersAreUTF8();
|
||||
};
|
||||
|
||||
struct nsPluginInstanceTag
|
||||
{
|
||||
nsPluginInstanceTag* mNext;
|
||||
char* mURL;
|
||||
nsRefPtr<nsPluginTag> mPluginTag;
|
||||
nsIPluginInstance* mInstance;
|
||||
PRTime mllStopTime;
|
||||
PRPackedBool mStopped;
|
||||
PRPackedBool mDefaultPlugin;
|
||||
PRPackedBool mXPConnected;
|
||||
// Array holding all opened stream listeners for this entry
|
||||
nsCOMPtr <nsISupportsArray> mStreams;
|
||||
|
||||
nsPluginInstanceTag(nsPluginTag* aPluginTag,
|
||||
nsIPluginInstance* aInstance,
|
||||
const char * url,
|
||||
PRBool aDefaultPlugin);
|
||||
~nsPluginInstanceTag();
|
||||
|
||||
void setStopped(PRBool stopped);
|
||||
};
|
||||
|
||||
class nsPluginInstanceTagList
|
||||
{
|
||||
public:
|
||||
nsPluginInstanceTag *mFirst;
|
||||
nsPluginInstanceTag *mLast;
|
||||
PRInt32 mCount;
|
||||
|
||||
nsPluginInstanceTagList();
|
||||
~nsPluginInstanceTagList();
|
||||
|
||||
void shutdown();
|
||||
PRBool add(nsPluginInstanceTag *plugin);
|
||||
PRBool remove(nsPluginInstanceTag *plugin);
|
||||
nsPluginInstanceTag *find(nsIPluginInstance *instance);
|
||||
nsPluginInstanceTag *find(const char *mimetype);
|
||||
nsPluginInstanceTag *findStopped(const char *url);
|
||||
PRUint32 getStoppedCount();
|
||||
nsPluginInstanceTag *findOldestStopped();
|
||||
void removeAllStopped();
|
||||
void stopRunning(nsISupportsArray *aReloadDocs, nsPluginTag *aPluginTag);
|
||||
PRBool IsLastInstance(nsPluginInstanceTag *plugin);
|
||||
};
|
||||
#if defined(XP_MACOSX) && !defined(NP_NO_CARBON)
|
||||
#define MAC_CARBON_PLUGINS
|
||||
#endif
|
||||
|
||||
class nsPluginHost : public nsIPluginHost,
|
||||
public nsIObserver,
|
||||
public nsITimerCallback,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
public:
|
||||
@ -198,6 +88,7 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPLUGINHOST
|
||||
NS_DECL_NSIOBSERVER
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
|
||||
NS_IMETHOD
|
||||
GetURL(nsISupports* pluginInst,
|
||||
@ -266,6 +157,11 @@ public:
|
||||
|
||||
static nsresult GetPrompt(nsIPluginInstanceOwner *aOwner, nsIPrompt **aPrompt);
|
||||
|
||||
static nsresult PostPluginUnloadEvent(PRLibrary* aLibrary);
|
||||
|
||||
void AddIdleTimeTarget(nsIPluginInstanceOwner* objectFrame, PRBool isVisible);
|
||||
void RemoveIdleTimeTarget(nsIPluginInstanceOwner* objectFrame);
|
||||
|
||||
private:
|
||||
nsresult
|
||||
TrySetUpPluginInstance(const char *aMimeType, nsIURI *aURL, nsIPluginInstanceOwner *aOwner);
|
||||
@ -373,6 +269,13 @@ private:
|
||||
// We need to hold a global ptr to ourselves because we register for
|
||||
// two different CIDs for some reason...
|
||||
static nsPluginHost* sInst;
|
||||
|
||||
#ifdef MAC_CARBON_PLUGINS
|
||||
nsCOMPtr<nsITimer> mVisiblePluginTimer;
|
||||
nsTObserverArray<nsIPluginInstanceOwner*> mVisibleTimerTargets;
|
||||
nsCOMPtr<nsITimer> mHiddenPluginTimer;
|
||||
nsTObserverArray<nsIPluginInstanceOwner*> mHiddenTimerTargets;
|
||||
#endif
|
||||
};
|
||||
|
||||
class NS_STACK_CLASS PluginDestructionGuard : protected PRCList
|
||||
|
842
modules/plugin/base/src/nsPluginTags.cpp
Normal file
842
modules/plugin/base/src/nsPluginTags.cpp
Normal file
@ -0,0 +1,842 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** 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
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Sean Echevarria <sean@beatnik.com>
|
||||
* Håkan Waara <hwaara@chello.se>
|
||||
* Josh Aas <josh@mozilla.com>
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
#include "nsPluginTags.h"
|
||||
|
||||
#include "prlink.h"
|
||||
#include "plstr.h"
|
||||
#include "nsIPluginInstanceOwner.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsPluginsDir.h"
|
||||
#include "nsPluginHost.h"
|
||||
#include "nsIUnicodeDecoder.h"
|
||||
#include "nsIPlatformCharset.h"
|
||||
#include "nsICharsetConverterManager.h"
|
||||
#include "nsPluginLogging.h"
|
||||
#include "nsICategoryManager.h"
|
||||
|
||||
inline char* new_str(const char* str)
|
||||
{
|
||||
if (str == nsnull)
|
||||
return nsnull;
|
||||
|
||||
char* result = new char[strlen(str) + 1];
|
||||
if (result != nsnull)
|
||||
return strcpy(result, str);
|
||||
return result;
|
||||
}
|
||||
|
||||
/* nsPluginTag */
|
||||
|
||||
nsPluginTag::nsPluginTag(nsPluginTag* aPluginTag)
|
||||
: mPluginHost(nsnull),
|
||||
mName(aPluginTag->mName),
|
||||
mDescription(aPluginTag->mDescription),
|
||||
mVariants(aPluginTag->mVariants),
|
||||
mMimeTypeArray(nsnull),
|
||||
mMimeDescriptionArray(aPluginTag->mMimeDescriptionArray),
|
||||
mExtensionsArray(nsnull),
|
||||
mLibrary(nsnull),
|
||||
mCanUnloadLibrary(PR_TRUE),
|
||||
mXPConnected(PR_FALSE),
|
||||
mIsJavaPlugin(aPluginTag->mIsJavaPlugin),
|
||||
mIsNPRuntimeEnabledJavaPlugin(aPluginTag->mIsNPRuntimeEnabledJavaPlugin),
|
||||
mFileName(aPluginTag->mFileName),
|
||||
mFullPath(aPluginTag->mFullPath),
|
||||
mVersion(aPluginTag->mVersion),
|
||||
mLastModifiedTime(0),
|
||||
mFlags(NS_PLUGIN_FLAG_ENABLED)
|
||||
{
|
||||
if (aPluginTag->mMimeTypeArray != nsnull) {
|
||||
mMimeTypeArray = new char*[mVariants];
|
||||
for (int i = 0; i < mVariants; i++)
|
||||
mMimeTypeArray[i] = new_str(aPluginTag->mMimeTypeArray[i]);
|
||||
}
|
||||
|
||||
if (aPluginTag->mExtensionsArray != nsnull) {
|
||||
mExtensionsArray = new char*[mVariants];
|
||||
for (int i = 0; i < mVariants; i++)
|
||||
mExtensionsArray[i] = new_str(aPluginTag->mExtensionsArray[i]);
|
||||
}
|
||||
}
|
||||
|
||||
nsPluginTag::nsPluginTag(nsPluginInfo* aPluginInfo)
|
||||
: mPluginHost(nsnull),
|
||||
mName(aPluginInfo->fName),
|
||||
mDescription(aPluginInfo->fDescription),
|
||||
mVariants(aPluginInfo->fVariantCount),
|
||||
mMimeTypeArray(nsnull),
|
||||
mExtensionsArray(nsnull),
|
||||
mLibrary(nsnull),
|
||||
#ifdef XP_MACOSX
|
||||
mCanUnloadLibrary(!aPluginInfo->fBundle),
|
||||
#else
|
||||
mCanUnloadLibrary(PR_TRUE),
|
||||
#endif
|
||||
mXPConnected(PR_FALSE),
|
||||
mIsJavaPlugin(PR_FALSE),
|
||||
mIsNPRuntimeEnabledJavaPlugin(PR_FALSE),
|
||||
mFileName(aPluginInfo->fFileName),
|
||||
mFullPath(aPluginInfo->fFullPath),
|
||||
mVersion(aPluginInfo->fVersion),
|
||||
mLastModifiedTime(0),
|
||||
mFlags(NS_PLUGIN_FLAG_ENABLED)
|
||||
{
|
||||
if (aPluginInfo->fMimeTypeArray != nsnull) {
|
||||
mMimeTypeArray = new char*[mVariants];
|
||||
for (int i = 0; i < mVariants; i++) {
|
||||
if (mIsJavaPlugin && aPluginInfo->fMimeTypeArray[i] &&
|
||||
strcmp(aPluginInfo->fMimeTypeArray[i],
|
||||
"application/x-java-vm-npruntime") == 0) {
|
||||
mIsNPRuntimeEnabledJavaPlugin = PR_TRUE;
|
||||
|
||||
// Stop processing here, any mimetypes after the magic "I'm a
|
||||
// NPRuntime enabled Java plugin" mimetype will be ignored.
|
||||
mVariants = i;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
mMimeTypeArray[i] = new_str(aPluginInfo->fMimeTypeArray[i]);
|
||||
if (nsPluginHost::IsJavaMIMEType(mMimeTypeArray[i]))
|
||||
mIsJavaPlugin = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (aPluginInfo->fMimeDescriptionArray != nsnull) {
|
||||
for (int i = 0; i < mVariants; i++) {
|
||||
// we should cut off the list of suffixes which the mime
|
||||
// description string may have, see bug 53895
|
||||
// it is usually in form "some description (*.sf1, *.sf2)"
|
||||
// so we can search for the opening round bracket
|
||||
char cur = '\0';
|
||||
char pre = '\0';
|
||||
char * p = PL_strrchr(aPluginInfo->fMimeDescriptionArray[i], '(');
|
||||
if (p && (p != aPluginInfo->fMimeDescriptionArray[i])) {
|
||||
if ((p - 1) && *(p - 1) == ' ') {
|
||||
pre = *(p - 1);
|
||||
*(p - 1) = '\0';
|
||||
} else {
|
||||
cur = *p;
|
||||
*p = '\0';
|
||||
}
|
||||
|
||||
}
|
||||
mMimeDescriptionArray.AppendElement(
|
||||
aPluginInfo->fMimeDescriptionArray[i]);
|
||||
// restore the original string
|
||||
if (cur != '\0')
|
||||
*p = cur;
|
||||
if (pre != '\0')
|
||||
*(p - 1) = pre;
|
||||
}
|
||||
} else {
|
||||
mMimeDescriptionArray.SetLength(mVariants);
|
||||
}
|
||||
|
||||
if (aPluginInfo->fExtensionArray != nsnull) {
|
||||
mExtensionsArray = new char*[mVariants];
|
||||
for (int i = 0; i < mVariants; i++)
|
||||
mExtensionsArray[i] = new_str(aPluginInfo->fExtensionArray[i]);
|
||||
}
|
||||
|
||||
EnsureMembersAreUTF8();
|
||||
}
|
||||
|
||||
nsPluginTag::nsPluginTag(const char* aName,
|
||||
const char* aDescription,
|
||||
const char* aFileName,
|
||||
const char* aFullPath,
|
||||
const char* aVersion,
|
||||
const char* const* aMimeTypes,
|
||||
const char* const* aMimeDescriptions,
|
||||
const char* const* aExtensions,
|
||||
PRInt32 aVariants,
|
||||
PRInt64 aLastModifiedTime,
|
||||
PRBool aCanUnload,
|
||||
PRBool aArgsAreUTF8)
|
||||
: mPluginHost(nsnull),
|
||||
mName(aName),
|
||||
mDescription(aDescription),
|
||||
mVariants(aVariants),
|
||||
mMimeTypeArray(nsnull),
|
||||
mExtensionsArray(nsnull),
|
||||
mLibrary(nsnull),
|
||||
mCanUnloadLibrary(aCanUnload),
|
||||
mXPConnected(PR_FALSE),
|
||||
mIsJavaPlugin(PR_FALSE),
|
||||
mIsNPRuntimeEnabledJavaPlugin(PR_FALSE),
|
||||
mFileName(aFileName),
|
||||
mFullPath(aFullPath),
|
||||
mVersion(aVersion),
|
||||
mLastModifiedTime(aLastModifiedTime),
|
||||
mFlags(0) // Caller will read in our flags from cache
|
||||
{
|
||||
if (aVariants) {
|
||||
mMimeTypeArray = new char*[mVariants];
|
||||
mExtensionsArray = new char*[mVariants];
|
||||
|
||||
for (PRInt32 i = 0; i < aVariants; ++i) {
|
||||
if (mIsJavaPlugin && aMimeTypes[i] &&
|
||||
strcmp(aMimeTypes[i], "application/x-java-vm-npruntime") == 0) {
|
||||
mIsNPRuntimeEnabledJavaPlugin = PR_TRUE;
|
||||
|
||||
// Stop processing here, any mimetypes after the magic "I'm a
|
||||
// NPRuntime enabled Java plugin" mimetype will be ignored.
|
||||
mVariants = i;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
mMimeTypeArray[i] = new_str(aMimeTypes[i]);
|
||||
mMimeDescriptionArray.AppendElement(aMimeDescriptions[i]);
|
||||
mExtensionsArray[i] = new_str(aExtensions[i]);
|
||||
if (nsPluginHost::IsJavaMIMEType(mMimeTypeArray[i]))
|
||||
mIsJavaPlugin = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!aArgsAreUTF8)
|
||||
EnsureMembersAreUTF8();
|
||||
}
|
||||
|
||||
nsPluginTag::~nsPluginTag()
|
||||
{
|
||||
NS_ASSERTION(!mNext, "Risk of exhausting the stack space, bug 486349");
|
||||
|
||||
if (mMimeTypeArray) {
|
||||
for (int i = 0; i < mVariants; i++)
|
||||
delete[] mMimeTypeArray[i];
|
||||
|
||||
delete[] (mMimeTypeArray);
|
||||
mMimeTypeArray = nsnull;
|
||||
}
|
||||
|
||||
if (mExtensionsArray) {
|
||||
for (int i = 0; i < mVariants; i++)
|
||||
delete[] mExtensionsArray[i];
|
||||
|
||||
delete[] (mExtensionsArray);
|
||||
mExtensionsArray = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsPluginTag, nsIPluginTag)
|
||||
|
||||
static nsresult ConvertToUTF8(nsIUnicodeDecoder *aUnicodeDecoder,
|
||||
nsAFlatCString& aString)
|
||||
{
|
||||
PRInt32 numberOfBytes = aString.Length();
|
||||
PRInt32 outUnicodeLen;
|
||||
nsAutoString buffer;
|
||||
nsresult rv = aUnicodeDecoder->GetMaxLength(aString.get(), numberOfBytes,
|
||||
&outUnicodeLen);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!EnsureStringLength(buffer, outUnicodeLen))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
rv = aUnicodeDecoder->Convert(aString.get(), &numberOfBytes,
|
||||
buffer.BeginWriting(), &outUnicodeLen);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
buffer.SetLength(outUnicodeLen);
|
||||
CopyUTF16toUTF8(buffer, aString);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsPluginTag::EnsureMembersAreUTF8()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIPlatformCharset> pcs =
|
||||
do_GetService(NS_PLATFORMCHARSET_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsIUnicodeDecoder> decoder;
|
||||
nsCOMPtr<nsICharsetConverterManager> ccm =
|
||||
do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCAutoString charset;
|
||||
rv = pcs->GetCharset(kPlatformCharsetSel_FileName, charset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!charset.LowerCaseEqualsLiteral("utf-8")) {
|
||||
rv = ccm->GetUnicodeDecoderRaw(charset.get(), getter_AddRefs(decoder));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
ConvertToUTF8(decoder, mFileName);
|
||||
ConvertToUTF8(decoder, mFullPath);
|
||||
}
|
||||
|
||||
// The description of the plug-in and the various MIME type descriptions
|
||||
// should be encoded in the standard plain text file encoding for this system.
|
||||
// XXX should we add kPlatformCharsetSel_PluginResource?
|
||||
rv = pcs->GetCharset(kPlatformCharsetSel_PlainTextInFile, charset);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!charset.LowerCaseEqualsLiteral("utf-8")) {
|
||||
rv = ccm->GetUnicodeDecoderRaw(charset.get(), getter_AddRefs(decoder));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
ConvertToUTF8(decoder, mName);
|
||||
ConvertToUTF8(decoder, mDescription);
|
||||
for (PRUint32 i = 0; i < mMimeDescriptionArray.Length(); ++i) {
|
||||
ConvertToUTF8(decoder, mMimeDescriptionArray[i]);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsPluginTag::SetHost(nsPluginHost * aHost)
|
||||
{
|
||||
mPluginHost = aHost;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginTag::GetDescription(nsACString& aDescription)
|
||||
{
|
||||
aDescription = mDescription;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginTag::GetFilename(nsACString& aFileName)
|
||||
{
|
||||
aFileName = mFileName;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginTag::GetVersion(nsACString& aVersion)
|
||||
{
|
||||
aVersion = mVersion;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginTag::GetName(nsACString& aName)
|
||||
{
|
||||
aName = mName;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginTag::GetDisabled(PRBool* aDisabled)
|
||||
{
|
||||
*aDisabled = !HasFlag(NS_PLUGIN_FLAG_ENABLED);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginTag::SetDisabled(PRBool aDisabled)
|
||||
{
|
||||
if (HasFlag(NS_PLUGIN_FLAG_ENABLED) == !aDisabled)
|
||||
return NS_OK;
|
||||
|
||||
if (aDisabled)
|
||||
UnMark(NS_PLUGIN_FLAG_ENABLED);
|
||||
else
|
||||
Mark(NS_PLUGIN_FLAG_ENABLED);
|
||||
|
||||
mPluginHost->UpdatePluginInfo(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginTag::GetBlocklisted(PRBool* aBlocklisted)
|
||||
{
|
||||
*aBlocklisted = HasFlag(NS_PLUGIN_FLAG_BLOCKLISTED);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPluginTag::SetBlocklisted(PRBool aBlocklisted)
|
||||
{
|
||||
if (HasFlag(NS_PLUGIN_FLAG_BLOCKLISTED) == aBlocklisted)
|
||||
return NS_OK;
|
||||
|
||||
if (aBlocklisted)
|
||||
Mark(NS_PLUGIN_FLAG_BLOCKLISTED);
|
||||
else
|
||||
UnMark(NS_PLUGIN_FLAG_BLOCKLISTED);
|
||||
|
||||
mPluginHost->UpdatePluginInfo(nsnull);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsPluginTag::RegisterWithCategoryManager(PRBool aOverrideInternalTypes,
|
||||
nsPluginTag::nsRegisterType aType)
|
||||
{
|
||||
if (!mMimeTypeArray)
|
||||
return;
|
||||
|
||||
PLUGIN_LOG(PLUGIN_LOG_NORMAL,
|
||||
("nsPluginTag::RegisterWithCategoryManager plugin=%s, removing = %s\n",
|
||||
mFileName.get(), aType == ePluginUnregister ? "yes" : "no"));
|
||||
|
||||
nsCOMPtr<nsICategoryManager> catMan = do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
|
||||
if (!catMan)
|
||||
return;
|
||||
|
||||
const char *contractId = "@mozilla.org/content/plugin/document-loader-factory;1";
|
||||
|
||||
nsCOMPtr<nsIPrefBranch> psvc(do_GetService(NS_PREFSERVICE_CONTRACTID));
|
||||
if (!psvc)
|
||||
return; // NS_ERROR_OUT_OF_MEMORY
|
||||
|
||||
// A preference controls whether or not the full page plugin is disabled for
|
||||
// a particular type. The string must be in the form:
|
||||
// type1,type2,type3,type4
|
||||
// Note: need an actual interface to control this and subsequent disabling
|
||||
// (and other plugin host settings) so applications can reliably disable
|
||||
// plugins - without relying on implementation details such as prefs/category
|
||||
// manager entries.
|
||||
nsXPIDLCString overrideTypes;
|
||||
psvc->GetCharPref("plugin.disable_full_page_plugin_for_types", getter_Copies(overrideTypes));
|
||||
nsCAutoString overrideTypesFormatted;
|
||||
overrideTypesFormatted.Assign(',');
|
||||
overrideTypesFormatted += overrideTypes;
|
||||
overrideTypesFormatted.Append(',');
|
||||
|
||||
nsACString::const_iterator start, end;
|
||||
for (int i = 0; i < mVariants; i++) {
|
||||
if (aType == ePluginUnregister) {
|
||||
nsXPIDLCString value;
|
||||
if (NS_SUCCEEDED(catMan->GetCategoryEntry("Gecko-Content-Viewers",
|
||||
mMimeTypeArray[i],
|
||||
getter_Copies(value)))) {
|
||||
// Only delete the entry if a plugin registered for it
|
||||
if (strcmp(value, contractId) == 0) {
|
||||
catMan->DeleteCategoryEntry("Gecko-Content-Viewers",
|
||||
mMimeTypeArray[i],
|
||||
PR_TRUE);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
overrideTypesFormatted.BeginReading(start);
|
||||
overrideTypesFormatted.EndReading(end);
|
||||
|
||||
nsDependentCString mimeType(mMimeTypeArray[i]);
|
||||
nsCAutoString commaSeparated;
|
||||
commaSeparated.Assign(',');
|
||||
commaSeparated += mimeType;
|
||||
commaSeparated.Append(',');
|
||||
if (!FindInReadable(commaSeparated, start, end)) {
|
||||
catMan->AddCategoryEntry("Gecko-Content-Viewers",
|
||||
mMimeTypeArray[i],
|
||||
contractId,
|
||||
PR_FALSE, /* persist: broken by bug 193031 */
|
||||
aOverrideInternalTypes, /* replace if we're told to */
|
||||
nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
PLUGIN_LOG(PLUGIN_LOG_NOISY,
|
||||
("nsPluginTag::RegisterWithCategoryManager mime=%s, plugin=%s\n",
|
||||
mMimeTypeArray[i], mFileName.get()));
|
||||
}
|
||||
}
|
||||
|
||||
void nsPluginTag::Mark(PRUint32 mask)
|
||||
{
|
||||
PRBool wasEnabled = IsEnabled();
|
||||
mFlags |= mask;
|
||||
// Update entries in the category manager if necessary.
|
||||
if (mPluginHost && wasEnabled != IsEnabled()) {
|
||||
if (wasEnabled)
|
||||
RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginUnregister);
|
||||
else
|
||||
RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginRegister);
|
||||
}
|
||||
}
|
||||
|
||||
void nsPluginTag::UnMark(PRUint32 mask)
|
||||
{
|
||||
PRBool wasEnabled = IsEnabled();
|
||||
mFlags &= ~mask;
|
||||
// Update entries in the category manager if necessary.
|
||||
if (mPluginHost && wasEnabled != IsEnabled()) {
|
||||
if (wasEnabled)
|
||||
RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginUnregister);
|
||||
else
|
||||
RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginRegister);
|
||||
}
|
||||
}
|
||||
|
||||
PRBool nsPluginTag::HasFlag(PRUint32 flag)
|
||||
{
|
||||
return (mFlags & flag) != 0;
|
||||
}
|
||||
|
||||
PRUint32 nsPluginTag::Flags()
|
||||
{
|
||||
return mFlags;
|
||||
}
|
||||
|
||||
PRBool nsPluginTag::IsEnabled()
|
||||
{
|
||||
return HasFlag(NS_PLUGIN_FLAG_ENABLED) && !HasFlag(NS_PLUGIN_FLAG_BLOCKLISTED);
|
||||
}
|
||||
|
||||
PRBool nsPluginTag::Equals(nsPluginTag *aPluginTag)
|
||||
{
|
||||
NS_ENSURE_TRUE(aPluginTag, PR_FALSE);
|
||||
|
||||
if ((!mName.Equals(aPluginTag->mName)) ||
|
||||
(!mDescription.Equals(aPluginTag->mDescription)) ||
|
||||
(mVariants != aPluginTag->mVariants))
|
||||
return PR_FALSE;
|
||||
|
||||
if (mVariants && mMimeTypeArray && aPluginTag->mMimeTypeArray) {
|
||||
for (PRInt32 i = 0; i < mVariants; i++) {
|
||||
if (PL_strcmp(mMimeTypeArray[i], aPluginTag->mMimeTypeArray[i]) != 0)
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
void nsPluginTag::TryUnloadPlugin()
|
||||
{
|
||||
if (mEntryPoint) {
|
||||
mEntryPoint->Shutdown();
|
||||
mEntryPoint = nsnull;
|
||||
}
|
||||
|
||||
// before we unload check if we are allowed to, see bug #61388
|
||||
if (mLibrary && mCanUnloadLibrary) {
|
||||
// NPAPI plugins can be unloaded now if they don't use XPConnect
|
||||
if (!mXPConnected) {
|
||||
// unload the plugin asynchronously by posting a PLEvent
|
||||
nsPluginHost::PostPluginUnloadEvent(mLibrary);
|
||||
}
|
||||
else {
|
||||
// add library to the unused library list to handle it later
|
||||
if (mPluginHost)
|
||||
mPluginHost->AddUnusedLibrary(mLibrary);
|
||||
}
|
||||
}
|
||||
|
||||
// we should zero it anyway, it is going to be unloaded by
|
||||
// CleanUnsedLibraries before we need to call the library
|
||||
// again so the calling code should not be fooled and reload
|
||||
// the library fresh
|
||||
mLibrary = nsnull;
|
||||
|
||||
// Remove mime types added to the category manager
|
||||
// only if we were made 'active' by setting the host
|
||||
if (mPluginHost) {
|
||||
RegisterWithCategoryManager(PR_FALSE, nsPluginTag::ePluginUnregister);
|
||||
}
|
||||
}
|
||||
|
||||
/* nsPluginInstanceTag */
|
||||
|
||||
nsPluginInstanceTag::nsPluginInstanceTag(nsPluginTag* aPluginTag,
|
||||
nsIPluginInstance* aInstance,
|
||||
const char * url,
|
||||
PRBool aDefaultPlugin)
|
||||
{
|
||||
mNext = nsnull;
|
||||
mPluginTag = aPluginTag;
|
||||
|
||||
mURL = PL_strdup(url);
|
||||
mInstance = aInstance;
|
||||
if (aInstance)
|
||||
NS_ADDREF(aInstance);
|
||||
mXPConnected = PR_FALSE;
|
||||
mDefaultPlugin = aDefaultPlugin;
|
||||
mStopped = PR_FALSE;
|
||||
mllStopTime = LL_ZERO;
|
||||
}
|
||||
|
||||
nsPluginInstanceTag::~nsPluginInstanceTag()
|
||||
{
|
||||
mPluginTag = nsnull;
|
||||
if (mInstance) {
|
||||
nsCOMPtr<nsIPluginInstanceOwner> owner;
|
||||
mInstance->GetOwner(getter_AddRefs(owner));
|
||||
if (owner)
|
||||
owner->SetInstance(nsnull);
|
||||
mInstance->InvalidateOwner();
|
||||
|
||||
NS_RELEASE(mInstance);
|
||||
}
|
||||
PL_strfree(mURL);
|
||||
}
|
||||
|
||||
void nsPluginInstanceTag::setStopped(PRBool stopped)
|
||||
{
|
||||
mStopped = stopped;
|
||||
if (mStopped) // plugin instance is told to stop
|
||||
mllStopTime = PR_Now();
|
||||
else
|
||||
mllStopTime = LL_ZERO;
|
||||
}
|
||||
|
||||
/* nsPluginInstanceTagList */
|
||||
|
||||
nsPluginInstanceTagList::nsPluginInstanceTagList()
|
||||
{
|
||||
mFirst = nsnull;
|
||||
mLast = nsnull;
|
||||
mCount = 0;
|
||||
}
|
||||
|
||||
nsPluginInstanceTagList::~nsPluginInstanceTagList()
|
||||
{
|
||||
if (!mFirst)
|
||||
return;
|
||||
shutdown();
|
||||
}
|
||||
|
||||
void nsPluginInstanceTagList::shutdown()
|
||||
{
|
||||
if (!mFirst)
|
||||
return;
|
||||
|
||||
for (nsPluginInstanceTag * plugin = mFirst; plugin != nsnull;) {
|
||||
nsPluginInstanceTag * next = plugin->mNext;
|
||||
remove(plugin);
|
||||
plugin = next;
|
||||
}
|
||||
mFirst = nsnull;
|
||||
mLast = nsnull;
|
||||
}
|
||||
|
||||
PRInt32 nsPluginInstanceTagList::add(nsPluginInstanceTag * plugin)
|
||||
{
|
||||
if (!mFirst) {
|
||||
mFirst = plugin;
|
||||
mLast = plugin;
|
||||
mFirst->mNext = nsnull;
|
||||
}
|
||||
else {
|
||||
mLast->mNext = plugin;
|
||||
mLast = plugin;
|
||||
}
|
||||
mLast->mNext = nsnull;
|
||||
mCount++;
|
||||
return mCount;
|
||||
}
|
||||
|
||||
PRBool nsPluginInstanceTagList::IsLastInstance(nsPluginInstanceTag * plugin)
|
||||
{
|
||||
if (!plugin)
|
||||
return PR_FALSE;
|
||||
|
||||
if (!plugin->mPluginTag)
|
||||
return PR_FALSE;
|
||||
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
if ((p->mPluginTag == plugin->mPluginTag) && (p != plugin))
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool nsPluginInstanceTagList::remove(nsPluginInstanceTag * plugin)
|
||||
{
|
||||
if (!mFirst)
|
||||
return PR_FALSE;
|
||||
|
||||
nsPluginInstanceTag * prev = nsnull;
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
if (p == plugin) {
|
||||
PRBool lastInstance = IsLastInstance(p);
|
||||
|
||||
if (p == mFirst)
|
||||
mFirst = p->mNext;
|
||||
else
|
||||
prev->mNext = p->mNext;
|
||||
|
||||
if (prev && !prev->mNext)
|
||||
mLast = prev;
|
||||
|
||||
if (lastInstance) {
|
||||
nsRefPtr<nsPluginTag> pluginTag = p->mPluginTag;
|
||||
|
||||
delete p;
|
||||
|
||||
if (pluginTag) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrefBranch> pref(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRBool unloadPluginsASAP = PR_FALSE;
|
||||
rv = pref->GetBoolPref("plugins.unloadASAP", &unloadPluginsASAP);
|
||||
if (NS_SUCCEEDED(rv) && unloadPluginsASAP)
|
||||
pluginTag->TryUnloadPlugin();
|
||||
} else {
|
||||
NS_ASSERTION(pluginTag, "pluginTag was not set, plugin not shutdown");
|
||||
}
|
||||
} else {
|
||||
delete p;
|
||||
}
|
||||
|
||||
mCount--;
|
||||
return PR_TRUE;
|
||||
}
|
||||
prev = p;
|
||||
}
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// This method terminates all running instances of plugins and collects their
|
||||
// documents to be returned through an array. This method is used
|
||||
// when we are shutting down or when a plugins.refresh(1) happens.
|
||||
// If aPluginTag is given, then only that plugin is terminated
|
||||
void nsPluginInstanceTagList::stopRunning(nsISupportsArray* aReloadDocs,
|
||||
nsPluginTag* aPluginTag)
|
||||
{
|
||||
if (!mFirst)
|
||||
return;
|
||||
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
if (!p->mStopped && p->mInstance &&
|
||||
(!aPluginTag || aPluginTag == p->mPluginTag)) {
|
||||
p->mInstance->SetWindow(nsnull);
|
||||
p->mInstance->Stop();
|
||||
p->setStopped(PR_TRUE);
|
||||
|
||||
// If we've been passed an array to return, lets collect all our documents,
|
||||
// removing duplicates. These will be reframed (embedded) or reloaded (full-page) later
|
||||
// to kickstart our instances.
|
||||
if (aReloadDocs && p->mInstance) {
|
||||
nsCOMPtr<nsIPluginInstanceOwner> owner;
|
||||
p->mInstance->GetOwner(getter_AddRefs(owner));
|
||||
if (owner) {
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
owner->GetDocument(getter_AddRefs(doc));
|
||||
if (doc && aReloadDocs->IndexOf(doc) == -1) // don't allow for duplicates
|
||||
aReloadDocs->AppendElement(doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nsPluginInstanceTagList::removeAllStopped()
|
||||
{
|
||||
if (!mFirst)
|
||||
return;
|
||||
|
||||
nsPluginInstanceTag * next = nsnull;
|
||||
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull;) {
|
||||
next = p->mNext;
|
||||
|
||||
if (p->mStopped)
|
||||
remove(p);
|
||||
|
||||
p = next;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
nsPluginInstanceTag * nsPluginInstanceTagList::find(nsIPluginInstance* instance)
|
||||
{
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
if (p->mInstance == instance)
|
||||
return p;
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsPluginInstanceTag * nsPluginInstanceTagList::find(const char * mimetype)
|
||||
{
|
||||
PRBool defaultplugin = (PL_strcmp(mimetype, "*") == 0);
|
||||
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
// give it some special treatment for the default plugin first
|
||||
// because we cannot tell the default plugin by asking instance for a mime type
|
||||
if (defaultplugin && p->mDefaultPlugin)
|
||||
return p;
|
||||
|
||||
if (!p->mInstance)
|
||||
continue;
|
||||
|
||||
const char* mt;
|
||||
nsresult rv = p->mInstance->GetMIMEType(&mt);
|
||||
if (NS_FAILED(rv))
|
||||
continue;
|
||||
|
||||
if (PL_strcasecmp(mt, mimetype) == 0)
|
||||
return p;
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsPluginInstanceTag * nsPluginInstanceTagList::findStopped(const char * url)
|
||||
{
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
if (!PL_strcmp(url, p->mURL) && p->mStopped)
|
||||
return p;
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
PRUint32 nsPluginInstanceTagList::getStoppedCount()
|
||||
{
|
||||
PRUint32 stoppedCount = 0;
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
if (p->mStopped)
|
||||
stoppedCount++;
|
||||
}
|
||||
return stoppedCount;
|
||||
}
|
||||
|
||||
nsPluginInstanceTag * nsPluginInstanceTagList::findOldestStopped()
|
||||
{
|
||||
nsPluginInstanceTag * res = nsnull;
|
||||
PRInt64 llTime = LL_MAXINT;
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
if (!p->mStopped)
|
||||
continue;
|
||||
|
||||
if (LL_CMP(p->mllStopTime, <, llTime)) {
|
||||
llTime = p->mllStopTime;
|
||||
res = p;
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
172
modules/plugin/base/src/nsPluginTags.h
Normal file
172
modules/plugin/base/src/nsPluginTags.h
Normal file
@ -0,0 +1,172 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** 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
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Josh Aas <josh@mozilla.com>
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
#ifndef nsPluginTags_h_
|
||||
#define nsPluginTags_h_
|
||||
|
||||
#include "nscore.h"
|
||||
#include "prtypes.h"
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIPluginTag.h"
|
||||
#include "nsIPlugin.h"
|
||||
#include "nsIPluginInstance.h"
|
||||
#include "nsISupportsArray.h"
|
||||
|
||||
class nsPluginHost;
|
||||
class PRLibrary;
|
||||
class nsPluginInfo;
|
||||
|
||||
// Remember that flags are written out to pluginreg.dat, be careful
|
||||
// changing their meaning.
|
||||
#define NS_PLUGIN_FLAG_ENABLED 0x0001 // is this plugin enabled?
|
||||
// no longer used 0x0002 // reuse only if regenerating pluginreg.dat
|
||||
#define NS_PLUGIN_FLAG_FROMCACHE 0x0004 // this plugintag info was loaded from cache
|
||||
#define NS_PLUGIN_FLAG_UNWANTED 0x0008 // this is an unwanted plugin
|
||||
#define NS_PLUGIN_FLAG_BLOCKLISTED 0x0010 // this is a blocklisted plugin
|
||||
|
||||
// A linked-list of plugin information that is used for instantiating plugins
|
||||
// and reflecting plugin information into JavaScript.
|
||||
class nsPluginTag : public nsIPluginTag
|
||||
{
|
||||
public:
|
||||
enum nsRegisterType {
|
||||
ePluginRegister,
|
||||
ePluginUnregister
|
||||
};
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPLUGINTAG
|
||||
|
||||
nsPluginTag(nsPluginTag* aPluginTag);
|
||||
nsPluginTag(nsPluginInfo* aPluginInfo);
|
||||
nsPluginTag(const char* aName,
|
||||
const char* aDescription,
|
||||
const char* aFileName,
|
||||
const char* aFullPath,
|
||||
const char* aVersion,
|
||||
const char* const* aMimeTypes,
|
||||
const char* const* aMimeDescriptions,
|
||||
const char* const* aExtensions,
|
||||
PRInt32 aVariants,
|
||||
PRInt64 aLastModifiedTime = 0,
|
||||
PRBool aCanUnload = PR_TRUE,
|
||||
PRBool aArgsAreUTF8 = PR_FALSE);
|
||||
~nsPluginTag();
|
||||
|
||||
void SetHost(nsPluginHost * aHost);
|
||||
void TryUnloadPlugin();
|
||||
void Mark(PRUint32 mask);
|
||||
void UnMark(PRUint32 mask);
|
||||
PRBool HasFlag(PRUint32 flag);
|
||||
PRUint32 Flags();
|
||||
PRBool Equals(nsPluginTag* aPluginTag);
|
||||
PRBool IsEnabled();
|
||||
void RegisterWithCategoryManager(PRBool aOverrideInternalTypes,
|
||||
nsRegisterType aType = ePluginRegister);
|
||||
|
||||
nsRefPtr<nsPluginTag> mNext;
|
||||
nsPluginHost *mPluginHost;
|
||||
nsCString mName; // UTF-8
|
||||
nsCString mDescription; // UTF-8
|
||||
PRInt32 mVariants;
|
||||
char **mMimeTypeArray;
|
||||
nsTArray<nsCString> mMimeDescriptionArray; // UTF-8
|
||||
char **mExtensionsArray;
|
||||
PRLibrary *mLibrary;
|
||||
nsCOMPtr<nsIPlugin> mEntryPoint;
|
||||
PRPackedBool mCanUnloadLibrary;
|
||||
PRPackedBool mXPConnected;
|
||||
PRPackedBool mIsJavaPlugin;
|
||||
PRPackedBool mIsNPRuntimeEnabledJavaPlugin;
|
||||
nsCString mFileName; // UTF-8
|
||||
nsCString mFullPath; // UTF-8
|
||||
nsCString mVersion; // UTF-8
|
||||
PRInt64 mLastModifiedTime;
|
||||
private:
|
||||
PRUint32 mFlags;
|
||||
|
||||
nsresult EnsureMembersAreUTF8();
|
||||
};
|
||||
|
||||
struct nsPluginInstanceTag
|
||||
{
|
||||
nsPluginInstanceTag* mNext;
|
||||
char* mURL;
|
||||
nsRefPtr<nsPluginTag> mPluginTag;
|
||||
nsIPluginInstance* mInstance;
|
||||
PRTime mllStopTime;
|
||||
PRPackedBool mStopped;
|
||||
PRPackedBool mDefaultPlugin;
|
||||
PRPackedBool mXPConnected;
|
||||
// Array holding all opened stream listeners for this entry
|
||||
nsCOMPtr <nsISupportsArray> mStreams;
|
||||
|
||||
nsPluginInstanceTag(nsPluginTag* aPluginTag,
|
||||
nsIPluginInstance* aInstance,
|
||||
const char * url,
|
||||
PRBool aDefaultPlugin);
|
||||
~nsPluginInstanceTag();
|
||||
|
||||
void setStopped(PRBool stopped);
|
||||
};
|
||||
|
||||
class nsPluginInstanceTagList
|
||||
{
|
||||
public:
|
||||
nsPluginInstanceTag *mFirst;
|
||||
nsPluginInstanceTag *mLast;
|
||||
PRInt32 mCount;
|
||||
|
||||
nsPluginInstanceTagList();
|
||||
~nsPluginInstanceTagList();
|
||||
|
||||
void shutdown();
|
||||
PRBool add(nsPluginInstanceTag *plugin);
|
||||
PRBool remove(nsPluginInstanceTag *plugin);
|
||||
nsPluginInstanceTag *find(nsIPluginInstance *instance);
|
||||
nsPluginInstanceTag *find(const char *mimetype);
|
||||
nsPluginInstanceTag *findStopped(const char *url);
|
||||
PRUint32 getStoppedCount();
|
||||
nsPluginInstanceTag *findOldestStopped();
|
||||
void removeAllStopped();
|
||||
void stopRunning(nsISupportsArray *aReloadDocs, nsPluginTag *aPluginTag);
|
||||
PRBool IsLastInstance(nsPluginInstanceTag *plugin);
|
||||
};
|
||||
|
||||
#endif // nsPluginTags_h_
|
@ -52,18 +52,23 @@ interface nsIChannel;
|
||||
* list is changed, or a cookie is rejected:
|
||||
*
|
||||
* topic : "cookie-changed"
|
||||
* broadcast whenever the cookie list changes in some way. there
|
||||
* are four possible data strings for this notification; one
|
||||
* notification will be broadcast for each change, and will involve
|
||||
* a single cookie.
|
||||
* subject: an nsICookie2 interface pointer representing the cookie object
|
||||
* that changed.
|
||||
* broadcast whenever the cookie list changes in some way. see
|
||||
* explanation of data strings below.
|
||||
* subject: see below.
|
||||
* data : "deleted"
|
||||
* a cookie was deleted. the subject is the deleted cookie.
|
||||
* a cookie was deleted. the subject is an nsICookie2 representing
|
||||
* the deleted cookie.
|
||||
* "added"
|
||||
* a cookie was added. the subject is the added cookie.
|
||||
* a cookie was added. the subject is an nsICookie2 representing
|
||||
* the added cookie.
|
||||
* "changed"
|
||||
* a cookie was changed. the subject is the new cookie.
|
||||
* a cookie was changed. the subject is an nsICookie2 representing
|
||||
* the new cookie. (note that host, path, and name are invariant
|
||||
* for a given cookie; other parameters may change.)
|
||||
* "batch-deleted"
|
||||
* a batch of cookies was deleted (for instance, as part of a purging
|
||||
* operation). the subject is an nsIArray of nsICookie2's representing
|
||||
* the deleted cookies.
|
||||
* "cleared"
|
||||
* the entire cookie list was cleared. the subject is null.
|
||||
* "reload"
|
||||
@ -85,9 +90,11 @@ interface nsICookieService : nsISupports
|
||||
* @param aURI
|
||||
* the URI of the document for which cookies are being queried.
|
||||
* @param aChannel
|
||||
* the channel used to load the document. this parameter may be null,
|
||||
* but it is strongly recommended that a non-null value be provided to
|
||||
* ensure that the cookie privacy preferences are honored.
|
||||
* the channel used to load the document. this parameter should not
|
||||
* be null, otherwise the cookies will not be returned if third-party
|
||||
* cookies have been disabled by the user. (the channel is used
|
||||
* to determine the originating URI of the document; if it is not
|
||||
* provided, the cookies will be assumed third-party.)
|
||||
*
|
||||
* @return the resulting cookie string
|
||||
*/
|
||||
@ -105,9 +112,11 @@ interface nsICookieService : nsISupports
|
||||
* the URI that the user originally typed in or clicked on to initiate
|
||||
* the load of the document referenced by aURI.
|
||||
* @param aChannel
|
||||
* the channel used to load the document. this parameter may be null,
|
||||
* but it is strongly recommended that a non-null value be provided to
|
||||
* ensure that the cookie privacy preferences are honored.
|
||||
* the channel used to load the document. this parameter should not
|
||||
* be null, otherwise the cookies will not be returned if third-party
|
||||
* cookies have been disabled by the user. (the channel is used
|
||||
* to determine the originating URI of the document; if it is not
|
||||
* provided, the cookies will be assumed third-party.)
|
||||
*
|
||||
* @return the resulting cookie string
|
||||
*/
|
||||
@ -123,9 +132,11 @@ interface nsICookieService : nsISupports
|
||||
* @param aCookie
|
||||
* the cookie string to set.
|
||||
* @param aChannel
|
||||
* the channel used to load the document. this parameter may be null,
|
||||
* but it is strongly recommended that a non-null value be provided to
|
||||
* ensure that the cookie privacy preferences are honored.
|
||||
* the channel used to load the document. this parameter should not
|
||||
* be null, otherwise the cookies will not be set if third-party
|
||||
* cookies have been disabled by the user. (the channel is used
|
||||
* to determine the originating URI of the document; if it is not
|
||||
* provided, the cookies will be assumed third-party.)
|
||||
*
|
||||
* XXX should be able to allow null aPrompt, since nsIPrompt can be queryied
|
||||
* from aChannel.
|
||||
@ -151,9 +162,11 @@ interface nsICookieService : nsISupports
|
||||
* the expiry information of the cookie (the Date header from the HTTP
|
||||
* response).
|
||||
* @param aChannel
|
||||
* the channel used to load the document. this parameter may be null,
|
||||
* but it is strongly recommended that a non-null value be provided to
|
||||
* ensure that the cookie privacy preferences are honored.
|
||||
* the channel used to load the document. this parameter should not
|
||||
* be null, otherwise the cookies will not be set if third-party
|
||||
* cookies have been disabled by the user. (the channel is used
|
||||
* to determine the originating URI of the document; if it is not
|
||||
* provided, the cookies will be assumed third-party.)
|
||||
*/
|
||||
void setCookieStringFromHttp(in nsIURI aURI, in nsIURI aFirstURI, in nsIPrompt aPrompt, in string aCookie, in string aServerTime, in nsIChannel aChannel);
|
||||
};
|
||||
|
@ -55,7 +55,9 @@
|
||||
#include "nsILineInputStream.h"
|
||||
#include "nsIEffectiveTLDService.h"
|
||||
|
||||
#include "nsTArray.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsIMutableArray.h"
|
||||
#include "nsArrayEnumerator.h"
|
||||
#include "nsEnumeratorUtils.h"
|
||||
#include "nsAutoPtr.h"
|
||||
@ -85,12 +87,16 @@ static const char kCookieFileName[] = "cookies.sqlite";
|
||||
#define COOKIES_SCHEMA_VERSION 2
|
||||
|
||||
static const PRInt64 kCookieStaleThreshold = 60 * PR_USEC_PER_SEC; // 1 minute in microseconds
|
||||
static const PRInt64 kCookiePurgeAge = 30 * 24 * 60 * 60 * PR_USEC_PER_SEC; // 30 days in microseconds
|
||||
|
||||
static const char kOldCookieFileName[] = "cookies.txt";
|
||||
|
||||
#undef LIMIT
|
||||
#define LIMIT(x, low, high, default) ((x) >= (low) && (x) <= (high) ? (x) : (default))
|
||||
|
||||
#undef ADD_TEN_PERCENT
|
||||
#define ADD_TEN_PERCENT(i) ((i) + (i)/10)
|
||||
|
||||
// default limits for the cookie list. these can be tuned by the
|
||||
// network.cookie.maxNumber and network.cookie.maxPerHost prefs respectively.
|
||||
static const PRUint32 kMaxNumberOfCookies = 3000;
|
||||
@ -116,6 +122,7 @@ static const PRUint32 BEHAVIOR_REJECT = 2;
|
||||
static const char kPrefCookiesPermissions[] = "network.cookie.cookieBehavior";
|
||||
static const char kPrefMaxNumberOfCookies[] = "network.cookie.maxNumber";
|
||||
static const char kPrefMaxCookiesPerHost[] = "network.cookie.maxPerHost";
|
||||
static const char kPrefCookiePurgeAge[] = "network.cookie.purgeAge";
|
||||
|
||||
// struct for temporarily storing cookie attributes during header parsing
|
||||
struct nsCookieAttributes
|
||||
@ -206,7 +213,13 @@ static PRLogModuleInfo *sCookieLog = PR_NewLogModule("cookie");
|
||||
|
||||
#define COOKIE_LOGFAILURE(a, b, c, d) LogFailure(a, b, c, d)
|
||||
#define COOKIE_LOGSUCCESS(a, b, c, d, e) LogSuccess(a, b, c, d, e)
|
||||
#define COOKIE_LOGEVICTED(a) LogEvicted(a)
|
||||
|
||||
#define COOKIE_LOGEVICTED(a) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (PR_LOG_TEST(sCookieLog, PR_LOG_DEBUG)) \
|
||||
LogEvicted(a); \
|
||||
PR_END_MACRO
|
||||
|
||||
#define COOKIE_LOGSTRING(lvl, fmt) \
|
||||
PR_BEGIN_MACRO \
|
||||
PR_LOG(sCookieLog, lvl, fmt); \
|
||||
@ -299,11 +312,6 @@ LogSuccess(PRBool aSetCookie, nsIURI *aHostURI, const char *aCookieString, nsCoo
|
||||
static void
|
||||
LogEvicted(nsCookie *aCookie)
|
||||
{
|
||||
// if logging isn't enabled, return now to save cycles
|
||||
if (!PR_LOG_TEST(sCookieLog, PR_LOG_DEBUG)) {
|
||||
return;
|
||||
}
|
||||
|
||||
PR_LOG(sCookieLog, PR_LOG_DEBUG,("===== COOKIE EVICTED =====\n"));
|
||||
|
||||
LogCookie(aCookie);
|
||||
@ -380,6 +388,7 @@ nsCookieService::nsCookieService()
|
||||
, mCookiesPermissions(BEHAVIOR_ACCEPT)
|
||||
, mMaxNumberOfCookies(kMaxNumberOfCookies)
|
||||
, mMaxCookiesPerHost(kMaxCookiesPerHost)
|
||||
, mCookiePurgeAge(kCookiePurgeAge)
|
||||
{
|
||||
}
|
||||
|
||||
@ -400,6 +409,7 @@ nsCookieService::Init()
|
||||
prefBranch->AddObserver(kPrefCookiesPermissions, this, PR_TRUE);
|
||||
prefBranch->AddObserver(kPrefMaxNumberOfCookies, this, PR_TRUE);
|
||||
prefBranch->AddObserver(kPrefMaxCookiesPerHost, this, PR_TRUE);
|
||||
prefBranch->AddObserver(kPrefCookiePurgeAge, this, PR_TRUE);
|
||||
PrefChanged(prefBranch);
|
||||
}
|
||||
|
||||
@ -691,6 +701,7 @@ nsCookieService::Observe(nsISupports *aSubject,
|
||||
|
||||
NS_ASSERTION(mDBState == &mDefaultDBState, "already in private state");
|
||||
NS_ASSERTION(mPrivateDBState.cookieCount == 0, "private count not 0");
|
||||
NS_ASSERTION(mPrivateDBState.cookieOldestTime == LL_MAXINT, "private time not reset");
|
||||
NS_ASSERTION(mPrivateDBState.hostTable.Count() == 0, "private table not empty");
|
||||
NS_ASSERTION(mPrivateDBState.dbConn == NULL, "private DB connection not null");
|
||||
|
||||
@ -706,6 +717,7 @@ nsCookieService::Observe(nsISupports *aSubject,
|
||||
NS_ASSERTION(!mPrivateDBState.dbConn, "private DB connection not null");
|
||||
|
||||
mPrivateDBState.cookieCount = 0;
|
||||
mPrivateDBState.cookieOldestTime = LL_MAXINT;
|
||||
if (mPrivateDBState.hostTable.IsInitialized())
|
||||
mPrivateDBState.hostTable.Clear();
|
||||
|
||||
@ -812,18 +824,20 @@ nsCookieService::NotifyRejected(nsIURI *aHostURI)
|
||||
mObserverService->NotifyObservers(aHostURI, "cookie-rejected", nsnull);
|
||||
}
|
||||
|
||||
// notify observers that the cookie list changed. there are four possible
|
||||
// notify observers that the cookie list changed. there are five possible
|
||||
// values for aData:
|
||||
// "deleted" means a cookie was deleted. aCookie is the deleted cookie.
|
||||
// "added" means a cookie was added. aCookie is the added cookie.
|
||||
// "changed" means a cookie was altered. aCookie is the new cookie.
|
||||
// "cleared" means the entire cookie list was cleared. aCookie is null.
|
||||
// "deleted" means a cookie was deleted. aSubject is the deleted cookie.
|
||||
// "added" means a cookie was added. aSubject is the added cookie.
|
||||
// "changed" means a cookie was altered. aSubject is the new cookie.
|
||||
// "cleared" means the entire cookie list was cleared. aSubject is null.
|
||||
// "batch-deleted" means multiple cookies were deleted. aSubject is the list of
|
||||
// cookies.
|
||||
void
|
||||
nsCookieService::NotifyChanged(nsICookie2 *aCookie,
|
||||
nsCookieService::NotifyChanged(nsISupports *aSubject,
|
||||
const PRUnichar *aData)
|
||||
{
|
||||
if (mObserverService)
|
||||
mObserverService->NotifyObservers(aCookie, "cookie-changed", aData);
|
||||
mObserverService->NotifyObservers(aSubject, "cookie-changed", aData);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@ -843,6 +857,9 @@ nsCookieService::PrefChanged(nsIPrefBranch *aPrefBranch)
|
||||
|
||||
if (NS_SUCCEEDED(aPrefBranch->GetIntPref(kPrefMaxCookiesPerHost, &val)))
|
||||
mMaxCookiesPerHost = (PRUint16) LIMIT(val, 1, 0xFFFF, kMaxCookiesPerHost);
|
||||
|
||||
if (NS_SUCCEEDED(aPrefBranch->GetIntPref(kPrefCookiePurgeAge, &val)))
|
||||
mCookiePurgeAge = LIMIT(val, 0, PR_INT32_MAX, PR_INT32_MAX) * PR_USEC_PER_SEC;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
@ -938,7 +955,7 @@ nsCookieService::Add(const nsACString &aDomain,
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
AddInternal(cookie, currentTimeInUsec / PR_USEC_PER_SEC, nsnull, nsnull, PR_TRUE);
|
||||
AddInternal(cookie, currentTimeInUsec, nsnull, nsnull, PR_TRUE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -1182,7 +1199,7 @@ nsCookieService::ImportCookies(nsIFile *aCookieFile)
|
||||
if (originalCookieCount == 0)
|
||||
AddCookieToList(newCookie);
|
||||
else
|
||||
AddInternal(newCookie, currentTime, nsnull, nsnull, PR_TRUE);
|
||||
AddInternal(newCookie, currentTimeInUsec, nsnull, nsnull, PR_TRUE);
|
||||
}
|
||||
|
||||
COOKIE_LOGSTRING(PR_LOG_DEBUG, ("ImportCookies(): %ld cookies imported", mDBState->cookieCount));
|
||||
@ -1199,25 +1216,28 @@ nsCookieService::ImportCookies(nsIFile *aCookieFile)
|
||||
static inline PRBool ispathdelimiter(char c) { return c == '/' || c == '?' || c == '#' || c == ';'; }
|
||||
|
||||
// Comparator class for sorting cookies before sending to a server.
|
||||
class CompareCookiesForSendingComparator
|
||||
class CompareCookiesForSending
|
||||
{
|
||||
public:
|
||||
PRBool Equals(const nsCookie* aCookie1, const nsCookie* aCookie2) const {
|
||||
return PR_FALSE; // CreationID is unique, so two id's can never be equal.
|
||||
public:
|
||||
PRBool Equals(const nsCookie* aCookie1, const nsCookie* aCookie2) const
|
||||
{
|
||||
// CreationID is unique, so two id's can never be equal.
|
||||
return PR_FALSE;
|
||||
}
|
||||
PRBool LessThan(const nsCookie* aCookie1, const nsCookie* aCookie2) const {
|
||||
|
||||
PRBool LessThan(const nsCookie* aCookie1, const nsCookie* aCookie2) const
|
||||
{
|
||||
// compare by cookie path length in accordance with RFC2109
|
||||
int rv = aCookie2->Path().Length() - aCookie1->Path().Length();
|
||||
if (rv == 0) {
|
||||
// when path lengths match, older cookies should be listed first. this is
|
||||
// required for backwards compatibility since some websites erroneously
|
||||
// depend on receiving cookies in the order in which they were sent to the
|
||||
// browser! see bug 236772.
|
||||
// note: CreationID is unique, so two id's can never be equal.
|
||||
// we may have overflow problems returning the result directly, so we need branches
|
||||
rv = (aCookie1->CreationID() > aCookie2->CreationID() ? 1 : -1);
|
||||
}
|
||||
return rv < 0;
|
||||
PRInt32 result = aCookie2->Path().Length() - aCookie1->Path().Length();
|
||||
if (result != 0)
|
||||
return result < 0;
|
||||
|
||||
// when path lengths match, older cookies should be listed first. this is
|
||||
// required for backwards compatibility since some websites erroneously
|
||||
// depend on receiving cookies in the order in which they were sent to the
|
||||
// browser! see bug 236772.
|
||||
// note: CreationID is unique, so two id's can never be equal.
|
||||
return aCookie1->CreationID() < aCookie2->CreationID();
|
||||
}
|
||||
};
|
||||
|
||||
@ -1358,7 +1378,7 @@ nsCookieService::GetCookieInternal(nsIURI *aHostURI,
|
||||
// return cookies in order of path length; longest to shortest.
|
||||
// this is required per RFC2109. if cookies match in length,
|
||||
// then sort by creation time (see bug 236772).
|
||||
foundCookieList.Sort(CompareCookiesForSendingComparator());
|
||||
foundCookieList.Sort(CompareCookiesForSending());
|
||||
|
||||
nsCAutoString cookieData;
|
||||
for (PRInt32 i = 0; i < count; ++i) {
|
||||
@ -1481,7 +1501,7 @@ nsCookieService::SetCookieInternal(nsIURI *aHostURI,
|
||||
|
||||
// add the cookie to the list. AddInternal() takes care of logging.
|
||||
// we get the current time again here, since it may have changed during prompting
|
||||
AddInternal(cookie, PR_Now() / PR_USEC_PER_SEC, aHostURI, savedCookieHeader.get(), aFromHttp);
|
||||
AddInternal(cookie, PR_Now(), aHostURI, savedCookieHeader.get(), aFromHttp);
|
||||
return newCookie;
|
||||
}
|
||||
|
||||
@ -1492,11 +1512,13 @@ nsCookieService::SetCookieInternal(nsIURI *aHostURI,
|
||||
// reached). also performs list maintenance by removing expired cookies.
|
||||
void
|
||||
nsCookieService::AddInternal(nsCookie *aCookie,
|
||||
PRInt64 aCurrentTime,
|
||||
PRInt64 aCurrentTimeInUsec,
|
||||
nsIURI *aHostURI,
|
||||
const char *aCookieHeader,
|
||||
PRBool aFromHttp)
|
||||
{
|
||||
PRInt64 currentTime = aCurrentTimeInUsec / PR_USEC_PER_SEC;
|
||||
|
||||
// if the new cookie is httponly, make sure we're not coming from script
|
||||
if (!aFromHttp && aCookie->IsHttpOnly()) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieHeader, "cookie is httponly; coming from script");
|
||||
@ -1510,7 +1532,7 @@ nsCookieService::AddInternal(nsCookie *aCookie,
|
||||
|
||||
nsListIter matchIter;
|
||||
PRBool foundCookie = FindCookie(aCookie->Host(), aCookie->Name(), aCookie->Path(),
|
||||
matchIter, aCurrentTime);
|
||||
matchIter, currentTime);
|
||||
|
||||
nsRefPtr<nsCookie> oldCookie;
|
||||
if (foundCookie) {
|
||||
@ -1525,7 +1547,7 @@ nsCookieService::AddInternal(nsCookie *aCookie,
|
||||
RemoveCookieFromList(matchIter);
|
||||
|
||||
// check if the cookie has expired
|
||||
if (aCookie->Expiry() <= aCurrentTime) {
|
||||
if (aCookie->Expiry() <= currentTime) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieHeader, "previously stored cookie was deleted");
|
||||
NotifyChanged(oldCookie, NS_LITERAL_STRING("deleted").get());
|
||||
return;
|
||||
@ -1537,36 +1559,33 @@ nsCookieService::AddInternal(nsCookie *aCookie,
|
||||
|
||||
} else {
|
||||
// check if cookie has already expired
|
||||
if (aCookie->Expiry() <= aCurrentTime) {
|
||||
if (aCookie->Expiry() <= currentTime) {
|
||||
COOKIE_LOGFAILURE(SET_COOKIE, aHostURI, aCookieHeader, "cookie has already expired");
|
||||
return;
|
||||
}
|
||||
|
||||
// check if we have to delete an old cookie.
|
||||
nsEnumerationData data(aCurrentTime, LL_MAXINT);
|
||||
nsEnumerationData data(currentTime, LL_MAXINT);
|
||||
if (CountCookiesFromHostInternal(aCookie->RawHost(), data) >= mMaxCookiesPerHost) {
|
||||
// remove the oldest cookie from host
|
||||
oldCookie = data.iter.current;
|
||||
COOKIE_LOGEVICTED(oldCookie);
|
||||
RemoveCookieFromList(data.iter);
|
||||
|
||||
} else if (mDBState->cookieCount >= mMaxNumberOfCookies) {
|
||||
// try to make room, by removing expired cookies
|
||||
RemoveExpiredCookies(aCurrentTime);
|
||||
|
||||
// check if we still have to get rid of something
|
||||
if (mDBState->cookieCount >= mMaxNumberOfCookies) {
|
||||
// find the position of the oldest cookie, and remove it
|
||||
data.oldestTime = LL_MAXINT;
|
||||
FindOldestCookie(data);
|
||||
oldCookie = data.iter.current;
|
||||
RemoveCookieFromList(data.iter);
|
||||
}
|
||||
}
|
||||
|
||||
// if we deleted an old cookie, notify consumers
|
||||
if (oldCookie) {
|
||||
COOKIE_LOGEVICTED(oldCookie);
|
||||
NotifyChanged(oldCookie, NS_LITERAL_STRING("deleted").get());
|
||||
|
||||
} else if (mDBState->cookieCount >= ADD_TEN_PERCENT(mMaxNumberOfCookies)) {
|
||||
PRInt64 maxAge = aCurrentTimeInUsec - mDBState->cookieOldestTime;
|
||||
PRInt64 purgeAge = ADD_TEN_PERCENT(mCookiePurgeAge);
|
||||
if (maxAge >= purgeAge) {
|
||||
// we're over both size and age limits by 10%; time to purge the table!
|
||||
// do this by:
|
||||
// 1) removing expired cookies;
|
||||
// 2) evicting the balance of old cookies, until we reach the size limit.
|
||||
// note that the cookieOldestTime indicator can be pessimistic - if it's
|
||||
// older than the actual oldest cookie, we'll just purge more eagerly.
|
||||
PurgeCookies(aCurrentTimeInUsec);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2124,35 +2143,159 @@ nsCookieService::RemoveAllFromMemory()
|
||||
// which releases all their respective children.
|
||||
mDBState->hostTable.Clear();
|
||||
mDBState->cookieCount = 0;
|
||||
mDBState->cookieOldestTime = LL_MAXINT;
|
||||
}
|
||||
|
||||
PLDHashOperator
|
||||
removeExpiredCallback(nsCookieEntry *aEntry,
|
||||
void *aArg)
|
||||
// stores temporary data for enumerating over the hash entries,
|
||||
// since enumeration is done using callback functions
|
||||
struct nsPurgeData
|
||||
{
|
||||
const PRInt64 ¤tTime = *static_cast<PRInt64*>(aArg);
|
||||
nsPurgeData(PRInt64 aCurrentTime,
|
||||
PRInt64 aPurgeTime,
|
||||
nsTArray<nsListIter> &aPurgeList,
|
||||
nsIMutableArray *aRemovedList)
|
||||
: currentTime(aCurrentTime)
|
||||
, purgeTime(aPurgeTime)
|
||||
, oldestTime(LL_MAXINT)
|
||||
, purgeList(aPurgeList)
|
||||
, removedList(aRemovedList) {}
|
||||
|
||||
// the current time, in seconds
|
||||
PRInt64 currentTime;
|
||||
|
||||
// lastAccessed time older than which cookies are eligible for purge
|
||||
PRInt64 purgeTime;
|
||||
|
||||
// lastAccessed time of the oldest cookie found during purge, to update our indicator
|
||||
PRInt64 oldestTime;
|
||||
|
||||
// list of cookies over the age limit, for purging
|
||||
nsTArray<nsListIter> &purgeList;
|
||||
|
||||
// list of all cookies we've removed, for notification
|
||||
nsIMutableArray *removedList;
|
||||
};
|
||||
|
||||
// comparator class for lastaccessed times of cookies.
|
||||
class CompareCookiesByAge {
|
||||
public:
|
||||
PRBool Equals(const nsListIter &a, const nsListIter &b) const
|
||||
{
|
||||
// CreationID is unique, so two id's can never be equal.
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool LessThan(const nsListIter &a, const nsListIter &b) const
|
||||
{
|
||||
// compare by LastAccessed time, and tiebreak by CreationID.
|
||||
PRInt64 result = a.current->LastAccessed() - b.current->LastAccessed();
|
||||
if (result != 0)
|
||||
return result < 0;
|
||||
|
||||
return a.current->CreationID() < b.current->CreationID();
|
||||
}
|
||||
};
|
||||
|
||||
PLDHashOperator
|
||||
purgeCookiesCallback(nsCookieEntry *aEntry,
|
||||
void *aArg)
|
||||
{
|
||||
nsPurgeData &data = *static_cast<nsPurgeData*>(aArg);
|
||||
for (nsListIter iter(aEntry, nsnull, aEntry->Head()); iter.current; ) {
|
||||
if (iter.current->Expiry() <= currentTime)
|
||||
// check if the cookie has expired
|
||||
if (iter.current->Expiry() <= data.currentTime) {
|
||||
nsCookie *cookie = iter.current;
|
||||
data.removedList->AppendElement(cookie, PR_FALSE);
|
||||
COOKIE_LOGEVICTED(cookie);
|
||||
|
||||
// remove from list. this takes care of updating the iterator for us
|
||||
nsCookieService::gCookieService->RemoveCookieFromList(iter);
|
||||
else
|
||||
|
||||
} else {
|
||||
// check if the cookie is over the age limit
|
||||
if (iter.current->LastAccessed() <= data.purgeTime) {
|
||||
data.purgeList.AppendElement(iter);
|
||||
|
||||
} else if (iter.current->LastAccessed() < data.oldestTime) {
|
||||
// reset our indicator
|
||||
data.oldestTime = iter.current->LastAccessed();
|
||||
}
|
||||
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
// removes any expired cookies from memory
|
||||
// purges expired and old cookies in a batch operation.
|
||||
void
|
||||
nsCookieService::RemoveExpiredCookies(PRInt64 aCurrentTime)
|
||||
nsCookieService::PurgeCookies(PRInt64 aCurrentTimeInUsec)
|
||||
{
|
||||
NS_ASSERTION(mDBState->hostTable.Count() > 0, "table is empty");
|
||||
#ifdef PR_LOGGING
|
||||
PRUint32 initialCookieCount = mDBState->cookieCount;
|
||||
#endif
|
||||
mDBState->hostTable.EnumerateEntries(removeExpiredCallback, &aCurrentTime);
|
||||
COOKIE_LOGSTRING(PR_LOG_DEBUG,
|
||||
("RemoveExpiredCookies(): %ld purged; %ld remain",
|
||||
initialCookieCount - mDBState->cookieCount, mDBState->cookieCount));
|
||||
("PurgeCookies(): beginning purge with %ld cookies and %lld age",
|
||||
mDBState->cookieCount, aCurrentTimeInUsec - mDBState->cookieOldestTime));
|
||||
#endif
|
||||
|
||||
nsAutoTArray<nsListIter, kMaxNumberOfCookies> purgeList;
|
||||
|
||||
nsCOMPtr<nsIMutableArray> removedList = do_CreateInstance(NS_ARRAY_CONTRACTID);
|
||||
if (!removedList)
|
||||
return;
|
||||
|
||||
nsPurgeData data(aCurrentTimeInUsec / PR_USEC_PER_SEC,
|
||||
aCurrentTimeInUsec - mCookiePurgeAge, purgeList, removedList);
|
||||
mDBState->hostTable.EnumerateEntries(purgeCookiesCallback, &data);
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
PRUint32 postExpiryCookieCount = mDBState->cookieCount;
|
||||
#endif
|
||||
|
||||
// now we have a list of iterators for cookies over the age limit.
|
||||
// sort them by age, and then we'll see how many to remove...
|
||||
purgeList.Sort(CompareCookiesByAge());
|
||||
|
||||
// only remove old cookies until we reach the max cookie limit, no more.
|
||||
PRUint32 excess = mDBState->cookieCount - mMaxNumberOfCookies;
|
||||
if (purgeList.Length() > excess) {
|
||||
// we're not purging everything in the list, so update our indicator
|
||||
data.oldestTime = purgeList[excess].current->LastAccessed();
|
||||
|
||||
purgeList.SetLength(excess);
|
||||
}
|
||||
|
||||
// traverse the list and remove cookies. the iterators we've stored
|
||||
// in the list aren't stable under list mutation, so we need to do a
|
||||
// fresh linked list traversal from the hash entryclass for each cookie.
|
||||
for (PRUint32 i = 0; i < purgeList.Length(); ++i) {
|
||||
nsListIter iter(purgeList[i].entry, nsnull, purgeList[i].entry->Head());
|
||||
for (; iter.current; ++iter) {
|
||||
if (iter.current == purgeList[i].current) {
|
||||
// remove from list. this takes care of updating the iterator for us
|
||||
nsCookie *cookie = iter.current;
|
||||
removedList->AppendElement(cookie, PR_FALSE);
|
||||
COOKIE_LOGEVICTED(cookie);
|
||||
|
||||
RemoveCookieFromList(iter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// take all the cookies in the removed list, and notify about them in one batch
|
||||
NotifyChanged(removedList, NS_LITERAL_STRING("batch-deleted").get());
|
||||
|
||||
// reset the oldest time indicator
|
||||
mDBState->cookieOldestTime = data.oldestTime;
|
||||
|
||||
COOKIE_LOGSTRING(PR_LOG_DEBUG,
|
||||
("PurgeCookies(): %ld expired; %ld purged; %ld remain; %lld oldest age",
|
||||
initialCookieCount - postExpiryCookieCount,
|
||||
mDBState->cookieCount - postExpiryCookieCount,
|
||||
mDBState->cookieCount,
|
||||
aCurrentTimeInUsec - mDBState->cookieOldestTime));
|
||||
}
|
||||
|
||||
// find whether a given cookie has been previously set. this is provided by the
|
||||
@ -2379,6 +2522,10 @@ nsCookieService::AddCookieToList(nsCookie *aCookie, PRBool aWriteToDB)
|
||||
entry->Head() = aCookie;
|
||||
++mDBState->cookieCount;
|
||||
|
||||
// keep track of the oldest cookie, for when it comes time to purge
|
||||
if (aCookie->LastAccessed() < mDBState->cookieOldestTime)
|
||||
mDBState->cookieOldestTime = aCookie->LastAccessed();
|
||||
|
||||
// if it's a non-session cookie and hasn't just been read from the db, write it out.
|
||||
if (aWriteToDB && !aCookie->IsSession() && mDBState->dbConn) {
|
||||
// use our cached sqlite "insert" statement
|
||||
@ -2426,24 +2573,3 @@ nsCookieService::UpdateCookieInList(nsCookie *aCookie, PRInt64 aLastAccessed)
|
||||
}
|
||||
}
|
||||
|
||||
static PLDHashOperator
|
||||
findOldestCallback(nsCookieEntry *aEntry,
|
||||
void *aArg)
|
||||
{
|
||||
nsEnumerationData *data = static_cast<nsEnumerationData*>(aArg);
|
||||
for (nsListIter iter(aEntry, nsnull, aEntry->Head()); iter.current; ++iter) {
|
||||
// check if we've found the oldest cookie so far
|
||||
if (data->oldestTime > iter.current->LastAccessed()) {
|
||||
data->oldestTime = iter.current->LastAccessed();
|
||||
data->iter = iter;
|
||||
}
|
||||
}
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
void
|
||||
nsCookieService::FindOldestCookie(nsEnumerationData &aData)
|
||||
{
|
||||
NS_ASSERTION(mDBState->hostTable.Count() > 0, "table is empty");
|
||||
mDBState->hostTable.EnumerateEntries(findOldestCallback, &aData);
|
||||
}
|
||||
|
@ -144,10 +144,11 @@ class nsCookieEntry : public PLDHashEntryHdr
|
||||
// conveniently switch state when entering or exiting private browsing.
|
||||
struct DBState
|
||||
{
|
||||
DBState() : cookieCount(0) { }
|
||||
DBState() : cookieCount(0), cookieOldestTime(LL_MAXINT) { }
|
||||
|
||||
nsTHashtable<nsCookieEntry> hostTable;
|
||||
PRUint32 cookieCount;
|
||||
PRInt64 cookieOldestTime;
|
||||
nsCOMPtr<mozIStorageConnection> dbConn;
|
||||
nsCOMPtr<mozIStorageStatement> stmtInsert;
|
||||
nsCOMPtr<mozIStorageStatement> stmtDelete;
|
||||
@ -187,7 +188,7 @@ class nsCookieService : public nsICookieService
|
||||
void GetCookieInternal(nsIURI *aHostURI, nsIChannel *aChannel, PRBool aHttpBound, char **aCookie);
|
||||
nsresult SetCookieStringInternal(nsIURI *aHostURI, nsIPrompt *aPrompt, const char *aCookieHeader, const char *aServerTime, nsIChannel *aChannel, PRBool aFromHttp);
|
||||
PRBool SetCookieInternal(nsIURI *aHostURI, nsIChannel *aChannel, nsDependentCString &aCookieHeader, PRInt64 aServerTime, PRBool aFromHttp);
|
||||
void AddInternal(nsCookie *aCookie, PRInt64 aCurrentTime, nsIURI *aHostURI, const char *aCookieHeader, PRBool aFromHttp);
|
||||
void AddInternal(nsCookie *aCookie, PRInt64 aCurrentTimeInUsec, nsIURI *aHostURI, const char *aCookieHeader, PRBool aFromHttp);
|
||||
void RemoveCookieFromList(nsListIter &aIter);
|
||||
PRBool AddCookieToList(nsCookie *aCookie, PRBool aWriteToDB = PR_TRUE);
|
||||
void UpdateCookieInList(nsCookie *aCookie, PRInt64 aLastAccessed);
|
||||
@ -199,12 +200,11 @@ class nsCookieService : public nsICookieService
|
||||
static PRBool CheckPath(nsCookieAttributes &aCookie, nsIURI *aHostURI);
|
||||
static PRBool GetExpiry(nsCookieAttributes &aCookie, PRInt64 aServerTime, PRInt64 aCurrentTime);
|
||||
void RemoveAllFromMemory();
|
||||
void RemoveExpiredCookies(PRInt64 aCurrentTime);
|
||||
void PurgeCookies(PRInt64 aCurrentTimeInUsec);
|
||||
PRBool FindCookie(const nsAFlatCString &aHost, const nsAFlatCString &aName, const nsAFlatCString &aPath, nsListIter &aIter, PRInt64 aCurrentTime);
|
||||
void FindOldestCookie(nsEnumerationData &aData);
|
||||
PRUint32 CountCookiesFromHostInternal(const nsACString &aHost, nsEnumerationData &aData);
|
||||
void NotifyRejected(nsIURI *aHostURI);
|
||||
void NotifyChanged(nsICookie2 *aCookie, const PRUnichar *aData);
|
||||
void NotifyChanged(nsISupports *aSubject, const PRUnichar *aData);
|
||||
|
||||
protected:
|
||||
// cached members.
|
||||
@ -225,13 +225,14 @@ class nsCookieService : public nsICookieService
|
||||
PRUint8 mCookiesPermissions; // BEHAVIOR_{ACCEPT, REJECTFOREIGN, REJECT}
|
||||
PRUint16 mMaxNumberOfCookies;
|
||||
PRUint16 mMaxCookiesPerHost;
|
||||
PRInt64 mCookiePurgeAge;
|
||||
|
||||
// private static member, used to cache a ptr to nsCookieService,
|
||||
// so we can make nsCookieService a singleton xpcom object.
|
||||
static nsCookieService *gCookieService;
|
||||
|
||||
// this callback needs access to member functions
|
||||
friend PLDHashOperator removeExpiredCallback(nsCookieEntry *aEntry, void *aArg);
|
||||
friend PLDHashOperator purgeCookiesCallback(nsCookieEntry *aEntry, void *aArg);
|
||||
};
|
||||
|
||||
#endif // nsCookieService_h__
|
||||
|
@ -759,41 +759,7 @@ main(PRInt32 argc, char *argv[])
|
||||
GetACookie(cookieService, "http://creation.ordering.tests/", nsnull, getter_Copies(cookie));
|
||||
rv[0] = CheckResult(cookie.get(), MUST_EQUAL, expected.get());
|
||||
|
||||
// test that cookies are evicted by order of lastAccessed time, if the limit on total cookies
|
||||
// (3000) is reached
|
||||
nsCAutoString host;
|
||||
for (PRInt32 i = 0; i < 3010; ++i) {
|
||||
host = NS_LITERAL_CSTRING("http://eviction.");
|
||||
host.AppendInt(i);
|
||||
host += NS_LITERAL_CSTRING(".tests/");
|
||||
SetACookie(cookieService, host.get(), nsnull, "test=eviction", nsnull);
|
||||
|
||||
if (i == 9) {
|
||||
// sleep a couple of seconds, to make sure the first 10 cookies are older than
|
||||
// subsequent ones (timer resolution varies on different platforms).
|
||||
PR_Sleep(2 * PR_TicksPerSecond());
|
||||
}
|
||||
}
|
||||
rv[1] = NS_SUCCEEDED(cookieMgr->GetEnumerator(getter_AddRefs(enumerator)));
|
||||
i = 0;
|
||||
rv[2] = PR_FALSE; // init to failure in case we break from the while loop
|
||||
while (NS_SUCCEEDED(enumerator->HasMoreElements(&more)) && more) {
|
||||
nsCOMPtr<nsISupports> cookie;
|
||||
if (NS_FAILED(enumerator->GetNext(getter_AddRefs(cookie)))) break;
|
||||
++i;
|
||||
|
||||
// keep tabs on the third cookie, so we can check it later
|
||||
nsCOMPtr<nsICookie2> cookie2(do_QueryInterface(cookie));
|
||||
if (!cookie2) break;
|
||||
nsCAutoString domain;
|
||||
cookie2->GetRawHost(domain);
|
||||
PRInt32 hostNumber;
|
||||
PRInt32 numInts = PR_sscanf(domain.get(), "eviction.%ld.tests", &hostNumber);
|
||||
if (numInts != 1 || hostNumber < 10) break;
|
||||
}
|
||||
rv[2] = i == 3000;
|
||||
|
||||
allTestsPassed = PrintResult(rv, 3) && allTestsPassed;
|
||||
allTestsPassed = PrintResult(rv, 1) && allTestsPassed;
|
||||
|
||||
|
||||
// XXX the following are placeholders: add these tests please!
|
||||
|
@ -113,7 +113,6 @@ const HTTP_412 = new HttpError(412, "Precondition Failed");
|
||||
const HTTP_413 = new HttpError(413, "Request Entity Too Large");
|
||||
const HTTP_414 = new HttpError(414, "Request-URI Too Long");
|
||||
const HTTP_415 = new HttpError(415, "Unsupported Media Type");
|
||||
const HTTP_416 = new HttpError(416, "Requested Range Not Satisfiable");
|
||||
const HTTP_417 = new HttpError(417, "Expectation Failed");
|
||||
|
||||
const HTTP_500 = new HttpError(500, "Internal Server Error");
|
||||
@ -2227,6 +2226,8 @@ ServerHandler.prototype =
|
||||
dumpn("*** errorCode == " + errorCode);
|
||||
|
||||
response = new Response(connection);
|
||||
if (e.customErrorHandling)
|
||||
e.customErrorHandling(response);
|
||||
this._handleError(errorCode, request, response);
|
||||
return;
|
||||
}
|
||||
@ -2446,8 +2447,14 @@ ServerHandler.prototype =
|
||||
if (end === undefined || end >= file.fileSize)
|
||||
end = file.fileSize - 1;
|
||||
|
||||
if (start !== undefined && start >= file.fileSize)
|
||||
if (start !== undefined && start >= file.fileSize) {
|
||||
var HTTP_416 = new HttpError(416, "Requested Range Not Satisfiable");
|
||||
HTTP_416.customErrorHandling = function(errorResponse)
|
||||
{
|
||||
maybeAddHeaders(file, metadata, errorResponse);
|
||||
};
|
||||
throw HTTP_416;
|
||||
}
|
||||
|
||||
if (end < start)
|
||||
{
|
||||
|
1
netwerk/test/httpserver/test/data/ranges/headers.txt
Normal file
1
netwerk/test/httpserver/test/data/ranges/headers.txt
Normal file
@ -0,0 +1 @@
|
||||
Hello Kitty
|
@ -0,0 +1 @@
|
||||
X-SJS-Header: customized
|
@ -65,6 +65,8 @@ var tests =
|
||||
init_byterange11, start_byterange11, stop_byterange11),
|
||||
new Test(PREFIX + "/empty.txt",
|
||||
null, start_byterange12, stop_byterange12),
|
||||
new Test(PREFIX + "/headers.txt",
|
||||
init_byterange13, start_byterange13, null),
|
||||
new Test(PREFIX + "/range.txt",
|
||||
null, start_normal, stop_normal)
|
||||
];
|
||||
@ -289,3 +291,14 @@ function stop_byterange12(ch, cx, status, data)
|
||||
{
|
||||
do_check_eq(data.length, 0);
|
||||
}
|
||||
|
||||
function init_byterange13(ch)
|
||||
{
|
||||
ch.setRequestHeader("Range", "bytes=9999999-", false);
|
||||
}
|
||||
|
||||
function start_byterange13(ch, cx)
|
||||
{
|
||||
do_check_eq(ch.responseStatus, 416);
|
||||
do_check_eq(ch.getResponseHeader("X-SJS-Header"), "customized");
|
||||
}
|
||||
|
@ -222,18 +222,6 @@ nsHtml5Tokenizer::appendStrBuf(PRUnichar c)
|
||||
strBuf[strBufLen++] = c;
|
||||
}
|
||||
|
||||
void
|
||||
nsHtml5Tokenizer::appendStrBufForceWrite(PRUnichar c)
|
||||
{
|
||||
if (strBufLen == strBuf.length) {
|
||||
jArray<PRUnichar,PRInt32> newBuf = jArray<PRUnichar,PRInt32>(strBuf.length + NS_HTML5TOKENIZER_BUFFER_GROW_BY);
|
||||
nsHtml5ArrayCopy::arraycopy(strBuf, newBuf, strBuf.length);
|
||||
strBuf.release();
|
||||
strBuf = newBuf;
|
||||
}
|
||||
strBuf[strBufLen++] = c;
|
||||
}
|
||||
|
||||
nsString*
|
||||
nsHtml5Tokenizer::strBufToString()
|
||||
{
|
||||
@ -413,8 +401,8 @@ void
|
||||
nsHtml5Tokenizer::addAttributeWithValue()
|
||||
{
|
||||
if (!!attributeName) {
|
||||
nsString* value = longStrBufToString();
|
||||
attributes->addAttribute(attributeName, value);
|
||||
nsString* val = longStrBufToString();
|
||||
attributes->addAttribute(attributeName, val);
|
||||
attributeName = nsnull;
|
||||
}
|
||||
}
|
||||
|
@ -160,7 +160,6 @@ class nsHtml5Tokenizer
|
||||
void clearStrBufAndAppendForceWrite(PRUnichar c);
|
||||
void clearStrBufForNextState();
|
||||
void appendStrBuf(PRUnichar c);
|
||||
void appendStrBufForceWrite(PRUnichar c);
|
||||
protected:
|
||||
nsString* strBufToString();
|
||||
private:
|
||||
|
@ -2990,7 +2990,7 @@ nsHtml5TreeBuilder::resetTheInsertionMode()
|
||||
} else if (nsHtml5Atoms::table == name) {
|
||||
mode = NS_HTML5TREE_BUILDER_IN_TABLE;
|
||||
return;
|
||||
} else if (kNameSpaceID_XHTML != node->ns) {
|
||||
} else if (kNameSpaceID_XHTML != ns) {
|
||||
foreignFlag = NS_HTML5TREE_BUILDER_IN_FOREIGN;
|
||||
mode = NS_HTML5TREE_BUILDER_IN_BODY;
|
||||
return;
|
||||
|
@ -198,7 +198,7 @@ class nsHtml5TreeBuilder : public nsAHtml5TreeBuilderState
|
||||
void appendCommentToDocument(PRUnichar* buf, PRInt32 start, PRInt32 length);
|
||||
void addAttributesToElement(nsIContent** element, nsHtml5HtmlAttributes* attributes);
|
||||
void markMalformedIfScript(nsIContent** elt);
|
||||
void start(PRBool fragment);
|
||||
void start(PRBool fragmentMode);
|
||||
void end();
|
||||
void appendDoctypeToDocument(nsIAtom* name, nsString* publicIdentifier, nsString* systemIdentifier);
|
||||
void elementPushed(PRInt32 ns, nsIAtom* name, nsIContent** node);
|
||||
|
@ -113,13 +113,19 @@ nsHtml5TreeOpExecutor::DidBuildModel(PRBool aTerminated)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static_cast<nsHtml5Parser*> (mParser.get())->DropStreamParser();
|
||||
|
||||
// This is comes from nsXMLContentSink
|
||||
DidBuildModelImpl(aTerminated);
|
||||
mDocument->ScriptLoader()->RemoveObserver(this);
|
||||
ScrollToRef();
|
||||
mDocument->RemoveObserver(this);
|
||||
if (!mParser) {
|
||||
// DidBuildModelImpl may cause mParser to be nulled out
|
||||
// Return early to avoid unblocking the onload event too many times.
|
||||
return NS_OK;
|
||||
}
|
||||
mDocument->EndLoad();
|
||||
static_cast<nsHtml5Parser*> (mParser.get())->DropStreamParser();
|
||||
DropParserAndPerfHint();
|
||||
#ifdef GATHER_DOCWRITE_STATISTICS
|
||||
printf("UNSAFE SCRIPTS: %d\n", sUnsafeDocWrites);
|
||||
|
@ -183,6 +183,9 @@ DEFAULT_GMAKE_FLAGS += MOZILLA_CLIENT=1
|
||||
DEFAULT_GMAKE_FLAGS += NO_MDUPDATE=1
|
||||
DEFAULT_GMAKE_FLAGS += NSS_ENABLE_ECC=1
|
||||
DEFAULT_GMAKE_FLAGS += IMPORT_LIB_SUFFIX=".$(IMPORT_LIB_SUFFIX)"
|
||||
ifndef MOZ_NATIVE_SQLITE
|
||||
DEFAULT_GMAKE_FLAGS += SQLITE=$(call EXPAND_LIBNAME,mozsqlite3)
|
||||
endif
|
||||
ifdef NSS_DISABLE_DBM
|
||||
DEFAULT_GMAKE_FLAGS += NSS_DISABLE_DBM=1
|
||||
endif
|
||||
@ -320,7 +323,7 @@ ifndef NSS_DISABLE_DBM
|
||||
endif
|
||||
$(NSSMAKE) -C $(NSS_SRCDIR)/security/nss/lib $(DEFAULT_GMAKE_FLAGS)
|
||||
ifdef ENABLE_TESTS
|
||||
# Need certutil binary for mochitest certificates generation
|
||||
# Need certutil binary for mochitest certificates generation
|
||||
$(NSSMAKE) -C $(NSS_SRCDIR)/security/nss/cmd/lib $(DEFAULT_GMAKE_FLAGS)
|
||||
$(NSSMAKE) -C $(NSS_SRCDIR)/security/nss/cmd/certutil $(DEFAULT_GMAKE_FLAGS)
|
||||
$(NSSMAKE) -C $(NSS_SRCDIR)/security/nss/cmd/pk12util $(DEFAULT_GMAKE_FLAGS)
|
||||
|
@ -92,6 +92,7 @@ ifdef USE_STATIC_LIBS
|
||||
|
||||
# can't do this in manifest.mn because OS_ARCH isn't defined there.
|
||||
ifeq (,$(filter-out WINNT WINCE,$(OS_ARCH)))
|
||||
SQLITE = $(LIB_PREFIX)sqlite3.$(LIB_SUFFIX)
|
||||
|
||||
DEFINES += -DNSS_USE_STATIC_LIBS
|
||||
# $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
|
||||
@ -129,7 +130,7 @@ EXTRA_LIBS += \
|
||||
$(DIST)/lib/$(LIB_PREFIX)nssb.$(LIB_SUFFIX) \
|
||||
$(PKIXLIB) \
|
||||
$(DBMLIB) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)sqlite3.$(LIB_SUFFIX) \
|
||||
$(DIST)/lib/$(SQLITE) \
|
||||
$(DIST)/lib/$(LIB_PREFIX)nssutil3.$(LIB_SUFFIX) \
|
||||
$(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.$(LIB_SUFFIX) \
|
||||
$(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.$(LIB_SUFFIX) \
|
||||
|
@ -53,11 +53,12 @@ RES = $(OBJDIR)/$(LIBRARY_NAME).res
|
||||
RESNAME = $(LIBRARY_NAME).rc
|
||||
|
||||
ifdef NS_USE_GCC
|
||||
SQLITE = -lsqlite3
|
||||
EXTRA_SHARED_LIBS += \
|
||||
-L$(DIST)/lib \
|
||||
-L$(NSSUTIL_LIB_DIR) \
|
||||
-lnssutil3 \
|
||||
-lsqlite3 \
|
||||
$(SQLITE) \
|
||||
-L$(NSPR_LIB_DIR) \
|
||||
-lplc4 \
|
||||
-lplds4 \
|
||||
@ -65,8 +66,9 @@ EXTRA_SHARED_LIBS += \
|
||||
$(NULL)
|
||||
else # ! NS_USE_GCC
|
||||
|
||||
SQLITE = sqlite3.lib
|
||||
EXTRA_SHARED_LIBS += \
|
||||
$(DIST)/lib/sqlite3.lib \
|
||||
$(DIST)/lib/$(SQLITE) \
|
||||
$(DIST)/lib/nssutil3.lib \
|
||||
$(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plc4.lib \
|
||||
$(NSPR_LIB_DIR)/$(NSPR31_LIB_PREFIX)plds4.lib \
|
||||
@ -79,11 +81,12 @@ else
|
||||
|
||||
# $(PROGRAM) has NO explicit dependencies on $(EXTRA_SHARED_LIBS)
|
||||
# $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
|
||||
SQLITE = -lsqlite3
|
||||
EXTRA_SHARED_LIBS += \
|
||||
-L$(DIST)/lib \
|
||||
-L$(NSSUTIL_LIB_DIR) \
|
||||
-lnssutil3 \
|
||||
-lsqlite3 \
|
||||
$(SQLITE) \
|
||||
-L$(NSPR_LIB_DIR) \
|
||||
-lplc4 \
|
||||
-lplds4 \
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user