зеркало из https://github.com/mozilla/pjs.git
Merge last green changeset from mozilla-central to mozilla-inbound
This commit is contained in:
Коммит
97bcd1a43c
|
@ -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"/>
|
||||
|
|
Загрузка…
Ссылка в новой задаче