зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to mozilla-inbound
This commit is contained in:
Коммит
f57af7547e
|
@ -408,6 +408,10 @@
|
|||
<row>
|
||||
<label value="&syncMy.label;" />
|
||||
<vbox>
|
||||
<checkbox label="&engine.addons.label;"
|
||||
accesskey="&engine.addons.accesskey;"
|
||||
id="engine.addons"
|
||||
checked="true"/>
|
||||
<checkbox label="&engine.bookmarks.label;"
|
||||
accesskey="&engine.bookmarks.accesskey;"
|
||||
id="engine.bookmarks"
|
||||
|
@ -428,10 +432,6 @@
|
|||
accesskey="&engine.tabs.accesskey;"
|
||||
id="engine.tabs"
|
||||
checked="true"/>
|
||||
<checkbox label="&engine.addons.label;"
|
||||
accesskey="&engine.addons.accesskey;"
|
||||
id="engine.addons"
|
||||
checked="true"/>
|
||||
</vbox>
|
||||
</row>
|
||||
</rows>
|
||||
|
|
|
@ -57,12 +57,12 @@
|
|||
onpaneload="gSyncPane.init()">
|
||||
|
||||
<preferences>
|
||||
<preference id="engine.addons" name="services.sync.engine.addons" type="bool"/>
|
||||
<preference id="engine.bookmarks" name="services.sync.engine.bookmarks" type="bool"/>
|
||||
<preference id="engine.history" name="services.sync.engine.history" type="bool"/>
|
||||
<preference id="engine.tabs" name="services.sync.engine.tabs" type="bool"/>
|
||||
<preference id="engine.prefs" name="services.sync.engine.prefs" type="bool"/>
|
||||
<preference id="engine.passwords" name="services.sync.engine.passwords" type="bool"/>
|
||||
<preference id="engine.addons" name="services.sync.engine.addons" type="bool"/>
|
||||
</preferences>
|
||||
|
||||
|
||||
|
@ -128,6 +128,11 @@
|
|||
<richlistbox id="syncEnginesList"
|
||||
orient="vertical"
|
||||
onselect="if (this.selectedCount) this.clearSelection();">
|
||||
<richlistitem>
|
||||
<checkbox label="&engine.addons.label;"
|
||||
accesskey="&engine.addons.accesskey;"
|
||||
preference="engine.addons"/>
|
||||
</richlistitem>
|
||||
<richlistitem>
|
||||
<checkbox label="&engine.bookmarks.label;"
|
||||
accesskey="&engine.bookmarks.accesskey;"
|
||||
|
@ -153,11 +158,6 @@
|
|||
accesskey="&engine.tabs.accesskey;"
|
||||
preference="engine.tabs"/>
|
||||
</richlistitem>
|
||||
<richlistitem>
|
||||
<checkbox label="&engine.addons.label;"
|
||||
accesskey="&engine.addons.accesskey;"
|
||||
preference="engine.addons"/>
|
||||
</richlistitem>
|
||||
</richlistbox>
|
||||
</vbox>
|
||||
</groupbox>
|
||||
|
|
|
@ -4,12 +4,14 @@
|
|||
<body>
|
||||
<span contenteditable id="t" style="border: 1px dashed green; min-height: 2px; padding-right: 20px;"> </span></body>
|
||||
<script>
|
||||
// Only focus the span to put the caret at its beginning
|
||||
var sel = window.getSelection();
|
||||
sel.removeAllRanges();
|
||||
|
||||
// Focus the span to put the caret at its beginning.
|
||||
var area = document.getElementById('t');
|
||||
area.focus();
|
||||
|
||||
// Do nothing else.
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -4,14 +4,15 @@
|
|||
<body>
|
||||
<span contenteditable id="t" style="border: 1px dashed green; min-height: 2px; padding-right: 20px;"> </span></body>
|
||||
<script>
|
||||
// Enter a character in the span and delete it
|
||||
var sel = window.getSelection();
|
||||
sel.removeAllRanges();
|
||||
|
||||
// Focus the span to put the caret at its beginning.
|
||||
var area = document.getElementById('t');
|
||||
area.focus();
|
||||
|
||||
sendKey("W"); // enter a character
|
||||
// Enter a character in the span then delete it.
|
||||
sendChar("W");
|
||||
sendKey("BACK_SPACE");
|
||||
</script>
|
||||
</body>
|
||||
|
|
|
@ -43,6 +43,8 @@ VPATH = @srcdir@
|
|||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
FAIL_ON_WARNINGS := 1
|
||||
|
||||
MODULE = services-crypto
|
||||
XPIDL_MODULE = services-crypto-component
|
||||
|
||||
|
|
|
@ -244,8 +244,8 @@ AsyncResource.prototype = {
|
|||
channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
|
||||
channel.loadFlags |= Ci.nsIRequest.INHIBIT_CACHING;
|
||||
|
||||
// Setup a callback to handle bad HTTPS certificates.
|
||||
channel.notificationCallbacks = new BadCertListener();
|
||||
// Setup a callback to handle channel notifications.
|
||||
channel.notificationCallbacks = new ChannelNotificationListener();
|
||||
|
||||
// Compose a UA string fragment from the various available identifiers.
|
||||
if (Svc.Prefs.get("sendVersionInfo", true)) {
|
||||
|
@ -520,7 +520,14 @@ ChannelListener.prototype = {
|
|||
|
||||
onStartRequest: function Channel_onStartRequest(channel) {
|
||||
this._log.trace("onStartRequest called for channel " + channel + ".");
|
||||
|
||||
try {
|
||||
channel.QueryInterface(Ci.nsIHttpChannel);
|
||||
} catch (ex) {
|
||||
this._log.error("Unexpected error: channel is not a nsIHttpChannel!");
|
||||
channel.cancel(Cr.NS_BINDING_ABORTED);
|
||||
return;
|
||||
}
|
||||
|
||||
// Save the latest server timestamp when possible.
|
||||
try {
|
||||
|
@ -538,6 +545,22 @@ ChannelListener.prototype = {
|
|||
// Clear the abort timer now that the channel is done.
|
||||
this.abortTimer.clear();
|
||||
|
||||
if (!this._onComplete) {
|
||||
this._log.error("Unexpected error: _onComplete not defined in onStopRequest.");
|
||||
this._onProgress = null;
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
channel.QueryInterface(Ci.nsIHttpChannel);
|
||||
} catch (ex) {
|
||||
this._log.error("Unexpected error: channel is not a nsIHttpChannel!");
|
||||
|
||||
this._onComplete(ex, this._data, channel);
|
||||
this._onComplete = this._onProgress = null;
|
||||
return;
|
||||
}
|
||||
|
||||
let statusSuccess = Components.isSuccessCode(status);
|
||||
let uri = channel && channel.URI && channel.URI.spec || "<unknown>";
|
||||
this._log.trace("Channel for " + channel.requestMethod + " " + uri + ": " +
|
||||
|
@ -553,7 +576,9 @@ ChannelListener.prototype = {
|
|||
if (!statusSuccess) {
|
||||
let message = Components.Exception("", status).name;
|
||||
let error = Components.Exception(message, status);
|
||||
|
||||
this._onComplete(error, undefined, channel);
|
||||
this._onComplete = this._onProgress = null;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -561,6 +586,7 @@ ChannelListener.prototype = {
|
|||
", URI = " + uri +
|
||||
", HTTP success? " + channel.requestSucceeded);
|
||||
this._onComplete(null, this._data, channel);
|
||||
this._onComplete = this._onProgress = null;
|
||||
},
|
||||
|
||||
onDataAvailable: function Channel_onDataAvail(req, cb, stream, off, count) {
|
||||
|
@ -600,40 +626,49 @@ ChannelListener.prototype = {
|
|||
this.onStopRequest = function() {};
|
||||
let error = Components.Exception("Aborting due to channel inactivity.",
|
||||
Cr.NS_ERROR_NET_TIMEOUT);
|
||||
if (!this._onComplete) {
|
||||
this._log.error("Unexpected error: _onComplete not defined in " +
|
||||
"abortRequest.");
|
||||
return;
|
||||
}
|
||||
this._onComplete(error);
|
||||
}
|
||||
};
|
||||
|
||||
// = BadCertListener =
|
||||
//
|
||||
// We use this listener to ignore bad HTTPS
|
||||
// certificates and continue a request on a network
|
||||
// channel. Probably not a very smart thing to do,
|
||||
// but greatly simplifies debugging and is just very
|
||||
// convenient.
|
||||
function BadCertListener() {
|
||||
/**
|
||||
* This class handles channel notification events.
|
||||
*
|
||||
* An instance of this class is bound to each created channel.
|
||||
*/
|
||||
function ChannelNotificationListener() {
|
||||
}
|
||||
BadCertListener.prototype = {
|
||||
ChannelNotificationListener.prototype = {
|
||||
getInterface: function(aIID) {
|
||||
return this.QueryInterface(aIID);
|
||||
},
|
||||
|
||||
QueryInterface: function(aIID) {
|
||||
if (aIID.equals(Components.interfaces.nsIBadCertListener2) ||
|
||||
aIID.equals(Components.interfaces.nsIInterfaceRequestor) ||
|
||||
aIID.equals(Components.interfaces.nsISupports))
|
||||
if (aIID.equals(Ci.nsIBadCertListener2) ||
|
||||
aIID.equals(Ci.nsIInterfaceRequestor) ||
|
||||
aIID.equals(Ci.nsISupports) ||
|
||||
aIID.equals(Ci.nsIChannelEventSink))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
throw Cr.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
|
||||
notifyCertProblem: function certProblem(socketInfo, sslStatus, targetHost) {
|
||||
// Silently ignore?
|
||||
let log = Log4Moz.repository.getLogger("Sync.CertListener");
|
||||
log.level =
|
||||
Log4Moz.Level[Svc.Prefs.get("log.logger.network.resources")];
|
||||
log.debug("Invalid HTTPS certificate encountered, ignoring!");
|
||||
log.warn("Invalid HTTPS certificate encountered!");
|
||||
|
||||
// This suppresses the UI warning only. The request is still cancelled.
|
||||
return true;
|
||||
},
|
||||
|
||||
asyncOnChannelRedirect:
|
||||
function asyncOnChannelRedirect(oldChannel, newChannel, flags, callback) {
|
||||
|
||||
// We let all redirects proceed.
|
||||
callback.onRedirectVerifyCallback(Cr.NS_OK);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -126,7 +126,8 @@ RESTRequest.prototype = {
|
|||
|
||||
QueryInterface: XPCOMUtils.generateQI([
|
||||
Ci.nsIBadCertListener2,
|
||||
Ci.nsIInterfaceRequestor
|
||||
Ci.nsIInterfaceRequestor,
|
||||
Ci.nsIChannelEventSink
|
||||
]),
|
||||
|
||||
/*** Public API: ***/
|
||||
|
@ -364,22 +365,33 @@ RESTRequest.prototype = {
|
|||
this.abort();
|
||||
let error = Components.Exception("Aborting due to channel inactivity.",
|
||||
Cr.NS_ERROR_NET_TIMEOUT);
|
||||
if (!this.onComplete) {
|
||||
this._log.error("Unexpected error: onComplete not defined in " +
|
||||
"abortTimeout.")
|
||||
return;
|
||||
}
|
||||
this.onComplete(error);
|
||||
},
|
||||
|
||||
/*** nsIStreamListener ***/
|
||||
|
||||
onStartRequest: function onStartRequest(channel) {
|
||||
// Update the channel in case we got redirected.
|
||||
this.channel = channel;
|
||||
|
||||
if (this.status == this.ABORTED) {
|
||||
this._log.trace("Not proceeding with onStartRequest, request was aborted.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
channel.QueryInterface(Ci.nsIHttpChannel);
|
||||
} catch (ex) {
|
||||
this._log.error("Unexpected error: channel is not a nsIHttpChannel!");
|
||||
this.status = this.ABORTED;
|
||||
channel.cancel(Cr.NS_BINDING_ABORTED);
|
||||
return;
|
||||
}
|
||||
|
||||
this.status = this.IN_PROGRESS;
|
||||
|
||||
channel.QueryInterface(Ci.nsIHttpChannel);
|
||||
this._log.trace("onStartRequest: " + channel.requestMethod + " " +
|
||||
channel.URI.spec);
|
||||
|
||||
|
@ -397,9 +409,6 @@ RESTRequest.prototype = {
|
|||
},
|
||||
|
||||
onStopRequest: function onStopRequest(channel, context, statusCode) {
|
||||
// Update the channel in case we got redirected.
|
||||
this.channel = channel;
|
||||
|
||||
if (this.timeoutTimer) {
|
||||
// Clear the abort timer now that the channel is done.
|
||||
this.timeoutTimer.clear();
|
||||
|
@ -410,6 +419,14 @@ RESTRequest.prototype = {
|
|||
this._log.trace("Not proceeding with onStopRequest, request was aborted.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
channel.QueryInterface(Ci.nsIHttpChannel);
|
||||
} catch (ex) {
|
||||
this._log.error("Unexpected error: channel not nsIHttpChannel!");
|
||||
this.status = this.ABORTED;
|
||||
return;
|
||||
}
|
||||
this.status = this.COMPLETED;
|
||||
|
||||
let statusSuccess = Components.isSuccessCode(statusCode);
|
||||
|
@ -417,6 +434,13 @@ RESTRequest.prototype = {
|
|||
this._log.trace("Channel for " + channel.requestMethod + " " + uri +
|
||||
" returned status code " + statusCode);
|
||||
|
||||
if (!this.onComplete) {
|
||||
this._log.error("Unexpected error: onComplete not defined in " +
|
||||
"abortRequest.");
|
||||
this.onProgress = null;
|
||||
return;
|
||||
}
|
||||
|
||||
// Throw the failure code and stop execution. Use Components.Exception()
|
||||
// instead of Error() so the exception is QI-able and can be passed across
|
||||
// XPCOM borders while preserving the status code.
|
||||
|
@ -459,6 +483,14 @@ RESTRequest.prototype = {
|
|||
this.method + " " + req.URI.spec);
|
||||
this._log.debug("Exception: " + Utils.exceptionStr(ex));
|
||||
this.abort();
|
||||
|
||||
if (!this.onComplete) {
|
||||
this._log.error("Unexpected error: onComplete not defined in " +
|
||||
"onDataAvailable.");
|
||||
this.onProgress = null;
|
||||
return;
|
||||
}
|
||||
|
||||
this.onComplete(ex);
|
||||
this.onComplete = this.onProgress = null;
|
||||
return;
|
||||
|
@ -480,6 +512,24 @@ RESTRequest.prototype = {
|
|||
// Suppress invalid HTTPS certificate warnings in the UI.
|
||||
// (The request will still fail.)
|
||||
return true;
|
||||
},
|
||||
|
||||
/*** nsIChannelEventSink ***/
|
||||
asyncOnChannelRedirect:
|
||||
function asyncOnChannelRedirect(oldChannel, newChannel, flags, callback) {
|
||||
|
||||
try {
|
||||
newChannel.QueryInterface(Ci.nsIHttpChannel);
|
||||
} catch (ex) {
|
||||
this._log.error("Unexpected error: channel not nsIHttpChannel!");
|
||||
callback.onRedirectVerifyCallback(Cr.NS_ERROR_NO_INTERFACE);
|
||||
return;
|
||||
}
|
||||
|
||||
this.channel = newChannel;
|
||||
|
||||
// We let all redirects proceed.
|
||||
callback.onRedirectVerifyCallback(Cr.NS_OK);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -23,9 +23,9 @@ function return_timestamp(request, response, timestamp) {
|
|||
return timestamp;
|
||||
}
|
||||
|
||||
function httpd_setup (handlers) {
|
||||
function httpd_setup (handlers, port) {
|
||||
let port = port || 8080;
|
||||
let server = new nsHttpServer();
|
||||
let port = 8080;
|
||||
for (let path in handlers) {
|
||||
server.registerPathHandler(path, handlers[path]);
|
||||
}
|
||||
|
|
|
@ -145,6 +145,13 @@ function server_headers(metadata, response) {
|
|||
response.bodyOutputStream.write(body, body.length);
|
||||
}
|
||||
|
||||
function server_redirect(metadata, response) {
|
||||
let body = "Redirecting";
|
||||
response.setStatusLine(metadata.httpVersion, 307, "TEMPORARY REDIRECT");
|
||||
response.setHeader("Location", "http://localhost:8081/resource");
|
||||
response.bodyOutputStream.write(body, body.length);
|
||||
}
|
||||
|
||||
let quotaValue;
|
||||
Observers.add("weave:service:quota:remaining",
|
||||
function (subject) { quotaValue = subject; });
|
||||
|
@ -167,7 +174,8 @@ function run_test() {
|
|||
"/backoff": server_backoff,
|
||||
"/pac2": server_pac,
|
||||
"/quota-notice": server_quota_notice,
|
||||
"/quota-error": server_quota_error
|
||||
"/quota-error": server_quota_error,
|
||||
"/redirect": server_redirect
|
||||
});
|
||||
|
||||
Svc.Prefs.set("network.numRetries", 1); // speed up test
|
||||
|
@ -658,6 +666,31 @@ add_test(function test_uri_construction() {
|
|||
run_next_test();
|
||||
});
|
||||
|
||||
add_test(function test_new_channel() {
|
||||
_("Ensure a redirect to a new channel is handled properly.");
|
||||
|
||||
let resourceRequested = false;
|
||||
function resourceHandler(metadata, response) {
|
||||
resourceRequested = true;
|
||||
|
||||
let body = "Test";
|
||||
response.setHeader("Content-Type", "text/plain");
|
||||
response.bodyOutputStream.write(body, body.length);
|
||||
}
|
||||
let server2 = httpd_setup({"/resource": resourceHandler}, 8081);
|
||||
|
||||
let request = new AsyncResource("http://localhost:8080/redirect");
|
||||
request.get(function onRequest(error, content) {
|
||||
do_check_null(error);
|
||||
do_check_true(resourceRequested);
|
||||
do_check_eq(200, content.status);
|
||||
do_check_true("content-type" in content.headers);
|
||||
do_check_eq("text/plain", content.headers["content-type"]);
|
||||
|
||||
server2.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function tear_down() {
|
||||
server.stop(run_next_test);
|
||||
});
|
||||
|
|
|
@ -620,3 +620,44 @@ add_test(function test_exception_in_onProgress() {
|
|||
server.stop(run_next_test);
|
||||
});
|
||||
});
|
||||
|
||||
add_test(function test_new_channel() {
|
||||
_("Ensure a redirect to a new channel is handled properly.");
|
||||
|
||||
let redirectRequested = false;
|
||||
function redirectHandler(metadata, response) {
|
||||
redirectRequested = true;
|
||||
|
||||
let body = "Redirecting";
|
||||
response.setStatusLine(metadata.httpVersion, 307, "TEMPORARY REDIRECT");
|
||||
response.setHeader("Location", "http://localhost:8081/resource");
|
||||
response.bodyOutputStream.write(body, body.length);
|
||||
}
|
||||
|
||||
let resourceRequested = false;
|
||||
function resourceHandler(metadata, response) {
|
||||
resourceRequested = true;
|
||||
|
||||
let body = "Test";
|
||||
response.setHeader("Content-Type", "text/plain");
|
||||
response.bodyOutputStream.write(body, body.length);
|
||||
}
|
||||
let server1 = httpd_setup({"/redirect": redirectHandler}, 8080);
|
||||
let server2 = httpd_setup({"/resource": resourceHandler}, 8081);
|
||||
|
||||
function advance() {
|
||||
server1.stop(function () {
|
||||
server2.stop(run_next_test);
|
||||
});
|
||||
}
|
||||
|
||||
let request = new RESTRequest("http://localhost:8080/redirect");
|
||||
request.get(function onComplete(error) {
|
||||
let response = this.response;
|
||||
|
||||
do_check_eq(200, response.status);
|
||||
do_check_eq("Test", response.body);
|
||||
|
||||
advance();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1735,7 +1735,9 @@ GCGraphBuilder::NoteRoot(PRUint32 langID, void *root,
|
|||
return;
|
||||
}
|
||||
|
||||
if (!participant->CanSkipThis(root)) {
|
||||
AddNode(root, participant, langID);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP_(void)
|
||||
|
|
|
@ -134,6 +134,9 @@ protected:
|
|||
class NS_NO_VTABLE nsCycleCollectionParticipant
|
||||
{
|
||||
public:
|
||||
nsCycleCollectionParticipant() : mMightSkip(false) {}
|
||||
nsCycleCollectionParticipant(bool aSkip) : mMightSkip(aSkip) {}
|
||||
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_CYCLECOLLECTIONPARTICIPANT_IID)
|
||||
|
||||
NS_IMETHOD Traverse(void *p, nsCycleCollectionTraversalCallback &cb) = 0;
|
||||
|
@ -141,43 +144,6 @@ public:
|
|||
NS_IMETHOD Root(void *p) = 0;
|
||||
NS_IMETHOD Unlink(void *p) = 0;
|
||||
NS_IMETHOD Unroot(void *p) = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsCycleCollectionParticipant,
|
||||
NS_CYCLECOLLECTIONPARTICIPANT_IID)
|
||||
|
||||
#undef IMETHOD_VISIBILITY
|
||||
#define IMETHOD_VISIBILITY NS_COM_GLUE
|
||||
|
||||
typedef void
|
||||
(* TraceCallback)(PRUint32 langID, void *p, const char *name, void *closure);
|
||||
|
||||
class NS_NO_VTABLE nsScriptObjectTracer : public nsCycleCollectionParticipant
|
||||
{
|
||||
public:
|
||||
NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure) = 0;
|
||||
void NS_COM_GLUE TraverseScriptObjects(void *p,
|
||||
nsCycleCollectionTraversalCallback &cb);
|
||||
};
|
||||
|
||||
class NS_COM_GLUE nsXPCOMCycleCollectionParticipant
|
||||
: public nsScriptObjectTracer
|
||||
{
|
||||
public:
|
||||
nsXPCOMCycleCollectionParticipant() : mMightSkip(false) {}
|
||||
nsXPCOMCycleCollectionParticipant(bool aSkip) : mMightSkip(aSkip) {}
|
||||
|
||||
NS_IMETHOD Traverse(void *p, nsCycleCollectionTraversalCallback &cb);
|
||||
|
||||
NS_IMETHOD Root(void *p);
|
||||
NS_IMETHOD Unlink(void *p);
|
||||
NS_IMETHOD Unroot(void *p);
|
||||
|
||||
NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure);
|
||||
|
||||
NS_IMETHOD_(void) UnmarkPurple(nsISupports *p);
|
||||
|
||||
bool CheckForRightISupports(nsISupports *s);
|
||||
|
||||
// If CanSkip returns true, p is removed from the purple buffer during
|
||||
// a call to nsCycleCollector_forgetSkippable().
|
||||
|
@ -223,6 +189,48 @@ private:
|
|||
bool mMightSkip;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsCycleCollectionParticipant,
|
||||
NS_CYCLECOLLECTIONPARTICIPANT_IID)
|
||||
|
||||
#undef IMETHOD_VISIBILITY
|
||||
#define IMETHOD_VISIBILITY NS_COM_GLUE
|
||||
|
||||
typedef void
|
||||
(* TraceCallback)(PRUint32 langID, void *p, const char *name, void *closure);
|
||||
|
||||
class NS_NO_VTABLE nsScriptObjectTracer : public nsCycleCollectionParticipant
|
||||
{
|
||||
public:
|
||||
nsScriptObjectTracer() : nsCycleCollectionParticipant(false) {}
|
||||
nsScriptObjectTracer(bool aSkip) : nsCycleCollectionParticipant(aSkip) {}
|
||||
|
||||
NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure) = 0;
|
||||
void NS_COM_GLUE TraverseScriptObjects(void *p,
|
||||
nsCycleCollectionTraversalCallback &cb);
|
||||
};
|
||||
|
||||
class NS_COM_GLUE nsXPCOMCycleCollectionParticipant
|
||||
: public nsScriptObjectTracer
|
||||
{
|
||||
public:
|
||||
nsXPCOMCycleCollectionParticipant()
|
||||
: nsScriptObjectTracer(false) {}
|
||||
nsXPCOMCycleCollectionParticipant(bool aSkip)
|
||||
: nsScriptObjectTracer(aSkip) {}
|
||||
|
||||
NS_IMETHOD Traverse(void *p, nsCycleCollectionTraversalCallback &cb);
|
||||
|
||||
NS_IMETHOD Root(void *p);
|
||||
NS_IMETHOD Unlink(void *p);
|
||||
NS_IMETHOD Unroot(void *p);
|
||||
|
||||
NS_IMETHOD_(void) Trace(void *p, TraceCallback cb, void *closure);
|
||||
|
||||
NS_IMETHOD_(void) UnmarkPurple(nsISupports *p);
|
||||
|
||||
bool CheckForRightISupports(nsISupports *s);
|
||||
};
|
||||
|
||||
#undef IMETHOD_VISIBILITY
|
||||
#define IMETHOD_VISIBILITY NS_VISIBILITY_HIDDEN
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче