merge m-c to fx-team

This commit is contained in:
Jared Wein 2012-02-24 14:47:45 -05:00
commit 027e96add3
541 changed files with 9839 additions and 12275 deletions

View File

@ -90,10 +90,6 @@ public:
*/
virtual already_AddRefed<nsAccessible>
CreateHTMLBRAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
virtual already_AddRefed<nsAccessible>
CreateHTML4ButtonAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
virtual already_AddRefed<nsAccessible>
CreateHTMLButtonAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
virtual already_AddRefed<nsAccessible>
CreateHTMLCaptionAccessible(nsIContent* aContent, nsIPresShell* aPresShell) = 0;
virtual already_AddRefed<nsAccessible>

View File

@ -217,17 +217,6 @@ nsAccessibilityService::CreateOuterDocAccessible(nsIContent* aContent,
return accessible;
}
already_AddRefed<nsAccessible>
nsAccessibilityService::CreateHTML4ButtonAccessible(nsIContent* aContent,
nsIPresShell* aPresShell)
{
nsAccessible* accessible =
new nsHTML4ButtonAccessible(aContent,
nsAccUtils::GetDocAccessibleFor(aPresShell));
NS_ADDREF(accessible);
return accessible;
}
already_AddRefed<nsAccessible>
nsAccessibilityService::CreateHTMLButtonAccessible(nsIContent* aContent,
nsIPresShell* aPresShell)

View File

@ -89,13 +89,10 @@ public:
// nsIAccessibilityService
virtual nsAccessible* GetRootDocumentAccessible(nsIPresShell* aPresShell,
bool aCanCreate);
already_AddRefed<nsAccessible>
CreateHTMLButtonAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
virtual already_AddRefed<nsAccessible>
CreateHTMLBRAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
virtual already_AddRefed<nsAccessible>
CreateHTML4ButtonAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
virtual already_AddRefed<nsAccessible>
CreateHTMLButtonAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
already_AddRefed<nsAccessible>
CreateHTMLCanvasAccessible(nsIContent* aContent, nsIPresShell* aPresShell);
virtual already_AddRefed<nsAccessible>

View File

@ -838,9 +838,9 @@ nsAccessible::ChildAtPoint(PRInt32 aX, PRInt32 aY,
nsPresContext *presContext = frame->PresContext();
nsIntRect screenRect = frame->GetScreenRectExternal();
nsPoint offset(presContext->DevPixelsToAppUnits(aX - screenRect.x),
presContext->DevPixelsToAppUnits(aY - screenRect.y));
nsRect screenRect = frame->GetScreenRectInAppUnits();
nsPoint offset(presContext->DevPixelsToAppUnits(aX) - screenRect.x,
presContext->DevPixelsToAppUnits(aY) - screenRect.y);
nsCOMPtr<nsIPresShell> presShell = presContext->PresShell();
nsIFrame *foundFrame = presShell->GetFrameForPoint(frame, offset);
@ -853,6 +853,11 @@ nsAccessible::ChildAtPoint(PRInt32 aX, PRInt32 aY,
// the DOM parent chain.
nsDocAccessible* contentDocAcc = GetAccService()->
GetDocAccessible(content->OwnerDoc());
// contentDocAcc in some circumstances can be NULL
// See https://bugzilla.mozilla.org/show_bug.cgi?id=729861
NS_ENSURE_TRUE(contentDocAcc, fallbackAnswer);
nsAccessible* accessible = contentDocAcc->GetAccessibleOrContainer(content);
if (!accessible)
return fallbackAnswer;

View File

@ -314,7 +314,7 @@ nsresult
nsHTMLButtonAccessible::GetNameInternal(nsAString& aName)
{
nsAccessible::GetNameInternal(aName);
if (!aName.IsEmpty())
if (!aName.IsEmpty() || mContent->Tag() != nsGkAtoms::input)
return NS_OK;
// No name from HTML or ARIA
@ -353,71 +353,6 @@ nsHTMLButtonAccessible::IsWidget() const
}
////////////////////////////////////////////////////////////////////////////////
// nsHTML4ButtonAccessible
////////////////////////////////////////////////////////////////////////////////
nsHTML4ButtonAccessible::
nsHTML4ButtonAccessible(nsIContent* aContent, nsDocAccessible* aDoc) :
nsHyperTextAccessibleWrap(aContent, aDoc)
{
}
PRUint8
nsHTML4ButtonAccessible::ActionCount()
{
return 1;
}
NS_IMETHODIMP nsHTML4ButtonAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
{
if (aIndex == eAction_Click) {
aName.AssignLiteral("press");
return NS_OK;
}
return NS_ERROR_INVALID_ARG;
}
NS_IMETHODIMP
nsHTML4ButtonAccessible::DoAction(PRUint8 aIndex)
{
if (aIndex != 0)
return NS_ERROR_INVALID_ARG;
DoCommand();
return NS_OK;
}
role
nsHTML4ButtonAccessible::NativeRole()
{
return roles::PUSHBUTTON;
}
PRUint64
nsHTML4ButtonAccessible::NativeState()
{
PRUint64 state = nsHyperTextAccessibleWrap::NativeState();
state |= states::FOCUSABLE;
nsEventStates elmState = mContent->AsElement()->State();
if (elmState.HasState(NS_EVENT_STATE_DEFAULT))
state |= states::DEFAULT;
return state;
}
////////////////////////////////////////////////////////////////////////////////
// nsHTML4ButtonAccessible: Widgets
bool
nsHTML4ButtonAccessible::IsWidget() const
{
return true;
}
////////////////////////////////////////////////////////////////////////////////
// nsHTMLTextFieldAccessible
////////////////////////////////////////////////////////////////////////////////

View File

@ -92,7 +92,7 @@ public:
/**
* Accessible for HTML input@type="button", @type="submit", @type="image"
* elements.
* and HTML button elements.
*/
class nsHTMLButtonAccessible : public nsHyperTextAccessibleWrap
{
@ -120,33 +120,6 @@ public:
};
/**
* Accessible for HTML button element.
*/
class nsHTML4ButtonAccessible : public nsHyperTextAccessibleWrap
{
public:
enum { eAction_Click = 0 };
nsHTML4ButtonAccessible(nsIContent* aContent, nsDocAccessible* aDoc);
// nsIAccessible
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD DoAction(PRUint8 index);
// nsAccessible
virtual mozilla::a11y::role NativeRole();
virtual PRUint64 NativeState();
// ActionAccessible
virtual PRUint8 ActionCount();
// Widgets
virtual bool IsWidget() const;
};
/**
* Accessible for HTML input@type="text" element.
*/

View File

@ -50,7 +50,7 @@ _TEST_FILES =\
test_aria.html \
test_general.html \
test_general.xul \
test_inputs.html \
test_controls.html \
test_keys_menu.xul \
test_keys.html \
test_link.html \

View File

@ -25,6 +25,11 @@
actionName: "press",
events: CLICK_EVENTS
},
{
ID: "input_button",
actionName: "press",
events: CLICK_EVENTS
},
{
ID: "checkbox_unchecked",
actionName: "check",
@ -68,7 +73,9 @@
<pre id="test">
</pre>
<button id="button" value="button">Button</button>
<button id="button">Button</button>
<input id="input_button" type="button" value="normal">
<input id="checkbox_unchecked" type="checkbox">Checkbox</input>

View File

@ -18,36 +18,19 @@
src="../browser.js"></script>
<script type="application/javascript">
////////////////////////////////////////////////////////////////////////////
// If your patch changes UI or default styles then please tweek the numbers.
// Accessibility exposes coordinates and size in device pixels while DOM
// operates with CSS pixels. Thus it seems we don't have another way for
// accessibility testing rather than numbers hardcode.
////////////////////////////////////////////////////////////////////////////
function doTest()
{
var [outerX, outerY] = getBounds(getAccessible(currentTabDocument()).parent);
var tabDocument = currentTabDocument();
var p1 = tabDocument.body.firstElementChild;
var p2 = tabDocument.body.lastElementChild;
var p1 = currentTabDocument().body.firstElementChild;
var p2 = currentTabDocument().body.lastElementChild;
testBounds(p1);
testBounds(p2);
var deltaX = 8, deltaY = 8, indentY = 16, w = 584, h = (WIN ? 20 : 19);
testBounds(p1, outerX + deltaX, outerY + deltaY, w, h);
testBounds(p2, outerX + deltaX, outerY + deltaY + h + indentY, w, h);
zoomDocument(tabDocument, 2.0);
var docShell = currentTabWindow().
QueryInterface(Components.interfaces.nsIInterfaceRequestor).
getInterface(Components.interfaces.nsIWebNavigation).
QueryInterface(Components.interfaces.nsIDocShell);
var docViewer = docShell.contentViewer.
QueryInterface(Components.interfaces.nsIMarkupDocumentViewer);
docViewer.fullZoom = 2.0;
testBounds(p1, outerX + deltaX * 2, outerY + deltaY * 2, w * 2, h * 2);
testBounds(p2, outerX + deltaX * 2, outerY + (deltaY + h + indentY) * 2,
w * 2, h * 2);
testBounds(p1);
testBounds(p2);
closeBrowserWindow();
SimpleTest.finish();

View File

@ -98,6 +98,21 @@ function reloadButton()
return browserWindow().document.getElementById("urlbar-reload-button");
}
/**
* Zoom the given document.
*/
function zoomDocument(aDocument, aZoom)
{
var docShell = aDocument.defaultView.
QueryInterface(Components.interfaces.nsIInterfaceRequestor).
getInterface(Components.interfaces.nsIWebNavigation).
QueryInterface(Components.interfaces.nsIDocShell);
var docViewer = docShell.contentViewer.
QueryInterface(Components.interfaces.nsIMarkupDocumentViewer);
docViewer.fullZoom = aZoom;
}
////////////////////////////////////////////////////////////////////////////////
// private section

View File

@ -46,9 +46,10 @@ include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_TEST_FILES = \
test_browser.html \
test_general.html \
test_general.xul \
test_browser.html \
test_zoom.html \
$(NULL)
libs:: $(_TEST_FILES)

View File

@ -16,16 +16,13 @@
function doTest()
{
// Hit testing. See bug #726097
var nodeObj = { value: null };
var hititem = getAccessible("hititem", null, nodeObj);
var [deltaX, deltaY] = getScreenCoords(nodeObj.value);
var hititem = getAccessible("hititem");
var hittest = getAccessible("hittest");
var hitX = {}, hitY = {}, hitWidth = {}, hitHeight = {};
hititem.getBounds(hitX, hitY, hitWidth, hitHeight);
var [hitX, hitY, hitWidth, hitHeight] = getBounds(hititem);
var tgtX = hitX + hitWidth / 2;
var tgtY = hitY + hitHeight / 2;
var tgtX = deltaX + (hitWidth.value / 2);
var tgtY = deltaY + (hitHeight.value / 2);
var rootAcc = getRootAccessible();
var docAcc = getAccessible(document);
var outerDocAcc = docAcc.parent;

View File

@ -0,0 +1,57 @@
<!DOCTYPE html>
<html>
<head>
<title>childAtPoint when page is zoomed</title>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="../common.js"></script>
<script type="application/javascript"
src="../role.js"></script>
<script type="application/javascript"
src="../layout.js"></script>
<script type="application/javascript"
src="../browser.js"></script>
<script type="application/javascript">
function doTest()
{
var tabDocument = currentTabDocument();
var p1 = tabDocument.body.firstElementChild;
var p2 = tabDocument.body.lastElementChild;
hitTest(tabDocument, p1, p1.firstChild);
hitTest(tabDocument, p2, p2.firstChild);
zoomDocument(tabDocument, 2.0);
hitTest(tabDocument, p1, p1.firstChild);
hitTest(tabDocument, p2, p2.firstChild);
closeBrowserWindow();
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
openBrowserWindow(doTest,
"data:text/html,<html><body><p>para 1</p><p>para 2</p></body></html>",
{ left: 100, top: 100 });
</script>
</head>
<body>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=727942"
title="childAtPoint may return incorrect accessibles when page zoomed">
Mozilla Bug 727942
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
</body>
</html>

View File

@ -22,6 +22,29 @@ function testChildAtPoint(aIdentifier, aX, aY, aFindDeepestChild,
is(childAcc, actualChildAcc, msg);
}
/**
* Test if getChildAtPoint returns the given child and grand child accessibles
* at coordinates of child accessible (direct and deep hit test).
*/
function hitTest(aContainerID, aChildID, aGrandChildID)
{
var container = getAccessible(aContainerID);
var child = getAccessible(aChildID);
var grandChild = getAccessible(aGrandChildID);
var [x, y] = getBoundsForDOMElm(child);
var actualChild = container.getChildAtPoint(x + 1, y + 1);
is(actualChild, child,
"Wrong child, expected: " + prettyName(child) +
", got: " + prettyName(actualChild));
var actualGrandChild = container.getDeepestChildAtPoint(x + 1, y + 1);
is(actualGrandChild, grandChild,
"Wrong deepest child, expected: " + prettyName(grandChild) +
", got: " + prettyName(actualGrandChild));
}
/**
* Return child accessible at the given point.
*
@ -34,17 +57,14 @@ function testChildAtPoint(aIdentifier, aX, aY, aFindDeepestChild,
*/
function getChildAtPoint(aIdentifier, aX, aY, aFindDeepestChild)
{
var nodeObj = { value: null };
var acc = getAccessible(aIdentifier, null, nodeObj);
var node = nodeObj.value;
if (!acc || !node)
var acc = getAccessible(aIdentifier);
if (!acc)
return;
var [deltaX, deltaY] = getScreenCoords(node);
var [screenX, screenY] = getBoundsForDOMElm(acc.DOMNode);
var x = deltaX + aX;
var y = deltaY + aY;
var x = screenX + aX;
var y = screenY + aY;
try {
if (aFindDeepestChild)
@ -58,14 +78,16 @@ function getChildAtPoint(aIdentifier, aX, aY, aFindDeepestChild)
/**
* Test the accessible boundaries.
*/
function testBounds(aID, aX, aY, aWidth, aHeight)
function testBounds(aID)
{
var [expectedX, expectedY, expectedWidth, expectedHeight] =
getBoundsForDOMElm(aID);
var [x, y, width, height] = getBounds(aID);
is(x, aX, "Wrong x coordinate of " + prettyName(aID));
is(y, aY, "Wrong y coordinate of " + prettyName(aID));
// XXX: width varies depending on platform
//is(width, aWidth, "Wrong width of " + prettyName(aID));
is(height, aHeight, "Wrong height of " + prettyName(aID));
is(x, expectedX, "Wrong x coordinate of " + prettyName(aID));
is(y, expectedY, "Wrong y coordinate of " + prettyName(aID));
is(width, expectedWidth, "Wrong width of " + prettyName(aID));
is(height, expectedHeight, "Wrong height of " + prettyName(aID));
}
/**
@ -80,24 +102,21 @@ function getBounds(aID)
}
/**
* Return DOM node coordinates relative screen as pair (x, y).
* Return DOM node coordinates relative the screen and its size in device
* pixels.
*/
function getScreenCoords(aNode)
function getBoundsForDOMElm(aID)
{
if (aNode instanceof nsIDOMXULElement)
return [node.boxObject.screenX, node.boxObject.screenY];
var elm = getNode(aID);
var elmWindow = elm.ownerDocument.defaultView;
var winUtil = elmWindow.
QueryInterface(Components.interfaces.nsIInterfaceRequestor).
getInterface(Components.interfaces.nsIDOMWindowUtils);
// Ugly hack until bug 486200 is fixed.
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var descr = document.createElementNS(XUL_NS, "description");
descr.setAttribute("value", "helper description");
aNode.parentNode.appendChild(descr);
var descrBoxObject = descr.boxObject;
var descrRect = descr.getBoundingClientRect();
var deltaX = descrBoxObject.screenX - descrRect.left;
var deltaY = descrBoxObject.screenY - descrRect.top;
aNode.parentNode.removeChild(descr);
var rect = aNode.getBoundingClientRect();
return [rect.left + deltaX, rect.top + deltaY];
var ratio = winUtil.screenPixelsPerCSSPixel;
var rect = elm.getBoundingClientRect();
return [ (rect.left + elmWindow.mozInnerScreenX) * ratio,
(rect.top + elmWindow.mozInnerScreenY) * ratio,
rect.width * ratio,
rect.height * ratio ];
}

View File

@ -17,14 +17,16 @@
function doTest()
{
// Default state.
testStates("f1_image", STATE_DEFAULT);
testStates("f2_submit", STATE_DEFAULT);
testStates("f3_submitbutton", STATE_DEFAULT);
testStates("f4_button", 0, 0, STATE_DEFAULT);
testStates("f4_image1", STATE_DEFAULT);
testStates("f4_image2", 0, 0, STATE_DEFAULT);
testStates("f4_submit", 0, 0, STATE_DEFAULT);
testStates("f4_submitbutton", 0, 0, STATE_DEFAULT);
testStates("f1_image", STATE_DEFAULT | STATE_FOCUSABLE);
testStates("f2_submit", STATE_DEFAULT | STATE_FOCUSABLE);
testStates("f3_submitbutton", STATE_DEFAULT | STATE_FOCUSABLE);
testStates("f3_disabled_reset", STATE_UNAVAILABLE, 0, STATE_FOCUSABLE, 0);
testStates("f4_button", STATE_FOCUSABLE, 0, STATE_DEFAULT);
testStates("f4_disabled_button", STATE_UNAVAILABLE, 0, STATE_FOCUSABLE, 0);
testStates("f4_image1", STATE_DEFAULT | STATE_FOCUSABLE);
testStates("f4_image2", STATE_FOCUSABLE, 0, STATE_DEFAULT);
testStates("f4_submit", STATE_FOCUSABLE, 0, STATE_DEFAULT);
testStates("f4_submitbutton", STATE_FOCUSABLE, 0, STATE_DEFAULT);
SimpleTest.finish();
}
@ -62,6 +64,7 @@
<form name="form3" method="get">
<input type="text" name="hi">
<button id="f3_submitbutton" type="submit">submit</button>
<button id="f3_disabled_reset" type="reset" disabled>reset</button>
</form>
<p>A form with normal button, two image buttons, submit button,
@ -69,6 +72,7 @@
<form name="form4" method="get">
<input type="text" name="hi">
<input id="f4_button" type="button" value="normal" name="normal-button">
<input id="f4_disabled_button" type="button" value="disabled" name="disabled-button" disabled>
<input id="f4_image1" type="image" value="image-button1" name="image-button1">
<input id="f4_image2" type="image" value="image-button2" name="image-button2">
<input id="f4_submit" type="submit" value="real-submit" name="real-submit">

View File

@ -106,6 +106,7 @@ pref("mozilla.widget.force-24bpp", true);
pref("mozilla.widget.use-buffer-pixmap", true);
pref("mozilla.widget.disable-native-theme", true);
pref("layout.reflow.synthMouseMove", false);
pref("dom.send_after_paint_to_content", true);
/* download manager (don't show the window or alert) */
pref("browser.download.useDownloadDir", true);
@ -353,9 +354,6 @@ pref("urlclassifier.gethashtables", "goog-phish-shavar,goog-malware-shavar");
// the database.
pref("urlclassifier.confirm-age", 2700);
// Maximum size of the sqlite3 cache during an update, in bytes
pref("urlclassifier.updatecachemax", 4194304);
// URL for checking the reason for a malware warning.
pref("browser.safebrowsing.malware.reportURL", "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
#endif
@ -392,6 +390,7 @@ pref("layers.acceleration.force-enabled", true);
// screen.enabled and screen.brightness properties.
pref("dom.screenEnabledProperty.enabled", true);
pref("dom.screenBrightnessProperty.enabled", true);
pref("dom.mozScreenWhitelist", "http://localhost:7777");
// handle links targeting new windows
// 1=current window/tab, 2=new window, 3=new tab in most recent window
@ -430,6 +429,10 @@ pref("layout.frame_rate.precise", true);
pref("b2g.remote-js.enabled", true);
pref("b2g.remote-js.port", 9999);
// Handle hardware buttons in the b2g chrome package
pref("b2g.keys.menu.enabled", true);
pref("b2g.keys.search.enabled", false);
// Screen timeout in minutes
pref("power.screen.timeout", 60);

View File

@ -107,6 +107,6 @@ xul|thumb {
-moz-border-right-colors: none !important;
-moz-border-left-colors: none !important;
border: 1px solid rgba(255, 255, 255, 0.4) !important;
-moz-border-radius: 3px;
border-radius: 3px;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 850 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 886 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 631 B

View File

@ -0,0 +1,127 @@
/*
* This defines the look-and-feel styling of the error pages.
* (see: netError.xhtml)
*
* Original styling by William Price <bugzilla@mob.rice.edu>
* Updated for mobile by: Wes Johnston <wjohnston@mozilla.com>
*/
body {
margin: 0;
padding: 0 8px 8px;
font-family: "Nokia Sans", Tahoma, sans-serif !important;
}
h1 {
font-size: 22px;
}
h2 {
font-size: 16px;
}
ul {
margin: 0px;
padding: 0px 0px 0px 1em;
}
li {
margin: 0px;
padding: 8px 0px;
}
#errorPage {
background-color: #CEE6F4;
}
#errorPage.certerror {
background-color: #EFD400;
}
#errorPage.blockedsite {
background-color: #BF0000;
}
#errorTitle {
background: url("chrome://browser/content/images/errorpage-warning.png") left center no-repeat;
/* Scaled by .666 of their actual size */
background-size: 40px 40px;
background-origin: content-box;
min-height: 60px;
margin-left: auto;
margin-right: auto;
max-width: 500px;
margin-left: auto;
margin-right: auto;
}
#errorPage.certerror #errorTitle {
background-image: url("chrome://browser/content/images/errorpage-larry-black.png");
}
#errorPage.blockedsite #errorTitle {
background-image: url("chrome://browser/content/images/errorpage-larry-white.png");
color: white;
}
.errorTitleText {
padding: 0px 0px 0px 50px;
display: inline-block;
vertical-align: middle
}
#errorPageContainer {
background-color: white;
border: 1px solid #999999;
border-radius: 6px;
padding: 6px 20px 20px;
font-size: 14px;
max-width: 500px;
margin-left: auto;
margin-right: auto;
}
#errorShortDesc > p:empty {
display: none;
}
#errorShortDesc > p {
overflow: auto;
border-bottom: 1px solid #999999;
padding-bottom: 1em;
}
#errorPage.blockedsite #errorShortDesc > p {
font-weight: bold;
border-bottom: none;
padding-bottom: 0px;
}
#securityOverrideDiv {
padding-top: 10px;
}
div[collapsed] {
padding-left: 15px;
background-image: url("chrome://browser/skin/images/arrowright-16.png");
background-size: 11px 11px;
background-repeat: no-repeat;
background-position: left 0.3em;
}
div[collapsed="true"] {
background-image: url("chrome://browser/skin/images/arrowright-16.png");
}
div[collapsed="false"] {
background-image: url("chrome://browser/skin/images/arrowdown-16.png");
}
div[collapsed="true"] > p,
div[collapsed="true"] > div {
display: none;
}
button {
padding: 0.3em !important;
}

