Merge cvs-trunk-mirror -> mozilla-central

--HG--
rename : js/src/js.c => js/src/js.cpp
rename : js/src/jsinterp.c => js/src/jsinterp.cpp
rename : js/src/jsutil.c => js/src/jsutil.cpp
This commit is contained in:
benjamin@smedbergs.us 2008-03-11 11:22:05 -04:00
commit c247ccdc49
58 changed files with 1530 additions and 317 deletions

View File

@ -387,7 +387,7 @@
ondragdrop="nsDragAndDrop.drop(event, BookmarksMenuDropHandler);"
ondragover="nsDragAndDrop.dragOver(event, BookmarksMenuDropHandler);">
<menupopup id="bookmarksMenuPopup"
type="places" asyncinit="true"
type="places"
place="place:folder=2&amp;expandQueries=1"
context="placesContext"
openInTabs="children"
@ -411,12 +411,23 @@
</menu>
<menuitem label="&addCurPagesCmd.label;"
command="Browser:BookmarkAllTabs" key="bookmarkAllTabsKb"/>
<menuseparator id="organizeBookmarksSeparator"/>
<menuitem label="&showAllBookmarksCmd2.label;"
command="Browser:ShowAllBookmarks" key="manBookmarkKb"/>
<menu id="bookmarksToolbarFolderMenu"
class="menu-iconic bookmark-item"
container="true">
<menupopup id="bookmarksToolbarFolderPopup"
type="places"
context="placesContext"
oncommand="BookmarksEventHandler.onCommand(event);"
onclick="BookmarksEventHandler.onClick(event);"
onpopupshowing="BookmarksEventHandler.onPopupShowing(event);"/>
</menu>
<menuseparator builder="start"/>
</menupopup>
</menu>
<menu id="tools-menu" label="&toolsMenu.label;" accesskey="&toolsMenu.accesskey;">
<menupopup id="menu_ToolsPopup">
<menuitem label="&search.label;" accesskey="&search.accesskey;"

View File

@ -260,15 +260,17 @@ function BookmarkThisTab()
}
/**
* Initialize the bookmarks toolbar
* Initialize the bookmarks toolbar and the menuitem for it.
*/
function initBookmarksToolbar() {
var place = PlacesUtils.getQueryStringForFolder(PlacesUtils.bookmarks.toolbarFolder);
var bt = document.getElementById("bookmarksBarContent");
if (!bt)
return;
if (bt)
bt.place = place;
bt.place =
PlacesUtils.getQueryStringForFolder(PlacesUtils.bookmarks.toolbarFolder);
document.getElementById("bookmarksToolbarFolderPopup").place = place;
document.getElementById("bookmarksToolbarFolderMenu").label =
PlacesUtils.bookmarks.getItemTitle(PlacesUtils.bookmarks.toolbarFolder);
}
const gSessionHistoryObserver = {
@ -767,6 +769,12 @@ function BrowserStartup()
document.documentElement.setAttribute("height", defaultHeight);
}
if (gURLBar && document.documentElement.getAttribute("chromehidden").indexOf("toolbar") != -1) {
gURLBar.setAttribute("readonly", "true");
gURLBar.setAttribute("enablehistory", "false");
}
setTimeout(delayedStartup, 0);
}
@ -894,11 +902,6 @@ function delayedStartup()
BrowserOffline.init();
OfflineApps.init();
if (gURLBar && document.documentElement.getAttribute("chromehidden").indexOf("toolbar") != -1) {
gURLBar.setAttribute("readonly", "true");
gURLBar.setAttribute("enablehistory", "false");
}
gBrowser.addEventListener("pageshow", function(evt) { setTimeout(pageShowEventHandlers, 0, evt); }, true);
window.addEventListener("keypress", ctrlNumberTabSelection, false);

View File

@ -777,7 +777,7 @@
else
menuitem.removeAttribute("image");
var title = aNode.title;
var title = PlacesUtils.getBestTitle(aNode);
if (menuitem.getAttribute("label") != title)
menuitem.setAttribute("label", title);

View File

@ -543,6 +543,8 @@
break;
}
}
// Don't replace title on toolbarbuttons
var title = aNode.title;
}
else {
var popup = this._getPopupForContainer(parentNode);
@ -555,7 +557,8 @@
element = children[i];
break;
}
}
}
var title = PlacesUtils.getBestTitle(aNode);
}
if (PlacesUtils.nodeIsSeparator(aNode)) {
@ -572,7 +575,6 @@
else
element.removeAttribute("image");
var title = aNode.title;
if (element.getAttribute("label") != title) {
element.setAttribute("label", title);
if (onToolbar)

View File

@ -1131,7 +1131,7 @@ PlacesTreeView.prototype = {
// if they go through the "result" API.
if (PlacesUtils.nodeIsSeparator(node))
return "";
return node.title || PlacesUtils.getString("noTitle");
return PlacesUtils.getBestTitle(node);
case this.COLUMN_TYPE_TAGS:
return node.tags;
case this.COLUMN_TYPE_URI:

View File

@ -192,6 +192,14 @@ var PlacesUtils = {
getService(Ci.nsIURIFixup);
},
get ellipsis() {
delete this.ellipsis;
var pref = Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefBranch);
return this.ellipsis = pref.getComplexValue("intl.ellipsis",
Ci.nsIPrefLocalizedString).data;
},
/**
* Makes a URI from a spec.
* @param aSpec
@ -1877,7 +1885,8 @@ var PlacesUtils = {
else
throw "Unexpected node";
element.setAttribute("label", aNode.title);
element.setAttribute("label", this.getBestTitle(aNode));
if (iconURISpec)
element.setAttribute("image", iconURISpec);
}
@ -1887,6 +1896,31 @@ var PlacesUtils = {
return element;
},
getBestTitle: function PU_getBestTitle(aNode) {
var title;
if (!aNode.title && this.uriTypes.indexOf(aNode.type) != -1) {
// if node title is empty, try to set the label using host and filename
// this._uri() will throw if aNode.uri is not a valid URI
try {
var uri = this._uri(aNode.uri);
var host = uri.host;
var fileName = uri.QueryInterface(Ci.nsIURL).fileName;
// if fileName is empty, use path to distinguish labels
title = host + (fileName ?
(host ? "/" + this.ellipsis + "/" : "") + fileName :
uri.path);
}
catch (e) {
// Use (no title) for non-standard URIs (data:, javascript:, ...)
title = "";
}
}
else
title = aNode.title;
return title || PlacesUtils.getString("noTitle");
},
get leftPaneQueries() {
// build the map
this.leftPaneFolderId;

View File

@ -5,7 +5,7 @@
<!ENTITY proxyTitle.label "Configure Proxies to Access the Internet">
<!ENTITY noProxyTypeRadio.label "No proxy">
<!ENTITY noProxyTypeRadio.accesskey "x">
<!ENTITY noProxyTypeRadio.accesskey "y">
<!ENTITY systemTypeRadio.label "Use system proxy settings">
<!ENTITY systemTypeRadio.accesskey "u">
<!ENTITY WPADTypeRadio.label "Auto-detect proxy settings for this network">
@ -21,7 +21,7 @@
<!ENTITY gopher.label "Gopher Proxy:">
<!ENTITY gopher.accesskey "G">
<!ENTITY http.label "HTTP Proxy:">
<!ENTITY http.accesskey "y">
<!ENTITY http.accesskey "H">
<!ENTITY ssl.label "SSL Proxy:">
<!ENTITY ssl.accesskey "S">
<!ENTITY socks.label "SOCKS Host:">

View File

@ -950,7 +950,7 @@ toolbar[iconsize="small"] #paste-button[disabled="true"] {
#autocomplete-security-wrapper {
/* keep the URL bar content LTR */
direction: ltr;
-moz-box-align: center;
-moz-box-align: stretch;
/* cover the white gap between the text field and the drop down button */
margin-right: -3px;
}

View File

@ -78,6 +78,11 @@
-moz-image-region: rect(0px, 160px, 32px, 128px)
}
#mainDeck {
padding-left: 2px;
padding-right: 2px;
}
deck {
padding: 10px 10px 10px 10px;
}
@ -118,6 +123,14 @@ textbox[disabled] {
}
/* General Tab */
#generalPanel > #titletext {
-moz-margin-start: 5px;
}
#metaTags > .groupbox-body {
-moz-margin-start: 5px;
-moz-margin-end: 1px;
}
groupbox.collapsable caption .caption-icon {
width: 9px;
height: 9px;
@ -157,6 +170,7 @@ groupbox.treebox .groupbox-body {
/* Media Tab */
#imagetree {
min-height: 10em;
margin-top: 2px;
}
#mediaGrid {
@ -176,7 +190,17 @@ treechildren::-moz-tree-cell-text(broken) {
color: graytext;
}
#mediaPreviewBox .inset {
-moz-appearance: listbox;
margin-bottom: 0;
}
/* Feeds Tab */
#feedPanel {
margin-left: 2px;
margin-right: 2px;
}
#feedtree {
margin-bottom: 0px;
}
@ -196,6 +220,7 @@ treechildren::-moz-tree-cell-text(broken) {
}
#feedListbox {
margin-bottom: 0;
border: 2px solid;
-moz-border-top-colors: ThreeDShadow ThreeDDarkShadow;
-moz-border-right-colors: ThreeDHighlight ThreeDLightShadow;
@ -208,6 +233,11 @@ treechildren::-moz-tree-cell-text(broken) {
}
/* Permissions Tab */
#permPanel {
margin-left: 6px;
margin-right: 6px;
}
#permList {
-moz-appearance: listbox;
margin-top: .5em;

View File

@ -150,6 +150,25 @@ filefield[disabled="true"] .fileFieldIcon {
list-style-image: url("moz-icon://stock/gtk-file?size=menu");
}
#paneApplications {
margin-left: 4px;
margin-right: 4px;
padding-left: 0;
padding-right: 0;
}
#linksOpenInBox {
margin-top: 5px;
}
#paneAdvanced {
padding-bottom: 10px;
}
#advancedPrefs {
margin-left: 0;
margin-right: 0;
}
#cookiesChildren::-moz-tree-image(domainCol, container) {
list-style-image: url("moz-icon://stock/gtk-directory?size=menu");
}

View File

@ -707,7 +707,7 @@ from building Mozilla. Upgrade to Xcode 2.1 or later.])
case "$PBBUILD" in
*xcodebuild*)
changequote(,)
XCODEBUILD_VERSION=`$PBBUILD -version 2>/dev/null | sed -e 's/.*DevToolsCore-\([0-9]*\).*/\1/'`
XCODEBUILD_VERSION=`$PBBUILD -version 2>/dev/null | sed -e 's/.*DevToolsCore-\([0-9]*\).*/\1/' | tail -n 1`
changequote([,])
if test -n "$XCODEBUILD_VERSION" && test "$XCODEBUILD_VERSION" -ge 620 ; then
HAS_XCODE_2_1=1;

View File

@ -481,7 +481,7 @@ nsDOMAttributeMap::RemoveNamedItemNS(const nsAString& aNamespaceURI,
NS_ENSURE_SUCCESS(rv, rv);
if (!*aReturn) {
return NS_OK;
return NS_ERROR_DOM_NOT_FOUND_ERR;
}
nsCOMPtr<nsIAttribute> attr = do_QueryInterface(*aReturn);

View File

@ -59,16 +59,12 @@ bug371552 = ["elementhasattributens02"];
wrongDocError = ["elementsetattributenodens05", "namednodemapsetnameditemns03",
"setAttributeNodeNS05", "setNamedItemNS02"];
attrAppendChild = ["elementsetattributenodens06", "importNode01"];
removeNamedItemNS = ["namednodemapremovenameditemns06",
"namednodemapremovenameditemns07",
"namednodemapremovenameditemns08",
"removeNamedItemNS02"];
bogusPrefix = ["nodesetprefix05", "nodesetprefix09", "prefix06", "prefix07"];
prefixReplacement = ["setAttributeNodeNS04"];
var todoTests = {};
var exclusions = concat(dtdTests, bug371552, wrongDocError, attrAppendChild,
removeNamedItemNS, bogusPrefix, prefixReplacement);
bogusPrefix, prefixReplacement);
for (var excludedTestName in exclusions) {
todoTests[exclusions[excludedTestName]] = true;
}

View File

