Merged again from m-c to get latest bits and avoid deleted branch issue.

This commit is contained in:
Jason Duell 2010-06-22 17:57:09 -07:00
commit e9ace04a4c
104 changed files with 6238 additions and 1094 deletions

View File

@ -257,31 +257,13 @@ void nsAccessNode::ShutdownXPAccessibility()
NotifyA11yInitOrShutdown(PR_FALSE);
}
PRBool
nsAccessNode::IsDefunct()
already_AddRefed<nsIPresShell>
nsAccessNode::GetPresShell()
{
if (!mContent)
return PR_TRUE;
// Call GetPresShell() since the accessible may be shut down in it.
nsCOMPtr<nsIPresShell> presShell(GetPresShell());
return !presShell;
}
already_AddRefed<nsIPresShell> nsAccessNode::GetPresShell()
{
nsIPresShell *presShell = nsnull;
nsIPresShell* presShell = nsnull;
if (mWeakShell)
CallQueryReferent(mWeakShell.get(), &presShell);
if (!presShell) {
if (mWeakShell) {
// If our pres shell has died, but we're still holding onto
// a weak reference, our accessibles are no longer relevant
// and should be shut down
Shutdown();
}
return nsnull;
}
return presShell;
}

View File

@ -120,10 +120,10 @@ public:
*/
already_AddRefed<nsINode> GetCurrentFocus();
/**
* Returns true when the accessible is defunct.
*/
virtual PRBool IsDefunct();
/**
* Returns true when the accessible is defunct.
*/
virtual PRBool IsDefunct() { return !mContent; }
/**
* Initialize the access node object, add it to the cache.

View File

@ -611,6 +611,11 @@
accesskey="&errorConsoleCmd.accesskey;"
key="key_errorConsole"
oncommand="toJavaScriptConsole();"/>
<menuitem id="headsUpDisplayConsole"
label="&hudConsoleCmd.label;"
accesskey="&hudConsoleCmd.accesskey;"
key="key_hudConsole"
oncommand="HUDConsoleUI.toggleHUD();"/>
<menuitem id="menu_pageInfo"
accesskey="&pageInfoCmd.accesskey;"
label="&pageInfoCmd.label;"

View File

@ -222,6 +222,7 @@
<key id="key_openDownloads" key="&downloads.commandkey;" command="Tools:Downloads" modifiers="accel"/>
#endif
<key id="key_errorConsole" key="&errorConsoleCmd.commandkey;" oncommand="toJavaScriptConsole();" modifiers="accel,shift"/>
<key id="key_hudConsole" key="&hudConsoleCmd.commandkey;" oncommand="HUDConsoleUI.toggleHUD();" modifiers="accel,shift"/>
<key id="key_inspect" key="&inspectMenu.commandkey;" command="Tools:Inspect" modifiers="accel,shift"/>
<key id="openFileKb" key="&openFileCmd.commandkey;" command="Browser:OpenFile" modifiers="accel"/>
<key id="key_savePage" key="&savePageCmd.commandkey;" command="Browser:SavePage" modifiers="accel"/>

View File

@ -996,14 +996,6 @@ function BrowserStartup() {
}
if (window.opener && !window.opener.closed) {
let openerFindBar = window.opener.gFindBarInitialized ?
window.opener.gFindBar : null;
if (openerFindBar &&
!openerFindBar.hidden &&
openerFindBar.findMode == openerFindBar.FIND_NORMAL) {
gFindBar.open();
}
let openerSidebarBox = window.opener.document.getElementById("sidebar-box");
// If the opener had a sidebar, open the same sidebar in our window.
// The opener can be the hidden window too, if we're coming from the state
@ -7681,3 +7673,14 @@ var TabContextMenu = {
getClosedTabCount(window) == 0;
}
};
XPCOMUtils.defineLazyGetter(this, "HUDConsoleUI", function () {
Cu.import("resource://gre/modules/HUDService.jsm");
try {
return HUDService.consoleUI;
}
catch (ex) {
Components.utils.reportError(ex);
}
});

View File

@ -244,8 +244,8 @@
</tree>
</panel>
<popup id="toolbar-context-menu"
onpopupshowing="onViewToolbarsPopupShowing(event);">
<menupopup id="toolbar-context-menu"
onpopupshowing="onViewToolbarsPopupShowing(event);">
<menuseparator/>
<menuitem command="cmd_ToggleTabsOnTop"
type="checkbox"
@ -255,15 +255,15 @@
<menuitem command="cmd_CustomizeToolbars"
label="&viewCustomizeToolbar.label;"
accesskey="&viewCustomizeToolbar.accesskey;"/>
</popup>
</menupopup>
<popup id="blockedPopupOptions"
onpopupshowing="gPopupBlockerObserver.fillPopupList(event);">
<menupopup id="blockedPopupOptions"
onpopupshowing="gPopupBlockerObserver.fillPopupList(event);">
<menuitem observes="blockedPopupAllowSite"/>
<menuitem observes="blockedPopupEditSettings"/>
<menuitem observes="blockedPopupDontShowMessage"/>
<menuseparator observes="blockedPopupsSeparator"/>
</popup>
</menupopup>
<menupopup id="autohide-context"
onpopupshowing="FullScreen.getAutohide(this.firstChild);">
@ -276,13 +276,13 @@
oncommand="BrowserFullScreen();"/>
</menupopup>
<popup id="contentAreaContextMenu"
onpopupshowing="if (event.target != this) return true; updateEditUIVisibility(); gContextMenu = new nsContextMenu(this, window.getBrowser()); return gContextMenu.shouldDisplay;"
onpopuphiding="if (event.target == this) { gContextMenu = null; updateEditUIVisibility(); }">
<menupopup id="contentAreaContextMenu"
onpopupshowing="if (event.target != this) return true; updateEditUIVisibility(); gContextMenu = new nsContextMenu(this, window.getBrowser()); return gContextMenu.shouldDisplay;"
onpopuphiding="if (event.target == this) { gContextMenu = null; updateEditUIVisibility(); }">
#include browser-context.inc
</popup>
</menupopup>
<popup id="placesContext"/>
<menupopup id="placesContext"/>
<panel id="notification-popup" position="after_start" noautofocus="true" hidden="true"/>

View File

@ -2787,12 +2787,17 @@
]]></handler>
<handler event="click"><![CDATA[
if (event.button != 1 || event.target.localName != "tab")
if (event.button != 1)
return;
if (this.childNodes.length > 1 ||
!this._closeWindowWithLastTab)
this.tabbrowser.removeTab(event.target);
if (event.target.localName == "tab") {
if (this.childNodes.length > 1 || !this._closeWindowWithLastTab)
this.tabbrowser.removeTab(event.target);
} else if (event.originalTarget.localName == "box") {
BrowserOpenTab();
} else {
return;
}
event.stopPropagation();
]]></handler>

View File

@ -80,15 +80,15 @@
<popupset id="mainPopupSet">
<tooltip id="aHTMLTooltip" onpopupshowing="return FillInHTMLTooltip(document.tooltipNode);"/>
<popup id="contentAreaContextMenu"
onpopupshowing="if (event.target != this)
return true;
gContextMenu = new nsContextMenu(this, getPanelBrowser());
return gContextMenu.shouldDisplay;"
onpopuphiding="if (event.target == this)
gContextMenu = null;">
<menupopup id="contentAreaContextMenu"
onpopupshowing="if (event.target != this)
return true;
gContextMenu = new nsContextMenu(this, getPanelBrowser());
return gContextMenu.shouldDisplay;"
onpopuphiding="if (event.target == this)
gContextMenu = null;">
#include browser-context.inc
</popup>
</menupopup>
</popupset>
<commandset id="editMenuCommands"/>

View File

@ -59,7 +59,7 @@
<commandset id="placesCommands"/>
<commandset id="editMenuCommands"/>
<popup id="placesContext"/>
<menupopup id="placesContext"/>
<!-- Bookmarks and history tooltip -->
<tooltip id="bhTooltip"/>

View File

@ -75,7 +75,7 @@
</keyset>
<!-- required to overlay the context menu -->
<popup id="placesContext" />
<menupopup id="placesContext"/>
<!-- Bookmarks and history tooltip -->
<tooltip id="bhTooltip"/>

View File

@ -179,10 +179,10 @@
</keyset>
<popupset id="placesPopupset">
<popup id="placesContext"/>
<popup id="placesColumnsContext"
onpopupshowing="ViewMenu.fillWithColumns(event, null, null, 'checkbox', null);"
oncommand="ViewMenu.showHideColumn(event.target); event.stopPropagation();"/>
<menupopup id="placesContext"/>
<menupopup id="placesColumnsContext"
onpopupshowing="ViewMenu.fillWithColumns(event, null, null, 'checkbox', null);"
oncommand="ViewMenu.showHideColumn(event.target); event.stopPropagation();"/>
</popupset>
<toolbox id="placesToolbox">

View File

@ -123,10 +123,10 @@
oncommand="goDoPlacesCommand('placesCmd_delete');"/>
</commandset>
<popup id="placesContext"
onpopupshowing="this._view = PlacesUIUtils.getViewForNode(document.popupNode);
return this._view.buildContextMenu(this);"
onpopuphiding="this._view.destroyContextMenu();">
<menupopup id="placesContext"
onpopupshowing="this._view = PlacesUIUtils.getViewForNode(document.popupNode);
return this._view.buildContextMenu(this);"
onpopuphiding="this._view.destroyContextMenu();">
<menuitem id="placesContext_open"
command="placesCmd_open"
label="&cmd.open.label;"
@ -258,6 +258,6 @@
accesskey="&cmd.properties.accesskey;"
selection="bookmark|folder|query"
forcehideselection="livemarkChild"/>
</popup>
</menupopup>
</overlay>

View File

@ -787,6 +787,10 @@ PlacesTreeView.prototype = {
if (!this._tree || !this._result)
return;
// Nothing to do for the root node.
if (aNode == this._rootNode)
return;
let row = this._getRowForNode(aNode);
if (row == -1)
return;

View File

@ -50,6 +50,7 @@ _CHROME_TEST_FILES = \
test_0_multiple_left_pane.xul \
test_0_bug510634.xul \
test_bug549192.xul \
test_bug549491.xul \
$(NULL)
libs:: $(_CHROME_TEST_FILES)

View File

@ -45,13 +45,15 @@
SimpleTest.waitForExplicitFinish();
function runTest() {
// The mochitest page is added to history.
waitForClearHistory(continue_test);
}
function continue_test() {
const Cc = Components.classes;
const Ci = Components.interfaces;
Components.utils.import("resource://gre/modules/Services.jsm");
// Cleanup.
PlacesUtils.bhistory.removeAllPages();
// Add some visits.
let vtime = Date.now() * 1000;
const ttype = PlacesUtils.history.TRANSITION_TYPED;
@ -76,8 +78,13 @@
// loop through the rows and check formatting
let treeView = tree.view;
for (let i = 0; i < rc; i++) {
selection.select(rc);
let node = tree.selectedNode;
ok(true, "found " + node.title);
}
let rc = treeView.rowCount;
ok(rc == 3, "Rows found.");
is(rc, 3, "Rows found.");
let selection = treeView.selection;
for (let i = 0; i < rc; i++) {
selection.select(0);
@ -89,10 +96,25 @@
}
// Cleanup.
PlacesUtils.bhistory.removeAllPages();
SimpleTest.finish();
waitForClearHistory(SimpleTest.finish);
}
/**
* Clears history invoking callback when done.
*/
function waitForClearHistory(aCallback) {
const TOPIC_EXPIRATION_FINISHED = "places-expiration-finished";
let observer = {
observe: function(aSubject, aTopic, aData) {
Services.obs.removeObserver(this, TOPIC_EXPIRATION_FINISHED);
aCallback();
}
};
Services.obs.addObserver(observer, TOPIC_EXPIRATION_FINISHED, false);
let hs = Cc["@mozilla.org/browser/nav-history-service;1"].
getService(Ci.nsINavHistoryService);
hs.QueryInterface(Ci.nsIBrowserHistory).removeAllPages();
}
]]></script>
</window>

View File

@ -0,0 +1,100 @@
<?xml version="1.0"?>
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/licenses/publicdomain/
-->
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
type="text/css"?>
<?xml-stylesheet href="chrome://browser/content/places/places.css"?>
<?xml-stylesheet href="chrome://browser/skin/places/places.css"?>
<?xul-overlay href="chrome://browser/content/places/placesOverlay.xul"?>
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="549491: 'The root node is never visible' exception when details of the root node are modified "
onload="runTest();">
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js" />
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
<body xmlns="http://www.w3.org/1999/xhtml" />
<tree id="tree"
type="places"
flatList="true"
flex="1">
<treecols>
<treecol label="Title" id="title" anonid="title" primary="true" ordinal="1" flex="1"/>
<splitter class="tree-splitter"/>
<treecol label="Date" anonid="date" flex="1"/>
</treecols>
<treechildren flex="1"/>
</tree>
<script type="application/javascript"><![CDATA[
/**
* Bug 549491
* https://bugzilla.mozilla.org/show_bug.cgi?id=549491
*
* Ensures that changing the details of places tree's root-node doesn't
* throw.
*/
SimpleTest.waitForExplicitFinish();
function runTest() {
// The mochitest page is added to history.
waitForClearHistory(continue_test);
}
function continue_test() {
const Cc = Components.classes;
const Ci = Components.interfaces;
Components.utils.import("resource://gre/modules/Services.jsm");
PlacesUtils.history
.addVisit(Services.io.newURI("http://example.tld/", null, null),
Date.now() * 1000, null, PlacesUtils.history.TRANSITION_TYPED, false, 0);
// Make a history query.
let query = PlacesUtils.history.getNewQuery();
let opts = PlacesUtils.history.getNewQueryOptions();
let queryURI = PlacesUtils.history.queriesToQueryString([query], 1, opts);
// Setup the places tree contents.
let tree = document.getElementById("tree");
tree.place = queryURI;
let rootNode = tree.result.root;
let obs = tree.view.QueryInterface(Ci.nsINavHistoryResultObserver);
obs.nodeHistoryDetailsChanged(rootNode, rootNode.time, rootNode.accessCount);
obs.nodeTitleChanged(rootNode, rootNode.title);
ok(true, "No exceptions thrown");
// Cleanup.
waitForClearHistory(SimpleTest.finish);
}
/**
* Clears history invoking callback when done.
*/
function waitForClearHistory(aCallback) {
const TOPIC_EXPIRATION_FINISHED = "places-expiration-finished";
let observer = {
observe: function(aSubject, aTopic, aData) {
Services.obs.removeObserver(this, TOPIC_EXPIRATION_FINISHED);
aCallback();
}
};
Services.obs.addObserver(observer, TOPIC_EXPIRATION_FINISHED, false);
let hs = Cc["@mozilla.org/browser/nav-history-service;1"].
getService(Ci.nsINavHistoryService);
hs.QueryInterface(Ci.nsIBrowserHistory).removeAllPages();
}
]]></script>
</window>

View File

@ -86,6 +86,11 @@
SimpleTest.waitForExplicitFinish();
function runTest() {
// The mochitest page is added to history.
waitForClearHistory(continue_test);
}
function continue_test() {
const Cc = Components.classes;
const Ci = Components.interfaces;
@ -109,9 +114,6 @@
midnight.setSeconds(0);
midnight.setMilliseconds(0);
// Cleanup.
bh.removeAllPages();
// Add a visit 1ms before midnight.
hs.addVisit(uri("http://before.midnight.com/"),
(midnight.getTime() - 1) * 1000,
@ -196,11 +198,26 @@
}
// Cleanup.
bs.removeItem(itemId);
bh.removeAllPages();
SimpleTest.finish();
waitForClearHistory(SimpleTest.finish);
}
/**
* Clears history invoking callback when done.
*/
function waitForClearHistory(aCallback) {
const TOPIC_EXPIRATION_FINISHED = "places-expiration-finished";
let observer = {
observe: function(aSubject, aTopic, aData) {
Services.obs.removeObserver(this, TOPIC_EXPIRATION_FINISHED);
aCallback();
}
};
Services.obs.addObserver(observer, TOPIC_EXPIRATION_FINISHED, false);
let hs = Cc["@mozilla.org/browser/nav-history-service;1"].
getService(Ci.nsINavHistoryService);
hs.QueryInterface(Ci.nsIBrowserHistory).removeAllPages();
}
]]>
</script>
</window>

View File

@ -159,6 +159,10 @@
<!ENTITY errorConsoleCmd.accesskey "C">
<!ENTITY errorConsoleCmd.commandkey "j">
<!ENTITY hudConsoleCmd.label "Heads Up Display">
<!ENTITY hudConsoleCmd.accesskey "U">
<!ENTITY hudConsoleCmd.commandkey "k">
<!ENTITY inspectMenu.label "Inspect">
<!ENTITY inspectMenu.accesskey "T">
<!ENTITY inspectMenu.commandkey "I">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 11 KiB

File diff suppressed because it is too large Load Diff

View File

