author | Matthew Noorenberghe <mozilla@noorenberghe.ca> |
Thu, 17 Jan 2013 16:14:57 -0800 | |
changeset 119127 | b52c02f77cf5b76027fea25412e629cd3d551cb3 |
parent 119126 | 4a1b771880d830a75f83593b31493c0874166b13 (current diff) |
parent 119122 | d29ffd3357285b4797bff60bc3fb69cf4e71dfe6 (diff) |
child 119128 | fffc4af51c86adc5e28d8fe7831cbad2906a50ec |
child 119226 | 75d9c44ed26750c62aec5d68656077458d60bac1 |
child 119387 | a7234e6f89f2fe0c28608c209916db45533e92fe |
push id | 24192 |
push user | mozilla@noorenberghe.ca |
push date | Fri, 18 Jan 2013 00:18:36 +0000 |
treeherder | mozilla-central@b52c02f77cf5 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
milestone | 21.0a1 |
first release with | nightly linux32
b52c02f77cf5
/
21.0a1
/
20130118030915
/
files
nightly linux64
b52c02f77cf5
/
21.0a1
/
20130118030915
/
files
nightly mac
b52c02f77cf5
/
21.0a1
/
20130118030915
/
files
nightly win32
b52c02f77cf5
/
21.0a1
/
20130118030915
/
files
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
21.0a1
/
20130118030915
/
pushlog to previous
nightly linux64
21.0a1
/
20130118030915
/
pushlog to previous
nightly mac
21.0a1
/
20130118030915
/
pushlog to previous
nightly win32
21.0a1
/
20130118030915
/
pushlog to previous
|
--- a/accessible/src/base/NotificationController.cpp +++ b/accessible/src/base/NotificationController.cpp @@ -53,18 +53,16 @@ NotificationController::~NotificationCon } //////////////////////////////////////////////////////////////////////////////// // NotificationCollector: AddRef/Release and cycle collection NS_IMPL_CYCLE_COLLECTING_NATIVE_ADDREF(NotificationController) NS_IMPL_CYCLE_COLLECTING_NATIVE_RELEASE(NotificationController) -NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(NotificationController) - NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(NotificationController) if (tmp->mDocument) tmp->Shutdown(); NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(NotificationController) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mHangingChildDocuments) @@ -860,26 +858,18 @@ NotificationController::ContentInsertion } node = node->GetNextSibling(); } return haveToUpdate; } -NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(NotificationController::ContentInsertion) - -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(NotificationController::ContentInsertion) - NS_IMPL_CYCLE_COLLECTION_UNLINK(mContainer) -NS_IMPL_CYCLE_COLLECTION_UNLINK_END - -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(NotificationController::ContentInsertion) - NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mContainer"); - cb.NoteXPCOMChild(static_cast<nsIAccessible*>(tmp->mContainer.get())); -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END +NS_IMPL_CYCLE_COLLECTION_1(NotificationController::ContentInsertion, + mContainer) NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(NotificationController::ContentInsertion, AddRef) NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(NotificationController::ContentInsertion, Release) void NotificationController::ContentInsertion::Process()
--- a/accessible/src/generic/DocAccessible.cpp +++ b/accessible/src/generic/DocAccessible.cpp @@ -99,18 +99,16 @@ DocAccessible::~DocAccessible() { NS_ASSERTION(!mPresShell, "LastRelease was never called!?!"); } //////////////////////////////////////////////////////////////////////////////// // nsISupports -NS_IMPL_CYCLE_COLLECTION_CLASS(DocAccessible) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(DocAccessible, Accessible) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocumentNode) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mNotificationController) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mVirtualCursor) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChildDocuments) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAccessibleCache) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
--- a/accessible/src/msaa/HyperTextAccessibleWrap.cpp +++ b/accessible/src/msaa/HyperTextAccessibleWrap.cpp @@ -4,19 +4,27 @@ /* 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 "HyperTextAccessibleWrap.h" #include "nsEventShell.h" +#include "mozilla/StaticPtr.h" + using namespace mozilla; using namespace mozilla::a11y; +StaticRefPtr<Accessible> HyperTextAccessibleWrap::sLastTextChangeAcc; +StaticAutoPtr<nsString> HyperTextAccessibleWrap::sLastTextChangeString; +uint32_t HyperTextAccessibleWrap::sLastTextChangeStart = 0; +uint32_t HyperTextAccessibleWrap::sLastTextChangeEnd = 0; +bool HyperTextAccessibleWrap::sLastTextChangeWasInsert = false; + NS_IMPL_ISUPPORTS_INHERITED0(HyperTextAccessibleWrap, HyperTextAccessible) STDMETHODIMP HyperTextAccessibleWrap::QueryInterface(REFIID aIID, void** aInstancePtr) { if (!aInstancePtr) return E_FAIL; @@ -44,55 +52,50 @@ HyperTextAccessibleWrap::QueryInterface( nsresult HyperTextAccessibleWrap::HandleAccEvent(AccEvent* aEvent) { uint32_t eventType = aEvent->GetEventType(); if (eventType == nsIAccessibleEvent::EVENT_TEXT_REMOVED || eventType == nsIAccessibleEvent::EVENT_TEXT_INSERTED) { Accessible* accessible = aEvent->GetAccessible(); - if (accessible) { - nsCOMPtr<nsIWinAccessNode> winAccessNode(do_QueryObject(accessible)); - if (winAccessNode) { - void *instancePtr = NULL; - nsresult rv = winAccessNode->QueryNativeInterface(IID_IAccessibleText, - &instancePtr); - if (NS_SUCCEEDED(rv)) { - NS_IF_RELEASE(gTextEvent); - NS_IF_ADDREF(gTextEvent = downcast_accEvent(aEvent)); + if (accessible && accessible->IsHyperText()) { + sLastTextChangeAcc = accessible; + if (!sLastTextChangeString) + sLastTextChangeString = new nsString(); - (static_cast<IUnknown*>(instancePtr))->Release(); - } - } + AccTextChangeEvent* event = downcast_accEvent(aEvent); + event->GetModifiedText(*sLastTextChangeString); + sLastTextChangeStart = event->GetStartOffset(); + sLastTextChangeEnd = sLastTextChangeStart + event->GetLength(); + sLastTextChangeWasInsert = event->IsTextInserted(); } } return HyperTextAccessible::HandleAccEvent(aEvent); } nsresult HyperTextAccessibleWrap::GetModifiedText(bool aGetInsertedText, nsAString& aText, uint32_t* aStartOffset, uint32_t* aEndOffset) { aText.Truncate(); *aStartOffset = 0; *aEndOffset = 0; - if (!gTextEvent) + if (!sLastTextChangeAcc) return NS_OK; - bool isInserted = gTextEvent->IsTextInserted(); - if (aGetInsertedText != isInserted) + if (aGetInsertedText != sLastTextChangeWasInsert) return NS_OK; - Accessible* targetAcc = gTextEvent->GetAccessible(); - if (targetAcc != this) + if (sLastTextChangeAcc != this) return NS_OK; - *aStartOffset = gTextEvent->GetStartOffset(); - *aEndOffset = *aStartOffset + gTextEvent->GetLength(); - gTextEvent->GetModifiedText(aText); + *aStartOffset = sLastTextChangeStart; + *aEndOffset = sLastTextChangeEnd; + aText.Append(*sLastTextChangeString); return NS_OK; }
--- a/accessible/src/msaa/HyperTextAccessibleWrap.h +++ b/accessible/src/msaa/HyperTextAccessibleWrap.h @@ -8,16 +8,19 @@ #ifndef mozilla_a11y_HyperTextAccessibleWrap_h__ #define mozilla_a11y_HyperTextAccessibleWrap_h__ #include "HyperTextAccessible.h" #include "ia2AccessibleEditableText.h" #include "ia2AccessibleHypertext.h" namespace mozilla { +template<class T> class StaticAutoPtr; +template<class T> class StaticRefPtr; + namespace a11y { class HyperTextAccessibleWrap : public HyperTextAccessible, public ia2AccessibleHypertext, public ia2AccessibleEditableText { public: HyperTextAccessibleWrap(nsIContent* aContent, DocAccessible* aDoc) : @@ -31,14 +34,22 @@ public: // Accessible virtual nsresult HandleAccEvent(AccEvent* aEvent); protected: virtual nsresult GetModifiedText(bool aGetInsertedText, nsAString& aText, uint32_t *aStartOffset, uint32_t *aEndOffset); + + static StaticRefPtr<Accessible> sLastTextChangeAcc; + static StaticAutoPtr<nsString> sLastTextChangeString; + static bool sLastTextChangeWasInsert; + static uint32_t sLastTextChangeStart; + static uint32_t sLastTextChangeEnd; + + friend void PlatformInit(); }; } // namespace a11y } // namespace mozilla #endif
--- a/accessible/src/msaa/Platform.cpp +++ b/accessible/src/msaa/Platform.cpp @@ -3,31 +3,34 @@ /* 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 "Platform.h" #include "AccEvent.h" #include "Compatibility.h" -#include "nsAccessNodeWrap.h" +#include "HyperTextAccessibleWrap.h" #include "nsWinUtils.h" +#include "mozilla/ClearOnShutdown.h" + using namespace mozilla; using namespace mozilla::a11y; void a11y::PlatformInit() { Compatibility::Init(); nsWinUtils::MaybeStartWindowEmulation(); + ClearOnShutdown(&HyperTextAccessibleWrap::sLastTextChangeAcc); + ClearOnShutdown(&HyperTextAccessibleWrap::sLastTextChangeString); } void a11y::PlatformShutdown() { - NS_IF_RELEASE(nsAccessNodeWrap::gTextEvent); ::DestroyCaret(); nsWinUtils::ShutdownWindowEmulation(); }
--- a/accessible/src/msaa/nsAccessNodeWrap.cpp +++ b/accessible/src/msaa/nsAccessNodeWrap.cpp @@ -22,18 +22,16 @@ #include "nsIDOMHTMLElement.h" #include "nsINameSpaceManager.h" #include "nsPIDOMWindow.h" #include "nsIServiceManager.h" using namespace mozilla; using namespace mozilla::a11y; -AccTextChangeEvent* nsAccessNodeWrap::gTextEvent = nullptr; - //////////////////////////////////////////////////////////////////////////////// // nsAccessNodeWrap //////////////////////////////////////////////////////////////////////////////// nsAccessNodeWrap:: nsAccessNodeWrap(nsIContent* aContent, DocAccessible* aDoc) : nsAccessNode(aContent, aDoc) {
--- a/accessible/src/msaa/nsAccessNodeWrap.h +++ b/accessible/src/msaa/nsAccessNodeWrap.h @@ -42,18 +42,16 @@ } MOZ_SEH_EXCEPT(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), \ GetExceptionInformation())) \ { } \ return E_FAIL; namespace mozilla { namespace a11y { -class AccTextChangeEvent; - #ifdef __GNUC__ // Inheriting from both XPCOM and MSCOM interfaces causes a lot of warnings // about virtual functions being hidden by each other. This is done by // design, so silence the warning. #pragma GCC diagnostic ignored "-Woverloaded-virtual" #endif class nsAccessNodeWrap : public nsAccessNode, @@ -78,25 +76,16 @@ public: // construction, destruction void** aInstancePtr); static int FilterA11yExceptions(unsigned int aCode, EXCEPTION_POINTERS *aExceptionInfo); static LRESULT CALLBACK WindowProc(HWND hWnd, UINT Msg, WPARAM WParam, LPARAM lParam); static nsRefPtrHashtable<nsPtrHashKey<void>, DocAccessible> sHWNDCache; - -protected: - - /** - * It is used in HyperTextAccessibleWrap for IA2::newText/oldText - * implementation. - */ - static AccTextChangeEvent* gTextEvent; - friend void PlatformShutdown(); }; } // namespace a11y } // namespace mozilla /** * Converts nsresult to HRESULT. */
--- a/aclocal.m4 +++ b/aclocal.m4 @@ -21,16 +21,17 @@ builtin(include, build/autoconf/gcc-pr39 builtin(include, build/autoconf/llvm-pr8927.m4)dnl builtin(include, build/autoconf/frameptr.m4)dnl builtin(include, build/autoconf/compiler-opts.m4)dnl builtin(include, build/autoconf/expandlibs.m4)dnl builtin(include, build/autoconf/arch.m4)dnl builtin(include, build/autoconf/android.m4)dnl builtin(include, build/autoconf/zlib.m4)dnl builtin(include, build/autoconf/linux.m4)dnl +builtin(include, build/autoconf/python-virtualenv.m4)dnl MOZ_PROG_CHECKMSYS() # Read the user's .mozconfig script. We can't do this in # configure.in: autoconf puts the argument parsing code above anything # expanded from configure.in, and we need to get the configure options # from .mozconfig in place before that argument parsing code. MOZ_READ_MOZCONFIG(.)
--- a/b2g/chrome/content/shell.js +++ b/b2g/chrome/content/shell.js @@ -734,17 +734,18 @@ var AlertsHelper = { function send(appName, appIcon) { shell.sendChromeEvent({ type: "desktop-notification", id: uid, icon: imageUrl, title: title, text: text, appName: appName, - appIcon: appIcon + appIcon: appIcon, + manifestURL: manifestUrl }); } if (!manifestUrl || !manifestUrl.length) { send(null, null); } // If we have a manifest URL, get the icon and title from the manifest
--- a/b2g/confvars.sh +++ b/b2g/confvars.sh @@ -5,17 +5,17 @@ MOZ_APP_BASENAME=B2G MOZ_APP_VENDOR=Mozilla MOZ_APP_VERSION=21.0a1 MOZ_APP_UA_NAME=Firefox MOZ_UA_OS_AGNOSTIC=1 -MOZ_B2G_VERSION=1.0.0-prerelease +MOZ_B2G_VERSION=1.0.0.0-prerelease MOZ_B2G_OS_NAME=Boot2Gecko MOZ_BRANDING_DIRECTORY=b2g/branding/unofficial MOZ_OFFICIAL_BRANDING_DIRECTORY=b2g/branding/official # MOZ_APP_DISPLAYNAME is set by branding/configure.sh MOZ_SAFE_BROWSING= MOZ_SERVICES_COMMON=1
new file mode 100644 --- /dev/null +++ b/b2g/test/b2g-unittest-requirements.txt @@ -0,0 +1,2 @@ +mozprocess==0.8 +mozdevice==0.18
--- a/browser/base/content/browser-social.js +++ b/browser/base/content/browser-social.js @@ -964,18 +964,21 @@ var SocialToolbar = { dynamicResizer.start(panel, notificationFrame); setTimeout(function() { dispatchPanelEvent("socialFrameShow"); }, 0); }, true); } }); - let toolbarButtonIcon = document.getAnonymousElementByAttribute(aToolbarButton, "class", "toolbarbutton-icon"); - panel.openPopup(toolbarButtonIcon, "bottomcenter topright", 0, 0, false, false); + let navBar = document.getElementById("nav-bar"); + let anchor = navBar.getAttribute("mode") == "text" ? + document.getAnonymousElementByAttribute(aToolbarButton, "class", "toolbarbutton-text") : + document.getAnonymousElementByAttribute(aToolbarButton, "class", "toolbarbutton-icon"); + panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, false); }, setPanelErrorMessage: function SocialToolbar_setPanelErrorMessage(aNotificationFrame) { if (!aNotificationFrame) return; let src = aNotificationFrame.getAttribute("src"); aNotificationFrame.removeAttribute("src");
--- a/browser/components/downloads/content/allDownloadsViewOverlay.js +++ b/browser/components/downloads/content/allDownloadsViewOverlay.js @@ -36,16 +36,32 @@ const DOWNLOAD_VIEW_SUPPORTED_COMMANDS = ["cmd_delete", "cmd_copy", "cmd_paste", "cmd_selectAll", "downloadsCmd_pauseResume", "downloadsCmd_cancel", "downloadsCmd_open", "downloadsCmd_show", "downloadsCmd_retry", "downloadsCmd_openReferrer", "downloadsCmd_clearDownloads"]; const NOT_AVAILABLE = Number.MAX_VALUE; /** + * Download a URL. + * + * @param aURL + * the url to download (nsIURI object) + * @param [optional] aFileName + * the destination file name + */ +function DownloadURL(aURL, aFileName) { + // 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(aURL, aFileName, null, true, true, undefined, initiatingDoc); +} + +/** * A download element shell is responsible for handling the commands and the * displayed data for a single download view element. The download element * could represent either a past download (for which we get data from places) or * a "session" download (using a data-item object. See DownloadsCommon.jsm), or both. * * Once initialized with either a data item or a places node, the created richlistitem * can be accessed through the |element| getter, and can then be inserted/removed from * a richlistbox. @@ -155,17 +171,17 @@ DownloadElementShell.prototype = { get _downloadURIObj() { if (!("__downloadURIObj" in this)) this.__downloadURIObj = NetUtil.newURI(this.downloadURI); return this.__downloadURIObj; }, _getIcon: function DES__getIcon() { - let metaData = this._getDownloadMetaData(); + let metaData = this.getDownloadMetaData(); if ("filePath" in metaData) return "moz-icon://" + metaData.filePath + "?size=32"; if (this._placesNode) { // Try to extract an extension from the uri. let ext = this._downloadURIObj.QueryInterface(Ci.nsIURL).fileExtension; if (ext) return "moz-icon://." + ext + "?size=32"; @@ -208,17 +224,17 @@ DownloadElementShell.prototype = { }, _fetchTargetFileInfo: function DES__fetchTargetFileInfo(aUpdateMetaDataAndStatusUI = false) { if (this._targetFileInfoFetched) throw new Error("_fetchTargetFileInfo should not be called if the information was already fetched"); if (!this.active) throw new Error("Trying to _fetchTargetFileInfo on an inactive download shell"); - let path = this._getDownloadMetaData().filePath; + let path = this.getDownloadMetaData().filePath; // In previous version, the target file annotations were not set, // so we cannot tell where is the file. if (path === undefined) { this._targetFileInfoFetched = true; this._targetFileExists = false; if (aUpdateMetaDataAndStatusUI) { this._metaData = null; @@ -280,34 +296,34 @@ DownloadElementShell.prototype = { * * - state - any download state defined in nsIDownloadManager. If this field * is not set, the download state is unknown. * - endTime: the end time of the download. * - filePath: the downloaded file path on the file system, when it * was downloaded. The file may not exist. This is set for session * downloads that have a local file set, and for history downloads done * after the landing of bug 591289. + * - fileName: the downloaded file name on the file system. Set if filePath + * is set. * - displayName: the user-facing label for the download. This is always * set. If available, it's set to the downloaded file name. If not, * the places title for the download uri is used it's set. As a last * resort, we fallback to the download uri. * - fileSize (only set for downloads which completed succesfully): * the downloaded file size. For downloads done after the landing of * bug 826991, this value is "static" - that is, it does not necessarily * mean that the file is in place and has this size. */ - _getDownloadMetaData: function DES__getDownloadMetaData() { - if (!this.active) - throw new Error("_getDownloadMetaData called for an inactive item."); - + getDownloadMetaData: function DES_getDownloadMetaData() { if (!this._metaData) { if (this._dataItem) { this._metaData = { state: this._dataItem.state, endTime: this._dataItem.endTime, + fileName: this._dataItem.target, displayName: this._dataItem.target }; if (this._dataItem.done) this._metaData.fileSize = this._dataItem.maxBytes; if (this._dataItem.localFile) this._metaData.filePath = this._dataItem.localFile.path; } else { @@ -323,18 +339,19 @@ DownloadElementShell.prototype = { } // This is actually the start-time, but it's the best we can get. this._metaData.endTime = this._placesNode.time / 1000; } try { let targetFileURI = this._getAnnotation(DESTINATION_FILE_URI_ANNO); - [this._metaData.filePath, this._metaData.displayName] = + [this._metaData.filePath, this._metaData.fileName] = this._extractFilePathAndNameFromFileURI(targetFileURI); + this._metaData.displayName = this._metaData.fileName; } catch(ex) { this._metaData.displayName = this._placesNode.title || this.downloadURI; } } } return this._metaData; }, @@ -368,17 +385,17 @@ DownloadElementShell.prototype = { return s.stateScanning; } throw new Error("_getStatusText called with a bogus download state"); } // This is a not-in-progress or history download. let stateLabel = ""; - let state = this._getDownloadMetaData().state; + let state = this.getDownloadMetaData().state; switch (state) { case nsIDM.DOWNLOAD_FAILED: stateLabel = s.stateFailed; break; case nsIDM.DOWNLOAD_CANCELED: stateLabel = s.stateCanceled; break; case nsIDM.DOWNLOAD_BLOCKED_PARENTAL: @@ -387,17 +404,17 @@ DownloadElementShell.prototype = { case nsIDM.DOWNLOAD_BLOCKED_POLICY: stateLabel = s.stateBlockedPolicy; break; case nsIDM.DOWNLOAD_DIRTY: stateLabel = s.stateDirty; break; case nsIDM.DOWNLOAD_FINISHED:{ // For completed downloads, show the file size (e.g. "1.5 MB") - let metaData = this._getDownloadMetaData(); + let metaData = this.getDownloadMetaData(); if ("fileSize" in metaData) { let [size, unit] = DownloadUtils.convertByteUnits(metaData.fileSize); stateLabel = s.sizeWithUnits(size, unit); break; } // Fallback to default unknown state. } default: @@ -405,17 +422,17 @@ DownloadElementShell.prototype = { break; } // TODO (bug 829201): history downloads should get the referrer from Places. let referrer = this._dataItem && this._dataItem.referrer || this.downloadURI; let [displayHost, fullHost] = DownloadUtils.getURIHost(referrer); - let date = new Date(this._getDownloadMetaData().endTime); + let date = new Date(this.getDownloadMetaData().endTime); let [displayDate, fullDate] = DownloadUtils.getReadableDates(date); // We use the same XUL label to display the state, the host name, and the // end time. let firstPart = s.statusSeparator(stateLabel, displayHost); return s.statusSeparator(firstPart, displayDate); }, @@ -431,17 +448,17 @@ DownloadElementShell.prototype = { // Updates the download state attribute (and by that hide/unhide the // appropriate buttons and context menu items), the status text label, // and the progress meter. _updateDownloadStatusUI: function DES__updateDownloadStatusUI() { if (!this.active) throw new Error("_updateDownloadStatusUI called for an inactive item."); - let state = this._getDownloadMetaData().state; + let state = this.getDownloadMetaData().state; if (state !== undefined) this._element.setAttribute("state", state); this._element.setAttribute("status", this._getStatusText()); // For past-downloads, we're done. For session-downloads, we may also need // to update the progress-meter. if (!this._dataItem) @@ -469,105 +486,108 @@ DownloadElementShell.prototype = { if (this._progressElement) { let event = document.createEvent("Events"); event.initEvent("ValueChange", true, true); this._progressElement.dispatchEvent(event); } }, _updateDisplayNameAndIcon: function DES__updateDisplayNameAndIcon() { - let metaData = this._getDownloadMetaData(); + let metaData = this.getDownloadMetaData(); this._element.setAttribute("displayName", metaData.displayName); this._element.setAttribute("image", this._getIcon()); }, _updateUI: function DES__updateUI() { if (!this.active) throw new Error("Trying to _updateUI on an inactive download shell"); this._metaData = null; this._targetFileInfoFetched = false; this._updateDisplayNameAndIcon(); // For history downloads done in past releases, the downloads/metaData // annotation is not set, and therefore we cannot tell the download // state without the target file information. - if (this._dataItem || this._getDownloadMetaData().state !== undefined) + if (this._dataItem || this.getDownloadMetaData().state !== undefined) this._updateDownloadStatusUI(); else this._fetchTargetFileInfo(true); }, placesNodeIconChanged: function DES_placesNodeIconChanged() { if (!this._dataItem) this._element.setAttribute("image", this._getIcon()); }, placesNodeTitleChanged: function DES_placesNodeTitleChanged() { // If there's a file path, we use the leaf name for the title. - if (!this._dataItem && this.active && !this._getDownloadMetaData().filePath) { + if (!this._dataItem && this.active && !this.getDownloadMetaData().filePath) { this._metaData = null; this._updateDisplayNameAndIcon(); } }, placesNodeAnnotationChanged: function DES_placesNodeAnnotationChanged(aAnnoName) { this._annotations.delete(aAnnoName); if (!this._dataItem && this.active) { if (aAnnoName == DOWNLOAD_META_DATA_ANNO) { - let metaData = this._getDownloadMetaData(); + let metaData = this.getDownloadMetaData(); let annotatedMetaData = this._getAnnotatedMetaData(); metaData.endTme = annotatedMetaData.endTime; if ("fileSize" in annotatedMetaData) metaData.fileSize = annotatedMetaData.fileSize; else delete metaData.fileSize; if (metaData.state != annotatedMetaData.state) { metaData.state = annotatedMetaData.state; if (this._element.selected) goUpdateDownloadCommands(); } this._updateDownloadStatusUI(); } else if (aAnnoName == DESTINATION_FILE_URI_ANNO) { - let metaData = this._getDownloadMetaData(); + let metaData = this.getDownloadMetaData(); let targetFileURI = this._getAnnotation(DESTINATION_FILE_URI_ANNO); - [metaData.filePath, metaData.displayName] = + [metaData.filePath, metaData.fileName] = this._extractFilePathAndNameFromFileURI(targetFileURI); + metaData.displayName = metaData.fileName; this._updateDisplayNameAndIcon(); if (this._targetFileInfoFetched) { // This will also update the download commands if necessary. this._targetFileInfoFetched = false; this._fetchTargetFileInfo(); } } } }, /* DownloadView */ onStateChange: function DES_onStateChange(aOldState) { - let metaData = this._getDownloadMetaData(); + let metaData = this.getDownloadMetaData(); metaData.state = this.dataItem.state; if (aOldState != nsIDM.DOWNLOAD_FINISHED && aOldState != metaData.state) { // See comment in DVI_onStateChange in downloads.js (the panel-view) this._element.setAttribute("image", this._getIcon() + "&state=normal"); metaData.fileSize = this._dataItem.maxBytes; if (this._targetFileInfoFetched) { this._targetFileInfoFetched = false; this._fetchTargetFileInfo(); } } this._updateDownloadStatusUI(); if (this._element.selected) goUpdateDownloadCommands(); + else + goUpdateCommand("downloadsCmd_clearDownloads"); }, /* DownloadView */ onProgressChange: function DES_onProgressChange() { this._updateDownloadStatusUI(); }, /* nsIController */ @@ -583,30 +603,30 @@ DownloadElementShell.prototype = { if (this._dataItem && !this._dataItem.openable) return false; if (this._targetFileInfoFetched) return this._targetFileExists; // If the target file information is not yet fetched, // temporarily assume that the file is in place. - return this._getDownloadMetaData().state == nsIDM.DOWNLOAD_FINISHED; + return this.getDownloadMetaData().state == nsIDM.DOWNLOAD_FINISHED; } case "downloadsCmd_show": { // TODO: Bug 827010 - Handle part-file asynchronously. if (this._dataItem && this._dataItem.partFile && this._dataItem.partFile.exists()) return true; if (this._targetFileInfoFetched) return this._targetFileExists; // If the target file information is not yet fetched, // temporarily assume that the file is in place. - return this._getDownloadMetaData().state == nsIDM.DOWNLOAD_FINISHED; + return this.getDownloadMetaData().state == nsIDM.DOWNLOAD_FINISHED; } case "downloadsCmd_pauseResume": return this._dataItem && this._dataItem.inProgress && this._dataItem.resumable; case "downloadsCmd_retry": // An history download can always be retried. return !this._dataItem || this._dataItem.canRetry; case "downloadsCmd_openReferrer": return this._dataItem && !!this._dataItem.referrer; @@ -620,42 +640,36 @@ DownloadElementShell.prototype = { } return false; }, _retryAsHistoryDownload: function DES__retryAsHistoryDownload() { // 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._getDownloadMetaData().displayName, null, true, true, undefined, - initiatingDoc); + DownloadURL(this.downloadURI, this.getDownloadMetaData().fileName); }, /* nsIController */ doCommand: function DES_doCommand(aCommand) { switch (aCommand) { case "downloadsCmd_open": { let file = this._dataItem ? this.dataItem.localFile : - new FileUtils.File(this._getDownloadMetaData().filePath); + new FileUtils.File(this.getDownloadMetaData().filePath); DownloadsCommon.openDownloadedFile(file, null, window); break; } case "downloadsCmd_show": { if (this._dataItem) { this._dataItem.showLocalFile(); } else { - let file = new FileUtils.File(this._getDownloadMetaData().filePath); + let file = new FileUtils.File(this.getDownloadMetaData().filePath); DownloadsCommon.showDownloadedFile(file); } break; } case "downloadsCmd_openReferrer": { openURL(this._dataItem.referrer); break; } @@ -686,18 +700,18 @@ DownloadElementShell.prototype = { // Returns whether or not the download handled by this shell should // show up in the search results for the given term. Both the display // name for the download and the url are searched. matchesSearchTerm: function DES_matchesSearchTerm(aTerm) { if (!aTerm) return true; aTerm = aTerm.toLowerCase(); - return this._getDownloadMetaData().displayName.toLowerCase().indexOf(aTerm) != -1 || - this.downloadURI.toLowerCase().indexOf(aTerm) != -1; + return this.getDownloadMetaData().displayName.toLowerCase().contains(aTerm) || + this.downloadURI.toLowerCase().contains(aTerm); }, // Handles return kepress on the element (the keypress listener is // set in the DownloadsPlacesView object). doDefaultCommand: function DES_doDefaultCommand() { function getDefaultCommandForState(aState) { switch (aState) { case nsIDM.DOWNLOAD_FINISHED: @@ -715,17 +729,17 @@ DownloadElementShell.prototype = { return "downloadsCmd_show"; case nsIDM.DOWNLOAD_BLOCKED_PARENTAL: case nsIDM.DOWNLOAD_DIRTY: case nsIDM.DOWNLOAD_BLOCKED_POLICY: return "downloadsCmd_openReferrer"; } return ""; } - let command = getDefaultCommandForState(this._getDownloadMetaData().state); + let command = getDefaultCommandForState(this.getDownloadMetaData().state); if (this.isCommandEnabled(command)) this.doCommand(command); }, /** * At the first time an item is selected, we don't yet have * the target file information. Thus the call to goUpdateDownloadCommands * in DPV_onSelect would result in best-guess enabled/disabled result. @@ -749,17 +763,17 @@ DownloadElementShell.prototype = { * A richlistitem in this view can represent either a past download or a session * download, or both. Session downloads are shown first in the view, and as long * as they exist they "collapses" their history "counterpart" (So we don't show two * items for every download). */ function DownloadsPlacesView(aRichListBox, aActive = true) { this._richlistbox = aRichListBox; this._richlistbox._placesView = this; - this._richlistbox.controllers.appendController(this); + window.controllers.insertControllerAt(0, this); // Map download URLs to download element shells regardless of their type this._downloadElementsShellsForURI = new Map(); // Map download data items to their element shells. this._viewItemsForDataItems = new WeakMap(); // Points to the last session download element. We keep track of this @@ -773,17 +787,17 @@ function DownloadsPlacesView(aRichListBo // Register as a downloads view. The places data will be initialized by // the places setter. this._initiallySelectedElement = null; let downloadsData = DownloadsCommon.getData(window.opener || window); downloadsData.addView(this); // Make sure to unregister the view if the window is closed. window.addEventListener("unload", function() { - this._richlistbox.controllers.removeController(this); + window.controllers.removeController(this); downloadsData.removeView(this); this.result = null; }.bind(this), true); // Resizing the window may change items visibility. window.addEventListener("resize", function() { this._ensureVisibleElementsAreActive(); }.bind(this), true); } @@ -954,31 +968,34 @@ DownloadsPlacesView.prototype = { if (this.searchTerm) { newOrUpdatedShell.element.hidden = !newOrUpdatedShell.element._shell.matchesSearchTerm(this.searchTerm); } } // If aDocumentFragment is defined this is a batch change, so it's up to // the caller to append the fragment and activate the visible shells. - if (!aDocumentFragment) + if (!aDocumentFragment) { this._ensureVisibleElementsAreActive(); + goUpdateCommand("downloadsCmd_clearDownloads"); + } }, _removeElement: function DPV__removeElement(aElement) { // If the element was selected exclusively, select its next // sibling first, if any. if (aElement.nextSibling && this._richlistbox.selectedItems && this._richlistbox.selectedItems.length > 0 && this._richlistbox.selectedItems[0] == aElement) { this._richlistbox.selectItem(aElement.nextSibling); } this._richlistbox.removeChild(aElement); this._ensureVisibleElementsAreActive(); + goUpdateCommand("downloadsCmd_clearDownloads"); }, _removeHistoryDownloadFromView: function DPV__removeHistoryDownloadFromView(aPlacesNode) { let downloadURI = aPlacesNode.uri; let shellsForURI = this._downloadElementsShellsForURI.get(downloadURI, null); if (shellsForURI) { for (let shell of shellsForURI) { @@ -1167,28 +1184,27 @@ DownloadsPlacesView.prototype = { } catch(ex) { Cu.reportError(ex); } } this._appendDownloadsFragment(elementsToAppendFragment); this._ensureVisibleElementsAreActive(); + goUpdateDownloadCommands(); }, _appendDownloadsFragment: function DPV__appendDownloadsFragment(aDOMFragment) { // Workaround multiple reflows hang by removing the richlistbox // and adding it back when we're done. let parentNode = this._richlistbox.parentNode; let nextSibling = this._richlistbox.nextSibling; - this._richlistbox.controllers.removeController(this); parentNode.removeChild(this._richlistbox); this._richlistbox.appendChild(aDOMFragment); parentNode.insertBefore(this._richlistbox, nextSibling); - this._richlistbox.controllers.appendController(this); }, nodeInserted: function DPV_nodeInserted(aParent, aPlacesNode) { this._addDownloadData(null, aPlacesNode); }, nodeRemoved: function DPV_nodeRemoved(aParent, aPlacesNode, aOldIndex) { this._removeHistoryDownloadFromView(aPlacesNode); @@ -1281,37 +1297,63 @@ DownloadsPlacesView.prototype = { onDataItemRemoved: function DPV_onDataItemRemoved(aDataItem) { this._removeSessionDownloadFromView(aDataItem); }, getViewItem: function(aDataItem) this._viewItemsForDataItems.get(aDataItem, null), - supportsCommand: function(aCommand) - DOWNLOAD_VIEW_SUPPORTED_COMMANDS.indexOf(aCommand) != -1, + supportsCommand: function DPV_supportsCommand(aCommand) { + if (DOWNLOAD_VIEW_SUPPORTED_COMMANDS.indexOf(aCommand) != -1) { + // The clear-downloads command may be performed by the toolbar-button, + // which can be focused on OS X. Thus enable this command even if the + // richlistbox is not focused. + // For other commands, be prudent and disable them unless the richlistview + // is focused. It's important to make the decision here rather than in + // isCommandEnabled. Otherwise our controller may "steal" commands from + // other controls in the window (see goUpdateCommand & + // getControllerForCommand). + if (document.activeElement == this._richlistbox || + aCommand == "downloadsCmd_clearDownloads") { + return true; + } + } + return false; + }, isCommandEnabled: function DPV_isCommandEnabled(aCommand) { - let selectedElements = this._richlistbox.selectedItems; switch (aCommand) { case "cmd_copy": - return selectedElements && selectedElements.length > 0; + return this._richlistbox.selectedItems.length > 0; case "cmd_selectAll": return true; case "cmd_paste": return this._canDownloadClipboardURL(); case "downloadsCmd_clearDownloads": - return !!this._richlistbox.firstChild; + return this._canClearDownloads(); default: - return Array.every(selectedElements, function(element) { + return Array.every(this._richlistbox.selectedItems, function(element) { return element._shell.isCommandEnabled(aCommand); }); } }, + _canClearDownloads: function DPV__canClearDownloads() { + // Downloads can be cleared if there's at least one removeable download in + // the list (either a history download or a completed session download). + // Because history downloads are always removable and are listed after the + // session downloads, check from bottom to top. + for (let elt = this._richlistbox.lastChild; elt; elt = elt.previousSibling) { + if (elt._shell.placesNode || !elt._shell.dataItem.inProgress) + return true; + } + return false; + }, + _copySelectedDownloadsToClipboard: function DPV__copySelectedDownloadsToClipboard() { let selectedElements = this._richlistbox.selectedItems; let urls = [e._shell.downloadURI for each (e in selectedElements)]; Cc["@mozilla.org/widget/clipboardhelper;1"]. getService(Ci.nsIClipboardHelper).copyString(urls.join("\n"), document); }, @@ -1342,17 +1384,17 @@ DownloadsPlacesView.prototype = { _canDownloadClipboardURL: function DPV__canDownloadClipboardURL() { let [url, name] = this._getURLFromClipboardData(); return url != ""; }, _downloadURLFromClipboard: function DPV__downloadURLFromClipboard() { let [url, name] = this._getURLFromClipboardData(); - saveURL(url, name || url, null, true, true, undefined, document); + DownloadURL(url, name); }, doCommand: function DPV_doCommand(aCommand) { switch (aCommand) { case "cmd_copy": this._copySelectedDownloadsToClipboard(); break; case "cmd_selectAll": @@ -1367,16 +1409,19 @@ DownloadsPlacesView.prototype = { } else { Services.downloads.cleanUp(); } if (this.result) { Cc["@mozilla.org/browser/download-history;1"] .getService(Ci.nsIDownloadHistory) .removeAllDownloads(); } + // There may be no selection or focus change as a result + // of these change, and we want the command updated immediately. + goUpdateCommand("downloadsCmd_clearDownloads"); break; default: { let selectedElements = this._richlistbox.selectedItems; for (let element of selectedElements) { element._shell.doCommand(aCommand); } } } @@ -1387,17 +1432,17 @@ DownloadsPlacesView.prototype = { onContextMenu: function DPV_onContextMenu(aEvent) { let element = this._richlistbox.selectedItem; if (!element || !element._shell) return false; // Set the state attribute so that only the appropriate items are displayed. let contextMenu = document.getElementById("downloadsContextMenu"); - let state = element._shell._getDownloadMetaData().state; + let state = element._shell.getDownloadMetaData().state; if (state !== undefined) contextMenu.setAttribute("state", state); else contextMenu.removeAttribute("state"); return true; }, @@ -1442,16 +1487,61 @@ DownloadsPlacesView.prototype = { onSelect: function DPV_onSelect() { goUpdateDownloadCommands(); let selectedElements = this._richlistbox.selectedItems; for (let elt of selectedElements) { if (elt._shell) elt._shell.onSelect(); } + }, + + onDragStart: function DPV_onDragStart(aEvent) { + // TODO Bug 831358: Support d&d for multiple selection. + // For now, we just drag the first element. + let selectedItem = this._richlistbox.selectedItem; + if (!selectedItem) + return; + + let metaData = selectedItem._shell.getDownloadMetaData(); + if (!("filePath" in metaData)) + return; + let file = new FileUtils.File(metaData.filePath); + if (!file.exists()) + return; + + let dt = aEvent.dataTransfer; + dt.mozSetDataAt("application/x-moz-file", file, 0); + let url = Services.io.newFileURI(file).spec; + dt.setData("text/uri-list", url); + dt.setData("text/plain", url); + dt.effectAllowed = "copyMove"; + dt.addElement(selectedItem); + }, + + onDragOver: function DPV_onDragOver(aEvent) { + let types = aEvent.dataTransfer.types; + if (types.contains("text/uri-list") || + types.contains("text/x-moz-url") || + types.contains("text/plain")) { + aEvent.preventDefault(); + } + }, + + onDrop: function DPV_onDrop(aEvent) { + let dt = aEvent.dataTransfer; + // If dragged item is from our source, do not try to + // redownload already downloaded file. + if (dt.mozGetDataAt("application/x-moz-file", 0)) + return; + + let name = { }; + let url = Services.droppedLinkHandler.dropLink(aEvent, name); + if (url) + DownloadURL(url, name.value); } }; for (let methodName of ["load", "applyFilter", "selectNode", "selectItems"]) { DownloadsPlacesView.prototype[methodName] = function() { throw new Error("|" + methodName + "| is not implemented by the downloads view."); } }
--- a/browser/components/downloads/content/allDownloadsViewOverlay.xul +++ b/browser/components/downloads/content/allDownloadsViewOverlay.xul @@ -41,16 +41,19 @@ <richlistbox flex="1" seltype="multiple" id="downloadsRichListBox" context="downloadsContextMenu" onscroll="return this._placesView.onScroll();" onkeypress="return this._placesView.onKeyPress(event);" ondblclick="return this._placesView.onDoubleClick(event);" oncontextmenu="return this._placesView.onContextMenu(event);" + ondragstart="this._placesView.onDragStart(event);" + ondragover="this._placesView.onDragOver(event);" + ondrop="this._placesView.onDrop(event);" onfocus="goUpdateDownloadCommands();" onselect="this._placesView.onSelect();" onblur="goUpdateDownloadCommands();"/> <commandset id="downloadCommands" commandupdater="true" events="focus,select,contextmenu" oncommandupdate="goUpdateDownloadCommands();">
--- a/browser/components/downloads/src/DownloadsCommon.jsm +++ b/browser/components/downloads/src/DownloadsCommon.jsm @@ -731,21 +731,21 @@ DownloadsDataCtor.prototype = { * Removes the data item with the specified identifier. * * This method can be called at most once per download identifier. */ _removeDataItem: function DD_removeDataItem(aDownloadId) { if (aDownloadId in this.dataItems) { let dataItem = this.dataItems[aDownloadId]; + this.dataItems[aDownloadId] = null; this._views.forEach( function (view) view.onDataItemRemoved(dataItem) ); } - this.dataItems[aDownloadId] = null; }, ////////////////////////////////////////////////////////////////////////////// //// Persistent data loading /** * Represents an executing statement, allowing its cancellation. */
--- a/browser/components/nsBrowserContentHandler.js +++ b/browser/components/nsBrowserContentHandler.js @@ -507,17 +507,17 @@ nsBrowserContentHandler.prototype = { } if (cmdLine.handleFlag("preferences", false)) { openPreferences(); cmdLine.preventDefault = true; } if (cmdLine.handleFlag("silent", false)) cmdLine.preventDefault = true; #ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING - if (cmdLine.findFlag("private-window", false) >= 0) { + if (cmdLine.handleFlag("private-window", false)) { openWindow(null, this.chromeURL, "_blank", "chrome,dialog=no,private,all" + this.getFeatures(cmdLine), "about:privatebrowsing"); cmdLine.preventDefault = true; } #else if (cmdLine.findFlag("private-toggle", false) >= 0) cmdLine.preventDefault = true;
--- a/browser/components/places/content/places.js +++ b/browser/components/places/content/places.js @@ -1239,16 +1239,17 @@ let gPrivateBrowsingListener = { let ContentArea = { _specialViews: new Map(), init: function CA_init() { this._deck = document.getElementById("placesViewsDeck"); this._toolbar = document.getElementById("placesToolbar"); ContentTree.init(); + this._setupView(); }, /** * Gets the content view to be used for loading the given query. * If a custom view was set by setContentViewForQueryString, that * view would be returned, else the default tree view is returned * * @param aQueryString @@ -1375,20 +1376,16 @@ let ContentTree = { }), openSelectedNode: function CT_openSelectedNode(aEvent) { let view = this.view; PlacesUIUtils.openNodeWithEvent(view.selectedNode, aEvent, view); }, onClick: function CT_onClick(aEvent) { - // Only handle clicks on tree children. - if (aEvent.target.localName != "treechildren") - return; - let node = this.view.selectedNode; if (node) { let doubleClick = aEvent.button == 0 && aEvent.detail == 2; let middleClick = aEvent.button == 1 && aEvent.detail == 1; if (PlacesUtils.nodeIsURI(node) && (doubleClick || middleClick)) { // Open associated uri in the browser. this.openSelectedNode(aEvent); }
--- a/browser/components/places/content/places.xul +++ b/browser/components/places/content/places.xul @@ -368,18 +368,17 @@ flex="1" type="places" flatList="true" selectfirstnode="true" enableColumnDrag="true" onfocus="PlacesOrganizer.updateDetailsPane(event)" onselect="PlacesOrganizer.updateDetailsPane(event)" onkeypress="ContentTree.onKeyPress(event);" - onopenflatcontainer="PlacesOrganizer.openFlatContainer(aContainer);" - onclick="ContentTree.onClick(event);"> + onopenflatcontainer="PlacesOrganizer.openFlatContainer(aContainer);"> <treecols id="placeContentColumns" context="placesColumnsContext"> <treecol label="&col.name.label;" id="placesContentTitle" anonid="title" flex="5" primary="true" ordinal="1" persist="width hidden ordinal sortActive sortDirection"/> <splitter class="tree-splitter"/> <treecol label="&col.tags.label;" id="placesContentTags" anonid="tags" flex="2" persist="width hidden ordinal sortActive sortDirection"/> <splitter class="tree-splitter"/> <treecol label="&col.url.label;" id="placesContentUrl" anonid="url" flex="5" @@ -398,17 +397,17 @@ persist="width hidden ordinal sortActive sortDirection"/> <splitter class="tree-splitter"/> <treecol label="&col.dateadded.label;" id="placesContentDateAdded" anonid="dateAdded" flex="1" hidden="true" persist="width hidden ordinal sortActive sortDirection"/> <splitter class="tree-splitter"/> <treecol label="&col.lastmodified.label;" id="placesContentLastModified" anonid="lastModified" flex="1" hidden="true" persist="width hidden ordinal sortActive sortDirection"/> </treecols> - <treechildren flex="1"/> + <treechildren flex="1" onclick="ContentTree.onClick(event);"/> </tree> </deck> <deck id="detailsDeck" style="height: 11em;"> <vbox id="itemsCountBox" align="center"> <spacer flex="3"/> <label id="itemsCountText"/> <spacer flex="1"/> <description id="selectItemDescription">
--- a/browser/components/privatebrowsing/test/browser/perwindow/Makefile.in +++ b/browser/components/privatebrowsing/test/browser/perwindow/Makefile.in @@ -10,16 +10,19 @@ relativesrcdir = @relativesrcdir@ include $(DEPTH)/config/autoconf.mk MOCHITEST_BROWSER_FILES = \ head.js \ browser_privatebrowsing_certexceptionsui.js \ browser_privatebrowsing_concurrent.js \ browser_privatebrowsing_concurrent_page.html \ + browser_privatebrowsing_cookieacceptdialog.js \ + browser_privatebrowsing_cookieacceptdialog.html \ + browser_privatebrowsing_crh.js \ browser_privatebrowsing_downloadLastDir.js \ browser_privatebrowsing_downloadLastDir_c.js \ browser_privatebrowsing_downloadLastDir_toggle.js \ browser_privatebrowsing_DownloadLastDirWithCPS.js \ browser_privatebrowsing_geoprompt.js \ browser_privatebrowsing_geoprompt_page.html \ browser_privatebrowsing_lastpbcontextexited.js \ browser_privatebrowsing_localStorage.js \ @@ -43,18 +46,9 @@ MOCHITEST_BROWSER_FILES = \ browser_privatebrowsing_windowtitle.js \ browser_privatebrowsing_windowtitle_page.html \ browser_privatebrowsing_zoom.js \ browser_privatebrowsing_zoomrestore.js \ popup.html \ title.sjs \ $(NULL) -# Temporarily disabled on OS X for bug 822284 -ifneq ($(MOZ_WIDGET_TOOLKIT),cocoa) -MOCHITEST_BROWSER_FILES += \ - browser_privatebrowsing_cookieacceptdialog.js \ - browser_privatebrowsing_cookieacceptdialog.html \ - browser_privatebrowsing_crh.js \ - $(NULL) -endif - include $(topsrcdir)/config/rules.mk
--- a/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_cookieacceptdialog.js +++ b/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_cookieacceptdialog.js @@ -55,85 +55,98 @@ function test() { isSecure: false, expires: time, status: 0, policy: 0, isSession: false, expiry: time, isHttpOnly: true, QueryInterface: function(iid) { - const validIIDs = [Ci.nsISupports, - Ci.nsICookie, - Ci.nsICookie2]; + const validIIDs = [Ci.nsISupports, Ci.nsICookie, Ci.nsICookie2]; for (var i = 0; i < validIIDs.length; ++i) if (iid == validIIDs[i]) return this; throw Cr.NS_ERROR_NO_INTERFACE; } }; cp.cookieDialog(aWindow, cookie, "mozilla.org", 10, false, remember); } function checkSettingDialog(aIsPrivateWindow, aWindow, aCallback) { - aWindow.gBrowser.selectedTab = aWindow.gBrowser.addTab(); let selectedBrowser = aWindow.gBrowser.selectedBrowser; function onLoad() { + if (aWindow.content.location.href != TEST_URL) { + selectedBrowser.loadURI(TEST_URL); + return; + } selectedBrowser.removeEventListener("load", onLoad, true); Services.ww.unregisterNotification(observer); - ok(aIsPrivateWindow, "Confirm setting dialog is not displayed for private window"); + ok(aIsPrivateWindow, + "Confirm setting dialog is not displayed for private window"); executeSoon(aCallback); } selectedBrowser.addEventListener("load", onLoad, true); function observer(aSubject, aTopic, aData) { if (aTopic != "domwindowopened") return; selectedBrowser.removeEventListener("load", onLoad, true); Services.ww.unregisterNotification(observer); - - ok(!aIsPrivateWindow, "Confirm setting dialog is displayed for normal window"); - + ok(!aIsPrivateWindow, + "Confirm setting dialog is displayed for normal window"); let win = aSubject.QueryInterface(Ci.nsIDOMWindow); executeSoon(function () { - win.close(); - executeSoon(aCallback); + info("Wait for window close"); + waitForWindowClose(win, aCallback); }); } Services.ww.registerNotification(observer); selectedBrowser.loadURI(TEST_URL); } - var windowsToClose = []; - function testOnWindow(options, callback) { - var win = OpenBrowserWindow(options); - win.addEventListener("load", function onLoad() { - win.removeEventListener("load", onLoad, false); - windowsToClose.push(win); - callback(win); - }, false); + let windowsToClose = []; + function testOnWindow(aIsPrivate, aCallback) { + whenNewWindowLoaded({private: aIsPrivate}, function(aWin) { + windowsToClose.push(aWin); + aCallback(aWin); + }); } registerCleanupFunction(function() { + Services.prefs.clearUserPref("network.cookie.lifetimePolicy"); windowsToClose.forEach(function(win) { - Services.prefs.clearUserPref("network.cookie.lifetimePolicy"); win.close(); }); }); - // ask all cookies + // Ask all cookies Services.prefs.setIntPref("network.cookie.lifetimePolicy", 1); - testOnWindow({private: true}, function(aPrivWin) { + testOnWindow(true, function(aPrivWin) { + info("Test on private window"); checkRememberOption(true, aPrivWin, function() { checkSettingDialog(true, aPrivWin, function() { - testOnWindow(undefined, function(aWin) { + testOnWindow(false, function(aWin) { + info("Test on public window"); checkRememberOption(false, aWin, function() { checkSettingDialog(false, aWin, finish); }); }); }); }); }); } + +function waitForWindowClose(aWin, aCallback) { + function observer(aSubject, aTopic, aData) { + if (aTopic == "domwindowclosed") { + info("Window closed"); + Services.ww.unregisterNotification(observer); + executeSoon(aCallback); + } + } + Services.ww.registerNotification(observer); + aWin.close(); +}
--- a/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_crh.js +++ b/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_crh.js @@ -18,31 +18,42 @@ function test() { is(crhCommand.hasAttribute("disabled"), aPrivateMode, "Clear Recent History command should be disabled according to the private browsing mode"); executeSoon(aCallback); }); }; let windowsToClose = []; - function testOnWindow(options, callback) { - let win = OpenBrowserWindow(options); - win.addEventListener("load", function onLoad() { - win.removeEventListener("load", onLoad, false); - windowsToClose.push(win); - callback(win); - }, false); + let testURI = "about:blank"; + + function testOnWindow(aIsPrivate, aCallback) { + whenNewWindowLoaded({private: aIsPrivate}, function(aWin) { + windowsToClose.push(aWin); + aWin.gBrowser.selectedBrowser.addEventListener("load", function onLoad() { + if (aWin.content.location.href != testURI) { + aWin.gBrowser.loadURI(testURI); + return; + } + aWin.gBrowser.selectedBrowser.removeEventListener("load", onLoad, true); + executeSoon(function() aCallback(aWin)); + }, true); + + aWin.gBrowser.loadURI(testURI); + }); }; registerCleanupFunction(function() { windowsToClose.forEach(function(win) { win.close(); }); }); - testOnWindow({private: true}, function(win) { + testOnWindow(true, function(win) { + info("Test on private window"); checkDisableOption(true, win, function() { - testOnWindow({}, function(win) { + testOnWindow(false, function(win) { + info("Test on public window"); checkDisableOption(false, win, finish); }); }); }); }
--- a/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_lastpbcontextexited.js +++ b/browser/components/privatebrowsing/test/browser/perwindow/browser_privatebrowsing_lastpbcontextexited.js @@ -1,26 +1,49 @@ /* 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/. */ function test() { // We need to open a new window for this so that its docshell would get destroyed // when clearing the PB mode flag. - let newWin = OpenBrowserWindow({private: true}); + function runTest(aCloseWindow, aCallback) { + let newWin = OpenBrowserWindow({private: true}); + SimpleTest.waitForFocus(function() { + let expectedExiting = true; + let expectedExited = false; + let observerExiting = { + observe: function(aSubject, aTopic, aData) { + is(aTopic, "last-pb-context-exiting", "Correct topic should be dispatched (exiting)"); + is(expectedExiting, true, "notification not expected yet (exiting)"); + expectedExited = true; + Services.obs.removeObserver(observerExiting, "last-pb-context-exiting", false); + } + }; + let observerExited = { + observe: function(aSubject, aTopic, aData) { + is(aTopic, "last-pb-context-exited", "Correct topic should be dispatched (exited)"); + is(expectedExited, true, "notification not expected yet (exited)"); + Services.obs.removeObserver(observerExited, "last-pb-context-exited", false); + aCallback(); + } + }; + Services.obs.addObserver(observerExiting, "last-pb-context-exiting", false); + Services.obs.addObserver(observerExited, "last-pb-context-exited", false); + expectedExiting = true; + aCloseWindow(newWin); + newWin = null; + SpecialPowers.forceGC(); + }, newWin); + } + waitForExplicitFinish(); - SimpleTest.waitForFocus(function() { - let expected = false; - let observer = { - observe: function(aSubject, aTopic, aData) { - is(aTopic, "last-pb-context-exited", "Correct topic should be dispatched"); - is(expected, true, "notification not expected yet"); - Services.obs.removeObserver(observer, "last-pb-context-exited", false); - finish(); - } - }; - Services.obs.addObserver(observer, "last-pb-context-exited", false); - expected = true; - newWin.close(); // this will cause the docshells to leave PB mode - newWin = null; - SpecialPowers.forceGC(); - }, newWin); + + runTest(function(newWin) { + // Simulate pressing the window close button + newWin.document.getElementById("cmd_closeWindow").doCommand(); + }, function () { + runTest(function(newWin) { + // Simulate closing the last tab + newWin.document.getElementById("cmd_close").doCommand(); + }, finish); + }); }
--- a/browser/components/shell/test/browser_420786.js +++ b/browser/components/shell/test/browser_420786.js @@ -72,14 +72,24 @@ function onPageLoad() { function test() { var osString = Cc["@mozilla.org/xre/app-info;1"]. getService(Ci.nsIXULRuntime).OS; if (osString != "Linux") { todo(false, "This test is Linux specific for now."); return; } + try { + // If GSettings is available, then the GConf tests + // will fail + var gsettings = Cc["@mozilla.org/gsettings-service;1"]. + getService(Ci.nsIGSettingsService). + getCollectionForSchema("org.gnome.desktop.background"); + todo(false, "This test doesn't work when GSettings is available"); + return; + } catch(e) { } + gBrowser.selectedTab = gBrowser.addTab(); gBrowser.selectedBrowser.addEventListener("load", onPageLoad, true); content.location = "about:logo"; waitForExplicitFinish(); }
--- a/browser/components/shell/test/unit/test_421977.js +++ b/browser/components/shell/test/unit/test_421977.js @@ -62,16 +62,25 @@ function checkShellToGConfColor(aShellCo } function run_test() { // This test is Linux specific for now if (!("@mozilla.org/gnome-gconf-service;1" in Cc)) return; + try { + // If GSettings is available, then the GConf tests + // will fail + var gsettings = Cc["@mozilla.org/gsettings-service;1"]. + getService(Ci.nsIGSettingsService). + getCollectionForSchema("org.gnome.desktop.background"); + return; + } catch(e) { } + gGConf = Cc["@mozilla.org/gnome-gconf-service;1"]. getService(Ci.nsIGConfService); gShell = Cc["@mozilla.org/browser/shell-service;1"]. getService(Ci.nsIShellService); // Save the original background color so that we can restore it // after the test.
--- a/build/ConfigStatus.py +++ b/build/ConfigStatus.py @@ -6,49 +6,28 @@ # drop-in replacement for autoconf 2.13's config.status, with features # borrowed from autoconf > 2.5, and additional features. from __future__ import with_statement from optparse import OptionParser import sys, re, os, posixpath, ntpath import errno from StringIO import StringIO +from os.path import relpath + # Standalone js doesn't have virtualenv. sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'config')) from Preprocessor import Preprocessor # Basic logging facility verbose = False def log(string): if verbose: print >>sys.stderr, string -# We need relpath, but it is introduced in python 2.6 -# http://docs.python.org/library/os.path.html -def my_relpath(path, start): - """ - Return a relative version of a path - from /usr/lib/python2.6/posixpath.py - """ - - if not path: - raise ValueError("no path specified") - - start_list = os.path.abspath(start).split(os.path.sep) - path_list = os.path.abspath(path).split(os.path.sep) - - # Work out how much of the filepath is shared by start and path. - i = len(os.path.commonprefix([start_list, path_list])) - - rel_list = [os.path.pardir] * (len(start_list)-i) + path_list[i:] - if not rel_list: - return os.curdir - return os.path.join(*rel_list) - -relpath = getattr(os.path, "relpath", my_relpath) def ensureParentDir(file): '''Ensures the directory parent to the given file exists''' dir = os.path.dirname(file) if dir and not os.path.exists(dir): try: os.makedirs(dir) except OSError, error:
new file mode 100644 --- /dev/null +++ b/build/autoconf/python-virtualenv.m4 @@ -0,0 +1,77 @@ +dnl This Source Code Form is subject to the terms of the Mozilla Public +dnl License, v. 2.0. If a copy of the MPL was not distributed with this +dnl file, You can obtain one at http://mozilla.org/MPL/2.0/. + +AC_DEFUN([MOZ_PYTHON], +[ + +dnl We honor the Python path defined in an environment variable. This is used +dnl to pass the virtualenv's Python from the main configure to SpiderMonkey's +dnl configure, for example. +if test -z "$PYTHON"; then + MOZ_PATH_PROGS(PYTHON, $PYTHON python2.7 python) + if test -z "$PYTHON"; then + AC_MSG_ERROR([python was not found in \$PATH]) + fi +else + AC_MSG_RESULT([Using Python from environment variable \$PYTHON]) +fi + +_virtualenv_topsrcdir= +_virtualenv_populate_path= + +dnl If this is a mozilla-central, we'll find the virtualenv in the top +dnl source directory. If this is a SpiderMonkey build, we assume we're at +dnl js/src and try to find the virtualenv from the mozilla-central root. +for base in $MOZILLA_CENTRAL_PATH $_topsrcdir $_topsrcdir/../..; do + possible=$base/build/virtualenv/populate_virtualenv.py + + if test -e $possible; then + _virtualenv_topsrcdir=$base + _virtualenv_populate_path=$possible + break + fi +done + +if test -z $_virtualenv_populate_path; then + AC_MSG_ERROR([Unable to find Virtualenv population script. In order +to build, you will need mozilla-central's virtualenv. + +If you are building from a mozilla-central checkout, you should never see this +message. If you are building from a source archive, the source archive was +likely not created properly (it is missing the virtualenv files). + +If you have a copy of mozilla-central available, define the +MOZILLA_CENTRAL_PATH environment variable to the top source directory of +mozilla-central and relaunch configure.]) + +fi + +if test -z $DONT_POPULATE_VIRTUALENV; then + AC_MSG_RESULT([Creating Python environment]) + dnl This verifies our Python version is sane and ensures the Python + dnl virtualenv is present and up to date. It sanitizes the environment + dnl for us, so we don't need to clean anything out. + $PYTHON $_virtualenv_populate_path \ + $_virtualenv_topsrcdir $MOZ_BUILD_ROOT/_virtualenv || exit 1 + + case "$host_os" in + mingw*) + PYTHON=`cd $MOZ_BUILD_ROOT && pwd -W`/_virtualenv/Scripts/python.exe + ;; + *) + PYTHON=$MOZ_BUILD_ROOT/_virtualenv/bin/python + ;; + esac +fi + +AC_SUBST(PYTHON) + +AC_MSG_CHECKING([Python environment is Mozilla virtualenv]) +$PYTHON -c "import mozbuild.base" +if test "$?" != 0; then + AC_MSG_ERROR([Python environment does not appear to be sane.]) +fi +AC_MSG_RESULT([yes]) +]) +
--- a/build/automation.py.in +++ b/build/automation.py.in @@ -269,48 +269,47 @@ class Automation(object): def setupPermissionsDatabase(self, profileDir, permissions): # Open database and create table permDB = sqlite3.connect(os.path.join(profileDir, "permissions.sqlite")) cursor = permDB.cursor(); cursor.execute("PRAGMA user_version=3"); # SQL copied from nsPermissionManager.cpp - cursor.execute("""CREATE TABLE moz_hosts ( - id INTEGER PRIMARY KEY, - host TEXT, - type TEXT, - permission INTEGER, - expireType INTEGER, - expireTime INTEGER, - appId INTEGER, - isInBrowserElement INTEGER)""") + cursor.execute("""CREATE TABLE IF NOT EXISTS moz_hosts ( + id INTEGER PRIMARY KEY, + host TEXT, + type TEXT, + permission INTEGER, + expireType INTEGER, + expireTime INTEGER, + appId INTEGER, + isInBrowserElement INTEGER)""") # Insert desired permissions - c = 0 for perm in permissions.keys(): for host,allow in permissions[perm]: - c += 1 - cursor.execute("INSERT INTO moz_hosts values(?, ?, ?, ?, 0, 0, 0, 0)", - (c, host, perm, 1 if allow else 2)) + cursor.execute("INSERT INTO moz_hosts values(NULL, ?, ?, ?, 0, 0, 0, 0)", + (host, perm, 1 if allow else 2)) # Commit and close permDB.commit() cursor.close() def setupTestApps(self, profileDir, apps): - webappJSONTemplate = Template(""""$name": { -"origin": "$origin", -"installOrigin": "$origin", -"receipt": null, -"installTime": 132333986000, -"manifestURL": "$manifestURL", -"localId": $localId, -"appStatus": $appStatus, -"csp": "$csp" + webappJSONTemplate = Template(""""$id": { + "origin": "$origin", + "installOrigin": "$origin", + "receipt": null, + "installTime": 132333986000, + "manifestURL": "$manifestURL", + "localId": $localId, + "id": "$id", + "appStatus": $appStatus, + "csp": "$csp" }""") manifestTemplate = Template("""{ "name": "$name", "csp": "$csp", "description": "$description", "launch_path": "/", "developer": { @@ -328,46 +327,109 @@ class Automation(object): "default_locale": "en-US", "icons": { } } """) # Create webapps/webapps.json webappsDir = os.path.join(profileDir, "webapps") - os.mkdir(webappsDir); + if not os.access(webappsDir, os.F_OK): + os.mkdir(webappsDir) + + lineRe = re.compile(r'(.*?)"(.*?)": (.*)') + + webappsJSONFilename = os.path.join(webappsDir, "webapps.json") + webappsJSON = [] + if os.access(webappsJSONFilename, os.F_OK): + # If there is an existing webapps.json file (which will be the case for + # b2g), we parse the data in the existing file before appending test + # test apps to it. + startId = 1 + webappsJSONFile = open(webappsJSONFilename, "r") + contents = webappsJSONFile.read() - webappsJSON = [] + for app_content in contents.split('},'): + app = {} + # ghetto json parser needed due to lack of json/simplejson on test slaves + for line in app_content.split('\n'): + m = lineRe.match(line) + if m: + value = m.groups()[2] + # remove any trailing commas + if value[-1:] == ',': + value = value[:-1] + # set the app name from a line that looks like this: + # "name.gaiamobile.org": { + if value == '{': + app['id'] = m.groups()[1] + # parse string, None, bool and int types + elif value[0:1] == '"': + app[m.groups()[1]] = value[1:-1] + elif value == "null": + app[m.groups()[1]] = None + elif value == "true": + app[m.groups()[1]] = True + elif value == "false": + app[m.groups()[1]] = False + else: + app[m.groups()[1]] = int(value) + if app: + webappsJSON.append(app) + + webappsJSONFile.close() + + startId = 1 + for app in webappsJSON: + if app['localId'] >= startId: + startId = app['localId'] + 1 + if not app.get('csp'): + app['csp'] = '' + if not app.get('appStatus'): + app['appStatus'] = 3 + for localId, app in enumerate(apps): - app['localId'] = localId + 1 # Has to be 1..n - webappsJSON.append(webappJSONTemplate.substitute(app)) - webappsJSON = '{\n' + ',\n'.join(webappsJSON) + '\n}\n' + app['localId'] = localId + startId # localId must be from 1..N + if not app.get('id'): + app['id'] = app['name'] + webappsJSON.append(app) - webappsJSONFile = open(os.path.join(webappsDir, "webapps.json"), "a") - webappsJSONFile.write(webappsJSON) + contents = [] + for app in webappsJSON: + contents.append(webappJSONTemplate.substitute(app)) + contents = '{\n' + ',\n'.join(contents) + '\n}\n' + + webappsJSONFile = open(webappsJSONFilename, "w") + webappsJSONFile.write(contents) webappsJSONFile.close() # Create manifest file for each app. for app in apps: manifest = manifestTemplate.substitute(app) manifestDir = os.path.join(webappsDir, app['name']) os.mkdir(manifestDir) manifestFile = open(os.path.join(manifestDir, "manifest.webapp"), "a") manifestFile.write(manifest) manifestFile.close() - def initializeProfile(self, profileDir, extraPrefs = [], useServerLocations = False): + def initializeProfile(self, profileDir, extraPrefs=[], + useServerLocations=False, + initialProfile=None): " Sets up the standard testing profile." prefs = [] # Start with a clean slate. shutil.rmtree(profileDir, True) - os.mkdir(profileDir) + + if initialProfile: + shutil.copytree(initialProfile, profileDir) + else: + os.mkdir(profileDir) # Set up permissions database locations = self.readLocations() self.setupPermissionsDatabase(profileDir, {'allowXULXBL':[(l.host, 'noxul' not in l.options) for l in locations]}); part = """\ user_pref("social.skipLoadingProviders", true); @@ -595,49 +657,49 @@ user_pref("camino.use_system_proxy_setti }, { 'name': 'https_example_csp_certified', 'csp': "default-src *; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'", 'origin': 'https://example.com', 'manifestURL': 'https://example.com/manifest_csp_cert.webapp', 'description': 'https://example.com Certified App with manifest policy', 'appStatus': _APP_STATUS_CERTIFIED - }, + }, { 'name': 'https_example_csp_installed', 'csp': "default-src *; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'", 'origin': 'https://example.com', 'manifestURL': 'https://example.com/manifest_csp_inst.webapp', 'description': 'https://example.com Installed App with manifest policy', 'appStatus': _APP_STATUS_INSTALLED - }, + }, { 'name': 'https_example_csp_privileged', 'csp': "default-src *; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'", 'origin': 'https://example.com', 'manifestURL': 'https://example.com/manifest_csp_priv.webapp', 'description': 'https://example.com Privileged App with manifest policy', 'appStatus': _APP_STATUS_PRIVILEGED - }, + }, { 'name': 'https_a_domain_certified', - 'csp' : "", + 'csp': "", 'origin': 'https://acertified.com', 'manifestURL': 'https://acertified.com/manifest.webapp', 'description': 'https://acertified.com Certified App', 'appStatus': _APP_STATUS_CERTIFIED - }, + }, { 'name': 'https_a_domain_privileged', 'csp': "", 'origin': 'https://aprivileged.com', 'manifestURL': 'https://aprivileged.com/manifest.webapp', 'description': 'https://aprivileged.com Privileged App ', 'appStatus': _APP_STATUS_PRIVILEGED - }, + }, ]; self.setupTestApps(profileDir, apps) def addCommonOptions(self, parser): "Adds command-line options which are common to mochitest and reftest." parser.add_option("--setpref", action = "append", type = "string", @@ -1028,17 +1090,17 @@ user_pref("camino.use_system_proxy_setti def checkForCrashes(self, profileDir, symbolsPath): return automationutils.checkForCrashes(os.path.join(profileDir, "minidumps"), symbolsPath, self.lastTestSeen) def runApp(self, testURL, env, app, profileDir, extraArgs, runSSLTunnel = False, utilityPath = None, xrePath = None, certPath = None, debuggerInfo = None, symbolsPath = None, - timeout = -1, maxTime = None): + timeout = -1, maxTime = None, onLaunch = None): """ Run the app, log the duration it took to execute, return the status code. Kills the app if it runs for longer than |maxTime| seconds, or outputs nothing for |timeout| seconds. """ if utilityPath == None: utilityPath = self.DIST_BIN if xrePath == None: @@ -1085,16 +1147,21 @@ user_pref("camino.use_system_proxy_setti self.lastTestSeen = "automation.py" proc = self.Process([cmd] + args, env = self.environment(env, xrePath = xrePath, crashreporter = not debuggerInfo), stdout = outputPipe, stderr = subprocess.STDOUT) self.log.info("INFO | automation.py | Application pid: %d", proc.pid) + if onLaunch is not None: + # Allow callers to specify an onLaunch callback to be fired after the + # app is launched. + onLaunch() + status = self.waitForFinish(proc, utilityPath, timeout, maxTime, startTime, debuggerInfo, symbolsPath) self.log.info("INFO | automation.py | Application ran for: %s", str(datetime.now() - startTime)) # Do a final check for zombie child processes. zombieProcesses = self.checkForZombies(processLog) crashed = self.checkForCrashes(profileDir, symbolsPath)
--- a/build/mobile/b2gautomation.py +++ b/build/mobile/b2gautomation.py @@ -43,17 +43,17 @@ class B2GRemoteAutomation(Automation): self._is_emulator = False self.test_script = None self.test_script_args = None # Default our product to b2g self._product = "b2g" self.lastTestSeen = "b2gautomation.py" # Default log finish to mochitest standard - self.logFinish = 'INFO SimpleTest FINISHED' + self.logFinish = 'INFO SimpleTest FINISHED' Automation.__init__(self) def setEmulator(self, is_emulator): self._is_emulator = is_emulator def setDeviceManager(self, deviceManager): self._devicemanager = deviceManager @@ -80,17 +80,17 @@ class B2GRemoteAutomation(Automation): # so no copying of os.environ if env is None: env = {} # We always hide the results table in B2G; it's much slower if we don't. env['MOZ_HIDE_RESULTS_TABLE'] = '1' return env - def waitForNet(self): + def waitForNet(self): active = False time_out = 0 while not active and time_out < 40: data = self._devicemanager._runCmd(['shell', '/system/bin/netcfg']).stdout.readlines() data.pop(0) for line in data: if (re.search(r'UP\s+(?:[0-9]{1,3}\.){3}[0-9]{1,3}', line)): active = True @@ -101,25 +101,30 @@ class B2GRemoteAutomation(Automation): def checkForCrashes(self, directory, symbolsPath): # XXX: This will have to be updated after crash reporting on b2g # is in place. dumpDir = tempfile.mkdtemp() self._devicemanager.getDirectory(self._remoteProfile + '/minidumps/', dumpDir) crashed = automationutils.checkForCrashes(dumpDir, symbolsPath, self.lastTestSeen) try: - shutil.rmtree(dumpDir) + shutil.rmtree(dumpDir) except: - print "WARNING: unable to remove directory: %s" % (dumpDir) + print "WARNING: unable to remove directory: %s" % (dumpDir) return crashed - def initializeProfile(self, profileDir, extraPrefs = [], useServerLocations = False): + def initializeProfile(self, profileDir, extraPrefs=[], + useServerLocations=False, + initialProfile=None): # add b2g specific prefs extraPrefs.extend(["browser.manifestURL='dummy (bug 772307)'"]) - return Automation.initializeProfile(self, profileDir, extraPrefs, useServerLocations) + return Automation.initializeProfile(self, profileDir, + extraPrefs, + useServerLocations, + initialProfile) def buildCommandLine(self, app, debuggerInfo, profileDir, testURL, extraArgs): # if remote profile is specified, use that instead if (self._remoteProfile): profileDir = self._remoteProfile cmd, args = Automation.buildCommandLine(self, app, debuggerInfo, profileDir, testURL, extraArgs) @@ -160,17 +165,17 @@ class B2GRemoteAutomation(Automation): def getDeviceStatus(self, serial=None): # Get the current status of the device. If we know the device # serial number, we look for that, otherwise we use the (presumably # only) device shown in 'adb devices'. serial = serial or self._devicemanager.deviceSerial status = 'unknown' for line in self._devicemanager._runCmd(['devices']).stdout.readlines(): - result = re.match('(.*?)\t(.*)', line) + result = re.match('(.*?)\t(.*)', line) if result: thisSerial = result.group(1) if not serial or thisSerial == serial: serial = thisSerial status = result.group(2) return (serial, status) @@ -218,19 +223,19 @@ class B2GRemoteAutomation(Automation): # reboot device so it starts up with the mochitest profile # XXX: We could potentially use 'stop b2g' + 'start b2g' to achieve # a similar effect; will see which is more stable while attempting # to bring up the continuous integration. if not self._is_emulator: self.rebootDevice() time.sleep(5) - #wait for wlan to come up + #wait for wlan to come up if not self.waitForNet(): - raise Exception("network did not come up, please configure the network" + + raise Exception("network did not come up, please configure the network" + " prior to running before running the automation framework") # stop b2g self._devicemanager._runCmd(['shell', 'stop', 'b2g']) time.sleep(5) # relaunch b2g inside b2g instance instance = self.B2GInstance(self._devicemanager) @@ -329,15 +334,38 @@ class B2GRemoteAutomation(Automation): lines = [] while True: try: lines.append(self.queue.get_nowait()) except Queue.Empty: break return '\n'.join(lines) - def wait(self, timeout = None): + def wait(self, timeout=None): # this should never happen raise Exception("'wait' called on B2GInstance") def kill(self): # this should never happen raise Exception("'kill' called on B2GInstance") + + +class B2GDesktopAutomation(Automation): + + def buildCommandLine(self, app, debuggerInfo, profileDir, testURL, extraArgs): + """ build the application command line """ + + cmd = os.path.abspath(app) + args = [] + + if debuggerInfo: + args.extend(debuggerInfo["args"]) + args.append(cmd) + cmd = os.path.abspath(debuggerInfo["path"]) + + if self.IS_MAC: + args.append("-foreground") + + profileDirectory = profileDir + "/" + + args.extend(("-profile", profileDirectory)) + args.extend(extraArgs) + return cmd, args
--- a/build/unix/elfhack/elf.cpp +++ b/build/unix/elfhack/elf.cpp @@ -254,17 +254,25 @@ Elf::Elf(std::ifstream &file) if (phdr.p_type == PT_PHDR) segment->addSection(phdr_section); for (int j = 1; j < ehdr->e_shnum; j++) if (phdr.contains(sections[j])) segment->addSection(sections[j]); // Make sure that our view of segments corresponds to the original // ELF file. assert(segment->getFileSize() == phdr.p_filesz); - assert(segment->getMemSize() == phdr.p_memsz); + // gold makes TLS segments end on an aligned virtual address, even + // when the underlying section ends before that, while bfd ld + // doesn't. It's fine if we don't keep that alignment. + unsigned int memsize = segment->getMemSize(); + if (phdr.p_type == PT_TLS && memsize != phdr.p_memsz) { + unsigned int align = segment->getAlign(); + memsize = (memsize + align - 1) & ~(align - 1); + } + assert(memsize == phdr.p_memsz); segments.push_back(segment); } new (&eh_entry) ElfLocation(ehdr->e_entry, this); } Elf::~Elf() {
--- a/build/unix/elfhack/test.c +++ b/build/unix/elfhack/test.c @@ -117,18 +117,22 @@ static int ret = 1; int print_status() { fprintf(stderr, "%s\n", ret ? "FAIL" : "PASS"); return ret; } /* On ARM, this creates a .tbss section before .init_array, which * elfhack could then pick instead of .init_array. * Also, when .tbss is big enough, elfhack may wrongfully consider - * following sections as part of the PT_TLS segment. */ -__thread int foo[1024]; + * following sections as part of the PT_TLS segment. + * Finally, gold makes TLS segments end on an aligned virtual address, + * even when the underlying section ends before that, and elfhack + * sanity checks may yield an error. */ +__thread int foo; +__thread long long int bar[512]; void end_test() { static int count = 0; /* Only exit when both constructors have been called */ if (++count == 2) ret = 0; }
--- a/build/valgrind/cross-architecture.sup +++ b/build/valgrind/cross-architecture.sup @@ -250,16 +250,24 @@ Bug 812423 Memcheck:Leak fun:malloc fun:_ZN2js15ArgumentsObject6createI18CopyStackFrameArgsEEPS0_P9JSContextN2JS6HandleIP8JSScriptEENS7_IP10JSFunctionEEjRT_ fun:_ZN2js15ArgumentsObject14createExpectedEP9JSContextPNS_10StackFrameE ... } { + Bug 812423 + Memcheck:Leak + fun:malloc + fun:_ZN2js15ArgumentsObject6createI13CopyFrameArgsEEPS0_P9JSContextN2JS6HandleIP8JSScriptEENS7_IP10JSFunctionEEjRT_ + fun:_ZN2js15ArgumentsObject14createExpectedEP9JSContextNS_16AbstractFramePtrE + ... +} +{ Bug 823782 Memcheck:Leak fun:malloc ... fun:_ZN2js6ctypes7LibraryL7DeclareEP9JSContextjPN2JS5ValueE ... } {
--- a/build/virtualenv/populate_virtualenv.py +++ b/build/virtualenv/populate_virtualenv.py @@ -240,22 +240,18 @@ class VirtualenvManager(object): program = [sys.executable, setup] program.extend(arguments) # We probably could call the contents of this file inside the context # of this interpreter using execfile() or similar. However, if global # variables like sys.path are adjusted, this could cause all kinds of # havoc. While this may work, invoking a new process is safer. - # TODO Use check_output when we require Python 2.7. - fn = getattr(subprocess, 'check_output', - VirtualenvManager._check_output) - try: - output = fn(program, cwd=directory, stderr=subprocess.STDOUT) + output = subprocess.check_output(program, cwd=directory, stderr=subprocess.STDOUT) print(output) except subprocess.CalledProcessError as e: if 'Python.h: No such file or directory' in e.output: print('WARNING: Python.h not found. Install Python development headers.') else: print(e.output) raise Exception('Error installing package: %s' % directory) @@ -289,31 +285,16 @@ class VirtualenvManager(object): If you run a random Python script and wish to "activate" the virtualenv, you can simply instantiate an instance of this class and call .ensure() and .activate() to make the virtualenv active. """ execfile(self.activate_path, dict(__file__=self.activate_path)) - # TODO Eliminate when we require Python 2.7. - @staticmethod - def _check_output(*args, **kwargs): - """Python 2.6 compatible implementation of subprocess.check_output.""" - proc = subprocess.Popen(stdout=subprocess.PIPE, *args, **kwargs) - output, unused_err = proc.communicate() - retcode = proc.poll() - if retcode: - cmd = kwargs.get('args', args[0]) - e = subprocess.CalledProcessError(retcode, cmd) - e.output = output - raise e - - return output - def verify_python_version(log_handle): """Ensure the current version of Python is sufficient.""" major, minor = sys.version_info[:2] if major != MINIMUM_PYTHON_MAJOR or minor < MINIMUM_PYTHON_MINOR: log_handle.write('Python %d.%d or greater (but not Python 3) is ' 'required to build. ' %
--- a/configure.in +++ b/configure.in @@ -142,39 +142,17 @@ if test -e $_objdir/CLOBBER; then echo " ***" exit 1 break; fi else touch $_objdir/CLOBBER fi -MOZ_PATH_PROGS(PYTHON, $PYTHON python2.7 python) -if test -z "$PYTHON"; then - AC_MSG_ERROR([python was not found in \$PATH]) -fi - -AC_MSG_RESULT([Creating Python environment]) -dnl This verifies our Python version is sane and ensures the Python -dnl virtualenv is present and up to date. It sanitizes the environment -dnl for us, so we don't need to clean anything out. -$PYTHON $_topsrcdir/build/virtualenv/populate_virtualenv.py \ - $_topsrcdir $MOZ_BUILD_ROOT/_virtualenv || exit 1 - -dnl Create a virtualenv where we can install local Python packages -case "$host_os" in -mingw*) - PYTHON=`cd $MOZ_BUILD_ROOT && pwd -W`/_virtualenv/Scripts/python.exe - ;; -*) - PYTHON=$MOZ_BUILD_ROOT/_virtualenv/bin/python - ;; -esac - -AC_SUBST(PYTHON) +MOZ_PYTHON MOZ_DEFAULT_COMPILER COMPILE_ENVIRONMENT=1 MOZ_ARG_DISABLE_BOOL(compile-environment, [ --disable-compile-environment Disable compiler/library checks.], COMPILE_ENVIRONMENT= ) @@ -1398,16 +1376,19 @@ if test -n "$MOZ_LLVM_HACKS"; then fi AC_SUBST(MOZ_NO_WLZDEFS) AC_SUBST(MOZ_CFLAGS_NSS) dnl ======================================================== dnl GNU specific defaults dnl ======================================================== if test "$GNU_CC"; then + # Per bug 719659 comment 2, some of the headers on ancient build machines + # may require gnu89 inline semantics. But otherwise, we use C99. + CFLAGS="$CFLAGS -std=gnu99 -fgnu89-inline" # FIXME: Let us build with strict aliasing. bug 414641. CFLAGS="$CFLAGS -fno-strict-aliasing" MKSHLIB='$(CXX) $(CXXFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-h,$@ -o $@' MKCSHLIB='$(CC) $(CFLAGS) $(DSO_PIC_CFLAGS) $(DSO_LDOPTS) -Wl,-h,$@ -o $@' DSO_LDOPTS='-shared' if test "$GCC_USE_GNU_LD"; then # Some tools like ASan use a runtime library that is only # linked against executables, so we must allow undefined @@ -9342,15 +9323,18 @@ if test -n "$MOZ_GLUE_PROGRAM_LDFLAGS"; fi if test "$MOZ_NATIVE_ZLIB" != 1 -a "$OS_ARCH" = "WINNT"; then MOZ_ZLIB_LIBS= fi export MOZ_NATIVE_ZLIB export MOZ_ZLIB_CFLAGS export MOZ_ZLIB_LIBS export MOZ_APP_NAME +export DONT_POPULATE_VIRTUALENV=1 +export PYTHON +export MOZILLA_CENTRAL_PATH=$_topsrcdir export STLPORT_CPPFLAGS export STLPORT_LDFLAGS export STLPORT_LIBS AC_OUTPUT_SUBDIRS(js/src) ac_configure_args="$_SUBDIR_CONFIG_ARGS" fi # COMPILE_ENVIRONMENT && !LIBXUL_SDK_DIR
--- a/content/base/public/nsContentUtils.h +++ b/content/base/public/nsContentUtils.h @@ -433,16 +433,23 @@ public: { return sSecurityManager; } // Returns the subject principal. Guaranteed to return non-null. May only // be called when nsContentUtils is initialized. static nsIPrincipal* GetSubjectPrincipal(); + // Returns the principal of the given JS object. This should never be null + // for any object in the XPConnect runtime. + // + // In general, being interested in the principal of an object is enough to + // guarantee that the return value is non-null. + static nsIPrincipal* GetObjectPrincipal(JSObject* aObj); + static nsresult GenerateStateKey(nsIContent* aContent, const nsIDocument* aDocument, nsACString& aKey); /** * Create a new nsIURI from aSpec, using aBaseURI as the base. The * origin charset of the new nsIURI will be the document charset of * aDocument. @@ -2205,16 +2212,17 @@ private: // Combined code for PushNull() and Push(JSContext*) bool DoPush(JSContext* cx); nsCOMPtr<nsIScriptContext> mScx; bool mScriptIsRunning; bool mPushedSomething; #ifdef DEBUG JSContext* mPushedContext; + unsigned mCompartmentDepthOnEntry; #endif }; class NS_STACK_CLASS nsAutoScriptBlocker { public: nsAutoScriptBlocker(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM) { MOZ_GUARD_OBJECT_NOTIFIER_INIT; nsContentUtils::AddScriptBlocker();
--- a/content/base/src/EventSource.cpp +++ b/content/base/src/EventSource.cpp @@ -74,18 +74,16 @@ EventSource::~EventSource() { Close(); } //----------------------------------------------------------------------------- // EventSource::nsISupports //----------------------------------------------------------------------------- -NS_IMPL_CYCLE_COLLECTION_CLASS(EventSource) - NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(EventSource) bool isBlack = tmp->IsBlack(); if (isBlack || tmp->mWaitingForOnStopRequest) { if (tmp->mListenerManager) { tmp->mListenerManager->MarkForCC(); } if (!isBlack && tmp->PreservingWrapper()) { xpc_UnmarkGrayObject(tmp->GetWrapperPreserveColor()); @@ -525,25 +523,17 @@ public: return NS_OK; } private: nsRefPtr<EventSource> mEventSource; }; -NS_IMPL_CYCLE_COLLECTION_CLASS(AsyncVerifyRedirectCallbackFwr) - -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(AsyncVerifyRedirectCallbackFwr) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEventSource) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END - -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(AsyncVerifyRedirectCallbackFwr) - NS_IMPL_CYCLE_COLLECTION_UNLINK(mEventSource) -NS_IMPL_CYCLE_COLLECTION_UNLINK_END +NS_IMPL_CYCLE_COLLECTION_1(AsyncVerifyRedirectCallbackFwr, mEventSource) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AsyncVerifyRedirectCallbackFwr) NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_ENTRY(nsIAsyncVerifyRedirectCallback) NS_INTERFACE_MAP_END NS_IMPL_CYCLE_COLLECTING_ADDREF(AsyncVerifyRedirectCallbackFwr) NS_IMPL_CYCLE_COLLECTING_RELEASE(AsyncVerifyRedirectCallbackFwr)
--- a/content/base/src/FileIOObject.cpp +++ b/content/base/src/FileIOObject.cpp @@ -24,18 +24,16 @@ NS_IMPL_ADDREF_INHERITED(FileIOObject, n NS_IMPL_RELEASE_INHERITED(FileIOObject, nsDOMEventTargetHelper) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(FileIOObject) NS_INTERFACE_MAP_ENTRY(nsITimerCallback) NS_INTERFACE_MAP_ENTRY(nsIStreamListener) NS_INTERFACE_MAP_ENTRY(nsIRequestObserver) NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper) -NS_IMPL_CYCLE_COLLECTION_CLASS(FileIOObject) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(FileIOObject, nsDOMEventTargetHelper) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mProgressNotifier) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mError) // Can't traverse mChannel because it's a multithreaded object. NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(FileIOObject,
--- a/content/base/src/FragmentOrElement.cpp +++ b/content/base/src/FragmentOrElement.cpp @@ -958,18 +958,16 @@ FragmentOrElement::FireNodeInserted(nsID } } } //---------------------------------------------------------------------- // nsISupports implementation -NS_IMPL_CYCLE_COLLECTION_CLASS(FragmentOrElement) - #define SUBTREE_UNBINDINGS_PER_RUNNABLE 500 class ContentUnbinder : public nsRunnable { public: ContentUnbinder() { nsLayoutStatics::AddRef();
--- a/content/base/src/WebSocket.cpp +++ b/content/base/src/WebSocket.cpp @@ -571,18 +571,16 @@ WebSocket::Constructor(JSContext* aCx, if (NS_FAILED(rv)) { aRv.Throw(rv); return nullptr; } return webSocket.forget(); } -NS_IMPL_CYCLE_COLLECTION_CLASS(WebSocket) - NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(WebSocket) bool isBlack = tmp->IsBlack(); if (isBlack|| tmp->mKeepingAlive) { if (tmp->mListenerManager) { tmp->mListenerManager->MarkForCC(); } if (!isBlack && tmp->PreservingWrapper()) { xpc_UnmarkGrayObject(tmp->GetWrapperPreserveColor());
--- a/content/base/src/nsContentIterator.cpp +++ b/content/base/src/nsContentIterator.cpp @@ -1141,17 +1141,16 @@ protected: }; NS_IMPL_ADDREF_INHERITED(nsContentSubtreeIterator, nsContentIterator) NS_IMPL_RELEASE_INHERITED(nsContentSubtreeIterator, nsContentIterator) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsContentSubtreeIterator) NS_INTERFACE_MAP_END_INHERITING(nsContentIterator) -NS_IMPL_CYCLE_COLLECTION_CLASS(nsContentSubtreeIterator) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsContentSubtreeIterator, nsContentIterator) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRange) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsContentSubtreeIterator, nsContentIterator) NS_IMPL_CYCLE_COLLECTION_UNLINK(mRange) NS_IMPL_CYCLE_COLLECTION_UNLINK_END
--- a/content/base/src/nsContentList.cpp +++ b/content/base/src/nsContentList.cpp @@ -39,17 +39,16 @@ #endif using namespace mozilla::dom; nsBaseContentList::~nsBaseContentList() { } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsBaseContentList) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsBaseContentList) NS_IMPL_CYCLE_COLLECTION_UNLINK(mElements) NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsBaseContentList) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS if (nsCCUncollectableMarker::sGeneration && tmp->IsBlack() && MOZ_LIKELY(!cb.WantAllTraces())) { @@ -140,17 +139,16 @@ nsBaseContentList::IndexOf(nsIContent *a } int32_t nsBaseContentList::IndexOf(nsIContent* aContent) { return IndexOf(aContent, true); } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsSimpleContentList) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsSimpleContentList, nsBaseContentList) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRoot) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsSimpleContentList, nsBaseContentList) NS_IMPL_CYCLE_COLLECTION_UNLINK(mRoot) NS_IMPL_CYCLE_COLLECTION_UNLINK_END
--- a/content/base/src/nsContentSink.cpp +++ b/content/base/src/nsContentSink.cpp @@ -62,17 +62,16 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION( NS_INTERFACE_MAP_ENTRY(nsICSSLoaderObserver) NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) NS_INTERFACE_MAP_ENTRY(nsIDocumentObserver) NS_INTERFACE_MAP_ENTRY(nsIMutationObserver) NS_INTERFACE_MAP_ENTRY(nsITimerCallback) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDocumentObserver) NS_INTERFACE_MAP_END -NS_IMPL_CYCLE_COLLECTION_CLASS(nsContentSink) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsContentSink) if (tmp->mDocument) { tmp->mDocument->RemoveObserver(tmp); } NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument) NS_IMPL_CYCLE_COLLECTION_UNLINK(mParser) NS_IMPL_CYCLE_COLLECTION_UNLINK(mNodeInfoManager) NS_IMPL_CYCLE_COLLECTION_UNLINK(mScriptLoader)
--- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -2326,16 +2326,27 @@ nsContentUtils::GetSubjectPrincipal() // When the ssm says the subject is null, that means system principal. if (!subject) sSecurityManager->GetSystemPrincipal(getter_AddRefs(subject)); return subject; } // static +nsIPrincipal* +nsContentUtils::GetObjectPrincipal(JSObject* aObj) +{ + // This is duplicated from nsScriptSecurityManager. We don't call through there + // because the API unnecessarily requires a JSContext for historical reasons. + JSCompartment *compartment = js::GetObjectCompartment(aObj); + JSPrincipals *principals = JS_GetCompartmentPrincipals(compartment); + return nsJSPrincipals::get(principals); +} + +// static nsresult nsContentUtils::NewURIWithDocumentCharset(nsIURI** aResult, const nsAString& aSpec, nsIDocument* aDocument, nsIURI* aBaseURI) { return NS_NewURI(aResult, aSpec, aDocument ? aDocument->GetDocumentCharacterSet().get() : nullptr, @@ -3071,16 +3082,18 @@ nsCxPusher::DoPush(JSContext* cx) mScriptIsRunning = false; mScx = nullptr; return false; } mPushedSomething = true; #ifdef DEBUG mPushedContext = cx; + if (cx) + mCompartmentDepthOnEntry = js::GetEnterCompartmentDepth(cx); #endif return true; } bool nsCxPusher::PushNull() { return DoPush(nullptr); @@ -3095,16 +3108,24 @@ nsCxPusher::Pop() mPushedSomething = false; NS_ASSERTION(!mScriptIsRunning, "Huh, this can't be happening, " "mScriptIsRunning can't be set here!"); return; } + // When we push a context, we may save the frame chain and pretend like we + // haven't entered any compartment. This gets restored on Pop(), but we can + // run into trouble if a Push/Pop are interleaved with a + // JSAutoEnterCompartment. Make sure the compartment depth right before we + // pop is the same as it was right after we pushed. + MOZ_ASSERT_IF(mPushedContext, mCompartmentDepthOnEntry == + js::GetEnterCompartmentDepth(mPushedContext)); + JSContext *unused; stack->Pop(&unused); NS_ASSERTION(unused == mPushedContext, "Unexpected context popped"); if (!mScriptIsRunning && mScx) { // No JS is running in the context, but executing the event handler might have // caused some JS to run. Tell the script context that it's done.
--- a/content/base/src/nsDOMAttribute.cpp +++ b/content/base/src/nsDOMAttribute.cpp @@ -42,18 +42,16 @@ nsDOMAttribute::nsDOMAttribute(nsDOMAttr NS_ABORT_IF_FALSE(mNodeInfo, "We must get a nodeinfo here!"); NS_ABORT_IF_FALSE(mNodeInfo->NodeType() == nsIDOMNode::ATTRIBUTE_NODE, "Wrong nodeType"); // We don't add a reference to our content. It will tell us // to drop our reference when it goes away. } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMAttribute) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMAttribute) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS if (!nsINode::Traverse(tmp, cb)) { return NS_SUCCESS_INTERRUPTED_TRAVERSE; } NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
--- a/content/base/src/nsDOMAttributeMap.cpp +++ b/content/base/src/nsDOMAttributeMap.cpp @@ -50,18 +50,16 @@ nsDOMAttributeMap::~nsDOMAttributeMap() void nsDOMAttributeMap::DropReference() { mAttributeCache.Enumerate(RemoveMapRef, nullptr); mContent = nullptr; } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMAttributeMap) - NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMAttributeMap) tmp->DropReference(); NS_IMPL_CYCLE_COLLECTION_UNLINK_END PLDHashOperator TraverseMapEntry(nsAttrHashKey::KeyType aKey, nsRefPtr<nsDOMAttribute>& aData, void* aUserArg)
--- a/content/base/src/nsDOMDataChannel.cpp +++ b/content/base/src/nsDOMDataChannel.cpp @@ -97,18 +97,16 @@ private: { DC_BINARY_TYPE_ARRAYBUFFER, DC_BINARY_TYPE_BLOB, } mBinaryType; }; DOMCI_DATA(DataChannel, nsDOMDataChannel) -NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMDataChannel) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMDataChannel, nsDOMEventTargetHelper) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMDataChannel, nsDOMEventTargetHelper) NS_IMPL_CYCLE_COLLECTION_UNLINK_END
--- a/content/base/src/nsDOMFileReader.cpp +++ b/content/base/src/nsDOMFileReader.cpp @@ -50,18 +50,16 @@ using namespace mozilla; #define LOAD_STR "load" #define LOADSTART_STR "loadstart" #define LOADEND_STR "loadend" using mozilla::dom::EncodingUtils; using mozilla::dom::FileIOObject; -NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMFileReader) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMFileReader, FileIOObject) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFile) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPrincipal) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMFileReader, FileIOObject)
--- a/content/base/src/nsDOMMutationObserver.cpp +++ b/content/base/src/nsDOMMutationObserver.cpp @@ -39,18 +39,16 @@ nsINodeList* nsDOMMutationRecord::RemovedNodes() { if (!mRemovedNodes) { mRemovedNodes = new nsSimpleContentList(mTarget); } return mRemovedNodes; } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMMutationRecord) - NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMMutationRecord) NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_END NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMMutationRecord) NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMMutationRecord) @@ -335,18 +333,16 @@ nsMutationReceiver::ContentRemoved(nsIDo void nsMutationReceiver::NodeWillBeDestroyed(const nsINode *aNode) { NS_ASSERTION(!mParent, "Shouldn't have mParent here!"); Disconnect(true); } // Observer -NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMMutationObserver) - NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMMutationObserver) NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_END NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMMutationObserver) NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMMutationObserver)
--- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -1469,18 +1469,16 @@ nsDocument::~nsDocument() // We don't want to leave residual locks on images. Make sure we're in an // unlocked state, and then clear the table. SetImageLockingState(false); mImageTracker.Clear(); mPlugins.Clear(); } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsDocument) - NS_INTERFACE_TABLE_HEAD(nsDocument) NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY NS_DOCUMENT_INTERFACE_TABLE_BEGIN(nsDocument) NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDocument) NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDOMDocumentXBL) NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIScriptObjectPrincipal) NS_INTERFACE_TABLE_ENTRY(nsDocument, nsIDOMEventTarget) NS_INTERFACE_TABLE_ENTRY(nsDocument, nsISupportsWeakReference)
--- a/content/base/src/nsDocumentEncoder.cpp +++ b/content/base/src/nsDocumentEncoder.cpp @@ -159,18 +159,16 @@ protected: // Used when context has already been serialized for // table cell selections (where parent is <tr>) bool mDisableContextSerialize; bool mIsCopying; // Set to true only while copying bool mNodeIsContainer; nsStringBuffer* mCachedBuffer; }; -NS_IMPL_CYCLE_COLLECTION_CLASS(nsDocumentEncoder) - NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDocumentEncoder) NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDocumentEncoder) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDocumentEncoder) NS_INTERFACE_MAP_ENTRY(nsIDocumentEncoder) NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_END
--- a/content/base/src/nsFrameLoader.cpp +++ b/content/base/src/nsFrameLoader.cpp @@ -252,18 +252,16 @@ nsContentView::GetId(nsContentViewId* aI // does not count chrome frames when determining depth, nor does it // prevent chrome recursion. Number is fairly arbitrary, but meant to // keep number of shells to a reasonable number on accidental recursion with a // small (but not 1) branching factor. With large branching factors the number // of shells can rapidly become huge and run us out of memory. To solve that, // we'd need to re-institute a fixed version of bug 98158. #define MAX_DEPTH_CONTENT_FRAMES 10 -NS_IMPL_CYCLE_COLLECTION_CLASS(nsFrameLoader) - NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsFrameLoader) NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocShell) NS_IMPL_CYCLE_COLLECTION_UNLINK(mMessageManager) NS_IMPL_CYCLE_COLLECTION_UNLINK(mChildMessageManager) NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsFrameLoader) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocShell)
--- a/content/base/src/nsFrameMessageManager.cpp +++ b/content/base/src/nsFrameMessageManager.cpp @@ -52,18 +52,16 @@ IsChromeProcess() if (!rt) return true; uint32_t type; rt->GetProcessType(&type); return type == nsIXULRuntime::PROCESS_TYPE_DEFAULT; } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsFrameMessageManager) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsFrameMessageManager) uint32_t count = tmp->mListeners.Length(); for (uint32_t i = 0; i < count; i++) { NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mListeners[i] mListener"); cb.NoteXPCOMChild(tmp->mListeners[i].mListener.get()); } NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mChildManagers) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
--- a/content/base/src/nsGenericDOMDataNode.cpp +++ b/content/base/src/nsGenericDOMDataNode.cpp @@ -57,18 +57,16 @@ nsGenericDOMDataNode::~nsGenericDOMDataN { NS_PRECONDITION(!IsInDoc(), "Please remove this from the document properly"); if (GetParent()) { NS_RELEASE(mParent); } } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsGenericDOMDataNode) - NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsGenericDOMDataNode) nsINode::Trace(tmp, aCallback, aClosure); NS_IMPL_CYCLE_COLLECTION_TRACE_END NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsGenericDOMDataNode) return Element::CanSkip(tmp, aRemovingAllowed); NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
--- a/content/base/src/nsInProcessTabChildGlobal.cpp +++ b/content/base/src/nsInProcessTabChildGlobal.cpp @@ -150,18 +150,16 @@ nsInProcessTabChildGlobal::Init() nsIURI* docURI = mOwner->OwnerDoc()->GetDocumentURI(); if (mGlobal && NS_SUCCEEDED(mGlobal->GetJSObject(&global)) && docURI) { xpc::SetLocationForGlobal(global, docURI); } return NS_OK; } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsInProcessTabChildGlobal) - NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsInProcessTabChildGlobal, nsDOMEventTargetHelper) NS_IMPL_CYCLE_COLLECTION_UNLINK(mMessageManager) NS_IMPL_CYCLE_COLLECTION_UNLINK(mGlobal) nsFrameScriptExecutor::Unlink(tmp); NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsInProcessTabChildGlobal,
--- a/content/base/src/nsNodeInfo.cpp +++ b/content/base/src/nsNodeInfo.cpp @@ -143,17 +143,16 @@ nsNodeInfo::nsNodeInfo(nsIAtom *aName, n NS_ABORT_IF_FALSE(aNodeType == UINT16_MAX, "Unknown node type"); } } // nsISupports -NS_IMPL_CYCLE_COLLECTION_CLASS(nsNodeInfo) NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsNodeInfo) static const char* kNSURIs[] = { " ([none])", " (xmlns)", " (xml)", " (xhtml)", " (XLink)",
--- a/content/base/src/nsNodeInfoManager.cpp +++ b/content/base/src/nsNodeInfoManager.cpp @@ -124,18 +124,16 @@ nsNodeInfoManager::~nsNodeInfoManager() if (gNodeInfoManagerLeakPRLog) PR_LOG(gNodeInfoManagerLeakPRLog, PR_LOG_DEBUG, ("NODEINFOMANAGER %p destroyed", this)); #endif nsLayoutStatics::Release(); } - -NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(nsNodeInfoManager) NS_IMPL_CYCLE_COLLECTION_UNLINK_0(nsNodeInfoManager) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsNodeInfoManager) if (tmp->mDocument && nsCCUncollectableMarker::InGeneration(cb, tmp->mDocument->GetMarkedCCGeneration())) { return NS_SUCCESS_INTERRUPTED_TRAVERSE; } if (tmp->mNonDocumentNodeInfos) {
--- a/content/base/src/nsNodeIterator.cpp +++ b/content/base/src/nsNodeIterator.cpp @@ -151,17 +151,16 @@ nsNodeIterator::~nsNodeIterator() if (!mDetached && mRoot) mRoot->RemoveMutationObserver(this); } /* * nsISupports and cycle collection stuff */ -NS_IMPL_CYCLE_COLLECTION_CLASS(nsNodeIterator) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsNodeIterator) if (!tmp->mDetached && tmp->mRoot) tmp->mRoot->RemoveMutationObserver(tmp); NS_IMPL_CYCLE_COLLECTION_UNLINK(mRoot) NS_IMPL_CYCLE_COLLECTION_UNLINK(mFilter) NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsNodeIterator) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRoot)
--- a/content/base/src/nsRange.cpp +++ b/content/base/src/nsRange.cpp @@ -248,18 +248,16 @@ nsRange::CreateRange(nsIDOMNode* aStartP range.forget(aRange); return rv; } /****************************************************** * nsISupports ******************************************************/ -NS_IMPL_CYCLE_COLLECTION_CLASS(nsRange) - NS_IMPL_CYCLE_COLLECTING_ADDREF(nsRange) NS_IMPL_CYCLE_COLLECTING_RELEASE(nsRange) DOMCI_DATA(Range, nsRange) // QueryInterface implementation for nsRange NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsRange) NS_INTERFACE_MAP_ENTRY(nsIDOMRange)
--- a/content/base/src/nsScriptLoader.cpp +++ b/content/base/src/nsScriptLoader.cpp @@ -17,16 +17,17 @@ #include "mozilla/dom/Element.h" #include "nsGkAtoms.h" #include "nsNetUtil.h" #include "nsIScriptGlobalObject.h" #include "nsIScriptContext.h" #include "nsIScriptRuntime.h" #include "nsIScriptSecurityManager.h" #include "nsIPrincipal.h" +#include "nsJSPrincipals.h" #include "nsContentPolicyUtils.h" #include "nsIHttpChannel.h" #include "nsIHttpChannelInternal.h" #include "nsIScriptElement.h" #include "nsIDOMHTMLScriptElement.h" #include "nsIDocShell.h" #include "nsContentUtils.h" #include "nsUnicharUtils.h" @@ -850,23 +851,28 @@ nsScriptLoader::EvaluateScript(nsScriptL nsCOMPtr<nsIScriptElement> oldCurrent = mCurrentScript; mCurrentScript = aRequest->mElement; // It's very important to use aRequest->mURI, not the final URI of the channel // aRequest ended up getting script data from, as the script filename. nsAutoCString url; nsContentUtils::GetWrapperSafeScriptFilename(mDocument, aRequest->mURI, url); - bool isUndefined; - rv = context->EvaluateString(aScript, globalObject->GetGlobalJSObject(), - mDocument->NodePrincipal(), - aRequest->mOriginPrincipal, - url.get(), aRequest->mLineNo, - JSVersion(aRequest->mJSVersion), nullptr, - &isUndefined); + JSVersion version = JSVersion(aRequest->mJSVersion); + if (version != JSVERSION_UNKNOWN) { + JS::CompileOptions options(context->GetNativeContext()); + options.setFileAndLine(url.get(), aRequest->mLineNo) + .setVersion(JSVersion(aRequest->mJSVersion)); + if (aRequest->mOriginPrincipal) { + options.setOriginPrincipals(nsJSPrincipals::get(aRequest->mOriginPrincipal)); + } + JS::Value ignored; + rv = context->EvaluateString(aScript, *globalObject->GetGlobalJSObject(), + options, /* aCoerceToString = */ false, &ignored); + } // Put the old script back in case it wants to do anything else. mCurrentScript = oldCurrent; JSContext *cx = nullptr; // Initialize this to keep GCC happy. cx = context->GetNativeContext(); JSAutoRequest ar(cx); context->SetProcessingScriptTag(oldProcessingScriptTag);
--- a/content/base/src/nsXMLHttpRequest.cpp +++ b/content/base/src/nsXMLHttpRequest.cpp @@ -333,18 +333,16 @@ XMLHttpRequestAuthPrompt::PromptPassword bool* aRetval) { *aRetval = false; return NS_OK; } ///////////////////////////////////////////// -NS_IMPL_CYCLE_COLLECTION_CLASS(nsXHREventTarget) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXHREventTarget, nsDOMEventTargetHelper) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXHREventTarget, nsDOMEventTargetHelper) NS_IMPL_CYCLE_COLLECTION_UNLINK_END @@ -561,18 +559,16 @@ nsXMLHttpRequest::ResetResponse() } void nsXMLHttpRequest::SetRequestObserver(nsIRequestObserver* aObserver) { mRequestObserver = aObserver; } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLHttpRequest) - NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsXMLHttpRequest) bool isBlack = tmp->IsBlack(); if (isBlack || tmp->mWaitingForOnStopRequest) { if (tmp->mListenerManager) { tmp->mListenerManager->MarkForCC(); } if (!isBlack && tmp->PreservingWrapper()) { xpc_UnmarkGrayObject(tmp->GetWrapperPreserveColor()); @@ -3506,25 +3502,17 @@ public: return NS_OK; } private: nsRefPtr<nsXMLHttpRequest> mXHR; }; -NS_IMPL_CYCLE_COLLECTION_CLASS(AsyncVerifyRedirectCallbackForwarder) - -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(AsyncVerifyRedirectCallbackForwarder) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mXHR) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END - -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(AsyncVerifyRedirectCallbackForwarder) - NS_IMPL_CYCLE_COLLECTION_UNLINK(mXHR) -NS_IMPL_CYCLE_COLLECTION_UNLINK_END +NS_IMPL_CYCLE_COLLECTION_1(AsyncVerifyRedirectCallbackForwarder, mXHR) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AsyncVerifyRedirectCallbackForwarder) NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_ENTRY(nsIAsyncVerifyRedirectCallback) NS_INTERFACE_MAP_END NS_IMPL_CYCLE_COLLECTING_ADDREF(AsyncVerifyRedirectCallbackForwarder) NS_IMPL_CYCLE_COLLECTING_RELEASE(AsyncVerifyRedirectCallbackForwarder) @@ -4007,18 +3995,16 @@ nsXMLHttpProgressEvent::nsXMLHttpProgres mInner = aInner; mCurProgress = aCurrentProgress; mMaxProgress = aMaxProgress; } nsXMLHttpProgressEvent::~nsXMLHttpProgressEvent() {} -NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLHttpProgressEvent) - DOMCI_DATA(XMLHttpProgressEvent, nsXMLHttpProgressEvent) // QueryInterface implementation for nsXMLHttpProgressEvent NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXMLHttpProgressEvent) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMProgressEvent) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIDOMEvent, nsIDOMProgressEvent) NS_INTERFACE_MAP_ENTRY(nsIDOMProgressEvent) NS_INTERFACE_MAP_ENTRY(nsIDOMLSProgressEvent) @@ -4085,18 +4071,16 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION( NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStreamListener) NS_INTERFACE_MAP_END NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXMLHttpRequestXPCOMifier) NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXMLHttpRequestXPCOMifier) // Can't NS_IMPL_CYCLE_COLLECTION_1 because mXHR has ambiguous // inheritance from nsISupports. -NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLHttpRequestXPCOMifier) - NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXMLHttpRequestXPCOMifier) if (tmp->mXHR) { tmp->mXHR->mXPCOMifier = nullptr; } NS_IMPL_CYCLE_COLLECTION_UNLINK(mXHR) NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXMLHttpRequestXPCOMifier)
--- a/content/base/test/test_websocket_basic.html +++ b/content/base/test/test_websocket_basic.html @@ -119,23 +119,23 @@ function testWebSocket2() { is(e.data, testMessage + messageCount, "[2] Received message"); if (messageCount % displayInterval == 1) { gTestElement.textContent += " " + messageCount; } }; } /** - * Sends 100+1 test messages, then receives them, calling forcegc() at each step. + * Sends testcount+1 test messages, then receives them, calling forcegc() at each step. */ function testWebSocket3() { gTestElement.textContent = "Running testWebSocket3() [can take a little while]"; const displayInterval = 10; - const testCount = 100; + const testCount = 10; const testMessage = "test message 3."; var messageCount = 0; ws = new WebSocket(kUrl, "test"); // Set this before onopen() is called, // otherwise its display would be delayed by forcegc() calls... gTestElement.textContent += "\nSending :";
--- a/content/canvas/src/CanvasRenderingContext2D.cpp +++ b/content/canvas/src/CanvasRenderingContext2D.cpp @@ -1631,19 +1631,19 @@ CanvasRenderingContext2D::BeginPath() { mPath = nullptr; mPathBuilder = nullptr; mDSPathBuilder = nullptr; mPathTransformWillUpdate = false; } void -CanvasRenderingContext2D::Fill() +CanvasRenderingContext2D::Fill(const CanvasWindingRule& winding) { - EnsureUserSpacePath(); + EnsureUserSpacePath(winding); if (!mPath) { return; } mgfx::Rect bounds; if (NeedToDrawShadow()) { @@ -1682,19 +1682,19 @@ CanvasRenderingContext2D::Stroke() AdjustedTarget(this, bounds.IsEmpty() ? nullptr : &bounds)-> Stroke(mPath, CanvasGeneralPattern().ForStyle(this, STYLE_STROKE, mTarget), strokeOptions, DrawOptions(state.globalAlpha, UsedOperation())); Redraw(); } void -CanvasRenderingContext2D::Clip() +CanvasRenderingContext2D::Clip(const CanvasWindingRule& winding) { - EnsureUserSpacePath(); + EnsureUserSpacePath(winding); if (!mPath) { return; } mTarget->PushClip(mPath); CurrentState().clipsPushed.push_back(mPath); } @@ -1843,19 +1843,21 @@ CanvasRenderingContext2D::EnsureWritable mDSPathBuilder = mPath->TransformedCopyToBuilder(mPathToDS, fillRule); mPathTransformWillUpdate = false; mPath = nullptr; } } void -CanvasRenderingContext2D::EnsureUserSpacePath() +CanvasRenderingContext2D::EnsureUserSpacePath(const CanvasWindingRule& winding) { FillRule fillRule = CurrentState().fillRule; + if(winding == CanvasWindingRuleValues::Evenodd) + fillRule = FILL_EVEN_ODD; if (!mPath && !mPathBuilder && !mDSPathBuilder) { EnsureTarget(); mPathBuilder = mTarget->CreatePathBuilder(fillRule); } if (mPathBuilder) { mPath = mPathBuilder->Finish(); @@ -2831,29 +2833,31 @@ CanvasRenderingContext2D::SetMozDashOffs { ContextState& state = CurrentState(); if (!state.dash.IsEmpty()) { state.dashOffset = mozDashOffset; } } bool -CanvasRenderingContext2D::IsPointInPath(double x, double y) +CanvasRenderingContext2D::IsPointInPath(double x, double y, const CanvasWindingRule& winding) { if (!FloatValidate(x,y)) { return false; } - EnsureUserSpacePath(); + EnsureUserSpacePath(winding); if (!mPath) { return false; } + if (mPathTransformWillUpdate) { return mPath->ContainsPoint(Point(x, y), mPathToDS); } + return mPath->ContainsPoint(Point(x, y), mTarget->GetTransform()); } bool CanvasRenderingContext2D::IsPointInStroke(double x, double y) { if (!FloatValidate(x,y)) { return false;
--- a/content/canvas/src/CanvasRenderingContext2D.h +++ b/content/canvas/src/CanvasRenderingContext2D.h @@ -12,16 +12,17 @@ #include "nsColor.h" #include "mozilla/dom/HTMLCanvasElement.h" #include "nsHTMLVideoElement.h" #include "CanvasUtils.h" #include "gfxFont.h" #include "mozilla/ErrorResult.h" #include "mozilla/dom/ImageData.h" #include "mozilla/dom/UnionTypes.h" +#include "mozilla/dom/CanvasRenderingContext2DBinding.h" #define NS_CANVASGRADIENTAZURE_PRIVATE_IID \ {0x28425a6a, 0x90e0, 0x4d42, {0x9c, 0x75, 0xff, 0x60, 0x09, 0xb3, 0x10, 0xa8}} #define NS_CANVASPATTERNAZURE_PRIVATE_IID \ {0xc9bacc25, 0x28da, 0x421e, {0x9a, 0x4b, 0xbb, 0xd6, 0x93, 0x05, 0x12, 0xbc}} class nsIDOMXULElement; @@ -233,20 +234,20 @@ public: StyleColorToString(CurrentState().shadowColor, shadowColor); } void SetShadowColor(const nsAString& shadowColor); void ClearRect(double x, double y, double w, double h); void FillRect(double x, double y, double w, double h); void StrokeRect(double x, double y, double w, double h); void BeginPath(); - void Fill(); + void Fill(const CanvasWindingRule& winding); void Stroke(); - void Clip(); - bool IsPointInPath(double x, double y); + void Clip(const CanvasWindingRule& winding); + bool IsPointInPath(double x, double y, const CanvasWindingRule& winding); bool IsPointInStroke(double x, double y); void FillText(const nsAString& text, double x, double y, const mozilla::dom::Optional<double>& maxWidth, mozilla::ErrorResult& error); void StrokeText(const nsAString& text, double x, double y, const mozilla::dom::Optional<double>& maxWidth, mozilla::ErrorResult& error); already_AddRefed<nsIDOMTextMetrics> @@ -582,17 +583,17 @@ protected: /* This function ensures there is a writable pathbuilder available, this * pathbuilder may be working in user space or in device space or * device space. * After calling this function mPathTransformWillUpdate will be false */ void EnsureWritablePath(); // Ensures a path in UserSpace is available. - void EnsureUserSpacePath(); + void EnsureUserSpacePath(const CanvasWindingRule& winding = CanvasWindingRuleValues::Nonzero); /** * Needs to be called before updating the transform. This makes a call to * EnsureTarget() so you don't have to. */ void TransformWillUpdate(); // Report the fillRule has changed.
--- a/content/canvas/src/ImageData.cpp +++ b/content/canvas/src/ImageData.cpp @@ -17,18 +17,16 @@ namespace dom { NS_IMPL_CYCLE_COLLECTING_ADDREF(ImageData) NS_IMPL_CYCLE_COLLECTING_RELEASE(ImageData) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ImageData) NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_END -NS_IMPL_CYCLE_COLLECTION_CLASS(ImageData) - NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(ImageData) NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mData) NS_IMPL_CYCLE_COLLECTION_TRACE_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ImageData) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
--- a/content/canvas/src/WebGLUniformLocation.cpp +++ b/content/canvas/src/WebGLUniformLocation.cpp @@ -19,24 +19,16 @@ WebGLUniformLocation::WebGLUniformLocati , mProgram(program) , mProgramGeneration(program->Generation()) , mLocation(location) , mInfo(info) { mElementSize = info.ElementSize(); } -NS_IMPL_CYCLE_COLLECTION_CLASS(WebGLUniformLocation) - -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(WebGLUniformLocation) - NS_IMPL_CYCLE_COLLECTION_UNLINK(mProgram) -NS_IMPL_CYCLE_COLLECTION_UNLINK_END - -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(WebGLUniformLocation) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mProgram) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END +NS_IMPL_CYCLE_COLLECTION_1(WebGLUniformLocation, mProgram) NS_IMPL_CYCLE_COLLECTING_ADDREF(WebGLUniformLocation) NS_IMPL_CYCLE_COLLECTING_RELEASE(WebGLUniformLocation) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(WebGLUniformLocation) NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_END
--- a/content/canvas/test/Makefile.in +++ b/content/canvas/test/Makefile.in @@ -31,16 +31,17 @@ MOCHITEST_FILES = \ image_red.png \ image_transparent.png \ image_green.png \ image_green-redirect \ image_green-redirect^headers^ \ test_drawImageIncomplete.html \ test_canvas_font_setter.html \ test_2d.clearRect.image.offscreen.html \ + test_2d.clip.winding.html \ test_2d.composite.canvas.destination-atop.html \ test_2d.composite.canvas.destination-in.html \ test_2d.composite.canvas.source-in.html \ test_2d.composite.canvas.source-out.html \ test_2d.composite.canvas.multiply.html \ test_2d.composite.canvas.screen.html \ test_2d.composite.canvas.overlay.html \ test_2d.composite.canvas.darken.html \ @@ -88,16 +89,18 @@ MOCHITEST_FILES = \ test_2d.composite.uncovered.fill.soft-light.html \ test_2d.composite.uncovered.fill.difference.html \ test_2d.composite.uncovered.fill.exclusion.html \ test_2d.composite.uncovered.fill.hue.html \ test_2d.composite.uncovered.fill.saturation.html \ test_2d.composite.uncovered.fill.color.html \ test_2d.composite.uncovered.fill.luminosity.html \ test_2d.drawImage.zerocanvas.html \ + test_2d.fill.winding.html \ + test_2d.isPointInPath.winding.html \ test_2d.strokeRect.zero.5.html \ test_toBlob.html \ test_toDataURL_alpha.html \ test_toDataURL_lowercase_ascii.html \ test_toDataURL_parameters.html \ test_mozGetAsFile.html \ test_canvas_strokeStyle_getter.html \ test_bug613794.html \
new file mode 100644 --- /dev/null +++ b/content/canvas/test/test_2d.clip.winding.html @@ -0,0 +1,53 @@ +<!DOCTYPE HTML> +<title>Canvas test: 2d.clip.winding</title> +<script src="/MochiKit/MochiKit.js"></script> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"> +<body> +<canvas id="c" width="100" height="100"><p class="fallback">FAIL (fallback content)</p></canvas> +<script> +function isPixel(ctx, x,y, r,g,b,a, pos, colour, d) { + var pixel = ctx.getImageData(x, y, 1, 1); + var pr = pixel.data[0], + pg = pixel.data[1], + pb = pixel.data[2], + pa = pixel.data[3]; + ok(r-d <= pr && pr <= r+d && + g-d <= pg && pg <= g+d && + b-d <= pb && pb <= b+d && + a-d <= pa && pa <= a+d, + "pixel "+pos+" is "+pr+","+pg+","+pb+","+pa+"; expected "+colour+" +/- "+d); +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(function () { + +var canvas = document.getElementById('c'); +var ctx = canvas.getContext('2d'); + +ctx.fillStyle = 'rgb(255,0,0)'; +ctx.fillRect(0, 0, 100, 100); +ctx.fillStyle = 'rgb(0,255,0)'; +ctx.beginPath(); +ctx.rect(0, 0, 100, 100); +ctx.rect(25, 25, 50, 50); +ctx.clip(); +ctx.beginPath(); +ctx.fillRect(0, 0, 100, 100); +isPixel(ctx, 50,50, 0,255,0,255, "50,50", "0,255,0,255", 5); + +ctx.fillStyle = 'rgb(255,0,0)'; +ctx.fillRect(0, 0, 100, 100); +ctx.fillStyle = 'rgb(0,255,0)'; +ctx.beginPath(); +ctx.rect(0, 0, 100, 100); +ctx.rect(25, 25, 50, 50); +ctx.clip('evenodd'); +ctx.fillRect(0, 0, 100, 100); +isPixel(ctx, 50,50, 255,0,0,255, "50,50", "255,0,0,255", 5); + +SimpleTest.finish(); + +}); +</script> +
new file mode 100644 --- /dev/null +++ b/content/canvas/test/test_2d.fill.winding.html @@ -0,0 +1,51 @@ +<!DOCTYPE HTML> +<title>Canvas test: 2d.fill.winding</title> +<script src="/MochiKit/MochiKit.js"></script> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"> +<body> +<canvas id="c" width="100" height="100"><p class="fallback">FAIL (fallback content)</p></canvas> +<script> +function isPixel(ctx, x,y, r,g,b,a, pos, colour, d) { + var pixel = ctx.getImageData(x, y, 1, 1); + var pr = pixel.data[0], + pg = pixel.data[1], + pb = pixel.data[2], + pa = pixel.data[3]; + ok(r-d <= pr && pr <= r+d && + g-d <= pg && pg <= g+d && + b-d <= pb && pb <= b+d && + a-d <= pa && pa <= a+d, + "pixel "+pos+" is "+pr+","+pg+","+pb+","+pa+"; expected "+colour+" +/- "+d); +} + +SimpleTest.waitForExplicitFinish(); +addLoadEvent(function () { + +var canvas = document.getElementById('c'); +var ctx = canvas.getContext('2d'); + +ctx.fillStyle = 'rgb(255,0,0)'; +ctx.beginPath(); +ctx.fillRect(0, 0, 100, 100); +ctx.fillStyle = 'rgb(0,255,0)'; +ctx.beginPath(); +ctx.rect(0, 0, 100, 100); +ctx.rect(25, 25, 50, 50); +ctx.fill(); +isPixel(ctx, 50,50, 0,255,0,255, "50,50", "0,255,0,255", 5); + +ctx.fillStyle = 'rgb(255,0,0)'; +ctx.fillRect(0, 0, 100, 100); +ctx.fillStyle = 'rgb(0,255,0)'; +ctx.beginPath(); +ctx.rect(0, 0, 100, 100); +ctx.rect(25, 25, 50, 50); +ctx.fill('evenodd'); +isPixel(ctx, 50,50, 255,0,0,255, "50,50", "255,0,0,255", 5); + +SimpleTest.finish(); + +}); +</script> +
new file mode 100644 --- /dev/null +++ b/content/canvas/test/test_2d.isPointInPath.winding.html @@ -0,0 +1,29 @@ +<!DOCTYPE HTML> +<title>Canvas test: 2d.isPointInPath.winding</title> +<script src="/MochiKit/MochiKit.js"></script> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"> +<body> +<canvas id="c" width="100" height="100"><p class="fallback">FAIL (fallback content)</p></canvas> +<script> +SimpleTest.waitForExplicitFinish(); +addLoadEvent(function () { + +var canvas = document.getElementById('c'); +var ctx = canvas.getContext('2d'); + +ctx.beginPath(); +ctx.rect(0, 0, 100, 100); +ctx.rect(25, 25, 50, 50); +ok(ctx.isPointInPath(50, 50)); + +ctx.beginPath(); +ctx.rect(0, 0, 100, 100); +ctx.rect(25, 25, 50, 50); +ok(ctx.isPointInPath(50, 50, 'evenodd') == false); + +SimpleTest.finish(); + +}); +</script> +
--- a/content/events/src/nsDOMDataContainerEvent.cpp +++ b/content/events/src/nsDOMDataContainerEvent.cpp @@ -8,18 +8,16 @@ nsDOMDataContainerEvent::nsDOMDataContainerEvent(nsPresContext *aPresContext, nsEvent *aEvent) : nsDOMEvent(aPresContext, aEvent) { mData.Init(); } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMDataContainerEvent) - NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMDataContainerEvent, nsDOMEvent) if (tmp->mData.IsInitialized()) tmp->mData.Clear(); NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMDataContainerEvent, nsDOMEvent)
--- a/content/events/src/nsDOMDataTransfer.cpp +++ b/content/events/src/nsDOMDataTransfer.cpp @@ -25,17 +25,16 @@ #include "nsCRT.h" #include "nsIScriptObjectPrincipal.h" #include "nsIWebNavigation.h" #include "nsIDocShellTreeItem.h" #include "nsIScriptContext.h" using namespace mozilla; -NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMDataTransfer) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMDataTransfer) if (tmp->mFiles) { tmp->mFiles->Disconnect(); NS_IMPL_CYCLE_COLLECTION_UNLINK(mFiles) } NS_IMPL_CYCLE_COLLECTION_UNLINK(mDragTarget) NS_IMPL_CYCLE_COLLECTION_UNLINK(mDragImage) NS_IMPL_CYCLE_COLLECTION_UNLINK_END
--- a/content/events/src/nsDOMDeviceMotionEvent.cpp +++ b/content/events/src/nsDOMDeviceMotionEvent.cpp @@ -1,17 +1,15 @@ /* 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 "nsDOMClassInfoID.h" #include "nsDOMDeviceMotionEvent.h" -NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMDeviceMotionEvent) - NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMDeviceMotionEvent, nsDOMEvent) NS_IMPL_CYCLE_COLLECTION_UNLINK(mAcceleration) NS_IMPL_CYCLE_COLLECTION_UNLINK(mAccelerationIncludingGravity) NS_IMPL_CYCLE_COLLECTION_UNLINK(mRotationRate) NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMDeviceMotionEvent, nsDOMEvent) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAcceleration)
--- a/content/events/src/nsDOMEvent.cpp +++ b/content/events/src/nsDOMEvent.cpp @@ -96,18 +96,16 @@ nsDOMEvent::~nsDOMEvent() { NS_ASSERT_OWNINGTHREAD(nsDOMEvent); if (mEventIsInternal && mEvent) { delete mEvent; } } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMEvent) - DOMCI_DATA(Event, nsDOMEvent) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMEvent) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMEvent) NS_INTERFACE_MAP_ENTRY(nsIDOMEvent) NS_INTERFACE_MAP_ENTRY(nsIJSNativeInitializer) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Event) NS_INTERFACE_MAP_END
--- a/content/events/src/nsDOMEventTargetHelper.cpp +++ b/content/events/src/nsDOMEventTargetHelper.cpp @@ -13,18 +13,16 @@ #include "prprf.h" #include "nsGlobalWindow.h" #include "nsDOMEvent.h" #include "mozilla/Likely.h" using namespace mozilla; using namespace mozilla::dom; -NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMEventTargetHelper) - NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsDOMEventTargetHelper) NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER NS_IMPL_CYCLE_COLLECTION_TRACE_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(nsDOMEventTargetHelper) if (MOZ_UNLIKELY(cb.WantDebugInfo())) { char name[512]; nsAutoString uri;
--- a/content/events/src/nsDOMMessageEvent.cpp +++ b/content/events/src/nsDOMMessageEvent.cpp @@ -3,18 +3,16 @@ * 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 "nsDOMMessageEvent.h" #include "nsContentUtils.h" #include "jsapi.h" #include "nsDOMClassInfoID.h" -NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMMessageEvent) - NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMMessageEvent, nsDOMEvent) if (tmp->mDataRooted) { tmp->UnrootData(); } NS_IMPL_CYCLE_COLLECTION_UNLINK(mSource) NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMMessageEvent, nsDOMEvent)
--- a/content/events/src/nsDOMNotifyAudioAvailableEvent.cpp +++ b/content/events/src/nsDOMNotifyAudioAvailableEvent.cpp @@ -26,18 +26,16 @@ nsDOMNotifyAudioAvailableEvent::nsDOMNot MOZ_COUNT_CTOR(nsDOMNotifyAudioAvailableEvent); if (mEvent) { mEvent->message = aEventType; } } DOMCI_DATA(NotifyAudioAvailableEvent, nsDOMNotifyAudioAvailableEvent) -NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMNotifyAudioAvailableEvent) - NS_IMPL_ADDREF_INHERITED(nsDOMNotifyAudioAvailableEvent, nsDOMEvent) NS_IMPL_RELEASE_INHERITED(nsDOMNotifyAudioAvailableEvent, nsDOMEvent) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMNotifyAudioAvailableEvent, nsDOMEvent) if (tmp->mCachedArray) { tmp->mCachedArray = nullptr; NS_DROP_JS_OBJECTS(tmp, nsDOMNotifyAudioAvailableEvent); }
--- a/content/events/src/nsDOMTouchEvent.cpp +++ b/content/events/src/nsDOMTouchEvent.cpp @@ -137,30 +137,23 @@ nsDOMTouch::Equals(nsIDOMTouch* aTouch) // TouchList nsDOMTouchList::nsDOMTouchList(nsTArray<nsCOMPtr<nsIDOMTouch> > &aTouches) { mPoints.AppendElements(aTouches); } DOMCI_DATA(TouchList, nsDOMTouchList) -NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMTouchList) - NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMTouchList) NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_ENTRY(nsIDOMTouchList) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(TouchList) NS_INTERFACE_MAP_END -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMTouchList) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPoints) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMTouchList) - NS_IMPL_CYCLE_COLLECTION_UNLINK(mPoints) -NS_IMPL_CYCLE_COLLECTION_UNLINK_END +NS_IMPL_CYCLE_COLLECTION_1(nsDOMTouchList, mPoints) NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMTouchList) NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMTouchList) NS_IMETHODIMP nsDOMTouchList::GetLength(uint32_t* aLength) { *aLength = mPoints.Length(); @@ -214,18 +207,16 @@ nsDOMTouchEvent::nsDOMTouchEvent(nsPresC nsDOMTouchEvent::~nsDOMTouchEvent() { if (mEventIsInternal && mEvent) { delete static_cast<nsTouchEvent*>(mEvent); mEvent = nullptr; } } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMTouchEvent) - NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMTouchEvent, nsDOMUIEvent) NS_IMPL_CYCLE_COLLECTION_UNLINK(mTouches) NS_IMPL_CYCLE_COLLECTION_UNLINK(mTargetTouches) NS_IMPL_CYCLE_COLLECTION_UNLINK(mChangedTouches) NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMTouchEvent, nsDOMUIEvent) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTouches)
--- a/content/events/src/nsDOMUIEvent.cpp +++ b/content/events/src/nsDOMUIEvent.cpp @@ -70,18 +70,16 @@ nsDOMUIEvent::nsDOMUIEvent(nsPresContext { nsCOMPtr<nsIDOMWindow> window = do_GetInterface(container); if (window) mView = do_QueryInterface(window); } } } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMUIEvent) - NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMUIEvent, nsDOMEvent) NS_IMPL_CYCLE_COLLECTION_UNLINK(mView) NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMUIEvent, nsDOMEvent) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mView) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
--- a/content/events/src/nsDOMXULCommandEvent.cpp +++ b/content/events/src/nsDOMXULCommandEvent.cpp @@ -16,18 +16,16 @@ nsDOMXULCommandEvent::nsDOMXULCommandEve mEventIsInternal = false; } else { mEventIsInternal = true; mEvent->time = PR_Now(); } } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMXULCommandEvent) - NS_IMPL_ADDREF_INHERITED(nsDOMXULCommandEvent, nsDOMUIEvent) NS_IMPL_RELEASE_INHERITED(nsDOMXULCommandEvent, nsDOMUIEvent) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMXULCommandEvent, nsDOMUIEvent) NS_IMPL_CYCLE_COLLECTION_UNLINK(mSourceEvent) NS_IMPL_CYCLE_COLLECTION_UNLINK_END
--- a/content/events/src/nsEventListenerManager.cpp +++ b/content/events/src/nsEventListenerManager.cpp @@ -146,18 +146,16 @@ nsEventListenerManager::RemoveAllListene } void nsEventListenerManager::Shutdown() { nsDOMEvent::Shutdown(); } -NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(nsEventListenerManager) - NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(nsEventListenerManager, AddRef) NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(nsEventListenerManager, Release) inline void ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback& aCallback, nsListenerStruct& aField, const char* aName, unsigned aFlags)
--- a/content/events/src/nsEventStateManager.cpp +++ b/content/events/src/nsEventStateManager.cpp @@ -872,18 +872,16 @@ nsEventStateManager::Observe(nsISupports } else if (data.EqualsLiteral("dom.popup_allowed_events")) { nsDOMEvent::PopupAllowedEventsChanged(); } } return NS_OK; } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsEventStateManager) - NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsEventStateManager) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIObserver) NS_INTERFACE_MAP_ENTRY(nsIObserver) NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) NS_INTERFACE_MAP_END NS_IMPL_CYCLE_COLLECTING_ADDREF(nsEventStateManager) NS_IMPL_CYCLE_COLLECTING_RELEASE(nsEventStateManager)
--- a/content/html/content/public/nsIConstraintValidation.h +++ b/content/html/content/public/nsIConstraintValidation.h @@ -5,19 +5,24 @@ #ifndef nsIConstraintValidition_h___ #define nsIConstraintValidition_h___ #include "nsISupports.h" #include "nsAutoPtr.h" #include "nsString.h" -class nsDOMValidityState; class nsIDOMValidityState; +namespace mozilla { +namespace dom { +class ValidityState; +} +} + #define NS_ICONSTRAINTVALIDATION_IID \ { 0xca3824dc, 0x4f5c, 0x4878, \ { 0xa6, 0x8a, 0x95, 0x54, 0x5f, 0xfa, 0x4b, 0xf9 } } /** * This interface is for form elements implementing the validity constraint API. * See: http://dev.w3.org/html5/spec/forms.html#the-constraint-validation-api * @@ -25,17 +30,17 @@ class nsIDOMValidityState; * and only them. */ class nsIConstraintValidation : public nsISupports { public: NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONSTRAINTVALIDATION_IID); - friend class nsDOMValidityState; + friend class mozilla::dom::ValidityState; static const uint16_t sContentSpecifiedMaxLengthMessage; virtual ~nsIConstraintValidation(); bool IsValid() const { return mValidityBitField == 0; } bool IsCandidateForConstraintValidation() const { @@ -54,16 +59,23 @@ public: VALIDITY_STATE_RANGE_OVERFLOW = 0x20, // 0b00100000 VALIDITY_STATE_STEP_MISMATCH = 0x40, // 0b01000000 VALIDITY_STATE_CUSTOM_ERROR = 0x80 // 0b10000000 }; void SetValidityState(ValidityStateType mState, bool mValue); + // Web IDL binding methods + bool WillValidate() const { + return IsCandidateForConstraintValidation(); + } + mozilla::dom::ValidityState* Validity(); + bool CheckValidity(); + protected: // You can't instantiate an object from that class. nsIConstraintValidation(); nsresult GetValidity(nsIDOMValidityState** aValidity); nsresult CheckValidity(bool* aValidity); void SetCustomValidity(const nsAString& aError); @@ -74,30 +86,31 @@ protected: void SetBarredFromConstraintValidation(bool aBarred); virtual nsresult GetValidationMessage(nsAString& aValidationMessage, ValidityStateType aType) { return NS_OK; } +protected: + /** + * A pointer to the ValidityState object. + */ + nsRefPtr<mozilla::dom::ValidityState> mValidity; + private: /** * A bitfield representing the current validity state of the element. * Each bit represent an error. All bits to zero means the element is valid. */ int8_t mValidityBitField; /** - * A pointer to the ValidityState object. - */ - nsRefPtr<nsDOMValidityState> mValidity; - - /** * Keeps track whether the element is barred from constraint validation. */ bool mBarredFromConstraintValidation; /** * The string representing the custom error. */ nsString mCustomValidity; @@ -106,42 +119,43 @@ private: /** * Use these macro for class inheriting from nsIConstraintValidation to forward * functions to nsIConstraintValidation. */ #define NS_FORWARD_NSICONSTRAINTVALIDATION_EXCEPT_SETCUSTOMVALIDITY \ NS_IMETHOD GetValidity(nsIDOMValidityState** aValidity) { \ return nsIConstraintValidation::GetValidity(aValidity); \ } \ - NS_IMETHOD GetWillValidate(bool* aWillValidate) { \ - *aWillValidate = IsCandidateForConstraintValidation(); \ + NS_IMETHOD GetWillValidate(bool* aWillValidate) { \ + *aWillValidate = WillValidate(); \ return NS_OK; \ } \ NS_IMETHOD GetValidationMessage(nsAString& aValidationMessage) { \ return nsIConstraintValidation::GetValidationMessage(aValidationMessage); \ } \ - NS_IMETHOD CheckValidity(bool* aValidity) { \ + using nsIConstraintValidation::CheckValidity; \ + NS_IMETHOD CheckValidity(bool* aValidity) { \ return nsIConstraintValidation::CheckValidity(aValidity); \ } #define NS_FORWARD_NSICONSTRAINTVALIDATION \ NS_FORWARD_NSICONSTRAINTVALIDATION_EXCEPT_SETCUSTOMVALIDITY \ NS_IMETHOD SetCustomValidity(const nsAString& aError) { \ nsIConstraintValidation::SetCustomValidity(aError); \ return NS_OK; \ } /* Use these macro when class declares functions from nsIConstraintValidation */ #define NS_IMPL_NSICONSTRAINTVALIDATION_EXCEPT_SETCUSTOMVALIDITY(_from) \ NS_IMETHODIMP _from::GetValidity(nsIDOMValidityState** aValidity) { \ return nsIConstraintValidation::GetValidity(aValidity); \ } \ - NS_IMETHODIMP _from::GetWillValidate(bool* aWillValidate) { \ - *aWillValidate = IsCandidateForConstraintValidation(); \ + NS_IMETHODIMP _from::GetWillValidate(bool* aWillValidate) { \ + *aWillValidate = WillValidate(); \ return NS_OK; \ } \ NS_IMETHODIMP _from::GetValidationMessage(nsAString& aValidationMessage) { \ return nsIConstraintValidation::GetValidationMessage(aValidationMessage); \ } \ NS_IMETHODIMP _from::CheckValidity(bool* aValidity) { \ return nsIConstraintValidation::CheckValidity(aValidity); \ }
--- a/content/html/content/src/HTMLCanvasElement.cpp +++ b/content/html/content/src/HTMLCanvasElement.cpp @@ -141,42 +141,31 @@ NS_IMPL_CYCLE_COLLECTING_ADDREF(HTMLCanv NS_IMPL_CYCLE_COLLECTING_RELEASE(HTMLCanvasPrintState) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(HTMLCanvasPrintState) NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_ENTRY(nsIDOMMozCanvasPrintState) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozCanvasPrintState) NS_INTERFACE_MAP_END -NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLCanvasPrintState) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(HTMLCanvasPrintState) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCanvas) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContext) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCallback) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END +NS_IMPL_CYCLE_COLLECTION_3(HTMLCanvasPrintState, mCanvas, mContext, mCallback) -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(HTMLCanvasPrintState) - NS_IMPL_CYCLE_COLLECTION_UNLINK(mCanvas) - NS_IMPL_CYCLE_COLLECTION_UNLINK(mContext) - NS_IMPL_CYCLE_COLLECTION_UNLINK(mCallback) -NS_IMPL_CYCLE_COLLECTION_UNLINK_END // --------------------------------------------------------------------------- HTMLCanvasElement::HTMLCanvasElement(already_AddRefed<nsINodeInfo> aNodeInfo) : nsGenericHTMLElement(aNodeInfo), mWriteOnly(false) { } HTMLCanvasElement::~HTMLCanvasElement() { ResetPrintCallback(); } -NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLCanvasElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLCanvasElement, nsGenericHTMLElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCurrentContext) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPrintCallback) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPrintState) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOriginalCanvas) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
--- a/content/html/content/src/HTMLDataListElement.cpp +++ b/content/html/content/src/HTMLDataListElement.cpp @@ -23,17 +23,16 @@ HTMLDataListElement::WrapNode(JSContext return HTMLDataListElementBinding::Wrap(aCx, aScope, this, aTriedToWrap); } NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLDataListElement, nsGenericHTMLElement) NS_IMPL_CYCLE_COLLECTION_UNLINK(mOptions) NS_IMPL_CYCLE_COLLECTION_UNLINK_END -NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLDataListElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLDataListElement, nsGenericHTMLElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOptions) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_ADDREF_INHERITED(HTMLDataListElement, Element) NS_IMPL_RELEASE_INHERITED(HTMLDataListElement, Element)
new file mode 100644 --- /dev/null +++ b/content/html/content/src/HTMLObjectElement.cpp @@ -0,0 +1,557 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +// vim:set et sw=2 sts=2 cin: +/* 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 "mozilla/Util.h" + +#include "nsAutoPtr.h" +#include "nsGenericHTMLElement.h" +#include "nsAttrValueInlines.h" +#include "nsObjectLoadingContent.h" +#include "nsGkAtoms.h" +#include "nsError.h" +#include "nsIDocument.h" +#include "nsIPluginDocument.h" +#include "nsIDOMDocument.h" +#include "nsIDOMSVGDocument.h" +#include "nsIDOMGetSVGDocument.h" +#include "nsIDOMHTMLObjectElement.h" +#include "nsFormSubmission.h" +#include "nsIObjectFrame.h" +#include "nsNPAPIPluginInstance.h" +#include "nsIConstraintValidation.h" +#include "nsIWidget.h" + +namespace mozilla { +namespace dom { + +class HTMLObjectElement MOZ_FINAL : public nsGenericHTMLFormElement + , public nsObjectLoadingContent + , public nsIDOMHTMLObjectElement + , public nsIConstraintValidation + , public nsIDOMGetSVGDocument +{ +public: + using nsIConstraintValidation::GetValidationMessage; + + HTMLObjectElement(already_AddRefed<nsINodeInfo> aNodeInfo, + FromParser aFromParser = NOT_FROM_PARSER); + virtual ~HTMLObjectElement(); + + // nsISupports + NS_DECL_ISUPPORTS_INHERITED + + // nsIDOMNode + NS_FORWARD_NSIDOMNODE_TO_NSINODE + + // nsIDOMElement + NS_FORWARD_NSIDOMELEMENT_TO_GENERIC + + // nsIDOMHTMLElement + NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC + + virtual int32_t TabIndexDefault() MOZ_OVERRIDE; + + // nsIDOMHTMLObjectElement + NS_DECL_NSIDOMHTMLOBJECTELEMENT + + // nsIDOMGetSVGDocument + NS_DECL_NSIDOMGETSVGDOCUMENT + + virtual nsresult BindToTree(nsIDocument *aDocument, nsIContent *aParent, + nsIContent *aBindingParent, + bool aCompileEventHandlers); + virtual void UnbindFromTree(bool aDeep = true, + bool aNullParent = true); + virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom *aName, + nsIAtom *aPrefix, const nsAString &aValue, + bool aNotify); + virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute, + bool aNotify); + + virtual bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, int32_t *aTabIndex); + virtual IMEState GetDesiredIMEState(); + + // Overriden nsIFormControl methods + NS_IMETHOD_(uint32_t) GetType() const + { + return NS_FORM_OBJECT; + } + + NS_IMETHOD Reset(); + NS_IMETHOD SubmitNamesValues(nsFormSubmission *aFormSubmission); + + virtual bool IsDisabled() const { return false; } + + virtual void DoneAddingChildren(bool aHaveNotified); + virtual bool IsDoneAddingChildren(); + + virtual bool ParseAttribute(int32_t aNamespaceID, + nsIAtom *aAttribute, + const nsAString &aValue, + nsAttrValue &aResult); + virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const; + NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom *aAttribute) const; + virtual nsEventStates IntrinsicState() const; + virtual void DestroyContent(); + + // nsObjectLoadingContent + virtual uint32_t GetCapabilities() const; + + virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const; + + nsresult CopyInnerTo(Element* aDest); + + void StartObjectLoad() { StartObjectLoad(true); } + + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(HTMLObjectElement, + nsGenericHTMLFormElement) + + virtual nsXPCClassInfo* GetClassInfo(); + + virtual nsIDOMNode* AsDOMNode() { return this; } +private: + /** + * Calls LoadObject with the correct arguments to start the plugin load. + */ + NS_HIDDEN_(void) StartObjectLoad(bool aNotify); + + /** + * Returns if the element is currently focusable regardless of it's tabindex + * value. This is used to know the default tabindex value. + */ + bool IsFocusableForTabIndex(); + + virtual void GetItemValueText(nsAString& text); + virtual void SetItemValueText(const nsAString& text); + + bool mIsDoneAddingChildren; +}; + +HTMLObjectElement::HTMLObjectElement(already_AddRefed<nsINodeInfo> aNodeInfo, + FromParser aFromParser) + : nsGenericHTMLFormElement(aNodeInfo), + mIsDoneAddingChildren(!aFromParser) +{ + RegisterFreezableElement(); + SetIsNetworkCreated(aFromParser == FROM_PARSER_NETWORK); + + // <object> is always barred from constraint validation. + SetBarredFromConstraintValidation(true); + + // By default we're in the loading state + AddStatesSilently(NS_EVENT_STATE_LOADING); +} + +HTMLObjectElement::~HTMLObjectElement() +{ + UnregisterFreezableElement(); + DestroyImageLoadingContent(); +} + +bool +HTMLObjectElement::IsDoneAddingChildren() +{ + return mIsDoneAddingChildren; +} + +void +HTMLObjectElement::DoneAddingChildren(bool aHaveNotified) +{ + mIsDoneAddingChildren = true; + + // If we're already in a document, we need to trigger the load + // Otherwise, BindToTree takes care of that. + if (IsInDoc()) { + StartObjectLoad(aHaveNotified); + } +} + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLObjectElement, + nsGenericHTMLFormElement) + nsObjectLoadingContent::Traverse(tmp, cb); +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + +NS_IMPL_ADDREF_INHERITED(HTMLObjectElement, Element) +NS_IMPL_RELEASE_INHERITED(HTMLObjectElement, Element) + +NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLObjectElement) + NS_HTML_CONTENT_INTERFACE_TABLE_BEGIN(HTMLObjectElement) + NS_INTERFACE_TABLE_ENTRY(HTMLObjectElement, nsIDOMHTMLObjectElement) + NS_INTERFACE_TABLE_ENTRY(HTMLObjectElement, imgINotificationObserver) + NS_INTERFACE_TABLE_ENTRY(HTMLObjectElement, nsIRequestObserver) + NS_INTERFACE_TABLE_ENTRY(HTMLObjectElement, nsIStreamListener) + NS_INTERFACE_TABLE_ENTRY(HTMLObjectElement, nsIFrameLoaderOwner) + NS_INTERFACE_TABLE_ENTRY(HTMLObjectElement, nsIObjectLoadingContent) + NS_INTERFACE_TABLE_ENTRY(HTMLObjectElement, nsIImageLoadingContent) + NS_INTERFACE_TABLE_ENTRY(HTMLObjectElement, imgIOnloadBlocker) + NS_INTERFACE_TABLE_ENTRY(HTMLObjectElement, nsIInterfaceRequestor) + NS_INTERFACE_TABLE_ENTRY(HTMLObjectElement, nsIChannelEventSink) + NS_INTERFACE_TABLE_ENTRY(HTMLObjectElement, nsIConstraintValidation) + NS_INTERFACE_TABLE_ENTRY(HTMLObjectElement, nsIDOMGetSVGDocument) + NS_OFFSET_AND_INTERFACE_TABLE_END + NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(HTMLObjectElement, + nsGenericHTMLFormElement) +NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLObjectElement) + +NS_IMPL_ELEMENT_CLONE(HTMLObjectElement) + +// nsIConstraintValidation +NS_IMPL_NSICONSTRAINTVALIDATION(HTMLObjectElement) + +NS_IMETHODIMP +HTMLObjectElement::GetForm(nsIDOMHTMLFormElement **aForm) +{ + return nsGenericHTMLFormElement::GetForm(aForm); +} + +void +HTMLObjectElement::GetItemValueText(nsAString& aValue) +{ + GetData(aValue); +} + +void +HTMLObjectElement::SetItemValueText(const nsAString& aValue) +{ + SetData(aValue); +} + +nsresult +HTMLObjectElement::BindToTree(nsIDocument *aDocument, + nsIContent *aParent, + nsIContent *aBindingParent, + bool aCompileEventHandlers) +{ + nsresult rv = nsGenericHTMLFormElement::BindToTree(aDocument, aParent, + aBindingParent, + aCompileEventHandlers); + NS_ENSURE_SUCCESS(rv, rv); + + rv = nsObjectLoadingContent::BindToTree(aDocument, aParent, + aBindingParent, + aCompileEventHandlers); + NS_ENSURE_SUCCESS(rv, rv); + + // Don't kick off load from being bound to a plugin document - the plugin + // document will call nsObjectLoadingContent::InitializeFromChannel() for the + // initial load. + nsCOMPtr<nsIPluginDocument> pluginDoc = do_QueryInterface(aDocument); + + // If we already have all the children, start the load. + if (mIsDoneAddingChildren && !pluginDoc) { + void (HTMLObjectElement::*start)() = &HTMLObjectElement::StartObjectLoad; + nsContentUtils::AddScriptRunner(NS_NewRunnableMethod(this, start)); + } + + return NS_OK; +} + +void +HTMLObjectElement::UnbindFromTree(bool aDeep, + bool aNullParent) +{ + nsObjectLoadingContent::UnbindFromTree(aDeep, aNullParent); + nsGenericHTMLFormElement::UnbindFromTree(aDeep, aNullParent); +} + + + +nsresult +HTMLObjectElement::SetAttr(int32_t aNameSpaceID, nsIAtom *aName, + nsIAtom *aPrefix, const nsAString &aValue, + bool aNotify) +{ + nsresult rv = nsGenericHTMLFormElement::SetAttr(aNameSpaceID, aName, aPrefix, + aValue, aNotify); + NS_ENSURE_SUCCESS(rv, rv); + + // if aNotify is false, we are coming from the parser or some such place; + // we'll get bound after all the attributes have been set, so we'll do the + // object load from BindToTree/DoneAddingChildren. + // Skip the LoadObject call in that case. + // We also don't want to start loading the object when we're not yet in + // a document, just in case that the caller wants to set additional + // attributes before inserting the node into the document. + if (aNotify && IsInDoc() && mIsDoneAddingChildren && + aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::data) { + return LoadObject(aNotify, true); + } + + return NS_OK; +} + +nsresult +HTMLObjectElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute, + bool aNotify) +{ + nsresult rv = nsGenericHTMLFormElement::UnsetAttr(aNameSpaceID, + aAttribute, aNotify); + NS_ENSURE_SUCCESS(rv, rv); + + // See comment in SetAttr + if (aNotify && IsInDoc() && mIsDoneAddingChildren && + aNameSpaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::data) { + return LoadObject(aNotify, true); + } + + return NS_OK; +} + +bool +HTMLObjectElement::IsFocusableForTabIndex() +{ + nsIDocument* doc = GetCurrentDoc(); + if (!doc || doc->HasFlag(NODE_IS_EDITABLE)) { + return false; + } + + return IsEditableRoot() || + (Type() == eType_Document && + nsContentUtils::IsSubDocumentTabbable(this)); +} + +bool +HTMLObjectElement::IsHTMLFocusable(bool aWithMouse, + bool *aIsFocusable, int32_t *aTabIndex) +{ + // TODO: this should probably be managed directly by IsHTMLFocusable. + // See bug 597242. + nsIDocument *doc = GetCurrentDoc(); + if (!doc || doc->HasFlag(NODE_IS_EDITABLE)) { + if (aTabIndex) { + GetTabIndex(aTabIndex); + } + + *aIsFocusable = false; + + return false; + } + + // This method doesn't call nsGenericHTMLFormElement intentionally. + // TODO: It should probably be changed when bug 597242 will be fixed. + if (Type() == eType_Plugin || IsEditableRoot() || + (Type() == eType_Document && nsContentUtils::IsSubDocumentTabbable(this))) { + // Has plugin content: let the plugin decide what to do in terms of + // internal focus from mouse clicks + if (aTabIndex) { + GetTabIndex(aTabIndex); + } + + *aIsFocusable = true; + + return false; + } + + // TODO: this should probably be managed directly by IsHTMLFocusable. + // See bug 597242. + const nsAttrValue* attrVal = mAttrsAndChildren.GetAttr(nsGkAtoms::tabindex); + + *aIsFocusable = attrVal && attrVal->Type() == nsAttrValue::eInteger; + + if (aTabIndex && *aIsFocusable) { + *aTabIndex = attrVal->GetIntegerValue(); + } + + return false; +} + +nsIContent::IMEState +HTMLObjectElement::GetDesiredIMEState() +{ + if (Type() == eType_Plugin) { + return IMEState(IMEState::PLUGIN); + } + + return nsGenericHTMLFormElement::GetDesiredIMEState(); +} + +NS_IMETHODIMP +HTMLObjectElement::Reset() +{ + return NS_OK; +} + +NS_IMETHODIMP +HTMLObjectElement::SubmitNamesValues(nsFormSubmission *aFormSubmission) +{ + nsAutoString name; + if (!GetAttr(kNameSpaceID_None, nsGkAtoms::name, name)) { + // No name, don't submit. + + return NS_OK; + } + + nsIFrame* frame = GetPrimaryFrame(); + + nsIObjectFrame *objFrame = do_QueryFrame(frame); + if (!objFrame) { + // No frame, nothing to submit. + + return NS_OK; + } + + nsRefPtr<nsNPAPIPluginInstance> pi; + objFrame->GetPluginInstance(getter_AddRefs(pi)); + if (!pi) + return NS_OK; + + nsAutoString value; + nsresult rv = pi->GetFormValue(value); + NS_ENSURE_SUCCESS(rv, rv); + + return aFormSubmission->AddNameValuePair(name, value); +} + +NS_IMPL_STRING_ATTR(HTMLObjectElement, Align, align) +NS_IMPL_STRING_ATTR(HTMLObjectElement, Archive, archive) +NS_IMPL_STRING_ATTR(HTMLObjectElement, Border, border) +NS_IMPL_URI_ATTR_WITH_BASE(HTMLObjectElement, Code, code, codebase) +NS_IMPL_URI_ATTR(HTMLObjectElement, CodeBase, codebase) +NS_IMPL_STRING_ATTR(HTMLObjectElement, CodeType, codetype) +NS_IMPL_URI_ATTR_WITH_BASE(HTMLObjectElement, Data, data, codebase) +NS_IMPL_BOOL_ATTR(HTMLObjectElement, Declare, declare) +NS_IMPL_STRING_ATTR(HTMLObjectElement, Height, height) +NS_IMPL_INT_ATTR(HTMLObjectElement, Hspace, hspace) +NS_IMPL_STRING_ATTR(HTMLObjectElement, Name, name) +NS_IMPL_STRING_ATTR(HTMLObjectElement, Standby, standby) +NS_IMPL_STRING_ATTR(HTMLObjectElement, Type, type) +NS_IMPL_STRING_ATTR(HTMLObjectElement, UseMap, usemap) +NS_IMPL_INT_ATTR(HTMLObjectElement, Vspace, vspace) +NS_IMPL_STRING_ATTR(HTMLObjectElement, Width, width) + +int32_t +HTMLObjectElement::TabIndexDefault() +{ + return IsFocusableForTabIndex() ? 0 : -1; +} + +NS_IMETHODIMP +HTMLObjectElement::GetContentDocument(nsIDOMDocument **aContentDocument) +{ + NS_ENSURE_ARG_POINTER(aContentDocument); + + *aContentDocument = nullptr; + + if (!IsInDoc()) { + return NS_OK; + } + + // XXXbz should this use GetCurrentDoc()? sXBL/XBL2 issue! + nsIDocument *sub_doc = OwnerDoc()->GetSubDocumentFor(this); + if (!sub_doc) { + return NS_OK; + } + + return CallQueryInterface(sub_doc, aContentDocument); +} + +NS_IMETHODIMP +HTMLObjectElement::GetSVGDocument(nsIDOMDocument **aResult) +{ + return GetContentDocument(aResult); +} + +bool +HTMLObjectElement::ParseAttribute(int32_t aNamespaceID, + nsIAtom *aAttribute, + const nsAString &aValue, + nsAttrValue &aResult) +{ + if (aNamespaceID == kNameSpaceID_None) { + if (aAttribute == nsGkAtoms::align) { + return ParseAlignValue(aValue, aResult); + } + if (ParseImageAttribute(aAttribute, aValue, aResult)) { + return true; + } + } + + return nsGenericHTMLFormElement::ParseAttribute(aNamespaceID, aAttribute, + aValue, aResult); +} + +static void +MapAttributesIntoRule(const nsMappedAttributes *aAttributes, + nsRuleData *aData) +{ + nsGenericHTMLFormElement::MapImageAlignAttributeInto(aAttributes, aData); + nsGenericHTMLFormElement::MapImageBorderAttributeInto(aAttributes, aData); + nsGenericHTMLFormElement::MapImageMarginAttributeInto(aAttributes, aData); + nsGenericHTMLFormElement::MapImageSizeAttributesInto(aAttributes, aData); + nsGenericHTMLFormElement::MapCommonAttributesInto(aAttributes, aData); +} + +NS_IMETHODIMP_(bool) +HTMLObjectElement::IsAttributeMapped(const nsIAtom *aAttribute) const +{ + static const MappedAttributeEntry* const map[] = { + sCommonAttributeMap, + sImageMarginSizeAttributeMap, + sImageBorderAttributeMap, + sImageAlignAttributeMap, + }; + + return FindAttributeDependence(aAttribute, map); +} + + +nsMapRuleToAttributesFunc +HTMLObjectElement::GetAttributeMappingFunction() const +{ + return &MapAttributesIntoRule; +} + +void +HTMLObjectElement::StartObjectLoad(bool aNotify) +{ + // BindToTree can call us asynchronously, and we may be removed from the tree + // in the interim + if (!IsInDoc() || !OwnerDoc()->IsActive()) { + return; + } + + LoadObject(aNotify); + SetIsNetworkCreated(false); +} + +nsEventStates +HTMLObjectElement::IntrinsicState() const +{ + return nsGenericHTMLFormElement::IntrinsicState() | ObjectState(); +} + +uint32_t +HTMLObjectElement::GetCapabilities() const +{ + return nsObjectLoadingContent::GetCapabilities() | eSupportClassID; +} + +void +HTMLObjectElement::DestroyContent() +{ + nsObjectLoadingContent::DestroyContent(); + nsGenericHTMLFormElement::DestroyContent(); +} + +nsresult +HTMLObjectElement::CopyInnerTo(Element* aDest) +{ + nsresult rv = nsGenericHTMLFormElement::CopyInnerTo(aDest); + NS_ENSURE_SUCCESS(rv, rv); + + if (aDest->OwnerDoc()->IsStaticDocument()) { + CreateStaticClone(static_cast<HTMLObjectElement*>(aDest)); + } + + return rv; +} + +} // namespace dom +} // namespace mozilla + +DOMCI_NODE_DATA(HTMLObjectElement, mozilla::dom::HTMLObjectElement) + +NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Object)
--- a/content/html/content/src/HTMLPropertiesCollection.cpp +++ b/content/html/content/src/HTMLPropertiesCollection.cpp @@ -23,17 +23,16 @@ namespace dom { static PLDHashOperator TraverseNamedProperties(const nsAString& aKey, PropertyNodeList* aEntry, void* aData) { nsCycleCollectionTraversalCallback* cb = static_cast<nsCycleCollectionTraversalCallback*>(aData); cb->NoteXPCOMChild(static_cast<nsINodeList*>(aEntry)); return PL_DHASH_NEXT; } -NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLPropertiesCollection) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(HTMLPropertiesCollection) // SetDocument(nullptr) ensures that we remove ourselves as a mutation observer tmp->SetDocument(nullptr); NS_IMPL_CYCLE_COLLECTION_UNLINK(mRoot) NS_IMPL_CYCLE_COLLECTION_UNLINK(mNames) tmp->mNamedItemEntries.Clear(); NS_IMPL_CYCLE_COLLECTION_UNLINK(mProperties) NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER @@ -413,17 +412,16 @@ PropertyNodeList::GetParentObject() } JSObject* PropertyNodeList::WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap) { return PropertyNodeListBinding::Wrap(cx, scope, this, triedToWrap); } -NS_IMPL_CYCLE_COLLECTION_CLASS(PropertyNodeList) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(PropertyNodeList) // SetDocument(nullptr) ensures that we remove ourselves as a mutation observer tmp->SetDocument(nullptr); NS_IMPL_CYCLE_COLLECTION_UNLINK(mParent) NS_IMPL_CYCLE_COLLECTION_UNLINK(mCollection) NS_IMPL_CYCLE_COLLECTION_UNLINK(mElements) NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER NS_IMPL_CYCLE_COLLECTION_UNLINK_END @@ -524,23 +522,17 @@ PropertyNodeList::EnsureFresh() } } PropertyStringList::PropertyStringList(HTMLPropertiesCollection* aCollection) : nsDOMStringList() , mCollection(aCollection) { } -NS_IMPL_CYCLE_COLLECTION_CLASS(PropertyStringList) -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(PropertyStringList) - NS_IMPL_CYCLE_COLLECTION_UNLINK(mCollection) -NS_IMPL_CYCLE_COLLECTION_UNLINK_END -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(PropertyStringList) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCollection) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END +NS_IMPL_CYCLE_COLLECTION_1(PropertyStringList, mCollection) NS_IMPL_CYCLE_COLLECTING_ADDREF(PropertyStringList) NS_IMPL_CYCLE_COLLECTING_RELEASE(PropertyStringList) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(PropertyStringList) NS_INTERFACE_MAP_ENTRY(nsIDOMDOMStringList) NS_INTERFACE_MAP_ENTRY(nsISupports) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DOMStringList)
--- a/content/html/content/src/HTMLTableElement.cpp +++ b/content/html/content/src/HTMLTableElement.cpp @@ -78,17 +78,16 @@ TableRowsCollection::TableRowsCollection TableRowsCollection::~TableRowsCollection() { // we do NOT have a ref-counted reference to mParent, so do NOT // release it! this is to avoid circular references. The // instantiator who provided mParent is responsible for managing our // reference for us. } -NS_IMPL_CYCLE_COLLECTION_CLASS(TableRowsCollection) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(TableRowsCollection) NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER NS_IMPL_CYCLE_COLLECTION_UNLINK(mOrphanRows) NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(TableRowsCollection) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOrphanRows) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END @@ -322,17 +321,16 @@ HTMLTableElement::~HTMLTableElement() } JSObject* HTMLTableElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap) { return HTMLTableElementBinding::Wrap(aCx, aScope, this, aTriedToWrap); } -NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLTableElement) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLTableElement, nsGenericHTMLElement) NS_IMPL_CYCLE_COLLECTION_UNLINK(mTBodies) if (tmp->mRows) { tmp->mRows->ParentDestroyed(); } NS_IMPL_CYCLE_COLLECTION_UNLINK(mRows) NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLTableElement,
--- a/content/html/content/src/HTMLTableRowElement.cpp +++ b/content/html/content/src/HTMLTableRowElement.cpp @@ -21,17 +21,16 @@ namespace dom { JSObject* HTMLTableRowElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap) { return HTMLTableRowElementBinding::Wrap(aCx, aScope, this, aTriedToWrap); } -NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLTableRowElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLTableRowElement, nsGenericHTMLElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCells) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_ADDREF_INHERITED(HTMLTableRowElement, Element) NS_IMPL_RELEASE_INHERITED(HTMLTableRowElement, Element)
--- a/content/html/content/src/HTMLTableSectionElement.cpp +++ b/content/html/content/src/HTMLTableSectionElement.cpp @@ -22,17 +22,16 @@ namespace dom { JSObject* HTMLTableSectionElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap) { return HTMLTableSectionElementBinding::Wrap(aCx, aScope, this, aTriedToWrap); } -NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLTableSectionElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLTableSectionElement, nsGenericHTMLElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRows) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_ADDREF_INHERITED(HTMLTableSectionElement, Element) NS_IMPL_RELEASE_INHERITED(HTMLTableSectionElement, Element)
--- a/content/html/content/src/Makefile.in +++ b/content/html/content/src/Makefile.in @@ -49,16 +49,17 @@ EXPORTS_mozilla/dom = \ HTMLTableCellElement.h \ HTMLTableColElement.h \ HTMLTableElement.h \ HTMLTableRowElement.h \ HTMLTableSectionElement.h \ HTMLTitleElement.h \ HTMLUnknownElement.h \ UndoManager.h \ + ValidityState.h \ $(NULL) CPPSRCS = \ HTMLPropertiesCollection.cpp \ nsClientRect.cpp \ nsHTMLDNSPrefetch.cpp \ nsGenericHTMLElement.cpp \ nsGenericHTMLFrameElement.cpp \ @@ -88,17 +89,17 @@ CPPSRCS = \ nsHTMLLegendElement.cpp \ nsHTMLLinkElement.cpp \ nsHTMLMapElement.cpp \ nsHTMLMenuElement.cpp \ nsHTMLMenuItemElement.cpp \ nsHTMLMetaElement.cpp \ nsHTMLMeterElement.cpp \ nsHTMLModElement.cpp \ - nsHTMLObjectElement.cpp \ + HTMLObjectElement.cpp \ nsHTMLSharedObjectElement.cpp \ nsHTMLOptionElement.cpp \ nsHTMLOptGroupElement.cpp \ nsHTMLOutputElement.cpp \ HTMLParagraphElement.cpp \ HTMLPreElement.cpp \ nsHTMLProgressElement.cpp \ HTMLScriptElement.cpp \ @@ -111,17 +112,17 @@ CPPSRCS = \ HTMLTableCaptionElement.cpp \ HTMLTableCellElement.cpp \ HTMLTableColElement.cpp \ HTMLTableRowElement.cpp \ HTMLTableSectionElement.cpp \ nsHTMLTextAreaElement.cpp \ HTMLTitleElement.cpp \ HTMLUnknownElement.cpp \ - nsDOMValidityState.cpp \ + ValidityState.cpp \ nsIConstraintValidation.cpp \ nsRadioVisitor.cpp \ nsDOMStringMap.cpp \ UndoManager.cpp \ $(NULL) ifdef MOZ_MEDIA CPPSRCS += \
new file mode 100644 --- /dev/null +++ b/content/html/content/src/ValidityState.cpp @@ -0,0 +1,107 @@ +/* -*- 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 "mozilla/dom/ValidityState.h" +#include "mozilla/dom/ValidityStateBinding.h" + +#include "nsDOMClassInfoID.h" +#include "nsCycleCollectionParticipant.h" +#include "nsContentUtils.h" + +DOMCI_DATA(ValidityState, mozilla::dom::ValidityState) + +namespace mozilla { +namespace dom { + +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(ValidityState) +NS_IMPL_CYCLE_COLLECTING_ADDREF(ValidityState) +NS_IMPL_CYCLE_COLLECTING_RELEASE(ValidityState) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ValidityState) + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY + NS_INTERFACE_MAP_ENTRY(nsIDOMValidityState) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMValidityState) + NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ValidityState) +NS_INTERFACE_MAP_END + +ValidityState::ValidityState(nsIConstraintValidation* aConstraintValidation) + : mConstraintValidation(aConstraintValidation) +{ + SetIsDOMBinding(); +} + +NS_IMETHODIMP +ValidityState::GetValueMissing(bool* aValueMissing) +{ + *aValueMissing = ValueMissing(); + return NS_OK; +} + +NS_IMETHODIMP +ValidityState::GetTypeMismatch(bool* aTypeMismatch) +{ + *aTypeMismatch = TypeMismatch(); + return NS_OK; +} + +NS_IMETHODIMP +ValidityState::GetPatternMismatch(bool* aPatternMismatch) +{ + *aPatternMismatch = PatternMismatch(); + return NS_OK; +} + +NS_IMETHODIMP +ValidityState::GetTooLong(bool* aTooLong) +{ + *aTooLong = TooLong(); + return NS_OK; +} + +NS_IMETHODIMP +ValidityState::GetRangeUnderflow(bool* aRangeUnderflow) +{ + *aRangeUnderflow = RangeUnderflow(); + return NS_OK; +} + +NS_IMETHODIMP +ValidityState::GetRangeOverflow(bool* aRangeOverflow) +{ + *aRangeOverflow = RangeOverflow(); + return NS_OK; +} + +NS_IMETHODIMP +ValidityState::GetStepMismatch(bool* aStepMismatch) +{ + *aStepMismatch = StepMismatch(); + return NS_OK; +} + +NS_IMETHODIMP +ValidityState::GetCustomError(bool* aCustomError) +{ + *aCustomError = CustomError(); + return NS_OK; +} + +NS_IMETHODIMP +ValidityState::GetValid(bool* aValid) +{ + *aValid = Valid(); + return NS_OK; +} + +JSObject* +ValidityState::WrapObject(JSContext* aCx, JSObject* aScope, + bool* aTriedToWrap) +{ + return ValidityStateBinding::Wrap(aCx, aScope, this, aTriedToWrap); +} + +} // namespace dom +} // namespace mozilla +
new file mode 100644 --- /dev/null +++ b/content/html/content/src/ValidityState.h @@ -0,0 +1,104 @@ +/* -*- 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/. */ + +#ifndef mozilla_dom_ValidityState_h +#define mozilla_dom_ValidityState_h + +#include "nsIDOMValidityState.h" +#include "nsIConstraintValidation.h" +#include "nsWrapperCache.h" + +struct JSObject; +struct JSContext; + +namespace mozilla { +namespace dom { + +class ValidityState MOZ_FINAL : public nsIDOMValidityState, + public nsWrapperCache +{ +public: + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(ValidityState) + NS_DECL_NSIDOMVALIDITYSTATE + + friend class ::nsIConstraintValidation; + + nsIConstraintValidation* GetParentObject() const { + return mConstraintValidation; + } + + virtual JSObject* WrapObject(JSContext *aCx, JSObject *aScope, + bool *aTriedToWrap) MOZ_OVERRIDE; + + // Web IDL methods + bool ValueMissing() const + { + return GetValidityState(nsIConstraintValidation::VALIDITY_STATE_VALUE_MISSING); + } + bool TypeMismatch() const + { + return GetValidityState(nsIConstraintValidation::VALIDITY_STATE_TYPE_MISMATCH); + } + bool PatternMismatch() const + { + return GetValidityState(nsIConstraintValidation::VALIDITY_STATE_PATTERN_MISMATCH); + } + bool TooLong() const + { + return GetValidityState(nsIConstraintValidation::VALIDITY_STATE_TOO_LONG); + } + bool RangeUnderflow() const + { + return GetValidityState(nsIConstraintValidation::VALIDITY_STATE_RANGE_UNDERFLOW); + } + bool RangeOverflow() const + { + return GetValidityState(nsIConstraintValidation::VALIDITY_STATE_RANGE_OVERFLOW); + } + bool StepMismatch() const + { + return GetValidityState(nsIConstraintValidation::VALIDITY_STATE_STEP_MISMATCH); + } + bool CustomError() const + { + return GetValidityState(nsIConstraintValidation::VALIDITY_STATE_CUSTOM_ERROR); + } + bool Valid() const + { + return !mConstraintValidation || mConstraintValidation->IsValid(); + } + +protected: + ValidityState(nsIConstraintValidation* aConstraintValidation); + + /** + * This function should be called by nsIConstraintValidation + * to set mConstraintValidation to null to be sure + * it will not be used when the object is destroyed. + */ + inline void Disconnect() + { + mConstraintValidation = nullptr; + } + + /** + * Helper function to get a validity state from constraint validation instance. + */ + inline bool GetValidityState(nsIConstraintValidation::ValidityStateType aState) const + { + return mConstraintValidation && + mConstraintValidation->GetValidityState(aState); + } + + // Weak reference to owner which will call Disconnect() when being destroyed. + nsIConstraintValidation* mConstraintValidation; +}; + +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_ValidityState_h +
--- a/content/html/content/src/nsDOMStringMap.cpp +++ b/content/html/content/src/nsDOMStringMap.cpp @@ -9,17 +9,16 @@ #include "nsGenericHTMLElement.h" #include "nsContentUtils.h" #include "mozilla/dom/DOMStringMapBinding.h" using namespace mozilla; using namespace mozilla::dom; -NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMStringMap) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMStringMap) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMStringMap) NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER // Check that mElement exists in case the unlink code is run more than once. if (tmp->mElement) {
deleted file mode 100644 --- a/content/html/content/src/nsDOMValidityState.cpp +++ /dev/null @@ -1,89 +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 "nsDOMValidityState.h" - -#include "nsDOMClassInfoID.h" - - -DOMCI_DATA(ValidityState, nsDOMValidityState) - -NS_IMPL_ADDREF(nsDOMValidityState) -NS_IMPL_RELEASE(nsDOMValidityState) - -NS_INTERFACE_MAP_BEGIN(nsDOMValidityState) - NS_INTERFACE_MAP_ENTRY(nsIDOMValidityState) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMValidityState) - NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(ValidityState) -NS_INTERFACE_MAP_END - -nsDOMValidityState::nsDOMValidityState(nsIConstraintValidation* aConstraintValidation) - : mConstraintValidation(aConstraintValidation) -{ -} - -NS_IMETHODIMP -nsDOMValidityState::GetValueMissing(bool* aValueMissing) -{ - *aValueMissing = GetValidityState(nsIConstraintValidation::VALIDITY_STATE_VALUE_MISSING); - return NS_OK; -} - -NS_IMETHODIMP -nsDOMValidityState::GetTypeMismatch(bool* aTypeMismatch) -{ - *aTypeMismatch = GetValidityState(nsIConstraintValidation::VALIDITY_STATE_TYPE_MISMATCH); - return NS_OK; -} - -NS_IMETHODIMP -nsDOMValidityState::GetPatternMismatch(bool* aPatternMismatch) -{ - *aPatternMismatch = GetValidityState(nsIConstraintValidation::VALIDITY_STATE_PATTERN_MISMATCH); - return NS_OK; -} - -NS_IMETHODIMP -nsDOMValidityState::GetTooLong(bool* aTooLong) -{ - *aTooLong = GetValidityState(nsIConstraintValidation::VALIDITY_STATE_TOO_LONG); - return NS_OK; -} - -NS_IMETHODIMP -nsDOMValidityState::GetRangeUnderflow(bool* aRangeUnderflow) -{ - *aRangeUnderflow = GetValidityState(nsIConstraintValidation::VALIDITY_STATE_RANGE_UNDERFLOW); - return NS_OK; -} - -NS_IMETHODIMP -nsDOMValidityState::GetRangeOverflow(bool* aRangeOverflow) -{ - *aRangeOverflow = GetValidityState(nsIConstraintValidation::VALIDITY_STATE_RANGE_OVERFLOW); - return NS_OK; -} - -NS_IMETHODIMP -nsDOMValidityState::GetStepMismatch(bool* aStepMismatch) -{ - *aStepMismatch = GetValidityState(nsIConstraintValidation::VALIDITY_STATE_STEP_MISMATCH); - return NS_OK; -} - -NS_IMETHODIMP -nsDOMValidityState::GetCustomError(bool* aCustomError) -{ - *aCustomError = GetValidityState(nsIConstraintValidation::VALIDITY_STATE_CUSTOM_ERROR); - return NS_OK; -} - -NS_IMETHODIMP -nsDOMValidityState::GetValid(bool* aValid) -{ - *aValid = !mConstraintValidation || mConstraintValidation->IsValid(); - return NS_OK; -} -
deleted file mode 100644 --- a/content/html/content/src/nsDOMValidityState.h +++ /dev/null @@ -1,48 +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/. */ - -#ifndef nsDOMValidityState_h__ -#define nsDOMValidityState_h__ - -#include "nsIDOMValidityState.h" -#include "nsIConstraintValidation.h" - - -class nsDOMValidityState MOZ_FINAL : public nsIDOMValidityState -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSIDOMVALIDITYSTATE - - friend class nsIConstraintValidation; - -protected: - nsDOMValidityState(nsIConstraintValidation* aConstraintValidation); - - /** - * This function should be called by nsIConstraintValidation - * to set mConstraintValidation to null to be sure - * it will not be used when the object is destroyed. - */ - inline void Disconnect() - { - mConstraintValidation = nullptr; - } - - /** - * Helper function to get a validity state from constraint validation instance. - */ - inline bool GetValidityState(nsIConstraintValidation::ValidityStateType aState) const - { - return mConstraintValidation && - mConstraintValidation->GetValidityState(aState); - } - - // Weak reference to owner which will call Disconnect() when being destroyed. - nsIConstraintValidation* mConstraintValidation; -}; - -#endif // nsDOMValidityState_h__ -
--- a/content/html/content/src/nsGenericHTMLElement.h +++ b/content/html/content/src/nsGenericHTMLElement.h @@ -10,16 +10,17 @@ #include "nsIDOMHTMLElement.h" #include "nsINameSpaceManager.h" // for kNameSpaceID_None #include "nsIFormControl.h" #include "nsGkAtoms.h" #include "nsContentCreatorFunctions.h" #include "mozilla/ErrorResult.h" #include "nsContentUtils.h" #include "nsIDOMHTMLMenuElement.h" +#include "mozilla/dom/ValidityState.h" class nsIDOMAttr; class nsIDOMEventListener; class nsIDOMNodeList; class nsIFrame; class nsIStyleRule; class nsChildContentList; class nsDOMCSSDeclaration;
--- a/content/html/content/src/nsGenericHTMLFrameElement.cpp +++ b/content/html/content/src/nsGenericHTMLFrameElement.cpp @@ -12,17 +12,16 @@ #include "nsIAppsService.h" #include "nsServiceManagerUtils.h" #include "nsIDOMApplicationRegistry.h" #include "nsIPermissionManager.h" using namespace mozilla; using namespace mozilla::dom; -NS_IMPL_CYCLE_COLLECTION_CLASS(nsGenericHTMLFrameElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsGenericHTMLFrameElement, nsGenericHTMLElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFrameLoader) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_INTERFACE_TABLE_HEAD(nsGenericHTMLFrameElement) NS_INTERFACE_TABLE_INHERITED3(nsGenericHTMLFrameElement, nsIFrameLoaderOwner,
--- a/content/html/content/src/nsHTMLButtonElement.cpp +++ b/content/html/content/src/nsHTMLButtonElement.cpp @@ -54,16 +54,19 @@ class nsHTMLButtonElement : public nsGen { public: using nsIConstraintValidation::GetValidationMessage; nsHTMLButtonElement(already_AddRefed<nsINodeInfo> aNodeInfo, FromParser aFromParser = NOT_FROM_PARSER); virtual ~nsHTMLButtonElement(); + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHTMLButtonElement, + nsGenericHTMLFormElement) + // nsISupports NS_DECL_ISUPPORTS_INHERITED // nsIDOMNode NS_FORWARD_NSIDOMNODE_TO_NSINODE // nsIDOMElement NS_FORWARD_NSIDOMELEMENT_TO_GENERIC @@ -147,16 +150,25 @@ nsHTMLButtonElement::nsHTMLButtonElement } nsHTMLButtonElement::~nsHTMLButtonElement() { } // nsISupports +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLButtonElement, + nsGenericHTMLFormElement) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mValidity) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHTMLButtonElement, + nsGenericHTMLFormElement) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mValidity) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + NS_IMPL_ADDREF_INHERITED(nsHTMLButtonElement, Element) NS_IMPL_RELEASE_INHERITED(nsHTMLButtonElement, Element) DOMCI_NODE_DATA(HTMLButtonElement, nsHTMLButtonElement) // QueryInterface implementation for nsHTMLButtonElement NS_INTERFACE_TABLE_HEAD(nsHTMLButtonElement)
--- a/content/html/content/src/nsHTMLFieldSetElement.cpp +++ b/content/html/content/src/nsHTMLFieldSetElement.cpp @@ -37,22 +37,23 @@ nsHTMLFieldSetElement::~nsHTMLFieldSetEl mDependentElements[i]->ForgetFieldSet(this); } } // nsISupports NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHTMLFieldSetElement, nsGenericHTMLFormElement) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mValidity) NS_IMPL_CYCLE_COLLECTION_UNLINK(mElements) NS_IMPL_CYCLE_COLLECTION_UNLINK_END -NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLFieldSetElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLFieldSetElement, nsGenericHTMLFormElement) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mValidity) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mElements) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_ADDREF_INHERITED(nsHTMLFieldSetElement, Element) NS_IMPL_RELEASE_INHERITED(nsHTMLFieldSetElement, Element) DOMCI_NODE_DATA(HTMLFieldSetElement, nsHTMLFieldSetElement)
--- a/content/html/content/src/nsHTMLFormElement.cpp +++ b/content/html/content/src/nsHTMLFormElement.cpp @@ -281,17 +281,16 @@ ElementTraverser(const nsAString& key, n { nsCycleCollectionTraversalCallback *cb = static_cast<nsCycleCollectionTraversalCallback*>(userArg); cb->NoteXPCOMChild(element); return PL_DHASH_NEXT; } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLFormElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLFormElement, nsGenericHTMLElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mControls) tmp->mSelectedRadioButtons.EnumerateRead(ElementTraverser, &cb); NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_ADDREF_INHERITED(nsHTMLFormElement, Element) NS_IMPL_RELEASE_INHERITED(nsHTMLFormElement, Element) @@ -2175,17 +2174,16 @@ ControlTraverser(const nsAString& key, n { nsCycleCollectionTraversalCallback *cb = static_cast<nsCycleCollectionTraversalCallback*>(userArg); cb->NoteXPCOMChild(control); return PL_DHASH_NEXT; } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsFormControlList) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsFormControlList) tmp->Clear(); NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsFormControlList) tmp->mNameLookupTable.EnumerateRead(ControlTraverser, &cb); NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
--- a/content/html/content/src/nsHTMLInputElement.cpp +++ b/content/html/content/src/nsHTMLInputElement.cpp @@ -629,29 +629,30 @@ nsHTMLInputElement::GetEditorState() con "Single line text controls need to have a state associated with them"); return mInputData.mState; } // nsISupports -NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLInputElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLInputElement, nsGenericHTMLFormElement) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mValidity) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mControllers) if (tmp->IsSingleLineTextControl(false)) { tmp->mInputData.mState->Traverse(cb); } NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFiles) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFileList) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHTMLInputElement, nsGenericHTMLFormElement) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mValidity) NS_IMPL_CYCLE_COLLECTION_UNLINK(mControllers) NS_IMPL_CYCLE_COLLECTION_UNLINK(mFiles) if (tmp->mFileList) { tmp->mFileList->Disconnect(); tmp->mFileList = nullptr; } if (tmp->IsSingleLineTextControl(false)) { tmp->mInputData.mState->Unlink();
--- a/content/html/content/src/nsHTMLLinkElement.cpp +++ b/content/html/content/src/nsHTMLLinkElement.cpp @@ -120,17 +120,16 @@ nsHTMLLinkElement::nsHTMLLinkElement(alr Link(this) { } nsHTMLLinkElement::~nsHTMLLinkElement() { } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLLinkElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLLinkElement, nsGenericHTMLElement) tmp->nsStyleLinkElement::Traverse(cb); NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHTMLLinkElement, nsGenericHTMLElement) tmp->nsStyleLinkElement::Unlink(); NS_IMPL_CYCLE_COLLECTION_UNLINK_END
--- a/content/html/content/src/nsHTMLMapElement.cpp +++ b/content/html/content/src/nsHTMLMapElement.cpp @@ -49,17 +49,16 @@ protected: NS_IMPL_NS_NEW_HTML_ELEMENT(Map) nsHTMLMapElement::nsHTMLMapElement(already_AddRefed<nsINodeInfo> aNodeInfo) : nsGenericHTMLElement(aNodeInfo) { } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLMapElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLMapElement, nsGenericHTMLElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mAreas) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_ADDREF_INHERITED(nsHTMLMapElement, Element) NS_IMPL_RELEASE_INHERITED(nsHTMLMapElement, Element)
--- a/content/html/content/src/nsHTMLMediaElement.cpp +++ b/content/html/content/src/nsHTMLMediaElement.cpp @@ -425,18 +425,16 @@ NS_IMETHODIMP nsHTMLMediaElement::MediaL NS_IMETHODIMP nsHTMLMediaElement::MediaLoadListener::GetInterface(const nsIID & aIID, void **aResult) { return QueryInterface(aIID, aResult); } NS_IMPL_ADDREF_INHERITED(nsHTMLMediaElement, nsGenericHTMLElement) NS_IMPL_RELEASE_INHERITED(nsHTMLMediaElement, nsGenericHTMLElement) -NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLMediaElement) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLMediaElement, nsGenericHTMLElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSrcStream) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSrcAttrStream) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourcePointer) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLoadBlockedDoc) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mSourceLoadCandidate) for (uint32_t i = 0; i < tmp->mOutputStreams.Length(); ++i) { NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOutputStreams[i].mStream);
deleted file mode 100644 --- a/content/html/content/src/nsHTMLObjectElement.cpp +++ /dev/null @@ -1,557 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -// vim:set et sw=2 sts=2 cin: -/* 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 "mozilla/Util.h" - -#include "nsAutoPtr.h" -#include "nsGenericHTMLElement.h" -#include "nsAttrValueInlines.h" -#include "nsObjectLoadingContent.h" -#include "nsGkAtoms.h" -#include "nsError.h" -#include "nsIDocument.h" -#include "nsIPluginDocument.h" -#include "nsIDOMDocument.h" -#include "nsIDOMSVGDocument.h" -#include "nsIDOMGetSVGDocument.h" -#include "nsIDOMHTMLObjectElement.h" -#include "nsFormSubmission.h" -#include "nsIObjectFrame.h" -#include "nsNPAPIPluginInstance.h" -#include "nsIConstraintValidation.h" -#include "nsIWidget.h" - -using namespace mozilla; -using namespace mozilla::dom; - -class nsHTMLObjectElement : public nsGenericHTMLFormElement - , public nsObjectLoadingContent - , public nsIDOMHTMLObjectElement - , public nsIConstraintValidation - , public nsIDOMGetSVGDocument -{ -public: - using nsIConstraintValidation::GetValidationMessage; - - nsHTMLObjectElement(already_AddRefed<nsINodeInfo> aNodeInfo, - mozilla::dom::FromParser aFromParser = mozilla::dom::NOT_FROM_PARSER); - virtual ~nsHTMLObjectElement(); - - // nsISupports - NS_DECL_ISUPPORTS_INHERITED - - // nsIDOMNode - NS_FORWARD_NSIDOMNODE_TO_NSINODE - - // nsIDOMElement - NS_FORWARD_NSIDOMELEMENT_TO_GENERIC - - // nsIDOMHTMLElement - NS_FORWARD_NSIDOMHTMLELEMENT_TO_GENERIC - - virtual int32_t TabIndexDefault() MOZ_OVERRIDE; - - // nsIDOMHTMLObjectElement - NS_DECL_NSIDOMHTMLOBJECTELEMENT - - // nsIDOMGetSVGDocument - NS_DECL_NSIDOMGETSVGDOCUMENT - - virtual nsresult BindToTree(nsIDocument *aDocument, nsIContent *aParent, - nsIContent *aBindingParent, - bool aCompileEventHandlers); - virtual void UnbindFromTree(bool aDeep = true, - bool aNullParent = true); - virtual nsresult SetAttr(int32_t aNameSpaceID, nsIAtom *aName, - nsIAtom *aPrefix, const nsAString &aValue, - bool aNotify); - virtual nsresult UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute, - bool aNotify); - - virtual bool IsHTMLFocusable(bool aWithMouse, bool *aIsFocusable, int32_t *aTabIndex); - virtual IMEState GetDesiredIMEState(); - - // Overriden nsIFormControl methods - NS_IMETHOD_(uint32_t) GetType() const - { - return NS_FORM_OBJECT; - } - - NS_IMETHOD Reset(); - NS_IMETHOD SubmitNamesValues(nsFormSubmission *aFormSubmission); - - virtual bool IsDisabled() const { return false; } - - virtual void DoneAddingChildren(bool aHaveNotified); - virtual bool IsDoneAddingChildren(); - - virtual bool ParseAttribute(int32_t aNamespaceID, - nsIAtom *aAttribute, - const nsAString &aValue, - nsAttrValue &aResult); - virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const; - NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom *aAttribute) const; - virtual nsEventStates IntrinsicState() const; - virtual void DestroyContent(); - - // nsObjectLoadingContent - virtual uint32_t GetCapabilities() const; - - virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const; - - nsresult CopyInnerTo(Element* aDest); - - void StartObjectLoad() { StartObjectLoad(true); } - - NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsHTMLObjectElement, - nsGenericHTMLFormElement) - - virtual nsXPCClassInfo* GetClassInfo(); - - virtual nsIDOMNode* AsDOMNode() { return this; } -private: - /** - * Calls LoadObject with the correct arguments to start the plugin load. - */ - NS_HIDDEN_(void) StartObjectLoad(bool aNotify); - - /** - * Returns if the element is currently focusable regardless of it's tabindex - * value. This is used to know the default tabindex value. - */ - bool IsFocusableForTabIndex(); - - virtual void GetItemValueText(nsAString& text); - virtual void SetItemValueText(const nsAString& text); - - bool mIsDoneAddingChildren; -}; - - -NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(Object) - - -nsHTMLObjectElement::nsHTMLObjectElement(already_AddRefed<nsINodeInfo> aNodeInfo, - FromParser aFromParser) - : nsGenericHTMLFormElement(aNodeInfo), - mIsDoneAddingChildren(!aFromParser) -{ - RegisterFreezableElement(); - SetIsNetworkCreated(aFromParser == FROM_PARSER_NETWORK); - - // <object> is always barred from constraint validation. - SetBarredFromConstraintValidation(true); - - // By default we're in the loading state - AddStatesSilently(NS_EVENT_STATE_LOADING); -} - -nsHTMLObjectElement::~nsHTMLObjectElement() -{ - UnregisterFreezableElement(); - DestroyImageLoadingContent(); -} - -bool -nsHTMLObjectElement::IsDoneAddingChildren() -{ - return mIsDoneAddingChildren; -} - -void -nsHTMLObjectElement::DoneAddingChildren(bool aHaveNotified) -{ - mIsDoneAddingChildren = true; - - // If we're already in a document, we need to trigger the load - // Otherwise, BindToTree takes care of that. - if (IsInDoc()) { - StartObjectLoad(aHaveNotified); - } -} - -NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLObjectElement) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLObjectElement, - nsGenericHTMLFormElement) - nsObjectLoadingContent::Traverse(tmp, cb); -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END - -NS_IMPL_ADDREF_INHERITED(nsHTMLObjectElement, Element) -NS_IMPL_RELEASE_INHERITED(nsHTMLObjectElement, Element) - -DOMCI_NODE_DATA(HTMLObjectElement, nsHTMLObjectElement) - -NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsHTMLObjectElement) - NS_HTML_CONTENT_INTERFACE_TABLE_BEGIN(nsHTMLObjectElement) - NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIDOMHTMLObjectElement) - NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, imgINotificationObserver) - NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIRequestObserver) - NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIStreamListener) - NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIFrameLoaderOwner) - NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIObjectLoadingContent) - NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIImageLoadingContent) - NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, imgIOnloadBlocker) - NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIInterfaceRequestor) - NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIChannelEventSink) - NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIConstraintValidation) - NS_INTERFACE_TABLE_ENTRY(nsHTMLObjectElement, nsIDOMGetSVGDocument) - NS_OFFSET_AND_INTERFACE_TABLE_END - NS_HTML_CONTENT_INTERFACE_TABLE_TO_MAP_SEGUE(nsHTMLObjectElement, - nsGenericHTMLFormElement) -NS_HTML_CONTENT_INTERFACE_TABLE_TAIL_CLASSINFO(HTMLObjectElement) - -NS_IMPL_ELEMENT_CLONE(nsHTMLObjectElement) - -// nsIConstraintValidation -NS_IMPL_NSICONSTRAINTVALIDATION(nsHTMLObjectElement) - -NS_IMETHODIMP -nsHTMLObjectElement::GetForm(nsIDOMHTMLFormElement **aForm) -{ - return nsGenericHTMLFormElement::GetForm(aForm); -} - -void -nsHTMLObjectElement::GetItemValueText(nsAString& aValue) -{ - GetData(aValue); -} - -void -nsHTMLObjectElement::SetItemValueText(const nsAString& aValue) -{ - SetData(aValue); -} - -nsresult -nsHTMLObjectElement::BindToTree(nsIDocument *aDocument, - nsIContent *aParent, - nsIContent *aBindingParent, - bool aCompileEventHandlers) -{ - nsresult rv = nsGenericHTMLFormElement::BindToTree(aDocument, aParent, - aBindingParent, - aCompileEventHandlers); - NS_ENSURE_SUCCESS(rv, rv); - - rv = nsObjectLoadingContent::BindToTree(aDocument, aParent, - aBindingParent, - aCompileEventHandlers); - NS_ENSURE_SUCCESS(rv, rv); - - // Don't kick off load from being bound to a plugin document - the plugin - // document will call nsObjectLoadingContent::InitializeFromChannel() for the - // initial load. - nsCOMPtr<nsIPluginDocument> pluginDoc = do_QueryInterface(aDocument); - - // If we already have all the children, start the load. - if (mIsDoneAddingChildren && !pluginDoc) { - void (nsHTMLObjectElement::*start)() = &nsHTMLObjectElement::StartObjectLoad; - nsContentUtils::AddScriptRunner(NS_NewRunnableMethod(this, start)); - } - - return NS_OK; -} - -void -nsHTMLObjectElement::UnbindFromTree(bool aDeep, - bool aNullParent) -{ - nsObjectLoadingContent::UnbindFromTree(aDeep, aNullParent); - nsGenericHTMLFormElement::UnbindFromTree(aDeep, aNullParent); -} - - - -nsresult -nsHTMLObjectElement::SetAttr(int32_t aNameSpaceID, nsIAtom *aName, - nsIAtom *aPrefix, const nsAString &aValue, - bool aNotify) -{ - nsresult rv = nsGenericHTMLFormElement::SetAttr(aNameSpaceID, aName, aPrefix, - aValue, aNotify); - NS_ENSURE_SUCCESS(rv, rv); - - // if aNotify is false, we are coming from the parser or some such place; - // we'll get bound after all the attributes have been set, so we'll do the - // object load from BindToTree/DoneAddingChildren. - // Skip the LoadObject call in that case. - // We also don't want to start loading the object when we're not yet in - // a document, just in case that the caller wants to set additional - // attributes before inserting the node into the document. - if (aNotify && IsInDoc() && mIsDoneAddingChildren && - aNameSpaceID == kNameSpaceID_None && aName == nsGkAtoms::data) { - return LoadObject(aNotify, true); - } - - return NS_OK; -} - -nsresult -nsHTMLObjectElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute, - bool aNotify) -{ - nsresult rv = nsGenericHTMLFormElement::UnsetAttr(aNameSpaceID, - aAttribute, aNotify); - NS_ENSURE_SUCCESS(rv, rv); - - // See comment in SetAttr - if (aNotify && IsInDoc() && mIsDoneAddingChildren && - aNameSpaceID == kNameSpaceID_None && aAttribute == nsGkAtoms::data) { - return LoadObject(aNotify, true); - } - - return NS_OK; -} - -bool -nsHTMLObjectElement::IsFocusableForTabIndex() -{ - nsIDocument* doc = GetCurrentDoc(); - if (!doc || doc->HasFlag(NODE_IS_EDITABLE)) { - return false; - } - - return IsEditableRoot() || - (Type() == eType_Document && - nsContentUtils::IsSubDocumentTabbable(this)); -} - -bool -nsHTMLObjectElement::IsHTMLFocusable(bool aWithMouse, - bool *aIsFocusable, int32_t *aTabIndex) -{ - // TODO: this should probably be managed directly by IsHTMLFocusable. - // See bug 597242. - nsIDocument *doc = GetCurrentDoc(); - if (!doc || doc->HasFlag(NODE_IS_EDITABLE)) { - if (aTabIndex) { - GetTabIndex(aTabIndex); - } - - *aIsFocusable = false; - - return false; - } - - // This method doesn't call nsGenericHTMLFormElement intentionally. - // TODO: It should probably be changed when bug 597242 will be fixed. - if (Type() == eType_Plugin || IsEditableRoot() || - (Type() == eType_Document && nsContentUtils::IsSubDocumentTabbable(this))) { - // Has plugin content: let the plugin decide what to do in terms of - // internal focus from mouse clicks - if (aTabIndex) { - GetTabIndex(aTabIndex); - } - - *aIsFocusable = true; - - return false; - } - - // TODO: this should probably be managed directly by IsHTMLFocusable. - // See bug 597242. - const nsAttrValue* attrVal = mAttrsAndChildren.GetAttr(nsGkAtoms::tabindex); - - *aIsFocusable = attrVal && attrVal->Type() == nsAttrValue::eInteger; - - if (aTabIndex && *aIsFocusable) { - *aTabIndex = attrVal->GetIntegerValue(); - } - - return false; -} - -nsIContent::IMEState -nsHTMLObjectElement::GetDesiredIMEState() -{ - if (Type() == eType_Plugin) { - return IMEState(IMEState::PLUGIN); - } - - return nsGenericHTMLFormElement::GetDesiredIMEState(); -} - -NS_IMETHODIMP -nsHTMLObjectElement::Reset() -{ - return NS_OK; -} - -NS_IMETHODIMP -nsHTMLObjectElement::SubmitNamesValues(nsFormSubmission *aFormSubmission) -{ - nsAutoString name; - if (!GetAttr(kNameSpaceID_None, nsGkAtoms::name, name)) { - // No name, don't submit. - - return NS_OK; - } - - nsIFrame* frame = GetPrimaryFrame(); - - nsIObjectFrame *objFrame = do_QueryFrame(frame); - if (!objFrame) { - // No frame, nothing to submit. - - return NS_OK; - } - - nsRefPtr<nsNPAPIPluginInstance> pi; - objFrame->GetPluginInstance(getter_AddRefs(pi)); - if (!pi) - return NS_OK; - - nsAutoString value; - nsresult rv = pi->GetFormValue(value); - NS_ENSURE_SUCCESS(rv, rv); - - return aFormSubmission->AddNameValuePair(name, value); -} - -NS_IMPL_STRING_ATTR(nsHTMLObjectElement, Align, align) -NS_IMPL_STRING_ATTR(nsHTMLObjectElement, Archive, archive) -NS_IMPL_STRING_ATTR(nsHTMLObjectElement, Border, border) -NS_IMPL_URI_ATTR_WITH_BASE(nsHTMLObjectElement, Code, code, codebase) -NS_IMPL_URI_ATTR(nsHTMLObjectElement, CodeBase, codebase) -NS_IMPL_STRING_ATTR(nsHTMLObjectElement, CodeType, codetype) -NS_IMPL_URI_ATTR_WITH_BASE(nsHTMLObjectElement, Data, data, codebase) -NS_IMPL_BOOL_ATTR(nsHTMLObjectElement, Declare, declare) -NS_IMPL_STRING_ATTR(nsHTMLObjectElement, Height, height) -NS_IMPL_INT_ATTR(nsHTMLObjectElement, Hspace, hspace) -NS_IMPL_STRING_ATTR(nsHTMLObjectElement, Name, name) -NS_IMPL_STRING_ATTR(nsHTMLObjectElement, Standby, standby) -NS_IMPL_STRING_ATTR(nsHTMLObjectElement, Type, type) -NS_IMPL_STRING_ATTR(nsHTMLObjectElement, UseMap, usemap) -NS_IMPL_INT_ATTR(nsHTMLObjectElement, Vspace, vspace) -NS_IMPL_STRING_ATTR(nsHTMLObjectElement, Width, width) - -int32_t -nsHTMLObjectElement::TabIndexDefault() -{ - return IsFocusableForTabIndex() ? 0 : -1; -} - -NS_IMETHODIMP -nsHTMLObjectElement::GetContentDocument(nsIDOMDocument **aContentDocument) -{ - NS_ENSURE_ARG_POINTER(aContentDocument); - - *aContentDocument = nullptr; - - if (!IsInDoc()) { - return NS_OK; - } - - // XXXbz should this use GetCurrentDoc()? sXBL/XBL2 issue! - nsIDocument *sub_doc = OwnerDoc()->GetSubDocumentFor(this); - if (!sub_doc) { - return NS_OK; - } - - return CallQueryInterface(sub_doc, aContentDocument); -} - -NS_IMETHODIMP -nsHTMLObjectElement::GetSVGDocument(nsIDOMDocument **aResult) -{ - return GetContentDocument(aResult); -} - -bool -nsHTMLObjectElement::ParseAttribute(int32_t aNamespaceID, - nsIAtom *aAttribute, - const nsAString &aValue, - nsAttrValue &aResult) -{ - if (aNamespaceID == kNameSpaceID_None) { - if (aAttribute == nsGkAtoms::align) { - return ParseAlignValue(aValue, aResult); - } - if (ParseImageAttribute(aAttribute, aValue, aResult)) { - return true; - } - } - - return nsGenericHTMLFormElement::ParseAttribute(aNamespaceID, aAttribute, - aValue, aResult); -} - -static void -MapAttributesIntoRule(const nsMappedAttributes *aAttributes, - nsRuleData *aData) -{ - nsGenericHTMLFormElement::MapImageAlignAttributeInto(aAttributes, aData); - nsGenericHTMLFormElement::MapImageBorderAttributeInto(aAttributes, aData); - nsGenericHTMLFormElement::MapImageMarginAttributeInto(aAttributes, aData); - nsGenericHTMLFormElement::MapImageSizeAttributesInto(aAttributes, aData); - nsGenericHTMLFormElement::MapCommonAttributesInto(aAttributes, aData); -} - -NS_IMETHODIMP_(bool) -nsHTMLObjectElement::IsAttributeMapped(const nsIAtom *aAttribute) const -{ - static const MappedAttributeEntry* const map[] = { - sCommonAttributeMap, - sImageMarginSizeAttributeMap, - sImageBorderAttributeMap, - sImageAlignAttributeMap, - }; - - return FindAttributeDependence(aAttribute, map); -} - - -nsMapRuleToAttributesFunc -nsHTMLObjectElement::GetAttributeMappingFunction() const -{ - return &MapAttributesIntoRule; -} - -void -nsHTMLObjectElement::StartObjectLoad(bool aNotify) -{ - // BindToTree can call us asynchronously, and we may be removed from the tree - // in the interim - if (!IsInDoc() || !OwnerDoc()->IsActive()) { - return; - } - - LoadObject(aNotify); - SetIsNetworkCreated(false); -} - -nsEventStates -nsHTMLObjectElement::IntrinsicState() const -{ - return nsGenericHTMLFormElement::IntrinsicState() | ObjectState(); -} - -uint32_t -nsHTMLObjectElement::GetCapabilities() const -{ - return nsObjectLoadingContent::GetCapabilities() | eSupportClassID; -} - -void -nsHTMLObjectElement::DestroyContent() -{ - nsObjectLoadingContent::DestroyContent(); - nsGenericHTMLFormElement::DestroyContent(); -} - -nsresult -nsHTMLObjectElement::CopyInnerTo(Element* aDest) -{ - nsresult rv = nsGenericHTMLFormElement::CopyInnerTo(aDest); - NS_ENSURE_SUCCESS(rv, rv); - - if (aDest->OwnerDoc()->IsStaticDocument()) { - CreateStaticClone(static_cast<nsHTMLObjectElement*>(aDest)); - } - - return rv; -}
--- a/content/html/content/src/nsHTMLOutputElement.cpp +++ b/content/html/content/src/nsHTMLOutputElement.cpp @@ -102,26 +102,27 @@ nsHTMLOutputElement::nsHTMLOutputElement nsHTMLOutputElement::~nsHTMLOutputElement() { if (mTokenList) { mTokenList->DropReference(); } } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLOutputElement) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHTMLOutputElement, nsGenericHTMLFormElement) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mValidity) if (tmp->mTokenList) { tmp->mTokenList->DropReference(); NS_IMPL_CYCLE_COLLECTION_UNLINK(mTokenList) } NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLOutputElement, nsGenericHTMLFormElement) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mValidity) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTokenList) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_ADDREF_INHERITED(nsHTMLOutputElement, Element) NS_IMPL_RELEASE_INHERITED(nsHTMLOutputElement, Element) DOMCI_NODE_DATA(HTMLOutputElement, nsHTMLOutputElement)
--- a/content/html/content/src/nsHTMLSelectElement.cpp +++ b/content/html/content/src/nsHTMLSelectElement.cpp @@ -130,21 +130,25 @@ nsHTMLSelectElement::nsHTMLSelectElement nsHTMLSelectElement::~nsHTMLSelectElement() { mOptions->DropReference(); } // ISupports -NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLSelectElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLSelectElement, nsGenericHTMLFormElement) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mValidity) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOptions) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHTMLSelectElement, + nsGenericHTMLFormElement) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mValidity) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_ADDREF_INHERITED(nsHTMLSelectElement, Element) NS_IMPL_RELEASE_INHERITED(nsHTMLSelectElement, Element) DOMCI_NODE_DATA(HTMLSelectElement, nsHTMLSelectElement) // QueryInterface implementation for nsHTMLSelectElement @@ -1973,17 +1977,16 @@ nsHTMLOptionCollection::GetOptionIndex(m return NS_OK; } } return NS_ERROR_FAILURE; } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLOptionCollection) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsHTMLOptionCollection) NS_IMPL_CYCLE_COLLECTION_UNLINK(mElements) NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsHTMLOptionCollection) { uint32_t i; for (i = 0; i < tmp->mElements.Length(); ++i) {
--- a/content/html/content/src/nsHTMLSelectElement.h +++ b/content/html/content/src/nsHTMLSelectElement.h @@ -377,18 +377,18 @@ public: nsAttrValue& aResult); virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const; virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute, int32_t aModType) const; NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const; virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const; - NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsHTMLSelectElement, - nsGenericHTMLFormElement) + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHTMLSelectElement, + nsGenericHTMLFormElement) nsHTMLOptionCollection *GetOptions() { return mOptions; } static nsHTMLSelectElement *FromSupports(nsISupports *aSupports) {
--- a/content/html/content/src/nsHTMLSharedObjectElement.cpp +++ b/content/html/content/src/nsHTMLSharedObjectElement.cpp @@ -201,17 +201,16 @@ nsHTMLSharedObjectElement::DoneAddingChi // If we're already in a document, we need to trigger the load // Otherwise, BindToTree takes care of that. if (IsInDoc()) { StartObjectLoad(aHaveNotified); } } } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLSharedObjectElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLSharedObjectElement, nsGenericHTMLElement) nsObjectLoadingContent::Traverse(tmp, cb); NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_ADDREF_INHERITED(nsHTMLSharedObjectElement, Element) NS_IMPL_RELEASE_INHERITED(nsHTMLSharedObjectElement, Element)
--- a/content/html/content/src/nsHTMLStyleElement.cpp +++ b/content/html/content/src/nsHTMLStyleElement.cpp @@ -105,17 +105,16 @@ nsHTMLStyleElement::nsHTMLStyleElement(a { AddMutationObserver(this); } nsHTMLStyleElement::~nsHTMLStyleElement() { } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLStyleElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLStyleElement, nsGenericHTMLElement) tmp->nsStyleLinkElement::Traverse(cb); NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHTMLStyleElement, nsGenericHTMLElement) tmp->nsStyleLinkElement::Unlink(); NS_IMPL_CYCLE_COLLECTION_UNLINK_END
--- a/content/html/content/src/nsHTMLTextAreaElement.cpp +++ b/content/html/content/src/nsHTMLTextAreaElement.cpp @@ -295,24 +295,25 @@ nsHTMLTextAreaElement::nsHTMLTextAreaEle // until someone calls UpdateEditableState on us, apparently! Also // by default we don't have to show validity UI and so forth. AddStatesSilently(NS_EVENT_STATE_ENABLED | NS_EVENT_STATE_OPTIONAL | NS_EVENT_STATE_VALID); } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLTextAreaElement) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHTMLTextAreaElement, nsGenericHTMLFormElement) + NS_IMPL_CYCLE_COLLECTION_UNLINK(mValidity) NS_IMPL_CYCLE_COLLECTION_UNLINK(mControllers) tmp->mState.Unlink(); NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLTextAreaElement, nsGenericHTMLFormElement) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mValidity) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mControllers) tmp->mState.Traverse(cb); NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_ADDREF_INHERITED(nsHTMLTextAreaElement, Element) NS_IMPL_RELEASE_INHERITED(nsHTMLTextAreaElement, Element)
--- a/content/html/content/src/nsIConstraintValidation.cpp +++ b/content/html/content/src/nsIConstraintValidation.cpp @@ -3,45 +3,52 @@ * 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 "nsIConstraintValidation.h" #include "nsAString.h" #include "nsGenericHTMLElement.h" #include "nsHTMLFormElement.h" -#include "nsDOMValidityState.h" +#include "mozilla/dom/ValidityState.h" #include "nsIFormControl.h" #include "nsContentUtils.h" const uint16_t nsIConstraintValidation::sContentSpecifiedMaxLengthMessage = 256; nsIConstraintValidation::nsIConstraintValidation() : mValidityBitField(0) - , mValidity(nullptr) // By default, all elements are subjects to constraint validation. , mBarredFromConstraintValidation(false) { } nsIConstraintValidation::~nsIConstraintValidation() { if (mValidity) { mValidity->Disconnect(); } } +mozilla::dom::ValidityState* +nsIConstraintValidation::Validity() +{ + if (!mValidity) { + mValidity = new mozilla::dom::ValidityState(this); + } + + return mValidity; +} + nsresult nsIConstraintValidation::GetValidity(nsIDOMValidityState** aValidity) { - if (!mValidity) { - mValidity = new nsDOMValidityState(this); - } + NS_ENSURE_ARG_POINTER(aValidity); - NS_ADDREF(*aValidity = mValidity); + NS_ADDREF(*aValidity = Validity()); return NS_OK; } NS_IMETHODIMP nsIConstraintValidation::GetValidationMessage(nsAString& aValidationMessage) { aValidationMessage.Truncate(); @@ -84,32 +91,40 @@ nsIConstraintValidation::GetValidationMe } } else { aValidationMessage.Truncate(); } return NS_OK; } -nsresult -nsIConstraintValidation::CheckValidity(bool* aValidity) +bool +nsIConstraintValidation::CheckValidity() { if (!IsCandidateForConstraintValidation() || IsValid()) { - *aValidity = true; - return NS_OK; + return true; } - *aValidity = false; - nsCOMPtr<nsIContent> content = do_QueryInterface(this); NS_ASSERTION(content, "This class should be inherited by HTML elements only!"); - return nsContentUtils::DispatchTrustedEvent(content->OwnerDoc(), content, - NS_LITERAL_STRING("invalid"), - false, true); + nsContentUtils::DispatchTrustedEvent(content->OwnerDoc(), content, + NS_LITERAL_STRING("invalid"), + false, true); + return false; +} + +nsresult +nsIConstraintValidation::CheckValidity(bool* aValidity) +{ + NS_ENSURE_ARG_POINTER(aValidity); + + *aValidity = CheckValidity(); + + return NS_OK; } void nsIConstraintValidation::SetValidityState(ValidityStateType aState, bool aValue) { bool previousValidity = IsValid();
--- a/content/html/document/src/ImageDocument.cpp +++ b/content/html/document/src/ImageDocument.cpp @@ -215,17 +215,16 @@ ImageDocument::ImageDocument() // NOTE! nsDocument::operator new() zeroes out all members, so don't // bother initializing members to 0. } ImageDocument::~ImageDocument() { } -NS_IMPL_CYCLE_COLLECTION_CLASS(ImageDocument) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ImageDocument, MediaDocument) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImageContent) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(ImageDocument, MediaDocument) NS_IMPL_CYCLE_COLLECTION_UNLINK(mImageContent) NS_IMPL_CYCLE_COLLECTION_UNLINK_END
--- a/content/html/document/src/PluginDocument.cpp +++ b/content/html/document/src/PluginDocument.cpp @@ -103,17 +103,16 @@ PluginStreamListener::OnStartRequest(nsI // bother initializing members to 0. PluginDocument::PluginDocument() {} PluginDocument::~PluginDocument() {} -NS_IMPL_CYCLE_COLLECTION_CLASS(PluginDocument) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(PluginDocument, MediaDocument) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mPluginContent) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(PluginDocument, MediaDocument) NS_IMPL_CYCLE_COLLECTION_UNLINK(mPluginContent) NS_IMPL_CYCLE_COLLECTION_UNLINK_END
--- a/content/html/document/src/nsHTMLContentSink.cpp +++ b/content/html/document/src/nsHTMLContentSink.cpp @@ -1283,18 +1283,16 @@ HTMLContentSink::~HTMLContentSink() delete mHeadContext; for (i = 0; uint32_t(i) < ArrayLength(mNodeInfoCache); ++i) { NS_IF_RELEASE(mNodeInfoCache[i]); } } -NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLContentSink) - NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLContentSink, nsContentSink) NS_IMPL_CYCLE_COLLECTION_UNLINK(mHTMLDocument) NS_IMPL_CYCLE_COLLECTION_UNLINK(mRoot) NS_IMPL_CYCLE_COLLECTION_UNLINK(mBody) NS_IMPL_CYCLE_COLLECTION_UNLINK(mHead) for (uint32_t i = 0; i < ArrayLength(tmp->mNodeInfoCache); ++i) { NS_IF_RELEASE(tmp->mNodeInfoCache[i]); }
--- a/content/html/document/src/nsHTMLDocument.cpp +++ b/content/html/document/src/nsHTMLDocument.cpp @@ -200,17 +200,16 @@ nsHTMLDocument::nsHTMLDocument() // NOTE! nsDocument::operator new() zeroes out all members, so don't // bother initializing members to 0. mIsRegularHTML = true; mDefaultElementType = kNameSpaceID_XHTML; mCompatMode = eCompatibility_NavQuirks; } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLDocument) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLDocument, nsDocument) NS_ASSERTION(!nsCCUncollectableMarker::InGeneration(cb, tmp->GetMarkedCCGeneration()), "Shouldn't traverse nsHTMLDocument!"); NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mImages) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mApplets) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEmbeds) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mLinks)
--- a/content/media/MediaDecoderStateMachine.cpp +++ b/content/media/MediaDecoderStateMachine.cpp @@ -993,17 +993,16 @@ void MediaDecoderStateMachine::AudioLoop playbackRate = mPlaybackRate; if (playbackRate != 1.0) { NS_ASSERTION(playbackRate != 0, "Don't set the playbackRate to 0 on an AudioStream."); mAudioStream->SetPlaybackRate(playbackRate); } } while (1) { - // Wait while we're not playing, and we're not shutting down, or we're // playing and we've got no audio to play. { ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); NS_ASSERTION(mState != DECODER_STATE_DECODING_METADATA, "Should have meta data before audio started playing."); while (mState != DECODER_STATE_SHUTDOWN && !mStopAudioThread && @@ -1256,17 +1255,17 @@ void MediaDecoderStateMachine::StopPlayb } void MediaDecoderStateMachine::StartPlayback() { LOG(PR_LOG_DEBUG, ("%p StartPlayback()", mDecoder.get())); NS_ASSERTION(!IsPlaying(), "Shouldn't be playing when StartPlayback() is called"); mDecoder->GetReentrantMonitor().AssertCurrentThreadIn(); - LOG(PR_LOG_DEBUG, ("%p StartPlayback", mDecoder.get())); + mDecoder->NotifyPlaybackStarted(); mPlayStartTime = TimeStamp::Now(); NS_ASSERTION(IsPlaying(), "Should report playing by end of StartPlayback()"); if (NS_FAILED(StartAudioThread())) { NS_WARNING("Failed to create audio thread"); } mDecoder->GetReentrantMonitor().NotifyAll(); @@ -2027,16 +2026,24 @@ nsresult MediaDecoderStateMachine::RunSt NS_ENSURE_TRUE(resource, NS_ERROR_NULL_POINTER); switch (mState) { case DECODER_STATE_SHUTDOWN: { if (IsPlaying()) { StopPlayback(); } StopAudioThread(); + // If mAudioThread is non-null after StopAudioThread completes, we are + // running in a nested event loop waiting for Shutdown() on + // mAudioThread to complete. Return to the event loop and let it + // finish processing before continuing with shutdown. + if (mAudioThread) { + MOZ_ASSERT(mStopAudioThread); + return NS_OK; + } StopDecodeThread(); // Now that those threads are stopped, there's no possibility of // mPendingWakeDecoder being needed again. Revoke it. mPendingWakeDecoder = nullptr; NS_ASSERTION(mState == DECODER_STATE_SHUTDOWN, "How did we escape from the shutdown state?"); // We must daisy-chain these events to destroy the decoder. We must // destroy the decoder on the main thread, but we can't destroy the @@ -2182,17 +2189,17 @@ nsresult MediaDecoderStateMachine::RunSt StopPlayback(); if (mState != DECODER_STATE_COMPLETED) { // While we're presenting a frame we can change state. Whatever changed // our state should have scheduled another state machine run. NS_ASSERTION(IsStateMachineScheduled(), "Must have timer scheduled"); return NS_OK; } - + StopAudioThread(); if (mDecoder->GetState() == MediaDecoder::PLAY_STATE_PLAYING) { int64_t videoTime = HasVideo() ? mVideoFrameEndTime : 0; int64_t clockTime = std::max(mEndTime, std::max(videoTime, GetAudioClock())); UpdatePlaybackPosition(clockTime); nsCOMPtr<nsIRunnable> event = NS_NewRunnableMethod(mDecoder, &MediaDecoder::PlaybackEnded); NS_DispatchToMainThread(event, NS_DISPATCH_NORMAL); @@ -2624,17 +2631,17 @@ void MediaDecoderStateMachine::TimeoutEx // Otherwise, an event has already been dispatched to run the state machine // as soon as possible. Nothing else needed to do, the state machine is // going to run anyway. } void MediaDecoderStateMachine::ScheduleStateMachineWithLockAndWakeDecoder() { ReentrantMonitorAutoEnter mon(mDecoder->GetReentrantMonitor()); mon.NotifyAll(); - ScheduleStateMachine(0); + ScheduleStateMachine(); } nsresult MediaDecoderStateMachine::ScheduleStateMachine(int64_t aUsecs) { mDecoder->GetReentrantMonitor().AssertCurrentThreadIn(); NS_ABORT_IF_FALSE(GetStateMachineThread(), "Must have a state machine thread to schedule"); if (mState == DECODER_STATE_SHUTDOWN) {
--- a/content/media/nsDOMMediaStream.cpp +++ b/content/media/nsDOMMediaStream.cpp @@ -15,18 +15,16 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION( NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_ENTRY(nsIDOMMediaStream) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MediaStream) NS_INTERFACE_MAP_END NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMMediaStream) NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMMediaStream) -NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMMediaStream) - NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMMediaStream) NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMMediaStream) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END // LocalMediaStream currently is the same C++ class as MediaStream; // they may eventually split @@ -37,18 +35,16 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION( NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIDOMMediaStream, nsDOMMediaStream) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMLocalMediaStream) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(LocalMediaStream) NS_INTERFACE_MAP_END NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMLocalMediaStream) NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMLocalMediaStream) -NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMLocalMediaStream) - NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMLocalMediaStream) NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMLocalMediaStream) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END nsDOMMediaStream::~nsDOMMediaStream()
--- a/content/media/webaudio/AudioBuffer.cpp +++ b/content/media/webaudio/AudioBuffer.cpp @@ -9,18 +9,16 @@ #include "nsContentUtils.h" #include "AudioContext.h" #include "jsfriendapi.h" #include "mozilla/ErrorResult.h" namespace mozilla { namespace dom { -NS_IMPL_CYCLE_COLLECTION_CLASS(AudioBuffer) - NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(AudioBuffer) NS_IMPL_CYCLE_COLLECTION_UNLINK(mContext) NS_IMPL_CYCLE_COLLECTION_UNLINK(mChannels) NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(AudioBuffer) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContext)
--- a/content/smil/nsDOMTimeEvent.cpp +++ b/content/smil/nsDOMTimeEvent.cpp @@ -34,18 +34,16 @@ nsDOMTimeEvent::nsDOMTimeEvent(nsPresCon nsCOMPtr<nsIDOMWindow> window = do_GetInterface(container); if (window) { mView = do_QueryInterface(window); } } } } -NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMTimeEvent) - NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMTimeEvent, nsDOMEvent) NS_IMPL_CYCLE_COLLECTION_UNLINK(mView) NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMTimeEvent, nsDOMEvent) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mView) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
copy from content/svg/content/src/DOMSVGPoint.cpp copy to content/svg/content/nsISVGPoint.cpp --- a/content/svg/content/src/DOMSVGPoint.cpp +++ b/content/svg/content/nsISVGPoint.cpp @@ -16,17 +16,16 @@ // See the architecture comment in DOMSVGPointList.h. using namespace mozilla; // We could use NS_IMPL_CYCLE_COLLECTION_1, except that in Unlink() we need to // clear our list's weak ref to us to be safe. (The other option would be to // not unlink and rely on the breaking of the other edges in the cycle, as // NS_SVG_VAL_IMPL_CYCLE_COLLECTION does.) -NS_IMPL_CYCLE_COLLECTION_CLASS(DOMSVGPoint) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGPoint) // We may not belong to a list, so we must null check tmp->mList. if (tmp->mList) { tmp->mList->mItems[tmp->mListIndex] = nullptr; } NS_IMPL_CYCLE_COLLECTION_UNLINK(mList) NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER NS_IMPL_CYCLE_COLLECTION_UNLINK_END
--- a/content/svg/content/src/DOMSVGLength.cpp +++ b/content/svg/content/src/DOMSVGLength.cpp @@ -16,17 +16,16 @@ // See the architecture comment in DOMSVGAnimatedLengthList.h. namespace mozilla { // We could use NS_IMPL_CYCLE_COLLECTION_1, except that in Unlink() we need to // clear our list's weak ref to us to be safe. (The other option would be to // not unlink and rely on the breaking of the other edges in the cycle, as // NS_SVG_VAL_IMPL_CYCLE_COLLECTION does.) -NS_IMPL_CYCLE_COLLECTION_CLASS(DOMSVGLength) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGLength) // We may not belong to a list, so we must null check tmp->mList. if (tmp->mList) { tmp->mList->mItems[tmp->mListIndex] = nullptr; } NS_IMPL_CYCLE_COLLECTION_UNLINK(mList) NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGLength)
--- a/content/svg/content/src/DOMSVGLengthList.cpp +++ b/content/svg/content/src/DOMSVGLengthList.cpp @@ -35,17 +35,16 @@ void UpdateListIndicesFromIndex(nsTArray } // namespace namespace mozilla { // We could use NS_IMPL_CYCLE_COLLECTION_1, except that in Unlink() we need to // clear our DOMSVGAnimatedLengthList's weak ref to us to be safe. (The other // option would be to not unlink and rely on the breaking of the other edges in // the cycle, as NS_SVG_VAL_IMPL_CYCLE_COLLECTION does.) -NS_IMPL_CYCLE_COLLECTION_CLASS(DOMSVGLengthList) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGLengthList) if (tmp->mAList) { if (tmp->IsAnimValList()) { tmp->mAList->mAnimVal = nullptr; } else { tmp->mAList->mBaseVal = nullptr; } NS_IMPL_CYCLE_COLLECTION_UNLINK(mAList)
--- a/content/svg/content/src/DOMSVGNumber.cpp +++ b/content/svg/content/src/DOMSVGNumber.cpp @@ -15,17 +15,16 @@ // See the architecture comment in DOMSVGAnimatedNumberList.h. using namespace mozilla; // We could use NS_IMPL_CYCLE_COLLECTION_1, except that in Unlink() we need to // clear our list's weak ref to us to be safe. (The other option would be to // not unlink and rely on the breaking of the other edges in the cycle, as // NS_SVG_VAL_IMPL_CYCLE_COLLECTION does.) -NS_IMPL_CYCLE_COLLECTION_CLASS(DOMSVGNumber) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGNumber) // We may not belong to a list, so we must null check tmp->mList. if (tmp->mList) { tmp->mList->mItems[tmp->mListIndex] = nullptr; } NS_IMPL_CYCLE_COLLECTION_UNLINK(mList) NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGNumber)
--- a/content/svg/content/src/DOMSVGNumberList.cpp +++ b/content/svg/content/src/DOMSVGNumberList.cpp @@ -35,17 +35,16 @@ void UpdateListIndicesFromIndex(nsTArray } } // namespace // We could use NS_IMPL_CYCLE_COLLECTION_1, except that in Unlink() we need to // clear our DOMSVGAnimatedNumberList's weak ref to us to be safe. (The other // option would be to not unlink and rely on the breaking of the other edges in // the cycle, as NS_SVG_VAL_IMPL_CYCLE_COLLECTION does.) -NS_IMPL_CYCLE_COLLECTION_CLASS(DOMSVGNumberList) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGNumberList) if (tmp->mAList) { if (tmp->IsAnimValList()) { tmp->mAList->mAnimVal = nullptr; } else { tmp->mAList->mBaseVal = nullptr; } NS_IMPL_CYCLE_COLLECTION_UNLINK(mAList)
--- a/content/svg/content/src/DOMSVGPathSeg.cpp +++ b/content/svg/content/src/DOMSVGPathSeg.cpp @@ -15,17 +15,16 @@ // See the architecture comment in DOMSVGPathSegList.h. using namespace mozilla; // We could use NS_IMPL_CYCLE_COLLECTION_1, except that in Unlink() we need to // clear our list's weak ref to us to be safe. (The other option would be to // not unlink and rely on the breaking of the other edges in the cycle, as // NS_SVG_VAL_IMPL_CYCLE_COLLECTION does.) -NS_IMPL_CYCLE_COLLECTION_CLASS(DOMSVGPathSeg) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGPathSeg) // We may not belong to a list, so we must null check tmp->mList. if (tmp->mList) { tmp->mList->ItemAt(tmp->mListIndex) = nullptr; } NS_IMPL_CYCLE_COLLECTION_UNLINK(mList) NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER NS_IMPL_CYCLE_COLLECTION_UNLINK_END @@ -359,155 +358,8 @@ DOMSVGPathSeg::CreateFor(DOMSVGPathSegLi case PATHSEG_CURVETO_QUADRATIC_SMOOTH_REL: return new DOMSVGPathSegCurvetoQuadraticSmoothRel(aList, aListIndex, aIsAnimValItem); default: NS_NOTREACHED("Invalid path segment type"); return nullptr; } } - - - -DOMSVGPathSeg* -NS_NewSVGPathSegClosePath() -{ - return new DOMSVGPathSegClosePath(); -} - -DOMSVGPathSeg* -NS_NewSVGPathSegMovetoAbs(float x, float y) -{ - return new DOMSVGPathSegMovetoAbs(x, y); -} - -DOMSVGPathSeg* -NS_NewSVGPathSegMovetoRel(float x, float y) -{ - return new DOMSVGPathSegMovetoRel(x, y); -} - -DOMSVGPathSeg* -NS_NewSVGPathSegLinetoAbs(float x, float y) -{ - return new DOMSVGPathSegLinetoAbs(x, y); -} - -DOMSVGPathSeg* -NS_NewSVGPathSegLinetoRel(float x, float y) -{ - return new DOMSVGPathSegLinetoRel(x, y); -} - -DOMSVGPathSeg* -NS_NewSVGPathSegCurvetoCubicAbs(float x, float y, - float x1, float y1, - float x2, float y2) -{ - // Note that we swap from DOM API argument order to the argument order used - // in the <path> element's 'd' attribute (i.e. we put the arguments for the - // end point of the segment last instead of first). - - return new DOMSVGPathSegCurvetoCubicAbs(x1, y1, x2, y2, x, y); -} - -DOMSVGPathSeg* -NS_NewSVGPathSegCurvetoCubicRel(float x, float y, - float x1, float y1, - float x2, float y2) -{ - // See comment in NS_NewSVGPathSegCurvetoCubicAbs! - - return new DOMSVGPathSegCurvetoCubicRel(x1, y1, x2, y2, x, y); -} - -DOMSVGPathSeg* -NS_NewSVGPathSegCurvetoQuadraticAbs(float x, float y, - float x1, float y1) -{ - // See comment in NS_NewSVGPathSegCurvetoCubicAbs! - - return new DOMSVGPathSegCurvetoQuadraticAbs(x1, y1, x, y); -} - -DOMSVGPathSeg* -NS_NewSVGPathSegCurvetoQuadraticRel(float x, float y, - float x1, float y1) -{ - // See comment in NS_NewSVGPathSegCurvetoCubicAbs! - - return new DOMSVGPathSegCurvetoQuadraticRel(x1, y1, x, y); -} - -DOMSVGPathSeg* -NS_NewSVGPathSegArcAbs(float x, float y, - float r1, float r2, float angle, - bool largeArcFlag, bool sweepFlag) -{ - // See comment in NS_NewSVGPathSegCurvetoCubicAbs! - - return new DOMSVGPathSegArcAbs(r1, r2, angle, largeArcFlag, sweepFlag, x, y); -} - -DOMSVGPathSeg* -NS_NewSVGPathSegArcRel(float x, float y, - float r1, float r2, float angle, - bool largeArcFlag, bool sweepFlag) -{ - // See comment in NS_NewSVGPathSegCurvetoCubicAbs! - - return new DOMSVGPathSegArcRel(r1, r2, angle, largeArcFlag, sweepFlag, x, y); -} - -DOMSVGPathSeg* -NS_NewSVGPathSegLinetoHorizontalAbs(float x) -{ - return new DOMSVGPathSegLinetoHorizontalAbs(x); -} - -DOMSVGPathSeg* -NS_NewSVGPathSegLinetoHorizontalRel(float x) -{ - return new DOMSVGPathSegLinetoHorizontalRel(x); -} - -DOMSVGPathSeg* -NS_NewSVGPathSegLinetoVerticalAbs(float y) -{ - return new DOMSVGPathSegLinetoVerticalAbs(y); -} - -DOMSVGPathSeg* -NS_NewSVGPathSegLinetoVerticalRel(float y) -{ - return new DOMSVGPathSegLinetoVerticalRel(y); -} - -DOMSVGPathSeg* -NS_NewSVGPathSegCurvetoCubicSmoothAbs(float x, float y, - float x2, float y2) -{ - // See comment in NS_NewSVGPathSegCurvetoCubicAbs! - - return new DOMSVGPathSegCurvetoCubicSmoothAbs(x2, y2, x, y); -} - -DOMSVGPathSeg* -NS_NewSVGPathSegCurvetoCubicSmoothRel(float x, float y, - float x2, float y2) -{ - // See comment in NS_NewSVGPathSegCurvetoCubicAbs! - - return new DOMSVGPathSegCurvetoCubicSmoothRel(x2, y2, x, y); -} - -DOMSVGPathSeg* -NS_NewSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y) -{ - return new DOMSVGPathSegCurvetoQuadraticSmoothAbs(x, y); -} - -DOMSVGPathSeg* -NS_NewSVGPathSegCurvetoQuadraticSmoothRel(float x, float y) -{ - return new DOMSVGPathSegCurvetoQuadraticSmoothRel(x, y); -} -
--- a/content/svg/content/src/DOMSVGPathSeg.h +++ b/content/svg/content/src/DOMSVGPathSeg.h @@ -723,80 +723,11 @@ public: void SetY(float aY, ErrorResult& rv); protected: float mArgs[2]; }; } // namespace mozilla -mozilla::DOMSVGPathSeg* -NS_NewSVGPathSegClosePath(); - -mozilla::DOMSVGPathSeg* -NS_NewSVGPathSegMovetoAbs(float x, float y); - -mozilla::DOMSVGPathSeg* -NS_NewSVGPathSegMovetoRel(float x, float y); - -mozilla::DOMSVGPathSeg* -NS_NewSVGPathSegLinetoAbs(float x, float y); - -mozilla::DOMSVGPathSeg* -NS_NewSVGPathSegLinetoRel(float x, float y); - -mozilla::DOMSVGPathSeg* -NS_NewSVGPathSegCurvetoCubicAbs(float x, float y, - float x1, float y1, - float x2, float y2); - -mozilla::DOMSVGPathSeg* -NS_NewSVGPathSegCurvetoCubicRel(float x, float y, - float x1, float y1, - float x2, float y2); - -mozilla::DOMSVGPathSeg* -NS_NewSVGPathSegCurvetoQuadraticAbs(float x, float y, - float x1, float y1); - -mozilla::DOMSVGPathSeg* -NS_NewSVGPathSegCurvetoQuadraticRel(float x, float y, - float x1, float y1); - -mozilla::DOMSVGPathSeg* -NS_NewSVGPathSegArcAbs(float x, float y, - float r1, float r2, float angle, - bool largeArcFlag, bool sweepFlag); - -mozilla::DOMSVGPathSeg* -NS_NewSVGPathSegArcRel(float x, float y, - float r1, float r2, float angle, - bool largeArcFlag, bool sweepFlag); - -mozilla::DOMSVGPathSeg* -NS_NewSVGPathSegLinetoHorizontalAbs(float x); - -mozilla::DOMSVGPathSeg* -NS_NewSVGPathSegLinetoHorizontalRel(float x); - -mozilla::DOMSVGPathSeg* -NS_NewSVGPathSegLinetoVerticalAbs(float y); - -mozilla::DOMSVGPathSeg* -NS_NewSVGPathSegLinetoVerticalRel(float y); - -mozilla::DOMSVGPathSeg* -NS_NewSVGPathSegCurvetoCubicSmoothAbs(float x, float y, - float x2, float y2); - -mozilla::DOMSVGPathSeg* -NS_NewSVGPathSegCurvetoCubicSmoothRel(float x, float y, - float x2, float y2); - -mozilla::DOMSVGPathSeg* -NS_NewSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y); - -mozilla::DOMSVGPathSeg* -NS_NewSVGPathSegCurvetoQuadraticSmoothRel(float x, float y); - #undef MOZ_SVG_LIST_INDEX_BIT_COUNT #endif // MOZILLA_DOMSVGPATHSEG_H__
--- a/content/svg/content/src/DOMSVGPathSegList.cpp +++ b/content/svg/content/src/DOMSVGPathSegList.cpp @@ -16,17 +16,16 @@ // See the comment in this file's header. namespace mozilla { static nsSVGAttrTearoffTable<void, DOMSVGPathSegList> sSVGPathSegListTearoffTable; -NS_IMPL_CYCLE_COLLECTION_CLASS(DOMSVGPathSegList) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGPathSegList) // No unlinking of mElement, we'd need to null out the value pointer (the // object it points to is held by the element) and null-check it everywhere. NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGPathSegList) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
--- a/content/svg/content/src/DOMSVGPoint.cpp +++ b/content/svg/content/src/DOMSVGPoint.cpp @@ -12,49 +12,16 @@ #include "nsContentUtils.h" // NS_ENSURE_FINITE #include "mozilla/dom/SVGMatrix.h" #include "mozilla/dom/SVGPointBinding.h" // See the architecture comment in DOMSVGPointList.h. using namespace mozilla; -// We could use NS_IMPL_CYCLE_COLLECTION_1, except that in Unlink() we need to -// clear our list's weak ref to us to be safe. (The other option would be to -// not unlink and rely on the breaking of the other edges in the cycle, as -// NS_SVG_VAL_IMPL_CYCLE_COLLECTION does.) -NS_IMPL_CYCLE_COLLECTION_CLASS(DOMSVGPoint) -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGPoint) - // We may not belong to a list, so we must null check tmp->mList. - if (tmp->mList) { - tmp->mList->mItems[tmp->mListIndex] = nullptr; - } -NS_IMPL_CYCLE_COLLECTION_UNLINK(mList) -NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER -NS_IMPL_CYCLE_COLLECTION_UNLINK_END - -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGPoint) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mList) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END - -NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(DOMSVGPoint) -NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER -NS_IMPL_CYCLE_COLLECTION_TRACE_END - -NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMSVGPoint) -NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMSVGPoint) - -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMSVGPoint) - NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY - NS_INTERFACE_MAP_ENTRY(DOMSVGPoint) // pseudo-interface - NS_INTERFACE_MAP_ENTRY(nsISVGPoint) - NS_INTERFACE_MAP_ENTRY(nsISupports) -NS_INTERFACE_MAP_END - float DOMSVGPoint::X() { if (mIsAnimValItem && HasOwner()) { Element()->FlushAnimations(); // May make HasOwner() == false } return HasOwner() ? InternalItem().mX : mPt.mX; } @@ -119,47 +86,8 @@ DOMSVGPoint::MatrixTransform(dom::SVGMat { float x = HasOwner() ? InternalItem().mX : mPt.mX; float y = HasOwner() ? InternalItem().mY : mPt.mY; gfxPoint pt = matrix.Matrix().Transform(gfxPoint(x, y)); nsCOMPtr<nsISVGPoint> newPoint = new DOMSVGPoint(pt); return newPoint.forget(); } - -void -DOMSVGPoint::InsertingIntoList(DOMSVGPointList *aList, - uint32_t aListIndex, - bool aIsAnimValItem) -{ - NS_ABORT_IF_FALSE(!HasOwner(), "Inserting item that already has an owner"); - - mList = aList; - mListIndex = aListIndex; - mIsReadonly = false; - mIsAnimValItem = aIsAnimValItem; - - NS_ABORT_IF_FALSE(IndexIsValid(), "Bad index for DOMSVGPoint!"); -} - -void -DOMSVGPoint::RemovingFromList() -{ - mPt = InternalItem(); - mList = nullptr; - NS_ABORT_IF_FALSE(!mIsReadonly, "mIsReadonly set for list"); - mIsAnimValItem = false; -} - -SVGPoint& -DOMSVGPoint::InternalItem() -{ - return mList->InternalList().mItems[mListIndex]; -} - -#ifdef DEBUG -bool -DOMSVGPoint::IndexIsValid() -{ - return mListIndex < mList->InternalList().Length(); -} -#endif -
--- a/content/svg/content/src/DOMSVGPoint.h +++ b/content/svg/content/src/DOMSVGPoint.h @@ -14,27 +14,16 @@ #include "nsISVGPoint.h" #include "nsTArray.h" #include "SVGPoint.h" #include "nsWrapperCache.h" #include "mozilla/Attributes.h" class nsSVGElement; -// We make DOMSVGPoint a pseudo-interface to allow us to QI to it in order to -// check that the objects that scripts pass to DOMSVGPointList methods are -// our *native* point objects. -// -// {d6b6c440-af8d-40ee-856b-02a317cab275} -#define MOZILLA_DOMSVGPOINT_IID \ - { 0xd6b6c440, 0xaf8d, 0x40ee, \ - { 0x85, 0x6b, 0x02, 0xa3, 0x17, 0xca, 0xb2, 0x75 } } - -#define MOZ_SVG_LIST_INDEX_BIT_COUNT 30 - namespace mozilla { namespace dom { class SVGMatrix; } /** * Class DOMSVGPoint @@ -48,191 +37,76 @@ class SVGMatrix; * important points regarding these DOM wrapper structures. * * See the architecture comment in DOMSVGLength.h (yes, LENGTH) for an overview * of the important points regarding how this specific class works. */ class DOMSVGPoint MOZ_FINAL : public nsISVGPoint { public: - NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_DOMSVGPOINT_IID) - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMSVGPoint) - /** * Generic ctor for DOMSVGPoint objects that are created for an attribute. */ DOMSVGPoint(DOMSVGPointList *aList, uint32_t aListIndex, bool aIsAnimValItem) : nsISVGPoint() - , mList(aList) - , mListIndex(aListIndex) - , mIsReadonly(false) - , mIsAnimValItem(aIsAnimValItem) { + mList = aList; + mListIndex = aListIndex; + mIsAnimValItem = aIsAnimValItem; + // These shifts are in sync with the members. NS_ABORT_IF_FALSE(aList && aListIndex <= MaxListIndex(), "bad arg"); NS_ABORT_IF_FALSE(IndexIsValid(), "Bad index for DOMSVGPoint!"); } explicit DOMSVGPoint(const DOMSVGPoint *aPt = nullptr) : nsISVGPoint() - , mList(nullptr) - , mListIndex(0) - , mIsReadonly(false) - , mIsAnimValItem(false) { if (aPt) { mPt = aPt->ToSVGPoint(); } } DOMSVGPoint(float aX, float aY) : nsISVGPoint() - , mList(nullptr) - , mListIndex(0) - , mIsReadonly(false) - , mIsAnimValItem(false) { mPt.mX = aX; mPt.mY = aY; } explicit DOMSVGPoint(const gfxPoint &aPt) : nsISVGPoint() - , mList(nullptr) - , mListIndex(0) - , mIsReadonly(false) - , mIsAnimValItem(false) { mPt.mX = float(aPt.x); mPt.mY = float(aPt.y); NS_ASSERTION(NS_finite(mPt.mX) && NS_finite(mPt.mX), "DOMSVGPoint coords are not finite"); } - virtual ~DOMSVGPoint() { - // Our mList's weak ref to us must be nulled out when we die. If GC has - // unlinked us using the cycle collector code, then that has already - // happened, and mList is null. - if (mList) { - mList->mItems[mListIndex] = nullptr; - } - } - // WebIDL virtual float X(); virtual void SetX(float aX, ErrorResult& rv); virtual float Y(); virtual void SetY(float aY, ErrorResult& rv); virtual already_AddRefed<nsISVGPoint> MatrixTransform(dom::SVGMatrix& matrix); nsISupports* GetParentObject() MOZ_OVERRIDE { return mList; } - /** - * Create an unowned copy of this object. The caller is responsible for the - * first AddRef()! - */ - DOMSVGPoint* Clone() { + nsISVGPoint* Clone() { return new DOMSVGPoint(this); } - bool IsInList() const { - return !!mList; - } - - /** - * In future, if this class is used for non-list points, this will be - * different to IsInList(). "Owner" here means that the instance has an - * internal counterpart from which it gets its values. (A better name may - * be HasWrappee().) - */ - bool HasOwner() const { - return !!mList; - } - - /** - * This method is called to notify this DOM object that it is being inserted - * into a list, and give it the information it needs as a result. - * - * This object MUST NOT already belong to a list when this method is called. - * That's not to say that script can't move these DOM objects between - * lists - it can - it's just that the logic to handle that (and send out - * the necessary notifications) is located elsewhere (in DOMSVGPointList).) - */ - void InsertingIntoList(DOMSVGPointList *aList, - uint32_t aListIndex, - bool aIsAnimValItem); - - static uint32_t MaxListIndex() { - return (1U << MOZ_SVG_LIST_INDEX_BIT_COUNT) - 1; - } - - /// This method is called to notify this object that its list index changed. - void UpdateListIndex(uint32_t aListIndex) { - mListIndex = aListIndex; - } - - /** - * This method is called to notify this DOM object that it is about to be - * removed from its current DOM list so that it can first make a copy of its - * internal counterpart's values. (If it didn't do this, then it would - * "lose" its value on being removed.) - */ - void RemovingFromList(); - - SVGPoint ToSVGPoint() const { - return HasOwner() ? const_cast<DOMSVGPoint*>(this)->InternalItem() : mPt; - } - - bool IsReadonly() const { - return mIsReadonly; - } - void SetReadonly(bool aReadonly) { - mIsReadonly = aReadonly; - } - protected: nsSVGElement* Element() { return mList->Element(); } - - /** - * Get a reference to the internal SVGPoint list item that this DOM wrapper - * object currently wraps. - * - * To simplify the code we just have this one method for obtaining both - * baseVal and animVal internal items. This means that animVal items don't - * get const protection, but then our setter methods guard against changing - * animVal items. - */ - SVGPoint& InternalItem(); - -#ifdef DEBUG - bool IndexIsValid(); -#endif - - nsRefPtr<DOMSVGPointList> mList; - - // Bounds for the following are checked in the ctor, so be sure to update - // that if you change the capacity of any of the following. - - uint32_t mListIndex:MOZ_SVG_LIST_INDEX_BIT_COUNT; - uint32_t mIsReadonly:1; // uint32_t because MSVC won't pack otherwise - uint32_t mIsAnimValItem:1; // uint32_t because MSVC won't pack otherwise - - // The following member is only used when we're not in a list: - SVGPoint mPt; }; -NS_DEFINE_STATIC_IID_ACCESSOR(DOMSVGPoint, MOZILLA_DOMSVGPOINT_IID) - } // namespace mozilla -#undef MOZ_SVG_LIST_INDEX_BIT_COUNT - #endif // MOZILLA_DOMSVGPOINT_H__
--- a/content/svg/content/src/DOMSVGPointList.cpp +++ b/content/svg/content/src/DOMSVGPointList.cpp @@ -14,20 +14,18 @@ #include "mozilla/dom/SVGPointListBinding.h" #include <algorithm> // See the comment in this file's header. // local helper functions namespace { -using mozilla::DOMSVGPoint; - void -UpdateListIndicesFromIndex(nsTArray<DOMSVGPoint*>& aItemsArray, +UpdateListIndicesFromIndex(nsTArray<mozilla::nsISVGPoint*>& aItemsArray, uint32_t aStartingIndex) { uint32_t length = aItemsArray.Length(); for (uint32_t i = aStartingIndex; i < length; ++i) { if (aItemsArray[i]) { aItemsArray[i]->UpdateListIndex(i); } @@ -36,17 +34,16 @@ UpdateListIndicesFromIndex(nsTArray<DOMS } // namespace namespace mozilla { static nsSVGAttrTearoffTable<void, DOMSVGPointList> sSVGPointListTearoffTable; -NS_IMPL_CYCLE_COLLECTION_CLASS(DOMSVGPointList) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGPointList) // No unlinking of mElement, we'd need to null out the value pointer (the // object it points to is held by the element) and null-check it everywhere. NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(DOMSVGPointList) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS @@ -105,20 +102,20 @@ DOMSVGPointList::InternalListWillChangeT { // When the number of items in our internal counterpart changes, we MUST stay // in sync. Everything in the scary comment in // DOMSVGLengthList::InternalBaseValListWillChangeTo applies here too! uint32_t oldLength = mItems.Length(); uint32_t newLength = aNewValue.Length(); - if (newLength > DOMSVGPoint::MaxListIndex()) { + if (newLength > nsISVGPoint::MaxListIndex()) { // It's safe to get out of sync with our internal list as long as we have // FEWER items than it does. - newLength = DOMSVGPoint::MaxListIndex(); + newLength = nsISVGPoint::MaxListIndex(); } nsRefPtr<DOMSVGPointList> kungFuDeathGrip; if (newLength < oldLength) { // RemovingFromList() might clear last reference to |this|. // Retain a temporary reference to keep from dying before returning. kungFuDeathGrip = this; } @@ -210,21 +207,17 @@ DOMSVGPointList::Initialize(nsISVGPoint& // If aNewItem is already in a list we should insert a clone of aNewItem, // and for consistency, this should happen even if *this* is the list that // aNewItem is currently in. Note that in the case of aNewItem being in this // list, the Clear() call before the InsertItemBefore() call would remove it // from this list, and so the InsertItemBefore() call would not insert a // clone of aNewItem, it would actually insert aNewItem. To prevent that // from happening we have to do the clone here, if necessary. - nsCOMPtr<DOMSVGPoint> domItem = do_QueryInterface(&aNewItem); - if (!domItem) { - aError.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR); - return nullptr; - } + nsCOMPtr<nsISVGPoint> domItem = &aNewItem; if (domItem->HasOwner() || domItem->IsReadonly()) { domItem = domItem->Clone(); // must do this before changing anything! } ErrorResult rv; Clear(rv); MOZ_ASSERT(!rv.Failed()); return InsertItemBefore(*domItem, 0, aError); @@ -250,26 +243,22 @@ DOMSVGPointList::InsertItemBefore(nsISVG ErrorResult& aError) { if (IsAnimValList()) { aError.Throw(NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR); return nullptr; } aIndex = std::min(aIndex, LengthNoFlush()); - if (aIndex >= DOMSVGPoint::MaxListIndex()) { + if (aIndex >= nsISVGPoint::MaxListIndex()) { aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); return nullptr; } - nsCOMPtr<DOMSVGPoint> domItem = do_QueryInterface(&aNewItem); - if (!domItem) { - aError.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR); - return nullptr; - } + nsCOMPtr<nsISVGPoint> domItem = &aNewItem; if (domItem->HasOwner() || domItem->IsReadonly()) { domItem = domItem->Clone(); // must do this before changing anything! } // Ensure we have enough memory so we can avoid complex error handling below: if (!mItems.SetCapacity(mItems.Length() + 1) || !InternalList().SetCapacity(InternalList().Length() + 1)) { aError.Throw(NS_ERROR_OUT_OF_MEMORY); @@ -306,21 +295,17 @@ DOMSVGPointList::ReplaceItem(nsISVGPoint return nullptr; } if (aIndex >= LengthNoFlush()) { aError.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR); return nullptr; } - nsCOMPtr<DOMSVGPoint> domItem = do_QueryInterface(&aNewItem); - if (!domItem) { - aError.Throw(NS_ERROR_DOM_SVG_WRONG_TYPE_ERR); - return nullptr; - } + nsCOMPtr<nsISVGPoint> domItem = &aNewItem; if (domItem->HasOwner() || domItem->IsReadonly()) { domItem = domItem->Clone(); // must do this before changing anything! } nsAttrValue emptyOrOldValue = Element()->WillChangePointList(); if (mItems[aIndex]) { // Notify any existing DOM item of removal *before* modifying the lists so // that the DOM item can copy the *old* value at its index: @@ -361,17 +346,17 @@ DOMSVGPointList::RemoveItem(uint32_t aIn MaybeRemoveItemFromAnimValListAt(aIndex); // We have to return the removed item, so make sure it exists: EnsureItemAt(aIndex); // Notify the DOM item of removal *before* modifying the lists so that the // DOM item can copy its *old* value: mItems[aIndex]->RemovingFromList(); - nsRefPtr<DOMSVGPoint> result = mItems[aIndex]; + nsCOMPtr<nsISVGPoint> result = mItems[aIndex]; InternalList().RemoveItem(aIndex); mItems.RemoveElementAt(aIndex); UpdateListIndicesFromIndex(mItems, aIndex); Element()->DidChangePointList(emptyOrOldValue); if (AttrIsAnimating()) { @@ -404,17 +389,17 @@ DOMSVGPointList::MaybeInsertNullInAnimVa if (!animVal) { // No animVal list wrapper return; } NS_ABORT_IF_FALSE(animVal->mItems.Length() == mItems.Length(), "animVal list not in sync!"); - animVal->mItems.InsertElementAt(aIndex, static_cast<DOMSVGPoint*>(nullptr)); + animVal->mItems.InsertElementAt(aIndex, static_cast<nsISVGPoint*>(nullptr)); UpdateListIndicesFromIndex(animVal->mItems, aIndex + 1); } void DOMSVGPointList::MaybeRemoveItemFromAnimValListAt(uint32_t aIndex) { NS_ABORT_IF_FALSE(!IsAnimValList(), "call from baseVal to animVal");
--- a/content/svg/content/src/DOMSVGPointList.h +++ b/content/svg/content/src/DOMSVGPointList.h @@ -11,18 +11,16 @@ #include "nsCycleCollectionParticipant.h" #include "nsDebug.h" #include "nsSVGElement.h" #include "nsTArray.h" #include "SVGPointList.h" // IWYU pragma: keep #include "mozilla/Attributes.h" #include "mozilla/ErrorResult.h" -class nsIDOMSVGPoint; - namespace mozilla { class DOMSVGPoint; class nsISVGPoint; class SVGAnimatedPointList; /** * Class DOMSVGPointList @@ -47,17 +45,18 @@ class SVGAnimatedPointList; * items are friends of us and responsible for nulling out our pointers to * them when they die. * * Our DOM items are created lazily on demand as and when script requests them. */ class DOMSVGPointList MOZ_FINAL : public nsISupports, public nsWrapperCache { - friend class DOMSVGPoint; + friend class nsISVGPoint; + friend class mozilla::DOMSVGPoint; public: NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMSVGPointList) virtual JSObject* WrapObject(JSContext *cx, JSObject *scope, bool *triedToWrap); @@ -203,28 +202,28 @@ private: * base val and anim val internal lists. This means that anim val lists don't * get const protection, but our setter methods guard against changing * anim val lists. */ SVGPointList& InternalList() const; SVGAnimatedPointList& InternalAList() const; - /// Creates a DOMSVGPoint for aIndex, if it doesn't already exist. + /// Creates an nsISVGPoint for aIndex, if it doesn't already exist. void EnsureItemAt(uint32_t aIndex); void MaybeInsertNullInAnimValListAt(uint32_t aIndex); void MaybeRemoveItemFromAnimValListAt(uint32_t aIndex); - // Weak refs to our DOMSVGPoint items. The items are friends and take care + // Weak refs to our nsISVGPoint items. The items are friends and take care // of clearing our pointer to them when they die. - nsTArray<DOMSVGPoint*> mItems; + nsTArray<nsISVGPoint*> mItems; // Strong ref to our element to keep it alive. We hold this not only for - // ourself, but also for our DOMSVGPoint items too. + // ourself, but also for our nsISVGPoint items too. nsRefPtr<nsSVGElement> mElement; bool mIsAnimValList; }; } // namespace mozilla #endif // MOZILLA_DOMSVGPOINTLIST_H__
--- a/content/svg/content/src/DOMSVGTransform.cpp +++ b/content/svg/content/src/DOMSVGTransform.cpp @@ -22,17 +22,16 @@ static nsSVGAttrTearoffTable<DOMSVGTrans //---------------------------------------------------------------------- // nsISupports methods: // We could use NS_IMPL_CYCLE_COLLECTION_1, except that in Unlink() we need to // clear our list's weak ref to us to be safe. (The other option would be to // not unlink and rely on the breaking of the other edges in the cycle, as // NS_SVG_VAL_IMPL_CYCLE_COLLECTION does.) -NS_IMPL_CYCLE_COLLECTION_CLASS(DOMSVGTransform) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGTransform) // We may not belong to a list, so we must null check tmp->mList. if (tmp->mList) { tmp->mList->mItems[tmp->mListIndex] = nullptr; } NS_IMPL_CYCLE_COLLECTION_UNLINK(mList) NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER NS_IMPL_CYCLE_COLLECTION_UNLINK_END
--- a/content/svg/content/src/DOMSVGTransformList.cpp +++ b/content/svg/content/src/DOMSVGTransformList.cpp @@ -32,17 +32,16 @@ void UpdateListIndicesFromIndex( } // anonymous namespace namespace mozilla { // We could use NS_IMPL_CYCLE_COLLECTION_1, except that in Unlink() we need to // clear our DOMSVGAnimatedTransformList's weak ref to us to be safe. (The other // option would be to not unlink and rely on the breaking of the other edges in // the cycle, as NS_SVG_VAL_IMPL_CYCLE_COLLECTION does.) -NS_IMPL_CYCLE_COLLECTION_CLASS(DOMSVGTransformList) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(DOMSVGTransformList) if (tmp->mAList) { if (tmp->IsAnimValList()) { tmp->mAList->mAnimVal = nullptr; } else { tmp->mAList->mBaseVal = nullptr; } NS_IMPL_CYCLE_COLLECTION_UNLINK(mAList)
--- a/content/svg/content/src/Makefile.in +++ b/content/svg/content/src/Makefile.in @@ -30,16 +30,17 @@ CPPSRCS = \ DOMSVGPoint.cpp \ DOMSVGPointList.cpp \ DOMSVGStringList.cpp \ DOMSVGTests.cpp \ DOMSVGTransform.cpp \ DOMSVGTransformList.cpp \ nsDOMSVGZoomEvent.cpp \ nsDOMSVGEvent.cpp \ + nsISVGPoint.cpp \ nsSVGAngle.cpp \ nsSVGBoolean.cpp \ nsSVGClass.cpp \ nsSVGClipPathElement.cpp \ nsSVGDataParser.cpp \ nsSVGElement.cpp \ nsSVGElementFactory.cpp \ nsSVGEnum.cpp \ @@ -50,23 +51,20 @@ CPPSRCS = \ nsSVGIntegerPair.cpp \ nsSVGLength2.cpp \ nsSVGMarkerElement.cpp \ nsSVGMaskElement.cpp \ nsSVGNumber2.cpp \ nsSVGNumberPair.cpp \ nsSVGPathDataParser.cpp \ nsSVGPathGeometryElement.cpp \ - nsSVGPatternElement.cpp \ nsSVGPolyElement.cpp \ nsSVGString.cpp \ nsSVGRect.cpp \ - nsSVGSymbolElement.cpp \ nsSVGUnknownElement.cpp \ - nsSVGUseElement.cpp \ nsSVGViewBox.cpp \ SVGAElement.cpp \ SVGAltGlyphElement.cpp \ SVGAngle.cpp \ SVGAnimatedAngle.cpp \ SVGAnimatedBoolean.cpp \ SVGAnimatedLengthList.cpp \ SVGAnimatedNumberList.cpp \ @@ -106,40 +104,43 @@ CPPSRCS = \ SVGNumberList.cpp \ SVGNumberListSMILType.cpp \ SVGNumberPairSMILType.cpp \ SVGOrientSMILType.cpp \ SVGPathData.cpp \ SVGPathElement.cpp \ SVGPathSegUtils.cpp \ SVGPathSegListSMILType.cpp \ + SVGPatternElement.cpp \ SVGPointList.cpp \ SVGPointListSMILType.cpp \ SVGPolygonElement.cpp \ SVGPolylineElement.cpp \ SVGPreserveAspectRatio.cpp \ SVGRectElement.cpp \ SVGScriptElement.cpp \ SVGSetElement.cpp \ SVGStopElement.cpp \ SVGStringList.cpp \ SVGStyleElement.cpp \ + SVGSymbolElement.cpp \ SVGSVGElement.cpp \ SVGSwitchElement.cpp \ SVGTextContentElement.cpp \ SVGTextElement.cpp \ SVGTextPathElement.cpp \ SVGTextPositioningElement.cpp \ SVGTitleElement.cpp \ SVGTransform.cpp \ SVGTransformableElement.cpp \ SVGTransformList.cpp \ SVGTransformListParser.cpp \ SVGTransformListSMILType.cpp \ SVGTSpanElement.cpp \ + SVGUseElement.cpp \ SVGViewBoxSMILType.cpp \ SVGViewElement.cpp \ $(NULL) include $(topsrcdir)/config/config.mk # we don't want the shared lib, but we want to force the creation of a static lib. FORCE_STATIC_LIB = 1 @@ -172,32 +173,35 @@ EXPORTS_mozilla/dom = \ SVGGraphicsElement.h \ SVGImageElement.h \ SVGLineElement.h \ SVGLocatableElement.h \ SVGMatrix.h \ SVGMetadataElement.h \ SVGMPathElement.h \ SVGPathElement.h \ + SVGPatternElement.h \ SVGPolygonElement.h \ SVGPolylineElement.h \ SVGRectElement.h \ SVGScriptElement.h \ SVGSetElement.h \ SVGStopElement.h \ SVGStyleElement.h \ + SVGSymbolElement.h \ SVGSVGElement.h \ SVGSwitchElement.h \ SVGTextContentElement.h \ SVGTextElement.h \ SVGTextPathElement.h \ SVGTextPositioningElement.h \ SVGTitleElement.h \ SVGTransformableElement.h \ SVGTSpanElement.h \ + SVGUseElement.h \ SVGViewElement.h \ $(NULL) include $(topsrcdir)/config/rules.mk INCLUDES += \ -I$(srcdir)/../../../xml/content/src \ -I$(srcdir)/../../../../dom \
--- a/content/svg/content/src/SVGAnimationElement.cpp +++ b/content/svg/content/src/SVGAnimationElement.cpp @@ -22,17 +22,16 @@ NS_IMPL_RELEASE_INHERITED(SVGAnimationEl NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SVGAnimationElement) NS_INTERFACE_MAP_ENTRY(nsISMILAnimationElement) NS_INTERFACE_MAP_ENTRY(nsIDOMElementTimeControl) NS_INTERFACE_MAP_ENTRY(nsIDOMSVGTests) NS_INTERFACE_MAP_END_INHERITING(SVGAnimationElementBase) // Cycle collection magic -- based on nsSVGUseElement -NS_IMPL_CYCLE_COLLECTION_CLASS(SVGAnimationElement) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(SVGAnimationElement, SVGAnimationElementBase) tmp->mHrefTarget.Unlink(); tmp->mTimedElement.Unlink(); NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(SVGAnimationElement, SVGAnimationElementBase)
--- a/content/svg/content/src/SVGGraphicsElement.cpp +++ b/content/svg/content/src/SVGGraphicsElement.cpp @@ -4,22 +4,16 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/dom/SVGGraphicsElement.h" #include "mozilla/dom/SVGGraphicsElementBinding.h" namespace mozilla { namespace dom { -JSObject* -SVGGraphicsElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap) -{ - return SVGGraphicsElementBinding::Wrap(aCx, aScope, this, aTriedToWrap); -} - //---------------------------------------------------------------------- // nsISupports methods NS_IMPL_ADDREF_INHERITED(SVGGraphicsElement, SVGGraphicsElementBase) NS_IMPL_RELEASE_INHERITED(SVGGraphicsElement, SVGGraphicsElementBase) NS_INTERFACE_MAP_BEGIN(SVGGraphicsElement) NS_INTERFACE_MAP_ENTRY(nsIDOMSVGTests)
--- a/content/svg/content/src/SVGGraphicsElement.h +++ b/content/svg/content/src/SVGGraphicsElement.h @@ -4,42 +4,28 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_dom_SVGGraphicsElement_h #define mozilla_dom_SVGGraphicsElement_h #include "mozilla/dom/SVGTransformableElement.h" #include "DOMSVGTests.h" -#define MOZILLA_SVGGRAPHICSELEMENT_IID \ - { 0xe57b8fe5, 0x9088, 0x446e, \ - {0xa1, 0x87, 0xd1, 0xdb, 0xbb, 0x58, 0xce, 0xdc}} - namespace mozilla { namespace dom { typedef SVGTransformableElement SVGGraphicsElementBase; class SVGGraphicsElement : public SVGGraphicsElementBase, public DOMSVGTests { protected: SVGGraphicsElement(already_AddRefed<nsINodeInfo> aNodeInfo); public: // interfaces: NS_DECL_ISUPPORTS_INHERITED - NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_SVGGRAPHICSELEMENT_IID) - NS_FORWARD_NSIDOMSVGLOCATABLE(SVGLocatableElement::) - NS_FORWARD_NSIDOMSVGTRANSFORMABLE(SVGTransformableElement::) - -protected: - virtual JSObject* WrapNode(JSContext *cx, JSObject *scope, bool *triedToWrap) MOZ_OVERRIDE; - }; -NS_DEFINE_STATIC_IID_ACCESSOR(SVGGraphicsElement, - MOZILLA_SVGGRAPHICSELEMENT_IID) - } // namespace dom } // namespace mozilla #endif // mozilla_dom_SVGGraphicsElement_h
--- a/content/svg/content/src/SVGLocatableElement.cpp +++ b/content/svg/content/src/SVGLocatableElement.cpp @@ -16,61 +16,34 @@ namespace dom { //---------------------------------------------------------------------- // nsISupports methods NS_IMPL_ADDREF_INHERITED(SVGLocatableElement, nsSVGElement) NS_IMPL_RELEASE_INHERITED(SVGLocatableElement, nsSVGElement) NS_INTERFACE_MAP_BEGIN(SVGLocatableElement) - NS_INTERFACE_MAP_ENTRY(nsIDOMSVGLocatable) + NS_INTERFACE_MAP_ENTRY(mozilla::dom::SVGLocatableElement) NS_INTERFACE_MAP_END_INHERITING(nsSVGElement) //---------------------------------------------------------------------- -// nsIDOMSVGLocatable methods - -/* readonly attribute nsIDOMSVGElement nearestViewportElement; */ -NS_IMETHODIMP -SVGLocatableElement::GetNearestViewportElement(nsIDOMSVGElement * *aNearestViewportElement) -{ - nsCOMPtr<nsIDOMSVGElement> domElem = do_QueryInterface(GetNearestViewportElement()); - domElem.forget(aNearestViewportElement); - return NS_OK; -} nsSVGElement* SVGLocatableElement::GetNearestViewportElement() { return SVGContentUtils::GetNearestViewportElement(this); } -/* readonly attribute nsIDOMSVGElement farthestViewportElement; */ -NS_IMETHODIMP -SVGLocatableElement::GetFarthestViewportElement(nsIDOMSVGElement * *aFarthestViewportElement) -{ - NS_IF_ADDREF(*aFarthestViewportElement = SVGContentUtils::GetOuterSVGElement(this)); - return NS_OK; -} - nsSVGElement* SVGLocatableElement::GetFarthestViewportElement() { return SVGContentUtils::GetOuterSVGElement(this); } -/* nsIDOMSVGRect getBBox (); */ -NS_IMETHODIMP -SVGLocatableElement::GetBBox(nsIDOMSVGRect **_retval) -{ - ErrorResult rv; - *_retval = GetBBox(rv).get(); - return rv.ErrorCode(); -} - already_AddRefed<nsIDOMSVGRect> SVGLocatableElement::GetBBox(ErrorResult& rv) { nsIFrame* frame = GetPrimaryFrame(Flush_Layout); if (!frame || (frame->GetStateBits() & NS_STATE_SVG_NONDISPLAY_CHILD)) { rv.Throw(NS_ERROR_FAILURE); return nullptr; @@ -82,75 +55,39 @@ SVGLocatableElement::GetBBox(ErrorResult return nullptr; } nsCOMPtr<nsIDOMSVGRect> rect; rv = NS_NewSVGRect(getter_AddRefs(rect), nsSVGUtils::GetBBox(frame)); return rect.forget(); } -/* SVGMatrix getCTM (); */ -NS_IMETHODIMP -SVGLocatableElement::GetCTM(nsISupports * *aCTM) -{ - *aCTM = GetCTM().get(); - return NS_OK; -} - already_AddRefed<SVGMatrix> SVGLocatableElement::GetCTM() { gfxMatrix m = SVGContentUtils::GetCTM(this, false); nsCOMPtr<SVGMatrix> mat = m.IsSingular() ? nullptr : new SVGMatrix(m); return mat.forget(); } -/* SVGMatrix getScreenCTM (); */ -NS_IMETHODIMP -SVGLocatableElement::GetScreenCTM(nsISupports * *aCTM) -{ - *aCTM = GetScreenCTM().get(); - return NS_OK; -} - already_AddRefed<SVGMatrix> SVGLocatableElement::GetScreenCTM() { gfxMatrix m = SVGContentUtils::GetCTM(this, true); nsCOMPtr<SVGMatrix> mat = m.IsSingular() ? nullptr : new SVGMatrix(m); return mat.forget(); } -/* SVGMatrix getTransformToElement (in nsIDOMSVGElement element); */ -NS_IMETHODIMP -SVGLocatableElement::GetTransformToElement(nsIDOMSVGElement *element, - nsISupports **_retval) -{ - nsCOMPtr<nsSVGElement> elem = do_QueryInterface(element); - if (!elem) - return NS_ERROR_DOM_SVG_WRONG_TYPE_ERR; - ErrorResult rv; - *_retval = GetTransformToElement(*elem, rv).get(); - return rv.ErrorCode(); -} - already_AddRefed<SVGMatrix> -SVGLocatableElement::GetTransformToElement(nsSVGElement& aElement, +SVGLocatableElement::GetTransformToElement(SVGLocatableElement& aElement, ErrorResult& rv) { - nsCOMPtr<nsIDOMSVGLocatable> target = do_QueryInterface(&aElement); - if (!target) { - rv.Throw(NS_NOINTERFACE); - return nullptr; - } - // the easiest way to do this (if likely to increase rounding error): nsCOMPtr<SVGMatrix> ourScreenCTM = GetScreenCTM(); - nsCOMPtr<SVGMatrix> targetScreenCTM; - target->GetScreenCTM(getter_AddRefs(targetScreenCTM)); + nsCOMPtr<SVGMatrix> targetScreenCTM = aElement.GetScreenCTM(); if (!ourScreenCTM || !targetScreenCTM) { rv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR); return nullptr; } nsCOMPtr<SVGMatrix> tmp = targetScreenCTM->Inverse(rv); if (rv.Failed()) return nullptr; nsCOMPtr<SVGMatrix> mat = tmp->Multiply(*ourScreenCTM).get();
--- a/content/svg/content/src/SVGLocatableElement.h +++ b/content/svg/content/src/SVGLocatableElement.h @@ -2,46 +2,45 @@ /* 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/. */ #ifndef SVGLocatableElement_h #define SVGLocatableElement_h #include "nsSVGElement.h" -#include "nsIDOMSVGLocatable.h" #define MOZILLA_SVGLOCATABLEELEMENT_IID \ { 0xe20176ba, 0xc48d, 0x4704, \ {0x89, 0xec, 0xe6, 0x69, 0x6c, 0xb7, 0xb8, 0xb3} } +class nsIDOMSVGRect; + namespace mozilla { namespace dom { class SVGMatrix; -class SVGLocatableElement : public nsSVGElement, - public nsIDOMSVGLocatable +class SVGLocatableElement : public nsSVGElement { public: SVGLocatableElement(already_AddRefed<nsINodeInfo> aNodeInfo) : nsSVGElement(aNodeInfo) {} virtual ~SVGLocatableElement() {} NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_SVGLOCATABLEELEMENT_IID) NS_DECL_ISUPPORTS_INHERITED - NS_DECL_NSIDOMSVGLOCATABLE // WebIDL nsSVGElement* GetNearestViewportElement(); nsSVGElement* GetFarthestViewportElement(); already_AddRefed<nsIDOMSVGRect> GetBBox(ErrorResult& rv); already_AddRefed<SVGMatrix> GetCTM(); already_AddRefed<SVGMatrix> GetScreenCTM(); - already_AddRefed<SVGMatrix> GetTransformToElement(nsSVGElement& aElement, + already_AddRefed<SVGMatrix> GetTransformToElement(SVGLocatableElement& aElement, ErrorResult& rv); }; NS_DEFINE_STATIC_IID_ACCESSOR(SVGLocatableElement, MOZILLA_SVGLOCATABLEELEMENT_IID) } // namespace dom } // namespace mozilla
--- a/content/svg/content/src/SVGMPathElement.cpp +++ b/content/svg/content/src/SVGMPathElement.cpp @@ -27,17 +27,16 @@ SVGMPathElement::WrapNode(JSContext *aCx } nsSVGElement::StringInfo SVGMPathElement::sStringInfo[1] = { { &nsGkAtoms::href, kNameSpaceID_XLink, false } }; // Cycle collection magic -- based on nsSVGUseElement -NS_IMPL_CYCLE_COLLECTION_CLASS(SVGMPathElement) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(SVGMPathElement, SVGMPathElementBase) tmp->UnlinkHrefTarget(false); NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(SVGMPathElement, SVGMPathElementBase) tmp->mHrefTarget.Traverse(&cb);
--- a/content/svg/content/src/SVGMatrix.cpp +++ b/content/svg/content/src/SVGMatrix.cpp @@ -13,30 +13,17 @@ const double radPerDegree = 2.0 * M_PI / 360.0; namespace mozilla { namespace dom { //---------------------------------------------------------------------- // nsISupports methods: -NS_IMPL_CYCLE_COLLECTION_CLASS(SVGMatrix) -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(SVGMatrix) -NS_IMPL_CYCLE_COLLECTION_UNLINK(mTransform) -NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER -NS_IMPL_CYCLE_COLLECTION_UNLINK_END - -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(SVGMatrix) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTransform) -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END - -NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(SVGMatrix) -NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER -NS_IMPL_CYCLE_COLLECTION_TRACE_END + NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(SVGMatrix, mTransform) NS_IMPL_CYCLE_COLLECTING_ADDREF(SVGMatrix) NS_IMPL_CYCLE_COLLECTING_RELEASE(SVGMatrix) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(SVGMatrix) NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY NS_INTERFACE_MAP_ENTRY(mozilla::dom::SVGMatrix) // pseudo-interface NS_INTERFACE_MAP_ENTRY(nsISupports)
--- a/content/svg/content/src/SVGPathElement.cpp +++ b/content/svg/content/src/SVGPathElement.cpp @@ -9,302 +9,490 @@ #include "DOMSVGPathSeg.h" #include "DOMSVGPathSegList.h" #include "nsCOMPtr.h" #include "nsContentUtils.h" #include "mozilla/dom/SVGPathElement.h" #include "DOMSVGPoint.h" #include "gfxContext.h" #include <algorithm> +#include "mozilla/dom/SVGPathElementBinding.h" DOMCI_NODE_DATA(SVGPathElement, mozilla::dom::SVGPathElement) NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(Path) namespace mozilla { namespace dom { +JSObject* +SVGPathElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap) +{ + return SVGPathElementBinding::Wrap(aCx, aScope, this, aTriedToWrap); +} + nsSVGElement::NumberInfo SVGPathElement::sNumberInfo = { &nsGkAtoms::pathLength, 0, false }; //---------------------------------------------------------------------- // nsISupports methods NS_IMPL_ADDREF_INHERITED(SVGPathElement,SVGPathElementBase) NS_IMPL_RELEASE_INHERITED(SVGPathElement,SVGPathElementBase) NS_INTERFACE_TABLE_HEAD(SVGPathElement) - NS_NODE_INTERFACE_TABLE5(SVGPathElement, nsIDOMNode, nsIDOMElement, + NS_NODE_INTERFACE_TABLE4(SVGPathElement, nsIDOMNode, nsIDOMElement, nsIDOMSVGElement, - nsIDOMSVGPathElement, nsIDOMSVGAnimatedPathData) + nsIDOMSVGPathElement) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGPathElement) NS_INTERFACE_MAP_END_INHERITING(SVGPathElementBase) //---------------------------------------------------------------------- // Implementation SVGPathElement::SVGPathElement(already_AddRefed<nsINodeInfo> aNodeInfo) : SVGPathElementBase(aNodeInfo) { + SetIsDOMBinding(); } //---------------------------------------------------------------------- // nsIDOMNode methods NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGPathElement) //---------------------------------------------------------------------- // nsIDOMSVGPathElement methods: /* readonly attribute nsIDOMSVGAnimatedNumber pathLength; */ NS_IMETHODIMP SVGPathElement::GetPathLength(nsIDOMSVGAnimatedNumber * *aPathLength) { - return mPathLength.ToDOMAnimatedNumber(aPathLength, this); + *aPathLength = PathLength().get(); + return NS_OK; +} + +already_AddRefed<nsIDOMSVGAnimatedNumber> +SVGPathElement::PathLength() +{ + nsCOMPtr<nsIDOMSVGAnimatedNumber> number; + mPathLength.ToDOMAnimatedNumber(getter_AddRefs(number), this); + return number.forget(); } /* float getTotalLength (); */ NS_IMETHODIMP SVGPathElement::GetTotalLength(float *_retval) { - *_retval = 0; + ErrorResult rv; + *_retval = GetTotalLength(rv); + return rv.ErrorCode(); +} +float +SVGPathElement::GetTotalLength(ErrorResult& rv) +{ nsRefPtr<gfxFlattenedPath> flat = GetFlattenedPath(gfxMatrix()); - if (!flat) - return NS_ERROR_FAILURE; + if (!flat) { + rv.Throw(NS_ERROR_FAILURE); + return 0.f; + } - *_retval = flat->GetLength(); - - return NS_OK; + return flat->GetLength(); } /* DOMSVGPoint getPointAtLength (in float distance); */ NS_IMETHODIMP SVGPathElement::GetPointAtLength(float distance, nsISupports **_retval) { NS_ENSURE_FINITE(distance, NS_ERROR_ILLEGAL_VALUE); + ErrorResult rv; + *_retval = GetPointAtLength(distance, rv).get(); + return rv.ErrorCode(); +} + +already_AddRefed<nsISVGPoint> +SVGPathElement::GetPointAtLength(float distance, ErrorResult& rv) +{ nsRefPtr<gfxFlattenedPath> flat = GetFlattenedPath(gfxMatrix()); - if (!flat) - return NS_ERROR_FAILURE; + if (!flat) { + rv.Throw(NS_ERROR_FAILURE); + return nullptr; + } float totalLength = flat->GetLength(); if (mPathLength.IsExplicitlySet()) { float pathLength = mPathLength.GetAnimValue(); if (pathLength <= 0) { - return NS_ERROR_FAILURE; + rv.Throw(NS_ERROR_FAILURE); + return nullptr; } distance *= totalLength / pathLength; } distance = std::max(0.f, distance); distance = std::min(totalLength, distance); - NS_ADDREF(*_retval = new DOMSVGPoint(flat->FindPoint(gfxPoint(distance, 0)))); - return NS_OK; + nsCOMPtr<nsISVGPoint> point = new DOMSVGPoint(flat->FindPoint(gfxPoint(distance, 0))); + return point.forget(); } /* unsigned long getPathSegAtLength (in float distance); */ NS_IMETHODIMP SVGPathElement::GetPathSegAtLength(float distance, uint32_t *_retval) { NS_ENSURE_FINITE(distance, NS_ERROR_ILLEGAL_VALUE); - *_retval = mD.GetAnimValue().GetPathSegAtLength(distance); + *_retval = GetPathSegAtLength(distance); return NS_OK; } +uint32_t +SVGPathElement::GetPathSegAtLength(float distance) +{ + return mD.GetAnimValue().GetPathSegAtLength(distance); +} + /* nsISupports createSVGPathSegClosePath (); */ NS_IMETHODIMP SVGPathElement::CreateSVGPathSegClosePath(nsISupports **_retval) { - nsISupports* seg = NS_NewSVGPathSegClosePath(); - NS_ENSURE_TRUE(seg, NS_ERROR_OUT_OF_MEMORY); - return CallQueryInterface(seg, _retval); + *_retval = CreateSVGPathSegClosePath().get(); + return NS_OK; +} + +already_AddRefed<DOMSVGPathSegClosePath> +SVGPathElement::CreateSVGPathSegClosePath() +{ + nsRefPtr<DOMSVGPathSegClosePath> pathSeg = new DOMSVGPathSegClosePath(); + return pathSeg.forget(); } /* nsISupports createSVGPathSegMovetoAbs (in float x, in float y); */ NS_IMETHODIMP SVGPathElement::CreateSVGPathSegMovetoAbs(float x, float y, nsISupports **_retval) { NS_ENSURE_FINITE2(x, y, NS_ERROR_ILLEGAL_VALUE); - nsISupports* seg = NS_NewSVGPathSegMovetoAbs(x, y); - NS_ENSURE_TRUE(seg, NS_ERROR_OUT_OF_MEMORY); - return CallQueryInterface(seg, _retval); + *_retval = CreateSVGPathSegMovetoAbs(x, y).get(); + return NS_OK; +} + +already_AddRefed<DOMSVGPathSegMovetoAbs> +SVGPathElement::CreateSVGPathSegMovetoAbs(float x, float y) +{ + nsRefPtr<DOMSVGPathSegMovetoAbs> pathSeg = new DOMSVGPathSegMovetoAbs(x, y); + return pathSeg.forget(); } /* nsISupports createSVGPathSegMovetoRel (in float x, in float y); */ NS_IMETHODIMP SVGPathElement::CreateSVGPathSegMovetoRel(float x, float y, nsISupports **_retval) { NS_ENSURE_FINITE2(x, y, NS_ERROR_ILLEGAL_VALUE); - nsISupports* seg = NS_NewSVGPathSegMovetoRel(x, y); - NS_ENSURE_TRUE(seg, NS_ERROR_OUT_OF_MEMORY); - return CallQueryInterface(seg, _retval); + *_retval = CreateSVGPathSegMovetoRel(x, y).get(); + return NS_OK; +} + +already_AddRefed<DOMSVGPathSegMovetoRel> +SVGPathElement::CreateSVGPathSegMovetoRel(float x, float y) +{ + nsRefPtr<DOMSVGPathSegMovetoRel> pathSeg = new DOMSVGPathSegMovetoRel(x, y); + return pathSeg.forget(); } /* nsISupports createSVGPathSegLinetoAbs (in float x, in float y); */ NS_IMETHODIMP SVGPathElement::CreateSVGPathSegLinetoAbs(float x, float y, nsISupports **_retval) { NS_ENSURE_FINITE2(x, y, NS_ERROR_ILLEGAL_VALUE); - nsISupports* seg = NS_NewSVGPathSegLinetoAbs(x, y); - NS_ENSURE_TRUE(seg, NS_ERROR_OUT_OF_MEMORY); - return CallQueryInterface(seg, _retval); + *_retval = CreateSVGPathSegLinetoAbs(x, y).get(); + return NS_OK; +} + +already_AddRefed<DOMSVGPathSegLinetoAbs> +SVGPathElement::CreateSVGPathSegLinetoAbs(float x, float y) +{ + nsRefPtr<DOMSVGPathSegLinetoAbs> pathSeg = new DOMSVGPathSegLinetoAbs(x, y); + return pathSeg.forget(); } /* nsISupports createSVGPathSegLinetoRel (in float x, in float y); */ NS_IMETHODIMP SVGPathElement::CreateSVGPathSegLinetoRel(float x, float y, nsISupports **_retval) { NS_ENSURE_FINITE2(x, y, NS_ERROR_ILLEGAL_VALUE); - nsISupports* seg = NS_NewSVGPathSegLinetoRel(x, y); - NS_ENSURE_TRUE(seg, NS_ERROR_OUT_OF_MEMORY); - return CallQueryInterface(seg, _retval); + *_retval = CreateSVGPathSegLinetoRel(x, y).get(); + return NS_OK; +} + +already_AddRefed<DOMSVGPathSegLinetoRel> +SVGPathElement::CreateSVGPathSegLinetoRel(float x, float y) +{ + nsRefPtr<DOMSVGPathSegLinetoRel> pathSeg = new DOMSVGPathSegLinetoRel(x, y); + return pathSeg.forget(); } /* nsISupports createSVGPathSegCurvetoCubicAbs (in float x, in float y, in float x1, in float y1, in float x2, in float y2); */ NS_IMETHODIMP SVGPathElement::CreateSVGPathSegCurvetoCubicAbs(float x, float y, float x1, float y1, float x2, float y2, nsISupports **_retval) { NS_ENSURE_FINITE6(x, y, x1, y1, x2, y2, NS_ERROR_ILLEGAL_VALUE); - nsISupports* seg = NS_NewSVGPathSegCurvetoCubicAbs(x, y, x1, y1, x2, y2); - NS_ENSURE_TRUE(seg, NS_ERROR_OUT_OF_MEMORY); - return CallQueryInterface(seg, _retval); + *_retval = CreateSVGPathSegCurvetoCubicAbs(x, y, x1, y1, x2, y2).get(); + return NS_OK; +} + +already_AddRefed<DOMSVGPathSegCurvetoCubicAbs> +SVGPathElement::CreateSVGPathSegCurvetoCubicAbs(float x, float y, float x1, float y1, float x2, float y2) +{ + // Note that we swap from DOM API argument order to the argument order used + // in the <path> element's 'd' attribute (i.e. we put the arguments for the + // end point of the segment last instead of first). + nsRefPtr<DOMSVGPathSegCurvetoCubicAbs> pathSeg = + new DOMSVGPathSegCurvetoCubicAbs(x1, y1, x2, y2, x, y); + return pathSeg.forget(); } /* nsISupports createSVGPathSegCurvetoCubicRel (in float x, in float y, in float x1, in float y1, in float x2, in float y2); */ NS_IMETHODIMP SVGPathElement::CreateSVGPathSegCurvetoCubicRel(float x, float y, float x1, float y1, float x2, float y2, nsISupports **_retval) { NS_ENSURE_FINITE6(x, y, x1, y1, x2, y2, NS_ERROR_ILLEGAL_VALUE); - nsISupports* seg = NS_NewSVGPathSegCurvetoCubicRel(x, y, x1, y1, x2, y2); - NS_ENSURE_TRUE(seg, NS_ERROR_OUT_OF_MEMORY); - return CallQueryInterface(seg, _retval); + *_retval = CreateSVGPathSegCurvetoCubicRel(x, y, x1, y1, x2, y2).get(); + return NS_OK; +} + +already_AddRefed<DOMSVGPathSegCurvetoCubicRel> +SVGPathElement::CreateSVGPathSegCurvetoCubicRel(float x, float y, float x1, float y1, float x2, float y2) +{ + // See comment in CreateSVGPathSegCurvetoCubicAbs + nsRefPtr<DOMSVGPathSegCurvetoCubicRel> pathSeg = + new DOMSVGPathSegCurvetoCubicRel(x1, y1, x2, y2, x, y); + return pathSeg.forget(); } /* nsISupports createSVGPathSegCurvetoQuadraticAbs (in float x, in float y, in float x1, in float y1); */ NS_IMETHODIMP SVGPathElement::CreateSVGPathSegCurvetoQuadraticAbs(float x, float y, float x1, float y1, nsISupports **_retval) { NS_ENSURE_FINITE4(x, y, x1, y1, NS_ERROR_ILLEGAL_VALUE); - nsISupports* seg = NS_NewSVGPathSegCurvetoQuadraticAbs(x, y, x1, y1); - NS_ENSURE_TRUE(seg, NS_ERROR_OUT_OF_MEMORY); - return CallQueryInterface(seg, _retval); + *_retval = CreateSVGPathSegCurvetoQuadraticAbs(x, y, x1, y1).get(); + return NS_OK; +} + +already_AddRefed<DOMSVGPathSegCurvetoQuadraticAbs> +SVGPathElement::CreateSVGPathSegCurvetoQuadraticAbs(float x, float y, float x1, float y1) +{ + // See comment in CreateSVGPathSegCurvetoCubicAbs + nsRefPtr<DOMSVGPathSegCurvetoQuadraticAbs> pathSeg = + new DOMSVGPathSegCurvetoQuadraticAbs(x1, y1, x, y); + return pathSeg.forget(); } /* nsISupports createSVGPathSegCurvetoQuadraticRel (in float x, in float y, in float x1, in float y1); */ NS_IMETHODIMP SVGPathElement::CreateSVGPathSegCurvetoQuadraticRel(float x, float y, float x1, float y1, nsISupports **_retval) { NS_ENSURE_FINITE4(x, y, x1, y1, NS_ERROR_ILLEGAL_VALUE); - nsISupports* seg = NS_NewSVGPathSegCurvetoQuadraticRel(x, y, x1, y1); - NS_ENSURE_TRUE(seg, NS_ERROR_OUT_OF_MEMORY); - return CallQueryInterface(seg, _retval); + *_retval = CreateSVGPathSegCurvetoQuadraticRel(x, y, x1, y1).get(); + return NS_OK; +} + +already_AddRefed<DOMSVGPathSegCurvetoQuadraticRel> +SVGPathElement::CreateSVGPathSegCurvetoQuadraticRel(float x, float y, float x1, float y1) +{ + // See comment in CreateSVGPathSegCurvetoCubicAbs + nsRefPtr<DOMSVGPathSegCurvetoQuadraticRel> pathSeg = + new DOMSVGPathSegCurvetoQuadraticRel(x1, y1, x, y); + return pathSeg.forget(); } /* nsISupports createSVGPathSegArcAbs (in float x, in float y, in float r1, in float r2, in float angle, in boolean largeArcFlag, in boolean sweepFlag); */ NS_IMETHODIMP SVGPathElement::CreateSVGPathSegArcAbs(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, nsISupports **_retval) { NS_ENSURE_FINITE5(x, y, r1, r2, angle, NS_ERROR_ILLEGAL_VALUE); - nsISupports* seg = NS_NewSVGPathSegArcAbs(x, y, r1, r2, angle, - largeArcFlag, sweepFlag); - NS_ENSURE_TRUE(seg, NS_ERROR_OUT_OF_MEMORY); - return CallQueryInterface(seg, _retval); + *_retval = CreateSVGPathSegArcAbs(x, y, r1, r2, angle, largeArcFlag, sweepFlag).get(); + return NS_OK; +} + +already_AddRefed<DOMSVGPathSegArcAbs> +SVGPathElement::CreateSVGPathSegArcAbs(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag) +{ + // See comment in CreateSVGPathSegCurvetoCubicAbs + nsRefPtr<DOMSVGPathSegArcAbs> pathSeg = + new DOMSVGPathSegArcAbs(r1, r2, angle, largeArcFlag, sweepFlag, x, y); + return pathSeg.forget(); } /* nsISupports createSVGPathSegArcRel (in float x, in float y, in float r1, in float r2, in float angle, in boolean largeArcFlag, in boolean sweepFlag); */ NS_IMETHODIMP SVGPathElement::CreateSVGPathSegArcRel(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, nsISupports **_retval) { NS_ENSURE_FINITE5(x, y, r1, r2, angle, NS_ERROR_ILLEGAL_VALUE); - nsISupports* seg = NS_NewSVGPathSegArcRel(x, y, r1, r2, angle, - largeArcFlag, sweepFlag); - NS_ENSURE_TRUE(seg, NS_ERROR_OUT_OF_MEMORY); - return CallQueryInterface(seg, _retval); + *_retval = CreateSVGPathSegArcRel(x, y, r1, r2, angle, largeArcFlag, sweepFlag).get(); + return NS_OK; +} + +already_AddRefed<DOMSVGPathSegArcRel> +SVGPathElement::CreateSVGPathSegArcRel(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag) +{ + // See comment in CreateSVGPathSegCurvetoCubicAbs + nsRefPtr<DOMSVGPathSegArcRel> pathSeg = + new DOMSVGPathSegArcRel(r1, r2, angle, largeArcFlag, sweepFlag, x, y); + return pathSeg.forget(); } /* nsISupports createSVGPathSegLinetoHorizontalAbs (in float x); */ NS_IMETHODIMP SVGPathElement::CreateSVGPathSegLinetoHorizontalAbs(float x, nsISupports **_retval) { NS_ENSURE_FINITE(x, NS_ERROR_ILLEGAL_VALUE); - nsISupports* seg = NS_NewSVGPathSegLinetoHorizontalAbs(x); - NS_ENSURE_TRUE(seg, NS_ERROR_OUT_OF_MEMORY); - return CallQueryInterface(seg, _retval); + *_retval = CreateSVGPathSegLinetoHorizontalAbs(x).get(); + return NS_OK; +} + +already_AddRefed<DOMSVGPathSegLinetoHorizontalAbs> +SVGPathElement::CreateSVGPathSegLinetoHorizontalAbs(float x) +{ + nsRefPtr<DOMSVGPathSegLinetoHorizontalAbs> pathSeg = + new DOMSVGPathSegLinetoHorizontalAbs(x); + return pathSeg.forget(); } /* nsISupports createSVGPathSegLinetoHorizontalRel (in float x); */ NS_IMETHODIMP SVGPathElement::CreateSVGPathSegLinetoHorizontalRel(float x, nsISupports **_retval) { NS_ENSURE_FINITE(x, NS_ERROR_ILLEGAL_VALUE); - nsISupports* seg = NS_NewSVGPathSegLinetoHorizontalRel(x); - NS_ENSURE_TRUE(seg, NS_ERROR_OUT_OF_MEMORY); - return CallQueryInterface(seg, _retval); + *_retval = CreateSVGPathSegLinetoHorizontalRel(x).get(); + return NS_OK; +} + +already_AddRefed<DOMSVGPathSegLinetoHorizontalRel> +SVGPathElement::CreateSVGPathSegLinetoHorizontalRel(float x) +{ + nsRefPtr<DOMSVGPathSegLinetoHorizontalRel> pathSeg = + new DOMSVGPathSegLinetoHorizontalRel(x); + return pathSeg.forget(); } /* nsISupports createSVGPathSegLinetoVerticalAbs (in float y); */ NS_IMETHODIMP SVGPathElement::CreateSVGPathSegLinetoVerticalAbs(float y, nsISupports **_retval) { NS_ENSURE_FINITE(y, NS_ERROR_ILLEGAL_VALUE); - nsISupports* seg = NS_NewSVGPathSegLinetoVerticalAbs(y); - NS_ENSURE_TRUE(seg, NS_ERROR_OUT_OF_MEMORY); - return CallQueryInterface(seg, _retval); + *_retval = CreateSVGPathSegLinetoVerticalAbs(y).get(); + return NS_OK; +} + +already_AddRefed<DOMSVGPathSegLinetoVerticalAbs> +SVGPathElement::CreateSVGPathSegLinetoVerticalAbs(float y) +{ + nsRefPtr<DOMSVGPathSegLinetoVerticalAbs> pathSeg = + new DOMSVGPathSegLinetoVerticalAbs(y); + return pathSeg.forget(); } /* nsISupports createSVGPathSegLinetoVerticalRel (in float y); */ NS_IMETHODIMP SVGPathElement::CreateSVGPathSegLinetoVerticalRel(float y, nsISupports **_retval) { NS_ENSURE_FINITE(y, NS_ERROR_ILLEGAL_VALUE); - nsISupports* seg = NS_NewSVGPathSegLinetoVerticalRel(y); - NS_ENSURE_TRUE(seg, NS_ERROR_OUT_OF_MEMORY); - return CallQueryInterface(seg, _retval); + *_retval = CreateSVGPathSegLinetoVerticalRel(y).get(); + return NS_OK; +} + +already_AddRefed<DOMSVGPathSegLinetoVerticalRel> +SVGPathElement::CreateSVGPathSegLinetoVerticalRel(float y) +{ + nsRefPtr<DOMSVGPathSegLinetoVerticalRel> pathSeg = + new DOMSVGPathSegLinetoVerticalRel(y); + return pathSeg.forget(); } /* nsISupports createSVGPathSegCurvetoCubicSmoothAbs (in float x, in float y, in float x2, in float y2); */ NS_IMETHODIMP SVGPathElement::CreateSVGPathSegCurvetoCubicSmoothAbs(float x, float y, float x2, float y2, nsISupports **_retval) { NS_ENSURE_FINITE4(x, y, x2, y2, NS_ERROR_ILLEGAL_VALUE); - nsISupports* seg = NS_NewSVGPathSegCurvetoCubicSmoothAbs(x, y, x2, y2); - NS_ENSURE_TRUE(seg, NS_ERROR_OUT_OF_MEMORY); - return CallQueryInterface(seg, _retval); + *_retval = CreateSVGPathSegCurvetoCubicSmoothAbs(x, y, x2, y2).get(); + return NS_OK; +} + +already_AddRefed<DOMSVGPathSegCurvetoCubicSmoothAbs> +SVGPathElement::CreateSVGPathSegCurvetoCubicSmoothAbs(float x, float y, float x2, float y2) +{ + // See comment in CreateSVGPathSegCurvetoCubicAbs + nsRefPtr<DOMSVGPathSegCurvetoCubicSmoothAbs> pathSeg = + new DOMSVGPathSegCurvetoCubicSmoothAbs(x2, y2, x, y); + return pathSeg.forget(); } /* nsISupports createSVGPathSegCurvetoCubicSmoothRel (in float x, in float y, in float x2, in float y2); */ NS_IMETHODIMP SVGPathElement::CreateSVGPathSegCurvetoCubicSmoothRel(float x, float y, float x2, float y2, nsISupports **_retval) { NS_ENSURE_FINITE4(x, y, x2, y2, NS_ERROR_ILLEGAL_VALUE); - nsISupports* seg = NS_NewSVGPathSegCurvetoCubicSmoothRel(x, y, x2, y2); - NS_ENSURE_TRUE(seg, NS_ERROR_OUT_OF_MEMORY); - return CallQueryInterface(seg, _retval); + *_retval = CreateSVGPathSegCurvetoCubicSmoothRel(x, y, x2, y2).get(); + return NS_OK; +} + +already_AddRefed<DOMSVGPathSegCurvetoCubicSmoothRel> +SVGPathElement::CreateSVGPathSegCurvetoCubicSmoothRel(float x, float y, float x2, float y2) +{ + // See comment in CreateSVGPathSegCurvetoCubicAbs + nsRefPtr<DOMSVGPathSegCurvetoCubicSmoothRel> pathSeg = + new DOMSVGPathSegCurvetoCubicSmoothRel(x2, y2, x, y); + return pathSeg.forget(); } /* nsISupports createSVGPathSegCurvetoQuadraticSmoothAbs (in float x, in float y); */ NS_IMETHODIMP SVGPathElement::CreateSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y, nsISupports **_retval) { NS_ENSURE_FINITE2(x, y, NS_ERROR_ILLEGAL_VALUE); - nsISupports* seg = NS_NewSVGPathSegCurvetoQuadraticSmoothAbs(x, y); - NS_ENSURE_TRUE(seg, NS_ERROR_OUT_OF_MEMORY); - return CallQueryInterface(seg, _retval); + *_retval = CreateSVGPathSegCurvetoQuadraticSmoothAbs(x, y).get(); + return NS_OK; +} + +already_AddRefed<DOMSVGPathSegCurvetoQuadraticSmoothAbs> +SVGPathElement::CreateSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y) +{ + nsRefPtr<DOMSVGPathSegCurvetoQuadraticSmoothAbs> pathSeg = + new DOMSVGPathSegCurvetoQuadraticSmoothAbs(x, y); + return pathSeg.forget(); } /* nsISupports createSVGPathSegCurvetoQuadraticSmoothRel (in float x, in float y); */ NS_IMETHODIMP SVGPathElement::CreateSVGPathSegCurvetoQuadraticSmoothRel(float x, float y, nsISupports **_retval) { NS_ENSURE_FINITE2(x, y, NS_ERROR_ILLEGAL_VALUE); - nsISupports* seg = NS_NewSVGPathSegCurvetoQuadraticSmoothRel(x, y); - NS_ENSURE_TRUE(seg, NS_ERROR_OUT_OF_MEMORY); - return CallQueryInterface(seg, _retval); + *_retval = CreateSVGPathSegCurvetoQuadraticSmoothRel(x, y).get(); + return NS_OK; +} + +already_AddRefed<DOMSVGPathSegCurvetoQuadraticSmoothRel> +SVGPathElement::CreateSVGPathSegCurvetoQuadraticSmoothRel(float x, float y) +{ + nsRefPtr<DOMSVGPathSegCurvetoQuadraticSmoothRel> pathSeg = + new DOMSVGPathSegCurvetoQuadraticSmoothRel(x, y); + return pathSeg.forget(); +} + +already_AddRefed<DOMSVGPathSegList> +SVGPathElement::PathSegList() +{ + return DOMSVGPathSegList::GetDOMWrapper(mD.GetBaseValKey(), this, false); +} + +already_AddRefed<DOMSVGPathSegList> +SVGPathElement::AnimatedPathSegList() +{ + return DOMSVGPathSegList::GetDOMWrapper(mD.GetAnimValKey(), this, true); } //---------------------------------------------------------------------- // nsSVGElement methods /* virtual */ bool SVGPathElement::HasValidDimensions() const { @@ -313,36 +501,16 @@ SVGPathElement::HasValidDimensions() con nsSVGElement::NumberAttributesInfo SVGPathElement::GetNumberInfo() { return NumberAttributesInfo(&mPathLength, &sNumberInfo, 1); } //---------------------------------------------------------------------- -// nsIDOMSVGAnimatedPathData methods: - -/* readonly attribute DOMSVGPathSegList pathSegList; */ -NS_IMETHODIMP SVGPathElement::GetPathSegList(nsISupports * *aPathSegList) -{ - void *key = mD.GetBaseValKey(); - *aPathSegList = DOMSVGPathSegList::GetDOMWrapper(key, this, false).get(); - return *aPathSegList ? NS_OK : NS_ERROR_OUT_OF_MEMORY; -} - -/* readonly attribute DOMSVGPathSegList animatedPathSegList; */ -NS_IMETHODIMP SVGPathElement::GetAnimatedPathSegList(nsISupports * *aAnimatedPathSegList) -{ - void *key = mD.GetAnimValKey(); - *aAnimatedPathSegList = - DOMSVGPathSegList::GetDOMWrapper(key, this, true).get(); - return *aAnimatedPathSegList ? NS_OK : NS_ERROR_OUT_OF_MEMORY; -} - -//---------------------------------------------------------------------- // nsIContent methods NS_IMETHODIMP_(bool) SVGPathElement::IsAttributeMapped(const nsIAtom* name) const { static const MappedAttributeEntry* const map[] = { sMarkersMap };
--- a/content/svg/content/src/SVGPathElement.h +++ b/content/svg/content/src/SVGPathElement.h @@ -1,50 +1,52 @@ /* -*- Mode: C++; 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/. */ #ifndef mozilla_dom_SVGPathElement_h #define mozilla_dom_SVGPathElement_h -#include "nsIDOMSVGAnimatedPathData.h" #include "nsIDOMSVGPathElement.h" #include "nsSVGNumber2.h" #include "nsSVGPathGeometryElement.h" #include "SVGAnimatedPathSegList.h" +#include "DOMSVGPathSeg.h" nsresult NS_NewSVGPathElement(nsIContent **aResult, already_AddRefed<nsINodeInfo> aNodeInfo); class gfxContext; typedef nsSVGPathGeometryElement SVGPathElementBase; namespace mozilla { + +class nsISVGPoint; + namespace dom { class SVGPathElement MOZ_FINAL : public SVGPathElementBase, - public nsIDOMSVGPathElement, - public nsIDOMSVGAnimatedPathData + public nsIDOMSVGPathElement { friend class nsSVGPathFrame; protected: friend nsresult (::NS_NewSVGPathElement(nsIContent **aResult, already_AddRefed<nsINodeInfo> aNodeInfo)); + virtual JSObject* WrapNode(JSContext *cx, JSObject *scope, bool *triedToWrap) MOZ_OVERRIDE; SVGPathElement(already_AddRefed<nsINodeInfo> aNodeInfo); public: typedef SVGAnimatedPathSegList SVGAnimatedPathSegList; // interfaces: NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIDOMSVGPATHELEMENT - NS_DECL_NSIDOMSVGANIMATEDPATHDATA // xxx I wish we could use virtual inheritance NS_FORWARD_NSIDOMNODE_TO_NSINODE NS_FORWARD_NSIDOMELEMENT_TO_GENERIC NS_FORWARD_NSIDOMSVGELEMENT(SVGPathElementBase::) // nsIContent interface NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const; @@ -82,16 +84,53 @@ public: /** * Gets the ratio of the actual path length to the content author's estimated * length (as provided by the <path> element's 'pathLength' attribute). This * is used to scale stroke dashing, and to scale offsets along a textPath. */ gfxFloat GetPathLengthScale(PathLengthScaleForType aFor); + // WebIDL + already_AddRefed<nsIDOMSVGAnimatedNumber> PathLength(); + float GetTotalLength(ErrorResult& rv); + already_AddRefed<nsISVGPoint> GetPointAtLength(float distance, ErrorResult& rv); + uint32_t GetPathSegAtLength(float distance); + already_AddRefed<DOMSVGPathSegClosePath> CreateSVGPathSegClosePath(); + already_AddRefed<DOMSVGPathSegMovetoAbs> CreateSVGPathSegMovetoAbs(float x, float y); + already_AddRefed<DOMSVGPathSegMovetoRel> CreateSVGPathSegMovetoRel(float x, float y); + already_AddRefed<DOMSVGPathSegLinetoAbs> CreateSVGPathSegLinetoAbs(float x, float y); + already_AddRefed<DOMSVGPathSegLinetoRel> CreateSVGPathSegLinetoRel(float x, float y); + already_AddRefed<DOMSVGPathSegCurvetoCubicAbs> + CreateSVGPathSegCurvetoCubicAbs(float x, float y, float x1, float y1, float x2, float y2); + already_AddRefed<DOMSVGPathSegCurvetoCubicRel> + CreateSVGPathSegCurvetoCubicRel(float x, float y, float x1, float y1, float x2, float y2); + already_AddRefed<DOMSVGPathSegCurvetoQuadraticAbs> + CreateSVGPathSegCurvetoQuadraticAbs(float x, float y, float x1, float y1); + already_AddRefed<DOMSVGPathSegCurvetoQuadraticRel> + CreateSVGPathSegCurvetoQuadraticRel(float x, float y, float x1, float y1); + already_AddRefed<DOMSVGPathSegArcAbs> + CreateSVGPathSegArcAbs(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag); + already_AddRefed<DOMSVGPathSegArcRel> + CreateSVGPathSegArcRel(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag); + already_AddRefed<DOMSVGPathSegLinetoHorizontalAbs> CreateSVGPathSegLinetoHorizontalAbs(float x); + already_AddRefed<DOMSVGPathSegLinetoHorizontalRel> CreateSVGPathSegLinetoHorizontalRel(float x); + already_AddRefed<DOMSVGPathSegLinetoVerticalAbs> CreateSVGPathSegLinetoVerticalAbs(float y); + already_AddRefed<DOMSVGPathSegLinetoVerticalRel> CreateSVGPathSegLinetoVerticalRel(float y); + already_AddRefed<DOMSVGPathSegCurvetoCubicSmoothAbs> + CreateSVGPathSegCurvetoCubicSmoothAbs(float x, float y, float x2, float y2); + already_AddRefed<DOMSVGPathSegCurvetoCubicSmoothRel> + CreateSVGPathSegCurvetoCubicSmoothRel(float x, float y, float x2, float y2); + already_AddRefed<DOMSVGPathSegCurvetoQuadraticSmoothAbs> + CreateSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y); + already_AddRefed<DOMSVGPathSegCurvetoQuadraticSmoothRel> + CreateSVGPathSegCurvetoQuadraticSmoothRel(float x, float y); + already_AddRefed<DOMSVGPathSegList> PathSegList(); + already_AddRefed<DOMSVGPathSegList> AnimatedPathSegList(); + protected: // nsSVGElement method virtual NumberAttributesInfo GetNumberInfo(); SVGAnimatedPathSegList mD; nsSVGNumber2 mPathLength; static NumberInfo sNumberInfo;
rename from content/svg/content/src/nsSVGPatternElement.cpp rename to content/svg/content/src/SVGPatternElement.cpp --- a/content/svg/content/src/nsSVGPatternElement.cpp +++ b/content/svg/content/src/SVGPatternElement.cpp @@ -4,226 +4,306 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/Util.h" #include "DOMSVGAnimatedTransformList.h" #include "nsIDOMMutationEvent.h" #include "nsCOMPtr.h" #include "nsGkAtoms.h" -#include "nsSVGPatternElement.h" +#include "mozilla/dom/SVGPatternElement.h" +#include "mozilla/dom/SVGPatternElementBinding.h" + +NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(Pattern) + +DOMCI_NODE_DATA(SVGPatternElement, mozilla::dom::SVGPatternElement) -using namespace mozilla; -using namespace mozilla::dom; +namespace mozilla { +namespace dom { + +JSObject* +SVGPatternElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap) +{ + return SVGPatternElementBinding::Wrap(aCx, aScope, this, aTriedToWrap); +} //--------------------- Patterns ------------------------ -nsSVGElement::LengthInfo nsSVGPatternElement::sLengthInfo[4] = +nsSVGElement::LengthInfo SVGPatternElement::sLengthInfo[4] = { { &nsGkAtoms::x, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::X }, { &nsGkAtoms::y, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::Y }, { &nsGkAtoms::width, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::X }, { &nsGkAtoms::height, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_PERCENTAGE, SVGContentUtils::Y }, }; -nsSVGElement::EnumInfo nsSVGPatternElement::sEnumInfo[2] = +nsSVGElement::EnumInfo SVGPatternElement::sEnumInfo[2] = { { &nsGkAtoms::patternUnits, sSVGUnitTypesMap, nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX }, { &nsGkAtoms::patternContentUnits, sSVGUnitTypesMap, nsIDOMSVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE } }; -nsSVGElement::StringInfo nsSVGPatternElement::sStringInfo[1] = +nsSVGElement::StringInfo SVGPatternElement::sStringInfo[1] = { { &nsGkAtoms::href, kNameSpaceID_XLink, true } }; -NS_IMPL_NS_NEW_SVG_ELEMENT(Pattern) - //---------------------------------------------------------------------- // nsISupports methods -NS_IMPL_ADDREF_INHERITED(nsSVGPatternElement,nsSVGPatternElementBase) -NS_IMPL_RELEASE_INHERITED(nsSVGPatternElement,nsSVGPatternElementBase) +NS_IMPL_ADDREF_INHERITED(SVGPatternElement,SVGPatternElementBase) +NS_IMPL_RELEASE_INHERITED(SVGPatternElement,SVGPatternElementBase) -DOMCI_NODE_DATA(SVGPatternElement, nsSVGPatternElement) - -NS_INTERFACE_TABLE_HEAD(nsSVGPatternElement) - NS_NODE_INTERFACE_TABLE7(nsSVGPatternElement, nsIDOMNode, nsIDOMElement, +NS_INTERFACE_TABLE_HEAD(SVGPatternElement) + NS_NODE_INTERFACE_TABLE7(SVGPatternElement, nsIDOMNode, nsIDOMElement, nsIDOMSVGElement, nsIDOMSVGFitToViewBox, nsIDOMSVGURIReference, nsIDOMSVGPatternElement, nsIDOMSVGUnitTypes) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGPatternElement) -NS_INTERFACE_MAP_END_INHERITING(nsSVGPatternElementBase) +NS_INTERFACE_MAP_END_INHERITING(SVGPatternElementBase) //---------------------------------------------------------------------- // Implementation -nsSVGPatternElement::nsSVGPatternElement(already_AddRefed<nsINodeInfo> aNodeInfo) - : nsSVGPatternElementBase(aNodeInfo) +SVGPatternElement::SVGPatternElement(already_AddRefed<nsINodeInfo> aNodeInfo) + : SVGPatternElementBase(aNodeInfo) { + SetIsDOMBinding(); } //---------------------------------------------------------------------- // nsIDOMNode method -NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGPatternElement) +NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGPatternElement) //---------------------------------------------------------------------- // nsIDOMSVGFitToViewBox methods /* readonly attribute nsIDOMSVGAnimatedRect viewBox; */ -NS_IMETHODIMP nsSVGPatternElement::GetViewBox(nsIDOMSVGAnimatedRect * *aViewBox) +NS_IMETHODIMP SVGPatternElement::GetViewBox(nsIDOMSVGAnimatedRect * *aViewBox) { - return mViewBox.ToDOMAnimatedRect(aViewBox, this); + *aViewBox = ViewBox().get(); + return NS_OK; +} + +already_AddRefed<nsIDOMSVGAnimatedRect> +SVGPatternElement::ViewBox() +{ + nsCOMPtr<nsIDOMSVGAnimatedRect> rect; + mViewBox.ToDOMAnimatedRect(getter_AddRefs(rect), this); + return rect.forget(); } /* readonly attribute SVGPreserveAspectRatio preserveAspectRatio; */ NS_IMETHODIMP -nsSVGPatternElement::GetPreserveAspectRatio(nsISupports - **aPreserveAspectRatio) +SVGPatternElement::GetPreserveAspectRatio(nsISupports **aPreserveAspectRatio) +{ + *aPreserveAspectRatio = PreserveAspectRatio().get(); + return NS_OK; +} + +already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> +SVGPatternElement::PreserveAspectRatio() { nsRefPtr<DOMSVGAnimatedPreserveAspectRatio> ratio; mPreserveAspectRatio.ToDOMAnimatedPreserveAspectRatio(getter_AddRefs(ratio), this); - ratio.forget(aPreserveAspectRatio); - return NS_OK; + return ratio.forget(); } //---------------------------------------------------------------------- // nsIDOMSVGPatternElement methods /* readonly attribute nsIDOMSVGAnimatedEnumeration patternUnits; */ -NS_IMETHODIMP nsSVGPatternElement::GetPatternUnits(nsIDOMSVGAnimatedEnumeration * *aPatternUnits) +NS_IMETHODIMP SVGPatternElement::GetPatternUnits(nsIDOMSVGAnimatedEnumeration * *aPatternUnits) { - return mEnumAttributes[PATTERNUNITS].ToDOMAnimatedEnum(aPatternUnits, this); + *aPatternUnits = PatternUnits().get(); + return NS_OK; +} + +already_AddRefed<nsIDOMSVGAnimatedEnumeration> +SVGPatternElement::PatternUnits() +{ + return mEnumAttributes[PATTERNUNITS].ToDOMAnimatedEnum(this); } /* readonly attribute nsIDOMSVGAnimatedEnumeration patternContentUnits; */ -NS_IMETHODIMP nsSVGPatternElement::GetPatternContentUnits(nsIDOMSVGAnimatedEnumeration * *aPatternUnits) +NS_IMETHODIMP SVGPatternElement::GetPatternContentUnits(nsIDOMSVGAnimatedEnumeration * *aPatternUnits) { - return mEnumAttributes[PATTERNCONTENTUNITS].ToDOMAnimatedEnum(aPatternUnits, this); + *aPatternUnits = PatternContentUnits().get(); + return NS_OK; +} + +already_AddRefed<nsIDOMSVGAnimatedEnumeration> +SVGPatternElement::PatternContentUnits() +{ + return mEnumAttributes[PATTERNCONTENTUNITS].ToDOMAnimatedEnum(this); } /* readonly attribute nsISupports patternTransform; */ -NS_IMETHODIMP nsSVGPatternElement::GetPatternTransform(nsISupports * *aPatternTransform) +NS_IMETHODIMP SVGPatternElement::GetPatternTransform(nsISupports * *aPatternTransform) +{ + *aPatternTransform = PatternTransform().get(); + return NS_OK; +} + +already_AddRefed<DOMSVGAnimatedTransformList> +SVGPatternElement::PatternTransform() { // We're creating a DOM wrapper, so we must tell GetAnimatedTransformList // to allocate the SVGAnimatedTransformList if it hasn't already done so: - *aPatternTransform = DOMSVGAnimatedTransformList::GetDOMWrapper( - GetAnimatedTransformList(DO_ALLOCATE), this).get(); - return NS_OK; + return DOMSVGAnimatedTransformList::GetDOMWrapper( + GetAnimatedTransformList(DO_ALLOCATE), this); } /* readonly attribute nsIDOMSVGAnimatedLength x; */ -NS_IMETHODIMP nsSVGPatternElement::GetX(nsIDOMSVGAnimatedLength * *aX) +NS_IMETHODIMP SVGPatternElement::GetX(nsIDOMSVGAnimatedLength * *aX) { - return mLengthAttributes[X].ToDOMAnimatedLength(aX, this); + *aX = X().get(); + return NS_OK; +} + +already_AddRefed<nsIDOMSVGAnimatedLength> +SVGPatternElement::X() +{ + return mLengthAttributes[ATTR_X].ToDOMAnimatedLength(this); } /* readonly attribute nsIDOMSVGAnimatedLength y; */ -NS_IMETHODIMP nsSVGPatternElement::GetY(nsIDOMSVGAnimatedLength * *aY) +NS_IMETHODIMP SVGPatternElement::GetY(nsIDOMSVGAnimatedLength * *aY) { - return mLengthAttributes[Y].ToDOMAnimatedLength(aY, this); + *aY = Y().get(); + return NS_OK; +} + +already_AddRefed<nsIDOMSVGAnimatedLength> +SVGPatternElement::Y() +{ + return mLengthAttributes[ATTR_Y].ToDOMAnimatedLength(this); } /* readonly attribute nsIDOMSVGAnimatedLength width; */ -NS_IMETHODIMP nsSVGPatternElement::GetWidth(nsIDOMSVGAnimatedLength * *aWidth) +NS_IMETHODIMP SVGPatternElement::GetWidth(nsIDOMSVGAnimatedLength * *aWidth) { - return mLengthAttributes[WIDTH].ToDOMAnimatedLength(aWidth, this); + *aWidth = Width().get(); + return NS_OK; +} + +already_AddRefed<nsIDOMSVGAnimatedLength> +SVGPatternElement::Width() +{ + return mLengthAttributes[ATTR_WIDTH].ToDOMAnimatedLength(this); } /* readonly attribute nsIDOMSVGAnimatedLength height; */ -NS_IMETHODIMP nsSVGPatternElement::GetHeight(nsIDOMSVGAnimatedLength * *aHeight) +NS_IMETHODIMP SVGPatternElement::GetHeight(nsIDOMSVGAnimatedLength * *aHeight) { - return mLengthAttributes[HEIGHT].ToDOMAnimatedLength(aHeight, this); + *aHeight = Height().get(); + return NS_OK; } +already_AddRefed<nsIDOMSVGAnimatedLength> +SVGPatternElement::Height() +{ + return mLengthAttributes[ATTR_HEIGHT].ToDOMAnimatedLength(this); +} //---------------------------------------------------------------------- // nsIDOMSVGURIReference methods: /* readonly attribute nsIDOMSVGAnimatedString href; */ NS_IMETHODIMP -nsSVGPatternElement::GetHref(nsIDOMSVGAnimatedString * *aHref) +SVGPatternElement::GetHref(nsIDOMSVGAnimatedString * *aHref) { - return mStringAttributes[HREF].ToDOMAnimatedString(aHref, this); + *aHref = Href().get(); + return NS_OK; +} + +already_AddRefed<nsIDOMSVGAnimatedString> +SVGPatternElement::Href() +{ + nsCOMPtr<nsIDOMSVGAnimatedString> href; + mStringAttributes[HREF].ToDOMAnimatedString(getter_AddRefs(href), this); + return href.forget(); } //---------------------------------------------------------------------- // nsIContent methods NS_IMETHODIMP_(bool) -nsSVGPatternElement::IsAttributeMapped(const nsIAtom* name) const +SVGPatternElement::IsAttributeMapped(const nsIAtom* name) const { static const MappedAttributeEntry* const map[] = { sFEFloodMap, sFiltersMap, sFontSpecificationMap, sGradientStopMap, sLightingEffectsMap, sMarkersMap, sTextContentElementsMap, sViewportsMap }; return FindAttributeDependence(name, map) || - nsSVGPatternElementBase::IsAttributeMapped(name); + SVGPatternElementBase::IsAttributeMapped(name); } //---------------------------------------------------------------------- // nsSVGElement methods SVGAnimatedTransformList* -nsSVGPatternElement::GetAnimatedTransformList(uint32_t aFlags) +SVGPatternElement::GetAnimatedTransformList(uint32_t aFlags) { if (!mPatternTransform && (aFlags & DO_ALLOCATE)) { mPatternTransform = new SVGAnimatedTransformList(); } return mPatternTransform; } /* virtual */ bool -nsSVGPatternElement::HasValidDimensions() const +SVGPatternElement::HasValidDimensions() const { - return mLengthAttributes[WIDTH].IsExplicitlySet() && - mLengthAttributes[WIDTH].GetAnimValInSpecifiedUnits() > 0 && - mLengthAttributes[HEIGHT].IsExplicitlySet() && - mLengthAttributes[HEIGHT].GetAnimValInSpecifiedUnits() > 0; + return mLengthAttributes[ATTR_WIDTH].IsExplicitlySet() && + mLengthAttributes[ATTR_WIDTH].GetAnimValInSpecifiedUnits() > 0 && + mLengthAttributes[ATTR_HEIGHT].IsExplicitlySet() && + mLengthAttributes[ATTR_HEIGHT].GetAnimValInSpecifiedUnits() > 0; } nsSVGElement::LengthAttributesInfo -nsSVGPatternElement::GetLengthInfo() +SVGPatternElement::GetLengthInfo() { return LengthAttributesInfo(mLengthAttributes, sLengthInfo, ArrayLength(sLengthInfo)); } nsSVGElement::EnumAttributesInfo -nsSVGPatternElement::GetEnumInfo() +SVGPatternElement::GetEnumInfo() { return EnumAttributesInfo(mEnumAttributes, sEnumInfo, ArrayLength(sEnumInfo)); } nsSVGViewBox * -nsSVGPatternElement::GetViewBox() +SVGPatternElement::GetViewBox() { return &mViewBox; } SVGAnimatedPreserveAspectRatio * -nsSVGPatternElement::GetPreserveAspectRatio() +SVGPatternElement::GetPreserveAspectRatio() { return &mPreserveAspectRatio; } nsSVGElement::StringAttributesInfo -nsSVGPatternElement::GetStringInfo() +SVGPatternElement::GetStringInfo() { return StringAttributesInfo(mStringAttributes, sStringInfo, ArrayLength(sStringInfo)); } +} // namespace dom +} // namespace mozilla
rename from content/svg/content/src/nsSVGPatternElement.h rename to content/svg/content/src/SVGPatternElement.h --- a/content/svg/content/src/nsSVGPatternElement.h +++ b/content/svg/content/src/SVGPatternElement.h @@ -1,44 +1,53 @@ /* -*- Mode: C++; 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/. */ -#ifndef __NS_SVGPATTERNELEMENT_H__ -#define __NS_SVGPATTERNELEMENT_H__ +#ifndef mozilla_dom_SVGPatternElement_h +#define mozilla_dom_SVGPatternElement_h #include "nsIDOMSVGFitToViewBox.h" #include "nsIDOMSVGPatternElement.h" #include "nsIDOMSVGUnitTypes.h" #include "nsIDOMSVGURIReference.h" #include "nsSVGEnum.h" #include "nsSVGLength2.h" #include "nsSVGString.h" #include "nsSVGElement.h" #include "nsSVGViewBox.h" #include "SVGAnimatedPreserveAspectRatio.h" #include "SVGAnimatedTransformList.h" -//--------------------- Patterns ------------------------ +class nsSVGPatternFrame; + +nsresult NS_NewSVGPatternElement(nsIContent **aResult, + already_AddRefed<nsINodeInfo> aNodeInfo); -typedef nsSVGElement nsSVGPatternElementBase; +namespace mozilla { +class DOMSVGAnimatedTransformList; + +namespace dom { -class nsSVGPatternElement : public nsSVGPatternElementBase, - public nsIDOMSVGPatternElement, - public nsIDOMSVGURIReference, - public nsIDOMSVGFitToViewBox, - public nsIDOMSVGUnitTypes +typedef nsSVGElement SVGPatternElementBase; + +class SVGPatternElement MOZ_FINAL : public SVGPatternElementBase, + public nsIDOMSVGPatternElement, + public nsIDOMSVGURIReference, + public nsIDOMSVGFitToViewBox, + public nsIDOMSVGUnitTypes { - friend class nsSVGPatternFrame; + friend class ::nsSVGPatternFrame; protected: - friend nsresult NS_NewSVGPatternElement(nsIContent **aResult, - already_AddRefed<nsINodeInfo> aNodeInfo); - nsSVGPatternElement(already_AddRefed<nsINodeInfo> aNodeInfo); + friend nsresult (::NS_NewSVGPatternElement(nsIContent **aResult, + already_AddRefed<nsINodeInfo> aNodeInfo)); + SVGPatternElement(already_AddRefed<nsINodeInfo> aNodeInfo); + virtual JSObject* WrapNode(JSContext *cx, JSObject *scope, bool *triedToWrap) MOZ_OVERRIDE; public: typedef mozilla::SVGAnimatedPreserveAspectRatio SVGAnimatedPreserveAspectRatio; // interfaces: NS_DECL_ISUPPORTS_INHERITED // Pattern Element @@ -66,26 +75,39 @@ public: // nsSVGSVGElement methods: virtual bool HasValidDimensions() const; virtual mozilla::SVGAnimatedTransformList* GetAnimatedTransformList(uint32_t aFlags = 0); virtual nsIAtom* GetTransformListAttrName() const { return nsGkAtoms::patternTransform; } + + // WebIDL + already_AddRefed<nsIDOMSVGAnimatedRect> ViewBox(); + already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> PreserveAspectRatio(); + already_AddRefed<nsIDOMSVGAnimatedEnumeration> PatternUnits(); + already_AddRefed<nsIDOMSVGAnimatedEnumeration> PatternContentUnits(); + already_AddRefed<DOMSVGAnimatedTransformList> PatternTransform(); + already_AddRefed<nsIDOMSVGAnimatedLength> X(); + already_AddRefed<nsIDOMSVGAnimatedLength> Y(); + already_AddRefed<nsIDOMSVGAnimatedLength> Width(); + already_AddRefed<nsIDOMSVGAnimatedLength> Height(); + already_AddRefed<nsIDOMSVGAnimatedString> Href(); + protected: virtual LengthAttributesInfo GetLengthInfo(); virtual EnumAttributesInfo GetEnumInfo(); virtual nsSVGViewBox *GetViewBox(); virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio(); virtual StringAttributesInfo GetStringInfo(); // nsIDOMSVGPatternElement values - enum { X, Y, WIDTH, HEIGHT }; + enum { ATTR_X, ATTR_Y, ATTR_WIDTH, ATTR_HEIGHT }; nsSVGLength2 mLengthAttributes[4]; static LengthInfo sLengthInfo[4]; enum { PATTERNUNITS, PATTERNCONTENTUNITS }; nsSVGEnum mEnumAttributes[2]; static EnumInfo sEnumInfo[2]; nsAutoPtr<mozilla::SVGAnimatedTransformList> mPatternTransform; @@ -95,9 +117,12 @@ protected: nsSVGString mStringAttributes[1]; static StringInfo sStringInfo[1]; // nsIDOMSVGFitToViewbox properties nsSVGViewBox mViewBox; SVGAnimatedPreserveAspectRatio mPreserveAspectRatio; }; -#endif +} // namespace dom +} // namespace mozilla + +#endif // mozilla_dom_SVGPatternElement_h
--- a/content/svg/content/src/SVGPoint.h +++ b/content/svg/content/src/SVGPoint.h @@ -16,20 +16,18 @@ namespace mozilla { * * The DOM wrapper class for this class is DOMSVGPoint. */ class SVGPoint { public: SVGPoint() -#ifdef DEBUG : mX(0.0f) , mY(0.0f) -#endif {} SVGPoint(float aX, float aY) : mX(aX) , mY(aY) { NS_ASSERTION(IsValid(), "Constructed an invalid SVGPoint"); } @@ -60,16 +58,29 @@ public: } #ifdef DEBUG bool IsValid() const { return NS_finite(mX) && NS_finite(mY); } #endif + void SetX(float aX) + { mX = aX; } + void SetY(float aY) + { mY = aY; } + float GetX() const + { return mX; } + float GetY() const + { return mY; } + + bool operator!=(const SVGPoint &rhs) const { + return mX != rhs.mX || mY != rhs.mY; + } + float mX; float mY; }; inline SVGPoint operator+(const SVGPoint& aP1, const SVGPoint& aP2) { return SVGPoint(aP1.mX + aP2.mX, aP1.mY + aP2.mY);
--- a/content/svg/content/src/SVGPointList.h +++ b/content/svg/content/src/SVGPointList.h @@ -13,28 +13,30 @@ #include "nsIWeakReferenceUtils.h" #include "nsSVGElement.h" #include "nsTArray.h" #include "SVGPoint.h" #include <string.h> namespace mozilla { +class nsISVGPoint; /** * ATTENTION! WARNING! WATCH OUT!! * * Consumers that modify objects of this type absolutely MUST keep the DOM * wrappers for those lists (if any) in sync!! That's why this class is so * locked down. * * The DOM wrapper class for this class is DOMSVGPointList. */ class SVGPointList { + friend class mozilla::nsISVGPoint; friend class SVGAnimatedPointList; friend class DOMSVGPointList; friend class DOMSVGPoint; public: SVGPointList(){} ~SVGPointList(){}
--- a/content/svg/content/src/SVGSVGElement.cpp +++ b/content/svg/content/src/SVGSVGElement.cpp @@ -49,62 +49,60 @@ namespace mozilla { namespace dom { JSObject* SVGSVGElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap) { return SVGSVGElementBinding::Wrap(aCx, aScope, this, aTriedToWrap); } -NS_SVG_VAL_IMPL_CYCLE_COLLECTION_WRAPPERCACHED(nsSVGTranslatePoint::DOMVal, mElement) +NS_SVG_VAL_IMPL_CYCLE_COLLECTION_WRAPPERCACHED(DOMSVGTranslatePoint, mElement) -NS_IMPL_CYCLE_COLLECTING_ADDREF(nsSVGTranslatePoint::DOMVal) -NS_IMPL_CYCLE_COLLECTING_RELEASE(nsSVGTranslatePoint::DOMVal) +NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMSVGTranslatePoint) +NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMSVGTranslatePoint) -NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsSVGTranslatePoint::DOMVal) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMSVGTranslatePoint) NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY // We have to qualify nsISVGPoint because NS_GET_IID looks for a class in the // global namespace NS_INTERFACE_MAP_ENTRY(mozilla::nsISVGPoint) NS_INTERFACE_MAP_ENTRY(nsISupports) NS_INTERFACE_MAP_END -nsresult -nsSVGTranslatePoint::ToDOMVal(SVGSVGElement *aElement, - nsISupports **aResult) +nsISVGPoint* +DOMSVGTranslatePoint::Clone() { - NS_ADDREF(*aResult = new DOMVal(this, aElement)); - return NS_OK; + return new DOMSVGTranslatePoint(this); } nsISupports* -nsSVGTranslatePoint::DOMVal::GetParentObject() +DOMSVGTranslatePoint::GetParentObject() { return static_cast<nsIDOMSVGSVGElement*>(mElement); } void -nsSVGTranslatePoint::DOMVal::SetX(float aValue, ErrorResult& rv) +DOMSVGTranslatePoint::SetX(float aValue, ErrorResult& rv) { - rv = mElement->SetCurrentTranslate(aValue, mVal->GetY()); + rv = mElement->SetCurrentTranslate(aValue, mPt.GetY()); } void -nsSVGTranslatePoint::DOMVal::SetY(float aValue, ErrorResult& rv) +DOMSVGTranslatePoint::SetY(float aValue, ErrorResult& rv) { - rv = mElement->SetCurrentTranslate(mVal->GetX(), aValue); + rv = mElement->SetCurrentTranslate(mPt.GetX(), aValue); } already_AddRefed<nsISVGPoint> -nsSVGTranslatePoint::DOMVal::MatrixTransform(SVGMatrix& matrix) +DOMSVGTranslatePoint::MatrixTransform(SVGMatrix& matrix) { float a = matrix.A(), b = matrix.B(), c = matrix.C(); float d = matrix.D(), e = matrix.E(), f = matrix.F(); - float x = mVal->GetX(); - float y = mVal->GetY(); + float x = mPt.GetX(); + float y = mPt.GetY(); nsCOMPtr<nsISVGPoint> point = new DOMSVGPoint(a*x + c*y + e, b*x + d*y + f); return point.forget(); } nsSVGElement::LengthInfo SVGSVGElement::sLengthInfo[4] = { { &nsGkAtoms::x, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::X }, @@ -125,17 +123,16 @@ nsSVGElement::EnumInfo SVGSVGElement::sE sZoomAndPanMap, SVG_ZOOMANDPAN_MAGNIFY } }; //---------------------------------------------------------------------- // nsISupports methods -NS_IMPL_CYCLE_COLLECTION_CLASS(SVGSVGElement) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(SVGSVGElement, SVGSVGElementBase) if (tmp->mTimedDocumentRoot) { tmp->mTimedDocumentRoot->Unlink(); } NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(SVGSVGElement, SVGSVGElementBase) @@ -357,18 +354,17 @@ SVGSVGElement::GetCurrentTranslate(nsISu { *aCurrentTranslate = CurrentTranslate().get(); return NS_OK; } already_AddRefed<nsISVGPoint> SVGSVGElement::CurrentTranslate() { - nsCOMPtr<nsISVGPoint> point; - mCurrentTranslate.ToDOMVal(this, getter_AddRefs(point)); + nsCOMPtr<nsISVGPoint> point = new DOMSVGTranslatePoint(&mCurrentTranslate, this); return point.forget(); } /* unsigned long suspendRedraw (in unsigned long max_wait_milliseconds); */ NS_IMETHODIMP SVGSVGElement::SuspendRedraw(uint32_t max_wait_milliseconds, uint32_t *_retval) { *_retval = SuspendRedraw(max_wait_milliseconds); @@ -788,17 +784,17 @@ SVGSVGElement::SetCurrentScaleTranslate( // the state of currentScale and currentTranslate immediately before the // change that caused the event's dispatch, which is *not* necessarily the // same thing as the values of currentScale and currentTranslate prior to // their own last change. mPreviousScale = mCurrentScale; mPreviousTranslate = mCurrentTranslate; mCurrentScale = s; - mCurrentTranslate = nsSVGTranslatePoint(x, y); + mCurrentTranslate = SVGPoint(x, y); // now dispatch the appropriate event if we are the root element nsIDocument* doc = GetCurrentDoc(); if (doc) { nsCOMPtr<nsIPresShell> presShell = doc->GetShell(); if (presShell && IsRoot()) { bool scaling = (mPreviousScale != mCurrentScale); nsEventStatus status = nsEventStatus_eIgnore; @@ -960,17 +956,17 @@ SVGSVGElement::GetViewBoxTransform() con GetPreserveAspectRatioWithOverride()); } void SVGSVGElement::UpdateHasChildrenOnlyTransform() { bool hasChildrenOnlyTransform = HasViewBoxOrSyntheticViewBox() || - (IsRoot() && (mCurrentTranslate != nsSVGTranslatePoint(0.0f, 0.0f) || + (IsRoot() && (mCurrentTranslate != SVGPoint(0.0f, 0.0f) || mCurrentScale != 1.0f)); mHasChildrenOnlyTransform = hasChildrenOnlyTransform; } void SVGSVGElement::ChildrenOnlyTransformChanged(uint32_t aFlags) { // Avoid wasteful calls:
--- a/content/svg/content/src/SVGSVGElement.h +++ b/content/svg/content/src/SVGSVGElement.h @@ -3,17 +3,16 @@ * 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 mozilla_dom_SVGSVGElement_h #define mozilla_dom_SVGSVGElement_h #include "mozilla/dom/FromParser.h" #include "nsIDOMSVGFitToViewBox.h" -#include "nsIDOMSVGLocatable.h" #include "nsISVGPoint.h" #include "nsIDOMSVGSVGElement.h" #include "nsSVGEnum.h" #include "nsSVGLength2.h" #include "SVGGraphicsElement.h" #include "nsSVGViewBox.h" #include "SVGPreserveAspectRatio.h" #include "SVGAnimatedPreserveAspectRatio.h" @@ -35,67 +34,39 @@ class SVGFragmentIdentifier; namespace dom { class SVGAngle; class SVGMatrix; class SVGViewElement; class SVGSVGElement; -class nsSVGTranslatePoint { +class DOMSVGTranslatePoint MOZ_FINAL : public nsISVGPoint { public: - nsSVGTranslatePoint() - : mX(0.0f) - , mY(0.0f) - {} + DOMSVGTranslatePoint(SVGPoint* aPt, SVGSVGElement *aElement) + : nsISVGPoint(aPt), mElement(aElement) {} - nsSVGTranslatePoint(float aX, float aY) - : mX(aX) - , mY(aY) - {} + DOMSVGTranslatePoint(DOMSVGTranslatePoint* aPt) + : nsISVGPoint(&aPt->mPt), mElement(aPt->mElement) {} - void SetX(float aX) - { mX = aX; } - void SetY(float aY) - { mY = aY; } - float GetX() const - { return mX; } - float GetY() const - { return mY; } - - nsresult ToDOMVal(SVGSVGElement *aElement, nsISupports **aResult); + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMSVGTranslatePoint) - bool operator!=(const nsSVGTranslatePoint &rhs) const { - return mX != rhs.mX || mY != rhs.mY; - } - -private: - - struct DOMVal MOZ_FINAL : public nsISVGPoint { - DOMVal(nsSVGTranslatePoint* aVal, SVGSVGElement *aElement) - : nsISVGPoint(), mVal(aVal), mElement(aElement) {} - - NS_DECL_CYCLE_COLLECTING_ISUPPORTS - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(DOMVal) + virtual nsISVGPoint* Clone(); - // WebIDL - virtual float X() { return mVal->GetX(); } - virtual float Y() { return mVal->GetY(); } - virtual void SetX(float aValue, ErrorResult& rv); - virtual void SetY(float aValue, ErrorResult& rv); - virtual already_AddRefed<nsISVGPoint> MatrixTransform(SVGMatrix& matrix); + // WebIDL + virtual float X() { return mPt.GetX(); } + virtual float Y() { return mPt.GetY(); } + virtual void SetX(float aValue, ErrorResult& rv); + virtual void SetY(float aValue, ErrorResult& rv); + virtual already_AddRefed<nsISVGPoint> MatrixTransform(SVGMatrix& matrix); - virtual nsISupports* GetParentObject() MOZ_OVERRIDE; + virtual nsISupports* GetParentObject() MOZ_OVERRIDE; - nsSVGTranslatePoint *mVal; // kept alive because it belongs to mElement - nsRefPtr<SVGSVGElement> mElement; - }; - - float mX; - float mY; + nsRefPtr<SVGSVGElement> mElement; }; class svgFloatSize { public: svgFloatSize(float aWidth, float aHeight) : width(aWidth) , height(aHeight) {} @@ -149,24 +120,24 @@ public: * to be set by a single operation that dispatches a single SVGScroll event * (instead of two). */ NS_IMETHOD SetCurrentTranslate(float x, float y); /** * Retrieve the value of currentScale and currentTranslate. */ - const nsSVGTranslatePoint& GetCurrentTranslate() { return mCurrentTranslate; } + const SVGPoint& GetCurrentTranslate() { return mCurrentTranslate; } float GetCurrentScale() { return mCurrentScale; } /** * Retrieve the value of currentScale, currentTranslate.x or * currentTranslate.y prior to the last change made to any one of them. */ - const nsSVGTranslatePoint& GetPreviousTranslate() { return mPreviousTranslate; } + const SVGPoint& GetPreviousTranslate() { return mPreviousTranslate; } float GetPreviousScale() { return mPreviousScale; } nsSMILTimeContainer* GetTimedDocumentRoot(); // nsIContent interface NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const; virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor); @@ -408,28 +379,28 @@ private: // The time container for animations within this SVG document fragment. Set // for all outermost <svg> elements (not nested <svg> elements). nsAutoPtr<nsSMILTimeContainer> mTimedDocumentRoot; // zoom and pan // IMPORTANT: see the comment in RecordCurrentScaleTranslate before writing // code to change any of these! - nsSVGTranslatePoint mCurrentTranslate; - float mCurrentScale; - nsSVGTranslatePoint mPreviousTranslate; - float mPreviousScale; + SVGPoint mCurrentTranslate; + float mCurrentScale; + SVGPoint mPreviousTranslate; + float mPreviousScale; // For outermost <svg> elements created from parsing, animation is started by // the onload event in accordance with the SVG spec, but for <svg> elements // created by script or promoted from inner <svg> to outermost <svg> we need // to manually kick off animation when they are bound to the tree. - bool mStartAnimationOnBindToTree; - bool mImageNeedsTransformInvalidation; - bool mIsPaintingSVGImageElement; - bool mHasChildrenOnlyTransform; - bool mUseCurrentView; + bool mStartAnimationOnBindToTree; + bool mImageNeedsTransformInvalidation; + bool mIsPaintingSVGImageElement; + bool mHasChildrenOnlyTransform; + bool mUseCurrentView; }; } // namespace dom } // namespace mozilla #endif // SVGSVGElement_h
--- a/content/svg/content/src/SVGStyleElement.cpp +++ b/content/svg/content/src/SVGStyleElement.cpp @@ -31,17 +31,16 @@ NS_IMPL_RELEASE_INHERITED(SVGStyleElemen NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(SVGStyleElement) NS_NODE_INTERFACE_TABLE7(SVGStyleElement, nsIDOMNode, nsIDOMElement, nsIDOMSVGElement, nsIDOMSVGStyleElement, nsIDOMLinkStyle, nsIStyleSheetLinkingElement, nsIMutationObserver) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGStyleElement) NS_INTERFACE_MAP_END_INHERITING(SVGStyleElementBase) -NS_IMPL_CYCLE_COLLECTION_CLASS(SVGStyleElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(SVGStyleElement, SVGStyleElementBase) tmp->nsStyleLinkElement::Traverse(cb); NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(SVGStyleElement, SVGStyleElementBase) tmp->nsStyleLinkElement::Unlink(); NS_IMPL_CYCLE_COLLECTION_UNLINK_END
--- a/content/svg/content/src/SVGSwitchElement.cpp +++ b/content/svg/content/src/SVGSwitchElement.cpp @@ -23,17 +23,16 @@ JSObject* SVGSwitchElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap) { return SVGSwitchElementBinding::Wrap(aCx, aScope, this, aTriedToWrap); } //---------------------------------------------------------------------- // nsISupports methods -NS_IMPL_CYCLE_COLLECTION_CLASS(SVGSwitchElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(SVGSwitchElement, SVGSwitchElementBase) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mActiveChild) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(SVGSwitchElement, SVGSwitchElementBase) NS_IMPL_CYCLE_COLLECTION_UNLINK(mActiveChild) NS_IMPL_CYCLE_COLLECTION_UNLINK_END
rename from content/svg/content/src/nsSVGSymbolElement.cpp rename to content/svg/content/src/SVGSymbolElement.cpp --- a/content/svg/content/src/nsSVGSymbolElement.cpp +++ b/content/svg/content/src/SVGSymbolElement.cpp @@ -1,147 +1,125 @@ /* -*- Mode: C++; 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 "mozilla/Util.h" - -#include "nsIDOMSVGSymbolElement.h" -#include "DOMSVGTests.h" -#include "nsSVGElement.h" -#include "nsSVGViewBox.h" -#include "SVGAnimatedPreserveAspectRatio.h" -#include "nsIDOMSVGFitToViewBox.h" -#include "nsGkAtoms.h" +#include "mozilla/dom/SVGSymbolElement.h" +#include "mozilla/dom/SVGSymbolElementBinding.h" -using namespace mozilla; -using namespace mozilla::dom; - -typedef nsSVGElement nsSVGSymbolElementBase; +NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(Symbol) -class nsSVGSymbolElement : public nsSVGSymbolElementBase, - public nsIDOMSVGSymbolElement, - public DOMSVGTests, - public nsIDOMSVGFitToViewBox -{ -protected: - friend nsresult NS_NewSVGSymbolElement(nsIContent **aResult, - already_AddRefed<nsINodeInfo> aNodeInfo); - nsSVGSymbolElement(already_AddRefed<nsINodeInfo> aNodeInfo); +DOMCI_NODE_DATA(SVGSymbolElement, mozilla::dom::SVGSymbolElement) -public: - // interfaces: - - NS_DECL_ISUPPORTS_INHERITED - NS_DECL_NSIDOMSVGSYMBOLELEMENT - NS_DECL_NSIDOMSVGFITTOVIEWBOX - - // xxx I wish we could use virtual inheritance - NS_FORWARD_NSIDOMNODE_TO_NSINODE - NS_FORWARD_NSIDOMELEMENT_TO_GENERIC - NS_FORWARD_NSIDOMSVGELEMENT(nsSVGElement::) - - // nsIContent interface - NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const; +namespace mozilla { +namespace dom { - virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const; - - virtual nsXPCClassInfo* GetClassInfo(); - - virtual nsIDOMNode* AsDOMNode() { return this; } -protected: - virtual nsSVGViewBox *GetViewBox(); - virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio(); - - nsSVGViewBox mViewBox; - SVGAnimatedPreserveAspectRatio mPreserveAspectRatio; -}; - -NS_IMPL_NS_NEW_SVG_ELEMENT(Symbol) +JSObject* +SVGSymbolElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap) +{ + return SVGSymbolElementBinding::Wrap(aCx, aScope, this, aTriedToWrap); +} //---------------------------------------------------------------------- // nsISupports methods -NS_IMPL_ADDREF_INHERITED(nsSVGSymbolElement,nsSVGSymbolElementBase) -NS_IMPL_RELEASE_INHERITED(nsSVGSymbolElement,nsSVGSymbolElementBase) - -DOMCI_NODE_DATA(SVGSymbolElement, nsSVGSymbolElement) +NS_IMPL_ADDREF_INHERITED(SVGSymbolElement,SVGSymbolElementBase) +NS_IMPL_RELEASE_INHERITED(SVGSymbolElement,SVGSymbolElementBase) -NS_INTERFACE_TABLE_HEAD(nsSVGSymbolElement) - NS_NODE_INTERFACE_TABLE5(nsSVGSymbolElement, nsIDOMNode, nsIDOMElement, +NS_INTERFACE_TABLE_HEAD(SVGSymbolElement) + NS_NODE_INTERFACE_TABLE6(SVGSymbolElement, nsIDOMNode, nsIDOMElement, nsIDOMSVGElement, nsIDOMSVGFitToViewBox, - nsIDOMSVGSymbolElement) + nsIDOMSVGSymbolElement, nsIDOMSVGTests) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGSymbolElement) -NS_INTERFACE_MAP_END_INHERITING(nsSVGSymbolElementBase) +NS_INTERFACE_MAP_END_INHERITING(SVGSymbolElementBase) //---------------------------------------------------------------------- // Implementation -nsSVGSymbolElement::nsSVGSymbolElement(already_AddRefed<nsINodeInfo> aNodeInfo) - : nsSVGSymbolElementBase(aNodeInfo) +SVGSymbolElement::SVGSymbolElement(already_AddRefed<nsINodeInfo> aNodeInfo) + : SVGSymbolElementBase(aNodeInfo) { + SetIsDOMBinding(); } //---------------------------------------------------------------------- // nsIDOMNode methods -NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGSymbolElement) +NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGSymbolElement) //---------------------------------------------------------------------- // nsIDOMSVGFitToViewBox methods /* readonly attribute nsIDOMSVGAnimatedRect viewBox; */ -NS_IMETHODIMP nsSVGSymbolElement::GetViewBox(nsIDOMSVGAnimatedRect * *aViewBox) +NS_IMETHODIMP SVGSymbolElement::GetViewBox(nsIDOMSVGAnimatedRect * *aViewBox) { - return mViewBox.ToDOMAnimatedRect(aViewBox, this); + *aViewBox = ViewBox().get(); + return NS_OK; +} + +already_AddRefed<nsIDOMSVGAnimatedRect> +SVGSymbolElement::ViewBox() +{ + nsCOMPtr<nsIDOMSVGAnimatedRect> rect; + mViewBox.ToDOMAnimatedRect(getter_AddRefs(rect), this); + return rect.forget(); } /* readonly attribute SVGPreserveAspectRatio preserveAspectRatio; */ NS_IMETHODIMP -nsSVGSymbolElement::GetPreserveAspectRatio(nsISupports - **aPreserveAspectRatio) +SVGSymbolElement::GetPreserveAspectRatio(nsISupports + **aPreserveAspectRatio) +{ + *aPreserveAspectRatio = PreserveAspectRatio().get(); + return NS_OK; +} + +already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> +SVGSymbolElement::PreserveAspectRatio() { nsRefPtr<DOMSVGAnimatedPreserveAspectRatio> ratio; mPreserveAspectRatio.ToDOMAnimatedPreserveAspectRatio(getter_AddRefs(ratio), this); - ratio.forget(aPreserveAspectRatio); - return NS_OK; + return ratio.forget(); } //---------------------------------------------------------------------- // nsIContent methods NS_IMETHODIMP_(bool) -nsSVGSymbolElement::IsAttributeMapped(const nsIAtom* name) const +SVGSymbolElement::IsAttributeMapped(const nsIAtom* name) const { static const MappedAttributeEntry* const map[] = { sColorMap, sFEFloodMap, sFillStrokeMap, sFiltersMap, sFontSpecificationMap, sGradientStopMap, sGraphicsMap, sLightingEffectsMap, sMarkersMap, sTextContentElementsMap, sViewportsMap }; return FindAttributeDependence(name, map) || - nsSVGSymbolElementBase::IsAttributeMapped(name); + SVGSymbolElementBase::IsAttributeMapped(name); } //---------------------------------------------------------------------- // nsSVGElement methods nsSVGViewBox * -nsSVGSymbolElement::GetViewBox() +SVGSymbolElement::GetViewBox() { return &mViewBox; } SVGAnimatedPreserveAspectRatio * -nsSVGSymbolElement::GetPreserveAspectRatio() +SVGSymbolElement::GetPreserveAspectRatio() { return &mPreserveAspectRatio; } + +} // namespace dom +} // namespace mozilla
copy from content/svg/content/src/nsSVGSymbolElement.cpp copy to content/svg/content/src/SVGSymbolElement.h --- a/content/svg/content/src/nsSVGSymbolElement.cpp +++ b/content/svg/content/src/SVGSymbolElement.h @@ -1,37 +1,42 @@ /* -*- Mode: C++; 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 "mozilla/Util.h" +#ifndef mozilla_dom_SVGSymbolElement_h +#define mozilla_dom_SVGSymbolElement_h #include "nsIDOMSVGSymbolElement.h" #include "DOMSVGTests.h" #include "nsSVGElement.h" #include "nsSVGViewBox.h" #include "SVGAnimatedPreserveAspectRatio.h" #include "nsIDOMSVGFitToViewBox.h" #include "nsGkAtoms.h" -using namespace mozilla; -using namespace mozilla::dom; +nsresult NS_NewSVGSymbolElement(nsIContent **aResult, + already_AddRefed<nsINodeInfo> aNodeInfo); -typedef nsSVGElement nsSVGSymbolElementBase; +namespace mozilla { +namespace dom { -class nsSVGSymbolElement : public nsSVGSymbolElementBase, - public nsIDOMSVGSymbolElement, - public DOMSVGTests, - public nsIDOMSVGFitToViewBox +typedef nsSVGElement SVGSymbolElementBase; + +class SVGSymbolElement MOZ_FINAL : public SVGSymbolElementBase, + public nsIDOMSVGSymbolElement, + public DOMSVGTests, + public nsIDOMSVGFitToViewBox { protected: - friend nsresult NS_NewSVGSymbolElement(nsIContent **aResult, - already_AddRefed<nsINodeInfo> aNodeInfo); - nsSVGSymbolElement(already_AddRefed<nsINodeInfo> aNodeInfo); + friend nsresult (::NS_NewSVGSymbolElement(nsIContent **aResult, + already_AddRefed<nsINodeInfo> aNodeInfo)); + SVGSymbolElement(already_AddRefed<nsINodeInfo> aNodeInfo); + virtual JSObject* WrapNode(JSContext *cx, JSObject *scope, bool *triedToWrap) MOZ_OVERRIDE; public: // interfaces: NS_DECL_ISUPPORTS_INHERITED NS_DECL_NSIDOMSVGSYMBOLELEMENT NS_DECL_NSIDOMSVGFITTOVIEWBOX @@ -43,105 +48,25 @@ public: // nsIContent interface NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const; virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const; virtual nsXPCClassInfo* GetClassInfo(); virtual nsIDOMNode* AsDOMNode() { return this; } + + // WebIDL + already_AddRefed<nsIDOMSVGAnimatedRect> ViewBox(); + already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> PreserveAspectRatio(); + protected: virtual nsSVGViewBox *GetViewBox(); virtual SVGAnimatedPreserveAspectRatio *GetPreserveAspectRatio(); nsSVGViewBox mViewBox; SVGAnimatedPreserveAspectRatio mPreserveAspectRatio; }; -NS_IMPL_NS_NEW_SVG_ELEMENT(Symbol) - -//---------------------------------------------------------------------- -// nsISupports methods - -NS_IMPL_ADDREF_INHERITED(nsSVGSymbolElement,nsSVGSymbolElementBase) -NS_IMPL_RELEASE_INHERITED(nsSVGSymbolElement,nsSVGSymbolElementBase) - -DOMCI_NODE_DATA(SVGSymbolElement, nsSVGSymbolElement) - -NS_INTERFACE_TABLE_HEAD(nsSVGSymbolElement) - NS_NODE_INTERFACE_TABLE5(nsSVGSymbolElement, nsIDOMNode, nsIDOMElement, - nsIDOMSVGElement, nsIDOMSVGFitToViewBox, - nsIDOMSVGSymbolElement) - NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGSymbolElement) -NS_INTERFACE_MAP_END_INHERITING(nsSVGSymbolElementBase) - -//---------------------------------------------------------------------- -// Implementation - -nsSVGSymbolElement::nsSVGSymbolElement(already_AddRefed<nsINodeInfo> aNodeInfo) - : nsSVGSymbolElementBase(aNodeInfo) -{ -} - - -//---------------------------------------------------------------------- -// nsIDOMNode methods - -NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGSymbolElement) - -//---------------------------------------------------------------------- -// nsIDOMSVGFitToViewBox methods - -/* readonly attribute nsIDOMSVGAnimatedRect viewBox; */ -NS_IMETHODIMP nsSVGSymbolElement::GetViewBox(nsIDOMSVGAnimatedRect * *aViewBox) -{ - return mViewBox.ToDOMAnimatedRect(aViewBox, this); -} +} // namespace dom +} // namespace mozilla -/* readonly attribute SVGPreserveAspectRatio preserveAspectRatio; */ -NS_IMETHODIMP -nsSVGSymbolElement::GetPreserveAspectRatio(nsISupports - **aPreserveAspectRatio) -{ - nsRefPtr<DOMSVGAnimatedPreserveAspectRatio> ratio; - mPreserveAspectRatio.ToDOMAnimatedPreserveAspectRatio(getter_AddRefs(ratio), this); - ratio.forget(aPreserveAspectRatio); - return NS_OK; -} - -//---------------------------------------------------------------------- -// nsIContent methods - -NS_IMETHODIMP_(bool) -nsSVGSymbolElement::IsAttributeMapped(const nsIAtom* name) const -{ - static const MappedAttributeEntry* const map[] = { - sColorMap, - sFEFloodMap, - sFillStrokeMap, - sFiltersMap, - sFontSpecificationMap, - sGradientStopMap, - sGraphicsMap, - sLightingEffectsMap, - sMarkersMap, - sTextContentElementsMap, - sViewportsMap - }; - - return FindAttributeDependence(name, map) || - nsSVGSymbolElementBase::IsAttributeMapped(name); -} - -//---------------------------------------------------------------------- -// nsSVGElement methods - -nsSVGViewBox * -nsSVGSymbolElement::GetViewBox() -{ - return &mViewBox; -} - -SVGAnimatedPreserveAspectRatio * -nsSVGSymbolElement::GetPreserveAspectRatio() -{ - return &mPreserveAspectRatio; -} +#endif // mozilla_dom_SVGSymbolElement_h
--- a/content/svg/content/src/SVGTransformableElement.cpp +++ b/content/svg/content/src/SVGTransformableElement.cpp @@ -15,31 +15,19 @@ namespace dom { //---------------------------------------------------------------------- // nsISupports methods NS_IMPL_ADDREF_INHERITED(SVGTransformableElement, SVGLocatableElement) NS_IMPL_RELEASE_INHERITED(SVGTransformableElement, SVGLocatableElement) NS_INTERFACE_MAP_BEGIN(SVGTransformableElement) - NS_INTERFACE_MAP_ENTRY(nsIDOMSVGTransformable) + NS_INTERFACE_MAP_ENTRY(mozilla::dom::SVGTransformableElement) NS_INTERFACE_MAP_END_INHERITING(SVGLocatableElement) - -//---------------------------------------------------------------------- -// nsIDOMSVGTransformable methods -/* readonly attribute nsISupports transform; */ - -NS_IMETHODIMP -SVGTransformableElement::GetTransform(nsISupports **aTransform) -{ - *aTransform = Transform().get(); - return NS_OK; -} - already_AddRefed<DOMSVGAnimatedTransformList> SVGTransformableElement::Transform() { // We're creating a DOM wrapper, so we must tell GetAnimatedTransformList // to allocate the SVGAnimatedTransformList if it hasn't already done so: return DOMSVGAnimatedTransformList::GetDOMWrapper( GetAnimatedTransformList(DO_ALLOCATE), this).get();
--- a/content/svg/content/src/SVGTransformableElement.h +++ b/content/svg/content/src/SVGTransformableElement.h @@ -2,39 +2,36 @@ /* 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/. */ #ifndef SVGTransformableElement_h #define SVGTransformableElement_h #include "mozilla/dom/SVGLocatableElement.h" -#include "nsIDOMSVGTransformable.h" #include "gfxMatrix.h" #include "SVGAnimatedTransformList.h" #define MOZILLA_SVGTRANSFORMABLEELEMENT_IID \ { 0x77888cba, 0x0b43, 0x4654, \ {0x96, 0x3c, 0xf5, 0x50, 0xfc, 0xb5, 0x5e, 0x32}} namespace mozilla { class DOMSVGAnimatedTransformList; namespace dom { -class SVGTransformableElement : public SVGLocatableElement, - public nsIDOMSVGTransformable +class SVGTransformableElement : public SVGLocatableElement { public: SVGTransformableElement(already_AddRefed<nsINodeInfo> aNodeInfo) : SVGLocatableElement(aNodeInfo) {} virtual ~SVGTransformableElement() {} NS_DECLARE_STATIC_IID_ACCESSOR(MOZILLA_SVGTRANSFORMABLEELEMENT_IID) NS_DECL_ISUPPORTS_INHERITED - NS_DECL_NSIDOMSVGTRANSFORMABLE // WebIDL already_AddRefed<DOMSVGAnimatedTransformList> Transform(); // nsIContent interface NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const; nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
rename from content/svg/content/src/nsSVGUseElement.cpp rename to content/svg/content/src/SVGUseElement.cpp --- a/content/svg/content/src/nsSVGUseElement.cpp +++ b/content/svg/content/src/SVGUseElement.cpp @@ -1,236 +1,280 @@ /* -*- Mode: C++; 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 "mozilla/Util.h" -#include "nsSVGUseElement.h" +#include "mozilla/dom/SVGUseElement.h" +#include "mozilla/dom/SVGUseElementBinding.h" #include "nsIDOMSVGGElement.h" #include "nsGkAtoms.h" #include "mozilla/dom/SVGSVGElement.h" #include "nsIDOMSVGSymbolElement.h" #include "nsIDocument.h" #include "nsIPresShell.h" #include "mozilla/dom/Element.h" #include "nsContentUtils.h" -using namespace mozilla; -using namespace mozilla::dom; +DOMCI_NODE_DATA(SVGUseElement, mozilla::dom::SVGUseElement) + +NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(Use) + +namespace mozilla { +namespace dom { + +JSObject* +SVGUseElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap) +{ + return SVGUseElementBinding::Wrap(aCx, aScope, this, aTriedToWrap); +} //////////////////////////////////////////////////////////////////////// // implementation -nsSVGElement::LengthInfo nsSVGUseElement::sLengthInfo[4] = +nsSVGElement::LengthInfo SVGUseElement::sLengthInfo[4] = { { &nsGkAtoms::x, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::X }, { &nsGkAtoms::y, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::Y }, { &nsGkAtoms::width, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::X }, { &nsGkAtoms::height, 0, nsIDOMSVGLength::SVG_LENGTHTYPE_NUMBER, SVGContentUtils::Y }, }; -nsSVGElement::StringInfo nsSVGUseElement::sStringInfo[1] = +nsSVGElement::StringInfo SVGUseElement::sStringInfo[1] = { { &nsGkAtoms::href, kNameSpaceID_XLink, true } }; -NS_IMPL_NS_NEW_SVG_ELEMENT(Use) - //---------------------------------------------------------------------- // nsISupports methods -NS_IMPL_CYCLE_COLLECTION_CLASS(nsSVGUseElement) -NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsSVGUseElement, - nsSVGUseElementBase) +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(SVGUseElement, + SVGUseElementBase) nsAutoScriptBlocker scriptBlocker; NS_IMPL_CYCLE_COLLECTION_UNLINK(mOriginal) tmp->DestroyAnonymousContent(); tmp->UnlinkSource(); NS_IMPL_CYCLE_COLLECTION_UNLINK_END -NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsSVGUseElement, - nsSVGUseElementBase) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(SVGUseElement, + SVGUseElementBase) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOriginal) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mClone) tmp->mSource.Traverse(&cb); NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END -NS_IMPL_ADDREF_INHERITED(nsSVGUseElement,nsSVGUseElementBase) -NS_IMPL_RELEASE_INHERITED(nsSVGUseElement,nsSVGUseElementBase) +NS_IMPL_ADDREF_INHERITED(SVGUseElement,SVGUseElementBase) +NS_IMPL_RELEASE_INHERITED(SVGUseElement,SVGUseElementBase) -DOMCI_NODE_DATA(SVGUseElement, nsSVGUseElement) - -NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(nsSVGUseElement) - NS_NODE_INTERFACE_TABLE6(nsSVGUseElement, nsIDOMNode, nsIDOMElement, +NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(SVGUseElement) + NS_NODE_INTERFACE_TABLE6(SVGUseElement, nsIDOMNode, nsIDOMElement, nsIDOMSVGElement, nsIDOMSVGURIReference, nsIDOMSVGUseElement, nsIMutationObserver) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGUseElement) - if (aIID.Equals(NS_GET_IID(nsSVGUseElement))) + if (aIID.Equals(NS_GET_IID(mozilla::dom::SVGUseElement))) foundInterface = reinterpret_cast<nsISupports*>(this); else -NS_INTERFACE_MAP_END_INHERITING(nsSVGUseElementBase) +NS_INTERFACE_MAP_END_INHERITING(SVGUseElementBase) //---------------------------------------------------------------------- // Implementation #ifdef _MSC_VER // Disable "warning C4355: 'this' : used in base member initializer list". // We can ignore that warning because we know that mSource's constructor // doesn't dereference the pointer passed to it. #pragma warning(push) #pragma warning(disable:4355) #endif -nsSVGUseElement::nsSVGUseElement(already_AddRefed<nsINodeInfo> aNodeInfo)