@ -541,7 +541,8 @@ public:
NATIVE_GDK_DRAWABLE = 2,
NATIVE_WINDOWS_DC = 3,
NATIVE_MAC_THING = 4,
NATIVE_THEBES_CONTEXT = 5
NATIVE_THEBES_CONTEXT = 5,
NATIVE_OS2_PS = 6
};
/**
* Retrieve the native graphic data given by aType. Return

View File

@ -720,6 +720,14 @@ nsThebesRenderingContext::GetNativeGraphicData(GraphicDataType aType)
return static_cast<gfxWindowsSurface*>(static_cast<gfxASurface*>(surf.get()))->GetDC();
}
#endif
#ifdef XP_OS2
if (aType == NATIVE_OS2_PS) {
nsRefPtr<gfxASurface> surf(mThebes->CurrentSurface());
if (!surf || surf->CairoStatus())
return nsnull;
return (void*)(static_cast<gfxOS2Surface*>(static_cast<gfxASurface*>(surf.get()))->GetPS());
}
#endif
return nsnull;
}

View File

@ -405,7 +405,7 @@ TextRunWordCache::FinishTextRun(gfxTextRun *aTextRun, gfxTextRun *aNewRun,
// need to find out what the platform would do
// if the marks were at the start of the text.
tmpTextRun = aNewRun->GetFontGroup()->MakeTextRun(
aTextRun->GetTextUnicode() + sourceOffset, length, aParams,
source->GetTextUnicode() + sourceOffset, length, aParams,
aNewRun->GetFlags());
source = tmpTextRun;
sourceOffset = 0;
@ -739,7 +739,7 @@ TextRunWordCache::CacheDumpEntry(CacheHashEntry* aEntry, void* userArg)
fprintf(output, "<EMPTY>\n");
return PL_DHASH_NEXT;
}
fprintf(output, "Word at %x:%d => ", aEntry->mTextRun, aEntry->mWordOffset);
fprintf(output, "Word at %p:%d => ", static_cast<void*>(aEntry->mTextRun), aEntry->mWordOffset);
aEntry->mTextRun->Dump(output);
fprintf(output, " (hashed by %s)\n", aEntry->mHashedByFont ? "font" : "fontgroup");
return PL_DHASH_NEXT;

View File

@ -464,22 +464,18 @@ jsds_FilterHook (JSDContext *jsdc, JSDThreadState *state)
JS_STATIC_DLL_CALLBACK (void)
jsds_NotifyPendingDeadScripts (JSContext *cx)
{
/* Bug 411249, we can't drop the script hook.
* Even if we could drop the script hook, jsds_GCCallbackProc
* is never cleared, so it would call us anyway.
*
* If there's no gJsds, then we can't do anything.
*/
if (!gJsds)
return;
nsCOMPtr<jsdIScriptHook> hook = 0;
gJsds->GetScriptHook (getter_AddRefs(hook));
#ifdef CAUTIOUS_SCRIPTHOOK
JSRuntime *rt = JS_GetRuntime(cx);
#endif
gJsds->Pause(nsnull);
jsdService *jsds = gJsds;
nsCOMPtr<jsdIScriptHook> hook;
if (jsds) {
NS_ADDREF(jsds);
jsds->GetScriptHook (getter_AddRefs(hook));
jsds->Pause(nsnull);
}
DeadScript *deadScripts = gDeadScripts;
gDeadScripts = nsnull;
while (deadScripts) {
@ -511,7 +507,10 @@ jsds_NotifyPendingDeadScripts (JSContext *cx)
PR_Free(ds);
}
gJsds->UnPause(nsnull);
if (jsds) {
jsds->UnPause(nsnull);
NS_RELEASE(jsds);
}
}
JS_STATIC_DLL_CALLBACK (JSBool)
@ -2562,13 +2561,11 @@ jsdService::Off (void)
return NS_ERROR_NOT_INITIALIZED;
if (gDeadScripts) {
if (gGCStatus == JSGC_END)
{
JSContext *cx = JSD_GetDefaultJSContext(mCx);
jsds_NotifyPendingDeadScripts(cx);
}
else
if (gGCStatus != JSGC_END)
return NS_ERROR_NOT_AVAILABLE;
JSContext *cx = JSD_GetDefaultJSContext(mCx);
jsds_NotifyPendingDeadScripts(cx);
}
/*
@ -2583,6 +2580,7 @@ jsdService::Off (void)
ClearAllBreakpoints();
JSD_SetErrorReporter (mCx, NULL, NULL);
JSD_SetScriptHook (mCx, NULL, NULL);
JSD_ClearThrowHook (mCx);
JSD_ClearInterruptHook (mCx);
JSD_ClearDebuggerHook (mCx);
@ -3278,6 +3276,16 @@ jsdService::GetFunctionHook (jsdICallHook **aHook)
jsdService::~jsdService()
{
ClearFilters();
mErrorHook = nsnull;
mBreakpointHook = nsnull;
mDebugHook = nsnull;
mDebuggerHook = nsnull;
mInterruptHook = nsnull;
mScriptHook = nsnull;
mThrowHook = nsnull;
mTopLevelHook = nsnull;
mFunctionHook = nsnull;
gGCStatus = JSGC_END;
Off();
gJsds = nsnull;
}

View File

@ -49,7 +49,7 @@ LIBRARY_NAME = mozjs
GRE_MODULE = 1
ifdef GNU_CC
MODULE_OPTIMIZE_FLAGS = -Os
MODULE_OPTIMIZE_FLAGS = -Os -fstrict-aliasing
else
ifeq ($(OS_ARCH),SunOS)
MODULE_OPTIMIZE_FLAGS = -O

View File

@ -113,13 +113,6 @@ JSBool gQuitting = JS_FALSE;
FILE *gErrFile = NULL;
FILE *gOutFile = NULL;
#ifdef JSDEBUGGER
static JSDContext *_jsdc;
#ifdef JSDEBUGGER_JAVA_UI
static JSDJContext *_jsdjc;
#endif /* JSDEBUGGER_JAVA_UI */
#endif /* JSDEBUGGER */
static JSBool reportWarnings = JS_TRUE;
static JSBool compileOnly = JS_FALSE;
@ -3804,12 +3797,16 @@ main(int argc, char **argv, char **envp)
#ifdef LIVECONNECT
JavaVM *java_vm = NULL;
#endif
#ifdef JSDEBUGGER
JSDContext *jsdc;
#ifdef JSDEBUGGER_JAVA_UI
JNIEnv *java_env;
JSDJContext *jsdjc;
#endif
#ifdef JSDEBUGGER_C_UI
JSBool jsdbc;
#endif /* JSDEBUGGER_C_UI */
#endif /* JSDEBUGGER */
CheckHelpMessages();
setlocale(LC_ALL, "");
@ -3866,19 +3863,19 @@ main(int argc, char **argv, char **envp)
/*
* XXX A command line option to enable debugging (or not) would be good
*/
_jsdc = JSD_DebuggerOnForUser(rt, NULL, NULL);
if (!_jsdc)
jsdc = JSD_DebuggerOnForUser(rt, NULL, NULL);
if (!jsdc)
return 1;
JSD_JSContextInUse(_jsdc, cx);
JSD_JSContextInUse(jsdc, cx);
#ifdef JSD_LOWLEVEL_SOURCE
JS_SetSourceHandler(rt, SendSourceToJSDebugger, _jsdc);
JS_SetSourceHandler(rt, SendSourceToJSDebugger, jsdc);
#endif /* JSD_LOWLEVEL_SOURCE */
#ifdef JSDEBUGGER_JAVA_UI
_jsdjc = JSDJ_CreateContext();
if (! _jsdjc)
jsdjc = JSDJ_CreateContext();
if (! jsdjc)
return 1;
JSDJ_SetJSDContext(_jsdjc, _jsdc);
java_env = JSDJ_CreateJavaVMAndStartDebugger(_jsdjc);
JSDJ_SetJSDContext(jsdjc, jsdc);
java_env = JSDJ_CreateJavaVMAndStartDebugger(jsdjc);
#ifdef LIVECONNECT
if (java_env)
(*java_env)->GetJavaVM(java_env, &java_vm);
@ -3890,7 +3887,7 @@ main(int argc, char **argv, char **envp)
*/
#endif /* JSDEBUGGER_JAVA_UI */
#ifdef JSDEBUGGER_C_UI
jsdbc = JSDB_InitDebugger(rt, _jsdc, 0);
jsdbc = JSDB_InitDebugger(rt, jsdc, 0);
#endif /* JSDEBUGGER_C_UI */
#endif /* JSDEBUGGER */
@ -3928,12 +3925,12 @@ main(int argc, char **argv, char **envp)
result = ProcessArgs(cx, glob, argv, argc);
#ifdef JSDEBUGGER
if (_jsdc) {
if (jsdc) {
#ifdef JSDEBUGGER_C_UI
if (jsdbc)
JSDB_TermDebugger(_jsdc);
JSDB_TermDebugger(jsdc);
#endif /* JSDEBUGGER_C_UI */
JSD_DebuggerOff(_jsdc);
JSD_DebuggerOff(jsdc);
}
#endif /* JSDEBUGGER */

View File

@ -6844,7 +6844,7 @@ interrupt:
* op may be invalid here when a catch or finally handler jumps to
* advance_pc.
*/
op = pc[-len];
op = (JSOp) pc[-len];
ndefs = js_CodeSpec[op].ndefs;
if (ndefs) {
SAVE_SP_AND_PC(fp);

View File

@ -89,7 +89,7 @@ BinToVal(uintN logscale, uintN bin)
if (logscale == 2)
return JS_BIT(bin);
JS_ASSERT(logscale == 10);
return (uint32) pow(10, bin);
return (uint32) pow(10, (double) bin);
}
static uintN
@ -100,7 +100,7 @@ ValToBin(uintN logscale, uint32 val)
if (val <= 1)
return val;
bin = (logscale == 10)
? (uintN) ceil(log10(val))
? (uintN) ceil(log10((double) val))
: (logscale == 2)
? (uintN) JS_CeilingLog2(val)
: val;
@ -198,7 +198,7 @@ JS_DumpHistogram(JSBasicStats *bs, FILE *fp)
fprintf(fp, "%s %8u ", (bin == 10) ? "+" : ":", cnt);
if (cnt != 0) {
if (max > 1e6 && mean > 1e3)
cnt = (uint32) ceil(log10(cnt));
cnt = (uint32) ceil(log10((double) cnt));
else if (max > 16 && mean > 8)
cnt = JS_CeilingLog2(cnt);
for (i = 0; i < cnt; i++)

View File

@ -169,3 +169,49 @@ XPC_MSG_DEF(NS_ERROR_XPC_COM_INVALID_CLASS_ID , "Invalid class ID")
XPC_MSG_DEF(NS_ERROR_XPC_COM_CREATE_FAILED , "Unable to create an instance of the desired COM class")
XPC_MSG_DEF(NS_ERROR_XPC_IDISPATCH_NOT_ENABLED , "IDispatch support is not enabled")
#endif
/* network related codes (from nsNetError.h) */
XPC_MSG_DEF(NS_BINDING_FAILED , "The async request failed for some unknown reason")
XPC_MSG_DEF(NS_BINDING_ABORTED , "The async request failed because it was aborted by some user action")
XPC_MSG_DEF(NS_BINDING_REDIRECTED , "The async request has been redirected to a different async request")
XPC_MSG_DEF(NS_BINDING_RETARGETED , "The async request has been retargeted to a different handler")
XPC_MSG_DEF(NS_ERROR_MALFORMED_URI , "The URI is malformed")
XPC_MSG_DEF(NS_ERROR_UNKNOWN_PROTOCOL , "The URI scheme corresponds to an unknown protocol handler")
XPC_MSG_DEF(NS_ERROR_NO_CONTENT , "Channel opened successfully but no data will be returned")
XPC_MSG_DEF(NS_ERROR_IN_PROGRESS , "The requested action could not be completed while the object is busy")
XPC_MSG_DEF(NS_ERROR_ALREADY_OPENED , "Channel is already open")
XPC_MSG_DEF(NS_ERROR_INVALID_CONTENT_ENCODING , "The content encoding of the source document is incorrect")
XPC_MSG_DEF(NS_ERROR_ALREADY_CONNECTED , "The connection is already established")
XPC_MSG_DEF(NS_ERROR_NOT_CONNECTED , "The connection does not exist")
XPC_MSG_DEF(NS_ERROR_CONNECTION_REFUSED , "The connection was refused")
XPC_MSG_DEF(NS_ERROR_PROXY_CONNECTION_REFUSED , "The connection to the proxy server was refused")
XPC_MSG_DEF(NS_ERROR_NET_TIMEOUT , "The connection has timed out")
XPC_MSG_DEF(NS_ERROR_OFFLINE , "The requested action could not be completed in the offline state")
XPC_MSG_DEF(NS_ERROR_PORT_ACCESS_NOT_ALLOWED , "Establishing a connection to an unsafe or otherwise banned port was prohibited")
XPC_MSG_DEF(NS_ERROR_NET_RESET , "The connection was established, but no data was ever received")
XPC_MSG_DEF(NS_ERROR_NET_INTERRUPT , "The connection was established, but the data transfer was interrupted")
XPC_MSG_DEF(NS_ERROR_NOT_RESUMABLE , "This request is not resumable, but it was tried to resume it, or to request resume-specific data")
XPC_MSG_DEF(NS_ERROR_ENTITY_CHANGED , "It was attempted to resume the request, but the entity has changed in the meantime")
XPC_MSG_DEF(NS_ERROR_REDIRECT_LOOP , "The request failed as a result of a detected redirection loop")
XPC_MSG_DEF(NS_ERROR_UNSAFE_CONTENT_TYPE , "The request failed because the content type returned by the server was not a type expected by the channel")
XPC_MSG_DEF(NS_ERROR_FTP_LOGIN , "FTP error while logging in")
XPC_MSG_DEF(NS_ERROR_FTP_CWD , "FTP error while changing directory")
XPC_MSG_DEF(NS_ERROR_FTP_PASV , "FTP error while changing to passive mode")
XPC_MSG_DEF(NS_ERROR_FTP_PWD , "FTP error while retrieving current directory")
XPC_MSG_DEF(NS_ERROR_FTP_LIST , "FTP error while retrieving a directory listing")
XPC_MSG_DEF(NS_ERROR_UNKNOWN_HOST , "The lookup of the hostname failed")
XPC_MSG_DEF(NS_ERROR_UNKNOWN_PROXY_HOST , "The lookup of the proxy hostname failed")
XPC_MSG_DEF(NS_ERROR_UNKNOWN_SOCKET_TYPE , "The specified socket type does not exist")
XPC_MSG_DEF(NS_ERROR_SOCKET_CREATE_FAILED , "The specified socket type could not be created")
XPC_MSG_DEF(NS_ERROR_CACHE_KEY_NOT_FOUND , "Cache key could not be found")
XPC_MSG_DEF(NS_ERROR_CACHE_DATA_IS_STREAM , "Cache data is a stream")
XPC_MSG_DEF(NS_ERROR_CACHE_DATA_IS_NOT_STREAM , "Cache data is not a stream")
XPC_MSG_DEF(NS_ERROR_CACHE_WAIT_FOR_VALIDATION , "Cache entry exists but needs to be validated first")
XPC_MSG_DEF(NS_ERROR_CACHE_ENTRY_DOOMED , "Cache entry has been doomed")
XPC_MSG_DEF(NS_ERROR_CACHE_READ_ACCESS_DENIED , "Read access to cache denied")
XPC_MSG_DEF(NS_ERROR_CACHE_WRITE_ACCESS_DENIED , "Write access to cache denied")
XPC_MSG_DEF(NS_ERROR_CACHE_IN_USE , "Cache is currently in use")
XPC_MSG_DEF(NS_ERROR_DOCUMENT_NOT_CACHED , "Document does not exist in cache")
XPC_MSG_DEF(NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS , "The requested number of domain levels exceeds those present in the host string")
XPC_MSG_DEF(NS_ERROR_HOST_IS_IP_ADDRESS , "The host string is an IP address")

View File

@ -42,6 +42,7 @@
/* An implementaion of nsIException. */
#include "xpcprivate.h"
#include "nsNetError.h"
/***************************************************************************/
/* Quick and dirty mapping of well known result codes to strings. We only

View File

@ -44,6 +44,18 @@ var expect = 'No Crash';
printBugNumber(BUGNUMBER);
printStatus (summary);
this.__proto__ = [];
this.unwatch("x");
try
{
this.__proto__ = [];
this.unwatch("x");
}
catch(ex)
{
print(ex + '');
if (typeof window != 'undefined')
{
expect = 'Error: invalid __proto__ value (can only be set to null)';
}
actual = ex + '';
}
reportCompare(expect, actual, summary);

View File

@ -361,6 +361,8 @@ public:
#elif defined(MOZ_X11)
void Paint(nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect);
#elif defined(XP_OS2)
void Paint(const nsRect& aDirtyRect, HPS aHPS);
#endif
// nsITimerCallback interface
@ -445,7 +447,7 @@ private:
};
#if defined(XP_WIN) || (defined(DO_DIRTY_INTERSECT) && defined(XP_MACOSX)) || defined(MOZ_X11)
#if defined(XP_WIN) || (defined(DO_DIRTY_INTERSECT) && defined(XP_MACOSX)) || defined(MOZ_X11) || defined(XP_OS2)
static void ConvertAppUnitsToPixels(const nsPresContext& aPresContext, const nsRect& aTwipsRect, nsIntRect& aPixelRect);
#endif
@ -1183,6 +1185,15 @@ nsObjectFrame::PrintPlugin(nsIRenderingContext& aRenderingContext,
PR_LOG(nsObjectFrameLM, PR_LOG_DEBUG, ("plugin printing done, return code is %lx\n", (long)rv));
#endif
#elif defined(XP_OS2)
void *hps = aRenderingContext.GetNativeGraphicData(nsIRenderingContext::NATIVE_OS2_PS);
if (!hps)
return;
npprint.print.embedPrint.platformPrint = hps;
npprint.print.embedPrint.window = window;
// send off print info to plugin
rv = pi->Print(&npprint);
#elif defined(XP_WIN)
/* On Windows, we use the win32 printing surface to print. This, in
@ -1342,9 +1353,7 @@ nsObjectFrame::PaintPlugin(nsIRenderingContext& aRenderingContext,
if (window->type == nsPluginWindowType_Drawable)
mInstanceOwner->Paint(aRenderingContext, aDirtyRect);
}
#elif defined (XP_WIN) // || defined(XP_OS2)
// XXX for OS/2 we need to overhaul this for Cairo builds
// for now just ignore plugin stuff
#elif defined (XP_WIN) || defined(XP_OS2)
nsCOMPtr<nsIPluginInstance> inst;
GetPluginInstance(*getter_AddRefs(inst));
if (inst) {
@ -1395,6 +1404,7 @@ nsObjectFrame::PaintPlugin(nsIRenderingContext& aRenderingContext,
return;
}
#ifdef XP_WIN
// check if we need to update hdc
HDC hdc = (HDC)aRenderingContext.GetNativeGraphicData(nsIRenderingContext::NATIVE_WINDOWS_DC);
@ -1408,6 +1418,25 @@ nsObjectFrame::PaintPlugin(nsIRenderingContext& aRenderingContext,
POINT origViewportOrigin;
GetViewportOrgEx(hdc, &origViewportOrigin);
SetViewportOrgEx(hdc, origViewportOrigin.x + (int) xoff, origViewportOrigin.y + (int) yoff, NULL);
#else // do something similar on OS/2
// check if we need to update the PS
HPS hps = (HPS)aRenderingContext.GetNativeGraphicData(nsIRenderingContext::NATIVE_OS2_PS);
if (reinterpret_cast<HPS>(window->window) != hps) {
window->window = reinterpret_cast<nsPluginPort*>(hps);
doupdatewindow = PR_TRUE;
}
LONG lPSid = GpiSavePS(hps);
RECTL rclViewport;
if (GpiQueryDevice(hps) != NULLHANDLE) { // ensure that we have an associated HDC
if (GpiQueryPageViewport(hps, &rclViewport)) {
rclViewport.xLeft += (LONG)xoff;
rclViewport.xRight += (LONG)xoff;
rclViewport.yBottom += (LONG)yoff;
rclViewport.yTop += (LONG)yoff;
GpiSetPageViewport(hps, &rclViewport);
}
}
#endif
if ((window->x != origin.x) || (window->y != origin.y)) {
window->x = origin.x;
@ -1460,6 +1489,7 @@ nsObjectFrame::PaintPlugin(nsIRenderingContext& aRenderingContext,
inst->SetWindow(window);
}
#ifdef XP_WIN
// FIXME - Bug 385435:
// This expects a dirty rect relative to the plugin's rect
// XXX I wonder if this breaks if we give the frame a border so the
@ -1467,6 +1497,12 @@ nsObjectFrame::PaintPlugin(nsIRenderingContext& aRenderingContext,
mInstanceOwner->Paint(aDirtyRect, hdc);
RestoreDC(hdc, -1);
#else // do something similar on OS/2
mInstanceOwner->Paint(aDirtyRect, hps);
if (lPSid >= 1) {
GpiRestorePS(hps, lPSid);
}
#endif
surf->MarkDirty();
}
}
@ -3826,6 +3862,36 @@ void nsPluginInstanceOwner::Paint(const nsRect& aDirtyRect, HDC ndc)
}
#endif
#ifdef XP_OS2
void nsPluginInstanceOwner::Paint(const nsRect& aDirtyRect, HPS aHPS)
{
if (!mInstance || !mOwner)
return;
nsPluginWindow * window;
GetWindow(window);
nsRect relDirtyRect = nsRect(aDirtyRect.x, aDirtyRect.y, aDirtyRect.width, aDirtyRect.height);
nsIntRect relDirtyRectInPixels;
ConvertAppUnitsToPixels(*mOwner->PresContext(), relDirtyRect,
relDirtyRectInPixels);
// we got dirty rectangle in relative window coordinates, but we
// need it in absolute units and in the (left, top, right, bottom) form
RECTL rectl;
rectl.xLeft = relDirtyRectInPixels.x + window->x;
rectl.yBottom = relDirtyRectInPixels.y + window->y;
rectl.xRight = rectl.xLeft + relDirtyRectInPixels.width;
rectl.yTop = rectl.yBottom + relDirtyRectInPixels.height;
nsPluginEvent pluginEvent;
pluginEvent.event = WM_PAINT;
pluginEvent.wParam = (uint32)aHPS;
pluginEvent.lParam = (uint32)&rectl;
PRBool eventHandled = PR_FALSE;
mInstance->HandleEvent(&pluginEvent, &eventHandled);
}
#endif
#ifdef MOZ_X11
void nsPluginInstanceOwner::Paint(nsIRenderingContext& aRenderingContext,
const nsRect& aDirtyRect)
@ -4184,7 +4250,7 @@ void nsPluginInstanceOwner::SetPluginHost(nsIPluginHost* aHost)
mPluginHost = aHost;
}
#if defined(XP_WIN) || (defined(DO_DIRTY_INTERSECT) && defined(XP_MACOSX)) || defined(MOZ_X11)
#if defined(XP_WIN) || (defined(DO_DIRTY_INTERSECT) && defined(XP_MACOSX)) || defined(MOZ_X11) || defined(XP_OS2)
// convert frame coordinates from twips to pixels
static void ConvertAppUnitsToPixels(const nsPresContext& aPresContext, const nsRect& aTwipsRect, nsIntRect& aPixelRect)
{

View File

@ -0,0 +1,67 @@
<html>
<head><style>
tr { height: 1em; }
td.wide { width: 500px; }
td.orange { background: orange; }
td.purple { background: purple; }
td.teal { background: teal; }
td.blue { background: lightblue; }
</style></head>
<body>
<p>(x,x) labels indicate the column & row order of the orange cell.</p>
<br/>(0,0)
<table cellpadding="0" cellspacing="0">
<tr>
<td class="orange wide"></td>
<td class="orange"></td>
<td class="purple"></td>
</td>
</tr><tr>
<td class="teal">x</td>
<td class="blue" colspan="2">y z</td>
</tr>
</table>
<br/>(0,1)
<table cellpadding="0" cellspacing="0">
<tr>
<td class="teal">x</td>
<td class="blue" colspan="2">y z</td>
</td>
</tr><tr>
<td class="orange wide"></td>
<td class="orange"></td>
<td class="purple"></td>
</tr>
</table>
<br/>(1,0)
<table cellpadding="0" cellspacing="0">
<tr>
<td class="purple"></td>
<td class="orange"></td>
<td class="orange wide"></td>
</td>
</tr><tr>
<td class="blue" colspan="2">y z</td>
<td class="teal">x</td>
</tr>
</table>
<br/>(1,1)
<table cellpadding="0" cellspacing="0">
<tr>
<td class="blue" colspan="2">y z</td>
<td class="teal">x</td>
</td>
</tr><tr>
<td class="purple"></td>
<td class="orange"></td>
<td class="orange wide"></td>
</tr>
</table>
</body>
</html>

View File

@ -0,0 +1,73 @@
<html>
<!-- This testcase asserts that in all the tables below, all 500px of the --
-- orange colspanning cell's specified width should go to its first --
-- spanned column. Its second spanned column receives none of the --
-- 500px, and it only gets a small amount of width by taking half of the --
-- light-blue cell's preferred width. --
-- --
-- This happens because the first column starts with nonzero pref-width, --
-- whereas the second and third columns have zero pref-width. Hence, --
-- the orange colspanning cell favors the first column over the second, --
-- whereas the lightblue colspanning cell distributes its width equally --
-- between the second and third columns. -->
<head><style>
tr { height: 1em; }
td.wide { width: 500px; }
td.orange { background: orange; }
td.purple { background: purple; }
td.teal { background: teal; }
td.blue { background: lightblue; }
</style></head>
<body>
<p>(x,x) labels indicate the column & row order of the orange cell.</p>
<br/>(0,0)
<table cellpadding="0" cellspacing="0">
<tr>
<td class="orange wide" colspan="2"></td>
<td class="purple"></td>
</td>
</tr><tr>
<td class="teal">x</td>
<td class="blue" colspan="2">y z</td>
</tr>
</table>
<br/>(0,1)
<table cellpadding="0" cellspacing="0">
<tr>
<td class="teal">x</td>
<td class="blue" colspan="2">y z</td>
</td>
</tr><tr>
<td class="orange wide" colspan="2"></td>
<td class="purple"></td>
</tr>
</table>
<br/>(1,0)
<table cellpadding="0" cellspacing="0">
<tr>
<td class="purple"></td>
<td class="orange wide" colspan="2"></td>
</td>
</tr><tr>
<td class="blue" colspan="2">y z</td>
<td class="teal">x</td>
</tr>
</table>
<br/>(1,1)
<table cellpadding="0" cellspacing="0">
<tr>
<td class="blue" colspan="2">y z</td>
<td class="teal">x</td>
</td>
</tr><tr>
<td class="purple"></td>
<td class="orange wide" colspan="2"></td>
</tr>
</table>
</body>
</html>

View File

@ -0,0 +1,10 @@
<html><head>
<title>Testcase 3 for bug 413027 - Marquee height is sized too small, clipping text vertically</title>
</head>
<body>
<div style="background-color: lime; width: 600px; float:left;">
<div style="margin: 100px 0px;">text</div>
</div>
</body></html>

View File

@ -0,0 +1,12 @@
<html><head>
<title>Testcase 3 for bug 413027 - Marquee height is sized too small, clipping text vertically</title>
</head>
<body>
<div style="display: -moz-box; background-color: lime; width: 600px;">
<div>
<div style="margin: 100px 0px;">text</div>
</div>
</div>
</body></html>

View File

@ -0,0 +1,17 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Testcase bug - List item marker takes up room now with list-style-type: none in strict mode</title>
<style>
div.li {
border: 1px solid red;
}
div.inside {
border: 1px solid black;
}
</style></head>
<body>
<ul><div class="li"><div class="inside">text</div></div></ul>
</body>
</html>

View File

@ -0,0 +1,19 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Testcase bug - List item marker takes up room now with list-style-type: none in strict mode</title>
<style>
li{
list-style-type: none;
list-style-position: inside;
border: 1px solid red;
}
div {
border: 1px solid black;
}
</style></head>
<body>
<ul><li><div>text</div></li></ul>
</body>
</html>

View File

@ -698,6 +698,7 @@ random == 403134-1.html 403134-1-ref.html # bug 405377
== 407095-1.html 407095-1-ref.html
== 407111-1.html 407111-1-ref.html
== 407227-1.html 407227-1-ref.html
== 407243-1.html 407243-1-ref.html
== 407937-1.html 407937-1-ref.html
== 408493-1.html about:blank
== 408493-2.html 408493-2-ref.html
@ -719,6 +720,7 @@ random == 403134-1.html 403134-1-ref.html # bug 405377
== 412607-1b.html 412607-1-ref.html
== 412679-1.html 412679-1-ref.html
== 412679-2.html 412679-2-ref.html
# == 413027-1.html 413027-1-ref.html
== 413286-1a.html 413286-1-ref.html
== 413286-1b.html 413286-1-ref.html
== 413286-1c.html 413286-1-ref.html
@ -750,3 +752,5 @@ random == 403134-1.html 403134-1-ref.html # bug 405377
== 419531-1.html 419531-1-ref.html
== 420069-1.html 420069-1-ref.html
== 420069-2.html 420069-2-ref.html
# == 420351-1.html 420351-1-ref.html

View File

@ -42,7 +42,7 @@ interface nsIPrompt;
/**
* @status UNDER_REVIEW
*/
[scriptable, uuid(310fae75-191c-412d-be7f-6190df509e3c)]
[scriptable, uuid(358089f9-ee4b-4711-82fd-bcd07fc62061)]
interface nsIAuthPrompt : nsISupports
{
const PRUint32 SAVE_PASSWORD_NEVER = 0;
@ -87,7 +87,7 @@ interface nsIAuthPrompt : nsISupports
in wstring text,
in wstring passwordRealm,
in PRUint32 savePassword,
out wstring user,
inout wstring user,
inout wstring pwd);
/**
@ -95,7 +95,11 @@ interface nsIAuthPrompt : nsISupports
* @param dialogText The title for the dialog.
* @param text The text to display in the dialog.
* @param passwordRealm The "realm" the password belongs to: e.g.
* ldap://localhost/dc=test
* ldap://localhost/dc=test. If a username is
* specified (http://user@site.com) it will be used
* when matching existing logins or saving new ones.
* If no username is specified, only password-only
* logins will be matched or saved.
* @param savePassword One of the SAVE_PASSWORD_* options above.
* @param pwd The password entered by the user if OK was
* selected.

View File

@ -243,15 +243,14 @@ var pacUtils =
" return newRe.test(url);\n" +
"}\n" +
"var wdays = new Array('SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT');\n" +
"var wdays = {SUN: 0, MON: 1, TUE: 2, WED: 3, THU: 4, FRI: 5, SAT: 6};\n" +
"var monthes = new Array('JAN', 'FEB', 'MAR', 'APR', 'MAY', 'JUN', 'JUL', 'AUG', 'SEP', 'OCT', 'NOV', 'DEC');\n"+
"var months = {JAN: 0, FEB: 1, MAR: 2, APR: 3, MAY: 4, JUN: 5, JUL: 6, AUG: 7, SEP: 8, OCT: 9, NOV: 10, DEC: 11};\n"+
"function weekdayRange() {\n" +
" function getDay(weekday) {\n" +
" for (var i = 0; i < 6; i++) {\n" +
" if (weekday == wdays[i]) \n" +
" return i;\n" +
" if (weekday in wdays) {\n" +
" return wdays[weekday];\n" +
" }\n" +
" return -1;\n" +
" }\n" +
@ -274,9 +273,8 @@ var pacUtils =
"function dateRange() {\n" +
" function getMonth(name) {\n" +
" for (var i = 0; i < 6; i++) {\n" +
" if (name == monthes[i])\n" +
" return i;\n" +
" if (name in months) {\n" +
" return months[name];\n" +
" }\n" +
" return -1;\n" +
" }\n" +

View File

@ -488,25 +488,14 @@ nsCacheEntryHashTable::RemoveEntry( nsCacheEntry *cacheEntry)
void
nsCacheEntryHashTable::VisitEntries( nsCacheEntryHashTable::Visitor *visitor)
nsCacheEntryHashTable::VisitEntries( PLDHashEnumerator etor, void *arg)
{
NS_ASSERTION(initialized, "nsCacheEntryHashTable not initialized");
if (!initialized) return; // NS_ERROR_NOT_INITIALIZED
PL_DHashTableEnumerate(&table, VisitEntry, visitor);
PL_DHashTableEnumerate(&table, etor, arg);
}
PLDHashOperator PR_CALLBACK
nsCacheEntryHashTable::VisitEntry(PLDHashTable *table,
PLDHashEntryHdr *hashEntry,
PRUint32 number,
void *arg)
{
nsCacheEntry *cacheEntry = ((nsCacheEntryHashTableEntry *)hashEntry)->cacheEntry;
nsCacheEntryHashTable::Visitor *visitor = (nsCacheEntryHashTable::Visitor*) arg;
return (visitor->VisitEntry(cacheEntry) ? PL_DHASH_NEXT : PL_DHASH_STOP);
}
/**
* hash table operation callback functions
*/

View File

@ -295,17 +295,9 @@ public:
nsresult AddEntry( nsCacheEntry *entry);
void RemoveEntry( nsCacheEntry *entry);
// XXX enumerate entries?
class Visitor {
public:
virtual PRBool VisitEntry( nsCacheEntry *entry) = 0;
};
void VisitEntries( Visitor *visitor);
private:
friend class nsCacheService; // XXX redefine interface so this isn't necessary
void VisitEntries( PLDHashEnumerator etor, void *arg);
private:
// PLDHashTable operation callbacks
static PLDHashNumber PR_CALLBACK HashKey( PLDHashTable *table, const void *key);

View File

@ -2139,8 +2139,7 @@ nsCacheService::ClearDoomList()
void
nsCacheService::ClearActiveEntries()
{
// XXX really we want a different finalize callback for mActiveEntries
PL_DHashTableEnumerate(&mActiveEntries.table, DeactivateAndClearEntry, nsnull);
mActiveEntries.VisitEntries(DeactivateAndClearEntry, nsnull);
mActiveEntries.Shutdown();
}
@ -2168,7 +2167,7 @@ nsCacheService::DoomActiveEntries()
{
nsAutoVoidArray array;
PL_DHashTableEnumerate(&mActiveEntries.table, RemoveActiveEntry, &array);
mActiveEntries.VisitEntries(RemoveActiveEntry, &array);
PRUint32 count = array.Count();
for (PRUint32 i=0; i < count; ++i)

View File

@ -472,22 +472,14 @@ nsMemoryCacheDevice::SetCapacity(PRInt32 capacity)
#ifdef DEBUG
class nsCacheHashCounter : public nsCacheEntryHashTable::Visitor {
public:
nsCacheHashCounter() : entryCount(0) {}
PRBool VisitEntry(nsCacheEntry * entry);
PRInt32 entryCount;
};
PRBool nsCacheHashCounter::VisitEntry(nsCacheEntry * entry)
static PLDHashOperator PR_CALLBACK
CountEntry(PLDHashTable * table, PLDHashEntryHdr * hdr, PRUint32 number, void * arg)
{
++entryCount;
return PR_TRUE;
PRInt32 *entryCount = (PRInt32 *)arg;
++(*entryCount);
return PL_DHASH_NEXT;
}
void
nsMemoryCacheDevice::CheckEntryCount()
{
@ -503,9 +495,9 @@ nsMemoryCacheDevice::CheckEntryCount()
}
NS_ASSERTION(mEntryCount == evictionListCount, "### mem cache badness");
nsCacheHashCounter hash;
mMemCacheEntries.VisitEntries(&hash);
NS_ASSERTION(mEntryCount == hash.entryCount, "### mem cache badness");
PRInt32 entryCount = 0;
mMemCacheEntries.VisitEntries(CountEntry, &entryCount);
NS_ASSERTION(mEntryCount == entryCount, "### mem cache badness");
}
#endif

View File

@ -44,10 +44,6 @@
xmlns:html="http://www.w3.org/1999/xhtml">
<tabpanel id="qa-tab-bugzilla">
<vbox flex="1">
<label href="http://bugzilla.mozilla.org"
value="Help us by filing and confirming bugs in Bugzilla"
class="text-link" />
<groupbox>
<caption label="Bug Search" />
<radiogroup id = "qa-bugzilla-input-radiogroup"

View File

@ -47,9 +47,8 @@
<tabpanel id="qa-tab-help">
<vbox flex="1">
<groupbox>
<caption label="Mozilla QA Help" />
<div xmlns="http://www.w3.org/1999/xhtml" id="qa-help-info" flex="1">
</div>
<caption label="&qa.help.helptitle;" />
<description>&qa.help.intro;</description>
</groupbox>
</vbox>

View File

@ -183,7 +183,10 @@ possible, but please check the settings below and make any necessary changes.
<!ENTITY qa.chat.title "Chat">
<!ENTITY qa.chat.introtitle "What is IRC?">
<!ENTITY qa.chat.intro "Internet Relay Chat (IRC) is the living room of the Mozilla QA Community. IRC is a place to ask questions, learn how you can help with the next versions of Firefox and Thunderbird, and meet other members of the community. Many of the regular QA events happen over IRC, such as Test Days and Bug Days. Come join us on IRC!">
<!ENTITY qa.chat.intro "Internet Relay Chat (IRC) is the living room of the Mozilla QA Community.
IRC is a place to ask questions, learn how you can help with the next versions of Firefox and Thunderbird,
and meet other members of the community. Many of the regular QA events happen over IRC,
such as Test Days and Bug Days. Come join us on IRC!">
<!ENTITY qa.chat.intro2 "If you have a favorite IRC client, you can connect to <html:em>irc.mozilla.org</html:em>, channel #qa, but the easist way to get on IRC right now is through your web browser. Just click the button below.">
<!ENTITY qa.chat.howdoItitle "How do I get on IRC?">
<!ENTITY qa.chat.howdoI.imo "Learn more about irc.mozilla.org">
@ -193,5 +196,22 @@ possible, but please check the settings below and make any necessary changes.
<!ENTITY qa.chat.howdoI.joinnow "Join IRC Now">
<!ENTITY qa.help.title "Help">
<!ENTITY qa.help.helptitle "Mozilla QA Help">
<!ENTITY qa.help.intro "
Visit <html:a href='http://quality.mozilla.org/' style='color: #0067ac;' target='_blank'>
QMO</html:a>, the home of Mozilla QA, for more information about what's happening with the community. Here are a few useful links:<html:br></html:br><html:br></html:br>
<html:ul>
<html:li><html:a href='http://quality.mozilla.org/qac' style='color: #0067ac;' target='_blank'>QA Companion Home</html:a></html:li>
<html:li><html:a href='http://quality.mozilla.org/events' style='color: #0067ac;' target='_blank'>Community Events</html:a></html:li>
<html:li><html:a href='http://quality.mozilla.org/forums' style='color: #0067ac;' target='_blank'>Discussion Forums</html:a></html:li>
</html:ul>
<html:h4>Litmus</html:h4>
The Litmus tab is great for running a few quick tests, but visit <html:a href='http://litmus.mozilla.org/' style='color: #0067ac;'
target='_blank'>Litmus</html:a> for detailed information about test cases and community activity through the Web interface. Make sure to read
the <html:a href='http://quality.mozilla.org/litmus' style='color: #0067ac;' target='_blank'>Litmus Tutorial</html:a>.
<html:h4>Bugzilla</html:h4>
The Bugzilla tab allows you to run a few basic searches, but visit <html:a href='http://bugzilla.mozilla.org/' style='color: #0067ac;'
target='_blank'>Bugzilla</html:a> to learn more about how we handle bugs, run advanced searches or work with bugs directly.
">
<!ENTITY qa.notification.inprogress "Come Join! Event in Progress Now!">

View File

@ -8,7 +8,7 @@
em:maxVersion="3.0b5pre"/>
<RDF:Description RDF:about="urn:mozilla:install-manifest"
em:id="{667e9f3d-0096-4d2b-b171-9a96afbabe20}"
em:version="0.1.8"
em:version="0.1.9"
em:type="2"
em:name="Mozilla QA Companion"
em:description="The QA tool for testers."

View File

@ -219,7 +219,6 @@ LoginManagerPrompter.prototype = {
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
var selectedLogin = null;
var foundLogins;
var checkBox = { value : false };
var checkBoxLabel = null;
var hostname = this._getFormattedHostname(aPasswordRealm);
@ -234,19 +233,28 @@ LoginManagerPrompter.prototype = {
if (canRememberLogin)
checkBoxLabel = this._getLocalizedString("rememberPassword");
if (!aUsername.value && !aPassword.value) {
// Look for existing logins.
foundLogins = this._pwmgr.findLogins({}, hostname, null,
// Look for existing logins.
var foundLogins = this._pwmgr.findLogins({}, hostname, null,
aPasswordRealm);
// XXX Like the original code, we can't deal with multiple
// account selection. (bug 227632)
if (foundLogins.length > 0) {
selectedLogin = foundLogins[0];
// We've got a login, but don't return straight away because
// the old wallet code didn't either.
aUsername.value = foundLogins[0].username;
aPassword.value = foundLogins[0].password;
// XXX Like the original code, we can't deal with multiple
// account selection. (bug 227632)
if (foundLogins.length > 0) {
selectedLogin = foundLogins[0];
// If the caller provided a username, try to use it. If they
// provided only a password, this will try to find a password-only
// login (or return null if none exists).
if (aUsername.value)
selectedLogin = this._repickSelectedLogin(foundLogins,
aUsername.value);
if (selectedLogin) {
checkBox.value = true;
aUsername.value = selectedLogin.username;
// If the caller provided a password, prefer it.
if (!aPassword.value)
aPassword.value = selectedLogin.password;
}
}
@ -254,29 +262,33 @@ LoginManagerPrompter.prototype = {
aDialogTitle, aText, aUsername, aPassword,
checkBoxLabel, checkBox);
if (ok && checkBox.value) {
var newLogin = Cc["@mozilla.org/login-manager/loginInfo;1"].
createInstance(Ci.nsILoginInfo);
newLogin.init(hostname, null, aPasswordRealm,
aUsername.value, aPassword.value,
"", "");
if (!ok || !checkBox.value)
return ok;
// If we didn't find an existing login, or if the username
// changed, save as a new login.
if (!selectedLogin || username != selectedLogin.username) {
// add as new
this.log("New login seen for " + aPasswordRealm);
this._pwmgr.addLogin(newLogin);
} else if (selectedLogin &&
password != selectedLogin.password) {
// update password
this.log("Updating password for " + aPasswordRealm);
this._pwmgr.modifyLogin(foundLogins[0], newLogin);
} else {
this.log("Login unchanged, no further action needed.");
return ok;
}
var newLogin = Cc["@mozilla.org/login-manager/loginInfo;1"].
createInstance(Ci.nsILoginInfo);
newLogin.init(hostname, null, aPasswordRealm,
aUsername.value, aPassword.value,
"", "");
// XXX We can't prompt with multiple logins yet (bug 227632), so
// the entered login might correspond to an existing login
// other than the one we originally selected.
selectedLogin = this._repickSelectedLogin(foundLogins, aUsername.value);
// If we didn't find an existing login, or if the username
// changed, save as a new login.
if (!selectedLogin) {
// add as new
this.log("New login seen for " + aPasswordRealm);
this._pwmgr.addLogin(newLogin);
} else if (aPassword.value != selectedLogin.password) {
// update password
this.log("Updating password for " + aPasswordRealm);
this._pwmgr.modifyLogin(selectedLogin, newLogin);
} else {
this.log("Login unchanged, no further action needed.");
}
return ok;
@ -316,15 +328,13 @@ LoginManagerPrompter.prototype = {
if (!aPassword.value) {
// Look for existing logins.
var foundLogins = this._pwmgr.findLogins({}, hostname, null,
newRealm);
var i;
// XXX Like the original code, we can't deal with multiple
// account selection (bug 227632). We can deal with finding the
// account based on the supplied username - but in this case we'll
// just return the first match.
for (i = 0; i < foundLogins.length; ++i) {
for (var i = 0; i < foundLogins.length; ++i) {
if (foundLogins[i].username == username) {
aPassword.value = foundLogins[i].password;
// wallet returned straight away, so this mimics that code
@ -414,48 +424,48 @@ LoginManagerPrompter.prototype = {
var ok = this._promptService.promptAuth(this._window, aChannel,
aLevel, aAuthInfo, checkboxLabel, checkbox);
if (epicfail)
// If there's a notification box, use it to allow the user to
// determine if the login should be saved. If there isn't a
// notification box, only save the login if the user set the
// checkbox to do so.
var rememberLogin = notifyBox ? canRememberLogin : checkbox.value;
if (!ok || !rememberLogin || epicfail)
return ok;
try {
var [username, password] = this._GetAuthInfo(aAuthInfo);
// If there's a notification box, use it to allow the user to
// determine if the login should be saved. If there isn't a
// notification box, only save the login if the user set the
// checkbox to do so.
var rememberLogin = notifyBox ? canRememberLogin : checkbox.value;
var newLogin = Cc["@mozilla.org/login-manager/loginInfo;1"].
createInstance(Ci.nsILoginInfo);
newLogin.init(hostname, null, httpRealm,
username, password, "", "");
if (ok && rememberLogin) {
var newLogin = Cc["@mozilla.org/login-manager/loginInfo;1"].
createInstance(Ci.nsILoginInfo);
newLogin.init(hostname, null, httpRealm,
username, password, "", "");
// XXX We can't prompt with multiple logins yet (bug 227632), so
// the entered login might correspond to an existing login
// other than the one we originally selected.
selectedLogin = this._repickSelectedLogin(foundLogins, username);
// If we didn't find an existing login, or if the username
// changed, save as a new login.
if (!selectedLogin || username != selectedLogin.username) {
// If we didn't find an existing login, or if the username
// changed, save as a new login.
if (!selectedLogin) {
// add as new
this.log("New login seen for " + username +
" @ " + hostname + " (" + httpRealm + ")");
if (notifyBox)
this._showSaveLoginNotification(notifyBox, newLogin);
else
this._pwmgr.addLogin(newLogin);
// add as new
this.log("New login seen for " + username +
" @ " + hostname + " (" + httpRealm + ")");
if (notifyBox)
this._showSaveLoginNotification(notifyBox, newLogin);
else
this._pwmgr.addLogin(newLogin);
} else if (password != selectedLogin.password) {
} else if (selectedLogin &&
password != selectedLogin.password) {
this.log("Updating password for " + username +
" @ " + hostname + " (" + httpRealm + ")");
// update password
this._pwmgr.modifyLogin(selectedLogin, newLogin);
this.log("Updating password for " + username +
" @ " + hostname + " (" + httpRealm + ")");
// update password
this._pwmgr.modifyLogin(foundLogins[0], newLogin);
} else {
this.log("Login unchanged, no further action needed.");
return ok;
}
} else {
this.log("Login unchanged, no further action needed.");
}
} catch (e) {
Components.utils.reportError("LoginManagerPrompter: " +
@ -899,6 +909,21 @@ LoginManagerPrompter.prototype = {
},
/*
* _repickSelectedLogin
*
* The user might enter a login that isn't the one we prefilled, but
* is the same as some other existing login. So, pick a login with a
* matching username, or return null.
*/
_repickSelectedLogin : function (foundLogins, username) {
for (var i = 0; i < foundLogins.length; i++)
if (foundLogins[i].username == username)
return foundLogins[i];
return null;
},
/*
* _getLocalizedString
*

View File

@ -63,6 +63,7 @@ MOCHI_TESTS = \
test_bug_360493_1.html \
test_bug_360493_2.html \
test_bug_391514.html \
test_prompt.html \
test_zzz_finish.html \
$(NULL)

View File

@ -0,0 +1,627 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test for Login Manager</title>
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="pwmgr_common.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
Login Manager test: username/password prompts
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Login Manager: username / password prompts. **/
var pwmgr, login1, login2A, login2B;
function initLogins() {
pwmgr = Cc["@mozilla.org/login-manager;1"].
getService(Ci.nsILoginManager);
login1 = Cc["@mozilla.org/login-manager/loginInfo;1"].
createInstance(Ci.nsILoginInfo);
login2A = Cc["@mozilla.org/login-manager/loginInfo;1"].
createInstance(Ci.nsILoginInfo);
login2B = Cc["@mozilla.org/login-manager/loginInfo;1"].
createInstance(Ci.nsILoginInfo);
login1.init("http://example.com", null, "http://example.com",
"", "examplepass", "", "");
login2A.init("http://example2.com", null, "http://example2.com",
"user1name", "user1pass", "", "");
login2B.init("http://example2.com", null, "http://example2.com",
"user2name", "user2pass", "", "");
pwmgr.addLogin(login1);
pwmgr.addLogin(login2A);
pwmgr.addLogin(login2B);
}
function cleanupLogins() {
pwmgr.removeLogin(login1);
pwmgr.removeLogin(login2A);
pwmgr.removeLogin(login2B);
}
function getDialogDoc() {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
// Find the <browser> which contains notifyWindow, by looking
// through all the open windows and all the <browsers> in each.
var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
getService(Ci.nsIWindowMediator);
//var enumerator = wm.getEnumerator("navigator:browser");
var enumerator = wm.getXULWindowEnumerator(null);
var promptDoc = null;
while (!promptDoc && enumerator.hasMoreElements()) {
var win = enumerator.getNext();
var windowDocShell = win.QueryInterface(Ci.nsIXULWindow).docShell;
var containedDocShells = windowDocShell.getDocShellEnumerator(
Ci.nsIDocShellTreeItem.typeChrome,
Ci.nsIDocShell.ENUMERATE_FORWARDS);
while (!promptDoc && containedDocShells.hasMoreElements()) {
// Get the corresponding document for this docshell
var childDoc = containedDocShells.getNext()
.QueryInterface(Ci.nsIDocShell)
.contentViewer
.DOMDocument;
//ok(true, "Got window: " + childDoc.location.href);
if (childDoc.location.href == "chrome://global/content/commonDialog.xul")
promptDoc = childDoc;
}
}
return promptDoc;
}
function handleDialog(doc, testNum) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
ok(true, "handleDialog running for test " + testNum);
var clickOK = true;
var userfield = doc.getElementById("loginTextbox");
var passfield = doc.getElementById("password1Textbox");
var username = userfield.getAttribute("value");
var password = passfield.getAttribute("value");
var dialog = doc.getElementById("commonDialog");
switch(testNum) {
case 1:
is(username, "abc", "Checking provided username");
userfield.setAttribute("value", "xyz");
break;
case 2:
clickOK = false;
break;
case 10:
is(password, "inputpw", "Checking provided password");
passfield.setAttribute("value", "secret");
break;
case 11:
is(password, "inputpw", "Checking provided password");
clickOK = false;
break;
case 12:
is(password, "", "Checking provided password");
passfield.setAttribute("value", "secret");
break;
case 14:
is(password, "", "Checking provided password");
passfield.setAttribute("value", "secret");
break;
case 100:
is(username, "inuser", "Checking provided username");
is(password, "inpass", "Checking provided password");
userfield.setAttribute("value", "outuser");
passfield.setAttribute("value", "outpass");
break;
case 101:
clickOK = false;
break;
case 102:
is(username, "", "Checking provided username");
is(password, "examplepass", "Checking provided password");
break;
case 103:
ok(username == "user1name" || username == "user2name", "Checking filled username");
ok(password == "user1pass" || password == "user2pass", "Checking filled password");
break;
case 104:
is(username, "user1name", "Checking filled username");
is(password, "user1pass", "Checking filled password");
break;
case 105:
is(username, "user2name", "Checking filled username");
is(password, "user2pass", "Checking filled password");
break;
case 106:
is(username, "user2name", "Checking filled username");
is(password, "user2pass", "Checking filled password");
passfield.setAttribute("value", "NEWuser2pass");
break;
case 107:
is(username, "user2name", "Checking filled username");
is(password, "NEWuser2pass", "Checking filled password");
passfield.setAttribute("value", "user2pass");
break;
case 500:
is(username, "inuser", "Checking unfilled username");
is(password, "inpass", "Checking unfilled password");
userfield.setAttribute("value", "outuser");
passfield.setAttribute("value", "outpass");
break;
case 501:
clickOK = false;
break;
case 502:
is(username, "", "Checking filled username");
is(password, "examplepass", "Checking filled password");
break;
case 503:
// either of the two logins might have been filled in
ok(username == "user1name" || username == "user2name", "Checking filled username");
ok(password == "user1pass" || password == "user2pass", "Checking filled password");
break;
case 504:
// either of the two logins might have been filled in
ok(username == "user1name" || username == "user2name", "Checking filled username");
ok(password == "user1pass" || password == "user2pass", "Checking filled password");
// enter one of the known logins, test 504+505 exercise the two possible states.
userfield.setAttribute("value", "user1name");
passfield.setAttribute("value", "user1pass");
break;
case 505:
// either of the two logins might have been filled in
ok(username == "user1name" || username == "user2name", "Checking filled username");
ok(password == "user1pass" || password == "user2pass", "Checking filled password");
// enter one of the known logins, test 504+505 exercise the two possible states.
userfield.setAttribute("value", "user2name");
passfield.setAttribute("value", "user2pass");
break;
case 506:
// either of the two logins might have been filled in
ok(username == "user1name" || username == "user2name", "Checking filled username");
ok(password == "user1pass" || password == "user2pass", "Checking filled password");
// force to user2, and change the password
userfield.setAttribute("value", "user2name");
passfield.setAttribute("value", "NEWuser2pass");
break;
case 507:
// either of the two logins might have been filled in
ok(username == "user1name" || username == "user2name", "Checking filled username");
ok(password == "user1pass" || password == "user2pass", "Checking filled password");
// force to user2, and change the password back
userfield.setAttribute("value", "user2name");
passfield.setAttribute("value", "user2pass");
break;
default:
ok(false, "Uhh, unhandled switch for testNum #" + testNum);
break;
}
if (clickOK)
dialog.acceptDialog();
else
dialog.cancelDialog();
ok(true, "handleDialog done");
}
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
const Ci = Components.interfaces;
ok(Ci != null, "Access Ci");
const Cc = Components.classes;
ok(Cc != null, "Access Cc");
initLogins();
const Cc_promptFac= Cc["@mozilla.org/passwordmanager/authpromptfactory;1"];
ok(Cc_promptFac != null, "Access Cc[@mozilla.org/passwordmanager/authpromptfactory;1]");
const Ci_promptFac = Ci.nsIPromptFactory;
ok(Ci_promptFac != null, "Access Ci.nsIPromptFactory");
const promptFac = Cc_promptFac.getService(Ci_promptFac);
ok(promptFac != null, "promptFac getService()");
var timer; // keep in outer scope so it's not GC'd before firing
function startCallbackTimer() {
// Delay before the callback twiddles the prompt.
const dialogDelay = 300;
// Use a timer to invoke a callback to twiddle the authentication dialog
timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
timer.init(observer, dialogDelay, Ci.nsITimer.TYPE_ONE_SHOT);
}
var observer = {
QueryInterface : function (iid) {
const interfaces = [Ci.nsIObserver,
Ci.nsISupports, Ci.nsISupportsWeakReference];
if (!interfaces.some( function(v) { return iid.equals(v) } ))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
},
observe : function (subject, topic, data) {
ok(true, "timer fired for test " + testNum);
var doc = getDialogDoc();
ok(doc, "Got commonDialog.xul document");
if (doc)
handleDialog(doc, testNum);
}
};
var authinfo = {
// QueryInterface : ... ?
username : "",
password : "",
domain : "",
flags : Ci.nsIAuthInformation.AUTH_HOST,
authenticationScheme : "basic",
realm : ""
};
var prompter1 = promptFac.getPrompt(window, Ci.nsIAuthPrompt);
var prompter2 = promptFac.getPrompt(window, Ci.nsIAuthPrompt2);
function dialogTitle() { return "nsILoginManagerPrompter test #" + testNum; }
var dialogText = "This dialog should be modified and dismissed by the test.";
var uname = { value : null };
var pword = { value : null };
var result = { value : null };
var isOk;
// ===== test 1 =====
var testNum = 1;
startCallbackTimer();
isOk = prompter1.prompt(dialogTitle(), dialogText, "http://example.com",
Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, "abc", result);
ok(isOk, "Checking dialog return value (accept)");
is(result.value, "xyz", "Checking prompt() returned value");
// ===== test 2 =====
testNum++;
startCallbackTimer();
isOk = prompter1.prompt(dialogTitle(), dialogText, "http://example.com",
Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, "abc", result);
ok(!isOk, "Checking dialog return value (cancel)");
// ===== test 10 =====
// Default password provided, existing logins are ignored.
testNum = 10;
pword.value = "inputpw";
startCallbackTimer();
isOk = prompter1.promptPassword(dialogTitle(), dialogText, "http://example.com",
Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
ok(isOk, "Checking dialog return value (accept)");
is(pword.value, "secret", "Checking returned password");
// ===== test 11 =====
// Default password provided, existing logins are ignored.
testNum++;
pword.value = "inputpw";
startCallbackTimer();
isOk = prompter1.promptPassword(dialogTitle(), dialogText, "http://example.com",
Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
ok(!isOk, "Checking dialog return value (cancel)");
// ===== test 12 =====
// No default password provided, realm does not match existing login.
testNum++;
pword.value = null;
startCallbackTimer();
isOk = prompter1.promptPassword(dialogTitle(), dialogText, "http://nonexample.com",
Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
ok(isOk, "Checking dialog return value (accept)");
is(pword.value, "secret", "Checking returned password");
// ===== test 13 =====
// No default password provided, matching login is returned w/o prompting.
testNum++;
pword.value = null;
isOk = prompter1.promptPassword(dialogTitle(), dialogText, "http://example.com",
Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
ok(isOk, "Checking dialog return value (accept)");
is(pword.value, "examplepass", "Checking returned password");
// ===== test 14 =====
// No default password provided, none of the logins from this host are
// password-only so the user is prompted.
testNum++;
pword.value = null;
startCallbackTimer();
isOk = prompter1.promptPassword(dialogTitle(), dialogText, "http://example2.com",
Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
ok(isOk, "Checking dialog return value (accept)");
is(pword.value, "secret", "Checking returned password");
// ===== test 15 =====
// No default password provided, matching login is returned w/o prompting.
testNum++;
pword.value = null;
isOk = prompter1.promptPassword(dialogTitle(), dialogText, "http://user1name@example2.com",
Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
ok(isOk, "Checking dialog return value (accept)");
is(pword.value, "user1pass", "Checking returned password");
// ===== test 16 =====
// No default password provided, matching login is returned w/o prompting.
testNum++;
pword.value = null;
isOk = prompter1.promptPassword(dialogTitle(), dialogText, "http://user2name@example2.com",
Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, pword);
ok(isOk, "Checking dialog return value (accept)");
is(pword.value, "user2pass", "Checking returned password");
// XXX test saving a password with Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY
// ===== test 100 =====
testNum = 100;
uname.value = "inuser";
pword.value = "inpass";
startCallbackTimer();
isOk = prompter1.promptUsernameAndPassword(dialogTitle(), dialogText, "http://nonexample.com",
Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, uname, pword);
ok(isOk, "Checking dialog return value (accept)");
is(uname.value, "outuser", "Checking returned username");
is(pword.value, "outpass", "Checking returned password");
// ===== test 101 =====
testNum++;
uname.value = "inuser";
pword.value = "inpass";
startCallbackTimer();
isOk = prompter1.promptUsernameAndPassword(dialogTitle(), dialogText, "http://nonexample.com",
Ci.nsIAuthPrompt.SAVE_PASSWORD_NEVER, uname, pword);
ok(!isOk, "Checking dialog return value (cancel)");
// ===== test 102 =====
// test filling in existing password-only login
testNum++;
uname.value = null;
pword.value = null;
startCallbackTimer();
isOk = prompter1.promptUsernameAndPassword(dialogTitle(), dialogText, "http://example.com",
Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword);
ok(isOk, "Checking dialog return value (accept)");
is(uname.value, "", "Checking returned username");
is(pword.value, "examplepass", "Checking returned password");
// ===== test 103 =====
// test filling in existing login (undetermined from multiple selection)
testNum++;
uname.value = null;
pword.value = null;
startCallbackTimer();
isOk = prompter1.promptUsernameAndPassword(dialogTitle(), dialogText, "http://example2.com",
Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword);
ok(isOk, "Checking dialog return value (accept)");
ok(uname.value == "user1name" || uname.value == "user2name", "Checking returned username");
ok(pword.value == "user1pass" || uname.value == "user2pass", "Checking returned password");
// ===== test 104 =====
// test filling in existing login (user1 from multiple selection)
testNum++;
uname.value = "user1name";
pword.value = null;
startCallbackTimer();
isOk = prompter1.promptUsernameAndPassword(dialogTitle(), dialogText, "http://example2.com",
Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword);
ok(isOk, "Checking dialog return value (accept)");
is(uname.value, "user1name", "Checking returned username");
is(pword.value, "user1pass", "Checking returned password");
// ===== test 105 =====
// test filling in existing login (user2 from multiple selection)
testNum++;
uname.value = "user2name";
pword.value = null;
startCallbackTimer();
isOk = prompter1.promptUsernameAndPassword(dialogTitle(), dialogText, "http://example2.com",
Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword);
ok(isOk, "Checking dialog return value (accept)");
is(uname.value, "user2name", "Checking returned username");
is(pword.value, "user2pass", "Checking returned password");
// ===== test 106 =====
// test changing password
testNum++;
uname.value = "user2name";
pword.value = null;
startCallbackTimer();
isOk = prompter1.promptUsernameAndPassword(dialogTitle(), dialogText, "http://example2.com",
Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword);
ok(isOk, "Checking dialog return value (accept)");
is(uname.value, "user2name", "Checking returned username");
is(pword.value, "NEWuser2pass", "Checking returned password");
// ===== test 107 =====
// test changing password (back to original value)
testNum++;
uname.value = "user2name";
pword.value = null;
startCallbackTimer();
isOk = prompter1.promptUsernameAndPassword(dialogTitle(), dialogText, "http://example2.com",
Ci.nsIAuthPrompt.SAVE_PASSWORD_PERMANENTLY, uname, pword);
ok(isOk, "Checking dialog return value (accept)");
is(uname.value, "user2name", "Checking returned username");
is(pword.value, "user2pass", "Checking returned password");
var channel1 = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService).
newChannel("http://example.com", null, null);
var channel2 = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService).
newChannel("http://example2.com", null, null);
var level = Ci.nsIAuthPrompt2.LEVEL_NONE;
// ===== test 500 =====
testNum = 500;
authinfo.username = "inuser";
authinfo.password = "inpass";
authinfo.realm = "some realm";
startCallbackTimer();
isOk = prompter2.promptAuth(channel1, level, authinfo);
ok(isOk, "Checking dialog return value (accept)");
is(authinfo.username, "outuser", "Checking returned username");
is(authinfo.password, "outpass", "Checking returned password");
// ===== test 501 =====
testNum++;
startCallbackTimer();
isOk = prompter2.promptAuth(channel1, level, authinfo);
// XXX for some reason |!isOk == false| on the OS X tinderbox, although it's
// not when run locally (and clicking cancel does work, which is what this
// is testing). Not sure why.
// ok(!isOk, "Checking dialog return value (cancel)");
ok(true, "XXX dialog returned " + isOk);
// ===== test 502 =====
// test filling in password-only login
testNum++;
authinfo.username = "";
authinfo.password = "";
authinfo.realm = "http://example.com";
startCallbackTimer();
isOk = prompter2.promptAuth(channel1, level, authinfo);
ok(isOk, "Checking dialog return value (accept)");
is(authinfo.username, "", "Checking returned username");
is(authinfo.password, "examplepass", "Checking returned password");
// ===== test 503 =====
// test filling in existing login (undetermined from multiple selection)
testNum++;
authinfo.username = "";
authinfo.password = "";
authinfo.realm = "http://example2.com";
startCallbackTimer();
isOk = prompter2.promptAuth(channel2, level, authinfo);
ok(isOk, "Checking dialog return value (accept)");
ok(authinfo.username == "user1name" || authinfo.username == "user2name", "Checking returned username");
ok(authinfo.password == "user1pass" || authinfo.password == "user2pass", "Checking returned password");
// ===== test 504 =====
// test filling in existing login (undetermined --> user1)
testNum++;
authinfo.username = "";
authinfo.password = "";
authinfo.realm = "http://example2.com";
startCallbackTimer();
isOk = prompter2.promptAuth(channel2, level, authinfo);
ok(isOk, "Checking dialog return value (accept)");
is(authinfo.username, "user1name", "Checking returned username");
is(authinfo.password, "user1pass", "Checking returned password");
// ===== test 505 =====
// test filling in existing login (undetermined --> user2)
testNum++;
authinfo.username = "";
authinfo.password = "";
authinfo.realm = "http://example2.com";
startCallbackTimer();
isOk = prompter2.promptAuth(channel2, level, authinfo);
ok(isOk, "Checking dialog return value (accept)");
is(authinfo.username, "user2name", "Checking returned username");
is(authinfo.password, "user2pass", "Checking returned password");
// ===== test 506 =====
// test changing a password (undetermined --> user2 w/ newpass)
testNum++;
authinfo.username = "";
authinfo.password = "";
authinfo.realm = "http://example2.com";
startCallbackTimer();
isOk = prompter2.promptAuth(channel2, level, authinfo);
ok(isOk, "Checking dialog return value (accept)");
is(authinfo.username, "user2name", "Checking returned username");
is(authinfo.password, "NEWuser2pass", "Checking returned password");
// ===== test 507 =====
// test changing a password (undetermined --> user2 w/ origpass)
testNum++;
authinfo.username = "";
authinfo.password = "";
authinfo.realm = "http://example2.com";
startCallbackTimer();
isOk = prompter2.promptAuth(channel2, level, authinfo);
ok(isOk, "Checking dialog return value (accept)");
is(authinfo.username, "user2name", "Checking returned username");
is(authinfo.password, "user2pass", "Checking returned password");
// XXX check for and kill notification bar??
// XXX check for checkbox / checkstate on old prompts?
// XXX check NTLM domain stuff
cleanupLogins();
</script>
</pre>
</body>
</html>

View File

@ -5,6 +5,7 @@
XUL Widget Test for textbox with emptyText
-->
<window title="Textbox with emptyText test" width="500" height="600"
onload="window.focus();"
onfocus="if (!gDone) { gDone = true; doTests(); }"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript" src="/MochiKit/packed.js"></script>

View File

@ -5,6 +5,7 @@
XUL Widget Test for textbox type="number"
-->
<window title="Textbox type='number' test" width="500" height="600"
onload="window.focus();"
onfocus="if (!gDone) { gDone = true; doTests(); }"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript" src="/MochiKit/packed.js"></script>

View File

@ -3,7 +3,8 @@
<?xml-stylesheet href="/tests/SimpleTest/test.css" type="text/css"?>
<window title="Tooltip Noautohide Tests"
onfocus="setTimeout(runTests, 0);"
onload="window.focus();"
onfocus="if (!gDone) { gDone = true; setTimeout(runTests, 0); }"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<script type="application/javascript" src="/MochiKit/packed.js"></script>
@ -21,6 +22,7 @@
<script class="testbody" type="application/javascript">
<![CDATA[
var gDone = false;
var gChecked = false;
SimpleTest.waitForExplicitFinish();

View File

@ -3,7 +3,7 @@
For example style definitions for navigator can be found in navigator.css
THIS FILE IS LOCKED DOWN. YOU ARE NOT ALLOWED TO MODIFY IT WITHOUT FIRST HAVING YOUR
CHANGES REVIEWED BY mconnor@steelgryphon.com
CHANGES REVIEWED BY enndeakin@sympatico.ca
**/
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); /* set default namespace to XUL */
@ -53,8 +53,7 @@ window[chromehidden~="toolbar"] .chromeclass-toolbar-additional
:: or URI elements
::::: */
textbox.uri-element,
menulist.uri-element
.uri-element
{
direction: ltr !important;
}

View File

@ -436,13 +436,18 @@ nsUnknownContentTypeDialog.prototype = {
mimeType == "application/x-msdownload" ||
this.mLauncher.targetFileIsExecutable);
if (shouldntRememberChoice && !this.openWithDefaultOK()) {
let acceptButton = this.mDialog.document.getButton("accept");
// change the accept button icon to a save one
acceptButton.setAttribute("icon", "save");
// change button labels
acceptButton.label =
this.dialogElement("strings").getString("unknownAccept.label");
this.mDialog.document.documentElement.getButton("cancel").label =
this.dialogElement("strings").getString("unknownCancel.label");
// hide featured choice
this.mDialog.document.getElementById("normalBox").collapsed = "true";
// show basic choice
this.mDialog.document.getElementById("basicBox").collapsed = "false";
// change button labels
this.mDialog.document.documentElement.getButton("accept").label = this.dialogElement("strings").getString("unknownAccept.label");
this.mDialog.document.documentElement.getButton("cancel").label = this.dialogElement("strings").getString("unknownCancel.label");
// hide other handler
this.mDialog.document.getElementById("openHandler").collapsed = "true";
// set save as the selected option

View File

@ -1,8 +1,18 @@
#extensionsBox {
margin: 10px 10px 0px 10px;
margin: 10px 8px 0 8px;
min-width:1px;
}
/* Addons notification */
notification {
background-color: transparent;
}
.notification-inner {
background-color: infobackground;
border-color: ThreeDShadow;
margin: 9px 8px 0 8px;
}
#extensionsView {
border: 2px solid;
-moz-border-top-colors: ThreeDShadow ThreeDDarkShadow;
@ -54,6 +64,7 @@ richlistitem[isDisabled="true"] {
richlistitem[newAddon="true"] {
background-color: InfoBackground;
color: InfoText;
}
richlistitem[selected="true"] {

View File

@ -59,6 +59,7 @@ richlistitem[isDisabled="true"] {
richlistitem[newAddon="true"] {
background-color: #fdf2ab;
color: #585620;
}
richlistitem[selected="true"] {

View File

@ -53,6 +53,7 @@ richlistitem[isDisabled="true"] {
richlistitem[newAddon="true"] {
background-color: InfoBackground;
color: InfoText;
}
richlistitem[selected="true"] {

View File

@ -99,6 +99,7 @@ static GtkShadowType gToolbarShadowType;
static style_prop_t style_prop_func;
static gboolean have_menu_shadow_type;
static gboolean have_arrow_scaling;
static gboolean is_initialized;
gint
@ -253,54 +254,120 @@ ensure_option_menu_widget()
return MOZ_GTK_SUCCESS;
}
static gint
ensure_combo_box_entry_widget()
{
if (!gComboBoxEntryWidget) {
gComboBoxEntryWidget = gtk_combo_box_entry_new();
setup_widget_prototype(gComboBoxEntryWidget);
}
return MOZ_GTK_SUCCESS;
}
/* We need to have pointers to the inner widgets (entry, button, arrow) of
* the ComboBoxEntry to get the correct rendering from theme engines which
* special cases their look. Since the inner layout can change, we ask GTK
* to NULL our pointers when they are about to become invalid because the
* corresponding widgets don't exist anymore. It's the role of
* g_object_add_weak_pointer().
* Note that if we don't find the inner widgets (which shouldn't happen), we
* fallback to use generic "non-inner" widgets, and they don't need that kind
* of weak pointer since they are explicit children of gProtoWindow and as
* such GTK holds a strong reference to them. */
static gint
ensure_dropdown_entry_widget()
static void
moz_gtk_get_combo_box_entry_inner_widgets(GtkWidget *widget,
gpointer client_data)
{
if (!gDropdownEntryWidget) {
ensure_combo_box_entry_widget();
gDropdownEntryWidget = GTK_BIN(gComboBoxEntryWidget)->child;
gtk_widget_realize(gDropdownEntryWidget);
}
return MOZ_GTK_SUCCESS;
if (GTK_IS_TOGGLE_BUTTON(widget)) {
gDropdownButtonWidget = widget;
g_object_add_weak_pointer(G_OBJECT(widget),
(gpointer) &gDropdownButtonWidget);
} else if (GTK_IS_ENTRY(widget)) {
gDropdownEntryWidget = widget;
g_object_add_weak_pointer(G_OBJECT(widget),
(gpointer) &gDropdownEntryWidget);
} else
return;
gtk_widget_realize(widget);
}
static void
moz_gtk_get_dropdown_button(GtkWidget *widget,
gpointer client_data)
moz_gtk_get_combo_box_entry_arrow(GtkWidget *widget, gpointer client_data)
{
if (GTK_IS_TOGGLE_BUTTON(widget))
gDropdownButtonWidget = widget;
if (GTK_IS_ARROW(widget)) {
gArrowWidget = widget;
g_object_add_weak_pointer(G_OBJECT(widget),
(gpointer) &gArrowWidget);
gtk_widget_realize(widget);
}
}
static gint
ensure_arrow_widget()
ensure_combo_box_entry_widgets()
{
if (!gArrowWidget) {
ensure_combo_box_entry_widget();
if (!gDropdownEntryWidget ||
!gDropdownButtonWidget ||
!gArrowWidget) {
GtkWidget* buttonChild;
/* Create a ComboBoxEntry if needed */
if (!gComboBoxEntryWidget) {
gComboBoxEntryWidget = gtk_combo_box_entry_new();
setup_widget_prototype(gComboBoxEntryWidget);
}
/* Get its inner Entry and Button */
gtk_container_forall(GTK_CONTAINER(gComboBoxEntryWidget),
moz_gtk_get_dropdown_button,
moz_gtk_get_combo_box_entry_inner_widgets,
NULL);
gArrowWidget = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_OUT);
gtk_container_add(GTK_CONTAINER(GTK_BIN(gDropdownButtonWidget)->child),
gArrowWidget);
gtk_widget_realize(gArrowWidget);
if (!gDropdownEntryWidget) {
ensure_entry_widget();
gDropdownEntryWidget = gEntryWidget;
}
if (gDropdownButtonWidget) {
/* Get the Arrow inside the Button */
buttonChild = GTK_BIN(gDropdownButtonWidget)->child;
if (GTK_IS_HBOX(buttonChild)) {
/* appears-as-list = FALSE, cell-view = TRUE; the button
* contains an hbox. This hbox is there because ComboBoxEntry
* inherits from ComboBox which needs to place a cell renderer,
* a separator, and an arrow in the button when appears-as-list
* is FALSE. Here the hbox should only contain an arrow, since
* a ComboBoxEntry doesn't need all those widgets in the
* button. */
gtk_container_forall(GTK_CONTAINER(buttonChild),
moz_gtk_get_combo_box_entry_arrow,
NULL);
} else if(GTK_IS_ARROW(buttonChild)) {
/* appears-as-list = TRUE, or cell-view = FALSE;
* the button only contains an arrow */
gArrowWidget = buttonChild;
g_object_add_weak_pointer(G_OBJECT(buttonChild),
(gpointer) &gArrowWidget);
gtk_widget_realize(gArrowWidget);
}
} else {
/* Shouldn't be reached with current internal gtk implementation;
* we use a generic toggle button as last resort fallback to avoid
* crashing. */
ensure_toggle_button_widget();
gDropdownButtonWidget = gToggleButtonWidget;
}
if (!gArrowWidget) {
/* Shouldn't be reached with current internal gtk implementation;
* we use a generic down arrow as last resort fallback to avoid
* crashing. */
gArrowWidget = gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_NONE);
setup_widget_prototype(gArrowWidget);
}
}
return MOZ_GTK_SUCCESS;
}
/* Will go away when bug 416003 lands (Use different arrow widgets for
* arrows in different context) */
static gint
ensure_arrow_widget()
{
if (!gArrowWidget)
ensure_combo_box_entry_widgets();
return MOZ_GTK_SUCCESS;
}
static gint
ensure_handlebox_widget()
{
@ -675,6 +742,8 @@ moz_gtk_init()
have_menu_shadow_type =
(gtk_major_version > 2 ||
(gtk_major_version == 2 && gtk_minor_version >= 1));
have_arrow_scaling = (gtk_major_version > 2 ||
(gtk_major_version == 2 && gtk_minor_version >= 12));
return MOZ_GTK_SUCCESS;
}
@ -854,20 +923,28 @@ moz_gtk_toggle_paint(GdkDrawable* drawable, GdkRectangle* rect,
}
static gint
calculate_arrow_dimensions(GdkRectangle* rect, GdkRectangle* arrow_rect)
calculate_arrow_dimensions(GdkRectangle* rect, GdkRectangle* arrow_rect,
GtkTextDirection direction)
{
/* defined in gtkarrow.c */
gfloat arrow_scaling = 0.7;
gfloat xalign, xpad;
gint extent;
GtkMisc* misc = GTK_MISC(gArrowWidget);
gint extent = MIN(rect->width - misc->xpad * 2,
rect->height - misc->ypad * 2);
if (have_arrow_scaling)
gtk_widget_style_get(gArrowWidget,
"arrow_scaling", &arrow_scaling, NULL);
extent = MIN((rect->width - misc->xpad * 2),
(rect->height - misc->ypad * 2)) * arrow_scaling;
arrow_rect->x = ((rect->x + misc->xpad) * (1.0 - misc->xalign) +
(rect->x + rect->width - extent - misc->xpad) *
misc->xalign);
xalign = direction == GTK_TEXT_DIR_LTR ? misc->xalign : 1.0 - misc->xalign;
xpad = misc->xpad + (rect->width - extent) * xalign;
arrow_rect->y = ((rect->y + misc->ypad) * (1.0 - misc->yalign) +
(rect->y + rect->height - extent - misc->ypad) *
misc->yalign);
arrow_rect->x = direction == GTK_TEXT_DIR_LTR ?
floor(rect->x + xpad) : ceil(rect->x + xpad);
arrow_rect->y = floor(rect->y + misc->ypad +
((rect->height - extent) * misc->yalign));
arrow_rect->width = arrow_rect->height = extent;
@ -883,11 +960,11 @@ moz_gtk_scrollbar_button_paint(GdkDrawable* drawable, GdkRectangle* rect,
GtkStateType state_type = ConvertGtkState(state);
GtkShadowType shadow_type = (state->active) ?
GTK_SHADOW_IN : GTK_SHADOW_OUT;
GdkRectangle button_rect;
GdkRectangle arrow_rect;
GtkStyle* style;
GtkWidget *scrollbar;
GtkArrowType arrow_type;
gint arrow_displacement_x, arrow_displacement_y;
const char* detail = (flags & MOZ_GTK_STEPPER_VERTICAL) ?
"vscrollbar" : "hscrollbar";
@ -940,20 +1017,26 @@ moz_gtk_scrollbar_button_paint(GdkDrawable* drawable, GdkRectangle* rect,
style = scrollbar->style;
ensure_arrow_widget();
calculate_arrow_dimensions(rect, &button_rect);
TSOffsetStyleGCs(style, button_rect.x, button_rect.y);
TSOffsetStyleGCs(style, rect->x, rect->y);
gtk_paint_box(style, drawable, state_type, shadow_type, cliprect,
scrollbar, detail, button_rect.x, button_rect.y,
button_rect.width, button_rect.height);
scrollbar, detail, rect->x, rect->y,
rect->width, rect->height);
arrow_rect.width = button_rect.width / 2;
arrow_rect.height = button_rect.height / 2;
arrow_rect.x = button_rect.x + (button_rect.width - arrow_rect.width) / 2;
arrow_rect.y = button_rect.y +
(button_rect.height - arrow_rect.height) / 2;
arrow_rect.width = rect->width / 2;
arrow_rect.height = rect->height / 2;
arrow_rect.x = rect->x + (rect->width - arrow_rect.width) / 2;
arrow_rect.y = rect->y + (rect->height - arrow_rect.height) / 2;
if (state_type == GTK_STATE_ACTIVE) {
gtk_widget_style_get(scrollbar,
"arrow-displacement-x", &arrow_displacement_x,
"arrow-displacement-y", &arrow_displacement_y,
NULL);
arrow_rect.x += arrow_displacement_x;
arrow_rect.y += arrow_displacement_y;
}
gtk_paint_arrow(style, drawable, state_type, shadow_type, cliprect,
scrollbar, detail, arrow_type, TRUE, arrow_rect.x,
@ -1578,16 +1661,16 @@ moz_gtk_dropdown_arrow_paint(GdkDrawable* drawable, GdkRectangle* rect,
GdkRectangle* cliprect, GtkWidgetState* state,
gboolean input_focus, GtkTextDirection direction)
{
const gfloat arrow_scaling = 0.7;
gint real_arrow_padding;
GtkBorder inner_border;
gboolean interior_focus;
gint focus_width, focus_pad;
gint x_displacement, y_displacement;
GdkRectangle arrow_rect, real_arrow_rect;
GtkStateType state_type = ConvertGtkState(state);
GtkShadowType shadow_type = state->active ? GTK_SHADOW_IN : GTK_SHADOW_OUT;
GtkStyle* style;
ensure_arrow_widget();
ensure_dropdown_entry_widget();
gtk_widget_set_direction(gDropdownButtonWidget, direction);
ensure_combo_box_entry_widgets();
if (input_focus) {
/* Some themes draw a complementary focus ring for the dropdown button
@ -1603,27 +1686,37 @@ moz_gtk_dropdown_arrow_paint(GdkDrawable* drawable, GdkRectangle* rect,
/* This mirrors gtkbutton's child positioning */
style = gDropdownButtonWidget->style;
arrow_rect.x = rect->x + 1 + XTHICKNESS(style);
arrow_rect.y = rect->y + 1 + YTHICKNESS(style);
arrow_rect.width = MAX(1, rect->width - (arrow_rect.x - rect->x) * 2);
arrow_rect.height = MAX(1, rect->height - (arrow_rect.y - rect->y) * 2);
calculate_arrow_dimensions(&arrow_rect, &real_arrow_rect);
moz_gtk_button_get_inner_border(gDropdownButtonWidget, &inner_border);
moz_gtk_widget_get_focus(gDropdownButtonWidget, &interior_focus,
&focus_width, &focus_pad);
arrow_rect.x = rect->x + XTHICKNESS(style) + focus_width + focus_pad;
arrow_rect.x += direction == GTK_TEXT_DIR_LTR ?
inner_border.left : inner_border.right;
arrow_rect.y = rect->y + inner_border.top + YTHICKNESS(style) +
focus_width + focus_pad;
arrow_rect.width = MAX(1, rect->width - inner_border.left -
inner_border.right - (XTHICKNESS(style) + focus_pad + focus_width) * 2);
arrow_rect.height = MAX(1, rect->height - inner_border.top -
inner_border.bottom - (YTHICKNESS(style) + focus_pad + focus_width) * 2);
if (state_type == GTK_STATE_ACTIVE) {
gtk_widget_style_get(gDropdownButtonWidget,
"child-displacement-x", &x_displacement,
"child-displacement-y", &y_displacement,
NULL);
arrow_rect.x += x_displacement;
arrow_rect.y += y_displacement;
}
calculate_arrow_dimensions(&arrow_rect, &real_arrow_rect, direction);
style = gArrowWidget->style;
TSOffsetStyleGCs(style, real_arrow_rect.x, real_arrow_rect.y);
real_arrow_rect.width = real_arrow_rect.height =
MIN (real_arrow_rect.width, real_arrow_rect.height) * arrow_scaling;
real_arrow_padding = floor((arrow_rect.width - real_arrow_rect.width) / 2 + 0.5);
real_arrow_rect.x = arrow_rect.x + real_arrow_padding;
if (direction == GTK_TEXT_DIR_RTL)
real_arrow_rect.x = arrow_rect.x + arrow_rect.width -
real_arrow_rect.width - real_arrow_padding;
real_arrow_rect.y = floor (arrow_rect.y + ((arrow_rect.height - real_arrow_rect.height) / 2) + 0.5);
gtk_paint_arrow(style, drawable, state_type, shadow_type, cliprect,
gDropdownButtonWidget, "arrow", GTK_ARROW_DOWN, TRUE,
gArrowWidget, "arrow", GTK_ARROW_DOWN, TRUE,
real_arrow_rect.x, real_arrow_rect.y,
real_arrow_rect.width, real_arrow_rect.height);
@ -2405,11 +2498,11 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top,
w = gTreeHeaderSortArrowWidget;
break;
case MOZ_GTK_DROPDOWN_ENTRY:
ensure_dropdown_entry_widget();
ensure_combo_box_entry_widgets();
w = gDropdownEntryWidget;
break;
case MOZ_GTK_DROPDOWN_ARROW:
ensure_arrow_widget();
ensure_combo_box_entry_widgets();
w = gDropdownButtonWidget;
break;
case MOZ_GTK_DROPDOWN:
@ -2578,20 +2671,17 @@ moz_gtk_get_widget_border(GtkThemeWidgetType widget, gint* left, gint* top,
gint
moz_gtk_get_dropdown_arrow_size(gint* width, gint* height)
{
const gint min_arrow_size = 15;
ensure_arrow_widget();
/*
* First get the border of the dropdown arrow, then add in the requested
* size of the arrow. Note that the minimum arrow size is fixed at
* 15 pixels.
*/
* We get the requisition of the drop down button, which includes
* all padding, border and focus line widths the button uses,
* as well as the minimum arrow size and its padding
* */
GtkRequisition requisition;
ensure_combo_box_entry_widgets();
*width = 2 * (1 + XTHICKNESS(gDropdownButtonWidget->style));
*width += min_arrow_size + GTK_MISC(gArrowWidget)->xpad * 2;
*height = 2 * (1 + YTHICKNESS(gDropdownButtonWidget->style));
*height += min_arrow_size + GTK_MISC(gArrowWidget)->ypad * 2;
gtk_widget_size_request(gDropdownButtonWidget, &requisition);
*width = requisition.width;
*height = requisition.height;
return MOZ_GTK_SUCCESS;
}
@ -2829,7 +2919,7 @@ moz_gtk_widget_paint(GtkThemeWidgetType widget, GdkDrawable* drawable,
flags, direction);
break;
case MOZ_GTK_DROPDOWN_ENTRY:
ensure_dropdown_entry_widget();
ensure_combo_box_entry_widgets();
return moz_gtk_entry_paint(drawable, rect, cliprect, state,
gDropdownEntryWidget, direction);
break;

View File

@ -920,8 +920,9 @@ nsNativeThemeGTK::GetWidgetPadding(nsIDeviceContext* aContext,
case NS_THEME_BUTTON_FOCUS:
case NS_THEME_TOOLBAR_BUTTON:
case NS_THEME_TOOLBAR_DUAL_BUTTON:
case NS_THEME_TAB_SCROLLARROW_BACK :
case NS_THEME_TAB_SCROLLARROW_BACK:
case NS_THEME_TAB_SCROLLARROW_FORWARD:
case NS_THEME_DROPDOWN_BUTTON:
// Radios and checkboxes return a fixed size in GetMinimumWidgetSize
// and have a meaningful baseline, so they can't have
// author-specified padding.

View File

@ -277,7 +277,23 @@ NS_IMETHODIMP TimerThread::Run()
// We are going to let the call to PostTimerEvent here handle the
// release of the timer so that we don't end up releasing the timer
// on the TimerThread instead of on the thread it targets.
timer->PostTimerEvent();
if (NS_FAILED(timer->PostTimerEvent())) {
nsrefcnt rc;
NS_RELEASE2(timer, rc);
// The nsITimer interface requires that its users keep a reference
// to the timers they use while those timers are initialized but
// have not yet fired. If this ever happens, it is a bug in the
// code that created and used the timer.
//
// Further, note that this should never happen even with a
// misbehaving user, because nsTimerImpl::Release checks for a
// refcount of 1 with an armed timer (a timer whose only reference
// is from the timer thread) and when it hits this will remove the
// timer from the timer thread and thus destroy the last reference,
// preventing this situation from occurring.
NS_ASSERTION(rc != 0, "destroyed timer off its target thread!");
}
timer = nsnull;
lock.lock();
@ -329,7 +345,7 @@ nsresult TimerThread::AddTimer(nsTimerImpl *aTimer)
// Add the timer to our list.
PRInt32 i = AddTimerInternal(aTimer);
if (i < 0)
return NS_ERROR_FAILURE;
return NS_ERROR_OUT_OF_MEMORY;
// Awaken the timer thread.
if (mCondVar && mWaiting && i == 0)

View File

@ -450,6 +450,7 @@ public:
nsTimerEvent(nsTimerImpl *timer, PRInt32 generation)
: mTimer(timer), mGeneration(generation) {
// timer is already addref'd for us
MOZ_COUNT_CTOR(nsTimerEvent);
}
#ifdef DEBUG_TIMERS
@ -462,6 +463,7 @@ private:
if (mTimer)
NS_WARNING("leaking reference to nsTimerImpl");
#endif
MOZ_COUNT_DTOR(nsTimerEvent);
}
nsTimerImpl *mTimer;
@ -490,7 +492,7 @@ NS_IMETHODIMP nsTimerEvent::Run()
return NS_OK;
}
void nsTimerImpl::PostTimerEvent()
nsresult nsTimerImpl::PostTimerEvent()
{
// XXX we may want to reuse this nsTimerEvent in the case of repeating timers.
@ -499,9 +501,9 @@ void nsTimerImpl::PostTimerEvent()
// from this timer into the event, so we can avoid firing a timer that was
// re-initialized after being canceled.
nsTimerEvent* event = new nsTimerEvent(this, mGeneration);
nsRefPtr<nsTimerEvent> event = new nsTimerEvent(this, mGeneration);
if (!event)
return;
return NS_ERROR_OUT_OF_MEMORY;
#ifdef DEBUG_TIMERS
if (PR_LOG_TEST(gTimerLog, PR_LOG_DEBUG)) {
@ -513,11 +515,17 @@ void nsTimerImpl::PostTimerEvent()
// the next timer to fire before we make the callback.
if (mType == TYPE_REPEATING_PRECISE) {
SetDelayInternal(mDelay);
if (gThread)
gThread->AddTimer(this);
if (gThread) {
nsresult rv = gThread->AddTimer(this);
if (NS_FAILED(rv))
return rv;
}
}
mCallingThread->Dispatch(event, NS_DISPATCH_NORMAL);
nsresult rv = mCallingThread->Dispatch(event, NS_DISPATCH_NORMAL);
if (NS_FAILED(rv) && gThread)
gThread->RemoveTimer(this);
return rv;
}
void nsTimerImpl::SetDelayInternal(PRUint32 aDelay)

View File

@ -44,7 +44,6 @@
//#define FORCE_PR_LOG /* Allow logging in the release build */
#include "nsITimer.h"
#include "nsVoidArray.h"
#include "nsIThread.h"
#include "nsIObserver.h"
@ -96,7 +95,7 @@ public:
friend class TimerThread;
void Fire();
void PostTimerEvent();
nsresult PostTimerEvent();
void SetDelayInternal(PRUint32 aDelay);
NS_DECL_ISUPPORTS