зеркало из https://github.com/mozilla/pjs.git
Merge mozilla-central and tracemonkey. (a=blockers)
This commit is contained in:
Коммит
10dffb9902
|
@ -1459,7 +1459,8 @@
|
|||
aTab.removeAttribute("fadein");
|
||||
|
||||
setTimeout(function (tab, tabbrowser) {
|
||||
if (tab.parentNode) {
|
||||
if (tab.parentNode &&
|
||||
window.getComputedStyle(tab).maxWidth == "0.1px") {
|
||||
NS_ASSERT(false, "Giving up waiting for the tab closing animation to finish (bug 608589)");
|
||||
tabbrowser._endRemoveTab(tab);
|
||||
}
|
||||
|
|
|
@ -336,7 +336,7 @@ SearchEventHandlerClass.prototype = {
|
|||
|
||||
iQ("#searchbutton").mousedown(function() {
|
||||
self.initiatedBy = "buttonclick";
|
||||
ensureSearchShown(null);
|
||||
ensureSearchShown();
|
||||
self.switchToInMode();
|
||||
});
|
||||
|
||||
|
@ -347,30 +347,37 @@ SearchEventHandlerClass.prototype = {
|
|||
|
||||
// ----------
|
||||
// Function: beforeSearchKeyHandler
|
||||
// Handles all keypresses before the search interface is brought up.
|
||||
// Handles all keydown before the search interface is brought up.
|
||||
beforeSearchKeyHandler: function (event) {
|
||||
// Only match reasonable text-like characters for quick search.
|
||||
// TODO: Also include funky chars. Bug 593904
|
||||
if (!String.fromCharCode(event.which).match(/[a-zA-Z0-9]/) || event.altKey ||
|
||||
event.ctrlKey || event.metaKey)
|
||||
if (event.altKey || event.ctrlKey || event.metaKey)
|
||||
return;
|
||||
|
||||
if ((event.keyCode > 0 && event.keyCode <= event.DOM_VK_DELETE) ||
|
||||
event.keyCode == event.DOM_VK_CONTEXT_MENU ||
|
||||
event.keyCode == event.DOM_VK_SLEEP ||
|
||||
(event.keyCode >= event.DOM_VK_F1 &&
|
||||
event.keyCode <= event.DOM_VK_SCROLL_LOCK) ||
|
||||
event.keyCode == event.DOM_VK_META) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If we are already in an input field, allow typing as normal.
|
||||
if (event.target.nodeName == "INPUT")
|
||||
return;
|
||||
|
||||
this.switchToInMode();
|
||||
this.initiatedBy = "keypress";
|
||||
ensureSearchShown(event);
|
||||
this.initiatedBy = "keydown";
|
||||
ensureSearchShown();
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: inSearchKeyHandler
|
||||
// Handles all keypresses while search mode.
|
||||
// Handles all keydown while search mode.
|
||||
inSearchKeyHandler: function (event) {
|
||||
let term = iQ("#searchbox").val();
|
||||
if ((event.keyCode == event.DOM_VK_ESCAPE) ||
|
||||
(event.keyCode == event.DOM_VK_BACK_SPACE && term.length <= 1 && this.initiatedBy == "keypress")) {
|
||||
(event.keyCode == event.DOM_VK_BACK_SPACE && term.length <= 1 && this.initiatedBy == "keydown")) {
|
||||
hideSearch(event);
|
||||
return;
|
||||
}
|
||||
|
@ -396,9 +403,9 @@ SearchEventHandlerClass.prototype = {
|
|||
switchToBeforeMode: function switchToBeforeMode() {
|
||||
let self = this;
|
||||
if (this.currentHandler)
|
||||
iQ(window).unbind("keypress", this.currentHandler);
|
||||
iQ(window).unbind("keydown", this.currentHandler);
|
||||
this.currentHandler = function(event) self.beforeSearchKeyHandler(event);
|
||||
iQ(window).keypress(this.currentHandler);
|
||||
iQ(window).keydown(this.currentHandler);
|
||||
},
|
||||
|
||||
// ----------
|
||||
|
@ -408,9 +415,9 @@ SearchEventHandlerClass.prototype = {
|
|||
switchToInMode: function switchToInMode() {
|
||||
let self = this;
|
||||
if (this.currentHandler)
|
||||
iQ(window).unbind("keypress", this.currentHandler);
|
||||
iQ(window).unbind("keydown", this.currentHandler);
|
||||
this.currentHandler = function(event) self.inSearchKeyHandler(event);
|
||||
iQ(window).keypress(this.currentHandler);
|
||||
iQ(window).keydown(this.currentHandler);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -534,7 +541,7 @@ function performSearch() {
|
|||
matcher.doSearch(TabHandlers.onMatch, TabHandlers.onUnmatch, TabHandlers.onOther);
|
||||
}
|
||||
|
||||
function ensureSearchShown(event){
|
||||
function ensureSearchShown(){
|
||||
var $search = iQ("#search");
|
||||
var $searchShade = iQ("#searchshade");
|
||||
var $searchbox = iQ("#searchbox");
|
||||
|
@ -546,17 +553,13 @@ function ensureSearchShown(event){
|
|||
var mainWindow = gWindow.document.getElementById("main-window");
|
||||
mainWindow.setAttribute("activetitlebarcolor", "#717171");
|
||||
|
||||
// Marshal the focusing, otherwise you end up with
|
||||
// a race condition where only sometimes would the
|
||||
// first keystroke be registered by the search box.
|
||||
// When you marshal it never gets registered, so we
|
||||
// manually
|
||||
setTimeout(function focusSearch() {
|
||||
$searchbox[0].focus();
|
||||
$searchbox[0].val = '0';
|
||||
if (event != null)
|
||||
$searchbox.val(String.fromCharCode(event.charCode));
|
||||
$searchbox[0].focus();
|
||||
$searchbox[0].val = '0';
|
||||
|
||||
// NOTE: when this function is called by keydown handler, next keypress
|
||||
// event or composition events of IME will be fired on the focused editor.
|
||||
|
||||
setTimeout(function dispatchTabViewSearchEnabledEvent() {
|
||||
let newEvent = document.createEvent("Events");
|
||||
newEvent.initEvent("tabviewsearchenabled", false, false);
|
||||
dispatchEvent(newEvent);
|
||||
|
|
|
@ -79,7 +79,7 @@ function escapeTest(contentWindow) {
|
|||
}
|
||||
contentWindow.addEventListener("tabviewsearchdisabled", onSearchDisabled,
|
||||
false);
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", { type: "keypress" }, contentWindow);
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", { }, contentWindow);
|
||||
}
|
||||
|
||||
function toggleTabViewTest(contentWindow) {
|
||||
|
|
|
@ -159,6 +159,14 @@
|
|||
}
|
||||
}
|
||||
|
||||
%ifndef WINSTRIPE_AERO
|
||||
@media all and (-moz-windows-default-theme) {
|
||||
#main-window[sizemode="normal"] #appmenu-button {
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
}
|
||||
%endif
|
||||
|
||||
#main-window[privatebrowsingmode=temporary] #appmenu-button {
|
||||
background-image: -moz-linear-gradient(rgb(153,38,211), rgb(105,19,163) 95%);
|
||||
border-color: rgba(43,8,65,.9);
|
||||
|
|
|
@ -285,6 +285,9 @@ public:
|
|||
* Get/Set the base target of a link in a document.
|
||||
*/
|
||||
virtual void GetBaseTarget(nsAString &aBaseTarget) = 0;
|
||||
void SetBaseTarget(const nsString& aBaseTarget) {
|
||||
mBaseTarget = aBaseTarget;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a standard name for the document's character set.
|
||||
|
@ -1746,6 +1749,9 @@ protected:
|
|||
// The session history entry in which we're currently bf-cached. Non-null
|
||||
// if and only if we're currently in the bfcache.
|
||||
nsISHEntry* mSHEntry;
|
||||
|
||||
// Our base target.
|
||||
nsString mBaseTarget;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocument, NS_IDOCUMENT_IID)
|
||||
|
|
|
@ -2966,19 +2966,7 @@ nsDocument::SetBaseURI(nsIURI* aURI)
|
|||
void
|
||||
nsDocument::GetBaseTarget(nsAString &aBaseTarget)
|
||||
{
|
||||
aBaseTarget.Truncate();
|
||||
Element* head = GetHeadElement();
|
||||
if (!head) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (ChildIterator iter(head); !iter.IsDone(); iter.Next()) {
|
||||
nsIContent* child = iter;
|
||||
if (child->NodeInfo()->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) &&
|
||||
child->GetAttr(kNameSpaceID_None, nsGkAtoms::target, aBaseTarget)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
aBaseTarget = mBaseTarget;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1165,8 +1165,6 @@ protected:
|
|||
|
||||
nsCOMPtr<nsIScriptEventManager> mScriptEventManager;
|
||||
|
||||
nsString mBaseTarget;
|
||||
|
||||
// Our update nesting level
|
||||
PRUint32 mUpdateNestLevel;
|
||||
|
||||
|
|
|
@ -1655,7 +1655,6 @@ nsXMLHttpRequest::OpenRequest(const nsACString& method,
|
|||
const nsAString& password)
|
||||
{
|
||||
NS_ENSURE_ARG(!method.IsEmpty());
|
||||
NS_ENSURE_ARG(!url.IsEmpty());
|
||||
|
||||
NS_ENSURE_TRUE(mPrincipal, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
|
|
|
@ -455,6 +455,7 @@ _TEST_FILES2 = \
|
|||
test_bug590771.html \
|
||||
test_bug622117.html \
|
||||
test_bug622246.html \
|
||||
test_bug484396.html \
|
||||
$(NULL)
|
||||
|
||||
# This test fails on the Mac for some reason
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=484396
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 484396</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=484396">Mozilla Bug 484396</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var msg = 'xhr.open() succeeds with empty url';
|
||||
var xhr = new XMLHttpRequest();
|
||||
|
||||
try {
|
||||
xhr.open('GET', '');
|
||||
ok(true, msg);
|
||||
} catch (e) {
|
||||
ok(false, msg);
|
||||
}
|
||||
|
||||
xhr.onerror = function () {
|
||||
ok(false, 'xhr.send() succeeds with empty url');
|
||||
}
|
||||
|
||||
xhr.onreadystatechange = function () {
|
||||
if (4 == xhr.readyState) {
|
||||
is(xhr.status, 200, 'xhr.status is 200 OK');
|
||||
ok(-1 < xhr.responseText.indexOf('Bug 484396'), 'xhr.responseText contains the calling page');
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
};
|
||||
|
||||
xhr.send('');
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -108,13 +108,13 @@ head.insertBefore(basehref0, head.firstChild);
|
|||
verifyBase("base6/", "insert base with href before existing");
|
||||
|
||||
// Insert base as grandchild of head
|
||||
var baseerr = document.createElement("base");
|
||||
baseerr.href = "baseerr/";
|
||||
var basehref3 = document.createElement("base");
|
||||
basehref3.href = "base7/";
|
||||
var tmp = document.createElement("head");
|
||||
tmp.appendChild(baseerr);
|
||||
tmp.appendChild(basehref3);
|
||||
head.insertBefore(tmp, head.firstChild);
|
||||
verifyBase("base6/", "inserted base as grandchild of head");
|
||||
is(baseerr.parentNode.parentNode, head, "base got inserted correctly");
|
||||
verifyBase("base7/", "inserted base as grandchild of head at the beginning of head");
|
||||
is(basehref3.parentNode.parentNode, head, "base got inserted correctly");
|
||||
|
||||
// Remove secondary bases
|
||||
var tmp, tmp2;
|
||||
|
@ -124,7 +124,7 @@ for (tmp = head.firstChild; tmp = tmp.nextSibling; tmp) {
|
|||
head.removeChild(tmp);
|
||||
tmp = tmp2;
|
||||
}
|
||||
verifyBase("base6/", "remove unneeded base");
|
||||
verifyBase("base7/", "remove unneeded base");
|
||||
}
|
||||
|
||||
// Remove head
|
||||
|
@ -132,8 +132,8 @@ document.documentElement.removeChild(head);
|
|||
verifyBase("", "removed head");
|
||||
|
||||
// Insert base in body
|
||||
document.body.insertBefore(baseerr, document.body.firstChild);
|
||||
verifyBase("", "inserted base in body");
|
||||
document.body.insertBefore(basehref3, document.body.firstChild);
|
||||
verifyBase("base7/", "inserted base in body");
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
|
|
|
@ -349,9 +349,12 @@ nsIDOMCanvasRenderingContext2D_PutImageData(JSContext *cx, uintN argc, jsval *vp
|
|||
hasDirtyRect = PR_TRUE;
|
||||
}
|
||||
|
||||
if (!JS_GetProperty(cx, dataObject, "data", tv.jsval_addr()) ||
|
||||
JSVAL_IS_PRIMITIVE(tv.jsval_value()))
|
||||
if (!JS_GetProperty(cx, dataObject, "data", tv.jsval_addr()))
|
||||
return JS_FALSE;
|
||||
|
||||
if (JSVAL_IS_PRIMITIVE(tv.jsval_value()))
|
||||
return xpc_qsThrow(cx, NS_ERROR_DOM_TYPE_MISMATCH_ERR);
|
||||
|
||||
darray = JSVAL_TO_OBJECT(tv.jsval_value());
|
||||
|
||||
js::AutoValueRooter tsrc_tvr(cx);
|
||||
|
|
|
@ -81,6 +81,7 @@ _TEST_FILES_0 = \
|
|||
test_2d.composite.uncovered.image.source-out.html \
|
||||
test_mozGetAsFile.html \
|
||||
test_canvas_strokeStyle_getter.html \
|
||||
test_bug613794.html \
|
||||
$(NULL)
|
||||
|
||||
ifneq (1_Linux,$(MOZ_SUITE)_$(OS_ARCH))
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=613794
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 613794</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=613794">Mozilla Bug 613794</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 613794 **/
|
||||
|
||||
var c = document.createElement("canvas");
|
||||
c.width = c.height = 1;
|
||||
|
||||
c = c.getContext("2d");
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var threw = true;
|
||||
try {
|
||||
c.putImageData({ width: 1, height: 1, data: [ 0, 0, 0, 0] }, 0, 0);
|
||||
threw = false;
|
||||
} catch(e) {
|
||||
threw = true;
|
||||
}
|
||||
|
||||
is(threw, false, "Should be able to pass in custom imagedata objects with array data");
|
||||
|
||||
threw = false;
|
||||
try {
|
||||
c.putImageData({ width: 1, height: 1, data: null }, 0, 0);
|
||||
threw = false;
|
||||
} catch(e) {
|
||||
threw = e.code;
|
||||
}
|
||||
|
||||
is(threw, DOMException.TYPE_MISMATCH_ERR,
|
||||
"Should throw type error when data is not an array");
|
||||
SimpleTest.finish();
|
||||
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -447,7 +447,7 @@ nsHTMLButtonElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
|||
if (fm)
|
||||
fm->SetFocus(this, nsIFocusManager::FLAG_BYMOUSE |
|
||||
nsIFocusManager::FLAG_NOSCROLL);
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
aVisitor.mEvent->flags |= NS_EVENT_FLAG_PREVENT_ANCHOR_ACTIONS;
|
||||
} else if (static_cast<nsMouseEvent*>(aVisitor.mEvent)->button ==
|
||||
nsMouseEvent::eMiddleButton ||
|
||||
static_cast<nsMouseEvent*>(aVisitor.mEvent)->button ==
|
||||
|
|
|
@ -377,18 +377,14 @@ nsHTMLSharedElement::IsAttributeMapped(const nsIAtom* aAttribute) const
|
|||
return nsGenericHTMLElement::IsAttributeMapped(aAttribute);
|
||||
}
|
||||
|
||||
void
|
||||
SetBaseURIUsingFirstBaseWithHref(nsIContent* aHead, nsIContent* aMustMatch)
|
||||
static void
|
||||
SetBaseURIUsingFirstBaseWithHref(nsIDocument* aDocument, nsIContent* aMustMatch)
|
||||
{
|
||||
NS_PRECONDITION(aHead && aHead->GetOwnerDoc() &&
|
||||
aHead->GetOwnerDoc()->GetHeadElement() == aHead,
|
||||
"Bad head");
|
||||
NS_PRECONDITION(aDocument, "Need a document!");
|
||||
|
||||
nsIDocument* doc = aHead->GetOwnerDoc();
|
||||
|
||||
for (nsINode::ChildIterator iter(aHead); !iter.IsDone(); iter.Next()) {
|
||||
nsIContent* child = iter;
|
||||
if (child->NodeInfo()->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) &&
|
||||
for (nsIContent* child = aDocument->GetFirstChild(); child;
|
||||
child = child->GetNextNode()) {
|
||||
if (child->IsHTML(nsGkAtoms::base) &&
|
||||
child->HasAttr(kNameSpaceID_None, nsGkAtoms::href)) {
|
||||
if (aMustMatch && child != aMustMatch) {
|
||||
return;
|
||||
|
@ -400,18 +396,43 @@ SetBaseURIUsingFirstBaseWithHref(nsIContent* aHead, nsIContent* aMustMatch)
|
|||
|
||||
nsCOMPtr<nsIURI> newBaseURI;
|
||||
nsContentUtils::NewURIWithDocumentCharset(
|
||||
getter_AddRefs(newBaseURI), href, doc, doc->GetDocumentURI());
|
||||
getter_AddRefs(newBaseURI), href, aDocument,
|
||||
aDocument->GetDocumentURI());
|
||||
|
||||
// Try to set our base URI. If that fails, try to set base URI to null
|
||||
nsresult rv = doc->SetBaseURI(newBaseURI);
|
||||
nsresult rv = aDocument->SetBaseURI(newBaseURI);
|
||||
if (NS_FAILED(rv)) {
|
||||
doc->SetBaseURI(nsnull);
|
||||
aDocument->SetBaseURI(nsnull);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
doc->SetBaseURI(nsnull);
|
||||
aDocument->SetBaseURI(nsnull);
|
||||
}
|
||||
|
||||
static void
|
||||
SetBaseTargetUsingFirstBaseWithTarget(nsIDocument* aDocument,
|
||||
nsIContent* aMustMatch)
|
||||
{
|
||||
NS_PRECONDITION(aDocument, "Need a document!");
|
||||
|
||||
for (nsIContent* child = aDocument->GetFirstChild(); child;
|
||||
child = child->GetNextNode()) {
|
||||
if (child->IsHTML(nsGkAtoms::base) &&
|
||||
child->HasAttr(kNameSpaceID_None, nsGkAtoms::target)) {
|
||||
if (aMustMatch && child != aMustMatch) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsString target;
|
||||
child->GetAttr(kNameSpaceID_None, nsGkAtoms::target, target);
|
||||
aDocument->SetBaseTarget(target);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
aDocument->SetBaseTarget(EmptyString());
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -425,15 +446,16 @@ nsHTMLSharedElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
|||
|
||||
// If the href attribute of a <base> tag is changing, we may need to update
|
||||
// the document's base URI, which will cause all the links on the page to be
|
||||
// re-resolved given the new base.
|
||||
nsIContent* head;
|
||||
if (mNodeInfo->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) &&
|
||||
aName == nsGkAtoms::href &&
|
||||
// re-resolved given the new base. If the target attribute is changing, we
|
||||
// similarly need to change the base target.
|
||||
if (mNodeInfo->Equals(nsGkAtoms::base) &&
|
||||
aNameSpaceID == kNameSpaceID_None &&
|
||||
IsInDoc() &&
|
||||
(head = GetParent()) &&
|
||||
head == GetOwnerDoc()->GetHeadElement()) {
|
||||
SetBaseURIUsingFirstBaseWithHref(head, this);
|
||||
IsInDoc()) {
|
||||
if (aName == nsGkAtoms::href) {
|
||||
SetBaseURIUsingFirstBaseWithHref(GetCurrentDoc(), this);
|
||||
} else if (aName == nsGkAtoms::target) {
|
||||
SetBaseTargetUsingFirstBaseWithTarget(GetCurrentDoc(), this);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -448,15 +470,15 @@ nsHTMLSharedElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
|||
|
||||
// If we're the first <base> with an href and our href attribute is being
|
||||
// unset, then we're no longer the first <base> with an href, and we need to
|
||||
// find the new one.
|
||||
nsIContent* head;
|
||||
if (mNodeInfo->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) &&
|
||||
aName == nsGkAtoms::href &&
|
||||
// find the new one. Similar for target.
|
||||
if (mNodeInfo->Equals(nsGkAtoms::base) &&
|
||||
aNameSpaceID == kNameSpaceID_None &&
|
||||
IsInDoc() &&
|
||||
(head = GetParent()) &&
|
||||
head == GetOwnerDoc()->GetHeadElement()) {
|
||||
SetBaseURIUsingFirstBaseWithHref(head, nsnull);
|
||||
IsInDoc()) {
|
||||
if (aName == nsGkAtoms::href) {
|
||||
SetBaseURIUsingFirstBaseWithHref(GetCurrentDoc(), nsnull);
|
||||
} else if (aName == nsGkAtoms::target) {
|
||||
SetBaseTargetUsingFirstBaseWithTarget(GetCurrentDoc(), nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -472,14 +494,16 @@ nsHTMLSharedElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
|||
aCompileEventHandlers);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// The document stores a pointer to its first <base> element, which we may
|
||||
// The document stores a pointer to its base URI and base target, which we may
|
||||
// need to update here.
|
||||
if (mNodeInfo->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) &&
|
||||
HasAttr(kNameSpaceID_None, nsGkAtoms::href) &&
|
||||
aDocument && aParent &&
|
||||
aDocument->GetHeadElement() == aParent) {
|
||||
|
||||
SetBaseURIUsingFirstBaseWithHref(aParent, this);
|
||||
if (mNodeInfo->Equals(nsGkAtoms::base) &&
|
||||
aDocument) {
|
||||
if (HasAttr(kNameSpaceID_None, nsGkAtoms::href)) {
|
||||
SetBaseURIUsingFirstBaseWithHref(aDocument, this);
|
||||
}
|
||||
if (HasAttr(kNameSpaceID_None, nsGkAtoms::target)) {
|
||||
SetBaseTargetUsingFirstBaseWithTarget(aDocument, this);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -488,27 +512,18 @@ nsHTMLSharedElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
|||
void
|
||||
nsHTMLSharedElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
||||
{
|
||||
nsIDocument* doc;
|
||||
nsIContent* parent;
|
||||
PRBool inHeadBase = mNodeInfo->Equals(nsGkAtoms::base, kNameSpaceID_XHTML) &&
|
||||
(doc = GetCurrentDoc()) &&
|
||||
(parent = GetParent()) &&
|
||||
parent->NodeInfo()->Equals(nsGkAtoms::head,
|
||||
kNameSpaceID_XHTML);
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
|
||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||
|
||||
// If we're removing a <base> from a document, we may need to update the
|
||||
// document's record of the first base node.
|
||||
if (inHeadBase) {
|
||||
// We might have gotten here as a result of the <head> being removed
|
||||
// from the document. In that case we need to call SetBaseURI(nsnull)
|
||||
Element* head = doc->GetHeadElement();
|
||||
if (head) {
|
||||
SetBaseURIUsingFirstBaseWithHref(head, nsnull);
|
||||
// document's base URI and base target
|
||||
if (doc && mNodeInfo->Equals(nsGkAtoms::base)) {
|
||||
if (HasAttr(kNameSpaceID_None, nsGkAtoms::href)) {
|
||||
SetBaseURIUsingFirstBaseWithHref(doc, nsnull);
|
||||
}
|
||||
else {
|
||||
doc->SetBaseURI(nsnull);
|
||||
if (HasAttr(kNameSpaceID_None, nsGkAtoms::target)) {
|
||||
SetBaseTargetUsingFirstBaseWithTarget(doc, nsnull);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -250,6 +250,7 @@ _TEST_FILES = \
|
|||
test_bug601030.html \
|
||||
test_bug610687.html \
|
||||
test_bug618948.html \
|
||||
test_bug623291.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=623291
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 623291</title>
|
||||
<script type="application/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=623291">Mozilla Bug 623291</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<input id="textField" onfocus="next()" onblur="done();">
|
||||
<button id="b">a button</button>
|
||||
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
|
||||
/** Test for Bug 623291 **/
|
||||
|
||||
function runTest() {
|
||||
document.getElementById("textField").focus();
|
||||
}
|
||||
|
||||
function next() {
|
||||
synthesizeMouseAtCenter(document.getElementById('b'), {}, window);
|
||||
}
|
||||
|
||||
function done() {
|
||||
isnot(document.activeElement, document.getElementById("textField"),
|
||||
"TextField should not be active anymore!");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SimpleTest.waitForFocus(runTest);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -146,6 +146,12 @@ nsDSURIContentListener::DoContent(const char* aContentType,
|
|||
}
|
||||
|
||||
rv = mDocShell->CreateContentViewer(aContentType, request, aContentHandler);
|
||||
|
||||
if (rv == NS_ERROR_REMOTE_XUL) {
|
||||
request->Cancel(rv);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
// it's okay if we don't know how to handle the content
|
||||
return NS_OK;
|
||||
|
|
|
@ -3922,6 +3922,36 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI,
|
|||
// Bad Content Encoding.
|
||||
error.AssignLiteral("contentEncodingError");
|
||||
break;
|
||||
case NS_ERROR_REMOTE_XUL:
|
||||
{
|
||||
error.AssignLiteral("remoteXUL");
|
||||
|
||||
/**
|
||||
* We want to set an hardcoded messageStr which uses the
|
||||
* brandShortName.
|
||||
*/
|
||||
nsCOMPtr<nsIStringBundleService> stringBundleService =
|
||||
mozilla::services::GetStringBundleService();
|
||||
if (!stringBundleService) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIStringBundle> brandBundle;
|
||||
rv = stringBundleService->CreateBundle(kBrandBundleURL,
|
||||
getter_AddRefs(brandBundle));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsXPIDLString brandName;
|
||||
rv = brandBundle->GetStringFromName(NS_LITERAL_STRING("brandShortName").get(),
|
||||
getter_Copies(brandName));
|
||||
|
||||
// We could use something like nsTextFormatter::smprintf.
|
||||
messageStr.AssignLiteral("This page uses an unsupported technology "
|
||||
"that is no longer available in ");
|
||||
messageStr.Append(brandName);
|
||||
messageStr.AppendLiteral(".");
|
||||
break;
|
||||
}
|
||||
case NS_ERROR_UNSAFE_CONTENT_TYPE:
|
||||
// Channel refused to load from an unrecognized content type.
|
||||
error.AssignLiteral("unsafeContentType");
|
||||
|
@ -6253,6 +6283,7 @@ nsDocShell::EndPageLoad(nsIWebProgress * aProgress,
|
|||
aStatus == NS_ERROR_MALWARE_URI ||
|
||||
aStatus == NS_ERROR_PHISHING_URI ||
|
||||
aStatus == NS_ERROR_UNSAFE_CONTENT_TYPE ||
|
||||
aStatus == NS_ERROR_REMOTE_XUL ||
|
||||
NS_ERROR_GET_MODULE(aStatus) == NS_ERROR_MODULE_SECURITY) {
|
||||
DisplayLoadError(aStatus, url, nsnull, aChannel);
|
||||
}
|
||||
|
@ -7292,7 +7323,7 @@ nsDocShell::CreateContentViewer(const char *aContentType,
|
|||
aContentHandler, getter_AddRefs(viewer));
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
return NS_ERROR_FAILURE;
|
||||
return rv;
|
||||
|
||||
// Notify the current document that it is about to be unloaded!!
|
||||
//
|
||||
|
@ -7474,14 +7505,14 @@ nsDocShell::NewContentViewerObj(const char *aContentType,
|
|||
|
||||
// Now create an instance of the content viewer
|
||||
// nsLayoutDLF makes the determination if it should be a "view-source" instead of "view"
|
||||
NS_ENSURE_SUCCESS(docLoaderFactory->CreateInstance("view",
|
||||
aOpenedChannel,
|
||||
aLoadGroup, aContentType,
|
||||
static_cast<nsIContentViewerContainer*>(this),
|
||||
nsnull,
|
||||
aContentHandler,
|
||||
aViewer),
|
||||
NS_ERROR_FAILURE);
|
||||
nsresult rv = docLoaderFactory->CreateInstance("view",
|
||||
aOpenedChannel,
|
||||
aLoadGroup, aContentType,
|
||||
static_cast<nsIContentViewerContainer*>(this),
|
||||
nsnull,
|
||||
aContentHandler,
|
||||
aViewer);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
(*aViewer)->SetContainer(static_cast<nsIContentViewerContainer *>(this));
|
||||
return NS_OK;
|
||||
|
|
|
@ -70,9 +70,11 @@ NS_IMETHODIMP nsDocShellEnumerator::GetNext(nsISupports **outCurItem)
|
|||
if (mCurIndex >= mItemArray.Length()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
|
||||
// post-increment is important here
|
||||
return CallQueryInterface(mItemArray[mCurIndex++], outCurItem);
|
||||
nsCOMPtr<nsISupports> item = do_QueryReferent(mItemArray[mCurIndex++], &rv);
|
||||
item.forget(outCurItem);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* boolean hasMoreElements (); */
|
||||
|
@ -91,14 +93,14 @@ NS_IMETHODIMP nsDocShellEnumerator::HasMoreElements(PRBool *outHasMore)
|
|||
nsresult nsDocShellEnumerator::GetEnumerationRootItem(nsIDocShellTreeItem * *aEnumerationRootItem)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aEnumerationRootItem);
|
||||
*aEnumerationRootItem = mRootItem;
|
||||
NS_IF_ADDREF(*aEnumerationRootItem);
|
||||
nsCOMPtr<nsIDocShellTreeItem> item = do_QueryReferent(mRootItem);
|
||||
item.forget(aEnumerationRootItem);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsDocShellEnumerator::SetEnumerationRootItem(nsIDocShellTreeItem * aEnumerationRootItem)
|
||||
{
|
||||
mRootItem = aEnumerationRootItem;
|
||||
mRootItem = do_GetWeakReference(aEnumerationRootItem);
|
||||
ClearState();
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -142,14 +144,15 @@ nsresult nsDocShellEnumerator::ClearState()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsDocShellEnumerator::BuildDocShellArray(nsTArray<nsIDocShellTreeItem*>& inItemArray)
|
||||
nsresult nsDocShellEnumerator::BuildDocShellArray(nsTArray<nsWeakPtr>& inItemArray)
|
||||
{
|
||||
NS_ENSURE_TRUE(mRootItem, NS_ERROR_NOT_INITIALIZED);
|
||||
inItemArray.Clear();
|
||||
return BuildArrayRecursive(mRootItem, inItemArray);
|
||||
nsCOMPtr<nsIDocShellTreeItem> item = do_QueryReferent(mRootItem);
|
||||
return BuildArrayRecursive(item, inItemArray);
|
||||
}
|
||||
|
||||
nsresult nsDocShellForwardsEnumerator::BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsTArray<nsIDocShellTreeItem*>& inItemArray)
|
||||
nsresult nsDocShellForwardsEnumerator::BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsTArray<nsWeakPtr>& inItemArray)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIDocShellTreeNode> itemAsNode = do_QueryInterface(inItem, &rv);
|
||||
|
@ -160,7 +163,7 @@ nsresult nsDocShellForwardsEnumerator::BuildArrayRecursive(nsIDocShellTreeItem*
|
|||
if ((mDocShellType == nsIDocShellTreeItem::typeAll) ||
|
||||
(NS_SUCCEEDED(inItem->GetItemType(&itemType)) && (itemType == mDocShellType)))
|
||||
{
|
||||
if (!inItemArray.AppendElement(inItem))
|
||||
if (!inItemArray.AppendElement(do_GetWeakReference(inItem)))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
@ -182,7 +185,7 @@ nsresult nsDocShellForwardsEnumerator::BuildArrayRecursive(nsIDocShellTreeItem*
|
|||
}
|
||||
|
||||
|
||||
nsresult nsDocShellBackwardsEnumerator::BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsTArray<nsIDocShellTreeItem*>& inItemArray)
|
||||
nsresult nsDocShellBackwardsEnumerator::BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsTArray<nsWeakPtr>& inItemArray)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIDocShellTreeNode> itemAsNode = do_QueryInterface(inItem, &rv);
|
||||
|
@ -207,7 +210,7 @@ nsresult nsDocShellBackwardsEnumerator::BuildArrayRecursive(nsIDocShellTreeItem*
|
|||
if ((mDocShellType == nsIDocShellTreeItem::typeAll) ||
|
||||
(NS_SUCCEEDED(inItem->GetItemType(&itemType)) && (itemType == mDocShellType)))
|
||||
{
|
||||
if (!inItemArray.AppendElement(inItem))
|
||||
if (!inItemArray.AppendElement(do_GetWeakReference(inItem)))
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@
|
|||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsIWeakReference.h"
|
||||
#include "nsIWeakReferenceUtils.h"
|
||||
|
||||
class nsIDocShellTreeItem;
|
||||
|
||||
|
@ -98,14 +100,14 @@ protected:
|
|||
nsresult EnsureDocShellArray();
|
||||
nsresult ClearState();
|
||||
|
||||
nsresult BuildDocShellArray(nsTArray<nsIDocShellTreeItem*>& inItemArray);
|
||||
virtual nsresult BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsTArray<nsIDocShellTreeItem*>& inItemArray) = 0;
|
||||
nsresult BuildDocShellArray(nsTArray<nsWeakPtr>& inItemArray);
|
||||
virtual nsresult BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsTArray<nsWeakPtr>& inItemArray) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
nsIDocShellTreeItem* mRootItem; // weak ref!
|
||||
nsWeakPtr mRootItem; // weak ref!
|
||||
|
||||
nsTArray<nsIDocShellTreeItem*> mItemArray; // flattened list of items with matching type
|
||||
nsTArray<nsWeakPtr> mItemArray; // flattened list of items with matching type
|
||||
PRUint32 mCurIndex;
|
||||
|
||||
PRInt32 mDocShellType; // only want shells of this type
|
||||
|
@ -126,7 +128,7 @@ public:
|
|||
|
||||
protected:
|
||||
|
||||
virtual nsresult BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsTArray<nsIDocShellTreeItem*>& inItemArray);
|
||||
virtual nsresult BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsTArray<nsWeakPtr>& inItemArray);
|
||||
|
||||
};
|
||||
|
||||
|
@ -140,6 +142,6 @@ public:
|
|||
}
|
||||
protected:
|
||||
|
||||
virtual nsresult BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsTArray<nsIDocShellTreeItem*>& inItemArray);
|
||||
virtual nsresult BuildArrayRecursive(nsIDocShellTreeItem* inItem, nsTArray<nsWeakPtr>& inItemArray);
|
||||
|
||||
};
|
||||
|
|
|
@ -186,6 +186,12 @@
|
|||
showSecuritySection();
|
||||
}
|
||||
|
||||
if (err == "remoteXUL") {
|
||||
// Remove the "Try again" button for remote XUL errors given that
|
||||
// it is useless.
|
||||
document.getElementById("errorTryAgain").style.display = "none";
|
||||
}
|
||||
|
||||
if (err == "cspFrameAncestorBlocked") {
|
||||
// Remove the "Try again" button for CSP frame ancestors violation, since it's
|
||||
// almost certainly useless. (Bug 553180)
|
||||
|
@ -322,6 +328,7 @@
|
|||
<h1 id="et_nssBadCert">&nssBadCert.title;</h1>
|
||||
<h1 id="et_malwareBlocked">&malwareBlocked.title;</h1>
|
||||
<h1 id="et_cspFrameAncestorBlocked">&cspFrameAncestorBlocked.title;</h1>
|
||||
<h1 id="et_remoteXUL">Remote XUL</h1>
|
||||
</div>
|
||||
<div id="errorDescriptionsContainer">
|
||||
<div id="ed_generic">&generic.longDesc;</div>
|
||||
|
@ -345,6 +352,7 @@
|
|||
<div id="ed_nssBadCert">&nssBadCert.longDesc2;</div>
|
||||
<div id="ed_malwareBlocked">&malwareBlocked.longDesc;</div>
|
||||
<div id="ed_cspFrameAncestorBlocked">&cspFrameAncestorBlocked.longDesc;</div>
|
||||
<div id="ed_remoteXUL"><ul><li>Please contact the website owners to inform them of this problem.</li></ul></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -2544,7 +2544,6 @@ PluginInstanceChild::PaintRectToPlatformSurface(const nsIntRect& aRect,
|
|||
if (mMaemoImageRendering &&
|
||||
aSurface->GetType() == gfxASurface::SurfaceTypeImage) {
|
||||
aSurface->Flush();
|
||||
mPendingPluginCall = PR_TRUE;
|
||||
gfxImageSurface* image = static_cast<gfxImageSurface*>(aSurface);
|
||||
NPImageExpose imgExp;
|
||||
imgExp.depth = gfxUtils::ImageFormatToDepth(image->Format());
|
||||
|
@ -2577,14 +2576,12 @@ PluginInstanceChild::PaintRectToPlatformSurface(const nsIntRect& aRect,
|
|||
exposeEvent.major_code = 0;
|
||||
exposeEvent.minor_code = 0;
|
||||
mPluginIface->event(&mData, reinterpret_cast<void*>(&exposeEvent));
|
||||
mPendingPluginCall = PR_FALSE;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
NS_ASSERTION(aSurface->GetType() == gfxASurface::SurfaceTypeXlib,
|
||||
"Non supported platform surface type");
|
||||
|
||||
mPendingPluginCall = true;
|
||||
NPEvent pluginEvent;
|
||||
XGraphicsExposeEvent& exposeEvent = pluginEvent.xgraphicsexpose;
|
||||
exposeEvent.type = GraphicsExpose;
|
||||
|
@ -2601,7 +2598,6 @@ PluginInstanceChild::PaintRectToPlatformSurface(const nsIntRect& aRect,
|
|||
exposeEvent.major_code = 0;
|
||||
exposeEvent.minor_code = 0;
|
||||
mPluginIface->event(&mData, reinterpret_cast<void*>(&exposeEvent));
|
||||
mPendingPluginCall = false;
|
||||
return;
|
||||
#endif
|
||||
|
||||
|
@ -2609,8 +2605,6 @@ PluginInstanceChild::PaintRectToPlatformSurface(const nsIntRect& aRect,
|
|||
NS_ASSERTION(SharedDIBSurface::IsSharedDIBSurface(aSurface),
|
||||
"Expected (SharedDIB) image surface.");
|
||||
|
||||
mPendingPluginCall = true;
|
||||
|
||||
// This rect is in the window coordinate space. aRect is in the plugin
|
||||
// coordinate space.
|
||||
RECT rect = {
|
||||
|
@ -2627,7 +2621,6 @@ PluginInstanceChild::PaintRectToPlatformSurface(const nsIntRect& aRect,
|
|||
::SetViewportOrgEx((HDC) mWindow.window, -mWindow.x, -mWindow.y, NULL);
|
||||
|
||||
mPluginIface->event(&mData, reinterpret_cast<void*>(&paintEvent));
|
||||
mPendingPluginCall = false;
|
||||
return;
|
||||
#endif
|
||||
|
||||
|
@ -2737,6 +2730,9 @@ PluginInstanceChild::ShowPluginFrame()
|
|||
return false;
|
||||
}
|
||||
|
||||
AutoRestore<bool> pending(mPendingPluginCall);
|
||||
mPendingPluginCall = true;
|
||||
|
||||
if (!EnsureCurrentBuffer()) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -872,11 +872,6 @@ ShowNativePrintDialog(HWND aHWnd,
|
|||
}
|
||||
}
|
||||
|
||||
NS_ASSERTION(!printerName.IsEmpty(), "We have to have a printer name");
|
||||
if (printerName.IsEmpty()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Now create a DEVNAMES struct so the the dialog is initialized correctly.
|
||||
|
||||
PRUint32 len = printerName.Length();
|
||||
|
|
|
@ -691,6 +691,43 @@ gfxWindowsPlatform::WindowsOSVersion()
|
|||
return winVersion;
|
||||
}
|
||||
|
||||
void
|
||||
gfxWindowsPlatform::GetDLLVersion(PRUnichar *aDLLPath, nsAString& aVersion)
|
||||
{
|
||||
DWORD versInfoSize, vers[4] = {0};
|
||||
// version info not available case
|
||||
aVersion.Assign(NS_LITERAL_STRING("0.0.0.0"));
|
||||
versInfoSize = GetFileVersionInfoSizeW(aDLLPath, NULL);
|
||||
nsAutoTArray<BYTE,512> versionInfo;
|
||||
|
||||
if (!versionInfo.AppendElements(PRUint32(versInfoSize))) {
|
||||
return;
|
||||
}
|
||||
if (!GetFileVersionInfoW(aDLLPath, NULL, versInfoSize,
|
||||
LPBYTE(versionInfo.Elements()))) {
|
||||
return;
|
||||
}
|
||||
|
||||
UINT len;
|
||||
VS_FIXEDFILEINFO *fileInfo;
|
||||
if (!VerQueryValue(LPBYTE(versionInfo.Elements()), TEXT("\\"),
|
||||
(LPVOID *)&fileInfo , &len)) {
|
||||
return;
|
||||
}
|
||||
|
||||
DWORD fileVersMS = fileInfo->dwFileVersionMS;
|
||||
DWORD fileVersLS = fileInfo->dwFileVersionLS;
|
||||
|
||||
vers[0] = HIWORD(fileVersMS);
|
||||
vers[1] = LOWORD(fileVersMS);
|
||||
vers[2] = HIWORD(fileVersLS);
|
||||
vers[3] = LOWORD(fileVersLS);
|
||||
|
||||
char buf[256];
|
||||
sprintf(buf, "%d.%d.%d.%d", vers[0], vers[1], vers[2], vers[3]);
|
||||
aVersion.Assign(NS_ConvertUTF8toUTF16(buf));
|
||||
}
|
||||
|
||||
void
|
||||
gfxWindowsPlatform::FontsPrefsChanged(nsIPrefBranch *aPrefBranch, const char *aPref)
|
||||
{
|
||||
|
|
|
@ -227,6 +227,8 @@ public:
|
|||
|
||||
static PRInt32 WindowsOSVersion();
|
||||
|
||||
static void GetDLLVersion(PRUnichar *aDLLPath, nsAString& aVersion);
|
||||
|
||||
virtual void FontsPrefsChanged(nsIPrefBranch *aPrefBranch, const char *aPref);
|
||||
|
||||
#ifdef CAIRO_HAS_DWRITE_FONT
|
||||
|
|
|
@ -8791,9 +8791,29 @@ nsCSSFrameConstructor::ReplicateFixedFrames(nsPageContentFrame* aParentFrame)
|
|||
nsIFrame* prevPlaceholder = mPresShell->FrameManager()->GetPlaceholderFrameFor(fixed);
|
||||
if (prevPlaceholder &&
|
||||
nsLayoutUtils::IsProperAncestorFrame(prevCanvasFrame, prevPlaceholder)) {
|
||||
nsresult rv = ConstructFrame(state, fixed->GetContent(),
|
||||
canvasFrame, fixedPlaceholders);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// We want to use the same style as the primary style frame for
|
||||
// our content
|
||||
nsIContent* content = fixed->GetContent();
|
||||
nsStyleContext* styleContext =
|
||||
nsLayoutUtils::GetStyleFrame(content->GetPrimaryFrame())->
|
||||
GetStyleContext();
|
||||
FrameConstructionItemList items;
|
||||
AddFrameConstructionItemsInternal(state, content, canvasFrame,
|
||||
content->Tag(),
|
||||
content->GetNameSpaceID(),
|
||||
PR_TRUE,
|
||||
styleContext,
|
||||
ITEM_ALLOW_XBL_BASE |
|
||||
ITEM_ALLOW_PAGE_BREAK,
|
||||
items);
|
||||
for (FCItemIterator iter(items); !iter.IsDone(); iter.Next()) {
|
||||
NS_ASSERTION(iter.item().DesiredParentType() ==
|
||||
GetParentType(canvasFrame),
|
||||
"This is not going to work");
|
||||
nsresult rv =
|
||||
ConstructFramesFromItem(state, iter, canvasFrame, fixedPlaceholders);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2288,7 +2288,7 @@ nsCSSRendering::PaintBackgroundWithSC(nsPresContext* aPresContext,
|
|||
currentBackgroundClip = bg->BottomLayer().mClip;
|
||||
isSolidBorder =
|
||||
(aFlags & PAINTBG_WILL_PAINT_BORDER) && IsOpaqueBorder(aBorder);
|
||||
if (isSolidBorder)
|
||||
if (isSolidBorder && currentBackgroundClip == NS_STYLE_BG_CLIP_BORDER)
|
||||
currentBackgroundClip = NS_STYLE_BG_CLIP_PADDING;
|
||||
SetupBackgroundClip(ctx, currentBackgroundClip, aForFrame,
|
||||
aBorderArea, aDirtyRect, haveRoundedCorners,
|
||||
|
|
|
@ -281,8 +281,11 @@ nsContentDLF::CreateInstance(const char* aCommand,
|
|||
// Try XUL
|
||||
typeIndex = 0;
|
||||
while (gXULTypes[typeIndex]) {
|
||||
if (0 == PL_strcmp(gXULTypes[typeIndex++], aContentType) &&
|
||||
MayUseXULXBL(aChannel)) {
|
||||
if (0 == PL_strcmp(gXULTypes[typeIndex++], aContentType)) {
|
||||
if (!MayUseXULXBL(aChannel)) {
|
||||
return NS_ERROR_REMOTE_XUL;
|
||||
}
|
||||
|
||||
return CreateXULDocument(aCommand,
|
||||
aChannel, aLoadGroup,
|
||||
aContentType, aContainer,
|
||||
|
|
|
@ -44,14 +44,15 @@
|
|||
#include "nsGkAtoms.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
|
||||
#include "nsIBaseWindow.h"
|
||||
|
||||
//---------------------------------------------------
|
||||
//-- nsPrintObject Class Impl
|
||||
//---------------------------------------------------
|
||||
nsPrintObject::nsPrintObject() :
|
||||
mContent(nsnull), mFrameType(eFrame), mParent(nsnull),
|
||||
mHasBeenPrinted(PR_FALSE), mDontPrint(PR_TRUE), mPrintAsIs(PR_FALSE),
|
||||
mSharedPresShell(PR_FALSE), mInvisible(PR_FALSE),
|
||||
mSharedPresShell(PR_FALSE), mInvisible(PR_FALSE), mDidCreateDocShell(PR_FALSE),
|
||||
mShrinkRatio(1.0), mZoomRatio(1.0)
|
||||
{
|
||||
}
|
||||
|
@ -65,6 +66,12 @@ nsPrintObject::~nsPrintObject()
|
|||
}
|
||||
|
||||
DestroyPresentation();
|
||||
if (mDidCreateDocShell && mDocShell) {
|
||||
nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(mDocShell));
|
||||
if (baseWin) {
|
||||
baseWin->Destroy();
|
||||
}
|
||||
}
|
||||
mDocShell = nsnull;
|
||||
mTreeOwner = nsnull; // mTreeOwner must be released after mDocShell;
|
||||
}
|
||||
|
@ -86,6 +93,7 @@ nsPrintObject::Init(nsIDocShell* aDocShell, nsIDOMDocument* aDoc,
|
|||
// Create a container docshell for printing.
|
||||
mDocShell = do_CreateInstance("@mozilla.org/docshell;1");
|
||||
NS_ENSURE_TRUE(mDocShell, NS_ERROR_OUT_OF_MEMORY);
|
||||
mDidCreateDocShell = PR_TRUE;
|
||||
nsCOMPtr<nsIDocShellTreeItem> newItem = do_QueryInterface(mDocShell);
|
||||
newItem->SetItemType(itemType);
|
||||
newItem->SetTreeOwner(mTreeOwner);
|
||||
|
|
|
@ -89,6 +89,7 @@ public:
|
|||
PRPackedBool mSharedPresShell;
|
||||
PRPackedBool mInvisible; // Indicates PO is set to not visible by CSS
|
||||
PRPackedBool mPrintPreview;
|
||||
PRPackedBool mDidCreateDocShell;
|
||||
float mShrinkRatio;
|
||||
float mZoomRatio;
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<div style="padding: 10px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border: 10px solid black">
|
||||
<div style="width: 100px; height: 100px; background: black">
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,12 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<div style="padding: 10px;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: black;
|
||||
border: 10px solid black;
|
||||
background-clip: content-box;">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -27,6 +27,7 @@
|
|||
== background-redraw-237766.html background-redraw-237766-ref.html
|
||||
|
||||
== background-clip-1.html background-clip-1-ref.html
|
||||
== background-clip-2.html background-clip-2-ref.html
|
||||
|
||||
== background-size-auto-auto.html background-size-auto-ref.html
|
||||
== background-size-auto.html background-size-auto-ref.html
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-print">
|
||||
<body>
|
||||
<div style="position: fixed; color: green; font-size: 2em">Big green text</div>
|
||||
<!-- force two pages -->
|
||||
<div style="height: 3in; width: 2in"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,8 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="reftest-print">
|
||||
<body style="color: green; font-size: 2em">
|
||||
<div style="position: fixed">Big green text</div>
|
||||
<!-- force two pages -->
|
||||
<div style="height: 3in; width: 2in"></div>
|
||||
</body>
|
||||
</html>
|
|
@ -9,3 +9,4 @@
|
|||
== test-async-print.html 272830-1-ref.html
|
||||
== 129941-1a.html 129941-1-ref.html
|
||||
== 129941-1b.html 129941-1-ref.html
|
||||
== 577450-1.html 577450-1-ref.html
|
||||
|
|
|
@ -285,7 +285,7 @@ static nsresult ConvertToUTF8(nsIUnicodeDecoder *aUnicodeDecoder,
|
|||
|
||||
nsresult nsPluginTag::EnsureMembersAreUTF8()
|
||||
{
|
||||
#ifdef XP_WIN
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX)
|
||||
return NS_OK;
|
||||
#else
|
||||
nsresult rv;
|
||||
|
|
|
@ -124,12 +124,27 @@ PRBool nsPluginsDir::IsPluginFile(nsIFile* file)
|
|||
// Caller is responsible for freeing returned buffer.
|
||||
static char* CFStringRefToUTF8Buffer(CFStringRef cfString)
|
||||
{
|
||||
int bufferLength = ::CFStringGetLength(cfString) + 1;
|
||||
char* newBuffer = static_cast<char*>(NS_Alloc(bufferLength));
|
||||
if (newBuffer && !::CFStringGetCString(cfString, newBuffer, bufferLength, kCFStringEncodingUTF8)) {
|
||||
NS_Free(newBuffer);
|
||||
newBuffer = nsnull;
|
||||
const char* buffer = ::CFStringGetCStringPtr(cfString, kCFStringEncodingUTF8);
|
||||
if (buffer) {
|
||||
return PL_strdup(buffer);
|
||||
}
|
||||
|
||||
int bufferLength =
|
||||
::CFStringGetMaximumSizeForEncoding(::CFStringGetLength(cfString),
|
||||
kCFStringEncodingUTF8) + 1;
|
||||
char* newBuffer = static_cast<char*>(NS_Alloc(bufferLength));
|
||||
if (!newBuffer) {
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
if (!::CFStringGetCString(cfString, newBuffer, bufferLength,
|
||||
kCFStringEncodingUTF8)) {
|
||||
NS_Free(newBuffer);
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
newBuffer = static_cast<char*>(NS_Realloc(newBuffer,
|
||||
PL_strlen(newBuffer) + 1));
|
||||
return newBuffer;
|
||||
}
|
||||
|
||||
|
|
|
@ -129,8 +129,6 @@ _MOCHICHROME_FILES += \
|
|||
$(NULL)
|
||||
endif
|
||||
|
||||
# Temporarily disable the tests on Linux, see bug 573290 and bug 583591.
|
||||
ifneq ($(OS_ARCH),Linux)
|
||||
ifdef MOZ_CRASHREPORTER
|
||||
_MOCHICHROME_FILES += \
|
||||
test_crash_notify.xul \
|
||||
|
@ -138,7 +136,6 @@ _MOCHICHROME_FILES += \
|
|||
test_crash_submit.xul \
|
||||
$(NULL)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
||||
_MOCHICHROME_FILES += \
|
||||
|
|
|
@ -240,6 +240,14 @@
|
|||
#define NS_ERROR_UNSAFE_CONTENT_TYPE \
|
||||
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 74)
|
||||
|
||||
/**
|
||||
* The request failed because the user tried to access to a remote XUL document
|
||||
* from a website that is not in its white-list.
|
||||
*/
|
||||
#define NS_ERROR_REMOTE_XUL \
|
||||
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 75)
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* FTP specific error codes:
|
||||
*
|
||||
|
|
|
@ -149,9 +149,7 @@ nsHtml5TreeBuilder::createElement(PRInt32 aNamespace, nsIAtom* aName, nsHtml5Htm
|
|||
if (url) {
|
||||
mSpeculativeLoadQueue.AppendElement()->InitManifest(*url);
|
||||
}
|
||||
} else if (nsHtml5Atoms::base == aName &&
|
||||
(mode == NS_HTML5TREE_BUILDER_IN_HEAD ||
|
||||
mode == NS_HTML5TREE_BUILDER_AFTER_HEAD)) {
|
||||
} else if (nsHtml5Atoms::base == aName) {
|
||||
nsString* url =
|
||||
aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
|
||||
if (url) {
|
||||
|
|
|
@ -299,6 +299,81 @@ function synthesizeMouseScroll(aTarget, aOffsetX, aOffsetY, aEvent, aWindow)
|
|||
}
|
||||
}
|
||||
|
||||
function _computeKeyCodeFromChar(aChar)
|
||||
{
|
||||
if (aChar.length != 1) {
|
||||
return 0;
|
||||
}
|
||||
const nsIDOMKeyEvent = Components.interfaces.nsIDOMKeyEvent;
|
||||
if (aChar >= 'a' && aChar <= 'z') {
|
||||
return nsIDOMKeyEvent.DOM_VK_A + aChar.charCodeAt(0) - 'a'.charCodeAt(0);
|
||||
}
|
||||
if (aChar >= 'A' && aChar <= 'Z') {
|
||||
return nsIDOMKeyEvent.DOM_VK_A + aChar.charCodeAt(0) - 'A'.charCodeAt(0);
|
||||
}
|
||||
if (aChar >= '0' && aChar <= '9') {
|
||||
return nsIDOMKeyEvent.DOM_VK_0 + aChar.charCodeAt(0) - '0'.charCodeAt(0);
|
||||
}
|
||||
// returns US keyboard layout's keycode
|
||||
switch (aChar) {
|
||||
case '~':
|
||||
case '`':
|
||||
return nsIDOMKeyEvent.DOM_VK_BACK_QUOTE;
|
||||
case '!':
|
||||
return nsIDOMKeyEvent.DOM_VK_1;
|
||||
case '@':
|
||||
return nsIDOMKeyEvent.DOM_VK_2;
|
||||
case '#':
|
||||
return nsIDOMKeyEvent.DOM_VK_3;
|
||||
case '$':
|
||||
return nsIDOMKeyEvent.DOM_VK_4;
|
||||
case '%':
|
||||
return nsIDOMKeyEvent.DOM_VK_5;
|
||||
case '^':
|
||||
return nsIDOMKeyEvent.DOM_VK_6;
|
||||
case '&':
|
||||
return nsIDOMKeyEvent.DOM_VK_7;
|
||||
case '*':
|
||||
return nsIDOMKeyEvent.DOM_VK_8;
|
||||
case '(':
|
||||
return nsIDOMKeyEvent.DOM_VK_9;
|
||||
case ')':
|
||||
return nsIDOMKeyEvent.DOM_VK_0;
|
||||
case '-':
|
||||
case '_':
|
||||
return nsIDOMKeyEvent.DOM_VK_SUBTRACT;
|
||||
case '+':
|
||||
case '=':
|
||||
return nsIDOMKeyEvent.DOM_VK_EQUALS;
|
||||
case '{':
|
||||
case '[':
|
||||
return nsIDOMKeyEvent.DOM_VK_OPEN_BRACKET;
|
||||
case '}':
|
||||
case ']':
|
||||
return nsIDOMKeyEvent.DOM_VK_CLOSE_BRACKET;
|
||||
case '|':
|
||||
case '\\':
|
||||
return nsIDOMKeyEvent.DOM_VK_BACK_SLASH;
|
||||
case ':':
|
||||
case ';':
|
||||
return nsIDOMKeyEvent.DOM_VK_SEMICOLON;
|
||||
case '\'':
|
||||
case '"':
|
||||
return nsIDOMKeyEvent.DOM_VK_QUOTE;
|
||||
case '<':
|
||||
case ',':
|
||||
return nsIDOMKeyEvent.DOM_VK_COMMA;
|
||||
case '>':
|
||||
case '.':
|
||||
return nsIDOMKeyEvent.DOM_VK_PERIOD;
|
||||
case '?':
|
||||
case '/':
|
||||
return nsIDOMKeyEvent.DOM_VK_SLASH;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Synthesize a key event. It is targeted at whatever would be targeted by an
|
||||
* actual keypress by the user, typically the focused element.
|
||||
|
@ -327,20 +402,24 @@ function synthesizeKey(aKey, aEvent, aWindow)
|
|||
var keyCode = 0, charCode = 0;
|
||||
if (aKey.indexOf("VK_") == 0)
|
||||
keyCode = KeyEvent["DOM_" + aKey];
|
||||
else
|
||||
else {
|
||||
charCode = aKey.charCodeAt(0);
|
||||
keyCode = _computeKeyCodeFromChar(aKey.charAt(0));
|
||||
}
|
||||
|
||||
var modifiers = _parseModifiers(aEvent);
|
||||
|
||||
if (aEvent.type) {
|
||||
utils.sendKeyEvent(aEvent.type, keyCode, charCode, modifiers);
|
||||
}
|
||||
else {
|
||||
if (aEvent.type == "keypress") {
|
||||
utils.sendKeyEvent(aEvent.type, charCode ? 0 : keyCode,
|
||||
charCode, modifiers);
|
||||
} else if (aEvent.type) {
|
||||
utils.sendKeyEvent(aEvent.type, keyCode, 0, modifiers);
|
||||
} else {
|
||||
var keyDownDefaultHappened =
|
||||
utils.sendKeyEvent("keydown", keyCode, charCode, modifiers);
|
||||
utils.sendKeyEvent("keypress", keyCode, charCode, modifiers,
|
||||
!keyDownDefaultHappened);
|
||||
utils.sendKeyEvent("keyup", keyCode, charCode, modifiers);
|
||||
utils.sendKeyEvent("keydown", keyCode, 0, modifiers);
|
||||
utils.sendKeyEvent("keypress", charCode ? 0 : keyCode, charCode,
|
||||
modifiers, !keyDownDefaultHappened);
|
||||
utils.sendKeyEvent("keyup", keyCode, 0, modifiers);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
#include "nsXPCOMCID.h"
|
||||
#include "plstr.h"
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#ifdef MOZ_WIDGET_COCOA
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include "nsILocalFileMac.h"
|
||||
#elif defined(XP_WIN)
|
||||
|
@ -287,7 +287,7 @@ nsCommandLine::ResolveFile(const nsAString& aArgument, nsIFile* *aResult)
|
|||
|
||||
nsresult rv;
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
#if defined(MOZ_WIDGET_COCOA)
|
||||
nsCOMPtr<nsILocalFileMac> lfm (do_QueryInterface(mWorkingDir));
|
||||
NS_ENSURE_TRUE(lfm, NS_ERROR_NO_INTERFACE);
|
||||
|
||||
|
|
|
@ -82,9 +82,9 @@ function run_test() {
|
|||
bmsvc.DEFAULT_INDEX, "");
|
||||
do_check_true(observer.itemChangedProperty == null);
|
||||
|
||||
// We set lastModified 1us in the past to workaround a timing bug on
|
||||
// We set lastModified in the past to workaround a timing bug on
|
||||
// virtual machines, see bug 427142 for details.
|
||||
var newDate = Date.now() * 1000 - 1;
|
||||
var newDate = (Date.now() - 10) * 1000;
|
||||
bmsvc.setItemDateAdded(bookmarkId, newDate);
|
||||
// test notification
|
||||
do_check_eq(observer._itemChangedProperty, "dateAdded");
|
||||
|
@ -129,7 +129,7 @@ function run_test() {
|
|||
// test live update of lastModified caused by other changes:
|
||||
// We set lastModified in the past to workaround timers resolution,
|
||||
// see bug 427142 for details.
|
||||
var pastDate = Date.now() * 1000 - 20000;
|
||||
var pastDate = (Date.now() - 10) * 1000;
|
||||
bmsvc.setItemLastModified(bookmarkId, pastDate);
|
||||
// set title (causing update of last modified)
|
||||
var oldLastModified = bmsvc.getItemLastModified(bookmarkId);
|
||||
|
|
|
@ -233,12 +233,16 @@ function populateGraphicsSection() {
|
|||
]));
|
||||
|
||||
var dwEnabled = false;
|
||||
var dwriteEnabledStr = dwEnabled.toString();
|
||||
var dwriteVersion;
|
||||
try {
|
||||
dwEnabled = gfxInfo.DWriteEnabled;
|
||||
dwriteVersion = gfxInfo.DWriteVersion;
|
||||
dwriteEnabledStr = dwEnabled.toString() + " (" + dwriteVersion + ")";
|
||||
} catch(e) {}
|
||||
trGraphics.push(createParentElement("tr", [
|
||||
createHeader(bundle.GetStringFromName("directWriteEnabled")),
|
||||
createElement("td", dwEnabled),
|
||||
createElement("td", dwriteEnabledStr),
|
||||
]));
|
||||
|
||||
var webglrenderer;
|
||||
|
|
|
@ -122,10 +122,7 @@ EXTRA_JS_MODULES = \
|
|||
$(NULL)
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
# Temporarily disable the tests on Linux, see bug 573290 and bug 583591
|
||||
ifneq ($(OS_ARCH),Linux)
|
||||
TOOL_DIRS = test
|
||||
endif
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -79,7 +79,9 @@
|
|||
#ifndef GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_H__
|
||||
#define GOOGLE_BREAKPAD_PROCESSOR_MINIDUMP_H__
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
|
|
@ -44,13 +44,21 @@
|
|||
|
||||
namespace google_breakpad {
|
||||
|
||||
#ifdef _WIN32
|
||||
#define snprintf _snprintf
|
||||
#endif
|
||||
|
||||
LogStream::LogStream(std::ostream &stream, Severity severity,
|
||||
const char *file, int line)
|
||||
: stream_(stream) {
|
||||
time_t clock;
|
||||
time(&clock);
|
||||
struct tm tm_struct;
|
||||
#ifdef _WIN32
|
||||
localtime_s(&tm_struct, &clock);
|
||||
#else
|
||||
localtime_r(&clock, &tm_struct);
|
||||
#endif
|
||||
char time_string[20];
|
||||
strftime(time_string, sizeof(time_string), "%Y-%m-%d %H:%M:%S", &tm_struct);
|
||||
|
||||
|
|
|
@ -68,6 +68,15 @@
|
|||
|
||||
namespace google_breakpad {
|
||||
|
||||
// These are defined in Microsoft headers.
|
||||
#ifdef SEVERITY_ERROR
|
||||
#undef SEVERITY_ERROR
|
||||
#endif
|
||||
|
||||
#ifdef ERROR
|
||||
#undef ERROR
|
||||
#endif
|
||||
|
||||
class LogStream {
|
||||
public:
|
||||
enum Severity {
|
||||
|
|
|
@ -40,14 +40,15 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <io.h>
|
||||
typedef SSIZE_T ssize_t;
|
||||
#define open _open
|
||||
#define read _read
|
||||
#define lseek _lseek
|
||||
#define PRIx64 "llx"
|
||||
#define PRIx32 "lx"
|
||||
#define snprintf _snprintf
|
||||
#else // _WIN32
|
||||
#include <unistd.h>
|
||||
#define O_BINARY 0
|
||||
#endif // _WIN32
|
||||
|
||||
|
@ -1101,7 +1102,7 @@ void MinidumpMemoryRegion::SetDescriptor(MDMemoryDescriptor* descriptor) {
|
|||
descriptor_ = descriptor;
|
||||
valid_ = descriptor &&
|
||||
descriptor_->memory.data_size <=
|
||||
numeric_limits<uint64_t>::max() -
|
||||
numeric_limits<u_int64_t>::max() -
|
||||
descriptor_->start_of_memory_range;
|
||||
}
|
||||
|
||||
|
@ -3688,7 +3689,11 @@ void Minidump::Print() {
|
|||
printf(" stream_directory_rva = 0x%x\n", header_.stream_directory_rva);
|
||||
printf(" checksum = 0x%x\n", header_.checksum);
|
||||
struct tm timestruct;
|
||||
#ifdef _WIN32
|
||||
gmtime_s(×truct, reinterpret_cast<time_t*>(&header_.time_date_stamp));
|
||||
#else
|
||||
gmtime_r(reinterpret_cast<time_t*>(&header_.time_date_stamp), ×truct);
|
||||
#endif
|
||||
char timestr[20];
|
||||
strftime(timestr, 20, "%Y-%m-%d %H:%M:%S", ×truct);
|
||||
printf(" time_date_stamp = 0x%x %s\n", header_.time_date_stamp,
|
||||
|
|
|
@ -209,10 +209,6 @@ static AnnotationTable* crashReporterAPIData_Hash;
|
|||
static nsCString* crashReporterAPIData = nsnull;
|
||||
static nsCString* notesField = nsnull;
|
||||
|
||||
#if defined(XP_WIN)
|
||||
static HMODULE dbghelp = NULL;
|
||||
#endif
|
||||
|
||||
#if defined(MOZ_IPC)
|
||||
// OOP crash reporting
|
||||
static CrashGenerationServer* crashServer; // chrome process has this
|
||||
|
@ -723,17 +719,23 @@ nsresult SetExceptionHandler(nsILocalFile* aXREDirectory,
|
|||
|
||||
#ifdef XP_WIN
|
||||
// Try to determine what version of dbghelp.dll we're using.
|
||||
// MinidumpWithFullMemoryInfo is only available in 6.2 or newer.
|
||||
dbghelp = LoadLibraryW(L"dbghelp.dll");
|
||||
// MinidumpWithFullMemoryInfo is only available in 6.1.x or newer.
|
||||
MINIDUMP_TYPE minidump_type = MiniDumpNormal;
|
||||
if (dbghelp) {
|
||||
typedef LPAPI_VERSION (WINAPI *ImagehlpApiVersionPtr)(void);
|
||||
ImagehlpApiVersionPtr imagehlp_api_version =
|
||||
(ImagehlpApiVersionPtr)GetProcAddress(dbghelp, "ImagehlpApiVersion");
|
||||
if (imagehlp_api_version) {
|
||||
LPAPI_VERSION api_version = imagehlp_api_version();
|
||||
if (api_version->MajorVersion > 6 ||
|
||||
(api_version->MajorVersion == 6 && api_version->MinorVersion > 1)) {
|
||||
DWORD version_size = GetFileVersionInfoSizeW(L"dbghelp.dll", NULL);
|
||||
if (version_size > 0) {
|
||||
std::vector<BYTE> buffer(version_size);
|
||||
if (GetFileVersionInfoW(L"dbghelp.dll",
|
||||
0,
|
||||
version_size,
|
||||
&buffer[0])) {
|
||||
UINT len;
|
||||
VS_FIXEDFILEINFO* file_info;
|
||||
VerQueryValue(&buffer[0], L"\\", (void**)&file_info, &len);
|
||||
WORD major = HIWORD(file_info->dwFileVersionMS),
|
||||
minor = LOWORD(file_info->dwFileVersionMS),
|
||||
revision = HIWORD(file_info->dwFileVersionLS);
|
||||
if (major > 6 || (major == 6 && minor > 1) ||
|
||||
(major == 6 && minor == 1 && revision >= 7600)) {
|
||||
minidump_type = MiniDumpWithFullMemoryInfo;
|
||||
}
|
||||
}
|
||||
|
@ -1028,12 +1030,6 @@ nsresult UnsetExceptionHandler()
|
|||
{
|
||||
delete gExceptionHandler;
|
||||
|
||||
#if defined(XP_WIN)
|
||||
if (dbghelp) {
|
||||
FreeLibrary(dbghelp);
|
||||
}
|
||||
#endif
|
||||
|
||||
// do this here in the unlikely case that we succeeded in allocating
|
||||
// our strings but failed to allocate gExceptionHandler.
|
||||
if (crashReporterAPIData_Hash) {
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
var EXPORTED_SYMBOLS = ["CrashTestUtils"];
|
||||
|
||||
let CrashTestUtils = {
|
||||
// These will be defined using ctypes APIs below.
|
||||
crash: null,
|
||||
lockDir: null,
|
||||
dumpHasStream: null,
|
||||
|
||||
// Constants for crash()
|
||||
// Keep these in sync with nsTestCrasher.cpp!
|
||||
CRASH_INVALID_POINTER_DEREF: 0,
|
||||
CRASH_PURE_VIRTUAL_CALL: 1,
|
||||
CRASH_RUNTIMEABORT: 2,
|
||||
|
||||
// Constants for dumpHasStream()
|
||||
// From google_breakpad/common/minidump_format.h
|
||||
MD_THREAD_LIST_STREAM: 3,
|
||||
MD_MEMORY_INFO_LIST_STREAM: 16
|
||||
};
|
||||
|
||||
// Grab APIs from the testcrasher shared library
|
||||
Components.utils.import("resource://gre/modules/ctypes.jsm");
|
||||
let dir = __LOCATION__.parent;
|
||||
let file = dir.clone();
|
||||
file.append(ctypes.libraryName("testcrasher"));
|
||||
let lib = ctypes.open(file.path);
|
||||
CrashTestUtils.crash = lib.declare("Crash",
|
||||
ctypes.default_abi,
|
||||
ctypes.void_t,
|
||||
ctypes.int16_t);
|
||||
|
||||
CrashTestUtils.lockDir = lib.declare("LockDir",
|
||||
ctypes.default_abi,
|
||||
ctypes.voidptr_t, // nsILocalFile*
|
||||
ctypes.voidptr_t); // nsISupports*
|
||||
|
||||
|
||||
CrashTestUtils.dumpHasStream = lib.declare("DumpHasStream",
|
||||
ctypes.default_abi,
|
||||
ctypes.bool,
|
||||
ctypes.char.ptr,
|
||||
ctypes.uint32_t);
|
|
@ -47,16 +47,26 @@ MODULE = crashreporter_test
|
|||
XPCSHELL_TESTS = unit
|
||||
|
||||
LIBRARY_NAME = testcrasher
|
||||
IS_COMPONENT = 1
|
||||
NO_DIST_INSTALL = 1
|
||||
|
||||
XPIDLSRCS = nsITestCrasher.idl
|
||||
VPATH += \
|
||||
$(srcdir)/../google-breakpad/src/processor/ \
|
||||
$(srcdir)/../google-breakpad/src/common/ \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
nsTestCrasher.cpp \
|
||||
dumputils.cpp \
|
||||
basic_code_modules.cc \
|
||||
logging.cc \
|
||||
minidump.cc \
|
||||
pathname_stripper.cc \
|
||||
$(NULL)
|
||||
|
||||
LOCAL_INCLUDES += -I$(XPIDL_GEN_DIR)
|
||||
LOCAL_INCLUDES += \
|
||||
-I$(XPIDL_GEN_DIR) \
|
||||
-I$(srcdir)/../google-breakpad/src/ \
|
||||
$(NULL)
|
||||
EXTRA_DSO_LIBS += xpcom
|
||||
EXTRA_DSO_LDOPTS += $(LIBS_DIR) $(MOZ_COMPONENT_LIBS)
|
||||
|
||||
|
@ -76,11 +86,11 @@ EXTRA_DSO_LDOPTS += $(EXTRA_DSO_LIBS) $(XPCOM_LIBS)
|
|||
|
||||
endif
|
||||
|
||||
EXTRA_PP_COMPONENTS = testcrasher.manifest
|
||||
EXTRA_JS_MODULES = CrashTestUtils.jsm
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
DEFINES += -DSHARED_LIBRARY=$(SHARED_LIBRARY)
|
||||
DEFINES += -DSHARED_LIBRARY=$(SHARED_LIBRARY) -DNOMINMAX
|
||||
|
||||
ifneq (mobile,$(MOZ_BUILD_APP))
|
||||
_BROWSER_FILES = \
|
||||
|
@ -95,7 +105,6 @@ libs:: $(_BROWSER_FILES)
|
|||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)/browser
|
||||
endif
|
||||
|
||||
libs:: $(SHARED_LIBRARY) $(XPIDL_GEN_DIR)/$(XPIDL_MODULE).xpt
|
||||
$(NSINSTALL) -D $(DEPTH)/_tests/xpcshell/$(relativesrcdir)/unit/components
|
||||
$(INSTALL) $^ $(DEPTH)/_tests/xpcshell/$(relativesrcdir)/unit/components
|
||||
$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $(XULPPFLAGS) $(srcdir)/testcrasher.manifest > $(DEPTH)/_tests/xpcshell/$(relativesrcdir)/unit/components/testcrasher.manifest
|
||||
libs:: $(SHARED_LIBRARY) $(EXTRA_JS_MODULES)
|
||||
$(INSTALL) $^ $(DEPTH)/_tests/xpcshell/$(relativesrcdir)/unit/
|
||||
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
#include "google_breakpad/processor/minidump.h"
|
||||
#include "nscore.h"
|
||||
|
||||
using namespace google_breakpad;
|
||||
|
||||
extern "C"
|
||||
NS_EXPORT bool
|
||||
DumpHasStream(const char* dump_file, u_int32_t stream_type)
|
||||
{
|
||||
Minidump dump(dump_file);
|
||||
if (!dump.Read())
|
||||
return false;
|
||||
|
||||
u_int32_t length;
|
||||
if (!dump.SeekToStreamType(stream_type, &length) || length == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
#include "nsISupports.idl"
|
||||
|
||||
interface nsILocalFile;
|
||||
|
||||
[scriptable, uuid(95464a04-6949-46cb-b621-d167790704a0)]
|
||||
interface nsITestCrasher : nsISupports
|
||||
{
|
||||
void crash(in short how);
|
||||
|
||||
/**
|
||||
* Lock a directory using XRE_LockProfileDirectory.
|
||||
*
|
||||
* @param directory The directory to lock
|
||||
* @return An opaque lock object.
|
||||
*/
|
||||
nsISupports lockDir(in nsILocalFile directory);
|
||||
|
||||
const short CRASH_INVALID_POINTER_DEREF = 0;
|
||||
const short CRASH_PURE_VIRTUAL_CALL = 1;
|
||||
const short CRASH_RUNTIMEABORT = 2;
|
||||
};
|
|
@ -1,23 +1,5 @@
|
|||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIComponentManager.h"
|
||||
#include "nsITestCrasher.h"
|
||||
#include "nscore.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
#include "mozilla/ModuleUtils.h"
|
||||
|
||||
class nsTestCrasher : public nsITestCrasher
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSITESTCRASHER
|
||||
|
||||
nsTestCrasher() {}
|
||||
|
||||
private:
|
||||
~nsTestCrasher() {};
|
||||
};
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsTestCrasher, nsITestCrasher)
|
||||
|
||||
/*
|
||||
* This pure virtual call example is from MSDN
|
||||
|
@ -49,59 +31,39 @@ void PureVirtualCall()
|
|||
B b;
|
||||
}
|
||||
|
||||
/* void crash (); */
|
||||
NS_IMETHODIMP nsTestCrasher::Crash(PRInt16 how)
|
||||
// Keep these in sync with CrashTestUtils.jsm!
|
||||
const PRInt16 CRASH_INVALID_POINTER_DEREF = 0;
|
||||
const PRInt16 CRASH_PURE_VIRTUAL_CALL = 1;
|
||||
const PRInt16 CRASH_RUNTIMEABORT = 2;
|
||||
|
||||
extern "C" NS_EXPORT
|
||||
void Crash(PRInt16 how)
|
||||
{
|
||||
switch (how) {
|
||||
case nsITestCrasher::CRASH_INVALID_POINTER_DEREF: {
|
||||
case CRASH_INVALID_POINTER_DEREF: {
|
||||
volatile int* foo = (int*)0x42;
|
||||
*foo = 0;
|
||||
// not reached
|
||||
break;
|
||||
}
|
||||
case nsITestCrasher::CRASH_PURE_VIRTUAL_CALL: {
|
||||
case CRASH_PURE_VIRTUAL_CALL: {
|
||||
PureVirtualCall();
|
||||
// not reached
|
||||
break;
|
||||
}
|
||||
case nsITestCrasher::CRASH_RUNTIMEABORT: {
|
||||
case CRASH_RUNTIMEABORT: {
|
||||
NS_RUNTIMEABORT("Intentional crash");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
break;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* nsISupports LockDir (in nsILocalFile directory); */
|
||||
NS_IMETHODIMP nsTestCrasher::LockDir(nsILocalFile *directory,
|
||||
nsISupports **_retval NS_OUTPARAM)
|
||||
extern "C" NS_EXPORT
|
||||
nsISupports* LockDir(nsILocalFile *directory)
|
||||
{
|
||||
return XRE_LockProfileDirectory(directory, _retval);
|
||||
nsISupports* lockfile = nsnull;
|
||||
XRE_LockProfileDirectory(directory, &lockfile);
|
||||
return lockfile;
|
||||
}
|
||||
|
||||
// 54afce51-38d7-4df0-9750-2f90f9ffbca2
|
||||
#define NS_TESTCRASHER_CID \
|
||||
{ 0x54afce51, 0x38d7, 0x4df0, {0x97, 0x50, 0x2f, 0x90, 0xf9, 0xff, 0xbc, 0xa2} }
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsTestCrasher)
|
||||
NS_DEFINE_NAMED_CID(NS_TESTCRASHER_CID);
|
||||
|
||||
static const mozilla::Module::CIDEntry kTestCrasherCIDs[] = {
|
||||
{ &kNS_TESTCRASHER_CID, false, NULL, nsTestCrasherConstructor },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static const mozilla::Module::ContractIDEntry kTestCrasherContracts[] = {
|
||||
{ "@mozilla.org/testcrasher;1", &kNS_TESTCRASHER_CID },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static const mozilla::Module kTestCrasherModule = {
|
||||
mozilla::Module::kVersion,
|
||||
kTestCrasherCIDs,
|
||||
kTestCrasherContracts
|
||||
};
|
||||
|
||||
NSMODULE_DEFN(nsTestCrasherModule) = &kTestCrasherModule;
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
#filter substitution
|
||||
binary-component @SHARED_LIBRARY@
|
||||
interfaces crashreporter_test.xpt
|
|
@ -7,9 +7,12 @@ let crashReporter =
|
|||
.getService(Components.interfaces.nsICrashReporter);
|
||||
crashReporter.enabled = true;
|
||||
crashReporter.minidumpPath = cwd;
|
||||
let cd = cwd.clone();
|
||||
cd.append("components");
|
||||
cd.append("testcrasher.manifest");
|
||||
Components.manager instanceof Components.interfaces.nsIComponentRegistrar;
|
||||
Components.manager.autoRegister(cd);
|
||||
let crashType = Components.interfaces.nsITestCrasher.CRASH_INVALID_POINTER_DEREF;
|
||||
|
||||
let ios = Components.classes["@mozilla.org/network/io-service;1"]
|
||||
.getService(Components.interfaces.nsIIOService);
|
||||
let protocolHandler = ios.getProtocolHandler("resource")
|
||||
.QueryInterface(Components.interfaces.nsIResProtocolHandler);
|
||||
let curDirURI = ios.newFileURI(cwd);
|
||||
protocolHandler.setSubstitution("test", curDirURI);
|
||||
Components.utils.import("resource://test/CrashTestUtils.jsm");
|
||||
let crashType = CrashTestUtils.CRASH_INVALID_POINTER_DEREF;
|
||||
|
|
|
@ -1,3 +1,2 @@
|
|||
// now actually crash
|
||||
let crasher = Components.classes["@mozilla.org/testcrasher;1"].createInstance(Components.interfaces.nsITestCrasher);
|
||||
crasher.crash(crashType);
|
||||
CrashTestUtils.crash(crashType);
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
* @param canReturnZero
|
||||
* If true, the subprocess may return with a zero exit code.
|
||||
* Certain types of crashes may not cause the process to
|
||||
* exit with an error.
|
||||
* exit with an error.
|
||||
*/
|
||||
function do_crash(setup, callback, canReturnZero)
|
||||
{
|
||||
|
@ -81,6 +81,14 @@ function do_crash(setup, callback, canReturnZero)
|
|||
|
||||
let extrafile = minidump.clone();
|
||||
extrafile.leafName = extrafile.leafName.slice(0, -4) + ".extra";
|
||||
|
||||
// Just in case, don't let these files linger.
|
||||
do_register_cleanup(function() {
|
||||
if (minidump.exists())
|
||||
minidump.remove(false);
|
||||
if (extrafile.exists())
|
||||
extrafile.remove(false);
|
||||
});
|
||||
do_check_true(extrafile.exists());
|
||||
let extra = parseKeyValuePairsFromFile(extrafile);
|
||||
|
||||
|
@ -129,3 +137,6 @@ function parseKeyValuePairsFromFile(file) {
|
|||
fstream.close();
|
||||
return parseKeyValuePairs(contents);
|
||||
}
|
||||
|
||||
// Import binary APIs via js-ctypes.
|
||||
Components.utils.import("resource://test/CrashTestUtils.jsm");
|
||||
|
|
|
@ -13,7 +13,7 @@ function run_test()
|
|||
|
||||
// Try crashing with a pure virtual call
|
||||
do_crash(function() {
|
||||
crashType = Components.interfaces.nsITestCrasher.CRASH_PURE_VIRTUAL_CALL;
|
||||
crashType = CrashTestUtils.CRASH_PURE_VIRTUAL_CALL;
|
||||
crashReporter.annotateCrashReport("TestKey", "TestValue");
|
||||
},
|
||||
function(mdump, extra) {
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
function run_test()
|
||||
{
|
||||
if (!("@mozilla.org/toolkit/crash-reporter;1" in Components.classes)) {
|
||||
dump("INFO | test_crash_purevirtual.js | Can't test crashreporter in a non-libxul build.\n");
|
||||
dump("INFO | test_crash_runtimeabort.js | Can't test crashreporter in a non-libxul build.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// Try crashing with a runtime abort
|
||||
do_crash(function() {
|
||||
crashType = Components.interfaces.nsITestCrasher.CRASH_RUNTIMEABORT;
|
||||
crashType = CrashTestUtils.CRASH_RUNTIMEABORT;
|
||||
crashReporter.annotateCrashReport("TestKey", "TestValue");
|
||||
},
|
||||
function(mdump, extra) {
|
||||
|
|
|
@ -5,12 +5,24 @@ function run_test()
|
|||
return;
|
||||
}
|
||||
|
||||
var is_win7_or_newer = false;
|
||||
var ph = Components.classes["@mozilla.org/network/protocol;1?name=http"]
|
||||
.getService(Components.interfaces.nsIHttpProtocolHandler);
|
||||
var match = ph.userAgent.match(/Windows NT (\d+).(\d+)/);
|
||||
if (match && (parseInt(match[1]) > 6 ||
|
||||
parseInt(match[1]) == 6 && parseInt(match[2]) >= 1)) {
|
||||
is_win7_or_newer = true;
|
||||
}
|
||||
|
||||
// try a basic crash
|
||||
do_crash(null, function(mdump, extra) {
|
||||
do_check_true(mdump.exists());
|
||||
do_check_true(mdump.fileSize > 0);
|
||||
do_check_true('StartupTime' in extra);
|
||||
do_check_true('CrashTime' in extra);
|
||||
do_check_true(CrashTestUtils.dumpHasStream(mdump.path, CrashTestUtils.MD_THREAD_LIST_STREAM));
|
||||
if (is_win7_or_newer)
|
||||
do_check_true(CrashTestUtils.dumpHasStream(mdump.path, CrashTestUtils.MD_MEMORY_INFO_LIST_STREAM));
|
||||
});
|
||||
|
||||
// check setting some basic data
|
||||
|
|
|
@ -16,8 +16,7 @@ function run_test()
|
|||
let dir = Components.classes["@mozilla.org/file/local;1"]
|
||||
.createInstance(Components.interfaces.nsILocalFile);
|
||||
dir.initWithPath(profd);
|
||||
let mycrasher = Components.classes["@mozilla.org/testcrasher;1"].createInstance(Components.interfaces.nsITestCrasher);
|
||||
let lock = mycrasher.lockDir(dir);
|
||||
let lock = CrashTestUtils.lockDir(dir);
|
||||
// when we crash, the lock file should be cleaned up
|
||||
},
|
||||
function(mdump, extra) {
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
/* NOTE: this interface is completely undesigned, not stable and likely to change */
|
||||
|
||||
[scriptable, uuid(d2bfa0fd-8f73-4660-9609-f999680243b1)]
|
||||
[scriptable, uuid(5c5de1e7-f7f4-46b4-9ced-03ab1f869eaf)]
|
||||
interface nsIGfxInfo : nsISupports
|
||||
{
|
||||
/*
|
||||
|
@ -48,6 +48,7 @@ interface nsIGfxInfo : nsISupports
|
|||
*/
|
||||
readonly attribute boolean D2DEnabled;
|
||||
readonly attribute boolean DWriteEnabled;
|
||||
readonly attribute DOMString DWriteVersion;
|
||||
|
||||
/**
|
||||
* The name of the display adapter.
|
||||
|
|
|
@ -71,6 +71,13 @@ GfxInfo::GetDWriteEnabled(PRBool *aEnabled)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* readonly attribute DOMString DWriteVersion; */
|
||||
NS_IMETHODIMP
|
||||
GfxInfo::GetDWriteVersion(nsAString & aDwriteVersion)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
void
|
||||
GfxInfo::Init()
|
||||
{
|
||||
|
|
|
@ -106,6 +106,13 @@ GfxInfo::GetDWriteEnabled(PRBool *aEnabled)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* readonly attribute DOMString DWriteVersion; */
|
||||
NS_IMETHODIMP
|
||||
GfxInfo::GetDWriteVersion(nsAString & aDwriteVersion)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* readonly attribute DOMString adapterDescription; */
|
||||
NS_IMETHODIMP
|
||||
GfxInfo::GetAdapterDescription(nsAString & aAdapterDescription)
|
||||
|
|
|
@ -363,7 +363,8 @@ nsGtkIMModule::OnBlurWindow(nsWindow* aWindow)
|
|||
}
|
||||
|
||||
PRBool
|
||||
nsGtkIMModule::OnKeyEvent(nsWindow* aCaller, GdkEventKey* aEvent)
|
||||
nsGtkIMModule::OnKeyEvent(nsWindow* aCaller, GdkEventKey* aEvent,
|
||||
PRBool aKeyDownEventWasSent /* = PR_FALSE */)
|
||||
{
|
||||
NS_PRECONDITION(aEvent, "aEvent must be non-null");
|
||||
|
||||
|
@ -372,8 +373,8 @@ nsGtkIMModule::OnKeyEvent(nsWindow* aCaller, GdkEventKey* aEvent)
|
|||
}
|
||||
|
||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||
("GtkIMModule(%p): OnKeyEvent, aCaller=%p",
|
||||
this, aCaller));
|
||||
("GtkIMModule(%p): OnKeyEvent, aCaller=%p, aKeyDownEventWasSent=%s",
|
||||
this, aCaller, aKeyDownEventWasSent ? "TRUE" : "FALSE"));
|
||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||
(" aEvent: type=%s, keyval=0x%X, unicode=0x%X",
|
||||
aEvent->type == GDK_KEY_PRESS ? "GDK_KEY_PRESS" :
|
||||
|
@ -394,6 +395,7 @@ nsGtkIMModule::OnKeyEvent(nsWindow* aCaller, GdkEventKey* aEvent)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
mKeyDownEventWasSent = aKeyDownEventWasSent;
|
||||
mFilterKeyEvent = PR_TRUE;
|
||||
mProcessingKeyEvent = aEvent;
|
||||
gboolean isFiltered = gtk_im_context_filter_keypress(im, aEvent);
|
||||
|
@ -1040,13 +1042,16 @@ nsGtkIMModule::DispatchCompositionStart()
|
|||
|
||||
mCompositionStart = selection.mReply.mOffset;
|
||||
|
||||
if (mProcessingKeyEvent && mProcessingKeyEvent->type == GDK_KEY_PRESS) {
|
||||
if (mProcessingKeyEvent && !mKeyDownEventWasSent &&
|
||||
mProcessingKeyEvent->type == GDK_KEY_PRESS) {
|
||||
// If this composition is started by a native keydown event, we need to
|
||||
// dispatch our keydown event here (before composition start).
|
||||
nsCOMPtr<nsIWidget> kungFuDeathGrip = mLastFocusedWindow;
|
||||
PRBool isCancelled;
|
||||
mLastFocusedWindow->DispatchKeyDownEvent(mProcessingKeyEvent,
|
||||
&isCancelled);
|
||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||
(" keydown event is dispatched"));
|
||||
if (static_cast<nsWindow*>(kungFuDeathGrip.get())->IsDestroyed() ||
|
||||
kungFuDeathGrip != mLastFocusedWindow) {
|
||||
PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
|
||||
|
|
|
@ -89,6 +89,10 @@ public:
|
|||
nsGtkIMModule(nsWindow* aOwnerWindow);
|
||||
~nsGtkIMModule();
|
||||
|
||||
// "Enabled" means the users can use all IMEs.
|
||||
// I.e., the focus is in the normal editors.
|
||||
PRBool IsEnabled();
|
||||
|
||||
// OnFocusWindow is a notification that aWindow is going to be focused.
|
||||
void OnFocusWindow(nsWindow* aWindow);
|
||||
// OnBlurWindow is a notification that aWindow is going to be unfocused.
|
||||
|
@ -103,7 +107,8 @@ public:
|
|||
// filtered by IME. Otherwise, this returns FALSE.
|
||||
// NOTE: When the keypress event starts composition, this returns TRUE but
|
||||
// this dispatches keydown event before compositionstart event.
|
||||
PRBool OnKeyEvent(nsWindow* aWindow, GdkEventKey* aEvent);
|
||||
PRBool OnKeyEvent(nsWindow* aWindow, GdkEventKey* aEvent,
|
||||
PRBool aKeyDownEventWasSent = PR_FALSE);
|
||||
|
||||
// IME related nsIWidget methods.
|
||||
nsresult ResetInputState(nsWindow* aCaller);
|
||||
|
@ -179,6 +184,12 @@ protected:
|
|||
// another content (nsIContent). Don't refer this value directly, use
|
||||
// ShouldIgnoreNativeCompositionEvent().
|
||||
PRPackedBool mIgnoreNativeCompositionEvent;
|
||||
// mKeyDownEventWasSent is used by OnKeyEvent() and
|
||||
// DispatchCompositionStart(). DispatchCompositionStart() dispatches
|
||||
// a keydown event if the composition start is caused by a native
|
||||
// keypress event. If this is true, the keydown event has been dispatched.
|
||||
// Then, DispatchCompositionStart() doesn't dispatch keydown event.
|
||||
PRPackedBool mKeyDownEventWasSent;
|
||||
|
||||
// sLastFocusedModule is a pointer to the last focused instance of this
|
||||
// class. When a instance is destroyed and sLastFocusedModule refers it,
|
||||
|
@ -219,10 +230,6 @@ protected:
|
|||
// state. So, this means *current* IM context.
|
||||
GtkIMContext* GetContext();
|
||||
|
||||
// "Enabled" means the users can use all IMEs.
|
||||
// I.e., the focus is in the normal editors.
|
||||
PRBool IsEnabled();
|
||||
|
||||
// "Editable" means the users can input characters. They may be not able to
|
||||
// use IMEs but they can use dead keys.
|
||||
// I.e., the focus is in the normal editors or the password editors or
|
||||
|
|
|
@ -3014,8 +3014,12 @@ nsWindow::OnKeyPressEvent(GtkWidget *aWidget, GdkEventKey *aEvent)
|
|||
|
||||
// if we are in the middle of composing text, XIM gets to see it
|
||||
// before mozilla does.
|
||||
if (mIMModule && mIMModule->OnKeyEvent(this, aEvent)) {
|
||||
return TRUE;
|
||||
PRBool IMEWasEnabled = PR_FALSE;
|
||||
if (mIMModule) {
|
||||
IMEWasEnabled = mIMModule->IsEnabled();
|
||||
if (mIMModule->OnKeyEvent(this, aEvent)) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
nsEventStatus status;
|
||||
|
@ -3039,6 +3043,17 @@ nsWindow::OnKeyPressEvent(GtkWidget *aWidget, GdkEventKey *aEvent)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
// If a keydown event handler causes to enable IME, i.e., it moves
|
||||
// focus from IME unusable content to IME usable editor, we should
|
||||
// send the native key event to IME for the first input on the editor.
|
||||
if (!IMEWasEnabled && mIMModule && mIMModule->IsEnabled()) {
|
||||
// Notice our keydown event was already dispatched. This prevents
|
||||
// unnecessary DOM keydown event in the editor.
|
||||
if (mIMModule->OnKeyEvent(this, aEvent, PR_TRUE)) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
// Don't pass modifiers as NS_KEY_PRESS events.
|
||||
// TODO: Instead of selectively excluding some keys from NS_KEY_PRESS events,
|
||||
// we should instead selectively include (as per MSDN spec; no official
|
||||
|
|
|
@ -74,6 +74,14 @@ GfxInfo::GetDWriteEnabled(PRBool *aEnabled)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
/* readonly attribute DOMString DWriteVersion; */
|
||||
NS_IMETHODIMP
|
||||
GfxInfo::GetDWriteVersion(nsAString & aDwriteVersion)
|
||||
{
|
||||
gfxWindowsPlatform::GetPlatform()->GetDLLVersion(L"dwrite.dll", aDwriteVersion);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* XXX: GfxInfo doesn't handle multiple GPUs. We should try to do that. Bug #591057 */
|
||||
|
||||
static nsresult GetKeyValue(const WCHAR* keyLocation, const WCHAR* keyName, nsAString& destString, int type)
|
||||
|
|
|
@ -316,6 +316,8 @@ PRUint32 nsWindow::sOOPPPluginFocusEvent =
|
|||
RegisterWindowMessageW(kOOPPPluginFocusEventId);
|
||||
#endif
|
||||
|
||||
MSG nsWindow::sRedirectedKeyDown;
|
||||
|
||||
/**************************************************************
|
||||
*
|
||||
* SECTION: globals variables
|
||||
|
@ -460,6 +462,8 @@ nsWindow::nsWindow() : nsBaseWidget()
|
|||
nsUXThemeData::InitTitlebarInfo();
|
||||
// Init theme data
|
||||
nsUXThemeData::UpdateNativeThemeInfo();
|
||||
|
||||
ForgetRedirectedKeyDownMessage();
|
||||
} // !sInstanceCount
|
||||
|
||||
mIdleService = nsnull;
|
||||
|
@ -5322,6 +5326,11 @@ PRBool nsWindow::ProcessMessage(UINT msg, WPARAM &wParam, LPARAM &lParam,
|
|||
#endif
|
||||
|
||||
case WM_SETFOCUS:
|
||||
// If previous focused window isn't ours, it must have received the
|
||||
// redirected message. So, we should forget it.
|
||||
if (!IsOurProcessWindow(HWND(wParam))) {
|
||||
ForgetRedirectedKeyDownMessage();
|
||||
}
|
||||
if (sJustGotActivate) {
|
||||
result = DispatchFocusToTopLevelWindow(NS_ACTIVATE);
|
||||
}
|
||||
|
@ -5880,6 +5889,25 @@ void nsWindow::PostSleepWakeNotification(const char* aNotification)
|
|||
}
|
||||
#endif
|
||||
|
||||
// RemoveNextCharMessage() should be called by WM_KEYDOWN or WM_SYSKEYDOWM
|
||||
// message handler. If there is no WM_(SYS)CHAR message for it, this
|
||||
// method does nothing.
|
||||
// NOTE: WM_(SYS)CHAR message is posted by TranslateMessage() API which is
|
||||
// called in message loop. So, WM_(SYS)KEYDOWN message should have
|
||||
// WM_(SYS)CHAR message in the queue if the keydown event causes character
|
||||
// input.
|
||||
|
||||
/* static */
|
||||
void nsWindow::RemoveNextCharMessage(HWND aWnd)
|
||||
{
|
||||
MSG msg;
|
||||
if (::PeekMessageW(&msg, aWnd,
|
||||
WM_KEYFIRST, WM_KEYLAST, PM_NOREMOVE | PM_NOYIELD) &&
|
||||
(msg.message == WM_CHAR || msg.message == WM_SYSCHAR)) {
|
||||
::GetMessageW(&msg, aWnd, msg.message, msg.message);
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT nsWindow::ProcessCharMessage(const MSG &aMsg, PRBool *aEventDispatched)
|
||||
{
|
||||
NS_PRECONDITION(aMsg.message == WM_CHAR || aMsg.message == WM_SYSCHAR,
|
||||
|
@ -5941,6 +5969,12 @@ LRESULT nsWindow::ProcessKeyDownMessage(const MSG &aMsg,
|
|||
NS_PRECONDITION(aMsg.message == WM_KEYDOWN || aMsg.message == WM_SYSKEYDOWN,
|
||||
"message is not keydown event");
|
||||
|
||||
// If this method doesn't call OnKeyDown(), this method must clean up the
|
||||
// redirected message information itself. For more information, see above
|
||||
// comment of AutoForgetRedirectedKeyDownMessage struct definition in
|
||||
// nsWindow.h.
|
||||
AutoForgetRedirectedKeyDownMessage forgetRedirectedMessage(this, aMsg);
|
||||
|
||||
nsModifierKeyState modKeyState;
|
||||
|
||||
// Note: the original code passed (HIWORD(lParam)) to OnKeyDown as
|
||||
|
@ -5962,6 +5996,9 @@ LRESULT nsWindow::ProcessKeyDownMessage(const MSG &aMsg,
|
|||
nsIMM32Handler::NotifyEndStatusChange();
|
||||
} else if (!nsIMM32Handler::IsComposingOn(this)) {
|
||||
result = OnKeyDown(aMsg, modKeyState, aEventDispatched, nsnull);
|
||||
// OnKeyDown cleaned up the redirected message information itself, so,
|
||||
// we should do nothing.
|
||||
forgetRedirectedMessage.mCancel = PR_TRUE;
|
||||
}
|
||||
|
||||
#ifndef WINCE
|
||||
|
@ -6673,6 +6710,14 @@ UINT nsWindow::MapFromNativeToDOM(UINT aNativeKeyCode)
|
|||
return aNativeKeyCode;
|
||||
}
|
||||
|
||||
/* static */
|
||||
PRBool nsWindow::IsRedirectedKeyDownMessage(const MSG &aMsg)
|
||||
{
|
||||
return (aMsg.message == WM_KEYDOWN || aMsg.message == WM_SYSKEYDOWN) &&
|
||||
(sRedirectedKeyDown.message == aMsg.message &&
|
||||
GetScanCode(sRedirectedKeyDown.lParam) == GetScanCode(aMsg.lParam));
|
||||
}
|
||||
|
||||
/**
|
||||
* nsWindow::OnKeyDown peeks into the message queue and pulls out
|
||||
* WM_CHAR messages for processing. During testing we don't want to
|
||||
|
@ -6686,14 +6731,15 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg,
|
|||
PRBool *aEventDispatched,
|
||||
nsFakeCharMessage* aFakeCharMessage)
|
||||
{
|
||||
UINT virtualKeyCode = aMsg.wParam;
|
||||
UINT virtualKeyCode =
|
||||
aMsg.wParam != VK_PROCESSKEY ? aMsg.wParam : ::ImmGetVirtualKey(mWnd);
|
||||
|
||||
#ifndef WINCE
|
||||
gKbdLayout.OnKeyDown (virtualKeyCode);
|
||||
gKbdLayout.OnKeyDown(virtualKeyCode);
|
||||
#endif
|
||||
|
||||
// Use only DOMKeyCode for XP processing.
|
||||
// Use aVirtualKeyCode for gKbdLayout and native processing.
|
||||
// Use virtualKeyCode for gKbdLayout and native processing.
|
||||
UINT DOMKeyCode = nsIMM32Handler::IsComposingOn(this) ?
|
||||
virtualKeyCode : MapFromNativeToDOM(virtualKeyCode);
|
||||
|
||||
|
@ -6701,10 +6747,71 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg,
|
|||
//printf("In OnKeyDown virt: %d\n", DOMKeyCode);
|
||||
#endif
|
||||
|
||||
PRBool noDefault =
|
||||
DispatchKeyEvent(NS_KEY_DOWN, 0, nsnull, DOMKeyCode, &aMsg, aModKeyState);
|
||||
if (aEventDispatched)
|
||||
*aEventDispatched = PR_TRUE;
|
||||
static PRBool sRedirectedKeyDownEventPreventedDefault = PR_FALSE;
|
||||
PRBool noDefault;
|
||||
if (aFakeCharMessage || !IsRedirectedKeyDownMessage(aMsg)) {
|
||||
HIMC oldIMC = mOldIMC;
|
||||
noDefault =
|
||||
DispatchKeyEvent(NS_KEY_DOWN, 0, nsnull, DOMKeyCode, &aMsg, aModKeyState);
|
||||
if (aEventDispatched) {
|
||||
*aEventDispatched = PR_TRUE;
|
||||
}
|
||||
|
||||
// If IMC wasn't associated to the window but is associated it now (i.e.,
|
||||
// focus is moved from a non-editable editor to an editor by keydown
|
||||
// event handler), WM_CHAR and WM_SYSCHAR shouldn't cause first character
|
||||
// inputting if IME is opened. But then, we should redirect the native
|
||||
// keydown message to IME.
|
||||
// However, note that if focus has been already moved to another
|
||||
// application, we shouldn't redirect the message to it because the keydown
|
||||
// message is processed by us, so, nobody shouldn't process it.
|
||||
HWND focusedWnd = ::GetFocus();
|
||||
if (!noDefault && !aFakeCharMessage && oldIMC && !mOldIMC && focusedWnd &&
|
||||
!PluginHasFocus()) {
|
||||
RemoveNextCharMessage(focusedWnd);
|
||||
|
||||
INPUT keyinput;
|
||||
keyinput.type = INPUT_KEYBOARD;
|
||||
keyinput.ki.wVk = aMsg.wParam;
|
||||
keyinput.ki.wScan = GetScanCode(aMsg.lParam);
|
||||
keyinput.ki.dwFlags = KEYEVENTF_SCANCODE;
|
||||
if (IsExtendedScanCode(aMsg.lParam)) {
|
||||
keyinput.ki.dwFlags |= KEYEVENTF_EXTENDEDKEY;
|
||||
}
|
||||
keyinput.ki.time = 0;
|
||||
keyinput.ki.dwExtraInfo = NULL;
|
||||
|
||||
sRedirectedKeyDownEventPreventedDefault = noDefault;
|
||||
sRedirectedKeyDown = aMsg;
|
||||
|
||||
::SendInput(1, &keyinput, sizeof(keyinput));
|
||||
|
||||
// Return here. We shouldn't dispatch keypress event for this WM_KEYDOWN.
|
||||
// If it's needed, it will be dispatched after next (redirected)
|
||||
// WM_KEYDOWN.
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (mOnDestroyCalled) {
|
||||
// If this was destroyed by the keydown event handler, we shouldn't
|
||||
// dispatch keypress event on this window.
|
||||
return PR_TRUE;
|
||||
}
|
||||
} else {
|
||||
noDefault = sRedirectedKeyDownEventPreventedDefault;
|
||||
// If this is redirected keydown message, we have dispatched the keydown
|
||||
// event already.
|
||||
if (aEventDispatched) {
|
||||
*aEventDispatched = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
ForgetRedirectedKeyDownMessage();
|
||||
|
||||
// If the key was processed by IME, we shouldn't dispatch keypress event.
|
||||
if (aMsg.wParam == VK_PROCESSKEY) {
|
||||
return noDefault;
|
||||
}
|
||||
|
||||
// If we won't be getting a WM_CHAR, WM_SYSCHAR or WM_DEADCHAR, synthesize a keypress
|
||||
// for almost all keys
|
||||
|
@ -7408,14 +7515,19 @@ void nsWindow::OnSettingsChange(WPARAM wParam, LPARAM lParam)
|
|||
nsWindowGfx::OnSettingsChangeGfx(wParam);
|
||||
}
|
||||
|
||||
static PRBool IsOurProcessWindow(HWND aHWND)
|
||||
/* static */
|
||||
PRBool nsWindow::IsOurProcessWindow(HWND aHWND)
|
||||
{
|
||||
if (!aHWND) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
DWORD processId = 0;
|
||||
::GetWindowThreadProcessId(aHWND, &processId);
|
||||
return processId == ::GetCurrentProcessId();
|
||||
}
|
||||
|
||||
static HWND FindOurProcessWindow(HWND aHWND)
|
||||
/* static */
|
||||
HWND nsWindow::FindOurProcessWindow(HWND aHWND)
|
||||
{
|
||||
for (HWND wnd = ::GetParent(aHWND); wnd; wnd = ::GetParent(wnd)) {
|
||||
if (IsOurProcessWindow(wnd)) {
|
||||
|
|
|
@ -336,6 +336,8 @@ protected:
|
|||
return mTransparencyMode == eTransparencyGlass ||
|
||||
mTransparencyMode == eTransparencyBorderlessGlass;
|
||||
}
|
||||
PRBool IsOurProcessWindow(HWND aHWND);
|
||||
HWND FindOurProcessWindow(HWND aHWND);
|
||||
|
||||
/**
|
||||
* Event processing helpers
|
||||
|
@ -346,6 +348,7 @@ protected:
|
|||
PRBool DispatchStandardEvent(PRUint32 aMsg);
|
||||
PRBool DispatchCommandEvent(PRUint32 aEventCommand);
|
||||
void RelayMouseEvent(UINT aMsg, WPARAM wParam, LPARAM lParam);
|
||||
static void RemoveNextCharMessage(HWND aWnd);
|
||||
void RemoveMessageAndDispatchPluginEvent(UINT aFirstMsg, UINT aLastMsg);
|
||||
static MSG InitMSG(UINT aMessage, WPARAM wParam, LPARAM lParam);
|
||||
virtual PRBool ProcessMessage(UINT msg, WPARAM &wParam,
|
||||
|
@ -368,6 +371,19 @@ protected:
|
|||
LRESULT* aRetValue,
|
||||
PRBool& aQuitProcessing);
|
||||
PRInt32 ClientMarginHitTestPoint(PRInt32 mx, PRInt32 my);
|
||||
static WORD GetScanCode(LPARAM aLParam)
|
||||
{
|
||||
return (aLParam >> 16) & 0xFF;
|
||||
}
|
||||
static PRBool IsExtendedScanCode(LPARAM aLParam)
|
||||
{
|
||||
return (aLParam & 0x1000000) != 0;
|
||||
}
|
||||
static PRBool IsRedirectedKeyDownMessage(const MSG &aMsg);
|
||||
static void ForgetRedirectedKeyDownMessage()
|
||||
{
|
||||
sRedirectedKeyDown.message = WM_NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Event handlers
|
||||
|
@ -608,6 +624,45 @@ protected:
|
|||
static HINSTANCE sAccLib;
|
||||
static LPFNLRESULTFROMOBJECT sLresultFromObject;
|
||||
#endif // ACCESSIBILITY
|
||||
|
||||
// sRedirectedKeyDown is WM_KEYDOWN message or WM_SYSKEYDOWN message which
|
||||
// was reirected to SendInput() API by OnKeyDown().
|
||||
static MSG sRedirectedKeyDown;
|
||||
|
||||
// If a window receives WM_KEYDOWN message or WM_SYSKEYDOWM message which is
|
||||
// redirected message, OnKeyDowm() prevents to dispatch NS_KEY_DOWN event
|
||||
// because it has been dispatched before the message was redirected.
|
||||
// However, in some cases, ProcessKeyDownMessage() doesn't call OnKeyDown().
|
||||
// Then, ProcessKeyDownMessage() needs to forget the redirected message and
|
||||
// remove WM_CHAR message or WM_SYSCHAR message for the redirected keydown
|
||||
// message. AutoForgetRedirectedKeyDownMessage struct is a helper struct
|
||||
// for doing that. This must be created in stack.
|
||||
struct AutoForgetRedirectedKeyDownMessage
|
||||
{
|
||||
AutoForgetRedirectedKeyDownMessage(nsWindow* aWindow, const MSG &aMsg) :
|
||||
mCancel(!nsWindow::IsRedirectedKeyDownMessage(aMsg)),
|
||||
mWindow(aWindow), mMsg(aMsg)
|
||||
{
|
||||
}
|
||||
|
||||
~AutoForgetRedirectedKeyDownMessage()
|
||||
{
|
||||
if (mCancel) {
|
||||
return;
|
||||
}
|
||||
// Prevent unnecessary keypress event
|
||||
if (!mWindow->mOnDestroyCalled) {
|
||||
nsWindow::RemoveNextCharMessage(mWindow->mWnd);
|
||||
}
|
||||
// Foreget the redirected message
|
||||
nsWindow::ForgetRedirectedKeyDownMessage();
|
||||
}
|
||||
|
||||
PRBool mCancel;
|
||||
nsCOMPtr<nsWindow> mWindow;
|
||||
const MSG &mMsg;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -994,8 +994,6 @@ struct nsCycleCollector
|
|||
|
||||
nsPurpleBuffer mPurpleBuf;
|
||||
|
||||
nsCOMPtr<nsICycleCollectorListener> mListener;
|
||||
|
||||
void RegisterRuntime(PRUint32 langID,
|
||||
nsCycleCollectionLanguageRuntime *rt);
|
||||
nsCycleCollectionLanguageRuntime * GetRuntime(PRUint32 langID);
|
||||
|
@ -1407,7 +1405,7 @@ private:
|
|||
PtrInfo *mCurrPi;
|
||||
nsCycleCollectionLanguageRuntime **mRuntimes; // weak, from nsCycleCollector
|
||||
nsCString mNextEdgeName;
|
||||
nsCOMPtr<nsICycleCollectorListener> mListener;
|
||||
nsICycleCollectorListener *mListener;
|
||||
|
||||
public:
|
||||
GCGraphBuilder(GCGraph &aGraph,
|
||||
|
@ -2499,7 +2497,6 @@ void
|
|||
nsCycleCollector::CleanupAfterCollection()
|
||||
{
|
||||
mWhiteNodes = nsnull;
|
||||
mListener = nsnull;
|
||||
mCollectionInProgress = PR_FALSE;
|
||||
|
||||
#ifdef XP_OS2
|
||||
|
@ -2527,14 +2524,6 @@ nsCycleCollector::Collect(PRUint32 aTryCollections,
|
|||
if (!PrepareForCollection(&whiteNodes))
|
||||
return 0;
|
||||
|
||||
#ifdef DEBUG_CC
|
||||
nsCOMPtr<nsICycleCollectorListener> tempListener;
|
||||
if (!aListener && mParams.mDrawGraphs) {
|
||||
tempListener = new nsCycleCollectorLogger();
|
||||
aListener = tempListener;
|
||||
}
|
||||
#endif
|
||||
|
||||
PRUint32 totalCollections = 0;
|
||||
while (aTryCollections > totalCollections) {
|
||||
// Synchronous cycle collection. Always force a JS GC as well.
|
||||
|
@ -3285,7 +3274,7 @@ nsCycleCollector_DEBUG_wasFreed(nsISupports *n)
|
|||
class nsCycleCollectorRunner : public nsRunnable
|
||||
{
|
||||
nsCycleCollector *mCollector;
|
||||
nsCOMPtr<nsICycleCollectorListener> mListener;
|
||||
nsICycleCollectorListener *mListener;
|
||||
Mutex mLock;
|
||||
CondVar mRequest;
|
||||
CondVar mReply;
|
||||
|
@ -3330,6 +3319,7 @@ public:
|
|||
|
||||
nsCycleCollectorRunner(nsCycleCollector *collector)
|
||||
: mCollector(collector),
|
||||
mListener(nsnull),
|
||||
mLock("cycle collector lock"),
|
||||
mRequest(mLock, "cycle collector request condvar"),
|
||||
mReply(mLock, "cycle collector reply condvar"),
|
||||
|
@ -3469,9 +3459,16 @@ PRUint32
|
|||
nsCycleCollector_collect(nsICycleCollectorListener *aListener)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
nsCOMPtr<nsICycleCollectorListener> listener(aListener);
|
||||
#ifdef DEBUG_CC
|
||||
if (!aListener && sCollector.mParams.mDrawGraphs) {
|
||||
listener = new nsCycleCollectorLogger();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (sCollectorRunner)
|
||||
return sCollectorRunner->Collect(aListener);
|
||||
return sCollector ? sCollector->Collect(1, aListener) : 0;
|
||||
return sCollectorRunner->Collect(listener);
|
||||
return sCollector ? sCollector->Collect(1, listener) : 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -41,6 +41,16 @@
|
|||
|
||||
#include "nsTArray.h"
|
||||
|
||||
/**
|
||||
* An array of observers. Like a normal array, but supports iterators that are
|
||||
* stable even if the array is modified during iteration.
|
||||
* The template parameter T is the observer type the array will hold;
|
||||
* N is the number of built-in storage slots that come with the array.
|
||||
* NOTE: You probably want to use nsTObserverArray, unless you specifically
|
||||
* want built-in storage. See below.
|
||||
* @see nsTObserverArray, nsTArray
|
||||
*/
|
||||
|
||||
class NS_COM_GLUE nsTObserverArray_base {
|
||||
public:
|
||||
typedef PRUint32 index_type;
|
||||
|
@ -90,16 +100,6 @@ class NS_COM_GLUE nsTObserverArray_base {
|
|||
mutable Iterator_base* mIterators;
|
||||
};
|
||||
|
||||
/**
|
||||
* An array of observers. Like a normal array, but supports iterators that are
|
||||
* stable even if the array is modified during iteration.
|
||||
* The template parameter T is the observer type the array will hold;
|
||||
* N is the number of built-in storage slots that come with the array.
|
||||
* NOTE: You probably want to use nsTObserverArray, unless you specifically
|
||||
* want built-in storage. See below.
|
||||
* @see nsTObserverArray, nsTArray
|
||||
*/
|
||||
|
||||
template<class T, PRUint32 N>
|
||||
class nsAutoTObserverArray : protected nsTObserverArray_base {
|
||||
public:
|
||||
|
|
|
@ -249,13 +249,13 @@ function test_kill_2()
|
|||
process.kill();
|
||||
}
|
||||
catch (e) { }
|
||||
}
|
||||
|
||||
// We need to ensure that we process any events on the main thread -
|
||||
// this allow threads to clean up properly and avoid out of memory
|
||||
// errors during the test.
|
||||
while (thread.hasPendingEvents())
|
||||
thread.processNextEvent(false);
|
||||
// We need to ensure that we process any events on the main thread -
|
||||
// this allow threads to clean up properly and avoid out of memory
|
||||
// errors during the test.
|
||||
while (thread.hasPendingEvents())
|
||||
thread.processNextEvent(false);
|
||||
}
|
||||
}
|
||||
|
||||
function run_test() {
|
||||
|
|
Загрузка…
Ссылка в новой задаче