author | Ehsan Akhgari <ehsan@mozilla.com> |
Mon, 11 Apr 2011 20:24:12 -0400 | |
changeset 67875 | 0cfe6840e0a4a771e290a94c6a31101f9beaf9f5 |
parent 67874 | 3577f08df0c106cb7297f77d9f04c3df9733a18b (current diff) |
parent 67871 | 6f1a2405f71ec92e9484475f2cb6474fb99475ff (diff) |
child 67876 | c2bd5cf4070e0794a5dcd197f904fdbfd18ac0cf |
child 68306 | 19edf1831109cd45cacd925ce0fba813d29950aa |
push id | 1 |
push user | root |
push date | Tue, 26 Apr 2011 22:38:44 +0000 |
treeherder | mozilla-beta@bfdb6e623a36 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
milestone | 2.2a1pre |
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
|
--- a/browser/base/content/sanitize.js +++ b/browser/base/content/sanitize.js @@ -152,17 +152,17 @@ Sanitizer.prototype = { } else { // Remove everything cookieMgr.removeAll(); } // Clear plugin data. let ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost); - const phInterface = Ci.nsIPluginHost_MOZILLA_2_0_BRANCH; + const phInterface = Ci.nsIPluginHost; const FLAG_CLEAR_ALL = phInterface.FLAG_CLEAR_ALL; ph.QueryInterface(phInterface); // Determine age range in seconds. (-1 means clear all.) We don't know // that this.range[1] is actually now, so we compute age range based // on the lower bound. If this.range results in a negative age, do // nothing. let age = this.range ? (Date.now() / 1000 - this.range[0] / 1000000)
--- a/browser/base/content/test/browser_clearplugindata.js +++ b/browser/base/content/test/browser_clearplugindata.js @@ -5,17 +5,17 @@ // Test clearing plugin data using sanitize.js. const testURL1 = "http://mochi.test:8888/browser/browser/base/content/test/browser_clearplugindata.html"; const testURL2 = "http://mochi.test:8888/browser/browser/base/content/test/browser_clearplugindata_noage.html"; Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader) .loadSubScript("chrome://browser/content/sanitize.js"); -const pluginHostIface = Ci.nsIPluginHost_MOZILLA_2_0_BRANCH; +const pluginHostIface = Ci.nsIPluginHost; var pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost); pluginHost.QueryInterface(pluginHostIface); var pluginTag; var s; function stored(needles) { var something = pluginHost.siteHasData(this.pluginTag, null);
--- a/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js +++ b/browser/components/privatebrowsing/src/nsPrivateBrowsingService.js @@ -613,17 +613,17 @@ PrivateBrowsingService.prototype = { while (enumerator.hasMoreElements()) { let cookie = enumerator.getNext().QueryInterface(Ci.nsICookie); cm.remove(cookie.host, cookie.name, cookie.path, false); } } // Plugin data let (ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost)) { - const phInterface = Ci.nsIPluginHost_MOZILLA_2_0_BRANCH; + const phInterface = Ci.nsIPluginHost; const FLAG_CLEAR_ALL = phInterface.FLAG_CLEAR_ALL; ph.QueryInterface(phInterface); let tags = ph.getPluginTags(); for (let i = 0; i < tags.length; i++) { try { ph.clearSiteData(tags[i], aDomain, FLAG_CLEAR_ALL, -1); } catch (e) {
--- a/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_clearplugindata.js +++ b/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_clearplugindata.js @@ -1,17 +1,17 @@ /** * Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ // Test clearing plugin data by domain using nsPrivateBrowsingService. const testURL = "http://mochi.test:8888/browser/browser/components/privatebrowsing/test/browser/browser_privatebrowsing_clearplugindata.html"; -const pluginHostIface = Ci.nsIPluginHost_MOZILLA_2_0_BRANCH; +const pluginHostIface = Ci.nsIPluginHost; var pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost); pluginHost.QueryInterface(pluginHostIface); var pluginTag; function stored(needles) { var something = pluginHost.siteHasData(this.pluginTag, null); if (!needles)
--- a/content/base/public/nsIContentUtils.h +++ b/content/base/public/nsIContentUtils.h @@ -86,35 +86,9 @@ public: virtual nsIInterfaceRequestor* GetSameOriginChecker(); // Returns NS_OK for same origin, error (NS_ERROR_DOM_BAD_URI) if not. virtual nsresult CheckSameOrigin(nsIChannel *aOldChannel, nsIChannel *aNewChannel); }; NS_DEFINE_STATIC_IID_ACCESSOR(nsIContentUtils2, NS_ICONTENTUTILS2_IID) -#ifndef MOZ_ENABLE_LIBXUL -// nsIContentUtils_MOZILLA_2_0_BRANCH is a non-libxul only interface to enable -// us keep those builds working. - -#define NS_ICONTENTUTILS_MOZILLA_2_0_BRANCH_IID \ -{ 0x0fe8099c, 0x622a, 0x4c79, \ -{ 0xb0, 0x02, 0x55, 0xf0, 0x44, 0x34, 0x00, 0x30 } } - -class nsIContentUtils_MOZILLA_2_0_BRANCH : public nsISupports -{ -public: - NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENTURILS_MOZILLA_2_0_BRANCH_IID) - NS_DECL_ISUPPORTS - - virtual nsresult DispatchTrustedEvent(nsIDocument* aDoc, - nsISupports* aTarget, - const nsAString& aEventName, - PRBool aCanBubble, - PRBool aCancelable, - PRBool *aDefaultAction = nsnull); -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIContentUtils_MOZILLA_2_0_BRANCH, NS_ICONTENTUTILS_MOZILLA_2_0_BRANCH_IID) - -#endif - #endif /* nsIContentUtils_h__ */
--- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -6509,26 +6509,8 @@ nsIContentUtils2::GetSameOriginChecker() return nsContentUtils::GetSameOriginChecker(); } nsresult nsIContentUtils2::CheckSameOrigin(nsIChannel *aOldChannel, nsIChannel *aNewChannel) { return nsContentUtils::CheckSameOrigin(aOldChannel, aNewChannel); } - -#ifndef MOZ_ENABLE_LIBXUL - -NS_IMPL_ISUPPORTS1(nsIContentUtils_MOZILLA_2_0_BRANCH, nsIContentUtils_MOZILLA_2_0_BRANCH) - -nsresult -nsIContentUtils_MOZILLA_2_0_BRANCH::DispatchTrustedEvent(nsIDocument* aDoc, - nsISupports* aTarget, - const nsAString& aEventName, - PRBool aCanBubble, - PRBool aCancelable, - PRBool *aDefaultAction) -{ - return nsContentUtils::DispatchTrustedEvent(aDoc, aTarget, aEventName, - aCanBubble, aCancelable, aDefaultAction); -} - -#endif
--- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -6745,20 +6745,18 @@ nsDocument::WalkRadioGroup(const nsAStri PRBool aFlushContent) { nsRadioGroupStruct* radioGroup = nsnull; GetRadioGroup(aName, &radioGroup); if (!radioGroup) { return NS_OK; } - PRBool stop = PR_FALSE; for (int i = 0; i < radioGroup->mRadioButtons.Count(); i++) { - aVisitor->Visit(radioGroup->mRadioButtons[i], &stop); - if (stop) { + if (!aVisitor->Visit(radioGroup->mRadioButtons[i])) { return NS_OK; } } return NS_OK; } PRUint32
--- a/content/base/test/test_CrossSiteXHR.html +++ b/content/base/test/test_CrossSiteXHR.html @@ -837,16 +837,21 @@ function runTest() { is(res.events.join(","), "opening,rs1,sending,rs1,loadstart,rs2,rs4,error,loadend", "wrong events in test for " + test.toSource()); is(res.progressEvents, 0, "wrong events in test for " + test.toSource()); } } + // Make sure to clear cookies to avoid affecting other tests + document.cookie = "a=; path=/; expires=Thu, 01-Jan-1970 00:00:01 GMT" + is(document.cookie, "", "No cookies should be left over"); + + // Test redirects is(loader.src, "http://example.org/tests/content/base/test/file_CrossSiteXHR_inner.html"); is(origin, "http://example.org"); tests = [{ pass: 1, method: "GET", hops: [{ server: "http://example.com", allowOrigin: origin
--- a/content/base/test/test_bug482935.html +++ b/content/base/test/test_bug482935.html @@ -25,34 +25,34 @@ function testCancelInPhase4() { clearCache(); // First request - should be loaded from server var xhr = new XMLHttpRequest(); xhr.addEventListener("readystatechange", function(e) { if (xhr.readyState >= 4) { xhr.abort(); - setTimeout(function() { + SimpleTest.executeSoon(function() { // This request was cancelled, so the responseText should be empty string is(xhr.responseText, "", "Expected empty response to cancelled request"); // Second request - should be found in cache var xhr2 = new XMLHttpRequest(); xhr2.open("GET", url, false); // note : synch-request xhr2.setRequestHeader("X-Request", "1", false); try { xhr2.send(); } catch(e) { is(xhr2.status, "200", "Exception!"); } is(xhr2.responseText, "0", "Received fresh value for second request"); testCancelBeforePhase4(); - }, 100); + }); } }, false); xhr.open("GET", url, true); xhr.setRequestHeader("X-Request", "0", false); try { xhr.send(); } catch(e) { is("Nothing", "Exception", "Boom: " + e); @@ -65,34 +65,34 @@ function testCancelBeforePhase4() { clearCache(); // First request - should be loaded from server var xhr = new XMLHttpRequest(); xhr.addEventListener("readystatechange", function(e) { if (xhr.readyState == 3) { xhr.abort(); - setTimeout(function() { + SimpleTest.executeSoon(function() { // This request was cancelled, so the responseText should be empty string is(xhr.responseText, "", "Expected empty response to cancelled request"); // Second request - should be found in cache var xhr2 = new XMLHttpRequest(); xhr2.open("GET", url, false); // note : synch-request xhr2.setRequestHeader("X-Request", "1", false); try { xhr2.send(); } catch(e) { is(xhr2.status, "200", "Exception!"); } is(xhr2.responseText, "1", "Received cached value for second request"); SimpleTest.finish(); - }, 100); + }); } }, false); xhr.open("GET", url, true); xhr.setRequestHeader("X-Request", "0", false); try { xhr.send(); } catch(e) { is("Nothing", "Exception", "Boom: " + e);
--- a/content/html/content/public/nsIRadioVisitor.h +++ b/content/html/content/public/nsIRadioVisitor.h @@ -36,80 +36,40 @@ * * ***** END LICENSE BLOCK ***** */ #ifndef nsIRadioVisitor_h___ #define nsIRadioVisitor_h___ #include "nsISupports.h" class nsIFormControl; -class nsIDocument; // IID for the nsIRadioControl interface #define NS_IRADIOVISITOR_IID \ -{ 0xd3494bd2, 0x1dd1, 0x11b2, \ - { 0xbe, 0x86, 0xb5, 0x08, 0xc8, 0x71, 0xd7, 0xc5 } } +{ 0xc6bed232, 0x1181, 0x4ab2, \ + { 0xa1, 0xda, 0x55, 0xc2, 0x13, 0x6d, 0xea, 0x3d } } /** * This interface is used for the text control frame to store its value away * into the content. */ class nsIRadioVisitor : public nsISupports { public: NS_DECLARE_STATIC_IID_ACCESSOR(NS_IRADIOVISITOR_IID) /** * Visit a node in the tree. This is meant to be called on all radios in a * group, sequentially. (Each radio group implementor may define * sequentially in their own way, it just has to be the same every time.) * Currently all radio groups are ordered in the order they appear in the - * document. Radio group implementors should honor the aStop parameter and - * stop iterating over form controls when Visit() returns true there. + * document. Radio group implementors should honor the return value of the + * method and stop iterating if the return value is false. * * @param aRadio the radio button in question (must be nsnull and QI'able to * nsIRadioControlElement) - * @param aStop whether or not to stop iterating (out-param) */ - NS_IMETHOD Visit(nsIFormControl* aRadio, PRBool* aStop) = 0; + virtual PRBool Visit(nsIFormControl* aRadio) = 0; }; NS_DEFINE_STATIC_IID_ACCESSOR(nsIRadioVisitor, NS_IRADIOVISITOR_IID) -/** - * This visitor sets CheckedChanged on all elements it finds. - * - * @param aVisitor the visitor (out param) - * @param aCheckedChanged the value of CheckedChanged to set on all elements - */ -nsresult -NS_GetRadioSetCheckedChangedVisitor(PRBool aCheckedChanged, - nsIRadioVisitor** aVisitor); - -/** - * This visitor will take the boolean you're pointing at and put - * aCheckedChanged into it. If the visitor is never called, aCheckedChanged - * will of course not change. - * - * @param aVisitor the visitor (out param) - * @param aCheckedChanged the boolean to put CheckedChanged into - * @param aExcludeElement the element - */ -nsresult -NS_GetRadioGetCheckedChangedVisitor(PRBool* aCheckedChanged, - nsIFormControl* aExcludeElement, - nsIRadioVisitor** aVisitor); - -/** - * This visitor will update the validity states of all radio in the group and - * call ContentStatesChanged if needed. - * - * @param aExcludeElement an element to exclude (for optimization purpose), can be null - * @param aDocument the document owning the group - * @param aNotify whether we should call ContentStatesChanged - * @return the visitor - */ -nsIRadioVisitor* -NS_SetRadioValueMissingState(nsIFormControl* aExcludeElement, - nsIDocument* aDocument, - bool aValidity, bool aNotify); - #endif // nsIRadioVisitor_h___
--- a/content/html/content/src/Makefile.in +++ b/content/html/content/src/Makefile.in @@ -105,16 +105,17 @@ CPPSRCS = \ nsHTMLTableColElement.cpp \ nsHTMLTableRowElement.cpp \ nsHTMLTableSectionElement.cpp \ nsHTMLTextAreaElement.cpp \ nsHTMLTitleElement.cpp \ nsHTMLUnknownElement.cpp \ nsDOMValidityState.cpp \ nsIConstraintValidation.cpp \ + nsRadioVisitor.cpp \ $(NULL) ifdef MOZ_MEDIA CPPSRCS += \ nsHTMLAudioElement.cpp \ nsHTMLMediaElement.cpp \ nsMediaError.cpp \ nsHTMLSourceElement.cpp \
--- a/content/html/content/src/nsHTMLFormElement.cpp +++ b/content/html/content/src/nsHTMLFormElement.cpp @@ -2050,34 +2050,31 @@ nsHTMLFormElement::GetNextRadioButton(co NS_IMETHODIMP nsHTMLFormElement::WalkRadioGroup(const nsAString& aName, nsIRadioVisitor* aVisitor, PRBool aFlushContent) { nsresult rv = NS_OK; - PRBool stopIterating = PR_FALSE; - if (aName.IsEmpty()) { // // XXX If the name is empty, it's not stored in the control list. There // *must* be a more efficient way to do this. // nsCOMPtr<nsIFormControl> control; PRUint32 len = GetElementCount(); for (PRUint32 i=0; i<len; i++) { control = GetElementAt(i); if (control->GetType() == NS_FORM_INPUT_RADIO) { nsCOMPtr<nsIContent> controlContent(do_QueryInterface(control)); if (controlContent) { if (controlContent->AttrValueIs(kNameSpaceID_None, nsGkAtoms::name, EmptyString(), eCaseMatters)) { - aVisitor->Visit(control, &stopIterating); - if (stopIterating) { + if (!aVisitor->Visit(control)) { break; } } } } } } else { // @@ -2089,31 +2086,30 @@ nsHTMLFormElement::WalkRadioGroup(const if (item) { // // If it's just a lone radio button, then select it. // nsCOMPtr<nsIFormControl> formControl(do_QueryInterface(item)); if (formControl) { if (formControl->GetType() == NS_FORM_INPUT_RADIO) { - aVisitor->Visit(formControl, &stopIterating); + aVisitor->Visit(formControl); } } else { nsCOMPtr<nsIDOMNodeList> nodeList(do_QueryInterface(item)); if (nodeList) { PRUint32 length = 0; nodeList->GetLength(&length); for (PRUint32 i=0; i<length; i++) { nsCOMPtr<nsIDOMNode> node; nodeList->Item(i, getter_AddRefs(node)); nsCOMPtr<nsIFormControl> formControl(do_QueryInterface(node)); if (formControl) { if (formControl->GetType() == NS_FORM_INPUT_RADIO) { - aVisitor->Visit(formControl, &stopIterating); - if (stopIterating) { + if (!aVisitor->Visit(formControl)) { break; } } } } } } }
--- a/content/html/content/src/nsHTMLInputElement.cpp +++ b/content/html/content/src/nsHTMLInputElement.cpp @@ -92,17 +92,16 @@ #include "nsIEventListenerManager.h" #include "nsRuleData.h" // input type=radio #include "nsIRadioGroupContainer.h" // input type=file -#include "nsIFile.h" #include "nsILocalFile.h" #include "nsNetUtil.h" #include "nsDOMFile.h" #include "nsIFilePicker.h" #include "nsDirectoryServiceDefs.h" #include "nsIPrivateBrowsingService.h" #include "nsIContentURIGrouper.h" #include "nsIContentPrefService.h" @@ -113,16 +112,17 @@ // input type=image #include "nsImageLoadingContent.h" #include "nsIDOMWindowInternal.h" #include "mozAutoDocUpdate.h" #include "nsContentCreatorFunctions.h" #include "nsCharSeparatedTokenizer.h" #include "nsContentUtils.h" +#include "nsRadioVisitor.h" #include "nsTextEditRules.h" // JS headers are needed for the pattern attribute. #include "jsapi.h" #include "jscntxt.h" #include "nsHTMLInputElement.h" @@ -1504,19 +1504,18 @@ nsHTMLInputElement::SetCheckedChanged(PR } void nsHTMLInputElement::DoSetCheckedChanged(PRBool aCheckedChanged, PRBool aNotify) { if (mType == NS_FORM_INPUT_RADIO) { if (GET_BOOLBIT(mBitField, BF_CHECKED_CHANGED) != aCheckedChanged) { - nsCOMPtr<nsIRadioVisitor> visitor; - NS_GetRadioSetCheckedChangedVisitor(aCheckedChanged, - getter_AddRefs(visitor)); + nsCOMPtr<nsIRadioVisitor> visitor = + new nsRadioSetCheckedChangedVisitor(aCheckedChanged); VisitGroup(visitor, aNotify); } } else { SetCheckedChangedInternal(aCheckedChanged); } } void @@ -3412,25 +3411,24 @@ nsHTMLInputElement::AddedToRadioGroup() // RadioSetChecked(notify); } // // For integrity purposes, we have to ensure that "checkedChanged" is // the same for this new element as for all the others in the group // - PRBool checkedChanged = GET_BOOLBIT(mBitField, BF_CHECKED_CHANGED); - nsCOMPtr<nsIRadioVisitor> visitor; - nsresult rv = NS_GetRadioGetCheckedChangedVisitor(&checkedChanged, this, - getter_AddRefs(visitor)); - if (NS_FAILED(rv)) { return; } - + bool checkedChanged = GET_BOOLBIT(mBitField, BF_CHECKED_CHANGED); + + nsCOMPtr<nsIRadioVisitor> visitor = + new nsRadioGetCheckedChangedVisitor(&checkedChanged, this); VisitGroup(visitor, notify); + SetCheckedChangedInternal(checkedChanged); - + // // Add the radio to the radio group container. // nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer(); if (container) { nsAutoString name; if (GetNameIfExists(name)) { container->AddToRadioGroup(name, static_cast<nsIFormControl*>(this)); @@ -3576,22 +3574,20 @@ nsHTMLInputElement::VisitGroup(nsIRadioV { nsresult rv = NS_OK; nsCOMPtr<nsIRadioGroupContainer> container = GetRadioGroupContainer(); if (container) { nsAutoString name; if (GetNameIfExists(name)) { rv = container->WalkRadioGroup(name, aVisitor, aFlushContent); } else { - PRBool stop; - aVisitor->Visit(this, &stop); + aVisitor->Visit(this); } } else { - PRBool stop; - aVisitor->Visit(this, &stop); + aVisitor->Visit(this); } return rv; } nsHTMLInputElement::ValueModeType nsHTMLInputElement::GetValueMode() const { switch (mType) @@ -3885,18 +3881,17 @@ nsHTMLInputElement::UpdateValueMissingVa if (container && !name.IsEmpty()) { if (container->GetValueMissingState(name) != valueMissing) { container->SetValueMissingState(name, valueMissing); SetValidityState(VALIDITY_STATE_VALUE_MISSING, valueMissing); nsCOMPtr<nsIRadioVisitor> visitor = - NS_SetRadioValueMissingState(this, GetCurrentDoc(), valueMissing, - notify); + new nsRadioSetValueMissingState(this, valueMissing, notify); VisitGroup(visitor, notify); } } else { SetValidityState(VALIDITY_STATE_VALUE_MISSING, valueMissing); } } void @@ -4153,222 +4148,16 @@ nsHTMLInputElement::IsPatternMatching(ns res = JS_ExecuteRegExpNoStatics(ctx, re, reinterpret_cast<jschar*> (aValue.BeginWriting()), aValue.Length(), &idx, JS_TRUE, &rval); return res == JS_FALSE || rval != JSVAL_NULL; } -// -// Visitor classes -// -// -// CLASS nsRadioVisitor -// -// (this is the superclass of the others) -// -class nsRadioVisitor : public nsIRadioVisitor { -public: - nsRadioVisitor() { } - virtual ~nsRadioVisitor() { } - - NS_DECL_ISUPPORTS - - NS_IMETHOD Visit(nsIFormControl* aRadio, PRBool* aStop) = 0; -}; - -NS_IMPL_ISUPPORTS1(nsRadioVisitor, nsIRadioVisitor) - - -// -// CLASS nsRadioSetCheckedChangedVisitor -// -class nsRadioSetCheckedChangedVisitor : public nsRadioVisitor { -public: - nsRadioSetCheckedChangedVisitor(PRBool aCheckedChanged) : - nsRadioVisitor(), mCheckedChanged(aCheckedChanged) - { } - - virtual ~nsRadioSetCheckedChangedVisitor() { } - - NS_IMETHOD Visit(nsIFormControl* aRadio, PRBool* aStop) - { - nsRefPtr<nsHTMLInputElement> radio = - static_cast<nsHTMLInputElement*>(aRadio); - NS_ASSERTION(radio, "Visit() passed a null button!"); - radio->SetCheckedChangedInternal(mCheckedChanged); - return NS_OK; - } - -protected: - PRPackedBool mCheckedChanged; -}; - -// -// CLASS nsRadioGetCheckedChangedVisitor -// -class nsRadioGetCheckedChangedVisitor : public nsRadioVisitor { -public: - nsRadioGetCheckedChangedVisitor(PRBool* aCheckedChanged, - nsIFormControl* aExcludeElement) : - nsRadioVisitor(), - mCheckedChanged(aCheckedChanged), - mExcludeElement(aExcludeElement) - { } - - virtual ~nsRadioGetCheckedChangedVisitor() { } - - NS_IMETHOD Visit(nsIFormControl* aRadio, PRBool* aStop) - { - if (aRadio == mExcludeElement) { - return NS_OK; - } - nsRefPtr<nsHTMLInputElement> radio = - static_cast<nsHTMLInputElement*>(aRadio); - NS_ASSERTION(radio, "Visit() passed a null button!"); - *mCheckedChanged = radio->GetCheckedChanged(); - *aStop = PR_TRUE; - return NS_OK; - } - -protected: - PRBool* mCheckedChanged; - nsIFormControl* mExcludeElement; -}; - -class nsRadioSetValueMissingState : public nsRadioVisitor { -public: - nsRadioSetValueMissingState(nsIFormControl* aExcludeElement, - nsIDocument* aDocument, bool aValidity, - bool aNotify) - : mExcludeElement(aExcludeElement) - , mDocument(aDocument) - , mValidity(aValidity) - , mNotify(aNotify) - { } - - NS_IMETHOD Visit(nsIFormControl* aRadio, PRBool* aStop) - { - if (aRadio == mExcludeElement) { - return NS_OK; - } - - nsHTMLInputElement* input = static_cast<nsHTMLInputElement*>(aRadio); - - input->SetValidityState(nsIConstraintValidation::VALIDITY_STATE_VALUE_MISSING, - mValidity); - - if (mNotify && mDocument) { - mDocument->ContentStateChanged(input, - NS_EVENT_STATE_VALID | - NS_EVENT_STATE_INVALID | - NS_EVENT_STATE_MOZ_UI_VALID | - NS_EVENT_STATE_MOZ_UI_INVALID); - } - - return NS_OK; - } - -protected: - nsIFormControl* mExcludeElement; - nsIDocument* mDocument; - bool mValidity; - bool mNotify; -}; - -nsresult -NS_GetRadioSetCheckedChangedVisitor(PRBool aCheckedChanged, - nsIRadioVisitor** aVisitor) -{ - // - // These are static so that we don't have to keep creating new visitors for - // such an ordinary process all the time. There are only two possibilities - // for this visitor: set to true, and set to false. - // - static nsIRadioVisitor* sVisitorTrue = nsnull; - static nsIRadioVisitor* sVisitorFalse = nsnull; - - // - // Get the visitor that sets them to true - // - if (aCheckedChanged) { - if (!sVisitorTrue) { - sVisitorTrue = new nsRadioSetCheckedChangedVisitor(PR_TRUE); - if (!sVisitorTrue) { - return NS_ERROR_OUT_OF_MEMORY; - } - NS_ADDREF(sVisitorTrue); - nsresult rv = - nsContentUtils::ReleasePtrOnShutdown((nsISupports**)&sVisitorTrue); - if (NS_FAILED(rv)) { - NS_RELEASE(sVisitorTrue); - return rv; - } - } - *aVisitor = sVisitorTrue; - } - // - // Get the visitor that sets them to false - // - else { - if (!sVisitorFalse) { - sVisitorFalse = new nsRadioSetCheckedChangedVisitor(PR_FALSE); - if (!sVisitorFalse) { - return NS_ERROR_OUT_OF_MEMORY; - } - NS_ADDREF(sVisitorFalse); - nsresult rv = - nsContentUtils::ReleasePtrOnShutdown((nsISupports**)&sVisitorFalse); - if (NS_FAILED(rv)) { - NS_RELEASE(sVisitorFalse); - return rv; - } - } - *aVisitor = sVisitorFalse; - } - - NS_ADDREF(*aVisitor); - return NS_OK; -} - -nsresult -NS_GetRadioGetCheckedChangedVisitor(PRBool* aCheckedChanged, - nsIFormControl* aExcludeElement, - nsIRadioVisitor** aVisitor) -{ - *aVisitor = new nsRadioGetCheckedChangedVisitor(aCheckedChanged, - aExcludeElement); - if (!*aVisitor) { - return NS_ERROR_OUT_OF_MEMORY; - } - NS_ADDREF(*aVisitor); - - return NS_OK; -} - -/* - * These methods are factores: they let callers to create an instance of - * a radio group visitor without the class declaration and definition. - * - * TODO: - * Do we really need factories for radio visitors? Or at least, we should move - * that somewhere else because it feels like it's here only because the radio - * visitor classes are defined after most of nsHTMLInputElement code. - * See bug 586298 - */ -nsIRadioVisitor* -NS_SetRadioValueMissingState(nsIFormControl* aExcludeElement, - nsIDocument* aDocument, - bool aValidity, bool aNotify) -{ - return new nsRadioSetValueMissingState(aExcludeElement, aDocument, aValidity, - aNotify); -} - NS_IMETHODIMP_(PRBool) nsHTMLInputElement::IsSingleLineTextControl() const { return IsSingleLineTextControl(PR_FALSE); } NS_IMETHODIMP_(PRBool) nsHTMLInputElement::IsTextArea() const
--- a/content/html/content/src/nsHTMLInputElement.h +++ b/content/html/content/src/nsHTMLInputElement.h @@ -45,16 +45,17 @@ #include "nsITextControlElement.h" #include "nsIPhonetic.h" #include "nsIDOMNSEditableElement.h" #include "nsTextEditorState.h" #include "nsCOMPtr.h" #include "nsIConstraintValidation.h" #include "nsDOMFile.h" #include "nsHTMLFormElement.h" // for ShouldShowInvalidUI() +#include "nsIFile.h" // // Accessors for mBitField // #define BF_DISABLED_CHANGED 0 #define BF_VALUE_CHANGED 1 #define BF_CHECKED_CHANGED 2 #define BF_CHECKED 3 @@ -104,18 +105,16 @@ public: */ nsresult StoreLastUsedDirectory(nsIURI* aURI, nsILocalFile* aFile); private: // Directories are stored here during private browsing mode nsInterfaceHashtable<nsStringHashKey, nsILocalFile> mUploadLastDirStore; PRBool mInPrivateBrowsing; }; -class nsIRadioVisitor; - class nsHTMLInputElement : public nsGenericHTMLFormElement, public nsImageLoadingContent, public nsIDOMHTMLInputElement, public nsITextControlElement, public nsIPhonetic, public nsIDOMNSEditableElement, public nsIConstraintValidation {
new file mode 100644 --- /dev/null +++ b/content/html/content/src/nsRadioVisitor.cpp @@ -0,0 +1,96 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla code. + * + * The Initial Developer of the Original Code is Mozilla Foundation + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Mounir Lamouri <mounir.lamouri@mozilla.com> (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsRadioVisitor.h" +#include "nsAutoPtr.h" +#include "nsHTMLInputElement.h" +#include "nsIEventStateManager.h" +#include "nsIDocument.h" +#include "nsIConstraintValidation.h" + + +NS_IMPL_ISUPPORTS1(nsRadioVisitor, nsIRadioVisitor) + +PRBool +nsRadioSetCheckedChangedVisitor::Visit(nsIFormControl* aRadio) +{ + nsRefPtr<nsHTMLInputElement> radio = + static_cast<nsHTMLInputElement*>(aRadio); + NS_ASSERTION(radio, "Visit() passed a null button!"); + + radio->SetCheckedChangedInternal(mCheckedChanged); + return PR_TRUE; +} + +PRBool +nsRadioGetCheckedChangedVisitor::Visit(nsIFormControl* aRadio) +{ + if (aRadio == mExcludeElement) { + return PR_TRUE; + } + + nsRefPtr<nsHTMLInputElement> radio = + static_cast<nsHTMLInputElement*>(aRadio); + NS_ASSERTION(radio, "Visit() passed a null button!"); + + *mCheckedChanged = radio->GetCheckedChanged(); + return PR_FALSE; +} + +PRBool +nsRadioSetValueMissingState::Visit(nsIFormControl* aRadio) +{ + if (aRadio == mExcludeElement) { + return PR_TRUE; + } + + nsHTMLInputElement* input = static_cast<nsHTMLInputElement*>(aRadio); + + input->SetValidityState(nsIConstraintValidation::VALIDITY_STATE_VALUE_MISSING, + mValidity); + + nsIDocument* doc = input->GetCurrentDoc(); + if (mNotify && doc) { + doc->ContentStateChanged(input, NS_EVENT_STATE_VALID | + NS_EVENT_STATE_INVALID | + NS_EVENT_STATE_MOZ_UI_VALID | + NS_EVENT_STATE_MOZ_UI_INVALID); + } + + return PR_TRUE; +} +
new file mode 100644 --- /dev/null +++ b/content/html/content/src/nsRadioVisitor.h @@ -0,0 +1,128 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Mozilla code. + * + * The Initial Developer of the Original Code is Mozilla Foundation + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Mounir Lamouri <mounir.lamouri@mozilla.com> (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either of the GNU General Public License Version 2 or later (the "GPL"), + * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef _nsRadioVisitor_h__ +#define _nsRadioVisitor_h__ + +#include "nsIRadioVisitor.h" + +class nsIFormControl; +class nsIDocument; + + +/** + * nsRadioVisitor is the base class implementing nsIRadioVisitor and inherited + * by all radio visitors. + */ +class nsRadioVisitor : public nsIRadioVisitor +{ +public: + nsRadioVisitor() { } + virtual ~nsRadioVisitor() { } + + NS_DECL_ISUPPORTS + + virtual PRBool Visit(nsIFormControl* aRadio) = 0; +}; + +/** + * The following declarations are radio visitors inheriting from nsRadioVisitor. + */ + +/** + * nsRadioSetCheckedChangedVisitor is calling SetCheckedChanged with the given + * parameter to all radio elements in the group. + */ +class nsRadioSetCheckedChangedVisitor : public nsRadioVisitor +{ +public: + nsRadioSetCheckedChangedVisitor(bool aCheckedChanged) + : mCheckedChanged(aCheckedChanged) + { } + + virtual PRBool Visit(nsIFormControl* aRadio); + +protected: + bool mCheckedChanged; +}; + +/** + * nsRadioGetCheckedChangedVisitor is getting the current checked changed value. + * Getting it from one radio element is the group is enough given that all + * elements should have the same value. + */ +class nsRadioGetCheckedChangedVisitor : public nsRadioVisitor +{ +public: + nsRadioGetCheckedChangedVisitor(bool* aCheckedChanged, + nsIFormControl* aExcludeElement) + : mCheckedChanged(aCheckedChanged) + , mExcludeElement(aExcludeElement) + { } + + virtual PRBool Visit(nsIFormControl* aRadio); + +protected: + bool* mCheckedChanged; + nsIFormControl* mExcludeElement; +}; + +/** + * nsRadioSetValueMissingState is calling SetValueMissingState with the given + * parameter to all radio elements in the group. + * It is also calling ContentStatesChanged if needed. + */ +class nsRadioSetValueMissingState : public nsRadioVisitor +{ +public: + nsRadioSetValueMissingState(nsIFormControl* aExcludeElement, + bool aValidity, bool aNotify) + : mExcludeElement(aExcludeElement) + , mValidity(aValidity) + , mNotify(aNotify) + { } + + virtual PRBool Visit(nsIFormControl* aRadio); + +protected: + nsIFormControl* mExcludeElement; + bool mValidity; + bool mNotify; +}; + +#endif // _nsRadioVisitor_h__ +
--- a/content/html/content/src/nsTextEditorState.cpp +++ b/content/html/content/src/nsTextEditorState.cpp @@ -892,20 +892,18 @@ nsTextInputListener::EditAction() // no undo items; JS could change the value and we'd still need to save it) frame->SetValueChanged(PR_TRUE); if (!mSettingValue) { mTxtCtrlElement->OnValueChanged(PR_TRUE); } // Fire input event - nsCOMPtr<nsIEditor_MOZILLA_2_0_BRANCH> editor20 = do_QueryInterface(editor); - NS_ASSERTION(editor20, "Something is very wrong!"); PRBool trusted = PR_FALSE; - editor20->GetLastKeypressEventTrusted(&trusted); + editor->GetLastKeypressEventTrusted(&trusted); frame->FireOnInput(trusted); // mFrame may be dead after this, but we don't need to check for it, because // we are not uisng it in this function any more. return NS_OK; }
--- a/content/html/content/test/Makefile.in +++ b/content/html/content/test/Makefile.in @@ -255,12 +255,13 @@ include $(topsrcdir)/config/rules.mk test_bug619278.html \ test_bug622558.html \ test_bug622597.html \ test_bug636336.html \ test_bug630889.html \ test_bug610212.html \ test_bug633058.html \ test_bug641219.html \ + test_bug643051.html \ $(NULL) libs:: $(_TEST_FILES) $(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
new file mode 100644 --- /dev/null +++ b/content/html/content/test/test_bug643051.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=643051 +--> +<head> + <title>Test for Bug 643051</title> + <script type="application/javascript" src="/MochiKit/packed.js"></script> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=643051">Mozilla Bug 643051</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 643051 **/ +document.cookie = "a=; expires=Thu, 01-Jan-1970 00:00:01 GMT"; // clear cookie +document.cookie = "a2=; expires=Thu, 01-Jan-1970 00:00:01 GMT"; // clear cookie +document.cookie = "a3=; expires=Thu, 01-Jan-1970 00:00:01 GMT"; // clear cookie + +// single cookie, should work +document.cookie = "a=bar"; +is(document.cookie, "a=bar", "Can't read stored cookie!"); + +document.cookie = "a2=bar\na3=bar"; +is(document.cookie, "a=bar; a2=bar", "Wrong cookie value"); + +document.cookie = "a2=baz; a3=bar"; +is(document.cookie, "a=bar; a2=baz", "Wrong cookie value"); + +// clear cookies again to avoid affecting other tests +document.cookie = "a=; expires=Thu, 01-Jan-1970 00:00:01 GMT"; +document.cookie = "a2=; expires=Thu, 01-Jan-1970 00:00:01 GMT"; +document.cookie = "a3=; expires=Thu, 01-Jan-1970 00:00:01 GMT"; +</script> +</pre> +</body> +</html>
--- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -512,16 +512,22 @@ NS_IMETHODIMP nsDummyJavaPluginOwner::GetWindow(NPWindow *&aWindow) { aWindow = nsnull; return NS_OK; } NS_IMETHODIMP +nsDummyJavaPluginOwner::SetWindow() +{ + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP nsDummyJavaPluginOwner::GetMode(PRInt32 *aMode) { // This is wrong, but there's no better alternative. *aMode = NP_EMBED; return NS_ERROR_NOT_IMPLEMENTED; }
--- a/dom/plugins/PluginInstanceParent.cpp +++ b/dom/plugins/PluginInstanceParent.cpp @@ -592,26 +592,16 @@ PluginInstanceParent::AsyncSetWindow(NPW if (!SendAsyncSetWindow(gfxPlatform::GetPlatform()->ScreenReferenceSurface()->GetType(), window)) return NS_ERROR_FAILURE; return NS_OK; } nsresult -PluginInstanceParent::GetSurface(gfxASurface** aSurface) -{ - if (mFrontSurface) { - NS_ADDREF(*aSurface = mFrontSurface); - return NS_OK; - } - return NS_ERROR_NOT_AVAILABLE; -} - -nsresult PluginInstanceParent::GetImage(ImageContainer* aContainer, Image** aImage) { #ifdef XP_MACOSX if (!mFrontSurface && !mIOSurface) #else if (!mFrontSurface) #endif return NS_ERROR_NOT_AVAILABLE;
--- a/dom/plugins/PluginInstanceParent.h +++ b/dom/plugins/PluginInstanceParent.h @@ -275,17 +275,16 @@ public: virtual bool AnswerPluginFocusChange(const bool& gotFocus); #if defined(OS_MACOSX) void Invalidate(); #endif // definied(OS_MACOSX) nsresult AsyncSetWindow(NPWindow* window); - nsresult GetSurface(gfxASurface** aSurface); nsresult GetImage(mozilla::layers::ImageContainer* aContainer, mozilla::layers::Image** aImage); nsresult GetImageSize(nsIntSize* aSize); #ifdef XP_MACOSX nsresult IsRemoteDrawingCoreAnimation(PRBool *aDrawing); #endif nsresult SetBackgroundUnknown(); nsresult BeginUpdateBackground(const nsIntRect& aRect, gfxContext** aCtx);
--- a/dom/plugins/PluginLibrary.h +++ b/dom/plugins/PluginLibrary.h @@ -94,17 +94,16 @@ public: char* argv[], NPSavedData* saved, NPError* error) = 0; virtual nsresult NPP_ClearSiteData(const char* site, uint64_t flags, uint64_t maxAge) = 0; virtual nsresult NPP_GetSitesWithData(InfallibleTArray<nsCString>& aResult) = 0; virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window) = 0; - virtual nsresult GetSurface(NPP instance, gfxASurface** aSurface) = 0; virtual nsresult GetImage(NPP instance, ImageContainer* aContainer, Image** aImage) = 0; virtual nsresult GetImageSize(NPP instance, nsIntSize* aSize) = 0; virtual bool UseAsyncPainting() = 0; #if defined(XP_MACOSX) virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance, PRBool *aDrawing) = 0; #endif /** * The next three methods are the third leg in the trip to
--- a/dom/plugins/PluginModuleParent.cpp +++ b/dom/plugins/PluginModuleParent.cpp @@ -668,26 +668,16 @@ PluginModuleParent::AsyncSetWindow(NPP i PluginInstanceParent* i = InstCast(instance); if (!i) return NS_ERROR_FAILURE; return i->AsyncSetWindow(window); } nsresult -PluginModuleParent::GetSurface(NPP instance, gfxASurface** aSurface) -{ - PluginInstanceParent* i = InstCast(instance); - if (!i) - return NS_ERROR_FAILURE; - - return i->GetSurface(aSurface); -} - -nsresult PluginModuleParent::GetImage(NPP instance, mozilla::layers::ImageContainer* aContainer, mozilla::layers::Image** aImage) { PluginInstanceParent* i = InstCast(instance); return !i ? NS_ERROR_FAILURE : i->GetImage(aContainer, aImage); }
--- a/dom/plugins/PluginModuleParent.h +++ b/dom/plugins/PluginModuleParent.h @@ -226,17 +226,16 @@ private: NPPVariable variable, void *ret_value); static NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value); static void NPP_URLRedirectNotify(NPP instance, const char* url, int32_t status, void* notifyData); virtual bool HasRequiredFunctions(); virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window); - virtual nsresult GetSurface(NPP instance, gfxASurface** aSurface); virtual nsresult GetImage(NPP instance, mozilla::layers::ImageContainer* aContainer, mozilla::layers::Image** aImage); virtual nsresult GetImageSize(NPP instance, nsIntSize* aSize); NS_OVERRIDE virtual bool UseAsyncPainting() { return true; } NS_OVERRIDE virtual nsresult SetBackgroundUnknown(NPP instance); NS_OVERRIDE virtual nsresult BeginUpdateBackground(NPP instance, const nsIntRect& aRect,
--- a/editor/idl/nsIEditor.idl +++ b/editor/idl/nsIEditor.idl @@ -50,17 +50,17 @@ interface nsIDocumentStateListener; interface nsIOutputStream; interface nsITransactionManager; interface nsITransaction; interface nsIEditorObserver; interface nsIEditActionListener; interface nsIInlineSpellChecker; interface nsITransferable; -[scriptable, uuid(78b0bde0-ab69-428b-ab30-fcc09eead499)] +[scriptable, uuid(bd5d93f0-6451-11e0-ae3e-0800200c9a66)] interface nsIEditor : nsISupports { %{C++ typedef short EDirection; %} const short eNone = 0; const short eNext = 1; @@ -567,20 +567,16 @@ interface nsIEditor : nsISupports /** Dumps a text representation of the content tree to standard out */ void debugDumpContent() ; /* Run unit tests. Noop in optimized builds */ void debugUnitTests(out long outNumTests, out long outNumTestsFailed); /* checks if a node is read-only or not */ [notxpcom] boolean isModifiableNode(in nsIDOMNode aNode); -}; -[uuid(54c0bc08-6c0e-4967-bb0d-ec991d78a8b3)] -interface nsIEditor_MOZILLA_2_0_BRANCH : nsISupports -{ /** * Will be set to true if the last keypress event that the editor has handled * has been trusted. The value will only be valid when the edit action listeners * are being called, and will throw upon access at all other times. */ readonly attribute boolean lastKeypressEventTrusted; };
--- a/editor/libeditor/base/nsEditor.cpp +++ b/editor/libeditor/base/nsEditor.cpp @@ -200,17 +200,16 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN( NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mActionListeners) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mEditorObservers) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mDocStateListeners) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mEventTarget) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mEventListener) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsEditor) - NS_INTERFACE_MAP_ENTRY(nsIEditor_MOZILLA_2_0_BRANCH) NS_INTERFACE_MAP_ENTRY(nsIPhonetic) NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) NS_INTERFACE_MAP_ENTRY(nsIEditorIMESupport) NS_INTERFACE_MAP_ENTRY(nsIEditor) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIEditor) NS_INTERFACE_MAP_END NS_IMPL_CYCLE_COLLECTING_ADDREF(nsEditor)
--- a/editor/libeditor/base/nsEditor.h +++ b/editor/libeditor/base/nsEditor.h @@ -95,18 +95,17 @@ class nsIDOMNSEvent; /** implementation of an editor object. it will be the controller/focal point * for the main editor services. i.e. the GUIManager, publishing, transaction * manager, event interfaces. the idea for the event interfaces is to have them * delegate the actual commands to the editor independent of the XPFE implementation. */ class nsEditor : public nsIEditor, public nsIEditorIMESupport, public nsSupportsWeakReference, - public nsIPhonetic, - public nsIEditor_MOZILLA_2_0_BRANCH + public nsIPhonetic { public: enum IterDirection { kIterForward, kIterBackward }; @@ -152,19 +151,16 @@ public: /* ------------ nsIEditor methods -------------- */ NS_DECL_NSIEDITOR /* ------------ nsIEditorIMESupport methods -------------- */ NS_DECL_NSIEDITORIMESUPPORT // nsIPhonetic NS_DECL_NSIPHONETIC - // nsIEditor_MOZILLA_2_0_BRANCH - NS_DECL_NSIEDITOR_MOZILLA_2_0_BRANCH - public: NS_IMETHOD InsertTextImpl(const nsAString& aStringToInsert, nsCOMPtr<nsIDOMNode> *aInOutNode, PRInt32 *aInOutOffset, nsIDOMDocument *aDoc); nsresult InsertTextIntoTextNodeImpl(const nsAString& aStringToInsert,
--- a/embedding/android/GeckoAppShell.java +++ b/embedding/android/GeckoAppShell.java @@ -517,25 +517,27 @@ public class GeckoAppShell case NOTIFY_IME_FOCUSCHANGE: IMEStateUpdater.resetIME(); break; } } public static void notifyIMEEnabled(int state, String typeHint, - String actionHint) { + String actionHint, boolean landscapeFS) + { if (GeckoApp.surfaceView == null) return; /* When IME is 'disabled', IME processing is disabled. In addition, the IME UI is hidden */ GeckoApp.surfaceView.mIMEState = state; GeckoApp.surfaceView.mIMETypeHint = typeHint; GeckoApp.surfaceView.mIMEActionHint = actionHint; + GeckoApp.surfaceView.mIMELandscapeFS = landscapeFS; IMEStateUpdater.enableIME(); } public static void notifyIMEChange(String text, int start, int end, int newEnd) { if (GeckoApp.surfaceView == null || GeckoApp.surfaceView.inputConnection == null) return;
--- a/embedding/android/GeckoSurfaceView.java +++ b/embedding/android/GeckoSurfaceView.java @@ -378,17 +378,20 @@ class GeckoSurfaceView else if (mIMEActionHint.equalsIgnoreCase("next")) outAttrs.imeOptions = EditorInfo.IME_ACTION_NEXT; else if (mIMEActionHint.equalsIgnoreCase("search")) outAttrs.imeOptions = EditorInfo.IME_ACTION_SEARCH; else if (mIMEActionHint.equalsIgnoreCase("send")) outAttrs.imeOptions = EditorInfo.IME_ACTION_SEND; else if (mIMEActionHint != null && mIMEActionHint.length() != 0) outAttrs.actionLabel = mIMEActionHint; - + + if (mIMELandscapeFS == false) + outAttrs.imeOptions |= EditorInfo.IME_FLAG_NO_EXTRACT_UI; + inputConnection.reset(); return inputConnection; } public void setEditable(String contents) { mEditable.removeSpan(inputConnection); mEditable.replace(0, mEditable.length(), contents); @@ -619,16 +622,17 @@ class GeckoSurfaceView GeckoInputConnection inputConnection; KeyListener mKeyListener; Editable mEditable; Editable.Factory mEditableFactory; int mIMEState; String mIMETypeHint; String mIMEActionHint; + boolean mIMELandscapeFS; // Software rendering ByteBuffer mSoftwareBuffer; Bitmap mSoftwareBitmap; Geocoder mGeocoder; Address mLastGeoAddress;
--- a/gfx/cairo/cairo/src/cairo-d2d-surface.cpp +++ b/gfx/cairo/cairo/src/cairo-d2d-surface.cpp @@ -3155,54 +3155,80 @@ static cairo_int_status_t cairo_operator_t op, const cairo_pattern_t *source, const cairo_pattern_t *mask, cairo_clip_t *clip) { cairo_d2d_surface_t *d2dsurf = static_cast<cairo_d2d_surface_t*>(surface); cairo_rectangle_int_t extents; + cairo_clip_t *actual_clip = clip; + cairo_int_status_t status; status = (cairo_int_status_t)_cairo_surface_mask_extents (&d2dsurf->base, op, source, mask, clip, &extents); if (unlikely (status)) return status; - - D2D1_RECT_F rect = D2D1::RectF(0, - 0, - (FLOAT)d2dsurf->rt->GetPixelSize().width, - (FLOAT)d2dsurf->rt->GetPixelSize().height); - - rect.left = (FLOAT)extents.x; - rect.right = (FLOAT)(extents.x + extents.width); - rect.top = (FLOAT)extents.y; - rect.bottom = (FLOAT)(extents.y + extents.height); - bool isSolidAlphaMask = false; float solidAlphaValue = 1.0f; if (mask->type == CAIRO_PATTERN_TYPE_SOLID) { cairo_solid_pattern_t *solidPattern = (cairo_solid_pattern_t*)mask; if (solidPattern->content = CAIRO_CONTENT_ALPHA) { isSolidAlphaMask = true; solidAlphaValue = solidPattern->color.alpha; } } + cairo_box_t box; + _cairo_box_from_rectangle(&box, &extents); + + if (clip) { + // We do some work here to try and avoid pushing and popping clips for rectangular areas, + // if we do this fill rects will occur without rectangular clips being pushed and popped. + // This is faster for non-axis aligned clips in general and allows more efficient batching + // of the pop-clip calls. + int num_boxes = 1; + cairo_box_t box_stack; + cairo_box_t *boxes; + boxes = &box_stack; + + // This function assumes atleast a single box resides at 'boxes' and the + // amount of boxes that reside there are passed in under num_boxes. + status = _cairo_clip_get_boxes(clip, &boxes, &num_boxes); + + if (!status && num_boxes == 1) { + box.p1.x = MAX(box.p1.x, boxes->p1.x); + box.p2.x = MIN(box.p2.x, boxes->p2.x); + box.p1.y = MAX(box.p1.y, boxes->p1.y); + box.p2.y = MIN(box.p2.y, boxes->p2.y); + + if (clip->path != d2dsurf->clip.path) { + // Only reset the clip if we don't have the right clip set. Otherwise + // just leave the clip as it is. If we have the right clip set we + // should not do a needless pop of the clip. + actual_clip = NULL; + } + } + + if (boxes != &box_stack) { + // If the function changed the boxes pointer, we need to free it. + free(boxes); + } + } + if (isSolidAlphaMask) { if (source->type == CAIRO_PATTERN_TYPE_SURFACE) { const cairo_surface_pattern_t *surf_pattern = reinterpret_cast<const cairo_surface_pattern_t*>(source); - cairo_box_t box; - _cairo_box_from_rectangle(&box, &extents); cairo_int_status_t rv = _cairo_d2d_try_fastblit(d2dsurf, surf_pattern->surface, &box, &source->matrix, clip, op, source->filter, solidAlphaValue); @@ -3223,23 +3249,28 @@ static cairo_int_status_t #endif target_rt = _cairo_d2d_get_temp_rt(d2dsurf, clip); if (!target_rt) { return CAIRO_INT_STATUS_UNSUPPORTED; } #ifndef ALWAYS_MANUAL_COMPOSITE } else { _begin_draw_state(d2dsurf); - status = (cairo_int_status_t)_cairo_d2d_set_clip (d2dsurf, clip); - + + status = (cairo_int_status_t)_cairo_d2d_set_clip (d2dsurf, actual_clip); if (unlikely(status)) return status; } #endif + D2D1_RECT_F rect = D2D1::RectF(_cairo_fixed_to_float(box.p1.x), + _cairo_fixed_to_float(box.p1.y), + _cairo_fixed_to_float(box.p2.x), + _cairo_fixed_to_float(box.p2.y)); + if (isSolidAlphaMask) { brush->SetOpacity(solidAlphaValue); target_rt->FillRectangle(rect, brush); brush->SetOpacity(1.0); if (target_rt.get() != d2dsurf->rt.get()) { return _cairo_d2d_blend_temp_surface(d2dsurf, op, target_rt, clip);
--- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -758,16 +758,22 @@ public: /** * Dynamic downcast to a Thebes layer. Returns null if this is not * a ThebesLayer. */ virtual ThebesLayer* AsThebesLayer() { return nsnull; } /** + * Dynamic cast to a ContainerLayer. Returns null if this is not + * a ContainerLayer. + */ + virtual ContainerLayer* AsContainerLayer() { return nsnull; } + + /** * Dynamic cast to a ShadowLayer. Return null if this is not a * ShadowLayer. Can be used anytime. */ virtual ShadowLayer* AsShadowLayer() { return nsnull; } // These getters can be used anytime. They return the effective // values that should be used when drawing this layer to screen, // accounting for this layer possibly being a shadow. @@ -1024,16 +1030,18 @@ public: */ void SetFrameMetrics(const FrameMetrics& aFrameMetrics) { mFrameMetrics = aFrameMetrics; } // These getters can be used anytime. + virtual ContainerLayer* AsContainerLayer() { return this; } + virtual Layer* GetFirstChild() { return mFirstChild; } virtual Layer* GetLastChild() { return mLastChild; } const FrameMetrics& GetFrameMetrics() { return mFrameMetrics; } MOZ_LAYER_DECL_NAME("ContainerLayer", TYPE_CONTAINER) /** * ContainerLayer backends need to override ComputeEffectiveTransforms
--- a/layout/base/FrameLayerBuilder.h +++ b/layout/base/FrameLayerBuilder.h @@ -54,17 +54,19 @@ class nsRootPresContext; namespace mozilla { enum LayerState { LAYER_NONE, LAYER_INACTIVE, LAYER_ACTIVE, // Force an active layer even if it causes incorrect rendering, e.g. // when the layer has rounded rect clips. - LAYER_ACTIVE_FORCE + LAYER_ACTIVE_FORCE, + // Special layer that is metadata only. + LAYER_ACTIVE_EMPTY }; /** * The FrameLayerBuilder belongs to an nsDisplayListBuilder and is * responsible for converting display lists into layer trees. * * The most important API in this class is BuildContainerLayerFor. This * method takes a display list as input and constructs a ContainerLayer
--- a/layout/base/nsDisplayItemTypes.h +++ b/layout/base/nsDisplayItemTypes.h @@ -79,16 +79,17 @@ enum Type { TYPE_PAGE_SEQUENCE, TYPE_PLUGIN, TYPE_PLUGIN_READBACK, TYPE_PRINT_PREVIEW_BACKGROUND, TYPE_PRINT_PLUGIN, TYPE_REMOTE, TYPE_REMOTE_SHADOW, TYPE_SCROLL_LAYER, + TYPE_SCROLL_INFO_LAYER, TYPE_SELECTION_OVERLAY, TYPE_SOLID_COLOR, TYPE_TABLE_CELL_BACKGROUND, TYPE_TABLE_CELL_SELECTION, TYPE_TABLE_ROW_BACKGROUND, TYPE_TABLE_ROW_GROUP_BACKGROUND, TYPE_TABLE_BORDER_BACKGROUND, TYPE_TEXT,
--- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -1831,16 +1831,35 @@ nsDisplayScrollLayer::ComputeVisibility( #ifdef NS_BUILD_REFCNT_LOGGING nsDisplayScrollLayer::~nsDisplayScrollLayer() { MOZ_COUNT_DTOR(nsDisplayScrollLayer); } #endif +nsDisplayScrollInfoLayer::nsDisplayScrollInfoLayer( + nsDisplayListBuilder* aBuilder, + nsDisplayList* aList, + nsIFrame* aForFrame, + nsIFrame* aViewportFrame) + : nsDisplayScrollLayer(aBuilder, aList, aForFrame, aViewportFrame) +{ +#ifdef NS_BUILD_REFCNT_LOGGING + MOZ_COUNT_CTOR(nsDisplayScrollInfoLayer); +#endif +} + +#ifdef NS_BUILD_REFCNT_LOGGING +nsDisplayScrollInfoLayer::~nsDisplayScrollInfoLayer() +{ + MOZ_COUNT_DTOR(nsDisplayScrollInfoLayer); +} +#endif + nsDisplayClip::nsDisplayClip(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame, nsDisplayItem* aItem, const nsRect& aRect) : nsDisplayWrapList(aBuilder, aFrame, aItem) { MOZ_COUNT_CTOR(nsDisplayClip); mClip = SnapBounds(aBuilder->IsSnappingEnabled() && !aBuilder->IsInTransform(), aBuilder->CurrentPresContext(), aRect); }
--- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -1832,16 +1832,40 @@ public: // This causes incorrect rendering for rounded clips! return mozilla::LAYER_ACTIVE_FORCE; } private: nsIFrame* mViewportFrame; }; /** + * Like nsDisplayScrollLayer, but only has metadata on the scroll frame. This + * creates a layer that has no Thebes child layer, but still allows the + * compositor process to know of the scroll frame's existence. + */ +class nsDisplayScrollInfoLayer : public nsDisplayScrollLayer +{ +public: + nsDisplayScrollInfoLayer(nsDisplayListBuilder* aBuilder, nsDisplayList* aList, + nsIFrame* aForFrame, nsIFrame* aViewportFrame); + NS_DISPLAY_DECL_NAME("ScrollInfoLayer", TYPE_SCROLL_INFO_LAYER) + +#ifdef NS_BUILD_REFCNT_LOGGING + virtual ~nsDisplayScrollInfoLayer(); +#endif + + virtual LayerState GetLayerState(nsDisplayListBuilder* aBuilder, + LayerManager* aManager) + { + return mozilla::LAYER_ACTIVE_EMPTY; + } + +}; + +/** * nsDisplayClip can clip a list of items, but we take a single item * initially and then later merge other items into it when we merge * adjacent matching nsDisplayClips */ class nsDisplayClip : public nsDisplayWrapList { public: /** * @param aFrame the frame that should be considered the underlying
--- a/layout/build/nsLayoutCID.h +++ b/layout/build/nsLayoutCID.h @@ -241,22 +241,16 @@ // {762C4AE7-B923-422F-B97E-B9BFC1EF7BF0} #define NS_ICONTENTUTILS_CID \ { 0x762C4AE7, 0xB923, 0x422F, { 0xB9, 0x7E, 0xB9, 0xBF, 0xC1, 0xEF, 0x7B, 0xF0 } } // {1802442d-a59b-43b8-b8fd-070da5549593} #define NS_ICONTENTUTILS2_CID \ { 0x1802442d, 0xa59b, 0x43b8, { 0xb8, 0xfd, 0x07, 0x0d, 0xa5, 0x54, 0x95, 0x93 } } -#ifndef MOZ_ENABLE_LIBXUL -// {4c14b440-307f-11e0-91fa-0800200c9a66} -#define NS_ICONTENTUTILS_MOZILLA_2_0_BRANCH_CID \ -{ 0x4c14b440, 0x307f, 0x11e9, { 0x91, 0xfa, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66 } } -#endif - // {1A26A7B7-D06E-4F45-8B45-D7AD60F7A9AB} #define INDEXEDDB_MANAGER_CID \ { 0x1a26a7b7, 0xd06e, 0x4f45, { 0x8b, 0x45, 0xd7, 0xad, 0x60, 0xf7, 0xa9, 0xab } } #ifdef MOZ_MEDIA #define NS_HTMLAUDIOELEMENT_CID \ { /* 1d40026b-4c44-4f6f-b158-26bb5e9c65e9 */ \ 0x1d40026b, 0x4c44, 0x4f6f, \
--- a/layout/build/nsLayoutModule.cpp +++ b/layout/build/nsLayoutModule.cpp @@ -577,19 +577,16 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsSyncLoa MAKE_CTOR(CreatePluginDocument, nsIDocument, NS_NewPluginDocument) #ifdef MOZ_MEDIA MAKE_CTOR(CreateVideoDocument, nsIDocument, NS_NewVideoDocument) #endif MAKE_CTOR(CreateFocusManager, nsIFocusManager, NS_NewFocusManager) NS_GENERIC_FACTORY_CONSTRUCTOR(nsIContentUtils) NS_GENERIC_FACTORY_CONSTRUCTOR(nsIContentUtils2) -#ifndef MOZ_ENABLE_LIBXUL -NS_GENERIC_FACTORY_CONSTRUCTOR(nsIContentUtils_MOZILLA_2_0_BRANCH) -#endif MAKE_CTOR(CreateCanvasRenderingContext2D, nsIDOMCanvasRenderingContext2D, NS_NewCanvasRenderingContext2D) MAKE_CTOR(CreateCanvasRenderingContextWebGL, nsIDOMWebGLRenderingContext, NS_NewCanvasRenderingContextWebGL) NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsStyleSheetService, Init) NS_GENERIC_FACTORY_CONSTRUCTOR(nsJSURI) @@ -868,19 +865,16 @@ NS_DEFINE_NAMED_CID(NS_HTMLEDITOR_CID); NS_DEFINE_NAMED_CID(NS_EDITORCONTROLLER_CID); NS_DEFINE_NAMED_CID(NS_EDITORCOMMANDTABLE_CID); NS_DEFINE_NAMED_CID(NS_TEXTSERVICESDOCUMENT_CID); NS_DEFINE_NAMED_CID(NS_GEOLOCATION_SERVICE_CID); NS_DEFINE_NAMED_CID(NS_GEOLOCATION_CID); NS_DEFINE_NAMED_CID(NS_FOCUSMANAGER_CID); NS_DEFINE_NAMED_CID(NS_ICONTENTUTILS_CID); NS_DEFINE_NAMED_CID(NS_ICONTENTUTILS2_CID); -#ifndef MOZ_ENABLE_LIBXUL -NS_DEFINE_NAMED_CID(NS_ICONTENTUTILS_MOZILLA_2_0_BRANCH_CID); -#endif NS_DEFINE_NAMED_CID(CSPSERVICE_CID); NS_DEFINE_NAMED_CID(NS_EVENTLISTENERSERVICE_CID); NS_DEFINE_NAMED_CID(NS_GLOBALMESSAGEMANAGER_CID); NS_DEFINE_NAMED_CID(NS_PARENTPROCESSMESSAGEMANAGER_CID); NS_DEFINE_NAMED_CID(NS_CHILDPROCESSMESSAGEMANAGER_CID); NS_DEFINE_NAMED_CID(NSCHANNELPOLICY_CID); NS_DEFINE_NAMED_CID(NS_SCRIPTSECURITYMANAGER_CID); NS_DEFINE_NAMED_CID(NS_PRINCIPAL_CID); @@ -1022,19 +1016,16 @@ static const mozilla::Module::CIDEntry k { &kNS_EDITORCONTROLLER_CID, false, NULL, nsEditorControllerConstructor }, { &kNS_EDITORCOMMANDTABLE_CID, false, NULL, nsEditorCommandTableConstructor }, { &kNS_TEXTSERVICESDOCUMENT_CID, false, NULL, nsTextServicesDocumentConstructor }, { &kNS_GEOLOCATION_SERVICE_CID, false, NULL, nsGeolocationServiceConstructor }, { &kNS_GEOLOCATION_CID, false, NULL, nsGeolocationConstructor }, { &kNS_FOCUSMANAGER_CID, false, NULL, CreateFocusManager }, { &kNS_ICONTENTUTILS_CID, false, NULL, nsIContentUtilsConstructor }, { &kNS_ICONTENTUTILS2_CID, false, NULL, nsIContentUtils2Constructor }, -#ifndef MOZ_ENABLE_LIBXUL - { &kNS_ICONTENTUTILS_MOZILLA_2_0_BRANCH_CID, false, NULL, nsIContentUtils_MOZILLA_2_0_BRANCHConstructor }, -#endif { &kCSPSERVICE_CID, false, NULL, CSPServiceConstructor }, { &kNS_EVENTLISTENERSERVICE_CID, false, NULL, CreateEventListenerService }, { &kNS_GLOBALMESSAGEMANAGER_CID, false, NULL, CreateGlobalMessageManager }, { &kNS_PARENTPROCESSMESSAGEMANAGER_CID, false, NULL, CreateParentMessageManager }, { &kNS_CHILDPROCESSMESSAGEMANAGER_CID, false, NULL, CreateChildMessageManager }, { &kNSCHANNELPOLICY_CID, false, NULL, nsChannelPolicyConstructor }, { &kNS_SCRIPTSECURITYMANAGER_CID, false, NULL, Construct_nsIScriptSecurityManager }, { &kNS_PRINCIPAL_CID, false, NULL, nsPrincipalConstructor }, @@ -1170,19 +1161,16 @@ static const mozilla::Module::ContractID { "@mozilla.org/editor/editorcontroller;1", &kNS_EDITORCONTROLLER_CID }, { "", &kNS_EDITORCOMMANDTABLE_CID }, { "@mozilla.org/textservices/textservicesdocument;1", &kNS_TEXTSERVICESDOCUMENT_CID }, { "@mozilla.org/geolocation/service;1", &kNS_GEOLOCATION_SERVICE_CID }, { "@mozilla.org/geolocation;1", &kNS_GEOLOCATION_CID }, { "@mozilla.org/focus-manager;1", &kNS_FOCUSMANAGER_CID }, { "@mozilla.org/content/contentutils;1", &kNS_ICONTENTUTILS_CID }, { "@mozilla.org/content/contentutils2;1", &kNS_ICONTENTUTILS2_CID }, -#ifndef MOZ_ENABLE_LIBXUL - { "@mozilla.org/content/contentutils-moz2.0;1", &kNS_ICONTENTUTILS_MOZILLA_2_0_BRANCH_CID }, -#endif { CSPSERVICE_CONTRACTID, &kCSPSERVICE_CID }, { NS_EVENTLISTENERSERVICE_CONTRACTID, &kNS_EVENTLISTENERSERVICE_CID }, { NS_GLOBALMESSAGEMANAGER_CONTRACTID, &kNS_GLOBALMESSAGEMANAGER_CID }, { NS_PARENTPROCESSMESSAGEMANAGER_CONTRACTID, &kNS_PARENTPROCESSMESSAGEMANAGER_CID }, { NS_CHILDPROCESSMESSAGEMANAGER_CONTRACTID, &kNS_CHILDPROCESSMESSAGEMANAGER_CID }, { NSCHANNELPOLICY_CONTRACTID, &kNSCHANNELPOLICY_CID }, { NS_SCRIPTSECURITYMANAGER_CONTRACTID, &kNS_SCRIPTSECURITYMANAGER_CID }, { NS_GLOBAL_CHANNELEVENTSINK_CONTRACTID, &kNS_SCRIPTSECURITYMANAGER_CID },
--- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -1956,55 +1956,68 @@ nsGfxScrollFrameInner::BuildDisplayList( // Not all our descendants will be clipped by overflow clipping, but all // the ones that aren't clipped will be out of flow frames that have already // had dirty rects saved for them by their parent frames calling // MarkOutOfFlowChildrenForDisplayList, so it's safe to restrict our // dirty rect here. dirtyRect.IntersectRect(aDirtyRect, mScrollPort); // Override the dirty rectangle if the displayport has been set. - nsLayoutUtils::GetDisplayPort(mOuter->GetContent(), &dirtyRect); + PRBool usingDisplayport = + nsLayoutUtils::GetDisplayPort(mOuter->GetContent(), &dirtyRect); nsDisplayListCollection set; nsPresContext* presContext = mOuter->PresContext(); // Since making new layers is expensive, only use nsDisplayScrollLayer // if the area is scrollable. // // Scroll frames can be generated with a scroll range that is 0, 0. // Furthermore, it is not worth the memory tradeoff to allow asynchronous // scrolling of small scroll frames. We use an arbitrary minimum scroll // range of 20 pixels to eliminate many gfx scroll frames from becoming a // layer. // - PRInt32 appUnitsPerDevPixel = presContext->AppUnitsPerDevPixel(); nsRect scrollRange = GetScrollRange(); ScrollbarStyles styles = GetScrollbarStylesFromFrame(); mShouldBuildLayer = (XRE_GetProcessType() == GeckoProcessType_Content && (styles.mHorizontal != NS_STYLE_OVERFLOW_HIDDEN || styles.mVertical != NS_STYLE_OVERFLOW_HIDDEN) && - (scrollRange.width >= NSIntPixelsToAppUnits(20, appUnitsPerDevPixel) || - scrollRange.height >= NSIntPixelsToAppUnits(20, appUnitsPerDevPixel))) && - (!mIsRoot || !mOuter->PresContext()->IsRootContentDocument()); + (!mIsRoot || !mOuter->PresContext()->IsRootContentDocument())); if (ShouldBuildLayer()) { - // Note that using StackingContext breaks z order, so the resulting - // rendering can be incorrect for weird edge cases! - nsDisplayList list; - rv = mScrolledFrame->BuildDisplayListForStackingContext( - aBuilder, dirtyRect + mOuter->GetOffsetTo(mScrolledFrame), &list); - - nsDisplayScrollLayer* layerItem = new (aBuilder) nsDisplayScrollLayer( - aBuilder, &list, mScrolledFrame, mOuter); - set.Content()->AppendNewToTop(layerItem); - } else - { + if (usingDisplayport) { + // Once a displayport is set, assume that scrolling needs to be fast + // so create a layer with all the content inside. The compositor + // process will be able to scroll the content asynchronously. + // + // Note that using StackingContext breaks z order, so the resulting + // rendering can be incorrect for weird edge cases! + + rv = mScrolledFrame->BuildDisplayListForStackingContext( + aBuilder, dirtyRect + mOuter->GetOffsetTo(mScrolledFrame), &list); + + nsDisplayScrollLayer* layerItem = new (aBuilder) nsDisplayScrollLayer( + aBuilder, &list, mScrolledFrame, mOuter); + set.Content()->AppendNewToTop(layerItem); + } else { + // If there is no displayport set, there is no reason here to force a + // layer that needs a memory-expensive allocation, but the compositor + // process would still like to know that it exists. + + nsDisplayScrollLayer* layerItem = new (aBuilder) nsDisplayScrollInfoLayer( + aBuilder, &list, mScrolledFrame, mOuter); + set.Content()->AppendNewToTop(layerItem); + + rv = mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, dirtyRect, set); + } + } else { rv = mOuter->BuildDisplayListForChild(aBuilder, mScrolledFrame, dirtyRect, set); } NS_ENSURE_SUCCESS(rv, rv); nsRect clip; clip = mScrollPort + aBuilder->ToReferenceFrame(mOuter); nscoord radii[8];
--- a/layout/generic/nsObjectFrame.cpp +++ b/layout/generic/nsObjectFrame.cpp @@ -265,33 +265,31 @@ public: nsEventStatus ProcessEvent(const nsGUIEvent& anEvent) { return nsEventStatus_eConsumeNoDefault; } }; class nsPluginInstanceOwner : public nsIPluginInstanceOwner, - public nsIPluginInstanceOwner_MOZILLA_2_0_BRANCH, public nsIPluginTagInfo, public nsIDOMMouseListener, public nsIDOMMouseMotionListener, public nsIDOMKeyListener, public nsIDOMFocusListener, public nsIScrollPositionListener { public: nsPluginInstanceOwner(); virtual ~nsPluginInstanceOwner(); NS_DECL_ISUPPORTS //nsIPluginInstanceOwner interface NS_DECL_NSIPLUGININSTANCEOWNER - NS_DECL_NSIPLUGININSTANCEOWNER_MOZILLA_2_0_BRANCH NS_IMETHOD GetURL(const char *aURL, const char *aTarget, nsIInputStream *aPostStream, void *aHeadersData, PRUint32 aHeadersDataLen); NS_IMETHOD ShowStatus(const PRUnichar *aStatusMsg); NPError ShowNativeContextMenu(NPMenu* menu, void* event); @@ -495,32 +493,21 @@ public: mPluginWindow->type == NPWindowTypeDrawable)); } private: // return FALSE if LayerSurface dirty (newly created and don't have valid plugin content yet) PRBool IsUpToDate() { - nsCOMPtr<nsIPluginInstance_MOZILLA_2_0_BRANCH> inst = do_QueryInterface(mInstance); - if (!inst) - return PR_FALSE; - nsIntSize size; - return NS_SUCCEEDED(inst->GetImageSize(&size)) && + return NS_SUCCEEDED(mInstance->GetImageSize(&size)) && size == nsIntSize(mPluginWindow->width, mPluginWindow->height); } - already_AddRefed<nsIPluginInstance_MOZILLA_2_0_BRANCH> - GetInstance() - { - nsCOMPtr<nsIPluginInstance_MOZILLA_2_0_BRANCH> inst = do_QueryInterface(mInstance); - return inst.forget(); - } - void FixUpURLS(const nsString &name, nsAString &value); nsPluginNativeWindow *mPluginWindow; nsCOMPtr<nsIPluginInstance> mInstance; nsObjectFrame *mObjectFrame; // owns nsPluginInstanceOwner nsCOMPtr<nsIContent> mContent; nsCString mDocumentBase; char *mTagText; @@ -1999,22 +1986,21 @@ nsObjectFrame::UpdateImageLayer(ImageCon #endif mInstanceOwner->SetCurrentImage(aContainer); } PRBool nsPluginInstanceOwner::SetCurrentImage(ImageContainer* aContainer) { - nsCOMPtr<nsIPluginInstance_MOZILLA_2_0_BRANCH> inst = do_QueryInterface(mInstance); - if (inst) { + if (mInstance) { nsRefPtr<Image> image; - // Every call to nsIPluginInstance_MOZILLA_2_0_BRANCH::GetImage() creates + // Every call to nsIPluginInstance::GetImage() creates // a new image. See nsIPluginInstance.idl. - inst->GetImage(aContainer, getter_AddRefs(image)); + mInstance->GetImage(aContainer, getter_AddRefs(image)); if (image) { #ifdef XP_MACOSX if (image->GetFormat() == Image::MAC_IO_SURFACE && mObjectFrame) { MacIOSurfaceImage *oglImage = static_cast<MacIOSurfaceImage*>(image.get()); NS_ADDREF_THIS(); oglImage->SetUpdateCallback(&DrawPlugin, this); oglImage->SetDestroyCallback(&OnDestroyImage); } @@ -2025,53 +2011,49 @@ nsPluginInstanceOwner::SetCurrentImage(I } aContainer->SetCurrentImage(nsnull); return PR_FALSE; } void nsPluginInstanceOwner::SetBackgroundUnknown() { - nsCOMPtr<nsIPluginInstance_MOZILLA_2_0_BRANCH> inst = GetInstance(); - if (inst) { - inst->SetBackgroundUnknown(); + if (mInstance) { + mInstance->SetBackgroundUnknown(); } } already_AddRefed<gfxContext> nsPluginInstanceOwner::BeginUpdateBackground(const nsIntRect& aRect) { nsIntRect rect = aRect; - nsCOMPtr<nsIPluginInstance_MOZILLA_2_0_BRANCH> inst = GetInstance(); nsRefPtr<gfxContext> ctx; - if (inst && - NS_SUCCEEDED(inst->BeginUpdateBackground(&rect, getter_AddRefs(ctx)))) { + if (mInstance && + NS_SUCCEEDED(mInstance->BeginUpdateBackground(&rect, getter_AddRefs(ctx)))) { return ctx.forget(); } return nsnull; } void nsPluginInstanceOwner::EndUpdateBackground(gfxContext* aContext, const nsIntRect& aRect) { nsIntRect rect = aRect; - nsCOMPtr<nsIPluginInstance_MOZILLA_2_0_BRANCH> inst = GetInstance(); - if (inst) { - inst->EndUpdateBackground(aContext, &rect); + if (mInstance) { + mInstance->EndUpdateBackground(aContext, &rect); } } nsIntSize nsPluginInstanceOwner::GetCurrentImageSize() { - nsCOMPtr<nsIPluginInstance_MOZILLA_2_0_BRANCH> inst = GetInstance(); nsIntSize size(0,0); - if (inst) { - inst->GetImageSize(&size); + if (mInstance) { + mInstance->GetImageSize(&size); } return size; } LayerState nsObjectFrame::GetLayerState(nsDisplayListBuilder* aBuilder, LayerManager* aManager) { @@ -3303,17 +3285,16 @@ nsPluginInstanceOwner::~nsPluginInstance * nsISupports Implementation */ NS_IMPL_ADDREF(nsPluginInstanceOwner) NS_IMPL_RELEASE(nsPluginInstanceOwner) NS_INTERFACE_MAP_BEGIN(nsPluginInstanceOwner) NS_INTERFACE_MAP_ENTRY(nsIPluginInstanceOwner) - NS_INTERFACE_MAP_ENTRY(nsIPluginInstanceOwner_MOZILLA_2_0_BRANCH) NS_INTERFACE_MAP_ENTRY(nsIPluginTagInfo) NS_INTERFACE_MAP_ENTRY(nsIDOMMouseListener) NS_INTERFACE_MAP_ENTRY(nsIDOMMouseMotionListener) NS_INTERFACE_MAP_ENTRY(nsIDOMKeyListener) NS_INTERFACE_MAP_ENTRY(nsIDOMFocusListener) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIDOMEventListener, nsIDOMMouseListener) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPluginInstanceOwner) NS_INTERFACE_MAP_END @@ -4294,22 +4275,21 @@ NPDrawingModel nsPluginInstanceOwner::Ge return drawingModel; mInstance->GetDrawingModel((PRInt32*)&drawingModel); return drawingModel; } PRBool nsPluginInstanceOwner::IsRemoteDrawingCoreAnimation() { - nsCOMPtr<nsIPluginInstance_MOZILLA_2_0_BRANCH> inst = do_QueryInterface(mInstance); - if (!inst) + if (mInstance) return PR_FALSE; PRBool coreAnimation; - if (!NS_SUCCEEDED(inst->IsRemoteDrawingCoreAnimation(&coreAnimation))) + if (!NS_SUCCEEDED(mInstance->IsRemoteDrawingCoreAnimation(&coreAnimation))) return PR_FALSE; return coreAnimation; } NPEventModel nsPluginInstanceOwner::GetEventModel() { return mEventModel;
--- a/layout/ipc/RenderFrameParent.cpp +++ b/layout/ipc/RenderFrameParent.cpp @@ -134,23 +134,18 @@ FindViewForId(const ViewMap& aMap, ViewI { ViewMap::const_iterator iter = aMap.find(aId); return iter != aMap.end() ? iter->second : NULL; } static const FrameMetrics* GetFrameMetrics(Layer* aLayer) { - // Children are not container layers, so they don't have frame metrics. Give - // them a blank metric. - if (!aLayer->GetFirstChild()) - return NULL; - - ContainerLayer* container = static_cast<ContainerLayer*>(aLayer); - return &container->GetFrameMetrics(); + ContainerLayer* container = aLayer->AsContainerLayer(); + return container ? &container->GetFrameMetrics() : NULL; } static nsIntPoint GetRootFrameOffset(nsIFrame* aContainerFrame, nsDisplayListBuilder* aBuilder) { nscoord auPerDevPixel = aContainerFrame->PresContext()->AppUnitsPerDevPixel(); // Offset to the content rect in case we have borders or padding @@ -341,20 +336,19 @@ IsTempLayerManager(LayerManager* aManage // aXScale and aYScale are used to calculate any values that need to be in // chrome-document CSS pixels and aren't part of the rendering loop, such as // the initial scroll offset for a new view. static void BuildViewMap(ViewMap& oldContentViews, ViewMap& newContentViews, nsFrameLoader* aFrameLoader, Layer* aLayer, float aXScale = 1, float aYScale = 1) { - if (!aLayer->GetFirstChild()) + ContainerLayer* container = aLayer->AsContainerLayer(); + if (!container) return; - - ContainerLayer* container = static_cast<ContainerLayer*>(aLayer); const FrameMetrics metrics = container->GetFrameMetrics(); const ViewID scrollId = metrics.mScrollId; if (metrics.IsScrollable()) { nscoord auPerDevPixel = aFrameLoader->GetPrimaryFrameOfOwningContent() ->PresContext()->AppUnitsPerDevPixel(); nsContentView* view = FindViewForId(oldContentViews, scrollId); if (view) {
--- a/mobile/app/mobile.js +++ b/mobile/app/mobile.js @@ -390,19 +390,19 @@ pref("javascript.options.methodjit.chrom pref("dom.max_chrome_script_run_time", 0); // disable slow script dialog for chrome pref("dom.max_script_run_time", 20); // JS error console pref("devtools.errorconsole.enabled", false); // kinetic tweakables -pref("browser.ui.kinetic.updateInterval", 30); -pref("browser.ui.kinetic.decelerationRate", 20); -pref("browser.ui.kinetic.speedSensitivity", 80); +pref("browser.ui.kinetic.updateInterval", 16); +pref("browser.ui.kinetic.exponentialC", 1400); +pref("browser.ui.kinetic.polynomialC", 100); pref("browser.ui.kinetic.swipeLength", 160); // zooming pref("browser.ui.zoom.pageFitGranularity", 9); // don't zoom to fit by less than 1/9 (11%) pref("browser.ui.zoom.animationDuration", 200); // ms duration of double-tap zoom animation pref("browser.ui.zoom.reflow", false); // Change text wrapping on double-tap pref("browser.ui.zoom.reflow.fontSize", 720); @@ -580,13 +580,19 @@ pref("notification.feature.enabled", tru // prevent tooltips from showing up pref("browser.chrome.toolbar_tips", false); pref("indexedDB.feature.enabled", false); // prevent video elements from preloading too much data pref("media.preload.default", 1); // default to preload none pref("media.preload.auto", 2); // preload metadata if preload=auto +// 0: don't show fullscreen keyboard +// 1: always show fullscreen keyboard +// -1: show fullscreen keyboard based on threshold pref +pref("widget.ime.android.landscape_fullscreen", 0); +pref("widget.ime.android.fullscreen_threshold", 300); // in hundreths of inches + // optimize images memory usage pref("image.mem.decodeondraw", true); pref("content.image.allow_locking", false); pref("image.mem.min_discard_timeout_ms", 20000);
--- a/mobile/chrome/content/BookmarkHelper.js +++ b/mobile/chrome/content/BookmarkHelper.js @@ -11,17 +11,17 @@ var BookmarkHelper = { if (!aURI) aURI = getBrowser().currentURI; let itemId = PlacesUtils.getMostRecentBookmarkForURI(aURI); if (itemId == -1) return; // When opening the bookmark helper dialog be sure there is not others - // popup opened like the bookmakr popup + // popup opened like the bookmark popup BookmarkPopup.hide(); let title = PlacesUtils.bookmarks.getItemTitle(itemId); let tags = PlacesUtils.tagging.getTagsForURI(aURI, {}); const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; this._editor = document.createElementNS(XULNS, "placeitem"); this._editor.setAttribute("id", "bookmark-item");
--- a/mobile/chrome/content/MenuListHelperUI.js +++ b/mobile/chrome/content/MenuListHelperUI.js @@ -40,17 +40,17 @@ var MenuListHelperUI = { let item = document.createElement("richlistitem"); if (child.disabled) item.setAttribute("disabled", "true"); if (child.hidden) item.setAttribute("hidden", "true"); // Add selected as a class name instead of an attribute to not being overidden // by the richlistbox behavior (it sets the "current" and "selected" attribute - item.setAttribute("class", "option-command prompt-button" + (child.selected ? " selected" : "")); + item.setAttribute("class", "option-command action-button" + (child.selected ? " selected" : "")); let image = document.createElement("image"); image.setAttribute("src", child.image || ""); item.appendChild(image); let label = document.createElement("label"); label.setAttribute("value", child.label); item.appendChild(label);
--- a/mobile/chrome/content/SelectHelperUI.js +++ b/mobile/chrome/content/SelectHelperUI.js @@ -38,17 +38,17 @@ var SelectHelperUI = { // Using a fragment prevent us to hang on huge list let fragment = document.createDocumentFragment(); let choices = aList.choices; for (let i = 0; i < choices.length; i++) { let choice = choices[i]; let item = document.createElement("listitem"); - item.setAttribute("class", "option-command listitem-iconic prompt-button"); + item.setAttribute("class", "option-command listitem-iconic action-button"); item.setAttribute("image", ""); item.setAttribute("flex", "1"); item.setAttribute("crop", "center"); item.setAttribute("label", choice.text); choice.selected ? item.classList.add("selected") : item.classList.remove("selected");
--- a/mobile/chrome/content/SharingUI.js +++ b/mobile/chrome/content/SharingUI.js @@ -18,17 +18,17 @@ var SharingUI = { this._dialog = importDialog(window, "chrome://browser/content/share.xul", null); document.getElementById("share-title").value = aTitle || aURL; BrowserUI.pushPopup(this, this._dialog); let bbox = document.getElementById("share-buttons-box"); this._handlers.forEach(function(handler) { let button = document.createElement("button"); - button.className = "prompt-button"; + button.className = "action-button"; button.setAttribute("label", handler.name); button.addEventListener("command", function() { SharingUI.hide(); handler.callback(aURL || "", aTitle || ""); }, false); bbox.appendChild(button); });
--- a/mobile/chrome/content/bindings.xml +++ b/mobile/chrome/content/bindings.xml @@ -868,19 +868,19 @@ <xul:label class="bookmark-item-tags" xbl:inherits="value=tags"/> </xul:vbox> </xul:hbox> <xul:hbox anonid="bookmark-manage" class="bookmark-manage" hidden="true" flex="1"> <xul:image xbl:inherits="src"/> <xul:vbox flex="1"> <xul:vbox flex="1"> - <xul:textbox anonid="name" xbl:inherits="value=title"/> - <xul:textbox anonid="uri" xbl:inherits="value=uri"/> - <xul:textbox anonid="tags" xbl:inherits="value=tags" emptytext="&editBookmarkTags.label;"/> + <xul:textbox anonid="name" xbl:inherits="value=title" class="prompt-edit" flex="1"/> + <xul:textbox anonid="uri" xbl:inherits="value=uri" class="prompt-edit" flex="1"/> + <xul:textbox anonid="tags" xbl:inherits="value=tags" emptytext="&editBookmarkTags.label;" class="prompt-edit" flex="1"/> </xul:vbox> <xul:hbox class="bookmark-controls" align="center"> <xul:spacer flex="1"/> <xul:button anonid="done-button" class="bookmark-done" label="&editBookmarkDone.label;" oncommand="document.getBindingParent(this).stopEditing(true)"/> </xul:hbox> </xul:vbox>
--- a/mobile/chrome/content/browser.xul +++ b/mobile/chrome/content/browser.xul @@ -354,28 +354,28 @@ <separator class="thin"/> <vbox> <button id="bookmark-popup-edit" label="&bookmarkEdit.label;" oncommand="BookmarkHelper.edit();"/> <spacer/> <button id="bookmark-popup-remove" label="&bookmarkRemove.label;" oncommand="BookmarkPopup.hide(); BookmarkHelper.removeBookmarksForURI(getBrowser().currentURI);"/> </vbox> </arrowbox> - <vbox id="bookmark-container" hidden="true" class="panel-dark window-width window-height"> - <vbox id="bookmark-dialog" class="panel-dark"> - <hbox id="bookmark-form-title"> + <box id="bookmark-container" class="perm-modal-block window-width window-height" hidden="true"> + <dialog id="bookmark-dialog" flex="1"> + <hbox id="bookmark-form-title" class="prompt-title"> <description>&editBookmarkDialog.title;</description> </hbox> - <separator id="bookmark-form-line"/> - <scrollbox id="bookmark-form" align="start"/> - <hbox id="bookmark-form-buttons" pack="center"> - <button label="&editBookmarkDone.label;" oncommand="BookmarkHelper.save();"/> + <separator id="bookmark-form-line" class="prompt-line"/> + <scrollbox id="bookmark-form" align="start" class="prompt-message" flex="1"/> + <hbox id="bookmark-form-buttons" pack="center" class="prompt-buttons"> + <button label="&editBookmarkDone.label;" class="prompt-button" oncommand="BookmarkHelper.save();"/> </hbox> - </vbox> - </vbox> + </dialog> + </box> <vbox id="panel-container" class="panel-dark window-width window-height" style="-moz-stack-sizing: ignore" left="10000" hidden="true"> <hbox id="panel-controls" class="panel-row-header" oncommand="BrowserUI.switchPane(event.target.getAttribute('linkedpanel'));"> <toolbarbutton id="tool-preferences" class="panel-row-button" type="radio" group="1" checked="true" linkedpanel="prefs-container"/> <toolbarbutton id="tool-downloads" class="panel-row-button" type="radio" group="1" linkedpanel="downloads-container"/> <toolbarbutton id="tool-addons" class="panel-row-button" type="radio" group="1" linkedpanel="addons-container"/> <toolbarbutton id="tool-console" class="panel-row-button" type="radio" group="1" hidden="true" linkedpanel="console-container"/> #ifndef ANDROID @@ -456,16 +456,17 @@ <setting id="sync-disconnect" class="setting-subgroup" type="control" collapsed="true"> <button label="&sync.disconnect;" oncommand="WeaveGlue.disconnect();" /> </setting> </settings> #endif <settings id="prefs-privacy" label="&privacy.title;"> <setting pref="network.cookie.cookieBehavior" title="&allowCookies.title;" type="boolint" on="0" off="2"/> <setting pref="signon.rememberSignons" title="&rememberPasswords.title;" type="bool"/> + <setting pref="privacy.donottrackheader.enabled" title="&doNotTrack.title;" type="bool"/> <setting title="&clearPrivateData2.title;" type="control"> <button id="prefs-clear-data" label="&clearPrivateData.button;" command="cmd_sanitize"/> </setting> </settings> <settings id="prefs-content" label="&content.title;"> <setting pref="browser.ui.zoom.reflow" title="&reflowZoom.title;" type="bool"/> <setting pref="permissions.default.image" title="&showImages.title;" type="boolint" on="1" off="2"/> <setting pref="javascript.enabled" type="bool" title="&enableJavaScript.title;"/> @@ -516,67 +517,67 @@ <placelist id="bookmarks-items" type="bookmarks" onopen="BookmarkList.openLink(event);" onhide="BrowserUI.updateStar();" flex="1" hidden="true"/> <historylist id="history-items" onopen="HistoryList.openLink(event);" flex="1" hidden="true"/> #ifdef MOZ_SERVICES_SYNC <remotetabslist id="remotetabs-items" onopen="RemoteTabsList.openLink(event)" flex="1" hidden="true"/> #endif </vbox> #ifdef MOZ_SERVICES_SYNC - <vbox id="syncsetup-container" class="window-width window-height" hidden="true"> - <vbox id="syncsetup-dialog" class="panel-dark" flex="1"> - <hbox class="syncsetup-title"> + <box id="syncsetup-container" class="perm-modal-block window-width window-height" hidden="true"> + <dialog id="syncsetup-dialog" flex="1"> + <hbox class="prompt-title"> <description>&sync.setup.title;</description> </hbox> - <separator class="syncsetup-line"/> + <separator class="prompt-line"/> <vbox id="syncsetup-simple" class="syncsetup-page" flex="1"> - <scrollbox class="syncsetup-scrollbox" orient="vertical" flex="1"> + <scrollbox class="prompt-message" orient="vertical" flex="1"> <description class="syncsetup-desc syncsetup-center" flex="1">&sync.setup.jpake;</description> <description class="syncsetup-center syncsetup-link" flex="1" onclick="WeaveGlue.openTutorial();">&sync.setup.tutorial;</description> <separator/> <vbox align="center" flex="1"> <description id="syncsetup-code1" class="syncsetup-code">....</description> <description id="syncsetup-code2" class="syncsetup-code">....</description> <description id="syncsetup-code3" class="syncsetup-code">....</description> </vbox> <separator/> <description class="syncsetup-center syncsetup-link" flex="1" onclick="WeaveGlue.openManual();">&sync.fallback;</description> <separator flex="1"/> </scrollbox> - <hbox class="syncsetup-buttons" pack="center"> + <hbox class="prompt-buttons" pack="center"> <button oncommand="WeaveGlue.close();">&sync.setup.cancel;</button> </hbox> </vbox> <vbox id="syncsetup-fallback" class="syncsetup-page" flex="1" hidden="true"> - <scrollbox class="syncsetup-scrollbox" orient="vertical" flex="1"> + <scrollbox class="prompt-message" orient="vertical" flex="1"> <description class="syncsetup-desc syncsetup-center" flex="1">&sync.setup.manual;</description> <separator/> - <textbox id="syncsetup-account" class="syncsetup-edit" placeholder="&sync.account;" oninput="WeaveGlue.canConnect();"/> - <textbox id="syncsetup-password" class="syncsetup-edit" placeholder="&sync.password;" type="password" oninput="WeaveGlue.canConnect();"/> - <textbox id="syncsetup-synckey" class="syncsetup-edit" placeholder="&sync.syncKey;" oninput="WeaveGlue.canConnect();"/> + <textbox id="syncsetup-account" class="prompt-edit" placeholder="&sync.account;" oninput="WeaveGlue.canConnect();"/> + <textbox id="syncsetup-password" class="prompt-edit" placeholder="&sync.password;" type="password" oninput="WeaveGlue.canConnect();"/> + <textbox id="syncsetup-synckey" class="prompt-edit" placeholder="&sync.syncKey;" oninput="WeaveGlue.canConnect();"/> <separator class="thin"/> <button id="syncsetup-usecustomserver" type="checkbox" class="button-checkbox" pack="start" oncommand="WeaveGlue.toggleCustomServer();"> <image class="button-image-icon"/> - <description class="syncsetup-label" flex="1">&sync.customServer;</description> + <description class="syncsetup-label prompt-checkbox-label" flex="1">&sync.customServer;</description> </button> - <textbox id="syncsetup-customserver" placeholder="&sync.serverURL;"/> + <textbox id="syncsetup-customserver" class="prompt-edit" placeholder="&sync.serverURL;"/> <separator flex="1"/> </scrollbox> - <hbox class="syncsetup-buttons" pack="center"> + <hbox class="prompt-buttons" pack="center"> <button oncommand="WeaveGlue.close();">&sync.setup.cancel;</button> <separator/> <button id="syncsetup-button-connect" oncommand="WeaveGlue.close(); WeaveGlue.connect();">&sync.setup.connect;</button> </hbox> </vbox> - </vbox> - </vbox> + </dialog> + </box> #endif <arrowbox id="search-engines-popup" hidden="true" offset="18" flex="1"> - <hbox id="search-engines-list" class="prompt-buttons" flex="1"/> + <hbox id="search-engines-list" class="action-buttons" flex="1"/> </arrowbox> <arrowbox id="newtab-popup" class="arrowbox-dark" hidden="true" onclick="NewTabPopup.selectTab()" align="center" start="0"> <label/> </arrowbox> <!-- options dialog for select form field --> <vbox id="select-container" class="window-width window-height context-block" top="0" left="0" hidden="true" flex="1"> @@ -655,17 +656,17 @@ #endif </richlistbox> </vbox> </hbox> <hbox id="menulist-container" class="window-width window-height context-block" top="0" left="0" hidden="true" flex="1"> <vbox id="menulist-popup" class="dialog-dark"> <label id="menulist-title" class="options-title" crop="center" flex="1"/> - <richlistbox id="menulist-commands" class="prompt-buttons" onclick="if (event.target != this) MenuListHelperUI.selectByIndex(this.selectedIndex);" flex="1"/> + <richlistbox id="menulist-commands" class="action-buttons" onclick="if (event.target != this) MenuListHelperUI.selectByIndex(this.selectedIndex);" flex="1"/> </vbox> </hbox> <!-- alerts for content --> <hbox id="alerts-container" hidden="true" align="start" bottom="0" onclick="AlertsHelper.click(event);"> <image id="alerts-image"/> <vbox flex="1"> <label id="alerts-title" value=""/>
--- a/mobile/chrome/content/common-ui.js +++ b/mobile/chrome/content/common-ui.js @@ -25,17 +25,17 @@ var BrowserSearch = { show: function bs_show() { let popup = this._popup; let list = this._list; while (list.lastChild) list.removeChild(list.lastChild); this.engines.forEach(function(aEngine) { let button = document.createElement("button"); - button.className = "prompt-button"; + button.className = "action-button"; button.setAttribute("label", aEngine.name); button.setAttribute("crop", "end"); button.setAttribute("pack", "start"); button.setAttribute("image", aEngine.iconURI ? aEngine.iconURI.spec : null); button.onclick = function() { popup.hidden = true; BrowserUI.doOpenSearch(aEngine.name); }
--- a/mobile/chrome/content/input.js +++ b/mobile/chrome/content/input.js @@ -55,16 +55,23 @@ const kOverTapWait = 150; const kLongTapWait = 500; // maximum drag distance in inches while axis locking can still be reverted const kAxisLockRevertThreshold = 0.8; // Same as NS_EVENT_STATE_ACTIVE from nsIEventStateManager.h const kStateActive = 0x00000001; +// After a drag begins, kinetic panning is stopped if the drag doesn't become +// a pan in 300 milliseconds. +const kStopKineticPanOnDragTimeout = 300; + +// Max velocity of a pan. This is in pixels/millisecond. +const kMaxVelocity = 6; + /** * MouseModule * * Handles all touch-related input such as dragging and tapping. * * The Fennec chrome DOM tree has elements that are augmented dynamically with * custom JS properties that tell the MouseModule they have custom support for * either dragging or clicking. These JS properties are JS objects that expose @@ -200,29 +207,31 @@ MouseModule.prototype = { // stop kinetic panning if targetScrollbox has changed if (this._kinetic.isActive() && this._dragger != dragger) this._kinetic.end(); this._targetScrollbox = targetScrollInterface ? targetScrollInterface.element : targetScrollbox; this._targetScrollInterface = targetScrollInterface; // Do tap - let event = document.createEvent("Events"); - event.initEvent("TapDown", true, true); - event.clientX = aEvent.clientX; - event.clientY = aEvent.clientY; - let success = aEvent.target.dispatchEvent(event); - if (success) { - this._recordEvent(aEvent); - this._target = aEvent.target; - this._mouseOverTimeout.once(kOverTapWait); - this._longClickTimeout.once(kLongTapWait); - } else { - // cancel all pending content clicks - this._cleanClickBuffer(); + if (!this._kinetic.isActive()) { + let event = document.createEvent("Events"); + event.initEvent("TapDown", true, true); + event.clientX = aEvent.clientX; + event.clientY = aEvent.clientY; + let success = aEvent.target.dispatchEvent(event); + if (success) { + this._recordEvent(aEvent); + this._target = aEvent.target; + this._mouseOverTimeout.once(kOverTapWait); + this._longClickTimeout.once(kLongTapWait); + } else { + // cancel all pending content clicks + this._cleanClickBuffer(); + } } // Do pan if (dragger) { let draggable = dragger.isDraggable(targetScrollbox, targetScrollInterface); dragData.locked = !draggable.x || !draggable.y; if (draggable.x || draggable.y) { this._dragger = dragger; @@ -323,21 +332,18 @@ MouseModule.prototype = { // let [sX, sY] = dragData.panPosition(); this.dX += dragData.prevPanX - sX; this.dY += dragData.prevPanY - sY; if (dragData.isPan()) { // Only pan when mouse event isn't part of a click. Prevent jittering on tap. this._kinetic.addData(sX - dragData.prevPanX, sY - dragData.prevPanY); - if (!this._waitingForPaint) { - this._dragBy(this.dX, this.dY); - this.dX = 0; - this.dY = 0; - } + this._dragBy(this.dX, this.dY); + // dragBy will reset dX and dY values to 0. // Let everyone know when mousemove begins a pan if (!oldIsPan && dragData.isPan()) { this._mouseOverTimeout.clear(); this._longClickTimeout.clear(); let event = document.createEvent("Events"); event.initEvent("PanBegin", true, false); @@ -356,55 +362,67 @@ MouseModule.prototype = { /** * Inform our dragger of a dragStart. */ _doDragStart: function _doDragStart(aEvent, aDraggable) { let dragData = this._dragData; dragData.setDragStart(aEvent.screenX, aEvent.screenY, aDraggable); this._kinetic.addData(0, 0); + this._dragStartTime = Date.now(); if (!this._kinetic.isActive()) this._dragger.dragStart(aEvent.clientX, aEvent.clientY, aEvent.target, this._targetScrollInterface); }, /** Finish a drag. */ _doDragStop: function _doDragStop() { let dragData = this._dragData; if (!dragData.dragging) return; dragData.endDrag(); // Note: it is possible for kinetic scrolling to be active from a // mousedown/mouseup event previous to this one. In this case, we // want the kinetic panner to tell our drag interface to stop. - if (!dragData.isPan() && !this._kinetic.isActive()) { - // There was no pan and no kinetic scrolling, so just stop dragger. + if (dragData.isPan()) { + if (Date.now() - this._dragStartTime > kStopKineticPanOnDragTimeout) + this._kinetic._velocity.set(0, 0); + // Start kinetic pan. + this._kinetic.start(); + } else { + this._kinetic.end(); this._dragger.dragStop(0, 0, this._targetScrollInterface); this._dragger = null; - } else if (dragData.isPan()) { - // Start kinetic pan. - this._kinetic.start(); } }, /** * Used by _onMouseMove() above and by KineticController's timer to do the * actual dragMove signalling to the dragger. We'd put this in _onMouseMove() * but then KineticController would be adding to its own data as it signals * the dragger of dragMove()s. */ _dragBy: function _dragBy(dX, dY, aIsKinetic) { + let dragged = true; let dragData = this._dragData; - let dragged = this._dragger.dragMove(dX, dY, this._targetScrollInterface, aIsKinetic); - if (dragged && !this._waitingForPaint) { - this._waitingForPaint = true; - mozRequestAnimationFrame(this); + if (!this._waitingForPaint || aIsKinetic) { + let dragData = this._dragData; + dragged = this._dragger.dragMove(dX, dY, this._targetScrollInterface, aIsKinetic); + if (dragged && !this._waitingForPaint) { + this._waitingForPaint = true; + mozRequestAnimationFrame(this); + } + this.dX = 0; + this.dY = 0; } + if (!dragData.isPan()) + this._kinetic.pause(); + return dragged; }, /** Callback for kinetic scroller. */ _kineticStop: function _kineticStop() { // Kinetic panning could finish while user is panning, so don't finish // the pan just yet. let dragData = this._dragData; @@ -811,122 +829,130 @@ function KineticController(aPanBy, aEndC this._velocity = new Point(0, 0); this._acceleration = new Point(0, 0); this._time = 0; this._timeStart = 0; // How often do we change the position of the scroll pane? Too often and panning may jerk near // the end. Too little and panning will be choppy. In milliseconds. this._updateInterval = Services.prefs.getIntPref("browser.ui.kinetic.updateInterval"); - // "Friction" of the scroll pane. The lower, the less friction and the further distance traveled. - this._decelerationRate = Services.prefs.getIntPref("browser.ui.kinetic.decelerationRate") / 10000; - // A multiplier for the initial velocity of the movement. - this._speedSensitivity = Services.prefs.getIntPref("browser.ui.kinetic.speedSensitivity") / 100; + // Constants that affect the "friction" of the scroll pane. + this._exponentialC = Services.prefs.getIntPref("browser.ui.kinetic.exponentialC"); + this._polynomialC = Services.prefs.getIntPref("browser.ui.kinetic.polynomialC") / 1000000; // Number of milliseconds that can contain a swipe. Movements earlier than this are disregarded. this._swipeLength = Services.prefs.getIntPref("browser.ui.kinetic.swipeLength"); this._reset(); } KineticController.prototype = { _reset: function _reset() { this._active = false; + this._paused = false; this.momentumBuffer = []; this._velocity.set(0, 0); }, isActive: function isActive() { return this._active; }, _startTimer: function _startTimer() { - // Use closed form of a parabola to calculate each position for panning. - // x(t) = v0*t + .5*t^2*a - // where: v0 is initial velocity - // a is acceleration - // t is time elapsed - // - // x(t) - // ^ - // | | - // | - // | | - // | ....^^^^.... - // | ...^^ | ^^... - // | ...^ ^... - // |.. | .. - // -----------------------------------> t - // t0 tf=-v0/a - // - // Using this formula, distance moved is independent of the time between each frame, unlike time - // step approaches. Once the time is up, set the position to x(tf) and stop the timer. + let self = this; - let lastx = this._position; // track last position vector because pan takes differences + let lastp = this._position; // track last position vector because pan takes deltas let v0 = this._velocity; // initial velocity let a = this._acceleration; // acceleration + let c = this._exponentialC; + let p = new Point(0, 0); + let dx, dy, t, realt; - // Temporary "bins" so that we don't create new objects during pan. - let aBin = new Point(0, 0); - let v0Bin = new Point(0, 0); - let self = this; + function calcP(v0, a, t) { + // Important traits for this function: + // p(t=0) is 0 + // p'(t=0) is v0 + // + // We use exponential to get a smoother stop, but by itself exponential + // is too smooth at the end. Adding a polynomial with the appropriate + // weight helps to balance + return v0 * Math.exp(-t / c) * -c + a * t * t + v0 * c; + } + + this._calcV = function(v0, a, t) { + return v0 * Math.exp(-t / c) + 2 * a * t; + } let callback = { onBeforePaint: function kineticHandleEvent(timeStamp) { - if (!self.isActive()) // someone called end() on us between timer intervals + // Someone called end() on us between timer intervals + // or we are paused. + if (!self.isActive() || self._paused) return; // To make animation end fast enough but to keep smoothness, average the ideal // time frame (smooth animation) with the actual time lapse (end fast enough). // Animation will never take longer than 2 times the ideal length of time. - let realt = timeStamp - self._initialTime; + realt = timeStamp - self._initialTime; self._time += self._updateInterval; - let t = (self._time + realt) / 2; + t = (self._time + realt) / 2; - // Calculate new position using x(t) formula. - let x = v0Bin.set(v0).scale(t).add(aBin.set(a).scale(0.5 * t * t)); - let dx = x.x - lastx.x; - let dy = x.y - lastx.y; - lastx.set(x); + // Calculate new position. + p.x = calcP(v0.x, a.x, t); + p.y = calcP(v0.y, a.y, t); + dx = Math.round(p.x - lastp.x); + dy = Math.round(p.y - lastp.y); - // Test to see if movement is finished for each component. As seen in graph, we want the - // final position to be at tf. - if (t >= -v0.x / a.x) { - // Plug in t=-v0/a into x(t) to get final position. - dx = -v0.x * v0.x / 2 / a.x - lastx.x; - // Reset components. Next frame: a's component will be 0 and t >= NaN will be false. - lastx.x = 0; + // Test to see if movement is finished for each component. + if (dx * a.x > 0) { + dx = 0; + lastp.x = 0; v0.x = 0; a.x = 0; } // Symmetric to above case. - if (t >= -v0.y / a.y) { - dy = -v0.y * v0.y / 2 / a.y - lastx.y; - lastx.y = 0; + if (dy * a.y > 0) { + dy = 0; + lastp.y = 0; v0.y = 0; a.y = 0; } - let panned = false; - try { panned = self._panBy(Math.round(-dx), Math.round(-dy), true); } catch (e) {} - if (!panned) + if (v0.x == 0 && v0.y == 0) { self.end(); - else - mozRequestAnimationFrame(this); + } else { + let panStop = false; + if (dx != 0 || dy != 0) { + try { panStop = !self._panBy(-dx, -dy, true); } catch (e) {} + lastp.add(dx, dy); + } + + if (panStop) + self.end(); + else + mozRequestAnimationFrame(this); + } } }; this._active = true; + this._paused = false; mozRequestAnimationFrame(callback); }, start: function start() { function sign(x) { return x ? ((x > 0) ? 1 : -1) : 0; } + function clampFromZero(x, closerToZero, furtherFromZero) { + if (x >= 0) + return Math.max(closerToZero, Math.min(furtherFromZero, x)); + return Math.min(-closerToZero, Math.max(-furtherFromZero, x)); + } + let mb = this.momentumBuffer; let mblen = this.momentumBuffer.length; let lastTime = mb[mblen - 1].t; let distanceX = 0; let distanceY = 0; let swipeLength = this._swipeLength; @@ -935,34 +961,53 @@ KineticController.prototype = { for (let i = 0; i < mblen; i++) { me = mb[i]; if (lastTime - me.t < swipeLength) { distanceX += me.dx; distanceY += me.dy; } } - // Only allow kinetic scrolling to speed up if kinetic scrolling is active. - this._velocity.x = (distanceX < 0 ? Math.min : Math.max)((distanceX / swipeLength) * this._speedSensitivity, this._velocity.x); - this._velocity.y = (distanceY < 0 ? Math.min : Math.max)((distanceY / swipeLength) * this._speedSensitivity, this._velocity.y); + let currentVelocityX = 0; + let currentVelocityY = 0; + + if (this.isActive()) { + // If active, then we expect this._calcV to be defined. + let currentTime = Date.now() - this._initialTime; + currentVelocityX = Util.clamp(this._calcV(this._velocity.x, this._acceleration.x, currentTime), -kMaxVelocity, kMaxVelocity); + currentVelocityY = Util.clamp(this._calcV(this._velocity.y, this._acceleration.y, currentTime), -kMaxVelocity, kMaxVelocity); + } + + if (currentVelocityX * this._velocity.x <= 0) + currentVelocityX = 0; + if (currentVelocityY * this._velocity.y <= 0) + currentVelocityY = 0; + + let swipeTime = Math.min(swipeLength, lastTime - mb[0].t); + this._velocity.x = clampFromZero((distanceX / swipeTime) + currentVelocityX, Math.abs(currentVelocityX), 6); + this._velocity.y = clampFromZero((distanceY / swipeTime) + currentVelocityY, Math.abs(currentVelocityY), 6); // Set acceleration vector to opposite signs of velocity - this._acceleration.set(this._velocity.clone().map(sign).scale(-this._decelerationRate)); + this._acceleration.set(this._velocity.clone().map(sign).scale(-this._polynomialC)); this._position.set(0, 0); this._initialTime = mozAnimationStartTime; this._time = 0; this.momentumBuffer = []; - if (!this.isActive()) + if (!this.isActive() || this._paused) this._startTimer(); return true; }, + pause: function pause() { + this._paused = true; + }, + end: function end() { if (this.isActive()) { if (this._beforeEnd) this._beforeEnd(); this._reset(); } },
--- a/mobile/chrome/content/prompt/alert.xul +++ b/mobile/chrome/content/prompt/alert.xul @@ -14,17 +14,18 @@ </keyset> <commandset> <command id="cmd_ok" oncommand="document.getElementById('prompt-alert-dialog').close()"/> <command id="cmd_cancel" oncommand="document.getElementById('prompt-alert-dialog').close()"/> </commandset> <vbox class="prompt-header" flex="1"> - <label id="prompt-alert-title" class="prompt-title" crop="center" flex="1"/> + <description id="prompt-alert-title" class="prompt-title" crop="center" flex="1"/> + <separator id="prompt-alert-separator" class="prompt-line"/> <scrollbox orient="vertical" class="prompt-message" flex="1"> <description id="prompt-alert-message"/> </scrollbox> <button id="prompt-alert-checkbox" type="checkbox" class="button-checkbox" collapsed="true" pack="start" flex="1"> <image class="button-image-icon"/> <description id="prompt-alert-checkbox-label" class="prompt-checkbox-label" flex="1"/>
--- a/mobile/chrome/content/prompt/confirm.xul +++ b/mobile/chrome/content/prompt/confirm.xul @@ -14,17 +14,18 @@ </keyset> <commandset> <command id="cmd_ok" oncommand="document.getElementById('prompt-confirm-dialog').PromptHelper.closeConfirm(true)"/> <command id="cmd_cancel" oncommand="document.getElementById('prompt-confirm-dialog').PromptHelper.closeConfirm(false)"/> </commandset> <vbox class="prompt-header" flex="1"> - <label id="prompt-confirm-title" class="prompt-title" crop="center" flex="1"/> + <description id="prompt-confirm-title" class="prompt-title" crop="center" flex="1"/> + <separator id="prompt-confirm-separator" class="prompt-line"/> <scrollbox orient="vertical" class="prompt-message" flex="1"> <description id="prompt-confirm-message"/> </scrollbox> <button id="prompt-confirm-checkbox" type="checkbox" class="button-checkbox" collapsed="true" pack="start" flex="1"> <image class="button-image-icon"/> <description id="prompt-confirm-checkbox-label" class="prompt-checkbox-label" flex="1"/>
--- a/mobile/chrome/content/prompt/prompt.xul +++ b/mobile/chrome/content/prompt/prompt.xul @@ -14,23 +14,24 @@ </keyset> <commandset> <command id="cmd_ok" oncommand="document.getElementById('prompt-prompt-dialog').PromptHelper.closePrompt(true)"/> <command id="cmd_cancel" oncommand="document.getElementById('prompt-prompt-dialog').PromptHelper.closePrompt(false)"/> </commandset> <vbox class="prompt-header" flex="1"> - <label id="prompt-prompt-title" class="prompt-title" crop="center" flex="1"/> + <description id="prompt-prompt-title" class="prompt-title" crop="center" flex="1"/> + <separator class="prompt-line"/> <scrollbox orient="vertical" class="prompt-message" flex="1"> <description id="prompt-prompt-message"/> </scrollbox> - <textbox id="prompt-prompt-textbox"/> + <textbox id="prompt-prompt-textbox" class="prompt-edit"/> <button id="prompt-prompt-checkbox" type="checkbox" class="button-checkbox" collapsed="true" pack="start" flex="1"> <image class="button-image-icon"/> <description id="prompt-prompt-checkbox-label" class="prompt-checkbox-label" flex="1"/> </button> </vbox> <hbox class="prompt-buttons">
--- a/mobile/chrome/content/prompt/promptPassword.xul +++ b/mobile/chrome/content/prompt/promptPassword.xul @@ -19,35 +19,36 @@ </keyset> <commandset> <command id="cmd_ok" oncommand="document.getElementById('prompt-password-dialog').PromptHelper.closePassword(true)"/> <command id="cmd_cancel" oncommand="document.getElementById('prompt-password-dialog').PromptHelper.closePassword(false)"/> </commandset> <vbox class="prompt-header" flex="1"> - <label id="prompt-password-title" class="prompt-title" crop="center" flex="1"/> + <description id="prompt-password-title" class="prompt-title" crop="center" flex="1"/> + <separator class="prompt-line"/> <scrollbox orient="vertical" class="prompt-message" flex="1"> <description id="prompt-password-message"/> </scrollbox> - <grid> + <grid class="prompt-message"> <columns> <column flex="1"/> <column flex="1"/> </columns> <rows> <row align="center"> <label value="&editfield0.label;"/> - <textbox id="prompt-password-user"/> + <textbox id="prompt-password-user" class="prompt-edit"/> </row> <row align="center"> <label value="&editfield1.label;"/> - <textbox type="password" id="prompt-password-password"/> + <textbox type="password" id="prompt-password-password" class="prompt-edit"/> </row> </rows> </grid> <button id="prompt-password-checkbox" type="checkbox" class="button-checkbox" collapsed="true" pack="start" flex="1"> <image class="button-image-icon"/> <description id="prompt-password-checkbox-label" class="prompt-checkbox-label" flex="1"/> </button>
--- a/mobile/chrome/content/prompt/select.xul +++ b/mobile/chrome/content/prompt/select.xul @@ -14,17 +14,18 @@ </keyset> <commandset> <command id="cmd_ok" oncommand="document.getElementById('prompt-select-dialog').PromptHelper.closeSelect(true)"/> <command id="cmd_cancel" oncommand="document.getElementById('prompt-select-dialog').PromptHelper.closeSelect(false)"/> </commandset> <vbox class="prompt-header" flex="1"> - <label id="prompt-select-title" class="prompt-title" crop="center" flex="1"/> + <description id="prompt-select-title" class="prompt-title" crop="center" flex="1"/> + <separator class="prompt-line"/> <scrollbox orient="vertical" class="prompt-message" flex="1"> <description id="prompt-select-message"/> </scrollbox> <menulist id="prompt-select-list"/> </vbox>
--- a/mobile/chrome/tests/browser_addons.js +++ b/mobile/chrome/tests/browser_addons.js @@ -150,46 +150,42 @@ function isRestartShown(aShown, isUpdate done(notification); }, true); } else { done(notification); } } function checkInstallAlert(aShown, aCallback) { - info("checkInstallAlert " + aShown + "\n"); checkAlert(null, "xpinstall", null, aShown, function(aNotifyBox, aNotification) { if (aShown) { let button = aNotification.childNodes[0]; ok(!!button, "Notification has button"); if (button) button.click(); } aNotifyBox.removeAllNotifications(true); if (aCallback) aCallback(); }); } function checkDownloadNotification(aCallback) { - dump("checkDownloadNotification\n"); let msg = /download/i; checkNotification(/Add-ons/, msg, ADDON_IMG, aCallback); } function checkInstallNotification(aRestart, aCallback) { - dump("checkInstallNotification " + aRestart + "\n"); let msg = null; if (aRestart) msg = /restart/i; checkNotification(/Add-ons/, msg, ADDON_IMG, aCallback); } function checkNotification(aTitle, aMessage, aIcon, aCallback) { - dump("checkNotification " + aTitle + " " + aMessage + " " + aIcon + "\n"); let doTest = function() { ok(document.getElementById("alerts-container").classList.contains("showing"), "Alert shown"); let title = document.getElementById("alerts-title").value; let msg = document.getElementById("alerts-text").textContent; let img = document.getElementById("alerts-image").getAttribute("src"); if (aTitle) ok(aTitle.test(title), "Correct title alert shown: " + title); @@ -204,17 +200,16 @@ function checkNotification(aTitle, aMess AlertsHelper.container.hidden = true; aCallback(); }; waitFor(doTest, function() { return AlertsHelper.container.hidden == false; }); } function checkAlert(aId, aName, aLabel, aShown, aCallback) { - info("checkAlert " + aId + " " + aName + " " + aLabel + " " + aShown + "\n"); let msg = null; if (aId) msg = document.getElementById(aId); else msg = window.getNotificationBox(gCurrentTab.browser); ok(!!msg, "Have notification box"); let haveNotification = function(notify) { @@ -302,33 +297,35 @@ function loadUrl(aURL, aCallback, aNewTa gCurrentTab.browser.messageManager.removeMessageListener(aMessage.name, arguments.callee); if (aCallback) setTimeout(aCallback, 0); } }); } function checkInstallPopup(aName, aCallback) { - testPrompt("Installing Add-on", aName, [ {label: "Install", click: true}, {label: "Cancel", click: false}], aCallback); + testPrompt("Installing Add-on", aName, [ {label: "Install", click: true}, + {label: "Cancel", click: false}], + aCallback); } function testPrompt(aTitle, aMessage, aButtons, aCallback) { function doTest() { let prompt = document.getElementById("prompt-confirm-dialog"); ok(!!prompt, "Prompt shown"); if (prompt) { let title = document.getElementById("prompt-confirm-title"); let message = document.getElementById("prompt-confirm-message"); - is(aTitle, title.value, "Correct title shown"); + is(aTitle, title.textContent, "Correct title shown"); is(aMessage, message.textContent, "Correct message shown"); - let buttons = document.getElementsByClassName("prompt-button"); + let buttons = document.querySelectorAll("#prompt-confirm-buttons-box .prompt-button"); let clickButton = null; - ok(buttons.length == aButtons.length, "Prompt has correct number of buttons"); + is(buttons.length, aButtons.length, "Prompt has correct number of buttons"); if (buttons.length == aButtons.length) { for (let i = 0; i < buttons.length; i++) { is(buttons[i].label, aButtons[i].label, "Button has correct label"); if (aButtons[i].click) clickButton = buttons[i]; } } if (clickButton) @@ -346,33 +343,25 @@ function testPrompt(aTitle, aMessage, aB }, true); } else { doTest(); } } // Installs an addon via the urlbar. function installFromURLBar(aAddon) { - info("installFromURLBar " + aAddon + "\n"); return function() { loadUrl(gTestURL, function() { - info("loadUrl: " + gTestURL + "\n"); loadUrl(aAddon.sourceURL, null, false); - info("loadUrl: " + aAddon.sourceURL + "(2)\n"); checkInstallAlert(true, function() { - dump("info: checkInstallAlert callback\n"); checkDownloadNotification(function() { - dump("info: checkDownloadNotification callback\n"); checkInstallPopup(aAddon.name, function() { - dump("info: checkInstallPopup callback\n"); checkInstallNotification(!aAddon.bootstrapped, function() { - dump("info: checkInstallNotification callback\n"); open_manager(true, function() { isRestartShown(!aAddon.bootstrapped, false, function() { - dump("info: isRestartShown callback\n"); let elt = get_addon_element(aAddon.id); if (aAddon.bootstrapped) { checkAddonListing(aAddon, elt, "local"); var button = document.getAnonymousElementByAttribute(elt, "anonid", "uninstall-button"); ok(!!button, "Extension has uninstall button"); var updateButton = document.getElementById("addons-update-all"); is(updateButton.disabled, false, "Update button is enabled"); @@ -438,51 +427,36 @@ add_test(installFromAddonsPage(addons[1] function installListener(aSettings) { this.onComplete = aSettings.onComplete; this.addon = aSettings.addon; } installListener.prototype = { onNewInstall : function(install) { }, - onDownloadStarted : function(install) { - info("download started"); - }, - onDownloadProgress : function(install) { - info("download progress"); - }, - onDownloadEnded : function(install) { - info("download ended"); - }, - onDownloadCancelled : function(install) { - info("download cancelled"); - }, + onDownloadStarted : function(install) { }, + onDownloadProgress : function(install) { }, + onDownloadEnded : function(install) { }, + onDownloadCancelled : function(install) { }, onDownloadFailed : function(install) { if(this.addon.willFail) ok(false, "Install failed"); - info("download failed"); }, - onInstallStarted : function(install) { - info("Install started"); - }, + onInstallStarted : function(install) { }, onInstallEnded : function(install, addon) { - info("Install ended"); let self = this; isRestartShown(!this.addon.bootstrapped, false, function() { if(self.onComplete) self.onComplete(); }); }, - onInstallCancelled : function(install) { - info("Install cancelled"); - }, + onInstallCancelled : function(install) { }, onInstallFailed : function(install) { if(this.willFail) ok(false, "Install failed"); - info("install failed"); }, onExternalInstall : function(install, existing, needsRestart) { }, }; function updateListener(aSettings) { this.onComplete = aSettings.onComplete; this.addon = aSettings.addon; }
--- a/mobile/chrome/tests/browser_sidebars.js +++ b/mobile/chrome/tests/browser_sidebars.js @@ -11,16 +11,20 @@ function runNextTest() { if (gTests.length > 0) { gCurrentTest = gTests.shift(); info(gCurrentTest.desc); gCurrentTest.run(); } else { // Close the awesome panel just in case BrowserUI.activePanel = null; + + for (let iTab=0; iTab<newTabs.length; iTab++) + Browser.closeTab(newTabs[iTab], { forceClose: true }); + finish(); } } function waitForNavigationPanel(aCallback, aWaitForHide) { let evt = aWaitForHide ? "NavigationPanelHidden" : "NavigationPanelShown"; info("waitFor " + evt + "(" + Components.stack.caller + ")"); window.addEventListener(evt, function(aEvent) {
--- a/mobile/components/PromptService.js +++ b/mobile/components/PromptService.js @@ -234,33 +234,37 @@ Prompt.prototype = { /* ---------- internal methods ---------- */ openDialog: function openDialog(aSrc, aParams) { let browser = Services.wm.getMostRecentWindow("navigator:browser"); return browser.importDialog(this._domWin, aSrc, aParams); }, + _setupPrompt: function setupPrompt(aDoc, aType, aTitle, aText, aCheck) { + aDoc.getElementById("prompt-" + aType + "-title").appendChild(aDoc.createTextNode(aTitle)); + aDoc.getElementById("prompt-" + aType + "-message").appendChild(aDoc.createTextNode(aText)); + + if (aCheck && aCheck.msg) { + aDoc.getElementById("prompt-" + aType + "-checkbox").checked = aCheck.value; + this.setLabelForNode(aDoc.getElementById("prompt-" + aType + "-checkbox-label"), aCheck.msg); + aDoc.getElementById("prompt-" + aType + "-checkbox").removeAttribute("collapsed"); + } + }, + commonPrompt: function commonPrompt(aTitle, aText, aValue, aCheckMsg, aCheckState, isPassword) { var params = new Object(); params.result = false; params.checkbox = aCheckState; params.value = aValue; let dialog = this.openDialog("chrome://browser/content/prompt/prompt.xul", params); let doc = this._doc; - doc.getElementById("prompt-prompt-title").value = aTitle; - doc.getElementById("prompt-prompt-message").appendChild(doc.createTextNode(aText)); - - doc.getElementById("prompt-prompt-checkbox").checked = aCheckState.value; - this.setLabelForNode(doc.getElementById("prompt-prompt-checkbox-label"), aCheckMsg); + this._setupPrompt(doc, "prompt", aTitle, aText, {value: aCheckState.value, msg: aCheckMsg}); doc.getElementById("prompt-prompt-textbox").value = aValue.value; - if (aCheckMsg) - doc.getElementById("prompt-prompt-checkbox").removeAttribute("collapsed"); - if (isPassword) doc.getElementById("prompt-prompt-textbox").type = "password"; dialog.waitForClose(); return params.result; }, // @@ -343,61 +347,48 @@ Prompt.prototype = { return this.nsIAuthPrompt_promptPassword.apply(this, arguments); }, /* ---------- nsIPrompt ---------- */ alert: function alert(aTitle, aText) { let dialog = this.openDialog("chrome://browser/content/prompt/alert.xul", null); let doc = this._doc; - doc.getElementById("prompt-alert-title").value = aTitle; - doc.getElementById("prompt-alert-message").appendChild(doc.createTextNode(aText)); + this._setupPrompt(doc, "alert", aTitle, aText); dialog.waitForClose(); }, alertCheck: function alertCheck(aTitle, aText, aCheckMsg, aCheckState) { let dialog = this.openDialog("chrome://browser/content/prompt/alert.xul", aCheckState); let doc = this._doc; - doc.getElementById("prompt-alert-title").value = aTitle; - doc.getElementById("prompt-alert-message").appendChild(doc.createTextNode(aText)); - - doc.getElementById("prompt-alert-checkbox").checked = aCheckState.value; - this.setLabelForNode(doc.getElementById("prompt-alert-checkbox-label"), aCheckMsg); - doc.getElementById("prompt-alert-checkbox").removeAttribute("collapsed"); - + this._setupPrompt(doc, "alert", aTitle, aText, {value: aCheckState.value, msg: aCheckMsg}); dialog.waitForClose(); }, confirm: function confirm(aTitle, aText) { var params = new Object(); params.result = false; let dialog = this.openDialog("chrome://browser/content/prompt/confirm.xul", params); let doc = this._doc; - doc.getElementById("prompt-confirm-title").value = aTitle; - doc.getElementById("prompt-confirm-message").appendChild(doc.createTextNode(aText)); + this._setupPrompt(doc, "confirm", aTitle, aText); dialog.waitForClose(); return params.result; }, confirmCheck: function confirmCheck(aTitle, aText, aCheckMsg, aCheckState) { var params = new Object(); params.result = false; params.checkbox = aCheckState; let dialog = this.openDialog("chrome://browser/content/prompt/confirm.xul", params); let doc = this._doc; - doc.getElementById("prompt-confirm-title").value = aTitle; - doc.getElementById("prompt-confirm-message").appendChild(doc.createTextNode(aText)); - - doc.getElementById("prompt-confirm-checkbox").checked = aCheckState.value; - this.setLabelForNode(doc.getElementById("prompt-confirm-checkbox-label"), aCheckMsg); - doc.getElementById("prompt-confirm-checkbox").removeAttribute("collapsed"); + this._setupPrompt(doc, "prompt", aTitle, aText, {value: aCheckState.value, msg: aCheckMsg}); dialog.waitForClose(); return params.result; }, confirmEx: function confirmEx(aTitle, aText, aButtonFlags, aButton0, aButton1, aButton2, aCheckMsg, aCheckState) { @@ -413,24 +404,17 @@ Prompt.prototype = { var params = { result: false, checkbox: aCheckState, defaultButton: defaultButton } let dialog = this.openDialog("chrome://browser/content/prompt/confirm.xul", params); let doc = this._doc; - doc.getElementById("prompt-confirm-title").value = aTitle; - doc.getElementById("prompt-confirm-message").appendChild(doc.createTextNode(aText)); - - doc.getElementById("prompt-confirm-checkbox").checked = aCheckState.value; - this.setLabelForNode(doc.getElementById("prompt-confirm-checkbox-label"), aCheckMsg); - if (aCheckMsg) - doc.getElementById("prompt-confirm-checkbox").removeAttribute("collapsed"); - + this._setupPrompt(doc, "confirm", aTitle, aText, {value: aCheckState.value, msg: aCheckMsg}); let bbox = doc.getElementById("prompt-confirm-buttons-box"); while (bbox.lastChild) bbox.removeChild(bbox.lastChild); for (let i = 0; i < 3; i++) { let bTitle = null; switch (aButtonFlags & 0xff) { @@ -495,40 +479,33 @@ Prompt.prototype = { var params = new Object(); params.result = false; params.checkbox = aCheckState; params.user = aUsername; params.password = aPassword; let dialog = this.openDialog("chrome://browser/content/prompt/promptPassword.xul", params); let doc = this._doc; - doc.getElementById("prompt-password-title").value = aTitle; - doc.getElementById("prompt-password-message").appendChild(doc.createTextNode(aText)); - doc.getElementById("prompt-password-checkbox").checked = aCheckState.value; + this._setupPrompt(doc, "password", aTitle, aText, {value: aCheckState.value, msg: aCheckMsg}); doc.getElementById("prompt-password-user").value = aUsername.value; doc.getElementById("prompt-password-password").value = aPassword.value; - if (aCheckMsg) { - doc.getElementById("prompt-password-checkbox").removeAttribute("collapsed"); - this.setLabelForNode(doc.getElementById("prompt-password-checkbox-label"), aCheckMsg); - } dialog.waitForClose(); return params.result; }, select: function select(aTitle, aText, aCount, aSelectList, aOutSelection) { var params = new Object(); params.result = false; params.selection = aOutSelection; let dialog = this.openDialog("chrome://browser/content/prompt/select.xul", params); let doc = this._doc; - doc.getElementById("prompt-select-title").value = aTitle; - doc.getElementById("prompt-select-message").appendChild(doc.createTextNode(aText)); + this._setupPrompt(doc, "select", aTitle, aText); let list = doc.getElementById("prompt-select-list"); for (let i = 0; i < aCount; i++) list.appendItem(aSelectList[i], null, null); // select the first one list.selectedIndex = 0;
--- a/mobile/locales/en-US/chrome/preferences.dtd +++ b/mobile/locales/en-US/chrome/preferences.dtd @@ -3,16 +3,17 @@ <!ENTITY about.button "Go to Page"> <!ENTITY content.title "Content"> <!ENTITY reflowZoom.title "Reformat text on zoom"> <!ENTITY showImages.title "Show images"> <!ENTITY enableJavaScript.title "Enable JavaScript"> <!ENTITY enablePlugins.title "Enable Plugins"> <!ENTITY privacy.title "Privacy & Security"> <!ENTITY allowCookies.title "Allow cookies"> +<!ENTITY doNotTrack.title "Tell sites not to track me"> <!ENTITY clearPrivateData2.title "Clear private data"> <!ENTITY clearPrivateData.button "Clear"> <!ENTITY rememberPasswords.title "Remember passwords"> <!ENTITY language.title "Language"> <!ENTITY language.auto "Auto-detect"> <!ENTITY defaultBrowser.title "Default Browser"> <!ENTITY defaultBrowser.description "Make &brandShortName; your default browser"> <!ENTITY homepage.title "Start page">
--- a/mobile/themes/core/browser.css +++ b/mobile/themes/core/browser.css @@ -977,55 +977,20 @@ documenttab[reload="true"] > stack > .do #newtab-button { -moz-box-flex: 1; list-style-image: url("images/newtab-default-hdpi.png"); height: @sidebar_button_height@; } /* bookmark editor ------------------------------------------------------- */ -#bookmark-container { - -moz-box-align: center; - -moz-box-pack: center; - background-color: rgba(0,0,0,.6); - padding: 0; -} - -#bookmark-dialog { - margin: @margin_xxxnormal@ !important; - border: @border_width_small@ solid white; - border-radius: @border_radius_normal@; - box-shadow: black 0 @shadow_width_small@ @shadow_width_small@; -} - -#bookmark-form { - padding: @padding_xxxnormal@; -} - -#bookmark-form-title { - font-size: @font_xnormal@; - padding-top: @padding_large@; - -moz-box-align: center; - -moz-box-pack: center; -} - -#bookmark-form-line { - border-bottom: @border_width_small@ solid white; - margin: @margin_small@ 3em 0 3em; - height: @padding_normal@ !important; -} - #bookmark-form .bookmark-controls { display: none; } -#bookmark-form-buttons { - background-color: lightgray; -} - /* Identity popup -------------------------------------------------------- */ #identity-popup-container { padding: @padding_normal@; /* core spacing */ padding-bottom: @padding_xxxnormal@; } /* Popup Icons */ #identity-popup-icon { @@ -1077,27 +1042,27 @@ documenttab[reload="true"] > stack > .do } #identity-container[mode="verifiedIdentity"] > hbox > vbox > #identity-popup-encryption-icon , #identity-container[mode="verifiedDomain"] > hbox > vbox > #identity-popup-encryption-icon { list-style-image: url("chrome://browser/skin/images/locked-hdpi.png"); } /* Page Actions, Prompt, and Context Menu popups --------------------------- */ -.prompt-buttons, +.action-buttons, #context-commands, #pageactions-container { background: transparent; border-top: @border_width_tiny@ solid rgb(205,205,205); padding: 0; -moz-user-focus: ignore; display: inline-block; } -.prompt-button, +.action-button, .context-command, pageaction { -moz-border-top-colors: white; -moz-border-right-colors: rgb(175,175,175); -moz-border-bottom-colors: rgb(175,175,175); -moz-border-left-colors: white; border-style: solid; border-width: @border_width_tiny@ !important; @@ -1107,62 +1072,62 @@ pageaction { min-width: @touch_action_minwidth@; /* keep the button from being too narrow */ } /* Override richlistbox and richlistitem styles */ #context-commands > scrollbox { width: 100%; } -.prompt-button, +.action-button, .context-command { -moz-box-align: center; } -.prompt-button[disabled="true"], +.action-button[disabled="true"], .context-command[disabled="true"] { pointer-events: none; color: #aaa !important; } -.prompt-button[selected="true"], +.action-button[selected="true"], .context-command[selected="true"] { background: transparent; } /* Override button styles */ -.prompt-button { +.action-button { margin: 0; -moz-border-image: none !important; border-radius: 0; margin: 0; background: transparent; } -.prompt-button > .button-box { +.action-button > .button-box { padding: 0 @padding_small@ @padding_tiny@ @padding_xsmall@ !important; } -.prompt-button > .button-box > .button-icon { +.action-button > .button-box > .button-icon { -moz-margin-end: @margin_normal@; } @media (min-width: 500px) { - .prompt-button, + .action-button, pageaction { width: 50%; } - .prompt-button:last-child:nth-child(odd), + .action-button:last-child:nth-child(odd), pageaction.odd-last-child { width: 100%; } } -.prompt-button:not([disabled]):hover:active, +.action-button:not([disabled]):hover:active, .context-command:not([disabled]):hover:active, pageaction:not([disabled]):hover:active { background: url("chrome://browser/skin/images/popup-selected-item-hdpi.png") repeat-x !important; background-origin: border-box !important; background-clip: border-box !important; -moz-border-top-colors: transparent; -moz-border-left-colors: transparent; } @@ -1172,17 +1137,17 @@ pageaction > hbox > .pageaction-image { height: 32px; -moz-margin-end: @margin_normal@; } pageaction:not([image]) > hbox >.pageaction-image { width: 0; } -.prompt-button, +.action-button, .context-command, .pageaction-title { font-size: @font_normal@ !important; color: #414141 !important; } .pageaction-desc { font-size: @font_tiny@ !important; @@ -1198,22 +1163,22 @@ pageaction:not([image]) > hbox >.pageact font-size: @font_small@; padding: @padding_small@; } #context-hint[value=""] { visibility: collapse; } -#search-engines-list > .prompt-button > .button-box > .button-text { +#search-engines-list > .action-button > .button-box > .button-text { text-align: start; -moz-box-flex: 1; /* Needed for the crop attribute to have an effect */ } -#search-engines-list > .prompt-button > .button-box > .button-icon { +#search-engines-list > .action-button > .button-box > .button-icon { width: 32px; height: 32px; } /* Preferences window ---------------------------------------------------- */ .setting { padding-left: @padding_xnormal@; border-bottom: @border_width_tiny@ solid #cacdd5; @@ -1399,57 +1364,20 @@ richlistitem.appmenu-downloads-button > #appmenu[count="5"] > .appmenu-button[show="3"], #appmenu[count="5"] > .appmenu-button[show="4"], #appmenu[count="6"] > .appmenu-button { width: 33.33%; } } /* Sync setup ------------------------------------------------------------- */ -#syncsetup-container { - background-color: rgba(0,0,0,.6); - padding: 0; -} - -#syncsetup-dialog { - margin: @margin_xxxnormal@ !important; - border: @border_width_large@ solid white; - border-radius: @border_radius_normal@; - box-shadow: black 0 @shadow_width_small@ @shadow_width_small@; -} - -.syncsetup-scrollbox { - padding: @padding_xxxnormal@; -} - .syncsetup-center { text-align: center; } -.syncsetup-title { - font-size: @font_xnormal@; - padding-top: @padding_large@; - -moz-box-align: center; - -moz-box-pack: center; -} - -.syncsetup-line { - border-bottom: @border_width_small@ solid white; - margin: @margin_small@ 3em 0 3em; - height: @padding_normal@ !important; -} - -.syncsetup-desc { - font-size: @font_snormal@; -} - -.syncsetup-buttons { - background-color: lightgray; -} - .syncsetup-code { color: #000; background-color: #fff; border-radius: @border_radius_normal@; font-size: @font_xlarge@ !important; padding: 0.2em 0.4em; -moz-padding-end: 0.2em; letter-spacing: 0.2em; @@ -1460,20 +1388,16 @@ richlistitem.appmenu-downloads-button > .syncsetup-link { text-decoration: underline; } .syncsetup-label { color: #fff; } -.syncsetup-edit { - margin-bottom: @margin_xnormal@; -} - #syncsetup-customserver { -moz-margin-start: @margin_xnormal@; } /* content scrollbars */ .scroller { opacity: 0; background-color: rgba(0, 0, 0, 0.4) !important;
--- a/mobile/themes/core/defines.inc +++ b/mobile/themes/core/defines.inc @@ -75,16 +75,18 @@ %define autocomplete_item_container_padding 5.08mozmm %define autocomplete_item_subtitle_margin 2.75mozmm %define autocomplete_item_label_margin 3.18mozmm %define autocomplete_item_tags_margin 3.39mozmm %define autocompleteresult_padding 0.53mozmm +%define dialog_width 76.2mozmm + %define appmenu_portrait_height 21.17mozmm %define appmenu_button_height 10.48mozmm %else %define font_xlarge 48px %define font_xnormal 26px %define font_normal 24px %define font_snormal 22px %define font_small 18px @@ -157,16 +159,18 @@ %define autocomplete_item_container_padding 48px %define autocomplete_item_subtitle_margin 26px %define autocomplete_item_label_margin 30px %define autocomplete_item_tags_margin 32px %define autocompleteresult_padding 5px +%define dialog_width 500px + %define appmenu_portrait_height 200px %define appmenu_button_height 99px %endif %ifdef MOZ_PLATFORM_MAEMO %define orientation -moz-device-orientation %elifdef ANDROID %define orientation -moz-device-orientation
--- a/mobile/themes/core/platform.css +++ b/mobile/themes/core/platform.css @@ -100,56 +100,43 @@ textbox[disabled="true"] { /* sidebars spacer --------------------------------------------------------- */ .sidebar-spacer { background-color: #767973; } /* prompt dialogs ---------------------------------------------------------- */ .context-block, -.modal-block { +.modal-block, +.perm-modal-block { -moz-box-align: center; -moz-box-pack: center; background-color: rgba(0,0,0,.6); +} + +.context-block { padding: @touch_normal@; } -dialog, .dialog-dark, .panel-arrowcontent { background: url("chrome://browser/skin/images/popup-bg-hdpi.png") left bottom repeat-x; background-color: white; border-radius: @border_radius_normal@; box-shadow: black 0 @border_radius_tiny@ @border_radius_tiny@, black 0 -@border_radius_tiny@ @border_radius_tiny@; padding: @padding_normal@ 0; /* core spacing on top/bottom */ } -dialog > .prompt-header { - padding: @padding_normal@; - font-size: @font_small@ !important; -} - -dialog > .prompt-header > .prompt-title { - font-size: @font_normal@ !important; -} - @media (max-width: 499px) { - .context-block, - .modal-block { + .context-block { padding: @padding_xlarge@; } - - dialog > .prompt-header, - dialog > .prompt-header > .prompt-title { - font-size: @font_small@ !important; - } } dialog > .prompt-header > .prompt-message { - margin-top: @margin_normal@; white-space: pre-wrap; } dialog > .prompt-header > .button-checkbox { margin-left: @margin_large@; } /* buttons ----------------------------------------------------------------- */ @@ -282,16 +269,24 @@ toolbarbutton[open="true"] { } /* checkbox buttons ----------------------------------------------------------- */ .button-checkbox { padding: 0 !important; background: none !important; border: none !important; -moz-border-image: none !important; + color: white; + -moz-box-align: center; + font-size: @font_small@; + -moz-box-align: center; +} + +.prompt-checkbox-label { + text-align: left; } .button-checkbox > .button-image-icon { -moz-margin-end: @margin_normal@; list-style-image: url("chrome://browser/skin/images/check-unselected-30.png"); } .button-checkbox[checked="true"] > .button-image-icon { @@ -555,28 +550,75 @@ progressmeter { /* panels / arrowboxes------------------------------------------------------ */ arrowbox { -moz-appearance: none; background: transparent !important; border: none; } +dialog, .arrowbox-dark .panel-arrowcontent, .panel-dark { color: white; background: rgb(94,97,102); } - + +dialog, .arrowbox-dark .panel-arrowcontent { border: @border_width_large@ solid white; border-radius: @border_radius_normal@; box-shadow: black 0 @shadow_width_small@ @shadow_width_small@; } +dialog { + margin: @margin_xxxnormal@ !important; + max-width: @dialog_width@; +} + +.prompt-message { + text-align: center; + -moz-box-pack: center; + font-size: @font_snormal@; + margin: @padding_normal@; +} + +.prompt-title { + text-align: center; + font-size: @font_xnormal@; + -moz-box-align: center; + -moz-box-pack: center; + padding-top: @padding_xnormal@; +} + +/* Authentication dialogs do not have a title */ +.prompt-title:empty, +.prompt-title:empty + .prompt-line { + display: none; +} + +.prompt-line { + border-bottom: @border_width_small@ solid white; + margin: @margin_small@ 3em 0 3em; + height: @padding_normal@ !important; +} + +.prompt-buttons { + font-size: @font_snormal@; + background-color: lightgray; + display: inline-block; + text-align: center; +} + +.prompt-edit { + margin: @margin_xnormal@; + font-size: @font_normal@; + text-align: start; +} + .panel-arrow[side="top"] { list-style-image: url("chrome://browser/skin/images/arrowbox-up.png"); margin-bottom: -@margin_normal@; } .panel-arrow[side="bottom"] { list-style-image: url("chrome://browser/skin/images/arrowbox-down.png"); margin-top: -@margin_normal@;
--- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -695,21 +695,18 @@ pref("network.http.keep-alive", true); / pref("network.http.proxy.keep-alive", true); // There is a problem with some IIS7 servers that don't close the connection // properly after it times out (bug #491541). Default timeout on IIS7 is // 120 seconds. We need to reuse or drop the connection within this time. // We set the timeout a little shorter to keep a reserve for cases when // the packet is lost or delayed on the route. pref("network.http.keep-alive.timeout", 115); -// Limit the absolute number of http connections. -// Note: the socket transport service will clamp the number below 256 if the OS -// cannot allocate that many FDs, and it also always tries to reserve up to 250 -// file descriptors for things other than sockets. -pref("network.http.max-connections", 256); +// limit the absolute number of http connections. +pref("network.http.max-connections", 30); // limit the absolute number of http connections that can be established per // host. if a http proxy server is enabled, then the "server" is the proxy // server. Otherwise, "server" is the http origin server. pref("network.http.max-connections-per-server", 15); // if network.http.keep-alive is true, and if NOT connecting via a proxy, then // a new connection will only be attempted if the number of active persistent
--- a/modules/plugin/base/public/nsIPluginHost.idl +++ b/modules/plugin/base/public/nsIPluginHost.idl @@ -136,26 +136,23 @@ interface nsIPluginHost : nsISupports * host specified in the URL. This is used to prevent DNS-spoofing * attacks. Can be defaulted to NULL meaning use the host in the URL. * @param referrer - the referring URL (may be NULL) * @param forceJSEnabled - forces JavaScript to be enabled for 'javascript:' * URLs, even if the user currently has JavaScript disabled (usually * specify PR_FALSE) * @result - NS_OK if this operation was successful */ -%{C++ - NS_IMETHOD - GetURL(nsISupports* pluginInst, - const char* url, - const char* target = NULL, - nsIPluginStreamListener* streamListener = NULL, - const char* altHost = NULL, - const char* referrer = NULL, - PRBool forceJSEnabled = PR_FALSE) = 0; -%} + [noscript] void getURL(in nsISupports pluginInt, + in string url, + in string target, + in nsIPluginStreamListener streamListener, + in string altHost, + in string referrer, + in boolean forceJSEnabled); /** * Posts to a URL with post data and/or post headers. * * (Corresponds to NPN_PostURL and NPN_PostURLNotify.) * * @param pluginInst - the plugin making the request. If NULL, the URL * is fetched in the background. @@ -178,31 +175,28 @@ interface nsIPluginHost : nsISupports * specify PR_FALSE) * @param postHeadersLength - the length of postHeaders (if non-NULL) * @param postHeaders - the headers to POST. Must be in the form of * "HeaderName: HeaderValue\r\n". Each header, including the last, * must be followed by "\r\n". NULL specifies that there are no * post headers * @result - NS_OK if this operation was successful */ -%{C++ - NS_IMETHOD - PostURL(nsISupports* pluginInst, - const char* url, - PRUint32 postDataLen, - const char* postData, - PRBool isFile = PR_FALSE, - const char* target = NULL, - nsIPluginStreamListener* streamListener = NULL, - const char* altHost = NULL, - const char* referrer = NULL, - PRBool forceJSEnabled = PR_FALSE, - PRUint32 postHeadersLength = 0, - const char* postHeaders = NULL) = 0; -%} + [noscript] void postURL(in nsISupports pluginInst, + in string url, + in PRUint32 postDataLen, + in string postData, + in boolean isFile, + in string target, + in nsIPluginStreamListener streamListener, + in string altHost, + in string referrer, + in boolean forceJSEnabled, + in PRUint32 postHeadersLength, + in string postHeaders); /** * Returns the proxy info for a given URL. The caller is required to * free the resulting memory with nsIMalloc::Free. The result will be in the * following format * * i) "DIRECT" -- no proxy * ii) "PROXY xxx.xxx.xxx.xxx" -- use proxy @@ -279,29 +273,19 @@ interface nsIPluginHost : nsISupports /** * Get the plugin tag associated with a given plugin instance. * @param aInstance the plugin instance object * @return plugin tag object */ [noscript] nsIPluginTag getPluginTagForInstance(in nsIPluginInstance aInstance); -%{C++ - virtual void AddIdleTimeTarget(nsIPluginInstanceOwner* objectFrame, PRBool isVisible) = 0; - virtual void RemoveIdleTimeTarget(nsIPluginInstanceOwner* objectFrame) = 0; -%} -}; + [noscript, notxpcom] void addIdleTimeTarget(in nsIPluginInstanceOwner objectFrame, in boolean isVisible); + [noscript, notxpcom] void removeIdleTimeTarget(in nsIPluginInstanceOwner objectFrame); -/* - * Methods for clearing plugin private data. These should be moved onto - * nsIPluginHost proper post-Gecko 2.0. - */ -[scriptable, uuid(0b0a2fb8-dc2b-4df2-b721-4b7a4008df6c)] -interface nsIPluginHost_MOZILLA_2_0_BRANCH : nsISupports -{ /* * Flags for use with clearSiteData. * * FLAG_CLEAR_ALL: clear all data associated with a site. * FLAG_CLEAR_CACHE: clear cached data that can be retrieved again without * loss of functionality. To be used out of concern for * space and not necessarily privacy. */
--- a/modules/plugin/base/public/nsIPluginInstance.idl +++ b/modules/plugin/base/public/nsIPluginInstance.idl @@ -249,47 +249,38 @@ interface nsIPluginInstance : nsISupport void asyncSetWindow(in NPWindowPtr aWindow); /** * Call this each time after the plugin has been painted to the screen */ void notifyPainted(); /** - * This should return a valid gfxASurface pointer, or null if there is nothing to render yet. - * NO LONGER USED. Do not call. - */ - void getSurface(out gfxASurfacePtr aSurface); - - /** * @return true if plugin module supports async rendering */ PRBool useAsyncPainting(); -}; - -// XXX kill me after branching -[noscript, uuid(24235105-ac5f-483b-86ec-7c9446ddcb8a)] -interface nsIPluginInstance_MOZILLA_2_0_BRANCH : nsIPluginInstance -{ PRBool isRemoteDrawingCoreAnimation(); + /** * Returns a new Image object which draws an asynchronously-rendered * plugin. The Image is created using aContainer. * Fails if the plugin is using async rendering but no image has yet * been received, or if the plugin is not using async rendering. */ void getImage(in ImageContainerPtr aContainer, out ImagePtr aImage); + /** * Returns the size of the Image object that would be created if we called * getImage. * Fails if the plugin is using async rendering but no image has yet * been received, or if the plugin is not using async rendering. */ void getImageSize(in nsIntSizePtr aSize); + /** * This is the second leg in the trip to PluginInstanceParent. It * approximately follows the ReadbackSink API. */ void setBackgroundUnknown(); void beginUpdateBackground(in nsIntRectPtr rect, out gfxContextPtr ctx); void endUpdateBackground(in gfxContextPtr ctx, in nsIntRectPtr rect); };
--- a/modules/plugin/base/public/nsIPluginInstanceOwner.idl +++ b/modules/plugin/base/public/nsIPluginInstanceOwner.idl @@ -143,21 +143,14 @@ interface nsIPluginInstanceOwner : nsISu double *destX, double *destY, NPCoordinateSpace destSpace) = 0; %} void setEventModel(in PRInt32 eventModel); %{C++ virtual void SendIdleEvent() = 0; %} -}; -/** - * This interface extends nsIPluginInstanceOwner for the 2.0 branch - */ -[uuid(20504739-4519-45f3-a8f7-fc8afba7ea87)] -interface nsIPluginInstanceOwner_MOZILLA_2_0_BRANCH : nsISupports -{ /** * Call NPP_SetWindow on the plugin. */ void setWindow(); };
--- a/modules/plugin/base/src/PluginPRLibrary.cpp +++ b/modules/plugin/base/src/PluginPRLibrary.cpp @@ -242,22 +242,16 @@ nsresult PluginPRLibrary::AsyncSetWindow(NPP instance, NPWindow* window) { nsNPAPIPluginInstance* inst = (nsNPAPIPluginInstance*)instance->ndata; NS_ENSURE_TRUE(inst, NS_ERROR_NULL_POINTER); return NS_ERROR_NOT_IMPLEMENTED; } nsresult -PluginPRLibrary::GetSurface(NPP instance, gfxASurface** aSurface) -{ - return NS_ERROR_NOT_IMPLEMENTED; -} - -nsresult PluginPRLibrary::GetImage(NPP instance, ImageContainer* aContainer, Image** aImage) { return NS_ERROR_NOT_IMPLEMENTED; } nsresult PluginPRLibrary::GetImageSize(NPP instance, nsIntSize* aSize) {
--- a/modules/plugin/base/src/PluginPRLibrary.h +++ b/modules/plugin/base/src/PluginPRLibrary.h @@ -135,17 +135,16 @@ public: char* argv[], NPSavedData* saved, NPError* error); virtual nsresult NPP_ClearSiteData(const char* site, uint64_t flags, uint64_t maxAge); virtual nsresult NPP_GetSitesWithData(InfallibleTArray<nsCString>& result); virtual nsresult AsyncSetWindow(NPP instance, NPWindow* window); - virtual nsresult GetSurface(NPP instance, gfxASurface** aSurface); virtual nsresult GetImage(NPP instance, ImageContainer* aContainer, Image** aImage); virtual nsresult GetImageSize(NPP instance, nsIntSize* aSize); NS_OVERRIDE virtual bool UseAsyncPainting() { return false; } #if defined(XP_MACOSX) virtual nsresult IsRemoteDrawingCoreAnimation(NPP instance, PRBool *aDrawing); #endif NS_OVERRIDE virtual nsresult SetBackgroundUnknown(NPP instance);
--- a/modules/plugin/base/src/nsNPAPIPlugin.cpp +++ b/modules/plugin/base/src/nsNPAPIPlugin.cpp @@ -614,23 +614,24 @@ MakeNewNPAPIStreamInternal(NPP npp, cons if (listener) { static_cast<nsNPAPIPluginStreamListener*>(listener.get())->SetCallNotify(PR_FALSE); } } switch (type) { case eNPPStreamTypeInternal_Get: { - if (NS_FAILED(pluginHost->GetURL(inst, relativeURL, target, listener))) + if (NS_FAILED(pluginHost->GetURL(inst, relativeURL, target, listener, + NULL, NULL, false))) return NPERR_GENERIC_ERROR; break; } case eNPPStreamTypeInternal_Post: { - if (NS_FAILED(pluginHost->PostURL(inst, relativeURL, len, buf, file, target, listener))) + if (NS_FAILED(pluginHost->PostURL(inst, relativeURL, len, buf, file, target, listener, NULL, NULL, false, 0, NULL))) return NPERR_GENERIC_ERROR; break; } default: NS_ERROR("how'd I get here"); } if (listener) {
--- a/modules/plugin/base/src/nsNPAPIPluginInstance.cpp +++ b/modules/plugin/base/src/nsNPAPIPluginInstance.cpp @@ -45,32 +45,31 @@ #include "nsNPAPIPluginInstance.h" #include "nsNPAPIPlugin.h" #include "nsNPAPIPluginStreamListener.h" #include "nsPluginHost.h" #include "nsPluginSafety.h" #include "nsPluginLogging.h" #include "nsIPrivateBrowsingService.h" #include "nsContentUtils.h" -#include "nsIContentUtils.h" #include "nsIDocument.h" #include "nsIScriptGlobalObject.h" #include "nsIScriptContext.h" #include "nsDirectoryServiceDefs.h" #include "nsJSNPRuntime.h" #include "nsPluginStreamListenerPeer.h" using namespace mozilla; using namespace mozilla::plugins::parent; static NS_DEFINE_IID(kIOutputStreamIID, NS_IOUTPUTSTREAM_IID); static NS_DEFINE_IID(kIPluginStreamListenerIID, NS_IPLUGINSTREAMLISTENER_IID); -NS_IMPL_ISUPPORTS2(nsNPAPIPluginInstance, nsIPluginInstance, nsIPluginInstance_MOZILLA_2_0_BRANCH) +NS_IMPL_ISUPPORTS1(nsNPAPIPluginInstance, nsIPluginInstance) nsNPAPIPluginInstance::nsNPAPIPluginInstance(nsNPAPIPlugin* plugin) : #ifdef XP_MACOSX #ifdef NP_NO_QUICKDRAW mDrawingModel(NPDrawingModelCoreGraphics), #else mDrawingModel(NPDrawingModelQuickDraw), @@ -874,29 +873,16 @@ nsNPAPIPluginInstance::AsyncSetWindow(NP AutoPluginLibraryCall library(this); if (!library) return NS_ERROR_FAILURE; return library->AsyncSetWindow(&mNPP, window); } NS_IMETHODIMP -nsNPAPIPluginInstance::GetSurface(gfxASurface** aSurface) -{ - if (RUNNING != mRunning) - return NS_OK; - - AutoPluginLibraryCall library(this); - if (!library) - return NS_ERROR_FAILURE; - - return library->GetSurface(&mNPP, aSurface); -} - -NS_IMETHODIMP nsNPAPIPluginInstance::GetImage(ImageContainer* aContainer, Image** aImage) { *aImage = nsnull; if (RUNNING != mRunning) return NS_OK; AutoPluginLibraryCall library(this); @@ -1370,27 +1356,18 @@ public: NS_IMETHOD Run(); }; NS_IMETHODIMP CarbonEventModelFailureEvent::Run() { nsString type = NS_LITERAL_STRING("npapi-carbon-event-model-failure"); -#ifdef MOZ_ENABLE_LIBXUL nsContentUtils::DispatchTrustedEvent(mContent->GetDocument(), mContent, type, PR_TRUE, PR_TRUE); -#else - nsCOMPtr<nsIContentUtils_MOZILLA_2_0_BRANCH> cu = - do_GetService("@mozilla.org/content/contentutils-moz2.0;1"); - if (cu) { - cu->DispatchTrustedEvent(mContent->GetDocument(), mContent, - type, PR_TRUE, PR_TRUE); - } -#endif return NS_OK; } void nsNPAPIPluginInstance::CarbonNPAPIFailure() { nsCOMPtr<nsIDOMElement> element; GetDOMElement(getter_AddRefs(element));
--- a/modules/plugin/base/src/nsNPAPIPluginInstance.h +++ b/modules/plugin/base/src/nsNPAPIPluginInstance.h @@ -62,25 +62,24 @@ class nsNPAPITimer { public: NPP npp; uint32_t id; nsCOMPtr<nsITimer> timer; void (*callback)(NPP npp, uint32_t timerID); }; -class nsNPAPIPluginInstance : public nsIPluginInstance_MOZILLA_2_0_BRANCH +class nsNPAPIPluginInstance : public nsIPluginInstance { private: typedef mozilla::PluginLibrary PluginLibrary; public: NS_DECL_ISUPPORTS NS_DECL_NSIPLUGININSTANCE - NS_DECL_NSIPLUGININSTANCE_MOZILLA_2_0_BRANCH nsNPAPIPlugin* GetPlugin(); nsresult GetNPP(NPP * aNPP); void SetURI(nsIURI* uri); nsIURI* GetURI();
--- a/modules/plugin/base/src/nsPluginHost.cpp +++ b/modules/plugin/base/src/nsPluginHost.cpp @@ -426,19 +426,18 @@ nsPluginHost::nsPluginHost() nsPluginHost::~nsPluginHost() { PLUGIN_LOG(PLUGIN_LOG_ALWAYS,("nsPluginHost::dtor\n")); Destroy(); sInst = nsnull; } -NS_IMPL_ISUPPORTS5(nsPluginHost, +NS_IMPL_ISUPPORTS4(nsPluginHost, nsIPluginHost, - nsIPluginHost_MOZILLA_2_0_BRANCH, nsIObserver, nsITimerCallback, nsISupportsWeakReference) nsPluginHost* nsPluginHost::GetInst() { if (!sInst) { @@ -1103,19 +1102,17 @@ nsPluginHost::DoInstantiateEmbeddedPlugi // if we are here then we have loaded a plugin for this mimetype nsNPAPIPluginInstance *instance = static_cast<nsNPAPIPluginInstance*>(instanceCOMPtr.get()); if (instance) { instance->Start(); aOwner->CreateWidget(); // If we've got a native window, the let the plugin know about it. - nsCOMPtr<nsIPluginInstanceOwner_MOZILLA_2_0_BRANCH> owner = do_QueryInterface(aOwner); - if (owner) - owner->SetWindow(); + aOwner->SetWindow(); // create an initial stream with data // don't make the stream if it's a java applet or we don't have SRC or DATA attribute PRBool havedata = PR_FALSE; nsCOMPtr<nsIPluginTagInfo> pti(do_QueryInterface(aOwner, &rv)); if (pti) { @@ -1180,25 +1177,22 @@ NS_IMETHODIMP nsPluginHost::InstantiateF NPWindow* win = nsnull; aOwner->GetWindow(win); if (win && instance) { instance->Start(); aOwner->CreateWidget(); // If we've got a native window, the let the plugin know about it. - nsCOMPtr<nsIPluginInstanceOwner_MOZILLA_2_0_BRANCH> owner = do_QueryInterface(aOwner); - if (owner) - owner->SetWindow(); + aOwner->SetWindow(); rv = NewFullPagePluginStream(aURI, instance, aStreamListener); // If we've got a native window, the let the plugin know about it. - if (owner) - owner->SetWindow(); + aOwner->SetWindow(); } } PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsPluginHost::InstantiateFullPagePlugin End mime=%s, rv=%d, owner=%p, url=%s\n", aMimeType, rv, aOwner, urlSpec.get())); return rv; @@ -1243,19 +1237,17 @@ nsresult nsPluginHost::FindStoppedPlugin if (instance && !instance->IsRunning()) { aOwner->SetInstance(instance); instance->SetOwner(aOwner); instance->Start(); aOwner->CreateWidget(); // If we've got a native window, the let the plugin know about it. - nsCOMPtr<nsIPluginInstanceOwner_MOZILLA_2_0_BRANCH> owner = do_QueryInterface(aOwner); - if (owner) - owner->SetWindow(); + aOwner->SetWindow(); return NS_OK; } return NS_ERROR_FAILURE; } NS_IMETHODIMP nsPluginHost::SetUpPluginInstance(const char *aMimeType, nsIURI *aURL,
--- a/modules/plugin/base/src/nsPluginHost.h +++ b/modules/plugin/base/src/nsPluginHost.h @@ -85,58 +85,33 @@ public: PRInt64 mLastModifiedTime; bool mSeen; nsRefPtr<nsInvalidPluginTag> mPrev; nsRefPtr<nsInvalidPluginTag> mNext; }; class nsPluginHost : public nsIPluginHost, - public nsIPluginHost_MOZILLA_2_0_BRANCH, public nsIObserver, public nsITimerCallback, public nsSupportsWeakReference { public: nsPluginHost(); virtual ~nsPluginHost(); static nsPluginHost* GetInst(); NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW NS_DECL_ISUPPORTS NS_DECL_NSIPLUGINHOST - NS_DECL_NSIPLUGINHOST_MOZILLA_2_0_BRANCH NS_DECL_NSIOBSERVER NS_DECL_NSITIMERCALLBACK - NS_IMETHOD - GetURL(nsISupports* pluginInst, - const char* url, - const char* target = NULL, - nsIPluginStreamListener* streamListener = NULL, - const char* altHost = NULL, - const char* referrer = NULL, - PRBool forceJSEnabled = PR_FALSE); - - NS_IMETHOD - PostURL(nsISupports* pluginInst, - const char* url, - PRUint32 postDataLen, - const char* postData, - PRBool isFile = PR_FALSE, - const char* target = NULL, - nsIPluginStreamListener* streamListener = NULL, - const char* altHost = NULL, - const char* referrer = NULL, - PRBool forceJSEnabled = PR_FALSE, - PRUint32 postHeadersLength = 0, - const char* postHeaders = NULL); - nsresult NewPluginURLStream(const nsString& aURL, nsNPAPIPluginInstance *aInstance, nsIPluginStreamListener *aListener, nsIInputStream *aPostStream = nsnull, const char *aHeadersData = nsnull, PRUint32 aHeadersDataLen = 0); @@ -168,19 +143,16 @@ public: // checks whether aTag is a "java" plugin tag (a tag for a plugin // that does Java) static PRBool IsJavaMIMEType(const char *aType); static nsresult GetPrompt(nsIPluginInstanceOwner *aOwner, nsIPrompt **aPrompt); static nsresult PostPluginUnloadEvent(PRLibrary* aLibrary); - void AddIdleTimeTarget(nsIPluginInstanceOwner* objectFrame, PRBool isVisible); - void RemoveIdleTimeTarget(nsIPluginInstanceOwner* objectFrame); - void PluginCrashed(nsNPAPIPlugin* plugin, const nsAString& pluginDumpID, const nsAString& browserDumpID); nsNPAPIPluginInstance *FindInstance(const char *mimetype); nsNPAPIPluginInstance *FindStoppedInstance(const char * url); nsNPAPIPluginInstance *FindOldestStoppedInstance(); PRUint32 StoppedInstanceCount();
--- a/modules/plugin/base/src/nsPluginStreamListenerPeer.cpp +++ b/modules/plugin/base/src/nsPluginStreamListenerPeer.cpp @@ -667,19 +667,17 @@ nsPluginStreamListenerPeer::OnStartReque if (NS_OK == rv) { mOwner->GetInstance(getter_AddRefs(pluginInstCOMPtr)); mPluginInstance = static_cast<nsNPAPIPluginInstance*>(pluginInstCOMPtr.get()); if (mPluginInstance) { mPluginInstance->Start(); mOwner->CreateWidget(); // If we've got a native window, the let the plugin know about it. - nsCOMPtr<nsIPluginInstanceOwner_MOZILLA_2_0_BRANCH> owner = do_QueryInterface(mOwner); - if (owner) - owner->SetWindow(); + mOwner->SetWindow(); } } } } // Set up the stream listener... rv = SetUpStreamListener(request, aURL); if (NS_FAILED(rv)) return rv; @@ -871,19 +869,17 @@ nsresult nsPluginStreamListenerPeer::Ser // Should call GetPluginPort() here. // This part is copied from nsPluginInstanceOwner::GetPluginPort(). nsCOMPtr<nsIWidget> widget; ((nsPluginNativeWindow*)window)->GetPluginWidget(getter_AddRefs(widget)); if (widget) { window->window = widget->GetNativeData(NS_NATIVE_PLUGIN_PORT); } #endif - nsCOMPtr<nsIPluginInstanceOwner_MOZILLA_2_0_BRANCH> owner = do_QueryInterface(mOwner); - if (owner) - owner->SetWindow(); + mOwner->SetWindow(); } mSeekable = PR_FALSE; mPStreamListener->OnStartBinding(this); mStreamOffset = 0; // force the plugin to use stream as file mStreamType = NP_ASFILE;
--- a/modules/plugin/test/mochitest/test_clear_site_data.html +++ b/modules/plugin/test/mochitest/test_clear_site_data.html @@ -7,17 +7,17 @@ </head> <body> <embed id="plugin1" type="application/x-test" width="200" height="200"></embed> <script class="testbody" type="application/javascript"> netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect'); SimpleTest.waitForExplicitFinish(); - const pluginHostIface = Components.interfaces.nsIPluginHost_MOZILLA_2_0_BRANCH; + const pluginHostIface = Components.interfaces.nsIPluginHost; var pluginHost = Components.classes["@mozilla.org/plugin/host;1"]. getService(pluginHostIface); const FLAG_CLEAR_ALL = pluginHostIface.FLAG_CLEAR_ALL; const FLAG_CLEAR_CACHE = pluginHostIface.FLAG_CLEAR_CACHE; // Make sure clearing by timerange is supported. var p = document.getElementById("plugin1"); p.setSitesWithDataCapabilities(true);
--- a/netwerk/base/src/nsSocketTransportService2.cpp +++ b/netwerk/base/src/nsSocketTransportService2.cpp @@ -59,63 +59,49 @@ using namespace mozilla; #if defined(PR_LOGGING) PRLogModuleInfo *gSocketTransportLog = nsnull; #endif nsSocketTransportService *gSocketTransportService = nsnull; PRThread *gSocketThread = nsnull; #define SEND_BUFFER_PREF "network.tcp.sendbuffer" -#define SOCKET_LIMIT_TARGET 550 //----------------------------------------------------------------------------- // ctor/dtor (called on the main/UI thread by the service manager) nsSocketTransportService::nsSocketTransportService() : mThread(nsnull) , mThreadEvent(nsnull) , mAutodialEnabled(PR_FALSE) , mLock("nsSocketTransportService::mLock") , mInitialized(PR_FALSE) , mShuttingDown(PR_FALSE) - , mActiveListSize(50) - , mIdleListSize(50) , mActiveCount(0) , mIdleCount(0) , mSendBufferSize(0) { #if defined(PR_LOGGING) gSocketTransportLog = PR_NewLogModule("nsSocketTransport"); #endif NS_ASSERTION(NS_IsMainThread(), "wrong thread"); - DetermineMaxCount(); /* init mMaxCount */ - mActiveList = (SocketContext *) - moz_xmalloc(sizeof(SocketContext) * mActiveListSize); - mIdleList = (SocketContext *) - moz_xmalloc(sizeof(SocketContext) * mIdleListSize); - mPollList = (PRPollDesc *) - moz_xmalloc(sizeof(PRPollDesc) * (mActiveListSize + 1)); - NS_ASSERTION(!gSocketTransportService, "must not instantiate twice"); gSocketTransportService = this; } nsSocketTransportService::~nsSocketTransportService() { NS_ASSERTION(NS_IsMainThread(), "wrong thread"); NS_ASSERTION(!mInitialized, "not shutdown properly"); if (mThreadEvent) PR_DestroyPollableEvent(mThreadEvent); - moz_free(mActiveList); - moz_free(mIdleList); - moz_free(mPollList); gSocketTransportService = nsnull; } //----------------------------------------------------------------------------- // event queue (any thread) already_AddRefed<nsIThread> nsSocketTransportService::GetThreadSafely() @@ -186,30 +172,30 @@ nsSocketTransportService::AttachSocket(P nsresult rv = AddToIdleList(&sock); if (NS_SUCCEEDED(rv)) NS_ADDREF(handler); return rv; } nsresult -nsSocketTransportService::DetachSocket(SocketContext *listHead, SocketContext *sock) +nsSocketTransportService::DetachSocket(SocketContext *sock) { SOCKET_LOG(("nsSocketTransportService::DetachSocket [handler=%x]\n", sock->mHandler)); - NS_ABORT_IF_FALSE((listHead == mActiveList) || (listHead == mIdleList), - "DetachSocket invalid head"); // inform the handler that this socket is going away sock->mHandler->OnSocketDetached(sock->mFD); // cleanup sock->mFD = nsnull; NS_RELEASE(sock->mHandler); - if (listHead == mActiveList) + // find out what list this is on. + PRUint32 index = sock - mActiveList; + if (index < NS_SOCKET_MAX_COUNT) RemoveFromPollList(sock); else RemoveFromIdleList(sock); // NOTE: sock is now an invalid pointer // // notify the first element on the pending socket queue... @@ -220,28 +206,23 @@ nsSocketTransportService::DetachSocket(S return Dispatch(event, NS_DISPATCH_NORMAL); } return NS_OK; } nsresult nsSocketTransportService::AddToPollList(SocketContext *sock) { - NS_ABORT_IF_FALSE(!(((PRUint32)(sock - mActiveList)) < mActiveListSize), - "AddToPollList Socket Already Active"); + SOCKET_LOG(("nsSocketTransportService::AddToPollList [handler=%x]\n", sock->mHandler)); - SOCKET_LOG(("nsSocketTransportService::AddToPollList [handler=%x]\n", sock->mHandler)); - if (mActiveCount == mActiveListSize) { - SOCKET_LOG((" Active List size of %d met\n", mActiveCount)); - if (!GrowActiveList()) { - NS_ERROR("too many active sockets"); - return NS_ERROR_OUT_OF_MEMORY; - } + if (mActiveCount == NS_SOCKET_MAX_COUNT) { + NS_ERROR("too many active sockets"); + return NS_ERROR_UNEXPECTED; } - + mActiveList[mActiveCount] = *sock; mActiveCount++; mPollList[mActiveCount].fd = sock->mFD; mPollList[mActiveCount].in_flags = sock->mHandler->mPollFlags; mPollList[mActiveCount].out_flags = 0; SOCKET_LOG((" active=%u idle=%u\n", mActiveCount, mIdleCount)); @@ -249,118 +230,81 @@ nsSocketTransportService::AddToPollList( } void nsSocketTransportService::RemoveFromPollList(SocketContext *sock) { SOCKET_LOG(("nsSocketTransportService::RemoveFromPollList [handler=%x]\n", sock->mHandler)); PRUint32 index = sock - mActiveList; - NS_ABORT_IF_FALSE(index < mActiveListSize, "invalid index"); + NS_ASSERTION(index < NS_SOCKET_MAX_COUNT, "invalid index"); SOCKET_LOG((" index=%u mActiveCount=%u\n", index, mActiveCount)); if (index != mActiveCount-1) { mActiveList[index] = mActiveList[mActiveCount-1]; mPollList[index+1] = mPollList[mActiveCount]; } mActiveCount--; SOCKET_LOG((" active=%u idle=%u\n", mActiveCount, mIdleCount)); } nsresult nsSocketTransportService::AddToIdleList(SocketContext *sock) { - NS_ABORT_IF_FALSE(!(((PRUint32)(sock - mIdleList)) < mIdleListSize), - "AddToIdlelList Socket Already Idle"); + SOCKET_LOG(("nsSocketTransportService::AddToIdleList [handler=%x]\n", sock->mHandler)); - SOCKET_LOG(("nsSocketTransportService::AddToIdleList [handler=%x]\n", sock->mHandler)); - if (mIdleCount == mIdleListSize) { - SOCKET_LOG((" Idle List size of %d met\n", mIdleCount)); - if (!GrowIdleList()) { - NS_ERROR("too many idle sockets"); - return NS_ERROR_OUT_OF_MEMORY; - } + if (mIdleCount == NS_SOCKET_MAX_COUNT) { + NS_ERROR("too many idle sockets"); + return NS_ERROR_UNEXPECTED; } mIdleList[mIdleCount] = *sock; mIdleCount++; SOCKET_LOG((" active=%u idle=%u\n", mActiveCount, mIdleCount)); return NS_OK; } void nsSocketTransportService::RemoveFromIdleList(SocketContext *sock) { SOCKET_LOG(("nsSocketTransportService::RemoveFromIdleList [handler=%x]\n", sock->mHandler)); - PRUint32 index = sock - mIdleList; - NS_ASSERTION(index < mIdleListSize, "invalid index in idle list"); + PRUint32 index = sock - &mIdleList[0]; + NS_ASSERTION(index < NS_SOCKET_MAX_COUNT, "invalid index"); if (index != mIdleCount-1) mIdleList[index] = mIdleList[mIdleCount-1]; mIdleCount--; SOCKET_LOG((" active=%u idle=%u\n", mActiveCount, mIdleCount)); } void nsSocketTransportService::MoveToIdleList(SocketContext *sock) { nsresult rv = AddToIdleList(sock); if (NS_FAILED(rv)) - DetachSocket(mActiveList, sock); + DetachSocket(sock); else RemoveFromPollList(sock); } void nsSocketTransportService::MoveToPollList(SocketContext *sock) { nsresult rv = AddToPollList(sock); if (NS_FAILED(rv)) - DetachSocket(mIdleList, sock); + DetachSocket(sock); else RemoveFromIdleList(sock); } -PRBool -nsSocketTransportService::GrowActiveList() -{ - PRInt32 toAdd = MaxCount() - mActiveListSize; - if (toAdd > 100) - toAdd = 100; - if (toAdd < 1) - return PR_FALSE; - - mActiveListSize += toAdd; - mActiveList = (SocketContext *) - moz_xrealloc(mActiveList, sizeof(SocketContext) * mActiveListSize); - mPollList = (PRPollDesc *) - moz_xrealloc(mPollList, sizeof(PRPollDesc) * (mActiveListSize + 1)); - return PR_TRUE; -} - -PRBool -nsSocketTransportService::GrowIdleList() -{ - PRInt32 toAdd = MaxCount() - mIdleListSize; - if (toAdd > 100) - toAdd = 100; - if (toAdd < 1) - return PR_FALSE; - - mIdleListSize += toAdd; - mIdleList = (SocketContext *) - moz_xrealloc(mIdleList, sizeof(SocketContext) * mIdleListSize); - return PR_TRUE; -} - PRIntervalTime nsSocketTransportService::PollTimeout() { if (mActiveCount == 0) return NS_SOCKET_POLL_TIMEOUT; // compute minimum time before any socket timeout expires. PRUint32 minR = PR_UINT16_MAX; @@ -645,19 +589,19 @@ nsSocketTransportService::Run() NS_ProcessNextEvent(thread); } SOCKET_LOG(("STS shutting down thread\n")); // detach any sockets PRInt32 i; for (i=mActiveCount-1; i>=0; --i) - DetachSocket(mActiveList, &mActiveList[i]); + DetachSocket(&mActiveList[i]); for (i=mIdleCount-1; i>=0; --i) - DetachSocket(mIdleList, &mIdleList[i]); + DetachSocket(&mIdleList[i]); // Final pass over the event queue. This makes sure that events posted by // socket detach handlers get processed. NS_ProcessPendingEvents(thread); gSocketThread = nsnull; SOCKET_LOG(("STS thread exit\n")); @@ -686,17 +630,17 @@ nsSocketTransportService::DoPollIteratio for (i=mActiveCount-1; i>=0; --i) { //--- SOCKET_LOG((" active [%u] { handler=%x condition=%x pollflags=%hu }\n", i, mActiveList[i].mHandler, mActiveList[i].mHandler->mCondition, mActiveList[i].mHandler->mPollFlags)); //--- if (NS_FAILED(mActiveList[i].mHandler->mCondition)) - DetachSocket(mActiveList, &mActiveList[i]); + DetachSocket(&mActiveList[i]); else { PRUint16 in_flags = mActiveList[i].mHandler->mPollFlags; if (in_flags == 0) MoveToIdleList(&mActiveList[i]); else { // update poll flags mPollList[i+1].in_flags = in_flags; mPollList[i+1].out_flags = 0; @@ -706,17 +650,17 @@ nsSocketTransportService::DoPollIteratio for (i=count-1; i>=0; --i) { //--- SOCKET_LOG((" idle [%u] { handler=%x condition=%x pollflags=%hu }\n", i, mIdleList[i].mHandler, mIdleList[i].mHandler->mCondition, mIdleList[i].mHandler->mPollFlags)); //--- if (NS_FAILED(mIdleList[i].mHandler->mCondition)) - DetachSocket(mIdleList, &mIdleList[i]); + DetachSocket(&mIdleList[i]); else if (mIdleList[i].mHandler->mPollFlags != 0) MoveToPollList(&mIdleList[i]); } SOCKET_LOG((" calling PR_Poll [active=%u idle=%u]\n", mActiveCount, mIdleCount)); // Measures seconds spent while blocked on PR_Poll PRUint32 pollInterval; @@ -753,17 +697,17 @@ nsSocketTransportService::DoPollIteratio } // // check for "dead" sockets and remove them (need to do this in // reverse order obviously). // for (i=mActiveCount-1; i>=0; --i) { if (NS_FAILED(mActiveList[i].mHandler->mCondition)) - DetachSocket(mActiveList, &mActiveList[i]); + DetachSocket(&mActiveList[i]); } if (n != 0 && mPollList[0].out_flags == PR_POLL_READ) { // acknowledge pollable event (wait should not block) if (PR_WaitForPollableEvent(mThreadEvent) != PR_SUCCESS) { // On Windows, the TCP loopback connection in the // pollable event may become broken when a laptop // switches between wired and wireless networks or @@ -822,72 +766,8 @@ nsSocketTransportService::Observe(nsISup NS_IMETHODIMP nsSocketTransportService::GetSendBufferSize(PRInt32 *value) { *value = mSendBufferSize; return NS_OK; } -/// ugly OS specific includes are placed at the bottom of the src for clarity - -#if defined(XP_WIN) -#include <windows.h> -#elif defined(XP_UNIX) && !defined(AIX) && !defined(NEXTSTEP) && !defined(QNX) -#include <sys/resource.h> -#endif - -void -nsSocketTransportService::DetermineMaxCount() -{ - mMaxCount = 50; /* historic default */ - -#if defined(XP_UNIX) && !defined(AIX) && !defined(NEXTSTEP) && !defined(QNX) - // on unix and os x network sockets and file - // descriptors are the same. OS X comes defaulted at 256, - // most linux at 1000. We can reliably use [sg]rlimit to - // query that and raise it. We will try to raise it 250 past - // our target number of SOCKET_LIMIT_TARGET so that some descriptors - // are still available for other things. - - struct rlimit rlimitData; - if (getrlimit(RLIMIT_NOFILE, &rlimitData) == -1) - return; - if (rlimitData.rlim_cur >= SOCKET_LIMIT_TARGET + 250) { - mMaxCount = SOCKET_LIMIT_TARGET; - return; - } - - PRInt32 maxallowed = rlimitData.rlim_max; - if (maxallowed == -1) /* no limit */ - maxallowed = SOCKET_LIMIT_TARGET + 250; - else if (maxallowed < 50 + 250) - return; - else if (maxallowed > SOCKET_LIMIT_TARGET + 250) - maxallowed = SOCKET_LIMIT_TARGET + 250; - - rlimitData.rlim_cur = maxallowed; - setrlimit(RLIMIT_NOFILE, &rlimitData); - if (getrlimit(RLIMIT_NOFILE, &rlimitData) == -1) - return; - if (rlimitData.rlim_cur > 50 + 250) - mMaxCount = rlimitData.rlim_cur - 250; - return; - -#elif defined(XP_WIN) && !defined(WIN_CE) - // win 95, 98, etc had a limit of 100 - so we will just - // use the historical 50 in every case older than XP (0x501). - // >= XP is confirmed to have at least 1000 - - OSVERSIONINFO osInfo = { sizeof(OSVERSIONINFO) }; - if (GetVersionEx(&osInfo)) { - PRInt32 version = - (osInfo.dwMajorVersion & 0xff) << 8 | - (osInfo.dwMinorVersion & 0xff); - if (version >= 0x501) { /* xp or later */ - mMaxCount = SOCKET_LIMIT_TARGET; - } - } - return; -#else - // other platforms are harder to test - so leave at safe legacy value -#endif -}
--- a/netwerk/base/src/nsSocketTransportService2.h +++ b/netwerk/base/src/nsSocketTransportService2.h @@ -60,16 +60,17 @@ // extern PRLogModuleInfo *gSocketTransportLog; #endif #define SOCKET_LOG(args) PR_LOG(gSocketTransportLog, PR_LOG_DEBUG, args) #define SOCKET_LOG_ENABLED() PR_LOG_TEST(gSocketTransportLog, PR_LOG_DEBUG) //----------------------------------------------------------------------------- +#define NS_SOCKET_MAX_COUNT 50 #define NS_SOCKET_POLL_TIMEOUT PR_INTERVAL_NO_TIMEOUT //----------------------------------------------------------------------------- class nsSocketTransportService : public nsPISocketTransportService , public nsIEventTarget , public nsIThreadObserver , public nsIRunnable @@ -91,21 +92,19 @@ public: // // the number of sockets that can be attached at any given time is // limited. this is done because some operating systems (e.g., Win9x) // limit the number of sockets that can be created by an application. // AttachSocket will fail if the limit is exceeded. consumers should // call CanAttachSocket and check the result before creating a socket. // PRBool CanAttachSocket() { - return mActiveCount + mIdleCount < mMaxCount; + return mActiveCount + mIdleCount < NS_SOCKET_MAX_COUNT; } - PRUint32 MaxCount() { return mMaxCount; } - protected: virtual ~nsSocketTransportService(); private: //------------------------------------------------------------------------- // misc (any thread) @@ -149,45 +148,38 @@ private: struct SocketContext { PRFileDesc *mFD; nsASocketHandler *mHandler; PRUint16 mElapsedTime; // time elapsed w/o activity }; - SocketContext *mActiveList; /* mListSize entries */ - SocketContext *mIdleList; /* mListSize entries */ + SocketContext mActiveList [ NS_SOCKET_MAX_COUNT ]; + SocketContext mIdleList [ NS_SOCKET_MAX_COUNT ]; - PRUint32 mActiveListSize; - PRUint32 mIdleListSize; PRUint32 mActiveCount; PRUint32 mIdleCount; - PRUint32 mMaxCount; - nsresult DetachSocket(SocketContext *, SocketContext *); + nsresult DetachSocket(SocketContext *); nsresult AddToIdleList(SocketContext *); nsresult AddToPollList(SocketContext *); void RemoveFromIdleList(SocketContext *); void RemoveFromPollList(SocketContext *); void MoveToIdleList(SocketContext *sock); void MoveToPollList(SocketContext *sock); - - PRBool GrowActiveList(); - PRBool GrowIdleList(); - void DetermineMaxCount(); - + //------------------------------------------------------------------------- // poll list (socket thread only) // // first element of the poll list is mThreadEvent (or null if the pollable // event cannot be created). //------------------------------------------------------------------------- - PRPollDesc *mPollList; /* mListSize + 1 entries */ + PRPollDesc mPollList[ NS_SOCKET_MAX_COUNT + 1 ]; PRIntervalTime PollTimeout(); // computes ideal poll timeout nsresult DoPollIteration(PRBool wait); // perfoms a single poll iteration PRInt32 Poll(PRBool wait, PRUint32 *interval); // calls PR_Poll. the out param // interval indicates the poll // duration in seconds.
--- a/netwerk/cookie/nsCookieService.cpp +++ b/netwerk/cookie/nsCookieService.cpp @@ -1545,17 +1545,21 @@ nsCookieService::SetCookieStringInternal serverTime = tempServerTime / PR_USEC_PER_SEC; } else { serverTime = PR_Now() / PR_USEC_PER_SEC; } // process each cookie in the header nsDependentCString cookieHeader(aCookieHeader); while (SetCookieInternal(aHostURI, baseDomain, requireHostMatch, - cookieStatus, cookieHeader, serverTime, aFromHttp)); + cookieStatus, cookieHeader, serverTime, aFromHttp)) { + // document.cookie can only set one cookie at a time + if (!aFromHttp) + break; + } } // notify observers that a cookie was rejected due to the users' prefs. void nsCookieService::NotifyRejected(nsIURI *aHostURI) { if (mObserverService) mObserverService->NotifyObservers(aHostURI, "cookie-rejected", nsnull);
new file mode 100644 --- /dev/null +++ b/netwerk/cookie/test/unit/test_bug643051.js @@ -0,0 +1,25 @@ +const Cc = Components.classes; +const Ci = Components.interfaces; + +Components.utils.import("resource://gre/modules/NetUtil.jsm"); + +function run_test() { + let cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService); + + let uri = NetUtil.newURI("http://example.org/"); + + let set = "foo=bar\nbaz=foo"; + let expected = "foo=bar; baz=foo"; + cs.setCookieStringFromHttp(uri, null, null, set, null, null); + + let actual = cs.getCookieStringFromHttp(uri, null, null); + do_check_eq(actual, expected); + + uri = NetUtil.newURI("http://example.com/"); + cs.setCookieString(uri, null, set, null); + + expected = "foo=bar"; + actual = cs.getCookieString(uri, null, null); + do_check_eq(actual, expected); +} +
--- a/netwerk/protocol/http/nsHttpHandler.cpp +++ b/netwerk/protocol/http/nsHttpHandler.cpp @@ -839,18 +839,17 @@ nsHttpHandler::PrefsChanged(nsIPrefBranc mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_REQUEST_DELAY, mMaxRequestDelay); } } if (PREF_CHANGED(HTTP_PREF("max-connections"))) { rv = prefs->GetIntPref(HTTP_PREF("max-connections"), &val); if (NS_SUCCEEDED(rv)) { - mMaxConnections = (PRUint16) NS_CLAMP( - val, 1, gSocketTransportService->MaxCount()); + mMaxConnections = (PRUint16) NS_CLAMP(val, 1, NS_SOCKET_MAX_COUNT); if (mConnMgr) mConnMgr->UpdateParam(nsHttpConnectionMgr::MAX_CONNECTIONS, mMaxConnections); } } if (PREF_CHANGED(HTTP_PREF("max-connections-per-server"))) { rv = prefs->GetIntPref(HTTP_PREF("max-connections-per-server"), &val);
--- a/storage/public/mozStorage.h +++ b/storage/public/mozStorage.h @@ -31,16 +31,27 @@ * 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 ***** */ +/** + * To add additional errors to Storage, please append entries to the bottom of + * the list in the following format: + * '#define NS_ERROR_STORAGE_YOUR_ERR \ + * NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_STORAGE, n)' + * where n is the next unique positive integer. You must also add an entry to + * js/src/xpconnect/src/xpc.msg under the code block beginning with the comment + * 'storage related codes (from mozStorage.h)', in the following format: + * 'XPC_MSG_DEF(NS_ERROR_STORAGE_YOUR_ERR, "brief description of your error")' + */ + #ifndef MOZSTORAGE_H #define MOZSTORAGE_H #define NS_ERROR_STORAGE_BUSY \ NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_STORAGE, 1) #define NS_ERROR_STORAGE_IOERR \ NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_STORAGE, 2)
--- a/toolkit/components/places/nsPlacesExpiration.js +++ b/toolkit/components/places/nsPlacesExpiration.js @@ -189,23 +189,25 @@ const LIMIT = { const STATUS = { CLEAN: 0, DIRTY: 1, UNKNOWN: 2, }; // Represents actions on which a query will run. const ACTION = { - TIMED: 1 << 0, - CLEAR_HISTORY: 1 << 1, - SHUTDOWN: 1 << 2, - CLEAN_SHUTDOWN: 1 << 3, - IDLE: 1 << 4, - DEBUG: 1 << 5, - TIMED_OVERLIMIT: 1 << 6, + TIMED: 1 << 0, // happens every this._interval + CLEAR_HISTORY: 1 << 1, // happens when history is cleared + SHUTDOWN: 1 << 2, // happens at shutdown when the db has a DIRTY state + CLEAN_SHUTDOWN: 1 << 3, // happens at shutdown when the db has a CLEAN or + // UNKNOWN state + IDLE: 1 << 4, // happens once on idle + DEBUG: 1 << 5, // happens whenever TOPIC_DEBUG_START_EXPIRATION is dispatched + TIMED_OVERLIMIT: 1 << 6, // just like TIMED, but also when we have too much + // history }; // The queries we use to expire. const EXPIRATION_QUERIES = { // Finds visits to be expired. Will return nothing if we are not over the // unique URIs limit. QUERY_FIND_VISITS_TO_EXPIRE: { @@ -395,17 +397,41 @@ const EXPIRATION_QUERIES = { ACTION.IDLE | ACTION.DEBUG }, // Empty the notifications table. QUERY_DELETE_NOTIFICATIONS: { sql: "DELETE FROM expiration_notify", actions: ACTION.TIMED | ACTION.TIMED_OVERLIMIT | ACTION.SHUTDOWN | ACTION.IDLE | ACTION.DEBUG - } + }, + + // The following queries are used to adjust the sqlite_stat1 table to help the + // query planner create better queries. These should always be run LAST, and + // are therefore at the end of the object. + + QUERY_ANALYZE_MOZ_PLACES: { + sql: "ANALYZE moz_places", + actions: ACTION.TIMED_OVERLIMIT | ACTION.CLEAR_HISTORY | ACTION.IDLE | + ACTION.DEBUG + }, + QUERY_ANALYZE_MOZ_BOOKMARKS: { + sql: "ANALYZE moz_bookmarks", + actions: ACTION.IDLE | ACTION.DEBUG + }, + QUERY_ANALYZE_MOZ_HISTORYVISITS: { + sql: "ANALYZE moz_historyvisits", + actions: ACTION.TIMED_OVERLIMIT | ACTION.CLEAR_HISTORY | ACTION.IDLE | + ACTION.DEBUG + }, + QUERY_ANALYZE_MOZ_INPUTHISTORY: { + sql: "ANALYZE moz_inputhistory", + actions: ACTION.TIMED | ACTION.TIMED_OVERLIMIT | ACTION.CLEAR_HISTORY | + ACTION.IDLE | ACTION.DEBUG + }, }; //////////////////////////////////////////////////////////////////////////////// //// nsPlacesExpiration definition function nsPlacesExpiration() { ////////////////////////////////////////////////////////////////////////////// @@ -730,18 +756,21 @@ nsPlacesExpiration.prototype = { catch (e) {} if (this._interval <= 0) this._interval = PREF_INTERVAL_SECONDS_NOTSET; }, /** * Execute async statements to expire with the specified queries. * - * @param aQueryNames - * The names of the queries to use for this expiration step. + * @param aAction + * The ACTION we are expiring for. See the ACTION const for values. + * @param aLimit + * Whether to use small, large or no limits when expiring. See the + * LIMIT const for values. */ _expireWithActionAndLimit: function PEX__expireWithActionAndLimit(aAction, aLimit) { // Skip expiration during batch mode. if (this._inBatchMode) return; @@ -860,19 +889,19 @@ nsPlacesExpiration.prototype = { params.expire_session = Ci.nsIAnnotationService.EXPIRE_SESSION; break; } return stmt; }, /** - * Creates a new timer based on this._syncInterval. + * Creates a new timer based on this._interval. * - * @return a REPEATING_SLACK nsITimer that runs every this._syncInterval. + * @return a REPEATING_SLACK nsITimer that runs every this._interval. */ _newTimer: function PEX__newTimer() { if (this._timer) this._timer.cancel(); if (this._shuttingDown) return; let interval = this.status != STATUS.DIRTY ?
new file mode 100644 --- /dev/null +++ b/toolkit/components/places/tests/expiration/test_analyze_runs.js @@ -0,0 +1,170 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +//////////////////////////////////////////////////////////////////////////////// +//// Constants + +const TOPIC_AUTOCOMPLETE_FEEDBACK_INCOMING = "autocomplete-will-enter-text"; + +//////////////////////////////////////////////////////////////////////////////// +//// Helpers + +/** + * Ensures that we have no data in the tables created by ANALYZE. + */ +function clearAnalyzeData() +{ + let db = DBConn(); + if (!db.tableExists("sqlite_stat1")) { + return; + } + db.executeSimpleSQL("DELETE FROM sqlite_stat1"); +} + +/** + * Checks that we ran ANALYZE on the specified table. + * + * @param aTableName + * The table to check if ANALYZE was ran. + * @param aRan + * True if it was expected to run, false otherwise + */ +function do_check_analyze_ran(aTableName, aRan) +{ + let db = DBConn(); + do_check_true(db.tableExists("sqlite_stat1")); + let stmt = db.createStatement("SELECT idx FROM sqlite_stat1 WHERE tbl = :table"); + stmt.params.table = aTableName; + try { + if (aRan) { + do_check_true(stmt.executeStep()); + do_check_neq(stmt.row.idx, null); + } + else { + do_check_false(stmt.executeStep()); + } + } + finally { + stmt.finalize(); + } +} + +//////////////////////////////////////////////////////////////////////////////// +//// Tests + +function test_timed() +{ + clearAnalyzeData(); + + let observer = function(aSubject, aTopic, aData) { + Services.obs.removeObserver(observer, + PlacesUtils.TOPIC_EXPIRATION_FINISHED); + setInterval(3600); + do_check_analyze_ran("moz_places", false); + do_check_analyze_ran("moz_bookmarks", false); + do_check_analyze_ran("moz_historyvisits", false); + do_check_analyze_ran("moz_inputhistory", true); + run_next_test(); + }; + + Services.obs.addObserver(observer, PlacesUtils.TOPIC_EXPIRATION_FINISHED, + false); + // Set a low interval and wait for the timed expiration to start. + setInterval(3); +} + +function test_debug() +{ + clearAnalyzeData(); + + let observer = function(aSubject, aTopic, aData) { + Services.obs.removeObserver(observer, + PlacesUtils.TOPIC_EXPIRATION_FINISHED); + do_check_analyze_ran("moz_places", true); + do_check_analyze_ran("moz_bookmarks", true); + do_check_analyze_ran("moz_historyvisits", true); + do_check_analyze_ran("moz_inputhistory", true); + run_next_test(); + }; + + Services.obs.addObserver(observer, PlacesUtils.TOPIC_EXPIRATION_FINISHED, + false); + force_expiration_step(1); +} + +function test_clear_history() +{ + clearAnalyzeData(); + + let observer = function(aSubject, aTopic, aData) { + Services.obs.removeObserver(observer, + PlacesUtils.TOPIC_EXPIRATION_FINISHED); + do_check_analyze_ran("moz_places", true); + do_check_analyze_ran("moz_bookmarks", false); + do_check_analyze_ran("moz_historyvisits", true); + do_check_analyze_ran("moz_inputhistory", true); + run_next_test(); + }; + + Services.obs.addObserver(observer, PlacesUtils.TOPIC_EXPIRATION_FINISHED, + false); + let listener = Cc["@mozilla.org/places/expiration;1"]. + getService(Ci.nsINavHistoryObserver); + listener.onClearHistory(); +} + +function test_shutdown() +{ + clearAnalyzeData(); + + let observer = function(aSubject, aTopic, aData) { + Services.obs.removeObserver(observer, + PlacesUtils.TOPIC_EXPIRATION_FINISHED); + do_check_analyze_ran("moz_places", false); + do_check_analyze_ran("moz_bookmarks", false); + do_check_analyze_ran("moz_historyvisits", false); + do_check_analyze_ran("moz_inputhistory", false); + run_next_test(); + }; + + Services.obs.addObserver(observer, PlacesUtils.TOPIC_EXPIRATION_FINISHED, + false); + shutdownExpiration(); +} + +//////////////////////////////////////////////////////////////////////////////// +//// Test Harness + +let gTests = [ + test_timed, + test_debug, + test_clear_history, + test_shutdown, +]; + +function run_test() +{ + const TEST_URI = NetUtil.newURI("http://mozilla.org/"); + const TEST_TITLE = "This is a test"; + let bs = PlacesUtils.bookmarks; + bs.insertBookmark(PlacesUtils.unfiledBookmarksFolderId, TEST_URI, + bs.DEFAULT_INDEX, TEST_TITLE); + let hs = PlacesUtils.history; + hs.addVisit(TEST_URI, Date.now() * 1000, null, hs.TRANSITION_TYPED, false, 0); + + let thing = { + QueryInterface: XPCOMUtils.generateQI([Ci.nsIAutoCompleteInput, + Ci.nsIAutoCompletePopup, + Ci.nsIAutoCompleteController]), + get popup() { return thing; }, + get controller() { return thing; }, + popupOpen: true, + selectedIndex: 0, + getValueAt: function() { return TEST_URI.spec; }, + searchString: TEST_TITLE, + }; + Services.obs.notifyObservers(thing, TOPIC_AUTOCOMPLETE_FEEDBACK_INCOMING, + null); + + run_next_test(); +}
--- a/widget/src/android/AndroidBridge.cpp +++ b/widget/src/android/AndroidBridge.cpp @@ -40,23 +40,28 @@ #include "nsXULAppAPI.h" #include <pthread.h> #include <prthread.h> #include "nsXPCOMStrings.h" #include "AndroidBridge.h" #include "nsAppShell.h" #include "nsOSHelperAppService.h" +#include "nsIPrefService.h" +#include "nsWindow.h" #ifdef DEBUG #define ALOG_BRIDGE(args...) ALOG(args) #else #define ALOG_BRIDGE(args...) #endif +#define IME_FULLSCREEN_PREF "widget.ime.android.landscape_fullscreen" +#define IME_FULLSCREEN_THRESHOLD_PREF "widget.ime.android.fullscreen_threshold" + using namespace mozilla; static PRUintn sJavaEnvThreadIndex = 0; AndroidBridge *AndroidBridge::sBridge = 0; static void JavaThreadDetachFunc(void *arg) @@ -98,17 +103,17 @@ AndroidBridge::Init(JNIEnv *jEnv, jEnv->GetJavaVM(&mJavaVM); mJNIEnv = nsnull; mThread = nsnull; mGeckoAppShellClass = (jclass) jEnv->NewGlobalRef(jGeckoAppShellClass); jNotifyIME = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "notifyIME", "(II)V"); - jNotifyIMEEnabled = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "notifyIMEEnabled", "(ILjava/lang/String;Ljava/lang/String;)V"); + jNotifyIMEEnabled = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "notifyIMEEnabled", "(ILjava/lang/String;Ljava/lang/String;Z)V"); jNotifyIMEChange = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "notifyIMEChange", "(Ljava/lang/String;III)V"); jAcknowledgeEventSync = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "acknowledgeEventSync", "()V"); jEnableAccelerometer = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "enableAccelerometer", "(Z)V"); jEnableLocation = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "enableLocation", "(Z)V"); jReturnIMEQueryResult = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "returnIMEQueryResult", "(Ljava/lang/String;II)V"); jScheduleRestart = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "scheduleRestart", "()V"); jNotifyAppShellReady = (jmethodID) jEnv->GetStaticMethodID(jGeckoAppShellClass, "onAppShellReady", "()V"); @@ -232,21 +237,45 @@ AndroidBridge::NotifyIMEEnabled(int aSta { ALOG_BRIDGE("AndroidBridge::NotifyIMEEnabled"); if (!sBridge) return; nsPromiseFlatString typeHint(aTypeHint); nsPromiseFlatString actionHint(aActionHint); - jvalue args[3]; + jvalue args[4]; AutoLocalJNIFrame jniFrame(1); args[0].i = aState; args[1].l = JNI()->NewString(typeHint.get(), typeHint.Length()); args[2].l = JNI()->NewString(actionHint.get(), actionHint.Length()); + args[3].z = false; + nsCOMPtr<nsIPrefBranch> prefs = + do_GetService(NS_PREFSERVICE_CONTRACTID); + if (prefs) { + PRInt32 landscapeFS; + nsresult rv = prefs->GetIntPref(IME_FULLSCREEN_PREF, &landscapeFS); + if (NS_SUCCEEDED(rv)) { + if (landscapeFS == 1) { + args[3].z = true; + } else if (landscapeFS == -1){ + rv = prefs->GetIntPref(IME_FULLSCREEN_THRESHOLD_PREF, + &landscapeFS); + if (NS_SUCCEEDED(rv)) { + // the threshold is hundreths of inches, so convert the + // threshold to pixels and multiply the height by 100 + if (nsWindow::GetAndroidScreenBounds().height * 100 < + landscapeFS * Bridge()->GetDPI()) + args[3].z = true; + } + + } + } + } + JNI()->CallStaticVoidMethodA(sBridge->mGeckoAppShellClass, sBridge->jNotifyIMEEnabled, args); } void AndroidBridge::NotifyIMEChange(const PRUnichar *aText, PRUint32 aTextLen, int aStart, int aEnd, int aNewEnd) {
--- a/widget/src/windows/nsWindow.cpp +++ b/widget/src/windows/nsWindow.cpp @@ -2901,17 +2901,18 @@ nsWindow::MakeFullScreen(PRBool aFullScr SetSizeMode(nsSizeMode_Fullscreen); } else { SetSizeMode(mOldSizeMode); } UpdateNonClientMargins(); PRBool visible = mIsVisible; - Show(PR_FALSE); + if (mOldSizeMode == nsSizeMode_Normal) + Show(PR_FALSE); // Will call hide chrome, reposition window. Note this will // also cache dimensions for restoration, so it should only // be called once per fullscreen request. nsresult rv = nsBaseWidget::MakeFullScreen(aFullScreen); if (visible) { Show(PR_TRUE);