@ -37,6 +37,7 @@ browser.jar:
skin/classic/browser/Popup-blocked.png
skin/classic/browser/Privacy-16.png
skin/classic/browser/Privacy-48.png
skin/classic/browser/searchbar-dropmarker.png
skin/classic/browser/searchbar.css
skin/classic/browser/Search.png
skin/classic/browser/Search-addengines.png
@ -47,6 +48,7 @@ browser.jar:
skin/classic/browser/Secure-statusbar-broken.png
skin/classic/browser/Secure-background.gif
skin/classic/browser/Toolbar.png
skin/classic/browser/toolbarbutton-dropmarker.png
skin/classic/browser/urlbar-favicon-glow.png
skin/classic/browser/feeds/subscribe.css (feeds/subscribe.css)
skin/classic/browser/feeds/feedIcon.png (feeds/feedIcon.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 B

View File

@ -1,38 +1,44 @@
.searchbar-engine-image {
width: 16px;
height: 16px;
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
-moz-margin-start: 3px;
.searchbar-textbox {
-moz-border-radius: 100%;
}
.searchbar-engine-button {
-moz-padding-start: 6px;
-moz-padding-end: 2px;
margin: 0;
-moz-margin-end: 2px;
-moz-appearance: none;
min-width: 0;
}
.searchbar-engine-button > .button-box {
-moz-appearance: none;
padding: 0;
-moz-padding-end: 3px;
border: 0;
}
.searchbar-engine-button[addengines="true"] > .button-box {
.searchbar-engine-button[addengines="true"] {
background: transparent url(chrome://browser/skin/Search-addengines.png) no-repeat right center;
}
.searchbar-textbox:-moz-locale-dir(rtl) .searchbar-engine-button[addengines="true"] > .button-box {
.searchbar-engine-button[addengines="true"]:-moz-locale-dir(rtl) {
background-position: left center;
}
.searchbar-textbox > .autocomplete-textbox-container > .textbox-input-box {
margin: 0;
padding: 3px 0 2px;
height: 20px;
}
.searchbar-engine-image {
width: 16px;
height: 16px;
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
}
.searchbar-dropmarker-image {
list-style-image: url("chrome://global/skin/arrow/arrow-dn.png");
list-style-image: url("chrome://browser/skin/searchbar-dropmarker.png");
-moz-margin-start: 2px;
margin-top: 1px;
}
.search-go-container {
-moz-box-align: center;
-moz-padding-end: 6px;
}
.search-go-button {

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 B

View File

@ -24,6 +24,11 @@
background: transparent;
}
#main-window:not(:-moz-lwtheme)[inFullscreen="true"] {
-moz-appearance: none;
background-color: #556;
}
#toolbar-menubar:not(:-moz-lwtheme),
#navigator-toolbox[tabsontop="true"] > #TabsToolbar:not(:-moz-lwtheme),
#navigator-toolbox:not([tabsontop="true"]) > #nav-bar:not(:-moz-lwtheme),

View File

@ -6703,7 +6703,7 @@ else
dnl === SQLITE_ENABLE_FTS3 check ===
dnl ================================
dnl check to see if the system SQLite package is compiled with
dnl SQLITE_THREADSAFE enabled.
dnl SQLITE_ENABLE_FTS3 enabled.
AC_MSG_CHECKING(for SQLITE_ENABLE_FTS3 support in system SQLite)
_SAVE_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $SQLITE_CFLAGS"
@ -6727,6 +6727,35 @@ else
if test "x$ac_cv_sqlite_enable_fts3" = "xno"; then
AC_MSG_ERROR([System SQLite library is not compiled with SQLITE_ENABLE_FTS3.])
fi
dnl =========================================
dnl === SQLITE_ENABLE_UNLOCK_NOTIFY check ===
dnl =========================================
dnl check to see if the system SQLite package is compiled with
dnl SQLITE_ENABLE_UNLOCK_NOTIFY enabled.
AC_MSG_CHECKING(for SQLITE_ENABLE_UNLOCK_NOTIFY support in system SQLite)
_SAVE_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $SQLITE_CFLAGS"
_SAVE_LIBS="$LIBS"
LIBS="$LIBS $SQLITE_LIBS"
AC_CACHE_VAL(ac_cv_sqlite_enable_unlock_notify,[
AC_TRY_RUN([
#include "sqlite3.h"
int main(int argc, char **argv){
return !sqlite3_compileoption_used("SQLITE_ENABLE_UNLOCK_NOTIFY");
}],
ac_cv_sqlite_enable_unlock_notify=yes,
ac_cv_sqlite_enable_unlock_notify=no,
ac_cv_sqlite_enable_unlock_notify=no
)
])
AC_MSG_RESULT($ac_cv_sqlite_enable_unlock_notify)
CFLAGS="$_SAVE_CFLAGS"
LIBS="$_SAVE_LIBS"
if test "x$ac_cv_sqlite_enable_unlock_notify" = "xno"; then
AC_MSG_ERROR([System SQLite library is not compiled with SQLITE_ENABLE_UNLOCK_NOTIFY.])
fi
fi
AC_SUBST(MOZ_NATIVE_SQLITE)

View File

@ -162,9 +162,12 @@ enum EventNameType {
EventNameType_All = 0xFFFF
};
struct EventNameMapping {
PRUint32 mId;
PRInt32 mType;
struct EventNameMapping
{
nsIAtom* mAtom;
PRUint32 mId;
PRInt32 mType;
PRUint32 mStructType;
};
struct nsShortcutCandidate {
@ -955,6 +958,19 @@ public:
*/
static PRUint32 GetEventId(nsIAtom* aName);
/**
* Return the event id and atom for the event with the given name.
* The name is the event name *without* the 'on' prefix.
* Returns NS_USER_DEFINED_EVENT on the aEventID if the
* event doesn't match a known event name in the category.
*
* @param aName the event name to look up
* @param aEventStruct only return event id in aEventStruct category
*/
static nsIAtom* GetEventIdAndAtom(const nsAString& aName,
PRUint32 aEventStruct,
PRUint32* aEventID);
/**
* Used only during traversal of the XPCOM graph by the cycle
* collector: push a pointer to the listener manager onto the
@ -1669,7 +1685,9 @@ private:
static nsIConsoleService* sConsoleService;
static nsDataHashtable<nsISupportsHashKey, EventNameMapping>* sEventTable;
static nsDataHashtable<nsISupportsHashKey, EventNameMapping>* sAtomEventTable;
static nsDataHashtable<nsStringHashKey, EventNameMapping>* sStringEventTable;
static nsCOMArray<nsIAtom>* sUserDefinedEvents;
static nsIStringBundleService* sStringBundleService;
static nsIStringBundle* sStringBundles[PropertiesFile_COUNT];

View File

@ -230,7 +230,9 @@ imgILoader *nsContentUtils::sImgLoader;
imgICache *nsContentUtils::sImgCache;
mozilla::IHistory *nsContentUtils::sHistory;
nsIConsoleService *nsContentUtils::sConsoleService;
nsDataHashtable<nsISupportsHashKey, EventNameMapping>* nsContentUtils::sEventTable = nsnull;
nsDataHashtable<nsISupportsHashKey, EventNameMapping>* nsContentUtils::sAtomEventTable = nsnull;
nsDataHashtable<nsStringHashKey, EventNameMapping>* nsContentUtils::sStringEventTable = nsnull;
nsCOMArray<nsIAtom>* nsContentUtils::sUserDefinedEvents = nsnull;
nsIStringBundleService *nsContentUtils::sStringBundleService;
nsIStringBundle *nsContentUtils::sStringBundles[PropertiesFile_COUNT];
nsIContentPolicy *nsContentUtils::sContentPolicyService;
@ -462,151 +464,174 @@ nsContentUtils::Init()
PRBool
nsContentUtils::InitializeEventTable() {
NS_ASSERTION(!sEventTable, "EventTable already initialized!");
NS_ASSERTION(!sAtomEventTable, "EventTable already initialized!");
NS_ASSERTION(!sStringEventTable, "EventTable already initialized!");
struct EventItem
{
nsIAtom** mAtom;
EventNameMapping mValue;
};
static const EventNameMapping eventArray[] = {
{ nsGkAtoms::onmousedown, NS_MOUSE_BUTTON_DOWN, EventNameType_All, NS_MOUSE_EVENT },
{ nsGkAtoms::onmouseup, NS_MOUSE_BUTTON_UP, EventNameType_All, NS_MOUSE_EVENT },
{ nsGkAtoms::onclick, NS_MOUSE_CLICK, EventNameType_All, NS_MOUSE_EVENT },
{ nsGkAtoms::ondblclick, NS_MOUSE_DOUBLECLICK, EventNameType_HTMLXUL, NS_MOUSE_EVENT },
{ nsGkAtoms::onmouseover, NS_MOUSE_ENTER_SYNTH, EventNameType_All, NS_MOUSE_EVENT },
{ nsGkAtoms::onmouseout, NS_MOUSE_EXIT_SYNTH, EventNameType_All, NS_MOUSE_EVENT },
{ nsGkAtoms::onmousemove, NS_MOUSE_MOVE, EventNameType_All, NS_MOUSE_EVENT },
{ nsGkAtoms::oncontextmenu, NS_CONTEXTMENU, EventNameType_HTMLXUL, NS_MOUSE_EVENT },
static const EventItem eventArray[] = {
{ &nsGkAtoms::onmousedown, { NS_MOUSE_BUTTON_DOWN, EventNameType_All }},
{ &nsGkAtoms::onmouseup, { NS_MOUSE_BUTTON_UP, EventNameType_All }},
{ &nsGkAtoms::onclick, { NS_MOUSE_CLICK, EventNameType_All }},
{ &nsGkAtoms::ondblclick, { NS_MOUSE_DOUBLECLICK, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onmouseover, { NS_MOUSE_ENTER_SYNTH, EventNameType_All }},
{ &nsGkAtoms::onmouseout, { NS_MOUSE_EXIT_SYNTH, EventNameType_All }},
{ &nsGkAtoms::onmousemove, { NS_MOUSE_MOVE, EventNameType_All }},
{ &nsGkAtoms::oncontextmenu, { NS_CONTEXTMENU, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onkeydown, { NS_KEY_DOWN, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onkeyup, { NS_KEY_UP, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onkeypress, { NS_KEY_PRESS, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onfocus, { NS_FOCUS_CONTENT, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onblur, { NS_BLUR_CONTENT, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onoffline, { NS_OFFLINE, EventNameType_HTMLXUL }},
{ &nsGkAtoms::ononline, { NS_ONLINE, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onsubmit, { NS_FORM_SUBMIT, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onreset, { NS_FORM_RESET, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onchange, { NS_FORM_CHANGE, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onselect, { NS_FORM_SELECTED, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onload, { NS_LOAD, EventNameType_All }},
{ &nsGkAtoms::onpopstate, { NS_POPSTATE, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onunload, { NS_PAGE_UNLOAD,
(EventNameType_HTMLXUL | EventNameType_SVGSVG) }},
{ &nsGkAtoms::onhashchange, { NS_HASHCHANGE, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onbeforeunload, { NS_BEFORE_PAGE_UNLOAD, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onabort, { NS_IMAGE_ABORT,
(EventNameType_HTMLXUL | EventNameType_SVGSVG) }},
{ &nsGkAtoms::onerror, { NS_LOAD_ERROR,
(EventNameType_HTMLXUL | EventNameType_SVGSVG) }},
{ &nsGkAtoms::onDOMAttrModified, { NS_MUTATION_ATTRMODIFIED, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onDOMCharacterDataModified, { NS_MUTATION_CHARACTERDATAMODIFIED, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onDOMNodeInserted, { NS_MUTATION_NODEINSERTED, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onDOMNodeRemoved, { NS_MUTATION_NODEREMOVED, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onDOMNodeInsertedIntoDocument, { NS_MUTATION_NODEINSERTEDINTODOCUMENT, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onDOMNodeRemovedFromDocument, { NS_MUTATION_NODEREMOVEDFROMDOCUMENT, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onDOMSubtreeModified, { NS_MUTATION_SUBTREEMODIFIED, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onDOMActivate, { NS_UI_ACTIVATE, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onDOMFocusIn, { NS_UI_FOCUSIN, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onDOMFocusOut, { NS_UI_FOCUSOUT, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onDOMMouseScroll, { NS_MOUSE_SCROLL, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onMozMousePixelScroll, { NS_MOUSE_PIXEL_SCROLL, EventNameType_HTMLXUL }},
{ &nsGkAtoms::oninput, { NS_FORM_INPUT, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onpageshow, { NS_PAGE_SHOW, EventNameType_HTML }},
{ &nsGkAtoms::onpagehide, { NS_PAGE_HIDE, EventNameType_HTML }},
{ &nsGkAtoms::onresize, { NS_RESIZE_EVENT,
(EventNameType_HTMLXUL | EventNameType_SVGSVG) }},
{ &nsGkAtoms::onscroll, { NS_SCROLL_EVENT,
(EventNameType_HTMLXUL | EventNameType_SVGSVG) }},
{ &nsGkAtoms::oncopy, { NS_COPY, EventNameType_HTMLXUL }},
{ &nsGkAtoms::oncut, { NS_CUT, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onpaste, { NS_PASTE, EventNameType_HTMLXUL }},
{ nsGkAtoms::onkeydown, NS_KEY_DOWN, EventNameType_HTMLXUL, NS_KEY_EVENT },
{ nsGkAtoms::onkeyup, NS_KEY_UP, EventNameType_HTMLXUL, NS_KEY_EVENT },
{ nsGkAtoms::onkeypress, NS_KEY_PRESS, EventNameType_HTMLXUL, NS_KEY_EVENT },
{ nsGkAtoms::onfocus, NS_FOCUS_CONTENT, EventNameType_HTMLXUL, NS_FOCUS_EVENT },
{ nsGkAtoms::onblur, NS_BLUR_CONTENT, EventNameType_HTMLXUL, NS_FOCUS_EVENT },
{ nsGkAtoms::onoffline, NS_OFFLINE, EventNameType_HTMLXUL, NS_EVENT },
{ nsGkAtoms::ononline, NS_ONLINE, EventNameType_HTMLXUL, NS_EVENT },
{ nsGkAtoms::onsubmit, NS_FORM_SUBMIT, EventNameType_HTMLXUL, NS_EVENT },
{ nsGkAtoms::onreset, NS_FORM_RESET, EventNameType_HTMLXUL, NS_EVENT },
{ nsGkAtoms::onchange, NS_FORM_CHANGE, EventNameType_HTMLXUL, NS_EVENT },
{ nsGkAtoms::onselect, NS_FORM_SELECTED, EventNameType_HTMLXUL, NS_EVENT },
{ nsGkAtoms::onload, NS_LOAD, EventNameType_All, NS_EVENT },
{ nsGkAtoms::onpopstate, NS_POPSTATE, EventNameType_HTMLXUL, NS_EVENT_NULL },
{ nsGkAtoms::onunload, NS_PAGE_UNLOAD,
(EventNameType_HTMLXUL | EventNameType_SVGSVG), NS_EVENT },
{ nsGkAtoms::onhashchange, NS_HASHCHANGE, EventNameType_HTMLXUL, NS_EVENT },
{ nsGkAtoms::onbeforeunload, NS_BEFORE_PAGE_UNLOAD, EventNameType_HTMLXUL, NS_EVENT },
{ nsGkAtoms::onabort, NS_IMAGE_ABORT,
(EventNameType_HTMLXUL | EventNameType_SVGSVG), NS_EVENT },
{ nsGkAtoms::onerror, NS_LOAD_ERROR,
(EventNameType_HTMLXUL | EventNameType_SVGSVG), NS_EVENT },
{ nsGkAtoms::onDOMAttrModified, NS_MUTATION_ATTRMODIFIED, EventNameType_HTMLXUL, NS_MUTATION_EVENT },
{ nsGkAtoms::onDOMCharacterDataModified, NS_MUTATION_CHARACTERDATAMODIFIED, EventNameType_HTMLXUL, NS_MUTATION_EVENT },
{ nsGkAtoms::onDOMNodeInserted, NS_MUTATION_NODEINSERTED, EventNameType_HTMLXUL, NS_MUTATION_EVENT },
{ nsGkAtoms::onDOMNodeRemoved, NS_MUTATION_NODEREMOVED, EventNameType_HTMLXUL, NS_MUTATION_EVENT },
{ nsGkAtoms::onDOMNodeInsertedIntoDocument, NS_MUTATION_NODEINSERTEDINTODOCUMENT, EventNameType_HTMLXUL, NS_MUTATION_EVENT },
{ nsGkAtoms::onDOMNodeRemovedFromDocument, NS_MUTATION_NODEREMOVEDFROMDOCUMENT, EventNameType_HTMLXUL, NS_MUTATION_EVENT },
{ nsGkAtoms::onDOMSubtreeModified, NS_MUTATION_SUBTREEMODIFIED, EventNameType_HTMLXUL, NS_MUTATION_EVENT },
{ nsGkAtoms::onDOMActivate, NS_UI_ACTIVATE, EventNameType_HTMLXUL, NS_UI_EVENT },
{ nsGkAtoms::onDOMFocusIn, NS_UI_FOCUSIN, EventNameType_HTMLXUL, NS_UI_EVENT },
{ nsGkAtoms::onDOMFocusOut, NS_UI_FOCUSOUT, EventNameType_HTMLXUL, NS_UI_EVENT },
{ nsGkAtoms::oninput, NS_FORM_INPUT, EventNameType_HTMLXUL, NS_UI_EVENT },
{ nsGkAtoms::onDOMMouseScroll, NS_MOUSE_SCROLL, EventNameType_HTMLXUL, NS_MOUSE_SCROLL_EVENT },
{ nsGkAtoms::onMozMousePixelScroll, NS_MOUSE_PIXEL_SCROLL, EventNameType_HTMLXUL, NS_MOUSE_SCROLL_EVENT },
{ nsGkAtoms::onpageshow, NS_PAGE_SHOW, EventNameType_HTML, NS_EVENT },
{ nsGkAtoms::onpagehide, NS_PAGE_HIDE, EventNameType_HTML, NS_EVENT },
{ nsGkAtoms::onresize, NS_RESIZE_EVENT,
(EventNameType_HTMLXUL | EventNameType_SVGSVG), NS_EVENT },
{ nsGkAtoms::onscroll, NS_SCROLL_EVENT,
(EventNameType_HTMLXUL | EventNameType_SVGSVG), NS_EVENT_NULL },
{ nsGkAtoms::oncopy, NS_COPY, EventNameType_HTMLXUL, NS_EVENT },
{ nsGkAtoms::oncut, NS_CUT, EventNameType_HTMLXUL, NS_EVENT },
{ nsGkAtoms::onpaste, NS_PASTE, EventNameType_HTMLXUL, NS_EVENT },
// XUL specific events
{ &nsGkAtoms::ontext, { NS_TEXT_TEXT, EventNameType_XUL }},
{ &nsGkAtoms::oncompositionstart, { NS_COMPOSITION_START, EventNameType_XUL }},
{ &nsGkAtoms::oncompositionend, { NS_COMPOSITION_END, EventNameType_XUL }},
{ &nsGkAtoms::onclose, { NS_XUL_CLOSE, EventNameType_XUL }},
{ &nsGkAtoms::onpopupshowing, { NS_XUL_POPUP_SHOWING, EventNameType_XUL }},
{ &nsGkAtoms::onpopupshown, { NS_XUL_POPUP_SHOWN, EventNameType_XUL }},
{ &nsGkAtoms::onpopuphiding, { NS_XUL_POPUP_HIDING, EventNameType_XUL }},
{ &nsGkAtoms::onpopuphidden, { NS_XUL_POPUP_HIDDEN, EventNameType_XUL }},
{ &nsGkAtoms::oncommand, { NS_XUL_COMMAND, EventNameType_XUL }},
{ &nsGkAtoms::onbroadcast, { NS_XUL_BROADCAST, EventNameType_XUL }},
{ &nsGkAtoms::oncommandupdate, { NS_XUL_COMMAND_UPDATE, EventNameType_XUL }},
{ &nsGkAtoms::ondragenter, { NS_DRAGDROP_ENTER, EventNameType_HTMLXUL }},
{ &nsGkAtoms::ondragover, { NS_DRAGDROP_OVER_SYNTH, EventNameType_HTMLXUL }},
{ &nsGkAtoms::ondragexit, { NS_DRAGDROP_EXIT_SYNTH, EventNameType_XUL }},
{ &nsGkAtoms::ondragdrop, { NS_DRAGDROP_DRAGDROP, EventNameType_XUL }},
{ &nsGkAtoms::ondraggesture, { NS_DRAGDROP_GESTURE, EventNameType_XUL }},
{ &nsGkAtoms::ondrag, { NS_DRAGDROP_DRAG, EventNameType_HTMLXUL }},
{ &nsGkAtoms::ondragend, { NS_DRAGDROP_END, EventNameType_HTMLXUL }},
{ &nsGkAtoms::ondragstart, { NS_DRAGDROP_START, EventNameType_HTMLXUL }},
{ &nsGkAtoms::ondragleave, { NS_DRAGDROP_LEAVE_SYNTH, EventNameType_HTMLXUL }},
{ &nsGkAtoms::ondrop, { NS_DRAGDROP_DROP, EventNameType_HTMLXUL }},
{ &nsGkAtoms::onoverflow, { NS_SCROLLPORT_OVERFLOW, EventNameType_XUL }},
{ &nsGkAtoms::onunderflow, { NS_SCROLLPORT_UNDERFLOW, EventNameType_XUL }},
{ nsGkAtoms::ontext, NS_TEXT_TEXT, EventNameType_XUL, NS_EVENT_NULL },
{ nsGkAtoms::oncompositionstart, NS_COMPOSITION_START, EventNameType_XUL, NS_COMPOSITION_EVENT },
{ nsGkAtoms::oncompositionend, NS_COMPOSITION_END, EventNameType_XUL, NS_COMPOSITION_EVENT },
{ nsGkAtoms::oncommand, NS_XUL_COMMAND, EventNameType_XUL, NS_INPUT_EVENT },
{ nsGkAtoms::onclose, NS_XUL_CLOSE, EventNameType_XUL, NS_EVENT_NULL},
{ nsGkAtoms::onpopupshowing, NS_XUL_POPUP_SHOWING, EventNameType_XUL, NS_EVENT_NULL},
{ nsGkAtoms::onpopupshown, NS_XUL_POPUP_SHOWN, EventNameType_XUL, NS_EVENT_NULL},
{ nsGkAtoms::onpopuphiding, NS_XUL_POPUP_HIDING, EventNameType_XUL, NS_EVENT_NULL},
{ nsGkAtoms::onpopuphidden, NS_XUL_POPUP_HIDDEN, EventNameType_XUL, NS_EVENT_NULL},
{ nsGkAtoms::onbroadcast, NS_XUL_BROADCAST, EventNameType_XUL, NS_EVENT_NULL},
{ nsGkAtoms::oncommandupdate, NS_XUL_COMMAND_UPDATE, EventNameType_XUL, NS_EVENT_NULL},
{ nsGkAtoms::ondragenter, NS_DRAGDROP_ENTER, EventNameType_HTMLXUL, NS_DRAG_EVENT },
{ nsGkAtoms::ondragover, NS_DRAGDROP_OVER_SYNTH, EventNameType_HTMLXUL, NS_DRAG_EVENT },
{ nsGkAtoms::ondragexit, NS_DRAGDROP_EXIT_SYNTH, EventNameType_XUL, NS_DRAG_EVENT },
{ nsGkAtoms::ondragdrop, NS_DRAGDROP_DRAGDROP, EventNameType_XUL, NS_DRAG_EVENT },
{ nsGkAtoms::ondraggesture, NS_DRAGDROP_GESTURE, EventNameType_XUL, NS_DRAG_EVENT },
{ nsGkAtoms::ondrag, NS_DRAGDROP_DRAG, EventNameType_HTMLXUL, NS_DRAG_EVENT },
{ nsGkAtoms::ondragend, NS_DRAGDROP_END, EventNameType_HTMLXUL, NS_DRAG_EVENT },
{ nsGkAtoms::ondragstart, NS_DRAGDROP_START, EventNameType_HTMLXUL, NS_DRAG_EVENT },
{ nsGkAtoms::ondragleave, NS_DRAGDROP_LEAVE_SYNTH, EventNameType_HTMLXUL, NS_DRAG_EVENT },
{ nsGkAtoms::ondrop, NS_DRAGDROP_DROP, EventNameType_HTMLXUL, NS_DRAG_EVENT },
{ nsGkAtoms::onoverflow, NS_SCROLLPORT_OVERFLOW, EventNameType_XUL, NS_EVENT_NULL},
{ nsGkAtoms::onunderflow, NS_SCROLLPORT_UNDERFLOW, EventNameType_XUL, NS_EVENT_NULL},
#ifdef MOZ_SVG
{ &nsGkAtoms::onSVGLoad, { NS_SVG_LOAD, EventNameType_None }},
{ &nsGkAtoms::onSVGUnload, { NS_SVG_UNLOAD, EventNameType_None }},
{ &nsGkAtoms::onSVGAbort, { NS_SVG_ABORT, EventNameType_None }},
{ &nsGkAtoms::onSVGError, { NS_SVG_ERROR, EventNameType_None }},
{ &nsGkAtoms::onSVGResize, { NS_SVG_RESIZE, EventNameType_None }},
{ &nsGkAtoms::onSVGScroll, { NS_SVG_SCROLL, EventNameType_None }},
{ &nsGkAtoms::onSVGZoom, { NS_SVG_ZOOM, EventNameType_None }},
{ &nsGkAtoms::onzoom, { NS_SVG_ZOOM, EventNameType_SVGSVG }},
{ nsGkAtoms::onSVGLoad, NS_SVG_LOAD, EventNameType_None, NS_SVG_EVENT },
{ nsGkAtoms::onSVGUnload, NS_SVG_UNLOAD, EventNameType_None, NS_SVG_EVENT },
{ nsGkAtoms::onSVGAbort, NS_SVG_ABORT, EventNameType_None, NS_SVG_EVENT },
{ nsGkAtoms::onSVGError, NS_SVG_ERROR, EventNameType_None, NS_SVG_EVENT },
{ nsGkAtoms::onSVGResize, NS_SVG_RESIZE, EventNameType_None, NS_SVG_EVENT },
{ nsGkAtoms::onSVGScroll, NS_SVG_SCROLL, EventNameType_None, NS_SVG_EVENT },
{ nsGkAtoms::onSVGZoom, NS_SVG_ZOOM, EventNameType_None, NS_SVGZOOM_EVENT },
// This is a bit hackish, but SVG's event names are weird.
{ nsGkAtoms::onzoom, NS_SVG_ZOOM, EventNameType_SVGSVG, NS_EVENT_NULL },
#endif // MOZ_SVG
#ifdef MOZ_MEDIA
{ &nsGkAtoms::onloadstart, { NS_LOADSTART, EventNameType_HTML }},
{ &nsGkAtoms::onprogress, { NS_PROGRESS, EventNameType_HTML }},
{ &nsGkAtoms::onsuspend, { NS_SUSPEND, EventNameType_HTML }},
{ &nsGkAtoms::onemptied, { NS_EMPTIED, EventNameType_HTML }},
{ &nsGkAtoms::onstalled, { NS_STALLED, EventNameType_HTML }},
{ &nsGkAtoms::onplay, { NS_PLAY, EventNameType_HTML }},
{ &nsGkAtoms::onpause, { NS_PAUSE, EventNameType_HTML }},
{ &nsGkAtoms::onloadedmetadata, { NS_LOADEDMETADATA, EventNameType_HTML }},
{ &nsGkAtoms::onloadeddata, { NS_LOADEDDATA, EventNameType_HTML }},
{ &nsGkAtoms::onwaiting, { NS_WAITING, EventNameType_HTML }},
{ &nsGkAtoms::onplaying, { NS_PLAYING, EventNameType_HTML }},
{ &nsGkAtoms::oncanplay, { NS_CANPLAY, EventNameType_HTML }},
{ &nsGkAtoms::oncanplaythrough, { NS_CANPLAYTHROUGH, EventNameType_HTML }},
{ &nsGkAtoms::onseeking, { NS_SEEKING, EventNameType_HTML }},
{ &nsGkAtoms::onseeked, { NS_SEEKED, EventNameType_HTML }},
{ &nsGkAtoms::ontimeupdate, { NS_TIMEUPDATE, EventNameType_HTML }},
{ &nsGkAtoms::onended, { NS_ENDED, EventNameType_HTML }},
{ &nsGkAtoms::onratechange, { NS_RATECHANGE, EventNameType_HTML }},
{ &nsGkAtoms::ondurationchange, { NS_DURATIONCHANGE, EventNameType_HTML }},
{ &nsGkAtoms::onvolumechange, { NS_VOLUMECHANGE, EventNameType_HTML }},
#endif //MOZ_MEDIA
{ &nsGkAtoms::onMozAfterPaint, { NS_AFTERPAINT, EventNameType_None }},
{ &nsGkAtoms::onMozScrolledAreaChanged, { NS_SCROLLEDAREACHANGED, EventNameType_None }},
#ifdef MOZ_MEDIA
{ nsGkAtoms::onloadstart, NS_LOADSTART, EventNameType_HTML, NS_EVENT_NULL },
{ nsGkAtoms::onprogress, NS_PROGRESS, EventNameType_HTML, NS_EVENT_NULL },
{ nsGkAtoms::onsuspend, NS_SUSPEND, EventNameType_HTML, NS_EVENT_NULL },
{ nsGkAtoms::onemptied, NS_EMPTIED, EventNameType_HTML, NS_EVENT_NULL },
{ nsGkAtoms::onstalled, NS_STALLED, EventNameType_HTML, NS_EVENT_NULL },
{ nsGkAtoms::onplay, NS_PLAY, EventNameType_HTML, NS_EVENT_NULL },
{ nsGkAtoms::onpause, NS_PAUSE, EventNameType_HTML, NS_EVENT_NULL },
{ nsGkAtoms::onloadedmetadata, NS_LOADEDMETADATA, EventNameType_HTML, NS_EVENT_NULL },
{ nsGkAtoms::onloadeddata, NS_LOADEDDATA, EventNameType_HTML, NS_EVENT_NULL },
{ nsGkAtoms::onwaiting, NS_WAITING, EventNameType_HTML, NS_EVENT_NULL },
{ nsGkAtoms::onplaying, NS_PLAYING, EventNameType_HTML, NS_EVENT_NULL },
{ nsGkAtoms::oncanplay, NS_CANPLAY, EventNameType_HTML, NS_EVENT_NULL },
{ nsGkAtoms::oncanplaythrough, NS_CANPLAYTHROUGH, EventNameType_HTML, NS_EVENT_NULL },
{ nsGkAtoms::onseeking, NS_SEEKING, EventNameType_HTML, NS_EVENT_NULL },
{ nsGkAtoms::onseeked, NS_SEEKED, EventNameType_HTML, NS_EVENT_NULL },
{ nsGkAtoms::ontimeupdate, NS_TIMEUPDATE, EventNameType_HTML, NS_EVENT_NULL },
{ nsGkAtoms::onended, NS_ENDED, EventNameType_HTML, NS_EVENT_NULL },
{ nsGkAtoms::onratechange, NS_RATECHANGE, EventNameType_HTML, NS_EVENT_NULL },
{ nsGkAtoms::ondurationchange, NS_DURATIONCHANGE, EventNameType_HTML, NS_EVENT_NULL },
{ nsGkAtoms::onvolumechange, NS_VOLUMECHANGE, EventNameType_HTML, NS_EVENT_NULL },
#endif // MOZ_MEDIA
{ nsGkAtoms::onMozAfterPaint, NS_AFTERPAINT, EventNameType_None, NS_EVENT },
{ nsGkAtoms::onMozScrolledAreaChanged, NS_SCROLLEDAREACHANGED, EventNameType_None, NS_SCROLLAREA_EVENT },
// Simple gesture events
{ &nsGkAtoms::onMozSwipeGesture, { NS_SIMPLE_GESTURE_SWIPE, EventNameType_None } },
{ &nsGkAtoms::onMozMagnifyGestureStart, { NS_SIMPLE_GESTURE_MAGNIFY_START, EventNameType_None } },
{ &nsGkAtoms::onMozMagnifyGestureUpdate, { NS_SIMPLE_GESTURE_MAGNIFY_UPDATE, EventNameType_None } },
{ &nsGkAtoms::onMozMagnifyGesture, { NS_SIMPLE_GESTURE_MAGNIFY, EventNameType_None } },
{ &nsGkAtoms::onMozRotateGestureStart, { NS_SIMPLE_GESTURE_ROTATE_START, EventNameType_None } },
{ &nsGkAtoms::onMozRotateGestureUpdate, { NS_SIMPLE_GESTURE_ROTATE_UPDATE, EventNameType_None } },
{ &nsGkAtoms::onMozRotateGesture, { NS_SIMPLE_GESTURE_ROTATE, EventNameType_None } },
{ &nsGkAtoms::onMozTapGesture, { NS_SIMPLE_GESTURE_TAP, EventNameType_None } },
{ &nsGkAtoms::onMozPressTapGesture, { NS_SIMPLE_GESTURE_PRESSTAP, EventNameType_None } },
{ nsGkAtoms::onMozSwipeGesture, NS_SIMPLE_GESTURE_SWIPE, EventNameType_None, NS_SIMPLE_GESTURE_EVENT },
{ nsGkAtoms::onMozMagnifyGestureStart, NS_SIMPLE_GESTURE_MAGNIFY_START, EventNameType_None, NS_SIMPLE_GESTURE_EVENT },
{ nsGkAtoms::onMozMagnifyGestureUpdate, NS_SIMPLE_GESTURE_MAGNIFY_UPDATE, EventNameType_None, NS_SIMPLE_GESTURE_EVENT },
{ nsGkAtoms::onMozMagnifyGesture, NS_SIMPLE_GESTURE_MAGNIFY, EventNameType_None, NS_SIMPLE_GESTURE_EVENT },
{ nsGkAtoms::onMozRotateGestureStart, NS_SIMPLE_GESTURE_ROTATE_START, EventNameType_None, NS_SIMPLE_GESTURE_EVENT },
{ nsGkAtoms::onMozRotateGestureUpdate, NS_SIMPLE_GESTURE_ROTATE_UPDATE, EventNameType_None, NS_SIMPLE_GESTURE_EVENT },
{ nsGkAtoms::onMozRotateGesture, NS_SIMPLE_GESTURE_ROTATE, EventNameType_None, NS_SIMPLE_GESTURE_EVENT },
{ nsGkAtoms::onMozTapGesture, NS_SIMPLE_GESTURE_TAP, EventNameType_None, NS_SIMPLE_GESTURE_EVENT },
{ nsGkAtoms::onMozPressTapGesture, NS_SIMPLE_GESTURE_PRESSTAP, EventNameType_None, NS_SIMPLE_GESTURE_EVENT },
{ &nsGkAtoms::ontransitionend, { NS_TRANSITION_END, EventNameType_None }},
{ nsGkAtoms::ontransitionend, NS_TRANSITION_END, EventNameType_None, NS_TRANSITION_EVENT }
};
sEventTable = new nsDataHashtable<nsISupportsHashKey, EventNameMapping>;
if (!sEventTable ||
!sEventTable->Init(int(NS_ARRAY_LENGTH(eventArray) / 0.75) + 1)) {
delete sEventTable;
sEventTable = nsnull;
sAtomEventTable = new nsDataHashtable<nsISupportsHashKey, EventNameMapping>;
sStringEventTable = new nsDataHashtable<nsStringHashKey, EventNameMapping>;
sUserDefinedEvents = new nsCOMArray<nsIAtom>(64);
if (!sAtomEventTable || !sStringEventTable || !sUserDefinedEvents ||
!sAtomEventTable->Init(int(NS_ARRAY_LENGTH(eventArray) / 0.75) + 1) ||
!sStringEventTable->Init(int(NS_ARRAY_LENGTH(eventArray) / 0.75) + 1)) {
delete sAtomEventTable;
sAtomEventTable = nsnull;
delete sStringEventTable;
sStringEventTable = nsnull;
delete sUserDefinedEvents;
sUserDefinedEvents = nsnull;
return PR_FALSE;
}
for (PRUint32 i = 0; i < NS_ARRAY_LENGTH(eventArray); ++i) {
if (!sEventTable->Put(*(eventArray[i].mAtom), eventArray[i].mValue)) {
delete sEventTable;
sEventTable = nsnull;
if (!sAtomEventTable->Put(eventArray[i].mAtom, eventArray[i]) ||
!sStringEventTable->Put(Substring(nsDependentAtomString(eventArray[i].mAtom), 2),
eventArray[i])) {
delete sAtomEventTable;
sAtomEventTable = nsnull;
delete sStringEventTable;
sStringEventTable = nsnull;
return PR_FALSE;
}
}
@ -1012,8 +1037,12 @@ nsContentUtils::Shutdown()
NS_IF_RELEASE(sBidiKeyboard);
#endif
delete sEventTable;
sEventTable = nsnull;
delete sAtomEventTable;
sAtomEventTable = nsnull;
delete sStringEventTable;
sStringEventTable = nsnull;
delete sUserDefinedEvents;
sUserDefinedEvents = nsnull;
if (sPtrsToPtrsToRelease) {
for (i = 0; i < sPtrsToPtrsToRelease->Length(); ++i) {
@ -3131,7 +3160,7 @@ nsContentUtils::IsEventAttributeName(nsIAtom* aName, PRInt32 aType)
return PR_FALSE;
EventNameMapping mapping;
return (sEventTable->Get(aName, &mapping) && mapping.mType & aType);
return (sAtomEventTable->Get(aName, &mapping) && mapping.mType & aType);
}
// static
@ -3139,12 +3168,44 @@ PRUint32
nsContentUtils::GetEventId(nsIAtom* aName)
{
EventNameMapping mapping;
if (sEventTable->Get(aName, &mapping))
if (sAtomEventTable->Get(aName, &mapping))
return mapping.mId;
return NS_USER_DEFINED_EVENT;
}
nsIAtom*
nsContentUtils::GetEventIdAndAtom(const nsAString& aName,
PRUint32 aEventStruct,
PRUint32* aEventID)
{
EventNameMapping mapping;
if (sStringEventTable->Get(aName, &mapping)) {
*aEventID =
mapping.mStructType == aEventStruct ? mapping.mId : NS_USER_DEFINED_EVENT;
return mapping.mAtom;
}
// If we have cached lots of user defined event names, clear some of them.
if (sUserDefinedEvents->Count() > 127) {
while (sUserDefinedEvents->Count() > 64) {
nsIAtom* first = sUserDefinedEvents->ObjectAt(0);
sStringEventTable->Remove(Substring(nsDependentAtomString(first), 2));
sUserDefinedEvents->RemoveObjectAt(0);
}
}
*aEventID = NS_USER_DEFINED_EVENT;
nsCOMPtr<nsIAtom> atom = do_GetAtom(NS_LITERAL_STRING("on") + aName);
sUserDefinedEvents->AppendObject(atom);
mapping.mAtom = atom;
mapping.mId = NS_USER_DEFINED_EVENT;
mapping.mType = EventNameType_None;
mapping.mStructType = NS_EVENT_NULL;
sStringEventTable->Put(aName, mapping);
return mapping.mAtom;
}
static
nsresult GetEventAndTarget(nsIDocument* aDoc, nsISupports* aTarget,
const nsAString& aEventName,

View File

@ -484,235 +484,9 @@ nsDOMEvent::PreventDefault()
nsresult
nsDOMEvent::SetEventType(const nsAString& aEventTypeArg)
{
nsCOMPtr<nsIAtom> atom = do_GetAtom(NS_LITERAL_STRING("on") + aEventTypeArg);
mEvent->message = NS_USER_DEFINED_EVENT;
if (mEvent->eventStructType == NS_MOUSE_EVENT) {
if (atom == nsGkAtoms::onmousedown)
mEvent->message = NS_MOUSE_BUTTON_DOWN;
else if (atom == nsGkAtoms::onmouseup)
mEvent->message = NS_MOUSE_BUTTON_UP;
else if (atom == nsGkAtoms::onclick)
mEvent->message = NS_MOUSE_CLICK;
else if (atom == nsGkAtoms::ondblclick)
mEvent->message = NS_MOUSE_DOUBLECLICK;
else if (atom == nsGkAtoms::onmouseover)
mEvent->message = NS_MOUSE_ENTER_SYNTH;
else if (atom == nsGkAtoms::onmouseout)
mEvent->message = NS_MOUSE_EXIT_SYNTH;
else if (atom == nsGkAtoms::onmousemove)
mEvent->message = NS_MOUSE_MOVE;
else if (atom == nsGkAtoms::oncontextmenu)
mEvent->message = NS_CONTEXTMENU;
} else if (mEvent->eventStructType == NS_MOUSE_SCROLL_EVENT) {
if (atom == nsGkAtoms::onDOMMouseScroll)
mEvent->message = NS_MOUSE_SCROLL;
else if (atom == nsGkAtoms::onMozMousePixelScroll)
mEvent->message = NS_MOUSE_PIXEL_SCROLL;
} else if (mEvent->eventStructType == NS_DRAG_EVENT) {
if (atom == nsGkAtoms::ondragstart)
mEvent->message = NS_DRAGDROP_START;
else if (atom == nsGkAtoms::ondraggesture)
mEvent->message = NS_DRAGDROP_GESTURE;
else if (atom == nsGkAtoms::ondragenter)
mEvent->message = NS_DRAGDROP_ENTER;
else if (atom == nsGkAtoms::ondragover)
mEvent->message = NS_DRAGDROP_OVER_SYNTH;
else if (atom == nsGkAtoms::ondragleave)
mEvent->message = NS_DRAGDROP_LEAVE_SYNTH;
else if (atom == nsGkAtoms::ondragexit)
mEvent->message = NS_DRAGDROP_EXIT;
else if (atom == nsGkAtoms::ondrag)
mEvent->message = NS_DRAGDROP_DRAG;
else if (atom == nsGkAtoms::ondrop)
mEvent->message = NS_DRAGDROP_DROP;
else if (atom == nsGkAtoms::ondragdrop)
mEvent->message = NS_DRAGDROP_DRAGDROP;
else if (atom == nsGkAtoms::ondragend)
mEvent->message = NS_DRAGDROP_END;
} else if (mEvent->eventStructType == NS_KEY_EVENT) {
if (atom == nsGkAtoms::onkeydown)
mEvent->message = NS_KEY_DOWN;
else if (atom == nsGkAtoms::onkeyup)
mEvent->message = NS_KEY_UP;
else if (atom == nsGkAtoms::onkeypress)
mEvent->message = NS_KEY_PRESS;
} else if (mEvent->eventStructType == NS_COMPOSITION_EVENT) {
if (atom == nsGkAtoms::oncompositionstart)
mEvent->message = NS_COMPOSITION_START;
else if (atom == nsGkAtoms::oncompositionend)
mEvent->message = NS_COMPOSITION_END;
} else if (mEvent->eventStructType == NS_EVENT) {
if (atom == nsGkAtoms::onMozAfterPaint)
mEvent->message = NS_AFTERPAINT;
else if (atom == nsGkAtoms::onsubmit)
mEvent->message = NS_FORM_SUBMIT;
else if (atom == nsGkAtoms::onreset)
mEvent->message = NS_FORM_RESET;
else if (atom == nsGkAtoms::onchange)
mEvent->message = NS_FORM_CHANGE;
else if (atom == nsGkAtoms::onselect)
mEvent->message = NS_FORM_SELECTED;
else if (atom == nsGkAtoms::onload)
mEvent->message = NS_LOAD;
else if (atom == nsGkAtoms::onunload)
mEvent->message = NS_PAGE_UNLOAD;
else if (atom == nsGkAtoms::onbeforeunload)
mEvent->message = NS_BEFORE_PAGE_UNLOAD;
else if (atom == nsGkAtoms::onabort)
mEvent->message = NS_IMAGE_ABORT;
else if (atom == nsGkAtoms::onerror)
mEvent->message = NS_LOAD_ERROR;
else if (atom == nsGkAtoms::onoffline)
mEvent->message = NS_OFFLINE;
else if (atom == nsGkAtoms::ononline)
mEvent->message = NS_ONLINE;
else if (atom == nsGkAtoms::oncopy)
mEvent->message = NS_COPY;
else if (atom == nsGkAtoms::oncut)
mEvent->message = NS_CUT;
else if (atom == nsGkAtoms::onpaste)
mEvent->message = NS_PASTE;
else if (atom == nsGkAtoms::onpageshow)
mEvent->message = NS_PAGE_SHOW;
else if (atom == nsGkAtoms::onpagehide)
mEvent->message = NS_PAGE_HIDE;
else if (atom == nsGkAtoms::onhashchange)
mEvent->message = NS_HASHCHANGE;
} else if (mEvent->eventStructType == NS_FOCUS_EVENT) {
if (atom == nsGkAtoms::onfocus)
mEvent->message = NS_FOCUS_CONTENT;
else if (atom == nsGkAtoms::onblur)
mEvent->message = NS_BLUR_CONTENT;
} else if (mEvent->eventStructType == NS_MUTATION_EVENT) {
if (atom == nsGkAtoms::onDOMAttrModified)
mEvent->message = NS_MUTATION_ATTRMODIFIED;
else if (atom == nsGkAtoms::onDOMCharacterDataModified)
mEvent->message = NS_MUTATION_CHARACTERDATAMODIFIED;
else if (atom == nsGkAtoms::onDOMNodeInserted)
mEvent->message = NS_MUTATION_NODEINSERTED;
else if (atom == nsGkAtoms::onDOMNodeRemoved)
mEvent->message = NS_MUTATION_NODEREMOVED;
else if (atom == nsGkAtoms::onDOMNodeInsertedIntoDocument)
mEvent->message = NS_MUTATION_NODEINSERTEDINTODOCUMENT;
else if (atom == nsGkAtoms::onDOMNodeRemovedFromDocument)
mEvent->message = NS_MUTATION_NODEREMOVEDFROMDOCUMENT;
else if (atom == nsGkAtoms::onDOMSubtreeModified)
mEvent->message = NS_MUTATION_SUBTREEMODIFIED;
} else if (mEvent->eventStructType == NS_UI_EVENT) {
if (atom == nsGkAtoms::onDOMActivate)
mEvent->message = NS_UI_ACTIVATE;
else if (atom == nsGkAtoms::onDOMFocusIn)
mEvent->message = NS_UI_FOCUSIN;
else if (atom == nsGkAtoms::onDOMFocusOut)
mEvent->message = NS_UI_FOCUSOUT;
else if (atom == nsGkAtoms::oninput)
mEvent->message = NS_FORM_INPUT;
} else if (mEvent->eventStructType == NS_SCROLLAREA_EVENT) {
if (atom == nsGkAtoms::onMozScrolledAreaChanged)
mEvent->message = NS_SCROLLEDAREACHANGED;
} else if (mEvent->eventStructType == NS_INPUT_EVENT) {
if (atom == nsGkAtoms::oncommand)
mEvent->message = NS_XUL_COMMAND;
}
#ifdef MOZ_SVG
else if (mEvent->eventStructType == NS_SVG_EVENT) {
if (atom == nsGkAtoms::onSVGLoad)
mEvent->message = NS_SVG_LOAD;
else if (atom == nsGkAtoms::onSVGUnload)
mEvent->message = NS_SVG_UNLOAD;
else if (atom == nsGkAtoms::onSVGAbort)
mEvent->message = NS_SVG_ABORT;
else if (atom == nsGkAtoms::onSVGError)
mEvent->message = NS_SVG_ERROR;
else if (atom == nsGkAtoms::onSVGResize)
mEvent->message = NS_SVG_RESIZE;
else if (atom == nsGkAtoms::onSVGScroll)
mEvent->message = NS_SVG_SCROLL;
} else if (mEvent->eventStructType == NS_SVGZOOM_EVENT) {
if (atom == nsGkAtoms::onSVGZoom)
mEvent->message = NS_SVG_ZOOM;
}
#endif // MOZ_SVG
#ifdef MOZ_MEDIA
else if (mEvent->eventStructType == NS_MEDIA_EVENT) {
if (atom == nsGkAtoms::onloadstart)
mEvent->message = NS_LOADSTART;
else if (atom == nsGkAtoms::onprogress)
mEvent->message = NS_PROGRESS;
else if (atom == nsGkAtoms::onsuspend)
mEvent->message = NS_SUSPEND;
else if (atom == nsGkAtoms::onemptied)
mEvent->message = NS_EMPTIED;
else if (atom == nsGkAtoms::onstalled)
mEvent->message = NS_STALLED;
else if (atom == nsGkAtoms::onplay)
mEvent->message = NS_PLAY;
else if (atom == nsGkAtoms::onpause)
mEvent->message = NS_PAUSE;
else if (atom == nsGkAtoms::onloadedmetadata)
mEvent->message = NS_LOADEDMETADATA;
else if (atom == nsGkAtoms::onloadeddata)
mEvent->message = NS_LOADEDDATA;
else if (atom == nsGkAtoms::onwaiting)
mEvent->message = NS_WAITING;
else if (atom == nsGkAtoms::onplaying)
mEvent->message = NS_PLAYING;
else if (atom == nsGkAtoms::oncanplay)
mEvent->message = NS_CANPLAY;
else if (atom == nsGkAtoms::oncanplaythrough)
mEvent->message = NS_CANPLAYTHROUGH;
else if (atom == nsGkAtoms::onseeking)
mEvent->message = NS_SEEKING;
else if (atom == nsGkAtoms::onseeked)
mEvent->message = NS_SEEKED;
else if (atom == nsGkAtoms::ontimeupdate)
mEvent->message = NS_TIMEUPDATE;
else if (atom == nsGkAtoms::onended)
mEvent->message = NS_ENDED;
else if (atom == nsGkAtoms::onratechange)
mEvent->message = NS_RATECHANGE;
else if (atom == nsGkAtoms::ondurationchange)
mEvent->message = NS_DURATIONCHANGE;
else if (atom == nsGkAtoms::onvolumechange)
mEvent->message = NS_VOLUMECHANGE;
else if (atom == nsGkAtoms::onload)
mEvent->message = NS_LOAD;
else if (atom == nsGkAtoms::onabort)
mEvent->message = NS_MEDIA_ABORT;
else if (atom == nsGkAtoms::onerror)
mEvent->message = NS_MEDIA_ERROR;
}
#endif // MOZ_MEDIA
else if (mEvent->eventStructType == NS_SIMPLE_GESTURE_EVENT) {
if (atom == nsGkAtoms::onMozSwipeGesture)
mEvent->message = NS_SIMPLE_GESTURE_SWIPE;
else if (atom == nsGkAtoms::onMozMagnifyGestureStart)
mEvent->message = NS_SIMPLE_GESTURE_MAGNIFY_START;
else if (atom == nsGkAtoms::onMozMagnifyGestureUpdate)
mEvent->message = NS_SIMPLE_GESTURE_MAGNIFY_UPDATE;
else if (atom == nsGkAtoms::onMozMagnifyGesture)
mEvent->message = NS_SIMPLE_GESTURE_MAGNIFY;
else if (atom == nsGkAtoms::onMozRotateGestureStart)
mEvent->message = NS_SIMPLE_GESTURE_ROTATE_START;
else if (atom == nsGkAtoms::onMozRotateGestureUpdate)
mEvent->message = NS_SIMPLE_GESTURE_ROTATE_UPDATE;
else if (atom == nsGkAtoms::onMozRotateGesture)
mEvent->message = NS_SIMPLE_GESTURE_ROTATE;
else if (atom == nsGkAtoms::onMozPressTapGesture)
mEvent->message = NS_SIMPLE_GESTURE_PRESSTAP;
else if (atom == nsGkAtoms::onMozTapGesture)
mEvent->message = NS_SIMPLE_GESTURE_TAP;
}
else if (mEvent->eventStructType == NS_TRANSITION_EVENT) {
if (atom == nsGkAtoms::ontransitionend)
mEvent->message = NS_TRANSITION_END;
}
if (mEvent->message == NS_USER_DEFINED_EVENT)
mEvent->userType = atom;
mEvent->userType =
nsContentUtils::GetEventIdAndAtom(aEventTypeArg, mEvent->eventStructType,
&(mEvent->message));
return NS_OK;
}

View File

@ -87,9 +87,6 @@ public:
return nsnull;
}
/** Call on shutdown to release globals */
static void Shutdown();
/**
* Handle QI for the standard DOM interfaces (DOMNode, DOMElement,
* DOMHTMLElement) and handles tearoffs for other standard interfaces.

View File

@ -308,7 +308,7 @@ morkBuilder::OnPortEnd(morkEnv* ev, const morkSpan& inSpan)
morkBuilder::OnNewGroup(morkEnv* ev, const morkPlace& inPlace, mork_gid inGid)
{
MORK_USED_1(inPlace);
// mParser_InGroup = morkBool_kTrue;
mParser_InGroup = morkBool_kTrue;
mork_pos startPos = inPlace.mPlace_Pos;
morkStore* store = mBuilder_Store;

View File

@ -1297,6 +1297,7 @@ mork_bool morkParser::ReadEndGroupId(morkEnv* ev)
{
// looks good, so return with no error
outSawGroupId = morkBool_kTrue;
mParser_InGroup = false;
}
else
ev->NewError("expected '@' after @$$}id}");
@ -1419,20 +1420,24 @@ mork_bool
morkParser::ReadContent(morkEnv* ev, mork_bool inInsideGroup)
{
int c;
while ( (c = this->NextChar(ev)) != EOF && ev->Good() )
mork_bool keep_going = true;
while ( keep_going && (c = this->NextChar(ev)) != EOF && ev->Good())
{
switch ( c )
{
case '[': // row
this->ReadRow(ev, '[');
keep_going = false;
break;
case '{': // table
this->ReadTable(ev);
keep_going = false;
break;
case '<': // dict
this->ReadDict(ev);
keep_going = false;
break;
case '@': // group
@ -1467,14 +1472,18 @@ morkParser::ReadContent(morkEnv* ev, mork_bool inInsideGroup)
void
morkParser::OnPortState(morkEnv* ev)
{
mork_bool firstTime = !mParser_InPort;
mParser_InPort = morkBool_kTrue;
this->OnNewPort(ev, *mParser_PortSpan.AsPlace());
if (firstTime)
this->OnNewPort(ev, *mParser_PortSpan.AsPlace());
while ( this->ReadContent(ev, /*inInsideGroup*/ morkBool_kFalse) )
/* empty */;
mParser_InPort = morkBool_kFalse;
this->OnPortEnd(ev, mParser_PortSpan);
mork_bool done = !this->ReadContent(ev, mParser_InGroup/*inInsideGroup*/);
if (done)
{
mParser_InPort = morkBool_kFalse;
this->OnPortEnd(ev, mParser_PortSpan);
}
if ( ev->Bad() )
mParser_State = morkParser_kBrokenState;
@ -1503,51 +1512,48 @@ morkParser::OnStartState(morkEnv* mev)
}
/*protected non-poly*/ void
morkParser::ParseLoop(morkEnv* ev)
morkParser::ParseChunk(morkEnv* ev)
{
mParser_Change = morkChange_kNil;
mParser_DoMore = morkBool_kTrue;
while ( mParser_DoMore )
switch ( mParser_State )
{
switch ( mParser_State )
{
case morkParser_kCellState: // 0
this->OnCellState(ev); break;
case morkParser_kMetaState: // 1
this->OnMetaState(ev); break;
case morkParser_kRowState: // 2
this->OnRowState(ev); break;
case morkParser_kTableState: // 3
this->OnTableState(ev); break;
case morkParser_kDictState: // 4
this->OnDictState(ev); break;
case morkParser_kPortState: // 5
this->OnPortState(ev); break;
case morkParser_kStartState: // 6
this->OnStartState(ev); break;
case morkParser_kDoneState: // 7
mParser_DoMore = morkBool_kFalse;
mParser_IsDone = morkBool_kTrue;
this->StopParse(ev);
break;
case morkParser_kBrokenState: // 8
mParser_DoMore = morkBool_kFalse;
mParser_IsBroken = morkBool_kTrue;
this->StopParse(ev);
break;
default: // ?
MORK_ASSERT(morkBool_kFalse);
mParser_State = morkParser_kBrokenState;
break;
}
case morkParser_kCellState: // 0
this->OnCellState(ev); break;
case morkParser_kMetaState: // 1
this->OnMetaState(ev); break;
case morkParser_kRowState: // 2
this->OnRowState(ev); break;
case morkParser_kTableState: // 3
this->OnTableState(ev); break;
case morkParser_kDictState: // 4
this->OnDictState(ev); break;
case morkParser_kPortState: // 5
this->OnPortState(ev); break;
case morkParser_kStartState: // 6
this->OnStartState(ev); break;
case morkParser_kDoneState: // 7
mParser_DoMore = morkBool_kFalse;
mParser_IsDone = morkBool_kTrue;
this->StopParse(ev);
break;
case morkParser_kBrokenState: // 8
mParser_DoMore = morkBool_kFalse;
mParser_IsBroken = morkBool_kTrue;
this->StopParse(ev);
break;
default: // ?
MORK_ASSERT(morkBool_kFalse);
mParser_State = morkParser_kBrokenState;
break;
}
}
@ -1565,18 +1571,22 @@ morkParser::ParseMore( // return count of bytes consumed now
mork_pos startPos = this->HerePos();
if ( !mParser_IsDone && !mParser_IsBroken )
this->ParseLoop(ev);
this->ParseChunk(ev);
mork_pos endPos = this->HerePos();
// HerePos is only updated for groups. I'd like it to be more accurate.
mork_pos here;
nsresult rv = mParser_Stream->Tell(ev, &here);
if ( outDone )
*outDone = mParser_IsDone;
if ( outBroken )
*outBroken = mParser_IsBroken;
if ( outPos )
*outPos = endPos;
*outPos = here;
if ( endPos > startPos )
outCount = (mdb_count) (endPos - startPos);
if ( here > startPos )
outCount = (mdb_count) (here - startPos);
}
else
{

View File

@ -478,7 +478,7 @@ public: // out virtual morkParser methods, data flow parser to subclass
// ````` ````` ````` ````` ````` ````` ````` `````
protected: // protected parser helper methods
void ParseLoop(morkEnv* ev); // find parse continuation and resume
void ParseChunk(morkEnv* ev); // find parse continuation and resume
void StartParse(morkEnv* ev); // prepare for parsing
void StopParse(morkEnv* ev); // terminate parsing & call needed methods

View File

@ -106,6 +106,7 @@ DEFINES = \
-DSQLITE_THREADSAFE=1 \
-DSQLITE_CORE=1 \
-DSQLITE_ENABLE_FTS3=1 \
-DSQLITE_ENABLE_UNLOCK_NOTIFY=1 \
$(NULL)
# -DSQLITE_ENABLE_LOCKING_STYLE=1 to help with AFP folders

View File

@ -158,6 +158,7 @@ EXPORTS
sqlite3_total_changes
sqlite3_trace
sqlite3_transfer_bindings
sqlite3_unlock_notify
sqlite3_update_hook
sqlite3_user_data
sqlite3_value_blob

View File

@ -2,6 +2,7 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.mozilla.@MOZ_APP_NAME@"
android:installLocation="auto"
android:versionCode="1"
android:versionName="1.9.3"
android:sharedUserId="org.mozilla.sharedID">

View File

@ -161,6 +161,8 @@ abstract public class GeckoApp
@Override
public void onPause()
{
Log.i("GeckoApp", "pause");
GeckoAppShell.sendEventToGecko(new GeckoEvent(GeckoEvent.ACTIVITY_PAUSING));
// The user is navigating away from this activity, but nothing
// has come to the foreground yet; for Gecko, we may want to
@ -176,6 +178,10 @@ abstract public class GeckoApp
@Override
public void onResume()
{
Log.i("GeckoApp", "resume");
GeckoAppShell.onResume();
if (surfaceView != null)
surfaceView.mSurfaceNeedsRedraw = true;
// After an onPause, the activity is back in the foreground.
// Undo whatever we did in onPause.
super.onResume();

View File

@ -72,6 +72,8 @@ class GeckoAppShell
static private boolean gRestartScheduled = false;
static protected Timer mSoftKBTimer;
/* The Android-side API: API methods that Android calls */
// Initialization methods
@ -82,6 +84,7 @@ class GeckoAppShell
public static native void setInitialSize(int width, int height);
public static native void setSurfaceView(GeckoSurfaceView sv);
public static native void putenv(String map);
public static native void onResume();
// java-side stuff
public static void loadGeckoLibs() {
@ -173,14 +176,24 @@ class GeckoAppShell
}
public static void showIME(int state) {
InputMethodManager imm = (InputMethodManager)
GeckoApp.surfaceView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
GeckoApp.surfaceView.mIMEState = state;
if (state != 0)
imm.showSoftInput(GeckoApp.surfaceView, 0);
else
imm.hideSoftInputFromWindow(GeckoApp.surfaceView.getWindowToken(), 0);
if (mSoftKBTimer == null) {
mSoftKBTimer = new Timer();
mSoftKBTimer.schedule(new TimerTask() {
public void run() {
InputMethodManager imm = (InputMethodManager)
GeckoApp.surfaceView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
if (GeckoApp.surfaceView.mIMEState != 0)
imm.showSoftInput(GeckoApp.surfaceView, 0);
else
imm.hideSoftInputFromWindow(GeckoApp.surfaceView.getWindowToken(), 0);
mSoftKBTimer = null;
}
}, 200);
}
}
public static void enableAccelerometer(boolean enable) {

View File

@ -509,7 +509,13 @@ LayerManagerOGL::Render()
DEBUG_GL_ERROR_CHECK(mGLContext);
mGLContext->fFinish();
// XXX this is an intermediate workaround for windows that are
// double-buffered by default on GLX systems. The swap is a no-op
// everywhere else (and for non-double-buffered GLX windows). If
// the swap is actually performed, it implicitly glFlush()s.
if (!mGLContext->SwapBuffers()) {
mGLContext->fFlush();
}
DEBUG_GL_ERROR_CHECK(mGLContext);
}

View File

@ -265,7 +265,7 @@ protected:
mGL->fAttachShader(mProgram, mFragmentShader);
// bind common attribs to consistent indices
mGL->fBindAttribLocation(mProgram, VertexAttrib, "aVertex");
mGL->fBindAttribLocation(mProgram, VertexAttrib, "aVertexCoord");
mGL->fBindAttribLocation(mProgram, TexCoordAttrib, "aTexCoord");
mGL->fLinkProgram(mProgram);

View File

@ -45,6 +45,9 @@
#if defined(MOZ_WIDGET_GTK2)
# include <gdk/gdkx.h>
#elif defined(MOZ_WIDGET_QT)
// X11/X.h has #define CursorShape 0, but Qt's qnamespace.h defines
// enum CursorShape { ... }. Good times!
#undef CursorShape
# include <QX11Info>
#else
# error Unknown toolkit

View File

@ -158,6 +158,13 @@ public:
*/
virtual PRBool Resize(const gfxIntSize& aNewSize) { return PR_FALSE; }
/**
* If this context wraps a double-buffered target, swap the back
* and front buffers. It should be assumed that after a swap, the
* contents of the new back buffer are undefined.
*/
virtual PRBool SwapBuffers() { return PR_FALSE; }
protected:
PRBool mInitialized;

View File

@ -47,11 +47,6 @@ class GLXLibrary
public:
GLXLibrary() : mInitialized(PR_FALSE), mOGLLibrary(nsnull) {}
typedef GLXContext (GLAPIENTRY * PFNGLXCREATECONTEXTPROC) (Display*,
XVisualInfo*,
GLXContext,
Bool);
PFNGLXCREATECONTEXTPROC xCreateContext;
typedef void (GLAPIENTRY * PFNGLXDELETECONTEXTPROC) (Display*,
GLXContext);
PFNGLXDELETECONTEXTPROC xDeleteContext;
@ -70,6 +65,10 @@ public:
const int *,
int *);
PFNGLXCHOOSEFBCONFIG xChooseFBConfig;
typedef GLXFBConfig* (GLAPIENTRY * PFNGLXGETFBCONFIGS) (Display *,
int,
int *);
PFNGLXGETFBCONFIGS xGetFBConfigs;
typedef GLXPbuffer (GLAPIENTRY * PFNGLXCREATEPBUFFER) (Display *,
GLXFBConfig,
const int *);
@ -87,7 +86,20 @@ public:
typedef XVisualInfo* (GLAPIENTRY * PFNGLXGETVISUALFROMFBCONFIG) (Display *,
GLXFBConfig);
PFNGLXGETVISUALFROMFBCONFIG xGetVisualFromFBConfig;
typedef int (GLAPIENTRY * PFNGLXGETFBCONFIGATTRIB) (Display *,
GLXFBConfig,
int,
int *);
PFNGLXGETFBCONFIGATTRIB xGetFBConfigAttrib;
typedef void (GLAPIENTRY * PFNGLXSWAPBUFFERS) (Display *,
GLXDrawable);
PFNGLXSWAPBUFFERS xSwapBuffers;
typedef const char * (GLAPIENTRY * PFNGLXQUERYSERVERSTRING) (Display *,
int,
int);
PFNGLXQUERYSERVERSTRING xQueryServerString;
PRBool EnsureInitialized();
private:

View File

@ -71,12 +71,7 @@ public:
virtual ~gfxXlibSurface();
const gfxIntSize& GetSize() {
if (mSize.width == -1 || mSize.height == -1)
DoSizeQuery();
return mSize;
}
const gfxIntSize& GetSize() { return mSize; }
Display* XDisplay() { return mDisplay; }
Drawable XDrawable() { return mDrawable; }

View File

@ -77,16 +77,19 @@ GLXLibrary::EnsureInitialized()
}
LibrarySymbolLoader::SymLoadStruct symbols[] = {
{ (PRFuncPtr*) &xCreateContext, { "glXCreateContext", NULL } },
{ (PRFuncPtr*) &xDeleteContext, { "glXDestroyContext", NULL } },
{ (PRFuncPtr*) &xMakeCurrent, { "glXMakeCurrent", NULL } },
{ (PRFuncPtr*) &xGetProcAddress, { "glXGetProcAddress", NULL } },
{ (PRFuncPtr*) &xChooseVisual, { "glXChooseVisual", NULL } },
{ (PRFuncPtr*) &xChooseFBConfig, { "glXChooseFBConfig", NULL } },
{ (PRFuncPtr*) &xGetFBConfigs, { "glXGetFBConfigs", NULL } },
{ (PRFuncPtr*) &xCreatePbuffer, { "glXCreatePbuffer", NULL } },
{ (PRFuncPtr*) &xCreateNewContext, { "glXCreateNewContext", NULL } },
{ (PRFuncPtr*) &xDestroyPbuffer, { "glXDestroyPbuffer", NULL } },
{ (PRFuncPtr*) &xGetVisualFromFBConfig, { "glXGetVisualFromFBConfig", NULL } },
{ (PRFuncPtr*) &xGetFBConfigAttrib, { "glXGetFBConfigAttrib", NULL } },
{ (PRFuncPtr*) &xSwapBuffers, { "glXSwapBuffers", NULL } },
{ (PRFuncPtr*) &xQueryServerString, { "glXQueryServerString", NULL } },
{ NULL, { NULL } }
};
@ -114,6 +117,15 @@ class GLContextGLX : public GLContext
public:
static GLContextGLX *CreateGLContext(Display *display, GLXDrawable drawable, GLXFBConfig cfg, PRBool pbuffer)
{
int db = 0, err;
err = sGLXLibrary.xGetFBConfigAttrib(display, cfg,
GLX_DOUBLEBUFFER, &db);
if (GLX_BAD_ATTRIBUTE != err) {
#ifdef DEBUG
printf("[GLX] FBConfig is %sdouble-buffered\n", db ? "" : "not ");
#endif
}
ctxErrorOccurred = false;
int (*oldHandler)(Display *, XErrorEvent *) = XSetErrorHandler(&ctxErrorHandler);
@ -134,7 +146,8 @@ public:
GLContextGLX *glContext = new GLContextGLX(display,
drawable,
context,
pbuffer);
pbuffer,
db);
if (!glContext->Init()) {
return nsnull;
}
@ -185,29 +198,168 @@ public:
if (mPBuffer) {
return (void *)mWindow;
}
// fall through
default:
return nsnull;
}
}
virtual PRBool SwapBuffers()
{
if (mPBuffer || !mDoubleBuffered)
return PR_FALSE;
sGLXLibrary.xSwapBuffers(mDisplay, mWindow);
return PR_TRUE;
}
private:
GLContextGLX(Display *aDisplay, GLXDrawable aWindow, GLXContext aContext, PRBool aPBuffer = PR_FALSE)
GLContextGLX(Display *aDisplay, GLXDrawable aWindow, GLXContext aContext, PRBool aPBuffer = PR_FALSE, PRBool aDoubleBuffered=PR_FALSE)
: mContext(aContext),
mDisplay(aDisplay),
mWindow(aWindow),
mPBuffer(aPBuffer) {}
mPBuffer(aPBuffer),
mDoubleBuffered(aDoubleBuffered) {}
GLXContext mContext;
Display *mDisplay;
GLXDrawable mWindow;
PRBool mPBuffer;
PRBool mDoubleBuffered;
};
static PRBool AreCompatibleVisuals(XVisualInfo *one, XVisualInfo *two)
{
if (one->c_class != two->c_class) {
return PR_FALSE;
}
if (one->depth != two->depth) {
return PR_FALSE;
}
if (one->red_mask != two->red_mask ||
one->green_mask != two->green_mask ||
one->blue_mask != two->blue_mask) {
return PR_FALSE;
}
if (one->bits_per_rgb != two->bits_per_rgb) {
return PR_FALSE;
}
return PR_TRUE;
}
already_AddRefed<GLContext>
GLContextProvider::CreateForWindow(nsIWidget *aWidget)
{
return nsnull;
if (!sGLXLibrary.EnsureInitialized()) {
return nsnull;
}
// Currently, we take whatever Visual the window already has, and
// try to create an fbconfig for that visual. This isn't
// necessarily what we want in the long run; an fbconfig may not
// be available for the existing visual, or if it is, the GL
// performance might be suboptimal. But using the existing visual
// is a relatively safe intermediate step.
Display *display = (Display*)aWidget->GetNativeData(NS_NATIVE_DISPLAY);
int xscreen = DefaultScreen(display);
Window window = GET_NATIVE_WINDOW(aWidget);
const char *vendor = sGLXLibrary.xQueryServerString(display, xscreen, GLX_VENDOR);
PRBool isATI = vendor && strstr(vendor, "ATI");
int numConfigs;
GLXFBConfig *cfgs;
if (isATI) {
const int attribs[] = {
GLX_DOUBLEBUFFER, False,
0
};
cfgs = sGLXLibrary.xChooseFBConfig(display,
xscreen,
attribs,
&numConfigs);
} else {
cfgs = sGLXLibrary.xGetFBConfigs(display,
xscreen,
&numConfigs);
}
if (!cfgs) {
NS_WARNING("[GLX] glXGetFBConfigs() failed");
return nsnull;
}
NS_ASSERTION(numConfigs > 0, "No FBConfigs found!");
// XXX the visual ID is almost certainly the GLX_FBCONFIG_ID, so
// we could probably do this first and replace the glXGetFBConfigs
// with glXChooseConfigs. Docs are sparklingly clear as always.
XWindowAttributes widgetAttrs;
if (!XGetWindowAttributes(display, window, &widgetAttrs)) {
NS_WARNING("[GLX] XGetWindowAttributes() failed");
XFree(cfgs);
return nsnull;
}
const VisualID widgetVisualID = XVisualIDFromVisual(widgetAttrs.visual);
#ifdef DEBUG
printf("[GLX] widget has VisualID 0x%lx\n", widgetVisualID);
#endif
XVisualInfo *vi = NULL;
if (isATI) {
XVisualInfo vinfo_template;
int nvisuals;
vinfo_template.visual = widgetAttrs.visual;
vinfo_template.visualid = XVisualIDFromVisual(vinfo_template.visual);
vinfo_template.depth = widgetAttrs.depth;
vinfo_template.screen = xscreen;
vi = XGetVisualInfo(display, VisualIDMask|VisualDepthMask|VisualScreenMask,
&vinfo_template, &nvisuals);
NS_ASSERTION(vi && nvisuals == 1, "Could not locate unique matching XVisualInfo for Visual");
}
int matchIndex = -1;
for (int i = 0; i < numConfigs; i++) {
XVisualInfo *info = sGLXLibrary.xGetVisualFromFBConfig(display, cfgs[i]);
if (!info) {
continue;
}
if (isATI) {
if (AreCompatibleVisuals(vi, info)) {
matchIndex = i;
XFree(info);
break;
}
} else {
if (widgetVisualID == info->visualid) {
matchIndex = i;
XFree(info);
break;
}
}
XFree(info);
}
if (isATI) {
XFree(vi);
}
if (matchIndex == -1) {
NS_WARNING("[GLX] Couldn't find a FBConfig matching widget visual");
XFree(cfgs);
return nsnull;
}
nsRefPtr<GLContextGLX> glContext = GLContextGLX::CreateGLContext(display,
window,
cfgs[matchIndex],
PR_FALSE);
XFree(cfgs);
return glContext.forget().get();
}
already_AddRefed<GLContext>

View File

@ -741,23 +741,8 @@ gfxPlatformGtk::SetGdkDrawable(gfxASurface *target,
#ifdef MOZ_X11
// Look for an existing Colormap that is known to be associated with visual.
static GdkColormap *
LookupGdkColormapForVisual(const Screen* screen, const Visual* visual)
LookupGdkColormapForVisual(GdkScreen* gdkScreen, const Visual* visual)
{
Display* dpy = DisplayOfScreen(screen);
GdkDisplay* gdkDpy = gdk_x11_lookup_xdisplay(dpy);
if (!gdkDpy)
return NULL;
// I wish there were a gdk_x11_display_lookup_screen.
gint screen_num = 0;
for (int s = 0; s < ScreenCount(dpy); ++s) {
if (ScreenOfDisplay(dpy, s) == screen) {
screen_num = s;
break;
}
}
GdkScreen* gdkScreen = gdk_display_get_screen(gdkDpy, screen_num);
// Common case: the display's default colormap
if (visual ==
GDK_VISUAL_XVISUAL(gdk_screen_get_system_visual(gdkScreen)))
@ -790,7 +775,7 @@ GdkDrawable *
gfxPlatformGtk::GetGdkDrawable(gfxASurface *target)
{
if (target->CairoStatus())
return nsnull;
return NULL;
GdkDrawable *result;
@ -800,39 +785,60 @@ gfxPlatformGtk::GetGdkDrawable(gfxASurface *target)
return result;
#ifdef MOZ_X11
if (target->GetType() == gfxASurface::SurfaceTypeXlib) {
gfxXlibSurface *xs = (gfxXlibSurface*) target;
if (target->GetType() != gfxASurface::SurfaceTypeXlib)
return NULL;
// try looking it up in gdk's table
result = (GdkDrawable*) gdk_xid_table_lookup(xs->XDrawable());
if (result) {
SetGdkDrawable(target, result);
return result;
}
gfxXlibSurface *xs = static_cast<gfxXlibSurface*>(target);
// If all else fails, try doing a foreign_new
// but don't bother if we can't get a colormap.
// Without a colormap GDK won't know how to draw.
Screen *screen = cairo_xlib_surface_get_screen(xs->CairoSurface());
Visual *visual = cairo_xlib_surface_get_visual(xs->CairoSurface());
GdkColormap *cmap = LookupGdkColormapForVisual(screen, visual);
if (cmap == None)
return nsnull;
// try looking it up in gdk's table
result = (GdkDrawable*) gdk_xid_table_lookup(xs->XDrawable());
if (result) {
SetGdkDrawable(target, result);
return result;
}
result = (GdkDrawable*) gdk_pixmap_foreign_new_for_display
(gdk_display_get_default(), xs->XDrawable());
if (result) {
gdk_drawable_set_colormap(result, cmap);
// If all else fails, try doing a foreign_new
// but don't bother if we can't get a colormap.
// Without a colormap GDK won't know how to draw.
Screen *screen = cairo_xlib_surface_get_screen(xs->CairoSurface());
Visual *visual = cairo_xlib_surface_get_visual(xs->CairoSurface());
Display* dpy = DisplayOfScreen(screen);
SetGdkDrawable(target, result);
// Release our ref. The object is held by target. Caller will
// only need to ref if it wants to keep the drawable longer than
// target.
g_object_unref(result);
return result;
GdkDisplay* gdkDpy = gdk_x11_lookup_xdisplay(dpy);
if (!gdkDpy)
return NULL;
// I wish there were a gdk_x11_display_lookup_screen.
gint screen_num = 0;
for (int s = 0; s < ScreenCount(dpy); ++s) {
if (ScreenOfDisplay(dpy, s) == screen) {
screen_num = s;
break;
}
}
#endif
GdkScreen* gdkScreen = gdk_display_get_screen(gdkDpy, screen_num);
return nsnull;
GdkColormap *cmap = LookupGdkColormapForVisual(gdkScreen, visual);
if (cmap == NULL)
return NULL;
gfxIntSize size = xs->GetSize();
int depth = cairo_xlib_surface_get_depth(xs->CairoSurface());
result = gdk_pixmap_foreign_new_for_screen(gdkScreen, xs->XDrawable(),
size.width, size.height, depth);
if (!result)
return NULL;
gdk_drawable_set_colormap(result, cmap);
SetGdkDrawable(target, result);
// Release our ref. The object is held by target. Caller will
// only need to ref if it wants to keep the drawable longer than
// target.
g_object_unref(result);
return result;
#else
return NULL;
#endif
}

View File

@ -118,7 +118,9 @@ gfxXlibSurface::gfxXlibSurface(Display *dpy, XRenderPictFormat *format, const gf
}
gfxXlibSurface::gfxXlibSurface(cairo_surface_t *csurf)
: mPixmapTaken(PR_FALSE), mSize(-1.0, -1.0)
: mPixmapTaken(PR_FALSE),
mSize(cairo_xlib_surface_get_width(csurf),
cairo_xlib_surface_get_height(csurf))
{
mDrawable = cairo_xlib_surface_get_drawable(csurf);
mDisplay = cairo_xlib_surface_get_display(csurf);

View File

@ -332,9 +332,8 @@ AsyncStatement::getAsyncStatement(sqlite3_stmt **_stmt)
#endif
if (!mAsyncStatement) {
int rc = ::sqlite3_prepare_v2(mDBConnection->GetNativeConnection(),
mSQLString.get(), -1,
&mAsyncStatement, NULL);
int rc = prepareStmt(mDBConnection->GetNativeConnection(), mSQLString,
&mAsyncStatement);
if (rc != SQLITE_OK) {
#ifdef PR_LOGGING
PR_LOG(gStorageLog, PR_LOG_ERROR,

View File

@ -342,7 +342,7 @@ AsyncExecuteStatements::executeStatement(sqlite3_stmt *aStatement)
// lock the sqlite mutex so sqlite3_errmsg cannot change
SQLiteMutexAutoLock lockedScope(mDBMutex);
int rc = ::sqlite3_step(aStatement);
int rc = stepStmt(aStatement);
// Stop if we have no more results.
if (rc == SQLITE_DONE)
return false;

View File

@ -413,10 +413,10 @@ Connection::initialize(nsIFile *aDatabaseFile)
// Execute a dummy statement to force the db open, and to verify if it is
// valid or not.
sqlite3_stmt *stmt;
srv = ::sqlite3_prepare_v2(mDBConn, "SELECT * FROM sqlite_master", -1, &stmt,
NULL);
srv = prepareStmt(mDBConn, NS_LITERAL_CSTRING("SELECT * FROM sqlite_master"),
&stmt);
if (srv == SQLITE_OK) {
srv = ::sqlite3_step(stmt);
srv = stepStmt(stmt);
if (srv == SQLITE_DONE || srv == SQLITE_ROW)
srv = SQLITE_OK;
@ -476,11 +476,11 @@ Connection::databaseElementExists(enum DatabaseElementType aElementType,
query.Append("'");
sqlite3_stmt *stmt;
int srv = ::sqlite3_prepare_v2(mDBConn, query.get(), -1, &stmt, NULL);
int srv = prepareStmt(mDBConn, query, &stmt);
if (srv != SQLITE_OK)
return convertResultCode(srv);
srv = ::sqlite3_step(stmt);
srv = stepStmt(stmt);
// we just care about the return value from step
(void)::sqlite3_finalize(stmt);

View File

@ -46,6 +46,8 @@
#include "nsPrintfCString.h"
#include "nsString.h"
#include "nsError.h"
#include "mozilla/Mutex.h"
#include "mozilla/CondVar.h"
#include "nsThreadUtils.h"
#include "Variant.h"
@ -60,7 +62,10 @@ namespace storage {
nsresult
convertResultCode(int aSQLiteResultCode)
{
switch (aSQLiteResultCode) {
// Drop off the extended result bits of the result code.
int rc = aSQLiteResultCode & 0xFF;
switch (rc) {
case SQLITE_OK:
case SQLITE_ROW:
case SQLITE_DONE:
@ -97,7 +102,7 @@ convertResultCode(int aSQLiteResultCode)
#ifdef DEBUG
nsCAutoString message;
message.AppendLiteral("SQLite returned error code ");
message.AppendInt(aSQLiteResultCode);
message.AppendInt(rc);
message.AppendLiteral(" , Storage will convert it to NS_ERROR_FAILURE");
NS_WARNING(message.get());
#endif
@ -203,5 +208,128 @@ newCompletionEvent(mozIStorageCompletionCallback *aCallback)
return event.forget();
}
/**
* This code is heavily based on the sample at:
* http://www.sqlite.org/unlock_notify.html
*/
namespace {
class UnlockNotification
{
public:
UnlockNotification()
: mMutex("UnlockNotification mMutex")
, mCondVar(mMutex, "UnlockNotification condVar")
, mSignaled(false)
{
}
void Wait()
{
mozilla::MutexAutoLock lock(mMutex);
while (!mSignaled) {
(void)mCondVar.Wait();
}
}
void Signal()
{
mozilla::MutexAutoLock lock(mMutex);
mSignaled = true;
(void)mCondVar.Notify();
}
private:
mozilla::Mutex mMutex;
mozilla::CondVar mCondVar;
bool mSignaled;
};
void
UnlockNotifyCallback(void **aArgs,
int aArgsSize)
{
for (int i = 0; i < aArgsSize; i++) {
UnlockNotification *notification =
static_cast<UnlockNotification *>(aArgs[i]);
notification->Signal();
}
}
int
WaitForUnlockNotify(sqlite3* aDatabase)
{
UnlockNotification notification;
int srv = ::sqlite3_unlock_notify(aDatabase, UnlockNotifyCallback,
&notification);
NS_ASSERTION(srv == SQLITE_LOCKED || srv == SQLITE_OK, "Bad result!");
if (srv == SQLITE_OK)
notification.Wait();
return srv;
}
} // anonymous namespace
int
stepStmt(sqlite3_stmt* aStatement)
{
bool checkedMainThread = false;
sqlite3* db = ::sqlite3_db_handle(aStatement);
(void)::sqlite3_extended_result_codes(db, 1);
int srv;
while ((srv = ::sqlite3_step(aStatement)) == SQLITE_LOCKED_SHAREDCACHE) {
if (!checkedMainThread) {
checkedMainThread = true;
if (NS_IsMainThread()) {
NS_WARNING("We won't allow blocking on the main thread!");
break;
}
}
srv = WaitForUnlockNotify(sqlite3_db_handle(aStatement));
if (srv != SQLITE_OK)
break;
::sqlite3_reset(aStatement);
}
(void)::sqlite3_extended_result_codes(db, 0);
// Drop off the extended result bits of the result code.
return srv & 0xFF;
}
int
prepareStmt(sqlite3* aDatabase,
const nsCString &aSQL,
sqlite3_stmt **_stmt)
{
bool checkedMainThread = false;
(void)::sqlite3_extended_result_codes(aDatabase, 1);
int srv;
while((srv = ::sqlite3_prepare_v2(aDatabase, aSQL.get(), -1, _stmt, NULL)) ==
SQLITE_LOCKED_SHAREDCACHE) {
if (!checkedMainThread) {
checkedMainThread = true;
if (NS_IsMainThread()) {
NS_WARNING("We won't allow blocking on the main thread!");
break;
}
}
srv = WaitForUnlockNotify(aDatabase);
if (srv != SQLITE_OK)
break;
}
(void)::sqlite3_extended_result_codes(aDatabase, 0);
// Drop off the extended result bits of the result code.
return srv & 0xFF;
}
} // namespace storage
} // namespace mozilla

View File

@ -113,6 +113,29 @@ already_AddRefed<nsIRunnable> newCompletionEvent(
mozIStorageCompletionCallback *aCallback
);
/**
* Performs a sqlite3_step on aStatement, while properly handling SQLITE_LOCKED
* when not on the main thread by waiting until we are notified.
*
* @param aStatement
* A pointer to a sqlite3_stmt object.
* @return the result from sqlite3_step.
*/
int stepStmt(sqlite3_stmt *aStatement);
/**
* Obtains a prepared sqlite3_stmt object for aDatabase from aSQL.
*
* @param aDatabase
* The database the statement will execute on.
* @param aSQL
* The SQL statement to compile.
* @return the result from sqlite3_prepare_v2.
*/
int prepareStmt(sqlite3 *aDatabase, const nsCString &aSQL,
sqlite3_stmt **_stmt);
} // namespace storage
} // namespace mozilla

View File

@ -175,8 +175,7 @@ Statement::initialize(Connection *aDBConnection,
sqlite3 *db = aDBConnection->GetNativeConnection();
NS_ASSERTION(db, "We should never be called with a null sqlite3 database!");
int srv = ::sqlite3_prepare_v2(db, PromiseFlatCString(aSQLStatement).get(),
-1, &mDBStatement, NULL);
int srv = prepareStmt(db, PromiseFlatCString(aSQLStatement), &mDBStatement);
if (srv != SQLITE_OK) {
#ifdef PR_LOGGING
PR_LOG(gStorageLog, PR_LOG_ERROR,
@ -319,9 +318,9 @@ Statement::getAsyncStatement(sqlite3_stmt **_stmt)
// If we do not yet have a cached async statement, clone our statement now.
if (!mAsyncStatement) {
int rc = ::sqlite3_prepare_v2(mDBConnection->GetNativeConnection(),
::sqlite3_sql(mDBStatement), -1,
&mAsyncStatement, NULL);
nsDependentCString sql(::sqlite3_sql(mDBStatement));
int rc = prepareStmt(mDBConnection->GetNativeConnection(), sql,
&mAsyncStatement);
if (rc != SQLITE_OK) {
*_stmt = nsnull;
return rc;
@ -615,7 +614,7 @@ Statement::ExecuteStep(PRBool *_moreResults)
// We have bound, so now we can clear our array.
mParamsArray = nsnull;
}
int srv = ::sqlite3_step(mDBStatement);
int srv = stepStmt(mDBStatement);
#ifdef PR_LOGGING
if (srv != SQLITE_ROW && srv != SQLITE_DONE) {

View File

@ -54,6 +54,7 @@ CPP_UNIT_TESTS = \
test_mutex.cpp \
test_binding_params.cpp \
test_true_async.cpp \
test_unlock_notify.cpp \
$(NULL)
ifdef MOZ_DEBUG

View File

@ -16,7 +16,7 @@
* The Original Code is storage test code.
*
* The Initial Developer of the Original Code is
* Mozilla Corporation.
* The Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2009
* the Initial Developer. All Rights Reserved.
*
@ -39,6 +39,7 @@
#include "TestHarness.h"
#include "nsMemory.h"
#include "nsDirectoryServiceDefs.h"
#include "mozIStorageService.h"
#include "mozIStorageConnection.h"
@ -48,27 +49,55 @@ static int gPassedTests = 0;
#define do_check_true(aCondition) \
PR_BEGIN_MACRO \
gTotalTests++; \
if (aCondition) \
if (aCondition) { \
gPassedTests++; \
else \
fail("Expected true, got false on line %d!", __LINE__); \
} else { \
fail("Expected true, got false at %s:%d!", __FILE__, __LINE__); \
} \
PR_END_MACRO
#define do_check_false(aCondition) \
PR_BEGIN_MACRO \
gTotalTests++; \
if (!aCondition) \
if (!aCondition) { \
gPassedTests++; \
else \
fail("Expected false, got true on line %d!", __LINE__); \
} else { \
fail("Expected false, got true at %s:%d!", __FILE__, __LINE__); \
} \
PR_END_MACRO
#define do_check_success(aResult) \
do_check_true(NS_SUCCEEDED(aResult))
#define do_check_eq(aFirst, aSecond) \
do_check_true(aFirst == aSecond)
already_AddRefed<mozIStorageConnection>
getMemoryDatabase()
{
nsCOMPtr<mozIStorageService> ss =
do_GetService("@mozilla.org/storage/service;1");
nsCOMPtr<mozIStorageConnection> conn;
(void)ss->OpenSpecialDatabase("memory", getter_AddRefs(conn));
nsresult rv = ss->OpenSpecialDatabase("memory", getter_AddRefs(conn));
do_check_success(rv);
return conn.forget();
}
already_AddRefed<mozIStorageConnection>
getDatabase()
{
nsCOMPtr<nsIFile> dbFile;
(void)NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
getter_AddRefs(dbFile));
NS_ASSERTION(dbFile, "The directory doesn't exists?!");
nsresult rv = dbFile->Append(NS_LITERAL_STRING("storage_test_db.sqlite"));
do_check_success(rv);
nsCOMPtr<mozIStorageService> ss =
do_GetService("@mozilla.org/storage/service;1");
nsCOMPtr<mozIStorageConnection> conn;
rv = ss->OpenDatabase(dbFile, getter_AddRefs(conn));
do_check_success(rv);
return conn.forget();
}

View File

@ -0,0 +1,284 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim set:sw=2 ts=2 et lcs=trail\:.,tab\:>~ : */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is storage test code.
*
* The Initial Developer of the Original Code is
* The Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Shawn Wilsher <me@shawnwilsher.com> (Original Author)
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "storage_test_harness.h"
#include "mozilla/Monitor.h"
#include "nsThreadUtils.h"
#include "mozIStorageStatement.h"
/**
* This file tests that our implementation around sqlite3_unlock_notify works
* as expected.
*/
////////////////////////////////////////////////////////////////////////////////
//// Helpers
enum State {
STARTING,
WRITE_LOCK,
READ_LOCK,
TEST_DONE
};
class DatabaseLocker : public nsRunnable
{
public:
DatabaseLocker(const char* aSQL)
: monitor("DatabaseLocker::monitor")
, mSQL(aSQL)
, mState(STARTING)
{
}
void RunInBackground()
{
(void)NS_NewThread(getter_AddRefs(mThread));
do_check_true(mThread);
do_check_success(mThread->Dispatch(this, NS_DISPATCH_NORMAL));
}
NS_IMETHOD Run()
{
mozilla::MonitorAutoEnter lock(monitor);
nsCOMPtr<mozIStorageConnection> db(getDatabase());
nsCString sql(mSQL);
nsCOMPtr<mozIStorageStatement> stmt;
do_check_success(db->CreateStatement(sql, getter_AddRefs(stmt)));
PRBool hasResult;
do_check_success(stmt->ExecuteStep(&hasResult));
Notify(WRITE_LOCK);
WaitFor(TEST_DONE);
return NS_OK;
}
void WaitFor(State aState)
{
monitor.AssertCurrentThreadIn();
while (mState != aState) {
do_check_success(monitor.Wait());
}
}
void Notify(State aState)
{
monitor.AssertCurrentThreadIn();
mState = aState;
do_check_success(monitor.Notify());
}
mozilla::Monitor monitor;
protected:
nsCOMPtr<nsIThread> mThread;
const char *const mSQL;
State mState;
};
class DatabaseTester : public DatabaseLocker
{
public:
DatabaseTester(mozIStorageConnection *aConnection,
const char* aSQL)
: DatabaseLocker(aSQL)
, mConnection(aConnection)
{
}
NS_IMETHOD Run()
{
mozilla::MonitorAutoEnter lock(monitor);
WaitFor(READ_LOCK);
nsCString sql(mSQL);
nsCOMPtr<mozIStorageStatement> stmt;
do_check_success(mConnection->CreateStatement(sql, getter_AddRefs(stmt)));
PRBool hasResult;
nsresult rv = stmt->ExecuteStep(&hasResult);
do_check_eq(rv, NS_ERROR_FILE_IS_LOCKED);
// Finalize our statement and null out our connection before notifying to
// ensure that we close on the proper thread.
rv = stmt->Finalize();
do_check_eq(rv, NS_ERROR_FILE_IS_LOCKED);
mConnection = nsnull;
Notify(TEST_DONE);
return NS_OK;
}
private:
nsCOMPtr<mozIStorageConnection> mConnection;
State mState;
};
////////////////////////////////////////////////////////////////////////////////
//// Test Functions
void
setup()
{
nsCOMPtr<mozIStorageConnection> db(getDatabase());
// Create and populate a dummy table.
nsresult rv = db->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"CREATE TABLE test (id INTEGER PRIMARY KEY, data STRING)"
));
do_check_success(rv);
rv = db->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"INSERT INTO test (data) VALUES ('foo')"
));
do_check_success(rv);
rv = db->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"INSERT INTO test (data) VALUES ('bar')"
));
do_check_success(rv);
rv = db->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
"CREATE UNIQUE INDEX unique_data ON test (data)"
));
do_check_success(rv);
}
void
test_step_locked_does_not_block_main_thread()
{
nsCOMPtr<mozIStorageConnection> db(getDatabase());
// Need to prepare our statement ahead of time so we make sure to only test
// step and not prepare.
nsCOMPtr<mozIStorageStatement> stmt;
nsresult rv = db->CreateStatement(NS_LITERAL_CSTRING(
"INSERT INTO test (data) VALUES ('test1')"
), getter_AddRefs(stmt));
do_check_success(rv);
nsRefPtr<DatabaseLocker> locker(new DatabaseLocker("SELECT * FROM test"));
do_check_true(locker);
mozilla::MonitorAutoEnter lock(locker->monitor);
locker->RunInBackground();
// Wait for the locker to notify us that it has locked the database properly.
locker->WaitFor(WRITE_LOCK);
PRBool hasResult;
rv = stmt->ExecuteStep(&hasResult);
do_check_eq(rv, NS_ERROR_FILE_IS_LOCKED);
locker->Notify(TEST_DONE);
}
void
test_drop_index_does_not_loop()
{
nsCOMPtr<mozIStorageConnection> db(getDatabase());
// Need to prepare our statement ahead of time so we make sure to only test
// step and not prepare.
nsCOMPtr<mozIStorageStatement> stmt;
nsresult rv = db->CreateStatement(NS_LITERAL_CSTRING(
"SELECT * FROM test"
), getter_AddRefs(stmt));
do_check_success(rv);
nsRefPtr<DatabaseTester> tester =
new DatabaseTester(db, "DROP INDEX unique_data");
do_check_true(tester);
mozilla::MonitorAutoEnter lock(tester->monitor);
tester->RunInBackground();
// Hold a read lock on the database, and then let the tester try to execute.
PRBool hasResult;
rv = stmt->ExecuteStep(&hasResult);
do_check_success(rv);
do_check_true(hasResult);
tester->Notify(READ_LOCK);
// Make sure the tester finishes its test before we move on.
tester->WaitFor(TEST_DONE);
}
void
test_drop_table_does_not_loop()
{
nsCOMPtr<mozIStorageConnection> db(getDatabase());
// Need to prepare our statement ahead of time so we make sure to only test
// step and not prepare.
nsCOMPtr<mozIStorageStatement> stmt;
nsresult rv = db->CreateStatement(NS_LITERAL_CSTRING(
"SELECT * FROM test"
), getter_AddRefs(stmt));
do_check_success(rv);
nsRefPtr<DatabaseTester> tester(new DatabaseTester(db, "DROP TABLE test"));
do_check_true(tester);
mozilla::MonitorAutoEnter lock(tester->monitor);
tester->RunInBackground();
// Hold a read lock on the database, and then let the tester try to execute.
PRBool hasResult;
rv = stmt->ExecuteStep(&hasResult);
do_check_success(rv);
do_check_true(hasResult);
tester->Notify(READ_LOCK);
// Make sure the tester finishes its test before we move on.
tester->WaitFor(TEST_DONE);
}
void (*gTests[])(void) = {
setup,
test_step_locked_does_not_block_main_thread,
test_drop_index_does_not_loop,
test_drop_table_does_not_loop,
};
const char *file = __FILE__;
#define TEST_NAME "sqlite3_unlock_notify"
#define TEST_FILE file
#include "storage_test_harness_tail.h"

View File

@ -72,11 +72,13 @@ Tester.prototype = {
waitForWindowsState: function Tester_waitForWindowsState(aCallback) {
if (this.currentTest && window.gBrowser && gBrowser.tabs.length > 1) {
let msg = "Found " + (gBrowser.tabs.length - 1) +
" unexpected tab(s) at the end of test run";
this.currentTest.addResult(new testResult(false, msg, "", false));
while (gBrowser.tabs.length > 1)
gBrowser.removeTab(gBrowser.tabContainer.lastChild);
while (gBrowser.tabs.length > 1) {
let lastTab = gBrowser.tabContainer.lastChild;
let msg = "Found an unexpected tab at the end of test run: " +
lastTab.linkedBrowser.currentURI.spec;
this.currentTest.addResult(new testResult(false, msg, "", false));
gBrowser.removeTab(lastTab);
}
}
this.dumper.dump("TEST-INFO | checking window state\n");

View File

@ -43,6 +43,9 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
PARALLEL_DIRS = hudservice \
$(NULL)
EXTRA_PP_COMPONENTS = jsconsole-clhandler.js
include $(topsrcdir)/config/rules.mk

View File

@ -79,7 +79,7 @@
</keyset>
<popupset id="ContextMenus">
<popup id="ConsoleContext">
<menupopup id="ConsoleContext">
<menuitem type="radio" id="Console:sortAscend"
label="&sortFirst.label;" accesskey="&sortFirst.accesskey;"
oncommand="changeSortOrder('forward');"/>
@ -89,7 +89,7 @@
<menuseparator/>
<menuitem id="menu_copy_cm" command="cmd_copy"
label="&copyCmd.label;" accesskey="&copyCmd.accesskey;"/>
</popup>
</menupopup>
</popupset>
<toolbox id="console-toolbox">

View File

@ -0,0 +1,205 @@
/* ***** 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 DevTools code
*
* The Initial Developer of the Original Code is
* Mozilla Corporation
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* David Dahl <ddahl@mozilla.com>
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
.hud-box {
border-bottom: 1px solid #aaa;
}
.hud-outer-wrapper {
width: 100%;
height: 100%;
}
.hud-filter-btn > .toolbarbutton-icon { display: none; }
.hud-console-wrapper {
width: 100%;
overflow: auto;
max-height: 400px;
height: 400px;
}
.hud-main-label {
font-size: 1em;
padding-top: 0.33em;
font-weight: bold;
}
.hud-output-node div {
-moz-user-select: text;
}
.hud-output-node .hud-network {
color: blue;
}
.hud-output-node .hud-error {
color: red;
}
.hud-output-node .hud-log {
color: black;
}
.hud-output-node .hud-warn {
color: orange;
}
.hud-output-node .hud-info {
color: green;
}
.hud-output-node .hud-exception {
color: red; font-weight: bold;
}
.hud-hidden {
display: none;
}
.hud-msg-node {
width: 100%;
margin-top: 0.3em;
margin-bottom: 0.3em;
padding-left: 0.3em;
border-bottom: 1px solid #eee;
}
.hud-output-node {
height:380px;
max-height: 380px;
border-bottom: 1px solid #ddd;
border-top: 1px solid #ddd;
overflow-x: auto; overflow: auto;
font: 1em monospace; background-color: white;
width: 100%;
}
/* JSTerm Styles */
.jsterm-wrapper-node {
font-family: monospace;
font-size: 1em;
background-color: #000;
border: 1px solid #333;
padding: 0.1em;
width: 100%;
height: 400px;
}
.jsterm-output-node {
width: 100%;
height: 400px;
color: white;
background-color: black;
overflow: auto;
overflow-x: auto;
position: absolute;
-moz-box-direction: reverse;
}
.jsterm-output-node div {
-moz-user-select: text;
}
.jsterm-scroll-to-node {
height: 1px; width: 1px; position: relative; top: 92%; display: block;
}
.jsterm-input-node {
width: 98%;
font-family: monospace;
font-size: 1.2em;
line-height: 1.6em;
background-color: black;
color: white;
}
.jsterm-output-line {
font-size: 1.2em;
}
%include ../../../themes/pinstripe/global/shared.inc
toolbar[mode="text"] .toolbarbutton-text {
margin: 1px 2px !important;
}
toolbarbutton:hover:active,
toolbarbutton[open="true"] {
padding-top: 2px;
padding-bottom: 2px;
-moz-padding-start: 2px;
-moz-padding-end: 1px;
}
toolbarbutton[disabled="true"],
toolbarbutton[disabled="true"]:hover,
toolbarbutton[disabled="true"]:hover:active,
toolbarbutton[disabled="true"][open="true"] {
padding-top: 2px;
padding-bottom: 2px;
-moz-padding-start: 2px;
-moz-padding-end: 1px;
}
/* ..... checked state ..... */
toolbarbutton[checked="true"] {
border-color: ThreeDShadow ThreeDHighlight ThreeDHighlight ThreeDShadow !important;
padding-top: 2px !important;
padding-bottom: 2px !important;
-moz-padding-start: 2px !important;
-moz-padding-end: 1px !important;
}
/* ..... unchecked state ..... */
toolbarbutton[checked="false"] {
padding-top: 2px !important;
padding-bottom: 2px !important;
-moz-padding-start: 2px !important;
-moz-padding-end: 1px !important;
}
toolbar {
padding: 1px 0px;
-moz-box-align: center;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,55 @@
#
# ***** 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 HUDService code.
#
# The Initial Developer of the Original Code is Mozilla Corporation.
#
# Portions created by the Initial Developer are Copyright (C) 2010
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# David Dahl <ddahl@mozilla.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
DEPTH = ../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = hudservice
EXTRA_JS_MODULES = HUDService.jsm \
$(NULL)
ifdef ENABLE_TESTS
DIRS += tests
endif
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,50 @@
#
# ***** 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 HUDService code.
#
# The Initial Developer of the Original Code is
# Mozilla Corporation.
# Portions created by the Initial Developer are Copyright (C) 2010
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# David Dahl <ddahl@mozilla.com> (Original author)
#
# Alternatively, the contents of this file may be used under the terms of
# either of 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 *****
DEPTH = ../../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = test_hudservice
DIRS = browser
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,64 @@
# ***** 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 HUD test code.
#
# 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):
# David Dahl <ddahl@mozilla.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either of 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 *****
DEPTH = ../../../../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
relativesrcdir = toolkit/components/console/hudservice/tests/browser
include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_BROWSER_TEST_FILES = \
browser_HUDServiceTestsAll.js \
$(NULL)
_BROWSER_TEST_PAGES = \
test-console.html \
test-network.html \
test-mutation.html \
testscript.js \
test-filter.html \
test-observe-http-ajax.html \
test-data.json \
$(NULL)
libs:: $(_BROWSER_TEST_FILES)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)
libs:: $(_BROWSER_TEST_PAGES)
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/browser/$(relativesrcdir)

View File

@ -0,0 +1,420 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* ***** 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 DevTools test code.
*
* 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):
* David Dahl <ddahl@mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
XPCOMUtils.defineLazyGetter(this, "HUDService", function () {
Cu.import("resource://gre/modules/HUDService.jsm");
try {
return HUDService;
}
catch (ex) {
dump(ex + "\n");
}
});
let log = function _log(msg) {
dump("*** HUD Browser Test Log: " + msg + "\n");
};
const TEST_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-console.html";
const TEST_HTTP_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-observe-http-ajax.html";
const TEST_NETWORK_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-network.html";
const TEST_FILTER_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-filter.html";
const TEST_MUTATION_URI = "http://example.com/browser/toolkit/components/console/hudservice/tests/browser/test-mutation.html";
function noCacheUriSpec(aUriSpec) {
return aUriSpec + "?_=" + Date.now();
}
content.location.href = TEST_URI;
function testRegistries() {
var displaysIdx = HUDService.displaysIndex();
ok(displaysIdx.length == 1, "one display id found");
var display = displaysIdx[0];
var registry = HUDService.displayRegistry;
var uri = registry[display];
ok(registry[display], "we have a URI: " + registry[display]);
var uriRegistry = HUDService.uriRegistry;
ok(uriRegistry[uri].length == 1, "uri registry is working");
}
function testGetDisplayByURISpec() {
var outputNode = HUDService.getDisplayByURISpec(TEST_URI);
hudId = outputNode.getAttribute("id");
ok(hudId == HUDService.displaysIndex()[0], "outputNode fetched by URIspec");
}
function introspectLogNodes() {
var console =
tab.linkedBrowser.contentWindow.wrappedJSObject.console;
ok(console, "console exists");
console.log("I am a log message");
console.error("I am an error");
console.info("I am an info message");
console.warn("I am a warning message");
var len = HUDService.displaysIndex().length;
let id = HUDService.displaysIndex()[len - 1];
let hudBox = tab.ownerDocument.getElementById(id);
let outputNode =
hudBox.querySelectorAll(".hud-output-node")[0];
ok(outputNode.childElementCount > 0, "more than 1 child node");
let domLogEntries =
outputNode.childNodes;
let count = outputNode.childNodes.length;
ok(count > 0, "LogCount: " + count);
let klasses = ["hud-msg-node hud-log",
"hud-msg-node hud-warn",
"hud-msg-node hud-info",
"hud-msg-node hud-error",
"hud-msg-node hud-exception",
"hud-msg-node hud-network"];
function verifyClass(klass) {
let len = klasses.length;
for (var i = 0; i < len; i++) {
if (klass == klasses[i]) {
return true;
}
}
return false;
}
for (var i = 0; i < count; i++) {
let klass = domLogEntries[i].getAttribute("class");
ok(verifyClass(klass),
"Log Node class verified: " + klass);
}
}
function getAllHUDS() {
var allHuds = HUDService.displays();
ok(typeof allHuds == "object", "allHuds is an object");
var idx = HUDService.displaysIndex();
hudId = idx[0];
ok(typeof idx == "object", "displays is an object");
ok(typeof idx.push == "function", "displaysIndex is an array");
var len = idx.length;
ok(idx.length > 0, "idx.length > 0: " + len);
}
function testGetDisplayByLoadGroup() {
var outputNode = HUDService.getDisplayByURISpec(TEST_URI);
var hudId = outputNode.getAttribute("id");
var loadGroup = HUDService.getLoadGroup(hudId);
var display = HUDService.getDisplayByLoadGroup(loadGroup);
ok(display.getAttribute("id") == hudId, "got display by loadGroup");
content.location = TEST_HTTP_URI;
executeSoon(function () {
let id = HUDService.displaysIndex()[0];
let domLogEntries =
outputNode.childNodes;
let count = outputNode.childNodes.length;
ok(count > 0, "LogCount: " + count);
let klasses = ["hud-network"];
function verifyClass(klass) {
let len = klasses.length;
for (var i = 0; i < len; i++) {
if (klass == klasses[i]) {
return true;
}
}
return false;
}
for (var i = 0; i < count; i++) {
let klass = domLogEntries[i].getAttribute("class");
if (klass != "hud-network") {
continue;
}
ok(verifyClass(klass),
"Log Node network class verified");
}
});
}
function testUnregister() {
HUDService.deactivateHUDForContext(tab);
ok(HUDService.displays()[0] == undefined,
"No heads up displays are registered");
HUDService.shutdown();
}
function getHUDById() {
let hud = HUDService.getHeadsUpDisplay(hudId);
ok(hud.getAttribute("id") == hudId, "found HUD node by Id.");
}
function testGetContentWindowFromHUDId() {
let window = HUDService.getContentWindowFromHUDId(hudId);
ok(window.document, "we have a contentWindow");
}
function testConsoleLoggingAPI(aMethod)
{
filterBox.value = "foo";
browser.contentWindow.wrappedJSObject.console[aMethod]("foo-bar-baz");
browser.contentWindow.wrappedJSObject.console[aMethod]("bar-baz");
var count = outputNode.querySelectorAll(".hud-hidden").length;
ok(count == 1, "1 hidden " + aMethod + " node found");
HUDService.clearDisplay(hudId);
// now toggle the current method off - make sure no visible message
// nodes are logged
filterBox.value = "";
HUDService.setFilterState(hudId, aMethod, false);
browser.contentWindow.wrappedJSObject.console[aMethod]("foo-bar-baz");
count = outputNode.querySelectorAll(".hud-hidden").length;
ok(count == 0, aMethod + " logging tunred off, 0 messages logged");
HUDService.clearDisplay(hudId);
filterBox.value = "";
}
function testLogEntry(aOutputNode, aMatchString, aSuccessErrObj)
{
executeSoon(function (){
var msgs = aOutputNode.childNodes;
for (var i = 0; i < msgs.length; i++) {
var message = msgs[i].innerHTML.indexOf(aMatchString);
if (message > -1) {
ok(true, aSuccessErrObj.success);
return;
}
else {
throw new Error(aSuccessErrObj.err);
}
}
});
}
// test network logging
function testNet()
{
HUDService.activateHUDForContext(tab);
content.location = TEST_NETWORK_URI;
executeSoon(function () {
HUDService.setFilterState(hudId, "network", true);
filterBox.value = "";
var successMsg =
"Found the loggged network message referencing a js file";
var errMsg = "Could not get logged network message for js file";
testLogEntry(outputNode,
"Network:", { success: successMsg, err: errMsg });
content.location.href = noCacheUriSpec(TEST_NETWORK_URI);
});
}
// test DOM Mutation logging
function testDOMMutation()
{
HUDService.setFilterState(hudId, "mutation", true);
filterBox.value = "";
content.location = TEST_MUTATION_URI;
executeSoon(function() {
content.wrappedJSObject.addEventListener("DOMContentLoaded",
function () {
var successMsg = "Found Mutation Log Message";
var errMsg = "Could NOT find Mutation Log Message";
var display = HUDService.getHeadsUpDisplay(hudId);
var outputNode = display.querySelectorAll(".hud-output-node")[0];
testLogEntry(outputNode,
"Mutation", { success: successMsg, err: errMsg });
}, false);
content.location.href = TEST_NETWORK_URI;
});
}
function testCreateDisplay() {
ok(typeof cs.consoleDisplays == "object",
"consoledisplays exist");
ok(typeof cs.displayIndexes == "object",
"console indexes exist");
cs.createDisplay("foo");
ok(typeof cs.consoleDisplays["foo"] == "object",
"foo display exists");
ok(typeof cs.displayIndexes["foo"] == "object",
"foo index exists");
}
function testRecordEntry() {
var config = {
logLevel: "network",
message: "HumminaHummina!",
activity: {
stage: "barStage",
data: "bar bar bar bar"
}
};
var entry = cs.recordEntry("foo", config);
var res = entry.id;
ok(entry.id != null, "Entry.id is: " + res);
ok(cs.displayIndexes["foo"].length == 1,
"We added one entry.");
entry = cs.getEntry(res);
ok(entry.id > -1,
"We got an entry through the global interface");
}
function testRecordManyEntries() {
var configArr = [];
for (var i = 0; i < 1000; i++){
let config = {
logLevel: "network",
message: "HumminaHummina!",
activity: {
stage: "barStage",
data: "bar bar bar bar"
}
};
configArr.push(config);
}
var start = Date.now();
cs.recordEntries("foo", configArr);
var end = Date.now();
var elapsed = end - start;
ok(cs.displayIndexes["foo"].length == 1001,
"1001 entries in foo now");
}
function testIteration() {
var id = "foo";
var it = cs.displayStore(id);
var entry = it.next();
var entry2 = it.next();
let entries = [];
for (var i = 0; i < 100; i++) {
let _entry = it.next();
entries.push(_entry);
}
ok(entries.length == 100, "entries length == 100");
let entries2 = [];
for (var i = 0; i < 100; i++){
let _entry = it.next();
entries2.push(_entry);
}
ok(entries[0].id != entries2[0].id,
"two distinct pages of log entries");
}
let tab, browser, hudId, hud, filterBox, outputNode, cs;
let win = gBrowser.selectedBrowser;
tab = gBrowser.selectedTab;
browser = gBrowser.getBrowserForTab(tab);
function test() {
waitForExplicitFinish();
browser.addEventListener("DOMContentLoaded", function onLoad(event) {
browser.removeEventListener("DOMContentLoaded", onLoad, false);
HUDService.activateHUDForContext(tab);
hudId = HUDService.displaysIndex()[0];
hud = HUDService.getHeadsUpDisplay(hudId);
cs = HUDService.storage;
// enter some filter text into the filter textbox
filterBox = hud.querySelectorAll(".hud-filter-box")[0];
outputNode = HUDService.getHeadsUpDisplay(hudId);
executeSoon(function () {
testRegistries();
testGetDisplayByURISpec();
introspectLogNodes();
getAllHUDS();
getHUDById();
testGetDisplayByLoadGroup();
testGetContentWindowFromHUDId();
content.location.href = TEST_FILTER_URI;
testConsoleLoggingAPI("log");
testConsoleLoggingAPI("info");
testConsoleLoggingAPI("warn");
testConsoleLoggingAPI("error");
testConsoleLoggingAPI("exception");
testNet();
// testDOMMutation();
// ConsoleStorageTests
testCreateDisplay();
testRecordEntry();
testRecordManyEntries();
testIteration();
// testUnregister();
executeSoon(function () {
HUDService.deactivateHUDForContext(tab);
HUDService.shutdown();
});
finish();
});
}, false);
}

View File

@ -0,0 +1,22 @@
<!DOCTYPE HTML>
<html dir="ltr" xml:lang="en-US" lang="en-US"><head>
<title>Console test</title>
<script type="text/javascript">
dump("i am dumping this");
function test() {
var str = "Dolske Digs Bacon, Now and Forevermore."
for (var i=0; i < 5; i++) {
console.log(str);
}
}
console.info("INLINE SCRIPT:");
test();
console.warn("I'm warning you, he will eat up all yr bacon.");
console.error("Error Message");
</script>
</head>
<body>
<h1>Heads Up Display Demo</h1>
<button onclick="test();">Log stuff about Dolske</button>
</body>
</html>

View File

@ -0,0 +1 @@
{ id: "test JSON data", myArray: [ "foo", "bar", "baz", "biff" ] }

View File

@ -0,0 +1,10 @@
<!DOCTYPE HTML>
<html dir="ltr" xml:lang="en-US" lang="en-US"><head>
<title>Console test</title>
<script type="text/javascript">
</script>
</head>
<body>
<h1>Heads Up Display Filter Test Page</h1>
</body>
</html>

View File

@ -0,0 +1,15 @@
<!DOCTYPE HTML>
<html dir="ltr" xml:lang="en-US" lang="en-US">
<head>
<title>Console mutation test</title>
<script>
window.onload = function (){
var node = document.createElement("div");
document.body.appendChild(node);
};
</script>
</head>
<body>
<h1>Heads Up Display DOM Mutation Test Page</h1>
</body>
</html>

View File

@ -0,0 +1,9 @@
<!DOCTYPE HTML>
<html dir="ltr" xml:lang="en-US" lang="en-US"><head>
<title>Console network test</title>
<script src="testscript.js"></script>
</head>
<body>
<h1>Heads Up Display Network Test Page</h1>
</body>
</html>

View File

@ -0,0 +1,16 @@
<!DOCTYPE HTML>
<html dir="ltr" xml:lang="en-US" lang="en-US"><head>
<title>Console HTTP test page</title>
<script type="text/javascript">
function test() {
var xmlhttp = new XMLHttpRequest();
xmlhttp.open('get', 'test-data.json', false);
xmlhttp.send(null);
}
</script>
</head>
<body onload="test();">
<h1>Heads Up Display HTTP & AJAX Test Page</h1>
<h2>This page fires an ajax request so we can see the http logging of the console</h2>
</body>
</html>

View File

@ -0,0 +1 @@
console.log("running network console logging tests");

View File

@ -3,3 +3,4 @@ toolkit.jar:
*+ content/global/console.xul (content/console.xul)
+ content/global/console.css (content/console.css)
+ content/global/consoleBindings.xml (content/consoleBindings.xml)
*+ content/global/headsUpDisplay.css (content/headsUpDisplay.css)

View File

@ -44,8 +44,8 @@
# Help Window's right-click menu
<popupset id="contentAreaContextSet">
<popup id="contentAreaContextMenu"
onpopupshowing="goUpdateCommand('cmd_copy')">
<menupopup id="contentAreaContextMenu"
onpopupshowing="goUpdateCommand('cmd_copy')">
<menuitem id="context-back"
label="&backButton.label;"
accesskey="&backButton.accesskey;"
@ -88,6 +88,6 @@
accesskey="&zLevel.accesskey;"
oncommand="toggleZLevel(this);"/>
#endif
</popup>
</menupopup>
</popupset>
</overlay>

View File

@ -25,8 +25,8 @@
</commandset>
<popupset id="contentAreaContextSet">
<popup id="contentAreaContextMenu"
onpopupshowing="goUpdateCommand('cmd_copy')">
<menupopup id="contentAreaContextMenu"
onpopupshowing="goUpdateCommand('cmd_copy')">
<menuitem id="context-copy"
label="&copyCmd.label;"
accesskey="&copyCmd.accesskey;"
@ -36,7 +36,7 @@
label="&selectAllCmd.label;"
accesskey="&selectAllCmd.accesskey;"
command="cmd_selectAll"/>
</popup>
</menupopup>
</popupset>
<hbox id="filler" style="min-width: 0%;">

View File

@ -55,7 +55,7 @@
<stringbundle id="configBundle" src="chrome://global/locale/config.properties"/>
<popup id="configContext" onpopupshowing="if (event.target == this) updateContextMenu();">
<menupopup id="configContext" onpopupshowing="if (event.target == this) updateContextMenu();">
<menuitem id="toggleSelected" default="true"
label="&toggle.label;" accesskey="&toggle.accesskey;"
oncommand="ModifySelected();"/>
@ -74,7 +74,7 @@
</menupopup>
</menu>
<menuitem id="resetSelected" label="&reset.label;" accesskey="&reset.accesskey;" oncommand="ResetSelected();"/>
</popup>
</menupopup>
<keyset id="configTreeKeyset" disabled="true">
<key keycode="VK_ENTER" oncommand="ModifySelected();"/>

View File

@ -111,13 +111,13 @@
<key id="key_textZoomReset2" key="&textReset.commandkey2;" command="cmd_textZoomReset" modifiers="accel"/>
</keyset>
<popup id="viewSourceContextMenu">
<menupopup id="viewSourceContextMenu">
<menuitem id="cMenu_findAgain"/>
<menuseparator/>
<menuitem id="cMenu_copy"/>
<menuseparator/>
<menuitem id="cMenu_selectAll"/>
</popup>
</menupopup>
<!-- Menu -->
<toolbox id="viewSource-toolbox">

View File

@ -142,7 +142,7 @@
</keyset>
<popup id="viewSourceContextMenu">
<menupopup id="viewSourceContextMenu">
<menuitem id="context-back"
label="&backCmd.label;"
accesskey="&backCmd.accesskey;"
@ -159,7 +159,7 @@
<menuitem id="cMenu_copy"/>
<menuseparator/>
<menuitem id="cMenu_selectAll"/>
</popup>
</menupopup>
<!-- Menu -->
<toolbox id="viewSource-toolbox">

View File

@ -0,0 +1,64 @@
<!-- ***** 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 DevTools Code
-
- 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):
- David Dahl <ddahl@mozilla.com>
-
- Alternatively, the contents of this file may be used under the terms of
- either the GNU General Public License Version 2 or later (the "GPL"), or
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- in which case the provisions of the GPL or the LGPL are applicable instead
- of those above. If you wish to allow use of your version of this file only
- under the terms of either the GPL or the LGPL, and not to allow others to
- use your version of this file under the terms of the MPL, indicate your
- decision by deleting the provisions above and replace them with the notice
- and other provisions required by the LGPL or the GPL. 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 ***** -->
<!ENTITY hud.title "Heads Up Display">
<!ENTITY errFile.label "Source File:">
<!ENTITY errLine.label "Line:">
<!ENTITY errColumn.label "Column:">
<!ENTITY all.label "All">
<!ENTITY all.accesskey "A">
<!ENTITY errors.label "Errors">
<!ENTITY errors.accesskey "E">
<!ENTITY warnings.label "Warnings">
<!ENTITY warnings.accesskey "W">
<!ENTITY messages.label "Messages">
<!ENTITY messages.accesskey "M">
<!ENTITY clear.label "Clear">
<!ENTITY clear.accesskey "C">
<!ENTITY codeEval.label "Code:">
<!ENTITY codeEval.accesskey "o">
<!ENTITY evaluate.label "Evaluate">
<!ENTITY evaluate.accesskey "v">
<!ENTITY copyCmd.label "Copy">
<!ENTITY copyCmd.accesskey "C">
<!ENTITY copyCmd.commandkey "C">
<!ENTITY closeCmd.commandkey "w">
<!ENTITY focus1.commandkey "l">
<!ENTITY focus2.commandkey "d">

View File

@ -0,0 +1,37 @@
typeError=Error:
typeWarning=Warning:
typeNetwork=Network:
typeException=Exception:
typeCssParser=CSS Parser:
typeStrict=Strict Warning:
msgCategory=Category:
errFile=Source File: %S
errLine=Line: %S
errLineCol=Line: %S, Column: %S
errCode=Source Code:
hudTitle=Heads Up Display
jsWorkspaceTitle=JS Workspace
btnHide=Hide
btnPrefs=Preferences
btnMutation=DOM Mutation
tipMutation=Toggle DOM Mutation event logging
btnNetwork=Network
tipNetwork=Toggle Network event logging
btnCSSParser=CSS Warnings
tipCSSParser=Toggle CSS Warning logging
btnException=Exceptions
tipException=Toggle Exception logging
btnError=Error
tipError=Toggle console.error logging
btnInfo=Info
tipInfo=Toggle console.info logging
btnWarn=Warnings
tipWarn=Toggle console.warn logging
btnLog=Log
tipLog=Toggle console.log logging
btnGlobal=Global Messages
tipGlobal=Toggle Global Message logging
localConsole=Local Console
btnClear=Clear Console
tipClear=Clear the console output
stringFilterClear=Clear Filter

View File

@ -35,6 +35,8 @@
+ locale/@AB_CD@/global/finddialog.dtd (%chrome/global/finddialog.dtd)
+ locale/@AB_CD@/global/finddialog.properties (%chrome/global/finddialog.properties)
locale/@AB_CD@/global/globalKeys.dtd (%chrome/global/globalKeys.dtd)
* locale/@AB_CD@/global/headsUpDisplay.dtd (%chrome/global/headsUpDisplay.dtd)
+ locale/@AB_CD@/global/headsUpDisplay.properties (%chrome/global/headsUpDisplay.properties)
+ locale/@AB_CD@/global/intl.css (%chrome/global/intl.css)
+ locale/@AB_CD@/global/intl.properties (%chrome/global/intl.properties)
+ locale/@AB_CD@/global/keys.properties (%chrome/global/keys.properties)

View File

@ -33,12 +33,13 @@ let gGen, dm, dmui, chromeWindow, testCleanup;
function test()
{
testSetup();
SimpleTest.waitForExplicitFinish();
if (testSetup()) {
SimpleTest.waitForExplicitFinish();
//Start test
gGen = doTest();
gGen.next();
//Start test
gGen = doTest();
gGen.next();
}
}
function doTest()
@ -128,8 +129,11 @@ function testSetup()
dm = Cc["@mozilla.org/download-manager;1"].
getService(Ci.nsIDownloadManager);
dmui = Cc["@mozilla.org/download-manager-ui;1"].
getService(Ci.nsIDownloadManagerUI);
dmui = getDMUI();
if (!dmui) {
todo(false, "skip test for toolkit download manager UI");
return false;
}
downloadListener = {
@ -153,6 +157,8 @@ function testSetup()
dm.removeListener(downloadListener);
chromeWindow.document.documentElement.setAttribute("windowtype", oldWinType);
};
return true;
}
function openBrowserWindow(callback)

View File

@ -4727,7 +4727,7 @@ function AddonWrapper(aAddon) {
return aAddon.iconURL;
if (this.hasResource("icon.png"))
return this.getResourceURL("icon.png");
return this.getResourceURI("icon.png").spec;
return null;
}, this);
@ -4776,7 +4776,7 @@ function AddonWrapper(aAddon) {
let screenshots = [];
if (aAddon.type == "theme" && this.hasResource("preview.png"))
screenshots.push(this.getResourceURL("preview.png"));
screenshots.push(this.getResourceURI("preview.png").spec);
return screenshots;
});
@ -4901,7 +4901,7 @@ function AddonWrapper(aAddon) {
return result;
},
this.getResourceURL = function(aPath) {
this.getResourceURI = function(aPath) {
let bundle = null;
if (aAddon instanceof DBAddonInternal) {
bundle = aAddon._sourceBundle = aAddon._installLocation
@ -4913,10 +4913,10 @@ function AddonWrapper(aAddon) {
if (bundle.isDirectory()) {
bundle.append(aPath);
return Services.io.newFileURI(bundle).spec;
return Services.io.newFileURI(bundle);
}
return buildJarURI(bundle, aPath).spec;
return buildJarURI(bundle, aPath);
}
}

View File

@ -48,15 +48,13 @@ include $(DEPTH)/config/autoconf.mk
MODULE = test_extensionmanager
DIRS = \
xpinstall \
$(NULL)
ifneq (mobile,$(MOZ_BUILD_APP))
DIRS += browser
DIRS += \
xpinstall \
browser \
$(NULL)
endif
XPCSHELL_TESTS = \
xpcshell \
$(NULL)

View File

@ -7,10 +7,27 @@ const redirect = RELATIVE_DIR + "redirect.sjs?";
const SUCCESS = 0;
var gTests = [];
var gStart = 0;
var gLast = 0;
var gPendingInstall = null;
function test() {
gStart = Date.now();
requestLongerTimeout(2);
waitForExplicitFinish();
registerCleanupFunction(function() {
if (gPendingInstall) {
gTests = [];
ok(false, "Timed out in the middle of downloading " + gPendingInstall.sourceURL);
try {
gPendingInstall.cancel();
}
catch (e) {
}
}
});
run_next_test();
}
@ -22,6 +39,7 @@ function end_test() {
cos.clearValidityOverride("untrusted.example.com", -1);
cos.clearValidityOverride("expired.example.com", -1);
info("All tests completed in " + (Date.now() - gStart) + "ms");
finish();
}
@ -35,20 +53,26 @@ function run_install_tests(callback) {
callback();
return;
}
gLast = Date.now();
let [url, expectedStatus, message] = gTests.shift();
AddonManager.getInstallForURL(url, function(install) {
gPendingInstall = install;
install.addListener({
onDownloadEnded: function(install) {
is(SUCCESS, expectedStatus, message);
run_next_install_test();
info("Install test ran in " + (Date.now() - gLast) + "ms");
// Don't proceed with the install
install.cancel();
gPendingInstall = null;
run_next_install_test();
return false;
},
onDownloadFailed: function(install) {
is(install.error, expectedStatus, message);
info("Install test ran in " + (Date.now() - gLast) + "ms");
gPendingInstall = null;
run_next_install_test();
}
});

View File

@ -9,8 +9,12 @@ const redirect = RELATIVE_DIR + "redirect.sjs?";
const SUCCESS = 0;
var gTests = [];
var gStart = 0;
var gLast = 0;
function test() {
gStart = Date.now();
requestLongerTimeout(2);
waitForExplicitFinish();
run_next_test();
@ -24,6 +28,7 @@ function end_test() {
cos.clearValidityOverride("untrusted.example.com", -1);
cos.clearValidityOverride("expired.example.com", -1);
info("All tests completed in " + (Date.now() - gStart) + "ms");
finish();
}
@ -37,6 +42,7 @@ function run_update_tests(callback) {
callback();
return;
}
gLast = Date.now();
let [url, expectedStatus, message] = gTests.shift();
AddonUpdateChecker.checkForUpdates("addon1@tests.mozilla.org", "extension",
@ -44,11 +50,13 @@ function run_update_tests(callback) {
onUpdateCheckComplete: function(updates) {
is(updates.length, 1);
is(SUCCESS, expectedStatus, message);
info("Update test ran in " + (Date.now() - gLast) + "ms");
run_next_update_test();
},
onUpdateCheckError: function(status) {
is(status, expectedStatus, message);
info("Update test ran in " + (Date.now() - gLast) + "ms");
run_next_update_test();
}
});

View File

@ -100,7 +100,7 @@ function check_test_1() {
dir.append("bootstrap1@tests.mozilla.org");
dir.append("bootstrap.js");
let uri = Services.io.newFileURI(dir).spec;
do_check_eq(b1.getResourceURL("bootstrap.js"), uri);
do_check_eq(b1.getResourceURI("bootstrap.js").spec, uri);
AddonManager.getAddonsWithOperationsByTypes(null, function(list) {
do_check_eq(list.length, 0);

View File

@ -55,7 +55,7 @@ function run_test() {
do_check_neq(a1, null);
do_check_true(a1.hasResource("install.rdf"));
let uri = Services.io.newURI(a1.getResourceURL("install.rdf"), "UTF-8", null);
let uri = a1.getResourceURI("install.rdf");
do_check_true(uri instanceof AM_Ci.nsIFileURL);
let file = uri.file;
do_check_true(file.exists());
@ -64,7 +64,7 @@ function run_test() {
do_check_neq(a2, null);
do_check_true(a2.hasResource("install.rdf"));
uri = Services.io.newURI(a2.getResourceURL("install.rdf"), "UTF-8", null);
uri = a2.getResourceURI("install.rdf");
do_check_true(uri instanceof AM_Ci.nsIFileURL);
file = uri.file;
do_check_true(file.exists());

View File

@ -51,7 +51,7 @@ function run_test() {
do_check_neq(addon, null);
do_check_true(addon.hasResource("binary"));
let uri = Services.io.newURI(addon.getResourceURL("binary"), "UTF-8", null);
let uri = addon.getResourceURI("binary");
do_check_true(uri instanceof AM_Ci.nsIFileURL);
let file = uri.file;
do_check_true(file.exists());

View File

@ -0,0 +1,48 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
// This verifies the functionality of getResourceURI
// There are two cases - with a filename it returns an nsIFileURL to the filename
// and with no parameters, it returns an nsIFileURL to the root of the addon
function run_test() {
do_test_pending();
createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1");
startupManager();
installAllFiles([do_get_file("data/unsigned.xpi")], function() {
restartManager();
AddonManager.getAddonByID("unsigned-xpi@tests.mozilla.org",
function(a1) {
do_check_neq(a1, null);
do_check_true(a1.hasResource("install.rdf"));
let uri = a1.getResourceURI("install.rdf");
do_check_true(uri instanceof AM_Ci.nsIFileURL);
let uri2 = a1.getResourceURI();
do_check_true(uri2 instanceof AM_Ci.nsIFileURL);
let addonDir = gProfD.clone();
addonDir.append("extensions");
addonDir.append("unsigned-xpi@tests.mozilla.org");
do_check_eq(uri2.file.path, addonDir.path);
a1.uninstall();
restartManager();
AddonManager.getAddonByID("unsigned-xpi@tests.mozilla.org",
function(newa1) {
do_check_eq(newa1, null);
do_test_finished();
});
});
});
}

View File

@ -60,7 +60,7 @@ function run_test_1() {
let file = do_get_addon("test_install1");
let uri = Services.io.newFileURI(file).spec;
do_check_eq(install.addon.getResourceURL("install.rdf"), "jar:" + uri + "!/install.rdf");
do_check_eq(install.addon.getResourceURI("install.rdf").spec, "jar:" + uri + "!/install.rdf");
do_check_eq(install.addon.iconURL, "jar:" + uri + "!/icon.png");
do_check_eq(install.iconURL, null);
@ -132,7 +132,7 @@ function check_test_1() {
dir.append("addon1@tests.mozilla.org");
dir.append("install.rdf");
let uri = Services.io.newFileURI(dir).spec;
do_check_eq(a1.getResourceURL("install.rdf"), uri);
do_check_eq(a1.getResourceURI("install.rdf").spec, uri);
a1.uninstall();
restartManager(0);

View File

@ -3755,6 +3755,8 @@
StrCmp "$R0" "\" +1 end ; If this isn't a relative path goto end
StrCmp "$R9" "\install.log" end +1 ; Skip the install.log
StrCmp "$R9" "\MapiProxy_InUse.dll" end +1 ; Skip the MapiProxy_InUse.dll
StrCmp "$R9" "\mozMapi32_InUse.dll" end +1 ; Skip the mozMapi32_InUse.dll
StrCpy $R1 "$INSTDIR$R9" ; Copy the install dir path and suffix it with the string
IfFileExists "$R1" +1 end

View File

@ -26,9 +26,9 @@
]]></script>
<popupset id="aTooltipSet">
<popup id="aTooltip" class="tooltip" onpopupshowing="return FillInTooltip(document.tooltipNode);" >
<tooltip id="aTooltip" class="tooltip" onpopupshowing="return FillInTooltip(document.tooltipNode);">
<label id="TOOLTIP-tooltipText" class="tooltip-label" flex="1"/>
</popup>
</tooltip>
</popupset>
</overlay>

View File

@ -50,6 +50,7 @@ toolbarbutton {
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.4);
}
toolbarbutton[open="true"],
toolbarbutton:not([disabled="true"]):active:hover {
text-shadow: none;
}
@ -119,13 +120,14 @@ toolbarbutton[type="menu-button"][disabled="true"]:hover:active {
-moz-box-align: center;
-moz-box-pack: center;
-moz-box-orient: vertical;
text-shadow: inherit;
}
/* .......... dropmarker .......... */
.toolbarbutton-menubutton-dropmarker {
-moz-appearance: none !important;
border: none !important;
border: none;
background-color: transparent !important;
list-style-image: url("chrome://global/skin/arrow/arrow-dn.png");
width: auto;

View File

@ -816,7 +816,11 @@ nsXREDirProvider::DoStartup()
obsSvc->NotifyObservers(nsnull, "profile-do-change", kStartup);
// Init the Extension Manager
nsCOMPtr<nsIObserver> em = do_GetService("@mozilla.org/addons/integration;1");
em->Observe(nsnull, "addons-startup", nsnull);
if (em) {
em->Observe(nsnull, "addons-startup", nsnull);
} else {
NS_WARNING("Failed to create Addons Manager.");
}
obsSvc->NotifyObservers(nsnull, "profile-after-change", kStartup);
// Any component that has registered for the profile-after-change category

View File

@ -270,6 +270,12 @@ while (<>) {
print $line;
}
} elsif ($line =~ "Test timed out") {
# Temporary logging for debugging mochitests bug 569237 et al
print $line;
system qw(xprop -root);
system qw(xwininfo -tree -root);
} else {
print $line;
}

View File

@ -103,9 +103,7 @@ class nsHashKey;
#endif // MOZ_SVG
#define NS_QUERY_CONTENT_EVENT 33
#ifdef MOZ_MEDIA
#define NS_MEDIA_EVENT 34
#endif // MOZ_MEDIA
#define NS_DRAG_EVENT 35
#define NS_NOTIFYPAINT_EVENT 36
#define NS_SIMPLE_GESTURE_EVENT 37
@ -401,8 +399,6 @@ class nsHashKey;
#define NS_RATECHANGE (NS_MEDIA_EVENT_START+17)
#define NS_DURATIONCHANGE (NS_MEDIA_EVENT_START+18)
#define NS_VOLUMECHANGE (NS_MEDIA_EVENT_START+19)
#define NS_MEDIA_ABORT (NS_MEDIA_EVENT_START+20)
#define NS_MEDIA_ERROR (NS_MEDIA_EVENT_START+21)
#endif // MOZ_MEDIA
// paint notification events

View File

@ -57,6 +57,7 @@ extern "C" {
NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_setSurfaceView(JNIEnv *jenv, jclass, jobject sv);
NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_setInitialSize(JNIEnv *jenv, jclass, int width, int height);
NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_putenv(JNIEnv *jenv, jclass, jstring map);
NS_EXPORT void JNICALL Java_org_mozilla_gecko_GeckoAppShell_onResume(JNIEnv *, jclass);
}
@ -106,3 +107,10 @@ Java_org_mozilla_gecko_GeckoAppShell_putenv(JNIEnv *jenv, jclass, jstring map)
jenv->ReleaseStringUTFChars(map, str);
}
NS_EXPORT void JNICALL
Java_org_mozilla_gecko_GeckoAppShell_onResume(JNIEnv *jenv, jclass jc)
{
if (nsAppShell::gAppShell)
nsAppShell::gAppShell->OnResume();
}

View File

@ -43,6 +43,7 @@
#include "nsIObserverService.h"
#include "nsIAppStartup.h"
#include "nsIGeolocationProvider.h"
#include "nsIPrefService.h"
#include "mozilla/Services.h"
#include "prenv.h"
@ -79,6 +80,8 @@ nsAppShell::nsAppShell()
: mQueueLock(nsnull),
mCondLock(nsnull),
mQueueCond(nsnull),
mPausedLock(nsnull),
mPaused(nsnull),
mNumDraws(0)
{
gAppShell = this;
@ -111,7 +114,9 @@ nsAppShell::Init()
mQueueLock = PR_NewLock();
mCondLock = PR_NewLock();
mPausedLock = PR_NewLock();
mQueueCond = PR_NewCondVar(mCondLock);
mPaused = PR_NewCondVar(mPausedLock);
return nsBaseAppShell::Init();
}
@ -238,7 +243,6 @@ nsAppShell::ProcessNextNativeEvent(PRBool mayWait)
NS_NAMED_LITERAL_STRING(context, "shutdown-persist");
obsServ->NotifyObservers(nsnull, "quit-application-granted", nsnull);
obsServ->NotifyObservers(nsnull, "quit-application-forced", nsnull);
obsServ->NotifyObservers(nsnull, "quit-application", nsnull);
obsServ->NotifyObservers(nsnull, "profile-change-net-teardown", context.get());
obsServ->NotifyObservers(nsnull, "profile-change-teardown", context.get());
obsServ->NotifyObservers(nsnull, "profile-before-change", context.get());
@ -249,9 +253,16 @@ nsAppShell::ProcessNextNativeEvent(PRBool mayWait)
}
case AndroidGeckoEvent::ACTIVITY_PAUSING: {
nsCOMPtr<nsIObserverService> obsServ =
mozilla::services::GetObserverService();
obsServ->NotifyObservers(nsnull, "profile-before-change", nsnull);
// We really want to send a notification like profile-before-change,
// but profile-before-change ends up shutting some things down instead
// of flushing data
nsCOMPtr<nsIPrefService> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
if (prefs)
prefs->SavePrefFile(nsnull);
// The OS is sending us to the background, block this thread until
// onResume is called to signal that we're back in the foreground
PR_WaitCondVar(mPaused, PR_INTERVAL_NO_TIMEOUT);
break;
}
@ -346,6 +357,15 @@ nsAppShell::RemoveNextEvent()
PR_Unlock(mQueueLock);
}
void
nsAppShell::OnResume()
{
PR_Lock(mPausedLock);
PR_NotifyCondVar(mPaused);
PR_Unlock(mPausedLock);
}
// Used by IPC code
namespace mozilla {

View File

@ -68,6 +68,8 @@ public:
void PostEvent(mozilla::AndroidGeckoEvent *event);
void RemoveNextEvent();
void OnResume();
protected:
virtual void ScheduleNativeEventCallback();
virtual ~nsAppShell();
@ -75,7 +77,9 @@ protected:
int mNumDraws;
PRLock *mQueueLock;
PRLock *mCondLock;
PRLock *mPausedLock;
PRCondVar *mQueueCond;
PRCondVar *mPaused;
nsTArray<mozilla::AndroidGeckoEvent *> mEventQueue;
mozilla::AndroidGeckoEvent *GetNextEvent();

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