Merge last green changeset from mozilla-central to mozilla-inbound

This commit is contained in:
Marco Bonardo 2011-07-04 20:29:30 +02:00
Родитель a8fb775abc 74aecf92be
Коммит 69c847e57d
27 изменённых файлов: 490 добавлений и 96 удалений

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

@ -732,15 +732,18 @@ var InspectorUI = {
}
if (node instanceof GetSVGDocument) {
// then the node is a frame
if (index == 0) {
if (!this.embeddedBrowserParents)
this.embeddedBrowserParents = {};
let skipChild = node.getSVGDocument().documentElement;
this.embeddedBrowserParents[skipChild] = node;
return skipChild; // the node's SVGElement
let svgDocument = node.getSVGDocument();
if (svgDocument) {
// then the node is a frame
if (index == 0) {
if (!this.embeddedBrowserParents)
this.embeddedBrowserParents = {};
let skipChild = svgDocument.documentElement;
this.embeddedBrowserParents[skipChild] = node;
return skipChild; // the node's SVGElement
}
return null;
}
return null;
}
let child = null;

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

@ -2005,13 +2005,18 @@
in the current window, in which case this will do nothing. -->
<method name="replaceTabWithWindow">
<parameter name="aTab"/>
<parameter name="aOptions"/>
<body>
<![CDATA[
if (this.tabs.length == 1)
return null;
var options = "chrome,dialog=no,all";
for (var name in aOptions)
options += "," + name + "=" + aOptions[name];
// tell a new window to take the "dropped" tab
return window.openDialog(getBrowserURL(), "_blank", "dialog=no,all", aTab);
return window.openDialog(getBrowserURL(), "_blank", options, aTab);
]]>
</body>
</method>
@ -3298,6 +3303,17 @@
let canvas = tabPreviews.capture(tab, false);
dt.setDragImage(canvas, 0, 0);
// _dragOffsetX/Y give the coordinates that the mouse should be
// positioned relative to the corner of the new window created upon
// dragend such that the mouse appears to have the same position
// relative to the corner of the dragged tab.
function clientX(ele) ele.getBoundingClientRect().left;
let tabOffsetX = clientX(tab) -
clientX(this.children[0].pinned ? this.children[0] : this);
tab._dragOffsetX = event.screenX - window.screenX - tabOffsetX;
tab._dragOffsetY = event.screenY - window.screenY;
event.stopPropagation();
]]></handler>
@ -3477,6 +3493,11 @@
}
}
}
// these offsets are only used in dragend, but we need to free them here
// as well
delete draggedTab._dragOffsetX;
delete draggedTab._dragOffsetY;
]]></handler>
<handler event="dragend"><![CDATA[
@ -3491,6 +3512,7 @@
// Disable detach within the browser toolbox
var eX = event.screenX;
var eY = event.screenY;
var wX = window.screenX;
// check if the drop point is horizontally within the window
if (eX > wX && eX < (wX + window.outerWidth)) {
@ -3498,13 +3520,45 @@
// also avoid detaching if the the tab was dropped too close to
// the tabbar (half a tab)
let endScreenY = bo.screenY + 1.5 * bo.height;
let eY = event.screenY;
if (eY < endScreenY && eY > window.screenY)
return;
}
var draggedTab = dt.mozGetDataAt(TAB_DROP_TYPE, 0);
this.tabbrowser.replaceTabWithWindow(draggedTab);
// screen.availLeft et. al. only check the screen that this window is on,
// but we want to look at the screen the tab is being dropped onto.
var sX = {}, sY = {}, sWidth = {}, sHeight = {};
Cc["@mozilla.org/gfx/screenmanager;1"]
.getService(Ci.nsIScreenManager)
.screenForRect(eX, eY, 1, 1)
.GetAvailRect(sX, sY, sWidth, sHeight);
// ensure new window entirely within screen
var winWidth = Math.min(window.outerWidth, sWidth.value);
var winHeight = Math.min(window.outerHeight, sHeight.value);
var left = Math.min(Math.max(eX - draggedTab._dragOffsetX, sX.value),
sX.value + sWidth.value - winWidth);
var top = Math.min(Math.max(eY - draggedTab._dragOffsetY, sY.value),
sY.value + sHeight.value - winHeight);
delete draggedTab._dragOffsetX;
delete draggedTab._dragOffsetY;
if (this.tabbrowser.tabs.length == 1) {
// resize _before_ move to ensure the window fits the new screen. if
// the window is too large for its screen, the window manager may do
// automatic repositioning.
window.resizeTo(winWidth, winHeight);
window.moveTo(left, top);
window.focus();
} else {
this.tabbrowser.replaceTabWithWindow(draggedTab, { screenX: left,
screenY: top,
#ifndef XP_WIN
outerWidth: winWidth,
outerHeight: winHeight
#endif
});
}
event.stopPropagation();
]]></handler>

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

