diff --git a/b2g/components/SignInToWebsite.jsm b/b2g/components/SignInToWebsite.jsm index 75fe785bd00..51df5a8b395 100644 --- a/b2g/components/SignInToWebsite.jsm +++ b/b2g/components/SignInToWebsite.jsm @@ -158,6 +158,8 @@ let Pipe = { // kIdentityShimFile, where it is used to access the BrowserID object // and its internal API. let content = GaiaInterface.getContent(); + let mm = null; + let uuid = getRandomId(); if (!content) { log("ERROR: what the what? no content window?"); @@ -165,73 +167,90 @@ let Pipe = { return; } - // Prepare a message for gaia. The parameter showUI signals - // whether user interaction is needed. If it is, gaia will open a - // dialog; if not, a hidden iframe. In each case, BrowserID is - // available in the context. - let id = kOpenIdentityDialog + "-" + getRandomId(); - let detail = { - type: kOpenIdentityDialog, - showUI: aGaiaOptions.showUI || false, - id: id - }; + function removeMessageListeners() { + if (mm) { + mm.removeMessageListener(kIdentityDelegateFinished, identityDelegateFinished); + mm.removeMessageListener(kIdentityControllerDoMethod, aMessageCallback); + } + } + + function identityDelegateFinished() { + removeMessageListeners(); + + let detail = { + type: kReceivedIdentityAssertion, + showUI: aGaiaOptions.showUI || false, + id: kReceivedIdentityAssertion + "-" + uuid + }; + log('telling gaia to close the dialog'); + // tell gaia to close the dialog + GaiaInterface.sendChromeEvent(detail); + } - // When gaia signals back with a mozContentEvent containing the - // unique id we created, we know the window is ready. We then inject - // the magic javascript (kIdentityShimFile) that will give the content - // the superpowers it needs to communicate back with this code. content.addEventListener("mozContentEvent", function getAssertion(evt) { - - // Make sure the message is really for us let msg = evt.detail; - if (msg.id != id) { + if (!msg.id.match(uuid)) { return; } - // We only need to catch the first mozContentEvent from the - // iframe or popup, so we remove the listener right away. - content.removeEventListener("mozContentEvent", getAssertion); + switch (msg.id) { + case kOpenIdentityDialog + '-' + uuid: + if (msg.type === 'cancel') { + // The user closed the dialog. Clean up and call cancel. + content.removeEventListener("mozContentEvent", getAssertion); + removeMessageListeners(); + aMessageCallback({json: {method: "cancel"}}); + } else { + // The window has opened. Inject the identity shim file containing + // the callbacks in the content script. This could be either the + // visible popup that the user interacts with, or it could be an + // invisible frame. + let frame = evt.detail.frame; + let frameLoader = frame.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader; + mm = frameLoader.messageManager; + try { + mm.loadFrameScript(kIdentityShimFile, true); + log("Loaded shim " + kIdentityShimFile + "\n"); + } catch (e) { + log("Error loading ", kIdentityShimFile, " as a frame script: ", e); + } - // Try to load the identity shim file containing the callbacks - // in the content script. This could be either the visible - // popup that the user interacts with, or it could be an invisible - // frame. - let frame = evt.detail.frame; - let frameLoader = frame.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader; - let mm = frameLoader.messageManager; - try { - mm.loadFrameScript(kIdentityShimFile, true); - log("Loaded shim " + kIdentityShimFile + "\n"); - } catch (e) { - log("Error loading ", kIdentityShimFile, " as a frame script: ", e); + // There are two messages that the delegate can send back: a "do + // method" event, and a "finished" event. We pass the do-method + // events straight to the caller for interpretation and handling. + // If we receive a "finished" event, then the delegate is done, so + // we shut down the pipe and clean up. + mm.addMessageListener(kIdentityControllerDoMethod, aMessageCallback); + mm.addMessageListener(kIdentityDelegateFinished, identityDelegateFinished); + + mm.sendAsyncMessage(aGaiaOptions.message, aRpOptions); + } + break; + + case kReceivedIdentityAssertion + '-' + uuid: + // Received our assertion. The message manager callbacks will handle + // communicating back to the IDService. All we have to do is remove + // this listener. + content.removeEventListener("mozContentEvent", getAssertion); + break; + + default: + log("ERROR - Unexpected message: id=" + msg.id + ", type=" + msg.type + ", errorMsg=" + msg.errorMsg); + break; } - // There are two messages that the delegate can send back: a "do - // method" event, and a "finished" event. We pass the do-method - // events straight to the caller for interpretation and handling. - // If we receive a "finished" event, then the delegate is done, so - // we shut down the pipe and clean up. - mm.addMessageListener(kIdentityControllerDoMethod, aMessageCallback); - mm.addMessageListener(kIdentityDelegateFinished, function identityDelegateFinished() { - // clean up listeners - mm.removeMessageListener(kIdentityDelegateFinished, identityDelegateFinished); - mm.removeMessageListener(kIdentityControllerDoMethod, aMessageCallback); - - let id = kReceivedIdentityAssertion + "-" + getRandomId(); - let detail = { - type: kReceivedIdentityAssertion, - showUI: aGaiaOptions.showUI || false, - id: id - }; - log('telling gaia to close the dialog'); - // tell gaia to close the dialog - GaiaInterface.sendChromeEvent(detail); - }); - - mm.sendAsyncMessage(aGaiaOptions.message, aRpOptions); }); - // Tell gaia to open the identity iframe or trusty popup + // Tell gaia to open the identity iframe or trusty popup. The parameter + // showUI signals whether user interaction is needed. If it is, gaia will + // open a dialog; if not, a hidden iframe. In each case, BrowserID is + // available in the context. + let detail = { + type: kOpenIdentityDialog, + showUI: aGaiaOptions.showUI || false, + id: kOpenIdentityDialog + "-" + uuid + }; + GaiaInterface.sendChromeEvent(detail); } @@ -316,6 +335,10 @@ this.SignInToWebsiteController = { IdentityService.doLogout(aRpId); break; + case "cancel": + IdentityService.doCancel(aRpId); + break; + default: log("WARNING: wonky method call:", message.method); break; diff --git a/browser/app/Makefile.in b/browser/app/Makefile.in index 8cd5d1955a5..04a5386a715 100644 --- a/browser/app/Makefile.in +++ b/browser/app/Makefile.in @@ -31,9 +31,12 @@ DEFINES += \ -DNEWWINDOW_ICO=\"$(DIST)/branding/newwindow.ico\" \ -DNEWTAB_ICO=\"$(DIST)/branding/newtab.ico\" \ -DPBMODE_ICO=\"$(DIST)/branding/pbmode.ico\" \ - $(NULL) +ifdef MOZILLA_OFFICIAL +DEFINES += -DMOZILLA_OFFICIAL +endif + ifdef LIBXUL_SDK #{ PREF_JS_EXPORTS += $(srcdir)/profile/channel-prefs.js DEFINES += -DLIBXUL_SDK diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index 748911013d2..1f899a03645 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -729,6 +729,12 @@ pref("browser.safebrowsing.reportMalwareErrorURL", "http://%LOCALE%.malware-erro pref("browser.safebrowsing.warning.infoURL", "http://www.mozilla.com/%LOCALE%/firefox/phishing-protection/"); pref("browser.safebrowsing.malware.reportURL", "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site="); +#ifdef MOZILLA_OFFICIAL +// Normally the "client ID" sent in updates is appinfo.name, but for +// official Firefox releases from Mozilla we use a special identifier. +pref("browser.safebrowsing.id", "navclient-auto-ffox"); +#endif + // Name of the about: page contributed by safebrowsing to handle display of error // pages on phishing/malware hits. (bug 399233) pref("urlclassifier.alternate_error_page", "blocked"); diff --git a/browser/components/downloads/content/allDownloadsViewOverlay.js b/browser/components/downloads/content/allDownloadsViewOverlay.js index 34ed3714f73..682da84150d 100644 --- a/browser/components/downloads/content/allDownloadsViewOverlay.js +++ b/browser/components/downloads/content/allDownloadsViewOverlay.js @@ -22,6 +22,8 @@ Cu.import("resource://gre/modules/osfile.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "PrivateBrowsingUtils", "resource://gre/modules/PrivateBrowsingUtils.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "RecentWindow", + "resource:///modules/RecentWindow.jsm"); const nsIDM = Ci.nsIDownloadManager; @@ -389,13 +391,12 @@ DownloadElementShell.prototype = { // The progressmeter element for the download get _progressElement() { - let progressElement = document.getAnonymousElementByAttribute( - this._element, "anonid", "progressmeter"); - if (progressElement) { - delete this._progressElement; - return this._progressElement = progressElement; + if (!("__progressElement" in this)) { + this.__progressElement = + document.getAnonymousElementByAttribute(this._element, "anonid", + "progressmeter"); } - return null; + return this.__progressElement; }, // Updates the download state attribute (and by that hide/unhide the @@ -533,8 +534,8 @@ DownloadElementShell.prototype = { case "downloadsCmd_pauseResume": return this._dataItem && this._dataItem.inProgress && this._dataItem.resumable; case "downloadsCmd_retry": - // Disable the retry command for past downloads until it's fully implemented. - return this._dataItem && this._dataItem.canRetry; + // An history download can always be retried. + return !this._dataItem || this._dataItem.canRetry; case "downloadsCmd_openReferrer": return this._dataItem && !!this._dataItem.referrer; case "cmd_delete": @@ -549,8 +550,16 @@ DownloadElementShell.prototype = { }, _retryAsHistoryDownload: function DES__retryAsHistoryDownload() { - // TODO: save in the right location (the current saveURL api does not allow this) - saveURL(this.downloadURI, this._displayName, null, true, true, undefined, document); + // In future we may try to download into the same original target uri, when + // we have it. Though that requires verifying the path is still valid and + // may surprise the user if he wants to be requested every time. + + // For private browsing, try to get document out of the most recent browser + // window, or provide our own if there's no browser window. + let browserWin = RecentWindow.getMostRecentBrowserWindow(); + let initiatingDoc = browserWin ? browserWin.document : document; + saveURL(this.downloadURI, this._displayName, null, true, true, undefined, + initiatingDoc); }, /* nsIController */ @@ -840,6 +849,10 @@ DownloadsPlacesView.prototype = { if (!this._lastSessionDownloadElement) { this._lastSessionDownloadElement = newOrUpdatedShell.element; } + // Some operations like retrying an history download move an element to + // the top of the richlistbox, along with other session downloads. + // More generally, if a new download is added, should be made visible. + this._richlistbox.ensureElementIsVisible(newOrUpdatedShell.element); } else if (aDataItem) { let before = this._lastSessionDownloadElement ? @@ -937,13 +950,15 @@ DownloadsPlacesView.prototype = { this._ensureVisibleTimer = setTimeout(function() { delete this._ensureVisibleTimer; + if (!this._richlistbox.firstChild) + return; let rlRect = this._richlistbox.getBoundingClientRect(); let fcRect = this._richlistbox.firstChild.getBoundingClientRect(); // For simplicity assume border and padding are the same across all sides. // This works as far as there isn't an horizontal scrollbar since fcRect // is relative to the scrolled area. - let offset = fcRect.left - rlRect.left + 1; + let offset = (fcRect.left - rlRect.left) + 1; let firstVisible = document.elementFromPoint(fcRect.left, rlRect.top + offset); if (!firstVisible || firstVisible.localName != "richlistitem") diff --git a/browser/components/downloads/content/download.css b/browser/components/downloads/content/download.css index 93f44a90d1f..7412fa7202f 100644 --- a/browser/components/downloads/content/download.css +++ b/browser/components/downloads/content/download.css @@ -14,34 +14,32 @@ richlistitem.download button { .download-state:-moz-any( [state="6"], /* Blocked (parental) */ [state="8"], /* Blocked (dirty) */ [state="9"]) /* Blocked (policy) */ - .downloadTypeIcon:not(.blockedIcon), + > .downloadTypeIcon:not(.blockedIcon), .download-state:not(:-moz-any([state="6"], /* Blocked (parental) */ [state="8"], /* Blocked (dirty) */ [state="9"]) /* Blocked (policy) */) - .downloadTypeIcon.blockedIcon, + > .downloadTypeIcon.blockedIcon, .download-state:not(:-moz-any([state="-1"],/* Starting (initial) */ [state="5"], /* Starting (queued) */ [state="0"], /* Downloading */ [state="4"], /* Paused */ [state="7"]) /* Scanning */) - .downloadProgress, + > vbox > .downloadProgress, .download-state:not(:-moz-any([state="-1"],/* Starting (initial) */ [state="5"], /* Starting (queued) */ [state="0"], /* Downloading */ [state="4"]) /* Paused */) - .downloadCancel, + > .downloadCancel, -.download-state:not(:-moz-any([state="2"], /* Failed */ - [state="3"]) /* Canceled */) - .downloadRetry, +.download-state[state]:not(:-moz-any([state="2"], /* Failed */ + [state="3"]) /* Canceled */) + > .downloadRetry, .download-state:not( [state="1"] /* Finished */) - .downloadShow, - -.download-state:not([state]) > button + > .downloadShow { display: none; } diff --git a/content/base/public/nsIImageLoadingContent.idl b/content/base/public/nsIImageLoadingContent.idl index 9c95dfe0a98..8734a61c830 100644 --- a/content/base/public/nsIImageLoadingContent.idl +++ b/content/base/public/nsIImageLoadingContent.idl @@ -33,8 +33,8 @@ interface nsIFrame; * this issue. (It could be that the image status on imgIRequest is * sufficient, when combined with the imageBlockingStatus information.) * - * Please make sure to update the HTMLImageElement Web IDL interface to - * mirror this interface when changing it. + * Please make sure to update the HTMLImageElement and SVGImageElement + * Web IDL interfaces to mirror this interface when changing it. */ [scriptable, builtinclass, uuid(497bfb9b-d996-4d1e-a647-8137b0cfc876)] diff --git a/content/html/content/crashtests/828180.html b/content/html/content/crashtests/828180.html new file mode 100644 index 00000000000..055c8a34baf --- /dev/null +++ b/content/html/content/crashtests/828180.html @@ -0,0 +1,5 @@ + diff --git a/content/html/content/crashtests/crashtests.list b/content/html/content/crashtests/crashtests.list index 8e1448cf653..e139545d6b0 100644 --- a/content/html/content/crashtests/crashtests.list +++ b/content/html/content/crashtests/crashtests.list @@ -44,3 +44,4 @@ load 795221-5.xml load 798802-1.html load 811226.html load 819745.html +load 828180.html diff --git a/content/html/content/src/HTMLTableElement.h b/content/html/content/src/HTMLTableElement.h index 2a0550a57fc..d0c2459fe60 100644 --- a/content/html/content/src/HTMLTableElement.h +++ b/content/html/content/src/HTMLTableElement.h @@ -62,7 +62,7 @@ public: } void SetTHead(HTMLTableSectionElement* aTHead, ErrorResult& aError) { - if (!aTHead->IsHTML(nsGkAtoms::thead)) { + if (aTHead && !aTHead->IsHTML(nsGkAtoms::thead)) { aError.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR); return; } @@ -80,7 +80,7 @@ public: } void SetTFoot(HTMLTableSectionElement* aTFoot, ErrorResult& aError) { - if (!aTFoot->IsHTML(nsGkAtoms::tfoot)) { + if (aTFoot && !aTFoot->IsHTML(nsGkAtoms::tfoot)) { aError.Throw(NS_ERROR_DOM_HIERARCHY_REQUEST_ERR); return; } diff --git a/content/svg/content/src/Makefile.in b/content/svg/content/src/Makefile.in index 115a303fb2d..4507c8ff441 100644 --- a/content/svg/content/src/Makefile.in +++ b/content/svg/content/src/Makefile.in @@ -36,7 +36,6 @@ CPPSRCS = \ DOMSVGTransformList.cpp \ nsDOMSVGZoomEvent.cpp \ nsDOMSVGEvent.cpp \ - nsSVGAElement.cpp \ nsSVGAngle.cpp \ nsSVGBoolean.cpp \ nsSVGClass.cpp \ @@ -67,6 +66,7 @@ CPPSRCS = \ nsSVGUnknownElement.cpp \ nsSVGUseElement.cpp \ nsSVGViewBox.cpp \ + SVGAElement.cpp \ SVGAltGlyphElement.cpp \ SVGAngle.cpp \ SVGAnimatedAngle.cpp \ @@ -153,6 +153,7 @@ EXPORTS = \ EXPORTS_NAMESPACES = mozilla/dom EXPORTS_mozilla/dom = \ + SVGAElement.h \ SVGAltGlyphElement.h \ SVGAngle.h \ SVGAnimatedAngle.h \ diff --git a/content/svg/content/src/nsSVGAElement.cpp b/content/svg/content/src/SVGAElement.cpp similarity index 70% rename from content/svg/content/src/nsSVGAElement.cpp rename to content/svg/content/src/SVGAElement.cpp index 5b9c72681ba..214124f0bf3 100644 --- a/content/svg/content/src/nsSVGAElement.cpp +++ b/content/svg/content/src/SVGAElement.cpp @@ -5,7 +5,8 @@ #include "mozilla/Util.h" -#include "nsSVGAElement.h" +#include "mozilla/dom/SVGAElement.h" +#include "mozilla/dom/SVGAElementBinding.h" #include "nsIDOMSVGAElement.h" #include "nsIDOMSVGURIReference.h" #include "nsILink.h" @@ -14,28 +15,34 @@ #include "nsGkAtoms.h" #include "nsContentUtils.h" -using namespace mozilla; -using namespace mozilla::dom; +DOMCI_NODE_DATA(SVGAElement, mozilla::dom::SVGAElement) -nsSVGElement::StringInfo nsSVGAElement::sStringInfo[2] = +NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(A) + +namespace mozilla { +namespace dom { + +JSObject* +SVGAElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap) +{ + return SVGAElementBinding::Wrap(aCx, aScope, this, aTriedToWrap); +} + +nsSVGElement::StringInfo SVGAElement::sStringInfo[2] = { { &nsGkAtoms::href, kNameSpaceID_XLink, true }, { &nsGkAtoms::target, kNameSpaceID_None, true } }; -NS_IMPL_NS_NEW_SVG_ELEMENT(A) - //---------------------------------------------------------------------- // nsISupports methods -NS_IMPL_ADDREF_INHERITED(nsSVGAElement, nsSVGAElementBase) -NS_IMPL_RELEASE_INHERITED(nsSVGAElement, nsSVGAElementBase) +NS_IMPL_ADDREF_INHERITED(SVGAElement, SVGAElementBase) +NS_IMPL_RELEASE_INHERITED(SVGAElement, SVGAElementBase) -DOMCI_NODE_DATA(SVGAElement, nsSVGAElement) - -NS_INTERFACE_TABLE_HEAD(nsSVGAElement) - NS_NODE_INTERFACE_TABLE7(nsSVGAElement, +NS_INTERFACE_TABLE_HEAD(SVGAElement) + NS_NODE_INTERFACE_TABLE7(SVGAElement, nsIDOMNode, nsIDOMElement, nsIDOMSVGElement, @@ -44,16 +51,17 @@ NS_INTERFACE_TABLE_HEAD(nsSVGAElement) nsILink, Link) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGAElement) -NS_INTERFACE_MAP_END_INHERITING(nsSVGAElementBase) +NS_INTERFACE_MAP_END_INHERITING(SVGAElementBase) //---------------------------------------------------------------------- // Implementation -nsSVGAElement::nsSVGAElement(already_AddRefed aNodeInfo) - : nsSVGAElementBase(aNodeInfo), +SVGAElement::SVGAElement(already_AddRefed aNodeInfo) + : SVGAElementBase(aNodeInfo), Link(this) { + SetIsDOMBinding(); } //---------------------------------------------------------------------- @@ -61,18 +69,27 @@ nsSVGAElement::nsSVGAElement(already_AddRefed aNodeInfo) /* readonly attribute nsIDOMSVGAnimatedString href; */ NS_IMETHODIMP -nsSVGAElement::GetHref(nsIDOMSVGAnimatedString * *aHref) +SVGAElement::GetHref(nsIDOMSVGAnimatedString * *aHref) { - return mStringAttributes[HREF].ToDOMAnimatedString(aHref, this); + *aHref = Href().get(); + return NS_OK; } -NS_IMPL_STRING_ATTR(nsSVGAElement, Download, download) +already_AddRefed +SVGAElement::Href() +{ + nsCOMPtr href; + mStringAttributes[HREF].ToDOMAnimatedString(getter_AddRefs(href), this); + return href.forget(); +} + +NS_IMPL_STRING_ATTR(SVGAElement, Download, download) //---------------------------------------------------------------------- // nsINode methods nsresult -nsSVGAElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor) +SVGAElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor) { nsresult rv = Element::PreHandleEvent(aVisitor); NS_ENSURE_SUCCESS(rv, rv); @@ -81,12 +98,12 @@ nsSVGAElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor) } nsresult -nsSVGAElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor) +SVGAElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor) { return PostHandleEventForLinks(aVisitor); } -NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGAElement) +NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGAElement) //---------------------------------------------------------------------- @@ -94,27 +111,37 @@ NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGAElement) /* readonly attribute nsIDOMSVGAnimatedString target; */ NS_IMETHODIMP -nsSVGAElement::GetTarget(nsIDOMSVGAnimatedString * *aTarget) +SVGAElement::GetTarget(nsIDOMSVGAnimatedString * *aTarget) { - return mStringAttributes[TARGET].ToDOMAnimatedString(aTarget, this); + *aTarget = Target().get(); + return NS_OK; } +already_AddRefed +SVGAElement::Target() +{ + nsCOMPtr target; + mStringAttributes[TARGET].ToDOMAnimatedString(getter_AddRefs(target), this); + return target.forget(); +} + + //---------------------------------------------------------------------- // nsIContent methods nsresult -nsSVGAElement::BindToTree(nsIDocument *aDocument, nsIContent *aParent, - nsIContent *aBindingParent, - bool aCompileEventHandlers) +SVGAElement::BindToTree(nsIDocument *aDocument, nsIContent *aParent, + nsIContent *aBindingParent, + bool aCompileEventHandlers) { Link::ResetLinkState(false, Link::ElementHasHref()); - nsresult rv = nsSVGAElementBase::BindToTree(aDocument, aParent, - aBindingParent, - aCompileEventHandlers); + nsresult rv = SVGAElementBase::BindToTree(aDocument, aParent, + aBindingParent, + aCompileEventHandlers); NS_ENSURE_SUCCESS(rv, rv); - + if (aDocument) { aDocument->RegisterPendingLinkUpdate(this); } @@ -123,28 +150,28 @@ nsSVGAElement::BindToTree(nsIDocument *aDocument, nsIContent *aParent, } void -nsSVGAElement::UnbindFromTree(bool aDeep, bool aNullParent) +SVGAElement::UnbindFromTree(bool aDeep, bool aNullParent) { // If this link is ever reinserted into a document, it might // be under a different xml:base, so forget the cached state now. Link::ResetLinkState(false, Link::ElementHasHref()); - + nsIDocument* doc = GetCurrentDoc(); if (doc) { doc->UnregisterPendingLinkUpdate(this); } - nsSVGAElementBase::UnbindFromTree(aDeep, aNullParent); + SVGAElementBase::UnbindFromTree(aDeep, aNullParent); } nsLinkState -nsSVGAElement::GetLinkState() const +SVGAElement::GetLinkState() const { return Link::GetLinkState(); } already_AddRefed -nsSVGAElement::GetHrefURI() const +SVGAElement::GetHrefURI() const { nsCOMPtr hrefURI; return IsLink(getter_AddRefs(hrefURI)) ? hrefURI.forget() : nullptr; @@ -152,7 +179,7 @@ nsSVGAElement::GetHrefURI() const NS_IMETHODIMP_(bool) -nsSVGAElement::IsAttributeMapped(const nsIAtom* name) const +SVGAElement::IsAttributeMapped(const nsIAtom* name) const { static const MappedAttributeEntry* const map[] = { sFEFloodMap, @@ -166,11 +193,11 @@ nsSVGAElement::IsAttributeMapped(const nsIAtom* name) const }; return FindAttributeDependence(name, map) || - nsSVGAElementBase::IsAttributeMapped(name); + SVGAElementBase::IsAttributeMapped(name); } bool -nsSVGAElement::IsFocusable(int32_t *aTabIndex, bool aWithMouse) +SVGAElement::IsFocusable(int32_t *aTabIndex, bool aWithMouse) { nsCOMPtr uri; if (IsLink(getter_AddRefs(uri))) { @@ -188,7 +215,7 @@ nsSVGAElement::IsFocusable(int32_t *aTabIndex, bool aWithMouse) } bool -nsSVGAElement::IsLink(nsIURI** aURI) const +SVGAElement::IsLink(nsIURI** aURI) const { // To be a clickable XLink for styling and interaction purposes, we require: // @@ -237,7 +264,7 @@ nsSVGAElement::IsLink(nsIURI** aURI) const } void -nsSVGAElement::GetLinkTarget(nsAString& aTarget) +SVGAElement::GetLinkTarget(nsAString& aTarget) { mStringAttributes[TARGET].GetAnimValue(aTarget, this); if (aTarget.IsEmpty()) { @@ -261,18 +288,18 @@ nsSVGAElement::GetLinkTarget(nsAString& aTarget) } nsEventStates -nsSVGAElement::IntrinsicState() const +SVGAElement::IntrinsicState() const { - return Link::LinkState() | nsSVGAElementBase::IntrinsicState(); + return Link::LinkState() | SVGAElementBase::IntrinsicState(); } nsresult -nsSVGAElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName, - nsIAtom* aPrefix, const nsAString& aValue, - bool aNotify) +SVGAElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName, + nsIAtom* aPrefix, const nsAString& aValue, + bool aNotify) { - nsresult rv = nsSVGAElementBase::SetAttr(aNameSpaceID, aName, aPrefix, - aValue, aNotify); + nsresult rv = SVGAElementBase::SetAttr(aNameSpaceID, aName, aPrefix, + aValue, aNotify); // The ordering of the parent class's SetAttr call and Link::ResetLinkState // is important here! The attribute is not set until SetAttr returns, and @@ -287,8 +314,8 @@ nsSVGAElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName, } nsresult -nsSVGAElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttr, - bool aNotify) +SVGAElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttr, + bool aNotify) { nsresult rv = nsSVGElement::UnsetAttr(aNameSpaceID, aAttr, aNotify); @@ -308,8 +335,11 @@ nsSVGAElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttr, // nsSVGElement methods nsSVGElement::StringAttributesInfo -nsSVGAElement::GetStringInfo() +SVGAElement::GetStringInfo() { return StringAttributesInfo(mStringAttributes, sStringInfo, ArrayLength(sStringInfo)); } + +} // namespace dom +} // namespace mozilla diff --git a/content/svg/content/src/nsSVGAElement.h b/content/svg/content/src/SVGAElement.h similarity index 68% rename from content/svg/content/src/nsSVGAElement.h rename to content/svg/content/src/SVGAElement.h index 05a4eeb9824..b8b3ffd6af1 100644 --- a/content/svg/content/src/nsSVGAElement.h +++ b/content/svg/content/src/SVGAElement.h @@ -3,28 +3,35 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef NS_SVGAELEMENT_H_ -#define NS_SVGAELEMENT_H_ +#ifndef mozilla_dom_SVGAElement_h +#define mozilla_dom_SVGAElement_h #include "Link.h" #include "nsIDOMSVGAElement.h" #include "nsIDOMSVGURIReference.h" #include "nsILink.h" #include "nsSVGString.h" -#include "SVGGraphicsElement.h" +#include "mozilla/dom/SVGGraphicsElement.h" -typedef mozilla::dom::SVGGraphicsElement nsSVGAElementBase; +nsresult NS_NewSVGAElement(nsIContent **aResult, + already_AddRefed aNodeInfo); -class nsSVGAElement : public nsSVGAElementBase, - public nsIDOMSVGAElement, - public nsIDOMSVGURIReference, - public nsILink, - public mozilla::dom::Link +namespace mozilla { +namespace dom { + +typedef SVGGraphicsElement SVGAElementBase; + +class SVGAElement MOZ_FINAL : public SVGAElementBase, + public nsIDOMSVGAElement, + public nsIDOMSVGURIReference, + public nsILink, + public Link { protected: - friend nsresult NS_NewSVGAElement(nsIContent **aResult, - already_AddRefed aNodeInfo); - nsSVGAElement(already_AddRefed aNodeInfo); + SVGAElement(already_AddRefed aNodeInfo); + friend nsresult (::NS_NewSVGAElement(nsIContent **aResult, + already_AddRefed aNodeInfo)); + virtual JSObject* WrapNode(JSContext *cx, JSObject *scope, bool *triedToWrap) MOZ_OVERRIDE; public: // interfaces: @@ -36,7 +43,7 @@ public: // XXX: I wish we could use virtual inheritance NS_FORWARD_NSIDOMNODE_TO_NSINODE NS_FORWARD_NSIDOMELEMENT_TO_GENERIC - NS_FORWARD_NSIDOMSVGELEMENT(nsSVGAElementBase::) + NS_FORWARD_NSIDOMSVGELEMENT(SVGAElementBase::) // nsINode interface methods virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor); @@ -74,6 +81,11 @@ public: virtual nsXPCClassInfo* GetClassInfo(); virtual nsIDOMNode* AsDOMNode() { return this; } + + // WebIDL + already_AddRefed Href(); + already_AddRefed Target(); + protected: virtual StringAttributesInfo GetStringInfo(); @@ -83,4 +95,7 @@ protected: static StringInfo sStringInfo[2]; }; -#endif // NS_SVGAELEMENT_H_ +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_SVGAElement_h diff --git a/content/svg/content/src/SVGFragmentIdentifier.cpp b/content/svg/content/src/SVGFragmentIdentifier.cpp index 38e434704ac..d3b96749c08 100644 --- a/content/svg/content/src/SVGFragmentIdentifier.cpp +++ b/content/svg/content/src/SVGFragmentIdentifier.cpp @@ -83,11 +83,11 @@ SVGFragmentIdentifier::SaveOldZoomAndPan(dom::SVGSVGElement *root) } } -void +void SVGFragmentIdentifier::RestoreOldZoomAndPan(dom::SVGSVGElement *root) { uint16_t oldZoomAndPan = root->GetZoomAndPanProperty(); - if (oldZoomAndPan != nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_UNKNOWN) { + if (oldZoomAndPan != SVG_ZOOMANDPAN_UNKNOWN) { root->mEnumAttributes[dom::SVGSVGElement::ZOOMANDPAN].SetBaseValue(oldZoomAndPan, root); } else if (root->mEnumAttributes[dom::SVGSVGElement::ZOOMANDPAN].IsExplicitlySet()) { mozilla::ErrorResult error; diff --git a/content/svg/content/src/SVGSVGElement.cpp b/content/svg/content/src/SVGSVGElement.cpp index 245659fe71e..3a5ae4b17d4 100644 --- a/content/svg/content/src/SVGSVGElement.cpp +++ b/content/svg/content/src/SVGSVGElement.cpp @@ -113,8 +113,8 @@ nsSVGElement::LengthInfo SVGSVGElement::sLengthInfo[4] = }; nsSVGEnumMapping SVGSVGElement::sZoomAndPanMap[] = { - {&nsGkAtoms::disable, nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_DISABLE}, - {&nsGkAtoms::magnify, nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_MAGNIFY}, + {&nsGkAtoms::disable, SVG_ZOOMANDPAN_DISABLE}, + {&nsGkAtoms::magnify, SVG_ZOOMANDPAN_MAGNIFY}, {nullptr, 0} }; @@ -122,7 +122,7 @@ nsSVGElement::EnumInfo SVGSVGElement::sEnumInfo[1] = { { &nsGkAtoms::zoomAndPan, sZoomAndPanMap, - nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_MAGNIFY + SVG_ZOOMANDPAN_MAGNIFY } }; @@ -147,11 +147,10 @@ NS_IMPL_ADDREF_INHERITED(SVGSVGElement,SVGSVGElementBase) NS_IMPL_RELEASE_INHERITED(SVGSVGElement,SVGSVGElementBase) NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(SVGSVGElement) - NS_NODE_INTERFACE_TABLE6(SVGSVGElement, nsIDOMNode, nsIDOMElement, + NS_NODE_INTERFACE_TABLE5(SVGSVGElement, nsIDOMNode, nsIDOMElement, nsIDOMSVGElement, nsIDOMSVGSVGElement, - nsIDOMSVGFitToViewBox, - nsIDOMSVGZoomAndPan) + nsIDOMSVGFitToViewBox) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGSVGElement) NS_INTERFACE_MAP_END_INHERITING(SVGSVGElementBase) @@ -738,17 +737,6 @@ SVGSVGElement::PreserveAspectRatio() return ratio.forget(); } -//---------------------------------------------------------------------- -// nsIDOMSVGZoomAndPan methods - -/* attribute unsigned short zoomAndPan; */ -NS_IMETHODIMP -SVGSVGElement::GetZoomAndPan(uint16_t *aZoomAndPan) -{ - *aZoomAndPan = ZoomAndPan(); - return NS_OK; -} - uint16_t SVGSVGElement::ZoomAndPan() { @@ -761,19 +749,11 @@ SVGSVGElement::ZoomAndPan() return mEnumAttributes[ZOOMANDPAN].GetAnimValue(); } -NS_IMETHODIMP -SVGSVGElement::SetZoomAndPan(uint16_t aZoomAndPan) -{ - ErrorResult rv; - SetZoomAndPan(aZoomAndPan, rv); - return rv.ErrorCode(); -} - void SVGSVGElement::SetZoomAndPan(uint16_t aZoomAndPan, ErrorResult& rv) { - if (aZoomAndPan == nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_DISABLE || - aZoomAndPan == nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_MAGNIFY) { + if (aZoomAndPan == SVG_ZOOMANDPAN_DISABLE || + aZoomAndPan == SVG_ZOOMANDPAN_MAGNIFY) { mEnumAttributes[ZOOMANDPAN].SetBaseValue(aZoomAndPan, this); return; } @@ -1530,7 +1510,7 @@ SVGSVGElement::GetZoomAndPanProperty() const if (valPtr) { return reinterpret_cast(valPtr); } - return nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_UNKNOWN; + return SVG_ZOOMANDPAN_UNKNOWN; } bool diff --git a/content/svg/content/src/SVGSVGElement.h b/content/svg/content/src/SVGSVGElement.h index 457bd204e7e..c9684c67a70 100644 --- a/content/svg/content/src/SVGSVGElement.h +++ b/content/svg/content/src/SVGSVGElement.h @@ -11,7 +11,6 @@ #include "nsIDOMSVGLocatable.h" #include "nsISVGPoint.h" #include "nsIDOMSVGSVGElement.h" -#include "nsIDOMSVGZoomAndPan.h" #include "nsSVGEnum.h" #include "nsSVGLength2.h" #include "SVGGraphicsElement.h" @@ -111,8 +110,7 @@ typedef SVGGraphicsElement SVGSVGElementBase; class SVGSVGElement MOZ_FINAL : public SVGSVGElementBase, public nsIDOMSVGSVGElement, - public nsIDOMSVGFitToViewBox, - public nsIDOMSVGZoomAndPan + public nsIDOMSVGFitToViewBox { friend class ::nsSVGOuterSVGFrame; friend class ::nsSVGInnerSVGFrame; @@ -133,7 +131,6 @@ public: NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SVGSVGElement, SVGSVGElementBase) NS_DECL_NSIDOMSVGSVGELEMENT NS_DECL_NSIDOMSVGFITTOVIEWBOX - NS_DECL_NSIDOMSVGZOOMANDPAN // xxx I wish we could use virtual inheritance NS_FORWARD_NSIDOMNODE_TO_NSINODE diff --git a/content/svg/content/src/SVGViewElement.cpp b/content/svg/content/src/SVGViewElement.cpp index 98a3df12ba3..303dbeb931a 100644 --- a/content/svg/content/src/SVGViewElement.cpp +++ b/content/svg/content/src/SVGViewElement.cpp @@ -26,8 +26,8 @@ nsSVGElement::StringListInfo SVGViewElement::sStringListInfo[1] = }; nsSVGEnumMapping SVGViewElement::sZoomAndPanMap[] = { - {&nsGkAtoms::disable, nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_DISABLE}, - {&nsGkAtoms::magnify, nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_MAGNIFY}, + {&nsGkAtoms::disable, SVG_ZOOMANDPAN_DISABLE}, + {&nsGkAtoms::magnify, SVG_ZOOMANDPAN_MAGNIFY}, {nullptr, 0} }; @@ -35,7 +35,7 @@ nsSVGElement::EnumInfo SVGViewElement::sEnumInfo[1] = { { &nsGkAtoms::zoomAndPan, sZoomAndPanMap, - nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_MAGNIFY + SVG_ZOOMANDPAN_MAGNIFY } }; @@ -46,10 +46,9 @@ NS_IMPL_ADDREF_INHERITED(SVGViewElement,SVGViewElementBase) NS_IMPL_RELEASE_INHERITED(SVGViewElement,SVGViewElementBase) NS_INTERFACE_TABLE_HEAD(SVGViewElement) - NS_NODE_INTERFACE_TABLE6(SVGViewElement, nsIDOMNode, nsIDOMElement, + NS_NODE_INTERFACE_TABLE5(SVGViewElement, nsIDOMNode, nsIDOMElement, nsIDOMSVGElement, nsIDOMSVGViewElement, - nsIDOMSVGFitToViewBox, - nsIDOMSVGZoomAndPan) + nsIDOMSVGFitToViewBox) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGViewElement) NS_INTERFACE_MAP_END_INHERITING(SVGViewElementBase) @@ -66,30 +65,11 @@ SVGViewElement::SVGViewElement(already_AddRefed aNodeInfo) NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGViewElement) -//---------------------------------------------------------------------- -// nsIDOMSVGZoomAndPan methods - -/* attribute unsigned short zoomAndPan; */ -NS_IMETHODIMP -SVGViewElement::GetZoomAndPan(uint16_t *aZoomAndPan) -{ - *aZoomAndPan = ZoomAndPan(); - return NS_OK; -} - -NS_IMETHODIMP -SVGViewElement::SetZoomAndPan(uint16_t aZoomAndPan) -{ - ErrorResult rv; - SetZoomAndPan(aZoomAndPan, rv); - return rv.ErrorCode(); -} - void SVGViewElement::SetZoomAndPan(uint16_t aZoomAndPan, ErrorResult& rv) { - if (aZoomAndPan == nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_DISABLE || - aZoomAndPan == nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_MAGNIFY) { + if (aZoomAndPan == SVG_ZOOMANDPAN_DISABLE || + aZoomAndPan == SVG_ZOOMANDPAN_MAGNIFY) { mEnumAttributes[ZOOMANDPAN].SetBaseValue(aZoomAndPan, this); return; } diff --git a/content/svg/content/src/SVGViewElement.h b/content/svg/content/src/SVGViewElement.h index b188b1de4fb..abdd8485bbf 100644 --- a/content/svg/content/src/SVGViewElement.h +++ b/content/svg/content/src/SVGViewElement.h @@ -8,13 +8,16 @@ #include "nsIDOMSVGViewElement.h" #include "nsIDOMSVGFitToViewBox.h" -#include "nsIDOMSVGZoomAndPan.h" #include "nsSVGElement.h" #include "nsSVGEnum.h" #include "nsSVGViewBox.h" #include "SVGAnimatedPreserveAspectRatio.h" #include "SVGStringList.h" +static const unsigned short SVG_ZOOMANDPAN_UNKNOWN = 0; +static const unsigned short SVG_ZOOMANDPAN_DISABLE = 1; +static const unsigned short SVG_ZOOMANDPAN_MAGNIFY = 2; + typedef nsSVGElement SVGViewElementBase; class nsSVGOuterSVGFrame; @@ -30,8 +33,7 @@ class SVGSVGElement; class SVGViewElement : public SVGViewElementBase, public nsIDOMSVGViewElement, - public nsIDOMSVGFitToViewBox, - public nsIDOMSVGZoomAndPan + public nsIDOMSVGFitToViewBox { protected: friend class mozilla::SVGFragmentIdentifier; @@ -48,7 +50,6 @@ public: NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIDOMSVGVIEWELEMENT NS_DECL_NSIDOMSVGFITTOVIEWBOX - NS_DECL_NSIDOMSVGZOOMANDPAN // xxx If xpcom allowed virtual inheritance we wouldn't need to // forward here :-( diff --git a/dom/apps/src/Webapps.jsm b/dom/apps/src/Webapps.jsm index fd3e48be5d6..7555fcaa551 100644 --- a/dom/apps/src/Webapps.jsm +++ b/dom/apps/src/Webapps.jsm @@ -224,6 +224,9 @@ this.DOMApplicationRegistry = { let baseDir; try { baseDir = FileUtils.getDir("coreAppsDir", ["webapps", aId], false); + if (!baseDir.exists()) { + return; + } } catch(e) { // In ENG builds, we don't have apps in coreAppsDir. return; diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index d59b4928fb4..920fa1f1bb9 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -372,7 +372,6 @@ #include "nsIDOMSVGURIReference.h" #include "nsIDOMSVGUseElement.h" #include "nsIDOMSVGViewElement.h" -#include "nsIDOMSVGZoomAndPan.h" #include "nsIDOMSVGZoomEvent.h" #include "nsIImageDocument.h" @@ -3366,7 +3365,6 @@ nsDOMClassInfo::Init() DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGSVGElement) DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFitToViewBox) DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGLocatable) - DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGZoomAndPan) DOM_CLASSINFO_SVG_GRAPHIC_ELEMENT_MAP_ENTRIES DOM_CLASSINFO_MAP_END @@ -3416,7 +3414,6 @@ nsDOMClassInfo::Init() DOM_CLASSINFO_MAP_BEGIN(SVGViewElement, nsIDOMSVGViewElement) DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGFitToViewBox) - DOM_CLASSINFO_MAP_ENTRY(nsIDOMSVGZoomAndPan) DOM_CLASSINFO_SVG_ELEMENT_MAP_ENTRIES DOM_CLASSINFO_MAP_END diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index 8e819b0e68b..7017b3418bc 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -589,6 +589,10 @@ DOMInterfaces = { 'prefable': True, }, +'SVGAElement': { + 'hasInstanceInterface': 'nsIDOMSVGAElement', +}, + 'SVGAnimatedLengthList': { 'nativeType': 'mozilla::DOMSVGAnimatedLengthList', 'headerFile': 'DOMSVGAnimatedLengthList.h' diff --git a/dom/identity/DOMIdentity.jsm b/dom/identity/DOMIdentity.jsm index 294c062cf55..2324244860a 100644 --- a/dom/identity/DOMIdentity.jsm +++ b/dom/identity/DOMIdentity.jsm @@ -127,6 +127,12 @@ RPWatchContext.prototype = { this._mm.sendAsyncMessage("Identity:RP:Watch:OnReady", message); }, + doCancel: function RPWatchContext_oncancel() { + log("doCancel: " + this.id); + let message = new IDDOMMessage({id: this.id}); + this._mm.sendAsyncMessage("Identity:RP:Watch:OnCancel", message); + }, + doError: function RPWatchContext_onerror(aMessage) { log("doError: " + aMessage); } diff --git a/dom/identity/nsDOMIdentity.js b/dom/identity/nsDOMIdentity.js index d1553450fbe..288865cdaec 100644 --- a/dom/identity/nsDOMIdentity.js +++ b/dom/identity/nsDOMIdentity.js @@ -439,7 +439,7 @@ nsDOMIdentity.prototype = { this._rpWatcher.onready(); } break; - case "Identity:RP:Request:OnCancel": + case "Identity:RP:Watch:OnCancel": // Do we have a watcher? if (!this._rpWatcher) { dump("WARNING: Received OnCancel message, but there is no RP watcher\n"); @@ -598,7 +598,7 @@ nsDOMIdentityInternal.prototype = { "Identity:RP:Watch:OnLogin", "Identity:RP:Watch:OnLogout", "Identity:RP:Watch:OnReady", - "Identity:RP:Request:OnCancel", + "Identity:RP:Watch:OnCancel", "Identity:IDP:CallBeginProvisioningCallback", "Identity:IDP:CallGenKeyPairCallback", "Identity:IDP:CallBeginAuthenticationCallback", diff --git a/dom/interfaces/svg/Makefile.in b/dom/interfaces/svg/Makefile.in index 3448cb7f5a0..c126cee1331 100644 --- a/dom/interfaces/svg/Makefile.in +++ b/dom/interfaces/svg/Makefile.in @@ -80,7 +80,6 @@ XPIDLSRCS = \ nsIDOMSVGUnitTypes.idl \ nsIDOMSVGUseElement.idl \ nsIDOMSVGViewElement.idl \ - nsIDOMSVGZoomAndPan.idl \ nsIDOMSVGZoomEvent.idl \ $(NULL) diff --git a/dom/interfaces/svg/nsIDOMSVGZoomAndPan.idl b/dom/interfaces/svg/nsIDOMSVGZoomAndPan.idl deleted file mode 100644 index e1c3294c745..00000000000 --- a/dom/interfaces/svg/nsIDOMSVGZoomAndPan.idl +++ /dev/null @@ -1,18 +0,0 @@ -/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "domstubs.idl" - -[scriptable, uuid(18967370-921a-4245-8158-a279b190abca)] -interface nsIDOMSVGZoomAndPan : nsISupports -{ - // Zoom and Pan Types - const unsigned short SVG_ZOOMANDPAN_UNKNOWN = 0; - const unsigned short SVG_ZOOMANDPAN_DISABLE = 1; - const unsigned short SVG_ZOOMANDPAN_MAGNIFY = 2; - - attribute unsigned short zoomAndPan; - // raises DOMException on setting -}; diff --git a/dom/webidl/SVGAElement.webidl b/dom/webidl/SVGAElement.webidl new file mode 100644 index 00000000000..1f3d793d8a0 --- /dev/null +++ b/dom/webidl/SVGAElement.webidl @@ -0,0 +1,20 @@ +/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. + * + * The origin of this IDL file is + * http://www.w3.org/TR/SVG2/ + * + * Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C + * liability, trademark and document use rules apply. + */ + +interface SVGAnimatedString; + +interface SVGAElement : SVGGraphicsElement { + readonly attribute SVGAnimatedString target; +}; + +SVGAElement implements SVGURIReference; + diff --git a/dom/webidl/WebIDL.mk b/dom/webidl/WebIDL.mk index 4b4cbc141a5..ee8bdbdff3d 100644 --- a/dom/webidl/WebIDL.mk +++ b/dom/webidl/WebIDL.mk @@ -98,6 +98,7 @@ webidl_files = \ Rect.webidl \ RGBColor.webidl \ Screen.webidl \ + SVGAElement.webidl \ SVGAltGlyphElement.webidl \ SVGAngle.webidl \ SVGAnimatedAngle.webidl \ diff --git a/gfx/layers/Layers.h b/gfx/layers/Layers.h index ac53410bc5c..326f83d2dd9 100644 --- a/gfx/layers/Layers.h +++ b/gfx/layers/Layers.h @@ -495,7 +495,11 @@ public: static PRLogModuleInfo* GetLog() { return sLog; } bool IsCompositingCheap(LayersBackend aBackend) - { return LAYERS_BASIC != aBackend; } + { + // LAYERS_NONE is an error state, but in that case we should try to + // avoid loading the compositor! + return LAYERS_BASIC != aBackend && LAYERS_NONE != aBackend; + } virtual bool IsCompositingCheap() { return true; } diff --git a/gfx/layers/ipc/AsyncPanZoomController.cpp b/gfx/layers/ipc/AsyncPanZoomController.cpp index 61fdc240de2..06598773c17 100644 --- a/gfx/layers/ipc/AsyncPanZoomController.cpp +++ b/gfx/layers/ipc/AsyncPanZoomController.cpp @@ -24,7 +24,13 @@ using namespace mozilla::css; namespace mozilla { namespace layers { -const float AsyncPanZoomController::TOUCH_START_TOLERANCE = 1.0f/16.0f; +/** + * Constant describing the tolerance in distance we use, multiplied by the + * device DPI, before we start panning the screen. This is to prevent us from + * accidentally processing taps as touch moves, and from very short/accidental + * touches moving the screen. + */ +static float gTouchStartTolerance = 1.0f/16.0f; static const float EPSILON = 0.0001; @@ -32,19 +38,19 @@ static const float EPSILON = 0.0001; * Maximum amount of time while panning before sending a viewport change. This * will asynchronously repaint the page. It is also forced when panning stops. */ -static const int32_t PAN_REPAINT_INTERVAL = 250; +static int32_t gPanRepaintInterval = 250; /** * Maximum amount of time flinging before sending a viewport change. This will * asynchronously repaint the page. */ -static const int32_t FLING_REPAINT_INTERVAL = 75; +static int32_t gFlingRepaintInterval = 75; /** * Minimum amount of speed along an axis before we begin painting far ahead by * adjusting the displayport. */ -static const float MIN_SKATE_SPEED = 0.7f; +static float gMinSkateSpeed = 0.7f; /** * Duration of a zoom to animation. @@ -72,13 +78,68 @@ static const double MIN_ZOOM = 0.125; * time, we will just pretend that content did not preventDefault any touch * events we dispatched to it. */ -static const int TOUCH_LISTENER_TIMEOUT = 300; +static int gTouchListenerTimeout = 300; /** * Number of samples to store of how long it took to paint after the previous * requests. */ -static const int NUM_PAINT_DURATION_SAMPLES = 3; +static int gNumPaintDurationSamples = 3; + +/** The multiplier we apply to a dimension's length if it is skating. That is, + * if it's going above sMinSkateSpeed. We prefer to increase the size of the + * Y axis because it is more natural in the case that a user is reading a page + * that scrolls up/down. Note that one, both or neither of these may be used + * at any instant. + */ +static float gXSkateSizeMultiplier = 3.0f; +static float gYSkateSizeMultiplier = 3.5f; + +/** The multiplier we apply to a dimension's length if it is stationary. We + * prefer to increase the size of the Y axis because it is more natural in the + * case that a user is reading a page that scrolls up/down. Note that one, + * both or neither of these may be used at any instant. + */ +static float gXStationarySizeMultiplier = 1.5f; +static float gYStationarySizeMultiplier = 2.5f; + +static void ReadAZPCPrefs() +{ + Preferences::AddIntVarCache(&gPanRepaintInterval, "gfx.azpc.pan_repaint_interval", gPanRepaintInterval); + Preferences::AddIntVarCache(&gFlingRepaintInterval, "gfx.azpc.fling_repaint_interval", gFlingRepaintInterval); + Preferences::AddFloatVarCache(&gMinSkateSpeed, "gfx.azpc.min_skate_speed", gMinSkateSpeed); + Preferences::AddIntVarCache(&gTouchListenerTimeout, "gfx.azpc.touch_listener_timeout", gTouchListenerTimeout); + Preferences::AddIntVarCache(&gNumPaintDurationSamples, "gfx.azpc.num_paint_duration_samples", gNumPaintDurationSamples); + Preferences::AddFloatVarCache(&gTouchStartTolerance, "gfx.azpc.touch_start_tolerance", gTouchStartTolerance); + Preferences::AddFloatVarCache(&gXSkateSizeMultiplier, "gfx.azpc.x_skate_size_multiplier", gXSkateSizeMultiplier); + Preferences::AddFloatVarCache(&gYSkateSizeMultiplier, "gfx.azpc.y_skate_size_multiplier", gYSkateSizeMultiplier); + Preferences::AddFloatVarCache(&gXStationarySizeMultiplier, "gfx.azpc.x_stationary_size_multiplier", gXStationarySizeMultiplier); + Preferences::AddFloatVarCache(&gYStationarySizeMultiplier, "gfx.azpc.y_stationary_size_multiplier", gYStationarySizeMultiplier); +} + +class ReadAZPCPref MOZ_FINAL : public nsRunnable { +public: + NS_IMETHOD Run() + { + ReadAZPCPrefs(); + return NS_OK; + } +}; + +static void InitAZPCPrefs() +{ + static bool sInitialized = false; + if (sInitialized) + return; + + sInitialized = true; + if (NS_IsMainThread()) { + ReadAZPCPrefs(); + } else { + // We have to dispatch an event to the main thread to read the pref. + NS_DispatchToMainThread(new ReadAZPCPref()); + } +} AsyncPanZoomController::AsyncPanZoomController(GeckoContentController* aGeckoContentController, GestureBehavior aGestures) @@ -106,6 +167,9 @@ AsyncPanZoomController::AsyncPanZoomController(GeckoContentController* aGeckoCon mDelayPanning(false) { MOZ_ASSERT(NS_IsMainThread()); + + InitAZPCPrefs(); + if (aGestures == USE_GESTURE_DETECTOR) { mGestureEventListener = new GestureEventListener(this); } @@ -127,6 +191,12 @@ AsyncPanZoomController::~AsyncPanZoomController() { } +/* static */float +AsyncPanZoomController::GetTouchStartTolerance() +{ + return gTouchStartTolerance; +} + static gfx::Point WidgetSpaceToCompensatedViewportSpace(const gfx::Point& aPoint, gfxFloat aCurrentZoom) @@ -231,7 +301,7 @@ nsEventStatus AsyncPanZoomController::ReceiveInputEvent(const InputData& aEvent) MessageLoop::current()->PostDelayedTask( FROM_HERE, mTouchListenerTimeoutTask, - TOUCH_LISTENER_TIMEOUT); + gTouchListenerTimeout); } } return nsEventStatus_eConsumeNoDefault; @@ -263,7 +333,7 @@ nsEventStatus AsyncPanZoomController::HandleInputEvent(const InputData& aEvent) MessageLoop::current()->PostDelayedTask( FROM_HERE, mTouchListenerTimeoutTask, - TOUCH_LISTENER_TIMEOUT); + gTouchListenerTimeout); } return nsEventStatus_eConsumeNoDefault; } @@ -364,7 +434,7 @@ nsEventStatus AsyncPanZoomController::OnTouchMove(const MultiTouchInput& aEvent) return nsEventStatus_eIgnore; case TOUCHING: { - float panThreshold = TOUCH_START_TOLERANCE * mDPI; + float panThreshold = gTouchStartTolerance * mDPI; UpdateWithTouchAtDevicePoint(aEvent); if (PanDistance() < panThreshold) { @@ -697,7 +767,7 @@ void AsyncPanZoomController::TrackTouch(const MultiTouchInput& aEvent) { ScheduleComposite(); TimeDuration timePaintDelta = TimeStamp::Now() - mPreviousPaintStartTime; - if (timePaintDelta.ToMilliseconds() > PAN_REPAINT_INTERVAL) { + if (timePaintDelta.ToMilliseconds() > gPanRepaintInterval) { RequestContentRepaint(); } } @@ -734,7 +804,7 @@ bool AsyncPanZoomController::DoFling(const TimeDuration& aDelta) { mY.GetDisplacementForDuration(inverseResolution, aDelta) )); TimeDuration timePaintDelta = TimeStamp::Now() - mPreviousPaintStartTime; - if (timePaintDelta.ToMilliseconds() > FLING_REPAINT_INTERVAL) { + if (timePaintDelta.ToMilliseconds() > gFlingRepaintInterval) { RequestContentRepaint(); } @@ -803,7 +873,7 @@ bool AsyncPanZoomController::EnlargeDisplayPortAlongAxis(float aSkateSizeMultipl float* aDisplayPortOffset, float* aDisplayPortLength) { - if (fabsf(aVelocity) > MIN_SKATE_SPEED) { + if (fabsf(aVelocity) > gMinSkateSpeed) { // Enlarge the area we paint. *aDisplayPortLength = aCompositionBounds * aSkateSizeMultiplier; // Position the area we paint such that all of the excess that extends past @@ -835,21 +905,6 @@ const gfx::Rect AsyncPanZoomController::CalculatePendingDisplayPort( const gfx::Point& aAcceleration, double aEstimatedPaintDuration) { - // The multiplier we apply to a dimension's length if it is skating. That is, - // if it's going above MIN_SKATE_SPEED. We prefer to increase the size of the - // Y axis because it is more natural in the case that a user is reading a page - // that scrolls up/down. Note that one, both or neither of these may be used - // at any instant. - const float X_SKATE_SIZE_MULTIPLIER = 3.0f; - const float Y_SKATE_SIZE_MULTIPLIER = 3.5f; - - // The multiplier we apply to a dimension's length if it is stationary. We - // prefer to increase the size of the Y axis because it is more natural in the - // case that a user is reading a page that scrolls up/down. Note that one, - // both or neither of these may be used at any instant. - const float X_STATIONARY_SIZE_MULTIPLIER = 1.5f; - const float Y_STATIONARY_SIZE_MULTIPLIER = 2.5f; - // If we don't get an estimated paint duration, we probably don't have any // data. In this case, we're dealing with either a stationary frame or a first // paint. In either of these cases, we can just assume it'll take 1 second to @@ -866,18 +921,18 @@ const gfx::Rect AsyncPanZoomController::CalculatePendingDisplayPort( gfx::Point scrollOffset = aFrameMetrics.mScrollOffset; gfx::Rect displayPort(0, 0, - compositionBounds.width * X_STATIONARY_SIZE_MULTIPLIER, - compositionBounds.height * Y_STATIONARY_SIZE_MULTIPLIER); + compositionBounds.width * gXStationarySizeMultiplier, + compositionBounds.height * gYStationarySizeMultiplier); // If there's motion along an axis of movement, and it's above a threshold, // then we want to paint a larger area in the direction of that motion so that // it's less likely to checkerboard. bool enlargedX = EnlargeDisplayPortAlongAxis( - X_SKATE_SIZE_MULTIPLIER, estimatedPaintDuration, + gXSkateSizeMultiplier, estimatedPaintDuration, compositionBounds.width, aVelocity.x, aAcceleration.x, &displayPort.x, &displayPort.width); bool enlargedY = EnlargeDisplayPortAlongAxis( - Y_SKATE_SIZE_MULTIPLIER, estimatedPaintDuration, + gYSkateSizeMultiplier, estimatedPaintDuration, compositionBounds.height, aVelocity.y, aAcceleration.y, &displayPort.y, &displayPort.height); @@ -1162,7 +1217,7 @@ void AsyncPanZoomController::NotifyLayersUpdated(const FrameMetrics& aViewportFr if (mWaitingForContentToPaint) { // Remove the oldest sample we have if adding a new sample takes us over our // desired number of samples. - if (mPreviousPaintDurations.Length() >= NUM_PAINT_DURATION_SAMPLES) { + if (mPreviousPaintDurations.Length() >= gNumPaintDurationSamples) { mPreviousPaintDurations.RemoveElementAt(0); } diff --git a/gfx/layers/ipc/AsyncPanZoomController.h b/gfx/layers/ipc/AsyncPanZoomController.h index 3363d070962..03b982e5a12 100644 --- a/gfx/layers/ipc/AsyncPanZoomController.h +++ b/gfx/layers/ipc/AsyncPanZoomController.h @@ -68,7 +68,7 @@ public: * accidentally processing taps as touch moves, and from very short/accidental * touches moving the screen. */ - static const float TOUCH_START_TOLERANCE; + static float GetTouchStartTolerance(); AsyncPanZoomController(GeckoContentController* aController, GestureBehavior aGestures = DEFAULT_GESTURES); diff --git a/gfx/layers/ipc/Axis.cpp b/gfx/layers/ipc/Axis.cpp index e65cf57706b..e0a673ac51c 100644 --- a/gfx/layers/ipc/Axis.cpp +++ b/gfx/layers/ipc/Axis.cpp @@ -6,6 +6,7 @@ #include "Axis.h" #include "AsyncPanZoomController.h" +#include "mozilla/Preferences.h" namespace mozilla { namespace layers { @@ -18,18 +19,18 @@ static const float EPSILON = 0.0001f; * or we get a touch point very far away from the previous position for some * reason. */ -static const float MAX_EVENT_ACCELERATION = 999.0f; +static float gMaxEventAcceleration = 999.0f; /** * Amount of friction applied during flings. */ -static const float FLING_FRICTION = 0.007f; +static float gFlingFriction = 0.007f; /** * Threshold for velocity beneath which we turn off any acceleration we had * during repeated flings. */ -static const float VELOCITY_THRESHOLD = 0.14f; +static float gVelocityThreshold = 0.14f; /** * Amount of acceleration we multiply in each time the user flings in one @@ -39,14 +40,47 @@ static const float VELOCITY_THRESHOLD = 0.14f; * slow down enough, or if they put their finger down without moving it for a * moment (or in the opposite direction). */ -static const float ACCELERATION_MULTIPLIER = 1.125f; +static float gAccelerationMultiplier = 1.125f; /** * When flinging, if the velocity goes below this number, we just stop the * animation completely. This is to prevent asymptotically approaching 0 * velocity and rerendering unnecessarily. */ -static const float FLING_STOPPED_THRESHOLD = 0.01f; +static float gFlingStoppedThreshold = 0.01f; + +static void ReadAxisPrefs() +{ + Preferences::AddFloatVarCache(&gMaxEventAcceleration, "gfx.axis.max_event_acceleration", gMaxEventAcceleration); + Preferences::AddFloatVarCache(&gFlingFriction, "gfx.axis.fling_friction", gFlingFriction); + Preferences::AddFloatVarCache(&gVelocityThreshold, "gfx.axis.velocity_threshold", gVelocityThreshold); + Preferences::AddFloatVarCache(&gAccelerationMultiplier, "gfx.axis.acceleration_multiplier", gAccelerationMultiplier); + Preferences::AddFloatVarCache(&gFlingStoppedThreshold, "gfx.axis.fling_stopped_threshold", gFlingStoppedThreshold); +} + +class ReadAxisPref MOZ_FINAL : public nsRunnable { +public: + NS_IMETHOD Run() + { + ReadAxisPrefs(); + return NS_OK; + } +}; + +static void InitAxisPrefs() +{ + static bool sInitialized = false; + if (sInitialized) + return; + + sInitialized = true; + if (NS_IsMainThread()) { + ReadAxisPrefs(); + } else { + // We have to dispatch an event to the main thread to read the pref. + NS_DispatchToMainThread(new ReadAxisPref()); + } +} Axis::Axis(AsyncPanZoomController* aAsyncPanZoomController) : mPos(0.0f), @@ -54,14 +88,14 @@ Axis::Axis(AsyncPanZoomController* aAsyncPanZoomController) mAcceleration(0), mAsyncPanZoomController(aAsyncPanZoomController) { - + InitAxisPrefs(); } void Axis::UpdateWithTouchAtDevicePoint(int32_t aPos, const TimeDuration& aTimeDelta) { float newVelocity = (mPos - aPos) / aTimeDelta.ToMilliseconds(); bool curVelocityIsLow = fabsf(newVelocity) < 0.01f; - bool curVelocityBelowThreshold = fabsf(newVelocity) < VELOCITY_THRESHOLD; + bool curVelocityBelowThreshold = fabsf(newVelocity) < gVelocityThreshold; bool directionChange = (mVelocity > 0) != (newVelocity > 0); // If we've changed directions, or the current velocity threshold, stop any @@ -75,7 +109,7 @@ void Axis::UpdateWithTouchAtDevicePoint(int32_t aPos, const TimeDuration& aTimeD if (curVelocityIsLow || (directionChange && fabs(newVelocity) - EPSILON <= 0.0f)) { mVelocity = newVelocity; } else { - float maxChange = fabsf(mVelocity * aTimeDelta.ToMilliseconds() * MAX_EVENT_ACCELERATION); + float maxChange = fabsf(mVelocity * aTimeDelta.ToMilliseconds() * gMaxEventAcceleration); mVelocity = NS_MIN(mVelocity + maxChange, NS_MAX(mVelocity - maxChange, newVelocity)); } @@ -89,7 +123,7 @@ void Axis::StartTouch(int32_t aPos) { } float Axis::GetDisplacementForDuration(float aScale, const TimeDuration& aDelta) { - if (fabsf(mVelocity) < VELOCITY_THRESHOLD) { + if (fabsf(mVelocity) < gVelocityThreshold) { mAcceleration = 0; } @@ -121,14 +155,14 @@ void Axis::CancelTouch() { } bool Axis::FlingApplyFrictionOrCancel(const TimeDuration& aDelta) { - if (fabsf(mVelocity) <= FLING_STOPPED_THRESHOLD) { + if (fabsf(mVelocity) <= gFlingStoppedThreshold) { // If the velocity is very low, just set it to 0 and stop the fling, // otherwise we'll just asymptotically approach 0 and the user won't // actually see any changes. mVelocity = 0.0f; return false; } else { - mVelocity *= NS_MAX(1.0f - FLING_FRICTION * aDelta.ToMilliseconds(), 0.0); + mVelocity *= NS_MAX(1.0f - gFlingFriction * aDelta.ToMilliseconds(), 0.0); } return true; } @@ -226,7 +260,7 @@ float Axis::GetVelocity() { } float Axis::GetAccelerationFactor() { - return powf(ACCELERATION_MULTIPLIER, NS_MAX(0, (mAcceleration - 4) * 3)); + return powf(gAccelerationMultiplier, NS_MAX(0, (mAcceleration - 4) * 3)); } float Axis::GetCompositionEnd() { diff --git a/gfx/layers/ipc/GestureEventListener.cpp b/gfx/layers/ipc/GestureEventListener.cpp index 39d2572765f..4bab0ee926e 100644 --- a/gfx/layers/ipc/GestureEventListener.cpp +++ b/gfx/layers/ipc/GestureEventListener.cpp @@ -105,7 +105,7 @@ nsEventStatus GestureEventListener::HandleInputEvent(const InputData& aEvent) nsIntPoint touch = (nsIntPoint&)event.mTouches[0].mScreenPoint; if (mTouches.Length() == 1 && NS_hypot(mTouchStartPosition.x - touch.x, mTouchStartPosition.y - touch.y) > - mAsyncPanZoomController->GetDPI() * AsyncPanZoomController::TOUCH_START_TOLERANCE) + mAsyncPanZoomController->GetDPI() * mAsyncPanZoomController->GetTouchStartTolerance()) { HandleTapCancel(event); } diff --git a/gfx/layers/opengl/LayerManagerOGL.h b/gfx/layers/opengl/LayerManagerOGL.h index 4a54edf87a0..4bba11eca6d 100644 --- a/gfx/layers/opengl/LayerManagerOGL.h +++ b/gfx/layers/opengl/LayerManagerOGL.h @@ -10,6 +10,7 @@ #include "mozilla/layers/ShadowLayers.h" #include "mozilla/TimeStamp.h" +#include "nsPoint.h" #ifdef XP_WIN #include @@ -435,12 +436,20 @@ enum LayerRenderStateFlags { }; struct LayerRenderState { - LayerRenderState() : mSurface(nullptr), mFlags(0) + LayerRenderState() : mSurface(nullptr), mFlags(0), mHasOwnOffset(false) {} LayerRenderState(SurfaceDescriptor* aSurface, uint32_t aFlags = 0) : mSurface(aSurface) , mFlags(aFlags) + , mHasOwnOffset(false) + {} + + LayerRenderState(SurfaceDescriptor* aSurface, nsIntPoint aOffset, uint32_t aFlags = 0) + : mSurface(aSurface) + , mFlags(aFlags) + , mOffset(aOffset) + , mHasOwnOffset(true) {} bool YFlipped() const @@ -451,6 +460,8 @@ struct LayerRenderState { SurfaceDescriptor* mSurface; uint32_t mFlags; + nsIntPoint mOffset; + bool mHasOwnOffset; }; /** diff --git a/gfx/layers/opengl/ThebesLayerOGL.cpp b/gfx/layers/opengl/ThebesLayerOGL.cpp index 5147120ee80..432ada089aa 100644 --- a/gfx/layers/opengl/ThebesLayerOGL.cpp +++ b/gfx/layers/opengl/ThebesLayerOGL.cpp @@ -98,8 +98,8 @@ public: bool Initialised() { return mInitialised; } -protected: virtual nsIntPoint GetOriginOffset() = 0; +protected: GLContext* gl() const { return mOGLLayer->gl(); } @@ -343,7 +343,6 @@ public: return mTexImage ? mTexImage->GetBackingSurface() : nullptr; } -protected: virtual nsIntPoint GetOriginOffset() { return BufferRect().TopLeft() - BufferRotation(); } @@ -366,6 +365,10 @@ public: virtual PaintState BeginPaint(ContentType aContentType, uint32_t aFlags); + virtual nsIntPoint GetOriginOffset() { + return mBufferRect.TopLeft() - mBufferRotation; + } + protected: enum XSide { @@ -376,10 +379,6 @@ protected: }; nsIntRect GetQuadrantRectangle(XSide aXSide, YSide aYSide); - virtual nsIntPoint GetOriginOffset() { - return mBufferRect.TopLeft() - mBufferRotation; - } - private: nsIntRect mBufferRect; nsIntPoint mBufferRotation; @@ -947,7 +946,6 @@ public: return mBufferRotation; } -protected: virtual nsIntPoint GetOriginOffset() { return mBufferRect.TopLeft() - mBufferRotation; } @@ -1156,7 +1154,7 @@ ShadowThebesLayerOGL::GetRenderState() } uint32_t flags = (mBuffer->Rotation() != nsIntPoint()) ? LAYER_RENDER_STATE_BUFFER_ROTATION : 0; - return LayerRenderState(&mBufferDescriptor, flags); + return LayerRenderState(&mBufferDescriptor, mBuffer->GetOriginOffset(), flags); } bool diff --git a/js/src/ion/IonFrames.cpp b/js/src/ion/IonFrames.cpp index cd4ddfb6bbf..08bc6672360 100644 --- a/js/src/ion/IonFrames.cpp +++ b/js/src/ion/IonFrames.cpp @@ -1042,8 +1042,12 @@ InlineFrameIterator::scopeChain() const // scopeChain Value v = s.read(); - JS_ASSERT(v.isObject()); - return &v.toObject(); + if (v.isObject()) { + JS_ASSERT_IF(script()->hasAnalysis(), script()->analysis()->usesScopeChain()); + return &v.toObject(); + } + + return callee()->environment(); } JSObject * diff --git a/layout/ipc/RenderFrameParent.cpp b/layout/ipc/RenderFrameParent.cpp index 1dcf3956e16..af125ace64b 100644 --- a/layout/ipc/RenderFrameParent.cpp +++ b/layout/ipc/RenderFrameParent.cpp @@ -600,8 +600,11 @@ RenderFrameParent::RenderFrameParent(nsFrameLoader* aFrameLoader, *aId = 0; nsRefPtr lm = GetFrom(mFrameLoader); - *aBackendType = lm->GetBackendType(); - *aMaxTextureSize = lm->GetMaxTextureSize(); + // Perhaps the document containing this frame currently has no presentation? + if (lm) { + *aBackendType = lm->GetBackendType(); + *aMaxTextureSize = lm->GetMaxTextureSize(); + } if (CompositorParent::CompositorLoop()) { // Our remote frame will push layers updates to the compositor, diff --git a/layout/svg/nsSVGAFrame.cpp b/layout/svg/nsSVGAFrame.cpp index 6ff9c54973b..2e66dfdb3ba 100644 --- a/layout/svg/nsSVGAFrame.cpp +++ b/layout/svg/nsSVGAFrame.cpp @@ -5,7 +5,7 @@ // Keep in (case-insensitive) order: #include "gfxMatrix.h" -#include "nsSVGAElement.h" +#include "mozilla/dom/SVGAElement.h" #include "nsSVGIntegrationUtils.h" #include "nsSVGTSpanFrame.h" #include "nsSVGUtils.h" @@ -153,7 +153,7 @@ nsSVGAFrame::GetCanvasTM(uint32_t aFor) NS_ASSERTION(mParent, "null parent"); nsSVGContainerFrame *parent = static_cast(mParent); - nsSVGAElement *content = static_cast(mContent); + dom::SVGAElement *content = static_cast(mContent); gfxMatrix tm = content->PrependLocalTransformsTo(parent->GetCanvasTM(aFor)); diff --git a/mobile/android/app/Makefile.in b/mobile/android/app/Makefile.in index d2be0c8ef0d..54545dae4dc 100644 --- a/mobile/android/app/Makefile.in +++ b/mobile/android/app/Makefile.in @@ -46,6 +46,7 @@ DEFINES += \ -DAPP_NAME=$(MOZ_APP_NAME) \ -DAPP_VERSION=$(MOZ_APP_VERSION) \ -DMOZ_UPDATER=$(MOZ_UPDATER) \ + -DMOZ_APP_UA_NAME=$(MOZ_APP_UA_NAME) \ $(NULL) ifdef MOZ_PKG_SPECIAL diff --git a/mobile/android/app/mobile.js b/mobile/android/app/mobile.js index edbeb27194c..126e46953bb 100644 --- a/mobile/android/app/mobile.js +++ b/mobile/android/app/mobile.js @@ -568,6 +568,8 @@ pref("browser.safebrowsing.reportMalwareErrorURL", "http://%LOCALE%.malware-erro pref("browser.safebrowsing.warning.infoURL", "http://www.mozilla.com/%LOCALE%/firefox/phishing-protection/"); pref("browser.safebrowsing.malware.reportURL", "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site="); +pref("browser.safebrowsing.id", "@MOZ_APP_UA_NAME@"); + // Name of the about: page contributed by safebrowsing to handle display of error // pages on phishing/malware hits. (bug 399233) pref("urlclassifier.alternate_error_page", "blocked"); diff --git a/mobile/android/chrome/content/Readability.js b/mobile/android/chrome/content/Readability.js index db708b222d6..7b147820453 100644 --- a/mobile/android/chrome/content/Readability.js +++ b/mobile/android/chrome/content/Readability.js @@ -26,6 +26,7 @@ var Readability = function(uri, doc) { this._doc = doc; this._biggestFrame = false; this._articleByline = null; + this._articleDir = null; // Start with all flags set this._flags = this.FLAG_STRIP_UNLIKELYS | @@ -406,6 +407,9 @@ Readability.prototype = { page = page ? page : this._doc.body; let pageCacheHtml = page.innerHTML; + // Check if any "dir" is set on the toplevel document element + this._articleDir = doc.documentElement.getAttribute("dir"); + while (true) { let stripUnlikelyCandidates = this._flagIsActive(this.FLAG_STRIP_UNLIKELYS); let allElements = page.getElementsByTagName('*'); @@ -1432,6 +1436,7 @@ Readability.prototype = { return { title: articleTitle, byline: this._articleByline, + dir: this._articleDir, content: articleContent.innerHTML }; } }; diff --git a/mobile/android/chrome/content/aboutReader.js b/mobile/android/chrome/content/aboutReader.js index 6707a65b9f5..9632e2601f7 100644 --- a/mobile/android/chrome/content/aboutReader.js +++ b/mobile/android/chrome/content/aboutReader.js @@ -427,6 +427,15 @@ AboutReader.prototype = { } }, + _maybeSetTextDirection: function Read_maybeSetTextDirection(article){ + if(!article.dir) + return; + + //Set "dir" attribute on content + this._contentElement.setAttribute("dir", article.dir); + this._headerElement.setAttribute("dir", article.dir); + }, + _showError: function Reader_showError(error) { this._headerElement.style.display = "none"; this._contentElement.style.display = "none"; @@ -460,6 +469,7 @@ AboutReader.prototype = { this._contentElement.innerHTML = ""; this._contentElement.appendChild(contentFragment); this._updateImageMargins(); + this._maybeSetTextDirection(article); this._contentElement.style.display = "block"; diff --git a/mobile/android/components/Makefile.in b/mobile/android/components/Makefile.in index 90dc3510886..3d3addde484 100644 --- a/mobile/android/components/Makefile.in +++ b/mobile/android/components/Makefile.in @@ -39,14 +39,4 @@ EXTRA_COMPONENTS = \ BlocklistPrompt.js \ $(NULL) -ifdef MOZ_SAFE_BROWSING -DEFINES += \ - -DMOZ_APP_UA_NAME=$(MOZ_APP_UA_NAME) \ - $(NULL) - -EXTRA_PP_JS_MODULES = \ - SafeBrowsing.jsm \ - $(NULL) -endif - include $(topsrcdir)/config/rules.mk diff --git a/mobile/android/components/SafeBrowsing.jsm b/mobile/android/components/SafeBrowsing.jsm deleted file mode 100644 index 82fca71d77e..00000000000 --- a/mobile/android/components/SafeBrowsing.jsm +++ /dev/null @@ -1,182 +0,0 @@ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ - -this.EXPORTED_SYMBOLS = ["SafeBrowsing"]; - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cu = Components.utils; - -Cu.import("resource://gre/modules/Services.jsm"); - -const phishingList = "goog-phish-shavar"; -const malwareList = "goog-malware-shavar"; - -var debug = false; - -function log(...stuff) { - if (!debug) - return; - - let msg = "SafeBrowsing: " + stuff.join(" "); - Services.console.logStringMessage(msg); - dump(msg + "\n"); -} - -this.SafeBrowsing = { - - init: function() { - if (this.initialized) { - log("Already initialized"); - return; - } - - Services.prefs.addObserver("browser.safebrowsing", this.readPrefs, false); - this.readPrefs(); - - // Register our two types of tables, and add custom Mozilla entries - let listManager = Cc["@mozilla.org/url-classifier/listmanager;1"]. - getService(Ci.nsIUrlListManager); - listManager.registerTable(phishingList, false); - listManager.registerTable(malwareList, false); - this.addMozEntries(); - - this.controlUpdateChecking(); - this.initialized = true; - - log("init() finished"); - }, - - - initialized: false, - phishingEnabled: false, - malwareEnabled: false, - - updateURL: null, - keyURL: null, - gethashURL: null, - - reportURL: null, - reportGenericURL: null, - reportErrorURL: null, - reportPhishURL: null, - reportMalwareURL: null, - reportMalwareErrorURL: null, - - - getReportURL: function(kind) { - return this["report" + kind + "URL"]; - }, - - - readPrefs: function() { - log("reading prefs"); - - debug = Services.prefs.getBoolPref("browser.safebrowsing.debug"); - this.phishingEnabled = Services.prefs.getBoolPref("browser.safebrowsing.enabled"); - this.malwareEnabled = Services.prefs.getBoolPref("browser.safebrowsing.malware.enabled"); - this.updateProviderURLs(); - - // XXX The listManager backend gets confused if this is called before the - // lists are registered. So only call it here when a pref changes, and not - // when doing initialization. I expect to refactor this later, so pardon the hack. - if (this.initialized) - this.controlUpdateChecking(); - }, - - - updateProviderURLs: function() { -#ifdef USE_HISTORIC_SAFEBROWSING_ID - let clientID = "navclient-auto-ffox"; -#else -#expand let clientID = __MOZ_APP_UA_NAME__; -#endif - - log("initializing safe browsing URLs"); - let basePref = "browser.safebrowsing."; - - // Urls to HTML report pages - this.reportURL = Services.urlFormatter.formatURLPref(basePref + "reportURL"); - this.reportGenericURL = Services.urlFormatter.formatURLPref(basePref + "reportGenericURL"); - this.reportErrorURL = Services.urlFormatter.formatURLPref(basePref + "reportErrorURL"); - this.reportPhishURL = Services.urlFormatter.formatURLPref(basePref + "reportPhishURL"); - this.reportMalwareURL = Services.urlFormatter.formatURLPref(basePref + "reportMalwareURL"); - this.reportMalwareErrorURL = Services.urlFormatter.formatURLPref(basePref + "reportMalwareErrorURL"); - - // Urls used to update DB - this.updateURL = Services.urlFormatter.formatURLPref(basePref + "updateURL"); - this.keyURL = Services.urlFormatter.formatURLPref(basePref + "keyURL"); - this.gethashURL = Services.urlFormatter.formatURLPref(basePref + "gethashURL"); - - this.updateURL = this.updateURL.replace("SAFEBROWSING_ID", clientID); - this.keyURL = this.keyURL.replace("SAFEBROWSING_ID", clientID); - this.gethashURL = this.gethashURL.replace("SAFEBROWSING_ID", clientID); - - let listManager = Cc["@mozilla.org/url-classifier/listmanager;1"]. - getService(Ci.nsIUrlListManager); - - listManager.setUpdateUrl(this.updateURL); - // XXX Bug 779317 - setKeyUrl has the side effect of fetching a key from the server. - // This shouldn't happen if anti-phishing/anti-malware is disabled. - if (this.phishingEnabled || this.malwareEnabled) - listManager.setKeyUrl(this.keyURL); - listManager.setGethashUrl(this.gethashURL); - }, - - - controlUpdateChecking: function() { - log("phishingEnabled:", this.phishingEnabled, "malwareEnabled:", this.malwareEnabled); - - let listManager = Cc["@mozilla.org/url-classifier/listmanager;1"]. - getService(Ci.nsIUrlListManager); - - if (this.phishingEnabled) - listManager.enableUpdate(phishingList); - else - listManager.disableUpdate(phishingList); - - if (this.malwareEnabled) - listManager.enableUpdate(malwareList); - else - listManager.disableUpdate(malwareList); - }, - - - addMozEntries: function() { - // Add test entries to the DB. - // XXX bug 779008 - this could be done by DB itself? - const phishURL = "mozilla.org/firefox/its-a-trap.html"; - const malwareURL = "mozilla.org/firefox/its-an-attack.html"; - - let update = "n:1000\ni:test-malware-simple\nad:1\n" + - "a:1:32:" + malwareURL.length + "\n" + - malwareURL; - update += "n:1000\ni:test-phish-simple\nad:1\n" + - "a:1:32:" + phishURL.length + "\n" + - phishURL; - log("addMozEntries:", update); - - let db = Cc["@mozilla.org/url-classifier/dbservice;1"]. - getService(Ci.nsIUrlClassifierDBService); - - // nsIUrlClassifierUpdateObserver - let dummyListener = { - updateUrlRequested: function() { }, - streamFinished: function() { }, - updateError: function() { }, - updateSuccess: function() { } - }; - - try { - db.beginUpdate(dummyListener, "test-malware-simple,test-phish-simple", ""); - db.beginStream("", ""); - db.updateStream(update); - db.finishStream(); - db.finishUpdate(); - } catch(ex) { - // beginUpdate will throw harmlessly if there's an existing update in progress, ignore failures. - log("addMozEntries failed!", ex); - } - }, -}; diff --git a/mobile/android/themes/core/aboutReader.css b/mobile/android/themes/core/aboutReader.css index 8a29fa7f7f2..77a66229b50 100644 --- a/mobile/android/themes/core/aboutReader.css +++ b/mobile/android/themes/core/aboutReader.css @@ -31,7 +31,7 @@ body { } .header { - text-align: left; + text-align: start; display: none; } @@ -259,7 +259,7 @@ body { margin: 0px !important; margin-bottom: 20px !important; padding: 0px !important; - padding-left: 16px !important; + -moz-padding-start: 16px !important; border: 0px !important; border-left: 2px solid !important; } @@ -283,12 +283,12 @@ body { } .content ul { - padding-left: 30px !important; + -moz-padding-start: 30px !important; list-style: disk !important; } .content ol { - padding-left: 35px !important; + -moz-padding-start: 35px !important; list-style: decimal !important; } @@ -378,7 +378,7 @@ body { } .dropdown-popup { - text-align: left; + text-align: start; position: absolute; left: 0px; z-index: 1000; diff --git a/mobile/android/themes/core/aboutReaderContent.css b/mobile/android/themes/core/aboutReaderContent.css index 2b058d05ef8..11bdd05b75e 100644 --- a/mobile/android/themes/core/aboutReaderContent.css +++ b/mobile/android/themes/core/aboutReaderContent.css @@ -18,7 +18,7 @@ body { } .header { - text-align: left; + text-align: start; display: none; } @@ -246,7 +246,7 @@ body { margin: 0px !important; margin-bottom: 20px !important; padding: 0px !important; - padding-left: 16px !important; + -moz-padding-start: 16px !important; border: 0px !important; border-left: 2px solid !important; } @@ -270,12 +270,12 @@ body { } .content ul { - padding-left: 30px !important; + -moz-padding-start: 30px !important; list-style: disk !important; } .content ol { - padding-left: 35px !important; + -moz-padding-start: 35px !important; list-style: decimal !important; } diff --git a/modules/libpref/public/Preferences.h b/modules/libpref/public/Preferences.h index 5ce8048d266..55347b490cb 100644 --- a/modules/libpref/public/Preferences.h +++ b/modules/libpref/public/Preferences.h @@ -123,6 +123,13 @@ public: return result; } + static float GetFloat(const char* aPref, float aDefault = 0) + { + float result = aDefault; + GetFloat(aPref, &result); + return result; + } + /** * Gets char type pref value directly. If failed, the get() of result * returns NULL. Even if succeeded but the result was empty string, the @@ -263,6 +270,9 @@ public: static nsresult AddUintVarCache(uint32_t* aVariable, const char* aPref, uint32_t aDefault = 0); + static nsresult AddFloatVarCache(float* aVariable, + const char* aPref, + float aDefault = 0.0f); /** * Gets the default bool, int or uint value of the pref. @@ -334,6 +344,7 @@ public: static void SetPreference(const PrefSetting& aPref); static int64_t GetPreferencesMemoryUsed(); + static nsresult SetFloat(const char* aPref, float aValue); protected: nsresult NotifyServiceObservers(const char *aSubject); diff --git a/modules/libpref/src/Preferences.cpp b/modules/libpref/src/Preferences.cpp index 9c5e5d1f882..d434fd3e1bd 100644 --- a/modules/libpref/src/Preferences.cpp +++ b/modules/libpref/src/Preferences.cpp @@ -151,6 +151,7 @@ struct CacheData { bool defaultValueBool; int32_t defaultValueInt; uint32_t defaultValueUint; + float defaultValueFloat; }; }; @@ -1557,6 +1558,29 @@ Preferences::AddUintVarCache(uint32_t* aCache, return RegisterCallback(UintVarChanged, aPref, data); } +static int FloatVarChanged(const char* aPref, void* aClosure) +{ + CacheData* cache = static_cast(aClosure); + *((float*)cache->cacheLocation) = + Preferences::GetFloat(aPref, cache->defaultValueFloat); + return 0; +} + +// static +nsresult +Preferences::AddFloatVarCache(float* aCache, + const char* aPref, + float aDefault) +{ + NS_ASSERTION(aCache, "aCache must not be NULL"); + *aCache = Preferences::GetFloat(aPref, aDefault); + CacheData* data = new CacheData(); + data->cacheLocation = aCache; + data->defaultValueFloat = aDefault; + gCacheData->AppendElement(data); + return RegisterCallback(FloatVarChanged, aPref, data); +} + // static nsresult Preferences::GetDefaultBool(const char* aPref, bool* aResult) diff --git a/mozglue/linker/Mappable.cpp b/mozglue/linker/Mappable.cpp index 87aad7c288d..f92a44c7ca5 100644 --- a/mozglue/linker/Mappable.cpp +++ b/mozglue/linker/Mappable.cpp @@ -333,6 +333,8 @@ MappableDeflate::mmap(const void *addr, size_t length, int prot, int flags, off_ void MappableDeflate::finalize() { + /* Free zlib internal buffers */ + inflateEnd(&zStream); /* Free decompression buffer */ buffer = NULL; /* Remove reference to Zip archive */ diff --git a/services/sync/tests/tps/test_privbrw_formdata.js b/services/sync/tests/tps/test_privbrw_formdata.js index 4b092cecdb5..e1661611e8a 100644 --- a/services/sync/tests/tps/test_privbrw_formdata.js +++ b/services/sync/tests/tps/test_privbrw_formdata.js @@ -60,7 +60,7 @@ Phase('phase2', [ Phase('phase3', [ [Sync], - [SetPrivateBrowsing, true], + [Windows.add, { private: true }], [Formdata.add, formdata2], [Formdata.verify, formdata2], [Sync], diff --git a/services/sync/tests/tps/test_privbrw_passwords.js b/services/sync/tests/tps/test_privbrw_passwords.js index 64849fc012a..ce90cc12f5b 100644 --- a/services/sync/tests/tps/test_privbrw_passwords.js +++ b/services/sync/tests/tps/test_privbrw_passwords.js @@ -90,7 +90,7 @@ Phase('phase2', [ Phase('phase3', [ [Sync], - [SetPrivateBrowsing, true], + [Windows.add, { private: true }], [Passwords.verify, passwords_after_first_change], [Passwords.modify, passwords_after_first_change], [Passwords.verify, passwords_after_second_change], diff --git a/services/sync/tps/extensions/tps/modules/tps.jsm b/services/sync/tps/extensions/tps/modules/tps.jsm index f1122a397cb..8d753e44f79 100644 --- a/services/sync/tps/extensions/tps/modules/tps.jsm +++ b/services/sync/tps/extensions/tps/modules/tps.jsm @@ -682,13 +682,6 @@ let TPS = { frame.runTestFile(mozmillfile.path, false); }, - SetPrivateBrowsing: function TPS__SetPrivateBrowsing(options) { - let PBSvc = CC["@mozilla.org/privatebrowsing;1"]. - getService(CI.nsIPrivateBrowsingService); - PBSvc.privateBrowsingEnabled = options; - Logger.logInfo("set privateBrowsingEnabled: " + options); - }, - /** * Synchronously wait for the named event to be observed. * diff --git a/toolkit/components/url-classifier/Makefile.in b/toolkit/components/url-classifier/Makefile.in index 515ef3dffe7..883c21b618b 100644 --- a/toolkit/components/url-classifier/Makefile.in +++ b/toolkit/components/url-classifier/Makefile.in @@ -18,14 +18,6 @@ LIBXUL_LIBRARY = 1 FORCE_STATIC_LIB = 1 FAIL_ON_WARNINGS = 1 -# Normally the "client ID" sent in updates is appinfo.name, but for -# official Firefox releases from Mozilla we use a special identifier. -ifdef MOZILLA_OFFICIAL -ifdef MOZ_PHOENIX -DEFINES += -DUSE_HISTORIC_SAFEBROWSING_ID=1 -endif -endif - XPIDLSRCS = \ nsIUrlClassifierDBService.idl \ nsIUrlClassifierHashCompleter.idl \ @@ -65,7 +57,7 @@ EXTRA_PP_COMPONENTS = \ nsUrlClassifierListManager.js \ $(NULL) -EXTRA_PP_JS_MODULES = \ +EXTRA_JS_MODULES = \ SafeBrowsing.jsm \ $(NULL) diff --git a/toolkit/components/url-classifier/SafeBrowsing.jsm b/toolkit/components/url-classifier/SafeBrowsing.jsm index 675eb7b81f6..4e1bf900aed 100644 --- a/toolkit/components/url-classifier/SafeBrowsing.jsm +++ b/toolkit/components/url-classifier/SafeBrowsing.jsm @@ -86,11 +86,11 @@ this.SafeBrowsing = { updateProviderURLs: function() { -#ifdef USE_HISTORIC_SAFEBROWSING_ID - let clientID = "navclient-auto-ffox"; -#else - let clientID = Services.appinfo.name; -#endif + try { + var clientID = Services.prefs.getCharPref("browser.safebrowsing.id"); + } catch(e) { + var clientID = Services.appinfo.name; + } log("initializing safe browsing URLs"); let basePref = "browser.safebrowsing."; diff --git a/toolkit/identity/MinimalIdentity.jsm b/toolkit/identity/MinimalIdentity.jsm index fc77598161e..490081b08f5 100644 --- a/toolkit/identity/MinimalIdentity.jsm +++ b/toolkit/identity/MinimalIdentity.jsm @@ -208,6 +208,16 @@ IDService.prototype = { rp.doReady(); }, + doCancel: function doCancel(aRpCallerId) { + let rp = this._rpFlows[aRpCallerId]; + if (!rp) { + dump("WARNING: doCancel found no rp to go with callerId " + aRpCallerId + "\n"); + return; + } + + rp.doCancel(); + }, + /* * XXX Bug 804229: Implement Identity Provider Functions diff --git a/widget/gonk/HwcComposer2D.cpp b/widget/gonk/HwcComposer2D.cpp index 3d9e9ee75b6..4d08cfa903f 100644 --- a/widget/gonk/HwcComposer2D.cpp +++ b/widget/gonk/HwcComposer2D.cpp @@ -174,13 +174,13 @@ HwcComposer2D::GetRotation() * Sets hwc layer rectangles required for hwc composition * * @param aVisible Input. Layer's unclipped visible rectangle - * The origin is the layer's buffer + * The origin is the top-left corner of the layer * @param aTransform Input. Layer's transformation matrix * It transforms from layer space to screen space * @param aClip Input. A clipping rectangle. * The origin is the top-left corner of the screen * @param aBufferRect Input. The layer's buffer bounds - * The origin is the buffer itself and hence always (0,0) + * The origin is the top-left corner of the layer * @param aSurceCrop Output. Area of the source to consider, * the origin is the top-left corner of the buffer * @param aVisibleRegionScreen Output. Visible region in screen space. @@ -207,9 +207,7 @@ PrepareLayerRects(nsIntRect aVisible, const gfxMatrix& aTransform, gfxMatrix inverse(aTransform); inverse.Invert(); gfxRect crop = inverse.TransformBounds(visibleRectScreen); - // Map to buffer space - crop -= visibleRect.TopLeft(); - gfxRect bufferRect(aBufferRect); + //clip to buffer size crop.IntersectRect(crop, aBufferRect); crop.RoundOut(); @@ -219,11 +217,13 @@ PrepareLayerRects(nsIntRect aVisible, const gfxMatrix& aTransform, return false; } - //propagate buffer clipping back to visible rect - visibleRectScreen = aTransform.TransformBounds(crop + visibleRect.TopLeft()); + visibleRectScreen = aTransform.TransformBounds(crop); visibleRectScreen.RoundOut(); + // Map from layer space to buffer space + crop -= aBufferRect.TopLeft(); + aSourceCrop->left = crop.x; aSourceCrop->top = crop.y; aSourceCrop->right = crop.x + crop.width; @@ -326,11 +326,15 @@ HwcComposer2D::PrepareLayerList(Layer* aLayer, nsIntRect bufferRect; if (fillColor) { - bufferRect = nsIntRect(0, 0, visibleRect.width, - visibleRect.height); + bufferRect = nsIntRect(visibleRect); } else { - bufferRect = nsIntRect(0, 0, int(buffer->getWidth()), - int(buffer->getHeight())); + if(state.mHasOwnOffset) { + bufferRect = nsIntRect(state.mOffset.x, state.mOffset.y, + int(buffer->getWidth()), int(buffer->getHeight())); + } else { + bufferRect = nsIntRect(visibleRect.x, visibleRect.y, + int(buffer->getWidth()), int(buffer->getHeight())); + } } hwc_layer_t& hwcLayer = mList->hwLayers[current];