Merge mozilla-central into Places

This commit is contained in:
Shawn Wilsher 2010-12-06 09:48:54 -08:00
commit aeffa1f8c7
534 changed files with 20448 additions and 13904 deletions

View File

@ -192,7 +192,10 @@ ifdef MOZ_CRASHREPORTER
cd $(DIST)/crashreporter-symbols && \
zip -r9D "../$(PKG_PATH)$(SYMBOL_FULL_ARCHIVE_BASENAME).zip" .
cd $(DIST)/crashreporter-symbols && \
zip -r9D "../$(PKG_PATH)$(SYMBOL_ARCHIVE_BASENAME).zip" . -i "*.sym"
grep "sym" $(SYMBOL_INDEX_NAME) > $(SYMBOL_INDEX_NAME).tmp && \
mv $(SYMBOL_INDEX_NAME).tmp $(SYMBOL_INDEX_NAME)
cd $(DIST)/crashreporter-symbols && \
zip -r9D "../$(PKG_PATH)$(SYMBOL_ARCHIVE_BASENAME).zip" . -i "*.sym" -i "*.txt"
else
ifdef WINCE
ifdef SYMBOLSTORE_PATH

View File

@ -491,17 +491,25 @@ nsAccDocManager::CreateDocOrRootAccessible(nsIDocument *aDocument)
// nsAccDocManager static
PLDHashOperator
nsAccDocManager::ClearDocCacheEntry(const nsIDocument* aKey,
nsRefPtr<nsDocAccessible>& aDocAccessible,
void* aUserArg)
nsAccDocManager::GetFirstEntryInDocCache(const nsIDocument* aKey,
nsDocAccessible* aDocAccessible,
void* aUserArg)
{
NS_ASSERTION(aDocAccessible,
"Calling ClearDocCacheEntry with a NULL pointer!");
"No doc accessible for the object in doc accessible cache!");
*reinterpret_cast<nsDocAccessible**>(aUserArg) = aDocAccessible;
if (aDocAccessible)
aDocAccessible->Shutdown();
return PL_DHASH_STOP;
}
return PL_DHASH_REMOVE;
void
nsAccDocManager::ClearDocCache()
{
nsDocAccessible* docAcc = nsnull;
while (mDocAccessibleCache.EnumerateRead(GetFirstEntryInDocCache, static_cast<void*>(&docAcc))) {
if (docAcc)
docAcc->Shutdown();
}
}
PLDHashOperator

View File