@ -54,6 +54,7 @@ _BROWSER_FILES = \
browser_inspector_treePanel_output.js \
browser_inspector_treePanel_input.html \
browser_inspector_treePanel_result.html \
browser_inspector_bug_665880.js \
$(NULL)
libs:: $(_BROWSER_FILES)

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

@ -0,0 +1,62 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function test()
{
waitForExplicitFinish();
let doc;
let objectNode;
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function() {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
doc = content.document;
waitForFocus(setupObjectInspectionTest, content);
}, true);
content.location = "data:text/html,<object style='padding: 100px'><p>foobar</p></object>";
function setupObjectInspectionTest()
{
objectNode = doc.querySelector("object");
ok(objectNode, "we have the object node");
Services.obs.addObserver(runObjectInspectionTest,
INSPECTOR_NOTIFICATIONS.OPENED, false);
InspectorUI.toggleInspectorUI();
}
function runObjectInspectionTest()
{
Services.obs.removeObserver(runObjectInspectionTest,
INSPECTOR_NOTIFICATIONS.OPENED);
executeSoon(function() {
Services.obs.addObserver(performTestComparison,
INSPECTOR_NOTIFICATIONS.HIGHLIGHTING, false);
InspectorUI.inspectNode(objectNode);
});
}
function performTestComparison()
{
Services.obs.removeObserver(performTestComparison,
INSPECTOR_NOTIFICATIONS.HIGHLIGHTING);
is(InspectorUI.selection, objectNode, "selection matches node");
Services.obs.addObserver(finishUp,
INSPECTOR_NOTIFICATIONS.CLOSED, false);
InspectorUI.closeInspectorUI();
}
function finishUp() {
Services.obs.removeObserver(finishUp, INSPECTOR_NOTIFICATIONS.CLOSED);
doc = objectNode = null;
gBrowser.removeCurrentTab();
finish();
}
}

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

@ -0,0 +1,11 @@
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="#stylesheet"?>
<!DOCTYPE root [
<!ATTLIST xsl:stylesheet id ID #IMPLIED>
]>
<root>
<xsl:stylesheet id="stylesheet" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:variable name="var"><p>a</p></xsl:variable>
<xsl:template match="/"><xsl:copy-of select="$var" /></xsl:template>
</xsl:stylesheet>
</root>

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

@ -13,3 +13,4 @@ load 545927.html
load 601543.html
load 603844.html
load 602115.html
load 667315.xml

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

@ -163,6 +163,7 @@ public:
txAXMLEventHandler* mOutputHandler;
txAXMLEventHandler* mResultHandler;
nsAutoPtr<txAXMLEventHandler> mObsoleteHandler;
txAOutputHandlerFactory* mOutputHandlerFactory;
nsAutoPtr<txVariableMap> mTemplateParams;

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

