author | Matt Brubeck <mbrubeck@mozilla.com> |
Thu, 12 Jan 2012 08:22:14 -0800 | |
changeset 84334 | fb5bcf9ae739c64ffb6718e4f7030f2b84cae4f9 |
parent 84278 | cab1a867f0bd72ffc26b010ea58564218b6a2b31 (current diff) |
parent 84333 | feba786cfdc8667873f84cb1979b4105ad7bbfac (diff) |
child 84335 | c98283f80ae7d02a408e21169144adcf13be08e0 |
push id | 21839 |
push user | mbrubeck@mozilla.com |
push date | Thu, 12 Jan 2012 16:24:29 +0000 |
treeherder | mozilla-central@fb5bcf9ae739 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
milestone | 12.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
content/base/src/nsFileDataProtocolHandler.cpp | file | annotate | diff | comparison | revisions | |
content/base/src/nsFileDataProtocolHandler.h | file | annotate | diff | comparison | revisions | |
mobile/android/base/resources/drawable-hdpi-v11/ic_awesomebar_go.png | file | annotate | diff | comparison | revisions | |
mobile/android/base/resources/drawable-hdpi-v11/ic_awesomebar_search.png | file | annotate | diff | comparison | revisions | |
mobile/android/base/resources/drawable-mdpi-v11/ic_awesomebar_go.png | file | annotate | diff | comparison | revisions | |
mobile/android/base/resources/drawable-mdpi-v11/ic_awesomebar_search.png | file | annotate | diff | comparison | revisions |
--- a/b2g/app/b2g.js +++ b/b2g/app/b2g.js @@ -394,8 +394,17 @@ pref("layers.acceleration.force-enabled" pref("dom.screenEnabledProperty.enabled", true); pref("dom.screenBrightnessProperty.enabled", true); // Temporary permission hack for WebSMS pref("dom.sms.enabled", true); pref("dom.sms.whitelist", "file://,http://localhost:6666"); // Ignore X-Frame-Options headers. pref("b2g.ignoreXFrameOptions", true); + +// "Preview" landing of bug 710563, which is bogged down in analysis +// of talos regression. This is a needed change for higher-framerate +// CSS animations, and incidentally works around an apparent bug in +// our handling of requestAnimationFrame() listeners, which are +// supposed to enable this REPEATING_PRECISE_CAN_SKIP behavior. The +// secondary bug isn't really worth investigating since it's obseleted +// by bug 710563. +pref("layout.frame_rate.precise", true);
--- a/browser/base/content/browser-appmenu.inc +++ b/browser/base/content/browser-appmenu.inc @@ -174,17 +174,18 @@ </menupopup> </splitmenu> <menuseparator class="appmenu-menuseparator"/> <menu id="appmenu_webDeveloper" label="&appMenuWebDeveloper.label;"> <menupopup id="appmenu_webDeveloper_popup"> <menuitem id="appmenu_webConsole" label="&webConsoleCmd.label;" - oncommand="HUDConsoleUI.toggleHUD();" + type="checkbox" + command="Tools:WebConsole" key="key_webConsole"/> <menuitem id="appmenu_pageInspect" hidden="true" label="&inspectMenu.label;" type="checkbox" command="Tools:Inspect" key="key_inspect"/> <menuitem id="appmenu_scratchpad"
--- a/browser/base/content/browser-menubar.inc +++ b/browser/base/content/browser-menubar.inc @@ -528,20 +528,21 @@ oncommand="gSyncUI.doSync(event);"/> #endif <menuseparator id="devToolsSeparator"/> <menu id="webDeveloperMenu" label="&webDeveloperMenu.label;" accesskey="&webDeveloperMenu.accesskey;"> <menupopup id="menuWebDeveloperPopup"> <menuitem id="webConsole" + type="checkbox" label="&webConsoleCmd.label;" accesskey="&webConsoleCmd.accesskey;" key="key_webConsole" - oncommand="HUDConsoleUI.toggleHUD();"/> + command="Tools:WebConsole"/> <menuitem id="menu_pageinspect" type="checkbox" hidden="true" label="&inspectMenu.label;" accesskey="&inspectMenu.accesskey;" key="key_inspect" command="Tools:Inspect"/> <menuitem id="menu_scratchpad"
--- a/browser/base/content/browser-sets.inc +++ b/browser/base/content/browser-sets.inc @@ -120,16 +120,17 @@ <command id="cmd_fullZoomReduce" oncommand="FullZoom.reduce()"/> <command id="cmd_fullZoomEnlarge" oncommand="FullZoom.enlarge()"/> <command id="cmd_fullZoomReset" oncommand="FullZoom.reset()"/> <command id="cmd_fullZoomToggle" oncommand="ZoomManager.toggleZoom();"/> <command id="Browser:OpenLocation" oncommand="openLocation();"/> <command id="Tools:Search" oncommand="BrowserSearch.webSearch();"/> <command id="Tools:Downloads" oncommand="BrowserDownloadsUI();"/> + <command id="Tools:WebConsole" oncommand="HUDConsoleUI.toggleHUD();"/> <command id="Tools:Inspect" oncommand="InspectorUI.toggleInspectorUI();" disabled="true"/> <command id="Tools:Scratchpad" oncommand="Scratchpad.openScratchpad();" disabled="true"/> <command id="Tools:StyleEditor" oncommand="StyleEditor.openChrome();" disabled="true"/> <command id="Tools:Addons" oncommand="BrowserOpenAddonsMgr();"/> <command id="Tools:Sanitize" oncommand="Cc['@mozilla.org/browser/browserglue;1'].getService(Ci.nsIBrowserGlue).sanitize(window);"/> <command id="Tools:PrivateBrowsing" oncommand="gPrivateBrowsingUI.toggleMode();"/> <command id="History:UndoCloseTab" oncommand="undoCloseTab();"/>
--- a/browser/config/mozconfigs/macosx32/debug +++ b/browser/config/mozconfigs/macosx32/debug @@ -4,11 +4,8 @@ ac_add_options --enable-trace-malloc # Enable parallel compiling mk_add_options MOZ_MAKE_FLAGS="-j4" # Needed to enable breakpad in application.ini export MOZILLA_OFFICIAL=1 ac_add_options --with-macbundlename-prefix=Firefox - -# Treat warnings as errors in directories with FAIL_ON_WARNINGS. -ac_add_options --enable-warnings-as-errors
--- a/browser/devtools/scratchpad/test/browser_scratchpad_bug690552_display_outputs_errors.js +++ b/browser/devtools/scratchpad/test/browser_scratchpad_bug690552_display_outputs_errors.js @@ -13,17 +13,17 @@ function test() }, true); content.location = "data:text/html,<p>test that exceptions our output as " + "comments for 'display' and not sent to the console in Scratchpad"; } function runTests() { - scratchpad = gScratchpadWindow.Scratchpad; + var scratchpad = gScratchpadWindow.Scratchpad; var message = "\"Hello World!\"" var openComment = "/*\n"; var closeComment = "\n*/"; var error = "throw new Error(\"Ouch!\")"; let messageArray = {}; let count = {};
--- a/browser/devtools/webconsole/HUDService.jsm +++ b/browser/devtools/webconsole/HUDService.jsm @@ -1506,28 +1506,30 @@ HUD_SERVICE.prototype = * @param boolean aAnimated animate opening the Web Console? * @returns void */ activateHUDForContext: function HS_activateHUDForContext(aContext, aAnimated) { this.wakeup(); let window = aContext.linkedBrowser.contentWindow; - let nBox = aContext.ownerDocument.defaultView. - getNotificationBox(window); + let chromeDocument = aContext.ownerDocument; + let nBox = chromeDocument.defaultView.getNotificationBox(window); this.registerActiveContext(nBox.id); this.windowInitializer(window); let hudId = "hud_" + nBox.id; let hudRef = this.hudReferences[hudId]; if (!aAnimated || hudRef.consolePanel) { this.disableAnimation(hudId); } + chromeDocument.getElementById("Tools:WebConsole").setAttribute("checked", "true"); + // Create a processing instruction for GCLIs CSS stylesheet, but only if // we don't have one for this document. Also record the context we're // adding this for so we know when to remove it. let procInstr = aContext.ownerDocument.gcliCssProcInstr; if (!procInstr) { procInstr = aContext.ownerDocument.createProcessingInstruction( "xml-stylesheet", "href='chrome://browser/skin/devtools/gcli.css' type='text/css'"); @@ -1567,16 +1569,18 @@ HUD_SERVICE.prototype = browser.webProgress.removeProgressListener(hud.progressListener); delete hud.progressListener; this.unregisterDisplay(hudId); window.focus(); } + chromeDocument.getElementById("Tools:WebConsole").setAttribute("checked", "false"); + // Remove this context from the list of contexts that need the GCLI CSS // processing instruction and then remove the processing instruction if it // isn't needed any more. let procInstr = aContext.ownerDocument.gcliCssProcInstr; if (procInstr) { procInstr.contexts = procInstr.contexts.filter(function(id) { return id !== hudId; });
--- a/browser/devtools/webconsole/test/browser_webconsole_bug_618078_network_exceptions.js +++ b/browser/devtools/webconsole/test/browser_webconsole_bug_618078_network_exceptions.js @@ -1,11 +1,11 @@ /* vim:set ts=2 sw=2 sts=2 et: */ /* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1 + * 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 @@ -17,16 +17,28 @@ * The Initial Developer of the Original Code is * Mihai Sucan. * Portions created by the Initial Developer are Copyright (C) 2010 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Mihai Sucan <mihai.sucan@gmail.com> * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * * ***** END LICENSE BLOCK ***** */ // Tests that network log messages bring up the network panel. const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test//test-bug-618078-network-exceptions.html"; let testEnded = false;
--- a/build/mobile/robocop/FennecNativeAssert.java.in +++ b/build/mobile/robocop/FennecNativeAssert.java.in @@ -34,46 +34,27 @@ * 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 ***** */ package @ANDROID_PACKAGE_NAME@; -import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; -import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; -import java.util.ArrayList; import java.util.LinkedList; -import java.util.HashMap; import java.util.List; import java.util.Date; -import java.lang.Class; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.lang.reflect.InvocationHandler; -import java.lang.Long; - -import android.app.Activity; import android.util.Log; -import android.view.View; - -import org.json.*; - -import com.jayway.android.robotium.solo.Solo; public class FennecNativeAssert implements Assert { - // Map of IDs to element names. - private HashMap locators = null; private String logFile = null; // Objects for reflexive access of fennec classes. private LinkedList<testInfo> testList = new LinkedList<testInfo>(); // If waiting for an event. private boolean asleep = false; @@ -199,16 +180,19 @@ public class FennecNativeAssert implemen if (test.todo) { todo++; } else if (isError) { failed++; } else { passed++; } + if (isError) { + junit.framework.Assert.fail(message); + } } public void finalize() { // It appears that we call finalize during cleanup, this might be an invalid assertion. String message; if (logTestName != "") {
--- a/build/mobile/robocop/Makefile.in +++ b/build/mobile/robocop/Makefile.in @@ -106,17 +106,16 @@ AndroidManifest.xml: % : %.in $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $< > $@ $(_JAVA_TESTS): % : $(TESTPATH)/%.in $(NSINSTALL) -D $(DEPTH)/mobile/android/base/tests $(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $< > $(DEPTH)/mobile/android/base/tests/$@ $(_ROBOCOP_TOOLS): cp $(TESTPATH)/robocop.ini robocop.ini - cp $(srcdir)/parse_ids.txt parse_ids.txt libs:: $(_TEST_FILES) $(NSINSTALL) -D $(DEPTH)/_tests/testing/mochitest/tests/robocop $(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/robocop/ tools:: robocop.apk classes.dex: robocop.ap_
--- a/content/base/public/nsIDOMFile.idl +++ b/content/base/public/nsIDOMFile.idl @@ -63,17 +63,17 @@ interface nsIDOMBlob; [scriptable, builtinclass, uuid(f62c6887-e3bc-495a-802c-287e12e969a0)] interface nsIDOMBlob : nsISupports { readonly attribute unsigned long long size; readonly attribute DOMString type; [noscript] readonly attribute nsIInputStream internalStream; // The caller is responsible for releasing the internalUrl from the - // moz-filedata: protocol handler + // blob: protocol handler [noscript] DOMString getInternalUrl(in nsIPrincipal principal); [optional_argc] nsIDOMBlob mozSlice([optional] in long long start, [optional] in long long end, [optional] in DOMString contentType); // Get internal id of stored file. Returns -1 if it is not a stored file. // Intended only for testing. It can be called on any thread.
--- a/content/base/public/nsIDocument.h +++ b/content/base/public/nsIDocument.h @@ -1490,17 +1490,17 @@ public: virtual nsEventStates GetDocumentState() = 0; virtual nsISupports* GetCurrentContentSink() = 0; /** * Register/Unregister a filedata uri as being "owned" by this document. * I.e. that its lifetime is connected with this document. When the document * goes away it should "kill" the uri by calling - * nsFileDataProtocolHandler::RemoveFileDataEntry + * nsBlobProtocolHandler::RemoveFileDataEntry */ virtual void RegisterFileDataUri(const nsACString& aUri) = 0; virtual void UnregisterFileDataUri(const nsACString& aUri) = 0; virtual void SetScrollToRef(nsIURI *aDocumentURI) = 0; virtual void ScrollToRef() = 0; virtual void ResetScrolledToRefAlready() = 0; virtual void SetChangeScrollPosWhenScrollingToRef(bool aValue) = 0;
--- a/content/base/public/nsISelectionController.idl +++ b/content/base/public/nsISelectionController.idl @@ -93,16 +93,17 @@ interface nsISelectionController : nsISe * * @param aType will hold the type of selection //SelectionType * @param _return will hold the return value */ nsISelection getSelection(in short type); const short SCROLL_SYNCHRONOUS = 1<<1; const short SCROLL_FIRST_ANCESTOR_ONLY = 1<<2; + const short SCROLL_CENTER_VERTICALLY = 1<<4; /** * ScrollSelectionIntoView scrolls a region of the selection, * so that it is visible in the scrolled view. * * @param aType the selection to scroll into view. //SelectionType * @param aRegion the region inside the selection to scroll into view. //SelectionRegion * @param aFlags the scroll flags. Valid bits include:
--- a/content/base/src/Makefile.in +++ b/content/base/src/Makefile.in @@ -146,17 +146,17 @@ CPPSRCS = \ nsTreeSanitizer.cpp \ nsTreeWalker.cpp \ nsWebSocket.cpp \ nsXHTMLContentSerializer.cpp \ nsXMLContentSerializer.cpp \ nsXMLHttpRequest.cpp \ nsXMLNameSpaceMap.cpp \ Link.cpp \ - nsFileDataProtocolHandler.cpp \ + nsBlobProtocolHandler.cpp \ nsFrameMessageManager.cpp \ nsInProcessTabChildGlobal.cpp \ ThirdPartyUtil.cpp \ nsEventSource.cpp \ FileIOObject.cpp \ $(NULL) # Are we targeting x86-32 or x86-64? If so, we want to include SSE2 code for
rename from content/base/src/nsFileDataProtocolHandler.cpp rename to content/base/src/nsBlobProtocolHandler.cpp --- a/content/base/src/nsFileDataProtocolHandler.cpp +++ b/content/base/src/nsBlobProtocolHandler.cpp @@ -29,17 +29,17 @@ * 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 "nsFileDataProtocolHandler.h" +#include "nsBlobProtocolHandler.h" #include "nsSimpleURI.h" #include "nsDOMError.h" #include "nsCOMPtr.h" #include "nsClassHashtable.h" #include "nsNetUtil.h" #include "nsIURIWithPrincipal.h" #include "nsIPrincipal.h" #include "nsIDOMFile.h" @@ -55,17 +55,17 @@ struct FileDataInfo { nsCOMPtr<nsIDOMBlob> mFile; nsCOMPtr<nsIPrincipal> mPrincipal; }; static nsClassHashtable<nsCStringHashKey, FileDataInfo>* gFileDataTable; void -nsFileDataProtocolHandler::AddFileDataEntry(nsACString& aUri, +nsBlobProtocolHandler::AddFileDataEntry(nsACString& aUri, nsIDOMBlob* aFile, nsIPrincipal* aPrincipal) { if (!gFileDataTable) { gFileDataTable = new nsClassHashtable<nsCStringHashKey, FileDataInfo>; gFileDataTable->Init(); } @@ -73,29 +73,29 @@ nsFileDataProtocolHandler::AddFileDataEn info->mFile = aFile; info->mPrincipal = aPrincipal; gFileDataTable->Put(aUri, info); } void -nsFileDataProtocolHandler::RemoveFileDataEntry(nsACString& aUri) +nsBlobProtocolHandler::RemoveFileDataEntry(nsACString& aUri) { if (gFileDataTable) { gFileDataTable->Remove(aUri); if (gFileDataTable->Count() == 0) { delete gFileDataTable; gFileDataTable = nsnull; } } } nsIPrincipal* -nsFileDataProtocolHandler::GetFileDataEntryPrincipal(nsACString& aUri) +nsBlobProtocolHandler::GetFileDataEntryPrincipal(nsACString& aUri) { if (!gFileDataTable) { return nsnull; } FileDataInfo* res; gFileDataTable->Get(aUri, &res); if (!res) { @@ -104,308 +104,308 @@ nsFileDataProtocolHandler::GetFileDataEn return res->mPrincipal; } static FileDataInfo* GetFileDataInfo(const nsACString& aUri) { NS_ASSERTION(StringBeginsWith(aUri, - NS_LITERAL_CSTRING(FILEDATA_SCHEME ":")), + NS_LITERAL_CSTRING(BLOBURI_SCHEME ":")), "Bad URI"); if (!gFileDataTable) { return nsnull; } FileDataInfo* res; gFileDataTable->Get(aUri, &res); return res; } // ----------------------------------------------------------------------- // Uri -#define NS_FILEDATAURI_CID \ +#define NS_BLOBURI_CID \ { 0xf5475c51, 0x59a7, 0x4757, \ { 0xb3, 0xd9, 0xe2, 0x11, 0xa9, 0x41, 0x08, 0x72 } } -static NS_DEFINE_CID(kFILEDATAURICID, NS_FILEDATAURI_CID); +static NS_DEFINE_CID(kBLOBURICID, NS_BLOBURI_CID); -class nsFileDataURI : public nsSimpleURI, +class nsBlobURI : public nsSimpleURI, public nsIURIWithPrincipal { public: - nsFileDataURI(nsIPrincipal* aPrincipal) : + nsBlobURI(nsIPrincipal* aPrincipal) : nsSimpleURI(), mPrincipal(aPrincipal) {} - virtual ~nsFileDataURI() {} + virtual ~nsBlobURI() {} // For use only from deserialization - nsFileDataURI() : nsSimpleURI() {} + nsBlobURI() : nsSimpleURI() {} NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIURIWITHPRINCIPAL NS_DECL_NSISERIALIZABLE NS_DECL_NSICLASSINFO // Override CloneInternal() and EqualsInternal() virtual nsresult CloneInternal(RefHandlingEnum aRefHandlingMode, nsIURI** aClone); virtual nsresult EqualsInternal(nsIURI* aOther, RefHandlingEnum aRefHandlingMode, bool* aResult); - // Override StartClone to hand back a nsFileDataURI + // Override StartClone to hand back a nsBlobURI virtual nsSimpleURI* StartClone(RefHandlingEnum /* unused */) - { return new nsFileDataURI(); } + { return new nsBlobURI(); } nsCOMPtr<nsIPrincipal> mPrincipal; }; static NS_DEFINE_CID(kThisSimpleURIImplementationCID, NS_THIS_SIMPLEURI_IMPLEMENTATION_CID); -NS_IMPL_ADDREF_INHERITED(nsFileDataURI, nsSimpleURI) -NS_IMPL_RELEASE_INHERITED(nsFileDataURI, nsSimpleURI) +NS_IMPL_ADDREF_INHERITED(nsBlobURI, nsSimpleURI) +NS_IMPL_RELEASE_INHERITED(nsBlobURI, nsSimpleURI) -NS_INTERFACE_MAP_BEGIN(nsFileDataURI) +NS_INTERFACE_MAP_BEGIN(nsBlobURI) NS_INTERFACE_MAP_ENTRY(nsIURIWithPrincipal) - if (aIID.Equals(kFILEDATAURICID)) + if (aIID.Equals(kBLOBURICID)) foundInterface = static_cast<nsIURI*>(this); else if (aIID.Equals(kThisSimpleURIImplementationCID)) { // Need to return explicitly here, because if we just set foundInterface // to null the NS_INTERFACE_MAP_END_INHERITING will end up calling into // nsSimplURI::QueryInterface and finding something for this CID. *aInstancePtr = nsnull; return NS_NOINTERFACE; } else NS_INTERFACE_MAP_END_INHERITING(nsSimpleURI) // nsIURIWithPrincipal methods: NS_IMETHODIMP -nsFileDataURI::GetPrincipal(nsIPrincipal** aPrincipal) +nsBlobURI::GetPrincipal(nsIPrincipal** aPrincipal) { NS_IF_ADDREF(*aPrincipal = mPrincipal); return NS_OK; } NS_IMETHODIMP -nsFileDataURI::GetPrincipalUri(nsIURI** aUri) +nsBlobURI::GetPrincipalUri(nsIURI** aUri) { if (mPrincipal) { mPrincipal->GetURI(aUri); } else { *aUri = nsnull; } return NS_OK; } // nsISerializable methods: NS_IMETHODIMP -nsFileDataURI::Read(nsIObjectInputStream* aStream) +nsBlobURI::Read(nsIObjectInputStream* aStream) { nsresult rv = nsSimpleURI::Read(aStream); NS_ENSURE_SUCCESS(rv, rv); return NS_ReadOptionalObject(aStream, true, getter_AddRefs(mPrincipal)); } NS_IMETHODIMP -nsFileDataURI::Write(nsIObjectOutputStream* aStream) +nsBlobURI::Write(nsIObjectOutputStream* aStream) { nsresult rv = nsSimpleURI::Write(aStream); NS_ENSURE_SUCCESS(rv, rv); return NS_WriteOptionalCompoundObject(aStream, mPrincipal, NS_GET_IID(nsIPrincipal), true); } // nsIURI methods: nsresult -nsFileDataURI::CloneInternal(nsSimpleURI::RefHandlingEnum aRefHandlingMode, +nsBlobURI::CloneInternal(nsSimpleURI::RefHandlingEnum aRefHandlingMode, nsIURI** aClone) { nsCOMPtr<nsIURI> simpleClone; nsresult rv = nsSimpleURI::CloneInternal(aRefHandlingMode, getter_AddRefs(simpleClone)); NS_ENSURE_SUCCESS(rv, rv); #ifdef DEBUG - nsRefPtr<nsFileDataURI> uriCheck; - rv = simpleClone->QueryInterface(kFILEDATAURICID, getter_AddRefs(uriCheck)); + nsRefPtr<nsBlobURI> uriCheck; + rv = simpleClone->QueryInterface(kBLOBURICID, getter_AddRefs(uriCheck)); NS_ABORT_IF_FALSE(NS_SUCCEEDED(rv) && uriCheck, "Unexpected!"); #endif - nsFileDataURI* fileDataURI = static_cast<nsFileDataURI*>(simpleClone.get()); + nsBlobURI* blobURI = static_cast<nsBlobURI*>(simpleClone.get()); - fileDataURI->mPrincipal = mPrincipal; + blobURI->mPrincipal = mPrincipal; simpleClone.forget(aClone); return NS_OK; } /* virtual */ nsresult -nsFileDataURI::EqualsInternal(nsIURI* aOther, +nsBlobURI::EqualsInternal(nsIURI* aOther, nsSimpleURI::RefHandlingEnum aRefHandlingMode, bool* aResult) { if (!aOther) { *aResult = false; return NS_OK; } - nsRefPtr<nsFileDataURI> otherFileDataUri; - aOther->QueryInterface(kFILEDATAURICID, getter_AddRefs(otherFileDataUri)); - if (!otherFileDataUri) { + nsRefPtr<nsBlobURI> otherBlobUri; + aOther->QueryInterface(kBLOBURICID, getter_AddRefs(otherBlobUri)); + if (!otherBlobUri) { *aResult = false; return NS_OK; } // Compare the member data that our base class knows about. - if (!nsSimpleURI::EqualsInternal(otherFileDataUri, aRefHandlingMode)) { + if (!nsSimpleURI::EqualsInternal(otherBlobUri, aRefHandlingMode)) { *aResult = false; return NS_OK; } // Compare the piece of additional member data that we add to base class. - if (mPrincipal && otherFileDataUri->mPrincipal) { + if (mPrincipal && otherBlobUri->mPrincipal) { // Both of us have mPrincipals. Compare them. - return mPrincipal->Equals(otherFileDataUri->mPrincipal, aResult); + return mPrincipal->Equals(otherBlobUri->mPrincipal, aResult); } // else, at least one of us lacks a principal; only equal if *both* lack it. - *aResult = (!mPrincipal && !otherFileDataUri->mPrincipal); + *aResult = (!mPrincipal && !otherBlobUri->mPrincipal); return NS_OK; } // nsIClassInfo methods: NS_IMETHODIMP -nsFileDataURI::GetInterfaces(PRUint32 *count, nsIID * **array) +nsBlobURI::GetInterfaces(PRUint32 *count, nsIID * **array) { *count = 0; *array = nsnull; return NS_OK; } NS_IMETHODIMP -nsFileDataURI::GetHelperForLanguage(PRUint32 language, nsISupports **_retval) +nsBlobURI::GetHelperForLanguage(PRUint32 language, nsISupports **_retval) { *_retval = nsnull; return NS_OK; } NS_IMETHODIMP -nsFileDataURI::GetContractID(char * *aContractID) +nsBlobURI::GetContractID(char * *aContractID) { // Make sure to modify any subclasses as needed if this ever // changes. *aContractID = nsnull; return NS_OK; } NS_IMETHODIMP -nsFileDataURI::GetClassDescription(char * *aClassDescription) +nsBlobURI::GetClassDescription(char * *aClassDescription) { *aClassDescription = nsnull; return NS_OK; } NS_IMETHODIMP -nsFileDataURI::GetClassID(nsCID * *aClassID) +nsBlobURI::GetClassID(nsCID * *aClassID) { // Make sure to modify any subclasses as needed if this ever // changes to not call the virtual GetClassIDNoAlloc. *aClassID = (nsCID*) nsMemory::Alloc(sizeof(nsCID)); NS_ENSURE_TRUE(*aClassID, NS_ERROR_OUT_OF_MEMORY); return GetClassIDNoAlloc(*aClassID); } NS_IMETHODIMP -nsFileDataURI::GetImplementationLanguage(PRUint32 *aImplementationLanguage) +nsBlobURI::GetImplementationLanguage(PRUint32 *aImplementationLanguage) { *aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS; return NS_OK; } NS_IMETHODIMP -nsFileDataURI::GetFlags(PRUint32 *aFlags) +nsBlobURI::GetFlags(PRUint32 *aFlags) { *aFlags = nsIClassInfo::MAIN_THREAD_ONLY; return NS_OK; } NS_IMETHODIMP -nsFileDataURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) +nsBlobURI::GetClassIDNoAlloc(nsCID *aClassIDNoAlloc) { - *aClassIDNoAlloc = kFILEDATAURICID; + *aClassIDNoAlloc = kBLOBURICID; return NS_OK; } // ----------------------------------------------------------------------- // Protocol handler -NS_IMPL_ISUPPORTS1(nsFileDataProtocolHandler, nsIProtocolHandler) +NS_IMPL_ISUPPORTS1(nsBlobProtocolHandler, nsIProtocolHandler) NS_IMETHODIMP -nsFileDataProtocolHandler::GetScheme(nsACString &result) +nsBlobProtocolHandler::GetScheme(nsACString &result) { - result.AssignLiteral(FILEDATA_SCHEME); + result.AssignLiteral(BLOBURI_SCHEME); return NS_OK; } NS_IMETHODIMP -nsFileDataProtocolHandler::GetDefaultPort(PRInt32 *result) +nsBlobProtocolHandler::GetDefaultPort(PRInt32 *result) { *result = -1; return NS_OK; } NS_IMETHODIMP -nsFileDataProtocolHandler::GetProtocolFlags(PRUint32 *result) +nsBlobProtocolHandler::GetProtocolFlags(PRUint32 *result) { *result = URI_NORELATIVE | URI_NOAUTH | URI_LOADABLE_BY_SUBSUMERS | URI_IS_LOCAL_RESOURCE | URI_NON_PERSISTABLE; return NS_OK; } NS_IMETHODIMP -nsFileDataProtocolHandler::NewURI(const nsACString& aSpec, +nsBlobProtocolHandler::NewURI(const nsACString& aSpec, const char *aCharset, nsIURI *aBaseURI, nsIURI **aResult) { *aResult = nsnull; nsresult rv; FileDataInfo* info = GetFileDataInfo(aSpec); - nsRefPtr<nsFileDataURI> uri = - new nsFileDataURI(info ? info->mPrincipal.get() : nsnull); + nsRefPtr<nsBlobURI> uri = + new nsBlobURI(info ? info->mPrincipal.get() : nsnull); rv = uri->SetSpec(aSpec); NS_ENSURE_SUCCESS(rv, rv); NS_TryToSetImmutable(uri); uri.forget(aResult); return NS_OK; } NS_IMETHODIMP -nsFileDataProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result) +nsBlobProtocolHandler::NewChannel(nsIURI* uri, nsIChannel* *result) { *result = nsnull; nsCString spec; uri->GetSpec(spec); FileDataInfo* info = GetFileDataInfo(spec); @@ -443,15 +443,15 @@ nsFileDataProtocolHandler::NewChannel(ns channel->SetOriginalURI(uri); channel->SetContentType(NS_ConvertUTF16toUTF8(type)); channel.forget(result); return NS_OK; } NS_IMETHODIMP -nsFileDataProtocolHandler::AllowPort(PRInt32 port, const char *scheme, +nsBlobProtocolHandler::AllowPort(PRInt32 port, const char *scheme, bool *_retval) { // don't override anything. *_retval = false; return NS_OK; }
rename from content/base/src/nsFileDataProtocolHandler.h rename to content/base/src/nsBlobProtocolHandler.h --- a/content/base/src/nsFileDataProtocolHandler.h +++ b/content/base/src/nsBlobProtocolHandler.h @@ -29,44 +29,44 @@ * 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 ***** */ -#ifndef nsFileDataProtocolHandler_h___ -#define nsFileDataProtocolHandler_h___ +#ifndef nsBlobProtocolHandler_h +#define nsBlobProtocolHandler_h #include "nsIProtocolHandler.h" -#define FILEDATA_SCHEME "moz-filedata" +#define BLOBURI_SCHEME "blob" class nsIDOMBlob; class nsIPrincipal; -class nsFileDataProtocolHandler : public nsIProtocolHandler +class nsBlobProtocolHandler : public nsIProtocolHandler { public: NS_DECL_ISUPPORTS // nsIProtocolHandler methods: NS_DECL_NSIPROTOCOLHANDLER - // nsFileDataProtocolHandler methods: - nsFileDataProtocolHandler() {} - virtual ~nsFileDataProtocolHandler() {} + // nsBlobProtocolHandler methods: + nsBlobProtocolHandler() {} + virtual ~nsBlobProtocolHandler() {} // Methods for managing uri->file mapping static void AddFileDataEntry(nsACString& aUri, nsIDOMBlob* aFile, nsIPrincipal* aPrincipal); static void RemoveFileDataEntry(nsACString& aUri); static nsIPrincipal* GetFileDataEntryPrincipal(nsACString& aUri); }; -#define NS_FILEDATAPROTOCOLHANDLER_CID \ +#define NS_BLOBPROTOCOLHANDLER_CID \ { 0xb43964aa, 0xa078, 0x44b2, \ { 0xb0, 0x6b, 0xfd, 0x4d, 0x1b, 0x17, 0x2e, 0x66 } } -#endif /* nsFileDataProtocolHandler_h___ */ +#endif /* nsBlobProtocolHandler_h */
--- a/content/base/src/nsDOMFile.cpp +++ b/content/base/src/nsDOMFile.cpp @@ -55,17 +55,17 @@ #include "nsIMIMEService.h" #include "nsIPlatformCharset.h" #include "nsISeekableStream.h" #include "nsIUnicharInputStream.h" #include "nsIUnicodeDecoder.h" #include "nsNetCID.h" #include "nsNetUtil.h" #include "nsIUUIDGenerator.h" -#include "nsFileDataProtocolHandler.h" +#include "nsBlobProtocolHandler.h" #include "nsStringStream.h" #include "CheckedInt.h" #include "nsJSUtils.h" #include "mozilla/Preferences.h" #include "plbase64.h" #include "prmem.h" @@ -283,20 +283,20 @@ nsDOMFileBase::GetInternalUrl(nsIPrincip nsID id; rv = uuidgen->GenerateUUIDInPlace(&id); NS_ENSURE_SUCCESS(rv, rv); char chars[NSID_LENGTH]; id.ToProvidedString(chars); - nsCString url = NS_LITERAL_CSTRING(FILEDATA_SCHEME ":") + + nsCString url = NS_LITERAL_CSTRING(BLOBURI_SCHEME ":") + Substring(chars + 1, chars + NSID_LENGTH - 2); - nsFileDataProtocolHandler::AddFileDataEntry(url, this, + nsBlobProtocolHandler::AddFileDataEntry(url, this, aPrincipal); CopyASCIItoUTF16(url, aURL); return NS_OK; } NS_IMETHODIMP_(PRInt64) @@ -663,11 +663,11 @@ nsDOMFileInternalUrlHolder::nsDOMFileInt MOZ_GUARD_OBJECT_NOTIFIER_INIT; aFile->GetInternalUrl(aPrincipal, mUrl); } nsDOMFileInternalUrlHolder::~nsDOMFileInternalUrlHolder() { if (!mUrl.IsEmpty()) { nsCAutoString narrowUrl; CopyUTF16toUTF8(mUrl, narrowUrl); - nsFileDataProtocolHandler::RemoveFileDataEntry(narrowUrl); + nsBlobProtocolHandler::RemoveFileDataEntry(narrowUrl); } }
--- a/content/base/src/nsDOMFileReader.cpp +++ b/content/base/src/nsDOMFileReader.cpp @@ -69,17 +69,17 @@ #include "nsIJSContextStack.h" #include "nsJSEnvironment.h" #include "nsIScriptGlobalObject.h" #include "nsCExternalHandlerService.h" #include "nsIStreamConverterService.h" #include "nsCycleCollectionParticipant.h" #include "nsLayoutStatics.h" #include "nsIScriptObjectPrincipal.h" -#include "nsFileDataProtocolHandler.h" +#include "nsBlobProtocolHandler.h" #include "mozilla/Preferences.h" #include "xpcpublic.h" #include "nsIScriptSecurityManager.h" #include "nsDOMJSUtils.h" #include "jstypedarray.h" using namespace mozilla;
--- a/content/base/src/nsDataDocumentContentPolicy.cpp +++ b/content/base/src/nsDataDocumentContentPolicy.cpp @@ -97,17 +97,17 @@ nsDataDocumentContentPolicy::ShouldLoad( return NS_OK; } if (doc->IsBeingUsedAsImage()) { // We only allow SVG images to load content from URIs that are local and // also satisfy one of the following conditions: // - URI inherits security context, e.g. data URIs // OR - // - URI loadable by subsumers, e.g. moz-filedata URIs + // - URI loadable by subsumers, e.g. blob URIs // Any URI that doesn't meet these requirements will be rejected below. if (!HasFlags(aContentLocation, nsIProtocolHandler::URI_IS_LOCAL_RESOURCE) || (!HasFlags(aContentLocation, nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT) && !HasFlags(aContentLocation, nsIProtocolHandler::URI_LOADABLE_BY_SUBSUMERS))) { *aDecision = nsIContentPolicy::REJECT_TYPE;
--- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -139,17 +139,17 @@ #include "nsContentCreatorFunctions.h" #include "nsIScriptContext.h" #include "nsBindingManager.h" #include "nsIDOMHTMLDocument.h" #include "nsIDOMHTMLFormElement.h" #include "nsIRequest.h" #include "nsILink.h" -#include "nsFileDataProtocolHandler.h" +#include "nsBlobProtocolHandler.h" #include "nsICharsetAlias.h" #include "nsIParser.h" #include "nsIContentSink.h" #include "nsDateTimeFormatCID.h" #include "nsIDateTimeFormat.h" #include "nsEventDispatcher.h" @@ -1664,17 +1664,17 @@ nsDocument::~nsDocument() if (mBoxObjectTable) { mBoxObjectTable->EnumerateRead(ClearAllBoxObjects, nsnull); delete mBoxObjectTable; } mPendingTitleChangeEvent.Revoke(); for (PRUint32 i = 0; i < mFileDataUris.Length(); ++i) { - nsFileDataProtocolHandler::RemoveFileDataEntry(mFileDataUris[i]); + nsBlobProtocolHandler::RemoveFileDataEntry(mFileDataUris[i]); } // We don't want to leave residual locks on images. Make sure we're in an // unlocked state, and then clear the table. SetImageLockingState(false); mImageTracker.Clear(); }
--- a/content/html/document/src/nsHTMLContentSink.cpp +++ b/content/html/document/src/nsHTMLContentSink.cpp @@ -203,17 +203,16 @@ public: NS_IMETHOD CloseMalformedContainer(const nsHTMLTag aTag); NS_IMETHOD AddLeaf(const nsIParserNode& aNode); NS_IMETHOD AddComment(const nsIParserNode& aNode); NS_IMETHOD AddProcessingInstruction(const nsIParserNode& aNode); NS_IMETHOD AddDocTypeDecl(const nsIParserNode& aNode); NS_IMETHOD DidProcessTokens(void); NS_IMETHOD WillProcessAToken(void); NS_IMETHOD DidProcessAToken(void); - NS_IMETHOD NotifyTagObservers(nsIParserNode* aNode); NS_IMETHOD BeginContext(PRInt32 aID); NS_IMETHOD EndContext(PRInt32 aID); NS_IMETHOD OpenHead(); NS_IMETHOD IsEnabled(PRInt32 aTag, bool* aReturn); NS_IMETHOD_(bool) IsFormOnStack(); #ifdef DEBUG // nsIDebugDumpContent @@ -265,18 +264,16 @@ protected: // yet. We want to make sure to only do this once. bool mNotifiedRootInsertion; PRUint8 mScriptEnabled : 1; PRUint8 mFramesEnabled : 1; PRUint8 mFormOnStack : 1; PRUint8 unused : 5; // bits available if someone needs one - nsCOMPtr<nsIObserverEntry> mObservers; - nsINodeInfo* mNodeInfoCache[NS_HTML_TAG_MAX + 1]; nsresult FlushTags(); void StartLayout(bool aIgnorePendingSheets); // Routines for tags that require special handling nsresult CloseHTML(); @@ -1569,25 +1566,16 @@ HTMLContentSink::Init(nsIDocument* aDoc, if (NS_FAILED(rv)) { return rv; } aDoc->AddObserver(this); mIsDocumentObserver = true; mHTMLDocument = do_QueryInterface(aDoc); - mObservers = nsnull; - nsIParserService* service = nsContentUtils::GetParserService(); - if (!service) { - return NS_ERROR_OUT_OF_MEMORY; - } - - service->GetTopicObservers(NS_LITERAL_STRING("text/html"), - getter_AddRefs(mObservers)); - NS_ASSERTION(mDocShell, "oops no docshell!"); // Find out if subframes are enabled if (mDocShell) { bool subFramesEnabled = true; mDocShell->GetAllowSubframes(&subFramesEnabled); if (subFramesEnabled) { mFramesEnabled = true; @@ -2501,37 +2489,16 @@ HTMLContentSink::WillInterrupt() } NS_IMETHODIMP HTMLContentSink::WillResume() { return WillResumeImpl(); } -NS_IMETHODIMP -HTMLContentSink::NotifyTagObservers(nsIParserNode* aNode) -{ - // Bug 125317 - // Inform observers that we're handling a document.write(). - // This information is necessary for the charset observer, atleast, - // to make a decision whether a new charset loading is required or not. - - if (!mObservers) { - return NS_OK; - } - - PRUint32 flag = 0; - - if (mHTMLDocument && mHTMLDocument->IsWriting()) { - flag = nsIElementObserver::IS_DOCUMENT_WRITE; - } - - return mObservers->Notify(aNode, mParser, mDocShell, flag); -} - void HTMLContentSink::StartLayout(bool aIgnorePendingSheets) { if (mLayoutStarted) { return; } mHTMLDocument->SetIsFrameset(mFrameset != nsnull);
--- a/content/smil/Makefile.in +++ b/content/smil/Makefile.in @@ -40,16 +40,17 @@ topsrcdir = @top_srcdir@ srcdir = @srcdir@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk MODULE = content LIBRARY_NAME = gkconsmil_s LIBXUL_LIBRARY = 1 +FAIL_ON_WARNINGS = 1 EXPORTS = \ nsISMILAnimationElement.h \ nsISMILAttr.h \ nsISMILType.h \ nsSMILAnimationController.h \ nsSMILCompositorTable.h \ nsSMILCSSProperty.h \
--- a/content/svg/document/src/Makefile.in +++ b/content/svg/document/src/Makefile.in @@ -40,16 +40,17 @@ topsrcdir = @top_srcdir@ srcdir = @srcdir@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk MODULE = content LIBRARY_NAME = gkconsvgdoc_s LIBXUL_LIBRARY = 1 +FAIL_ON_WARNINGS = 1 CPPSRCS = \ nsSVGDocument.cpp \ $(NULL) # we don't want the shared lib, but we want to force the creation of a static lib. FORCE_STATIC_LIB = 1
--- a/content/xul/content/test/test_bug330705-2.xul +++ b/content/xul/content/test/test_bug330705-2.xul @@ -21,24 +21,25 @@ https://bugzilla.mozilla.org/show_bug.cg var isFocused = false; function doTest() { document.getElementsByTagName('box')[1].blur(); setTimeout(function () { ok(isFocused, "The first box element is still focused after blur() has been called on the second box element"); SimpleTest.finish(); - }, 100); + }, 0); } function onLoad() { var box = document.getElementsByTagName('box')[0]; box.addEventListener('focus', function() { isFocused = true; setTimeout(doTest, 0); + box.removeEventListener('focus', arguments.callee, true); }, true); box.addEventListener('blur', function() { isFocused = false;}, true); box.focus(); } addLoadEvent(onLoad); ]]> </script>
--- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -175,17 +175,17 @@ #include "nsIScriptError.h" #include "nsIConsoleService.h" #include "nsIControllers.h" #include "nsIControllerContext.h" #include "nsGlobalWindowCommands.h" #include "nsAutoPtr.h" #include "nsContentUtils.h" #include "nsCSSProps.h" -#include "nsFileDataProtocolHandler.h" +#include "nsBlobProtocolHandler.h" #include "nsIDOMFile.h" #include "nsIDOMFileList.h" #include "nsIURIFixup.h" #include "mozilla/FunctionTimer.h" #include "nsCDefaultURIFixup.h" #include "nsEventDispatcher.h" #include "nsIObserverService.h" #include "nsIXULAppInfo.h" @@ -684,25 +684,25 @@ nsDOMMozURLProperty::RevokeObjectURL(con NS_LossyConvertUTF16toASCII asciiurl(aURL); nsIPrincipal* winPrincipal = mWindow->GetPrincipal(); if (!winPrincipal) { return NS_OK; } nsIPrincipal* principal = - nsFileDataProtocolHandler::GetFileDataEntryPrincipal(asciiurl); + nsBlobProtocolHandler::GetFileDataEntryPrincipal(asciiurl); bool subsumes; if (principal && winPrincipal && NS_SUCCEEDED(winPrincipal->Subsumes(principal, &subsumes)) && subsumes) { if (mWindow->mDoc) { mWindow->mDoc->UnregisterFileDataUri(asciiurl); } - nsFileDataProtocolHandler::RemoveFileDataEntry(asciiurl); + nsBlobProtocolHandler::RemoveFileDataEntry(asciiurl); } return NS_OK; } /** * An indirect observer object that means we don't have to implement nsIObserver * on nsGlobalWindow, where any script could see it.
--- a/dom/plugins/base/nsPluginHost.cpp +++ b/dom/plugins/base/nsPluginHost.cpp @@ -3089,33 +3089,38 @@ nsresult nsPluginHost::NewPluginURLStrea // Plug-ins seem to depend on javascript: URIs running synchronously scriptChannel->SetExecuteAsync(false); } } // deal with headers and post data nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(channel)); if (httpChannel) { + rv = httpChannel->SetReferrer(doc->GetDocumentURI()); + NS_ENSURE_SUCCESS(rv,rv); + if (aPostStream) { // XXX it's a bit of a hack to rewind the postdata stream // here but it has to be done in case the post data is // being reused multiple times. nsCOMPtr<nsISeekableStream> postDataSeekable(do_QueryInterface(aPostStream)); if (postDataSeekable) postDataSeekable->Seek(nsISeekableStream::NS_SEEK_SET, 0); nsCOMPtr<nsIUploadChannel> uploadChannel(do_QueryInterface(httpChannel)); NS_ASSERTION(uploadChannel, "http must support nsIUploadChannel"); uploadChannel->SetUploadStream(aPostStream, EmptyCString(), -1); } - if (aHeadersData) + if (aHeadersData) { rv = AddHeadersToChannel(aHeadersData, aHeadersDataLen, httpChannel); + NS_ENSURE_SUCCESS(rv,rv); + } } rv = channel->AsyncOpen(listenerPeer, nsnull); if (NS_SUCCEEDED(rv)) listenerPeer->TrackRequest(channel); return rv; } // Called by GetURL and PostURL
--- a/dom/plugins/test/mochitest/Makefile.in +++ b/dom/plugins/test/mochitest/Makefile.in @@ -59,16 +59,17 @@ include $(topsrcdir)/config/rules.mk loremipsum_nocache.txt \ loremipsum_nocache.txt^headers^ \ post.sjs \ pluginstream.js \ plugin_window.html \ test_painting.html \ test_pluginstream_err.html \ test_pluginstream_src.html \ + test_pluginstream_src_dynamic.html \ test_pluginstream_geturl.html \ test_pluginstream_geturlnotify.html \ test_pluginstream_asfile.html \ test_pluginstream_asfileonly.html \ test_pluginstream_post.html \ test_pluginstream_poststream.html \ test_pluginstream_seek.html \ test_pluginstream_newstream.html \
--- a/dom/plugins/test/mochitest/pluginstream.js +++ b/dom/plugins/test/mochitest/pluginstream.js @@ -1,21 +1,24 @@ SimpleTest.waitForExplicitFinish(); function frameLoaded() { var testframe = document.getElementById('testframe'); var embed = document.getElementsByTagName('embed')[0]; + if (undefined === embed) + embed = document.getElementsByTagName('object')[0]; try { var content = testframe.contentDocument.body.innerHTML; if (!content.length) return; var filename = embed.getAttribute("src") || embed.getAttribute("geturl") || - embed.getAttribute("geturlnotify"); + embed.getAttribute("geturlnotify") || + embed.getAttribute("data"); var req = new XMLHttpRequest(); req.open('GET', filename, false); req.overrideMimeType('text/plain; charset=x-user-defined'); req.send(null); is(req.status, 200, "bad XMLHttpRequest status"); is(content, req.responseText.replace(/\r\n/g, "\n"), "content doesn't match");
--- a/dom/plugins/test/mochitest/test_pluginstream_poststream.html +++ b/dom/plugins/test/mochitest/test_pluginstream_poststream.html @@ -19,9 +19,9 @@ - plugin via NPP_NewStream. Once this stream is received, it's displayed - in a frame in the browser via a call to NPN_GetURL. --> <embed src="loremipsum.txt" streammode="normal" frame="testframe" posturl="post.sjs" postmode="stream" id="embedtest" style="width: 400px; height: 100px;" type="application/x-test"></embed> </body> -</html> \ No newline at end of file +</html>
new file mode 100644 --- /dev/null +++ b/dom/plugins/test/mochitest/test_pluginstream_src_dynamic.html @@ -0,0 +1,39 @@ +<html> +<head> + <title>NPAPI src="" NPStream Test</title> + <script type="text/javascript" + src="/tests/SimpleTest/SimpleTest.js"></script> + <script type="text/javascript" + src="pluginstream.js"></script> + <link rel="stylesheet" type="text/css" + href="/tests/SimpleTest/test.css" /> +</head> +<body> + <p id="display"></p> + + <iframe id="testframe" name="testframe" onload="frameLoaded()"></iframe> + + <!-- + - A stream is sent to the browser via NPP_NewStream, NP_NORMAL. + - The plugin reports that data can only be sent to it in 100-byte + - chunks. When NPP_DestroyStream is called, the plugin sends the stream + - content back to the browser by passing it as a data: url to + - NPN_GetURL, using a frame, so that the stream content should + - be displayed in the frame in the browser. + - + - We create the object element dynamically, which in some cases has caused us to deliver the data="" + - stream twice. This verifies that we only deliver the data="" stream once. + --> + + <script type="text/javascript"> + var e = document.createElement('object'); + e.setAttribute('data', 'loremipsum.xtest'); + e.setAttribute('type', 'application/x-test'); + e.setAttribute('streammode', 'normal'); + e.setAttribute('streamchunksize', '100'); + e.setAttribute('frame', 'testframe'); + e.setAttribute('style', 'width: 400px; height: 100px;'); + document.body.appendChild(e); + </script> +</body> +</html>
--- a/dom/plugins/test/testplugin/nptest.cpp +++ b/dom/plugins/test/testplugin/nptest.cpp @@ -1028,16 +1028,20 @@ NPP_NewStream(NPP instance, NPMIMEType t if (instanceData->streamBufSize) { free(instanceData->streamBuf); instanceData->streamBufSize = 0; if (instanceData->testFunction == FUNCTION_NPP_POSTURL && instanceData->postMode == POSTMODE_STREAM) { instanceData->testFunction = FUNCTION_NPP_GETURL; } + else { + // We already got a stream and didn't ask for another one. + instanceData->err << "Received unexpected multiple NPP_NewStream"; + } } } return NPERR_NO_ERROR; } NPError NPP_DestroyStream(NPP instance, NPStream* stream, NPReason reason) {
--- a/dom/telephony/Telephony.cpp +++ b/dom/telephony/Telephony.cpp @@ -197,16 +197,27 @@ DOMCI_DATA(Telephony, Telephony) NS_IMPL_ISUPPORTS1(Telephony::TelephoneCallback, nsITelephoneCallback) NS_IMETHODIMP Telephony::Dial(const nsAString& aNumber, nsIDOMTelephonyCall** aResult) { NS_ENSURE_ARG(!aNumber.IsEmpty()); + for (PRUint32 index = 0; index < mCalls.Length(); index++) { + const nsRefPtr<TelephonyCall>& tempCall = mCalls[index]; + if (tempCall->IsOutgoing() && + tempCall->CallState() < nsITelephone::CALL_STATE_CONNECTED) { + // One call has been dialed already and we only support one outgoing call + // at a time. + NS_WARNING("Only permitted to dial one call at a time!"); + return NS_ERROR_NOT_AVAILABLE; + } + } + nsresult rv = mTelephone->Dial(aNumber); NS_ENSURE_SUCCESS(rv, rv); nsRefPtr<TelephonyCall> call = TelephonyCall::Create(this, aNumber, nsITelephone::CALL_STATE_DIALING); NS_ASSERTION(call, "This should never fail!"); NS_ASSERTION(mCalls.Contains(call), "Should have auto-added new call!"); @@ -352,32 +363,59 @@ Telephony::SendTones(const nsAString& aT } NS_IMPL_EVENT_HANDLER(Telephony, incoming) NS_IMETHODIMP Telephony::CallStateChanged(PRUint32 aCallIndex, PRUint16 aCallState, const nsAString& aNumber) { - // If we already know about this call then just update its state. + NS_ASSERTION(aCallIndex != kOutgoingPlaceholderCallIndex, + "This should never happen!"); + + nsRefPtr<TelephonyCall> modifiedCall; + nsRefPtr<TelephonyCall> outgoingCall; + for (PRUint32 index = 0; index < mCalls.Length(); index++) { nsRefPtr<TelephonyCall>& tempCall = mCalls[index]; - if (tempCall->CallIndex() == aCallIndex) { - // This can call back and modify the array... Grab a real ref here. - nsRefPtr<TelephonyCall> call = tempCall; + if (tempCall->CallIndex() == kOutgoingPlaceholderCallIndex) { + NS_ASSERTION(!outgoingCall, "More than one outgoing call not supported!"); + NS_ASSERTION(tempCall->CallState() == nsITelephone::CALL_STATE_DIALING, + "Something really wrong here!"); + // Stash this for later, we may need it if aCallIndex doesn't match one of + // our other calls. + outgoingCall = tempCall; + } else if (tempCall->CallIndex() == aCallIndex) { + // We already know about this call so just update its state. + modifiedCall = tempCall; + outgoingCall = nsnull; + break; + } + } - // See if this should replace our current active call. - if (aCallState == nsITelephone::CALL_STATE_CONNECTED) { - SwitchActiveCall(call); - } + // If nothing matched above and the call state isn't incoming but we do have + // an outgoing call then we must be seeing a status update for our outgoing + // call. + if (!modifiedCall && + aCallState != nsITelephone::CALL_STATE_INCOMING && + outgoingCall) { + outgoingCall->UpdateCallIndex(aCallIndex); + modifiedCall.swap(outgoingCall); + } - // Change state. - call->ChangeState(aCallState); - return NS_OK; + if (modifiedCall) { + // Change state. + modifiedCall->ChangeState(aCallState); + + // See if this should replace our current active call. + if (aCallState == nsITelephone::CALL_STATE_CONNECTED) { + SwitchActiveCall(modifiedCall); } + + return NS_OK; } // Didn't know anything about this call before now, must be incoming. NS_ASSERTION(aCallState == nsITelephone::CALL_STATE_INCOMING, "Serious logic problem here!"); nsRefPtr<TelephonyCall> call = TelephonyCall::Create(this, aNumber, aCallState, aCallIndex); @@ -429,41 +467,56 @@ NS_NewTelephony(nsPIDOMWindow* aWindow, NS_ASSERTION(aWindow, "Null pointer!"); // Make sure we're dealing with an inner window. nsPIDOMWindow* innerWindow = aWindow->IsInnerWindow() ? aWindow : aWindow->GetCurrentInnerWindow(); NS_ENSURE_TRUE(innerWindow, NS_ERROR_FAILURE); + // Make sure we're being called from a window that we have permission to + // access. if (!nsContentUtils::CanCallerAccess(innerWindow)) { return NS_ERROR_DOM_SECURITY_ERR; } + // Need the document in order to make security decisions. nsCOMPtr<nsIDocument> document = do_QueryInterface(innerWindow->GetExtantDocument()); NS_ENSURE_TRUE(document, NS_NOINTERFACE); - nsCOMPtr<nsIURI> documentURI; - nsresult rv = document->NodePrincipal()->GetURI(getter_AddRefs(documentURI)); - NS_ENSURE_SUCCESS(rv, rv); + // Do security checks. We assume that chrome is always allowed and we also + // allow a single page specified by preferences. + if (!nsContentUtils::IsSystemPrincipal(document->NodePrincipal())) { + nsCOMPtr<nsIURI> documentURI; + nsresult rv = + document->NodePrincipal()->GetURI(getter_AddRefs(documentURI)); + NS_ENSURE_SUCCESS(rv, rv); - nsCString documentURL; - rv = documentURI->GetSpec(documentURL); - NS_ENSURE_SUCCESS(rv, rv); + nsCString documentURL; + rv = documentURI->GetSpec(documentURL); + NS_ENSURE_SUCCESS(rv, rv); - nsCString phoneAppURL; - rv = Preferences::GetCString(DOM_TELEPHONY_APP_PHONE_URL_PREF, &phoneAppURL); - NS_ENSURE_SUCCESS(rv, rv); + // The pref may not exist but in that case we deny access just as we do if + // the url doesn't match. + nsCString phoneAppURL; + if (NS_FAILED(Preferences::GetCString(DOM_TELEPHONY_APP_PHONE_URL_PREF, + &phoneAppURL)) || + !phoneAppURL.Equals(documentURL, + nsCaseInsensitiveCStringComparator())) { + *aTelephony = nsnull; + return NS_OK; + } + } - nsRefPtr<Telephony> telephony; - if (phoneAppURL.Equals(documentURL, nsCaseInsensitiveCStringComparator())) { - nsIInterfaceRequestor* ireq = SystemWorkerManager::GetInterfaceRequestor(); - NS_ENSURE_TRUE(ireq, NS_ERROR_UNEXPECTED); + // Security checks passed, make a telephony object. + nsIInterfaceRequestor* ireq = SystemWorkerManager::GetInterfaceRequestor(); + NS_ENSURE_TRUE(ireq, NS_ERROR_UNEXPECTED); - nsCOMPtr<nsITelephone> telephone = do_GetInterface(ireq); - NS_ENSURE_TRUE(telephone, NS_ERROR_UNEXPECTED); + nsCOMPtr<nsITelephone> telephone = do_GetInterface(ireq); + NS_ENSURE_TRUE(telephone, NS_ERROR_UNEXPECTED); - telephony = Telephony::Create(innerWindow, telephone); - } + nsRefPtr<Telephony> telephony = Telephony::Create(innerWindow, telephone); + NS_ENSURE_TRUE(telephony, NS_ERROR_UNEXPECTED); + telephony.forget(aTelephony); return NS_OK; }
--- a/dom/telephony/TelephonyCall.cpp +++ b/dom/telephony/TelephonyCall.cpp @@ -110,16 +110,20 @@ TelephonyCall::ChangeStateInternal(PRUin break; default: NS_NOTREACHED("Unknown state!"); } mState = stateString; mCallState = aCallState; + if (aCallState == nsITelephone::CALL_STATE_DIALING) { + mOutgoing = true; + } + if (aCallState == nsITelephone::CALL_STATE_DISCONNECTED) { NS_ASSERTION(mLive, "Should be live!"); mTelephony->RemoveCall(this); mLive = false; } else if (!mLive) { mTelephony->AddCall(this); mLive = true; }
--- a/dom/telephony/TelephonyCall.h +++ b/dom/telephony/TelephonyCall.h @@ -65,27 +65,28 @@ class TelephonyCall : public nsDOMEventT nsRefPtr<Telephony> mTelephony; nsString mNumber; nsString mState; PRUint32 mCallIndex; PRUint16 mCallState; bool mLive; + bool mOutgoing; public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIDOMTELEPHONYCALL NS_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetWrapperCache::) NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TelephonyCall, nsDOMEventTargetWrapperCache) static already_AddRefed<TelephonyCall> Create(Telephony* aTelephony, const nsAString& aNumber, PRUint16 aCallState, - PRUint32 aCallIndex = PR_UINT32_MAX); + PRUint32 aCallIndex = kOutgoingPlaceholderCallIndex); nsIDOMEventTarget* ToIDOMEventTarget() const { return static_cast<nsDOMEventTargetWrapperCache*>( const_cast<TelephonyCall*>(this)); } @@ -102,26 +103,40 @@ public: } PRUint32 CallIndex() const { return mCallIndex; } + void + UpdateCallIndex(PRUint32 aCallIndex) + { + NS_ASSERTION(mCallIndex == kOutgoingPlaceholderCallIndex, + "Call index should not be set!"); + mCallIndex = aCallIndex; + } + PRUint16 CallState() const { return mCallState; } + bool + IsOutgoing() const + { + return mOutgoing; + } + private: TelephonyCall() - : mCallIndex(PR_UINT32_MAX), mCallState(nsITelephone::CALL_STATE_UNKNOWN), - mLive(false) + : mCallIndex(kOutgoingPlaceholderCallIndex), + mCallState(nsITelephone::CALL_STATE_UNKNOWN), mLive(false), mOutgoing(false) { } ~TelephonyCall() { } void ChangeStateInternal(PRUint16 aCallState, bool aFireEvents); };
--- a/dom/telephony/TelephonyCommon.h +++ b/dom/telephony/TelephonyCommon.h @@ -55,14 +55,18 @@ #define USING_TELEPHONY_NAMESPACE \ using namespace mozilla::dom::telephony; class nsIDOMTelephony; class nsIDOMTelephonyCall; BEGIN_TELEPHONY_NAMESPACE +enum { + kOutgoingPlaceholderCallIndex = PR_UINT32_MAX +}; + class Telephony; class TelephonyCall; END_TELEPHONY_NAMESPACE #endif // mozilla_dom_telephony_telephonycommon_h__
--- a/dom/telephony/nsTelephonyWorker.js +++ b/dom/telephony/nsTelephonyWorker.js @@ -184,80 +184,75 @@ nsTelephonyWorker.prototype = { }, /** * Track the active call and update the audio system as its state changes. * * XXX Needs some more work to support hold/resume. */ _activeCall: null, - get activeCall() { - return this._activeCall; - }, - set activeCall(val) { - if (val && !this._activeCall) { - // Enable audio. - switch (val.state) { - case nsITelephone.CALL_STATE_INCOMING: - gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_RINGTONE; - break; - case nsITelephone.CALL_STATE_DIALING: // Fall through... - case nsITelephone.CALL_STATE_CONNECTED: - gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_IN_CALL; - gAudioManager.setForceForUse(nsIAudioManager.USE_COMMUNICATION, - nsIAudioManager.FORCE_NONE); - break; - default: - throw new Error("Invalid call state for active call: " + val.state); - } - } else if (!val && this._activeCall) { + updateCallAudioState: function updateCallAudioState() { + if (!this._activeCall) { // Disable audio. gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_NORMAL; + debug("No active call, put audio system into PHONE_STATE_NORMAL."); + return; } - this._activeCall = val; + switch (this._activeCall.state) { + case nsITelephone.CALL_STATE_INCOMING: + gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_RINGTONE; + debug("Incoming call, put audio system into PHONE_STATE_RINGTONE."); + break; + case nsITelephone.CALL_STATE_DIALING: // Fall through... + case nsITelephone.CALL_STATE_CONNECTED: + gAudioManager.phoneState = nsIAudioManager.PHONE_STATE_IN_CALL; + gAudioManager.setForceForUse(nsIAudioManager.USE_COMMUNICATION, + nsIAudioManager.FORCE_NONE); + debug("Active call, put audio system into PHONE_STATE_IN_CALL."); + break; + } }, /** * Handle call state changes by updating our current state and the audio * system. */ handleCallStateChange: function handleCallStateChange(call) { debug("handleCallStateChange: " + JSON.stringify(call)); call.state = convertRILCallState(call.state); - if (call.state == nsITelephone.CALL_STATE_INCOMING || - call.state == nsITelephone.CALL_STATE_DIALING || - call.state == nsITelephone.CALL_STATE_CONNECTED) { + if (call.state == nsITelephone.CALL_STATE_CONNECTED) { // This is now the active call. - this.activeCall = call; + this._activeCall = call; } + this.updateCallAudioState(); this._deliverCallback("callStateChanged", [call.callIndex, call.state, call.number]); }, /** * Handle call disconnects by updating our current state and the audio system. */ - handleCallDisconnected: function handleCallStateChange(call) { + handleCallDisconnected: function handleCallDisconnected(call) { debug("handleCallDisconnected: " + JSON.stringify(call)); - if (this.activeCall == call) { - // No loner active. - this.activeCall = null; + if (this._activeCall.callIndex == call.callIndex) { + this._activeCall = null; } + this.updateCallAudioState(); this._deliverCallback("callStateChanged", [call.callIndex, nsITelephone.CALL_STATE_DISCONNECTED, call.number]); }, /** * Handle calls delivered in response to a 'enumerateCalls' request. */ handleEnumerateCalls: function handleEnumerateCalls(calls) { debug("handleEnumerateCalls: " + JSON.stringify(calls)); let callback = this._enumerationCallbacks.shift(); - let activeCallIndex = this.activeCall ? this.activeCall.callIndex : -1; + let activeCallIndex = this._activeCall ? this._activeCall.callIndex : -1; for (let i in calls) { let call = calls[i]; let state = convertRILCallState(call.state); let keepGoing; try { keepGoing = callback.enumerateCallState(call.callIndex, state, call.number, call.callIndex == activeCallIndex); @@ -358,32 +353,35 @@ nsTelephonyWorker.prototype = { number: number, body: message}); }, _callbacks: null, _enumerationCallbacks: null, registerCallback: function registerCallback(callback) { - debug("Registering callback: " + callback); if (this._callbacks) { if (this._callbacks.indexOf(callback) != -1) { throw new Error("Already registered this callback!"); } } else { this._callbacks = []; } this._callbacks.push(callback); + debug("Registered callback: " + callback); }, unregisterCallback: function unregisterCallback(callback) { - debug("Unregistering callback: " + callback); - let index; - if (this._callbacks && (index = this._callbacks.indexOf(callback) != -1)) { + if (!this._callbacks) { + return; + } + let index = this._callbacks.indexOf(callback); + if (index != -1) { this._callbacks.splice(index, 1); + debug("Unregistered callback: " + callback); } }, enumerateCalls: function enumerateCalls(callback) { debug("Requesting enumeration of calls for callback: " + callback); this.worker.postMessage({type: "enumerateCalls"}); if (!this._enumerationCallbacks) { this._enumerationCallbacks = [];
--- a/dom/tests/mochitest/geolocation/test_clearWatch.html +++ b/dom/tests/mochitest/geolocation/test_clearWatch.html @@ -27,33 +27,41 @@ var hasBeenCleared = false; var successWasCalledAfterClear = false; function failureCallback(error) { ok(0, "we should not be seeing failures from this watchPosition"); } function successCallback(position) { + ok(true, "successCallback was called, hasBeenCleared=" + hasBeenCleared + + ", successWasCalledAfterClear=" + successWasCalledAfterClear); if (hasBeenCleared == true) { successWasCalledAfterClear = true; } SimpleTest.executeSoon(clearWatch); } function clearWatch() { + ok(true, "clearWatch was called, hasBeenCleared=" + hasBeenCleared + + ", successWasCalledAfterClear=" + successWasCalledAfterClear); navigator.geolocation.clearWatch(watchID); hasBeenCleared = true; SimpleTest.executeSoon(testAccepted); } function testAccepted() { + ok(true, "testAccepted was called, hasBeenCleared=" + hasBeenCleared + + ", successWasCalledAfterClear=" + successWasCalledAfterClear); ok(!successWasCalledAfterClear, "The successCallback should not be called after clear"); reset_prompt(); SimpleTest.finish(); } +ok(true, "Getting the watchPosition"); watchID = navigator.geolocation.watchPosition(successCallback, failureCallback, null); +ok(true, "Waiting"); </script> </pre> </body> </html>
--- a/gfx/skia/Makefile.in +++ b/gfx/skia/Makefile.in @@ -230,17 +230,17 @@ CPPSRCS = \ SkGlyphCache.cpp \ SkGraphics.cpp \ SkLineClipper.cpp \ SkMallocPixelRef.cpp \ SkMask.cpp \ SkMaskFilter.cpp \ SkMath.cpp \ SkMatrix.cpp \ - SkMemory_stdlib.cpp \ + SkMemory_malloc.cpp \ SkMetaData.cpp \ SkPackBits.cpp \ SkPaint.cpp \ SkPath.cpp \ SkPathEffect.cpp \ SkPathHeap.cpp \ SkPathMeasure.cpp \ SkPicture.cpp \
--- a/hal/gonk/GonkHal.cpp +++ b/hal/gonk/GonkHal.cpp @@ -308,17 +308,17 @@ GetCurrentBatteryInformation(hal::Batter } namespace { /** * RAII class to help us remember to close file descriptors. */ const char *screenEnabledFilename = "/sys/power/state"; -const char *screenBrightnessFilename = "/sys/class/backlight/pwm-backlight/brightness"; +const char *screenBrightnessFilename = "/sys/class/leds/lcd-backlight/brightness"; template<ssize_t n> bool ReadFromFile(const char *filename, char (&buf)[n]) { int fd = open(filename, O_RDONLY); ScopedClose autoClose(fd); if (fd < 0) { HAL_LOG(("Unable to open file %s.", filename));
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/basic/bug717208.js @@ -0,0 +1,15 @@ +var count = 0; +var a = {__noSuchMethod__: function() { count++; } } + +function f() { + for (var i = 0; i < 10; i++) { + try { + a.b(); + } catch (e) { + assertEq(true, false); + } + } +} +f(); + +assertEq(count, 10);
--- a/js/src/jslock.h +++ b/js/src/jslock.h @@ -139,17 +139,17 @@ extern JSBool js_IsRuntimeLocked(JSRunti #else /* !JS_THREADSAFE */ #define JS_ATOMIC_INCREMENT(p) (++*(p)) #define JS_ATOMIC_DECREMENT(p) (--*(p)) #define JS_ATOMIC_ADD(p,v) (*(p) += (v)) #define JS_ATOMIC_SET(p,v) (*(p) = (v)) -#define js_CurrentThreadId() (void*)NULL +#define js_CurrentThreadId() ((void*)NULL) #define JS_NEW_LOCK() NULL #define JS_DESTROY_LOCK(l) ((void)0) #define JS_ACQUIRE_LOCK(l) ((void)0) #define JS_RELEASE_LOCK(l) ((void)0) #define JS_LOCK(cx, tl) ((void)0) #define JS_UNLOCK(cx, tl) ((void)0) #define JS_NEW_CONDVAR(l) NULL
--- a/js/src/jswrapper.cpp +++ b/js/src/jswrapper.cpp @@ -854,26 +854,28 @@ SecurityWrapper<Base>::SecurityWrapper(u : Base(flags) {} template <class Base> bool SecurityWrapper<Base>::nativeCall(JSContext *cx, JSObject *wrapper, Class *clasp, Native native, CallArgs args) { - /* Let ProxyHandler report the error. */ - DebugOnly<bool> ret = ProxyHandler::nativeCall(cx, wrapper, clasp, native, args); - JS_ASSERT(!ret); - return false; + /* + * Let this through until compartment-per-global lets us have stronger + * invariants wrt document.domain (bug 714547). + */ + return Base::nativeCall(cx, wrapper, clasp, native, args); } template <class Base> bool SecurityWrapper<Base>::objectClassIs(JSObject *obj, ESClassValue classValue, JSContext *cx) { - /* Let ProxyHandler say 'no'. */ - bool ret = ProxyHandler::objectClassIs(obj, classValue, cx); - JS_ASSERT(!ret && !cx->isExceptionPending()); - return ret; + /* + * Let this through until compartment-per-global lets us have stronger + * invariants wrt document.domain (bug 714547). + */ + return Base::objectClassIs(obj, classValue, cx); } template class js::SecurityWrapper<Wrapper>; template class js::SecurityWrapper<CrossCompartmentWrapper>;
--- a/js/src/methodjit/Compiler.cpp +++ b/js/src/methodjit/Compiler.cpp @@ -4636,51 +4636,56 @@ mjit::Compiler::jsop_getprop(PropertyNam */ RegisterID objReg = frame.copyDataIntoReg(top); RegisterID shapeReg = frame.allocReg(); RESERVE_IC_SPACE(masm); PICGenInfo pic(ic::PICInfo::GET, JSOp(*PC)); - /* Guard that the type is an object. */ - Label typeCheck; - if (doTypeCheck && !top->isTypeKnown()) { - RegisterID reg = frame.tempRegForType(top); - pic.typeReg = reg; - - /* Start the hot path where it's easy to patch it. */ - pic.fastPathStart = masm.label(); - Jump j = masm.testObject(Assembler::NotEqual, reg); - typeCheck = masm.label(); - RETURN_IF_OOM(false); - - pic.typeCheck = stubcc.linkExit(j, Uses(1)); - pic.hasTypeCheck = true; - } else { - pic.fastPathStart = masm.label(); - pic.hasTypeCheck = false; - pic.typeReg = Registers::ReturnReg; - } - /* * If this access has been on a shape with a getter hook, make preparations * so that we can generate a stub to call the hook directly (rather than be * forced to make a stub call). Sync the stack up front and kill all * registers so that PIC stubs can contain calls, and always generate a * type barrier if inference is enabled (known property types do not * reflect properties with getter hooks). */ pic.canCallHook = pic.forcedTypeBarrier = !forPrototype && JSOp(*PC) == JSOP_GETPROP && - name != cx->runtime->atomState.lengthAtom && analysis->getCode(PC).accessGetter; - if (pic.canCallHook) - frame.syncAndKillEverything(); + + /* Guard that the type is an object. */ + Label typeCheck; + if (doTypeCheck && !top->isTypeKnown()) { + RegisterID reg = frame.tempRegForType(top); + pic.typeReg = reg; + + if (pic.canCallHook) { + PinRegAcrossSyncAndKill p1(frame, reg); + frame.syncAndKillEverything(); + } + + /* Start the hot path where it's easy to patch it. */ + pic.fastPathStart = masm.label(); + Jump j = masm.testObject(Assembler::NotEqual, reg); + typeCheck = masm.label(); + RETURN_IF_OOM(false); + + pic.typeCheck = stubcc.linkExit(j, Uses(1)); + pic.hasTypeCheck = true; + } else { + if (pic.canCallHook) + frame.syncAndKillEverything(); + + pic.fastPathStart = masm.label(); + pic.hasTypeCheck = false; + pic.typeReg = Registers::ReturnReg; + } pic.shapeReg = shapeReg; pic.name = name; /* Guard on shape. */ masm.loadShape(objReg, shapeReg); pic.shapeGuard = masm.label();
--- a/js/src/methodjit/PolyIC.cpp +++ b/js/src/methodjit/PolyIC.cpp @@ -1830,19 +1830,33 @@ class BindNameCompiler : public PICStubC LookupStatus status = generateStub(obj); if (status == Lookup_Error) return NULL; return obj; } }; +static void JS_FASTCALL +DisabledGetPropIC(VMFrame &f, ic::PICInfo *pic) +{ + stubs::GetProp(f, pic->name); +} + +static void JS_FASTCALL +DisabledGetPropNoCacheIC(VMFrame &f, ic::PICInfo *pic) +{ + stubs::GetPropNoCache(f, pic->name); +} + static inline void -GetPropWithStub(VMFrame &f, ic::PICInfo *pic, VoidStubPIC stub) +GetPropMaybeCached(VMFrame &f, ic::PICInfo *pic, bool cached) { + VoidStubPIC stub = cached ? DisabledGetPropIC : DisabledGetPropNoCacheIC; + JSScript *script = f.fp()->script(); PropertyName *name = pic->name; if (name == f.cx->runtime->atomState.lengthAtom) { if (f.regs.sp[-1].isMagic(JS_LAZY_ARGUMENTS)) { f.regs.sp[-1].setInt32(f.regs.fp()->numActualArgs()); return; } else if (!f.regs.sp[-1].isPrimitive()) { @@ -1902,44 +1916,37 @@ GetPropWithStub(VMFrame &f, ic::PICInfo if (!monitor.recompiled() && pic->shouldUpdate(f.cx)) { GetPropCompiler cc(f, script, obj, *pic, name, stub); if (!cc.update()) THROW(); } Value v; - if (!GetPropertyGenericMaybeCallXML(f.cx, JSOp(*f.pc()), obj, ATOM_TO_JSID(name), &v)) - THROW(); + if (cached) { + if (!GetPropertyOperation(f.cx, f.pc(), ObjectValue(*obj), &v)) + THROW(); + } else { + if (!obj->getProperty(f.cx, name, &v)) + THROW(); + } f.regs.sp[-1] = v; } -static void JS_FASTCALL -DisabledGetPropIC(VMFrame &f, ic::PICInfo *pic) -{ - stubs::GetProp(f, pic->name); -} - -static void JS_FASTCALL -DisabledGetPropNoCacheIC(VMFrame &f, ic::PICInfo *pic) -{ - stubs::GetPropNoCache(f, pic->name); -} - void JS_FASTCALL ic::GetProp(VMFrame &f, ic::PICInfo *pic) { - GetPropWithStub(f, pic, DisabledGetPropIC); + GetPropMaybeCached(f, pic, /* cache = */ true); } void JS_FASTCALL ic::GetPropNoCache(VMFrame &f, ic::PICInfo *pic) { - GetPropWithStub(f, pic, DisabledGetPropNoCacheIC); + GetPropMaybeCached(f, pic, /* cache = */ false); } template <JSBool strict> static void JS_FASTCALL DisabledSetPropIC(VMFrame &f, ic::PICInfo *pic) { stubs::SetName<strict>(f, pic->name); }
--- a/js/xpconnect/wrappers/FilteringWrapper.cpp +++ b/js/xpconnect/wrappers/FilteringWrapper.cpp @@ -1,32 +1,33 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- - * vim: set ts=4 sw=4 et tw=99 ft=cpp: - * - * ***** BEGIN LICENSE BLOCK ***** +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* vim: set ts=4 sw=4 et tw=99 ft=cpp: */ +/* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code, released * June 24, 2010. * * The Initial Developer of the Original Code is - * The Mozilla Foundation + * the Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. * * Contributor(s): - * Andreas Gal <gal@mozilla.com> + * Andreas Gal <gal@mozilla.com> * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your
--- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -7501,19 +7501,20 @@ PresShell::ProcessReflowCommands(bool aI // We only unlock if we're out of reflows. It's pointless // to unlock if reflows are still pending, since reflows // are just going to thrash the frames around some more. By // waiting we avoid an overeager "jitter" effect. mShouldUnsuppressPainting = false; UnsuppressAndInvalidate(); } - if (mDocument->GetRootElement() && mDocument->GetRootElement()->IsXUL()) { - mozilla::Telemetry::AccumulateTimeDelta(Telemetry::XUL_REFLOW_MS, - timerStart); + if (mDocument->GetRootElement()) { + Telemetry::ID id = (mDocument->GetRootElement()->IsXUL() + ? Telemetry::XUL_REFLOW_MS : Telemetry::HTML_REFLOW_MS); + Telemetry::AccumulateTimeDelta(id, timerStart); } return !interrupted; } #ifdef MOZ_XUL /* * It's better to add stuff to the |DidSetStyleContext| method of the
--- a/layout/build/nsLayoutModule.cpp +++ b/layout/build/nsLayoutModule.cpp @@ -109,17 +109,17 @@ #include "nsViewsCID.h" #include "nsViewManager.h" #include "nsContentCreatorFunctions.h" // DOM includes #include "nsDOMException.h" #include "nsDOMFileReader.h" #include "nsFormData.h" -#include "nsFileDataProtocolHandler.h" +#include "nsBlobProtocolHandler.h" #include "nsGlobalWindowCommands.h" #include "nsIControllerCommandTable.h" #include "nsJSProtocolHandler.h" #include "nsScriptNameSpaceManager.h" #include "nsIControllerContext.h" #include "nsDOMScriptObjectFactory.h" #include "nsDOMStorage.h" #include "nsJSON.h" @@ -269,17 +269,17 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(txMozilla NS_GENERIC_AGGREGATED_CONSTRUCTOR_INIT(nsXPathEvaluator, Init) NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(txNodeSetAdaptor, Init) NS_GENERIC_FACTORY_CONSTRUCTOR(nsDOMSerializer) NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsXMLHttpRequest, Init) NS_GENERIC_FACTORY_CONSTRUCTOR(nsEventSource) NS_GENERIC_FACTORY_CONSTRUCTOR(nsWebSocket) NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsDOMFileReader, Init) NS_GENERIC_FACTORY_CONSTRUCTOR(nsFormData) -NS_GENERIC_FACTORY_CONSTRUCTOR(nsFileDataProtocolHandler) +NS_GENERIC_FACTORY_CONSTRUCTOR(nsBlobProtocolHandler) NS_GENERIC_FACTORY_CONSTRUCTOR(nsDOMParser) NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsDOMStorageManager, nsDOMStorageManager::GetInstance) NS_GENERIC_FACTORY_CONSTRUCTOR(nsChannelPolicy) NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(IndexedDatabaseManager, IndexedDatabaseManager::FactoryCreate) #ifdef MOZ_B2G_RIL NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(SystemWorkerManager, @@ -733,17 +733,17 @@ NS_DEFINE_NAMED_CID(NS_VIDEODOCUMENT_CID #endif NS_DEFINE_NAMED_CID(NS_STYLESHEETSERVICE_CID); NS_DEFINE_NAMED_CID(TRANSFORMIIX_XSLT_PROCESSOR_CID); NS_DEFINE_NAMED_CID(TRANSFORMIIX_XPATH_EVALUATOR_CID); NS_DEFINE_NAMED_CID(TRANSFORMIIX_NODESET_CID); NS_DEFINE_NAMED_CID(NS_XMLSERIALIZER_CID); NS_DEFINE_NAMED_CID(NS_FILEREADER_CID); NS_DEFINE_NAMED_CID(NS_FORMDATA_CID); -NS_DEFINE_NAMED_CID(NS_FILEDATAPROTOCOLHANDLER_CID); +NS_DEFINE_NAMED_CID(NS_BLOBPROTOCOLHANDLER_CID); NS_DEFINE_NAMED_CID(NS_XMLHTTPREQUEST_CID); NS_DEFINE_NAMED_CID(NS_EVENTSOURCE_CID); NS_DEFINE_NAMED_CID(NS_WEBSOCKET_CID); NS_DEFINE_NAMED_CID(NS_DOMPARSER_CID); NS_DEFINE_NAMED_CID(NS_DOMSTORAGE_CID); NS_DEFINE_NAMED_CID(NS_DOMSTORAGE2_CID); NS_DEFINE_NAMED_CID(NS_DOMSTORAGEMANAGER_CID); NS_DEFINE_NAMED_CID(NS_DOMJSON_CID); @@ -1004,17 +1004,17 @@ static const mozilla::Module::CIDEntry k #endif { &kNS_STYLESHEETSERVICE_CID, false, NULL, nsStyleSheetServiceConstructor }, { &kTRANSFORMIIX_XSLT_PROCESSOR_CID, false, NULL, txMozillaXSLTProcessorConstructor }, { &kTRANSFORMIIX_XPATH_EVALUATOR_CID, false, NULL, nsXPathEvaluatorConstructor }, { &kTRANSFORMIIX_NODESET_CID, false, NULL, txNodeSetAdaptorConstructor }, { &kNS_XMLSERIALIZER_CID, false, NULL, nsDOMSerializerConstructor }, { &kNS_FILEREADER_CID, false, NULL, nsDOMFileReaderConstructor }, { &kNS_FORMDATA_CID, false, NULL, nsFormDataConstructor }, - { &kNS_FILEDATAPROTOCOLHANDLER_CID, false, NULL, nsFileDataProtocolHandlerConstructor }, + { &kNS_BLOBPROTOCOLHANDLER_CID, false, NULL, nsBlobProtocolHandlerConstructor }, { &kNS_XMLHTTPREQUEST_CID, false, NULL, nsXMLHttpRequestConstructor }, { &kNS_EVENTSOURCE_CID, false, NULL, nsEventSourceConstructor }, { &kNS_WEBSOCKET_CID, false, NULL, nsWebSocketConstructor }, { &kNS_DOMPARSER_CID, false, NULL, nsDOMParserConstructor }, { &kNS_DOMSTORAGE_CID, false, NULL, NS_NewDOMStorage }, { &kNS_DOMSTORAGE2_CID, false, NULL, NS_NewDOMStorage2 }, { &kNS_DOMSTORAGEMANAGER_CID, false, NULL, nsDOMStorageManagerConstructor }, { &kNS_DOMJSON_CID, false, NULL, NS_NewJSON }, @@ -1140,17 +1140,17 @@ static const mozilla::Module::ContractID { PLUGIN_DLF_CONTRACTID, &kNS_PLUGINDOCLOADERFACTORY_CID }, { NS_STYLESHEETSERVICE_CONTRACTID, &kNS_STYLESHEETSERVICE_CID }, { TRANSFORMIIX_XSLT_PROCESSOR_CONTRACTID, &kTRANSFORMIIX_XSLT_PROCESSOR_CID }, { NS_XPATH_EVALUATOR_CONTRACTID, &kTRANSFORMIIX_XPATH_EVALUATOR_CID }, { TRANSFORMIIX_NODESET_CONTRACTID, &kTRANSFORMIIX_NODESET_CID }, { NS_XMLSERIALIZER_CONTRACTID, &kNS_XMLSERIALIZER_CID }, { NS_FILEREADER_CONTRACTID, &kNS_FILEREADER_CID }, { NS_FORMDATA_CONTRACTID, &kNS_FORMDATA_CID }, - { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX FILEDATA_SCHEME, &kNS_FILEDATAPROTOCOLHANDLER_CID }, + { NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX BLOBURI_SCHEME, &kNS_BLOBPROTOCOLHANDLER_CID }, { NS_XMLHTTPREQUEST_CONTRACTID, &kNS_XMLHTTPREQUEST_CID }, { NS_EVENTSOURCE_CONTRACTID, &kNS_EVENTSOURCE_CID }, { NS_WEBSOCKET_CONTRACTID, &kNS_WEBSOCKET_CID }, { NS_DOMPARSER_CONTRACTID, &kNS_DOMPARSER_CID }, { "@mozilla.org/dom/storage;1", &kNS_DOMSTORAGE_CID }, { "@mozilla.org/dom/storage;2", &kNS_DOMSTORAGE2_CID }, { "@mozilla.org/dom/storagemanager;1", &kNS_DOMSTORAGEMANAGER_CID }, { "@mozilla.org/dom/json;1", &kNS_DOMJSON_CID },
--- a/layout/forms/nsICapturePicker.idl +++ b/layout/forms/nsICapturePicker.idl @@ -81,15 +81,15 @@ interface nsICapturePicker : nsISupports * * @return false if the requested mode can definitely not be captured, * true otherwise. */ boolean modeMayBeAvailable(in unsigned long mode); /** * Get the captured image/video/audio. This may be a data URI, file URI, - * or a moz-filedata reference URI. + * or a blob reference URI. */ readonly attribute nsIDOMFile file; // The MIME type of the captured content. Cannot be set after calling show() attribute AString type; };
--- a/layout/generic/nsSelection.cpp +++ b/layout/generic/nsSelection.cpp @@ -203,17 +203,20 @@ public: // SELECTION_WHOLE_SELECTION the rect contains both the anchor and focus // region rects. nsIFrame* GetSelectionAnchorGeometry(SelectionRegion aRegion, nsRect *aRect); // Returns the position of the region (SELECTION_ANCHOR_REGION or // SELECTION_FOCUS_REGION only), and frame that that position is relative to. // The 'position' is a zero-width rectangle. nsIFrame* GetSelectionEndPointGeometry(SelectionRegion aRegion, nsRect *aRect); - nsresult PostScrollSelectionIntoViewEvent(SelectionRegion aRegion, bool aFirstAncestorOnly); + nsresult PostScrollSelectionIntoViewEvent(SelectionRegion aRegion, + bool aFirstAncestorOnly, + PRInt16 aVPercent, + PRInt16 aHPercent); enum { SCROLL_SYNCHRONOUS = 1<<1, SCROLL_FIRST_ANCESTOR_ONLY = 1<<2, SCROLL_DO_FLUSH = 1<<3 }; // aDoFlush only matters if aIsSynchronous is true. If not, we'll just flush // when the scroll event fires so we make sure to scroll to the right place. nsresult ScrollIntoView(SelectionRegion aRegion, @@ -280,26 +283,32 @@ private: class ScrollSelectionIntoViewEvent; friend class ScrollSelectionIntoViewEvent; class ScrollSelectionIntoViewEvent : public nsRunnable { public: NS_DECL_NSIRUNNABLE ScrollSelectionIntoViewEvent(nsTypedSelection *aTypedSelection, SelectionRegion aRegion, + PRInt16 aVScroll, + PRInt16 aHScroll, bool aFirstAncestorOnly) : mTypedSelection(aTypedSelection), mRegion(aRegion), + mVerticalScroll(aVScroll), + mHorizontalScroll(aHScroll), mFirstAncestorOnly(aFirstAncestorOnly) { NS_ASSERTION(aTypedSelection, "null parameter"); } void Revoke() { mTypedSelection = nsnull; } private: nsTypedSelection *mTypedSelection; SelectionRegion mRegion; + PRInt16 mVerticalScroll; + PRInt16 mHorizontalScroll; bool mFirstAncestorOnly; }; void setAnchorFocusRange(PRInt32 aIndex); // pass in index into mRanges; // negative value clears // mAnchorFocusRange nsresult SelectAllFramesForContent(nsIContentIterator *aInnerIter, nsIContent *aContent, @@ -1146,32 +1155,30 @@ nsFrameSelection::MoveCaret(PRUint32 case nsIDOMKeyEvent::DOM_VK_UP : { const nsRange* anchorFocusRange = sel->GetAnchorFocusRange(); if (anchorFocusRange) { sel->Collapse(anchorFocusRange->GetStartParent(), anchorFocusRange->StartOffset()); } mHint = HINTRIGHT; - sel->ScrollIntoView(nsISelectionController::SELECTION_FOCUS_REGION, - false, false); + sel->ScrollIntoView(nsISelectionController::SELECTION_FOCUS_REGION); return NS_OK; } case nsIDOMKeyEvent::DOM_VK_RIGHT : case nsIDOMKeyEvent::DOM_VK_DOWN : { const nsRange* anchorFocusRange = sel->GetAnchorFocusRange(); if (anchorFocusRange) { sel->Collapse(anchorFocusRange->GetEndParent(), anchorFocusRange->EndOffset()); } mHint = HINTLEFT; - sel->ScrollIntoView(nsISelectionController::SELECTION_FOCUS_REGION, - false, false); + sel->ScrollIntoView(nsISelectionController::SELECTION_FOCUS_REGION); return NS_OK; } } } nsIFrame *frame; PRInt32 offsetused = 0; result = sel->GetPrimaryFrameForFocusNode(&frame, &offsetused, @@ -1287,18 +1294,17 @@ nsFrameSelection::MoveCaret(PRUint32 if (!isBRFrame) { mHint = HINTLEFT; // We're now at the end of the frame to the left. } result = NS_OK; } if (NS_SUCCEEDED(result)) { result = mDomSelections[index]-> - ScrollIntoView(nsISelectionController::SELECTION_FOCUS_REGION, - false, false); + ScrollIntoView(nsISelectionController::SELECTION_FOCUS_REGION); } return result; } //END nsFrameSelection methods @@ -1961,27 +1967,31 @@ nsFrameSelection::ScrollSelectionIntoVie { PRInt8 index = GetIndexFromSelectionType(aType); if (index < 0) return NS_ERROR_INVALID_ARG; if (!mDomSelections[index]) return NS_ERROR_NULL_POINTER; + PRInt16 verticalScroll = PRInt16(NS_PRESSHELL_SCROLL_ANYWHERE); PRInt32 flags = nsTypedSelection::SCROLL_DO_FLUSH; if (aFlags & nsISelectionController::SCROLL_SYNCHRONOUS) { flags |= nsTypedSelection::SCROLL_SYNCHRONOUS; } else if (aFlags & nsISelectionController::SCROLL_FIRST_ANCESTOR_ONLY) { flags |= nsTypedSelection::SCROLL_FIRST_ANCESTOR_ONLY; } + if (aFlags & nsISelectionController::SCROLL_CENTER_VERTICALLY) { + verticalScroll = PRInt16(NS_PRESSHELL_SCROLL_CENTER); + } // After ScrollSelectionIntoView(), the pending notifications might be // flushed and PresShell/PresContext/Frames may be dead. See bug 418470. return mDomSelections[index]->ScrollIntoView(aRegion, - PRInt16(NS_PRESSHELL_SCROLL_ANYWHERE), + verticalScroll, PRInt16(NS_PRESSHELL_SCROLL_ANYWHERE), flags); } nsresult nsFrameSelection::RepaintSelection(SelectionType aType) const { PRInt8 index = GetIndexFromSelectionType(aType); @@ -4829,18 +4839,17 @@ nsTypedSelection::RemoveRange(nsIDOMRang // Reset anchor to LAST range or clear it if there are no ranges. setAnchorFocusRange(cnt - 1); // When the selection is user-created it makes sense to scroll the range // into view. The spell-check selection, however, is created and destroyed // in the background. We don't want to scroll in this case or the view // might appear to be moving randomly (bug 337871). if (mType != nsISelectionController::SELECTION_SPELLCHECK && cnt > 0) - ScrollIntoView(nsISelectionController::SELECTION_FOCUS_REGION, false, - false); + ScrollIntoView(nsISelectionController::SELECTION_FOCUS_REGION); } if (!mFrameSelection) return NS_OK;//nothing to do return mFrameSelection->NotifySelectionListeners(GetType()); } @@ -5564,34 +5573,36 @@ nsTypedSelection::ScrollSelectionIntoVie PRInt32 flags = nsTypedSelection::SCROLL_DO_FLUSH | nsTypedSelection::SCROLL_SYNCHRONOUS; if (mFirstAncestorOnly) { flags |= nsTypedSelection::SCROLL_FIRST_ANCESTOR_ONLY; } mTypedSelection->mScrollEvent.Forget(); - mTypedSelection->ScrollIntoView(mRegion, - PRInt16(NS_PRESSHELL_SCROLL_ANYWHERE), - PRInt16(NS_PRESSHELL_SCROLL_ANYWHERE), - flags); + mTypedSelection->ScrollIntoView(mRegion, mVerticalScroll, + mHorizontalScroll, flags); return NS_OK; } nsresult -nsTypedSelection::PostScrollSelectionIntoViewEvent(SelectionRegion aRegion, bool aFirstAncestorOnly) +nsTypedSelection::PostScrollSelectionIntoViewEvent(SelectionRegion aRegion, + bool aFirstAncestorOnly, + PRInt16 aVPercent, + PRInt16 aHPercent) { // If we've already posted an event, revoke it and place a new one at the // end of the queue to make sure that any new pending reflow events are // processed before we scroll. This will insure that we scroll to the // correct place on screen. mScrollEvent.Revoke(); nsRefPtr<ScrollSelectionIntoViewEvent> ev = - new ScrollSelectionIntoViewEvent(this, aRegion, aFirstAncestorOnly); + new ScrollSelectionIntoViewEvent(this, aRegion, aVPercent, aHPercent, + aFirstAncestorOnly); nsresult rv = NS_DispatchToCurrentThread(ev); NS_ENSURE_SUCCESS(rv, rv); mScrollEvent = ev; return NS_OK; } NS_IMETHODIMP @@ -5611,17 +5622,18 @@ nsTypedSelection::ScrollIntoView(Selecti if (!mFrameSelection) return NS_OK;//nothing to do if (mFrameSelection->GetBatching()) return NS_OK; if (!(aFlags & nsTypedSelection::SCROLL_SYNCHRONOUS)) return PostScrollSelectionIntoViewEvent(aRegion, - !!(aFlags & nsTypedSelection::SCROLL_FIRST_ANCESTOR_ONLY)); + !!(aFlags & nsTypedSelection::SCROLL_FIRST_ANCESTOR_ONLY), + aVPercent, aHPercent); // // Shut the caret off before scrolling to avoid // leaving caret turds on the screen! // nsCOMPtr<nsIPresShell> presShell; result = GetPresShell(getter_AddRefs(presShell)); if (NS_FAILED(result) || !presShell)
--- a/layout/reftests/svg/as-image/img-blobBuilder-1.html +++ b/layout/reftests/svg/as-image/img-blobBuilder-1.html @@ -1,29 +1,29 @@ <!DOCTYPE html> <!-- This test checks to be sure we can render SVG-as-an-image - from a MozBlobBuilder-generated 'moz-filedata' URI. --> + from a MozBlobBuilder-generated 'blob' URI. --> <html class="reftest-wait"> <head> <script> function go() { - // Generate a moz-filedata URL encoding of an SVG document + // Generate a blob URL encoding of an SVG document var filedataURL = generateMozFiledataURL(); // Tell our img element to render the URL var img = document.getElementsByTagName("img")[0] img.src = filedataURL; // Once our img loads, take reftest snapshot. img.addEventListener("load", function() { document.documentElement.removeAttribute("class"); }); } - // Helper function -- returns a moz-filedata URL representing a + // Helper function -- returns a blob URL representing a // 100x100 fully-lime SVG document. function generateMozFiledataURL() { var blobBuilder = new self.MozBlobBuilder; var svg = '<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">' + '<rect height="100%" width="100%" fill="lime"/>' + '</svg>'; blobBuilder.append(svg);
--- a/layout/reftests/svg/as-image/img-blobBuilder-2.html +++ b/layout/reftests/svg/as-image/img-blobBuilder-2.html @@ -1,19 +1,19 @@ <!DOCTYPE html> <!-- This test checks to be sure we allow MozBlobBuilder-generated - 'moz-filedata' URIs *inside of* SVG-as-an-image. --> + 'blob' URIs *inside of* SVG-as-an-image. --> <html class="reftest-wait"> <head> <script> function go() { - // Generate a moz-filedata URL encoding of an SVG document + // Generate a blob URL encoding of an SVG document var filedataURL = generateMozFiledataURL(); - // Now generate a data URI, containing our moz-filedata URI + // Now generate a data URI, containing our blob URI var outerSVG = '<svg xmlns="http://www.w3.org/2000/svg" ' + 'xmlns:xlink="http://www.w3.org/1999/xlink" ' + 'width="100" height="100">' + '<image height="100" width="100" ' + 'xlink:href="' + filedataURL + '"/>' + '</svg>'; @@ -22,17 +22,17 @@ img.src = "data:image/svg+xml," + outerSVG; // Once our img loads, take reftest snapshot. img.addEventListener("load", function() { document.documentElement.removeAttribute("class"); }); } - // Helper function -- returns a moz-filedata URL representing a + // Helper function -- returns a blob URL representing a // 100x100 fully-lime SVG document. function generateMozFiledataURL() { var blobBuilder = new self.MozBlobBuilder; var svg = '<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">' + '<rect height="100%" width="100%" fill="lime"/>' + '</svg>'; blobBuilder.append(svg);
new file mode 100644 --- /dev/null +++ b/layout/reftests/svg/dynamic-text-06.svg @@ -0,0 +1,27 @@ +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<svg xmlns="http://www.w3.org/2000/svg" class="reftest-wait" onload="sample()"> + <script> + var curXScale = 3; + function sample() { + var g = document.getElementById("g"); + g.setAttribute("transform", "scale(" + curXScale + " 1)"); + + if (curXScale > 1) { + curXScale -= 0.1; + setTimeout("sample()", 1); + } else { + document.documentElement.removeAttribute('class'); + } + } + </script> + + <rect width="100%" height="100%" fill="lime"/> + <g font-family="sans-serif" font-weight="bold" font-size="120px" id="g"> + <text y="100">A</text> + <text y="250">V</text> + </g> + <rect width="100" height="100%" fill="lime"/> +</svg>
--- a/layout/reftests/svg/reftest.list +++ b/layout/reftests/svg/reftest.list @@ -93,16 +93,17 @@ include svg-integration/reftest.list == dynamic-small-object-scaled-up-01.svg pass.svg == dynamic-small-object-scaled-up-02.svg pass.svg == dynamic-switch-01.svg pass.svg == dynamic-text-01.svg dynamic-text-01-ref.svg == dynamic-text-02.svg dynamic-text-02-ref.svg == dynamic-text-03.svg dynamic-text-03-ref.svg fails-if(/^Windows\x20NT\x205\.1/.test(http.oscpu)) == dynamic-text-04.svg dynamic-text-04-ref.svg # bug 421587 for WinXP == dynamic-text-05.svg pass.svg +== dynamic-text-06.svg pass.svg == dynamic-textPath-01.svg dynamic-textPath-01-ref.svg == dynamic-use-01.svg pass.svg == dynamic-use-02.svg pass.svg == dynamic-use-03.svg pass.svg == dynamic-use-04.svg pass.svg == dynamic-use-05.svg pass.svg random == dynamic-use-nested-01.svg dynamic-use-nested-01-ref.svg # bug 467498 == dynamic-use-remove-width.svg dynamic-use-remove-width-ref.svg
--- a/layout/style/nsCSSRules.cpp +++ b/layout/style/nsCSSRules.cpp @@ -2008,20 +2008,17 @@ nsCSSKeyframesRule::InsertRule(const nsA // which also turns out to match WebKit: // http://lists.w3.org/Archives/Public/www-style/2011Apr/0034.html nsCSSParser parser; // FIXME: pass filename and line number nsRefPtr<nsCSSKeyframeRule> rule = parser.ParseKeyframeRule(aRule, nsnull, 0); if (rule) { - mRules.AppendObject(rule); - if (mSheet) { - mSheet->SetModifiedByChildRule(); - } + AppendStyleRule(rule); } return NS_OK; } static const PRUint32 RULE_NOT_FOUND = PRUint32(-1); PRUint32
--- a/layout/style/test/Makefile.in +++ b/layout/style/test/Makefile.in @@ -128,16 +128,17 @@ GARBAGE += css_properties.js test_bug635286.html \ test_bug652486.html \ test_bug657143.html \ test_bug664955.html \ test_bug667520.html \ test_bug645998.html \ file_bug645998-1.css \ file_bug645998-2.css \ + test_bug716226.html \ test_cascade.html \ test_ch_ex_no_infloops.html \ test_compute_data_with_start_struct.html \ test_computed_style.html \ test_computed_style_no_pseudo.html \ test_css_cross_domain.html \ test_css_eof_handling.html \ test_descriptor_storage.html \
new file mode 100644 --- /dev/null +++ b/layout/style/test/test_bug716226.html @@ -0,0 +1,52 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=716226 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 716226</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <style id="s"> + @-moz-keyframes foo { } + </style> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=716226">Mozilla Bug 716226</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 716226 **/ +var sheet = $("s").sheet; +var rules = sheet.cssRules; +is(rules.length, 1, "Should have one keyframes rule"); +var keyframesRule = rules[0]; +var keyframeRules = keyframesRule.cssRules; +is(keyframeRules.length, 0, "Should have no keyframe rules yet"); + +keyframesRule.insertRule('0% { }'); +is(keyframeRules.length, 1, "Should have a keyframe rule now"); +var keyframeRule = keyframeRules[0]; +is(keyframeRule.parentRule, keyframesRule, + "Parent of keyframe should be keyframes"); +is(keyframeRule.parentStyleSheet, sheet, + "Parent stylesheet of keyframe should be our sheet"); + +is(keyframeRule.style.cssText, "", "Should have no declarations yet"); +// Note: purposefully non-canonical cssText string so we can make sure we +// really invoked the CSS parser and serializer. +keyframeRule.style.cssText = "color:green"; +is(keyframeRule.style.cssText, "color: green;", + "Should have the declarations we set now"); + + + +</script> +</pre> +</body> +</html>
--- a/layout/svg/base/src/Makefile.in +++ b/layout/svg/base/src/Makefile.in @@ -40,16 +40,17 @@ topsrcdir = @top_srcdir@ srcdir = @srcdir@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk MODULE = layout LIBRARY_NAME = gksvgbase_s LIBXUL_LIBRARY = 1 +FAIL_ON_WARNINGS = 1 CPPSRCS = \ nsSVGAFrame.cpp \ nsSVGClipPathFrame.cpp \ nsSVGContainerFrame.cpp \ nsSVGEffects.cpp \ nsSVGFilterFrame.cpp \
--- a/layout/svg/base/src/nsSVGGlyphFrame.cpp +++ b/layout/svg/base/src/nsSVGGlyphFrame.cpp @@ -459,21 +459,19 @@ nsSVGGlyphFrame::UpdateCoveredRegion() bool hasStroke = HasStroke(); if (hasStroke) { SetupCairoStrokeGeometry(tmpCtx); } else if (GetStyleSVG()->mFill.mType == eStyleSVGPaintType_None) { return NS_OK; } - mPropagateTransform = false; CharacterIterator iter(this, true); iter.SetInitialMatrix(tmpCtx); AddBoundingBoxesToPath(&iter, tmpCtx); - mPropagateTransform = true; tmpCtx->IdentityMatrix(); // Be careful when replacing the following logic to get the fill and stroke // extents independently (instead of computing the stroke extents from the // path extents). You may think that you can just use the stroke extents if // there is both a fill and a stroke. In reality it's necessary to calculate // both the fill and stroke extents, and take the union of the two. There are // two reasons for this: @@ -1457,33 +1455,20 @@ void nsSVGGlyphFrame::NotifyGlyphMetricsChange() { nsSVGTextContainerFrame *containerFrame = static_cast<nsSVGTextContainerFrame *>(mParent); if (containerFrame) containerFrame->NotifyGlyphMetricsChange(); } -bool -nsSVGGlyphFrame::GetGlobalTransform(gfxMatrix *aMatrix) -{ - if (!mPropagateTransform) { - aMatrix->Reset(); - return true; - } - - *aMatrix = GetCanvasTM(); - return !aMatrix->IsSingular(); -} - void nsSVGGlyphFrame::SetupGlobalTransform(gfxContext *aContext) { - gfxMatrix matrix; - GetGlobalTransform(&matrix); + gfxMatrix matrix = GetCanvasTM(); if (!matrix.IsSingular()) { aContext->Multiply(matrix); } } void nsSVGGlyphFrame::ClearTextRun() { @@ -1552,17 +1537,18 @@ nsSVGGlyphFrame::EnsureTextRun(float *aD baseDirection, bidiOverride); if (!visualText.IsEmpty()) { text = visualText; } gfxMatrix m; if (aForceGlobalTransform || !(GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD)) { - if (!GetGlobalTransform(&m)) + m = GetCanvasTM(); + if (m.IsSingular()) return false; } // The context scale is the ratio of the length of the transformed // diagonal vector (1,1) to the length of the untransformed diagonal // (which is sqrt(2)). gfxPoint p = m.Transform(gfxPoint(1, 1)) - m.Transform(gfxPoint(0, 0)); double contextScale = nsSVGUtils::ComputeNormalizedHypotenuse(p.x, p.y);
--- a/layout/svg/base/src/nsSVGGlyphFrame.h +++ b/layout/svg/base/src/nsSVGGlyphFrame.h @@ -63,18 +63,17 @@ class nsSVGGlyphFrame : public nsSVGGlyp NS_NewSVGGlyphFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); protected: nsSVGGlyphFrame(nsStyleContext* aContext) : nsSVGGlyphFrameBase(aContext), mTextRun(nsnull), mStartIndex(0), mCompressWhitespace(true), mTrimLeadingWhitespace(false), - mTrimTrailingWhitespace(false), - mPropagateTransform(true) + mTrimTrailingWhitespace(false) {} ~nsSVGGlyphFrame() { ClearTextRun(); } public: NS_DECL_QUERYFRAME @@ -227,17 +226,16 @@ protected: void AddCharactersToPath(CharacterIterator *aIter, gfxContext *aContext); void AddBoundingBoxesToPath(CharacterIterator *aIter, gfxContext *aContext); void FillCharacters(CharacterIterator *aIter, gfxContext *aContext); void NotifyGlyphMetricsChange(); - bool GetGlobalTransform(gfxMatrix *aMatrix); void SetupGlobalTransform(gfxContext *aContext); nsresult GetHighlight(PRUint32 *charnum, PRUint32 *nchars, nscolor *foreground, nscolor *background); float GetSubStringAdvance(PRUint32 charnum, PRUint32 fragmentChars, float aMetricsScale); gfxFloat GetBaselineOffset(float aMetricsScale); virtual void GetDxDy(SVGUserUnitList *aDx, SVGUserUnitList *aDy); @@ -250,12 +248,11 @@ protected: // Owning pointer, must call gfxTextRunWordCache::RemoveTextRun before deleting gfxTextRun *mTextRun; gfxPoint mPosition; // The start index into the position and rotation data PRUint32 mStartIndex; bool mCompressWhitespace; bool mTrimLeadingWhitespace; bool mTrimTrailingWhitespace; - bool mPropagateTransform; }; #endif
--- a/mobile/android/base/AwesomeBarTabs.java +++ b/mobile/android/base/AwesomeBarTabs.java @@ -617,17 +617,25 @@ public class AwesomeBarTabs extends TabH new int[] { R.id.title, R.id.url, R.id.favicon } ); mAllPagesCursorAdapter.setViewBinder(new AwesomeCursorViewBinder()); mAllPagesCursorAdapter.setFilterQueryProvider(new FilterQueryProvider() { public Cursor runQuery(CharSequence constraint) { ContentResolver resolver = mContext.getContentResolver(); - return BrowserDB.filter(resolver, constraint, MAX_RESULTS); + long start = new Date().getTime(); + + Cursor c = BrowserDB.filter(resolver, constraint, MAX_RESULTS); + c.getCount(); // ensure the query runs at least once + + long end = new Date().getTime(); + Log.i(LOGTAG, "Got cursor in " + (end - start) + "ms"); + + return c; } }); final ListView allPagesList = (ListView) findViewById(R.id.all_pages_list); allPagesList.setOnItemClickListener(new AdapterView.OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { handleItemClick(allPagesList, position);
--- a/mobile/android/base/Makefile.in +++ b/mobile/android/base/Makefile.in @@ -353,30 +353,26 @@ RES_DRAWABLE_HDPI_V9 = \ res/drawable-hdpi-v9/ic_menu_find_in_page.png \ res/drawable-hdpi-v9/ic_menu_reload.png \ res/drawable-hdpi-v9/ic_menu_save_as_pdf.png \ res/drawable-hdpi-v9/ic_menu_share.png \ res/drawable-hdpi-v9/ic_menu_forward.png \ $(NULL) RES_DRAWABLE_MDPI_V11 = \ - res/drawable-mdpi-v11/ic_awesomebar_go.png \ - res/drawable-mdpi-v11/ic_awesomebar_search.png \ res/drawable-mdpi-v11/ic_menu_bookmark_add.png \ res/drawable-mdpi-v11/ic_menu_bookmark_remove.png \ res/drawable-mdpi-v11/ic_menu_find_in_page.png \ res/drawable-mdpi-v11/ic_menu_reload.png \ res/drawable-mdpi-v11/ic_menu_save_as_pdf.png \ res/drawable-mdpi-v11/ic_menu_share.png \ res/drawable-mdpi-v11/ic_menu_forward.png \ $(NULL) RES_DRAWABLE_HDPI_V11 = \ - res/drawable-hdpi-v11/ic_awesomebar_go.png \ - res/drawable-hdpi-v11/ic_awesomebar_search.png \ res/drawable-hdpi-v11/ic_menu_bookmark_add.png \ res/drawable-hdpi-v11/ic_menu_bookmark_remove.png \ res/drawable-hdpi-v11/ic_menu_find_in_page.png \ res/drawable-hdpi-v11/ic_menu_reload.png \ res/drawable-hdpi-v11/ic_menu_save_as_pdf.png \ res/drawable-hdpi-v11/ic_menu_share.png \ res/drawable-hdpi-v11/ic_menu_forward.png \ $(NULL)
--- a/mobile/android/base/Tab.java +++ b/mobile/android/base/Tab.java @@ -53,17 +53,18 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.mozilla.gecko.db.BrowserDB; public class Tab { public static enum AgentMode { MOBILE, DESKTOP }; private static final String LOGTAG = "GeckoTab"; - private static final int kThumbnailSize = 96; + private static final int kThumbnailWidth = 120; + private static final int kThumbnailHeight = 80; static int sMinDim = 0; static float sDensity = 1; private int mId; private String mUrl; private String mTitle; private Drawable mFavicon; private String mFaviconUrl; @@ -147,23 +148,23 @@ public class Tab { } public void updateThumbnail(final Bitmap b) { GeckoAppShell.getHandler().post(new Runnable() { public void run() { if (sMinDim == 0) { DisplayMetrics metrics = new DisplayMetrics(); GeckoApp.mAppContext.getWindowManager().getDefaultDisplay().getMetrics(metrics); - sMinDim = Math.min(metrics.widthPixels, metrics.heightPixels); + sMinDim = Math.min(metrics.widthPixels / 3, metrics.heightPixels / 2); sDensity = metrics.density; } if (b != null) { try { - Bitmap cropped = Bitmap.createBitmap(b, 0, 0, sMinDim, sMinDim); - Bitmap bitmap = Bitmap.createScaledBitmap(cropped, kThumbnailSize, kThumbnailSize, false); + Bitmap cropped = Bitmap.createBitmap(b, 0, 0, sMinDim * 3, sMinDim * 2); + Bitmap bitmap = Bitmap.createScaledBitmap(cropped, (int) (kThumbnailWidth * sDensity), (int) (kThumbnailHeight * sDensity), false); saveThumbnailToDB(new BitmapDrawable(bitmap)); b.recycle(); bitmap = Bitmap.createBitmap(cropped, 0, 0, (int) (138 * sDensity), (int) (78 * sDensity)); mThumbnail = new BitmapDrawable(bitmap); cropped.recycle(); } catch (OutOfMemoryError oom) { Log.e(LOGTAG, "Unable to create/scale bitmap", oom);
--- a/mobile/android/base/db/BrowserDB.java +++ b/mobile/android/base/db/BrowserDB.java @@ -78,19 +78,18 @@ public class BrowserDB { public BitmapDrawable getFaviconForUrl(ContentResolver cr, String uri); public void updateFaviconForUrl(ContentResolver cr, String uri, BitmapDrawable favicon); public void updateThumbnailForUrl(ContentResolver cr, String uri, BitmapDrawable thumbnail); } static { - // FIXME: Still need to figure out how to use local or android - // database here. - sDb = new AndroidBrowserDB(); + // Forcing local DB no option to switch to Android DB for now + sDb = new LocalBrowserDB(BrowserContract.DEFAULT_PROFILE); } public static Cursor filter(ContentResolver cr, CharSequence constraint, int limit, CharSequence urlFilter) { return sDb.filter(cr, constraint, limit, urlFilter); } public static Cursor filter(ContentResolver cr, CharSequence constraint, int limit) { return sDb.filter(cr, constraint, limit, null);
--- a/mobile/android/base/db/BrowserProvider.java.in +++ b/mobile/android/base/db/BrowserProvider.java.in @@ -688,19 +688,19 @@ public class BrowserProvider extends Con if (!values.containsKey(Bookmarks.POSITION)) { Log.d(LOGTAG, "Inserting bookmark with no position for URI"); values.put(Bookmarks.POSITION, Long.toString(Long.MIN_VALUE)); } String url = values.getAsString(Bookmarks.URL); ContentValues imageValues = extractImageValues(values, url); - Boolean isFolder = values.getAsInteger(Bookmarks.IS_FOLDER) == 1; + Integer isFolder = values.getAsInteger(Bookmarks.IS_FOLDER); - if ((isFolder == null || !isFolder) && imageValues != null + if ((isFolder == null || isFolder != 1) && imageValues != null && !TextUtils.isEmpty(url)) { Log.d(LOGTAG, "Inserting bookmark image for URL: " + url); updateOrInsertImage(uri, imageValues, Images.URL + " = ?", new String[] { url }); } Log.d(LOGTAG, "Inserting bookmark in database with URL: " + url); id = db.insertOrThrow(TABLE_BOOKMARKS, Bookmarks.TITLE, values);
deleted file mode 100644 index 5cf6e22a5b7419fb7a6b4b5484f925191f4f28e1..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@<O00001
deleted file mode 100644 index 85e68b8d9cb2b17c292087c9f9a5779b85e493c4..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@<O00001
index 2a7ee86aa8e8d986239af2bf40312856c852c3cf..4c4888efbcad0a02d08a461815bcf10c5c8009f5 GIT binary patch literal 662 zc$@*20%`q;P)<h;3K|Lk000e1NJLTq001Na001Ni1^@s6;Q*MJ0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU!I7vi7RCwC#*h^~~Q4|O8<ESGVotZRL zqm_Jsth&lBbXT${bZY`3Sp*WY=%!E#m9~)v`w2?hRoYFn$R@kuI*_lBCp5-qqSpE( zqcis0q7Z`Bd7KF@JaBLvXU3m+?|-h^I-L%TQgJY1H3khUhu#wwS2tkl!6XFy5AD+d z|0kc<yIif+V)?7<kEu)+%H=-;&)@y_g%&j7@qj1@c12acU#2rl@{J5W!5jB@+<Z6` zjIm>ep-4eDvJAhHm#ZAdE%8n#)Ef<$lq7f*n%;7|-C!1_8`NsG*u$}ch1+)a<afFJ z?==dP(LsHH9l=(5I~XdR$w9N(WT>}@0!b3@b(ZZ}figSo$x#$JM2eycMluv-Qfoqy zPy6T37W(HC24p&$-MdJpB9%&Y7kBlI1gzMg>)Y-wKi<5LKMsdO`;sWk=nhRpWpjCi z<)BzB!R>2z!xIqo?&XV(m}XF9W&O3o;fS;CcDqe_<Lsd@P@`MXSKFG$5Q9)-dSBns z$r&7<o`1lbG_Mt;Sh>9De$cN!c0S8mK|isR7MgajH#Lu;VTEIC*dcS+32gB{m^EAz zDP+^WU%6Z^2nPHhiozT&0uqH{NxZr)fU2sxFeJgK2cu<ta-)PX1+oHT7-SX35Xgz^ zX#B+iKA)EyV`!GScpk&8HCrr|5~|uE#TWwB>UGvn2IY*Iv^P4a*&82HW6Xe>*iXB^ wKFBa;le&gIk3B<q@3W2n9~y&9)?Wbz0LN%${b&1f5&!@I07*qoM6N<$f(uV8>i_@%
index 5ba4b52a97727b08a8434d9b26ac120d951cdcfe..8ce941140c075bcfc7d7df74b0a2a634639693e9 GIT binary patch literal 1153 zc$@)&1b+L8P)<h;3K|Lk000e1NJLTq001Na001Ni1^@s6;Q*MJ0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU$BS}O-RCwC#m|chyR}{xjz9yN;B)dsA zG3(e}!&)s{qz`>47Nyb$p$Pj>d?<<(idKvkHEmsly5L8lt+grz#iED>p#?!G^u>Zy zEEJ@D^0n0x$!6o4NwS%I&t&}HVMelc*ELMKTG#_8ncSJV`Q?Al$DKHIU8fhxob-a( z63{~Co@?;E_jk>vb~-5-5Ggt^K=F8t0-~Qh9uJ38oTh0?wOXUx^g}v4e&D}XC;*UE zBMEwK?W=ujR*$4Y{e9QnZZ~p4Z@|ld)q{b+A0vt3iHn!7#O(q(=E^drki+4iNF+@0 zSd?PXfxQ?$Qkt0wXQy&hD3qvHuN&8Ty<P$&4MMqaD5L=Po4hO^{bXNK>nTtq9HM2h zC?|^kOIVVvQ@IE9FfTuKvM}zEmdB|t5WG>TR^A;?eN^fR(9S(6s1hZY+x2~0)3#4$ zb5yO>tkZYkSK(=R6Fvmr3}4SqBDQGd&`adwy*D&f+ca_LW6gF@i=s%CYV|{}m)kx) zowr~V_zw7wbKLR;{4MyER;wlblfF;GLo41^RrLtQKC>Ov&1O@qHyRV=vSPt7>EE0O z#<H96H{cmS8Ow`#QU}H-B-=oWQrSwnF3E+WHIy`$>Z$g_<?|U9g6z0hERm{eJe1yR z8>rE2j-kF-AOBiFnJ1xs!`m;W(p0b4H}|3rt!=5Qb^H^&+Z1N^7|RWnMz?*i+hrFh zj)^)I>elYDmsU%qcDwD;w6<gyh(m^u$897b$5OdVGZg74DYg}2!AZQp6UTYh_`IA^ zxx27Yf#<Db&6>{+(9OraOcckwKA(&Av}ZNHAdGpq$Ew~&pf~LT{mfowX37jm5(Qy5 z`Wf*)-@Fr9%ew#I;j#YyzIAK|&>7%%fv#GCSymKOZvV+>B(i?>%OggQ>s&r|91I2s z-JZTab9NLk7f?2c6-TqWe`mXOm_6zcD=T@qfR4^_=<2`5m&H!RqLHIzrBY*692rD@ zzra*<x!taPdAWET<9wk|F!oSTwS;TfTFbV(y=f=mDRzKgPAirV5}-1Iz+ZDZoOg86 zStcbamFkw<gXvY1*(oZZLbExs4Kc2dL_$#7vGLRW$#gG(Sh{{?K^a?&P`|OwfGSYI zfjCo0h9bpMiBNB5#}%L?11bzC9Z-AHc7ZJ0VuB?Wm`^ri@AY}0HUKKqi%mWY@>k&7 z;Mbn0-f1%{*{>LeZ-oDDon$R2GnpmqA`?h}TPIGRm3pDjvo==ieiq2r;p=88B@NO5 zl)_g+sbpr+9)keJ(*2!(DV52xeNqA?;nuM)Pf3gVTn4Dpd{Ed?CjP#A@7qOxQ0#!Z z-3i4yK)v4h^SL~^noyfMp<w4Q{`qrzl<t7K$Tt1>oa`#gmi}y50{TA#JrZC5jdjIL TU2meS00000NkvXXu0mjfVvQ<{
index 570aef60f0ce9f67e4c47b2ce68922de0535f69a..e135e341e2a66bc1083b9ea2d62fab69076dc24a GIT binary patch literal 913 zc$@)|18)3@P)<h;3K|Lk000e1NJLTq000#L000#T1^@s6sTZY|0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU#Gf6~2RCwBqlu1kzVHC$_x<X11rQm_c z(h3p+*bs!IAw-NR)&=n(frN`8vIGi9H1Xz1O++!WQwpsJ8WInBa0^Q*RAdV@Bpe{J z95iaQ7>G#Qna<SrkeX(?z?b|x^WJ>#H($T+|Ar*?M^5f3Nsp<&cWZlVSe<#IZ*FPb z?PeGv*bwmfL{^$oFk@RPmrAATn#yZcO>Nz~F3L^tyuhaB_7?(?s7Nl4?s_w9sl);- z3<Z2UGF~T>$y<aXap~R0rh(dus}iwDK#(veY;<zrr7TjWVHgj==ktg#k-)RDzIy$F zCQr{@u`e(|aqPa6qRD@CB(Z6?zt-etmEcOH*7315Ts9WFD4K9mZc?F4e9T>OAfUI- z;iNnh7V|nxli+NzWpv2N=L?QxWM(O`m|<A>CCTWhDDC-zOZGf<hD}$0gUw7;_yKXS zEbHm*Y#DBTc<(ucpAm{r9P@M2b{>x>&p4T#zy%i+Ubg3EtCrr6T6OUXr617H(QGyu zI*br5fPNtqtN(zu7v^Su1Oi6^xVWS=EhaXu*6E@MF7Sz=qX)t%(D$juPj2t=h6FP# zOA5u|$rSA-XqpKL#Am*q2?~b#|2hcBg>u36bX7*$(b#x7*QXz?mgUAfx0~^n3&g<- z;BB1n)7U?lqS53ha~nV?;1g%H+7!KM;5dYK^f4De25K0z4fynd!$o<#hvGZLB4Nk| z;T;BudpKbp{^Fe!szJEWpg=ej>#c_BXK?*+7%=}JU~gCJn5nxRPkGihKf4C5hz!&q z-p;GiHLwU3yn1Ke1G;G14`|f48TM_n0on}KAd#|2ZT`87_A@z|w!IGuOYjPR?>d74 zr$OJqHV(Lc#TURf7~q-3cPn-rF4E0-3L%WZT(npmR;=$ETt&Z4+E(bYO5G6Ti$JmX zPasctg)t}&R9s$NKY}%=R>RX};9P;ceD8Y-N)n1hrysQ$Y8Gwt>ph(<MxPb>c}lHH zLU0V;R@5|<rKYRmZq`+_(-buZxizm(5u6B02JM2Df&l}7Q$gXN6$C<!)7Sh6mf+rl nc0vI;;D~(}VT}v(e+3u-^|LqlCon<300000NkvXXu0mjfx3;1Y
index 08d66d782c328454d83377f2480f2077aad49562..4c0f1b62a52e7113f514202c7bb3784f1f3c2c95 GIT binary patch literal 584 zc$@)90=NB%P)<h;3K|Lk000e1NJLTq0015U0015c1^@s6J20-I0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUz>PbXFRCwBA{Qv(y!$1H=WX|!6xA7{r z)K_IccjeYnF;U@QumI4_FJ8Y{Vxp^_0@V8xC{L87AkQ)p>q4NRjCPJL3V#@wgP*_t z$nf~ZJBH_PKQjDdV2J@r3zO<&CQ=lC{qjZR@85q6fByaj^Z)$$%kcN#KM+%pmKHPp z{{5Q`ha4+SeN0U-YVoMWGy^Qi99an={EAta7&tlD7{34b1sCJuU?WN|wjz`L^u_Db zCB?-OQ43J?Vvd2~$Issk-+ufAVuZ!qoa|u7aI&)!C?<i$>&w@RO!YO=fJNp{kX4c= zFWq^<%*@2}`_Et61uZi(!>`}JzF8Y;r~oZ~4vJ%;fB*l})KYNq3M^*-{QkoXWb(rj z7b~696)Vi*-xtoExkL{eZ{55Os(1gu5|=a(+X1mI5Od;7h(f|5!dv$pkHJ!9&H++i z2-y1_h%W>2Az&Oo1!bo<APx{;A`t9MJiNRHKspAC+)g0AL%`zSK>QJEA2=WX1mdS4 zjIRX(^cAy!fDk_p={rEZ7l>_vjF#1-7LQuY@Z-n#e*<Chzgsu1y+3>U1iX0t_wV2T zGpCN9hZYXxHw1_P?{ZRNJCKUkZ_r}!Jw<&dA^<zIyCMiJUVlR^eG4rCiS9cA1Q-CJ WAhTsM>(Gw?0000<MNUMnLSTaQJqn)y
index 681b238c24de41e0891cf1994ff715fcfd27c54b..27f0f12ef636d7c888a57594cf919f4c93690b12 GIT binary patch literal 792 zc$@(k1LypSP)<h;3K|Lk000e1NJLTq001Na001Ni1^@s6;Q*MJ0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU!x=BPqRCwC#*UM`YK^Oq=+1+enH!+E; z&BLHr@LDMJ5AfjKlZQg_anehR(E3P0P!vpQP!dtln;tA4JPBSZ`3F1+JyirnY~J17 znx`8#^_yj*X|g-}NJPOM7>3Et?*5pW@0$&^x3`D>r9!zN7vzHeCg{@QRTPg#P%Ij` z5)OwJ>h;E>VyT?n&KHoh`;GYEm(QQ7?fr*OW@6FFOsDf>vs5lG-&k6dN%zsDi$@Og z$m8)O1xd<mefW4%5T%UY&s|F#jiYcVXn3F3%c||YbatlORdSy`e>qhuR~BfRd2x63 zftU1759wm1QaytxD#b7ilB8Y4^M_C(9$Vu$4go5S#|+LC#>8V$4b#mPiX|Q}XyU*G z3IzOTJDtuJ47=$FRI4}k^#wsxTO(8t6AA`Zj3A0CMp3$`-e{;53gdXmpuC2<GKktP z6j8g~#;9M*N5b@#SESi7oguBPYHiABrlw9DPirqW!_2{ES4IVyqN0&W#Io$$ulYO) zGjE2m10tdnMOmXLsxC@WfPj&$yu@QOZ|S0N1VTOw;Ql~fvxRX2(nZ0((HmzQV<pN+ zsH|@4rzqTPI>FeUA)nW)hBnR6IGWDwz;e}U^?hSl)`N~E64O4Pcd2hS$3H_oOehqb z^>bWKmSw)#Yz~c+<qm?)jcA%q!8w-vBcL887(6%&5w)=+2zsIYJ9&x{%0u#OwOY1O zv>gmA(*_~W+!_ap9usCB>Ybru#sP{5!WkG&Xe$`GFZv8o>CEHgNTBbsJXNk#tzwWF zs!|nF%PY4pIu3h4OhdyPB|ROCaYhFeuJ`~RWmCU_x^5HG`-B~uDJbu?z2+E%Pv`Sc zpK1MdE0_V)b?rItpq_@`1jirwa~Cf6ck$8*R>QaVk*__6H-otU%UqBP`fou$1sDK* Wl-{nRkDw+10000<MNUMnLSTZWA!)_{
index ac7db408a6b23f2cc48ac4111f4af225d7acf0f0..2a8d691c8e8c139468c8e70d23a05dbc256822e7 GIT binary patch literal 577 zc$@)20>1r;P)<h;3K|Lk000e1NJLTq0015U0015c1^@s6J20-I0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUz<4Ht8RCwBA{Qv(y!$1Hgh5-UY%i`&? z7bs4hHD7|R7I#mW8p6rRd7GDq`^JQ+v&_h~n30skl~q__!|?zA0Tvb(W;Qlf1~F05 zkIc+WZpC?-r)cWqckkXyynFwF`PJ(;49{P@WO(`NHUHng|916EoMuK-i&re1xds&4 zAU4oKh8Hg(mjC<rA7r^PP2(77c^Q!EK(_qVYp~^ednZjdrfI4MT3(54IVjjcmIK*D zTTXU9#%1}RKY#ZU6YLZfAW+L&ku87y<_#>t8Pl}n0$N_f#mR|g`CB1E2@WG4xA#ms zCNC#r$;ik^l*M1aeq(s{`~}04XU`cvefkU*1Lkc8NeKyHJ{NiS|NlR?@}k_c1TBt; zPyf%(&d%`j=TC}40%W;_xH!YFU%%clF)?XR>~491EYE^X6Q!2Ig8eBl6o7z}*f`!n z#Y*Tq5C;L%!3&DYYFq#qJ!wE{CJsw?&?Hp@6JwgDy6Q|JK>?yIrPyMSrNG296Ifm| z04oooEv3j}9G3nf#!|8^#$%~JF_z-YPWV7`XMftizkeyRlw^z3a!Wiwsh5SBnIcO` zwis9>GNTERWhpr=kgY(ffKp4zE<k_<hCQeW2DJ1tU0Ru=T^LFLK!5=NxhymN&O;<T P00000NkvXXu0mjfxv~9l
index a7f7fa2a9b0d291a6e4df3c9e64c4d49f1dcb817..d51934f10a37df17870607500d631b2d88585bed GIT binary patch literal 922 zc$@*617-Y)P)<h;3K|Lk000e1NJLTq0015U0015c1^@s6J20-I0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU#JV``BRCwC#R!eIWQ4~ItWF}2A$)tI- z^_8?mC=}{Sx^vTQ7g9kKq3SB7lG379v8{-YQc#qLu~MxIU5H|#AoMo~t^}c26$`a# zUM5ZRoFtQs=MIxL+FCOMr3-uDo0)s=<C}BuobL=JiX!ZWQG3L@LVWsM-}<x3WP}E% z0~~g{lQkK=8ja=@MNw^4a~E*#Og5YIM`N*2I2?gzj~~=btlP@TaTaho>|m?6_ESLJ zT?vNRU?>8~RBC;U#bR#TzprVup5q2_?3hlgeW)bjO~fQpD-zQ>-Bcp6=J^p=fn1KS zbT1;}2wO6lYC(XZu8wuP5BX?@K8*f>T8TBkH8dJ98I6$77rg0A#`ERd_X_Dd#1TX* z;;4Kl?b#g9!{>#skjZ4dSFhjpsv<TS4Nxc+Z9LE4i9}-+_YK5x#HT;zlJ*I?AA-R! zdC7^v;W3-?h_zbCq%)qfD02CHp19@^xBjsP>7OH!3#Ag9&1OA{iPPx}6a}GMC<+zV zc#S(JjUzA1=L_A6iA$vtxpm|VQnYJ`_caoeadA8%C>Dzyiiy#*B%8`*DYxTNqEpoN zLa@;vm*;V6h)Kw4A}TaZJ29oSdOfr40t~}cUbsmXqqG`gVjsx`bD71Q?&2(#zeY{` zX4XV<xr>aip09>@Mhd-LMs>3Ij79^43bu)yw5=QmdfXCJIv;HG&#EPUjtIr$s{o?d zZf4o(X1B}G((IC=V;EXeH@E8`fx%*Cr%`y?F%2u<#Z$FfotCBV?b339oOQ3mZtHAu zyRNl1yFZ{mfM<E2ES5V{sq{o5!MCBbN;`zwZKG-3c^u<cU7gS_BJPt1QZSkt8^CJi z0E+<#f&lT=1cW0|h~dsu)*$_jSkZ9%2S$bm{c4Gc^&lq67rV_GQBpMIFMFMw(K7?1 z!$W>0XIyQwazW^m<#S&4&&zG%cO%ZqsR(4-!_l8m$QK@s-}CjWjaZ4DLA<O)UT?MH zkA$7%`GwIdLr;`Oti)bbN4}a!0I6_m$<*ZKk(<3cNer)FOl=}x`mqelft8*eCEki0 wZ3%H{$BC=RPa@tRj$wOo@4x#0BmO180A;sRzA!<+TmS$707*qoM6N<$f<FSW>;M1&
index 9d34886c7287dd694049debfb3e3288b8611a9e2..592c8872d58325ab5290333ee80f054b6af66010 GIT binary patch literal 707 zc$@*l0zCbRP)<h;3K|Lk000e1NJLTq0015U0015c1^@s6J20-I0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU!Wl2OqRCwC#mfvgBP!z{cnl!FW-DXOc zr1%#IKKbm658~567%0LfvIi9$J_y1<7$~wA2ab*uAH*NUAt?A42>uEF0g5o&q;YH0 zY;#MKCGp&nNNkguRKy2+;PfWFKR!A4p6^L0&-3747&Qj}zu>#~9)K`YIwcCF%E7^5 zt*L!`{<WdN?(SaX_<Sx0Wk~>05N3IPda>2kSC(!pevAWW;yPG1d)hS34~nXt+u#5G ztWe-?pDar-Ie9!1Dv1Jc95-in%{Q91J!_iX_xD%V&cv<H#C3f7{ACTB5>01ddTI*F zW$`gC>>zxjjvYbd0Tdr>&bIAWirQq`x(*pC!`nwkt2pF*s)*65=#JyKfZGO&(gcjA zg78~G<o(d?off;(Y6F>rPzUEfO?}3fuU;q374(<rG`T7ACrIQlacpAA^V|)5DsWxz z7pT7;fnIz4;z=#_R{OT;w>>zCoEX9@k|2=FX1$@Lh9&{W!fng0xSnU}dS?KNUi;mm zOhVZWz}tGKm;B@>Ei?^y0N$4ysi29$BzrM)F{`^4MNtk)=_eTPp;+W;Hp>(kCJP<I zh%GXyz)_M3_xBzE9pN%&I~2Hlwf?6O$LTb5ro?FSA2CT1WYjsJ&Z{GX6F?WjXWkF@ z3lOBP)uJ#1c`i2$y6O8u5Iq^Asv4<q@}qV6=1AbKWnD0gy<yOBwhzEN9YbDTc{rbX zs~d_sALukBnSN-b)Ck<)`ipTA8}^b|M&C*Rjf~u%duNoaCKJ!1lULhY^mhr1%pv+E p@-2b&dTad6H3pBtf8BlvFaSrqhaE2<4Eg{7002ovPDHLkV1h6RLz4gi
index 9aa7407e433b80274f9d4dcbbbaf0beae13c2d49..e713a89ad4ca974b1a52781a2c3e786473b5aa0b GIT binary patch literal 282 zc%17D@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE;=WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8J)SO(Ar-fh{`~)M&uq#l%siEmyGKxPexG-*tw28Gqbh}W zhnHp?Jv7s0cLATkXNE$3f$2eqPp3Nk;Xd_FDMiDOZ5{ig0260zjovA~8ExAh8%>!K zp>`@jOvOxEz@9xxQAj7V{gUjBm=m6h5>K?9N;LjpEpT7`@BuG{x|XvJ0XH-l4VC5I z^oz6^9JV^qD`Kw@$IF|&rfp)9LSUO<w!%dq@qi_XSNYljkqj<{3<(YczF$n!Ua>K; aNHExa(w-Z}-BS$o2ZN`ppUXO@geCw(gkVPi
index 3e47226dbe9f463ef04453b6375766e36ebe9b8a..297e7dc0dd59f59e2eca49fb65910b8898e611d0 GIT binary patch literal 432 zc$@*S0Z;ykP)<h;3K|Lk000e1NJLTq000yK000yS1^@s6jfou%0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzQb|NXRCwBA{Qv(y12q8?1C;>_j1du^ zjw~(>`C48$rx{0NB80`U|m8w0FZI1|-CBwz`|8-Z99NepDD6A<Ts>;~dZ#Cn+@ zh*v`mTL#2>K+FilGC*7dRkIX`6^S*l9f+lYcp?x-1My|3_){Qm1>zJS<^kf##2Od^ z#NUxzgASHKE%AUFjMqR;s8>OO{sm7&f(&E^VmU$vf?W0s8pHSiEc`wa<K=@;S9;?x z43q-QfcQQ%TnQQo3cJ5RJRgYd(d2ZYF%0tV0%9ZO6cATJU3mbA_X05}#cl`UGf3X8 zfJO{aS+5(29f0^6G%=?^HNSwyGAsf&Vhb7;94-fir8YEz6rthu0xI_i>OwXkUI)aX z$T^3FK#abFVq{Q><ZU)+&I0AAo0OC`mC&GJfEx6ISQp|0Wk7r!8a(hc$vEf>SgIQc a5MTfi=|i^>j$4)h0000<MNUMnLSTZsJ)M^T
index e96250af40de73512958b4bfe18276518e236471..c31c2a1357b1a7663a74c125aa12de7a989cef82 GIT binary patch literal 317 zc%17D@N?(olHy`uVBq!ia0vp^A|TAc1|)ksWqE;=WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8`<^b2Ar-fh{`~)M&uq#l%siFxDsPITct?l7IBU@7#tLD9 z^M@AdOLqKiuqZrwXy*G5QXDL+8*j*U>}~v^FL2&<vOn{qnE~IF6uv1wdAio)jb*^~ z1Y;hSYr<cQ1WK3<jRm$VOL8%vXiH5jv<+i+T)^y=Y%IcZsjyXlUj&<ERGX`ftbdB2 zkJ<YT9e<U~Wz~{DYB8I5s!qsCV49Vv=@8@7v+#zJs@N(<HlfA}Mxp)UCj$bkVtr1u zKCIw*?OeQ4-cYZn`B}r%7u%F2f5~>lE)-kDaBO0D4R0MYBNGq9>`(g7JTC8f4fHC5 Mr>mdKI;Vst0BTEc!vFvP
index c4f2998aea581926b5a8cc47c47cee1f472724c1..2a4a9fd9b6dfb7cc4f03cb38a731c8ed075b88b5 GIT binary patch literal 773 zc$@(R1N!`lP)<h;3K|Lk000e1NJLTq001Ze001Zm1^@s6jQ+T70000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU!r%6OXRCwC#*v*R)VHg1LXGR^;bPU>= z^<&fB?*0e6;ITiUP6a``1a-=wYji58Lks1?9=dglf`|^nLP5uF9m3ji)Itrl)tvET zoSt`eL)%?*ocGlweBkBvW1RW<yq`0iX_|17gPQ~Az`x?+<@Mnca2$j~0ayx$gm5T$ zp;D>7S9AGtCX<DBr*r7{&z~hNU5~f*?+_OX24GQ^yrR#SGP~WEUhnCT0a=bjqvyco zblT3KtuvhQ`$6=1y?V3tM#-qF-wQ>8jVwwF@35@lA?k6NoC;8H>hL-JB_RmHDqv61 zbRBd}CtvlDveZMWIcT@r6J5hr6KjYujIK&*f+In)MY2{X{fOXOf?SD4mcZq5O&{2g zZ7dH4Klp<z6eD1oJDAOhkxojp!R>yX7(!yx?l-qA5o8=+@6IBFgUG{~L}Z~@BF(*@ z$yoybjpVqU$4|FcW(gdPBz+PGjuj*e;IT-hhYaJu85_w8cqFoOfGn2AMp|BrU%h@i z)^W9Z9lk0mD2jUjSEG>_nmTX^T*he!M|U3k<=TyntGg2cA8jU+=a-|`$eKGz5Tu&T zLnfPpYV{|KK*kZ7wgkL%Wy6i%HAK+|dwVq|ec%8oiela{jQE{fH`8NJ)QA&E%?dZz zCp{i_xY=yoBfB{(D@kh_8&ZPoC*hN&QH&c)4XaHo#uS`ec)hz!cGP2pge8R~HUhWK zdb2PT4u=D81A-teoRxT<OO?yjST6q!nyr>49FvKfCXPCgHjXNg1&$h!6^;tf3J#0q zDS$u8INQ^V-!Fp4eM-_aErm-Jb)0QrtyYI}xst#|Kjz?h>NwlL{>}IYvYsCC?7%jT z)+l~~<vI%-&3W)iA4GPg4{724&*y`4;2cOfehV-FB*UkTq$#?`00000NkvXXu0mjf Dp;2P}
index f13e814f8b589cc73bd98a1ad0387fd7eda22a60..e91350481c971b14b67f782ac4f19b91166145a8 GIT binary patch literal 1282 zc$@(O1^xPoP)<h;3K|Lk000e1NJLTq001Ze001Zm1^@s6jQ+T70000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU$q)9|URCwC#m~Chqbr`^(+~w`sCYPpp z>r1k#AB26exKXJf3Nje<Q(;5t5IY%@6&+&?aj2k!(P0_rgx1LroTwd4qWdI_6$j$* z!(bo`huvD!q)qdl%O!WY<Sst{?yh8AOq29Ri}Vjq?lsT-?)g7&_cv5371+*$f^9x_ z0RQ)Z#%BNU_2nPT4%R+Q(bNG07zPXm!)|gOw`6l0<yNU&zLrX*uZO}B2#1%TAP5cV zp84kD<^aFD^5Yo8SU-s;l7W?29HJ;Z&x0hDz-qOCgJt)0`#gI*ZudL*5_j6#m=kte z$IXRM7!rx(le6IY3)2if@N$;R9SBF3AQn$Txm<qa9#JepRE$A%B?cCY1^Rlr2mF0K zzq(zna}-6LHq!L!HQfQvPJYH%EtVVM$nwx4P8XlgufJsuC5z%i=_MzM#Uk9FUx0Kr z3;hBA`>4R@^Lh?Tk_4%AMqfaoAY2jzafn!sSV<ir!j2L|zlm!nUw`xM0B*)mPNJ~r zhpU!G$T3+_?z&xFljH@7OXvc4;=PYX(6>gD$y7Dm_b5jYtd{2!@G~f1q5O<8$Z<JX zj;;{@oTyZkV3*T5M~*iQc>L4{bg5LHP!t7n{Mxk6BG{n@^hQx$LHQkJ0D}rJVCZ5| znm~6sXfhh1w9bc{&Vv{b!?Gejo5^O^PN5ub!hMK^52DEAfcPFx_Xx-Hf%cB}%_nMf z^kLFSRQbypv|gymAe>WO0@G0*%CbzOPY+{M>rzPu6<Mi1zS?3jxI%u&%a%)JC`!_x zD2TcM22h!{pK8H++W1r3kxCMvPX`21A3&O<2%28KMQVjiEr0wP;6ryYH`9aG1LPk* zgaV_{=sxt;INdBDMlPrc{E_(6tDCt;eq>n&)^4NQ80%28fM%1KSn*}M-L^h(bOF4j zIX5;4;Bc_Vno(@Cb)e;GU|IW^*<`A|G^-cjx7rTJ@zBxUKKk+5$&p5slFr8Kag!;2 zqtn3-R@HAZz1MXC#HhWer3fyU!^F+u1KXx9OkWDrQ%I)snWy@ptFv>+ZnIs?=L^+k z@|>E$b?c}<)D)5yi{m&SmZ?8xuKu*Y*3EmLe-2)JVK4OW@*h<yl^a++n7G;py1Jau z?ej_je;;v|#xuc2A&(u(DCt#K3pdu#o^BuP^7n$*>$zz$n}c}zH&usOsVMsj1>v>G zQgrtscGCn-(~q4D5IDwa9mgr3UI;BhCX?N;qc${>lMs@$Pv_Ut2g861AJ~hqENeq> z6P89164>=DM`Kub(=}TvkK2Wiy%==NcrM332H7&83b|jkq;oSLLG>VO0XAH<@z1~D z=4q7429j+A<z4b#>#I;Ko`BF|1O!2t!c=q&o7uWPX=r8X1FcD_%0ALiXl;H~5}sAR z?zBNt(+u&^jV$@)=b!2WSO@&SF4c#`z~K<`^r_=p_Te6^H{At6oT4bh(XC!t2&x_S zV~`K#|AD)I{r$y}@srN2Ui!FJ3o@O_kPdzx^J8{9tj*MdoJV;TGljfe7LPPY@=bjQ s<s~&WJ=rMUSs&a1+yUHz@vi^_099}uxu_9NbpQYW07*qoM6N<$f{&qU0RR91
index 7e729609152043e3461da2b9803fccb8a1ca768f..929a37991dc08ea3d549b8af7bf8128d28be6c1d GIT binary patch literal 828 zc$@(|1H=4@P)<h;3K|Lk000e1NJLTq001Ze001Zm1^@s6jQ+T70000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU!-bqA3RCwC#*xQQ|Q5XR5qpoACyISsQ zYpYfe1O+`rY%dEv1W^b=5wuXmyzOhTP()A=^iU5)g&Wp}7HkME^-lyrFI}PR;{ASi zb#s)|z9VC(>*$O#8yn4mkKxRW<BxOB_nlEmqtQT{xk=F`Zz50xiokyzI5Oyli<hsV z9fqk<<FsK>rBqsS`ND;0EdJaV2%^>1BID;=PwgH3+jngQJi|VwQdzRO+&p=1?xi3j zsMk%7%H<<3yuJYW_Weg)K3{mIQIC_m%qFB(kFy$uTX!B13W9L^{6X^Fhflgfq3F8* zaOt!lz*s!7oK9zs|M2?Jm#^OujGU}YRhHNyF-|U*yL0)x)$0$S&z^565DF9VL~{Ac z^_#Q2r#P8P&qDm^Cz2_AkeQ6r7>NMs^an#7(=CxmI&g5!8j3{G+S<?Nc~~O&KtRku zyyBZA^ANRG2k+e&845>aRHeFZBr$HgUdM=QYi}T)2$98jG0*iyYSiTJoo2LEqi*61 zQ+hVIV~|J%-cwAs6&mTn)7y@ur`v(2d*;wVCq+>NRjCMq;{s$v!eVb;#K_4BEm5!6 zEwE+<!EpulMB;{#7@Nst?EplnOhypgFhE8mJ>5)gC>)=yZlybMHUh_YFUH981Mczg z!3{OVtvWZRQWC#vwKFAHYp~O-yAQTDWHuT15`_FDbe(_YZKj38bxy0@=H8-ESj**d z&wDG?Dk_#rNU2mhY>yn|h6CGi1Bx(e&u%E@h@vV(Bc%f4Jl%=I7bz7GhqLu?uk7Z7 z90=sHw?Y({O3<*#fk2&Zf{;q3Y;k?-WIOVn?J+3`FdB_7rqWq1xYjFwUt}a2b6mQ5 z;|OnHCY#$A423!2*dT*|gxDiQ7B4`QxZ(yO>1E&)0{9x@L>rPdt`8FT&%*hdP=y-* zZrD$M$x$x2F604-Q}{X1ud=Ga;{SspPy~v={~Y*RfB^u;J@J{AlrI4Q0000<MNUMn GLSTaYvw|l8
deleted file mode 100644 index e8b3dfc199d0b61b32be4e9703247574455567d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@<O00001
deleted file mode 100644 index a9eba2afdb28e0811a0437de8465bc22ce36030e..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@<O00001
index aba191b5b2876e9f5932c22a5a8949914d58fe83..50cf9d413caa13928bcf141ccfc9ce301a40cecc GIT binary patch literal 492 zc$@+30Tcd-P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzj!8s8RCwBA{Qv(y11$j)1C0R-F^U>m zyIlnY_`AM*`C3*}UbveS3m6FnQA$>k851+p0WlF_P9|pN??9oTrkb)HR12anU%&qS z^yxG6oqG=$UcY|J`S;J?b#*OW9#pen#lo3qfmA3E|9b!71H-%bA3&CDB-Rq5A{l7O zCNxXfh_!_1RD{P8Z>l9zY?l1_^Jg7COGwTKAWOKpxxkiu`1q0G{ris)OPV|V@FvsD z{BmYtA%WYXA|i_TEcpHBH^}7-Z{NLV0H!Xmm;gUN13w?{ufPBP`gFI}@5Y+ZfL`VS zVntALBo%;s0>o@U$4&-vHE;zHC==Z$r#JwG0ucWNGMh-w$=E<de7YHs+6Bb?P$7`v ziNN?-OtA%3^=)SV{{7qa>GNlPP+Z_Moa9tQs^LVJrg#jG0~)@J;^Mlbs?m&@nQ7PO z&tFI~oTxa6PRe5b`}gm2Ha1q#U%!5nWH?cAuyo!ukb%p{F`T4S1WcMmK<W;(JYt}_ i1%tNIr?~|H0R{lUybWUC2W`jz0000<MNUMnLSTYTOWmyi
index 09844b8247fbcb3b5e012e782e0f7e8db372ad94..824b6a83ff9cdeb7d641534a4ad59e3506a3a693 GIT binary patch literal 799 zc$@(r1K|9LP)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU!!AV3xRCwC#RZD9VQ53$DNhVEZI+IB( zE!4KAD*l5)AyA13g@!H!K@?vrS0WT#6kP}|bm>AAL8)fdg;WSFNCmMV3I$h!5Jatg z&_tVL@|b5biQkQBN#9dxcOLkdnLGEM@1A?Ub1qY>)yP4biyW{WIDxzQ<J{$I#LIC+ zmIEXx2PB^7Z?dfGG=B9lgt73Pt=6hjB~^Qz%PILxCQD4qT3bK<;>pegzLu7{^ME7{ zvMl>_IhE>MTv}fJ%`prU>FGKg2?V4O%sGp(nUze2SXS9t1iZi#?D(RpY4M-)i*$%? zFF|(>2oOZy-2B2Iv#{6}?&+T9Jf2gMD864oB-@E)9f4i3JBuatk)q`3XA+>h{Jde! zAe_ZP)D{ZL<A|ykkz1Os@1Eq6s*dQoAvAV=W(()kUISOF)hf|6y%W)1;W&>o6_v~7 zVbe6}>vQ1C4&s;s-oQCA40Fi%yT*}ByBp6L2MYXHKUUigo2KQw4qUGK5c0Qu*f{t4 zoYlEIb%TurNxInY^Yv57LaLh<(DU|sIpT4<BMryNy;O1nArnz-Juiwvxb0AgG)F>< zFeuBURS*U+XO$q~xRPNHfg9OePB_xtHH}KX0Fv28;<0lt&W8*Y3#Bn7pQnUY#kOD4 zsE}+&1S#MWDs$rd-2Abl;hqnYBu)uD|EWf5KB%l;Q3?b3LXi|pB@zk-IltdGfn3Ct zd_i|YK<yO}t5hoS<kxROybq(GhHdD+QGjcf$!2kc?NOfhPs)-M!;tQ@n^K+k0;5#2 znQU$e&VNwt1J{A$G`Y52C8>0psHzra-R$J8JNJB>6xS><+D-Rh9l$%_1o{{0Xm2Mi zUhi9oBzFJqZGAuP1Ddas&5@*k{f+_;_VdD7M}l5Pbi<h4Ey@2%GDaIAE}duF=HUOO dzm@$FU;wv+C4XurV6XrH002ovPDHLkV1l||be8}C
index 036f4538bf506b9916e6f0b0807da58bd9b38100..a8f89c935f207a15e6046057f2a913db62c33f04 GIT binary patch literal 669 zc$@*90%HA%P)<h;3K|Lk000e1NJLTq000gE000gM1^@s6A4o0H0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU!KS@MERCwBAVqjokOv}m@zV+bg-h;=_ zL<0FN448oB_}NR@H|{>(WNmBD4HM+rcl`YED|ep!zj6QR?+x2_$D(Ow*|z6k@vVo? z|6jiS`2Vg$r#1n_IGBJ0&z_yz&wTv+_5X*@-&xeuHRk~}!)yj=%2!ZS?t1&-3&W=` zU;l2|wEhB6oSPX)upK_I_XiUblc>ItiPG;s|CpsDC4F68-5w^Sq&mwhDtCVT@}24L z-@pGRbhT`lKWo|=pq|Gdjemgn+qp9*UokQ=3K<xgDuOhNOG^0g^9#9t`uYQ`sjs7H z)7q6w7Xj6RZ2Sn)_z$EJ#5sTF)JtT|zkdH=glSs0YS{vyno~gh8e|z0Gyp)hJ_q8n z5)u-R*jN!^!_LOSASESr2P6m61QKUN4n1I?<O2hz3+5-F?TpOK%#3{89DlA}zL*#q z;JpH-5oROH_PvL)ku`O-)E$~Nb;2ni`#;d1EZVyI^Ve<J8HOBHEbF)K$pyyI-{Ti= z|37l>#@~?0*o{E(L?BK{%`Vt;^!&|#CobLjf9ckv->cSdivsBZ>E>nO;7a`R4H9}2 zx?8ubS-yB4Q2aa)GtZtn;S<R8q_k}3uit;NFtc+e0J&R0Vq(G~qH&8>ZF(3Ho45hU z4*+6GSONfIIUo*8&netBd-3Yq?Cc!DK)x_2aJYb24T#l&_&pF`0peG%K!9qN0%9Fd ziUHzlKzx@G8nT>F!QVjq1xXVFl4f2g{TYaV00bBSPx=RJ%h5Wi00000NkvXXu0mjf D^~62A
index cde009cdc5933b5eda5359b9b892787d4275894e..d759a5b37c774371a7e93568bab458c3693a8afe GIT binary patch literal 481 zc$@*@0UrK|P)<h;3K|Lk000e1NJLTq000yK000yS1^@s6jfou%0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUzgGod|RCwBA{Qv(y12q97jB)(pZ460E zeO0cjcOG5i=jE3F{N>x@sL(*|=?j*B#^wf~S_Y8gm<U)X_UY?S`Dd>`Fns*_LzZ7q zNXbG^l@Xr?76JzHfr!6<|A9Fl-oF!o`U+<_5pp4l{J($ynUI5t90N%PR5uVFhBD$p z42)Pj!^OeI@a@Mh22LQ&!UC~hRze6V7#JA7|NMoLY(PolGB9Z<p&R!7=WmAZK*PR% z{|Ppji-VnkgPj$_;t!v`T+>mNHw7k}Z!FNHp#;Quy#jJ22;%@+Kr9Nx4?%w5dHd$| z8%n|rs-FkuWd$I10b+G5>5>PSgHm7|Zzszo@7}(7i<S=m0P#&A-UIaV1CRl)KpY@G zg(cQifEaEd4=?Y2pn(@aae<sXf%p^D9I%VN0r3MIc^QQ-ARu)A5ySn9K(&8ysU7?Y zo9+hw1C}r!ph@HXy*sx)<11;1DZV~=I+&M2WBV=;zoXPZSduyc#9u&sU<~6m5Fo$+ X;{BdGkyHhq00000NkvXXu0mjf)GW)*
index 217c356f9fab54b8080bf31b7f858cda2b457330..741e90ca8ea4a3338ab28302f52fc9c04f8bf2ad GIT binary patch literal 569 zc$@(_0>=G`P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBUz+et)0RCwBA{Qv(y11$j)1C7DZw}1tk zU}<$Do3N13G&VL?#Sb4ohBnofzr$rfYuAKKE-ub+pt_XCnzB1Y`QY9A50hWKe3ks> z?K>w%M#fz=jqO6%)KxXK<$wG3ecIc%@9cqU4`k+-^Alyk*RS6=ffg{_yZ?~k)8{Y7 zOiWA|mVgZZ{rmR>kh(kf9x%Lp_nz(jhYxJT#z8s|?*K8Lzj(>;`O8<ZB`ux(U`whS z+QEjud-s9i>$h(pq1Qm{ykg<Z*XRZ@;>rgR@#&mEY8?=JfcTOU;tWE90%w8ovK|;5 zEm#b{jLjTId>IXB3CPPEVU`FA2r&Ey!e2jsF?{>}ouJ_aEx=|85+G<eQTYI9z%O91 z>}F+Ug^MvWGcoY-@;>6_;eJYSMyslC%NG|D?PWu<;P2mm4BXsY#=v;NnS_b50Gt&6 zV5F9P=&1{zB{(gptZ&7d6oJ?ih_|9!0!+F>L`QN~L3tW8GxJPfF2$M@p%K3ti2Xo( z32`xoKY#z8W%&Q!YD!=GFJg)ckJoSB;!NkDhzC-kK)eaW2j%8BZ{BJF^9Mh%L6ic- zXYnOPG)q94!UtPUW&i~dE*u`0#)D6u7<G)JRp#)w03g5sw_Q-I2jV#-00000NkvXX Hu0mjf7Hk9+
index e6e2017eda05f1f926931d1d94ffb851836372b6..10531135d070736e2ae5e36db6acb2959dc12449 GIT binary patch literal 866 zc$@)Z1D*VdP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU#1W80eRCwC#m`iIDQ546|L_2AkchZQM zCQTaC$43wp-4wcTQ%NCGty&ZnT=)&dwJQ+{qF`NA3MrKqT)7uiRH)dR=2ZjL+UA|K z(++)jZfIS^+BTDWZ&R29e*$;H-2ZRRy>reTVQXs(j&cYpfC``jR0j~ec6-n3Hk%dv zJ};{6jM1QX#^;h_k!TzeKaxP^8h!bcDu9OO&4_uQ*8`4b`#p_Dc(*3YA-l~w?rZai z-c~mVf<Qe3$7$WjWHN%s?SiHz-Q7$!_vF);DUc)yIy?Nm&34;po3}NHf0JngP|JWp zuZKdR5LjGX8cNJ1;n%`%$mI+0Jsg2lI@8<Os3j0$z3+h#Do{CSF`Gyx05kD=b#*Ox z^LoErmwNzX7`0J3Sec3E!y{t70=z*D@PyC+{dmO_f(5{VA+%btW(ZaQ2ZBgvvIJtJ z76_IA`$Nn|2}A&wlVS+g0DD8^@?{8IPKqIT05FB%1;7lV>Pr0n<7Y+gmseIG9EriV znef$AD*Xb7j{Q@yEoSI!KMf}w&0|=x`v(Uu%QXQ!9(s1ZtHU2Mn@kQGDIgHhSOR9F zF_{0k0K3giAiCQ9V7FV}O491ZTQ{!AiUF|i30W<cK(SPU_4RdbYt3jh06sXd+iYX9 zEcfpPv0po_%jR<2Pg%uc39}T(<)qnZ4EyR~6IT^vW6xl*oBBE(7`$`;Eb{{mi^yZK z+dc#(m1aOXWCmis56{tx0Un_~9J2XIu3se%5IWQZs=HS6-1Y$Z8qw-*0auGtCpI)p zU<21p>OpCFxhC^m-a=*bE;i<w1N=4bDw`jtZJsGWrTI)Y+Y^h^HO~xSH}mAl7fW=_ zGXdafo;m<A?{+zH!=B<|o+`kOd3TFb#Nc9{DgYirP!4fpb8~{1d8&nsRP;zJ{?MRr z>LE=S5A#$37MD`w=Ok%^Yi$n>^DXq?KdrC4eJGivJRfxcV*UbZo`-o>g)D(OhnhxZ sP?uPlSJY0|Tc`jkfC_NL0saUu0J6mNQ<KZO0{{R307*qoM6N<$g5YL+`~Uy|
index d40cd295796d434a90a3f0b5dd2238cbd3cf7363..1e39259a108ac59586cec09d725cb8388c933000 GIT binary patch literal 1524 zc$@+B1q=F#P)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU%mPtfGRCwC#S!+yNbrk>K-o7p^loiU_ z@sLLu$WlWxL)?sCAo_)6hJ-~v_#jb3rhYIO&5Sx@#1AuZX1>VGvN7l8d?ZF>rfy+z znbBm4i3w(-P@uFt%1TRH+TQlwK0N=sURElDK5l`<p5)};d)s^O`Tfs1zjMwl5sSsp z{VXDMpGzJ<9>D({fH<3rhkv`SrR4I1gorpuAVLeLnhAm+5rJIrc?xtS8jb$w^ZBn> zrfu|?c>>MNFQ7;yvgZ9Ro;|ra0Dk`Ea#K-JVIRweJ7(uBV3Zxr+ZWLCvJWvVizrI2 zR_`cQ@6u`aR_xMs!-1!%arc)cCF&0*CM}+^aWh)>`33O+k!~IMX~=ja6bkiCTCC)x zWg2<C%j^E0BuP}JDMbzSb*QSc+zz0-thSkJx5muK<yzW24}5;|G*w)zI^$Y$KLxvp z7H&IGD&TRrVDBt0I+1;$T3c6JeYvbm(*suy+!`H6OK$h(<UlkQ`)YR1-Z?R4K^~7c z`D+j8HBfuPxxI1agbjz0X?z0F!JxFRrus|)MKQHC4_p{EF~}bX<d%irKlbr^fk2?s zJUNwYJT~|xP#w7cNmzRl^kL8n(0)(`{}_90+B$>qCIo|_Q&Op<rLwXdLE`7m14oYb zHA}>jw;Ybe<ajrN9s<LC>s&q?2RH!wJ!lm^X`7itGMS8$N+joHQt2K@ZU%=~PCNh< z*vE!h(y{shgP;dCFg{UkfbIu%aN!t@a-Il>!}_Hq_w&W7qTGbgi!b*Y;9>1fV2gx= z#r*y(7#~UVS=bwg_yb@v<n#McFcf+v7z`q)C&B{=&~%3gXb|&zg1imJdotWGoajIB z2TmtPqfLH4ZGgHWJb*|f+JRP6C9bgFW?6eq@E?GYxNr)Fg6)~kCHG9?uIGBBcXnqL z#ThdQon-klPP;06z%VRkq-JPE1owajR0=Vgcy2_1>K}>c5ho1G;QT7b-Vho9#dCL3 z!4g7T{0G>5yeKmbq4faJi3f^;0=%fRYP{|iEDbb#f^5us0PK7P<+ezvKng{HAsYbr z9&yj=lXl!HIDmMv{=E{bkZgrY<-u3qc!$dLVJe_XsKBkIr6p7-#0ZjG8&%?~D?avm z5mZb{E|Ya<@*vFfVp5Fn(F^xT&MjlE0GwOtMuD$=K&cu{Y2Qbm^lQ?22(Ge~73D}O zlXjM<ceJ|Qp5)!njRzo%Zo+bbKgNAMP1EXPm1^kh`R`H+rNTlbYHX;7p{Ar6rnFOD zsOq?dNRZ>X9_rualNk>uQx+>8LRu6B)E~wxSF7%I5%l}q6!zHuN6>=}_3a`;bbZn3 zQq9}%jtl^ZE>tRv+MQ)cEY55^Pidrts(cuhFIGYVD6nz29>HKj>vY-^5YYXP?rX6Q zUiy^-DUpbQb`@Y0xi1)EUbjqJJMau(was#&$nBg+gn=QQcIOC;oo%+6S;x^gU(4N0 z3?MLo!z-=>1MsX{udhY5)m6YSMJ7^APN5jG!aWTkhN-#jSk#W2Cy~W!TXS~CxzX65 z2N2qkXf)E+{dAWjmjFmuJ_PMe{!T8JVT#2e!42`y#UhxU5gnkpQF5aM&jv)=ZzTZ8 zGq8NhH)BFbHXzb|GY8CsskJuF9&{SR%nP7xYh8mIxlxlDSk7(`iOAuBuP<tH=7A({ zU@Cnav_1X?0*9F%)P$!|(BDBX#an1zT0w{SW-(h&5JLXJ0f18dsbC<s>g6tOQ4XXM zPN&a(quGuCQU>94x`vM(|4b?9%iSD+_)j=t5dYjXA(mwg@sJzbZXVds6JR_)z1`T3 zA(RRTZ2S{I-S+JcU@Z{5@qcaCBwnjXVh|6ZJMUBXY-GIPbzmzb|1V`8KpsFIz}CvY a0t^7bM3c$!jR;`?0000<MNUMnLSTX>MaK{T
index d720b270ec6bbb9fc42631977ff6e557ad3c80f9..06b539a4bf7142b25a98a4a10da514e1778d542f GIT binary patch literal 1005 zc$@+40}}j+P)<h;3K|Lk000e1NJLTq000~S000~a1^@s6at+^<0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU#k4Z#9RCwCF)@w*pQ5*p9JMX=2J}3=> zrum_KTTuiG5|mJ2g;86+HASgD^g@yXL(C_dREn0AlBG<;M=slzCPoR8p^j9{QVXPq zehAYvbGvts&e40uy6$o2hyL(qoICINd0ziBfzfCr{$~ix8?gz=8w-j`WHU3<4<q)4 zJ?kI+tkdfa*qxE26A`x4mwNqXKqB5EjxWf|Nt4ypE}-w>;G9rH5*_DpB`aG=Qq)ng z*H&4ZqB91*3_EcIldHPo#bR$6=;y@6jLbGTh&3aG*tP6jrHi|J__BsEQWQxzQzSe7 z;eERF*x?p?BQ?hYgF+r?8662;AY4R3!Joy2p5mfhsl2s$9*z)#F5SIqrH7~I0fWIv z=nbnKi-a^5Y6;UYtm!)^fq<Buo$ZR;A1Vc)2F{n8ytS!Mqh$;TgQ3x~1f$c_fx$a! ztxc~j3<mrMmo-{lTXW-E=)h;N2lj4xX;0aWf_6P`2)0m!wRdzUS;AnjEUPaq%#q)} zQ`QTc2wVa=`lP8rcB?o~iGvDh%7pm`1XbI>+7<Ga2GAVi9MiF&KyC&ZCW%Q%&CI$U zMe^nkt?9(av2;mPWSgSnWxQ`dpiNBqw6z{I2SNUTGmJJ3;Rq@O=*;vtnb_MW#Ssjh zLjiBo*+rdcYV{DWbgsk35J>Sr9rs85@|MRd5BMm<LvS(k5fP4}>&4J6T@!u7ljf+b zyHhn}tE|0HwW|TvU=Onj!hn?peEh7cdE_IFj^0Cqa%U;vn#Lz2?5(J(@dC{`@SYy~ zwlKr&o-<2F29-f>S=NN5U20leT+9*lpX&)1gBzr|v3>%6+NwxaHsl)6E>@DCtpato z@pegm=Xy|qBN(^!;clD)xm_BYn4EDnJBp@h5@&kN*AN#&=WGt-CXk^3O~pmg8d9x_ z&ZKR=0oa8YoKr1#-Uh&3S65zIsI)e{egVO?O>&iKdRH!Bk`|>cEo*TxJ+C;}M3*!S zO$l97LDLn1bV}^;dt;*`UvM!C70D_(GNhhLlpLvn4g!BKF8mt1bT+kebokwOTnq;t zQV)E+a3-ZftJRG2FJL%aKQ}k`gEuRy&plVj2f3TtCT1StyZzDC7J4!+=~Tp_$X%Du zpRQsV<`sB031^sJX;x4!=eeH+SeOMg1mp$|`UEj+rA@^Bx?;I0z{Yr2o-4OzO9(^Y bUjYUHm#Gw_>%k|O00000NkvXXu0mjfdI88~
index ee1ca9dba54f7d3fefff0c43db6f58c6000efced..568411585e2680d0f8786d488500d5f3e3b67f8d GIT binary patch literal 481 zc%17D@N?(olHy`uVBq!ia0vp^8X(NU1|)m_?Z^dEk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+7@Iv^978H@CH?vT-~Mm{Th9?Ko4Su?T=#?Grxt$dsf?0~ zi<@q7Gt%(P&u@>f*PB*))-BklAMjPhnop!cN2H?f=ZS~SL2A>sEzme1$}8kh(>_Tc zWs%GK<^A%NoGTtKH0hct!DcB@`d|gKyR5~l1A**)RuhaIN|GJJoH(3&dV5<NC(rGD z`1^dkL{W@PPS1`n6R+H1GMl-j&~)Yp^Hzy}%`$8`VTLvAW@|4z-D!DK($eyV#0kUi zpQq=a-x88?wejrQd>t2)nJ1Xy_y7OHe}w1BjNflxhnFd+avkCC%rv?v`{(a(_9<U> zxEFt1!OZTx-jBT_wjp9($a&4xtGsn0H>*laXG-wTvzzeCY0=L5h97JK?-|96`5kvY zH5ABieJT~iRhcL#n5`h&<9^o9sH*gT!w+MD{cTrO<QLAkQfD}O!-f?yjJf3vzw{>D z)|Wf0vY1Z>$+LV5^VGM69si~)oyS<n*|+SLtkJBfkkSY7OunWQ9>)c|a%f;+W>EQB V=VqJKlM0M822WQ%mvv4FO#r;p$T$E1
index 9cde69c572a58b0f3f18bae7c89058e2a2bb311a..2ea325016270499454172bda0aac832c02615bc0 GIT binary patch literal 966 zc$@*o13CPOP)<h;3K|Lk000e1NJLTq001xm001xu1^@s6R|5Hm0000PbVXQnQ*UN; zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU#Xh}ptRCwC#nBPkjQ547T%;?gl><@Q0 zOwnvzfAkOpKKT#?ML{nS2+ER54{a3qC-l;r1VL;?OQp8yDq#;j*^AIa^dN~uV5$4V z)zo5t3C_->Hg4y_EZDlb_s-r`f;n)x?Cfyo`?=@bbIuHx$z;&~Y@80D1Ly!cfDWJo z(AdE1QKQRwx>FRz*{fGBP3?DISMTkDYgJh-sLAC-O^wcTm6a9M;YjrT{6Yvtmw%wq zp=U&TcpCA(mwvOwWcnbA=|P_7KfQVT&aHLlu=qx213KZbd&<g$8AVYh?6#^AxF*!s z)e^5$Mtb8D-+;NiynOQ8{6bqOw1^xIn*g5h508zb8(kd%E#l24lP8%>`KD*SAX(l- ztt~FM)nZnh4X19xZ3;6F+`HdzSXuiy5sN3<f}seKWEm|jub^N!BFOS@4B^%yUY2EF zB)WuF*M6bY`Z}7M528de)g4bJy-Yo@5DL3sYUel(WzP(rF$5T~C-xJcwPb1?O?{rh zYj?xXyDZN@5XRTs1D}N;@kAl<yVnFG4oM<_u~)t=m@Z<7d=JbAVYOJO#j6$|-F@mb z3aQZn(<F?udlrK5!r24DNiiCa^*}5KzRv~WI-(WdgAXulT50M44aCk)Ca}G|jlD!A zUiCWrI-o8bBMqmz+8TFl%}HwUhtf)rc%r7dTKS_W!piC@wfK^S5Di35W}({ol7$dW zIAsUxuwe#J2;u-^BAy9A4#X0{?H^f*r)uU3*_oE6>(EiwN21FJr_Ov<Sy6#nnj6~< z216(I0<IId2Rd>OycinsK(+OW>GZzhv85#m#S=;4xY6jhRaxE8eg0Fij|2dVC&=@8 z>jVo3{;<TC3W6^}{2c=E<0KWk7zkdgczCIK8eS~e9(0km9a<rHt>Pmfe(fhwdk`xn z1Qo#Z!C_kQStEvkZ02rlcCiQOf9Ul{5}9}?Z25{55rmkQ{2b49FfC-gxB85mTU%bc z-G<`vgck9+5PKTHEJQjj2^$-tS4{wHJOJYHD`l)m@kE}0LWiF>%le%d3%iCt926<O zAOzT~n!VVb0T4J1)8!lpE#eP?z~V2c|FO?PD#Uphk74u`A$~Um7W@FlBNZq{vw;42 oT?fzsbO0Sd2hahI(*6oC0Ol{prF{tFwg3PC07*qoM6N<$f=iLRG5`Po
--- a/mobile/android/base/resources/drawable/address_bar_bg.xml +++ b/mobile/android/base/resources/drawable/address_bar_bg.xml @@ -1,11 +1,11 @@ <?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item android:right="44dp"> <bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/address_bar_texture" - android:tileMode="repeat" + android:tileMode="mirror" android:dither="false"/> </item> </layer-list>
--- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -964,22 +964,19 @@ var NativeWindow = { delete this.doorhanger._callbacks[id]; } } } } }, contextmenus: { items: {}, // a list of context menu items that we may show - textContext: null, // saved selector for text input areas - _contextId: 0, // id to assign to new context menu items if they are added init: function() { - this.textContext = this.SelectorContext("input[type='text'],input[type='password'],textarea"); this.imageContext = this.SelectorContext("img"); Services.obs.addObserver(this, "Gesture:LongPress", false); // TODO: These should eventually move into more appropriate classes this.add(Strings.browser.GetStringFromName("contextmenu.openInNewTab"), this.linkOpenableContext, function(aTarget) { @@ -1075,16 +1072,23 @@ var NativeWindow = { let dontOpen = /^(mailto|javascript|news|snews)$/; return (scheme && !dontOpen.test(scheme)); } return false; } }, + textContext: { + matches: function textContext(aElement) { + return ((aElement instanceof Ci.nsIDOMHTMLInputElement && aElement.mozIsTextField(false)) + || aElement instanceof Ci.nsIDOMHTMLTextAreaElement); + } + }, + _sendToContent: function(aX, aY) { // initially we look for nearby clickable elements. If we don't find one we fall back to using whatever this click was on let rootElement = ElementTouchHelper.elementFromPoint(BrowserApp.selectedBrowser.contentWindow, aX, aY); if (!rootElement) rootElement = ElementTouchHelper.anyElementFromPoint(BrowserApp.selectedBrowser.contentWindow, aX, aY) this.menuitems = null; let element = rootElement; @@ -3430,17 +3434,17 @@ var ConsoleAPI = { return aSourceURL; } }; var ClipboardHelper = { init: function() { NativeWindow.contextmenus.add(Strings.browser.GetStringFromName("contextmenu.copy"), ClipboardHelper.getCopyContext(false), ClipboardHelper.copy.bind(ClipboardHelper)); NativeWindow.contextmenus.add(Strings.browser.GetStringFromName("contextmenu.copyAll"), ClipboardHelper.getCopyContext(true), ClipboardHelper.copy.bind(ClipboardHelper)); - NativeWindow.contextmenus.add(Strings.browser.GetStringFromName("contextmenu.selectAll"), NativeWindow.contextmenus.textContext, ClipboardHelper.select.bind(ClipboardHelper)); + NativeWindow.contextmenus.add(Strings.browser.GetStringFromName("contextmenu.selectAll"), ClipboardHelper.selectAllContext, ClipboardHelper.select.bind(ClipboardHelper)); NativeWindow.contextmenus.add(Strings.browser.GetStringFromName("contextmenu.paste"), ClipboardHelper.pasteContext, ClipboardHelper.paste.bind(ClipboardHelper)); NativeWindow.contextmenus.add(Strings.browser.GetStringFromName("contextmenu.changeInputMethod"), NativeWindow.contextmenus.textContext, ClipboardHelper.inputMethod.bind(ClipboardHelper)); }, get clipboardHelper() { delete this.clipboardHelper; return this.clipboardHelper = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); }, @@ -3480,28 +3484,45 @@ var ClipboardHelper = { inputMethod: function(aElement) { Cc["@mozilla.org/imepicker;1"].getService(Ci.nsIIMEPicker).show(); }, getCopyContext: function(isCopyAll) { return { matches: function(aElement) { if (NativeWindow.contextmenus.textContext.matches(aElement)) { + // Don't include "copy" for password fields. + // mozIsTextField(true) tests for only non-password fields. + if (aElement instanceof Ci.nsIDOMHTMLInputElement && !aElement.mozIsTextField(true)) + return false; + let selectionStart = aElement.selectionStart; let selectionEnd = aElement.selectionEnd; if (selectionStart != selectionEnd) return true; - else if (isCopyAll) + + if (isCopyAll && aElement.textLength > 0) return true; } return false; } } }, + selectAllContext: { + matches: function selectAllContextMatches(aElement) { + if (NativeWindow.contextmenus.textContext.matches(aElement)) { + let selectionStart = aElement.selectionStart; + let selectionEnd = aElement.selectionEnd; + return (selectionStart > 0 || selectionEnd < aElement.textLength); + } + return false; + } + }, + pasteContext: { matches: function(aElement) { if (NativeWindow.contextmenus.textContext.matches(aElement)) { let flavors = ["text/unicode"]; return ClipboardHelper.clipboard.hasDataMatchingFlavors(flavors, flavors.length, Ci.nsIClipboard.kGlobalClipboard); } return false; }
--- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -3409,15 +3409,15 @@ pref("profiler.entries", 100000); #ifdef XP_WIN // On 32-bit Windows, fire a low-memory notification if we have less than this // many mb of virtual address space available. pref("memory.low_virtual_memory_threshold_mb", 128); // On Windows 32- or 64-bit, fire a low-memory notification if we have less // than this many mb of physical memory available on the whole machine. -pref("memory.low_physical_mem_threshold_mb", 0); +pref("memory.low_physical_memory_threshold_mb", 0); // On Windows 32- or 64-bit, don't fire a low-memory notification because of // low available physical memory more than once every // low_physical_memory_notification_interval_ms. pref("memory.low_physical_memory_notification_interval_ms", 10000); #endif
--- a/netwerk/base/src/nsAutodialWin.cpp +++ b/netwerk/base/src/nsAutodialWin.cpp @@ -41,16 +41,17 @@ // Registry entries for Autodial mappings are located here: // HKEY_CURRENT_USER\Software\Microsoft\RAS Autodial\Addresses #include <windows.h> #include <winsvc.h> #include "nsString.h" #include "nsAutodialWin.h" #include "prlog.h" +#include "nsWindowsHelpers.h" #define AUTODIAL_DEFAULT AUTODIAL_NEVER // // Log module for autodial logging... // // To enable logging (see prlog.h for full details): // @@ -510,29 +511,31 @@ nsresult nsAutodial::GetDefaultEntryName return NS_OK; } // Determine if the autodial service is running on this PC. bool nsAutodial::IsAutodialServiceRunning() { - SC_HANDLE hSCManager = - OpenSCManager(nsnull, SERVICES_ACTIVE_DATABASE, SERVICE_QUERY_STATUS); + nsAutoServiceHandle hSCManager(OpenSCManager(nsnull, + SERVICES_ACTIVE_DATABASE, + SERVICE_QUERY_STATUS)); if (hSCManager == nsnull) { LOGE(("Autodial: failed to open service control manager. Error %d.", ::GetLastError())); return false; } - SC_HANDLE hService = - OpenServiceW(hSCManager, L"RasAuto", SERVICE_QUERY_STATUS); + nsAutoServiceHandle hService(OpenServiceW(hSCManager, + L"RasAuto", + SERVICE_QUERY_STATUS)); if (hSCManager == nsnull) { LOGE(("Autodial: failed to open RasAuto service.")); return false; } SERVICE_STATUS status;
--- a/netwerk/base/src/nsIOService.cpp +++ b/netwerk/base/src/nsIOService.cpp @@ -58,17 +58,16 @@ #include "nsIPrefLocalizedString.h" #include "nsICategoryManager.h" #include "nsXPCOM.h" #include "nsISupportsPrimitives.h" #include "nsIProxiedProtocolHandler.h" #include "nsIProxyInfo.h" #include "nsEscape.h" #include "nsNetCID.h" -#include "nsIRecyclingAllocator.h" #include "nsISocketTransport.h" #include "nsCRT.h" #include "nsSimpleNestedURI.h" #include "nsNetUtil.h" #include "nsThreadUtils.h" #include "nsIPermissionManager.h" #include "nsTArray.h" #include "nsIConsoleService.h" @@ -81,16 +80,19 @@ #include "nsNativeConnectionHelper.h" #endif #define PORT_PREF_PREFIX "network.security.ports." #define PORT_PREF(x) PORT_PREF_PREFIX x #define AUTODIAL_PREF "network.autodial-helper.enabled" #define MANAGE_OFFLINE_STATUS_PREF "network.manage-offline-status" +// Nb: these have been misnomers since bug 715770 removed the buffer cache. +// "network.segment.count" and "network.segment.size" would be better names, +// but the old names are still used to preserve backward compatibility. #define NECKO_BUFFER_CACHE_COUNT_PREF "network.buffer.cache.count" #define NECKO_BUFFER_CACHE_SIZE_PREF "network.buffer.cache.size" #define MAX_RECURSION_COUNT 50 nsIOService* gIOService = nsnull; static bool gHasWarnedUploadChannel2; @@ -161,18 +163,17 @@ PRInt16 gBadPortList[] = { 6000, // x11 0, // This MUST be zero so that we can populating the array }; static const char kProfileChangeNetTeardownTopic[] = "profile-change-net-teardown"; static const char kProfileChangeNetRestoreTopic[] = "profile-change-net-restore"; static const char kProfileDoChange[] = "profile-do-change"; -// Necko buffer cache -nsIMemory* nsIOService::gBufferCache = nsnull; +// Necko buffer defaults PRUint32 nsIOService::gDefaultSegmentSize = 4096; PRUint32 nsIOService::gDefaultSegmentCount = 24; //////////////////////////////////////////////////////////////////////////////// nsIOService::nsIOService() : mOffline(true) , mOfflineForProfileChange(false) @@ -240,34 +241,16 @@ nsIOService::Init() observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, true); observerService->AddObserver(this, NS_NETWORK_LINK_TOPIC, true); } else NS_WARNING("failed to get observer service"); NS_TIME_FUNCTION_MARK("Registered observers"); - // Get the allocator ready - if (!gBufferCache) { - nsresult rv = NS_OK; - nsCOMPtr<nsIRecyclingAllocator> recyclingAllocator = - do_CreateInstance(NS_RECYCLINGALLOCATOR_CONTRACTID, &rv); - - if (NS_FAILED(rv)) - return rv; - rv = recyclingAllocator->Init(gDefaultSegmentCount, - (15 * 60), // 15 minutes - "necko"); - - NS_WARN_IF_FALSE(NS_SUCCEEDED(rv), "Was unable to allocate. No gBufferCache."); - CallQueryInterface(recyclingAllocator, &gBufferCache); - } - - NS_TIME_FUNCTION_MARK("Set up the recycling allocator"); - gIOService = this; InitializeNetworkLinkService(); NS_TIME_FUNCTION_MARK("Set up network link service"); return NS_OK; } @@ -919,17 +902,17 @@ nsIOService::PrefsChanged(nsIPrefBranch &size))) /* check for bogus values and default if we find such a value * the upper limit here is arbitrary. having a 1mb segment size * is pretty crazy. if you remove this, consider adding some * integer rollover test. */ if (size > 0 && size < 1024*1024) gDefaultSegmentSize = size; - NS_WARN_IF_FALSE( (!(size & (size - 1))) , "network buffer cache size is not a power of 2!"); + NS_WARN_IF_FALSE( (!(size & (size - 1))) , "network segment size is not a power of 2!"); } } void nsIOService::ParsePortList(nsIPrefBranch *prefBranch, const char *pref, bool remove) { nsXPIDLCString portList;
--- a/netwerk/base/src/nsIOService.h +++ b/netwerk/base/src/nsIOService.h @@ -160,19 +160,17 @@ private: // cached categories nsCategoryCache<nsIChannelEventSink> mChannelEventSinks; nsCategoryCache<nsIContentSniffer> mContentSniffers; nsTArray<PRInt32> mRestrictedPortList; bool mAutoDialEnabled; public: - // Necko buffer cache. Used for all default buffer sizes that necko - // allocates. - static nsIMemory *gBufferCache; + // Used for all default buffer sizes that necko allocates. static PRUint32 gDefaultSegmentSize; static PRUint32 gDefaultSegmentCount; }; /** * Reference to the IO service singleton. May be null. */ extern nsIOService* gIOService;
--- a/netwerk/base/src/nsNetSegmentUtils.h +++ b/netwerk/base/src/nsNetSegmentUtils.h @@ -36,28 +36,16 @@ * ***** END LICENSE BLOCK ***** */ #ifndef nsNetSegmentUtils_h__ #define nsNetSegmentUtils_h__ #include "nsIOService.h" /** - * returns preferred allocator for given segment size. NULL implies - * system allocator. this result can be used when allocating a pipe. - */ - -static inline nsIMemory * -net_GetSegmentAlloc(PRUint32 segsize) -{ - return (segsize == nsIOService::gDefaultSegmentSize) - ? nsIOService::gBufferCache : nsnull; -} - -/** * applies defaults to segment params in a consistent way. */ static inline void net_ResolveSegmentParams(PRUint32 &segsize, PRUint32 &segcount) { if (!segsize) segsize = nsIOService::gDefaultSegmentSize;
--- a/netwerk/base/src/nsSocketTransport2.cpp +++ b/netwerk/base/src/nsSocketTransport2.cpp @@ -1720,22 +1720,21 @@ nsSocketTransport::OpenInputStream(PRUin nsCOMPtr<nsIAsyncInputStream> pipeIn; if (!(flags & OPEN_UNBUFFERED) || (flags & OPEN_BLOCKING)) { // XXX if the caller wants blocking, then the caller also gets buffered! //bool openBuffered = !(flags & OPEN_UNBUFFERED); bool openBlocking = (flags & OPEN_BLOCKING); net_ResolveSegmentParams(segsize, segcount); - nsIMemory *segalloc = net_GetSegmentAlloc(segsize); // create a pipe nsCOMPtr<nsIAsyncOutputStream> pipeOut; rv = NS_NewPipe2(getter_AddRefs(pipeIn), getter_AddRefs(pipeOut), - !openBlocking, true, segsize, segcount, segalloc); + !openBlocking, true, segsize, segcount); if (NS_FAILED(rv)) return rv; // async copy from socket to pipe rv = NS_AsyncCopy(&mInput, pipeOut, gSocketTransportService, NS_ASYNCCOPY_VIA_WRITESEGMENTS, segsize); if (NS_FAILED(rv)) return rv; *result = pipeIn; @@ -1767,22 +1766,21 @@ nsSocketTransport::OpenOutputStream(PRUi nsresult rv; nsCOMPtr<nsIAsyncOutputStream> pipeOut; if (!(flags & OPEN_UNBUFFERED) || (flags & OPEN_BLOCKING)) { // XXX if the caller wants blocking, then the caller also gets buffered! //bool openBuffered = !(flags & OPEN_UNBUFFERED); bool openBlocking = (flags & OPEN_BLOCKING); net_ResolveSegmentParams(segsize, segcount); - nsIMemory *segalloc = net_GetSegmentAlloc(segsize); // create a pipe nsCOMPtr<nsIAsyncInputStream> pipeIn; rv = NS_NewPipe2(getter_AddRefs(pipeIn), getter_AddRefs(pipeOut), - true, !openBlocking, segsize, segcount, segalloc); + true, !openBlocking, segsize, segcount); if (NS_FAILED(rv)) return rv; // async copy from socket to pipe rv = NS_AsyncCopy(pipeIn, &mOutput, gSocketTransportService, NS_ASYNCCOPY_VIA_READSEGMENTS, segsize); if (NS_FAILED(rv)) return rv; *result = pipeOut;
--- a/netwerk/base/src/nsStreamListenerTee.cpp +++ b/netwerk/base/src/nsStreamListenerTee.cpp @@ -31,16 +31,17 @@ * 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 "nsStreamListenerTee.h" +#include "nsProxyRelease.h" NS_IMPL_ISUPPORTS3(nsStreamListenerTee, nsIStreamListener, nsIRequestObserver, nsIStreamListenerTee) NS_IMETHODIMP nsStreamListenerTee::OnStartRequest(nsIRequest *request, @@ -62,17 +63,27 @@ nsStreamListenerTee::OnStopRequest(nsIRe nsresult status) { NS_ENSURE_TRUE(mListener, NS_ERROR_NOT_INITIALIZED); // it is critical that we close out the input stream tee if (mInputTee) { mInputTee->SetSink(nsnull); mInputTee = 0; } - mSink = 0; + + // release sink on the same thread where the data was written (bug 716293) + if (mEventTarget) { + nsIOutputStream *sink = nsnull; + mSink.swap(sink); + NS_ProxyRelease(mEventTarget, sink); + } + else { + mSink = 0; + } + nsresult rv = mListener->OnStopRequest(request, context, status); if (mObserver) mObserver->OnStopRequest(request, context, status); mObserver = 0; return rv; } NS_IMETHODIMP
--- a/netwerk/base/src/nsStreamTransportService.cpp +++ b/netwerk/base/src/nsStreamTransportService.cpp @@ -124,23 +124,22 @@ nsInputStreamTransport::OpenInputStream( // XXX if the caller requests an unbuffered stream, then perhaps // we'd want to simply return mSource; however, then we would // not be reading mSource on a background thread. is this ok? bool nonblocking = !(flags & OPEN_BLOCKING); net_ResolveSegmentParams(segsize, segcount); - nsIMemory *segalloc = net_GetSegmentAlloc(segsize); nsCOMPtr<nsIAsyncOutputStream> pipeOut; rv = NS_NewPipe2(getter_AddRefs(mPipeIn), getter_AddRefs(pipeOut), nonblocking, true, - segsize, segcount, segalloc); + segsize, segcount); if (NS_FAILED(rv)) return rv; mInProgress = true; // startup async copy process... rv = NS_AsyncCopy(this, pipeOut, target, NS_ASYNCCOPY_VIA_WRITESEGMENTS, segsize); if (NS_SUCCEEDED(rv)) @@ -335,23 +334,22 @@ nsOutputStreamTransport::OpenOutputStrea // XXX if the caller requests an unbuffered stream, then perhaps // we'd want to simply return mSink; however, then we would // not be writing to mSink on a background thread. is this ok? bool nonblocking = !(flags & OPEN_BLOCKING); net_ResolveSegmentParams(segsize, segcount); - nsIMemory *segalloc = net_GetSegmentAlloc(segsize); nsCOMPtr<nsIAsyncInputStream> pipeIn; rv = NS_NewPipe2(getter_AddRefs(pipeIn), getter_AddRefs(mPipeOut), true, nonblocking, - segsize, segcount, segalloc); + segsize, segcount); if (NS_FAILED(rv)) return rv; mInProgress = true; // startup async copy process... rv = NS_AsyncCopy(pipeIn, this, target, NS_ASYNCCOPY_VIA_READSEGMENTS, segsize); if (NS_SUCCEEDED(rv))
--- a/netwerk/build/nsNetModule.cpp +++ b/netwerk/build/nsNetModule.cpp @@ -650,19 +650,16 @@ static nsresult nsNetStartup() // Net module shutdown hook static void nsNetShutdown() { // Release the url parser that the stdurl is holding. nsStandardURL::ShutdownGlobalObjects(); - // Release buffer cache - NS_IF_RELEASE(nsIOService::gBufferCache); - // Release global state used by the URL helper module. net_ShutdownURLHelper(); #ifdef XP_MACOSX net_ShutdownURLHelperOSX(); #endif // Release necko strings delete gNetStrings;
--- a/netwerk/cache/nsCacheService.cpp +++ b/netwerk/cache/nsCacheService.cpp @@ -1172,16 +1172,19 @@ nsCacheService::Shutdown() // deallocate memory and disk caches delete mMemoryDevice; mMemoryDevice = nsnull; delete mDiskDevice; mDiskDevice = nsnull; + if (mOfflineDevice) + mOfflineDevice->Shutdown(); + NS_IF_RELEASE(mOfflineDevice); #ifdef PR_LOGGING LogCacheStatistics(); #endif mCacheIOThread.swap(cacheIOThread); }
--- a/netwerk/cache/nsDiskCacheDeviceSQL.cpp +++ b/netwerk/cache/nsDiskCacheDeviceSQL.cpp @@ -825,21 +825,16 @@ NS_IMPL_THREADSAFE_ISUPPORTS1(nsOfflineC nsOfflineCacheDevice::nsOfflineCacheDevice() : mDB(nsnull) , mCacheCapacity(0) , mDeltaCounter(0) { } -nsOfflineCacheDevice::~nsOfflineCacheDevice() -{ - Shutdown(); -} - /* static */ bool nsOfflineCacheDevice::GetStrictFileOriginPolicy() { nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID); bool retval; if (prefs && NS_SUCCEEDED(prefs->GetBoolPref("security.fileuri.strict_origin_policy", &retval)))
--- a/netwerk/cache/nsDiskCacheDeviceSQL.h +++ b/netwerk/cache/nsDiskCacheDeviceSQL.h @@ -97,18 +97,16 @@ public: NS_DECL_ISUPPORTS NS_DECL_NSIAPPLICATIONCACHESERVICE /** * nsCacheDevice methods */ - virtual ~nsOfflineCacheDevice(); - static nsOfflineCacheDevice *GetInstance(); virtual nsresult Init(); virtual nsresult Shutdown(); virtual const char * GetDeviceID(void); virtual nsCacheEntry * FindEntry(nsCString * key, bool *collision); virtual nsresult DeactivateEntry(nsCacheEntry * entry);
--- a/netwerk/protocol/http/nsHttpPipeline.cpp +++ b/netwerk/protocol/http/nsHttpPipeline.cpp @@ -721,18 +721,17 @@ nsHttpPipeline::FillSendBuf() nsresult rv; if (!mSendBufIn) { // allocate a single-segment pipe rv = NS_NewPipe(getter_AddRefs(mSendBufIn), getter_AddRefs(mSendBufOut), nsIOService::gDefaultSegmentSize, /* segment size */ nsIOService::gDefaultSegmentSize, /* max size */ - true, true, - nsIOService::gBufferCache); + true, true); if (NS_FAILED(rv)) return rv; } PRUint32 n, avail; nsAHttpTransaction *trans; nsITransport *transport = Transport(); while ((trans = Request(0)) != nsnull) {
--- a/netwerk/protocol/http/nsHttpTransaction.cpp +++ b/netwerk/protocol/http/nsHttpTransaction.cpp @@ -292,18 +292,17 @@ nsHttpTransaction::Init(PRUint8 caps, rv = mRequestStream->Available(&mRequestSize); if (NS_FAILED(rv)) return rv; // create pipe for response stream rv = NS_NewPipe2(getter_AddRefs(mPipeIn), getter_AddRefs(mPipeOut), true, true, nsIOService::gDefaultSegmentSize, - nsIOService::gDefaultSegmentCount, - nsIOService::gBufferCache); + nsIOService::gDefaultSegmentCount); if (NS_FAILED(rv)) return rv; NS_ADDREF(*responseBody = mPipeIn); return NS_OK; } nsAHttpConnection * nsHttpTransaction::Connection()
--- a/netwerk/test/unit/test_URIs.js +++ b/netwerk/test/unit/test_URIs.js @@ -218,19 +218,19 @@ var gTests = [ ref: "", nsIURL: false, nsINestedURI: false }, { spec: "javascript:new Date()", scheme: "javascript", prePath: "javascript:", path: "new%20Date()", ref: "", nsIURL: false, nsINestedURI: false }, - { spec: "moz-filedata:123456", - scheme: "moz-filedata", - prePath: "moz-filedata:", + { spec: "blob:123456", + scheme: "blob", + prePath: "blob:", path: "123456", ref: "", nsIURL: false, nsINestedURI: false, immutable: true }, { spec: "place:redirectsMode=2&sort=8&maxResults=10", scheme: "place", prePath: "place:", path: "redirectsMode=2&sort=8&maxResults=10", ref: "",
--- a/netwerk/test/unit/test_bug660066.js +++ b/netwerk/test/unit/test_bug660066.js @@ -1,13 +1,13 @@ /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ Components.utils.import("resource://gre/modules/NetUtil.jsm"); const Ci = Components.interfaces; const SIMPLEURI_SPEC = "data:text/plain,hello world"; -const FILEDATA_SPEC = "moz-filedata:123456"; +const BLOBURI_SPEC = "blob:123456"; function do_info(text, stack) { if (!stack) stack = Components.stack.caller; dump( "\n" + "TEST-INFO | " + stack.filename + " | [" + stack.name + " : " + stack.lineNumber + "] " + text + "\n"); @@ -22,22 +22,22 @@ function do_check_uri_neq(uri1, uri2) do_info("Checking equality in reverse direction..."); do_check_false(uri2.equals(uri1)); do_check_false(uri2.equalsExceptRef(uri1)); } function run_test() { var simpleURI = NetUtil.newURI(SIMPLEURI_SPEC); - var fileDataURI = NetUtil.newURI(FILEDATA_SPEC); + var fileDataURI = NetUtil.newURI(BLOBURI_SPEC); - do_info("Checking that " + SIMPLEURI_SPEC + " != " + FILEDATA_SPEC); + do_info("Checking that " + SIMPLEURI_SPEC + " != " + BLOBURI_SPEC); do_check_uri_neq(simpleURI, fileDataURI); do_info("Changing the nsSimpleURI spec to match the nsFileDataURI"); - simpleURI.spec = FILEDATA_SPEC; + simpleURI.spec = BLOBURI_SPEC; do_info("Verifying that .spec matches"); do_check_eq(simpleURI.spec, fileDataURI.spec); do_info("Checking that nsSimpleURI != nsFileDataURI despite their .spec matching") do_check_uri_neq(simpleURI, fileDataURI); }
--- a/parser/htmlparser/public/nsIHTMLContentSink.h +++ b/parser/htmlparser/public/nsIHTMLContentSink.h @@ -77,20 +77,19 @@ * * NOTE: I haven't figured out how sub-documents (non-frames) * are going to be handled. Stay tuned. */ #include "nsIParserNode.h" #include "nsIContentSink.h" #include "nsHTMLTags.h" -// d19e6730-5e2f-4131-89db-8a918515097d #define NS_IHTML_CONTENT_SINK_IID \ -{ 0xd19e6730, 0x5e2f, 0x4131, \ - { 0x89, 0xdb, 0x8a, 0x91, 0x85, 0x15, 0x09, 0x7d } } +{ 0x44b5a4f4, 0x01f7, 0x4116, \ + { 0xb5, 0xa5, 0x56, 0x4d, 0x64, 0x0b, 0x68, 0x1f } } #define MAX_REFLOW_DEPTH 200 class nsIHTMLContentSink : public nsIContentSink { public: NS_DECLARE_STATIC_IID_ACCESSOR(NS_IHTML_CONTENT_SINK_IID) @@ -212,24 +211,16 @@ public: * * XXX Should the parser also parse the internal subset? * * @param nsIParserNode reference to parser node interface */ NS_IMETHOD AddDocTypeDecl(const nsIParserNode& aNode) = 0; /** - * This gets called by the parser to notify observers of - * the tag - * - * @param aErrorResult the error code - */ - NS_IMETHOD NotifyTagObservers(nsIParserNode* aNode) = 0; - - /** * Call this method to determnine if a FORM is on the sink's stack * * @return true if found else false */ NS_IMETHOD_(bool) IsFormOnStack() = 0; };
--- a/parser/htmlparser/public/nsIParserService.h +++ b/parser/htmlparser/public/nsIParserService.h @@ -47,35 +47,16 @@ class nsIParser; class nsIParserNode; #define NS_PARSERSERVICE_CONTRACTID "@mozilla.org/parser/parser-service;1" // {90a92e37-abd6-441b-9b39-4064d98e1ede} #define NS_IPARSERSERVICE_IID \ { 0x90a92e37, 0xabd6, 0x441b, { 0x9b, 0x39, 0x40, 0x64, 0xd9, 0x8e, 0x1e, 0xde } } -// {78081E70-AD53-11d5-8498-0010A4E0C706} -#define NS_IOBSERVERENTRY_IID \ -{ 0x78081e70, 0xad53, 0x11d5, { 0x84, 0x98, 0x00, 0x10, 0xa4, 0xe0, 0xc7, 0x06 } } - - -class nsIObserverEntry : public nsISupports { - public: - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IOBSERVERENTRY_IID) - - NS_IMETHOD Notify(nsIParserNode* aNode, - nsIParser* aParser, - nsISupports* aDocShell, - const PRUint32 aFlags) = 0; - -}; - - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIObserverEntry, NS_IOBSERVERENTRY_IID) - class nsIParserService : public nsISupports { public: NS_DECLARE_STATIC_IID_ACCESSOR(NS_IPARSERSERVICE_IID) /** * Looks up the nsHTMLTag enum value corresponding to the tag in aAtom. The * lookup happens case insensitively. * @@ -140,26 +121,16 @@ class nsIParserService : public nsISuppo PRInt32* aUnicode) const = 0; NS_IMETHOD HTMLConvertUnicodeToEntity(PRInt32 aUnicode, nsCString& aEntity) const = 0; NS_IMETHOD IsContainer(PRInt32 aId, bool& aIsContainer) const = 0; NS_IMETHOD IsBlock(PRInt32 aId, bool& aIsBlock) const = 0; - // Observer mechanism - NS_IMETHOD RegisterObserver(nsIElementObserver* aObserver, - const nsAString& aTopic, - const eHTMLTags* aTags = nsnull) = 0; - - NS_IMETHOD UnregisterObserver(nsIElementObserver* aObserver, - const nsAString& aTopic) = 0; - NS_IMETHOD GetTopicObservers(const nsAString& aTopic, - nsIObserverEntry** aEntry) = 0; - virtual nsresult CheckQName(const nsAString& aQName, bool aNamespaceAware, const PRUnichar** aColon) = 0; virtual bool IsXMLLetter(PRUnichar aChar) = 0; virtual bool IsXMLNCNameChar(PRUnichar aChar) = 0; /** * Decodes an entity into a UTF-16 character. If a ; is found between aStart
--- a/parser/htmlparser/src/CNavDTD.cpp +++ b/parser/htmlparser/src/CNavDTD.cpp @@ -1081,20 +1081,16 @@ CNavDTD::WillHandleStartTag(CToken* aTok // the correct node. while (stackDepth != MAX_REFLOW_DEPTH && NS_SUCCEEDED(result)) { result = CloseContainersTo(mBodyContext->Last(), false); --stackDepth; } } } - if (aTag <= NS_HTML_TAG_MAX) { - result = mSink->NotifyTagObservers(&aNode); - } - return result; } static void PushMisplacedAttributes(nsIParserNode& aNode, nsDeque& aDeque) { nsCParserNode& theAttrNode = static_cast<nsCParserNode &>(aNode);
--- a/parser/htmlparser/src/nsDTDUtils.cpp +++ b/parser/htmlparser/src/nsDTDUtils.cpp @@ -1021,132 +1021,8 @@ nsCParserNode* nsNodeAllocator::CreateNo #endif return result; } #ifdef DEBUG void DebugDumpContainmentRules(nsIDTD& theDTD,const char* aFilename,const char* aTitle) { } #endif - -/************************************************************** - This defines the topic object used by the observer service. - The observerService uses a list of these, 1 per topic when - registering tags. - **************************************************************/ -NS_IMPL_ISUPPORTS1(nsObserverEntry, nsIObserverEntry) - -nsObserverEntry::nsObserverEntry(const nsAString& aTopic) : mTopic(aTopic) -{ - memset(mObservers, 0, sizeof(mObservers)); -} - -nsObserverEntry::~nsObserverEntry() { - for (PRInt32 i = 0; i <= NS_HTML_TAG_MAX; ++i){ - delete mObservers[i]; - } -} - -NS_IMETHODIMP -nsObserverEntry::Notify(nsIParserNode* aNode, - nsIParser* aParser, - nsISupports* aDocShell, - const PRUint32 aFlags) -{ - NS_ENSURE_ARG_POINTER(aNode); - NS_ENSURE_ARG_POINTER(aParser); - - nsresult result = NS_OK; - eHTMLTags theTag = (eHTMLTags)aNode->GetNodeType(); - - if (theTag <= NS_HTML_TAG_MAX) { - nsCOMArray<nsIElementObserver>* theObservers = mObservers[theTag]; - if (theObservers) { - PRInt32 theCharsetSource; - nsCAutoString charset; - aParser->GetDocumentCharset(charset,theCharsetSource); - NS_ConvertASCIItoUTF16 theCharsetValue(charset); - - PRInt32 theAttrCount = aNode->GetAttributeCount(); - PRInt32 theObserversCount = theObservers->Count(); - if (0 < theObserversCount){ - nsTArray<nsString> keys(theAttrCount + 4), values(theAttrCount + 4); - - // XXX this and the following code may be a performance issue. - // Every key and value is copied and added to an voidarray (causing at - // least 2 allocations for mImpl, usually more, plus at least 1 per - // string (total = 2*(keys+3) + 2(or more) array allocations )). - PRInt32 index; - for (index = 0; index < theAttrCount; ++index) { - keys.AppendElement(aNode->GetKeyAt(index)); - values.AppendElement(aNode->GetValueAt(index)); - } - - nsAutoString intValue; - - keys.AppendElement(NS_LITERAL_STRING("charset")); - values.AppendElement(theCharsetValue); - - keys.AppendElement(NS_LITERAL_STRING("charsetSource")); - intValue.AppendInt(PRInt32(theCharsetSource),10); - values.AppendElement(intValue); - - keys.AppendElement(NS_LITERAL_STRING("X_COMMAND")); - values.AppendElement(NS_LITERAL_STRING("text/html")); - - nsCOMPtr<nsIChannel> channel; - aParser->GetChannel(getter_AddRefs(channel)); - - for (index=0;index<theObserversCount;++index) { - nsIElementObserver* observer = theObservers->ObjectAt(index); - if (observer) { - result = observer->Notify(aDocShell, channel, - nsHTMLTags::GetStringValue(theTag), - &keys, &values, aFlags); - if (NS_FAILED(result)) { - break; - } - - if (result == NS_HTMLPARSER_VALID_META_CHARSET) { - // Inform the parser that this meta tag contained a valid - // charset. See bug 272815 - aParser->SetDocumentCharset(charset, kCharsetFromMetaTag); - result = NS_OK; - } - } - } - } - } - } - return result; -} - -bool -nsObserverEntry::Matches(const nsAString& aString) { - bool result = aString.Equals(mTopic); - return result; -} - -nsresult -nsObserverEntry::AddObserver(nsIElementObserver *aObserver, - eHTMLTags aTag) -{ - if (aObserver) { - if (!mObservers[aTag]) { - mObservers[aTag] = new nsCOMArray<nsIElementObserver>(); - if (!mObservers[aTag]) { - return NS_ERROR_OUT_OF_MEMORY; - } - } - mObservers[aTag]->AppendObject(aObserver); - } - return NS_OK; -} - -void -nsObserverEntry::RemoveObserver(nsIElementObserver *aObserver) -{ - for (PRInt32 i=0; i <= NS_HTML_TAG_MAX; ++i){ - if (mObservers[i]) { - mObservers[i]->RemoveObject(aObserver); - } - } -}
--- a/parser/htmlparser/src/nsDTDUtils.h +++ b/parser/htmlparser/src/nsDTDUtils.h @@ -416,46 +416,18 @@ inline PRInt32 IndexOfTagInSet(PRInt32 a * @param aTag -- tag to be search for in set * @param aTagSet -- set of tags to be searched * @return */ inline bool FindTagInSet(PRInt32 aTag,const eHTMLTags *aTagSet,PRInt32 aCount) { return bool(-1<IndexOfTagInSet(aTag,aTagSet,aCount)); } -/************************************************************** - This defines the topic object used by the observer service. - The observerService uses a list of these, 1 per topic when - registering tags. - **************************************************************/ - -class nsObserverEntry : public nsIObserverEntry { -public: - NS_DECL_ISUPPORTS - nsObserverEntry(const nsAString& aString); - virtual ~nsObserverEntry(); - - NS_IMETHOD Notify(nsIParserNode* aNode, - nsIParser* aParser, - nsISupports* aDocShell, - const PRUint32 aFlags); - - nsresult AddObserver(nsIElementObserver* aObserver,eHTMLTags aTag); - void RemoveObserver(nsIElementObserver* aObserver); - bool Matches(const nsAString& aTopic); - -protected: - nsString mTopic; - nsCOMArray<nsIElementObserver>* mObservers[NS_HTML_TAG_MAX + 1]; - friend class nsMatchesTopic; -}; - /*********************************************************************************************/ - struct TagList { size_t mCount; const eHTMLTags *mTags; }; /** * Find the last member of given taglist on the given context * @update gess 12/14/99
--- a/parser/htmlparser/src/nsParser.cpp +++ b/parser/htmlparser/src/nsParser.cpp @@ -157,513 +157,18 @@ public: { mParser->HandleParserContinueEvent(this); return NS_OK; } }; //-------------- End ParseContinue Event Definition ------------------------ -template <class Type> -class Holder { -public: - typedef void (*Reaper)(Type *); - - Holder(Reaper aReaper) - : mHoldee(nsnull), mReaper(aReaper) - { - } - - ~Holder() { - if (mHoldee) { - mReaper(mHoldee); - } - } - - Type *get() { - return mHoldee; - } - const Holder &operator =(Type *aHoldee) { - if (mHoldee && aHoldee != mHoldee) { - mReaper(mHoldee); - } - mHoldee = aHoldee; - return *this; - } - -private: - Type *mHoldee; - Reaper mReaper; -}; - -class nsSpeculativeScriptThread : public nsIRunnable { -public: - nsSpeculativeScriptThread() - : mLock("nsSpeculativeScriptThread.mLock"), - mCVar(mLock, "nsSpeculativeScriptThread.mCVar"), - mKeepParsing(false), - mCurrentlyParsing(false), - mNumConsumed(0), - mContext(nsnull), - mTerminated(false) { - } - - ~nsSpeculativeScriptThread() { - NS_ASSERTION(NS_IsMainThread() || !mDocument, - "Destroying the document on the wrong thread"); - } - - NS_DECL_ISUPPORTS - NS_DECL_NSIRUNNABLE - - nsresult StartParsing(nsParser *aParser); - void StopParsing(bool aFromDocWrite); - - enum PrefetchType { NONE, SCRIPT, STYLESHEET, IMAGE }; - struct PrefetchEntry { - PrefetchType type; - nsString uri; - nsString charset; - nsString elementType; - }; - - nsIDocument *GetDocument() { - NS_ASSERTION(NS_IsMainThread(), "Potential threadsafety hazard"); - return mDocument; - } - - bool Parsing() { - return mCurrentlyParsing; - } - - CParserContext *Context() { - return mContext; - } - - typedef nsDataHashtable<nsCStringHashKey, bool> PreloadedType; - PreloadedType& GetPreloadedURIs() { - return mPreloadedURIs; - } - - void Terminate() { - mTerminated = true; - StopParsing(false); - } - bool Terminated() { - return mTerminated; - } - -private: - - void ProcessToken(CToken *aToken); - - void AddToPrefetchList(const nsAString &src, - const nsAString &charset, - const nsAString &elementType, - PrefetchType type); - - void FlushURIs(); - - // These members are only accessed on the speculatively parsing thread. - nsTokenAllocator mTokenAllocator; - - // The following members are shared across the main thread and the - // speculatively parsing thread. - Mutex mLock; - CondVar mCVar; - - volatile bool mKeepParsing; - volatile bool mCurrentlyParsing; - nsRefPtr<nsHTMLTokenizer> mTokenizer; - nsAutoPtr<nsScanner> mScanner; - - enum { kBatchPrefetchURIs = 5 }; - nsAutoTArray<PrefetchEntry, kBatchPrefetchURIs> mURIs; - - // Number of characters consumed by the last speculative parse. - PRUint32 mNumConsumed; - - // These members are only accessed on the main thread. - nsCOMPtr<nsIDocument> mDocument; - CParserContext *mContext; - PreloadedType mPreloadedURIs; - bool mTerminated; -}; - -class nsPreloadURIs : public nsIRunnable { -public: - nsPreloadURIs(nsAutoTArray<nsSpeculativeScriptThread::PrefetchEntry, 5> &aURIs, - nsSpeculativeScriptThread *aScriptThread) - : mURIs(aURIs), - mScriptThread(aScriptThread) { - } - - NS_DECL_ISUPPORTS - NS_DECL_NSIRUNNABLE - - static void PreloadURIs(const nsAutoTArray<nsSpeculativeScriptThread::PrefetchEntry, 5> &aURIs, - nsSpeculativeScriptThread *aScriptThread); - -private: - nsAutoTArray<nsSpeculativeScriptThread::PrefetchEntry, 5> mURIs; - nsRefPtr<nsSpeculativeScriptThread> mScriptThread; -}; - -NS_IMPL_THREADSAFE_ISUPPORTS1(nsPreloadURIs, nsIRunnable) - -NS_IMETHODIMP -nsPreloadURIs::Run() -{ - PreloadURIs(mURIs, mScriptThread); - return NS_OK; -} - -void -nsPreloadURIs::PreloadURIs(const nsAutoTArray<nsSpeculativeScriptThread::PrefetchEntry, 5> &aURIs, - nsSpeculativeScriptThread *aScriptThread) -{ - NS_ASSERTION(NS_IsMainThread(), "Touching non-threadsafe objects off thread"); - - if (aScriptThread->Terminated()) { - return; - } - - nsIDocument *doc = aScriptThread->GetDocument(); - NS_ASSERTION(doc, "We shouldn't have started preloading without a document"); - - // Note: Per the code in the HTML content sink, we should be keeping track - // of each <base href> as it comes. However, because we do our speculative - // parsing off the main thread, this is hard to emulate. For now, just load - // the URIs using the document's base URI at the potential cost of being - // wrong and having to re-load a given relative URI later. - nsIURI *base = doc->GetDocBaseURI(); - const nsCString &charset = doc->GetDocumentCharacterSet(); - nsSpeculativeScriptThread::PreloadedType &alreadyPreloaded = - aScriptThread->GetPreloadedURIs(); - for (PRUint32 i = 0, e = aURIs.Length(); i < e; ++i) { - const nsSpeculativeScriptThread::PrefetchEntry &pe = aURIs[i]; - nsCOMPtr<nsIURI> uri; - nsresult rv = NS_NewURI(getter_AddRefs(uri), pe.uri, charset.get(), base); - if (NS_FAILED(rv)) { - NS_WARNING("Failed to create a URI"); - continue; - } - - nsCAutoString spec; - uri->GetSpec(spec); - bool answer; - if (alreadyPreloaded.Get(spec, &answer)) { - // Already preloaded. Don't preload again. - continue; - } - - alreadyPreloaded.Put(spec, true); - - switch (pe.type) { - case nsSpeculativeScriptThread::SCRIPT: - doc->ScriptLoader()->PreloadURI(uri, pe.charset, pe.elementType); - break; - case nsSpeculativeScriptThread::IMAGE: - doc->MaybePreLoadImage(uri, EmptyString()); - break; - case nsSpeculativeScriptThread::STYLESHEET: - doc->PreloadStyle(uri, pe.charset); - break; - case nsSpeculativeScriptThread::NONE: - NS_NOTREACHED("Uninitialized preload entry?"); - break; - } - } -} - -NS_IMPL_THREADSAFE_ISUPPORTS1(nsSpeculativeScriptThread, nsIRunnable) - -NS_IMETHODIMP -nsSpeculativeScriptThread::Run() -{ - NS_ASSERTION(!NS_IsMainThread(), "Speculative parsing on the main thread?"); - - mNumConsumed = 0; - - mTokenizer->WillTokenize(false, &mTokenAllocator); - while (mKeepParsing) { - bool flushTokens = false; - nsresult rv = mTokenizer->ConsumeToken(*mScanner, flushTokens); - if (NS_FAILED(rv)) { - break; - } - - mNumConsumed += mScanner->Mark(); - - // TODO Don't pop the tokens. - CToken *token; - while (mKeepParsing && (token = mTokenizer->PopToken())) { - ProcessToken(token); - } - } - mTokenizer->DidTokenize(false); - - if (mKeepParsing) { - // Ran out of room in this part of the document -- flush out the URIs we - // gathered so far so we don't end up waiting for the parser's current - // load to finish. - if (!mURIs.IsEmpty()) { - FlushURIs(); - } - } - - { - MutexAutoLock al(mLock); - - mCurrentlyParsing = false; - mCVar.Notify(); - } - return NS_OK; -} - -nsresult -nsSpeculativeScriptThread::StartParsing(nsParser *aParser) -{ - NS_ASSERTION(NS_IsMainThread(), "Called on the wrong thread"); - NS_ASSERTION(!mCurrentlyParsing, "Bad race happening"); - - if (!aParser->ThreadPool()) { - return NS_OK; - } - - nsIContentSink *sink = aParser->GetContentSink(); - if (!sink) { - return NS_OK; - } - - nsCOMPtr<nsIDocument> doc = do_QueryInterface(sink->GetTarget()); - if (!doc) { - return NS_OK; - } - - nsAutoString toScan; - CParserContext *context = aParser->PeekContext(); - if (!mTokenizer) { - if (!mPreloadedURIs.Init(15)) { - return NS_ERROR_OUT_OF_MEMORY; - } - - mTokenizer = new nsHTMLTokenizer(context->mDTDMode, context->mDocType, - context->mParserCommand, 0); - if (!mTokenizer) { - return NS_ERROR_OUT_OF_MEMORY; - } - mTokenizer->CopyState(context->mTokenizer); - context->mScanner->CopyUnusedData(toScan); - if (toScan.IsEmpty()) { - return NS_OK; - } - } else if (context == mContext) { - // Don't parse the same part of the document twice. - nsScannerIterator end; - context->mScanner->EndReading(end); - - nsScannerIterator start; - context->mScanner->CurrentPosition(start); - - if (mNumConsumed > context->mNumConsumed) { - // We consumed more the last time we tried speculatively parsing than we - // did the last time we actually parsed. - PRUint32 distance = Distance(start, end); - start.advance(NS_MIN(mNumConsumed - context->mNumConsumed, distance)); - } - - if (start == end) { - // We're at the end of this context's buffer, nothing else to do. - return NS_OK; - } - - CopyUnicodeTo(start, end, toScan); - } else { - // Grab all of the context. - context->mScanner->CopyUnusedData(toScan); - if (toScan.IsEmpty()) { - // Nothing to parse, don't do anything. - return NS_OK; - } - } - - nsCAutoString charset; - PRInt32 source; - aParser->GetDocumentCharset(charset, source); - - mScanner = new nsScanner(toScan, charset, source); - if (!mScanner) { - return NS_ERROR_OUT_OF_MEMORY; - } - mScanner->SetIncremental(true); - - mDocument.swap(doc); - mKeepParsing = true; - mCurrentlyParsing = true; - mContext = context; - return aParser->ThreadPool()->Dispatch(this, NS_DISPATCH_NORMAL); -} - -void -nsSpeculativeScriptThread::StopParsing(bool /*aFromDocWrite*/) -{ - NS_ASSERTION(NS_IsMainThread(), "Can't stop parsing from another thread"); - - { - MutexAutoLock al(mLock); - - mKeepParsing = false; - if (mCurrentlyParsing) { - mCVar.Wait(); - NS_ASSERTION(!mCurrentlyParsing, "Didn't actually stop parsing?"); - } - } - - // The thread is now idle. - if (mTerminated) { - // If we're terminated, then we need to ensure that we release our document - // and tokenizer here on the main thread so that our last reference to them - // isn't our alter-ego rescheduled on another thread. - mDocument = nsnull; - mTokenizer = nsnull; - mScanner = nsnull; - } else if (mURIs.Length()) { - // Note: Don't do this if we're terminated. - nsPreloadURIs::PreloadURIs(mURIs, this); - mURIs.Clear(); - } - - // Note: Currently, we pop the tokens off (see the comment in Run) so this - // isn't a problem. If and when we actually use the tokens created - // off-thread, we'll need to use aFromDocWrite for real. -} - -void -nsSpeculativeScriptThread::ProcessToken(CToken *aToken) -{ - // Only called on the speculative script thread. - - CHTMLToken *token = static_cast<CHTMLToken *>(aToken); - switch (static_cast<eHTMLTokenTypes>(token->GetTokenType())) { - case eToken_start: { - CStartToken *start = static_cast<CStartToken *>(aToken); - nsHTMLTag tag = static_cast<nsHTMLTag>(start->GetTypeID()); - PRInt16 attrs = start->GetAttributeCount(); - PRInt16 i = 0; - nsAutoString src; - nsAutoString elementType; - nsAutoString charset; - nsAutoString href; - nsAutoString rel; - PrefetchType ptype = NONE; - - switch (tag) { - case eHTMLTag_link: - ptype = STYLESHEET; - break; - - case eHTMLTag_img: - ptype = IMAGE; - break; - - case eHTMLTag_script: - ptype = SCRIPT; - break; - - default: - break; - } - - // We currently handle the following element/attribute combos : - // <link rel="stylesheet" href= charset= type> - // <script src= charset= type=> - if (ptype != NONE) { - // loop over all attributes to extract relevant info - for (; i < attrs ; ++i) { - CAttributeToken *attr = static_cast<CAttributeToken *>(mTokenizer->PopToken()); - NS_ASSERTION(attr->GetTokenType() == eToken_attribute, "Weird token"); - - if (attr->GetKey().EqualsLiteral("src")) { - src.Assign(attr->GetValue()); - } else if (attr->GetKey().EqualsLiteral("href")) { - href.Assign(attr->GetValue()); - } else if (attr->GetKey().EqualsLiteral("rel")) { - rel.Assign(attr->GetValue()); - } else if (attr->GetKey().EqualsLiteral("charset")) { - charset.Assign(attr->GetValue()); - } else if (attr->GetKey().EqualsLiteral("type")) { - elementType.Assign(attr->GetValue()); - } - - IF_FREE(attr, &mTokenAllocator); - } - - // ensure we have the right kind if it's a link-element - if (ptype == STYLESHEET) { - if (rel.EqualsLiteral("stylesheet")) { - src = href; // src is the important variable below - } else { - src.Truncate(); // clear src if wrong kind of link - } - } - - // add to list if we have a valid src - if (!src.IsEmpty()) { - AddToPrefetchList(src, charset, elementType, ptype); - } - } else { - // Irrelevant tag, but pop and free all its attributes in any case - for (; i < attrs ; ++i) { - CToken *attr = mTokenizer->PopToken(); - IF_FREE(attr, &mTokenAllocator); - } - } - break; - } - - default: - break; - } - - IF_FREE(aToken, &mTokenAllocator); -} - -void -nsSpeculativeScriptThread::AddToPrefetchList(const nsAString &src, - const nsAString &charset, - const nsAString &elementType, - PrefetchType type) -{ - PrefetchEntry *pe = mURIs.AppendElement(); - pe->type = type; - pe->uri = src; - pe->charset = charset; - pe->elementType = elementType; - - if (mURIs.Length() == kBatchPrefetchURIs) { - FlushURIs(); - } -} - -void -nsSpeculativeScriptThread::FlushURIs() -{ - nsCOMPtr<nsIRunnable> r = new nsPreloadURIs(mURIs, this); - if (!r) { - return; - } - - mURIs.Clear(); - NS_DispatchToMainThread(r, NS_DISPATCH_NORMAL); -} - nsICharsetAlias* nsParser::sCharsetAliasService = nsnull; nsICharsetConverterManager* nsParser::sCharsetConverterManager = nsnull; -nsIThreadPool* nsParser::sSpeculativeThreadPool = nsnull; /** * This gets called when the htmlparser module is initialized. */ // static nsresult nsParser::Init() { @@ -675,47 +180,28 @@ nsParser::Init() nsCOMPtr<nsICharsetConverterManager> charsetConverter = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); charsetAlias.swap(sCharsetAliasService); charsetConverter.swap(sCharsetConverterManager); - nsCOMPtr<nsIThreadPool> threadPool = - do_CreateInstance(NS_THREADPOOL_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - rv = threadPool->SetThreadLimit(kSpeculativeThreadLimit); - NS_ENSURE_SUCCESS(rv, rv); - - rv = threadPool->SetIdleThreadLimit(kIdleThreadLimit); - NS_ENSURE_SUCCESS(rv, rv); - - rv = threadPool->SetIdleThreadTimeout(kIdleThreadTimeout); - NS_ENSURE_SUCCESS(rv, rv); - - threadPool.swap(sSpeculativeThreadPool); - return NS_OK; } /** * This gets called when the htmlparser module is shutdown. */ // static void nsParser::Shutdown() { NS_IF_RELEASE(sCharsetAliasService); NS_IF_RELEASE(sCharsetConverterManager); - if (sSpeculativeThreadPool) { - sSpeculativeThreadPool->Shutdown(); - NS_RELEASE(sSpeculativeThreadPool); - } } #ifdef DEBUG static bool gDumpContent=false; #endif /** * default constructor @@ -790,20 +276,16 @@ nsParser::Cleanup() delete mParserContext; mParserContext = pc; } // It should not be possible for this flag to be set when we are getting // destroyed since this flag implies a pending nsParserContinueEvent, which // has an owning reference to |this|. NS_ASSERTION(!(mFlags & NS_PARSER_FLAG_PENDING_CONTINUE_EVENT), "bad"); - if (mSpeculativeScriptThread) { - mSpeculativeScriptThread->Terminate(); - mSpeculativeScriptThread = nsnull; - } } NS_IMPL_CYCLE_COLLECTION_CLASS(nsParser) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsParser) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDTD) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mSink) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mObserver) @@ -1522,48 +1004,22 @@ nsParser::DidBuildModel(nsresult anError // DTD was to NS_ENSURE_SUCCESS the sink DidBuildModel call, so if the // sink returns failure we should use sinkResult instead of dtdResult, // to preserve the old error handling behavior of the DTD: result = NS_FAILED(sinkResult) ? sinkResult : dtdResult; } //Ref. to bug 61462. mParserContext->mRequest = 0; - - if (mSpeculativeScriptThread) { - mSpeculativeScriptThread->Terminate(); - mSpeculativeScriptThread = nsnull; - } } } return result; } -void -nsParser::SpeculativelyParse() -{ - if (mParserContext->mParserCommand == eViewNormal && - !mParserContext->mMimeType.EqualsLiteral("text/html")) { - return; - } - - if (!mSpeculativeScriptThread) { - mSpeculativeScriptThread = new nsSpeculativeScriptThread(); - if (!mSpeculativeScriptThread) { - return; - } - } - - nsresult rv = mSpeculativeScriptThread->StartParsing(this); - if (NS_FAILED(rv)) { - mSpeculativeScriptThread = nsnull; - } -} - /** * This method adds a new parser context to the list, * pushing the current one to the next position. * * @param ptr to new context */ void nsParser::PushContext(CParserContext& aContext) @@ -1655,20 +1111,16 @@ nsParser::Terminate(void) mInternalState = result = NS_ERROR_HTMLPARSER_STOPPARSING; // CancelParsingEvents must be called to avoid leaking the nsParser object // @see bug 108049 // If NS_PARSER_FLAG_PENDING_CONTINUE_EVENT is set then CancelParsingEvents // will reset it so DidBuildModel will call DidBuildModel on the DTD. Note: // The IsComplete() call inside of DidBuildModel looks at the pendingContinueEvents flag. CancelParsingEvents(); - if (mSpeculativeScriptThread) { - mSpeculativeScriptThread->Terminate(); - mSpeculativeScriptThread = nsnull; - } // If we got interrupted in the middle of a document.write, then we might // have more than one parser context on our parsercontext stack. This has // the effect of making DidBuildModel a no-op, meaning that we never call // our sink's DidBuildModel and break the reference cycle, causing a leak. // Since we're getting terminated, we manually clean up our context stack. while (mParserContext && mParserContext->mPrevContext) { CParserContext *prev = mParserContext->mPrevContext; @@ -1707,20 +1159,16 @@ nsParser::ContinueInterruptedParsing() nsCOMPtr<nsIParser> kungFuDeathGrip(this); #ifdef DEBUG if (!(mFlags & NS_PARSER_FLAG_PARSER_ENABLED)) { NS_WARNING("Don't call ContinueInterruptedParsing on a blocked parser."); } #endif - if (mSpeculativeScriptThread) { - mSpeculativeScriptThread->StopParsing(false); - } - bool isFinalChunk = mParserContext && mParserContext->mStreamListenerState == eOnStop; mProcessingNetworkData = true; if (mSink) { mSink->WillParse(); } result = ResumeParse(true, isFinalChunk); // Ref. bug 57999 @@ -1845,17 +1293,16 @@ nsParser::SetCanInterrupt(bool aCanInter NS_IMETHODIMP nsParser::Parse(nsIURI* aURL, nsIRequestObserver* aListener, void* aKey, nsDTDMode aMode) { NS_PRECONDITION(aURL, "Error: Null URL given"); - NS_ASSERTION(!mSpeculativeScriptThread, "Can't reuse a parser like this"); nsresult result=kBadURL; mObserver = aListener; if (aURL) { nsCAutoString spec; nsresult rv = aURL->GetSpec(spec); if (rv != NS_OK) { @@ -1907,20 +1354,16 @@ nsParser::Parse(const nsAString& aSource // Nothing is being passed to the parser so return // immediately. mUnusedInput will get processed when // some data is actually passed in. // But if this is the last call, make sure to finish up // stuff correctly. return result; } - if (mSpeculativeScriptThread) { - mSpeculativeScriptThread->StopParsing(true); - } - // Hack to pass on to the dtd the caller's desire to // parse a fragment without worrying about containment rules if (aMode == eDTDMode_fragment) mCommand = eViewFragment; // Maintain a reference to ourselves so we don't go away // till we're completely done. nsCOMPtr<nsIParser> kungFuDeathGrip(this); @@ -2022,18 +1465,16 @@ nsParser::ParseFragment(const nsAString& nsresult result = NS_OK; nsAutoString theContext; PRUint32 theCount = aTagStack.Length(); PRUint32 theIndex = 0; // Disable observers for fragments mFlags &= ~NS_PARSER_FLAG_OBSERVERS_ENABLED; - NS_ASSERTION(!mSpeculativeScriptThread, "Can't reuse a parser like this"); - for (theIndex = 0; theIndex < theCount; theIndex++) { theContext.AppendLiteral("<"); theContext.Append(aTagStack[theCount - theIndex - 1]); theContext.AppendLiteral(">"); } if (theCount == 0) { // Ensure that the buffer is not empty. Because none of the DTDs care @@ -2141,18 +1582,16 @@ nsParser::ParseFragment(const nsAString& nsresult nsParser::ResumeParse(bool allowIteration, bool aIsFinalChunk, bool aCanInterrupt) { nsresult result = NS_OK; if ((mFlags & NS_PARSER_FLAG_PARSER_ENABLED) && mInternalState != NS_ERROR_HTMLPARSER_STOPPARSING) { - NS_ASSERTION(!mSpeculativeScriptThread || !mSpeculativeScriptThread->Parsing(), - "Bad races happening, expect to crash!"); result = WillBuildModel(mParserContext->mScanner->GetFilename()); if (NS_FAILED(result)) { mFlags &= ~NS_PARSER_FLAG_CAN_TOKENIZE; return result; } if (mDTD) { @@ -2192,17 +1631,16 @@ nsParser::ResumeParse(bool allowIteratio // If we're told to block the parser, we disable all further parsing // (and cache any data coming in) until the parser is re-enabled. if (NS_ERROR_HTMLPARSER_BLOCK == result) { mSink->WillInterrupt(); if (mFlags & NS_PARSER_FLAG_PARSER_ENABLED) { // If we were blocked by a recursive invocation, don't re-block. BlockParser(); - SpeculativelyParse(); } return NS_OK; } if (NS_ERROR_HTMLPARSER_STOPPARSING == result) { // Note: Parser Terminate() calls DidBuildModel. if (mInternalState != NS_ERROR_HTMLPARSER_STOPPARSING) { DidBuildModel(mStreamStatus); mInternalState = result; @@ -2713,21 +2151,16 @@ nsParser::OnDataAvailable(nsIRequest *re while (theContext && theContext->mRequest != request) { theContext = theContext->mPrevContext; } if (theContext) { theContext->mStreamListenerState = eOnDataAvail; - if ((mFlags & NS_PARSER_FLAG_PARSER_ENABLED) && - mSpeculativeScriptThread) { - mSpeculativeScriptThread->StopParsing(false); - } - if (eInvalidDetect == theContext->mAutoDetectStatus) { if (theContext->mScanner) { nsScannerIterator iter; theContext->mScanner->EndReading(iter); theContext->mScanner->SetPosition(iter, true); } } @@ -2767,21 +2200,16 @@ nsParser::OnDataAvailable(nsIRequest *re * has been collected from the net. */ nsresult nsParser::OnStopRequest(nsIRequest *request, nsISupports* aContext, nsresult status) { nsresult rv = NS_OK; - if ((mFlags & NS_PARSER_FLAG_PARSER_ENABLED) && - mSpeculativeScriptThread) { - mSpeculativeScriptThread->StopParsing(false); - } - CParserContext *pc = mParserContext; while (pc) { if (pc->mRequest == request) { pc->mStreamListenerState = eOnStop; pc->mScanner->SetIncremental(false); break; }
--- a/parser/htmlparser/src/nsParser.h +++ b/parser/htmlparser/src/nsParser.h @@ -87,17 +87,16 @@ #include "nsCOMArray.h" #include "nsCycleCollectionParticipant.h" #include "nsWeakReference.h" class nsICharsetConverterManager; class nsICharsetAlias; class nsIDTD; class nsScanner; -class nsSpeculativeScriptThread; class nsIThreadPool; #ifdef _MSC_VER #pragma warning( disable : 4275 ) #endif class nsParser : public nsIParser, @@ -375,20 +374,16 @@ class nsParser : public nsIParser, return sCharsetConverterManager; } virtual void Reset() { Cleanup(); Initialize(); } - nsIThreadPool* ThreadPool() { - return sSpeculativeThreadPool; - } - bool IsScriptExecuting() { return mSink && mSink->IsScriptExecuting(); } bool IsOkToProcessNetworkData() { return !IsScriptExecuting() && !mProcessingNetworkData; } @@ -408,18 +403,16 @@ class nsParser : public nsIParser, /** * * @update gess5/18/98 * @param * @return */ nsresult DidBuildModel(nsresult anErrorCode); - void SpeculativelyParse(); - private: /******************************************* These are the tokenization methods... *******************************************/ /** * Part of the code sandwich, this gets called right before @@ -460,17 +453,16 @@ protected: //********************************************* CParserContext* mParserContext; nsCOMPtr<nsIDTD> mDTD; nsCOMPtr<nsIRequestObserver> mObserver; nsCOMPtr<nsIContentSink> mSink; nsIRunnable* mContinueEvent; // weak ref - nsRefPtr<nsSpeculativeScriptThread> mSpeculativeScriptThread; nsTokenAllocator mTokenAllocator; eParserCommands mCommand; nsresult mInternalState; PRInt32 mStreamStatus; PRInt32 mCharsetSource; @@ -479,19 +471,12 @@ protected: nsString mUnusedInput; nsCString mCharset; nsCString mCommandStr; bool mProcessingNetworkData; static nsICharsetAlias* sCharsetAliasService; static nsICharsetConverterManager* sCharsetConverterManager; - static nsIThreadPool* sSpeculativeThreadPool; - - enum { - kSpeculativeThreadLimit = 15, - kIdleThreadLimit = 0, - kIdleThreadTimeout = 50 - }; }; #endif
--- a/parser/htmlparser/src/nsParserService.cpp +++ b/parser/htmlparser/src/nsParserService.cpp @@ -42,27 +42,22 @@ #include "nsHTMLEntities.h" #include "nsElementTable.h" #include "nsICategoryManager.h" #include "nsCategoryManagerUtils.h" extern "C" int MOZ_XMLCheckQName(const char* ptr, const char* end, int ns_aware, const char** colon); -nsParserService::nsParserService() : mEntries(0) +nsParserService::nsParserService() { - mHaveNotifiedCategoryObservers = false; } nsParserService::~nsParserService() { - nsObserverEntry *entry = nsnull; - while( (entry = static_cast<nsObserverEntry*>(mEntries.Pop())) ) { - NS_RELEASE(entry); - } } NS_IMPL_ISUPPORTS1(nsParserService, nsIParserService) PRInt32 nsParserService::HTMLAtomTagToId(nsIAtom* aAtom) const { return nsHTMLTags::LookupTag(nsDependentAtomString(aAtom)); @@ -133,70 +128,16 @@ nsParserService::IsBlock(PRInt32 aId, bo } else { aIsBlock = false; } return NS_OK; } -NS_IMETHODIMP -nsParserService::RegisterObserver(nsIElementObserver* aObserver, - const nsAString& aTopic, - const eHTMLTags* aTags) -{ - nsresult result = NS_OK; - nsObserverEntry* entry = GetEntry(aTopic); - - if(!entry) { - result = CreateEntry(aTopic,&entry); - NS_ENSURE_SUCCESS(result,result); - } - - while (*aTags) { - if (*aTags <= NS_HTML_TAG_MAX) { - entry->AddObserver(aObserver,*aTags); - } - ++aTags; - } - - return result; -} - -NS_IMETHODIMP -nsParserService::UnregisterObserver(nsIElementObserver* aObserver, - const nsAString& aTopic) -{ - PRInt32 count = mEntries.GetSize(); - - for (PRInt32 i=0; i < count; ++i) { - nsObserverEntry* entry = static_cast<nsObserverEntry*>(mEntries.ObjectAt(i)); - if (entry && entry->Matches(aTopic)) { - entry->RemoveObserver(aObserver); - } - } - - return NS_OK; -} - -NS_IMETHODIMP -nsParserService::GetTopicObservers(const nsAString& aTopic, - nsIObserverEntry** aEntry) { - nsresult result = NS_OK; - nsObserverEntry* entry = GetEntry(aTopic); - - if (!entry) { - return NS_ERROR_NULL_POINTER; - } - - NS_ADDREF(*aEntry = entry); - - return result; -} - nsresult nsParserService::CheckQName(const nsAString& aQName, bool aNamespaceAware, const PRUnichar** aColon) { const char* colon; const PRUnichar *begin, *end; begin = aQName.BeginReading(); @@ -212,52 +153,8 @@ nsParserService::CheckQName(const nsAStr // MOZ_EXPAT_EMPTY_QNAME || MOZ_EXPAT_INVALID_CHARACTER if (result == (1 << 0) || result == (1 << 1)) { return NS_ERROR_DOM_INVALID_CHARACTER_ERR; } return NS_ERROR_DOM_NAMESPACE_ERR; } - -class nsMatchesTopic : public nsDequeFunctor{ - const nsAString& mString; -public: - bool matched; - nsObserverEntry* entry; - nsMatchesTopic(const nsAString& aString):mString(aString),matched(false){} - virtual void* operator()(void* anObject){ - entry=static_cast<nsObserverEntry*>(anObject); - matched=mString.Equals(entry->mTopic); - return matched ? nsnull : anObject; - } -}; - -// XXX This may be more efficient as a HashTable instead of linear search -nsObserverEntry* -nsParserService::GetEntry(const nsAString& aTopic) -{ - if (!mHaveNotifiedCategoryObservers) { - mHaveNotifiedCategoryObservers = true; - NS_CreateServicesFromCategory("parser-service-category", - static_cast<nsISupports*>(static_cast<void*>(this)), - "parser-service-start"); - } - - nsMatchesTopic matchesTopic(aTopic); - mEntries.FirstThat(*&matchesTopic); - return matchesTopic.matched?matchesTopic.entry:nsnull; -} - -nsresult -nsParserService::CreateEntry(const nsAString& aTopic, nsObserverEntry** aEntry) -{ - *aEntry = new nsObserverEntry(aTopic); - - if (!*aEntry) { - return NS_ERROR_OUT_OF_MEMORY; - } - - NS_ADDREF(*aEntry); - mEntries.Push(*aEntry); - - return NS_OK; -}
--- a/parser/htmlparser/src/nsParserService.h +++ b/parser/htmlparser/src/nsParserService.h @@ -65,26 +65,16 @@ public: NS_IMETHOD HTMLConvertEntityToUnicode(const nsAString& aEntity, PRInt32* aUnicode) const; NS_IMETHOD HTMLConvertUnicodeToEntity(PRInt32 aUnicode, nsCString& aEntity) const; NS_IMETHOD IsContainer(PRInt32 aId, bool& aIsContainer) const; NS_IMETHOD IsBlock(PRInt32 aId, bool& aIsBlock) const; - // Observer mechanism - NS_IMETHOD RegisterObserver(nsIElementObserver* aObserver, - const nsAString& aTopic, - const eHTMLTags* aTags = nsnull); - - NS_IMETHOD UnregisterObserver(nsIElementObserver* aObserver, - const nsAString& aTopic); - NS_IMETHOD GetTopicObservers(const nsAString& aTopic, - nsIObserverEntry** aEntry); - nsresult CheckQName(const nsAString& aQName, bool aNamespaceAware, const PRUnichar** aColon); bool IsXMLLetter(PRUnichar aChar) { return !!MOZ_XMLIsLetter(reinterpret_cast<const char*>(&aChar)); } bool IsXMLNCNameChar(PRUnichar aChar) @@ -95,19 +85,11 @@ public: const PRUnichar** aNext, PRUnichar* aResult) { *aNext = nsnull; return MOZ_XMLTranslateEntity(reinterpret_cast<const char*>(aStart), reinterpret_cast<const char*>(aEnd), reinterpret_cast<const char**>(aNext), aResult); } - -protected: - nsObserverEntry* GetEntry(const nsAString& aTopic); - nsresult CreateEntry(const nsAString& aTopic, - nsObserverEntry** aEntry); - - nsDeque mEntries; //each topic holds a list of observers per tag. - bool mHaveNotifiedCategoryObservers; }; #endif
--- a/testing/mochitest/runtestsremote.py +++ b/testing/mochitest/runtestsremote.py @@ -219,16 +219,17 @@ class MochiRemote(Mochitest): self.remoteProfile = options.remoteTestRoot + "/profile" self._automation.setRemoteProfile(self.remoteProfile) self.remoteLog = options.remoteLogFile def cleanup(self, manifest, options): self._dm.getFile(self.remoteLog, self.localLog) self._dm.removeFile(self.remoteLog) self._dm.removeDir(self.remoteProfile) + if (options.pidFile != ""): try: os.remove(options.pidFile) os.remove(options.pidFile + ".xpcshell.pid") except: print "Warning: cleaning up pidfile '%s' was unsuccessful from the test harness" % options.pidFile def findPath(self, paths, filename = None): @@ -382,18 +383,23 @@ def main(): fHandle = open("robotium.config", "w") fHandle.write("profile=%s\n" % (mochitest.remoteProfile)) fHandle.write("logfile=%s\n" % (options.remoteLogFile)) fHandle.close() deviceRoot = dm.getDeviceRoot() # Note, we are pushing to /sdcard since we have this location hard coded in robocop + dm.removeFile("/sdcard/fennec_ids.txt") + dm.removeFile("/sdcard/robotium.config") dm.pushFile("robotium.config", "/sdcard/robotium.config") - dm.pushFile(os.path.abspath(options.robocop + "/fennec_ids.txt"), "/sdcard/fennec_ids.txt") + fennec_ids = os.path.abspath("fennec_ids.txt") + if not os.path.exists(fennec_ids) and options.robocopPath: + fennec_ids = os.path.abspath(os.path.join(options.robocopPath, "fennec_ids.txt")) + dm.pushFile(fennec_ids, "/sdcard/fennec_ids.txt") options.extraPrefs.append('robocop.logfile="%s/robocop.log"' % deviceRoot) if (options.dm_trans == 'adb' and options.robocopPath): dm.checkCmd(["install", "-r", os.path.join(options.robocopPath, "robocop.apk")]) appname = options.app for test in robocop_tests: if options.testPath and options.testPath != test['name']: @@ -405,23 +411,31 @@ def main(): options.browserArgs.append("org.mozilla.roboexample.test/android.test.InstrumentationTestRunner") try: retVal = mochitest.runTests(options) except: print "TEST-UNEXPECTED-ERROR | %s | Exception caught while running robocop tests." % sys.exc_info()[1] mochitest.stopWebServer(options) mochitest.stopWebSocketServer(options) + try: + self.cleanup(None, options) + except: + pass sys.exit(1) else: try: retVal = mochitest.runTests(options) except: - print "TEST-UNEXPECTED-ERROR | | Exception caught while running tests." + print "TEST-UNEXPECTED-ERROR | %s | Exception caught while running tests." % sys.exc_info()[1] mochitest.stopWebServer(options) mochitest.stopWebSocketServer(options) + try: + self.cleanup(None, options) + except: + pass sys.exit(1) sys.exit(retVal) if __name__ == "__main__": main()
--- a/testing/testsuite-targets.mk +++ b/testing/testsuite-targets.mk @@ -71,20 +71,20 @@ RUN_MOCHITEST_REMOTE = \ rm -f ./$@.log && \ $(PYTHON) _tests/testing/mochitest/runtestsremote.py --autorun --close-when-done \ --console-level=INFO --log-file=./$@.log --file-level=INFO $(DM_FLAGS) --dm_trans=$(DM_TRANS) \ --app=$(TEST_PACKAGE_NAME) --deviceIP=${TEST_DEVICE} --xre-path=${MOZ_HOST_BIN} \ $(SYMBOLS_PATH) $(TEST_PATH_ARG) $(EXTRA_TEST_ARGS) RUN_MOCHITEST_ROBOTIUM = \ rm -f ./$@.log && \ - $(PYTHON) _tests/testing/mochitest/runtestsremote.py --robocop-path build/mobile/robocop \ + $(PYTHON) _tests/testing/mochitest/runtestsremote.py --robocop-path=$(DEPTH)/build/mobile/robocop \ --console-level=INFO --log-file=./$@.log --file-level=INFO $(DM_FLAGS) --dm_trans=adb \ --app=$(TEST_PACKAGE_NAME) --deviceIP=${TEST_DEVICE} --xre-path=${MOZ_HOST_BIN} \ - --robocop build/mobile/robocop/robocop.ini $(SYMBOLS_PATH) $(TEST_PATH_ARG) $(EXTRA_TEST_ARGS) + --robocop=$(DEPTH)/build/mobile/robocop/robocop.ini $(SYMBOLS_PATH) $(TEST_PATH_ARG) $(EXTRA_TEST_ARGS) ifndef NO_FAIL_ON_TEST_ERRORS define CHECK_TEST_ERROR @errors=`grep "TEST-UNEXPECTED-" $@.log` ;\ if test "$$errors" ; then \ echo "$@ failed:"; \ echo "$$errors"; \ exit 1; \ @@ -97,16 +97,17 @@ endif mochitest-remote: DM_TRANS?=adb mochitest-remote: @if test -f ${MOZ_HOST_BIN}/xpcshell && [ "${TEST_DEVICE}" != "usb" -o "$(DM_TRANS)" = "adb" ]; \ then $(RUN_MOCHITEST_REMOTE); \ else \ echo "please prepare your host with environment variables for TEST_DEVICE and MOZ_HOST_BIN"; \ fi +mochitest-robotium: robotium-id-map mochitest-robotium: DM_TRANS?=adb mochitest-robotium: @if test -f ${MOZ_HOST_BIN}/xpcshell && [ "${TEST_DEVICE}" != "usb" -o "$(DM_TRANS)" = "adb" ]; \ then $(RUN_MOCHITEST_ROBOTIUM); \ else \ echo "please prepare your host with environment variables for TEST_DEVICE and MOZ_HOST_BIN"; \ fi @@ -279,38 +280,43 @@ endif ifeq (Android, $(OS_TARGET)) package-tests: stage-android endif make-stage-dir: rm -rf $(PKG_STAGE) && $(NSINSTALL) -D $(PKG_STAGE) && $(NSINSTALL) -D $(PKG_STAGE)/bin && $(NSINSTALL) -D $(PKG_STAGE)/bin/components && $(NSINSTALL) -D $(PKG_STAGE)/certs && $(NSINSTALL) -D $(PKG_STAGE)/jetpack && $(NSINSTALL) -D $(PKG_STAGE)/firebug && $(NSINSTALL) -D $(PKG_STAGE)/peptest && $(NSINSTALL) -D $(PKG_STAGE)/mozbase +robotium-id-map: +ifeq ($(MOZ_BUILD_APP),mobile/android) + $(PYTHON) $(DEPTH)/build/mobile/robocop/parse_ids.py -i $(DEPTH)/mobile/android/base/R.java -o $(DEPTH)/build/mobile/robocop/fennec_ids.txt +endif + +stage-mochitest: robotium-id-map stage-mochitest: make-stage-dir $(MAKE) -C $(DEPTH)/testing/mochitest stage-package +ifeq ($(MOZ_BUILD_APP),mobile/android) + $(NSINSTALL) $(DEPTH)/build/mobile/robocop/robocop.apk $(PKG_STAGE)/bin + $(NSINSTALL) $(DEPTH)/build/mobile/robocop/fennec_ids.txt $(PKG_STAGE)/mochitest +endif stage-reftest: make-stage-dir $(MAKE) -C $(DEPTH)/layout/tools/reftest stage-package stage-xpcshell: make-stage-dir $(MAKE) -C $(DEPTH)/testing/xpcshell stage-package stage-jstests: make-stage-dir $(MAKE) -C $(DEPTH)/js/src/tests stage-package stage-android: make-stage-dir $(NSINSTALL) $(DEPTH)/build/mobile/sutagent/android/sutAgentAndroid.apk $(PKG_STAGE)/bin $(NSINSTALL) $(DEPTH)/build/mobile/sutagent/android/watcher/Watcher.apk $(PKG_STAGE)/bin $(NSINSTALL) $(DEPTH)/build/mobile/sutagent/android/fencp/FenCP.apk $(PKG_STAGE)/bin $(NSINSTALL) $(DEPTH)/build/mobile/sutagent/android/ffxcp/FfxCP.apk $(PKG_STAGE)/bin -ifeq ($(MOZ_BUILD_APP),mobile/android) - $(NSINSTALL) $(DEPTH)/build/mobile/robocop/robocop.apk $(PKG_STAGE)/bin - $(PYTHON) $(DIST)/../build/mobile/robocop/parse_ids.py -i $(DEPTH)/mobile/android/base/R.java -o $(DEPTH)/build/mobile/robocop/fennec_ids.txt - $(NSINSTALL) $(DEPTH)/build/mobile/robocop/fennec_ids.txt $(PKG_STAGE)/bin -endif stage-jetpack: make-stage-dir $(NSINSTALL) $(topsrcdir)/testing/jetpack/jetpack-location.txt $(PKG_STAGE)/jetpack stage-firebug: make-stage-dir $(MAKE) -C $(DEPTH)/testing/firebug stage-package stage-peptest: make-stage-dir
--- a/toolkit/components/downloads/nsDownloadManager.cpp +++ b/toolkit/components/downloads/nsDownloadManager.cpp @@ -1938,19 +1938,18 @@ nsDownloadManager::Observe(nsISupports * NS_ENSURE_SUCCESS(rv, rv); PRUint32 id; dl->GetId(&id); nsDownload *dl2 = FindDownload(id); if (dl2) return CancelDownload(id); } else if (strcmp(aTopic, "profile-before-change") == 0) { - // Null statements to finalize them. - mGetIdsForURIStatement = nsnull; - mUpdateDownloadStatement = nsnull; + mGetIdsForURIStatement->Finalize(); + mUpdateDownloadStatement->Finalize(); mozilla::DebugOnly<nsresult> rv = mDBConn->Close(); MOZ_ASSERT(NS_SUCCEEDED(rv)); } else if (strcmp(aTopic, "quit-application") == 0) { // Try to pause all downloads and, if appropriate, mark them as auto-resume // unless user has specified that downloads should be canceled enum QuitBehavior behavior = GetQuitBehavior(); if (behavior != QUIT_AND_CANCEL) (void)PauseAllDownloads(bool(behavior != QUIT_AND_PAUSE));
--- a/toolkit/components/telemetry/Telemetry.h +++ b/toolkit/components/telemetry/Telemetry.h @@ -99,16 +99,44 @@ public: AccumulateTimeDelta(id, start); } private: const TimeStamp start; MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER }; +template<ID id> +class AutoCounter { +public: + AutoCounter(PRUint32 counterStart = 0 MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + : counter(counterStart) + { + MOZ_GUARD_OBJECT_NOTIFIER_INIT; + } + + ~AutoCounter() { + Accumulate(id, counter); + } + + // Prefix increment only, to encourage good habits. + void operator++() { + ++counter; + } + + // Chaining doesn't make any sense, don't return anything. + void operator+=(int increment) { + counter += increment; + } + +private: + PRUint32 counter; + MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER +}; + /** * Records slow SQL statements for Telemetry reporting. * For privacy reasons, only prepared statements are reported. * * @param statement - offending SQL statement to record * @param dbName - DB filename; reporting is only done for whitelisted DBs * @param delay - execution time in milliseconds */
--- a/toolkit/components/telemetry/TelemetryHistograms.h +++ b/toolkit/components/telemetry/TelemetryHistograms.h @@ -309,17 +309,18 @@ HISTOGRAM(THUNDERBIRD_INDEXING_RATE_MSG_ // Disable this application-specific #ifdef ftb. (See bug 710562) // #ifdef MOZ_PHOENIX HISTOGRAM(FX_TAB_ANIM_OPEN_MS, 1, 3000, 10, EXPONENTIAL, "Firefox: Time taken by the tab opening animation") HISTOGRAM(FX_TAB_ANIM_CLOSE_MS, 1, 3000, 10, EXPONENTIAL, "Firefox: Time taken by the tab closing animation") HISTOGRAM_BOOLEAN(FX_CONTEXT_SEARCH_AND_TAB_SELECT, "Firefox: Background tab was selected within 5 seconds of searching from the context menu") // #endif HISTOGRAM_BOOLEAN(INNERWINDOWS_WITH_MUTATION_LISTENERS, "Deleted or to-be-reused innerwindow which has had mutation event listeners.") -HISTOGRAM(XUL_REFLOW_MS, 1, 3000, 10, EXPONENTIAL, "xul reflows") +HISTOGRAM(XUL_REFLOW_MS, 1, 3000, 10, EXPONENTIAL, "XUL reflows (ms)") +HISTOGRAM(HTML_REFLOW_MS, 1, 3000, 10, EXPONENTIAL, "HTML reflows (ms)") HISTOGRAM(XUL_INITIAL_FRAME_CONSTRUCTION, 1, 3000, 10, EXPONENTIAL, "initial xul frame construction") HISTOGRAM_BOOLEAN(XMLHTTPREQUEST_ASYNC_OR_SYNC, "Type of XMLHttpRequest, async or sync") /** * DOM Storage telemetry. */ #define DOMSTORAGE_HISTOGRAM(PREFIX, TYPE, TYPESTRING, DESCRIPTION) \ HISTOGRAM(PREFIX ## DOMSTORAGE_ ## TYPE ## _SIZE_BYTES, \
--- a/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp +++ b/toolkit/components/typeaheadfind/nsTypeAheadFind.cpp @@ -555,16 +555,17 @@ nsTypeAheadFind::FindItNow(nsIPresShell // link, we'll blur, which will lose the ATTENTION. if (selectionController) { // Beware! This may flush notifications via synchronous // ScrollSelectionIntoView. SetSelectionModeAndRepaint(nsISelectionController::SELECTION_ATTENTION); selectionController->ScrollSelectionIntoView( nsISelectionController::SELECTION_NORMAL, nsISelectionController::SELECTION_WHOLE_SELECTION, + nsISelectionController::SCROLL_CENTER_VERTICALLY | nsISelectionController::SCROLL_SYNCHRONOUS); } mCurrentWindow = window; *aResult = hasWrapped ? FIND_WRAPPED : FIND_FOUND; return NS_OK; }
--- a/toolkit/mozapps/extensions/content/extensions.xul +++ b/toolkit/mozapps/extensions/content/extensions.xul @@ -523,17 +523,19 @@ <button id="detail-undo-btn" class="button-link" label="&addon.undoAction.label;" tooltipText="&addon.undoAction.tooltip;" command="cmd_cancelOperation"/> <spacer flex="5000"/> <!-- Necessary to allow the message to wrap --> </hbox> </vbox> <hbox align="start"> - <image id="detail-icon" class="icon"/> + <vbox id="detail-icon-container" align="end"> + <image id="detail-icon" class="icon"/> + </vbox> <vbox flex="1"> <vbox id="detail-summary"> <hbox id="detail-name-container" class="name-container" align="start"> <label id="detail-name" flex="1"/> <label id="detail-version"/> <label class="disabled-postfix" value="&addon.disabled.postfix;"/> <label class="update-postfix" value="&addon.update.postfix;"/>
--- a/toolkit/themes/gnomestripe/mozapps/extensions/extensions.css +++ b/toolkit/themes/gnomestripe/mozapps/extensions/extensions.css @@ -643,18 +643,22 @@ } #detail-notifications .warning, #detail-notifications .pending, #detail-notifications .error { -moz-margin-start: 0; } +#detail-icon-container { + width: 64px; + -moz-margin-end: 10px; +} + #detail-icon { - -moz-margin-end: 10px; max-width: 64px; max-height: 64px; } #detail-summary { margin-bottom: 2em; }
--- a/toolkit/themes/pinstripe/mozapps/extensions/extensions.css +++ b/toolkit/themes/pinstripe/mozapps/extensions/extensions.css @@ -782,19 +782,23 @@ } #detail-notifications .warning, #detail-notifications .pending, #detail-notifications .error { -moz-margin-start: 0; } -#detail-icon { +#detail-icon-container { + width: 64px; -moz-margin-end: 10px; margin-top: 6px; +} + +#detail-icon { max-width: 64px; max-height: 64px; } #detail-summary { margin-bottom: 2em; }
--- a/toolkit/themes/winstripe/mozapps/extensions/extensions.css +++ b/toolkit/themes/winstripe/mozapps/extensions/extensions.css @@ -760,19 +760,23 @@ } #detail-notifications .warning, #detail-notifications .pending, #detail-notifications .error { -moz-margin-start: 0; } -#detail-icon { +#detail-icon-container { + width: 64px; -moz-margin-end: 10px; margin-top: 6px; +} + +#detail-icon { max-width: 64px; max-height: 64px; } #detail-summary { margin-bottom: 2em; }
--- a/widget/xpwidgets/nsIdleService.cpp +++ b/widget/xpwidgets/nsIdleService.cpp @@ -195,17 +195,17 @@ nsIdleService::AddIdleObserver(nsIObserv // Create our timer callback if it's not there already. if (!mTimer) { nsresult rv; mTimer = do_CreateInstance(NS_TIMER_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); } // Make sure our observer goes into 'idle' immediately if applicable. - CheckAwayState(false); + CheckAwayState(true); return NS_OK; } NS_IMETHODIMP nsIdleService::RemoveIdleObserver(nsIObserver* aObserver, PRUint32 aTime) { NS_ENSURE_ARG_POINTER(aObserver); @@ -223,28 +223,21 @@ nsIdleService::RemoveIdleObserver(nsIObs // If we get here, we haven't removed anything: return NS_ERROR_FAILURE; } void nsIdleService::ResetIdleTimeOut() { - // A zero in mLastIdleReset indicates that this function has never been - // called. - bool calledBefore = mLastIdleReset != 0; mLastIdleReset = PR_IntervalToSeconds(PR_IntervalNow()); if (!mLastIdleReset) mLastIdleReset = 1; // Now check if this changes anything - // Note that if we have never been called before, we cannot do the - // optimization of passing true to CheckAwayState, which avoids - // calculating the timer (because if we have never been called before, - // we need to recalculate the timer and start it there). - CheckAwayState(calledBefore); + CheckAwayState(false); } NS_IMETHODIMP nsIdleService::GetIdleTime(PRUint32* idleTime) { // Check sanity of in parameter. if (!idleTime) { return NS_ERROR_NULL_POINTER; @@ -301,83 +294,158 @@ nsIdleService::UsePollMode() void nsIdleService::IdleTimerCallback(nsITimer* aTimer, void* aClosure) { static_cast<nsIdleService*>(aClosure)->CheckAwayState(false); } void -nsIdleService::CheckAwayState(bool aNoTimeReset) +nsIdleService::CheckAwayState(bool aNewObserver) { /** * Find our last detected idle time (it's important this happens before the * call below to GetIdleTime, as we use the two values to detect if there * has been user activity since the last time we were here). */ PRUint32 curTime = static_cast<PRUint32>(PR_Now() / PR_USEC_PER_SEC); PRUint32 lastTime = curTime - mLastHandledActivity; + bool bootstrapTimer = mLastHandledActivity == 0; + + /** + * Too short since last check. + * Bail out + */ + if (!lastTime && !aNewObserver) { + return; + } // Get the idle time (in seconds). PRUint32 idleTime; if (NS_FAILED(GetIdleTime(&idleTime))) { return; } // If we have no valid data about the idle time, stop if (!mPolledIdleTimeIsValid && 0 == mLastIdleReset) { return; } // GetIdleTime returns the time in ms, internally we only calculate in s. idleTime /= 1000; - // We need a text string to send with any state change events. - nsAutoString timeStr; - timeStr.AppendInt(idleTime); - // Set the time for last user activity. mLastHandledActivity = curTime - idleTime; /** * Now, if the idle time, is less than what we expect, it means the * user was active since last time that we checked. */ - nsCOMArray<nsIObserver> notifyList; - - if (lastTime > idleTime) { - // Loop trough all listeners, and find any that have detected idle. - for (PRUint32 i = 0; i < mArrayListeners.Length(); i++) { - IdleListener& curListener = mArrayListeners.ElementAt(i); + bool userActivity = lastTime > idleTime; - if (curListener.isIdle) { - notifyList.AppendObject(curListener.observer); - curListener.isIdle = false; - } - } - - // Send the "non-idle" events. - for (PRInt32 i = 0; i < notifyList.Count(); i++) { - notifyList[i]->Observe(this, OBSERVER_TOPIC_BACK, timeStr.get()); + if (userActivity) { + if (TryNotifyBackState(idleTime) || idleTime) { + RescheduleIdleTimer(idleTime); } } + if (!userActivity || aNewObserver || bootstrapTimer) { + TryNotifyIdleState(idleTime); + RescheduleIdleTimer(idleTime); + } +} + +bool +nsIdleService::TryNotifyBackState(PRUint32 aIdleTime) +{ + nsCOMArray<nsIObserver> notifyList; + + // Loop trough all listeners, and find any that have detected idle. + for (PRUint32 i = 0; i < mArrayListeners.Length(); i++) { + IdleListener& curListener = mArrayListeners.ElementAt(i); + + if (curListener.isIdle) { + notifyList.AppendObject(curListener.observer); + curListener.isIdle = false; + } + } + + PRInt32 numberOfPendingNotifications = notifyList.Count(); + + // Bail id nothing to do + if(!numberOfPendingNotifications) { + return false; + } + + // We need a text string to send with any state change events. + nsAutoString timeStr; + timeStr.AppendInt(aIdleTime); + + // Send the "non-idle" events. + while(numberOfPendingNotifications--) { + notifyList[numberOfPendingNotifications]->Observe(this, + OBSERVER_TOPIC_BACK, + timeStr.get()); + } + + // We found something so return true + return true; +} + +bool +nsIdleService::TryNotifyIdleState(PRUint32 aIdleTime) +{ /** * Now we need to check for listeners that have expired, and while we are * looping through all the elements, we will also calculate when, if ever * the next one will need to be notified. */ - // Clean up the list, so it's ready for the next iteration. - notifyList.Clear(); + nsCOMArray<nsIObserver> notifyList; + + for (PRUint32 i = 0; i < mArrayListeners.Length(); i++) { + IdleListener& curListener = mArrayListeners.ElementAt(i); + + // We are only interested in items, that are not in the idle state. + if (!curListener.isIdle) { + // If they have an idle time smaller than the actual idle time. + if (curListener.reqIdleTime <= aIdleTime) { + // then add the listener to the list of listeners that should be + // notified. + notifyList.AppendObject(curListener.observer); + // This listener is now idle. + curListener.isIdle = true; + } + } + } + + PRInt32 numberOfPendingNotifications = notifyList.Count(); - // Bail out if we don't need to calculate new times. - if (aNoTimeReset) { - return; + // Bail if nothing to do + if(!numberOfPendingNotifications) { + return false; } + + // We need a text string to send with any state change events. + nsAutoString timeStr; + timeStr.AppendInt(aIdleTime); + + // Notify all listeners that just timed out. + while(numberOfPendingNotifications--) { + notifyList[numberOfPendingNotifications]->Observe(this, + OBSERVER_TOPIC_IDLE, + timeStr.get()); + } + + return true; +} + +void +nsIdleService::RescheduleIdleTimer(PRUint32 aIdleTime) +{ /** * Placet to store the wait time to the next notification, note that * PR_UINT32_MAX means no-one are listening (or that they have such a big * delay that it doesn't matter). */ PRUint32 nextWaitTime = PR_UINT32_MAX; /** @@ -387,42 +455,30 @@ nsIdleService::CheckAwayState(bool aNoTi */ bool anyOneIdle = false; for (PRUint32 i = 0; i < mArrayListeners.Length(); i++) { IdleListener& curListener = mArrayListeners.ElementAt(i); // We are only interested in items, that are not in the idle state. if (!curListener.isIdle) { - // If they have an idle time smaller than the actual idle time. - if (curListener.reqIdleTime <= idleTime) { - // then add the listener to the list of listeners that should be - // notified. - notifyList.AppendObject(curListener.observer); - // This listener is now idle. - curListener.isIdle = true; - } else { // If it hasn't expired yet, then we should note the time when it should // expire. nextWaitTime = NS_MIN(nextWaitTime, curListener.reqIdleTime); - } } // Remember if anyone becomes idle (it's safe to do this as a binary compare // as we are or'ing). anyOneIdle |= curListener.isIdle; } // In order to find when the next idle event should time out, we need to // subtract the time we should wait, from the time that has already passed. - nextWaitTime -= idleTime; - - // Notify all listeners that just timed out. - for (PRInt32 i = 0; i < notifyList.Count(); i++) { - notifyList[i]->Observe(this, OBSERVER_TOPIC_IDLE, timeStr.get()); + if (PR_UINT32_MAX != nextWaitTime) { + nextWaitTime -= aIdleTime; } // If we are in poll mode, we need to poll for activity if anyone are idle, // otherwise we can wait polling until they would expire. if (UsePollMode() && anyOneIdle && nextWaitTime > MIN_IDLE_POLL_INTERVAL) { nextWaitTime = MIN_IDLE_POLL_INTERVAL;
--- a/widget/xpwidgets/nsIdleService.h +++ b/widget/xpwidgets/nsIdleService.h @@ -156,20 +156,20 @@ protected: * * @return true if polling is supported, false otherwise. */ virtual bool UsePollMode(); /** * Send expired events and start timers. * - * @param aNoTimeReset - * If true new times will not be calculated. + * @param aNewObserver + * Whether there are new observers to check. */ - void CheckAwayState(bool aNoTimeReset); + void CheckAwayState(bool aNewObserver); private: /** * Start the internal timer, restart it if it is allready running. * * @param aDelay * The time in seconds that should pass before the next timeout. */ @@ -220,11 +220,41 @@ private: */ static void IdleTimerCallback(nsITimer* aTimer, void* aClosure); /** * Whether the idle time calculated in the last call to GetIdleTime is * actually valid (see nsIdleService.idl - we return 0 when it isn't). */ bool mPolledIdleTimeIsValid; + + /** + * Check if any listeners were in idle state, notify them that user + * is back and change them to non-idle state. + * + * @param aIdleTime + * The idle time in seconds. + * + * @return true if any listeners were notified. + */ + bool TryNotifyBackState(PRUint32 aIdleTime); + + /** + * Check if any listeners were in non-idle state, notify them that user + * is idle and change them to idle state. + * + * @param aIdleTime + * The idle time in seconds. + * + * @return true if any listeners were notified. + */ + bool TryNotifyIdleState(PRUint32 aIdleTime); + + /** + * Reschedule the idle timer to fire on next checkpoint. + * + * @param aIdleTime + * The idle time has passed in seconds. + */ + void RescheduleIdleTimer(PRUint32 aIdleTime); }; #endif // nsIdleService_h__
--- a/xpcom/base/AvailableMemoryTracker.cpp +++ b/xpcom/base/AvailableMemoryTracker.cpp @@ -409,25 +409,25 @@ public: NS_IMETHOD GetDescription(nsACString &aDescription) { aDescription.AssignLiteral( "Number of low-physical-memory events fired since startup. "); if (sLowPhysicalMemoryThreshold == 0 || !sHooksInstalled) { aDescription.Append(nsPrintfCString(1024, "Tracking low-physical-memory events is disabled, but you can enable it " - "by giving the memory.low_physical_mem_threshold_mb pref a non-zero " + "by giving the memory.low_physical_memory_threshold_mb pref a non-zero " "value%s.", sHooksInstalled ? "" : " and restarting")); } else { aDescription.Append(nsPrintfCString(1024, "We fire such an event if we notice there is less than %d MB of " "available physical memory (controlled by the " - "'memory.low_physical_mem_threshold_mb' pref). The machine will start " + "'memory.low_physical_memory_threshold_mb' pref). The machine will start " "to page if it runs out of physical memory; this may cause it to run " "slowly, but it shouldn't cause us to crash.", sLowPhysicalMemoryThreshold)); } return NS_OK; } }; @@ -446,17 +446,17 @@ void Init() sLowVirtualMemoryThreshold = 0; } else { Preferences::AddUintVarCache(&sLowVirtualMemoryThreshold, "memory.low_virtual_mem_threshold_mb", 128); } Preferences::AddUintVarCache(&sLowPhysicalMemoryThreshold, - "memory.low_physical_mem_threshold_mb", 0); + "memory.low_physical_memory_threshold_mb", 0); Preferences::AddUintVarCache(&sLowPhysicalMemoryNotificationIntervalMS, "memory.low_physical_memory_notification_interval_ms", 10000); // Don't register the hooks if we're a build instrumented for PGO or if both // thresholds are 0. (If we're an instrumented build, the compiler adds // function calls all over the place which may call VirtualAlloc; this makes // it hard to prevent VirtualAllocHook from reentering itself.)
--- a/xpcom/ds/nsCheapSets.h +++ b/xpcom/ds/nsCheapSets.h @@ -170,17 +170,26 @@ private: /** Get the single integer */ PRInt32 GetInt() { return PtrBits(mValOrHash) >> 1; } /** Set the single integer */ void SetInt(PRInt32 aInt) { - mValOrHash = (void*)((aInt << 1) | 0x1); + /** + * NOTE: on 64-bit GCC, we do an intermediate cast to (intptr_t) to fix + * build warning about converting 32-bit value to 64-bit pointer. + * This is GCC-only since some platforms/compilers lack "intptr_t". + */ + mValOrHash = (void*) +#if (defined(__GNUC__) && defined(__x86_64__)) + (intptr_t) +#endif + ((aInt << 1) | 0x1); } /** Create the hash and initialize */ nsresult InitHash(nsInt32HashSet** aSet); private: /** A hash or int, depending on the lower bit (0=hash, 1=int) */ void* mValOrHash; };