diff --git a/accessible/src/base/nsAccessible.cpp b/accessible/src/base/nsAccessible.cpp index 232f1d461812..1baf5cc8c109 100644 --- a/accessible/src/base/nsAccessible.cpp +++ b/accessible/src/base/nsAccessible.cpp @@ -1639,15 +1639,14 @@ nsresult nsAccessible::AppendFlatStringFromContentNode(nsIContent *aContent, nsA nsresult nsAccessible::AppendFlatStringFromSubtree(nsIContent *aContent, nsAString *aFlatString) { - static nsIContent *startContent = nsnull; - // never run into the same content node, to prevent infinite recursion - if (startContent == aContent) { + static PRBool isAlreadyHere; // Prevent recursion which can cause infinite loops + if (isAlreadyHere) { return NS_OK; } - if (!startContent) { - startContent = aContent; - } + isAlreadyHere = PR_TRUE; nsresult rv = AppendFlatStringFromSubtreeRecurse(aContent, aFlatString); + isAlreadyHere = PR_FALSE; + if (NS_SUCCEEDED(rv) && !aFlatString->IsEmpty()) { nsAString::const_iterator start, end; aFlatString->BeginReading(start); @@ -1661,10 +1660,6 @@ nsresult nsAccessible::AppendFlatStringFromSubtree(nsIContent *aContent, nsAStri aFlatString->Truncate(aFlatString->Length() - spacesToTruncate); } - if (startContent == aContent) { - // we are leaving the original invoking - startContent = nsnull; - } return rv; } diff --git a/accessible/src/base/nsBaseWidgetAccessible.h b/accessible/src/base/nsBaseWidgetAccessible.h index a665acabafd6..6aaca5d437f3 100644 --- a/accessible/src/base/nsBaseWidgetAccessible.h +++ b/accessible/src/base/nsBaseWidgetAccessible.h @@ -64,7 +64,7 @@ public: NS_IMETHOD GetChildCount(PRInt32 *_retval); NS_IMETHOD GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren); NS_IMETHOD GetChildAtPoint(PRInt32 aX, PRInt32 aY, nsIAccessible **aAccessible) - { *aAccessible = this; return NS_OK; } // Don't walk into these + { NS_ENSURE_ARG_POINTER(aAccessible); NS_ADDREF(*aAccessible = this); return NS_OK; } // Don't walk into these }; /** diff --git a/accessible/src/base/nsRootAccessible.cpp b/accessible/src/base/nsRootAccessible.cpp index 8ffd84b6a664..bbc8c9e44e01 100644 --- a/accessible/src/base/nsRootAccessible.cpp +++ b/accessible/src/base/nsRootAccessible.cpp @@ -731,7 +731,7 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent, else #endif if (eventType.EqualsLiteral("focus")) { - if (aTargetNode == mDOMNode) { + if (aTargetNode == mDOMNode && mDOMNode != gLastFocusedNode) { // Got focus event for the window, we will make sure that an accessible // focus event for initial focus is fired. We do this on a short timer // because the initial focus may not have been set yet. @@ -847,8 +847,15 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent, NS_ENSURE_TRUE(containerAccessible, NS_ERROR_FAILURE); // It is not top level menuitem // Only fire focus event if it is not inside collapsed popup - if (State(containerAccessible) & nsIAccessibleStates::STATE_COLLAPSED) - return NS_OK; + // and not a listitem of a combo box + if (State(containerAccessible) & nsIAccessibleStates::STATE_COLLAPSED) { + nsCOMPtr containerParent; + containerAccessible->GetParent(getter_AddRefs(containerParent)); + NS_ENSURE_TRUE(containerParent, NS_ERROR_FAILURE); + if (Role(containerParent) != nsIAccessibleRole::ROLE_COMBOBOX) { + return NS_OK; + } + } } } nsAccEvent::PrepareForEvent(aTargetNode, PR_TRUE); // Always asynch, always from user input diff --git a/accessible/src/html/nsHTMLAreaAccessible.h b/accessible/src/html/nsHTMLAreaAccessible.h index 75291dede5e5..9b5aa97f27e6 100644 --- a/accessible/src/html/nsHTMLAreaAccessible.h +++ b/accessible/src/html/nsHTMLAreaAccessible.h @@ -57,7 +57,7 @@ public: NS_IMETHOD GetDescription(nsAString& _retval); NS_IMETHOD GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height); NS_IMETHOD GetChildAtPoint(PRInt32 aX, PRInt32 aY, nsIAccessible **aAccessible) - { *aAccessible = this; return NS_OK; } // Don't walk into these + { NS_ENSURE_ARG_POINTER(aAccessible); NS_ADDREF(*aAccessible = this); return NS_OK; } // Don't walk into these }; #endif diff --git a/accessible/src/html/nsHTMLTableAccessible.cpp b/accessible/src/html/nsHTMLTableAccessible.cpp index f284d35c6ff0..571c88a90563 100644 --- a/accessible/src/html/nsHTMLTableAccessible.cpp +++ b/accessible/src/html/nsHTMLTableAccessible.cpp @@ -849,7 +849,10 @@ nsHTMLTableAccessible::GetTableLayout(nsITableLayout **aLayoutObject) nsCOMPtr content(do_QueryInterface(tableNode)); NS_ENSURE_TRUE(content, NS_ERROR_FAILURE); - nsIPresShell *presShell = content->GetDocument()->GetPrimaryShell(); + nsIDocument *doc = content->GetDocument(); + NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE); + + nsIPresShell *presShell = doc->GetPrimaryShell(); nsCOMPtr layoutObject; rv = presShell->GetLayoutObjectFor(content, getter_AddRefs(layoutObject)); diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index 74664ba19b2d..7c7b1682e421 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -200,8 +200,6 @@ pref("browser.urlbar.doubleClickSelectsAll", false); #endif pref("browser.urlbar.autoFill", false); pref("browser.urlbar.matchOnlyTyped", false); -pref("browser.urlbar.hideProtocols", ""); -pref("browser.urlbar.animateBlend", true); pref("browser.download.useDownloadDir", true); pref("browser.download.folderList", 0); @@ -380,7 +378,7 @@ pref("mousewheel.withmetakey.action",0); pref("mousewheel.withmetakey.sysnumlines",true); pref("mousewheel.withmetakey.numlines",1); #endif -pref("mousewheel.withcontrolkey.action",3); +pref("mousewheel.withcontrolkey.action",5); pref("mousewheel.withcontrolkey.sysnumlines",false); pref("mousewheel.withcontrolkey.numlines",1); @@ -443,11 +441,7 @@ pref("browser.preferences.instantApply", false); #else pref("browser.preferences.instantApply", true); #endif -#ifdef XP_MACOSX -pref("browser.preferences.animateFadeIn", true); -#else pref("browser.preferences.animateFadeIn", false); -#endif pref("browser.download.show_plugins_in_list", true); pref("browser.download.hide_plugins_without_extensions", true); @@ -545,6 +539,10 @@ pref("browser.safebrowsing.provider.0.reportPhishURL", "http://{moz:locale}.phis // FAQ URL pref("browser.safebrowsing.warning.infoURL", "http://%LOCALE%.www.mozilla.com/%LOCALE%/firefox/phishing-protection/"); + +// Name of the about: page contributed by safebrowsing to handle display of error +// pages on phishing/malware hits. (bug 399233) +pref("urlclassifier.alternate_error_page", "blocked"); #endif // defaults to true @@ -574,8 +572,5 @@ pref("accessibility.blockautorefresh", false); // import bookmarks.html into Places bookmarks pref("browser.places.importBookmarksHTML", true); -// Show infobar on chromeless windows -pref("browser.warn_chromeless_window.infobar", false); - // if false, will add the "Places" folder to the personal toolbar pref("browser.places.createdDefaultQueries", false); diff --git a/browser/base/content/aboutDialog.css b/browser/base/content/aboutDialog.css index 2b21b16bb4fe..f0fd9c76b4a9 100644 --- a/browser/base/content/aboutDialog.css +++ b/browser/base/content/aboutDialog.css @@ -1,5 +1,8 @@ #aboutDialog { - padding: 0px 0px 10px 0px; + padding-top: 0; + -moz-padding-end: 0; + padding-bottom: 10px; + -moz-padding-start: 0; width: 299px; } @@ -20,53 +23,71 @@ } #userAgent { - margin: 11px 20px 0px 13px; + margin-top: 11px; + -moz-margin-end: 20px; + margin-bottom: 0; + -moz-margin-start: 13px; background-color: #FFFFFF; color: #000000; - padding: 1px 0px 0px 3px; + padding-top: 1px; + -moz-padding-end: 0; + padding-bottom: 0; + -moz-padding-start: 3px; -moz-appearance: none; overflow: hidden; - border: 0px; + border: 0; } #groove { - margin-top: 0px; + margin-top: 0; } #creditsIframe { cursor: default; -moz-user-select: none; - border: 0px; + border: 0; } #version { font-weight: bold; color: #909090; - margin: 1em 0px 10px 17px; + margin-top: 1em; + -moz-margin-end: 0; + margin-bottom: 10px; + -moz-margin-start: 17px; } #distribution { font-weight: bold; color: #909090; display: none; - margin: 0em 0px 0px 17px; + margin-top: 0; + -moz-margin-end: 0; + margin-bottom: 0; + -moz-margin-start: 17px; } #distributionId { font-weight: bold; color: #909090; display: none; - margin: 0em 0px 10px 17px; + margin-top: 0; + -moz-margin-end: 0; + margin-bottom: 10px; + -moz-margin-start: 17px; } #copyright { - margin: 0px 0px 3px 16px; + margin-top: 0; + -moz-margin-end: 0; + margin-bottom: 3px; + -moz-margin-start: 16px; } button[dlgtype="extra2"] { - margin-left: 13px; + -moz-margin-start: 13px; } button[dlgtype="accept"] { - margin-right: 13px; + -moz-margin-end: 13px; } diff --git a/browser/base/content/browser-menubar.inc b/browser/base/content/browser-menubar.inc index a238208904a7..54f8c198d471 100644 --- a/browser/base/content/browser-menubar.inc +++ b/browser/base/content/browser-menubar.inc @@ -171,15 +171,15 @@ #endif - - - - + + + + - + diff --git a/browser/base/content/browser-places.js b/browser/base/content/browser-places.js index 3444c01472da..8e9671d12cd1 100644 --- a/browser/base/content/browser-places.js +++ b/browser/base/content/browser-places.js @@ -50,7 +50,11 @@ var PlacesCommandHook = { // Edit-bookmark panel get panel() { - return document.getElementById("editBookmarkPanel"); + delete this.panel; + var element = document.getElementById("editBookmarkPanel"); + element.addEventListener("popuphiding", this, false); + element.addEventListener("keypress", this, true); + return this.panel = element; }, // list of command elements (by id) to disable when the panel is opened @@ -129,13 +133,15 @@ var PlacesCommandHook = { this._overlayLoading = true; document.loadOverlay("chrome://browser/content/places/editBookmarkOverlay.xul", loadObserver); - this.panel.addEventListener("popuphiding", this, false); }, _doShowEditBookmarkPanel: function PCH__doShowEditBookmarkPanel(aItemId, aAnchorElement, aPosition) { - this.panel.addEventListener("keypress", this, true); this._blockCommands(); // un-done in the popuphiding handler + + // Consume dismiss clicks, see bug 400924 + this.panel.popupBoxObject + .setConsumeRollupEvent(Ci.nsIPopupBoxObject.ROLLUP_CONSUME); this.panel.openPopup(aAnchorElement, aPosition, -1, -1); gEditItemOverlay.initPanel(aItemId, @@ -405,7 +411,7 @@ var BookmarksEventHandler = { node.localName == "menupopup")) { if (node.localName == "menupopup") node.hidePopup(); - + node = node.parentNode; } } @@ -415,9 +421,9 @@ var BookmarksEventHandler = { // separately. var bookmarksBar = document.getElementById("bookmarksBarContent"); if (bookmarksBar._chevron.getAttribute("open") == "true") - bookmarksBar._chevron.firstChild.hidePopupAndChildPopups(); + bookmarksBar._chevron.firstChild.hidePopup(); }, - + /** * Handler for command event for an item in the bookmarks toolbar. * Menus and submenus from the folder buttons bubble up to this handler. @@ -426,17 +432,12 @@ var BookmarksEventHandler = { * DOMEvent for the command */ onCommand: function BM_onCommand(aEvent) { - // If this is the special "Open All in Tabs" menuitem, - // load all the menuitems in tabs. - var target = aEvent.originalTarget; - if (target.hasAttribute("siteURI")) - openUILink(target.getAttribute("siteURI"), aEvent); - // If this is a normal bookmark, just load the bookmark's URI. - else if (!target.hasAttribute("openInTabs")) + if (target.node) { PlacesUtils.getViewForNode(target) .controller .openSelectedNodeWithEvent(aEvent); + } }, /** @@ -456,7 +457,6 @@ var BookmarksEventHandler = { // Add the "Open (Feed Name)" menuitem if it's a livemark with a siteURI. var numNodes = 0; var hasMultipleEntries = false; - var hasFeedHomePage = false; var currentChild = target.firstChild; while (currentChild) { if (currentChild.localName == "menuitem" && currentChild.node) @@ -473,32 +473,35 @@ var BookmarksEventHandler = { if (numNodes > 1) hasMultipleEntries = true; - var button = target.parentNode; - if (button.getAttribute("livemark") == "true" && - button.hasAttribute("siteURI")) - hasFeedHomePage = true; + var itemId = target._resultNode.itemId; + var siteURIString = ""; + if (itemId != -1 && PlacesUtils.livemarks.isLivemark(itemId)) { + var siteURI = PlacesUtils.livemarks.getSiteURI(itemId); + if (siteURI) + siteURIString = siteURI.spec; + } - if (hasMultipleEntries || hasFeedHomePage) { + if (hasMultipleEntries || siteURIString) { var separator = document.createElement("menuseparator"); target.appendChild(separator); - if (hasFeedHomePage) { + if (siteURIString) { var openHomePage = document.createElement("menuitem"); - openHomePage.setAttribute( - "siteURI", button.getAttribute("siteURI")); + openHomePage.setAttribute("siteURI", siteURIString); + openHomePage.setAttribute("oncommand", + "openUILink(this.getAttribute('siteURI'), event);"); openHomePage.setAttribute( "label", PlacesUtils.getFormattedString("menuOpenLivemarkOrigin.label", - [button.getAttribute("label")])); + [target.parentNode.getAttribute("label")])); target.appendChild(openHomePage); } if (hasMultipleEntries) { var openInTabs = document.createElement("menuitem"); openInTabs.setAttribute("openInTabs", "true"); - openInTabs.setAttribute("onclick", "checkForMiddleClick(this, event)"); openInTabs.setAttribute("oncommand", - "PlacesUtils.openContainerNodeInTabs(this.parentNode.getResultNode(), event);"); + "PlacesUtils.openContainerNodeInTabs(this.parentNode._resultNode, event);"); openInTabs.setAttribute("label", gNavigatorBundle.getString("menuOpenAllInTabs.label")); target.appendChild(openInTabs); @@ -703,19 +706,19 @@ var PlacesMenuDNDController = { // Close the bookmarks menu var bookmarksMenu = document.getElementById("bookmarksMenu"); - bookmarksMenu.firstChild.hidePopupAndChildPopups(); + bookmarksMenu.firstChild.hidePopup(); var bookmarksBar = document.getElementById("bookmarksBarContent"); if (bookmarksBar) { // Close the overflow chevron menu and all its children - bookmarksBar._chevron.firstChild.hidePopupAndChildPopups(); + bookmarksBar._chevron.firstChild.hidePopup(); // Close all popups on the bookmarks toolbar var toolbarItems = bookmarksBar.childNodes; for (var i = 0; i < toolbarItems.length; ++i) { var item = toolbarItems[i] if (this._isContainer(item)) - item.firstChild.hidePopupAndChildPopups(); + item.firstChild.hidePopup(); } } }, diff --git a/browser/base/content/browser-sets.inc b/browser/base/content/browser-sets.inc index b76b8f861072..9066f494aae1 100644 --- a/browser/base/content/browser-sets.inc +++ b/browser/base/content/browser-sets.inc @@ -101,9 +101,9 @@ - - - + + + @@ -286,10 +286,10 @@ #endif command="viewHistorySidebar"/> - - - - + + + + diff --git a/browser/base/content/browser-textZoom.js b/browser/base/content/browser-textZoom.js index 72bd44ab805a..1d41e284c715 100755 --- a/browser/base/content/browser-textZoom.js +++ b/browser/base/content/browser-textZoom.js @@ -21,6 +21,7 @@ * * Contributor(s): * Myk Melez + * Dão Gottwald * * 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 @@ -41,58 +42,35 @@ // From nsMouseScrollEvent::kIsHorizontal const MOUSE_SCROLL_IS_HORIZONTAL = 1 << 2; -// Not sure where this comes from. It's one of the possible values -// for the mousewheel.* preferences. -const MOUSE_SCROLL_TEXTSIZE = 3; +// One of the possible values for the mousewheel.* preferences. +// From nsEventStateManager.cpp. +const MOUSE_SCROLL_FULLZOOM = 5; /** - * Controls the "text zoom" setting and its site-specific preferences. + * Controls the "full zoom" setting and its site-specific preferences. */ -var TextZoom = { +var FullZoom = { //**************************************************************************// // Name & Values // The name of the setting. Identifies the setting in the prefs database. - name: "browser.content.text-zoom", + name: "browser.content.full-zoom", // The global value (if any) for the setting. Retrieved from the prefs // database when this handler gets initialized, then updated as it changes. // If there is no global value, then this should be undefined. globalValue: undefined, - // From viewZoomOverlay.js - minValue: 1, - maxValue: 2000, - defaultValue: 100, - //**************************************************************************// // Convenience Getters - __zoomManager: null, - get _zoomManager() { - if (!this.__zoomManager) - this.__zoomManager = ZoomManager.prototype.getInstance(); - return this.__zoomManager; - }, - // Content Pref Service - __cps: null, get _cps() { - if (!this.__cps) - this.__cps = Cc["@mozilla.org/content-pref/service;1"]. - getService(Ci.nsIContentPrefService); - return this.__cps; - }, - - // Pref Branch - __prefBranch: null, - get _prefBranch() { - if (!this.__prefBranch) - this.__prefBranch = Cc["@mozilla.org/preferences-service;1"]. - getService(Ci.nsIPrefBranch); - return this.__prefBranch; + delete this._cps; + return this._cps = Cc["@mozilla.org/content-pref/service;1"]. + getService(Ci.nsIContentPrefService); }, @@ -104,8 +82,8 @@ var TextZoom = { Components.interfaces.nsIContentPrefObserver, Components.interfaces.nsISupports], - QueryInterface: function TextZoom_QueryInterface(aIID) { - if (!this.interfaces.some( function(v) { return aIID.equals(v) } )) + QueryInterface: function (aIID) { + if (!this.interfaces.some(function (v) aIID.equals(v))) throw Cr.NS_ERROR_NO_INTERFACE; return this; }, @@ -114,7 +92,7 @@ var TextZoom = { //**************************************************************************// // Initialization & Destruction - init: function TextZoom_init() { + init: function () { // Listen for scrollwheel events so we can save scrollwheel-based changes. window.addEventListener("DOMMouseScroll", this, false); @@ -129,7 +107,7 @@ var TextZoom = { this._applyPrefToSetting(); }, - destroy: function TextZoom_destroy() { + destroy: function () { ContentPrefSink.removeObserver(this.name, this); this._cps.removeObserver(this.name, this); window.removeEventListener("DOMMouseScroll", this, false); @@ -149,12 +127,15 @@ var TextZoom = { // nsIDOMEventListener - handleEvent: function TextZoom_handleEvent(event) { - // The only events we handle are DOMMouseScroll events. - this._handleMouseScrolled(event); + handleEvent: function (event) { + switch (event.type) { + case "DOMMouseScroll": + this._handleMouseScrolled(event); + break; + } }, - _handleMouseScrolled: function TextZoom__handleMouseScrolled(event) { + _handleMouseScrolled: function (event) { // Construct the "mousewheel action" pref key corresponding to this event. // Based on nsEventStateManager::GetBasePrefKeyForMouseWheel. var pref = "mousewheel"; @@ -174,8 +155,12 @@ var TextZoom = { pref += ".action"; - // Don't do anything if this isn't a "change text size" scroll event. - if (this._getAppPref(pref, null) != MOUSE_SCROLL_TEXTSIZE) + // Don't do anything if this isn't a "zoom" scroll event. + var isZoomEvent = false; + try { + isZoomEvent = (gPrefService.getIntPref(pref) == MOUSE_SCROLL_FULLZOOM); + } catch (e) {} + if (!isZoomEvent) return; // XXX Lazily cache all the possible action prefs so we don't have to get @@ -185,12 +170,12 @@ var TextZoom = { // We have to call _applySettingToPref in a timeout because we handle // the event before the event state manager has a chance to apply the zoom // during nsEventStateManager::PostHandleEvent. - window.setTimeout(function() { TextZoom._applySettingToPref() }, 0); + window.setTimeout(function (self) { self._applySettingToPref() }, 0, this); }, // nsIContentPrefObserver - onContentPrefSet: function TextZoom_onContentPrefSet(aGroup, aName, aValue) { + onContentPrefSet: function (aGroup, aName, aValue) { if (aGroup == this._cps.grouper.group(gBrowser.currentURI)) this._applyPrefToSetting(aValue); else if (aGroup == null) { @@ -204,7 +189,7 @@ var TextZoom = { } }, - onContentPrefRemoved: function TextZoom_onContentPrefRemoved(aGroup, aName) { + onContentPrefRemoved: function (aGroup, aName) { if (aGroup == this._cps.grouper.group(gBrowser.currentURI)) this._applyPrefToSetting(); else if (aGroup == null) { @@ -220,7 +205,7 @@ var TextZoom = { // ContentPrefSink observer - onLocationChanged: function TextZoom_onLocationChanged(aURI, aName, aValue) { + onLocationChanged: function (aURI, aName, aValue) { this._applyPrefToSetting(aValue); }, @@ -228,35 +213,35 @@ var TextZoom = { //**************************************************************************// // Setting & Pref Manipulation - reduce: function TextZoom_reduce() { - this._zoomManager.reduce(); + reduce: function () { + ZoomManager.reduce(); this._applySettingToPref(); }, - enlarge: function TextZoom_enlarge() { - this._zoomManager.enlarge(); + enlarge: function () { + ZoomManager.enlarge(); this._applySettingToPref(); }, - reset: function TextZoom_reset() { + reset: function () { if (typeof this.globalValue != "undefined") - this._zoomManager.textZoom = this.globalValue; + ZoomManager.fullZoom = this.globalValue; else - this._zoomManager.reset(); + ZoomManager.reset(); this._removePref(); }, /** - * Set the text zoom for the current tab. + * Set the zoom level for the current tab. * - * Per DocumentViewerImpl::SetTextZoom in nsDocumentViewer.cpp, it looks + * Per DocumentViewerImpl::SetFullZoom in nsDocumentViewer.cpp, it looks * like we can set the zoom to its current value without significant impact * on performance, as the setting is only applied if it differs from the * current setting. * * And perhaps we should always set the zoom even if it were to incur - * a performance penalty, since SetTextZoom claims that child documents + * a performance penalty, since SetFullZoom claims that child documents * may have a different zoom under unusual circumstances, and it implies * that those child zooms should get updated when the parent zoom gets set. * @@ -264,26 +249,26 @@ var TextZoom = { * We don't check first to see if the new value is the same as the current * one. **/ - _applyPrefToSetting: function TextZoom__applyPrefToSetting(aValue) { + _applyPrefToSetting: function (aValue) { // Bug 375918 means this will sometimes throw, so we catch it // and don't do anything in those cases. try { if (typeof aValue != "undefined") - this._zoomManager.textZoom = this._ensureValid(aValue); + ZoomManager.fullZoom = this._ensureValid(aValue); else if (typeof this.globalValue != "undefined") - this._zoomManager.textZoom = this.globalValue; + ZoomManager.fullZoom = this.globalValue; else - this._zoomManager.reset(); + ZoomManager.reset(); } catch(ex) {} }, - _applySettingToPref: function TextZoom__applySettingToPref() { - var textZoom = this._zoomManager.textZoom; - this._cps.setPref(gBrowser.currentURI, this.name, textZoom); + _applySettingToPref: function () { + var fullZoom = ZoomManager.fullZoom; + this._cps.setPref(gBrowser.currentURI, this.name, fullZoom); }, - _removePref: function TextZoom__removePref() { + _removePref: function () { this._cps.removePref(gBrowser.currentURI, this.name); }, @@ -291,41 +276,16 @@ var TextZoom = { //**************************************************************************// // Utilities - _ensureValid: function TextZoom__ensureValid(aValue) { + _ensureValid: function (aValue) { if (isNaN(aValue)) - return this.defaultValue; + return 1; - if (aValue < this.minValue) - return this.minValue; + if (aValue < ZoomManager.MIN) + return ZoomManager.MIN; - if (aValue > this.maxValue) - return this.maxValue; + if (aValue > ZoomManager.MAX) + return ZoomManager.MAX; return aValue; - }, - - /** - * Get a value from a pref or a default value if the pref doesn't exist. - * - * @param aPrefName - * @param aDefaultValue - * @returns the pref's value or the default (if it is missing) - */ - _getAppPref: function TextZoom__getAppPref(aPrefName, aDefaultValue) { - try { - switch (this._prefBranch.getPrefType(aPrefName)) { - case this._prefBranch.PREF_STRING: - return this._prefBranch.getCharPref(aPrefName); - - case this._prefBranch.PREF_BOOL: - return this._prefBranch.getBoolPref(aPrefName); - - case this._prefBranch.PREF_INT: - return this._prefBranch.getIntPref(aPrefName); - } - } - catch (ex) { /* return the default value */ } - - return aDefaultValue; } }; diff --git a/browser/base/content/browser.js b/browser/base/content/browser.js index 33d96a2564c8..81c59d09375b 100644 --- a/browser/base/content/browser.js +++ b/browser/base/content/browser.js @@ -362,7 +362,7 @@ function initPlacesDefaultQueries() { var recentlyCreatedBookmarksItem = bmsvc.insertBookmark(placesFolder, IO.newURI("place:folder=" + bookmarksRoot + "&folder=" + unfiledRoot + "&queryType=" + Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS + - "&sort=" + + "&sort=" + Ci.nsINavHistoryQueryOptions.SORT_BY_DATEADDED_DESCENDING + "&excludeItemIfParentHasAnnotation=livemark%2FfeedURI" + "&maxResults=" + maxResults + @@ -372,15 +372,17 @@ function initPlacesDefaultQueries() { var recentlyVisitedBookmarksItem = bmsvc.insertBookmark(placesFolder, IO.newURI("place:folder=" + bookmarksRoot + "&folder=" + unfiledRoot + "&queryType=" + Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS + - "&sort=" + Ci.nsINavHistoryQueryOptions.SORT_BY_DATE_DESCENDING + + "&sort=" + Ci.nsINavHistoryQueryOptions.SORT_BY_DATE_DESCENDING + + "&excludeItemIfParentHasAnnotation=livemark%2FfeedURI" + "&minVisits=1&maxResults=" + maxResults), defaultIndex, recentlyVisitedBookmarksTitle); var mostVisitedBookmarksItem = bmsvc.insertBookmark(placesFolder, IO.newURI("place:folder=" + bookmarksRoot + "&folder=" + unfiledRoot + "&queryType=" + Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS + - "&sort=" + - Ci.nsINavHistoryQueryOptions.SORT_BY_VISITCOUNT_DESCENDING + + "&sort=" + + Ci.nsINavHistoryQueryOptions.SORT_BY_VISITCOUNT_DESCENDING + + "&excludeItemIfParentHasAnnotation=livemark%2FfeedURI" + "&minVisits=1&maxResults=" + maxResults), defaultIndex, mostVisitedBookmarksTitle); @@ -388,28 +390,28 @@ function initPlacesDefaultQueries() { IO.newURI("place:folder=" + tagRoot + "&group=" + Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER + "&queryType=" + Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS + - "&applyOptionsToContainers=1" + - "&sort=" + - Ci.nsINavHistoryQueryOptions.SORT_BY_DATEADDED_DESCENDING + + "&applyOptionsToContainers=1" + + "&sort=" + + Ci.nsINavHistoryQueryOptions.SORT_BY_DATEADDED_DESCENDING + "&resolveNullBookmarkTitles=1" + "&maxResults=" + maxResults), defaultIndex, recentlyUsedTagsTitle); var mostUsedTagsItem = bmsvc.insertBookmark(placesFolder, - IO.newURI("place:folder=" + tagRoot + + IO.newURI("place:folder=" + tagRoot + "&group=" + Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER + "&queryType=" + Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS + "&applyOptionsToContainers=1" + - "&sort=" + Ci.nsINavHistoryQueryOptions.SORT_BY_COUNT_DESCENDING + + "&sort=" + Ci.nsINavHistoryQueryOptions.SORT_BY_COUNT_DESCENDING + "&resolveNullBookmarkTitles=1" + "&maxResults=" + maxResults), defaultIndex, mostUsedTagsTitle); var mostVisitedSitesItem = bmsvc.insertBookmark(placesFolder, - IO.newURI("place:queryType=" + + IO.newURI("place:queryType=" + Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY + - "&sort=" + - Ci.nsINavHistoryQueryOptions.SORT_BY_VISITCOUNT_DESCENDING + + "&sort=" + + Ci.nsINavHistoryQueryOptions.SORT_BY_VISITCOUNT_DESCENDING + "&maxResults=" + maxResults), defaultIndex, mostVisitedSitesTitle); } @@ -1164,7 +1166,7 @@ function delayedStartup() // apply text zoom settings to tabs restored by the session restore service. try { ContentPrefSink.init(); - TextZoom.init(); + FullZoom.init(); } catch(ex) { Components.utils.reportError("Failed to init content pref service:\n" + ex); @@ -1202,16 +1204,12 @@ function delayedStartup() // bookmark-all-tabs command gBookmarkAllTabsHandler = new BookmarkAllTabsHandler(); - - // Prevent chrome-spoofing popups from forging our chrome, by adding a - // notification box entry in cases of chromeless popups. - checkForChromelessWindow(); } function BrowserShutdown() { try { - TextZoom.destroy(); + FullZoom.destroy(); ContentPrefSink.destroy(); } catch(ex) { @@ -1288,7 +1286,7 @@ function nonBrowserWindowStartup() var disabledItems = ['cmd_newNavigatorTab', 'Browser:SavePage', 'Browser:SendLink', 'cmd_pageSetup', 'cmd_print', 'cmd_find', 'cmd_findAgain', 'viewToolbarsMenu', 'cmd_toggleTaskbar', 'viewSidebarMenuMenu', 'Browser:Reload', 'Browser:ReloadSkipCache', - 'viewTextZoomMenu', 'pageStyleMenu', 'charsetMenu', 'View:PageSource', 'View:FullScreen', + 'viewFullZoomMenu', 'pageStyleMenu', 'charsetMenu', 'View:PageSource', 'View:FullScreen', 'viewHistorySidebar', 'Browser:AddBookmarkAs', 'View:PageInfo', 'Tasks:InspectPage']; var element; @@ -2233,6 +2231,16 @@ function PageProxyClickHandler(aEvent) return true; } +function URLBarOnInput(evt) +{ + gBrowser.userTypedValue = gURLBar.value; + + // If the user is interacting with the url bar, get rid of the identity popup + var ih = getIdentityHandler(); + if(ih._identityPopup) + ih._identityPopup.hidePopup(); +} + function URLBarOnDragOver(evt) { nsDragAndDrop.dragOver(evt, urlbarObserver); @@ -3848,6 +3856,7 @@ nsBrowserStatusHandler.prototype = this.securityButton.removeAttribute("label"); this.securityButton.setAttribute("tooltiptext", this._tooltipText); + getIdentityHandler().checkIdentity(this._state, this._host); }, // simulate all change notifications after switching tabs @@ -3942,6 +3951,10 @@ nsBrowserAccess.prototype = return null; } + if (!gPrefService) + gPrefService = Components.classes["@mozilla.org/preferences-service;1"] + .getService(Components.interfaces.nsIPrefBranch2); + var loadflags = isExternal ? Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL : Ci.nsIWebNavigation.LOAD_FLAGS_NONE; @@ -3977,6 +3990,8 @@ nsBrowserAccess.prototype = newWindow.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIWebNavigation) .loadURI(url, loadflags, referrer, null, null); + if (!loadInBackground && isExternal) + newWindow.focus(); } catch(e) { } break; @@ -5576,87 +5591,6 @@ BookmarkAllTabsHandler.prototype = { } }; - -/** - * Check the chromehidden attribute to see if the toolbar is hidden. If so, - * and if they haven't disabled the security.warn_chromeless_window.infobar - * pref, show an infobar notification informing them of what's going on. This - * helps fight chrome spoofing on popups. See bug 337344 - */ -function checkForChromelessWindow() { - - var prefs = Components.classes["@mozilla.org/preferences-service;1"] - .getService(Components.interfaces.nsIPrefBranch); - - // true by default - if (!prefs.getBoolPref("browser.warn_chromeless_window.infobar")) - return; - - if (document.documentElement.getAttribute("chromehidden").indexOf("toolbar") != -1 || - document.documentElement.getAttribute("chromehidden").indexOf("location") != -1) { - - var bundle_browser = document.getElementById("bundle_browser"); - - // It's possible that something in the window.content.opener.location.path - // chain might be null. Rather than chaining a ton of 99% pass null checks, - // though, let's try/catch in order to fail gracefully - try { - var messageString = bundle_browser.getFormattedString("chromelessWindow.warningMessage", - [window.content.opener.location.host]); - } catch (ex) { - - // An exception here is not worth breaking our security warning, but is worth - // logging, since it shouldn't happen. - Components.utils.reportError(ex); - messageString = bundle_browser.getString("chromelessWindow.warningNoLocation"); - - } - - var notificationBox = gBrowser.getNotificationBox(); - var notificationName = "chromeless-info"; - if (notificationBox.getNotificationWithValue(notificationName)) { - Components.utils.reportError("Already have a chromeless-info notification!") - return; - } - - var buttons = [{ - label: bundle_browser.getString("chromelessWindow.showToolbarsButton"), - accessKey: bundle_browser.getString("chromelessWindow.accessKey"), - popup: null, - callback: function() { return showToolbars(); } - }]; - - notificationBox.appendNotification(messageString, - notificationName, - "chrome://browser/skin/Info.png", - notificationBox.PRIORITY_INFO_HIGH, - buttons); - } -} - -/** - * Callback for "Show Toolbars" button in chromeless window notification box. - * Resets visibility of the go button stack and url bar, and wipes the - * chromehidden document attribute. - */ -function showToolbars() { - - // Unhide the chrome elements - document.documentElement.removeAttribute("chromehidden"); - - // Undo the URLBar tweaks performed when the url bar was chromehidden - if (gURLBar) { - gURLBar.removeAttribute("readonly"); - gURLBar.setAttribute("enablehistory", "true"); - } - - var goButtonStack = document.getElementById("go-button-stack"); - if (goButtonStack) - goButtonStack.removeAttribute("hidden"); - - return false; // Dismiss the notification message -} - /** * Utility class to handle manipulations of the identity indicators in the UI */ @@ -5696,7 +5630,7 @@ IdentityHandler.prototype = { // Cache the most recently seen SSLStatus and URI to prevent unnecessary updates _lastStatus : null, - _lastURI : null, + _lastHost : null, /** * Handler for mouseclicks on the "Tell me more about this website" link text @@ -5744,27 +5678,17 @@ IdentityHandler.prototype = { /** * Determine the identity of the page being displayed by examining its SSL cert * (if available) and, if necessary, update the UI to reflect this. Intended to - * be called by an nsIWebProgressListener. - * - * @param nsIWebProgress webProgress - * @param nsIRequest request + * be called by onSecurityChange + * * @param PRUint32 state + * @param AUTF8String host */ - checkIdentity : function(state) { - var currentURI = gBrowser.currentURI; - if (currentURI.schemeIs("http") && this._lastURI.schemeIs("http")) - return; - + checkIdentity : function(state, host) { var currentStatus = gBrowser.securityUI .QueryInterface(Components.interfaces.nsISSLStatusProvider) .SSLStatus; - if (currentStatus == this._lastStatus && currentURI == this._lastURI) { - // No need to update, this is a no-op check - return; - } - this._lastStatus = currentStatus; - this._lastURI = currentURI; + this._lastHost = host; if (state & Components.interfaces.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL) this.setMode(this.IDENTITY_MODE_IDENTIFIED); @@ -5802,7 +5726,7 @@ IdentityHandler.prototype = { // it's not the only place you have to check, there can be more than one domain, // et cetera, ad nauseum. We know the cert is valid for location.host, so // let's just use that, it's what the status bar does too. - var icon_label = this._lastURI.host; + var icon_label = this._lastHost; var tooltip = this._stringBundle.getFormattedString("identity.identified.verifier", [iData.caOrg]); } @@ -5850,7 +5774,7 @@ IdentityHandler.prototype = { if (newMode == this.IDENTITY_MODE_DOMAIN_VERIFIED) { var iData = this.getIdentityData(); - var body = this._lastURI.host; + var body = this._lastHost; verifier = this._stringBundle.getFormattedString("identity.identified.verifier", [iData.caOrg]); supplemental = this._stringBundle.getString("identity.domainverified.supplemental"); @@ -5897,6 +5821,10 @@ IdentityHandler.prototype = { // the popup is actually needed this._identityPopup.hidden = false; + // Tell the popup to consume dismiss clicks, to avoid bug 395314 + this._identityPopup.popupBoxObject + .setConsumeRollupEvent(Ci.nsIPopupBoxObject.ROLLUP_CONSUME); + // Update the popup strings this.setPopupMessages(this._identityBox.className); diff --git a/browser/base/content/browser.xul b/browser/base/content/browser.xul index c50e80ab16c9..117dbedeaf3c 100644 --- a/browser/base/content/browser.xul +++ b/browser/base/content/browser.xul @@ -28,6 +28,7 @@ # Joe Hewitt # Pierre Chanial # Dean Tessman +# Johnathan Nightingale # # 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 @@ -57,7 +58,7 @@ # All DTD information is stored in a separate file so that it can be shared by # hiddenWindow.xul. #include browser-doctype.inc - + + + + @@ -146,7 +175,7 @@ - + @@ -183,7 +212,7 @@ oncommand="gotoHistoryIndex(event); event.stopPropagation();" onclick="checkForMiddleClick(this, event);"/> - + - + - + - - - - + + + + + + + - #ifdef MOZ_SAFE_BROWSING - + ondragexit="nsDragAndDrop.dragExit(event, newTabButtonObserver);"/> #endif - + - - + - + + - + diff --git a/browser/base/content/pageinfo/pageInfo.xul b/browser/base/content/pageinfo/pageInfo.xul index 15aaa55f1448..56c3cbe512d3 100644 --- a/browser/base/content/pageinfo/pageInfo.xul +++ b/browser/base/content/pageinfo/pageInfo.xul @@ -59,7 +59,7 @@ windowtype="Browser:page-info" onload="onLoadPageInfo()" onunload="onUnloadPageInfo()" - xmlns:xhtml="http://www.w3.org/1999/xhtml"> + xmlns:xhtml="http://www.w3.org/1999/xhtml" align="stretch" screenX="10" screenY="10" width="&pageInfoWindow.width;" height="&pageInfoWindow.height;" diff --git a/browser/base/content/tabbrowser.xml b/browser/base/content/tabbrowser.xml index 1e3bd36b8d3b..6cf9302c1f20 100644 --- a/browser/base/content/tabbrowser.xml +++ b/browser/base/content/tabbrowser.xml @@ -1699,22 +1699,26 @@ diff --git a/browser/base/content/urlbarBindings.xml b/browser/base/content/urlbarBindings.xml index c576c23ed579..3d0ea89bc15b 100644 --- a/browser/base/content/urlbarBindings.xml +++ b/browser/base/content/urlbarBindings.xml @@ -38,54 +38,9 @@ # # ***** END LICENSE BLOCK ***** - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -1; - - var host = this._uri.host; - if (host) { - var subdomain; - var port = (this._uri.port > -1) ? ":" + this._uri.port : ""; - if (this._uri.hostPort[0] == "[") { - // IPv6 address - subdomain = "["; - port = "]" + port; - } - else if (0 && !/^[.0-9]+$/.test(host)) { - //XXX subdomain detection disabled (bug 386727) - //XXX subdomain detection disabled for IP addresses (bug 364129) - - // getEffectiveTLDLength might convert our host and return a misleading length. - // To avoid this, pass the ASCII host, count the dots of its effective TLD - // and use that number to operate on our actual host. - - var asciiHost = this._uri.asciiHost; - var domainSegments = host.split("."); - var cSubdomain = domainSegments.length - - asciiHost.slice(asciiHost.length - - this.tldService.getEffectiveTLDLength(asciiHost)) - .split(".").length - 1; - if (cSubdomain > 0) { - host = domainSegments; - subdomain = host.splice(0, cSubdomain).join(".") + "."; - host = host.join("."); - } - } else { - subdomain = ""; - } - this._subDomain.setAttribute("value", subdomain); - this._domain.setAttribute("value", host); - this._port.setAttribute("value", port); - } else { - this._subDomain.removeAttribute("value"); - this._domain.removeAttribute("value"); - this._port.removeAttribute("value"); - } - - var path = this._uri.path; - try { - // try to decode as UTF-8 - path = decodeURI(path); - } catch(e) {} - this._path.setAttribute("value", path); - ]]> - - - - - - - - - 0) { - opacity -= opacity * DECLINATION_REL + DECLINATION_ABS; - if (opacity < 0) - opacity = 0; - this._blendingTimers.push(setTimeout(processFrame, delay, opacity, delay == INITIAL_DELAY)); - delay += FRAME_LENGTH; - } - ]]> - - - - - @@ -411,12 +179,6 @@ @@ -435,71 +194,27 @@ - - - - - pBO.screenX + pBO.width) - return; - } - this._mouseover = true; - setTimeout(function(self) { - if (self._mouseover) { - self.plain = true; - if (!self._focused && self._contentIsCropped) - self._initURLTooltip(function() { - return this.plain ? this.value : null; - }, self, "start"); - } - }, 60, this); - ]]> - - - - - - + diff --git a/browser/components/migration/src/nsIEProfileMigrator.cpp b/browser/components/migration/src/nsIEProfileMigrator.cpp index e2a96bdb1f4b..2eea04bc8d47 100644 --- a/browser/components/migration/src/nsIEProfileMigrator.cpp +++ b/browser/components/migration/src/nsIEProfileMigrator.cpp @@ -1532,7 +1532,7 @@ nsIEProfileMigrator::CopyCookies(PRBool aReplace) { // IE cookies are stored in files named @domain[n].txt // (in 's Cookies folder. isn't the naming redundant?) - PRBool rv = NS_OK; + nsresult rv = NS_OK; nsCOMPtr cookiesDir; nsCOMPtr cookieFiles; @@ -1543,8 +1543,33 @@ nsIEProfileMigrator::CopyCookies(PRBool aReplace) // find the cookies directory NS_GetSpecialDirectory(NS_WIN_COOKIES_DIR, getter_AddRefs(cookiesDir)); - if (cookiesDir) - cookiesDir->GetDirectoryEntries(getter_AddRefs(cookieFiles)); + if (!cookiesDir) + return NS_ERROR_FAILURE; + + // Check for Vista's UAC, if so, tack on a "Low" sub dir + nsCOMPtr regKey = + do_CreateInstance("@mozilla.org/windows-registry-key;1"); + if (regKey) { + NS_NAMED_LITERAL_STRING(regPath,"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System"); + if (NS_SUCCEEDED(regKey->Open(nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE, + regPath, + nsIWindowsRegKey::ACCESS_QUERY_VALUE))) { + PRUint32 value; + if (NS_SUCCEEDED(regKey->ReadIntValue(NS_LITERAL_STRING("EnableLUA"), + &value)) && + value == 1) { + nsAutoString dir; + // For cases where we are running under protected mode, check + // cookiesDir for the Low sub directory. (Simpler than using + // process token calls to check our Vista integrity level.) + cookiesDir->GetLeafName(dir); + if (!dir.EqualsLiteral("Low")) + cookiesDir->Append(NS_LITERAL_STRING("Low")); + } + } + } + + cookiesDir->GetDirectoryEntries(getter_AddRefs(cookieFiles)); if (!cookieFiles) return NS_ERROR_FAILURE; diff --git a/browser/components/places/content/bookmarksPanel.js b/browser/components/places/content/bookmarksPanel.js index 5ea819e9f9f1..2d12a2b7f51b 100644 --- a/browser/components/places/content/bookmarksPanel.js +++ b/browser/components/places/content/bookmarksPanel.js @@ -44,6 +44,6 @@ function searchBookmarks(aSearchString) { if (!aSearchString) tree.place = tree.place; else - tree.applyFilter(aSearchString, true); + tree.applyFilter(aSearchString, true, + [PlacesUtils.bookmarksRootId, PlacesUtils.unfiledRootId]); } - diff --git a/browser/components/places/content/bookmarksPanel.xul b/browser/components/places/content/bookmarksPanel.xul index a67c888439bf..8de3bf4235ed 100644 --- a/browser/components/places/content/bookmarksPanel.xul +++ b/browser/components/places/content/bookmarksPanel.xul @@ -67,7 +67,7 @@ oncommand="searchBookmarks(this.value);"/> - - + diff --git a/browser/components/places/content/controller.js b/browser/components/places/content/controller.js index 0f02a5912719..4894c74a7685 100755 --- a/browser/components/places/content/controller.js +++ b/browser/components/places/content/controller.js @@ -1030,39 +1030,48 @@ PlacesController.prototype = { * elsewhere. */ getTransferData: function PC_getTransferData(dragAction) { - var nodes = null; - if (dragAction == Ci.nsIDragService.DRAGDROP_ACTION_COPY) - nodes = this._view.getCopyableSelection(); - else - nodes = this._view.getDragableSelection(); - var dataSet = new TransferDataSet(); - for (var i = 0; i < nodes.length; ++i) { - var node = nodes[i]; + var result = this._view.getResult(); + var oldViewer = result.viewer; + try { + result.viewer = null; + var nodes = null; + if (dragAction == Ci.nsIDragService.DRAGDROP_ACTION_COPY) + nodes = this._view.getCopyableSelection(); + else + nodes = this._view.getDragableSelection(); + var dataSet = new TransferDataSet(); + for (var i = 0; i < nodes.length; ++i) { + var node = nodes[i]; - var data = new TransferData(); - function addData(type, overrideURI) { - data.addDataForFlavour(type, PlacesUtils._wrapString( - PlacesUtils.wrapNode(node, type, overrideURI))); + var data = new TransferData(); + function addData(type, overrideURI) { + data.addDataForFlavour(type, PlacesUtils._wrapString( + PlacesUtils.wrapNode(node, type, overrideURI))); + } + + function addURIData(overrideURI) { + addData(PlacesUtils.TYPE_X_MOZ_URL, overrideURI); + addData(PlacesUtils.TYPE_UNICODE, overrideURI); + addData(PlacesUtils.TYPE_HTML, overrideURI); + } + + // This order is _important_! It controls how this and other + // applications select data to be inserted based on type. + addData(PlacesUtils.TYPE_X_MOZ_PLACE); + + var uri; + + // Allow dropping the feed uri of live-bookmark folders + if (PlacesUtils.nodeIsLivemarkContainer(node)) + uri = PlacesUtils.livemarks.getFeedURI(node.itemId).spec; + + addURIData(uri); + dataSet.push(data); } - - function addURIData(overrideURI) { - addData(PlacesUtils.TYPE_X_MOZ_URL, overrideURI); - addData(PlacesUtils.TYPE_UNICODE, overrideURI); - addData(PlacesUtils.TYPE_HTML, overrideURI); - } - - // This order is _important_! It controls how this and other - // applications select data to be inserted based on type. - addData(PlacesUtils.TYPE_X_MOZ_PLACE); - - var uri; - - // Allow dropping the feed uri of live-bookmark folders - if (PlacesUtils.nodeIsLivemarkContainer(node)) - uri = PlacesUtils.livemarks.getFeedURI(node.itemId).spec; - - addURIData(uri); - dataSet.push(data); + } + finally { + if (oldViewer) + result.viewer = oldViewer; } return dataSet; }, @@ -1071,63 +1080,69 @@ PlacesController.prototype = { * Copy Bookmarks and Folders to the clipboard */ copy: function PC_copy() { - var nodes = this._view.getCopyableSelection(); + var result = this._view.getResult(); + var oldViewer = result.viewer; + try { + result.viewer = null; + var nodes = this._view.getCopyableSelection(); - var xferable = - Cc["@mozilla.org/widget/transferable;1"]. - createInstance(Ci.nsITransferable); - var foundFolder = false, foundLink = false; - var copiedFolders = []; - var placeString = mozURLString = htmlString = unicodeString = ""; + var xferable = Cc["@mozilla.org/widget/transferable;1"]. + createInstance(Ci.nsITransferable); + var foundFolder = false, foundLink = false; + var copiedFolders = []; + var placeString = mozURLString = htmlString = unicodeString = ""; - for (var i = 0; i < nodes.length; ++i) { - var node = nodes[i]; - if (this._shouldSkipNode(node, copiedFolders)) - continue; - if (PlacesUtils.nodeIsFolder(node)) - copiedFolders.push(node); + for (var i = 0; i < nodes.length; ++i) { + var node = nodes[i]; + if (this._shouldSkipNode(node, copiedFolders)) + continue; + if (PlacesUtils.nodeIsFolder(node)) + copiedFolders.push(node); - function generateChunk(type, overrideURI) { - var suffix = i < (nodes.length - 1) ? NEWLINE : ""; - var uri = overrideURI; + function generateChunk(type, overrideURI) { + var suffix = i < (nodes.length - 1) ? NEWLINE : ""; + var uri = overrideURI; - if (PlacesUtils.nodeIsLivemarkContainer(node)) - uri = PlacesUtils.livemarks.getFeedURI(node.itemId).spec - - mozURLString += (PlacesUtils.wrapNode(node, PlacesUtils.TYPE_X_MOZ_URL, - uri) + suffix); - unicodeString += (PlacesUtils.wrapNode(node, PlacesUtils.TYPE_UNICODE, - uri) + suffix); - htmlString += (PlacesUtils.wrapNode(node, PlacesUtils.TYPE_HTML, - uri) + suffix); + if (PlacesUtils.nodeIsLivemarkContainer(node)) + uri = PlacesUtils.livemarks.getFeedURI(node.itemId).spec + + mozURLString += (PlacesUtils.wrapNode(node, PlacesUtils.TYPE_X_MOZ_URL, + uri) + suffix); + unicodeString += (PlacesUtils.wrapNode(node, PlacesUtils.TYPE_UNICODE, + uri) + suffix); + htmlString += (PlacesUtils.wrapNode(node, PlacesUtils.TYPE_HTML, + uri) + suffix); - var placeSuffix = i < (nodes.length - 1) ? "," : ""; - return PlacesUtils.wrapNode(node, type, overrideURI) + placeSuffix; + var placeSuffix = i < (nodes.length - 1) ? "," : ""; + return PlacesUtils.wrapNode(node, type, overrideURI) + placeSuffix; + } + + // all items wrapped as TYPE_X_MOZ_PLACE + placeString += generateChunk(PlacesUtils.TYPE_X_MOZ_PLACE); } - // all items wrapped as TYPE_X_MOZ_PLACE - placeString += generateChunk(PlacesUtils.TYPE_X_MOZ_PLACE); - } + function addData(type, data) { + xferable.addDataFlavor(type); + xferable.setTransferData(type, PlacesUtils._wrapString(data), data.length * 2); + } + // This order is _important_! It controls how this and other applications + // select data to be inserted based on type. + if (placeString) + addData(PlacesUtils.TYPE_X_MOZ_PLACE, placeString); + if (mozURLString) + addData(PlacesUtils.TYPE_X_MOZ_URL, mozURLString); + if (unicodeString) + addData(PlacesUtils.TYPE_UNICODE, unicodeString); + if (htmlString) + addData(PlacesUtils.TYPE_HTML, htmlString); - function addData(type, data) { - xferable.addDataFlavor(type); - xferable.setTransferData(type, PlacesUtils._wrapString(data), data.length * 2); + if (placeString || unicodeString || htmlString || mozURLString) { + PlacesUtils.clipboard.setData(xferable, null, Ci.nsIClipboard.kGlobalClipboard); + } } - // This order is _important_! It controls how this and other applications - // select data to be inserted based on type. - if (placeString) - addData(PlacesUtils.TYPE_X_MOZ_PLACE, placeString); - if (mozURLString) - addData(PlacesUtils.TYPE_X_MOZ_URL, mozURLString); - if (unicodeString) - addData(PlacesUtils.TYPE_UNICODE, unicodeString); - if (htmlString) - addData(PlacesUtils.TYPE_HTML, htmlString); - - if (placeString || unicodeString || htmlString || mozURLString) { - var clipboard = - Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard); - clipboard.setData(xferable, null, Ci.nsIClipboard.kGlobalClipboard); + finally { + if (oldViewer) + result.viewer = oldViewer; } }, @@ -1166,8 +1181,7 @@ PlacesController.prototype = { return xferable; } - var clipboard = Cc["@mozilla.org/widget/clipboard;1"]. - getService(Ci.nsIClipboard); + var clipboard = PlacesUtils.clipboard; var ip = this._view.insertionPoint; if (!ip) @@ -1221,6 +1235,285 @@ PlacesController.prototype = { } }; +function PlacesMenuDNDObserver(aView, aPopup) { + this._view = aView; + this._popup = aPopup; + this._popup.addEventListener("draggesture", this, false); + this._popup.addEventListener("dragover", this, false); + this._popup.addEventListener("dragdrop", this, false); + this._popup.addEventListener("dragexit", this, false); +} + +/** + * XXXmano-please-rewrite-me: This code was ported over from menu.xul in bug 399729. + * Unsurprisngly it's still mostly broken due to bug 337761, thus I didn't bother + * trying to cleaning up this extremely buggy over-folder detection code yet. + */ +PlacesMenuDNDObserver.prototype = { + _view: null, + _popup: null, + + // Sub-menus should be opened when the mouse drags over them, and closed + // when the mouse drags off. The overFolder object manages opening and closing + // of folders when the mouse hovers. + _overFolder: {node: null, openTimer: null, hoverTime: 350, closeTimer: null}, + + // If this menu's parent auto-opened it because it was dragged over, but didn't + // close it because the mouse dragged into it, the menu should close itself + // onDragExit. This timer is set in dragExit to close the menu. + _closeMenuTimer: null, + + _setTimer: function TBV_DO_setTimer(time) { + var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); + timer.initWithCallback(this, time, timer.TYPE_ONE_SHOT); + return timer; + }, + + // Function to process all timer notifications. + notify: function TBV_DO_notify(timer) { + // Timer to open a submenu that's being dragged over. + if (timer == this._overFolder.openTimer) { + this._overFolder.node.lastChild.setAttribute("autoopened", "true"); + this._overFolder.node.lastChild.showPopup(this._overFolder.node); + this._overFolder.openTimer = null; + } + + // Timer to close a submenu that's been dragged off of. + if (timer == this._overFolder.closeTimer) { + // Only close the submenu if the mouse isn't being dragged over any + // of its child menus. + var draggingOverChild = + PlacesControllerDragHelper.draggingOverChildNode(this._overFolder.node); + if (draggingOverChild) + this._overFolder.node = null; + this._clearOverFolder(); + + // Close any parent folders which aren't being dragged over. + // (This is necessary because of the above code that keeps a folder + // open while its children are being dragged over.) + if (!draggingOverChild) + this._closeParentMenus(); + } + + // Timer to close this menu after the drag exit. + if (timer == this._closeMenuTimer) { + if (!PlacesControllerDragHelper.draggingOverChildNode(this._popup)) { + this._popup.hidePopup(); + // Close any parent menus that aren't being dragged over; + // otherwise they'll stay open because they couldn't close + // while this menu was being dragged over. + this._closeParentMenus(); + } + } + }, + + // Helper function to close all parent menus of this menu, + // as long as none of the parent's children are currently being + // dragged over. + _closeParentMenus: function TBV_DO_closeParentMenus() { + var parent = this._popup.parentNode; + while (parent) { + if (parent.nodeName == "menupopup" && parent._resultNode) { + if (PlacesControllerDragHelper.draggingOverChildNode(parent.parentNode)) + break; + parent.hidePopup(); + } + parent = parent.parentNode; + } + }, + + // The mouse is no longer dragging over the stored menubutton. + // Close the menubutton, clear out drag styles, and clear all + // timers for opening/closing it. + _clearOverFolder: function TBV_DO_clearOverFolder() { + if (this._overFolder.node && this._overFolder.node.lastChild) { + if (!this._overFolder.node.lastChild.hasAttribute("dragover")) + this._overFolder.node.lastChild.hidePopup(); + this._overFolder.node = null; + } + if (this._overFolder.openTimer) { + this._overFolder.openTimer.cancel(); + this._overFolder.openTimer = null; + } + if (this._overFolder.closeTimer) { + this._overFolder.closeTimer.cancel(); + this._overFolder.closeTimer = null; + } + }, + + // This function returns information about where to drop when + // dragging over this menu--insertion point, child index to drop + // before, and folder to drop into. + _getDropPoint: function TBV_DO_getDropPoint(event) { + // Can't drop if the menu isn't a folder + var resultNode = this._popup._resultNode; + if (!PlacesUtils.nodeIsFolder(resultNode)) + return null; + + var dropPoint = { ip: null, beforeIndex: null, folderNode: null }; + // Loop through all the nodes to see which one this should + // get dropped in/above/below. + var start = 0; + var end = this._popup.childNodes.length; + if (this._popup == this._view && this._view.localName == "menupopup") { + // Ignore static content at the top and bottom of the menu. + start = this._view._startMarker + 1; + if (this._view._endMarker != -1) + end = this._view._endMarker; + } + + for (var i = start; i < end; i++) { + var xulNode = this._popup.childNodes[i]; + var nodeY = xulNode.boxObject.y - this._popup.boxObject.y; + var nodeHeight = xulNode.boxObject.height; + if (xulNode.node && + PlacesUtils.nodeIsFolder(xulNode.node) && + !PlacesUtils.nodeIsReadOnly(xulNode.node)) { + // This is a folder. If the mouse is in the top 25% of the + // node, drop above the folder. If it's in the middle + // 50%, drop into the folder. If it's past that, drop below. + if (event.clientY < nodeY + (nodeHeight * 0.25)) { + // Drop above this folder. + dropPoint.ip = new InsertionPoint(resultNode.itemId, i - start, + -1); + dropPoint.beforeIndex = i; + return dropPoint; + } + else if (event.clientY < nodeY + (nodeHeight * 0.75)) { + // Drop inside this folder. + dropPoint.ip = new InsertionPoint(xulNode.node.itemId, -1, 1); + dropPoint.beforeIndex = i; + dropPoint.folderNode = xulNode; + return dropPoint; + } + } else { + // This is a non-folder node. If the mouse is above the middle, + // drop above the folder. Otherwise, drop below. + if (event.clientY < nodeY + (nodeHeight / 2)) { + // Drop above this bookmark. + dropPoint.ip = new InsertionPoint(resultNode.itemId, i - start, -1); + dropPoint.beforeIndex = i; + return dropPoint; + } + } + } + // Should drop below the last node. + dropPoint.ip = new InsertionPoint(resultNode.itemId, -1, 1); + dropPoint.beforeIndex = -1; + return dropPoint; + }, + + // This function clears all of the dragover styles that were set when + // a menuitem was dragged over. + _clearStyles: function TBV_DO_clearStyles() { + this._popup.removeAttribute("dragover"); + for (var i = 0; i < this._popup.childNodes.length; i++) { + this._popup.childNodes[i].removeAttribute("dragover-top"); + this._popup.childNodes[i].removeAttribute("dragover-bottom"); + this._popup.childNodes[i].removeAttribute("dragover-into"); + } + }, + + onDragStart: function TBV_DO_onDragStart(event, xferData, dragAction) { + this._view._selection = event.target.node; + this._view._cachedInsertionPoint = undefined; + if (event.ctrlKey) + dragAction.action = Ci.nsIDragService.DRAGDROP_ACTION_COPY; + xferData.data = this._view.controller.getTransferData(dragAction.action); + }, + + canDrop: function TBV_DO_canDrop(event, session) { + return PlacesControllerDragHelper.canDrop(this._view, -1); + }, + + onDragOver: function TBV_DO_onDragOver(event, flavor, session) { + PlacesControllerDragHelper.currentDropTarget = event.target; + var dropPoint = this._getDropPoint(event); + if (dropPoint == null) + return; + + this._clearStyles(); + if (dropPoint.folderNode) { + // Dragging over a folder; set the appropriate styles. + if (this._overFolder.node != dropPoint.folderNode) { + this._clearOverFolder(); + this._overFolder.node = dropPoint.folderNode; + this._overFolder.openTimer = this._setTimer(this._overFolder.hoverTime); + } + dropPoint.folderNode.setAttribute("dragover-into", "true"); + } + else { + // Dragging over a menuitem, set dragover-top/bottom to show where + // the item will be dropped and clear out any old folder info. + if (dropPoint.beforeIndex == -1) { + if (this._popup == this._view && this._view.localName == "menupopup" && + this._popup._endMarker != -1) { + this._popup.childNodes[this._popup._endMarker] + .setAttribute("dragover-top", "true"); + } + else + this._popup.lastChild.setAttribute("dragover-bottom", "true"); + } + else { + this._popup.childNodes[dropPoint.beforeIndex] + .setAttribute("dragover-top", "true"); + } + + // Clear out old folder information + this._clearOverFolder(); + } + this._popup.setAttribute("dragover", "true"); + }, + + onDrop: function TBV_DO_onDrop(event, dropData, session) { + var dropPoint = this._getDropPoint(event); + if (!dropPoint) + return; + + PlacesControllerDragHelper.onDrop(null, this._view, dropPoint.ip); + }, + + onDragExit: function TBV_DO_onDragExit(event, session) { + PlacesControllerDragHelper.currentDropTarget = null; + this._clearStyles(); + // Close any folder being hovered over + if (this._overFolder.node) + this._overFolder.closeTimer = this._setTimer(this._overFolder.hoverTime); + // The autoopened attribute is set when this folder was automatically + // opened after the user dragged over it. If this attribute is set, + // auto-close the folder on drag exit. + if (this._popup.hasAttribute("autoopened")) + this._closeMenuTimer = this._setTimer(this._overFolder.hoverTime); + }, + + getSupportedFlavours: function TBV_DO_getSupportedFlavours() { + var flavorSet = new FlavourSet(); + for (var i = 0; i < this._view.peerDropTypes.length; ++i) + flavorSet.appendFlavour(this._view.peerDropTypes[i]); + return flavorSet; + }, + + handleEvent: function(aEvent) { + switch (aEvent.type) { + case "draggesture": + if (aEvent.target.localName != "menu" && aEvent.target.node) { + // TODO--allow menu drag if shift (or alt??) key is down + nsDragAndDrop.startDrag(aEvent, this); + } + break; + case "dragover": + nsDragAndDrop.dragOver(aEvent, this); + break; + case "dragdrop": + nsDragAndDrop.drop(aEvent, this); + break; + case "dragexit": + nsDragAndDrop.dragExit(aEvent, this); + break; + } + } +} + /** * Handles drag and drop operations for views. Note that this is view agnostic! * You should not use PlacesController._view within these methods, since @@ -1273,9 +1566,9 @@ var PlacesControllerDragHelper = { * it is being dragged over, false otherwise. */ canDrop: function PCDH_canDrop(view, orientation) { - var parent = view.getResult().root; - if (PlacesUtils.nodeIsReadOnly(parent) || - !PlacesUtils.nodeIsFolder(parent)) + var root = view.getResult().root; + if (PlacesUtils.nodeIsReadOnly(root) || + !PlacesUtils.nodeIsFolder(root)) return false; var session = this.getSession(); @@ -1335,21 +1628,21 @@ var PlacesControllerDragHelper = { var xferable = this._initTransferable(session, targetView, insertionPoint.orientation); var dropCount = session.numDropItems; - + var movedCount = 0; - + for (var i = 0; i < dropCount; ++i) { session.getData(xferable, i); - + var data = { }, flavor = { }; xferable.getAnyTransferData(flavor, data, { }); data.value.QueryInterface(Ci.nsISupportsString); - + // There's only ever one in the D&D case. var unwrapped = PlacesUtils.unwrapNodes(data.value.data, flavor.value)[0]; var index = insertionPoint.index; - + // Adjust insertion index to prevent reversal of dragged items. When you // drag multiple elts upward: need to increment index or each successive // elt will be inserted at the same index, each above the previous. @@ -1358,7 +1651,7 @@ var PlacesControllerDragHelper = { index = index + movedCount; movedCount++; } - + transactions.push(PlacesUtils.makeTransaction(unwrapped, flavor.value, insertionPoint.itemId, index, copy)); diff --git a/browser/components/places/content/editBookmarkOverlay.js b/browser/components/places/content/editBookmarkOverlay.js index b88bf787a2c1..fcbaff41c227 100644 --- a/browser/components/places/content/editBookmarkOverlay.js +++ b/browser/components/places/content/editBookmarkOverlay.js @@ -571,11 +571,28 @@ var gEditItemOverlay = { expander.className = "expander-up" expander.setAttribute("tooltiptext", expander.getAttribute("tooltiptextup")); - if (!this._folderTree.treeBoxObject.view.isContainerOpen(0)) - this._folderTree.treeBoxObject.view.toggleOpenState(0); - this._folderTree.selectFolders([this._getFolderIdFromMenuList()]); this._folderTree.collapsed = false; - this._folderTree.focus(); + if (!this._folderTree.place) { + const FOLDER_TREE_PLACE_URI = + "place:folder=2&excludeItems=1&excludeQueries=1&excludeReadOnlyFolders=1"; + this._folderTree.place = FOLDER_TREE_PLACE_URI; + } + + var currentFolder = this._getFolderIdFromMenuList(); + // Don't select anything in the tree if the item is "unfiled" + if (currentFolder == PlacesUtils.unfiledRootId) + this._folderTree.selectFolders([]); + else { + this._folderTree.selectFolders([currentFolder]); + this._folderTree.focus(); + } + + if ((currentFolder == PlacesUtils.bookmarksRootId || + currentFolder == PlacesUtils.unfiledRootId) && + !this._folderTree.treeBoxObject.view.isContainerOpen(0)) { + // Expand the root node if selectFolder didn't + this._folderTree.treeBoxObject.view.toggleOpenState(0); + } } }, diff --git a/browser/components/places/content/editBookmarkOverlay.xul b/browser/components/places/content/editBookmarkOverlay.xul index ccdca15f1bc0..658e7bc01942 100644 --- a/browser/components/places/content/editBookmarkOverlay.xul +++ b/browser/components/places/content/editBookmarkOverlay.xul @@ -144,7 +144,6 @@ collapsed="true" onselect="gEditItemOverlay.onFolderTreeSelect();" showRoot="true" - place="place:folder=2&excludeItems=1&excludeQueries=1&excludeReadOnlyFolders=1" hidecolumnpicker="true" observes="paneElementsBroadcaster"> diff --git a/browser/components/places/content/history-panel.xul b/browser/components/places/content/history-panel.xul index c34bd4916bb4..606ab9a1d768 100644 --- a/browser/components/places/content/history-panel.xul +++ b/browser/components/places/content/history-panel.xul @@ -114,6 +114,7 @@ - + diff --git a/browser/components/places/content/menu.xml b/browser/components/places/content/menu.xml index 5e57e14e4566..0e4536a2e581 100755 --- a/browser/components/places/content/menu.xml +++ b/browser/components/places/content/menu.xml @@ -80,34 +80,21 @@ false - false - + null - - - - - - - - -1 - -1 - + 0) --this._endMarker; } @@ -170,18 +147,18 @@ // If no static items were found at the beginning, remove all items before // the static items at the end. - if (this._startMarker == -1) { - var end = (this._endMarker == -1) ? this.childNodes.length - 1 : this._endMarker - 1; + if (aPopup._startMarker == -1) { + var end = aPopup._endMarker == -1 ? + aPopup.childNodes.length - 1 : aPopup._endMarker - 1; for (var i = end; i >=0; i--) { // skip the empty menu item - if (this._emptyMenuItem != this.childNodes[i]) { - this.removeChild(this.childNodes[i]); - if (this._endMarker > 0) - --this._endMarker; + if (aPopup._emptyMenuItem != aPopup.childNodes[i]) { + aPopup.removeChild(aPopup.childNodes[i]); + if (aPopup._endMarker > 0) + --aPopup._endMarker; } } } - //LOG("KIDS = " + this.childNodes.length); ]]> @@ -190,157 +167,78 @@ - - + + + -#ifdef XP_MACOSX - false -#endif - - null + + 0) { - if (this._emptyMenuItem) - this._emptyMenuItem.hidden = true; + if (aPopup._emptyMenuItem) + aPopup._emptyMenuItem.hidden = true; for (var i = 0; i < cc; ++i) { - var child = this._resultNode.getChild(i); - this.insertNewItem(child, null); + var child = aPopup._resultNode.getChild(i); + this.insertNewItem(child, aPopup, null); } } else { // This menu is empty. If there is no static content, add // an element to show it is empty. - if (this._startMarker == -1 && this._endMarker == -1) - this._showEmptyMenuItem(); + if (aPopup._startMarker == -1 && aPopup._endMarker == -1) + this._showEmptyMenuItem(aPopup); } - this._built = true; + aPopup._built = true; ]]> @@ -348,72 +246,60 @@ - - - - - - - @@ -943,64 +551,48 @@ - - if (event.target == this) - this.onPopupShowing(); + + this._ensureInitialized(); + if (event.target._resultNode) + this.onPopupShowing(event); - if (event.target != this) + var popup = event.target; + if (!popup._resultNode) return; // UI performance: folder queries are cheap, keep the resultnode open // so we don't rebuild its contents whenever the popup is reopened. - if (!PlacesUtils.nodeIsFolder(this._resultNode)) { - this._resultNode.containerOpen = false; - this._built = false; - } + if (!PlacesUtils.nodeIsFolder(popup._resultNode)) + popup._resultNode.containerOpen = false; // The autoopened attribute is set for folders which have been // automatically opened when dragged over. Turn off this attribute // when the folder closes because it is no longer applicable. - this.removeAttribute("autoopened"); + popup.removeAttribute("autoopened"); - - - - - diff --git a/browser/components/places/content/moveBookmarks.js b/browser/components/places/content/moveBookmarks.js index a1ecdd2d7fdd..1d7d2bea3dc1 100644 --- a/browser/components/places/content/moveBookmarks.js +++ b/browser/components/places/content/moveBookmarks.js @@ -52,12 +52,9 @@ var gMoveBookmarksDialog = { this._nodes = window.arguments[0]; this._tm = window.arguments[1]; - // setTimeout until bug 373944 is fixed - setTimeout(function(aSelf) { - // select and expand the root node - aSelf.foldersTree.selectFolders([PlacesUtils.bookmarksRootId]); - aSelf.foldersTree.selectedNode.containerOpen = true; - }, 0, this); + // select and expand the root node + this.foldersTree.selectFolders([PlacesUtils.bookmarksRootId]); + this.foldersTree.selectedNode.containerOpen = true; }, onOK: function MBD_onOK(aEvent) { diff --git a/browser/components/places/content/places.js b/browser/components/places/content/places.js index 6672f8084467..fef15dc7a6ad 100755 --- a/browser/components/places/content/places.js +++ b/browser/components/places/content/places.js @@ -54,13 +54,6 @@ var PlacesOrganizer = { _content: null, init: function PO_init() { - var self = this; - // on timeout because of the corresponding setTimeout() - // in the places tree binding's constructor - setTimeout(function() { self._init(); }, 0); - }, - - _init: function PO__init() { this._places = document.getElementById("placesList"); this._content = document.getElementById("placeContent"); @@ -576,7 +569,8 @@ var PlacesOrganizer = { // are saved if (gEditItemOverlay.itemId != -1) { var focusedElement = document.commandDispatcher.focusedElement; - if (focusedElement instanceof HTMLInputElement && + if ((focusedElement instanceof HTMLInputElement || + focusedElement instanceof HTMLTextAreaElement) && /^editBMPanel.*/.test(focusedElement.parentNode.parentNode.id)) focusedElement.blur(); } diff --git a/browser/components/places/content/places.xul b/browser/components/places/content/places.xul index 0954f99275d8..b87e5621184f 100755 --- a/browser/components/places/content/places.xul +++ b/browser/components/places/content/places.xul @@ -124,7 +124,7 @@ oncommand="close();"/> diff --git a/browser/components/places/content/toolbar.xml b/browser/components/places/content/toolbar.xml index fd63c180c76e..21d7135983ed 100755 --- a/browser/components/places/content/toolbar.xml +++ b/browser/components/places/content/toolbar.xml @@ -54,7 +54,7 @@ - + @@ -75,9 +75,9 @@ - + - + - - document.getAnonymousElementByAttribute(this, "class", "toolbar-drop-indicator-bar") document.getAnonymousElementByAttribute(this, "class", "chevron") - - null - - null - - null - false + null + + null + + null @@ -164,85 +151,69 @@ while (this.hasChildNodes()) this.removeChild(this.firstChild); - const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; - var cc = this._result.root.childCount; - for (var i = 0; i < cc; ++i) - this.insertNewItem(this._result.root.getChild(i), null); - var popup = this._chevron.firstChild; - popup.setAttribute("type", "places"); - // This is set here and not in the XBL constructor for the menu because - // it doesn't get initialized properly in the constructor. -#ifndef XP_MACOSX - // No context menus on menuitems on Mac - popup.setAttribute("context", "placesContext"); -#endif - popup.place = this.place; - var t = this; - popup.popupShowingCallback = function() { t.chevronPopupShowing(); }; + var rootNode = this._result.root; + var cc = rootNode.childCount; + for (var i = 0; i < cc; ++i) + this.insertNewItem(rootNode.getChild(i), null); + + var chevronPopup = this._chevron.lastChild; + if (chevronPopup.hasAttribute("type")) { + // Otherwise we'll set it when the chevron is enabled (see updateChevron) + chevronPopup.place = this.place; + } + + while (chevronPopup.hasChildNodes()) + chevronPopup.removeChild(chevronPopup.lastChild); // This needs to be in a timeout to make sure our boxObject has time // to get its proper size + var t = this; setTimeout(function() { t.updateChevron(); }, 0); ]]> - - + + @@ -253,18 +224,24 @@ + @@ -281,7 +258,7 @@ return element.boxObject.width + leftMargin + rightMargin; ]]> - + - + - + [] - - - @@ -998,21 +900,111 @@ - - - + + + + + + + + + + + + + + + + + + 0) { + if (aPopup._emptyMenuItem) + aPopup._emptyMenuItem.hidden = true; + + for (var i = 0; i < cc; ++i) { + var child = resultNode.getChild(i); + this.insertNewItemToPopup(child, aPopup, null); + } + } + else { + // add element to show it is empty. + this._showEmptyMenuItem(aPopup); + } + aPopup._built = true; + + if (!aPopup._DNDObserver) + aPopup._DNDObserver = new PlacesMenuDNDObserver(this, aPopup); + ]]> + + + + + + - + + + + @@ -114,11 +111,11 @@ if (optionsFilter) options = optionsFilter.filter(queryNode.getQueries({}), options, optionsFilter.historyHandler); - + var query = PlacesUtils.history.getNewQuery(); query.searchTerms = filterString; query.onlyBookmarked = onlyBookmarks; - + // Remove "group by folder" from the options list, because // nsNavHistory::RecursiveGroup doesn't support it. function isFolderGrouping(grouping, index, ary) { @@ -156,7 +153,8 @@ if (this.showRoot != val) { this.setAttribute("showRoot", val); // reload with the last place set - this.place = this.place; + if (this.place) + this.place = this.place; } return val; ]]> @@ -278,7 +276,7 @@ - 0) @@ -371,7 +375,7 @@ PlacesTreeView.prototype = { // now, open any containers that were persisted for (var i = 0; i < toOpenElements.length; i++) { - var item = asContainer(toOpenElements[i]); + var item = toOpenElements[i]; var parent = item.parent; // avoid recursively opening containers while (parent) { @@ -734,20 +738,9 @@ PlacesTreeView.prototype = { containerClosed: function PTV_containerClosed(aItem) { this.invalidateContainer(aItem); - }, - - get ignoreInvalidateContainer() { - return this._ignoreInvalidateContainer; }, - set ignoreInvalidateContainer(val) { - return this._ignoreInvalidateContainer = val; - }, - - invalidateContainer: function PTV_invalidateContainer(aItem) { - if (this._ignoreInvalidateContainer) - return; - + invalidateContainer: function PTV_invalidateContainer(aItem) { NS_ASSERT(this._result, "Got a notification but have no result!"); if (!this._tree) return; // nothing to do, container is not visible @@ -808,8 +801,10 @@ PlacesTreeView.prototype = { }, set result(val) { - this._result = val; - this._finishInit(); + if (this._result != val) { + this._result = val; + this._finishInit(); + } return val; }, @@ -875,7 +870,7 @@ PlacesTreeView.prototype = { return viewIndex; }, - _getResourceForNode : function PTV_getResourceForNode(aNode) + _getResourceForNode: function PTV_getResourceForNode(aNode) { var uri = aNode.uri; NS_ASSERT(uri, "if there is no uri, we can't persist the open state"); @@ -916,7 +911,7 @@ PlacesTreeView.prototype = { }, getCellProperties: function PTV_getCellProperties(aRow, aColumn, aProperties) { - var columnType = aColumn.id || aColumn.element.getAttribute("anonid") ; + var columnType = aColumn.id || aColumn.element.getAttribute("anonid"); if (columnType != "title") return; @@ -933,16 +928,14 @@ PlacesTreeView.prototype = { this._ensureValidRow(aRow); var node = this._visibleElements[aRow]; if (PlacesUtils.nodeIsContainer(node)) { + // the root node is always expandable + if (!node.parent) + return true; + // treat non-expandable queries as non-containers if (PlacesUtils.nodeIsQuery(node)) { asQuery(node); - if (node.queryOptions.expandQueries) - return true; - // the root node is always expandable - if (!node.parent) - return true; - - return false; + return node.queryOptions.expandQueries; } return true; } @@ -954,7 +947,7 @@ PlacesTreeView.prototype = { if (!PlacesUtils.nodeIsContainer(this._visibleElements[aRow])) throw Cr.NS_ERROR_INVALID_ARG; - return asContainer(this._visibleElements[aRow]).containerOpen; + return this._visibleElements[aRow].containerOpen; }, isContainerEmpty: function PTV_isContainerEmpty(aRow) { @@ -962,7 +955,7 @@ PlacesTreeView.prototype = { if (!PlacesUtils.nodeIsContainer(this._visibleElements[aRow])) throw Cr.NS_ERROR_INVALID_ARG; - return !asContainer(this._visibleElements[aRow]).hasChildren; + return !this._visibleElements[aRow].hasChildren; }, isSeparator: function PTV_isSeparator(aRow) { @@ -1003,8 +996,15 @@ PlacesTreeView.prototype = { return false; } - return this._visibleElements[aRow].indentLevel == - this._visibleElements[aRow + 1].indentLevel; + var thisLevel = this._visibleElements[aRow].indentLevel; + for (var i = aAfterIndex + 1; i < this._visibleElements.length; ++i) { + var nextLevel = this._visibleElements[i].indentLevel; + if (nextLevel == thisLevel) + return true; + if (nextLevel < thisLevel) + break; + } + return false; }, getLevel: function PTV_getLevel(aRow) { @@ -1133,7 +1133,6 @@ PlacesTreeView.prototype = { if (!PlacesUtils.nodeIsContainer(node)) return; // not a container, nothing to do - asContainer(node); var resource = this._getResourceForNode(node); if (resource) { const openLiteral = PlacesUtils.RDF.GetResource("http://home.netscape.com/NC-rdf#open"); @@ -1304,5 +1303,4 @@ function PlacesTreeView(aShowRoot) { this._visibleElements = []; this._observers = []; this._showRoot = aShowRoot; - this._ignoreInvalidateContainer = false; } diff --git a/browser/components/places/content/utils.js b/browser/components/places/content/utils.js index 9873e3a6b7aa..8a3eafee4314 100644 --- a/browser/components/places/content/utils.js +++ b/browser/components/places/content/utils.js @@ -95,119 +95,92 @@ var PlacesUtils = { /** * The Bookmarks Service. */ - _bookmarks: null, get bookmarks() { - if (!this._bookmarks) { - this._bookmarks = Cc["@mozilla.org/browser/nav-bookmarks-service;1"]. - getService(Ci.nsINavBookmarksService); - } - return this._bookmarks; + delete this.bookmarks; + return this.bookmarks = Cc["@mozilla.org/browser/nav-bookmarks-service;1"]. + getService(Ci.nsINavBookmarksService); }, /** * The Nav History Service. */ - _history: null, get history() { - if (!this._history) { - this._history = Cc["@mozilla.org/browser/nav-history-service;1"]. - getService(Ci.nsINavHistoryService); - } - return this._history; + delete this.history; + return this.history = Cc["@mozilla.org/browser/nav-history-service;1"]. + getService(Ci.nsINavHistoryService); }, /** * The Live Bookmark Service. */ - _livemarks: null, get livemarks() { - if (!this._livemarks) { - this._livemarks = Cc["@mozilla.org/browser/livemark-service;2"]. - getService(Ci.nsILivemarkService); - } - return this._livemarks; + delete this.livemarks; + return this.livemarks = Cc["@mozilla.org/browser/livemark-service;2"]. + getService(Ci.nsILivemarkService); }, /** * The Annotations Service. */ - _annotations: null, get annotations() { - if (!this._annotations) { - this._annotations = Cc["@mozilla.org/browser/annotation-service;1"]. - getService(Ci.nsIAnnotationService); - } - return this._annotations; + delete this.annotations; + return this.annotations = Cc["@mozilla.org/browser/annotation-service;1"]. + getService(Ci.nsIAnnotationService); }, /** * The Favicons Service */ - _favicons: null, get favicons() { - if (!this._favicons) { - this._favicons = Cc["@mozilla.org/browser/favicon-service;1"]. - getService(Ci.nsIFaviconService); - } - return this._favicons; + delete this.favicons; + return this.favicons = Cc["@mozilla.org/browser/favicon-service;1"]. + getService(Ci.nsIFaviconService); }, /** * The Microsummary Service */ - _microsummaries: null, get microsummaries() { - if (!this._microsummaries) - this._microsummaries = Cc["@mozilla.org/microsummary/service;1"]. - getService(Ci.nsIMicrosummaryService); - return this._microsummaries; + delete this.microsummaries; + return this.microsummaries = Cc["@mozilla.org/microsummary/service;1"]. + getService(Ci.nsIMicrosummaryService); }, /** * The Places Tagging Service */ get tagging() { - if (!this._tagging) - this._tagging = Cc["@mozilla.org/browser/tagging-service;1"]. - getService(Ci.nsITaggingService); - return this._tagging; + delete this.tagging; + return this.tagging = Cc["@mozilla.org/browser/tagging-service;1"]. + getService(Ci.nsITaggingService); }, - _RDF: null, get RDF() { - if (!this._RDF) - this._RDF = Cc["@mozilla.org/rdf/rdf-service;1"]. - getService(Ci.nsIRDFService); - return this._RDF; + delete this.RDF; + return this.RDF = Cc["@mozilla.org/rdf/rdf-service;1"]. + getService(Ci.nsIRDFService); }, - _localStore: null, get localStore() { - if (!this._localStore) - this._localStore = this.RDF.GetDataSource("rdf:local-store"); - return this._localStore; + delete this.localStore; + return this.localStore = this.RDF.GetDataSource("rdf:local-store"); }, get tm() { - return this.ptm.transactionManager; + delete this.tm; + return this.tm = this.ptm.transactionManager; }, - _ptm: null, get ptm() { - if (!this._ptm) { - this._ptm = Cc["@mozilla.org/browser/placesTransactionsService;1"]. - getService(Components.interfaces.nsIPlacesTransactionsService); - } - return this._ptm; + delete this.ptm; + return this.ptm = Cc["@mozilla.org/browser/placesTransactionsService;1"]. + getService(Ci.nsIPlacesTransactionsService); }, - _clipboard: null, get clipboard() { - if (!this._clipboard) { - this._clipboard = Cc["@mozilla.org/widget/clipboard;1"]. - getService(Ci.nsIClipboard); - } - return this._clipboard; + delete this.clipboard; + return this.clipboard = Cc["@mozilla.org/widget/clipboard;1"]. + getService(Ci.nsIClipboard); }, /** @@ -218,9 +191,7 @@ var PlacesUtils = { */ _uri: function PU__uri(aSpec) { NS_ASSERT(aSpec, "empty URL spec"); - var ios = Cc["@mozilla.org/network/io-service;1"]. - getService(Ci.nsIIOService); - return ios.newURI(aSpec, null, null); + return IO.newURI(aSpec); }, /** @@ -239,16 +210,13 @@ var PlacesUtils = { /** * String bundle helpers */ - __bundle: null, get _bundle() { - if (!this.__bundle) { - const PLACES_STRING_BUNDLE_URI = + const PLACES_STRING_BUNDLE_URI = "chrome://browser/locale/places/places.properties"; - this.__bundle = Cc["@mozilla.org/intl/stringbundle;1"]. - getService(Ci.nsIStringBundleService). - createBundle(PLACES_STRING_BUNDLE_URI); - } - return this.__bundle; + delete this._bundle; + return this._bundle = Cc["@mozilla.org/intl/stringbundle;1"]. + getService(Ci.nsIStringBundleService). + createBundle(PLACES_STRING_BUNDLE_URI); }, getFormattedString: function PU_getFormattedString(key, params) { @@ -315,14 +283,12 @@ var PlacesUtils = { * A result node * @returns true if the node is a URL item, false otherwise */ + uriTypes: [Ci.nsINavHistoryResultNode.RESULT_TYPE_URI, + Ci.nsINavHistoryResultNode.RESULT_TYPE_VISIT, + Ci.nsINavHistoryResultNode.RESULT_TYPE_FULL_VISIT], nodeIsURI: function PU_nodeIsURI(aNode) { NS_ASSERT(aNode, "null node"); - - const NHRN = Ci.nsINavHistoryResultNode; - var type = aNode.type; - return type == NHRN.RESULT_TYPE_URI || - type == NHRN.RESULT_TYPE_VISIT || - type == NHRN.RESULT_TYPE_FULL_VISIT; + return this.uriTypes.indexOf(aNode.type) != -1; }, /** @@ -333,7 +299,6 @@ var PlacesUtils = { */ nodeIsQuery: function PU_nodeIsQuery(aNode) { NS_ASSERT(aNode, "null node"); - return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY; }, @@ -362,7 +327,6 @@ var PlacesUtils = { */ nodeIsHost: function PU_nodeIsHost(aNode) { NS_ASSERT(aNode, "null node"); - return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_HOST; }, @@ -372,16 +336,14 @@ var PlacesUtils = { * A result node * @returns true if the node is a container item, false otherwise */ + containerTypes: [Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER, + Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY, + Ci.nsINavHistoryResultNode.RESULT_TYPE_HOST, + Ci.nsINavHistoryResultNode.RESULT_TYPE_DAY, + Ci.nsINavHistoryResultNode.RESULT_TYPE_DYNAMIC_CONTAINER], nodeIsContainer: function PU_nodeIsContainer(aNode) { NS_ASSERT(aNode, "null node"); - - const NHRN = Ci.nsINavHistoryResultNode; - var type = aNode.type; - return type == NHRN.RESULT_TYPE_HOST || - type == NHRN.RESULT_TYPE_QUERY || - type == NHRN.RESULT_TYPE_FOLDER || - type == NHRN.RESULT_TYPE_DAY || - type == NHRN.RESULT_TYPE_DYNAMIC_CONTAINER; + return this.containerTypes.indexOf(aNode.type) != -1; }, /** @@ -448,14 +410,22 @@ var PlacesUtils = { NS_ASSERT(aNode, "null node"); var parent = aNode.parent; - if (!parent || !PlacesUtils.nodeIsContainer(parent)) + if (!parent) return -1; var wasOpen = parent.containerOpen; - parent.containerOpen = true; + var result, oldViewer; + if (!wasOpen) { + result = parent.parentResult; + oldViewer = result.viewer; + result.viewer = null; + parent.containerOpen = true; + } var cc = parent.childCount; - asContainer(parent); for (var i = 0; i < cc && parent.getChild(i) != aNode; ++i); - parent.containerOpen = wasOpen; + if (!wasOpen) { + parent.containerOpen = false; + result.viewer = oldViewer; + } return i < cc ? i : -1; }, @@ -650,7 +620,7 @@ var PlacesUtils = { * @returns A nsITransaction object that performs the copy. */ _getURIItemCopyTransaction: function (aData, aContainer, aIndex) { - return this.ptm.createItem(this._uri(aData.uri), aContainer, aIndex, + return this.ptm.createItem(IO.newURI(aData.uri), aContainer, aIndex, aData.title, ""); }, @@ -671,7 +641,7 @@ var PlacesUtils = { _getBookmarkItemCopyTransaction: function PU__getBookmarkItemCopyTransaction(aData, aContainer, aIndex, aExcludeAnnotations) { - var itemURL = this._uri(aData.uri); + var itemURL = IO.newURI(aData.uri); var itemTitle = aData.title; var keyword = aData.keyword; var annos = aData.annos; @@ -724,8 +694,8 @@ var PlacesUtils = { folderItemsTransactions); } else { // node is a livemark - var feedURI = self._uri(node.uri.feed); - var siteURI = self._uri(node.uri.site); + var feedURI = IO.newURI(node.uri.feed); + var siteURI = IO.newURI(node.uri.site); txn = self.ptm.createLivemark(feedURI, siteURI, node.title, aContainer, index, node.annos); } @@ -776,8 +746,8 @@ var PlacesUtils = { for (var i = 0; i < parts.length; i=i+2) { var uriString = parts[i]; var titleString = parts[i+1]; - // note: this._uri() will throw if uriString is not a valid URI - if (this._uri(uriString)) { + // note: IO.newURI() will throw if uriString is not a valid URI + if (IO.newURI(uriString)) { nodes.push({ uri: uriString, title: titleString ? titleString : uriString }); } @@ -787,8 +757,8 @@ var PlacesUtils = { var parts = blob.split("\n"); for (var i = 0; i < parts.length; i++) { var uriString = parts[i]; - // note: this._uri() will throw if uriString is not a valid URI - if (uriString != "" && this._uri(uriString)) + // note: IO.newURI() will throw if uriString is not a valid URI + if (uriString != "" && IO.newURI(uriString)) nodes.push({ uri: uriString, title: uriString }); } break; @@ -826,8 +796,8 @@ var PlacesUtils = { } else if (copy) { // Place is a Livemark Container, should be reinstantiated - var feedURI = this._uri(data.uri.feed); - var siteURI = this._uri(data.uri.site); + var feedURI = IO.newURI(data.uri.feed); + var siteURI = IO.newURI(data.uri.site); return this.ptm.createLivemark(feedURI, siteURI, data.title, container, index, data.annos); } @@ -855,7 +825,7 @@ var PlacesUtils = { default: if (type == this.TYPE_X_MOZ_URL || type == this.TYPE_UNICODE) { var title = (type == this.TYPE_X_MOZ_URL) ? data.title : data.uri; - return this.ptm.createItem(this._uri(data.uri), container, index, + return this.ptm.createItem(IO.newURI(data.uri), container, index, title); } return null; @@ -892,7 +862,6 @@ var PlacesUtils = { var result = this.history.executeQuery(query, options); result.root.containerOpen = true; - asContainer(result.root); return result; }, @@ -1270,7 +1239,7 @@ var PlacesUtils = { */ checkURLSecurity: function PU_checkURLSecurity(aURINode) { if (!this.nodeIsBookmark(aURINode)) { - var uri = this._uri(aURINode.uri); + var uri = IO.newURI(aURINode.uri); if (uri.schemeIs("javascript") || uri.schemeIs("data")) { const BRANDING_BUNDLE_URI = "chrome://branding/locale/brand.properties"; var brandShortName = Cc["@mozilla.org/intl/stringbundle;1"]. @@ -1557,15 +1526,27 @@ var PlacesUtils = { } } else { - let wasOpen = aNode.containerOpen; - if (!wasOpen) - aNode.containerOpen = true; - for (let i = 0; i < aNode.childCount; ++i) { - let child = aNode.getChild(i); - if (this.nodeIsURI(child)) - urls.push(child.uri); + let result, oldViewer; + try { + let wasOpen = aNode.containerOpen; + if (!wasOpen) { + result = aNode.parentResult; + oldViewer = result.viewer; + result.viewer = null; + aNode.containerOpen = true; + } + for (let i = 0; i < aNode.childCount; ++i) { + let child = aNode.getChild(i); + if (this.nodeIsURI(child)) + urls.push(child.uri); + } + if (!wasOpen) + aNode.containerOpen = false; + } + finally { + if (oldViewer) + result.viewer = oldViewer; } - aNode.containerOpen = wasOpen; } return urls; @@ -1646,22 +1627,70 @@ var PlacesUtils = { this._openTabset(urlsToOpen, aEvent); }, - _placesFlavors: null, get placesFlavors() { - if (!this._placesFlavors) { - var placeTypes = [PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER, - PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR, - PlacesUtils.TYPE_X_MOZ_PLACE]; - this._placesFlavors = Cc["@mozilla.org/supports-array;1"]. - createInstance(Ci.nsISupportsArray); - for (var i = 0; i < placeTypes.length; ++i) { - var cstring = Cc["@mozilla.org/supports-cstring;1"]. - createInstance(Ci.nsISupportsCString); - cstring.data = placeTypes[i]; - this._placesFlavors.AppendElement(cstring); - } + delete this.placesFlavors; + var placeTypes = [PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER, + PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR, + PlacesUtils.TYPE_X_MOZ_PLACE]; + this.placesFlavors = Cc["@mozilla.org/supports-array;1"]. + createInstance(Ci.nsISupportsArray); + for (var i = 0; i < placeTypes.length; ++i) { + var cstring = Cc["@mozilla.org/supports-cstring;1"]. + createInstance(Ci.nsISupportsCString); + cstring.data = placeTypes[i]; + this.placesFlavors.AppendElement(cstring); } - return this._placesFlavors; + return this.placesFlavors; + }, + + /** + * Helper for the toolbar and menu views + */ + createMenuItemForNode: function(aNode, aContainersMap) { + var element; + var type = aNode.type; + if (type == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR) + element = document.createElement("menuseparator"); + else { + var iconURI = aNode.icon; + var iconURISpec = ""; + if (iconURI) + iconURISpec = iconURI.spec; + + if (this.uriTypes.indexOf(type) != -1) { + element = document.createElement("menuitem"); + element.setAttribute("statustext", aNode.uri); + element.className = "menuitem-iconic bookmark-item"; + } + else if (this.containerTypes.indexOf(type) != -1) { + element = document.createElement("menu"); + element.setAttribute("container", "true"); + + if (iconURISpec == "chrome://browser/skin/places/livemarkItem.png") + element.setAttribute("livemark", "true"); + + var popup = document.createElement("menupopup"); + popup._resultNode = asContainer(aNode); +#ifndef XP_MACOSX + // no context menu on mac + popup.setAttribute("context", "placesContext"); +#endif + element.appendChild(popup); + if (aContainersMap) + aContainersMap.push({ resultNode: aNode, domNode: popup }); + element.className = "menu-iconic bookmark-item"; + } + else + throw "Unexpected node"; + + element.setAttribute("label", aNode.title); + if (iconURISpec) + element.setAttribute("image", iconURISpec); + } + element.node = aNode; + element.node.viewIndex = 0; + + return element; } }; diff --git a/browser/components/places/src/nsPlacesImportExportService.cpp b/browser/components/places/src/nsPlacesImportExportService.cpp index b9e92d14ddd7..7c805f12d1cb 100644 --- a/browser/components/places/src/nsPlacesImportExportService.cpp +++ b/browser/components/places/src/nsPlacesImportExportService.cpp @@ -121,11 +121,13 @@ static NS_DEFINE_CID(kParserCID, NS_PARSER_CID); #define KEY_MICSUM_GEN_URI_LOWER "micsum_gen_uri" #define KEY_DATE_ADDED_LOWER "add_date" #define KEY_LAST_MODIFIED_LOWER "last_modified" +#define KEY_GENERATED_TITLE_LOWER "generated_title" #define LOAD_IN_SIDEBAR_ANNO NS_LITERAL_CSTRING("bookmarkProperties/loadInSidebar") #define DESCRIPTION_ANNO NS_LITERAL_CSTRING("bookmarkProperties/description") #define POST_DATA_ANNO NS_LITERAL_CSTRING("URIProperties/POSTData") #define LAST_CHARSET_ANNO NS_LITERAL_CSTRING("URIProperties/characterSet") +#define STATIC_TITLE_ANNO NS_LITERAL_CSTRING("bookmarks/staticTitle") #define BOOKMARKS_MENU_ICON_URI "chrome://browser/skin/places/bookmarksMenu.png" @@ -208,6 +210,13 @@ public: // and the livemark title is known, we can create it. nsCOMPtr mPreviousFeed; + // contains the text content of the previous microsummary, so that when the + // link ends, we can replace the bookmark's title with it and store the user's + // title in the staticTitle annotation. + nsString mPreviousMicrosummaryText; + + nsCOMPtr mPreviousMicrosummary; + void ConsumeHeading(nsAString* aHeading, ContainerType* aContainerType) { *aHeading = mPreviousText; @@ -791,6 +800,10 @@ BookmarkContentSink::HandleLinkBegin(const nsIParserNode& node) // mPreviousText will hold our link text, clear it so that can be appended to frame.mPreviousText.Truncate(); + + // Empty our microsummary items from the previous frame. + frame.mPreviousMicrosummary = nsnull; + frame.mPreviousMicrosummaryText.Truncate(); // get the attributes we care about nsAutoString href; @@ -803,6 +816,7 @@ BookmarkContentSink::HandleLinkBegin(const nsIParserNode& node) nsAutoString webPanel; nsAutoString itemId; nsAutoString micsumGenURI; + nsAutoString generatedTitle; nsAutoString dateAdded; nsAutoString lastModified; @@ -827,6 +841,8 @@ BookmarkContentSink::HandleLinkBegin(const nsIParserNode& node) webPanel = node.GetValueAt(i); } else if (key.LowerCaseEqualsLiteral(KEY_MICSUM_GEN_URI_LOWER)) { micsumGenURI = node.GetValueAt(i); + } else if (key.LowerCaseEqualsLiteral(KEY_GENERATED_TITLE_LOWER)) { + generatedTitle = node.GetValueAt(i); } else if (key.LowerCaseEqualsLiteral(KEY_DATE_ADDED_LOWER)) { dateAdded = node.GetValueAt(i); } else if (key.LowerCaseEqualsLiteral(KEY_LAST_MODIFIED_LOWER)) { @@ -843,6 +859,7 @@ BookmarkContentSink::HandleLinkBegin(const nsIParserNode& node) webPanel.Trim(kWhitespace); itemId.Trim(kWhitespace); micsumGenURI.Trim(kWhitespace); + generatedTitle.Trim(kWhitespace); dateAdded.Trim(kWhitespace); lastModified.Trim(kWhitespace); @@ -946,15 +963,12 @@ BookmarkContentSink::HandleLinkBegin(const nsIParserNode& node) } // import microsummary - // Note: expiration and generated title are ignored, and will be recalculated - // by the microsummary service if (!micsumGenURI.IsEmpty()) { nsCOMPtr micsumGenURIObject; if (NS_SUCCEEDED(NS_NewURI(getter_AddRefs(micsumGenURIObject), micsumGenURI))) { - nsCOMPtr microsummary; mMicrosummaryService->CreateMicrosummary(frame.mPreviousLink, micsumGenURIObject, - getter_AddRefs(microsummary)); - mMicrosummaryService->SetMicrosummary(frame.mPreviousId, microsummary); + getter_AddRefs(frame.mPreviousMicrosummary)); + frame.mPreviousMicrosummaryText = generatedTitle; } } @@ -1048,7 +1062,17 @@ BookmarkContentSink::HandleLinkEnd() printf("Creating bookmark '%s' %lld\n", NS_ConvertUTF16toUTF8(frame.mPreviousText).get(), frame.mPreviousId); #endif - mBookmarksService->SetItemTitle(frame.mPreviousId, frame.mPreviousText); + if (frame.mPreviousMicrosummary) { + rv = mAnnotationService->SetItemAnnotationString(frame.mPreviousId, STATIC_TITLE_ANNO, + frame.mPreviousText, 0, + nsIAnnotationService::EXPIRE_NEVER); + NS_ASSERTION(NS_SUCCEEDED(rv), "Could not store user's bookmark title!"); + + mBookmarksService->SetItemTitle(frame.mPreviousId, frame.mPreviousMicrosummaryText); + mMicrosummaryService->SetMicrosummary(frame.mPreviousId, frame.mPreviousMicrosummary); + } + else + mBookmarksService->SetItemTitle(frame.mPreviousId, frame.mPreviousText); } // Set last-modified-date for bookmarks and livemarks here so that the diff --git a/browser/components/preferences/applications.js b/browser/components/preferences/applications.js index 8006850cde38..97e535d4a28b 100755 --- a/browser/components/preferences/applications.js +++ b/browser/components/preferences/applications.js @@ -718,6 +718,14 @@ var feedHandlerInfo = { this.element(PREF_FEED_SELECTED_ACTION).value = "reader"; }, + // Whether or not we are currently storing the action selected by the user. + // We use this to suppress notification-triggered updates to the list when + // we make changes that may spawn such updates, specifically when we change + // the action for the feed type, which results in feed preference updates, + // which spawn "pref changed" notifications that would otherwise cause us + // to rebuild the view unnecessarily. + _storingAction: false, + //**************************************************************************// // nsIMIMEInfo @@ -881,7 +889,7 @@ var gApplicationsPane = { observe: function (aSubject, aTopic, aData) { // Rebuild the list when there are changes to preferences that influence // whether or not to show certain entries in the list. - if (aTopic == "nsPref:changed") { + if (aTopic == "nsPref:changed" && !this._storingAction) { // These two prefs alter the list of visible types, so we have to rebuild // that list when they change. if (aData == PREF_SHOW_PLUGINS_IN_LIST || @@ -1450,6 +1458,17 @@ var gApplicationsPane = { // Changes onSelectAction: function(aActionItem) { + this._storingAction = true; + + try { + this._storeAction(aActionItem); + } + finally { + this._storingAction = false; + } + }, + + _storeAction: function(aActionItem) { var typeItem = this._list.selectedItem; var handlerInfo = this._handledTypes[typeItem.type]; @@ -1499,13 +1518,43 @@ var gApplicationsPane = { // as we handle it specially ourselves. aEvent.stopPropagation(); + var handlerApp; + +#ifdef XP_WIN + var params = {}; + var handlerInfo = this._handledTypes[this._list.selectedItem.type]; + + if (handlerInfo.type == TYPE_MAYBE_FEED) { + // MIME info will be null, create a temp object. + params.mimeInfo = this._mimeSvc.getFromTypeAndExtension(handlerInfo.type, + handlerInfo.primaryExtension); + } else { + params.mimeInfo = handlerInfo.wrappedHandlerInfo; + } + + params.title = this._prefsBundle.getString("fpTitleChooseApp"); + params.description = handlerInfo.description; + params.filename = null; + params.handlerApp = null; + + window.openDialog("chrome://global/content/appPicker.xul", null, + "chrome,modal,centerscreen,titlebar,dialog=yes", + params); + + if (params.handlerApp && + params.handlerApp.executable && + params.handlerApp.executable.isFile()) { + handlerApp = params.handlerApp; + + // Add the app to the type's list of possible handlers. + handlerInfo.possibleApplicationHandlers.appendElement(handlerApp, false); + } +#else var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); var winTitle = this._prefsBundle.getString("fpTitleChooseApp"); fp.init(window, winTitle, Ci.nsIFilePicker.modeOpen); fp.appendFilters(Ci.nsIFilePicker.filterApps); - var handlerApp; - // Prompt the user to pick an app. If they pick one, and it's a valid // selection, then add it to the list of possible handlers. if (fp.show() == Ci.nsIFilePicker.returnOK && fp.file && @@ -1519,6 +1568,7 @@ var gApplicationsPane = { let handlerInfo = this._handledTypes[this._list.selectedItem.type]; handlerInfo.possibleApplicationHandlers.appendElement(handlerApp, false); } +#endif // Rebuild the actions menu whether the user picked an app or canceled. // If they picked an app, we want to add the app to the menu and select it. diff --git a/browser/components/preferences/preferences.xul b/browser/components/preferences/preferences.xul index 2f5675e1a513..a2a672a3cfd9 100644 --- a/browser/components/preferences/preferences.xul +++ b/browser/components/preferences/preferences.xul @@ -85,7 +85,7 @@ style="&prefWin.styleWin;"> #else #ifdef XP_MACOSX - style="&prefWindow.styleMac;"> + style="&prefWin.styleMac;"> #else style="&prefWin.styleGNOME;"> #endif diff --git a/browser/components/preferences/security.js b/browser/components/preferences/security.js index 7a2b7c573616..ba264031fe42 100644 --- a/browser/components/preferences/security.js +++ b/browser/components/preferences/security.js @@ -234,9 +234,9 @@ var gSecurityPane = { var popup = document.getElementById(onloadPopupId); if (!popup) { - var providerBranch = Cc["@mozilla.org/preferences-service;1"] - .getService(Ci.nsIPrefService) - .getBranch("browser.safebrowsing.provider."); + var providerBranch = Cc["@mozilla.org/preferences-service;1"]. + getService(Ci.nsIPrefService). + getBranch("browser.safebrowsing.provider."); // fill in onload phishing list data -- but require a privacy policy // URL be provided, and require it to be at a chrome URL so it's always @@ -374,8 +374,8 @@ var gSecurityPane = { _masterPasswordSet: function () { const Cc = Components.classes, Ci = Components.interfaces; - var secmodDB = Cc["@mozilla.org/security/pkcs11moduledb;1"] - .getService(Ci.nsIPKCS11ModuleDB); + var secmodDB = Cc["@mozilla.org/security/pkcs11moduledb;1"]. + getService(Ci.nsIPKCS11ModuleDB); var slot = secmodDB.findSlotByName(""); if (slot) { var status = slot.status; @@ -419,9 +419,12 @@ var gSecurityPane = { */ _removeMasterPassword: function () { - var secmodDB = Components.classes["@mozilla.org/security/pkcs11moduledb;1"] - .getService(Components.interfaces.nsIPKCS11ModuleDB); + const Cc = Components.classes, Ci = Components.interfaces; + var secmodDB = Cc["@mozilla.org/security/pkcs11moduledb;1"]. + getService(Ci.nsIPKCS11ModuleDB); if (secmodDB.isFIPSEnabled) { + var promptService = Cc["@mozilla.org/embedcomp/prompt-service;1"]. + getService(Ci.nsIPromptService); var bundle = document.getElementById("bundlePreferences"); promptService.alert(window, bundle.getString("pw_change_failed_title"), diff --git a/browser/components/safebrowsing/content/application.js b/browser/components/safebrowsing/content/application.js index bce52af2ba46..31c8460c17a1 100644 --- a/browser/components/safebrowsing/content/application.js +++ b/browser/components/safebrowsing/content/application.js @@ -38,8 +38,8 @@ var gDataProvider = null; // An instance of our application is a PROT_Application object. It -// basically just populates a few globals and instantiates wardens and -// the listmanager. +// basically just populates a few globals and instantiates wardens, +// the listmanager, and the about:blocked error page. /** * An instance of our application. There should be exactly one of these. @@ -100,3 +100,30 @@ function PROT_Application() { PROT_Application.prototype.getReportURL = function(name) { return gDataProvider["getReport" + name + "URL"](); } + +/** + * about:blocked implementation + */ +PROT_Application.prototype.newChannel = function(uri) { + var ioService = Cc["@mozilla.org/network/io-service;1"] + .getService(Ci.nsIIOService); + var childURI = ioService.newURI("chrome://browser/content/safebrowsing/blockedSite.xhtml", + null, null); + var channel = ioService.newChannelFromURI(childURI); + channel.originalURI = uri; + + return channel; +} + +PROT_Application.prototype.getURIFlags = function(uri) { + return Ci.nsIAboutModule.ALLOW_SCRIPT; +} + +PROT_Application.prototype.QueryInterface = function(iid) { + if (iid.equals(Ci.nsISupports) || + iid.equals(Ci.nsIAboutModule)) + return this; + + Components.returnCode = Components.results.NS_ERROR_NO_INTERFACE; + return null; +} diff --git a/browser/components/safebrowsing/content/blockedSite.xhtml b/browser/components/safebrowsing/content/blockedSite.xhtml new file mode 100644 index 000000000000..63a145e14c85 --- /dev/null +++ b/browser/components/safebrowsing/content/blockedSite.xhtml @@ -0,0 +1,210 @@ + + + + %htmlDTD; + + %globalDTD; + + %brandDTD; + + %blockedSiteDTD; +]> + + + + + + + + + + + + +
+ + +
+

+

+ +
+ + +
+

+

+ + +
+

+

+ + +
+ +
+
+
+ + + + diff --git a/browser/components/safebrowsing/content/malware-warden.js b/browser/components/safebrowsing/content/malware-warden.js index a201816fb082..9363e8020abc 100644 --- a/browser/components/safebrowsing/content/malware-warden.js +++ b/browser/components/safebrowsing/content/malware-warden.js @@ -64,6 +64,13 @@ function PROT_MalwareWarden() { "a:1:" + testData.length + "\n" + testData + "\n"; + + testData = "mozilla.com/firefox/its-a-trap.html"; + testUpdate += + "n:1000\ni:test-phish-simple\nad:1\n" + + "a:1:" + testData.length + "\n" + + testData + + "\n"; var dbService_ = Cc["@mozilla.org/url-classifier/dbservice;1"] .getService(Ci.nsIUrlClassifierDBService); diff --git a/browser/components/safebrowsing/content/phishing-afterload-displayer.js b/browser/components/safebrowsing/content/phishing-afterload-displayer.js index a0b3ecf33989..0fbb7e7abca2 100644 --- a/browser/components/safebrowsing/content/phishing-afterload-displayer.js +++ b/browser/components/safebrowsing/content/phishing-afterload-displayer.js @@ -208,7 +208,6 @@ PROT_PhishMsgDisplayerBase.prototype.browserSelected = function() { this.messageShouldShow_ = true; } - this.hideLockIcon_(); // Comes back when we are unselected or unloaded this.addWarningInUrlbar_(); // Goes away when we are unselected or unloaded // messageShouldShow might be false if the user dismissed the warning, @@ -234,7 +233,6 @@ PROT_PhishMsgDisplayerBase.prototype.explicitShow = function() { */ PROT_PhishMsgDisplayerBase.prototype.browserUnselected = function() { this.removeWarningInUrlbar_(); - this.unhideLockIcon_(); if (this.messageShowing_) this.hideMessage_(); } @@ -290,7 +288,6 @@ PROT_PhishMsgDisplayerBase.prototype.done = function() { // If we were started, we must be the current problem, so these things // must be showing this.removeWarningInUrlbar_(); - this.unhideLockIcon_(); // Could be though that they've closed the warning dialog if (this.messageShowing_) @@ -327,28 +324,6 @@ PROT_PhishMsgDisplayerBase.prototype.removeIfExists_ = function(orig, return orig; } -/** - * We don't want to confuse users if they land on a phishy page that uses - * SSL, so ensure that the lock icon never shows when we're showing our - * warning. - */ -PROT_PhishMsgDisplayerBase.prototype.hideLockIcon_ = function() { - var lockIcon = this.doc_.getElementById("lock-icon"); - if (!lockIcon) - return; - lockIcon.hidden = true; -} - -/** - * Ensure they can see it after our warning is finished. - */ -PROT_PhishMsgDisplayerBase.prototype.unhideLockIcon_ = function() { - var lockIcon = this.doc_.getElementById("lock-icon"); - if (!lockIcon) - return; - lockIcon.hidden = false; -} - /** * This method makes our warning icon visible in the location bar. It will * be removed only when the problematic document is navigated awy from @@ -557,26 +532,7 @@ PROT_PhishMsgDisplayerCanvas.inherits(PROT_PhishMsgDisplayerBase); * Displays the warning message. First we make sure the overlay is loaded * then call showMessageAfterOverlay_. */ -PROT_PhishMsgDisplayerCanvas.prototype.showMessage_ = function() { - G_Debug(this, "Showing message."); - - // Load the overlay if we haven't already. - var dimmer = this.doc_.getElementById('safebrowsing-dim-area-canvas'); - if (!dimmer) { - var onOverlayMerged = BindToObject(this.showMessageAfterOverlay_, - this); - var observer = new G_ObserverWrapper("xul-overlay-merged", - onOverlayMerged); - - this.doc_.loadOverlay( - "chrome://browser/content/safebrowsing/warning-overlay.xul", - observer); - } else { - // The overlay is already loaded so we go ahead and call - // showMessageAfterOverlay_. - this.showMessageAfterOverlay_(); - } -} +PROT_PhishMsgDisplayerCanvas.prototype.showMessage_ = function() { } /** * This does the actual work of showing the warning message. @@ -703,34 +659,7 @@ PROT_PhishMsgDisplayerCanvas.prototype.isVisibleElement_ = function(elt) { /** * Hide the warning message from the user. */ -PROT_PhishMsgDisplayerCanvas.prototype.hideMessage_ = function() { - G_Debug(this, "Hiding phishing warning."); - G_Assert(this, this.messageShowing_, "Hide message called but not showing?"); - - this.messageShowing_ = false; - this.repainter_.cancel(); - this.repainter_ = null; - - // Hide the warning popup. - var message = this.doc_.getElementById(this.messageId_); - message.hidden = true; - message.style.display = "none"; - var content = this.doc_.getElementById(this.messageContentId_); - content.style.height = ""; - content.style.overflow = ""; - - var tail = this.doc_.getElementById(this.messageTailId_); - tail.hidden = true; - tail.style.display = "none"; - - // Remove the canvas element from the chrome document. - var pageCanvas = this.doc_.getElementById(this.pageCanvasId_); - pageCanvas.parentNode.removeChild(pageCanvas); - - // Hide the dimmer. - var dimarea = this.doc_.getElementById(this.dimAreaId_); - dimarea.hidden = true; -} +PROT_PhishMsgDisplayerCanvas.prototype.hideMessage_ = function() { } /** diff --git a/browser/components/safebrowsing/jar.mn b/browser/components/safebrowsing/jar.mn index 2c7212856c97..51d7b8653dd6 100644 --- a/browser/components/safebrowsing/jar.mn +++ b/browser/components/safebrowsing/jar.mn @@ -3,4 +3,5 @@ browser.jar: * content/browser/safebrowsing/sb-loader.js (content/sb-loader.js) + content/browser/safebrowsing/warning-overlay.xul (content/warning-overlay.xul) + content/browser/safebrowsing/report-phishing-overlay.xul (content/report-phishing-overlay.xul) ++ content/browser/safebrowsing/blockedSite.xhtml (content/blockedSite.xhtml) % overlay chrome://browser/content/browser.xul chrome://browser/content/safebrowsing/report-phishing-overlay.xul diff --git a/browser/components/safebrowsing/src/nsSafebrowsingApplication.js b/browser/components/safebrowsing/src/nsSafebrowsingApplication.js index 4649cdf6166e..570753c0f41c 100644 --- a/browser/components/safebrowsing/src/nsSafebrowsingApplication.js +++ b/browser/components/safebrowsing/src/nsSafebrowsingApplication.js @@ -61,6 +61,13 @@ SafebrowsingApplicationMod.prototype.registerSelf = function(compMgr, fileSpec, fileSpec, loc, type); + + compMgr.registerFactoryLocation(this.cid, + "UrlClassifier Blocked Error Page", + "@mozilla.org/network/protocol/about;1?what=blocked", + fileSpec, + loc, + type); }; SafebrowsingApplicationMod.prototype.getClassObject = function(compMgr, cid, iid) { diff --git a/browser/components/sessionstore/src/nsSessionStore.js b/browser/components/sessionstore/src/nsSessionStore.js index 3b1d8bfdf8f0..610c53ee3920 100644 --- a/browser/components/sessionstore/src/nsSessionStore.js +++ b/browser/components/sessionstore/src/nsSessionStore.js @@ -1979,7 +1979,11 @@ SessionStoreService.prototype = { var cr = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsICrashReporter); cr.annotateCrashReport("URL", currentUrl); } - catch (ex) { debug(ex); } + catch (ex) { + // don't make noise when crashreporter is built but not enabled + if (ex.result != Components.results.NS_ERROR_NOT_INITIALIZED) + debug(ex); + } }, /** diff --git a/browser/installer/windows/nsis/installer.nsi b/browser/installer/windows/nsis/installer.nsi index 00bcf0995a0a..bb3b796a1ff1 100755 --- a/browser/installer/windows/nsis/installer.nsi +++ b/browser/installer/windows/nsis/installer.nsi @@ -35,9 +35,9 @@ # ***** END LICENSE BLOCK ***** # Required Plugins: -# SetVistaDefaultApp http://nsis.sourceforge.net/SetVistaDefaultApp_plug-in -# ShellLink http://nsis.sourceforge.net/ShellLink_plug-in -# UAC http://nsis.sourceforge.net/UAC_plug-in +# AppAssocReg http://nsis.sourceforge.net/Application_Association_Registration_plug-in +# ShellLink http://nsis.sourceforge.net/ShellLink_plug-in +# UAC http://nsis.sourceforge.net/UAC_plug-in ; Set verbosity to 3 (e.g. no script) to lessen the noise in the build logs !verbose 3 @@ -110,14 +110,18 @@ VIAddVersionKey "FileDescription" "${BrandShortName} Installer" !insertmacro _LoggingCommon !insertmacro AddDDEHandlerValues +!insertmacro ChangeMUIHeaderImage !insertmacro CloseApp !insertmacro CreateRegKey !insertmacro GetPathFromString +!insertmacro GetParent !insertmacro IsHandlerForInstallDir !insertmacro ManualCloseAppPrompt !insertmacro RegCleanAppHandler !insertmacro RegCleanMain !insertmacro RegCleanUninstall +!insertmacro SetBrandNameVars +!insertmacro UnloadUAC !insertmacro WriteRegStr2 !insertmacro WriteRegDWORD2 @@ -129,6 +133,7 @@ VIAddVersionKey "FileDescription" "${BrandShortName} Installer" !insertmacro InstallOnInitCommon !insertmacro InstallStartCleanupCommon !insertmacro LeaveDirectoryCommon +!insertmacro OnEndCommon !insertmacro PreDirectoryCommon Name "${BrandFullName}" @@ -164,9 +169,11 @@ ReserveFile summary.ini * Installation Pages */ ; Welcome Page +!define MUI_PAGE_CUSTOMFUNCTION_PRE preWelcome !insertmacro MUI_PAGE_WELCOME ; License Page +!define MUI_PAGE_CUSTOMFUNCTION_SHOW showLicense !define MUI_LICENSEPAGE_CHECKBOX !insertmacro MUI_PAGE_LICENSE license.rtf @@ -217,7 +224,7 @@ Section "-InstallStartCleanup" DetailPrint $(STATUS_CLEANUP) SetDetailsPrint none - SetOutPath $INSTDIR + SetOutPath "$INSTDIR" ${StartInstallLog} "${BrandFullName}" "${AB_CD}" "${AppVersion}" "${GREVersion}" ; Try to delete the app's main executable and if we can't delete it try to @@ -229,8 +236,8 @@ Section "-InstallStartCleanup" ; Create a temporary backup directory. GetTempFileName $TmpVal "$TEMP" - ${DeleteFile} $TmpVal - SetOutPath $TmpVal + ${DeleteFile} "$TmpVal" + SetOutPath "$TmpVal" ${If} ${FileExists} "$INSTDIR\${FileMainEXE}" ClearErrors @@ -266,7 +273,7 @@ Section "-InstallStartCleanup" StrCpy $R1 "xpicleanup.exe" Call CheckInUse - SetOutPath $INSTDIR + SetOutPath "$INSTDIR" RmDir /r "$TmpVal" ClearErrors @@ -389,6 +396,11 @@ Section "-Application" APP_IDX StrCpy $TmpVal "HKLM" ; used primarily for logging ${RegCleanMain} "Software\Mozilla" ${RegCleanUninstall} + + ReadRegStr $0 HKLM "Software\mozilla.org\Mozilla" "CurrentVersion" + ${If} "$0" != "${GREVersion}" + WriteRegStr HKLM "Software\mozilla.org\Mozilla" "CurrentVersion" "${GREVersion}" + ${EndIf} ${EndIf} ${RemoveDeprecatedKeys} @@ -533,8 +545,9 @@ Function CheckInUse MessageBox MB_RETRYCANCEL|MB_ICONQUESTION "$0" IDRETRY retry Delete "$TmpVal\$R1" CopyFiles /SILENT "$TmpVal\*" "$INSTDIR\" - SetOutPath $INSTDIR + SetOutPath "$INSTDIR" RmDir /r "$TmpVal" + ${OnEndCommon} Quit ${EndIf} ${EndIf} @@ -612,19 +625,16 @@ Function CopyFile FunctionEnd Function LaunchApp + ClearErrors ${GetParameters} $0 - ${If} $0 != "" - ClearErrors - ${GetOptions} "$0" "/UAC:" $1 - ${Unless} ${Errors} - GetFunctionAddress $0 LaunchAppFromElevatedProcess - UAC::ExecCodeSegment $0 - Quit - ${EndUnless} + ${GetOptions} "$0" "/UAC:" $1 + ${If} ${Errors} + ${ManualCloseAppPrompt} "${WindowClass}" "$(WARN_MANUALLY_CLOSE_APP_LAUNCH)" + Exec "$INSTDIR\${FileMainEXE}" + ${Else} + GetFunctionAddress $0 LaunchAppFromElevatedProcess + UAC::ExecCodeSegment $0 ${EndIf} - - ${ManualCloseAppPrompt} "${WindowClass}" "$(WARN_MANUALLY_CLOSE_APP_LAUNCH)" - Exec "$INSTDIR\${FileMainEXE}" FunctionEnd Function LaunchAppFromElevatedProcess @@ -635,6 +645,10 @@ Function LaunchAppFromElevatedProcess ${StrFilter} "${FileMainEXE}" "+" "" "" $R9 ReadRegStr $0 HKLM "Software\Clients\StartMenuInternet\$R9\DefaultIcon" "" ${GetPathFromString} "$0" $0 + ${GetParent} "$0" $1 + ; Set our current working directory to the application's install directory + ; otherwise the 7-Zip temp directory will be in use and won't be deleted. + SetOutPath "$1" Exec "$0" FunctionEnd @@ -653,7 +667,23 @@ FunctionEnd BrandingText " " ################################################################################ -# Page pre and leave functions +# Page pre, show, and leave functions + +Function preWelcome + ${If} ${FileExists} "$EXEDIR\localized\distribution\modern-wizard.bmp" + Delete "$PLUGINSDIR\modern-wizard.bmp" + CopyFiles /SILENT "$EXEDIR\localized\distribution\modern-wizard.bmp" "$PLUGINSDIR\modern-wizard.bmp" + ${EndIf} +FunctionEnd + +Function showLicense + ${If} ${FileExists} "$EXEDIR\localized\distribution\modern-header.bmp" + ${AndIf} $hHeaderBitmap == "" + Delete "$PLUGINSDIR\modern-header.bmp" + CopyFiles /SILENT "$EXEDIR\localized\distribution\modern-header.bmp" "$PLUGINSDIR\modern-header.bmp" + ${ChangeMUIHeaderImage} "$PLUGINSDIR\modern-header.bmp" + ${EndIf} +FunctionEnd Function preOptions !insertmacro MUI_HEADER_TEXT "$(OPTIONS_PAGE_TITLE)" "$(OPTIONS_PAGE_SUBTITLE)" @@ -758,6 +788,9 @@ FunctionEnd # Initialization Functions Function .onInit + StrCpy $LANGUAGE 0 + ${SetBrandNameVars} "$EXEDIR\localized\distribution\setup.ini" + ${InstallOnInitCommon} "$(WARN_UNSUPPORTED_MSG)" !insertmacro MUI_INSTALLOPTIONS_EXTRACT "options.ini" @@ -768,8 +801,6 @@ Function .onInit !insertmacro createComponentsINI !insertmacro createShortcutsINI - StrCpy $LANGUAGE 0 - ; There must always be nonlocalized and localized directories. ${GetSize} "$EXEDIR\nonlocalized\" "/S=0K" $R5 $R7 $R8 ${GetSize} "$EXEDIR\localized\" "/S=0K" $R6 $R7 $R8 @@ -784,12 +815,12 @@ Function .onInit ; Hide DOMi in the components page if it isn't available. SectionSetText ${DOMI_IDX} "" ${EndIf} + + ; Initialize $hHeaderBitmap to prevent redundant changing of the bitmap if + ; the user clicks the back button + StrCpy $hHeaderBitmap "" FunctionEnd -Function .OnInstFailed - UAC::Unload -FunctionEnd - -Function .OnInstSuccess - UAC::Unload +Function .onGUIEnd + ${OnEndCommon} FunctionEnd diff --git a/browser/installer/windows/nsis/shared.nsh b/browser/installer/windows/nsis/shared.nsh index 41d81d8243ea..9a439f88d127 100755 --- a/browser/installer/windows/nsis/shared.nsh +++ b/browser/installer/windows/nsis/shared.nsh @@ -55,6 +55,11 @@ ${SetStartMenuInternet} ${FixShellIconHandler} ${SetUninstallKeys} + + ReadRegStr $0 HKLM "Software\mozilla.org\Mozilla" "CurrentVersion" + ${If} "$0" != "${GREVersion}" + WriteRegStr HKLM "Software\mozilla.org\Mozilla" "CurrentVersion" "${GREVersion}" + ${EndIf} ${EndIf} ${RemoveDeprecatedKeys} @@ -110,7 +115,7 @@ ; Only register as the handler on Vista if the app registry name exists ; under the RegisteredApplications registry key. ${Unless} ${Errors} - SetVistaDefaultApp::SetAsDefault "${AppRegName}" + AppAssocReg::SetAppAsDefaultAll "${AppRegName}" ${EndUnless} ${EndIf} !endif diff --git a/browser/installer/windows/nsis/uninstaller.nsi b/browser/installer/windows/nsis/uninstaller.nsi index 4f819ac56a40..f5517e200e31 100755 --- a/browser/installer/windows/nsis/uninstaller.nsi +++ b/browser/installer/windows/nsis/uninstaller.nsi @@ -35,9 +35,9 @@ # ***** END LICENSE BLOCK ***** # Required Plugins: -# SetVistaDefaultApp http://nsis.sourceforge.net/SetVistaDefaultApp_plug-in -# ShellLink http://nsis.sourceforge.net/ShellLink_plug-in -# UAC http://nsis.sourceforge.net/UAC_plug-in +# AppAssocReg http://nsis.sourceforge.net/Application_Association_Registration_plug-in +# ShellLink http://nsis.sourceforge.net/ShellLink_plug-in +# UAC http://nsis.sourceforge.net/UAC_plug-in ; Set verbosity to 3 (e.g. no script) to lessen the noise in the build logs !verbose 3 @@ -62,10 +62,10 @@ Var TmpVal ; The following includes are provided by NSIS. !include FileFunc.nsh !include LogicLib.nsh +!include MUI.nsh !include TextFunc.nsh !include WinMessages.nsh !include WordFunc.nsh -!include MUI.nsh ; WinVer.nsh was added in the same release that RequestExecutionLevel so check ; if ___WINVER__NSH___ is defined to determine if RequestExecutionLevel is @@ -74,7 +74,7 @@ Var TmpVal !ifdef ___WINVER__NSH___ RequestExecutionLevel user !else - !warning "Uninstaller will be created without Vista compatibility.$\n \ + !warning "Installer will be created without Vista compatibility.$\n \ Upgrade your NSIS installation to at least version 2.22 to resolve." !endif @@ -104,10 +104,13 @@ VIAddVersionKey "FileDescription" "${BrandShortName} Helper" !insertmacro RegCleanAppHandler !insertmacro RegCleanMain !insertmacro RegCleanUninstall +!insertmacro UnloadUAC !insertmacro WriteRegDWORD2 !insertmacro WriteRegStr2 +!insertmacro un.ChangeMUIHeaderImage !insertmacro un.CleanVirtualStore +!insertmacro un.DeleteRelativeProfiles !insertmacro un.GetLongPath !insertmacro un.GetSecondInstallPath !insertmacro un.ManualCloseAppPrompt @@ -118,12 +121,16 @@ VIAddVersionKey "FileDescription" "${BrandShortName} Helper" !insertmacro un.RegCleanUninstall !insertmacro un.RegCleanProtocolHandler !insertmacro un.RemoveQuotesFromPath +!insertmacro un.SetBrandNameVars !include shared.nsh ; Helper macros for ui callbacks. Insert these after shared.nsh +!insertmacro OnEndCommon !insertmacro UninstallOnInitCommon +!insertmacro un.OnEndCommon + Name "${BrandFullName}" OutFile "helper.exe" InstallDirRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${BrandFullNameInternal} (${AppVersion})" "InstallLocation" @@ -152,11 +159,11 @@ ShowUnInstDetails nevershow * Uninstall Pages */ ; Welcome Page +!define MUI_PAGE_CUSTOMFUNCTION_PRE un.preWelcome !insertmacro MUI_UNPAGE_WELCOME ; Uninstall Confirm Page -!define MUI_PAGE_CUSTOMFUNCTION_LEAVE un.leaveConfirm -!insertmacro MUI_UNPAGE_CONFIRM +UninstPage custom un.preConfirm un.leaveConfirm ; Remove Files Page !insertmacro MUI_UNPAGE_INSTFILES @@ -201,6 +208,11 @@ Section "Uninstall" ClearErrors ${EndIf} + ${MUI_INSTALLOPTIONS_READ} $0 "unconfirm.ini" "Field 3" "State" + ${If} "$0" == "1" + ${un.DeleteRelativeProfiles} "Mozilla\Firefox" + ${EndIf} + SetShellVarContext current ; Set SHCTX to HKCU ${un.RegCleanMain} "Software\Mozilla" ${un.RegCleanUninstall} @@ -354,10 +366,50 @@ FunctionEnd BrandingText " " ################################################################################ -# Page pre and leave functions +# Page pre, show, and leave functions + +Function un.preWelcome + ${If} ${FileExists} "$INSTDIR\distribution\modern-wizard.bmp" + Delete "$PLUGINSDIR\modern-wizard.bmp" + CopyFiles /SILENT "$INSTDIR\distribution\modern-wizard.bmp" "$PLUGINSDIR\modern-wizard.bmp" + ${EndIf} +FunctionEnd + +Function un.preConfirm + ${If} ${FileExists} "$INSTDIR\distribution\modern-header.bmp" + ${AndIf} $hHeaderBitmap == "" + Delete "$PLUGINSDIR\modern-header.bmp" + CopyFiles /SILENT "$INSTDIR\distribution\modern-header.bmp" "$PLUGINSDIR\modern-header.bmp" + ${un.ChangeMUIHeaderImage} "$PLUGINSDIR\modern-header.bmp" + ${EndIf} + + !insertmacro un.createUnConfirmINI + !insertmacro MUI_HEADER_TEXT "$(UN_CONFIRM_PAGE_TITLE)" "$(UN_CONFIRM_PAGE_SUBTITLE)" + ; The Summary custom page has a textbox that will automatically receive + ; focus. This sets the focus to the Install button instead. + !insertmacro MUI_INSTALLOPTIONS_INITDIALOG "unconfirm.ini" + GetDlgItem $0 $HWNDPARENT 1 + ${MUI_INSTALLOPTIONS_READ} $1 "unconfirm.ini" "Field 4" "HWND" + SetCtlColors $1 0x000000 0xFFFFEE + ShowWindow $1 ${SW_HIDE} + System::Call "user32::SetFocus(i r0, i 0x0007, i,i)i" + !insertmacro MUI_INSTALLOPTIONS_SHOW +FunctionEnd -; Checks if the app being uninstalled is running. Function un.leaveConfirm + ${MUI_INSTALLOPTIONS_READ} $0 "unconfirm.ini" "Settings" "State" + StrCmp $0 "3" +1 continue + ${MUI_INSTALLOPTIONS_READ} $0 "unconfirm.ini" "Field 3" "State" + ${MUI_INSTALLOPTIONS_READ} $1 "unconfirm.ini" "Field 4" "HWND" + StrCmp $0 1 +1 +3 + ShowWindow $1 ${SW_SHOW} + Abort + + ShowWindow $1 ${SW_HIDE} + Abort + + continue: + ; Try to delete the app executable and if we can't delete it try to find the ; app's message window and prompt the user to close the app. This allows ; running an instance that is located in another directory. If for whatever @@ -415,5 +467,19 @@ Function un.onInit ${Unless} ${FileExists} "$INSTDIR\${FileMainEXE}" Abort ${EndUnless} + StrCpy $LANGUAGE 0 + ${un.SetBrandNameVars} "$INSTDIR\distribution\setup.ini" + + ; Initialize $hHeaderBitmap to prevent redundant changing of the bitmap if + ; the user clicks the back button + StrCpy $hHeaderBitmap "" +FunctionEnd + +Function .onGUIEnd + ${OnEndCommon} +FunctionEnd + +Function un.onGUIEnd + ${un.OnEndCommon} FunctionEnd diff --git a/browser/locales/Makefile.in b/browser/locales/Makefile.in index 4224780dcce5..a047776c1c2f 100644 --- a/browser/locales/Makefile.in +++ b/browser/locales/Makefile.in @@ -193,6 +193,10 @@ include $(call EXPAND_LOCALE_SRCDIR,toolkit/locales)/installer/windows/charset.m repackage-win32-installer: WIN32_INSTALLER_OUT=$(_ABS_DIST)/install/sea/$(PKG_BASENAME).installer.exe repackage-win32-installer: $(WIN32_INSTALLER_IN) $(SUBMAKEFILES) +ifneq (en-US,$(AB_CD)) + @echo "Verifying $(AB_CD) installer variable usage" + @$(PERL) $(topsrcdir)/toolkit/mozapps/installer/windows/nsis/check-locales.pl $(LOCALE_SRCDIR)/installer +endif @echo "Repackaging $(WIN32_INSTALLER_IN) into $(WIN32_INSTALLER_OUT)." ifdef MOZ_BRANDING_DIRECTORY $(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY) export diff --git a/browser/locales/en-US/chrome/browser/browser.dtd b/browser/locales/en-US/chrome/browser/browser.dtd index 6e560a578da2..e5b0f10aa660 100644 --- a/browser/locales/en-US/chrome/browser/browser.dtd +++ b/browser/locales/en-US/chrome/browser/browser.dtd @@ -273,19 +273,19 @@ - - - - + + + + - - - - - - - - + + + + + + + + @@ -345,3 +345,5 @@ + + diff --git a/browser/locales/en-US/chrome/browser/browser.properties b/browser/locales/en-US/chrome/browser/browser.properties index da6c4e612743..f38695c72773 100644 --- a/browser/locales/en-US/chrome/browser/browser.properties +++ b/browser/locales/en-US/chrome/browser/browser.properties @@ -83,12 +83,23 @@ refreshBlocked.goButton.accesskey=A refreshBlocked.refreshLabel=%S prevented this page from automatically reloading. refreshBlocked.redirectLabel=%S prevented this page from automatically redirecting to another page. -# Chromeless popup handling -chromelessWindow.warningMessage=The web site at %S has hidden your toolbars. -chromelessWindow.warningNoLocation=This web site has hidden your toolbars. -chromelessWindow.showToolbarsButton=Show Toolbars -chromelessWindow.accessKey=S - # Star button starButtonOn.tooltip=Edit this bookmark starButtonOff.tooltip=Bookmark this page + +# Identity information +identity.domainverified.title=Location Verified +identity.domainverified.body=You are currently visiting: +identity.domainverified.supplemental=Information identifying the owner of this web site may not have been validated. + +identity.identified.title=Identity Verified +identity.identified.body=This web site is owned by: +identity.identified.verifier=Verified by: %S +identity.identified.state_and_country=%S, %S +identity.identified.title_with_country=%S (%S) + +identity.unknown.title=Identity Unknown +identity.unknown.body=This web site does not supply identity information. + +identity.encrypted=Your connection to this web site is encrypted to prevent eavesdropping. +identity.unencrypted=Your connection to this web site is not encrypted. diff --git a/browser/locales/en-US/chrome/browser/preferences/preferences.dtd b/browser/locales/en-US/chrome/browser/preferences/preferences.dtd index dfde7f1a5642..02235a868995 100644 --- a/browser/locales/en-US/chrome/browser/preferences/preferences.dtd +++ b/browser/locales/en-US/chrome/browser/preferences/preferences.dtd @@ -4,7 +4,7 @@ - + diff --git a/browser/locales/en-US/chrome/browser/safebrowsing/blockedSite.properties b/browser/locales/en-US/chrome/browser/safebrowsing/blockedSite.properties new file mode 100644 index 000000000000..d143313ca444 --- /dev/null +++ b/browser/locales/en-US/chrome/browser/safebrowsing/blockedSite.properties @@ -0,0 +1,11 @@ +malware.title=Suspected Attack Site! +malware.shortDesc=The web site at %S has been reported as an attack site and has been blocked based on your security preferences. +malware.longDesc=

Attack sites try to install programs that steal private information, use your computer to attack others, or damage your system.

\n

Web site owners who believe their site has been reported as an attack site in error may request a review.

+ +phishing.title=Suspected Web Forgery! +phishing.shortDesc=The web site at %S has been reported as a web forgery designed to trick users into sharing personal or financial information. +phishing.longDesc=

Entering any personal information on this page may result in identity theft or other fraud.

These types of web forgeries are used in scams known as phishing attacks, in which fraudulent web pages and emails are used to imitate sources you may trust.

+ +# Localization note (phishing.learnMoreLink): please leave the text +# as-is. A localized href is pulled in from user preferences automatically. +phishing.learnMoreLink=

You can find out more about how %S protects you from phishing attacks.

diff --git a/browser/locales/en-US/chrome/overrides/appstrings.properties b/browser/locales/en-US/chrome/overrides/appstrings.properties index 357abe385ca2..e70e7632de78 100644 --- a/browser/locales/en-US/chrome/overrides/appstrings.properties +++ b/browser/locales/en-US/chrome/overrides/appstrings.properties @@ -60,3 +60,4 @@ externalProtocolUnknown= externalProtocolChkMsg=Remember my choice for all links of this type. externalProtocolLaunchBtn=Launch application malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences. +phishingBlocked=The web site at %S has been reported as a web forgery designed to trick users into sharing personal or financial information. diff --git a/browser/locales/en-US/chrome/overrides/netError.dtd b/browser/locales/en-US/chrome/overrides/netError.dtd index 2d3d56a17019..a8e546bb7047 100644 --- a/browser/locales/en-US/chrome/overrides/netError.dtd +++ b/browser/locales/en-US/chrome/overrides/netError.dtd @@ -123,6 +123,17 @@ "> + + +
  • This could be a problem with the server's configuration, or it could be +someone trying to impersonate the server.
  • +
  • If you have connected to this server successfully in the past, the error may +be temporary, and you can try again later.
  • +
  • You can see and change your current list of servers with known security problems + in your advanced encryption settings.
  • + +"> @@ -140,3 +151,9 @@

    Attack sites try to install programs that steal private information, use your computer to attack others, or damage your system.

    Web site owners who believe their site has been reported as an attack site in error may request a review.

    "> + + +Entering any personal information on this page may result in identity theft or other fraud.

    +

    These types of web forgeries are used in scams known as phishing attacks, in which fraudulent web pages and emails are used to imitate sources you may trust.

    +"> diff --git a/browser/locales/en-US/installer/custom.properties b/browser/locales/en-US/installer/custom.properties index da0174a92752..61ae5a07134b 100755 --- a/browser/locales/en-US/installer/custom.properties +++ b/browser/locales/en-US/installer/custom.properties @@ -41,60 +41,68 @@ # Accesskeys are defined by prefixing the letter that is to be used for the # accesskey with an ampersand (e.g. &). -# Do not replace ${BrandShortName} or ${BrandFullName} with a custom string. +# Do not replace $BrandShortName, $BrandFullName, or $BrandFullNameDA with a +# custom string and always use the same one as used by the en-US files. +# $BrandFullNameDA allows the string to contain an ampersand (e.g. DA stands +# for double ampersand) and prevents the letter following the ampersand from +# being used as an accesskey. # You can use \n to create a newline in the string but only when the string # from en-US contains a \n. -REG_APP_DESC=${BrandShortName} delivers safe, easy web browsing. A familiar user interface, enhanced security features including protection from online identity theft, and integrated search let you get the most out of the web. +REG_APP_DESC=$BrandShortName delivers safe, easy web browsing. A familiar user interface, enhanced security features including protection from online identity theft, and integrated search let you get the most out of the web. OPTIONAL_COMPONENTS_TITLE=Choose Optional Components -OPTIONAL_COMPONENTS_SUBTITLE=Choose which features of $(^NameDA) you want to install. +OPTIONAL_COMPONENTS_SUBTITLE=Choose which features of $BrandShortName you want to install. OPTIONAL_COMPONENTS_LABEL=Optional Components: -APP_DESC=Required files for the ${BrandShortName} application DOMI_TITLE=DOM Inspector DOMI_TEXT=Inspects the structure and properties of a window and its contents. -QFA_TITLE=Quality Feedback Agent -QFA_TEXT=Sends information about program crashes to Mozilla. -CONTEXT_OPTIONS=${BrandShortName} &Options -CONTEXT_SAFE_MODE=${BrandShortName} &Safe Mode +CONTEXT_OPTIONS=$BrandShortName &Options +CONTEXT_SAFE_MODE=$BrandShortName &Safe Mode SAFE_MODE=Safe Mode OPTIONS_PAGE_TITLE=Setup Type OPTIONS_PAGE_SUBTITLE=Choose setup options SHORTCUTS_PAGE_TITLE=Set Up Shortcuts SHORTCUTS_PAGE_SUBTITLE=Create Program Icons SUMMARY_PAGE_TITLE=Summary -SUMMARY_PAGE_SUBTITLE=Ready to start installing ${BrandShortName} -SUMMARY_INSTALLED_TO=${BrandShortName} will be installed to the following location: +SUMMARY_PAGE_SUBTITLE=Ready to start installing $BrandShortName +SUMMARY_INSTALLED_TO=$BrandShortName will be installed to the following location: SUMMARY_CLICK=Click Install to continue. -SURVEY_TEXT=&Tell us what you thought of ${BrandShortName} -LAUNCH_TEXT=&Launch ${BrandFullName} now -WARN_APP_RUNNING_INSTALL=${BrandFullName} must be closed to proceed with the installation.\n\nClick "OK" to exit ${BrandFullName} automatically and continue. -CREATE_ICONS_DESC=Create icons for ${BrandShortName}: +SURVEY_TEXT=&Tell us what you thought of $BrandShortName +LAUNCH_TEXT=&Launch $BrandShortName now +WARN_APP_RUNNING_INSTALL=$BrandShortName must be closed to proceed with the installation.\n\nClick "OK" to exit $BrandShortName automatically and continue. +CREATE_ICONS_DESC=Create icons for $BrandShortName: ICONS_DESKTOP=On my &Desktop ICONS_STARTMENU=In my &Start Menu Programs folder ICONS_QUICKLAUNCH=In my &Quick Launch bar -WARN_MANUALLY_CLOSE_APP_UNINSTALL=${BrandFullName} must be closed to proceed with the uninstall.\n\nPlease close ${BrandFullName} to continue. -WARN_MANUALLY_CLOSE_APP_LAUNCH=${BrandFullName} is already running.\n\nPlease close ${BrandFullName} prior to launching the version you have just installed. +WARN_MANUALLY_CLOSE_APP_UNINSTALL=$BrandShortName must be closed to proceed with the uninstall.\n\nPlease close $BrandShortName to continue. +WARN_MANUALLY_CLOSE_APP_LAUNCH=$BrandShortName is already running.\n\nPlease close $BrandShortName prior to launching the version you have just installed. WARN_WRITE_ACCESS=You don't have access to write to the installation directory.\n\nClick OK to select a different directory. WARN_DISK_SPACE=You don't have sufficient disk space to install to this location.\n\nClick OK to select a different location. -WARN_UNSUPPORTED_MSG=Sorry, ${BrandShortName} can't be installed. This version of ${BrandShortName} requires ${MinUnsupportedVer} or newer. -WARN_RESTART_REQUIRED_UNINSTALL=Your computer must be restarted to complete a previous uninstall of ${BrandShortName}. Do you want to reboot now? +WARN_UNSUPPORTED_MSG=Sorry, $BrandShortName can't be installed. This version of $BrandShortName requires ${MinUnsupportedVer} or newer. +WARN_RESTART_REQUIRED_UNINSTALL=Your computer must be restarted to complete a previous uninstall of $BrandShortName. Do you want to reboot now? ERROR_CREATE_DIRECTORY=Error creating directory:\n\n$0\n\nClick Cancel to stop the installation or\nRetry to try again. -STATUS_INSTALL_APP=Installing ${BrandShortName}... +UN_CONFIRM_PAGE_TITLE=Uninstall $BrandFullName +UN_CONFIRM_PAGE_SUBTITLE=Remove $BrandFullName from your computer. +UN_CONFIRM_UNINSTALLED_FROM=$BrandShortName will be uninstalled from the following location: +UN_CONFIRM_CLICK=Click Uninstall to continue. +UN_REMOVE_PROFILES=&Remove my $BrandShortName personal data and customizations +UN_REMOVE_PROFILES_DESC=This will permanently remove your bookmarks, saved passwords, cookies and customizations. You may wish to keep this information if you plan on installing another version of $BrandShortName in the future. + +STATUS_INSTALL_APP=Installing $BrandShortName... STATUS_INSTALL_LANG=Installing Language Files (${AB_CD})... STATUS_INSTALL_OPTIONAL=Installing Optional Components... -STATUS_UNINSTALL_MAIN=Uninstalling ${BrandShortName}... +STATUS_UNINSTALL_MAIN=Uninstalling $BrandShortName... STATUS_CLEANUP=A Little Housekeeping... # _DESC strings support approximately 65 characters per line. # One line OPTIONS_SUMMARY=Choose the type of setup you prefer, then click Next. # One line -OPTION_STANDARD_DESC=${BrandShortName} will be installed with the most common options. +OPTION_STANDARD_DESC=$BrandShortName will be installed with the most common options. OPTION_STANDARD_RADIO=&Standard # One line -OPTION_COMPLETE_DESC=${BrandShortName} will be installed with all available options. +OPTION_COMPLETE_DESC=$BrandShortName will be installed with all available options. OPTION_COMPLETE_RADIO=C&omplete # Two lines OPTION_CUSTOM_DESC=You may choose individual options to be installed. Recommended for experienced users. diff --git a/browser/locales/en-US/installer/mui.properties b/browser/locales/en-US/installer/mui.properties index 037414379ccf..1a82d9ef61e5 100755 --- a/browser/locales/en-US/installer/mui.properties +++ b/browser/locales/en-US/installer/mui.properties @@ -44,54 +44,55 @@ # Accesskeys are defined by prefixing the letter that is to be used for the # accesskey with an ampersand (e.g. &). -# Do not replace $(^NameDA) or $(^Name) with a custom string. - -# Do not change $(^NameDA) to $(^Name) or $(^Name) to $(^NameDA). NameDA allows -# Name to contain an ampersand (e.g. DA stands for double ampersand) and -# prevents the letter following the ampersand being used as an accesskey. +# Do not replace $BrandShortName, $BrandFullName, or $BrandFullNameDA with a +# custom string and always use the same one as used by the en-US files. +# $BrandFullNameDA allows the string to contain an ampersand (e.g. DA stands +# for double ampersand) and prevents the letter following the ampersand from +# being used as an accesskey. # You can use \n to create a newline in the string but only when the string # from en-US contains a \n. -MUI_TEXT_WELCOME_INFO_TITLE=Welcome to the $(^NameDA) Setup Wizard -MUI_TEXT_WELCOME_INFO_TEXT=This wizard will guide you through the installation of $(^NameDA).\n\nIt is recommended that you close all other applications before starting Setup. This will make it possible to update relevant system files without having to reboot your computer.\n\n$_CLICK + +MUI_TEXT_WELCOME_INFO_TITLE=Welcome to the $BrandFullNameDA Setup Wizard +MUI_TEXT_WELCOME_INFO_TEXT=This wizard will guide you through the installation of $BrandFullNameDA.\n\nIt is recommended that you close all other applications before starting Setup. This will make it possible to update relevant system files without having to reboot your computer.\n\n$_CLICK MUI_TEXT_LICENSE_TITLE=License Agreement -MUI_TEXT_LICENSE_SUBTITLE=Please review the license terms before installing $(^NameDA). +MUI_TEXT_LICENSE_SUBTITLE=Please review the license terms before installing $BrandFullNameDA. MUI_INNERTEXT_LICENSE_TOP=Press Page Down to see the rest of the agreement. -MUI_INNERTEXT_LICENSE_BOTTOM_CHECKBOX=If you accept the terms of the agreement, click the check box below. You must accept the agreement to install $(^NameDA). $_CLICK -MUI_INNERTEXT_LICENSE_BOTTOM_RADIOBUTTONS=If you accept the terms of the agreement, select the first option below. You must accept the agreement to install $(^NameDA). $_CLICK +MUI_INNERTEXT_LICENSE_BOTTOM_CHECKBOX=If you accept the terms of the agreement, click the check box below. You must accept the agreement to install $BrandFullNameDA. $_CLICK +MUI_INNERTEXT_LICENSE_BOTTOM_RADIOBUTTONS=If you accept the terms of the agreement, select the first option below. You must accept the agreement to install $BrandFullNameDA. $_CLICK MUI_TEXT_COMPONENTS_TITLE=Choose Components -MUI_TEXT_COMPONENTS_SUBTITLE=Choose which features of $(^NameDA) you want to install. +MUI_TEXT_COMPONENTS_SUBTITLE=Choose which features of $BrandFullNameDA you want to install. MUI_INNERTEXT_COMPONENTS_DESCRIPTION_TITLE=Description MUI_INNERTEXT_COMPONENTS_DESCRIPTION_INFO=Position your mouse over a component to see its description. MUI_TEXT_DIRECTORY_TITLE=Choose Install Location -MUI_TEXT_DIRECTORY_SUBTITLE=Choose the folder in which to install $(^NameDA). +MUI_TEXT_DIRECTORY_SUBTITLE=Choose the folder in which to install $BrandFullNameDA. MUI_TEXT_INSTALLING_TITLE=Installing -MUI_TEXT_INSTALLING_SUBTITLE=Please wait while $(^NameDA) is being installed. +MUI_TEXT_INSTALLING_SUBTITLE=Please wait while $BrandFullNameDA is being installed. MUI_TEXT_FINISH_TITLE=Installation Complete MUI_TEXT_FINISH_SUBTITLE=Setup was completed successfully. MUI_TEXT_ABORT_TITLE=Installation Aborted MUI_TEXT_ABORT_SUBTITLE=Setup was not completed successfully. MUI_BUTTONTEXT_FINISH=&Finish -MUI_TEXT_FINISH_INFO_TITLE=Completing the $(^NameDA) Setup Wizard -MUI_TEXT_FINISH_INFO_TEXT=$(^NameDA) has been installed on your computer.\n\nClick Finish to close this wizard. -MUI_TEXT_FINISH_INFO_REBOOT=Your computer must be restarted in order to complete the installation of $(^NameDA). Do you want to reboot now? +MUI_TEXT_FINISH_INFO_TITLE=Completing the $BrandFullNameDA Setup Wizard +MUI_TEXT_FINISH_INFO_TEXT=$BrandFullNameDA has been installed on your computer.\n\nClick Finish to close this wizard. +MUI_TEXT_FINISH_INFO_REBOOT=Your computer must be restarted in order to complete the installation of $BrandFullNameDA. Do you want to reboot now? MUI_TEXT_FINISH_REBOOTNOW=Reboot now MUI_TEXT_FINISH_REBOOTLATER=I want to manually reboot later MUI_TEXT_STARTMENU_TITLE=Choose Start Menu Folder -MUI_TEXT_STARTMENU_SUBTITLE=Choose a Start Menu folder for the $(^NameDA) shortcuts. +MUI_TEXT_STARTMENU_SUBTITLE=Choose a Start Menu folder for the $BrandFullNameDA shortcuts. MUI_INNERTEXT_STARTMENU_TOP=Select the Start Menu folder in which you would like to create the program's shortcuts. You can also enter a name to create a new folder. -MUI_TEXT_ABORTWARNING=Are you sure you want to quit $(^Name) Setup? -MUI_UNTEXT_WELCOME_INFO_TITLE=Welcome to the $(^NameDA) Uninstall Wizard -MUI_UNTEXT_WELCOME_INFO_TEXT=This wizard will guide you through the uninstallation of $(^NameDA).\n\nBefore starting the uninstallation, make sure $(^NameDA) is not running.\n\n$_CLICK -MUI_UNTEXT_CONFIRM_TITLE=Uninstall $(^NameDA) -MUI_UNTEXT_CONFIRM_SUBTITLE=Remove $(^NameDA) from your computer. +MUI_TEXT_ABORTWARNING=Are you sure you want to quit $BrandFullName Setup? +MUI_UNTEXT_WELCOME_INFO_TITLE=Welcome to the $BrandFullNameDA Uninstall Wizard +MUI_UNTEXT_WELCOME_INFO_TEXT=This wizard will guide you through the uninstallation of $BrandFullNameDA.\n\nBefore starting the uninstallation, make sure $BrandFullNameDA is not running.\n\n$_CLICK +MUI_UNTEXT_CONFIRM_TITLE=Uninstall $BrandFullNameDA +MUI_UNTEXT_CONFIRM_SUBTITLE=Remove $BrandFullNameDA from your computer. MUI_UNTEXT_UNINSTALLING_TITLE=Uninstalling -MUI_UNTEXT_UNINSTALLING_SUBTITLE=Please wait while $(^NameDA) is being uninstalled. +MUI_UNTEXT_UNINSTALLING_SUBTITLE=Please wait while $BrandFullNameDA is being uninstalled. MUI_UNTEXT_FINISH_TITLE=Uninstallation Complete MUI_UNTEXT_FINISH_SUBTITLE=Uninstall was completed successfully. MUI_UNTEXT_ABORT_TITLE=Uninstallation Aborted MUI_UNTEXT_ABORT_SUBTITLE=Uninstall was not completed successfully. -MUI_UNTEXT_FINISH_INFO_TITLE=Completing the $(^NameDA) Uninstall Wizard -MUI_UNTEXT_FINISH_INFO_TEXT=$(^NameDA) has been uninstalled from your computer.\n\nClick Finish to close this wizard. -MUI_UNTEXT_FINISH_INFO_REBOOT=Your computer must be restarted in order to complete the uninstallation of $(^NameDA). Do you want to reboot now? -MUI_UNTEXT_ABORTWARNING=Are you sure you want to quit $(^Name) Uninstall? +MUI_UNTEXT_FINISH_INFO_TITLE=Completing the $BrandFullNameDA Uninstall Wizard +MUI_UNTEXT_FINISH_INFO_TEXT=$BrandFullNameDA has been uninstalled from your computer.\n\nClick Finish to close this wizard. +MUI_UNTEXT_FINISH_INFO_REBOOT=Your computer must be restarted in order to complete the uninstallation of $BrandFullNameDA. Do you want to reboot now? +MUI_UNTEXT_ABORTWARNING=Are you sure you want to quit $BrandFullName Uninstall? diff --git a/browser/locales/en-US/installer/override.properties b/browser/locales/en-US/installer/override.properties index 7d09ead353ab..00ea4f940193 100755 --- a/browser/locales/en-US/installer/override.properties +++ b/browser/locales/en-US/installer/override.properties @@ -41,11 +41,11 @@ # Accesskeys are defined by prefixing the letter that is to be used for the # accesskey with an ampersand (e.g. &). -# Do not replace $(^NameDA) or $(^Name) with a custom string. - -# Do not change $(^NameDA) to $(^Name) or $(^Name) to $(^NameDA). NameDA allows -# Name to contain an ampersand (e.g. DA stands for double ampersand) and -# prevents the letter following the ampersand being used as an accesskey. +# Do not replace $BrandShortName, $BrandFullName, or $BrandFullNameDA with a +# custom string and always use the same one as used by the en-US files. +# $BrandFullNameDA allows the string to contain an ampersand (e.g. DA stands +# for double ampersand) and prevents the letter following the ampersand from +# being used as an accesskey. # You can use \n to create a newline in the string but only when the string # from en-US contains a \n. @@ -55,8 +55,8 @@ # and end of a strong enclose the add and additional double quote to the # beginning and end of the string (e.g. ""This will include quotes""). -SetupCaption=$(^Name) Setup -UninstallCaption=$(^Name) Uninstall +SetupCaption=$BrandFullName Setup +UninstallCaption=$BrandFullName Uninstall BackBtn=< &Back NextBtn=&Next > AcceptBtn=I &accept the terms in the License Agreement @@ -71,15 +71,15 @@ ClickNext=Click Next to continue. ClickInstall=Click Install to start the installation. ClickUninstall=Click Uninstall to start the uninstallation. Completed=Completed -LicenseTextRB=Please review the license agreement before installing $(^NameDA). If you accept all terms of the agreement, select the first option below. $_CLICK +LicenseTextRB=Please review the license agreement before installing $BrandFullNameDA. If you accept all terms of the agreement, select the first option below. $_CLICK ComponentsText=Check the components you want to install and uncheck the components you don't want to install. $_CLICK ComponentsSubText2_NoInstTypes=Select components to install: -DirText=Setup will install $(^NameDA) in the following folder. To install in a different folder, click Browse and select another folder. $_CLICK +DirText=Setup will install $BrandFullNameDA in the following folder. To install in a different folder, click Browse and select another folder. $_CLICK DirSubText=Destination Folder -DirBrowseText=Select the folder to install $(^NameDA) in: +DirBrowseText=Select the folder to install $BrandFullNameDA in: SpaceAvailable="Space available: " SpaceRequired="Space required: " -UninstallingText=$(^NameDA) will be uninstalled from the following folder. $_CLICK +UninstallingText=$BrandFullNameDA will be uninstalled from the following folder. $_CLICK UninstallingSubText=Uninstalling from: FileError=Error opening file for writing: \r\n\r\n$0\r\n\r\nClick Abort to stop the installation,\r\nRetry to try again, or\r\nIgnore to skip this file. FileError_NoIgnore=Error opening file for writing: \r\n\r\n$0\r\n\r\nClick Retry to try again, or\r\nCancel to stop the installation. diff --git a/browser/locales/jar.mn b/browser/locales/jar.mn index 830120e52d1d..686a5ba45a21 100644 --- a/browser/locales/jar.mn +++ b/browser/locales/jar.mn @@ -37,6 +37,7 @@ #ifdef MOZ_SAFE_BROWSING locale/browser/safebrowsing/phishing-afterload-warning-message.dtd (%chrome/browser/safebrowsing/phishing-afterload-warning-message.dtd) locale/browser/safebrowsing/report-phishing.dtd (%chrome/browser/safebrowsing/report-phishing.dtd) + locale/browser/safebrowsing/blockedSite.properties (%chrome/browser/safebrowsing/blockedSite.properties) #endif locale/browser/feeds/subscribe.dtd (%chrome/browser/feeds/subscribe.dtd) locale/browser/feeds/subscribe.properties (%chrome/browser/feeds/subscribe.properties) diff --git a/browser/themes/pinstripe/browser/browser.css b/browser/themes/pinstripe/browser/browser.css index b2bd37567e48..211fb1328571 100755 --- a/browser/themes/pinstripe/browser/browser.css +++ b/browser/themes/pinstripe/browser/browser.css @@ -831,7 +831,7 @@ toolbar[iconsize="small"] #paste-button:hover:active { #urlbar { margin-top: 5px; margin-bottom: 5px; - -moz-margin-start: 4px; + -moz-margin-start: 0px; -moz-margin-end: 0px; width: 7em; min-width: 7em; @@ -839,33 +839,6 @@ toolbar[iconsize="small"] #paste-button:hover:active { font: icon !important; } -.formatted-url { - -moz-box-align: center; - margin: 0 3px; - /*XXX Gecko 1.9 quirk*/ - -moz-padding-start: 1px; - color: -moz-fieldtext; -} - -#urlbar[level="high"] .formatted-url , -#urlbar[level="low"] .formatted-url { - color: black; -} - -.formatted-url * { - margin: 0; - padding: 0; - cursor: text; -} - -.formatted-url-ellipsis { - -moz-margin-start: 1px; -} - -.formatted-url-prePath { - -moz-box-pack: center; -} - #urlbar[level="high"] > .autocomplete-textbox-container, #urlbar[level="low"] > .autocomplete-textbox-container { @@ -883,46 +856,6 @@ toolbar[iconsize="small"] #paste-button:hover:active { background: url("chrome://browser/skin/Secure-background.gif") #FFFED8 repeat-x; } -#urlbar #lock-icon { - height: 18px; - margin: -1px; -} - -#urlbar[level="high"] #lock-icon { - list-style-image: url("chrome://browser/skin/Secure.png"); - -moz-image-region: rect(0px, 18px, 18px, 0px); -} -#urlbar[level="high"] #lock-icon:hover { - -moz-image-region: rect(18px, 18px, 36px, 0px); -} -#urlbar[level="high"] #lock-icon:active { - -moz-image-region: rect(36px, 18px, 54px, 0px); -} - -#urlbar[level="low"] #lock-icon { - list-style-image: url("chrome://browser/skin/Secure.png"); - -moz-image-region: rect(0px, 18px, 18px, 0px); -} -#urlbar[level="low"] #lock-icon:hover { - -moz-image-region: rect(18px, 18px, 36px, 0px); -} -#urlbar[level="low"] #lock-icon:active { - -moz-image-region: rect(36px, 18px, 54px, 0px); -} - -#urlbar[level="broken"] #lock-icon { - list-style-image: url("chrome://browser/skin/Security-broken.png"); - -moz-image-region: rect(0px, 18px, 18px, 0px); -} - -#urlbar[level="broken"] #lock-icon:hover { - -moz-image-region: rect(18px, 18px, 36px, 0px); -} - -#urlbar[level="broken"] #lock-icon:active { - -moz-image-region: rect(36px, 18px, 54px, 0px); -} - #urlbar-container { -moz-padding-end: 5px; } @@ -1707,3 +1640,116 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] { -moz-border-left-colors: ThreeDLightShadow ThreeDHighlight !important; } +/* ::::: Identity Indicator Styling ::::: */ +/* Location bar visuals*/ +#identity-box { + /* Extend our margins out so that our highlight/separator bar covers the + location bar properly */ + margin: -1px 0 -2px; + padding: 1px 2px 2px 0; + border-right: 1px solid #888; + background-color: white; + opacity: 0.9; +} + +#identity-box:hover { + opacity: 1.0; +} + +#identity-box.verifiedIdentity { + background-color: #BFA; +} + +#urlbar[level="high"] > #identity-box, +#urlbar[level="low"] > #identity-box { + /* urlbar adds padding when security level is set, which we need to + counteract here so that we still fill the background. */ + margin: -2px; + padding: 1px 2px 2px; +} + +#identity-icon-label { + padding: 2px 2px 0; + margin: 0; + color: black; + vertical-align: middle; +} + +.unknownIdentity > #identity-icon-label { + display: none; +} + +/* Popup Icons */ +#identity-popup-icon { + height: 64px; + width: 64px; + padding: 0; + margin: 10px 0 0; + list-style-image: url("chrome://browser/skin/identity.png"); + -moz-image-region: rect(0px, 64px, 64px, 0px); +} + +.verifiedDomain > #identity-popup-container > #identity-popup-icon { + -moz-image-region: rect(64px, 64px, 128px, 0px); +} + +.verifiedIdentity > #identity-popup-container > #identity-popup-icon { + -moz-image-region: rect(128px, 64px, 192px, 0px); +} + +/* Popup Title */ +#identity-popup-title { + font-size: 120%; + font-weight: bold; +} + +.verifiedIdentity > #identity-popup-title { + color: #6A6; +} + +.unknownIdentity > #identity-popup-title { + color: #999; +} + +.verifiedDomain > #identity-popup-title { + color: black; +} + +/* Popup Body Text */ +#identity-popup-content-box > description, +#identity-popup-encryption-label { + white-space: -moz-pre-wrap; + color: black; + padding-left: 10px; +} + +#identity-popup-content { + padding-top: 5px; + margin-bottom: 0; + max-width: 200px; +} + +.verifiedIdentity > #identity-popup-content, +.verifiedDomain > #identity-popup-content { + font-size: 140%; + font-weight: bold; + max-width: 300px; +} + +#identity-popup-encryption { + margin: 10px 0; +} + +.verifiedIdentity > #identity-popup-encryption > * > #identity-popup-encryption-icon, +.verifiedDomain > #identity-popup-encryption > * >#identity-popup-encryption-icon { + list-style-image: url("chrome://browser/skin/Secure.png"); + -moz-image-region: rect(0px, 18px, 18px, 0px); +} + +/* Popup Bounding Box */ +#identity-popup-container { + background-image: none; + background-color: white; + min-width: 280px; + padding: 10px; +} diff --git a/browser/themes/pinstripe/browser/jar.mn b/browser/themes/pinstripe/browser/jar.mn index c1fd37e96a8a..191f21a872bd 100644 --- a/browser/themes/pinstripe/browser/jar.mn +++ b/browser/themes/pinstripe/browser/jar.mn @@ -10,6 +10,7 @@ classic.jar: skin/classic/browser/find.png skin/classic/browser/find-bar-background.png skin/classic/browser/Go.png + skin/classic/browser/identity.png skin/classic/browser/Info.png skin/classic/browser/page-livemarks.png skin/classic/browser/livemark-item.png diff --git a/browser/themes/pinstripe/browser/places/places.css b/browser/themes/pinstripe/browser/places/places.css index 7412b224540a..242f20a11aed 100755 --- a/browser/themes/pinstripe/browser/places/places.css +++ b/browser/themes/pinstripe/browser/places/places.css @@ -1,3 +1,26 @@ +/* Sidebars */ + +.sidebar-placesTree { + -moz-appearance: none; + border: 0; + margin: 0; + border-top: 1px solid ThreeDShadow; +} + +.sidebar-placesTreechildren::-moz-tree-cell(leaf) , +.sidebar-placesTreechildren::-moz-tree-image(leaf) { + cursor: pointer; +} + +.sidebar-placesTreechildren::-moz-tree-cell-text(leaf, hover) { + cursor: pointer; + text-decoration: underline; +} + +.sidebar-placesTreechildren::-moz-tree-cell(separator) { + cursor: default; +} + /* Toolbar */ #placesToolbar { border-bottom: none; diff --git a/browser/themes/winstripe/browser/browser.css b/browser/themes/winstripe/browser/browser.css index 9361bf188a8c..87e959e2036d 100644 --- a/browser/themes/winstripe/browser/browser.css +++ b/browser/themes/winstripe/browser/browser.css @@ -856,7 +856,7 @@ toolbar[iconsize="small"] #paste-button:not([disabled="true"]):hover:active { margin-bottom: 2px; margin-top: 2px; -moz-margin-end: 0px; - -moz-margin-start: 3px; + -moz-margin-start: 0px; width: 7em; min-width: 7em; @@ -868,33 +868,6 @@ toolbar[iconsize="small"] #paste-button:not([disabled="true"]):hover:active { border-width: 1px; } -.formatted-url { - -moz-box-align: center; - margin: 0 3px; - /*XXX Gecko 1.9 quirk*/ - -moz-padding-start: 1px; - color: -moz-fieldtext; -} - -#urlbar[level="high"] .formatted-url , -#urlbar[level="low"] .formatted-url { - color: black; -} - -.formatted-url * { - margin: 0; - padding: 0; - cursor: text; -} - -.formatted-url-ellipsis { - -moz-margin-start: 1px; -} - -.formatted-url-prePath { - -moz-box-pack: center; -} - #urlbar-container { -moz-box-orient: horizontal; -moz-box-align: stretch; @@ -1746,43 +1719,6 @@ toolbar[mode="text"] > #window-controls > toolbarbutton > .toolbarbutton-text { color: #000000; } -#urlbar[level="high"] #lock-icon { - -moz-image-region: rect(0px, 18px, 18px, 0px); - list-style-image: url("chrome://browser/skin/Secure.png"); -} -#urlbar[level="high"] #lock-icon:hover { - -moz-image-region: rect(18px, 18px, 36px, 0px); - list-style-image: url("chrome://browser/skin/Secure.png"); -} -#urlbar[level="high"] #lock-icon:active { - -moz-image-region: rect(36px, 18px, 54px, 0px); - list-style-image: url("chrome://browser/skin/Secure.png"); -} -#urlbar[level="low"] #lock-icon { - -moz-image-region: rect(0px, 18px, 18px, 0px); - list-style-image: url("chrome://browser/skin/Secure.png"); -} -#urlbar[level="low"] #lock-icon:hover { - -moz-image-region: rect(18px, 18px, 36px, 0px); - list-style-image: url("chrome://browser/skin/Secure.png"); -} -#urlbar[level="low"] #lock-icon:active { - -moz-image-region: rect(36px, 18px, 54px, 0px); - list-style-image: url("chrome://browser/skin/Secure.png"); -} -#urlbar[level="broken"] #lock-icon { - -moz-image-region: rect(0px, 18px, 18px, 0px); - list-style-image: url("chrome://browser/skin/Security-broken.png"); -} -#urlbar[level="broken"] #lock-icon:hover { - -moz-image-region: rect(18px, 18px, 36px, 0px); - list-style-image: url("chrome://browser/skin/Security-broken.png"); -} -#urlbar[level="broken"] #lock-icon:active { - -moz-image-region: rect(36px, 18px, 54px, 0px); - list-style-image: url("chrome://browser/skin/Security-broken.png"); -} - %ifdef MOZ_WIDGET_GTK2 #urlbar > .autocomplete-textbox-container { -moz-binding: url(chrome://browser/skin/browser.xml#autocomplete-security-wrapper); @@ -1895,3 +1831,117 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] { .bookmark-item[dragover-bottom="true"] { -moz-border-bottom-colors: #000000; } + +/* ::::: Identity Indicator Styling ::::: */ +/* Location bar visuals*/ +#identity-box { + cursor: help; + background-color: ThreeDFace; +%ifdef MOZ_WIDGET_GTK2 + -moz-border-end: 1px solid ThreeDShadow; +%else + -moz-appearance: toolbox; + outline: 1px solid ThreeDShadow; +%endif +} + +#identity-box.verifiedIdentity { +%ifdef MOZ_WIDGET_GTK2 + border-color: highlight; +%else + outline-color: highlight; +%endif +} + +#identity-box:hover { +%ifdef MOZ_WIDGET_GTK2 + border-color: ThreeDDarkShadow; +%else + outline-color: ThreeDDarkShadow; +%endif +} + +#identity-icon-label { + padding: 0 2px; + margin: 0; + cursor: inherit; +} + +.unknownIdentity > #identity-icon-label { + display: none; +} + +/* Popup Icons */ +#identity-popup-icon { + height: 64px; + width: 64px; + padding: 0; + margin: 10px 0 0; + list-style-image: url("chrome://browser/skin/identity.png"); + -moz-image-region: rect(0px, 64px, 64px, 0px); +} + +.verifiedDomain > #identity-popup-container > #identity-popup-icon { + -moz-image-region: rect(64px, 64px, 128px, 0px); +} + +.verifiedIdentity > #identity-popup-container > #identity-popup-icon { + -moz-image-region: rect(128px, 64px, 192px, 0px); +} + +/* Popup Title */ +#identity-popup-title { + font-size: 120%; + font-weight: bold; +} + +.verifiedIdentity > #identity-popup-title { + color: #6A6; +} + +.unknownIdentity > #identity-popup-title { + color: #999; +} + +.verifiedDomain > #identity-popup-title { + color: black; +} + +/* Popup Body Text */ +#identity-popup-content-box > description, +#identity-popup-encryption-label { + white-space: -moz-pre-wrap; + color: black; + padding-left: 10px; +} + +#identity-popup-content { + padding-top: 5px; + margin-bottom: 0; + max-width: 200px; +} + +.verifiedIdentity > #identity-popup-content, +.verifiedDomain > #identity-popup-content { + font-size: 140%; + font-weight: bold; + max-width: 300px; +} + +#identity-popup-encryption { + margin: 10px 0; +} + +.verifiedIdentity > #identity-popup-encryption > * > #identity-popup-encryption-icon, +.verifiedDomain > #identity-popup-encryption > * >#identity-popup-encryption-icon { + list-style-image: url("chrome://browser/skin/Secure.png"); + -moz-image-region: rect(0px, 18px, 18px, 0px); +} + +/* Popup Bounding Box */ +#identity-popup-container { + background-image: none; + background-color: white; + min-width: 280px; + padding: 10px; +} diff --git a/browser/themes/winstripe/browser/jar.mn b/browser/themes/winstripe/browser/jar.mn index bc9c831e0134..65d48f57b1a6 100644 --- a/browser/themes/winstripe/browser/jar.mn +++ b/browser/themes/winstripe/browser/jar.mn @@ -6,6 +6,7 @@ classic.jar: skin/classic/browser/endcap-bkgnd-hover.png * skin/classic/browser/engineManager.css (engineManager.css) skin/classic/browser/Info.png + skin/classic/browser/identity.png skin/classic/browser/pageInfo.css skin/classic/browser/pageInfo.png skin/classic/browser/page-livemarks.png diff --git a/browser/themes/winstripe/browser/places/places.css b/browser/themes/winstripe/browser/places/places.css index ba911021067b..005ad7e9ec81 100755 --- a/browser/themes/winstripe/browser/places/places.css +++ b/browser/themes/winstripe/browser/places/places.css @@ -1,15 +1,26 @@ /* Sidebars */ -page > .placesTree > treechildren::-moz-tree-cell(leaf) , -page > .placesTree > treechildren::-moz-tree-image(leaf) { +.sidebar-placesTree { + -moz-appearance: none; + border: 0; + margin: 0; + border-top: 1px solid ThreeDShadow; +} + +.sidebar-placesTreechildren::-moz-tree-cell(leaf) , +.sidebar-placesTreechildren::-moz-tree-image(leaf) { cursor: pointer; } -page > .placesTree > treechildren::-moz-tree-cell-text(leaf, hover) { +.sidebar-placesTreechildren::-moz-tree-cell-text(leaf, hover) { cursor: pointer; text-decoration: underline; } +.sidebar-placesTreechildren::-moz-tree-cell(separator) { + cursor: default; +} + /* Toolbar */ #placesToolbar { border: none; diff --git a/caps/idl/nsIScriptSecurityManager.idl b/caps/idl/nsIScriptSecurityManager.idl index 4a857d2139b3..cdf1759ee674 100644 --- a/caps/idl/nsIScriptSecurityManager.idl +++ b/caps/idl/nsIScriptSecurityManager.idl @@ -284,9 +284,12 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager /** * Returns OK if aSourceURI and target have the same "origin" * (scheme, host, and port). + * ReportError flag suppresses error reports for functions that + * don't need reporting. */ void checkSameOriginURI(in nsIURI aSourceURI, - in nsIURI aTargetURI); + in nsIURI aTargetURI, + in boolean reportError); /** * Returns OK if aSourcePrincipal and aTargetPrincipal diff --git a/caps/src/nsScriptSecurityManager.cpp b/caps/src/nsScriptSecurityManager.cpp index 771417396613..2a4ec91341e9 100644 --- a/caps/src/nsScriptSecurityManager.cpp +++ b/caps/src/nsScriptSecurityManager.cpp @@ -446,13 +446,8 @@ nsScriptSecurityManager::GetChannelPrincipal(nsIChannel* aChannel, // OK, get the principal from the URI. Make sure this does the same thing // as nsDocument::Reset and nsXULDocument::StartDocumentLoad. nsCOMPtr uri; - nsLoadFlags loadFlags = 0; - nsresult rv = aChannel->GetLoadFlags(&loadFlags); - if (NS_SUCCEEDED(rv) && (loadFlags & nsIChannel::LOAD_REPLACE)) { - aChannel->GetURI(getter_AddRefs(uri)); - } else { - aChannel->GetOriginalURI(getter_AddRefs(uri)); - } + nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri)); + NS_ENSURE_SUCCESS(rv, rv); return GetCodebasePrincipal(uri, aPrincipal); } @@ -681,12 +676,15 @@ nsScriptSecurityManager::CheckSameOrigin(JSContext* cx, NS_IMETHODIMP nsScriptSecurityManager::CheckSameOriginURI(nsIURI* aSourceURI, - nsIURI* aTargetURI) + nsIURI* aTargetURI, + PRBool reportError) { if (!SecurityCompareURIs(aSourceURI, aTargetURI)) { - ReportError(nsnull, NS_LITERAL_STRING("CheckSameOriginError"), + if (reportError) { + ReportError(nsnull, NS_LITERAL_STRING("CheckSameOriginError"), aSourceURI, aTargetURI); + } return NS_ERROR_DOM_BAD_URI; } return NS_OK; diff --git a/client.py b/client.py index c3074cfc646c..ba595fe6c281 100644 --- a/client.py +++ b/client.py @@ -1,6 +1,6 @@ #!/usr/bin/python -NSPR_CO_TAG = 'NSPR_HEAD_20071009' +NSPR_CO_TAG = 'NSPR_HEAD_20071016' NSS_CO_TAG = 'NSS_3_12_ALPHA_2' NSPR_DIRS = ('nsprpub',) diff --git a/config/rules.mk b/config/rules.mk index 0f577b2e63b0..887ff989b20b 100644 --- a/config/rules.mk +++ b/config/rules.mk @@ -1048,6 +1048,15 @@ ifdef NO_LD_ARCHIVE_FLAGS SUB_SHLOBJS = $(SUB_LOBJS) endif +ifdef HAVE_DTRACE +ifdef DTRACE_PROBE_OBJ +ifndef DTRACE_LIB_DEPENDENT +$(DTRACE_PROBE_OBJ): $(OBJS) + dtrace -G -C -32 -s $(MOZILLA_DTRACE_SRC) -o $(DTRACE_PROBE_OBJ) $(OBJS) +endif +endif +endif + # On Darwin (Mac OS X), dwarf2 debugging uses debug info left in .o files, # so instead of deleting .o files after repacking them into a dylib, we make # symlinks back to the originals. The symlinks are a no-op for stabs debugging, @@ -1078,17 +1087,17 @@ ifdef SHARED_LIBRARY_LIBS @for lib in $(SHARED_LIBRARY_LIBS); do $(AR_EXTRACT) $${lib}; $(CLEANUP2); done endif # SHARED_LIBRARY_LIBS endif # NO_LD_ARCHIVE_FLAGS -ifdef NEED_DTRACE_PROBE_OBJ +ifdef DTRACE_LIB_DEPENDENT @rm -f $(PROBE_LOBJS) @for lib in $(MOZILLA_PROBE_LIBS); do $(AR_EXTRACT) $${lib}; $(CLEANUP2); done - dtrace -G -C -32 -s $(MOZILLA_DTRACE_SRC) -o $(NEED_DTRACE_PROBE_OBJ) $(PROBE_LOBJS) + dtrace -G -C -32 -s $(MOZILLA_DTRACE_SRC) -o $(DTRACE_PROBE_OBJ) $(PROBE_LOBJS) @for lib in $(MOZILLA_PROBE_LIBS); do \ ofiles=`$(AR_LIST) $${lib}`; \ $(AR_DELETE) $${lib} $$ofiles; \ done - $(MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(LOBJS) $(SUB_SHLOBJS) $(NEED_DTRACE_PROBE_OBJ) $(PROBE_LOBJS) $(RESFILE) $(LDFLAGS) $(EXTRA_DSO_LDOPTS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE) + $(MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(LOBJS) $(SUB_SHLOBJS) $(DTRACE_PROBE_OBJ) $(PROBE_LOBJS) $(RESFILE) $(LDFLAGS) $(EXTRA_DSO_LDOPTS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE) @rm -f $(PROBE_LOBJS) - @rm -f $(NEED_DTRACE_PROBE_OBJ) + @rm -f $(DTRACE_PROBE_OBJ) @for lib in $(MOZILLA_PROBE_LIBS); do \ if [ -L $${lib} ]; then rm -f `readlink $${lib}`; fi; \ done @@ -1096,7 +1105,7 @@ ifdef NEED_DTRACE_PROBE_OBJ else $(MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(DTRACE_PROBE_OBJ) $(LOBJS) $(SUB_SHLOBJS) $(RESFILE) $(LDFLAGS) $(EXTRA_DSO_LDOPTS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE) -endif # NEED_DTRACE_PROBE_OBJ +endif # DTRACE_LIB_DEPENDENT ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH)) ifdef MSMANIFEST_TOOL diff --git a/content/base/public/nsContentUtils.h b/content/base/public/nsContentUtils.h index 82a9e4216256..96ed665fbfb4 100644 --- a/content/base/public/nsContentUtils.h +++ b/content/base/public/nsContentUtils.h @@ -557,6 +557,8 @@ public: PRInt16* aImageBlockingStatus = nsnull); /** * Method to start an image load. This does not do any security checks. + * This method will attempt to make aURI immutable; a caller that wants to + * keep a mutable version around should pass in a clone. * * @param aURI uri of the image to be loaded * @param aLoadingDocument the document we belong to @@ -750,42 +752,6 @@ public: */ static nsIContentPolicy *GetContentPolicy(); - /** - * Make sure that whatever value *aPtr contains at any given moment is - * protected from JS GC until we remove the GC root. A call to this that - * succeeds MUST be matched by a call to RemoveJSGCRoot to avoid leaking. - */ - static nsresult AddJSGCRoot(jsval* aPtr, const char* aName) { - return AddJSGCRoot((void*)aPtr, aName); - } - - /** - * Make sure that whatever object *aPtr is pointing to at any given moment is - * protected from JS GC until we remove the GC root. A call to this that - * succeeds MUST be matched by a call to RemoveJSGCRoot to avoid leaking. - */ - static nsresult AddJSGCRoot(JSObject** aPtr, const char* aName) { - return AddJSGCRoot((void*)aPtr, aName); - } - - /** - * Make sure that whatever object *aPtr is pointing to at any given moment is - * protected from JS GC until we remove the GC root. A call to this that - * succeeds MUST be matched by a call to RemoveJSGCRoot to avoid leaking. - */ - static nsresult AddJSGCRoot(void* aPtr, const char* aName); - - /** - * Remove aPtr as a JS GC root - */ - static nsresult RemoveJSGCRoot(jsval* aPtr) { - return RemoveJSGCRoot((void*)aPtr); - } - static nsresult RemoveJSGCRoot(JSObject** aPtr) { - return RemoveJSGCRoot((void*)aPtr); - } - static nsresult RemoveJSGCRoot(void* aPtr); - /** * Quick helper to determine whether there are any mutation listeners * of a given type that apply to this content or any of its ancestors. @@ -950,7 +916,7 @@ public: PRBool aTryReuse); /** - * Get the textual contents of a node. This is a concatination of all + * Get the textual contents of a node. This is a concatenation of all * textnodes that are direct or (depending on aDeep) indirect children * of the node. * @@ -1000,40 +966,73 @@ public: */ static void DestroyAnonymousContent(nsCOMPtr* aContent); - static nsresult HoldScriptObject(PRUint32 aLangID, void *aObject); - static nsresult DropScriptObject(PRUint32 aLangID, void *aObject); - - class ScriptObjectHolder + /** + * Keep script object aNewObject, held by aScriptObjectHolder, alive. + * + * NOTE: This currently only supports objects that hold script objects of one + * scripting language. + * + * @param aLangID script language ID of aNewObject + * @param aScriptObjectHolder the object that holds aNewObject + * @param aTracer the tracer for aScriptObject + * @param aNewObject the script object to hold + * @param aWasHoldingObjects whether aScriptObjectHolder was already holding + * script objects (ie. HoldScriptObject was called + * on it before, without a corresponding call to + * DropScriptObjects) + */ + static nsresult HoldScriptObject(PRUint32 aLangID, void* aScriptObjectHolder, + nsScriptObjectTracer* aTracer, + void* aNewObject, PRBool aWasHoldingObjects) { - public: - ScriptObjectHolder(PRUint32 aLangID) : mLangID(aLangID), - mObject(nsnull) - { - MOZ_COUNT_CTOR(ScriptObjectHolder); + if (aLangID == nsIProgrammingLanguage::JAVASCRIPT) { + return aWasHoldingObjects ? NS_OK : + HoldJSObjects(aScriptObjectHolder, aTracer); } - ~ScriptObjectHolder() - { - MOZ_COUNT_DTOR(ScriptObjectHolder); - if (mObject) - DropScriptObject(mLangID, mObject); + + return HoldScriptObject(aLangID, aNewObject); + } + + /** + * Drop any script objects that aScriptObjectHolder is holding. + * + * NOTE: This currently only supports objects that hold script objects of one + * scripting language. + * + * @param aLangID script language ID of the objects that + * @param aScriptObjectHolder the object that holds script object that we want + * to drop + * @param aTracer the tracer for aScriptObject + */ + static nsresult DropScriptObjects(PRUint32 aLangID, void* aScriptObjectHolder, + nsScriptObjectTracer* aTracer) + { + if (aLangID == nsIProgrammingLanguage::JAVASCRIPT) { + return DropJSObjects(aScriptObjectHolder); } - nsresult set(void *aObject) - { - NS_ASSERTION(aObject, "unexpected null object"); - NS_ASSERTION(!mObject, "already have an object"); - nsresult rv = HoldScriptObject(mLangID, aObject); - if (NS_SUCCEEDED(rv)) { - mObject = aObject; - } - return rv; - } - void traverse(nsCycleCollectionTraversalCallback &cb) - { - cb.NoteScriptChild(mLangID, mObject); - } - PRUint32 mLangID; - void *mObject; - }; + + aTracer->Trace(aScriptObjectHolder, DropScriptObject, nsnull); + + return NS_OK; + } + + /** + * Keep the JS objects held by aScriptObjectHolder alive. + * + * @param aScriptObjectHolder the object that holds JS objects that we want to + * keep alive + * @param aTracer the tracer for aScriptObject + */ + static nsresult HoldJSObjects(void* aScriptObjectHolder, + nsScriptObjectTracer* aTracer); + + /** + * Drop the JS objects held by aScriptObjectHolder. + * + * @param aScriptObjectHolder the object that holds JS objects that we want to + * drop + */ + static nsresult DropJSObjects(void* aScriptObjectHolder); /** * Convert nsIContent::IME_STATUS_* to nsIKBStateControll::IME_STATUS_* @@ -1120,6 +1119,10 @@ private: static nsIDOMScriptObjectFactory *GetDOMScriptObjectFactory(); + static nsresult HoldScriptObject(PRUint32 aLangID, void* aObject); + PR_STATIC_CALLBACK(void) DropScriptObject(PRUint32 aLangID, void *aObject, + void *aClosure); + static nsIDOMScriptObjectFactory *sDOMScriptObjectFactory; static nsIXPConnect *sXPConnect; @@ -1161,14 +1164,9 @@ private: // Holds pointers to nsISupports* that should be released at shutdown static nsVoidArray* sPtrsToPtrsToRelease; - // For now, we don't want to automatically clean this up in Shutdown(), since - // consumers might unfortunately end up wanting to use it after that - static nsIJSRuntimeService* sJSRuntimeService; - static JSRuntime* sJSScriptRuntime; - static PRInt32 sJSScriptRootCount; - static nsIScriptRuntime* sScriptRuntimes[NS_STID_ARRAY_UBOUND]; static PRInt32 sScriptRootCount[NS_STID_ARRAY_UBOUND]; + static PRUint32 sJSGCThingRootCount; #ifdef IBMBIDI static nsIBidiKeyboard* sBidiKeyboard; @@ -1178,6 +1176,14 @@ private: }; +#define NS_HOLD_JS_OBJECTS(obj, clazz) \ + nsContentUtils::HoldJSObjects(NS_CYCLE_COLLECTION_UPCAST(obj, clazz), \ + &NS_CYCLE_COLLECTION_NAME(clazz)) + +#define NS_DROP_JS_OBJECTS(obj, clazz) \ + nsContentUtils::DropJSObjects(NS_CYCLE_COLLECTION_UPCAST(obj, clazz)) + + class nsCxPusher { public: @@ -1200,33 +1206,38 @@ public: nsAutoGCRoot(jsval* aPtr, nsresult* aResult) : mPtr(aPtr) { - mResult = *aResult = - nsContentUtils::AddJSGCRoot(aPtr, "nsAutoGCRoot"); + mResult = *aResult = AddJSGCRoot(aPtr, "nsAutoGCRoot"); } // aPtr should be the pointer to the JSObject* we want to protect nsAutoGCRoot(JSObject** aPtr, nsresult* aResult) : mPtr(aPtr) { - mResult = *aResult = - nsContentUtils::AddJSGCRoot(aPtr, "nsAutoGCRoot"); + mResult = *aResult = AddJSGCRoot(aPtr, "nsAutoGCRoot"); } // aPtr should be the pointer to the thing we want to protect nsAutoGCRoot(void* aPtr, nsresult* aResult) : mPtr(aPtr) { - mResult = *aResult = - nsContentUtils::AddJSGCRoot(aPtr, "nsAutoGCRoot"); + mResult = *aResult = AddJSGCRoot(aPtr, "nsAutoGCRoot"); } ~nsAutoGCRoot() { if (NS_SUCCEEDED(mResult)) { - nsContentUtils::RemoveJSGCRoot(mPtr); + RemoveJSGCRoot(mPtr); } } + static void Shutdown(); + private: + static nsresult AddJSGCRoot(void *aPtr, const char* aName); + static nsresult RemoveJSGCRoot(void *aPtr); + + static nsIJSRuntimeService* sJSRuntimeService; + static JSRuntime* sJSScriptRuntime; + void* mPtr; nsresult mResult; }; diff --git a/content/base/public/nsINode.h b/content/base/public/nsINode.h index 7c5fa009d292..a482fbe75f57 100644 --- a/content/base/public/nsINode.h +++ b/content/base/public/nsINode.h @@ -100,8 +100,11 @@ enum { NODE_IS_INSERTION_PARENT = 0x00001000U, + // Keep track of whether this node is in the middle of binding teardown + NODE_IS_IN_BINDING_TEARDOWN = 0x00002000U, + // Four bits for the script-type ID - NODE_SCRIPT_TYPE_OFFSET = 13, + NODE_SCRIPT_TYPE_OFFSET = 14, NODE_SCRIPT_TYPE_SIZE = 4, diff --git a/content/base/public/nsLineBreaker.h b/content/base/public/nsLineBreaker.h index af2aa3633b81..be1f86a54652 100644 --- a/content/base/public/nsLineBreaker.h +++ b/content/base/public/nsLineBreaker.h @@ -73,9 +73,9 @@ public: * into AppendText calls. * * The current strategy is that we break the overall text into - * whitespace-delimited "words". Then for words that contain a "complex" - * character (currently CJK or Thai), we break within the word using complex - * rules (JISx4051 or Pango). + * whitespace-delimited "words". Then those words are passed to the nsILineBreaker + * service for deeper analysis if they contain a "complex" character as described + * below. */ class nsLineBreaker { public: @@ -102,9 +102,9 @@ public: (0xff00 <= u && u <= 0xffef); // Halfwidth and Fullwidth Forms } - // Normally, break opportunities exist at the end of each run of whitespace - // (see IsSpace above). Break opportunities can also exist inside runs of - // non-whitespace, as determined by nsILineBreaker. We pass a whitespace- + // Break opportunities exist at the end of each run of breakable whitespace + // (see IsSpace above). Break opportunities can also exist between pairs of + // non-whitespace characters, as determined by nsILineBreaker. We pass a whitespace- // delimited word to nsILineBreaker if it contains at least one character // matching IsComplexChar. // We provide flags to control on a per-chunk basis where breaks are allowed. @@ -114,22 +114,38 @@ public: // We operate on text after whitespace processing has been applied, so // other characters (e.g. tabs and newlines) may have been converted to // spaces. + + /** + * Flags passed with each chunk of text. + */ enum { - /** - * Allow a break opportunity at the start of this chunk of text. + /* + * Do not introduce a break opportunity at the start of this chunk of text. */ - BREAK_ALLOW_INITIAL = 0x01, + BREAK_SUPPRESS_INITIAL = 0x01, /** - * Allow a break opportunity in the interior of this chunk of text. + * Do not introduce a break opportunity in the interior of this chunk of text. + * Also, whitespace in this chunk is treated as non-breakable. */ - BREAK_ALLOW_INSIDE = 0x02 + BREAK_SUPPRESS_INSIDE = 0x02, + /** + * The sink currently is already set up to have no breaks in it; + * if no breaks are possible, nsLineBreaker does not need to call + * SetBreaks on it. This is useful when handling large quantities of + * preformatted text; the textruns will never have any breaks set on them, + * and there is no need to ever actually scan the text for breaks, except + * at the end of textruns in case context is needed for following breakable + * text. + */ + BREAK_SKIP_SETTING_NO_BREAKS = 0x04 }; /** * Append "invisible whitespace". This acts like whitespace, but there is - * no actual text associated with it. + * no actual text associated with it. Only the BREAK_SUPPRESS_INSIDE flag + * is relevant here. */ - nsresult AppendInvisibleWhitespace(); + nsresult AppendInvisibleWhitespace(PRUint32 aFlags); /** * Feed Unicode text into the linebreaker for analysis. aLength must be @@ -184,8 +200,11 @@ private: nsAutoTArray mTextItems; PRPackedBool mCurrentWordContainsComplexChar; - // True if the previous character was whitespace - PRPackedBool mAfterSpace; + // True if the previous character was breakable whitespace + PRPackedBool mAfterBreakableSpace; + // True if a break must be allowed at the current position because + // a run of breakable whitespace ends here + PRPackedBool mBreakHere; }; #endif /*NSLINEBREAKER_H_*/ diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index cc85bdb3a6e4..6957e21c3d7d 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -180,15 +180,15 @@ nsILineBreaker *nsContentUtils::sLineBreaker; nsIWordBreaker *nsContentUtils::sWordBreaker; nsICaseConversion *nsContentUtils::sCaseConv; nsVoidArray *nsContentUtils::sPtrsToPtrsToRelease; -nsIJSRuntimeService *nsContentUtils::sJSRuntimeService; -JSRuntime *nsContentUtils::sJSScriptRuntime; -PRInt32 nsContentUtils::sJSScriptRootCount = 0; nsIScriptRuntime *nsContentUtils::sScriptRuntimes[NS_STID_ARRAY_UBOUND]; PRInt32 nsContentUtils::sScriptRootCount[NS_STID_ARRAY_UBOUND]; +PRUint32 nsContentUtils::sJSGCThingRootCount; #ifdef IBMBIDI nsIBidiKeyboard *nsContentUtils::sBidiKeyboard = nsnull; #endif +nsIJSRuntimeService *nsAutoGCRoot::sJSRuntimeService; +JSRuntime *nsAutoGCRoot::sJSScriptRuntime; PRBool nsContentUtils::sInitialized = PR_FALSE; @@ -671,7 +671,8 @@ nsContentUtils::Shutdown() NS_IF_RELEASE(sStringBundleService); NS_IF_RELEASE(sConsoleService); NS_IF_RELEASE(sDOMScriptObjectFactory); - NS_IF_RELEASE(sXPConnect); + if (sJSGCThingRootCount == 0 && sXPConnect) + NS_RELEASE(sXPConnect); NS_IF_RELEASE(sSecurityManager); NS_IF_RELEASE(sThreadJSContextStack); NS_IF_RELEASE(sNameSpaceManager); @@ -721,6 +722,8 @@ nsContentUtils::Shutdown() sEventListenerManagersHash.ops = nsnull; } } + + nsAutoGCRoot::Shutdown(); } static PRBool IsCallerTrustedForCapability(const char* aCapability) @@ -2157,6 +2160,9 @@ nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument, nsIURI *documentURI = aLoadingDocument->GetDocumentURI(); + // Make the URI immutable so people won't change it under us + NS_TryToSetImmutable(aURI); + // We don't use aLoadingPrincipal for anything here yet... but we // will. See bug 377092. @@ -2669,7 +2675,7 @@ nsContentUtils::GetContentPolicy() // static nsresult -nsContentUtils::AddJSGCRoot(void* aPtr, const char* aName) +nsAutoGCRoot::AddJSGCRoot(void* aPtr, const char* aName) { if (!sJSScriptRuntime) { nsresult rv = CallGetService("@mozilla.org/js/xpc/RuntimeService;1", @@ -2687,25 +2693,16 @@ nsContentUtils::AddJSGCRoot(void* aPtr, const char* aName) PRBool ok; ok = ::JS_AddNamedRootRT(sJSScriptRuntime, aPtr, aName); if (!ok) { - if (sJSScriptRootCount == 0) { - // We just got the runtime... Just null things out, since no - // one's expecting us to have a runtime yet - NS_RELEASE(sJSRuntimeService); - sJSScriptRuntime = nsnull; - } NS_WARNING("JS_AddNamedRootRT failed"); return NS_ERROR_OUT_OF_MEMORY; } - // We now have one more root we added to the runtime - ++sJSScriptRootCount; - return NS_OK; } /* static */ nsresult -nsContentUtils::RemoveJSGCRoot(void* aPtr) +nsAutoGCRoot::RemoveJSGCRoot(void* aPtr) { if (!sJSScriptRuntime) { NS_NOTREACHED("Trying to remove a JS GC root when none were added"); @@ -2714,11 +2711,6 @@ nsContentUtils::RemoveJSGCRoot(void* aPtr) ::JS_RemoveRootRT(sJSScriptRuntime, aPtr); - if (--sJSScriptRootCount == 0) { - NS_RELEASE(sJSRuntimeService); - sJSScriptRuntime = nsnull; - } - return NS_OK; } @@ -3522,6 +3514,8 @@ nsresult nsContentUtils::HoldScriptObject(PRUint32 aLangID, void *aObject) { NS_ASSERTION(aObject, "unexpected null object"); + NS_ASSERTION(aLangID != nsIProgrammingLanguage::JAVASCRIPT, + "Should use HoldJSObjects."); nsresult rv; PRUint32 langIndex = NS_STID_INDEX(aLangID); @@ -3548,17 +3542,47 @@ nsContentUtils::HoldScriptObject(PRUint32 aLangID, void *aObject) } /* static */ -nsresult -nsContentUtils::DropScriptObject(PRUint32 aLangID, void *aObject) +void +nsContentUtils::DropScriptObject(PRUint32 aLangID, void *aObject, + void *aClosure) { NS_ASSERTION(aObject, "unexpected null object"); + NS_ASSERTION(aLangID != nsIProgrammingLanguage::JAVASCRIPT, + "Should use DropJSObjects."); PRUint32 langIndex = NS_STID_INDEX(aLangID); NS_LOG_RELEASE(sScriptRuntimes[langIndex], sScriptRootCount[langIndex] - 1, "HoldScriptObject"); - nsresult rv = sScriptRuntimes[langIndex]->DropScriptObject(aObject); + sScriptRuntimes[langIndex]->DropScriptObject(aObject); if (--sScriptRootCount[langIndex] == 0) { NS_RELEASE(sScriptRuntimes[langIndex]); } +} + +/* static */ +nsresult +nsContentUtils::HoldJSObjects(void* aScriptObjectHolder, + nsScriptObjectTracer* aTracer) +{ + PRBool newHolder; + nsresult rv = sXPConnect->AddJSHolder(aScriptObjectHolder, aTracer); + NS_ENSURE_SUCCESS(rv, rv); + + ++sJSGCThingRootCount; + NS_LOG_ADDREF(sXPConnect, sJSGCThingRootCount, "HoldJSObjects", + sizeof(void*)); + + return NS_OK; +} + +/* static */ +nsresult +nsContentUtils::DropJSObjects(void* aScriptObjectHolder) +{ + NS_LOG_RELEASE(sXPConnect, sJSGCThingRootCount - 1, "HoldJSObjects"); + nsresult rv = sXPConnect->RemoveJSHolder(aScriptObjectHolder); + if (--sJSGCThingRootCount == 0 && !sInitialized) { + NS_RELEASE(sXPConnect); + } return rv; } @@ -3640,7 +3664,7 @@ nsContentUtils::CheckSecurityBeforeLoad(nsIURI* aURIToLoad, nsCOMPtr loadingURI; rv = aLoadingPrincipal->GetURI(getter_AddRefs(loadingURI)); NS_ENSURE_SUCCESS(rv, rv); - return sSecurityManager->CheckSameOriginURI(loadingURI, aURIToLoad); + return sSecurityManager->CheckSameOriginURI(loadingURI, aURIToLoad, PR_TRUE); } /* static */ @@ -3698,10 +3722,26 @@ nsContentUtils::IsNativeAnonymous(nsIContent* aContent) return PR_TRUE; } - NS_ASSERTION(!aContent->IsNativeAnonymous(), + // Nasty hack to work around spell-check resolving style on + // native-anonymous content that's already been torn down. Don't assert + // !IsNativeAnonymous() if aContent->GetCurrentDoc() is null. The caller + // will get "wrong" style data, but it's just asking for that sort of thing + // anyway. + NS_ASSERTION(!aContent->IsNativeAnonymous() || + !aContent->GetCurrentDoc() || + (aContent->GetParent() && + aContent->GetParent()->NodeInfo()-> + Equals(nsGkAtoms::use, kNameSpaceID_SVG)), "Native anonymous node with wrong binding parent"); aContent = bindingParent; } return PR_FALSE; } + +/* static */ +void +nsAutoGCRoot::Shutdown() +{ + NS_IF_RELEASE(sJSRuntimeService); +} diff --git a/content/base/src/nsCrossSiteListenerProxy.cpp b/content/base/src/nsCrossSiteListenerProxy.cpp index 5c603fc97e74..2b6ed3bce954 100644 --- a/content/base/src/nsCrossSiteListenerProxy.cpp +++ b/content/base/src/nsCrossSiteListenerProxy.cpp @@ -134,7 +134,7 @@ nsCrossSiteListenerProxy::OnStartRequest(nsIRequest* aRequest, nsCOMPtr finalURI; channel->GetURI(getter_AddRefs(finalURI)); rv = nsContentUtils::GetSecurityManager()-> - CheckSameOriginURI(mRequestingURI, finalURI); + CheckSameOriginURI(mRequestingURI, finalURI, PR_FALSE); if (NS_SUCCEEDED(rv)) { mAcceptState = eAccept; return ForwardRequest(PR_FALSE); diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index 300f44fda70f..4567ccb83513 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -1161,13 +1161,7 @@ nsDocument::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup) // Note: this code is duplicated in nsXULDocument::StartDocumentLoad and // nsScriptSecurityManager::GetChannelPrincipal. // Note: this should match nsDocShell::OnLoadingSite - nsLoadFlags loadFlags = 0; - nsresult rv = aChannel->GetLoadFlags(&loadFlags); - if (NS_SUCCEEDED(rv) && (loadFlags & nsIChannel::LOAD_REPLACE)) { - aChannel->GetURI(getter_AddRefs(uri)); - } else { - aChannel->GetOriginalURI(getter_AddRefs(uri)); - } + NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri)); nsIScriptSecurityManager *securityManager = nsContentUtils::GetSecurityManager(); diff --git a/content/base/src/nsDocument.h b/content/base/src/nsDocument.h index 0440c8098bcd..235b26064740 100644 --- a/content/base/src/nsDocument.h +++ b/content/base/src/nsDocument.h @@ -792,6 +792,9 @@ protected: nsString mBaseTarget; + // Our update nesting level + PRUint32 mUpdateNestLevel; + private: friend class nsUnblockOnloadEvent; @@ -833,9 +836,6 @@ private: // Member to store out last-selected stylesheet set. nsString mLastStyleSheetSet; - - // Our update nesting level - PRUint32 mUpdateNestLevel; }; diff --git a/content/base/src/nsGkAtomList.h b/content/base/src/nsGkAtomList.h index 447167643d65..ea6fc17e72e2 100755 --- a/content/base/src/nsGkAtomList.h +++ b/content/base/src/nsGkAtomList.h @@ -838,6 +838,7 @@ GK_ATOM(thead, "thead") GK_ATOM(thumb, "thumb") GK_ATOM(title, "title") GK_ATOM(titlebar, "titlebar") +GK_ATOM(titlebarcolor, "titlebarcolor") GK_ATOM(titletip, "titletip") GK_ATOM(toggled, "toggled") GK_ATOM(token, "token") diff --git a/content/base/src/nsLineBreaker.cpp b/content/base/src/nsLineBreaker.cpp index 1df29c88b6ba..dc2b83f7d32b 100644 --- a/content/base/src/nsLineBreaker.cpp +++ b/content/base/src/nsLineBreaker.cpp @@ -42,7 +42,7 @@ nsLineBreaker::nsLineBreaker() : mCurrentWordContainsComplexChar(PR_FALSE), - mAfterSpace(PR_FALSE) + mAfterBreakableSpace(PR_FALSE), mBreakHere(PR_FALSE) { } @@ -72,10 +72,10 @@ nsLineBreaker::FlushCurrentWord() TextItem* ti = &mTextItems[i]; NS_ASSERTION(ti->mLength > 0, "Zero length word contribution?"); - if (!(ti->mFlags & BREAK_ALLOW_INITIAL) && ti->mSinkOffset == 0) { + if ((ti->mFlags & BREAK_SUPPRESS_INITIAL) && ti->mSinkOffset == 0) { breakState[offset] = PR_FALSE; } - if (!(ti->mFlags & BREAK_ALLOW_INSIDE)) { + if (ti->mFlags & BREAK_SUPPRESS_INSIDE) { PRUint32 exclude = ti->mSinkOffset == 0 ? 1 : 0; memset(breakState.Elements() + offset + exclude, PR_FALSE, ti->mLength - exclude); } @@ -107,7 +107,7 @@ nsLineBreaker::AppendText(nsIAtom* aLangGroup, const PRUnichar* aText, PRUint32 // Continue the current word if (mCurrentWord.Length() > 0) { - NS_ASSERTION(!mAfterSpace, "These should not be set"); + NS_ASSERTION(!mAfterBreakableSpace && !mBreakHere, "These should not be set"); while (offset < aLength && !IsSpace(aText[offset])) { mCurrentWord.AppendElement(aText[offset]); @@ -137,8 +137,14 @@ nsLineBreaker::AppendText(nsIAtom* aLangGroup, const PRUnichar* aText, PRUint32 } PRUint32 start = offset; - if (!aSink && !aFlags) { - // Skip to the space before the last word, since we don't need the breaks + PRBool noBreaksNeeded = !aSink || + ((aFlags & BREAK_SUPPRESS_INITIAL) && (aFlags & BREAK_SUPPRESS_INSIDE) && + !mBreakHere && !mAfterBreakableSpace && (aFlags & BREAK_SKIP_SETTING_NO_BREAKS)); + if (noBreaksNeeded) { + // Skip to the space before the last word, since either the break data + // here is not needed, or no breaks are set in the sink and there cannot + // be any breaks in this chunk; all we need is the context for the next + // chunk (if any) offset = aLength; while (offset > start) { --offset; @@ -152,16 +158,17 @@ nsLineBreaker::AppendText(nsIAtom* aLangGroup, const PRUnichar* aText, PRUint32 for (;;) { PRUnichar ch = aText[offset]; PRBool isSpace = IsSpace(ch); + PRBool isBreakableSpace = isSpace && !(aFlags & BREAK_SUPPRESS_INSIDE); if (aSink) { - breakState[offset] = mAfterSpace && !isSpace && - (aFlags & (offset == 0 ? BREAK_ALLOW_INITIAL : BREAK_ALLOW_INSIDE)); + breakState[offset] = mBreakHere || (mAfterBreakableSpace && !isBreakableSpace); } - mAfterSpace = isSpace; + mBreakHere = PR_FALSE; + mAfterBreakableSpace = isBreakableSpace; if (isSpace) { if (offset > wordStart && wordHasComplexChar) { - if (aSink && (aFlags & BREAK_ALLOW_INSIDE)) { + if (aSink && !(aFlags & BREAK_SUPPRESS_INSIDE)) { // Save current start-of-word state because GetJISx4051Breaks will // set it to false PRPackedBool currentStart = breakState[wordStart]; @@ -198,7 +205,7 @@ nsLineBreaker::AppendText(nsIAtom* aLangGroup, const PRUnichar* aText, PRUint32 } } - if (aSink) { + if (!noBreaksNeeded) { aSink->SetBreaks(start, offset - start, breakState.Elements() + start); } return NS_OK; @@ -214,7 +221,7 @@ nsLineBreaker::AppendText(nsIAtom* aLangGroup, const PRUint8* aText, PRUint32 aL // Continue the current word if (mCurrentWord.Length() > 0) { - NS_ASSERTION(!mAfterSpace, "These should not be set"); + NS_ASSERTION(!mAfterBreakableSpace && !mBreakHere, "These should not be set"); while (offset < aLength && !IsSpace(aText[offset])) { mCurrentWord.AppendElement(aText[offset]); @@ -247,8 +254,14 @@ nsLineBreaker::AppendText(nsIAtom* aLangGroup, const PRUint8* aText, PRUint32 aL } PRUint32 start = offset; - if (!aSink && !aFlags) { - // Skip to the space before the last word, since we don't need the breaks + PRBool noBreaksNeeded = !aSink || + ((aFlags & BREAK_SUPPRESS_INITIAL) && (aFlags & BREAK_SUPPRESS_INSIDE) && + !mBreakHere && !mAfterBreakableSpace && (aFlags & BREAK_SKIP_SETTING_NO_BREAKS)); + if (noBreaksNeeded) { + // Skip to the space before the last word, since either the break data + // here is not needed, or no breaks are set in the sink and there cannot + // be any breaks in this chunk; all we need is the context for the next + // chunk (if any) offset = aLength; while (offset > start) { --offset; @@ -262,16 +275,17 @@ nsLineBreaker::AppendText(nsIAtom* aLangGroup, const PRUint8* aText, PRUint32 aL for (;;) { PRUint8 ch = aText[offset]; PRBool isSpace = IsSpace(ch); + PRBool isBreakableSpace = isSpace && !(aFlags & BREAK_SUPPRESS_INSIDE); if (aSink) { - breakState[offset] = mAfterSpace && !isSpace && - (aFlags & (offset == 0 ? BREAK_ALLOW_INITIAL : BREAK_ALLOW_INSIDE)); + breakState[offset] = mBreakHere || (mAfterBreakableSpace && !isBreakableSpace); } - mAfterSpace = isSpace; + mBreakHere = PR_FALSE; + mAfterBreakableSpace = isBreakableSpace; if (isSpace) { if (offset > wordStart && wordHasComplexChar) { - if (aSink && (aFlags & BREAK_ALLOW_INSIDE)) { + if (aSink && !(aFlags & BREAK_SUPPRESS_INSIDE)) { // Save current start-of-word state because GetJISx4051Breaks will // set it to false PRPackedBool currentStart = breakState[wordStart]; @@ -311,18 +325,22 @@ nsLineBreaker::AppendText(nsIAtom* aLangGroup, const PRUint8* aText, PRUint32 aL } } - if (aSink) { + if (!noBreaksNeeded) { aSink->SetBreaks(start, offset - start, breakState.Elements() + start); } return NS_OK; } nsresult -nsLineBreaker::AppendInvisibleWhitespace() { - // Treat as "invisible whitespace" +nsLineBreaker::AppendInvisibleWhitespace(PRUint32 aFlags) { nsresult rv = FlushCurrentWord(); if (NS_FAILED(rv)) return rv; - mAfterSpace = PR_TRUE; + + PRBool isBreakableSpace = !(aFlags & BREAK_SUPPRESS_INSIDE); + if (mAfterBreakableSpace && !isBreakableSpace) { + mBreakHere = PR_TRUE; + } + mAfterBreakableSpace = isBreakableSpace; return NS_OK; } diff --git a/content/base/src/nsSyncLoadService.cpp b/content/base/src/nsSyncLoadService.cpp index 6b1b4a5e3fc5..d46568c1d874 100644 --- a/content/base/src/nsSyncLoadService.cpp +++ b/content/base/src/nsSyncLoadService.cpp @@ -194,7 +194,7 @@ nsSyncLoader::LoadDocument(nsIChannel* aChannel, nsIScriptSecurityManager::STANDARD); NS_ENSURE_SUCCESS(rv, rv); - rv = securityManager->CheckSameOriginURI(aLoaderURI, docURI); + rv = securityManager->CheckSameOriginURI(aLoaderURI, docURI, PR_TRUE); NS_ENSURE_SUCCESS(rv, rv); } @@ -378,7 +378,7 @@ nsSyncLoader::OnChannelRedirect(nsIChannel *aOldChannel, nsIScriptSecurityManager *securityManager = nsContentUtils::GetSecurityManager(); - rv = securityManager->CheckSameOriginURI(oldURI, newURI); + rv = securityManager->CheckSameOriginURI(oldURI, newURI, PR_TRUE); NS_ENSURE_SUCCESS(rv, rv); mChannel = aNewChannel; diff --git a/content/base/src/nsXMLHttpRequest.cpp b/content/base/src/nsXMLHttpRequest.cpp index cc39b3a575ad..27a7eb8c6ff8 100644 --- a/content/base/src/nsXMLHttpRequest.cpp +++ b/content/base/src/nsXMLHttpRequest.cpp @@ -56,6 +56,7 @@ #include "prprf.h" #include "nsIDOMEventListener.h" #include "nsIJSContextStack.h" +#include "nsJSEnvironment.h" #include "nsIScriptSecurityManager.h" #include "nsWeakPtr.h" #include "nsICharsetAlias.h" @@ -1149,7 +1150,8 @@ IsSameOrigin(nsIPrincipal* aPrincipal, nsIChannel* aChannel) rv = aChannel->GetURI(getter_AddRefs(channelURI)); NS_ENSURE_SUCCESS(rv, rv); - rv = nsContentUtils::GetSecurityManager()->CheckSameOriginURI(codebase, channelURI); + rv = nsContentUtils::GetSecurityManager()-> + CheckSameOriginURI(codebase, channelURI, PR_FALSE); return NS_SUCCEEDED(rv); } @@ -1778,6 +1780,7 @@ nsXMLHttpRequest::RequestCompleted() ChangeState(XML_HTTP_REQUEST_OPENED); } + nsJSContext::MaybeCC(PR_FALSE); return rv; } @@ -2320,6 +2323,7 @@ nsXMLHttpRequest::Error(nsIDOMEvent* aEvent) NotifyEventListeners(errorEventListeners, event); } + nsJSContext::MaybeCC(PR_FALSE); return NS_OK; } diff --git a/content/canvas/src/nsCanvasRenderingContext2D.cpp b/content/canvas/src/nsCanvasRenderingContext2D.cpp index 8b0f2ea9ba31..9b4db0b7d93a 100644 --- a/content/canvas/src/nsCanvasRenderingContext2D.cpp +++ b/content/canvas/src/nsCanvasRenderingContext2D.cpp @@ -2465,6 +2465,13 @@ nsCanvasRenderingContext2D::GetImageData() PRUint8 g = *row++; PRUint8 b = *row++; #endif + // Convert to non-premultiplied color + if (a != 0) { + r = (r * 255) / a; + g = (g * 255) / a; + b = (b * 255) / a; + } + *dest++ = INT_TO_JSVAL(r); *dest++ = INT_TO_JSVAL(g); *dest++ = INT_TO_JSVAL(b); @@ -2588,6 +2595,11 @@ nsCanvasRenderingContext2D::PutImageData() else if (JSVAL_IS_DOUBLE(va)) ia = (PRUint8) (*JSVAL_TO_DOUBLE(va)); else return NS_ERROR_DOM_SYNTAX_ERR; + // Convert to premultiplied color (losslessly if the input came from getImageData) + ir = (ir*ia + 254) / 255; + ig = (ig*ia + 254) / 255; + ib = (ib*ia + 254) / 255; + #ifdef IS_LITTLE_ENDIAN *imgPtr++ = ib; *imgPtr++ = ig; diff --git a/content/events/src/nsEventStateManager.cpp b/content/events/src/nsEventStateManager.cpp index aebc2d709810..500f42b56781 100644 --- a/content/events/src/nsEventStateManager.cpp +++ b/content/events/src/nsEventStateManager.cpp @@ -136,6 +136,9 @@ #include "nsEventDispatcher.h" #include "nsPresShellIterator.h" +#include "nsServiceManagerUtils.h" +#include "nsITimer.h" + #ifdef XP_MACOSX #include #endif @@ -144,6 +147,8 @@ //#define DEBUG_DOCSHELL_FOCUS #endif +#define NS_USER_INTERACTION_INTERVAL 5000 // ms + static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID); @@ -171,12 +176,48 @@ static PRUint32 sESMInstanceCount = 0; static PRInt32 sChromeAccessModifier = 0, sContentAccessModifier = 0; PRInt32 nsEventStateManager::sUserInputEventDepth = 0; +static PRUint32 gMouseOrKeyboardEventCounter = 0; +static nsITimer* gUserInteractionTimer = nsnull; +static nsITimerCallback* gUserInteractionTimerCallback = nsnull; + +class nsUITimerCallback : public nsITimerCallback +{ +public: + nsUITimerCallback() : mPreviousCount(0) {} + NS_DECL_ISUPPORTS + NS_DECL_NSITIMERCALLBACK +private: + PRUint32 mPreviousCount; +}; + +NS_IMPL_ISUPPORTS1(nsUITimerCallback, nsITimerCallback) + +// If aTimer is nsnull, this method always sends "user-interaction-inactive" +// notification. +NS_IMETHODIMP +nsUITimerCallback::Notify(nsITimer* aTimer) +{ + nsresult rv; + nsCOMPtr obs = + do_GetService("@mozilla.org/observer-service;1", &rv); + NS_ENSURE_SUCCESS(rv, rv); + if ((gMouseOrKeyboardEventCounter == mPreviousCount) || !aTimer) { + gMouseOrKeyboardEventCounter = 0; + obs->NotifyObservers(nsnull, "user-interaction-inactive", nsnull); + } else { + obs->NotifyObservers(nsnull, "user-interaction-active", nsnull); + } + mPreviousCount = gMouseOrKeyboardEventCounter; + return NS_OK; +} + enum { MOUSE_SCROLL_N_LINES, MOUSE_SCROLL_PAGE, MOUSE_SCROLL_HISTORY, MOUSE_SCROLL_TEXTSIZE, - MOUSE_SCROLL_PIXELS + MOUSE_SCROLL_PIXELS, + MOUSE_SCROLL_FULLZOOM }; struct AccessKeyInfo { @@ -431,6 +472,18 @@ nsEventStateManager::nsEventStateManager() mTabbedThroughDocument(PR_FALSE), mAccessKeys(nsnull) { + if (sESMInstanceCount == 0) { + gUserInteractionTimerCallback = new nsUITimerCallback(); + if (gUserInteractionTimerCallback) { + NS_ADDREF(gUserInteractionTimerCallback); + CallCreateInstance("@mozilla.org/timer;1", &gUserInteractionTimer); + if (gUserInteractionTimer) { + gUserInteractionTimer->InitWithCallback(gUserInteractionTimerCallback, + NS_USER_INTERACTION_INTERVAL, + nsITimer::TYPE_REPEATING_SLACK); + } + } + } ++sESMInstanceCount; } @@ -509,6 +562,14 @@ nsEventStateManager::~nsEventStateManager() if(sESMInstanceCount == 0) { NS_IF_RELEASE(gLastFocusedContent); NS_IF_RELEASE(gLastFocusedDocument); + if (gUserInteractionTimerCallback) { + gUserInteractionTimerCallback->Notify(nsnull); + NS_RELEASE(gUserInteractionTimerCallback); + } + if (gUserInteractionTimer) { + gUserInteractionTimer->Cancel(); + NS_RELEASE(gUserInteractionTimer); + } } delete mAccessKeys; @@ -724,6 +785,25 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext, if (!mCurrentTarget) return NS_ERROR_NULL_POINTER; } + // Do not take account NS_MOUSE_ENTER/EXIT so that loading a page + // when user is not active doesn't change the state to active. + if (NS_IS_TRUSTED_EVENT(aEvent) && + ((aEvent->eventStructType == NS_MOUSE_EVENT && + static_cast(aEvent)->reason == nsMouseEvent::eReal && + aEvent->message != NS_MOUSE_ENTER && + aEvent->message != NS_MOUSE_EXIT) || + aEvent->eventStructType == NS_MOUSE_SCROLL_EVENT || + aEvent->eventStructType == NS_KEY_EVENT)) { + if (gMouseOrKeyboardEventCounter == 0) { + nsCOMPtr obs = + do_GetService("@mozilla.org/observer-service;1"); + if (obs) { + obs->NotifyObservers(nsnull, "user-interaction-active", nsnull); + } + } + ++gMouseOrKeyboardEventCounter; + } + *aStatus = nsEventStatus_eIgnore; nsMouseWheelTransaction::OnEvent(aEvent); @@ -1859,8 +1939,10 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext, } // GenerateDragGesture nsresult -nsEventStateManager::ChangeTextSize(PRInt32 change) +nsEventStateManager::GetMarkupDocumentViewer(nsIMarkupDocumentViewer** aMv) { + *aMv = nsnull; + if(!gLastFocusedDocument) return NS_ERROR_FAILURE; nsPIDOMWindow* ourWindow = gLastFocusedDocument->GetWindow(); @@ -1894,6 +1976,19 @@ nsEventStateManager::ChangeTextSize(PRInt32 change) nsCOMPtr mv(do_QueryInterface(cv)); if(!mv) return NS_ERROR_FAILURE; + *aMv = mv; + NS_IF_ADDREF(*aMv); + + return NS_OK; +} + +nsresult +nsEventStateManager::ChangeTextSize(PRInt32 change) +{ + nsCOMPtr mv; + nsresult rv = GetMarkupDocumentViewer(getter_AddRefs(mv)); + NS_ENSURE_SUCCESS(rv, rv); + float textzoom; mv->GetTextZoom(&textzoom); textzoom += ((float)change) / 10; @@ -1903,6 +1998,27 @@ nsEventStateManager::ChangeTextSize(PRInt32 change) return NS_OK; } +nsresult +nsEventStateManager::ChangeFullZoom(PRInt32 change) +{ + nsCOMPtr mv; + nsresult rv = GetMarkupDocumentViewer(getter_AddRefs(mv)); + NS_ENSURE_SUCCESS(rv, rv); + + float fullzoom; + float zoomMin = ((float)nsContentUtils::GetIntPref("fullZoom.minPercent", 50)) / 100; + float zoomMax = ((float)nsContentUtils::GetIntPref("fullZoom.maxPercent", 300)) / 100; + mv->GetFullZoom(&fullzoom); + fullzoom += ((float)change) / 10; + if (fullzoom < zoomMin) + fullzoom = zoomMin; + else if (fullzoom > zoomMax) + fullzoom = zoomMax; + mv->SetFullZoom(fullzoom); + + return NS_OK; +} + void nsEventStateManager::DoScrollHistory(PRInt32 direction) { @@ -1934,6 +2050,21 @@ nsEventStateManager::DoScrollTextsize(nsIFrame *aTargetFrame, } } +void +nsEventStateManager::DoScrollFullZoom(nsIFrame *aTargetFrame, + PRInt32 adjustment) +{ + // Exclude form controls and XUL content. + nsIContent *content = aTargetFrame->GetContent(); + if (content && + !content->IsNodeOfType(nsINode::eHTML_FORM_CONTROL) && + !content->IsNodeOfType(nsINode::eXUL)) + { + // negative adjustment to increase zoom, positive to decrease + ChangeFullZoom((adjustment > 0) ? -1 : 1); + } +} + static nsIFrame* GetParentFrameToScroll(nsPresContext* aPresContext, nsIFrame* aFrame) { @@ -2317,6 +2448,12 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext, } break; + case MOUSE_SCROLL_FULLZOOM: + { + DoScrollFullZoom(aTargetFrame, msEvent->delta); + } + break; + default: // Including -1 (do nothing) break; } diff --git a/content/events/src/nsEventStateManager.h b/content/events/src/nsEventStateManager.h index 2d4e8043be24..2478a5bead28 100644 --- a/content/events/src/nsEventStateManager.h +++ b/content/events/src/nsEventStateManager.h @@ -51,6 +51,7 @@ #include "nsCOMArray.h" #include "nsIFrame.h" #include "nsCycleCollectionParticipant.h" +#include "nsIMarkupDocumentViewer.h" class nsIScrollableView; class nsIPresShell; @@ -304,7 +305,10 @@ protected: void ForceViewUpdate(nsIView* aView); void DoScrollHistory(PRInt32 direction); void DoScrollTextsize(nsIFrame *aTargetFrame, PRInt32 adjustment); + void DoScrollFullZoom(nsIFrame *aTargetFrame, PRInt32 adjustment); + nsresult GetMarkupDocumentViewer(nsIMarkupDocumentViewer** aMv); nsresult ChangeTextSize(PRInt32 change); + nsresult ChangeFullZoom(PRInt32 change); // end mousewheel functions // routines for the d&d gesture tracking state machine diff --git a/content/html/content/src/nsFormSubmission.cpp b/content/html/content/src/nsFormSubmission.cpp index 6992401abfcb..86db9da4c612 100644 --- a/content/html/content/src/nsFormSubmission.cpp +++ b/content/html/content/src/nsFormSubmission.cpp @@ -764,16 +764,10 @@ nsFSMultipartFormData::AddNameValuePair(nsIDOMHTMLElement* aSource, // XXX: name parameter should be encoded per RFC 2231 // RFC 2388 specifies that RFC 2047 be used, but I think it's not // consistent with MIME standard. - // NOTE: The ordering of these headers, and in particular which comes first - // and which comes last, is important. See comments in - // nsFSMultipartFormData::AddNameFilePair mPostDataChunk += NS_LITERAL_CSTRING("--") + mBoundary + NS_LITERAL_CSTRING(CRLF) + NS_LITERAL_CSTRING("Content-Disposition: form-data; name=\"") - + nameStr + NS_LITERAL_CSTRING("\"" CRLF) - + NS_LITERAL_CSTRING("Content-Type: text/plain; charset=") - + mCharset - + NS_LITERAL_CSTRING(CRLF CRLF) + + nameStr + NS_LITERAL_CSTRING("\"" CRLF CRLF) + valueStr + NS_LITERAL_CSTRING(CRLF); return NS_OK; @@ -800,23 +794,12 @@ nsFSMultipartFormData::AddNameFilePair(nsIDOMHTMLElement* aSource, + NS_LITERAL_CSTRING(CRLF); if (!mBackwardsCompatibleSubmit) { // XXX Is there any way to tell when "8bit" or "7bit" etc may be - // XXXbz See bug 58189 for why we try to send it and bug 83065 for why we - // don't just always do it. It seems like a better solution would be to - // just make sure we send this header before the Content-Type header (to - // deal with the PHP brain-deadness described in bug 83065), but to send it - // anyway. However, we need to make sure it comes after the - // Content-Disposition header, because other server-side packages make the - // equally brain-dead assumption that Content-Disposition is the first - // header in every part. See bug 116346 for that fun. mPostDataChunk += NS_LITERAL_CSTRING("Content-Transfer-Encoding: binary" CRLF); } // XXX: name/filename parameter should be encoded per RFC 2231 // RFC 2388 specifies that RFC 2047 be used, but I think it's not // consistent with the MIME standard. - // NOTE: The Content-Disposition MUST come first and the Content-Type last to - // satisfy non-MIME-compliant server-side parsers. See comment above on - // Content-Transfer-Encoding. mPostDataChunk += NS_LITERAL_CSTRING("Content-Disposition: form-data; name=\"") + nameStr + NS_LITERAL_CSTRING("\"; filename=\"") @@ -1160,9 +1143,6 @@ GetSubmissionFromForm(nsGenericHTMLElement* aForm, nsCOMPtr encoder; nsFormSubmission::GetEncoder(aForm, charset, getter_AddRefs(encoder)); - if (!encoder) - charset.AssignLiteral("UTF-8"); - // Get form processor nsCOMPtr formProcessor = do_GetService(kFormProcessorCID, &rv); diff --git a/content/html/document/src/nsHTMLDocument.cpp b/content/html/document/src/nsHTMLDocument.cpp index 27ae5325d2d4..6b0ac09ce181 100644 --- a/content/html/document/src/nsHTMLDocument.cpp +++ b/content/html/document/src/nsHTMLDocument.cpp @@ -1703,30 +1703,21 @@ nsHTMLDocument::SetDomain(const nsAString& aDomain) nsAutoString current; if (NS_FAILED(GetDomain(current))) return NS_ERROR_FAILURE; - PRBool ok = PR_FALSE; - if (current.Equals(aDomain)) { - ok = PR_TRUE; - } else if (aDomain.Length() < current.Length()) { - nsAutoString suffix; - current.Right(suffix, aDomain.Length()); - PRUnichar c = current.CharAt(current.Length() - aDomain.Length() - 1); - if (suffix.Equals(aDomain, nsCaseInsensitiveStringComparator()) && - (c == '.')) { - // Using only a TLD is forbidden (bug 368700) - nsCOMPtr tldService = - do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID); - if (!tldService) - return NS_ERROR_NOT_AVAILABLE; + PRBool ok = current.Equals(aDomain); + if (current.Length() > aDomain.Length() && + StringEndsWith(current, aDomain, nsCaseInsensitiveStringComparator()) && + current.CharAt(current.Length() - aDomain.Length() - 1) == '.') { + // Using only a TLD is forbidden (bug 368700) + nsCOMPtr tldService = + do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID); + if (!tldService) + return NS_ERROR_NOT_AVAILABLE; - NS_ConvertUTF16toUTF8 str(aDomain); - PRUint32 tldLength; - nsresult rv = tldService->GetEffectiveTLDLength(str, &tldLength); - if (NS_FAILED(rv)) - return rv; - - if (tldLength < str.Length()) - ok = PR_TRUE; - } + // try to get the base domain; if this works, we're ok + NS_ConvertUTF16toUTF8 str(aDomain); + nsCAutoString etld; + nsresult rv = tldService->GetBaseDomainFromHost(str, 0, etld); + ok = NS_SUCCEEDED(rv); } if (!ok) { // Error: illegal domain @@ -2219,6 +2210,7 @@ nsHTMLDocument::OpenCommon(const nsACString& aContentType, PRBool aReplace) if (root) { // Tear down the frames for the root element. + MOZ_AUTO_DOC_UPDATE(this, UPDATE_CONTENT_MODEL, PR_TRUE); nsNodeUtils::ContentRemoved(this, root, 0); // Put the root element back into the document, we don't notify @@ -3740,6 +3732,16 @@ nsHTMLDocument::GetDesignMode(nsAString & aDesignMode) return NS_OK; } +void +nsHTMLDocument::EndUpdate(nsUpdateType aUpdateType) +{ + nsDocument::EndUpdate(aUpdateType); + + if (mUpdateNestLevel == 0 && mContentEditableCount > 0 != IsEditingOn()) { + EditingStateChanged(); + } +} + nsresult nsHTMLDocument::ChangeContentEditableCount(nsIContent *aElement, PRInt32 aChange) @@ -3749,7 +3751,8 @@ nsHTMLDocument::ChangeContentEditableCount(nsIContent *aElement, mContentEditableCount += aChange; - if (mParser) { + if (mParser || + (mUpdateNestLevel > 0 && mContentEditableCount > 0 != IsEditingOn())) { return NS_OK; } diff --git a/content/html/document/src/nsHTMLDocument.h b/content/html/document/src/nsHTMLDocument.h index 0b895a8ef57e..ff80c06fa3f3 100644 --- a/content/html/document/src/nsHTMLDocument.h +++ b/content/html/document/src/nsHTMLDocument.h @@ -212,6 +212,8 @@ public: mDisableCookieAccess = PR_TRUE; } + void EndUpdate(nsUpdateType aUpdateType); + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsHTMLDocument, nsDocument) protected: diff --git a/content/svg/content/src/nsSVGAngle.cpp b/content/svg/content/src/nsSVGAngle.cpp index ab870597169b..63f2116f95da 100644 --- a/content/svg/content/src/nsSVGAngle.cpp +++ b/content/svg/content/src/nsSVGAngle.cpp @@ -184,28 +184,22 @@ GetValueFromString(const nsAString &aValueAsString, float *aValue, PRUint16 *aUnitType) { - char *str = ToNewCString(aValueAsString); - if (!str) - return NS_ERROR_OUT_OF_MEMORY; + NS_ConvertUTF16toUTF8 value(aValueAsString); + const char *str = value.get(); - nsresult rv = NS_ERROR_FAILURE; + if (NS_IsAsciiWhitespace(*str)) + return NS_ERROR_FAILURE; - if (*str) { - char *rest; - *aValue = static_cast(PR_strtod(str, &rest)); - if (rest != str) { - *aUnitType = GetUnitTypeForString(nsCRT::strtok(rest, - "\x20\x9\xD\xA", - &rest)); - if (IsValidUnitType(*aUnitType)) { - rv = NS_OK; - } + char *rest; + *aValue = float(PR_strtod(str, &rest)); + if (rest != str) { + *aUnitType = GetUnitTypeForString(rest); + if (IsValidUnitType(*aUnitType)) { + return NS_OK; } } - nsMemory::Free(str); - - return rv; + return NS_ERROR_FAILURE; } float diff --git a/content/svg/content/src/nsSVGInteger.cpp b/content/svg/content/src/nsSVGInteger.cpp index 1ace1d3edab8..0fc88f2fba58 100755 --- a/content/svg/content/src/nsSVGInteger.cpp +++ b/content/svg/content/src/nsSVGInteger.cpp @@ -52,12 +52,18 @@ nsSVGInteger::SetBaseValueString(const nsAString &aValueAsString, nsSVGElement *aSVGElement, PRBool aDoSetAttr) { - nsAutoString s; - s.Assign(aValueAsString); - PRInt32 err; - PRInt32 val = s.ToInteger(&err); - nsresult rv = static_cast(err); - NS_ENSURE_SUCCESS(rv, rv); + NS_ConvertUTF16toUTF8 value(aValueAsString); + const char *str = value.get(); + + if (NS_IsAsciiWhitespace(*str)) + return NS_ERROR_FAILURE; + + char *rest; + PRInt32 val = strtol(str, &rest, 10); + if (rest == str || *rest != '\0') { + return NS_ERROR_FAILURE; + } + mBaseVal = mAnimVal = val; return NS_OK; } diff --git a/content/svg/content/src/nsSVGLength2.cpp b/content/svg/content/src/nsSVGLength2.cpp index e25a497e87e2..7c2d75f8265f 100644 --- a/content/svg/content/src/nsSVGLength2.cpp +++ b/content/svg/content/src/nsSVGLength2.cpp @@ -145,28 +145,22 @@ GetValueFromString(const nsAString &aValueAsString, float *aValue, PRUint16 *aUnitType) { - char *str = ToNewCString(aValueAsString); - if (!str) - return NS_ERROR_OUT_OF_MEMORY; + NS_ConvertUTF16toUTF8 value(aValueAsString); + const char *str = value.get(); - nsresult rv = NS_ERROR_FAILURE; + if (NS_IsAsciiWhitespace(*str)) + return NS_ERROR_FAILURE; - if (*str) { - char *rest; - *aValue = static_cast(PR_strtod(str, &rest)); - if (rest != str) { - *aUnitType = GetUnitTypeForString(nsCRT::strtok(rest, - "\x20\x9\xD\xA", - &rest)); - if (IsValidUnitType(*aUnitType)) { - rv = NS_OK; - } + char *rest; + *aValue = float(PR_strtod(str, &rest)); + if (rest != str) { + *aUnitType = GetUnitTypeForString(rest); + if (IsValidUnitType(*aUnitType)) { + return NS_OK; } } - nsMemory::Free(str); - - return rv; + return NS_ERROR_FAILURE; } float diff --git a/content/svg/content/src/nsSVGNumber2.cpp b/content/svg/content/src/nsSVGNumber2.cpp index d7f0ff810d97..56461ee93851 100644 --- a/content/svg/content/src/nsSVGNumber2.cpp +++ b/content/svg/content/src/nsSVGNumber2.cpp @@ -54,12 +54,18 @@ nsSVGNumber2::SetBaseValueString(const nsAString &aValueAsString, nsSVGElement *aSVGElement, PRBool aDoSetAttr) { - nsAutoString s; - s.Assign(aValueAsString); - PRInt32 err; - float val = s.ToFloat(&err); - nsresult rv = static_cast(err); - NS_ENSURE_SUCCESS(rv, rv); + NS_ConvertUTF16toUTF8 value(aValueAsString); + const char *str = value.get(); + + if (NS_IsAsciiWhitespace(*str)) + return NS_ERROR_FAILURE; + + char *rest; + float val = float(PR_strtod(str, &rest)); + if (rest == str || *rest != '\0') { + return NS_ERROR_FAILURE; + } + mBaseVal = mAnimVal = val; return NS_OK; } diff --git a/content/xbl/src/nsBindingManager.cpp b/content/xbl/src/nsBindingManager.cpp index 9a5153879ad9..ed4896ab0fa8 100644 --- a/content/xbl/src/nsBindingManager.cpp +++ b/content/xbl/src/nsBindingManager.cpp @@ -915,7 +915,10 @@ nsBindingManager::DoProcessAttachedQueue() mProcessAttachedQueueEvent = nsnull; if (mDocument) { - mDocument->UnblockOnload(PR_TRUE); + // Hold a strong reference while calling UnblockOnload since that might + // run script. + nsCOMPtr doc = mDocument; + doc->UnblockOnload(PR_TRUE); } } @@ -933,6 +936,11 @@ nsBindingManager::ProcessAttachedQueue() mAttachedStack.RemoveElementAt(lastItem); NS_ASSERTION(binding, "null item in attached stack?"); + nsresult rv = binding->EnsureScriptAPI(); + if (NS_FAILED(rv)) { + return; + } + binding->ExecuteAttachedHandler(); } diff --git a/content/xbl/src/nsXBLBinding.cpp b/content/xbl/src/nsXBLBinding.cpp index 656bd975183d..611519fccf62 100644 --- a/content/xbl/src/nsXBLBinding.cpp +++ b/content/xbl/src/nsXBLBinding.cpp @@ -186,6 +186,11 @@ XBLResolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, return JS_FALSE; } + if (content->HasFlag(NODE_IS_IN_BINDING_TEARDOWN)) { + // Don't evaluate fields now! + return JS_TRUE; + } + // This mirrors code in nsXBLProtoImpl::InstallImplementation nsIDocument* doc = content->GetOwnerDoc(); if (!doc) { @@ -272,7 +277,8 @@ nsXBLBinding::nsXBLBinding(nsXBLPrototypeBinding* aBinding) : mPrototypeBinding(aBinding), mInsertionPointTable(nsnull), mIsStyleBinding(PR_TRUE), - mMarkedForDeath(PR_FALSE) + mMarkedForDeath(PR_FALSE), + mInstalledAPI(PR_FALSE) { NS_ASSERTION(mPrototypeBinding, "Must have a prototype binding!"); // Grab a ref to the document info so the prototype binding won't die @@ -300,7 +306,7 @@ TraverseKey(nsISupports* aKey, nsInsertionPointList* aData, void* aClosure) return PL_DHASH_NEXT; } -NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(nsXBLBinding) +NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLBinding) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXBLBinding) // XXX Probably can't unlink mPrototypeBinding->XBLDocumentInfo(), because // mPrototypeBinding is weak. @@ -375,18 +381,6 @@ nsXBLBinding::SetBoundElement(nsIContent* aElement) mNextBinding->SetBoundElement(aElement); } -nsXBLBinding* -nsXBLBinding::GetFirstBindingWithConstructor() -{ - if (mPrototypeBinding->GetConstructor()) - return this; - - if (mNextBinding) - return mNextBinding->GetFirstBindingWithConstructor(); - - return nsnull; -} - PRBool nsXBLBinding::HasStyleSheets() const { @@ -800,6 +794,22 @@ nsXBLBinding::GenerateAnonymousContent() } } +nsresult +nsXBLBinding::EnsureScriptAPI() +{ + if (mInstalledAPI) { + return NS_OK; + } + + // Set mInstalledAPI right away since we'll recurse into here from + // nsElementSH::PostCreate when InstallImplementation is called. + mInstalledAPI = PR_TRUE; + + InstallEventHandlers(); + + return InstallImplementation(); +} + void nsXBLBinding::InstallEventHandlers() { @@ -1039,25 +1049,19 @@ void nsXBLBinding::ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocument) { if (aOldDocument != aNewDocument) { - if (mNextBinding) - mNextBinding->ChangeDocument(aOldDocument, aNewDocument); - - // Only style bindings get their prototypes unhooked. + // Only style bindings get their prototypes unhooked. First do ourselves. if (mIsStyleBinding) { // Now the binding dies. Unhook our prototypes. - nsIContent* interfaceElement = - mPrototypeBinding->GetImmediateChild(nsGkAtoms::implementation); - - if (interfaceElement) { - nsIScriptGlobalObject *global = aOldDocument->GetScriptGlobalObject(); + if (mPrototypeBinding->HasImplementation()) { + nsIScriptGlobalObject *global = aOldDocument->GetScopeObject(); if (global) { - nsIScriptContext *context = global->GetContext(); + nsCOMPtr context = global->GetContext(); if (context) { - JSContext *jscontext = (JSContext *)context->GetNativeContext(); + JSContext *cx = (JSContext *)context->GetNativeContext(); nsCOMPtr wrapper; nsresult rv = nsContentUtils::XPConnect()-> - WrapNative(jscontext, global->GetGlobalJSObject(), + WrapNative(cx, global->GetGlobalJSObject(), mBoundElement, NS_GET_IID(nsISupports), getter_AddRefs(wrapper)); if (NS_FAILED(rv)) @@ -1070,16 +1074,62 @@ nsXBLBinding::ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocumen // XXX Stay in sync! What if a layered binding has an // ?! + // XXXbz what does that comment mean, really? It seems to date + // back to when there was such a thing as an , whever + // that was... - // XXX Sanity check to make sure our class name matches - // Pull ourselves out of the proto chain. - JSObject* ourProto = ::JS_GetPrototype(jscontext, scriptObject); - if (ourProto) - { - JSObject* grandProto = ::JS_GetPrototype(jscontext, ourProto); - ::JS_SetPrototype(jscontext, scriptObject, grandProto); + // Find the right prototype. + JSObject* base = scriptObject; + JSObject* proto; + JSAutoRequest ar(cx); + for ( ; true; base = proto) { // Will break out on null proto + proto = ::JS_GetPrototype(cx, base); + if (!proto) { + break; + } + + JSClass* clazz = ::JS_GetClass(cx, proto); + if (!clazz || + (~clazz->flags & + (JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS)) || + JSCLASS_RESERVED_SLOTS(clazz) != 1) { + // Clearly not the right class + continue; + } + + nsCOMPtr docInfo = + do_QueryInterface(static_cast + (::JS_GetPrivate(cx, proto))); + if (!docInfo) { + // Not the proto we seek + continue; + } + + jsval protoBinding; + if (!::JS_GetReservedSlot(cx, proto, 0, &protoBinding)) { + NS_ERROR("Really shouldn't happen"); + continue; + } + + if (JSVAL_TO_PRIVATE(protoBinding) != mPrototypeBinding) { + // Not the right binding + continue; + } + + // Alright! This is the right prototype. Pull it out of the + // proto chain. + JSObject* grandProto = ::JS_GetPrototype(cx, proto); + ::JS_SetPrototype(cx, base, grandProto); + break; } + // Do this after unhooking the proto to avoid extra walking along + // the proto chain as the JS engine tries to resolve the properties + // we're removing. + mBoundElement->SetFlags(NODE_IS_IN_BINDING_TEARDOWN); + mPrototypeBinding->UndefineFields(cx, scriptObject); + mBoundElement->UnsetFlags(NODE_IS_IN_BINDING_TEARDOWN); + // Don't remove the reference from the document to the // wrapper here since it'll be removed by the element // itself when that's taken out of the document. @@ -1088,7 +1138,14 @@ nsXBLBinding::ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocumen } } + // Then do our ancestors. This reverses the construction order, so that at + // all times things are consistent as far as everyone is concerned. + if (mNextBinding) { + mNextBinding->ChangeDocument(aOldDocument, aNewDocument); + } + // Update the anonymous content. + // XXXbz why not only for style bindings? nsIContent *anonymous = mContent; if (anonymous) { // Also kill the default content within all our insertion points. diff --git a/content/xbl/src/nsXBLBinding.h b/content/xbl/src/nsXBLBinding.h index 59d1471d77ad..77658efdd4bb 100644 --- a/content/xbl/src/nsXBLBinding.h +++ b/content/xbl/src/nsXBLBinding.h @@ -120,15 +120,13 @@ public: void GenerateAnonymousContent(); void InstallAnonymousContent(nsIContent* aAnonParent, nsIContent* aElement); - void InstallEventHandlers(); - nsresult InstallImplementation(); + nsresult EnsureScriptAPI(); void ExecuteAttachedHandler(); void ExecuteDetachedHandler(); void UnhookEventHandlers(); nsIAtom* GetBaseTag(PRInt32* aNameSpaceID); - nsXBLBinding* GetFirstBindingWithConstructor(); nsXBLBinding* RootBinding(); nsXBLBinding* GetFirstStyleBinding(); @@ -169,6 +167,12 @@ public: // MEMBER VARIABLES protected: + // These two functions recursively install the event handlers + // and implementation on this binding and its base class bindings. + // External callers should call EnsureScriptAPI instead. + void InstallEventHandlers(); + nsresult InstallImplementation(); + nsAutoRefCnt mRefCnt; nsXBLPrototypeBinding* mPrototypeBinding; // Weak, but we're holding a ref to the docinfo nsCOMPtr mContent; // Strong. Our anonymous content stays around with us. @@ -181,6 +185,7 @@ protected: PRPackedBool mIsStyleBinding; PRPackedBool mMarkedForDeath; + PRPackedBool mInstalledAPI; }; #endif // nsXBLBinding_h_ diff --git a/content/xbl/src/nsXBLDocumentInfo.cpp b/content/xbl/src/nsXBLDocumentInfo.cpp index 4da0e377fb1c..5b4007f0deba 100644 --- a/content/xbl/src/nsXBLDocumentInfo.cpp +++ b/content/xbl/src/nsXBLDocumentInfo.cpp @@ -452,6 +452,21 @@ UnlinkProtos(nsHashKey *aKey, void *aData, void* aClosure) return kHashEnumerateNext; } +struct ProtoTracer +{ + TraceCallback mCallback; + void *mClosure; +}; + +static PRIntn PR_CALLBACK +TraceProtos(nsHashKey *aKey, void *aData, void* aClosure) +{ + ProtoTracer* closure = static_cast(aClosure); + nsXBLPrototypeBinding *proto = static_cast(aData); + proto->Trace(closure->mCallback, closure->mClosure); + return kHashEnumerateNext; +} + NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLDocumentInfo) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXBLDocumentInfo) if (tmp->mBindingTable) { @@ -466,7 +481,14 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXBLDocumentInfo) tmp->mBindingTable->Enumerate(TraverseProtos, &cb); } cb.NoteXPCOMChild(static_cast(tmp->mGlobalObject)); + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END +NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsXBLDocumentInfo) + if (tmp->mBindingTable) { + ProtoTracer closure = { aCallback, aClosure }; + tmp->mBindingTable->Enumerate(TraceProtos, &closure); + } +NS_IMPL_CYCLE_COLLECTION_TRACE_END NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXBLDocumentInfo) NS_INTERFACE_MAP_ENTRY(nsIXBLDocumentInfo) @@ -507,7 +529,10 @@ nsXBLDocumentInfo::~nsXBLDocumentInfo() mGlobalObject->SetScriptContext(nsIProgrammingLanguage::JAVASCRIPT, nsnull); mGlobalObject->ClearGlobalObjectOwner(); // just in case } - delete mBindingTable; + if (mBindingTable) { + NS_DROP_JS_OBJECTS(this, nsXBLDocumentInfo); + delete mBindingTable; + } } NS_IMETHODIMP @@ -541,8 +566,13 @@ DeletePrototypeBinding(nsHashKey* aKey, void* aData, void* aClosure) NS_IMETHODIMP nsXBLDocumentInfo::SetPrototypeBinding(const nsACString& aRef, nsXBLPrototypeBinding* aBinding) { - if (!mBindingTable) + if (!mBindingTable) { mBindingTable = new nsObjectHashtable(nsnull, nsnull, DeletePrototypeBinding, nsnull); + if (!mBindingTable) + return NS_ERROR_OUT_OF_MEMORY; + + NS_HOLD_JS_OBJECTS(this, nsXBLDocumentInfo); + } const nsPromiseFlatCString& flat = PromiseFlatCString(aRef); nsCStringKey key(flat.get()); diff --git a/content/xbl/src/nsXBLDocumentInfo.h b/content/xbl/src/nsXBLDocumentInfo.h index 1f65e7168d6b..29054dd1e2bd 100644 --- a/content/xbl/src/nsXBLDocumentInfo.h +++ b/content/xbl/src/nsXBLDocumentInfo.h @@ -72,8 +72,8 @@ public: // nsIScriptGlobalObjectOwner methods virtual nsIScriptGlobalObject* GetScriptGlobalObject(); - NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXBLDocumentInfo, - nsIXBLDocumentInfo) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsXBLDocumentInfo, + nsIXBLDocumentInfo) private: nsCOMPtr mDocument; diff --git a/content/xbl/src/nsXBLInsertionPoint.cpp b/content/xbl/src/nsXBLInsertionPoint.cpp index c3c6dd6b500e..56d86fccabaf 100644 --- a/content/xbl/src/nsXBLInsertionPoint.cpp +++ b/content/xbl/src/nsXBLInsertionPoint.cpp @@ -64,7 +64,7 @@ nsXBLInsertionPoint::Release() return mRefCnt; } -NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(nsXBLInsertionPoint) +NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLInsertionPoint) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXBLInsertionPoint) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mElements) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDefaultContentTemplate) diff --git a/content/xbl/src/nsXBLProtoImpl.cpp b/content/xbl/src/nsXBLProtoImpl.cpp index efe7bd20361d..a1860f98ded1 100644 --- a/content/xbl/src/nsXBLProtoImpl.cpp +++ b/content/xbl/src/nsXBLProtoImpl.cpp @@ -200,7 +200,7 @@ nsXBLProtoImpl::CompilePrototypeMembers(nsXBLPrototypeBinding* aBinding) } void -nsXBLProtoImpl::Traverse(nsCycleCollectionTraversalCallback &cb) const +nsXBLProtoImpl::Trace(TraceCallback aCallback, void *aClosure) const { // If we don't have a class object then we either didn't compile members // or we only have fields, in both cases there are no cycles through our @@ -211,7 +211,7 @@ nsXBLProtoImpl::Traverse(nsCycleCollectionTraversalCallback &cb) const nsXBLProtoImplMember *member; for (member = mMembers; member; member = member->GetNext()) { - member->Traverse(cb); + member->Trace(aCallback, aClosure); } } @@ -254,6 +254,19 @@ nsXBLProtoImpl::ResolveAllFields(JSContext *cx, JSObject *obj) const return PR_TRUE; } +void +nsXBLProtoImpl::UndefineFields(JSContext *cx, JSObject *obj) const +{ + JSAutoRequest ar(cx); + for (nsXBLProtoImplField* f = mFields; f; f = f->GetNext()) { + nsDependentString name(f->GetName()); + jsval dummy; + ::JS_DeleteUCProperty2(cx, obj, + reinterpret_cast(name.get()), + name.Length(), &dummy); + } +} + void nsXBLProtoImpl::DestroyMembers(nsXBLProtoImplMember* aBrokenMember) { diff --git a/content/xbl/src/nsXBLProtoImpl.h b/content/xbl/src/nsXBLProtoImpl.h index e39f921b993c..caa264360447 100644 --- a/content/xbl/src/nsXBLProtoImpl.h +++ b/content/xbl/src/nsXBLProtoImpl.h @@ -90,7 +90,7 @@ public: mFields = aFieldList; } - void Traverse(nsCycleCollectionTraversalCallback &cb) const; + void Trace(TraceCallback aCallback, void *aClosure) const; void Unlink(); nsXBLProtoImplField* FindField(const nsString& aFieldName) const; @@ -99,6 +99,10 @@ public: // return means a JS exception was set. PRBool ResolveAllFields(JSContext *cx, JSObject *obj) const; + // Undefine all our fields from object |obj| (which should be a + // JSObject for a bound element). + void UndefineFields(JSContext* cx, JSObject* obj) const; + PRBool CompiledMembers() const { return mClassObject != nsnull; } diff --git a/content/xbl/src/nsXBLProtoImplMember.h b/content/xbl/src/nsXBLProtoImplMember.h index 0ca62573a13e..d8e12cd3181f 100644 --- a/content/xbl/src/nsXBLProtoImplMember.h +++ b/content/xbl/src/nsXBLProtoImplMember.h @@ -47,11 +47,11 @@ #include "nsIJSRuntimeService.h" #include "nsIServiceManager.h" #include "nsReadableUtils.h" +#include "nsCycleCollectionParticipant.h" class nsIScriptContext; struct JSRuntime; class nsIJSRuntimeService; -class nsCycleCollectionTraversalCallback; struct nsXBLTextWithLineNumber { @@ -114,7 +114,7 @@ public: const nsCString& aClassStr, void* aClassObject)=0; - virtual void Traverse(nsCycleCollectionTraversalCallback &cb) const = 0; + virtual void Trace(TraceCallback aCallback, void *aClosure) const = 0; protected: friend class nsAutoGCRoot; diff --git a/content/xbl/src/nsXBLProtoImplMethod.cpp b/content/xbl/src/nsXBLProtoImplMethod.cpp index d18768118319..3da1692c64ce 100644 --- a/content/xbl/src/nsXBLProtoImplMethod.cpp +++ b/content/xbl/src/nsXBLProtoImplMethod.cpp @@ -72,8 +72,6 @@ nsXBLProtoImplMethod::Destroy(PRBool aIsCompiled) NS_PRECONDITION(aIsCompiled == mIsCompiled, "Incorrect aIsCompiled in nsXBLProtoImplMethod::Destroy"); if (aIsCompiled) { - if (mJSMethodObject) - nsContentUtils::RemoveJSGCRoot(&mJSMethodObject); mJSMethodObject = nsnull; } else { @@ -263,8 +261,6 @@ nsXBLProtoImplMethod::CompileMember(nsIScriptContext* aContext, const nsCString& if (methodObject) { // Root the compiled prototype script object. - rv = nsContentUtils::AddJSGCRoot(&mJSMethodObject, - "nsXBLProtoImplMethod::mJSMethodObject"); if (NS_FAILED(rv)) { mJSMethodObject = nsnull; } @@ -277,11 +273,13 @@ nsXBLProtoImplMethod::CompileMember(nsIScriptContext* aContext, const nsCString& } void -nsXBLProtoImplMethod::Traverse(nsCycleCollectionTraversalCallback &cb) const +nsXBLProtoImplMethod::Trace(TraceCallback aCallback, void *aClosure) const { NS_ASSERTION(mIsCompiled, "Shouldn't traverse uncompiled method"); - cb.NoteScriptChild(nsIProgrammingLanguage::JAVASCRIPT, mJSMethodObject); + if (mJSMethodObject) { + aCallback(nsIProgrammingLanguage::JAVASCRIPT, mJSMethodObject, aClosure); + } } nsresult diff --git a/content/xbl/src/nsXBLProtoImplMethod.h b/content/xbl/src/nsXBLProtoImplMethod.h index a1e665836397..bac2927b56f2 100644 --- a/content/xbl/src/nsXBLProtoImplMethod.h +++ b/content/xbl/src/nsXBLProtoImplMethod.h @@ -129,7 +129,7 @@ public: const nsCString& aClassStr, void* aClassObject); - virtual void Traverse(nsCycleCollectionTraversalCallback &cb) const; + virtual void Trace(TraceCallback aCallback, void *aClosure) const; protected: union { diff --git a/content/xbl/src/nsXBLProtoImplProperty.cpp b/content/xbl/src/nsXBLProtoImplProperty.cpp index 76a5b44bec06..407265f8acf7 100644 --- a/content/xbl/src/nsXBLProtoImplProperty.cpp +++ b/content/xbl/src/nsXBLProtoImplProperty.cpp @@ -87,14 +87,14 @@ nsXBLProtoImplProperty::Destroy(PRBool aIsCompiled) "Incorrect aIsCompiled in nsXBLProtoImplProperty::Destroy"); if ((mJSAttributes & JSPROP_GETTER) && mJSGetterObject) { - nsContentUtils::RemoveJSGCRoot(&mJSGetterObject); + mJSGetterObject = nsnull; } else { delete mGetterText; } if ((mJSAttributes & JSPROP_SETTER) && mJSSetterObject) { - nsContentUtils::RemoveJSGCRoot(&mJSSetterObject); + mJSSetterObject = nsnull; } else { delete mSetterText; @@ -268,9 +268,6 @@ nsXBLProtoImplProperty::CompileMember(nsIScriptContext* aContext, const nsCStrin if (mJSGetterObject && NS_SUCCEEDED(rv)) { mJSAttributes |= JSPROP_GETTER | JSPROP_SHARED; - // Root the compiled prototype script object. - rv = nsContentUtils::AddJSGCRoot(&mJSGetterObject, - "nsXBLProtoImplProperty::mJSGetterObject"); } if (NS_FAILED(rv)) { mJSGetterObject = nsnull; @@ -320,9 +317,6 @@ nsXBLProtoImplProperty::CompileMember(nsIScriptContext* aContext, const nsCStrin if (mJSSetterObject && NS_SUCCEEDED(rv)) { mJSAttributes |= JSPROP_SETTER | JSPROP_SHARED; - // Root the compiled prototype script object. - rv = nsContentUtils::AddJSGCRoot(&mJSSetterObject, - "nsXBLProtoImplProperty::mJSSetterObject"); } if (NS_FAILED(rv)) { mJSSetterObject = nsnull; @@ -345,15 +339,15 @@ nsXBLProtoImplProperty::CompileMember(nsIScriptContext* aContext, const nsCStrin } void -nsXBLProtoImplProperty::Traverse(nsCycleCollectionTraversalCallback &cb) const +nsXBLProtoImplProperty::Trace(TraceCallback aCallback, void *aClosure) const { NS_ASSERTION(mIsCompiled, "Shouldn't traverse uncompiled method"); - if (mJSAttributes & JSPROP_GETTER) { - cb.NoteScriptChild(nsIProgrammingLanguage::JAVASCRIPT, mJSGetterObject); + if ((mJSAttributes & JSPROP_GETTER) && mJSGetterObject) { + aCallback(nsIProgrammingLanguage::JAVASCRIPT, mJSGetterObject, aClosure); } - if (mJSAttributes & JSPROP_SETTER) { - cb.NoteScriptChild(nsIProgrammingLanguage::JAVASCRIPT, mJSSetterObject); + if ((mJSAttributes & JSPROP_SETTER) && mJSSetterObject) { + aCallback(nsIProgrammingLanguage::JAVASCRIPT, mJSSetterObject, aClosure); } } diff --git a/content/xbl/src/nsXBLProtoImplProperty.h b/content/xbl/src/nsXBLProtoImplProperty.h index f5ab70c79ace..9c10326c43de 100644 --- a/content/xbl/src/nsXBLProtoImplProperty.h +++ b/content/xbl/src/nsXBLProtoImplProperty.h @@ -72,7 +72,7 @@ public: const nsCString& aClassStr, void* aClassObject); - virtual void Traverse(nsCycleCollectionTraversalCallback &cb) const; + virtual void Trace(TraceCallback aCallback, void *aClosure) const; protected: union { diff --git a/content/xbl/src/nsXBLPrototypeBinding.cpp b/content/xbl/src/nsXBLPrototypeBinding.cpp index 568945789b41..725ec9a755f6 100644 --- a/content/xbl/src/nsXBLPrototypeBinding.cpp +++ b/content/xbl/src/nsXBLPrototypeBinding.cpp @@ -244,7 +244,7 @@ private: PRUint32 nsXBLInsertionPointEntry::gRefCnt = 0; nsFixedSizeAllocator* nsXBLInsertionPointEntry::kPool; -NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(nsXBLInsertionPointEntry) +NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLInsertionPointEntry) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXBLInsertionPointEntry) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mInsertionParent) if (tmp->mDefaultContent) { @@ -355,8 +355,6 @@ void nsXBLPrototypeBinding::Traverse(nsCycleCollectionTraversalCallback &cb) const { cb.NoteXPCOMChild(mBinding); - if (mImplementation) - mImplementation->Traverse(cb); if (mResources) cb.NoteXPCOMChild(mResources->mLoader); if (mInsertionPointTable) @@ -372,6 +370,13 @@ nsXBLPrototypeBinding::Unlink() mImplementation->Unlink(); } +void +nsXBLPrototypeBinding::Trace(TraceCallback aCallback, void *aClosure) const +{ + if (mImplementation) + mImplementation->Trace(aCallback, aClosure); +} + void nsXBLPrototypeBinding::Initialize() { diff --git a/content/xbl/src/nsXBLPrototypeBinding.h b/content/xbl/src/nsXBLPrototypeBinding.h index 3965a3aa1d72..3243bd254900 100644 --- a/content/xbl/src/nsXBLPrototypeBinding.h +++ b/content/xbl/src/nsXBLPrototypeBinding.h @@ -106,6 +106,14 @@ public: return !mImplementation || mImplementation->ResolveAllFields(cx, obj); } + // Undefine all our fields from object |obj| (which should be a + // JSObject for a bound element). + void UndefineFields(JSContext* cx, JSObject* obj) const { + if (mImplementation) { + mImplementation->UndefineFields(cx, obj); + } + } + const nsCString& ClassName() const { return mImplementation ? mImplementation->mClassName : EmptyCString(); } @@ -118,6 +126,7 @@ public: void SetImplementation(nsXBLProtoImpl* aImpl) { mImplementation = aImpl; } nsresult InstallImplementation(nsIContent* aBoundElement); + PRBool HasImplementation() const { return mImplementation != nsnull; } void AttributeChanged(nsIAtom* aAttribute, PRInt32 aNameSpaceID, PRBool aRemoveFlag, nsIContent* aChangedElement, @@ -189,6 +198,7 @@ public: void Traverse(nsCycleCollectionTraversalCallback &cb) const; void Unlink(); + void Trace(TraceCallback aCallback, void *aClosure) const; // Static members static PRUint32 gRefCnt; diff --git a/content/xbl/src/nsXBLService.cpp b/content/xbl/src/nsXBLService.cpp index cf7515777260..044abc2b72c9 100644 --- a/content/xbl/src/nsXBLService.cpp +++ b/content/xbl/src/nsXBLService.cpp @@ -579,20 +579,11 @@ nsXBLService::LoadBindings(nsIContent* aContent, nsIURI* aURL, // Tell the binding to build the anonymous content. newBinding->GenerateAnonymousContent(); - // Tell the binding to install event handlers - newBinding->InstallEventHandlers(); - - // Set up our properties - rv = newBinding->InstallImplementation(); - NS_ENSURE_SUCCESS(rv, rv); - - // Figure out if we need to execute a constructor. - *aBinding = newBinding->GetFirstBindingWithConstructor(); - NS_IF_ADDREF(*aBinding); - // Figure out if we have any scoped sheets. If so, we do a second resolve. *aResolveStyle = newBinding->HasStyleSheets(); + newBinding.swap(*aBinding); + return NS_OK; } @@ -1120,7 +1111,7 @@ nsSameOriginChecker::OnChannelRedirect(nsIChannel *aOldChannel, NS_ENSURE_SUCCESS(rv, rv); return nsContentUtils::GetSecurityManager()-> - CheckSameOriginURI(oldURI, newURI); + CheckSameOriginURI(oldURI, newURI, PR_TRUE); } NS_IMETHODIMP diff --git a/content/xbl/test/Makefile.in b/content/xbl/test/Makefile.in index 75a866dfad8d..97934fcd2f0b 100644 --- a/content/xbl/test/Makefile.in +++ b/content/xbl/test/Makefile.in @@ -48,11 +48,15 @@ include $(topsrcdir)/config/rules.mk _TEST_FILES = \ test_bug296375.xul \ + test_bug310107.html \ test_bug366770.html \ test_bug371724.xhtml \ test_bug372769.xhtml \ test_bug378866.xhtml \ test_bug397934.xhtml \ + test_bug398135.xhtml \ + test_bug400705.xhtml \ + bug310107-resource.xhtml \ $(NULL) libs:: $(_TEST_FILES) diff --git a/content/xbl/test/bug310107-resource.xhtml b/content/xbl/test/bug310107-resource.xhtml new file mode 100644 index 000000000000..7aa766e76ed0 --- /dev/null +++ b/content/xbl/test/bug310107-resource.xhtml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + +
    + + diff --git a/content/xbl/test/test_bug310107.html b/content/xbl/test/test_bug310107.html new file mode 100644 index 000000000000..be066963ed0e --- /dev/null +++ b/content/xbl/test/test_bug310107.html @@ -0,0 +1,54 @@ + + + + + Test for Bug 310107 + + + + + +Mozilla Bug 310107 +

    + +
    +
    +
    + + + diff --git a/content/xbl/test/test_bug398135.xhtml b/content/xbl/test/test_bug398135.xhtml new file mode 100644 index 000000000000..2fbe774fb936 --- /dev/null +++ b/content/xbl/test/test_bug398135.xhtml @@ -0,0 +1,136 @@ + + + + Test for Bug 398135 + + + + + + + + + window.log += "ancestorConstructor:"; + + + window.log += "ancestorDestructor:"; + + "ancestorField" + + + + return "ancestorMethod"; + + + + + + + + window.log += "descendantConstructor:"; + + + window.log += "descendantDestructor:"; + + "descendantField" + + document.getAnonymousNodes(this)[0]; + + + + + return "descendantMethod"; + + + + + + + + + + + +Mozilla Bug 398135 +

    + +
    +
    +
    + + + diff --git a/content/xbl/test/test_bug400705.xhtml b/content/xbl/test/test_bug400705.xhtml new file mode 100644 index 000000000000..054519537121 --- /dev/null +++ b/content/xbl/test/test_bug400705.xhtml @@ -0,0 +1,49 @@ + + + + Test for Bug 400705 + + + + + + + window.countera++ + window.counterb++ + + + + + +Mozilla Bug 400705 +

    + +
    +
    +
    + + + diff --git a/content/xml/document/src/nsXMLContentSink.cpp b/content/xml/document/src/nsXMLContentSink.cpp index 1d95815a09a1..817a2774895f 100644 --- a/content/xml/document/src/nsXMLContentSink.cpp +++ b/content/xml/document/src/nsXMLContentSink.cpp @@ -756,7 +756,7 @@ nsXMLContentSink::ProcessStyleLink(nsIContent* aElement, nsIScriptSecurityManager::ALLOW_CHROME); NS_ENSURE_SUCCESS(rv, NS_OK); - rv = secMan->CheckSameOriginURI(mDocumentURI, url); + rv = secMan->CheckSameOriginURI(mDocumentURI, url, PR_TRUE); NS_ENSURE_SUCCESS(rv, NS_OK); // Do content policy check diff --git a/content/xml/document/test/Makefile.in b/content/xml/document/test/Makefile.in index 86b26866218c..34e83f20dc22 100644 --- a/content/xml/document/test/Makefile.in +++ b/content/xml/document/test/Makefile.in @@ -47,6 +47,7 @@ include $(topsrcdir)/config/rules.mk _TEST_FILES = test_bug232004.xhtml \ test_bug343870.xhtml \ test_bug355213.xhtml \ + test_bug399502.xhtml \ $(NULL) libs:: $(_TEST_FILES) diff --git a/content/xml/document/test/test_bug399502.xhtml b/content/xml/document/test/test_bug399502.xhtml new file mode 100644 index 000000000000..5b88b76b2224 --- /dev/null +++ b/content/xml/document/test/test_bug399502.xhtml @@ -0,0 +1,42 @@ + + + + + Test for Bug 399502 + + + + + +Mozilla Bug 399502 +

    + +
    +
    +
    + + + diff --git a/content/xslt/src/xslt/txMozillaStylesheetCompiler.cpp b/content/xslt/src/xslt/txMozillaStylesheetCompiler.cpp index cfb71ccb403c..e6b945905b4c 100644 --- a/content/xslt/src/xslt/txMozillaStylesheetCompiler.cpp +++ b/content/xslt/src/xslt/txMozillaStylesheetCompiler.cpp @@ -393,7 +393,7 @@ txStylesheetSink::OnChannelRedirect(nsIChannel *aOldChannel, rv = aNewChannel->GetURI(getter_AddRefs(newURI)); // The new URI NS_ENSURE_SUCCESS(rv, rv); - return secMan->CheckSameOriginURI(oldURI, newURI); + return secMan->CheckSameOriginURI(oldURI, newURI, PR_TRUE); } NS_IMETHODIMP diff --git a/content/xul/content/src/nsXULElement.cpp b/content/xul/content/src/nsXULElement.cpp index cc28aeda5117..93b935a89e43 100644 --- a/content/xul/content/src/nsXULElement.cpp +++ b/content/xul/content/src/nsXULElement.cpp @@ -55,7 +55,6 @@ * use in OS2 */ -#include "jsapi.h" // for JS_AddNamedRoot and JS_RemoveRootRT #include "nsCOMPtr.h" #include "nsDOMCID.h" #include "nsDOMError.h" @@ -64,6 +63,7 @@ #include "nsIPrivateDOMEvent.h" #include "nsHashtable.h" #include "nsIAtom.h" +#include "nsIBaseWindow.h" #include "nsIDOMAttr.h" #include "nsIDOMDocument.h" #include "nsIDOMElement.h" @@ -702,7 +702,8 @@ nsScriptEventHandlerOwnerTearoff::CompileEventHandler( nsCOMPtr xuldoc = do_QueryInterface(mElement->GetOwnerDoc()); nsIScriptContext *context; - if (mElement->mPrototype && xuldoc) { + nsXULPrototypeElement *elem = mElement->mPrototype; + if (elem && xuldoc) { // It'll be shared among the instances of the prototype. // Use the prototype document's special context. Because @@ -755,9 +756,16 @@ nsScriptEventHandlerOwnerTearoff::CompileEventHandler( XUL_PROTOTYPE_ATTRIBUTE_METER(gNumCacheFills); // take a copy of the event handler, and tell the language about it. if (aHandler) { + NS_ASSERTION(!attr->mEventHandler, "Leaking handler."); + rv = nsContentUtils::HoldScriptObject(aContext->GetScriptTypeID(), - aHandler); + elem, + &NS_CYCLE_COLLECTION_NAME(nsXULPrototypeNode), + aHandler, + elem->mHoldsScriptObject); if (NS_FAILED(rv)) return rv; + + elem->mHoldsScriptObject = PR_TRUE; } attr->mEventHandler = (void *)aHandler; } @@ -1048,8 +1056,20 @@ nsXULElement::AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName, HideWindowChrome(aValue && NS_LITERAL_STRING("true").Equals(*aValue)); } - // handle :read-only/:read-write + // titlebarcolor is settable on any root node (windows, dialogs, etc) nsIDocument *document = GetCurrentDoc(); + if (aName == nsGkAtoms::titlebarcolor && + document && document->GetRootContent() == this) { + + nscolor color = NS_RGBA(0, 0, 0, 0); + nsAttrValue attrValue; + attrValue.ParseColor(*aValue, document); + attrValue.GetColorValue(color); + + SetTitlebarColor(color); + } + + // handle :read-only/:read-write if (aName == nsGkAtoms::readonly && document) { mozAutoDocUpdate upd(document, UPDATE_CONTENT_STATE, PR_TRUE); document->ContentStatesChanged(this, nsnull, @@ -1291,6 +1311,12 @@ nsXULElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, PRBool aNotify) HideWindowChrome(PR_FALSE); } + if (aName == nsGkAtoms::titlebarcolor && + doc && doc->GetRootContent() == this) { + // Use 0, 0, 0, 0 as the "none" color. + SetTitlebarColor(NS_RGBA(0, 0, 0, 0)); + } + // If the accesskey attribute is removed, unregister it here // Also see nsAreaFrame, nsBoxFrame and nsTextBoxFrame's AttributeChanged if (aName == nsGkAtoms::accesskey || aName == nsGkAtoms::control) { @@ -2284,6 +2310,28 @@ nsXULElement::HideWindowChrome(PRBool aShouldHide) return NS_OK; } +void +nsXULElement::SetTitlebarColor(nscolor aColor) +{ + nsIDocument* doc = GetCurrentDoc(); + if (!doc || doc->GetRootContent() != this) { + return; + } + + // only top level chrome documents can set the titlebar color + if (!doc->GetParentDocument()) { + nsCOMPtr container = doc->GetContainer(); + nsCOMPtr baseWindow = do_QueryInterface(container); + if (baseWindow) { + nsCOMPtr mainWidget; + baseWindow->GetMainWidget(getter_AddRefs(mainWidget)); + if (mainWidget) { + mainWidget->SetWindowTitlebarColor(aColor); + } + } + } +} + PRBool nsXULElement::BoolAttrIsTrue(nsIAtom* aName) { @@ -2351,26 +2399,40 @@ nsXULElement::RecompileScriptEventListeners() } } -NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(nsXULPrototypeNode) +NS_IMPL_CYCLE_COLLECTION_CLASS(nsXULPrototypeNode) NS_IMPL_CYCLE_COLLECTION_UNLINK_NATIVE_0(nsXULPrototypeNode) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(nsXULPrototypeNode) if (tmp->mType == nsXULPrototypeNode::eType_Element) { nsXULPrototypeElement *elem = static_cast(tmp); PRUint32 i; - for (i = 0; i < elem->mNumAttributes; ++i) { - cb.NoteScriptChild(elem->mScriptTypeID, - elem->mAttributes[i].mEventHandler); - } for (i = 0; i < elem->mNumChildren; ++i) { NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_PTR(elem->mChildren[i], nsXULPrototypeNode) } } - else if (tmp->mType == nsXULPrototypeNode::eType_Script) { - static_cast(tmp)->mScriptObject.traverse(cb); - } + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END +NS_IMPL_CYCLE_COLLECTION_TRACE_NATIVE_BEGIN(nsXULPrototypeNode) + if (tmp->mType == nsXULPrototypeNode::eType_Element) { + nsXULPrototypeElement *elem = + static_cast(tmp); + if (elem->mHoldsScriptObject) { + PRUint32 i; + for (i = 0; i < elem->mNumAttributes; ++i) { + void *handler = elem->mAttributes[i].mEventHandler; + NS_IMPL_CYCLE_COLLECTION_TRACE_CALLBACK(elem->mScriptTypeID, + handler) + } + } + } + else if (tmp->mType == nsXULPrototypeNode::eType_Script) { + nsXULPrototypeScript *script = + static_cast(tmp); + NS_IMPL_CYCLE_COLLECTION_TRACE_CALLBACK(script->mScriptObject.mLangID, + script->mScriptObject.mObject) + } +NS_IMPL_CYCLE_COLLECTION_TRACE_END NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsXULPrototypeNode, AddRef) NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsXULPrototypeNode, Release) @@ -2382,17 +2444,6 @@ NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsXULPrototypeNode, Release) nsXULPrototypeAttribute::~nsXULPrototypeAttribute() { MOZ_COUNT_DTOR(nsXULPrototypeAttribute); - NS_ASSERTION(!mEventHandler, "Finalize not called - language object leak!"); -} - -void -nsXULPrototypeAttribute::Finalize(PRUint32 aLangID) -{ - if (mEventHandler) { - if (NS_FAILED(nsContentUtils::DropScriptObject(aLangID, mEventHandler))) - NS_ERROR("Failed to drop script object"); - mEventHandler = nsnull; - } } @@ -2679,6 +2730,19 @@ nsXULPrototypeElement::SetAttrAt(PRUint32 aPos, const nsAString& aValue, return NS_OK; } +void +nsXULPrototypeElement::Unlink() +{ + if (mHoldsScriptObject) { + nsContentUtils::DropScriptObjects(mScriptTypeID, this, + &NS_CYCLE_COLLECTION_NAME(nsXULPrototypeNode)); + mHoldsScriptObject = PR_FALSE; + } + mNumAttributes = 0; + delete[] mAttributes; + mAttributes = nsnull; +} + //---------------------------------------------------------------------- // // nsXULPrototypeScript @@ -2701,6 +2765,7 @@ nsXULPrototypeScript::nsXULPrototypeScript(PRUint32 aLangID, PRUint32 aLineNo, P nsXULPrototypeScript::~nsXULPrototypeScript() { + Unlink(); } nsresult @@ -2818,7 +2883,7 @@ nsXULPrototypeScript::Deserialize(nsIObjectInputStream* aStream, NS_WARNING("Language deseralization failed"); return rv; } - mScriptObject.set(newScriptObject); + Set(newScriptObject); return NS_OK; } @@ -2871,7 +2936,7 @@ nsXULPrototypeScript::DeserializeOutOfLine(nsIObjectInputStream* aInput, NS_ERROR("XUL cache gave different language?"); return NS_ERROR_UNEXPECTED; } - mScriptObject.set(newScriptObject); + Set(newScriptObject); } } } @@ -2997,7 +3062,7 @@ nsXULPrototypeScript::Compile(const PRUnichar* aText, if (NS_FAILED(rv)) return rv; - mScriptObject.set(newScriptObject); + Set(newScriptObject); return rv; } diff --git a/content/xul/content/src/nsXULElement.h b/content/xul/content/src/nsXULElement.h index aed4c073b3b8..cbf3f8d07610 100644 --- a/content/xul/content/src/nsXULElement.h +++ b/content/xul/content/src/nsXULElement.h @@ -124,9 +124,6 @@ public: // nsScriptObjectHolder, but want to avoid the extra lang ID. void* mEventHandler; - // Containing element must tell us the langID so we can cleanup. - void Finalize(PRUint32 aLangID); - #ifdef XUL_PROTOTYPE_ATTRIBUTE_METERING /** If enough attributes, on average, are event handlers, it pays to keep @@ -230,7 +227,7 @@ public: */ virtual void ReleaseSubtree() { Release(); } - NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(nsXULPrototypeNode) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_NATIVE_CLASS(nsXULPrototypeNode) protected: nsXULPrototypeNode(Type aType) @@ -249,6 +246,7 @@ public: mHasIdAttribute(PR_FALSE), mHasClassAttribute(PR_FALSE), mHasStyleAttribute(PR_FALSE), + mHoldsScriptObject(PR_FALSE), mScriptTypeID(nsIProgrammingLanguage::UNKNOWN) { NS_LOG_ADDREF(this, 1, ClassName(), ClassSize()); @@ -256,10 +254,7 @@ public: virtual ~nsXULPrototypeElement() { - PRUint32 i; - for (i = 0; i < mNumAttributes; i++) - mAttributes[i].Finalize(mScriptTypeID); - delete[] mAttributes; + Unlink(); NS_ASSERTION(!mChildren && mNumChildren == 0, "ReleaseSubtree not called"); } @@ -294,6 +289,8 @@ public: nsresult SetAttrAt(PRUint32 aPos, const nsAString& aValue, nsIURI* aDocumentURI); + void Unlink(); + PRUint32 mNumChildren; nsXULPrototypeNode** mChildren; // [OWNER] @@ -305,6 +302,7 @@ public: PRPackedBool mHasIdAttribute:1; PRPackedBool mHasClassAttribute:1; PRPackedBool mHasStyleAttribute:1; + PRPackedBool mHoldsScriptObject:1; // The language ID can not be set on a per-node basis, but is tracked // so that the language ID from the originating root can be used @@ -361,13 +359,52 @@ public: nsIDocument* aDocument, nsIScriptGlobalObjectOwner* aGlobalOwner); + void Unlink() + { + if (mScriptObject.mObject) { + nsContentUtils::DropScriptObjects(mScriptObject.mLangID, this, + &NS_CYCLE_COLLECTION_NAME(nsXULPrototypeNode)); + mScriptObject.mObject = nsnull; + } + } + + void Set(nsScriptObjectHolder &aHolder) + { + NS_ASSERTION(mScriptObject.mLangID == aHolder.getScriptTypeID(), + "Wrong language, this will leak the previous object."); + + mScriptObject.mLangID = aHolder.getScriptTypeID(); + Set((void*)aHolder); + } + void Set(void *aObject) + { + NS_ASSERTION(!mScriptObject.mObject, "Leaking script object."); + + nsresult rv = nsContentUtils::HoldScriptObject(mScriptObject.mLangID, + this, + &NS_CYCLE_COLLECTION_NAME(nsXULPrototypeNode), + aObject, PR_FALSE); + if (NS_SUCCEEDED(rv)) { + mScriptObject.mObject = aObject; + } + } + + struct ScriptObjectHolder + { + ScriptObjectHolder(PRUint32 aLangID) : mLangID(aLangID), + mObject(nsnull) + { + } + PRUint32 mLangID; + void* mObject; + }; nsCOMPtr mSrcURI; PRUint32 mLineNo; PRPackedBool mSrcLoading; PRPackedBool mOutOfLine; nsXULDocument* mSrcLoadWaiters; // [OWNER] but not COMPtr PRUint32 mLangVersion; - nsContentUtils::ScriptObjectHolder mScriptObject; + ScriptObjectHolder mScriptObject; }; class nsXULPrototypeText : public nsXULPrototypeNode @@ -676,6 +713,8 @@ protected: nsresult HideWindowChrome(PRBool aShouldHide); + void SetTitlebarColor(nscolor aColor); + const nsAttrName* InternalGetExistingAttrNameFromQName(const nsAString& aStr) const; protected: diff --git a/content/xul/document/src/nsXULDocument.cpp b/content/xul/document/src/nsXULDocument.cpp index 1b18e2e6a211..f5b2a1e9b09f 100644 --- a/content/xul/document/src/nsXULDocument.cpp +++ b/content/xul/document/src/nsXULDocument.cpp @@ -424,18 +424,8 @@ nsXULDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel, mChannel = aChannel; // Get the URI. Note that this should match nsDocShell::OnLoadingSite - // XXXbz this code is repeated from nsDocument::Reset and - // nsScriptSecurityManager::GetChannelPrincipal; we really need to refactor - // this part better. - nsLoadFlags loadFlags = 0; - nsresult rv = aChannel->GetLoadFlags(&loadFlags); - if (NS_SUCCEEDED(rv)) { - if (loadFlags & nsIChannel::LOAD_REPLACE) { - rv = aChannel->GetURI(getter_AddRefs(mDocumentURI)); - } else { - rv = aChannel->GetOriginalURI(getter_AddRefs(mDocumentURI)); - } - } + nsresult rv = + NS_GetFinalChannelURI(aChannel, getter_AddRefs(mDocumentURI)); NS_ENSURE_SUCCESS(rv, rv); rv = ResetStylesheetsToURI(mDocumentURI); @@ -2618,7 +2608,7 @@ nsXULDocument::LoadOverlayInternal(nsIURI* aURI, PRBool aIsDynamic, PRBool overlayIsChrome = IsChromeURI(aURI); if (!IsChromeURI(mDocumentURI) && !overlayIsChrome) { // Make sure we're allowed to load this overlay. - rv = secMan->CheckSameOriginURI(mDocumentURI, aURI); + rv = secMan->CheckSameOriginURI(mDocumentURI, aURI, PR_TRUE); if (NS_FAILED(rv)) { *aFailureFromContent = PR_TRUE; return rv; @@ -3219,7 +3209,7 @@ nsXULDocument::LoadScript(nsXULPrototypeScript* aScriptProto, PRBool* aBlock) NS_ERROR("XUL cache gave me an incorrect script language"); return NS_ERROR_UNEXPECTED; } - aScriptProto->mScriptObject.set(newScriptObject); + aScriptProto->Set(newScriptObject); } if (aScriptProto->mScriptObject.mObject) { @@ -4064,6 +4054,10 @@ nsXULDocument::FindBroadcaster(nsIContent* aElement, // broadcaster element, and an 'attribute' element, which // specifies the name of the attribute to observe. nsIContent* parent = aElement->GetParent(); + if (!parent) { + // is the root element + return NS_FINDBROADCASTER_NOT_FOUND; + } // If we're still parented by an 'overlay' tag, then we haven't // made it into the real document yet. Defer hookup. diff --git a/docshell/base/nsDocShell.cpp b/docshell/base/nsDocShell.cpp index 8c07f26b6c2b..20bda6c3e2c3 100644 --- a/docshell/base/nsDocShell.cpp +++ b/docshell/base/nsDocShell.cpp @@ -2853,6 +2853,9 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI, nsresult rv = NS_OK; nsAutoString messageStr; nsCAutoString cssClass; + nsCAutoString errorPage; + + errorPage.AssignLiteral("neterror"); // Turn the error code into a human readable error message. if (NS_ERROR_UNKNOWN_PROTOCOL == aError) { @@ -2928,6 +2931,15 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI, error.AssignLiteral("netTimeout"); } else if (NS_ERROR_GET_MODULE(aError) == NS_ERROR_MODULE_SECURITY) { + nsCOMPtr nsserr = + do_GetService(NS_NSS_ERRORS_SERVICE_CONTRACTID); + + PRUint32 errorClass; + if (!nsserr || + NS_FAILED(nsserr->GetErrorClass(aError, &errorClass))) { + errorClass = nsINSSErrorsService::ERROR_CLASS_SSL_PROTOCOL; + } + nsCOMPtr securityInfo; nsCOMPtr tsi; if (aFailedChannel) @@ -2939,14 +2951,36 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI, } else { // No channel, let's obtain the generic error message - nsCOMPtr nsserr = - do_GetService(NS_NSS_ERRORS_SERVICE_CONTRACTID); if (nsserr) { nsserr->GetErrorMessage(aError, messageStr); } } - if (!messageStr.IsEmpty()) - error.AssignLiteral("nssFailure2"); + if (!messageStr.IsEmpty()) { + if (errorClass == nsINSSErrorsService::ERROR_CLASS_BAD_CERT) { + error.AssignLiteral("nssBadCert"); + } else { + error.AssignLiteral("nssFailure2"); + } + } + } else if (NS_ERROR_PHISHING_URI == aError || NS_ERROR_MALWARE_URI == aError) { + nsCAutoString host; + aURI->GetHost(host); + CopyUTF8toUTF16(host, formatStrs[0]); + formatStrCount = 1; + + // Malware and phishing detectors may want to use an alternate error + // page, but if the pref's not set, we'll fall back on the standard page + nsXPIDLCString alternateErrorPage; + mPrefs->GetCharPref("urlclassifier.alternate_error_page", + getter_Copies(alternateErrorPage)); + if (alternateErrorPage) + errorPage.Assign(alternateErrorPage); + + if (NS_ERROR_PHISHING_URI == aError) + error.AssignLiteral("phishingBlocked"); + else + error.AssignLiteral("malwareBlocked"); + cssClass.AssignLiteral("blacklist"); } else { // Errors requiring simple formatting @@ -2993,15 +3027,6 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI, // Bad Content Encoding. error.AssignLiteral("contentEncodingError"); break; - case NS_ERROR_MALWARE_URI: - nsCAutoString host; - aURI->GetHost(host); - CopyUTF8toUTF16(host, formatStrs[0]); - formatStrCount = 1; - - error.AssignLiteral("malwareBlocked"); - cssClass.AssignLiteral("blacklist"); - break; } } @@ -3042,8 +3067,8 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI, // URI object. Missing URI objects are handled badly by session history. if (mUseErrorPages && aURI && aFailedChannel) { // Display an error page - LoadErrorPage(aURI, aURL, error.get(), messageStr.get(), - cssClass.get(), aFailedChannel); + LoadErrorPage(aURI, aURL, errorPage.get(), error.get(), + messageStr.get(), cssClass.get(), aFailedChannel); } else { @@ -3066,6 +3091,7 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI, NS_IMETHODIMP nsDocShell::LoadErrorPage(nsIURI *aURI, const PRUnichar *aURL, + const char *aErrorPage, const PRUnichar *aErrorType, const PRUnichar *aDescription, const char *aCSSClass, @@ -3135,7 +3161,9 @@ nsDocShell::LoadErrorPage(nsIURI *aURI, const PRUnichar *aURL, char *escapedDescription = nsEscape(NS_ConvertUTF16toUTF8(aDescription).get(), url_Path); char *escapedCSSClass = nsEscape(aCSSClass, url_Path); - nsCString errorPageUrl("about:neterror?e="); + nsCString errorPageUrl("about:"); + errorPageUrl.AppendASCII(aErrorPage); + errorPageUrl.AppendLiteral("?e="); errorPageUrl.AppendASCII(escapedError); errorPageUrl.AppendLiteral("&u="); @@ -7760,12 +7788,7 @@ nsDocShell::OnLoadingSite(nsIChannel * aChannel, PRBool aFireOnLocationChange, // else use the original url // // Note that this should match what documents do (see nsDocument::Reset). - nsLoadFlags loadFlags = 0; - aChannel->GetLoadFlags(&loadFlags); - if (loadFlags & nsIChannel::LOAD_REPLACE) - aChannel->GetURI(getter_AddRefs(uri)); - else - aChannel->GetOriginalURI(getter_AddRefs(uri)); + NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri)); NS_ENSURE_TRUE(uri, PR_FALSE); return OnNewURI(uri, aChannel, mLoadType, aFireOnLocationChange, diff --git a/docshell/base/nsDocShell.h b/docshell/base/nsDocShell.h index e44a8deb521e..6dbd4eb2e0de 100644 --- a/docshell/base/nsDocShell.h +++ b/docshell/base/nsDocShell.h @@ -404,7 +404,8 @@ protected: const PRUnichar *aURL, nsIChannel* aFailedChannel = nsnull); NS_IMETHOD LoadErrorPage(nsIURI *aURI, const PRUnichar *aURL, - const PRUnichar *aPage, + const char *aErrorPage, + const PRUnichar *aErrorType, const PRUnichar *aDescription, const char *aCSSClass, nsIChannel* aFailedChannel); diff --git a/docshell/base/nsWebShell.cpp b/docshell/base/nsWebShell.cpp index d561c75893a7..c146c498fd97 100644 --- a/docshell/base/nsWebShell.cpp +++ b/docshell/base/nsWebShell.cpp @@ -1195,6 +1195,7 @@ nsresult nsWebShell::EndPageLoad(nsIWebProgress *aProgress, aStatus == NS_ERROR_NET_INTERRUPT || aStatus == NS_ERROR_NET_RESET || aStatus == NS_ERROR_MALWARE_URI || + aStatus == NS_ERROR_PHISHING_URI || NS_ERROR_GET_MODULE(aStatus) == NS_ERROR_MODULE_SECURITY) { DisplayLoadError(aStatus, url, nsnull, channel); } diff --git a/docshell/build/Makefile.in b/docshell/build/Makefile.in index a018bc2fd6ec..d2019f9585a5 100644 --- a/docshell/build/Makefile.in +++ b/docshell/build/Makefile.in @@ -135,7 +135,7 @@ EXTRA_DSO_LDOPTS += \ endif ifeq ($(OS_ARCH),WINNT) -OS_LIBS += $(call EXPAND_LIBNAME, shell32) +OS_LIBS += $(call EXPAND_LIBNAME, shell32 ole32) endif ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2) diff --git a/docshell/resources/content/netError.xhtml b/docshell/resources/content/netError.xhtml index 886410ebeb3e..01d245936334 100644 --- a/docshell/resources/content/netError.xhtml +++ b/docshell/resources/content/netError.xhtml @@ -202,6 +202,7 @@

    &proxyConnectFailure.title;

    &contentEncodingError.title;

    &nssFailure2.title;

    +

    &nssBadCert.title;

    &malwareBlocked.title;

    @@ -222,6 +223,7 @@
    &proxyConnectFailure.longDesc;
    &contentEncodingError.longDesc;
    &nssFailure2.longDesc;
    +
    &nssBadCert.longDesc;
    &malwareBlocked.longDesc;
    diff --git a/dom/locales/en-US/chrome/appstrings.properties b/dom/locales/en-US/chrome/appstrings.properties index b31d45522e7d..2efa1b8fed84 100644 --- a/dom/locales/en-US/chrome/appstrings.properties +++ b/dom/locales/en-US/chrome/appstrings.properties @@ -60,3 +60,4 @@ externalProtocolUnknown= externalProtocolChkMsg=Remember my choice for all links of this type. externalProtocolLaunchBtn=Launch application malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences. +phishingBlocked=The web site at %S has been reported as a web forgery designed to trick users into sharing personal or financial information. diff --git a/dom/locales/en-US/chrome/layout/xul.properties b/dom/locales/en-US/chrome/layout/xul.properties index 6765b1f5d7aa..45c8a8dfa85a 100644 --- a/dom/locales/en-US/chrome/layout/xul.properties +++ b/dom/locales/en-US/chrome/layout/xul.properties @@ -35,3 +35,4 @@ MissingOverlay=Failed to load overlay from %1$S. PINotInProlog= processing instruction does not have any effect outside the prolog anymore (see bug 360119). +NeededToWrapXUL=XUL box for %1$S element contained an inline %2$S child, forcing all its children to be wrapped in a block. diff --git a/dom/locales/en-US/chrome/netError.dtd b/dom/locales/en-US/chrome/netError.dtd index d92d0808f531..d99b2aebd6e7 100644 --- a/dom/locales/en-US/chrome/netError.dtd +++ b/dom/locales/en-US/chrome/netError.dtd @@ -54,8 +54,22 @@ The page you are trying to view can not be shown because the authenticity of the received data could not be verified.

    • Please contact the web site owners to inform them of this problem.
    "> + + +
  • This could be a problem with the server's configuration, or it could be someone trying to impersonate the server.
  • +
  • If you have connected to this server successfully in the past, the error may be temporary, and you can try again later.
  • +
  • You can see and change your current list of servers with known security problems in your advanced encryption settings.
  • + +"> + Attack sites try to install programs that steal private information, use your computer to attack others, or damage your system.

    Web site owners who believe their site has been reported as an attack site in error may request a review.

    "> + + +Entering any personal information on this page may result in identity theft or other fraud.

    +

    These types of web forgeries are used in scams known as phishing attacks, in which fraudulent web pages and emails are used to imitate sources you may trust.

    +"> diff --git a/dom/public/idl/base/nsIDOMWindowUtils.idl b/dom/public/idl/base/nsIDOMWindowUtils.idl index 04cbca58ff54..55307d7895b9 100644 --- a/dom/public/idl/base/nsIDOMWindowUtils.idl +++ b/dom/public/idl/base/nsIDOMWindowUtils.idl @@ -47,7 +47,7 @@ interface nsIDOMElement; -[scriptable, uuid(25f55fb2-a6f8-4f7f-93c3-3adafd5166bc)] +[scriptable, uuid(7a55fc2b-afb3-41c6-9e50-3fee341fa87c)] interface nsIDOMWindowUtils : nsISupports { /** @@ -156,4 +156,13 @@ interface nsIDOMWindowUtils : nsISupports { * @param aElement the element to focus */ void focus(in nsIDOMElement aElement); + + /** + * Force a garbage collection. This will run the cycle-collector twice to + * make sure all garbage is collected. + * + * Will throw a DOM security error if called without UniversalXPConnect + * privileges in non-debug builds. Available to all callers in debug builds. + */ + void garbageCollect(); }; diff --git a/dom/src/base/nsDOMClassInfo.cpp b/dom/src/base/nsDOMClassInfo.cpp index 9dff7007856d..13fce75329d2 100644 --- a/dom/src/base/nsDOMClassInfo.cpp +++ b/dom/src/base/nsDOMClassInfo.cpp @@ -6586,9 +6586,10 @@ nsNodeSH::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, { if ((id == sBaseURIObject_id || id == sNodePrincipal_id) && IsPrivilegedScript()) { - // Is there a better error we could use here? We don't want privileged - // script that can read these properties to set them, but _do_ want to - // allow everyone else to. + // We don't want privileged script that can read this property to set it, + // but _do_ want to allow everyone else to set a value they can then read. + // + // XXXbz Is there a better error we could use here? return NS_ERROR_DOM_NOT_SUPPORTED_ERR; } @@ -6953,6 +6954,25 @@ nsElementSH::PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx, return NS_OK; } + // We must ensure that the XBL Binding is installed before we hand + // back this object. + + nsRefPtr binding; + if (content->HasFlag(NODE_MAY_BE_IN_BINDING_MNGR) && + (binding = doc->BindingManager()->GetBinding(content))) { + // There's already a binding for this element, make sure that + // the script API has been installed. + // Note that this could end up recusing into code that calls + // WrapNative. So don't do anything important beyond this point + // as that will not be done to the wrapper returned from that + // WrapNative call. + // In theory we could also call ExecuteAttachedHandler here if + // we also removed the binding from the PAQ queue, but that seems + // like a scary change that would mosly just add more inconsistencies. + + return binding->EnsureScriptAPI(); + } + // See if we have a frame. nsIPresShell *shell = doc->GetPrimaryShell(); @@ -6968,23 +6988,12 @@ nsElementSH::PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx, return NS_OK; } - // We must ensure that the XBL Binding is installed before we hand - // back this object. - - if (doc->BindingManager()->GetBinding(content)) { - // There's already a binding for this element so nothing left to - // be done here. - - return NS_OK; - } - // Get the computed -moz-binding directly from the style context nsPresContext *pctx = shell->GetPresContext(); NS_ENSURE_TRUE(pctx, NS_ERROR_UNEXPECTED); // Make sure the style context goes away _before_ we execute the binding // constructor, since the constructor can destroy the relevant presshell. - nsRefPtr binding; { // Scope for the nsRefPtr nsRefPtr sc = pctx->StyleSet()->ResolveStyleFor(content, @@ -7009,6 +7018,16 @@ nsElementSH::PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx, } if (binding) { + +#ifdef DEBUG + PRBool safeToRunScript = PR_FALSE; + pctx->PresShell()->IsSafeToFlush(safeToRunScript); + NS_ASSERTION(safeToRunScript, "Wrapping when it's not safe to flush"); +#endif + + rv = binding->EnsureScriptAPI(); + NS_ENSURE_SUCCESS(rv, rv); + binding->ExecuteAttachedHandler(); } @@ -7484,9 +7503,10 @@ nsDocumentSH::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, } if (id == sDocumentURIObject_id && IsPrivilegedScript()) { - // Is there a better error we could use here? We don't want privileged - // script that can read this property to set it, but _do_ want to allow - // everyone else to. + // We don't want privileged script that can read this property to set it, + // but _do_ want to allow everyone else to set a value they can then read. + // + // XXXbz Is there a better error we could use here? return NS_ERROR_DOM_NOT_SUPPORTED_ERR; } diff --git a/dom/src/base/nsDOMWindowUtils.cpp b/dom/src/base/nsDOMWindowUtils.cpp index 6a1d53da183a..92cd1d5b1c94 100644 --- a/dom/src/base/nsDOMWindowUtils.cpp +++ b/dom/src/base/nsDOMWindowUtils.cpp @@ -53,6 +53,7 @@ #include "nsIWidget.h" #include "nsGUIEvent.h" #include "nsIParser.h" +#include "nsCycleCollector.h" #ifdef MOZ_ENABLE_GTK2 #include @@ -327,3 +328,21 @@ nsDOMWindowUtils::Focus(nsIDOMElement* aElement) return NS_OK; } +NS_IMETHODIMP +nsDOMWindowUtils::GarbageCollect() +{ + // NOTE: Only do this in NON debug builds, as this function can useful + // during debugging. +#ifndef DEBUG + PRBool hasCap = PR_FALSE; + if (NS_FAILED(nsContentUtils::GetSecurityManager()-> + IsCapabilityEnabled("UniversalXPConnect", &hasCap)) + || !hasCap) + return NS_ERROR_DOM_SECURITY_ERR; +#endif + + nsCycleCollector_collect(); + nsCycleCollector_collect(); + + return NS_OK; +} diff --git a/dom/src/base/nsJSEnvironment.cpp b/dom/src/base/nsJSEnvironment.cpp index f920b4cf0cfa..f1ae27b10128 100644 --- a/dom/src/base/nsJSEnvironment.cpp +++ b/dom/src/base/nsJSEnvironment.cpp @@ -149,8 +149,27 @@ static PRLogModuleInfo* gJSDiagnostics; #define JAVASCRIPT nsIProgrammingLanguage::JAVASCRIPT +// The max number of delayed cycle collects.. +#define NS_MAX_DELAYED_CCOLLECT 45 +// The max number of user interaction notifications in inactive state before +// we try to call cycle collector more aggressively. +#define NS_CC_SOFT_LIMIT_INACTIVE 6 +// The max number of user interaction notifications in active state before +// we try to call cycle collector more aggressively. +#define NS_CC_SOFT_LIMIT_ACTIVE 12 +// When higher probability MaybeCC is used, the number of sDelayedCCollectCount +// is multiplied with this number. +#define NS_PROBABILITY_MULTIPLIER 3 +// Cycle collector should never run more often than this value +#define NS_MIN_CC_INTERVAL 10000 // ms + // if you add statics here, add them to the list in nsJSRuntime::Startup +static PRUint32 sDelayedCCollectCount; +static PRUint32 sCCollectCount; +static PRBool sUserIsActive; +static PRTime sPreviousCCTime; +static PRBool sPreviousCCDidCollect; static nsITimer *sGCTimer; static PRBool sReadyForGC; @@ -194,6 +213,74 @@ static nsICollation *gCollation; static nsIUnicodeDecoder *gDecoder; +// nsUserActivityObserver observes user-interaction-active and +// user-interaction-inactive notifications. It counts the number of +// notifications and if the number is bigger than NS_CC_SOFT_LIMIT_ACTIVE +// (in case the current notification is user-interaction-active) or +// NS_CC_SOFT_LIMIT_INACTIVE (current notification is user-interaction-inactive) +// MaybeCC is called with aHigherParameter set to PR_TRUE, otherwise PR_FALSE. +// +// When moving from active state to inactive, nsJSContext::CC() is called +// unless the timer related to page load is active. + +class nsUserActivityObserver : public nsIObserver +{ +public: + nsUserActivityObserver() + : mUserActivityCounter(0), mOldCCollectCount(0) {} + NS_DECL_ISUPPORTS + NS_DECL_NSIOBSERVER +private: + PRUint32 mUserActivityCounter; + PRUint32 mOldCCollectCount; +}; + +NS_IMPL_ISUPPORTS1(nsUserActivityObserver, nsIObserver) + +NS_IMETHODIMP +nsUserActivityObserver::Observe(nsISupports* aSubject, const char* aTopic, + const PRUnichar* aData) +{ + if (mOldCCollectCount != sCCollectCount) { + mOldCCollectCount = sCCollectCount; + // Cycle collector was called between user interaction notifications, so + // we can reset the counter. + mUserActivityCounter = 0; + } + PRBool higherProbability = PR_FALSE; + ++mUserActivityCounter; + if (!strcmp(aTopic, "user-interaction-inactive")) { +#ifdef DEBUG_smaug + printf("user-interaction-inactive\n"); +#endif + if (sUserIsActive) { + sUserIsActive = PR_FALSE; + if (!sGCTimer) { + nsJSContext::CC(); + return NS_OK; + } + } + higherProbability = (mUserActivityCounter > NS_CC_SOFT_LIMIT_INACTIVE); + } else if (!strcmp(aTopic, "user-interaction-active")) { +#ifdef DEBUG_smaug + printf("user-interaction-active\n"); +#endif + sUserIsActive = PR_TRUE; + higherProbability = (mUserActivityCounter > NS_CC_SOFT_LIMIT_ACTIVE); + } else if (!strcmp(aTopic, "xpcom-shutdown")) { + nsCOMPtr obs = + do_GetService("@mozilla.org/observer-service;1"); + if (obs) { + obs->RemoveObserver(this, "user-interaction-active"); + obs->RemoveObserver(this, "user-interaction-inactive"); + obs->RemoveObserver(this, "xpcom-shutdown"); + } + return NS_OK; + } + nsJSContext::MaybeCC(higherProbability); + return NS_OK; +} + /**************************************************************** ************************** AutoFree **************************** ****************************************************************/ @@ -340,7 +427,7 @@ NS_ScriptErrorReporter(JSContext *cx, // URIs. See bug 387476. sameOrigin = NS_SUCCEEDED(sSecurityManager-> - CheckSameOriginURI(errorURI, codebase)); + CheckSameOriginURI(errorURI, codebase, PR_TRUE)); } } @@ -1746,17 +1833,6 @@ nsJSContext::CallEventHandler(nsISupports* aTarget, void *aScope, void *aHandler return NS_OK; } - // This may not be strictly needed, but lets do it as an extra level - // of safety. Ideally the check in nsGenericElement::AddScriptEventListener - // is enough. - nsCOMPtr nodeTarget = do_QueryInterface(aTarget); - if (nodeTarget) { - nsIDocument* doc = nodeTarget->GetOwnerDoc(); - if (!doc || doc->IsLoadedAsData()) { - return NS_ERROR_NOT_AVAILABLE; - } - } - nsresult rv; JSObject* target = nsnull; nsAutoGCRoot root(&target, &rv); @@ -3182,6 +3258,63 @@ nsJSContext::PreserveWrapper(nsIXPConnectWrappedNative *aWrapper) return nsDOMClassInfo::PreserveNodeWrapper(aWrapper); } +//static +void +nsJSContext::CC() +{ + sPreviousCCTime = PR_Now(); + sDelayedCCollectCount = 0; + ++sCCollectCount; +#ifdef DEBUG_smaug + printf("Will run cycle collector (%i)\n", sCCollectCount); +#endif + // nsCycleCollector_collect() will run a ::JS_GC() indirectly, so + // we do not explicitly call ::JS_GC() here. + sPreviousCCDidCollect = nsCycleCollector_collect(); +#ifdef DEBUG_smaug + printf("(1) %s\n", sPreviousCCDidCollect ? + "Cycle collector did collect nodes" : + "Cycle collector did not collect nodes"); +#endif +} + +//static +PRBool +nsJSContext::MaybeCC(PRBool aHigherProbability) +{ + ++sDelayedCCollectCount; + // Increase the probability also if the previous call to cycle collector + // collected something. + if (aHigherProbability || sPreviousCCDidCollect) { + sDelayedCCollectCount *= NS_PROBABILITY_MULTIPLIER; + } + + if (!sGCTimer && (sDelayedCCollectCount > NS_MAX_DELAYED_CCOLLECT)) { + if ((PR_Now() - sPreviousCCTime) >= + PRTime(NS_MIN_CC_INTERVAL * PR_USEC_PER_MSEC)) { + nsJSContext::CC(); + return PR_TRUE; + } +#ifdef DEBUG_smaug + else { + printf("Running cycle collector was delayed: NS_MIN_CC_INTERVAL\n"); + } +#endif + } + return PR_FALSE; +} + +//static +void +nsJSContext::CCIfUserInactive() +{ + if (sUserIsActive) { + MaybeCC(PR_TRUE); + } else { + CC(); + } +} + NS_IMETHODIMP nsJSContext::Notify(nsITimer *timer) { @@ -3200,9 +3333,7 @@ nsJSContext::Notify(nsITimer *timer) // loading and move on as if they weren't. sPendingLoadCount = 0; - // nsCycleCollector_collect() will run a ::JS_GC() indirectly, - // so we do not explicitly call ::JS_GC() here. - nsCycleCollector_collect(); + CCIfUserInactive(); } else { FireGCTimer(PR_TRUE); } @@ -3231,13 +3362,10 @@ nsJSContext::LoadEnd() if (!sPendingLoadCount && sLoadInProgressGCTimer) { sGCTimer->Cancel(); - NS_RELEASE(sGCTimer); sLoadInProgressGCTimer = PR_FALSE; - // nsCycleCollector_collect() will run a ::JS_GC() indirectly, so - // we do not explicitly call ::JS_GC() here. - nsCycleCollector_collect(); + CCIfUserInactive(); } } @@ -3264,10 +3392,7 @@ nsJSContext::FireGCTimer(PRBool aLoadInProgress) // timer. sLoadInProgressGCTimer = PR_FALSE; - // nsCycleCollector_collect() will run a ::JS_GC() indirectly, so - // we do not explicitly call ::JS_GC() here. - nsCycleCollector_collect(); - + CCIfUserInactive(); return; } @@ -3375,6 +3500,11 @@ void nsJSRuntime::Startup() { // initialize all our statics, so that we can restart XPCOM + sDelayedCCollectCount = 0; + sCCollectCount = 0; + sUserIsActive = PR_FALSE; + sPreviousCCTime = 0; + sPreviousCCDidCollect = PR_FALSE; sGCTimer = nsnull; sReadyForGC = PR_FALSE; sLoadInProgressGCTimer = PR_FALSE; @@ -3493,6 +3623,15 @@ nsJSRuntime::Init() MaxScriptRunTimePrefChangedCallback("dom.max_chrome_script_run_time", nsnull); + nsCOMPtr obs = + do_GetService("@mozilla.org/observer-service;1", &rv); + NS_ENSURE_SUCCESS(rv, rv); + nsIObserver* activityObserver = new nsUserActivityObserver(); + NS_ENSURE_TRUE(activityObserver, NS_ERROR_OUT_OF_MEMORY); + obs->AddObserver(activityObserver, "user-interaction-inactive", PR_FALSE); + obs->AddObserver(activityObserver, "user-interaction-active", PR_FALSE); + obs->AddObserver(activityObserver, "xpcom-shutdown", PR_FALSE); + rv = CallGetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &sSecurityManager); sIsInitialized = NS_SUCCEEDED(rv); @@ -3590,7 +3729,8 @@ public: ~nsJSArgArray(); // nsISupports NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsJSArgArray, nsIJSArgArray) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsJSArgArray, + nsIJSArgArray) // nsIArray NS_DECL_NSIARRAY @@ -3620,16 +3760,14 @@ nsJSArgArray::nsJSArgArray(JSContext *aContext, PRUint32 argc, jsval *argv, return; } - JSAutoRequest ar(aContext); - for (PRUint32 i = 0; i < argc; ++i) { - if (argv) + // Callers are allowed to pass in a null argv even for argc > 0. They can + // then use GetArgs to initialize the values. + if (argv) { + for (PRUint32 i = 0; i < argc; ++i) mArgv[i] = argv[i]; - if (!::JS_AddNamedRoot(aContext, &mArgv[i], "nsJSArgArray.mArgv[i]")) { - *prv = NS_ERROR_UNEXPECTED; - return; - } } - *prv = NS_OK; + + *prv = argc > 0 ? NS_HOLD_JS_OBJECTS(this, nsJSArgArray) : NS_OK; } nsJSArgArray::~nsJSArgArray() @@ -3640,13 +3778,9 @@ nsJSArgArray::~nsJSArgArray() void nsJSArgArray::ReleaseJSObjects() { + if (mArgc > 0) + NS_DROP_JS_OBJECTS(this, nsJSArgArray); if (mArgv) { - NS_ASSERTION(nsJSRuntime::sRuntime, "Where's the runtime gone?"); - if (nsJSRuntime::sRuntime) { - for (PRUint32 i = 0; i < mArgc; ++i) { - ::JS_RemoveRootRT(nsJSRuntime::sRuntime, &mArgv[i]); - } - } PR_DELETE(mArgv); } mArgc = 0; @@ -3658,17 +3792,20 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsJSArgArray) tmp->ReleaseJSObjects(); NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsJSArgArray) - { - jsval *argv = tmp->mArgv; - if (argv) { - jsval *end; - for (end = argv + tmp->mArgc; argv < end; ++argv) { - if (JSVAL_IS_OBJECT(*argv)) - cb.NoteScriptChild(JAVASCRIPT, JSVAL_TO_OBJECT(*argv)); - } + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsJSArgArray) + jsval *argv = tmp->mArgv; + if (argv) { + jsval *end; + for (end = argv + tmp->mArgc; argv < end; ++argv) { + if (JSVAL_IS_GCTHING(*argv)) + NS_IMPL_CYCLE_COLLECTION_TRACE_CALLBACK(JAVASCRIPT, + JSVAL_TO_GCTHING(*argv)) } } -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END +NS_IMPL_CYCLE_COLLECTION_TRACE_END NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsJSArgArray) NS_INTERFACE_MAP_ENTRY(nsIArray) diff --git a/dom/src/base/nsJSEnvironment.h b/dom/src/base/nsJSEnvironment.h index c1cefb86a41a..0c48c1a97c9d 100644 --- a/dom/src/base/nsJSEnvironment.h +++ b/dom/src/base/nsJSEnvironment.h @@ -170,6 +170,27 @@ public: static void LoadStart(); static void LoadEnd(); + // CC does always call cycle collector and it also updates the counters + // that MaybeCC uses. + static void CC(); + + // MaybeCC calls cycle collector if certain conditions are fulfilled. + // The conditions are: + // - The timer related to page load (sGCTimer) must not be active. + // - At least NS_MIN_CC_INTERVAL milliseconds must have elapsed since the + // previous cycle collector call. + // - Certain number of MaybeCC calls have occurred. + // The number of needed MaybeCC calls depends on the aHigherProbability + // parameter. If the parameter is true, probability for calling cycle + // collector rises increasingly. If the parameter is all the time false, + // at least NS_MAX_DELAYED_CCOLLECT MaybeCC calls are needed. + // If the previous call to cycle collector did collect something, + // MaybeCC works effectively as if aHigherProbability was true. + // @return PR_TRUE if cycle collector was called. + static PRBool MaybeCC(PRBool aHigherProbability); + + // Calls CC() if user is currently inactive, otherwise MaybeCC(PR_TRUE) + static void CCIfUserInactive(); protected: nsresult InitializeExternalClasses(); // aHolder should be holding our global object diff --git a/dom/src/base/nsJSTimeoutHandler.cpp b/dom/src/base/nsJSTimeoutHandler.cpp index b2dd3e89eb7f..989f4dd3c0cb 100644 --- a/dom/src/base/nsJSTimeoutHandler.cpp +++ b/dom/src/base/nsJSTimeoutHandler.cpp @@ -59,7 +59,7 @@ class nsJSScriptTimeoutHandler: public nsIScriptTimeoutHandler public: // nsISupports NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_CLASS(nsJSScriptTimeoutHandler) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsJSScriptTimeoutHandler) nsJSScriptTimeoutHandler(); ~nsJSScriptTimeoutHandler(); @@ -118,9 +118,14 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsJSScriptTimeoutHandler) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mContext) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mArgv) - cb.NoteScriptChild(nsIProgrammingLanguage::JAVASCRIPT, tmp->mFunObj); + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END +NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsJSScriptTimeoutHandler) + NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mExpr) + NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mFunObj) +NS_IMPL_CYCLE_COLLECTION_TRACE_END + NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsJSScriptTimeoutHandler) NS_INTERFACE_MAP_ENTRY(nsIScriptTimeoutHandler) NS_INTERFACE_MAP_ENTRY(nsISupports) @@ -146,49 +151,11 @@ void nsJSScriptTimeoutHandler::ReleaseJSObjects() { if (mExpr || mFunObj) { - nsCOMPtr scx = mContext; - JSRuntime *rt = nsnull; - - if (scx) { - JSContext *cx; - cx = (JSContext *)scx->GetNativeContext(); - rt = ::JS_GetRuntime(cx); - mContext = nsnull; - } else { - // XXX The timeout *must* be unrooted, even if !scx. This can be - // done without a JS context using the JSRuntime. This is safe - // enough, but it would be better to drop all a window's - // timeouts before its context is cleared. Bug 50705 describes a - // situation where we're not. In that case, at the time the - // context is cleared, a timeout (actually an Interval) is still - // active, but temporarily removed from the window's list of - // timers (placed instead on the timer manager's list). This - // makes the nearly handy ClearAllTimeouts routine useless, so - // we settled on using the JSRuntime rather than relying on the - // window having a context. It would be good to remedy this - // workable but clumsy situation someday. - - nsCOMPtr rtsvc = - do_GetService("@mozilla.org/js/xpc/RuntimeService;1"); - - if (rtsvc) { - rtsvc->GetRuntime(&rt); - } - } - - if (!rt) { - // most unexpected. not much choice but to bail. - - NS_ERROR("nsTimeout::Release() with no JSRuntime. eek!"); - - return; - } - if (mExpr) { - ::JS_RemoveRootRT(rt, &mExpr); + NS_DROP_JS_OBJECTS(this, nsJSScriptTimeoutHandler); mExpr = nsnull; } else if (mFunObj) { - ::JS_RemoveRootRT(rt, &mFunObj); + NS_DROP_JS_OBJECTS(this, nsJSScriptTimeoutHandler); mFunObj = nsnull; } else { NS_WARNING("No func and no expr - roots may not have been removed"); @@ -280,9 +247,8 @@ nsJSScriptTimeoutHandler::Init(nsIScriptContext *aContext, PRBool *aIsInterval, } if (expr) { - if (!::JS_AddNamedRoot(cx, &mExpr, "timeout.mExpr")) { - return NS_ERROR_OUT_OF_MEMORY; - } + rv = NS_HOLD_JS_OBJECTS(this, nsJSScriptTimeoutHandler); + NS_ENSURE_SUCCESS(rv, rv); mExpr = expr; @@ -292,9 +258,8 @@ nsJSScriptTimeoutHandler::Init(nsIScriptContext *aContext, PRBool *aIsInterval, mFileName.Assign(filename); } } else if (funobj) { - if (!::JS_AddNamedRoot(cx, &mFunObj, "timeout.mFunObj")) { - return NS_ERROR_OUT_OF_MEMORY; - } + rv = NS_HOLD_JS_OBJECTS(this, nsJSScriptTimeoutHandler); + NS_ENSURE_SUCCESS(rv, rv); mFunObj = funobj; diff --git a/dom/src/events/nsJSEventListener.cpp b/dom/src/events/nsJSEventListener.cpp index 414da25a809a..46ae7c366cec 100644 --- a/dom/src/events/nsJSEventListener.cpp +++ b/dom/src/events/nsJSEventListener.cpp @@ -81,12 +81,13 @@ nsJSEventListener::nsJSEventListener(nsIScriptContext *aContext, // until we are done with it. NS_ASSERTION(aScopeObject && aContext, "EventListener with no context or scope?"); - aContext->HoldScriptObject(aScopeObject); + NS_HOLD_JS_OBJECTS(this, nsJSEventListener); } nsJSEventListener::~nsJSEventListener() { - mContext->DropScriptObject(mScopeObject); + if (mContext) + NS_DROP_JS_OBJECTS(this, nsJSEventListener); } NS_IMPL_CYCLE_COLLECTION_CLASS(nsJSEventListener) @@ -96,9 +97,14 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsJSEventListener) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTarget) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mContext) - cb.NoteScriptChild(nsIProgrammingLanguage::JAVASCRIPT, tmp->mScopeObject); + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END +NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsJSEventListener) + NS_IMPL_CYCLE_COLLECTION_TRACE_MEMBER_CALLBACK(tmp->mContext->GetScriptTypeID(), + mScopeObject) +NS_IMPL_CYCLE_COLLECTION_TRACE_END + NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsJSEventListener) NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener) NS_INTERFACE_MAP_ENTRY(nsIJSEventListener) diff --git a/dom/src/events/nsJSEventListener.h b/dom/src/events/nsJSEventListener.h index 542d113d8384..d7de952c1803 100644 --- a/dom/src/events/nsJSEventListener.h +++ b/dom/src/events/nsJSEventListener.h @@ -65,8 +65,8 @@ public: // nsIJSEventListener interface virtual void SetEventName(nsIAtom* aName); - NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsJSEventListener, - nsIDOMEventListener) + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsJSEventListener, + nsIDOMEventListener) protected: nsCOMPtr mEventName; diff --git a/dom/tests/mochitest/bugs/Makefile.in b/dom/tests/mochitest/bugs/Makefile.in index ae72002a600e..5f1c7e889128 100644 --- a/dom/tests/mochitest/bugs/Makefile.in +++ b/dom/tests/mochitest/bugs/Makefile.in @@ -56,6 +56,7 @@ _TEST_FILES = \ test_bug370098.html \ test_bug377539.html \ test_bug384122.html \ + test_bug389366.html \ test_bug393974.html \ test_bug396843.html \ $(NULL) diff --git a/dom/tests/mochitest/bugs/test_bug389366.html b/dom/tests/mochitest/bugs/test_bug389366.html new file mode 100644 index 000000000000..ddbbd0dca879 --- /dev/null +++ b/dom/tests/mochitest/bugs/test_bug389366.html @@ -0,0 +1,95 @@ + + + + + Test for Bug 389366 + + + + + +Mozilla Bug 389366 +

    + +
    +
    +
    + + diff --git a/editor/ui/composer/content/editor.js b/editor/ui/composer/content/editor.js index 590332ab8d96..0ae4d7ab9da5 100644 --- a/editor/ui/composer/content/editor.js +++ b/editor/ui/composer/content/editor.js @@ -2476,14 +2476,10 @@ function EditorSetDefaultPrefsAndDoctype() catch (ex) {} if ( prefCharsetString && prefCharsetString != 0) { - element = domdoc.createElement("meta"); - if ( element ) - { - element.setAttribute("http-equiv", "content-type"); - element.setAttribute("content", "text/html; charset=" + prefCharsetString); - headelement.insertBefore( element, headelement.firstChild ); - editor.documentCharacterSet = prefCharsetString; - } + editor.enableUndo(false); + editor.documentCharacterSet = prefCharsetString; + editor.resetModificationCount(); + editor.enableUndo(true); } var node = 0; diff --git a/embedding/components/windowwatcher/src/nsPrompt.cpp b/embedding/components/windowwatcher/src/nsPrompt.cpp index 8f632132914a..111202b5a816 100644 --- a/embedding/components/windowwatcher/src/nsPrompt.cpp +++ b/embedding/components/windowwatcher/src/nsPrompt.cpp @@ -128,16 +128,19 @@ NS_NewAuthPrompter(nsIAuthPrompt **result, nsIDOMWindow *aParent) nsresult NS_NewAuthPrompter2(nsIAuthPrompt2 **result, nsIDOMWindow *aParent) { + nsresult rv; + nsCOMPtr factory = do_GetService(NS_PWMGR_AUTHPROMPTFACTORY); if (factory) { // We just delegate everything to the pw mgr. - return factory->GetPrompt(aParent, + rv = factory->GetPrompt(aParent, NS_GET_IID(nsIAuthPrompt2), reinterpret_cast(result)); + if (NS_SUCCEEDED(rv)) + return rv; } - nsresult rv; *result = 0; nsPrompt *prompter = new nsPrompt(aParent); diff --git a/extensions/canvas3d/install.rdf b/extensions/canvas3d/install.rdf index f0efb8325558..7eaacc96cedd 100644 --- a/extensions/canvas3d/install.rdf +++ b/extensions/canvas3d/install.rdf @@ -4,7 +4,7 @@ xmlns:em="http://www.mozilla.org/2004/em-rdf#"> canvas3d@mozilla.com - 0.1 + 0.1.18 2 @@ -17,7 +17,7 @@ to internal interfaces. --> 3.0a8pre - 3.0a8pre + 3.0 diff --git a/extensions/canvas3d/src/Makefile.in b/extensions/canvas3d/src/Makefile.in index 5e951954119a..f69e70aad14c 100644 --- a/extensions/canvas3d/src/Makefile.in +++ b/extensions/canvas3d/src/Makefile.in @@ -54,6 +54,8 @@ MODULE_NAME = nsCanvas3DModule GRE_MODULE = 1 BUILD_STATIC_LIBS = +USE_STATIC_LIBS = 1 + REQUIRES = \ xpcom \ string \ diff --git a/extensions/canvas3d/src/glew.c b/extensions/canvas3d/src/glew.c index af49fef0c127..05a12fe9419d 100644 --- a/extensions/canvas3d/src/glew.c +++ b/extensions/canvas3d/src/glew.c @@ -4858,6 +4858,30 @@ GLenum glewContextInit (GLEW_CONTEXT_ARG_DEF_LIST) #ifdef GL_VERSION_2_0 if (glewExperimental || GLEW_VERSION_2_0) GLEW_VERSION_2_0 = !_glewInit_GL_VERSION_2_0(GLEW_CONTEXT_ARG_VAR_INIT); #endif /* GL_VERSION_2_0 */ + +/* Canvas3D Extensions */ +#ifdef GL_ARB_multitexture + GLEW_ARB_multitexture = glewGetExtension("GL_ARB_multitexture"); + if (glewExperimental || GLEW_ARB_multitexture) GLEW_ARB_multitexture = !_glewInit_GL_ARB_multitexture(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_multitexture */ +#ifdef GL_ARB_point_parameters + GLEW_ARB_point_parameters = glewGetExtension("GL_ARB_point_parameters"); + if (glewExperimental || GLEW_ARB_point_parameters) GLEW_ARB_point_parameters = !_glewInit_GL_ARB_point_parameters(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_ARB_point_parameters */ +#ifdef GL_ARB_texture_rectangle + GLEW_ARB_texture_rectangle = glewGetExtension("GL_ARB_texture_rectangle"); +#endif /* GL_ARB_texture_rectangle */ +#ifdef GL_EXT_texture_filter_anisotropic + GLEW_EXT_texture_filter_anisotropic = glewGetExtension("GL_EXT_texture_filter_anisotropic"); +#endif /* GL_EXT_texture_filter_anisotropic */ + +/* unused extensions */ +#if 0 + +#ifdef GL_EXT_point_parameters + GLEW_EXT_point_parameters = glewGetExtension("GL_EXT_point_parameters"); + if (glewExperimental || GLEW_EXT_point_parameters) GLEW_EXT_point_parameters = !_glewInit_GL_EXT_point_parameters(GLEW_CONTEXT_ARG_VAR_INIT); +#endif /* GL_EXT_point_parameters */ #ifdef GL_3DFX_multisample GLEW_3DFX_multisample = glewGetExtension("GL_3DFX_multisample"); #endif /* GL_3DFX_multisample */ @@ -4941,10 +4965,6 @@ GLenum glewContextInit (GLEW_CONTEXT_ARG_DEF_LIST) GLEW_ARB_multisample = glewGetExtension("GL_ARB_multisample"); if (glewExperimental || GLEW_ARB_multisample) GLEW_ARB_multisample = !_glewInit_GL_ARB_multisample(GLEW_CONTEXT_ARG_VAR_INIT); #endif /* GL_ARB_multisample */ -#ifdef GL_ARB_multitexture - GLEW_ARB_multitexture = glewGetExtension("GL_ARB_multitexture"); - if (glewExperimental || GLEW_ARB_multitexture) GLEW_ARB_multitexture = !_glewInit_GL_ARB_multitexture(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ARB_multitexture */ #ifdef GL_ARB_occlusion_query GLEW_ARB_occlusion_query = glewGetExtension("GL_ARB_occlusion_query"); if (glewExperimental || GLEW_ARB_occlusion_query) GLEW_ARB_occlusion_query = !_glewInit_GL_ARB_occlusion_query(GLEW_CONTEXT_ARG_VAR_INIT); @@ -4952,10 +4972,6 @@ GLenum glewContextInit (GLEW_CONTEXT_ARG_DEF_LIST) #ifdef GL_ARB_pixel_buffer_object GLEW_ARB_pixel_buffer_object = glewGetExtension("GL_ARB_pixel_buffer_object"); #endif /* GL_ARB_pixel_buffer_object */ -#ifdef GL_ARB_point_parameters - GLEW_ARB_point_parameters = glewGetExtension("GL_ARB_point_parameters"); - if (glewExperimental || GLEW_ARB_point_parameters) GLEW_ARB_point_parameters = !_glewInit_GL_ARB_point_parameters(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_ARB_point_parameters */ #ifdef GL_ARB_point_sprite GLEW_ARB_point_sprite = glewGetExtension("GL_ARB_point_sprite"); #endif /* GL_ARB_point_sprite */ @@ -5003,9 +5019,6 @@ GLenum glewContextInit (GLEW_CONTEXT_ARG_DEF_LIST) #ifdef GL_ARB_texture_non_power_of_two GLEW_ARB_texture_non_power_of_two = glewGetExtension("GL_ARB_texture_non_power_of_two"); #endif /* GL_ARB_texture_non_power_of_two */ -#ifdef GL_ARB_texture_rectangle - GLEW_ARB_texture_rectangle = glewGetExtension("GL_ARB_texture_rectangle"); -#endif /* GL_ARB_texture_rectangle */ #ifdef GL_ARB_transpose_matrix GLEW_ARB_transpose_matrix = glewGetExtension("GL_ARB_transpose_matrix"); if (glewExperimental || GLEW_ARB_transpose_matrix) GLEW_ARB_transpose_matrix = !_glewInit_GL_ARB_transpose_matrix(GLEW_CONTEXT_ARG_VAR_INIT); @@ -5242,10 +5255,6 @@ GLenum glewContextInit (GLEW_CONTEXT_ARG_DEF_LIST) #ifdef GL_EXT_pixel_transform_color_table GLEW_EXT_pixel_transform_color_table = glewGetExtension("GL_EXT_pixel_transform_color_table"); #endif /* GL_EXT_pixel_transform_color_table */ -#ifdef GL_EXT_point_parameters - GLEW_EXT_point_parameters = glewGetExtension("GL_EXT_point_parameters"); - if (glewExperimental || GLEW_EXT_point_parameters) GLEW_EXT_point_parameters = !_glewInit_GL_EXT_point_parameters(GLEW_CONTEXT_ARG_VAR_INIT); -#endif /* GL_EXT_point_parameters */ #ifdef GL_EXT_polygon_offset GLEW_EXT_polygon_offset = glewGetExtension("GL_EXT_polygon_offset"); if (glewExperimental || GLEW_EXT_polygon_offset) GLEW_EXT_polygon_offset = !_glewInit_GL_EXT_polygon_offset(GLEW_CONTEXT_ARG_VAR_INIT); @@ -5315,9 +5324,6 @@ GLenum glewContextInit (GLEW_CONTEXT_ARG_DEF_LIST) #ifdef GL_EXT_texture_env_dot3 GLEW_EXT_texture_env_dot3 = glewGetExtension("GL_EXT_texture_env_dot3"); #endif /* GL_EXT_texture_env_dot3 */ -#ifdef GL_EXT_texture_filter_anisotropic - GLEW_EXT_texture_filter_anisotropic = glewGetExtension("GL_EXT_texture_filter_anisotropic"); -#endif /* GL_EXT_texture_filter_anisotropic */ #ifdef GL_EXT_texture_lod_bias GLEW_EXT_texture_lod_bias = glewGetExtension("GL_EXT_texture_lod_bias"); #endif /* GL_EXT_texture_lod_bias */ @@ -5760,6 +5766,8 @@ GLenum glewContextInit (GLEW_CONTEXT_ARG_DEF_LIST) if (glewExperimental || GLEW_WIN_swap_hint) GLEW_WIN_swap_hint = !_glewInit_GL_WIN_swap_hint(GLEW_CONTEXT_ARG_VAR_INIT); #endif /* GL_WIN_swap_hint */ +#endif /* #if 0'd unused extensions */ + return GLEW_OK; } diff --git a/extensions/canvas3d/src/nsCanvasRenderingContextGL.cpp b/extensions/canvas3d/src/nsCanvasRenderingContextGL.cpp index fd56122dd7e4..1c7740fbadcf 100644 --- a/extensions/canvas3d/src/nsCanvasRenderingContextGL.cpp +++ b/extensions/canvas3d/src/nsCanvasRenderingContextGL.cpp @@ -437,6 +437,15 @@ JSArrayToSimpleBuffer (SimpleBuffer& sbuffer, ::JS_ValueToECMAUint32(ctx, jv, &iv); *ptr++ = (unsigned char) iv; } + } else if (typeParam == GL_UNSIGNED_SHORT) { + PRUint16 *ptr = (PRUint16*) sbuffer.data; + for (PRUint32 i = 0; i < arrayLen; i++) { + jsval jv; + uint32 iv; + ::JS_GetElement(ctx, arrayObj, i, &jv); + ::JS_ValueToECMAUint32(ctx, jv, &iv); + *ptr++ = (unsigned short) iv; + } } else if (typeParam == GL_UNSIGNED_INT) { PRUint32 *ptr = (PRUint32*) sbuffer.data; for (PRUint32 i = 0; i < arrayLen; i++) { @@ -474,14 +483,45 @@ nsCanvasRenderingContextGLPrivate::LostCurrentContext(void *closure) NS_IMETHODIMP nsCanvasRenderingContextGLPrivate::SetCanvasElement(nsICanvasElement* aParentCanvas) { + nsresult rv; + + if (aParentCanvas == nsnull) { + // we get this on shutdown; we should do some more cleanup here, + // but instead we just let our destructor do it. + return NS_OK; + } + + LogMessage(NS_LITERAL_CSTRING("Canvas 3D: hello?")); + if (!SafeToCreateCanvas3DContext()) return NS_ERROR_FAILURE; + LogMessage(NS_LITERAL_CSTRING("Canvas 3D: is anyone there?")); + mGLPbuffer = new nsGLPbuffer(); if (!mGLPbuffer->Init(this)) return NS_ERROR_FAILURE; + LogMessage(NS_LITERAL_CSTRING("Canvas 3D: it's dark in here.")); + + // Let's find our prefs + nsCOMPtr prefService = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + + mPrefWireframe = PR_FALSE; + + nsCOMPtr prefBranch; + rv = prefService->GetBranch("extensions.canvas3d.", getter_AddRefs(prefBranch)); + if (NS_SUCCEEDED(rv)) { + PRBool val; + rv = prefBranch->GetBoolPref("wireframe", &val); + if (NS_SUCCEEDED(rv)) + mPrefWireframe = val; + } + + fprintf (stderr, "Wireframe: %d\n", mPrefWireframe); + if (!ValidateGL()) { // XXX over here we need to destroy mGLPbuffer and create a mesa buffer @@ -499,6 +539,8 @@ nsCanvasRenderingContextGLPrivate::SetDimensions(PRInt32 width, PRInt32 height) { fprintf (stderr, "VVVV CanvasGLBuffer::SetDimensions %d %d\n", width, height); + LogMessage(NS_LITERAL_CSTRING("Canvas 3D: look! there's a light!")); + if (mWidth == width && mHeight == height) return NS_OK; @@ -507,6 +549,8 @@ nsCanvasRenderingContextGLPrivate::SetDimensions(PRInt32 width, PRInt32 height) return NS_ERROR_FAILURE; } + LogMessage(NS_LITERAL_CSTRING("Canvas 3D: maybe that's the way out.")); + mWidth = width; mHeight = height; @@ -525,7 +569,11 @@ nsCanvasRenderingContextGLPrivate::Render(gfxContext *ctx) return NS_OK; nsRefPtr surf = mGLPbuffer->ThebesSurface(); - nsRefPtr pat = new gfxPattern(surf); + nsRefPtr pat = CanvasGLThebes::CreatePattern(surf); + gfxMatrix m; + m.Translate(gfxPoint(0.0, mGLPbuffer->Height())); + m.Scale(1.0, -1.0); + pat->SetMatrix(m); // XXX I don't want to use PixelSnapped here, but layout doesn't guarantee // pixel alignment for this stuff! @@ -569,6 +617,11 @@ nsCanvasRenderingContextGLPrivate::CairoSurfaceFromElement(nsIDOMElement *imgElt // XXX ERRMSG we need to report an error to developers here! (bug 329026) return NS_ERROR_NOT_AVAILABLE; + PRUint32 status; + imgRequest->GetImageStatus(&status); + if ((status & imgIRequest::STATUS_LOAD_COMPLETE) == 0) + return NS_ERROR_NOT_AVAILABLE; + nsCOMPtr uri; rv = imageLoader->GetCurrentURI(uriOut); NS_ENSURE_SUCCESS(rv, rv); @@ -586,8 +639,8 @@ nsCanvasRenderingContextGLPrivate::CairoSurfaceFromElement(nsIDOMElement *imgElt NS_ENSURE_SUCCESS(rv, rv); nsRefPtr surf = - new gfxImageSurface (gfxIntSize(w, h), gfxASurface::ImageFormatARGB32); - nsRefPtr ctx = new gfxContext(surf); + CanvasGLThebes::CreateImageSurface(gfxIntSize(w, h), gfxASurface::ImageFormatARGB32); + nsRefPtr ctx = CanvasGLThebes::CreateContext(surf); ctx->SetOperator(gfxContext::OPERATOR_CLEAR); ctx->Paint(); ctx->SetOperator(gfxContext::OPERATOR_OVER); @@ -723,6 +776,8 @@ nsCanvasRenderingContextGLPrivate::nsCanvasRenderingContextGLPrivate() } else { NS_ADDREF(gJSRuntimeService); } + + LogMessage(NS_LITERAL_CSTRING("Canvas 3D: where am I?")); } nsCanvasRenderingContextGLPrivate::~nsCanvasRenderingContextGLPrivate() @@ -790,6 +845,28 @@ nsCanvasRenderingContextGLPrivate::SafeToCreateCanvas3DContext() return PR_FALSE; } +gfxImageSurface * +CanvasGLThebes::CreateImageSurface (const gfxIntSize &isize, + gfxASurface::gfxImageFormat fmt) +{ + /*void *p = NS_Alloc(sizeof(gfxImageSurface));*/ + return new /*(p)*/ gfxImageSurface (isize, fmt); +} + +gfxContext * +CanvasGLThebes::CreateContext (gfxASurface *surf) +{ + void *p = NS_Alloc(sizeof(gfxContext)); + return new (p) gfxContext (surf); +} + +gfxPattern * +CanvasGLThebes::CreatePattern (gfxASurface *surf) +{ + /*void *p = NS_Alloc(sizeof(gfxPattern));*/ + return new /*(p)*/ gfxPattern(surf); +} + /* * We need this here, because nsAString has a different type name based on whether it's * used internally or externally. BeginPrinting isn't ever called, but gfxImageSurface diff --git a/extensions/canvas3d/src/nsCanvasRenderingContextGL.h b/extensions/canvas3d/src/nsCanvasRenderingContextGL.h index 20b26e1fa229..ffa510976288 100644 --- a/extensions/canvas3d/src/nsCanvasRenderingContextGL.h +++ b/extensions/canvas3d/src/nsCanvasRenderingContextGL.h @@ -143,6 +143,8 @@ protected: PRInt32 mWidth, mHeight; nsICanvasElement* mCanvasElement; + PRPackedBool mPrefWireframe; + static inline PRBool JSValToFloatArray (JSContext *ctx, jsval val, jsuint cnt, float *array) { @@ -152,6 +154,7 @@ protected: jsdouble dv; if (!::JS_ValueToObject(ctx, val, &arrayObj) || + arrayObj == NULL || !::JS_IsArrayObject(ctx, arrayObj) || !::JS_GetArrayLength(ctx, arrayObj, &arrayLen) || (arrayLen < cnt)) @@ -176,6 +179,7 @@ protected: jsdouble dv; if (!::JS_ValueToObject(ctx, val, &arrayObj) || + arrayObj == NULL || !::JS_IsArrayObject(ctx, arrayObj) || !::JS_GetArrayLength(ctx, arrayObj, &arrayLen) || (arrayLen < cnt)) @@ -197,6 +201,7 @@ protected: JSObject *obj = nsnull; jsuint len; if (!::JS_ValueToObject(ctx, val, &obj) || + obj == NULL || !::JS_IsArrayObject(ctx, obj) || !::JS_GetArrayLength(ctx, obj, &len)) { @@ -259,7 +264,8 @@ protected: void LogMessage (const nsCString& errorString) { nsCOMPtr console(do_GetService(NS_CONSOLESERVICE_CONTRACTID)); - console->LogStringMessage(NS_ConvertUTF8toUTF16(errorString).get()); + if (console) + console->LogStringMessage(NS_ConvertUTF8toUTF16(errorString).get()); } }; @@ -607,6 +613,16 @@ protected: GLuint mBufferID; }; +class CanvasGLThebes { +public: + static gfxImageSurface *CreateImageSurface (const gfxIntSize &isize, + gfxASurface::gfxImageFormat fmt); + + static gfxContext *CreateContext (gfxASurface *surf); + + static gfxPattern *CreatePattern (gfxASurface *surf); +}; + /* Helper macros for when we're just wrapping a gl method, so that * we can avoid having to type this 500 times. Note that these MUST * NOT BE USED if we need to check any of the parameters. diff --git a/extensions/canvas3d/src/nsCanvasRenderingContextGLES11.cpp b/extensions/canvas3d/src/nsCanvasRenderingContextGLES11.cpp index 91e3ef25cca8..0fcd58f9d73b 100644 --- a/extensions/canvas3d/src/nsCanvasRenderingContextGLES11.cpp +++ b/extensions/canvas3d/src/nsCanvasRenderingContextGLES11.cpp @@ -1147,10 +1147,11 @@ nsCanvasRenderingContextGLES11::TexImage2DHTML(PRUint32 target, nsIDOMHTMLElemen } if (!image_data) { - nsRefPtr tmpImageSurface = new gfxImageSurface(gfxIntSize(width, height), - gfxASurface::ImageFormatARGB32); - - nsRefPtr cx = new gfxContext(tmpImageSurface); + nsRefPtr tmpImageSurface = + CanvasGLThebes::CreateImageSurface(gfxIntSize(width, height), + gfxASurface::ImageFormatARGB32); + nsRefPtr cx = + CanvasGLThebes::CreateContext(tmpImageSurface); cx->SetSource(surf); cx->SetOperator(gfxContext::OPERATOR_SOURCE); cx->Paint(); @@ -1872,6 +1873,7 @@ nsCanvasRenderingContextGLES11::BufferData() jsuint type; jsuint usage; if (!::JS_ConvertArguments(js.ctx, js.argc, js.argv, "uouu", &target, &arrayObj, &type, &usage) || + arrayObj == NULL || !::JS_IsArrayObject(js.ctx, arrayObj) || !::JS_GetArrayLength(js.ctx, arrayObj, &arrayLen)) { @@ -1905,6 +1907,7 @@ nsCanvasRenderingContextGLES11::BufferSubData() jsuint offset; jsuint type; if (!::JS_ConvertArguments(js.ctx, js.argc, js.argv, "uuou", &target, &offset, &arrayObj, &type) || + arrayObj == NULL || !::JS_IsArrayObject(js.ctx, arrayObj) || !::JS_GetArrayLength(js.ctx, arrayObj, &arrayLen)) { diff --git a/extensions/canvas3d/src/nsCanvasRenderingContextGLWeb20.cpp b/extensions/canvas3d/src/nsCanvasRenderingContextGLWeb20.cpp index fd80dec0c0df..7de15bde4897 100644 --- a/extensions/canvas3d/src/nsCanvasRenderingContextGLWeb20.cpp +++ b/extensions/canvas3d/src/nsCanvasRenderingContextGLWeb20.cpp @@ -41,6 +41,8 @@ #include "nsIRenderingContext.h" +#include "nsTArray.h" + #define NSGL_CONTEXT_NAME nsCanvasRenderingContextGLWeb20 #include "nsCanvasRenderingContextGL.h" @@ -114,6 +116,9 @@ public: // nsICanvasRenderingContextPrivate virtual nsICanvasRenderingContextGL *GetSelf() { return this; } virtual PRBool ValidateGL(); + +protected: + nsTArray > mAttribBuffers; }; @@ -215,6 +220,7 @@ nsCanvasRenderingContextGLWeb20::BufferData() jsuint type; jsuint usage; if (!::JS_ConvertArguments(js.ctx, js.argc, js.argv, "uouu", &target, &arrayObj, &type, &usage) || + arrayObj == NULL || !::JS_IsArrayObject(js.ctx, arrayObj) || !::JS_GetArrayLength(js.ctx, arrayObj, &arrayLen)) { @@ -248,6 +254,7 @@ nsCanvasRenderingContextGLWeb20::BufferSubData() jsuint offset; jsuint type; if (!::JS_ConvertArguments(js.ctx, js.argc, js.argv, "uuou", &target, &offset, &arrayObj, &type) || + arrayObj == NULL || !::JS_IsArrayObject(js.ctx, arrayObj) || !::JS_GetArrayLength(js.ctx, arrayObj, &arrayLen)) { @@ -372,7 +379,34 @@ GL_SAME_METHOD_3(DrawArrays, DrawArrays, PRUint32, PRUint32, PRUint32) NS_IMETHODIMP nsCanvasRenderingContextGLWeb20::DrawElements() { - return NS_ERROR_NOT_IMPLEMENTED; + NativeJSContext js; + if (NS_FAILED(js.error)) + return js.error; + + if (js.argc != 3) + return NS_ERROR_DOM_SYNTAX_ERR; + + JSObject *arrayObj; + jsuint arrayLen; + jsuint mode; + jsuint count; + if (!::JS_ConvertArguments(js.ctx, js.argc, js.argv, "uuo", &mode, &count, &arrayObj) || + arrayObj == NULL || + !::JS_IsArrayObject(js.ctx, arrayObj) || + !::JS_GetArrayLength(js.ctx, arrayObj, &arrayLen)) + { + return NS_ERROR_DOM_SYNTAX_ERR; + } + + SimpleBuffer sbuffer; + nsresult rv = JSArrayToSimpleBuffer(sbuffer, GL_UNSIGNED_SHORT, 1, js.ctx, arrayObj, arrayLen); + if (NS_FAILED(rv)) + return rv; + + MakeContextCurrent(); + glDrawElements(mode, count, GL_UNSIGNED_SHORT, sbuffer.data); + + return NS_OK; } GL_SAME_METHOD_1(Enable, Enable, PRUint32) @@ -1027,10 +1061,11 @@ nsCanvasRenderingContextGLWeb20::TexImage2DHTML(PRUint32 target, nsIDOMHTMLEleme } if (!image_data) { - nsRefPtr tmpImageSurface = new gfxImageSurface(gfxIntSize(width, height), - gfxASurface::ImageFormatARGB32); - - nsRefPtr cx = new gfxContext(tmpImageSurface); + nsRefPtr tmpImageSurface = + CanvasGLThebes::CreateImageSurface(gfxIntSize(width, height), + gfxASurface::ImageFormatARGB32); + nsRefPtr cx = + CanvasGLThebes::CreateContext(tmpImageSurface); cx->SetSource(surf); cx->SetOperator(gfxContext::OPERATOR_SOURCE); cx->Paint(); @@ -1401,6 +1436,12 @@ nsCanvasRenderingContextGLWeb20::VertexAttribPointer() return NS_ERROR_DOM_SYNTAX_ERR; } + // if it's out of bounds, bail + if (vertexAttribIndex >= mAttribBuffers.Length()) + return NS_ERROR_DOM_SYNTAX_ERR; + + mAttribBuffers[vertexAttribIndex] = newBuffer; + MakeContextCurrent(); glVertexAttribPointer(vertexAttribIndex, newBuffer->GetSimpleBuffer().sizePerVertex, @@ -1418,5 +1459,13 @@ nsCanvasRenderingContextGLWeb20::ValidateGL() if (!GLEW_VERSION_2_0) return PR_FALSE; + GLint val; + glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &val); + mAttribBuffers.SetLength(val); + + MakeContextCurrent(); + if (mPrefWireframe) + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + return PR_TRUE; } diff --git a/extensions/canvas3d/src/nsGLPbuffer.cpp b/extensions/canvas3d/src/nsGLPbuffer.cpp index a201be5bae56..efcda8f0b6ab 100644 --- a/extensions/canvas3d/src/nsGLPbuffer.cpp +++ b/extensions/canvas3d/src/nsGLPbuffer.cpp @@ -46,13 +46,17 @@ void *nsGLPbuffer::sCurrentContextToken = nsnull; +static PRUint32 gActiveBuffers = 0; + nsGLPbuffer::nsGLPbuffer() : mWidth(0), mHeight(0), #ifdef XP_WIN mGlewWindow(nsnull), mGlewDC(nsnull), mGlewWglContext(nsnull), - mPbufferDC(nsnull), mPbufferContext(nsnull) + mPbuffer(nsnull), mPbufferDC(nsnull), mPbufferContext(nsnull) #endif { + gActiveBuffers++; + fprintf (stderr, "nsGLPbuffer: gActiveBuffers: %d\n", gActiveBuffers); } PRBool @@ -116,11 +120,15 @@ nsGLPbuffer::Init(nsCanvasRenderingContextGLPrivate *priv) return PR_FALSE; } + PRInt64 t1 = PR_Now(); + if (wglewInit() != GLEW_OK) { mPriv->LogMessage(NS_LITERAL_CSTRING("Canvas 3D: WGLEW init failed")); return PR_FALSE; } + PRInt64 t2 = PR_Now(); + fprintf (stderr, "nsGLPbuffer::Init!\n"); #else return PR_FALSE; @@ -131,6 +139,12 @@ nsGLPbuffer::Init(nsCanvasRenderingContextGLPrivate *priv) return PR_FALSE; } + PRInt64 t3 = PR_Now(); + + fprintf (stderr, "nsGLPbuffer:: Initialization took t2-t1: %f t3-t2: %f\n", + ((double)(t2-t1))/1000.0, ((double)(t3-t2))/1000.0); + fflush (stderr); + return PR_TRUE; } @@ -145,6 +159,17 @@ nsGLPbuffer::Resize(PRInt32 width, PRInt32 height) Destroy(); + mThebesSurface = CanvasGLThebes::CreateImageSurface(gfxIntSize(width, height), gfxASurface::ImageFormatARGB32); + if (mThebesSurface->CairoStatus() != 0) { + fprintf (stderr, "image surface failed\n"); + return PR_FALSE; + } + + // clear the surface + memset (mThebesSurface->Data(), + 0, + height * mThebesSurface->Stride()); + #ifdef XP_WIN if (!wglMakeCurrent(mGlewDC, mGlewWglContext)) { fprintf (stderr, "Error: %d\n", GetLastError()); @@ -257,21 +282,6 @@ nsGLPbuffer::Resize(PRInt32 width, PRInt32 height) mPbufferDC = wglGetPbufferDCARB(mPbuffer); mPbufferContext = wglCreateContext(mPbufferDC); - - mThebesSurface = new gfxImageSurface(gfxIntSize(width, height), gfxASurface::ImageFormatARGB32); -#if 0 - if (mThebesSurface->Status() != 0) { - fprintf (stderr, "image surface failed\n"); - return PR_FALSE; - } -#endif - - { - nsRefPtr ctx = new gfxContext(mThebesSurface); - ctx->SetColor(gfxRGBA(0, 1, 0, 1)); - ctx->Paint(); - } - #endif mWidth = width; @@ -304,6 +314,10 @@ nsGLPbuffer::~nsGLPbuffer() mGlewWindow = nsnull; } #endif + + gActiveBuffers--; + fprintf (stderr, "nsGLPbuffer: gActiveBuffers: %d\n", gActiveBuffers); + fflush (stderr); } void diff --git a/extensions/canvas3d/src/nsGLPbuffer.h b/extensions/canvas3d/src/nsGLPbuffer.h index 949371ddafec..e00c544078b6 100644 --- a/extensions/canvas3d/src/nsGLPbuffer.h +++ b/extensions/canvas3d/src/nsGLPbuffer.h @@ -76,6 +76,9 @@ public: } #endif + PRInt32 Width() { return mWidth; } + PRInt32 Height() { return mHeight; } + protected: static void *sCurrentContextToken; diff --git a/extensions/pref/autoconfig/src/nsReadConfig.cpp b/extensions/pref/autoconfig/src/nsReadConfig.cpp index f4ee045af884..9da42798ae0d 100644 --- a/extensions/pref/autoconfig/src/nsReadConfig.cpp +++ b/extensions/pref/autoconfig/src/nsReadConfig.cpp @@ -216,7 +216,7 @@ nsresult nsReadConfig::readConfigFile() PRInt32 obscureValue = 0; (void) defaultPrefBranch->GetIntPref("general.config.obscure_value", &obscureValue); PR_LOG(MCD, PR_LOG_DEBUG, ("evaluating .cfg file %s with obscureValue %d\n", lockFileName.get(), obscureValue)); - rv = openAndEvaluateJSFile(lockFileName.get(), PR_TRUE, obscureValue, PR_TRUE); + rv = openAndEvaluateJSFile(lockFileName.get(), obscureValue, PR_TRUE, PR_TRUE); if (NS_FAILED(rv)) { PR_LOG(MCD, PR_LOG_DEBUG, ("error evaluating .cfg file %s %x\n", lockFileName.get(), rv)); @@ -267,8 +267,8 @@ nsresult nsReadConfig::readConfigFile() } // ReadConfigFile -nsresult nsReadConfig::openAndEvaluateJSFile(const char *aFileName, PRBool isEncoded, - PRInt32 obscureValue, +nsresult nsReadConfig::openAndEvaluateJSFile(const char *aFileName, PRInt32 obscureValue, + PRBool isEncoded, PRBool isBinDir) { nsresult rv; diff --git a/extensions/reporter/locales/en-US/chrome/reportWizard.properties b/extensions/reporter/locales/en-US/chrome/reportWizard.properties index e7c793be0df4..afc2eb5f0ac3 100644 --- a/extensions/reporter/locales/en-US/chrome/reportWizard.properties +++ b/extensions/reporter/locales/en-US/chrome/reportWizard.properties @@ -8,3 +8,5 @@ finishError=Error Sending Report successfullyCreatedReport=Successfully Transmitted Report failedCreatingReport=There was an error creating the report, and so no information was sent to mozilla.org +defaultError=Unable to make a successful connection to the server. +invalidResponse=An invalid response was received from the server. Please try again later. diff --git a/extensions/reporter/resources/content/prefs/reporter.js b/extensions/reporter/resources/content/prefs/reporter.js index 0e333d726deb..f11a0de6fa54 100644 --- a/extensions/reporter/resources/content/prefs/reporter.js +++ b/extensions/reporter/resources/content/prefs/reporter.js @@ -1,4 +1,3 @@ -// Make sure there are trailing slashes! -pref("extensions.reporter.privacyURL", "http://reporter.mozilla.org/privacy/"); -pref("extensions.reporter.serviceURL", "http://reporter.mozilla.org/service/"); - +// Make sure there are trailing slashes! +pref("extensions.reporter.privacyURL", "http://reporter.mozilla.org/privacy/"); +pref("extensions.reporter.serviceURL", "http://reporter.mozilla.org/service/0.3/"); diff --git a/extensions/reporter/resources/content/reporter/reportWizard.js b/extensions/reporter/resources/content/reporter/reportWizard.js index 3ff80f1640ce..388bd7162cfe 100644 --- a/extensions/reporter/resources/content/reporter/reportWizard.js +++ b/extensions/reporter/resources/content/reporter/reportWizard.js @@ -43,17 +43,23 @@ * or a reporter.mozilla.org Admin! *******************************************************/ -const gURL = window.arguments[0]; -const gLanguage = window.navigator.language; -const gRMOvers = "0.2"; // Do not touch without contacting reporter admin! +const gParamLanguage = window.navigator.language; +const gRMOvers = "0.3"; // Do not touch without contacting reporter admin! +const gParamURL = window.arguments[0]; +const gParamUserAgent = navigator.userAgent; +const gParamOSCPU = navigator.oscpu; +const gParamPlatform = navigator.platform; // Globals -var gReportID; -var gSysID; -var gFaultCode; -var gFaultMessage; -var gSOAPerror = false; +var gParamDescription; +var gParamProblemType; +var gParamBehindLogin; +var gParamEmail; +var gParamBuildConfig; +var gParamGecko; + var gPrefBranch; +var gStatusIndicator; function getReporterPrefBranch() { if (!gPrefBranch) { @@ -119,7 +125,7 @@ function initForm() { var reportWizard = document.getElementById('reportWizard'); reportWizard.canRewind = false; - document.getElementById('url').value = gURL; + document.getElementById('url').value = gParamURL; // Change next button to "submit report" reportWizard.getButton('next').label = strbundle.getString("submitReport"); @@ -144,31 +150,51 @@ function validateForm() { document.getElementById('reportWizard').canAdvance = canAdvance; } -function registerSysID(){ - var param = new Array();; - param[0] = new SOAPParameter(gLanguage, "language"); +function registerSysID() { + var param = { + 'method': 'submitRegister', + 'language': gParamLanguage + }; - // get sysID - callReporter("register", param, setValSysID); + // go get sysID + sendReporterServerData(param, onRegisterSysIDLoad); +} - // saving - if (gSysID != undefined){ - var prefs = getReporterPrefBranch(); - prefs.setCharPref("sysid", gSysID); - return gSysID; +function onRegisterSysIDLoad(req) { + if (req.status == 200) { + var paramSysID = req.responseXML.getElementsByTagName('result').item(0); + + // saving + if (paramSysID) { + var prefs = getReporterPrefBranch(); + prefs.setCharPref("sysid", paramSysID.textContent); + + // Finally send report + sendReport(); + return; + } + + // Invalid Response Error + var strbundle = document.getElementById("strings"); + showError(strbundle.getString("invalidResponse")); + + return; } - return ""; + + // On error + var errorStr = extractError(req); + showError(errorStr); } -function getSysID() { - var sysId = getCharPref("sysid", ""); - if (sysId == "") - sysId = registerSysID(); - - return sysId; -} function sendReport() { + // Check for a sysid, if we don't have one, get one it will call sendReport on success. + var sysId = getCharPref("sysid", ""); + if (sysId == ""){ + registerSysID(); + return; + } + // we control the user path from here. var reportWizard = document.getElementById('reportWizard'); @@ -179,90 +205,158 @@ function sendReport() { var strbundle=document.getElementById("strings"); var statusDescription = document.getElementById('sendReportProgressDescription'); - var statusIndicator = document.getElementById('sendReportProgressIndicator'); + gStatusIndicator = document.getElementById('sendReportProgressIndicator'); // Data from form we need - var descriptionStri = document.getElementById('description').value; - var problemTypeStri = document.getElementById('problem_type').value; - var behindLoginStri = document.getElementById('behind_login').checked; - var emailStri = document.getElementById('email').value; + gParamDescription = document.getElementById('description').value; + gParamProblemType = document.getElementById('problem_type').value; + gParamBehindLogin = document.getElementById('behind_login').checked; + gParamEmail = document.getElementById('email').value; - var buildConfig = getBuildConfig(); - var userAgent = navigator.userAgent; + gParamBuildConfig = getBuildConfig(); + gParamGecko = getGecko(); // SOAP params - var param = new Array(); - param[0] = new SOAPParameter(gRMOvers, "rmoVers"); - param[1] = new SOAPParameter(gURL, "url"); - param[2] = new SOAPParameter(problemTypeStri, "problem_type"); - param[3] = new SOAPParameter(descriptionStri, "description"); - param[4] = new SOAPParameter(behindLoginStri, "behind_login"); - param[5] = new SOAPParameter(navigator.platform, "platform"); - param[6] = new SOAPParameter(navigator.oscpu, "oscpu"); - param[7] = new SOAPParameter(getGecko(), "gecko"); - param[8] = new SOAPParameter(getProduct(), "product"); - param[9] = new SOAPParameter(navigator.userAgent, "useragent"); - param[10] = new SOAPParameter(buildConfig, "buildconfig"); - param[11] = new SOAPParameter(gLanguage, "language"); - param[12] = new SOAPParameter(emailStri, "email"); - param[13] = new SOAPParameter(getSysID(), "sysid"); + var param = { + 'method': 'submitReport', + 'rmoVers': gRMOvers, + 'url': gParamURL, + 'problem_type': gParamProblemType, + 'description': gParamDescription, + 'behind_login': gParamBehindLogin, + 'platform': gParamPlatform, + 'oscpu': gParamOSCPU, + 'gecko': gParamGecko, + 'product': getProduct(), + 'useragent': gParamUserAgent, + 'buildconfig': gParamBuildConfig, + 'language': gParamLanguage, + 'email': gParamEmail, + 'sysid': sysId + }; - statusIndicator.setAttribute("value", "5%"); - statusDescription.setAttribute("value", strbundle.getString("sendingReport")); - callReporter("submitReport", param, setValReportID); + gStatusIndicator.value = "5%"; + statusDescription.value = strbundle.getString("sendingReport"); + + sendReporterServerData(param, onSendReportDataLoad); +} + +function onSendReportDataProgress(e) { + gStatusIndicator.value = (e.position / e.totalSize)*100; +} + +function sendReporterServerData(params, callback) { + var serviceURL = getCharPref("serviceURL", "http://reporter.mozilla.org/service/0.3/"); + + params = serializeParams(params); + + var request = new XMLHttpRequest(); + request.onprogress = onSendReportDataProgress; + request.open("POST", serviceURL, true); + + request.onreadystatechange = function () { + if (request.readyState == 4) + callback(request); + }; + + request.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); + request.setRequestHeader("Content-length", params.length); + request.setRequestHeader("Connection", "close"); + request.send(params); +} + +function serializeParams(params) { + var str = ''; + for (var key in params) { + str += key + '=' + encodeURIComponent(params[key]) + '&'; + } + return str.substr(0, str.length-1); +} + +function onSendReportDataLoad(req) { + if (req.status != 200) { + var errorStr = extractError(req); + showError(errorStr); + return; + } + + var reportWizard = document.getElementById('reportWizard'); var finishSummary = document.getElementById('finishSummary'); var finishExtendedFailed = document.getElementById('finishExtendedFailed'); var finishExtendedSuccess = document.getElementById('finishExtendedSuccess'); - if (!gSOAPerror) { - // If successful - finishExtendedFailed.setAttribute("class", "hide"); + var statusDescription = document.getElementById('sendReportProgressDescription'); - statusIndicator.setAttribute("value", "95%"); - statusDescription.setAttribute("value", strbundle.getString("reportSent")); + var strbundle = document.getElementById("strings"); - reportWizard.canAdvance = true; - statusIndicator.setAttribute("value", "100%"); + // If successful + finishExtendedFailed.hidden = true; - // Send to the finish page - reportWizard.advance(); + statusDescription.value = strbundle.getString("reportSent"); - // report ID returned from the web service - finishSummary.setAttribute("value", strbundle.getString("successfullyCreatedReport") + " " + gReportID); + reportWizard.canAdvance = true; + gStatusIndicator.value = "100%"; - finishExtendedDoc = finishExtendedSuccess.contentDocument; - finishExtendedDoc.getElementById('urlStri').textContent = gURL; - finishExtendedDoc.getElementById('problemTypeStri').textContent = document.getElementById('problem_type').label; - finishExtendedDoc.getElementById('descriptionStri').textContent = descriptionStri; - finishExtendedDoc.getElementById('platformStri').textContent = navigator.platform; - finishExtendedDoc.getElementById('oscpuStri').textContent = navigator.oscpu; - finishExtendedDoc.getElementById('productStri').textContent = getProduct(); - finishExtendedDoc.getElementById('geckoStri').textContent = getGecko(); - finishExtendedDoc.getElementById('buildConfigStri').textContent = buildConfig; - finishExtendedDoc.getElementById('userAgentStri').textContent = navigator.userAgent; - finishExtendedDoc.getElementById('langStri').textContent = gLanguage; - finishExtendedDoc.getElementById('emailStri').textContent = emailStri; + // Send to the finish page + reportWizard.advance(); - reportWizard.canRewind = false; + // report ID returned from the web service + var reportId = req.responseXML.getElementsByTagName('reportId').item(0).firstChild.data; + finishSummary.value = strbundle.getString("successfullyCreatedReport") + " " + reportId; - } else { - // If there was an error from the server - finishExtendedSuccess.setAttribute("class", "hide"); + finishExtendedDoc = finishExtendedSuccess.contentDocument; + finishExtendedDoc.getElementById('urlStri').textContent = gParamURL; + finishExtendedDoc.getElementById('problemTypeStri').textContent = document.getElementById('problem_type').label; + finishExtendedDoc.getElementById('descriptionStri').textContent = gParamDescription; + finishExtendedDoc.getElementById('platformStri').textContent = gParamPlatform; + finishExtendedDoc.getElementById('oscpuStri').textContent = gParamOSCPU; + finishExtendedDoc.getElementById('productStri').textContent = getProduct(); + finishExtendedDoc.getElementById('geckoStri').textContent = gParamGecko; + finishExtendedDoc.getElementById('buildConfigStri').textContent = gParamBuildConfig; + finishExtendedDoc.getElementById('userAgentStri').textContent = gParamUserAgent; + finishExtendedDoc.getElementById('langStri').textContent = gParamLanguage; + finishExtendedDoc.getElementById('emailStri').textContent = gParamEmail; - // Change the label on the page so users know we have an error - var finishPage = document.getElementById('finish'); - finishPage.setAttribute("label",strbundle.getString("finishError")); + reportWizard.canRewind = false; - reportWizard.canAdvance = true; - reportWizard.advance(); + document.getElementById('finishExtendedFrame').collapsed = true; + reportWizard.getButton("cancel").disabled = true; + return; +} - finishSummary.setAttribute("value",strbundle.getString("failedCreatingReport")); - - finishExtendedDoc = finishExtendedFailed.contentDocument; - //finishExtendedDoc.getElementById('faultCode').textContent = gFaultCode; - finishExtendedDoc.getElementById('faultMessage').textContent = gFaultMessage; +function extractError(req){ + var error = req.responseXML.getElementsByTagName('errorString').item(0) + if (error) { + return error.textContent; } + // Default error + var strbundle = document.getElementById("strings"); + return strbundle.getString("defaultError"); +} + +function showError(errorStr){ + var strbundle = document.getElementById("strings"); + var finishSummary = document.getElementById('finishSummary'); + var finishExtendedSuccess = document.getElementById('finishExtendedSuccess'); + var finishExtendedFailed = document.getElementById('finishExtendedFailed'); + + // If there was an error from the server + finishExtendedSuccess.hidden = true; + + // Change the label on the page so users know we have an error + var finishPage = document.getElementById('finish'); + finishPage.setAttribute("label",strbundle.getString("finishError")); + + var reportWizard = document.getElementById('reportWizard'); + reportWizard.canAdvance = true; + reportWizard.advance(); + + finishSummary.value = strbundle.getString("failedCreatingReport"); + + finishExtendedDoc = finishExtendedFailed.contentDocument; + finishExtendedDoc.getElementById('faultMessage').textContent = errorStr; + document.getElementById('finishExtendedFrame').collapsed = true; reportWizard.getButton("cancel").disabled = true; } @@ -305,51 +399,6 @@ function getBuildConfig() { } } -/* NEW WEB SERVICE MODULE */ -/* Based on Apple's example implementation of SOAP at: developer.apple.com/internet/webservices/mozgoogle_source.html */ -function callReporter(method, params, callback) { - var serviceURL = getCharPref("serviceURL", "http://reporter.mozilla.org/service/"); - - var soapCall = new SOAPCall(); - soapCall.transportURI = serviceURL; - soapCall.encode(0, method, "urn:MozillaReporter", 0, null, params.length, params); - - var response = soapCall.invoke(); - var error = handleSOAPResponse(response); - if (!error) - callback(response); -} - -function handleSOAPResponse (response) { - var fault = response.fault; - if (fault != null) { - gSOAPerror = true; - gFaultCode = fault.faultCode; - gFaultMessage = fault.faultString; - return true; - } - - return false; -} - -function setValSysID(results) { - if (results) { - var params = results.getParameters(false,{}); - for (var i = 0; i < params.length; i++){ - gSysID = params[i].value; - } - } -} - -function setValReportID(results) { - if (results) { - var params = results.getParameters(false,{}); - for (var i = 0; i < params.length; i++){ - gReportID = params[i].value; - } - } -} - function getProduct() { try { // Works on Firefox 1.0+ and Future SeaMonkey's diff --git a/extensions/reporter/resources/skin/classic/reporter/reportWizard.css b/extensions/reporter/resources/skin/classic/reporter/reportWizard.css index 1e43faf7c3d3..a009e41394e1 100644 --- a/extensions/reporter/resources/skin/classic/reporter/reportWizard.css +++ b/extensions/reporter/resources/skin/classic/reporter/reportWizard.css @@ -47,10 +47,6 @@ color: -moz-FieldText; } -.hide { - display: none; -} - wizard[description=""] .wizard-header-description { display: none; } diff --git a/gfx/cairo/README b/gfx/cairo/README index 6071d0947314..3dd7055a2bda 100644 --- a/gfx/cairo/README +++ b/gfx/cairo/README @@ -29,3 +29,4 @@ win32-glyph-metrics.patch: GetGlyphOutline only works on Truetype fonts, so for non-Truetype fonts, assume no left or right bearing and use the font ascent and descent for the glyph extents. +endian.patch: include cairo-platform.h for endian macros diff --git a/gfx/cairo/cairo/src/cairo-quartz-surface.c b/gfx/cairo/cairo/src/cairo-quartz-surface.c index 540bdca769af..8488f384a92d 100644 --- a/gfx/cairo/cairo/src/cairo-quartz-surface.c +++ b/gfx/cairo/cairo/src/cairo-quartz-surface.c @@ -39,6 +39,7 @@ #include "cairo-quartz-private.h" #include +#include #undef QUARTZ_DEBUG @@ -97,6 +98,26 @@ CG_EXTERN CGImageRef CGBitmapContextCreateImage (CGContextRef); static void quartz_surface_to_png (cairo_quartz_surface_t *nq, char *dest); static void quartz_image_to_png (CGImageRef, char *dest); +/* CoreGraphics limitation with flipped CTM surfaces: height must be less than signed 16-bit max */ + +#define CG_MAX_HEIGHT SHRT_MAX +#define CG_MAX_WIDTH USHRT_MAX + +/* is the desired size of the surface within bounds? */ +static cairo_bool_t verify_surface_size(int width, int height) +{ + /* hmmm, allow width, height == 0 ? */ + if (width < 0 || height < 0) { + return FALSE; + } + + if (width > CG_MAX_WIDTH || height > CG_MAX_HEIGHT) { + return FALSE; + } + + return TRUE; +} + /* * Cairo path -> Quartz path conversion helpers */ @@ -449,6 +470,13 @@ _cairo_quartz_surface_to_quartz (cairo_surface_t *target, cairo_surface_t *pat_s cairo_surface_destroy(ref_type); quartz_surf = (cairo_quartz_surface_t *) new_surf; + + if (new_surf && + cairo_surface_get_type (new_surf) != CAIRO_SURFACE_TYPE_QUARTZ) { + ND((stderr, "got a non-quartz surface, format=%d width=%u height=%u type=%d\n", cairo_surface_get_type (pat_surf), rect.width, rect.height, cairo_surface_get_type (new_surf))); + cairo_surface_destroy (new_surf); + quartz_surf = NULL; + } } else { /* If it's a quartz surface, we can try to see if it's a CGBitmapContext; * we do this when we call CGBitmapContextCreateImage below. @@ -469,6 +497,9 @@ SurfacePatternDrawFunc (void *info, CGContextRef context) cairo_surface_t *pat_surf = spat->surface; cairo_quartz_surface_t *quartz_surf = _cairo_quartz_surface_to_quartz (NULL, pat_surf); + if (!quartz_surf) + return; + CGImageRef img = CGBitmapContextCreateImage (quartz_surf->cgContext); CGRect imageBounds; @@ -673,6 +704,9 @@ _cairo_quartz_setup_source (cairo_quartz_surface_t *surface, cairo_surface_pattern_t *spat = (cairo_surface_pattern_t *) source; cairo_surface_t *pat_surf = spat->surface; cairo_quartz_surface_t *quartz_surf = _cairo_quartz_surface_to_quartz ((cairo_surface_t *) surface, pat_surf); + if (!quartz_surf) + return DO_UNSUPPORTED; + CGImageRef img = CGBitmapContextCreateImage (quartz_surf->cgContext); cairo_matrix_t m = spat->base.matrix; cairo_rectangle_int_t extents; @@ -981,6 +1015,12 @@ _cairo_quartz_surface_create_similar (void *abstract_surface, format = CAIRO_FORMAT_A8; else return NULL; + + // verify width and height of surface + if (!verify_surface_size(width, height)) { + _cairo_error (CAIRO_STATUS_NO_MEMORY); + return NULL; + } return cairo_quartz_surface_create (format, width, height); } @@ -996,6 +1036,13 @@ _cairo_quartz_surface_clone_similar (void *abstract_surface, { cairo_quartz_surface_t *new_surface = NULL; cairo_format_t new_format; + + *clone_out = NULL; + + // verify width and height of surface + if (!verify_surface_size(width, height)) { + return CAIRO_INT_STATUS_UNSUPPORTED; + } CGImageRef quartz_image = NULL; @@ -1032,6 +1079,7 @@ _cairo_quartz_surface_clone_similar (void *abstract_surface, new_format = isurf->format; + dataProvider = CGDataProviderCreateWithData (NULL, isurf->data, isurf->height * isurf->stride, @@ -1060,8 +1108,10 @@ _cairo_quartz_surface_clone_similar (void *abstract_surface, cairo_quartz_surface_create (new_format, CGImageGetWidth (quartz_image), CGImageGetHeight (quartz_image)); - if (!new_surface || new_surface->base.status) + if (!new_surface || new_surface->base.status) { + CGImageRelease (quartz_image); return CAIRO_INT_STATUS_UNSUPPORTED; + } CGContextSetCompositeOperation (new_surface->cgContext, kPrivateCGCompositeCopy); @@ -1564,6 +1614,9 @@ static const struct _cairo_surface_backend cairo_quartz_surface_backend = { #endif /* CAIRO_HAS_ATSUI_FONT */ NULL, /* snapshot */ + NULL, /* is_similar */ + NULL, /* reset */ + NULL /* fill_stroke */ }; static cairo_quartz_surface_t * @@ -1681,6 +1734,12 @@ cairo_quartz_surface_create (cairo_format_t format, int stride; int bitsPerComponent; + // verify width and height of surface + if (!verify_surface_size(width, height)) { + _cairo_error (CAIRO_STATUS_NO_MEMORY); + return (cairo_surface_t*) &_cairo_surface_nil; + } + if (format == CAIRO_FORMAT_ARGB32) { cgColorspace = CGColorSpaceCreateDeviceRGB(); stride = width * 4; @@ -1729,6 +1788,7 @@ cairo_quartz_surface_create (cairo_format_t format, if (!cgc) { _cairo_error (CAIRO_STATUS_NO_MEMORY); + free (imageData); return (cairo_surface_t*) &_cairo_surface_nil; } diff --git a/gfx/cairo/cairo/src/cairo-win32-font.c b/gfx/cairo/cairo/src/cairo-win32-font.c index 9f01bc8ddd5b..2b5e31493ad7 100644 --- a/gfx/cairo/cairo/src/cairo-win32-font.c +++ b/gfx/cairo/cairo/src/cairo-win32-font.c @@ -1332,10 +1332,8 @@ _cairo_win32_transform_FIXED_to_fixed (cairo_matrix_t *matrix, FIXED Fx, FIXED Fy, cairo_fixed_t *fx, cairo_fixed_t *fy) { - double x, y; - - x = _cairo_fixed_to_double (*((cairo_fixed_t *)&Fx)); - y = _cairo_fixed_to_double (*((cairo_fixed_t *)&Fy)); + double x = Fx.value + Fx.fract / 65536.0; + double y = Fy.value + Fy.fract / 65536.0; cairo_matrix_transform_point (matrix, &x, &y); *fx = _cairo_fixed_from_double (x); *fy = _cairo_fixed_from_double (y); diff --git a/gfx/cairo/endian.patch b/gfx/cairo/endian.patch new file mode 100644 index 000000000000..218ddff87832 --- /dev/null +++ b/gfx/cairo/endian.patch @@ -0,0 +1,43 @@ +--- a/libpixman/src/Makefile.in Fri Oct 19 14:57:40 2007 ++++ b/libpixman/src/Makefile.in Fri Oct 19 14:52:04 2007 +@@ -88,7 +88,7 @@ + + EXPORTS = pixman.h pixman-remap.h + +-LOCAL_INCLUDES += -I$(srcdir) ++LOCAL_INCLUDES += -I$(srcdir) -I$(srcdir)/../../cairo/src + + FORCE_STATIC_LIB = 1 + # This library is used by other shared libs in a static build +--- a/libpixman/src/pixman-private.h Fri Oct 19 14:55:56 2007 ++++ b/libpixman/src/pixman-private.h Fri Oct 19 14:56:45 2007 +@@ -5,6 +5,8 @@ + #ifndef PIXMAN_PRIVATE_H + #define PIXMAN_PRIVATE_H + ++#include "cairo-platform.h" ++ + #include "pixman.h" + #include + +--- a/glitz/src/Makefile.in Fri Oct 19 14:55:50 2007 ++++ b/glitz/src/Makefile.in Fri Oct 19 14:57:19 2007 +@@ -91,6 +91,6 @@ + FORCE_STATIC_LIB = 1 + FORCE_USE_PIC = 1 + +-LOCAL_INCLUDES += -I$(srcdir) ++LOCAL_INCLUDES += -I$(srcdir) -I$(srcdir)/../../cairo/src + + include $(topsrcdir)/config/rules.mk +--- a/glitz/src/glitzint.h Fri Oct 19 14:55:50 2007 ++++ b/glitz/src/glitzint.h Fri Oct 19 14:57:19 2007 +@@ -26,6 +26,8 @@ + #ifndef GLITZINT_H_INCLUDED + #define GLITZINT_H_INCLUDED + ++#include "cairo-platform.h" ++ + #ifdef _MSC_VER + #define _USE_MATH_DEFINES + #endif diff --git a/gfx/cairo/libpixman/src/pixman-compose.c b/gfx/cairo/libpixman/src/pixman-compose.c index 1e91864af296..baf79a71e08f 100644 --- a/gfx/cairo/libpixman/src/pixman-compose.c +++ b/gfx/cairo/libpixman/src/pixman-compose.c @@ -3890,7 +3890,7 @@ static void fbFetchTransformed(bits_image_t * pict, int x, int y, int width, uin tl = x1_out|y1_out ? 0 : fetch((pixman_image_t *)pict, b, x_off, indexed); tr = x2_out|y1_out ? 0 : fetch((pixman_image_t *)pict, b, x_off + 1, indexed); - b += stride; + b = bits + (y2)*stride; bl = x1_out|y2_out ? 0 : fetch((pixman_image_t *)pict, b, x_off, indexed); br = x2_out|y2_out ? 0 : fetch((pixman_image_t *)pict, b, x_off + 1, indexed); @@ -3953,7 +3953,7 @@ static void fbFetchTransformed(bits_image_t * pict, int x, int y, int width, uin ? fetch((pixman_image_t *)pict, b, x_off, indexed) : 0; tr = pixman_region_contains_point(pict->common.src_clip, x2, y1, &box) ? fetch((pixman_image_t *)pict, b, x_off + 1, indexed) : 0; - b += stride; + b = bits + (y2)*stride; bl = pixman_region_contains_point(pict->common.src_clip, x1, y2, &box) ? fetch((pixman_image_t *)pict, b, x_off, indexed) : 0; br = pixman_region_contains_point(pict->common.src_clip, x2, y2, &box) diff --git a/gfx/cairo/libpixman/src/pixman-private.h b/gfx/cairo/libpixman/src/pixman-private.h index 6487bfd7fdc6..072def13eb5b 100644 --- a/gfx/cairo/libpixman/src/pixman-private.h +++ b/gfx/cairo/libpixman/src/pixman-private.h @@ -5,6 +5,8 @@ #ifndef PIXMAN_PRIVATE_H #define PIXMAN_PRIVATE_H +#include "cairo-platform.h" + #include "pixman.h" #include diff --git a/gfx/idl/gfxIImageFrame.idl b/gfx/idl/gfxIImageFrame.idl index 7658a2332165..9779af4627b8 100644 --- a/gfx/idl/gfxIImageFrame.idl +++ b/gfx/idl/gfxIImageFrame.idl @@ -57,7 +57,7 @@ native nsRectRef(nsIntRect &); * @author Stuart Parmenter * @version 0.1 */ -[scriptable, uuid(2502c898-73bd-4da5-8fae-21cf7a492f64)] +[scriptable, uuid(7292afa2-3b94-424d-97d5-51ce2f04c0fe)] interface gfxIImageFrame : nsISupports { /** @@ -156,4 +156,8 @@ interface gfxIImageFrame : nsISupports * moment */ attribute long frameDisposalMethod; + + /* PNG specific methods */ + + attribute long blendMethod; }; diff --git a/gfx/src/shared/gfxImageFrame.cpp b/gfx/src/shared/gfxImageFrame.cpp index 060667c14d3f..9091b3587223 100644 --- a/gfx/src/shared/gfxImageFrame.cpp +++ b/gfx/src/shared/gfxImageFrame.cpp @@ -39,6 +39,7 @@ #include "gfxImageFrame.h" #include "nsIServiceManager.h" +#include NS_IMPL_ISUPPORTS2(gfxImageFrame, gfxIImageFrame, nsIInterfaceRequestor) @@ -46,7 +47,8 @@ gfxImageFrame::gfxImageFrame() : mInitialized(PR_FALSE), mMutable(PR_TRUE), mTimeout(100), - mDisposalMethod(0) + mDisposalMethod(0), /* imgIContainer::kDisposeNotSpecified */ + mBlendMethod(1) /* imgIContainer::kBlendOver */ { /* member initializers and constructor code */ } @@ -62,6 +64,8 @@ NS_IMETHODIMP gfxImageFrame::Init(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt3 if (mInitialized) return NS_ERROR_FAILURE; + // assert for properties that should be verified by decoders, warn for properties related to bad content + if (aWidth <= 0 || aHeight <= 0) { NS_ASSERTION(0, "error - negative image size\n"); return NS_ERROR_FAILURE; @@ -70,26 +74,34 @@ NS_IMETHODIMP gfxImageFrame::Init(PRInt32 aX, PRInt32 aY, PRInt32 aWidth, PRInt3 /* check to make sure we don't overflow a 32-bit */ PRInt32 tmp = aWidth * aHeight; if (tmp / aHeight != aWidth) { - NS_ASSERTION(0, "width or height too large\n"); + NS_WARNING("width or height too large"); return NS_ERROR_FAILURE; } tmp = tmp * 4; if (tmp / 4 != aWidth * aHeight) { - NS_ASSERTION(0, "width or height too large\n"); + NS_WARNING("width or height too large"); return NS_ERROR_FAILURE; } if ( (aDepth != 8) && (aDepth != 24) ){ - NS_ERROR("This Depth is not supported\n"); + NS_ERROR("This Depth is not supported"); return NS_ERROR_FAILURE; } /* reject over-wide or over-tall images */ const PRInt32 k64KLimit = 0x0000FFFF; if ( aWidth > k64KLimit || aHeight > k64KLimit ){ - NS_ERROR("image too big"); + NS_WARNING("image too big"); return NS_ERROR_FAILURE; } + +#if defined(XP_MACOSX) + // CoreGraphics is limited to images < 32K in *height*, so clamp all surfaces on the Mac to that height + if (aHeight > SHRT_MAX) { + NS_WARNING("image too big"); + return NS_ERROR_FAILURE; + } +#endif nsresult rv; @@ -343,6 +355,24 @@ NS_IMETHODIMP gfxImageFrame::SetFrameDisposalMethod(PRInt32 aFrameDisposalMethod return NS_OK; } +/* attribute long blendMethod; */ +NS_IMETHODIMP gfxImageFrame::GetBlendMethod(PRInt32 *aBlendMethod) +{ + if (!mInitialized) + return NS_ERROR_NOT_INITIALIZED; + + *aBlendMethod = mBlendMethod; + return NS_OK; +} +NS_IMETHODIMP gfxImageFrame::SetBlendMethod(PRInt32 aBlendMethod) +{ + if (!mInitialized) + return NS_ERROR_NOT_INITIALIZED; + + mBlendMethod = (PRInt8)aBlendMethod; + return NS_OK; +} + NS_IMETHODIMP gfxImageFrame::GetInterface(const nsIID & aIID, void * *result) { if (!mInitialized) diff --git a/gfx/src/shared/gfxImageFrame.h b/gfx/src/shared/gfxImageFrame.h index d9f251461e54..80108af75af3 100644 --- a/gfx/src/shared/gfxImageFrame.h +++ b/gfx/src/shared/gfxImageFrame.h @@ -80,4 +80,5 @@ private: PRInt32 mTimeout; // -1 means display forever nsIntPoint mOffset; PRInt32 mDisposalMethod; + PRInt8 mBlendMethod; }; diff --git a/gfx/src/thebes/nsThebesRenderingContext.cpp b/gfx/src/thebes/nsThebesRenderingContext.cpp index 4d66acc6d24a..e54f7c2b7f2b 100644 --- a/gfx/src/thebes/nsThebesRenderingContext.cpp +++ b/gfx/src/thebes/nsThebesRenderingContext.cpp @@ -493,7 +493,7 @@ nsThebesRenderingContext::DrawRect(nscoord aX, nscoord aY, nscoord aWidth, nscoo } -/* Clamp r to (0,0) (16384,16384); +/* Clamp r to (0,0) (2^23,2^23) * these are to be device coordinates. * * Returns PR_FALSE if the rectangle is completely out of bounds, @@ -520,7 +520,7 @@ nsThebesRenderingContext::DrawRect(nscoord aX, nscoord aY, nscoord aWidth, nscoo * the width and height are clamped such x+width or y+height are equal * to CAIRO_COORD_MAX, and PR_TRUE is returned. */ -#define CAIRO_COORD_MAX (16384.0) +#define CAIRO_COORD_MAX (8388608.0) static PRBool ConditionRect(gfxRect& r) { diff --git a/gfx/thebes/public/Makefile.in b/gfx/thebes/public/Makefile.in index 46719562b820..d41c8db30ee0 100644 --- a/gfx/thebes/public/Makefile.in +++ b/gfx/thebes/public/Makefile.in @@ -8,7 +8,9 @@ include $(DEPTH)/config/autoconf.mk MODULE = thebes -REQUIRES = cairo +REQUIRES = cairo \ + unicharutil \ + $(NULL) EXPORTS = gfxASurface.h \ gfxAlphaRecovery.h \ diff --git a/gfx/thebes/public/gfxFont.h b/gfx/thebes/public/gfxFont.h index e4c2aabf0ad6..84cda4af5714 100644 --- a/gfx/thebes/public/gfxFont.h +++ b/gfx/thebes/public/gfxFont.h @@ -50,6 +50,7 @@ #include "gfxRect.h" #include "nsExpirationTracker.h" #include "nsMathUtils.h" +#include "nsBidiUtils.h" class gfxContext; class gfxTextRun; @@ -1358,8 +1359,17 @@ public: * be treated as invisible and zero-width. */ static PRBool IsInvalidChar(PRUnichar ch) { - return ch == '\t' || ch == '\r' || ch == '\n' || ch == '\f' || - ch == 0x200B/*ZWSP*/ || ch == 0x2028/*LSEP*/ || ch == 0x2029/*PSEP*/; + if (ch >= 32) { + return ch == 0x0085/*NEL*/ || + ((ch & 0xFF00) == 0x2000 /* Unicode control character */ && + (ch == 0x200B/*ZWSP*/ || ch == 0x2028/*LSEP*/ || ch == 0x2029/*PSEP*/ || + IS_BIDI_CONTROL_CHAR(ch))); + } + // We could just blacklist all control characters, but it seems better + // to only blacklist the ones we know cause problems for native font + // engines. + return ch == 0x0B || ch == '\t' || ch == '\r' || ch == '\n' || ch == '\f' || + (ch >= 0x1c && ch <= 0x1f); } /** diff --git a/gfx/thebes/public/gfxOS2Surface.h b/gfx/thebes/public/gfxOS2Surface.h index b12f2bcc7625..6bc1058db830 100644 --- a/gfx/thebes/public/gfxOS2Surface.h +++ b/gfx/thebes/public/gfxOS2Surface.h @@ -47,8 +47,6 @@ class THEBES_API gfxOS2Surface : public gfxASurface { public: - // constructor to create a cairo surface using an existing PS - gfxOS2Surface(HPS aPS, const gfxIntSize& aSize); // constructor used to create a memory surface of given size gfxOS2Surface(const gfxIntSize& aSize, gfxASurface::gfxImageFormat aImageFormat); @@ -56,11 +54,20 @@ public: gfxOS2Surface(HWND aWnd); virtual ~gfxOS2Surface(); + // Special functions that only make sense for the OS/2 port of cairo: + + // Update the cairo surface. + // While gfxOS2Surface keeps track of the presentation handle itself, + // use the one from WinBeginPaint() here. + void Refresh(RECTL *aRect, HPS aPS); + + // Reset the cairo surface to the given size. + int Resize(const gfxIntSize& aSize); + HPS GetPS() { return mPS; } gfxIntSize GetSize() { return mSize; } private: - PRBool mOwnsPS; PRBool mHasWnd; // indicates if created through the HWND constructor HDC mDC; // memory device context HPS mPS; // presentation space connected to window or memory device diff --git a/gfx/thebes/src/gfxASurface.cpp b/gfx/thebes/src/gfxASurface.cpp index 3570c4dc2f7f..d975535844bc 100644 --- a/gfx/thebes/src/gfxASurface.cpp +++ b/gfx/thebes/src/gfxASurface.cpp @@ -55,6 +55,7 @@ #endif #include +#include static cairo_user_data_key_t gfxasurface_pointer_key; @@ -281,6 +282,14 @@ gfxASurface::CheckSurfaceSize(const gfxIntSize& sz, PRInt32 limit) return PR_FALSE; } +#if defined(XP_MACOSX) + // CoreGraphics is limited to images < 32K in *height*, so clamp all surfaces on the Mac to that height + if (sz.height > SHRT_MAX) { + NS_WARNING("Surface size too large (would overflow)!"); + return PR_FALSE; + } +#endif + // check to make sure we don't overflow a 32-bit PRInt32 tmp = sz.width * sz.height; if (tmp && tmp / sz.height != sz.width) { diff --git a/gfx/thebes/src/gfxAtsuiFonts.cpp b/gfx/thebes/src/gfxAtsuiFonts.cpp index 2a7dde5a5570..d4db8c5b3971 100644 --- a/gfx/thebes/src/gfxAtsuiFonts.cpp +++ b/gfx/thebes/src/gfxAtsuiFonts.cpp @@ -821,18 +821,18 @@ SetGlyphsForCharacterGroup(ATSLayoutRecord *aGlyphs, PRUint32 aGlyphCount, for (i = 0; i < aGlyphCount; ++i) { ATSLayoutRecord *glyph = &aGlyphs[i]; if (glyph->glyphID != ATSUI_SPECIAL_GLYPH_ID) { - if (detailedGlyphs.Length() > 0) { - detailedGlyphs[detailedGlyphs.Length() - 1].mAdvance = - GetAdvanceAppUnits(advanceStart, glyph - advanceStart, aAppUnitsPerDevUnit); - advanceStart = glyph; - } - gfxTextRun::DetailedGlyph *details = detailedGlyphs.AppendElement(); if (!details) return; + details->mAdvance = 0; details->mIsLastGlyph = PR_FALSE; details->mGlyphID = glyph->glyphID; details->mXOffset = 0; + if (detailedGlyphs.Length() > 1) { + details->mXOffset += + GetAdvanceAppUnits(advanceStart, glyph - advanceStart, + aAppUnitsPerDevUnit); + } details->mYOffset = !aBaselineDeltas ? 0.0f : FixedToFloat(aBaselineDeltas[i])*aAppUnitsPerDevUnit; } @@ -843,9 +843,13 @@ SetGlyphsForCharacterGroup(ATSLayoutRecord *aGlyphs, PRUint32 aGlyphCount, return; } + // The advance width for the whole cluster + PRInt32 clusterAdvance = GetAdvanceAppUnits(aGlyphs, aGlyphCount, aAppUnitsPerDevUnit); detailedGlyphs[detailedGlyphs.Length() - 1].mIsLastGlyph = PR_TRUE; - detailedGlyphs[detailedGlyphs.Length() - 1].mAdvance = - GetAdvanceAppUnits(advanceStart, aGlyphs + aGlyphCount - advanceStart, aAppUnitsPerDevUnit); + if (aRun->IsRightToLeft()) + detailedGlyphs[0].mAdvance = clusterAdvance; + else + detailedGlyphs[detailedGlyphs.Length() - 1].mAdvance = clusterAdvance; aRun->SetDetailedGlyphs(aSegmentStart + index, detailedGlyphs.Elements(), detailedGlyphs.Length()); } diff --git a/gfx/thebes/src/gfxOS2Fonts.cpp b/gfx/thebes/src/gfxOS2Fonts.cpp index 53f9a77fe63c..1d85ebae9881 100644 --- a/gfx/thebes/src/gfxOS2Fonts.cpp +++ b/gfx/thebes/src/gfxOS2Fonts.cpp @@ -99,6 +99,12 @@ const gfxFont::Metrics& gfxOS2Font::GetMetrics() FT_UInt gid; // glyph ID FT_Face face = cairo_ft_scaled_font_lock_face(CairoScaledFont()); + if (!face) { + // Abort here already, otherwise we crash in the following + // this can happen if the font-size requested is zero. + // The metrics will be incomplete, but then we don't care. + return *mMetrics; + } double emUnit = 1.0 * face->units_per_EM; double xScale = face->size->metrics.x_ppem / emUnit; @@ -337,7 +343,7 @@ cairo_scaled_font_t *gfxOS2Font::CairoScaledFont() } NS_ASSERTION(cairo_scaled_font_status(mScaledFont) == CAIRO_STATUS_SUCCESS, - "Failed to make scaled font"); + "Failed to make scaled font"); return mScaledFont; } diff --git a/gfx/thebes/src/gfxOS2Surface.cpp b/gfx/thebes/src/gfxOS2Surface.cpp index bd21c8358a23..3a4c9ee69789 100644 --- a/gfx/thebes/src/gfxOS2Surface.cpp +++ b/gfx/thebes/src/gfxOS2Surface.cpp @@ -43,28 +43,9 @@ * class gfxOS2Surface **********************************************************************/ -gfxOS2Surface::gfxOS2Surface(HPS aPS, const gfxIntSize& aSize) - : mOwnsPS(PR_FALSE), mHasWnd(PR_FALSE), mDC(nsnull), mPS(aPS), mBitmap(nsnull), mSize(aSize) -{ -#ifdef DEBUG_thebes_2 - printf("gfxOS2Surface[%#x]::gfxOS2Surface(HPS=%#x, Size=%dx%d)\n", (unsigned int)this, - (unsigned int)mPS, aSize.width, aSize.height); -#endif - - // create the cairo surface on the passed PS - cairo_surface_t *surf = cairo_os2_surface_create(mPS, mSize.width, mSize.height); -#ifdef DEBUG_thebes_2 - printf(" type(%#x)=%d (ID=%#x, h/w=%d/%d)\n", (unsigned int)surf, - cairo_surface_get_type(surf), (unsigned int)mPS, mSize.width, mSize.height); -#endif - // XXX for now uncomment the mark_dirty function, see bug 371505 - //cairo_surface_mark_dirty(surf); - Init(surf); -} - gfxOS2Surface::gfxOS2Surface(const gfxIntSize& aSize, gfxASurface::gfxImageFormat aImageFormat) - : mOwnsPS(PR_TRUE), mHasWnd(PR_FALSE), mSize(aSize) + : mHasWnd(PR_FALSE), mSize(aSize) { #ifdef DEBUG_thebes_2 printf("gfxOS2Surface[%#x]::gfxOS2Surface(Size=%dx%d, %d)\n", (unsigned int)this, @@ -105,13 +86,18 @@ gfxOS2Surface::gfxOS2Surface(const gfxIntSize& aSize, printf(" type(%#x)=%d (ID=%#x, h/w=%d/%d)\n", (unsigned int)surf, cairo_surface_get_type(surf), (unsigned int)mPS, mSize.width, mSize.height); #endif - // XXX for now uncomment the mark_dirty function, see bug 371505 - //cairo_surface_mark_dirty(surf); + // Normally, OS/2 cairo surfaces have to be forced to redraw completely + // by calling cairo_surface_mark_dirty(surf), but Mozilla paints them in + // full, so that is not necessary here. + + // manual refresh is done from nsWindow::OnPaint + cairo_os2_surface_set_manual_window_refresh(surf, 1); + Init(surf); } gfxOS2Surface::gfxOS2Surface(HWND aWnd) - : mOwnsPS(PR_TRUE), mHasWnd(PR_TRUE), mDC(nsnull), mBitmap(nsnull) + : mHasWnd(PR_TRUE), mDC(nsnull), mBitmap(nsnull) { #ifdef DEBUG_thebes_2 printf("gfxOS2Surface[%#x]::gfxOS2Surface(HWND=%#x)\n", (unsigned int)this, @@ -131,10 +117,15 @@ gfxOS2Surface::gfxOS2Surface(HWND aWnd) printf(" type(%#x)=%d (ID=%#x, h/w=%d/%d)\n", (unsigned int)surf, cairo_surface_get_type(surf), (unsigned int)mPS, mSize.width, mSize.height); #endif + // Normally, OS/2 cairo surfaces have to be forced to redraw completely + // by calling cairo_surface_mark_dirty(surf), but Mozilla paints them in + // full, so that is not necessary here. + // record the window handle in the cairo surface, so that refresh works cairo_os2_surface_set_hwnd(surf, aWnd); - // XXX for now uncomment the mark_dirty function, see bug 371505 - //cairo_surface_mark_dirty(surf); + // manual refresh is done from nsWindow::OnPaint + cairo_os2_surface_set_manual_window_refresh(surf, 1); + Init(surf); } @@ -149,7 +140,7 @@ gfxOS2Surface::~gfxOS2Surface() // hand were created on memory device contexts with the GPI functions, so // use those to clean up stuff. if (mHasWnd) { - if (mOwnsPS && mPS) { + if (mPS) { WinReleasePS(mPS); } } else { @@ -157,7 +148,7 @@ gfxOS2Surface::~gfxOS2Surface() GpiSetBitmap(mPS, NULL); GpiDeleteBitmap(mBitmap); } - if (mOwnsPS && mPS) { + if (mPS) { GpiDestroyPS(mPS); } if (mDC) { @@ -165,3 +156,25 @@ gfxOS2Surface::~gfxOS2Surface() } } } + +void gfxOS2Surface::Refresh(RECTL *aRect, HPS aPS) +{ +#ifdef DEBUG_thebes_2 + printf("gfxOS2Surface[%#x]::Refresh(x=%ld,%ld/y=%ld,%ld, HPS=%#x), mPS=%#x\n", + (unsigned int)this, + aRect->xLeft, aRect->xRight, aRect->yBottom, aRect->yTop, + (unsigned int)aPS, (unsigned int)mPS); +#endif + cairo_os2_surface_refresh_window(CairoSurface(), aPS, aRect); +} + +int gfxOS2Surface::Resize(const gfxIntSize& aSize) +{ +#ifdef DEBUG_thebes_2 + printf("gfxOS2Surface[%#x]::Resize(%dx%d)\n", (unsigned int)this, + aSize.width, aSize.height); +#endif + mSize = aSize; // record the new size + // hardcode mutex timeout to 50ms for now + return cairo_os2_surface_set_size(CairoSurface(), mSize.width, mSize.height, 50); +} diff --git a/gfx/thebes/src/gfxPangoFonts.cpp b/gfx/thebes/src/gfxPangoFonts.cpp index 6e39fb89a9ac..78908b285f40 100644 --- a/gfx/thebes/src/gfxPangoFonts.cpp +++ b/gfx/thebes/src/gfxPangoFonts.cpp @@ -216,10 +216,14 @@ gfxPangoFont::Shutdown() { gfxPangoFontCache::Shutdown(); + // This just cleans up memory used by Pango's caches and may cause an + // assert and crash in cairo (Bug 399556), so only do this when we care + // about cleaning up memory on shutdown. +#if defined(DEBUG) || defined(NS_BUILD_REFCNT_LOGGING) || defined(NS_TRACE_MALLOC) PangoFontMap *fontmap = pango_cairo_font_map_get_default (); if (PANGO_IS_FC_FONT_MAP (fontmap)) pango_fc_font_map_shutdown (PANGO_FC_FONT_MAP (fontmap)); - +#endif } static PangoStyle diff --git a/gfx/thebes/src/gfxPlatform.cpp b/gfx/thebes/src/gfxPlatform.cpp index 75e830471747..2a619c0e68f7 100644 --- a/gfx/thebes/src/gfxPlatform.cpp +++ b/gfx/thebes/src/gfxPlatform.cpp @@ -155,7 +155,11 @@ gfxPlatform::~gfxPlatform() // but we're generally in the habit of trying to shut down as // cleanly as possible even in production code, so call this // cairo_debug_* function unconditionally. + // + // because cairo can assert and thus crash on shutdown, don't do this in release builds +#if defined(DEBUG) || defined(NS_BUILD_REFCNT_LOGGING) || defined(NS_TRACE_MALLOC) cairo_debug_reset_static_data(); +#endif #if 0 // It would be nice to do this (although it might need to be after diff --git a/gfx/thebes/src/gfxWindowsFonts.cpp b/gfx/thebes/src/gfxWindowsFonts.cpp index b94edd69fcc0..062c9d939d64 100644 --- a/gfx/thebes/src/gfxWindowsFonts.cpp +++ b/gfx/thebes/src/gfxWindowsFonts.cpp @@ -1443,6 +1443,8 @@ private: if (mAlternativeString) free(mAlternativeString); mAlternativeString = (PRUnichar *)malloc(mRangeLength * sizeof(PRUnichar)); + if (!mAlternativeString) + return; memcpy((void *)mAlternativeString, (const void *)mRangeString, mRangeLength * sizeof(PRUnichar)); for (PRUint32 i = 0; i < mRangeLength; i++) { diff --git a/gfx/thebes/test/Makefile.in b/gfx/thebes/test/Makefile.in index f76f4d6df896..117120674348 100644 --- a/gfx/thebes/test/Makefile.in +++ b/gfx/thebes/test/Makefile.in @@ -51,7 +51,7 @@ REQUIRES = \ thebes \ cairo \ pref \ - thebes \ + unicharutil \ $(NULL) # All platforms diff --git a/js/narcissus/jsexec.js b/js/narcissus/jsexec.js index 44193eca21ed..98ff537add07 100644 --- a/js/narcissus/jsexec.js +++ b/js/narcissus/jsexec.js @@ -499,7 +499,7 @@ function execute(n, x) { putValue(r, v, n[0]); break; - case CONDITIONAL: + case HOOK: v = getValue(execute(n[0], x)) ? getValue(execute(n[1], x)) : getValue(execute(n[2], x)); break; diff --git a/js/narcissus/jsparse.js b/js/narcissus/jsparse.js index 574299b90535..7cccbac582c2 100644 --- a/js/narcissus/jsparse.js +++ b/js/narcissus/jsparse.js @@ -153,7 +153,7 @@ Tokenizer.prototype = { } else if ((match = /^0[xX][\da-fA-F]+|^0[0-7]*|^\d+/(input))) { token.type = NUMBER; token.value = parseInt(match[0]); - } else if ((match = /^\w+/(input))) { + } else if ((match = /^[$_\w]+/(input))) { // FIXME no ES3 unicode var id = match[0]; token.type = keywords[id] || IDENTIFIER; token.value = id; @@ -272,7 +272,7 @@ function tokenstr(tt) { Np.toString = function () { var a = []; for (var i in this) { - if (this.hasOwnProperty(i) && i != 'type') + if (this.hasOwnProperty(i) && i != 'type' && i != 'target') a.push({id: i, value: this[i]}); } a.sort(function (a,b) { return (a.id < b.id) ? -1 : 1; }); @@ -642,7 +642,7 @@ function ParenExpression(t, x) { var opPrecedence = { SEMICOLON: 0, COMMA: 1, - ASSIGN: 2, HOOK: 2, COLON: 2, CONDITIONAL: 2, + ASSIGN: 2, HOOK: 2, COLON: 2, // The above all have to have the same precedence, see bug 330975. OR: 4, AND: 5, @@ -668,7 +668,7 @@ for (i in opPrecedence) var opArity = { COMMA: -2, ASSIGN: 2, - CONDITIONAL: 3, + HOOK: 3, OR: 2, AND: 2, BITWISE_OR: 2, @@ -751,7 +751,6 @@ loop: n = operators.top(); if (n.type != HOOK) throw t.newSyntaxError("Invalid label"); - n.type = CONDITIONAL; --x.hookLevel; } else { operators.push(new Node(t)); diff --git a/js/src/Makefile.in b/js/src/Makefile.in index b5eccb62e9d9..5253466efcae 100644 --- a/js/src/Makefile.in +++ b/js/src/Makefile.in @@ -102,6 +102,11 @@ CPPSRCS = \ prmjtime.cpp \ $(NULL) +ifdef HAVE_DTRACE +CSRCS += \ + jsdtracef.c +endif + EXPORTS = \ jsautocfg.h \ jsautokw.h \ @@ -151,6 +156,13 @@ EXPORTS = \ jsxml.h \ $(NULL) +ifdef HAVE_DTRACE +EXPORTS += \ + jsdtracef.h \ + javascript-trace.h \ + $(NULL) +endif + ifeq (,$(filter-out WINNT WINCE,$(OS_ARCH))) EXPORTS += jscpucfg.h endif @@ -202,6 +214,11 @@ HOST_SIMPLE_PROGRAMS += host_jskwgen$(HOST_BIN_SUFFIX) GARBAGE += jsautokw.h host_jskwgen$(HOST_BIN_SUFFIX) USE_HOST_CXX = 1 +ifdef HAVE_DTRACE +DTRACE_PROBE_OBJ = $(LIBRARY_NAME)-dtrace.$(OBJ_SUFFIX) +MOZILLA_DTRACE_SRC = $(srcdir)/javascript-trace.d +endif + include $(topsrcdir)/config/rules.mk DEFINES += -DEXPORT_JS_API @@ -392,3 +409,11 @@ host_jskwgen.$(OBJ_SUFFIX): jsconfig.h jskeyword.tbl jsautokw.h: host_jskwgen$(HOST_BIN_SUFFIX) ./host_jskwgen$(HOST_BIN_SUFFIX) $@ + +ifdef HAVE_DTRACE +javascript-trace.h: $(srcdir)/javascript-trace.d + dtrace -h -s $(srcdir)/javascript-trace.d -o javascript-trace.h.in + sed 's/if _DTRACE_VERSION/ifdef INCLUDE_MOZILLA_DTRACE/' \ + javascript-trace.h.in > javascript-trace.h +endif + diff --git a/js/src/javascript-trace.d b/js/src/javascript-trace.d new file mode 100644 index 000000000000..eedb482d0e0e --- /dev/null +++ b/js/src/javascript-trace.d @@ -0,0 +1,71 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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. + * + * Copyright (C) 2007 Sun Microsystems, Inc. All Rights Reserved. + * + * 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 ***** */ + +/* + * javascript provider probes + * + * function-entry (filename, classname, funcname) + * function-info (filename, classname, funcname, lineno, + * runfilename, runlineno) + * function-args (filename, classname, funcname, argc, argv, argv0, + * argv1, argv2, argv3, argv4) + * function-rval (filename, classname, funcname, lineno, rval, rval0) + * function-return (filename, classname, funcname) + * object-create-start (filename, classname) + * object-create (filename, classname, *object, rlineno) + * object-create-done (filename, classname) + * object-finalize (NULL, classname, *object) + * execute-start (filename, lineno) + * execute-done (filename, lineno) + */ + +provider javascript { + probe function__entry(char *, char *, char *); + probe function__info(char *, char *, char *, int, char *, int); + probe function__args(char *, char *, char *, int, void *, void *, void *, + void *, void *, void *); + probe function__rval(char *, char *, char *, int, void *, void *); + probe function__return(char *, char *, char *); + probe object__create__start(char *, char *); + probe object__create__done(char *, char *); + probe object__create(char *, char *, uintptr_t, int); + probe object__finalize(char *, char *, uintptr_t); + probe execute__start(char *, int); + probe execute__done(char *, int); +}; + +/* +#pragma D attributes Unstable/Unstable/Common provider mozilla provider +#pragma D attributes Private/Private/Unknown provider mozilla module +#pragma D attributes Private/Private/Unknown provider mozilla function +#pragma D attributes Unstable/Unstable/Common provider mozilla name +#pragma D attributes Unstable/Unstable/Common provider mozilla args +*/ + diff --git a/js/src/jsdtracef.c b/js/src/jsdtracef.c new file mode 100644 index 000000000000..dd3c5d0badde --- /dev/null +++ b/js/src/jsdtracef.c @@ -0,0 +1,311 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sw=4 et tw=80: + * + * ***** 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. + * + * Copyright (C) 2007 Sun Microsystems, Inc. All Rights Reserved. + * + * Contributor(s): + * Brendan Eich + * + * 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 ***** */ + +#include "jsapi.h" +#include "jsutil.h" +#include "jsatom.h" +#include "jscntxt.h" +#include "jsdbgapi.h" +#include "jsfun.h" +#include "jsinterp.h" +#include "jsobj.h" +#include "jsscript.h" +#include "jsstr.h" + +#include "jsdtracef.h" +#include + +#define TYPEOF(cx,v) (JSVAL_IS_NULL(v) ? JSTYPE_NULL : JS_TypeOfValue(cx,v)) + +static char dempty[] = ""; + +char * +jsdtrace_filename(JSStackFrame *fp) +{ + while (fp && fp->script == NULL) + fp = fp->down; + return (fp && fp->script && fp->script->filename) + ? (char *)fp->script->filename + : dempty; +} + +int +jsdtrace_linenumber(JSContext *cx, JSStackFrame *fp) +{ + while (fp && fp->script == NULL) + fp = fp->down; + return (fp && fp->script && fp->pc) + ? js_PCToLineNumber(cx, fp->script, fp->pc) + : -1; +} + +/* + * This function is used to convert function arguments and return value (jsval) + * into the following based on each value's type tag: + * + * jsval returned + * ------------------- + * STRING -> char * + * INT -> int + * DOUBLE -> double * + * BOOLEAN -> int + * OBJECT -> void * + * + * All are presented as void * for DTrace consumers to use, after shifting or + * masking out the JavaScript type bits. This allows D scripts to use ints and + * booleans directly and copyinstr() for string arguments, when types are known + * beforehand. + * + * This is used by the function-args and function-rval probes, which also + * provide raw (unmasked) jsvals should type info be useful from D scripts. + */ +void * +jsdtrace_jsvaltovoid(JSContext *cx, jsval argval) +{ + JSType type = TYPEOF(cx, argval); + + switch (type) { + case JSTYPE_NULL: + case JSTYPE_VOID: + return JS_TYPE_STR(type); + + case JSTYPE_BOOLEAN: + return (void *)JSVAL_TO_BOOLEAN(argval); + + case JSTYPE_STRING: + return (void *)js_GetStringBytes(cx, JSVAL_TO_STRING(argval)); + + case JSTYPE_NUMBER: + if (JSVAL_IS_INT(argval)) + return (void *)JSVAL_TO_INT(argval); + return JSVAL_TO_DOUBLE(argval); + + default: + return JSVAL_TO_GCTHING(argval); + } + /* NOTREACHED */ +} + +char * +jsdtrace_function_name(JSContext *cx, JSStackFrame *fp, JSFunction *fun) +{ + JSAtom *atom; + JSScript *script; + jsbytecode *pc; + char *name; + + atom = fun->atom; + if (!atom) { + if (fp->fun != fun || !fp->down) + return dempty; + + script = fp->down->script; + pc = fp->down->pc; + if (!script || !pc) + return dempty; + + /* + * An anonymous function called from an active script or interpreted + * function: try to fetch the variable or property name by which the + * anonymous function was invoked. First handle call ops by recovering + * the generating pc for the callee expression at argv[-2]. + */ + switch ((JSOp) *pc) { + case JSOP_CALL: + case JSOP_EVAL: + JS_ASSERT(fp->argv == fp->down->sp - (int)GET_ARGC(pc)); + + pc = (jsbytecode *) fp->argv[-2 - (int)script->depth]; + + /* + * Be paranoid about bugs to-do with generating pc storage when + * attempting to descend into the operand stack basement. + */ + if ((uintptr_t)(pc - script->code) >= script->length) + return dempty; + break; + } + + switch ((JSOp) *pc) { + case JSOP_CALLNAME: + case JSOP_CALLPROP: + case JSOP_NAME: + case JSOP_SETNAME: + case JSOP_GETPROP: + case JSOP_SETPROP: + GET_ATOM_FROM_BYTECODE(script, pc, 0, atom); + break; + + case JSOP_CALLELEM: + case JSOP_GETELEM: + case JSOP_SETELEM: + case JSOP_CALLGVAR: + case JSOP_GETGVAR: + case JSOP_SETGVAR: + case JSOP_CALLVAR: + case JSOP_CALLARG: + case JSOP_CALLLOCAL: + /* FIXME: try to recover a name from these ops. */ + /* FALL THROUGH */ + + default: + return dempty; + } + } + + name = (char *)js_GetStringBytes(cx, ATOM_TO_STRING(atom)); + return name ? name : dempty; +} + +/* + * These functions call the DTrace macros for the JavaScript USDT probes. + * Originally this code was inlined in the JavaScript code; however since + * a number of operations are called, these have been placed into functions + * to reduce any negative compiler optimization effect that the addition of + * a number of usually unused lines of code would cause. + */ +void +jsdtrace_function_entry(JSContext *cx, JSStackFrame *fp, JSFunction *fun) +{ + JAVASCRIPT_FUNCTION_ENTRY( + jsdtrace_filename(fp), + fun->clasp ? (char *)fun->clasp->name : dempty, + jsdtrace_function_name(cx, fp, fun) + ); +} + +void +jsdtrace_function_info(JSContext *cx, JSStackFrame *fp, JSStackFrame *dfp, + JSFunction *fun) +{ + JAVASCRIPT_FUNCTION_INFO( + jsdtrace_filename(fp), + fun->clasp ? (char *)fun->clasp->name : dempty, + jsdtrace_function_name(cx, fp, fun), + fp->script->lineno, + jsdtrace_filename(dfp), + jsdtrace_linenumber(cx, dfp) + ); +} + +void +jsdtrace_function_args(JSContext *cx, JSStackFrame *fp, JSFunction *fun) +{ + JAVASCRIPT_FUNCTION_ARGS( + jsdtrace_filename(fp), + fun->clasp ? (char *)fun->clasp->name : dempty, + jsdtrace_function_name(cx, fp, fun), + fp->argc, (void *)fp->argv, + (fp->argc > 0) ? jsdtrace_jsvaltovoid(cx, fp->argv[0]) : 0, + (fp->argc > 1) ? jsdtrace_jsvaltovoid(cx, fp->argv[1]) : 0, + (fp->argc > 2) ? jsdtrace_jsvaltovoid(cx, fp->argv[2]) : 0, + (fp->argc > 3) ? jsdtrace_jsvaltovoid(cx, fp->argv[3]) : 0, + (fp->argc > 4) ? jsdtrace_jsvaltovoid(cx, fp->argv[4]) : 0 + ); +} + +void +jsdtrace_function_rval(JSContext *cx, JSStackFrame *fp, JSFunction *fun) +{ + JAVASCRIPT_FUNCTION_RVAL( + jsdtrace_filename(fp), + fun->clasp ? (char *)fun->clasp->name : dempty, + jsdtrace_function_name(cx, fp, fun), + jsdtrace_linenumber(cx, fp), (void *)fp->rval, + jsdtrace_jsvaltovoid(cx, fp->rval) + ); +} + +void +jsdtrace_function_return(JSContext *cx, JSStackFrame *fp, JSFunction *fun) +{ + JAVASCRIPT_FUNCTION_RETURN( + jsdtrace_filename(fp), + fun->clasp ? (char *)fun->clasp->name : dempty, + jsdtrace_function_name(cx, fp, fun) + ); +} + +void +jsdtrace_object_create_start(JSStackFrame *fp, JSClass *clasp) +{ + JAVASCRIPT_OBJECT_CREATE_START(jsdtrace_filename(fp), (char *)clasp->name); +} + +void +jsdtrace_object_create_done(JSStackFrame *fp, JSClass *clasp) +{ + JAVASCRIPT_OBJECT_CREATE_DONE(jsdtrace_filename(fp), (char *)clasp->name); +} + +void +jsdtrace_object_create(JSContext *cx, JSClass *clasp, JSObject *obj) +{ + JAVASCRIPT_OBJECT_CREATE( + jsdtrace_filename(cx->fp), + (char *)clasp->name, + (uintptr_t)obj, + jsdtrace_linenumber(cx, cx->fp) + ); +} + +void +jsdtrace_object_finalize(JSObject *obj) +{ + JSClass *clasp; + + clasp = LOCKED_OBJ_GET_CLASS(obj); + + /* the first arg is NULL - reserved for future use (filename?) */ + JAVASCRIPT_OBJECT_FINALIZE(NULL, (char *)clasp->name, (uintptr_t)obj); +} + +void +jsdtrace_execute_start(JSScript *script) +{ + JAVASCRIPT_EXECUTE_START( + script->filename ? (char *)script->filename : dempty, + script->lineno + ); +} + +void +jsdtrace_execute_done(JSScript *script) +{ + JAVASCRIPT_EXECUTE_DONE( + script->filename ? (char *)script->filename : dempty, + script->lineno + ); +} diff --git a/js/src/jsdtracef.h b/js/src/jsdtracef.h new file mode 100644 index 000000000000..6b1f0c2d4dce --- /dev/null +++ b/js/src/jsdtracef.h @@ -0,0 +1,77 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * vim: set ts=8 sw=4 et tw=80: + * + * ***** 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. + * + * Copyright (C) 2007 Sun Microsystems, Inc. All Rights Reserved. + * + * Contributor(s): + * Brendan Eich + * + * 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 ***** */ + +#include "javascript-trace.h" +#include "jspubtd.h" +#include "jsprvtd.h" + +#ifndef _JSDTRACEF_H +#define _JSDTRACEF_H + +extern void +jsdtrace_function_entry(JSContext *cx, JSStackFrame *fp, JSFunction *fun); + +extern void +jsdtrace_function_info(JSContext *cx, JSStackFrame *fp, JSStackFrame *dfp, + JSFunction *fun); + +extern void +jsdtrace_function_args(JSContext *cx, JSStackFrame *fp, JSFunction *fun); + +extern void +jsdtrace_function_rval(JSContext *cx, JSStackFrame *fp, JSFunction *fun); + +extern void +jsdtrace_function_return(JSContext *cx, JSStackFrame *fp, JSFunction *fun); + +extern void +jsdtrace_object_create_start(JSStackFrame *fp, JSClass *clasp); + +extern void +jsdtrace_object_create_done(JSStackFrame *fp, JSClass *clasp); + +extern void +jsdtrace_object_create(JSContext *cx, JSClass *clasp, JSObject *obj); + +extern void +jsdtrace_object_finalize(JSObject *obj); + +extern void +jsdtrace_execute_start(JSScript *script); + +extern void +jsdtrace_execute_done(JSScript *script); + +#endif /* _JSDTRACE_H */ diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp index bfe227c804b4..54376fd3da19 100644 --- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -1403,7 +1403,8 @@ fun_xdrObject(JSXDRState *xdr, JSObject **objp) /* Flag duplicate argument if atom is bound in fun->object. */ dupflag = SCOPE_GET_PROPERTY(OBJ_SCOPE(fun->object), - ATOM_TO_JSID(propAtom)) + JSID_HIDE_NAME( + ATOM_TO_JSID(propAtom))) ? SPROP_IS_DUPLICATE : 0; diff --git a/js/src/jsinterp.cpp b/js/src/jsinterp.cpp index a85a57f38df1..0655752e1204 100644 --- a/js/src/jsinterp.cpp +++ b/js/src/jsinterp.cpp @@ -69,6 +69,10 @@ #include "jsscript.h" #include "jsstr.h" +#ifdef INCLUDE_MOZILLA_DTRACE +#include "jsdtracef.h" +#endif + #if JS_HAS_XML_SUPPORT #include "jsxml.h" #endif @@ -1533,6 +1537,11 @@ js_Execute(JSContext *cx, JSObject *chain, JSScript *script, JSObject *obj, *tmp; JSBool ok; +#ifdef INCLUDE_MOZILLA_DTRACE + if (JAVASCRIPT_EXECUTE_START_ENABLED()) + jsdtrace_execute_start(script); +#endif + hook = cx->debugHooks->executeHook; hookData = mark = NULL; oldfp = cx->fp; @@ -1569,8 +1578,10 @@ js_Execute(JSContext *cx, JSObject *chain, JSScript *script, frame.nvars += JS_SCRIPT_REGEXPS(script)->length; if (frame.nvars != 0) { frame.vars = js_AllocRawStack(cx, frame.nvars, &mark); - if (!frame.vars) - return JS_FALSE; + if (!frame.vars) { + ok = JS_FALSE; + goto out; + } memset(frame.vars, 0, frame.nvars * sizeof(jsval)); } else { frame.vars = NULL; @@ -1637,6 +1648,11 @@ js_Execute(JSContext *cx, JSObject *chain, JSScript *script, oldfp->dormantNext = NULL; } +out: +#ifdef INCLUDE_MOZILLA_DTRACE + if (JAVASCRIPT_EXECUTE_DONE_ENABLED()) + jsdtrace_execute_done(script); +#endif return ok; } @@ -2614,6 +2630,14 @@ interrupt: ok &= js_PutArgsObject(cx, fp); } +#ifdef INCLUDE_MOZILLA_DTRACE + /* DTrace function return, inlines */ + if (JAVASCRIPT_FUNCTION_RVAL_ENABLED()) + jsdtrace_function_rval(cx, fp, fp->fun); + if (JAVASCRIPT_FUNCTION_RETURN_ENABLED()) + jsdtrace_function_return(cx, fp, fp->fun); +#endif + /* Restore context version only if callee hasn't set version. */ if (JS_LIKELY(cx->version == currentVersion)) { currentVersion = ifp->callerVersion; @@ -4038,6 +4062,16 @@ interrupt: inlineCallCount++; JS_RUNTIME_METER(rt, inlineCalls); +#ifdef INCLUDE_MOZILLA_DTRACE + /* DTrace function entry, inlines */ + if (JAVASCRIPT_FUNCTION_ENTRY_ENABLED()) + jsdtrace_function_entry(cx, fp, fun); + if (JAVASCRIPT_FUNCTION_INFO_ENABLED()) + jsdtrace_function_info(cx, fp, fp->down, fun); + if (JAVASCRIPT_FUNCTION_ARGS_ENABLED()) + jsdtrace_function_args(cx, fp, fun); +#endif + /* Load first op and dispatch it (safe since JSOP_STOP). */ op = (JSOp) *pc; DO_OP(); @@ -4053,6 +4087,18 @@ interrupt: goto out; } +#ifdef INCLUDE_MOZILLA_DTRACE + /* DTrace function entry, non-inlines */ + if (VALUE_IS_FUNCTION(cx, lval)) { + if (JAVASCRIPT_FUNCTION_ENTRY_ENABLED()) + jsdtrace_function_entry(cx, fp, fun); + if (JAVASCRIPT_FUNCTION_INFO_ENABLED()) + jsdtrace_function_info(cx, fp, fp, fun); + if (JAVASCRIPT_FUNCTION_ARGS_ENABLED()) + jsdtrace_function_args(cx, fp, fun); + } +#endif + if (fun->flags & JSFUN_FAST_NATIVE) { JS_ASSERT(fun->u.n.extra == 0); if (argc < fun->u.n.minargs) { @@ -4080,6 +4126,14 @@ interrupt: PRIMITIVE_THIS_TEST(fun, vp[1])); ok = ((JSFastNative) fun->u.n.native)(cx, argc, vp); +#ifdef INCLUDE_MOZILLA_DTRACE + if (VALUE_IS_FUNCTION(cx, lval)) { + if (JAVASCRIPT_FUNCTION_RVAL_ENABLED()) + jsdtrace_function_rval(cx, fp, fun); + if (JAVASCRIPT_FUNCTION_RETURN_ENABLED()) + jsdtrace_function_return(cx, fp, fun); + } +#endif if (!ok) goto out; sp = vp + 1; @@ -4090,6 +4144,15 @@ interrupt: do_invoke: ok = js_Invoke(cx, argc, vp, 0); +#ifdef INCLUDE_MOZILLA_DTRACE + /* DTrace function return, non-inlines */ + if (VALUE_IS_FUNCTION(cx, lval)) { + if (JAVASCRIPT_FUNCTION_RVAL_ENABLED()) + jsdtrace_function_rval(cx, fp, fun); + if (JAVASCRIPT_FUNCTION_RETURN_ENABLED()) + jsdtrace_function_return(cx, fp, fun); + } +#endif sp = vp + 1; vp[-depth] = (jsval)pc; LOAD_INTERRUPT_HANDLER(cx); diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 508c429b8d65..1794a8c51a1d 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -83,6 +83,10 @@ #include "jsxdrapi.h" #endif +#ifdef INCLUDE_MOZILLA_DTRACE +#include "jsdtracef.h" +#endif + #ifdef JS_THREADSAFE #define NATIVE_DROP_PROPERTY js_DropProperty @@ -2511,16 +2515,21 @@ js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent) uint32 nslots, i; JSTempValueRooter tvr; +#ifdef INCLUDE_MOZILLA_DTRACE + if (JAVASCRIPT_OBJECT_CREATE_START_ENABLED()) + jsdtrace_object_create_start(cx->fp, clasp); +#endif + /* Bootstrap the ur-object, and make it the default prototype object. */ if (!proto) { if (!js_GetClassId(cx, clasp, &id)) - return NULL; + goto earlybad; if (!js_GetClassPrototype(cx, parent, id, &proto)) - return NULL; + goto earlybad; if (!proto && !js_GetClassPrototype(cx, parent, INT_TO_JSID(JSProto_Object), &proto)) { - return NULL; + goto earlybad; } } @@ -2536,7 +2545,7 @@ js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent) */ obj = (JSObject *) js_NewGCThing(cx, GCX_OBJECT, sizeof(JSObject)); if (!obj) - return NULL; + goto earlybad; /* * Initialize all JSObject fields before doing any operation that can @@ -2621,11 +2630,26 @@ js_NewObject(JSContext *cx, JSClass *clasp, JSObject *proto, JSObject *parent) out: JS_POP_TEMP_ROOT(cx, &tvr); cx->weakRoots.newborn[GCX_OBJECT] = obj; +#ifdef INCLUDE_MOZILLA_DTRACE + if (JAVASCRIPT_OBJECT_CREATE_ENABLED()) + jsdtrace_object_create(cx, clasp, obj); + if (JAVASCRIPT_OBJECT_CREATE_DONE_ENABLED()) + jsdtrace_object_create_done(cx->fp, clasp); +#endif return obj; bad: obj = NULL; goto out; + +earlybad: +#ifdef INCLUDE_MOZILLA_DTRACE + if (JAVASCRIPT_OBJECT_CREATE_ENABLED()) + jsdtrace_object_create(cx, clasp, NULL); + if (JAVASCRIPT_OBJECT_CREATE_DONE_ENABLED()) + jsdtrace_object_create_done(cx->fp, clasp); +#endif + return NULL; } JS_BEGIN_EXTERN_C @@ -2874,6 +2898,11 @@ js_FinalizeObject(JSContext *cx, JSObject *obj) /* Finalize obj first, in case it needs map and slots. */ GC_AWARE_GET_CLASS(cx, obj)->finalize(cx, obj); +#ifdef INCLUDE_MOZILLA_DTRACE + if (JAVASCRIPT_OBJECT_FINALIZE_ENABLED()) + jsdtrace_object_finalize(obj); +#endif + /* Drop map and free slots. */ js_DropObjectMap(cx, map, obj); FreeSlots(cx, obj); diff --git a/js/src/xpconnect/idl/nsIXPCScriptable.idl b/js/src/xpconnect/idl/nsIXPCScriptable.idl index 7c37283480ee..00c8edd905cf 100644 --- a/js/src/xpconnect/idl/nsIXPCScriptable.idl +++ b/js/src/xpconnect/idl/nsIXPCScriptable.idl @@ -41,6 +41,8 @@ #include "nsISupports.idl" #include "nsIXPConnect.idl" +[ptr] native JSTracerPtr(JSTracer); + %{ C++ #define NS_SUCCESS_I_DID_SOMETHING \ (NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XPCONNECT,1)) diff --git a/js/src/xpconnect/idl/nsIXPConnect.idl b/js/src/xpconnect/idl/nsIXPConnect.idl index a523c7c7c104..beecc437481a 100644 --- a/js/src/xpconnect/idl/nsIXPConnect.idl +++ b/js/src/xpconnect/idl/nsIXPConnect.idl @@ -64,7 +64,7 @@ native JSVal(jsval); native JSID(jsid); [ptr] native voidPtrPtr(void*); -[ptr] native JSTracerPtr(JSTracer); +[ptr] native nsScriptObjectTracerPtr(nsScriptObjectTracer); /***************************************************************************/ @@ -150,7 +150,7 @@ interface nsIXPCSecurityManager; interface nsIPrincipal; %{C++ -class nsCycleCollectionTraversalCallback; +class nsScriptObjectTracer; %} /***************************************************************************/ @@ -443,7 +443,7 @@ interface nsIXPCFunctionThisTranslator : nsISupports { 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } } %} -[uuid(52fc2ff3-c0ea-46c1-9105-655283c361ff)] +[uuid(3eb7f5fc-1325-43af-aead-6033162e04af)] interface nsIXPConnect : nsISupports { %{ C++ @@ -727,4 +727,18 @@ interface nsIXPConnect : nsISupports [noscript] JSVal getCrossOriginWrapperForObject(in JSContextPtr aJSContext, in JSObjectPtr aParent, in JSObjectPtr aWrappedObj); + + /** + * Root JS objects held by aHolder. + * @param aHolder The object that hold the JS objects that should be rooted. + * @param aTrace The tracer for aHolder. + */ + [noscript] void addJSHolder(in voidPtr aHolder, + in nsScriptObjectTracerPtr aTracer); + + /** + * Stop rooting the JS objects held by aHolder. + * @param aHolder The object that hold the rooted JS objects. + */ + [noscript] void removeJSHolder(in voidPtr aHolder); }; diff --git a/js/src/xpconnect/shell/xpcshell.cpp b/js/src/xpconnect/shell/xpcshell.cpp index 589bca7d675e..d4903f61efd2 100644 --- a/js/src/xpconnect/shell/xpcshell.cpp +++ b/js/src/xpconnect/shell/xpcshell.cpp @@ -1161,7 +1161,8 @@ FullTrustSecMan::CheckSameOrigin(JSContext * aJSContext, nsIURI *aTargetURI) /* void checkSameOriginURI (in nsIURI aSourceURI, in nsIURI aTargetURI); */ NS_IMETHODIMP -FullTrustSecMan::CheckSameOriginURI(nsIURI *aSourceURI, nsIURI *aTargetURI) +FullTrustSecMan::CheckSameOriginURI(nsIURI *aSourceURI, nsIURI *aTargetURI, + PRBool reportError) { return NS_OK; } diff --git a/js/src/xpconnect/src/nsXPConnect.cpp b/js/src/xpconnect/src/nsXPConnect.cpp index 91e9f94551dd..6a6edec25c6a 100644 --- a/js/src/xpconnect/src/nsXPConnect.cpp +++ b/js/src/xpconnect/src/nsXPConnect.cpp @@ -534,10 +534,7 @@ void XPCMarkNotification(void *thing, uint8 flags, void *closure) { // XXX This can't deal with JS atoms yet, but probably should. uint8 ty = flags & GCF_TYPEMASK; - if(ty != GCX_OBJECT && - ty != GCX_NAMESPACE && - ty != GCX_QNAME && - ty != GCX_XML) + if(ty == GCX_FUNCTION) return; JSObjectRefcounts* jsr = static_cast(closure); @@ -695,16 +692,31 @@ NoteJSChild(JSTracer *trc, void *thing, uint32 kind) static uint8 GCTypeToTraceKindMap[GCX_NTYPES] = { JSTRACE_OBJECT, /* GCX_OBJECT */ - JSTRACE_STRING, /* GCX_STRING (unused) */ - JSTRACE_DOUBLE, /* GCX_DOUBLE (unused) */ - JSTRACE_STRING, /* GCX_MUTABLE_STRING (unused) */ - JSTRACE_FUNCTION, /* GCX_FUNCTION (unused) */ + JSTRACE_STRING, /* GCX_STRING */ + JSTRACE_DOUBLE, /* GCX_DOUBLE */ + JSTRACE_FUNCTION, /* GCX_FUNCTION */ JSTRACE_NAMESPACE, /* GCX_NAMESPACE */ JSTRACE_QNAME, /* GCX_QNAME */ - JSTRACE_XML /* GCX_XML */ - // We don't care about JSTRACE_STRING, so stop here + JSTRACE_XML, /* GCX_XML */ + (uint8)-1, /* unused */ + JSTRACE_STRING, /* GCX_EXTERNAL_STRING + 0 */ + JSTRACE_STRING, /* GCX_EXTERNAL_STRING + 1 */ + JSTRACE_STRING, /* GCX_EXTERNAL_STRING + 2 */ + JSTRACE_STRING, /* GCX_EXTERNAL_STRING + 3 */ + JSTRACE_STRING, /* GCX_EXTERNAL_STRING + 4 */ + JSTRACE_STRING, /* GCX_EXTERNAL_STRING + 5 */ + JSTRACE_STRING, /* GCX_EXTERNAL_STRING + 6 */ + JSTRACE_STRING, /* GCX_EXTERNAL_STRING + 7 */ }; +// static +uint8 +nsXPConnect::GetTraceKind(void *thing) +{ + uint8 type = *js_GetGCThingFlags(thing) & GCF_TYPEMASK; + return GCTypeToTraceKindMap[type]; +} + NS_IMETHODIMP nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb) { @@ -716,11 +728,6 @@ nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb) PRUint32 refcount = mObjRefcounts->Get(p); NS_ASSERTION(refcount > 0, "JS object but unknown to the JS GC?"); - uint8 ty = *js_GetGCThingFlags(p) & GCF_TYPEMASK; - if(ty != GCX_OBJECT && ty != GCX_NAMESPACE && ty != GCX_QNAME && - ty != GCX_XML) - return NS_OK; - #ifdef DEBUG_CC if(ty == GCX_OBJECT) { @@ -826,6 +833,11 @@ nsXPConnect::Traverse(void *p, nsCycleCollectionTraversalCallback &cb) cb.DescribeNode(refcount); #endif + uint8 ty = GetTraceKind(p); + if(ty != GCX_OBJECT && ty != GCX_NAMESPACE && ty != GCX_QNAME && + ty != GCX_XML) + return NS_OK; + ContextCallbackItem trc; trc.cb = &cb; @@ -2097,6 +2109,18 @@ nsXPConnect::OnDispatchedEvent(nsIThreadInternal* aThread) return NS_ERROR_UNEXPECTED; } +NS_IMETHODIMP +nsXPConnect::AddJSHolder(void* aHolder, nsScriptObjectTracer* aTracer) +{ + return mRuntime->AddJSHolder(aHolder, aTracer); +} + +NS_IMETHODIMP +nsXPConnect::RemoveJSHolder(void* aHolder) +{ + return mRuntime->RemoveJSHolder(aHolder); +} + #ifdef DEBUG /* These are here to be callable from a debugger */ JS_BEGIN_EXTERN_C diff --git a/js/src/xpconnect/src/xpcconvert.cpp b/js/src/xpconnect/src/xpcconvert.cpp index 395983bb626b..c5e30bc985a8 100644 --- a/js/src/xpconnect/src/xpcconvert.cpp +++ b/js/src/xpconnect/src/xpcconvert.cpp @@ -1479,14 +1479,14 @@ XPCConvert::JSValToXPCException(XPCCallContext& ccx, } else { - number = *(JSVAL_TO_DOUBLE(s)); - if(number > 0.0 && - number < (double)0xffffffff && - 0.0 == fmod(number,1)) - { - rv = (nsresult) number; - if(NS_FAILED(rv)) - isResult = JS_TRUE; + number = *(JSVAL_TO_DOUBLE(s)); + if(number > 0.0 && + number < (double)0xffffffff && + 0.0 == fmod(number,1)) + { + rv = (nsresult) number; + if(NS_FAILED(rv)) + isResult = JS_TRUE; } } diff --git a/js/src/xpconnect/src/xpcjsruntime.cpp b/js/src/xpconnect/src/xpcjsruntime.cpp index b02612fc5ad7..ced529b9ae79 100644 --- a/js/src/xpconnect/src/xpcjsruntime.cpp +++ b/js/src/xpconnect/src/xpcjsruntime.cpp @@ -251,6 +251,42 @@ ContextCallback(JSContext *cx, uintN operation) : JS_TRUE; } +struct ObjectHolder : public JSDHashEntryHdr +{ + void *holder; + nsScriptObjectTracer* tracer; +}; + +nsresult +XPCJSRuntime::AddJSHolder(void* aHolder, nsScriptObjectTracer* aTracer) +{ + if(!mJSHolders.ops) + return NS_ERROR_OUT_OF_MEMORY; + + ObjectHolder *entry = + reinterpret_cast(JS_DHashTableOperate(&mJSHolders, + aHolder, + JS_DHASH_ADD)); + if(!entry) + return NS_ERROR_OUT_OF_MEMORY; + + entry->holder = aHolder; + entry->tracer = aTracer; + + return NS_OK; +} + +nsresult +XPCJSRuntime::RemoveJSHolder(void* aHolder) +{ + if(!mJSHolders.ops) + return NS_ERROR_OUT_OF_MEMORY; + + JS_DHashTableOperate(&mJSHolders, aHolder, JS_DHASH_REMOVE); + + return NS_OK; +} + // static void XPCJSRuntime::TraceJS(JSTracer* trc, void* data) { @@ -277,16 +313,48 @@ void XPCJSRuntime::TraceJS(JSTracer* trc, void* data) } } - XPCWrappedNativeScope::TraceJS(trc, self); + // XPCJSObjectHolders don't participate in cycle collection, so always trace + // them here. + for(XPCRootSetElem *e = self->mObjectHolderRoots; e ; e = e->GetNextRoot()) + static_cast(e)->TraceJS(trc); + + self->TraceXPConnectRoots(trc); +} - for (XPCRootSetElem *e = self->mVariantRoots; e ; e = e->GetNextRoot()) +PR_STATIC_CALLBACK(void) +TraceJSObject(PRUint32 aLangID, void *aScriptThing, void *aClosure) +{ + if(aLangID == nsIProgrammingLanguage::JAVASCRIPT) + { + JS_CALL_TRACER(static_cast(aClosure), aScriptThing, + nsXPConnect::GetXPConnect()->GetTraceKind(aScriptThing), + "JSObjectHolder"); + } +} + +JS_STATIC_DLL_CALLBACK(JSDHashOperator) +TraceJSHolder(JSDHashTable *table, JSDHashEntryHdr *hdr, uint32 number, + void *arg) +{ + ObjectHolder* entry = reinterpret_cast(hdr); + + entry->tracer->Trace(entry->holder, TraceJSObject, arg); + + return JS_DHASH_NEXT; +} + +void XPCJSRuntime::TraceXPConnectRoots(JSTracer *trc) +{ + XPCWrappedNativeScope::TraceJS(trc, this); + + for(XPCRootSetElem *e = mVariantRoots; e ; e = e->GetNextRoot()) static_cast(e)->TraceJS(trc); - for (XPCRootSetElem *e = self->mWrappedJSRoots; e ; e = e->GetNextRoot()) + for(XPCRootSetElem *e = mWrappedJSRoots; e ; e = e->GetNextRoot()) static_cast(e)->TraceJS(trc); - for (XPCRootSetElem *e = self->mObjectHolderRoots; e ; e = e->GetNextRoot()) - static_cast(e)->TraceJS(trc); + if(mJSHolders.ops) + JS_DHashTableEnumerate(&mJSHolders, TraceJSHolder, trc); } // static @@ -809,6 +877,12 @@ XPCJSRuntime::~XPCJSRuntime() gOldJSGCCallback = NULL; gOldJSContextCallback = NULL; + + if(mJSHolders.ops) + { + JS_DHashTableFinish(&mJSHolders); + mJSHolders.ops = nsnull; + } } XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect, @@ -862,6 +936,10 @@ XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect, JS_SetExtraGCRoots(mJSRuntime, TraceJS, this); } + if(!JS_DHashTableInit(&mJSHolders, JS_DHashGetStubOps(), nsnull, + sizeof(ObjectHolder), 512)) + mJSHolders.ops = nsnull; + // Install a JavaScript 'debugger' keyword handler in debug builds only #ifdef DEBUG if(mJSRuntime && !JS_GetGlobalDebugHooks(mJSRuntime)->debuggerHandler) diff --git a/js/src/xpconnect/src/xpcprivate.h b/js/src/xpconnect/src/xpcprivate.h index 0bcc64caaf14..31ed95b2e080 100644 --- a/js/src/xpconnect/src/xpcprivate.h +++ b/js/src/xpconnect/src/xpcprivate.h @@ -498,6 +498,9 @@ public: #endif JSObjectRefcounts* GetJSObjectRefcounts() {return mObjRefcounts;} + + static uint8 GetTraceKind(void *thing); + #ifndef XPCONNECT_STANDALONE void RecordTraversal(void *p, nsISupports *s); #endif @@ -676,6 +679,9 @@ public: } static void JS_DLL_CALLBACK TraceJS(JSTracer* trc, void* data); + void TraceXPConnectRoots(JSTracer *trc); + void AddXPConnectRoots(JSContext* cx, + nsCycleCollectionTraversalCallback& cb); static JSBool JS_DLL_CALLBACK GCCallback(JSContext *cx, JSGCStatus status); @@ -683,6 +689,9 @@ public: inline void AddWrappedJSRoot(nsXPCWrappedJS* wrappedJS); inline void AddObjectHolderRoot(XPCJSObjectHolder* holder); + nsresult AddJSHolder(void* aHolder, nsScriptObjectTracer* aTracer); + nsresult RemoveJSHolder(void* aHolder); + void DebugDump(PRInt16 depth); void SystemIsBeingShutDown(JSContext* cx); @@ -746,6 +755,7 @@ private: XPCRootSetElem *mVariantRoots; XPCRootSetElem *mWrappedJSRoots; XPCRootSetElem *mObjectHolderRoots; + JSDHashTable mJSHolders; }; /***************************************************************************/ @@ -1191,8 +1201,6 @@ public: static void InitStatics() { gScopes = nsnull; gDyingScopes = nsnull; } - void Traverse(nsCycleCollectionTraversalCallback &cb); - #ifndef XPCONNECT_STANDALONE /** * Fills the hash mapping global object to principal. @@ -1931,10 +1939,11 @@ private: class XPCWrappedNative : public nsIXPConnectWrappedNative { public: - NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_ISUPPORTS NS_DECL_NSIXPCONNECTJSOBJECTHOLDER NS_DECL_NSIXPCONNECTWRAPPEDNATIVE NS_DECL_CYCLE_COLLECTION_CLASS(XPCWrappedNative) + NS_DECL_CYCLE_COLLECTION_UNMARK_PURPLE_STUB(XPCWrappedNative) #ifndef XPCONNECT_STANDALONE virtual nsIPrincipal* GetObjectPrincipal() const; @@ -2044,7 +2053,7 @@ public: nsISupports* aCOMObj, XPCWrappedNative** aWrapper); - void FlatJSObjectFinalized(JSContext *cx, JSObject *obj); + void FlatJSObjectFinalized(JSContext *cx); void SystemIsBeingShutDown(JSContext* cx); @@ -2196,8 +2205,10 @@ private: XPCWrappedNativeTearOffChunk mFirstChunk; JSObject* mWrapper; +#ifdef XPC_CHECK_WRAPPER_THREADSAFETY public: nsCOMPtr mThread; // Don't want to overload _mOwningThread +#endif }; /*************************************************************************** @@ -3028,7 +3039,6 @@ private: JSUint32 mWrappedNativeThreadsafetyReportDepth; #endif PRThread* mThread; - nsVoidArray mNativesToReleaseArray; static PRLock* gLock; static XPCPerThreadData* gThreads; diff --git a/js/src/xpconnect/src/xpcwrappedjs.cpp b/js/src/xpconnect/src/xpcwrappedjs.cpp index 32cd5edcf712..8eed14c1d4fc 100644 --- a/js/src/xpconnect/src/xpcwrappedjs.cpp +++ b/js/src/xpconnect/src/xpcwrappedjs.cpp @@ -589,10 +589,6 @@ nsXPCWrappedJS::SystemIsBeingShutDown(JSRuntime* rt) // work (and avoid crashing some platforms). mJSObj = nsnull; - // There is no reason to keep this root any longer. Since we've cleared - // mJSObj our dtor will not remove the root later. So, we do it now. - JS_RemoveRootRT(rt, &mJSObj); - // Notify other wrappers in the chain. if(mNext) mNext->SystemIsBeingShutDown(rt); diff --git a/js/src/xpconnect/src/xpcwrappedjsclass.cpp b/js/src/xpconnect/src/xpcwrappedjsclass.cpp index faacc2ba7296..dc61c443822b 100644 --- a/js/src/xpconnect/src/xpcwrappedjsclass.cpp +++ b/js/src/xpconnect/src/xpcwrappedjsclass.cpp @@ -112,18 +112,16 @@ AutoScriptEvaluate::~AutoScriptEvaluate() // function is factored out to manage that. JSBool xpc_IsReportableErrorCode(nsresult code) { - if(NS_SUCCEEDED(code)) - return JS_FALSE; - switch(code) { - // Error codes that we don't want to report as errors... - // These generally indicate bad interface design AFAIC. - case NS_ERROR_FACTORY_REGISTER_AGAIN: - case NS_BASE_STREAM_WOULD_BLOCK: - return JS_FALSE; + case NS_ERROR_XPC_JS_THREW_NULL: + case NS_ERROR_XPC_JS_THREW_JS_OBJECT: + case NS_ERROR_XPC_JS_THREW_NATIVE_OBJECT: + case NS_ERROR_XPC_JAVASCRIPT_ERROR_WITH_DETAILS: + case NS_ERROR_XPC_JAVASCRIPT_ERROR: + return JS_TRUE; } - return JS_TRUE; + return JS_FALSE; } // static diff --git a/js/src/xpconnect/src/xpcwrappednative.cpp b/js/src/xpconnect/src/xpcwrappednative.cpp index 2b1d3e88b820..ed78d2add53a 100644 --- a/js/src/xpconnect/src/xpcwrappednative.cpp +++ b/js/src/xpconnect/src/xpcwrappednative.cpp @@ -961,7 +961,7 @@ NS_IMPL_THREADSAFE_RELEASE(XPCWrappedNative) */ void -XPCWrappedNative::FlatJSObjectFinalized(JSContext *cx, JSObject *obj) +XPCWrappedNative::FlatJSObjectFinalized(JSContext *cx) { if(!IsValid()) return; diff --git a/js/src/xpconnect/src/xpcwrappednativejsops.cpp b/js/src/xpconnect/src/xpcwrappednativejsops.cpp index 32d084a7cb6f..674e457af3c8 100644 --- a/js/src/xpconnect/src/xpcwrappednativejsops.cpp +++ b/js/src/xpconnect/src/xpcwrappednativejsops.cpp @@ -647,7 +647,7 @@ XPC_WN_NoHelper_Finalize(JSContext *cx, JSObject *obj) XPCWrappedNative* p = (XPCWrappedNative*) JS_GetPrivate(cx, obj); if(!p) return; - p->FlatJSObjectFinalized(cx, obj); + p->FlatJSObjectFinalized(cx); } static void @@ -658,7 +658,7 @@ TraceScopeJSObjects(JSTracer *trc, XPCWrappedNativeScope* scope) JSObject* obj; obj = scope->GetGlobalJSObject(); - NS_ASSERTION(scope, "bad scope JSObject"); + NS_ASSERTION(obj, "bad scope JSObject"); JS_CALL_OBJECT_TRACER(trc, obj, "XPCWrappedNativeScope::mGlobalJSObject"); obj = scope->GetPrototypeJSObject(); @@ -1035,7 +1035,7 @@ XPC_WN_Helper_Finalize(JSContext *cx, JSObject *obj) if(!wrapper) return; wrapper->GetScriptableCallback()->Finalize(wrapper, cx, obj); - wrapper->FlatJSObjectFinalized(cx, obj); + wrapper->FlatJSObjectFinalized(cx); } JS_STATIC_DLL_CALLBACK(void) diff --git a/js/src/xpconnect/src/xpcwrappednativescope.cpp b/js/src/xpconnect/src/xpcwrappednativescope.cpp index ea9c5b6d588f..e167780f0167 100644 --- a/js/src/xpconnect/src/xpcwrappednativescope.cpp +++ b/js/src/xpconnect/src/xpcwrappednativescope.cpp @@ -851,16 +851,6 @@ XPCWrappedNativeScope::DebugDump(PRInt16 depth) #endif } -void -XPCWrappedNativeScope::Traverse(nsCycleCollectionTraversalCallback &cb) -{ - // See TraceScopeJSObjects. - cb.NoteScriptChild(nsIProgrammingLanguage::JAVASCRIPT, mGlobalJSObject); - cb.NoteScriptChild(nsIProgrammingLanguage::JAVASCRIPT, mPrototypeJSObject); - cb.NoteScriptChild(nsIProgrammingLanguage::JAVASCRIPT, - mPrototypeJSFunction); -} - #ifndef XPCONNECT_STANDALONE // static void diff --git a/js/tests/js1_5/GC/regress-390078.js b/js/tests/js1_5/GC/regress-390078.js new file mode 100755 index 000000000000..0528120b4912 --- /dev/null +++ b/js/tests/js1_5/GC/regress-390078.js @@ -0,0 +1,69 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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 JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2007 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Igor Bukanov + * + * 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 ***** */ + +var gTestfile = 'regress-390078.js'; + +//----------------------------------------------------------------------------- +var BUGNUMBER = 390078; +var summary = 'GC hazard with JSstackFrame.argv[-1]'; +var actual = 'No Crash'; +var expect = 'No Crash'; + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + var a = new Array(10*1000); + a[0] = { toString: function() { gc(); return ".*9"; }};; + a[1] = "g"; + + for (var i = 0; i != 10*1000; ++i) { + String(new Number(123456789)); + } + + "".match.apply(123456789, a); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_7/extensions/regress-387955-01.js b/js/tests/js1_7/extensions/regress-387955-01.js new file mode 100755 index 000000000000..14c92bb74c0c --- /dev/null +++ b/js/tests/js1_7/extensions/regress-387955-01.js @@ -0,0 +1,73 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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 JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2007 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jesse Ruderman + * + * 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 ***** */ + +var gTestfile = 'regress-387955-01.js'; + +//----------------------------------------------------------------------------- +var BUGNUMBER = 387955; +var summary = 'Do not Crash [@ JS_CallTracer]'; +var actual = 'No Crash'; +var expect = 'No Crash'; + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + var fal = false; + + function gen() { + let x; + function y(){} + this.__defineGetter__('', function(){}); + if (fal) + yield; + } + + for (var i in gen()) { } + + gc(); + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/js1_7/extensions/regress-387955-02.js b/js/tests/js1_7/extensions/regress-387955-02.js new file mode 100755 index 000000000000..121226e440d4 --- /dev/null +++ b/js/tests/js1_7/extensions/regress-387955-02.js @@ -0,0 +1,75 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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 JavaScript Engine testing utilities. + * + * The Initial Developer of the Original Code is + * Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2007 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): Jesse Ruderman + * Igor Bukanov + * + * 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 ***** */ + +var gTestfile = 'regress-387955.js'; + +//----------------------------------------------------------------------------- +var BUGNUMBER = 387955; +var summary = 'Do not Crash [@ JS_CallTracer]'; +var actual = 'No Crash'; +var expect = 'No Crash'; + +//----------------------------------------------------------------------------- +test(); +//----------------------------------------------------------------------------- + +function test() +{ + enterFunc ('test'); + printBugNumber(BUGNUMBER); + printStatus (summary); + + var f; + + function gen(yield_at_least_once) { + let x = 11; + function y(){} + f = function(){ return x; }; + if (yield_at_least_once) + yield; + } + + for (var i in gen()) { } + + if (f() !== 11) + throw "unexpected value of local x"; + + reportCompare(expect, actual, summary); + + exitFunc ('test'); +} diff --git a/js/tests/known-failures.pl b/js/tests/known-failures.pl index b15a21a661f2..3548e4d337ff 100755 --- a/js/tests/known-failures.pl +++ b/js/tests/known-failures.pl @@ -227,7 +227,7 @@ foreach $fix (@fixes) { } close OUTPUT; -print STDOUT "$outputprefix-results-possible-fixes.log\n"; +print STDOUT "log: $outputprefix-results-possible-fixes.log\n"; debug "finding regressions"; @@ -292,7 +292,7 @@ foreach $failure (@failures) { } close OUTPUT; -print STDOUT "$outputprefix-results-possible-regressions.log\n"; +print STDOUT "log: $outputprefix-results-possible-regressions.log\n"; sub debug { diff --git a/js/tests/public-failures.txt b/js/tests/public-failures.txt index a1b95ac42e07..5d29ee96a087 100644 --- a/js/tests/public-failures.txt +++ b/js/tests/public-failures.txt @@ -40,7 +40,7 @@ TEST_ID=e4x/XML/regress-376773.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_B TEST_ID=e4x/XML/regress-376773.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=(linux|mac), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION= expected: Expected exit 0 actual: Actual exit 3, signal 0 reason: BUGNUMBER: 376773 STATUS: xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 1 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 2 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 3 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 4 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 5 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 6 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 7 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 8 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 9 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 10 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 11 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 12 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 13 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 14 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 15 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 16 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 17 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 18 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 19 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 20 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 21 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 22 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 23 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 24 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 25 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 26 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 27 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 28 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 29 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 30 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 31 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 32 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 33 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 34 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 35 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 36 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 37 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 38 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 39 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 40 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 41 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 42 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 43 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 44 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 45 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Sectio./e4x/XML/regress-376773.js:`[`0`-`9`]``+`: ReferenceError: reference to undefined XML name @mozilla.org/js/function::charAt n 46 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 47 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 48 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 49 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 50 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 51 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 52 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 53 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 54 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 55 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 56 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 57 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 58 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 59 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 60 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 61 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod TEST_ID=e4x/XML/regress-376773.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION= expected: Expected exit 0 actual: Actual exit 3, signal 0 reason: BUGNUMBER: 376773 STATUS: xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 1 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 2 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 3 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 4 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 5 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 6 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 7 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 8 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 9 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 10 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 11 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 12 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 13 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 14 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 15 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 16 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 17 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 18 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 19 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 20 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 21 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 22 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 23 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 24 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 25 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 26 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 27 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 28 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 29 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 30 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 31 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 32 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 33 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 34 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 35 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 36 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 37 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 38 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 39 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 40 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 41 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 42 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 43 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 44 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 45 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 46 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 47 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 48 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 49 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 50 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 51 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 52 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 53 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 54 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 55 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 56 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 57 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 58 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 59 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 60 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod PASSED! Section 61 of test - xmlsimple.stringmethod === xmlsimple.function::stringmethod TEST_ID=e4x/decompilation/decompile-xml-escapes.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Section 1 of test - Decompiler escapes line breaks/backslashes in E4X literals expected: false actual: 'function anonymous() {NL return ;NL}' does not contain ''! reason: Type mismatch, expected type boolean, actual type string Expected value 'false', Actual value ''function anonymous() {NL return ;NL}' does not contain ''!' -TEST_ID=e4x/decompilation/decompile-xml-escapes.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=opt, TEST_TYPE=browser, TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=2.6.20.*fc6, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=EXIT STATUS: TIMED OUT (900 seconds), +TEST_ID=e4x/decompilation/decompile-xml-escapes.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=opt, TEST_TYPE=browser, TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=2.6.20.*fc6, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=EXIT STATUS: TIMED OUT (900 seconds), TEST_ID=e4x/decompilation/decompile-xml-escapes.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Section 1 of test - Decompiler escapes line breaks/backslashes in E4X literals expected: false actual: 'function anonymous() {NL return ;NL}' does not contain ''! reason: Type mismatch, expected type boolean, actual type string Expected value 'false', Actual value ''function anonymous() {NL return ;NL}' does not contain ''!' TEST_ID=e4x/decompilation/regress-352013.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Section 11 of test - Decompilation with new operator redeaux expected: function ( ) { new ( x ( y ) . n : : z ) ; } actual: function ( ) { new x ( y ) . n : : z ; } reason: Expected value ' function ( ) { new ( x ( y ) . n : : z ) ; } ', Actual value ' function ( ) { new x ( y ) . n : : z ; } ' TEST_ID=e4x/decompilation/regress-352013.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Section 12 of test - Decompilation with new operator redeaux expected: function ( ) { new ( x ( y ) . n : : z ) ; } actual: function ( ) { new x ( y ) . n : : z ; } reason: Expected value ' function ( ) { new ( x ( y ) . n : : z ) ; } ', Actual value ' function ( ) { new x ( y ) . n : : z ; } ' @@ -58,44 +58,26 @@ TEST_ID=e4x/extensions/regress-312196.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_ID=e4x/extensions/regress-337226.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=browser, TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=function::globalfunction Section expected: actual: error reason: reference to undefined XML name @mozilla.org/js/function::parseInt Page: http://`.``*`/e4x/extensions/regress-337226.js Line: `[`0`-`9`]``+` TEST_ID=e4x/extensions/regress-337226.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=(linux|mac), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION= expected: Expected exit 0 actual: Actual exit 3, signal 0 reason: ./e4x/extensions/regress-337226.js:`[`0`-`9`]``+`: ReferenceError: reference to undefined XML name @mozilla.org/js/function::parseInt BUGNUMBER: 337226 STATUS: function::globalfunction TEST_ID=e4x/extensions/regress-337226.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION= expected: Expected exit 0 actual: Actual exit 3, signal 0 reason: BUGNUMBER: 337226 STATUS: function::globalfunction ./e4x/extensions/regress-337226.js:`[`0`-`9`]``+`: ReferenceError: reference to undefined XML name @mozilla.org/js/function::parseInt -TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=(2.6.18.*el5PAE|2.6.20.*fc6|2.6.22.*fc6).*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getDate() expected: 2 actual: 1 reason: wrong value -TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=(2.6.18.*el5PAE|2.6.20.*fc6|2.6.22.*fc6).*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getDay() expected: 3 actual: 2 reason: wrong value -TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=(2.6.18.*el5PAE|2.6.20.*fc6|2.6.22.*fc6).*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getHours() expected: 0 actual: 23 reason: wrong value -TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=2.6.9.*ELsmp, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getHours() expected: 3 actual: 2 reason: wrong value -TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=mac, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i386, TEST_KERNEL=8.10.1, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getDate() expected: 2 actual: 1 reason: wrong value -TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=mac, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i386, TEST_KERNEL=8.10.1, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getDay() expected: 3 actual: 2 reason: wrong value -TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=mac, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i386, TEST_KERNEL=8.10.1, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getHours() expected: 0 actual: 23 reason: wrong value -TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=mac, TEST_MACHINE=.*, TEST_PROCESSORTYPE=powerpc, TEST_KERNEL=8.10.0, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getHours() expected: 3 actual: 2 reason: wrong value -TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=browser, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=unknown, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getHours() expected: 3 actual: 2 reason: wrong value -TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=(2.6.18.*el5PAE|2.6.20.*fc6|2.6.22.*fc6).*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getHours() expected: 3 actual: 2 reason: wrong value -TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=debug, TEST_TYPE=browser, TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=(2.6.18.*el5PAE|2.6.20.*fc6|2.6.22.*fc6).*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getHours() expected: 3 actual: 2 reason: wrong value -TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=(athlon|i686), TEST_KERNEL=2.6.9.*ELsmp, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getDate() expected: 2 actual: 1 reason: wrong value -TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=(athlon|i686), TEST_KERNEL=2.6.9.*ELsmp, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getDay() expected: 3 actual: 2 reason: wrong value -TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=(athlon|i686), TEST_KERNEL=2.6.9.*ELsmp, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getHours() expected: 0 actual: 23 reason: wrong value -TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=browser, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=unknown, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getDate() expected: 2 actual: 1 reason: wrong value -TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=browser, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=unknown, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getDay() expected: 3 actual: 2 reason: wrong value -TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=browser, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=unknown, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getHours() expected: 0 actual: 23 reason: wrong value -TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=athlon, TEST_KERNEL=2.6.9.*ELsmp, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getHours() expected: 3 actual: 2 reason: wrong value -TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=mac, TEST_MACHINE=.*, TEST_PROCESSORTYPE=powerpc, TEST_KERNEL=8.10.0, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getDate() expected: 2 actual: 1 reason: wrong value -TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=mac, TEST_MACHINE=.*, TEST_PROCESSORTYPE=powerpc, TEST_KERNEL=8.10.0, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getDay() expected: 3 actual: 2 reason: wrong value -TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=mac, TEST_MACHINE=.*, TEST_PROCESSORTYPE=powerpc, TEST_KERNEL=8.10.0, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getHours() expected: 0 actual: 23 reason: wrong value -TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=opt, TEST_TYPE=browser, TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=2.6.18.*el5PAE, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getHours() expected: 3 actual: 2 reason: wrong value -TEST_ID=ecma/Date/15.9.5.35-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=(2.6.18.*el5PAE|2.6.20.*fc6|2.6.22.*fc6).*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(0);(TDATE).setUTCMonth(3,4);TDATE.getHours() expected: 17 actual: 16 reason: wrong value -TEST_ID=ecma/Date/15.9.5.35-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=2.6.9.*ELsmp, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=TDATE = new Date(0);(TDATE).setUTCMonth(3,4);TDATE.getHours() expected: 20 actual: 19 reason: wrong value -TEST_ID=ecma/Date/15.9.5.35-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=mac, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i386, TEST_KERNEL=8.10.1, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(0);(TDATE).setUTCMonth(3,4);TDATE.getHours() expected: 17 actual: 16 reason: wrong value -TEST_ID=ecma/Date/15.9.5.35-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=mac, TEST_MACHINE=.*, TEST_PROCESSORTYPE=powerpc, TEST_KERNEL=8.10.0, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=TDATE = new Date(0);(TDATE).setUTCMonth(3,4);TDATE.getHours() expected: 20 actual: 19 reason: wrong value -TEST_ID=ecma/Date/15.9.5.35-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=browser, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=unknown, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=TDATE = new Date(0);(TDATE).setUTCMonth(3,4);TDATE.getHours() expected: 20 actual: 19 reason: wrong value -TEST_ID=ecma/Date/15.9.5.35-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=(2.6.18.*el5PAE|2.6.20.*fc6|2.6.22.*fc6).*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=TDATE = new Date(0);(TDATE).setUTCMonth(3,4);TDATE.getHours() expected: 20 actual: 19 reason: wrong value -TEST_ID=ecma/Date/15.9.5.35-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=debug, TEST_TYPE=browser, TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=(2.6.18.*el5PAE|2.6.20.*fc6|2.6.22.*fc6).*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=TDATE = new Date(0);(TDATE).setUTCMonth(3,4);TDATE.getHours() expected: 20 actual: 19 reason: wrong value -TEST_ID=ecma/Date/15.9.5.35-1.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=(athlon|i686), TEST_KERNEL=2.6.9.*ELsmp, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(0);(TDATE).setUTCMonth(3,4);TDATE.getHours() expected: 17 actual: 16 reason: wrong value -TEST_ID=ecma/Date/15.9.5.35-1.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=browser, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=unknown, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(0);(TDATE).setUTCMonth(3,4);TDATE.getHours() expected: 17 actual: 16 reason: wrong value -TEST_ID=ecma/Date/15.9.5.35-1.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=athlon, TEST_KERNEL=2.6.9.*ELsmp, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=TDATE = new Date(0);(TDATE).setUTCMonth(3,4);TDATE.getHours() expected: 20 actual: 19 reason: wrong value -TEST_ID=ecma/Date/15.9.5.35-1.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=mac, TEST_MACHINE=.*, TEST_PROCESSORTYPE=powerpc, TEST_KERNEL=8.10.0, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(0);(TDATE).setUTCMonth(3,4);TDATE.getHours() expected: 17 actual: 16 reason: wrong value -TEST_ID=ecma/Date/15.9.5.35-1.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=opt, TEST_TYPE=browser, TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=2.6.18.*el5PAE, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=TDATE = new Date(0);(TDATE).setUTCMonth(3,4);TDATE.getHours() expected: 20 actual: 19 reason: wrong value +TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=(linux|mac), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getHours() expected: 3 actual: 2 reason: wrong value +TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=(linux|mac), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getDate() expected: 2 actual: 1 reason: wrong value +TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=(linux|mac), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getDay() expected: 3 actual: 2 reason: wrong value +TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=(linux|mac), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getHours() expected: 0 actual: 23 reason: wrong value +TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=browser, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getHours() expected: 3 actual: 2 reason: wrong value +TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=browser, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getDate() expected: 2 actual: 1 reason: wrong value +TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=browser, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getDay() expected: 3 actual: 2 reason: wrong value +TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=browser, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getHours() expected: 0 actual: 23 reason: wrong value +TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=debug, TEST_TYPE=browser, TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getHours() expected: 3 actual: 2 reason: wrong value +TEST_ID=ecma/Date/15.9.5.31-1.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=opt, TEST_TYPE=browser, TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=TDATE = new Date(946684800000);(TDATE).setUTCHours(1234567);TDATE.getHours() expected: 3 actual: 2 reason: wrong value +TEST_ID=ecma/Date/15.9.5.35-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=(linux|mac), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=TDATE = new Date(0);(TDATE).setUTCMonth(3,4);TDATE.getHours() expected: 20 actual: 19 reason: wrong value +TEST_ID=ecma/Date/15.9.5.35-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=(linux|mac), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(0);(TDATE).setUTCMonth(3,4);TDATE.getHours() expected: 17 actual: 16 reason: wrong value +TEST_ID=ecma/Date/15.9.5.35-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=browser, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=TDATE = new Date(0);(TDATE).setUTCMonth(3,4);TDATE.getHours() expected: 20 actual: 19 reason: wrong value +TEST_ID=ecma/Date/15.9.5.35-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=browser, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=TDATE = new Date(0);(TDATE).setUTCMonth(3,4);TDATE.getHours() expected: 17 actual: 16 reason: wrong value +TEST_ID=ecma/Date/15.9.5.35-1.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=debug, TEST_TYPE=browser, TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=TDATE = new Date(0);(TDATE).setUTCMonth(3,4);TDATE.getHours() expected: 20 actual: 19 reason: wrong value +TEST_ID=ecma/Date/15.9.5.35-1.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=opt, TEST_TYPE=browser, TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=TDATE = new Date(0);(TDATE).setUTCMonth(3,4);TDATE.getHours() expected: 20 actual: 19 reason: wrong value TEST_ID=ecma/Math/15.8.2.5.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=debug, TEST_TYPE=browser, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Infinity/Math.atan2(-0, 1) expected: -Infinity actual: Infinity reason: wrong value TEST_ID=ecma/Math/15.8.2.5.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=debug, TEST_TYPE=browser, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Infinity/Math.atan2(-1, Infinity) expected: -Infinity actual: Infinity reason: wrong value TEST_ID=ecma/ObjectObjects/15.2.2.1.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=debug, TEST_TYPE=browser, TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=EXIT STATUS: TIMED OUT (`[`0`-`9`]``+` seconds), 15.2.2.1 new Object( value ); typeof new Object(null) = object; MYOB = new Object(null); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Object]; typeof new Object(void 0) = object; MYOB = new Object(new Object(void 0)); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Object]; typeof new Object('string') = object; MYOB = (new Object('string'); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object String]; (new Object('string').valueOf() = string; typeof new Object('') = object; MYOB = (new Object(''); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object String]; (new Object('').valueOf() =; typeof new Object(Number.NaN) = object; MYOB = (new Object(Number.NaN); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Number]; (new Object(Number.NaN).valueOf() = NaN; typeof new Object(0) = object; MYOB = (new Object(0); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Number]; (new Object(0).valueOf() = 0; typeof new Object(-0) = object; MYOB = (new Object(-0); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Number]; (new Object(-0).valueOf() = 0; typeof new Object(1) = object; MYOB = (new Object(1); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Number]; (new Object(1).valueOf() = 1; typeof new Object(-1) = object; MYOB = (new Object(-1); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Number]; (new Object(-1).valueOf() = -1; typeof new Object(true) = object; MYOB = (new Object(true); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Boolean]; (new Object(true).valueOf() = true; typeof new Object(false) = object; MYOB = (new Object(false); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Boolean]; (new Object(false).valueOf() = false; typeof new Object(Boolean()) = object; MYOB = (new Object(Boolean()); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Boolean]; (new Object(Boolean()).valueOf() = false; myglobal = new Object( this ) = [object Window @ 0x`[`0`-`9a`-`f`]``+` (native @ 0x`[`0`-`9a`-`f`]``+`)]; myobject = new Object('my new object'); new Object(myobject) = [object Object]; myarray = new Array(); new Object(myarray) =; myboolean = new Boolean(); new Object(myboolean) = false; mynumber = new Number(); new Object(mynumber) = 0; mystring = new String9); new Object(mystring) =; myobject = new Object(); new Object(mynobject) = [object Object]; myfunction = new Function(); new Object(myfunction) = function anonymous(x) {; return x;; }; mymath = Math; new Object(mymath) = [object Math]; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; JavaScript error: , line 0: uncaught exception: [Exception... "Unexpected error" nsresult: "0x8000ffff (NS_ERROR_UNEXPECTED)" location: "JS frame :: http://`.``*`shell.js :: toPrinted :: line `[`0`-`9`]``+`" data: no] -TEST_ID=ecma/ObjectObjects/15.2.2.1.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=opt, TEST_TYPE=browser, TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=EXIT STATUS: TIMED OUT (`[`0`-`9`]``+` seconds), 15.2.2.1 new Object( value ); typeof new Object(null) = object; MYOB = new Object(null); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Object]; typeof new Object(void 0) = object; MYOB = new Object(new Object(void 0)); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Object]; typeof new Object('string') = object; MYOB = (new Object('string'); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object String]; (new Object('string').valueOf() = string; typeof new Object('') = object; MYOB = (new Object(''); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object String]; (new Object('').valueOf() =; typeof new Object(Number.NaN) = object; MYOB = (new Object(Number.NaN); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Number]; (new Object(Number.NaN).valueOf() = NaN; typeof new Object(0) = object; MYOB = (new Object(0); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Number]; (new Object(0).valueOf() = 0; typeof new Object(-0) = object; MYOB = (new Object(-0); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Number]; (new Object(-0).valueOf() = 0; typeof new Object(1) = object; MYOB = (new Object(1); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Number]; (new Object(1).valueOf() = 1; typeof new Object(-1) = object; MYOB = (new Object(-1); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Number]; (new Object(-1).valueOf() = -1; typeof new Object(true) = object; MYOB = (new Object(true); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Boolean]; (new Object(true).valueOf() = true; typeof new Object(false) = object; MYOB = (new Object(false); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Boolean]; (new Object(false).valueOf() = false; typeof new Object(Boolean()) = object; MYOB = (new Object(Boolean()); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Boolean]; (new Object(Boolean()).valueOf() = false; myglobal = new Object( this ) = [object Window]; myobject = new Object('my new object'); new Object(myobject) = [object Object]; myarray = new Array(); new Object(myarray) =; myboolean = new Boolean(); new Object(myboolean) = false; mynumber = new Number(); new Object(mynumber) = 0; mystring = new String9); new Object(mystring) =; myobject = new Object(); new Object(mynobject) = [object Object]; myfunction = new Function(); new Object(myfunction) = function anonymous(x) {; return x;; }; mymath = Math; new Object(mymath) = [object Math]; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; +TEST_ID=ecma/ObjectObjects/15.2.2.1.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=opt, TEST_TYPE=browser, TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=EXIT STATUS: TIMED OUT (`[`0`-`9`]``+` seconds), 15.2.2.1 new Object( value ); typeof new Object(null) = object; MYOB = new Object(null); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Object]; typeof new Object(void 0) = object; MYOB = new Object(new Object(void 0)); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Object]; typeof new Object('string') = object; MYOB = (new Object('string'); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object String]; (new Object('string').valueOf() = string; typeof new Object('') = object; MYOB = (new Object(''); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object String]; (new Object('').valueOf() =; typeof new Object(Number.NaN) = object; MYOB = (new Object(Number.NaN); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Number]; (new Object(Number.NaN).valueOf() = NaN; typeof new Object(0) = object; MYOB = (new Object(0); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Number]; (new Object(0).valueOf() = 0; typeof new Object(-0) = object; MYOB = (new Object(-0); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Number]; (new Object(-0).valueOf() = 0; typeof new Object(1) = object; MYOB = (new Object(1); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Number]; (new Object(1).valueOf() = 1; typeof new Object(-1) = object; MYOB = (new Object(-1); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Number]; (new Object(-1).valueOf() = -1; typeof new Object(true) = object; MYOB = (new Object(true); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Boolean]; (new Object(true).valueOf() = true; typeof new Object(false) = object; MYOB = (new Object(false); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Boolean]; (new Object(false).valueOf() = false; typeof new Object(Boolean()) = object; MYOB = (new Object(Boolean()); MYOB.toString = Object.prototype.toString; MYOB.toString() = [object Boolean]; (new Object(Boolean()).valueOf() = false; myglobal = new Object( this ) = [object Window]; myobject = new Object('my new object'); new Object(myobject) = [object Object]; myarray = new Array(); new Object(myarray) =; myboolean = new Boolean(); new Object(myboolean) = false; mynumber = new Number(); new Object(mynumber) = 0; mystring = new String9); new Object(mystring) =; myobject = new Object(); new Object(mynobject) = [object Object]; myfunction = new Function(); new Object(myfunction) = function anonymous(x) {; return x;; }; mymath = Math; new Object(mymath) = [object Math]; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; ; TEST_ID=ecma/ObjectObjects/15.2.4.2.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=browser, TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Unknown expected: Unknown actual: error reason: uncaught exception: [Exception... "Unexpected error" nsresult: "0x8000ffff (NS_ERROR_UNEXPECTED)" location: "JS frame :: http://`.``*`ecma/ObjectObjects/15.2.4.2.js :: :: line `[`0`-`9`]``+`" data: no] Page: Line: 0 TEST_ID=ecma/ObjectObjects/15.2.4.2.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=browser, TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=myvar = this; myvar.toString = Object.prototype.toString; myvar.toString() expected: [object Window] actual: [object XPCCrossOriginWrapper] reason: TEST_ID=ecma/String/15.5.4.6-2.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=debug, TEST_TYPE=browser, TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=var f = new Object( String.prototype.indexOf ); f('[object Window @ `[`x0`-`9a`-`f`]``+` (native @ `[`x0`-`9a`-`f`]``+`)]') expected: 0 actual: -1 reason: wrong value @@ -123,34 +105,7 @@ TEST_ID=ecma_3/Array/regress-387501.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, T TEST_ID=ecma_3/Date/15.9.4.3.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=15.9.4.3 - Date.UTC edge-case arguments.: date -1 expected: 30 actual: 1 reason: Expected value '30', Actual value '1' TEST_ID=ecma_3/Date/15.9.4.3.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=15.9.4.3 - Date.UTC edge-case arguments.: date 0 expected: 31 actual: 1 reason: Expected value '31', Actual value '1' TEST_ID=ecma_3/Date/15.9.4.3.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=15.9.4.3 - Date.UTC edge-case arguments.: date null expected: 31 actual: 1 reason: Expected value '31', Actual value '1' -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=2.6.9.*ELsmp, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.parse(Fri Dec 31 1999 19:00:00 GMT-0500 (EST)).toLocaleDateString()) expected: 946616400000 actual: 994910400000 reason: wrong value -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=2.6.9.*ELsmp, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.parse(Fri Dec 31 2004 18:59:59 GMT-0500 (EST)).toLocaleDateString()) expected: 1104469200000 actual: 1152676800000 reason: wrong value -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=2.6.9.*ELsmp, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.parse(Fri Dec 31 2004 19:00:00 GMT-0500 (EST)).toLocaleDateString()) expected: 1104469200000 actual: 1152676800000 reason: wrong value -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=2.6.9.*ELsmp, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.parse(Mon Feb 28 2000 18:59:59 GMT-0500 (EST)).toLocaleDateString()) expected: 951714000000 actual: 1017723600000 reason: wrong value -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=2.6.9.*ELsmp, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.parse(Mon Feb 28 2000 19:00:00 GMT-0500 (EST)).toLocaleDateString()) expected: 951714000000 actual: 1017723600000 reason: wrong value -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=2.6.9.*ELsmp, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.parse(Sun Dec 31 1899 19:00:00 GMT-0500 (EST)).toLocaleDateString()) expected: -2209057200000 actual: -2160849600000 reason: wrong value -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=2.6.9.*ELsmp, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.parse(Tue Feb 29 2000 00:00:00 GMT-0500 (EST)).toLocaleDateString()) expected: 951800400000 actual: 1020312000000 reason: wrong value -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=(2.6.18.*el5PAE|2.6.9.*ELsmp), TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=(Date.parse(now.toLocaleDateString()) - (midnight(now)).valueOf()) == 0 expected: true actual: false reason: wrong value -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=(2.6.18.*el5PAE|2.6.9.*ELsmp), TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=Date.parse(Fri Dec 31 1999 16:00:00 GMT-0800 (PST)).toLocaleDateString()) expected: 946627200000 actual: 994921200000 reason: wrong value -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=(2.6.18.*el5PAE|2.6.9.*ELsmp), TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=Date.parse(Fri Dec 31 2004 15:59:59 GMT-0800 (PST)).toLocaleDateString()) expected: 1104480000000 actual: 1152687600000 reason: wrong value -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=(2.6.18.*el5PAE|2.6.9.*ELsmp), TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=Date.parse(Fri Dec 31 2004 16:00:00 GMT-0800 (PST)).toLocaleDateString()) expected: 1104480000000 actual: 1152687600000 reason: wrong value -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=(2.6.18.*el5PAE|2.6.9.*ELsmp), TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=Date.parse(Mon Feb 28 2000 15:59:59 GMT-0800 (PST)).toLocaleDateString()) expected: 951724800000 actual: 1017734400000 reason: wrong value -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=(2.6.18.*el5PAE|2.6.9.*ELsmp), TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=Date.parse(Mon Feb 28 2000 16:00:00 GMT-0800 (PST)).toLocaleDateString()) expected: 951724800000 actual: 1017734400000 reason: wrong value -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=(2.6.18.*el5PAE|2.6.9.*ELsmp), TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=Date.parse(Sun Dec 31 1899 16:00:00 GMT-0800 (PST)).toLocaleDateString()) expected: -2209046400000 actual: -2160838800000 reason: wrong value -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=(2.6.18.*el5PAE|2.6.9.*ELsmp), TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=Date.parse(Tue Feb 29 2000 00:00:00 GMT-0800 (PST)).toLocaleDateString()) expected: 951811200000 actual: 1020322800000 reason: wrong value -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=(2.6.18.*el5PAE|2.6.9.*ELsmp), TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=Date.parse(Wed Dec 31 1969 08:00:00 GMT-0800 (PST)).toLocaleDateString()) expected: -57600000 actual: 48150000000 reason: wrong value -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=(2.6.18.*el5PAE|2.6.9.*ELsmp), TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=Date.parse(Wed Dec 31 1969 16:00:00 GMT-0800 (PST)).toLocaleDateString()) expected: -57600000 actual: 48150000000 reason: wrong value TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=debug, TEST_TYPE=browser, TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=2.6.9.*ELsmp, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.parse(Fri Dec 31 1999 19:00:00 GMT-0500 (EST)).toLocaleDateString()) expected: 946616400000 actual: 994910400000 reason: wrong value -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=(2.6.18.*el5PAE|2.6.9.*ELsmp), TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=(Date.parse(now.toLocaleDateString()) - (midnight(now)).valueOf()) == 0 expected: true actual: false reason: wrong value -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=(2.6.18.*el5PAE|2.6.9.*ELsmp), TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.parse(Wed Dec 31 1969 14:00:00 GMT-0500 (EST)).toLocaleDateString()) expected: -68400000 actual: 48139200000 reason: wrong value -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=(2.6.18.*el5PAE|2.6.9.*ELsmp), TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.parse(Wed Dec 31 1969 19:00:00 GMT-0500 (EST)).toLocaleDateString()) expected: -68400000 actual: 48139200000 reason: wrong value -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=2.6.18.*el5PAE, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.parse(Fri Dec 31 1999 19:00:00 GMT-0500 (EST)).toLocaleDateString()) expected: 946616400000 actual: 994910400000 reason: wrong value -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=2.6.18.*el5PAE, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.parse(Fri Dec 31 2004 18:59:59 GMT-0500 (EST)).toLocaleDateString()) expected: 1104469200000 actual: 1152676800000 reason: wrong value -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=2.6.18.*el5PAE, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.parse(Fri Dec 31 2004 19:00:00 GMT-0500 (EST)).toLocaleDateString()) expected: 1104469200000 actual: 1152676800000 reason: wrong value -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=2.6.18.*el5PAE, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.parse(Mon Feb 28 2000 18:59:59 GMT-0500 (EST)).toLocaleDateString()) expected: 951714000000 actual: 1017723600000 reason: wrong value -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=2.6.18.*el5PAE, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.parse(Mon Feb 28 2000 19:00:00 GMT-0500 (EST)).toLocaleDateString()) expected: 951714000000 actual: 1017723600000 reason: wrong value -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=2.6.18.*el5PAE, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.parse(Sun Dec 31 1899 19:00:00 GMT-0500 (EST)).toLocaleDateString()) expected: -2209057200000 actual: -2160849600000 reason: wrong value -TEST_ID=ecma_3/Date/15.9.5.6.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=2.6.18.*el5PAE, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.parse(Tue Feb 29 2000 00:00:00 GMT-0500 (EST)).toLocaleDateString()) expected: 951800400000 actual: 1020312000000 reason: wrong value TEST_ID=ecma_3/ExecutionContexts/10.1.3-2.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(opt|debug), TEST_TYPE=(browser|shell), TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=`.``*`x is not a function TEST_ID=ecma_3/Expressions/11.10-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=.*, TEST_TYPE=.*, TEST_OS=.*, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=11.10 - & should evaluate operands in order: order expected: o.valueOf, p.valueOf actual: , p.valueOfo.valueOf reason: Expected value 'o.valueOf, p.valueOf', Actual value ', p.valueOfo.valueOf' TEST_ID=ecma_3/Expressions/11.10-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=.*, TEST_TYPE=.*, TEST_OS=.*, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=11.10 - ^ should evaluate operands in order: order expected: o.valueOf, p.valueOf actual: , p.valueOfo.valueOf reason: Expected value 'o.valueOf, p.valueOf', Actual value ', p.valueOfo.valueOf' @@ -200,46 +155,6 @@ TEST_ID=js1_5/Array/11.1.4.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TE TEST_ID=js1_5/Array/11.1.4.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Elisons in Array literals should not be enumed Section 4 of test - [1,,] expected: 0 actual: 01 reason: Expected value '0', Actual value '01' TEST_ID=js1_5/Array/regress-101964.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Section 1 of test - expected: Truncation took less than `[`0`-`9`]``+` ms actual: Truncation took `[`0`-`9`]``+` ms reason: Expected value 'Truncation took less than `[`0`-`9`]``+` ms', Actual value 'Truncation took `[`0`-`9`]``+` ms' TEST_ID=js1_5/Array/regress-157652.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=browser, TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=BUGNUMBER: 157652; STATUS: Testing that Array.sort() doesn't crash on very large arrays; --- NOTE: IN THIS TESTCASE, WE EXPECT EXIT CODE 5 --- -TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=2.6.18.*el5PAE, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%m/%d/%y) == Date.toLocaleFormat("%x") expected: 06/04/2005 actual: 04/06/2005 reason: Expected value '06/04/2005', Actual value '04/06/2005' -TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%C") expected: 20 actual: Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time) reason: Expected value '20', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time)' -TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%C%y") == Date.toLocaleFormat("%Y") expected: 05 actual: 2005 reason: Expected value '05', Actual value '2005' -TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%G") expected: 2005 actual: Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time) reason: Expected value '2005', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time)' -TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%H:%M") == Date.toLocaleFormat("%R") expected: 20:00 actual: Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time) reason: Expected value '20:00', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time)' -TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%H:%M:%S") == Date.toLocaleFormat("%T") expected: 20:00:00 actual: Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time) reason: Expected value '20:00:00', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time)' -TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%I:%M:%S %p") == Date.toLocaleFormat("%r") expected: 08:00:00 PM actual: Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time) reason: Expected value '08:00:00 PM', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time)' -TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%V") expected: 22 actual: Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time) reason: Expected value '22', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time)' -TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%Y-%m-%d") == Date.toLocaleFormat("%F") expected: 2005-06-04 actual: Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time) reason: Expected value '2005-06-04', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time)' -TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%b") == Date.toLocaleFormat("%h") expected: Jun actual: Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time) reason: Expected value 'Jun', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time)' -TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%e") expected: 4 actual: Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time) reason: Expected value ' 4', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time)' -TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%g") expected: 05 actual: Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time) reason: Expected value '05', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time)' -TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%m/%d/%y") == Date.toLocaleFormat("%D") expected: 06/04/05 actual: Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time) reason: Expected value '06/04/05', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time)' -TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%m/%d/%y) == Date.toLocaleFormat("%x") expected: 06/04/2005 actual: 2005-06-04 reason: Expected value '06/04/2005', Actual value '2005-06-04' -TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%n") == "NL" expected: NL actual: Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time) reason: Expected value 'NL', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time)' -TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%t") == "\t" expected: actual: Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time) reason: Expected value ' ', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time)' -TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%u") expected: 6 actual: Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time) reason: Expected value '6', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (Eastern Daylight Time)' -TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION= expected: Expected exit 0 actual: Actual exit 4, signal 0 reason: Testcase produced no output! -TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("xxxx%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y") expected: Sat Jan 01 -0051 00:00:00 `.``*` actual: xxxx-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51 reason: Expected value 'Sat Jan 01 -0051 00:00:00 `.``*`', Actual value 'xxxx-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51' -TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=mac, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%Y %y") expected: -1 99 actual: -001 -1 reason: Expected value '-1 99', Actual value '-001 -1' -TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=mac, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%Y %y") expected: -51 49 actual: -051 -51 reason: Expected value '-51 49', Actual value '-051 -51' -TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=mac, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y") expected: -51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51 actual: -051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051 reason: Expected value '-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51', Actual value '-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051' -TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=mac, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("xxx%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y") expected: xxx-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51 actual: xxx-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051 reason: Expected value 'xxx-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51', Actual value 'xxx-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051' -TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%Y %y") expected: -1 99 actual: 000/ 0/ reason: Expected value '-1 99', Actual value '000/ 0/' -TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%Y %y") expected: -100 00 actual: 0/00 00 reason: Expected value '-100 00', Actual value '0/00 00' -TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%Y %y") expected: -51 49 actual: 00+/ +/ reason: Expected value '-51 49', Actual value '00+/ +/' -TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%Y %y") expected: 1851 51 actual: 1851 ,' reason: Expected value '1851 51', Actual value '1851 ,'' -TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%Y %y") expected: 1899 99 actual: 1899 0/ reason: Expected value '1899 99', Actual value '1899 0/' -TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y") expected: -9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999 actual: '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' reason: Expected value '-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999', Actual value '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' -TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y") expected: 32767327673276732767327673276732767327673276732767327673276732767327673276732767327673276732767 actual: 2767276727672767276727672767276727672767276727672767276727672767276727672767 reason: Expected value '32767327673276732767327673276732767327673276732767327673276732767327673276732767327673276732767', Actual value '2767276727672767276727672767276727672767276727672767276727672767276727672767' -TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y") expected: -51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51 actual: 00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/ reason: Expected value '-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51', Actual value '00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/' -TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("xxx%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y") expected: xxx-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51 actual: xxx00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/ reason: Expected value 'xxx-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51', Actual value 'xxx00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/' -TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("xxxx%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y") expected: xxxx-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999 actual: xxxx'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' reason: Expected value 'xxxx-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999', Actual value 'xxxx''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' -TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("xxxx%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y") expected: xxxx32767327673276732767327673276732767327673276732767327673276732767327673276732767327673276732767 actual: xxxx2767276727672767276727672767276727672767276727672767276727672767276727672767 reason: Expected value 'xxxx32767327673276732767327673276732767327673276732767327673276732767327673276732767327673276732767', Actual value 'xxxx2767276727672767276727672767276727672767276727672767276727672767276727672767' -TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("xxxx%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y") expected: Mon Jan 01 -9999 00:00:00 `.``*` actual: xxxx'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' reason: Expected value 'Mon Jan 01 -9999 00:00:00 `.``*`', Actual value 'xxxx''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' -TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("xxxx%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y") expected: Sun Jan 01 32767 00:00:00 `.``*` actual: xxxx2767276727672767276727672767276727672767276727672767276727672767276727672767276727672767 reason: Expected value 'Sun Jan 01 32767 00:00:00 `.``*`', Actual value 'xxxx2767276727672767276727672767276727672767276727672767276727672767276727672767276727672767' -TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("xxxxx%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y") expected: Sun Jan 01 32767 00:00:00 `.``*` actual: xxxxx2767276727672767276727672767276727672767276727672767276727672767276727672767 reason: Expected value 'Sun Jan 01 32767 00:00:00 `.``*`', Actual value 'xxxxx2767276727672767276727672767276727672767276727672767276727672767276727672767' -TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION= expected: Expected exit 0 actual: Actual exit 4, signal 0 reason: Testcase produced no output! -TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=debug, TEST_TYPE=browser, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=EXIT STATUS: TIMED OUT `.``*`, BUGNUMBER: 291494; STATUS: Date.prototype.toLocaleFormat extension; PASSED! Date.toLocaleFormat("%a"); PASSED! Date.toLocaleFormat("%A"); PASSED! Date.toLocaleFormat("%b"); PASSED! Date.toLocaleFormat("%B"); PASSED! Date.toLocaleFormat("%d"); PASSED! Date.toLocaleFormat(%H); PASSED! Date.toLocaleFormat(%I); PASSED! Date.toLocaleFormat("%j"); PASSED! Date.toLocaleFormat("%m"); PASSED! Date.toLocaleFormat("%M"); PASSED! Date.toLocaleFormat("%p") is AM or PM; PASSED! Date.toLocaleFormat("%S"); PASSED! Date.toLocaleFormat("%U"); PASSED! Date.toLocaleFormat("%w"); PASSED! Date.toLocaleFormat("%W"); PASSED! Date.toLocaleTimeString() == Date.toLocaleFormat("%X"); PASSED! Date.toLocaleFormat("%y"); PASSED! Date.toLocaleFormat("%Y"); PASSED! Date.toLocaleFormat("%%") -TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=opt, TEST_TYPE=browser, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=EXIT STATUS: CRASHED `.``*`, BUGNUMBER: 291494; STATUS: Date.prototype.toLocaleFormat extension; PASSED! Date.toLocaleFormat("%a"); PASSED! Date.toLocaleFormat("%A"); PASSED! Date.toLocaleFormat("%b"); PASSED! Date.toLocaleFormat("%B"); PASSED! Date.toLocaleFormat("%d"); PASSED! Date.toLocaleFormat(%H); PASSED! Date.toLocaleFormat(%I); PASSED! Date.toLocaleFormat("%j"); PASSED! Date.toLocaleFormat("%m"); PASSED! Date.toLocaleFormat("%M"); PASSED! Date.toLocaleFormat("%p") is AM or PM; PASSED! Date.toLocaleFormat("%S"); PASSED! Date.toLocaleFormat("%U"); PASSED! Date.toLocaleFormat("%w"); PASSED! Date.toLocaleFormat("%W"); PASSED! Date.toLocaleTimeString() == Date.toLocaleFormat("%X"); PASSED! Date.toLocaleFormat("%y"); PASSED! Date.toLocaleFormat("%Y"); PASSED! Date.toLocaleFormat("%%") TEST_ID=js1_5/Error/regress-354246.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=browser, TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Unknown expected: Unknown actual: error reason: x is not defined Page: http://`.``*`/js1_5/Error/regress-354246.js Line: `[`0`-`9`]``+` TEST_ID=js1_5/Error/regress-354246.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=(linux|mac), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION= expected: Expected exit 0 actual: Actual exit 3, signal 0 reason: ./js1_5/Error/regress-354246.js:`[`0`-`9`]``+`: x is not defined BUGNUMBER: 354246 STATUS: calling Error constructor with object with bad toString TEST_ID=js1_5/Error/regress-354246.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION= expected: Expected exit 0 actual: Actual exit 3, signal 0 reason: BUGNUMBER: 354246 STATUS: calling Error constructor with object with bad toString ./js1_5/Error/regress-354246.js:`[`0`-`9`]``+`: x is not defined @@ -273,12 +188,11 @@ TEST_ID=js1_5/Regress/regress-330352.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_ID=js1_5/Regress/regress-346237.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED( TIMED OUT)?, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=(2.6.18.*el5PAE|2.6.20.*fc6|2.6.22.*fc6).*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=`(` expected: Expected exit 0 actual: Actual exit 5, signal 0 `|` expected: actual: `)``?`reason: ./js1_5/Regress/regress-346237.js:`[`0`-`9`]``+`: out of memory`(` BUGNUMBER: 346237 STATUS: RegExp - /(|)??x/g.exec("y")`)``?` TEST_ID=js1_5/Regress/regress-346237.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=browser, TEST_OS=(mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=BUGNUMBER: 346237; STATUS: RegExp - /(|)??x/g.exec("y") TEST_ID=js1_5/Regress/regress-346237.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=browser, TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=(2.6.18.*el5PAE|2.6.20.*fc6|2.6.22.*fc6).*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=BUGNUMBER: 346237; STATUS: RegExp - /(|)??x/g.exec("y") -TEST_ID=js1_5/Regress/regress-346237.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=athlon, TEST_KERNEL=2.6.9.*ELsmp, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION= expected: Expected exit 0 actual: Actual exit 0, signal `[`1`-`9`]``[`0`-`9`]``*` reason: ./js1_5/Regress/regress-346237.js:`[`0`-`9`]``+`: out of memory BUGNUMBER: 346237 STATUS: RegExp - /(|)??x/g.exec("y") -TEST_ID=js1_5/Regress/regress-346237.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=i686, TEST_KERNEL=2.6.9.*ELsmp, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION= expected: Expected exit 0 actual: Actual exit 0, signal 6 reason: ./js1_5/Regress/regress-346237.js:56: out of memory BUGNUMBER: 346237 STATUS: RegExp - /(|)??x/g.exec("y") -TEST_ID=js1_5/Regress/regress-346237.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=mac, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION= expected: Expected exit 0 actual: Actual exit 5, signal 0 reason: `.``*` malloc: `.``*` error: can't allocate region `.``*` ./js1_5/Regress/regress-346237.js:`[`0`-`9`]``+`: out of memory BUGNUMBER: 346237 STATUS: RegExp - /(|)??x/g.exec("y") -TEST_ID=js1_5/Regress/regress-346237.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION= expected: Expected exit 0 actual: Actual exit 5, signal 0 reason: BUGNUMBER: 346237 STATUS: RegExp - /(|)??x/g.exec("y") ./js1_5/Regress/regress-346237.js:`[`0`-`9`]``+`: out of memory +TEST_ID=js1_5/Regress/regress-346237.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=(athlon|i686), TEST_KERNEL=2.6.9.*ELsmp, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=`.``*`/js1_5/Regress/regress-346237.js:`[`0`-`9`]``+`: out of memory +TEST_ID=js1_5/Regress/regress-346237.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=mac, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION= `.``*`/js1_5/Regress/regress-346237.js:`[`0`-`9`]``+`: out of memory +TEST_ID=js1_5/Regress/regress-346237.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=`.``*`/js1_5/Regress/regress-346237.js:`[`0`-`9`]``+`: out of memory TEST_ID=js1_5/Regress/regress-346237.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=debug, TEST_TYPE=browser, TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=(athlon|i686), TEST_KERNEL=2.6.9.*ELsmp, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=`(`EXIT STATUS: CRASHED `[`4`-`9`]` (`[`0`-`9`.``]``+` seconds), `)``?`BUGNUMBER: 346237; STATUS: RegExp - /(|)??x/g.exec("y"); JavaScript error: `.``*`/js1_5/Regress/regress-346237.js, line `[`0`-`9`]``+`: out of memory; -TEST_ID=js1_5/Regress/regress-346237.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=debug, TEST_TYPE=browser, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=BUGNUMBER: 346237; STATUS: RegExp - /(|)??x/g.exec("y"); JavaScript error: `.``*`/js1_5/Regress/regress-346237.js, line `[`0`-`9`]``+`: out of memory; +TEST_ID=js1_5/Regress/regress-346237.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=debug, TEST_TYPE=browser, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=`.``*`/js1_5/Regress/regress-346237.js, line `[`0`-`9`]``+`: out of memory TEST_ID=js1_5/Regress/regress-346237.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=opt, TEST_TYPE=browser, TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=(athlon|i686), TEST_KERNEL=2.6.9.*ELsmp, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=EXIT STATUS: CRASHED signal `[`1`-`9`]``[`0`-`9`]``*` (`[`0`-`9`.``]``+` seconds), BUGNUMBER: 346237; STATUS: RegExp - /(|)??x/g.exec("y") TEST_ID=js1_5/Regress/regress-350268.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=new Function with unbalanced braces expected: SyntaxError actual: No Error reason: Expected value 'SyntaxError', Actual value 'No Error' TEST_ID=js1_5/Regress/regress-3649-n.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=browser, TEST_OS=(mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=BUGNUMBER: 3649; STATUS: gc-checking branch callback.; --- NOTE: IN THIS TESTCASE, WE EXPECT EXIT CODE 0 ---; --- NOTE: IN THIS TESTCASE, WE EXPECT EXIT CODE 5 --- @@ -291,6 +205,7 @@ TEST_ID=js1_5/Regress/regress-3649-n.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_ID=js1_5/Regress/regress-3649-n.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=opt, TEST_TYPE=browser, TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=athlon, TEST_KERNEL=2.6.9.*ELsmp, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=EXIT STATUS: CRASHED signal 6 (`.``*` seconds), BUGNUMBER: 3649; STATUS: gc-checking branch callback.; --- NOTE: IN THIS TESTCASE, WE EXPECT EXIT CODE 0 ---; --- NOTE: IN THIS TESTCASE, WE EXPECT EXIT CODE 5 --- TEST_ID=js1_5/Regress/regress-383674.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Statement that implicitly calls toString should not be optimized away as a "useless expression": 1 expected: toString called actual: toString not called reason: Expected value 'toString called', Actual value 'toString not called' TEST_ID=js1_5/Regress/regress-383674.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Statement that implicitly calls toString should not be optimized away as a "useless expression": 2 expected: toString called actual: toString not called reason: Expected value 'toString called', Actual value 'toString not called' +TEST_ID=js1_5/Regress/regress-68498-003.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=(opt|debug), TEST_TYPE=browser, TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Testing calling obj.eval(str); currently at expect[3] within test - expected: false actual: true reason: Expected value 'false', Actual value 'true' TEST_ID=js1_5/decompilation/regress-351219.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Decompilation of immutable infinity, NaN decompile Infinity as 1/0 expected: function ( ) { return 1 / 0 ; } actual: function ( ) { return Infinity ; } reason: Expected value ' function ( ) { return 1 / 0 ; } ', Actual value ' function ( ) { return Infinity ; } ' TEST_ID=js1_5/decompilation/regress-351219.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Decompilation of immutable infinity, NaN: decompile NaN as 0/0 expected: function ( ) { var NaN = 0 / 0 ; return NaN ; } actual: function ( ) { var NaN = NaN ; return NaN ; } reason: Expected value ' function ( ) { var NaN = 0 / 0 ; return NaN ; } ', Actual value ' function ( ) { var NaN = NaN ; return NaN ; } ' TEST_ID=js1_5/decompilation/regress-352013.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=decompilation of new parenthetic expressions expected: function ( ) { new ( x ( y ) ( z ) ) ; } actual: function ( ) { new x ( y ) ( z ) ; } reason: Expected value ' function ( ) { new ( x ( y ) ( z ) ) ; } ', Actual value ' function ( ) { new x ( y ) ( z ) ; } ' @@ -348,6 +263,61 @@ TEST_ID=js1_5/extensions/regress-385134.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILE TEST_ID=js1_5/extensions/regress-385134.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION= expected: Expected exit 0 actual: Actual exit 4, signal 0 reason: Testcase produced no output! TEST_ID=js1_5/extensions/scope-001.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=(opt|debug), TEST_TYPE=browser, TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Step 1: setting obj.__proto__ = global object expected: 5 actual: 1 reason: Expected value '5', Actual value '1' TEST_ID=js1_5/extensions/scope-001.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=(opt|debug), TEST_TYPE=browser, TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Step 2: setting obj.__proto__ = null expected: undefined actual: 1 reason: Type mismatch, expected type undefined, actual type number Expected value 'undefined', Actual value '1' +TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=linux, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("xxxx%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y") expected: Sat Jan 01 -0051 00:00:00 `.``*` actual: xxxx-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51 reason: Expected value 'Sat Jan 01 -0051 00:00:00 `.``*`', Actual value 'xxxx-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51' +TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=mac, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%Y %y") expected: -1 99 actual: -001 -1 reason: Expected value '-1 99', Actual value '-001 -1' +TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=mac, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%Y %y") expected: -51 49 actual: -051 -51 reason: Expected value '-51 49', Actual value '-051 -51' +TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=mac, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y") expected: -51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51 actual: -051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051 reason: Expected value '-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51', Actual value '-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051' +TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=mac, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("xxx%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y") expected: xxx-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51 actual: xxx-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051 reason: Expected value 'xxx-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51', Actual value 'xxx-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051-051' +TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%Y %y") expected: -1 99 actual: 000/ 0/ reason: Expected value '-1 99', Actual value '000/ 0/' +TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%Y %y") expected: -100 00 actual: 0/00 00 reason: Expected value '-100 00', Actual value '0/00 00' +TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%Y %y") expected: -51 49 actual: 00+/ +/ reason: Expected value '-51 49', Actual value '00+/ +/' +TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%Y %y") expected: 1851 51 actual: 1851 ,' reason: Expected value '1851 51', Actual value '1851 ,'' +TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%Y %y") expected: 1899 99 actual: 1899 0/ reason: Expected value '1899 99', Actual value '1899 0/' +TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y") expected: -9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999 actual: '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' reason: Expected value '-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999', Actual value '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y") expected: 32767327673276732767327673276732767327673276732767327673276732767327673276732767327673276732767 actual: 2767276727672767276727672767276727672767276727672767276727672767276727672767 reason: Expected value '32767327673276732767327673276732767327673276732767327673276732767327673276732767327673276732767', Actual value '2767276727672767276727672767276727672767276727672767276727672767276727672767' +TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y") expected: -51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51 actual: 00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/ reason: Expected value '-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51', Actual value '00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/' +TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("xxx%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y") expected: xxx-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51 actual: xxx00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/ reason: Expected value 'xxx-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51-51', Actual value 'xxx00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/00+/' +TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("xxxx%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y") expected: xxxx-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999 actual: xxxx'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' reason: Expected value 'xxxx-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999-9999', Actual value 'xxxx''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("xxxx%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y") expected: xxxx32767327673276732767327673276732767327673276732767327673276732767327673276732767327673276732767 actual: xxxx2767276727672767276727672767276727672767276727672767276727672767276727672767 reason: Expected value 'xxxx32767327673276732767327673276732767327673276732767327673276732767327673276732767327673276732767', Actual value 'xxxx2767276727672767276727672767276727672767276727672767276727672767276727672767' +TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("xxxx%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y") expected: Mon Jan 01 -9999 00:00:00 `.``*` actual: xxxx'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' reason: Expected value 'Mon Jan 01 -9999 00:00:00 `.``*`', Actual value 'xxxx''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' +TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("xxxx%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y") expected: Sun Jan 01 32767 00:00:00 `.``*` actual: xxxx2767276727672767276727672767276727672767276727672767276727672767276727672767276727672767 reason: Expected value 'Sun Jan 01 32767 00:00:00 `.``*`', Actual value 'xxxx2767276727672767276727672767276727672767276727672767276727672767276727672767276727672767' +TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Date.toLocaleFormat("xxxxx%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y%Y") expected: Sun Jan 01 32767 00:00:00 `.``*` actual: xxxxx2767276727672767276727672767276727672767276727672767276727672767276727672767 reason: Expected value 'Sun Jan 01 32767 00:00:00 `.``*`', Actual value 'xxxxx2767276727672767276727672767276727672767276727672767276727672767276727672767' +TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION= expected: Expected exit 0 actual: Actual exit 4, signal 0 reason: Testcase produced no output! +TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=debug, TEST_TYPE=browser, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=EXIT STATUS: TIMED OUT `.``*`, BUGNUMBER: 291494; STATUS: Date.prototype.toLocaleFormat extension; PASSED! Date.toLocaleFormat("%a"); PASSED! Date.toLocaleFormat("%A"); PASSED! Date.toLocaleFormat("%b"); PASSED! Date.toLocaleFormat("%B"); PASSED! Date.toLocaleFormat("%d"); PASSED! Date.toLocaleFormat(%H); PASSED! Date.toLocaleFormat(%I); PASSED! Date.toLocaleFormat("%j"); PASSED! Date.toLocaleFormat("%m"); PASSED! Date.toLocaleFormat("%M"); PASSED! Date.toLocaleFormat("%p") is AM or PM; PASSED! Date.toLocaleFormat("%S"); PASSED! Date.toLocaleFormat("%U"); PASSED! Date.toLocaleFormat("%w"); PASSED! Date.toLocaleFormat("%W"); PASSED! Date.toLocaleTimeString() == Date.toLocaleFormat("%X"); PASSED! Date.toLocaleFormat("%y"); PASSED! Date.toLocaleFormat("%Y"); PASSED! Date.toLocaleFormat("%%") +TEST_ID=js1_5/extensions/toLocaleFormat-01.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=opt, TEST_TYPE=browser, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=EXIT STATUS: CRASHED `.``*`, BUGNUMBER: 291494; STATUS: Date.prototype.toLocaleFormat extension; PASSED! Date.toLocaleFormat("%a"); PASSED! Date.toLocaleFormat("%A"); PASSED! Date.toLocaleFormat("%b"); PASSED! Date.toLocaleFormat("%B"); PASSED! Date.toLocaleFormat("%d"); PASSED! Date.toLocaleFormat(%H); PASSED! Date.toLocaleFormat(%I); PASSED! Date.toLocaleFormat("%j"); PASSED! Date.toLocaleFormat("%m"); PASSED! Date.toLocaleFormat("%M"); PASSED! Date.toLocaleFormat("%p") is AM or PM; PASSED! Date.toLocaleFormat("%S"); PASSED! Date.toLocaleFormat("%U"); PASSED! Date.toLocaleFormat("%w"); PASSED! Date.toLocaleFormat("%W"); PASSED! Date.toLocaleTimeString() == Date.toLocaleFormat("%X"); PASSED! Date.toLocaleFormat("%y"); PASSED! Date.toLocaleFormat("%Y"); PASSED! Date.toLocaleFormat("%%") +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=(-0400|-0700), TEST_DESCRIPTION=Date.toLocaleFormat("%C%y") == Date.toLocaleFormat("%Y") expected: 05 actual: 2005 reason: Expected value '05', Actual value '2005' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=(-0400|-0700), TEST_DESCRIPTION=Date.toLocaleFormat("%m/%d/%y) == Date.toLocaleFormat("%x") expected: 06/04/2005 actual: 2005-06-04 reason: Expected value '06/04/2005', Actual value '2005-06-04' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.toLocaleFormat("%C") expected: 20 actual: Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`) reason: Expected value '20', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.toLocaleFormat("%G") expected: 2005 actual: Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`) reason: Expected value '2005', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.toLocaleFormat("%H:%M") == Date.toLocaleFormat("%R") expected: 20:00 actual: Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`) reason: Expected value '20:00', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.toLocaleFormat("%H:%M:%S") == Date.toLocaleFormat("%T") expected: 20:00:00 actual: Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`) reason: Expected value '20:00:00', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.toLocaleFormat("%I:%M:%S %p") == Date.toLocaleFormat("%r") expected: 08:00:00 PM actual: Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`) reason: Expected value '08:00:00 PM', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.toLocaleFormat("%V") expected: 22 actual: Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`) reason: Expected value '22', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.toLocaleFormat("%Y-%m-%d") == Date.toLocaleFormat("%F") expected: 2005-06-04 actual: Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`) reason: Expected value '2005-06-04', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.toLocaleFormat("%b") == Date.toLocaleFormat("%h") expected: Jun actual: Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`) reason: Expected value 'Jun', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.toLocaleFormat("%e") expected: 4 actual: Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`) reason: Expected value ' 4', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.toLocaleFormat("%g") expected: 05 actual: Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`) reason: Expected value '05', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.toLocaleFormat("%m/%d/%y") == Date.toLocaleFormat("%D") expected: 06/04/05 actual: Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`) reason: Expected value '06/04/05', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.toLocaleFormat("%n") == "NL" expected: NL actual: Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`) reason: Expected value 'NL', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.toLocaleFormat("%t") == "\t" expected: actual: Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`) reason: Expected value ' ', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0400, TEST_DESCRIPTION=Date.toLocaleFormat("%u") expected: 6 actual: Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`) reason: Expected value '6', Actual value 'Sat Jun 04 2005 20:00:00 GMT-0400 (`(`Eastern Daylight Time`|`EDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=Date.toLocaleFormat("%C") expected: 20 actual: Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`) reason: Expected value '20', Actual value 'Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=Date.toLocaleFormat("%G") expected: 2005 actual: Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`) reason: Expected value '2005', Actual value 'Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=Date.toLocaleFormat("%H:%M") == Date.toLocaleFormat("%R") expected: 17:00 actual: Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`) reason: Expected value '17:00', Actual value 'Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=Date.toLocaleFormat("%H:%M:%S") == Date.toLocaleFormat("%T") expected: 17:00:00 actual: Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`) reason: Expected value '17:00:00', Actual value 'Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=Date.toLocaleFormat("%I:%M:%S %p") == Date.toLocaleFormat("%r") expected: 05:00:00 PM actual: Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`) reason: Expected value '05:00:00 PM', Actual value 'Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=Date.toLocaleFormat("%V") expected: 22 actual: Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`) reason: Expected value '22', Actual value 'Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=Date.toLocaleFormat("%Y-%m-%d") == Date.toLocaleFormat("%F") expected: 2005-06-04 actual: Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`) reason: Expected value '2005-06-04', Actual value 'Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=Date.toLocaleFormat("%b") == Date.toLocaleFormat("%h") expected: Jun actual: Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`) reason: Expected value 'Jun', Actual value 'Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=Date.toLocaleFormat("%e") expected: 4 actual: Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`) reason: Expected value ' 4', Actual value 'Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=Date.toLocaleFormat("%g") expected: 05 actual: Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`) reason: Expected value '05', Actual value 'Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=Date.toLocaleFormat("%m/%d/%y") == Date.toLocaleFormat("%D") expected: 06/04/05 actual: Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`) reason: Expected value '06/04/05', Actual value 'Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=Date.toLocaleFormat("%n") == "NL" expected: NL actual: Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`) reason: Expected value 'NL', Actual value 'Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=Date.toLocaleFormat("%t") == "\t" expected: actual: Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`) reason: Expected value ' ', Actual value 'Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=-0700, TEST_DESCRIPTION=Date.toLocaleFormat("%u") expected: 6 actual: Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`) reason: Expected value '6', Actual value 'Sat Jun 04 2005 17:00:00 GMT-0700 (`(`Pacific Daylight Time`|`PDT`)`)' +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=shell, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION= expected: Expected exit 0 actual: Actual exit 4, signal 0 reason: Testcase produced no output! +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=debug, TEST_TYPE=browser, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=EXIT STATUS: TIMED OUT `.``*`, BUGNUMBER: 291494; STATUS: Date.prototype.toLocaleFormat extension +TEST_ID=js1_5/extensions/toLocaleFormat-02.js, TEST_BRANCH=1.9.0, TEST_RESULT=FAILED, TEST_BUILDTYPE=opt, TEST_TYPE=browser, TEST_OS=win32, TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=EXIT STATUS: CRASHED `.``*`, BUGNUMBER: 291494; STATUS: Date.prototype.toLocaleFormat extension TEST_ID=js1_6/Array/regress-320887.js, TEST_BRANCH=(1.8.1|1.9.0), TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=var x should not throw a ReferenceError expected: No error actual: ReferenceError: x is not defined reason: Expected value 'No error', Actual value 'ReferenceError: x is not defined' TEST_ID=js1_6/Array/regress-386030.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Array.reduce should ignore holes: 1 expected: PASS actual: FAIL, reduce reason: Expected value 'PASS', Actual value 'FAIL, reduce' TEST_ID=js1_6/Array/regress-386030.js, TEST_BRANCH=1.8.1, TEST_RESULT=FAILED, TEST_BUILDTYPE=(debug|opt), TEST_TYPE=(browser|shell), TEST_OS=(linux|mac|win32), TEST_MACHINE=.*, TEST_PROCESSORTYPE=.*, TEST_KERNEL=.*, TEST_DATE=.*, TEST_TIMEZONE=.*, TEST_DESCRIPTION=Array.reduce should ignore holes: 2 expected: PASS actual: FAIL, reduceRight reason: Expected value 'PASS', Actual value 'FAIL, reduceRight' diff --git a/js/tests/runtests.sh b/js/tests/runtests.sh index 7036f9a3c94d..723886b36346 100755 --- a/js/tests/runtests.sh +++ b/js/tests/runtests.sh @@ -70,7 +70,7 @@ source ${TEST_BIN}/library.sh usage() { cat <IsFrameOfType(nsIFrame::eLineParticipant); } +/** + * If any children require a block parent, return the first such child. + * Otherwise return null. + */ +static nsIContent* +AnyKidsNeedBlockParent(nsIFrame *aFrameList) +{ + for (nsIFrame *k = aFrameList; k; k = k->GetNextSibling()) { + // Line participants, such as text and inline frames, can't be + // directly inside a XUL box; they must be wrapped in an + // intermediate block. + if (k->IsFrameOfType(nsIFrame::eLineParticipant)) { + return k->GetContent(); + } + } + return nsnull; +} + +// Reparent a frame into a wrapper frame that is a child of its old parent. +static void +ReparentFrame(nsFrameManager* aFrameManager, + nsIFrame* aNewParentFrame, + nsIFrame* aFrame) +{ + aFrame->SetParent(aNewParentFrame); + aFrameManager->ReParentStyleContext(aFrame); + if (aFrame->GetStateBits() & + (NS_FRAME_HAS_VIEW | NS_FRAME_HAS_CHILD_WITH_VIEW)) { + // No need to walk up the tree, since the bits are already set + // right on the parent of aNewParentFrame. + NS_ASSERTION(aNewParentFrame->GetParent()->GetStateBits() & + NS_FRAME_HAS_CHILD_WITH_VIEW, + "aNewParentFrame's parent should have this bit set!"); + aNewParentFrame->AddStateBits(NS_FRAME_HAS_CHILD_WITH_VIEW); + } +} + //---------------------------------------------------------------------- // // When inline frames get weird and have block frames in them, we @@ -6187,9 +6225,48 @@ nsCSSFrameConstructor::ConstructXULFrame(nsFrameConstructorState& aState, if (mDocument->BindingManager()->ShouldBuildChildFrames(aContent)) { rv = ProcessChildren(aState, aContent, newFrame, PR_FALSE, childItems, PR_FALSE); + nsIContent *badKid; + if (newFrame->IsBoxFrame() && + (badKid = AnyKidsNeedBlockParent(childItems.childList))) { + nsAutoString parentTag, kidTag; + aContent->Tag()->ToString(parentTag); + badKid->Tag()->ToString(kidTag); + const PRUnichar* params[] = { parentTag.get(), kidTag.get() }; + nsContentUtils::ReportToConsole(nsContentUtils::eXUL_PROPERTIES, + "NeededToWrapXUL", + params, NS_ARRAY_LENGTH(params), + mDocument->GetDocumentURI(), + EmptyString(), 0, 0, // not useful + nsIScriptError::warningFlag, + "FrameConstructor"); + + nsRefPtr blockSC = mPresShell->StyleSet()-> + ResolvePseudoStyleFor(aContent, + nsCSSAnonBoxes::mozXULAnonymousBlock, + aStyleContext); + nsIFrame *blockFrame = NS_NewBlockFrame(mPresShell, blockSC); + // We might, in theory, want to set NS_BLOCK_SPACE_MGR and + // NS_BLOCK_MARGIN_ROOT, but I think it's a bad idea given that + // a real block placed here wouldn't get those set on it. + + InitAndRestoreFrame(aState, aContent, newFrame, nsnull, + blockFrame, PR_FALSE); + + NS_ASSERTION(!blockFrame->HasView(), "need to do view reparenting"); + for (nsIFrame *f = childItems.childList; f; f = f->GetNextSibling()) { + ReparentFrame(aState.mFrameManager, blockFrame, f); + } + + blockFrame->AppendFrames(nsnull, childItems.childList); + childItems = nsFrameItems(); + childItems.AddChild(blockFrame); + + newFrame->AddStateBits(NS_STATE_BOX_WRAPS_KIDS_IN_BLOCK); + } } } + // XXX These should go after the wrapper! CreateAnonymousFrames(aTag, aState, aContent, newFrame, PR_FALSE, childItems); @@ -6744,24 +6821,6 @@ nsCSSFrameConstructor::ResolveStyleContext(nsIFrame* aParentFrame, } } -static void -ReparentFrame(nsFrameManager* aFrameManager, - nsIFrame* aNewParentFrame, - nsIFrame* aFrame) -{ - aFrame->SetParent(aNewParentFrame); - aFrameManager->ReParentStyleContext(aFrame); - if (aFrame->GetStateBits() & - (NS_FRAME_HAS_VIEW | NS_FRAME_HAS_CHILD_WITH_VIEW)) { - // No need to walk up the tree, since the bits are already set - // right on the parent of aNewParentFrame. - NS_ASSERTION(aNewParentFrame->GetParent()->GetStateBits() & - NS_FRAME_HAS_CHILD_WITH_VIEW, - "aNewParentFrame's parent should have this bit set!"); - aNewParentFrame->AddStateBits(NS_FRAME_HAS_CHILD_WITH_VIEW); - } -} - // MathML Mod - RBS #ifdef MOZ_MATHML nsresult @@ -7475,8 +7534,7 @@ nsCSSFrameConstructor::ConstructSVGFrame(nsFrameConstructorState& aState, // absolute containing block. nsFrameConstructorSaveState saveState; aState.PushFloatContainingBlock(nsnull, saveState, PR_FALSE, PR_FALSE); - const nsStyleDisplay* disp = innerPseudoStyle->GetStyleDisplay(); - rv = ConstructBlock(aState, disp, aContent, + rv = ConstructBlock(aState, innerPseudoStyle->GetStyleDisplay(), aContent, newFrame, newFrame, innerPseudoStyle, &blockFrame, childItems, PR_TRUE); // Give the blockFrame a view so that GetOffsetTo works for descendants @@ -7836,17 +7894,22 @@ nsCSSFrameConstructor::ReconstructDocElementHierarchyInternal() NS_ASSERTION(docElementFrame->GetParent() == mDocElementContainingBlock, "Unexpected doc element parent frame"); + // Notify self that we will destroy the entire frame tree, this blocks + // RemoveMappingsForFrameSubtree() which would otherwise lead to a + // crash since we cleared the placeholder map above (bug 398982). + PRBool wasDestroyingFrameTree = mIsDestroyingFrameTree; + WillDestroyFrameTree(); // Remove the old document element hieararchy rv = state.mFrameManager->RemoveFrame(mDocElementContainingBlock, nsnull, docElementFrame); + mIsDestroyingFrameTree = wasDestroyingFrameTree; if (NS_FAILED(rv)) { return rv; } - } // Create the new document element hierarchy - nsIFrame* newChild; + nsIFrame* newChild; rv = ConstructDocElementFrame(state, rootContent, mDocElementContainingBlock, &newChild); @@ -9574,6 +9637,18 @@ nsCSSFrameConstructor::ContentRemoved(nsIContent* aContainer, if (possibleMathMLAncestor->IsFrameOfType(nsIFrame::eMathML)) return RecreateFramesForContent(possibleMathMLAncestor->GetContent()); #endif + + // Undo XUL wrapping if it's no longer needed. + // (If we're in the XUL block-wrapping situation, parentFrame is the + // wrapper frame.) + nsIFrame* grandparentFrame = parentFrame->GetParent(); + if (grandparentFrame && grandparentFrame->IsBoxFrame() && + (grandparentFrame->GetStateBits() & NS_STATE_BOX_WRAPS_KIDS_IN_BLOCK) && + // check if this frame is the only one needing wrapping + aChild == AnyKidsNeedBlockParent(parentFrame->GetFirstChild(nsnull)) && + !AnyKidsNeedBlockParent(childFrame->GetNextSibling())) { + return RecreateFramesForContent(grandparentFrame->GetContent()); + } // Examine the containing-block for the removed content and see if // :first-letter style applies. @@ -11273,8 +11348,8 @@ nsCSSFrameConstructor::RecreateFramesForContent(nsIContent* aContent) PRUint32 event; if (frame) { nsIFrame *newFrame = mPresShell->GetPrimaryFrameFor(aContent); - event = newFrame ? nsIAccessibleEvent::EVENT_ASYNCH_SIGNIFICANT_CHANGE : - nsIAccessibleEvent::EVENT_ASYNCH_HIDE; + event = newFrame ? PRUint32(nsIAccessibleEvent::EVENT_ASYNCH_SIGNIFICANT_CHANGE) : + PRUint32(nsIAccessibleEvent::EVENT_ASYNCH_HIDE); } else { event = nsIAccessibleEvent::EVENT_ASYNCH_SHOW; @@ -12503,8 +12578,8 @@ nsCSSFrameConstructor::ConstructBlock(nsFrameConstructorState& aState, return rv; } -PRBool -nsCSSFrameConstructor::AreAllKidsInline(nsIFrame* aFrameList) +static PRBool +AreAllKidsInline(nsIFrame* aFrameList) { nsIFrame* kid = aFrameList; while (kid) { @@ -12830,6 +12905,55 @@ nsCSSFrameConstructor::ProcessInlineChildren(nsFrameConstructorState& aState, return rv; } +static void +DestroyNewlyCreatedFrames(nsFrameConstructorState& aState, + nsIFrame* aParentFrame, + const nsFrameItems& aFrameList) +{ + // Ok, reverse tracks: wipe out the frames we just created + nsFrameManager *frameManager = aState.mFrameManager; + + // Destroy the frames. As we do make sure any content to frame mappings + // or entries in the undisplayed content map are removed + frameManager->ClearAllUndisplayedContentIn(aParentFrame->GetContent()); + + CleanupFrameReferences(frameManager, aFrameList.childList); + if (aState.mAbsoluteItems.childList) { + CleanupFrameReferences(frameManager, aState.mAbsoluteItems.childList); + } + if (aState.mFixedItems.childList) { + CleanupFrameReferences(frameManager, aState.mFixedItems.childList); + } + if (aState.mFloatedItems.childList) { + CleanupFrameReferences(frameManager, aState.mFloatedItems.childList); + } +#ifdef MOZ_XUL + if (aState.mPopupItems.childList) { + CleanupFrameReferences(frameManager, aState.mPopupItems.childList); + } +#endif + nsFrameList tmp(aFrameList.childList); + tmp.DestroyFrames(); + + tmp.SetFrames(aState.mAbsoluteItems.childList); + tmp.DestroyFrames(); + aState.mAbsoluteItems.childList = nsnull; + + tmp.SetFrames(aState.mFixedItems.childList); + tmp.DestroyFrames(); + aState.mFixedItems.childList = nsnull; + + tmp.SetFrames(aState.mFloatedItems.childList); + tmp.DestroyFrames(); + aState.mFloatedItems.childList = nsnull; + +#ifdef MOZ_XUL + tmp.SetFrames(aState.mPopupItems.childList); + tmp.DestroyFrames(); + aState.mPopupItems.childList = nsnull; +#endif +} + PRBool nsCSSFrameConstructor::WipeContainingBlock(nsFrameConstructorState& aState, nsIFrame* aContainingBlock, @@ -12842,8 +12966,20 @@ nsCSSFrameConstructor::WipeContainingBlock(nsFrameConstructorState& aState, return PR_FALSE; } - // Before we go and append the frames, check for a special - // situation: an inline frame that will now contain block + // Before we go and append the frames, we must check for two + // special situations. + + // Situation #1 is a XUL frame that contains frames that are required + // to be wrapped in blocks. + if (aFrame->IsBoxFrame() && + !(aFrame->GetStateBits() & NS_STATE_BOX_WRAPS_KIDS_IN_BLOCK) && + AnyKidsNeedBlockParent(aFrameList.childList)) { + DestroyNewlyCreatedFrames(aState, aFrame, aFrameList); + RecreateFramesForContent(aFrame->GetContent()); + return PR_TRUE; + } + + // Situation #2 is an inline frame that will now contain block // frames. This is a no-no and the frame construction logic knows // how to fix this. See defition of IsInlineFrame() for what "an // inline" is. Whether we have "a block" is tested for by @@ -12905,48 +13041,7 @@ nsCSSFrameConstructor::WipeContainingBlock(nsFrameConstructorState& aState, } } - // Ok, reverse tracks: wipe out the frames we just created - nsFrameManager *frameManager = aState.mFrameManager; - - // Destroy the frames. As we do make sure any content to frame mappings - // or entries in the undisplayed content map are removed - frameManager->ClearAllUndisplayedContentIn(aFrame->GetContent()); - - CleanupFrameReferences(frameManager, aFrameList.childList); - if (aState.mAbsoluteItems.childList) { - CleanupFrameReferences(frameManager, aState.mAbsoluteItems.childList); - } - if (aState.mFixedItems.childList) { - CleanupFrameReferences(frameManager, aState.mFixedItems.childList); - } - if (aState.mFloatedItems.childList) { - CleanupFrameReferences(frameManager, aState.mFloatedItems.childList); - } -#ifdef MOZ_XUL - if (aState.mPopupItems.childList) { - CleanupFrameReferences(frameManager, aState.mPopupItems.childList); - } -#endif - nsFrameList tmp(aFrameList.childList); - tmp.DestroyFrames(); - - tmp.SetFrames(aState.mAbsoluteItems.childList); - tmp.DestroyFrames(); - aState.mAbsoluteItems.childList = nsnull; - - tmp.SetFrames(aState.mFixedItems.childList); - tmp.DestroyFrames(); - aState.mFixedItems.childList = nsnull; - - tmp.SetFrames(aState.mFloatedItems.childList); - tmp.DestroyFrames(); - aState.mFloatedItems.childList = nsnull; - -#ifdef MOZ_XUL - tmp.SetFrames(aState.mPopupItems.childList); - tmp.DestroyFrames(); - aState.mPopupItems.childList = nsnull; -#endif + DestroyNewlyCreatedFrames(aState, aFrame, aFrameList); // If we don't have a containing block, start with aFrame and look for one. if (!aContainingBlock) { diff --git a/layout/base/nsCSSFrameConstructor.h b/layout/base/nsCSSFrameConstructor.h index 4b3e6d2370af..961ae49bcd82 100644 --- a/layout/base/nsCSSFrameConstructor.h +++ b/layout/base/nsCSSFrameConstructor.h @@ -885,8 +885,6 @@ private: nsFrameItems& aFrameItems, PRBool* aKidsAllInline); - PRBool AreAllKidsInline(nsIFrame* aFrameList); - // Determine whether we need to wipe out what we just did and start over // because we're doing something like adding block kids to an inline frame // (and therefore need an {ib} split). If aIsAppend is true, aPrevSibling is diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h index ff8f43ced4ce..26189bcdf1e2 100644 --- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -147,7 +147,7 @@ public: PRBool IsBackgroundOnly() { return mIsBackgroundOnly; } /** * @return PR_TRUE if the currently active BuildDisplayList call is being - * applied to a frame at the root of a pseudo stacking context. A psuedo + * applied to a frame at the root of a pseudo stacking context. A pseudo * stacking context is either a real stacking context or basically what * CSS2.1 appendix E refers to with "treat the element as if it created * a new stacking context diff --git a/layout/base/nsFrameManager.cpp b/layout/base/nsFrameManager.cpp index 8ac65af44921..a6147b9b929c 100644 --- a/layout/base/nsFrameManager.cpp +++ b/layout/base/nsFrameManager.cpp @@ -59,6 +59,7 @@ #include "prthread.h" #include "plhash.h" #include "nsPlaceholderFrame.h" +#include "nsBlockFrame.h" #include "nsGkAtoms.h" #include "nsCSSAnonBoxes.h" #include "nsCSSPseudoElements.h" @@ -1126,6 +1127,12 @@ nsFrameManager::ReResolveStyleContext(nsPresContext *aPresContext, newContext->AddRef(); } } else { + if (pseudoTag == nsCSSPseudoElements::firstLetter) { + NS_ASSERTION(aFrame->GetType() == nsGkAtoms::letterFrame, + "firstLetter pseudoTag without a nsFirstLetterFrame"); + nsBlockFrame* block = nsBlockFrame::GetNearestAncestorBlock(aFrame); + pseudoContent = block->GetContent(); + } newContext = styleSet->ResolvePseudoStyleFor(pseudoContent, pseudoTag, parentContext).get(); diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index f7c50cdca196..7f2470f3747c 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -1849,7 +1849,7 @@ nsresult PresShell::CreatePreferenceStyleSheet(void) result = NS_NewURI(getter_AddRefs(uri), "about:PreferenceStyleSheet", nsnull); if (NS_SUCCEEDED(result)) { NS_ASSERTION(uri, "null but no error"); - result = mPrefStyleSheet->SetURIs(uri, uri); + result = mPrefStyleSheet->SetURIs(uri, nsnull, uri); if (NS_SUCCEEDED(result)) { mPrefStyleSheet->SetComplete(); nsCOMPtr sheet(do_QueryInterface(mPrefStyleSheet)); @@ -3332,7 +3332,11 @@ PresShell::RecreateFramesFor(nsIContent* aContent) nsStyleChangeList changeList; changeList.AppendChange(nsnull, aContent, nsChangeHint_ReconstructFrame); + // Mark ourselves as not safe to flush while we're doing frame construction. + ++mChangeNestCount; nsresult rv = mFrameConstructor->ProcessRestyledFrames(changeList); + --mChangeNestCount; + mViewManager->EndUpdateViewBatch(NS_VMREFRESH_NO_SYNC); #ifdef ACCESSIBILITY InvalidateAccessibleSubtree(aContent); @@ -6031,6 +6035,10 @@ PresShell::DidCauseReflow() if (--mChangeNestCount == 0) { // We may have had more reflow commands appended to the queue during // our reflow. Make sure these get processed at some point. + + // XXXbz why is this really needed? ProcessReflowCommands handles posting + // reflow events if there are reflow roots remaining, and FrameNeedsReflow + // posts events as needed as well. I think we should remove this. PostReflowEvent(); } @@ -6375,7 +6383,11 @@ PresShell::Observe(nsISupports* aSubject, nsStyleChangeList changeList; WalkFramesThroughPlaceholders(mPresContext, rootFrame, ReframeImageBoxes, &changeList); + // Mark ourselves as not safe to flush while we're doing frame + // construction. + ++mChangeNestCount; mFrameConstructor->ProcessRestyledFrames(changeList); + --mChangeNestCount; mViewManager->EndUpdateViewBatch(NS_VMREFRESH_NO_SYNC); #ifdef ACCESSIBILITY diff --git a/layout/forms/nsFileControlFrame.cpp b/layout/forms/nsFileControlFrame.cpp index a89c1817d95b..f54926eba91b 100644 --- a/layout/forms/nsFileControlFrame.cpp +++ b/layout/forms/nsFileControlFrame.cpp @@ -164,7 +164,6 @@ nsFileControlFrame::CreateAnonymousContent(nsTArray& aElements) } textControl->SetTabIndex(-1); - textControl->SetDisabled(PR_TRUE); textControl->SetReadOnly(PR_TRUE); } diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp index c151c67b861f..fd4f0896040b 100644 --- a/layout/generic/nsBlockFrame.cpp +++ b/layout/generic/nsBlockFrame.cpp @@ -5221,7 +5221,8 @@ nsBlockFrame::DoRemoveFrame(nsIFrame* aDeletedFrame, PRBool aDestroyFrames, if (aDestroyFrames) { nsIFrame* nif = aDeletedFrame->GetNextInFlow(); if (nif) - nsContainerFrame::DeleteNextInFlowChild(presContext, nif); + static_cast(nif->GetParent()) + ->nsContainerFrame::DeleteNextInFlowChild(presContext, nif); nsresult rv = nsContainerFrame::StealFrame(presContext, aDeletedFrame); NS_ENSURE_SUCCESS(rv, rv); aDeletedFrame->Destroy(); @@ -6695,6 +6696,24 @@ nsBlockFrame::BlockNeedsSpaceManager(nsIFrame* aBlock) (parent && !parent->IsFloatContainingBlock()); } +/* static */ +nsBlockFrame* +nsBlockFrame::GetNearestAncestorBlock(nsIFrame* aCandidate) +{ + nsBlockFrame* block = nsnull; + while(aCandidate) { + aCandidate->QueryInterface(kBlockFrameCID, (void**)&block); + if (block) { + // yay, candidate is a block! + return block; + } + // Not a block. Check its parent next. + aCandidate = aCandidate->GetParent(); + } + NS_NOTREACHED("Fell off frame tree looking for ancestor block!"); + return nsnull; +} + #ifdef IBMBIDI nsresult nsBlockFrame::ResolveBidi() diff --git a/layout/generic/nsBlockFrame.h b/layout/generic/nsBlockFrame.h index 1947e1efc4b9..373edcc739fd 100644 --- a/layout/generic/nsBlockFrame.h +++ b/layout/generic/nsBlockFrame.h @@ -293,6 +293,11 @@ public: static PRBool BlockIsMarginRoot(nsIFrame* aBlock); static PRBool BlockNeedsSpaceManager(nsIFrame* aBlock); + /** + * Walks up the frame tree, starting with aCandidate, and returns the first + * block frame that it encounters. + */ + static nsBlockFrame* GetNearestAncestorBlock(nsIFrame* aCandidate); protected: nsBlockFrame(nsStyleContext* aContext) diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 22d4c8e3117d..a886c151cdfa 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -1396,7 +1396,7 @@ nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder, nsRect clipRect; PRBool applyAbsPosClipping = ApplyAbsPosClipping(aBuilder, disp, aChild, &clipRect); - // A psuedo-stacking context (e.g., a positioned element with z-index auto). + // A pseudo-stacking context (e.g., a positioned element with z-index auto). // we allow positioned descendants of this element to escape to our // container's positioned descendant list, because they might be // z-index:non-auto @@ -5393,8 +5393,8 @@ nsFrame::CorrectStyleParentFrame(nsIFrame* aProspectiveParent, return aProspectiveParent; } - // Otherwise, walk up out of all anon boxes. For placeholder frames, walk ot - // of all pseudo-elements a well. Otherwise ReParentStyleContext could cause + // Otherwise, walk up out of all anon boxes. For placeholder frames, walk out + // of all pseudo-elements as well. Otherwise ReParentStyleContext could cause // style data to be out of sync with the frame tree. nsIFrame* parent = aProspectiveParent; do { diff --git a/layout/generic/nsHTMLFrame.cpp b/layout/generic/nsHTMLFrame.cpp index c41d9d672961..f01a2a03ada3 100644 --- a/layout/generic/nsHTMLFrame.cpp +++ b/layout/generic/nsHTMLFrame.cpp @@ -571,6 +571,13 @@ CanvasFrame::Reflow(nsPresContext* aPresContext, nsSize(aReflowState.availableWidth, NS_UNCONSTRAINEDSIZE)); + if (aReflowState.mFlags.mVResize && + (kidFrame->GetStateBits() & NS_FRAME_CONTAINS_RELATIVE_HEIGHT)) { + // Tell our kid it's being vertically resized too. Bit of a + // hack for framesets. + kidReflowState.mFlags.mVResize = PR_TRUE; + } + // Reflow the frame ReflowChild(kidFrame, aPresContext, kidDesiredSize, kidReflowState, kidReflowState.mComputedMargin.left, kidReflowState.mComputedMargin.top, diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp index 93de91d44f4f..f43e189ac422 100644 --- a/layout/generic/nsLineLayout.cpp +++ b/layout/generic/nsLineLayout.cpp @@ -118,6 +118,7 @@ nsLineLayout::nsLineLayout(nsPresContext* aPresContext, mPlacedFloats = 0; mTotalPlacedFrames = 0; mTopEdge = 0; + mTrimmableWidth = 0; // Instead of always pre-initializing the free-lists for frames and // spans, we do it on demand so that situations that only use a few @@ -1034,7 +1035,9 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame, } if (!continuingTextRun) { - SetHasTrailingTextFrame(PR_FALSE); + if (!pfd->GetFlag(PFD_SKIPWHENTRIMMINGWHITESPACE)) { + mTrimmableWidth = 0; + } if (!psd->mNoWrap && (!CanPlaceFloatNow() || placedFloat)) { // record soft break opportunity after this content that can't be // part of a text run. This is not a text frame so we know @@ -1183,7 +1186,7 @@ nsLineLayout::CanPlaceFrame(PerFrameData* pfd, // Set outside to PR_TRUE if the result of the reflow leads to the // frame sticking outside of our available area. - PRBool outside = pfd->mBounds.XMost() + endMargin > psd->mRightEdge; + PRBool outside = pfd->mBounds.XMost() - mTrimmableWidth + endMargin > psd->mRightEdge; if (!outside) { // If it fits, it fits #ifdef NOISY_CAN_PLACE_FRAME diff --git a/layout/generic/nsLineLayout.h b/layout/generic/nsLineLayout.h index fa6e33d52723..7170564a522a 100644 --- a/layout/generic/nsLineLayout.h +++ b/layout/generic/nsLineLayout.h @@ -143,10 +143,9 @@ protected: #define LL_LASTFLOATWASLETTERFRAME 0x00000080 #define LL_CANPLACEFLOAT 0x00000100 #define LL_LINEENDSINBR 0x00000200 -#define LL_HASTRAILINGTEXTFRAME 0x00000400 -#define LL_NEEDBACKUP 0x00000800 -#define LL_INFIRSTLINE 0x00002000 -#define LL_GOTLINEBOX 0x00004000 +#define LL_NEEDBACKUP 0x00000400 +#define LL_INFIRSTLINE 0x00000800 +#define LL_GOTLINEBOX 0x00001000 #define LL_LASTFLAG LL_GOTLINEBOX PRUint16 mFlags; @@ -203,17 +202,8 @@ public: return mBlockRS->AddFloat(*this, aFrame, PR_FALSE, aReflowStatus); } - /** - * If the last content placed on the line (not counting inline containers) - * was text, and can form a contiguous text flow with the next content to be - * placed, and is not just a frame of all-skipped whitespace, this flag is - * true. - */ - PRBool HasTrailingTextFrame() const { - return GetFlag(LL_HASTRAILINGTEXTFRAME); - } - void SetHasTrailingTextFrame(PRBool aHasTrailingTextFrame) { - SetFlag(LL_HASTRAILINGTEXTFRAME, aHasTrailingTextFrame); + void SetTrimmableWidth(nscoord aTrimmableWidth) { + mTrimmableWidth = aTrimmableWidth; } //---------------------------------------- @@ -377,6 +367,9 @@ protected: // Final computed line-height value after VerticalAlignFrames for // the block has been called. nscoord mFinalLineHeight; + + // Amount of trimmable whitespace width for the trailing text frame, if any + nscoord mTrimmableWidth; // Per-frame data recorded by the line-layout reflow logic. This // state is the state needed to post-process the line after reflow diff --git a/layout/generic/nsObjectFrame.cpp b/layout/generic/nsObjectFrame.cpp index 41b62c5774dd..2da713f84bce 100644 --- a/layout/generic/nsObjectFrame.cpp +++ b/layout/generic/nsObjectFrame.cpp @@ -533,6 +533,22 @@ nsObjectFrame::Destroy() nsObjectFrameSuper::Destroy(); } +NS_IMETHODIMP +nsObjectFrame::DidSetStyleContext() +{ + if (HasView()) { + nsIView* view = GetView(); + nsIViewManager* vm = view->GetViewManager(); + if (vm) { + nsViewVisibility visibility = + IsHidden() ? nsViewVisibility_kHide : nsViewVisibility_kShow; + vm->SetViewVisibility(view, visibility); + } + } + + return nsObjectFrameSuper::DidSetStyleContext(); +} + nsIAtom* nsObjectFrame::GetType() const { @@ -608,7 +624,9 @@ nsObjectFrame::CreateWidget(nscoord aWidth, } - viewMan->SetViewVisibility(view, nsViewVisibility_kShow); + if (!IsHidden()) { + viewMan->SetViewVisibility(view, nsViewVisibility_kShow); + } return NS_OK; } diff --git a/layout/generic/nsObjectFrame.h b/layout/generic/nsObjectFrame.h index 47c21e252437..2d2ed2be2275 100644 --- a/layout/generic/nsObjectFrame.h +++ b/layout/generic/nsObjectFrame.h @@ -107,6 +107,8 @@ public: virtual void Destroy(); + NS_IMETHOD DidSetStyleContext(); + NS_IMETHOD GetPluginInstance(nsIPluginInstance*& aPluginInstance); virtual nsresult Instantiate(nsIChannel* aChannel, nsIStreamListener** aStreamListener); virtual nsresult Instantiate(const char* aMimeType, nsIURI* aURI); diff --git a/layout/generic/nsTextFrameThebes.cpp b/layout/generic/nsTextFrameThebes.cpp index c7648149233e..d1cfd87a4788 100644 --- a/layout/generic/nsTextFrameThebes.cpp +++ b/layout/generic/nsTextFrameThebes.cpp @@ -633,7 +633,6 @@ public: // ancestor of mStartFrame and the previous text frame, or null if there // was no previous text frame on this line. nsIFrame* mAncestorControllingInitialBreak; - PRUint32 mTransformedTextOffset; // Only used inside BuildTextRunForFrames PRInt32 GetContentEnd() { return mEndFrame ? mEndFrame->GetContentOffset() @@ -654,6 +653,8 @@ public: if (mTextRun->SetPotentialLineBreaks(aOffset + mOffsetIntoTextRun, aLength, aBreakBefore, mContext)) { mChangedBreaks = PR_TRUE; + // Be conservative and assume that some breaks have been set + mTextRun->ClearFlagBits(nsTextFrameUtils::TEXT_NO_BREAKS); } } @@ -1078,6 +1079,17 @@ BuildTextRunsScanner::ContinueTextRunAcrossFrames(nsTextFrame* aFrame1, nsTextFr if (textStyle1->WhiteSpaceIsSignificant() && HasTerminalNewline(aFrame1)) return PR_FALSE; + if (aFrame1->GetContent() == aFrame2->GetContent() && + aFrame1->GetNextInFlow() != aFrame2) { + // aFrame2 must be a non-fluid continuation of aFrame1. This can happen + // sometimes when the unicode-bidi property is used; the bidi resolver + // breaks text into different frames even though the text has the same + // direction. We can't allow these two frames to share the same textrun + // because that would violate our invariant that two flows in the same + // textrun have different content elements. + return PR_FALSE; + } + nsStyleContext* sc2 = aFrame2->GetStyleContext(); if (sc1 == sc2) return PR_TRUE; @@ -1132,8 +1144,6 @@ void BuildTextRunsScanner::ScanFrame(nsIFrame* aFrame) mappedFlow->mStartFrame = frame; mappedFlow->mAncestorControllingInitialBreak = mCommonAncestorWithLastFrame; - // This is temporary: it's overwritten in BuildTextRunForFrames - mappedFlow->mTransformedTextOffset = 0; AccumulateRunInfo(frame); if (mMappedFlows.Length() == 1) { @@ -1325,8 +1335,6 @@ BuildTextRunsScanner::BuildTextRunForFrames(void* aTextBuffer) MappedFlow* mappedFlow = &mMappedFlows[i]; nsTextFrame* f = mappedFlow->mStartFrame; - mappedFlow->mTransformedTextOffset = currentTransformedTextOffset; - lastStyleContext = f->GetStyleContext(); // Detect use of text-transform or font-variant anywhere in the run textStyle = f->GetStyleText(); @@ -1451,29 +1459,6 @@ BuildTextRunsScanner::BuildTextRunForFrames(void* aTextBuffer) return; } - // Setup factory chain - nsAutoPtr transformingFactory; - if (anySmallcapsStyle) { - transformingFactory = new nsFontVariantTextRunFactory(); - } - if (anyTextTransformStyle) { - transformingFactory = - new nsCaseTransformTextRunFactory(transformingFactory.forget()); - } - nsTArray styles; - if (transformingFactory) { - for (i = 0; i < mMappedFlows.Length(); ++i) { - MappedFlow* mappedFlow = &mMappedFlows[i]; - PRUint32 end = i == mMappedFlows.Length() - 1 ? transformedLength : - mMappedFlows[i + 1].mTransformedTextOffset; - nsStyleContext* sc = mappedFlow->mStartFrame->GetStyleContext(); - PRUint32 j; - for (j = mappedFlow->mTransformedTextOffset; j < end; ++j) { - styles.AppendElement(sc); - } - } - } - if (textFlags & nsTextFrameUtils::TEXT_HAS_TAB) { textFlags |= gfxTextRunFactory::TEXT_ENABLE_SPACING; } @@ -1511,6 +1496,32 @@ BuildTextRunsScanner::BuildTextRunForFrames(void* aTextBuffer) AppendLineBreakOffset(&textBreakPointsAfterTransform, transformedLength); } + // Setup factory chain + nsAutoPtr transformingFactory; + if (anySmallcapsStyle) { + transformingFactory = new nsFontVariantTextRunFactory(); + } + if (anyTextTransformStyle) { + transformingFactory = + new nsCaseTransformTextRunFactory(transformingFactory.forget()); + } + nsTArray styles; + if (transformingFactory) { + iter.SetOriginalOffset(0); + for (i = 0; i < mMappedFlows.Length(); ++i) { + MappedFlow* mappedFlow = &mMappedFlows[i]; + PRUint32 offset = iter.GetSkippedOffset(); + iter.AdvanceOriginal(mappedFlow->GetContentEnd() - + mappedFlow->mStartFrame->GetContentOffset()); + PRUint32 end = iter.GetSkippedOffset(); + nsStyleContext* sc = mappedFlow->mStartFrame->GetStyleContext(); + PRUint32 j; + for (j = offset; j < end; ++j) { + styles.AppendElement(sc); + } + } + } + gfxTextRun* textRun; gfxTextRunFactory::Parameters params = { mContext, finalUserData, &skipChars, @@ -1604,50 +1615,40 @@ BuildTextRunsScanner::SetupBreakSinksForTextRun(gfxTextRun* aTextRun, PRUint32 i; for (i = 0; i < mMappedFlows.Length(); ++i) { MappedFlow* mappedFlow = &mMappedFlows[i]; + PRUint32 offset = iter.GetSkippedOffset(); + gfxSkipCharsIterator iterNext = iter; + iterNext.AdvanceOriginal(mappedFlow->GetContentEnd() - + mappedFlow->mStartFrame->GetContentOffset()); + nsAutoPtr* breakSink = mBreakSinks.AppendElement( - new BreakSink(aTextRun, mContext, - mappedFlow->mTransformedTextOffset, aIsExistingTextRun)); + new BreakSink(aTextRun, mContext, offset, aIsExistingTextRun)); if (!breakSink || !*breakSink) return; - PRUint32 offset = mappedFlow->mTransformedTextOffset; - - PRUint32 length = - (i == mMappedFlows.Length() - 1 ? aTextRun->GetLength() - : mMappedFlows[i + 1].mTransformedTextOffset) - - offset; + PRUint32 length = iterNext.GetSkippedOffset() - offset; + PRUint32 flags = 0; + nsIFrame* initialBreakController = mappedFlow->mAncestorControllingInitialBreak; + if (!initialBreakController) { + initialBreakController = mLineContainer; + } + if (!initialBreakController->GetStyleText()->WhiteSpaceCanWrap()) { + flags |= nsLineBreaker::BREAK_SUPPRESS_INITIAL; + } nsTextFrame* startFrame = mappedFlow->mStartFrame; + const nsStyleText* textStyle = startFrame->GetStyleText(); + if (!textStyle->WhiteSpaceCanWrap()) { + flags |= nsLineBreaker::BREAK_SUPPRESS_INSIDE; + } + if (aTextRun->GetFlags() & nsTextFrameUtils::TEXT_NO_BREAKS) { + flags |= nsLineBreaker::BREAK_SKIP_SETTING_NO_BREAKS; + } + if (HasCompressedLeadingWhitespace(startFrame, mappedFlow->GetContentEnd(), iter)) { - mLineBreaker.AppendInvisibleWhitespace(); + mLineBreaker.AppendInvisibleWhitespace(flags); } if (length > 0) { - PRUint32 flags = 0; - nsIFrame* initialBreakController = mappedFlow->mAncestorControllingInitialBreak; - if (!initialBreakController) { - initialBreakController = mLineContainer; - } - if (initialBreakController->GetStyleText()->WhiteSpaceCanWrap()) { - flags |= nsLineBreaker::BREAK_ALLOW_INITIAL; - } - const nsStyleText* textStyle = startFrame->GetStyleText(); - if (textStyle->WhiteSpaceCanWrap()) { - // If white-space is preserved, then the only break opportunity is at - // the end of whitespace runs; otherwise there is a break opportunity before - // and after each whitespace character - flags |= nsLineBreaker::BREAK_ALLOW_INSIDE; - } - - BreakSink* sink = *breakSink; - if (aSuppressSink) { - sink = nsnull; - } else if (flags) { - aTextRun->ClearFlagBits(nsTextFrameUtils::TEXT_NO_BREAKS); - } else if (aTextRun->GetFlags() & nsTextFrameUtils::TEXT_NO_BREAKS) { - // Don't bother setting breaks on a textrun that can't be broken - // and currently has no breaks set... - sink = nsnull; - } + BreakSink* sink = aSuppressSink ? nsnull : (*breakSink).get(); if (aTextRun->GetFlags() & gfxFontGroup::TEXT_IS_8BIT) { mLineBreaker.AppendText(lang, aTextRun->GetText8Bit() + offset, length, flags, sink); @@ -1657,8 +1658,7 @@ BuildTextRunsScanner::SetupBreakSinksForTextRun(gfxTextRun* aTextRun, } } - iter.AdvanceOriginal(mappedFlow->GetContentEnd() - - mappedFlow->mStartFrame->GetContentOffset()); + iter = iterNext; } } @@ -1744,10 +1744,8 @@ nsTextFrame::EnsureTextRun(gfxContext* aReferenceContext, nsIFrame* aLineContain for (i = startAt; 0 <= i && i < userData->mMappedFlowCount; i += direction) { TextRunMappedFlow* flow = &userData->mMappedFlows[i]; if (flow->mStartFrame->GetContent() == mContent) { - // This may not actually be the flow that we're in. But BuildTextRuns - // promises that this will work ... flows for the same content in the same - // textrun have to be consecutive, they can't skip characters in the middle. - // See assertion "Gap in textframes mapping content?!" above. + // Since textruns can only contain one flow for a given content element, + // this must be our flow. userData->mLastFlowIndex = i; gfxSkipCharsIterator iter(mTextRun->GetSkipChars(), flow->mDOMOffsetToBeforeTransformOffset, mContentOffset); @@ -1803,8 +1801,7 @@ nsTextFrame::GetTrimmedOffsets(const nsTextFragment* aFrag, offsets.mLength -= whitespaceCount; } - if (aTrimAfter && (GetStateBits() & TEXT_END_OF_LINE) && - textStyle->WhiteSpaceCanWrap()) { + if (aTrimAfter && (GetStateBits() & TEXT_END_OF_LINE)) { PRInt32 whitespaceCount = GetTrimmableWhitespaceCount(aFrag, offsets.GetEnd() - 1, offsets.mLength, -1); @@ -5222,8 +5219,6 @@ nsTextFrame::Reflow(nsPresContext* aPresContext, NS_ASSERTION(!(NS_REFLOW_CALC_BOUNDING_METRICS & aMetrics.mFlags), "We shouldn't be passed NS_REFLOW_CALC_BOUNDING_METRICS anymore"); #endif - PRBool suppressInitialBreak = !lineLayout.LineIsBreakable() || - !lineLayout.HasTrailingTextFrame(); PRInt32 limitLength = length; PRInt32 forceBreak = lineLayout.GetForcedBreakPosition(mContent); @@ -5255,13 +5250,12 @@ nsTextFrame::Reflow(nsPresContext* aPresContext, PRBool usedHyphenation; gfxFloat trimmedWidth = 0; gfxFloat availWidth = aReflowState.availableWidth; - PRBool canTrimTrailingWhitespace = !textStyle->WhiteSpaceIsSignificant() && - textStyle->WhiteSpaceCanWrap(); + PRBool canTrimTrailingWhitespace = !textStyle->WhiteSpaceIsSignificant(); PRUint32 transformedCharsFit = mTextRun->BreakAndMeasureText(transformedOffset, transformedLength, (GetStateBits() & TEXT_START_OF_LINE) != 0, availWidth, - &provider, suppressInitialBreak, + &provider, !lineLayout.LineIsBreakable(), canTrimTrailingWhitespace ? &trimmedWidth : nsnull, &textMetrics, needTightBoundingBox, ctx, &usedHyphenation, &transformedLastBreak); @@ -5299,26 +5293,38 @@ nsTextFrame::Reflow(nsPresContext* aPresContext, AddStateBits(TEXT_HYPHEN_BREAK); } - // If everything fits including trimmed whitespace, then we should add the - // trimmed whitespace to our metrics now because it probably won't be trimmed - // and we need to position subsequent frames correctly... - if (forceBreak < 0 && textMetrics.mAdvanceWidth + trimmedWidth <= availWidth) { - textMetrics.mAdvanceWidth += trimmedWidth; - if (mTextRun->IsRightToLeft()) { - // Space comes before text, so the bounding box is moved to the - // right by trimmdWidth - textMetrics.mBoundingBox.MoveBy(gfxPoint(trimmedWidth, 0)); + gfxFloat trimmableWidth = 0; + if (canTrimTrailingWhitespace) { + // Optimization: if we trimmed trailing whitespace, and we can be sure + // this frame will be at the end of the line, then leave it trimmed off. + // Otherwise we have to undo the trimming, in case we're not at the end of + // the line. (If we actually do end up at the end of the line, we'll have + // to trim it off again in TrimTrailingWhiteSpace, and we'd like to avoid + // having to re-do it.) + if (forceBreak >= 0 || transformedCharsFit < transformedLength) { + // We're definitely going to break so our trailing whitespace should + // definitely be timmed. Record that we've already done it. + AddStateBits(TEXT_TRIMMED_TRAILING_WHITESPACE); + } else { + // We might not be at the end of the line. (Note that even if this frame + // ends in breakable whitespace, it might not be at the end of the line + // because it might be followed by breakable, but preformatted, whitespace.) + // Undo the trimming. + textMetrics.mAdvanceWidth += trimmedWidth; + trimmableWidth = trimmedWidth; + if (mTextRun->IsRightToLeft()) { + // Space comes before text, so the bounding box is moved to the + // right by trimmdWidth + textMetrics.mBoundingBox.MoveBy(gfxPoint(trimmedWidth, 0)); + } + + // Since everything fit and no break was forced, + // record the last break opportunity + if (lastBreak >= 0) { + lineLayout.NotifyOptionalBreakPosition(mContent, lastBreak, + textMetrics.mAdvanceWidth <= aReflowState.availableWidth); + } } - - if (lastBreak >= 0) { - lineLayout.NotifyOptionalBreakPosition(mContent, lastBreak, - textMetrics.mAdvanceWidth <= aReflowState.availableWidth); - } - } else { - // We're definitely going to break and our whitespace will definitely - // be trimmed. - // Record that whitespace has already been trimmed. - AddStateBits(TEXT_TRIMMED_TRAILING_WHITESPACE); } PRInt32 contentLength = offset + charsFit - GetContentOffset(); @@ -5353,25 +5359,19 @@ nsTextFrame::Reflow(nsPresContext* aPresContext, // Clean up, update state ///////////////////////////////////////////////////////////////////// - if (charsFit > 0) { - lineLayout.SetHasTrailingTextFrame(PR_TRUE); - if (charsFit == length) { - if (textStyle->WhiteSpaceCanWrap() && - IsTrimmableSpace(frag, offset + charsFit - 1)) { - // Record a potential break after final breakable whitespace - lineLayout.NotifyOptionalBreakPosition(mContent, offset + length, - textMetrics.mAdvanceWidth <= aReflowState.availableWidth); - } else if (HasSoftHyphenBefore(frag, mTextRun, offset, end)) { - // Record a potential break after final soft hyphen - lineLayout.NotifyOptionalBreakPosition(mContent, offset + length, - textMetrics.mAdvanceWidth + provider.GetHyphenWidth() <= availWidth); - } - } - } else { - // Don't allow subsequent text frame to break-before. All our text is - // being skipped (usually whitespace, could be discarded Unicode control - // characters). - lineLayout.SetHasTrailingTextFrame(PR_FALSE); + // If all our characters are discarded or collapsed, then trimmable width + // from the last textframe should be preserved. Otherwise the trimmable width + // from this textframe overrides. (Currently in CSS trimmable width can be + // at most one space so there's no way for trimmable width from a previous + // frame to accumulate with trimmable width from this frame.) + if (transformedCharsFit > 0) { + lineLayout.SetTrimmableWidth(NSToCoordFloor(trimmableWidth)); + } + if (charsFit > 0 && charsFit == length && + HasSoftHyphenBefore(frag, mTextRun, offset, end)) { + // Record a potential break after final soft hyphen + lineLayout.NotifyOptionalBreakPosition(mContent, offset + length, + textMetrics.mAdvanceWidth + provider.GetHyphenWidth() <= availWidth); } if (completedFirstLetter) { lineLayout.SetFirstLetterStyleOK(PR_FALSE); diff --git a/layout/mathml/base/src/nsMathMLFrame.cpp b/layout/mathml/base/src/nsMathMLFrame.cpp index 9611a960bcf0..6c6516c77e1b 100644 --- a/layout/mathml/base/src/nsMathMLFrame.cpp +++ b/layout/mathml/base/src/nsMathMLFrame.cpp @@ -594,7 +594,7 @@ GetMathMLAttributeStyleSheet(nsPresContext* aPresContext, nsCOMPtr cssSheet(do_CreateInstance(kCSSStyleSheetCID)); if (!cssSheet) return; - cssSheet->SetURIs(uri, uri); + cssSheet->SetURIs(uri, nsnull, uri); cssSheet->SetTitle(NS_ConvertASCIItoUTF16(kTitle)); // all done, no further activity from the net involved, so we better do this cssSheet->SetComplete(); diff --git a/layout/reftests/bidi/bidi-000-ref.html b/layout/reftests/bidi/bidi-000-ref.html index 6576586f3f93..9f86f8fa6193 100644 --- a/layout/reftests/bidi/bidi-000-ref.html +++ b/layout/reftests/bidi/bidi-000-ref.html @@ -3,7 +3,7 @@ directory can be relied upon --> -

    the quick brown fox jumps over the lazy dog

    diff --git a/layout/reftests/bidi/bidi-001-j.html b/layout/reftests/bidi/bidi-001-j.html index 2480ada3a154..045232ed635f 100644 --- a/layout/reftests/bidi/bidi-001-j.html +++ b/layout/reftests/bidi/bidi-001-j.html @@ -2,17 +2,15 @@ - -

    המשא אשר חזה חבקוק הנביא - - +

    המשא אשר חזה חבקוק הנביא

    diff --git a/layout/reftests/bidi/bidi-001-ref.html b/layout/reftests/bidi/bidi-001-ref.html index 4fb27b6f55bf..26583434d154 100644 --- a/layout/reftests/bidi/bidi-001-ref.html +++ b/layout/reftests/bidi/bidi-001-ref.html @@ -1,13 +1,13 @@ -

    איבנה קוקבח הזח רשא אשמה

    diff --git a/layout/reftests/bidi/bidi-001-v.html b/layout/reftests/bidi/bidi-001-v.html index dae3f1ebbce8..adc4fbdaeeca 100644 --- a/layout/reftests/bidi/bidi-001-v.html +++ b/layout/reftests/bidi/bidi-001-v.html @@ -2,14 +2,14 @@ -

    diff --git a/layout/reftests/bidi/bidi-001.html b/layout/reftests/bidi/bidi-001.html index a1dc46643f8f..1b5bedae1758 100644 --- a/layout/reftests/bidi/bidi-001.html +++ b/layout/reftests/bidi/bidi-001.html @@ -2,7 +2,7 @@ - -

    המשא אשר חזה חבקוק הנביא - - +

    המשא אשר חזה חבקוק הנביא

    diff --git a/layout/reftests/bidi/bidi-002-ref.html b/layout/reftests/bidi/bidi-002-ref.html index c1bb285d8969..5fd5e7483edf 100644 --- a/layout/reftests/bidi/bidi-002-ref.html +++ b/layout/reftests/bidi/bidi-002-ref.html @@ -1,13 +1,13 @@ -

    v2.0.0.4 תירבעה הסריגה Mozilla Firefox

    diff --git a/layout/reftests/bidi/bidi-002.html b/layout/reftests/bidi/bidi-002.html index e349f4c194ac..dcb966823acd 100644 --- a/layout/reftests/bidi/bidi-002.html +++ b/layout/reftests/bidi/bidi-002.html @@ -2,14 +2,14 @@ -

    Mozilla Firefox הגירסה העברית v2.0.0.4

    diff --git a/layout/reftests/bidi/bidi-003-ref.html b/layout/reftests/bidi/bidi-003-ref.html index ec7e146451fb..65f6e8cfb1e0 100644 --- a/layout/reftests/bidi/bidi-003-ref.html +++ b/layout/reftests/bidi/bidi-003-ref.html @@ -1,13 +1,13 @@ -

    v2.0.0.4 תירבעה הסריגה Mozilla Firefox

    diff --git a/layout/reftests/bidi/bidi-003.html b/layout/reftests/bidi/bidi-003.html index 2073d75fa58a..56f491c05ccb 100644 --- a/layout/reftests/bidi/bidi-003.html +++ b/layout/reftests/bidi/bidi-003.html @@ -3,14 +3,14 @@ directional run boundaries --> -

    Mozilla Firefox הגירסה העברית v2.0.0.4

    diff --git a/layout/reftests/bidi/bidi-004-j.html b/layout/reftests/bidi/bidi-004-j.html index 07931816e2f5..0b197669735c 100644 --- a/layout/reftests/bidi/bidi-004-j.html +++ b/layout/reftests/bidi/bidi-004-j.html @@ -2,14 +2,14 @@ -

    אַבּוּשׁ

    diff --git a/layout/reftests/bidi/bidi-004-ref.html b/layout/reftests/bidi/bidi-004-ref.html index 2d3ccae21d65..e2e8897f10b1 100644 --- a/layout/reftests/bidi/bidi-004-ref.html +++ b/layout/reftests/bidi/bidi-004-ref.html @@ -1,13 +1,13 @@ -

    שׁוּבּאַ

    diff --git a/layout/reftests/bidi/bidi-004.html b/layout/reftests/bidi/bidi-004.html index d5665c6c3f55..f6d0a0cfd236 100644 --- a/layout/reftests/bidi/bidi-004.html +++ b/layout/reftests/bidi/bidi-004.html @@ -2,7 +2,7 @@ -

    𐤆𐤅𐤇𐤓𐤉𐤟𐤐𐤎𐤀𐤅𐤇𐤓𐤉

    diff --git a/layout/reftests/bidi/bidi-005.html b/layout/reftests/bidi/bidi-005.html index dfb255eddf2b..0ec2eafc7ab4 100644 --- a/layout/reftests/bidi/bidi-005.html +++ b/layout/reftests/bidi/bidi-005.html @@ -2,17 +2,15 @@ - -

    𐤉𐤓𐤇𐤅𐤀𐤎𐤐𐤟𐤉𐤓𐤇𐤅𐤆 - - +

    𐤉𐤓𐤇𐤅𐤀𐤎𐤐𐤟𐤉𐤓𐤇𐤅𐤆

    diff --git a/layout/reftests/bidi/bidi-006-j.html b/layout/reftests/bidi/bidi-006-j.html index 64cdd7d5a055..4bc5d99e8ec7 100644 --- a/layout/reftests/bidi/bidi-006-j.html +++ b/layout/reftests/bidi/bidi-006-j.html @@ -43,7 +43,7 @@ p#test { } -

    זָ

    -

    ז

    +

    נָ

    +

    נ

    diff --git a/layout/reftests/bidi/bidi-006-ref.html b/layout/reftests/bidi/bidi-006-ref.html index 45711cf2c83f..5f4a31e44cd1 100644 --- a/layout/reftests/bidi/bidi-006-ref.html +++ b/layout/reftests/bidi/bidi-006-ref.html @@ -35,7 +35,7 @@ span { p#test { margin: 0 3em; } -

    זָ

    -

    ז

    +

    נָ

    +

    נ

    diff --git a/layout/reftests/bidi/bidi-006.html b/layout/reftests/bidi/bidi-006.html index bb32b39544d2..01118469b208 100644 --- a/layout/reftests/bidi/bidi-006.html +++ b/layout/reftests/bidi/bidi-006.html @@ -42,7 +42,7 @@ p#test { } -

    זָ

    -

    ז

    +

    נָ

    +

    נ

    diff --git a/layout/reftests/bidi/reftest.list b/layout/reftests/bidi/reftest.list index 6bdaf1ca44b8..85f5ed2be1b6 100644 --- a/layout/reftests/bidi/reftest.list +++ b/layout/reftests/bidi/reftest.list @@ -7,7 +7,7 @@ fails-if(MOZ_WIDGET_TOOLKIT!="windows") == bidi-004.html bidi-004-ref.html # Bug 386567 (Linux), bug 386573 (Mac) fails-if(MOZ_WIDGET_TOOLKIT!="windows") == bidi-004-j.html bidi-004-ref.html == bidi-005.html bidi-005-ref.html -fails-if(MOZ_WIDGET_TOOLKIT=="cocoa") == bidi-006.html bidi-006-ref.html # Bug 386573 -fails-if(MOZ_WIDGET_TOOLKIT=="cocoa") == bidi-006-j.html bidi-006-ref.html # Bug 386573 +== bidi-006.html bidi-006-ref.html +== bidi-006-j.html bidi-006-ref.html == 386339.html 386339-ref.html fails-if(MOZ_WIDGET_TOOLKIT!="gtk2") == 387653.html 387653-ref.html # Linux-specific bug diff --git a/layout/reftests/bugs/23604-1-ref.html b/layout/reftests/bugs/23604-1-ref.html new file mode 100644 index 000000000000..536728eec875 --- /dev/null +++ b/layout/reftests/bugs/23604-1-ref.html @@ -0,0 +1,13 @@ + + + + + +

    The first letter of this paragraph should be + in sans-serif while the first-line should be in monospace.

    + + diff --git a/layout/reftests/bugs/23604-1.html b/layout/reftests/bugs/23604-1.html new file mode 100644 index 000000000000..14d3cfa70457 --- /dev/null +++ b/layout/reftests/bugs/23604-1.html @@ -0,0 +1,18 @@ + + + + + + +

    The first letter of this paragraph should be + in sans-serif while the first-line should be in monospace.

    + + diff --git a/layout/reftests/bugs/23604-2-ref.html b/layout/reftests/bugs/23604-2-ref.html new file mode 100644 index 000000000000..4fae573513ee --- /dev/null +++ b/layout/reftests/bugs/23604-2-ref.html @@ -0,0 +1,37 @@ + + + + + + + +
      +
    • Lorem ipsum dolor sit amet
    • +
    +
      +
    • Lorem ipsum dolor sit amet
    • +
    +
      +
    • Lorem ipsum dolor sit amet
    • +
    + + diff --git a/layout/reftests/bugs/23604-2.html b/layout/reftests/bugs/23604-2.html new file mode 100644 index 000000000000..ff62d5fc0c20 --- /dev/null +++ b/layout/reftests/bugs/23604-2.html @@ -0,0 +1,42 @@ + + + + + + + + +
      +
    • Lorem ipsum dolor sit amet
    • +
    +
      +
    • Lorem ipsum dolor sit amet
    • +
    +
      +
    • Lorem ipsum dolor sit amet
    • +
    + + diff --git a/layout/reftests/bugs/244135-2-ref.html b/layout/reftests/bugs/244135-2-ref.html new file mode 100644 index 000000000000..754c98a8f149 --- /dev/null +++ b/layout/reftests/bugs/244135-2-ref.html @@ -0,0 +1,46 @@ + + + +http://bugzilla.mozilla.org/show_bug.cgi?id=244135 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/layout/reftests/bugs/244135-2.html b/layout/reftests/bugs/244135-2.html new file mode 100644 index 000000000000..1352d61985e3 --- /dev/null +++ b/layout/reftests/bugs/244135-2.html @@ -0,0 +1,47 @@ + + + +http://bugzilla.mozilla.org/show_bug.cgi?id=244135 + + + +
    texttexttexttext
    td rowspan=4texttexttext +
    texttexttext +
    texttexttext + + +
    texttexttext +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/layout/reftests/bugs/321402-1.html b/layout/reftests/bugs/321402-1.html new file mode 100644 index 000000000000..1ab7a4871104 --- /dev/null +++ b/layout/reftests/bugs/321402-1.html @@ -0,0 +1,2 @@ + +hello world diff --git a/layout/reftests/bugs/321402-2.html b/layout/reftests/bugs/321402-2.html new file mode 100644 index 000000000000..8ffd3e619e8c --- /dev/null +++ b/layout/reftests/bugs/321402-2.html @@ -0,0 +1,2 @@ + +  diff --git a/layout/reftests/bugs/321402-3-ref.xul b/layout/reftests/bugs/321402-3-ref.xul new file mode 100644 index 000000000000..856b4a012da6 --- /dev/null +++ b/layout/reftests/bugs/321402-3-ref.xul @@ -0,0 +1,6 @@ + + + + diff --git a/layout/reftests/bugs/321402-3.xul b/layout/reftests/bugs/321402-3.xul new file mode 100644 index 000000000000..bae78277dec4 --- /dev/null +++ b/layout/reftests/bugs/321402-3.xul @@ -0,0 +1,8 @@ + + + + + + diff --git a/layout/reftests/bugs/321402-4-ref.xul b/layout/reftests/bugs/321402-4-ref.xul new file mode 100644 index 000000000000..8e6171664d17 --- /dev/null +++ b/layout/reftests/bugs/321402-4-ref.xul @@ -0,0 +1,8 @@ + + + + + + diff --git a/layout/reftests/bugs/321402-4.xul b/layout/reftests/bugs/321402-4.xul new file mode 100644 index 000000000000..0e0fc1ece6e9 --- /dev/null +++ b/layout/reftests/bugs/321402-4.xul @@ -0,0 +1,25 @@ + + class="reftest-wait"> + + + + + diff --git a/layout/reftests/bugs/321402-5-ref.xul b/layout/reftests/bugs/321402-5-ref.xul new file mode 100644 index 000000000000..96b86f6ee232 --- /dev/null +++ b/layout/reftests/bugs/321402-5-ref.xul @@ -0,0 +1,8 @@ + + + + + diff --git a/layout/reftests/bugs/321402-5.xul b/layout/reftests/bugs/321402-5.xul new file mode 100644 index 000000000000..ca98e8d40171 --- /dev/null +++ b/layout/reftests/bugs/321402-5.xul @@ -0,0 +1,25 @@ + + class="reftest-wait"> + + + + + diff --git a/layout/reftests/bugs/321402-6-ref.xul b/layout/reftests/bugs/321402-6-ref.xul new file mode 100644 index 000000000000..203d3f1d661c --- /dev/null +++ b/layout/reftests/bugs/321402-6-ref.xul @@ -0,0 +1,7 @@ + + + + + diff --git a/layout/reftests/bugs/321402-6.xul b/layout/reftests/bugs/321402-6.xul new file mode 100644 index 000000000000..e3c19fc2b4d5 --- /dev/null +++ b/layout/reftests/bugs/321402-6.xul @@ -0,0 +1,25 @@ + + class="reftest-wait"> + + + + + + diff --git a/layout/reftests/bugs/336736-1-ref.html b/layout/reftests/bugs/336736-1-ref.html index e8fe89728f39..116e5ade28d6 100644 --- a/layout/reftests/bugs/336736-1-ref.html +++ b/layout/reftests/bugs/336736-1-ref.html @@ -1,13 +1,5 @@ - - - a - +
     
    diff --git a/layout/reftests/bugs/336736-1.html b/layout/reftests/bugs/336736-1a.html similarity index 73% rename from layout/reftests/bugs/336736-1.html rename to layout/reftests/bugs/336736-1a.html index 9a32fa3a1f59..fb54f3060e13 100644 --- a/layout/reftests/bugs/336736-1.html +++ b/layout/reftests/bugs/336736-1a.html @@ -2,12 +2,12 @@ - - a - +
     
    + diff --git a/layout/reftests/bugs/336736-1b.html b/layout/reftests/bugs/336736-1b.html new file mode 100644 index 000000000000..85338167c244 --- /dev/null +++ b/layout/reftests/bugs/336736-1b.html @@ -0,0 +1,13 @@ + + + + +
     
    +
    + + diff --git a/layout/reftests/bugs/374927-1-ref.html b/layout/reftests/bugs/374927-1-ref.html new file mode 100644 index 000000000000..15752c40bd1f --- /dev/null +++ b/layout/reftests/bugs/374927-1-ref.html @@ -0,0 +1,26 @@ + + +The words "One Two Three" should appear down the right side of this page. +
    texttexttexttext
    td rowspan=4texttexttext + +
    texttexttext +
    texttexttext + + +
    texttexttext +
    + + + +
    + One
    + + + + + +
    + Two
    + + + + + +
    + Three
    + + + diff --git a/layout/reftests/bugs/374927-1.html b/layout/reftests/bugs/374927-1.html new file mode 100644 index 000000000000..a9691e53d48e --- /dev/null +++ b/layout/reftests/bugs/374927-1.html @@ -0,0 +1,29 @@ + + +The words "One Two Three" should appear down the right side of this page. + + + + + +
    One
    + + + + + + + +
    Two
    + + + + + + + + +
    Three
    + + + diff --git a/layout/reftests/bugs/389468-1-ref.html b/layout/reftests/bugs/389468-1-ref.html new file mode 100644 index 000000000000..2d31941cd93d --- /dev/null +++ b/layout/reftests/bugs/389468-1-ref.html @@ -0,0 +1,20 @@ + + + + + + + + + +
    China's Leader Closes Door to Reform - New York Times
    + Hostesses for the Communist Party's 17th National Congress played + Hostesses for the Communist Party's 17th National Congress played + Hostesses for the Communist Party's 17th National Congress played + Hostesses for the Communist Party's 17th National Congress played + a game Monday outside the Great Hall of the People. By + JOS... all 1,062 news + articles
    + + + \ No newline at end of file diff --git a/layout/reftests/bugs/389468-1.html b/layout/reftests/bugs/389468-1.html new file mode 100644 index 000000000000..1d22363154c9 --- /dev/null +++ b/layout/reftests/bugs/389468-1.html @@ -0,0 +1,28 @@ + + + + + + + + + +
    China's Leader Closes Door to Reform - New York Times
    + Hostesses for the Communist Party's 17th National Congress played + Hostesses for the Communist Party's 17th National Congress played + Hostesses for the Communist Party's 17th National Congress played + Hostesses for the Communist Party's 17th National Congress played + a game Monday outside the Great Hall of the People. By + JOS... all 1,062 news + articles
    + + + + \ No newline at end of file diff --git a/layout/reftests/bugs/391412-1-ref.html b/layout/reftests/bugs/391412-1-ref.html new file mode 100755 index 000000000000..e3474a8e2942 --- /dev/null +++ b/layout/reftests/bugs/391412-1-ref.html @@ -0,0 +1,8 @@ + +Testcase bug 391412 Regression in float layout causing "clear:" to be ignored + + +
    +
    + + diff --git a/layout/reftests/bugs/391412-1a.html b/layout/reftests/bugs/391412-1a.html new file mode 100755 index 000000000000..f2616cf11589 --- /dev/null +++ b/layout/reftests/bugs/391412-1a.html @@ -0,0 +1,11 @@ + +Testcase bug 391412 Regression in float layout causing "clear:" to be ignored + + +
    +
    +
    +
    +
    + + diff --git a/layout/reftests/bugs/391412-1b.html b/layout/reftests/bugs/391412-1b.html new file mode 100755 index 000000000000..a14f429f9ca6 --- /dev/null +++ b/layout/reftests/bugs/391412-1b.html @@ -0,0 +1,11 @@ + +Testcase bug 391412 Regression in float layout causing "clear:" to be ignored + + +
    +
    +
    +
    +
    + + diff --git a/layout/reftests/bugs/399384-1-ref.html b/layout/reftests/bugs/399384-1-ref.html new file mode 100644 index 000000000000..26959bad235a --- /dev/null +++ b/layout/reftests/bugs/399384-1-ref.html @@ -0,0 +1,16 @@ + + + + + + +
    abc
    +
    def
    +
    geh
    + + + diff --git a/layout/reftests/bugs/399384-1.html b/layout/reftests/bugs/399384-1.html new file mode 100644 index 000000000000..7b5b47542692 --- /dev/null +++ b/layout/reftests/bugs/399384-1.html @@ -0,0 +1,21 @@ + + + + + + + +
    abc
    +
    def
    +
    geh
    + + + diff --git a/layout/reftests/bugs/400421-1-ref.html b/layout/reftests/bugs/400421-1-ref.html new file mode 100644 index 000000000000..0a5fd517051c --- /dev/null +++ b/layout/reftests/bugs/400421-1-ref.html @@ -0,0 +1,5 @@ + + + + + diff --git a/layout/reftests/bugs/400421-1.html b/layout/reftests/bugs/400421-1.html new file mode 100644 index 000000000000..3e355f9eefd9 --- /dev/null +++ b/layout/reftests/bugs/400421-1.html @@ -0,0 +1,20 @@ + + + + + + + + + + + diff --git a/layout/reftests/bugs/reftest.list b/layout/reftests/bugs/reftest.list index 1a5767346aeb..074cf1c2a93b 100644 --- a/layout/reftests/bugs/reftest.list +++ b/layout/reftests/bugs/reftest.list @@ -30,6 +30,8 @@ == 18217-zorder-3.html 18217-zorder-ref-inline.html == 18217-zorder-4.html 18217-zorder-ref-inline-table.html == 18217-zorder-5.html 18217-zorder-ref-inline-table.html +== 23604-1.html 23604-1-ref.html +== 23604-2.html 23604-2-ref.html fails == 25888-1l.html 25888-1l-ref.html # bug 25888 fails != 25888-1l.html 25888-1l-notref.html # bug 25888 fails == 25888-1r.html 25888-1r-ref.html # bug 25888 @@ -101,6 +103,7 @@ fails-if(MOZ_WIDGET_TOOLKIT=="cocoa") == 28811-2a.html 28811-2-ref.html # bug 38 == 243266-1.html 243266-1-ref.html == 243302-1.html 243302-1-ref.html == 244135-1.html 244135-1-ref.html +== 244135-2.html 244135-2-ref.html == 244932-1.html 244932-1-ref.html == 249982-1.html 249982-1-ref.html == 253701-1.html 253701-1-ref.html @@ -127,6 +130,12 @@ fails-if(MOZ_WIDGET_TOOLKIT=="cocoa") == 28811-2a.html 28811-2-ref.html # bug 38 != 315620-1b.html 315620-1-ref.html == 315620-2a.xhtml 315620-2-ref.xhtml != 315620-2b.xhtml 315620-2-ref.xhtml +!= 321402-1.html about:blank +!= 321402-2.html about:blank +== 321402-3.xul 321402-3-ref.xul +== 321402-4.xul 321402-4-ref.xul +== 321402-5.xul 321402-5-ref.xul +== 321402-6.xul 321402-6-ref.xul == 322461-1.xml 322461-1-ref.html == 323656-1.html 323656-1-ref.html == 323656-2.html 323656-2-ref.html @@ -149,7 +158,8 @@ random-if(MOZ_WIDGET_TOOLKIT=="gtk2") == 333970-1.html 333970-1-ref.html # bug 3 == 335628-1.html 335628-1-ref.html != 335628-2.xul 335628-2-ref.xul == 336147-1.html 336147-1-ref.html -fails-if(MOZ_WIDGET_TOOLKIT=="cocoa") == 336736-1.html 336736-1-ref.html # something wrong with subpixel horizontal alignment (tracked in bug 336736) +== 336736-1a.html 336736-1-ref.html +== 336736-1b.html 336736-1-ref.html == 339289-1.html 339289-1-ref.html == 341043-1a.html 341043-1-ref.html != 341043-1b.html 341043-1-ref.html @@ -313,8 +323,9 @@ fails == 368504-2.html 368504-2-ref.html # bug 368504 == 372768-1.html 372768-1-ref.html == 373383-1.html 373383-1-ref.html == 374038-1.xul 374038-1-ref.xul -== 374038-2.xul 374038-2-ref.xul +random == 374038-2.xul 374038-2-ref.xul # bug 401176 == 374193-1.xhtml about:blank +fails == 374927-1.html 374927-1-ref.html # Was broken by patch for bug 368600; fails until bug 400776 is fixed == 375716-1.html 375716-1-ref.html == 375827-1.html 375827-1-ref.html == 376484-1.html 376484-1-ref.html @@ -379,6 +390,7 @@ fails == 386310-1d.html 386310-1-ref.html == 387876-2.html 387876-2-ref.html == 387876-3a.html 387876-3-ref.html == 387876-3b.html 387876-3-ref.html +== 389468-1.html 389468-1-ref.html == 389636-1.html about:blank # assertion test == 389924-1a.html 389924-1-ref.html == 389924-1b.html 389924-1-ref.html @@ -387,6 +399,8 @@ fails == 386310-1d.html 386310-1-ref.html == 390318-1b.html 390318-1-ref.html == 391045.html 391045-ref.html # windows-specific bug, appears to pass on other platforms because of missing fonts == 391140-1.html 391140-1-ref.html +== 391412-1a.html 391412-1-ref.html +== 391412-1b.html 391412-1-ref.html == 391909-1.html 391909-1-ref.html == 391994-1.html 391994-1-ref.html == 392435-1.html 392435-1-ref.html @@ -403,3 +417,5 @@ fails == 386310-1d.html 386310-1-ref.html == 395331-1.xml 395331-1-ref.xml == 396286-1.html about:blank # crash test == 398289-1.html 398289-1-ref.html +== 399384-1.html 399384-1-ref.html +== 400421-1.html 400421-1-ref.html diff --git a/layout/reftests/svg/reftest.list b/layout/reftests/svg/reftest.list index 23327077871d..59e89db5d81c 100755 --- a/layout/reftests/svg/reftest.list +++ b/layout/reftests/svg/reftest.list @@ -20,7 +20,7 @@ skip-if(MOZ_WIDGET_TOOLKIT=="gtk2") == pseudo-classes-02.svg pseudo-classes-02-r == rootElement-null-01.svg pass.svg == stroke-width-percentage-01.svg pass.svg fails == style-property-not-on-script-element-01.svg pass.svg -fails-if(MOZ_WIDGET_TOOLKIT=="gtk2") == text-font-weight-01.svg text-font-weight-01-ref.svg # bug 386713 +random-if(MOZ_WIDGET_TOOLKIT=="gtk2") == text-font-weight-01.svg text-font-weight-01-ref.svg # bug 386713 skip-if(MOZ_WIDGET_TOOLKIT=="gtk2") == text-in-link-01.svg text-in-link-01-ref.svg # bug 379600 (crashes linux) == text-style-01a.svg text-style-01-ref.svg == text-style-01b.svg text-style-01-ref.svg diff --git a/layout/reftests/text/reftest.list b/layout/reftests/text/reftest.list index 529b19c995fb..364a6a22bf68 100644 --- a/layout/reftests/text/reftest.list +++ b/layout/reftests/text/reftest.list @@ -2,3 +2,6 @@ == soft-hyphens-1a.html soft-hyphens-1-ref.html == soft-hyphens-1b.html soft-hyphens-1-ref.html == soft-hyphens-1c.html soft-hyphens-1-ref.html +== white-space-1a.html white-space-1-ref.html +== white-space-1b.html white-space-1-ref.html +== white-space-2.html white-space-2-ref.html diff --git a/layout/reftests/text/white-space-1-ref.html b/layout/reftests/text/white-space-1-ref.html new file mode 100644 index 000000000000..fa5b7ed2ca5f --- /dev/null +++ b/layout/reftests/text/white-space-1-ref.html @@ -0,0 +1,64 @@ + + + + + + + + +
    +

    Hello +Kitty +

    Hello Kitty +

    Hello Kitty +

    Hello +Kitty +

    + +
    +

    Hello +Kitty +

    Hello +Kitty +

    Hello +Kitty +

    Hello +Kitty +

    + +
    +

    Hello + Kitty +

    Hello Kitty +

    Hello Kitty +

    Hello + Kitty +

    + +
    +

    Hello +Kitty +

    Hello Kitty +

    Hello Kitty +

    Hello +Kitty +

    + +
    +

    Hello +Kitty +

    Hello +Kitty +

    Hello +Kitty +

    Hello +Kitty +

    + + + diff --git a/layout/reftests/text/white-space-1a.html b/layout/reftests/text/white-space-1a.html new file mode 100644 index 000000000000..4271011fd272 --- /dev/null +++ b/layout/reftests/text/white-space-1a.html @@ -0,0 +1,53 @@ + + + + + + + + +
    +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    + +
    +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    + +
    +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    + +
    +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    + +
    +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    + + + diff --git a/layout/reftests/text/white-space-1b.html b/layout/reftests/text/white-space-1b.html new file mode 100644 index 000000000000..3152a90538a4 --- /dev/null +++ b/layout/reftests/text/white-space-1b.html @@ -0,0 +1,53 @@ + + + + + + + + +
    +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    + +
    +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    + +
    +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    + +
    +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    + +
    +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    + + + diff --git a/layout/reftests/text/white-space-2-ref.html b/layout/reftests/text/white-space-2-ref.html new file mode 100644 index 000000000000..581daa9d4229 --- /dev/null +++ b/layout/reftests/text/white-space-2-ref.html @@ -0,0 +1,65 @@ + + + + + + + + +
    +

    Hello +Kitty +

    Hello Kitty +

    Hello Kitty +

    Hello +Kitty +

    + +
    +

    Hello +Kitty +

    Hello +Kitty +

    Hello +Kitty +

    Hello +Kitty +

    + +
    +

    Hello + Kitty +

    Hello Kitty +

    Hello Kitty +

    Hello + Kitty +

    + +
    +

    Hello +Kitty +

    Hello Kitty +

    Hello Kitty +

    Hello +Kitty +

    + +
    +

    Hello +Kitty +

    Hello +Kitty +

    Hello +Kitty +

    Hello +Kitty +

    + + + diff --git a/layout/reftests/text/white-space-2.html b/layout/reftests/text/white-space-2.html new file mode 100644 index 000000000000..55055746ee2e --- /dev/null +++ b/layout/reftests/text/white-space-2.html @@ -0,0 +1,54 @@ + + + + + + + + +
    +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    + +
    +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    + +
    +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    + +
    +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    + +
    +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    Hello Kitty +

    + + + diff --git a/layout/style/forms.css b/layout/style/forms.css index e2e8bc83e308..05cd26451b48 100644 --- a/layout/style/forms.css +++ b/layout/style/forms.css @@ -356,13 +356,9 @@ input[type="file"] { border-style: none !important; } -input[type="file"] > input[type="text"][disabled] { +input[type="file"] > input[type="text"] { border-color: inherit; background-color: inherit; - -moz-user-focus: ignore !important; - /* enable user input so that clicking on the control can bring up the - file dialog. It's still read-only. */ - -moz-user-input: enabled; color: inherit; font-size: inherit; height: inherit; diff --git a/layout/style/nsCSSAnonBoxList.h b/layout/style/nsCSSAnonBoxList.h index 07546027a7ce..947d813696d7 100644 --- a/layout/style/nsCSSAnonBoxList.h +++ b/layout/style/nsCSSAnonBoxList.h @@ -57,6 +57,7 @@ CSS_ANON_BOX(mozNonElement, ":-moz-non-element") CSS_ANON_BOX(mozAnonymousBlock, ":-moz-anonymous-block") CSS_ANON_BOX(mozAnonymousPositionedBlock, ":-moz-anonymous-positioned-block") CSS_ANON_BOX(mozMathMLAnonymousBlock, ":-moz-mathml-anonymous-block") +CSS_ANON_BOX(mozXULAnonymousBlock, ":-moz-xul-anonymous-block") CSS_ANON_BOX(mozLineFrame, ":-moz-line-frame") diff --git a/layout/style/nsCSSLoader.cpp b/layout/style/nsCSSLoader.cpp index 55d0af685588..fb549ba616ce 100644 --- a/layout/style/nsCSSLoader.cpp +++ b/layout/style/nsCSSLoader.cpp @@ -777,19 +777,18 @@ SheetLoadData::OnStreamComplete(nsIUnicharStreamLoader* aLoader, return NS_OK; } - nsCOMPtr channelURI; + nsCOMPtr originalURI; + channel->GetOriginalURI(getter_AddRefs(originalURI)); + // If the channel's original URI is "chrome:", we want that, since // the observer code in nsXULPrototypeCache depends on chrome stylesheets // having a chrome URI. (Whether or not chrome stylesheets come through // this codepath seems nondeterministic.) // Otherwise we want the potentially-HTTP-redirected URI. - channel->GetOriginalURI(getter_AddRefs(channelURI)); - PRBool isChrome; - if (NS_FAILED(channelURI->SchemeIs("chrome", &isChrome)) || !isChrome) { - channel->GetURI(getter_AddRefs(channelURI)); - } + nsCOMPtr channelURI; + NS_GetFinalChannelURI(channel, getter_AddRefs(channelURI)); - if (!channelURI) { + if (!channelURI || !originalURI) { NS_ERROR("Someone just violated the nsIRequest contract"); LOG_WARN((" Channel without a URI. Bad!")); mLoader->SheetComplete(this, NS_ERROR_UNEXPECTED); @@ -875,9 +874,9 @@ SheetLoadData::OnStreamComplete(nsIUnicharStreamLoader* aLoader, return NS_OK; } - // Enough to set the URI on mSheet, since any sibling datas we have share + // Enough to set the URIs on mSheet, since any sibling datas we have share // the same mInner as mSheet and will thus get the same URI. - mSheet->SetURIs(channelURI, channelURI); + mSheet->SetURIs(channelURI, originalURI, channelURI); PRBool completed; return mLoader->ParseSheet(aDataStream, this, completed); @@ -1082,19 +1081,25 @@ CSSLoaderImpl::CreateSheet(nsIURI* aURI, if (!*aSheet) { aSheetState = eSheetNeedsParser; - nsIURI *sheetURI = aURI; - nsCOMPtr baseURI = aURI; + nsIURI *sheetURI; + nsCOMPtr baseURI; + nsIURI* originalURI; if (!aURI) { // Inline style. Use the document's base URL so that @import in // the inline sheet picks up the right base. NS_ASSERTION(aLinkingContent, "Inline stylesheet without linking content?"); baseURI = aLinkingContent->GetBaseURI(); sheetURI = aLinkingContent->GetDocument()->GetDocumentURI(); + originalURI = nsnull; + } else { + baseURI = aURI; + sheetURI = aURI; + originalURI = aURI; } rv = NS_NewCSSStyleSheet(aSheet); NS_ENSURE_SUCCESS(rv, rv); - (*aSheet)->SetURIs(sheetURI, baseURI); + (*aSheet)->SetURIs(sheetURI, originalURI, baseURI); } NS_ASSERTION(*aSheet, "We should have a sheet by now!"); diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index 6afc9ebe8430..a844d7462b9b 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -707,7 +707,7 @@ CSSParserImpl::Parse(nsIUnicharInputStream* aInput, NS_NewCSSStyleSheet(getter_AddRefs(mSheet)); NS_ENSURE_TRUE(mSheet, NS_ERROR_OUT_OF_MEMORY); - mSheet->SetURIs(aSheetURI, aBaseURI); + mSheet->SetURIs(aSheetURI, aSheetURI, aBaseURI); mSheet->SetPrincipal(aSheetPrincipal); mNameSpaceMap = nsnull; } diff --git a/layout/style/nsCSSStyleSheet.cpp b/layout/style/nsCSSStyleSheet.cpp index a2f458ff4f46..2dc36f89d5a5 100644 --- a/layout/style/nsCSSStyleSheet.cpp +++ b/layout/style/nsCSSStyleSheet.cpp @@ -771,7 +771,8 @@ nsCSSStyleSheet::DropRuleProcessor(nsCSSRuleProcessor* aProcessor) NS_IMETHODIMP -nsCSSStyleSheet::SetURIs(nsIURI* aSheetURI, nsIURI* aBaseURI) +nsCSSStyleSheet::SetURIs(nsIURI* aSheetURI, nsIURI* aOriginalSheetURI, + nsIURI* aBaseURI) { NS_PRECONDITION(aSheetURI && aBaseURI, "null ptr"); @@ -779,6 +780,7 @@ nsCSSStyleSheet::SetURIs(nsIURI* aSheetURI, nsIURI* aBaseURI) "Can't call SetURL on sheets that are complete or have rules"); mInner->mSheetURI = aSheetURI; + mInner->mOriginalSheetURI = aOriginalSheetURI; mInner->mBaseURI = aBaseURI; return NS_OK; } @@ -1416,15 +1418,14 @@ nsCSSStyleSheet::GetParentStyleSheet(nsIDOMStyleSheet** aParentStyleSheet) NS_IMETHODIMP nsCSSStyleSheet::GetHref(nsAString& aHref) { - nsCAutoString str; - - // XXXldb The DOM spec says that this should be null for inline style sheets. - if (mInner->mSheetURI) { - mInner->mSheetURI->GetSpec(str); + if (mInner->mOriginalSheetURI) { + nsCAutoString str; + mInner->mOriginalSheetURI->GetSpec(str); + CopyUTF8toUTF16(str, aHref); + } else { + SetDOMStringToNull(aHref); } - CopyUTF8toUTF16(str, aHref); - return NS_OK; } diff --git a/layout/style/nsCSSStyleSheet.h b/layout/style/nsCSSStyleSheet.h index 9179ceebf6cc..9b72f99a6ccb 100644 --- a/layout/style/nsCSSStyleSheet.h +++ b/layout/style/nsCSSStyleSheet.h @@ -74,6 +74,7 @@ public: nsAutoVoidArray mSheets; nsCOMPtr mSheetURI; // for error reports, etc. + nsCOMPtr mOriginalSheetURI; // for GetHref. Can be null. nsCOMPtr mBaseURI; // for resolving relative URIs nsCOMPtr mPrincipal; nsCOMArray mOrderedRules; @@ -136,7 +137,8 @@ public: NS_IMETHOD ReplaceRuleInGroup(nsICSSGroupRule* aGroup, nsICSSRule* aOld, nsICSSRule* aNew); NS_IMETHOD StyleSheetCount(PRInt32& aCount) const; NS_IMETHOD GetStyleSheetAt(PRInt32 aIndex, nsICSSStyleSheet*& aSheet) const; - NS_IMETHOD SetURIs(nsIURI* aSheetURI, nsIURI* aBaseURI); + NS_IMETHOD SetURIs(nsIURI* aSheetURI, nsIURI* aOriginalSheetURI, + nsIURI* aBaseURI); virtual NS_HIDDEN_(void) SetPrincipal(nsIPrincipal* aPrincipal); virtual NS_HIDDEN_(nsIPrincipal*) Principal() const; NS_IMETHOD SetTitle(const nsAString& aTitle); diff --git a/layout/style/nsICSSStyleSheet.h b/layout/style/nsICSSStyleSheet.h index 77df3fa9ed9b..c38b8367a868 100644 --- a/layout/style/nsICSSStyleSheet.h +++ b/layout/style/nsICSSStyleSheet.h @@ -53,10 +53,10 @@ class nsICSSImportRule; class nsIPrincipal; // IID for the nsICSSStyleSheet interface -// 36541c18-e735-48ef-8622-3a481275b757 +// 74fa10f3-fab7-425a-a7dd-e2afd1ba7a07 #define NS_ICSS_STYLE_SHEET_IID \ -{ 0x36541c18, 0xe735, 0x48ef, \ - { 0x86, 0x22, 0x3a, 0x48, 0x12, 0x75, 0xb7, 0x57 } } +{ 0x74fa10f3, 0xfab7, 0x425a, \ + { 0xa7, 0xdd, 0xe2, 0xaf, 0xd1, 0xba, 0x7a, 0x07 } } class nsICSSStyleSheet : public nsIStyleSheet { public: @@ -87,7 +87,8 @@ public: * SetURIs may only be called while the sheet is 1) incomplete and 2) * has no rules in it */ - NS_IMETHOD SetURIs(nsIURI* aSheetURI, nsIURI* aBaseURI) = 0; + NS_IMETHOD SetURIs(nsIURI* aSheetURI, nsIURI* aOriginalSheetURI, + nsIURI* aBaseURI) = 0; /** * SetPrincipal should be called on all sheets before parsing into them. diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index edd85d773f77..9cf4f783ed75 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -4335,19 +4335,19 @@ SetSVGPaint(const nsCSSValuePair& aValue, const nsStyleSVGPaint& parentPaint, nsStyleSVGPaint& aResult, nsStyleSVGPaintType aInitialPaintType, PRBool& aInherited) { - aResult.~nsStyleSVGPaint(); - new (&aResult) nsStyleSVGPaint(); + nscolor color; + if (aValue.mXValue.GetUnit() == eCSSUnit_Inherit) { aResult = parentPaint; aInherited = PR_TRUE; } else if (aValue.mXValue.GetUnit() == eCSSUnit_None) { - aResult.mType = eStyleSVGPaintType_None; + aResult.SetType(eStyleSVGPaintType_None); } else if (aValue.mXValue.GetUnit() == eCSSUnit_Initial) { - aResult.mType = aInitialPaintType; + aResult.SetType(aInitialPaintType); aResult.mPaint.mColor = NS_RGB(0, 0, 0); aResult.mFallbackColor = NS_RGB(0, 0, 0); } else if (aValue.mXValue.GetUnit() == eCSSUnit_URL) { - aResult.mType = eStyleSVGPaintType_Server; + aResult.SetType(eStyleSVGPaintType_Server); aResult.mPaint.mPaintServer = aValue.mXValue.GetURLValue(); NS_IF_ADDREF(aResult.mPaint.mPaintServer); if (aValue.mYValue.GetUnit() == eCSSUnit_None) { @@ -4356,8 +4356,9 @@ SetSVGPaint(const nsCSSValuePair& aValue, const nsStyleSVGPaint& parentPaint, NS_ASSERTION(aValue.mYValue.GetUnit() != eCSSUnit_Inherit, "cannot inherit fallback colour"); SetColor(aValue.mYValue, NS_RGB(0, 0, 0), aPresContext, aContext, aResult.mFallbackColor, aInherited); } - } else if (SetColor(aValue.mXValue, parentPaint.mPaint.mColor, aPresContext, aContext, aResult.mPaint.mColor, aInherited)) { - aResult.mType = eStyleSVGPaintType_Color; + } else if (SetColor(aValue.mXValue, parentPaint.mPaint.mColor, aPresContext, aContext, color, aInherited)) { + aResult.SetType(eStyleSVGPaintType_Color); + aResult.mPaint.mColor = color; } } diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index 63874811ca1e..4f46da09a965 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -829,20 +829,30 @@ nsChangeHint nsStyleSVGReset::MaxDifference() #endif // nsStyleSVGPaint implementation -nsStyleSVGPaint::~nsStyleSVGPaint() { +nsStyleSVGPaint::~nsStyleSVGPaint() +{ if (mType == eStyleSVGPaintType_Server) { NS_IF_RELEASE(mPaint.mPaintServer); - } + } +} + +void +nsStyleSVGPaint::SetType(nsStyleSVGPaintType aType) +{ + if (mType == eStyleSVGPaintType_Server) { + this->~nsStyleSVGPaint(); + new (this) nsStyleSVGPaint(); + } + mType = aType; } nsStyleSVGPaint& nsStyleSVGPaint::operator=(const nsStyleSVGPaint& aOther) { if (this == &aOther) return *this; - this->~nsStyleSVGPaint(); - new (this) nsStyleSVGPaint(); - mType = aOther.mType; + SetType(aOther.mType); + mFallbackColor = aOther.mFallbackColor; if (mType == eStyleSVGPaintType_Server) { mPaint.mPaintServer = aOther.mPaint.mPaintServer; diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index d48b5851fa73..0c2b9c92c9c4 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -1218,7 +1218,7 @@ struct nsStyleColumn : public nsStyleStruct { #ifdef MOZ_SVG enum nsStyleSVGPaintType { - eStyleSVGPaintType_None = 0, + eStyleSVGPaintType_None = 1, eStyleSVGPaintType_Color, eStyleSVGPaintType_Server }; @@ -1232,9 +1232,9 @@ struct nsStyleSVGPaint } mPaint; nscolor mFallbackColor; - // empty constructor to keep Sun compiler happy - nsStyleSVGPaint() {} - ~nsStyleSVGPaint(); + nsStyleSVGPaint() : mType(nsStyleSVGPaintType(0)) { mPaint.mPaintServer = nsnull; } + ~nsStyleSVGPaint(); + void SetType(nsStyleSVGPaintType aType); nsStyleSVGPaint& operator=(const nsStyleSVGPaint& aOther); PRBool operator==(const nsStyleSVGPaint& aOther) const; diff --git a/layout/style/test/Makefile.in b/layout/style/test/Makefile.in index 1ba18dfe4327..69cb05eb6791 100644 --- a/layout/style/test/Makefile.in +++ b/layout/style/test/Makefile.in @@ -83,6 +83,7 @@ _TEST_FILES = test_bug74880.html \ test_bug389464.html \ test_bug391034.html \ test_bug391221.html \ + test_bug397427.html \ test_compute_data_with_start_struct.html \ test_dont_use_document_colors.html \ test_inherit_storage.html \ @@ -101,6 +102,15 @@ _TEST_FILES = test_bug74880.html \ unstyled.css \ unstyled-frame.xml \ unstyled-frame.css \ + redirect-1.css \ + post-redirect-1.css \ + redirect-1.css^headers^ \ + redirect-2.css \ + post-redirect-2.css \ + redirect-2.css^headers^ \ + redirect-3.css \ + redirect-3.css^headers^ \ + post-redirect-3.css \ $(NULL) diff --git a/layout/style/test/post-redirect-1.css b/layout/style/test/post-redirect-1.css new file mode 100644 index 000000000000..c2ae5d6eb2c4 --- /dev/null +++ b/layout/style/test/post-redirect-1.css @@ -0,0 +1 @@ +#one { color: green; background: url("#"); } diff --git a/layout/style/test/post-redirect-2.css b/layout/style/test/post-redirect-2.css new file mode 100644 index 000000000000..0a75299ce2ed --- /dev/null +++ b/layout/style/test/post-redirect-2.css @@ -0,0 +1 @@ +#two { color: green; background: url("#"); } diff --git a/layout/style/test/post-redirect-3.css b/layout/style/test/post-redirect-3.css new file mode 100644 index 000000000000..b33887ae32c2 --- /dev/null +++ b/layout/style/test/post-redirect-3.css @@ -0,0 +1 @@ +#three { color: green; background: url("#"); } diff --git a/layout/style/test/redirect-1.css b/layout/style/test/redirect-1.css new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/layout/style/test/redirect-1.css^headers^ b/layout/style/test/redirect-1.css^headers^ new file mode 100644 index 000000000000..582de3f2be23 --- /dev/null +++ b/layout/style/test/redirect-1.css^headers^ @@ -0,0 +1,2 @@ +HTTP 302 Found +Location: http://example.org/tests/layout/style/test/post-redirect-1.css diff --git a/layout/style/test/redirect-2.css b/layout/style/test/redirect-2.css new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/layout/style/test/redirect-2.css^headers^ b/layout/style/test/redirect-2.css^headers^ new file mode 100644 index 000000000000..09280cc486b6 --- /dev/null +++ b/layout/style/test/redirect-2.css^headers^ @@ -0,0 +1,2 @@ +HTTP 302 Found +Location: http://example.org/tests/layout/style/test/post-redirect-2.css diff --git a/layout/style/test/redirect-3.css b/layout/style/test/redirect-3.css new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/layout/style/test/redirect-3.css^headers^ b/layout/style/test/redirect-3.css^headers^ new file mode 100644 index 000000000000..42419234f2d5 --- /dev/null +++ b/layout/style/test/redirect-3.css^headers^ @@ -0,0 +1,2 @@ +HTTP 302 Found +Location: http://example.org/tests/layout/style/test/post-redirect-3.css diff --git a/layout/style/test/test_bug397427.html b/layout/style/test/test_bug397427.html new file mode 100644 index 000000000000..ae457215e11a --- /dev/null +++ b/layout/style/test/test_bug397427.html @@ -0,0 +1,92 @@ + + + + + Test for Bug 397427 + + + + + + + + + +Mozilla Bug 397427 +

    + + + +

    + +
    +
    +
    + + + diff --git a/layout/style/ua.css b/layout/style/ua.css index 8508b4cbf35b..fdbc4f334ce4 100644 --- a/layout/style/ua.css +++ b/layout/style/ua.css @@ -128,6 +128,12 @@ position: static !important; } +*|*::-moz-xul-anonymous-block { + display: block ! important; + position: static ! important; + float: none ! important; +} + *|*::-moz-scrolled-content, *|*::-moz-scrolled-canvas, *|*::-moz-scrolled-page-sequence { /* e.g., text inputs, select boxes */ diff --git a/layout/svg/base/src/nsISVGChildFrame.h b/layout/svg/base/src/nsISVGChildFrame.h index 0be28de9cce3..0e01c82f6e2b 100644 --- a/layout/svg/base/src/nsISVGChildFrame.h +++ b/layout/svg/base/src/nsISVGChildFrame.h @@ -76,7 +76,13 @@ public: NS_IMETHOD_(nsRect) GetCoveredRegion()=0; NS_IMETHOD UpdateCoveredRegion()=0; + + // Called once on all SVG child frames, either when their nsSVGOuterSVGFrame + // receives its initial reflow (i.e. once the SVG viewport dimensions are + // known), or else when they're inserted into the frame tree (if they're + // inserted after the initial reflow). NS_IMETHOD InitialUpdate()=0; + NS_IMETHOD NotifyCanvasTMChanged(PRBool suppressInvalidation)=0; NS_IMETHOD NotifyRedrawSuspended()=0; NS_IMETHOD NotifyRedrawUnsuspended()=0; diff --git a/layout/svg/base/src/nsSVGContainerFrame.cpp b/layout/svg/base/src/nsSVGContainerFrame.cpp index b1dcb8154e03..212e0a5f4b43 100644 --- a/layout/svg/base/src/nsSVGContainerFrame.cpp +++ b/layout/svg/base/src/nsSVGContainerFrame.cpp @@ -125,20 +125,23 @@ nsSVGDisplayContainerFrame::InsertFrames(nsIAtom* aListName, // Insert the new frames nsSVGContainerFrame::InsertFrames(aListName, aPrevFrame, aFrameList); - // call InitialUpdate() on all new frames: - nsIFrame* end = nsnull; - if (lastNewFrame) - end = lastNewFrame->GetNextSibling(); - - for (nsIFrame* kid = aFrameList; kid != end; - kid = kid->GetNextSibling()) { - nsISVGChildFrame* SVGFrame=nsnull; - CallQueryInterface(kid, &SVGFrame); - if (SVGFrame) { - SVGFrame->InitialUpdate(); + // Call InitialUpdate on the new frames ONLY if our nsSVGOuterSVGFrame has had + // its initial reflow (our NS_FRAME_FIRST_REFLOW bit is clear) - bug 399863. + if (!(GetStateBits() & NS_FRAME_FIRST_REFLOW)) { + nsIFrame* end = nsnull; + if (lastNewFrame) + end = lastNewFrame->GetNextSibling(); + + for (nsIFrame* kid = aFrameList; kid != end; + kid = kid->GetNextSibling()) { + nsISVGChildFrame* SVGFrame = nsnull; + CallQueryInterface(kid, &SVGFrame); + if (SVGFrame) { + SVGFrame->InitialUpdate(); + } } } - + return NS_OK; } @@ -214,6 +217,10 @@ nsSVGDisplayContainerFrame::UpdateCoveredRegion() NS_IMETHODIMP nsSVGDisplayContainerFrame::InitialUpdate() { + NS_ASSERTION(GetStateBits() & NS_FRAME_FIRST_REFLOW, + "Yikes! We've been called already! Hopefully we weren't called " + "before our nsSVGOuterSVGFrame's initial Reflow()!!!"); + for (nsIFrame* kid = mFrames.FirstChild(); kid; kid = kid->GetNextSibling()) { nsISVGChildFrame* SVGFrame = nsnull; diff --git a/layout/svg/base/src/nsSVGForeignObjectFrame.cpp b/layout/svg/base/src/nsSVGForeignObjectFrame.cpp index bb7d221836ff..0b492914f6d1 100644 --- a/layout/svg/base/src/nsSVGForeignObjectFrame.cpp +++ b/layout/svg/base/src/nsSVGForeignObjectFrame.cpp @@ -365,6 +365,10 @@ nsSVGForeignObjectFrame::UpdateCoveredRegion() NS_IMETHODIMP nsSVGForeignObjectFrame::InitialUpdate() { + NS_ASSERTION(GetStateBits() & NS_FRAME_FIRST_REFLOW, + "Yikes! We've been called already! Hopefully we weren't called " + "before our nsSVGOuterSVGFrame's initial Reflow()!!!"); + UpdateCoveredRegion(); DoReflow(); @@ -585,6 +589,10 @@ nsSVGForeignObjectFrame::DoReflow() printf("**nsSVGForeignObjectFrame::DoReflow()\n"); #endif + NS_ASSERTION(!(nsSVGUtils::GetOuterSVGFrame(this)-> + GetStateBits() & NS_FRAME_FIRST_REFLOW), + "Calling InitialUpdate too early - must not call DoReflow!!!"); + if (IsDisabled()) return; diff --git a/layout/svg/base/src/nsSVGGeometryFrame.cpp b/layout/svg/base/src/nsSVGGeometryFrame.cpp index 48426b365660..7ba3e0f866ba 100644 --- a/layout/svg/base/src/nsSVGGeometryFrame.cpp +++ b/layout/svg/base/src/nsSVGGeometryFrame.cpp @@ -332,8 +332,7 @@ nsSVGGeometryFrame::MaybeOptimizeOpacity(float aOpacity) } PRBool -nsSVGGeometryFrame::SetupCairoFill(gfxContext *aContext, - void **aClosure) +nsSVGGeometryFrame::SetupCairoFill(gfxContext *aContext) { if (GetStyleSVG()->mFillRule == NS_STYLE_FILL_RULE_EVENODD) aContext->SetFillRule(gfxContext::FILL_RULE_EVEN_ODD); @@ -345,7 +344,7 @@ nsSVGGeometryFrame::SetupCairoFill(gfxContext *aContext, if (GetStateBits() & NS_STATE_SVG_FILL_PSERVER) { nsSVGPaintServerFrame *ps = static_cast (GetProperty(nsGkAtoms::fill)); - return ps->SetupPaintServer(aContext, this, opacity, aClosure); + return ps->SetupPaintServer(aContext, this, opacity); } else if (GetStyleSVG()->mFill.mType == eStyleSVGPaintType_Server) { SetupCairoColor(aContext, GetStyleSVG()->mFill.mFallbackColor, @@ -405,8 +404,7 @@ nsSVGGeometryFrame::SetupCairoStrokeHitGeometry(gfxContext *aContext) } PRBool -nsSVGGeometryFrame::SetupCairoStroke(gfxContext *aContext, - void **aClosure) +nsSVGGeometryFrame::SetupCairoStroke(gfxContext *aContext) { SetupCairoStrokeHitGeometry(aContext); @@ -415,7 +413,7 @@ nsSVGGeometryFrame::SetupCairoStroke(gfxContext *aContext, if (GetStateBits() & NS_STATE_SVG_STROKE_PSERVER) { nsSVGPaintServerFrame *ps = static_cast (GetProperty(nsGkAtoms::stroke)); - return ps->SetupPaintServer(aContext, this, opacity, aClosure); + return ps->SetupPaintServer(aContext, this, opacity); } else if (GetStyleSVG()->mStroke.mType == eStyleSVGPaintType_Server) { SetupCairoColor(aContext, GetStyleSVG()->mStroke.mFallbackColor, diff --git a/layout/svg/base/src/nsSVGGeometryFrame.h b/layout/svg/base/src/nsSVGGeometryFrame.h index 23a5eb6bec58..e52819431a5c 100644 --- a/layout/svg/base/src/nsSVGGeometryFrame.h +++ b/layout/svg/base/src/nsSVGGeometryFrame.h @@ -98,7 +98,7 @@ public: * Set up a cairo context for filling a path * @return PR_FALSE to skip rendering */ - PRBool SetupCairoFill(gfxContext *aContext, void **aClosure); + PRBool SetupCairoFill(gfxContext *aContext); // Set up a cairo context for measuring a stroked path void SetupCairoStrokeGeometry(gfxContext *aContext); @@ -110,7 +110,7 @@ public: * Set up a cairo context for stroking a path * @return PR_FALSE to skip rendering */ - PRBool SetupCairoStroke(gfxContext *aContext, void **aClosure); + PRBool SetupCairoStroke(gfxContext *aContext); protected: virtual nsresult UpdateGraphic(PRBool suppressInvalidation = PR_FALSE) = 0; diff --git a/layout/svg/base/src/nsSVGGlyphFrame.cpp b/layout/svg/base/src/nsSVGGlyphFrame.cpp index 0ac8d7e75aa8..77c3cc813969 100644 --- a/layout/svg/base/src/nsSVGGlyphFrame.cpp +++ b/layout/svg/base/src/nsSVGGlyphFrame.cpp @@ -299,12 +299,11 @@ nsSVGGlyphFrame::PaintSVG(nsSVGRenderState *aContext, nsRect *aDirtyRect) return NS_OK; } - void *closure; - if (HasFill() && SetupCairoFill(gfx, &closure)) { + if (HasFill() && SetupCairoFill(gfx)) { LoopCharacters(gfx, text, cp, FILL); } - if (HasStroke() && SetupCairoStroke(gfx, &closure)) { + if (HasStroke() && SetupCairoStroke(gfx)) { gfx->NewPath(); LoopCharacters(gfx, text, cp, STROKE); gfx->Stroke(); @@ -461,6 +460,10 @@ nsSVGGlyphFrame::UpdateCoveredRegion() NS_IMETHODIMP nsSVGGlyphFrame::InitialUpdate() { + NS_ASSERTION(GetStateBits() & NS_FRAME_FIRST_REFLOW, + "Yikes! We've been called already! Hopefully we weren't called " + "before our nsSVGOuterSVGFrame's initial Reflow()!!!"); + NS_ASSERTION(!(mState & NS_FRAME_IN_REFLOW), "We don't actually participate in reflow"); diff --git a/layout/svg/base/src/nsSVGGradientFrame.cpp b/layout/svg/base/src/nsSVGGradientFrame.cpp index ab558154e917..0a385220cda1 100644 --- a/layout/svg/base/src/nsSVGGradientFrame.cpp +++ b/layout/svg/base/src/nsSVGGradientFrame.cpp @@ -324,11 +324,8 @@ nsSVGGradientFrame::GetSpreadMethod() PRBool nsSVGGradientFrame::SetupPaintServer(gfxContext *aContext, nsSVGGeometryFrame *aSource, - float aGraphicOpacity, - void **aClosure) + float aGraphicOpacity) { - *aClosure = nsnull; - PRUint32 nStops = GetStopCount(); // SVG specification says that no stops should be treated like diff --git a/layout/svg/base/src/nsSVGGradientFrame.h b/layout/svg/base/src/nsSVGGradientFrame.h index dd0e58580fd2..c721fa86b1db 100644 --- a/layout/svg/base/src/nsSVGGradientFrame.h +++ b/layout/svg/base/src/nsSVGGradientFrame.h @@ -63,8 +63,7 @@ public: // nsSVGPaintServerFrame methods: virtual PRBool SetupPaintServer(gfxContext *aContext, nsSVGGeometryFrame *aSource, - float aGraphicOpacity, - void **aClosure); + float aGraphicOpacity); // nsISupports interface: NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); diff --git a/layout/svg/base/src/nsSVGPaintServerFrame.h b/layout/svg/base/src/nsSVGPaintServerFrame.h index e6b72244278e..db685b68b1ed 100644 --- a/layout/svg/base/src/nsSVGPaintServerFrame.h +++ b/layout/svg/base/src/nsSVGPaintServerFrame.h @@ -59,8 +59,7 @@ public: */ virtual PRBool SetupPaintServer(gfxContext *aContext, nsSVGGeometryFrame *aSource, - float aOpacity, - void **aClosure) = 0; + float aOpacity) = 0; // nsISupports interface: NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); diff --git a/layout/svg/base/src/nsSVGPathGeometryFrame.cpp b/layout/svg/base/src/nsSVGPathGeometryFrame.cpp index 1a39fdc08982..e97f67ca18ae 100644 --- a/layout/svg/base/src/nsSVGPathGeometryFrame.cpp +++ b/layout/svg/base/src/nsSVGPathGeometryFrame.cpp @@ -444,6 +444,10 @@ nsSVGPathGeometryFrame::UpdateCoveredRegion() NS_IMETHODIMP nsSVGPathGeometryFrame::InitialUpdate() { + NS_ASSERTION(GetStateBits() & NS_FRAME_FIRST_REFLOW, + "Yikes! We've been called already! Hopefully we weren't called " + "before our nsSVGOuterSVGFrame's initial Reflow()!!!"); + UpdateGraphic(); NS_ASSERTION(!(mState & NS_FRAME_IN_REFLOW), @@ -638,12 +642,11 @@ nsSVGPathGeometryFrame::Render(nsSVGRenderState *aContext) break; } - void *closure; - if (HasFill() && SetupCairoFill(gfx, &closure)) { + if (HasFill() && SetupCairoFill(gfx)) { gfx->Fill(); } - if (HasStroke() && SetupCairoStroke(gfx, &closure)) { + if (HasStroke() && SetupCairoStroke(gfx)) { gfx->Stroke(); } diff --git a/layout/svg/base/src/nsSVGPatternFrame.cpp b/layout/svg/base/src/nsSVGPatternFrame.cpp index a4211405d6f0..18db92a29b8d 100644 --- a/layout/svg/base/src/nsSVGPatternFrame.cpp +++ b/layout/svg/base/src/nsSVGPatternFrame.cpp @@ -831,11 +831,8 @@ nsSVGPatternFrame::GetCallerGeometry(nsIDOMSVGMatrix **aCTM, PRBool nsSVGPatternFrame::SetupPaintServer(gfxContext *aContext, nsSVGGeometryFrame *aSource, - float aGraphicOpacity, - void **aClosure) + float aGraphicOpacity) { - *aClosure = nsnull; - if (aGraphicOpacity == 0.0f) return PR_FALSE; diff --git a/layout/svg/base/src/nsSVGPatternFrame.h b/layout/svg/base/src/nsSVGPatternFrame.h index f22b2d60f9ea..6b43456f1666 100644 --- a/layout/svg/base/src/nsSVGPatternFrame.h +++ b/layout/svg/base/src/nsSVGPatternFrame.h @@ -73,8 +73,7 @@ public: // nsSVGPaintServerFrame methods: virtual PRBool SetupPaintServer(gfxContext *aContext, nsSVGGeometryFrame *aSource, - float aGraphicOpacity, - void **aClosure); + float aGraphicOpacity); // nsISupports interface: NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); diff --git a/layout/tables/nsCellMap.cpp b/layout/tables/nsCellMap.cpp index 99b1db557e69..a7cdb20d8349 100644 --- a/layout/tables/nsCellMap.cpp +++ b/layout/tables/nsCellMap.cpp @@ -565,8 +565,8 @@ nsTableCellMap::InsertRows(nsTableRowGroupFrame& aParent, nsTableRowGroupFrame* rg = cellMap->GetRowGroup(); if (rg == &aParent) { cellMap->InsertRows(*this, aRows, rowIndex, aConsiderSpans, aDamageArea); - aDamageArea.y = aFirstRowIndex; - aDamageArea.height = PR_MAX(0, GetRowCount() - aFirstRowIndex); + aDamageArea.y = PR_MIN(aFirstRowIndex, aDamageArea.y); + aDamageArea.height = PR_MAX(0, GetRowCount() - aDamageArea.y); #ifdef DEBUG_TABLE_CELLMAP Dump("after InsertRows"); #endif diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp index e5f9e84c6d79..6f7af5a22f2f 100644 --- a/layout/tables/nsTableFrame.cpp +++ b/layout/tables/nsTableFrame.cpp @@ -3530,8 +3530,7 @@ nsTableFrame::IsAutoLayout() // (at least as long as FixedTableLayoutStrategy::GetPrefWidth returns // nscoord_MAX) const nsStyleCoord &width = GetStylePosition()->mWidth; - return (GetStyleDisplay()->mDisplay == NS_STYLE_DISPLAY_INLINE_TABLE && - width.GetUnit() == eStyleUnit_Auto) || + return (width.GetUnit() == eStyleUnit_Auto) || (width.GetUnit() == eStyleUnit_Enumerated && width.GetIntValue() == NS_STYLE_WIDTH_INTRINSIC); } diff --git a/layout/xul/base/src/nsBoxFrame.cpp b/layout/xul/base/src/nsBoxFrame.cpp index da68a17ae7cb..c4b55d6080c0 100644 --- a/layout/xul/base/src/nsBoxFrame.cpp +++ b/layout/xul/base/src/nsBoxFrame.cpp @@ -1032,6 +1032,8 @@ nsBoxFrame::InsertFrames(nsIAtom* aListName, { NS_ASSERTION(!aPrevFrame || aPrevFrame->GetParent() == this, "inserting after sibling frame with different parent"); + NS_ASSERTION(!aPrevFrame || mFrames.ContainsFrame(aPrevFrame), + "inserting after sibling frame not in our child list"); NS_PRECONDITION(!aListName, "We don't support out-of-flow kids"); nsBoxLayoutState state(PresContext()); @@ -1084,7 +1086,13 @@ nsBoxFrame::AppendFrames(nsIAtom* aListName, return NS_OK; } - +/* virtual */ nsIFrame* +nsBoxFrame::GetContentInsertionFrame() +{ + if (GetStateBits() & NS_STATE_BOX_WRAPS_KIDS_IN_BLOCK) + return GetFirstChild(nsnull)->GetContentInsertionFrame(); + return nsContainerFrame::GetContentInsertionFrame(); +} NS_IMETHODIMP nsBoxFrame::AttributeChanged(PRInt32 aNameSpaceID, diff --git a/layout/xul/base/src/nsBoxFrame.h b/layout/xul/base/src/nsBoxFrame.h index 4a4ba55b5f3f..9bf2f778ea61 100644 --- a/layout/xul/base/src/nsBoxFrame.h +++ b/layout/xul/base/src/nsBoxFrame.h @@ -55,12 +55,12 @@ class nsBoxLayoutState; #define NS_STATE_STACK_NOT_POSITIONED 0x00200000 //#define NS_STATE_IS_HORIZONTAL 0x00400000 moved to nsIFrame.h #define NS_STATE_AUTO_STRETCH 0x00800000 -//#define NS_STATE_IS_ROOT 0x01000000 moved to nsIFrame.h +//#define NS_STATE_IS_ROOT 0x01000000 moved to nsBox.h #define NS_STATE_CURRENTLY_IN_DEBUG 0x02000000 -//#define NS_STATE_SET_TO_DEBUG 0x04000000 moved to nsIFrame.h -//#define NS_STATE_DEBUG_WAS_SET 0x08000000 moved to nsIFrame.h +//#define NS_STATE_SET_TO_DEBUG 0x04000000 moved to nsBox.h +//#define NS_STATE_DEBUG_WAS_SET 0x08000000 moved to nsBox.h #define NS_STATE_IS_COLLAPSED 0x10000000 -//#define NS_STATE_STYLE_CHANGE 0x20000000 moved to nsIFrame.h +#define NS_STATE_BOX_WRAPS_KIDS_IN_BLOCK 0x20000000 #define NS_STATE_EQUAL_SIZE 0x40000000 //#define NS_STATE_IS_DIRECTION_NORMAL 0x80000000 moved to nsIFrame.h @@ -134,6 +134,8 @@ public: NS_IMETHOD RemoveFrame(nsIAtom* aListName, nsIFrame* aOldFrame); + virtual nsIFrame* GetContentInsertionFrame(); + NS_IMETHOD SetInitialChildList(nsIAtom* aListName, nsIFrame* aChildList); diff --git a/layout/xul/base/src/nsMenuFrame.cpp b/layout/xul/base/src/nsMenuFrame.cpp index d5745a99e0e0..aa8353f07088 100644 --- a/layout/xul/base/src/nsMenuFrame.cpp +++ b/layout/xul/base/src/nsMenuFrame.cpp @@ -1198,6 +1198,9 @@ nsMenuFrame::InsertFrames(nsIAtom* aListName, NS_FRAME_HAS_DIRTY_CHILDREN); rv = NS_OK; } else { + if (NS_UNLIKELY(aPrevFrame == mPopupFrame)) { + aPrevFrame = nsnull; + } rv = nsBoxFrame::InsertFrames(aListName, aPrevFrame, aFrameList); } diff --git a/layout/xul/base/src/nsPopupSetFrame.cpp b/layout/xul/base/src/nsPopupSetFrame.cpp index a9694afceee9..7a8e5122ca4e 100644 --- a/layout/xul/base/src/nsPopupSetFrame.cpp +++ b/layout/xul/base/src/nsPopupSetFrame.cpp @@ -45,13 +45,8 @@ #include "nsIContent.h" #include "nsPresContext.h" #include "nsStyleContext.h" -#include "nsCSSRendering.h" -#include "nsINameSpaceManager.h" -#include "nsIDocument.h" #include "nsBoxLayoutState.h" #include "nsIScrollableFrame.h" -#include "nsCSSFrameConstructor.h" -#include "nsGUIEvent.h" #include "nsIRootBox.h" nsPopupFrameList::nsPopupFrameList(nsIContent* aPopupContent, nsPopupFrameList* aNext) @@ -139,13 +134,11 @@ nsPopupSetFrame::SetInitialChildList(nsIAtom* aListName, void nsPopupSetFrame::Destroy() { - nsCSSFrameConstructor* frameConstructor = - PresContext()->PresShell()->FrameConstructor(); // remove each popup from the list as we go. while (mPopupList) { - if (mPopupList->mPopupFrame) - DestroyPopupFrame(frameConstructor, mPopupList->mPopupFrame); - + if (mPopupList->mPopupFrame) { + mPopupList->mPopupFrame->Destroy(); + } nsPopupFrameList* temp = mPopupList; mPopupList = mPopupList->mNextPopup; delete temp; @@ -227,6 +220,9 @@ nsPopupSetFrame::RemovePopupFrame(nsIFrame* aPopup) { // This was called by the Destroy() method of the popup, so all we have to do is // get the popup out of our list, so we don't reflow it later. +#ifdef DEBUG + PRBool found = PR_FALSE; +#endif nsPopupFrameList* currEntry = mPopupList; nsPopupFrameList* temp = nsnull; while (currEntry) { @@ -237,13 +233,18 @@ nsPopupSetFrame::RemovePopupFrame(nsIFrame* aPopup) else mPopupList = currEntry->mNextPopup; + NS_ASSERTION((aPopup->GetStateBits() & NS_FRAME_OUT_OF_FLOW) && + aPopup->GetType() == nsGkAtoms::menuPopupFrame, + "found wrong type of frame in popupset's ::popupList"); // Destroy the frame. - DestroyPopupFrame(PresContext()->PresShell()->FrameConstructor(), - currEntry->mPopupFrame); + currEntry->mPopupFrame->Destroy(); // Delete the entry. currEntry->mNextPopup = nsnull; delete currEntry; +#ifdef DEBUG + found = PR_TRUE; +#endif // Break out of the loop. break; @@ -253,6 +254,7 @@ nsPopupSetFrame::RemovePopupFrame(nsIFrame* aPopup) currEntry = currEntry->mNextPopup; } + NS_ASSERTION(found, "frame to remove is not in our ::popupList"); return NS_OK; } @@ -269,10 +271,9 @@ nsPopupSetFrame::AddPopupFrameList(nsIFrame* aPopupFrameList) nsresult nsPopupSetFrame::AddPopupFrame(nsIFrame* aPopup) { - NS_ASSERTION(aPopup->GetType() == nsGkAtoms::menuPopupFrame, - "expected a menupopup frame to be added to a popupset"); - if (aPopup->GetType() != nsGkAtoms::menuPopupFrame) - return NS_ERROR_UNEXPECTED; + NS_ASSERTION((aPopup->GetStateBits() & NS_FRAME_OUT_OF_FLOW) && + aPopup->GetType() == nsGkAtoms::menuPopupFrame, + "adding wrong type of frame in popupset's ::popupList"); // The entry should already exist, but might not (if someone decided to make their // popup visible straightaway, e.g., the autocomplete widget). @@ -297,9 +298,115 @@ nsPopupSetFrame::AddPopupFrame(nsIFrame* aPopup) return NS_OK; } -void -nsPopupSetFrame::DestroyPopupFrame(nsCSSFrameConstructor* aFc, nsIFrame* aPopup) +#ifdef DEBUG +NS_IMETHODIMP +nsPopupSetFrame::List(FILE* out, PRInt32 aIndent) const { - aFc->RemoveMappingsForFrameSubtree(aPopup); - aPopup->Destroy(); + IndentBy(out, aIndent); + ListTag(out); +#ifdef DEBUG_waterson + fprintf(out, " [parent=%p]", static_cast(mParent)); +#endif + if (HasView()) { + fprintf(out, " [view=%p]", static_cast(GetView())); + } + if (nsnull != mNextSibling) { + fprintf(out, " next=%p", static_cast(mNextSibling)); + } + if (nsnull != GetPrevContinuation()) { + fprintf(out, " prev-continuation=%p", static_cast(GetPrevContinuation())); + } + if (nsnull != GetNextContinuation()) { + fprintf(out, " next-continuation=%p", static_cast(GetNextContinuation())); + } + fprintf(out, " {%d,%d,%d,%d}", mRect.x, mRect.y, mRect.width, mRect.height); + if (0 != mState) { + fprintf(out, " [state=%08x]", mState); + } + fprintf(out, " [content=%p]", static_cast(mContent)); + nsPopupSetFrame* f = const_cast(this); + nsRect* overflowArea = f->GetOverflowAreaProperty(PR_FALSE); + if (overflowArea) { + fprintf(out, " [overflow=%d,%d,%d,%d]", overflowArea->x, overflowArea->y, + overflowArea->width, overflowArea->height); + } + fprintf(out, " [sc=%p]", static_cast(mStyleContext)); + nsIAtom* pseudoTag = mStyleContext->GetPseudoType(); + if (pseudoTag) { + nsAutoString atomString; + pseudoTag->ToString(atomString); + fprintf(out, " pst=%s", + NS_LossyConvertUTF16toASCII(atomString).get()); + } + + // Output the children + nsIAtom* listName = nsnull; + PRInt32 listIndex = 0; + PRBool outputOneList = PR_FALSE; + do { + nsIFrame* kid = GetFirstChild(listName); + if (nsnull != kid) { + if (outputOneList) { + IndentBy(out, aIndent); + } + outputOneList = PR_TRUE; + nsAutoString tmp; + if (nsnull != listName) { + listName->ToString(tmp); + fputs(NS_LossyConvertUTF16toASCII(tmp).get(), out); + } + fputs("<\n", out); + while (nsnull != kid) { + // Verify the child frame's parent frame pointer is correct + NS_ASSERTION(kid->GetParent() == (nsIFrame*)this, "bad parent frame pointer"); + + // Have the child frame list + nsIFrameDebug* frameDebug; + if (NS_SUCCEEDED(kid->QueryInterface(NS_GET_IID(nsIFrameDebug), (void**)&frameDebug))) { + frameDebug->List(out, aIndent + 1); + } + kid = kid->GetNextSibling(); + } + IndentBy(out, aIndent); + fputs(">\n", out); + } + listName = GetAdditionalChildListName(listIndex++); + } while(nsnull != listName); + + // XXXmats the above is copy-pasted from nsContainerFrame::List which is lame, + // clean this up after bug 399111 is implemented. + + if (mPopupList) { + fputs("<\n", out); + ++aIndent; + IndentBy(out, aIndent); + nsAutoString tmp; + nsGkAtoms::popupList->ToString(tmp); + fputs(NS_LossyConvertUTF16toASCII(tmp).get(), out); + fputs(" for ", out); + ListTag(out); + fputs(" <\n", out); + ++aIndent; + for (nsPopupFrameList* l = mPopupList; l; l = l->mNextPopup) { + nsIFrameDebug* frameDebug; + if (l->mPopupFrame && + NS_SUCCEEDED(CallQueryInterface(l->mPopupFrame, &frameDebug))) { + frameDebug->List(out, aIndent); + } + } + --aIndent; + IndentBy(out, aIndent); + fputs(">\n", out); + --aIndent; + IndentBy(out, aIndent); + fputs(">\n", out); + outputOneList = PR_TRUE; + } + + if (!outputOneList) { + fputs("<>\n", out); + } + + return NS_OK; } +#endif diff --git a/layout/xul/base/src/nsPopupSetFrame.h b/layout/xul/base/src/nsPopupSetFrame.h index 901b578ed6ec..92a65bb84687 100644 --- a/layout/xul/base/src/nsPopupSetFrame.h +++ b/layout/xul/base/src/nsPopupSetFrame.h @@ -91,6 +91,7 @@ public: virtual nsIAtom* GetType() const; #ifdef DEBUG + NS_IMETHOD List(FILE* out, PRInt32 aIndent) const; NS_IMETHOD GetFrameName(nsAString& aResult) const { return MakeFrameName(NS_LITERAL_STRING("PopupSet"), aResult); @@ -102,7 +103,6 @@ protected: nsresult AddPopupFrameList(nsIFrame* aPopupFrameList); nsresult AddPopupFrame(nsIFrame* aPopup); nsresult RemovePopupFrame(nsIFrame* aPopup); - void DestroyPopupFrame(nsCSSFrameConstructor* aFc, nsIFrame* aPopup); nsPopupFrameList* mPopupList; diff --git a/layout/xul/base/src/nsXULPopupManager.cpp b/layout/xul/base/src/nsXULPopupManager.cpp index c8c472cfb840..bf1bfcf7dcb3 100644 --- a/layout/xul/base/src/nsXULPopupManager.cpp +++ b/layout/xul/base/src/nsXULPopupManager.cpp @@ -603,7 +603,7 @@ nsXULPopupManager::HidePopupCallback(nsIContent* aPopup, nsPopupType aPopupType, PRBool aDeselectMenu) { - if (mCloseTimer) { + if (mCloseTimer && mTimerMenu == aPopupFrame) { mCloseTimer->Cancel(); mCloseTimer = nsnull; mTimerMenu = nsnull; @@ -1845,10 +1845,16 @@ nsXULMenuCommandEvent::Run() // need to be hidden. nsIFrame* popupFrame = menuFrame->GetParent(); while (popupFrame) { - if (popupFrame->GetType() == nsGkAtoms::menuPopupFrame) { - popup = popupFrame->GetContent(); + // If the menu is a descendant of a menubar, clear the recently closed + // state. Break out afterwards, as the menubar is the top level of a + // menu hierarchy. + if (popupFrame->GetType() == nsGkAtoms::menuBarFrame) { + (static_cast(popupFrame))->SetRecentlyClosed(nsnull); break; } + else if (!popup && popupFrame->GetType() == nsGkAtoms::menuPopupFrame) { + popup = popupFrame->GetContent(); + } popupFrame = popupFrame->GetParent(); } diff --git a/layout/xul/test/Makefile.in b/layout/xul/test/Makefile.in index 0120a8a5428e..f258d73f1b04 100644 --- a/layout/xul/test/Makefile.in +++ b/layout/xul/test/Makefile.in @@ -45,6 +45,10 @@ include $(DEPTH)/config/autoconf.mk include $(topsrcdir)/config/rules.mk _TEST_FILES = test_bug372685.xul \ + test_bug386386.html \ + test_bug394800.xhtml \ + test_bug398982-1.xul \ + test_bug398982-2.xul \ $(NULL) libs:: $(_TEST_FILES) diff --git a/layout/xul/test/test_bug386386.html b/layout/xul/test/test_bug386386.html new file mode 100644 index 000000000000..ee87aa56d7cf --- /dev/null +++ b/layout/xul/test/test_bug386386.html @@ -0,0 +1,34 @@ + +Testcase for bug 386386 + + + + + + + + + + + + diff --git a/layout/xul/test/test_bug394800.xhtml b/layout/xul/test/test_bug394800.xhtml new file mode 100644 index 000000000000..61f56b4eb0a8 --- /dev/null +++ b/layout/xul/test/test_bug394800.xhtml @@ -0,0 +1,40 @@ + + + + Test Mozilla bug 394800 + + + + + + + + +
    + +Mozilla Bug 394800 +

    + +
    +
    + + + + + diff --git a/layout/xul/test/test_bug398982-1.xul b/layout/xul/test/test_bug398982-1.xul new file mode 100644 index 000000000000..d41c4e81bf0b --- /dev/null +++ b/layout/xul/test/test_bug398982-1.xul @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + diff --git a/layout/xul/test/test_bug398982-2.xul b/layout/xul/test/test_bug398982-2.xul new file mode 100644 index 000000000000..6a7bfe5cd3f9 --- /dev/null +++ b/layout/xul/test/test_bug398982-2.xul @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + diff --git a/modules/libpr0n/decoders/bmp/nsBMPDecoder.cpp b/modules/libpr0n/decoders/bmp/nsBMPDecoder.cpp index 11956f371c46..0635c3b11ffe 100644 --- a/modules/libpr0n/decoders/bmp/nsBMPDecoder.cpp +++ b/modules/libpr0n/decoders/bmp/nsBMPDecoder.cpp @@ -122,17 +122,32 @@ NS_IMETHODIMP nsBMPDecoder::Flush() NS_METHOD nsBMPDecoder::ReadSegCb(nsIInputStream* aIn, void* aClosure, const char* aFromRawSegment, PRUint32 aToOffset, - PRUint32 aCount, PRUint32 *aWriteCount) { + PRUint32 aCount, PRUint32 *aWriteCount) +{ nsBMPDecoder *decoder = reinterpret_cast(aClosure); *aWriteCount = aCount; - return decoder->ProcessData(aFromRawSegment, aCount); + + nsresult rv = decoder->ProcessData(aFromRawSegment, aCount); + + if (NS_FAILED(rv)) { + *aWriteCount = 0; + } + + return rv; } NS_IMETHODIMP nsBMPDecoder::WriteFrom(nsIInputStream *aInStr, PRUint32 aCount, PRUint32 *aRetval) { PR_LOG(gBMPLog, PR_LOG_DEBUG, ("nsBMPDecoder::WriteFrom(%p, %lu, %p)\n", aInStr, aCount, aRetval)); - return aInStr->ReadSegments(ReadSegCb, this, aCount, aRetval); + nsresult rv = aInStr->ReadSegments(ReadSegCb, this, aCount, aRetval); + + if (aCount != *aRetval) { + *aRetval = aCount; + return NS_ERROR_FAILURE; + } + + return rv; } // ---------------------------------------- diff --git a/modules/libpr0n/decoders/gif/nsGIFDecoder2.cpp b/modules/libpr0n/decoders/gif/nsGIFDecoder2.cpp index 99512a7f3843..9d799b97a8f9 100644 --- a/modules/libpr0n/decoders/gif/nsGIFDecoder2.cpp +++ b/modules/libpr0n/decoders/gif/nsGIFDecoder2.cpp @@ -965,6 +965,12 @@ nsresult nsGIFDecoder2::GifWrite(const PRUint8 *buf, PRUint32 len) } BeginImageFrame(); + + // handle allocation error + if (!mImageFrame) { + mGIFStruct.state = gif_error; + break; + } if (q[8] & 0x40) { mGIFStruct.interlaced = PR_TRUE; @@ -1055,11 +1061,15 @@ nsresult nsGIFDecoder2::GifWrite(const PRUint8 *buf, PRUint32 len) break; case gif_done: - case gif_error: EndGIF(); return NS_OK; break; + case gif_error: + EndGIF(); + return NS_ERROR_FAILURE; + break; + // Handle out of memory errors case gif_oom: return NS_ERROR_OUT_OF_MEMORY; @@ -1070,6 +1080,12 @@ nsresult nsGIFDecoder2::GifWrite(const PRUint8 *buf, PRUint32 len) } } + // if an error state is set but no data remains, code flow reaches here + if (mGIFStruct.state == gif_error) { + EndGIF(); + return NS_ERROR_FAILURE; + } + // Copy the leftover into mGIFStruct.hold mGIFStruct.bytes_in_hold = len; if (len) { diff --git a/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp b/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp index a1cfc0c95c05..150da9b2ae2b 100644 --- a/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp +++ b/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.cpp @@ -22,6 +22,7 @@ * * Contributor(s): * Stuart Parmenter + * Federico Mena-Quintero * * 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 @@ -63,8 +64,10 @@ NS_IMPL_ISUPPORTS1(nsJPEGDecoder, imgIDecoder) #if defined(PR_LOGGING) PRLogModuleInfo *gJPEGlog = PR_NewLogModule("JPEGDecoder"); +static PRLogModuleInfo *gJPEGDecoderAccountingLog = PR_NewLogModule("JPEGDecoderAccounting"); #else #define gJPEGlog +#define gJPEGDecoderAccountingLog #endif @@ -96,6 +99,10 @@ nsJPEGDecoder::nsJPEGDecoder() mInProfile = nsnull; mTransform = nsnull; + + PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, + ("nsJPEGDecoder::nsJPEGDecoder: Creating JPEG decoder %p", + this)); } nsJPEGDecoder::~nsJPEGDecoder() @@ -106,6 +113,10 @@ nsJPEGDecoder::~nsJPEGDecoder() cmsDeleteTransform(mTransform); if (mInProfile) cmsCloseProfile(mInProfile); + + PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, + ("nsJPEGDecoder::~nsJPEGDecoder: Destroying JPEG decoder %p", + this)); } @@ -147,6 +158,34 @@ NS_IMETHODIMP nsJPEGDecoder::Init(imgILoad *aLoad) for (PRUint32 m = 0; m < 16; m++) jpeg_save_markers(&mInfo, JPEG_APP0 + m, 0xFFFF); + + + /* Check if the request already has an image container. + * this is the case when multipart/x-mixed-replace is being downloaded + * if we already have one and it has the same width and height, reuse it. + * This is also the case when an existing container is reloading itself from + * us. + * + * If we have a mismatch in width/height for the container later on we will + * generate an error. + */ + mImageLoad->GetImage(getter_AddRefs(mImage)); + + if (!mImage) { + mImage = do_CreateInstance("@mozilla.org/image/container;1"); + if (!mImage) + return NS_ERROR_OUT_OF_MEMORY; + + mImageLoad->SetImage(mImage); + nsresult result = mImage->SetDiscardable("image/jpeg"); + if (NS_FAILED(result)) { + mState = JPEG_ERROR; + PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, + (" (could not set image container to discardable)")); + return result; + } + } + return NS_OK; } @@ -185,11 +224,20 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR { LOG_SCOPE_WITH_PARAM(gJPEGlog, "nsJPEGDecoder::WriteFrom", "count", count); + PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, + ("nsJPEGDecoder::WriteFrom(decoder = %p) {\n" + " image container %s; %u bytes to be added", + this, + mImage ? "exists" : "does not exist", + count)); + if (inStr) { if (!mBuffer) { mBuffer = (JOCTET *)PR_Malloc(count); if (!mBuffer) { mState = JPEG_ERROR; + PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, + ("} (out of memory allocating buffer)")); return NS_ERROR_OUT_OF_MEMORY; } mBufferSize = count; @@ -197,6 +245,8 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR JOCTET *buf = (JOCTET *)PR_Realloc(mBuffer, count); if (!buf) { mState = JPEG_ERROR; + PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, + ("} (out of memory resizing buffer)")); return NS_ERROR_OUT_OF_MEMORY; } mBuffer = buf; @@ -204,9 +254,29 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR } nsresult rv = inStr->Read((char*)mBuffer, count, &mBufferLen); + NS_ASSERTION(NS_SUCCEEDED(rv), "nsJPEGDecoder::WriteFrom -- inStr->Read failed"); + + PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, + ("nsJPEGDecoder::WriteFrom(): decoder %p got %u bytes, read %u from the stream (buffer size %u)", + this, + count, + mBufferLen, + mBufferSize)); + *_retval = mBufferLen; - NS_ASSERTION(NS_SUCCEEDED(rv), "nsJPEGDecoder::WriteFrom -- inStr->Read failed"); + nsresult result = mImage->AddRestoreData((char *) mBuffer, count); + + if (NS_FAILED(result)) { + mState = JPEG_ERROR; + PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, + ("} (could not add restore data)")); + return result; + } + + PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, + (" added %u bytes to restore data", + count)); } // else no input stream.. Flush() ? @@ -217,11 +287,15 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR if (error_code == NS_ERROR_FAILURE) { /* Error due to corrupt stream - return NS_OK so that libpr0n doesn't throw away a partial image load */ + PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, + ("} (setjmp returned NS_ERROR_FAILURE)")); return NS_OK; } else { /* Error due to reasons external to the stream (probably out of memory) - let libpr0n attempt to clean up, even though mozilla is seconds away from falling flat on its face. */ + PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, + ("} (setjmp returned an error)")); return error_code; } } @@ -235,8 +309,11 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- entering JPEG_HEADER case"); /* Step 3: read file parameters with jpeg_read_header() */ - if (jpeg_read_header(&mInfo, TRUE) == JPEG_SUSPENDED) + if (jpeg_read_header(&mInfo, TRUE) == JPEG_SUSPENDED) { + PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, + ("} (JPEG_SUSPENDED)")); return NS_OK; /* I/O suspension */ + } JOCTET *profile; PRUint32 profileLength; @@ -278,6 +355,8 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR break; default: mState = JPEG_ERROR; + PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, + ("} (unknown colorpsace (1))")); return NS_ERROR_UNEXPECTED; } @@ -301,6 +380,8 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR break; default: mState = JPEG_ERROR; + PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, + ("} (unknown colorpsace (2))")); return NS_ERROR_UNEXPECTED; } @@ -336,6 +417,8 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR break; default: mState = JPEG_ERROR; + PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, + ("} (unknown colorpsace (3))")); return NS_ERROR_UNEXPECTED; break; } @@ -352,30 +435,21 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR mObserver->OnStartDecode(nsnull); - /* Check if the request already has an image container. - this is the case when multipart/x-mixed-replace is being downloaded - if we already have one and it has the same width and height, reuse it. + /* verify that the width and height of the image are the same as + * the container we're about to put things in to. + * XXX it might not matter maybe we should just resize the image. */ - mImageLoad->GetImage(getter_AddRefs(mImage)); - if (mImage) { - PRInt32 width, height; - mImage->GetWidth(&width); - mImage->GetHeight(&height); - if ((width != (PRInt32)mInfo.image_width) || - (height != (PRInt32)mInfo.image_height)) { - mImage = nsnull; - } + PRInt32 width, height; + mImage->GetWidth(&width); + mImage->GetHeight(&height); + if (width == 0 && height == 0) { + mImage->Init(mInfo.image_width, mInfo.image_height, mObserver); + } else if ((width != (PRInt32)mInfo.image_width) || (height != (PRInt32)mInfo.image_height)) { + mState = JPEG_ERROR; + return NS_ERROR_UNEXPECTED; } - if (!mImage) { - mImage = do_CreateInstance("@mozilla.org/image/container;1"); - if (!mImage) { - mState = JPEG_ERROR; - return NS_ERROR_OUT_OF_MEMORY; - } - mImageLoad->SetImage(mImage); - mImage->Init(mInfo.image_width, mInfo.image_height, mObserver); - } + mImage->Init(mInfo.image_width, mInfo.image_height, mObserver); mObserver->OnStartContainer(nsnull, mImage); @@ -400,6 +474,8 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR mFrame = do_CreateInstance("@mozilla.org/gfx/image/frame;2"); if (!mFrame) { mState = JPEG_ERROR; + PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, + ("} (could not create image frame)")); return NS_ERROR_OUT_OF_MEMORY; } @@ -410,11 +486,17 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR if (NS_FAILED(mFrame->Init(0, 0, mInfo.image_width, mInfo.image_height, format, 24))) { mState = JPEG_ERROR; + PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, + ("} (could not initialize image frame)")); return NS_ERROR_OUT_OF_MEMORY; } mImage->AppendFrame(mFrame); - } + + PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, + (" JPEGDecoderAccounting: nsJPEGDecoder::WriteFrom -- created image frame with %ux%u pixels", + mInfo.image_width, mInfo.image_height)); + } mObserver->OnStartFrame(nsnull, mFrame); mState = JPEG_START_DECOMPRESS; @@ -435,8 +517,11 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR mInfo.do_block_smoothing = TRUE; /* Step 5: Start decompressor */ - if (jpeg_start_decompress(&mInfo) == FALSE) + if (jpeg_start_decompress(&mInfo) == FALSE) { + PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, + ("} (I/O suspension after jpeg_start_decompress())")); return NS_OK; /* I/O suspension */ + } /* If this is a progressive JPEG ... */ if (mInfo.buffered_image) { @@ -452,8 +537,11 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR { LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- JPEG_DECOMPRESS_SEQUENTIAL case"); - if (!OutputScanlines()) + if (!OutputScanlines()) { + PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, + ("} (I/O suspension after OutputScanlines() - SEQUENTIAL)")); return NS_OK; /* I/O suspension */ + } /* If we've completed image output ... */ NS_ASSERTION(mInfo.output_scanline == mInfo.output_height, "We didn't process all of the data!"); @@ -485,8 +573,11 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR (status != JPEG_REACHED_EOI)) scan--; - if (!jpeg_start_output(&mInfo, scan)) + if (!jpeg_start_output(&mInfo, scan)) { + PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, + ("} (I/O suspension after jpeg_start_output() - PROGRESSIVE)")); return NS_OK; /* I/O suspension */ + } } if (mInfo.output_scanline == 0xffffff) @@ -498,13 +589,18 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR jpeg_start_output() multiple times for the same scan */ mInfo.output_scanline = 0xffffff; } + PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, + ("} (I/O suspension after OutputScanlines() - PROGRESSIVE)")); return NS_OK; /* I/O suspension */ } if (mInfo.output_scanline == mInfo.output_height) { - if (!jpeg_finish_output(&mInfo)) + if (!jpeg_finish_output(&mInfo)) { + PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, + ("} (I/O suspension after jpeg_finish_output() - PROGRESSIVE)")); return NS_OK; /* I/O suspension */ + } if (jpeg_input_complete(&mInfo) && (mInfo.input_scan_number == mInfo.output_scan_number)) @@ -520,15 +616,28 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR case JPEG_DONE: { + nsresult result; + LOG_SCOPE(gJPEGlog, "nsJPEGDecoder::WriteFrom -- entering JPEG_DONE case"); /* Step 7: Finish decompression */ - if (jpeg_finish_decompress(&mInfo) == FALSE) + if (jpeg_finish_decompress(&mInfo) == FALSE) { + PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, + ("} (I/O suspension after jpeg_finish_decompress() - DONE)")); return NS_OK; /* I/O suspension */ + } mState = JPEG_SINK_NON_JPEG_TRAILER; + result = mImage->RestoreDataDone(); + if (NS_FAILED (result)) { + mState = JPEG_ERROR; + PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, + ("} (could not mark image container with RestoreDataDone)")); + return result; + } + /* we're done dude */ break; } @@ -545,6 +654,8 @@ NS_IMETHODIMP nsJPEGDecoder::WriteFrom(nsIInputStream *inStr, PRUint32 count, PR break; } + PR_LOG(gJPEGDecoderAccountingLog, PR_LOG_DEBUG, + ("} (end of function)")); return NS_OK; } diff --git a/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.h b/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.h index d4f960d42fd0..dae586fe4c5e 100644 --- a/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.h +++ b/modules/libpr0n/decoders/jpeg/nsJPEGDecoder.h @@ -124,6 +124,10 @@ public: cmsHTRANSFORM mTransform; PRPackedBool mReading; + +private: + + nsresult AddToTmpAccumulateBuffer(JOCTET *src, PRUint32 len); }; #endif // nsJPEGDecoder_h__ diff --git a/modules/libpr0n/decoders/png/nsPNGDecoder.cpp b/modules/libpr0n/decoders/png/nsPNGDecoder.cpp index 69feefa45589..0b00ef52d614 100644 --- a/modules/libpr0n/decoders/png/nsPNGDecoder.cpp +++ b/modules/libpr0n/decoders/png/nsPNGDecoder.cpp @@ -23,6 +23,7 @@ * Contributor(s): * Stuart Parmenter * Andrew Smith + * Federico Mena-Quintero * * 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 @@ -72,7 +73,8 @@ static void PNGAPI error_callback(png_structp png_ptr, png_const_charp error_msg static void PNGAPI warning_callback(png_structp png_ptr, png_const_charp warning_msg); #ifdef PR_LOGGING -PRLogModuleInfo *gPNGLog = PR_NewLogModule("PNGDecoder"); +static PRLogModuleInfo *gPNGLog = PR_NewLogModule("PNGDecoder"); +static PRLogModuleInfo *gPNGDecoderAccountingLog = PR_NewLogModule("PNGDecoderAccounting"); #endif NS_IMPL_ISUPPORTS1(nsPNGDecoder, imgIDecoder) @@ -120,6 +122,12 @@ void nsPNGDecoder::CreateFrame(png_uint_32 x_offset, png_uint_32 y_offset, if (mObserver) mObserver->OnStartFrame(nsnull, mFrame); + + PR_LOG(gPNGDecoderAccountingLog, PR_LOG_DEBUG, + ("PNGDecoderAccounting: nsPNGDecoder::CreateFrame -- created image frame with %dx%d pixels in container %p", + width, height, + mImage.get ())); + mFrameHasNoAlpha = PR_TRUE; } @@ -128,13 +136,13 @@ void nsPNGDecoder::SetAnimFrameInfo() { png_uint_16 delay_num, delay_den; /* in seconds */ png_byte dispose_op; + png_byte blend_op; PRInt32 timeout; /* in milliseconds */ delay_num = png_get_next_frame_delay_num(mPNG, mInfo); delay_den = png_get_next_frame_delay_den(mPNG, mInfo); dispose_op = png_get_next_frame_dispose_op(mPNG, mInfo); - - // XXX need to handle blend_op here! + blend_op = png_get_next_frame_blend_op(mPNG, mInfo); if (delay_num == 0) { timeout = 0; // gfxImageFrame::SetTimeout() will set to a minimum @@ -155,6 +163,11 @@ void nsPNGDecoder::SetAnimFrameInfo() mFrame->SetFrameDisposalMethod(imgIContainer::kDisposeClear); else mFrame->SetFrameDisposalMethod(imgIContainer::kDisposeKeep); + + if (blend_op == PNG_BLEND_OP_SOURCE) + mFrame->SetBlendMethod(imgIContainer::kBlendSource); + /*else // 'over' is the default for a gfxImageFrame + mFrame->SetBlendMethod(imgIContainer::kBlendOver); */ } @@ -209,6 +222,25 @@ NS_IMETHODIMP nsPNGDecoder::Init(imgILoad *aLoad) png_set_progressive_read_fn(mPNG, static_cast(this), info_callback, row_callback, end_callback); + + /* The image container may already exist if it is reloading itself from us. + * Check that it has the same width/height; otherwise create a new container. + */ + mImageLoad->GetImage(getter_AddRefs(mImage)); + if (!mImage) { + mImage = do_CreateInstance("@mozilla.org/image/container;1"); + if (!mImage) + return NS_ERROR_OUT_OF_MEMORY; + + mImageLoad->SetImage(mImage); + if (NS_FAILED(mImage->SetDiscardable("image/png"))) { + PR_LOG(gPNGDecoderAccountingLog, PR_LOG_DEBUG, + ("PNGDecoderAccounting: info_callback(): failed to set image container %p as discardable", + mImage.get())); + return NS_ERROR_FAILURE; + } + } + return NS_OK; } @@ -218,13 +250,28 @@ NS_IMETHODIMP nsPNGDecoder::Close() if (mPNG) png_destroy_read_struct(&mPNG, mInfo ? &mInfo : NULL, NULL); + if (mImage) { // mImage could be null in the case of an error + nsresult result = mImage->RestoreDataDone(); + if (NS_FAILED(result)) { + PR_LOG(gPNGDecoderAccountingLog, PR_LOG_DEBUG, + ("PNGDecoderAccounting: nsPNGDecoder::Close(): failure in RestoreDataDone() for image container %p", + mImage.get())); + + mError = PR_TRUE; + return result; + } + + PR_LOG(gPNGDecoderAccountingLog, PR_LOG_DEBUG, + ("PNGDecoderAccounting: nsPNGDecoder::Close(): image container %p is now with RestoreDataDone", + mImage.get())); + } return NS_OK; } /* void flush (); */ NS_IMETHODIMP nsPNGDecoder::Flush() { - return NS_ERROR_NOT_IMPLEMENTED; + return NS_OK; } @@ -250,10 +297,24 @@ static NS_METHOD ReadDataOut(nsIInputStream* in, *writeCount = 0; return NS_ERROR_FAILURE; } - png_process_data(decoder->mPNG, decoder->mInfo, reinterpret_cast(const_cast(fromRawSegment)), count); + nsresult result = decoder->mImage->AddRestoreData((char *) fromRawSegment, count); + if (NS_FAILED (result)) { + PR_LOG(gPNGDecoderAccountingLog, PR_LOG_DEBUG, + ("PNGDecoderAccounting: ReadDataOut(): failed to add restore data to image container %p", + decoder->mImage.get())); + + decoder->mError = PR_TRUE; + *writeCount = 0; + return result; + } + + PR_LOG(gPNGDecoderAccountingLog, PR_LOG_DEBUG, + ("PNGDecoderAccounting: ReadDataOut(): Added restore data to image container %p", + decoder->mImage.get())); + *writeCount = count; return NS_OK; } @@ -513,13 +574,18 @@ info_callback(png_structp png_ptr, png_infop info_ptr) if (decoder->mObserver) decoder->mObserver->OnStartDecode(nsnull); - decoder->mImage = do_CreateInstance("@mozilla.org/image/container;1"); - if (!decoder->mImage) - longjmp(decoder->mPNG->jmpbuf, 5); // NS_ERROR_OUT_OF_MEMORY - - decoder->mImageLoad->SetImage(decoder->mImage); - - decoder->mImage->Init(width, height, decoder->mObserver); + /* The image container may already exist if it is reloading itself from us. + * Check that it has the same width/height; otherwise create a new container. + */ + PRInt32 containerWidth, containerHeight; + decoder->mImage->GetWidth(&containerWidth); + decoder->mImage->GetHeight(&containerHeight); + if (containerWidth == 0 && containerHeight == 0) { + // the image hasn't been inited yet + decoder->mImage->Init(width, height, decoder->mObserver); + } else if (containerWidth != width || containerHeight != height) { + longjmp(decoder->mPNG->jmpbuf, 5); // NS_ERROR_UNEXPECTED + } if (decoder->mObserver) decoder->mObserver->OnStartContainer(nsnull, decoder->mImage); @@ -761,7 +827,7 @@ end_callback(png_structp png_ptr, png_infop info_ptr) } decoder->mImage->DecodingComplete(); - + if (decoder->mObserver) { if (!(decoder->apngFlags & FRAME_HIDDEN)) decoder->mObserver->OnStopFrame(nsnull, decoder->mFrame); diff --git a/modules/libpr0n/decoders/xbm/nsXBMDecoder.cpp b/modules/libpr0n/decoders/xbm/nsXBMDecoder.cpp index 962586b66441..538ce5efc797 100644 --- a/modules/libpr0n/decoders/xbm/nsXBMDecoder.cpp +++ b/modules/libpr0n/decoders/xbm/nsXBMDecoder.cpp @@ -121,12 +121,26 @@ NS_METHOD nsXBMDecoder::ReadSegCb(nsIInputStream* aIn, void* aClosure, PRUint32 aCount, PRUint32 *aWriteCount) { nsXBMDecoder *decoder = reinterpret_cast(aClosure); *aWriteCount = aCount; - return decoder->ProcessData(aFromRawSegment, aCount); + + nsresult rv = decoder->ProcessData(aFromRawSegment, aCount); + + if (NS_FAILED(rv)) { + *aWriteCount = 0; + } + + return rv; } NS_IMETHODIMP nsXBMDecoder::WriteFrom(nsIInputStream *aInStr, PRUint32 aCount, PRUint32 *aRetval) { - return aInStr->ReadSegments(ReadSegCb, this, aCount, aRetval); + nsresult rv = aInStr->ReadSegments(ReadSegCb, this, aCount, aRetval); + + if (aCount != *aRetval) { + *aRetval = aCount; + return NS_ERROR_FAILURE; + } + + return rv; } nsresult nsXBMDecoder::ProcessData(const char* aData, PRUint32 aCount) { diff --git a/modules/libpr0n/encoders/png/nsPNGEncoder.cpp b/modules/libpr0n/encoders/png/nsPNGEncoder.cpp index 791b5d1fb5e3..83dc98403220 100644 --- a/modules/libpr0n/encoders/png/nsPNGEncoder.cpp +++ b/modules/libpr0n/encoders/png/nsPNGEncoder.cpp @@ -69,6 +69,9 @@ nsPNGEncoder::~nsPNGEncoder() PR_Free(mImageBuffer); mImageBuffer = nsnull; } + // don't leak if EndImageEncode wasn't called + if (mPNG) + png_destroy_write_struct(&mPNG, &mPNGinfo); } // nsPNGEncoder::InitFromData @@ -215,6 +218,10 @@ NS_IMETHODIMP nsPNGEncoder::AddImageFrame(const PRUint8* aData, if (mImageBuffer == nsnull) return NS_ERROR_NOT_INITIALIZED; + // EndImageEncode was done, or some error occurred earlier + if (!mPNG) + return NS_BASE_STREAM_CLOSED; + // validate input format if (aInputFormat != INPUT_FORMAT_RGB && aInputFormat != INPUT_FORMAT_RGBA && @@ -296,6 +303,10 @@ NS_IMETHODIMP nsPNGEncoder::EndImageEncode() if (mImageBuffer == nsnull) return NS_ERROR_NOT_INITIALIZED; + // EndImageEncode has already been called, or some error occurred earlier + if (!mPNG) + return NS_BASE_STREAM_CLOSED; + // libpng's error handler jumps back here upon an error. if (setjmp(png_jmpbuf(mPNG))) { png_destroy_write_struct(&mPNG, &mPNGinfo); diff --git a/modules/libpr0n/public/imgIContainer.idl b/modules/libpr0n/public/imgIContainer.idl index fc42335576dc..cc7502128983 100644 --- a/modules/libpr0n/public/imgIContainer.idl +++ b/modules/libpr0n/public/imgIContainer.idl @@ -22,6 +22,7 @@ * * Contributor(s): * Stuart Parmenter + * Federico Mena-Quintero * * 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 @@ -67,6 +68,16 @@ interface imgIContainer : nsISupports const long kDisposeClear = 2; // Clear the frame's area, revealing bg const long kDisposeRestorePrevious = 3; // Restore the previous (composited) frame + /* + * "Blend" method indicates how the current image is combined with the + * previous image. + */ + const long kBlendSource = 0; // All color components of the frame, including alpha, + // overwrite the current contents of the frame's + // output buffer region + const long kBlendOver = 1; // The frame should be composited onto the output buffer + // based on its alpha, using a simple OVER operation + /** * Create a new \a aWidth x \a aHeight sized image container. * @@ -144,4 +155,10 @@ interface imgIContainer : nsISupports * @note -1 means forever. */ attribute long loopCount; + + /* Methods to discard uncompressed images and restore them again */ + [noscript] void setDiscardable(in string aMimeType); + [noscript] void addRestoreData([array, size_is(aCount), const] in char data, + in unsigned long aCount); + [noscript] void restoreDataDone(); }; diff --git a/modules/libpr0n/src/imgContainer.cpp b/modules/libpr0n/src/imgContainer.cpp index 61503b044e19..ac1816b334e1 100644 --- a/modules/libpr0n/src/imgContainer.cpp +++ b/modules/libpr0n/src/imgContainer.cpp @@ -25,6 +25,7 @@ * Asko Tontti * Arron Mogge * Andrew Smith + * Federico Mena-Quintero * * 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 @@ -42,23 +43,47 @@ #include "nsComponentManagerUtils.h" #include "imgIContainerObserver.h" +#include "ImageErrors.h" #include "nsIImage.h" +#include "imgILoad.h" +#include "imgIDecoder.h" +#include "imgIDecoderObserver.h" #include "imgContainer.h" #include "nsIInterfaceRequestor.h" #include "nsIInterfaceRequestorUtils.h" #include "nsAutoPtr.h" +#include "nsStringStream.h" +#include "prmem.h" +#include "prlog.h" +#include "prenv.h" #include "gfxContext.h" +/* Accounting for compressed data */ +#if defined(PR_LOGGING) +static PRLogModuleInfo *gCompressedImageAccountingLog = PR_NewLogModule ("CompressedImageAccounting"); +#else +#define gCompressedImageAccountingLog +#endif + +static int num_containers_with_discardable_data; +static PRInt64 num_compressed_image_bytes; + + NS_IMPL_ISUPPORTS3(imgContainer, imgIContainer, nsITimerCallback, nsIProperties) //****************************************************************************** imgContainer::imgContainer() : mSize(0,0), + mNumFrames(0), mAnim(nsnull), mAnimationMode(kNormalAnimMode), mLoopCount(-1), - mObserver(nsnull) + mObserver(nsnull), + mDiscardable(PR_FALSE), + mDiscarded(PR_FALSE), + mRestoreDataDone(PR_FALSE), + mDiscardTimer(nsnull) { } @@ -67,6 +92,23 @@ imgContainer::~imgContainer() { if (mAnim) delete mAnim; + + if (!mRestoreData.IsEmpty()) { + num_containers_with_discardable_data--; + num_compressed_image_bytes -= mRestoreData.Length(); + + PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG, + ("CompressedImageAccounting: destroying imgContainer %p. " + "Compressed containers: %d, Compressed data bytes: %lld", + this, + num_containers_with_discardable_data, + num_compressed_image_bytes)); + } + + if (mDiscardTimer) { + mDiscardTimer->Cancel (); + mDiscardTimer = nsnull; + } } //****************************************************************************** @@ -124,15 +166,53 @@ NS_IMETHODIMP imgContainer::GetHeight(PRInt32 *aHeight) return NS_OK; } +nsresult imgContainer::GetCurrentFrameNoRef(gfxIImageFrame **aFrame) +{ + nsresult result; + + result = RestoreDiscardedData(); + if (NS_FAILED (result)) { + PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG, + ("CompressedImageAccounting: imgContainer::GetCurrentFrameNoRef(): error %d in RestoreDiscardedData(); " + "returning a null frame from imgContainer %p", + result, + this)); + + *aFrame = nsnull; + return result; + } + + if (!mAnim) + *aFrame = mFrames.SafeObjectAt(0); + else if (mAnim->lastCompositedFrameIndex == mAnim->currentAnimationFrameIndex) + *aFrame = mAnim->compositingFrame; + else + *aFrame = mFrames.SafeObjectAt(mAnim->currentAnimationFrameIndex); + + if (!*aFrame) + PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG, + ("CompressedImageAccounting: imgContainer::GetCurrentFrameNoRef(): returning null frame from imgContainer %p " + "(no errors when restoring data)", + this)); + + return NS_OK; +} + //****************************************************************************** /* readonly attribute gfxIImageFrame currentFrame; */ NS_IMETHODIMP imgContainer::GetCurrentFrame(gfxIImageFrame **aCurrentFrame) { + nsresult result; + NS_ASSERTION(aCurrentFrame, "imgContainer::GetCurrentFrame; Invalid Arg"); if (!aCurrentFrame) return NS_ERROR_INVALID_POINTER; - if (!(*aCurrentFrame = inlinedGetCurrentFrame())) + result = GetCurrentFrameNoRef (aCurrentFrame); + if (NS_FAILED (result)) + return result; + + if (!*aCurrentFrame) return NS_ERROR_FAILURE; NS_ADDREF(*aCurrentFrame); @@ -148,7 +228,7 @@ NS_IMETHODIMP imgContainer::GetNumFrames(PRUint32 *aNumFrames) if (!aNumFrames) return NS_ERROR_INVALID_ARG; - *aNumFrames = mFrames.Count(); + *aNumFrames = mNumFrames; return NS_OK; } @@ -157,16 +237,24 @@ NS_IMETHODIMP imgContainer::GetNumFrames(PRUint32 *aNumFrames) /* gfxIImageFrame getFrameAt (in unsigned long index); */ NS_IMETHODIMP imgContainer::GetFrameAt(PRUint32 index, gfxIImageFrame **_retval) { + nsresult result; + NS_ASSERTION(_retval, "imgContainer::GetFrameAt; Invalid Arg"); if (!_retval) return NS_ERROR_INVALID_POINTER; - if (!mFrames.Count()) { + if (mNumFrames == 0) { *_retval = nsnull; return NS_OK; } - NS_ENSURE_ARG(index < static_cast(mFrames.Count())); + NS_ENSURE_ARG((int) index < mNumFrames); + + result = RestoreDiscardedData (); + if (NS_FAILED (result)) { + *_retval = nsnull; + return result; + } if (!(*_retval = mFrames[index])) return NS_ERROR_FAILURE; @@ -183,17 +271,18 @@ NS_IMETHODIMP imgContainer::AppendFrame(gfxIImageFrame *item) NS_ASSERTION(item, "imgContainer::AppendFrame; Invalid Arg"); if (!item) return NS_ERROR_INVALID_ARG; - - PRInt32 numFrames = mFrames.Count(); - - if (numFrames == 0) { + + if (mFrames.Count() == 0) { // This may not be an animated image, don't do all the animation stuff. mFrames.AppendObject(item); + + mNumFrames++; + return NS_OK; } - if (numFrames == 1) { - // Now that we got a second frame, initialize animation stuff. + if (mFrames.Count() == 1) { + // Since we're about to add our second frame, initialize animation stuff if (!ensureAnimExists()) return NS_ERROR_OUT_OF_MEMORY; @@ -216,11 +305,13 @@ NS_IMETHODIMP imgContainer::AppendFrame(gfxIImageFrame *item) itemRect); mFrames.AppendObject(item); + + mNumFrames++; - // If this is our second frame, start the animation. - // Must be called after AppendObject because StartAnimation checks for > 1 - // frame - if (numFrames == 1) + // If this is our second frame (We've just added our second frame above), + // count should now be 2. This must be called after we AppendObject + // because StartAnimation checks for > 1 frames + if (mFrames.Count() == 2) StartAnimation(); return NS_OK; @@ -230,6 +321,7 @@ NS_IMETHODIMP imgContainer::AppendFrame(gfxIImageFrame *item) /* void removeFrame (in gfxIImageFrame item); */ NS_IMETHODIMP imgContainer::RemoveFrame(gfxIImageFrame *item) { + /* Remember to decrement mNumFrames if you implement this */ return NS_ERROR_NOT_IMPLEMENTED; } @@ -253,7 +345,7 @@ NS_IMETHODIMP imgContainer::DecodingComplete(void) mAnim->doneDecoding = PR_TRUE; // If there's only 1 frame, optimize it. // Optimizing animated images is not supported - if (mFrames.Count() == 1) + if (mNumFrames == 1) mFrames[0]->SetMutable(PR_FALSE); return NS_OK; } @@ -292,11 +384,11 @@ NS_IMETHODIMP imgContainer::SetAnimationMode(PRUint16 aAnimationMode) break; case kNormalAnimMode: if (mLoopCount != 0 || - (mAnim && (mAnim->currentAnimationFrameIndex + 1 < mFrames.Count()))) + (mAnim && (mAnim->currentAnimationFrameIndex + 1 < mNumFrames))) StartAnimation(); break; case kLoopOnceAnimMode: - if (mAnim && (mAnim->currentAnimationFrameIndex + 1 < mFrames.Count())) + if (mAnim && (mAnim->currentAnimationFrameIndex + 1 < mNumFrames)) StartAnimation(); break; } @@ -312,12 +404,18 @@ NS_IMETHODIMP imgContainer::StartAnimation() (mAnim && (mAnim->timer || mAnim->animating))) return NS_OK; - if (mFrames.Count() > 1) { + if (mNumFrames > 1) { if (!ensureAnimExists()) return NS_ERROR_OUT_OF_MEMORY; PRInt32 timeout; - gfxIImageFrame *currentFrame = inlinedGetCurrentFrame(); + nsresult result; + gfxIImageFrame *currentFrame; + + result = GetCurrentFrameNoRef (¤tFrame); + if (NS_FAILED (result)) + return result; + if (currentFrame) { currentFrame->GetTimeout(&timeout); if (timeout <= 0) // -1 means display this frame forever @@ -376,8 +474,15 @@ NS_IMETHODIMP imgContainer::ResetAnimation() mAnim->currentAnimationFrameIndex = 0; // Update display nsCOMPtr observer(do_QueryReferent(mObserver)); - if (observer) + if (observer) { + nsresult result; + + result = RestoreDiscardedData (); + if (NS_FAILED (result)) + return result; + observer->FrameChanged(this, mFrames[0], &(mAnim->firstFrameRefreshArea)); + } if (oldAnimating) return StartAnimation(); @@ -411,10 +516,150 @@ NS_IMETHODIMP imgContainer::SetLoopCount(PRInt32 aLoopCount) return NS_OK; } +static PRBool +DiscardingEnabled(void) +{ + static PRBool inited; + static PRBool enabled; + + if (!inited) { + inited = PR_TRUE; + + enabled = (PR_GetEnv("MOZ_DISABLE_IMAGE_DISCARD") == nsnull); + } + + return enabled; +} + +//****************************************************************************** +/* void setDiscardable(in string mime_type); */ +NS_IMETHODIMP imgContainer::SetDiscardable(const char* aMimeType) +{ + NS_ASSERTION(aMimeType, "imgContainer::SetDiscardable() called with null aMimeType"); + + if (!DiscardingEnabled()) + return NS_OK; + + if (mDiscardable) { + NS_WARNING ("imgContainer::SetDiscardable(): cannot change an imgContainer which is already discardable"); + return NS_ERROR_FAILURE; + } + + mDiscardableMimeType.Assign(aMimeType); + mDiscardable = PR_TRUE; + + num_containers_with_discardable_data++; + PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG, + ("CompressedImageAccounting: Making imgContainer %p (%s) discardable. " + "Compressed containers: %d, Compressed data bytes: %lld", + this, + aMimeType, + num_containers_with_discardable_data, + num_compressed_image_bytes)); + + return NS_OK; +} + +//****************************************************************************** +/* void addRestoreData(in nsIInputStream aInputStream, in unsigned long aCount); */ +NS_IMETHODIMP imgContainer::AddRestoreData(const char *aBuffer, PRUint32 aCount) +{ + NS_ASSERTION(aBuffer, "imgContainer::AddRestoreData() called with null aBuffer"); + + if (!DiscardingEnabled ()) + return NS_OK; + + if (!mDiscardable) { + NS_WARNING ("imgContainer::AddRestoreData() can only be called if SetDiscardable is called first"); + return NS_ERROR_FAILURE; + } + + if (mRestoreDataDone) { + /* We are being called from the decoder while the data is being restored + * (i.e. we were fully loaded once, then we discarded the image data, then + * we are being restored). We don't want to save the compressed data again, + * since we already have it. + */ + return NS_OK; + } + + if (!mRestoreData.AppendElements(aBuffer, aCount)) + return NS_ERROR_OUT_OF_MEMORY; + + num_compressed_image_bytes += aCount; + + PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG, + ("CompressedImageAccounting: Added compressed data to imgContainer %p (%s). " + "Compressed containers: %d, Compressed data bytes: %lld", + this, + mDiscardableMimeType.get(), + num_containers_with_discardable_data, + num_compressed_image_bytes)); + + return NS_OK; +} + +/* Note! buf must be declared as char buf[9]; */ +// just used for logging and hashing the header +static void +get_header_str (char *buf, char *data, PRSize data_len) +{ + int i; + int n; + static char hex[] = "0123456789abcdef"; + + n = data_len < 4 ? data_len : 4; + + for (i = 0; i < n; i++) { + buf[i * 2] = hex[(data[i] >> 4) & 0x0f]; + buf[i * 2 + 1] = hex[data[i] & 0x0f]; + } + + buf[i * 2] = 0; +} + +//****************************************************************************** +/* void restoreDataDone(); */ +NS_IMETHODIMP imgContainer::RestoreDataDone (void) +{ + + if (!DiscardingEnabled ()) + return NS_OK; + + if (mRestoreDataDone) + return NS_OK; + + mRestoreData.Compact(); + + mRestoreDataDone = PR_TRUE; + + if (PR_LOG_TEST(gCompressedImageAccountingLog, PR_LOG_DEBUG)) { + char buf[9]; + get_header_str(buf, mRestoreData.Elements(), mRestoreData.Length()); + PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG, + ("CompressedImageAccounting: imgContainer::RestoreDataDone() - data is done for container %p (%s), %d real frames (cached as %d frames) - header %p is 0x%s (length %d)", + this, + mDiscardableMimeType.get(), + mFrames.Count (), + mNumFrames, + mRestoreData.Elements(), + buf, + mRestoreData.Length())); + } + + return ResetDiscardTimer(); +} + //****************************************************************************** /* void notify(in nsITimer timer); */ NS_IMETHODIMP imgContainer::Notify(nsITimer *timer) { + nsresult result; + + result = RestoreDiscardedData(); + if (NS_FAILED (result)) + return result; + // This should never happen since the timer is only set up in StartAnimation() // after mAnim is checked to exist. NS_ASSERTION(mAnim, "imgContainer::Notify() called but mAnim is null"); @@ -433,8 +678,7 @@ NS_IMETHODIMP imgContainer::Notify(nsITimer *timer) return NS_OK; } - PRInt32 numFrames = mFrames.Count(); - if (!numFrames) + if (mNumFrames == 0) return NS_OK; gfxIImageFrame *nextFrame = nsnull; @@ -448,7 +692,7 @@ NS_IMETHODIMP imgContainer::Notify(nsITimer *timer) // finished decoding (see EndFrameDecode) if (mAnim->doneDecoding || (nextFrameIndex < mAnim->currentDecodingFrameIndex)) { - if (numFrames == nextFrameIndex) { + if (mNumFrames == nextFrameIndex) { // End of Animation // If animation mode is "loop once", it's time to stop animating @@ -699,7 +943,7 @@ nsresult imgContainer::DoComposite(gfxIImageFrame** aFrameToUse, } // Check if the frame we are composing wants the previous image restored afer - // it is done. Don't store it (again) if last frame wanted it's image restored + // it is done. Don't store it (again) if last frame wanted its image restored // too if ((nextFrameDisposalMethod == imgIContainer::kDisposeRestorePrevious) && (prevFrameDisposalMethod != imgIContainer::kDisposeRestorePrevious)) { @@ -845,7 +1089,19 @@ nsresult imgContainer::DrawFrameTo(gfxIImageFrame *aSrc, dstImg->GetSurface(getter_AddRefs(dstSurf)); gfxContext dst(dstSurf); + + // first clear the surface if the blend flag says so + PRInt32 blendMethod; + aSrc->GetBlendMethod(&blendMethod); + gfxContext::GraphicsOperator defaultOperator = dst.CurrentOperator(); + if (blendMethod == imgIContainer::kBlendSource) { + dst.SetOperator(gfxContext::OPERATOR_CLEAR); + dst.Rectangle(gfxRect(aDstRect.x, aDstRect.y, aDstRect.width, aDstRect.height)); + dst.Fill(); + } + dst.NewPath(); + dst.SetOperator(defaultOperator); // We don't use PixelSnappedRectangleAndSetPattern because if // these coords aren't already pixel aligned, we've lost // before we've even begun. @@ -906,3 +1162,308 @@ NS_IMETHODIMP imgContainer::GetKeys(PRUint32 *count, char ***keys) } return mProperties->GetKeys(count, keys); } + +static int +get_discard_timer_ms (void) +{ + /* FIXME: don't hardcode this */ + return 45000; /* 45 seconds */ +} + +void +imgContainer::sDiscardTimerCallback(nsITimer *aTimer, void *aClosure) +{ + imgContainer *self = (imgContainer *) aClosure; + int old_frame_count; + + NS_ASSERTION(aTimer == self->mDiscardTimer, + "imgContainer::DiscardTimerCallback() got a callback for an unknown timer"); + + self->mDiscardTimer = nsnull; + + old_frame_count = self->mFrames.Count(); + + if (self->mAnim) { + delete self->mAnim; + self->mAnim = nsnull; + } + + self->mFrames.Clear(); + + self->mDiscarded = PR_TRUE; + + PR_LOG(gCompressedImageAccountingLog, PR_LOG_DEBUG, + ("CompressedImageAccounting: discarded uncompressed image data from imgContainer %p (%s) - %d frames (cached count: %d); " + "Compressed containers: %d, Compressed data bytes: %lld", + self, + self->mDiscardableMimeType.get(), + old_frame_count, + self->mNumFrames, + num_containers_with_discardable_data, + num_compressed_image_bytes)); +} + +nsresult +imgContainer::ResetDiscardTimer (void) +{ + if (!DiscardingEnabled()) + return NS_OK; + + if (!mDiscardTimer) { + mDiscardTimer = do_CreateInstance("@mozilla.org/timer;1"); + + if (!mDiscardTimer) + return NS_ERROR_OUT_OF_MEMORY; + } else { + if (NS_FAILED(mDiscardTimer->Cancel())) + return NS_ERROR_FAILURE; + } + + return mDiscardTimer->InitWithFuncCallback(sDiscardTimerCallback, + (void *) this, + get_discard_timer_ms (), + nsITimer::TYPE_ONE_SHOT); +} + +nsresult +imgContainer::RestoreDiscardedData(void) +{ + nsresult result; + int num_expected_frames; + + if (!mDiscardable) + return NS_OK; + + result = ResetDiscardTimer(); + if (NS_FAILED (result)) + return result; + + if (!mDiscarded) + return NS_OK; + + num_expected_frames = mNumFrames; + + result = ReloadImages (); + if (NS_FAILED (result)) { + PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG, + ("CompressedImageAccounting: imgContainer::RestoreDiscardedData() for container %p failed to ReloadImages()", + this)); + return result; + } + + mDiscarded = PR_FALSE; + + NS_ASSERTION (mNumFrames == mFrames.Count(), + "number of restored image frames doesn't match"); + NS_ASSERTION (num_expected_frames == mNumFrames, + "number of restored image frames doesn't match the original number of frames!"); + + PR_LOG (gCompressedImageAccountingLog, PR_LOG_DEBUG, + ("CompressedImageAccounting: imgContainer::RestoreDiscardedData() restored discarded data " + "for imgContainer %p (%s) - %d image frames. " + "Compressed containers: %d, Compressed data bytes: %lld", + this, + mDiscardableMimeType.get(), + mNumFrames, + num_containers_with_discardable_data, + num_compressed_image_bytes)); + + return NS_OK; +} + +class ContainerLoader : public imgILoad, + public imgIDecoderObserver, + public nsSupportsWeakReference +{ +public: + + NS_DECL_ISUPPORTS + NS_DECL_IMGILOAD + NS_DECL_IMGIDECODEROBSERVER + NS_DECL_IMGICONTAINEROBSERVER + + ContainerLoader(void); + +private: + + imgIContainer *mContainer; +}; + +NS_IMPL_ISUPPORTS4 (ContainerLoader, imgILoad, imgIDecoderObserver, imgIContainerObserver, nsISupportsWeakReference) + +ContainerLoader::ContainerLoader (void) +{ +} + +/* Implement imgILoad::image getter */ +NS_IMETHODIMP +ContainerLoader::GetImage(imgIContainer **aImage) +{ + *aImage = mContainer; + NS_IF_ADDREF (*aImage); + return NS_OK; +} + +/* Implement imgILoad::image setter */ +NS_IMETHODIMP +ContainerLoader::SetImage(imgIContainer *aImage) +{ + mContainer = aImage; + return NS_OK; +} + +/* Implement imgILoad::isMultiPartChannel getter */ +NS_IMETHODIMP +ContainerLoader::GetIsMultiPartChannel(PRBool *aIsMultiPartChannel) +{ + *aIsMultiPartChannel = PR_FALSE; /* FIXME: is this always right? */ + return NS_OK; +} + +/* Implement imgIDecoderObserver::onStartRequest() */ +NS_IMETHODIMP +ContainerLoader::OnStartRequest(imgIRequest *aRequest) +{ + return NS_OK; +} + +/* Implement imgIDecoderObserver::onStartDecode() */ +NS_IMETHODIMP +ContainerLoader::OnStartDecode(imgIRequest *aRequest) +{ + return NS_OK; +} + +/* Implement imgIDecoderObserver::onStartContainer() */ +NS_IMETHODIMP +ContainerLoader::OnStartContainer(imgIRequest *aRequest, imgIContainer *aContainer) +{ + return NS_OK; +} + +/* Implement imgIDecoderObserver::onStartFrame() */ +NS_IMETHODIMP +ContainerLoader::OnStartFrame(imgIRequest *aRequest, gfxIImageFrame *aFrame) +{ + return NS_OK; +} + +/* Implement imgIDecoderObserver::onDataAvailable() */ +NS_IMETHODIMP +ContainerLoader::OnDataAvailable(imgIRequest *aRequest, gfxIImageFrame *aFrame, const nsIntRect * aRect) +{ + return NS_OK; +} + +/* Implement imgIDecoderObserver::onStopFrame() */ +NS_IMETHODIMP +ContainerLoader::OnStopFrame(imgIRequest *aRequest, gfxIImageFrame *aFrame) +{ + return NS_OK; +} + +/* Implement imgIDecoderObserver::onStopContainer() */ +NS_IMETHODIMP +ContainerLoader::OnStopContainer(imgIRequest *aRequest, imgIContainer *aContainer) +{ + return NS_OK; +} + +/* Implement imgIDecoderObserver::onStopDecode() */ +NS_IMETHODIMP +ContainerLoader::OnStopDecode(imgIRequest *aRequest, nsresult status, const PRUnichar *statusArg) +{ + return NS_OK; +} + +/* Implement imgIDecoderObserver::onStopRequest() */ +NS_IMETHODIMP +ContainerLoader::OnStopRequest(imgIRequest *aRequest, PRBool aIsLastPart) +{ + return NS_OK; +} + +/* implement imgIContainerObserver::frameChanged() */ +NS_IMETHODIMP +ContainerLoader::FrameChanged(imgIContainer *aContainer, gfxIImageFrame *aFrame, nsIntRect * aDirtyRect) +{ + return NS_OK; +} + +nsresult +imgContainer::ReloadImages(void) +{ + nsresult result = NS_ERROR_FAILURE; + nsCOMPtr stream; + + NS_ASSERTION(!mRestoreData.IsEmpty(), + "imgContainer::ReloadImages(): mRestoreData should not be empty"); + NS_ASSERTION(mRestoreDataDone, + "imgContainer::ReloadImages(): mRestoreDataDone shoudl be true!"); + + mNumFrames = 0; + NS_ASSERTION(mFrames.Count() == 0, + "imgContainer::ReloadImages(): mFrames should be empty"); + + nsCAutoString decoderCID(NS_LITERAL_CSTRING("@mozilla.org/image/decoder;2?type=") + mDiscardableMimeType); + + nsCOMPtr decoder = do_CreateInstance(decoderCID.get()); + if (!decoder) { + PR_LOG(gCompressedImageAccountingLog, PR_LOG_WARNING, + ("CompressedImageAccounting: imgContainer::ReloadImages() could not create decoder for %s", + mDiscardableMimeType.get())); + return NS_IMAGELIB_ERROR_NO_DECODER; + } + + nsCOMPtr loader = new ContainerLoader(); + if (!loader) { + PR_LOG(gCompressedImageAccountingLog, PR_LOG_WARNING, + ("CompressedImageAccounting: imgContainer::ReloadImages() could not allocate ContainerLoader " + "when reloading the images for container %p", + this)); + return NS_ERROR_OUT_OF_MEMORY; + } + + loader->SetImage(this); + + result = decoder->Init(loader); + if (NS_FAILED(result)) { + PR_LOG(gCompressedImageAccountingLog, PR_LOG_WARNING, + ("CompressedImageAccounting: imgContainer::ReloadImages() image container %p " + "failed to initialize the decoder (%s)", + this, + mDiscardableMimeType.get())); + return result; + } + + result = NS_NewByteInputStream(getter_AddRefs(stream), mRestoreData.Elements(), mRestoreData.Length(), NS_ASSIGNMENT_DEPEND); + NS_ENSURE_SUCCESS(result, result); + + if (PR_LOG_TEST(gCompressedImageAccountingLog, PR_LOG_DEBUG)) { + char buf[9]; + get_header_str(buf, mRestoreData.Elements(), mRestoreData.Length()); + PR_LOG(gCompressedImageAccountingLog, PR_LOG_WARNING, + ("CompressedImageAccounting: imgContainer::ReloadImages() starting to restore images for container %p (%s) - " + "header %p is 0x%s (length %d)", + this, + mDiscardableMimeType.get(), + mRestoreData.Elements(), + buf, + mRestoreData.Length())); + } + + PRUint32 written; + result = decoder->WriteFrom(stream, mRestoreData.Length(), &written); + NS_ENSURE_SUCCESS(result, result); + + if (NS_FAILED(decoder->Flush())) + return result; + + result = decoder->Close(); + NS_ENSURE_SUCCESS(result, result); + + NS_ASSERTION(mFrames.Count() == mNumFrames, + "imgContainer::ReloadImages(): the restored mFrames.Count() doesn't match mNumFrames!"); + + return result; +} diff --git a/modules/libpr0n/src/imgContainer.h b/modules/libpr0n/src/imgContainer.h index 379da52f634b..53e532d8ea1d 100644 --- a/modules/libpr0n/src/imgContainer.h +++ b/modules/libpr0n/src/imgContainer.h @@ -23,6 +23,7 @@ * Contributor(s): * Stuart Parmenter * Chris Saari + * Federico Mena-Quintero * * 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 @@ -58,6 +59,7 @@ #include "nsIProperties.h" #include "nsITimer.h" #include "nsWeakReference.h" +#include "nsTArray.h" #define NS_IMGCONTAINER_CID \ { /* 27f0682c-ff64-4dd2-ae7a-668e59f2fd38 */ \ @@ -192,14 +194,8 @@ private: timer->Cancel(); } }; - - inline gfxIImageFrame* inlinedGetCurrentFrame() { - if (!mAnim) - return mFrames.SafeObjectAt(0); - if (mAnim->lastCompositedFrameIndex == mAnim->currentAnimationFrameIndex) - return mAnim->compositingFrame; - return mFrames.SafeObjectAt(mAnim->currentAnimationFrameIndex); - } + + nsresult GetCurrentFrameNoRef(gfxIImageFrame** aFrame); inline Anim* ensureAnimExists() { if (!mAnim) @@ -283,10 +279,15 @@ private: nsIntSize mSize; //! All the s of the PNG + // *** IMPORTANT: if you use mFrames in a method, call RestoreDiscardedData() first to ensure + // that the frames actually exist (they may have been discarded to save memory). nsCOMArray mFrames; + int mNumFrames; /* stored separately from mFrames.Count() to support discarded images */ nsCOMPtr mProperties; - + + // *** IMPORTANT: if you use mAnim in a method, call RestoreDiscardedData() first to ensure + // that the frames actually exist (they may have been discarded to save memory). imgContainer::Anim* mAnim; //! See imgIContainer for mode constants @@ -297,6 +298,19 @@ private: //! imgIContainerObserver nsWeakPtr mObserver; + + PRBool mDiscardable; + PRBool mDiscarded; + nsCString mDiscardableMimeType; + + nsTArray mRestoreData; + PRBool mRestoreDataDone; + nsCOMPtr mDiscardTimer; + + nsresult ResetDiscardTimer (void); + nsresult RestoreDiscardedData (void); + nsresult ReloadImages (void); + static void sDiscardTimerCallback (nsITimer *aTimer, void *aClosure); }; #endif /* __imgContainer_h__ */ diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index 9f454e0d6962..1b71396eb3fb 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -2472,3 +2472,8 @@ pref("signon.SignonFileName", "signons.txt"); // obsolete pref("signon.SignonFileName2", "signons2.txt"); pref("signon.autofillForms", true); pref("signon.debug", false); // logs to Error Console + +// Zoom prefs +pref("fullZoom.minPercent", 50); +pref("fullZoom.maxPercent", 300); +pref("toolkit.zoomManager.fullZoomValues", ".5,.75,1,1.25,1.5,2,3"); diff --git a/modules/plugin/base/src/nsJSNPRuntime.cpp b/modules/plugin/base/src/nsJSNPRuntime.cpp index 74638f217369..b6155aa6f25c 100644 --- a/modules/plugin/base/src/nsJSNPRuntime.cpp +++ b/modules/plugin/base/src/nsJSNPRuntime.cpp @@ -680,6 +680,7 @@ nsJSObjWrapper::NP_HasProperty(NPObject *npobj, NPIdentifier identifier) jsval id = (jsval)identifier; JSBool found, ok = JS_FALSE; + AutoCXPusher pusher(cx); JSAutoRequest ar(cx); if (JSVAL_IS_STRING(id)) { diff --git a/netwerk/base/public/nsINSSErrorsService.idl b/netwerk/base/public/nsINSSErrorsService.idl index 05f0d44d3fc5..871bade60d74 100644 --- a/netwerk/base/public/nsINSSErrorsService.idl +++ b/netwerk/base/public/nsINSSErrorsService.idl @@ -39,7 +39,7 @@ #include "nsISupports.idl" -[scriptable, uuid(c6ac6e5d-9db1-4cad-bedc-e2d226913c21)] +[scriptable, uuid(3a5c7a0f-f5da-4a8b-a748-d7c5a528f33b)] interface nsINSSErrorsService : nsISupports { /** @@ -61,4 +61,14 @@ interface nsINSSErrorsService : nsISupports * return A localized human readable error explanation. */ AString getErrorMessage(in nsresult aXPCOMErrorCode); + + /** + * Function will fail if aXPCOMErrorCode is not an NSS error code. + * @param aXPCOMErrorCode An error code obtain using getXPCOMFromNSSError + * return the + */ + PRUint32 getErrorClass(in nsresult aXPCOMErrorCode); + + const unsigned long ERROR_CLASS_SSL_PROTOCOL = 1; + const unsigned long ERROR_CLASS_BAD_CERT = 2; }; diff --git a/netwerk/base/public/nsNetError.h b/netwerk/base/public/nsNetError.h index 1a4c06705968..65b15348866b 100644 --- a/netwerk/base/public/nsNetError.h +++ b/netwerk/base/public/nsNetError.h @@ -330,4 +330,21 @@ NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 70) +/****************************************************************************** + * Effective TLD Service specific error codes: + */ + +/** + * The requested number of domain levels exceeds those present in the host string. + */ +#define NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 80) + +/** + * The host string is an IP address. + */ +#define NS_ERROR_HOST_IS_IP_ADDRESS \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_NETWORK, 81) + + #endif // !nsNetError_h__ diff --git a/netwerk/base/public/nsNetUtil.h b/netwerk/base/public/nsNetUtil.h index ce786fe4bced..5a159b53f71d 100644 --- a/netwerk/base/public/nsNetUtil.h +++ b/netwerk/base/public/nsNetUtil.h @@ -1304,4 +1304,26 @@ NS_GetInnermostURI(nsIURI *uri) return uri; } +/** + * Get the "final" URI for a channel. This is either the same as GetURI or + * GetOriginalURI, depending on whether this channel has + * nsIChanel::LOAD_REPLACE set. For channels without that flag set, the final + * URI is the original URI, while for ones with the flag the final URI is the + * channel URI. + */ +inline nsresult +NS_GetFinalChannelURI(nsIChannel* channel, nsIURI** uri) +{ + *uri = nsnull; + nsLoadFlags loadFlags = 0; + nsresult rv = channel->GetLoadFlags(&loadFlags); + NS_ENSURE_SUCCESS(rv, rv); + + if (loadFlags & nsIChannel::LOAD_REPLACE) { + return channel->GetURI(uri); + } + + return channel->GetOriginalURI(uri); +} + #endif // !nsNetUtil_h__ diff --git a/netwerk/dns/public/nsIEffectiveTLDService.idl b/netwerk/dns/public/nsIEffectiveTLDService.idl index cd48f0460929..cced0a3b0e88 100644 --- a/netwerk/dns/public/nsIEffectiveTLDService.idl +++ b/netwerk/dns/public/nsIEffectiveTLDService.idl @@ -21,6 +21,7 @@ * * Contributor(s): * Pamela Greene (original author) + * Daniel Witte * * 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 @@ -38,36 +39,84 @@ #include "nsISupports.idl" -[scriptable, uuid(4b8cdd85-e186-46e5-9ec0-9488ae7f0b92)] +interface nsIURI; + +[scriptable, uuid(b07cb0f0-3394-572e-6260-dbaed0a292ba)] interface nsIEffectiveTLDService : nsISupports { /** - * getEffectiveTLDLength + * Returns the public suffix of a URI. A public suffix is the highest-level domain + * under which individual domains may be registered; it may therefore contain one + * or more dots. For example, the public suffix for "www.bbc.co.uk" is "co.uk", + * because the .uk TLD does not allow the registration of domains at the + * second level ("bbc.uk" is forbidden). * - * Finds the length of the effective TLD of a hostname. An effective TLD - * is the highest-level domain under which individual domains may be - * registered; it may therefore contain one or more dots. For example, - * the effective TLD for "www.bbc.co.uk" is "co.uk", because the .uk TLD - * does not allow the registration of domains at the second level ("bbc.uk" - * is forbidden). Similarly, the effective TLD of "developer.mozilla.com" - * is "com". + * The public suffix will be returned encoded in UTF8 and will be normalized using + * nsIIDNService::normalize, which follows RFC 3454. * - * The hostname will be normalized using nsIIDNService::normalize, which - * follows RFC 3454. getEffectiveTLDLength() will fail, generating an - * error, if the hostname contains characters that are invalid in URIs. + * @param aURI The URI to be analyzed * - * @param aHostname The hostname to be analyzed, in UTF-8 - * - * @returns the number of bytes that the longest identified effective TLD - * (TLD or TLD-like higher-level subdomain) occupies, not including - * the leading dot: - * bugzilla.mozilla.org -> org -> 3 - * theregister.co.uk -> co.uk -> 5 - * mysite.us -> us -> 2 + * @returns the public suffix * * @throws NS_ERROR_UNEXPECTED * or other error returned by nsIIDNService::normalize when - * aHostname is not UTF-8 or contains characters disallowed in URIs + * the hostname contains characters disallowed in URIs + * @throws NS_ERROR_HOST_IS_IP_ADDRESS + * if the host is a numeric IPv4 or IPv6 address (as determined by + * the success of a call to PR_StringToNetAddr()). */ - PRUint32 getEffectiveTLDLength(in AUTF8String aHostname); + AUTF8String getPublicSuffix(in nsIURI aURI); + + /** + * Returns the base domain of a URI; that is, the public suffix with a given + * number of additional domain name parts. For example, the result of this method + * for "www.bbc.co.uk", depending on the value of aAdditionalParts parameter, will + * be: + * + * 0 (default) -> bbc.co.uk + * 1 -> news.bbc.co.uk + * + * Similarly, the public suffix for "developer.mozilla.org" is "org", and the base + * domain will be: + * + * 0 (default) -> mozilla.org + * 1 -> developer.mozilla.org + * + * The base domain will be returned encoded in UTF8 and will be normalized using + * nsIIDNService::normalize, which follows RFC 3454. + * + * @param aURI The URI to be analyzed + * @param aAdditionalParts Number of domain name parts to be + * returned in addition to the public suffix + * + * @returns the base domain (public suffix plus the requested number of additional parts) + * + * @throws NS_ERROR_UNEXPECTED + * or other error returned by nsIIDNService::normalize when + * the hostname contains characters disallowed in URIs + * @throws NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS + * when there are insufficient subdomain levels in the hostname to satisfy the + * requested aAdditionalParts value. + * @throws NS_ERROR_HOST_IS_IP_ADDRESS + * if aHost is a numeric IPv4 or IPv6 address (as determined by + * the success of a call to PR_StringToNetAddr()). + * + * @see getPublicSuffix() + */ + AUTF8String getBaseDomain(in nsIURI aURI, [optional] in PRUint32 aAdditionalParts); + + /** + * Returns the public suffix of a host string. Otherwise identical to getPublicSuffix(). + * + * @see getPublicSuffix() + */ + AUTF8String getPublicSuffixFromHost(in AUTF8String aHost); + + /** + * Returns the base domain of a host string. Otherwise identical to getBaseDomain(). + * + * @see getBaseDomain() + */ + AUTF8String getBaseDomainFromHost(in AUTF8String aHost, [optional] in PRUint32 aAdditionalParts); }; + diff --git a/netwerk/dns/src/nsEffectiveTLDService.cpp b/netwerk/dns/src/nsEffectiveTLDService.cpp index 140087aaa387..08e87d1a257b 100644 --- a/netwerk/dns/src/nsEffectiveTLDService.cpp +++ b/netwerk/dns/src/nsEffectiveTLDService.cpp @@ -49,6 +49,7 @@ #include "nsIFile.h" #include "nsIIDNService.h" #include "nsNetUtil.h" +#include "prnetdb.h" // The file name of the list of TLD-like names. A file with this name in the // system "res" directory will always be used. In addition, if a file with @@ -96,6 +97,10 @@ nsEffectiveTLDService::Init() if (!mHash.Init()) return NS_ERROR_OUT_OF_MEMORY; + nsresult rv; + mIDNService = do_GetService(NS_IDNSERVICE_CONTRACTID, &rv); + if (NS_FAILED(rv)) return rv; + return LoadEffectiveTLDFiles(); } @@ -112,27 +117,94 @@ nsEffectiveTLDService::~nsEffectiveTLDService() gArena = nsnull; } -// nsEffectiveTLDService::getEffectiveTLDLength -// -// The main external function: finds the length in bytes of the effective TLD -// for the given hostname. This will fail, generating an error, if the -// hostname is not UTF-8 or includes characters that are not valid in a URL. +// External function for dealing with URI's correctly. +// Pulls out the host portion from an nsIURI, and calls through to +// GetPublicSuffixFromHost(). NS_IMETHODIMP -nsEffectiveTLDService::GetEffectiveTLDLength(const nsACString &aHostname, - PRUint32 *effTLDLength) +nsEffectiveTLDService::GetPublicSuffix(nsIURI *aURI, + nsACString &aPublicSuffix) { - // Create a mutable copy of the hostname and normalize it. This will fail - // if the hostname includes invalid characters. + NS_ENSURE_ARG_POINTER(aURI); + + nsCOMPtr innerURI = NS_GetInnermostURI(aURI); + NS_ENSURE_ARG_POINTER(innerURI); + + nsCAutoString host; + innerURI->GetHost(host); + + return GetBaseDomainInternal(host, 0, aPublicSuffix); +} + +// External function for dealing with URI's correctly. +// Pulls out the host portion from an nsIURI, and calls through to +// GetBaseDomainFromHost(). +NS_IMETHODIMP +nsEffectiveTLDService::GetBaseDomain(nsIURI *aURI, + PRUint32 aAdditionalParts, + nsACString &aBaseDomain) +{ + NS_ENSURE_ARG_POINTER(aURI); + + nsCOMPtr innerURI = NS_GetInnermostURI(aURI); + NS_ENSURE_ARG_POINTER(innerURI); + + nsCAutoString host; + innerURI->GetHost(host); + + return GetBaseDomainInternal(host, aAdditionalParts + 1, aBaseDomain); +} + +// External function for dealing with a host string directly: finds the public +// suffix (e.g. co.uk) for the given hostname. See GetBaseDomainInternal(). +NS_IMETHODIMP +nsEffectiveTLDService::GetPublicSuffixFromHost(const nsACString &aHostname, + nsACString &aPublicSuffix) +{ + return GetBaseDomainInternal(aHostname, 0, aPublicSuffix); +} + +// External function for dealing with a host string directly: finds the base +// domain (e.g. www.co.uk) for the given hostname and number of subdomain parts +// requested. See GetBaseDomainInternal(). +NS_IMETHODIMP +nsEffectiveTLDService::GetBaseDomainFromHost(const nsACString &aHostname, + PRUint32 aAdditionalParts, + nsACString &aBaseDomain) +{ + return GetBaseDomainInternal(aHostname, aAdditionalParts + 1, aBaseDomain); +} + +// Finds the base domain for a host, with requested number of additional parts. +// This will fail, generating an error, if the host is an IPv4/IPv6 address, +// if more subdomain parts are requested than are available, or if the hostname +// includes characters that are not valid in a URL. Normalization is performed +// on the host string and the result will be in UTF8. +nsresult +nsEffectiveTLDService::GetBaseDomainInternal(const nsACString &aHostname, + PRUint32 aAdditionalParts, + nsACString &aBaseDomain) +{ + if (aHostname.IsEmpty()) + return NS_ERROR_INVALID_ARG; + + // Create a mutable copy of the hostname and normalize it to UTF8. + // This will fail if the hostname includes invalid characters. nsCAutoString normHostname(aHostname); nsresult rv = NormalizeHostname(normHostname); if (NS_FAILED(rv)) return rv; - // chomp any trailing dot, and remember to add it back later - PRUint32 trailingDot = normHostname.Last() == '.'; + // chomp any trailing dot, and keep track of it for later + PRBool trailingDot = normHostname.Last() == '.'; if (trailingDot) normHostname.Truncate(normHostname.Length() - 1); + // Check if we're dealing with an IPv4/IPv6 hostname, and return + PRNetAddr addr; + PRStatus result = PR_StringToNetAddr(normHostname.get(), &addr); + if (result == PR_SUCCESS) + return NS_ERROR_HOST_IS_IP_ADDRESS; + // walk up the domain tree, most specific to least specific, // looking for matches at each level. note that a given level may // have multiple attributes (e.g. IsWild() and IsNormal()). @@ -140,29 +212,30 @@ nsEffectiveTLDService::GetEffectiveTLDLength(const nsACString &aHostname, const char *currDomain = normHostname.get(); const char *nextDot = strchr(currDomain, '.'); const char *end = currDomain + normHostname.Length(); + const char *eTLD = currDomain; while (1) { nsDomainEntry *entry = mHash.GetEntry(currDomain); if (entry) { if (entry->IsWild() && prevDomain) { // wildcard rules imply an eTLD one level inferior to the match. - *effTLDLength = end - prevDomain; + eTLD = prevDomain; break; } else if (entry->IsNormal() || !nextDot) { // specific match, or we've hit the top domain level - *effTLDLength = end - currDomain; + eTLD = currDomain; break; } else if (entry->IsException()) { // exception rules imply an eTLD one level superior to the match. - *effTLDLength = end - nextDot - 1; + eTLD = nextDot + 1; break; } } if (!nextDot) { - // we've hit the top domain level; return it by default. - *effTLDLength = end - currDomain; + // we've hit the top domain level; use it by default. + eTLD = currDomain; break; } @@ -171,38 +244,52 @@ nsEffectiveTLDService::GetEffectiveTLDLength(const nsACString &aHostname, nextDot = strchr(currDomain, '.'); } + // count off the number of requested domains. + const char *begin = normHostname.get(); + const char *iter = eTLD; + while (1) { + if (iter == begin) + break; + + if (*(--iter) == '.' && aAdditionalParts-- == 0) { + ++iter; + ++aAdditionalParts; + break; + } + } + + if (aAdditionalParts != 0) + return NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS; + + aBaseDomain = Substring(iter, end); // add on the trailing dot, if applicable - *effTLDLength += trailingDot; + if (trailingDot) + aBaseDomain.Append('.'); return NS_OK; } -// NormalizeHostname -// -// Normalizes characters of hostname. ASCII names are lower-cased, and names -// using other characters are normalized with nsIIDNService::Normalize, which -// follows RFC 3454. +// Normalizes characters of hostname. ASCII names are lower-cased, UTF8 names +// are normalized with nsIIDNService::Normalize which follows RFC 3454, and +// ACE names are converted to UTF8 and normalized as above. nsresult nsEffectiveTLDService::NormalizeHostname(nsCString &aHostname) { if (IsASCII(aHostname)) { - ToLowerCase(aHostname); - return NS_OK; - } + PRBool isACE; + if (NS_FAILED(mIDNService->IsACE(aHostname, &isACE)) || !isACE) { + ToLowerCase(aHostname); + return NS_OK; + } - if (!mIDNService) { - nsresult rv; - mIDNService = do_GetService(NS_IDNSERVICE_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); + nsresult rv = mIDNService->ConvertACEtoUTF8(aHostname, aHostname); + if (NS_FAILED(rv)) return rv; } return mIDNService->Normalize(aHostname, aHostname); } -// AddEffectiveTLDEntry -// // Adds the given domain name rule to the effective-TLD hash. -// // CAUTION: As a side effect, the domain name rule will be normalized. // see NormalizeHostname(). nsresult @@ -253,8 +340,6 @@ nsEffectiveTLDService::AddEffectiveTLDEntry(nsCString &aDomainName) return NS_OK; } -// LocateEffectiveTLDFile -// // Locates the effective-TLD file. If aUseProfile is true, uses the file from // the user's profile directory; otherwise uses the one from the system "res" // directory. Places nsnull in foundFile if the desired file was not found. @@ -314,8 +399,6 @@ TruncateAtWhitespace(nsCString &aString) } } -// LoadOneEffectiveTLDFile -// // Loads the contents of the given effective-TLD file, building the tree as it // goes. nsresult @@ -350,8 +433,6 @@ nsEffectiveTLDService::LoadOneEffectiveTLDFile(nsCOMPtr& effTLDFile) return NS_OK; } -// LoadEffectiveTLDFiles -// // Loads the contents of the system and user effective-TLD files. nsresult nsEffectiveTLDService::LoadEffectiveTLDFiles() diff --git a/netwerk/dns/src/nsEffectiveTLDService.h b/netwerk/dns/src/nsEffectiveTLDService.h index 07b60f78d2b1..359099ccb0b4 100644 --- a/netwerk/dns/src/nsEffectiveTLDService.h +++ b/netwerk/dns/src/nsEffectiveTLDService.h @@ -21,6 +21,7 @@ * * Contributor(s): * Pamela Greene (original author) + * Daniel Witte * * 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 @@ -111,6 +112,7 @@ public: nsresult Init(); private: + nsresult GetBaseDomainInternal(const nsACString &aHostname, PRUint32 aAdditionalParts, nsACString &aBaseDomain); nsresult NormalizeHostname(nsCString &aHostname); nsresult AddEffectiveTLDEntry(nsCString &aDomainName); nsresult LoadEffectiveTLDFiles(); diff --git a/netwerk/mime/public/nsIMIMEInfo.idl b/netwerk/mime/public/nsIMIMEInfo.idl index f4d94d7e29b8..cb6ba9252af8 100644 --- a/netwerk/mime/public/nsIMIMEInfo.idl +++ b/netwerk/mime/public/nsIMIMEInfo.idl @@ -43,6 +43,7 @@ interface nsIURI; interface nsIFile; interface nsIUTF8StringEnumerator; interface nsIHandlerApp; +interface nsIArray; interface nsIMutableArray; interface nsIInterfaceRequestor; @@ -113,12 +114,9 @@ interface nsIHandlerInfo : nsISupports { * * @param aWindowContext * The window to parent the dialog against, and, if a web handler - * is chosen, it is loaded in this window as well. This parameter - * may be ultimately passed nsIURILoader.openURI in the case of a - * web handler, and aWindowContext is null or not present, web - * handlers will fail. We need to do better than that; bug 394483 - * filed in order to track. - * + * is chosen, it is loaded in this window as well. See + * nsIHandlerApp.launchWithURI for more details. + * * @throw NS_ERROR_INVALID_ARG if preferredAction is not valid for this * call. Other exceptions may be thrown. */ @@ -159,7 +157,7 @@ interface nsIHandlerInfo : nsISupports { * MIMEInfo objects are generally retrieved from the MIME Service * @see nsIMIMEService */ -[scriptable, uuid(a4011016-81a1-47d9-b01e-19a2272ae89b)] +[scriptable, uuid(cd7083f8-5fe9-4248-bb09-0b0e2982fde8)] interface nsIMIMEInfo : nsIHandlerInfo { /** * Gives you an array of file types associated with this type. @@ -218,6 +216,17 @@ interface nsIMIMEInfo : nsIHandlerInfo { */ boolean equals(in nsIMIMEInfo aMIMEInfo); + /** + * Returns a list of nsILocalHandlerApp objects containing + * handlers associated with this mimeinfo. Implemented per + * platform using information in this object to generate the + * best list. Typically used for an "open with" style user + * option. + * + * @return nsIArray of nsILocalHandlerApp + */ + readonly attribute nsIArray possibleLocalHandlers; + /** * Launches the application with the specified file, in a way that * depends on the value of preferredAction. preferredAction must be @@ -267,9 +276,16 @@ interface nsIHandlerApp : nsISupports { * The URI to launch this application with * * @param aWindowContext - * Required for web handlers; is passed through to - * nsIURILoader.openURI, but see bug 394483 for info on - * how this needs to evolve. + * + * Currently only relevant to web-handler apps. If given, this + * represents the docshell to load the handler in and is passed + * through to nsIURILoader.openURI. If this parameter is null or + * not present, the web handler app implementation will attempt to + * find/create a place to load the handler and do so. As of this + * writing, it tries to load the web handler in a new window using + * nsIBrowserDOMWindow.openURI. In the future, it may attempt to + * have a more comprehensive strategy which could include handing + * off to the system default browser (bug 394479). */ void launchWithURI(in nsIURI aURI, [optional] in nsIInterfaceRequestor aWindowContext); diff --git a/netwerk/protocol/http/src/nsHttpHandler.cpp b/netwerk/protocol/http/src/nsHttpHandler.cpp index 1f18e33c47d7..9e108a11030a 100644 --- a/netwerk/protocol/http/src/nsHttpHandler.cpp +++ b/netwerk/protocol/http/src/nsHttpHandler.cpp @@ -85,6 +85,10 @@ #include #endif +#if defined(XP_MACOSX) +#include +#endif + #if defined(XP_OS2) #define INCL_DOSMISC #include @@ -688,10 +692,17 @@ nsHttpHandler::InitUserAgentComponents() } } } -#elif defined (XP_MACOSX) && defined(__ppc__) +#elif defined (XP_MACOSX) +#if defined(__ppc__) mOscpu.AssignLiteral("PPC Mac OS X Mach-O"); -#elif defined (XP_MACOSX) && defined(__i386__) +#elif defined(__i386__) mOscpu.AssignLiteral("Intel Mac OS X"); +#endif + long majorVersion, minorVersion; + if ((::Gestalt(gestaltSystemVersionMajor, &majorVersion) == noErr) && + (::Gestalt(gestaltSystemVersionMinor, &minorVersion) == noErr)) { + mOscpu += nsPrintfCString(" %ld.%ld", majorVersion, minorVersion); + } #elif defined (XP_UNIX) || defined (XP_BEOS) struct utsname name; diff --git a/netwerk/test/unit/test_bug368702.js b/netwerk/test/unit/test_bug368702.js index 34d732e1a615..5f35292d06cf 100644 --- a/netwerk/test/unit/test_bug368702.js +++ b/netwerk/test/unit/test_bug368702.js @@ -1,15 +1,83 @@ const Cc = Components.classes; const Ci = Components.interfaces; +const NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS = 0x804b0050; +const NS_ERROR_HOST_IS_IP_ADDRESS = 0x804b0051; + function run_test() { var tld = Cc["@mozilla.org/network/effective-tld-service;1"]. getService(Ci.nsIEffectiveTLDService); - do_check_eq(tld.getEffectiveTLDLength("localhost"), 9); - do_check_eq(tld.getEffectiveTLDLength("localhost."), 10); - do_check_eq(tld.getEffectiveTLDLength("domain.com"), 3); - do_check_eq(tld.getEffectiveTLDLength("domain.com."), 4); - do_check_eq(tld.getEffectiveTLDLength("domain.co.uk"), 5); - do_check_eq(tld.getEffectiveTLDLength("domain.co.uk."), 6); + var etld; + + do_check_eq(tld.getPublicSuffixFromHost("localhost"), "localhost"); + do_check_eq(tld.getPublicSuffixFromHost("localhost."), "localhost."); + do_check_eq(tld.getPublicSuffixFromHost("domain.com"), "com"); + do_check_eq(tld.getPublicSuffixFromHost("domain.com."), "com."); + do_check_eq(tld.getPublicSuffixFromHost("domain.co.uk"), "co.uk"); + do_check_eq(tld.getPublicSuffixFromHost("domain.co.uk."), "co.uk."); + do_check_eq(tld.getBaseDomainFromHost("domain.co.uk"), "domain.co.uk"); + do_check_eq(tld.getBaseDomainFromHost("domain.co.uk."), "domain.co.uk."); + + try { + etld = tld.getBaseDomainFromHost("domain.co.uk", 1); + do_throw("this should fail"); + } catch(e) { + do_check_eq(e.result, NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS); + } + + try { + etld = tld.getPublicSuffixFromHost("1.2.3.4"); + do_throw("this should fail"); + } catch(e) { + do_check_eq(e.result, NS_ERROR_HOST_IS_IP_ADDRESS); + } + + try { + etld = tld.getPublicSuffixFromHost("2010:836B:4179::836B:4179"); + do_throw("this should fail"); + } catch(e) { + do_check_eq(e.result, NS_ERROR_HOST_IS_IP_ADDRESS); + } + + /* + // test commented out because it erroneously passes on xserve01 + try { + etld = tld.getPublicSuffixFromHost("3232235878"); + do_throw("this should fail"); + } catch(e) { + do_check_eq(e.result, NS_ERROR_HOST_IS_IP_ADDRESS); + } + */ + + try { + etld = tld.getPublicSuffixFromHost("::ffff:192.9.5.5"); + do_throw("this should fail"); + } catch(e) { + do_check_eq(e.result, NS_ERROR_HOST_IS_IP_ADDRESS); + } + + try { + etld = tld.getPublicSuffixFromHost("::1"); + do_throw("this should fail"); + } catch(e) { + do_check_eq(e.result, NS_ERROR_HOST_IS_IP_ADDRESS); + } + + // Check IP addresses with trailing dot as well, Necko sometimes accepts + // those (depending on operating system, see bug 380543) + try { + etld = tld.getPublicSuffixFromHost("127.0.0.1."); + do_throw("this should fail"); + } catch(e) { + do_check_eq(e.result, NS_ERROR_HOST_IS_IP_ADDRESS); + } + + try { + etld = tld.getPublicSuffixFromHost("::ffff:127.0.0.1."); + do_throw("this should fail"); + } catch(e) { + do_check_eq(e.result, NS_ERROR_HOST_IS_IP_ADDRESS); + } } diff --git a/security/manager/Makefile.in b/security/manager/Makefile.in index 423c7d41d4dc..d42f8c127358 100644 --- a/security/manager/Makefile.in +++ b/security/manager/Makefile.in @@ -156,7 +156,7 @@ ifneq ($(ABS_topsrcdir),$(MOZ_BUILD_ROOT)) DEFAULT_GMAKE_FLAGS += BUILD_TREE=$(MOZ_BUILD_ROOT) endif ifndef MOZ_DEBUG -DEFAULT_GMAKE_FLAGS += BUILD_OPT=1 +DEFAULT_GMAKE_FLAGS += BUILD_OPT=1 OPT_CODE_SIZE=1 endif ifdef GNU_CC DEFAULT_GMAKE_FLAGS += NS_USE_GCC=1 NS_USE_NATIVE= diff --git a/security/manager/locales/en-US/chrome/pipnss/pipnss.properties b/security/manager/locales/en-US/chrome/pipnss/pipnss.properties index 8a03eae55cba..a08e96f687c7 100644 --- a/security/manager/locales/en-US/chrome/pipnss/pipnss.properties +++ b/security/manager/locales/en-US/chrome/pipnss/pipnss.properties @@ -225,6 +225,7 @@ CertDumpHold=Certificate Hold CertDumpOCSPResponder=OCSP CertDumpCAIssuers=CA Issuers CertDumpCPSPointer=Certification Practice Statement pointer +CertDumpPolicyOidEV=Extended Validation (EV) SSL Server Certificate CertDumpUserNotice=User Notice CertDumpLogotype=Logotype CertDumpECPublicKey=Elliptic Curve Public Key @@ -336,12 +337,24 @@ PSMERR_HostReusedIssuerSerial=You have received an invalid certificate. Please SSLConnectionErrorPrefix=An error occurred during a connection to %S. -certErrorIntro=An error occurred during a connection to %S because it uses an invalid security certificate. -certErrorUntrusted=The certificate is not trusted or its issuer certificate is invalid. -certErrorMismatch=The certificate is not valid for domain name %S. -certErrorExpired=The certificate has expired on %S. +certErrorIntro=%S uses an invalid security certificate. + +certErrorTrust_SelfSigned=The certificate is not trusted because it is self signed. +certErrorTrust_UnknownIssuer=The certificate is not trusted because the issuer certificate is unknown. +certErrorTrust_CaInvalid=The certificate is not trusted because it was issued by an invalid CA certificate. +certErrorTrust_Issuer=The certificate is not trusted because the issuer certificate is not trusted. +certErrorTrust_ExpiredIssuer=The certificate is not trusted because the issuer certificate has expired. +certErrorTrust_Untrusted=The certificate does not come from a trusted source. + +certErrorMismatch=The certificate is not valid for the name %S. +certErrorMismatchSingle=The certificate is only valid for name %S. +certErrorMismatchMultiple=The certificate is only valid for the following names: + +certErrorExpired=The certificate expired on %S. certErrorNotYetValid=The certificate will not be valid until %S. +certErrorCodePrefix=(Error code: %S) + CertInfoIssuedFor=Issued to: CertInfoIssuedBy=Issued by: CertInfoValid=Valid diff --git a/security/manager/locales/en-US/chrome/pippki/certManager.dtd b/security/manager/locales/en-US/chrome/pippki/certManager.dtd index 366c92564fad..5af23acf72a4 100644 --- a/security/manager/locales/en-US/chrome/pippki/certManager.dtd +++ b/security/manager/locales/en-US/chrome/pippki/certManager.dtd @@ -38,17 +38,17 @@ - + - + - + diff --git a/security/manager/pki/resources/content/WebSitesOverlay.xul b/security/manager/pki/resources/content/WebSitesOverlay.xul index cbe7e1b813a1..92edf9f4ddf9 100644 --- a/security/manager/pki/resources/content/WebSitesOverlay.xul +++ b/security/manager/pki/resources/content/WebSitesOverlay.xul @@ -48,7 +48,7 @@ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"> - &certmgr.websites; + &certmgr.websites2; diff --git a/security/manager/pki/resources/content/certManager.xul b/security/manager/pki/resources/content/certManager.xul index fbe1cdd0150f..5cac62352c37 100644 --- a/security/manager/pki/resources/content/certManager.xul +++ b/security/manager/pki/resources/content/certManager.xul @@ -64,11 +64,11 @@ - + - + diff --git a/security/manager/pki/resources/content/exceptionDialog.js b/security/manager/pki/resources/content/exceptionDialog.js index 3340eae4c91b..bd8d45168cfe 100644 --- a/security/manager/pki/resources/content/exceptionDialog.js +++ b/security/manager/pki/resources/content/exceptionDialog.js @@ -83,6 +83,32 @@ function initExceptionDialog() { gDialog.getButton("extra1").disabled = true; } +// returns true if found and global status could be set +function findRecentBadCert(uri) { + try { + var recentCertsSvc = Components.classes["@mozilla.org/security/recentbadcerts;1"] + .getService(Components.interfaces.nsIRecentBadCertsService); + if (!recentCertsSvc) + return false; + + var hostWithPort = uri.host + ":" + uri.port; + gSSLStatus = recentCertsSvc.getRecentBadCert(hostWithPort); + if (!gSSLStatus) + return false; + + gCert = gSSLStatus.QueryInterface(Components.interfaces.nsISSLStatus).serverCert; + if (!gCert) + return false; + + gBroken = true; + } + catch (e) { + return false; + } + updateCertStatus(); + return true; +} + /** * Attempt to download the certificate for the location specified, and populate * the Certificate Status section with the result. @@ -95,8 +121,13 @@ function checkCert() { gBroken = false; updateCertStatus(); - var req = new XMLHttpRequest(); var uri = getURI(); + + // Is the cert already known in the list of recently seen bad certs? + if (findRecentBadCert(uri) == true) + return; + + var req = new XMLHttpRequest(); try { if(uri) { req.open('GET', uri.prePath, false); diff --git a/security/manager/pki/resources/content/exceptionDialog.xul b/security/manager/pki/resources/content/exceptionDialog.xul index 7e6ca33edbd4..1ab7f9fd4577 100644 --- a/security/manager/pki/resources/content/exceptionDialog.xul +++ b/security/manager/pki/resources/content/exceptionDialog.xul @@ -67,9 +67,9 @@ + style="white-space: -moz-pre-wrap"/> + style="font-weight: bold; white-space: -moz-pre-wrap;"> &exceptionMgr.supplementalWarning; @@ -90,7 +90,7 @@ -