@ -43,7 +43,8 @@
#include "txAtoms.h"
txUnknownHandler::txUnknownHandler(txExecutionState* aEs)
: mEs(aEs)
: mEs(aEs),
mFlushed(PR_FALSE)
{
MOZ_COUNT_CTOR_INHERITED(txUnknownHandler, txBufferingHandler);
}
@ -53,92 +54,145 @@ txUnknownHandler::~txUnknownHandler()
MOZ_COUNT_DTOR_INHERITED(txUnknownHandler, txBufferingHandler);
}
nsresult
txUnknownHandler::attribute(nsIAtom* aPrefix, nsIAtom* aLocalName,
nsIAtom* aLowercaseLocalName, PRInt32 aNsID,
const nsString& aValue)
{
return mFlushed ?
mEs->mResultHandler->attribute(aPrefix, aLocalName,
aLowercaseLocalName, aNsID, aValue) :
txBufferingHandler::attribute(aPrefix, aLocalName,
aLowercaseLocalName, aNsID, aValue);
}
nsresult
txUnknownHandler::attribute(nsIAtom* aPrefix, const nsSubstring& aLocalName,
const PRInt32 aNsID, const nsString& aValue)
{
return mFlushed ?
mEs->mResultHandler->attribute(aPrefix, aLocalName, aNsID, aValue) :
txBufferingHandler::attribute(aPrefix, aLocalName, aNsID, aValue);
}
nsresult
txUnknownHandler::characters(const nsSubstring& aData, PRBool aDOE)
{
return mFlushed ?
mEs->mResultHandler->characters(aData, aDOE) :
txBufferingHandler::characters(aData, aDOE);
}
nsresult
txUnknownHandler::comment(const nsString& aData)
{
return mFlushed ?
mEs->mResultHandler->comment(aData) :
txBufferingHandler::comment(aData);
}
nsresult
txUnknownHandler::endDocument(nsresult aResult)
{
if (NS_FAILED(aResult)) {
return NS_OK;
if (!mFlushed) {
if (NS_FAILED(aResult)) {
return NS_OK;
}
// This is an unusual case, no output method has been set and we
// didn't create a document element. Switching to XML output mode
// anyway.
// Make sure that mEs->mResultHandler == this is true, otherwise we'll
// leak mEs->mResultHandler in createHandlerAndFlush.
NS_ASSERTION(mEs->mResultHandler == this,
"We're leaking mEs->mResultHandler.");
nsresult rv = createHandlerAndFlush(PR_FALSE, EmptyString(),
kNameSpaceID_None);
NS_ENSURE_SUCCESS(rv, rv);
}
// This is an unusual case, no output method has been set and we
// didn't create a document element. Switching to XML output mode
// anyway.
return mEs->mResultHandler->endDocument(aResult);
}
// Make sure that mEs->mResultHandler == this is true, otherwise we'll
// leak mEs->mResultHandler in createHandlerAndFlush and we'll crash on
// the last line (delete this).
NS_ASSERTION(mEs->mResultHandler == this,
"We're leaking mEs->mResultHandler and are going to crash.");
nsresult
txUnknownHandler::endElement()
{
return mFlushed ?
mEs->mResultHandler->endElement() :
txBufferingHandler::endElement();
}
nsresult rv = createHandlerAndFlush(PR_FALSE, EmptyString(),
kNameSpaceID_None);
NS_ENSURE_SUCCESS(rv, rv);
nsresult
txUnknownHandler::processingInstruction(const nsString& aTarget,
const nsString& aData)
{
return mFlushed ?
mEs->mResultHandler->processingInstruction(aTarget, aData) :
txBufferingHandler::processingInstruction(aTarget, aData);
}
rv = mEs->mResultHandler->endDocument(aResult);
delete this;
return rv;
nsresult
txUnknownHandler::startDocument()
{
return mFlushed ?
mEs->mResultHandler->startDocument() :
txBufferingHandler::startDocument();
}
nsresult
txUnknownHandler::startElement(nsIAtom* aPrefix, nsIAtom* aLocalName,
nsIAtom* aLowercaseLocalName, PRInt32 aNsID)
{
// Make sure that mEs->mResultHandler == this is true, otherwise we'll
// leak mEs->mResultHandler in createHandlerAndFlush and we may crash
// later on trying to delete this handler again.
NS_ASSERTION(mEs->mResultHandler == this,
"We're leaking mEs->mResultHandler.");
if (!mFlushed) {
// Make sure that mEs->mResultHandler == this is true, otherwise we'll
// leak mEs->mResultHandler in createHandlerAndFlush.
NS_ASSERTION(mEs->mResultHandler == this,
"We're leaking mEs->mResultHandler.");
nsCOMPtr<nsIAtom> owner;
if (!aLowercaseLocalName) {
owner = TX_ToLowerCaseAtom(aLocalName);
NS_ENSURE_TRUE(owner, NS_ERROR_OUT_OF_MEMORY);
aLowercaseLocalName = owner;
nsCOMPtr<nsIAtom> owner;
if (!aLowercaseLocalName) {
owner = TX_ToLowerCaseAtom(aLocalName);
NS_ENSURE_TRUE(owner, NS_ERROR_OUT_OF_MEMORY);
aLowercaseLocalName = owner;
}
PRBool htmlRoot = aNsID == kNameSpaceID_None && !aPrefix &&
aLowercaseLocalName == txHTMLAtoms::html;
// Use aLocalName and not aLowercaseLocalName in case the output
// handler cares about case. For eHTMLOutput the handler will hardcode
// to 'html' anyway.
nsresult rv = createHandlerAndFlush(htmlRoot,
nsDependentAtomString(aLocalName),
aNsID);
NS_ENSURE_SUCCESS(rv, rv);
}
PRBool htmlRoot = aNsID == kNameSpaceID_None && !aPrefix &&
aLowercaseLocalName == txHTMLAtoms::html;
// Use aLocalName and not aLowercaseLocalName in case the output
// handler cares about case. For eHTMLOutput the handler will hardcode
// to 'html' anyway.
nsresult rv = createHandlerAndFlush(htmlRoot,
nsDependentAtomString(aLocalName),
aNsID);
NS_ENSURE_SUCCESS(rv, rv);
rv = mEs->mResultHandler->startElement(aPrefix, aLocalName,
aLowercaseLocalName, aNsID);
delete this;
return rv;
return mEs->mResultHandler->startElement(aPrefix, aLocalName,
aLowercaseLocalName, aNsID);
}
nsresult
txUnknownHandler::startElement(nsIAtom* aPrefix, const nsSubstring& aLocalName,
const PRInt32 aNsID)
{
// Make sure that mEs->mResultHandler == this is true, otherwise we'll
// leak mEs->mResultHandler in createHandlerAndFlush and we may crash
// later on trying to delete this handler again.
NS_ASSERTION(mEs->mResultHandler == this,
"We're leaking mEs->mResultHandler.");
if (!mFlushed) {
// Make sure that mEs->mResultHandler == this is true, otherwise we'll
// leak mEs->mResultHandler in createHandlerAndFlush.
NS_ASSERTION(mEs->mResultHandler == this,
"We're leaking mEs->mResultHandler.");
PRBool htmlRoot = aNsID == kNameSpaceID_None && !aPrefix &&
aLocalName.Equals(NS_LITERAL_STRING("html"),
txCaseInsensitiveStringComparator());
nsresult rv = createHandlerAndFlush(htmlRoot, aLocalName, aNsID);
NS_ENSURE_SUCCESS(rv, rv);
PRBool htmlRoot = aNsID == kNameSpaceID_None && !aPrefix &&
aLocalName.Equals(NS_LITERAL_STRING("html"),
txCaseInsensitiveStringComparator());
nsresult rv = createHandlerAndFlush(htmlRoot, aLocalName, aNsID);
NS_ENSURE_SUCCESS(rv, rv);
}
rv = mEs->mResultHandler->startElement(aPrefix, aLocalName, aNsID);
delete this;
return rv;
return mEs->mResultHandler->startElement(aPrefix, aLocalName, aNsID);
}
nsresult txUnknownHandler::createHandlerAndFlush(PRBool aHTMLRoot,
@ -159,11 +213,18 @@ nsresult txUnknownHandler::createHandlerAndFlush(PRBool aHTMLRoot,
getter_Transfers(handler));
NS_ENSURE_SUCCESS(rv, rv);
rv = mBuffer->flushToHandler(handler);
NS_ENSURE_SUCCESS(rv, rv);
mEs->mOutputHandler = handler;
mEs->mResultHandler = handler.forget();
// Let the executionstate delete us. We need to stay alive because we might
// need to forward hooks to mEs->mResultHandler if someone is currently
// flushing a buffer to mEs->mResultHandler.
mEs->mObsoleteHandler = this;
return NS_OK;
mFlushed = PR_TRUE;
// Let go of out buffer as soon as we're done flushing it, we're not going
// to need it anymore from this point on (all hooks get forwarded to
// mEs->mResultHandler.
nsAutoPtr<txResultBuffer> buffer(mBuffer);
return buffer->flushToHandler(mEs->mResultHandler);
}

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

@ -50,11 +50,7 @@ public:
txUnknownHandler(txExecutionState* aEs);
virtual ~txUnknownHandler();
nsresult endDocument(nsresult aResult);
nsresult startElement(nsIAtom* aPrefix, nsIAtom* aName,
nsIAtom* aLowercaseName, PRInt32 aNsID);
nsresult startElement(nsIAtom* aPrefix, const nsSubstring& aLocalName,
const PRInt32 aNsID);
TX_DECL_TXAXMLEVENTHANDLER
private:
nsresult createHandlerAndFlush(PRBool aHTMLRoot,
@ -67,6 +63,10 @@ private:
* The right fix may need a txOutputFormat here.
*/
txExecutionState* mEs;
// If mFlushed is true then we've replaced mEs->mResultHandler with a
// different handler and we should forward to that handler.
PRBool mFlushed;
};
#endif /* txUnknownHandler_h___ */

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

@ -55,6 +55,7 @@ _TEST_FILES = test_bug319374.xhtml \
test_bug566629.html \
test_bug566629.xhtml \
test_bug603159.html \
test_bug667315.html \
test_exslt_regex.html \
$(NULL)

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

@ -0,0 +1,47 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=667315
-->
<head>
<title>Test for Bug 667315</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=667315">Mozilla Bug 667315</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 667315 **/
var style =
'<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" ' +
'version="1.0">' +
'<xsl:variable name="var">' +
'<html><p>a</p></html>' +
'</xsl:variable>' +
'<xsl:template match="/">' +
'<xsl:copy-of select="$var" />' +
'</xsl:template>' +
'</xsl:stylesheet>';
var styleDoc = new DOMParser().parseFromString (style, "text/xml");
var data = '<root/>';
var originalDoc = new DOMParser().parseFromString(data, "text/xml");
var processor = new XSLTProcessor();
processor.importStylesheet(styleDoc);
var doc = processor.transformToDocument(originalDoc);
ok(doc instanceof HTMLDocument, "should have switched to html output method");
</script>
</pre>
</body>
</html>

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

@ -677,7 +677,9 @@ ConvertLoadTypeToNavigationType(PRUint32 aLoadType)
case LOAD_NORMAL_BYPASS_CACHE:
case LOAD_NORMAL_BYPASS_PROXY:
case LOAD_NORMAL_BYPASS_PROXY_AND_CACHE:
case LOAD_NORMAL_REPLACE:
case LOAD_LINK:
case LOAD_STOP_CONTENT:
result = nsIDOMPerformanceNavigation::TYPE_NAVIGATE;
break;
case LOAD_HISTORY:
@ -690,8 +692,6 @@ ConvertLoadTypeToNavigationType(PRUint32 aLoadType)
case LOAD_RELOAD_BYPASS_PROXY_AND_CACHE:
result = nsIDOMPerformanceNavigation::TYPE_RELOAD;
break;
case LOAD_NORMAL_REPLACE:
case LOAD_STOP_CONTENT:
case LOAD_STOP_CONTENT_AND_REPLACE:
case LOAD_REFRESH:
case LOAD_BYPASS_HISTORY:

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

@ -113,6 +113,9 @@ _TEST_FILES = \
file_bug662170.html \
test_bug570341.html \
bug570341_recordevents.html \
test_bug668513.html \
bug668513_redirect.html \
bug668513_redirect.html^headers^ \
$(NULL)
ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa)

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

@ -0,0 +1 @@
<html><body>This document is redirected to a blank document.</body></html>

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

@ -0,0 +1,2 @@
HTTP 302 Moved Temporarily
Location: navigation/blank.html

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

@ -0,0 +1,114 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=668513
-->
<head>
<title>Test for Bug 668513</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"/>
<script>
function onload_test()
{
var win = frames[0];
ok(win.performance, 'Window.performance should be defined');
ok(win.performance.navigation, 'Window.performance.navigation should be defined');
var navigation = win.performance && win.performance.navigation;
if (navigation === undefined)
{
// avoid script errors
SimpleTest.finish();
return;
}
// do this with a timeout to see the visuals of the navigations.
setTimeout("nav_frame();", 100);
}
var step = 1;
function nav_frame()
{
var navigation_frame = frames[0];
var navigation = navigation_frame.performance.navigation;
switch (step)
{
case 1:
{
navigation_frame.location.href = 'bug570341_recordevents.html';
step++;
break;
}
case 2:
{
is(navigation.type, navigation.TYPE_NAVIGATE,
'Expected window.performance.navigation.type == TYPE_NAVIGATE');
navigation_frame.history.back();
step++;
break;
}
case 3:
{
is(navigation.type, navigation.TYPE_BACK_FORWARD,
'Expected window.performance.navigation.type == TYPE_BACK_FORWARD');
step++;
navigation_frame.history.forward();
break;
}
case 4:
{
is(navigation.type, navigation.TYPE_BACK_FORWARD,
'Expected window.performance.navigation.type == TYPE_BACK_FORWARD');
navigation_frame.location.href = 'bug668513_redirect.html';
step++;
break;
}
case 5:
{
is(navigation.type, navigation.TYPE_NAVIGATE,
'Expected timing.navigation.type as TYPE_NAVIGATE');
is(navigation.redirectCount, 1,
'Expected navigation.redirectCount == 1 on an server redirected navigation');
var timing = navigation_frame.performance && navigation_frame.performance.timing;
if (timing === undefined)
{
// avoid script errors
SimpleTest.finish();
break;
}
ok(timing.navigationStart > 0, 'navigationStart should be > 0');
sequence = ['navigationStart', 'redirectStart', 'redirectEnd', 'fetchStart'];
for (var j = 1; j < sequence.length; ++j) {
var prop = sequence[j];
var prevProp = sequence[j-1];
ok(timing[prevProp] <= timing[prop],
['Expected ', prevProp, ' to happen before ', prop,
', got ', prevProp, ' = ', timing[prevProp],
', ', prop, ' = ', timing[prop]].join(''));
}
step++;
SimpleTest.finish();
}
default:
break;
}
}
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=668513">Mozilla Bug 668513</a>
<div id="frames">
<iframe name="child0" onload="onload_test();" src="navigation/blank.html"></iframe>
</div>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
</html>

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

@ -64,6 +64,7 @@ nsDOMNavigationTiming::Clear()
mFetchStart = 0;
mRedirectStart = 0;
mRedirectEnd = 0;
mRedirectCount = 0;
mBeforeUnloadStart = 0;
mUnloadStart = 0;
mUnloadEnd = 0;
@ -156,6 +157,7 @@ PRBool
nsDOMNavigationTiming::ReportRedirects()
{
if (mRedirectCheck == NOT_CHECKED) {
mRedirectCount = mRedirects.Count();
if (mRedirects.Count() == 0) {
mRedirectCheck = NO_REDIRECTS;
} else {
@ -166,6 +168,7 @@ nsDOMNavigationTiming::ReportRedirects()
nsresult rv = ssm->CheckSameOriginURI(curr, mLoadedURI, PR_FALSE);
if (!NS_SUCCEEDED(rv)) {
mRedirectCheck = CHECK_FAILED;
mRedirectCount = 0;
break;
}
}
@ -243,7 +246,7 @@ nsDOMNavigationTiming::GetRedirectCount(PRUint16* aRedirectCount)
{
*aRedirectCount = 0;
if (ReportRedirects()) {
*aRedirectCount = mRedirects.Count();
*aRedirectCount = mRedirectCount;
}
return NS_OK;
}

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

@ -95,6 +95,7 @@ private:
NO_REDIRECTS,
CHECK_FAILED} RedirectCheckState;
RedirectCheckState mRedirectCheck;
PRInt16 mRedirectCount;
nsDOMPerformanceNavigationType mNavigationType;
DOMTimeMilliSec mNavigationStart;

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

@ -2579,7 +2579,8 @@ nsGlobalWindow::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
} else if (msg == NS_MOUSE_BUTTON_DOWN &&
NS_IS_TRUSTED_EVENT(aVisitor.mEvent)) {
gMouseDown = PR_TRUE;
} else if (msg == NS_MOUSE_BUTTON_UP &&
} else if ((msg == NS_MOUSE_BUTTON_UP ||
msg == NS_DRAGDROP_END) &&
NS_IS_TRUSTED_EVENT(aVisitor.mEvent)) {
gMouseDown = PR_FALSE;
if (gDragServiceDisabled) {

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

@ -138,7 +138,7 @@ interface nsISocketTransport : nsITransport
/**
* connectionFlags is a bitmask that can be used to modify underlying
* behavior of the socket connection.
* behavior of the socket connection. See the flags below.
*/
attribute unsigned long connectionFlags;
@ -159,6 +159,12 @@ interface nsISocketTransport : nsITransport
*/
const unsigned long ANONYMOUS_CONNECT = (1 << 1);
/**
* If set, we will skip all IPv6 addresses the host may have and only
* connect to IPv4 ones.
*/
const unsigned long DISABLE_IPV6 = (1 << 2);
/**
* Socket QoS/ToS markings. Valid values are IPTOS_DSCP_AFxx or
* IPTOS_CLASS_CSx (or IPTOS_DSCP_EF, but currently no supported

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

@ -942,6 +942,8 @@ nsSocketTransport::ResolveHost()
PRUint32 dnsFlags = 0;
if (mConnectionFlags & nsSocketTransport::BYPASS_CACHE)
dnsFlags = nsIDNSService::RESOLVE_BYPASS_CACHE;
if (mConnectionFlags & nsSocketTransport::DISABLE_IPV6)
dnsFlags |= nsIDNSService::RESOLVE_DISABLE_IPV6;
SendStatus(STATUS_RESOLVING);
rv = dns->AsyncResolve(SocketHost(), dnsFlags, this, nsnull,

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

@ -462,7 +462,7 @@ nsDNSService::AsyncResolve(const nsACString &hostname,
listener = listenerProxy;
}
PRUint16 af = GetAFForLookup(*hostPtr);
PRUint16 af = GetAFForLookup(*hostPtr, flags);
nsDNSAsyncRequest *req =
new nsDNSAsyncRequest(res, *hostPtr, listener, flags, af);
@ -520,7 +520,7 @@ nsDNSService::Resolve(const nsACString &hostname,
PR_EnterMonitor(mon);
nsDNSSyncRequest syncReq(mon);
PRUint16 af = GetAFForLookup(*hostPtr);
PRUint16 af = GetAFForLookup(*hostPtr, flags);
rv = res->ResolveHost(PromiseFlatCString(*hostPtr).get(), flags, af, &syncReq);
if (NS_SUCCEEDED(rv)) {
@ -580,9 +580,9 @@ nsDNSService::Observe(nsISupports *subject, const char *topic, const PRUnichar *
}
PRUint16
nsDNSService::GetAFForLookup(const nsACString &host)
nsDNSService::GetAFForLookup(const nsACString &host, PRUint32 flags)
{
if (mDisableIPv6)
if (mDisableIPv6 || (flags & RESOLVE_DISABLE_IPV6))
return PR_AF_INET;
MutexAutoLock lock(mLock);

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

@ -55,7 +55,7 @@ public:
~nsDNSService();
private:
PRUint16 GetAFForLookup(const nsACString &host);
PRUint16 GetAFForLookup(const nsACString &host, PRUint32 flags);
nsRefPtr<nsHostResolver> mResolver;
nsCOMPtr<nsIIDNService> mIDN;

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

@ -120,4 +120,9 @@ interface nsIDNSService : nsISupports
* return errors if prefetching is disabled by configuration.
*/
const unsigned long RESOLVE_SPECULATE = (1 << 4);
/**
* If set, only IPv4 addresses will be returned from resolve/asyncResolve.
*/
const unsigned long RESOLVE_DISABLE_IPV6 = (1 << 5);
};

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

@ -1291,7 +1291,8 @@ nsresult
nsHttpConnectionMgr::
nsHalfOpenSocket::SetupStreams(nsISocketTransport **transport,
nsIAsyncInputStream **instream,
nsIAsyncOutputStream **outstream)
nsIAsyncOutputStream **outstream,
PRBool isBackup)
{
nsresult rv;
@ -1320,6 +1321,14 @@ nsHalfOpenSocket::SetupStreams(nsISocketTransport **transport,
if (mTransaction->Caps() & NS_HTTP_LOAD_ANONYMOUS)
tmpFlags |= nsISocketTransport::ANONYMOUS_CONNECT;
// For backup connections, we disable IPv6. That's because some users have
// broken IPv6 connectivity (leading to very long timeouts), and disabling
// IPv6 on the backup connection gives them a much better user experience
// with dual-stack hosts, though they still pay the 250ms delay for each new
// connection. This strategy is also known as "happy eyeballs".
if (isBackup)
tmpFlags |= nsISocketTransport::DISABLE_IPV6;
socketTransport->SetConnectionFlags(tmpFlags);
socketTransport->SetQoSBits(gHttpHandler->GetQoSBits());
@ -1358,7 +1367,8 @@ nsHttpConnectionMgr::nsHalfOpenSocket::SetupPrimaryStreams()
{
nsresult rv = SetupStreams(getter_AddRefs(mSocketTransport),
getter_AddRefs(mStreamIn),
getter_AddRefs(mStreamOut));
getter_AddRefs(mStreamOut),
PR_FALSE);
LOG(("nsHalfOpenSocket::SetupPrimaryStream [this=%p ent=%s rv=%x]",
this, mEnt->mConnInfo->Host(), rv));
if (NS_FAILED(rv)) {
@ -1376,7 +1386,8 @@ nsHttpConnectionMgr::nsHalfOpenSocket::SetupBackupStreams()
{
nsresult rv = SetupStreams(getter_AddRefs(mBackupTransport),
getter_AddRefs(mBackupStreamIn),
getter_AddRefs(mBackupStreamOut));
getter_AddRefs(mBackupStreamOut),
PR_TRUE);
LOG(("nsHalfOpenSocket::SetupBackupStream [this=%p ent=%s rv=%x]",
this, mEnt->mConnInfo->Host(), rv));
if (NS_FAILED(rv)) {

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

@ -211,7 +211,8 @@ private:
nsresult SetupStreams(nsISocketTransport **,
nsIAsyncInputStream **,
nsIAsyncOutputStream **);
nsIAsyncOutputStream **,
PRBool isBackup);
nsresult SetupPrimaryStreams();
nsresult SetupBackupStreams();
void SetupBackupTimer();

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

@ -14,6 +14,8 @@
</resources>
<content sizetopopup="pref">
<children includes="menupopup"/>
<xul:hbox class="autocomplete-textbox-container" flex="1" align="center">
<children includes="image|deck|stack|box">
<xul:image class="autocomplete-icon" allowevents="true"/>