View File

@ -304,7 +304,6 @@
</head>
<body id="errorPage" dir="&locale.dir;">
<!-- ERROR ITEM CONTAINER (removed during loading to avoid bug 39098) -->
<div id="errorContainer">
<div id="errorTitlesContainer">
@ -318,6 +317,7 @@
<h1 id="et_redirectLoop">&redirectLoop.title;</h1>
<h1 id="et_unknownSocketType">&unknownSocketType.title;</h1>
<h1 id="et_netReset">&netReset.title;</h1>
<h1 id="et_notCached">&notCached.title;</h1>
<h1 id="et_netOffline">&netOffline.title;</h1>
<h1 id="et_netInterrupt">&netInterrupt.title;</h1>
<h1 id="et_deniedPortAccess">&deniedPortAccess.title;</h1>
@ -342,6 +342,7 @@
<div id="ed_redirectLoop">&redirectLoop.longDesc;</div>
<div id="ed_unknownSocketType">&unknownSocketType.longDesc;</div>
<div id="ed_netReset">&netReset.longDesc;</div>
<div id="ed_notCached">&notCached.longDesc;</div>
<div id="ed_netOffline">&netOffline.longDesc2;</div>
<div id="ed_netInterrupt">&netInterrupt.longDesc;</div>
<div id="ed_deniedPortAccess">&deniedPortAccess.longDesc;</div>

View File