@ -152,20 +152,17 @@ private:
nsDocAccessibleHashtable;
/**
* Shutdown and remove the document accessible from cache.
* Get first entry of the document accessible from cache.
*/
static PLDHashOperator
ClearDocCacheEntry(const nsIDocument* aKey,
nsRefPtr<nsDocAccessible>& aDocAccessible,
void* aUserArg);
GetFirstEntryInDocCache(const nsIDocument* aKey,
nsDocAccessible* aDocAccessible,
void* aUserArg);
/**
* Clear the cache and shutdown the document accessibles.
*/
void ClearDocCache()
{
mDocAccessibleCache.Enumerate(ClearDocCacheEntry, static_cast<void*>(this));
}
void ClearDocCache();
struct nsSearchAccessibleInCacheArg
{

View File

@ -8,6 +8,8 @@ const EVENT_DOCUMENT_LOAD_STOPPED = nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_STOPP
const EVENT_HIDE = nsIAccessibleEvent.EVENT_HIDE;
const EVENT_FOCUS = nsIAccessibleEvent.EVENT_FOCUS;
const EVENT_NAME_CHANGE = nsIAccessibleEvent.EVENT_NAME_CHANGE;
const EVENT_MENU_START = nsIAccessibleEvent.EVENT_MENU_START;
const EVENT_MENU_END = nsIAccessibleEvent.EVENT_MENU_END;
const EVENT_MENUPOPUP_START = nsIAccessibleEvent.EVENT_MENUPOPUP_START;
const EVENT_MENUPOPUP_END = nsIAccessibleEvent.EVENT_MENUPOPUP_END;
const EVENT_REORDER = nsIAccessibleEvent.EVENT_REORDER;
@ -35,6 +37,11 @@ var gA11yEventDumpID = "";
*/
var gA11yEventDumpToConsole = false;
/**
* Set up this variable to dump event processing into error console.
*/
var gA11yEventDumpToAppConsole = false;
/**
* Executes the function when requested event is handled.
*
@ -270,10 +277,12 @@ function eventQueue(aEventType)
// Start processing of next invoker.
invoker = this.getNextInvoker();
this.setEventHandler(invoker);
if (gLogger.isEnabled()) {
gLogger.logToConsole("Event queue: \n invoke: " + invoker.getID());
gLogger.logToDOM("EQ: invoke: " + invoker.getID(), true);
}
if (gA11yEventDumpToConsole)
dump("\nEvent queue: \n invoke: " + invoker.getID() + "\n");
this.setEventHandler(invoker);
if (invoker.invoke() == INVOKER_ACTION_FAILED) {
// Invoker failed to prepare action, fail and finish tests.
@ -402,6 +411,22 @@ function eventQueue(aEventType)
for (var idx = 0; idx < this.mEventSeq.length; idx++) {
var eventType = this.getEventType(idx);
if (gLogger.isEnabled()) {
var strEventType = (typeof eventType == "string") ? eventType :
eventTypeToString(eventType);
var msg = "registered";
if (this.isEventUnexpected(idx))
msg += " unexpected";
msg += ": event type: " + strEventType + ", target: " +
prettyName(this.getEventTarget(idx));
gLogger.logToConsole(msg);
gLogger.logToDOM(msg, true);
}
if (typeof eventType == "string") {
// DOM event
var target = this.getEventTarget(idx);
@ -466,6 +491,11 @@ function eventQueue(aEventType)
return invoker.getID();
}
this.isEventUnexpected = function eventQueue_isEventUnexpected(aIdx)
{
return this.mEventSeq[aIdx].unexpected;
}
this.compareEvents = function eventQueue_compareEvents(aIdx, aEvent)
{
var eventType1 = this.getEventType(aIdx);
@ -526,7 +556,7 @@ function eventQueue(aEventType)
aExpectedEventIdx,
aMatch)
{
if (!gA11yEventDumpID) // debug stuff
if (!gLogger.isEnabled()) // debug stuff
return;
// Dump DOM event information. Skip a11y event since it is dumped by
@ -534,46 +564,31 @@ function eventQueue(aEventType)
if (aOrigEvent instanceof nsIDOMEvent) {
var info = "Event type: " + aOrigEvent.type;
info += ". Target: " + prettyName(aOrigEvent.originalTarget);
dumpInfoToDOM(info);
gLogger.logToDOM(info);
}
var currType = this.getEventType(aExpectedEventIdx);
var currTarget = this.getEventTarget(aExpectedEventIdx);
var containerTagName = document instanceof nsIDOMHTMLDocument ?
"div" : "description";
var inlineTagName = document instanceof nsIDOMHTMLDocument ?
"span" : "description";
var container = document.createElement(containerTagName);
container.setAttribute("style", "padding-left: 10px;");
var text1 = document.createTextNode("EQ: ");
container.appendChild(text1);
var styledNode = document.createElement(inlineTagName);
var msg = "EQ: ";
var emphText = "";
if (aMatch) {
styledNode.setAttribute("style", "color: blue;");
styledNode.textContent = "matched";
emphText = "matched ";
// Dump matched events into console.
if (gA11yEventDumpToConsole)
dump("\n*****\nEQ matched: " + eventTypeToString(currType) + "\n*****\n");
var consoleMsg =
"*****\nEQ matched: " + eventTypeToString(currType) + "\n*****";
gLogger.logToConsole(consoleMsg);
} else {
styledNode.textContent = "expected";
msg += "expected";
}
container.appendChild(styledNode);
var info = " event, type: ";
info += (typeof currType == "string") ?
msg += " event, type: ";
msg += (typeof currType == "string") ?
currType : eventTypeToString(currType);
info += ". Target: " + prettyName(currTarget);
msg += ", target: " + prettyName(currTarget);
var text1 = document.createTextNode(info);
container.appendChild(text1);
dumpInfoToDOM(container);
gLogger.logToDOM(msg, true, emphText);
}
this.mDefEventType = aEventType;
@ -640,11 +655,12 @@ function sequence()
// Event queue invokers
/**
* Invokers defined below take a checker object implementing 'check' method
* which will be called when proper event is handled. Invokers listen default
* event type registered in event queue object until it is passed explicetly.
* Invokers defined below take a checker object (or array of checker objects)
* implementing 'check' method which will be called when proper event is
* handled. Invokers listen default event type registered in event queue object
* until it is passed explicetly.
*
* Note, checker object is optional.
* Note, checker object or array of checker objects is optional.
* Note, you don't need to initialize 'target' and 'type' members of checker
* object. The 'target' member will be initialized by invoker object and you are
* free to use it in 'check' method.
@ -653,9 +669,9 @@ function sequence()
/**
* Click invoker.
*/
function synthClick(aNodeOrID, aChecker, aEventType)
function synthClick(aNodeOrID, aCheckerOrEventSeq, aEventType)
{
this.__proto__ = new synthAction(aNodeOrID, aChecker, aEventType);
this.__proto__ = new synthAction(aNodeOrID, aCheckerOrEventSeq, aEventType);
this.invoke = function synthClick_invoke()
{
@ -675,9 +691,9 @@ function synthClick(aNodeOrID, aChecker, aEventType)
/**
* Mouse move invoker.
*/
function synthMouseMove(aNodeOrID, aChecker, aEventType)
function synthMouseMove(aNodeOrID, aCheckerOrEventSeq, aEventType)
{
this.__proto__ = new synthAction(aNodeOrID, aChecker, aEventType);
this.__proto__ = new synthAction(aNodeOrID, aCheckerOrEventSeq, aEventType);
this.invoke = function synthMouseMove_invoke()
{
@ -694,9 +710,9 @@ function synthMouseMove(aNodeOrID, aChecker, aEventType)
/**
* General key press invoker.
*/
function synthKey(aNodeOrID, aKey, aArgs, aChecker, aEventType)
function synthKey(aNodeOrID, aKey, aArgs, aCheckerOrEventSeq, aEventType)
{
this.__proto__ = new synthAction(aNodeOrID, aChecker, aEventType);
this.__proto__ = new synthAction(aNodeOrID, aCheckerOrEventSeq, aEventType);
this.invoke = function synthKey_invoke()
{
@ -715,10 +731,10 @@ function synthKey(aNodeOrID, aKey, aArgs, aChecker, aEventType)
/**
* Tab key invoker.
*/
function synthTab(aNodeOrID, aChecker, aEventType)
function synthTab(aNodeOrID, aCheckerOrEventSeq, aEventType)
{
this.__proto__ = new synthKey(aNodeOrID, "VK_TAB", { shiftKey: false },
aChecker, aEventType);
aCheckerOrEventSeq, aEventType);
this.getID = function synthTab_getID()
{
@ -729,10 +745,10 @@ function synthTab(aNodeOrID, aChecker, aEventType)
/**
* Shift tab key invoker.
*/
function synthShiftTab(aNodeOrID, aChecker, aEventType)
function synthShiftTab(aNodeOrID, aCheckerOrEventSeq, aEventType)
{
this.__proto__ = new synthKey(aNodeOrID, "VK_TAB", { shiftKey: true },
aChecker, aEventType);
aCheckerOrEventSeq, aEventType);
this.getID = function synthTabTest_getID()
{
@ -743,9 +759,9 @@ function synthShiftTab(aNodeOrID, aChecker, aEventType)
/**
* Down arrow key invoker.
*/
function synthDownKey(aNodeOrID, aChecker, aEventType)
function synthDownKey(aNodeOrID, aCheckerOrEventSeq, aEventType)
{
this.__proto__ = new synthKey(aNodeOrID, "VK_DOWN", null, aChecker,
this.__proto__ = new synthKey(aNodeOrID, "VK_DOWN", null, aCheckerOrEventSeq,
aEventType);
this.getID = function synthDownKey_getID()
@ -757,9 +773,9 @@ function synthDownKey(aNodeOrID, aChecker, aEventType)
/**
* Right arrow key invoker.
*/
function synthRightKey(aNodeOrID, aChecker, aEventType)
function synthRightKey(aNodeOrID, aCheckerOrEventSeq, aEventType)
{
this.__proto__ = new synthKey(aNodeOrID, "VK_RIGHT", null, aChecker,
this.__proto__ = new synthKey(aNodeOrID, "VK_RIGHT", null, aCheckerOrEventSeq,
aEventType);
this.getID = function synthRightKey_getID()
@ -771,9 +787,9 @@ function synthRightKey(aNodeOrID, aChecker, aEventType)
/**
* Home key invoker.
*/
function synthHomeKey(aNodeOrID, aChecker, aEventType)
function synthHomeKey(aNodeOrID, aCheckerOrEventSeq, aEventType)
{
this.__proto__ = new synthKey(aNodeOrID, "VK_HOME", null, aChecker,
this.__proto__ = new synthKey(aNodeOrID, "VK_HOME", null, aCheckerOrEventSeq,
aEventType);
this.getID = function synthHomeKey_getID()
@ -785,9 +801,9 @@ function synthHomeKey(aNodeOrID, aChecker, aEventType)
/**
* Focus invoker.
*/
function synthFocus(aNodeOrID, aChecker, aEventType)
function synthFocus(aNodeOrID, aCheckerOrEventSeq, aEventType)
{
this.__proto__ = new synthAction(aNodeOrID, aChecker, aEventType);
this.__proto__ = new synthAction(aNodeOrID, aCheckerOrEventSeq, aEventType);
this.invoke = function synthFocus_invoke()
{
@ -803,10 +819,10 @@ function synthFocus(aNodeOrID, aChecker, aEventType)
/**
* Focus invoker. Focus the HTML body of content document of iframe.
*/
function synthFocusOnFrame(aNodeOrID, aChecker, aEventType)
function synthFocusOnFrame(aNodeOrID, aCheckerOrEventSeq, aEventType)
{
this.__proto__ = new synthAction(getNode(aNodeOrID).contentDocument,
aChecker, aEventType);
aCheckerOrEventSeq, aEventType);
this.invoke = function synthFocus_invoke()
{
@ -822,9 +838,9 @@ function synthFocusOnFrame(aNodeOrID, aChecker, aEventType)
/**
* Select all invoker.
*/
function synthSelectAll(aNodeOrID, aChecker, aEventType)
function synthSelectAll(aNodeOrID, aCheckerOrEventSeq, aEventType)
{
this.__proto__ = new synthAction(aNodeOrID, aChecker, aEventType);
this.__proto__ = new synthAction(aNodeOrID, aCheckerOrEventSeq, aEventType);
this.invoke = function synthSelectAll_invoke()
{
@ -911,17 +927,20 @@ var gA11yEventObserver =
var listenersArray = gA11yEventListeners[event.eventType];
var eventFromDumpArea = false;
if (gA11yEventDumpID) { // debug stuff
if (gLogger.isEnabled()) { // debug stuff
eventFromDumpArea = true;
var target = event.DOMNode;
var dumpElm = document.getElementById(gA11yEventDumpID);
var dumpElm = gA11yEventDumpID ?
document.getElementById(gA11yEventDumpID) : null;
var parent = target;
while (parent && parent != dumpElm)
parent = parent.parentNode;
if (dumpElm) {
var parent = target;
while (parent && parent != dumpElm)
parent = parent.parentNode;
}
if (parent != dumpElm) {
if (!dumpElm || parent != dumpElm) {
var type = eventTypeToString(event.eventType);
var info = "Event type: " + type;
@ -937,10 +956,7 @@ var gA11yEventObserver =
info += ". Listeners count: " + listenersArray.length;
eventFromDumpArea = false;
if (gA11yEventDumpToConsole)
dump("\n" + info + "\n");
dumpInfoToDOM(info);
gLogger.log(info);
}
}
@ -998,35 +1014,93 @@ function removeA11yEventListener(aEventType, aEventHandler)
}
/**
* Dumps message to DOM.
*
* @param aInfo [in] the message or DOM node to dump
* @param aDumpNode [in, optional] host DOM node for dumped message, if ommited
* then global variable gA11yEventDumpID is used
* Used to dump debug information.
*/
function dumpInfoToDOM(aInfo, aDumpNode)
var gLogger =
{
var dumpID = gA11yEventDumpID ? gA11yEventDumpID : aDumpNode;
if (!dumpID)
return;
var dumpElm = document.getElementById(dumpID);
if (!dumpElm) {
ok(false, "No dump element '" + dumpID + "' within the document!");
return;
}
var containerTagName = document instanceof nsIDOMHTMLDocument ?
"div" : "description";
/**
* Return true if dump is enabled.
*/
isEnabled: function debugOutput_isEnabled()
{
return gA11yEventDumpID || gA11yEventDumpToConsole ||
gA11yEventDumpToAppConsole;
},
var container = document.createElement(containerTagName);
if (aInfo instanceof nsIDOMNode)
container.appendChild(aInfo);
else
container.textContent = aInfo;
/**
* Dump information into DOM and console if applicable.
*/
log: function logger_log(aMsg)
{
this.logToConsole(aMsg);
this.logToAppConsole(aMsg);
this.logToDOM(aMsg);
},
dumpElm.appendChild(container);
}
/**
* Log message to DOM.
*
* @param aMsg [in] the primary message
* @param aHasIndent [in, optional] if specified the message has an indent
* @param aPreEmphText [in, optional] the text is colored and appended prior
* primary message
*/
logToDOM: function logger_logToDOM(aMsg, aHasIndent, aPreEmphText)
{
if (gA11yEventDumpID == "")
return;
var dumpElm = document.getElementById(gA11yEventDumpID);
if (!dumpElm) {
ok(false,
"No dump element '" + gA11yEventDumpID + "' within the document!");
return;
}
var containerTagName = document instanceof nsIDOMHTMLDocument ?
"div" : "description";
var container = document.createElement(containerTagName);
if (aHasIndent)
container.setAttribute("style", "padding-left: 10px;");
if (aPreEmphText) {
var inlineTagName = document instanceof nsIDOMHTMLDocument ?
"span" : "description";
var emphElm = document.createElement(inlineTagName);
emphElm.setAttribute("style", "color: blue;");
emphElm.textContent = aPreEmphText;
container.appendChild(emphElm);
}
var textNode = document.createTextNode(aMsg);
container.appendChild(textNode);
dumpElm.appendChild(container);
},
/**
* Log message to console.
*/
logToConsole: function logger_logToConsole(aMsg)
{
if (gA11yEventDumpToConsole)
dump("\n" + aMsg + "\n");
},
/**
* Log message to error console.
*/
logToAppConsole: function logger_logToAppConsole(aMsg)
{
if (gA11yEventDumpToAppConsole)
consoleService.logStringMessage("events: " + aMsg);
},
consoleService: Components.classes["@mozilla.org/consoleservice;1"].
getService(Components.interfaces.nsIConsoleService)
};
////////////////////////////////////////////////////////////////////////////////
@ -1073,19 +1147,27 @@ function sequenceItem(aProcessor, aEventType, aTarget, aItemID)
/**
* Invoker base class for prepare an action.
*/
function synthAction(aNodeOrID, aChecker, aEventType)
function synthAction(aNodeOrID, aCheckerOrEventSeq, aEventType)
{
this.DOMNode = getNode(aNodeOrID);
if (aChecker)
aChecker.target = this.DOMNode;
this.checker = null;
if (aCheckerOrEventSeq) {
if (aCheckerOrEventSeq instanceof Array) {
this.eventSeq = aCheckerOrEventSeq;
} else {
this.checker = aCheckerOrEventSeq;
this.checker.target = this.DOMNode;
}
}
if (aEventType)
this.eventSeq = [ new invokerChecker(aEventType, this.DOMNode) ];
this.check = function synthAction_check(aEvent)
{
if (aChecker)
aChecker.check(aEvent);
if (this.checker)
this.checker.check(aEvent);
}
this.getID = function synthAction_getID() { return aNodeOrID + " action"; }

View File

@ -65,6 +65,7 @@ _TEST_FILES =\
test_focus.xul \
test_focus_name.html \
test_focusdoc.html \
test_menu.xul \
test_mutation.html \
test_scroll.xul \
test_selection.html \

View File

@ -10,6 +10,8 @@
src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"></script>
<script type="application/javascript"
src="../common.js"></script>
@ -22,14 +24,32 @@
const kViaDisplayStyle = 0;
const kViaVisibilityStyle = 1;
function showMenu(aMenuID, aHow)
function focusMenu(aMenuBarID, aMenuID)
{
this.eventSeq = [
new invokerChecker(EVENT_MENU_START, getNode(aMenuBarID)),
new invokerChecker(EVENT_FOCUS, getNode(aMenuID)),
];
this.invoke = function focusMenu_invoke()
{
getNode(aMenuID).focus();
}
this.getID = function focusMenu_getID()
{
return "focus menu '" + aMenuID + "'";
}
}
function showMenu(aMenuID, aParentMenuID, aHow)
{
this.menuNode = getNode(aMenuID);
this.eventSeq = [
new invokerChecker(EVENT_SHOW, this.menuNode),
new invokerChecker(EVENT_MENUPOPUP_START, this.menuNode),
new invokerChecker(EVENT_REORDER, document)
new invokerChecker(EVENT_REORDER, getNode(aParentMenuID))
];
this.invoke = function showMenu_invoke()
@ -48,7 +68,7 @@
};
}
function closeMenu(aMenuID, aHow)
function closeMenu(aMenuID, aParentMenuID, aHow)
{
this.menuNode = getNode(aMenuID);
this.menu = null;
@ -56,7 +76,7 @@
this.eventSeq = [
new invokerChecker(EVENT_MENUPOPUP_END, getMenu, this),
new invokerChecker(EVENT_HIDE, getMenu, this),
new invokerChecker(EVENT_REORDER, document),
new invokerChecker(EVENT_REORDER, getNode(aParentMenuID))
];
this.invoke = function closeMenu_invoke()
@ -84,21 +104,61 @@
}
}
function focusInsideMenu(aMenuID, aMenuBarID)
{
this.eventSeq = [
new invokerChecker(EVENT_FOCUS, getNode(aMenuID))
];
this.unexpectedEventSeq = [
new invokerChecker(EVENT_MENU_END, getNode(aMenuBarID))
];
this.invoke = function focusInsideMenu_invoke()
{
getNode(aMenuID).focus();
}
this.getID = function focusInsideMenu_getID()
{
return "focus menu '" + aMenuID + "'";
}
}
function blurMenu(aMenuBarID)
{
var eventSeq = [
new invokerChecker(EVENT_MENU_END, getNode(aMenuBarID)),
new invokerChecker(EVENT_FOCUS, getNode("outsidemenu"))
];
this.__proto__ = new synthClick("outsidemenu", eventSeq);
this.getID = function blurMenu_getID()
{
return "blur menu";
}
}
////////////////////////////////////////////////////////////////////////////
// Do tests
var gQueue = null;
//gA11yEventDumpID = "eventdump";
//gA11yEventDumpToConsole = true;
function doTests()
{
gQueue = new eventQueue();
gQueue.push(new showMenu("menu1", kViaDisplayStyle));
gQueue.push(new closeMenu("menu1", kViaDisplayStyle));
gQueue.push(new showMenu("menu2", kViaVisibilityStyle));
gQueue.push(new closeMenu("menu2", kViaVisibilityStyle));
gQueue.push(new focusMenu("menubar", "menu-file"));
gQueue.push(new showMenu("menupopup-file", "menu-file", kViaDisplayStyle));
gQueue.push(new closeMenu("menupopup-file", "menu-file", kViaDisplayStyle));
gQueue.push(new showMenu("menupopup-edit", "menu-edit", kViaVisibilityStyle));
gQueue.push(new closeMenu("menupopup-edit", "menu-edit", kViaVisibilityStyle));
gQueue.push(new focusInsideMenu("menu-edit", "menubar"));
gQueue.push(new blurMenu("menubar"));
gQueue.invoke(); // Will call SimpleTest.finish();
}
@ -120,20 +180,34 @@
title="Menupopup end event isn't fired for ARIA menus">
Mozilla Bug 614829
</a>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=615189"
title="Clean up FireAccessibleFocusEvent">
Mozilla Bug 615189
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<div id="menu1" role="menu" style="display: none;">
<div role="menuitem">menuitem1.1</div>
<div role="menuitem">menuitem1.2</div>
</div>
<div id="menu2" role="menu" style="visibility: hidden;">
<div role="menuitem">menuitem2.1</div>
<div role="menuitem">menuitem2.2</div>
<div id="menubar" role="menubar">
<div id="menu-file" role="menuitem" tabindex="0">
File
<div id="menupopup-file" role="menu" style="display: none;">
<div id="menuitem-newtab" role="menuitem" tabindex="0">New Tab</div>
<div id="menuitem-newwindow" role="menuitem" tabindex="0">New Window</div>
</div>
</div>
<div id="menu-edit" role="menuitem" tabindex="0">
Edit
<div id="menupopup-edit" role="menu" style="visibility: hidden;">
<div id="menuitem-undo" role="menuitem" tabindex="0">Undo</div>
<div id="menuitem-redo" role="menuitem" tabindex="0">Redo</div>
</div>
</div>
</div>
<div tabindex="0" id="outsidemenu">outsidemenu</div>
<div id="eventdump"></div>

View File

@ -0,0 +1,204 @@
<?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="Accessible menu events testing for XUL menu">
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js" />
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
<script type="application/javascript"
src="../common.js" />
<script type="application/javascript"
src="../events.js" />
<script type="application/javascript">
function openFileMenu()
{
this.eventSeq = [
new invokerChecker(EVENT_MENU_START, getNode("menubar")),
new invokerChecker(EVENT_MENUPOPUP_START, getNode("menupopup-file"))
// new invokerChecker(EVENT_FOCUS, getNode("menuitem-newtab")) intermitent failure
];
this.invoke = function openFileMenu_invoke()
{
synthesizeKey("F", { altKey: true, shiftKey: true });
}
this.getID = function openFileMenu_getID()
{
return "open file menu by alt+F press";
}
}
function openEditMenu()
{
this.eventSeq = [
new invokerChecker(EVENT_MENUPOPUP_END, getNode("menupopup-file")),
new invokerChecker(EVENT_MENUPOPUP_START, getNode("menupopup-edit"))
// new invokerChecker(EVENT_FOCUS, getNode("menuitem-undo")) intermitent failure
];
this.invoke = function openEditMenu_invoke()
{
synthesizeKey("VK_RIGHT", { });
}
this.getID = function openEditMenu_getID()
{
return "open edit menu by lef arrow press";
}
}
function closeEditMenu()
{
this.eventSeq = [
//new invokerChecker(EVENT_FOCUS, document), intermitent failure
new invokerChecker(EVENT_MENUPOPUP_END, getNode("menupopup-edit")),
new invokerChecker(EVENT_MENU_END, getNode("menubar"))
];
this.invoke = function closeEditMenu_invoke()
{
synthesizeKey("VK_ESCAPE", { });
}
this.getID = function closeEditMenu_getID()
{
return "close edit menu, leave menubar";
}
}
function focusFileMenu()
{
this.eventSeq = [
new invokerChecker(EVENT_MENU_START, getNode("menubar")),
new invokerChecker(EVENT_FOCUS, getNode("menuitem-file"))
];
this.invoke = function focusFileMenu_invoke()
{
synthesizeKey("VK_ALT", { });
}
this.getID = function focusFileMenu_getID()
{
return "activate menubar, focus file menu (atl press)";
}
}
function focusEditMenu()
{
this.eventSeq = [
new invokerChecker(EVENT_FOCUS, getNode("menuitem-edit"))
];
this.invoke = function focusEditMenu_invoke()
{
synthesizeKey("VK_RIGHT", { });
}
this.getID = function focusEditMenu_getID()
{
return "focus edit menu";
}
}
function leaveMenubar()
{
this.eventSeq = [
//new invokerChecker(EVENT_FOCUS, document), intermitent failure
new invokerChecker(EVENT_MENU_END, getNode("menubar"))
];
this.invoke = function leaveMenubar_invoke()
{
synthesizeKey("VK_ESCAPE", { });
}
this.getID = function leaveMenubar_getID()
{
return "leave menubar";
}
}
/**
* Do tests.
*/
//gA11yEventDumpID = "eventdump";
gA11yEventDumpToConsole = true;
var gQueue = null;
function doTests()
{
if (!WIN) {
todo(false, "Enable this test on other platforms.");
SimpleTest.finish();
return;
}
todo(false,
"Fix intermitent failures. Focus may randomly occur before or after menupopup events!");
gQueue = new eventQueue();
gQueue.push(new openFileMenu());
gQueue.push(new openEditMenu());
gQueue.push(new closeEditMenu());
// Alt key is used to active menubar and focus menu item on Windows,
// other platforms requires setting a ui.key.menuAccessKeyFocuses
// preference.
if (WIN) {
gQueue.push(new focusFileMenu());
gQueue.push(new focusEditMenu());
gQueue.push(new leaveMenubar());
}
gQueue.invoke(); // Will call SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTests);
</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=615189"
title="Clean up FireAccessibleFocusEvent">
Mozilla Bug 615189
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
</body>
<vbox flex="1">
<menubar id="menubar">
<menu id="menuitem-file" label="File" accesskey="F">
<menupopup id="menupopup-file">
<menuitem id="menuitem-newtab" label="New Tab"/>
</menupopup>
</menu>
<menu id="menuitem-edit" label="Edit" accesskey="E">
<menupopup id="menupopup-edit">
<menuitem id="menuitem-undo" label="Undo"/>
</menupopup>
</menu>
</menubar>
<vbox id="eventdump" role="log"/>
</vbox>
</hbox>
</window>

View File

@ -5,6 +5,10 @@ var gNameRulesFileURL = "markuprules.xml";
var gRuleDoc = null;
// Debuggin stuff.
var gDumpToConsole = false;
gA11yEventDumpToConsole = gDumpToConsole;
/**
* Start name tests. Run through markup elements and test names for test
* element (see namerules.xml for details).
@ -61,10 +65,16 @@ var gTestIterator =
return;
}
document.body.removeChild(this.container);
this.ruleIdx = -1;
testNamesForMarkup(this.markupElms[this.markupIdx]);
if (gDumpToConsole) {
dump("\nPend next markup processing. Wait for reorder event on " +
prettyName(document) + "'\n");
}
waitForEvent(EVENT_REORDER, document, testNamesForMarkup,
null, this.markupElms[this.markupIdx]);
document.body.removeChild(this.container);
return;
}
@ -85,6 +95,9 @@ var gTestIterator =
*/
function testNamesForMarkup(aMarkupElm)
{
if (gDumpToConsole)
dump("\nProcessing markup '" + aMarkupElm.getAttribute("id") + "'\n");
var div = document.createElement("div");
div.setAttribute("id", "test");
@ -95,6 +108,10 @@ function testNamesForMarkup(aMarkupElm)
child = child.nextSibling;
}
if (gDumpToConsole) {
dump("\nProcessing markup. Wait for reorder event on " +
prettyName(document) + "'\n");
}
waitForEvent(EVENT_REORDER, document, testNamesForMarkupRules,
null, aMarkupElm, div);
@ -103,6 +120,9 @@ function testNamesForMarkup(aMarkupElm)
function testNamesForMarkupRules(aMarkupElm, aContainer)
{
if (gDumpToConsole)
dump("\nProcessing markup rules '" + aMarkupElm.getAttribute("id") + "'\n");
ensureAccessibleTree(aContainer);
var serializer = new XMLSerializer();
@ -122,12 +142,29 @@ function testNamesForMarkupRules(aMarkupElm, aContainer)
*/
function testNameForRule(aElm, aRuleElm)
{
if (aRuleElm.hasAttribute("attr"))
if (aRuleElm.hasAttribute("attr")) {
if (gDumpToConsole) {
dump("\nProcessing rule { attr: " + aRuleElm.getAttribute("attr") +" }\n");
}
testNameForAttrRule(aElm, aRuleElm);
else if (aRuleElm.hasAttribute("elm") && aRuleElm.hasAttribute("elmattr"))
} else if (aRuleElm.hasAttribute("elm") && aRuleElm.hasAttribute("elmattr")) {
if (gDumpToConsole) {
dump("\nProcessing rule { elm: " + aRuleElm.getAttribute("elm") +
", elmattr: " + aRuleElm.getAttribute("elmattr") +" }\n");
}
testNameForElmRule(aElm, aRuleElm);
else if (aRuleElm.getAttribute("fromsubtree") == "true")
} else if (aRuleElm.getAttribute("fromsubtree") == "true") {
if (gDumpToConsole) {
dump("\nProcessing rule { fromsubtree: " +
aRuleElm.getAttribute("fromsubtree") +" }\n");
}
testNameForSubtreeRule(aElm, aRuleElm);
}
}
function testNameForAttrRule(aElm, aRule)
@ -187,6 +224,11 @@ function testNameForElmRule(aElm, aRule)
testName(aElm, labelElm.getAttribute("a11yname"), msg);
var parentNode = labelElm.parentNode;
if (gDumpToConsole) {
dump("\nProcessed elm rule. Wait for reorder event on " +
prettyName(parentNode) + "'\n");
}
waitForEvent(EVENT_REORDER, parentNode,
gTestIterator.iterateNext, gTestIterator);
@ -198,6 +240,10 @@ function testNameForSubtreeRule(aElm, aRule)
var msg = "From subtree test.";
testName(aElm, aElm.getAttribute("a11yname"), msg);
if (gDumpToConsole) {
dump("\nProcessed from subtree rule. Wait for reorder event on " +
prettyName(aElm) + "\n");
}
waitForEvent(EVENT_REORDER, aElm, gTestIterator.iterateNext, gTestIterator);
while (aElm.firstChild)

View File

@ -124,7 +124,7 @@
<rulesample>
<markup ref="html:button" ruleset="htmlctrl">
<markup ref="html:button" ruleset="htmlctrl" id="markup1test">
<html:span id="l1" a11yname="test2">test2</html:span>
<html:span id="l2" a11yname="test3">test3</html:span>
<html:label for="btn" a11yname="test4">test4</html:label>
@ -135,7 +135,7 @@
a11yname="press me">press me</html:button>
</markup>
<markup ref="html:input" ruleset="htmlinputbutton">
<markup ref="html:input" ruleset="htmlinputbutton" id="markup2test">
<html:span id="l1" a11yname="test2">test2</html:span>
<html:span id="l2" a11yname="test3">test3</html:span>
<html:label for="btn" a11yname="test4">test4</html:label>
@ -150,7 +150,8 @@
title="test9"/>
</markup>
<markup ref="html:select/html:option[1]" ruleset="htmloption">
<markup ref="html:select/html:option[1]" ruleset="htmloption"
id="markup3test">
<html:span id="l1" a11yname="test2">test2</html:span>
<html:span id="l2" a11yname="test3">test3</html:span>
<html:select>
@ -164,7 +165,8 @@
</html:select>
</markup>
<markup ref="html:table/html:tr/html:td" ruleset="htmlelm">
<markup ref="html:table/html:tr/html:td" ruleset="htmlelm"
id="markup4test">
<html:span id="l1" a11yname="test2">test2</html:span>
<html:span id="l2" a11yname="test3">test3</html:span>
<html:label for="tc" a11yname="test4">test4</html:label>
@ -184,7 +186,8 @@
</html:table>
</markup>
<markup ref="html:table/html:tr/html:td" ruleset="htmlctrl">
<markup ref="html:table/html:tr/html:td" ruleset="htmlctrl"
id="markup5test">
<html:span id="l1" a11yname="test2">test2</html:span>
<html:span id="l2" a11yname="test3">test3</html:span>
<html:label for="gc" a11yname="test4">test4</html:label>

View File

@ -1,6 +1,7 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>Keyboard shortcuts tests</title>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
@ -27,7 +28,7 @@
function doTest()
{
testKeyboardShortcut("input1", "");
testKeyboardShortcut("input2", "Alt+Shift+b");
testKeyboardShortcut("input2", MAC ? "⌃b" : "Alt+Shift+b");
SimpleTest.finish();
}

View File

@ -279,14 +279,14 @@
label="&historyUndoMenu.label;"
disabled="true">
<menupopup id="appmenu_recentlyClosedTabsMenupopup"
onpopupshowing="document.getElementById('appmenu_historyMenu')._placesView.populateUndoSubmenu();"/>
onpopupshowing="document.getElementById('appmenu_history')._placesView.populateUndoSubmenu();"/>
</menu>
<menu id="appmenu_recentlyClosedWindowsMenu"
class="recentlyClosedWindowsMenu"
label="&historyUndoWindowMenu.label;"
disabled="true">
<menupopup id="appmenu_recentlyClosedWindowsMenupopup"
onpopupshowing="document.getElementById('appmenu_historyMenu')._placesView.populateUndoWindowSubmenu();"/>
onpopupshowing="document.getElementById('appmenu_history')._placesView.populateUndoWindowSubmenu();"/>
</menu>
<menuseparator/>
</menupopup>

View File

@ -230,7 +230,7 @@ var StarUI = {
// Consume dismiss clicks, see bug 400924
this.panel.popupBoxObject
.setConsumeRollupEvent(Ci.nsIPopupBoxObject.ROLLUP_CONSUME);
this.panel.openPopup(aAnchorElement, aPosition, -1, -1);
this.panel.openPopup(aAnchorElement, aPosition);
gEditItemOverlay.initPanel(this._itemId,
{ hiddenRows: ["description", "location",
@ -348,7 +348,8 @@ var PlacesCommandHook = {
if (starIcon && isElementVisible(starIcon)) {
// Make sure the bookmark properties dialog hangs toward the middle of
// the location bar in RTL builds
var position = (getComputedStyle(gNavToolbox, "").direction == "rtl") ? 'after_start' : 'after_end';
var position = (getComputedStyle(gNavToolbox, "").direction == "rtl") ?
'bottomcenter topleft' : 'bottomcenter topright';
if (aShowEditUI)
StarUI.showEditBookmarkPopup(itemId, starIcon, position);
return;
@ -845,11 +846,11 @@ var PlacesMenuDNDHandler = {
},
/**
* Handles dragleave on the <menu> element.
* Handles dragexit on the <menu> element.
* @returns true if the element is a container element (menu or
* menu-toolbarbutton), false otherwise.
*/
onDragLeave: function PMDH_onDragLeave(event) {
onDragExit: function PMDH_onDragExit(event) {
// Closing menus in a Places popup is handled by the view itself.
if (!this._isStaticContainer(event.target))
return;

View File

@ -248,5 +248,12 @@ let TabView = {
});
}
}, true);
},
// ----------
// Prepares the tab view for undo close tab.
prepareUndoCloseTab: function() {
if (this._window)
this._window.UI.restoredClosedTab = true;
}
};

View File

@ -1228,6 +1228,9 @@ function BrowserStartup() {
BookmarksMenuButton.init();
// initialize the private browsing UI
gPrivateBrowsingUI.init();
setTimeout(delayedStartup, 0, isLoadingBlank, mustLoadSidebar);
}
@ -1513,9 +1516,6 @@ function delayedStartup(isLoadingBlank, mustLoadSidebar) {
placesContext.addEventListener("popuphiding", updateEditUIVisibility, false);
#endif
// initialize the private browsing UI
gPrivateBrowsingUI.init();
gBrowser.mPanelContainer.addEventListener("InstallBrowserTheme", LightWeightThemeWebInstaller, false, true);
gBrowser.mPanelContainer.addEventListener("PreviewBrowserTheme", LightWeightThemeWebInstaller, false, true);
gBrowser.mPanelContainer.addEventListener("ResetBrowserThemePreview", LightWeightThemeWebInstaller, false, true);
@ -2885,7 +2885,7 @@ var homeButtonObserver = {
browserDragAndDrop.dragOver(aEvent, "droponhomebutton");
aEvent.dropEffect = "link";
},
onDragLeave: function (aEvent)
onDragExit: function (aEvent)
{
XULWindowBrowser.setStatusText("");
}
@ -2928,7 +2928,7 @@ var bookmarksButtonObserver = {
aEvent.dropEffect = "link";
},
onDragLeave: function (aEvent)
onDragExit: function (aEvent)
{
XULWindowBrowser.setStatusText("");
}
@ -2940,7 +2940,7 @@ var newTabButtonObserver = {
browserDragAndDrop.dragOver(aEvent, "droponnewtabbutton");
},
onDragLeave: function (aEvent)
onDragExit: function (aEvent)
{
XULWindowBrowser.setStatusText("");
},
@ -2962,7 +2962,7 @@ var newWindowButtonObserver = {
{
browserDragAndDrop.dragOver(aEvent, "droponnewwindowbutton");
},
onDragLeave: function (aEvent)
onDragExit: function (aEvent)
{
XULWindowBrowser.setStatusText("");
},
@ -2989,7 +2989,7 @@ var DownloadsButtonDNDObserver = {
aEvent.preventDefault();
},
onDragLeave: function (aEvent)
onDragExit: function (aEvent)
{
XULWindowBrowser.setStatusText("");
},
@ -6784,6 +6784,7 @@ function undoCloseTab(aIndex) {
var ss = Cc["@mozilla.org/browser/sessionstore;1"].
getService(Ci.nsISessionStore);
if (ss.getClosedTabCount(window) > (aIndex || 0)) {
TabView.prepareUndoCloseTab();
tab = ss.undoCloseTab(window, aIndex || 0);
if (blankTabToRemove)
@ -7264,7 +7265,7 @@ var gIdentityHandler = {
// Make sure the identity popup hangs toward the middle of the location bar
// in RTL builds
var position = (getComputedStyle(gNavToolbox, "").direction == "rtl") ? 'after_end' : 'after_start';
var position = (getComputedStyle(gNavToolbox, "").direction == "rtl") ? 'bottomcenter topright' : 'bottomcenter topleft';
// Add the "open" attribute to the identity box for styling
this._identityBox.setAttribute("open", "true");
@ -7495,11 +7496,8 @@ let gPrivateBrowsingUI = {
}
else if (aTopic == "private-browsing-transition-complete") {
if (this._disableUIOnToggle) {
// use setTimeout here in order to make the code testable
setTimeout(function() {
document.getElementById("Tools:PrivateBrowsing")
.removeAttribute("disabled");
}, 0);
document.getElementById("Tools:PrivateBrowsing")
.removeAttribute("disabled");
}
}
},

View File

@ -174,6 +174,7 @@
</panel>
<panel id="editBookmarkPanel"
type="arrow"
orient="vertical"
ignorekeys="true"
hidden="true"
@ -334,10 +335,13 @@
<menupopup id="placesContext"/>
<panel id="notification-popup" type="arrow" position="after_start"
noautofocus="true" hidden="true" orient="vertical"/>
hidden="true" orient="vertical"/>
<!-- Popup for site identity information -->
<panel id="identity-popup" position="after_start" hidden="true" noautofocus="true"
<panel id="identity-popup"
type="arrow"
hidden="true"
noautofocus="true"
onpopupshown="document.getElementById('identity-popup-more-info-button').focus();"
level="top">
<hbox id="identity-popup-container" align="top">
@ -515,7 +519,7 @@
ondragover="homeButtonObserver.onDragOver(event)"
ondragenter="homeButtonObserver.onDragOver(event)"
ondrop="homeButtonObserver.onDrop(event)"
ondragleave="homeButtonObserver.onDragLeave(event)"
ondragexit="homeButtonObserver.onDragExit(event)"
onclick="BrowserGoHome(event);"
aboutHomeOverrideTooltip="&abouthome.pageTitle;"/>
@ -625,7 +629,7 @@
tooltiptext="&bookmarksMenuButton.tooltip;"
ondragenter="PlacesMenuDNDHandler.onDragEnter(event);"
ondragover="PlacesMenuDNDHandler.onDragOver(event);"
ondragleave="PlacesMenuDNDHandler.onDragLeave(event);"
ondragexit="PlacesMenuDNDHandler.onDragExit(event);"
ondrop="PlacesMenuDNDHandler.onDrop(event);">
<menupopup id="BMB_bookmarksPopup"
placespopup="true"
@ -814,7 +818,7 @@
ondrop="newTabButtonObserver.onDrop(event)"
ondragover="newTabButtonObserver.onDragOver(event)"
ondragenter="newTabButtonObserver.onDragOver(event)"
ondragleave="newTabButtonObserver.onDragLeave(event)"
ondragexit="newTabButtonObserver.onDragExit(event)"
removable="true"/>
<toolbarbutton id="alltabs-button"
@ -861,7 +865,7 @@
ondrop="DownloadsButtonDNDObserver.onDrop(event)"
ondragover="DownloadsButtonDNDObserver.onDragOver(event)"
ondragenter="DownloadsButtonDNDObserver.onDragOver(event)"
ondragleave="DownloadsButtonDNDObserver.onDragLeave(event)"
ondragexit="DownloadsButtonDNDObserver.onDragExit(event)"
label="&downloads.label;"
tooltiptext="&downloads.tooltip;"/>
@ -875,7 +879,7 @@
ondrop="bookmarksButtonObserver.onDrop(event)"
ondragover="bookmarksButtonObserver.onDragOver(event)"
ondragenter="bookmarksButtonObserver.onDragOver(event)"
ondragleave="bookmarksButtonObserver.onDragLeave(event)"/>
ondragexit="bookmarksButtonObserver.onDragExit(event)"/>
<toolbarbutton id="new-window-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
label="&newNavigatorCmd.label;"
@ -884,7 +888,7 @@
ondrop="newWindowButtonObserver.onDrop(event)"
ondragover="newWindowButtonObserver.onDragOver(event)"
ondragenter="newWindowButtonObserver.onDragOver(event)"
ondragleave="newWindowButtonObserver.onDragLeave(event)"/>
ondragexit="newWindowButtonObserver.onDragExit(event)"/>
<toolbarbutton id="cut-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
label="&cutCmd.label;"

View File

@ -1425,13 +1425,13 @@ XPCOMUtils.defineLazyGetter(InspectorUI, "strings", function () {
XPCOMUtils.defineLazyGetter(InspectorUI, "PropertyTreeView", function () {
var obj = {};
Cu.import("resource://gre/modules/PropertyPanel.jsm", obj);
Cu.import("resource:///modules/PropertyPanel.jsm", obj);
return obj.PropertyTreeView;
});
XPCOMUtils.defineLazyGetter(InspectorUI, "PropertyPanel", function () {
var obj = {};
Cu.import("resource://gre/modules/PropertyPanel.jsm", obj);
Cu.import("resource:///modules/PropertyPanel.jsm", obj);
return obj.PropertyPanel;
});

View File

@ -3298,7 +3298,7 @@
event.stopPropagation();
]]></handler>
<handler event="dragleave"><![CDATA[
<handler event="dragexit"><![CDATA[
this._dragTime = 0;
// This does not work at all (see bug 458613)

View File

@ -324,7 +324,8 @@ SearchEventHandlerClass.prototype = {
init: function () {
var self = this;
iQ("#searchbox")[0].focus();
iQ("#search").hide().click(function(event) {
iQ("#search").hide();
iQ("#searchshade").hide().click(function(event) {
if ( event.target.id != "searchbox")
hideSearch();
});
@ -364,6 +365,7 @@ SearchEventHandlerClass.prototype = {
// Function: inSearchKeyHandler
// Handles all keypresses while search mode.
inSearchKeyHandler: function (event) {
let term = iQ("#searchbox").val();
if ((event.keyCode == event.DOM_VK_ESCAPE) ||
(event.keyCode == event.DOM_VK_BACK_SPACE && term.length <= 1)) {
hideSearch(event);
@ -462,6 +464,7 @@ var TabHandlers = {
_hideHandler: function(event){
iQ("#search").fadeOut();
iQ("#searchshade").fadeOut();
TabHandlers._mouseDownLocation = {x:event.clientX, y:event.clientY};
},
@ -475,6 +478,7 @@ var TabHandlers = {
return;
}
iQ("#searchshade").show();
iQ("#search").show();
iQ("#searchbox")[0].focus();
// Marshal the search.
@ -490,6 +494,7 @@ function createSearchTabMacher() {
function hideSearch(event){
iQ("#searchbox").val("");
iQ("#searchshade").hide();
iQ("#search").hide();
iQ("#searchbutton").css({ opacity:.8 });
@ -528,10 +533,12 @@ function performSearch() {
function ensureSearchShown(event){
var $search = iQ("#search");
var $searchShade = iQ("#searchshade");
var $searchbox = iQ("#searchbox");
iQ("#searchbutton").css({ opacity: 1 });
if (!isSearchEnabled()) {
$searchShade.show();
$search.show();
var mainWindow = gWindow.document.getElementById("main-window");
mainWindow.setAttribute("activetitlebarcolor", "#717171");
@ -544,7 +551,6 @@ function ensureSearchShown(event){
setTimeout(function focusSearch() {
$searchbox[0].focus();
$searchbox[0].val = '0';
$searchbox.css({"z-index":"1015"});
if (event != null)
$searchbox.val(String.fromCharCode(event.charCode));
@ -563,5 +569,4 @@ var SearchEventHandler = new SearchEventHandlerClass();
// Features to add:
// (1) Make sure this looks good on Windows. Bug 594429
// (2) Make sure that we don't put the matched tab over the search box. Bug 594433
// (3) Group all of the highlighted tabs into a group? Bug 594434
// (2) Group all of the highlighted tabs into a group? Bug 594434

View File

@ -199,11 +199,19 @@ body {
/* Search
----------------------------------*/
#searchshade{
position: absolute;
top: 0px;
left: 0px;
z-index: 1000;
}
#search{
position: absolute;
top: 0px;
left: 0px;
z-index: 1000;
pointer-events: none;
z-index: 1050;
}
html[dir=rtl] #search {
@ -215,7 +223,6 @@ html[dir=rtl] #search {
position: absolute;
right: 20px;
top: 20px;
z-index: 1050;
}
html[dir=rtl] #searchbox {

View File

@ -10,13 +10,15 @@
<body transparent="true">
<div id="content">
<div id="bg">
</div>
<input id="exit-button" type="image" alt="" groups="0" />
<div id="actions">
<input id="searchbutton" type="button"/>
</div>
<div id="bg" />
</div>
</div>
<div id="searchshade"></div>
<div id="search">
<input id="searchbox" type="text"/>
<div id="otherresults">

View File

@ -65,6 +65,10 @@ let UI = {
// If true, a select tab has just been closed in TabView.
_closedSelectedTabInTabView : false,
// Variable: restoredClosedTab
// If true, a closed tab has just been restored.
restoredClosedTab : false,
// Variable: _reorderTabItemsOnShow
// Keeps track of the <GroupItem>s which their tab items' tabs have been moved
// and re-orders the tab items when switching to TabView.
@ -169,7 +173,6 @@ let UI = {
this._addTabActionHandlers();
// ___ Storage
GroupItems.pauseArrange();
GroupItems.init();
@ -710,14 +713,25 @@ let UI = {
// if the last visible tab has just been closed, don't show the chrome UI.
if (this.isTabViewVisible() &&
(this._closedLastVisibleTab || this._closedSelectedTabInTabView)) {
(this._closedLastVisibleTab || this._closedSelectedTabInTabView ||
this.restoredClosedTab)) {
if (this.restoredClosedTab) {
// when the tab view UI is being displayed, update the thumb for the
// restored closed tab after the page load
tab.linkedBrowser.addEventListener("load", function (event) {
tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
TabItems._update(tab);
}, true);
}
this._closedLastVisibleTab = false;
this._closedSelectedTabInTabView = false;
this.restoredClosedTab = false;
return;
}
// reset these vars, just in case.
this._closedLastVisibleTab = false;
this._closedSelectedTabInTabView = false;
this.restoredClosedTab = false;
// if TabView is visible but we didn't just close the last tab or
// selected tab, show chrome.
@ -734,7 +748,7 @@ let UI = {
if (currentTab && currentTab.tabItem)
oldItem = currentTab.tabItem;
// update the tab bar for the new tab's group
if (tab && tab.tabItem) {
newItem = tab.tabItem;
@ -1193,16 +1207,51 @@ let UI = {
}
if (!zoomedIn) {
let unhiddenGroups = GroupItems.groupItems.filter(function(groupItem) {
return (!groupItem.hidden && groupItem.getChildren().length > 0);
});
// no visible groups, no orphaned tabs and no apps tabs, open a new group
// with a blank tab
if (unhiddenGroups.length == 0 && GroupItems.getOrphanedTabs().length == 0 &&
gBrowser._numPinnedTabs == 0) {
let box = new Rect(20, 20, 250, 200);
let groupItem = new GroupItem([], { bounds: box, immediately: true });
groupItem.newTab();
return;
}
// If there's an active TabItem, zoom into it. If not (for instance when the
// selected tab is an app tab), just go there.
let activeTabItem = this.getActiveTab();
if (!activeTabItem)
activeTabItem = gBrowser.selectedTab.tabItem;
if (!activeTabItem) {
let tabItem = gBrowser.selectedTab.tabItem;
if (tabItem) {
if (!tabItem.parent || !tabItem.parent.hidden) {
activeTabItem = tabItem;
} else { // set active tab item if there is at least one unhidden group
if (unhiddenGroups.length > 0)
activeTabItem = unhiddenGroups[0].getActiveTab();
}
}
}
if (activeTabItem)
if (activeTabItem) {
activeTabItem.zoomIn();
else
self.goToTab(gBrowser.selectedTab);
} else {
if (gBrowser._numPinnedTabs > 0) {
if (gBrowser.selectedTab.pinned) {
self.goToTab(gBrowser.selectedTab);
} else {
Array.some(gBrowser.tabs, function(tab) {
if (tab.pinned) {
self.goToTab(tab);
return true;
}
return false
});
}
}
}
}
},

View File

@ -69,6 +69,8 @@ _BROWSER_FILES = \
browser_tabview_bug599626.js \
browser_tabview_bug600645.js \
browser_tabview_bug606905.js \
browser_tabview_bug608037.js \
browser_tabview_bug608158.js \
browser_tabview_dragdrop.js \
browser_tabview_exit_button.js \
browser_tabview_group.js \

View File

@ -157,19 +157,36 @@ function onTabViewFrameInitialized() {
let contentWindow = restoredWin.document.getElementById("tab-view").contentWindow;
let tabItems = contentWindow.TabItems.getItems();
tabItems.forEach(function(tabItem) {
ok(tabItem.isShowingCachedData(), "Tab item is showing cached data");
});
let nextStep = function() {
// since we are not sure whether the frame is initialized first or two tabs
// compete loading first so we need this.
if (restoredNewTabOneLoaded && restoredNewTabTwoLoaded) {
// executeSoon is used to ensure tabItem.shouldHideCachedData is set
// because tabs progress listener might run at the same time as this test code.
executeSoon(updateAndCheck);
} else
frameInitialized = true;
}
// since we are not sure whether the frame is initialized first or two tabs
// compete loading first so we need this.
if (restoredNewTabOneLoaded && restoredNewTabTwoLoaded) {
// executeSoon is used to ensure tabItem.shouldHideCachedData is set
// because tabs progress listener might run at the same time as this test code.
executeSoon(updateAndCheck);
} else
frameInitialized = true;
let tabItems = contentWindow.TabItems.getItems();
let count = tabItems.length;
tabItems.forEach(function(tabItem) {
// tabitem might not be connected so use subscriber for those which are not
// connected.
if (tabItem.reconnected) {
ok(tabItem.isShowingCachedData(), "Tab item is showing cached data");
count--;
if (count == 0)
nextStep();
} else {
tabItem.addSubscriber(tabItem, "reconnected", function() {
tabItem.removeSubscriber(tabItem, "reconnected");
count--;
if (count == 0)
nextStep();
});
}
});
}
function updateAndCheck() {

View File

@ -0,0 +1,99 @@
/* ***** 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 a test for bug 608037.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Raymond Lee <raymond@appcoast.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 ***** */
let tabOne;
let tabTwo;
function test() {
waitForExplicitFinish();
tabOne = gBrowser.addTab("http://mochi.test:8888/");
tabTwo = gBrowser.addTab("http://mochi.test:8888/browser/browser/base/content/test/tabview/dummy_page.html");
// make sure our tabs are loaded so their titles are right
let stillToLoad = 0;
let onLoad = function(event) {
event.target.removeEventListener("load", onLoad, true);
stillToLoad--;
if (!stillToLoad) {
// show the tab view
window.addEventListener("tabviewshown", onTabViewWindowLoaded, false);
ok(!TabView.isVisible(), "Tab View is hidden");
// make sure the tab one is selected because undoCloseTab() would remove
// the selected tab if it's a blank tab.
gBrowser.selectedTab = tabOne;
TabView.toggle();
}
}
let newTabs = [ tabOne, tabTwo ];
newTabs.forEach(function(tab) {
stillToLoad++;
tab.linkedBrowser.addEventListener("load", onLoad, true);
});
}
function onTabViewWindowLoaded() {
window.removeEventListener("tabviewshown", onTabViewWindowLoaded, false);
let contentWindow = document.getElementById("tab-view").contentWindow;
let groupItems = contentWindow.GroupItems.groupItems;
is(groupItems.length, 1, "There is only one group");
is(groupItems[0].getChildren().length, 3, "The group has three tab items");
gBrowser.removeTab(tabTwo);
ok(TabView.isVisible(), "Tab View is still visible after removing a tab");
is(groupItems[0].getChildren().length, 2, "The group has two tab items");
tabTwo = undoCloseTab(0);
ok(TabView.isVisible(), "Tab View is still visible after restoring a tab");
is(groupItems[0].getChildren().length, 3, "The group has three tab items");
// clean up and finish
let endGame = function() {
window.removeEventListener("tabviewhidden", endGame, false);
gBrowser.removeTab(tabOne);
gBrowser.removeTab(tabTwo);
finish();
}
window.addEventListener("tabviewhidden", endGame, false);
TabView.toggle();
}

View File

@ -1,4 +1,3 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@ -12,15 +11,15 @@
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Mozilla SVG project.
* The Original Code is a test for bug 608158.
*
* The Initial Developer of the Original Code is
* Scooter Morris.
* Portions created by the Initial Developer are Copyright (C) 2004
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Scooter Morris <scootermorris@comcast.net> (original author)
* Raymond Lee <raymond@appcoast.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
@ -36,16 +35,39 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef __NS_SVGANIMATEDNUMBERLIST_H__
#define __NS_SVGANIMATEDNUMBERLIST_H__
function test() {
waitForExplicitFinish();
#include "nsIDOMSVGAnimatedNumberList.h"
#include "nsIDOMSVGNumberList.h"
window.addEventListener("tabviewshown", onTabViewWindowLoaded, false);
TabView.toggle();
}
nsresult
NS_NewSVGAnimatedNumberList(nsIDOMSVGAnimatedNumberList** result,
nsIDOMSVGNumberList* baseVal);
function onTabViewWindowLoaded() {
window.removeEventListener("tabviewshown", onTabViewWindowLoaded, false);
#endif //__NS_SVGANIMATEDNUMBERLIST_H__
let contentWindow = document.getElementById("tab-view").contentWindow;
is(contentWindow.GroupItems.groupItems.length, 1,
"There is one group item on startup");
is(gBrowser.tabs.length, 1, "There is one tab on startup");
let groupItem = contentWindow.GroupItems.groupItems[0];
groupItem.addSubscriber(groupItem, "groupHidden", function() {
groupItem.removeSubscriber(groupItem, "groupHidden");
let onTabViewHidden = function() {
window.removeEventListener("tabviewhidden", onTabViewHidden, false);
is(contentWindow.GroupItems.groupItems.length, 1,
"There is still one group item");
isnot(groupItem, contentWindow.GroupItems.groupItems[0],
"The initial group item is not the same as the final group item");
is(gBrowser.tabs.length, 1, "There is only one tab");
ok(!TabView.isVisible(), "Tab View is hidden");
finish();
};
window.addEventListener("tabviewhidden", onTabViewHidden, false);
TabView.hide();
});
groupItem.closeAll();
}

View File

@ -998,7 +998,7 @@
xbl:inherits="popupid"/>
<xul:vbox>
<xul:description class="popup-notification-description"
xbl:inherits="value=label"/>
xbl:inherits="xbl:text=label"/>
<xul:spacer flex="1"/>
<xul:hbox pack="end">
<xul:label anonid="learnmore" class="text-link geolocation-text-link"/>

View File

@ -819,7 +819,7 @@ function PlacesToolbar(aPlace) {
PlacesToolbar.prototype = {
__proto__: PlacesViewBase.prototype,
_cbEvents: ["dragstart", "dragover", "dragleave", "dragend", "drop",
_cbEvents: ["dragstart", "dragover", "dragexit", "dragend", "drop",
#ifdef XP_UNIX
#ifndef XP_MACOSX
"mousedown", "mouseup",
@ -991,8 +991,8 @@ PlacesToolbar.prototype = {
case "dragover":
this._onDragOver(aEvent);
break;
case "dragleave":
this._onDragLeave(aEvent);
case "dragexit":
this._onDragExit(aEvent);
break;
case "dragend":
this._onDragEnd(aEvent);
@ -1533,7 +1533,7 @@ PlacesToolbar.prototype = {
aEvent.stopPropagation();
},
_onDragLeave: function PT__onDragLeave(aEvent) {
_onDragExit: function PT__onDragExit(aEvent) {
PlacesControllerDragHelper.currentDropTarget = null;
// Set timer to turn off indicator bar (if we turn it off

View File

@ -490,7 +490,7 @@
event.stopPropagation();
]]></handler>
<handler event="dragleave"><![CDATA[
<handler event="dragexit"><![CDATA[
PlacesControllerDragHelper.currentDropTarget = null;
this.removeAttribute("dragover");

View File

@ -48,13 +48,6 @@ function test() {
let pass = 1;
function observer(aSubject, aTopic, aData) {
switch (aTopic) {
case "private-browsing":
setTimeout(function () {
ok(document.getElementById("Tools:PrivateBrowsing").hasAttribute("disabled"),
"The private browsing command should be disabled immediately after the mode switch");
}, 0);
break;
case "private-browsing-transition-complete":
if (pass++ == 1) {
setTimeout(function () {
@ -69,16 +62,31 @@ function test() {
ok(!pbCmd.hasAttribute("disabled"),
"The private browsing command should be re-enabled after exiting the private browsing mode");
Services.obs.removeObserver(observer, "private-browsing");
Services.obs.removeObserver(observer, "private-browsing-transition-complete");
finish();
}, 100);
}
break;
}
Services.obs.removeObserver(observer, "private-browsing-transition-complete");
}
Services.obs.addObserver(observer, "private-browsing", false);
Services.obs.addObserver(observer, "private-browsing-transition-complete", false);
let originalOnEnter = gPrivateBrowsingUI.onEnterPrivateBrowsing;
gPrivateBrowsingUI.onEnterPrivateBrowsing = function() {
originalOnEnter.apply(gPrivateBrowsingUI, arguments);
ok(pbCmd.hasAttribute("disabled"),
"The private browsing command should be disabled right after entering the private browsing mode");
Services.obs.addObserver(observer, "private-browsing-transition-complete", false);
};
let originalOnExit = gPrivateBrowsingUI.onExitPrivateBrowsing;
gPrivateBrowsingUI.onExitPrivateBrowsing = function() {
originalOnExit.apply(gPrivateBrowsingUI, arguments);
ok(pbCmd.hasAttribute("disabled"),
"The private browsing command should be disabled right after exiting the private browsing mode");
Services.obs.addObserver(observer, "private-browsing-transition-complete", false);
};
registerCleanupFunction(function() {
gPrivateBrowsingUI.onEnterPrivateBrowsing = originalOnEnter;
gPrivateBrowsingUI.onExitPrivateBrowsing = originalOnExit;
});
pb.privateBrowsingEnabled = true;
}

View File

@ -47,17 +47,16 @@ function test() {
pb.privateBrowsingEnabled = true;
let win = OpenBrowserWindow();
Services.obs.addObserver(function(subject, topic, data) {
Services.obs.removeObserver(arguments.callee, "browser-delayed-startup-finished");
var notifiedWin = subject.QueryInterface(Ci.nsIDOMWindow);
is(win, notifiedWin, "sanity check");
win.addEventListener("load", function() {
win.removeEventListener("load", arguments.callee, false);
executeSoon(function() {
let cmd = win.document.getElementById("Tools:PrivateBrowsing");
ok(!cmd.hasAttribute("disabled"),
"The Private Browsing command in a new window should be enabled");
let cmd = win.document.getElementById("Tools:PrivateBrowsing");
ok(!cmd.hasAttribute("disabled"),
"The Private Browsing command in a new window should be enabled");
win.close();
pb.privateBrowsingEnabled = false;
finish();
}, "browser-delayed-startup-finished", false);
win.close();
pb.privateBrowsingEnabled = false;
finish();
});
}, false);
}

View File

@ -93,19 +93,14 @@ function test() {
win.addEventListener("load", function() {
win.removeEventListener("load", arguments.callee, false);
// ensure that the test is run after delayedStartup
let _delayedStartup = win.delayedStartup;
win.delayedStartup = function() {
_delayedStartup.apply(win, arguments);
win.delayedStartup = _delayedStartup;
executeSoon(function() {
is(win.document.title, expected_title, "The window title for " + url +
" detached tab is correct (" + (insidePB ? "inside" : "outside") +
" private browsing mode)");
win.close();
setTimeout(funcNext, 0);
};
});
}, false);
});
}, false);

View File

@ -2494,6 +2494,10 @@ SessionStoreService.prototype = {
browser.__SS_data = tabData;
browser.__SS_restoreState = TAB_STATE_NEEDS_RESTORE;
// Make sure that set/getTabValue will set/read the correct data by
// wiping out any current value in tab.__SS_extdata.
delete tab.__SS_extdata;
if (!tabData.entries || tabData.entries.length == 0) {
// make sure to blank out this tab's content
// (just purging the tab's history won't be enough)
@ -2699,15 +2703,23 @@ SessionStoreService.prototype = {
if (tabData.userTypedValue) {
browser.userTypedValue = tabData.userTypedValue;
if (tabData.userTypedClear) {
// Make it so that we'll enter restoreDocument on page load. We will
// fire SSTabRestored from there. We don't have any form data to restore
// so we can just set the URL to null.
browser.__SS_restore_data = { url: null };
browser.__SS_restore_tab = aTab;
didStartLoad = true;
browser.loadURI(tabData.userTypedValue, null, null, true);
}
}
// If we didn't start a load, then we won't reset this tab through the usual
// channel (via the progress listener), so reset the tab ourselves.
if (!didStartLoad)
// channel (via the progress listener), so reset the tab ourselves. We will
// also send SSTabRestored since this tab has technically been restored.
if (!didStartLoad) {
this._sendTabRestoredNotification(aTab);
this._resetTabRestoringState(aTab);
}
return didStartLoad;
},
@ -2962,13 +2974,11 @@ SessionStoreService.prototype = {
var content = aEvent.originalTarget.defaultView;
restoreTextDataAndScrolling(content, aBrowser.__SS_restore_data, "");
aBrowser.markupDocumentViewer.authorStyleDisabled = selectedPageStyle == "_nostyle";
// notify the tabbrowser that this document has been completely restored
var event = aBrowser.ownerDocument.createEvent("Events");
event.initEvent("SSTabRestored", true, false);
aBrowser.__SS_restore_tab.dispatchEvent(event);
}
// notify the tabbrowser that this document has been completely restored
this._sendTabRestoredNotification(aBrowser.__SS_restore_tab);
delete aBrowser.__SS_restore_data;
delete aBrowser.__SS_restore_pageStyle;
delete aBrowser.__SS_restore_tab;
@ -3635,6 +3645,16 @@ SessionStoreService.prototype = {
}
},
/**
* Dispatch the SSTabRestored event for the given tab.
* @param aTab the which has been restored
*/
_sendTabRestoredNotification: function sss__sendTabRestoredNotification(aTab) {
let event = aTab.ownerDocument.createEvent("Events");
event.initEvent("SSTabRestored", true, false);
aTab.dispatchEvent(event);
},
/**
* @param aWindow
* Window reference

View File

@ -98,8 +98,13 @@ function test() {
is(ss.getClosedWindowCount(), closedWindowCount,
"The reopened window was removed from Recently Closed Windows");
// SSTabRestored will fire more than once, so we need to make sure we count them
let restoredTabs = 0;
let expectedTabs = data.tabs.length;
newWin2.addEventListener("load", function(aEvent) {
newWin2.gBrowser.tabContainer.addEventListener("SSTabRestored", function(aEvent) {
if (++restoredTabs < expectedTabs)
return;
newWin2.gBrowser.tabContainer.removeEventListener("SSTabRestored", arguments.callee, true);
is(newWin2.gBrowser.tabs.length, 2,

View File

@ -56,15 +56,13 @@ function test() {
getService(Ci.nsISessionStore);
function waitForBrowserState(aState, aSetStateCallback) {
var locationChanges = 0;
gBrowser.addTabsProgressListener({
onLocationChange: function (aBrowser) {
if (++locationChanges == aState.windows[0].tabs.length) {
gBrowser.removeTabsProgressListener(this);
executeSoon(aSetStateCallback);
}
let tabsRestored = 0;
gBrowser.tabContainer.addEventListener("SSTabRestored", function() {
if (++tabsRestored == aState.windows[0].tabs.length) {
gBrowser.tabContainer.removeEventListener("SSTabRestored", arguments.callee, true);
executeSoon(aSetStateCallback);
}
});
}, true);
ss.setBrowserState(JSON.stringify(aState));
}
@ -285,16 +283,7 @@ function test() {
}]
};
// Set state here and listen for load event because waitForBrowserState
// doesn't guarantee all the tabs have loaded, so the test could continue
// before we're in a testable state. This is important here because of the
// distinction between "http://example.com" and "http://example.com/".
ss.setBrowserState(JSON.stringify(state));
gBrowser.addEventListener("load", function(aEvent) {
if (gBrowser.currentURI.spec == "about:blank")
return;
gBrowser.removeEventListener("load", arguments.callee, true);
waitForBrowserState(state, function() {
let browser = gBrowser.selectedBrowser;
is(browser.currentURI.spec, "http://example.com/",
"userTypedClear=2 caused userTypedValue to be loaded");
@ -305,7 +294,7 @@ function test() {
is(gURLBar.value, "http://example.com/",
"Address bar's value set after loading URI");
runNextTest();
}, true);
});
}

View File

@ -54,6 +54,7 @@ function test() {
// fired for them.
let wasLoaded = { };
let restoringTabsCount = 0;
let restoredTabsCount = 0;
let uniq2 = { };
let uniq2Count = 0;
let state = { windows: [{ tabs: [] }] };
@ -74,6 +75,9 @@ function test() {
let uniq = ss.getTabValue(aEvent.originalTarget, "uniq");
wasLoaded[uniq] = true;
is(ss.getTabValue(aEvent.originalTarget, "foo"), "",
"There is no value for 'foo'");
// On the first SSTabRestoring we're going to run the the real test.
// We'll keep this listener around so we can keep marking tabs as restored.
if (restoringTabsCount == 1)
@ -82,6 +86,19 @@ function test() {
onLastSSTabRestoring();
}
function onSSTabRestored(aEvent) {
if (++restoredTabsCount < NUM_TABS)
return;
cleanup();
}
function onTabOpen(aEvent) {
// To test bug 614708, we'll just set a value on the tab here. This value
// would previously cause us to not recognize the values in extData until
// much later. So testing "uniq" failed.
ss.setTabValue(aEvent.originalTarget, "foo", "bar");
}
// This does the actual testing. SSTabRestoring should be firing on tabs from
// left to right, so we're going to start with the rightmost tab.
function onFirstSSTabRestoring() {
@ -120,12 +137,13 @@ function test() {
}
}
is(checked, uniq2Count, "checked the same number of uniq2 as we set");
cleanup();
}
function cleanup() {
// remove the event listener and clean up before finishing
gBrowser.tabContainer.removeEventListener("SSTabRestoring", onSSTabRestoring, false);
gBrowser.tabContainer.removeEventListener("SSTabRestored", onSSTabRestored, true);
gBrowser.tabContainer.removeEventListener("TabOpen", onTabOpen, false);
// Put this in an executeSoon because we still haven't called restoreNextTab
// in sessionstore for the last tab (we'll call it after this). We end up
// trying to restore the tab (since we then add a closed tab to the array).
@ -135,8 +153,10 @@ function test() {
});
}
// Add the event listener
// Add the event listeners
gBrowser.tabContainer.addEventListener("SSTabRestoring", onSSTabRestoring, false);
gBrowser.tabContainer.addEventListener("SSTabRestored", onSSTabRestored, true);
gBrowser.tabContainer.addEventListener("TabOpen", onTabOpen, false);
// Restore state
ss.setBrowserState(JSON.stringify(state));
}

View File

@ -62,18 +62,18 @@ function testBug600545() {
// Need to wait for all tabs to be restored before reading browser state
function waitForBrowserState(aState, aSetStateCallback) {
let locationChanges = 0;
let tabsRestored = getStateTabCount(aState);
let tabsRestored = 0;
let expectedTabs = getStateTabCount(aState);
// We know that there are only 2 windows total, so just be specific
let newWin;
// Used to determine when tabs have been restored
let progressListener = {
onLocationChange: function (aBrowser) {
if (++locationChanges == tabsRestored) {
// Remove the progress listener from this window, it will be removed from
// theWin when that window is closed (in setBrowserState).
window.gBrowser.removeTabsProgressListener(this);
executeSoon(aSetStateCallback);
}
function onTabRestored(aEvent) {
if (++tabsRestored == expectedTabs) {
gBrowser.tabContainer.removeEventListener("SSTabRestored", onTabRestored, true);
newWin.gBrowser.tabContainer.removeEventListener("SSTabRestored", onTabRestored, true);
executeSoon(aSetStateCallback);
}
}
@ -84,14 +84,17 @@ function testBug600545() {
theWin.addEventListener("load", function() {
theWin.removeEventListener("load", arguments.callee, false);
// So we can remove the event listener in onTabRestored
newWin = theWin;
Services.ww.unregisterNotification(windowObserver);
theWin.gBrowser.addTabsProgressListener(progressListener);
theWin.gBrowser.tabContainer.addEventListener("SSTabRestored", onTabRestored, true);
}, false);
}
}
Services.ww.registerNotification(windowObserver);
window.gBrowser.addTabsProgressListener(progressListener);
gBrowser.tabContainer.addEventListener("SSTabRestored", onTabRestored, true);
ss.setBrowserState(JSON.stringify(aState));
}
@ -150,4 +153,4 @@ function getStateTabCount(aState) {
for (let i in aState.windows)
tabCount += aState.windows[i].tabs.length;
return tabCount;
}
}

View File

@ -404,6 +404,14 @@
@BINPATH@/components/@DLL_PREFIX@mozgnome@DLL_SUFFIX@
#endif
; ANGLE on Win32
#ifdef XP_WIN32
#ifndef HAVE_64BIT_OS
@BINPATH@/libEGL.dll
@BINPATH@/libGLESv2.dll
#endif
#endif
; [Browser Chrome Files]
@BINPATH@/chrome/browser@JAREXT@
@BINPATH@/chrome/browser.manifest

View File

@ -4,6 +4,7 @@ ar
be
bg
bn-BD
bn-IN
br
ca
cs
@ -26,6 +27,7 @@ ga-IE
gd
gu-IN
he
hr
hu
hy-AM
id
@ -40,6 +42,7 @@ lg
lt
lv
mk
ml
nb-NO
nl
nn-NO
@ -54,9 +57,12 @@ ro
ru
si
sk
sl
son
sq
sv-SE
ta-LK
te
th
tr
uk

View File

@ -542,10 +542,15 @@ html[dir=rtl] #exit-button {
/* Search
----------------------------------*/
#search{
#searchshade{
background-color: rgba(0,0,0,.42);
width: 100%;
height: 100%;
height: 100%;
}
#search{
width: 100%;
height: 100%;
}
#searchbox{

View File

@ -1049,33 +1049,16 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
list-style-image: url("chrome://browser/skin/places/unstarred48.png");
}
#editBookmarkPanel {
-moz-appearance: none;
-moz-window-shadow: none;
-moz-border-image: url(chrome://browser/skin/hud-panel.png) 26 50 22 18 / 26px 50px 22px 18px repeat;
margin-right: -27px;
margin-top: 1px;
padding-top: 8px;
color: #ffffff;
background-color: transparent;
}
#editBookmarkPanelTitle {
font-size: 130%;
font-weight: bold;
}
#editBookmarkPanelContent,
#editBookmarkPanelBottomButtons {
margin-right: -30px;
}
/**** HUD style buttons ****/
.editBookmarkPanelHeaderButton,
.editBookmarkPanelBottomButton {
@hudButton@
padding: 0 9px;
margin: 6px;
min-width: 79px;
min-height: 22px;
@ -1083,14 +1066,12 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
.editBookmarkPanelHeaderButton:hover:active,
.editBookmarkPanelBottomButton:hover:active {
background-color: #86888B;
@hudButtonPressed@
}
.editBookmarkPanelHeaderButton:focus,
.editBookmarkPanelBottomButton:focus {
outline: 2px solid -moz-mac-focusring;
outline-offset: -2px;
-moz-outline-radius: 10000px;
.editBookmarkPanelHeaderButton:-moz-focusring,
.editBookmarkPanelBottomButton:-moz-focusring {
@hudButtonFocused@
}
.editBookmarkPanelBottomButton[default="true"] {
@ -1107,13 +1088,15 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
editBookmarkOverlay.css. */
#editBMPanel_newFolderBox {
background-image: url("chrome://browser/skin/hud-style-new-folder-bar-background.png");
background-repeat: repeat-x;
border: 0;
border-width: 1px 0 1px 0;
border-style: solid;
border-top-color: #212121;
border-bottom-color: #212121;
background-image: -moz-linear-gradient(rgb(90,90,90), rgb(40,40,40));
background-origin: padding-box;
background-clip: padding-box;
border-radius: 0 0 3px 3px;
border: 1px solid rgba(0,0,0,.3);
border-top: none;
box-shadow: inset 0 -1px 2px rgba(0,0,0,.2),
inset 0 1px 0 rgba(255,255,255,.15),
0 1px 0 rgba(255,255,255,.15);
padding: 0;
margin-left: 4px;
margin-right: 4px;
@ -1127,25 +1110,27 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
border: 0;
-moz-border-end-width: 3px;
border-style: solid;
-moz-border-right-colors: rgba(255,255,255,0.15) rgba(0,0,0,0.5) rgba(255,255,255,0.15);
-moz-border-left-colors: rgba(255,255,255,0.15) rgba(0,0,0,0.5) rgba(255,255,255,0.15);
-moz-border-right-colors: rgba(255,255,255,.1) rgba(0,0,0,.5) rgba(255,255,255,.1);
-moz-border-left-colors: rgba(255,255,255,.1) rgba(0,0,0,.5) rgba(255,255,255,.1);
padding: 0 9px;
margin: 0;
min-width: 21px;
min-height: 20px;
height: 20px;
color: #ffffff;
color: #fff;
list-style-image: url("chrome://browser/skin/hud-style-new-folder-plus-sign.png") !important;
position: relative;
}
#editBMPanel_newFolderButton:hover:active {
background-color: #86888B;
background: -moz-linear-gradient(rgba(40,40,40,.9), rgba(70,70,70,.9));
box-shadow: inset 0 0 3px rgba(0,0,0,.2), inset 0 1px 7px rgba(0,0,0,.4);
}
#editBMPanel_newFolderButton:focus {
outline: 2px solid -moz-mac-focusring;
outline-offset: -2px;
-moz-outline-radius: 1px;
#editBMPanel_newFolderButton:-moz-focusring {
box-shadow: 0 0 1px -moz-mac-focusring inset,
0 0 4px 1px -moz-mac-focusring,
0 0 2px 1px -moz-mac-focusring;
}
#editBMPanel_newFolderButton .button-text {
@ -1154,21 +1139,19 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
#editBMPanel_folderMenuList {
@hudButton@
border-radius: 5px;
margin: 0 3px !important;
border-radius: 3px;
min-height: 22px;
-moz-padding-start: 2px;
-moz-padding-start: 4px;
-moz-padding-end: 0;
}
#editBMPanel_folderMenuList:focus {
outline: 2px solid -moz-mac-focusring;
outline-offset: -2px;
-moz-outline-radius: 5px;
#editBMPanel_folderMenuList:-moz-focusring {
@hudButtonFocused@
}
#editBMPanel_folderMenuList[open="true"],
#editBMPanel_folderMenuList:hover:active {
background-image: url("chrome://browser/skin/hud-style-button-middle-background-active.png");
@hudButtonPressed@
}
#editBMPanel_folderMenuList > .menulist-dropmarker {
@ -1188,18 +1171,20 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
#editBMPanel_folderTree {
-moz-appearance: none;
background-color: #333333;
border-top: 2px solid;
-moz-border-top-colors: rgba(0,0,0,0.35) rgba(255,255,255,0.15);
color: #ffffff;
border-radius: 2px 2px 0 0;
background-color: rgba(50,50,50,.9);
border: 1px solid rgba(0,0,0,.3);
border-bottom: none;
box-shadow: inset 0 1px 2px rgba(0,0,0,.15);
color: #fff;
/* Implements editBookmarkPanel resizing on folderTree un-collapse. */
min-width: 27em;
position: relative;
}
#editBMPanel_folderTree:focus {
outline: 2px solid -moz-mac-focusring;
outline-offset: -1px;
-moz-outline-radius: 1px;
#editBMPanel_folderTree:-moz-focusring {
box-shadow: 0 0 4px 1px -moz-mac-focusring,
0 0 2px 1px -moz-mac-focusring;
}
#editBMPanel_folderTree > treechildren::-moz-tree-twisty {
@ -1224,20 +1209,19 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
#editBMPanel_tagsSelector {
-moz-appearance: none;
background-color: #333333;
border-top: 2px solid !important;
border-right: 0 !important;
border-bottom: 2px solid !important;
border-left: 0 !important;
-moz-border-top-colors: rgba(0,0,0,0.35) rgba(255,255,255,0.15);
-moz-border-bottom-colors: rgba(255,255,255,0.30) rgba(0,0,0,0.35) ;
color: #ffffff !important;
border-radius: 2px;
background-color: rgba(50,50,50,1);
border: 1px solid rgba(0,0,0,.3);
border-bottom: none;
box-shadow: inset 0 1px 2px rgba(0,0,0,.15),
0 1px 0 rgba(255,255,255,.15);
color: #fff;
}
#editBMPanel_tagsSelector:focus {
outline: 2px solid -moz-mac-focusring;
outline-offset: -2px;
-moz-outline-radius: 1px;
#editBMPanel_tagsSelector:-moz-focusring {
box-shadow: 0 0 1px -moz-mac-focusring inset,
0 0 4px 1px -moz-mac-focusring,
0 0 2px 1px -moz-mac-focusring;
}
#editBMPanel_tagsSelector .listcell-check {
@ -1254,7 +1238,7 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
}
#editBMPanel_folderTree treechildren::-moz-tree-row {
color: #ffffff !important;
color: #fff !important;
background-color: transparent !important;
border: none !important;
}
@ -1282,57 +1266,49 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
#editBookmarkPanel .expander-up,
#editBookmarkPanel .expander-down {
@hudButton@
border-radius: 5px;
border-radius: 3px;
-moz-margin-start: 4px;
-moz-margin-end: 2px;
padding: 0;
-moz-padding-start: 4px;
min-width: 10px;
min-height: 22px;
min-height: 20px;
}
#editBookmarkPanel .expander-up:focus,
#editBookmarkPanel .expander-down:focus {
outline: 2px solid -moz-mac-focusring;
outline-offset: -2px;
-moz-outline-radius: 5px;
#editBookmarkPanel .expander-up:-moz-focusring,
#editBookmarkPanel .expander-down:-moz-focusring {
@hudButtonFocused@
}
#editBookmarkPanel .expander-up {
list-style-image: url("chrome://browser/skin/hud-style-expander-open.png") !important;
}
#editBookmarkPanel .expander-down {
list-style-image: url("chrome://browser/skin/hud-style-expander-closed.png") !important;
#editBookmarkPanel .expander-up:hover:active,
#editBookmarkPanel .expander-down:hover:active {
@hudButtonPressed@
}
#editBookmarkPanel .expander-up,
#editBookmarkPanel .expander-down:hover:active {
list-style-image: url("chrome://browser/skin/hud-style-expander-open.png") !important;
background-image: url("chrome://browser/skin/hud-style-button-middle-background-active.png") !important;
background-repeat: repeat-x !important;
}
#editBookmarkPanel .expander-down,
#editBookmarkPanel .expander-up:hover:active {
list-style-image: url("chrome://browser/skin/hud-style-expander-closed.png") !important;
background-image: url("chrome://browser/skin/hud-style-button-middle-background-active.png") !important;
background-repeat: repeat-x !important;
}
/**** name picker ****/
#editBMPanel_tagsField,
#editBMPanel_namePicker[droppable="false"] > .menulist-editable-box {
-moz-appearance: none !important;
margin: 2px 4px !important;
border: 2px solid !important;
-moz-border-top-colors: #1c1c1c #545454 !important;
-moz-border-right-colors: #1c1c1c #636363 !important;
-moz-border-bottom-colors: #1c1c1c #797979 !important;
-moz-border-left-colors: #1c1c1c #636363 !important;
border-radius: 1px !important;
-moz-padding-start: 3px !important;
margin: 2px !important;
border: 1px solid rgba(0,0,0,.5) !important;
box-shadow: inset 0 1px 0 rgba(0,0,0,.3);
background-color: #666 !important;
background-clip: padding-box;
background-origin: padding-box;
color: #fff !important;
min-height: 20px;
}
#editBMPanel_namePicker[droppable="false"] > .menulist-editable-box > html|*.menulist-editable-input {
@ -1345,9 +1321,9 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
#editBMPanel_tagsField[focused="true"],
#editBMPanel_namePicker[droppable="false"][focused="true"] > .menulist-editable-box {
outline: 2px solid -moz-mac-focusring;
outline-offset: -1px;
-moz-outline-radius: 1px;
box-shadow: 0 0 1px -moz-mac-focusring inset,
0 0 4px 1px -moz-mac-focusring,
0 0 2px 1px -moz-mac-focusring;
background-color: #eee !important;
color: #000 !important;
}
@ -1978,7 +1954,6 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
/* Popup Body Text */
.identity-popup-description {
white-space: pre-wrap;
color: #ffffff;
-moz-padding-start: 15px;
margin: 2px 0 4px;
}
@ -2020,22 +1995,6 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
list-style-image: url("chrome://browser/skin/Secure-Glyph-White.png");
}
/* Popup Bounding Box */
#identity-popup {
-moz-appearance: none;
-moz-window-shadow: none;
background-color: transparent;
margin-top: -3px;
margin-left: -23px;
min-width: 280px;
-moz-border-image: url(chrome://browser/skin/hud-panel.png) 26 18 22 50 / 26px 18px 22px 50px repeat;
}
#notification-popup {
margin-left: -16px;
margin-right: -16px;
}
#notification-popup-box {
margin: 0 3px;
}
@ -2100,35 +2059,19 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
list-style-image: url(chrome://mozapps/skin/passwordmgr/key-64.png);
}
#identity-popup-container,
#identity-popup-notification-container {
margin: 4px 3px 2px -30px;
color: #fff;
}
#identity-popup-content-box {
margin-top: 4px;
}
#identity-popup.verifiedDomain,
#identity-popup.verifiedIdentity {
margin-left: -20px;
}
/* Popup Buttons */
#identity-popup-more-info-button {
@hudButton@
padding: 1px 9px;
margin: 10px 0 0;
min-height: 0px;
}
#identity-popup-more-info-button > .button-box > .button-text {
margin: 0 !important;
#identity-popup-more-info-button:focus {
@hudButtonFocused@
}
#identity-popup-more-info-button:hover:active {
background-color: #86888B;
@hudButtonPressed@
}
#download-monitor {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 137 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 163 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 148 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 B

View File

@ -18,16 +18,11 @@ browser.jar:
skin/classic/browser/Geolocation-64.png
skin/classic/browser/Go-arrow.png
skin/classic/browser/home.png
skin/classic/browser/hud-panel.png
skin/classic/browser/hud-style-button-middle-background.png
skin/classic/browser/hud-style-check-box-checked.png
skin/classic/browser/hud-style-check-box-empty.png
skin/classic/browser/hud-style-dropmarker-double-arrows.png
skin/classic/browser/hud-style-expander-closed.png
skin/classic/browser/hud-style-expander-open.png
skin/classic/browser/hud-style-new-folder-bar-background-active.png
skin/classic/browser/hud-style-new-folder-bar-background.gif
skin/classic/browser/hud-style-new-folder-bar-background.png
skin/classic/browser/hud-style-new-folder-plus-sign.png
skin/classic/browser/hud-style-twisties.png
skin/classic/browser/identity.png

View File

@ -1,4 +1,6 @@
%include ../../../../toolkit/themes/pinstripe/global/shared.inc
%include ../../browserShared.inc
%define hudButton -moz-appearance: none; background: url("chrome://browser/skin/hud-style-button-middle-background.png") repeat-x #464646 center center; border: 3px solid; -moz-border-top-colors: rgba(0,0,0,0.35) rgba(26,26,26,0.5) rgba(255,255,255,0.4); -moz-border-right-colors: rgba(53,53,53,1) rgba(53,53,53,1) rgba(162,162,162,1); -moz-border-bottom-colors: rgba(128,128,128,0.35) rgba(0,0,0,0.5) rgba(255,255,255,0.15); -moz-border-left-colors: rgba(0,0,0,0.35) rgba(26,26,26,0.5) rgba(255,255,255,0.4); border-radius: 20px; color: #fff;
%define hudButton -moz-appearance: none; color: #fff; text-shadow: 0 -1px 0 rgba(0,0,0,.5); border-radius: 12px; border: 1px solid rgba(0,0,0,.65); background: -moz-linear-gradient(rgba(110,110,110,.9), rgba(70,70,70,.9) 49%, rgba(50,50,50,.9) 51%, rgba(40,40,40,.9)); box-shadow: inset 0 1px 0 rgba(255,255,255,.2), inset 0 0 1px rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1); background-clip: padding-box; background-origin: padding-box; padding: 2px 9px;
%define hudButtonPressed background: -moz-linear-gradient(rgba(40,40,40,.9), rgba(70,70,70,.9)); box-shadow: inset 0 0 3px rgba(0,0,0,.2), inset 0 1px 7px rgba(0,0,0,.4), 0 1px 0 rgba(255,255,255,.1);
%define hudButtonFocused box-shadow: 0 0 1px -moz-mac-focusring inset, 0 0 4px 1px -moz-mac-focusring, 0 0 2px 1px -moz-mac-focusring;

View File

@ -534,12 +534,17 @@ html[dir=rtl] #exit-button {
/* Search
----------------------------------*/
#search {
#searchshade{
background-color: rgba(0,0,0,.42);
width: 100%;
height: 100%;
}
#search{
width: 100%;
height: 100%;
}
#searchbox {
width: 270px;
height: 30px;

View File

@ -45,21 +45,6 @@
-moz-margin-start: 1px;
}
/* Bug 413060, comment 16: Vista Aero is a special case where we use a
tooltip appearance for the address bar popup panels */
#identity-popup,
#editBookmarkPanel {
-moz-appearance: tooltip;
color: InfoText;
}
/* Make the left and right paddings smaller, to compensate for the horizontal
space added by the tooltip appearance, see bug 432529. */
#identity-popup-container {
-moz-padding-start: 6px;
-moz-padding-end: 6px;
}
#sidebar-splitter {
border: 0;
-moz-border-end: 1px solid #A9B7C9;

View File

@ -1366,13 +1366,6 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
}
/* bookmarking panel */
#editBookmarkPanel {
-moz-appearance: menupopup;
color: MenuText;
padding: 4px;
}
#editBookmarkPanelStarIcon {
list-style-image: url("chrome://browser/skin/places/starred48.png");
width: 48px;
@ -1853,17 +1846,6 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
-moz-margin-end: 0;
}
/* Popup Bounding Box */
#identity-popup {
-moz-appearance: menupopup;
color: MenuText;
}
/* Notification popup */
#notification-popup {
padding: 10px;
}
.popup-notification-icon {
width: 64px;
height: 64px;
@ -1930,7 +1912,6 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
#identity-popup-container {
min-width: 280px;
padding: 9px;
}
#download-monitor {

View File

@ -561,10 +561,15 @@ html[dir=rtl] #exit-button {
/* Search
----------------------------------*/
#search{
#searchshade{
background-color: rgba(0,0,0,.42);
width: 100%;
height: 100%;
height: 100%;
}
#search{
width: 100%;
height: 100%;
}
#searchbox{

View File

@ -47,6 +47,7 @@ import sys
import shutil
from datetime import datetime
from automation import Automation
from automationutils import getDebuggerInfo, addCommonOptions
PORT = 8888
SCRIPT_DIR = os.path.abspath(os.path.realpath(os.path.dirname(sys.argv[0])))
@ -58,7 +59,17 @@ class EasyServer(SocketServer.TCPServer):
allow_reuse_address = True
if __name__ == '__main__':
from optparse import OptionParser
automation = Automation()
parser = OptionParser()
addCommonOptions(parser)
options, args = parser.parse_args()
debuggerInfo = getDebuggerInfo(".", options.debugger, options.debuggerArgs,
options.debuggerInteractive)
httpd = EasyServer(("", PORT), SimpleHTTPServer.SimpleHTTPRequestHandler)
t = threading.Thread(target=httpd.serve_forever)
t.setDaemon(True) # don't hang on exit
@ -73,6 +84,7 @@ if __name__ == '__main__':
url = "http://localhost:%d/index.html" % PORT
appPath = os.path.join(SCRIPT_DIR, automation.DEFAULT_APP)
status = automation.runApp(url, browserEnv, appPath, PROFILE_DIRECTORY, {},
debuggerInfo=debuggerInfo,
# the profiling HTML doesn't output anything,
# so let's just run this without a timeout
timeout = None)

View File

@ -177,6 +177,8 @@ MOZ_HELP_VIEWER = @MOZ_HELP_VIEWER@
MOC= @MOC@
MOZ_NSS_PATCH = @MOZ_NSS_PATCH@
MOZ_WEBGL = @MOZ_WEBGL@
MOZ_ANGLE = @MOZ_ANGLE@
MOZ_DIRECTX_SDK_PATH = @MOZ_DIRECTX_SDK_PATH@
MOZ_JAVAXPCOM = @MOZ_JAVAXPCOM@
JAVA_INCLUDE_PATH="@JAVA_INCLUDE_PATH@"
@ -592,6 +594,8 @@ export CL_INCLUDES_PREFIX = @CL_INCLUDES_PREFIX@
MOZ_AUTO_DEPS = @MOZ_AUTO_DEPS@
COMPILER_DEPEND = @COMPILER_DEPEND@
MDDEPDIR := @MDDEPDIR@
CC_WRAPPER = @CC_WRAPPER@
CXX_WRAPPER = @CXX_WRAPPER@
MOZ_DEMANGLE_SYMBOLS = @MOZ_DEMANGLE_SYMBOLS@

View File

@ -170,19 +170,6 @@ endif
endif
endif
ifndef NO_CXX_WRAPPER
ifdef _MSC_VER
ifndef .PYMAKE
CC_WRAPPER = $(PYTHON) -O $(topsrcdir)/build/cl.py
CXX_WRAPPER = $(PYTHON) -O $(topsrcdir)/build/cl.py
else
PYCOMMANDPATH += $(topsrcdir)/build
CC_WRAPPER = %cl InvokeClWithDependencyGeneration
CXX_WRAPPER = %cl InvokeClWithDependencyGeneration
endif # .PYMAKE
endif # _MSC_VER
endif # NO_CXX_WRAPPER
CC := $(CC_WRAPPER) $(CC)
CXX := $(CXX_WRAPPER) $(CXX)

View File

@ -144,6 +144,8 @@ endif
# Testing frameworks support
################################################################################
testxpcobjdir = $(DEPTH)/_tests/xpcshell
ifdef ENABLE_TESTS
ifdef XPCSHELL_TESTS
@ -151,8 +153,6 @@ ifndef relativesrcdir
$(error Must define relativesrcdir when defining XPCSHELL_TESTS.)
endif
testxpcobjdir = $(DEPTH)/_tests/xpcshell
# Test file installation
ifneq (,$(filter WINNT os2-emx,$(HOST_OS_ARCH)))
# Windows and OS/2 nsinstall can't recursively copy directories, so use nsinstall.py

View File

@ -796,7 +796,7 @@ EOF
AC_LANG_RESTORE
])
if test "$ac_cv_have_std__Throw" == "yes"; then
if test "$ac_cv_have_std__Throw" = "yes"; then
AC_CACHE_CHECK(for |class __declspec(dllimport) exception| bug,
ac_cv_have_dllimport_exception_bug,
[
@ -1049,7 +1049,7 @@ from building Mozilla. Upgrade to Xcode 2.1 or later.])
changequote(,)
XCODEBUILD_VERSION=`$PBBUILD -version 2>/dev/null | xargs | sed -e 's/.*DevToolsCore-\([0-9]*\).*/\1/'`
changequote([,])
if test -n "$XCODEBUILD_VERSION" -a "$XCODEBUILD_VERSION" -ge 620 ; then
if test -n "$XCODEBUILD_VERSION" && test "$XCODEBUILD_VERSION" -ge 620 ; then
HAS_XCODE_2_1=1;
fi
;;
@ -3812,7 +3812,7 @@ fi
dnl check for wcrtomb/mbrtowc
dnl =======================================================================
if test -z "$MACOS_DEPLOYMENT_TARGET" -o "$MACOS_DEPLOYMENT_TARGET" -ge "100300"; then
if test -z "$MACOS_DEPLOYMENT_TARGET" || test "$MACOS_DEPLOYMENT_TARGET" -ge "100300"; then
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_CACHE_CHECK(for wcrtomb,
@ -6314,6 +6314,51 @@ if test -n "${MOZ_JAVAXPCOM}"; then
fi
fi
dnl ========================================================
dnl = ANGLE OpenGL->D3D translator for WebGL
dnl = * only applies to win32
dnl = * enabled by default (shipping build); requires explicit --disable to disable
dnl ========================================================
MOZ_ANGLE=
MOZ_DIRECTX_SDK_PATH=
case "$target_os" in
*msvc*|*mks*|*cygwin*|*mingw*)
MOZ_ANGLE=1
;;
esac
if test -n "$MOZ_ANGLE"; then
MOZ_ARG_DISABLE_BOOL(angle,
[ --disable-angle Disable building of ANGLE for WebGL->D3D translation],
MOZ_ANGLE=,
MOZ_ANGLE=1)
if test -n "$MOZ_ANGLE"; then
if test -z "$_WIN32_MSVC"; then
AC_MSG_ERROR([Building ANGLE requires MSVC. To build without ANGLE, reconfigure with --disable-angle.])
fi
AC_CHECK_HEADER(d3dx9.h, [], [MOZ_ANGLE=])
if test -z "$MOZ_ANGLE"; then
# Try again, but try to get the SDK path from the registry. We're going to hardcode
# the February 2010 SDK, since that's the one that's installed on the tinderboxen.
MOZ_DIRECTX_SDK_PATH=`reg query 'HKLM\Software\Microsoft\DirectX\Microsoft DirectX SDK (February 2010)' //v InstallPath | grep REG_SZ | sed 's, *, ,g' | cut -d' ' -f4`
if test -n "$MOZ_DIRECTX_SDK_PATH" ; then
if test -f "$MOZ_DIRECTX_SDK_PATH"/include/d3dx9.h && test -f "$MOZ_DIRECTX_SDK_PATH"/lib/x86/dxguid.lib ; then
AC_MSG_WARN([Found DirectX SDK in registry, using $MOZ_DIRECTX_SDK])
MOZ_ANGLE=1
fi
fi
fi
if test -z "$MOZ_ANGLE"; then
AC_MSG_WARN([Couldn't find d3dx9.h in your INCLUDE path, needed for ANGLE. Please install the February 2010 DirectX SDK, or make another version available in your LIB and INCLUDE path env variables. To explicitly build without ANGLE, reconfigure with --disable-angle.])
AC_MSG_WARN([This will become an error in the future.])
fi
fi
fi
dnl ========================================================
dnl = Breakpad crash reporting (on by default on supported platforms)
dnl ========================================================
@ -6557,14 +6602,14 @@ if test -n "$MOZ_INSTALLER" -a "$OS_ARCH" = "WINNT"; then
changequote(,)
MAKENSISU_VER=`"$MAKENSISU" -version 2>/dev/null | sed -e '/-Unicode/!s/.*//g' -e 's/^v\([0-9]\+\.[0-9]\+\)\-Unicode$/\1/g'`
changequote([,])
if test ! "$MAKENSISU_VER" == ""; then
if test ! "$MAKENSISU_VER" = ""; then
MAKENSISU_MAJOR_VER=`echo $MAKENSISU_VER | $AWK -F\. '{ print $1 }'`
MAKENSISU_MINOR_VER=`echo $MAKENSISU_VER | $AWK -F\. '{ print $2 }'`
fi
AC_MSG_CHECKING([for Unicode NSIS with major version == $REQ_NSIS_MAJOR_VER and minor version >= $MIN_NSIS_MINOR_VER])
if test "$MAKENSISU_VER" == "" -o \
! "$MAKENSISU_MAJOR_VER" == "$REQ_NSIS_MAJOR_VER" -o \
! "$MAKENSISU_MINOR_VER" -ge $MIN_NSIS_MINOR_VER; then
if test "$MAKENSISU_VER" = "" ||
test ! "$MAKENSISU_MAJOR_VER" = "$REQ_NSIS_MAJOR_VER" -o \
! "$MAKENSISU_MINOR_VER" -ge $MIN_NSIS_MINOR_VER; then
AC_MSG_RESULT([no])
AC_MSG_ERROR([To build the installer you must have the latest MozillaBuild or Unicode NSIS with a major version of $REQ_NSIS_MAJOR_VER and a minimum minor version of $MIN_NSIS_MINOR_VER in your path. To build without the installer reconfigure using --disable-installer.])
fi
@ -8156,7 +8201,10 @@ else
fi
AC_SUBST(CL_INCLUDES_PREFIX)
rm -f dummy-hello.c
_topsrcdirwin=`cd \`dirname $0\`; pwd -W`
dnl cl.py provides dependency generation for MSVC
CC_WRAPPER="$PYTHON -O $_topsrcdirwin/build/cl.py"
CXX_WRAPPER="$PYTHON -O $_topsrcdirwin/build/cl.py"
COMPILER_DEPEND=1
fi
fi
@ -8165,6 +8213,9 @@ MDDEPDIR='.deps'
AC_SUBST(MOZ_AUTO_DEPS)
AC_SUBST(COMPILER_DEPEND)
AC_SUBST(MDDEPDIR)
AC_SUBST(CC_WRAPPER)
AC_SUBST(CXX_WRAPPER)
dnl ========================================================
dnl =
@ -8920,6 +8971,8 @@ AC_SUBST(MOZ_SPELLCHECK)
AC_SUBST(MOZ_USER_DIR)
AC_SUBST(MOZ_CRASHREPORTER)
AC_SUBST(MOZ_UPDATER)
AC_SUBST(MOZ_ANGLE)
AC_SUBST(MOZ_DIRECTX_SDK_PATH)
AC_SUBST(ENABLE_STRIP)
AC_SUBST(PKG_SKIP_STRIP)

View File

@ -1512,6 +1512,8 @@ public:
static void ASCIIToUpper(nsAString& aStr);
static void ASCIIToUpper(const nsAString& aSource, nsAString& aDest);
// Returns NS_OK for same origin, error (NS_ERROR_DOM_BAD_URI) if not.
static nsresult CheckSameOrigin(nsIChannel *aOldChannel, nsIChannel *aNewChannel);
static nsIInterfaceRequestor* GetSameOriginChecker();
static nsIThreadJSContextStack* ThreadJSContextStack()

View File

@ -73,10 +73,10 @@ public:
NS_DEFINE_STATIC_IID_ACCESSOR(nsIContentUtils, NS_ICONTENTUTILS_IID)
// {60083ad4-f7ed-488b-a706-bacb378fe1a5}
// {c7193287-3e3d-467f-b6da-47b914eb4c83}
#define NS_ICONTENTUTILS2_IID \
{ 0x60083ad4, 0xf7ed, 0x488b, \
{ 0xa7, 0x06, 0xba, 0xcb, 0x37, 0x8f, 0xe1, 0xa5 } }
{ 0xc7193287, 0x3e3d, 0x467f, \
{ 0xb6, 0xda, 0x47, 0xb9, 0x14, 0xeb, 0x4c, 0x83 } }
class nsIContentUtils2 : public nsISupports
{
@ -85,6 +85,8 @@ public:
NS_DECL_ISUPPORTS
virtual nsIInterfaceRequestor* GetSameOriginChecker();
// Returns NS_OK for same origin, error (NS_ERROR_DOM_BAD_URI) if not.
virtual nsresult CheckSameOrigin(nsIChannel *aOldChannel, nsIChannel *aNewChannel);
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIContentUtils2, NS_ICONTENTUTILS2_IID)

View File

@ -445,9 +445,8 @@ nsAttrValue::ToString(nsAString& aResult) const
#endif
case eFloatValue:
{
nsAutoString str;
str.AppendFloat(GetFloatValue());
aResult = str;
aResult.Truncate();
aResult.AppendFloat(GetFloatValue());
break;
}
default:

View File

@ -5193,18 +5193,10 @@ nsContentUtils::GetSameOriginChecker()
return sSameOriginChecker;
}
NS_IMPL_ISUPPORTS2(nsSameOriginChecker,
nsIChannelEventSink,
nsIInterfaceRequestor)
NS_IMETHODIMP
nsSameOriginChecker::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
nsIChannel *aNewChannel,
PRUint32 aFlags,
nsIAsyncVerifyRedirectCallback *cb)
/* static */
nsresult
nsContentUtils::CheckSameOrigin(nsIChannel *aOldChannel, nsIChannel *aNewChannel)
{
NS_PRECONDITION(aNewChannel, "Redirecting to null channel?");
if (!nsContentUtils::GetSecurityManager())
return NS_ERROR_NOT_AVAILABLE;
@ -5224,11 +5216,27 @@ nsSameOriginChecker::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
rv = oldPrincipal->CheckMayLoad(newOriginalURI, PR_FALSE);
}
if (NS_FAILED(rv))
return rv;
return rv;
}
cb->OnRedirectVerifyCallback(NS_OK);
return NS_OK;
NS_IMPL_ISUPPORTS2(nsSameOriginChecker,
nsIChannelEventSink,
nsIInterfaceRequestor)
NS_IMETHODIMP
nsSameOriginChecker::AsyncOnChannelRedirect(nsIChannel *aOldChannel,
nsIChannel *aNewChannel,
PRUint32 aFlags,
nsIAsyncVerifyRedirectCallback *cb)
{
NS_PRECONDITION(aNewChannel, "Redirecting to null channel?");
nsresult rv = nsContentUtils::CheckSameOrigin(aOldChannel, aNewChannel);
if (NS_SUCCEEDED(rv)) {
cb->OnRedirectVerifyCallback(NS_OK);
}
return rv;
}
NS_IMETHODIMP
@ -6499,3 +6507,9 @@ nsIContentUtils2::GetSameOriginChecker()
{
return nsContentUtils::GetSameOriginChecker();
}
nsresult
nsIContentUtils2::CheckSameOrigin(nsIChannel *aOldChannel, nsIChannel *aNewChannel)
{
return nsContentUtils::CheckSameOrigin(aOldChannel, aNewChannel);
}

View File

@ -4351,7 +4351,18 @@ nsDocument::CreateElementNS(const nsAString& aNamespaceURI,
nsIDOMElement** aReturn)
{
*aReturn = nsnull;
nsCOMPtr<nsIContent> content;
nsresult rv = CreateElementNS(aNamespaceURI, aQualifiedName,
getter_AddRefs(content));
NS_ENSURE_SUCCESS(rv, rv);
return CallQueryInterface(content, aReturn);
}
nsresult
nsDocument::CreateElementNS(const nsAString& aNamespaceURI,
const nsAString& aQualifiedName,
nsIContent** aReturn)
{
nsCOMPtr<nsINodeInfo> nodeInfo;
nsresult rv = nsContentUtils::GetNodeInfoFromQName(aNamespaceURI,
aQualifiedName,
@ -4359,13 +4370,9 @@ nsDocument::CreateElementNS(const nsAString& aNamespaceURI,
getter_AddRefs(nodeInfo));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIContent> content;
PRInt32 ns = nodeInfo->NamespaceID();
rv = NS_NewElement(getter_AddRefs(content), ns, nodeInfo.forget(),
NOT_FROM_PARSER);
NS_ENSURE_SUCCESS(rv, rv);
return CallQueryInterface(content, aReturn);
return NS_NewElement(aReturn, ns,
nodeInfo.forget(), NOT_FROM_PARSER);
}
NS_IMETHODIMP
@ -6075,16 +6082,15 @@ nsDocument::AdoptNode(nsIDOMNode *aAdoptedNode, nsIDOMNode **aResult)
PRBool sameDocument = oldDocument == this;
JSContext *cx = nsnull;
JSObject *oldScope = adoptedNode->GetWrapper();
JSObject *newScope = nsnull;
if (oldScope && !sameDocument) {
if (!sameDocument) {
rv = nsContentUtils::GetContextAndScope(oldDocument, this, &cx, &newScope);
NS_ENSURE_SUCCESS(rv, rv);
}
nsCOMArray<nsINode> nodesWithProperties;
rv = nsNodeUtils::Adopt(adoptedNode, sameDocument ? nsnull : mNodeInfoManager,
cx, oldScope, newScope, nodesWithProperties);
cx, newScope, nodesWithProperties);
if (NS_FAILED(rv)) {
// Disconnect all nodes from their parents, since some have the old document
// as their ownerDocument and some have this as their ownerDocument.

View File

@ -859,6 +859,9 @@ public:
nsresult CreateElement(const nsAString& aTagName,
nsIContent** aReturn);
nsresult CreateElementNS(const nsAString& aNamespaceURI,
const nsAString& aQualifiedName,
nsIContent** aReturn);
nsresult CreateTextNode(const nsAString& aData, nsIContent** aReturn);

View File

@ -4006,14 +4006,12 @@ nsINode::ReplaceOrInsertBefore(PRBool aReplace, nsINode* aNewChild,
return NS_ERROR_NULL_POINTER;
}
if (IsNodeOfType(eDATA_NODE)) {
if (!IsNodeOfType(eDOCUMENT) &&
!IsNodeOfType(eDOCUMENT_FRAGMENT) &&
!IsElement()) {
return NS_ERROR_DOM_HIERARCHY_REQUEST_ERR;
}
if (IsNodeOfType(eATTRIBUTE)) {
return NS_ERROR_NOT_IMPLEMENTED;
}
nsIContent* refContent;
nsresult res = NS_OK;
PRInt32 insPos;

View File

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 sw=2 et tw=99: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@ -64,6 +65,7 @@
#include "nsImageLoadingContent.h"
#include "jsobj.h"
#include "jsgc.h"
#include "xpcpublic.h"
using namespace mozilla::dom;
@ -442,15 +444,14 @@ nsNodeUtils::CloneNodeImpl(nsINode *aNode, PRBool aDeep, nsIDOMNode **aResult)
nsresult
nsNodeUtils::CloneAndAdopt(nsINode *aNode, PRBool aClone, PRBool aDeep,
nsNodeInfoManager *aNewNodeInfoManager,
JSContext *aCx, JSObject *aOldScope,
JSObject *aNewScope,
JSContext *aCx, JSObject *aNewScope,
nsCOMArray<nsINode> &aNodesWithProperties,
nsINode *aParent, nsINode **aResult)
{
NS_PRECONDITION((!aClone && aNewNodeInfoManager) || !aCx,
"If cloning or not getting a new nodeinfo we shouldn't "
"rewrap");
NS_PRECONDITION(!aCx || (aOldScope && aNewScope), "Must have scopes");
NS_PRECONDITION(!aCx || aNewScope, "Must have new scope");
NS_PRECONDITION(!aParent || aNode->IsNodeOfType(nsINode::eCONTENT),
"Can't insert document or attribute nodes into a parent");
@ -461,6 +462,12 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, PRBool aClone, PRBool aDeep,
// attributes and children).
nsresult rv;
JSObject *wrapper;
if (aCx && (wrapper = aNode->GetWrapper())) {
rv = xpc_MorphSlimWrapper(aCx, aNode);
NS_ENSURE_SUCCESS(rv, rv);
}
nsNodeInfoManager *nodeInfoManager = aNewNodeInfoManager;
// aNode.
@ -516,11 +523,6 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, PRBool aClone, PRBool aDeep,
}
}
else if (nodeInfoManager) {
// FIXME Bug 601803 Need to support adopting a node cross-compartment
if (aCx && aOldScope->compartment() != aNewScope->compartment()) {
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
}
nsIDocument* oldDoc = aNode->GetOwnerDoc();
PRBool wasRegistered = PR_FALSE;
if (oldDoc && aNode->IsElement()) {
@ -580,12 +582,29 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, PRBool aClone, PRBool aDeep,
elem->RecompileScriptEventListeners();
}
if (aCx) {
if (aCx && wrapper) {
nsIXPConnect *xpc = nsContentUtils::XPConnect();
if (xpc) {
JSObject *preservedWrapper = nsnull;
// If reparenting moves us to a new compartment, preserving causes
// problems. In that case, we release ourselves and re-preserve after
// reparenting so we're sure to have the right JS object preserved.
// We use a JSObject stack copy of the wrapper to protect it from GC
// under ReparentWrappedNativeIfFound.
if (aNode->PreservingWrapper()) {
preservedWrapper = wrapper;
nsContentUtils::ReleaseWrapper(aNode, aNode);
}
nsCOMPtr<nsIXPConnectJSObjectHolder> oldWrapper;
rv = xpc->ReparentWrappedNativeIfFound(aCx, aOldScope, aNewScope, aNode,
rv = xpc->ReparentWrappedNativeIfFound(aCx, wrapper, aNewScope, aNode,
getter_AddRefs(oldWrapper));
if (preservedWrapper) {
nsContentUtils::PreserveWrapper(aNode, aNode);
}
if (NS_FAILED(rv)) {
aNode->mNodeInfo.swap(nodeInfo);
@ -627,8 +646,8 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, PRBool aClone, PRBool aDeep,
for (i = 0; i < length; ++i) {
nsCOMPtr<nsINode> child;
rv = CloneAndAdopt(aNode->GetChildAt(i), aClone, PR_TRUE, nodeInfoManager,
aCx, aOldScope, aNewScope, aNodesWithProperties,
clone, getter_AddRefs(child));
aCx, aNewScope, aNodesWithProperties, clone,
getter_AddRefs(child));
NS_ENSURE_SUCCESS(rv, rv);
}
}

View File

@ -172,7 +172,7 @@ public:
nsIDOMNode **aResult)
{
return CloneAndAdopt(aNode, PR_TRUE, aDeep, aNewNodeInfoManager, nsnull,
nsnull, nsnull, aNodesWithProperties, aResult);
nsnull, aNodesWithProperties, aResult);
}
/**
@ -190,18 +190,16 @@ public:
* @param aCx Context to use for reparenting the wrappers, or null if no
* reparenting should be done. Must be null if aNewNodeInfoManager
* is null.
* @param aOldScope Old scope for the wrappers. May be null if aCx is null.
* @param aNewScope New scope for the wrappers. May be null if aCx is null.
* @param aNodesWithProperties All nodes (from amongst aNode and its
* descendants) with properties.
*/
static nsresult Adopt(nsINode *aNode, nsNodeInfoManager *aNewNodeInfoManager,
JSContext *aCx, JSObject *aOldScope,
JSObject *aNewScope,
JSContext *aCx, JSObject *aNewScope,
nsCOMArray<nsINode> &aNodesWithProperties)
{
nsresult rv = CloneAndAdopt(aNode, PR_FALSE, PR_TRUE, aNewNodeInfoManager,
aCx, aOldScope, aNewScope, aNodesWithProperties,
aCx, aNewScope, aNodesWithProperties,
nsnull);
nsMutationGuard::DidMutate();
@ -277,7 +275,6 @@ private:
* @param aCx Context to use for reparenting the wrappers, or null if no
* reparenting should be done. Must be null if aClone is PR_TRUE or
* if aNewNodeInfoManager is null.
* @param aOldScope Old scope for the wrappers. May be null if aCx is null.
* @param aNewScope New scope for the wrappers. May be null if aCx is null.
* @param aNodesWithProperties All nodes (from amongst aNode and its
* descendants) with properties. If aClone is
@ -288,8 +285,7 @@ private:
*/
static nsresult CloneAndAdopt(nsINode *aNode, PRBool aClone, PRBool aDeep,
nsNodeInfoManager *aNewNodeInfoManager,
JSContext *aCx, JSObject *aOldScope,
JSObject *aNewScope,
JSContext *aCx, JSObject *aNewScope,
nsCOMArray<nsINode> &aNodesWithProperties,
nsIDOMNode **aResult)
{
@ -299,7 +295,7 @@ private:
nsCOMPtr<nsINode> clone;
nsresult rv = CloneAndAdopt(aNode, aClone, aDeep, aNewNodeInfoManager,
aCx, aOldScope, aNewScope, aNodesWithProperties,
aCx, aNewScope, aNodesWithProperties,
nsnull, getter_AddRefs(clone));
NS_ENSURE_SUCCESS(rv, rv);
@ -317,8 +313,7 @@ private:
*/
static nsresult CloneAndAdopt(nsINode *aNode, PRBool aClone, PRBool aDeep,
nsNodeInfoManager *aNewNodeInfoManager,
JSContext *aCx, JSObject *aOldScope,
JSObject *aNewScope,
JSContext *aCx, JSObject *aNewScope,
nsCOMArray<nsINode> &aNodesWithProperties,
nsINode *aParent, nsINode **aResult);
};

View File

@ -238,7 +238,7 @@ nsTextNode::List(FILE* out, PRInt32 aIndent) const
for (index = aIndent; --index >= 0; ) fputs(" ", out);
fprintf(out, "Text@%p", static_cast<const void*>(this));
fprintf(out, " intrinsicstate=[%11x]", IntrinsicState().GetInternalValue());
fprintf(out, " intrinsicstate=[%llx]", IntrinsicState().GetInternalValue());
fprintf(out, " flags=[%08x]", static_cast<unsigned int>(GetFlags()));
fprintf(out, " primaryframe=%p", static_cast<void*>(GetPrimaryFrame()));
fprintf(out, " refcount=%d<", mRefCnt.get());

View File

@ -1321,8 +1321,6 @@ nsXMLHttpRequest::GetStatusText(nsACString& aStatusText)
aStatusText.Truncate();
nsresult rv = NS_OK;
if (httpChannel) {
if (mState & XML_HTTP_REQUEST_USE_XSITE_AC) {
// Make sure we don't leak status information from denied cross-site

View File

@ -421,6 +421,7 @@ _TEST_FILES2 = \
file_x-frame-options_main.html \
file_x-frame-options_page.sjs \
test_createHTMLDocument.html \
test_bug564047.html \
test_bug567350.html \
test_bug574596.html \
test_bug578096.html \

View File

@ -0,0 +1,31 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=564047
-->
<head>
<title>Test for Bug 564047</title>
<script type="application/javascript" src="/MochiKit/packed.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=564047">Mozilla Bug 564047</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 564047 **/
try {
document.doctype.appendChild(document.createTextNode("test"));
ok(false, "Should have thrown an exception");
} catch (e) {
ok(e instanceof DOMException, "Should be a DOMException");
is(e.code, DOMException.HIERARCHY_REQUEST_ERR);
}
</script>
</pre>
</body>
</html>

View File

@ -22,7 +22,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=601803
SimpleTest.waitForExplicitFinish();
window.onmessage = function (event) {
todo(event.data == "false", "Shouldn't throw when adopting a node cross-compartment");
is(event.data, "false", "Shouldn't throw when adopting a node cross-compartment");
SimpleTest.finish();
}

View File

@ -332,6 +332,23 @@ nsIDOMCanvasRenderingContext2D_PutImageData(JSContext *cx, uintN argc, jsval *vp
uint32 w = (uint32) wi;
uint32 h = (uint32) hi;
// the optional dirty rect
PRBool hasDirtyRect = PR_FALSE;
int32 dirtyX = 0,
dirtyY = 0,
dirtyWidth = w,
dirtyHeight = h;
if (argc >= 7) {
if (!JS_ValueToECMAInt32(cx, argv[3], &dirtyX) ||
!JS_ValueToECMAInt32(cx, argv[4], &dirtyY) ||
!JS_ValueToECMAInt32(cx, argv[5], &dirtyWidth) ||
!JS_ValueToECMAInt32(cx, argv[6], &dirtyHeight))
return JS_FALSE;
hasDirtyRect = PR_TRUE;
}
if (!JS_GetProperty(cx, dataObject, "data", tv.jsval_addr()) ||
JSVAL_IS_PRIMITIVE(tv.jsval_value()))
return JS_FALSE;
@ -358,7 +375,7 @@ nsIDOMCanvasRenderingContext2D_PutImageData(JSContext *cx, uintN argc, jsval *vp
}
// make the call
rv = self->PutImageData_explicit(x, y, w, h, (PRUint8*) tsrc->data, tsrc->byteLength);
rv = self->PutImageData_explicit(x, y, w, h, (PRUint8*) tsrc->data, tsrc->byteLength, hasDirtyRect, dirtyX, dirtyY, dirtyWidth, dirtyHeight);
if (NS_FAILED(rv))
return xpc_qsThrowMethodFailed(cx, rv, vp);

View File

@ -74,22 +74,16 @@ CPPSRCS += \
WebGLContextValidate.cpp \
$(NULL)
# We can't build ANGLE on linux-64 until build bug 560894 and related
# We can't build ANGLE on linux until build bug 560894 and related
# are fixed.
ifneq ($(OS_ARCH)_$(OS_TEST),Linux_x86_64)
ifneq ($(OS_ARCH),Linux)
DEFINES += -DUSE_ANGLE
USE_ANGLE=1
else
ifdef FORCE_BUILD_ANGLE
DEFINES += -DUSE_ANGLE
USE_ANGLE=1
endif
ifndef MOZ_ENABLE_LIBXUL
ifdef USE_ANGLE
SHARED_LIBRARY_LIBS += \
$(DEPTH)/gfx/angle/$(LIB_PREFIX)angle.$(LIB_SUFFIX) \
$(NULL)
endif
endif
else

View File

@ -316,12 +316,14 @@ WebGLContext::SetContextOptions(nsIPropertyBag *aOptions)
// enforce that if stencil is specified, we also give back depth
newOpts.depth |= newOpts.stencil;
#if 0
LogMessage("aaHint: %d stencil: %d depth: %d alpha: %d premult: %d\n",
newOpts.antialiasHint ? 1 : 0,
newOpts.stencil ? 1 : 0,
newOpts.depth ? 1 : 0,
newOpts.alpha ? 1 : 0,
newOpts.premultipliedAlpha ? 1 : 0);
#endif
if (mOptionsFrozen && newOpts != mOptions) {
// Error if the options are already frozen, and the ones that were asked for
@ -398,8 +400,14 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
// Get some prefs for some preferred/overriden things
PRBool forceOSMesa = PR_FALSE;
PRBool preferEGL = PR_FALSE;
PRBool preferOpenGL = PR_FALSE;
prefService->GetBoolPref("webgl.force_osmesa", &forceOSMesa);
prefService->GetBoolPref("webgl.prefer_egl", &preferEGL);
prefService->GetBoolPref("webgl.prefer_gl", &preferOpenGL);
if (PR_GetEnv("MOZ_WEBGL_PREFER_EGL")) {
preferEGL = PR_TRUE;
}
// Ask GfxInfo about what we should use
PRBool useOpenGL = PR_TRUE;
@ -424,6 +432,13 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
}
}
// allow forcing GL and not EGL/ANGLE
if (PR_GetEnv("MOZ_WEBGL_FORCE_OPENGL")) {
preferEGL = PR_FALSE;
useANGLE = PR_FALSE;
useOpenGL = PR_TRUE;
}
// if we're forcing osmesa, do it first
if (forceOSMesa) {
gl = gl::GLContextProviderOSMesa::CreateOffscreen(gfxIntSize(width, height), format);
@ -435,24 +450,8 @@ WebGLContext::SetDimensions(PRInt32 width, PRInt32 height)
}
#ifdef XP_WIN
// On Windows, we may have a choice of backends, including straight
// OpenGL, D3D through ANGLE via EGL, or straight EGL/GLES2.
// We don't differentiate the latter two yet, but we allow for
// a env var to try EGL first, instead of last; there's also a pref,
// the env var being set overrides the pref
if (PR_GetEnv("MOZ_WEBGL_PREFER_EGL")) {
preferEGL = PR_TRUE;
}
// force opengl instead of EGL/ANGLE
if (PR_GetEnv("MOZ_WEBGL_FORCE_OPENGL")) {
preferEGL = PR_FALSE;
useANGLE = PR_FALSE;
useOpenGL = PR_TRUE;
}
// if we want EGL, try it first
if (!gl && (preferEGL || useANGLE)) {
// if we want EGL, try it now
if (!gl && (preferEGL || useANGLE) && !preferOpenGL) {
gl = gl::GLContextProviderEGL::CreateOffscreen(gfxIntSize(width, height), format);
if (gl && !InitAndValidateGL()) {
gl = nsnull;

View File

@ -2695,7 +2695,7 @@ WebGLContext::RenderbufferStorage(WebGLenum target, WebGLenum internalformat, We
internalformatForGL = LOCAL_GL_DEPTH24_STENCIL8;
break;
default:
ErrorInvalidEnumInfo("renderbufferStorage: internalformat", internalformat);
return ErrorInvalidEnumInfo("renderbufferStorage: internalformat", internalformat);
}
gl->fRenderbufferStorage(target, internalformatForGL, width, height);

View File

@ -948,9 +948,7 @@ nsCanvasRenderingContext2D::StyleColorToString(const nscolor& aColor, nsAString&
NS_GET_G(aColor),
NS_GET_B(aColor)),
aStr);
nsString tmp;
tmp.AppendFloat(nsStyleUtil::ColorComponentToFloat(NS_GET_A(aColor)));
aStr.Append(tmp);
aStr.AppendFloat(nsStyleUtil::ColorComponentToFloat(NS_GET_A(aColor)));
aStr.Append(')');
}
}
@ -2801,9 +2799,11 @@ nsCanvasRenderingContext2D::DrawOrMeasureText(const nsAString& aRawText,
gfxContextPathAutoSaveRestore pathSR(mThebes, PR_FALSE);
// back up path if stroking
if (aOp == nsCanvasRenderingContext2D::TEXT_DRAW_OPERATION_STROKE)
// back up and clear path if stroking
if (aOp == nsCanvasRenderingContext2D::TEXT_DRAW_OPERATION_STROKE) {
pathSR.Save();
mThebes->NewPath();
}
// doUseIntermediateSurface is mutually exclusive to op == STROKE
else {
if (doUseIntermediateSurface) {
@ -3884,7 +3884,9 @@ nsCanvasRenderingContext2D::PutImageData()
NS_IMETHODIMP
nsCanvasRenderingContext2D::PutImageData_explicit(PRInt32 x, PRInt32 y, PRUint32 w, PRUint32 h,
unsigned char *aData, PRUint32 aDataLen)
unsigned char *aData, PRUint32 aDataLen,
PRBool hasDirtyRect, PRInt32 dirtyX, PRInt32 dirtyY,
PRInt32 dirtyWidth, PRInt32 dirtyHeight)
{
if (!mValid)
return NS_ERROR_FAILURE;
@ -3892,8 +3894,49 @@ nsCanvasRenderingContext2D::PutImageData_explicit(PRInt32 x, PRInt32 y, PRUint32
if (w == 0 || h == 0)
return NS_ERROR_DOM_SYNTAX_ERR;
if (!CanvasUtils::CheckSaneSubrectSize (x, y, w, h, mWidth, mHeight))
return NS_ERROR_DOM_SYNTAX_ERR;
gfxRect dirtyRect;
gfxRect imageDataRect(0, 0, w, h);
if (hasDirtyRect) {
// fix up negative dimensions
if (dirtyWidth < 0) {
NS_ENSURE_TRUE(dirtyWidth != INT_MIN, NS_ERROR_DOM_INDEX_SIZE_ERR);
CheckedInt32 checkedDirtyX = CheckedInt32(dirtyX) + dirtyWidth;
if (!checkedDirtyX.valid())
return NS_ERROR_DOM_INDEX_SIZE_ERR;
dirtyX = checkedDirtyX.value();
dirtyWidth = -(int32)dirtyWidth;
}
if (dirtyHeight < 0) {
NS_ENSURE_TRUE(dirtyHeight != INT_MIN, NS_ERROR_DOM_INDEX_SIZE_ERR);
CheckedInt32 checkedDirtyY = CheckedInt32(dirtyY) + dirtyHeight;
if (!checkedDirtyY.valid())
return NS_ERROR_DOM_INDEX_SIZE_ERR;
dirtyY = checkedDirtyY.value();
dirtyHeight = -(int32)dirtyHeight;
}
// bound the dirty rect within the imageData rectangle
dirtyRect = imageDataRect.Intersect(gfxRect(dirtyX, dirtyY, dirtyWidth, dirtyHeight));
if (dirtyRect.Width() <= 0 || dirtyRect.Height() <= 0)
return NS_OK;
} else {
dirtyRect = imageDataRect;
}
dirtyRect.MoveBy(gfxPoint(x, y));
dirtyRect = gfxRect(0, 0, mWidth, mHeight).Intersect(dirtyRect);
if (dirtyRect.Width() <= 0 || dirtyRect.Height() <= 0)
return NS_OK;
PRUint32 len = w * h * 4;
if (aDataLen != len)
@ -3939,14 +3982,13 @@ nsCanvasRenderingContext2D::PutImageData_explicit(PRInt32 x, PRInt32 y, PRUint32
mThebes->ResetClip();
mThebes->IdentityMatrix();
mThebes->Translate(gfxPoint(x, y));
mThebes->NewPath();
mThebes->Rectangle(gfxRect(0, 0, w, h));
mThebes->SetSource(imgsurf, gfxPoint(0, 0));
mThebes->Rectangle(dirtyRect);
mThebes->SetSource(imgsurf, gfxPoint(x, y));
mThebes->SetOperator(gfxContext::OPERATOR_SOURCE);
mThebes->Fill();
return Redraw(gfxRect(x, y, w, h));
return Redraw(dirtyRect);
}
NS_IMETHODIMP

View File

@ -8411,7 +8411,7 @@ isPixel(ctx, 50,45, 0,255,0,255, 2);
} catch (e) {
_thrown_outer = true;
}
todo(!_thrown_outer, 'should not throw exception');
ok(!_thrown_outer, 'should not throw exception');
}
@ -8457,7 +8457,7 @@ isPixel(ctx, 1,45, 0,255,0,255, 2);
} catch (e) {
_thrown_outer = true;
}
todo(!_thrown_outer, 'should not throw exception');
ok(!_thrown_outer, 'should not throw exception');
}
@ -8501,7 +8501,7 @@ isPixel(ctx, 50,45, 0,255,0,255, 2);
} catch (e) {
_thrown_outer = true;
}
todo(!_thrown_outer, 'should not throw exception');
ok(!_thrown_outer, 'should not throw exception');
}
@ -8545,7 +8545,7 @@ isPixel(ctx, 50,45, 0,255,0,255, 2);
} catch (e) {
_thrown_outer = true;
}
todo(!_thrown_outer, 'should not throw exception');
ok(!_thrown_outer, 'should not throw exception');
}
@ -8571,7 +8571,7 @@ var imgdata = ctx.getImageData(0, 0, 100, 50);
ctx.fillStyle = '#0f0';
ctx.fillRect(0, 0, 100, 50)
ctx.putImageData(imgdata, 0, 0, 0, 0, 0, 0);
todo_isPixel(ctx, 50,25, 0,255,0,255, 2);
isPixel(ctx, 50,25, 0,255,0,255, 2);
}

View File

@ -1,6 +1,6 @@
This is a local copy of the WebGL conformance suite.
SVN revision: 12905
SVN revision: 13113
The canonical location for this testsuite is:

View File

@ -39,7 +39,15 @@ var imgURLs = [
'resources/zero-alpha.png',
'resources/3x3.png',
'resources/blue-1x1.jpg',
'resources/green-2x2-16bit.png'];
'resources/green-2x2-16bit.png',
'resources/small-square-with-colorspin-profile.jpg',
'resources/small-square-with-colorspin-profile.png',
'resources/small-square-with-cie-rgb-profile.png',
'resources/small-square-with-colormatch-profile.png',
'resources/small-square-with-e-srgb-profile.png',
'resources/small-square-with-smpte-c-profile.png',
'resources/small-square-with-srgb-iec61966-2.1-profile.png'];
wtu.loadImagesAsync(imgURLs, runTests);
@ -286,9 +294,7 @@ function runTests(imgs) {
glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
wtu.drawQuad(gl);
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
checkPixelRange(buf, middle, center, [ 0, 0, 255, 255], 10);
glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors");
debug("");
@ -300,10 +306,55 @@ function runTests(imgs) {
glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
wtu.drawQuad(gl);
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
checkPixelRange(buf, middle, center, [ 15, 121, 0, 255], 10);
glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors");
debug("");
debug("check uploading of images with ICC profiles");
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false);
gl.pixelStorei(gl.UNPACK_COLORSPACE_CONVERSION_WEBGL, gl.NONE);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
imgs['resources/small-square-with-colorspin-profile.jpg']);
glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
wtu.drawQuad(gl);
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
// The image is red. However, if we ignore the color profile, it is blue.
checkPixelRange(buf, middle, center, [ 0, 0, 255, 255], 10);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
imgs['resources/small-square-with-colorspin-profile.png']);
glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
wtu.drawQuad(gl);
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
// The image is red. However, if we ignore the color profile, it is blue.
checkPixelRange(buf, middle, center, [ 0, 0, 255, 255], 10);
var iccPNGs = [
'resources/small-square-with-cie-rgb-profile.png',
'resources/small-square-with-colormatch-profile.png',
'resources/small-square-with-e-srgb-profile.png',
'resources/small-square-with-smpte-c-profile.png',
'resources/small-square-with-srgb-iec61966-2.1-profile.png'];
for (var ii = 0; ii < iccPNGs.length; ++ii) {
var buf2 = new Uint8Array(width * height * 4);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE,
imgs[iccPNGs[ii]]);
glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors from setup");
wtu.drawQuad(gl);
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf2);
glErrorShouldBe(gl, gl.NO_ERROR, "Should be no errors");
var same = true;
for (var jj = 0; jj < buf.length; ++jj) {
if (buf[jj] != buf2[jj]) {
same = false;
break;
}
}
assertMsg(same, "uploading PNGs with same data but various ICC profiles should generate the same results");
}
debug("");
successfullyParsed = true;
shouldBeTrue("successfullyParsed");

View File

@ -461,6 +461,8 @@ if (!gl) {
linkSuccess: false,
passMsg: 'vertex shader uses #line directive should report correct line',
},
// TODO(zmo): adding these tests back once the limit is added to WebGL spec.
/*
{ vShaderId: 'vshader',
vShaderSuccess: true,
fShaderId: 'fshaderWith256CharacterIdentifier',
@ -475,6 +477,7 @@ if (!gl) {
linkSuccess: false,
passMsg: 'shared that uses 257 character identifier should fail',
},
*/
];
// Read in all the shader source.

View File

@ -6,15 +6,15 @@ found in the LICENSE file.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>WebGL ReadPixels conformance test.</title>
<link rel="stylesheet" href="../resources/js-test-style.css"/>
<script src="../resources/js-test-pre.js"></script>
<script src="resources/webgl-test.js"> </script>
<script src="resources/webgl-test-utils.js"> </script>
<head>
<title>WebGL ReadPixels conformance test.</title>
<link rel="stylesheet" href="../resources/js-test-style.css"/>
<script src="../resources/js-test-pre.js"></script>
<script src="resources/webgl-test.js"> </script>
<script src="resources/webgl-test-utils.js"> </script>
</head>
<body>
<canvas id="example" width="200" height="200"></canvas>
<canvas id="example" width="200" height="200" style="width: 20px; height: 20px"></canvas>
<div id="description"></div>
<div id="console"></div>
<script>
@ -70,8 +70,7 @@ for (var tt = 0; tt < tests.length; ++tt) {
test.oneColor, test.oneX, test.oneY);
}
glErrorShouldBe(gl, gl.NO_ERROR,
"there should be no GL errors");
glErrorShouldBe(gl, gl.NO_ERROR, "there should be no GL errors");
function checkBuffer(checkColor, x, y, oneColor, oneX, oneY) {
var buf = new Uint8Array(width * height * 4);
@ -85,8 +84,7 @@ function checkBuffer(checkColor, x, y, oneColor, oneX, oneY) {
var color = buf[offset + cc];
var diff = Math.abs(expectedColor - color);
assertMsg(diff < 3,
"color pixel at " + xx + ", " + yy + " should be about " +
expectedColor + " was " + color);
"color pixel at " + xx + ", " + yy + " should be about " + expectedColor);
}
}
}
@ -128,6 +126,8 @@ var badFormats = [
dest: new Uint8Array(2)
}
];
debug("");
debug("check disallowed formats");
for (var tt = 0; tt < badFormats.length; ++ tt) {
var info = badFormats[tt]
var format = info.format;
@ -142,15 +142,54 @@ for (var tt = 0; tt < badFormats.length; ++ tt) {
" / " + wtu.glEnumToString(gl, type));
}
debug("");
debug("check reading with lots of drawing");
width = 1024;
height = 1024;
canvas.width = width;
canvas.height = height;
gl.viewport(0, 0, 1024, 1024);
var program = wtu.setupTexturedQuad(gl);
var loc = gl.getUniformLocation(program, "tex");
gl.disable(gl.BLEND);
gl.disable(gl.DEPTH_TEST);
var colors = [[255, 0, 0, 1], [0, 255, 0, 1], [0, 0, 255, 1]];
var textures = [];
var results = [];
for (var ii = 0; ii < colors.length; ++ii) {
gl.activeTexture(gl.TEXTURE0 + ii);
var tex = gl.createTexture();
wtu.fillTexture(gl, tex, 1, 1, colors[ii]);
textures.push(tex);
}
for (var ii = 0; ii < colors.length; ++ii) {
for (var jj = 0; jj < 300 + ii + 1; ++jj) {
gl.uniform1i(loc, jj % 3);
gl.drawArrays(gl.TRIANGLES, 0, 6);
}
var buf = new Uint8Array(4);
gl.readPixels(512, 512, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, buf);
results.push(buf);
for (var kk = 0; kk < 99; ++kk) {
gl.uniform1i(loc, (jj + kk) % 3);
gl.drawArrays(gl.TRIANGLES, 0, 6);
}
}
var actual;
var expected;
for (var ii = 0; ii < colors.length; ++ii) {
var buf = results[ii];
var color = colors[ii];
actual = [buf[0], buf[1], buf[2], buf[3]];
expected = [color[0], color[1], color[2], color[3] * 255];
shouldBe("actual", "expected");
}
glErrorShouldBe(gl, gl.NO_ERROR, "there should be no GL errors");
debug("");
successfullyParsed = true;
</script>
</body>
<script src="../resources/js-test-post.js"></script>
<script>
</script>
</body>
</html>

View File

@ -9,23 +9,17 @@ found in the LICENSE file.
<script src="../resources/js-test-pre.js"></script>
<script src="resources/webgl-test.js"></script>
<script>
function runTest()
function runTest(gl, width, height)
{
var canvas = document.getElementById("testbed");
var gl = create3DContext(canvas);
if (!gl) {
testFailed('canvas.getContext() failed');
return false;
}
debug('Test whether the WebGL internal buffers have been initialized to 0.');
var buf = new Uint8Array(500 * 500 * 4);
gl.readPixels(0, 0, 500, 500, gl.RGBA, gl.UNSIGNED_BYTE, buf);
var totalBytes = width * height * 4;
var buf = new Uint8Array(totalBytes);
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
if (gl.getError() != gl.NO_ERROR) {
testFailed('GL error detected after readPixels().');
return false;
}
var totalBytes = 500 * 500 * 4;
for (var i = 0; i < totalBytes; ++i) {
if (buf[i] != 0) {
testFailed('WebGL internal buffers are dirty.');
@ -39,7 +33,7 @@ function runTest()
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
var colorbuffer = gl.createRenderbuffer();
gl.bindRenderbuffer(gl.RENDERBUFFER, colorbuffer);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, 500, 500);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.RGBA4, width, height);
if (gl.getError() != gl.NO_ERROR) {
testFailed('GL error detected after renderbufferStorage(internalformat = RGBA4).');
return false;
@ -49,7 +43,7 @@ function runTest()
testFailed('Framebuffer incomplete.');
return false;
}
gl.readPixels(0, 0, 500, 500, gl.RGBA, gl.UNSIGNED_BYTE, buf);
gl.readPixels(0, 0, width, height, gl.RGBA, gl.UNSIGNED_BYTE, buf);
if (gl.getError() != gl.NO_ERROR) {
testFailed('GL error detected after readPixels().');
return false;
@ -67,7 +61,7 @@ function runTest()
</script>
</head>
<body>
<canvas id="testbed" width="500px" height="500px"></canvas>
<canvas id="testbed" width="400px" height="400px"></canvas>
<div id="description"></div>
<div id="console"></div>
<script>
@ -75,9 +69,25 @@ var successfullyParsed = false;
description('Verify renderbuffers are initialized to 0 before being read in WebGL');
runTest();
var canvas = document.getElementById("testbed");
var gl = canvas.getContext("experimental-webgl");
if (!gl) {
testFailed('canvas.getContext() failed');
} else {
runTest(gl, canvas.width, canvas.height);
successfullyParsed = true;
// Testing that canvas resizing will clear the buffers with 0 instead of the current clear values.
gl.clearColor(1, 0, 0, 1);
canvas.width += 1;
canvas.height += 1;
runTest(gl, canvas.width, canvas.height);
// Testing buffer clearing won't change the clear values.
var clearColor = gl.getParameter(gl.COLOR_CLEAR_VALUE);
shouldBe("clearColor", "[1, 0, 0, 1]");
successfullyParsed = true;
}
</script>
<script src="../resources/js-test-post.js"></script>
</body>

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 868 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 871 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 841 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 871 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -284,7 +284,7 @@ var fillTexture = function(gl, tex, width, height, color, opt_level) {
*/
var createColoredTexture = function(gl, width, height, color) {
var tex = gl.createTexture();
fillTexture(gl, text, width, height, color);
fillTexture(gl, tex, width, height, color);
return tex;
};
@ -378,20 +378,15 @@ var loadTexture = function(gl, url, callback) {
* passed in one will be created.
* @return {!WebGLContext} The created context.
*/
var create3DContext = function(opt_canvas) {
var create3DContext = function(opt_canvas, opt_attributes) {
opt_canvas = opt_canvas || document.createElement("canvas");
var context = null;
try {
context = opt_canvas.getContext("experimental-webgl");
context = opt_canvas.getContext("webgl", opt_attributes);
} catch(e) {}
if (!context) {
try {
context = opt_canvas.getContext("webkit-3d");
} catch(e) {}
}
if (!context) {
try {
context = opt_canvas.getContext("moz-webgl");
context = opt_canvas.getContext("experimental-webgl", opt_attributes);
} catch(e) {}
}
if (!context) {

View File

@ -44,16 +44,11 @@ function create3DContext(canvas, attributes)
canvas = document.createElement("canvas");
var context = null;
try {
context = canvas.getContext("experimental-webgl", attributes);
context = canvas.getContext("webgl", attributes);
} catch(e) {}
if (!context) {
try {
context = canvas.getContext("webkit-3d", attributes);
} catch(e) {}
}
if (!context) {
try {
context = canvas.getContext("moz-webgl", attributes);
context = canvas.getContext("experimental-webgl", attributes);
} catch(e) {}
}
if (!context) {
@ -151,55 +146,55 @@ function glErrorShouldBe(gl, glError, opt_msg) {
//
function createProgram(gl, vshaders, fshaders, attribs)
{
if (typeof(vshaders) == "string")
vshaders = [vshaders];
if (typeof(fshaders) == "string")
fshaders = [fshaders];
if (typeof(vshaders) == "string")
vshaders = [vshaders];
if (typeof(fshaders) == "string")
fshaders = [fshaders];
var shaders = [];
var i;
var shaders = [];
var i;
for (i = 0; i < vshaders.length; ++i) {
var shader = loadShader(gl, vshaders[i], gl.VERTEX_SHADER);
if (!shader)
for (i = 0; i < vshaders.length; ++i) {
var shader = loadShader(gl, vshaders[i], gl.VERTEX_SHADER);
if (!shader)
return null;
shaders.push(shader);
}
for (i = 0; i < fshaders.length; ++i) {
var shader = loadShader(gl, fshaders[i], gl.FRAGMENT_SHADER);
if (!shader)
return null;
shaders.push(shader);
}
var prog = gl.createProgram();
for (i = 0; i < shaders.length; ++i) {
gl.attachShader(prog, shaders[i]);
}
if (attribs) {
for (var i in attribs) {
gl.bindAttribLocation (prog, i, attribs[i]);
shaders.push(shader);
}
for (i = 0; i < fshaders.length; ++i) {
var shader = loadShader(gl, fshaders[i], gl.FRAGMENT_SHADER);
if (!shader)
return null;
shaders.push(shader);
}
var prog = gl.createProgram();
for (i = 0; i < shaders.length; ++i) {
gl.attachShader(prog, shaders[i]);
}
if (attribs) {
for (var i in attribs) {
gl.bindAttribLocation(prog, parseInt(i), attribs[i]);
}
}
gl.linkProgram(prog);
gl.linkProgram(prog);
// Check the link status
var linked = gl.getProgramParameter(prog, gl.LINK_STATUS);
if (!linked) {
// something went wrong with the link
var error = gl.getProgramInfoLog(prog);
webglTestLog("Error in program linking:" + error);
// Check the link status
var linked = gl.getProgramParameter(prog, gl.LINK_STATUS);
if (!linked) {
// something went wrong with the link
var error = gl.getProgramInfoLog(prog);
webglTestLog("Error in program linking:" + error);
gl.deleteProgram(prog);
for (i = 0; i < shaders.length; ++i)
gl.deleteProgram(prog);
for (i = 0; i < shaders.length; ++i)
gl.deleteShader(shaders[i]);
return null;
}
return null;
}
return prog;
return prog;
}
//

View File

@ -57,6 +57,8 @@ function runOneIteration(videoElement, useTexSubImage2D, flipY, topColor, bottom
// Set up texture parameters
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
// Set up pixel store parameters
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, flipY);
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
@ -120,7 +122,7 @@ function finish() {
<canvas id="example" width="32px" height="32px"></canvas>
<div id="description"></div>
<div id="console"></div>
<video width="640" height="228" id="vid" controls autoplay>
<video width="640" height="228" id="vid" controls>
<source src="resources/red-green.mp4" type='video/mp4; codecs="avc1.42E01E, mp4a.40.2"' />
<source src="resources/red-green.webmvp8.webm" type='video/webm; codecs="vp8, vorbis"' />
<source src="resources/red-green.theora.ogv" type='video/ogg; codecs="theora, vorbis"' />

View File

@ -1,11 +1,11 @@
<!doctype html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>WebGL Uninitialized GL Resources Tests</title>
<link rel="stylesheet" href="../resources/js-test-style.css"/>
<script src="../resources/js-test-pre.js"></script>
<script src="resources/webgl-test.js"></script>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>WebGL Uninitialized GL Resources Tests</title>
<link rel="stylesheet" href="../resources/js-test-style.css"/>
<script src="../resources/js-test-pre.js"></script>
<script src="resources/webgl-test.js"></script>
</head>
<body>
<div id="description"></div>
@ -21,7 +21,6 @@ if (!gl)
else
testPassed("Context created.");
debug("Reading an uninitialized texture should succeed with all bytes set to 0.");
var width = 512;
@ -63,15 +62,15 @@ if (data.length != expectedDataLength) {
} else {
var k = 0;
for (var i = 0; i < data.length; ++i) {
if (data[i] != 0) {
k++;
}
if (data[i] != 0) {
k++;
}
}
if (k) {
testFailed("Found " + k + " non-zero bytes");
testFailed("Found " + k + " non-zero bytes");
} else {
testPassed("All data initialized");
testPassed("All data initialized");
}
}
@ -83,14 +82,10 @@ glErrorShouldBe(gl, gl.NO_ERROR);
//TODO: uninitialized renderbuffer? (implementations would need to do a GL clear at first binding?)
//TODO: uninitialized uniform arrays?
debug("");
successfullyParsed = true;
</script>
<script src="../resources/js-test-post.js"></script>
<script>
</script>
</body>
</html>

View File

@ -8,7 +8,7 @@ found in the LICENSE file.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>WebGL FBO Lost Context Test</title>
<title>WebGL Big FBO Test</title>
<link rel="stylesheet" href="../resources/js-test-style.css"/>
<script src="../resources/desktop-gl-constants.js" type="text/javascript"></script>
<script src="../../debug/webgl-debug.js"></script>
@ -18,162 +18,175 @@ found in the LICENSE file.
<body>
<div id="description"></div>
<div id="console"></div>
<script id="vshader" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec2 texCoord0;
uniform mat4 world;
varying vec2 texCoord;
void main()
{
gl_Position = vPosition * world;
texCoord = texCoord0;
}
</script>
<script id="vshader" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec2 texCoord0;
uniform mat4 world;
varying vec2 texCoord;
void main()
{
gl_Position = vPosition * world;
texCoord = texCoord0;
}
</script>
<script id="fshader" type="x-shader/x-fragment">
uniform sampler2D tex;
varying vec2 texCoord;
void main()
{
gl_FragColor = texture2D(tex, texCoord);
}
</script>
<script id="fshader" type="x-shader/x-fragment">
precision mediump float;
uniform sampler2D tex;
varying vec2 texCoord;
void main()
{
gl_FragColor = texture2D(tex, texCoord);
}
</script>
<canvas id="canvas" width="1024" height="1024"> </canvas>
<script>
description("This test is to help see if an WebGL app *can* get lost context.");
window.onload = init;
debug("Tests the performance of using lots of large FBOs");
debug("");
debug("Canvas.getContext");
var g_worldLoc;
var g_texLoc;
var g_textures = [];
gl = initWebGL("canvas", "vshader", "fshader", [ "vPosition", "texCoord0"], [ 0, 0, 0, 1 ], 1);
if (!gl) {
testFailed("context does not exist");
} else {
testPassed("context exists");
debug("");
debug("Checking for out of memory handling.");
var size = gl.getParameter(gl.MAX_RENDERBUFFER_SIZE);
debug("max render buffer size: " + size);
size = size / 2;
debug("size used: " + size);
var allocateFramebuffers = true;
var intervalId = 0;
var count = 0;
WebGLDebugUtils.init(gl);
function createFBO() {
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(gl.TEXTURE_2D,
0, // level
gl.RGBA, // internalFormat
size, // width
size, // height
0, // border
gl.RGBA, // format
gl.UNSIGNED_BYTE, // type
null); // data
var fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.framebufferTexture2D(
gl.FRAMEBUFFER,
gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D,
tex,
0);
var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
if (status != gl.FRAMEBUFFER_COMPLETE) {
testFailed("gl.checkFramebufferStatus() returned " + WebGLDebugUtils.glEnumToString(status));
return;
}
var err = gl.getError();
if (err != gl.NO_ERROR) {
if (err != gl.OUT_OF_MEMORY) {
testFailed("gl.getError returned " + err);
}
return;
}
return { fb: fb, tex: tex };
function init() {
if (confirm(
"after clicking ok your machine may be come unresponsive or crash")) {
main();
} else {
debug("cancelled");
}
gl.disable(gl.DEPTH_TEST);
var maxFBOs = 128;
for (var ii = 0; ii < maxFBOs; ++ii) {
createFBO();
var t = createFBO();
if (!t) {
break;
}
tex = t.tex;
fb = t.fb;
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.scissor(0, 0, size, size);
gl.clearColor(0, ii / maxFBOs, 1 - ii / maxFBOs, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
g_textures.push(tex);
}
debug("fbos allocated:" + g_textures.length);
gl.scissor(0, 0, 1024, 1024);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
var vertexObject = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
-1,1,0, 1,1,0, -1,-1,0,
-1,-1,0, 1,1,0, 1,-1,0
]), gl.STATIC_DRAW);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
var vertexObject = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0, 1,0, 0,1,
0,1, 1,0, 1,1
]), gl.STATIC_DRAW);
gl.enableVertexAttribArray(1);
gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);
g_texLoc = gl.getUniformLocation(gl.program, "tex");
gl.uniform1i(g_texLoc, 0);
g_worldLoc = gl.getUniformLocation(gl.program, "world");
gl.uniformMatrix4fv(g_worldLoc, false, [
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1]);
setInterval(render, 1000/60);
}
var g_angle = 0;
var g_texIndex = 0;
function render() {
g_angle += 0.1;
g_texIndex++;
if (g_texIndex >= g_textures.length) {
g_texIndex = 0;
function main() {
debug("");
debug("Canvas.getContext");
var g_worldLoc;
var g_texLoc;
var g_textures = [];
gl = initWebGL("canvas", "vshader", "fshader", [ "vPosition", "texCoord0"], [ 0, 0, 0, 1 ], 1);
if (!gl) {
testFailed("context does not exist");
} else {
testPassed("context exists");
debug("");
debug("Checking for out of memory handling.");
var size = gl.getParameter(gl.MAX_RENDERBUFFER_SIZE);
debug("max render buffer size: " + size);
size = size / 2;
debug("size used: " + size);
var allocateFramebuffers = true;
var intervalId = 0;
var count = 0;
WebGLDebugUtils.init(gl);
function createFBO() {
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(gl.TEXTURE_2D,
0, // level
gl.RGBA, // internalFormat
size, // width
size, // height
0, // border
gl.RGBA, // format
gl.UNSIGNED_BYTE, // type
null); // data
var fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.framebufferTexture2D(
gl.FRAMEBUFFER,
gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D,
tex,
0);
var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
if (status != gl.FRAMEBUFFER_COMPLETE) {
testFailed("gl.checkFramebufferStatus() returned " + WebGLDebugUtils.glEnumToString(status));
return;
}
var err = gl.getError();
if (err != gl.NO_ERROR) {
if (err != gl.OUT_OF_MEMORY) {
testFailed("gl.getError returned " + err);
}
return;
}
return { fb: fb, tex: tex };
}
gl.disable(gl.DEPTH_TEST);
var maxFBOs = 2;
for (var ii = 0; ii < maxFBOs; ++ii) {
createFBO();
var t = createFBO();
if (!t) {
break;
}
tex = t.tex;
fb = t.fb;
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.scissor(0, 0, size, size);
gl.clearColor(0, ii / maxFBOs, 1 - ii / maxFBOs, 1);
gl.clear(gl.COLOR_BUFFER_BIT);
g_textures.push(tex);
}
debug("fbos allocated:" + g_textures.length);
gl.scissor(0, 0, 1024, 1024);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
var vertexObject = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
-1,1,0, 1,1,0, -1,-1,0,
-1,-1,0, 1,1,0, 1,-1,0
]), gl.STATIC_DRAW);
gl.enableVertexAttribArray(0);
gl.vertexAttribPointer(0, 3, gl.FLOAT, false, 0, 0);
var vertexObject = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexObject);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([ 0,0, 1,0, 0,1,
0,1, 1,0, 1,1
]), gl.STATIC_DRAW);
gl.enableVertexAttribArray(1);
gl.vertexAttribPointer(1, 2, gl.FLOAT, false, 0, 0);
g_texLoc = gl.getUniformLocation(gl.program, "tex");
gl.uniform1i(g_texLoc, 0);
g_worldLoc = gl.getUniformLocation(gl.program, "world");
gl.uniformMatrix4fv(g_worldLoc, false, [
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1]);
setInterval(render, 1000/60);
}
var g_angle = 0;
var g_texIndex = 0;
function render() {
g_angle += 0.1;
g_texIndex++;
if (g_texIndex >= g_textures.length) {
g_texIndex = 0;
}
gl.bindTexture(gl.TEXTURE_2D, g_textures[g_texIndex]);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.uniformMatrix4fv(g_worldLoc, false, rotationZ(g_angle));
gl.clearColor(1,0,0,1);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 6);
}
gl.bindTexture(gl.TEXTURE_2D, g_textures[g_texIndex]);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.uniformMatrix4fv(g_worldLoc, false, rotationZ(g_angle));
gl.clearColor(1,0,0,1);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 6);
}
/**

View File

@ -29,7 +29,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
<title>Canvas Compositing Test</title>
<link rel="stylesheet" href="../resources/js-test-style.css"/>
<script src="../resources/js-test-pre.js"></script>
<script src="../fast/resources/webgl-test.js"> </script>
<script src="../conformance/resources/webgl-test.js"> </script>
</head>
<body>
Below are 2 50x50 pixel canvas but using CSS to display them at 100x100 pixels. <br/>

View File

@ -13,31 +13,32 @@ found in the LICENSE file.
<script src="../resources/desktop-gl-constants.js" type="text/javascript"></script>
<script src="../../debug/webgl-debug.js"></script>
<script src="../resources/js-test-pre.js"></script>
<script src="../fast/resources/webgl-test.js"></script>
<script src="../conformance/resources/webgl-test.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<script id="vshader" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec2 texCoord0;
uniform mat4 world;
varying vec2 texCoord;
void main()
{
gl_Position = vPosition * world;
texCoord = texCoord0;
}
</script>
<script id="vshader" type="x-shader/x-vertex">
attribute vec4 vPosition;
attribute vec2 texCoord0;
uniform mat4 world;
varying vec2 texCoord;
void main()
{
gl_Position = vPosition * world;
texCoord = texCoord0;
}
</script>
<script id="fshader" type="x-shader/x-fragment">
uniform sampler2D tex;
varying vec2 texCoord;
void main()
{
gl_FragColor = texture2D(tex, texCoord);
}
</script>
<script id="fshader" type="x-shader/x-fragment">
precision mediump float;
uniform sampler2D tex;
varying vec2 texCoord;
void main()
{
gl_FragColor = texture2D(tex, texCoord);
}
</script>
<canvas id="canvas" width="1024" height="1024"> </canvas>
<script>
description("This test is to help see if an WebGL app *can* get lost context.");

View File

@ -18,58 +18,66 @@ found in the LICENSE file.
<div id="description"></div>
<div id="console"></div>
<script>
var wtu = WebGLTestUtils;
var canvas = document.getElementById("example");
var gl = wtu.create3DContext(canvas);
var program = wtu.setupTexturedQuad(gl);
window.onload = init;
debug("Tests a WebGL program that draws a bunch of large polygons");
assertMsg(gl.getError() == gl.NO_ERROR, "Should be no errors from setup.");
var tex = gl.createTexture();
gl.enable(gl.BLEND);
gl.disable(gl.DEPTH_TEST);
wtu.fillTexture(gl, tex, 4096, 4096, [0, 192, 128, 255], 0);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after creating texture");
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after setting texture params");
var loc = gl.getUniformLocation(program, "tex");
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after getting tex locations");
gl.uniform1i(loc, 0);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after setting tex uniform");
var numQuads = 100000;
var indexBuf = new ArrayBuffer(numQuads * 6);
var indices = new Uint8Array(indexBuf);
for (var ii = 0; ii < numQuads; ++ii) {
var offset = ii * 6;
indices[offset + 0] = 0;
indices[offset + 1] = 1;
indices[offset + 2] = 2;
indices[offset + 3] = 3;
indices[offset + 4] = 4;
indices[offset + 5] = 5;
function init() {
if (confirm(
"after clicking ok your machine may be come unresponsive or crash")) {
main();
} else {
debug("cancelled");
}
}
var indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after creating index buffer");
gl.drawElements(gl.TRIANGLES, numQuads * 6, gl.UNSIGNED_BYTE, 0);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after drawing");
successfullyParsed = true;
function main() {
var wtu = WebGLTestUtils;
var canvas = document.getElementById("example");
var gl = wtu.create3DContext(canvas);
var program = wtu.setupTexturedQuad(gl);
assertMsg(gl.getError() == gl.NO_ERROR, "Should be no errors from setup.");
var tex = gl.createTexture();
gl.enable(gl.BLEND);
gl.disable(gl.DEPTH_TEST);
wtu.fillTexture(gl, tex, 4096, 4096, [0, 192, 128, 255], 0);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after creating texture");
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after setting texture params");
var loc = gl.getUniformLocation(program, "tex");
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after getting tex locations");
gl.uniform1i(loc, 0);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after setting tex uniform");
var numQuads = 100000;
var indexBuf = new ArrayBuffer(numQuads * 6);
var indices = new Uint8Array(indexBuf);
for (var ii = 0; ii < numQuads; ++ii) {
var offset = ii * 6;
indices[offset + 0] = 0;
indices[offset + 1] = 1;
indices[offset + 2] = 2;
indices[offset + 3] = 3;
indices[offset + 4] = 4;
indices[offset + 5] = 5;
}
var indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after creating index buffer");
gl.drawElements(gl.TRIANGLES, numQuads * 6, gl.UNSIGNED_BYTE, 0);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after drawing");
successfullyParsed = true;
}
</script>
</body>
<script src="../resources/js-test-post.js"></script>
<script>
</script>
</body>
</html>

View File

@ -8,18 +8,18 @@ found in the LICENSE file.
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>WebGL Out Of Memory Conformance Tests</title>
<title>WebGL Out Of Memory Test</title>
<link rel="stylesheet" href="../resources/js-test-style.css"/>
<script src="../resources/desktop-gl-constants.js" type="text/javascript"></script>
<script src="../resources/js-test-pre.js"></script>
<script src="../fast/resources/webgl-test.js"></script>
<script src="../conformance/resources/webgl-test.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<canvas id="canvas" width="2" height="2"> </canvas>
<script>
description("This tests WebGL running out of memory.");
debug("This tests WebGL running out of memory.");
debug("");
debug("Canvas.getContext");

View File

@ -13,7 +13,7 @@ found in the LICENSE file.
<script src="../resources/desktop-gl-constants.js" type="text/javascript"></script>
<script src="../../debug/webgl-debug.js"></script>
<script src="../resources/js-test-pre.js"></script>
<script src="../fast/resources/webgl-test.js"></script>
<script src="../conformance/resources/webgl-test.js"></script>
</head>
<body>
<div id="description"></div>
@ -21,81 +21,89 @@ found in the LICENSE file.
<canvas id="canvas" width="2" height="2"> </canvas>
<canvas id="canvas2" width="2" height="2"> </canvas>
<script>
description("This test is to check what happens if a WebGL program tries to use all of vram.");
window.onload = init;
debug("Tests a WebGL program that tries to use all of vram.");
debug("");
debug("Canvas.getContext");
var gl = create3DContext(document.getElementById("canvas"));
if (!gl) {
testFailed("context does not exist");
} else {
testPassed("context exists");
function init() {
if (confirm(
"after clicking ok your machine may be come unresponsive or crash")) {
main();
} else {
debug("cancelled");
}
}
function main() {
debug("");
debug("Checking for out of memory handling.");
debug("Canvas.getContext");
var size = gl.getParameter(gl.MAX_RENDERBUFFER_SIZE);
debug("max render buffer size: " + size);
var gl = create3DContext(document.getElementById("canvas"));
if (!gl) {
testFailed("context does not exist");
} else {
testPassed("context exists");
var allocateFramebuffers = true;
var itervalId;
var count = 0;
debug("");
debug("Checking for out of memory handling.");
gl = WebGLDebugUtils.makeDebugContext(gl, function(err, functionName, args) {
window.clearInterval(intervalId);
assertMsg(err == gl.OUT_OF_MEMORY,
"correctly returns gl.OUT_OF_MEMORY when out of memory");
finish();
});
var size = gl.getParameter(gl.MAX_RENDERBUFFER_SIZE);
debug("max render buffer size: " + size);
intervalId = window.setInterval(function() {
++count;
var mem = count * size * size * 4;
debug("#" + count + " : memory allocated so far " + (mem / 1024 / 1024) + "MB");
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(gl.TEXTURE_2D,
0, // level
gl.RGBA, // internalFormat
size, // width
size, // height
0, // border
gl.RGBA, // format
gl.UNSIGNED_BYTE, // type
null); // data
if (allocateFrameBuffers) {
var fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.framebufferTexture2D(
gl.FRAMEBUFFER,
gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D,
tex,
0);
var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
if (status != gl.FRAMEBUFFER_COMPLETE) {
testFailed("gl.checkFramebufferStatus() returned " + WebGLDebugUtils.glEnumToString(status) +
" should have gotten gl.OUT_OF_MEMORY before getting this.");
window.clearInterval(intervalId);
finish();
var allocateFramebuffers = true;
var itervalId;
var count = 0;
gl = WebGLDebugUtils.makeDebugContext(gl, function(err, functionName, args) {
window.clearInterval(intervalId);
assertMsg(err == gl.OUT_OF_MEMORY,
"correctly returns gl.OUT_OF_MEMORY when out of memory");
finish();
});
intervalId = window.setInterval(function() {
++count;
var mem = count * size * size * 4;
debug("#" + count + " : memory allocated so far " + (mem / 1024 / 1024) + "MB");
var tex = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(gl.TEXTURE_2D,
0, // level
gl.RGBA, // internalFormat
size, // width
size, // height
0, // border
gl.RGBA, // format
gl.UNSIGNED_BYTE, // type
null); // data
if (allocateFrameBuffers) {
var fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.framebufferTexture2D(
gl.FRAMEBUFFER,
gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D,
tex,
0);
var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
if (status != gl.FRAMEBUFFER_COMPLETE) {
testFailed("gl.checkFramebufferStatus() returned " + WebGLDebugUtils.glEnumToString(status) +
" should have gotten gl.OUT_OF_MEMORY before getting this.");
window.clearInterval(intervalId);
finish();
}
}
}
}, 1000/10);
}, 1000/10);
}
function finish() {
debug("");
successfullyParsed = true;
}
}
function finish() {
debug("");
successfullyParsed = true;
}
</script>
<script>
</script>
</body>
</html>

View File

@ -28,6 +28,9 @@ void main() {
}
</script>
<script>
window.onload = main;
debug("Tests drawing a very slow shader.");
var wtu = WebGLTestUtils;
var canvas = document.getElementById("example");
var gl = wtu.create3DContext(canvas);
@ -93,18 +96,19 @@ var indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after setting up indices");
alert("click to draw");
gl.drawElements(gl.TRIANGLES, numQuads * 6, gl.UNSIGNED_BYTE, 0);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after drawing");
function main () {
if (confirm(
"after clicking ok your machine may be come unresponsive or crash")) {
gl.drawElements(gl.TRIANGLES, numQuads * 6, gl.UNSIGNED_BYTE, 0);
wtu.glErrorShouldBe(gl, gl.NO_ERROR, "after drawing");
} else {
debug("cancelled");
}
}
successfullyParsed = true;
</script>
</body>
<script src="../resources/js-test-post.js"></script>
<script>
</script>
</body>
</html>

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