mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge mozilla-central to tracemonkey.
This commit is contained in:
commit
247b1e3f5d
@ -18,7 +18,7 @@ on http://developer.mozilla.org, you can try asking your question in a
|
||||
mozilla.* Usenet group, or on IRC at irc.mozilla.org. [The Mozilla news groups
|
||||
are accessible on Google Groups, or news.mozilla.org with a NNTP reader.]
|
||||
|
||||
You can download nightly development builds from the the Mozilla FTP server.
|
||||
You can download nightly development builds from the Mozilla FTP server.
|
||||
Keep in mind that nightly builds, which are used by Mozilla developers for
|
||||
testing, may be buggy. Firefox nightlies, for example, can be found at:
|
||||
|
||||
|
@ -74,7 +74,6 @@ nsHyperTextAccessibleWrap(aDomNode, aShell)
|
||||
|
||||
// nsAccessible
|
||||
|
||||
/* unsigned long getRole (); */
|
||||
nsresult
|
||||
nsHTMLTableCellAccessible::GetRoleInternal(PRUint32 *aResult)
|
||||
{
|
||||
@ -82,6 +81,29 @@ nsHTMLTableCellAccessible::GetRoleInternal(PRUint32 *aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLTableCellAccessible::GetStateInternal(PRUint32 *aState,
|
||||
PRUint32 *aExtraState)
|
||||
{
|
||||
nsresult rv= nsHyperTextAccessibleWrap::GetStateInternal(aState, aExtraState);
|
||||
NS_ENSURE_A11Y_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(mDOMNode);
|
||||
nsCOMPtr<nsIPresShell> presShell = do_QueryReferent(mWeakShell);
|
||||
nsIFrame *frame = presShell->GetPrimaryFrameFor(content);
|
||||
NS_ASSERTION(frame, "No frame for valid cell accessible!");
|
||||
|
||||
if (frame) {
|
||||
*aState |= nsIAccessibleStates::STATE_SELECTABLE;
|
||||
PRBool isSelected = PR_FALSE;
|
||||
frame->GetSelected(&isSelected);
|
||||
if (isSelected)
|
||||
*aState |= nsIAccessibleStates::STATE_SELECTED;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLTableCellAccessible::GetAttributesInternal(nsIPersistentProperties *aAttributes)
|
||||
{
|
||||
@ -1277,46 +1299,44 @@ NS_IMETHODIMP nsHTMLTableAccessible::GetDescription(nsAString& aDescription)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool nsHTMLTableAccessible::HasDescendant(const char *aTagName, PRBool aAllowEmpty)
|
||||
PRBool
|
||||
nsHTMLTableAccessible::HasDescendant(const nsAString& aTagName,
|
||||
PRBool aAllowEmpty)
|
||||
{
|
||||
nsCOMPtr<nsIDOMElement> tableElt(do_QueryInterface(mDOMNode));
|
||||
NS_ENSURE_TRUE(tableElt, PR_FALSE);
|
||||
|
||||
nsCOMPtr<nsIDOMNodeList> nodeList;
|
||||
nsAutoString tagName;
|
||||
tagName.AssignWithConversion(aTagName);
|
||||
tableElt->GetElementsByTagName(tagName, getter_AddRefs(nodeList));
|
||||
tableElt->GetElementsByTagName(aTagName, getter_AddRefs(nodeList));
|
||||
NS_ENSURE_TRUE(nodeList, PR_FALSE);
|
||||
PRUint32 length;
|
||||
nodeList->GetLength(&length);
|
||||
|
||||
if (length == 1) {
|
||||
// Make sure it's not the table itself
|
||||
nsCOMPtr<nsIDOMNode> foundItem;
|
||||
nodeList->Item(0, getter_AddRefs(foundItem));
|
||||
if (foundItem == mDOMNode) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
if (!aAllowEmpty) {
|
||||
// Make sure that the item we found has contents
|
||||
// and either has multiple children or the
|
||||
// found item is not a whitespace-only text node
|
||||
nsCOMPtr<nsIContent> foundItemContent = do_QueryInterface(foundItem);
|
||||
if (!foundItemContent) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
if (foundItemContent->GetChildCount() > 1) {
|
||||
return PR_TRUE; // Treat multiple child nodes as non-empty
|
||||
}
|
||||
nsIContent *innerItemContent = foundItemContent->GetChildAt(0);
|
||||
if (!innerItemContent || innerItemContent->TextIsOnlyWhitespace()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
return length > 0;
|
||||
nsCOMPtr<nsIDOMNode> foundItem;
|
||||
nodeList->Item(0, getter_AddRefs(foundItem));
|
||||
if (!foundItem)
|
||||
return PR_FALSE;
|
||||
|
||||
if (aAllowEmpty)
|
||||
return PR_TRUE;
|
||||
|
||||
// Make sure that the item we found has contents and either has multiple
|
||||
// children or the found item is not a whitespace-only text node.
|
||||
nsCOMPtr<nsIContent> foundItemContent = do_QueryInterface(foundItem);
|
||||
if (foundItemContent->GetChildCount() > 1)
|
||||
return PR_TRUE; // Treat multiple child nodes as non-empty
|
||||
|
||||
nsIContent *innerItemContent = foundItemContent->GetChildAt(0);
|
||||
if (innerItemContent && !innerItemContent->TextIsOnlyWhitespace())
|
||||
return PR_TRUE;
|
||||
|
||||
// If we found more than one node then return true not depending on
|
||||
// aAllowEmpty flag.
|
||||
// XXX it might be dummy but bug 501375 where we changed this addresses
|
||||
// performance problems only. Note, currently 'aAllowEmpty' flag is used for
|
||||
// caption element only. On another hand we create accessible object for
|
||||
// the first entry of caption element (see
|
||||
// nsHTMLTableAccessible::CacheChildren).
|
||||
nodeList->Item(1, getter_AddRefs(foundItem));
|
||||
return !!foundItem;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1373,11 +1393,14 @@ nsHTMLTableAccessible::IsProbablyForLayout(PRBool *aIsProbablyForLayout)
|
||||
// Check for legitimate data table elements or attributes
|
||||
nsAutoString summary;
|
||||
if ((content->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::summary, summary) && !summary.IsEmpty()) ||
|
||||
HasDescendant("caption", PR_FALSE) || HasDescendant("th") || HasDescendant("thead") ||
|
||||
HasDescendant("tfoot") || HasDescendant("colgroup")) {
|
||||
HasDescendant(NS_LITERAL_STRING("caption"), PR_FALSE) ||
|
||||
HasDescendant(NS_LITERAL_STRING("th")) ||
|
||||
HasDescendant(NS_LITERAL_STRING("thead")) ||
|
||||
HasDescendant(NS_LITERAL_STRING("tfoot")) ||
|
||||
HasDescendant(NS_LITERAL_STRING("colgroup"))) {
|
||||
RETURN_LAYOUT_ANSWER(PR_FALSE, "Has caption, summary, th, thead, tfoot or colgroup -- legitimate table structures");
|
||||
}
|
||||
if (HasDescendant("table")) {
|
||||
if (HasDescendant(NS_LITERAL_STRING("table"))) {
|
||||
RETURN_LAYOUT_ANSWER(PR_TRUE, "Has a nested table within it");
|
||||
}
|
||||
|
||||
@ -1487,7 +1510,10 @@ nsHTMLTableAccessible::IsProbablyForLayout(PRBool *aIsProbablyForLayout)
|
||||
RETURN_LAYOUT_ANSWER(PR_TRUE, "2-4 columns, 10 cells or less, non-bordered");
|
||||
}
|
||||
|
||||
if (HasDescendant("embed") || HasDescendant("object") || HasDescendant("applet") || HasDescendant("iframe")) {
|
||||
if (HasDescendant(NS_LITERAL_STRING("embed")) ||
|
||||
HasDescendant(NS_LITERAL_STRING("object")) ||
|
||||
HasDescendant(NS_LITERAL_STRING("applet")) ||
|
||||
HasDescendant(NS_LITERAL_STRING("iframe"))) {
|
||||
RETURN_LAYOUT_ANSWER(PR_TRUE, "Has no borders, and has iframe, object, applet or iframe, typical of advertisements");
|
||||
}
|
||||
|
||||
|
@ -61,6 +61,7 @@ public:
|
||||
|
||||
// nsAccessible
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
|
||||
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
|
||||
|
||||
protected:
|
||||
@ -210,7 +211,16 @@ protected:
|
||||
virtual void CacheChildren();
|
||||
nsresult GetTableNode(nsIDOMNode **_retval);
|
||||
nsresult GetTableLayout(nsITableLayout **aLayoutObject);
|
||||
PRBool HasDescendant(const char *aTagName, PRBool aAllowEmpty = PR_TRUE);
|
||||
|
||||
/**
|
||||
* Return true if table has an element with the given tag name.
|
||||
*
|
||||
* @param aTagName [in] tag name of searched element
|
||||
* @param aAllowEmpty [in, optional] points if found element can be empty
|
||||
* or contain whitespace text only.
|
||||
*/
|
||||
PRBool HasDescendant(const nsAString& aTagName, PRBool aAllowEmpty = PR_TRUE);
|
||||
|
||||
#ifdef SHOW_LAYOUT_HEURISTIC
|
||||
nsAutoString mLayoutHeuristic;
|
||||
#endif
|
||||
|
@ -76,6 +76,7 @@ _TEST_FILES =\
|
||||
test_aria_role_equation.html \
|
||||
test_aria_role_grid.html \
|
||||
test_aria_roles.html \
|
||||
test_aria_roles.xul \
|
||||
test_aria_token_attrs.html \
|
||||
test_bug420863.html \
|
||||
$(warning test_childAtPoint.html temporarily disabled) \
|
||||
|
@ -109,8 +109,7 @@ function testTableIndexes(aIdentifier, aIdxes)
|
||||
* cells states.
|
||||
* @param aMsg [in] text appended before every message
|
||||
*/
|
||||
function testTableSelection(aIdentifier, aCellsArray, aMsg,
|
||||
aSkipStatesTesting) // bug 501656
|
||||
function testTableSelection(aIdentifier, aCellsArray, aMsg)
|
||||
{
|
||||
var msg = aMsg ? aMsg : "";
|
||||
var acc = getAccessible(aIdentifier, [nsIAccessibleTable]);
|
||||
@ -235,9 +234,6 @@ function testTableSelection(aIdentifier, aCellsArray, aMsg,
|
||||
msg + "Cell at index " + selCells[i] + " should be selected.");
|
||||
}
|
||||
|
||||
if (aSkipStatesTesting)
|
||||
return;
|
||||
|
||||
// selected states tests
|
||||
for (var rowIdx = 0; rowIdx < rowsCount; rowIdx++) {
|
||||
for (var colIdx = 0; colIdx < colsCount; colIdx++) {
|
||||
@ -249,7 +245,7 @@ function testTableSelection(aIdentifier, aCellsArray, aMsg,
|
||||
if (isSel)
|
||||
testStates(cell, STATE_SELECTED);
|
||||
else
|
||||
testStates(cell, 0, 0, STATE_SELECTED);
|
||||
testStates(cell, STATE_SELECTABLE, 0, STATE_SELECTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -321,8 +317,7 @@ function testUnselectTableRow(aIdentifier, aRowIdx, aCellsArray)
|
||||
/**
|
||||
* Test selectRow method of accessible table.
|
||||
*/
|
||||
function testSelectTableRow(aIdentifier, aRowIdx, aCellsArray,
|
||||
aSkipStatesTesting) // bug 501656
|
||||
function testSelectTableRow(aIdentifier, aRowIdx, aCellsArray)
|
||||
{
|
||||
var acc = getAccessible(aIdentifier, [nsIAccessibleTable]);
|
||||
if (!acc)
|
||||
@ -340,6 +335,5 @@ function testSelectTableRow(aIdentifier, aRowIdx, aCellsArray,
|
||||
|
||||
acc.selectRow(aRowIdx);
|
||||
testTableSelection(aIdentifier, aCellsArray,
|
||||
"Select " + aRowIdx + " row: ",
|
||||
aSkipStatesTesting);
|
||||
"Select " + aRowIdx + " row: ");
|
||||
}
|
||||
|
57
accessible/tests/mochitest/test_aria_roles.xul
Normal file
57
accessible/tests/mochitest/test_aria_roles.xul
Normal file
@ -0,0 +1,57 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="Accessibility Name Calculating Test.">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
function doTest()
|
||||
{
|
||||
ok(!isAccessible("presentation_label"),
|
||||
"Presentation label shouldn't be accessible.");
|
||||
ok(!isAccessible("presentation_descr"),
|
||||
"Presentation description shouldn't be accessible.");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<hbox flex="1" style="overflow: auto;">
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=494345"
|
||||
title="Do not create accessibles for XUL label or description having a role of 'presentation'">
|
||||
Mozilla Bug 494345
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox flex="1">
|
||||
<label id="presentation_label" role="presentation" value="label"/>
|
||||
<description id="presentation_descr" role="presentation" value="description"/>
|
||||
</vbox>
|
||||
|
||||
|
||||
</hbox>
|
||||
</window>
|
||||
|
@ -107,7 +107,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=410052
|
||||
testTableIndexes("tableinsane4", idxes);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// tableinsane4 (just a crazy table)
|
||||
// tableinsane5 (just a crazy table)
|
||||
idxes = [
|
||||
[ 0, 1, 2, -1, -1],
|
||||
[-1, -1, -1, -1, -1],
|
||||
@ -118,6 +118,18 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=410052
|
||||
];
|
||||
testTableIndexes("tableinsane5", idxes);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// tableinsane6 (overlapping cells, mad table)
|
||||
idxes = [
|
||||
[ 0, 1, 2, -1, -1],
|
||||
[-1, -1, -1, -1, -1],
|
||||
[ 3, 4, 5, -1, -1],
|
||||
[ 6, 6, 7, -1, -1],
|
||||
[ 8, 9, 7, -1, -1],
|
||||
[ 10, 9, 7, 11, 12]
|
||||
];
|
||||
testTableIndexes("tableinsane6", idxes);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
@ -358,5 +370,39 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=410052
|
||||
|
||||
</tbody>
|
||||
|
||||
<table border="1" id="tableinsane6" >
|
||||
<caption>overlapping cells</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>header cell 0</th>
|
||||
<th>header cell 1</th>
|
||||
<th>header cell 2</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody><tr></tr></tbody>
|
||||
<tbody></tbody>
|
||||
<tbody></tbody>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>3</td>
|
||||
<td>4</td>
|
||||
<td>5</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="2">6</td>
|
||||
<td rowspan="0">7</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>8</td>
|
||||
<td rowspan="0">9</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3">10</td>
|
||||
<td>11</td>
|
||||
<td>12</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -35,6 +35,12 @@
|
||||
// table with caption
|
||||
testAbsentAttrs("table4", attr);
|
||||
|
||||
// table with empty caption
|
||||
testAttrs("table4.2", attr, true);
|
||||
|
||||
// table with two captions
|
||||
testAbsentAttrs("table4.3", attr);
|
||||
|
||||
// table with th element
|
||||
testAbsentAttrs("table5", attr);
|
||||
|
||||
@ -166,6 +172,23 @@
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- table with empty caption -->
|
||||
<table id="table4.2">
|
||||
<caption> </caption>
|
||||
<tr>
|
||||
<td>Cell1</td><td>cell2</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- table with two captions -->
|
||||
<table id="table4.3">
|
||||
<caption> </caption>
|
||||
<tr>
|
||||
<td>Cell1</td><td>cell2</td>
|
||||
</tr>
|
||||
<caption>a caption</caption>
|
||||
</table>
|
||||
|
||||
<!-- table with th element -->
|
||||
<table id="table5">
|
||||
<tr>
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
testTableSelection("table", cellsArray);
|
||||
|
||||
testSelectTableRow("table", 0, cellsArray, true);
|
||||
testSelectTableRow("table", 0, cellsArray);
|
||||
|
||||
var accTable = getAccessible("table", [nsIAccessibleTable]);
|
||||
for (var i = 0; i < 4; i++) {
|
||||
|
@ -192,7 +192,9 @@ endif
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
OS_LIBS += $(call EXPAND_LIBNAME,comctl32 comdlg32 uuid shell32 ole32 oleaut32 version winspool)
|
||||
OS_LIBS += $(call EXPAND_LIBNAME,usp10 msimg32)
|
||||
endif
|
||||
|
||||
ifneq (,$(filter WINNT WINCE,$(OS_ARCH)))
|
||||
RCINCLUDE = splash.rc
|
||||
ifndef GNU_CC
|
||||
RCFLAGS += -DMOZ_PHOENIX -I$(srcdir)
|
||||
@ -323,7 +325,7 @@ endif
|
||||
export::
|
||||
ifndef MOZ_BRANDING_DIRECTORY
|
||||
$(NSINSTALL) -D $(DIST)/branding
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
ifneq (,$(filter WINNT WINCE,$(OS_ARCH)))
|
||||
cp $(srcdir)/firefox.ico $(DIST)/branding/firefox.ico
|
||||
cp $(srcdir)/firefox.ico $(DIST)/branding/app.ico
|
||||
cp $(srcdir)/document.ico $(DIST)/branding/document.ico
|
||||
|
@ -326,7 +326,11 @@ pref("browser.link.open_newwindow", 3);
|
||||
pref("browser.link.open_newwindow.restriction", 2);
|
||||
|
||||
// Tabbed browser
|
||||
#ifndef WINCE
|
||||
pref("browser.tabs.autoHide", false);
|
||||
#else
|
||||
pref("browser.tabs.autoHide", true);
|
||||
#endif
|
||||
pref("browser.tabs.closeWindowWithLastTab", true);
|
||||
pref("browser.tabs.warnOnClose", true);
|
||||
pref("browser.tabs.warnOnOpen", true);
|
||||
@ -847,6 +851,36 @@ pref("browser.bookmarks.editDialog.firstEditField", "namePicker");
|
||||
// base url for the wifi geolocation network provider
|
||||
pref("geo.wifi.uri", "https://www.google.com/loc/json");
|
||||
|
||||
#ifdef WINCE
|
||||
|
||||
// tweak awesomebar -- increase the delay until a search happens, and reduce
|
||||
// the amount of time spent waiting for a search result
|
||||
pref("browser.urlbar.search.chunkSize", 100);
|
||||
pref("browser.urlbar.search.timeout", 500);
|
||||
pref("browser.urlbar.delay", 1000);
|
||||
|
||||
// disable safe browsing, due to perf hit
|
||||
pref("browser.safebrowsing.enabled", false);
|
||||
|
||||
// don't check for default browser
|
||||
pref("browser.shell.checkDefaultBrowser", false);
|
||||
|
||||
// disable bfcache for memory
|
||||
pref("browser.sessionhistory.max_total_viewers", 0);
|
||||
|
||||
// tweak default content sink prefs
|
||||
pref("content.sink.interactive_deflect_count", 10); /* default 0 */
|
||||
pref("content.sink.perf_deflect_count", 50); /* default 200 */
|
||||
pref("content.sink.interactive_parse_time", 5000); /* default 3000 */
|
||||
pref("content.sink.perf_parse_time", 150000); /* default 360000 */
|
||||
pref("content.sink.pending_event_mode", 0); /* default 1 */
|
||||
pref("content.sink.event_probe_rate", 1); /* default 1 */
|
||||
pref("content.sink.interactive_time", 750000); /* default 750000 */
|
||||
pref("content.sink.initial_perf_time", 500000); /* default 2000000 */
|
||||
pref("content.sink.enable_perf_mode", 0); /* default 0; 0 == switch, 1 == stay interactive, 2 == stay perf */
|
||||
|
||||
#endif /* WINCE */
|
||||
|
||||
// Whether to use a panel that looks like an OS X sheet for customization
|
||||
#ifdef XP_MACOSX
|
||||
pref("toolbar.customization.usesheet", true);
|
||||
|
@ -92,6 +92,6 @@ DEFINES += -DCONTEXT_COPY_IMAGE_CONTENTS=1
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq (,$(BUILD_OFFICIAL)$(MOZILLA_OFFICIAL))
|
||||
ifdef MOZILLA_OFFICIAL
|
||||
DEFINES += -DOFFICIAL_BUILD=1
|
||||
endif
|
||||
|
@ -88,6 +88,7 @@
|
||||
accesskey="&sendPageCmd.accesskey;"
|
||||
command="Browser:SendLink"/>
|
||||
<menuseparator/>
|
||||
#ifndef WINCE
|
||||
<menuitem id="menu_printSetup"
|
||||
label="&printSetupCmd.label;"
|
||||
accesskey="&printSetupCmd.accesskey;"
|
||||
@ -110,6 +111,7 @@
|
||||
oncommand="BrowserImport();"/>
|
||||
#ifndef XP_MACOSX
|
||||
<menuseparator/>
|
||||
#endif
|
||||
#endif
|
||||
<menuitem id="goOfflineMenuitem"
|
||||
label="&goOfflineCmd.label;"
|
||||
@ -227,7 +229,11 @@
|
||||
accesskey="&taskbarCmd.accesskey;"
|
||||
type="checkbox"
|
||||
command="cmd_toggleTaskbar"
|
||||
#ifndef WINCE
|
||||
checked="true" />
|
||||
#else
|
||||
checked="false" />
|
||||
#endif
|
||||
<menu id="viewSidebarMenuMenu"
|
||||
label="&viewSidebarMenu.label;"
|
||||
accesskey="&viewSidebarMenu.accesskey;">
|
||||
|
@ -105,12 +105,6 @@ window[chromehidden~="toolbar"] toolbar:not(.toolbar-primary):not(.chromeclass-m
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
/* Bug 483950 - Hide domain name in status bar pending removal */
|
||||
#security-button > label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* ::::: Fullscreen pseudo-toolbar ::::: */
|
||||
#fullscr-toggler {
|
||||
display: none;
|
||||
|
@ -4156,7 +4156,6 @@ var XULBrowserWindow = {
|
||||
|
||||
// Properties used to cache security state used to update the UI
|
||||
_state: null,
|
||||
_host: undefined,
|
||||
_tooltipText: null,
|
||||
_hostChanged: false, // onLocationChange will flip this bit
|
||||
|
||||
@ -4181,11 +4180,13 @@ var XULBrowserWindow = {
|
||||
}
|
||||
this._state = aState;
|
||||
|
||||
#ifdef DEBUG
|
||||
try {
|
||||
this._host = gBrowser.contentWindow.location.host;
|
||||
} catch(ex) {
|
||||
this._host = null;
|
||||
}
|
||||
#endif
|
||||
|
||||
this._hostChanged = false;
|
||||
this._tooltipText = gBrowser.securityUI.tooltipText
|
||||
@ -4200,17 +4201,14 @@ var XULBrowserWindow = {
|
||||
wpl.STATE_SECURE_MED |
|
||||
wpl.STATE_SECURE_LOW;
|
||||
var level;
|
||||
var setHost = false;
|
||||
|
||||
switch (this._state & wpl_security_bits) {
|
||||
case wpl.STATE_IS_SECURE | wpl.STATE_SECURE_HIGH:
|
||||
level = "high";
|
||||
setHost = true;
|
||||
break;
|
||||
case wpl.STATE_IS_SECURE | wpl.STATE_SECURE_MED:
|
||||
case wpl.STATE_IS_SECURE | wpl.STATE_SECURE_LOW:
|
||||
level = "low";
|
||||
setHost = true;
|
||||
break;
|
||||
case wpl.STATE_IS_BROKEN:
|
||||
level = "broken";
|
||||
@ -4231,11 +4229,6 @@ var XULBrowserWindow = {
|
||||
gURLBar.removeAttribute("level");
|
||||
}
|
||||
|
||||
if (setHost && this._host)
|
||||
this.securityButton.setAttribute("label", this._host);
|
||||
else
|
||||
this.securityButton.removeAttribute("label");
|
||||
|
||||
this.securityButton.setAttribute("tooltiptext", this._tooltipText);
|
||||
|
||||
// Don't pass in the actual location object, since it can cause us to
|
||||
|
@ -279,6 +279,9 @@
|
||||
</tooltip>
|
||||
|
||||
<toolbox id="navigator-toolbox" class="toolbox-top" mode="icons"
|
||||
#ifdef WINCE
|
||||
defaulticonsize="small" iconsize="small"
|
||||
#endif
|
||||
defaultmode="icons">
|
||||
<!-- Menu -->
|
||||
<toolbar type="menubar" id="toolbar-menubar" class="chromeclass-menubar" customizable="true"
|
||||
@ -506,12 +509,21 @@
|
||||
|
||||
<toolbar id="nav-bar" class="toolbar-primary chromeclass-toolbar"
|
||||
toolbarname="&navbarCmd.label;" accesskey="&navbarCmd.accesskey;"
|
||||
fullscreentoolbar="true" mode="icons" iconsize="large"
|
||||
fullscreentoolbar="true" mode="icons"
|
||||
#ifdef WINCE
|
||||
iconsize="small" defaulticonsize="small"
|
||||
#else
|
||||
iconsize="large"
|
||||
#endif
|
||||
customizable="true"
|
||||
#ifdef XP_MACOSX
|
||||
defaultset="unified-back-forward-button,reload-button,stop-button,home-button,urlbar-container,search-container"
|
||||
#else
|
||||
#ifdef WINCE
|
||||
defaultset="unified-back-forward-button,reload-button,stop-button,home-button,urlbar-container,search-container,navigator-throbber,fullscreenflex,window-controls"
|
||||
#else
|
||||
defaultset="unified-back-forward-button,reload-button,stop-button,home-button,urlbar-container,search-container,fullscreenflex,window-controls"
|
||||
#endif
|
||||
#endif
|
||||
context="toolbar-context-menu">
|
||||
#ifndef XP_MACOSX
|
||||
@ -540,6 +552,9 @@
|
||||
context="toolbar-context-menu"
|
||||
defaultset="personal-bookmarks"
|
||||
toolbarname="&personalbarCmd.label;" accesskey="&personalbarCmd.accesskey;"
|
||||
#ifdef WINCE
|
||||
collapsed="true"
|
||||
#endif
|
||||
customizable="true"/>
|
||||
</toolbox>
|
||||
|
||||
@ -575,6 +590,9 @@
|
||||
<findbar browserid="content" id="FindToolbar"/>
|
||||
|
||||
<statusbar class="chromeclass-status" id="status-bar"
|
||||
#ifdef WINCE
|
||||
hidden="true"
|
||||
#endif
|
||||
ondrop="contentAreaDNDObserver.onDrop(event)">
|
||||
<statusbarpanel id="statusbar-display" label="" flex="1"/>
|
||||
<statusbarpanel class="statusbarpanel-progress" collapsed="true" id="statusbar-progresspanel">
|
||||
@ -583,7 +601,7 @@
|
||||
<statusbarpanel id="download-monitor" class="statusbarpanel-iconic-text"
|
||||
tooltiptext="&downloadMonitor2.tooltip;" hidden="true"
|
||||
command="Tools:Downloads"/>
|
||||
<statusbarpanel id="security-button" class="statusbarpanel-iconic-text"
|
||||
<statusbarpanel id="security-button" class="statusbarpanel-iconic"
|
||||
hidden="true"
|
||||
onclick="if (event.button == 0 && event.detail == 1) displaySecurityInfo();"/>
|
||||
<statusbarpanel id="page-report-button" type="menu"
|
||||
|
@ -76,7 +76,7 @@
|
||||
<row id="link-url">
|
||||
<separator orient="vertical"/>
|
||||
<label value="&link-url.label; "/>
|
||||
<textbox readonly="true" id="link-url-text"/>
|
||||
<textbox readonly="true" id="link-url-text" class="uri-element"/>
|
||||
</row>
|
||||
<row id="link-target">
|
||||
<separator orient="vertical"/>
|
||||
@ -125,7 +125,7 @@
|
||||
<row id="image-url">
|
||||
<separator orient="vertical"/>
|
||||
<label value="&image-url.label; "/>
|
||||
<textbox readonly="true" id="image-url-text"/>
|
||||
<textbox readonly="true" id="image-url-text" class="uri-element"/>
|
||||
</row>
|
||||
<row id="image-type">
|
||||
<separator orient="vertical"/>
|
||||
|
@ -180,10 +180,14 @@ nsContextMenu.prototype = {
|
||||
this.showItem("context-saveimage", this.onLoadedImage || this.onCanvas);
|
||||
this.showItem("context-savevideo", this.onVideo);
|
||||
this.showItem("context-saveaudio", this.onAudio);
|
||||
this.setItemAttr("context-savevideo", "disabled", !this.mediaURL);
|
||||
this.setItemAttr("context-saveaudio", "disabled", !this.mediaURL);
|
||||
// Send media URL (but not for canvas, since it's a big data: URL)
|
||||
this.showItem("context-sendimage", this.onImage);
|
||||
this.showItem("context-sendvideo", this.onVideo);
|
||||
this.showItem("context-sendaudio", this.onAudio);
|
||||
this.setItemAttr("context-sendvideo", "disabled", !this.mediaURL);
|
||||
this.setItemAttr("context-sendaudio", "disabled", !this.mediaURL);
|
||||
},
|
||||
|
||||
initViewItems: function CM_initViewItems() {
|
||||
@ -231,6 +235,7 @@ nsContextMenu.prototype = {
|
||||
(!this.onStandaloneImage || this.inFrame)) || this.onCanvas);
|
||||
|
||||
this.showItem("context-viewvideo", this.onVideo);
|
||||
this.setItemAttr("context-viewvideo", "disabled", !this.mediaURL);
|
||||
|
||||
// View background image depends on whether there is one.
|
||||
this.showItem("context-viewbgimage", shouldShow);
|
||||
@ -380,6 +385,8 @@ nsContextMenu.prototype = {
|
||||
this.showItem("context-copyimage", this.onImage);
|
||||
this.showItem("context-copyvideourl", this.onVideo);
|
||||
this.showItem("context-copyaudiourl", this.onAudio);
|
||||
this.setItemAttr("context-copyvideourl", "disabled", !this.mediaURL);
|
||||
this.setItemAttr("context-copyaudiourl", "disabled", !this.mediaURL);
|
||||
this.showItem("context-sep-copyimage", this.onImage ||
|
||||
this.onVideo || this.onAudio);
|
||||
},
|
||||
@ -398,6 +405,16 @@ nsContextMenu.prototype = {
|
||||
this.showItem("context-media-unmute", onMedia && this.target.muted);
|
||||
this.showItem("context-media-showcontrols", onMedia && !this.target.controls)
|
||||
this.showItem("context-media-hidecontrols", onMedia && this.target.controls)
|
||||
// Disable them when there isn't a valid media source loaded.
|
||||
if (onMedia) {
|
||||
var hasError = (this.target.error != null);
|
||||
this.setItemAttr("context-media-play", "disabled", hasError);
|
||||
this.setItemAttr("context-media-pause", "disabled", hasError);
|
||||
this.setItemAttr("context-media-mute", "disabled", hasError);
|
||||
this.setItemAttr("context-media-unmute", "disabled", hasError);
|
||||
this.setItemAttr("context-media-showcontrols", "disabled", hasError);
|
||||
this.setItemAttr("context-media-hidecontrols", "disabled", hasError);
|
||||
}
|
||||
this.showItem("context-media-sep-commands", onMedia);
|
||||
},
|
||||
|
||||
@ -468,11 +485,11 @@ nsContextMenu.prototype = {
|
||||
}
|
||||
else if (this.target instanceof HTMLVideoElement) {
|
||||
this.onVideo = true;
|
||||
this.mediaURL = this.target.currentSrc;
|
||||
this.mediaURL = this.target.currentSrc || this.target.src;
|
||||
}
|
||||
else if (this.target instanceof HTMLAudioElement) {
|
||||
this.onAudio = true;
|
||||
this.mediaURL = this.target.currentSrc;
|
||||
this.mediaURL = this.target.currentSrc || this.target.src;
|
||||
}
|
||||
else if (this.target instanceof HTMLInputElement ) {
|
||||
this.onTextInput = this.isTargetATextBox(this.target);
|
||||
|
@ -10,7 +10,12 @@
|
||||
-moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-arrowscrollbox");
|
||||
}
|
||||
|
||||
.tab-close-button, .tabs-closebutton {
|
||||
.tabs-alltabs-popup {
|
||||
-moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-alltabs-popup");
|
||||
}
|
||||
|
||||
.tab-close-button,
|
||||
.tabs-closebutton {
|
||||
-moz-binding: url("chrome://browser/content/tabbrowser.xml#tabbrowser-close-tab-button");
|
||||
}
|
||||
|
||||
|
@ -941,12 +941,6 @@
|
||||
if (evt.target != this.contentDocument)
|
||||
return;
|
||||
|
||||
var i = 0;
|
||||
for ( ; i < this.parentNode.parentNode.childNodes.length; i++) {
|
||||
if (this.parentNode.parentNode.childNodes[i].firstChild == this)
|
||||
break;
|
||||
}
|
||||
|
||||
var tabBrowser = this.parentNode.parentNode.parentNode.parentNode;
|
||||
|
||||
var tab = document.getAnonymousElementByAttribute(tabBrowser, "linkedpanel", this.parentNode.id);
|
||||
@ -1195,16 +1189,13 @@
|
||||
|
||||
this.mTabContainer.appendChild(t);
|
||||
|
||||
if (document.defaultView
|
||||
.getComputedStyle(this.mTabContainer, "")
|
||||
.direction == "rtl") {
|
||||
if (this.tabContainer.mTabstrip._isRTLScrollbox) {
|
||||
/* In RTL UI, the tab is visually added to the left side of the
|
||||
* tabstrip. This means the tabstip has to be scrolled back in
|
||||
* order to make sure the same set of tabs is visible before and
|
||||
* after the new tab is added */
|
||||
|
||||
this.mTabContainer.mTabstrip.scrollBoxObject
|
||||
.scrollBy(this.mTabContainer.firstChild.boxObject.width, 0);
|
||||
this.tabContainer.mTabstrip.scrollByPixels(this.mTabs[0].clientWidth);
|
||||
}
|
||||
|
||||
// invalidate cache, because mTabContainer is about to change
|
||||
@ -1283,21 +1274,21 @@
|
||||
}
|
||||
}
|
||||
|
||||
// |setTimeout| here to ensure we're post reflow
|
||||
var _delayedUpdate = function(aTabContainer) {
|
||||
aTabContainer.adjustTabstrip();
|
||||
this.tabContainer.adjustTabstrip();
|
||||
|
||||
// Do this asynchronically, as we don't know yet if the tab
|
||||
// will be selected.
|
||||
setTimeout(function (aTabContainer) {
|
||||
if (aTabContainer.selectedItem != t)
|
||||
aTabContainer._notifyBackgroundTab(t);
|
||||
}, 0, this.tabContainer);
|
||||
|
||||
// XXXmano: this is a temporary workaround to bug 343585
|
||||
// We need to manually update the scroll buttons disabled state
|
||||
// if a tab was inserted to the overflow area or removed from it
|
||||
// without any scrolling and when the tabbar has already
|
||||
// overflowed.
|
||||
aTabContainer.mTabstrip._updateScrollButtonsDisabledState();
|
||||
}
|
||||
setTimeout(_delayedUpdate, 0, this.mTabContainer);
|
||||
// XXXmano: this is a temporary workaround for bug 345399
|
||||
// We need to manually update the scroll buttons disabled state
|
||||
// if a tab was inserted to the overflow area or removed from it
|
||||
// without any scrolling and when the tabbar has already
|
||||
// overflowed.
|
||||
this.tabContainer.mTabstrip._updateScrollButtonsDisabledState();
|
||||
|
||||
// Dispatch a new tab notification. We do this once we're
|
||||
// entirely done, so that things are in a consistent state
|
||||
@ -1505,15 +1496,12 @@
|
||||
while (this._removingTabs.length)
|
||||
this._endRemoveTab([this._removingTabs[0], false]);
|
||||
} else if (!this._windowIsClosing) {
|
||||
// see notes in addTab
|
||||
function _delayedUpdate(aTabContainer) {
|
||||
aTabContainer.adjustTabstrip();
|
||||
aTabContainer.mTabstrip._updateScrollButtonsDisabledState();
|
||||
};
|
||||
setTimeout(_delayedUpdate, 0, this.tabContainer);
|
||||
|
||||
if (aNewTab && gURLBar)
|
||||
gURLBar.focus();
|
||||
|
||||
this.tabContainer.adjustTabstrip();
|
||||
// workaround for bug 345399
|
||||
this.tabContainer.mTabstrip._updateScrollButtonsDisabledState();
|
||||
}
|
||||
|
||||
// We're going to remove the tab and the browser now.
|
||||
@ -1977,8 +1965,9 @@
|
||||
var newIndex = this.getNewIndex(aEvent);
|
||||
var ib = this.mTabDropIndicatorBar;
|
||||
var ind = ib.firstChild;
|
||||
var tabStripBoxObject = tabStrip.scrollBoxObject;
|
||||
var minMargin = tabStripBoxObject.x - this.boxObject.x;
|
||||
var scrollRect = tabStrip.scrollClientRect;
|
||||
var rect = this.getBoundingClientRect();
|
||||
var minMargin = scrollRect.left - rect.left;
|
||||
// make sure we don't place the tab drop indicator past the
|
||||
// edge, or the containing box will flex and stretch
|
||||
// the tab drop indicator bar, which will flex the url bar.
|
||||
@ -1986,13 +1975,13 @@
|
||||
// just use first value if you can figure out how to get
|
||||
// the tab drop indicator to crop instead of flex and stretch
|
||||
// the tab drop indicator bar.
|
||||
var maxMargin = Math.min(minMargin + tabStripBoxObject.width,
|
||||
ib.boxObject.x + ib.boxObject.width -
|
||||
ind.boxObject.width);
|
||||
var maxMargin = Math.min(minMargin + scrollRect.width,
|
||||
ib.getBoundingClientRect().right -
|
||||
ind.clientWidth);
|
||||
if (!ltr)
|
||||
[minMargin, maxMargin] = [this.boxObject.width - maxMargin,
|
||||
this.boxObject.width - minMargin];
|
||||
var newMargin, tabBoxObject;
|
||||
[minMargin, maxMargin] = [this.clientWidth - maxMargin,
|
||||
this.clientWidth - minMargin];
|
||||
var newMargin;
|
||||
if (pixelsToScroll) {
|
||||
// if we are scrolling, put the drop indicator at the edge
|
||||
// so that it doesn't jump while scrolling
|
||||
@ -2000,21 +1989,18 @@
|
||||
}
|
||||
else {
|
||||
if (newIndex == this.mTabs.length) {
|
||||
tabBoxObject = this.mTabs[newIndex-1].boxObject;
|
||||
let tabRect = this.mTabs[newIndex-1].getBoundingClientRect();
|
||||
if (ltr)
|
||||
newMargin = tabBoxObject.screenX - this.boxObject.screenX
|
||||
+ tabBoxObject.width;
|
||||
newMargin = tabRect.right - rect.left;
|
||||
else
|
||||
newMargin = this.boxObject.screenX - tabBoxObject.screenX
|
||||
+ this.boxObject.width;
|
||||
newMargin = rect.right - tabRect.left;
|
||||
}
|
||||
else {
|
||||
tabBoxObject = this.mTabs[newIndex].boxObject;
|
||||
let tabRect = this.mTabs[newIndex].getBoundingClientRect();
|
||||
if (ltr)
|
||||
newMargin = tabBoxObject.screenX - this.boxObject.screenX;
|
||||
newMargin = tabRect.left - rect.left;
|
||||
else
|
||||
newMargin = this.boxObject.screenX - tabBoxObject.screenX
|
||||
+ this.boxObject.width - tabBoxObject.width;
|
||||
newMargin = rect.right - tabRect.right;
|
||||
}
|
||||
// ensure we never place the drop indicator beyond our limits
|
||||
if (newMargin < minMargin)
|
||||
@ -2245,7 +2231,7 @@
|
||||
this.mTabContainer.childNodes[i]._selected = false;
|
||||
}
|
||||
this.mCurrentTab._selected = true;
|
||||
this.mTabContainer.mTabstrip.scrollBoxObject.ensureElementIsVisible(this.mCurrentTab);
|
||||
this.mTabContainer.mTabstrip.ensureElementIsVisible(this.mCurrentTab, false);
|
||||
|
||||
var evt = document.createEvent("UIEvents");
|
||||
evt.initUIEvent("TabMove", true, false, window, oldPosition);
|
||||
@ -2804,7 +2790,7 @@
|
||||
this._scrollButtonDownBox.collapsed = false;
|
||||
this._scrollButtonDownBoxAnimate.collapsed = false;
|
||||
#endif
|
||||
this.scrollBoxObject.ensureElementIsVisible(tabs.selectedItem);
|
||||
this.ensureElementIsVisible(tabs.selectedItem, false);
|
||||
]]></handler>
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
@ -3003,10 +2989,7 @@
|
||||
this.setAttribute("closebuttons", "activetab");
|
||||
break;
|
||||
case 1:
|
||||
var width = this.firstChild.boxObject.width;
|
||||
// 0 width is an invalid value and indicates
|
||||
// an item without display, so ignore.
|
||||
if (width > this.mTabClipWidth || width == 0)
|
||||
if (this.firstChild.getBoundingClientRect().width > this.mTabClipWidth)
|
||||
this.setAttribute("closebuttons", "alltabs");
|
||||
else
|
||||
this.setAttribute("closebuttons", "activetab");
|
||||
@ -3048,15 +3031,9 @@
|
||||
// of the tabstrip, we need to ensure that we stay
|
||||
// completely scrolled to the right side
|
||||
var tabStrip = this.mTabstrip;
|
||||
var scrollPos = {};
|
||||
tabStrip.scrollBoxObject.getPosition(scrollPos, {});
|
||||
var scrolledSize = {};
|
||||
tabStrip.scrollBoxObject.getScrolledSize(scrolledSize, {});
|
||||
|
||||
if (scrollPos.value + tabStrip.boxObject.width >=
|
||||
scrolledSize.value) {
|
||||
if (tabStrip.scrollPosition + tabStrip.scrollClientSize >=
|
||||
tabStrip.scrollSize)
|
||||
tabStrip.scrollByPixels(-1);
|
||||
}
|
||||
} catch (e) {}
|
||||
]]></body>
|
||||
</method>
|
||||
@ -3078,6 +3055,11 @@
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<field name="mAllTabsPopup">
|
||||
document.getAnonymousElementByAttribute(this,
|
||||
"anonid", "alltabs-popup");
|
||||
</field>
|
||||
|
||||
<field name="mAllTabsBoxAnimate">
|
||||
document.getAnonymousElementByAttribute(this,
|
||||
"anonid",
|
||||
@ -3120,30 +3102,26 @@
|
||||
<method name="_notifyBackgroundTab">
|
||||
<parameter name="aTab"/>
|
||||
<body><![CDATA[
|
||||
var tsbo = this.mTabstrip.scrollBoxObject;
|
||||
var tsboStart = tsbo.screenX;
|
||||
var tsboEnd = tsboStart + tsbo.width;
|
||||
|
||||
var ctbo = aTab.boxObject;
|
||||
var ctboStart = ctbo.screenX;
|
||||
var ctboEnd = ctboStart + ctbo.width;
|
||||
var scrollRect = this.mTabstrip.scrollClientRect;
|
||||
var tab = aTab.getBoundingClientRect();
|
||||
|
||||
// Is the new tab already completely visible?
|
||||
if (tsboStart <= ctboStart && ctboEnd <= tsboEnd)
|
||||
if (scrollRect.left <= tab.left && tab.right <= scrollRect.right)
|
||||
return;
|
||||
|
||||
if (this.mTabstrip.smoothScroll) {
|
||||
var selStart = this.selectedItem.boxObject.screenX;
|
||||
var selEnd = selStart + this.selectedItem.boxObject.width;
|
||||
let selected = this.selectedItem.getBoundingClientRect();
|
||||
|
||||
// Can we make both the new tab and the selected tab completely visible?
|
||||
if (Math.max(ctboEnd - selStart, selEnd - ctboStart) <= tsbo.width) {
|
||||
if (Math.max(tab.right - selected.left, selected.right - tab.left) <=
|
||||
scrollRect.width) {
|
||||
this.mTabstrip.ensureElementIsVisible(aTab);
|
||||
return;
|
||||
}
|
||||
|
||||
this.mTabstrip._smoothScrollByPixels(this.mTabstrip._isRTLScrollbox ?
|
||||
selEnd - tsboEnd : selStart - tsboStart);
|
||||
selected.right - scrollRect.right :
|
||||
selected.left - scrollRect.left);
|
||||
}
|
||||
|
||||
// start the flash timer
|
||||
@ -3270,6 +3248,7 @@
|
||||
|
||||
<implementation>
|
||||
<field name="mOverCloseButton">false</field>
|
||||
<field name="mCorrespondingMenuitem">null</field>
|
||||
</implementation>
|
||||
|
||||
<handlers>
|
||||
@ -3311,4 +3290,213 @@
|
||||
</handlers>
|
||||
</binding>
|
||||
|
||||
<binding id="tabbrowser-alltabs-popup"
|
||||
extends="chrome://global/content/bindings/popup.xml#popup">
|
||||
<implementation implements="nsIDOMEventListener">
|
||||
<field name="_xulWindow">
|
||||
null
|
||||
</field>
|
||||
|
||||
<constructor><![CDATA[
|
||||
// We cannot cache the XULBrowserWindow object itself since it might
|
||||
// be set after this binding is constructed.
|
||||
try {
|
||||
this._xulWindow =
|
||||
window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIWebNavigation)
|
||||
.QueryInterface(Components.interfaces.nsIDocShellTreeItem)
|
||||
.treeOwner
|
||||
.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIXULWindow);
|
||||
}
|
||||
catch(ex) { }
|
||||
]]></constructor>
|
||||
|
||||
<method name="_menuItemOnCommand">
|
||||
<parameter name="aEvent"/>
|
||||
|
||||
<body><![CDATA[
|
||||
var tabcontainer = document.getBindingParent(this);
|
||||
tabcontainer.selectedItem = aEvent.target.tab;
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="_tabOnAttrModified">
|
||||
<parameter name="aEvent"/>
|
||||
<body><![CDATA[
|
||||
var menuItem = aEvent.target.mCorrespondingMenuitem;
|
||||
if (menuItem) {
|
||||
var attrName = aEvent.attrName;
|
||||
switch (attrName) {
|
||||
case "label":
|
||||
case "crop":
|
||||
case "busy":
|
||||
case "image":
|
||||
case "selected":
|
||||
if (aEvent.attrChange == aEvent.REMOVAL)
|
||||
menuItem.removeAttribute(attrName);
|
||||
else
|
||||
menuItem.setAttribute(attrName, aEvent.newValue);
|
||||
}
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="_tabOnTabClose">
|
||||
<parameter name="aEvent"/>
|
||||
|
||||
<body><![CDATA[
|
||||
var menuItem = aEvent.target.mCorrespondingMenuitem;
|
||||
if (menuItem)
|
||||
this.removeChild(menuItem);
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="handleEvent">
|
||||
<parameter name="aEvent"/>
|
||||
<body><![CDATA[
|
||||
if (!aEvent.isTrusted)
|
||||
return;
|
||||
|
||||
switch (aEvent.type) {
|
||||
case "command":
|
||||
this._menuItemOnCommand(aEvent);
|
||||
break;
|
||||
case "DOMAttrModified":
|
||||
this._tabOnAttrModified(aEvent);
|
||||
break;
|
||||
case "TabClose":
|
||||
this._tabOnTabClose(aEvent);
|
||||
break;
|
||||
case "TabOpen":
|
||||
this._createTabMenuItem(aEvent.originalTarget);
|
||||
break;
|
||||
case "scroll":
|
||||
this._updateTabsVisibilityStatus();
|
||||
break;
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="_updateTabsVisibilityStatus">
|
||||
<body><![CDATA[
|
||||
var tabContainer = document.getBindingParent(this);
|
||||
// We don't want menu item decoration unless there is overflow.
|
||||
if (tabContainer.getAttribute("overflow") != "true")
|
||||
return;
|
||||
|
||||
var tabstripBO = tabContainer.mTabstrip.scrollBoxObject;
|
||||
for (var i = 0; i < this.childNodes.length; i++) {
|
||||
var curTabBO = this.childNodes[i].tab.boxObject;
|
||||
if (curTabBO.screenX >= tabstripBO.screenX &&
|
||||
curTabBO.screenX + curTabBO.width <= tabstripBO.screenX + tabstripBO.width)
|
||||
this.childNodes[i].setAttribute("tabIsVisible", "true");
|
||||
else
|
||||
this.childNodes[i].removeAttribute("tabIsVisible");
|
||||
}
|
||||
]]></body>
|
||||
|
||||
</method>
|
||||
|
||||
<method name="_createTabMenuItem">
|
||||
<parameter name="aTab"/>
|
||||
<body><![CDATA[
|
||||
var menuItem = document.createElementNS(
|
||||
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
|
||||
"menuitem");
|
||||
|
||||
menuItem.setAttribute("class", "menuitem-iconic alltabs-item");
|
||||
|
||||
menuItem.setAttribute("label", aTab.label);
|
||||
menuItem.setAttribute("crop", aTab.getAttribute("crop"));
|
||||
menuItem.setAttribute("image", aTab.getAttribute("image"));
|
||||
|
||||
if (aTab.hasAttribute("busy"))
|
||||
menuItem.setAttribute("busy", aTab.getAttribute("busy"));
|
||||
if (aTab.selected)
|
||||
menuItem.setAttribute("selected", "true");
|
||||
|
||||
// Keep some attributes of the menuitem in sync with its
|
||||
// corresponding tab (e.g. the tab label)
|
||||
aTab.mCorrespondingMenuitem = menuItem;
|
||||
aTab.addEventListener("DOMAttrModified", this, false);
|
||||
aTab.addEventListener("TabClose", this, false);
|
||||
menuItem.tab = aTab;
|
||||
menuItem.addEventListener("command", this, false);
|
||||
|
||||
this.appendChild(menuItem);
|
||||
return menuItem;
|
||||
]]></body>
|
||||
</method>
|
||||
</implementation>
|
||||
|
||||
<handlers>
|
||||
<handler event="popupshowing">
|
||||
|
||||
<![CDATA[
|
||||
// set up the menu popup
|
||||
var tabcontainer = document.getBindingParent(this);
|
||||
var tabs = tabcontainer.childNodes;
|
||||
|
||||
// Listen for changes in the tab bar.
|
||||
var tabbrowser = document.getBindingParent(tabcontainer);
|
||||
tabbrowser.addEventListener("TabOpen", this, false);
|
||||
tabcontainer.mTabstrip.addEventListener("scroll", this, false);
|
||||
|
||||
// if an animation is in progress and the user
|
||||
// clicks on the "all tabs" button, stop the animation
|
||||
tabcontainer._stopAnimation();
|
||||
|
||||
for (var i = 0; i < tabs.length; i++) {
|
||||
this._createTabMenuItem(tabs[i]);
|
||||
}
|
||||
this._updateTabsVisibilityStatus();
|
||||
]]></handler>
|
||||
|
||||
<handler event="popuphiding">
|
||||
<![CDATA[
|
||||
// clear out the menu popup and remove the listeners
|
||||
while (this.hasChildNodes()) {
|
||||
var menuItem = this.lastChild;
|
||||
menuItem.removeEventListener("command", this, false);
|
||||
menuItem.tab.removeEventListener("DOMAttrModified", this, false);
|
||||
menuItem.tab.removeEventListener("TabClose", this, false);
|
||||
menuItem.tab.mCorrespondingMenuitem = null;
|
||||
this.removeChild(menuItem);
|
||||
}
|
||||
var tabcontainer = document.getBindingParent(this);
|
||||
tabcontainer.mTabstrip.removeEventListener("scroll", this, false);
|
||||
document.getBindingParent(tabcontainer).removeEventListener("TabOpen", this, false);
|
||||
]]></handler>
|
||||
|
||||
<handler event="DOMMenuItemActive">
|
||||
<![CDATA[
|
||||
if (!this._xulWindow || !this._xulWindow.XULBrowserWindow)
|
||||
return;
|
||||
|
||||
var tab = event.target.tab;
|
||||
if (tab) {
|
||||
var statusText = tab.linkedBrowser.currentURI.spec;
|
||||
if (statusText == "about:blank") {
|
||||
// XXXhack: Passing a space here (and not "")
|
||||
// to make sure the the browser implementation would
|
||||
// still consider it a hovered link.
|
||||
statusText = " ";
|
||||
}
|
||||
|
||||
this._xulWindow.XULBrowserWindow.setOverLink(statusText, null);
|
||||
}
|
||||
]]></handler>
|
||||
|
||||
<handler event="DOMMenuItemInactive">
|
||||
<![CDATA[
|
||||
if (!this._xulWindow || !this._xulWindow.XULBrowserWindow)
|
||||
return;
|
||||
|
||||
this._xulWindow.XULBrowserWindow.setOverLink("", null);
|
||||
]]></handler>
|
||||
|
||||
</handlers>
|
||||
</binding>
|
||||
|
||||
</bindings>
|
||||
|
@ -43,13 +43,15 @@ relativesrcdir = browser/base/content/test
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_TEST_FILES = test_feed_discovery.html \
|
||||
_TEST_FILES = \
|
||||
test_feed_discovery.html \
|
||||
feed_discovery.html \
|
||||
test_bug395533.html \
|
||||
bug395533-data.txt \
|
||||
test_contextmenu.html \
|
||||
subtst_contextmenu.html \
|
||||
ctxmenu-image.png \
|
||||
video.ogg \
|
||||
test_offlineNotification.html \
|
||||
offlineChild.html \
|
||||
offlineChild.cacheManifest \
|
||||
@ -63,7 +65,6 @@ _TEST_FILES = test_feed_discovery.html \
|
||||
$(NULL)
|
||||
|
||||
# The following tests are disabled because they are unreliable:
|
||||
# browser_bug321000.js is bug 474081
|
||||
# browser_bug423833.js is bug 428712
|
||||
# browser_sanitize-download-history.js is bug 432425
|
||||
#
|
||||
@ -71,7 +72,9 @@ _TEST_FILES = test_feed_discovery.html \
|
||||
# back to the clear recent history dialog (santize.xul), if it ever is (bug
|
||||
# 480169)
|
||||
|
||||
_BROWSER_FILES = browser_sanitize-timespans.js \
|
||||
_BROWSER_FILES = \
|
||||
browser_bug321000.js \
|
||||
browser_sanitize-timespans.js \
|
||||
browser_bug405137.js \
|
||||
browser_bug409481.js \
|
||||
browser_bug413915.js \
|
||||
|
@ -1,48 +1,72 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: sw=2 ts=2 et lcs=trail\:.,tab\:>~ :
|
||||
* ***** 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 Firefox Browser Test Code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ted Mielczarek <ted.mielczarek@gmail.com> (Original Author)
|
||||
* Marco Bonardo <mak77@bonardo.net>
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
const Cc = Components.classes;
|
||||
|
||||
const kUrlBarElm = document.getElementById('urlbar');
|
||||
const kSearchBarElm = document.getElementById('searchbar');
|
||||
const kTestString = " hello hello \n world\nworld ";
|
||||
|
||||
function testPaste(name, element, expected) {
|
||||
element.focus();
|
||||
listener.expected = expected;
|
||||
listener.name = name;
|
||||
// Pasting is async because the Accel+V codepath ends up going through
|
||||
// DocumentViewerImpl::FireClipboardEvent.
|
||||
EventUtils.synthesizeKey("v", { accelKey: true });
|
||||
}
|
||||
var gTests = [
|
||||
|
||||
var listener = {
|
||||
expected: "",
|
||||
name: "",
|
||||
handleEvent: function(event) {
|
||||
var element = event.target;
|
||||
is(element.value, this.expected, this.name);
|
||||
switch (element) {
|
||||
case kUrlBarElm:
|
||||
continue_test();
|
||||
case kSearchBarElm:
|
||||
finish_test();
|
||||
}
|
||||
}
|
||||
}
|
||||
{ desc: "Urlbar strips newlines and surrounding whitespace",
|
||||
element: gURLBar,
|
||||
expected: kTestString.replace(/\s*\n\s*/g,'')
|
||||
},
|
||||
|
||||
// test bug 23485 and bug 321000
|
||||
// urlbar should strip newlines,
|
||||
// search bar should replace newlines with spaces
|
||||
{ desc: "Searchbar replaces newlines with spaces",
|
||||
element: document.getElementById('searchbar'),
|
||||
expected: kTestString.replace('\n',' ','g')
|
||||
},
|
||||
|
||||
];
|
||||
|
||||
// Test for bug 23485 and bug 321000.
|
||||
// Urlbar should strip newlines,
|
||||
// search bar should replace newlines with spaces.
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
// register listeners
|
||||
kUrlBarElm.addEventListener("input", listener, true);
|
||||
kSearchBarElm.addEventListener("input", listener, true);
|
||||
|
||||
// Put a multi-line string in the clipboard
|
||||
Components.classes["@mozilla.org/widget/clipboardhelper;1"]
|
||||
.getService(Components.interfaces.nsIClipboardHelper)
|
||||
.copyString(kTestString);
|
||||
// Put a multi-line string in the clipboard.
|
||||
info("About to put a string in clipboard");
|
||||
Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper)
|
||||
.copyString(kTestString);
|
||||
|
||||
// Setting the clipboard value is an async OS operation, so we need to poll
|
||||
// the clipboard for valid data before going on.
|
||||
@ -51,53 +75,84 @@ function test() {
|
||||
|
||||
var runCount = 0;
|
||||
function poll_clipboard() {
|
||||
// Poll for a maximum of 5s
|
||||
// Poll for a maximum of 5s (each run happens after 100ms).
|
||||
if (++runCount > 50) {
|
||||
// Log the failure
|
||||
// Log the failure.
|
||||
ok(false, "Timed out while polling clipboard for pasted data");
|
||||
// Cleanup and interrupt the test
|
||||
// Cleanup and interrupt the test.
|
||||
finish_test();
|
||||
return;
|
||||
}
|
||||
|
||||
var clip = Components.classes["@mozilla.org/widget/clipboard;1"].
|
||||
getService(Components.interfaces.nsIClipboard);
|
||||
var trans = Components.classes["@mozilla.org/widget/transferable;1"].
|
||||
createInstance(Components.interfaces.nsITransferable);
|
||||
info("Polling clipboard cycle " + runCount);
|
||||
var clip = Cc["@mozilla.org/widget/clipboard;1"].
|
||||
getService(Ci.nsIClipboard);
|
||||
var trans = Cc["@mozilla.org/widget/transferable;1"].
|
||||
createInstance(Ci.nsITransferable);
|
||||
trans.addDataFlavor("text/unicode");
|
||||
var str = new Object();
|
||||
try {
|
||||
// This code could throw if the clipboard is not set
|
||||
clip.getData(trans,clip.kGlobalClipboard);
|
||||
trans.getTransferData("text/unicode",str,{});
|
||||
str = str.value.QueryInterface(Components.interfaces.nsISupportsString);
|
||||
} catch (ex) {}
|
||||
// This code could throw if the clipboard is not set yet.
|
||||
clip.getData(trans, clip.kGlobalClipboard);
|
||||
trans.getTransferData("text/unicode", str, {});
|
||||
str = str.value.QueryInterface(Ci.nsISupportsString);
|
||||
}
|
||||
catch(ex) {}
|
||||
|
||||
if (kTestString == str) {
|
||||
testPaste('urlbar strips newlines and surrounding whitespace',
|
||||
kUrlBarElm,
|
||||
kTestString.replace(/\s*\n\s*/g,''));
|
||||
next_test();
|
||||
}
|
||||
else
|
||||
setTimeout(poll_clipboard, 100);
|
||||
}
|
||||
|
||||
function continue_test() {
|
||||
testPaste('searchbar replaces newlines with spaces',
|
||||
kSearchBarElm,
|
||||
kTestString.replace('\n',' ','g'));
|
||||
function next_test() {
|
||||
if (gTests.length) {
|
||||
var currentTest = gTests.shift();
|
||||
test_paste(currentTest);
|
||||
}
|
||||
else {
|
||||
// No more tests to run.
|
||||
// Clear the clipboard, emptyClipboard would not clear the native one, so
|
||||
// we are setting it to an empty string.
|
||||
Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper)
|
||||
.copyString("");
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
function finish_test() {
|
||||
kUrlBarElm.removeEventListener("input", listener, true);
|
||||
kSearchBarElm.removeEventListener("input", listener, true);
|
||||
// Clear the clipboard, emptyClipboard would not clear the native one, so
|
||||
// setting it to an empty string.
|
||||
Components.classes["@mozilla.org/widget/clipboardhelper;1"]
|
||||
.getService(Components.interfaces.nsIClipboardHelper)
|
||||
.copyString("");
|
||||
// Clear fields
|
||||
kUrlBarElm.value="";
|
||||
kSearchBarElm.value="";
|
||||
finish();
|
||||
function test_paste(aCurrentTest) {
|
||||
var element = aCurrentTest.element;
|
||||
|
||||
// Register input listener.
|
||||
var inputListener = {
|
||||
test: aCurrentTest,
|
||||
handleEvent: function(event) {
|
||||
var element = event.target;
|
||||
element.removeEventListener("input", this, false);
|
||||
|
||||
is(element.value, this.test.expected, this.test.desc);
|
||||
|
||||
// Clear the field and go to next test.
|
||||
element.value = "";
|
||||
setTimeout(next_test, 0);
|
||||
}
|
||||
}
|
||||
element.addEventListener("input", inputListener, false);
|
||||
|
||||
// Focus the window.
|
||||
window.focus();
|
||||
|
||||
// Focus the element and wait for focus event.
|
||||
info("About to focus " + element.id);
|
||||
element.addEventListener("focus", function() {
|
||||
element.removeEventListener("focus", arguments.callee, false);
|
||||
executeSoon(function() {
|
||||
// Pasting is async because the Accel+V codepath ends up going through
|
||||
// DocumentViewerImpl::FireClipboardEvent.
|
||||
info("Pasting into " + element.id);
|
||||
EventUtils.synthesizeKey("v", { accelKey: true });
|
||||
});
|
||||
}, false);
|
||||
element.focus();
|
||||
}
|
||||
|
@ -12,7 +12,11 @@ Browser context menu subtest.
|
||||
<input id="test-input"><br>
|
||||
<img id="test-image" src="ctxmenu-image.png">
|
||||
<canvas id="test-canvas" width="100" height="100" style="background-color: blue"></canvas>
|
||||
<video id="test-video" width="100" height="100" style="background-color: orange"></video>
|
||||
<video id="test-video-ok" src="video.ogg" width="100" height="100" style="background-color: green"></video>
|
||||
<video id="test-video-bad" src="bogus.duh" width="100" height="100" style="background-color: orange"></video>
|
||||
<video id="test-video-bad2" width="100" height="100" style="background-color: yellow">
|
||||
<source src="bogus.duh" type="video/durrrr;">
|
||||
</video>
|
||||
<iframe id="test-iframe" width="98" height="98" style="border: 1px solid black"></iframe>
|
||||
|
||||
</body>
|
||||
|
@ -76,9 +76,11 @@ function getVisibleMenuItems(aMenu) {
|
||||
else
|
||||
accessKeys[key] = item.id
|
||||
items.push(item.id);
|
||||
items.push(!item.disabled);
|
||||
} else if (item.nodeName == "menuseparator") {
|
||||
ok(true, "--- seperator id is " + item.id);
|
||||
items.push("---");
|
||||
items.push(null);
|
||||
} else if (item.nodeName == "menu") {
|
||||
ok(item.id, "child menu #" + i + " has an ID");
|
||||
ok(key, "menu has an access key");
|
||||
@ -87,9 +89,11 @@ function getVisibleMenuItems(aMenu) {
|
||||
else
|
||||
accessKeys[key] = item.id
|
||||
items.push(item.id);
|
||||
items.push(!item.disabled);
|
||||
// Add a dummy item to that the indexes in checkMenu are the same
|
||||
// for expectedItems and actualItems.
|
||||
items.push([]);
|
||||
items.push(null);
|
||||
} else {
|
||||
ok(false, "child #" + i + " of menu ID " + aMenu.id +
|
||||
" has an unknown type (" + item.nodeName + ")");
|
||||
@ -105,24 +109,37 @@ function checkContextMenu(expectedItems) {
|
||||
|
||||
/*
|
||||
* checkMenu - checks to see if the specified <menupopup> contains the
|
||||
* expected items, as specified by an array of element IDs. To check the
|
||||
* contents of a submenu, include a nested array after the expected <menu> ID.
|
||||
* For example: ["foo, "submenu", ["sub1", "sub2"], "bar"]
|
||||
* expected items and state.
|
||||
* expectedItems is a array of (1) item IDs and (2) a boolean specifying if
|
||||
* the item is enabled or not (or null to ignore it). Submenus can be checked
|
||||
* by providing a nested array entry after the expected <menu> ID.
|
||||
* For example: ["blah", true, // item enabled
|
||||
* "submenu", null, // submenu
|
||||
* ["sub1", true, // submenu contents
|
||||
* "sub2", false], null, // submenu contents
|
||||
* "lol", false] // item disabled
|
||||
*
|
||||
*/
|
||||
function checkMenu(menu, expectedItems) {
|
||||
var actualItems = getVisibleMenuItems(menu);
|
||||
//ok(false, "Items are: " + actualItems);
|
||||
for (var i = 0; i < expectedItems.length; i++) {
|
||||
if (expectedItems[i] instanceof Array) {
|
||||
for (var i = 0; i < expectedItems.length; i+=2) {
|
||||
var actualItem = actualItems[i];
|
||||
var actualEnabled = actualItems[i + 1];
|
||||
var expectedItem = expectedItems[i];
|
||||
var expectedEnabled = expectedItems[i + 1];
|
||||
if (expectedItem instanceof Array) {
|
||||
ok(true, "Checking submenu...");
|
||||
var menuID = expectedItems[i - 1]; // The last item was the menu ID.
|
||||
var menuID = expectedItems[i - 2]; // The last item was the menu ID.
|
||||
var submenu = menu.getElementsByAttribute("id", menuID)[0];
|
||||
ok(submenu && submenu.nodeName == "menu", "got expected submenu element");
|
||||
checkMenu(submenu.menupopup, expectedItems[i]);
|
||||
checkMenu(submenu.menupopup, expectedItem);
|
||||
} else {
|
||||
is(actualItems[i], expectedItems[i],
|
||||
"checking item #" + i + " (" + expectedItems[i] + ")");
|
||||
is(actualItem, expectedItem,
|
||||
"checking item #" + i/2 + " (" + expectedItem + ") name");
|
||||
if (expectedEnabled != null)
|
||||
is(actualEnabled, expectedEnabled,
|
||||
"checking item #" + i/2 + " (" + expectedItem + ") enabled state");
|
||||
}
|
||||
}
|
||||
// Could find unexpected extra items at the end...
|
||||
@ -150,136 +167,166 @@ function runTest(testNum) {
|
||||
|
||||
case 2:
|
||||
// Context menu for plain text
|
||||
checkContextMenu(["context-back",
|
||||
"context-forward",
|
||||
"context-reload",
|
||||
"context-stop",
|
||||
"---",
|
||||
"context-bookmarkpage",
|
||||
"context-savepage",
|
||||
"context-sendpage",
|
||||
"---",
|
||||
"context-viewbgimage",
|
||||
"context-selectall",
|
||||
"---",
|
||||
"context-viewsource",
|
||||
"context-viewinfo"]);
|
||||
checkContextMenu(["context-back", false,
|
||||
"context-forward", false,
|
||||
"context-reload", true,
|
||||
"context-stop", false,
|
||||
"---", null,
|
||||
"context-bookmarkpage", true,
|
||||
"context-savepage", true,
|
||||
"context-sendpage", true,
|
||||
"---", null,
|
||||
"context-viewbgimage", false,
|
||||
"context-selectall", true,
|
||||
"---", null,
|
||||
"context-viewsource", true,
|
||||
"context-viewinfo", true]);
|
||||
closeContextMenu()
|
||||
openContextMenuFor(link); // Invoke context menu for next test.
|
||||
break;
|
||||
|
||||
case 3:
|
||||
// Context menu for text link
|
||||
checkContextMenu(["context-openlink",
|
||||
"context-openlinkintab",
|
||||
"---",
|
||||
"context-bookmarklink",
|
||||
"context-savelink",
|
||||
"context-sendlink",
|
||||
"context-copylink",
|
||||
"---",
|
||||
"context-metadata"]);
|
||||
checkContextMenu(["context-openlink", true,
|
||||
"context-openlinkintab", true,
|
||||
"---", null,
|
||||
"context-bookmarklink", true,
|
||||
"context-savelink", true,
|
||||
"context-sendlink", true,
|
||||
"context-copylink", true,
|
||||
"---", null,
|
||||
"context-metadata", true]);
|
||||
closeContextMenu()
|
||||
openContextMenuFor(mailto); // Invoke context menu for next test.
|
||||
break;
|
||||
|
||||
case 4:
|
||||
// Context menu for text mailto-link
|
||||
checkContextMenu(["context-copyemail",
|
||||
"---",
|
||||
"context-metadata"]);
|
||||
checkContextMenu(["context-copyemail", true,
|
||||
"---", null,
|
||||
"context-metadata", true]);
|
||||
closeContextMenu()
|
||||
openContextMenuFor(input); // Invoke context menu for next test.
|
||||
break;
|
||||
|
||||
case 5:
|
||||
// Context menu for text input field
|
||||
checkContextMenu(["context-undo",
|
||||
"---",
|
||||
"context-cut",
|
||||
"context-copy",
|
||||
"context-paste",
|
||||
"context-delete",
|
||||
"---",
|
||||
"context-selectall",
|
||||
"---",
|
||||
"spell-check-enabled"]);
|
||||
checkContextMenu(["context-undo", false,
|
||||
"---", null,
|
||||
"context-cut", false,
|
||||
"context-copy", false,
|
||||
"context-paste", null, // ignore clipboard state
|
||||
"context-delete", false,
|
||||
"---", null,
|
||||
"context-selectall", true,
|
||||
"---", null,
|
||||
"spell-check-enabled", true]);
|
||||
closeContextMenu()
|
||||
openContextMenuFor(img); // Invoke context menu for next test.
|
||||
break;
|
||||
|
||||
case 6:
|
||||
// Context menu for an image
|
||||
checkContextMenu(["context-viewimage",
|
||||
"context-copyimage-contents",
|
||||
"context-copyimage",
|
||||
"---",
|
||||
"context-saveimage",
|
||||
"context-sendimage",
|
||||
"context-setDesktopBackground",
|
||||
"context-blockimage",
|
||||
"---",
|
||||
"context-metadata"]);
|
||||
checkContextMenu(["context-viewimage", true,
|
||||
"context-copyimage-contents", true,
|
||||
"context-copyimage", true,
|
||||
"---", null,
|
||||
"context-saveimage", true,
|
||||
"context-sendimage", true,
|
||||
"context-setDesktopBackground", true,
|
||||
"context-blockimage", true,
|
||||
"---", null,
|
||||
"context-metadata", true]);
|
||||
closeContextMenu();
|
||||
openContextMenuFor(canvas); // Invoke context menu for next test.
|
||||
break;
|
||||
|
||||
case 7:
|
||||
// Context menu for a canvas
|
||||
checkContextMenu(["context-viewimage",
|
||||
"context-saveimage",
|
||||
"context-bookmarkpage",
|
||||
"context-selectall"]);
|
||||
checkContextMenu(["context-viewimage", true,
|
||||
"context-saveimage", true,
|
||||
"context-bookmarkpage", true,
|
||||
"context-selectall", true]);
|
||||
closeContextMenu();
|
||||
openContextMenuFor(video); // Invoke context menu for next test.
|
||||
openContextMenuFor(video_ok); // Invoke context menu for next test.
|
||||
break;
|
||||
|
||||
case 8:
|
||||
// Context menu for a video
|
||||
checkContextMenu(["context-media-play",
|
||||
"context-media-mute",
|
||||
"context-media-showcontrols",
|
||||
"---",
|
||||
"context-viewvideo",
|
||||
"context-copyvideourl",
|
||||
"---",
|
||||
"context-savevideo",
|
||||
"context-sendvideo"]);
|
||||
// Context menu for a video (with a VALID media source)
|
||||
checkContextMenu(["context-media-play", true,
|
||||
"context-media-mute", true,
|
||||
"context-media-showcontrols", true,
|
||||
"---", null,
|
||||
"context-viewvideo", true,
|
||||
"context-copyvideourl", true,
|
||||
"---", null,
|
||||
"context-savevideo", true,
|
||||
"context-sendvideo", true]);
|
||||
closeContextMenu();
|
||||
openContextMenuFor(video_bad); // Invoke context menu for next test.
|
||||
break;
|
||||
|
||||
case 9:
|
||||
// Context menu for a video (with a INVALID media source)
|
||||
checkContextMenu(["context-media-play", false,
|
||||
"context-media-mute", false,
|
||||
"context-media-showcontrols", false,
|
||||
"---", null,
|
||||
"context-viewvideo", true,
|
||||
"context-copyvideourl", true,
|
||||
"---", null,
|
||||
"context-savevideo", true,
|
||||
"context-sendvideo", true]);
|
||||
closeContextMenu();
|
||||
openContextMenuFor(video_bad2); // Invoke context menu for next test.
|
||||
break;
|
||||
|
||||
case 10:
|
||||
// Context menu for a video (with a INVALID media source)
|
||||
checkContextMenu(["context-media-play", false,
|
||||
"context-media-mute", false,
|
||||
"context-media-showcontrols", false,
|
||||
"---", null,
|
||||
"context-viewvideo", false,
|
||||
"context-copyvideourl", false,
|
||||
"---", null,
|
||||
"context-savevideo", false,
|
||||
"context-sendvideo", false]);
|
||||
closeContextMenu();
|
||||
openContextMenuFor(iframe); // Invoke context menu for next test.
|
||||
break;
|
||||
|
||||
case 9:
|
||||
case 11:
|
||||
// Context menu for an iframe
|
||||
checkContextMenu(["context-back",
|
||||
"context-forward",
|
||||
"context-reload",
|
||||
"context-stop",
|
||||
"---",
|
||||
"context-bookmarkpage",
|
||||
"context-savepage",
|
||||
"context-sendpage",
|
||||
"---",
|
||||
"context-viewbgimage",
|
||||
"context-selectall",
|
||||
"---",
|
||||
"frame",
|
||||
["context-showonlythisframe",
|
||||
"context-openframe",
|
||||
"context-openframeintab",
|
||||
"---",
|
||||
"context-reloadframe",
|
||||
"---",
|
||||
"context-bookmarkframe",
|
||||
"context-saveframe",
|
||||
"---",
|
||||
"context-printframe",
|
||||
"---",
|
||||
"context-viewframesource",
|
||||
"context-viewframeinfo"],
|
||||
"---",
|
||||
"context-viewsource",
|
||||
"context-viewinfo"]);
|
||||
checkContextMenu(["context-back", false,
|
||||
"context-forward", false,
|
||||
"context-reload", true,
|
||||
"context-stop", false,
|
||||
"---", null,
|
||||
"context-bookmarkpage", true,
|
||||
"context-savepage", true,
|
||||
"context-sendpage", true,
|
||||
"---", null,
|
||||
"context-viewbgimage", false,
|
||||
"context-selectall", true,
|
||||
"---", null,
|
||||
"frame", null,
|
||||
["context-showonlythisframe", true,
|
||||
"context-openframe", true,
|
||||
"context-openframeintab", true,
|
||||
"---", null,
|
||||
"context-reloadframe", true,
|
||||
"---", null,
|
||||
"context-bookmarkframe", true,
|
||||
"context-saveframe", true,
|
||||
"---", null,
|
||||
"context-printframe", true,
|
||||
"---", null,
|
||||
"context-viewframesource", true,
|
||||
"context-viewframeinfo", true], null,
|
||||
"---", null,
|
||||
"context-viewsource", true,
|
||||
"context-viewinfo", true]);
|
||||
closeContextMenu();
|
||||
|
||||
subwindow.close();
|
||||
@ -327,7 +374,9 @@ function startTest() {
|
||||
input = subwindow.document.getElementById("test-input");
|
||||
img = subwindow.document.getElementById("test-image");
|
||||
canvas = subwindow.document.getElementById("test-canvas");
|
||||
video = subwindow.document.getElementById("test-video");
|
||||
video_ok = subwindow.document.getElementById("test-video-ok");
|
||||
video_bad = subwindow.document.getElementById("test-video-bad");
|
||||
video_bad2 = subwindow.document.getElementById("test-video-bad2");
|
||||
iframe = subwindow.document.getElementById("test-iframe");
|
||||
|
||||
contextMenu.addEventListener("popupshown", function() { runTest(++testNum); }, false);
|
||||
|
BIN
browser/base/content/test/video.ogg
Normal file
BIN
browser/base/content/test/video.ogg
Normal file
Binary file not shown.
@ -44,8 +44,10 @@ ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
|
||||
cp $(srcdir)/background.png $(DIST)/branding/background.png
|
||||
cp $(srcdir)/disk.icns $(DIST)/branding/disk.icns
|
||||
endif
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
ifneq (,$(filter WINNT WINCE,$(OS_ARCH)))
|
||||
cp $(srcdir)/firefox.ico $(DIST)/branding/app.ico
|
||||
endif
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
cp $(srcdir)/branding.nsi $(DIST)/branding/branding.nsi
|
||||
cp $(srcdir)/wizHeader.bmp $(DIST)/branding/wizHeader.bmp
|
||||
cp $(srcdir)/wizHeaderRTL.bmp $(DIST)/branding/wizHeaderRTL.bmp
|
||||
|
@ -83,7 +83,7 @@ endif
|
||||
|
||||
DIRS += build
|
||||
|
||||
ifneq (,$(BUILD_OFFICIAL)$(MOZILLA_OFFICIAL))
|
||||
ifdef MOZILLA_OFFICIAL
|
||||
DEFINES += -DOFFICIAL_BUILD=1
|
||||
endif
|
||||
|
||||
|
@ -2147,6 +2147,7 @@ MicrosummaryResource.prototype = {
|
||||
this._iframe.docShell.allowMetaRedirects = false;
|
||||
this._iframe.docShell.allowSubframes = false;
|
||||
this._iframe.docShell.allowImages = false;
|
||||
this._iframe.docShell.allowDNSPrefetch = false;
|
||||
|
||||
var parseHandler = {
|
||||
_self: this,
|
||||
|
@ -330,3 +330,13 @@ function dump_table(aName)
|
||||
stmt.finalize();
|
||||
stmt = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Flushes any events in the event loop of the main thread.
|
||||
*/
|
||||
function flush_main_thread_events()
|
||||
{
|
||||
let tm = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager);
|
||||
while (tm.mainThread.hasPendingEvents())
|
||||
tm.mainThread.processNextEvent(false);
|
||||
}
|
||||
|
@ -41,9 +41,7 @@
|
||||
// event loop long before code like this would run.
|
||||
// Not doing so could cause us to close the connection before all tasks have
|
||||
// been completed, and that would crash badly.
|
||||
let tm = Cc["@mozilla.org/thread-manager;1"].getService(Ci.nsIThreadManager);
|
||||
while (tm.mainThread.hasPendingEvents())
|
||||
tm.mainThread.processNextEvent(false);
|
||||
flush_main_thread_events();
|
||||
|
||||
// XPCShell doesn't dispatch quit-application, to ensure cleanup we have to
|
||||
// dispatch it after each test run.
|
||||
@ -52,6 +50,9 @@ var os = Cc['@mozilla.org/observer-service;1'].
|
||||
os.notifyObservers(null, "quit-application-granted", null);
|
||||
os.notifyObservers(null, "quit-application", null);
|
||||
|
||||
// Run the event loop, since we enqueue some statement finalization.
|
||||
flush_main_thread_events();
|
||||
|
||||
// try to close the connection so we can remove places.sqlite
|
||||
var pip = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService).
|
||||
|
@ -298,18 +298,6 @@ PrivateBrowsingService.prototype = {
|
||||
getService(Ci.nsIHttpAuthManager);
|
||||
authMgr.clearAll();
|
||||
|
||||
// Prevent any SSL sockets from remaining open. Without this, SSL
|
||||
// websites may fail to load after switching the private browsing mode
|
||||
// because the SSL sockets may still be open while the corresponding
|
||||
// NSS resources have been destroyed by the logoutAndTeardown call
|
||||
// above. See bug 463256 for more information.
|
||||
let ios = Cc["@mozilla.org/network/io-service;1"].
|
||||
getService(Ci.nsIIOService);
|
||||
if (!ios.offline) {
|
||||
ios.offline = true;
|
||||
ios.offline = false;
|
||||
}
|
||||
|
||||
if (!this._inPrivateBrowsing) {
|
||||
// Clear the error console
|
||||
let consoleService = Cc["@mozilla.org/consoleservice;1"].
|
||||
|
@ -59,9 +59,8 @@ _BROWSER_TEST_FILES = \
|
||||
browser_privatebrowsing_urlbarfocus.js \
|
||||
browser_privatebrowsing_forgetthissite.js \
|
||||
browser_privatebrowsing_pageinfo.js \
|
||||
browser_privatebrowsing_sslsite_transition.js \
|
||||
$(NULL)
|
||||
# Test for bug 463256 disabled until we figure why it fails intermittently (bug 486640)
|
||||
# browser_privatebrowsing_sslsite_transition.js \
|
||||
|
||||
libs:: $(_BROWSER_TEST_FILES)
|
||||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
|
||||
|
@ -36,9 +36,7 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// This test makes sure that SSL sites load correctly after leaving the
|
||||
// Private Browsing mode (bug 463256).
|
||||
|
||||
// This test is disabled until we figure why it fails intermittently (bug 486640).
|
||||
// Private Browsing mode (bug 463256 and bug 496335).
|
||||
|
||||
function test() {
|
||||
// initialization
|
||||
@ -78,3 +76,5 @@ function test() {
|
||||
}, true);
|
||||
browser.contentWindow.location = kTestURL;
|
||||
|
||||
waitForExplicitFinish();
|
||||
}
|
||||
|
@ -35,8 +35,8 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// This tests the private browsing service to make sure it switches the offline
|
||||
// status as expected (see bug 463256).
|
||||
// This tests the private browsing service to make sure it no longer switches
|
||||
// the offline status (see bug 463256).
|
||||
|
||||
function run_test_on_service() {
|
||||
// initialization
|
||||
@ -59,15 +59,11 @@ function run_test_on_service() {
|
||||
|
||||
// enter the private browsing mode, and wait for the about:pb page to load
|
||||
pb.privateBrowsingEnabled = true;
|
||||
do_check_eq(observer.events.length, 2);
|
||||
do_check_eq(observer.events[0], "offline");
|
||||
do_check_eq(observer.events[1], "online");
|
||||
do_check_eq(observer.events.length, 0);
|
||||
|
||||
// leave the private browsing mode, and wait for the SSL page to load again
|
||||
pb.privateBrowsingEnabled = false;
|
||||
do_check_eq(observer.events.length, 4);
|
||||
do_check_eq(observer.events[2], "offline");
|
||||
do_check_eq(observer.events[3], "online");
|
||||
do_check_eq(observer.events.length, 0);
|
||||
|
||||
os.removeObserver(observer, "network:offline-status-changed", false);
|
||||
prefBranch.clearUserPref("browser.privatebrowsing.keep_current_session");
|
@ -49,7 +49,7 @@ ifdef ENABLE_TESTS
|
||||
DIRS += content/test
|
||||
endif
|
||||
|
||||
ifneq (,$(BUILD_OFFICIAL)$(MOZILLA_OFFICIAL))
|
||||
ifdef MOZILLA_OFFICIAL
|
||||
DEFINES += -DOFFICIAL_BUILD=1
|
||||
endif
|
||||
|
||||
|
@ -1889,9 +1889,8 @@ SessionStoreService.prototype = {
|
||||
|
||||
if (aTabs.length > 0) {
|
||||
// Determine if we can optimize & load visible tabs first
|
||||
let tabScrollBoxObject = tabbrowser.tabContainer.mTabstrip.scrollBoxObject;
|
||||
let tabBoxObject = aTabs[0].boxObject;
|
||||
let maxVisibleTabs = Math.ceil(tabScrollBoxObject.width / tabBoxObject.width);
|
||||
let maxVisibleTabs = Math.ceil(tabbrowser.tabContainer.mTabstrip.scrollClientSize /
|
||||
aTabs[0].clientWidth);
|
||||
|
||||
// make sure we restore visible tabs first, if there are enough
|
||||
if (maxVisibleTabs < aTabs.length && aSelectTab > 1) {
|
||||
@ -2582,6 +2581,7 @@ SessionStoreService.prototype = {
|
||||
_getWindowDimension: function sss_getWindowDimension(aWindow, aAttribute) {
|
||||
if (aAttribute == "sizemode") {
|
||||
switch (aWindow.windowState) {
|
||||
case aWindow.STATE_FULLSCREEN:
|
||||
case aWindow.STATE_MAXIMIZED:
|
||||
return "maximized";
|
||||
case aWindow.STATE_MINIMIZED:
|
||||
|
@ -86,7 +86,11 @@
|
||||
#define REG_FAILED(val) \
|
||||
(val != ERROR_SUCCESS)
|
||||
|
||||
#ifndef WINCE
|
||||
NS_IMPL_ISUPPORTS2(nsWindowsShellService, nsIWindowsShellService, nsIShellService)
|
||||
#else
|
||||
NS_IMPL_ISUPPORTS1(nsWindowsShellService, nsIShellService)
|
||||
#endif
|
||||
|
||||
static nsresult
|
||||
OpenKeyForReading(HKEY aKeyRoot, const nsAString& aKeyName, HKEY* aKey)
|
||||
@ -106,6 +110,33 @@ OpenKeyForReading(HKEY aKeyRoot, const nsAString& aKeyName, HKEY* aKey)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef WINCE
|
||||
static nsresult
|
||||
OpenKeyForWriting(HKEY aStartKey, const nsAString& aKeyName, HKEY* aKey)
|
||||
{
|
||||
const nsString &flatName = PromiseFlatString(aKeyName);
|
||||
|
||||
DWORD dwDisp = 0;
|
||||
DWORD res = ::RegCreateKeyExW(aStartKey, flatName.get(), 0, NULL,
|
||||
0, KEY_READ | KEY_WRITE, NULL, aKey,
|
||||
&dwDisp);
|
||||
switch (res) {
|
||||
case ERROR_SUCCESS:
|
||||
break;
|
||||
case ERROR_ACCESS_DENIED:
|
||||
return NS_ERROR_FILE_ACCESS_DENIED;
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
res = ::RegCreateKeyExW(aStartKey, flatName.get(), 0, NULL,
|
||||
0, KEY_READ | KEY_WRITE, NULL, aKey,
|
||||
NULL);
|
||||
if (res != ERROR_SUCCESS)
|
||||
return NS_ERROR_FILE_ACCESS_DENIED;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Default Browser Registry Settings
|
||||
//
|
||||
@ -181,30 +212,52 @@ typedef struct {
|
||||
char* valueData;
|
||||
} SETTING;
|
||||
|
||||
#ifndef WINCE
|
||||
#define APP_REG_NAME L"Firefox"
|
||||
#define CLS_HTML "FirefoxHTML"
|
||||
#define CLS_URL "FirefoxURL"
|
||||
#define VAL_OPEN "\"%APPPATH%\" -requestPending -osint -url \"%1\""
|
||||
#define VAL_FILE_ICON "%APPPATH%,1"
|
||||
#else
|
||||
#define VAL_OPEN "\"%APPPATH%\" -osint -url \"%1\""
|
||||
#define VAL_FILE_ICON "%APPPATH%,-2"
|
||||
#endif
|
||||
|
||||
#define DI "\\DefaultIcon"
|
||||
#define SOP "\\shell\\open\\command"
|
||||
|
||||
#define CLS_HTML "FirefoxHTML"
|
||||
#define CLS_URL "FirefoxURL"
|
||||
#define VAL_FILE_ICON "%APPPATH%,1"
|
||||
#define VAL_OPEN "\"%APPPATH%\" -requestPending -osint -url \"%1\""
|
||||
|
||||
#define MAKE_KEY_NAME1(PREFIX, MID) \
|
||||
PREFIX MID
|
||||
|
||||
// The DefaultIcon registry key value should never be used when checking if
|
||||
// Firefox is the default browser since other applications (e.g. MS Office) may
|
||||
// modify the DefaultIcon registry key value to add Icon Handlers.
|
||||
// see http://msdn2.microsoft.com/en-us/library/aa969357.aspx for more info.
|
||||
// Firefox is the default browser for file handlers since other applications
|
||||
// (e.g. MS Office) may modify the DefaultIcon registry key value to add Icon
|
||||
// Handlers. see http://msdn2.microsoft.com/en-us/library/aa969357.aspx for
|
||||
// more info.
|
||||
static SETTING gSettings[] = {
|
||||
// File Extension Class - as of 1.8.1.2 the value for VAL_OPEN is also checked
|
||||
// for CLS_HTML since Firefox should also own opeing local files when set as
|
||||
// the default browser.
|
||||
#ifndef WINCE
|
||||
// File Handler Class
|
||||
{ MAKE_KEY_NAME1(CLS_HTML, SOP), "", VAL_OPEN },
|
||||
|
||||
// Protocol Handler Class - for Vista and above
|
||||
{ MAKE_KEY_NAME1(CLS_URL, SOP), "", VAL_OPEN },
|
||||
#else
|
||||
{ MAKE_KEY_NAME1("FTP", DI), "", VAL_FILE_ICON },
|
||||
{ MAKE_KEY_NAME1("FTP", SOP), "", VAL_OPEN },
|
||||
|
||||
// File handlers for Windows CE
|
||||
{ MAKE_KEY_NAME1("bmpfile", DI), "", VAL_FILE_ICON },
|
||||
{ MAKE_KEY_NAME1("bmpfile", SOP), "", VAL_OPEN },
|
||||
{ MAKE_KEY_NAME1("giffile", DI), "", VAL_FILE_ICON },
|
||||
{ MAKE_KEY_NAME1("giffile", SOP), "", VAL_OPEN },
|
||||
{ MAKE_KEY_NAME1("jpegfile", DI), "", VAL_FILE_ICON },
|
||||
{ MAKE_KEY_NAME1("jpegfile", SOP), "", VAL_OPEN },
|
||||
{ MAKE_KEY_NAME1("pngfile", DI), "", VAL_FILE_ICON },
|
||||
{ MAKE_KEY_NAME1("pngfile", SOP), "", VAL_OPEN },
|
||||
{ MAKE_KEY_NAME1("htmlfile", DI), "", VAL_FILE_ICON },
|
||||
{ MAKE_KEY_NAME1("htmlfile", SOP), "", VAL_OPEN },
|
||||
#endif
|
||||
|
||||
// Protocol Handlers
|
||||
{ MAKE_KEY_NAME1("HTTP", DI), "", VAL_FILE_ICON },
|
||||
@ -213,6 +266,7 @@ static SETTING gSettings[] = {
|
||||
{ MAKE_KEY_NAME1("HTTPS", SOP), "", VAL_OPEN }
|
||||
};
|
||||
|
||||
#ifndef WINCE
|
||||
PRBool
|
||||
nsWindowsShellService::IsDefaultBrowserVista(PRBool* aIsDefaultBrowser)
|
||||
{
|
||||
@ -236,6 +290,7 @@ nsWindowsShellService::IsDefaultBrowserVista(PRBool* aIsDefaultBrowser)
|
||||
#endif
|
||||
return PR_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowsShellService::IsDefaultBrowser(PRBool aStartupCheck,
|
||||
@ -295,10 +350,12 @@ nsWindowsShellService::IsDefaultBrowser(PRBool aStartupCheck,
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef WINCE
|
||||
// Only check if Firefox is the default browser on Vista if the previous
|
||||
// checks show that Firefox is the default browser.
|
||||
if (*aIsDefaultBrowser)
|
||||
IsDefaultBrowserVista(aIsDefaultBrowser);
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -306,6 +363,7 @@ nsWindowsShellService::IsDefaultBrowser(PRBool aStartupCheck,
|
||||
NS_IMETHODIMP
|
||||
nsWindowsShellService::SetDefaultBrowser(PRBool aClaimAllTypes, PRBool aForAllUsers)
|
||||
{
|
||||
#ifndef WINCE
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIProperties> directoryService =
|
||||
do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv);
|
||||
@ -342,10 +400,91 @@ nsWindowsShellService::SetDefaultBrowser(PRBool aClaimAllTypes, PRBool aForAllUs
|
||||
|
||||
CloseHandle(pi.hProcess);
|
||||
CloseHandle(pi.hThread);
|
||||
#else
|
||||
SETTING* settings;
|
||||
SETTING* end = gSettings + sizeof(gSettings)/sizeof(SETTING);
|
||||
|
||||
PRUnichar exePath[MAX_BUF];
|
||||
if (!::GetModuleFileNameW(0, exePath, MAX_BUF))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsAutoString appLongPath(exePath);
|
||||
|
||||
// The .png registry key isn't present by default so also add Content Type.
|
||||
SetRegKey(NS_LITERAL_STRING(".png"), EmptyString(),
|
||||
NS_LITERAL_STRING("pngfile"));
|
||||
SetRegKey(NS_LITERAL_STRING(".png"), NS_LITERAL_STRING("Content Type"),
|
||||
NS_LITERAL_STRING("image/png"));
|
||||
|
||||
// Set these keys to their default value for a clean install in case another
|
||||
// app has changed these keys.
|
||||
SetRegKey(NS_LITERAL_STRING(".htm"), EmptyString(),
|
||||
NS_LITERAL_STRING("htmlfile"));
|
||||
SetRegKey(NS_LITERAL_STRING(".html"), EmptyString(),
|
||||
NS_LITERAL_STRING("htmlfile"));
|
||||
SetRegKey(NS_LITERAL_STRING(".bmp"), EmptyString(),
|
||||
NS_LITERAL_STRING("bmpfile"));
|
||||
SetRegKey(NS_LITERAL_STRING(".gif"), EmptyString(),
|
||||
NS_LITERAL_STRING("giffile"));
|
||||
SetRegKey(NS_LITERAL_STRING(".jpe"), EmptyString(),
|
||||
NS_LITERAL_STRING("jpegfile"));
|
||||
SetRegKey(NS_LITERAL_STRING(".jpg"), EmptyString(),
|
||||
NS_LITERAL_STRING("jpegfile"));
|
||||
SetRegKey(NS_LITERAL_STRING(".jpeg"), EmptyString(),
|
||||
NS_LITERAL_STRING("jpegfile"));
|
||||
|
||||
for (settings = gSettings; settings < end; ++settings) {
|
||||
NS_ConvertUTF8toUTF16 dataLongPath(settings->valueData);
|
||||
NS_ConvertUTF8toUTF16 key(settings->keyName);
|
||||
NS_ConvertUTF8toUTF16 value(settings->valueName);
|
||||
PRInt32 offset = dataLongPath.Find("%APPPATH%");
|
||||
dataLongPath.Replace(offset, 9, appLongPath);
|
||||
SetRegKey(key, value, dataLongPath);
|
||||
}
|
||||
// On Windows CE RegFlushKey can negatively impact performance if there are a
|
||||
// lot of pending writes to the HKEY_CLASSES_ROOT registry hive but it is
|
||||
// necessary to save the values in the case where the user performs a hard
|
||||
// power off of the device.
|
||||
::RegFlushKey(HKEY_CLASSES_ROOT);
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef WINCE
|
||||
void
|
||||
nsWindowsShellService::SetRegKey(const nsString& aKeyName,
|
||||
const nsString& aValueName,
|
||||
const nsString& aValue)
|
||||
{
|
||||
PRUnichar buf[MAX_BUF];
|
||||
DWORD len = sizeof buf;
|
||||
|
||||
HKEY theKey;
|
||||
nsresult rv = OpenKeyForWriting(HKEY_CLASSES_ROOT, aKeyName, &theKey);
|
||||
if (NS_FAILED(rv))
|
||||
return;
|
||||
|
||||
// Get the current value.
|
||||
DWORD res = ::RegQueryValueExW(theKey, PromiseFlatString(aValueName).get(),
|
||||
NULL, NULL, (LPBYTE)buf, &len);
|
||||
|
||||
// Set the new value if it doesn't exist or it is different than the current
|
||||
// value.
|
||||
nsAutoString current(buf);
|
||||
if (REG_FAILED(res) || !current.Equals(aValue)) {
|
||||
const nsString &flatValue = PromiseFlatString(aValue);
|
||||
|
||||
::RegSetValueExW(theKey, PromiseFlatString(aValueName).get(),
|
||||
0, REG_SZ, (const BYTE *)flatValue.get(),
|
||||
(flatValue.Length() + 1) * sizeof(PRUnichar));
|
||||
}
|
||||
|
||||
// Close the key we opened.
|
||||
::RegCloseKey(theKey);
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowsShellService::GetShouldCheckDefaultBrowser(PRBool* aResult)
|
||||
{
|
||||
@ -715,6 +854,7 @@ nsWindowsShellService::SetDesktopBackgroundColor(PRUint32 aColor)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifndef WINCE
|
||||
NS_IMETHODIMP
|
||||
nsWindowsShellService::GetUnreadMailCount(PRUint32* aCount)
|
||||
{
|
||||
@ -774,6 +914,7 @@ nsWindowsShellService::GetMailAccountKey(HKEY* aResult)
|
||||
::RegCloseKey(mailKey);
|
||||
return PR_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowsShellService::OpenApplicationWithURI(nsILocalFile* aApplication,
|
||||
|
@ -46,7 +46,11 @@
|
||||
#include <windows.h>
|
||||
#include <ole2.h>
|
||||
|
||||
#ifndef WINCE
|
||||
class nsWindowsShellService : public nsIWindowsShellService
|
||||
#else
|
||||
class nsWindowsShellService : public nsIShellService
|
||||
#endif
|
||||
{
|
||||
public:
|
||||
nsWindowsShellService() : mCheckedThisSession(PR_FALSE) {};
|
||||
@ -54,12 +58,20 @@ public:
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSISHELLSERVICE
|
||||
#ifndef WINCE
|
||||
NS_DECL_NSIWINDOWSSHELLSERVICE
|
||||
#endif
|
||||
|
||||
protected:
|
||||
#ifndef WINCE
|
||||
PRBool IsDefaultBrowserVista(PRBool* aIsDefaultBrowser);
|
||||
|
||||
PRBool GetMailAccountKey(HKEY* aResult);
|
||||
#else
|
||||
void SetRegKey(const nsString& aKeyName,
|
||||
const nsString& aValueName,
|
||||
const nsString& aValue);
|
||||
#endif
|
||||
|
||||
private:
|
||||
PRBool mCheckedThisSession;
|
||||
|
@ -1109,11 +1109,6 @@ statusbarpanel#statusbar-display {
|
||||
-moz-padding-start: 0;
|
||||
}
|
||||
|
||||
#security-button {
|
||||
min-width: 20px;
|
||||
-moz-box-direction: reverse;
|
||||
}
|
||||
|
||||
#security-button[level="high"],
|
||||
#security-button[level="low"] {
|
||||
list-style-image: url("chrome://browser/skin/Secure.png");
|
||||
@ -1123,11 +1118,6 @@ statusbarpanel#statusbar-display {
|
||||
list-style-image: url("chrome://browser/skin/Security-broken.png");
|
||||
}
|
||||
|
||||
/* XXXsw prevent margins of a value-less label from shifting the image */
|
||||
#security-button > label:not([value]) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#page-report-button {
|
||||
list-style-image: url("chrome://browser/skin/Info.png");
|
||||
width: 20px;
|
||||
@ -1311,6 +1301,28 @@ tabpanels {
|
||||
margin: 2px 0 1px;
|
||||
}
|
||||
|
||||
.tabs-alltabs-button[type="menu"] > .toolbarbutton-menu-dropmarker {
|
||||
margin-bottom: -2px;
|
||||
}
|
||||
|
||||
.tabs-alltabs-button[type="menu"] > .toolbarbutton-icon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* All tabs menupopup */
|
||||
.alltabs-item > .menu-iconic-left > .menu-iconic-icon {
|
||||
list-style-image: url("chrome://global/skin/icons/folder-item.png");
|
||||
-moz-image-region: rect(0px, 16px, 16px, 0px);
|
||||
}
|
||||
|
||||
.alltabs-item[selected="true"] {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.alltabs-item[busy] > .menu-iconic-left > .menu-iconic-icon {
|
||||
list-style-image: url("chrome://global/skin/icons/loading_16.png");
|
||||
}
|
||||
|
||||
/* Sidebar */
|
||||
#sidebar-box .tabs-closebutton {
|
||||
margin-bottom: 0px !important;
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 171 B After Width: | Height: | Size: 192 B |
@ -1406,10 +1406,6 @@ sidebarheader > .tabs-closebutton > .toolbarbutton-text {
|
||||
|
||||
/* ----- SECURITY DISPLAY ----- */
|
||||
|
||||
#security-button {
|
||||
-moz-box-direction: reverse;
|
||||
}
|
||||
|
||||
#security-button[level="high"] ,
|
||||
#security-button[level="low"] {
|
||||
list-style-image: url("chrome://browser/skin/Secure-statusbar.png");
|
||||
@ -1733,6 +1729,7 @@ tabbrowser > tabbox > tabpanels {
|
||||
.tabs-alltabs-button:hover {
|
||||
-moz-image-region: rect(0, 44px, 20px, 22px);
|
||||
}
|
||||
.tabs-alltabs-button[type="menu"][open="true"],
|
||||
.tabs-alltabs-button:hover:active {
|
||||
-moz-image-region: rect(0, 66px, 20px, 44px);
|
||||
}
|
||||
@ -1745,6 +1742,7 @@ tabbrowser > tabbox > tabpanels {
|
||||
background-color: rgba(0,0,0,0.20);
|
||||
}
|
||||
|
||||
.tabs-alltabs-button[type="menu"] > .toolbarbutton-menu-dropmarker,
|
||||
.tabs-alltabs-button > .toolbarbutton-text {
|
||||
display: none;
|
||||
}
|
||||
@ -1761,6 +1759,20 @@ tabbrowser > tabbox > tabpanels {
|
||||
opacity: 0.0;
|
||||
}
|
||||
|
||||
/* All Tabs Menupopup */
|
||||
.alltabs-item > .menu-iconic-left > .menu-iconic-icon {
|
||||
list-style-image: url("chrome://global/skin/tree/item.png");
|
||||
}
|
||||
|
||||
.alltabs-item[selected="true"] {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.alltabs-item[busy] > .menu-iconic-left > .menu-iconic-icon {
|
||||
list-style-image: url("chrome://global/skin/icons/loading_16.png") !important;
|
||||
}
|
||||
|
||||
/* Tabstrip close button */
|
||||
.tabs-closebutton {
|
||||
-moz-padding-end: 4px;
|
||||
list-style-image: url("chrome://global/skin/icons/closetab.png");
|
||||
|
@ -1286,11 +1286,6 @@ statusbarpanel#statusbar-display {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
#security-button {
|
||||
min-width: 20px;
|
||||
-moz-box-direction: reverse;
|
||||
}
|
||||
|
||||
#security-button[level="high"],
|
||||
#security-button[level="low"] {
|
||||
list-style-image: url("chrome://browser/skin/Secure.png");
|
||||
@ -1300,11 +1295,6 @@ statusbarpanel#statusbar-display {
|
||||
list-style-image: url("chrome://browser/skin/Security-broken.png");
|
||||
}
|
||||
|
||||
/* XXXsw prevent margins of a value-less label from shifting the image */
|
||||
#security-button > label:not([value]) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#page-report-button {
|
||||
width: 20px;
|
||||
list-style-image: url("chrome://browser/skin/Info.png");
|
||||
@ -1571,8 +1561,26 @@ tabpanels {
|
||||
|
||||
.tabs-alltabs-button > .toolbarbutton-icon {
|
||||
list-style-image: url("chrome://browser/skin/tabbrowser/alltabs.png");
|
||||
margin: 6px 0 4px;
|
||||
-moz-image-region: auto;
|
||||
-moz-image-region: rect(0, 14px, 20px, 0);
|
||||
}
|
||||
|
||||
.tabs-alltabs-button:hover:active > .toolbarbutton-icon {
|
||||
-moz-image-region: rect(0, 28px, 20px, 14px);
|
||||
}
|
||||
|
||||
.tabs-alltabs-button[type="menu"] > .toolbarbutton-icon {
|
||||
list-style-image: url("chrome://browser/skin/mainwindow-dropdown-arrow.png");
|
||||
margin: 5px 0 4px;
|
||||
-moz-image-region: rect(0, 13px, 11px, 0);
|
||||
}
|
||||
|
||||
.tabs-alltabs-button[type="menu"] > .toolbarbutton-menu-dropmarker {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.tabs-alltabs-button[type="menu"]:hover:active > .toolbarbutton-icon,
|
||||
.tabs-alltabs-button[type="menu"][open="true"] > .toolbarbutton-icon {
|
||||
-moz-image-region: rect(0, 26px, 11px, 13px);
|
||||
}
|
||||
|
||||
.tabs-alltabs-box-animate {
|
||||
@ -1588,6 +1596,20 @@ stack[chromedir="rtl"] > hbox > .tabs-alltabs-box-animate {
|
||||
background-image: url("chrome://browser/skin/tabbrowser/alltabs-box-overflow-start-bkgnd-animate.png");
|
||||
}
|
||||
|
||||
/* All tabs menupopup */
|
||||
.alltabs-item > .menu-iconic-left > .menu-iconic-icon {
|
||||
list-style-image: url("chrome://global/skin/icons/folder-item.png");
|
||||
-moz-image-region: rect(0px, 16px, 16px, 0px);
|
||||
}
|
||||
|
||||
.alltabs-item[selected="true"] {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.alltabs-item[busy] > .menu-iconic-left > .menu-iconic-icon {
|
||||
list-style-image: url("chrome://global/skin/icons/loading_16.png");
|
||||
}
|
||||
|
||||
/* Tabstrip close button */
|
||||
.tabs-closebutton {
|
||||
-moz-appearance: none;
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 171 B After Width: | Height: | Size: 719 B |
@ -1,44 +0,0 @@
|
||||
#!/usr/bin/expect
|
||||
# ***** 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 Corporation Code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is
|
||||
# Clint Talbert.
|
||||
# Portions created by the Initial Developer are Copyright (C) 2007
|
||||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Armen Zambrano Gasparnian <armenzg@mozilla.com>
|
||||
# Axel Hecht <l10n@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 *****
|
||||
spawn hdiutil attach -readonly -mountroot /tmp -private -noautoopen $argv
|
||||
expect {
|
||||
"byte" {send "G"; exp_continue}
|
||||
"END" {send "\r"; exp_continue}
|
||||
"Y/N?" {send "Y\r"; exp_continue}
|
||||
}
|
88
build/package/mac_osx/unpack-diskimage
Executable file
88
build/package/mac_osx/unpack-diskimage
Executable file
@ -0,0 +1,88 @@
|
||||
#!/bin/bash
|
||||
# ***** 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 the installdmg.sh script from taols utilities
|
||||
#
|
||||
# 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):
|
||||
# Chris AtLee <catlee@mozilla.com>
|
||||
# Robert Kaiser <kairo@kairo.at>
|
||||
#
|
||||
# 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 *****
|
||||
|
||||
# Unpack a disk image to a specified target folder
|
||||
#
|
||||
# Usage: unpack-diskimage <image_file>
|
||||
# <mountpoint>
|
||||
# <target_path>
|
||||
|
||||
DMG_PATH=$1
|
||||
MOUNTPOINT=$2
|
||||
TARGETPATH=$3
|
||||
|
||||
# How long to wait before giving up waiting for the mount to finish (seconds)
|
||||
TIMEOUT=90
|
||||
|
||||
# If mnt already exists, then the previous run may not have cleaned up
|
||||
# properly. We should try to umount and remove the mnt directory.
|
||||
if [ -d $MOUNTPOINT ]; then
|
||||
echo "mnt already exists, trying to clean up"
|
||||
hdiutil detach $MOUNTPOINT -force
|
||||
rm -rdfv $MOUNTPOINT
|
||||
fi
|
||||
|
||||
# Install an on-exit handler that will unmount and remove the '$MOUNTPOINT' directory
|
||||
trap "{ if [ -d $MOUNTPOINT ]; then hdiutil detach $MOUNTPOINT -force; rm -rdfv $MOUNTPOINT; fi; }" EXIT
|
||||
|
||||
mkdir -p $MOUNTPOINT
|
||||
|
||||
hdiutil attach -verbose -noautoopen -mountpoint $MOUNTPOINT "$DMG_PATH"
|
||||
# Wait for files to show up
|
||||
# hdiutil uses a helper process, diskimages-helper, which isn't always done its
|
||||
# work by the time hdiutil exits. So we wait until something shows up in the
|
||||
# mnt directory. Due to the async nature of diskimages-helper, the best thing
|
||||
# we can do is to make sure the glob() rsync is making can find files.
|
||||
i=0
|
||||
while [ "$(echo $MOUNTPOINT/*)" == "$MOUNTPOINT/*" ]; do
|
||||
if [ $i -gt $TIMEOUT ]; then
|
||||
echo "No files found, exiting"
|
||||
exit 1
|
||||
fi
|
||||
sleep 1
|
||||
i=$(expr $i + 1)
|
||||
done
|
||||
# Now we can copy everything out of the $MOUNTPOINT directory into the target directory
|
||||
rsync -av $MOUNTPOINT/* $MOUNTPOINT/.DS_Store $MOUNTPOINT/.background $MOUNTPOINT/.VolumeIcon.icns $TARGETPATH/.
|
||||
hdiutil detach $MOUNTPOINT
|
||||
rm -rdf $MOUNTPOINT
|
||||
# diskimage-helper prints messages to stdout asynchronously as well, sleep
|
||||
# for a bit to ensure they don't disturb following commands in a script that
|
||||
# might parse stdout messages
|
||||
sleep 5
|
@ -130,6 +130,7 @@ unsigned int ExpandEnvironmentStringsW(const unsigned short* lpSrc,
|
||||
unsigned short * _wgetcwd(unsigned short* dir, unsigned long size);
|
||||
unsigned short *_wfullpath( unsigned short *absPath, const unsigned short *relPath, unsigned long maxLength );
|
||||
int _unlink(const char *filename );
|
||||
int _wchdir(const unsigned short* path);
|
||||
|
||||
/* The time stuff should be defined here, but it can't be because it
|
||||
is already defined in time.h.
|
||||
|
@ -6,6 +6,7 @@ SetEnvironmentVariableW
|
||||
_unlink
|
||||
_wfullpath
|
||||
_wgetcwd
|
||||
_wchdir
|
||||
abort
|
||||
clock
|
||||
errno
|
||||
|
@ -115,10 +115,21 @@ int errno = 0;
|
||||
|
||||
unsigned short * _wgetcwd(unsigned short * dir, unsigned long size)
|
||||
{
|
||||
if (!dir)
|
||||
return 0;
|
||||
unsigned short tmp[MAX_PATH] = {0};
|
||||
GetEnvironmentVariableW(L"CWD", tmp, size);
|
||||
if (tmp && tmp[0]) {
|
||||
if (wcslen(tmp) > size)
|
||||
return 0;
|
||||
wcscpy(dir, tmp);
|
||||
return dir;
|
||||
}
|
||||
unsigned long i;
|
||||
GetModuleFileName(GetModuleHandle (NULL), dir, MAX_PATH);
|
||||
for (i = _tcslen(dir); i && dir[i] != TEXT('\\'); i--) {}
|
||||
dir[i + 1] = TCHAR('\0');
|
||||
SetEnvironmentVariableW(L"CWD", dir);
|
||||
return dir;
|
||||
}
|
||||
|
||||
@ -150,6 +161,10 @@ unsigned short *_wfullpath( unsigned short *absPath, const unsigned short *relPa
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int _wchdir(const WCHAR* path) {
|
||||
return SetEnvironmentVariableW(L"CWD", path);
|
||||
}
|
||||
|
||||
int _unlink(const char *filename)
|
||||
{
|
||||
unsigned short wname[MAX_PATH];
|
||||
|
@ -72,6 +72,7 @@ endif
|
||||
CFLAGS += \
|
||||
-DVC_PATH='"$(subst \,\\,$(VCINSTALLDIR))\\"' \
|
||||
-DWM_SDK_PATH='"$(subst \,\\,$(WINCE_SDK_DIR))\\"' \
|
||||
-DOGLES_SDK_PATH='"$(subst \,\\,$(OGLES_SDK_DIR))\\"' \
|
||||
-DMOZCE_DEVENV='"$(MOZCE_DEVENV)"' \
|
||||
-DTOPSRCDIR='"$(TOPSRCDIR)"' \
|
||||
$(NULL)
|
||||
|
@ -25,6 +25,7 @@ main(int argc, char **argv)
|
||||
#ifdef MOZ_MEMORY
|
||||
args[i++] = "/DMOZ_MEMORY";
|
||||
#endif
|
||||
args[i++] = "/I\"" ATL_INC "\"";
|
||||
args[i++] = "/DMOZCE_STATIC_BUILD";
|
||||
args[i++] = "/DUNICODE";
|
||||
args[i++] = "/D_UNICODE_";
|
||||
@ -38,6 +39,7 @@ main(int argc, char **argv)
|
||||
// args[i++] = "/DPOCKETPC2003_UI_MODEL";
|
||||
args[i++] = "/D_WINDOWS";
|
||||
args[i++] = "/DNO_ERRNO";
|
||||
args[i++] = "/D_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA";
|
||||
|
||||
args[i++] = "/GS-"; // disable security checks
|
||||
args[i++] = "/GR-"; // disable C++ RTTI
|
||||
|
@ -11,11 +11,11 @@ main(int argc, char **argv)
|
||||
int s = 0;
|
||||
args[i++] = RC_PATH;
|
||||
args[i++] = "/I\"" WCE_RC_INC "\"";
|
||||
args[i++] = "/I\"" WM_SDK_INC "\"";
|
||||
args[i++] = "/I\"" WM_SDK_INC "\"";
|
||||
|
||||
argpath_conv(&argv[1], &args[i]);
|
||||
|
||||
// dumpargs(args);
|
||||
//dumpargs(args);
|
||||
|
||||
return run(args);
|
||||
}
|
||||
|
@ -23,8 +23,13 @@ void checkLinkArgs(int* k, int* s, int* i, int* j, char** args, char** argv) {
|
||||
void addLinkArgs(int k, int s, int *i, int *j, char** args, char** argv) {
|
||||
args[(*i)++] = "/LIBPATH:\"" WCE_LIB "\"";
|
||||
args[(*i)++] = "/LIBPATH:\"" WCE_CRT "\"";
|
||||
args[(*i)++] = "/LIBPATH:\"" ATL_LIB "\"";
|
||||
args[(*i)++] = "/LIBPATH:\"" OGLES_SDK_LIB "\"";
|
||||
args[(*i)++] = "/NODEFAULTLIB";
|
||||
|
||||
args[(*i)++] = "/MAP";
|
||||
args[(*i)++] = "/MAPINFO:EXPORTS";
|
||||
|
||||
#ifdef HAVE_SHUNT // simple test to see if we're in configure or not
|
||||
if(getenv("NO_SHUNT") == NULL) {
|
||||
args[(*i)++] = "/LIBPATH:\"" SHUNT_LIB "\"";
|
||||
|
@ -199,8 +199,8 @@ DWORD run(char** args)
|
||||
_putenv("LIBPATH=");
|
||||
_putenv("CC=");
|
||||
|
||||
_putenv("INCLUDE=" SHUNT_INC ";" WM_SDK_INC ";" WCE_INC);
|
||||
_putenv("LIB=" WCE_LIB ";" WCE_CRT);
|
||||
_putenv("INCLUDE=" SHUNT_INC ";" WM_SDK_INC ";" OGLES_SDK_INC ";" WCE_INC);
|
||||
_putenv("LIB=" WCE_LIB ";" OGLES_SDK_LIB ";" WCE_CRT);
|
||||
|
||||
for (j=1; args[j]; j++)
|
||||
{
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include <stdio.h>
|
||||
#include <process.h>
|
||||
|
||||
#define OGLES_SDK_INC OGLES_SDK_PATH "inc"
|
||||
#define OGLES_SDK_LIB OGLES_SDK_PATH "lib\\wince\\nvap\\release"
|
||||
#define WCE_BIN VC_PATH "ce\\bin\\x86_arm\\"
|
||||
#define WCE_RC_BIN WIN_SDK_PATH "bin\\"
|
||||
#define WCE_CRT VC_PATH "ce\\lib\\armv4i"
|
||||
@ -12,6 +14,8 @@
|
||||
#define WCE_LIB WM_SDK_PATH "Lib/Armv4i"
|
||||
#define WCE_RC_INC VC_PATH "ce\\atlmfc\\include"
|
||||
#define WCE_INC VC_PATH "ce\\include"
|
||||
#define ATL_INC VC_PATH "ce\\atlmfc\\include"
|
||||
#define ATL_LIB VC_PATH "ce\\atlmfc\\lib\\armv4i"
|
||||
|
||||
#ifndef SHUNT_LIB
|
||||
#define SHUNT_LIB ""
|
||||
|
@ -584,8 +584,6 @@ GSSAPI_INCLUDES = @GSSAPI_INCLUDES@
|
||||
USE_GSSAPI = @USE_GSSAPI@
|
||||
|
||||
MOZILLA_OFFICIAL = @MOZILLA_OFFICIAL@
|
||||
BUILD_OFFICIAL = @BUILD_OFFICIAL@
|
||||
MOZ_MILESTONE_RELEASE = @MOZ_MILESTONE_RELEASE@
|
||||
|
||||
# Win32 options
|
||||
MOZ_BROWSE_INFO = @MOZ_BROWSE_INFO@
|
||||
@ -622,8 +620,12 @@ MOZ_PHOENIX = @MOZ_PHOENIX@
|
||||
MOZ_XULRUNNER = @MOZ_XULRUNNER@
|
||||
WINCE = @WINCE@
|
||||
WINCE_SDK_DIR = @WINCE_SDK_DIR@
|
||||
OGLES_SDK_DIR = @OGLES_SDK_DIR@
|
||||
|
||||
WINCE_WINDOWS_MOBILE = @WINCE_WINDOWS_MOBILE@
|
||||
|
||||
HAS_OGLES = @HAS_OGLES@
|
||||
|
||||
MOZ_DISTRIBUTION_ID = @MOZ_DISTRIBUTION_ID@
|
||||
|
||||
NS_OSSO = @NS_OSSO@
|
||||
|
@ -44,9 +44,6 @@ include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
USE_STATIC_LIBS = 1
|
||||
|
||||
# undefine (as best we can, thanks gmake!) so we don't need build_number
|
||||
MOZILLA_OFFICIAL =
|
||||
BUILD_OFFICIAL =
|
||||
MODULE = mkdepend
|
||||
HOST_PROGRAM = mkdepend$(BIN_SUFFIX)
|
||||
ifdef GNU_CC
|
||||
|
@ -47,7 +47,7 @@ ifndef RESFILE
|
||||
RCFILE=./module.rc
|
||||
RESFILE=./module.res
|
||||
_RC_STRING = -QUIET 1 -DEPTH $(DEPTH) -TOPSRCDIR $(topsrcdir) -BITS $(MOZ_BITS) -OBJDIR . -SRCDIR $(srcdir) -DISPNAME $(MOZ_APP_DISPLAYNAME) -APPVERSION $(MOZ_APP_VERSION)
|
||||
ifneq ($(BUILD_OFFICIAL)_$(MOZILLA_OFFICIAL),_)
|
||||
ifdef MOZILLA_OFFICIAL
|
||||
_RC_STRING += -OFFICIAL 1
|
||||
endif
|
||||
ifdef MOZ_DEBUG
|
||||
|
47
configure.in
47
configure.in
@ -242,6 +242,11 @@ case "$target" in
|
||||
The path to the Windows CE SDK],
|
||||
WINCE_SDK_DIR=$withval)
|
||||
|
||||
MOZ_ARG_WITH_STRING(ogles-sdk,
|
||||
[ --with-ogles-sdk=OGLES_SDK_DIR
|
||||
The path to the OGLES SDK],
|
||||
OGLES_SDK_DIR=$withval)
|
||||
|
||||
dnl Default to Windows Mobile components enabled
|
||||
WINCE_WINDOWS_MOBILE=1
|
||||
|
||||
@ -268,7 +273,7 @@ case "$target" in
|
||||
|
||||
_pwdw=`pwd -W`
|
||||
_pwd=`pwd`
|
||||
make WINCE_SDK_DIR="$WINCE_SDK_DIR" TOPSRCDIR="$_topsrcdir" OBJDIR="$_pwdw" -C $srcdir/build/wince/tools
|
||||
make OGLES_SDK_DIR="$OGLES_SDK_DIR" WINCE_SDK_DIR="$WINCE_SDK_DIR" TOPSRCDIR="$_topsrcdir" OBJDIR="$_pwdw" -C $srcdir/build/wince/tools
|
||||
|
||||
CC="$_pwd/dist/sdk/bin/arm-wince-gcc"
|
||||
CXX="$_pwd/dist/sdk/bin/arm-wince-gcc"
|
||||
@ -3205,7 +3210,6 @@ else
|
||||
[MISSING_X="$MISSING_X -lX11"], $XLIBS)
|
||||
AC_CHECK_LIB(Xext, XextAddDisplay, [XEXT_LIBS="-lXext"],
|
||||
[MISSING_X="$MISSING_X -lXext"], $XLIBS)
|
||||
echo "green"
|
||||
|
||||
AC_CHECK_LIB(Xt, XtFree, [ XT_LIBS="-lXt"], [
|
||||
unset ac_cv_lib_Xt_XtFree
|
||||
@ -4210,7 +4214,7 @@ MOZ_ARG_WITH_BOOL(system-nspr,
|
||||
_USE_SYSTEM_NSPR=1 )
|
||||
|
||||
if test -n "$_USE_SYSTEM_NSPR"; then
|
||||
AM_PATH_NSPR(4.7.0, [MOZ_NATIVE_NSPR=1], [MOZ_NATIVE_NSPR=])
|
||||
AM_PATH_NSPR(4.8.0, [MOZ_NATIVE_NSPR=1], [MOZ_NATIVE_NSPR=])
|
||||
fi
|
||||
|
||||
if test -n "$MOZ_NATIVE_NSPR"; then
|
||||
@ -7626,19 +7630,36 @@ if test "$MOZ_TREE_CAIRO"; then
|
||||
if test "$MOZ_WIDGET_TOOLKIT" = "windows"; then
|
||||
WIN32_SURFACE_FEATURE="#define CAIRO_HAS_WIN32_SURFACE 1"
|
||||
if test -z "$WINCE"; then
|
||||
WIN32_FONT_FEATURE="#define CAIRO_HAS_WIN32_FONT 1"
|
||||
DDRAW_SURFACE_FEATURE=
|
||||
WIN32_FONT_FEATURE="#define CAIRO_HAS_WIN32_FONT 1"
|
||||
else
|
||||
WIN32_FONT_FEATURE=
|
||||
WIN32_FONT_FEATURE=
|
||||
fi
|
||||
|
||||
AC_TRY_COMPILE([#include <ddraw.h>], [int foo = DDLOCK_WAITNOTBUSY;], HAS_DDRAW=1, HAS_DDRAW=)
|
||||
if test -z "$HAS_DDRAW"; then
|
||||
AC_MSG_WARN([DirectDraw ddraw.h header not found or it's missing DDLOCK_WAITNOTBUSY, disabling DirectDraw surface. If you have an older SDK (such as the CE5 SDK), try copying in ddraw.lib and ddraw.h from the WM6 SDK.])
|
||||
DDRAW_SURFACE_FEATURE=
|
||||
AC_MSG_WARN([DirectDraw ddraw.h header not found or it's missing DDLOCK_WAITNOTBUSY, disabling DirectDraw surface. If you have an older SDK (such as the CE5 SDK), try copying in ddraw.lib and ddraw.h from the WM6 SDK.])
|
||||
DDRAW_SURFACE_FEATURE=
|
||||
else
|
||||
DDRAW_SURFACE_FEATURE="#define CAIRO_HAS_DDRAW_SURFACE 1"
|
||||
DDRAW_SURFACE_FEATURE="#define CAIRO_HAS_DDRAW_SURFACE 1"
|
||||
fi
|
||||
|
||||
if test -z "$OGLES_SDK_DIR"; then
|
||||
OGLES_SURFACE_FEATURE=
|
||||
else
|
||||
AC_TRY_COMPILE([
|
||||
#include <EGL/egl.h>
|
||||
#include <EGL/eglext.h>
|
||||
#include <GLES2/gl2.h>
|
||||
#include <GLES2/gl2ext.h>
|
||||
], [ EGLDisplay _cairo_ddraw_egl_dpy = EGL_NO_DISPLAY;], HAS_OGLES=1, HAS_OGLES=)
|
||||
if test -z "$HAS_OGLES"; then
|
||||
AC_MSG_WARN([OpenGL ES2 headers not found, disabling OpenGL acceleration surfaces.])
|
||||
OGLES_SURFACE_FEATURE=
|
||||
else
|
||||
OGLES_SURFACE_FEATURE="#define CAIRO_DDRAW_USE_GL 1"
|
||||
fi
|
||||
fi
|
||||
|
||||
PDF_SURFACE_FEATURE="#define CAIRO_HAS_PDF_SURFACE 1"
|
||||
fi
|
||||
if test "$MOZ_WIDGET_TOOLKIT" = "os2"; then
|
||||
@ -7659,6 +7680,7 @@ if test "$MOZ_TREE_CAIRO"; then
|
||||
fi
|
||||
AC_SUBST(MOZ_ENABLE_CAIRO_FT)
|
||||
AC_SUBST(CAIRO_FT_CFLAGS)
|
||||
AC_SUBST(HAS_OGLES)
|
||||
|
||||
if test "$MOZ_DEBUG"; then
|
||||
SANITY_CHECKING_FEATURE="#define CAIRO_DO_SANITY_CHECKING 1"
|
||||
@ -7678,6 +7700,7 @@ if test "$MOZ_TREE_CAIRO"; then
|
||||
AC_SUBST(XCB_SURFACE_FEATURE)
|
||||
AC_SUBST(WIN32_SURFACE_FEATURE)
|
||||
AC_SUBST(DDRAW_SURFACE_FEATURE)
|
||||
AC_SUBST(OGLES_SURFACE_FEATURE)
|
||||
AC_SUBST(OS2_SURFACE_FEATURE)
|
||||
AC_SUBST(BEOS_SURFACE_FEATURE)
|
||||
AC_SUBST(DIRECTFB_SURFACE_FEATURE)
|
||||
@ -8117,8 +8140,7 @@ AC_SUBST(MOZ_OS2_USE_DECLSPEC)
|
||||
AC_SUBST(MOZ_POST_DSO_LIB_COMMAND)
|
||||
AC_SUBST(MOZ_POST_PROGRAM_COMMAND)
|
||||
AC_SUBST(MOZ_TIMELINE)
|
||||
AC_SUBST(WINCE)
|
||||
AC_SUBST(WINCE_SDK_DIR)
|
||||
AC_SUBST(OGLES_SDK_DIR)
|
||||
|
||||
AC_SUBST(MOZ_APP_NAME)
|
||||
AC_SUBST(MOZ_APP_DISPLAYNAME)
|
||||
@ -8128,8 +8150,6 @@ AC_SUBST(FIREFOX_VERSION)
|
||||
AC_SUBST(MOZ_PKG_SPECIAL)
|
||||
|
||||
AC_SUBST(MOZILLA_OFFICIAL)
|
||||
AC_SUBST(BUILD_OFFICIAL)
|
||||
AC_SUBST(MOZ_MILESTONE_RELEASE)
|
||||
|
||||
dnl win32 options
|
||||
AC_SUBST(MOZ_DEBUG_SYMBOLS)
|
||||
@ -8142,6 +8162,7 @@ AC_SUBST(WIN32_REDIST_DIR)
|
||||
AC_SUBST(PYTHON)
|
||||
|
||||
AC_SUBST(WINCE)
|
||||
AC_SUBST(WINCE_SDK_DIR)
|
||||
AC_SUBST(WINCE_WINDOWS_MOBILE)
|
||||
|
||||
dnl Echo the CFLAGS to remove extra whitespace.
|
||||
|
@ -81,6 +81,7 @@ class nsIURI;
|
||||
class imgIDecoderObserver;
|
||||
class imgIRequest;
|
||||
class imgILoader;
|
||||
class imgICache;
|
||||
class nsIPrefBranch;
|
||||
class nsIImage;
|
||||
class nsIImageLoadingContent;
|
||||
@ -647,6 +648,11 @@ public:
|
||||
PRInt32 aLoadFlags,
|
||||
imgIRequest** aRequest);
|
||||
|
||||
/**
|
||||
* Returns whether the given URI is in the image cache.
|
||||
*/
|
||||
static PRBool IsImageInCache(nsIURI* aURI);
|
||||
|
||||
/**
|
||||
* Method to get an nsIImage from an image loading content
|
||||
*
|
||||
@ -1504,6 +1510,7 @@ private:
|
||||
static nsIPref *sPref;
|
||||
|
||||
static imgILoader* sImgLoader;
|
||||
static imgICache* sImgCache;
|
||||
|
||||
static nsIConsoleService* sConsoleService;
|
||||
|
||||
|
@ -105,8 +105,8 @@ class nsIBoxObject;
|
||||
|
||||
// IID for the nsIDocument interface
|
||||
#define NS_IDOCUMENT_IID \
|
||||
{0x2c155ed0, 0x3302, 0x4cff, \
|
||||
{0x9d, 0xb3, 0xed, 0x0c, 0xcd, 0xfc, 0x50, 0x06 } }
|
||||
{ 0x46003091, 0x7f99, 0x420f, \
|
||||
{ 0x95, 0xbc, 0x28, 0xd7, 0xd5, 0x01, 0x5a, 0x41 } }
|
||||
|
||||
// Flag for AddStyleSheet().
|
||||
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
|
||||
@ -1148,6 +1148,14 @@ public:
|
||||
PRUint32 EventHandlingSuppressed() const { return mEventsSuppressed; }
|
||||
|
||||
PRBool IsDNSPrefetchAllowed() const { return mAllowDNSPrefetch; }
|
||||
|
||||
/**
|
||||
* Called by nsParser to preload images. Can be removed and code moved
|
||||
* to nsPreloadURIs::PreloadURIs() in file nsParser.cpp whenever the
|
||||
* parser-module is linked with gklayout-module.
|
||||
*/
|
||||
virtual void MaybePreLoadImage(nsIURI* uri) = 0;
|
||||
|
||||
protected:
|
||||
~nsIDocument()
|
||||
{
|
||||
|
@ -36,6 +36,7 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsIObserver.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
||||
class nsCCUncollectableMarker : public nsIObserver
|
||||
{
|
||||
@ -50,8 +51,11 @@ class nsCCUncollectableMarker : public nsIObserver
|
||||
/**
|
||||
* Checks if we're collecting during a given generation
|
||||
*/
|
||||
static PRBool InGeneration(PRUint32 aGeneration) {
|
||||
return aGeneration && aGeneration == sGeneration;
|
||||
static PRBool InGeneration(nsCycleCollectionTraversalCallback &cb,
|
||||
PRUint32 aGeneration) {
|
||||
return !cb.WantAllTraces() &&
|
||||
aGeneration &&
|
||||
aGeneration == sGeneration;
|
||||
}
|
||||
|
||||
static PRUint32 sGeneration;
|
||||
|
@ -1780,7 +1780,7 @@ nsContentSink::ReadyToCallDidBuildModelImpl(PRBool aTerminated)
|
||||
}
|
||||
|
||||
if (mScriptLoader) {
|
||||
mScriptLoader->EndDeferringScripts(aTerminated);
|
||||
mScriptLoader->ParsingComplete(aTerminated);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -179,6 +179,7 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID);
|
||||
#include "nsIConsoleService.h"
|
||||
|
||||
#include "mozAutoDocUpdate.h"
|
||||
#include "imgICache.h"
|
||||
#include "jsinterp.h"
|
||||
|
||||
const char kLoadAsData[] = "loadAsData";
|
||||
@ -200,6 +201,7 @@ nsIXTFService *nsContentUtils::sXTFService = nsnull;
|
||||
nsIPrefBranch *nsContentUtils::sPrefBranch = nsnull;
|
||||
nsIPref *nsContentUtils::sPref = nsnull;
|
||||
imgILoader *nsContentUtils::sImgLoader;
|
||||
imgICache *nsContentUtils::sImgCache;
|
||||
nsIConsoleService *nsContentUtils::sConsoleService;
|
||||
nsDataHashtable<nsISupportsHashKey, EventNameMapping>* nsContentUtils::sEventTable = nsnull;
|
||||
nsIStringBundleService *nsContentUtils::sStringBundleService;
|
||||
@ -330,6 +332,10 @@ nsContentUtils::Init()
|
||||
if (NS_FAILED(rv)) {
|
||||
// no image loading for us. Oh, well.
|
||||
sImgLoader = nsnull;
|
||||
sImgCache = nsnull;
|
||||
} else {
|
||||
if (NS_FAILED(CallGetService("@mozilla.org/image/cache;1", &sImgCache )))
|
||||
sImgCache = nsnull;
|
||||
}
|
||||
|
||||
sPtrsToPtrsToRelease = new nsTArray<nsISupports**>();
|
||||
@ -893,6 +899,7 @@ nsContentUtils::Shutdown()
|
||||
NS_IF_RELEASE(sXTFService);
|
||||
#endif
|
||||
NS_IF_RELEASE(sImgLoader);
|
||||
NS_IF_RELEASE(sImgCache);
|
||||
NS_IF_RELEASE(sPrefBranch);
|
||||
NS_IF_RELEASE(sPref);
|
||||
#ifdef IBMBIDI
|
||||
@ -2383,6 +2390,19 @@ nsContentUtils::CanLoadImage(nsIURI* aURI, nsISupports* aContext,
|
||||
return NS_FAILED(rv) ? PR_FALSE : NS_CP_ACCEPTED(decision);
|
||||
}
|
||||
|
||||
// static
|
||||
PRBool
|
||||
nsContentUtils::IsImageInCache(nsIURI* aURI)
|
||||
{
|
||||
if (!sImgCache) return PR_FALSE;
|
||||
|
||||
// If something unexpected happened we return false, otherwise if props
|
||||
// is set, the image is cached and we return true
|
||||
nsCOMPtr<nsIProperties> props;
|
||||
nsresult rv = sImgCache->FindEntryProperties(aURI, getter_AddRefs(props));
|
||||
return (NS_SUCCEEDED(rv) && props);
|
||||
}
|
||||
|
||||
// static
|
||||
nsresult
|
||||
nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument,
|
||||
|
@ -1723,7 +1723,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDocument)
|
||||
// if we're uncollectable.
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
|
||||
|
||||
if (nsCCUncollectableMarker::InGeneration(tmp->GetMarkedCCGeneration())) {
|
||||
if (nsCCUncollectableMarker::InGeneration(cb, tmp->GetMarkedCCGeneration())) {
|
||||
return NS_SUCCESS_INTERRUPTED_TRAVERSE;
|
||||
}
|
||||
|
||||
@ -1780,6 +1780,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDocument)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mStyleSheets)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mCatalogSheets)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mVisitednessChangedURIs)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mPreloadingImages)
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
// Traverse animation components
|
||||
@ -1824,6 +1825,8 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDocument)
|
||||
|
||||
tmp->mParentDocument = nsnull;
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mPreloadingImages)
|
||||
|
||||
// nsDocument has a pretty complex destructor, so we're going to
|
||||
// assume that *most* cycles you actually want to break somewhere
|
||||
// else, and not unlink an awful lot here.
|
||||
@ -3863,6 +3866,9 @@ nsDocument::DispatchContentLoadedEvents()
|
||||
// If you add early returns from this method, make sure you're
|
||||
// calling UnblockOnload properly.
|
||||
|
||||
// Unpin references to preloaded images
|
||||
mPreloadingImages.Clear();
|
||||
|
||||
// Fire a DOM event notifying listeners that this document has been
|
||||
// loaded (excluding images and other loads initiated by this
|
||||
// document).
|
||||
@ -7485,6 +7491,34 @@ FireOrClearDelayedEvents(nsTArray<nsCOMPtr<nsIDocument> >& aDocuments,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::MaybePreLoadImage(nsIURI* uri)
|
||||
{
|
||||
// Early exit if the img is already present in the img-cache
|
||||
// which indicates that the "real" load has already started and
|
||||
// that we shouldn't preload it.
|
||||
if (nsContentUtils::IsImageInCache(uri)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Image not in cache - trigger preload
|
||||
nsCOMPtr<imgIRequest> request;
|
||||
nsresult rv =
|
||||
nsContentUtils::LoadImage(uri,
|
||||
this,
|
||||
NodePrincipal(),
|
||||
mDocumentURI, // uri of document used as referrer
|
||||
nsnull, // no observer
|
||||
nsIRequest::LOAD_NORMAL,
|
||||
getter_AddRefs(request));
|
||||
|
||||
// Pin image-reference to avoid evicting it from the img-cache before
|
||||
// the "real" load occurs. Unpinned in DispatchContentLoadedEvents and
|
||||
// unlink
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mPreloadingImages.AppendObject(request);
|
||||
}
|
||||
}
|
||||
class nsDelayedEventDispatcher : public nsRunnable
|
||||
{
|
||||
public:
|
||||
|
@ -116,6 +116,7 @@
|
||||
#include "nsIProgressEventSink.h"
|
||||
#include "nsISecurityEventSink.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
#include "imgIRequest.h"
|
||||
|
||||
#define XML_DECLARATION_BITS_DECLARATION_EXISTS (1 << 0)
|
||||
#define XML_DECLARATION_BITS_ENCODING_EXISTS (1 << 1)
|
||||
@ -1006,6 +1007,8 @@ public:
|
||||
void MaybeInitializeFinalizeFrameLoaders();
|
||||
|
||||
void MaybeEndOutermostXBLUpdate();
|
||||
|
||||
virtual void MaybePreLoadImage(nsIURI* uri);
|
||||
protected:
|
||||
|
||||
void RegisterNamedItems(nsIContent *aContent);
|
||||
@ -1264,6 +1267,9 @@ private:
|
||||
|
||||
nsExternalResourceMap mExternalResourceMap;
|
||||
|
||||
// All images in process of being preloaded
|
||||
nsCOMArray<imgIRequest> mPreloadingImages;
|
||||
|
||||
#ifdef MOZ_SMIL
|
||||
nsAutoPtr<nsSMILAnimationController> mAnimationController;
|
||||
#endif // MOZ_SMIL
|
||||
|
@ -91,7 +91,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsGenericDOMDataNode)
|
||||
|
||||
nsIDocument* currentDoc = tmp->GetCurrentDoc();
|
||||
if (currentDoc && nsCCUncollectableMarker::InGeneration(
|
||||
currentDoc->GetMarkedCCGeneration())) {
|
||||
cb, currentDoc->GetMarkedCCGeneration())) {
|
||||
return NS_SUCCESS_INTERRUPTED_TRAVERSE;
|
||||
}
|
||||
|
||||
|
@ -4009,7 +4009,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsGenericElement)
|
||||
|
||||
nsIDocument* currentDoc = tmp->GetCurrentDoc();
|
||||
if (currentDoc && nsCCUncollectableMarker::InGeneration(
|
||||
currentDoc->GetMarkedCCGeneration())) {
|
||||
cb, currentDoc->GetMarkedCCGeneration())) {
|
||||
return NS_SUCCESS_INTERRUPTED_TRAVERSE;
|
||||
}
|
||||
|
||||
|
@ -1029,23 +1029,24 @@ nsScriptLoader::ShouldExecuteScript(nsIDocument* aDocument,
|
||||
}
|
||||
|
||||
void
|
||||
nsScriptLoader::EndDeferringScripts(PRBool aKillDeferred)
|
||||
nsScriptLoader::ParsingComplete(PRBool aTerminated)
|
||||
{
|
||||
if (mDeferEnabled) {
|
||||
// Have to check because we apparently get EndDeferringScripts
|
||||
// Have to check because we apparently get ParsingComplete
|
||||
// without BeginDeferringScripts in some cases
|
||||
mUnblockOnloadWhenDoneProcessing = PR_TRUE;
|
||||
}
|
||||
mDeferEnabled = PR_FALSE;
|
||||
for (PRUint32 i = 0; i < (PRUint32)mRequests.Count(); ++i) {
|
||||
if (aKillDeferred && mRequests[i]->mDefer) {
|
||||
mRequests.RemoveObjectAt(i--);
|
||||
}
|
||||
else {
|
||||
if (aTerminated) {
|
||||
mRequests.Clear();
|
||||
} else {
|
||||
for (PRUint32 i = 0; i < (PRUint32)mRequests.Count(); ++i) {
|
||||
mRequests[i]->mDefer = PR_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// Have to call this even if aTerminated so we'll correctly unblock
|
||||
// onload and all.
|
||||
ProcessPendingRequests();
|
||||
}
|
||||
|
||||
|
@ -209,16 +209,15 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops defering scripts and immediately processes the mDeferredRequests
|
||||
* queue.
|
||||
* Notifies the script loader that parsing is done. If aTerminated is true,
|
||||
* this will drop any pending scripts that haven't run yet. Otherwise, it
|
||||
* will stops deferring scripts and immediately processes the
|
||||
* mDeferredRequests queue.
|
||||
*
|
||||
* WARNING: This function will syncronously execute content scripts, so be
|
||||
* WARNING: This function will synchronously execute content scripts, so be
|
||||
* prepared that the world might change around you.
|
||||
*
|
||||
* If aKillDeferred is PR_TRUE, deferred scripts won't be run, but instead
|
||||
* removed.
|
||||
*/
|
||||
void EndDeferringScripts(PRBool aKillDeferred);
|
||||
void ParsingComplete(PRBool aTerminated);
|
||||
|
||||
/**
|
||||
* Returns the number of pending scripts, deferred or not.
|
||||
|
@ -1267,6 +1267,12 @@ IsAccessKeyTarget(nsIContent* aContent, nsIFrame* aFrame, nsAString& aKey)
|
||||
tag == nsGkAtoms::label ||
|
||||
tag == nsGkAtoms::legend)
|
||||
return PR_TRUE;
|
||||
|
||||
} else if (aContent->IsNodeOfType(nsINode::eXUL)) {
|
||||
// XUL label elements are never focusable, so we need to check for them
|
||||
// explicitly before giving up.
|
||||
if (aContent->Tag() == nsGkAtoms::label)
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
|
@ -1139,14 +1139,14 @@ nsGenericHTMLElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
PRBool contentEditable = PR_FALSE;
|
||||
PRInt32 contentEditableChange;
|
||||
|
||||
if (aNameSpaceID == kNameSpaceID_None) {
|
||||
contentEditable = PR_TRUE;
|
||||
contentEditableChange = GetContentEditableValue() == eTrue ? -1 : 0;
|
||||
}
|
||||
|
||||
// Check for event handlers
|
||||
if (aNameSpaceID == kNameSpaceID_None) {
|
||||
if (nsContentUtils::IsEventAttributeName(aAttribute, EventNameType_HTML)) {
|
||||
if (aAttribute == nsGkAtoms::contenteditable) {
|
||||
contentEditable = PR_TRUE;
|
||||
contentEditableChange = GetContentEditableValue() == eTrue ? -1 : 0;
|
||||
}
|
||||
else if (nsContentUtils::IsEventAttributeName(aAttribute,
|
||||
EventNameType_HTML)) {
|
||||
nsIEventListenerManager* manager = GetListenerManager(PR_FALSE);
|
||||
if (manager) {
|
||||
manager->RemoveScriptEventListener(aAttribute);
|
||||
|
@ -59,6 +59,8 @@
|
||||
|
||||
#include "nsICanvasRenderingContextInternal.h"
|
||||
|
||||
#include "nsLayoutUtils.h"
|
||||
|
||||
#define DEFAULT_CANVAS_WIDTH 300
|
||||
#define DEFAULT_CANVAS_HEIGHT 150
|
||||
|
||||
@ -544,7 +546,14 @@ nsHTMLCanvasElement::SetWriteOnly()
|
||||
NS_IMETHODIMP
|
||||
nsHTMLCanvasElement::InvalidateFrame()
|
||||
{
|
||||
nsIFrame *frame = GetPrimaryFrame(Flush_Frames);
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
if (!doc) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// We don't need to flush anything here; if there's no frame or if
|
||||
// we plan to reframe we don't need to invalidate it anyway.
|
||||
nsIFrame *frame = GetPrimaryFrameFor(this, doc);
|
||||
if (frame) {
|
||||
nsRect r = frame->GetRect();
|
||||
r.x = r.y = 0;
|
||||
@ -557,8 +566,20 @@ nsHTMLCanvasElement::InvalidateFrame()
|
||||
NS_IMETHODIMP
|
||||
nsHTMLCanvasElement::InvalidateFrameSubrect(const gfxRect& damageRect)
|
||||
{
|
||||
nsIFrame *frame = GetPrimaryFrame(Flush_Frames);
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
if (!doc) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// We don't need to flush anything here; if there's no frame or if
|
||||
// we plan to reframe we don't need to invalidate it anyway.
|
||||
nsIFrame *frame = GetPrimaryFrameFor(this, doc);
|
||||
if (frame) {
|
||||
// Frame might be dirty, but we don't care about that; if the geometry
|
||||
// changes the right invalidates will happen anyway. Don't assert on our
|
||||
// geometry getters.
|
||||
nsAutoDisableGetUsedXAssertions noAssert;
|
||||
|
||||
nsRect contentArea(frame->GetContentRect());
|
||||
nsIntSize size = GetWidthHeight();
|
||||
|
||||
|
@ -172,6 +172,12 @@ void nsHTMLMediaElement::QueueLoadFromSourceTask()
|
||||
NS_DispatchToMainThread(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* There is a reference cycle involving this class: MediaLoadListener
|
||||
* holds a reference to the nsHTMLMediaElement, which holds a reference
|
||||
* to an nsIChannel, which holds a reference to this listener.
|
||||
* We break the reference cycle in OnStartRequest by clearing mElement.
|
||||
*/
|
||||
class nsHTMLMediaElement::MediaLoadListener : public nsIStreamListener,
|
||||
public nsIChannelEventSink,
|
||||
public nsIInterfaceRequestor
|
||||
@ -200,30 +206,35 @@ NS_IMPL_ISUPPORTS4(nsHTMLMediaElement::MediaLoadListener, nsIRequestObserver,
|
||||
|
||||
NS_IMETHODIMP nsHTMLMediaElement::MediaLoadListener::OnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
|
||||
{
|
||||
// The element is only needed until we've had a chance to call
|
||||
// InitializeDecoderForChannel. So make sure mElement is cleared here.
|
||||
nsRefPtr<nsHTMLMediaElement> element;
|
||||
element.swap(mElement);
|
||||
|
||||
// Don't continue to load if the request failed or has been canceled.
|
||||
nsresult rv;
|
||||
nsresult status;
|
||||
rv = aRequest->GetStatus(&status);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (NS_FAILED(status)) {
|
||||
if (mElement)
|
||||
mElement->NotifyLoadError();
|
||||
if (element)
|
||||
element->NotifyLoadError();
|
||||
return status;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
|
||||
if (channel &&
|
||||
mElement &&
|
||||
NS_SUCCEEDED(rv = mElement->InitializeDecoderForChannel(channel, getter_AddRefs(mNextListener))) &&
|
||||
element &&
|
||||
NS_SUCCEEDED(rv = element->InitializeDecoderForChannel(channel, getter_AddRefs(mNextListener))) &&
|
||||
mNextListener) {
|
||||
rv = mNextListener->OnStartRequest(aRequest, aContext);
|
||||
} else {
|
||||
// If InitializeDecoderForChannel() returned an error, fire a network
|
||||
// error.
|
||||
if (NS_FAILED(rv) && !mNextListener && mElement) {
|
||||
if (NS_FAILED(rv) && !mNextListener && element) {
|
||||
// Load failed, attempt to load the next candidate resource. If there
|
||||
// are none, this will trigger a MEDIA_ERR_NONE_SUPPORTED error.
|
||||
mElement->NotifyLoadError();
|
||||
element->NotifyLoadError();
|
||||
}
|
||||
// If InitializeDecoderForChannel did not return a listener (but may
|
||||
// have otherwise succeeded), we abort the connection since we aren't
|
||||
@ -231,10 +242,6 @@ NS_IMETHODIMP nsHTMLMediaElement::MediaLoadListener::OnStartRequest(nsIRequest*
|
||||
rv = NS_BINDING_ABORTED;
|
||||
}
|
||||
|
||||
// The element is only needed until we've had a chance to call
|
||||
// InitializeDecoderForChannel.
|
||||
mElement = nsnull;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -268,18 +268,31 @@ nsHTMLTableRowElement::InsertCell(PRInt32 aIndex, nsIDOMHTMLElement** aValue)
|
||||
if (aIndex < -1) {
|
||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||
}
|
||||
|
||||
|
||||
// Make sure mCells is initialized.
|
||||
nsCOMPtr<nsIDOMHTMLCollection> cells;
|
||||
GetCells(getter_AddRefs(cells));
|
||||
|
||||
PRUint32 cellCount;
|
||||
cells->GetLength(&cellCount);
|
||||
|
||||
if (aIndex > PRInt32(cellCount)) {
|
||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||
nsresult rv = GetCells(getter_AddRefs(cells));
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRBool doInsert = (aIndex < PRInt32(cellCount)) && (aIndex != -1);
|
||||
NS_ASSERTION(mCells, "How did that happen?");
|
||||
|
||||
nsCOMPtr<nsIDOMNode> nextSibling;
|
||||
// -1 means append, so should use null nextSibling
|
||||
if (aIndex != -1) {
|
||||
cells->Item(aIndex, getter_AddRefs(nextSibling));
|
||||
// Check whether we're inserting past end of list. We want to avoid doing
|
||||
// this unless we really have to, since this has to walk all our kids. If
|
||||
// we have a nextSibling, we're clearly not past end of list.
|
||||
if (!nextSibling) {
|
||||
PRUint32 cellCount;
|
||||
cells->GetLength(&cellCount);
|
||||
if (aIndex > PRInt32(cellCount)) {
|
||||
return NS_ERROR_DOM_INDEX_SIZE_ERR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// create the cell
|
||||
nsCOMPtr<nsINodeInfo> nodeInfo;
|
||||
@ -295,16 +308,7 @@ nsHTMLTableRowElement::InsertCell(PRInt32 aIndex, nsIDOMHTMLElement** aValue)
|
||||
NS_ASSERTION(cellNode, "Should implement nsIDOMNode!");
|
||||
|
||||
nsCOMPtr<nsIDOMNode> retChild;
|
||||
|
||||
nsresult rv;
|
||||
if (doInsert) {
|
||||
nsCOMPtr<nsIDOMNode> refCell;
|
||||
cells->Item(aIndex, getter_AddRefs(refCell));
|
||||
|
||||
rv = InsertBefore(cellNode, refCell, getter_AddRefs(retChild));
|
||||
} else {
|
||||
rv = AppendChild(cellNode, getter_AddRefs(retChild));
|
||||
}
|
||||
InsertBefore(cellNode, nextSibling, getter_AddRefs(retChild));
|
||||
|
||||
if (retChild) {
|
||||
CallQueryInterface(retChild, aValue);
|
||||
|
@ -30,41 +30,113 @@ function runTest()
|
||||
var focused;
|
||||
anchorInEditor.onfocus = function() { focused = true; };
|
||||
|
||||
function isReallyEditable()
|
||||
{
|
||||
editor.focus();
|
||||
var range = document.createRange();
|
||||
range.selectNodeContents(editor);
|
||||
var prevStr = range.toString();
|
||||
|
||||
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
|
||||
var docShell =
|
||||
window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsIWebNavigation)
|
||||
.QueryInterface(Components.interfaces.nsIDocShell);
|
||||
var controller =
|
||||
docShell.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
|
||||
.getInterface(Components.interfaces.nsISelectionDisplay)
|
||||
.QueryInterface(Components.interfaces.nsISelectionController);
|
||||
var sel = controller.getSelection(controller.SELECTION_NORMAL);
|
||||
sel.collapse(anchorInEditor, 0);
|
||||
synthesizeKey('a', {});
|
||||
range.selectNodeContents(editor);
|
||||
return prevStr != range.toString();
|
||||
}
|
||||
|
||||
focused = false;
|
||||
anchor.focus();
|
||||
editor.setAttribute("contenteditable", "true");
|
||||
anchorInEditor.focus();
|
||||
is(focused, false, "focus moved to element in contenteditable=true");
|
||||
is(isReallyEditable(), true, "cannot edit by a key event");
|
||||
|
||||
// for bug 502273
|
||||
focused = false;
|
||||
anchor.focus();
|
||||
editor.setAttribute("dummy", "dummy");
|
||||
editor.removeAttribute("dummy");
|
||||
anchorInEditor.focus();
|
||||
is(focused, false, "focus moved to element in contenteditable=true (after dummy attribute was removed)");
|
||||
is(isReallyEditable(), true, "cannot edit by a key event");
|
||||
|
||||
focused = false;
|
||||
anchor.focus();
|
||||
editor.setAttribute("contenteditable", "false");
|
||||
anchorInEditor.focus();
|
||||
is(focused, true, "focus didn't move to element in contenteditable=false");
|
||||
is(isReallyEditable(), false, "can edit by a key event");
|
||||
|
||||
// for bug 502273
|
||||
focused = false;
|
||||
anchor.focus();
|
||||
editor.setAttribute("dummy", "dummy");
|
||||
editor.removeAttribute("dummy");
|
||||
anchorInEditor.focus();
|
||||
is(focused, true, "focus moved to element in contenteditable=true (after dummy attribute was removed)");
|
||||
is(isReallyEditable(), false, "cannot edit by a key event");
|
||||
|
||||
focused = false;
|
||||
anchor.focus();
|
||||
editor.setAttribute("contenteditable", "true");
|
||||
anchorInEditor.focus();
|
||||
is(focused, false, "focus moved to element in contenteditable=true");
|
||||
is(isReallyEditable(), true, "cannot edit by a key event");
|
||||
|
||||
// for bug 502273
|
||||
focused = false;
|
||||
anchor.focus();
|
||||
editor.setAttribute("dummy", "dummy");
|
||||
editor.removeAttribute("dummy");
|
||||
anchorInEditor.focus();
|
||||
is(focused, false, "focus moved to element in contenteditable=true (after dummy attribute was removed)");
|
||||
is(isReallyEditable(), true, "cannot edit by a key event");
|
||||
|
||||
focused = false;
|
||||
anchor.focus();
|
||||
editor.removeAttribute("contenteditable");
|
||||
anchorInEditor.focus();
|
||||
is(focused, true, "focus didn't move to element in contenteditable removed element");
|
||||
is(isReallyEditable(), false, "can edit by a key event");
|
||||
|
||||
focused = false;
|
||||
anchor.focus();
|
||||
editor.contentEditable = true;
|
||||
anchorInEditor.focus();
|
||||
is(focused, false, "focus moved to element in contenteditable=true by property");
|
||||
is(isReallyEditable(), true, "cannot edit by a key event");
|
||||
|
||||
focused = false;
|
||||
anchor.focus();
|
||||
editor.contentEditable = false;
|
||||
anchorInEditor.focus();
|
||||
is(focused, true, "focus didn't move to element in contenteditable=false by property");
|
||||
is(isReallyEditable(), false, "can edit by a key event");
|
||||
|
||||
focused = false;
|
||||
anchor.focus();
|
||||
editor.setAttribute("contenteditable", "true");
|
||||
anchorInEditor.focus();
|
||||
is(focused, false, "focus moved to element in contenteditable=true");
|
||||
is(isReallyEditable(), true, "cannot edit by a key event");
|
||||
|
||||
// for bug 502273
|
||||
focused = false;
|
||||
anchor.focus();
|
||||
editor.setAttribute("dummy", "dummy");
|
||||
editor.removeAttribute("dummy");
|
||||
anchorInEditor.focus();
|
||||
is(focused, false, "focus moved to element in contenteditable=true (after dummy attribute was removed)");
|
||||
is(isReallyEditable(), true, "cannot edit by a key event");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
@ -238,7 +238,7 @@ nsHTMLDocument::nsHTMLDocument()
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLDocument)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLDocument, nsDocument)
|
||||
NS_ASSERTION(!nsCCUncollectableMarker::InGeneration(tmp->GetMarkedCCGeneration()),
|
||||
NS_ASSERTION(!nsCCUncollectableMarker::InGeneration(cb, tmp->GetMarkedCCGeneration()),
|
||||
"Shouldn't traverse nsHTMLDocument!");
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mImageMaps)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mImages)
|
||||
|
@ -43,39 +43,99 @@ relativesrcdir = content/media/test
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
# Media tests should be backend independent, i.e., not conditioned on
|
||||
# MOZ_OGG, MOZ_WAVE etc. (The only exception is the can_play_type tests,
|
||||
# which necessarily depend on the backend(s) configured.) As far as possible,
|
||||
# each test should work with any resource type. This makes it
|
||||
# easy to add new backends and reduces the amount of test duplication.
|
||||
|
||||
# For each supported backend, resources that can be played by that backend
|
||||
# should be added to the lists in manifest.js. Media tests that aren't
|
||||
# testing for a bug in handling a specific resource type should pick one of
|
||||
# the lists in manifest.js and run the test for each resource in the list
|
||||
# that is supported in the current build (the canPlayType API is useful
|
||||
# for this).
|
||||
|
||||
# To test whether a valid resource can simply be played through correctly,
|
||||
# and optionally that its metadata is read correctly, just
|
||||
# add it to gPlayTests in manifest.js. To test whether an invalid
|
||||
# resource correctly throws an error (and does not cause a crash or hang),
|
||||
# just add it to gErrorTests in manifest.js.
|
||||
|
||||
# To test for a specific bug in handling a specific resource type,
|
||||
# make the test first check canPlayType for the type, and if it's not
|
||||
# supported, just do ok(true, "Type not supported") and stop the test.
|
||||
|
||||
_TEST_FILES = \
|
||||
can_play_type_ogg.js \
|
||||
can_play_type_wave.js \
|
||||
manifest.js \
|
||||
seek1.js \
|
||||
seek2.js \
|
||||
seek3.js \
|
||||
seek4.js \
|
||||
seek5.js \
|
||||
seek6.js \
|
||||
seek7.js \
|
||||
seek8.js \
|
||||
seek9.js \
|
||||
test_audio1.html \
|
||||
test_audio2.html \
|
||||
test_autobuffer.html \
|
||||
test_autoplay.html \
|
||||
test_can_play_type.html \
|
||||
test_constants.html \
|
||||
test_controls.html \
|
||||
test_currentTime.html \
|
||||
test_decoder_disable.html \
|
||||
test_load.html \
|
||||
test_media_selection.html \
|
||||
test_networkState.html \
|
||||
test_paused.html \
|
||||
test_playback.html \
|
||||
test_playback_errors.html \
|
||||
test_readyState.html \
|
||||
test_seek.html \
|
||||
test_seek2.html \
|
||||
test_volume.html \
|
||||
use_large_cache.js \
|
||||
$(NULL)
|
||||
|
||||
# Ogg sample files
|
||||
_TEST_FILES += \
|
||||
320x240.ogv \
|
||||
320x240.allow-origin.ogv \
|
||||
320x240.allow-origin.ogv^headers^ \
|
||||
bug461281.ogg \
|
||||
bug482461.ogv \
|
||||
seek.ogv \
|
||||
small-shot.ogg \
|
||||
sound.ogg \
|
||||
$(NULL)
|
||||
|
||||
# Wave sample files
|
||||
_TEST_FILES += \
|
||||
big.wav \
|
||||
r11025_s16_c1.wav \
|
||||
r11025_s16_c1_trailing.wav \
|
||||
r11025_u8_c1.wav \
|
||||
r11025_u8_c1_trunc.wav \
|
||||
r16000_u8_c1_list.wav \
|
||||
$(NULL)
|
||||
|
||||
# These tests need to be converted to be backend-independent. This list
|
||||
# is deprecated, do not add to it.
|
||||
ifdef MOZ_OGG
|
||||
_TEST_FILES += \
|
||||
dynamic_redirect.sjs \
|
||||
test_access_control.html \
|
||||
file_access_controls.html \
|
||||
test_audio1.html \
|
||||
test_audio2.html \
|
||||
test_bug448534.html \
|
||||
test_bug461281.html \
|
||||
test_bug468190.html \
|
||||
test_bug482461.html \
|
||||
test_bug493187.html \
|
||||
test_bug495145.html \
|
||||
test_bug495300.html \
|
||||
test_bug495319.html \
|
||||
test_can_play_type_ogg.html \
|
||||
test_closing_connections.html \
|
||||
test_contentDuration1.html \
|
||||
test_contentDuration2.html \
|
||||
@ -100,11 +160,6 @@ _TEST_FILES += \
|
||||
test_standalone.html \
|
||||
test_timeupdate1.html \
|
||||
test_timeupdate2.html \
|
||||
320x240.ogv \
|
||||
320x240.allow-origin.ogv \
|
||||
320x240.allow-origin.ogv^headers^ \
|
||||
bug461281.ogg \
|
||||
bug482461.ogv \
|
||||
redirect.sjs \
|
||||
contentDuration1.sjs \
|
||||
contentDuration2.sjs \
|
||||
@ -112,73 +167,57 @@ _TEST_FILES += \
|
||||
contentDuration4.sjs \
|
||||
contentDuration5.sjs \
|
||||
contentDuration6.sjs \
|
||||
seek.ogv \
|
||||
small-shot.ogg \
|
||||
sound.ogg \
|
||||
$(NULL)
|
||||
|
||||
# These tests disabled until we figure out random failures.
|
||||
# Bug 492821:
|
||||
# test_videoDocumentTitle.html
|
||||
# Bug 493692:
|
||||
# test_autobuffer2.html
|
||||
|
||||
ifneq ($(OS_ARCH),WINNT)
|
||||
# These tests are disabled on windows until we
|
||||
# figure out the random failures. See bug 475369.
|
||||
_TEST_FILES += \
|
||||
test_seek1.html \
|
||||
test_seek3.html \
|
||||
test_seek4.html \
|
||||
test_seek5.html \
|
||||
test_seek6.html \
|
||||
test_seek7.html \
|
||||
test_seek8.html \
|
||||
test_seek9.html \
|
||||
test_timeupdate3.html \
|
||||
$(NULL)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef MOZ_OGG
|
||||
_TEST_FILES += \
|
||||
test_can_play_type_ogg.html \
|
||||
$(NULL)
|
||||
else
|
||||
_TEST_FILES += \
|
||||
test_can_play_type_no_ogg.html \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
# These tests need to be converted to be backend-independent. This list
|
||||
# is deprecated, do not add to it.
|
||||
ifdef MOZ_WAVE
|
||||
_TEST_FILES += \
|
||||
big.wav \
|
||||
test_bug463162.xhtml \
|
||||
test_bug465498.html \
|
||||
test_bug468190_wav.html \
|
||||
test_bug495145_wav.html \
|
||||
test_can_play_type_wave.html \
|
||||
test_paused_after_ended.html \
|
||||
test_progress2.html \
|
||||
test_progress4.html \
|
||||
test_wav_8bit.html \
|
||||
test_wav_ended1.html \
|
||||
test_wav_ended2.html \
|
||||
test_wav_list.html \
|
||||
test_wav_onloadedmetadata.html \
|
||||
test_wav_seek1.html \
|
||||
test_wav_seek3.html \
|
||||
test_wav_seek4.html \
|
||||
test_wav_seek5.html \
|
||||
test_wav_seek6.html \
|
||||
test_wav_seek7.html \
|
||||
test_wav_seek8.html \
|
||||
test_wav_seek_past_end.html \
|
||||
test_wav_seek_then_play.html \
|
||||
test_wav_timeupdate1.html \
|
||||
test_wav_timeupdate2.html \
|
||||
test_wav_trailing.html \
|
||||
test_wav_trunc.html \
|
||||
test_wav_trunc_seek.html \
|
||||
r11025_s16_c1.wav \
|
||||
r11025_s16_c1_trailing.wav \
|
||||
r11025_u8_c1.wav \
|
||||
r11025_u8_c1_trunc.wav \
|
||||
r16000_u8_c1_list.wav \
|
||||
$(NULL)
|
||||
# Disabled since we don't play Wave files standalone, for now
|
||||
# test_wav_standalone.html
|
||||
# test_audioDocumentTitle.html
|
||||
endif
|
||||
|
||||
ifdef MOZ_WAVE
|
||||
_TEST_FILES += \
|
||||
test_can_play_type_wave.html \
|
||||
$(NULL)
|
||||
else
|
||||
_TEST_FILES += \
|
||||
@ -186,19 +225,5 @@ _TEST_FILES += \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
# Disabled since we don't play Wave files standalone, for now
|
||||
# test_wav_standalone.html
|
||||
# test_audioDocumentTitle.html
|
||||
|
||||
ifdef MOZ_OGG
|
||||
ifdef MOZ_WAVE
|
||||
_TEST_FILES += \
|
||||
test_decoder_disable.html \
|
||||
test_load.html \
|
||||
test_media_selection.html \
|
||||
$(NULL)
|
||||
endif
|
||||
endif
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
|
||||
|
45
content/media/test/bogus.duh
Normal file
45
content/media/test/bogus.duh
Normal file
@ -0,0 +1,45 @@
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
45
content/media/test/bogus.ogv
Normal file
45
content/media/test/bogus.ogv
Normal file
@ -0,0 +1,45 @@
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
45
content/media/test/bogus.wav
Normal file
45
content/media/test/bogus.wav
Normal file
@ -0,0 +1,45 @@
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
||||
bogus bogus bogus
|
18
content/media/test/crashtests/493915-1.html
Normal file
18
content/media/test/crashtests/493915-1.html
Normal file
@ -0,0 +1,18 @@
|
||||
<html>
|
||||
<head>
|
||||
<script type="text/javascript">
|
||||
|
||||
function boom()
|
||||
{
|
||||
s = document.createElement("span");
|
||||
a = document.createElement("audio");
|
||||
a['src'] = "javascript:4";
|
||||
a['loopend'] = 3;
|
||||
s.appendChild(a);
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="boom();"></body>
|
||||
</html>
|
@ -1,3 +1,4 @@
|
||||
load 468763-1.html
|
||||
load 474744-1.html
|
||||
load 493915-1.html
|
||||
load 495794-1.html
|
||||
|
67
content/media/test/manifest.js
Normal file
67
content/media/test/manifest.js
Normal file
@ -0,0 +1,67 @@
|
||||
// In each list of tests below, test file types that are not supported should
|
||||
// be ignored. To make sure tests respect that, we include a file of type
|
||||
// "bogus/duh" in each list.
|
||||
|
||||
// These are small test files, good for just seeing if something loads.
|
||||
var gSmallTests = [
|
||||
{ name:"r11025_s16_c1.wav", type:"audio/x-wav", duration:1.0 },
|
||||
{ name:"320x240.ogv", type:"video/ogg", width:320, height:240 },
|
||||
{ name:"bogus.duh", type:"bogus/duh" }
|
||||
];
|
||||
|
||||
// These are files that we just want to make sure we can play through.
|
||||
// We can also check metadata.
|
||||
// Put files of the same type together in this list so if something crashes
|
||||
// we have some idea of which backend is responsible.
|
||||
var gPlayTests = [
|
||||
// 8-bit samples
|
||||
{ name:"r11025_u8_c1.wav", type:"audio/x-wav", duration:1.0 },
|
||||
// 8-bit samples, file is truncated
|
||||
{ name:"r11025_u8_c1_trunc.wav", type:"audio/x-wav", duration:1.8 },
|
||||
// file has trailing non-PCM data
|
||||
{ name:"r11025_s16_c1_trailing.wav", type:"audio/x-wav", duration:1.0 },
|
||||
// file with list chunk
|
||||
{ name:"r16000_u8_c1_list.wav", type:"audio/x-wav", duration:4.2 },
|
||||
// Ogg stream with eof marker
|
||||
{ name:"bug461281.ogg", type:"application/ogg" },
|
||||
// oggz-chop stream
|
||||
{ name:"bug482461.ogv", type:"video/ogg", duration:4.24 },
|
||||
{ name:"bogus.duh", type:"bogus/duh" }
|
||||
];
|
||||
|
||||
// These are files that should refuse to play and report an error,
|
||||
// without crashing of course.
|
||||
// Put files of the same type together in this list so if something crashes
|
||||
// we have some idea of which backend is responsible.
|
||||
var gErrorTests = [
|
||||
{ name:"bogus.wav", type:"audio/x-wav" },
|
||||
{ name:"bogus.ogv", type:"video/ogg" },
|
||||
{ name:"bogus.duh", type:"bogus/duh" }
|
||||
];
|
||||
|
||||
// These are files that have nontrivial duration and are useful for seeking within.
|
||||
var gSeekTests = [
|
||||
{ name:"r11025_s16_c1.wav", type:"audio/x-wav", duration:1.0 },
|
||||
{ name:"seek.ogv", type:"video/ogg", duration:3.966 },
|
||||
{ name:"bogus.duh", type:"bogus/duh", duration:123 }
|
||||
];
|
||||
|
||||
// These are files suitable for using with a "new Audio" constructor.
|
||||
var gAudioTests = [
|
||||
{ name:"r11025_s16_c1.wav", type:"audio/x-wav", duration:1.0 },
|
||||
{ name:"sound.ogg", type:"audio/ogg" },
|
||||
{ name:"bogus.duh", type:"bogus/duh", duration:123 }
|
||||
];
|
||||
|
||||
function checkMetadata(msg, e, test) {
|
||||
if (test.width) {
|
||||
is(e.videoWidth, test.width, msg + " video width");
|
||||
}
|
||||
if (test.height) {
|
||||
is(e.videoHeight, test.height, msg + " video height");
|
||||
}
|
||||
if (test.duration) {
|
||||
ok(Math.abs(e.duration - test.duration) < 0.1,
|
||||
msg + " duration should be around " + test.duration);
|
||||
}
|
||||
}
|
@ -1,14 +1,5 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Media test: seek test 1</title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
function test_seek1(v, seekTime, is, ok, finish) {
|
||||
|
||||
var startPassed = false;
|
||||
var endPassed = false;
|
||||
var seekFlagStart = false;
|
||||
@ -19,7 +10,6 @@ var completed = false;
|
||||
function startTest() {
|
||||
if (completed)
|
||||
return false;
|
||||
var v = document.getElementById('v');
|
||||
ok(!v.seeking, "seeking should default to false");
|
||||
try {
|
||||
v.seeking = 1;
|
||||
@ -31,7 +21,7 @@ function startTest() {
|
||||
ok(readonly, "seeking should be readonly");
|
||||
|
||||
v.play();
|
||||
v.currentTime=2;
|
||||
v.currentTime=seekTime;
|
||||
seekFlagStart = v.seeking;
|
||||
return false;
|
||||
}
|
||||
@ -39,7 +29,6 @@ function startTest() {
|
||||
function seekStarted() {
|
||||
if (completed)
|
||||
return false;
|
||||
var v = document.getElementById('v');
|
||||
v.pause();
|
||||
startPassed = true;
|
||||
return false;
|
||||
@ -49,12 +38,11 @@ function seekEnded() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
var v = document.getElementById('v');
|
||||
var t = v.currentTime;
|
||||
// Since we were playing, and we only paused asynchronously, we can't be
|
||||
// sure that we paused before the seek finished, so we may have played
|
||||
// ahead arbitrarily far.
|
||||
ok(t >= 1.9, "Video currentTime should be around 2: " + t);
|
||||
ok(t >= seekTime - 0.1, "Video currentTime should be around " + seekTime + ": " + t);
|
||||
v.play();
|
||||
endPassed = true;
|
||||
seekFlagEnd = v.seeking;
|
||||
@ -70,18 +58,13 @@ function playbackEnded() {
|
||||
ok(endPassed, "seeked event");
|
||||
ok(seekFlagStart, "seeking flag on start should be true");
|
||||
ok(!seekFlagEnd, "seeking flag on end should be false");
|
||||
SimpleTest.finish();
|
||||
finish();
|
||||
return false;
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
</pre>
|
||||
<video id='v'
|
||||
src='seek.ogv'
|
||||
onended='return playbackEnded();'
|
||||
onloadedmetadata='return startTest();'
|
||||
onseeking='return seekStarted();'
|
||||
onseeked='return seekEnded();'></video>
|
||||
</body>
|
||||
</html>
|
||||
v.addEventListener("ended", playbackEnded, false);
|
||||
v.addEventListener("loadedmetadata", startTest, false);
|
||||
v.addEventListener("seeking", seekStarted, false);
|
||||
v.addEventListener("seeked", seekEnded, false);
|
||||
|
||||
}
|
52
content/media/test/seek2.js
Normal file
52
content/media/test/seek2.js
Normal file
@ -0,0 +1,52 @@
|
||||
function test_seek2(v, seekTime, is, ok, finish) {
|
||||
|
||||
// Test seeking works if current time is set before video is
|
||||
// playing.
|
||||
var startPassed = false;
|
||||
var endPassed = false;
|
||||
var completed = false;
|
||||
|
||||
function startTest() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
v.currentTime=seekTime;
|
||||
v.play();
|
||||
return false;
|
||||
}
|
||||
|
||||
function seekStarted() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
startPassed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function seekEnded() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
endPassed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function playbackEnded() {
|
||||
if (completed)
|
||||
return false
|
||||
|
||||
completed = true;
|
||||
ok(startPassed, "send seeking event");
|
||||
ok(endPassed, "send seeked event");
|
||||
ok(v.ended, "Checking playback has ended");
|
||||
ok(Math.abs(v.currentTime - v.duration) <= 0.1, "Checking currentTime at end: " + v.currentTime);
|
||||
finish();
|
||||
return false;
|
||||
}
|
||||
|
||||
v.addEventListener("ended", playbackEnded, false);
|
||||
v.addEventListener("loadedmetadata", startTest, false);
|
||||
v.addEventListener("seeking", seekStarted, false);
|
||||
v.addEventListener("seeked", seekEnded, false);
|
||||
|
||||
}
|
38
content/media/test/seek3.js
Normal file
38
content/media/test/seek3.js
Normal file
@ -0,0 +1,38 @@
|
||||
function test_seek3(v, seekTime, is, ok, finish) {
|
||||
|
||||
// Test seeking works if current time is set but video is not played.
|
||||
var startPassed = false;
|
||||
var completed = false;
|
||||
|
||||
function startTest() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
v.currentTime=seekTime;
|
||||
return false;
|
||||
}
|
||||
|
||||
function seekStarted() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
startPassed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function seekEnded() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
var t = v.currentTime;
|
||||
ok(Math.abs(t - seekTime) <= 0.1, "Video currentTime should be around " + seekTime + ": " + t);
|
||||
completed = true;
|
||||
finish();
|
||||
return false;
|
||||
}
|
||||
|
||||
v.addEventListener("loadedmetadata", startTest, false);
|
||||
v.addEventListener("seeking", seekStarted, false);
|
||||
v.addEventListener("seeked", seekEnded, false);
|
||||
|
||||
}
|
41
content/media/test/seek4.js
Normal file
41
content/media/test/seek4.js
Normal file
@ -0,0 +1,41 @@
|
||||
function test_seek4(v, seekTime, is, ok, finish) {
|
||||
|
||||
// Test for a seek, followed by another seek before the first is complete.
|
||||
var seekCount = 0;
|
||||
var completed = false;
|
||||
|
||||
function startTest() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
v.currentTime=seekTime;
|
||||
return false;
|
||||
}
|
||||
|
||||
function seekStarted() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
v.currentTime=seekTime/2;
|
||||
return false;
|
||||
}
|
||||
|
||||
function seekEnded() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
seekCount++;
|
||||
if (seekCount == 2) {
|
||||
ok(Math.abs(v.currentTime - seekTime/2) <= 0.1, "Second seek on target: " + v.currentTime);
|
||||
completed = true;
|
||||
finish();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
v.addEventListener("loadedmetadata", startTest, false);
|
||||
v.addEventListener("seeking", seekStarted, false);
|
||||
v.addEventListener("seeked", seekEnded, false);
|
||||
|
||||
}
|
46
content/media/test/seek5.js
Normal file
46
content/media/test/seek5.js
Normal file
@ -0,0 +1,46 @@
|
||||
function test_seek5(v, seekTime, is, ok, finish) {
|
||||
|
||||
// Test for a seek, followed by a play before the seek completes, ensure we play at the end of the seek.
|
||||
var startPassed = false;
|
||||
var endPassed = false;
|
||||
var completed = false;
|
||||
|
||||
function startTest() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
v.currentTime=seekTime;
|
||||
return false;
|
||||
}
|
||||
|
||||
function seekStarted() {
|
||||
if (completed)
|
||||
return false;
|
||||
startPassed = true;
|
||||
v.play();
|
||||
return false;
|
||||
}
|
||||
|
||||
function seekEnded() {
|
||||
if (completed)
|
||||
return false;
|
||||
endPassed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function playbackEnded() {
|
||||
if (completed)
|
||||
return false;
|
||||
ok(startPassed, "Got seeking event");
|
||||
ok(endPassed, "Got seeked event");
|
||||
completed = true;
|
||||
finish();
|
||||
return false;
|
||||
}
|
||||
|
||||
v.addEventListener("ended", playbackEnded, false);
|
||||
v.addEventListener("loadedmetadata", startTest, false);
|
||||
v.addEventListener("seeking", seekStarted, false);
|
||||
v.addEventListener("seeked", seekEnded, false);
|
||||
|
||||
}
|
33
content/media/test/seek6.js
Normal file
33
content/media/test/seek6.js
Normal file
@ -0,0 +1,33 @@
|
||||
function test_seek6(v, seekTime, is, ok, finish) {
|
||||
|
||||
// Test for bug identified by Chris Pearce in comment 40 on
|
||||
// bug 449159.
|
||||
var seekCount = 0;
|
||||
var completed = false;
|
||||
var interval;
|
||||
|
||||
function startTest() {
|
||||
if (completed)
|
||||
return false;
|
||||
interval = setInterval(function() { v.currentTime=Math.random()*v.duration; }, 10);
|
||||
return false;
|
||||
}
|
||||
|
||||
function seekEnded() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
seekCount++;
|
||||
ok(true, "Seek " + seekCount);
|
||||
if (seekCount == 3) {
|
||||
clearInterval(interval);
|
||||
completed = true;
|
||||
finish();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
v.addEventListener("loadedmetadata", startTest, false);
|
||||
v.addEventListener("seeked", seekEnded, false);
|
||||
|
||||
}
|
35
content/media/test/seek7.js
Normal file
35
content/media/test/seek7.js
Normal file
@ -0,0 +1,35 @@
|
||||
function test_seek7(v, seekTime, is, ok, finish) {
|
||||
|
||||
// If a NaN is passed to currentTime, make sure this is caught
|
||||
// otherwise an infinite loop in the Ogg backend occurs.
|
||||
var completed = false;
|
||||
var thrown1 = false;
|
||||
var thrown2 = false;
|
||||
var thrown3 = false;
|
||||
|
||||
function startTest() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
try {
|
||||
v.currentTime = NaN;
|
||||
} catch(e) {
|
||||
thrown1 = true;
|
||||
}
|
||||
|
||||
try {
|
||||
v.currentTime = Math.random;
|
||||
} catch(e) {
|
||||
thrown3 = true;
|
||||
}
|
||||
|
||||
completed = true;
|
||||
ok(thrown1, "Setting currentTime to invalid value of NaN");
|
||||
ok(thrown3, "Setting currentTime to invalid value of a function");
|
||||
finish();
|
||||
return false;
|
||||
}
|
||||
|
||||
v.addEventListener("loadedmetadata", startTest, false);
|
||||
|
||||
}
|
21
content/media/test/seek8.js
Normal file
21
content/media/test/seek8.js
Normal file
@ -0,0 +1,21 @@
|
||||
function test_seek8(v, seekTime, is, ok, finish) {
|
||||
|
||||
var completed = false;
|
||||
|
||||
function startTest() {
|
||||
v.currentTime = 1000;
|
||||
}
|
||||
|
||||
function seekEnded() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
ok(Math.abs(v.currentTime - v.duration) < 0.2,
|
||||
"currentTime " + v.currentTime + " close to " + v.duration);
|
||||
finish();
|
||||
}
|
||||
|
||||
v.addEventListener("loadedmetadata", startTest, false);
|
||||
v.addEventListener("seeked", seekEnded, false);
|
||||
|
||||
}
|
20
content/media/test/seek9.js
Normal file
20
content/media/test/seek9.js
Normal file
@ -0,0 +1,20 @@
|
||||
function test_seek9(v, seekTime, is, ok, finish) {
|
||||
|
||||
var completed = false;
|
||||
|
||||
function startTest() {
|
||||
v.currentTime = -1000;
|
||||
}
|
||||
|
||||
function seekEnded() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
is(v.currentTime, 0, "currentTime clamped to 0");
|
||||
finish();
|
||||
}
|
||||
|
||||
v.addEventListener("loadedmetadata", startTest, false);
|
||||
v.addEventListener("seeked", seekEnded, false);
|
||||
|
||||
}
|
@ -5,17 +5,33 @@
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script type="text/javascript" src="use_large_cache.js"></script>
|
||||
<script type="text/javascript" src="manifest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
var a1 = new Audio();
|
||||
a1.addEventListener('load', function() {
|
||||
is(a1.networkState, HTMLMediaElement.NETWORK_LOADED, "Audio loaded");
|
||||
SimpleTest.finish();
|
||||
}, false);
|
||||
a1.src = 'sound.ogg';
|
||||
a1.load();
|
||||
var testsWaiting = 0;
|
||||
|
||||
for (var i = 0; i < gAudioTests.length; ++i) {
|
||||
var test = gAudioTests[i];
|
||||
var a1 = new Audio();
|
||||
if (a1.canPlayType(test.type) == "no")
|
||||
continue;
|
||||
|
||||
a1.setAttribute("autobuffer", "");
|
||||
a1.addEventListener('load', function(event) {
|
||||
is(event.target.networkState, HTMLMediaElement.NETWORK_LOADED,
|
||||
"Audio " + event.target.currentSrc + " loaded");
|
||||
--testsWaiting;
|
||||
if (testsWaiting == 0) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}, false);
|
||||
a1.src = test.name;
|
||||
a1.load();
|
||||
++testsWaiting;
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
|
@ -1,20 +1,37 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Media test: Audio Constructor Test 2</title>
|
||||
<title>Media test: Audio Constructor Test 1</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script type="text/javascript" src="use_large_cache.js"></script>
|
||||
<script type="text/javascript" src="manifest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
var a1 = Audio('sound.ogg');
|
||||
a1.addEventListener('load', function() {
|
||||
is(a1.networkState, HTMLMediaElement.NETWORK_LOADED, "Audio loaded");
|
||||
SimpleTest.finish();
|
||||
}, false);
|
||||
a1.load();
|
||||
var testsWaiting = 0;
|
||||
|
||||
var tmpAudio = new Audio();
|
||||
for (var i = 0; i < gAudioTests.length; ++i) {
|
||||
var test = gAudioTests[i];
|
||||
if (tmpAudio.canPlayType(test.type) == "no")
|
||||
continue;
|
||||
|
||||
var a1 = new Audio(test.name);
|
||||
a1.setAttribute("autobuffer", "");
|
||||
a1.addEventListener('load', function(event) {
|
||||
is(event.target.networkState, HTMLMediaElement.NETWORK_LOADED,
|
||||
"Audio " + event.target.currentSrc + " loaded");
|
||||
--testsWaiting;
|
||||
if (testsWaiting == 0) {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}, false);
|
||||
a1.load();
|
||||
++testsWaiting;
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
|
@ -1,44 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Media test: Bug 461281 - Ogg Streams with eof marker</title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
// Test if the ended event occurs with media without an eos marker
|
||||
var endPassed = false;
|
||||
var completed = false;
|
||||
|
||||
function startTest() {
|
||||
if (completed)
|
||||
return false;
|
||||
|
||||
var v = document.getElementById('v');
|
||||
v.play();
|
||||
return false;
|
||||
}
|
||||
|
||||
function playbackEnded() {
|
||||
if (completed)
|
||||
return false
|
||||
|
||||
completed = true;
|
||||
var v = document.getElementById('v');
|
||||
ok(v.ended, "Checking playback has ended");
|
||||
SimpleTest.finish();
|
||||
return false;
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
</pre>
|
||||
<video id='v'
|
||||
src='bug461281.ogg'
|
||||
onloadedmetadata='return startTest();'
|
||||
onended='return playbackEnded();'></video>
|
||||
</body>
|
||||
</html>
|
@ -1,49 +0,0 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=482461
|
||||
-->
|
||||
|
||||
<head>
|
||||
<title>Media test: Bug 482461 - Play oggz-chop streams</title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=482461">Mozilla Bug 482461</a>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
var v;
|
||||
var endPassed = false;
|
||||
var completed = false;
|
||||
|
||||
function startTest() {
|
||||
if (completed)
|
||||
return false;
|
||||
v = document.getElementById('v');
|
||||
v.play();
|
||||
return false;
|
||||
}
|
||||
|
||||
function playbackEnded() {
|
||||
if (completed)
|
||||
return false
|
||||
|
||||
completed = true;
|
||||
ok(v.currentTime > 3 && v.currentTime < 5,
|
||||
"Checking currentTime at end: " + v.currentTime);
|
||||
ok(v.ended, "Checking playback has ended");
|
||||
SimpleTest.finish();
|
||||
return false;
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
</pre>
|
||||
<video id='v'
|
||||
src='bug482461.ogv'
|
||||
onloadedmetadata='return startTest();'
|
||||
onended='return playbackEnded();'></video>
|
||||
</body>
|
||||
</html>
|
@ -9,6 +9,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=479859
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="application/javascript" src="use_large_cache.js"></script>
|
||||
<script type="application/javascript" src="manifest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=479859">Mozilla Bug 479859</a>
|
||||
@ -25,15 +26,17 @@ function log(msg) {
|
||||
|
||||
// We don't track: progress, canplay, canplaythrough and stalled events,
|
||||
// as these can be delivered out of order, and/or multiple times.
|
||||
var gEventTypes = [ 'loadstart', 'load', 'abort', 'error', 'emptied', 'play', 'pause', 'loadedmetadata', 'loadeddata', 'waiting', 'playing', 'seeking', 'seeked', 'timeupdate', 'ended', 'ratechange', 'durationchange', 'volumechange' ];
|
||||
var gEventTypes = [ 'loadstart', 'load', 'abort', 'error', 'emptied', 'play',
|
||||
'pause', 'loadedmetadata', 'loadeddata', 'waiting', 'playing', 'seeking',
|
||||
'seeked', 'timeupdate', 'ended', 'ratechange', 'durationchange', 'volumechange' ];
|
||||
|
||||
var gEventNum = 0;
|
||||
var gTestNum = 0;
|
||||
var gTestFileNum = 0;
|
||||
var gExpectedEvents = null;
|
||||
var gTest = null;
|
||||
var gTestName = "?";
|
||||
|
||||
|
||||
function listener(evt) {
|
||||
log('event ' + evt.type);
|
||||
evt.stopPropagation();
|
||||
@ -56,12 +59,6 @@ function createMedia(tag) {
|
||||
}
|
||||
}
|
||||
|
||||
var gWavAudio = 'r11025_s16_c1.wav';
|
||||
var gWavAudioType = 'audio/x-wav';
|
||||
|
||||
var gOggVideo = '320x240.ogv';
|
||||
var gOggVideoType = "application/ogg";
|
||||
|
||||
function addSource(src, type) {
|
||||
var s = document.createElement("source");
|
||||
s.src = src;
|
||||
@ -76,153 +73,74 @@ function prependSource(src, type) {
|
||||
gMedia.insertBefore(s, gMedia.firstChild);
|
||||
}
|
||||
|
||||
var gTest10Prepended = false;
|
||||
var gTest11Prepended = false;
|
||||
|
||||
var gTests = [
|
||||
{
|
||||
// Test 0: adding video to doc, then setting src should load implicitly.
|
||||
create:
|
||||
function() {
|
||||
createMedia("video");
|
||||
function(src, type) {
|
||||
document.body.appendChild(gMedia);
|
||||
gMedia.src = gOggVideo;
|
||||
gMedia.src = src;
|
||||
},
|
||||
expectedEvents: ['loadstart', 'durationchange', 'loadedmetadata', 'loadeddata', 'load']
|
||||
}, {
|
||||
// Test 1: adding audio to doc, then setting src should load implicitly.
|
||||
// Test 1: adding video to doc, then adding source.
|
||||
create:
|
||||
function() {
|
||||
createMedia("audio");
|
||||
function(src, type) {
|
||||
document.body.appendChild(gMedia);
|
||||
gMedia.src = gWavAudio;
|
||||
addSource(src, type);
|
||||
},
|
||||
expectedEvents: ['loadstart', 'durationchange', 'loadedmetadata', 'loadeddata', 'load']
|
||||
}, {
|
||||
// Test 2: adding video to doc, then adding source.
|
||||
// Test 2: video with multiple source, the first of which are bad, we should load the last.
|
||||
create:
|
||||
function() {
|
||||
createMedia("video");
|
||||
function(src, type) {
|
||||
document.body.appendChild(gMedia);
|
||||
addSource(gOggVideo, gOggVideoType);
|
||||
addSource("404a", type);
|
||||
addSource("404b", type);
|
||||
addSource(src, type);
|
||||
},
|
||||
expectedEvents: ['loadstart', 'durationchange', 'loadedmetadata', 'loadeddata', 'load']
|
||||
}, {
|
||||
// Test 3: adding audio to doc, then adding source.
|
||||
// Test 3: video with bad src, good <source>, ensure that <source> aren't used.
|
||||
create:
|
||||
function() {
|
||||
createMedia("audio");
|
||||
document.body.appendChild(gMedia);
|
||||
addSource(gWavAudio, gWavAudioType);
|
||||
},
|
||||
expectedEvents: ['loadstart', 'durationchange', 'loadedmetadata', 'loadeddata', 'load']
|
||||
}, {
|
||||
// Test 4: video with multiple source, the first of which are bad, we should load the last.
|
||||
create:
|
||||
function() {
|
||||
createMedia("video");
|
||||
document.body.appendChild(gMedia);
|
||||
addSource("404a.ogv", gOggVideoType);
|
||||
addSource("404b.ogv", gOggVideoType);
|
||||
addSource(gOggVideo, gOggVideoType);
|
||||
},
|
||||
expectedEvents: ['loadstart', 'durationchange', 'loadedmetadata', 'loadeddata', 'load']
|
||||
}, {
|
||||
// Test 5: audio with multiple source, the first of which are bad, we should load the last.
|
||||
create:
|
||||
function() {
|
||||
createMedia("audio");
|
||||
document.body.appendChild(gMedia);
|
||||
addSource("404a.wav", gWavAudioType);
|
||||
addSource("404b.wav", gWavAudioType);
|
||||
addSource(gWavAudio, gWavAudioType);
|
||||
},
|
||||
expectedEvents: ['loadstart', 'durationchange', 'loadedmetadata', 'loadeddata', 'load']
|
||||
}, {
|
||||
// Test 6: video with bad src, good <source>, ensure that <source> aren't used.
|
||||
create:
|
||||
function() {
|
||||
createMedia("video");
|
||||
gMedia.src = "404a.ogv";
|
||||
addSource(gOggVideo, gOggVideoType);
|
||||
function(src, type) {
|
||||
gMedia.src = "404a";
|
||||
addSource(src, type);
|
||||
document.body.appendChild(gMedia);
|
||||
},
|
||||
expectedEvents: ['loadstart', 'error']
|
||||
}, {
|
||||
// Test 7: audio with bad src, good <source>, ensure that <source> aren't used.
|
||||
// Test 4: video with only bad source, loading, then adding a good source
|
||||
// - should resume load.
|
||||
create:
|
||||
function() {
|
||||
createMedia("audio");
|
||||
gMedia.src = "404a.wav";
|
||||
addSource(gWavAudio, gWavAudioType);
|
||||
document.body.appendChild(gMedia);
|
||||
},
|
||||
expectedEvents: ['loadstart', 'error']
|
||||
}, {
|
||||
// Test 8: video with only bad source, loading, then adding a good source - should resume load.
|
||||
create:
|
||||
function() {
|
||||
createMedia("video");
|
||||
addSource("404a.ogv", gOggVideoType);
|
||||
addSource("404b.ogv", gOggVideoType);
|
||||
function(src, type) {
|
||||
addSource("404a", type);
|
||||
addSource("404b", type);
|
||||
gMedia.addEventListener("error",
|
||||
function(e) {
|
||||
// Should awaken waiting load, causing successful load.
|
||||
addSource(gOggVideo, gOggVideoType);
|
||||
addSource(src, type);
|
||||
},
|
||||
false);
|
||||
document.body.appendChild(gMedia);
|
||||
},
|
||||
expectedEvents: ['loadstart', 'error', 'durationchange', 'loadedmetadata', 'loadeddata', 'load']
|
||||
}, {
|
||||
// Test 9: audio with only bad source, loading, then adding a good source - should resume load.
|
||||
create:
|
||||
function() {
|
||||
createMedia("audio");
|
||||
addSource("404a.wav", gWavAudioType);
|
||||
addSource("404b.wav", gWavAudioType);
|
||||
gMedia.addEventListener("error",
|
||||
function(e) {
|
||||
// Should awaken waiting load, causing successful load.
|
||||
addSource(gWavAudio, gWavAudioType);
|
||||
},
|
||||
false);
|
||||
document.body.appendChild(gMedia);
|
||||
},
|
||||
expectedEvents: ['loadstart', 'error', 'durationchange', 'loadedmetadata', 'loadeddata', 'load']
|
||||
}, {
|
||||
// Test 10: video with only 1 bad source, let it fail to load, then prepend a good <source> to the video, it shouldn't be selected, because the "pointer" should be after the last child - the bad source.
|
||||
// Test 5: video with only 1 bad source, let it fail to load, then prepend
|
||||
// a good <source> to the video, it shouldn't be selected, because the
|
||||
// "pointer" should be after the last child - the bad source.
|
||||
prepended: false,
|
||||
create:
|
||||
function() {
|
||||
createMedia("video");
|
||||
addSource("404a.ogv", gOggVideoType);
|
||||
addSource("404b.ogv", gOggVideoType);
|
||||
function(src, type) {
|
||||
var prepended = false;
|
||||
addSource("404a", type);
|
||||
addSource("404b", type);
|
||||
gMedia.addEventListener("error",
|
||||
function(e) {
|
||||
// Should awaken waiting load, causing successful load.
|
||||
if (!gTest10Prepended) {
|
||||
prependSource(gOggVideo, gOggVideoType);
|
||||
gTest10Prepended = true;
|
||||
}
|
||||
},
|
||||
false);
|
||||
document.body.appendChild(gMedia);
|
||||
},
|
||||
expectedEvents: ['loadstart', 'error', 'error']
|
||||
}, {
|
||||
// Test 11: audio with only 1 bad source, let it fail to load, then prepend a good <source> to the video, it shouldn't be selected, because the "pointer" should be after the last child - the bad source.
|
||||
create:
|
||||
function() {
|
||||
createMedia("audio");
|
||||
addSource("404a.wav", gWavAudioType);
|
||||
addSource("404b.wav", gWavAudioType);
|
||||
gMedia.addEventListener("error",
|
||||
function(e) {
|
||||
// Should awaken waiting load, causing successful load.
|
||||
if (!gTest11Prepended) {
|
||||
prependSource(gWavAudio, gWavAudioType);
|
||||
gTest11Prepended = true;
|
||||
if (!prepended) {
|
||||
prependSource(src, type);
|
||||
prepended = true;
|
||||
}
|
||||
},
|
||||
false);
|
||||
@ -239,20 +157,34 @@ function nextTest() {
|
||||
gMedia = null;
|
||||
}
|
||||
gEventNum = 0;
|
||||
|
||||
|
||||
if (gTestNum == gTests.length) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
gTestNum = 0;
|
||||
++gTestFileNum;
|
||||
if (gTestFileNum == gSmallTests.length) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
log("Starting test " + gTestNum);
|
||||
|
||||
|
||||
var src = gSmallTests[gTestFileNum].name;
|
||||
var type = gSmallTests[gTestFileNum].type;
|
||||
|
||||
var t = gTests[gTestNum];
|
||||
gTestName = "Test"+gTestNum;
|
||||
gTestNum++;
|
||||
|
||||
createMedia(type.match(/^audio\//) ? "audio" : "video");
|
||||
if (gMedia.canPlayType(type) == "no") {
|
||||
// Unsupported type, skip to next test
|
||||
nextTest();
|
||||
return;
|
||||
}
|
||||
|
||||
gTestName = "Test " + src + " " + (gTestNum - 1);
|
||||
log("Starting " + gTestName);
|
||||
gExpectedEvents = t.expectedEvents;
|
||||
t.create();
|
||||
|
||||
t.create(src, type);
|
||||
}
|
||||
|
||||
addLoadEvent(nextTest);
|
||||
|
@ -5,17 +5,18 @@
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script type="application/javascript" src="manifest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function maketest(expect_load, attach_media, name, type, check_metadata) {
|
||||
function maketest(attach_media, name, type, check_metadata) {
|
||||
return function (testNum) {
|
||||
var e = document.createElement('video');
|
||||
var errorRun = false;
|
||||
if (expect_load) {
|
||||
if (check_metadata) {
|
||||
e.addEventListener('loadedmetadata', function () {
|
||||
ok(e.readyState >= HTMLMediaElement.HAVE_METADATA,
|
||||
'test ' + testNum + ' readyState ' + e.readyState + ' expected >= ' + HTMLMediaElement.HAVE_METADATA);
|
||||
@ -31,7 +32,6 @@ function maketest(expect_load, attach_media, name, type, check_metadata) {
|
||||
} else {
|
||||
e.addEventListener('error', function(event) {
|
||||
event.stopPropagation();
|
||||
is(expect_load, false, "Didn't load when we weren't expecting to.");
|
||||
is(errorRun, false, "error handler should run once only!");
|
||||
errorRun = true;
|
||||
is(e.readyState, HTMLMediaElement.HAVE_NOTHING,
|
||||
@ -87,56 +87,56 @@ function late_add_sources_first(element, name, type) {
|
||||
do_add_source(element, name, 'unsupported/type');
|
||||
}
|
||||
|
||||
function check_ogg(e) {
|
||||
is(e.videoWidth, 320, "video width " + e.currentSrc);
|
||||
is(e.videoHeight, 240, "video height " + e.currentSrc);
|
||||
}
|
||||
|
||||
function check_wav(e) {
|
||||
ok(e.duration > 0.9 && e.duration < 1.1, "duration should be around 1.0");
|
||||
}
|
||||
|
||||
var nextTest = 0;
|
||||
var subTests = [
|
||||
maketest(true, set_src, '320x240.ogv', null, check_ogg),
|
||||
maketest(true, add_source, '320x240.ogv', null, check_ogg),
|
||||
maketest(true, add_source, '320x240.ogv', 'application/ogg', check_ogg),
|
||||
maketest(true, add_sources_last, '320x240.ogv', null, check_ogg),
|
||||
maketest(true, add_sources_first, '320x240.ogv', 'application/ogg', check_ogg),
|
||||
maketest(true, set_src, 'r11025_u8_c1.wav', null, check_wav),
|
||||
maketest(true, add_source, 'r11025_u8_c1.wav', null, check_wav),
|
||||
maketest(true, add_source, 'r11025_u8_c1.wav', 'audio/x-wav', check_wav),
|
||||
maketest(true, add_sources_last, 'r11025_u8_c1.wav', null, check_wav),
|
||||
maketest(true, add_sources_first, 'r11025_u8_c1.wav', 'audio/x-wav', check_wav),
|
||||
var subtests = [
|
||||
maketest(add_source, 'unknown.raw', 'bogus/type', null)
|
||||
];
|
||||
|
||||
var tmpVid = document.createElement('video');
|
||||
|
||||
for (var i = 0; i < gSmallTests.length; ++i) {
|
||||
var test = gSmallTests[i];
|
||||
var src = test.name;
|
||||
var type = test.type;
|
||||
|
||||
if (tmpVid.canPlayType(type) == "no")
|
||||
continue;
|
||||
|
||||
// The following nested function hack is to ensure that 'test' is correctly
|
||||
// captured in the closure and we don't end up getting the value 'test'
|
||||
// had in the last iteration of the loop. I blame Brendan.
|
||||
var check = function(test) { return function (e) {
|
||||
checkMetadata(test.name, e, test);
|
||||
}}(test);
|
||||
|
||||
var otherType = type.match(/^video\//) ? "audio/x-wav" : "video/ogg";
|
||||
subtests.push(maketest(set_src, src, null, check),
|
||||
maketest(add_source, src, null, check),
|
||||
maketest(add_source, src, type, check),
|
||||
maketest(add_sources_last, src, null, check),
|
||||
maketest(add_sources_first, src, type, check),
|
||||
|
||||
// type hint matches a decoder, actual type matches different decoder
|
||||
maketest(true, add_source, '320x240.ogv', 'audio/x-wav', check_ogg),
|
||||
maketest(true, add_source, 'r11025_u8_c1.wav', 'application/ogg', check_wav),
|
||||
maketest(add_source, src, otherType, check),
|
||||
maketest(add_source, 'unknown.raw', type, null),
|
||||
|
||||
// should not start loading, type excludes it from media candiate list
|
||||
maketest(false, add_source, '320x240.ogv', 'bogus/type', null),
|
||||
maketest(false, add_source, 'r11025_u8_c1.wav', 'bogus/type', null),
|
||||
maketest(false, add_source, 'unknown.raw', 'bogus/type', null),
|
||||
|
||||
// should start loading, then fire error, needs bug 462455 fixed
|
||||
maketest(false, add_source, 'unknown.raw', 'application/ogg', null),
|
||||
maketest(false, add_source, 'unknown.raw', 'audio/x-wav', null),
|
||||
maketest(add_source, src, 'bogus/type', null),
|
||||
|
||||
// element doesn't notice source children attached later, needs bug 462455 fixed
|
||||
maketest(true, late_add_sources_last, '320x240.ogv', 'application/ogg', check_ogg),
|
||||
maketest(true, late_add_sources_first, '320x240.ogv', 'application/ogg', check_ogg),
|
||||
maketest(true, late_add_sources_last, 'r11025_u8_c1.wav', 'audio/x-wav', check_wav),
|
||||
maketest(true, late_add_sources_first, 'r11025_u8_c1.wav', 'audio/x-wav', check_wav),
|
||||
|
||||
SimpleTest.finish
|
||||
];
|
||||
maketest(late_add_sources_last, src, type, check),
|
||||
maketest(late_add_sources_first, src, type, check));
|
||||
}
|
||||
|
||||
function runNextTest() {
|
||||
if (nextTest >= subtests.length) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
setTimeout(function () {
|
||||
ok(true, 'subtest ' + nextTest);
|
||||
subTests[nextTest](nextTest);
|
||||
nextTest += 1;
|
||||
}, 0);
|
||||
subtests[nextTest](nextTest);
|
||||
nextTest += 1;
|
||||
}, 0);
|
||||
}
|
||||
|
||||
addLoadEvent(runNextTest);
|
||||
|
75
content/media/test/test_playback.html
Normal file
75
content/media/test/test_playback.html
Normal file
@ -0,0 +1,75 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test playback of media files that should play OK</title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script type="text/javascript" src="manifest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
var PARALLEL_TESTS = 2;
|
||||
|
||||
var testIndex = 0;
|
||||
var videos = [];
|
||||
|
||||
var testsWaiting = 0;
|
||||
|
||||
function startTest() {
|
||||
if (completed)
|
||||
return false;
|
||||
v = document.getElementById('v');
|
||||
v.play();
|
||||
return false;
|
||||
}
|
||||
|
||||
function startTests() {
|
||||
for (var i = 0; i < videos.length; ++i) {
|
||||
document.body.removeChild(videos[i]);
|
||||
}
|
||||
videos = [];
|
||||
while (videos.length < PARALLEL_TESTS && testIndex < gPlayTests.length) {
|
||||
var v = document.createElement('video');
|
||||
var test = gPlayTests[testIndex];
|
||||
++testIndex;
|
||||
if (v.canPlayType(test.type) == "no")
|
||||
continue;
|
||||
|
||||
v.src = test.name;
|
||||
var check = function(test, v) { return function() {
|
||||
checkMetadata(test.name, v, test);
|
||||
}}(test, v);
|
||||
var checkEnded = function(test, v) { return function() {
|
||||
if (test.duration) {
|
||||
ok(Math.abs(v.currentTime - test.duration) < 0.1,
|
||||
test.name + " current time at end: " + v.currentTime);
|
||||
}
|
||||
ok(v.ended, test.name + " checking playback has ended");
|
||||
--testsWaiting;
|
||||
if (testsWaiting == 0) {
|
||||
setTimeout(startTests, 0);
|
||||
}
|
||||
}}(test, v);
|
||||
v.addEventListener("loadedmetadata", check, false);
|
||||
v.addEventListener("ended", checkEnded, false);
|
||||
++testsWaiting;
|
||||
document.body.appendChild(v);
|
||||
v.play();
|
||||
videos.push(v);
|
||||
}
|
||||
if (videos.length == 0) {
|
||||
// No new tests were spawned, perhaps the remaining tests on the list are
|
||||
// not supported, or we just reached the end of the list.
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
addLoadEvent(startTests);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
82
content/media/test/test_playback_errors.html
Normal file
82
content/media/test/test_playback_errors.html
Normal file
@ -0,0 +1,82 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test playback of media files that should have errors</title>
|
||||
<script type="text/javascript" src="/MochiKit/packed.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script type="text/javascript" src="manifest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
var PARALLEL_TESTS = 2;
|
||||
|
||||
var testIndex = 0;
|
||||
var videos = [];
|
||||
|
||||
var testsWaiting = 0;
|
||||
|
||||
function startTest() {
|
||||
if (completed)
|
||||
return false;
|
||||
v = document.getElementById('v');
|
||||
v.play();
|
||||
return false;
|
||||
}
|
||||
|
||||
function startTests() {
|
||||
for (var i = 0; i < videos.length; ++i) {
|
||||
document.body.removeChild(videos[i]);
|
||||
}
|
||||
videos = [];
|
||||
while (videos.length < PARALLEL_TESTS && testIndex < gErrorTests.length) {
|
||||
var v = document.createElement('video');
|
||||
var test = gErrorTests[testIndex];
|
||||
++testIndex;
|
||||
if (v.canPlayType(test.type) == "no")
|
||||
continue;
|
||||
|
||||
v.src = test.name;
|
||||
v._errorCount = 0;
|
||||
v._ignore = false;
|
||||
function endedTest(v) {
|
||||
if (v._ignore)
|
||||
return;
|
||||
v._ignore = true;
|
||||
--testsWaiting;
|
||||
if (testsWaiting == 0) {
|
||||
setTimeout(startTests, 0);
|
||||
}
|
||||
}
|
||||
var checkError = function(test, v) { return function(evt) {
|
||||
evt.stopPropagation();
|
||||
v._errorCount++;
|
||||
is(v._errorCount, 1, test.name + " only one error fired");
|
||||
endedTest(v);
|
||||
}}(test, v);
|
||||
var checkEnded = function(test, v) { return function() {
|
||||
ok(false, test.name + " successfully played");
|
||||
endedTest(v);
|
||||
}}(test, v);
|
||||
v.addEventListener("error", checkError, false);
|
||||
v.addEventListener("ended", checkEnded, false);
|
||||
++testsWaiting;
|
||||
document.body.appendChild(v);
|
||||
v.play();
|
||||
videos.push(v);
|
||||
}
|
||||
if (videos.length == 0) {
|
||||
// No new tests were spawned, perhaps the remaining tests on the list are
|
||||
// not supported, or we just reached the end of the list.
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
addLoadEvent(startTests);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user