@ -37,6 +37,23 @@ XPCOMUtils.defineLazyServiceGetter(Services, 'fm', function(){
.getService(Ci.nsFocusManager);
});
#ifndef MOZ_WIDGET_GONK
// In order to use http:// scheme instead of file:// scheme
// (that is much more restricted) the following code kick-off
// a local http server listening on http://127.0.0.1:7777 and
// http://localhost:7777.
function startupHttpd(baseDir, port) {
const httpdURL = 'chrome://browser/content/httpd.js';
let httpd = {};
Services.scriptloader.loadSubScript(httpdURL, httpd);
let server = new httpd.nsHttpServer();
server.registerDirectory('/', new LocalFile(baseDir));
server.registerContentType('appcache', 'text/cache-manifest');
server.start(port);
}
#endif
// FIXME Bug 707625
// until we have a proper security model, add some rights to
// the pre-installed web applications
@ -105,7 +122,21 @@ var shell = {
let fileScheme = 'file://';
if (homeURL.substring(0, fileScheme.length) == fileScheme) {
#ifndef MOZ_WIDGET_GONK
homeURL = homeURL.replace(fileScheme, '');
let baseDir = homeURL.split('/');
baseDir.pop();
baseDir = baseDir.join('/');
const SERVER_PORT = 7777;
startupHttpd(baseDir, SERVER_PORT);
let baseHost = 'http://localhost';
homeURL = homeURL.replace(baseDir, baseHost + ':' + SERVER_PORT);
#else
homeURL = 'http://localhost:7777' + homeURL.replace(fileScheme, '');
#endif
}
addPermissions([homeURL]);
} catch (e) {
@ -213,10 +244,12 @@ var shell = {
case 'AppCommand':
switch (evt.command) {
case 'Menu':
this.sendEvent(content, 'menu');
if (Services.prefs.getBoolPref('b2g.keys.menu.enabled'))
this.sendEvent(content, 'menu');
break;
case 'Search':
this.toggleDebug();
if (Services.prefs.getBoolPref('b2g.keys.search.enabled'))
this.toggleDebug();
break;
case 'VolumeUp':
this.changeVolume(1);

View File

@ -20,11 +20,18 @@
#ifndef MOZ_TOUCH
<script type="application/javascript" src="chrome://browser/content/touch.js"/>
#endif
#ifndef MOZ_WIDGET_GONK
<script type="application/javascript" src="chrome://browser/content/httpd.js"/>
#endif
<commandset id="mainCommandSet">
<command id="cmd_close" oncommand="CommandUpdater.doCommand(this.id);"/>
</commandset>
<browser id="homescreen" type="content-primary" flex="1" style="overflow: hidden;"/>
<browser id="homescreen"
type="content-primary"
flex="1"
style="overflow: hidden;"
src="data:text/html;base64,PCFET0NUWVBFIGh0bWw+PGh0bWw+PGJvZHkgc3R5bGU9ImJhY2tncm91bmQ6YmxhY2s7Ij48L2JvZHk+PC9odG1sPgo="/>
</window>

View File

@ -84,6 +84,18 @@ XPCOMUtils.defineLazyGetter(Services, 'fm', function() {
content.dispatchEvent(event);
}
function maybeShowIme(targetElement) {
// FIXME/bug 729623: work around apparent bug in the IME manager
// in gecko.
let readonly = targetElement.getAttribute('readonly');
if (readonly)
return false;
let type = targetElement.type;
fireEvent('showime', { type: type });
return true;
}
let constructor = {
handleEvent: function vkm_handleEvent(evt) {
switch (evt.type) {
@ -102,9 +114,7 @@ XPCOMUtils.defineLazyGetter(Services, 'fm', function() {
if (evt.target != activeElement || isKeyboardOpened)
return;
let type = activeElement.type;
fireEvent('showime', { type: type });
isKeyboardOpened = true;
isKeyboardOpened = maybeShowIme(activeElement);
break;
}
},
@ -112,11 +122,10 @@ XPCOMUtils.defineLazyGetter(Services, 'fm', function() {
let shouldOpen = parseInt(data);
if (shouldOpen && !isKeyboardOpened) {
activeElement = Services.fm.focusedElement;
if (!activeElement)
if (!activeElement || !maybeShowIme(activeElement)) {
activeElement = null;
return;
let type = activeElement.type;
fireEvent('showime', { type: type });
}
} else if (!shouldOpen && isKeyboardOpened) {
fireEvent('hideime');
}
@ -313,7 +322,7 @@ const KineticPanning = {
return this.target !== null;
},
_target: null,
target: null,
start: function kp_start(target) {
this.target = target;

View File

@ -5,14 +5,21 @@ chrome.jar:
% content browser %content/
* content/shell.xul (content/shell.xul)
content/shell.js (content/shell.js)
* content/shell.js (content/shell.js)
#ifndef MOZ_TOUCH
content/touch.js (content/touch.js)
#endif
content/commandUtil.js (content/commandUtil.js)
#ifndef MOZ_WIDGET_GONK
content/httpd.js (content/httpd.js)
#endif
content/webapi.js (content/webapi.js)
content/content.css (content/content.css)
% override chrome://global/content/netError.xhtml chrome://browser/content/netError.xhtml
% override chrome://global/skin/netError.css chrome://browser/content/netError.css
content/netError.xhtml (content/netError.xhtml)
content/netError.css (content/netError.css)
content/images/errorpage-larry-black.png (content/images/errorpage-larry-black.png)
content/images/errorpage-larry-white.png (content/images/errorpage-larry-white.png)
content/images/errorpage-warning.png (content/images/errorpage-warning.png)

View File

@ -401,6 +401,8 @@
#ifdef MOZ_B2G_RIL
@BINPATH@/components/RadioInterfaceLayer.manifest
@BINPATH@/components/RadioInterfaceLayer.js
@BINPATH@/components/SmsDatabaseService.manifest
@BINPATH@/components/SmsDatabaseService.js
@BINPATH@/components/nsWifiWorker.js
@BINPATH@/components/nsWifiWorker.manifest
#endif

View File

@ -181,7 +181,7 @@ image.study-result {
color: white;
font-weight: bold;
padding: 2px;
-moz-border-radius: 100%;
border-radius: 100%;
margin-right: 25px;
margin-bottom: 13px;
}

View File

@ -102,9 +102,8 @@ src: url('chrome://testpilot/skin/fonts/DroidSans-Bold.ttf') format('truetype');
font-size: 16px;
padding: 8px 12px;
color: rgba(0, 0, 0, 0.8);
-moz-border-radius: 0.5em;
-webkit-border-radius: 0.5em;
-moz-box-shadow:
border-radius: 0.5em;
box-shadow:
inset rgba(0, 0, 0, 0.2) 0 1px 1px,
inset rgba(255, 255, 255, 1) 0 3px 1px,
inset rgba(255, 255, 255, 0.3) 0 16px 0px,
@ -122,9 +121,8 @@ src: url('chrome://testpilot/skin/fonts/DroidSans-Bold.ttf') format('truetype');
padding: 8px 12px;
width: 240px;
color: rgba(0, 0, 0, 0.8);
-moz-border-radius: 0.5em;
-webkit-border-radius: 0.5em;
-moz-box-shadow:
border-radius: 0.5em;
box-shadow:
inset rgba(0, 0, 0, 0.2) 0 1px 1px,
inset rgba(255, 255, 255, 1) 0 3px 1px,
inset rgba(255, 255, 255, 0.3) 0 16px 0px,
@ -143,10 +141,9 @@ src: url('chrome://testpilot/skin/fonts/DroidSans-Bold.ttf') format('truetype');
padding: 8px 24px;
margin: 24px auto;
color: rgba(0, 0, 0, 0.8);
-moz-border-radius: 0.5em;
-webkit-border-radius: 0.5em;
border-radius: 0.5em;
background: rgba(220, 240, 247, 0.8) url('chrome://testpilot/skin/callout.png') no-repeat top center;
-moz-box-shadow:
box-shadow:
inset rgba(185, 221, 234, 0.2) 0 -10px 12px,
inset rgba(185, 221, 234, 1) 0 0px 1px,
inset rgba(255, 255, 255, 0.2) 0 10px 12px;
@ -161,10 +158,9 @@ src: url('chrome://testpilot/skin/fonts/DroidSans-Bold.ttf') format('truetype');
padding: 8px 24px;
margin: 8px auto;
color: rgba(0, 0, 0, 0.8);
-moz-border-radius: 0.5em;
-webkit-border-radius: 0.5em;
border-radius: 0.5em;
background: rgba(220, 240, 247, 0.8) url('chrome://testpilot/skin/callout.png') no-repeat top center;
-moz-box-shadow:
box-shadow:
inset rgba(185, 221, 234, 0.2) 0 -10px 12px,
inset rgba(185, 221, 234, 1) 0 0px 1px,
inset rgba(255, 255, 255, 0.2) 0 10px 12px;
@ -197,8 +193,7 @@ src: url('chrome://testpilot/skin/fonts/DroidSans-Bold.ttf') format('truetype');
padding: 4px 40px;
width: 800px;
text-align: left;
-moz-border-radius: 0.25em;
-webkit-border-radius: 0.25em;
border-radius: 0.25em;
border-top: 1px solid #adb6ba;
border-left: 1px solid #adb6ba;
border-right: 1px solid #adb6ba;
@ -223,7 +218,7 @@ src: url('chrome://testpilot/skin/fonts/DroidSans-Bold.ttf') format('truetype');
font-size: 14px;
text-shadow: 1px 1px 1px rgba(173, 182, 186, 1);
background-color: rgba(173, 182, 186, 0.3);
-moz-box-shadow:
box-shadow:
inset rgba(0, 0, 0, 0.2) 0 -10px 12px;
padding: 9px 8px 8px 8px;
}
@ -255,4 +250,4 @@ src: url('chrome://testpilot/skin/fonts/DroidSans-Bold.ttf') format('truetype');
p.embiggened {
font-size: 14px;
}
}

View File

@ -53,7 +53,6 @@ body {
font-size: 16px;
padding: 6px 20px 20px 20px;
border-radius: 0.5em;
-webkit-border-radius: 0.5em;
background: rgba(220, 240, 247, 0.8) url('chrome://testpilot/skin/images/callout.png') no-repeat top center;
/* display: inline; */
}
@ -114,7 +113,6 @@ body {
padding: 8px 12px;
color: rgba(0, 0, 0, 0.8);
border-radius: 0.5em;
-webkit-border-radius: 0.5em;
box-shadow:
inset rgba(0, 0, 0, 0.2) 0 1px 1px,
inset rgba(255, 255, 255, 1) 0 3px 1px,
@ -133,7 +131,6 @@ body {
width: 240px;
color: rgba(0, 0, 0, 0.8);
border-radius: 0.5em;
-webkit-border-radius: 0.5em;
box-shadow:
inset rgba(0, 0, 0, 0.2) 0 1px 1px,
inset rgba(255, 255, 255, 1) 0 3px 1px,
@ -152,7 +149,6 @@ body {
margin: 24px auto;
color: rgba(0, 0, 0, 0.8);
border-radius: 0.5em;
-webkit-border-radius: 0.5em;
background: rgba(220, 240, 247, 0.8) url('chrome://testpilot/skin/images/callout.png') no-repeat top center;
box-shadow:
inset rgba(185, 221, 234, 0.2) 0 -10px 8.5px,
@ -174,7 +170,6 @@ body {
margin: 8px auto;
color: rgba(0, 0, 0, 0.8);
border-radius: 0.5em;
-webkit-border-radius: 0.5em;
background: rgba(220, 240, 247, 0.8) url('chrome://testpilot/skin/images/callout.png') no-repeat top center;
box-shadow:
inset rgba(185, 221, 234, 0.2) 0 -10px 8.5px,
@ -191,7 +186,6 @@ body {
margin: 8px auto;
color: rgba(0, 0, 0, 0.8);
border-radius: 0.5em;
-webkit-border-radius: 0.5em;
background: rgba(220, 240, 247, 0.8) url('chrome://testpilot/skin/images/callout_continue.png') no-repeat top center;
box-shadow:
inset rgba(185, 221, 234, 0.2) 0 -10px 8.5px,
@ -238,7 +232,6 @@ body {
width: 800px;
text-align: left;
border-radius: 0.25em;
-webkit-border-radius: 0.25em;
border-top: 1px solid #adb6ba;
border-left: 1px solid #adb6ba;
border-right: 1px solid #adb6ba;

View File

@ -759,12 +759,6 @@ pref("urlclassifier.gethashtables", "goog-phish-shavar,goog-malware-shavar");
// the database.
pref("urlclassifier.confirm-age", 2700);
// Maximum size of the sqlite3 cache during an update, in bytes
pref("urlclassifier.updatecachemax", 41943040);
// Maximum size of the sqlite3 cache for lookups, in bytes
pref("urlclassifier.lookupcachemax", 1048576);
// URL for checking the reason for a malware warning.
pref("browser.safebrowsing.malware.reportURL", "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");

View File

@ -165,24 +165,25 @@ var StarUI = {
return;
}
var loadObserver = {
_self: this,
_itemId: aItemId,
_anchorElement: aAnchorElement,
_position: aPosition,
observe: function (aSubject, aTopic, aData) {
this._overlayLoading = true;
document.loadOverlay(
"chrome://browser/content/places/editBookmarkOverlay.xul",
(function (aSubject, aTopic, aData) {
//XXX We just caused localstore.rdf to be re-applied (bug 640158)
retrieveToolbarIconsizesFromTheme();
this._self._overlayLoading = false;
this._self._overlayLoaded = true;
this._self._doShowEditBookmarkPanel(this._itemId, this._anchorElement,
this._position);
}
};
this._overlayLoading = true;
document.loadOverlay("chrome://browser/content/places/editBookmarkOverlay.xul",
loadObserver);
// Move the header (star, title, button) into the grid,
// so that it aligns nicely with the other items (bug 484022).
let header = this._element("editBookmarkPanelHeader");
let rows = this._element("editBookmarkPanelGrid").lastChild;
rows.insertBefore(header, rows.firstChild);
header.hidden = false;
this._overlayLoading = false;
this._overlayLoaded = true;
this._doShowEditBookmarkPanel(aItemId, aAnchorElement, aPosition);
}).bind(this)
);
},
_doShowEditBookmarkPanel:
@ -192,13 +193,6 @@ var StarUI = {
this._blockCommands(); // un-done in the popuphiding handler
// Move the header (star, title, possibly a button) into the grid,
// so that it aligns nicely with the other items (bug 484022).
var rows = this._element("editBookmarkPanelGrid").lastChild;
var header = this._element("editBookmarkPanelHeader");
rows.insertBefore(header, rows.firstChild);
header.hidden = false;
// Set panel title:
// if we are batching, i.e. the bookmark has been added now,
// then show Page Bookmarked, else if the bookmark did already exist,

View File

@ -3573,7 +3573,6 @@ const BrowserSearch = {
loadAddEngines: function BrowserSearch_loadAddEngines() {
var newWindowPref = gPrefService.getIntPref("browser.link.open_newwindow");
var where = newWindowPref == 3 ? "tab" : "window";
var regionBundle = document.getElementById("bundle_browser_region");
var searchEnginesURL = formatURL("browser.search.searchEnginesURL", true);
openUILinkIn(searchEnginesURL, where);
}
@ -4043,7 +4042,9 @@ var FullScreen = {
gBrowser.tabContainer.addEventListener("TabSelect", this.exitDomFullScreen);
// Exit DOM full-screen mode when the browser window loses focus (ALT+TAB, etc).
window.addEventListener("deactivate", this.exitDomFullScreen, true);
if (gPrefService.getBoolPref("full-screen-api.exit-on-deactivate")) {
window.addEventListener("deactivate", this.exitDomFullScreen, true);
}
// Cancel any "hide the toolbar" animation which is in progress, and make
// the toolbar hide immediately.

View File

@ -26,10 +26,8 @@ function test() {
// Now trigger the invalid URI test
executeSoon(function () {
info("Dialog closed? " + domwindow.closed + "\n");
let consoleListener = {
observe: function (m) {
info("m: " + m + "\n");
info("m.message: " + m.message + "\n");
if (m.message.indexOf("NS_ERROR_DOM_BAD_URI") > -1) {
ok(true, "drop was blocked");
@ -42,18 +40,27 @@ function test() {
Services.console.unregisterListener(consoleListener);
});
// The drop handler throws an exception when dragging URIs that inherit
// principal, e.g. javascript:
expectUncaughtException();
let originalHandler = homeButtonObserver.onDrop;
homeButtonObserver.onDrop = function (aEvent) {
info("homeButtonObserver.onDrop called");
originalHandler(aEvent);
};
registerCleanupFunction(function () {
homeButtonObserver.onDrop = originalHandler;
executeSoon(function () {
info("Attempting second drop, of a javascript: URI");
// The drop handler throws an exception when dragging URIs that inherit
// principal, e.g. javascript:
expectUncaughtException();
let originalHandler = homeButtonObserver.onDrop;
homeButtonObserver.onDrop = function (aEvent) {
info("homeButtonObserver.onDrop called");
try {
originalHandler(aEvent);
} catch (ex) {
info("originalHandler threw an exception: " + ex);
throw ex;
}
};
registerCleanupFunction(function () {
homeButtonObserver.onDrop = originalHandler;
});
chromeUtils.synthesizeDrop(homeButton, homeButton, [[{type: "text/plain", data: "javascript:8888"}]], "copy", window, EventUtils);
info("Triggered the second drop of a javascript: URI");
});
chromeUtils.synthesizeDrop(homeButton, homeButton, [[{type: "text/plain", data: "javascript:8888"}]], "copy", window, EventUtils);
})
});

View File

@ -403,7 +403,8 @@ function getShellService()
try {
shell = Components.classes["@mozilla.org/browser/shell-service;1"]
.getService(Components.interfaces.nsIShellService);
} catch (e) {dump("*** e = " + e + "\n");}
} catch (e) {
}
return shell;
}

View File

@ -224,7 +224,6 @@ FirefoxProfileMigrator.prototype = {
migrate : function Firefox_migrate(aItems, aStartup, aProfile)
{
if (aStartup) {
aStartup.doStartup();
this._replaceBookmarks = true;
}
@ -246,6 +245,11 @@ FirefoxProfileMigrator.prototype = {
if (aItems & MIGRATOR.PASSWORDS)
this._migratePasswords();
// The password manager encryption key must be copied before startup.
if (aStartup) {
aStartup.doStartup();
}
if (aItems & MIGRATOR.FORMDATA)
this._migrateFormData();

View File

@ -153,6 +153,7 @@ var gEngineManagerDialog = {
while (Services.prompt.prompt(window, title, msg, alias, null, {})) {
var bduplicate = false;
var eduplicate = false;
var dupName = "";
if (alias.value != "") {
try {
@ -168,6 +169,7 @@ var gEngineManagerDialog = {
if (engine.alias == alias.value &&
engine.name != selectedEngine.name) {
eduplicate = true;
dupName = engine.name;
break;
}
}
@ -177,8 +179,7 @@ var gEngineManagerDialog = {
if (eduplicate || bduplicate) {
var dtitle = strings.getString("duplicateTitle");
var bmsg = strings.getString("duplicateBookmarkMsg");
var emsg = strings.getFormattedString("duplicateEngineMsg",
[engine.name]);
var emsg = strings.getFormattedString("duplicateEngineMsg", [dupName]);
Services.prompt.alert(window, dtitle, eduplicate ? emsg : bmsg);
} else {

View File

@ -50,9 +50,9 @@
]>
<bindings id="SearchBindings"
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
xmlns="http://www.mozilla.org/xbl"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="searchbar">
<resources>
@ -96,13 +96,12 @@
<xul:image class="search-go-button"
anonid="search-go-button"
onclick="handleSearchCommand(event);"
tooltiptext="&searchEndCap.label;" />
tooltiptext="&searchEndCap.label;"/>
</xul:hbox>
</xul:textbox>
</content>
<implementation implements="nsIObserver">
<constructor><![CDATA[
if (this.parentNode.parentNode.localName == "toolbarpaletteitem")
return;
@ -164,7 +163,7 @@
<getter><![CDATA[
var currentEngine = this.searchService.currentEngine;
// Return a dummy engine if there is no currentEngine
return currentEngine || {name:"", uri:null};
return currentEngine || {name: "", uri: null};
]]></getter>
</property>
@ -335,7 +334,8 @@
// indexes as items are removed.
var items = popup.childNodes;
for (var i = items.length - 1; i >= 0; i--) {
if (items[i].getAttribute("class").indexOf("addengine") != -1)
if (items[i].classList.contains("addengine-item") ||
items[i].classList.contains("addengine-separator"))
popup.removeChild(items[i]);
}
@ -444,7 +444,7 @@
<body><![CDATA[
// Find the new index
var newIndex = this.engines.indexOf(this.currentEngine);
newIndex += (isNextEngine) ? 1 : -1;
newIndex += isNextEngine ? 1 : -1;
if (newIndex >= 0 && newIndex < this.engines.length)
this.currentEngine = this.engines[newIndex];
@ -495,13 +495,12 @@
openUILinkIn(submission.uri.spec, aWhere, null, submission.postData);
]]></body>
</method>
</implementation>
<handlers>
<handler event="command"><![CDATA[
const target = event.originalTarget;
if (target.getAttribute("class").indexOf("addengine-item") != -1) {
if (target.classList.contains("addengine-item")) {
var searchService =
Components.classes["@mozilla.org/browser/search-service;1"]
.getService(Components.interfaces.nsIBrowserSearchService);
@ -719,7 +718,7 @@
</body>
</method>
<!-- overload |onTextEntered| in autocomplete.xml -->
<!-- override |onTextEntered| in autocomplete.xml -->
<method name="onTextEntered">
<parameter name="aEvent"/>
<body><![CDATA[

View File

@ -35,7 +35,7 @@
* ***** END LICENSE BLOCK ***** */
function test() {
let tab1 = gBrowser.addTab("about:robots");
let tab1 = gBrowser.addTab("about:rights");
let tab2 = gBrowser.addTab("about:mozilla");
tab1.linkedBrowser.addEventListener("load", mainPart, true);
waitForExplicitFinish();
@ -44,7 +44,7 @@ function test() {
tab1.linkedBrowser.removeEventListener("load", mainPart, true);
// Tell the session storer that the tab is pinned
let newTabState = '{"entries":[{"url":"about:robots"}],"pinned":true,"userTypedValue":"Hello World!"}';
let newTabState = '{"entries":[{"url":"about:rights"}],"pinned":true,"userTypedValue":"Hello World!"}';
ss.setTabState(tab1, newTabState);
// Undo pinning

View File

@ -4,7 +4,7 @@
function test() {
let state = { windows: [{ tabs: [
{entries: [{url: "about:mozilla"}], hidden: true},
{entries: [{url: "about:robots"}], hidden: true}
{entries: [{url: "about:rights"}], hidden: true}
] }] };
waitForExplicitFinish();

View File

@ -252,7 +252,7 @@ function onWindowUnloaded() {
let previousClosedWindowData = ss.getClosedWindowData();
// Now we want to open a new window
let newWin = openDialog(location, "_blank", "chrome,all,dialog=no", "about:robots");
let newWin = openDialog(location, "_blank", "chrome,all,dialog=no", "about:mozilla");
newWin.addEventListener("load", function(aEvent) {
newWin.removeEventListener("load", arguments.callee, false);

View File

@ -5,7 +5,7 @@ function test() {
let oldState = {
windows: [{
tabs: [
{ entries: [{ url: "about:robots" }], hidden: true },
{ entries: [{ url: "about:mozilla" }], hidden: true },
{ entries: [{ url: "about:blank" }], hidden: false }
]
}]

View File

@ -40,7 +40,7 @@ const testState = {
windows: [{
tabs: [
{ entries: [{ url: "about:blank" }] },
{ entries: [{ url: "about:robots" }] }
{ entries: [{ url: "about:rights" }] }
]
}]
};
@ -174,7 +174,7 @@ function test_duplicateTab() {
is(busyEventCount, 1);
is(readyEventCount, 1);
is(ss.getTabValue(newTab, "baz"), "qux");
is(newTab.linkedBrowser.currentURI.spec, "about:robots");
is(newTab.linkedBrowser.currentURI.spec, "about:rights");
window.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
window.removeEventListener("SSWindowStateReady", onSSWindowStateReady, false);
@ -215,7 +215,7 @@ function test_undoCloseTab() {
is(busyEventCount, 1);
is(readyEventCount, 1);
is(ss.getTabValue(reopenedTab, "baz"), "qux");
is(reopenedTab.linkedBrowser.currentURI.spec, "about:robots");
is(reopenedTab.linkedBrowser.currentURI.spec, "about:rights");
window.removeEventListener("SSWindowStateBusy", onSSWindowStateBusy, false);
window.removeEventListener("SSWindowStateReady", onSSWindowStateReady, false);

View File

@ -40,7 +40,7 @@ const testState = {
windows: [{
tabs: [
{ entries: [{ url: "about:blank" }] },
{ entries: [{ url: "about:robots" }] }
{ entries: [{ url: "about:mozilla" }] }
]
}]
};

View File

@ -28,7 +28,7 @@ function test() {
// Open a new window, which should trigger a save event soon.
waitForSaveState(onSaveState);
newWin = openDialog(location, "_blank", "chrome,all,dialog=no", "about:robots");
newWin = openDialog(location, "_blank", "chrome,all,dialog=no", "about:rights");
}
function onSaveState() {

View File

@ -20,7 +20,7 @@ function test() {
assertNumberOfTabs(1, "we start off with one tab");
// setup
let tab = gBrowser.addTab("about:robots");
let tab = gBrowser.addTab("about:mozilla");
whenTabIsLoaded(tab, function () {
// hide the newly created tab
@ -35,7 +35,7 @@ function test() {
// check that everything was restored correctly, clean up and finish
whenTabIsLoaded(tab, function () {
is(tab.linkedBrowser.currentURI.spec, "about:robots", "restored tab has correct url");
is(tab.linkedBrowser.currentURI.spec, "about:mozilla", "restored tab has correct url");
gBrowser.removeTab(tab);
finish();

View File

@ -11,7 +11,6 @@ function test() {
let brokenState = {
windows: [
{ tabs: [{ entries: [{ url: "about:mozilla" }] }] }
//{ tabs: [{ entries: [{ url: "about:robots" }] }] },
],
selectedWindow: 2
};
@ -32,4 +31,3 @@ function test() {
let blankState = { windows: [{ tabs: [{ entries: [{ url: "about:blank" }] }]}]};
waitForBrowserState(blankState, finish);
}

View File

@ -336,7 +336,6 @@ nsWindowsShellService::ShortcutMaintenance()
bool
nsWindowsShellService::IsDefaultBrowserVista(bool* aIsDefaultBrowser)
{
#if MOZ_WINSDK_TARGETVER >= MOZ_NTDDI_LONGHORN
IApplicationAssociationRegistration* pAAR;
HRESULT hr = CoCreateInstance(CLSID_ApplicationAssociationRegistration,
@ -355,7 +354,6 @@ nsWindowsShellService::IsDefaultBrowserVista(bool* aIsDefaultBrowser)
pAAR->Release();
return true;
}
#endif
return false;
}

View File

@ -164,6 +164,7 @@
@BINPATH@/components/dom_indexeddb.xpt
@BINPATH@/components/dom_offline.xpt
@BINPATH@/components/dom_json.xpt
@BINPATH@/components/dom_power.xpt
@BINPATH@/components/dom_range.xpt
@BINPATH@/components/dom_sidebar.xpt
@BINPATH@/components/dom_sms.xpt
@ -379,6 +380,8 @@
#ifdef MOZ_B2G_RIL
@BINPATH@/components/RadioInterfaceLayer.manifest
@BINPATH@/components/RadioInterfaceLayer.js
@BINPATH@/components/SmsDatabaseService.manifest
@BINPATH@/components/SmsDatabaseService.js
@BINPATH@/components/nsWifiWorker.js
@BINPATH@/components/nsWifiWorker.manifest
#endif

View File

@ -169,11 +169,11 @@ libs:: $(addsuffix .xml,$(SEARCH_PLUGINS))
done
install:: $(addsuffix .xml,$(SEARCH_PLUGINS))
$(NSINSTALL) -D $(DESTDIR)$mozappdir/searchplugins
$(NSINSTALL) -D $(DESTDIR)$(mozappdir)/searchplugins
for i in $^; do \
SEARCH_PLUGIN_BASE=`basename $$SEARCH_PLUGIN`;\
$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) \
$$SEARCH_PLUGIN > $(DESTDIR)$mozappdir/searchplugins/$$SEARCH_PLUGIN_BASE; \
$$SEARCH_PLUGIN > $(DESTDIR)$(mozappdir)/searchplugins/$$SEARCH_PLUGIN_BASE; \
done

View File

@ -75,13 +75,13 @@ OrganizerQueryAllBookmarks=All Bookmarks
OrganizerQueryTags=Tags
# LOCALIZATION NOTE (tagResultLabel) :
# This is what we use to form the label (for screen readers)
# for url bar autocomplete results of type "tag"
# Noun used to describe the location bar autocomplete result type
# to users with screen readers
# See createResultLabel() in urlbarBindings.xml
tagResultLabel=Tag
# LOCALIZATION NOTE (bookmarkResultLabel) :
# This is what we use to form the label (for screen readers)
# for url bar autocomplete results of type "bookmark"
# Noun used to describe the location bar autocomplete result type
# to users with screen readers
# See createResultLabel() in urlbarBindings.xml
bookmarkResultLabel=Bookmark

View File

@ -282,5 +282,5 @@
.styleinspector-propertyeditor {
border: 1px solid #CCC;
padding: 0;
-moz-box-shadow: 2px 2px 2px #CCC;
box-shadow: 2px 2px 2px #CCC;
}

View File

@ -284,5 +284,5 @@
.styleinspector-propertyeditor {
border: 1px solid #CCC;
padding: 0;
-moz-box-shadow: 2px 2px 2px #CCC;
box-shadow: 2px 2px 2px #CCC;
}

View File

@ -282,5 +282,5 @@
.styleinspector-propertyeditor {
border: 1px solid #CCC;
padding: 0;
-moz-box-shadow: 2px 2px 2px #CCC;
box-shadow: 2px 2px 2px #CCC;
}

View File

@ -61,7 +61,6 @@ class DMError(Exception):
def __str__(self):
return self.msg
def abstractmethod(method):
line = method.func_code.co_firstlineno
filename = method.func_code.co_filename
@ -70,9 +69,18 @@ def abstractmethod(method):
'should be implemented by a concrete class' %
(repr(method), filename,line))
return not_implemented
class DeviceManager:
@abstractmethod
def shell(self, cmd, outputfile, env=None, cwd=None):
"""
executes shell command on device
returns:
success: Return code from command
failure: None
"""
@abstractmethod
def pushFile(self, localname, destname):
"""
@ -168,25 +176,27 @@ class DeviceManager:
success: array of process tuples
failure: None
"""
@abstractmethod
def fireProcess(self, appname, failIfRunning=False):
"""
external function
DEPRECATED: Use shell() or launchApplication() for new code
returns:
success: pid
failure: None
"""
@abstractmethod
def launchProcess(self, cmd, outputFile = "process.txt", cwd = '', env = '', failIfRunning=False):
"""
external function
DEPRECATED: Use shell() or launchApplication() for new code
returns:
success: output filename
failure: None
"""
def communicate(self, process, timeout = 600, interval = 5):
"""
loops until 'process' has exited or 'timeout' seconds is reached
@ -581,3 +591,35 @@ class NetworkTools:
print "Socket error trying to find open port"
return seed
def _pop_last_line(file):
'''
Utility function to get the last line from a file (shared between ADB and
SUT device managers). Function also removes it from the file. Intended to
strip off the return code from a shell command.
'''
bytes_from_end = 1
file.seek(0, 2)
length = file.tell() + 1
while bytes_from_end <= length:
file.seek((-1)*bytes_from_end, 2)
data = file.read()
if bytes_from_end == length and len(data) == 0: # no data, return None
return None
if data[0] == '\n' or bytes_from_end == length:
# found the last line, which should have the return value
if data[0] == '\n':
data = data[1:]
# truncate off the return code line
file.truncate(length - bytes_from_end)
file.seek(0,2)
file.write('\0')
return data
bytes_from_end += 1
return None

View File

@ -1,5 +1,5 @@
import subprocess
from devicemanager import DeviceManager, DMError
from devicemanager import DeviceManager, DMError, _pop_last_line
import re
import os
import sys
@ -63,6 +63,47 @@ class DeviceManagerADB(DeviceManager):
else:
print "restarting as root failed"
# external function: executes shell command on device
# returns:
# success: <return code>
# failure: None
def shell(self, cmd, outputfile, env=None, cwd=None):
# need to quote special characters here
for (index, arg) in enumerate(cmd):
if arg.find(" ") or arg.find("(") or arg.find(")") or arg.find("\""):
cmd[index] = '\'%s\'' % arg
# This is more complex than you'd think because adb doesn't actually
# return the return code from a process, so we have to capture the output
# to get it
# FIXME: this function buffers all output of the command into memory,
# always. :(
cmdline = subprocess.list2cmdline(cmd) + "; echo $?"
# prepend cwd and env to command if necessary
if cwd:
cmdline = "cd %s; %s" % (cwd, cmdline)
if env:
envstr = '; '.join(map(lambda x: 'export %s=%s' % (x[0], x[1]), env.iteritems()))
cmdline = envstr + "; " + cmdline
# all output should be in stdout
proc = subprocess.Popen(["adb", "shell", cmdline],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdout, stderr) = proc.communicate()
outputfile.write(stdout.rstrip('\n'))
lastline = _pop_last_line(outputfile)
if lastline:
m = re.search('([0-9]+)', lastline)
if m:
return_code = m.group(1)
outputfile.seek(-2, 2)
outputfile.truncate() # truncate off the return code
return return_code
return None
# external function
# returns:
# success: True
@ -264,6 +305,7 @@ class DeviceManagerADB(DeviceManager):
return ret
# external function
# DEPRECATED: Use shell() or launchApplication() for new code
# returns:
# success: pid
# failure: None
@ -275,6 +317,7 @@ class DeviceManagerADB(DeviceManager):
return self.launchProcess(parts, failIfRunning)
# external function
# DEPRECATED: Use shell() or launchApplication() for new code
# returns:
# success: output filename
# failure: None
@ -327,6 +370,7 @@ class DeviceManagerADB(DeviceManager):
if name == appname:
p = self.runCmdAs(["shell", "kill", pid])
return p.stdout.read()
return None
# external function
@ -611,7 +655,7 @@ class DeviceManagerADB(DeviceManager):
args.insert(1, "run-as")
args.insert(2, self.packageName)
args.insert(0, "adb")
return subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
return subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
def runCmdAs(self, args):
if self.useRunAs:

View File

@ -47,7 +47,18 @@ import subprocess
from threading import Thread
import traceback
import sys
from devicemanager import DeviceManager, DMError, FileError, NetworkTools
import StringIO
from devicemanager import DeviceManager, DMError, FileError, NetworkTools, _pop_last_line
class AgentError(Exception):
"SUTAgent-specific exception."
def __init__(self, msg= '', fatal = False):
self.msg = msg
self.fatal = fatal
def __str__(self):
return self.msg
class DeviceManagerSUT(DeviceManager):
host = ''
@ -76,7 +87,7 @@ class DeviceManagerSUT(DeviceManager):
self._sock = None
self.getDeviceRoot()
def cmdNeedsResponse(self, cmd):
def _cmdNeedsResponse(self, cmd):
""" Not all commands need a response from the agent:
* if the cmd matches the pushRE then it is the first half of push
and therefore we want to wait until the second half before looking
@ -93,18 +104,44 @@ class DeviceManagerSUT(DeviceManager):
for c in noResponseCmds:
if (c.match(cmd)):
return False
# If the command is not in our list, then it gets a response
return True
def shouldCmdCloseSocket(self, cmd):
def _stripPrompt(self, data):
'''
internal function
take a data blob and strip instances of the prompt '$>\x00'
'''
promptre = re.compile(self.prompt_regex + '.*')
retVal = []
lines = data.split('\n')
for line in lines:
foundPrompt = False
try:
while (promptre.match(line)):
foundPrompt = True
pieces = line.split(self.prompt_sep)
index = pieces.index('$>')
pieces.pop(index)
line = self.prompt_sep.join(pieces)
except(ValueError):
pass
# we don't want to append lines that are blank after stripping the
# prompt (those are basically "prompts")
if not foundPrompt or line:
retVal.append(line)
return '\n'.join(retVal)
def _shouldCmdCloseSocket(self, cmd):
""" Some commands need to close the socket after they are sent:
* push
* rebt
* uninst
* quit
"""
socketClosingCmds = [re.compile('^push .*$'),
re.compile('^quit.*'),
re.compile('^rebt.*'),
@ -116,85 +153,86 @@ class DeviceManagerSUT(DeviceManager):
return False
# convenience function to enable checks for agent errors
def verifySendCMD(self, cmdline, newline = True):
return self.sendCMD(cmdline, newline, False)
#
# create a wrapper for sendCMD that loops up to self.retrylimit iterations.
# this allows us to move the retry logic outside of the _doCMD() to make it
# easier for debugging in the future.
# note that since cmdline is a list of commands, they will all be retried if
# one fails. this is necessary in particular for pushFile(), where we don't want
# to accidentally send extra data if a failure occurs during data transmission.
#
def sendCMD(self, cmdline, newline = True, ignoreAgentErrors = True):
def sendCmds(self, cmdlist, outputfile, timeout = None, newline = True):
'''
a wrapper for _doCmds that loops up to self.retrylimit iterations.
this allows us to move the retry logic outside of the _doCmds() to make it
easier for debugging in the future.
note that since cmdlist is a list of commands, they will all be retried if
one fails. this is necessary in particular for pushFile(), where we don't want
to accidentally send extra data if a failure occurs during data transmission.
'''
done = False
while (not done):
retVal = self._doCMD(cmdline, newline)
if (retVal is None):
while self.retries < self.retrylimit:
try:
self._doCmds(cmdlist, outputfile, timeout, newline)
return
except AgentError, err:
# re-raise error if it's fatal (i.e. the device got the command but
# couldn't execute it). retry otherwise
if err.fatal:
raise err
if self.debug >= 2:
print err
self.retries += 1
else:
self.retries = 0
if ignoreAgentErrors == False:
if (self.agentErrorRE.match(retVal)):
raise DMError("error on the agent executing '%s'" % cmdline)
return retVal
if (self.retries >= self.retrylimit):
done = True
raise AgentError("unable to connect to %s after %s attempts" % (self.host, self.retrylimit))
raise DMError("unable to connect to %s after %s attempts" % (self.host, self.retrylimit))
def runCmds(self, cmdlist, timeout = None, newline = True):
'''
similar to sendCmds, but just returns any output as a string instead of
writing to a file. this is normally what you want to call to send a set
of commands to the agent
'''
outputfile = StringIO.StringIO()
self.sendCmds(cmdlist, outputfile, timeout, newline)
outputfile.seek(0)
return outputfile.read()
def _doCMD(self, cmdline, newline = True):
def _doCmds(self, cmdlist, outputfile, timeout, newline):
promptre = re.compile(self.prompt_regex + '$')
data = ""
shouldCloseSocket = False
recvGuard = 1000
if (self._sock == None):
if not self._sock:
try:
if (self.debug >= 1):
if self.debug >= 1:
print "reconnecting socket"
self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except:
self._sock = None
if (self.debug >= 2):
print "unable to create socket"
return None
raise AgentError("unable to create socket")
try:
self._sock.connect((self.host, int(self.port)))
self._sock.recv(1024)
except:
self._sock.close()
self._sock = None
if (self.debug >= 2):
print "unable to connect socket"
return None
for cmd in cmdline:
raise AgentError("unable to connect socket")
for cmd in cmdlist:
if newline: cmd += '\r\n'
try:
numbytes = self._sock.send(cmd)
if (numbytes != len(cmd)):
print "ERROR: our cmd was " + str(len(cmd)) + " bytes and we only sent " + str(numbytes)
return None
raise AgentError("ERROR: our cmd was %s bytes and we only sent %s" % (len(cmd),
numbytes))
if (self.debug >= 4): print "send cmd: " + str(cmd)
except:
self._sock.close()
self._sock = None
return None
return False
# Check if the command should close the socket
shouldCloseSocket = self.shouldCmdCloseSocket(cmd)
shouldCloseSocket = self._shouldCmdCloseSocket(cmd)
# Handle responses from commands
if (self.cmdNeedsResponse(cmd)):
if (self._cmdNeedsResponse(cmd)):
found = False
loopguard = 0
data = ""
while (found == False and (loopguard < recvGuard)):
temp = ''
@ -207,14 +245,14 @@ class DeviceManagerSUT(DeviceManager):
except:
self._sock.close()
self._sock = None
return None
raise AgentError("Error receiving data from socket")
data += temp
# If something goes wrong in the agent it will send back a string that
# starts with '##AGENT-ERROR##'
if self.agentErrorRE.match(data):
break
raise AgentError("Agent Error processing command: %s" % cmd, fatal=True)
for line in data.splitlines():
if promptre.match(line):
@ -222,40 +260,54 @@ class DeviceManagerSUT(DeviceManager):
data = self._stripPrompt(data)
break
# periodically flush data to output file to make sure it doesn't get
# too big/unwieldly
if len(data) > 1024:
outputfile.write(data[0:1024])
data = data[1024:]
# If we violently lose the connection to the device, this loop tends to spin,
# this guard prevents that
if (temp == ''):
loopguard += 1
if (shouldCloseSocket == True):
# Write any remaining data to outputfile
outputfile.write(data)
if shouldCloseSocket:
try:
self._sock.close()
self._sock = None
except:
self._sock = None
return None
raise AgentError("Error closing socket")
return data
# internal function
# take a data blob and strip instances of the prompt '$>\x00'
def _stripPrompt(self, data):
promptre = re.compile(self.prompt_regex + '.*')
retVal = []
lines = data.split('\n')
for line in lines:
try:
while (promptre.match(line)):
pieces = line.split(self.prompt_sep)
index = pieces.index('$>')
pieces.pop(index)
line = self.prompt_sep.join(pieces)
except(ValueError):
pass
retVal.append(line)
# external function: executes shell command on device
# returns:
# success: <return code>
# failure: None
def shell(self, cmd, outputfile, env=None, cwd=None):
cmdline = subprocess.list2cmdline(cmd)
if env:
cmdline = '%s %s' % (self.formatEnvString(env), cmdline)
return '\n'.join(retVal)
try:
if cwd:
self.sendCmds(['execcwd %s %s' % (cwd, cmdline)], outputfile)
else:
self.sendCmds(['exec %s' % cmdline], outputfile)
except AgentError:
return None
# dig through the output to get the return code
lastline = _pop_last_line(outputfile)
if lastline:
m = re.search('return code \[([0-9]+)\]', lastline)
if m:
return m.group(1)
# woops, we couldn't find an end of line/return value
return None
# external function
# returns:
@ -286,8 +338,8 @@ class DeviceManagerSUT(DeviceManager):
f.close()
try:
retVal = self.verifySendCMD(['push ' + destname + ' ' + str(filesize) + '\r\n', data], newline = False)
except(DMError):
retVal = self.runCmds(['push ' + destname + ' ' + str(filesize) + '\r\n', data], newline = False)
except AgentError:
retVal = False
if (self.debug >= 3): print "push returned: " + str(retVal)
@ -323,8 +375,8 @@ class DeviceManagerSUT(DeviceManager):
return name
else:
try:
retVal = self.verifySendCMD(['mkdr ' + name])
except(DMError):
retVal = self.runCmds(['mkdr ' + name])
except AgentError:
retVal = None
return retVal
@ -376,8 +428,8 @@ class DeviceManagerSUT(DeviceManager):
match = ".*" + dirname + "$"
dirre = re.compile(match)
try:
data = self.verifySendCMD(['cd ' + dirname, 'cwd'])
except(DMError):
data = self.runCmds(['cd ' + dirname, 'cwd'])
except AgentError:
return False
found = False
@ -412,8 +464,8 @@ class DeviceManagerSUT(DeviceManager):
if (self.dirExists(rootdir) == False):
return []
try:
data = self.verifySendCMD(['cd ' + rootdir, 'ls'])
except(DMError):
data = self.runCmds(['cd ' + rootdir, 'ls'])
except AgentError:
return []
files = filter(lambda x: x, data.splitlines())
@ -429,8 +481,8 @@ class DeviceManagerSUT(DeviceManager):
def removeFile(self, filename):
if (self.debug>= 2): print "removing file: " + filename
try:
retVal = self.verifySendCMD(['rm ' + filename])
except(DMError):
retVal = self.runCmds(['rm ' + filename])
except AgentError:
return None
return retVal
@ -442,8 +494,8 @@ class DeviceManagerSUT(DeviceManager):
# failure: None
def removeDir(self, remoteDir):
try:
retVal = self.verifySendCMD(['rmdr ' + remoteDir])
except(DMError):
retVal = self.runCmds(['rmdr ' + remoteDir])
except AgentError:
return None
return retVal
@ -454,8 +506,8 @@ class DeviceManagerSUT(DeviceManager):
# failure: []
def getProcessList(self):
try:
data = self.verifySendCMD(['ps'])
except DMError:
data = self.runCmds(['ps'])
except AgentError:
return []
files = []
@ -470,6 +522,7 @@ class DeviceManagerSUT(DeviceManager):
return files
# external function
# DEPRECATED: Use shell() or launchApplication() for new code
# returns:
# success: pid
# failure: None
@ -486,8 +539,8 @@ class DeviceManagerSUT(DeviceManager):
return None
try:
data = self.verifySendCMD(['exec ' + appname])
except(DMError):
data = self.runCmds(['exec ' + appname])
except AgentError:
return None
# wait up to 30 seconds for process to start up
@ -503,6 +556,7 @@ class DeviceManagerSUT(DeviceManager):
return process
# external function
# DEPRECATED: Use shell() or launchApplication() for new code
# returns:
# success: output filename
# failure: None
@ -532,8 +586,8 @@ class DeviceManagerSUT(DeviceManager):
# failure: None
def killProcess(self, appname):
try:
data = self.verifySendCMD(['kill ' + appname])
except(DMError):
data = self.runCmds(['kill ' + appname])
except AgentError:
return None
return data
@ -544,8 +598,8 @@ class DeviceManagerSUT(DeviceManager):
# failure: None
def getTempDir(self):
try:
data = self.verifySendCMD(['tmpd'])
except(DMError):
data = self.runCmds(['tmpd'])
except AgentError:
return None
return data.strip()
@ -556,12 +610,12 @@ class DeviceManagerSUT(DeviceManager):
# failure: None
def catFile(self, remoteFile):
try:
data = self.verifySendCMD(['cat ' + remoteFile])
except(DMError):
data = self.runCmds(['cat ' + remoteFile])
except AgentError:
return None
return data
# external function
# returns:
# success: output of pullfile, string
@ -625,8 +679,8 @@ class DeviceManagerSUT(DeviceManager):
# or, if error,
# <filename>,-1\n<error message>
try:
data = self.verifySendCMD(['pull ' + remoteFile])
except(DMError):
data = self.runCmds(['pull ' + remoteFile])
except AgentError:
return None
# read metadata; buffer the rest
@ -744,8 +798,8 @@ class DeviceManagerSUT(DeviceManager):
# Throws a FileError exception when null (invalid dir/filename)
def isDir(self, remotePath):
try:
data = self.verifySendCMD(['isdir ' + remotePath])
except(DMError):
data = self.runCmds(['isdir ' + remotePath])
except AgentError:
# normally there should be no error here; a nonexistent file/directory will
# return the string "<filename>: No such file or directory".
# However, I've seen AGENT-WARNING returned before.
@ -780,8 +834,8 @@ class DeviceManagerSUT(DeviceManager):
# failure: None
def getRemoteHash(self, filename):
try:
data = self.verifySendCMD(['hash ' + filename])
except(DMError):
data = self.runCmds(['hash ' + filename])
except AgentError:
return None
retVal = None
@ -809,7 +863,7 @@ class DeviceManagerSUT(DeviceManager):
# failure: None
def getDeviceRoot(self):
try:
data = self.verifySendCMD(['testroot'])
data = self.runCmds(['testroot'])
except:
return None
@ -823,7 +877,7 @@ class DeviceManagerSUT(DeviceManager):
def getAppRoot(self, packageName):
try:
data = self.verifySendCMD(['getapproot '+packageName])
data = self.runCmds(['getapproot '+packageName])
except:
return None
@ -851,8 +905,8 @@ class DeviceManagerSUT(DeviceManager):
return None
try:
data = self.verifySendCMD(['cd ' + dir, 'unzp ' + filename])
except(DMError):
data = self.runCmds(['cd ' + dir, 'unzp ' + filename])
except AgentError:
return None
return data
@ -872,8 +926,8 @@ class DeviceManagerSUT(DeviceManager):
try:
destname = '/data/data/com.mozilla.SUTAgentAndroid/files/update.info'
data = "%s,%s\rrebooting\r" % (ipAddr, port)
self.verifySendCMD(['push ' + destname + ' ' + str(len(data)) + '\r\n', data], newline = False)
except(DMError):
self.runCmds(['push ' + destname + ' ' + str(len(data)) + '\r\n', data], newline = False)
except AgentError:
return None
ip, port = self.getCallbackIpAndPort(ipAddr, port)
@ -882,8 +936,8 @@ class DeviceManagerSUT(DeviceManager):
callbacksvr = callbackServer(ip, port, self.debug)
try:
status = self.verifySendCMD([cmd])
except(DMError):
status = self.runCmds([cmd])
except AgentError:
return None
if (ipAddr is not None):
@ -918,7 +972,7 @@ class DeviceManagerSUT(DeviceManager):
directives = [directive]
for d in directives:
data = self.verifySendCMD(['info ' + d])
data = self.runCmds(['info ' + d])
if (data is None):
continue
data = collapseSpaces.sub(' ', data)
@ -955,8 +1009,8 @@ class DeviceManagerSUT(DeviceManager):
if destPath:
cmd += ' ' + destPath
try:
data = self.verifySendCMD([cmd])
except(DMError):
data = self.runCmds([cmd])
except AgentError:
return None
f = re.compile('Failure')
@ -981,8 +1035,8 @@ class DeviceManagerSUT(DeviceManager):
if installPath:
cmd += ' ' + installPath
try:
data = self.verifySendCMD([cmd])
except(DMError):
data = self.runCmds([cmd])
except AgentError:
return None
if (self.debug > 3): print "uninstallAppAndReboot: " + str(data)
@ -1026,8 +1080,8 @@ class DeviceManagerSUT(DeviceManager):
if (self.debug >= 3): print "INFO: updateApp using command: " + str(cmd)
try:
status = self.verifySendCMD([cmd])
except(DMError):
status = self.runCmds([cmd])
except AgentError:
return None
if ipAddr is not None:
@ -1046,8 +1100,8 @@ class DeviceManagerSUT(DeviceManager):
# failure: None
def getCurrentTime(self):
try:
data = self.verifySendCMD(['clok'])
except(DMError):
data = self.runCmds(['clok'])
except AgentError:
return None
return data.strip()
@ -1079,8 +1133,8 @@ class DeviceManagerSUT(DeviceManager):
return None
try:
data = self.verifySendCMD(['cd ' + dir, 'unzp ' + filename])
except(DMError):
data = self.runCmds(['cd ' + dir, 'unzp ' + filename])
except AgentError:
return None
return data
@ -1150,9 +1204,9 @@ class DeviceManagerSUT(DeviceManager):
if (self.debug >= 3): print "INFO: adjusting screen resolution to %s, %s and rebooting" % (width, height)
try:
self.verifySendCMD(["exec setprop persist.tegra.dpy%s.mode.width %s" % (screentype, width)])
self.verifySendCMD(["exec setprop persist.tegra.dpy%s.mode.height %s" % (screentype, height)])
except(DMError):
self.runCmds(["exec setprop persist.tegra.dpy%s.mode.width %s" % (screentype, width)])
self.runCmds(["exec setprop persist.tegra.dpy%s.mode.height %s" % (screentype, height)])
except AgentError:
return False
return True

87
build/mobile/droid.py Normal file
View File

@ -0,0 +1,87 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is Test Automation Framework.
#
# The Initial Developer of the Original Code is
# Mozilla foundation
#
# Portions created by the Initial Developer are Copyright (C) 2009
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Joel Maher <joel.maher@gmail.com> (Original Developer)
# William Lachance <wlachance@mozilla.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
from devicemanagerADB import DeviceManagerADB
from devicemanagerSUT import DeviceManagerSUT
class DroidMixin(object):
"""Mixin to extend DeviceManager with Android-specific functionality"""
def launchApplication(self, app, activity="App",
intent="android.intent.action.VIEW", env=None,
url=None, extra_args=None):
"""
Launches an Android application
returns:
success: True
failure: False
"""
# only one instance of an application may be running at once
if self.processExist(app):
return False
acmd = [ "am", "start", "-a", intent, "-W", "-n", "%s/.%s" % (app, activity)]
if extra_args:
acmd.extend(["--es", "args", " ".join(args)])
if env:
envCnt = 0
# env is expected to be a dict of environment variables
for envkey, envval in env.iteritems():
acmd.extend(["--es", "env" + str(envCnt), envkey + "=" + envval])
envCnt += 1
if url:
acmd.extend(["-d", ''.join(['"', url, '"'])])
# shell output not that interesting and debugging logs should already
# show what's going on here... so just create an empty memory buffer
# and ignore
shellOutput = StringIO.StringIO()
if self.shell(acmd, shellOutput) == 0:
return True
return False
class DroidADB(DeviceManagerADB, DroidMixin):
pass
class DroidSUT(DeviceManagerSUT, DroidMixin):
pass

View File

@ -136,12 +136,13 @@ public class DoCommand {
String ffxProvider = "org.mozilla.ffxcp";
String fenProvider = "org.mozilla.fencp";
private final String prgVersion = "SUTAgentAndroid Version 1.05";
private final String prgVersion = "SUTAgentAndroid Version 1.06";
public enum Command
{
RUN ("run"),
EXEC ("exec"),
EXECCWD ("execcwd"),
ENVRUN ("envrun"),
KILL ("kill"),
PS ("ps"),
@ -692,7 +693,25 @@ public class DoCommand {
theArgs[lcv - 1] = Argv[lcv];
}
strReturn = StartPrg2(theArgs, cmdOut);
strReturn = StartPrg2(theArgs, cmdOut, null);
}
else
{
strReturn = sErrorPrefix + "Wrong number of arguments for " + Argv[0] + " command!";
}
break;
case EXECCWD:
if (Argc >= 3)
{
String [] theArgs = new String [Argc - 2];
for (int lcv = 2; lcv < Argc; lcv++)
{
theArgs[lcv - 2] = Argv[lcv];
}
strReturn = StartPrg2(theArgs, cmdOut, Argv[1]);
}
else
{
@ -1262,6 +1281,11 @@ private void CancelNotification()
{
String sRet = null;
File tmpFile = new java.io.File("/data/local/tests");
if (tmpFile.exists() && tmpFile.isDirectory())
{
return("/data/local");
}
if (Environment.getExternalStorageState().equalsIgnoreCase(Environment.MEDIA_MOUNTED))
{
sRet = Environment.getExternalStorageDirectory().getAbsolutePath();
@ -3463,7 +3487,7 @@ private void CancelNotification()
return (sRet);
}
public String StartPrg2(String [] progArray, OutputStream out)
public String StartPrg2(String [] progArray, OutputStream out, String cwd)
{
String sRet = "";
@ -3553,7 +3577,15 @@ private void CancelNotification()
if (theArgs[0].contains("/") || theArgs[0].contains("\\") || !theArgs[0].contains("."))
{
pProc = Runtime.getRuntime().exec(theArgs, envArray);
if (cwd != null)
{
File f = new File(cwd);
pProc = Runtime.getRuntime().exec(theArgs, envArray, f);
}
else
{
pProc = Runtime.getRuntime().exec(theArgs, envArray);
}
RedirOutputThread outThrd = new RedirOutputThread(pProc, out);
outThrd.start();

View File

@ -52,7 +52,7 @@ interface nsIContentSecurityPolicy;
[ptr] native JSContext(JSContext);
[ptr] native JSPrincipals(JSPrincipals);
[scriptable, uuid(B406A2DB-E547-4C95-B8E2-AD09ECB54CE0)]
[scriptable, uuid(1f83b0e0-6b63-4bdc-a50a-b9afe256bd25)]
interface nsIPrincipal : nsISerializable
{
/**
@ -206,6 +206,12 @@ interface nsIPrincipal : nsISerializable
*/
boolean subsumes(in nsIPrincipal other);
/**
* Same as the previous method, subsumes(), but for codebase principals
* ignores changes to document.domain.
*/
boolean subsumesIgnoringDomain(in nsIPrincipal other);
/**
* Checks whether this principal is allowed to load the network resource
* located at the given URI under the same-origin policy. This means that

View File

@ -336,6 +336,12 @@ nsNullPrincipal::Subsumes(nsIPrincipal *aOther, bool *aResult)
return NS_OK;
}
NS_IMETHODIMP
nsNullPrincipal::SubsumesIgnoringDomain(nsIPrincipal *aOther, bool *aResult)
{
return Subsumes(aOther, aResult);
}
NS_IMETHODIMP
nsNullPrincipal::CheckMayLoad(nsIURI* aURI, bool aReport)
{

View File

@ -377,6 +377,12 @@ nsPrincipal::Subsumes(nsIPrincipal *aOther, bool *aResult)
return Equals(aOther, aResult);
}
NS_IMETHODIMP
nsPrincipal::SubsumesIgnoringDomain(nsIPrincipal *aOther, bool *aResult)
{
return EqualsIgnoringDomain(aOther, aResult);
}
static bool
URIIsLocalFile(nsIURI *aURI)
{

View File

@ -125,6 +125,13 @@ nsSystemPrincipal::Subsumes(nsIPrincipal *other, bool *result)
return NS_OK;
}
NS_IMETHODIMP
nsSystemPrincipal::SubsumesIgnoringDomain(nsIPrincipal *other, bool *result)
{
*result = true;
return NS_OK;
}
NS_IMETHODIMP
nsSystemPrincipal::CheckMayLoad(nsIURI* uri, bool aReport)
{

View File

@ -697,6 +697,8 @@ JS_SHARED_LIBRARY = @JS_SHARED_LIBRARY@
MOZ_INSTRUMENT_EVENT_LOOP = @MOZ_INSTRUMENT_EVENT_LOOP@
MOZ_SYSTEM_PLY = @MOZ_SYSTEM_PLY@
# We only want to do the pymake sanity on Windows, other os's can cope
ifeq ($(HOST_OS_ARCH),WINNT)
# Ensure invariants between GNU Make and pymake

View File

@ -792,8 +792,10 @@ EXPAND_LD = $(EXPAND_LIBS_EXEC) --uselist $(if $(REORDER),--reorder $(REORDER))-
EXPAND_MKSHLIB = $(EXPAND_LIBS_EXEC) --uselist $(if $(REORDER),--reorder $(REORDER))-- $(MKSHLIB)
ifdef STDCXX_COMPAT
ifneq ($(OS_ARCH),Darwin)
CHECK_STDCXX = objdump -p $(1) | grep -e 'GLIBCXX_3\.4\.\(9\|[1-9][0-9]\)' > /dev/null && echo "TEST-UNEXPECTED-FAIL | | We don't want these libstdc++ symbols to be used:" && objdump -T $(1) | grep -e 'GLIBCXX_3\.4\.\(9\|[1-9][0-9]\)' && exit 1 || exit 0
endif
endif
# autoconf.mk sets OBJ_SUFFIX to an error to avoid use before including
# this file

View File

@ -979,8 +979,6 @@ EOF
AC_DEFINE_UNQUOTED(MOZ_WINSDK_TARGETVER,0x$MOZ_WINSDK_TARGETVER)
# Definitions matching sdkddkver.h
AC_DEFINE_UNQUOTED(MOZ_NTDDI_WS03, 0x05020000)
AC_DEFINE_UNQUOTED(MOZ_NTDDI_LONGHORN, 0x06000000)
AC_DEFINE_UNQUOTED(MOZ_NTDDI_WIN7, 0x06010000)
;;
esac
@ -1051,6 +1049,16 @@ if test -z "$PYTHON"; then
AC_MSG_ERROR([python was not found in \$PATH])
fi
MOZ_ARG_WITH_BOOL(system-ply,
[ --with-system-ply Use system installed python ply library],
[if $PYTHON -c 'import ply' 2>&5; then
MOZ_SYSTEM_PLY=1
else
AC_MSG_ERROR([python ply library is not found but --with-system-ply was requested])
fi])
AC_SUBST(MOZ_SYSTEM_PLY)
if test -z "$COMPILE_ENVIRONMENT"; then
NSINSTALL_BIN='$(PYTHON) $(topsrcdir)/config/nsinstall.py'
fi
@ -3720,20 +3728,23 @@ AC_CHECK_FUNCS(random strerror lchown fchmod snprintf statvfs memmove rint stat6
AC_CHECK_FUNCS(flockfile getpagesize)
AC_CHECK_FUNCS(localtime_r strtok_r)
dnl check for clock_gettime(), the CLOCK_MONOTONIC clock, and -lrt
_SAVE_LDFLAGS=$LDFLAGS
LDFLAGS="$LDFLAGS -lrt"
AC_CACHE_CHECK(for clock_gettime(CLOCK_MONOTONIC) and -lrt,
ac_cv_have_clock_monotonic,
[AC_TRY_LINK([#include <time.h>],
[ struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts); ],
ac_cv_have_clock_monotonic=yes,
ac_cv_have_clock_monotonic=no)])
LDFLAGS=$_SAVE_LDFLAGS
if test "$ac_cv_have_clock_monotonic" = "yes"; then
dnl check for clock_gettime(), the CLOCK_MONOTONIC clock
AC_CACHE_CHECK(for clock_gettime(CLOCK_MONOTONIC),
ac_cv_clock_monotonic,
[for libs in "" -lrt; do
_SAVE_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS $libs"
AC_TRY_LINK([#include <time.h>],
[ struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts); ],
ac_cv_clock_monotonic=$libs
break,
ac_cv_clock_monotonic=no)
LDFLAGS="$_SAVE_LDFLAGS"
done])
if test "$ac_cv_clock_monotonic" != "no"; then
HAVE_CLOCK_MONOTONIC=1
REALTIME_LIBS=-lrt
REALTIME_LIBS=$ac_cv_clock_monotonic
AC_DEFINE(HAVE_CLOCK_MONOTONIC)
AC_SUBST(HAVE_CLOCK_MONOTONIC)
AC_SUBST(REALTIME_LIBS)

View File

@ -131,7 +131,6 @@ class nsIInterfaceRequestor;
template<class E> class nsCOMArray;
template<class K, class V> class nsRefPtrHashtable;
struct JSRuntime;
class nsIUGenCategory;
class nsIWidget;
class nsIDragSession;
class nsIPresShell;
@ -625,11 +624,6 @@ public:
return sWordBreaker;
}
static nsIUGenCategory* GetGenCat()
{
return sGenCat;
}
/**
* Regster aObserver as a shutdown observer. A strong reference is held
* to aObserver until UnregisterShutdownObserver is called.
@ -2017,7 +2011,6 @@ private:
static nsILineBreaker* sLineBreaker;
static nsIWordBreaker* sWordBreaker;
static nsIUGenCategory* sGenCat;
static nsIScriptRuntime* sScriptRuntimes[NS_STID_ARRAY_UBOUND];
static PRInt32 sScriptRootCount[NS_STID_ARRAY_UBOUND];

View File

@ -691,6 +691,7 @@ DragDataProducer::Produce(nsDOMDataTransfer* aDataTransfer,
rv = nsCopySupport::GetTransferableForNode(nodeToSerialize, doc,
getter_AddRefs(transferable));
}
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISupportsString> data;
PRUint32 dataSize;

View File

@ -122,6 +122,7 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
#include "nsLWBrkCIID.h"
#include "nsILineBreaker.h"
#include "nsIWordBreaker.h"
#include "nsUnicodeProperties.h"
#include "jsdbgapi.h"
#include "nsIJSRuntimeService.h"
#include "nsIDOMDocumentXBL.h"
@ -154,7 +155,6 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
#include "nsGenericHTMLElement.h"
#include "nsAttrValue.h"
#include "nsReferencedElement.h"
#include "nsIUGenCategory.h"
#include "nsIDragService.h"
#include "nsIChannelEventSink.h"
#include "nsIAsyncVerifyRedirectCallback.h"
@ -260,7 +260,6 @@ nsIContentPolicy *nsContentUtils::sContentPolicyService;
bool nsContentUtils::sTriedToGetContentPolicy = false;
nsILineBreaker *nsContentUtils::sLineBreaker;
nsIWordBreaker *nsContentUtils::sWordBreaker;
nsIUGenCategory *nsContentUtils::sGenCat;
nsIScriptRuntime *nsContentUtils::sScriptRuntimes[NS_STID_ARRAY_UBOUND];
PRInt32 nsContentUtils::sScriptRootCount[NS_STID_ARRAY_UBOUND];
PRUint32 nsContentUtils::sJSGCThingRootCount;
@ -389,9 +388,6 @@ nsContentUtils::Init()
rv = CallGetService(NS_WBRK_CONTRACTID, &sWordBreaker);
NS_ENSURE_SUCCESS(rv, rv);
rv = CallGetService(NS_UNICHARCATEGORY_CONTRACTID, &sGenCat);
NS_ENSURE_SUCCESS(rv, rv);
if (!InitializeEventTable())
return NS_ERROR_FAILURE;
@ -977,7 +973,7 @@ nsContentUtils::IsPunctuationMarkAt(const nsTextFragment* aFrag, PRUint32 aOffse
// static
bool nsContentUtils::IsAlphanumeric(PRUint32 aChar)
{
nsIUGenCategory::nsUGenCategory cat = sGenCat->Get(aChar);
nsIUGenCategory::nsUGenCategory cat = mozilla::unicode::GetGenCategory(aChar);
return (cat == nsIUGenCategory::kLetter || cat == nsIUGenCategory::kNumber);
}
@ -1138,7 +1134,6 @@ nsContentUtils::Shutdown()
NS_IF_RELEASE(sIOService);
NS_IF_RELEASE(sLineBreaker);
NS_IF_RELEASE(sWordBreaker);
NS_IF_RELEASE(sGenCat);
#ifdef MOZ_XTF
NS_IF_RELEASE(sXTFService);
#endif

View File

@ -480,10 +480,14 @@ nsDOMAttribute::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const
}
NS_IMETHODIMP
nsDOMAttribute::CloneNode(bool aDeep, nsIDOMNode** aResult)
nsDOMAttribute::CloneNode(bool aDeep, PRUint8 aOptionalArgc, nsIDOMNode** aResult)
{
OwnerDoc()->WarnOnceAbout(nsIDocument::eCloneNode);
if (!aOptionalArgc) {
aDeep = true;
}
return nsNodeUtils::CloneNodeImpl(this, aDeep, true, aResult);
}

View File

@ -5830,8 +5830,12 @@ nsDocument::AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
}
NS_IMETHODIMP
nsDocument::CloneNode(bool aDeep, nsIDOMNode** aReturn)
nsDocument::CloneNode(bool aDeep, PRUint8 aOptionalArgc, nsIDOMNode** aReturn)
{
if (!aOptionalArgc) {
aDeep = true;
}
return nsNodeUtils::CloneNodeImpl(this, aDeep, !mCreatingStaticClone, aReturn);
}
@ -8062,7 +8066,7 @@ nsIDocument::CreateStaticClone(nsISupports* aCloneContainer)
nsCOMPtr<nsISupports> originalContainer = GetContainer();
SetContainer(aCloneContainer);
nsCOMPtr<nsIDOMNode> clonedNode;
nsresult rv = domDoc->CloneNode(true, getter_AddRefs(clonedNode));
nsresult rv = domDoc->CloneNode(true, 1, getter_AddRefs(clonedNode));
SetContainer(originalContainer);
nsCOMPtr<nsIDocument> clonedDoc;

View File

@ -143,8 +143,12 @@ public:
nsresult IsSupported(const nsAString& aFeature,
const nsAString& aVersion,
bool* aReturn);
nsresult CloneNode(bool aDeep, nsIDOMNode** aReturn)
nsresult CloneNode(bool aDeep, PRUint8 aOptionalArgc, nsIDOMNode** aReturn)
{
if (!aOptionalArgc) {
aDeep = true;
}
return nsNodeUtils::CloneNodeImpl(this, aDeep, true, aReturn);
}

View File

@ -437,8 +437,12 @@ public:
// nsIDOMElement method implementation
NS_DECL_NSIDOMELEMENT
nsresult CloneNode(bool aDeep, nsIDOMNode **aResult)
nsresult CloneNode(bool aDeep, PRUint8 aOptionalArgc, nsIDOMNode **aResult)
{
if (!aOptionalArgc) {
aDeep = true;
}
return nsNodeUtils::CloneNodeImpl(this, aDeep, true, aResult);
}

View File

@ -1596,7 +1596,7 @@ nsresult nsRange::CutContents(nsIDOMDocumentFragment** aFragment)
cutValue);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIDOMNode> clone;
rv = charData->CloneNode(false, getter_AddRefs(clone));
rv = charData->CloneNode(false, 1, getter_AddRefs(clone));
NS_ENSURE_SUCCESS(rv, rv);
clone->SetNodeValue(cutValue);
nodeToResult = clone;
@ -1656,7 +1656,7 @@ nsresult nsRange::CutContents(nsIDOMDocumentFragment** aFragment)
{
if (retval) {
nsCOMPtr<nsIDOMNode> clone;
rv = node->CloneNode(false, getter_AddRefs(clone));
rv = node->CloneNode(false, 1, getter_AddRefs(clone));
NS_ENSURE_SUCCESS(rv, rv);
nodeToResult = clone;
}
@ -1827,7 +1827,7 @@ nsRange::CloneParentsBetween(nsIDOMNode *aAncestor,
{
nsCOMPtr<nsIDOMNode> clone, tmpNode;
res = parent->CloneNode(false, getter_AddRefs(clone));
res = parent->CloneNode(false, 1, getter_AddRefs(clone));
if (NS_FAILED(res)) return res;
if (!clone) return NS_ERROR_FAILURE;
@ -1928,7 +1928,7 @@ nsRange::CloneContents(nsIDOMDocumentFragment** aReturn)
// Clone the current subtree!
nsCOMPtr<nsIDOMNode> clone;
res = node->CloneNode(deepClone, getter_AddRefs(clone));
res = node->CloneNode(deepClone, 1, getter_AddRefs(clone));
if (NS_FAILED(res)) return res;
// If it's CharacterData, make sure we only clone what

View File

@ -555,6 +555,7 @@ _TEST_FILES2 = \
file_bug717511_2.html \
file_bug717511_2.html^headers^ \
test_bug726364.html \
test_bug698381.html \
$(NULL)
_CHROME_FILES = \

View File

@ -30,13 +30,13 @@ var constants = [
"INVALID_ACCESS_ERR",
"VALIDATION_ERR",
"TYPE_MISMATCH_ERR",
null,
null,
null,
null,
null,
null,
null,
"SECURITY_ERR",
"NETWORK_ERR",
"ABORT_ERR",
"URL_MISMATCH_ERR",
"QUOTA_EXCEEDED_ERR",
"TIMEOUT_ERR",
"INVALID_NODE_TYPE_ERR",
"DATA_CLONE_ERR"
];
for (var i = 0; i < constants.length; ++i) {

View File

@ -0,0 +1,56 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=698381
-->
<head>
<title>Test for Bug 698381</title>
<script type="text/javascript"
src="/tests/SimpleTest/SimpleTest.js"></script>
<script src="/tests/SimpleTest/EventUtils.js"
type="text/javascript"></script>
<link rel="stylesheet" type="text/css"
href="/tests/SimpleTest/test.css" />
</head>
<body onload="runTests();">
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=698381">
Mozilla Bug 698381</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<div id="noChildren" style="display: none"></div>
<div id="hasChildren" style="display: none">
<div id="childOne" style="display: none"></div>
</div>
<pre id="test">
<script type="text/javascript">
/*
Checks to see if default parameter handling is correct when 0
parameters are passed.
If none are passed, then Node.cloneNode should default aDeep
to true.
*/
SimpleTest.waitForExplicitFinish();
var hasChildren = document.getElementById("hasChildren"),
noChildren = document.getElementById("noChildren"),
clonedNode;
function runTests() {
// Test Node.cloneNode when no arguments are given
clonedNode = hasChildren.cloneNode();
is(clonedNode.hasChildNodes(), true, "Node.cloneNode with true " +
"default on a node with children clones the child nodes.");
clonedNode = noChildren.cloneNode();
is(clonedNode.hasChildNodes(), false, "Node.cloneNode with true " +
"default on a node without children doesn't clone child nodes." );
SimpleTest.finish();
}
</script>
</pre>
</body>
</html>

View File

@ -71,6 +71,7 @@ CPPSRCS += \
WebGLContextReporter.cpp \
WebGLContextValidate.cpp \
WebGLExtensionStandardDerivatives.cpp \
WebGLExtensionTextureFilterAnisotropic.cpp \
WebGLExtensionLoseContext.cpp \
$(NULL)

View File

@ -820,7 +820,6 @@ bool WebGLContext::IsExtensionSupported(WebGLExtensionID ei)
switch (ei) {
case WebGL_OES_texture_float:
MakeContextCurrent();
isSupported = gl->IsExtensionSupported(gl->IsGLES2() ? GLContext::OES_texture_float
: GLContext::ARB_texture_float);
break;
@ -828,6 +827,9 @@ bool WebGLContext::IsExtensionSupported(WebGLExtensionID ei)
// We always support this extension.
isSupported = true;
break;
case WebGL_EXT_texture_filter_anisotropic:
isSupported = gl->IsExtensionSupported(GLContext::EXT_texture_filter_anisotropic);
break;
case WebGL_MOZ_WEBGL_lose_context:
// We always support this extension.
isSupported = true;
@ -860,6 +862,10 @@ WebGLContext::GetExtension(const nsAString& aName, nsIWebGLExtension **retval)
if (IsExtensionSupported(WebGL_OES_standard_derivatives))
ei = WebGL_OES_standard_derivatives;
}
else if (aName.EqualsLiteral("MOZ_EXT_texture_filter_anisotropic")) {
if (IsExtensionSupported(WebGL_EXT_texture_filter_anisotropic))
ei = WebGL_EXT_texture_filter_anisotropic;
}
else if (aName.EqualsLiteral("MOZ_WEBGL_lose_context")) {
if (IsExtensionSupported(WebGL_MOZ_WEBGL_lose_context))
ei = WebGL_MOZ_WEBGL_lose_context;
@ -871,6 +877,9 @@ WebGLContext::GetExtension(const nsAString& aName, nsIWebGLExtension **retval)
case WebGL_OES_standard_derivatives:
mEnabledExtensions[ei] = new WebGLExtensionStandardDerivatives(this);
break;
case WebGL_EXT_texture_filter_anisotropic:
mEnabledExtensions[ei] = new WebGLExtensionTextureFilterAnisotropic(this);
break;
case WebGL_MOZ_WEBGL_lose_context:
mEnabledExtensions[ei] = new WebGLExtensionLoseContext(this);
break;
@ -1295,6 +1304,11 @@ NS_INTERFACE_MAP_BEGIN(WebGLExtensionStandardDerivatives)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLExtensionStandardDerivatives)
NS_INTERFACE_MAP_END_INHERITING(WebGLExtension)
NS_IMPL_ADDREF(WebGLExtensionTextureFilterAnisotropic)
NS_IMPL_RELEASE(WebGLExtensionTextureFilterAnisotropic)
DOMCI_DATA(WebGLExtensionTextureFilterAnisotropic, WebGLExtensionTextureFilterAnisotropic)
NS_IMPL_ADDREF(WebGLExtensionLoseContext)
NS_IMPL_RELEASE(WebGLExtensionLoseContext)
@ -1409,6 +1423,8 @@ WebGLContext::GetSupportedExtensions(nsIVariant **retval)
extList.InsertElementAt(extList.Length(), "OES_texture_float");
if (IsExtensionSupported(WebGL_OES_standard_derivatives))
extList.InsertElementAt(extList.Length(), "OES_standard_derivatives");
if (IsExtensionSupported(WebGL_EXT_texture_filter_anisotropic))
extList.InsertElementAt(extList.Length(), "MOZ_EXT_texture_filter_anisotropic");
if (IsExtensionSupported(WebGL_MOZ_WEBGL_lose_context))
extList.InsertElementAt(extList.Length(), "MOZ_WEBGL_lose_context");

View File

@ -745,6 +745,7 @@ protected:
enum WebGLExtensionID {
WebGL_OES_texture_float,
WebGL_OES_standard_derivatives,
WebGL_EXT_texture_filter_anisotropic,
WebGL_MOZ_WEBGL_lose_context,
WebGLExtensionID_Max
};

View File

@ -2210,6 +2210,15 @@ WebGLContext::GetParameter(PRUint32 pname, nsIVariant **retval)
break;
// float
case LOCAL_GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
if (mEnabledExtensions[WebGL_EXT_texture_filter_anisotropic]) {
GLfloat f = 0.f;
gl->fGetFloatv(pname, &f);
wrval->SetAsFloat(f);
} else {
return ErrorInvalidEnum("getParameter: parameter", pname);
}
break;
case LOCAL_GL_DEPTH_CLEAR_VALUE:
case LOCAL_GL_LINE_WIDTH:
case LOCAL_GL_POLYGON_OFFSET_FACTOR:
@ -2679,6 +2688,7 @@ nsresult WebGLContext::TexParameter_base(WebGLenum target, WebGLenum pname,
return ErrorInvalidOperation("texParameter: no texture is bound to this target");
bool pnameAndParamAreIncompatible = false;
bool paramValueInvalid = false;
switch (pname) {
case LOCAL_GL_TEXTURE_MIN_FILTER:
@ -2727,18 +2737,33 @@ nsresult WebGLContext::TexParameter_base(WebGLenum target, WebGLenum pname,
pnameAndParamAreIncompatible = true;
}
break;
case LOCAL_GL_TEXTURE_MAX_ANISOTROPY_EXT:
if (mEnabledExtensions[WebGL_EXT_texture_filter_anisotropic]) {
if (floatParamPtr && floatParam < 1.f)
paramValueInvalid = true;
else if (intParamPtr && intParam < 1)
paramValueInvalid = true;
}
else
pnameAndParamAreIncompatible = true;
break;
default:
return ErrorInvalidEnumInfo("texParameter: pname", pname);
}
if (pnameAndParamAreIncompatible) {
// note that currently all params are enums, and the tex-input-validation test wants INVALID_ENUM errors
// even for texParameterf. why not.
if (intParamPtr)
return ErrorInvalidEnum("texParameteri: pname %x and param %x (decimal %d) are mutually incompatible",
pname, intParam, intParam);
else
return ErrorInvalidEnum("texParameterf: pname %x and floating-point param %e are mutually incompatible",
return ErrorInvalidEnum("texParameterf: pname %x and param %g are mutually incompatible",
pname, floatParam);
} else if (paramValueInvalid) {
if (intParamPtr)
return ErrorInvalidValue("texParameteri: pname %x and param %x (decimal %d) is invalid",
pname, intParam, intParam);
else
return ErrorInvalidValue("texParameterf: pname %x and param %g is invalid",
pname, floatParam);
}
@ -2799,6 +2824,15 @@ WebGLContext::GetTexParameter(WebGLenum target, WebGLenum pname, nsIVariant **re
wrval->SetAsInt32(i);
}
break;
case LOCAL_GL_TEXTURE_MAX_ANISOTROPY_EXT:
if (mEnabledExtensions[WebGL_EXT_texture_filter_anisotropic]) {
GLfloat f = 0.f;
gl->fGetTexParameterfv(target, pname, &f);
wrval->SetAsFloat(f);
}
else
return ErrorInvalidEnumInfo("getTexParameter: parameter", pname);
break;
default:
return ErrorInvalidEnumInfo("getTexParameter: parameter", pname);

View File

@ -55,4 +55,5 @@ DOMCI_DATA(WebGLShaderPrecisionFormat, void)
DOMCI_DATA(WebGLActiveInfo, void)
DOMCI_DATA(WebGLExtension, void)
DOMCI_DATA(WebGLExtensionStandardDerivatives, void)
DOMCI_DATA(WebGLExtensionTextureFilterAnisotropic, void)
DOMCI_DATA(WebGLExtensionLoseContext, void)

View File

@ -0,0 +1,64 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Florian Boesch <pyalot@gmail.com> (original author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include <stdarg.h>
#include "WebGLContext.h"
#include "WebGLExtensions.h"
#include "nsContentUtils.h"
#include "mozilla/Preferences.h"
using namespace mozilla;
NS_INTERFACE_MAP_BEGIN(WebGLExtensionTextureFilterAnisotropic)
NS_INTERFACE_MAP_ENTRY(nsIWebGLExtensionTextureFilterAnisotropic)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, WebGLExtension)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(WebGLExtensionTextureFilterAnisotropic)
NS_INTERFACE_MAP_END_INHERITING(WebGLExtension)
WebGLExtensionTextureFilterAnisotropic::WebGLExtensionTextureFilterAnisotropic(WebGLContext* context) :
WebGLExtension(context)
{
}
WebGLExtensionTextureFilterAnisotropic::~WebGLExtensionTextureFilterAnisotropic()
{
}

View File

@ -41,9 +41,6 @@
namespace mozilla {
class WebGLExtensionLoseContext;
class WebGLExtensionStandardDerivatives;
class WebGLExtensionLoseContext :
public nsIWebGLExtensionLoseContext,
public WebGLExtension
@ -68,6 +65,18 @@ public:
NS_DECL_NSIWEBGLEXTENSION
};
class WebGLExtensionTextureFilterAnisotropic :
public nsIWebGLExtensionTextureFilterAnisotropic,
public WebGLExtension
{
public:
WebGLExtensionTextureFilterAnisotropic(WebGLContext* context);
virtual ~WebGLExtensionTextureFilterAnisotropic();
NS_DECL_ISUPPORTS
NS_DECL_NSIWEBGLEXTENSION
};
}
#endif // WEBGLEXTENSIONS_H_

View File

@ -21,7 +21,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=685518
SimpleTest.waitForExplicitFinish();
const SECURITY_ERR = 0x805303e8;
const SECURITY_ERR = 0x80530012;
const BAD_URI_ERR = 0x805303f4;
const OK = 0;

View File

@ -21,7 +21,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=682299
/** Test for Bug 682299 **/
const MEDIA_ERR_SRC_NOT_SUPPORTED = 4;
const SECURITY_ERR = 0x805303e8;
const SECURITY_ERR = 0x80530012;
function createCanvas(width, height) {
var c = document.createElement("canvas");

View File

@ -11,7 +11,7 @@
SimpleTest.waitForExplicitFinish();
const SECURITY_ERR = 0x805303e8;
const SECURITY_ERR = 0x80530012;
const OK = 0;
var gl;

View File

@ -19702,7 +19702,7 @@ function test_bug397524() {
try {
$("canvas2").toDataURL("image/png");
gotData = true;
} catch (ex if (ex.code == 1000 && ex.name == "NS_ERROR_DOM_SECURITY_ERR")) {
} catch (ex if (ex.code == 18 && ex.name == "SecurityError")) {
}
is(gotData, false, "Shouldn't be able to read images cross-site!");
@ -19711,7 +19711,7 @@ function test_bug397524() {
try {
$("canvas3").toDataURL("image/png");
gotData = true;
} catch (ex if (ex.code == 1000 && ex.name == "NS_ERROR_DOM_SECURITY_ERR")) {
} catch (ex if (ex.code == 18 && ex.name == "SecurityError")) {
}
is(gotData, false, "Shouldn't be able to read images redirected cross-site!");

View File

@ -1,4 +1,5 @@
oes-standard-derivatives.html
ext-texture-filter-anisotropic.html
oes-texture-float.html
oes-vertex-array-object.html
webgl-debug-renderer-info.html

View File

@ -0,0 +1,157 @@
<!--
Copyright (c) 2012 Florian Boesch <pyalot@gmail.com>. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>WebGL EXT_texture_filter_anisotropic Conformance Tests</title>
<link rel="stylesheet" href="../../resources/js-test-style.css"/>
<script src="../../resources/desktop-gl-constants.js" type="text/javascript"></script>
<script src="../../resources/js-test-pre.js"></script>
<script src="../resources/webgl-test.js"></script>
<script src="../resources/webgl-test-utils.js"></script>
</head>
<body>
<div id="description"></div>
<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
<div id="console"></div>
<script>
description("This test verifies the functionality of the EXT_texture_filter_anisotropic extension, if it is available.");
debug("");
var wtu = WebGLTestUtils;
var canvas = document.getElementById("canvas");
var gl = create3DContext(canvas);
var ext = null;
if (!gl) {
testFailed("WebGL context does not exist");
} else {
testPassed("WebGL context exists");
// Run tests with extension disabled
runHintTestDisabled();
// Query the extension and store globally so shouldBe can access it
ext = gl.getExtension("MOZ_EXT_texture_filter_anisotropic");
if (!ext) {
testPassed("No EXT_texture_filter_anisotropic support -- this is legal");
runSupportedTest(false);
} else {
testPassed("Successfully enabled EXT_texture_filter_anisotropic extension");
runSupportedTest(true);
runHintTestEnabled();
}
}
function runSupportedTest(extensionEnabled) {
var supported = gl.getSupportedExtensions();
if (supported.indexOf("MOZ_EXT_texture_filter_anisotropic") >= 0) {
if (extensionEnabled) {
testPassed("EXT_texture_filter_anisotropic listed as supported and getExtension succeeded");
} else {
testFailed("EXT_texture_filter_anisotropic listed as supported but getExtension failed");
}
} else {
if (extensionEnabled) {
testFailed("EXT_texture_filter_anisotropic not listed as supported but getExtension succeeded");
} else {
testPassed("EXt_texture_filter_anisotropic not listed as supported and getExtension failed -- this is legal");
}
}
}
function runHintTestDisabled() {
debug("Testing MAX_TEXTURE_MAX_ANISOTROPY with extension disabled");
var MAX_TEXTURE_MAX_ANISOTROPY = 0x84FF;
gl.getParameter(MAX_TEXTURE_MAX_ANISOTROPY);
glErrorShouldBe(gl, gl.INVALID_ENUM, "MAX_TEXTURE_MAX_ANISOTROPY should not be queryable if extension is disabled");
debug("Testing TEXTURE_MAX_ANISOTROPY with extension disabled");
var TEXTURE_MAX_ANISOTROPY = 0x84FE;
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.getTexParameter(gl.TEXTURE_2D, TEXTURE_MAX_ANISOTROPY);
glErrorShouldBe(gl, gl.INVALID_ENUM, "TEXTURE_MAX_ANISOTROPY should not be queryable if extension is disabled");
gl.texParameterf(gl.TEXTURE_2D, TEXTURE_MAX_ANISOTROPY, 1);
glErrorShouldBe(gl, gl.INVALID_ENUM, "TEXTURE_MAX_ANISOTROPY should not be settable if extension is disabled");
gl.texParameteri(gl.TEXTURE_2D, TEXTURE_MAX_ANISOTROPY, 1);
glErrorShouldBe(gl, gl.INVALID_ENUM, "TEXTURE_MAX_ANISOTROPY should not be settable if extension is disabled");
gl.deleteTexture(texture);
}
function runHintTestEnabled() {
debug("Testing MAX_TEXTURE_MAX_ANISOTROPY with extension enabled");
shouldBe("ext.MAX_TEXTURE_MAX_ANISOTROPY", "0x84FF");
var max_anisotropy = gl.getParameter(ext.MAX_TEXTURE_MAX_ANISOTROPY);
glErrorShouldBe(gl, gl.NO_ERROR, "MAX_TEXTURE_MAX_ANISOTROPY query should succeed if extension is enabled");
if(max_anisotropy >= 2){
testPassed("Minimum value of MAX_TEXTURE_MAX_ANISOTROPY is 2.0");
}
else{
testFailed("Minimum value of MAX_TEXTURE_MAX_ANISOTROPY is 2.0, returned values was: " + max_anisotropy);
}
// TODO make a texture and verify initial value == 1 and setting to less than 1 is invalid value
debug("Testing TEXTURE_MAX_ANISOTROPY with extension disabled");
shouldBe("ext.TEXTURE_MAX_ANISOTROPY", "0x84FE");
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
var queried_value = gl.getTexParameter(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY);
glErrorShouldBe(gl, gl.NO_ERROR, "TEXTURE_MAX_ANISOTROPY query should succeed if extension is enabled");
if(queried_value == 1){
testPassed("Initial value of TEXTURE_MAX_ANISOTROPY is 1.0");
}
else{
testFailed("Initial value of TEXTURE_MAX_ANISOTROPY should be 1.0, returned value was: " + queried_value);
}
gl.texParameterf(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY, 0);
glErrorShouldBe(gl, gl.INVALID_VALUE, "texParameterf TEXTURE_MAX_ANISOTROPY set to < 1 should be an invalid value");
gl.texParameteri(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY, 0);
glErrorShouldBe(gl, gl.INVALID_VALUE, "texParameteri TEXTURE_MAX_ANISOTROPY set to < 1 should be an invalid value");
gl.texParameterf(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY, max_anisotropy);
glErrorShouldBe(gl, gl.NO_ERROR, "texParameterf TEXTURE_MAX_ANISOTROPY set to >= 2 should should succeed");
gl.texParameteri(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY, max_anisotropy);
glErrorShouldBe(gl, gl.NO_ERROR, "texParameteri TEXTURE_MAX_ANISOTROPY set to >= 2 should should succeed");
var queried_value = gl.getTexParameter(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY);
if(queried_value == max_anisotropy){
testPassed("Set value of TEXTURE_MAX_ANISOTROPY matches expecation");
}
else{
testFailed("Set value of TEXTURE_MAX_ANISOTROPY should be: " + max_anisotropy + " , returned value was: " + queried_value);
}
gl.deleteTexture(texture);
}
debug("");
successfullyParsed = true;
</script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>

View File

@ -0,0 +1,174 @@
diff --git a/content/canvas/test/webgl/conformance/extensions/00_test_list.txt b/content/canvas/test/webgl/conformance/extensions/00_test_list.txt
--- a/content/canvas/test/webgl/conformance/extensions/00_test_list.txt
+++ b/content/canvas/test/webgl/conformance/extensions/00_test_list.txt
@@ -1,7 +1,8 @@
oes-standard-derivatives.html
+ext-texture-filter-anisotropic.html
oes-texture-float.html
oes-vertex-array-object.html
webgl-debug-renderer-info.html
webgl-debug-shaders.html
--min-version 1.0.2 webgl-experimental-compressed-textures.html
diff --git a/content/canvas/test/webgl/conformance/extensions/ext-texture-filter-anisotropic.html b/content/canvas/test/webgl/conformance/extensions/ext-texture-filter-anisotropic.html
new file mode 100644
--- /dev/null
+++ b/content/canvas/test/webgl/conformance/extensions/ext-texture-filter-anisotropic.html
@@ -0,0 +1,157 @@
+<!--
+Copyright (c) 2012 Florian Boesch <pyalot@gmail.com>. All rights reserved.
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+ -->
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset="utf-8">
+<title>WebGL EXT_texture_filter_anisotropic Conformance Tests</title>
+<link rel="stylesheet" href="../../resources/js-test-style.css"/>
+<script src="../../resources/desktop-gl-constants.js" type="text/javascript"></script>
+<script src="../../resources/js-test-pre.js"></script>
+<script src="../resources/webgl-test.js"></script>
+<script src="../resources/webgl-test-utils.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<canvas id="canvas" style="width: 50px; height: 50px;"> </canvas>
+<div id="console"></div>
+
+<script>
+description("This test verifies the functionality of the EXT_texture_filter_anisotropic extension, if it is available.");
+
+debug("");
+
+var wtu = WebGLTestUtils;
+var canvas = document.getElementById("canvas");
+var gl = create3DContext(canvas);
+var ext = null;
+
+if (!gl) {
+ testFailed("WebGL context does not exist");
+} else {
+ testPassed("WebGL context exists");
+
+ // Run tests with extension disabled
+ runHintTestDisabled();
+
+ // Query the extension and store globally so shouldBe can access it
+ ext = gl.getExtension("MOZ_EXT_texture_filter_anisotropic");
+ if (!ext) {
+ testPassed("No EXT_texture_filter_anisotropic support -- this is legal");
+
+ runSupportedTest(false);
+ } else {
+ testPassed("Successfully enabled EXT_texture_filter_anisotropic extension");
+
+ runSupportedTest(true);
+ runHintTestEnabled();
+ }
+}
+
+function runSupportedTest(extensionEnabled) {
+ var supported = gl.getSupportedExtensions();
+ if (supported.indexOf("MOZ_EXT_texture_filter_anisotropic") >= 0) {
+ if (extensionEnabled) {
+ testPassed("EXT_texture_filter_anisotropic listed as supported and getExtension succeeded");
+ } else {
+ testFailed("EXT_texture_filter_anisotropic listed as supported but getExtension failed");
+ }
+ } else {
+ if (extensionEnabled) {
+ testFailed("EXT_texture_filter_anisotropic not listed as supported but getExtension succeeded");
+ } else {
+ testPassed("EXt_texture_filter_anisotropic not listed as supported and getExtension failed -- this is legal");
+ }
+ }
+}
+
+function runHintTestDisabled() {
+ debug("Testing MAX_TEXTURE_MAX_ANISOTROPY with extension disabled");
+
+ var MAX_TEXTURE_MAX_ANISOTROPY = 0x84FF;
+ gl.getParameter(MAX_TEXTURE_MAX_ANISOTROPY);
+ glErrorShouldBe(gl, gl.INVALID_ENUM, "MAX_TEXTURE_MAX_ANISOTROPY should not be queryable if extension is disabled");
+
+ debug("Testing TEXTURE_MAX_ANISOTROPY with extension disabled");
+ var TEXTURE_MAX_ANISOTROPY = 0x84FE;
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+
+ gl.getTexParameter(gl.TEXTURE_2D, TEXTURE_MAX_ANISOTROPY);
+ glErrorShouldBe(gl, gl.INVALID_ENUM, "TEXTURE_MAX_ANISOTROPY should not be queryable if extension is disabled");
+
+ gl.texParameterf(gl.TEXTURE_2D, TEXTURE_MAX_ANISOTROPY, 1);
+ glErrorShouldBe(gl, gl.INVALID_ENUM, "TEXTURE_MAX_ANISOTROPY should not be settable if extension is disabled");
+
+ gl.texParameteri(gl.TEXTURE_2D, TEXTURE_MAX_ANISOTROPY, 1);
+ glErrorShouldBe(gl, gl.INVALID_ENUM, "TEXTURE_MAX_ANISOTROPY should not be settable if extension is disabled");
+
+ gl.deleteTexture(texture);
+}
+
+function runHintTestEnabled() {
+ debug("Testing MAX_TEXTURE_MAX_ANISOTROPY with extension enabled");
+
+ shouldBe("ext.MAX_TEXTURE_MAX_ANISOTROPY", "0x84FF");
+
+ var max_anisotropy = gl.getParameter(ext.MAX_TEXTURE_MAX_ANISOTROPY);
+ glErrorShouldBe(gl, gl.NO_ERROR, "MAX_TEXTURE_MAX_ANISOTROPY query should succeed if extension is enabled");
+
+ if(max_anisotropy >= 2){
+ testPassed("Minimum value of MAX_TEXTURE_MAX_ANISOTROPY is 2.0");
+ }
+ else{
+ testFailed("Minimum value of MAX_TEXTURE_MAX_ANISOTROPY is 2.0, returned values was: " + max_anisotropy);
+ }
+
+ // TODO make a texture and verify initial value == 1 and setting to less than 1 is invalid value
+
+ debug("Testing TEXTURE_MAX_ANISOTROPY with extension disabled");
+ shouldBe("ext.TEXTURE_MAX_ANISOTROPY", "0x84FE");
+
+ var texture = gl.createTexture();
+ gl.bindTexture(gl.TEXTURE_2D, texture);
+
+ var queried_value = gl.getTexParameter(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY);
+ glErrorShouldBe(gl, gl.NO_ERROR, "TEXTURE_MAX_ANISOTROPY query should succeed if extension is enabled");
+
+ if(queried_value == 1){
+ testPassed("Initial value of TEXTURE_MAX_ANISOTROPY is 1.0");
+ }
+ else{
+ testFailed("Initial value of TEXTURE_MAX_ANISOTROPY should be 1.0, returned value was: " + queried_value);
+ }
+
+ gl.texParameterf(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY, 0);
+ glErrorShouldBe(gl, gl.INVALID_VALUE, "texParameterf TEXTURE_MAX_ANISOTROPY set to < 1 should be an invalid value");
+
+ gl.texParameteri(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY, 0);
+ glErrorShouldBe(gl, gl.INVALID_VALUE, "texParameteri TEXTURE_MAX_ANISOTROPY set to < 1 should be an invalid value");
+
+ gl.texParameterf(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY, max_anisotropy);
+ glErrorShouldBe(gl, gl.NO_ERROR, "texParameterf TEXTURE_MAX_ANISOTROPY set to >= 2 should should succeed");
+
+ gl.texParameteri(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY, max_anisotropy);
+ glErrorShouldBe(gl, gl.NO_ERROR, "texParameteri TEXTURE_MAX_ANISOTROPY set to >= 2 should should succeed");
+
+ var queried_value = gl.getTexParameter(gl.TEXTURE_2D, ext.TEXTURE_MAX_ANISOTROPY);
+ if(queried_value == max_anisotropy){
+ testPassed("Set value of TEXTURE_MAX_ANISOTROPY matches expecation");
+ }
+ else{
+ testFailed("Set value of TEXTURE_MAX_ANISOTROPY should be: " + max_anisotropy + " , returned value was: " + queried_value);
+ }
+
+ gl.deleteTexture(texture);
+}
+
+debug("");
+successfullyParsed = true;
+</script>
+<script src="../../resources/js-test-post.js"></script>
+
+</body>
+</html>

View File

@ -78,7 +78,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=415498
browser.loadURI(chromeDir + "bug415498-doc1.html");
yield;
ok(verifyErrorReceived("NS_ERROR_DOM_HIERARCHY_REQUEST_ERR"),
ok(verifyErrorReceived("HierarchyRequestError"),
"Error message not reported in event listener callback!");
gMessages = [];
@ -87,7 +87,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=415498
browser.loadURI(chromeDir + "bug415498-doc2.html");
yield;
ok(verifyErrorReceived("NS_ERROR_DOM_HIERARCHY_REQUEST_ERR"),
ok(verifyErrorReceived("HierarchyRequestError"),
"Error message not reported in window.onload!");
}

View File

@ -38,17 +38,17 @@ function afterDragTests()
checkTypes(gDataTransfer, [], 0, "after dragstart event");
expectError(function() gDataTransfer.setData("text/plain", "Some Text"),
"NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR", "setData when read only");
"NoModificationAllowedError", "setData when read only");
expectError(function() gDataTransfer.clearData("text/plain"),
"NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR", "clearData when read only");
"NoModificationAllowedError", "clearData when read only");
expectError(function() gDataTransfer.mozSetDataAt("text/plain", "Some Text", 0),
"NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR", "setDataAt when read only");
"NoModificationAllowedError", "setDataAt when read only");
expectError(function() gDataTransfer.mozClearDataAt("text/plain", 0),
"NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR", "clearDataAt when read only");
"NoModificationAllowedError", "clearDataAt when read only");
expectError(function() gDataTransfer.setDragImage(draggable, 10, 10),
"NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR", "setDragImage when read only");
"NoModificationAllowedError", "setDragImage when read only");
expectError(function() gDataTransfer.addElement(draggable),
"NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR", "addElement when read only");
"NoModificationAllowedError", "addElement when read only");
var evt = document.createEvent("dragevent");
ok(evt instanceof DragEvent, "synthetic dragevent class")
@ -154,7 +154,7 @@ function test_DataTransfer(dt)
// calling setDataAt requires an index that is 0 <= index <= dt.itemCount
expectError(function() dt.mozSetDataAt("text/plain", "Some Text", 1),
"NS_ERROR_DOM_INDEX_SIZE_ERR", "setDataAt index too high");
"IndexSizeError", "setDataAt index too high");
is(dt.mozUserCancelled, false, "userCancelled");
@ -172,9 +172,9 @@ function test_DataTransfer(dt)
// similar with clearDataAt and getDataAt
expectError(function() dt.mozGetDataAt("text/plain", 1),
"NS_ERROR_DOM_INDEX_SIZE_ERR", "getDataAt index too high");
"IndexSizeError", "getDataAt index too high");
expectError(function() dt.mozClearDataAt("text/plain", 1),
"NS_ERROR_DOM_INDEX_SIZE_ERR", "clearDataAt index too high");
"IndexSizeError", "clearDataAt index too high");
dt.setData("text/plain", "Sample Text");
is(dt.mozItemCount, 1, "added plaintext itemCount");
@ -285,7 +285,7 @@ function test_DataTransfer(dt)
dt.mozSetDataAt("text/plain", "First Item", 0);
dt.mozSetDataAt("text/plain", "Second Item", 1);
expectError(function() dt.mozSetDataAt("text/plain", "Some Text", 3),
"NS_ERROR_DOM_INDEX_SIZE_ERR", "setDataAt index too high with two items");
"IndexSizeError", "setDataAt index too high with two items");
is(dt.mozItemCount, 2, "setDataAt item itemCount");
checkOneDataItem(dt, ["text/plain"], ["First Item"], 0, "setDataAt item at index 0");
checkOneDataItem(dt, ["text/plain"], ["Second Item"], 1, "setDataAt item at index 1");
@ -329,7 +329,7 @@ function test_DataTransfer(dt)
["First Item", "Changed with setData"], 0, "clearDataAt last type at index 0");
checkOneDataItem(dt, ["application/-moz-node"], [draggable], 1, "clearDataAt last type item at index 2");
expectError(function() dt.mozGetDataAt("text/plain", 2),
"NS_ERROR_DOM_INDEX_SIZE_ERR", "getDataAt after item removed index too high");
"IndexSizeError", "getDataAt after item removed index too high");
dt.mozSetDataAt("text/unknown", "Unknown type", 2);
dt.mozSetDataAt("text/unknown", "Unknown type", 1);
@ -356,7 +356,7 @@ function test_DataTransfer(dt)
["Unknown type"], 1, "clearData type that does not exist item at index 1");
expectError(function() dt.mozClearDataAt("text/plain", 3),
"NS_ERROR_DOM_INDEX_SIZE_ERR", "clearData index too high with two items");
"IndexSizeError", "clearData index too high with two items");
// ensure that clearData() removes all data associated with the first item
dt.clearData();

View File

@ -808,7 +808,7 @@ nsHTMLSelectElement::SetLength(PRUint32 aLength)
if (i + 1 < aLength) {
nsCOMPtr<nsIDOMNode> newNode;
rv = node->CloneNode(true, getter_AddRefs(newNode));
rv = node->CloneNode(true, 1, getter_AddRefs(newNode));
NS_ENSURE_SUCCESS(rv, rv);
node = newNode;

View File

@ -849,15 +849,11 @@ nsTextInputListener::EditAction()
nsCOMPtr<nsIEditor> editor;
frame->GetEditor(getter_AddRefs(editor));
nsCOMPtr<nsITransactionManager> manager;
editor->GetTransactionManager(getter_AddRefs(manager));
NS_ENSURE_TRUE(manager, NS_ERROR_FAILURE);
// Get the number of undo / redo items
PRInt32 numUndoItems = 0;
PRInt32 numRedoItems = 0;
manager->GetNumberOfUndoItems(&numUndoItems);
manager->GetNumberOfRedoItems(&numRedoItems);
editor->GetNumberOfUndoItems(&numUndoItems);
editor->GetNumberOfRedoItems(&numRedoItems);
if ((numUndoItems && !mHadUndoItems) || (!numUndoItems && mHadUndoItems) ||
(numRedoItems && !mHadRedoItems) || (!numRedoItems && mHadRedoItems)) {
// Modify the menu if undo or redo items are different

View File

@ -41,163 +41,16 @@
#include "mozilla/StdInt.h"
// Adds two 32bit unsigned numbers, retuns true if addition succeeded,
// or false the if addition would result in an overflow.
bool AddOverflow32(PRUint32 a, PRUint32 b, PRUint32& aResult) {
PRUint64 rl = static_cast<PRUint64>(a) + static_cast<PRUint64>(b);
if (rl > PR_UINT32_MAX) {
return false;
}
aResult = static_cast<PRUint32>(rl);
return true;
}
bool MulOverflow32(PRUint32 a, PRUint32 b, PRUint32& aResult)
{
// 32 bit integer multiplication with overflow checking. Returns true
// if the multiplication was successful, or false if the operation resulted
// in an integer overflow.
PRUint64 a64 = a;
PRUint64 b64 = b;
PRUint64 r64 = a64 * b64;
if (r64 > PR_UINT32_MAX)
return false;
aResult = static_cast<PRUint32>(r64);
return true;
}
// Adds two 64bit numbers, retuns true if addition succeeded, or false
// if addition would result in an overflow.
bool AddOverflow(PRInt64 a, PRInt64 b, PRInt64& aResult) {
if (b < 1) {
if (INT64_MIN - b <= a) {
aResult = a + b;
return true;
}
} else if (INT64_MAX - b >= a) {
aResult = a + b;
return true;
}
return false;
}
// 64 bit integer multiplication with overflow checking. Returns true
// if the multiplication was successful, or false if the operation resulted
// in an integer overflow.
bool MulOverflow(PRInt64 a, PRInt64 b, PRInt64& aResult) {
// We break a multiplication a * b into of sign_a * sign_b * abs(a) * abs(b)
//
// This is equivalent to:
//
// (sign_a * sign_b) * ((a_hi * 2^32) + a_lo) * ((b_hi * 2^32) + b_lo)
//
// Which is equivalent to:
//
// (sign_a * sign_b) *
// ((a_hi * b_hi << 64) +
// (a_hi * b_lo << 32) + (a_lo * b_hi << 32) +
// a_lo * b_lo)
//
// So to check if a*b overflows, we must check each sub part of the above
// sum.
//
// Note: -1 * INT64_MIN == INT64_MIN ; we can't negate INT64_MIN!
// Note: Shift of negative numbers is undefined.
//
// Figure out the sign after multiplication. Then we can just work with
// unsigned numbers.
PRInt64 sign = (!(a < 0) == !(b < 0)) ? 1 : -1;
PRInt64 abs_a = (a < 0) ? -a : a;
PRInt64 abs_b = (b < 0) ? -b : b;
if (abs_a < 0) {
NS_ASSERTION(a == INT64_MIN, "How else can this happen?");
if (b == 0 || b == 1) {
aResult = a * b;
return true;
} else {
return false;
}
}
if (abs_b < 0) {
NS_ASSERTION(b == INT64_MIN, "How else can this happen?");
if (a == 0 || a == 1) {
aResult = a * b;
return true;
} else {
return false;
}
}
NS_ASSERTION(abs_a >= 0 && abs_b >= 0, "abs values must be non-negative");
PRInt64 a_hi = abs_a >> 32;
PRInt64 a_lo = abs_a & 0xFFFFFFFF;
PRInt64 b_hi = abs_b >> 32;
PRInt64 b_lo = abs_b & 0xFFFFFFFF;
NS_ASSERTION((a_hi<<32) + a_lo == abs_a, "Partition must be correct");
NS_ASSERTION((b_hi<<32) + b_lo == abs_b, "Partition must be correct");
// In the sub-equation (a_hi * b_hi << 64), if a_hi or b_hi
// are non-zero, this will overflow as it's shifted by 64.
// Abort if this overflows.
if (a_hi != 0 && b_hi != 0) {
return false;
}
// We can now assume that either a_hi or b_hi is 0.
NS_ASSERTION(a_hi == 0 || b_hi == 0, "One of these must be 0");
// Next we calculate:
// (a_hi * b_lo << 32) + (a_lo * b_hi << 32)
// We can factor this as:
// (a_hi * b_lo + a_lo * b_hi) << 32
PRInt64 q = a_hi * b_lo + a_lo * b_hi;
if (q > PR_INT32_MAX) {
// q will overflow when we shift by 32; abort.
return false;
}
q <<= 32;
// Both a_lo and b_lo are less than INT32_MAX, so can't overflow.
PRUint64 lo = a_lo * b_lo;
if (lo > INT64_MAX) {
return false;
}
// Add the final result. We must check for overflow during addition.
if (!AddOverflow(q, static_cast<PRInt64>(lo), aResult)) {
return false;
}
aResult *= sign;
NS_ASSERTION(a * b == aResult, "We didn't overflow, but result is wrong!");
return true;
}
// Converts from number of audio frames to microseconds, given the specified
// audio rate.
bool FramesToUsecs(PRInt64 aFrames, PRUint32 aRate, PRInt64& aOutUsecs)
{
PRInt64 x;
if (!MulOverflow(aFrames, USECS_PER_S, x))
return false;
aOutUsecs = x / aRate;
return true;
CheckedInt64 FramesToUsecs(PRInt64 aFrames, PRUint32 aRate) {
return (CheckedInt64(aFrames) * USECS_PER_S) / aRate;
}
// Converts from microseconds to number of audio frames, given the specified
// audio rate.
bool UsecsToFrames(PRInt64 aUsecs, PRUint32 aRate, PRInt64& aOutFrames)
{
PRInt64 x;
if (!MulOverflow(aUsecs, aRate, x))
return false;
aOutFrames = x / USECS_PER_S;
return true;
CheckedInt64 UsecsToFrames(PRInt64 aUsecs, PRUint32 aRate) {
return (CheckedInt64(aUsecs) * aRate) / USECS_PER_S;
}
static PRInt32 ConditionDimension(float aValue)

View File

@ -44,6 +44,13 @@
#include "nsRect.h"
#include "nsIThreadManager.h"
#include "CheckedInt.h"
using mozilla::CheckedInt64;
using mozilla::CheckedUint64;
using mozilla::CheckedInt32;
using mozilla::CheckedUint32;
// This file contains stuff we'd rather put elsewhere, but which is
// dependent on other changes which we don't want to wait for. We plan to
// remove this file in the near future.
@ -97,35 +104,17 @@ private:
} // namespace mozilla
// Adds two 32bit unsigned numbers, retuns true if addition succeeded,
// or false the if addition would result in an overflow.
bool AddOverflow32(PRUint32 a, PRUint32 b, PRUint32& aResult);
// 32 bit integer multiplication with overflow checking. Returns true
// if the multiplication was successful, or false if the operation resulted
// in an integer overflow.
bool MulOverflow32(PRUint32 a, PRUint32 b, PRUint32& aResult);
// Adds two 64bit numbers, retuns true if addition succeeded, or false
// if addition would result in an overflow.
bool AddOverflow(PRInt64 a, PRInt64 b, PRInt64& aResult);
// 64 bit integer multiplication with overflow checking. Returns true
// if the multiplication was successful, or false if the operation resulted
// in an integer overflow.
bool MulOverflow(PRInt64 a, PRInt64 b, PRInt64& aResult);
// Converts from number of audio frames (aFrames) to microseconds, given
// the specified audio rate (aRate). Stores result in aOutUsecs. Returns true
// if the operation succeeded, or false if there was an integer overflow
// while calulating the conversion.
bool FramesToUsecs(PRInt64 aFrames, PRUint32 aRate, PRInt64& aOutUsecs);
CheckedInt64 FramesToUsecs(PRInt64 aFrames, PRUint32 aRate);
// Converts from microseconds (aUsecs) to number of audio frames, given the
// specified audio rate (aRate). Stores the result in aOutFrames. Returns
// true if the operation succeeded, or false if there was an integer
// overflow while calulating the conversion.
bool UsecsToFrames(PRInt64 aUsecs, PRUint32 aRate, PRInt64& aOutFrames);
CheckedInt64 UsecsToFrames(PRInt64 aUsecs, PRUint32 aRate);
// Number of microseconds per second. 1e6.
static const PRInt64 USECS_PER_S = 1000000;

View File

@ -142,12 +142,10 @@ VideoData* VideoData::Create(nsVideoInfo& aInfo,
// Ensure the picture size specified in the headers can be extracted out of
// the frame we've been supplied without indexing out of bounds.
PRUint32 xLimit;
PRUint32 yLimit;
if (!AddOverflow32(aPicture.x, aPicture.width, xLimit) ||
xLimit > aBuffer.mPlanes[0].mStride ||
!AddOverflow32(aPicture.y, aPicture.height, yLimit) ||
yLimit > aBuffer.mPlanes[0].mHeight)
CheckedUint32 xLimit = aPicture.x + CheckedUint32(aPicture.width);
CheckedUint32 yLimit = aPicture.y + CheckedUint32(aPicture.height);
if (!xLimit.valid() || xLimit.value() > aBuffer.mPlanes[0].mStride ||
!yLimit.valid() || yLimit.value() > aBuffer.mPlanes[0].mHeight)
{
// The specified picture dimensions can't be contained inside the video
// frame, we'll stomp memory if we try to copy it. Fail.
@ -312,10 +310,6 @@ nsresult nsBuiltinDecoderReader::DecodeToTarget(PRInt64 aTarget)
if (HasAudio()) {
// Decode audio forward to the seek target.
PRInt64 targetFrame = 0;
if (!UsecsToFrames(aTarget, mInfo.mAudioRate, targetFrame)) {
return NS_ERROR_FAILURE;
}
bool eof = false;
while (HasAudio() && !eof) {
while (!eof && mAudioQueue.GetSize() == 0) {
@ -330,18 +324,19 @@ nsresult nsBuiltinDecoderReader::DecodeToTarget(PRInt64 aTarget)
const AudioData* audio = mAudioQueue.PeekFront();
if (!audio)
break;
PRInt64 startFrame = 0;
if (!UsecsToFrames(audio->mTime, mInfo.mAudioRate, startFrame)) {
CheckedInt64 startFrame = UsecsToFrames(audio->mTime, mInfo.mAudioRate);
CheckedInt64 targetFrame = UsecsToFrames(aTarget, mInfo.mAudioRate);
if (!startFrame.valid() || !targetFrame.valid()) {
return NS_ERROR_FAILURE;
}
if (startFrame + audio->mFrames <= targetFrame) {
if (startFrame.value() + audio->mFrames <= targetFrame.value()) {
// Our seek target lies after the frames in this AudioData. Pop it
// off the queue, and keep decoding forwards.
delete mAudioQueue.PopFront();
audio = nsnull;
continue;
}
if (startFrame > targetFrame) {
if (startFrame.value() > targetFrame.value()) {
// The seek target doesn't lie in the audio block just after the last
// audio frames we've seen which were before the seek target. This
// could have been the first audio data we've seen after seek, i.e. the
@ -356,10 +351,12 @@ nsresult nsBuiltinDecoderReader::DecodeToTarget(PRInt64 aTarget)
// The seek target lies somewhere in this AudioData's frames, strip off
// any frames which lie before the seek target, so we'll begin playback
// exactly at the seek target.
NS_ASSERTION(targetFrame >= startFrame, "Target must at or be after data start.");
NS_ASSERTION(targetFrame < startFrame + audio->mFrames, "Data must end after target.");
NS_ASSERTION(targetFrame.value() >= startFrame.value(),
"Target must at or be after data start.");
NS_ASSERTION(targetFrame.value() < startFrame.value() + audio->mFrames,
"Data must end after target.");
PRInt64 framesToPrune = targetFrame - startFrame;
PRInt64 framesToPrune = targetFrame.value() - startFrame.value();
if (framesToPrune > audio->mFrames) {
// We've messed up somehow. Don't try to trim frames, the |frames|
// variable below will overflow.
@ -372,13 +369,13 @@ nsresult nsBuiltinDecoderReader::DecodeToTarget(PRInt64 aTarget)
memcpy(audioData.get(),
audio->mAudioData.get() + (framesToPrune * channels),
frames * channels * sizeof(AudioDataValue));
PRInt64 duration;
if (!FramesToUsecs(frames, mInfo.mAudioRate, duration)) {
CheckedInt64 duration = FramesToUsecs(frames, mInfo.mAudioRate);
if (!duration.valid()) {
return NS_ERROR_FAILURE;
}
nsAutoPtr<AudioData> data(new AudioData(audio->mOffset,
aTarget,
duration,
duration.value(),
frames,
audioData.forget(),
channels));

View File

@ -806,53 +806,39 @@ void nsBuiltinDecoderStateMachine::AudioLoop()
// Calculate the number of frames that have been pushed onto the audio
// hardware.
PRInt64 playedFrames = 0;
if (!UsecsToFrames(audioStartTime, rate, playedFrames)) {
NS_WARNING("Int overflow converting playedFrames");
break;
}
if (!AddOverflow(playedFrames, audioDuration, playedFrames)) {
NS_WARNING("Int overflow adding playedFrames");
break;
}
CheckedInt64 playedFrames = UsecsToFrames(audioStartTime, rate) +
audioDuration;
// Calculate the timestamp of the next chunk of audio in numbers of
// samples.
PRInt64 sampleTime = 0;
if (!UsecsToFrames(s->mTime, rate, sampleTime)) {
NS_WARNING("Int overflow converting sampleTime");
break;
}
PRInt64 missingFrames = 0;
if (!AddOverflow(sampleTime, -playedFrames, missingFrames)) {
NS_WARNING("Int overflow adding missingFrames");
CheckedInt64 sampleTime = UsecsToFrames(s->mTime, rate);
CheckedInt64 missingFrames = sampleTime - playedFrames;
if (!missingFrames.valid() || !sampleTime.valid()) {
NS_WARNING("Int overflow adding in AudioLoop()");
break;
}
PRInt64 framesWritten = 0;
if (missingFrames > 0) {
if (missingFrames.value() > 0) {
// The next audio chunk begins some time after the end of the last chunk
// we pushed to the audio hardware. We must push silence into the audio
// hardware so that the next audio chunk begins playback at the correct
// time.
missingFrames = NS_MIN(static_cast<PRInt64>(PR_UINT32_MAX), missingFrames);
framesWritten = PlaySilence(static_cast<PRUint32>(missingFrames),
channels, playedFrames);
missingFrames = NS_MIN(static_cast<PRInt64>(PR_UINT32_MAX),
missingFrames.value());
framesWritten = PlaySilence(static_cast<PRUint32>(missingFrames.value()),
channels, playedFrames.value());
} else {
framesWritten = PlayFromAudioQueue(sampleTime, channels);
framesWritten = PlayFromAudioQueue(sampleTime.value(), channels);
}
audioDuration += framesWritten;
{
ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor());
PRInt64 playedUsecs;
if (!FramesToUsecs(audioDuration, rate, playedUsecs)) {
NS_WARNING("Int overflow calculating playedUsecs");
break;
}
if (!AddOverflow(audioStartTime, playedUsecs, mAudioEndTime)) {
CheckedInt64 playedUsecs = FramesToUsecs(audioDuration, rate) + audioStartTime;
if (!playedUsecs.valid()) {
NS_WARNING("Int overflow calculating audio end time");
break;
}
mAudioEndTime = playedUsecs.value();
}
}
if (mReader->mAudioQueue.AtEndOfStream() &&

View File

@ -318,33 +318,27 @@ PRInt64 nsTheoraState::Time(th_info* aInfo, PRInt64 aGranulepos)
if (aGranulepos < 0 || aInfo->fps_numerator == 0) {
return -1;
}
PRInt64 t = 0;
// Implementation of th_granule_frame inlined here to operate
// on the th_info structure instead of the theora_state.
int shift = aInfo->keyframe_granule_shift;
ogg_int64_t iframe = aGranulepos >> shift;
ogg_int64_t pframe = aGranulepos - (iframe << shift);
PRInt64 frameno = iframe + pframe - TH_VERSION_CHECK(aInfo, 3, 2, 1);
if (!AddOverflow(frameno, 1, t))
CheckedInt64 t = ((CheckedInt64(frameno) + 1) * USECS_PER_S) * aInfo->fps_denominator;
if (!t.valid())
return -1;
if (!MulOverflow(t, USECS_PER_S, t))
return -1;
if (!MulOverflow(t, aInfo->fps_denominator, t))
return -1;
return t / aInfo->fps_numerator;
t /= aInfo->fps_numerator;
return t.valid() ? t.value() : -1;
}
PRInt64 nsTheoraState::StartTime(PRInt64 granulepos) {
if (granulepos < 0 || !mActive || mInfo.fps_numerator == 0) {
return -1;
}
PRInt64 t = 0;
PRInt64 frameno = th_granule_frame(mCtx, granulepos);
if (!MulOverflow(frameno, USECS_PER_S, t))
CheckedInt64 t = (CheckedInt64(th_granule_frame(mCtx, granulepos)) * USECS_PER_S) * mInfo.fps_denominator;
if (!t.valid())
return -1;
if (!MulOverflow(t, mInfo.fps_denominator, t))
return -1;
return t / mInfo.fps_numerator;
return t.value() / mInfo.fps_numerator;
}
PRInt64
@ -361,9 +355,10 @@ nsTheoraState::MaxKeyframeOffset()
PRInt64 keyframeDiff = (1 << mInfo.keyframe_granule_shift) - 1;
// Length of frame in usecs.
PRInt64 d = 0; // d will be 0 if multiplication overflows.
MulOverflow(USECS_PER_S, mInfo.fps_denominator, d);
frameDuration = d / mInfo.fps_numerator;
CheckedInt64 d = CheckedInt64(mInfo.fps_denominator) * USECS_PER_S;
if (!d.valid())
d = 0;
frameDuration = d.value() / mInfo.fps_numerator;
// Total time in usecs keyframe can be offset from any given frame.
return frameDuration * keyframeDiff;
@ -601,9 +596,10 @@ PRInt64 nsVorbisState::Time(vorbis_info* aInfo, PRInt64 aGranulepos)
if (aGranulepos == -1 || aInfo->rate == 0) {
return -1;
}
PRInt64 t = 0;
MulOverflow(USECS_PER_S, aGranulepos, t);
return t / aInfo->rate;
CheckedInt64 t = CheckedInt64(aGranulepos) * USECS_PER_S;
if (!t.valid())
t = 0;
return t.value() / aInfo->rate;
}
bool
@ -872,7 +868,6 @@ bool nsSkeletonState::DecodeIndex(ogg_packet* aPacket)
PRUint32 serialno = LEUint32(aPacket->packet + INDEX_SERIALNO_OFFSET);
PRInt64 numKeyPoints = LEInt64(aPacket->packet + INDEX_NUM_KEYPOINTS_OFFSET);
PRInt64 n = 0;
PRInt64 endTime = 0, startTime = 0;
const unsigned char* p = aPacket->packet;
@ -884,34 +879,32 @@ bool nsSkeletonState::DecodeIndex(ogg_packet* aPacket)
}
// Extract the start time.
n = LEInt64(p + INDEX_FIRST_NUMER_OFFSET);
PRInt64 t;
if (!MulOverflow(n, USECS_PER_S, t)) {
CheckedInt64 t = CheckedInt64(LEInt64(p + INDEX_FIRST_NUMER_OFFSET)) * USECS_PER_S;
if (!t.valid()) {
return (mActive = false);
} else {
startTime = t / timeDenom;
startTime = t.value() / timeDenom;
}
// Extract the end time.
n = LEInt64(p + INDEX_LAST_NUMER_OFFSET);
if (!MulOverflow(n, USECS_PER_S, t)) {
t = LEInt64(p + INDEX_LAST_NUMER_OFFSET) * USECS_PER_S;
if (!t.valid()) {
return (mActive = false);
} else {
endTime = t / timeDenom;
endTime = t.value() / timeDenom;
}
// Check the numKeyPoints value read, ensure we're not going to run out of
// memory while trying to decode the index packet.
PRInt64 minPacketSize;
if (!MulOverflow(numKeyPoints, MIN_KEY_POINT_SIZE, minPacketSize) ||
!AddOverflow(INDEX_KEYPOINT_OFFSET, minPacketSize, minPacketSize))
CheckedInt64 minPacketSize = (CheckedInt64(numKeyPoints) * MIN_KEY_POINT_SIZE) + INDEX_KEYPOINT_OFFSET;
if (!minPacketSize.valid())
{
return (mActive = false);
}
PRInt64 sizeofIndex = aPacket->bytes - INDEX_KEYPOINT_OFFSET;
PRInt64 maxNumKeyPoints = sizeofIndex / MIN_KEY_POINT_SIZE;
if (aPacket->bytes < minPacketSize ||
if (aPacket->bytes < minPacketSize.value() ||
numKeyPoints > maxNumKeyPoints ||
numKeyPoints < 0)
{
@ -933,32 +926,34 @@ bool nsSkeletonState::DecodeIndex(ogg_packet* aPacket)
p = aPacket->packet + INDEX_KEYPOINT_OFFSET;
const unsigned char* limit = aPacket->packet + aPacket->bytes;
PRInt64 numKeyPointsRead = 0;
PRInt64 offset = 0;
PRInt64 time = 0;
CheckedInt64 offset = 0;
CheckedInt64 time = 0;
while (p < limit &&
numKeyPointsRead < numKeyPoints)
{
PRInt64 delta = 0;
p = ReadVariableLengthInt(p, limit, delta);
offset += delta;
if (p == limit ||
!AddOverflow(offset, delta, offset) ||
offset > mLength ||
offset < 0)
!offset.valid() ||
offset.value() > mLength ||
offset.value() < 0)
{
return (mActive = false);
}
p = ReadVariableLengthInt(p, limit, delta);
if (!AddOverflow(time, delta, time) ||
time > endTime ||
time < startTime)
time += delta;
if (!time.valid() ||
time.value() > endTime ||
time.value() < startTime)
{
return (mActive = false);
}
PRInt64 timeUsecs = 0;
if (!MulOverflow(time, USECS_PER_S, timeUsecs))
CheckedInt64 timeUsecs = time * USECS_PER_S;
if (!timeUsecs.valid())
return mActive = false;
timeUsecs /= timeDenom;
keyPoints->Add(offset, timeUsecs);
keyPoints->Add(offset.value(), timeUsecs.value());
numKeyPointsRead++;
}
@ -1064,7 +1059,9 @@ nsresult nsSkeletonState::GetDuration(const nsTArray<PRUint32>& aTracks,
}
}
NS_ASSERTION(endTime > startTime, "Duration must be positive");
return AddOverflow(endTime, -startTime, aDuration) ? NS_OK : NS_ERROR_FAILURE;
CheckedInt64 duration = CheckedInt64(endTime) - startTime;
aDuration = duration.valid() ? duration.value() : 0;
return duration.valid() ? NS_OK : NS_ERROR_FAILURE;
}
bool nsSkeletonState::DecodeHeader(ogg_packet* aPacket)

Some files were not shown because too many files have changed in this diff Show More