From 38ebed24c21459c1f8bdf83eaa3dcb4abf5e730e Mon Sep 17 00:00:00 2001 From: Alexandre Poirot Date: Wed, 11 Oct 2017 17:35:09 +0200 Subject: [PATCH 01/78] Bug 1408182 - Replace ImmutableJS by plain JS code; r=rickychien MozReview-Commit-ID: 4f9Bv3XDuoc --HG-- extra : rebase_source : 834d1cfae3e32054fcaad6faa3569c4c3a885287 --- devtools/client/netmonitor/.eslintrc.js | 6 + .../src/components/RequestListContent.js | 2 +- .../src/components/StatisticsPanel.js | 4 +- .../netmonitor/src/components/Toolbar.js | 2 +- .../netmonitor/src/reducers/requests.js | 357 ++++++++++-------- .../netmonitor/src/selectors/requests.js | 29 +- .../src/selectors/timing-markers.js | 2 +- .../client/netmonitor/src/selectors/ui.js | 2 +- 8 files changed, 228 insertions(+), 176 deletions(-) diff --git a/devtools/client/netmonitor/.eslintrc.js b/devtools/client/netmonitor/.eslintrc.js index a7326d498044..2f8bf01fe6ee 100644 --- a/devtools/client/netmonitor/.eslintrc.js +++ b/devtools/client/netmonitor/.eslintrc.js @@ -20,4 +20,10 @@ module.exports = { /* eslint-disable max-len */ "mozilla/reject-some-requires": ["error", "^(chrome|chrome:.*|resource:.*|devtools/server/.*|.*\\.jsm|devtools/shared/platform/(chome|content)/.*)$"], }, + + "parserOptions": { + "ecmaFeatures": { + experimentalObjectRestSpread: true, + }, + }, }; diff --git a/devtools/client/netmonitor/src/components/RequestListContent.js b/devtools/client/netmonitor/src/components/RequestListContent.js index 537fa6282ae9..1a6cf81ba7ad 100644 --- a/devtools/client/netmonitor/src/components/RequestListContent.js +++ b/devtools/client/netmonitor/src/components/RequestListContent.js @@ -37,7 +37,7 @@ class RequestListContent extends Component { connector: PropTypes.object.isRequired, columns: PropTypes.object.isRequired, dispatch: PropTypes.func.isRequired, - displayedRequests: PropTypes.object.isRequired, + displayedRequests: PropTypes.array.isRequired, firstRequestStartedMillis: PropTypes.number.isRequired, fromCache: PropTypes.bool, onCauseBadgeMouseDown: PropTypes.func.isRequired, diff --git a/devtools/client/netmonitor/src/components/StatisticsPanel.js b/devtools/client/netmonitor/src/components/StatisticsPanel.js index ff0c8f809b79..c97300ffbab5 100644 --- a/devtools/client/netmonitor/src/components/StatisticsPanel.js +++ b/devtools/client/netmonitor/src/components/StatisticsPanel.js @@ -40,7 +40,7 @@ class StatisticsPanel extends Component { connector: PropTypes.object.isRequired, closeStatistics: PropTypes.func.isRequired, enableRequestFilterTypeOnly: PropTypes.func.isRequired, - requests: PropTypes.object, + requests: PropTypes.array, }; } @@ -67,7 +67,7 @@ class StatisticsPanel extends Component { MediaQueryList.addListener(this.onLayoutChange); const { requests } = this.props; - let ready = requests && !requests.isEmpty() && requests.every((req) => + let ready = requests && requests.length && requests.every((req) => req.contentSize !== undefined && req.mimeType && req.responseHeaders && req.status !== undefined && req.totalTime !== undefined ); diff --git a/devtools/client/netmonitor/src/components/Toolbar.js b/devtools/client/netmonitor/src/components/Toolbar.js index 07e958b77103..688e73d2f6b3 100644 --- a/devtools/client/netmonitor/src/components/Toolbar.js +++ b/devtools/client/netmonitor/src/components/Toolbar.js @@ -71,7 +71,7 @@ class Toolbar extends Component { toggleBrowserCache: PropTypes.func.isRequired, browserCacheDisabled: PropTypes.bool.isRequired, toggleRequestFilterType: PropTypes.func.isRequired, - filteredRequests: PropTypes.object.isRequired, + filteredRequests: PropTypes.array.isRequired, }; } diff --git a/devtools/client/netmonitor/src/reducers/requests.js b/devtools/client/netmonitor/src/reducers/requests.js index 3231b81b99df..dcb01f9400b6 100644 --- a/devtools/client/netmonitor/src/reducers/requests.js +++ b/devtools/client/netmonitor/src/reducers/requests.js @@ -4,7 +4,6 @@ "use strict"; -const I = require("devtools/client/shared/vendor/immutable"); const { getUrlDetails, processNetworkUpdates, @@ -21,59 +20,173 @@ const { UPDATE_REQUEST, } = require("../constants"); -const Request = I.Record({ - id: null, - // Set to true in case of a request that's being edited as part of "edit and resend" - isCustom: false, - // Request properties - at the beginning, they are unknown and are gradually filled in - startedMillis: undefined, - endedMillis: undefined, - method: undefined, - url: undefined, - urlDetails: undefined, - remotePort: undefined, - remoteAddress: undefined, - isXHR: undefined, - cause: undefined, - fromCache: undefined, - fromServiceWorker: undefined, - status: undefined, - statusText: undefined, - httpVersion: undefined, - securityState: undefined, - securityInfo: undefined, - mimeType: "text/plain", - contentSize: undefined, - transferredSize: undefined, - totalTime: undefined, - eventTimings: undefined, - headersSize: undefined, - // Text value is used for storing custom request query - // which only appears when user edit the custom requst form - customQueryValue: undefined, - requestHeaders: undefined, - requestHeadersFromUploadStream: undefined, - requestCookies: undefined, - requestPostData: undefined, - responseHeaders: undefined, - responseCookies: undefined, - responseContent: undefined, - responseContentAvailable: false, - formDataSections: undefined, -}); +/** + * This structure stores list of all HTTP requests received + * from the backend. It's using plain JS structures to store + * data instead of ImmutableJS, which is performance expensive. + */ +function Requests() { + return { + // Map with all requests (key = actor ID, value = request object) + requests: mapNew(), + // Selected request ID + selectedId: null, + preselectedId: null, + // True if the monitor is recording HTTP traffic + recording: true, + // Auxiliary fields to hold requests stats + firstStartedMillis: +Infinity, + lastEndedMillis: -Infinity, + }; +} -const Requests = I.Record({ - // The collection of requests (keyed by id) - requests: I.Map(), - // Selection state - selectedId: null, - preselectedId: null, - // Auxiliary fields to hold requests stats - firstStartedMillis: +Infinity, - lastEndedMillis: -Infinity, - // Recording state - recording: true, -}); +/** + * This reducer is responsible for maintaining list of request + * within the Network panel. + */ +function requestsReducer(state = Requests(), action) { + switch (action.type) { + // Appending new request into the list/map. + case ADD_REQUEST: { + let nextState = { ...state }; + + let newRequest = { + id: action.id, + ...action.data, + urlDetails: getUrlDetails(action.data.url), + }; + + nextState.requests = mapSet(state.requests, newRequest.id, newRequest); + + // Update the started/ended timestamps. + let { startedMillis } = action.data; + if (startedMillis < state.firstStartedMillis) { + nextState.firstStartedMillis = startedMillis; + } + if (startedMillis > state.lastEndedMillis) { + nextState.lastEndedMillis = startedMillis; + } + + // Select the request if it was preselected and there is no other selection. + if (state.preselectedId && state.preselectedId === action.id) { + nextState.selectedId = state.selectedId || state.preselectedId; + nextState.preselectedId = null; + } + + return nextState; + } + + // Update an existing request (with received data). + case UPDATE_REQUEST: { + let { requests, lastEndedMillis } = state; + + let request = requests.get(action.id); + if (!request) { + return state; + } + + request = { + ...request, + ...processNetworkUpdates(action.data), + }; + + return { + ...state, + requests: mapSet(state.requests, action.id, request), + lastEndedMillis: lastEndedMillis, + }; + } + + // Remove all requests in the list. Create fresh new state + // object, but keep value of the `recording` field. + case CLEAR_REQUESTS: { + return { + ...Requests(), + recording: state.recording, + }; + } + + // Select specific request. + case SELECT_REQUEST: { + return { + ...state, + selectedId: action.id, + }; + } + + // Clone selected request for re-send. + case CLONE_SELECTED_REQUEST: { + let { requests, selectedId } = state; + + if (!selectedId) { + return state; + } + + let clonedRequest = requests.get(selectedId); + if (!clonedRequest) { + return state; + } + + let newRequest = { + id: clonedRequest.id + "-clone", + method: clonedRequest.method, + url: clonedRequest.url, + urlDetails: clonedRequest.urlDetails, + requestHeaders: clonedRequest.requestHeaders, + requestPostData: clonedRequest.requestPostData, + isCustom: true + }; + + return { + ...state, + requests: mapSet(requests, newRequest.id, newRequest), + selectedId: newRequest.id, + }; + } + + // Removing temporary cloned request (created for re-send, but canceled). + case REMOVE_SELECTED_CUSTOM_REQUEST: { + return closeCustomRequest(state); + } + + // Re-sending an existing request. + case SEND_CUSTOM_REQUEST: { + // When a new request with a given id is added in future, select it immediately. + // where we know in advance the ID of the request, at a time when it + // wasn't sent yet. + return closeCustomRequest(state.set("preselectedId", action.id)); + } + + // Pause/resume button clicked. + case TOGGLE_RECORDING: { + return { + ...state, + recording: !state.recording, + }; + } + + // Side bar with request details opened. + case OPEN_NETWORK_DETAILS: { + let nextState = { ...state }; + if (!action.open) { + nextState.selectedId = null; + return nextState; + } + + if (!state.selectedId && !state.requests.isEmpty()) { + nextState.selectedId = [...state.requests.values()][0].id; + return nextState; + } + + return state; + } + + default: + return state; + } +} + +// Helpers /** * Remove the currently selected custom request. @@ -92,119 +205,41 @@ function closeCustomRequest(state) { return state; } - return state.withMutations(st => { - st.requests = st.requests.delete(selectedId); - st.selectedId = null; - }); + return { + ...state, + requests: mapDelete(state.requests, selectedId), + selectedId: null, + }; } -function requestsReducer(state = new Requests(), action) { - switch (action.type) { - case ADD_REQUEST: { - return state.withMutations(st => { - let newRequest = new Request(Object.assign( - { id: action.id }, - action.data, - { urlDetails: getUrlDetails(action.data.url) } - )); - st.requests = st.requests.set(newRequest.id, newRequest); +// Immutability helpers +// FIXME The following helper API need refactoring, see bug 1418969. - // Update the started/ended timestamps - let { startedMillis } = action.data; - if (startedMillis < st.firstStartedMillis) { - st.firstStartedMillis = startedMillis; - } - if (startedMillis > st.lastEndedMillis) { - st.lastEndedMillis = startedMillis; - } +/** + * Clone an existing map. + */ +function mapNew(map) { + let newMap = new Map(map); + newMap.isEmpty = () => newMap.size == 0; + newMap.valueSeq = () => [...newMap.values()]; + return newMap; +} - // Select the request if it was preselected and there is no other selection - if (st.preselectedId && st.preselectedId === action.id) { - st.selectedId = st.selectedId || st.preselectedId; - st.preselectedId = null; - } - }); - } - case CLEAR_REQUESTS: { - return new Requests({ - recording: state.recording - }); - } - case CLONE_SELECTED_REQUEST: { - let { requests, selectedId } = state; +/** + * Append new item into existing map and return new map. + */ +function mapSet(map, key, value) { + let newMap = mapNew(map); + return newMap.set(key, value); +} - if (!selectedId) { - return state; - } - - let clonedRequest = requests.get(selectedId); - if (!clonedRequest) { - return state; - } - - let newRequest = new Request({ - id: clonedRequest.id + "-clone", - method: clonedRequest.method, - url: clonedRequest.url, - urlDetails: clonedRequest.urlDetails, - requestHeaders: clonedRequest.requestHeaders, - requestPostData: clonedRequest.requestPostData, - isCustom: true - }); - - return state.withMutations(st => { - st.requests = requests.set(newRequest.id, newRequest); - st.selectedId = newRequest.id; - }); - } - case OPEN_NETWORK_DETAILS: { - if (!action.open) { - return state.set("selectedId", null); - } - - if (!state.selectedId && !state.requests.isEmpty()) { - return state.set("selectedId", state.requests.first().id); - } - - return state; - } - case REMOVE_SELECTED_CUSTOM_REQUEST: { - return closeCustomRequest(state); - } - case SELECT_REQUEST: { - return state.set("selectedId", action.id); - } - case SEND_CUSTOM_REQUEST: { - // When a new request with a given id is added in future, select it immediately. - // where we know in advance the ID of the request, at a time when it - // wasn't sent yet. - return closeCustomRequest(state.set("preselectedId", action.id)); - } - case TOGGLE_RECORDING: { - return state.set("recording", !state.recording); - } - case UPDATE_REQUEST: { - let { requests, lastEndedMillis } = state; - - let updatedRequest = requests.get(action.id); - if (!updatedRequest) { - return state; - } - - updatedRequest = updatedRequest.withMutations(request => { - let values = processNetworkUpdates(action.data); - request = Object.assign(request, values); - }); - - return state.withMutations(st => { - st.requests = requests.set(updatedRequest.id, updatedRequest); - st.lastEndedMillis = lastEndedMillis; - }); - } - - default: - return state; - } +/** + * Remove an item from existing map and return new map. + */ +function mapDelete(map, key) { + let newMap = mapNew(map); + newMap.requests.delete(key); + return newMap; } module.exports = { diff --git a/devtools/client/netmonitor/src/selectors/requests.js b/devtools/client/netmonitor/src/selectors/requests.js index b7950ef029f1..50aa4688e185 100644 --- a/devtools/client/netmonitor/src/selectors/requests.js +++ b/devtools/client/netmonitor/src/selectors/requests.js @@ -56,9 +56,9 @@ const getTypeFilterFn = createSelector( ); const getSortFn = createSelector( - state => state.requests.requests, + state => state.requests, state => state.sort, - (requests, sort) => { + ({ requests }, sort) => { const sorter = Sorters[sort.type || "waterfall"]; const ascending = sort.ascending ? +1 : -1; return (a, b) => ascending * sortWithClones(requests, sorter, a, b); @@ -66,23 +66,34 @@ const getSortFn = createSelector( ); const getSortedRequests = createSelector( - state => state.requests.requests, + state => state.requests, getSortFn, - (requests, sortFn) => requests.valueSeq().sort(sortFn).toList() + ({ requests }, sortFn) => { + let arr = requests.valueSeq().sort(sortFn); + arr.get = index => arr[index]; + arr.isEmpty = () => this.length == 0; + arr.size = arr.length; + return arr; + } ); const getDisplayedRequests = createSelector( - state => state.requests.requests, + state => state.requests, getFilterFn, getSortFn, - (requests, filterFn, sortFn) => requests.valueSeq() - .filter(filterFn).sort(sortFn).toList() + ({ requests }, filterFn, sortFn) => { + let arr = requests.valueSeq().filter(filterFn).sort(sortFn); + arr.get = index => arr[index]; + arr.isEmpty = () => this.length == 0; + arr.size = arr.length; + return arr; + } ); const getTypeFilteredRequests = createSelector( - state => state.requests.requests, + state => state.requests, getTypeFilterFn, - (requests, filterFn) => requests.valueSeq().filter(filterFn).toList() + ({ requests }, filterFn) => requests.valueSeq().filter(filterFn) ); const getDisplayedRequestsSummary = createSelector( diff --git a/devtools/client/netmonitor/src/selectors/timing-markers.js b/devtools/client/netmonitor/src/selectors/timing-markers.js index ee72ccddac16..1c018698cffc 100644 --- a/devtools/client/netmonitor/src/selectors/timing-markers.js +++ b/devtools/client/netmonitor/src/selectors/timing-markers.js @@ -5,7 +5,7 @@ "use strict"; function getDisplayedTimingMarker(state, marker) { - return state.timingMarkers.get(marker) - state.requests.get("firstStartedMillis"); + return state.timingMarkers.get(marker) - state.requests.firstStartedMillis; } module.exports = { diff --git a/devtools/client/netmonitor/src/selectors/ui.js b/devtools/client/netmonitor/src/selectors/ui.js index 44aaf4504032..b81e4ee320d0 100644 --- a/devtools/client/netmonitor/src/selectors/ui.js +++ b/devtools/client/netmonitor/src/selectors/ui.js @@ -8,7 +8,7 @@ const { REQUESTS_WATERFALL } = require("../constants"); const { getDisplayedRequests } = require("./requests"); function isNetworkDetailsToggleButtonDisabled(state) { - return getDisplayedRequests(state).isEmpty(); + return getDisplayedRequests(state).length == 0; } const EPSILON = 0.001; From 04927bc0587405e17e9a6f1b31583282de34fd6f Mon Sep 17 00:00:00 2001 From: Mike Hommey Date: Tue, 21 Nov 2017 14:11:14 +0900 Subject: [PATCH 02/78] Bug 1419269 - Support installing mercurial on Debian versions != 9. r=gps --HG-- extra : rebase_source : 187146a14083960b2175f907f466a46ad9091ce8 --- taskcluster/docker/recipes/install-mercurial.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/taskcluster/docker/recipes/install-mercurial.sh b/taskcluster/docker/recipes/install-mercurial.sh index 5b5d55dbded1..bae70b13fc97 100755 --- a/taskcluster/docker/recipes/install-mercurial.sh +++ b/taskcluster/docker/recipes/install-mercurial.sh @@ -30,11 +30,14 @@ if [ -f /etc/lsb-release ]; then elif [ -f /etc/os-release ]; then . /etc/os-release - if [ "${ID}" = "debian" -a "${VERSION_ID}" = "9" ]; then + if [ "${ID}" = "debian" ]; then if [ -f /usr/bin/pip2 ]; then PIP_PATH=/usr/bin/pip2 + elif [ -f /usr/bin/pip ]; then + # Versions of debian that don't have pip2 have pip pointing to the python2 version. + PIP_PATH=/usr/bin/pip else - echo "We currently require Python 2.7 and /usr/bin/pip2 to run Mercurial" + echo "We currently require Python 2.7 and pip to run Mercurial" exit 1 fi else From a661b32865fd4e8d591e0e678a58fa317fe2a93a Mon Sep 17 00:00:00 2001 From: Ethan Lin Date: Mon, 20 Nov 2017 10:36:14 +0800 Subject: [PATCH 03/78] Bug 1418869 - Do not try to share the fallback images. r=aosmond The flag of force update is only for fallback items. Fallback items can't share the images with other items. So I replace 'aForceUpdate' with 'aFallback' and remove some unnecessary checks. MozReview-Commit-ID: Dcu95FZXlUz --HG-- extra : rebase_source : 1ec96e0b5d39cc5760b4b5490c5ca9ccbc1933c6 --- gfx/layers/ipc/SharedSurfacesChild.cpp | 13 ++++------ gfx/layers/ipc/SharedSurfacesChild.h | 2 -- gfx/layers/wr/WebRenderUserData.cpp | 33 +++++++++++++------------- gfx/layers/wr/WebRenderUserData.h | 2 +- 4 files changed, 23 insertions(+), 27 deletions(-) diff --git a/gfx/layers/ipc/SharedSurfacesChild.cpp b/gfx/layers/ipc/SharedSurfacesChild.cpp index 0b183318146c..3c1a97394f36 100644 --- a/gfx/layers/ipc/SharedSurfacesChild.cpp +++ b/gfx/layers/ipc/SharedSurfacesChild.cpp @@ -92,7 +92,6 @@ public: wr::ImageKey UpdateKey(WebRenderLayerManager* aManager, wr::IpcResourceUpdateQueue& aResources, - bool aForceUpdate, uint32_t aGenerationId) { MOZ_ASSERT(aManager); @@ -114,7 +113,7 @@ public: mKeys.RemoveElementAt(i); } else if (entry.mManager == aManager) { found = true; - if (aForceUpdate || entry.mGenerationId != aGenerationId) { + if (entry.mGenerationId != aGenerationId) { aManager->AddImageKeyForDiscard(entry.mImageKey); entry.mGenerationId = aGenerationId; entry.mImageKey = aManager->WrBridge()->GetNextImageKey(); @@ -151,7 +150,6 @@ SharedSurfacesChild::DestroySharedUserData(void* aClosure) SharedSurfacesChild::Share(SourceSurfaceSharedData* aSurface, WebRenderLayerManager* aManager, wr::IpcResourceUpdateQueue& aResources, - bool aForceUpdate, uint32_t aGenerationId, wr::ImageKey& aKey) { @@ -176,7 +174,7 @@ SharedSurfacesChild::Share(SourceSurfaceSharedData* aSurface, data->SetId(manager->GetNextExternalImageId()); } else if (data->IsShared()) { // It has already been shared with the GPU process, reuse the id. - aKey = data->UpdateKey(aManager, aResources, aForceUpdate, aGenerationId); + aKey = data->UpdateKey(aManager, aResources, aGenerationId); return NS_OK; } @@ -194,7 +192,7 @@ SharedSurfacesChild::Share(SourceSurfaceSharedData* aSurface, if (pid == base::GetCurrentProcId()) { SharedSurfacesParent::AddSameProcess(data->Id(), aSurface); data->MarkShared(); - aKey = data->UpdateKey(aManager, aResources, aForceUpdate, aGenerationId); + aKey = data->UpdateKey(aManager, aResources, aGenerationId); return NS_OK; } @@ -229,7 +227,7 @@ SharedSurfacesChild::Share(SourceSurfaceSharedData* aSurface, SurfaceDescriptorShared(aSurface->GetSize(), aSurface->Stride(), format, handle)); - aKey = data->UpdateKey(aManager, aResources, aForceUpdate, aGenerationId); + aKey = data->UpdateKey(aManager, aResources, aGenerationId); return NS_OK; } @@ -237,7 +235,6 @@ SharedSurfacesChild::Share(SourceSurfaceSharedData* aSurface, SharedSurfacesChild::Share(ImageContainer* aContainer, WebRenderLayerManager* aManager, wr::IpcResourceUpdateQueue& aResources, - bool aForceUpdate, wr::ImageKey& aKey) { MOZ_ASSERT(NS_IsMainThread()); @@ -266,7 +263,7 @@ SharedSurfacesChild::Share(ImageContainer* aContainer, auto sharedSurface = static_cast(surface.get()); return Share(sharedSurface, aManager, aResources, - aForceUpdate, generation, aKey); + generation, aKey); } /* static */ void diff --git a/gfx/layers/ipc/SharedSurfacesChild.h b/gfx/layers/ipc/SharedSurfacesChild.h index 1c28be01fd59..8991093327fb 100644 --- a/gfx/layers/ipc/SharedSurfacesChild.h +++ b/gfx/layers/ipc/SharedSurfacesChild.h @@ -33,14 +33,12 @@ public: static nsresult Share(gfx::SourceSurfaceSharedData* aSurface, WebRenderLayerManager* aManager, wr::IpcResourceUpdateQueue& aResources, - bool aForceUpdate, uint32_t aGenerationId, wr::ImageKey& aKey); static nsresult Share(ImageContainer* aContainer, WebRenderLayerManager* aManager, wr::IpcResourceUpdateQueue& aResources, - bool aForceUpdate, wr::ImageKey& aKey); private: diff --git a/gfx/layers/wr/WebRenderUserData.cpp b/gfx/layers/wr/WebRenderUserData.cpp index fd7f563d8969..3b209b3ecba0 100644 --- a/gfx/layers/wr/WebRenderUserData.cpp +++ b/gfx/layers/wr/WebRenderUserData.cpp @@ -93,7 +93,7 @@ WebRenderImageData::ClearCachedResources() Maybe WebRenderImageData::UpdateImageKey(ImageContainer* aContainer, wr::IpcResourceUpdateQueue& aResources, - bool aForceUpdate) + bool aFallback) { MOZ_ASSERT(aContainer); @@ -102,21 +102,22 @@ WebRenderImageData::UpdateImageKey(ImageContainer* aContainer, } wr::WrImageKey key; - nsresult rv = SharedSurfacesChild::Share(aContainer, mWRManager, aResources, - aForceUpdate, key); - if (NS_SUCCEEDED(rv)) { - // Ensure that any previously owned keys are released before replacing. We - // don't own this key, the surface itself owns it, so that it can be shared - // across multiple elements. - ClearImageKey(); - mKey = Some(key); - return mKey; - } + if (!aFallback) { + nsresult rv = SharedSurfacesChild::Share(aContainer, mWRManager, aResources, key); + if (NS_SUCCEEDED(rv)) { + // Ensure that any previously owned keys are released before replacing. We + // don't own this key, the surface itself owns it, so that it can be shared + // across multiple elements. + ClearImageKey(); + mKey = Some(key); + return mKey; + } - if (rv != NS_ERROR_NOT_IMPLEMENTED) { - // We should be using the shared surface but somehow sharing it failed. - ClearImageKey(); - return Nothing(); + if (rv != NS_ERROR_NOT_IMPLEMENTED) { + // We should be using the shared surface but somehow sharing it failed. + ClearImageKey(); + return Nothing(); + } } CreateImageClientIfNeeded(); @@ -139,7 +140,7 @@ WebRenderImageData::UpdateImageKey(ImageContainer* aContainer, } // Reuse old key if generation is not updated. - if (!aForceUpdate && oldCounter == imageClient->GetLastUpdateGenerationCounter() && mKey) { + if (!aFallback && oldCounter == imageClient->GetLastUpdateGenerationCounter() && mKey) { return mKey; } diff --git a/gfx/layers/wr/WebRenderUserData.h b/gfx/layers/wr/WebRenderUserData.h index 5eca227adb77..35f0a5bbeb89 100644 --- a/gfx/layers/wr/WebRenderUserData.h +++ b/gfx/layers/wr/WebRenderUserData.h @@ -85,7 +85,7 @@ public: Maybe UpdateImageKey(ImageContainer* aContainer, wr::IpcResourceUpdateQueue& aResources, - bool aForceUpdate = false); + bool aFallback = false); void CreateAsyncImageWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder, ImageContainer* aContainer, From 980e6321f7ec015e1d7dfb3045abc0277daec7c2 Mon Sep 17 00:00:00 2001 From: James Teh Date: Wed, 15 Nov 2017 09:59:44 +1000 Subject: [PATCH 04/78] Bug 1416986 part 1: Allow an mscom Handler to signal that it knows an interface is definitely not available. r=aklotz If QueryHandlerInterface returns E_NOINTERFACE, the proxy will be queried for the interface. However, the handler might know that the interface is definitely not available and could thus avoid a pointless cross-process call. To facilitate this, the handler can now return S_FALSE to signal that the proxy should not be queried, thus immediately returning E_NOINTERFACE to the client. MozReview-Commit-ID: 4RtBsA9BTOV --HG-- extra : rebase_source : 4b0dcb16c469361c1944b24568ceb83fd0ac09c1 --- ipc/mscom/oop/Handler.cpp | 5 +++++ ipc/mscom/oop/Handler.h | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ipc/mscom/oop/Handler.cpp b/ipc/mscom/oop/Handler.cpp index 79f4a0a2599c..d8afa79f109e 100644 --- a/ipc/mscom/oop/Handler.cpp +++ b/ipc/mscom/oop/Handler.cpp @@ -74,6 +74,11 @@ Handler::InternalQueryInterface(REFIID riid, void** ppv) // Try the handler implementation HRESULT hr = QueryHandlerInterface(mInnerUnk, riid, ppv); + if (hr == S_FALSE) { + // The handler knows this interface is not available, so don't bother + // asking the proxy. + return E_NOINTERFACE; + } if (hr != E_NOINTERFACE) { return hr; } diff --git a/ipc/mscom/oop/Handler.h b/ipc/mscom/oop/Handler.h index 384eb69182df..3d7fc06bbfd2 100644 --- a/ipc/mscom/oop/Handler.h +++ b/ipc/mscom/oop/Handler.h @@ -52,7 +52,11 @@ public: * @param aIid Interface requested, similar to IUnknown::QueryInterface * @param aOutInterface Outparam for the resulting interface to return to the * client. - * @return The usual HRESULT codes similarly to IUnknown::QueryInterface + * @return The usual HRESULT codes similarly to IUnknown::QueryInterface. + * If E_NOINTERFACE is returned, the proxy will be queried. + * If the handler is certain that this interface is not available, + * it can return S_FALSE to avoid querying the proxy. This will be + * translated to E_NOINTERFACE before it is returned to the client. */ virtual HRESULT QueryHandlerInterface(IUnknown* aProxyUnknown, REFIID aIid, void** aOutInterface) = 0; From aebc388fb63cd2476188544c722cb58ce507a4a1 Mon Sep 17 00:00:00 2001 From: James Teh Date: Wed, 15 Nov 2017 12:18:18 +1000 Subject: [PATCH 05/78] Bug 1416986 part 2: Include interfaces the client is likely to request in the accessible handler payload. r=aklotz Now that virtual buffers have to render across processes, we want to eliminate as many cross-process calls as possible. This includes QueryInterface calls, since buffers query for several interfaces on every node they visit. To avoid these cross-process QI calls, we include interfaces clients are likely to request in the handler payload. This way, they get marshaled in the single call used to retrieve the object. This patch does the following: 1. Passes the interceptor when building the payload. We need this so we can get interceptors for other interfaces. 2. Splits the payload into two main parts: a static part and a dynamic part. The (new) static part contains the interface pointers. The dynamic part contains the rest. This is necessary because the refresh call cannot pass the interceptor, but the interceptor is needed to build the static part. Also, re-building the static part is pointless when refreshing. 3. Includes the interface pointers in the payload (BuildStaticIA2Data). The pointers also have to be cleaned up after marshaling. 4. Releases the interface pointers in the handler after the payload is received. We do this because they're aggregated by the proxy manager as they're unmarshaled. MozReview-Commit-ID: 6VRLMNScgwW --HG-- extra : rebase_source : 249589643b7a69e870962ea55a44849bf03a2693 --- accessible/ipc/win/HandlerProvider.cpp | 148 ++++++++++++++++-- accessible/ipc/win/HandlerProvider.h | 15 +- .../ipc/win/handler/AccessibleHandler.cpp | 38 ++++- accessible/ipc/win/handler/HandlerData.idl | 28 +++- 4 files changed, 199 insertions(+), 30 deletions(-) diff --git a/accessible/ipc/win/HandlerProvider.cpp b/accessible/ipc/win/HandlerProvider.cpp index 09d2906385f5..9d311cacb065 100644 --- a/accessible/ipc/win/HandlerProvider.cpp +++ b/accessible/ipc/win/HandlerProvider.cpp @@ -21,6 +21,7 @@ #include "mozilla/Move.h" #include "mozilla/mscom/AgileReference.h" #include "mozilla/mscom/FastMarshaler.h" +#include "mozilla/mscom/Interceptor.h" #include "mozilla/mscom/MainThreadInvoker.h" #include "mozilla/mscom/Ptr.h" #include "mozilla/mscom/StructStream.h" @@ -97,7 +98,8 @@ HandlerProvider::GetHandler(NotNull aHandlerClsid) } void -HandlerProvider::GetAndSerializePayload(const MutexAutoLock&) +HandlerProvider::GetAndSerializePayload(const MutexAutoLock&, + NotNull aInterceptor) { MOZ_ASSERT(mscom::IsCurrentThreadMTA()); @@ -107,10 +109,11 @@ HandlerProvider::GetAndSerializePayload(const MutexAutoLock&) IA2Payload payload{}; - if (!mscom::InvokeOnMainThread("HandlerProvider::BuildIA2Data", - this, &HandlerProvider::BuildIA2Data, - &payload.mData) || - !payload.mData.mUniqueId) { + if (!mscom::InvokeOnMainThread("HandlerProvider::BuildInitialIA2Data", + this, &HandlerProvider::BuildInitialIA2Data, + aInterceptor, + &payload.mStaticData, &payload.mDynamicData) || + !payload.mDynamicData.mUniqueId) { return; } @@ -124,9 +127,10 @@ HandlerProvider::GetAndSerializePayload(const MutexAutoLock&) mSerializer = MakeUnique(payload, &IA2Payload_Encode); - // Now that we have serialized payload, we should free any BSTRs that were - // allocated in BuildIA2Data. - ClearIA2Data(payload.mData); + // Now that we have serialized payload, we should clean up any + // BSTRs, interfaces, etc. fetched in BuildInitialIA2Data. + CleanupStaticIA2Data(payload.mStaticData); + CleanupDynamicIA2Data(payload.mDynamicData); } HRESULT @@ -142,7 +146,7 @@ HandlerProvider::GetHandlerPayloadSize(NotNull aIntercepto MutexAutoLock lock(mMutex); - GetAndSerializePayload(lock); + GetAndSerializePayload(lock, aInterceptor); if (!mSerializer || !(*mSerializer)) { // Failed payload serialization is non-fatal @@ -182,7 +186,72 @@ private: }; void -HandlerProvider::BuildIA2Data(IA2Data* aOutIA2Data) +HandlerProvider::BuildStaticIA2Data( + NotNull aInterceptor, + StaticIA2Data* aOutData) +{ + MOZ_ASSERT(aOutData); + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(mTargetUnk); + MOZ_ASSERT(IsTargetInterfaceCacheable()); + + // Include interfaces the client is likely to request. + // This is cheap here and saves multiple cross-process calls later. + // These interfaces must be released in CleanupStaticIA2Data! + + // If the target is already an IAccessible2, this pointer is redundant. + // However, the target might be an IAccessibleHyperlink, etc., in which + // case the client will almost certainly QI for IAccessible2. + HRESULT hr = aInterceptor->GetInterceptorForIID(NEWEST_IA2_IID, + (void**)&aOutData->mIA2); + if (FAILED(hr)) { + // IA2 should always be present, so something has + // gone very wrong if this fails. + aOutData->mIA2 = nullptr; + return; + } + + // Some of these interfaces aren't present on all accessibles, + // so it's not a failure if these interfaces can't be fetched. + hr = aInterceptor->GetInterceptorForIID(IID_IEnumVARIANT, + (void**)&aOutData->mIEnumVARIANT); + if (FAILED(hr)) { + aOutData->mIEnumVARIANT = nullptr; + } + + hr = aInterceptor->GetInterceptorForIID(IID_IAccessibleHypertext2, + (void**)&aOutData->mIAHypertext); + if (FAILED(hr)) { + aOutData->mIAHypertext = nullptr; + } + + hr = aInterceptor->GetInterceptorForIID(IID_IAccessibleHyperlink, + (void**)&aOutData->mIAHyperlink); + if (FAILED(hr)) { + aOutData->mIAHyperlink = nullptr; + } + + hr = aInterceptor->GetInterceptorForIID(IID_IAccessibleTable, + (void**)&aOutData->mIATable); + if (FAILED(hr)) { + aOutData->mIATable = nullptr; + } + + hr = aInterceptor->GetInterceptorForIID(IID_IAccessibleTable2, + (void**)&aOutData->mIATable2); + if (FAILED(hr)) { + aOutData->mIATable2 = nullptr; + } + + hr = aInterceptor->GetInterceptorForIID(IID_IAccessibleTableCell, + (void**)&aOutData->mIATableCell); + if (FAILED(hr)) { + aOutData->mIATableCell = nullptr; + } +} + +void +HandlerProvider::BuildDynamicIA2Data(DynamicIA2Data* aOutIA2Data) { MOZ_ASSERT(aOutIA2Data); MOZ_ASSERT(NS_IsMainThread()); @@ -203,7 +272,7 @@ HandlerProvider::BuildIA2Data(IA2Data* aOutIA2Data) }; auto cleanup = [this, aOutIA2Data]() -> void { - ClearIA2Data(*aOutIA2Data); + CleanupDynamicIA2Data(*aOutIA2Data); }; ExecuteWhen onFail(hasFailed, cleanup); @@ -291,10 +360,57 @@ HandlerProvider::BuildIA2Data(IA2Data* aOutIA2Data) } void -HandlerProvider::ClearIA2Data(IA2Data& aData) +HandlerProvider::CleanupStaticIA2Data(StaticIA2Data& aData) +{ + // When CoMarshalInterface writes interfaces out to a stream, it AddRefs. + // Therefore, we must release our references after this. + if (aData.mIA2) { + aData.mIA2->Release(); + } + if (aData.mIEnumVARIANT) { + aData.mIEnumVARIANT->Release(); + } + if (aData.mIAHypertext) { + aData.mIAHypertext->Release(); + } + if (aData.mIAHyperlink) { + aData.mIAHyperlink->Release(); + } + if (aData.mIATable) { + aData.mIATable->Release(); + } + if (aData.mIATable2) { + aData.mIATable2->Release(); + } + if (aData.mIATableCell) { + aData.mIATableCell->Release(); + } + ZeroMemory(&aData, sizeof(StaticIA2Data)); +} + +void +HandlerProvider::CleanupDynamicIA2Data(DynamicIA2Data& aData) { ::VariantClear(&aData.mRole); - ZeroMemory(&aData, sizeof(IA2Data)); + ZeroMemory(&aData, sizeof(DynamicIA2Data)); +} + +void +HandlerProvider::BuildInitialIA2Data( + NotNull aInterceptor, + StaticIA2Data* aOutStaticData, + DynamicIA2Data* aOutDynamicData) +{ + BuildStaticIA2Data(aInterceptor, aOutStaticData); + if (!aOutStaticData->mIA2) { + return; + } + BuildDynamicIA2Data(aOutDynamicData); + if (!aOutDynamicData->mUniqueId) { + // Building dynamic data failed, which means building the payload failed. + // However, we've already built static data, so we must clean this up. + CleanupStaticIA2Data(*aOutStaticData); + } } bool @@ -407,12 +523,12 @@ HandlerProvider::put_HandlerControl(long aPid, IHandlerControl* aCtrl) } HRESULT -HandlerProvider::Refresh(IA2Data* aOutData) +HandlerProvider::Refresh(DynamicIA2Data* aOutData) { MOZ_ASSERT(mscom::IsCurrentThreadMTA()); - if (!mscom::InvokeOnMainThread("HandlerProvider::BuildIA2Data", - this, &HandlerProvider::BuildIA2Data, + if (!mscom::InvokeOnMainThread("HandlerProvider::BuildDynamicIA2Data", + this, &HandlerProvider::BuildDynamicIA2Data, aOutData)) { return E_FAIL; } diff --git a/accessible/ipc/win/HandlerProvider.h b/accessible/ipc/win/HandlerProvider.h index 3aad6830db06..e25f836d01de 100644 --- a/accessible/ipc/win/HandlerProvider.h +++ b/accessible/ipc/win/HandlerProvider.h @@ -54,16 +54,23 @@ public: // IGeckoBackChannel STDMETHODIMP put_HandlerControl(long aPid, IHandlerControl* aCtrl) override; - STDMETHODIMP Refresh(IA2Data* aOutData) override; + STDMETHODIMP Refresh(DynamicIA2Data* aOutData) override; private: ~HandlerProvider() = default; void SetHandlerControlOnMainThread(DWORD aPid, mscom::ProxyUniquePtr aCtrl); - void GetAndSerializePayload(const MutexAutoLock&); - void BuildIA2Data(IA2Data* aOutIA2Data); - static void ClearIA2Data(IA2Data& aData); + void GetAndSerializePayload(const MutexAutoLock&, + NotNull aInterceptor); + void BuildStaticIA2Data(NotNull aInterceptor, + StaticIA2Data* aOutData); + void BuildDynamicIA2Data(DynamicIA2Data* aOutIA2Data); + void BuildInitialIA2Data(NotNull aInterceptor, + StaticIA2Data* aOutStaticData, + DynamicIA2Data* aOutDynamicData); + static void CleanupStaticIA2Data(StaticIA2Data& aData); + static void CleanupDynamicIA2Data(DynamicIA2Data& aData); bool IsTargetInterfaceCacheable(); Atomic mRefCnt; diff --git a/accessible/ipc/win/handler/AccessibleHandler.cpp b/accessible/ipc/win/handler/AccessibleHandler.cpp index d2c7021e9f39..1ef6d5bca9b3 100644 --- a/accessible/ipc/win/handler/AccessibleHandler.cpp +++ b/accessible/ipc/win/handler/AccessibleHandler.cpp @@ -147,7 +147,7 @@ AccessibleHandler::MaybeUpdateCachedData() return E_POINTER; } - return mCachedData.mGeckoBackChannel->Refresh(&mCachedData.mData); + return mCachedData.mGeckoBackChannel->Refresh(&mCachedData.mDynamicData); } HRESULT @@ -245,6 +245,34 @@ AccessibleHandler::ReadHandlerPayload(IStream* aStream, REFIID aIid) return E_FAIL; } + // These interfaces have been aggregated into the proxy manager. + // The proxy manager will resolve these interfaces now on QI, + // so we can release these pointers. + // Note that if pointers to other objects (in contrast to + // interfaces of *this* object) are added in future, we should not release + // those pointers. + if (mCachedData.mStaticData.mIA2) { + mCachedData.mStaticData.mIA2->Release(); + } + if (mCachedData.mStaticData.mIEnumVARIANT) { + mCachedData.mStaticData.mIEnumVARIANT->Release(); + } + if (mCachedData.mStaticData.mIAHypertext) { + mCachedData.mStaticData.mIAHypertext->Release(); + } + if (mCachedData.mStaticData.mIAHyperlink) { + mCachedData.mStaticData.mIAHyperlink->Release(); + } + if (mCachedData.mStaticData.mIATable) { + mCachedData.mStaticData.mIATable->Release(); + } + if (mCachedData.mStaticData.mIATable2) { + mCachedData.mStaticData.mIATable2->Release(); + } + if (mCachedData.mStaticData.mIATableCell) { + mCachedData.mStaticData.mIATableCell->Release(); + } + if (!mCachedData.mGeckoBackChannel) { return S_OK; } @@ -411,12 +439,12 @@ CopyBSTR(BSTR aSrc) #define GET_FIELD(member, assignTo) \ { \ - assignTo = mCachedData.mData.member; \ + assignTo = mCachedData.mDynamicData.member; \ } #define GET_BSTR(member, assignTo) \ { \ - assignTo = CopyBSTR(mCachedData.mData.member); \ + assignTo = CopyBSTR(mCachedData.mDynamicData.member); \ } /*** IAccessible ***/ @@ -547,7 +575,7 @@ AccessibleHandler::get_accRole(VARIANT varChild, VARIANT *pvarRole) } BEGIN_CACHE_ACCESS; - return ::VariantCopy(pvarRole, &mCachedData.mData.mRole); + return ::VariantCopy(pvarRole, &mCachedData.mDynamicData.mRole); } @@ -919,7 +947,7 @@ AccessibleHandler::get_uniqueID(long* uniqueID) } return mIA2PassThru->get_uniqueID(uniqueID); } - *uniqueID = mCachedData.mData.mUniqueId; + *uniqueID = mCachedData.mDynamicData.mUniqueId; return S_OK; } diff --git a/accessible/ipc/win/handler/HandlerData.idl b/accessible/ipc/win/handler/HandlerData.idl index 346d00f6d140..61190efbf054 100644 --- a/accessible/ipc/win/handler/HandlerData.idl +++ b/accessible/ipc/win/handler/HandlerData.idl @@ -7,12 +7,29 @@ #include "mozilla-config.h" #include "AccessibleHandler.h" +import "oaidl.idl"; import "ocidl.idl"; import "ServProv.idl"; -import "AccessibleText.idl"; +import "Accessible2_3.idl"; +import "AccessibleHypertext2.idl"; +import "AccessibleHyperlink.idl"; +import "AccessibleTable.idl"; +import "AccessibleTable2.idl"; +import "AccessibleTableCell.idl"; -typedef struct _IA2Data +typedef struct _StaticIA2Data +{ + NEWEST_IA2_INTERFACE* mIA2; + IEnumVARIANT* mIEnumVARIANT; + IAccessibleHypertext2* mIAHypertext; + IAccessibleHyperlink* mIAHyperlink; + IAccessibleTable* mIATable; + IAccessibleTable2* mIATable2; + IAccessibleTableCell* mIATableCell; +} StaticIA2Data; + +typedef struct _DynamicIA2Data { VARIANT mRole; long mState; @@ -32,7 +49,7 @@ typedef struct _IA2Data BSTR mAttributes; IA2Locale mIA2Locale; long mUniqueId; -} IA2Data; +} DynamicIA2Data; interface IGeckoBackChannel; @@ -100,7 +117,8 @@ interface HandlerData { typedef struct _IA2Payload { - IA2Data mData; + StaticIA2Data mStaticData; + DynamicIA2Data mDynamicData; IGeckoBackChannel* mGeckoBackChannel; } IA2Payload; } @@ -123,7 +141,7 @@ interface IHandlerControl : IUnknown interface IGeckoBackChannel : IUnknown { [propput] HRESULT HandlerControl([in] long aPid, [in] IHandlerControl* aCtrl); - HRESULT Refresh([out] IA2Data* aOutData); + HRESULT Refresh([out] DynamicIA2Data* aOutData); } [uuid(1e545f07-f108-4912-9471-546827a80983)] From ff41c00a3ee166465faaed68770961301d2d3820 Mon Sep 17 00:00:00 2001 From: James Teh Date: Wed, 15 Nov 2017 12:28:45 +1000 Subject: [PATCH 06/78] Bug 1416986 part 3: AccessibleHandler: Avoid cross-process QI calls for interfaces which we know don't exist. r=aklotz The proxy manager caches interfaces marshaled in the payload and returns them on QI without a cross-process call. However, it doesn't know about interfaces which don't exist. We can determine this from the payload, since interfaces which don't exist will have a null pointer. We use this information to avoid querying the proxy in this case. MozReview-Commit-ID: FnzDetmTiPP --HG-- extra : rebase_source : 076ce714a69d3883a149487e5f9235ff495eedd0 --- .../ipc/win/handler/AccessibleHandler.cpp | 43 ++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/accessible/ipc/win/handler/AccessibleHandler.cpp b/accessible/ipc/win/handler/AccessibleHandler.cpp index 1ef6d5bca9b3..92167aa707e5 100644 --- a/accessible/ipc/win/handler/AccessibleHandler.cpp +++ b/accessible/ipc/win/handler/AccessibleHandler.cpp @@ -29,7 +29,11 @@ #include "Accessible2_i.c" #include "Accessible2_2_i.c" #include "Accessible2_3_i.c" +#include "AccessibleAction_i.c" #include "AccessibleHyperlink_i.c" +#include "AccessibleTable_i.c" +#include "AccessibleTable2_i.c" +#include "AccessibleTableCell_i.c" namespace mozilla { namespace a11y { @@ -210,6 +214,32 @@ AccessibleHandler::QueryHandlerInterface(IUnknown* aProxyUnknown, REFIID aIid, return S_OK; } + if (HasPayload()) { + // The proxy manager caches interfaces marshaled in the payload + // and returns them on QI without a cross-process call. + // However, it doesn't know about interfaces which don't exist. + // We can determine this from the payload. + if ((aIid == IID_IEnumVARIANT && + !mCachedData.mStaticData.mIEnumVARIANT) || + ((aIid == IID_IAccessibleText || aIid == IID_IAccessibleHypertext || + aIid == IID_IAccessibleHypertext2) && + !mCachedData.mStaticData.mIAHypertext) || + ((aIid == IID_IAccessibleAction || aIid == IID_IAccessibleHyperlink) && + !mCachedData.mStaticData.mIAHyperlink) || + (aIid == IID_IAccessibleTable && + !mCachedData.mStaticData.mIATable) || + (aIid == IID_IAccessibleTable2 && + !mCachedData.mStaticData.mIATable2) || + (aIid == IID_IAccessibleTableCell && + !mCachedData.mStaticData.mIATableCell)) { + // We already know this interface is not available, so don't query + // the proxy, thus avoiding a pointless cross-process call. + // If we return E_NOINTERFACE here, mscom::Handler will try the COM + // proxy. S_FALSE signals that the proxy should not be tried. + return S_FALSE; + } + } + if (aIid == IID_IAccessibleText || aIid == IID_IAccessibleHypertext || aIid == IID_IAccessibleHypertext2) { RefPtr textTearoff(new AccessibleTextTearoff(this)); @@ -241,13 +271,24 @@ AccessibleHandler::ReadHandlerPayload(IStream* aStream, REFIID aIid) return S_FALSE; } - if (!deserializer.Read(&mCachedData, &IA2Payload_Decode)) { + // QueryHandlerInterface might get called while we deserialize the payload, + // but that checks the interface pointers in the payload to determine what + // interfaces are available. Therefore, deserialize into a temporary struct + // and update mCachedData only after deserialization completes. + // The decoding functions can misbehave if their target memory is not zeroed + // beforehand, so ensure we do that. + IA2Payload newData{}; + if (!deserializer.Read(&newData, &IA2Payload_Decode)) { return E_FAIL; } + mCachedData = newData; // These interfaces have been aggregated into the proxy manager. // The proxy manager will resolve these interfaces now on QI, // so we can release these pointers. + // However, we don't null them out because we use their presence + // to determine whether the interface is available + // so as to avoid pointless cross-proc QI calls returning E_NOINTERFACE. // Note that if pointers to other objects (in contrast to // interfaces of *this* object) are added in future, we should not release // those pointers. From fb7c94c665b36a83dafc636d3396f63e4119d8dc Mon Sep 17 00:00:00 2001 From: James Teh Date: Wed, 15 Nov 2017 12:32:52 +1000 Subject: [PATCH 07/78] Bug 1416986 part 4: AccessibleHandler: Don't fall through to the proxy for IAccessibleHyperlink. r=aklotz The handler's implementation of IAHyperlink just forwards calls through to the proxy. However, it exists because we want the cache to be used when a hyperlink is retrieved. When querying from the handler to IAHyperlink, we should use the same implementation. This is mostly about consistency/correctness, especially as we're increasing complexity. MozReview-Commit-ID: AwYibrFzUyf --HG-- extra : rebase_source : 3d8f33639190a4220a21d0a6eeac401829d8345c --- accessible/ipc/win/handler/AccessibleHandler.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/accessible/ipc/win/handler/AccessibleHandler.cpp b/accessible/ipc/win/handler/AccessibleHandler.cpp index 92167aa707e5..cfeca4f7eb11 100644 --- a/accessible/ipc/win/handler/AccessibleHandler.cpp +++ b/accessible/ipc/win/handler/AccessibleHandler.cpp @@ -240,6 +240,13 @@ AccessibleHandler::QueryHandlerInterface(IUnknown* aProxyUnknown, REFIID aIid, } } + if (aIid == IID_IAccessibleAction || aIid == IID_IAccessibleHyperlink) { + RefPtr iaLink( + static_cast(this)); + iaLink.forget(aOutInterface); + return S_OK; + } + if (aIid == IID_IAccessibleText || aIid == IID_IAccessibleHypertext || aIid == IID_IAccessibleHypertext2) { RefPtr textTearoff(new AccessibleTextTearoff(this)); From 6d13847e3c8226f3fccaf412fc70f38ae61fee52 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Tue, 21 Nov 2017 00:19:00 -0600 Subject: [PATCH 08/78] servo: Merge #19313 - style: Update layer filling function call in Gecko glue (from heycam:layer-filling); r=CJKu This is the (small) Servo part of https://bugzilla.mozilla.org/show_bug.cgi?id=1418899, reviewed there by CJKu. Source-Repo: https://github.com/servo/servo Source-Revision: bdb2cacad9036f1ff6ef452fffe4a50339ec721d --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : c74f55a80eae93e12c66d7681d755480874c887a --- .../style/gecko/generated/atom_macro.rs | 8 ----- .../style/gecko/generated/bindings.rs | 4 +-- .../style/gecko/generated/structs.rs | 33 ++++++++++++++----- .../components/style/properties/gecko.mako.rs | 4 +-- 4 files changed, 27 insertions(+), 22 deletions(-) diff --git a/servo/components/style/gecko/generated/atom_macro.rs b/servo/components/style/gecko/generated/atom_macro.rs index aad7ed1b1f2e..8242e60ff436 100644 --- a/servo/components/style/gecko/generated/atom_macro.rs +++ b/servo/components/style/gecko/generated/atom_macro.rs @@ -4058,8 +4058,6 @@ cfg_if! { pub static nsGkAtoms_ondevicelight: *mut nsStaticAtom; #[link_name = "_ZN9nsGkAtoms14ondevicechangeE"] pub static nsGkAtoms_ondevicechange: *mut nsStaticAtom; - #[link_name = "_ZN9nsGkAtoms33mozinputrangeignorepreventdefaultE"] - pub static nsGkAtoms_mozinputrangeignorepreventdefault: *mut nsStaticAtom; #[link_name = "_ZN9nsGkAtoms13moz_extensionE"] pub static nsGkAtoms_moz_extension: *mut nsStaticAtom; #[link_name = "_ZN9nsGkAtoms18all_urlsPermissionE"] @@ -9237,8 +9235,6 @@ cfg_if! { pub static nsGkAtoms_ondevicelight: *mut nsStaticAtom; #[link_name = "?ondevicechange@nsGkAtoms@@2PEAVnsStaticAtom@@EA"] pub static nsGkAtoms_ondevicechange: *mut nsStaticAtom; - #[link_name = "?mozinputrangeignorepreventdefault@nsGkAtoms@@2PEAVnsStaticAtom@@EA"] - pub static nsGkAtoms_mozinputrangeignorepreventdefault: *mut nsStaticAtom; #[link_name = "?moz_extension@nsGkAtoms@@2PEAVnsStaticAtom@@EA"] pub static nsGkAtoms_moz_extension: *mut nsStaticAtom; #[link_name = "?all_urlsPermission@nsGkAtoms@@2PEAVnsStaticAtom@@EA"] @@ -14416,8 +14412,6 @@ cfg_if! { pub static nsGkAtoms_ondevicelight: *mut nsStaticAtom; #[link_name = "\x01?ondevicechange@nsGkAtoms@@2PAVnsStaticAtom@@A"] pub static nsGkAtoms_ondevicechange: *mut nsStaticAtom; - #[link_name = "\x01?mozinputrangeignorepreventdefault@nsGkAtoms@@2PAVnsStaticAtom@@A"] - pub static nsGkAtoms_mozinputrangeignorepreventdefault: *mut nsStaticAtom; #[link_name = "\x01?moz_extension@nsGkAtoms@@2PAVnsStaticAtom@@A"] pub static nsGkAtoms_moz_extension: *mut nsStaticAtom; #[link_name = "\x01?all_urlsPermission@nsGkAtoms@@2PAVnsStaticAtom@@A"] @@ -19598,8 +19592,6 @@ macro_rules! atom { {{ #[allow(unsafe_code)] #[allow(unused_unsafe)]unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_ondevicelight as *mut _) } }}; ("ondevicechange") => {{ #[allow(unsafe_code)] #[allow(unused_unsafe)]unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_ondevicechange as *mut _) } }}; -("mozinputrangeignorepreventdefault") => - {{ #[allow(unsafe_code)] #[allow(unused_unsafe)]unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_mozinputrangeignorepreventdefault as *mut _) } }}; ("moz-extension") => {{ #[allow(unsafe_code)] #[allow(unused_unsafe)]unsafe { $crate::string_cache::atom_macro::atom_from_static($crate::string_cache::atom_macro::nsGkAtoms_moz_extension as *mut _) } }}; ("") => diff --git a/servo/components/style/gecko/generated/bindings.rs b/servo/components/style/gecko/generated/bindings.rs index 0f22c33105c9..ad6496b17153 100644 --- a/servo/components/style/gecko/generated/bindings.rs +++ b/servo/components/style/gecko/generated/bindings.rs @@ -850,9 +850,7 @@ extern "C" { } extern "C" { pub fn Gecko_ReleaseURLExtraDataArbitraryThread ( aPtr : * mut RawGeckoURLExtraData , ) ; } extern "C" { - pub fn Gecko_FillAllBackgroundLists ( layers : * mut nsStyleImageLayers , max_len : u32 , ) ; -} extern "C" { - pub fn Gecko_FillAllMaskLists ( layers : * mut nsStyleImageLayers , max_len : u32 , ) ; + pub fn Gecko_FillAllImageLayers ( layers : * mut nsStyleImageLayers , max_len : u32 , ) ; } extern "C" { pub fn Gecko_AddRefCalcArbitraryThread ( aPtr : * mut nsStyleCoord_Calc , ) ; } extern "C" { diff --git a/servo/components/style/gecko/generated/structs.rs b/servo/components/style/gecko/generated/structs.rs index bd87225e273a..0aeb67ec6a88 100644 --- a/servo/components/style/gecko/generated/structs.rs +++ b/servo/components/style/gecko/generated/structs.rs @@ -75,7 +75,7 @@ pub type ServoStyleContextStrong = ::gecko_bindings::sugar::ownership::Strong<:: # [ derive ( Debug , Copy , Clone , PartialEq , Eq , Hash ) ] pub enum URLMatchingFunction { eURL = 0 , eURLPrefix = 1 , eDomain = 2 , eRegExp = 3 , } # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct Rule { pub _base : root :: nsIDOMCSSRule , pub _base_1 : root :: nsWrapperCache , pub mRefCnt : root :: nsCycleCollectingAutoRefCnt , pub mSheet : * mut root :: mozilla :: StyleSheet , pub mParentRule : * mut root :: mozilla :: css :: GroupRule , pub mLineNumber : u32 , pub mColumnNumber : u32 , } pub type Rule_HasThreadSafeRefCnt = root :: mozilla :: FalseType ; # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct Rule_cycleCollection { pub _base : root :: nsXPCOMCycleCollectionParticipant , } # [ test ] fn bindgen_test_layout_Rule_cycleCollection ( ) { assert_eq ! ( :: std :: mem :: size_of :: < Rule_cycleCollection > ( ) , 16usize , concat ! ( "Size of: " , stringify ! ( Rule_cycleCollection ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < Rule_cycleCollection > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( Rule_cycleCollection ) ) ) ; } impl Clone for Rule_cycleCollection { fn clone ( & self ) -> Self { * self } } pub const Rule_UNKNOWN_RULE : root :: mozilla :: css :: Rule__bindgen_ty_1 = 0 ; pub const Rule_CHARSET_RULE : root :: mozilla :: css :: Rule__bindgen_ty_1 = 1 ; pub const Rule_IMPORT_RULE : root :: mozilla :: css :: Rule__bindgen_ty_1 = 2 ; pub const Rule_NAMESPACE_RULE : root :: mozilla :: css :: Rule__bindgen_ty_1 = 3 ; pub const Rule_STYLE_RULE : root :: mozilla :: css :: Rule__bindgen_ty_1 = 4 ; pub const Rule_MEDIA_RULE : root :: mozilla :: css :: Rule__bindgen_ty_1 = 5 ; pub const Rule_FONT_FACE_RULE : root :: mozilla :: css :: Rule__bindgen_ty_1 = 6 ; pub const Rule_PAGE_RULE : root :: mozilla :: css :: Rule__bindgen_ty_1 = 7 ; pub const Rule_KEYFRAME_RULE : root :: mozilla :: css :: Rule__bindgen_ty_1 = 8 ; pub const Rule_KEYFRAMES_RULE : root :: mozilla :: css :: Rule__bindgen_ty_1 = 9 ; pub const Rule_DOCUMENT_RULE : root :: mozilla :: css :: Rule__bindgen_ty_1 = 10 ; pub const Rule_SUPPORTS_RULE : root :: mozilla :: css :: Rule__bindgen_ty_1 = 11 ; pub const Rule_FONT_FEATURE_VALUES_RULE : root :: mozilla :: css :: Rule__bindgen_ty_1 = 12 ; pub const Rule_COUNTER_STYLE_RULE : root :: mozilla :: css :: Rule__bindgen_ty_1 = 13 ; pub type Rule__bindgen_ty_1 = :: std :: os :: raw :: c_uint ; extern "C" { # [ link_name = "\u{1}_ZN7mozilla3css4Rule21_cycleCollectorGlobalE" ] pub static mut Rule__cycleCollectorGlobal : root :: mozilla :: css :: Rule_cycleCollection ; -} # [ test ] fn bindgen_test_layout_Rule ( ) { assert_eq ! ( :: std :: mem :: size_of :: < Rule > ( ) , 64usize , concat ! ( "Size of: " , stringify ! ( Rule ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < Rule > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( Rule ) ) ) ; } } # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct ThreadSafeAutoRefCnt { pub mValue : u64 , } pub const ThreadSafeAutoRefCnt_isThreadSafe : bool = true ; # [ test ] fn bindgen_test_layout_ThreadSafeAutoRefCnt ( ) { assert_eq ! ( :: std :: mem :: size_of :: < ThreadSafeAutoRefCnt > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( ThreadSafeAutoRefCnt ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < ThreadSafeAutoRefCnt > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( ThreadSafeAutoRefCnt ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ThreadSafeAutoRefCnt ) ) . mValue as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( ThreadSafeAutoRefCnt ) , "::" , stringify ! ( mValue ) ) ) ; } pub type EnumeratedArray_ArrayType = u8 ; pub type EnumeratedArray_iterator = root :: mozilla :: EnumeratedArray_ArrayType ; pub type EnumeratedArray_const_iterator = root :: mozilla :: EnumeratedArray_ArrayType ; pub type EnumeratedArray_reverse_iterator = root :: mozilla :: EnumeratedArray_ArrayType ; pub type EnumeratedArray_const_reverse_iterator = root :: mozilla :: EnumeratedArray_ArrayType ; # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct LinkedListElement { pub mNext : * mut root :: mozilla :: LinkedListElement , pub mPrev : * mut root :: mozilla :: LinkedListElement , pub mIsSentinel : bool , } pub type LinkedListElement_Traits = root :: mozilla :: detail :: LinkedListElementTraits ; pub type LinkedListElement_RawType = root :: mozilla :: LinkedListElement_Traits ; pub type LinkedListElement_ConstRawType = root :: mozilla :: LinkedListElement_Traits ; pub type LinkedListElement_ClientType = root :: mozilla :: LinkedListElement_Traits ; pub type LinkedListElement_ConstClientType = root :: mozilla :: LinkedListElement_Traits ; pub const LinkedListElement_NodeKind_Normal : root :: mozilla :: LinkedListElement_NodeKind = 0 ; pub const LinkedListElement_NodeKind_Sentinel : root :: mozilla :: LinkedListElement_NodeKind = 0 ; pub type LinkedListElement_NodeKind = :: std :: os :: raw :: c_int ; # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct LinkedList { pub sentinel : root :: mozilla :: LinkedListElement , } pub type LinkedList_Traits = root :: mozilla :: detail :: LinkedListElementTraits ; pub type LinkedList_RawType = root :: mozilla :: LinkedList_Traits ; pub type LinkedList_ConstRawType = root :: mozilla :: LinkedList_Traits ; pub type LinkedList_ClientType = root :: mozilla :: LinkedList_Traits ; pub type LinkedList_ConstClientType = root :: mozilla :: LinkedList_Traits ; # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct LinkedList_Iterator { pub mCurrent : root :: mozilla :: LinkedList_RawType , } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct Maybe { pub _address : u8 , } pub type Maybe_ValueType < T > = T ; pub mod gfx { # [ allow ( unused_imports ) ] use self :: super :: super :: super :: root ; pub type Float = f32 ; # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct FontVariation { pub mTag : u32 , pub mValue : f32 , } # [ test ] fn bindgen_test_layout_FontVariation ( ) { assert_eq ! ( :: std :: mem :: size_of :: < FontVariation > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( FontVariation ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < FontVariation > ( ) , 4usize , concat ! ( "Alignment of " , stringify ! ( FontVariation ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const FontVariation ) ) . mTag as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( FontVariation ) , "::" , stringify ! ( mTag ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const FontVariation ) ) . mValue as * const _ as usize } , 4usize , concat ! ( "Alignment of field: " , stringify ! ( FontVariation ) , "::" , stringify ! ( mValue ) ) ) ; } impl Clone for FontVariation { fn clone ( & self ) -> Self { * self } } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct SourceSurface { _unused : [ u8 ; 0 ] } } pub mod layers { # [ allow ( unused_imports ) ] use self :: super :: super :: super :: root ; # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct LayerManager { _unused : [ u8 ; 0 ] } } pub mod dom { # [ allow ( unused_imports ) ] use self :: super :: super :: super :: root ; # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct AllOwningUnionBase { pub _address : u8 , } # [ test ] fn bindgen_test_layout_AllOwningUnionBase ( ) { assert_eq ! ( :: std :: mem :: size_of :: < AllOwningUnionBase > ( ) , 1usize , concat ! ( "Size of: " , stringify ! ( AllOwningUnionBase ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < AllOwningUnionBase > ( ) , 1usize , concat ! ( "Alignment of " , stringify ! ( AllOwningUnionBase ) ) ) ; } impl Clone for AllOwningUnionBase { fn clone ( & self ) -> Self { * self } } # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct GlobalObject { pub mGlobalJSObject : [ u64 ; 3usize ] , pub mCx : * mut root :: JSContext , pub mGlobalObject : * mut root :: nsISupports , } # [ test ] fn bindgen_test_layout_GlobalObject ( ) { assert_eq ! ( :: std :: mem :: size_of :: < GlobalObject > ( ) , 40usize , concat ! ( "Size of: " , stringify ! ( GlobalObject ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < GlobalObject > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( GlobalObject ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const GlobalObject ) ) . mGlobalJSObject as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( GlobalObject ) , "::" , stringify ! ( mGlobalJSObject ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const GlobalObject ) ) . mCx as * const _ as usize } , 24usize , concat ! ( "Alignment of field: " , stringify ! ( GlobalObject ) , "::" , stringify ! ( mCx ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const GlobalObject ) ) . mGlobalObject as * const _ as usize } , 32usize , concat ! ( "Alignment of field: " , stringify ! ( GlobalObject ) , "::" , stringify ! ( mGlobalObject ) ) ) ; } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct Sequence { pub _address : u8 , } # [ repr ( u32 ) ] # [ derive ( Debug , Copy , Clone , PartialEq , Eq , Hash ) ] pub enum CallerType { System = 0 , NonSystem = 1 , } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct Nullable { pub _address : u8 , } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct CSSImportRule { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct ShadowRoot { _unused : [ u8 ; 0 ] } +} # [ test ] fn bindgen_test_layout_Rule ( ) { assert_eq ! ( :: std :: mem :: size_of :: < Rule > ( ) , 64usize , concat ! ( "Size of: " , stringify ! ( Rule ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < Rule > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( Rule ) ) ) ; } } # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct ThreadSafeAutoRefCnt { pub mValue : u64 , } pub const ThreadSafeAutoRefCnt_isThreadSafe : bool = true ; # [ test ] fn bindgen_test_layout_ThreadSafeAutoRefCnt ( ) { assert_eq ! ( :: std :: mem :: size_of :: < ThreadSafeAutoRefCnt > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( ThreadSafeAutoRefCnt ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < ThreadSafeAutoRefCnt > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( ThreadSafeAutoRefCnt ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ThreadSafeAutoRefCnt ) ) . mValue as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( ThreadSafeAutoRefCnt ) , "::" , stringify ! ( mValue ) ) ) ; } pub type EnumeratedArray_ArrayType = u8 ; pub type EnumeratedArray_iterator = root :: mozilla :: EnumeratedArray_ArrayType ; pub type EnumeratedArray_const_iterator = root :: mozilla :: EnumeratedArray_ArrayType ; pub type EnumeratedArray_reverse_iterator = root :: mozilla :: EnumeratedArray_ArrayType ; pub type EnumeratedArray_const_reverse_iterator = root :: mozilla :: EnumeratedArray_ArrayType ; # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct LinkedListElement { pub mNext : * mut root :: mozilla :: LinkedListElement , pub mPrev : * mut root :: mozilla :: LinkedListElement , pub mIsSentinel : bool , } pub type LinkedListElement_Traits = root :: mozilla :: detail :: LinkedListElementTraits ; pub type LinkedListElement_RawType = root :: mozilla :: LinkedListElement_Traits ; pub type LinkedListElement_ConstRawType = root :: mozilla :: LinkedListElement_Traits ; pub type LinkedListElement_ClientType = root :: mozilla :: LinkedListElement_Traits ; pub type LinkedListElement_ConstClientType = root :: mozilla :: LinkedListElement_Traits ; pub const LinkedListElement_NodeKind_Normal : root :: mozilla :: LinkedListElement_NodeKind = 0 ; pub const LinkedListElement_NodeKind_Sentinel : root :: mozilla :: LinkedListElement_NodeKind = 0 ; pub type LinkedListElement_NodeKind = :: std :: os :: raw :: c_int ; # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct LinkedList { pub sentinel : root :: mozilla :: LinkedListElement , } pub type LinkedList_Traits = root :: mozilla :: detail :: LinkedListElementTraits ; pub type LinkedList_RawType = root :: mozilla :: LinkedList_Traits ; pub type LinkedList_ConstRawType = root :: mozilla :: LinkedList_Traits ; pub type LinkedList_ClientType = root :: mozilla :: LinkedList_Traits ; pub type LinkedList_ConstClientType = root :: mozilla :: LinkedList_Traits ; # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct LinkedList_Iterator { pub mCurrent : root :: mozilla :: LinkedList_RawType , } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct Maybe { pub _address : u8 , } pub type Maybe_ValueType < T > = T ; pub mod gfx { # [ allow ( unused_imports ) ] use self :: super :: super :: super :: root ; pub type Float = f32 ; # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct FontVariation { pub mTag : u32 , pub mValue : f32 , } # [ test ] fn bindgen_test_layout_FontVariation ( ) { assert_eq ! ( :: std :: mem :: size_of :: < FontVariation > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( FontVariation ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < FontVariation > ( ) , 4usize , concat ! ( "Alignment of " , stringify ! ( FontVariation ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const FontVariation ) ) . mTag as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( FontVariation ) , "::" , stringify ! ( mTag ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const FontVariation ) ) . mValue as * const _ as usize } , 4usize , concat ! ( "Alignment of field: " , stringify ! ( FontVariation ) , "::" , stringify ! ( mValue ) ) ) ; } impl Clone for FontVariation { fn clone ( & self ) -> Self { * self } } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct SourceSurface { _unused : [ u8 ; 0 ] } } pub mod layers { # [ allow ( unused_imports ) ] use self :: super :: super :: super :: root ; # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct LayerManager { _unused : [ u8 ; 0 ] } } pub mod dom { # [ allow ( unused_imports ) ] use self :: super :: super :: super :: root ; # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct AllOwningUnionBase { pub _address : u8 , } # [ test ] fn bindgen_test_layout_AllOwningUnionBase ( ) { assert_eq ! ( :: std :: mem :: size_of :: < AllOwningUnionBase > ( ) , 1usize , concat ! ( "Size of: " , stringify ! ( AllOwningUnionBase ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < AllOwningUnionBase > ( ) , 1usize , concat ! ( "Alignment of " , stringify ! ( AllOwningUnionBase ) ) ) ; } impl Clone for AllOwningUnionBase { fn clone ( & self ) -> Self { * self } } # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct GlobalObject { pub mGlobalJSObject : [ u64 ; 3usize ] , pub mCx : * mut root :: JSContext , pub mGlobalObject : * mut root :: nsISupports , } # [ test ] fn bindgen_test_layout_GlobalObject ( ) { assert_eq ! ( :: std :: mem :: size_of :: < GlobalObject > ( ) , 40usize , concat ! ( "Size of: " , stringify ! ( GlobalObject ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < GlobalObject > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( GlobalObject ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const GlobalObject ) ) . mGlobalJSObject as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( GlobalObject ) , "::" , stringify ! ( mGlobalJSObject ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const GlobalObject ) ) . mCx as * const _ as usize } , 24usize , concat ! ( "Alignment of field: " , stringify ! ( GlobalObject ) , "::" , stringify ! ( mCx ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const GlobalObject ) ) . mGlobalObject as * const _ as usize } , 32usize , concat ! ( "Alignment of field: " , stringify ! ( GlobalObject ) , "::" , stringify ! ( mGlobalObject ) ) ) ; } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct Sequence { pub _address : u8 , } # [ repr ( u32 ) ] # [ derive ( Debug , Copy , Clone , PartialEq , Eq , Hash ) ] pub enum CallerType { System = 0 , NonSystem = 1 , } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct Nullable { pub _address : u8 , } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct ClientSource { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct CSSImportRule { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct ShadowRoot { _unused : [ u8 ; 0 ] } /// Struct that stores info on an attribute. The name and value must either both /// be null or both be non-null. /// @@ -214,7 +214,7 @@ pub type ServoStyleContextStrong = ::gecko_bindings::sugar::ownership::Strong<:: /// ContentStatesChanged() has to be called when one of them changes thus /// informing the layout/style engine of the change. /// Event states are associated with pseudo-classes. - # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct EventStates { pub mStates : root :: mozilla :: EventStates_InternalType , } pub type EventStates_InternalType = u64 ; pub type EventStates_ServoType = u64 ; # [ test ] fn bindgen_test_layout_EventStates ( ) { assert_eq ! ( :: std :: mem :: size_of :: < EventStates > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( EventStates ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < EventStates > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( EventStates ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const EventStates ) ) . mStates as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( EventStates ) , "::" , stringify ! ( mStates ) ) ) ; } impl Clone for EventStates { fn clone ( & self ) -> Self { * self } } pub const ServoTraversalFlags_Empty : root :: mozilla :: ServoTraversalFlags = 0 ; pub const ServoTraversalFlags_AnimationOnly : root :: mozilla :: ServoTraversalFlags = 1 ; pub const ServoTraversalFlags_ForCSSRuleChanges : root :: mozilla :: ServoTraversalFlags = 2 ; pub const ServoTraversalFlags_UnstyledOnly : root :: mozilla :: ServoTraversalFlags = 4 ; pub const ServoTraversalFlags_Forgetful : root :: mozilla :: ServoTraversalFlags = 8 ; pub const ServoTraversalFlags_ClearDirtyBits : root :: mozilla :: ServoTraversalFlags = 32 ; pub const ServoTraversalFlags_ClearAnimationOnlyDirtyDescendants : root :: mozilla :: ServoTraversalFlags = 64 ; pub const ServoTraversalFlags_ParallelTraversal : root :: mozilla :: ServoTraversalFlags = 128 ; pub const ServoTraversalFlags_FlushThrottledAnimations : root :: mozilla :: ServoTraversalFlags = 256 ; pub type ServoTraversalFlags = u32 ; # [ repr ( i32 ) ] # [ derive ( Debug , Copy , Clone , PartialEq , Eq , Hash ) ] pub enum StyleRuleInclusion { All = 0 , DefaultOnly = 1 , } pub const UpdateAnimationsTasks_CSSAnimations : root :: mozilla :: UpdateAnimationsTasks = 1 ; pub const UpdateAnimationsTasks_CSSTransitions : root :: mozilla :: UpdateAnimationsTasks = 2 ; pub const UpdateAnimationsTasks_EffectProperties : root :: mozilla :: UpdateAnimationsTasks = 4 ; pub const UpdateAnimationsTasks_CascadeResults : root :: mozilla :: UpdateAnimationsTasks = 8 ; pub type UpdateAnimationsTasks = u8 ; pub const ParsingMode_Default : root :: mozilla :: ParsingMode = 0 ; pub const ParsingMode_AllowUnitlessLength : root :: mozilla :: ParsingMode = 1 ; pub const ParsingMode_AllowAllNumericValues : root :: mozilla :: ParsingMode = 2 ; pub type ParsingMode = u8 ; # [ repr ( i32 ) ] # [ derive ( Debug , Copy , Clone , PartialEq , Eq , Hash ) ] pub enum InheritTarget { Text = 0 , FirstLetterContinuation = 1 , PlaceholderFrame = 2 , } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct ServoStyleSetSizes { pub mRuleTree : usize , pub mPrecomputedPseudos : usize , pub mElementAndPseudosMaps : usize , pub mInvalidationMap : usize , pub mRevalidationSelectors : usize , pub mOther : usize , } # [ test ] fn bindgen_test_layout_ServoStyleSetSizes ( ) { assert_eq ! ( :: std :: mem :: size_of :: < ServoStyleSetSizes > ( ) , 48usize , concat ! ( "Size of: " , stringify ! ( ServoStyleSetSizes ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < ServoStyleSetSizes > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( ServoStyleSetSizes ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ServoStyleSetSizes ) ) . mRuleTree as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( ServoStyleSetSizes ) , "::" , stringify ! ( mRuleTree ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ServoStyleSetSizes ) ) . mPrecomputedPseudos as * const _ as usize } , 8usize , concat ! ( "Alignment of field: " , stringify ! ( ServoStyleSetSizes ) , "::" , stringify ! ( mPrecomputedPseudos ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ServoStyleSetSizes ) ) . mElementAndPseudosMaps as * const _ as usize } , 16usize , concat ! ( "Alignment of field: " , stringify ! ( ServoStyleSetSizes ) , "::" , stringify ! ( mElementAndPseudosMaps ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ServoStyleSetSizes ) ) . mInvalidationMap as * const _ as usize } , 24usize , concat ! ( "Alignment of field: " , stringify ! ( ServoStyleSetSizes ) , "::" , stringify ! ( mInvalidationMap ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ServoStyleSetSizes ) ) . mRevalidationSelectors as * const _ as usize } , 32usize , concat ! ( "Alignment of field: " , stringify ! ( ServoStyleSetSizes ) , "::" , stringify ! ( mRevalidationSelectors ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ServoStyleSetSizes ) ) . mOther as * const _ as usize } , 40usize , concat ! ( "Alignment of field: " , stringify ! ( ServoStyleSetSizes ) , "::" , stringify ! ( mOther ) ) ) ; } impl Clone for ServoStyleSetSizes { fn clone ( & self ) -> Self { * self } } pub const StyleBackendType_None : root :: mozilla :: StyleBackendType = 0 ; pub const StyleBackendType_Gecko : root :: mozilla :: StyleBackendType = 1 ; pub const StyleBackendType_Servo : root :: mozilla :: StyleBackendType = 2 ; pub type StyleBackendType = u8 ; pub type TimeStampValue = u64 ; + # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct EventStates { pub mStates : root :: mozilla :: EventStates_InternalType , } pub type EventStates_InternalType = u64 ; pub type EventStates_ServoType = u64 ; # [ test ] fn bindgen_test_layout_EventStates ( ) { assert_eq ! ( :: std :: mem :: size_of :: < EventStates > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( EventStates ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < EventStates > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( EventStates ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const EventStates ) ) . mStates as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( EventStates ) , "::" , stringify ! ( mStates ) ) ) ; } impl Clone for EventStates { fn clone ( & self ) -> Self { * self } } pub const ServoTraversalFlags_Empty : root :: mozilla :: ServoTraversalFlags = 0 ; pub const ServoTraversalFlags_AnimationOnly : root :: mozilla :: ServoTraversalFlags = 1 ; pub const ServoTraversalFlags_ForCSSRuleChanges : root :: mozilla :: ServoTraversalFlags = 2 ; pub const ServoTraversalFlags_Forgetful : root :: mozilla :: ServoTraversalFlags = 8 ; pub const ServoTraversalFlags_ClearDirtyBits : root :: mozilla :: ServoTraversalFlags = 32 ; pub const ServoTraversalFlags_ClearAnimationOnlyDirtyDescendants : root :: mozilla :: ServoTraversalFlags = 64 ; pub const ServoTraversalFlags_ParallelTraversal : root :: mozilla :: ServoTraversalFlags = 128 ; pub const ServoTraversalFlags_FlushThrottledAnimations : root :: mozilla :: ServoTraversalFlags = 256 ; pub type ServoTraversalFlags = u32 ; # [ repr ( i32 ) ] # [ derive ( Debug , Copy , Clone , PartialEq , Eq , Hash ) ] pub enum StyleRuleInclusion { All = 0 , DefaultOnly = 1 , } pub const UpdateAnimationsTasks_CSSAnimations : root :: mozilla :: UpdateAnimationsTasks = 1 ; pub const UpdateAnimationsTasks_CSSTransitions : root :: mozilla :: UpdateAnimationsTasks = 2 ; pub const UpdateAnimationsTasks_EffectProperties : root :: mozilla :: UpdateAnimationsTasks = 4 ; pub const UpdateAnimationsTasks_CascadeResults : root :: mozilla :: UpdateAnimationsTasks = 8 ; pub type UpdateAnimationsTasks = u8 ; pub const ParsingMode_Default : root :: mozilla :: ParsingMode = 0 ; pub const ParsingMode_AllowUnitlessLength : root :: mozilla :: ParsingMode = 1 ; pub const ParsingMode_AllowAllNumericValues : root :: mozilla :: ParsingMode = 2 ; pub type ParsingMode = u8 ; # [ repr ( i32 ) ] # [ derive ( Debug , Copy , Clone , PartialEq , Eq , Hash ) ] pub enum InheritTarget { Text = 0 , FirstLetterContinuation = 1 , PlaceholderFrame = 2 , } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct ServoStyleSetSizes { pub mRuleTree : usize , pub mPrecomputedPseudos : usize , pub mElementAndPseudosMaps : usize , pub mInvalidationMap : usize , pub mRevalidationSelectors : usize , pub mOther : usize , } # [ test ] fn bindgen_test_layout_ServoStyleSetSizes ( ) { assert_eq ! ( :: std :: mem :: size_of :: < ServoStyleSetSizes > ( ) , 48usize , concat ! ( "Size of: " , stringify ! ( ServoStyleSetSizes ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < ServoStyleSetSizes > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( ServoStyleSetSizes ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ServoStyleSetSizes ) ) . mRuleTree as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( ServoStyleSetSizes ) , "::" , stringify ! ( mRuleTree ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ServoStyleSetSizes ) ) . mPrecomputedPseudos as * const _ as usize } , 8usize , concat ! ( "Alignment of field: " , stringify ! ( ServoStyleSetSizes ) , "::" , stringify ! ( mPrecomputedPseudos ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ServoStyleSetSizes ) ) . mElementAndPseudosMaps as * const _ as usize } , 16usize , concat ! ( "Alignment of field: " , stringify ! ( ServoStyleSetSizes ) , "::" , stringify ! ( mElementAndPseudosMaps ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ServoStyleSetSizes ) ) . mInvalidationMap as * const _ as usize } , 24usize , concat ! ( "Alignment of field: " , stringify ! ( ServoStyleSetSizes ) , "::" , stringify ! ( mInvalidationMap ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ServoStyleSetSizes ) ) . mRevalidationSelectors as * const _ as usize } , 32usize , concat ! ( "Alignment of field: " , stringify ! ( ServoStyleSetSizes ) , "::" , stringify ! ( mRevalidationSelectors ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ServoStyleSetSizes ) ) . mOther as * const _ as usize } , 40usize , concat ! ( "Alignment of field: " , stringify ! ( ServoStyleSetSizes ) , "::" , stringify ! ( mOther ) ) ) ; } impl Clone for ServoStyleSetSizes { fn clone ( & self ) -> Self { * self } } pub const StyleBackendType_None : root :: mozilla :: StyleBackendType = 0 ; pub const StyleBackendType_Gecko : root :: mozilla :: StyleBackendType = 1 ; pub const StyleBackendType_Servo : root :: mozilla :: StyleBackendType = 2 ; pub type StyleBackendType = u8 ; pub type TimeStampValue = u64 ; /// Instances of this class represent the length of an interval of time. /// Negative durations are allowed, meaning the end is before the start. /// @@ -275,11 +275,26 @@ pub type ServoStyleContextStrong = ::gecko_bindings::sugar::ownership::Strong<:: } # [ test ] fn bindgen_test_layout_StyleSheet ( ) { assert_eq ! ( :: std :: mem :: size_of :: < StyleSheet > ( ) , 136usize , concat ! ( "Size of: " , stringify ! ( StyleSheet ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < StyleSheet > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( StyleSheet ) ) ) ; } pub const CSSEnabledState_eForAllContent : root :: mozilla :: CSSEnabledState = 0 ; pub const CSSEnabledState_eInUASheets : root :: mozilla :: CSSEnabledState = 1 ; pub const CSSEnabledState_eInChrome : root :: mozilla :: CSSEnabledState = 2 ; pub const CSSEnabledState_eIgnoreEnabledState : root :: mozilla :: CSSEnabledState = 255 ; pub type CSSEnabledState = :: std :: os :: raw :: c_int ; pub type CSSPseudoElementTypeBase = u8 ; pub const CSSPseudoElementType_InheritingAnonBox : root :: mozilla :: CSSPseudoElementType = CSSPseudoElementType :: Count ; # [ repr ( u8 ) ] # [ derive ( Debug , Copy , Clone , PartialEq , Eq , Hash ) ] pub enum CSSPseudoElementType { after = 0 , before = 1 , backdrop = 2 , cue = 3 , firstLetter = 4 , firstLine = 5 , mozSelection = 6 , mozFocusInner = 7 , mozFocusOuter = 8 , mozListBullet = 9 , mozListNumber = 10 , mozMathAnonymous = 11 , mozNumberWrapper = 12 , mozNumberText = 13 , mozNumberSpinBox = 14 , mozNumberSpinUp = 15 , mozNumberSpinDown = 16 , mozProgressBar = 17 , mozRangeTrack = 18 , mozRangeProgress = 19 , mozRangeThumb = 20 , mozMeterBar = 21 , mozPlaceholder = 22 , placeholder = 23 , mozColorSwatch = 24 , Count = 25 , NonInheritingAnonBox = 26 , XULTree = 27 , NotPseudo = 28 , MAX = 29 , } /// Smart pointer class that can hold a pointer to either an nsStyleSet /// or a ServoStyleSet. - # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct StyleSetHandle { pub mPtr : root :: mozilla :: StyleSetHandle_Ptr , } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct StyleSetHandle_Ptr { pub mValue : usize , } # [ test ] fn bindgen_test_layout_StyleSetHandle_Ptr ( ) { assert_eq ! ( :: std :: mem :: size_of :: < StyleSetHandle_Ptr > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( StyleSetHandle_Ptr ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < StyleSetHandle_Ptr > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( StyleSetHandle_Ptr ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const StyleSetHandle_Ptr ) ) . mValue as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( StyleSetHandle_Ptr ) , "::" , stringify ! ( mValue ) ) ) ; } impl Clone for StyleSetHandle_Ptr { fn clone ( & self ) -> Self { * self } } # [ test ] fn bindgen_test_layout_StyleSetHandle ( ) { assert_eq ! ( :: std :: mem :: size_of :: < StyleSetHandle > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( StyleSetHandle ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < StyleSetHandle > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( StyleSetHandle ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const StyleSetHandle ) ) . mPtr as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( StyleSetHandle ) , "::" , stringify ! ( mPtr ) ) ) ; } impl Clone for StyleSetHandle { fn clone ( & self ) -> Self { * self } } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct SeenPtrs { pub _bindgen_opaque_blob : [ u64 ; 4usize ] , } # [ test ] fn bindgen_test_layout_SeenPtrs ( ) { assert_eq ! ( :: std :: mem :: size_of :: < SeenPtrs > ( ) , 32usize , concat ! ( "Size of: " , stringify ! ( SeenPtrs ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < SeenPtrs > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( SeenPtrs ) ) ) ; } impl Clone for SeenPtrs { fn clone ( & self ) -> Self { * self } } pub mod widget { # [ allow ( unused_imports ) ] use self :: super :: super :: super :: root ; # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct IMEState { _unused : [ u8 ; 0 ] } } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct ArenaAllocator_ArenaHeader { + # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct StyleSetHandle { pub mPtr : root :: mozilla :: StyleSetHandle_Ptr , } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct StyleSetHandle_Ptr { pub mValue : usize , } # [ test ] fn bindgen_test_layout_StyleSetHandle_Ptr ( ) { assert_eq ! ( :: std :: mem :: size_of :: < StyleSetHandle_Ptr > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( StyleSetHandle_Ptr ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < StyleSetHandle_Ptr > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( StyleSetHandle_Ptr ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const StyleSetHandle_Ptr ) ) . mValue as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( StyleSetHandle_Ptr ) , "::" , stringify ! ( mValue ) ) ) ; } impl Clone for StyleSetHandle_Ptr { fn clone ( & self ) -> Self { * self } } # [ test ] fn bindgen_test_layout_StyleSetHandle ( ) { assert_eq ! ( :: std :: mem :: size_of :: < StyleSetHandle > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( StyleSetHandle ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < StyleSetHandle > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( StyleSetHandle ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const StyleSetHandle ) ) . mPtr as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( StyleSetHandle ) , "::" , stringify ! ( mPtr ) ) ) ; } impl Clone for StyleSetHandle { fn clone ( & self ) -> Self { * self } } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct SeenPtrs { pub _bindgen_opaque_blob : [ u64 ; 4usize ] , } # [ test ] fn bindgen_test_layout_SeenPtrs ( ) { assert_eq ! ( :: std :: mem :: size_of :: < SeenPtrs > ( ) , 32usize , concat ! ( "Size of: " , stringify ! ( SeenPtrs ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < SeenPtrs > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( SeenPtrs ) ) ) ; } impl Clone for SeenPtrs { fn clone ( & self ) -> Self { * self } } pub mod widget { # [ allow ( unused_imports ) ] use self :: super :: super :: super :: root ; # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct IMEState { _unused : [ u8 ; 0 ] } } + /// This class is designed to cause crashes when various kinds of memory + /// corruption are observed. For instance, let's say we have a class C where we + /// suspect out-of-bounds writes to some members. We can insert a member of type + /// Poison near the members we suspect are being corrupted by out-of-bounds + /// writes. Or perhaps we have a class K we suspect is subject to use-after-free + /// violations, in which case it doesn't particularly matter where in the class + /// we add the member of type Poison. + /// + /// In either case, we then insert calls to Check() throughout the code. Doing + /// so enables us to narrow down the location where the corruption is occurring. + /// A pleasant side-effect of these additional Check() calls is that crash + /// signatures may become more regular, as crashes will ideally occur + /// consolidated at the point of a Check(), rather than scattered about at + /// various uses of the corrupted memory. + # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct CorruptionCanary { pub mValue : usize , } pub const CorruptionCanary_kCanarySet : usize = 252382987 ; # [ test ] fn bindgen_test_layout_CorruptionCanary ( ) { assert_eq ! ( :: std :: mem :: size_of :: < CorruptionCanary > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( CorruptionCanary ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < CorruptionCanary > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( CorruptionCanary ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const CorruptionCanary ) ) . mValue as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( CorruptionCanary ) , "::" , stringify ! ( mValue ) ) ) ; } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct ArenaAllocator_ArenaHeader { /// The location in memory of the data portion of the arena. pub offset : usize , /// The location in memory of the end of the data portion of the arena. - pub tail : usize , } impl Clone for ArenaAllocator_ArenaHeader { fn clone ( & self ) -> Self { * self } } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct ArenaAllocator_ArenaChunk { pub header : root :: mozilla :: ArenaAllocator_ArenaHeader , pub next : * mut root :: mozilla :: ArenaAllocator_ArenaChunk , } impl Clone for ArenaAllocator_ArenaChunk { fn clone ( & self ) -> Self { * self } } pub mod a11y { # [ allow ( unused_imports ) ] use self :: super :: super :: super :: root ; # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct DocAccessible { _unused : [ u8 ; 0 ] } } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct Encoding { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct Runnable { pub _base : root :: nsIRunnable , pub _base_1 : root :: nsINamed , pub mRefCnt : root :: mozilla :: ThreadSafeAutoRefCnt , pub mName : * const :: std :: os :: raw :: c_char , } pub type Runnable_HasThreadSafeRefCnt = root :: mozilla :: TrueType ; # [ test ] fn bindgen_test_layout_Runnable ( ) { assert_eq ! ( :: std :: mem :: size_of :: < Runnable > ( ) , 32usize , concat ! ( "Size of: " , stringify ! ( Runnable ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < Runnable > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( Runnable ) ) ) ; } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct SegmentedVector_SegmentImpl_Storage { pub mBuf : root :: __BindgenUnionField < * mut :: std :: os :: raw :: c_char > , pub mAlign : root :: __BindgenUnionField < u8 > , pub bindgen_union_field : u64 , } pub type SegmentedVector_Segment = u8 ; # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct SegmentedVector_IterImpl { pub mSegment : * mut root :: mozilla :: SegmentedVector_Segment , pub mIndex : usize , } pub const UseCounter_eUseCounter_UNKNOWN : root :: mozilla :: UseCounter = -1 ; pub const UseCounter_eUseCounter_SVGSVGElement_getElementById : root :: mozilla :: UseCounter = 0 ; pub const UseCounter_eUseCounter_SVGSVGElement_currentScale_getter : root :: mozilla :: UseCounter = 1 ; pub const UseCounter_eUseCounter_SVGSVGElement_currentScale_setter : root :: mozilla :: UseCounter = 2 ; pub const UseCounter_eUseCounter_property_Fill : root :: mozilla :: UseCounter = 3 ; pub const UseCounter_eUseCounter_property_FillOpacity : root :: mozilla :: UseCounter = 4 ; pub const UseCounter_eUseCounter_XMLDocument_async_getter : root :: mozilla :: UseCounter = 5 ; pub const UseCounter_eUseCounter_XMLDocument_async_setter : root :: mozilla :: UseCounter = 6 ; pub const UseCounter_eUseCounter_DOMError_name_getter : root :: mozilla :: UseCounter = 7 ; pub const UseCounter_eUseCounter_DOMError_name_setter : root :: mozilla :: UseCounter = 8 ; pub const UseCounter_eUseCounter_DOMError_message_getter : root :: mozilla :: UseCounter = 9 ; pub const UseCounter_eUseCounter_DOMError_message_setter : root :: mozilla :: UseCounter = 10 ; pub const UseCounter_eUseCounter_custom_DOMErrorConstructor : root :: mozilla :: UseCounter = 11 ; pub const UseCounter_eUseCounter_PushManager_subscribe : root :: mozilla :: UseCounter = 12 ; pub const UseCounter_eUseCounter_PushSubscription_unsubscribe : root :: mozilla :: UseCounter = 13 ; pub const UseCounter_eUseCounter_Window_sidebar_getter : root :: mozilla :: UseCounter = 14 ; pub const UseCounter_eUseCounter_Window_sidebar_setter : root :: mozilla :: UseCounter = 15 ; pub const UseCounter_eUseCounter_External_addSearchEngine : root :: mozilla :: UseCounter = 16 ; pub const UseCounter_eUseCounter_OfflineResourceList_swapCache : root :: mozilla :: UseCounter = 17 ; pub const UseCounter_eUseCounter_OfflineResourceList_update : root :: mozilla :: UseCounter = 18 ; pub const UseCounter_eUseCounter_OfflineResourceList_status_getter : root :: mozilla :: UseCounter = 19 ; pub const UseCounter_eUseCounter_OfflineResourceList_status_setter : root :: mozilla :: UseCounter = 20 ; pub const UseCounter_eUseCounter_OfflineResourceList_onchecking_getter : root :: mozilla :: UseCounter = 21 ; pub const UseCounter_eUseCounter_OfflineResourceList_onchecking_setter : root :: mozilla :: UseCounter = 22 ; pub const UseCounter_eUseCounter_OfflineResourceList_onerror_getter : root :: mozilla :: UseCounter = 23 ; pub const UseCounter_eUseCounter_OfflineResourceList_onerror_setter : root :: mozilla :: UseCounter = 24 ; pub const UseCounter_eUseCounter_OfflineResourceList_onnoupdate_getter : root :: mozilla :: UseCounter = 25 ; pub const UseCounter_eUseCounter_OfflineResourceList_onnoupdate_setter : root :: mozilla :: UseCounter = 26 ; pub const UseCounter_eUseCounter_OfflineResourceList_ondownloading_getter : root :: mozilla :: UseCounter = 27 ; pub const UseCounter_eUseCounter_OfflineResourceList_ondownloading_setter : root :: mozilla :: UseCounter = 28 ; pub const UseCounter_eUseCounter_OfflineResourceList_onprogress_getter : root :: mozilla :: UseCounter = 29 ; pub const UseCounter_eUseCounter_OfflineResourceList_onprogress_setter : root :: mozilla :: UseCounter = 30 ; pub const UseCounter_eUseCounter_OfflineResourceList_onupdateready_getter : root :: mozilla :: UseCounter = 31 ; pub const UseCounter_eUseCounter_OfflineResourceList_onupdateready_setter : root :: mozilla :: UseCounter = 32 ; pub const UseCounter_eUseCounter_OfflineResourceList_oncached_getter : root :: mozilla :: UseCounter = 33 ; pub const UseCounter_eUseCounter_OfflineResourceList_oncached_setter : root :: mozilla :: UseCounter = 34 ; pub const UseCounter_eUseCounter_OfflineResourceList_onobsolete_getter : root :: mozilla :: UseCounter = 35 ; pub const UseCounter_eUseCounter_OfflineResourceList_onobsolete_setter : root :: mozilla :: UseCounter = 36 ; pub const UseCounter_eUseCounter_IDBDatabase_createMutableFile : root :: mozilla :: UseCounter = 37 ; pub const UseCounter_eUseCounter_IDBDatabase_mozCreateFileHandle : root :: mozilla :: UseCounter = 38 ; pub const UseCounter_eUseCounter_IDBMutableFile_open : root :: mozilla :: UseCounter = 39 ; pub const UseCounter_eUseCounter_IDBMutableFile_getFile : root :: mozilla :: UseCounter = 40 ; pub const UseCounter_eUseCounter_DataTransfer_addElement : root :: mozilla :: UseCounter = 41 ; pub const UseCounter_eUseCounter_DataTransfer_mozItemCount_getter : root :: mozilla :: UseCounter = 42 ; pub const UseCounter_eUseCounter_DataTransfer_mozItemCount_setter : root :: mozilla :: UseCounter = 43 ; pub const UseCounter_eUseCounter_DataTransfer_mozCursor_getter : root :: mozilla :: UseCounter = 44 ; pub const UseCounter_eUseCounter_DataTransfer_mozCursor_setter : root :: mozilla :: UseCounter = 45 ; pub const UseCounter_eUseCounter_DataTransfer_mozTypesAt : root :: mozilla :: UseCounter = 46 ; pub const UseCounter_eUseCounter_DataTransfer_mozClearDataAt : root :: mozilla :: UseCounter = 47 ; pub const UseCounter_eUseCounter_DataTransfer_mozSetDataAt : root :: mozilla :: UseCounter = 48 ; pub const UseCounter_eUseCounter_DataTransfer_mozGetDataAt : root :: mozilla :: UseCounter = 49 ; pub const UseCounter_eUseCounter_DataTransfer_mozUserCancelled_getter : root :: mozilla :: UseCounter = 50 ; pub const UseCounter_eUseCounter_DataTransfer_mozUserCancelled_setter : root :: mozilla :: UseCounter = 51 ; pub const UseCounter_eUseCounter_DataTransfer_mozSourceNode_getter : root :: mozilla :: UseCounter = 52 ; pub const UseCounter_eUseCounter_DataTransfer_mozSourceNode_setter : root :: mozilla :: UseCounter = 53 ; pub const UseCounter_eUseCounter_custom_JS_asmjs : root :: mozilla :: UseCounter = 54 ; pub const UseCounter_eUseCounter_custom_JS_wasm : root :: mozilla :: UseCounter = 55 ; pub const UseCounter_eUseCounter_EnablePrivilege : root :: mozilla :: UseCounter = 56 ; pub const UseCounter_eUseCounter_DOMExceptionCode : root :: mozilla :: UseCounter = 57 ; pub const UseCounter_eUseCounter_MutationEvent : root :: mozilla :: UseCounter = 58 ; pub const UseCounter_eUseCounter_Components : root :: mozilla :: UseCounter = 59 ; pub const UseCounter_eUseCounter_PrefixedVisibilityAPI : root :: mozilla :: UseCounter = 60 ; pub const UseCounter_eUseCounter_NodeIteratorDetach : root :: mozilla :: UseCounter = 61 ; pub const UseCounter_eUseCounter_LenientThis : root :: mozilla :: UseCounter = 62 ; pub const UseCounter_eUseCounter_GetPreventDefault : root :: mozilla :: UseCounter = 63 ; pub const UseCounter_eUseCounter_GetSetUserData : root :: mozilla :: UseCounter = 64 ; pub const UseCounter_eUseCounter_MozGetAsFile : root :: mozilla :: UseCounter = 65 ; pub const UseCounter_eUseCounter_UseOfCaptureEvents : root :: mozilla :: UseCounter = 66 ; pub const UseCounter_eUseCounter_UseOfReleaseEvents : root :: mozilla :: UseCounter = 67 ; pub const UseCounter_eUseCounter_UseOfDOM3LoadMethod : root :: mozilla :: UseCounter = 68 ; pub const UseCounter_eUseCounter_ChromeUseOfDOM3LoadMethod : root :: mozilla :: UseCounter = 69 ; pub const UseCounter_eUseCounter_ShowModalDialog : root :: mozilla :: UseCounter = 70 ; pub const UseCounter_eUseCounter_SyncXMLHttpRequest : root :: mozilla :: UseCounter = 71 ; pub const UseCounter_eUseCounter_Window_Cc_ontrollers : root :: mozilla :: UseCounter = 72 ; pub const UseCounter_eUseCounter_ImportXULIntoContent : root :: mozilla :: UseCounter = 73 ; pub const UseCounter_eUseCounter_PannerNodeDoppler : root :: mozilla :: UseCounter = 74 ; pub const UseCounter_eUseCounter_NavigatorGetUserMedia : root :: mozilla :: UseCounter = 75 ; pub const UseCounter_eUseCounter_WebrtcDeprecatedPrefix : root :: mozilla :: UseCounter = 76 ; pub const UseCounter_eUseCounter_RTCPeerConnectionGetStreams : root :: mozilla :: UseCounter = 77 ; pub const UseCounter_eUseCounter_AppCache : root :: mozilla :: UseCounter = 78 ; pub const UseCounter_eUseCounter_PrefixedImageSmoothingEnabled : root :: mozilla :: UseCounter = 79 ; pub const UseCounter_eUseCounter_PrefixedFullscreenAPI : root :: mozilla :: UseCounter = 80 ; pub const UseCounter_eUseCounter_LenientSetter : root :: mozilla :: UseCounter = 81 ; pub const UseCounter_eUseCounter_FileLastModifiedDate : root :: mozilla :: UseCounter = 82 ; pub const UseCounter_eUseCounter_ImageBitmapRenderingContext_TransferImageBitmap : root :: mozilla :: UseCounter = 83 ; pub const UseCounter_eUseCounter_URLCreateObjectURL_MediaStream : root :: mozilla :: UseCounter = 84 ; pub const UseCounter_eUseCounter_XMLBaseAttribute : root :: mozilla :: UseCounter = 85 ; pub const UseCounter_eUseCounter_WindowContentUntrusted : root :: mozilla :: UseCounter = 86 ; pub const UseCounter_eUseCounter_Count : root :: mozilla :: UseCounter = 87 ; pub type UseCounter = i16 ; # [ test ] fn __bindgen_test_layout_DefaultDelete_open0_RawServoStyleSet_close0_instantiation ( ) { assert_eq ! ( :: std :: mem :: size_of :: < root :: mozilla :: DefaultDelete > ( ) , 1usize , concat ! ( "Size of template specialization: " , stringify ! ( root :: mozilla :: DefaultDelete ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < root :: mozilla :: DefaultDelete > ( ) , 1usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root :: mozilla :: DefaultDelete ) ) ) ; } # [ test ] fn __bindgen_test_layout_DefaultDelete_open0_RawServoSelectorList_close0_instantiation ( ) { assert_eq ! ( :: std :: mem :: size_of :: < root :: mozilla :: DefaultDelete > ( ) , 1usize , concat ! ( "Size of template specialization: " , stringify ! ( root :: mozilla :: DefaultDelete ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < root :: mozilla :: DefaultDelete > ( ) , 1usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root :: mozilla :: DefaultDelete ) ) ) ; } # [ test ] fn __bindgen_test_layout_DefaultDelete_open0_RawServoSourceSizeList_close0_instantiation ( ) { assert_eq ! ( :: std :: mem :: size_of :: < root :: mozilla :: DefaultDelete > ( ) , 1usize , concat ! ( "Size of template specialization: " , stringify ! ( root :: mozilla :: DefaultDelete ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < root :: mozilla :: DefaultDelete > ( ) , 1usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root :: mozilla :: DefaultDelete ) ) ) ; } # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct ScrollbarStyles { pub mHorizontal : u8 , pub mVertical : u8 , pub mScrollBehavior : u8 , pub mScrollSnapTypeX : u8 , pub mScrollSnapTypeY : u8 , pub mScrollSnapPointsX : root :: nsStyleCoord , pub mScrollSnapPointsY : root :: nsStyleCoord , pub mScrollSnapDestinationX : root :: nsStyleCoord_CalcValue , pub mScrollSnapDestinationY : root :: nsStyleCoord_CalcValue , } # [ test ] fn bindgen_test_layout_ScrollbarStyles ( ) { assert_eq ! ( :: std :: mem :: size_of :: < ScrollbarStyles > ( ) , 64usize , concat ! ( "Size of: " , stringify ! ( ScrollbarStyles ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < ScrollbarStyles > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( ScrollbarStyles ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ScrollbarStyles ) ) . mHorizontal as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( ScrollbarStyles ) , "::" , stringify ! ( mHorizontal ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ScrollbarStyles ) ) . mVertical as * const _ as usize } , 1usize , concat ! ( "Alignment of field: " , stringify ! ( ScrollbarStyles ) , "::" , stringify ! ( mVertical ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ScrollbarStyles ) ) . mScrollBehavior as * const _ as usize } , 2usize , concat ! ( "Alignment of field: " , stringify ! ( ScrollbarStyles ) , "::" , stringify ! ( mScrollBehavior ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ScrollbarStyles ) ) . mScrollSnapTypeX as * const _ as usize } , 3usize , concat ! ( "Alignment of field: " , stringify ! ( ScrollbarStyles ) , "::" , stringify ! ( mScrollSnapTypeX ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ScrollbarStyles ) ) . mScrollSnapTypeY as * const _ as usize } , 4usize , concat ! ( "Alignment of field: " , stringify ! ( ScrollbarStyles ) , "::" , stringify ! ( mScrollSnapTypeY ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ScrollbarStyles ) ) . mScrollSnapPointsX as * const _ as usize } , 8usize , concat ! ( "Alignment of field: " , stringify ! ( ScrollbarStyles ) , "::" , stringify ! ( mScrollSnapPointsX ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ScrollbarStyles ) ) . mScrollSnapPointsY as * const _ as usize } , 24usize , concat ! ( "Alignment of field: " , stringify ! ( ScrollbarStyles ) , "::" , stringify ! ( mScrollSnapPointsY ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ScrollbarStyles ) ) . mScrollSnapDestinationX as * const _ as usize } , 40usize , concat ! ( "Alignment of field: " , stringify ! ( ScrollbarStyles ) , "::" , stringify ! ( mScrollSnapDestinationX ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ScrollbarStyles ) ) . mScrollSnapDestinationY as * const _ as usize } , 52usize , concat ! ( "Alignment of field: " , stringify ! ( ScrollbarStyles ) , "::" , stringify ! ( mScrollSnapDestinationY ) ) ) ; } # [ repr ( C ) ] pub struct LangGroupFontPrefs { pub mLangGroup : root :: RefPtr < root :: nsAtom > , pub mMinimumFontSize : root :: nscoord , pub mDefaultVariableFont : root :: nsFont , pub mDefaultFixedFont : root :: nsFont , pub mDefaultSerifFont : root :: nsFont , pub mDefaultSansSerifFont : root :: nsFont , pub mDefaultMonospaceFont : root :: nsFont , pub mDefaultCursiveFont : root :: nsFont , pub mDefaultFantasyFont : root :: nsFont , pub mNext : root :: nsAutoPtr < root :: mozilla :: LangGroupFontPrefs > , } # [ test ] fn bindgen_test_layout_LangGroupFontPrefs ( ) { assert_eq ! ( :: std :: mem :: size_of :: < LangGroupFontPrefs > ( ) , 696usize , concat ! ( "Size of: " , stringify ! ( LangGroupFontPrefs ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < LangGroupFontPrefs > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( LangGroupFontPrefs ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const LangGroupFontPrefs ) ) . mLangGroup as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( LangGroupFontPrefs ) , "::" , stringify ! ( mLangGroup ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const LangGroupFontPrefs ) ) . mMinimumFontSize as * const _ as usize } , 8usize , concat ! ( "Alignment of field: " , stringify ! ( LangGroupFontPrefs ) , "::" , stringify ! ( mMinimumFontSize ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const LangGroupFontPrefs ) ) . mDefaultVariableFont as * const _ as usize } , 16usize , concat ! ( "Alignment of field: " , stringify ! ( LangGroupFontPrefs ) , "::" , stringify ! ( mDefaultVariableFont ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const LangGroupFontPrefs ) ) . mDefaultFixedFont as * const _ as usize } , 112usize , concat ! ( "Alignment of field: " , stringify ! ( LangGroupFontPrefs ) , "::" , stringify ! ( mDefaultFixedFont ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const LangGroupFontPrefs ) ) . mDefaultSerifFont as * const _ as usize } , 208usize , concat ! ( "Alignment of field: " , stringify ! ( LangGroupFontPrefs ) , "::" , stringify ! ( mDefaultSerifFont ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const LangGroupFontPrefs ) ) . mDefaultSansSerifFont as * const _ as usize } , 304usize , concat ! ( "Alignment of field: " , stringify ! ( LangGroupFontPrefs ) , "::" , stringify ! ( mDefaultSansSerifFont ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const LangGroupFontPrefs ) ) . mDefaultMonospaceFont as * const _ as usize } , 400usize , concat ! ( "Alignment of field: " , stringify ! ( LangGroupFontPrefs ) , "::" , stringify ! ( mDefaultMonospaceFont ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const LangGroupFontPrefs ) ) . mDefaultCursiveFont as * const _ as usize } , 496usize , concat ! ( "Alignment of field: " , stringify ! ( LangGroupFontPrefs ) , "::" , stringify ! ( mDefaultCursiveFont ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const LangGroupFontPrefs ) ) . mDefaultFantasyFont as * const _ as usize } , 592usize , concat ! ( "Alignment of field: " , stringify ! ( LangGroupFontPrefs ) , "::" , stringify ! ( mDefaultFantasyFont ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const LangGroupFontPrefs ) ) . mNext as * const _ as usize } , 688usize , concat ! ( "Alignment of field: " , stringify ! ( LangGroupFontPrefs ) , "::" , stringify ! ( mNext ) ) ) ; } + pub tail : usize , } impl Clone for ArenaAllocator_ArenaHeader { fn clone ( & self ) -> Self { * self } } # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct ArenaAllocator_ArenaChunk { pub canary : root :: mozilla :: CorruptionCanary , pub header : root :: mozilla :: ArenaAllocator_ArenaHeader , pub next : * mut root :: mozilla :: ArenaAllocator_ArenaChunk , } pub mod a11y { # [ allow ( unused_imports ) ] use self :: super :: super :: super :: root ; # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct DocAccessible { _unused : [ u8 ; 0 ] } } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct Encoding { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct Runnable { pub _base : root :: nsIRunnable , pub _base_1 : root :: nsINamed , pub mRefCnt : root :: mozilla :: ThreadSafeAutoRefCnt , pub mName : * const :: std :: os :: raw :: c_char , } pub type Runnable_HasThreadSafeRefCnt = root :: mozilla :: TrueType ; # [ test ] fn bindgen_test_layout_Runnable ( ) { assert_eq ! ( :: std :: mem :: size_of :: < Runnable > ( ) , 32usize , concat ! ( "Size of: " , stringify ! ( Runnable ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < Runnable > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( Runnable ) ) ) ; } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct SegmentedVector_SegmentImpl_Storage { pub mBuf : root :: __BindgenUnionField < * mut :: std :: os :: raw :: c_char > , pub mAlign : root :: __BindgenUnionField < u8 > , pub bindgen_union_field : u64 , } pub type SegmentedVector_Segment = u8 ; # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct SegmentedVector_IterImpl { pub mSegment : * mut root :: mozilla :: SegmentedVector_Segment , pub mIndex : usize , } pub const UseCounter_eUseCounter_UNKNOWN : root :: mozilla :: UseCounter = -1 ; pub const UseCounter_eUseCounter_SVGSVGElement_getElementById : root :: mozilla :: UseCounter = 0 ; pub const UseCounter_eUseCounter_SVGSVGElement_currentScale_getter : root :: mozilla :: UseCounter = 1 ; pub const UseCounter_eUseCounter_SVGSVGElement_currentScale_setter : root :: mozilla :: UseCounter = 2 ; pub const UseCounter_eUseCounter_property_Fill : root :: mozilla :: UseCounter = 3 ; pub const UseCounter_eUseCounter_property_FillOpacity : root :: mozilla :: UseCounter = 4 ; pub const UseCounter_eUseCounter_XMLDocument_async_getter : root :: mozilla :: UseCounter = 5 ; pub const UseCounter_eUseCounter_XMLDocument_async_setter : root :: mozilla :: UseCounter = 6 ; pub const UseCounter_eUseCounter_DOMError_name_getter : root :: mozilla :: UseCounter = 7 ; pub const UseCounter_eUseCounter_DOMError_name_setter : root :: mozilla :: UseCounter = 8 ; pub const UseCounter_eUseCounter_DOMError_message_getter : root :: mozilla :: UseCounter = 9 ; pub const UseCounter_eUseCounter_DOMError_message_setter : root :: mozilla :: UseCounter = 10 ; pub const UseCounter_eUseCounter_custom_DOMErrorConstructor : root :: mozilla :: UseCounter = 11 ; pub const UseCounter_eUseCounter_PushManager_subscribe : root :: mozilla :: UseCounter = 12 ; pub const UseCounter_eUseCounter_PushSubscription_unsubscribe : root :: mozilla :: UseCounter = 13 ; pub const UseCounter_eUseCounter_Window_sidebar_getter : root :: mozilla :: UseCounter = 14 ; pub const UseCounter_eUseCounter_Window_sidebar_setter : root :: mozilla :: UseCounter = 15 ; pub const UseCounter_eUseCounter_External_addSearchEngine : root :: mozilla :: UseCounter = 16 ; pub const UseCounter_eUseCounter_OfflineResourceList_swapCache : root :: mozilla :: UseCounter = 17 ; pub const UseCounter_eUseCounter_OfflineResourceList_update : root :: mozilla :: UseCounter = 18 ; pub const UseCounter_eUseCounter_OfflineResourceList_status_getter : root :: mozilla :: UseCounter = 19 ; pub const UseCounter_eUseCounter_OfflineResourceList_status_setter : root :: mozilla :: UseCounter = 20 ; pub const UseCounter_eUseCounter_OfflineResourceList_onchecking_getter : root :: mozilla :: UseCounter = 21 ; pub const UseCounter_eUseCounter_OfflineResourceList_onchecking_setter : root :: mozilla :: UseCounter = 22 ; pub const UseCounter_eUseCounter_OfflineResourceList_onerror_getter : root :: mozilla :: UseCounter = 23 ; pub const UseCounter_eUseCounter_OfflineResourceList_onerror_setter : root :: mozilla :: UseCounter = 24 ; pub const UseCounter_eUseCounter_OfflineResourceList_onnoupdate_getter : root :: mozilla :: UseCounter = 25 ; pub const UseCounter_eUseCounter_OfflineResourceList_onnoupdate_setter : root :: mozilla :: UseCounter = 26 ; pub const UseCounter_eUseCounter_OfflineResourceList_ondownloading_getter : root :: mozilla :: UseCounter = 27 ; pub const UseCounter_eUseCounter_OfflineResourceList_ondownloading_setter : root :: mozilla :: UseCounter = 28 ; pub const UseCounter_eUseCounter_OfflineResourceList_onprogress_getter : root :: mozilla :: UseCounter = 29 ; pub const UseCounter_eUseCounter_OfflineResourceList_onprogress_setter : root :: mozilla :: UseCounter = 30 ; pub const UseCounter_eUseCounter_OfflineResourceList_onupdateready_getter : root :: mozilla :: UseCounter = 31 ; pub const UseCounter_eUseCounter_OfflineResourceList_onupdateready_setter : root :: mozilla :: UseCounter = 32 ; pub const UseCounter_eUseCounter_OfflineResourceList_oncached_getter : root :: mozilla :: UseCounter = 33 ; pub const UseCounter_eUseCounter_OfflineResourceList_oncached_setter : root :: mozilla :: UseCounter = 34 ; pub const UseCounter_eUseCounter_OfflineResourceList_onobsolete_getter : root :: mozilla :: UseCounter = 35 ; pub const UseCounter_eUseCounter_OfflineResourceList_onobsolete_setter : root :: mozilla :: UseCounter = 36 ; pub const UseCounter_eUseCounter_IDBDatabase_createMutableFile : root :: mozilla :: UseCounter = 37 ; pub const UseCounter_eUseCounter_IDBDatabase_mozCreateFileHandle : root :: mozilla :: UseCounter = 38 ; pub const UseCounter_eUseCounter_IDBMutableFile_open : root :: mozilla :: UseCounter = 39 ; pub const UseCounter_eUseCounter_IDBMutableFile_getFile : root :: mozilla :: UseCounter = 40 ; pub const UseCounter_eUseCounter_DataTransfer_addElement : root :: mozilla :: UseCounter = 41 ; pub const UseCounter_eUseCounter_DataTransfer_mozItemCount_getter : root :: mozilla :: UseCounter = 42 ; pub const UseCounter_eUseCounter_DataTransfer_mozItemCount_setter : root :: mozilla :: UseCounter = 43 ; pub const UseCounter_eUseCounter_DataTransfer_mozCursor_getter : root :: mozilla :: UseCounter = 44 ; pub const UseCounter_eUseCounter_DataTransfer_mozCursor_setter : root :: mozilla :: UseCounter = 45 ; pub const UseCounter_eUseCounter_DataTransfer_mozTypesAt : root :: mozilla :: UseCounter = 46 ; pub const UseCounter_eUseCounter_DataTransfer_mozClearDataAt : root :: mozilla :: UseCounter = 47 ; pub const UseCounter_eUseCounter_DataTransfer_mozSetDataAt : root :: mozilla :: UseCounter = 48 ; pub const UseCounter_eUseCounter_DataTransfer_mozGetDataAt : root :: mozilla :: UseCounter = 49 ; pub const UseCounter_eUseCounter_DataTransfer_mozUserCancelled_getter : root :: mozilla :: UseCounter = 50 ; pub const UseCounter_eUseCounter_DataTransfer_mozUserCancelled_setter : root :: mozilla :: UseCounter = 51 ; pub const UseCounter_eUseCounter_DataTransfer_mozSourceNode_getter : root :: mozilla :: UseCounter = 52 ; pub const UseCounter_eUseCounter_DataTransfer_mozSourceNode_setter : root :: mozilla :: UseCounter = 53 ; pub const UseCounter_eUseCounter_custom_JS_asmjs : root :: mozilla :: UseCounter = 54 ; pub const UseCounter_eUseCounter_custom_JS_wasm : root :: mozilla :: UseCounter = 55 ; pub const UseCounter_eUseCounter_EnablePrivilege : root :: mozilla :: UseCounter = 56 ; pub const UseCounter_eUseCounter_DOMExceptionCode : root :: mozilla :: UseCounter = 57 ; pub const UseCounter_eUseCounter_MutationEvent : root :: mozilla :: UseCounter = 58 ; pub const UseCounter_eUseCounter_Components : root :: mozilla :: UseCounter = 59 ; pub const UseCounter_eUseCounter_PrefixedVisibilityAPI : root :: mozilla :: UseCounter = 60 ; pub const UseCounter_eUseCounter_NodeIteratorDetach : root :: mozilla :: UseCounter = 61 ; pub const UseCounter_eUseCounter_LenientThis : root :: mozilla :: UseCounter = 62 ; pub const UseCounter_eUseCounter_GetPreventDefault : root :: mozilla :: UseCounter = 63 ; pub const UseCounter_eUseCounter_GetSetUserData : root :: mozilla :: UseCounter = 64 ; pub const UseCounter_eUseCounter_MozGetAsFile : root :: mozilla :: UseCounter = 65 ; pub const UseCounter_eUseCounter_UseOfCaptureEvents : root :: mozilla :: UseCounter = 66 ; pub const UseCounter_eUseCounter_UseOfReleaseEvents : root :: mozilla :: UseCounter = 67 ; pub const UseCounter_eUseCounter_UseOfDOM3LoadMethod : root :: mozilla :: UseCounter = 68 ; pub const UseCounter_eUseCounter_ChromeUseOfDOM3LoadMethod : root :: mozilla :: UseCounter = 69 ; pub const UseCounter_eUseCounter_ShowModalDialog : root :: mozilla :: UseCounter = 70 ; pub const UseCounter_eUseCounter_SyncXMLHttpRequest : root :: mozilla :: UseCounter = 71 ; pub const UseCounter_eUseCounter_Window_Cc_ontrollers : root :: mozilla :: UseCounter = 72 ; pub const UseCounter_eUseCounter_ImportXULIntoContent : root :: mozilla :: UseCounter = 73 ; pub const UseCounter_eUseCounter_PannerNodeDoppler : root :: mozilla :: UseCounter = 74 ; pub const UseCounter_eUseCounter_NavigatorGetUserMedia : root :: mozilla :: UseCounter = 75 ; pub const UseCounter_eUseCounter_WebrtcDeprecatedPrefix : root :: mozilla :: UseCounter = 76 ; pub const UseCounter_eUseCounter_RTCPeerConnectionGetStreams : root :: mozilla :: UseCounter = 77 ; pub const UseCounter_eUseCounter_AppCache : root :: mozilla :: UseCounter = 78 ; pub const UseCounter_eUseCounter_PrefixedImageSmoothingEnabled : root :: mozilla :: UseCounter = 79 ; pub const UseCounter_eUseCounter_PrefixedFullscreenAPI : root :: mozilla :: UseCounter = 80 ; pub const UseCounter_eUseCounter_LenientSetter : root :: mozilla :: UseCounter = 81 ; pub const UseCounter_eUseCounter_FileLastModifiedDate : root :: mozilla :: UseCounter = 82 ; pub const UseCounter_eUseCounter_ImageBitmapRenderingContext_TransferImageBitmap : root :: mozilla :: UseCounter = 83 ; pub const UseCounter_eUseCounter_URLCreateObjectURL_MediaStream : root :: mozilla :: UseCounter = 84 ; pub const UseCounter_eUseCounter_XMLBaseAttribute : root :: mozilla :: UseCounter = 85 ; pub const UseCounter_eUseCounter_WindowContentUntrusted : root :: mozilla :: UseCounter = 86 ; pub const UseCounter_eUseCounter_Count : root :: mozilla :: UseCounter = 87 ; pub type UseCounter = i16 ; # [ test ] fn __bindgen_test_layout_DefaultDelete_open0_RawServoStyleSet_close0_instantiation ( ) { assert_eq ! ( :: std :: mem :: size_of :: < root :: mozilla :: DefaultDelete > ( ) , 1usize , concat ! ( "Size of template specialization: " , stringify ! ( root :: mozilla :: DefaultDelete ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < root :: mozilla :: DefaultDelete > ( ) , 1usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root :: mozilla :: DefaultDelete ) ) ) ; } # [ test ] fn __bindgen_test_layout_DefaultDelete_open0_RawServoSelectorList_close0_instantiation ( ) { assert_eq ! ( :: std :: mem :: size_of :: < root :: mozilla :: DefaultDelete > ( ) , 1usize , concat ! ( "Size of template specialization: " , stringify ! ( root :: mozilla :: DefaultDelete ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < root :: mozilla :: DefaultDelete > ( ) , 1usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root :: mozilla :: DefaultDelete ) ) ) ; } # [ test ] fn __bindgen_test_layout_DefaultDelete_open0_RawServoSourceSizeList_close0_instantiation ( ) { assert_eq ! ( :: std :: mem :: size_of :: < root :: mozilla :: DefaultDelete > ( ) , 1usize , concat ! ( "Size of template specialization: " , stringify ! ( root :: mozilla :: DefaultDelete ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < root :: mozilla :: DefaultDelete > ( ) , 1usize , concat ! ( "Alignment of template specialization: " , stringify ! ( root :: mozilla :: DefaultDelete ) ) ) ; } # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct ScrollbarStyles { pub mHorizontal : u8 , pub mVertical : u8 , pub mScrollBehavior : u8 , pub mScrollSnapTypeX : u8 , pub mScrollSnapTypeY : u8 , pub mScrollSnapPointsX : root :: nsStyleCoord , pub mScrollSnapPointsY : root :: nsStyleCoord , pub mScrollSnapDestinationX : root :: nsStyleCoord_CalcValue , pub mScrollSnapDestinationY : root :: nsStyleCoord_CalcValue , } # [ test ] fn bindgen_test_layout_ScrollbarStyles ( ) { assert_eq ! ( :: std :: mem :: size_of :: < ScrollbarStyles > ( ) , 64usize , concat ! ( "Size of: " , stringify ! ( ScrollbarStyles ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < ScrollbarStyles > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( ScrollbarStyles ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ScrollbarStyles ) ) . mHorizontal as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( ScrollbarStyles ) , "::" , stringify ! ( mHorizontal ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ScrollbarStyles ) ) . mVertical as * const _ as usize } , 1usize , concat ! ( "Alignment of field: " , stringify ! ( ScrollbarStyles ) , "::" , stringify ! ( mVertical ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ScrollbarStyles ) ) . mScrollBehavior as * const _ as usize } , 2usize , concat ! ( "Alignment of field: " , stringify ! ( ScrollbarStyles ) , "::" , stringify ! ( mScrollBehavior ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ScrollbarStyles ) ) . mScrollSnapTypeX as * const _ as usize } , 3usize , concat ! ( "Alignment of field: " , stringify ! ( ScrollbarStyles ) , "::" , stringify ! ( mScrollSnapTypeX ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ScrollbarStyles ) ) . mScrollSnapTypeY as * const _ as usize } , 4usize , concat ! ( "Alignment of field: " , stringify ! ( ScrollbarStyles ) , "::" , stringify ! ( mScrollSnapTypeY ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ScrollbarStyles ) ) . mScrollSnapPointsX as * const _ as usize } , 8usize , concat ! ( "Alignment of field: " , stringify ! ( ScrollbarStyles ) , "::" , stringify ! ( mScrollSnapPointsX ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ScrollbarStyles ) ) . mScrollSnapPointsY as * const _ as usize } , 24usize , concat ! ( "Alignment of field: " , stringify ! ( ScrollbarStyles ) , "::" , stringify ! ( mScrollSnapPointsY ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ScrollbarStyles ) ) . mScrollSnapDestinationX as * const _ as usize } , 40usize , concat ! ( "Alignment of field: " , stringify ! ( ScrollbarStyles ) , "::" , stringify ! ( mScrollSnapDestinationX ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ScrollbarStyles ) ) . mScrollSnapDestinationY as * const _ as usize } , 52usize , concat ! ( "Alignment of field: " , stringify ! ( ScrollbarStyles ) , "::" , stringify ! ( mScrollSnapDestinationY ) ) ) ; } # [ repr ( C ) ] pub struct LangGroupFontPrefs { pub mLangGroup : root :: RefPtr < root :: nsAtom > , pub mMinimumFontSize : root :: nscoord , pub mDefaultVariableFont : root :: nsFont , pub mDefaultFixedFont : root :: nsFont , pub mDefaultSerifFont : root :: nsFont , pub mDefaultSansSerifFont : root :: nsFont , pub mDefaultMonospaceFont : root :: nsFont , pub mDefaultCursiveFont : root :: nsFont , pub mDefaultFantasyFont : root :: nsFont , pub mNext : root :: nsAutoPtr < root :: mozilla :: LangGroupFontPrefs > , } # [ test ] fn bindgen_test_layout_LangGroupFontPrefs ( ) { assert_eq ! ( :: std :: mem :: size_of :: < LangGroupFontPrefs > ( ) , 696usize , concat ! ( "Size of: " , stringify ! ( LangGroupFontPrefs ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < LangGroupFontPrefs > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( LangGroupFontPrefs ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const LangGroupFontPrefs ) ) . mLangGroup as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( LangGroupFontPrefs ) , "::" , stringify ! ( mLangGroup ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const LangGroupFontPrefs ) ) . mMinimumFontSize as * const _ as usize } , 8usize , concat ! ( "Alignment of field: " , stringify ! ( LangGroupFontPrefs ) , "::" , stringify ! ( mMinimumFontSize ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const LangGroupFontPrefs ) ) . mDefaultVariableFont as * const _ as usize } , 16usize , concat ! ( "Alignment of field: " , stringify ! ( LangGroupFontPrefs ) , "::" , stringify ! ( mDefaultVariableFont ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const LangGroupFontPrefs ) ) . mDefaultFixedFont as * const _ as usize } , 112usize , concat ! ( "Alignment of field: " , stringify ! ( LangGroupFontPrefs ) , "::" , stringify ! ( mDefaultFixedFont ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const LangGroupFontPrefs ) ) . mDefaultSerifFont as * const _ as usize } , 208usize , concat ! ( "Alignment of field: " , stringify ! ( LangGroupFontPrefs ) , "::" , stringify ! ( mDefaultSerifFont ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const LangGroupFontPrefs ) ) . mDefaultSansSerifFont as * const _ as usize } , 304usize , concat ! ( "Alignment of field: " , stringify ! ( LangGroupFontPrefs ) , "::" , stringify ! ( mDefaultSansSerifFont ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const LangGroupFontPrefs ) ) . mDefaultMonospaceFont as * const _ as usize } , 400usize , concat ! ( "Alignment of field: " , stringify ! ( LangGroupFontPrefs ) , "::" , stringify ! ( mDefaultMonospaceFont ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const LangGroupFontPrefs ) ) . mDefaultCursiveFont as * const _ as usize } , 496usize , concat ! ( "Alignment of field: " , stringify ! ( LangGroupFontPrefs ) , "::" , stringify ! ( mDefaultCursiveFont ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const LangGroupFontPrefs ) ) . mDefaultFantasyFont as * const _ as usize } , 592usize , concat ! ( "Alignment of field: " , stringify ! ( LangGroupFontPrefs ) , "::" , stringify ! ( mDefaultFantasyFont ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const LangGroupFontPrefs ) ) . mNext as * const _ as usize } , 688usize , concat ! ( "Alignment of field: " , stringify ! ( LangGroupFontPrefs ) , "::" , stringify ! ( mNext ) ) ) ; } /// Some functionality that has historically lived on nsPresContext does not /// actually need to be per-document. This singleton class serves as a host /// for that functionality. We delegate to it from nsPresContext where @@ -474,14 +489,14 @@ pub type ServoStyleContextStrong = ::gecko_bindings::sugar::ownership::Strong<:: /// this interface support runtime interface discovery (QueryInterface) /// and a reference counted memory model (AddRef/Release). This is /// modelled after the win32 IUnknown API. - # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct nsISupports { pub vtable_ : * const nsISupports__bindgen_vtable , } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsISupports_COMTypeInfo { pub _address : u8 , } # [ test ] fn bindgen_test_layout_nsISupports ( ) { assert_eq ! ( :: std :: mem :: size_of :: < nsISupports > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( nsISupports ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < nsISupports > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( nsISupports ) ) ) ; } impl Clone for nsISupports { fn clone ( & self ) -> Self { * self } } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct PRThread { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct nsCycleCollectingAutoRefCnt { pub mRefCntAndFlags : usize , } pub type nsCycleCollectingAutoRefCnt_Suspect = :: std :: option :: Option < unsafe extern "C" fn ( aPtr : * mut :: std :: os :: raw :: c_void , aCp : * mut root :: nsCycleCollectionParticipant , aRefCnt : * mut root :: nsCycleCollectingAutoRefCnt , aShouldDelete : * mut bool ) > ; # [ test ] fn bindgen_test_layout_nsCycleCollectingAutoRefCnt ( ) { assert_eq ! ( :: std :: mem :: size_of :: < nsCycleCollectingAutoRefCnt > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( nsCycleCollectingAutoRefCnt ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < nsCycleCollectingAutoRefCnt > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( nsCycleCollectingAutoRefCnt ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsCycleCollectingAutoRefCnt ) ) . mRefCntAndFlags as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( nsCycleCollectingAutoRefCnt ) , "::" , stringify ! ( mRefCntAndFlags ) ) ) ; } impl Clone for nsCycleCollectingAutoRefCnt { fn clone ( & self ) -> Self { * self } } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct nsAutoRefCnt { pub mValue : root :: nsrefcnt , } pub const nsAutoRefCnt_isThreadSafe : bool = false ; # [ test ] fn bindgen_test_layout_nsAutoRefCnt ( ) { assert_eq ! ( :: std :: mem :: size_of :: < nsAutoRefCnt > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( nsAutoRefCnt ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < nsAutoRefCnt > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( nsAutoRefCnt ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsAutoRefCnt ) ) . mValue as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( nsAutoRefCnt ) , "::" , stringify ! ( mValue ) ) ) ; } impl Clone for nsAutoRefCnt { fn clone ( & self ) -> Self { * self } } # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct RefPtr < T > { pub mRawPtr : * mut T , pub _phantom_0 : :: std :: marker :: PhantomData < :: std :: cell :: UnsafeCell < T > > , } pub type RefPtr_element_type < T > = T ; # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct RefPtr_Proxy { pub _address : u8 , } pub type RefPtr_Proxy_member_function = u8 ; # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct RefPtr_ConstRemovingRefPtrTraits { pub _address : u8 , } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct JSContext { _unused : [ u8 ; 0 ] } pub mod JS { # [ allow ( unused_imports ) ] use self :: super :: super :: root ; # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct DeletePolicy { pub _address : u8 , } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct FreePolicy { pub _address : u8 , } # [ test ] fn bindgen_test_layout_FreePolicy ( ) { assert_eq ! ( :: std :: mem :: size_of :: < FreePolicy > ( ) , 1usize , concat ! ( "Size of: " , stringify ! ( FreePolicy ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < FreePolicy > ( ) , 1usize , concat ! ( "Alignment of " , stringify ! ( FreePolicy ) ) ) ; } impl Clone for FreePolicy { fn clone ( & self ) -> Self { * self } } pub mod dbg { # [ allow ( unused_imports ) ] use self :: super :: super :: super :: root ; # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct GarbageCollectionEvent { pub majorGCNumber_ : u64 , pub reason : * const :: std :: os :: raw :: c_char , pub nonincrementalReason : * const :: std :: os :: raw :: c_char , pub collections : [ u64 ; 3usize ] , } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct GarbageCollectionEvent_Collection { pub startTimestamp : root :: mozilla :: TimeStamp , pub endTimestamp : root :: mozilla :: TimeStamp , } # [ test ] fn bindgen_test_layout_GarbageCollectionEvent_Collection ( ) { assert_eq ! ( :: std :: mem :: size_of :: < GarbageCollectionEvent_Collection > ( ) , 16usize , concat ! ( "Size of: " , stringify ! ( GarbageCollectionEvent_Collection ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < GarbageCollectionEvent_Collection > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( GarbageCollectionEvent_Collection ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const GarbageCollectionEvent_Collection ) ) . startTimestamp as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( GarbageCollectionEvent_Collection ) , "::" , stringify ! ( startTimestamp ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const GarbageCollectionEvent_Collection ) ) . endTimestamp as * const _ as usize } , 8usize , concat ! ( "Alignment of field: " , stringify ! ( GarbageCollectionEvent_Collection ) , "::" , stringify ! ( endTimestamp ) ) ) ; } impl Clone for GarbageCollectionEvent_Collection { fn clone ( & self ) -> Self { * self } } pub type GarbageCollectionEvent_Ptr = root :: mozilla :: UniquePtr < root :: JS :: dbg :: GarbageCollectionEvent > ; # [ test ] fn bindgen_test_layout_GarbageCollectionEvent ( ) { assert_eq ! ( :: std :: mem :: size_of :: < GarbageCollectionEvent > ( ) , 48usize , concat ! ( "Size of: " , stringify ! ( GarbageCollectionEvent ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < GarbageCollectionEvent > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( GarbageCollectionEvent ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const GarbageCollectionEvent ) ) . majorGCNumber_ as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( GarbageCollectionEvent ) , "::" , stringify ! ( majorGCNumber_ ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const GarbageCollectionEvent ) ) . reason as * const _ as usize } , 8usize , concat ! ( "Alignment of field: " , stringify ! ( GarbageCollectionEvent ) , "::" , stringify ! ( reason ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const GarbageCollectionEvent ) ) . nonincrementalReason as * const _ as usize } , 16usize , concat ! ( "Alignment of field: " , stringify ! ( GarbageCollectionEvent ) , "::" , stringify ! ( nonincrementalReason ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const GarbageCollectionEvent ) ) . collections as * const _ as usize } , 24usize , concat ! ( "Alignment of field: " , stringify ! ( GarbageCollectionEvent ) , "::" , stringify ! ( collections ) ) ) ; } } + # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct nsISupports { pub vtable_ : * const nsISupports__bindgen_vtable , } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsISupports_COMTypeInfo { pub _address : u8 , } # [ test ] fn bindgen_test_layout_nsISupports ( ) { assert_eq ! ( :: std :: mem :: size_of :: < nsISupports > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( nsISupports ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < nsISupports > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( nsISupports ) ) ) ; } impl Clone for nsISupports { fn clone ( & self ) -> Self { * self } } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct PRThread { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct nsCycleCollectingAutoRefCnt { pub mRefCntAndFlags : usize , } pub type nsCycleCollectingAutoRefCnt_Suspect = :: std :: option :: Option < unsafe extern "C" fn ( aPtr : * mut :: std :: os :: raw :: c_void , aCp : * mut root :: nsCycleCollectionParticipant , aRefCnt : * mut root :: nsCycleCollectingAutoRefCnt , aShouldDelete : * mut bool ) > ; # [ test ] fn bindgen_test_layout_nsCycleCollectingAutoRefCnt ( ) { assert_eq ! ( :: std :: mem :: size_of :: < nsCycleCollectingAutoRefCnt > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( nsCycleCollectingAutoRefCnt ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < nsCycleCollectingAutoRefCnt > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( nsCycleCollectingAutoRefCnt ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsCycleCollectingAutoRefCnt ) ) . mRefCntAndFlags as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( nsCycleCollectingAutoRefCnt ) , "::" , stringify ! ( mRefCntAndFlags ) ) ) ; } impl Clone for nsCycleCollectingAutoRefCnt { fn clone ( & self ) -> Self { * self } } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct nsAutoRefCnt { pub mValue : root :: nsrefcnt , } pub const nsAutoRefCnt_isThreadSafe : bool = false ; # [ test ] fn bindgen_test_layout_nsAutoRefCnt ( ) { assert_eq ! ( :: std :: mem :: size_of :: < nsAutoRefCnt > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( nsAutoRefCnt ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < nsAutoRefCnt > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( nsAutoRefCnt ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsAutoRefCnt ) ) . mValue as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( nsAutoRefCnt ) , "::" , stringify ! ( mValue ) ) ) ; } impl Clone for nsAutoRefCnt { fn clone ( & self ) -> Self { * self } } # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct RefPtr < T > { pub mRawPtr : * mut T , pub _phantom_0 : :: std :: marker :: PhantomData < :: std :: cell :: UnsafeCell < T > > , } pub type RefPtr_element_type < T > = T ; # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct RefPtr_Proxy { pub _address : u8 , } pub type RefPtr_Proxy_member_function = u8 ; # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct RefPtr_ConstRemovingRefPtrTraits { pub _address : u8 , } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct JSContext { _unused : [ u8 ; 0 ] } pub mod JS { # [ allow ( unused_imports ) ] use self :: super :: super :: root ; # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct DeletePolicy { pub _address : u8 , } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct FreePolicy { pub _address : u8 , } # [ test ] fn bindgen_test_layout_FreePolicy ( ) { assert_eq ! ( :: std :: mem :: size_of :: < FreePolicy > ( ) , 1usize , concat ! ( "Size of: " , stringify ! ( FreePolicy ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < FreePolicy > ( ) , 1usize , concat ! ( "Alignment of " , stringify ! ( FreePolicy ) ) ) ; } impl Clone for FreePolicy { fn clone ( & self ) -> Self { * self } } /// Local variable of type T whose value is always rooted. This is typically /// used for local variables, or for non-rooted values being passed to a /// function that requires a handle, e.g. Foo(Root(cx, x)). /// /// If you want to add additional methods to Rooted for a specific /// specialization, define a RootedBase specialization containing them. - # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct Rooted { pub _address : u8 , } pub type Rooted_ElementType < T > = T ; pub type Value_PayloadType = u64 ; # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct Value_layout { pub asBits : root :: __BindgenUnionField < u64 > , pub debugView : root :: __BindgenUnionField < root :: JS :: Value_layout__bindgen_ty_1 > , pub s : root :: __BindgenUnionField < root :: JS :: Value_layout__bindgen_ty_2 > , pub asDouble : root :: __BindgenUnionField < f64 > , pub asPtr : root :: __BindgenUnionField < * mut :: std :: os :: raw :: c_void > , pub asWord : root :: __BindgenUnionField < usize > , pub asUIntPtr : root :: __BindgenUnionField < usize > , pub bindgen_union_field : u64 , } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct Value_layout__bindgen_ty_1 { pub _bitfield_1 : u64 , pub __bindgen_align : [ u64 ; 0usize ] , } # [ test ] fn bindgen_test_layout_Value_layout__bindgen_ty_1 ( ) { assert_eq ! ( :: std :: mem :: size_of :: < Value_layout__bindgen_ty_1 > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( Value_layout__bindgen_ty_1 ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < Value_layout__bindgen_ty_1 > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( Value_layout__bindgen_ty_1 ) ) ) ; } impl Clone for Value_layout__bindgen_ty_1 { fn clone ( & self ) -> Self { * self } } impl Value_layout__bindgen_ty_1 { # [ inline ] pub fn payload47 ( & self ) -> u64 { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x7fffffffffff as u64 ; let val = ( unit_field_val & mask ) >> 0usize ; unsafe { :: std :: mem :: transmute ( val as u64 ) } } # [ inline ] pub fn set_payload47 ( & mut self , val : u64 ) { let mask = 0x7fffffffffff as u64 ; let val = val as u64 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 0usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn tag ( & self ) -> root :: JSValueTag { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0xffff800000000000 as u64 ; let val = ( unit_field_val & mask ) >> 47usize ; unsafe { :: std :: mem :: transmute ( val as u32 ) } } # [ inline ] pub fn set_tag ( & mut self , val : root :: JSValueTag ) { let mask = 0xffff800000000000 as u64 ; let val = val as u32 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 47usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn new_bitfield_1 ( payload47 : u64 , tag : root :: JSValueTag ) -> u64 { ( ( 0 | ( ( payload47 as u64 as u64 ) << 0usize ) & ( 0x7fffffffffff as u64 ) ) | ( ( tag as u32 as u64 ) << 47usize ) & ( 0xffff800000000000 as u64 ) ) } } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct Value_layout__bindgen_ty_2 { pub payload : root :: JS :: Value_layout__bindgen_ty_2__bindgen_ty_1 , } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct Value_layout__bindgen_ty_2__bindgen_ty_1 { pub i32 : root :: __BindgenUnionField < i32 > , pub u32 : root :: __BindgenUnionField < u32 > , pub why : root :: __BindgenUnionField < root :: JSWhyMagic > , pub bindgen_union_field : u32 , } # [ test ] fn bindgen_test_layout_Value_layout__bindgen_ty_2__bindgen_ty_1 ( ) { assert_eq ! ( :: std :: mem :: size_of :: < Value_layout__bindgen_ty_2__bindgen_ty_1 > ( ) , 4usize , concat ! ( "Size of: " , stringify ! ( Value_layout__bindgen_ty_2__bindgen_ty_1 ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < Value_layout__bindgen_ty_2__bindgen_ty_1 > ( ) , 4usize , concat ! ( "Alignment of " , stringify ! ( Value_layout__bindgen_ty_2__bindgen_ty_1 ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const Value_layout__bindgen_ty_2__bindgen_ty_1 ) ) . i32 as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( Value_layout__bindgen_ty_2__bindgen_ty_1 ) , "::" , stringify ! ( i32 ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const Value_layout__bindgen_ty_2__bindgen_ty_1 ) ) . u32 as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( Value_layout__bindgen_ty_2__bindgen_ty_1 ) , "::" , stringify ! ( u32 ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const Value_layout__bindgen_ty_2__bindgen_ty_1 ) ) . why as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( Value_layout__bindgen_ty_2__bindgen_ty_1 ) , "::" , stringify ! ( why ) ) ) ; } impl Clone for Value_layout__bindgen_ty_2__bindgen_ty_1 { fn clone ( & self ) -> Self { * self } } # [ test ] fn bindgen_test_layout_Value_layout__bindgen_ty_2 ( ) { assert_eq ! ( :: std :: mem :: size_of :: < Value_layout__bindgen_ty_2 > ( ) , 4usize , concat ! ( "Size of: " , stringify ! ( Value_layout__bindgen_ty_2 ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < Value_layout__bindgen_ty_2 > ( ) , 4usize , concat ! ( "Alignment of " , stringify ! ( Value_layout__bindgen_ty_2 ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const Value_layout__bindgen_ty_2 ) ) . payload as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( Value_layout__bindgen_ty_2 ) , "::" , stringify ! ( payload ) ) ) ; } impl Clone for Value_layout__bindgen_ty_2 { fn clone ( & self ) -> Self { * self } } # [ test ] fn bindgen_test_layout_Value_layout ( ) { assert_eq ! ( :: std :: mem :: size_of :: < Value_layout > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( Value_layout ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < Value_layout > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( Value_layout ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const Value_layout ) ) . asBits as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( Value_layout ) , "::" , stringify ! ( asBits ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const Value_layout ) ) . debugView as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( Value_layout ) , "::" , stringify ! ( debugView ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const Value_layout ) ) . s as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( Value_layout ) , "::" , stringify ! ( s ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const Value_layout ) ) . asDouble as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( Value_layout ) , "::" , stringify ! ( asDouble ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const Value_layout ) ) . asPtr as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( Value_layout ) , "::" , stringify ! ( asPtr ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const Value_layout ) ) . asWord as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( Value_layout ) , "::" , stringify ! ( asWord ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const Value_layout ) ) . asUIntPtr as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( Value_layout ) , "::" , stringify ! ( asUIntPtr ) ) ) ; } impl Clone for Value_layout { fn clone ( & self ) -> Self { * self } } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct ConstUTF8CharsZ { pub data_ : * const :: std :: os :: raw :: c_char , } pub type ConstUTF8CharsZ_CharT = :: std :: os :: raw :: c_uchar ; # [ test ] fn bindgen_test_layout_ConstUTF8CharsZ ( ) { assert_eq ! ( :: std :: mem :: size_of :: < ConstUTF8CharsZ > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( ConstUTF8CharsZ ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < ConstUTF8CharsZ > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( ConstUTF8CharsZ ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ConstUTF8CharsZ ) ) . data_ as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( ConstUTF8CharsZ ) , "::" , stringify ! ( data_ ) ) ) ; } impl Clone for ConstUTF8CharsZ { fn clone ( & self ) -> Self { * self } } } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct JSObject { _unused : [ u8 ; 0 ] } pub mod js { # [ allow ( unused_imports ) ] use self :: super :: super :: root ; pub mod gc { # [ allow ( unused_imports ) ] use self :: super :: super :: super :: root ; } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct SystemAllocPolicy { pub _address : u8 , } # [ test ] fn bindgen_test_layout_SystemAllocPolicy ( ) { assert_eq ! ( :: std :: mem :: size_of :: < SystemAllocPolicy > ( ) , 1usize , concat ! ( "Size of: " , stringify ! ( SystemAllocPolicy ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < SystemAllocPolicy > ( ) , 1usize , concat ! ( "Alignment of " , stringify ! ( SystemAllocPolicy ) ) ) ; } impl Clone for SystemAllocPolicy { fn clone ( & self ) -> Self { * self } } # [ repr ( C ) ] pub struct SourceHook__bindgen_vtable ( :: std :: os :: raw :: c_void ) ; + # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct Rooted { pub _address : u8 , } pub type Rooted_ElementType < T > = T ; pub mod dbg { # [ allow ( unused_imports ) ] use self :: super :: super :: super :: root ; # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct GarbageCollectionEvent { pub majorGCNumber_ : u64 , pub reason : * const :: std :: os :: raw :: c_char , pub nonincrementalReason : * const :: std :: os :: raw :: c_char , pub collections : [ u64 ; 3usize ] , } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct GarbageCollectionEvent_Collection { pub startTimestamp : root :: mozilla :: TimeStamp , pub endTimestamp : root :: mozilla :: TimeStamp , } # [ test ] fn bindgen_test_layout_GarbageCollectionEvent_Collection ( ) { assert_eq ! ( :: std :: mem :: size_of :: < GarbageCollectionEvent_Collection > ( ) , 16usize , concat ! ( "Size of: " , stringify ! ( GarbageCollectionEvent_Collection ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < GarbageCollectionEvent_Collection > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( GarbageCollectionEvent_Collection ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const GarbageCollectionEvent_Collection ) ) . startTimestamp as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( GarbageCollectionEvent_Collection ) , "::" , stringify ! ( startTimestamp ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const GarbageCollectionEvent_Collection ) ) . endTimestamp as * const _ as usize } , 8usize , concat ! ( "Alignment of field: " , stringify ! ( GarbageCollectionEvent_Collection ) , "::" , stringify ! ( endTimestamp ) ) ) ; } impl Clone for GarbageCollectionEvent_Collection { fn clone ( & self ) -> Self { * self } } pub type GarbageCollectionEvent_Ptr = root :: mozilla :: UniquePtr < root :: JS :: dbg :: GarbageCollectionEvent > ; # [ test ] fn bindgen_test_layout_GarbageCollectionEvent ( ) { assert_eq ! ( :: std :: mem :: size_of :: < GarbageCollectionEvent > ( ) , 48usize , concat ! ( "Size of: " , stringify ! ( GarbageCollectionEvent ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < GarbageCollectionEvent > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( GarbageCollectionEvent ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const GarbageCollectionEvent ) ) . majorGCNumber_ as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( GarbageCollectionEvent ) , "::" , stringify ! ( majorGCNumber_ ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const GarbageCollectionEvent ) ) . reason as * const _ as usize } , 8usize , concat ! ( "Alignment of field: " , stringify ! ( GarbageCollectionEvent ) , "::" , stringify ! ( reason ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const GarbageCollectionEvent ) ) . nonincrementalReason as * const _ as usize } , 16usize , concat ! ( "Alignment of field: " , stringify ! ( GarbageCollectionEvent ) , "::" , stringify ! ( nonincrementalReason ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const GarbageCollectionEvent ) ) . collections as * const _ as usize } , 24usize , concat ! ( "Alignment of field: " , stringify ! ( GarbageCollectionEvent ) , "::" , stringify ! ( collections ) ) ) ; } } pub type Value_PayloadType = u64 ; # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct Value_layout { pub asBits : root :: __BindgenUnionField < u64 > , pub debugView : root :: __BindgenUnionField < root :: JS :: Value_layout__bindgen_ty_1 > , pub s : root :: __BindgenUnionField < root :: JS :: Value_layout__bindgen_ty_2 > , pub asDouble : root :: __BindgenUnionField < f64 > , pub asPtr : root :: __BindgenUnionField < * mut :: std :: os :: raw :: c_void > , pub asWord : root :: __BindgenUnionField < usize > , pub asUIntPtr : root :: __BindgenUnionField < usize > , pub bindgen_union_field : u64 , } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct Value_layout__bindgen_ty_1 { pub _bitfield_1 : u64 , pub __bindgen_align : [ u64 ; 0usize ] , } # [ test ] fn bindgen_test_layout_Value_layout__bindgen_ty_1 ( ) { assert_eq ! ( :: std :: mem :: size_of :: < Value_layout__bindgen_ty_1 > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( Value_layout__bindgen_ty_1 ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < Value_layout__bindgen_ty_1 > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( Value_layout__bindgen_ty_1 ) ) ) ; } impl Clone for Value_layout__bindgen_ty_1 { fn clone ( & self ) -> Self { * self } } impl Value_layout__bindgen_ty_1 { # [ inline ] pub fn payload47 ( & self ) -> u64 { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x7fffffffffff as u64 ; let val = ( unit_field_val & mask ) >> 0usize ; unsafe { :: std :: mem :: transmute ( val as u64 ) } } # [ inline ] pub fn set_payload47 ( & mut self , val : u64 ) { let mask = 0x7fffffffffff as u64 ; let val = val as u64 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 0usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn tag ( & self ) -> root :: JSValueTag { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0xffff800000000000 as u64 ; let val = ( unit_field_val & mask ) >> 47usize ; unsafe { :: std :: mem :: transmute ( val as u32 ) } } # [ inline ] pub fn set_tag ( & mut self , val : root :: JSValueTag ) { let mask = 0xffff800000000000 as u64 ; let val = val as u32 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 47usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn new_bitfield_1 ( payload47 : u64 , tag : root :: JSValueTag ) -> u64 { ( ( 0 | ( ( payload47 as u64 as u64 ) << 0usize ) & ( 0x7fffffffffff as u64 ) ) | ( ( tag as u32 as u64 ) << 47usize ) & ( 0xffff800000000000 as u64 ) ) } } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct Value_layout__bindgen_ty_2 { pub payload : root :: JS :: Value_layout__bindgen_ty_2__bindgen_ty_1 , } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct Value_layout__bindgen_ty_2__bindgen_ty_1 { pub i32 : root :: __BindgenUnionField < i32 > , pub u32 : root :: __BindgenUnionField < u32 > , pub why : root :: __BindgenUnionField < root :: JSWhyMagic > , pub bindgen_union_field : u32 , } # [ test ] fn bindgen_test_layout_Value_layout__bindgen_ty_2__bindgen_ty_1 ( ) { assert_eq ! ( :: std :: mem :: size_of :: < Value_layout__bindgen_ty_2__bindgen_ty_1 > ( ) , 4usize , concat ! ( "Size of: " , stringify ! ( Value_layout__bindgen_ty_2__bindgen_ty_1 ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < Value_layout__bindgen_ty_2__bindgen_ty_1 > ( ) , 4usize , concat ! ( "Alignment of " , stringify ! ( Value_layout__bindgen_ty_2__bindgen_ty_1 ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const Value_layout__bindgen_ty_2__bindgen_ty_1 ) ) . i32 as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( Value_layout__bindgen_ty_2__bindgen_ty_1 ) , "::" , stringify ! ( i32 ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const Value_layout__bindgen_ty_2__bindgen_ty_1 ) ) . u32 as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( Value_layout__bindgen_ty_2__bindgen_ty_1 ) , "::" , stringify ! ( u32 ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const Value_layout__bindgen_ty_2__bindgen_ty_1 ) ) . why as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( Value_layout__bindgen_ty_2__bindgen_ty_1 ) , "::" , stringify ! ( why ) ) ) ; } impl Clone for Value_layout__bindgen_ty_2__bindgen_ty_1 { fn clone ( & self ) -> Self { * self } } # [ test ] fn bindgen_test_layout_Value_layout__bindgen_ty_2 ( ) { assert_eq ! ( :: std :: mem :: size_of :: < Value_layout__bindgen_ty_2 > ( ) , 4usize , concat ! ( "Size of: " , stringify ! ( Value_layout__bindgen_ty_2 ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < Value_layout__bindgen_ty_2 > ( ) , 4usize , concat ! ( "Alignment of " , stringify ! ( Value_layout__bindgen_ty_2 ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const Value_layout__bindgen_ty_2 ) ) . payload as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( Value_layout__bindgen_ty_2 ) , "::" , stringify ! ( payload ) ) ) ; } impl Clone for Value_layout__bindgen_ty_2 { fn clone ( & self ) -> Self { * self } } # [ test ] fn bindgen_test_layout_Value_layout ( ) { assert_eq ! ( :: std :: mem :: size_of :: < Value_layout > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( Value_layout ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < Value_layout > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( Value_layout ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const Value_layout ) ) . asBits as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( Value_layout ) , "::" , stringify ! ( asBits ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const Value_layout ) ) . debugView as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( Value_layout ) , "::" , stringify ! ( debugView ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const Value_layout ) ) . s as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( Value_layout ) , "::" , stringify ! ( s ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const Value_layout ) ) . asDouble as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( Value_layout ) , "::" , stringify ! ( asDouble ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const Value_layout ) ) . asPtr as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( Value_layout ) , "::" , stringify ! ( asPtr ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const Value_layout ) ) . asWord as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( Value_layout ) , "::" , stringify ! ( asWord ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const Value_layout ) ) . asUIntPtr as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( Value_layout ) , "::" , stringify ! ( asUIntPtr ) ) ) ; } impl Clone for Value_layout { fn clone ( & self ) -> Self { * self } } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct ConstUTF8CharsZ { pub data_ : * const :: std :: os :: raw :: c_char , } pub type ConstUTF8CharsZ_CharT = :: std :: os :: raw :: c_uchar ; # [ test ] fn bindgen_test_layout_ConstUTF8CharsZ ( ) { assert_eq ! ( :: std :: mem :: size_of :: < ConstUTF8CharsZ > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( ConstUTF8CharsZ ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < ConstUTF8CharsZ > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( ConstUTF8CharsZ ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const ConstUTF8CharsZ ) ) . data_ as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( ConstUTF8CharsZ ) , "::" , stringify ! ( data_ ) ) ) ; } impl Clone for ConstUTF8CharsZ { fn clone ( & self ) -> Self { * self } } } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct JSObject { _unused : [ u8 ; 0 ] } pub mod js { # [ allow ( unused_imports ) ] use self :: super :: super :: root ; pub mod gc { # [ allow ( unused_imports ) ] use self :: super :: super :: super :: root ; } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct SystemAllocPolicy { pub _address : u8 , } # [ test ] fn bindgen_test_layout_SystemAllocPolicy ( ) { assert_eq ! ( :: std :: mem :: size_of :: < SystemAllocPolicy > ( ) , 1usize , concat ! ( "Size of: " , stringify ! ( SystemAllocPolicy ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < SystemAllocPolicy > ( ) , 1usize , concat ! ( "Alignment of " , stringify ! ( SystemAllocPolicy ) ) ) ; } impl Clone for SystemAllocPolicy { fn clone ( & self ) -> Self { * self } } # [ repr ( C ) ] pub struct SourceHook__bindgen_vtable ( :: std :: os :: raw :: c_void ) ; /// A class of objects that return source code on demand. /// /// When code is compiled with setSourceIsLazy(true), SpiderMonkey doesn't @@ -767,7 +782,7 @@ pub type ServoStyleContextStrong = ::gecko_bindings::sugar::ownership::Strong<:: /// for a complete specification. /// @param Class the class-type being wrapped /// @see nsInterfaceHashtable, nsClassHashtable - # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsClassHashtable { pub _address : u8 , } pub type nsClassHashtable_KeyType = [ u8 ; 0usize ] ; pub type nsClassHashtable_UserDataType < T > = * mut T ; pub type nsClassHashtable_base_type = u8 ; # [ repr ( C ) ] pub struct nsPresArena { pub mFreeLists : [ root :: nsPresArena_FreeList ; 211usize ] , pub mPool : [ u64 ; 4usize ] , pub mArenaRefPtrs : [ u64 ; 4usize ] , } # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct nsPresArena_FreeList { pub mEntries : root :: nsTArray < * mut :: std :: os :: raw :: c_void > , pub mEntrySize : usize , pub mEntriesEverAllocated : usize , } # [ test ] fn bindgen_test_layout_nsPresArena_FreeList ( ) { assert_eq ! ( :: std :: mem :: size_of :: < nsPresArena_FreeList > ( ) , 24usize , concat ! ( "Size of: " , stringify ! ( nsPresArena_FreeList ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < nsPresArena_FreeList > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( nsPresArena_FreeList ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsPresArena_FreeList ) ) . mEntries as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( nsPresArena_FreeList ) , "::" , stringify ! ( mEntries ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsPresArena_FreeList ) ) . mEntrySize as * const _ as usize } , 8usize , concat ! ( "Alignment of field: " , stringify ! ( nsPresArena_FreeList ) , "::" , stringify ! ( mEntrySize ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsPresArena_FreeList ) ) . mEntriesEverAllocated as * const _ as usize } , 16usize , concat ! ( "Alignment of field: " , stringify ! ( nsPresArena_FreeList ) , "::" , stringify ! ( mEntriesEverAllocated ) ) ) ; } # [ test ] fn bindgen_test_layout_nsPresArena ( ) { assert_eq ! ( :: std :: mem :: size_of :: < nsPresArena > ( ) , 5128usize , concat ! ( "Size of: " , stringify ! ( nsPresArena ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < nsPresArena > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( nsPresArena ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsPresArena ) ) . mFreeLists as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( nsPresArena ) , "::" , stringify ! ( mFreeLists ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsPresArena ) ) . mPool as * const _ as usize } , 5064usize , concat ! ( "Alignment of field: " , stringify ! ( nsPresArena ) , "::" , stringify ! ( mPool ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsPresArena ) ) . mArenaRefPtrs as * const _ as usize } , 5096usize , concat ! ( "Alignment of field: " , stringify ! ( nsPresArena ) , "::" , stringify ! ( mArenaRefPtrs ) ) ) ; } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct imgINotificationObserver { pub _base : root :: nsISupports , } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct imgINotificationObserver_COMTypeInfo { pub _address : u8 , } pub const imgINotificationObserver_SIZE_AVAILABLE : root :: imgINotificationObserver__bindgen_ty_1 = 1 ; pub const imgINotificationObserver_FRAME_UPDATE : root :: imgINotificationObserver__bindgen_ty_1 = 2 ; pub const imgINotificationObserver_FRAME_COMPLETE : root :: imgINotificationObserver__bindgen_ty_1 = 3 ; pub const imgINotificationObserver_LOAD_COMPLETE : root :: imgINotificationObserver__bindgen_ty_1 = 4 ; pub const imgINotificationObserver_DECODE_COMPLETE : root :: imgINotificationObserver__bindgen_ty_1 = 5 ; pub const imgINotificationObserver_DISCARD : root :: imgINotificationObserver__bindgen_ty_1 = 6 ; pub const imgINotificationObserver_UNLOCKED_DRAW : root :: imgINotificationObserver__bindgen_ty_1 = 7 ; pub const imgINotificationObserver_IS_ANIMATED : root :: imgINotificationObserver__bindgen_ty_1 = 8 ; pub const imgINotificationObserver_HAS_TRANSPARENCY : root :: imgINotificationObserver__bindgen_ty_1 = 9 ; pub type imgINotificationObserver__bindgen_ty_1 = :: std :: os :: raw :: c_uint ; # [ test ] fn bindgen_test_layout_imgINotificationObserver ( ) { assert_eq ! ( :: std :: mem :: size_of :: < imgINotificationObserver > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( imgINotificationObserver ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < imgINotificationObserver > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( imgINotificationObserver ) ) ) ; } impl Clone for imgINotificationObserver { fn clone ( & self ) -> Self { * self } } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsDocShell { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsViewManager { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsFrameSelection { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsCSSFrameConstructor { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct AutoWeakFrame { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct WeakFrame { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsRefreshDriver { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] pub struct CapturingContentInfo { pub mAllowed : bool , pub mPointerLock : bool , pub mRetargetToElement : bool , pub mPreventDrag : bool , pub mContent : root :: mozilla :: StaticRefPtr < root :: nsIContent > , } # [ test ] fn bindgen_test_layout_CapturingContentInfo ( ) { assert_eq ! ( :: std :: mem :: size_of :: < CapturingContentInfo > ( ) , 16usize , concat ! ( "Size of: " , stringify ! ( CapturingContentInfo ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < CapturingContentInfo > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( CapturingContentInfo ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const CapturingContentInfo ) ) . mAllowed as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( CapturingContentInfo ) , "::" , stringify ! ( mAllowed ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const CapturingContentInfo ) ) . mPointerLock as * const _ as usize } , 1usize , concat ! ( "Alignment of field: " , stringify ! ( CapturingContentInfo ) , "::" , stringify ! ( mPointerLock ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const CapturingContentInfo ) ) . mRetargetToElement as * const _ as usize } , 2usize , concat ! ( "Alignment of field: " , stringify ! ( CapturingContentInfo ) , "::" , stringify ! ( mRetargetToElement ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const CapturingContentInfo ) ) . mPreventDrag as * const _ as usize } , 3usize , concat ! ( "Alignment of field: " , stringify ! ( CapturingContentInfo ) , "::" , stringify ! ( mPreventDrag ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const CapturingContentInfo ) ) . mContent as * const _ as usize } , 8usize , concat ! ( "Alignment of field: " , stringify ! ( CapturingContentInfo ) , "::" , stringify ! ( mContent ) ) ) ; } + # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsClassHashtable { pub _address : u8 , } pub type nsClassHashtable_KeyType = [ u8 ; 0usize ] ; pub type nsClassHashtable_UserDataType < T > = * mut T ; pub type nsClassHashtable_base_type = u8 ; # [ repr ( C ) ] pub struct nsPresArena { pub mFreeLists : [ root :: nsPresArena_FreeList ; 211usize ] , pub mPool : [ u64 ; 5usize ] , pub mArenaRefPtrs : [ u64 ; 4usize ] , } # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct nsPresArena_FreeList { pub mEntries : root :: nsTArray < * mut :: std :: os :: raw :: c_void > , pub mEntrySize : usize , pub mEntriesEverAllocated : usize , } # [ test ] fn bindgen_test_layout_nsPresArena_FreeList ( ) { assert_eq ! ( :: std :: mem :: size_of :: < nsPresArena_FreeList > ( ) , 24usize , concat ! ( "Size of: " , stringify ! ( nsPresArena_FreeList ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < nsPresArena_FreeList > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( nsPresArena_FreeList ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsPresArena_FreeList ) ) . mEntries as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( nsPresArena_FreeList ) , "::" , stringify ! ( mEntries ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsPresArena_FreeList ) ) . mEntrySize as * const _ as usize } , 8usize , concat ! ( "Alignment of field: " , stringify ! ( nsPresArena_FreeList ) , "::" , stringify ! ( mEntrySize ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsPresArena_FreeList ) ) . mEntriesEverAllocated as * const _ as usize } , 16usize , concat ! ( "Alignment of field: " , stringify ! ( nsPresArena_FreeList ) , "::" , stringify ! ( mEntriesEverAllocated ) ) ) ; } # [ test ] fn bindgen_test_layout_nsPresArena ( ) { assert_eq ! ( :: std :: mem :: size_of :: < nsPresArena > ( ) , 5136usize , concat ! ( "Size of: " , stringify ! ( nsPresArena ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < nsPresArena > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( nsPresArena ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsPresArena ) ) . mFreeLists as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( nsPresArena ) , "::" , stringify ! ( mFreeLists ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsPresArena ) ) . mPool as * const _ as usize } , 5064usize , concat ! ( "Alignment of field: " , stringify ! ( nsPresArena ) , "::" , stringify ! ( mPool ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsPresArena ) ) . mArenaRefPtrs as * const _ as usize } , 5104usize , concat ! ( "Alignment of field: " , stringify ! ( nsPresArena ) , "::" , stringify ! ( mArenaRefPtrs ) ) ) ; } # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct imgINotificationObserver { pub _base : root :: nsISupports , } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct imgINotificationObserver_COMTypeInfo { pub _address : u8 , } pub const imgINotificationObserver_SIZE_AVAILABLE : root :: imgINotificationObserver__bindgen_ty_1 = 1 ; pub const imgINotificationObserver_FRAME_UPDATE : root :: imgINotificationObserver__bindgen_ty_1 = 2 ; pub const imgINotificationObserver_FRAME_COMPLETE : root :: imgINotificationObserver__bindgen_ty_1 = 3 ; pub const imgINotificationObserver_LOAD_COMPLETE : root :: imgINotificationObserver__bindgen_ty_1 = 4 ; pub const imgINotificationObserver_DECODE_COMPLETE : root :: imgINotificationObserver__bindgen_ty_1 = 5 ; pub const imgINotificationObserver_DISCARD : root :: imgINotificationObserver__bindgen_ty_1 = 6 ; pub const imgINotificationObserver_UNLOCKED_DRAW : root :: imgINotificationObserver__bindgen_ty_1 = 7 ; pub const imgINotificationObserver_IS_ANIMATED : root :: imgINotificationObserver__bindgen_ty_1 = 8 ; pub const imgINotificationObserver_HAS_TRANSPARENCY : root :: imgINotificationObserver__bindgen_ty_1 = 9 ; pub type imgINotificationObserver__bindgen_ty_1 = :: std :: os :: raw :: c_uint ; # [ test ] fn bindgen_test_layout_imgINotificationObserver ( ) { assert_eq ! ( :: std :: mem :: size_of :: < imgINotificationObserver > ( ) , 8usize , concat ! ( "Size of: " , stringify ! ( imgINotificationObserver ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < imgINotificationObserver > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( imgINotificationObserver ) ) ) ; } impl Clone for imgINotificationObserver { fn clone ( & self ) -> Self { * self } } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsDocShell { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsViewManager { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsFrameSelection { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsCSSFrameConstructor { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct AutoWeakFrame { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct WeakFrame { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsRefreshDriver { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] pub struct CapturingContentInfo { pub mAllowed : bool , pub mPointerLock : bool , pub mRetargetToElement : bool , pub mPreventDrag : bool , pub mContent : root :: mozilla :: StaticRefPtr < root :: nsIContent > , } # [ test ] fn bindgen_test_layout_CapturingContentInfo ( ) { assert_eq ! ( :: std :: mem :: size_of :: < CapturingContentInfo > ( ) , 16usize , concat ! ( "Size of: " , stringify ! ( CapturingContentInfo ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < CapturingContentInfo > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( CapturingContentInfo ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const CapturingContentInfo ) ) . mAllowed as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( CapturingContentInfo ) , "::" , stringify ! ( mAllowed ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const CapturingContentInfo ) ) . mPointerLock as * const _ as usize } , 1usize , concat ! ( "Alignment of field: " , stringify ! ( CapturingContentInfo ) , "::" , stringify ! ( mPointerLock ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const CapturingContentInfo ) ) . mRetargetToElement as * const _ as usize } , 2usize , concat ! ( "Alignment of field: " , stringify ! ( CapturingContentInfo ) , "::" , stringify ! ( mRetargetToElement ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const CapturingContentInfo ) ) . mPreventDrag as * const _ as usize } , 3usize , concat ! ( "Alignment of field: " , stringify ! ( CapturingContentInfo ) , "::" , stringify ! ( mPreventDrag ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const CapturingContentInfo ) ) . mContent as * const _ as usize } , 8usize , concat ! ( "Alignment of field: " , stringify ! ( CapturingContentInfo ) , "::" , stringify ! ( mContent ) ) ) ; } /// Presentation shell interface. Presentation shells are the /// controlling point for managing the presentation of a document. The /// presentation shell holds a live reference to the document, the @@ -783,7 +798,7 @@ pub type ServoStyleContextStrong = ::gecko_bindings::sugar::ownership::Strong<:: } extern "C" { # [ link_name = "\u{1}_ZN12nsIPresShell14gKeyDownTargetE" ] pub static mut nsIPresShell_gKeyDownTarget : * mut root :: nsIContent ; -} # [ test ] fn bindgen_test_layout_nsIPresShell ( ) { assert_eq ! ( :: std :: mem :: size_of :: < nsIPresShell > ( ) , 5336usize , concat ! ( "Size of: " , stringify ! ( nsIPresShell ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < nsIPresShell > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( nsIPresShell ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mDocument as * const _ as usize } , 8usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mDocument ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mPresContext as * const _ as usize } , 16usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mPresContext ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mStyleSet as * const _ as usize } , 24usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mStyleSet ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mFrameConstructor as * const _ as usize } , 32usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mFrameConstructor ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mViewManager as * const _ as usize } , 40usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mViewManager ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mFrameArena as * const _ as usize } , 48usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mFrameArena ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mSelection as * const _ as usize } , 5176usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mSelection ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mFrameManager as * const _ as usize } , 5184usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mFrameManager ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mForwardingContainer as * const _ as usize } , 5192usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mForwardingContainer ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mDocAccessible as * const _ as usize } , 5200usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mDocAccessible ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mReflowContinueTimer as * const _ as usize } , 5208usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mReflowContinueTimer ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mPaintCount as * const _ as usize } , 5216usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mPaintCount ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mScrollPositionClampingScrollPortSize as * const _ as usize } , 5224usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mScrollPositionClampingScrollPortSize ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mAutoWeakFrames as * const _ as usize } , 5232usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mAutoWeakFrames ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mWeakFrames as * const _ as usize } , 5240usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mWeakFrames ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mStyleCause as * const _ as usize } , 5272usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mStyleCause ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mReflowCause as * const _ as usize } , 5280usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mReflowCause ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mCanvasBackgroundColor as * const _ as usize } , 5288usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mCanvasBackgroundColor ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mResolution as * const _ as usize } , 5292usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mResolution ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mSelectionFlags as * const _ as usize } , 5300usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mSelectionFlags ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mChangeNestCount as * const _ as usize } , 5302usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mChangeNestCount ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mRenderFlags as * const _ as usize } , 5304usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mRenderFlags ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mPresShellId as * const _ as usize } , 5308usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mPresShellId ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mFontSizeInflationEmPerLine as * const _ as usize } , 5312usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mFontSizeInflationEmPerLine ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mFontSizeInflationMinTwips as * const _ as usize } , 5316usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mFontSizeInflationMinTwips ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mFontSizeInflationLineThreshold as * const _ as usize } , 5320usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mFontSizeInflationLineThreshold ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mFontSizeInflationForceEnabled as * const _ as usize } , 5324usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mFontSizeInflationForceEnabled ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mFontSizeInflationDisabledInMasterProcess as * const _ as usize } , 5325usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mFontSizeInflationDisabledInMasterProcess ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mFontSizeInflationEnabled as * const _ as usize } , 5326usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mFontSizeInflationEnabled ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mFontSizeInflationEnabledIsDirty as * const _ as usize } , 5327usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mFontSizeInflationEnabledIsDirty ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mPaintingIsFrozen as * const _ as usize } , 5328usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mPaintingIsFrozen ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mIsNeverPainting as * const _ as usize } , 5329usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mIsNeverPainting ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mInFlush as * const _ as usize } , 5330usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mInFlush ) ) ) ; } impl nsIPresShell { # [ inline ] pub fn mDidInitialize ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x1 as u16 ; let val = ( unit_field_val & mask ) >> 0usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mDidInitialize ( & mut self , val : bool ) { let mask = 0x1 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 0usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mIsDestroying ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x2 as u16 ; let val = ( unit_field_val & mask ) >> 1usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mIsDestroying ( & mut self , val : bool ) { let mask = 0x2 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 1usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mIsReflowing ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x4 as u16 ; let val = ( unit_field_val & mask ) >> 2usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mIsReflowing ( & mut self , val : bool ) { let mask = 0x4 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 2usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mPaintingSuppressed ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x8 as u16 ; let val = ( unit_field_val & mask ) >> 3usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mPaintingSuppressed ( & mut self , val : bool ) { let mask = 0x8 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 3usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mIsActive ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x10 as u16 ; let val = ( unit_field_val & mask ) >> 4usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mIsActive ( & mut self , val : bool ) { let mask = 0x10 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 4usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mFrozen ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x20 as u16 ; let val = ( unit_field_val & mask ) >> 5usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mFrozen ( & mut self , val : bool ) { let mask = 0x20 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 5usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mIsFirstPaint ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x40 as u16 ; let val = ( unit_field_val & mask ) >> 6usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mIsFirstPaint ( & mut self , val : bool ) { let mask = 0x40 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 6usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mObservesMutationsForPrint ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x80 as u16 ; let val = ( unit_field_val & mask ) >> 7usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mObservesMutationsForPrint ( & mut self , val : bool ) { let mask = 0x80 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 7usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mWasLastReflowInterrupted ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x100 as u16 ; let val = ( unit_field_val & mask ) >> 8usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mWasLastReflowInterrupted ( & mut self , val : bool ) { let mask = 0x100 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 8usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mScrollPositionClampingScrollPortSizeSet ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x200 as u16 ; let val = ( unit_field_val & mask ) >> 9usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mScrollPositionClampingScrollPortSizeSet ( & mut self , val : bool ) { let mask = 0x200 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 9usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mNeedLayoutFlush ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x400 as u16 ; let val = ( unit_field_val & mask ) >> 10usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mNeedLayoutFlush ( & mut self , val : bool ) { let mask = 0x400 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 10usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mNeedStyleFlush ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x800 as u16 ; let val = ( unit_field_val & mask ) >> 11usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mNeedStyleFlush ( & mut self , val : bool ) { let mask = 0x800 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 11usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mObservingStyleFlushes ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x1000 as u16 ; let val = ( unit_field_val & mask ) >> 12usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mObservingStyleFlushes ( & mut self , val : bool ) { let mask = 0x1000 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 12usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mObservingLayoutFlushes ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x2000 as u16 ; let val = ( unit_field_val & mask ) >> 13usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mObservingLayoutFlushes ( & mut self , val : bool ) { let mask = 0x2000 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 13usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mNeedThrottledAnimationFlush ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x4000 as u16 ; let val = ( unit_field_val & mask ) >> 14usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mNeedThrottledAnimationFlush ( & mut self , val : bool ) { let mask = 0x4000 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 14usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn new_bitfield_1 ( mDidInitialize : bool , mIsDestroying : bool , mIsReflowing : bool , mPaintingSuppressed : bool , mIsActive : bool , mFrozen : bool , mIsFirstPaint : bool , mObservesMutationsForPrint : bool , mWasLastReflowInterrupted : bool , mScrollPositionClampingScrollPortSizeSet : bool , mNeedLayoutFlush : bool , mNeedStyleFlush : bool , mObservingStyleFlushes : bool , mObservingLayoutFlushes : bool , mNeedThrottledAnimationFlush : bool ) -> u16 { ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 0 | ( ( mDidInitialize as u8 as u16 ) << 0usize ) & ( 0x1 as u16 ) ) | ( ( mIsDestroying as u8 as u16 ) << 1usize ) & ( 0x2 as u16 ) ) | ( ( mIsReflowing as u8 as u16 ) << 2usize ) & ( 0x4 as u16 ) ) | ( ( mPaintingSuppressed as u8 as u16 ) << 3usize ) & ( 0x8 as u16 ) ) | ( ( mIsActive as u8 as u16 ) << 4usize ) & ( 0x10 as u16 ) ) | ( ( mFrozen as u8 as u16 ) << 5usize ) & ( 0x20 as u16 ) ) | ( ( mIsFirstPaint as u8 as u16 ) << 6usize ) & ( 0x40 as u16 ) ) | ( ( mObservesMutationsForPrint as u8 as u16 ) << 7usize ) & ( 0x80 as u16 ) ) | ( ( mWasLastReflowInterrupted as u8 as u16 ) << 8usize ) & ( 0x100 as u16 ) ) | ( ( mScrollPositionClampingScrollPortSizeSet as u8 as u16 ) << 9usize ) & ( 0x200 as u16 ) ) | ( ( mNeedLayoutFlush as u8 as u16 ) << 10usize ) & ( 0x400 as u16 ) ) | ( ( mNeedStyleFlush as u8 as u16 ) << 11usize ) & ( 0x800 as u16 ) ) | ( ( mObservingStyleFlushes as u8 as u16 ) << 12usize ) & ( 0x1000 as u16 ) ) | ( ( mObservingLayoutFlushes as u8 as u16 ) << 13usize ) & ( 0x2000 as u16 ) ) | ( ( mNeedThrottledAnimationFlush as u8 as u16 ) << 14usize ) & ( 0x4000 as u16 ) ) } } +} # [ test ] fn bindgen_test_layout_nsIPresShell ( ) { assert_eq ! ( :: std :: mem :: size_of :: < nsIPresShell > ( ) , 5344usize , concat ! ( "Size of: " , stringify ! ( nsIPresShell ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < nsIPresShell > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( nsIPresShell ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mDocument as * const _ as usize } , 8usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mDocument ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mPresContext as * const _ as usize } , 16usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mPresContext ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mStyleSet as * const _ as usize } , 24usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mStyleSet ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mFrameConstructor as * const _ as usize } , 32usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mFrameConstructor ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mViewManager as * const _ as usize } , 40usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mViewManager ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mFrameArena as * const _ as usize } , 48usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mFrameArena ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mSelection as * const _ as usize } , 5184usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mSelection ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mFrameManager as * const _ as usize } , 5192usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mFrameManager ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mForwardingContainer as * const _ as usize } , 5200usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mForwardingContainer ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mDocAccessible as * const _ as usize } , 5208usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mDocAccessible ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mReflowContinueTimer as * const _ as usize } , 5216usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mReflowContinueTimer ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mPaintCount as * const _ as usize } , 5224usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mPaintCount ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mScrollPositionClampingScrollPortSize as * const _ as usize } , 5232usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mScrollPositionClampingScrollPortSize ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mAutoWeakFrames as * const _ as usize } , 5240usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mAutoWeakFrames ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mWeakFrames as * const _ as usize } , 5248usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mWeakFrames ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mStyleCause as * const _ as usize } , 5280usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mStyleCause ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mReflowCause as * const _ as usize } , 5288usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mReflowCause ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mCanvasBackgroundColor as * const _ as usize } , 5296usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mCanvasBackgroundColor ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mResolution as * const _ as usize } , 5300usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mResolution ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mSelectionFlags as * const _ as usize } , 5308usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mSelectionFlags ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mChangeNestCount as * const _ as usize } , 5310usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mChangeNestCount ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mRenderFlags as * const _ as usize } , 5312usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mRenderFlags ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mPresShellId as * const _ as usize } , 5316usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mPresShellId ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mFontSizeInflationEmPerLine as * const _ as usize } , 5320usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mFontSizeInflationEmPerLine ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mFontSizeInflationMinTwips as * const _ as usize } , 5324usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mFontSizeInflationMinTwips ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mFontSizeInflationLineThreshold as * const _ as usize } , 5328usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mFontSizeInflationLineThreshold ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mFontSizeInflationForceEnabled as * const _ as usize } , 5332usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mFontSizeInflationForceEnabled ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mFontSizeInflationDisabledInMasterProcess as * const _ as usize } , 5333usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mFontSizeInflationDisabledInMasterProcess ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mFontSizeInflationEnabled as * const _ as usize } , 5334usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mFontSizeInflationEnabled ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mFontSizeInflationEnabledIsDirty as * const _ as usize } , 5335usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mFontSizeInflationEnabledIsDirty ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mPaintingIsFrozen as * const _ as usize } , 5336usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mPaintingIsFrozen ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mIsNeverPainting as * const _ as usize } , 5337usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mIsNeverPainting ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIPresShell ) ) . mInFlush as * const _ as usize } , 5338usize , concat ! ( "Alignment of field: " , stringify ! ( nsIPresShell ) , "::" , stringify ! ( mInFlush ) ) ) ; } impl nsIPresShell { # [ inline ] pub fn mDidInitialize ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x1 as u16 ; let val = ( unit_field_val & mask ) >> 0usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mDidInitialize ( & mut self , val : bool ) { let mask = 0x1 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 0usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mIsDestroying ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x2 as u16 ; let val = ( unit_field_val & mask ) >> 1usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mIsDestroying ( & mut self , val : bool ) { let mask = 0x2 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 1usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mIsReflowing ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x4 as u16 ; let val = ( unit_field_val & mask ) >> 2usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mIsReflowing ( & mut self , val : bool ) { let mask = 0x4 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 2usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mPaintingSuppressed ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x8 as u16 ; let val = ( unit_field_val & mask ) >> 3usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mPaintingSuppressed ( & mut self , val : bool ) { let mask = 0x8 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 3usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mIsActive ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x10 as u16 ; let val = ( unit_field_val & mask ) >> 4usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mIsActive ( & mut self , val : bool ) { let mask = 0x10 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 4usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mFrozen ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x20 as u16 ; let val = ( unit_field_val & mask ) >> 5usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mFrozen ( & mut self , val : bool ) { let mask = 0x20 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 5usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mIsFirstPaint ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x40 as u16 ; let val = ( unit_field_val & mask ) >> 6usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mIsFirstPaint ( & mut self , val : bool ) { let mask = 0x40 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 6usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mObservesMutationsForPrint ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x80 as u16 ; let val = ( unit_field_val & mask ) >> 7usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mObservesMutationsForPrint ( & mut self , val : bool ) { let mask = 0x80 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 7usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mWasLastReflowInterrupted ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x100 as u16 ; let val = ( unit_field_val & mask ) >> 8usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mWasLastReflowInterrupted ( & mut self , val : bool ) { let mask = 0x100 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 8usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mScrollPositionClampingScrollPortSizeSet ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x200 as u16 ; let val = ( unit_field_val & mask ) >> 9usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mScrollPositionClampingScrollPortSizeSet ( & mut self , val : bool ) { let mask = 0x200 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 9usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mNeedLayoutFlush ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x400 as u16 ; let val = ( unit_field_val & mask ) >> 10usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mNeedLayoutFlush ( & mut self , val : bool ) { let mask = 0x400 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 10usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mNeedStyleFlush ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x800 as u16 ; let val = ( unit_field_val & mask ) >> 11usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mNeedStyleFlush ( & mut self , val : bool ) { let mask = 0x800 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 11usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mObservingStyleFlushes ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x1000 as u16 ; let val = ( unit_field_val & mask ) >> 12usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mObservingStyleFlushes ( & mut self , val : bool ) { let mask = 0x1000 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 12usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mObservingLayoutFlushes ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x2000 as u16 ; let val = ( unit_field_val & mask ) >> 13usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mObservingLayoutFlushes ( & mut self , val : bool ) { let mask = 0x2000 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 13usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn mNeedThrottledAnimationFlush ( & self ) -> bool { let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; let mask = 0x4000 as u16 ; let val = ( unit_field_val & mask ) >> 14usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mNeedThrottledAnimationFlush ( & mut self , val : bool ) { let mask = 0x4000 as u16 ; let val = val as u8 as u16 ; let mut unit_field_val : u16 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u16 as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 14usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u16 > ( ) , ) ; } } # [ inline ] pub fn new_bitfield_1 ( mDidInitialize : bool , mIsDestroying : bool , mIsReflowing : bool , mPaintingSuppressed : bool , mIsActive : bool , mFrozen : bool , mIsFirstPaint : bool , mObservesMutationsForPrint : bool , mWasLastReflowInterrupted : bool , mScrollPositionClampingScrollPortSizeSet : bool , mNeedLayoutFlush : bool , mNeedStyleFlush : bool , mObservingStyleFlushes : bool , mObservingLayoutFlushes : bool , mNeedThrottledAnimationFlush : bool ) -> u16 { ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 0 | ( ( mDidInitialize as u8 as u16 ) << 0usize ) & ( 0x1 as u16 ) ) | ( ( mIsDestroying as u8 as u16 ) << 1usize ) & ( 0x2 as u16 ) ) | ( ( mIsReflowing as u8 as u16 ) << 2usize ) & ( 0x4 as u16 ) ) | ( ( mPaintingSuppressed as u8 as u16 ) << 3usize ) & ( 0x8 as u16 ) ) | ( ( mIsActive as u8 as u16 ) << 4usize ) & ( 0x10 as u16 ) ) | ( ( mFrozen as u8 as u16 ) << 5usize ) & ( 0x20 as u16 ) ) | ( ( mIsFirstPaint as u8 as u16 ) << 6usize ) & ( 0x40 as u16 ) ) | ( ( mObservesMutationsForPrint as u8 as u16 ) << 7usize ) & ( 0x80 as u16 ) ) | ( ( mWasLastReflowInterrupted as u8 as u16 ) << 8usize ) & ( 0x100 as u16 ) ) | ( ( mScrollPositionClampingScrollPortSizeSet as u8 as u16 ) << 9usize ) & ( 0x200 as u16 ) ) | ( ( mNeedLayoutFlush as u8 as u16 ) << 10usize ) & ( 0x400 as u16 ) ) | ( ( mNeedStyleFlush as u8 as u16 ) << 11usize ) & ( 0x800 as u16 ) ) | ( ( mObservingStyleFlushes as u8 as u16 ) << 12usize ) & ( 0x1000 as u16 ) ) | ( ( mObservingLayoutFlushes as u8 as u16 ) << 13usize ) & ( 0x2000 as u16 ) ) | ( ( mNeedThrottledAnimationFlush as u8 as u16 ) << 14usize ) & ( 0x4000 as u16 ) ) } } /// The signature of the timer callback function passed to initWithFuncCallback. /// This is the function that will get called when the timer expires if the /// timer is initialized via initWithFuncCallback. @@ -838,7 +853,7 @@ pub type ServoStyleContextStrong = ::gecko_bindings::sugar::ownership::Strong<:: /// will be "external-resource-document-created", and the data will be null. /// If document creation fails for some reason, observers will still be /// notified, with a null document pointer. - # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct nsIDocument_ExternalResourceLoad { pub _base : root :: nsISupports , pub mObservers : [ u64 ; 10usize ] , } # [ test ] fn bindgen_test_layout_nsIDocument_ExternalResourceLoad ( ) { assert_eq ! ( :: std :: mem :: size_of :: < nsIDocument_ExternalResourceLoad > ( ) , 88usize , concat ! ( "Size of: " , stringify ! ( nsIDocument_ExternalResourceLoad ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < nsIDocument_ExternalResourceLoad > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( nsIDocument_ExternalResourceLoad ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIDocument_ExternalResourceLoad ) ) . mObservers as * const _ as usize } , 8usize , concat ! ( "Alignment of field: " , stringify ! ( nsIDocument_ExternalResourceLoad ) , "::" , stringify ! ( mObservers ) ) ) ; } pub type nsIDocument_ActivityObserverEnumerator = :: std :: option :: Option < unsafe extern "C" fn ( arg1 : * mut root :: nsISupports , arg2 : * mut :: std :: os :: raw :: c_void ) > ; # [ repr ( u32 ) ] # [ derive ( Debug , Copy , Clone , PartialEq , Eq , Hash ) ] pub enum nsIDocument_DocumentTheme { Doc_Theme_Uninitialized = 0 , Doc_Theme_None = 1 , Doc_Theme_Neutral = 2 , Doc_Theme_Dark = 3 , Doc_Theme_Bright = 4 , } pub type nsIDocument_FrameRequestCallbackList = root :: nsTArray < root :: RefPtr < root :: mozilla :: dom :: FrameRequestCallback > > ; pub const nsIDocument_DeprecatedOperations_eEnablePrivilege : root :: nsIDocument_DeprecatedOperations = 0 ; pub const nsIDocument_DeprecatedOperations_eDOMExceptionCode : root :: nsIDocument_DeprecatedOperations = 1 ; pub const nsIDocument_DeprecatedOperations_eMutationEvent : root :: nsIDocument_DeprecatedOperations = 2 ; pub const nsIDocument_DeprecatedOperations_eComponents : root :: nsIDocument_DeprecatedOperations = 3 ; pub const nsIDocument_DeprecatedOperations_ePrefixedVisibilityAPI : root :: nsIDocument_DeprecatedOperations = 4 ; pub const nsIDocument_DeprecatedOperations_eNodeIteratorDetach : root :: nsIDocument_DeprecatedOperations = 5 ; pub const nsIDocument_DeprecatedOperations_eLenientThis : root :: nsIDocument_DeprecatedOperations = 6 ; pub const nsIDocument_DeprecatedOperations_eGetPreventDefault : root :: nsIDocument_DeprecatedOperations = 7 ; pub const nsIDocument_DeprecatedOperations_eGetSetUserData : root :: nsIDocument_DeprecatedOperations = 8 ; pub const nsIDocument_DeprecatedOperations_eMozGetAsFile : root :: nsIDocument_DeprecatedOperations = 9 ; pub const nsIDocument_DeprecatedOperations_eUseOfCaptureEvents : root :: nsIDocument_DeprecatedOperations = 10 ; pub const nsIDocument_DeprecatedOperations_eUseOfReleaseEvents : root :: nsIDocument_DeprecatedOperations = 11 ; pub const nsIDocument_DeprecatedOperations_eUseOfDOM3LoadMethod : root :: nsIDocument_DeprecatedOperations = 12 ; pub const nsIDocument_DeprecatedOperations_eChromeUseOfDOM3LoadMethod : root :: nsIDocument_DeprecatedOperations = 13 ; pub const nsIDocument_DeprecatedOperations_eShowModalDialog : root :: nsIDocument_DeprecatedOperations = 14 ; pub const nsIDocument_DeprecatedOperations_eSyncXMLHttpRequest : root :: nsIDocument_DeprecatedOperations = 15 ; pub const nsIDocument_DeprecatedOperations_eWindow_Cc_ontrollers : root :: nsIDocument_DeprecatedOperations = 16 ; pub const nsIDocument_DeprecatedOperations_eImportXULIntoContent : root :: nsIDocument_DeprecatedOperations = 17 ; pub const nsIDocument_DeprecatedOperations_ePannerNodeDoppler : root :: nsIDocument_DeprecatedOperations = 18 ; pub const nsIDocument_DeprecatedOperations_eNavigatorGetUserMedia : root :: nsIDocument_DeprecatedOperations = 19 ; pub const nsIDocument_DeprecatedOperations_eWebrtcDeprecatedPrefix : root :: nsIDocument_DeprecatedOperations = 20 ; pub const nsIDocument_DeprecatedOperations_eRTCPeerConnectionGetStreams : root :: nsIDocument_DeprecatedOperations = 21 ; pub const nsIDocument_DeprecatedOperations_eAppCache : root :: nsIDocument_DeprecatedOperations = 22 ; pub const nsIDocument_DeprecatedOperations_ePrefixedImageSmoothingEnabled : root :: nsIDocument_DeprecatedOperations = 23 ; pub const nsIDocument_DeprecatedOperations_ePrefixedFullscreenAPI : root :: nsIDocument_DeprecatedOperations = 24 ; pub const nsIDocument_DeprecatedOperations_eLenientSetter : root :: nsIDocument_DeprecatedOperations = 25 ; pub const nsIDocument_DeprecatedOperations_eFileLastModifiedDate : root :: nsIDocument_DeprecatedOperations = 26 ; pub const nsIDocument_DeprecatedOperations_eImageBitmapRenderingContext_TransferImageBitmap : root :: nsIDocument_DeprecatedOperations = 27 ; pub const nsIDocument_DeprecatedOperations_eURLCreateObjectURL_MediaStream : root :: nsIDocument_DeprecatedOperations = 28 ; pub const nsIDocument_DeprecatedOperations_eXMLBaseAttribute : root :: nsIDocument_DeprecatedOperations = 29 ; pub const nsIDocument_DeprecatedOperations_eWindowContentUntrusted : root :: nsIDocument_DeprecatedOperations = 30 ; pub const nsIDocument_DeprecatedOperations_eDeprecatedOperationCount : root :: nsIDocument_DeprecatedOperations = 31 ; pub type nsIDocument_DeprecatedOperations = :: std :: os :: raw :: c_uint ; pub const nsIDocument_DocumentWarnings_eIgnoringWillChangeOverBudget : root :: nsIDocument_DocumentWarnings = 0 ; pub const nsIDocument_DocumentWarnings_ePreventDefaultFromPassiveListener : root :: nsIDocument_DocumentWarnings = 1 ; pub const nsIDocument_DocumentWarnings_eSVGRefLoop : root :: nsIDocument_DocumentWarnings = 2 ; pub const nsIDocument_DocumentWarnings_eSVGRefChainLengthExceeded : root :: nsIDocument_DocumentWarnings = 3 ; pub const nsIDocument_DocumentWarnings_eDocumentWarningCount : root :: nsIDocument_DocumentWarnings = 4 ; pub type nsIDocument_DocumentWarnings = :: std :: os :: raw :: c_uint ; pub const nsIDocument_ElementCallbackType_eCreated : root :: nsIDocument_ElementCallbackType = 0 ; pub const nsIDocument_ElementCallbackType_eConnected : root :: nsIDocument_ElementCallbackType = 1 ; pub const nsIDocument_ElementCallbackType_eDisconnected : root :: nsIDocument_ElementCallbackType = 2 ; pub const nsIDocument_ElementCallbackType_eAdopted : root :: nsIDocument_ElementCallbackType = 3 ; pub const nsIDocument_ElementCallbackType_eAttributeChanged : root :: nsIDocument_ElementCallbackType = 4 ; pub type nsIDocument_ElementCallbackType = :: std :: os :: raw :: c_uint ; pub const nsIDocument_eScopedStyle_Unknown : root :: nsIDocument__bindgen_ty_1 = 0 ; pub const nsIDocument_eScopedStyle_Disabled : root :: nsIDocument__bindgen_ty_1 = 1 ; pub const nsIDocument_eScopedStyle_Enabled : root :: nsIDocument__bindgen_ty_1 = 2 ; pub type nsIDocument__bindgen_ty_1 = :: std :: os :: raw :: c_uint ; # [ repr ( u32 ) ] # [ derive ( Debug , Copy , Clone , PartialEq , Eq , Hash ) ] pub enum nsIDocument_Type { eUnknown = 0 , eHTML = 1 , eXHTML = 2 , eGenericXML = 3 , eSVG = 4 , eXUL = 5 , } pub const nsIDocument_Tri_eTriUnset : root :: nsIDocument_Tri = 0 ; pub const nsIDocument_Tri_eTriFalse : root :: nsIDocument_Tri = 1 ; pub const nsIDocument_Tri_eTriTrue : root :: nsIDocument_Tri = 2 ; pub type nsIDocument_Tri = :: std :: os :: raw :: c_uint ; # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsIDocument_FrameRequest { _unused : [ u8 ; 0 ] } pub const nsIDocument_kSegmentSize : usize = 128 ; # [ test ] fn bindgen_test_layout_nsIDocument ( ) { assert_eq ! ( :: std :: mem :: size_of :: < nsIDocument > ( ) , 896usize , concat ! ( "Size of: " , stringify ! ( nsIDocument ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < nsIDocument > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( nsIDocument ) ) ) ; } impl nsIDocument { # [ inline ] pub fn mBidiEnabled ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x1 as u64 ; let val = ( unit_field_val & mask ) >> 0usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mBidiEnabled ( & mut self , val : bool ) { let mask = 0x1 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 0usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mMathMLEnabled ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x2 as u64 ; let val = ( unit_field_val & mask ) >> 1usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mMathMLEnabled ( & mut self , val : bool ) { let mask = 0x2 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 1usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mIsInitialDocumentInWindow ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x4 as u64 ; let val = ( unit_field_val & mask ) >> 2usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mIsInitialDocumentInWindow ( & mut self , val : bool ) { let mask = 0x4 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 2usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mIgnoreDocGroupMismatches ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x8 as u64 ; let val = ( unit_field_val & mask ) >> 3usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mIgnoreDocGroupMismatches ( & mut self , val : bool ) { let mask = 0x8 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 3usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mLoadedAsData ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x10 as u64 ; let val = ( unit_field_val & mask ) >> 4usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mLoadedAsData ( & mut self , val : bool ) { let mask = 0x10 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 4usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mLoadedAsInteractiveData ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x20 as u64 ; let val = ( unit_field_val & mask ) >> 5usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mLoadedAsInteractiveData ( & mut self , val : bool ) { let mask = 0x20 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 5usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mMayStartLayout ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x40 as u64 ; let val = ( unit_field_val & mask ) >> 6usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mMayStartLayout ( & mut self , val : bool ) { let mask = 0x40 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 6usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHaveFiredTitleChange ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x80 as u64 ; let val = ( unit_field_val & mask ) >> 7usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHaveFiredTitleChange ( & mut self , val : bool ) { let mask = 0x80 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 7usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mIsShowing ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x100 as u64 ; let val = ( unit_field_val & mask ) >> 8usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mIsShowing ( & mut self , val : bool ) { let mask = 0x100 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 8usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mVisible ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x200 as u64 ; let val = ( unit_field_val & mask ) >> 9usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mVisible ( & mut self , val : bool ) { let mask = 0x200 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 9usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasReferrerPolicyCSP ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x400 as u64 ; let val = ( unit_field_val & mask ) >> 10usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasReferrerPolicyCSP ( & mut self , val : bool ) { let mask = 0x400 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 10usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mRemovedFromDocShell ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x800 as u64 ; let val = ( unit_field_val & mask ) >> 11usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mRemovedFromDocShell ( & mut self , val : bool ) { let mask = 0x800 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 11usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mAllowDNSPrefetch ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x1000 as u64 ; let val = ( unit_field_val & mask ) >> 12usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mAllowDNSPrefetch ( & mut self , val : bool ) { let mask = 0x1000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 12usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mIsStaticDocument ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x2000 as u64 ; let val = ( unit_field_val & mask ) >> 13usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mIsStaticDocument ( & mut self , val : bool ) { let mask = 0x2000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 13usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mCreatingStaticClone ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x4000 as u64 ; let val = ( unit_field_val & mask ) >> 14usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mCreatingStaticClone ( & mut self , val : bool ) { let mask = 0x4000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 14usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mInUnlinkOrDeletion ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x8000 as u64 ; let val = ( unit_field_val & mask ) >> 15usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mInUnlinkOrDeletion ( & mut self , val : bool ) { let mask = 0x8000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 15usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasHadScriptHandlingObject ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x10000 as u64 ; let val = ( unit_field_val & mask ) >> 16usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasHadScriptHandlingObject ( & mut self , val : bool ) { let mask = 0x10000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 16usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mIsBeingUsedAsImage ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x20000 as u64 ; let val = ( unit_field_val & mask ) >> 17usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mIsBeingUsedAsImage ( & mut self , val : bool ) { let mask = 0x20000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 17usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mIsSyntheticDocument ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x40000 as u64 ; let val = ( unit_field_val & mask ) >> 18usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mIsSyntheticDocument ( & mut self , val : bool ) { let mask = 0x40000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 18usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasLinksToUpdate ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x80000 as u64 ; let val = ( unit_field_val & mask ) >> 19usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasLinksToUpdate ( & mut self , val : bool ) { let mask = 0x80000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 19usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasLinksToUpdateRunnable ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x100000 as u64 ; let val = ( unit_field_val & mask ) >> 20usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasLinksToUpdateRunnable ( & mut self , val : bool ) { let mask = 0x100000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 20usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mMayHaveDOMMutationObservers ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x200000 as u64 ; let val = ( unit_field_val & mask ) >> 21usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mMayHaveDOMMutationObservers ( & mut self , val : bool ) { let mask = 0x200000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 21usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mMayHaveAnimationObservers ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x400000 as u64 ; let val = ( unit_field_val & mask ) >> 22usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mMayHaveAnimationObservers ( & mut self , val : bool ) { let mask = 0x400000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 22usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasMixedActiveContentLoaded ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x800000 as u64 ; let val = ( unit_field_val & mask ) >> 23usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasMixedActiveContentLoaded ( & mut self , val : bool ) { let mask = 0x800000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 23usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasMixedActiveContentBlocked ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x1000000 as u64 ; let val = ( unit_field_val & mask ) >> 24usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasMixedActiveContentBlocked ( & mut self , val : bool ) { let mask = 0x1000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 24usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasMixedDisplayContentLoaded ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x2000000 as u64 ; let val = ( unit_field_val & mask ) >> 25usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasMixedDisplayContentLoaded ( & mut self , val : bool ) { let mask = 0x2000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 25usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasMixedDisplayContentBlocked ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x4000000 as u64 ; let val = ( unit_field_val & mask ) >> 26usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasMixedDisplayContentBlocked ( & mut self , val : bool ) { let mask = 0x4000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 26usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasMixedContentObjectSubrequest ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x8000000 as u64 ; let val = ( unit_field_val & mask ) >> 27usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasMixedContentObjectSubrequest ( & mut self , val : bool ) { let mask = 0x8000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 27usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasCSP ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x10000000 as u64 ; let val = ( unit_field_val & mask ) >> 28usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasCSP ( & mut self , val : bool ) { let mask = 0x10000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 28usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasUnsafeEvalCSP ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x20000000 as u64 ; let val = ( unit_field_val & mask ) >> 29usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasUnsafeEvalCSP ( & mut self , val : bool ) { let mask = 0x20000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 29usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasUnsafeInlineCSP ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x40000000 as u64 ; let val = ( unit_field_val & mask ) >> 30usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasUnsafeInlineCSP ( & mut self , val : bool ) { let mask = 0x40000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 30usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasTrackingContentBlocked ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x80000000 as u64 ; let val = ( unit_field_val & mask ) >> 31usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasTrackingContentBlocked ( & mut self , val : bool ) { let mask = 0x80000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 31usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasTrackingContentLoaded ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x100000000 as u64 ; let val = ( unit_field_val & mask ) >> 32usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasTrackingContentLoaded ( & mut self , val : bool ) { let mask = 0x100000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 32usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mBFCacheDisallowed ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x200000000 as u64 ; let val = ( unit_field_val & mask ) >> 33usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mBFCacheDisallowed ( & mut self , val : bool ) { let mask = 0x200000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 33usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasHadDefaultView ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x400000000 as u64 ; let val = ( unit_field_val & mask ) >> 34usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasHadDefaultView ( & mut self , val : bool ) { let mask = 0x400000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 34usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mStyleSheetChangeEventsEnabled ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x800000000 as u64 ; let val = ( unit_field_val & mask ) >> 35usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mStyleSheetChangeEventsEnabled ( & mut self , val : bool ) { let mask = 0x800000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 35usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mIsSrcdocDocument ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x1000000000 as u64 ; let val = ( unit_field_val & mask ) >> 36usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mIsSrcdocDocument ( & mut self , val : bool ) { let mask = 0x1000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 36usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mDidDocumentOpen ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x2000000000 as u64 ; let val = ( unit_field_val & mask ) >> 37usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mDidDocumentOpen ( & mut self , val : bool ) { let mask = 0x2000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 37usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasDisplayDocument ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x4000000000 as u64 ; let val = ( unit_field_val & mask ) >> 38usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasDisplayDocument ( & mut self , val : bool ) { let mask = 0x4000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 38usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mFontFaceSetDirty ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x8000000000 as u64 ; let val = ( unit_field_val & mask ) >> 39usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mFontFaceSetDirty ( & mut self , val : bool ) { let mask = 0x8000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 39usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mGetUserFontSetCalled ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x10000000000 as u64 ; let val = ( unit_field_val & mask ) >> 40usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mGetUserFontSetCalled ( & mut self , val : bool ) { let mask = 0x10000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 40usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mPostedFlushUserFontSet ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x20000000000 as u64 ; let val = ( unit_field_val & mask ) >> 41usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mPostedFlushUserFontSet ( & mut self , val : bool ) { let mask = 0x20000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 41usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mDidFireDOMContentLoaded ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x40000000000 as u64 ; let val = ( unit_field_val & mask ) >> 42usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mDidFireDOMContentLoaded ( & mut self , val : bool ) { let mask = 0x40000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 42usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasScrollLinkedEffect ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x80000000000 as u64 ; let val = ( unit_field_val & mask ) >> 43usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasScrollLinkedEffect ( & mut self , val : bool ) { let mask = 0x80000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 43usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mFrameRequestCallbacksScheduled ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x100000000000 as u64 ; let val = ( unit_field_val & mask ) >> 44usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mFrameRequestCallbacksScheduled ( & mut self , val : bool ) { let mask = 0x100000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 44usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mIsTopLevelContentDocument ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x200000000000 as u64 ; let val = ( unit_field_val & mask ) >> 45usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mIsTopLevelContentDocument ( & mut self , val : bool ) { let mask = 0x200000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 45usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mIsContentDocument ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x400000000000 as u64 ; let val = ( unit_field_val & mask ) >> 46usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mIsContentDocument ( & mut self , val : bool ) { let mask = 0x400000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 46usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mMightHaveStaleServoData ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x800000000000 as u64 ; let val = ( unit_field_val & mask ) >> 47usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mMightHaveStaleServoData ( & mut self , val : bool ) { let mask = 0x800000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 47usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mDidCallBeginLoad ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x1000000000000 as u64 ; let val = ( unit_field_val & mask ) >> 48usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mDidCallBeginLoad ( & mut self , val : bool ) { let mask = 0x1000000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 48usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mBufferingCSPViolations ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x2000000000000 as u64 ; let val = ( unit_field_val & mask ) >> 49usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mBufferingCSPViolations ( & mut self , val : bool ) { let mask = 0x2000000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 49usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mAllowPaymentRequest ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x4000000000000 as u64 ; let val = ( unit_field_val & mask ) >> 50usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mAllowPaymentRequest ( & mut self , val : bool ) { let mask = 0x4000000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 50usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mIsScopedStyleEnabled ( & self ) -> :: std :: os :: raw :: c_uint { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x18000000000000 as u64 ; let val = ( unit_field_val & mask ) >> 51usize ; unsafe { :: std :: mem :: transmute ( val as u32 ) } } # [ inline ] pub fn set_mIsScopedStyleEnabled ( & mut self , val : :: std :: os :: raw :: c_uint ) { let mask = 0x18000000000000 as u64 ; let val = val as u32 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 51usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn new_bitfield_1 ( mBidiEnabled : bool , mMathMLEnabled : bool , mIsInitialDocumentInWindow : bool , mIgnoreDocGroupMismatches : bool , mLoadedAsData : bool , mLoadedAsInteractiveData : bool , mMayStartLayout : bool , mHaveFiredTitleChange : bool , mIsShowing : bool , mVisible : bool , mHasReferrerPolicyCSP : bool , mRemovedFromDocShell : bool , mAllowDNSPrefetch : bool , mIsStaticDocument : bool , mCreatingStaticClone : bool , mInUnlinkOrDeletion : bool , mHasHadScriptHandlingObject : bool , mIsBeingUsedAsImage : bool , mIsSyntheticDocument : bool , mHasLinksToUpdate : bool , mHasLinksToUpdateRunnable : bool , mMayHaveDOMMutationObservers : bool , mMayHaveAnimationObservers : bool , mHasMixedActiveContentLoaded : bool , mHasMixedActiveContentBlocked : bool , mHasMixedDisplayContentLoaded : bool , mHasMixedDisplayContentBlocked : bool , mHasMixedContentObjectSubrequest : bool , mHasCSP : bool , mHasUnsafeEvalCSP : bool , mHasUnsafeInlineCSP : bool , mHasTrackingContentBlocked : bool , mHasTrackingContentLoaded : bool , mBFCacheDisallowed : bool , mHasHadDefaultView : bool , mStyleSheetChangeEventsEnabled : bool , mIsSrcdocDocument : bool , mDidDocumentOpen : bool , mHasDisplayDocument : bool , mFontFaceSetDirty : bool , mGetUserFontSetCalled : bool , mPostedFlushUserFontSet : bool , mDidFireDOMContentLoaded : bool , mHasScrollLinkedEffect : bool , mFrameRequestCallbacksScheduled : bool , mIsTopLevelContentDocument : bool , mIsContentDocument : bool , mMightHaveStaleServoData : bool , mDidCallBeginLoad : bool , mBufferingCSPViolations : bool , mAllowPaymentRequest : bool , mIsScopedStyleEnabled : :: std :: os :: raw :: c_uint ) -> u64 { ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 0 | ( ( mBidiEnabled as u8 as u64 ) << 0usize ) & ( 0x1 as u64 ) ) | ( ( mMathMLEnabled as u8 as u64 ) << 1usize ) & ( 0x2 as u64 ) ) | ( ( mIsInitialDocumentInWindow as u8 as u64 ) << 2usize ) & ( 0x4 as u64 ) ) | ( ( mIgnoreDocGroupMismatches as u8 as u64 ) << 3usize ) & ( 0x8 as u64 ) ) | ( ( mLoadedAsData as u8 as u64 ) << 4usize ) & ( 0x10 as u64 ) ) | ( ( mLoadedAsInteractiveData as u8 as u64 ) << 5usize ) & ( 0x20 as u64 ) ) | ( ( mMayStartLayout as u8 as u64 ) << 6usize ) & ( 0x40 as u64 ) ) | ( ( mHaveFiredTitleChange as u8 as u64 ) << 7usize ) & ( 0x80 as u64 ) ) | ( ( mIsShowing as u8 as u64 ) << 8usize ) & ( 0x100 as u64 ) ) | ( ( mVisible as u8 as u64 ) << 9usize ) & ( 0x200 as u64 ) ) | ( ( mHasReferrerPolicyCSP as u8 as u64 ) << 10usize ) & ( 0x400 as u64 ) ) | ( ( mRemovedFromDocShell as u8 as u64 ) << 11usize ) & ( 0x800 as u64 ) ) | ( ( mAllowDNSPrefetch as u8 as u64 ) << 12usize ) & ( 0x1000 as u64 ) ) | ( ( mIsStaticDocument as u8 as u64 ) << 13usize ) & ( 0x2000 as u64 ) ) | ( ( mCreatingStaticClone as u8 as u64 ) << 14usize ) & ( 0x4000 as u64 ) ) | ( ( mInUnlinkOrDeletion as u8 as u64 ) << 15usize ) & ( 0x8000 as u64 ) ) | ( ( mHasHadScriptHandlingObject as u8 as u64 ) << 16usize ) & ( 0x10000 as u64 ) ) | ( ( mIsBeingUsedAsImage as u8 as u64 ) << 17usize ) & ( 0x20000 as u64 ) ) | ( ( mIsSyntheticDocument as u8 as u64 ) << 18usize ) & ( 0x40000 as u64 ) ) | ( ( mHasLinksToUpdate as u8 as u64 ) << 19usize ) & ( 0x80000 as u64 ) ) | ( ( mHasLinksToUpdateRunnable as u8 as u64 ) << 20usize ) & ( 0x100000 as u64 ) ) | ( ( mMayHaveDOMMutationObservers as u8 as u64 ) << 21usize ) & ( 0x200000 as u64 ) ) | ( ( mMayHaveAnimationObservers as u8 as u64 ) << 22usize ) & ( 0x400000 as u64 ) ) | ( ( mHasMixedActiveContentLoaded as u8 as u64 ) << 23usize ) & ( 0x800000 as u64 ) ) | ( ( mHasMixedActiveContentBlocked as u8 as u64 ) << 24usize ) & ( 0x1000000 as u64 ) ) | ( ( mHasMixedDisplayContentLoaded as u8 as u64 ) << 25usize ) & ( 0x2000000 as u64 ) ) | ( ( mHasMixedDisplayContentBlocked as u8 as u64 ) << 26usize ) & ( 0x4000000 as u64 ) ) | ( ( mHasMixedContentObjectSubrequest as u8 as u64 ) << 27usize ) & ( 0x8000000 as u64 ) ) | ( ( mHasCSP as u8 as u64 ) << 28usize ) & ( 0x10000000 as u64 ) ) | ( ( mHasUnsafeEvalCSP as u8 as u64 ) << 29usize ) & ( 0x20000000 as u64 ) ) | ( ( mHasUnsafeInlineCSP as u8 as u64 ) << 30usize ) & ( 0x40000000 as u64 ) ) | ( ( mHasTrackingContentBlocked as u8 as u64 ) << 31usize ) & ( 0x80000000 as u64 ) ) | ( ( mHasTrackingContentLoaded as u8 as u64 ) << 32usize ) & ( 0x100000000 as u64 ) ) | ( ( mBFCacheDisallowed as u8 as u64 ) << 33usize ) & ( 0x200000000 as u64 ) ) | ( ( mHasHadDefaultView as u8 as u64 ) << 34usize ) & ( 0x400000000 as u64 ) ) | ( ( mStyleSheetChangeEventsEnabled as u8 as u64 ) << 35usize ) & ( 0x800000000 as u64 ) ) | ( ( mIsSrcdocDocument as u8 as u64 ) << 36usize ) & ( 0x1000000000 as u64 ) ) | ( ( mDidDocumentOpen as u8 as u64 ) << 37usize ) & ( 0x2000000000 as u64 ) ) | ( ( mHasDisplayDocument as u8 as u64 ) << 38usize ) & ( 0x4000000000 as u64 ) ) | ( ( mFontFaceSetDirty as u8 as u64 ) << 39usize ) & ( 0x8000000000 as u64 ) ) | ( ( mGetUserFontSetCalled as u8 as u64 ) << 40usize ) & ( 0x10000000000 as u64 ) ) | ( ( mPostedFlushUserFontSet as u8 as u64 ) << 41usize ) & ( 0x20000000000 as u64 ) ) | ( ( mDidFireDOMContentLoaded as u8 as u64 ) << 42usize ) & ( 0x40000000000 as u64 ) ) | ( ( mHasScrollLinkedEffect as u8 as u64 ) << 43usize ) & ( 0x80000000000 as u64 ) ) | ( ( mFrameRequestCallbacksScheduled as u8 as u64 ) << 44usize ) & ( 0x100000000000 as u64 ) ) | ( ( mIsTopLevelContentDocument as u8 as u64 ) << 45usize ) & ( 0x200000000000 as u64 ) ) | ( ( mIsContentDocument as u8 as u64 ) << 46usize ) & ( 0x400000000000 as u64 ) ) | ( ( mMightHaveStaleServoData as u8 as u64 ) << 47usize ) & ( 0x800000000000 as u64 ) ) | ( ( mDidCallBeginLoad as u8 as u64 ) << 48usize ) & ( 0x1000000000000 as u64 ) ) | ( ( mBufferingCSPViolations as u8 as u64 ) << 49usize ) & ( 0x2000000000000 as u64 ) ) | ( ( mAllowPaymentRequest as u8 as u64 ) << 50usize ) & ( 0x4000000000000 as u64 ) ) | ( ( mIsScopedStyleEnabled as u32 as u64 ) << 51usize ) & ( 0x18000000000000 as u64 ) ) } } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsBidi { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsIPrintSettings { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsITheme { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct gfxTextPerfMetrics { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsTransitionManager { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsAnimationManager { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsDeviceContext { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct gfxMissingFontRecorder { _unused : [ u8 ; 0 ] } pub const kPresContext_DefaultVariableFont_ID : u8 = 0 ; pub const kPresContext_DefaultFixedFont_ID : u8 = 1 ; # [ repr ( C ) ] pub struct nsPresContext { pub _base : root :: nsISupports , pub _base_1 : u64 , pub mRefCnt : root :: nsCycleCollectingAutoRefCnt , pub mType : root :: nsPresContext_nsPresContextType , pub mShell : * mut root :: nsIPresShell , pub mDocument : root :: nsCOMPtr , pub mDeviceContext : root :: RefPtr < root :: nsDeviceContext > , pub mEventManager : root :: RefPtr < root :: mozilla :: EventStateManager > , pub mRefreshDriver : root :: RefPtr < root :: nsRefreshDriver > , pub mEffectCompositor : root :: RefPtr < root :: mozilla :: EffectCompositor > , pub mTransitionManager : root :: RefPtr < root :: nsTransitionManager > , pub mAnimationManager : root :: RefPtr < root :: nsAnimationManager > , pub mRestyleManager : root :: RefPtr < root :: mozilla :: RestyleManager > , pub mCounterStyleManager : root :: RefPtr < root :: mozilla :: CounterStyleManager > , pub mMedium : * mut root :: nsAtom , pub mMediaEmulated : root :: RefPtr < root :: nsAtom > , pub mFontFeatureValuesLookup : root :: RefPtr < root :: gfxFontFeatureValueSet > , pub mLinkHandler : * mut root :: nsILinkHandler , pub mLanguage : root :: RefPtr < root :: nsAtom > , pub mInflationDisabledForShrinkWrap : bool , pub mContainer : u64 , pub mBaseMinFontSize : i32 , pub mSystemFontScale : f32 , pub mTextZoom : f32 , pub mEffectiveTextZoom : f32 , pub mFullZoom : f32 , pub mOverrideDPPX : f32 , pub mLastFontInflationScreenSize : root :: gfxSize , pub mCurAppUnitsPerDevPixel : i32 , pub mAutoQualityMinFontSizePixelsPref : i32 , pub mTheme : root :: nsCOMPtr , pub mLangService : * mut root :: nsLanguageAtomService , pub mPrintSettings : root :: nsCOMPtr , pub mPrefChangedTimer : root :: nsCOMPtr , pub mBidiEngine : root :: mozilla :: UniquePtr < root :: nsBidi > , pub mTransactions : [ u64 ; 10usize ] , pub mTextPerf : root :: nsAutoPtr < root :: gfxTextPerfMetrics > , pub mMissingFonts : root :: nsAutoPtr < root :: gfxMissingFontRecorder > , pub mVisibleArea : root :: nsRect , pub mLastResizeEventVisibleArea : root :: nsRect , pub mPageSize : root :: nsSize , pub mPageScale : f32 , pub mPPScale : f32 , pub mDefaultColor : root :: nscolor , pub mBackgroundColor : root :: nscolor , pub mLinkColor : root :: nscolor , pub mActiveLinkColor : root :: nscolor , pub mVisitedLinkColor : root :: nscolor , pub mFocusBackgroundColor : root :: nscolor , pub mFocusTextColor : root :: nscolor , pub mBodyTextColor : root :: nscolor , pub mViewportScrollbarOverrideElement : * mut root :: mozilla :: dom :: Element , pub mViewportStyleScrollbar : root :: nsPresContext_ScrollbarStyles , pub mFocusRingWidth : u8 , pub mExistThrottledUpdates : bool , pub mImageAnimationMode : u16 , pub mImageAnimationModePref : u16 , pub mLangGroupFontPrefs : root :: nsPresContext_LangGroupFontPrefs , pub mFontGroupCacheDirty : bool , pub mLanguagesUsed : [ u64 ; 4usize ] , pub mBorderWidthTable : [ root :: nscoord ; 3usize ] , pub mInterruptChecksToSkip : u32 , pub mElementsRestyled : u64 , pub mFramesConstructed : u64 , pub mFramesReflowed : u64 , pub mReflowStartTime : root :: mozilla :: TimeStamp , pub mFirstNonBlankPaintTime : root :: mozilla :: TimeStamp , pub mFirstClickTime : root :: mozilla :: TimeStamp , pub mFirstKeyTime : root :: mozilla :: TimeStamp , pub mFirstMouseMoveTime : root :: mozilla :: TimeStamp , pub mFirstScrollTime : root :: mozilla :: TimeStamp , pub mInteractionTimeEnabled : bool , pub mLastStyleUpdateForAllAnimations : root :: mozilla :: TimeStamp , pub mTelemetryScrollLastY : root :: nscoord , pub mTelemetryScrollMaxY : root :: nscoord , pub mTelemetryScrollTotalY : root :: nscoord , pub _bitfield_1 : [ u8 ; 6usize ] , pub __bindgen_padding_0 : [ u16 ; 3usize ] , } pub type nsPresContext_Encoding = root :: mozilla :: Encoding ; pub type nsPresContext_NotNull < T > = root :: mozilla :: NotNull < T > ; pub type nsPresContext_LangGroupFontPrefs = root :: mozilla :: LangGroupFontPrefs ; pub type nsPresContext_ScrollbarStyles = root :: mozilla :: ScrollbarStyles ; pub type nsPresContext_StaticPresData = root :: mozilla :: StaticPresData ; pub type nsPresContext_HasThreadSafeRefCnt = root :: mozilla :: FalseType ; # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct nsPresContext_cycleCollection { pub _base : root :: nsXPCOMCycleCollectionParticipant , } # [ test ] fn bindgen_test_layout_nsPresContext_cycleCollection ( ) { assert_eq ! ( :: std :: mem :: size_of :: < nsPresContext_cycleCollection > ( ) , 16usize , concat ! ( "Size of: " , stringify ! ( nsPresContext_cycleCollection ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < nsPresContext_cycleCollection > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( nsPresContext_cycleCollection ) ) ) ; } impl Clone for nsPresContext_cycleCollection { fn clone ( & self ) -> Self { * self } } pub const nsPresContext_nsPresContextType_eContext_Galley : root :: nsPresContext_nsPresContextType = 0 ; pub const nsPresContext_nsPresContextType_eContext_PrintPreview : root :: nsPresContext_nsPresContextType = 1 ; pub const nsPresContext_nsPresContextType_eContext_Print : root :: nsPresContext_nsPresContextType = 2 ; pub const nsPresContext_nsPresContextType_eContext_PageLayout : root :: nsPresContext_nsPresContextType = 3 ; pub type nsPresContext_nsPresContextType = :: std :: os :: raw :: c_uint ; pub const nsPresContext_InteractionType_eClickInteraction : root :: nsPresContext_InteractionType = 0 ; pub const nsPresContext_InteractionType_eKeyInteraction : root :: nsPresContext_InteractionType = 1 ; pub const nsPresContext_InteractionType_eMouseMoveInteraction : root :: nsPresContext_InteractionType = 2 ; pub const nsPresContext_InteractionType_eScrollInteraction : root :: nsPresContext_InteractionType = 3 ; pub type nsPresContext_InteractionType = u32 ; + # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct nsIDocument_ExternalResourceLoad { pub _base : root :: nsISupports , pub mObservers : [ u64 ; 10usize ] , } # [ test ] fn bindgen_test_layout_nsIDocument_ExternalResourceLoad ( ) { assert_eq ! ( :: std :: mem :: size_of :: < nsIDocument_ExternalResourceLoad > ( ) , 88usize , concat ! ( "Size of: " , stringify ! ( nsIDocument_ExternalResourceLoad ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < nsIDocument_ExternalResourceLoad > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( nsIDocument_ExternalResourceLoad ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsIDocument_ExternalResourceLoad ) ) . mObservers as * const _ as usize } , 8usize , concat ! ( "Alignment of field: " , stringify ! ( nsIDocument_ExternalResourceLoad ) , "::" , stringify ! ( mObservers ) ) ) ; } pub type nsIDocument_ActivityObserverEnumerator = :: std :: option :: Option < unsafe extern "C" fn ( arg1 : * mut root :: nsISupports , arg2 : * mut :: std :: os :: raw :: c_void ) > ; # [ repr ( u32 ) ] # [ derive ( Debug , Copy , Clone , PartialEq , Eq , Hash ) ] pub enum nsIDocument_DocumentTheme { Doc_Theme_Uninitialized = 0 , Doc_Theme_None = 1 , Doc_Theme_Neutral = 2 , Doc_Theme_Dark = 3 , Doc_Theme_Bright = 4 , } pub type nsIDocument_FrameRequestCallbackList = root :: nsTArray < root :: RefPtr < root :: mozilla :: dom :: FrameRequestCallback > > ; pub const nsIDocument_DeprecatedOperations_eEnablePrivilege : root :: nsIDocument_DeprecatedOperations = 0 ; pub const nsIDocument_DeprecatedOperations_eDOMExceptionCode : root :: nsIDocument_DeprecatedOperations = 1 ; pub const nsIDocument_DeprecatedOperations_eMutationEvent : root :: nsIDocument_DeprecatedOperations = 2 ; pub const nsIDocument_DeprecatedOperations_eComponents : root :: nsIDocument_DeprecatedOperations = 3 ; pub const nsIDocument_DeprecatedOperations_ePrefixedVisibilityAPI : root :: nsIDocument_DeprecatedOperations = 4 ; pub const nsIDocument_DeprecatedOperations_eNodeIteratorDetach : root :: nsIDocument_DeprecatedOperations = 5 ; pub const nsIDocument_DeprecatedOperations_eLenientThis : root :: nsIDocument_DeprecatedOperations = 6 ; pub const nsIDocument_DeprecatedOperations_eGetPreventDefault : root :: nsIDocument_DeprecatedOperations = 7 ; pub const nsIDocument_DeprecatedOperations_eGetSetUserData : root :: nsIDocument_DeprecatedOperations = 8 ; pub const nsIDocument_DeprecatedOperations_eMozGetAsFile : root :: nsIDocument_DeprecatedOperations = 9 ; pub const nsIDocument_DeprecatedOperations_eUseOfCaptureEvents : root :: nsIDocument_DeprecatedOperations = 10 ; pub const nsIDocument_DeprecatedOperations_eUseOfReleaseEvents : root :: nsIDocument_DeprecatedOperations = 11 ; pub const nsIDocument_DeprecatedOperations_eUseOfDOM3LoadMethod : root :: nsIDocument_DeprecatedOperations = 12 ; pub const nsIDocument_DeprecatedOperations_eChromeUseOfDOM3LoadMethod : root :: nsIDocument_DeprecatedOperations = 13 ; pub const nsIDocument_DeprecatedOperations_eShowModalDialog : root :: nsIDocument_DeprecatedOperations = 14 ; pub const nsIDocument_DeprecatedOperations_eSyncXMLHttpRequest : root :: nsIDocument_DeprecatedOperations = 15 ; pub const nsIDocument_DeprecatedOperations_eWindow_Cc_ontrollers : root :: nsIDocument_DeprecatedOperations = 16 ; pub const nsIDocument_DeprecatedOperations_eImportXULIntoContent : root :: nsIDocument_DeprecatedOperations = 17 ; pub const nsIDocument_DeprecatedOperations_ePannerNodeDoppler : root :: nsIDocument_DeprecatedOperations = 18 ; pub const nsIDocument_DeprecatedOperations_eNavigatorGetUserMedia : root :: nsIDocument_DeprecatedOperations = 19 ; pub const nsIDocument_DeprecatedOperations_eWebrtcDeprecatedPrefix : root :: nsIDocument_DeprecatedOperations = 20 ; pub const nsIDocument_DeprecatedOperations_eRTCPeerConnectionGetStreams : root :: nsIDocument_DeprecatedOperations = 21 ; pub const nsIDocument_DeprecatedOperations_eAppCache : root :: nsIDocument_DeprecatedOperations = 22 ; pub const nsIDocument_DeprecatedOperations_ePrefixedImageSmoothingEnabled : root :: nsIDocument_DeprecatedOperations = 23 ; pub const nsIDocument_DeprecatedOperations_ePrefixedFullscreenAPI : root :: nsIDocument_DeprecatedOperations = 24 ; pub const nsIDocument_DeprecatedOperations_eLenientSetter : root :: nsIDocument_DeprecatedOperations = 25 ; pub const nsIDocument_DeprecatedOperations_eFileLastModifiedDate : root :: nsIDocument_DeprecatedOperations = 26 ; pub const nsIDocument_DeprecatedOperations_eImageBitmapRenderingContext_TransferImageBitmap : root :: nsIDocument_DeprecatedOperations = 27 ; pub const nsIDocument_DeprecatedOperations_eURLCreateObjectURL_MediaStream : root :: nsIDocument_DeprecatedOperations = 28 ; pub const nsIDocument_DeprecatedOperations_eXMLBaseAttribute : root :: nsIDocument_DeprecatedOperations = 29 ; pub const nsIDocument_DeprecatedOperations_eWindowContentUntrusted : root :: nsIDocument_DeprecatedOperations = 30 ; pub const nsIDocument_DeprecatedOperations_eDeprecatedOperationCount : root :: nsIDocument_DeprecatedOperations = 31 ; pub type nsIDocument_DeprecatedOperations = :: std :: os :: raw :: c_uint ; pub const nsIDocument_DocumentWarnings_eIgnoringWillChangeOverBudget : root :: nsIDocument_DocumentWarnings = 0 ; pub const nsIDocument_DocumentWarnings_ePreventDefaultFromPassiveListener : root :: nsIDocument_DocumentWarnings = 1 ; pub const nsIDocument_DocumentWarnings_eSVGRefLoop : root :: nsIDocument_DocumentWarnings = 2 ; pub const nsIDocument_DocumentWarnings_eSVGRefChainLengthExceeded : root :: nsIDocument_DocumentWarnings = 3 ; pub const nsIDocument_DocumentWarnings_eDocumentWarningCount : root :: nsIDocument_DocumentWarnings = 4 ; pub type nsIDocument_DocumentWarnings = :: std :: os :: raw :: c_uint ; pub const nsIDocument_ElementCallbackType_eConnected : root :: nsIDocument_ElementCallbackType = 0 ; pub const nsIDocument_ElementCallbackType_eDisconnected : root :: nsIDocument_ElementCallbackType = 1 ; pub const nsIDocument_ElementCallbackType_eAdopted : root :: nsIDocument_ElementCallbackType = 2 ; pub const nsIDocument_ElementCallbackType_eAttributeChanged : root :: nsIDocument_ElementCallbackType = 3 ; pub type nsIDocument_ElementCallbackType = :: std :: os :: raw :: c_uint ; pub const nsIDocument_eScopedStyle_Unknown : root :: nsIDocument__bindgen_ty_1 = 0 ; pub const nsIDocument_eScopedStyle_Disabled : root :: nsIDocument__bindgen_ty_1 = 1 ; pub const nsIDocument_eScopedStyle_Enabled : root :: nsIDocument__bindgen_ty_1 = 2 ; pub type nsIDocument__bindgen_ty_1 = :: std :: os :: raw :: c_uint ; # [ repr ( u32 ) ] # [ derive ( Debug , Copy , Clone , PartialEq , Eq , Hash ) ] pub enum nsIDocument_Type { eUnknown = 0 , eHTML = 1 , eXHTML = 2 , eGenericXML = 3 , eSVG = 4 , eXUL = 5 , } pub const nsIDocument_Tri_eTriUnset : root :: nsIDocument_Tri = 0 ; pub const nsIDocument_Tri_eTriFalse : root :: nsIDocument_Tri = 1 ; pub const nsIDocument_Tri_eTriTrue : root :: nsIDocument_Tri = 2 ; pub type nsIDocument_Tri = :: std :: os :: raw :: c_uint ; # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsIDocument_FrameRequest { _unused : [ u8 ; 0 ] } pub const nsIDocument_kSegmentSize : usize = 128 ; # [ test ] fn bindgen_test_layout_nsIDocument ( ) { assert_eq ! ( :: std :: mem :: size_of :: < nsIDocument > ( ) , 896usize , concat ! ( "Size of: " , stringify ! ( nsIDocument ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < nsIDocument > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( nsIDocument ) ) ) ; } impl nsIDocument { # [ inline ] pub fn mBidiEnabled ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x1 as u64 ; let val = ( unit_field_val & mask ) >> 0usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mBidiEnabled ( & mut self , val : bool ) { let mask = 0x1 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 0usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mMathMLEnabled ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x2 as u64 ; let val = ( unit_field_val & mask ) >> 1usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mMathMLEnabled ( & mut self , val : bool ) { let mask = 0x2 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 1usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mIsInitialDocumentInWindow ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x4 as u64 ; let val = ( unit_field_val & mask ) >> 2usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mIsInitialDocumentInWindow ( & mut self , val : bool ) { let mask = 0x4 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 2usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mIgnoreDocGroupMismatches ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x8 as u64 ; let val = ( unit_field_val & mask ) >> 3usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mIgnoreDocGroupMismatches ( & mut self , val : bool ) { let mask = 0x8 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 3usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mLoadedAsData ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x10 as u64 ; let val = ( unit_field_val & mask ) >> 4usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mLoadedAsData ( & mut self , val : bool ) { let mask = 0x10 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 4usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mLoadedAsInteractiveData ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x20 as u64 ; let val = ( unit_field_val & mask ) >> 5usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mLoadedAsInteractiveData ( & mut self , val : bool ) { let mask = 0x20 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 5usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mMayStartLayout ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x40 as u64 ; let val = ( unit_field_val & mask ) >> 6usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mMayStartLayout ( & mut self , val : bool ) { let mask = 0x40 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 6usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHaveFiredTitleChange ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x80 as u64 ; let val = ( unit_field_val & mask ) >> 7usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHaveFiredTitleChange ( & mut self , val : bool ) { let mask = 0x80 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 7usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mIsShowing ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x100 as u64 ; let val = ( unit_field_val & mask ) >> 8usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mIsShowing ( & mut self , val : bool ) { let mask = 0x100 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 8usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mVisible ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x200 as u64 ; let val = ( unit_field_val & mask ) >> 9usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mVisible ( & mut self , val : bool ) { let mask = 0x200 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 9usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasReferrerPolicyCSP ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x400 as u64 ; let val = ( unit_field_val & mask ) >> 10usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasReferrerPolicyCSP ( & mut self , val : bool ) { let mask = 0x400 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 10usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mRemovedFromDocShell ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x800 as u64 ; let val = ( unit_field_val & mask ) >> 11usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mRemovedFromDocShell ( & mut self , val : bool ) { let mask = 0x800 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 11usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mAllowDNSPrefetch ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x1000 as u64 ; let val = ( unit_field_val & mask ) >> 12usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mAllowDNSPrefetch ( & mut self , val : bool ) { let mask = 0x1000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 12usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mIsStaticDocument ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x2000 as u64 ; let val = ( unit_field_val & mask ) >> 13usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mIsStaticDocument ( & mut self , val : bool ) { let mask = 0x2000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 13usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mCreatingStaticClone ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x4000 as u64 ; let val = ( unit_field_val & mask ) >> 14usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mCreatingStaticClone ( & mut self , val : bool ) { let mask = 0x4000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 14usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mInUnlinkOrDeletion ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x8000 as u64 ; let val = ( unit_field_val & mask ) >> 15usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mInUnlinkOrDeletion ( & mut self , val : bool ) { let mask = 0x8000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 15usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasHadScriptHandlingObject ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x10000 as u64 ; let val = ( unit_field_val & mask ) >> 16usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasHadScriptHandlingObject ( & mut self , val : bool ) { let mask = 0x10000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 16usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mIsBeingUsedAsImage ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x20000 as u64 ; let val = ( unit_field_val & mask ) >> 17usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mIsBeingUsedAsImage ( & mut self , val : bool ) { let mask = 0x20000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 17usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mIsSyntheticDocument ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x40000 as u64 ; let val = ( unit_field_val & mask ) >> 18usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mIsSyntheticDocument ( & mut self , val : bool ) { let mask = 0x40000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 18usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasLinksToUpdate ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x80000 as u64 ; let val = ( unit_field_val & mask ) >> 19usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasLinksToUpdate ( & mut self , val : bool ) { let mask = 0x80000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 19usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasLinksToUpdateRunnable ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x100000 as u64 ; let val = ( unit_field_val & mask ) >> 20usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasLinksToUpdateRunnable ( & mut self , val : bool ) { let mask = 0x100000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 20usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mMayHaveDOMMutationObservers ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x200000 as u64 ; let val = ( unit_field_val & mask ) >> 21usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mMayHaveDOMMutationObservers ( & mut self , val : bool ) { let mask = 0x200000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 21usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mMayHaveAnimationObservers ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x400000 as u64 ; let val = ( unit_field_val & mask ) >> 22usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mMayHaveAnimationObservers ( & mut self , val : bool ) { let mask = 0x400000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 22usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasMixedActiveContentLoaded ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x800000 as u64 ; let val = ( unit_field_val & mask ) >> 23usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasMixedActiveContentLoaded ( & mut self , val : bool ) { let mask = 0x800000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 23usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasMixedActiveContentBlocked ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x1000000 as u64 ; let val = ( unit_field_val & mask ) >> 24usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasMixedActiveContentBlocked ( & mut self , val : bool ) { let mask = 0x1000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 24usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasMixedDisplayContentLoaded ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x2000000 as u64 ; let val = ( unit_field_val & mask ) >> 25usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasMixedDisplayContentLoaded ( & mut self , val : bool ) { let mask = 0x2000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 25usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasMixedDisplayContentBlocked ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x4000000 as u64 ; let val = ( unit_field_val & mask ) >> 26usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasMixedDisplayContentBlocked ( & mut self , val : bool ) { let mask = 0x4000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 26usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasMixedContentObjectSubrequest ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x8000000 as u64 ; let val = ( unit_field_val & mask ) >> 27usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasMixedContentObjectSubrequest ( & mut self , val : bool ) { let mask = 0x8000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 27usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasCSP ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x10000000 as u64 ; let val = ( unit_field_val & mask ) >> 28usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasCSP ( & mut self , val : bool ) { let mask = 0x10000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 28usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasUnsafeEvalCSP ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x20000000 as u64 ; let val = ( unit_field_val & mask ) >> 29usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasUnsafeEvalCSP ( & mut self , val : bool ) { let mask = 0x20000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 29usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasUnsafeInlineCSP ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x40000000 as u64 ; let val = ( unit_field_val & mask ) >> 30usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasUnsafeInlineCSP ( & mut self , val : bool ) { let mask = 0x40000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 30usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasTrackingContentBlocked ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x80000000 as u64 ; let val = ( unit_field_val & mask ) >> 31usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasTrackingContentBlocked ( & mut self , val : bool ) { let mask = 0x80000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 31usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasTrackingContentLoaded ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x100000000 as u64 ; let val = ( unit_field_val & mask ) >> 32usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasTrackingContentLoaded ( & mut self , val : bool ) { let mask = 0x100000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 32usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mBFCacheDisallowed ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x200000000 as u64 ; let val = ( unit_field_val & mask ) >> 33usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mBFCacheDisallowed ( & mut self , val : bool ) { let mask = 0x200000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 33usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasHadDefaultView ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x400000000 as u64 ; let val = ( unit_field_val & mask ) >> 34usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasHadDefaultView ( & mut self , val : bool ) { let mask = 0x400000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 34usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mStyleSheetChangeEventsEnabled ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x800000000 as u64 ; let val = ( unit_field_val & mask ) >> 35usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mStyleSheetChangeEventsEnabled ( & mut self , val : bool ) { let mask = 0x800000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 35usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mIsSrcdocDocument ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x1000000000 as u64 ; let val = ( unit_field_val & mask ) >> 36usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mIsSrcdocDocument ( & mut self , val : bool ) { let mask = 0x1000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 36usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mDidDocumentOpen ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x2000000000 as u64 ; let val = ( unit_field_val & mask ) >> 37usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mDidDocumentOpen ( & mut self , val : bool ) { let mask = 0x2000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 37usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasDisplayDocument ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x4000000000 as u64 ; let val = ( unit_field_val & mask ) >> 38usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasDisplayDocument ( & mut self , val : bool ) { let mask = 0x4000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 38usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mFontFaceSetDirty ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x8000000000 as u64 ; let val = ( unit_field_val & mask ) >> 39usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mFontFaceSetDirty ( & mut self , val : bool ) { let mask = 0x8000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 39usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mGetUserFontSetCalled ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x10000000000 as u64 ; let val = ( unit_field_val & mask ) >> 40usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mGetUserFontSetCalled ( & mut self , val : bool ) { let mask = 0x10000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 40usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mPostedFlushUserFontSet ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x20000000000 as u64 ; let val = ( unit_field_val & mask ) >> 41usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mPostedFlushUserFontSet ( & mut self , val : bool ) { let mask = 0x20000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 41usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mDidFireDOMContentLoaded ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x40000000000 as u64 ; let val = ( unit_field_val & mask ) >> 42usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mDidFireDOMContentLoaded ( & mut self , val : bool ) { let mask = 0x40000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 42usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mHasScrollLinkedEffect ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x80000000000 as u64 ; let val = ( unit_field_val & mask ) >> 43usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mHasScrollLinkedEffect ( & mut self , val : bool ) { let mask = 0x80000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 43usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mFrameRequestCallbacksScheduled ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x100000000000 as u64 ; let val = ( unit_field_val & mask ) >> 44usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mFrameRequestCallbacksScheduled ( & mut self , val : bool ) { let mask = 0x100000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 44usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mIsTopLevelContentDocument ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x200000000000 as u64 ; let val = ( unit_field_val & mask ) >> 45usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mIsTopLevelContentDocument ( & mut self , val : bool ) { let mask = 0x200000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 45usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mIsContentDocument ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x400000000000 as u64 ; let val = ( unit_field_val & mask ) >> 46usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mIsContentDocument ( & mut self , val : bool ) { let mask = 0x400000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 46usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mMightHaveStaleServoData ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x800000000000 as u64 ; let val = ( unit_field_val & mask ) >> 47usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mMightHaveStaleServoData ( & mut self , val : bool ) { let mask = 0x800000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 47usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mDidCallBeginLoad ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x1000000000000 as u64 ; let val = ( unit_field_val & mask ) >> 48usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mDidCallBeginLoad ( & mut self , val : bool ) { let mask = 0x1000000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 48usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mBufferingCSPViolations ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x2000000000000 as u64 ; let val = ( unit_field_val & mask ) >> 49usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mBufferingCSPViolations ( & mut self , val : bool ) { let mask = 0x2000000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 49usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mAllowPaymentRequest ( & self ) -> bool { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x4000000000000 as u64 ; let val = ( unit_field_val & mask ) >> 50usize ; unsafe { :: std :: mem :: transmute ( val as u8 ) } } # [ inline ] pub fn set_mAllowPaymentRequest ( & mut self , val : bool ) { let mask = 0x4000000000000 as u64 ; let val = val as u8 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 50usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn mIsScopedStyleEnabled ( & self ) -> :: std :: os :: raw :: c_uint { let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; let mask = 0x18000000000000 as u64 ; let val = ( unit_field_val & mask ) >> 51usize ; unsafe { :: std :: mem :: transmute ( val as u32 ) } } # [ inline ] pub fn set_mIsScopedStyleEnabled ( & mut self , val : :: std :: os :: raw :: c_uint ) { let mask = 0x18000000000000 as u64 ; let val = val as u32 as u64 ; let mut unit_field_val : u64 = unsafe { :: std :: mem :: uninitialized ( ) } ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & self . _bitfield_1 as * const _ as * const u8 , & mut unit_field_val as * mut u64 as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) } ; unit_field_val &= ! mask ; unit_field_val |= ( val << 51usize ) & mask ; unsafe { :: std :: ptr :: copy_nonoverlapping ( & unit_field_val as * const _ as * const u8 , & mut self . _bitfield_1 as * mut _ as * mut u8 , :: std :: mem :: size_of :: < u64 > ( ) , ) ; } } # [ inline ] pub fn new_bitfield_1 ( mBidiEnabled : bool , mMathMLEnabled : bool , mIsInitialDocumentInWindow : bool , mIgnoreDocGroupMismatches : bool , mLoadedAsData : bool , mLoadedAsInteractiveData : bool , mMayStartLayout : bool , mHaveFiredTitleChange : bool , mIsShowing : bool , mVisible : bool , mHasReferrerPolicyCSP : bool , mRemovedFromDocShell : bool , mAllowDNSPrefetch : bool , mIsStaticDocument : bool , mCreatingStaticClone : bool , mInUnlinkOrDeletion : bool , mHasHadScriptHandlingObject : bool , mIsBeingUsedAsImage : bool , mIsSyntheticDocument : bool , mHasLinksToUpdate : bool , mHasLinksToUpdateRunnable : bool , mMayHaveDOMMutationObservers : bool , mMayHaveAnimationObservers : bool , mHasMixedActiveContentLoaded : bool , mHasMixedActiveContentBlocked : bool , mHasMixedDisplayContentLoaded : bool , mHasMixedDisplayContentBlocked : bool , mHasMixedContentObjectSubrequest : bool , mHasCSP : bool , mHasUnsafeEvalCSP : bool , mHasUnsafeInlineCSP : bool , mHasTrackingContentBlocked : bool , mHasTrackingContentLoaded : bool , mBFCacheDisallowed : bool , mHasHadDefaultView : bool , mStyleSheetChangeEventsEnabled : bool , mIsSrcdocDocument : bool , mDidDocumentOpen : bool , mHasDisplayDocument : bool , mFontFaceSetDirty : bool , mGetUserFontSetCalled : bool , mPostedFlushUserFontSet : bool , mDidFireDOMContentLoaded : bool , mHasScrollLinkedEffect : bool , mFrameRequestCallbacksScheduled : bool , mIsTopLevelContentDocument : bool , mIsContentDocument : bool , mMightHaveStaleServoData : bool , mDidCallBeginLoad : bool , mBufferingCSPViolations : bool , mAllowPaymentRequest : bool , mIsScopedStyleEnabled : :: std :: os :: raw :: c_uint ) -> u64 { ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( ( 0 | ( ( mBidiEnabled as u8 as u64 ) << 0usize ) & ( 0x1 as u64 ) ) | ( ( mMathMLEnabled as u8 as u64 ) << 1usize ) & ( 0x2 as u64 ) ) | ( ( mIsInitialDocumentInWindow as u8 as u64 ) << 2usize ) & ( 0x4 as u64 ) ) | ( ( mIgnoreDocGroupMismatches as u8 as u64 ) << 3usize ) & ( 0x8 as u64 ) ) | ( ( mLoadedAsData as u8 as u64 ) << 4usize ) & ( 0x10 as u64 ) ) | ( ( mLoadedAsInteractiveData as u8 as u64 ) << 5usize ) & ( 0x20 as u64 ) ) | ( ( mMayStartLayout as u8 as u64 ) << 6usize ) & ( 0x40 as u64 ) ) | ( ( mHaveFiredTitleChange as u8 as u64 ) << 7usize ) & ( 0x80 as u64 ) ) | ( ( mIsShowing as u8 as u64 ) << 8usize ) & ( 0x100 as u64 ) ) | ( ( mVisible as u8 as u64 ) << 9usize ) & ( 0x200 as u64 ) ) | ( ( mHasReferrerPolicyCSP as u8 as u64 ) << 10usize ) & ( 0x400 as u64 ) ) | ( ( mRemovedFromDocShell as u8 as u64 ) << 11usize ) & ( 0x800 as u64 ) ) | ( ( mAllowDNSPrefetch as u8 as u64 ) << 12usize ) & ( 0x1000 as u64 ) ) | ( ( mIsStaticDocument as u8 as u64 ) << 13usize ) & ( 0x2000 as u64 ) ) | ( ( mCreatingStaticClone as u8 as u64 ) << 14usize ) & ( 0x4000 as u64 ) ) | ( ( mInUnlinkOrDeletion as u8 as u64 ) << 15usize ) & ( 0x8000 as u64 ) ) | ( ( mHasHadScriptHandlingObject as u8 as u64 ) << 16usize ) & ( 0x10000 as u64 ) ) | ( ( mIsBeingUsedAsImage as u8 as u64 ) << 17usize ) & ( 0x20000 as u64 ) ) | ( ( mIsSyntheticDocument as u8 as u64 ) << 18usize ) & ( 0x40000 as u64 ) ) | ( ( mHasLinksToUpdate as u8 as u64 ) << 19usize ) & ( 0x80000 as u64 ) ) | ( ( mHasLinksToUpdateRunnable as u8 as u64 ) << 20usize ) & ( 0x100000 as u64 ) ) | ( ( mMayHaveDOMMutationObservers as u8 as u64 ) << 21usize ) & ( 0x200000 as u64 ) ) | ( ( mMayHaveAnimationObservers as u8 as u64 ) << 22usize ) & ( 0x400000 as u64 ) ) | ( ( mHasMixedActiveContentLoaded as u8 as u64 ) << 23usize ) & ( 0x800000 as u64 ) ) | ( ( mHasMixedActiveContentBlocked as u8 as u64 ) << 24usize ) & ( 0x1000000 as u64 ) ) | ( ( mHasMixedDisplayContentLoaded as u8 as u64 ) << 25usize ) & ( 0x2000000 as u64 ) ) | ( ( mHasMixedDisplayContentBlocked as u8 as u64 ) << 26usize ) & ( 0x4000000 as u64 ) ) | ( ( mHasMixedContentObjectSubrequest as u8 as u64 ) << 27usize ) & ( 0x8000000 as u64 ) ) | ( ( mHasCSP as u8 as u64 ) << 28usize ) & ( 0x10000000 as u64 ) ) | ( ( mHasUnsafeEvalCSP as u8 as u64 ) << 29usize ) & ( 0x20000000 as u64 ) ) | ( ( mHasUnsafeInlineCSP as u8 as u64 ) << 30usize ) & ( 0x40000000 as u64 ) ) | ( ( mHasTrackingContentBlocked as u8 as u64 ) << 31usize ) & ( 0x80000000 as u64 ) ) | ( ( mHasTrackingContentLoaded as u8 as u64 ) << 32usize ) & ( 0x100000000 as u64 ) ) | ( ( mBFCacheDisallowed as u8 as u64 ) << 33usize ) & ( 0x200000000 as u64 ) ) | ( ( mHasHadDefaultView as u8 as u64 ) << 34usize ) & ( 0x400000000 as u64 ) ) | ( ( mStyleSheetChangeEventsEnabled as u8 as u64 ) << 35usize ) & ( 0x800000000 as u64 ) ) | ( ( mIsSrcdocDocument as u8 as u64 ) << 36usize ) & ( 0x1000000000 as u64 ) ) | ( ( mDidDocumentOpen as u8 as u64 ) << 37usize ) & ( 0x2000000000 as u64 ) ) | ( ( mHasDisplayDocument as u8 as u64 ) << 38usize ) & ( 0x4000000000 as u64 ) ) | ( ( mFontFaceSetDirty as u8 as u64 ) << 39usize ) & ( 0x8000000000 as u64 ) ) | ( ( mGetUserFontSetCalled as u8 as u64 ) << 40usize ) & ( 0x10000000000 as u64 ) ) | ( ( mPostedFlushUserFontSet as u8 as u64 ) << 41usize ) & ( 0x20000000000 as u64 ) ) | ( ( mDidFireDOMContentLoaded as u8 as u64 ) << 42usize ) & ( 0x40000000000 as u64 ) ) | ( ( mHasScrollLinkedEffect as u8 as u64 ) << 43usize ) & ( 0x80000000000 as u64 ) ) | ( ( mFrameRequestCallbacksScheduled as u8 as u64 ) << 44usize ) & ( 0x100000000000 as u64 ) ) | ( ( mIsTopLevelContentDocument as u8 as u64 ) << 45usize ) & ( 0x200000000000 as u64 ) ) | ( ( mIsContentDocument as u8 as u64 ) << 46usize ) & ( 0x400000000000 as u64 ) ) | ( ( mMightHaveStaleServoData as u8 as u64 ) << 47usize ) & ( 0x800000000000 as u64 ) ) | ( ( mDidCallBeginLoad as u8 as u64 ) << 48usize ) & ( 0x1000000000000 as u64 ) ) | ( ( mBufferingCSPViolations as u8 as u64 ) << 49usize ) & ( 0x2000000000000 as u64 ) ) | ( ( mAllowPaymentRequest as u8 as u64 ) << 50usize ) & ( 0x4000000000000 as u64 ) ) | ( ( mIsScopedStyleEnabled as u32 as u64 ) << 51usize ) & ( 0x18000000000000 as u64 ) ) } } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsBidi { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsIPrintSettings { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsITheme { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct gfxTextPerfMetrics { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsTransitionManager { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsAnimationManager { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct nsDeviceContext { _unused : [ u8 ; 0 ] } # [ repr ( C ) ] # [ derive ( Debug , Copy , Clone ) ] pub struct gfxMissingFontRecorder { _unused : [ u8 ; 0 ] } pub const kPresContext_DefaultVariableFont_ID : u8 = 0 ; pub const kPresContext_DefaultFixedFont_ID : u8 = 1 ; # [ repr ( C ) ] pub struct nsPresContext { pub _base : root :: nsISupports , pub _base_1 : u64 , pub mRefCnt : root :: nsCycleCollectingAutoRefCnt , pub mType : root :: nsPresContext_nsPresContextType , pub mShell : * mut root :: nsIPresShell , pub mDocument : root :: nsCOMPtr , pub mDeviceContext : root :: RefPtr < root :: nsDeviceContext > , pub mEventManager : root :: RefPtr < root :: mozilla :: EventStateManager > , pub mRefreshDriver : root :: RefPtr < root :: nsRefreshDriver > , pub mEffectCompositor : root :: RefPtr < root :: mozilla :: EffectCompositor > , pub mTransitionManager : root :: RefPtr < root :: nsTransitionManager > , pub mAnimationManager : root :: RefPtr < root :: nsAnimationManager > , pub mRestyleManager : root :: RefPtr < root :: mozilla :: RestyleManager > , pub mCounterStyleManager : root :: RefPtr < root :: mozilla :: CounterStyleManager > , pub mMedium : * mut root :: nsAtom , pub mMediaEmulated : root :: RefPtr < root :: nsAtom > , pub mFontFeatureValuesLookup : root :: RefPtr < root :: gfxFontFeatureValueSet > , pub mLinkHandler : * mut root :: nsILinkHandler , pub mLanguage : root :: RefPtr < root :: nsAtom > , pub mInflationDisabledForShrinkWrap : bool , pub mContainer : u64 , pub mBaseMinFontSize : i32 , pub mSystemFontScale : f32 , pub mTextZoom : f32 , pub mEffectiveTextZoom : f32 , pub mFullZoom : f32 , pub mOverrideDPPX : f32 , pub mLastFontInflationScreenSize : root :: gfxSize , pub mCurAppUnitsPerDevPixel : i32 , pub mAutoQualityMinFontSizePixelsPref : i32 , pub mTheme : root :: nsCOMPtr , pub mLangService : * mut root :: nsLanguageAtomService , pub mPrintSettings : root :: nsCOMPtr , pub mPrefChangedTimer : root :: nsCOMPtr , pub mBidiEngine : root :: mozilla :: UniquePtr < root :: nsBidi > , pub mTransactions : [ u64 ; 10usize ] , pub mTextPerf : root :: nsAutoPtr < root :: gfxTextPerfMetrics > , pub mMissingFonts : root :: nsAutoPtr < root :: gfxMissingFontRecorder > , pub mVisibleArea : root :: nsRect , pub mLastResizeEventVisibleArea : root :: nsRect , pub mPageSize : root :: nsSize , pub mPageScale : f32 , pub mPPScale : f32 , pub mDefaultColor : root :: nscolor , pub mBackgroundColor : root :: nscolor , pub mLinkColor : root :: nscolor , pub mActiveLinkColor : root :: nscolor , pub mVisitedLinkColor : root :: nscolor , pub mFocusBackgroundColor : root :: nscolor , pub mFocusTextColor : root :: nscolor , pub mBodyTextColor : root :: nscolor , pub mViewportScrollbarOverrideElement : * mut root :: mozilla :: dom :: Element , pub mViewportStyleScrollbar : root :: nsPresContext_ScrollbarStyles , pub mFocusRingWidth : u8 , pub mExistThrottledUpdates : bool , pub mImageAnimationMode : u16 , pub mImageAnimationModePref : u16 , pub mLangGroupFontPrefs : root :: nsPresContext_LangGroupFontPrefs , pub mFontGroupCacheDirty : bool , pub mLanguagesUsed : [ u64 ; 4usize ] , pub mBorderWidthTable : [ root :: nscoord ; 3usize ] , pub mInterruptChecksToSkip : u32 , pub mElementsRestyled : u64 , pub mFramesConstructed : u64 , pub mFramesReflowed : u64 , pub mReflowStartTime : root :: mozilla :: TimeStamp , pub mFirstNonBlankPaintTime : root :: mozilla :: TimeStamp , pub mFirstClickTime : root :: mozilla :: TimeStamp , pub mFirstKeyTime : root :: mozilla :: TimeStamp , pub mFirstMouseMoveTime : root :: mozilla :: TimeStamp , pub mFirstScrollTime : root :: mozilla :: TimeStamp , pub mInteractionTimeEnabled : bool , pub mLastStyleUpdateForAllAnimations : root :: mozilla :: TimeStamp , pub mTelemetryScrollLastY : root :: nscoord , pub mTelemetryScrollMaxY : root :: nscoord , pub mTelemetryScrollTotalY : root :: nscoord , pub _bitfield_1 : [ u8 ; 6usize ] , pub __bindgen_padding_0 : [ u16 ; 3usize ] , } pub type nsPresContext_Encoding = root :: mozilla :: Encoding ; pub type nsPresContext_NotNull < T > = root :: mozilla :: NotNull < T > ; pub type nsPresContext_LangGroupFontPrefs = root :: mozilla :: LangGroupFontPrefs ; pub type nsPresContext_ScrollbarStyles = root :: mozilla :: ScrollbarStyles ; pub type nsPresContext_StaticPresData = root :: mozilla :: StaticPresData ; pub type nsPresContext_HasThreadSafeRefCnt = root :: mozilla :: FalseType ; # [ repr ( C ) ] # [ derive ( Debug , Copy ) ] pub struct nsPresContext_cycleCollection { pub _base : root :: nsXPCOMCycleCollectionParticipant , } # [ test ] fn bindgen_test_layout_nsPresContext_cycleCollection ( ) { assert_eq ! ( :: std :: mem :: size_of :: < nsPresContext_cycleCollection > ( ) , 16usize , concat ! ( "Size of: " , stringify ! ( nsPresContext_cycleCollection ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < nsPresContext_cycleCollection > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( nsPresContext_cycleCollection ) ) ) ; } impl Clone for nsPresContext_cycleCollection { fn clone ( & self ) -> Self { * self } } pub const nsPresContext_nsPresContextType_eContext_Galley : root :: nsPresContext_nsPresContextType = 0 ; pub const nsPresContext_nsPresContextType_eContext_PrintPreview : root :: nsPresContext_nsPresContextType = 1 ; pub const nsPresContext_nsPresContextType_eContext_Print : root :: nsPresContext_nsPresContextType = 2 ; pub const nsPresContext_nsPresContextType_eContext_PageLayout : root :: nsPresContext_nsPresContextType = 3 ; pub type nsPresContext_nsPresContextType = :: std :: os :: raw :: c_uint ; pub const nsPresContext_InteractionType_eClickInteraction : root :: nsPresContext_InteractionType = 0 ; pub const nsPresContext_InteractionType_eKeyInteraction : root :: nsPresContext_InteractionType = 1 ; pub const nsPresContext_InteractionType_eMouseMoveInteraction : root :: nsPresContext_InteractionType = 2 ; pub const nsPresContext_InteractionType_eScrollInteraction : root :: nsPresContext_InteractionType = 3 ; pub type nsPresContext_InteractionType = u32 ; /// A class that can be used to temporarily disable reflow interruption. # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct nsPresContext_InterruptPreventer { pub mCtx : * mut root :: nsPresContext , pub mInterruptsEnabled : bool , pub mHasPendingInterrupt : bool , } # [ test ] fn bindgen_test_layout_nsPresContext_InterruptPreventer ( ) { assert_eq ! ( :: std :: mem :: size_of :: < nsPresContext_InterruptPreventer > ( ) , 16usize , concat ! ( "Size of: " , stringify ! ( nsPresContext_InterruptPreventer ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < nsPresContext_InterruptPreventer > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( nsPresContext_InterruptPreventer ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsPresContext_InterruptPreventer ) ) . mCtx as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( nsPresContext_InterruptPreventer ) , "::" , stringify ! ( mCtx ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsPresContext_InterruptPreventer ) ) . mInterruptsEnabled as * const _ as usize } , 8usize , concat ! ( "Alignment of field: " , stringify ! ( nsPresContext_InterruptPreventer ) , "::" , stringify ! ( mInterruptsEnabled ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsPresContext_InterruptPreventer ) ) . mHasPendingInterrupt as * const _ as usize } , 9usize , concat ! ( "Alignment of field: " , stringify ! ( nsPresContext_InterruptPreventer ) , "::" , stringify ! ( mHasPendingInterrupt ) ) ) ; } # [ repr ( C ) ] # [ derive ( Debug ) ] pub struct nsPresContext_TransactionInvalidations { pub mTransactionId : u64 , pub mInvalidations : root :: nsTArray < root :: nsRect > , } # [ test ] fn bindgen_test_layout_nsPresContext_TransactionInvalidations ( ) { assert_eq ! ( :: std :: mem :: size_of :: < nsPresContext_TransactionInvalidations > ( ) , 16usize , concat ! ( "Size of: " , stringify ! ( nsPresContext_TransactionInvalidations ) ) ) ; assert_eq ! ( :: std :: mem :: align_of :: < nsPresContext_TransactionInvalidations > ( ) , 8usize , concat ! ( "Alignment of " , stringify ! ( nsPresContext_TransactionInvalidations ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsPresContext_TransactionInvalidations ) ) . mTransactionId as * const _ as usize } , 0usize , concat ! ( "Alignment of field: " , stringify ! ( nsPresContext_TransactionInvalidations ) , "::" , stringify ! ( mTransactionId ) ) ) ; assert_eq ! ( unsafe { & ( * ( 0 as * const nsPresContext_TransactionInvalidations ) ) . mInvalidations as * const _ as usize } , 8usize , concat ! ( "Alignment of field: " , stringify ! ( nsPresContext_TransactionInvalidations ) , "::" , stringify ! ( mInvalidations ) ) ) ; } extern "C" { # [ link_name = "\u{1}_ZN13nsPresContext21_cycleCollectorGlobalE" ] diff --git a/servo/components/style/properties/gecko.mako.rs b/servo/components/style/properties/gecko.mako.rs index da74f191e5e7..dd868c5d2720 100644 --- a/servo/components/style/properties/gecko.mako.rs +++ b/servo/components/style/properties/gecko.mako.rs @@ -4072,7 +4072,7 @@ fn static_assert() { fill_fields += " mMaskMode mComposite" %> pub fn fill_arrays(&mut self) { - use gecko_bindings::bindings::Gecko_FillAll${shorthand.title()}Lists; + use gecko_bindings::bindings::Gecko_FillAllImageLayers; use std::cmp; let mut max_len = 1; % for member in fill_fields.split(): @@ -4081,7 +4081,7 @@ fn static_assert() { unsafe { // While we could do this manually, we'd need to also manually // run all the copy constructors, so we just delegate to gecko - Gecko_FillAll${shorthand.title()}Lists(&mut self.gecko.${image_layers_field}, max_len); + Gecko_FillAllImageLayers(&mut self.gecko.${image_layers_field}, max_len); } } From d8a0eb82deef1866c2e0a1529ec0ce8dbfd550c7 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Mon, 20 Nov 2017 13:09:16 +0800 Subject: [PATCH 09/78] Bug 1418899 - Part 1: Remove some unused method declarations on nsRuleNode. r=TYLin MozReview-Commit-ID: FOBOjJRJCea --HG-- extra : rebase_source : ff3bf2cccf2ec21bdbaf61c8112ee97bc3306bfe --- layout/style/nsRuleNode.h | 8 -------- 1 file changed, 8 deletions(-) diff --git a/layout/style/nsRuleNode.h b/layout/style/nsRuleNode.h index e972d88acd50..bcf255e4faa5 100644 --- a/layout/style/nsRuleNode.h +++ b/layout/style/nsRuleNode.h @@ -1069,14 +1069,6 @@ public: nsPresContext* aPresContext, nsFontSizeType aFontSizeType = eFontSize_HTML); - static nscoord FindNextSmallerFontSize(nscoord aFontSize, int32_t aBasePointSize, - nsPresContext* aPresContext, - nsFontSizeType aFontSizeType = eFontSize_HTML); - - static nscoord FindNextLargerFontSize(nscoord aFontSize, int32_t aBasePointSize, - nsPresContext* aPresContext, - nsFontSizeType aFontSizeType = eFontSize_HTML); - static uint32_t ParseFontLanguageOverride(const nsAString& aLangTag); /** From 3991f1ba0de763dcc6f41e0831583a0cac413dc0 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Mon, 20 Nov 2017 12:43:21 +0800 Subject: [PATCH 10/78] Bug 1418899 - Part 2: Move some font-related static methods out of nsRuleNode. r=TYLin MozReview-Commit-ID: 3l9L6bHr0PJ --HG-- extra : rebase_source : 4d60e21f70a0e8b7a54b009ca6f5d6c2c90a80bd --- layout/base/nsLayoutUtils.cpp | 226 ++++++++++++++++++++++++++++ layout/base/nsLayoutUtils.h | 42 ++++++ layout/style/FontFaceSet.cpp | 5 +- layout/style/ServoBindings.cpp | 18 ++- layout/style/nsRuleNode.cpp | 261 +++------------------------------ layout/style/nsRuleNode.h | 42 ------ layout/style/nsStyleUtil.cpp | 6 +- 7 files changed, 302 insertions(+), 298 deletions(-) diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index e380469f3a5a..3ad0a82ad122 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -10095,3 +10095,229 @@ nsLayoutUtils::ControlCharVisibilityDefault() ? NS_STYLE_CONTROL_CHARACTER_VISIBILITY_VISIBLE : NS_STYLE_CONTROL_CHARACTER_VISIBILITY_HIDDEN; } + +/* static */ +already_AddRefed +nsLayoutUtils::GetMetricsFor(nsPresContext* aPresContext, + bool aIsVertical, + const nsStyleFont* aStyleFont, + nscoord aFontSize, + bool aUseUserFontSet, + FlushUserFontSet aFlushUserFontSet) +{ + nsFont font = aStyleFont->mFont; + font.size = aFontSize; + gfxFont::Orientation orientation + = aIsVertical ? gfxFont::eVertical : gfxFont::eHorizontal; + nsFontMetrics::Params params; + params.language = aStyleFont->mLanguage; + params.explicitLanguage = aStyleFont->mExplicitLanguage; + params.orientation = orientation; + params.userFontSet = aUseUserFontSet + ? aPresContext->GetUserFontSet(aFlushUserFontSet == FlushUserFontSet::Yes) + : nullptr; + params.textPerf = aPresContext->GetTextPerfMetrics(); + return aPresContext->DeviceContext()->GetMetricsFor(font, params); +} + +/* static */ void +nsLayoutUtils::FixupNoneGeneric(nsFont* aFont, + const nsPresContext* aPresContext, + uint8_t aGenericFontID, + const nsFont* aDefaultVariableFont) +{ + bool useDocumentFonts = + aPresContext->GetCachedBoolPref(kPresContext_UseDocumentFonts); + if (aGenericFontID == kGenericFont_NONE || + (!useDocumentFonts && (aGenericFontID == kGenericFont_cursive || + aGenericFontID == kGenericFont_fantasy))) { + FontFamilyType defaultGeneric = + aDefaultVariableFont->fontlist.GetDefaultFontType(); + MOZ_ASSERT(aDefaultVariableFont->fontlist.IsEmpty() && + (defaultGeneric == eFamily_serif || + defaultGeneric == eFamily_sans_serif)); + if (defaultGeneric != eFamily_none) { + if (useDocumentFonts) { + aFont->fontlist.SetDefaultFontType(defaultGeneric); + } else { + // Either prioritize the first generic in the list, + // or (if there isn't one) prepend the default variable font. + if (!aFont->fontlist.PrioritizeFirstGeneric()) { + aFont->fontlist.PrependGeneric(defaultGeneric); + } + } + } + } else { + aFont->fontlist.SetDefaultFontType(eFamily_none); + } +} + +/* static */ void +nsLayoutUtils::ApplyMinFontSize(nsStyleFont* aFont, + const nsPresContext* aPresContext, + nscoord aMinFontSize) +{ + nscoord fontSize = aFont->mSize; + + // enforce the user' specified minimum font-size on the value that we expose + // (but don't change font-size:0, since that would unhide hidden text) + if (fontSize > 0) { + if (aMinFontSize < 0) { + aMinFontSize = 0; + } else { + aMinFontSize = (aMinFontSize * aFont->mMinFontSizeRatio) / 100; + } + if (fontSize < aMinFontSize && !aPresContext->IsChrome()) { + // override the minimum font-size constraint + fontSize = aMinFontSize; + } + } + aFont->mFont.size = fontSize; +} + +/* static */ void +nsLayoutUtils::ComputeSystemFont(nsFont* aSystemFont, LookAndFeel::FontID aFontID, + const nsPresContext* aPresContext, + const nsFont* aDefaultVariableFont) +{ + gfxFontStyle fontStyle; + float devPerCSS = + (float)nsPresContext::AppUnitsPerCSSPixel() / + aPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom(); + nsAutoString systemFontName; + if (LookAndFeel::GetFont(aFontID, systemFontName, fontStyle, devPerCSS)) { + systemFontName.Trim("\"'"); + aSystemFont->fontlist = FontFamilyList(systemFontName, eUnquotedName); + aSystemFont->fontlist.SetDefaultFontType(eFamily_none); + aSystemFont->style = fontStyle.style; + aSystemFont->systemFont = fontStyle.systemFont; + aSystemFont->weight = fontStyle.weight; + aSystemFont->stretch = fontStyle.stretch; + aSystemFont->size = + NSFloatPixelsToAppUnits(fontStyle.size, + aPresContext->DeviceContext()-> + AppUnitsPerDevPixelAtUnitFullZoom()); + //aSystemFont->langGroup = fontStyle.langGroup; + aSystemFont->sizeAdjust = fontStyle.sizeAdjust; + +#ifdef XP_WIN + // XXXldb This platform-specific stuff should be in the + // LookAndFeel implementation, not here. + // XXXzw Should we even still *have* this code? It looks to be making + // old, probably obsolete assumptions. + + if (aFontID == LookAndFeel::eFont_Field || + aFontID == LookAndFeel::eFont_Button || + aFontID == LookAndFeel::eFont_List) { + // As far as I can tell the system default fonts and sizes + // on MS-Windows for Buttons, Listboxes/Comboxes and Text Fields are + // all pre-determined and cannot be changed by either the control panel + // or programmatically. + // Fields (text fields) + // Button and Selects (listboxes/comboboxes) + // We use whatever font is defined by the system. Which it appears + // (and the assumption is) it is always a proportional font. Then we + // always use 2 points smaller than what the browser has defined as + // the default proportional font. + // Assumption: system defined font is proportional + aSystemFont->size = + std::max(aDefaultVariableFont->size - + nsPresContext::CSSPointsToAppUnits(2), 0); + } +#endif + } +} + +static inline void +AssertValidFontTag(const nsString& aString) +{ + // To be valid as a font feature tag, a string MUST be: + MOZ_ASSERT(aString.Length() == 4 && // (1) exactly 4 chars long + NS_IsAscii(aString.BeginReading()) && // (2) entirely ASCII + isprint(aString[0]) && // (3) all printable chars + isprint(aString[1]) && + isprint(aString[2]) && + isprint(aString[3])); +} + +/* static */ void +nsLayoutUtils::ComputeFontFeatures(const nsCSSValuePairList *aFeaturesList, + nsTArray& aFeatureSettings) +{ + aFeatureSettings.Clear(); + for (const nsCSSValuePairList* p = aFeaturesList; p; p = p->mNext) { + gfxFontFeature feat; + + MOZ_ASSERT(aFeaturesList->mXValue.GetUnit() == eCSSUnit_String, + "unexpected value unit"); + + // tag is a 4-byte ASCII sequence + nsAutoString tag; + p->mXValue.GetStringValue(tag); + AssertValidFontTag(tag); + if (tag.Length() != 4) { + continue; + } + // parsing validates that these are ASCII chars + // tags are always big-endian + feat.mTag = (tag[0] << 24) | (tag[1] << 16) | (tag[2] << 8) | tag[3]; + + // value + NS_ASSERTION(p->mYValue.GetUnit() == eCSSUnit_Integer, + "should have found an integer unit"); + feat.mValue = p->mYValue.GetIntValue(); + + aFeatureSettings.AppendElement(feat); + } +} + +/* static */ void +nsLayoutUtils::ComputeFontVariations(const nsCSSValuePairList* aVariationsList, + nsTArray& aVariationSettings) +{ + aVariationSettings.Clear(); + for (const nsCSSValuePairList* p = aVariationsList; p; p = p->mNext) { + gfxFontVariation var; + + MOZ_ASSERT(aVariationsList->mXValue.GetUnit() == eCSSUnit_String, + "unexpected value unit"); + + // tag is a 4-byte ASCII sequence + nsAutoString tag; + p->mXValue.GetStringValue(tag); + AssertValidFontTag(tag); + if (tag.Length() != 4) { + continue; + } + // parsing validates that these are ASCII chars + // tags are always big-endian + var.mTag = (tag[0] << 24) | (tag[1] << 16) | (tag[2] << 8) | tag[3]; + + // value + NS_ASSERTION(p->mYValue.GetUnit() == eCSSUnit_Number, + "should have found a number unit"); + var.mValue = p->mYValue.GetFloatValue(); + + aVariationSettings.AppendElement(var); + } +} + +/* static */ uint32_t +nsLayoutUtils::ParseFontLanguageOverride(const nsAString& aLangTag) +{ + if (!aLangTag.Length() || aLangTag.Length() > 4) { + return NO_FONT_LANGUAGE_OVERRIDE; + } + uint32_t index, result = 0; + for (index = 0; index < aLangTag.Length(); ++index) { + char16_t ch = aLangTag[index]; + if (!nsCRT::IsAscii(ch)) { // valid tags are pure ASCII + return NO_FONT_LANGUAGE_OVERRIDE; + } + result = (result << 8) + ch; + } + while (index++ < 4) { + result = (result << 8) + 0x20; + } + return result; +} diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index dee97d9c621d..743cbce561d6 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -3054,6 +3054,48 @@ public: // from preferences. static uint8_t ControlCharVisibilityDefault(); + enum class FlushUserFontSet { + Yes, + No, + }; + + static already_AddRefed GetMetricsFor(nsPresContext* aPresContext, + bool aIsVertical, + const nsStyleFont* aStyleFont, + nscoord aFontSize, + bool aUseUserFontSet, + FlushUserFontSet aFlushUserFontSet); + + /** + * Appropriately add the correct font if we are using DocumentFonts or + * overriding for XUL + */ + static void FixupNoneGeneric(nsFont* aFont, + const nsPresContext* aPresContext, + uint8_t aGenericFontID, + const nsFont* aDefaultVariableFont); + + /** + * For an nsStyleFont with mSize set, apply minimum font size constraints + * from preferences, as well as -moz-min-font-size-ratio. + */ + static void ApplyMinFontSize(nsStyleFont* aFont, + const nsPresContext* aPresContext, + nscoord aMinFontSize); + + static void ComputeSystemFont(nsFont* aSystemFont, + mozilla::LookAndFeel::FontID aFontID, + const nsPresContext* aPresContext, + const nsFont* aDefaultVariableFont); + + static void ComputeFontFeatures(const nsCSSValuePairList* aFeaturesList, + nsTArray& aFeatureSettings); + + static void ComputeFontVariations(const nsCSSValuePairList* aVariationsList, + nsTArray& aVariationSettings); + + static uint32_t ParseFontLanguageOverride(const nsAString& aLangTag); + private: static uint32_t sFontSizeInflationEmPerLine; static uint32_t sFontSizeInflationMinTwips; diff --git a/layout/style/FontFaceSet.cpp b/layout/style/FontFaceSet.cpp index e3601bb0abf9..c0769c4952fc 100644 --- a/layout/style/FontFaceSet.cpp +++ b/layout/style/FontFaceSet.cpp @@ -43,6 +43,7 @@ #include "nsNetUtil.h" #include "nsIProtocolHandler.h" #include "nsIInputStream.h" +#include "nsLayoutUtils.h" #include "nsPresContext.h" #include "nsPrintfCString.h" #include "nsStyleSet.h" @@ -1067,7 +1068,7 @@ FontFaceSet::FindOrCreateUserFontEntryFromFontFace(const nsAString& aFamilyName, if (unit == eCSSUnit_Normal) { // empty list of features } else if (unit == eCSSUnit_PairList || unit == eCSSUnit_PairListDep) { - nsRuleNode::ComputeFontFeatures(val.GetPairListValue(), featureSettings); + nsLayoutUtils::ComputeFontFeatures(val.GetPairListValue(), featureSettings); } else { NS_ASSERTION(unit == eCSSUnit_Null, "@font-face font-feature-settings has unexpected unit"); @@ -1081,7 +1082,7 @@ FontFaceSet::FindOrCreateUserFontEntryFromFontFace(const nsAString& aFamilyName, } else if (unit == eCSSUnit_String) { nsString stringValue; val.GetStringValue(stringValue); - languageOverride = nsRuleNode::ParseFontLanguageOverride(stringValue); + languageOverride = nsLayoutUtils::ParseFontLanguageOverride(stringValue); } else { NS_ASSERTION(unit == eCSSUnit_Null, "@font-face font-language-override has unexpected unit"); diff --git a/layout/style/ServoBindings.cpp b/layout/style/ServoBindings.cpp index cfbc51a8c6b4..5020c4f23dea 100644 --- a/layout/style/ServoBindings.cpp +++ b/layout/style/ServoBindings.cpp @@ -1340,7 +1340,8 @@ Gecko_nsFont_InitSystem(nsFont* aDest, int32_t aFontId, LookAndFeel::FontID fontID = static_cast(aFontId); AutoWriteLock guard(*sServoFFILock); - nsRuleNode::ComputeSystemFont(aDest, fontID, aPresContext, defaultVariableFont); + nsLayoutUtils::ComputeSystemFont(aDest, fontID, aPresContext, + defaultVariableFont); } void @@ -2357,10 +2358,11 @@ void Gecko_nsStyleFont_FixupNoneGeneric(nsStyleFont* aFont, RawGeckoPresContextBorrowed aPresContext) { - const nsFont* defaultVariableFont = ThreadSafeGetDefaultFontHelper(aPresContext, aFont->mLanguage, - kPresContext_DefaultVariableFont_ID); - nsRuleNode::FixupNoneGeneric(&aFont->mFont, aPresContext, - aFont->mGenericID, defaultVariableFont); + const nsFont* defaultVariableFont = + ThreadSafeGetDefaultFontHelper(aPresContext, aFont->mLanguage, + kPresContext_DefaultVariableFont_ID); + nsLayoutUtils::FixupNoneGeneric(&aFont->mFont, aPresContext, + aFont->mGenericID, defaultVariableFont); } void @@ -2397,7 +2399,7 @@ Gecko_nsStyleFont_FixupMinFontSize(nsStyleFont* aFont, minFontSize = aPresContext->MinFontSize(aFont->mLanguage, nullptr); } - nsRuleNode::ApplyMinFontSize(aFont, aPresContext, minFontSize); + nsLayoutUtils::ApplyMinFontSize(aFont, aPresContext, minFontSize); } void @@ -2513,9 +2515,9 @@ Gecko_GetFontMetrics(RawGeckoPresContextBorrowed aPresContext, nsPresContext* presContext = const_cast(aPresContext); presContext->SetUsesExChUnits(true); - RefPtr fm = nsRuleNode::GetMetricsFor( + RefPtr fm = nsLayoutUtils::GetMetricsFor( presContext, aIsVertical, aFont, aFontSize, aUseUserFontSet, - nsRuleNode::FlushUserFontSet::No); + nsLayoutUtils::FlushUserFontSet::No); ret.mXSize = fm->XHeight(); gfxFloat zeroWidth = fm->GetThebesFontGroup()->GetFirstValidFont()-> diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 8d30ce26a140..d1acb233cf34 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -371,30 +371,6 @@ static inline nscoord ScaleViewportCoordTrunc(const nsCSSValue& aValue, aViewportSize / 100.0f); } -/* static */ -already_AddRefed -nsRuleNode::GetMetricsFor(nsPresContext* aPresContext, - bool aIsVertical, - const nsStyleFont* aStyleFont, - nscoord aFontSize, - bool aUseUserFontSet, - FlushUserFontSet aFlushUserFontSet) -{ - nsFont font = aStyleFont->mFont; - font.size = aFontSize; - gfxFont::Orientation orientation - = aIsVertical ? gfxFont::eVertical : gfxFont::eHorizontal; - nsFontMetrics::Params params; - params.language = aStyleFont->mLanguage; - params.explicitLanguage = aStyleFont->mExplicitLanguage; - params.orientation = orientation; - params.userFontSet = aUseUserFontSet - ? aPresContext->GetUserFontSet(aFlushUserFontSet == FlushUserFontSet::Yes) - : nullptr; - params.textPerf = aPresContext->GetTextPerfMetrics(); - return aPresContext->DeviceContext()->GetMetricsFor(font, params); -} - /* static */ already_AddRefed nsRuleNode::GetMetricsFor(nsPresContext* aPresContext, @@ -410,66 +386,9 @@ nsRuleNode::GetMetricsFor(nsPresContext* aPresContext, isVertical = true; } } - return nsRuleNode::GetMetricsFor( + return nsLayoutUtils::GetMetricsFor( aPresContext, isVertical, aStyleFont, aFontSize, aUseUserFontSet, - FlushUserFontSet::Yes); -} - -/* static */ -void -nsRuleNode::FixupNoneGeneric(nsFont* aFont, - const nsPresContext* aPresContext, - uint8_t aGenericFontID, - const nsFont* aDefaultVariableFont) -{ - bool useDocumentFonts = - aPresContext->GetCachedBoolPref(kPresContext_UseDocumentFonts); - if (aGenericFontID == kGenericFont_NONE || - (!useDocumentFonts && (aGenericFontID == kGenericFont_cursive || - aGenericFontID == kGenericFont_fantasy))) { - FontFamilyType defaultGeneric = - aDefaultVariableFont->fontlist.GetDefaultFontType(); - MOZ_ASSERT(aDefaultVariableFont->fontlist.IsEmpty() && - (defaultGeneric == eFamily_serif || - defaultGeneric == eFamily_sans_serif)); - if (defaultGeneric != eFamily_none) { - if (useDocumentFonts) { - aFont->fontlist.SetDefaultFontType(defaultGeneric); - } else { - // Either prioritize the first generic in the list, - // or (if there isn't one) prepend the default variable font. - if (!aFont->fontlist.PrioritizeFirstGeneric()) { - aFont->fontlist.PrependGeneric(defaultGeneric); - } - } - } - } else { - aFont->fontlist.SetDefaultFontType(eFamily_none); - } -} - -/* static */ -void -nsRuleNode::ApplyMinFontSize(nsStyleFont* aFont, - const nsPresContext* aPresContext, - nscoord aMinFontSize) -{ - nscoord fontSize = aFont->mSize; - - // enforce the user' specified minimum font-size on the value that we expose - // (but don't change font-size:0, since that would unhide hidden text) - if (fontSize > 0) { - if (aMinFontSize < 0) { - aMinFontSize = 0; - } else { - aMinFontSize = (aMinFontSize * aFont->mMinFontSizeRatio) / 100; - } - if (fontSize < aMinFontSize && !aPresContext->IsChrome()) { - // override the minimum font-size constraint - fontSize = aMinFontSize; - } - } - aFont->mFont.size = fontSize; + nsLayoutUtils::FlushUserFontSet::Yes); } static nsSize CalcViewportUnitsScale(nsPresContext* aPresContext) @@ -3537,59 +3456,6 @@ static int8_t ClampTo8Bit(int32_t aValue) { return int8_t(aValue); } -/* static */ void -nsRuleNode::ComputeSystemFont(nsFont* aSystemFont, LookAndFeel::FontID aFontID, - const nsPresContext* aPresContext, - const nsFont* aDefaultVariableFont) -{ - gfxFontStyle fontStyle; - float devPerCSS = - (float)nsPresContext::AppUnitsPerCSSPixel() / - aPresContext->DeviceContext()->AppUnitsPerDevPixelAtUnitFullZoom(); - nsAutoString systemFontName; - if (LookAndFeel::GetFont(aFontID, systemFontName, fontStyle, devPerCSS)) { - systemFontName.Trim("\"'"); - aSystemFont->fontlist = FontFamilyList(systemFontName, eUnquotedName); - aSystemFont->fontlist.SetDefaultFontType(eFamily_none); - aSystemFont->style = fontStyle.style; - aSystemFont->systemFont = fontStyle.systemFont; - aSystemFont->weight = fontStyle.weight; - aSystemFont->stretch = fontStyle.stretch; - aSystemFont->size = - NSFloatPixelsToAppUnits(fontStyle.size, - aPresContext->DeviceContext()-> - AppUnitsPerDevPixelAtUnitFullZoom()); - //aSystemFont->langGroup = fontStyle.langGroup; - aSystemFont->sizeAdjust = fontStyle.sizeAdjust; - -#ifdef XP_WIN - // XXXldb This platform-specific stuff should be in the - // LookAndFeel implementation, not here. - // XXXzw Should we even still *have* this code? It looks to be making - // old, probably obsolete assumptions. - - if (aFontID == LookAndFeel::eFont_Field || - aFontID == LookAndFeel::eFont_Button || - aFontID == LookAndFeel::eFont_List) { - // As far as I can tell the system default fonts and sizes - // on MS-Windows for Buttons, Listboxes/Comboxes and Text Fields are - // all pre-determined and cannot be changed by either the control panel - // or programmatically. - // Fields (text fields) - // Button and Selects (listboxes/comboboxes) - // We use whatever font is defined by the system. Which it appears - // (and the assumption is) it is always a proportional font. Then we - // always use 2 points smaller than what the browser has defined as - // the default proportional font. - // Assumption: system defined font is proportional - aSystemFont->size = - std::max(aDefaultVariableFont->size - - nsPresContext::CSSPointsToAppUnits(2), 0); - } -#endif - } -} - /* static */ void nsRuleNode::SetFont(nsPresContext* aPresContext, GeckoStyleContext* aContext, uint8_t aGenericFontID, const nsRuleData* aRuleData, @@ -3658,8 +3524,8 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, GeckoStyleContext* aContext, lazySystemFont.emplace(*defaultVariableFont); LookAndFeel::FontID fontID = (LookAndFeel::FontID)systemFontValue->GetIntValue(); - ComputeSystemFont(lazySystemFont.ptr(), fontID, aPresContext, - defaultVariableFont); + nsLayoutUtils::ComputeSystemFont(lazySystemFont.ptr(), fontID, aPresContext, + defaultVariableFont); } const nsFont& systemFont = lazySystemFont.refOr(*defaultVariableFont); @@ -3668,8 +3534,8 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, GeckoStyleContext* aContext, case eCSSUnit_FontFamilyList: // set the correct font if we are using DocumentFonts OR we are overriding // for XUL - MJA: bug 31816 - nsRuleNode::FixupNoneGeneric(&aFont->mFont, aPresContext, - aGenericFontID, defaultVariableFont); + nsLayoutUtils::FixupNoneGeneric(&aFont->mFont, aPresContext, + aGenericFontID, defaultVariableFont); aFont->mFont.systemFont = false; // Technically this is redundant with the code below, but it's good @@ -3696,8 +3562,8 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, GeckoStyleContext* aContext, // with the default generic from defaultVariableFont, which is computed // using aFont->mLanguage above. if (aRuleData->ValueForLang()->GetUnit() != eCSSUnit_Null) { - FixupNoneGeneric(&aFont->mFont, aPresContext, aGenericFontID, - defaultVariableFont); + nsLayoutUtils::FixupNoneGeneric(&aFont->mFont, aPresContext, + aGenericFontID, defaultVariableFont); } break; case eCSSUnit_Initial: @@ -3999,8 +3865,9 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, GeckoStyleContext* aContext, case eCSSUnit_PairList: case eCSSUnit_PairListDep: - ComputeFontFeatures(featureSettingsValue->GetPairListValue(), - aFont->mFont.fontFeatureSettings); + nsLayoutUtils::ComputeFontFeatures( + featureSettingsValue->GetPairListValue(), + aFont->mFont.fontFeatureSettings); break; default: @@ -4034,8 +3901,9 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, GeckoStyleContext* aContext, case eCSSUnit_PairList: case eCSSUnit_PairListDep: - ComputeFontVariations(variationSettingsValue->GetPairListValue(), - aFont->mFont.fontVariationSettings); + nsLayoutUtils::ComputeFontVariations( + variationSettingsValue->GetPairListValue(), + aFont->mFont.fontVariationSettings); break; default: @@ -4058,7 +3926,8 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, GeckoStyleContext* aContext, } else if (eCSSUnit_String == languageOverrideValue->GetUnit()) { nsAutoString lang; languageOverrideValue->GetStringValue(lang); - aFont->mFont.languageOverride = ParseFontLanguageOverride(lang); + aFont->mFont.languageOverride = + nsLayoutUtils::ParseFontLanguageOverride(lang); } // -moz-min-font-size-ratio: percent, inherit @@ -4149,8 +4018,8 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, GeckoStyleContext* aContext, NS_ASSERTION(aFont->mScriptUnconstrainedSize <= aFont->mSize, "scriptminsize should never be making things bigger"); - nsRuleNode::ApplyMinFontSize(aFont, aPresContext, - aPresContext->MinFontSize(aFont->mLanguage)); + nsLayoutUtils::ApplyMinFontSize(aFont, aPresContext, + aPresContext->MinFontSize(aFont->mLanguage)); // font-size-adjust: number, none, inherit, initial, -moz-system-font const nsCSSValue* sizeAdjustValue = aRuleData->ValueForFontSizeAdjust(); @@ -4162,80 +4031,6 @@ nsRuleNode::SetFont(nsPresContext* aPresContext, GeckoStyleContext* aContext, SETFCT_NONE | SETFCT_UNSET_INHERIT); } -static inline void -AssertValidFontTag(const nsString& aString) -{ - // To be valid as a font feature tag, a string MUST be: - MOZ_ASSERT(aString.Length() == 4 && // (1) exactly 4 chars long - NS_IsAscii(aString.BeginReading()) && // (2) entirely ASCII - isprint(aString[0]) && // (3) all printable chars - isprint(aString[1]) && - isprint(aString[2]) && - isprint(aString[3])); -} - -/* static */ void -nsRuleNode::ComputeFontFeatures(const nsCSSValuePairList *aFeaturesList, - nsTArray& aFeatureSettings) -{ - aFeatureSettings.Clear(); - for (const nsCSSValuePairList* p = aFeaturesList; p; p = p->mNext) { - gfxFontFeature feat; - - MOZ_ASSERT(aFeaturesList->mXValue.GetUnit() == eCSSUnit_String, - "unexpected value unit"); - - // tag is a 4-byte ASCII sequence - nsAutoString tag; - p->mXValue.GetStringValue(tag); - AssertValidFontTag(tag); - if (tag.Length() != 4) { - continue; - } - // parsing validates that these are ASCII chars - // tags are always big-endian - feat.mTag = (tag[0] << 24) | (tag[1] << 16) | (tag[2] << 8) | tag[3]; - - // value - NS_ASSERTION(p->mYValue.GetUnit() == eCSSUnit_Integer, - "should have found an integer unit"); - feat.mValue = p->mYValue.GetIntValue(); - - aFeatureSettings.AppendElement(feat); - } -} - -/* static */ void -nsRuleNode::ComputeFontVariations(const nsCSSValuePairList* aVariationsList, - nsTArray& aVariationSettings) -{ - aVariationSettings.Clear(); - for (const nsCSSValuePairList* p = aVariationsList; p; p = p->mNext) { - gfxFontVariation var; - - MOZ_ASSERT(aVariationsList->mXValue.GetUnit() == eCSSUnit_String, - "unexpected value unit"); - - // tag is a 4-byte ASCII sequence - nsAutoString tag; - p->mXValue.GetStringValue(tag); - AssertValidFontTag(tag); - if (tag.Length() != 4) { - continue; - } - // parsing validates that these are ASCII chars - // tags are always big-endian - var.mTag = (tag[0] << 24) | (tag[1] << 16) | (tag[2] << 8) | tag[3]; - - // value - NS_ASSERTION(p->mYValue.GetUnit() == eCSSUnit_Number, - "should have found a number unit"); - var.mValue = p->mYValue.GetFloatValue(); - - aVariationSettings.AppendElement(var); - } -} - // This should die (bug 380915). // // SetGenericFont: @@ -4409,26 +4204,6 @@ nsRuleNode::ComputeFontData(void* aStartStruct, COMPUTE_END_INHERITED(Font, font) } -/*static*/ uint32_t -nsRuleNode::ParseFontLanguageOverride(const nsAString& aLangTag) -{ - if (!aLangTag.Length() || aLangTag.Length() > 4) { - return NO_FONT_LANGUAGE_OVERRIDE; - } - uint32_t index, result = 0; - for (index = 0; index < aLangTag.Length(); ++index) { - char16_t ch = aLangTag[index]; - if (!nsCRT::IsAscii(ch)) { // valid tags are pure ASCII - return NO_FONT_LANGUAGE_OVERRIDE; - } - result = (result << 8) + ch; - } - while (index++ < 4) { - result = (result << 8) + 0x20; - } - return result; -} - template inline uint32_t ListLength(const T* aList) { diff --git a/layout/style/nsRuleNode.h b/layout/style/nsRuleNode.h index bcf255e4faa5..13bbe47628ba 100644 --- a/layout/style/nsRuleNode.h +++ b/layout/style/nsRuleNode.h @@ -808,41 +808,12 @@ public: bool aConvertListItem = false); static void EnsureInlineDisplay(mozilla::StyleDisplay& display); - enum class FlushUserFontSet { - Yes, - No, - }; - - static already_AddRefed GetMetricsFor(nsPresContext* aPresContext, - bool aIsVertical, - const nsStyleFont* aStyleFont, - nscoord aFontSize, - bool aUseUserFontSet, - FlushUserFontSet aFlushUserFontSet); - static already_AddRefed GetMetricsFor(nsPresContext* aPresContext, nsStyleContext* aStyleContext, const nsStyleFont* aStyleFont, nscoord aFontSize, bool aUseUserFontSet); - /** - * Appropriately add the correct font if we are using DocumentFonts or - * overriding for XUL - */ - static void FixupNoneGeneric(nsFont* aFont, - const nsPresContext* aPresContext, - uint8_t aGenericFontID, - const nsFont* aDefaultVariableFont); - - /** - * For an nsStyleFont with mSize set, apply minimum font size constraints - * from preferences, as well as -moz-min-font-size-ratio. - */ - static void ApplyMinFontSize(nsStyleFont* aFont, - const nsPresContext* aPresContext, - nscoord aMinFontSize); - // Transition never returns null; on out of memory it'll just return |this|. nsRuleNode* Transition(nsIStyleRule* aRule, mozilla::SheetType aLevel, bool aIsImportantRule); @@ -1059,18 +1030,10 @@ public: return !!mStyleData.GetStyleData(aSID); } - static void ComputeFontFeatures(const nsCSSValuePairList* aFeaturesList, - nsTArray& aFeatureSettings); - - static void ComputeFontVariations(const nsCSSValuePairList* aVariationsList, - nsTArray& aVariationSettings); - static nscoord CalcFontPointSize(int32_t aHTMLSize, int32_t aBasePointSize, nsPresContext* aPresContext, nsFontSizeType aFontSizeType = eFontSize_HTML); - static uint32_t ParseFontLanguageOverride(const nsAString& aLangTag); - /** * @param aValue The color value, returned from nsCSSParser::ParseColorString * @param aPresContext Presentation context whose preferences are used @@ -1102,11 +1065,6 @@ public: static void FillAllMaskLists(nsStyleImageLayers& aLayers, uint32_t aMaxItemCount); - static void ComputeSystemFont(nsFont* aSystemFont, - mozilla::LookAndFeel::FontID aFontID, - const nsPresContext* aPresContext, - const nsFont* aDefaultVariableFont); - private: #ifdef DEBUG // non-inline helper function to allow assertions without incomplete diff --git a/layout/style/nsStyleUtil.cpp b/layout/style/nsStyleUtil.cpp index 1d01366008ca..999eb2612f3c 100644 --- a/layout/style/nsStyleUtil.cpp +++ b/layout/style/nsStyleUtil.cpp @@ -10,7 +10,6 @@ #include "nsIContent.h" #include "nsCSSProps.h" #include "nsContentUtils.h" -#include "nsRuleNode.h" #include "nsROCSSPrimitiveValue.h" #include "nsStyleStruct.h" #include "nsIContentPolicy.h" @@ -407,7 +406,7 @@ nsStyleUtil::AppendFontFeatureSettings(const nsCSSValue& aSrc, "improper value unit for font-feature-settings:"); nsTArray featureSettings; - nsRuleNode::ComputeFontFeatures(aSrc.GetPairListValue(), featureSettings); + nsLayoutUtils::ComputeFontFeatures(aSrc.GetPairListValue(), featureSettings); AppendFontFeatureSettings(featureSettings, aResult); } @@ -446,7 +445,8 @@ nsStyleUtil::AppendFontVariationSettings(const nsCSSValue& aSrc, "improper value unit for font-variation-settings:"); nsTArray variationSettings; - nsRuleNode::ComputeFontVariations(aSrc.GetPairListValue(), variationSettings); + nsLayoutUtils::ComputeFontVariations(aSrc.GetPairListValue(), + variationSettings); AppendFontVariationSettings(variationSettings, aResult); } From 630cd9c74ffb40387f2cb3c651464ad4b2e565ac Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Mon, 20 Nov 2017 13:44:22 +0800 Subject: [PATCH 11/78] Bug 1418899 - Part 3: Use a single image layer array filling function. r=cjku We were accidentally using the background one for the mask layers list anyway, and I don't think the overhead of filling the arrays for the two properties mask layers don't use is a problem. MozReview-Commit-ID: 7LDiYGrnUd5 --HG-- extra : rebase_source : 573d70e0e8c4d110ca6da2846e6fd2887b1fded2 --- layout/style/ServoBindings.cpp | 10 ++----- layout/style/ServoBindings.h | 3 +- layout/style/nsRuleNode.cpp | 52 ++++------------------------------ layout/style/nsRuleNode.h | 7 ++--- 4 files changed, 10 insertions(+), 62 deletions(-) diff --git a/layout/style/ServoBindings.cpp b/layout/style/ServoBindings.cpp index 5020c4f23dea..0a7f3308337d 100644 --- a/layout/style/ServoBindings.cpp +++ b/layout/style/ServoBindings.cpp @@ -850,15 +850,9 @@ Gecko_StyleTransition_SetUnsupportedProperty(StyleTransition* aTransition, } void -Gecko_FillAllBackgroundLists(nsStyleImageLayers* aLayers, uint32_t aMaxLen) +Gecko_FillAllImageLayers(nsStyleImageLayers* aLayers, uint32_t aMaxLen) { - nsRuleNode::FillAllBackgroundLists(*aLayers, aMaxLen); -} - -void -Gecko_FillAllMaskLists(nsStyleImageLayers* aLayers, uint32_t aMaxLen) -{ - nsRuleNode::FillAllMaskLists(*aLayers, aMaxLen); + nsRuleNode::FillAllImageLayers(*aLayers, aMaxLen); } bool diff --git a/layout/style/ServoBindings.h b/layout/style/ServoBindings.h index 128af4c6a596..dc3476a71233 100644 --- a/layout/style/ServoBindings.h +++ b/layout/style/ServoBindings.h @@ -538,8 +538,7 @@ mozilla::css::URLValue* Gecko_NewURLValue(ServoBundledURI uri); NS_DECL_THREADSAFE_FFI_REFCOUNTING(mozilla::css::URLValue, CSSURLValue); NS_DECL_THREADSAFE_FFI_REFCOUNTING(RawGeckoURLExtraData, URLExtraData); -void Gecko_FillAllBackgroundLists(nsStyleImageLayers* layers, uint32_t max_len); -void Gecko_FillAllMaskLists(nsStyleImageLayers* layers, uint32_t max_len); +void Gecko_FillAllImageLayers(nsStyleImageLayers* layers, uint32_t max_len); NS_DECL_THREADSAFE_FFI_REFCOUNTING(nsStyleCoord::Calc, Calc); nsCSSShadowArray* Gecko_NewCSSShadowArray(uint32_t len); diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index d1acb233cf34..783c4e513aaa 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -7131,10 +7131,9 @@ FillImageLayerPositionCoordList( } } -/* static */ -void -nsRuleNode::FillAllBackgroundLists(nsStyleImageLayers& aImage, - uint32_t aMaxItemCount) +/* static */ void +nsRuleNode::FillAllImageLayers(nsStyleImageLayers& aImage, + uint32_t aMaxItemCount) { // Delete any extra items. We need to keep layers in which any // property was specified. @@ -7291,7 +7290,7 @@ nsRuleNode::ComputeBackgroundData(void* aStartStruct, conditions); if (rebuild) { - FillAllBackgroundLists(bg->mImage, maxItemCount); + FillAllImageLayers(bg->mImage, maxItemCount); } COMPUTE_END_RESET(Background, bg) @@ -9190,47 +9189,6 @@ SetSVGOpacity(const nsCSSValue& aValue, } } -/* static */ -void -nsRuleNode::FillAllMaskLists(nsStyleImageLayers& aMask, - uint32_t aMaxItemCount) -{ - - // Delete any extra items. We need to keep layers in which any - // property was specified. - aMask.mLayers.TruncateLengthNonZero(aMaxItemCount); - - uint32_t fillCount = aMask.mImageCount; - - FillImageLayerList(aMask.mLayers, - &nsStyleImageLayers::Layer::mImage, - aMask.mImageCount, fillCount); - FillImageLayerList(aMask.mLayers, - &nsStyleImageLayers::Layer::mRepeat, - aMask.mRepeatCount, fillCount); - FillImageLayerList(aMask.mLayers, - &nsStyleImageLayers::Layer::mClip, - aMask.mClipCount, fillCount); - FillImageLayerList(aMask.mLayers, - &nsStyleImageLayers::Layer::mOrigin, - aMask.mOriginCount, fillCount); - FillImageLayerPositionCoordList(aMask.mLayers, - &Position::mXPosition, - aMask.mPositionXCount, fillCount); - FillImageLayerPositionCoordList(aMask.mLayers, - &Position::mYPosition, - aMask.mPositionYCount, fillCount); - FillImageLayerList(aMask.mLayers, - &nsStyleImageLayers::Layer::mSize, - aMask.mSizeCount, fillCount); - FillImageLayerList(aMask.mLayers, - &nsStyleImageLayers::Layer::mMaskMode, - aMask.mMaskModeCount, fillCount); - FillImageLayerList(aMask.mLayers, - &nsStyleImageLayers::Layer::mComposite, - aMask.mCompositeCount, fillCount); -} - const void* nsRuleNode::ComputeSVGData(void* aStartStruct, const nsRuleData* aRuleData, @@ -9989,7 +9947,7 @@ nsRuleNode::ComputeSVGResetData(void* aStartStruct, svgReset->mMask.mCompositeCount, maxItemCount, rebuild, conditions); if (rebuild) { - FillAllBackgroundLists(svgReset->mMask, maxItemCount); + FillAllImageLayers(svgReset->mMask, maxItemCount); } COMPUTE_END_RESET(SVGReset, svgReset) diff --git a/layout/style/nsRuleNode.h b/layout/style/nsRuleNode.h index 13bbe47628ba..ad52512928d7 100644 --- a/layout/style/nsRuleNode.h +++ b/layout/style/nsRuleNode.h @@ -1059,11 +1059,8 @@ public: // Fill unspecified layers by cycling through their values // till they all are of length aMaxItemCount - static void FillAllBackgroundLists(nsStyleImageLayers& aLayers, - uint32_t aMaxItemCount); - - static void FillAllMaskLists(nsStyleImageLayers& aLayers, - uint32_t aMaxItemCount); + static void FillAllImageLayers(nsStyleImageLayers& aLayers, + uint32_t aMaxItemCount); private: #ifdef DEBUG From 0a20585745f24b5ab57b2000f2ad57e52ec75a1f Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Mon, 20 Nov 2017 13:53:58 +0800 Subject: [PATCH 12/78] Bug 1418899 - Part 4: Move image layer filling function out of nsRuleNode. r=cjku MozReview-Commit-ID: 2FXGFEkpIKE --HG-- extra : rebase_source : 280c85f0e53e6426289580a345685898888ed266 --- layout/style/ServoBindings.cpp | 2 +- layout/style/nsRuleNode.cpp | 82 +--------------------------------- layout/style/nsRuleNode.h | 5 --- layout/style/nsStyleStruct.cpp | 77 +++++++++++++++++++++++++++++++ layout/style/nsStyleStruct.h | 4 ++ 5 files changed, 84 insertions(+), 86 deletions(-) diff --git a/layout/style/ServoBindings.cpp b/layout/style/ServoBindings.cpp index 0a7f3308337d..c36b2ad80efb 100644 --- a/layout/style/ServoBindings.cpp +++ b/layout/style/ServoBindings.cpp @@ -852,7 +852,7 @@ Gecko_StyleTransition_SetUnsupportedProperty(StyleTransition* aTransition, void Gecko_FillAllImageLayers(nsStyleImageLayers* aLayers, uint32_t aMaxLen) { - nsRuleNode::FillAllImageLayers(*aLayers, aMaxLen); + aLayers->FillAllLayers(aMaxLen); } bool diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index 783c4e513aaa..553371352654 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -7097,84 +7097,6 @@ SetImageLayerPairList(GeckoStyleContext* aStyleContext, aMaxItemCount = aItemCount; } -template -static void -FillImageLayerList( - nsStyleAutoArray& aLayers, - ComputedValueItem nsStyleImageLayers::Layer::* aResultLocation, - uint32_t aItemCount, uint32_t aFillCount) -{ - NS_PRECONDITION(aFillCount <= aLayers.Length(), "unexpected array length"); - for (uint32_t sourceLayer = 0, destLayer = aItemCount; - destLayer < aFillCount; - ++sourceLayer, ++destLayer) { - aLayers[destLayer].*aResultLocation = - aLayers[sourceLayer].*aResultLocation; - } -} - -// The same as FillImageLayerList, but for values stored in -// layer.mPosition.*aResultLocation instead of layer.*aResultLocation. -static void -FillImageLayerPositionCoordList( - nsStyleAutoArray& aLayers, - Position::Coord - Position::* aResultLocation, - uint32_t aItemCount, uint32_t aFillCount) -{ - NS_PRECONDITION(aFillCount <= aLayers.Length(), "unexpected array length"); - for (uint32_t sourceLayer = 0, destLayer = aItemCount; - destLayer < aFillCount; - ++sourceLayer, ++destLayer) { - aLayers[destLayer].mPosition.*aResultLocation = - aLayers[sourceLayer].mPosition.*aResultLocation; - } -} - -/* static */ void -nsRuleNode::FillAllImageLayers(nsStyleImageLayers& aImage, - uint32_t aMaxItemCount) -{ - // Delete any extra items. We need to keep layers in which any - // property was specified. - aImage.mLayers.TruncateLengthNonZero(aMaxItemCount); - - uint32_t fillCount = aImage.mImageCount; - FillImageLayerList(aImage.mLayers, - &nsStyleImageLayers::Layer::mImage, - aImage.mImageCount, fillCount); - FillImageLayerList(aImage.mLayers, - &nsStyleImageLayers::Layer::mRepeat, - aImage.mRepeatCount, fillCount); - FillImageLayerList(aImage.mLayers, - &nsStyleImageLayers::Layer::mAttachment, - aImage.mAttachmentCount, fillCount); - FillImageLayerList(aImage.mLayers, - &nsStyleImageLayers::Layer::mClip, - aImage.mClipCount, fillCount); - FillImageLayerList(aImage.mLayers, - &nsStyleImageLayers::Layer::mBlendMode, - aImage.mBlendModeCount, fillCount); - FillImageLayerList(aImage.mLayers, - &nsStyleImageLayers::Layer::mOrigin, - aImage.mOriginCount, fillCount); - FillImageLayerPositionCoordList(aImage.mLayers, - &Position::mXPosition, - aImage.mPositionXCount, fillCount); - FillImageLayerPositionCoordList(aImage.mLayers, - &Position::mYPosition, - aImage.mPositionYCount, fillCount); - FillImageLayerList(aImage.mLayers, - &nsStyleImageLayers::Layer::mSize, - aImage.mSizeCount, fillCount); - FillImageLayerList(aImage.mLayers, - &nsStyleImageLayers::Layer::mMaskMode, - aImage.mMaskModeCount, fillCount); - FillImageLayerList(aImage.mLayers, - &nsStyleImageLayers::Layer::mComposite, - aImage.mCompositeCount, fillCount); -} - const void* nsRuleNode::ComputeBackgroundData(void* aStartStruct, const nsRuleData* aRuleData, @@ -7290,7 +7212,7 @@ nsRuleNode::ComputeBackgroundData(void* aStartStruct, conditions); if (rebuild) { - FillAllImageLayers(bg->mImage, maxItemCount); + bg->mImage.FillAllLayers(maxItemCount); } COMPUTE_END_RESET(Background, bg) @@ -9947,7 +9869,7 @@ nsRuleNode::ComputeSVGResetData(void* aStartStruct, svgReset->mMask.mCompositeCount, maxItemCount, rebuild, conditions); if (rebuild) { - FillAllImageLayers(svgReset->mMask, maxItemCount); + svgReset->mMask.FillAllLayers(maxItemCount); } COMPUTE_END_RESET(SVGReset, svgReset) diff --git a/layout/style/nsRuleNode.h b/layout/style/nsRuleNode.h index ad52512928d7..a01508414031 100644 --- a/layout/style/nsRuleNode.h +++ b/layout/style/nsRuleNode.h @@ -1057,11 +1057,6 @@ public: static void ComputeTimingFunction(const nsCSSValue& aValue, nsTimingFunction& aResult); - // Fill unspecified layers by cycling through their values - // till they all are of length aMaxItemCount - static void FillAllImageLayers(nsStyleImageLayers& aLayers, - uint32_t aMaxItemCount); - private: #ifdef DEBUG // non-inline helper function to allow assertions without incomplete diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index f5b4abecdf0e..04e303cb12cc 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -3177,6 +3177,83 @@ nsStyleImageLayers::Layer::operator==(const Layer& aOther) const mComposite == aOther.mComposite; } +template +static void +FillImageLayerList( + nsStyleAutoArray& aLayers, + ComputedValueItem nsStyleImageLayers::Layer::* aResultLocation, + uint32_t aItemCount, uint32_t aFillCount) +{ + NS_PRECONDITION(aFillCount <= aLayers.Length(), "unexpected array length"); + for (uint32_t sourceLayer = 0, destLayer = aItemCount; + destLayer < aFillCount; + ++sourceLayer, ++destLayer) { + aLayers[destLayer].*aResultLocation = + aLayers[sourceLayer].*aResultLocation; + } +} + +// The same as FillImageLayerList, but for values stored in +// layer.mPosition.*aResultLocation instead of layer.*aResultLocation. +static void +FillImageLayerPositionCoordList( + nsStyleAutoArray& aLayers, + Position::Coord + Position::* aResultLocation, + uint32_t aItemCount, uint32_t aFillCount) +{ + NS_PRECONDITION(aFillCount <= aLayers.Length(), "unexpected array length"); + for (uint32_t sourceLayer = 0, destLayer = aItemCount; + destLayer < aFillCount; + ++sourceLayer, ++destLayer) { + aLayers[destLayer].mPosition.*aResultLocation = + aLayers[sourceLayer].mPosition.*aResultLocation; + } +} + +void +nsStyleImageLayers::FillAllLayers(uint32_t aMaxItemCount) +{ + // Delete any extra items. We need to keep layers in which any + // property was specified. + mLayers.TruncateLengthNonZero(aMaxItemCount); + + uint32_t fillCount = mImageCount; + FillImageLayerList(mLayers, + &nsStyleImageLayers::Layer::mImage, + mImageCount, fillCount); + FillImageLayerList(mLayers, + &nsStyleImageLayers::Layer::mRepeat, + mRepeatCount, fillCount); + FillImageLayerList(mLayers, + &nsStyleImageLayers::Layer::mAttachment, + mAttachmentCount, fillCount); + FillImageLayerList(mLayers, + &nsStyleImageLayers::Layer::mClip, + mClipCount, fillCount); + FillImageLayerList(mLayers, + &nsStyleImageLayers::Layer::mBlendMode, + mBlendModeCount, fillCount); + FillImageLayerList(mLayers, + &nsStyleImageLayers::Layer::mOrigin, + mOriginCount, fillCount); + FillImageLayerPositionCoordList(mLayers, + &Position::mXPosition, + mPositionXCount, fillCount); + FillImageLayerPositionCoordList(mLayers, + &Position::mYPosition, + mPositionYCount, fillCount); + FillImageLayerList(mLayers, + &nsStyleImageLayers::Layer::mSize, + mSizeCount, fillCount); + FillImageLayerList(mLayers, + &nsStyleImageLayers::Layer::mMaskMode, + mMaskModeCount, fillCount); + FillImageLayerList(mLayers, + &nsStyleImageLayers::Layer::mComposite, + mCompositeCount, fillCount); +} + nsChangeHint nsStyleImageLayers::Layer::CalcDifference(const nsStyleImageLayers::Layer& aNewLayer) const { diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index dc6e86043940..c09a632d8928 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -841,6 +841,10 @@ struct nsStyleImageLayers { } } + // Fill unspecified layers by cycling through their values + // till they all are of length aMaxItemCount + void FillAllLayers(uint32_t aMaxItemCount); + nsChangeHint CalcDifference(const nsStyleImageLayers& aNewLayers, nsStyleImageLayers::LayerType aType) const; From c5401dfc03b7f66f963e6f2bfd3abea3af44cde1 Mon Sep 17 00:00:00 2001 From: JW Wang Date: Wed, 15 Nov 2017 17:56:10 +0800 Subject: [PATCH 13/78] Bug 1418213 - always run MediaCacheStream::NotifyDataReceived() off the main thread. r=bechen,gerald MozReview-Commit-ID: GBQ0lEf8rVI --HG-- extra : rebase_source : cbcd69dd220c06e2e1cc0d12e33d23ce2f4e21ef extra : intermediate-source : 9e304fc5f5ee0b4d44f0e54a4cb2a6a9fe90979d extra : source : 1b29a7cde3c40ba3a35ee19eee63ad68e6d12176 --- dom/media/ChannelMediaResource.cpp | 24 ++++++++++++++++++------ dom/media/MediaCache.cpp | 2 +- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/dom/media/ChannelMediaResource.cpp b/dom/media/ChannelMediaResource.cpp index 2d1961d3aadd..720003320650 100644 --- a/dom/media/ChannelMediaResource.cpp +++ b/dom/media/ChannelMediaResource.cpp @@ -303,7 +303,6 @@ ChannelMediaResource::OnStartRequest(nsIRequest* aRequest, // Fires an initial progress event. owner->DownloadProgressed(); - // TODO: Don't turn this on until we fix all data races. nsCOMPtr retarget; if (Preferences::GetBool("media.omt_data_delivery.enabled", false) && (retarget = do_QueryInterface(aRequest))) { @@ -417,12 +416,25 @@ ChannelMediaResource::CopySegmentToCache(nsIInputStream* aInStream, uint32_t aCount, uint32_t* aWriteCount) { - Closure* closure = static_cast(aClosure); - closure->mResource->mCacheStream.NotifyDataReceived( - closure->mLoadID, - aCount, - reinterpret_cast(aFromSegment)); *aWriteCount = aCount; + Closure* closure = static_cast(aClosure); + MediaCacheStream* cacheStream = &closure->mResource->mCacheStream; + if (cacheStream->OwnerThread()->IsOnCurrentThread()) { + cacheStream->NotifyDataReceived( + closure->mLoadID, aCount, reinterpret_cast(aFromSegment)); + return NS_OK; + } + + RefPtr self = closure->mResource; + uint32_t loadID = closure->mLoadID; + UniquePtr data = MakeUnique(aCount); + memcpy(data.get(), aFromSegment, aCount); + cacheStream->OwnerThread()->Dispatch(NS_NewRunnableFunction( + "MediaCacheStream::NotifyDataReceived", + [ self, loadID, data = Move(data), aCount ]() { + self->mCacheStream.NotifyDataReceived(loadID, aCount, data.get()); + })); + return NS_OK; } diff --git a/dom/media/MediaCache.cpp b/dom/media/MediaCache.cpp index db635b2dc73d..580def82949f 100644 --- a/dom/media/MediaCache.cpp +++ b/dom/media/MediaCache.cpp @@ -2006,8 +2006,8 @@ MediaCacheStream::NotifyDataReceived(uint32_t aLoadID, uint32_t aCount, const uint8_t* aData) { + MOZ_ASSERT(OwnerThread()->IsOnCurrentThread()); MOZ_ASSERT(aLoadID > 0); - // This might happen off the main thread. ReentrantMonitorAutoEnter mon(mMediaCache->GetReentrantMonitor()); if (mClosed) { From c4a2859c9ef57179345c4280440daac72cee6717 Mon Sep 17 00:00:00 2001 From: Cameron McCormack Date: Tue, 21 Nov 2017 17:11:40 +0800 Subject: [PATCH 14/78] Bug 1418899 - Followup speculative Windows build fix. (CLOSED TREE) --- layout/style/nsStyleStruct.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index 04e303cb12cc..95e55465f9d3 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -3220,22 +3220,22 @@ nsStyleImageLayers::FillAllLayers(uint32_t aMaxItemCount) uint32_t fillCount = mImageCount; FillImageLayerList(mLayers, - &nsStyleImageLayers::Layer::mImage, + &Layer::mImage, mImageCount, fillCount); FillImageLayerList(mLayers, - &nsStyleImageLayers::Layer::mRepeat, + &Layer::mRepeat, mRepeatCount, fillCount); FillImageLayerList(mLayers, - &nsStyleImageLayers::Layer::mAttachment, + &Layer::mAttachment, mAttachmentCount, fillCount); FillImageLayerList(mLayers, - &nsStyleImageLayers::Layer::mClip, + &Layer::mClip, mClipCount, fillCount); FillImageLayerList(mLayers, - &nsStyleImageLayers::Layer::mBlendMode, + &Layer::mBlendMode, mBlendModeCount, fillCount); FillImageLayerList(mLayers, - &nsStyleImageLayers::Layer::mOrigin, + &Layer::mOrigin, mOriginCount, fillCount); FillImageLayerPositionCoordList(mLayers, &Position::mXPosition, @@ -3244,13 +3244,13 @@ nsStyleImageLayers::FillAllLayers(uint32_t aMaxItemCount) &Position::mYPosition, mPositionYCount, fillCount); FillImageLayerList(mLayers, - &nsStyleImageLayers::Layer::mSize, + &Layer::mSize, mSizeCount, fillCount); FillImageLayerList(mLayers, - &nsStyleImageLayers::Layer::mMaskMode, + &Layer::mMaskMode, mMaskModeCount, fillCount); FillImageLayerList(mLayers, - &nsStyleImageLayers::Layer::mComposite, + &Layer::mComposite, mCompositeCount, fillCount); } From 6b0d30658ad537e764901c38f937e8ca5ffe832d Mon Sep 17 00:00:00 2001 From: Tiberius Oros Date: Tue, 21 Nov 2017 11:46:50 +0200 Subject: [PATCH 15/78] Backed out changeset edf2b70d2f01 (bug 1408182)for failing in devtools/client/netmonitor/test/browser_net_copy_params.js r=backout on a CLOSED TREE --- devtools/client/netmonitor/.eslintrc.js | 6 - .../src/components/RequestListContent.js | 2 +- .../src/components/StatisticsPanel.js | 4 +- .../netmonitor/src/components/Toolbar.js | 2 +- .../netmonitor/src/reducers/requests.js | 357 ++++++++---------- .../netmonitor/src/selectors/requests.js | 29 +- .../src/selectors/timing-markers.js | 2 +- .../client/netmonitor/src/selectors/ui.js | 2 +- 8 files changed, 176 insertions(+), 228 deletions(-) diff --git a/devtools/client/netmonitor/.eslintrc.js b/devtools/client/netmonitor/.eslintrc.js index 2f8bf01fe6ee..a7326d498044 100644 --- a/devtools/client/netmonitor/.eslintrc.js +++ b/devtools/client/netmonitor/.eslintrc.js @@ -20,10 +20,4 @@ module.exports = { /* eslint-disable max-len */ "mozilla/reject-some-requires": ["error", "^(chrome|chrome:.*|resource:.*|devtools/server/.*|.*\\.jsm|devtools/shared/platform/(chome|content)/.*)$"], }, - - "parserOptions": { - "ecmaFeatures": { - experimentalObjectRestSpread: true, - }, - }, }; diff --git a/devtools/client/netmonitor/src/components/RequestListContent.js b/devtools/client/netmonitor/src/components/RequestListContent.js index 1a6cf81ba7ad..537fa6282ae9 100644 --- a/devtools/client/netmonitor/src/components/RequestListContent.js +++ b/devtools/client/netmonitor/src/components/RequestListContent.js @@ -37,7 +37,7 @@ class RequestListContent extends Component { connector: PropTypes.object.isRequired, columns: PropTypes.object.isRequired, dispatch: PropTypes.func.isRequired, - displayedRequests: PropTypes.array.isRequired, + displayedRequests: PropTypes.object.isRequired, firstRequestStartedMillis: PropTypes.number.isRequired, fromCache: PropTypes.bool, onCauseBadgeMouseDown: PropTypes.func.isRequired, diff --git a/devtools/client/netmonitor/src/components/StatisticsPanel.js b/devtools/client/netmonitor/src/components/StatisticsPanel.js index c97300ffbab5..ff0c8f809b79 100644 --- a/devtools/client/netmonitor/src/components/StatisticsPanel.js +++ b/devtools/client/netmonitor/src/components/StatisticsPanel.js @@ -40,7 +40,7 @@ class StatisticsPanel extends Component { connector: PropTypes.object.isRequired, closeStatistics: PropTypes.func.isRequired, enableRequestFilterTypeOnly: PropTypes.func.isRequired, - requests: PropTypes.array, + requests: PropTypes.object, }; } @@ -67,7 +67,7 @@ class StatisticsPanel extends Component { MediaQueryList.addListener(this.onLayoutChange); const { requests } = this.props; - let ready = requests && requests.length && requests.every((req) => + let ready = requests && !requests.isEmpty() && requests.every((req) => req.contentSize !== undefined && req.mimeType && req.responseHeaders && req.status !== undefined && req.totalTime !== undefined ); diff --git a/devtools/client/netmonitor/src/components/Toolbar.js b/devtools/client/netmonitor/src/components/Toolbar.js index 688e73d2f6b3..07e958b77103 100644 --- a/devtools/client/netmonitor/src/components/Toolbar.js +++ b/devtools/client/netmonitor/src/components/Toolbar.js @@ -71,7 +71,7 @@ class Toolbar extends Component { toggleBrowserCache: PropTypes.func.isRequired, browserCacheDisabled: PropTypes.bool.isRequired, toggleRequestFilterType: PropTypes.func.isRequired, - filteredRequests: PropTypes.array.isRequired, + filteredRequests: PropTypes.object.isRequired, }; } diff --git a/devtools/client/netmonitor/src/reducers/requests.js b/devtools/client/netmonitor/src/reducers/requests.js index dcb01f9400b6..3231b81b99df 100644 --- a/devtools/client/netmonitor/src/reducers/requests.js +++ b/devtools/client/netmonitor/src/reducers/requests.js @@ -4,6 +4,7 @@ "use strict"; +const I = require("devtools/client/shared/vendor/immutable"); const { getUrlDetails, processNetworkUpdates, @@ -20,173 +21,59 @@ const { UPDATE_REQUEST, } = require("../constants"); -/** - * This structure stores list of all HTTP requests received - * from the backend. It's using plain JS structures to store - * data instead of ImmutableJS, which is performance expensive. - */ -function Requests() { - return { - // Map with all requests (key = actor ID, value = request object) - requests: mapNew(), - // Selected request ID - selectedId: null, - preselectedId: null, - // True if the monitor is recording HTTP traffic - recording: true, - // Auxiliary fields to hold requests stats - firstStartedMillis: +Infinity, - lastEndedMillis: -Infinity, - }; -} +const Request = I.Record({ + id: null, + // Set to true in case of a request that's being edited as part of "edit and resend" + isCustom: false, + // Request properties - at the beginning, they are unknown and are gradually filled in + startedMillis: undefined, + endedMillis: undefined, + method: undefined, + url: undefined, + urlDetails: undefined, + remotePort: undefined, + remoteAddress: undefined, + isXHR: undefined, + cause: undefined, + fromCache: undefined, + fromServiceWorker: undefined, + status: undefined, + statusText: undefined, + httpVersion: undefined, + securityState: undefined, + securityInfo: undefined, + mimeType: "text/plain", + contentSize: undefined, + transferredSize: undefined, + totalTime: undefined, + eventTimings: undefined, + headersSize: undefined, + // Text value is used for storing custom request query + // which only appears when user edit the custom requst form + customQueryValue: undefined, + requestHeaders: undefined, + requestHeadersFromUploadStream: undefined, + requestCookies: undefined, + requestPostData: undefined, + responseHeaders: undefined, + responseCookies: undefined, + responseContent: undefined, + responseContentAvailable: false, + formDataSections: undefined, +}); -/** - * This reducer is responsible for maintaining list of request - * within the Network panel. - */ -function requestsReducer(state = Requests(), action) { - switch (action.type) { - // Appending new request into the list/map. - case ADD_REQUEST: { - let nextState = { ...state }; - - let newRequest = { - id: action.id, - ...action.data, - urlDetails: getUrlDetails(action.data.url), - }; - - nextState.requests = mapSet(state.requests, newRequest.id, newRequest); - - // Update the started/ended timestamps. - let { startedMillis } = action.data; - if (startedMillis < state.firstStartedMillis) { - nextState.firstStartedMillis = startedMillis; - } - if (startedMillis > state.lastEndedMillis) { - nextState.lastEndedMillis = startedMillis; - } - - // Select the request if it was preselected and there is no other selection. - if (state.preselectedId && state.preselectedId === action.id) { - nextState.selectedId = state.selectedId || state.preselectedId; - nextState.preselectedId = null; - } - - return nextState; - } - - // Update an existing request (with received data). - case UPDATE_REQUEST: { - let { requests, lastEndedMillis } = state; - - let request = requests.get(action.id); - if (!request) { - return state; - } - - request = { - ...request, - ...processNetworkUpdates(action.data), - }; - - return { - ...state, - requests: mapSet(state.requests, action.id, request), - lastEndedMillis: lastEndedMillis, - }; - } - - // Remove all requests in the list. Create fresh new state - // object, but keep value of the `recording` field. - case CLEAR_REQUESTS: { - return { - ...Requests(), - recording: state.recording, - }; - } - - // Select specific request. - case SELECT_REQUEST: { - return { - ...state, - selectedId: action.id, - }; - } - - // Clone selected request for re-send. - case CLONE_SELECTED_REQUEST: { - let { requests, selectedId } = state; - - if (!selectedId) { - return state; - } - - let clonedRequest = requests.get(selectedId); - if (!clonedRequest) { - return state; - } - - let newRequest = { - id: clonedRequest.id + "-clone", - method: clonedRequest.method, - url: clonedRequest.url, - urlDetails: clonedRequest.urlDetails, - requestHeaders: clonedRequest.requestHeaders, - requestPostData: clonedRequest.requestPostData, - isCustom: true - }; - - return { - ...state, - requests: mapSet(requests, newRequest.id, newRequest), - selectedId: newRequest.id, - }; - } - - // Removing temporary cloned request (created for re-send, but canceled). - case REMOVE_SELECTED_CUSTOM_REQUEST: { - return closeCustomRequest(state); - } - - // Re-sending an existing request. - case SEND_CUSTOM_REQUEST: { - // When a new request with a given id is added in future, select it immediately. - // where we know in advance the ID of the request, at a time when it - // wasn't sent yet. - return closeCustomRequest(state.set("preselectedId", action.id)); - } - - // Pause/resume button clicked. - case TOGGLE_RECORDING: { - return { - ...state, - recording: !state.recording, - }; - } - - // Side bar with request details opened. - case OPEN_NETWORK_DETAILS: { - let nextState = { ...state }; - if (!action.open) { - nextState.selectedId = null; - return nextState; - } - - if (!state.selectedId && !state.requests.isEmpty()) { - nextState.selectedId = [...state.requests.values()][0].id; - return nextState; - } - - return state; - } - - default: - return state; - } -} - -// Helpers +const Requests = I.Record({ + // The collection of requests (keyed by id) + requests: I.Map(), + // Selection state + selectedId: null, + preselectedId: null, + // Auxiliary fields to hold requests stats + firstStartedMillis: +Infinity, + lastEndedMillis: -Infinity, + // Recording state + recording: true, +}); /** * Remove the currently selected custom request. @@ -205,41 +92,119 @@ function closeCustomRequest(state) { return state; } - return { - ...state, - requests: mapDelete(state.requests, selectedId), - selectedId: null, - }; + return state.withMutations(st => { + st.requests = st.requests.delete(selectedId); + st.selectedId = null; + }); } -// Immutability helpers -// FIXME The following helper API need refactoring, see bug 1418969. +function requestsReducer(state = new Requests(), action) { + switch (action.type) { + case ADD_REQUEST: { + return state.withMutations(st => { + let newRequest = new Request(Object.assign( + { id: action.id }, + action.data, + { urlDetails: getUrlDetails(action.data.url) } + )); + st.requests = st.requests.set(newRequest.id, newRequest); -/** - * Clone an existing map. - */ -function mapNew(map) { - let newMap = new Map(map); - newMap.isEmpty = () => newMap.size == 0; - newMap.valueSeq = () => [...newMap.values()]; - return newMap; -} + // Update the started/ended timestamps + let { startedMillis } = action.data; + if (startedMillis < st.firstStartedMillis) { + st.firstStartedMillis = startedMillis; + } + if (startedMillis > st.lastEndedMillis) { + st.lastEndedMillis = startedMillis; + } -/** - * Append new item into existing map and return new map. - */ -function mapSet(map, key, value) { - let newMap = mapNew(map); - return newMap.set(key, value); -} + // Select the request if it was preselected and there is no other selection + if (st.preselectedId && st.preselectedId === action.id) { + st.selectedId = st.selectedId || st.preselectedId; + st.preselectedId = null; + } + }); + } + case CLEAR_REQUESTS: { + return new Requests({ + recording: state.recording + }); + } + case CLONE_SELECTED_REQUEST: { + let { requests, selectedId } = state; -/** - * Remove an item from existing map and return new map. - */ -function mapDelete(map, key) { - let newMap = mapNew(map); - newMap.requests.delete(key); - return newMap; + if (!selectedId) { + return state; + } + + let clonedRequest = requests.get(selectedId); + if (!clonedRequest) { + return state; + } + + let newRequest = new Request({ + id: clonedRequest.id + "-clone", + method: clonedRequest.method, + url: clonedRequest.url, + urlDetails: clonedRequest.urlDetails, + requestHeaders: clonedRequest.requestHeaders, + requestPostData: clonedRequest.requestPostData, + isCustom: true + }); + + return state.withMutations(st => { + st.requests = requests.set(newRequest.id, newRequest); + st.selectedId = newRequest.id; + }); + } + case OPEN_NETWORK_DETAILS: { + if (!action.open) { + return state.set("selectedId", null); + } + + if (!state.selectedId && !state.requests.isEmpty()) { + return state.set("selectedId", state.requests.first().id); + } + + return state; + } + case REMOVE_SELECTED_CUSTOM_REQUEST: { + return closeCustomRequest(state); + } + case SELECT_REQUEST: { + return state.set("selectedId", action.id); + } + case SEND_CUSTOM_REQUEST: { + // When a new request with a given id is added in future, select it immediately. + // where we know in advance the ID of the request, at a time when it + // wasn't sent yet. + return closeCustomRequest(state.set("preselectedId", action.id)); + } + case TOGGLE_RECORDING: { + return state.set("recording", !state.recording); + } + case UPDATE_REQUEST: { + let { requests, lastEndedMillis } = state; + + let updatedRequest = requests.get(action.id); + if (!updatedRequest) { + return state; + } + + updatedRequest = updatedRequest.withMutations(request => { + let values = processNetworkUpdates(action.data); + request = Object.assign(request, values); + }); + + return state.withMutations(st => { + st.requests = requests.set(updatedRequest.id, updatedRequest); + st.lastEndedMillis = lastEndedMillis; + }); + } + + default: + return state; + } } module.exports = { diff --git a/devtools/client/netmonitor/src/selectors/requests.js b/devtools/client/netmonitor/src/selectors/requests.js index 50aa4688e185..b7950ef029f1 100644 --- a/devtools/client/netmonitor/src/selectors/requests.js +++ b/devtools/client/netmonitor/src/selectors/requests.js @@ -56,9 +56,9 @@ const getTypeFilterFn = createSelector( ); const getSortFn = createSelector( - state => state.requests, + state => state.requests.requests, state => state.sort, - ({ requests }, sort) => { + (requests, sort) => { const sorter = Sorters[sort.type || "waterfall"]; const ascending = sort.ascending ? +1 : -1; return (a, b) => ascending * sortWithClones(requests, sorter, a, b); @@ -66,34 +66,23 @@ const getSortFn = createSelector( ); const getSortedRequests = createSelector( - state => state.requests, + state => state.requests.requests, getSortFn, - ({ requests }, sortFn) => { - let arr = requests.valueSeq().sort(sortFn); - arr.get = index => arr[index]; - arr.isEmpty = () => this.length == 0; - arr.size = arr.length; - return arr; - } + (requests, sortFn) => requests.valueSeq().sort(sortFn).toList() ); const getDisplayedRequests = createSelector( - state => state.requests, + state => state.requests.requests, getFilterFn, getSortFn, - ({ requests }, filterFn, sortFn) => { - let arr = requests.valueSeq().filter(filterFn).sort(sortFn); - arr.get = index => arr[index]; - arr.isEmpty = () => this.length == 0; - arr.size = arr.length; - return arr; - } + (requests, filterFn, sortFn) => requests.valueSeq() + .filter(filterFn).sort(sortFn).toList() ); const getTypeFilteredRequests = createSelector( - state => state.requests, + state => state.requests.requests, getTypeFilterFn, - ({ requests }, filterFn) => requests.valueSeq().filter(filterFn) + (requests, filterFn) => requests.valueSeq().filter(filterFn).toList() ); const getDisplayedRequestsSummary = createSelector( diff --git a/devtools/client/netmonitor/src/selectors/timing-markers.js b/devtools/client/netmonitor/src/selectors/timing-markers.js index 1c018698cffc..ee72ccddac16 100644 --- a/devtools/client/netmonitor/src/selectors/timing-markers.js +++ b/devtools/client/netmonitor/src/selectors/timing-markers.js @@ -5,7 +5,7 @@ "use strict"; function getDisplayedTimingMarker(state, marker) { - return state.timingMarkers.get(marker) - state.requests.firstStartedMillis; + return state.timingMarkers.get(marker) - state.requests.get("firstStartedMillis"); } module.exports = { diff --git a/devtools/client/netmonitor/src/selectors/ui.js b/devtools/client/netmonitor/src/selectors/ui.js index b81e4ee320d0..44aaf4504032 100644 --- a/devtools/client/netmonitor/src/selectors/ui.js +++ b/devtools/client/netmonitor/src/selectors/ui.js @@ -8,7 +8,7 @@ const { REQUESTS_WATERFALL } = require("../constants"); const { getDisplayedRequests } = require("./requests"); function isNetworkDetailsToggleButtonDisabled(state) { - return getDisplayedRequests(state).length == 0; + return getDisplayedRequests(state).isEmpty(); } const EPSILON = 0.001; From 040582886a1c2ddd4f1fdd485e456036683183e1 Mon Sep 17 00:00:00 2001 From: Patrick Brosset Date: Thu, 19 Oct 2017 10:57:30 +0200 Subject: [PATCH 16/78] Bug 1405288 - Remove resolveRelativeURL actor method check from the inspector r=ochameau The resolveRelativeURL actor method was added in bug 921102 which shipped with Firefox 40. This was 3 years ago, and well older than the latest current ESR (52), which is the latest version we support. MozReview-Commit-ID: 5X5czLP5v2E --HG-- extra : rebase_source : 7c1ee2c2a78151eb94ef1f1bacff6396d3ceb24e --- devtools/client/inspector/inspector.js | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/devtools/client/inspector/inspector.js b/devtools/client/inspector/inspector.js index 0fd40c5ff186..fd76068c7efc 100644 --- a/devtools/client/inspector/inspector.js +++ b/devtools/client/inspector/inspector.js @@ -221,7 +221,6 @@ Inspector.prototype = { _detectActorFeatures: function () { this._supportsDuplicateNode = false; this._supportsScrollIntoView = false; - this._supportsResolveRelativeURL = false; // Use getActorDescription first so that all actorHasMethod calls use // a cached response from the server. @@ -232,10 +231,7 @@ Inspector.prototype = { }).catch(console.error), this._target.actorHasMethod("domnode", "scrollIntoView").then(value => { this._supportsScrollIntoView = value; - }).catch(console.error), - this._target.actorHasMethod("inspector", "resolveRelativeURL").then(value => { - this._supportsResolveRelativeURL = value; - }).catch(console.error), + }).catch(console.error) ]); }); }, @@ -1600,8 +1596,7 @@ Inspector.prototype = { } let type = popupNode.dataset.type; - if (this._supportsResolveRelativeURL && - (type === "uri" || type === "cssresource" || type === "jsresource")) { + if ((type === "uri" || type === "cssresource" || type === "jsresource")) { // Links can't be opened in new tabs in the browser toolbox. if (type === "uri" && !this.target.chrome) { linkFollow.visible = true; @@ -2127,8 +2122,6 @@ Inspector.prototype = { if (type === "uri" || type === "cssresource" || type === "jsresource") { // Open link in a new tab. - // When the inspector menu was setup on click (see _getNodeLinkMenuItems), we - // already checked that resolveRelativeURL existed. this.inspector.resolveRelativeURL( link, this.selection.nodeFront).then(url => { if (type === "uri") { @@ -2169,8 +2162,6 @@ Inspector.prototype = { * This method is here for the benefit of copying links. */ copyAttributeLink: function (link) { - // When the inspector menu was setup on click (see _getNodeLinkMenuItems), we - // already checked that resolveRelativeURL existed. this.inspector.resolveRelativeURL(link, this.selection.nodeFront).then(url => { clipboardHelper.copyString(url); }, console.error); From 896c0325ae8e81e89aa78eaf2eec6ea9b5841dbd Mon Sep 17 00:00:00 2001 From: Patrick Brosset Date: Thu, 19 Oct 2017 11:05:10 +0200 Subject: [PATCH 17/78] Bug 1405288 - Remove duplicateNode actor method check from the inspector r=ochameau This method was added in bug 1208864 2 years ago and shipped with Firefox 44. We support all the way to the latest ESR, which now is 52. So let's remove this backward compat code. MozReview-Commit-ID: AdTU63Oehi4 --HG-- extra : rebase_source : 481f768101212db1f363c9b5204f7654aaea5208 --- devtools/client/inspector/inspector.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/devtools/client/inspector/inspector.js b/devtools/client/inspector/inspector.js index fd76068c7efc..12b1738e2f97 100644 --- a/devtools/client/inspector/inspector.js +++ b/devtools/client/inspector/inspector.js @@ -219,16 +219,12 @@ Inspector.prototype = { * Figure out what features the backend supports */ _detectActorFeatures: function () { - this._supportsDuplicateNode = false; this._supportsScrollIntoView = false; // Use getActorDescription first so that all actorHasMethod calls use // a cached response from the server. return this._target.getActorDescription("domwalker").then(desc => { return promise.all([ - this._target.actorHasMethod("domwalker", "duplicateNode").then(value => { - this._supportsDuplicateNode = value; - }).catch(console.error), this._target.actorHasMethod("domnode", "scrollIntoView").then(value => { this._supportsScrollIntoView = value; }).catch(console.error) @@ -1295,7 +1291,6 @@ Inspector.prototype = { menu.append(new MenuItem({ id: "node-menu-duplicatenode", label: INSPECTOR_L10N.getStr("inspectorDuplicateNode.label"), - hidden: !this._supportsDuplicateNode, disabled: !isDuplicatableElement, click: () => this.duplicateNode(), })); From b66f6388b177005842c22fd2a82b02a71d80694b Mon Sep 17 00:00:00 2001 From: Patrick Brosset Date: Thu, 19 Oct 2017 11:12:23 +0200 Subject: [PATCH 18/78] Bug 1405288 - Remove scrollIntoView actor method check from the inspector r=ochameau The scrollIntoView actor method was added in bug 901250 3 years ago and shipped with FF 40. We support all the way back to the latest ESR (52 now). So let's drop this backward compat check code. MozReview-Commit-ID: 5FKRpiOXfzd --HG-- extra : rebase_source : 4c3b0850750081a87b77bc1b85d7a2e852f58c82 --- devtools/client/inspector/inspector.js | 19 ------------------- .../markup/test/browser_markup_links_04.js | 6 ------ devtools/client/inspector/test/shared-head.js | 3 --- 3 files changed, 28 deletions(-) diff --git a/devtools/client/inspector/inspector.js b/devtools/client/inspector/inspector.js index 12b1738e2f97..b961f31d1191 100644 --- a/devtools/client/inspector/inspector.js +++ b/devtools/client/inspector/inspector.js @@ -131,7 +131,6 @@ function Inspector(toolbox) { this.onSidebarShown = this.onSidebarShown.bind(this); this._target.on("will-navigate", this._onBeforeNavigate); - this._detectingActorFeatures = this._detectActorFeatures(); } Inspector.prototype = { @@ -215,23 +214,6 @@ Inspector.prototype = { } }, - /** - * Figure out what features the backend supports - */ - _detectActorFeatures: function () { - this._supportsScrollIntoView = false; - - // Use getActorDescription first so that all actorHasMethod calls use - // a cached response from the server. - return this._target.getActorDescription("domwalker").then(desc => { - return promise.all([ - this._target.actorHasMethod("domnode", "scrollIntoView").then(value => { - this._supportsScrollIntoView = value; - }).catch(console.error) - ]); - }); - }, - _deferredOpen: async function (defaultSelection) { this.breadcrumbs = new HTMLBreadcrumbs(this); @@ -1374,7 +1356,6 @@ Inspector.prototype = { label: INSPECTOR_L10N.getStr("inspectorScrollNodeIntoView.label"), accesskey: INSPECTOR_L10N.getStr("inspectorScrollNodeIntoView.accesskey"), - hidden: !this._supportsScrollIntoView, disabled: !isSelectionElement, click: () => this.scrollNodeIntoView(), })); diff --git a/devtools/client/inspector/markup/test/browser_markup_links_04.js b/devtools/client/inspector/markup/test/browser_markup_links_04.js index f21afd8d242d..c45646fcecc4 100644 --- a/devtools/client/inspector/markup/test/browser_markup_links_04.js +++ b/devtools/client/inspector/markup/test/browser_markup_links_04.js @@ -93,12 +93,6 @@ add_task(function* () { let linkFollow = allMenuItems.find(i => i.id === "node-menu-link-follow"); let linkCopy = allMenuItems.find(i => i.id === "node-menu-link-copy"); - // The contextual menu setup is async, because it needs to know if the - // inspector has the resolveRelativeURL method first. So call actorHasMethod - // here too to make sure the first call resolves first and the menu is - // properly setup. - yield inspector.target.actorHasMethod("inspector", "resolveRelativeURL"); - is(linkFollow.visible, test.isLinkFollowItemVisible, "The follow-link item display is correct"); is(linkCopy.visible, test.isLinkCopyItemVisible, diff --git a/devtools/client/inspector/test/shared-head.js b/devtools/client/inspector/test/shared-head.js index 2eac1d44c23d..007f618b25e3 100644 --- a/devtools/client/inspector/test/shared-head.js +++ b/devtools/client/inspector/test/shared-head.js @@ -30,9 +30,6 @@ var openInspector = Task.async(function* (hostType) { yield inspector.once("inspector-updated"); } - info("Waiting for actor features to be detected"); - yield inspector._detectingActorFeatures; - yield registerTestActor(toolbox.target.client); let testActor = yield getTestActor(toolbox); From 827ce5b328525d8c1c2baeb839c6200ed9dc9ed7 Mon Sep 17 00:00:00 2001 From: Patrick Brosset Date: Thu, 19 Oct 2017 11:20:57 +0200 Subject: [PATCH 19/78] Bug 1405288 - Remove pickColorFromPage actor method check from then inspector r=ochameau This method was added in bug 1262439 last year, and shipped with FF50. We support all the way back to the latest ESR (52 now). So let's remove the backward compat code for this method. MozReview-Commit-ID: LUL7FFWWC5M --HG-- extra : rebase_source : 27969faff9e8827e23ff570addfde5c06fb57c97 --- devtools/client/inspector/inspector.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/devtools/client/inspector/inspector.js b/devtools/client/inspector/inspector.js index b961f31d1191..39880692008c 100644 --- a/devtools/client/inspector/inspector.js +++ b/devtools/client/inspector/inspector.js @@ -838,8 +838,6 @@ Inspector.prototype = { try { let hasSupportsHighlighters = yield this.target.actorHasMethod("inspector", "supportsHighlighters"); - let hasPickColorFromPage = - yield this.target.actorHasMethod("inspector", "pickColorFromPage"); let supportsHighlighters; if (hasSupportsHighlighters) { @@ -851,7 +849,7 @@ Inspector.prototype = { supportsHighlighters = nodeFront && nodeFront.isInHTMLDocument; } - return supportsHighlighters && hasPickColorFromPage; + return supportsHighlighters; } catch (e) { console.error(e); return false; @@ -1703,8 +1701,7 @@ Inspector.prototype = { * @return {Promise} resolves when the eyedropper is hidden. */ hideEyeDropper: function () { - // The eyedropper button doesn't exist, most probably because the actor doesn't - // support the pickColorFromPage, or because the page isn't HTML. + // The eyedropper button doesn't exist, most probably because the page isn't HTML. if (!this.eyeDropperButton) { return null; } From 4061ff0e690a47adc9ed0e3e1fea32b15dd64915 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 21 Nov 2017 00:53:51 +0100 Subject: [PATCH 20/78] Bug 1417781: Consider style structs as not equal if visited styles on them are changed. r=heycam This change should be also fine for the Gecko callers, but please double-check. MozReview-Commit-ID: 5ZntHeBt5wC --HG-- extra : rebase_source : d623693f690e933ccc67881795b3e4f5289e9fa4 --- layout/style/nsStyleContext.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/layout/style/nsStyleContext.cpp b/layout/style/nsStyleContext.cpp index ce7178720f0b..6ca18ffcd274 100644 --- a/layout/style/nsStyleContext.cpp +++ b/layout/style/nsStyleContext.cpp @@ -103,6 +103,7 @@ nsStyleContext::nsStyleContext(nsAtom* aPseudoTag, #endif } +// TODO(stylo-everywhere): Remove aSamePointerStructs. nsChangeHint nsStyleContext::CalcStyleDifference(nsStyleContext* aNewContext, uint32_t* aEqualStructs, @@ -302,8 +303,13 @@ nsStyleContext::CalcStyleDifference(nsStyleContext* aNewContext, if (!thisVis != !otherVis) { // One style context has a style-if-visited and the other doesn't. // Presume a difference. +#define STYLE_STRUCT(name_, fields_) \ + *aSamePointerStructs &= ~NS_STYLE_INHERIT_BIT(name_); \ + *aEqualStructs &= ~NS_STYLE_INHERIT_BIT(name_); +#include "nsCSSVisitedDependentPropList.h" +#undef STYLE_STRUCT hint |= nsChangeHint_RepaintFrame; - } else if (thisVis && !NS_IsHintSubset(nsChangeHint_RepaintFrame, hint)) { + } else if (thisVis) { // Both style contexts have a style-if-visited. bool change = false; @@ -314,12 +320,14 @@ nsStyleContext::CalcStyleDifference(nsStyleContext* aNewContext, // not having a style-if-visited), but not the other way around. #define STYLE_FIELD(name_) thisVisStruct->name_ != otherVisStruct->name_ #define STYLE_STRUCT(name_, fields_) \ - if (!change && (PEEK(name_) != nullptr)) { \ + if (PEEK(name_)) { \ const nsStyle##name_* thisVisStruct = \ thisVis->ThreadsafeStyle##name_(); \ const nsStyle##name_* otherVisStruct = \ otherVis->ThreadsafeStyle##name_(); \ if (MOZ_FOR_EACH_SEPARATED(STYLE_FIELD, (||), (), fields_)) { \ + *aSamePointerStructs &= ~NS_STYLE_INHERIT_BIT(name_); \ + *aEqualStructs &= ~NS_STYLE_INHERIT_BIT(name_); \ change = true; \ } \ } From f093ba24c0ffbf68ac055119a2e22a1bded46670 Mon Sep 17 00:00:00 2001 From: Timothy Guan-tin Chien Date: Tue, 21 Nov 2017 13:39:00 +0800 Subject: [PATCH 21/78] Bug 1419277 - Set Songti TC/SC as default zh-{CN/HK/TW} font in release r=m_kato MozReview-Commit-ID: 4TUNSFK0Fu9 --HG-- extra : rebase_source : c615125ba0e773c46f584c7a9c07e7344b33a46b --- modules/libpref/init/all.js | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 92bcf5f02564..09b3f6613f40 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -4153,29 +4153,17 @@ pref("font.name-list.monospace.x-western", "Courier, Courier New"); pref("font.name-list.cursive.x-western", "Apple Chancery"); pref("font.name-list.fantasy.x-western", "Papyrus"); -#ifdef EARLY_BETA_OR_EARLIER pref("font.name-list.serif.zh-CN", "Times, Songti SC, STSong, Heiti SC"); -#else -pref("font.name-list.serif.zh-CN", "Times, STSong, Heiti SC"); -#endif pref("font.name-list.sans-serif.zh-CN", "Helvetica, PingFang SC, STHeiti, Heiti SC"); pref("font.name-list.monospace.zh-CN", "Courier, PingFang SC, STHeiti, Heiti SC"); pref("font.name-list.cursive.zh-CN", "Kaiti SC"); -#ifdef EARLY_BETA_OR_EARLIER pref("font.name-list.serif.zh-TW", "Times, Songti TC, LiSong Pro, Heiti TC"); -#else -pref("font.name-list.serif.zh-TW", "Times, LiSong Pro, Heiti TC"); -#endif pref("font.name-list.sans-serif.zh-TW", "Helvetica, PingFang TC, Heiti TC, LiHei Pro"); pref("font.name-list.monospace.zh-TW", "Courier, PingFang TC, Heiti TC, LiHei Pro"); pref("font.name-list.cursive.zh-TW", "Kaiti TC"); -#ifdef EARLY_BETA_OR_EARLIER pref("font.name-list.serif.zh-HK", "Times, Songti TC, LiSong Pro, Heiti TC"); -#else -pref("font.name-list.serif.zh-HK", "Times, LiSong Pro, Heiti TC"); -#endif pref("font.name-list.sans-serif.zh-HK", "Helvetica, PingFang TC, Heiti TC, LiHei Pro"); pref("font.name-list.monospace.zh-HK", "Courier, PingFang TC, Heiti TC, LiHei Pro"); pref("font.name-list.cursive.zh-HK", "Kaiti TC"); From a2128b4cba9fd51532fdbc23cc6973ca267a79be Mon Sep 17 00:00:00 2001 From: Timothy Guan-tin Chien Date: Tue, 21 Nov 2017 13:43:36 +0800 Subject: [PATCH 22/78] Bug 1419277 - Follow-up, remove old & duplicate fonts from macOS default r=m_kato Given that we only support macOS >= 10.9 nowadays, we don't need to consider fallbacks on old systems anymore. Removing LiHei Pro & LiSong Pro because they are old. Removing STSong & STHeiti because they are simply old font names aliased to new Songti/Heiti SC. MozReview-Commit-ID: BNYBjXCpQOr --HG-- extra : rebase_source : 4c19607d183ac4033c8bdc05bd05b92c906a5e9d --- modules/libpref/init/all.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index 09b3f6613f40..7a2ee1cd1a0e 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -4153,19 +4153,19 @@ pref("font.name-list.monospace.x-western", "Courier, Courier New"); pref("font.name-list.cursive.x-western", "Apple Chancery"); pref("font.name-list.fantasy.x-western", "Papyrus"); -pref("font.name-list.serif.zh-CN", "Times, Songti SC, STSong, Heiti SC"); -pref("font.name-list.sans-serif.zh-CN", "Helvetica, PingFang SC, STHeiti, Heiti SC"); -pref("font.name-list.monospace.zh-CN", "Courier, PingFang SC, STHeiti, Heiti SC"); +pref("font.name-list.serif.zh-CN", "Times, Songti SC, Heiti SC"); +pref("font.name-list.sans-serif.zh-CN", "Helvetica, PingFang SC, Heiti SC"); +pref("font.name-list.monospace.zh-CN", "Courier, PingFang SC, Heiti SC"); pref("font.name-list.cursive.zh-CN", "Kaiti SC"); -pref("font.name-list.serif.zh-TW", "Times, Songti TC, LiSong Pro, Heiti TC"); -pref("font.name-list.sans-serif.zh-TW", "Helvetica, PingFang TC, Heiti TC, LiHei Pro"); -pref("font.name-list.monospace.zh-TW", "Courier, PingFang TC, Heiti TC, LiHei Pro"); +pref("font.name-list.serif.zh-TW", "Times, Songti TC, Heiti TC"); +pref("font.name-list.sans-serif.zh-TW", "Helvetica, PingFang TC, Heiti TC"); +pref("font.name-list.monospace.zh-TW", "Courier, PingFang TC, Heiti TC"); pref("font.name-list.cursive.zh-TW", "Kaiti TC"); -pref("font.name-list.serif.zh-HK", "Times, Songti TC, LiSong Pro, Heiti TC"); -pref("font.name-list.sans-serif.zh-HK", "Helvetica, PingFang TC, Heiti TC, LiHei Pro"); -pref("font.name-list.monospace.zh-HK", "Courier, PingFang TC, Heiti TC, LiHei Pro"); +pref("font.name-list.serif.zh-HK", "Times, Songti TC, Heiti TC"); +pref("font.name-list.sans-serif.zh-HK", "Helvetica, PingFang TC, Heiti TC"); +pref("font.name-list.monospace.zh-HK", "Courier, PingFang TC, Heiti TC"); pref("font.name-list.cursive.zh-HK", "Kaiti TC"); // XP_MACOSX changes to default font sizes From 1e31c0d7b6579a0c1bd65ff5d1415bb2565f0a16 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Sun, 12 Nov 2017 08:38:56 +0900 Subject: [PATCH 23/78] Bug 1413181 - part 1: Redesign EditorBase::SplitNodeImpl() with EditorDOMPoint r=m_kato EditorBaseSplitNodeImpl() should be clean up with EditorDOMPoint which should be an argument to point the first point of right node (existing split node). MozReview-Commit-ID: DN0yHm9G9yT --HG-- extra : rebase_source : 256b4e2125e831b7be9e5c4aefc6f04c80e3c1f5 --- editor/libeditor/EditorBase.cpp | 159 +++++++++++++--------- editor/libeditor/EditorBase.h | 31 +++-- editor/libeditor/SplitNodeTransaction.cpp | 46 +++++-- 3 files changed, 155 insertions(+), 81 deletions(-) diff --git a/editor/libeditor/EditorBase.cpp b/editor/libeditor/EditorBase.cpp index a75549fd5fcc..f0011f164ca3 100644 --- a/editor/libeditor/EditorBase.cpp +++ b/editor/libeditor/EditorBase.cpp @@ -2904,18 +2904,32 @@ struct SavedRange final int32_t mEndOffset; }; -nsresult -EditorBase::SplitNodeImpl(nsIContent& aExistingRightNode, - int32_t aOffset, - nsIContent& aNewLeftNode) +void +EditorBase::SplitNodeImpl(const EditorDOMPoint& aStartOfRightNode, + nsIContent& aNewLeftNode, + ErrorResult& aError) { + if (NS_WARN_IF(aError.Failed())) { + return; + } + + // XXX Perhaps, aStartOfRightNode may be invalid if this is a redo + // operation after modifying DOM node with JS. + if (NS_WARN_IF(!aStartOfRightNode.IsSet())) { + aError.Throw(NS_ERROR_INVALID_ARG); + return; + } + MOZ_ASSERT(aStartOfRightNode.IsSetAndValid()); + // Remember all selection points. AutoTArray savedRanges; for (SelectionType selectionType : kPresentSelectionTypes) { SavedRange range; range.mSelection = GetSelection(selectionType); - if (selectionType == SelectionType::eNormal) { - NS_ENSURE_TRUE(range.mSelection, NS_ERROR_NULL_POINTER); + if (NS_WARN_IF(!range.mSelection && + selectionType == SelectionType::eNormal)) { + aError.Throw(NS_ERROR_FAILURE); + return; } else if (!range.mSelection) { // For non-normal selections, skip over the non-existing ones. continue; @@ -2924,6 +2938,8 @@ EditorBase::SplitNodeImpl(nsIContent& aExistingRightNode, for (uint32_t j = 0; j < range.mSelection->RangeCount(); ++j) { RefPtr r = range.mSelection->GetRangeAt(j); MOZ_ASSERT(r->IsPositioned()); + // XXX Looks like that SavedRange should have mStart and mEnd which + // are RangeBoundary. Then, we can avoid to compute offset here. range.mStartContainer = r->GetStartContainer(); range.mStartOffset = r->StartOffset(); range.mEndContainer = r->GetEndContainer(); @@ -2933,54 +2949,69 @@ EditorBase::SplitNodeImpl(nsIContent& aExistingRightNode, } } - nsCOMPtr parent = aExistingRightNode.GetParentNode(); - NS_ENSURE_TRUE(parent, NS_ERROR_NULL_POINTER); - - ErrorResult rv; - nsCOMPtr refNode = &aExistingRightNode; - parent->InsertBefore(aNewLeftNode, refNode, rv); - NS_ENSURE_TRUE(!rv.Failed(), rv.StealNSResult()); - - // Split the children between the two nodes. At this point, - // aExistingRightNode has all the children. Move all the children whose - // index is < aOffset to aNewLeftNode. - if (aOffset < 0) { - // This means move no children - return NS_OK; + nsCOMPtr parent = aStartOfRightNode.Container()->GetParentNode(); + if (NS_WARN_IF(!parent)) { + aError.Throw(NS_ERROR_FAILURE); + return; } - // If it's a text node, just shuffle around some text - if (aExistingRightNode.GetAsText() && aNewLeftNode.GetAsText()) { - // Fix right node - nsAutoString leftText; - aExistingRightNode.GetAsText()->SubstringData(0, aOffset, leftText); - aExistingRightNode.GetAsText()->DeleteData(0, aOffset); - // Fix left node - aNewLeftNode.GetAsText()->SetData(leftText); - } else { - // Otherwise it's an interior node, so shuffle around the children. Go - // through list backwards so deletes don't interfere with the iteration. - nsCOMPtr childNodes = aExistingRightNode.ChildNodes(); - for (int32_t i = aOffset - 1; i >= 0; i--) { - nsCOMPtr childNode = childNodes->Item(i); - if (childNode) { - aExistingRightNode.RemoveChild(*childNode, rv); - if (!rv.Failed()) { - nsCOMPtr firstChild = aNewLeftNode.GetFirstChild(); - aNewLeftNode.InsertBefore(*childNode, firstChild, rv); + parent->InsertBefore(aNewLeftNode, aStartOfRightNode.Container(), + aError); + if (NS_WARN_IF(aError.Failed())) { + return; + } + + // At this point, the existing right node has all the children. Move all + // the children which are before aStartOfRightNode. + if (!aStartOfRightNode.IsStartOfContainer()) { + // If it's a text node, just shuffle around some text + Text* rightAsText = aStartOfRightNode.Container()->GetAsText(); + Text* leftAsText = aNewLeftNode.GetAsText(); + if (rightAsText && leftAsText) { + // Fix right node + nsAutoString leftText; + rightAsText->SubstringData(0, aStartOfRightNode.Offset(), + leftText); + rightAsText->DeleteData(0, aStartOfRightNode.Offset()); + // Fix left node + leftAsText->GetAsText()->SetData(leftText); + } else { + MOZ_DIAGNOSTIC_ASSERT(!rightAsText && !leftAsText); + // Otherwise it's an interior node, so shuffle around the children. Go + // through list backwards so deletes don't interfere with the iteration. + // FYI: It's okay to use raw pointer for caching existing right node since + // it's already grabbed by aStartOfRightNode. + nsINode* existingRightNode = aStartOfRightNode.Container(); + nsCOMPtr childNodes = existingRightNode->ChildNodes(); + // XXX This is wrong loop range if some children has already gone. + // This will be fixed by a later patch. + for (int32_t i = aStartOfRightNode.Offset() - 1; i >= 0; i--) { + nsCOMPtr childNode = childNodes->Item(i); + MOZ_RELEASE_ASSERT(childNode); + existingRightNode->RemoveChild(*childNode, aError); + if (NS_WARN_IF(aError.Failed())) { + break; } - } - if (rv.Failed()) { - break; + nsCOMPtr firstChild = aNewLeftNode.GetFirstChild(); + aNewLeftNode.InsertBefore(*childNode, firstChild, aError); + NS_WARNING_ASSERTION(!aError.Failed(), + "Failed to insert a child which is removed from the right node into " + "the left node"); } } } + // XXX Why do we ignore an error while moving nodes from the right node to + // the left node? + aError.SuppressException(); + // Handle selection nsCOMPtr ps = GetPresShell(); if (ps) { ps->FlushPendingNotifications(FlushType::Frames); } + NS_WARNING_ASSERTION(!Destroyed(), + "The editor is destroyed during splitting a node"); bool shouldSetSelection = GetShouldTxnSetSelection(); @@ -2991,11 +3022,16 @@ EditorBase::SplitNodeImpl(nsIContent& aExistingRightNode, // If we have not seen the selection yet, clear all of its ranges. if (range.mSelection != previousSelection) { - nsresult rv = range.mSelection->RemoveAllRanges(); - NS_ENSURE_SUCCESS(rv, rv); + range.mSelection->RemoveAllRanges(aError); + if (NS_WARN_IF(aError.Failed())) { + return; + } previousSelection = range.mSelection; } + // XXX Looks like that we don't need to modify normal selection here + // because selection will be modified by the caller if + // GetShouldTxnSetSelection() will return true. if (shouldSetSelection && range.mSelection->Type() == SelectionType::eNormal) { // If the editor should adjust the selection, don't bother restoring @@ -3004,19 +3040,21 @@ EditorBase::SplitNodeImpl(nsIContent& aExistingRightNode, } // Split the selection into existing node and new node. - if (range.mStartContainer == &aExistingRightNode) { - if (range.mStartOffset < aOffset) { + if (range.mStartContainer == aStartOfRightNode.Container()) { + if (static_cast(range.mStartOffset) < + aStartOfRightNode.Offset()) { range.mStartContainer = &aNewLeftNode; } else { - range.mStartOffset -= aOffset; + range.mStartOffset -= aStartOfRightNode.Offset(); } } - if (range.mEndContainer == &aExistingRightNode) { - if (range.mEndOffset < aOffset) { + if (range.mEndContainer == aStartOfRightNode.Container()) { + if (static_cast(range.mEndOffset) < + aStartOfRightNode.Offset()) { range.mEndContainer = &aNewLeftNode; } else { - range.mEndOffset -= aOffset; + range.mEndOffset -= aStartOfRightNode.Offset(); } } @@ -3026,19 +3064,18 @@ EditorBase::SplitNodeImpl(nsIContent& aExistingRightNode, range.mEndContainer, range.mEndOffset, getter_AddRefs(newRange)); - NS_ENSURE_SUCCESS(rv, rv); - rv = range.mSelection->AddRange(newRange); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + aError.Throw(rv); + return; + } + range.mSelection->AddRange(*newRange, aError); + if (NS_WARN_IF(aError.Failed())) { + return; + } } - if (shouldSetSelection) { - // Editor wants us to set selection at split point. - RefPtr selection = GetSelection(); - NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER); - selection->Collapse(&aNewLeftNode, aOffset); - } - - return NS_OK; + // We don't need to set selection here because the caller should do that + // in any case. } nsresult diff --git a/editor/libeditor/EditorBase.h b/editor/libeditor/EditorBase.h index 4c039e32f874..e8ab09c7d853 100644 --- a/editor/libeditor/EditorBase.h +++ b/editor/libeditor/EditorBase.h @@ -731,18 +731,27 @@ public: void StopPreservingSelection(); /** - * SplitNode() creates a new node identical to an existing node, and split - * the contents between the two nodes - * @param aExistingRightNode The node to split. It will become the new - * node's next sibling. - * @param aOffset The offset of aExistingRightNode's - * content|children to do the split at - * @param aNewLeftNode The new node resulting from the split, becomes - * aExistingRightNode's previous sibling. + * SplitNodeImpl() creates a new node (left node) identical to an existing + * node (right node), and split the contents between the same point in both + * nodes. + * + * @param aStartOfRightNode The point to split. Its container will be + * the right node, i.e., become the new node's + * next sibling. And the point will be start + * of the right node. + * @param aNewLeftNode The new node called as left node, so, this + * becomes the container of aPointToSplit's + * previous sibling. + * @param aError Must have not already failed. + * If succeed to insert aLeftNode before the + * right node and remove unnecessary contents + * (and collapse selection at end of the left + * node if necessary), returns no error. + * Otherwise, an error. */ - nsresult SplitNodeImpl(nsIContent& aExistingRightNode, - int32_t aOffset, - nsIContent& aNewLeftNode); + void SplitNodeImpl(const EditorDOMPoint& aStartOfRightNode, + nsIContent& aNewLeftNode, + ErrorResult& aError); /** * JoinNodes() takes 2 nodes and merge their content|children. diff --git a/editor/libeditor/SplitNodeTransaction.cpp b/editor/libeditor/SplitNodeTransaction.cpp index 8965b5399fd3..9f798eb7df19 100644 --- a/editor/libeditor/SplitNodeTransaction.cpp +++ b/editor/libeditor/SplitNodeTransaction.cpp @@ -47,26 +47,54 @@ SplitNodeTransaction::DoTransaction() } // Create a new node - ErrorResult rv; + ErrorResult error; // Don't use .downcast directly because AsContent has an assertion we want - nsCOMPtr clone = mExistingRightNode->CloneNode(false, rv); - NS_ASSERTION(!rv.Failed() && clone, "Could not create clone"); - NS_ENSURE_TRUE(!rv.Failed() && clone, rv.StealNSResult()); + nsCOMPtr clone = mExistingRightNode->CloneNode(false, error); + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); + } + if (NS_WARN_IF(!clone)) { + return NS_ERROR_UNEXPECTED; + } mNewLeftNode = dont_AddRef(clone.forget().take()->AsContent()); mEditorBase->MarkNodeDirty(mExistingRightNode->AsDOMNode()); // Get the parent node mParent = mExistingRightNode->GetParentNode(); - NS_ENSURE_TRUE(mParent, NS_ERROR_NULL_POINTER); + if (NS_WARN_IF(!mParent)) { + return NS_ERROR_FAILURE; + } // Insert the new node - rv = mEditorBase->SplitNodeImpl(*mExistingRightNode, mOffset, *mNewLeftNode); + int32_t offset = + std::min(std::max(mOffset, 0), + static_cast(mExistingRightNode->Length())); + mEditorBase->SplitNodeImpl(EditorDOMPoint(mExistingRightNode, offset), + *mNewLeftNode, error); + // XXX Really odd. The result of SplitNodeImpl() is respected only when + // we shouldn't set selection. Otherwise, it's overridden by the + // result of Selection.Collapse(). if (mEditorBase->GetShouldTxnSetSelection()) { + NS_WARNING_ASSERTION(!mEditorBase->Destroyed(), + "The editor has gone but SplitNodeTransaction keeps trying to modify " + "Selection"); RefPtr selection = mEditorBase->GetSelection(); - NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER); - rv = selection->Collapse(mNewLeftNode, mOffset); + if (NS_WARN_IF(!selection)) { + return NS_ERROR_FAILURE; + } + if (NS_WARN_IF(error.Failed())) { + // XXX This must be a bug. + error.SuppressException(); + } + MOZ_ASSERT(offset == mNewLeftNode->Length()); + EditorRawDOMPoint atEndOfLeftNode(mNewLeftNode, mNewLeftNode->Length()); + selection->Collapse(atEndOfLeftNode, error); } - return rv.StealNSResult(); + + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); + } + return NS_OK; } NS_IMETHODIMP From 9f55e711841510b7bf474db82bc1b10f5daec64b Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Sun, 12 Nov 2017 09:27:19 +0900 Subject: [PATCH 24/78] Bug 1413181 - part 2: SplitNodeTransaction should store start of existing right node with RangeBoundary r=m_kato Make SplitNodeTransaction stores start of existing right node (which will be split) instead of split point as a pair of the right node and offset in it. MozReview-Commit-ID: 2DIpJGSuNaC --HG-- extra : rebase_source : 13949bdddc30c59462e7fea7fadf29f015ab8d3a --- editor/libeditor/EditorBase.cpp | 5 +- editor/libeditor/SplitNodeTransaction.cpp | 88 ++++++++++++++--------- editor/libeditor/SplitNodeTransaction.h | 25 +++---- 3 files changed, 70 insertions(+), 48 deletions(-) diff --git a/editor/libeditor/EditorBase.cpp b/editor/libeditor/EditorBase.cpp index f0011f164ca3..cd78f5bf6f66 100644 --- a/editor/libeditor/EditorBase.cpp +++ b/editor/libeditor/EditorBase.cpp @@ -2876,8 +2876,11 @@ already_AddRefed EditorBase::CreateTxnForSplitNode(nsIContent& aNode, uint32_t aOffset) { + int32_t offset = + std::min(std::max(static_cast(aOffset), 0), + static_cast(aNode.Length())); RefPtr transaction = - new SplitNodeTransaction(*this, aNode, aOffset); + new SplitNodeTransaction(*this, EditorRawDOMPoint(&aNode, offset)); return transaction.forget(); } diff --git a/editor/libeditor/SplitNodeTransaction.cpp b/editor/libeditor/SplitNodeTransaction.cpp index 9f798eb7df19..5de1f40179b6 100644 --- a/editor/libeditor/SplitNodeTransaction.cpp +++ b/editor/libeditor/SplitNodeTransaction.cpp @@ -6,6 +6,7 @@ #include "SplitNodeTransaction.h" #include "mozilla/EditorBase.h" // for EditorBase +#include "mozilla/EditorDOMPoint.h" // for RangeBoundary, EditorRawDOMPoint #include "mozilla/dom/Selection.h" #include "nsAString.h" #include "nsDebug.h" // for NS_ASSERTION, etc. @@ -16,13 +17,14 @@ namespace mozilla { using namespace dom; -SplitNodeTransaction::SplitNodeTransaction(EditorBase& aEditorBase, - nsIContent& aNode, - int32_t aOffset) +SplitNodeTransaction::SplitNodeTransaction( + EditorBase& aEditorBase, + const EditorRawDOMPoint& aStartOfRightNode) : mEditorBase(&aEditorBase) - , mExistingRightNode(&aNode) - , mOffset(aOffset) + , mStartOfRightNode(aStartOfRightNode) { + MOZ_DIAGNOSTIC_ASSERT(aStartOfRightNode.IsSet()); + MOZ_DIAGNOSTIC_ASSERT(aStartOfRightNode.Container()->IsContent()); } SplitNodeTransaction::~SplitNodeTransaction() @@ -31,6 +33,7 @@ SplitNodeTransaction::~SplitNodeTransaction() NS_IMPL_CYCLE_COLLECTION_INHERITED(SplitNodeTransaction, EditTransactionBase, mEditorBase, + mStartOfRightNode, mParent, mNewLeftNode) @@ -42,14 +45,17 @@ NS_INTERFACE_MAP_END_INHERITING(EditTransactionBase) NS_IMETHODIMP SplitNodeTransaction::DoTransaction() { - if (NS_WARN_IF(!mEditorBase)) { + if (NS_WARN_IF(!mEditorBase) || + NS_WARN_IF(!mStartOfRightNode.IsSet())) { return NS_ERROR_NOT_INITIALIZED; } + MOZ_ASSERT(mStartOfRightNode.IsSetAndValid()); // Create a new node ErrorResult error; // Don't use .downcast directly because AsContent has an assertion we want - nsCOMPtr clone = mExistingRightNode->CloneNode(false, error); + nsCOMPtr clone = + mStartOfRightNode.Container()->CloneNode(false, error); if (NS_WARN_IF(error.Failed())) { return error.StealNSResult(); } @@ -57,19 +63,16 @@ SplitNodeTransaction::DoTransaction() return NS_ERROR_UNEXPECTED; } mNewLeftNode = dont_AddRef(clone.forget().take()->AsContent()); - mEditorBase->MarkNodeDirty(mExistingRightNode->AsDOMNode()); + mEditorBase->MarkNodeDirty(mStartOfRightNode.Container()->AsDOMNode()); // Get the parent node - mParent = mExistingRightNode->GetParentNode(); + mParent = mStartOfRightNode.Container()->GetParentNode(); if (NS_WARN_IF(!mParent)) { return NS_ERROR_FAILURE; } // Insert the new node - int32_t offset = - std::min(std::max(mOffset, 0), - static_cast(mExistingRightNode->Length())); - mEditorBase->SplitNodeImpl(EditorDOMPoint(mExistingRightNode, offset), + mEditorBase->SplitNodeImpl(EditorDOMPoint(mStartOfRightNode), *mNewLeftNode, error); // XXX Really odd. The result of SplitNodeImpl() is respected only when // we shouldn't set selection. Otherwise, it's overridden by the @@ -86,7 +89,7 @@ SplitNodeTransaction::DoTransaction() // XXX This must be a bug. error.SuppressException(); } - MOZ_ASSERT(offset == mNewLeftNode->Length()); + MOZ_ASSERT(mStartOfRightNode.Offset() == mNewLeftNode->Length()); EditorRawDOMPoint atEndOfLeftNode(mNewLeftNode, mNewLeftNode->Length()); selection->Collapse(atEndOfLeftNode, error); } @@ -102,12 +105,16 @@ SplitNodeTransaction::UndoTransaction() { if (NS_WARN_IF(!mEditorBase) || NS_WARN_IF(!mNewLeftNode) || - NS_WARN_IF(!mParent)) { + NS_WARN_IF(!mParent) || + NS_WARN_IF(!mStartOfRightNode.IsSet())) { return NS_ERROR_NOT_INITIALIZED; } // This assumes Do inserted the new node in front of the prior existing node - return mEditorBase->JoinNodesImpl(mExistingRightNode, mNewLeftNode, mParent); + // XXX Perhaps, we should reset mStartOfRightNode with current first child + // of the right node. + return mEditorBase->JoinNodesImpl(mStartOfRightNode.Container(), mNewLeftNode, + mParent); } /* Redo cannot simply resplit the right node, because subsequent transactions @@ -118,37 +125,52 @@ NS_IMETHODIMP SplitNodeTransaction::RedoTransaction() { if (NS_WARN_IF(!mNewLeftNode) || - NS_WARN_IF(!mParent)) { + NS_WARN_IF(!mParent) || + NS_WARN_IF(!mStartOfRightNode.IsSet())) { return NS_ERROR_NOT_INITIALIZED; } - ErrorResult rv; // First, massage the existing node so it is in its post-split state - if (mExistingRightNode->GetAsText()) { - rv = mExistingRightNode->GetAsText()->DeleteData(0, mOffset); - NS_ENSURE_TRUE(!rv.Failed(), rv.StealNSResult()); + if (mStartOfRightNode.Container()->IsNodeOfType(nsINode::eTEXT)) { + Text* rightNodeAsText = mStartOfRightNode.Container()->GetAsText(); + MOZ_DIAGNOSTIC_ASSERT(rightNodeAsText); + nsresult rv = + rightNodeAsText->DeleteData(0, mStartOfRightNode.Offset()); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } } else { - nsCOMPtr child = mExistingRightNode->GetFirstChild(); + nsCOMPtr child = mStartOfRightNode.Container()->GetFirstChild(); nsCOMPtr nextSibling; - for (int32_t i=0; i < mOffset; i++) { - if (rv.Failed()) { - return rv.StealNSResult(); - } - if (!child) { + for (uint32_t i = 0; i < mStartOfRightNode.Offset(); i++) { + // XXX This must be bad behavior. Perhaps, we should work with + // mStartOfRightNode::GetChildAtOffset(). Even if some children + // before the right node have been inserted or removed, we should + // move all children before the right node because user must focus + // on the right node, so, it must be the expected behavior. + if (NS_WARN_IF(!child)) { return NS_ERROR_NULL_POINTER; } nextSibling = child->GetNextSibling(); - mExistingRightNode->RemoveChild(*child, rv); - if (!rv.Failed()) { - mNewLeftNode->AppendChild(*child, rv); + ErrorResult error; + mStartOfRightNode.Container()->RemoveChild(*child, error); + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); + } + mNewLeftNode->AppendChild(*child, error); + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); } child = nextSibling; } } // Second, re-insert the left node into the tree - nsCOMPtr refNode = mExistingRightNode; - mParent->InsertBefore(*mNewLeftNode, refNode, rv); - return rv.StealNSResult(); + ErrorResult error; + mParent->InsertBefore(*mNewLeftNode, mStartOfRightNode.Container(), error); + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); + } + return NS_OK; } diff --git a/editor/libeditor/SplitNodeTransaction.h b/editor/libeditor/SplitNodeTransaction.h index 4c50143ecc43..8215381db424 100644 --- a/editor/libeditor/SplitNodeTransaction.h +++ b/editor/libeditor/SplitNodeTransaction.h @@ -6,6 +6,7 @@ #ifndef SplitNodeTransaction_h #define SplitNodeTransaction_h +#include "mozilla/EditorDOMPoint.h" // for RangeBoundary, EditorRawDOMPoint #include "mozilla/EditTransactionBase.h" // for EditTxn, etc. #include "nsCOMPtr.h" // for nsCOMPtr #include "nsCycleCollectionParticipant.h" @@ -27,14 +28,14 @@ class SplitNodeTransaction final : public EditTransactionBase { public: /** - * @param aEditorBase The provider of core editing operations - * @param aNode The node to split - * @param aOffset The location within aNode to do the split. aOffset may - * refer to children of aNode, or content of aNode. The - * left node will have child|content 0..aOffset-1. + * @param aEditorBase The provider of core editing operations. + * @param aStartOfRightNode The point to split. Its container will be + * the right node, i.e., become the new node's + * next sibling. And the point will be start + * of the right node. */ - SplitNodeTransaction(EditorBase& aEditorBase, nsIContent& aNode, - int32_t aOffset); + SplitNodeTransaction(EditorBase& aEditorBase, + const EditorRawDOMPoint& aStartOfRightNode); NS_DECL_ISUPPORTS_INHERITED NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(SplitNodeTransaction, @@ -51,13 +52,9 @@ protected: RefPtr mEditorBase; - // The node to operate upon. - nsCOMPtr mExistingRightNode; - - // The offset into mExistingRightNode where its children are split. mOffset - // is the index of the first child in the right node. -1 means the new node - // gets no children. - int32_t mOffset; + // The container is existing right node (will be split). + // The point referring this is start of the right node after it's split. + RangeBoundary mStartOfRightNode; // The node we create when splitting mExistingRightNode. nsCOMPtr mNewLeftNode; From 070ede0cf48984bdb53f2c6e87524c23d317b14d Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Sun, 12 Nov 2017 11:30:30 +0900 Subject: [PATCH 25/78] Bug 1413181 - part 3: EditorBase::CreateTxnForSplitNode() and EditorBase::SplitNode() should take EditorRawDOMPoint to specify the start of right node r=m_kato EditorBase::CreateTxnForSplitNode() and EditorBase::SplitNode() takes a set of container and offset in it for specifying a point to split. Instead, they should take EditorRawDOMPoint for specifying start of right node. MozReview-Commit-ID: 5VwS8oudzIT --HG-- extra : rebase_source : 727948e5cf95f0713019f57ae9a007b85569fa56 --- editor/libeditor/EditorBase.cpp | 171 +++++++++++++++-------- editor/libeditor/EditorBase.h | 33 ++++- editor/libeditor/HTMLEditRules.cpp | 202 ++++++++++++++++----------- editor/libeditor/HTMLStyleEditor.cpp | 83 +++++++---- editor/libeditor/SelectionState.cpp | 43 +++--- editor/libeditor/SelectionState.h | 3 +- editor/libeditor/TextEditor.cpp | 31 ++-- 7 files changed, 353 insertions(+), 213 deletions(-) diff --git a/editor/libeditor/EditorBase.cpp b/editor/libeditor/EditorBase.cpp index cd78f5bf6f66..a19e32c51747 100644 --- a/editor/libeditor/EditorBase.cpp +++ b/editor/libeditor/EditorBase.cpp @@ -1424,7 +1424,7 @@ EditorBase::CreateNode(nsAtom* aTag, MOZ_ASSERT(aTag); MOZ_ASSERT(aPointToInsert.IsSetAndValid()); - // XXX We need to offset at new node to mRangeUpdater. Therefore, we need + // XXX We need offset at new node for mRangeUpdater. Therefore, we need // to compute the offset now but this is expensive. So, if it's possible, // we need to redesign mRangeUpdater as avoiding using indices. int32_t offset = static_cast(aPointToInsert.Offset()); @@ -1516,49 +1516,73 @@ EditorBase::SplitNode(nsIDOMNode* aNode, nsIDOMNode** aNewLeftNode) { nsCOMPtr node = do_QueryInterface(aNode); - NS_ENSURE_STATE(node); - ErrorResult rv; - nsCOMPtr newNode = SplitNode(*node, aOffset, rv); + if (NS_WARN_IF(!node)) { + return NS_ERROR_INVALID_ARG; + } + + int32_t offset = std::min(std::max(aOffset, 0), + static_cast(node->Length())); + ErrorResult error; + nsCOMPtr newNode = + SplitNode(EditorRawDOMPoint(node, offset), error); *aNewLeftNode = GetAsDOMNode(newNode.forget().take()); - return rv.StealNSResult(); + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); + } + return NS_OK; } -nsIContent* -EditorBase::SplitNode(nsIContent& aNode, - int32_t aOffset, - ErrorResult& aResult) +already_AddRefed +EditorBase::SplitNode(const EditorRawDOMPoint& aStartOfRightNode, + ErrorResult& aError) { + if (NS_WARN_IF(!aStartOfRightNode.IsSet()) || + NS_WARN_IF(!aStartOfRightNode.Container()->IsContent())) { + aError.Throw(NS_ERROR_INVALID_ARG); + return nullptr; + } + MOZ_ASSERT(aStartOfRightNode.IsSetAndValid()); + AutoRules beginRulesSniffing(this, EditAction::splitNode, nsIEditor::eNext); + // Different from CreateNode(), we need offset at start of right node only + // for WillSplitNode() and DidSplitNoe() since the offset is always same as + // the length of new left node. { AutoActionListenerArray listeners(mActionListeners); for (auto& listener : listeners) { - listener->WillSplitNode(aNode.AsDOMNode(), aOffset); + listener->WillSplitNode(aStartOfRightNode.Container()->AsDOMNode(), + aStartOfRightNode.Offset()); } } RefPtr transaction = - CreateTxnForSplitNode(aNode, aOffset); - aResult = DoTransaction(transaction); + CreateTxnForSplitNode(aStartOfRightNode); + aError = DoTransaction(transaction); - nsCOMPtr newNode = aResult.Failed() ? nullptr - : transaction->GetNewNode(); + nsCOMPtr newNode = transaction->GetNewNode(); + NS_WARNING_ASSERTION(newNode, "Failed to create a new left node"); - mRangeUpdater.SelAdjSplitNode(aNode, aOffset, newNode); + mRangeUpdater.SelAdjSplitNode(*aStartOfRightNode.Container()->AsContent(), + newNode); - nsresult rv = aResult.StealNSResult(); + nsresult rv = aError.StealNSResult(); { AutoActionListenerArray listeners(mActionListeners); for (auto& listener : listeners) { - listener->DidSplitNode(aNode.AsDOMNode(), aOffset, GetAsDOMNode(newNode), - rv); + listener->DidSplitNode(aStartOfRightNode.Container()->AsDOMNode(), + aStartOfRightNode.Offset(), + GetAsDOMNode(newNode), rv); } } // Note: result might be a success code, so we can't use Throw() to // set it on aResult. - aResult = rv; + aError = rv; + if (NS_WARN_IF(aError.Failed())) { + return nullptr; + } - return newNode; + return newNode.forget(); } NS_IMETHODIMP @@ -2873,14 +2897,11 @@ EditorBase::CreateTxnForDeleteText(nsGenericDOMDataNode& aCharData, } already_AddRefed -EditorBase::CreateTxnForSplitNode(nsIContent& aNode, - uint32_t aOffset) +EditorBase::CreateTxnForSplitNode(const EditorRawDOMPoint& aStartOfRightNode) { - int32_t offset = - std::min(std::max(static_cast(aOffset), 0), - static_cast(aNode.Length())); + MOZ_ASSERT(aStartOfRightNode.IsSetAndValid()); RefPtr transaction = - new SplitNodeTransaction(*this, EditorRawDOMPoint(&aNode, offset)); + new SplitNodeTransaction(*this, aStartOfRightNode); return transaction.forget(); } @@ -4063,9 +4084,17 @@ EditorBase::SplitNodeDeep(nsIContent& aNode, !nodeToSplit->GetAsText()) || (offset && offset != (int32_t)nodeToSplit->Length())) { didSplit = true; - ErrorResult rv; - nsCOMPtr newLeftNode = SplitNode(nodeToSplit, offset, rv); - NS_ENSURE_TRUE(!NS_FAILED(rv.StealNSResult()), -1); + ErrorResult error; + int32_t offsetAtStartOfRightNode = + std::min(std::max(offset, 0), + static_cast(nodeToSplit->Length())); + nsCOMPtr newLeftNode = + SplitNode(EditorRawDOMPoint(nodeToSplit, offsetAtStartOfRightNode), + error); + if (NS_WARN_IF(error.Failed())) { + error.SuppressException(); + return -1; + } rightNode = nodeToSplit; leftNode = newLeftNode; @@ -4359,42 +4388,60 @@ EditorBase::DeleteSelectionAndPrepareToCreateNode() nsCOMPtr node = selection->GetAnchorNode(); MOZ_ASSERT(node, "Selection has no ranges in it"); - if (node && node->IsNodeOfType(nsINode::eDATA_NODE)) { - NS_ASSERTION(node->GetParentNode(), - "It's impossible to insert into chardata with no parent -- " - "fix the caller"); - NS_ENSURE_STATE(node->GetParentNode()); + if (!node || !node->IsNodeOfType(nsINode::eDATA_NODE)) { + return NS_OK; + } - uint32_t offset = selection->AnchorOffset(); + NS_ASSERTION(node->GetParentNode(), + "It's impossible to insert into chardata with no parent -- " + "fix the caller"); + NS_ENSURE_STATE(node->GetParentNode()); - if (!offset) { - EditorRawDOMPoint atNode(node); - if (NS_WARN_IF(!atNode.IsSetAndValid())) { - return NS_ERROR_FAILURE; - } - nsresult rv = selection->Collapse(atNode); - MOZ_ASSERT(NS_SUCCEEDED(rv)); - NS_ENSURE_SUCCESS(rv, rv); - } else if (offset == node->Length()) { - EditorRawDOMPoint afterNode(node); - if (NS_WARN_IF(!afterNode.AdvanceOffset())) { - return NS_ERROR_FAILURE; - } - nsresult rv = selection->Collapse(afterNode); - MOZ_ASSERT(NS_SUCCEEDED(rv)); - NS_ENSURE_SUCCESS(rv, rv); - } else { - nsCOMPtr tmp; - nsresult rv = SplitNode(node->AsDOMNode(), offset, getter_AddRefs(tmp)); - NS_ENSURE_SUCCESS(rv, rv); - EditorRawDOMPoint atNode(node); - if (NS_WARN_IF(!atNode.IsSetAndValid())) { - return NS_ERROR_FAILURE; - } - rv = selection->Collapse(atNode); - MOZ_ASSERT(NS_SUCCEEDED(rv)); - NS_ENSURE_SUCCESS(rv, rv); + // XXX We want Selection::AnchorRef() + uint32_t offset = selection->AnchorOffset(); + + if (!offset) { + EditorRawDOMPoint atNode(node); + if (NS_WARN_IF(!atNode.IsSetAndValid())) { + return NS_ERROR_FAILURE; } + ErrorResult error; + selection->Collapse(atNode, error); + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); + } + return NS_OK; + } + + if (offset == node->Length()) { + EditorRawDOMPoint afterNode(node); + if (NS_WARN_IF(!afterNode.AdvanceOffset())) { + return NS_ERROR_FAILURE; + } + ErrorResult error; + selection->Collapse(afterNode, error); + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); + } + return NS_OK; + } + + EditorRawDOMPoint atStartOfRightNode(node, offset); + MOZ_ASSERT(atStartOfRightNode.IsSetAndValid()); + ErrorResult error; + nsCOMPtr newLeftNode = SplitNode(atStartOfRightNode, error); + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); + } + + EditorRawDOMPoint atRightNode(atStartOfRightNode.Container()); + if (NS_WARN_IF(!atRightNode.IsSet())) { + return NS_ERROR_FAILURE; + } + MOZ_ASSERT(atRightNode.IsSetAndValid()); + selection->Collapse(atRightNode, error); + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); } return NS_OK; } diff --git a/editor/libeditor/EditorBase.h b/editor/libeditor/EditorBase.h index e8ab09c7d853..ce9e2f2405eb 100644 --- a/editor/libeditor/EditorBase.h +++ b/editor/libeditor/EditorBase.h @@ -345,8 +345,23 @@ public: nsAtom* aAttribute = nullptr, const nsAString* aValue = nullptr); - nsIContent* SplitNode(nsIContent& aNode, int32_t aOffset, - ErrorResult& aResult); + + /** + * SplitNode() creates a transaction to create a new node (left node) + * identical to an existing node (right node), and split the contents + * between the same point in both nodes, then, execute the transaction. + * + * @param aStartOfRightNode The point to split. Its container will be + * the right node, i.e., become the new node's + * next sibling. And the point will be start + * of the right node. + * @param aError If succeed, returns no error. Otherwise, an + * error. + */ + already_AddRefed + SplitNode(const EditorRawDOMPoint& aStartOfRightNode, + ErrorResult& aResult); + nsresult JoinNodes(nsINode& aLeftNode, nsINode& aRightNode); nsresult MoveNode(nsIContent* aNode, nsINode* aParent, int32_t aOffset); @@ -538,8 +553,20 @@ protected: CreateTxnForDeleteCharacter(nsGenericDOMDataNode& aData, uint32_t aOffset, EDirection aDirection); + /** + * CreateTxnForSplitNode() creates a transaction to create a new node + * (left node) identical to an existing node (right node), and split the + * contents between the same point in both nodes. + * + * @param aStartOfRightNode The point to split. Its container will be + * the right node, i.e., become the new node's + * next sibling. And the point will be start + * of the right node. + * @return The new transaction to split the container of + * aStartOfRightNode. + */ already_AddRefed - CreateTxnForSplitNode(nsIContent& aNode, uint32_t aOffset); + CreateTxnForSplitNode(const EditorRawDOMPoint& aStartOfRightNode); already_AddRefed CreateTxnForJoinNode(nsINode& aLeftNode, nsINode& aRightNode); diff --git a/editor/libeditor/HTMLEditRules.cpp b/editor/libeditor/HTMLEditRules.cpp index 76f6a8043bdf..7be0017e6f10 100644 --- a/editor/libeditor/HTMLEditRules.cpp +++ b/editor/libeditor/HTMLEditRules.cpp @@ -3497,7 +3497,6 @@ HTMLEditRules::WillMakeList(Selection* aSelection, // or whatever is approriate. Wohoo! uint32_t listCount = arrayOfNodes.Length(); - nsCOMPtr curParent; nsCOMPtr curList, prevListItem; for (uint32_t i = 0; i < listCount; i++) { @@ -3506,8 +3505,6 @@ HTMLEditRules::WillMakeList(Selection* aSelection, NS_ENSURE_STATE(arrayOfNodes[i]->IsContent()); OwningNonNull curNode = *arrayOfNodes[i]->AsContent(); nsCOMPtr curChild(curNode); - int32_t offset; - curParent = EditorBase::GetNodeLocation(curNode, &offset); // make sure we don't assemble content that is in different table cells // into the same list. respect table cell boundaries when listifying. @@ -3558,22 +3555,31 @@ HTMLEditRules::WillMakeList(Selection* aSelection, continue; } + EditorRawDOMPoint atCurNode(curNode); + if (NS_WARN_IF(!atCurNode.IsSet())) { + return NS_ERROR_FAILURE; + } + MOZ_ASSERT(atCurNode.IsSetAndValid()); if (HTMLEditUtils::IsListItem(curNode)) { NS_ENSURE_STATE(mHTMLEditor); - if (!curParent->IsHTMLElement(listType)) { + if (!atCurNode.Container()->IsHTMLElement(listType)) { // list item is in wrong type of list. if we don't have a curList, // split the old list and make a new list of correct type. if (!curList || EditorUtils::IsDescendantOf(*curNode, *curList)) { NS_ENSURE_STATE(mHTMLEditor); - NS_ENSURE_STATE(curParent->IsContent()); - ErrorResult rv; - nsCOMPtr splitNode = - mHTMLEditor->SplitNode(*curParent->AsContent(), offset, rv); - NS_ENSURE_TRUE(!rv.Failed(), rv.StealNSResult()); - newBlock = splitNode ? splitNode->AsElement() : nullptr; + if (NS_WARN_IF(!atCurNode.Container()->IsContent())) { + return NS_ERROR_FAILURE; + } + ErrorResult error; + nsCOMPtr newLeftNode = + mHTMLEditor->SplitNode(atCurNode, error); + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); + } + newBlock = newLeftNode ? newLeftNode->AsElement() : nullptr; NS_ENSURE_STATE(mHTMLEditor); - EditorRawDOMPoint atCurParent(curParent); - curList = mHTMLEditor->CreateNode(listType, atCurParent); + EditorRawDOMPoint atParentOfCurNode(atCurNode.Container()); + curList = mHTMLEditor->CreateNode(listType, atParentOfCurNode); NS_ENSURE_STATE(curList); } // move list item to new list @@ -3592,8 +3598,8 @@ HTMLEditRules::WillMakeList(Selection* aSelection, // item is in right type of list. But we might still have to move it. // and we might need to convert list item types. if (!curList) { - curList = curParent->AsElement(); - } else if (curParent != curList) { + curList = atCurNode.Container()->AsElement(); + } else if (atCurNode.Container() != curList) { // move list item to new list NS_ENSURE_STATE(mHTMLEditor); rv = mHTMLEditor->MoveNode(curNode, curList, -1); @@ -3639,7 +3645,9 @@ HTMLEditRules::WillMakeList(Selection* aSelection, // need to make a list to put things in if we haven't already, if (!curList) { + nsCOMPtr curParent(atCurNode.Container()); nsCOMPtr curChild(curNode); + int32_t offset = atCurNode.Offset(); rv = SplitAsNeeded(listType, curParent, offset, address_of(curChild)); NS_ENSURE_SUCCESS(rv, rv); @@ -3650,6 +3658,10 @@ HTMLEditRules::WillMakeList(Selection* aSelection, mNewBlock = curList; // curList is now the correct thing to put curNode in prevListItem = nullptr; + + // atCurChild is now referring the right node with mOffset but + // referring the left node with mRef. So, invalidate it now. + atCurNode.Clear(); } // if curNode isn't a list item, we must wrap it in one @@ -6031,31 +6043,32 @@ HTMLEditRules::GetNodesForOperation( NS_ENSURE_STATE(mHTMLEditor); RefPtr htmlEditor(mHTMLEditor); - int32_t rangeCount = aArrayOfRanges.Length(); if (aTouchContent == TouchContent::yes) { // Split text nodes. This is necessary, since GetPromotedPoint() may return a // range ending in a text node in case where part of a pre-formatted // elements needs to be moved. - for (int32_t i = 0; i < rangeCount; i++) { - RefPtr r = aArrayOfRanges[i]; - nsCOMPtr endContainer = r->GetEndContainer(); - if (!endContainer->IsNodeOfType(nsINode::eTEXT)) { + for (RefPtr& range : aArrayOfRanges) { + EditorDOMPoint atEnd(range->EndRef()); + if (NS_WARN_IF(!atEnd.IsSet()) || + !atEnd.Container()->IsNodeOfType(nsINode::eTEXT)) { continue; } - int32_t offset = r->EndOffset(); - if (0 < offset && - offset < static_cast(endContainer->Length())) { + if (!atEnd.IsStartOfContainer() && !atEnd.IsEndOfContainer()) { // Split the text node. - nsCOMPtr tempNode; - nsresult rv = htmlEditor->SplitNode(endContainer->AsDOMNode(), offset, - getter_AddRefs(tempNode)); - NS_ENSURE_SUCCESS(rv, rv); + ErrorResult error; + nsCOMPtr newLeftNode = + htmlEditor->SplitNode(atEnd.AsRaw(), error); + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); + } // Correct the range. // The new end parent becomes the parent node of the text. - nsCOMPtr newParent = endContainer->GetParent(); - r->SetEnd(newParent, newParent->IndexOf(endContainer)); + // XXX We want nsRange::SetEnd(const RawRangeBoundary&) + EditorRawDOMPoint atContainerOfSplitNode(atEnd.Container()); + range->SetEnd(atContainerOfSplitNode.Container(), + atContainerOfSplitNode.Offset()); } } } @@ -6065,13 +6078,13 @@ HTMLEditRules::GetNodesForOperation( if (aTouchContent == TouchContent::yes) { nsTArray> rangeItemArray; - rangeItemArray.AppendElements(rangeCount); + rangeItemArray.AppendElements(aArrayOfRanges.Length()); // First register ranges for special editor gravity - for (int32_t i = 0; i < rangeCount; i++) { - rangeItemArray[i] = new RangeItem(); - rangeItemArray[i]->StoreRange(aArrayOfRanges[0]); - htmlEditor->mRangeUpdater.RegisterRangeItem(rangeItemArray[i]); + for (auto& rangeItem : rangeItemArray) { + rangeItem = new RangeItem(); + rangeItem->StoreRange(aArrayOfRanges[0]); + htmlEditor->mRangeUpdater.RegisterRangeItem(rangeItem); aArrayOfRanges.RemoveElementAt(0); } // Now bust up inlines. @@ -6756,10 +6769,7 @@ HTMLEditRules::ReturnInParagraph(Selection& aSelection, bool splitAfterNewBR = false; nsCOMPtr brNode; - // Point to split aParentDivOrP. - // XXX We should use EditorDOMPoint. - nsCOMPtr containerAtSplitPoint = atStartOfSelection.Container(); - int32_t offsetAtSplitPoint = atStartOfSelection.Offset(); + EditorDOMPoint pointToSplitParentDivOrP(atStartOfSelection); EditorRawDOMPoint pointToInsertBR; if (doesCRCreateNewP && @@ -6792,18 +6802,18 @@ HTMLEditRules::ReturnInParagraph(Selection& aSelection, } } else { if (doesCRCreateNewP) { - ErrorResult errorResult; - containerAtSplitPoint = - htmlEditor->SplitNode(*containerAtSplitPoint->AsContent(), - offsetAtSplitPoint, errorResult); - if (NS_WARN_IF(errorResult.Failed())) { - return EditActionResult(errorResult.StealNSResult()); + ErrorResult error; + nsCOMPtr newLeftDivOrP = + htmlEditor->SplitNode(pointToSplitParentDivOrP.AsRaw(), error); + if (NS_WARN_IF(error.Failed())) { + return EditActionResult(error.StealNSResult()); } + pointToSplitParentDivOrP.Set(newLeftDivOrP, newLeftDivOrP->Length()); } // We need to put new
after the left node if given node was split // above. - pointToInsertBR.Set(containerAtSplitPoint); + pointToInsertBR.Set(pointToSplitParentDivOrP.Container()); DebugOnly advanced = pointToInsertBR.AdvanceOffset(); NS_WARNING_ASSERTION(advanced, "Failed to advance offset to after the container of selection start"); @@ -6844,13 +6854,16 @@ HTMLEditRules::ReturnInParagraph(Selection& aSelection, pointToInsertBR.Offset()); if (splitAfterNewBR) { // We split the parent after the br we've just inserted. - containerAtSplitPoint = pointToInsertBR.Container(); - offsetAtSplitPoint = pointToInsertBR.Offset() + 1; + pointToSplitParentDivOrP.Set(brNode); + DebugOnly advanced = pointToSplitParentDivOrP.AdvanceOffset(); + NS_WARNING_ASSERTION(advanced, + "Failed to advance offset after the new
"); } } EditActionResult result( SplitParagraph(aSelection, aParentDivOrP, brNode, - *containerAtSplitPoint, offsetAtSplitPoint)); + *pointToSplitParentDivOrP.Container(), + pointToSplitParentDivOrP.Offset())); result.MarkAsHandled(); if (NS_WARN_IF(result.Failed())) { return result; @@ -6941,32 +6954,36 @@ HTMLEditRules::ReturnInListItem(Selection& aSelection, // Get the item parent and the active editing host. nsCOMPtr root = htmlEditor->GetActiveEditingHost(); - nsCOMPtr list = aListItem.GetParentElement(); - int32_t itemOffset = list ? list->IndexOf(&aListItem) : -1; - // If we are in an empty item, then we want to pop up out of the list, but // only if prefs say it's okay and if the parent isn't the active editing // host. bool isEmpty; nsresult rv = IsEmptyBlock(aListItem, &isEmpty, MozBRCounts::no); NS_ENSURE_SUCCESS(rv, rv); - if (isEmpty && root != list && mReturnInEmptyLIKillsList) { - // Get the list offset now -- before we might eventually split the list - nsCOMPtr listParent = list->GetParentNode(); - int32_t offset = listParent ? listParent->IndexOf(list) : -1; - + if (isEmpty && root != aListItem.GetParentElement() && + mReturnInEmptyLIKillsList) { + nsCOMPtr leftListNode = aListItem.GetParent(); // Are we the last list item in the list? if (!htmlEditor->IsLastEditableChild(&aListItem)) { // We need to split the list! - ErrorResult rv; - htmlEditor->SplitNode(*list, itemOffset, rv); - NS_ENSURE_TRUE(!rv.Failed(), rv.StealNSResult()); + EditorRawDOMPoint atListItem(&aListItem); + ErrorResult error; + leftListNode = htmlEditor->SplitNode(atListItem, error); + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); + } } // Are we in a sublist? - if (HTMLEditUtils::IsList(listParent)) { + EditorRawDOMPoint atNextSiblingOfLeftList(leftListNode); + DebugOnly advanced = atNextSiblingOfLeftList.AdvanceOffset(); + NS_WARNING_ASSERTION(advanced, + "Failed to advance offset after the right list node"); + if (HTMLEditUtils::IsList(atNextSiblingOfLeftList.Container())) { // If so, move item out of this list and into the grandparent list - rv = htmlEditor->MoveNode(&aListItem, listParent, offset + 1); + rv = htmlEditor->MoveNode(&aListItem, + atNextSiblingOfLeftList.Container(), + atNextSiblingOfLeftList.Offset()); NS_ENSURE_SUCCESS(rv, rv); rv = aSelection.Collapse(&aListItem, 0); NS_ENSURE_SUCCESS(rv, rv); @@ -6978,11 +6995,10 @@ HTMLEditRules::ReturnInListItem(Selection& aSelection, // Time to insert a paragraph nsAtom& paraAtom = DefaultParagraphSeparator(); // We want a wrapper even if we separate with
- EditorRawDOMPoint atNextListItem(listParent, offset + 1); RefPtr pNode = htmlEditor->CreateNode(¶Atom == nsGkAtoms::br ? nsGkAtoms::p : ¶Atom, - atNextListItem); + atNextSiblingOfLeftList); NS_ENSURE_STATE(pNode); // Append a
to it @@ -8343,47 +8359,67 @@ HTMLEditRules::PopListItem(nsIContent& aListItem, nsCOMPtr kungFuDeathGrip(&aListItem); Unused << kungFuDeathGrip; - nsCOMPtr curParent = aListItem.GetParentNode(); - if (NS_WARN_IF(!curParent)) { - return NS_ERROR_FAILURE; - } - int32_t offset = curParent->IndexOf(&aListItem); - if (!HTMLEditUtils::IsListItem(&aListItem)) { + if (NS_WARN_IF(!mHTMLEditor) || + NS_WARN_IF(!aListItem.GetParent()) || + NS_WARN_IF(!aListItem.GetParent()->GetParentNode()) || + !HTMLEditUtils::IsListItem(&aListItem)) { return NS_ERROR_FAILURE; } // if it's first or last list item, don't need to split the list // otherwise we do. - nsCOMPtr curParPar = curParent->GetParentNode(); - int32_t parOffset = curParPar ? curParPar->IndexOf(curParent) : -1; - - NS_ENSURE_STATE(mHTMLEditor); bool bIsFirstListItem = mHTMLEditor->IsFirstEditableChild(&aListItem); - - NS_ENSURE_STATE(mHTMLEditor); + MOZ_ASSERT(mHTMLEditor); bool bIsLastListItem = mHTMLEditor->IsLastEditableChild(&aListItem); + MOZ_ASSERT(mHTMLEditor); + nsCOMPtr leftListNode = aListItem.GetParent(); if (!bIsFirstListItem && !bIsLastListItem) { + if (NS_WARN_IF(!mHTMLEditor)) { + return NS_ERROR_FAILURE; + } + + EditorDOMPoint atListItem(&aListItem); + if (NS_WARN_IF(!atListItem.IsSet())) { + return NS_ERROR_INVALID_ARG; + } + MOZ_ASSERT(atListItem.IsSetAndValid()); + // split the list - ErrorResult rv; - NS_ENSURE_STATE(mHTMLEditor); - mHTMLEditor->SplitNode(*curParent->AsContent(), offset, rv); - if (NS_WARN_IF(rv.Failed())) { - return rv.StealNSResult(); + ErrorResult error; + leftListNode = mHTMLEditor->SplitNode(atListItem.AsRaw(), error); + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); + } + if (NS_WARN_IF(!mHTMLEditor)) { + return NS_ERROR_FAILURE; } } + // In most cases, insert the list item into the new left list node.. + EditorDOMPoint pointToInsertListItem(leftListNode); + if (NS_WARN_IF(!pointToInsertListItem.IsSet())) { + return NS_ERROR_FAILURE; + } + MOZ_ASSERT(pointToInsertListItem.IsSetAndValid()); + + // But when the list item was the first child of the right list, it should + // be inserted into the next sibling of the list. This allows user to hit + // Enter twice at a list item breaks the parent list node. if (!bIsFirstListItem) { - parOffset++; + DebugOnly advanced = pointToInsertListItem.AdvanceOffset(); + NS_WARNING_ASSERTION(advanced, + "Failed to advance offset to right list node"); } - NS_ENSURE_STATE(mHTMLEditor); - nsresult rv = mHTMLEditor->MoveNode(&aListItem, curParPar, parOffset); + nsresult rv = + mHTMLEditor->MoveNode(&aListItem, pointToInsertListItem.Container(), + pointToInsertListItem.Offset()); NS_ENSURE_SUCCESS(rv, rv); // unwrap list item contents if they are no longer in a list - if (!HTMLEditUtils::IsList(curParPar) && + if (!HTMLEditUtils::IsList(pointToInsertListItem.Container()) && HTMLEditUtils::IsListItem(&aListItem)) { NS_ENSURE_STATE(mHTMLEditor); rv = mHTMLEditor->RemoveBlockContainer(*aListItem.AsElement()); diff --git a/editor/libeditor/HTMLStyleEditor.cpp b/editor/libeditor/HTMLStyleEditor.cpp index 01973f36151e..2311e3f047ed 100644 --- a/editor/libeditor/HTMLStyleEditor.cpp +++ b/editor/libeditor/HTMLStyleEditor.cpp @@ -285,37 +285,49 @@ HTMLEditor::SetInlinePropertyOnTextNode(Text& aText, return NS_OK; } - // Do we need to split the text node? - ErrorResult rv; - nsCOMPtr text = &aText; - if (uint32_t(aEndOffset) != aText.Length()) { + // Make the range an independent node. + nsCOMPtr textNodeForTheRange = &aText; + + // Split at the end of the range. + EditorRawDOMPoint atEnd(textNodeForTheRange, aEndOffset); + if (!atEnd.IsEndOfContainer()) { // We need to split off back of text node - text = SplitNode(*text, aEndOffset, rv); - NS_ENSURE_TRUE(!rv.Failed(), rv.StealNSResult()); + ErrorResult error; + textNodeForTheRange = SplitNode(atEnd, error); + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); + } } - if (aStartOffset) { + // Split at the start of the range. + EditorRawDOMPoint atStart(textNodeForTheRange, aStartOffset); + if (!atStart.IsStartOfContainer()) { // We need to split off front of text node - SplitNode(*text, aStartOffset, rv); - NS_ENSURE_TRUE(!rv.Failed(), rv.StealNSResult()); + ErrorResult error; + nsCOMPtr newLeftNode = SplitNode(atStart, error); + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); + } + Unused << newLeftNode; } if (aAttribute) { // Look for siblings that are correct type of node - nsIContent* sibling = GetPriorHTMLSibling(text); + nsIContent* sibling = GetPriorHTMLSibling(textNodeForTheRange); if (IsSimpleModifiableNode(sibling, &aProperty, aAttribute, &aValue)) { // Previous sib is already right kind of inline node; slide this over - return MoveNode(text, sibling, -1); + return MoveNode(textNodeForTheRange, sibling, -1); } - sibling = GetNextHTMLSibling(text); + sibling = GetNextHTMLSibling(textNodeForTheRange); if (IsSimpleModifiableNode(sibling, &aProperty, aAttribute, &aValue)) { // Following sib is already right kind of inline node; slide this over - return MoveNode(text, sibling, 0); + return MoveNode(textNodeForTheRange, sibling, 0); } } // Reparent the node inside inline node with appropriate {attribute,value} - return SetInlinePropertyOnNode(*text, aProperty, aAttribute, aValue); + return SetInlinePropertyOnNode(*textNodeForTheRange, + aProperty, aAttribute, aValue); } nsresult @@ -1436,47 +1448,58 @@ HTMLEditor::RelativeFontChangeOnTextNode(FontSize aDir, return NS_OK; } - OwningNonNull node = aTextNode; - - // Do we need to split the text node? - // -1 is a magic value meaning to the end of node if (aEndOffset == -1) { aEndOffset = aTextNode.Length(); } - ErrorResult rv; - if ((uint32_t)aEndOffset != aTextNode.Length()) { + // Make the range an independent node. + nsCOMPtr textNodeForTheRange = &aTextNode; + + // Split at the end of the range. + EditorRawDOMPoint atEnd(textNodeForTheRange, aEndOffset); + if (!atEnd.IsEndOfContainer()) { // We need to split off back of text node - node = SplitNode(node, aEndOffset, rv); - NS_ENSURE_TRUE(!rv.Failed(), rv.StealNSResult()); + ErrorResult error; + textNodeForTheRange = SplitNode(atEnd, error); + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); + } } - if (aStartOffset) { + + // Split at the start of the range. + EditorRawDOMPoint atStart(textNodeForTheRange, aStartOffset); + if (!atStart.IsStartOfContainer()) { // We need to split off front of text node - SplitNode(node, aStartOffset, rv); - NS_ENSURE_TRUE(!rv.Failed(), rv.StealNSResult()); + ErrorResult error; + nsCOMPtr newLeftNode = SplitNode(atStart, error); + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); + } + Unused << newLeftNode; } // Look for siblings that are correct type of node nsAtom* nodeType = aDir == FontSize::incr ? nsGkAtoms::big : nsGkAtoms::small; - nsCOMPtr sibling = GetPriorHTMLSibling(node); + nsCOMPtr sibling = GetPriorHTMLSibling(textNodeForTheRange); if (sibling && sibling->IsHTMLElement(nodeType)) { // Previous sib is already right kind of inline node; slide this over - nsresult rv = MoveNode(node, sibling, -1); + nsresult rv = MoveNode(textNodeForTheRange, sibling, -1); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; } - sibling = GetNextHTMLSibling(node); + sibling = GetNextHTMLSibling(textNodeForTheRange); if (sibling && sibling->IsHTMLElement(nodeType)) { // Following sib is already right kind of inline node; slide this over - nsresult rv = MoveNode(node, sibling, 0); + nsresult rv = MoveNode(textNodeForTheRange, sibling, 0); NS_ENSURE_SUCCESS(rv, rv); return NS_OK; } // Else reparent the node inside font node with appropriate relative size - nsCOMPtr newElement = InsertContainerAbove(node, nodeType); + nsCOMPtr newElement = + InsertContainerAbove(textNodeForTheRange, nodeType); NS_ENSURE_STATE(newElement); return NS_OK; diff --git a/editor/libeditor/SelectionState.cpp b/editor/libeditor/SelectionState.cpp index 58ba94622a97..e901d3421243 100644 --- a/editor/libeditor/SelectionState.cpp +++ b/editor/libeditor/SelectionState.cpp @@ -303,42 +303,47 @@ RangeUpdater::SelAdjDeleteNode(nsINode* aNode) } nsresult -RangeUpdater::SelAdjSplitNode(nsIContent& aOldRightNode, - int32_t aOffset, +RangeUpdater::SelAdjSplitNode(nsIContent& aRightNode, nsIContent* aNewLeftNode) { if (mLock) { // lock set by Will/DidReplaceParent, etc... return NS_OK; } - NS_ENSURE_TRUE(aNewLeftNode, NS_ERROR_NULL_POINTER); + if (NS_WARN_IF(!aNewLeftNode)) { + return NS_ERROR_FAILURE; + } + size_t count = mArray.Length(); if (!count) { return NS_OK; } - nsCOMPtr parent = aOldRightNode.GetParentNode(); - int32_t offset = parent ? parent->IndexOf(&aOldRightNode) : -1; + EditorRawDOMPoint atLeftNode(aNewLeftNode); + nsresult rv = SelAdjInsertNode(atLeftNode.Container(), atLeftNode.Offset()); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } - // first part is same as inserting aNewLeftnode - nsresult rv = SelAdjInsertNode(parent, offset - 1); - NS_ENSURE_SUCCESS(rv, rv); + // If point in the ranges is in left node, change its container to the left + // node. If point in the ranges is in right node, subtract numbers of + // children moved to left node from the offset. + int32_t lengthOfLeftNode = aNewLeftNode->Length(); + for (RefPtr& item : mArray) { + if (NS_WARN_IF(!item)) { + return NS_ERROR_FAILURE; + } - // next step is to check for range enpoints inside aOldRightNode - for (size_t i = 0; i < count; i++) { - RangeItem* item = mArray[i]; - NS_ENSURE_TRUE(item, NS_ERROR_NULL_POINTER); - - if (item->mStartContainer == &aOldRightNode) { - if (item->mStartOffset > aOffset) { - item->mStartOffset -= aOffset; + if (item->mStartContainer == &aRightNode) { + if (item->mStartOffset > lengthOfLeftNode) { + item->mStartOffset -= lengthOfLeftNode; } else { item->mStartContainer = aNewLeftNode; } } - if (item->mEndContainer == &aOldRightNode) { - if (item->mEndOffset > aOffset) { - item->mEndOffset -= aOffset; + if (item->mEndContainer == &aRightNode) { + if (item->mEndOffset > lengthOfLeftNode) { + item->mEndOffset -= lengthOfLeftNode; } else { item->mEndContainer = aNewLeftNode; } diff --git a/editor/libeditor/SelectionState.h b/editor/libeditor/SelectionState.h index f3de3955ef6c..97e34220f622 100644 --- a/editor/libeditor/SelectionState.h +++ b/editor/libeditor/SelectionState.h @@ -112,8 +112,7 @@ public: nsresult SelAdjCreateNode(nsINode* aParent, int32_t aPosition); nsresult SelAdjInsertNode(nsINode* aParent, int32_t aPosition); void SelAdjDeleteNode(nsINode* aNode); - nsresult SelAdjSplitNode(nsIContent& aOldRightNode, int32_t aOffset, - nsIContent* aNewLeftNode); + nsresult SelAdjSplitNode(nsIContent& aRightNode, nsIContent* aNewLeftNode); nsresult SelAdjJoinNodes(nsINode& aLeftNode, nsINode& aRightNode, nsINode& aParent, diff --git a/editor/libeditor/TextEditor.cpp b/editor/libeditor/TextEditor.cpp index 86a213e056ad..c0a3e31862e6 100644 --- a/editor/libeditor/TextEditor.cpp +++ b/editor/libeditor/TextEditor.cpp @@ -444,35 +444,38 @@ TextEditor::CreateBRImpl(nsCOMPtr* aInOutParent, int32_t theOffset = *aInOutOffset; RefPtr brNode; if (IsTextNode(node)) { - EditorRawDOMPoint atNode(node); - if (NS_WARN_IF(!atNode.IsSetAndValid())) { + EditorRawDOMPoint pointToInsertBrNode(node); + if (NS_WARN_IF(!pointToInsertBrNode.IsSetAndValid())) { return NS_ERROR_FAILURE; } if (!theOffset) { // we are already set to go } else if (theOffset == static_cast(node->Length())) { // update offset to point AFTER the text node - atNode.AdvanceOffset(); + pointToInsertBrNode.AdvanceOffset(); } else { + MOZ_DIAGNOSTIC_ASSERT(theOffset < static_cast(node->Length())); // split the text node - ErrorResult rv; - SplitNode(*node->AsContent(), theOffset, rv); - if (NS_WARN_IF(rv.Failed())) { - return rv.StealNSResult(); + EditorRawDOMPoint atStartOfNewLine(node, theOffset); + ErrorResult error; + nsCOMPtr newLeftNode = SplitNode(atStartOfNewLine, error); + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); } - atNode.Clear(); - atNode.Set(node); + // The right node offset in the parent is now changed. Recompute it. + pointToInsertBrNode.Set(node); + Unused << newLeftNode; } // create br - brNode = CreateNode(nsGkAtoms::br, atNode); + brNode = CreateNode(nsGkAtoms::br, pointToInsertBrNode); if (NS_WARN_IF(!brNode)) { return NS_ERROR_FAILURE; } - *aInOutParent = GetAsDOMNode(atNode.Container()); - *aInOutOffset = atNode.Offset() + 1; + *aInOutParent = GetAsDOMNode(pointToInsertBrNode.Container()); + *aInOutOffset = pointToInsertBrNode.Offset() + 1; } else { - EditorRawDOMPoint atTheOffset(node, theOffset); - brNode = CreateNode(nsGkAtoms::br, atTheOffset); + EditorRawDOMPoint pointToInsertBrNode(node, theOffset); + brNode = CreateNode(nsGkAtoms::br, pointToInsertBrNode); if (NS_WARN_IF(!brNode)) { return NS_ERROR_FAILURE; } From 11db05dbea7d01e1da18bc62054d925d2377a39a Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Mon, 13 Nov 2017 23:52:16 +0900 Subject: [PATCH 26/78] Bug 1413181 - part 4: Redesign nsIEditActionListener::DidSplitNode() r=m_kato nsIEditActionListner::DidSplitNode() takes 4 arguments, the right node, old offset in the old right node before splitting, the new left node and nsresult. Computing offset for this doesn't make sense because it's always same as the length of the left node. Additionally, nobody currently use nsersult. So, we can get rid of it now. Fortunately, nobody including comm-central and BlueGriffon implements WillSplitNode(). So, we can get rid of it. However, removing interface method should be done in a follow up bug. So, we can remove offset computation in EditorBase::SplitNode() completely in the future. MozReview-Commit-ID: JWj34SjBNJh --HG-- extra : rebase_source : f0e1ed0e466dc8217c1a0ab1722790883a7efd1f --- editor/libeditor/EditorBase.cpp | 15 +++++++-------- editor/libeditor/HTMLEditRules.cpp | 4 +--- editor/libeditor/HTMLEditRules.h | 4 ++-- editor/nsIEditActionListener.idl | 11 +++++------ editor/txtsvc/nsTextServicesDocument.cpp | 10 ++-------- editor/txtsvc/nsTextServicesDocument.h | 6 ++---- .../spellcheck/src/mozInlineSpellChecker.cpp | 9 +++++---- 7 files changed, 24 insertions(+), 35 deletions(-) diff --git a/editor/libeditor/EditorBase.cpp b/editor/libeditor/EditorBase.cpp index a19e32c51747..9b62c2950e96 100644 --- a/editor/libeditor/EditorBase.cpp +++ b/editor/libeditor/EditorBase.cpp @@ -1546,11 +1546,14 @@ EditorBase::SplitNode(const EditorRawDOMPoint& aStartOfRightNode, AutoRules beginRulesSniffing(this, EditAction::splitNode, nsIEditor::eNext); // Different from CreateNode(), we need offset at start of right node only - // for WillSplitNode() and DidSplitNoe() since the offset is always same as - // the length of new left node. + // for WillSplitNode() since the offset is always same as the length of new + // left node. { AutoActionListenerArray listeners(mActionListeners); for (auto& listener : listeners) { + // XXX Unfortunately, we need to compute offset here because the container + // may be a data node like text node. However, nobody implements this + // method actually. So, we should get rid of this in a follow up bug. listener->WillSplitNode(aStartOfRightNode.Container()->AsDOMNode(), aStartOfRightNode.Offset()); } @@ -1566,18 +1569,14 @@ EditorBase::SplitNode(const EditorRawDOMPoint& aStartOfRightNode, mRangeUpdater.SelAdjSplitNode(*aStartOfRightNode.Container()->AsContent(), newNode); - nsresult rv = aError.StealNSResult(); { AutoActionListenerArray listeners(mActionListeners); for (auto& listener : listeners) { listener->DidSplitNode(aStartOfRightNode.Container()->AsDOMNode(), - aStartOfRightNode.Offset(), - GetAsDOMNode(newNode), rv); + GetAsDOMNode(newNode)); } } - // Note: result might be a success code, so we can't use Throw() to - // set it on aResult. - aError = rv; + if (NS_WARN_IF(aError.Failed())) { return nullptr; } diff --git a/editor/libeditor/HTMLEditRules.cpp b/editor/libeditor/HTMLEditRules.cpp index 7be0017e6f10..0b1bddacbf45 100644 --- a/editor/libeditor/HTMLEditRules.cpp +++ b/editor/libeditor/HTMLEditRules.cpp @@ -8679,9 +8679,7 @@ HTMLEditRules::WillSplitNode(nsIDOMNode* aExistingRightNode, NS_IMETHODIMP HTMLEditRules::DidSplitNode(nsIDOMNode* aExistingRightNode, - int32_t aOffset, - nsIDOMNode* aNewLeftNode, - nsresult aResult) + nsIDOMNode* aNewLeftNode) { if (!mListenerEnabled) { return NS_OK; diff --git a/editor/libeditor/HTMLEditRules.h b/editor/libeditor/HTMLEditRules.h index 4fce64d2a1c5..99debebb236a 100644 --- a/editor/libeditor/HTMLEditRules.h +++ b/editor/libeditor/HTMLEditRules.h @@ -118,8 +118,8 @@ public: NS_IMETHOD DidDeleteNode(nsIDOMNode* aChild, nsresult aResult) override; NS_IMETHOD WillSplitNode(nsIDOMNode* aExistingRightNode, int32_t aOffset) override; - NS_IMETHOD DidSplitNode(nsIDOMNode* aExistingRightNode, int32_t aOffset, - nsIDOMNode* aNewLeftNode, nsresult aResult) override; + NS_IMETHOD DidSplitNode(nsIDOMNode* aExistingRightNode, + nsIDOMNode* aNewLeftNode) override; NS_IMETHOD WillJoinNodes(nsIDOMNode* aLeftNode, nsIDOMNode* aRightNode, nsIDOMNode* aParent) override; NS_IMETHOD DidJoinNodes(nsIDOMNode* aLeftNode, nsIDOMNode* aRightNode, diff --git a/editor/nsIEditActionListener.idl b/editor/nsIEditActionListener.idl index 8c88c8833efc..edeb079a6d81 100644 --- a/editor/nsIEditActionListener.idl +++ b/editor/nsIEditActionListener.idl @@ -98,14 +98,13 @@ interface nsIEditActionListener : nsISupports{ /** * Called after the editor splits a node. - * @param aExistingRightNode the node to split. It will become the new node's next sibling. - * @param aOffset the offset of aExistingRightNode's content|children to do the split at - * @param aNewLeftNode [OUT] the new node resulting from the split, becomes aExistingRightNode's previous sibling. + * @param aExistingRightNode The node which was split. It will become the + * next sibling of the new left node. + * @param aNewLeftNode The new node resulting from the split, becomes + * the previous sibling of aExistingRightNode. */ void DidSplitNode(in nsIDOMNode aExistingRightNode, - in long aOffset, - in nsIDOMNode aNewLeftNode, - in nsresult aResult); + in nsIDOMNode aNewLeftNode); /** * Called before the editor joins 2 nodes. diff --git a/editor/txtsvc/nsTextServicesDocument.cpp b/editor/txtsvc/nsTextServicesDocument.cpp index cab0f821efc7..c367c45e379d 100644 --- a/editor/txtsvc/nsTextServicesDocument.cpp +++ b/editor/txtsvc/nsTextServicesDocument.cpp @@ -1620,15 +1620,9 @@ nsTextServicesDocument::DidDeleteNode(nsIDOMNode *aChild, nsresult aResult) } NS_IMETHODIMP -nsTextServicesDocument::DidSplitNode(nsIDOMNode *aExistingRightNode, - int32_t aOffset, - nsIDOMNode *aNewLeftNode, - nsresult aResult) +nsTextServicesDocument::DidSplitNode(nsIDOMNode* aExistingRightNode, + nsIDOMNode* aNewLeftNode) { - //**** KDEBUG **** - // printf("** SplitNode: 0x%.8x %d 0x%.8x\n", aExistingRightNode, aOffset, aNewLeftNode); - // fflush(stdout); - //**** KDEBUG **** return NS_OK; } diff --git a/editor/txtsvc/nsTextServicesDocument.h b/editor/txtsvc/nsTextServicesDocument.h index b84f1e2ad5ad..aa0a92803785 100644 --- a/editor/txtsvc/nsTextServicesDocument.h +++ b/editor/txtsvc/nsTextServicesDocument.h @@ -105,10 +105,8 @@ public: NS_IMETHOD WillSplitNode(nsIDOMNode * aExistingRightNode, int32_t aOffset) override; - NS_IMETHOD DidSplitNode(nsIDOMNode *aExistingRightNode, - int32_t aOffset, - nsIDOMNode *aNewLeftNode, - nsresult aResult) override; + NS_IMETHOD DidSplitNode(nsIDOMNode* aExistingRightNode, + nsIDOMNode* aNewLeftNode) override; NS_IMETHOD WillJoinNodes(nsIDOMNode *aLeftNode, nsIDOMNode *aRightNode, diff --git a/extensions/spellcheck/src/mozInlineSpellChecker.cpp b/extensions/spellcheck/src/mozInlineSpellChecker.cpp index 8f78cec70330..177e1a15dbf6 100644 --- a/extensions/spellcheck/src/mozInlineSpellChecker.cpp +++ b/extensions/spellcheck/src/mozInlineSpellChecker.cpp @@ -1092,15 +1092,16 @@ NS_IMETHODIMP mozInlineSpellChecker::DidDeleteNode(nsIDOMNode *aChild, nsresult return NS_OK; } -NS_IMETHODIMP mozInlineSpellChecker::WillSplitNode(nsIDOMNode *aExistingRightNode, int32_t aOffset) +NS_IMETHODIMP +mozInlineSpellChecker::WillSplitNode(nsIDOMNode* aExistingRightNode, + int32_t aOffset) { return NS_OK; } NS_IMETHODIMP -mozInlineSpellChecker::DidSplitNode(nsIDOMNode *aExistingRightNode, - int32_t aOffset, - nsIDOMNode *aNewLeftNode, nsresult aResult) +mozInlineSpellChecker::DidSplitNode(nsIDOMNode* aExistingRightNode, + nsIDOMNode* aNewLeftNode) { return SpellCheckBetweenNodes(aNewLeftNode, 0, aNewLeftNode, 0); } From d94b3f01526646de0185f66588a56c549f25df5a Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Thu, 16 Nov 2017 13:26:58 +0900 Subject: [PATCH 27/78] Bug 1413181 - part 5: HTMLEditRules::SplitParagraph() should take EditorRawDOMPoint instead of a set of container node and offset r=m_kato Although, we need to make WSRunObject::PrepareToSplitAcrossBlocks() in another bug, we should do it now for making HTMLEditRules::ReturnInParagraph() implementation simpler. MozReview-Commit-ID: AoMYqAEgCaV --HG-- extra : rebase_source : cdfb16379f4ecab2a2694aeb283edd111fc81e95 --- editor/libeditor/HTMLEditRules.cpp | 26 +++++++++++++------------- editor/libeditor/HTMLEditRules.h | 22 ++++++++++++---------- 2 files changed, 25 insertions(+), 23 deletions(-) diff --git a/editor/libeditor/HTMLEditRules.cpp b/editor/libeditor/HTMLEditRules.cpp index 0b1bddacbf45..4f5a8aaefcee 100644 --- a/editor/libeditor/HTMLEditRules.cpp +++ b/editor/libeditor/HTMLEditRules.cpp @@ -6861,9 +6861,8 @@ HTMLEditRules::ReturnInParagraph(Selection& aSelection, } } EditActionResult result( - SplitParagraph(aSelection, aParentDivOrP, brNode, - *pointToSplitParentDivOrP.Container(), - pointToSplitParentDivOrP.Offset())); + SplitParagraph(aSelection, aParentDivOrP, pointToSplitParentDivOrP.AsRaw(), + brNode)); result.MarkAsHandled(); if (NS_WARN_IF(result.Failed())) { return result; @@ -6873,10 +6872,9 @@ HTMLEditRules::ReturnInParagraph(Selection& aSelection, nsresult HTMLEditRules::SplitParagraph(Selection& aSelection, - Element& aPara, - nsIContent* aBRNode, - nsINode& aSelNode, - int32_t aOffset) + Element& aParentDivOrP, + const EditorRawDOMPoint& aStartOfRightNode, + nsIContent* aNextBRNode) { if (NS_WARN_IF(!mHTMLEditor)) { return NS_ERROR_NOT_AVAILABLE; @@ -6887,26 +6885,28 @@ HTMLEditRules::SplitParagraph(Selection& aSelection, // split para // get ws code to adjust any ws nsCOMPtr leftPara, rightPara; - nsCOMPtr selNode = &aSelNode; + nsCOMPtr selNode = aStartOfRightNode.Container(); + int32_t selOffset = aStartOfRightNode.Offset(); nsresult rv = WSRunObject::PrepareToSplitAcrossBlocks(htmlEditor, - address_of(selNode), &aOffset); + address_of(selNode), &selOffset); // XXX When it fails, why do we need to return selection node? (Why can the // caller trust the result even when it returns error?) NS_ENSURE_SUCCESS(rv, rv); // split the paragraph NS_ENSURE_STATE(selNode->IsContent()); int32_t offset = - htmlEditor->SplitNodeDeep(aPara, *selNode->AsContent(), aOffset, + htmlEditor->SplitNodeDeep(aParentDivOrP, *selNode->AsContent(), selOffset, HTMLEditor::EmptyContainers::yes, getter_AddRefs(leftPara), getter_AddRefs(rightPara)); if (NS_WARN_IF(offset == -1)) { return NS_ERROR_FAILURE; } - // get rid of the break, if it is visible (otherwise it may be needed to prevent an empty p) - if (aBRNode && htmlEditor->IsVisibleBRElement(aBRNode)) { - rv = htmlEditor->DeleteNode(aBRNode); + // Get rid of the break, if it is visible (otherwise it may be needed to + // prevent an empty p). + if (aNextBRNode && htmlEditor->IsVisibleBRElement(aNextBRNode)) { + rv = htmlEditor->DeleteNode(aNextBRNode); NS_ENSURE_SUCCESS(rv, rv); } diff --git a/editor/libeditor/HTMLEditRules.h b/editor/libeditor/HTMLEditRules.h index 99debebb236a..6be6c5d8ce0c 100644 --- a/editor/libeditor/HTMLEditRules.h +++ b/editor/libeditor/HTMLEditRules.h @@ -314,18 +314,20 @@ protected: /** * SplitParagraph() splits the parent block, aPara, at aSelNode - aOffset. * - * @param aSelection The selection. - * @param aPara The parent block to be split. - * @param aBRNode Next
node if there is. Otherwise, nullptr. - * If this is not nullptr, the
node may be removed. - * @param aSelNode Set the selection container to split aPara at. - * @param aOffset Set the offset in the container. + * @param aSelection The selection. + * @param aParentDivOrP The parent block to be split. This must be

+ * or

element. + * @param aStartOfRightNode The point to be start of right node after + * split. This must be descendant of + * aParentDivOrP. + * @param aNextBRNode Next
node if there is. Otherwise, nullptr. + * If this is not nullptr, the
node may be + * removed. */ nsresult SplitParagraph(Selection& aSelection, - Element& aPara, - nsIContent* aBRNode, - nsINode& aSelNode, - int32_t aOffset); + Element& aParentDivOrP, + const EditorRawDOMPoint& aStartOfRightNode, + nsIContent* aBRNode); nsresult ReturnInListItem(Selection& aSelection, Element& aHeader, nsINode& aNode, int32_t aOffset); From bf54c638b24ef9dac8eb977311e8d189ddbf7123 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Mon, 13 Nov 2017 14:35:16 +0900 Subject: [PATCH 28/78] Bug 1413181 - part 6: Rename mozilla::EditorBase::EmptyContainers enum class to mozilla::SplitAtEdges for making its values clearer r=m_kato EmptyContainers::yes and EmptyContainers::no are not so clear name what they mean. They means whether NodeSplitDeep() creates or won't create empty nodes when split point is at start edge or end edge of an element. This patch renames them to SplitAtEdges::eDoNotCreateEmptyContainer and SplitAtEdges::eAllowToCreateEmptyContainer and make HTMLEditor::InsertNodeAtPoint() use it instead of an bool argument. Additionally, the argument of NodeSplitDeep() is now not optional because this difference is really important when you read around the callers. MozReview-Commit-ID: 9hpMRkVDvCg --HG-- extra : rebase_source : ee892361d66c9c9c5ed45ee9d3321474257ac417 --- editor/libeditor/EditorBase.cpp | 4 +- editor/libeditor/EditorBase.h | 21 ++++++-- editor/libeditor/HTMLEditRules.cpp | 53 +++++++++++---------- editor/libeditor/HTMLEditor.cpp | 19 ++++---- editor/libeditor/HTMLEditor.h | 2 +- editor/libeditor/HTMLEditorDataTransfer.cpp | 28 +++++++---- editor/libeditor/HTMLStyleEditor.cpp | 4 +- 7 files changed, 83 insertions(+), 48 deletions(-) diff --git a/editor/libeditor/EditorBase.cpp b/editor/libeditor/EditorBase.cpp index 9b62c2950e96..7fba450e8600 100644 --- a/editor/libeditor/EditorBase.cpp +++ b/editor/libeditor/EditorBase.cpp @@ -4060,7 +4060,7 @@ int32_t EditorBase::SplitNodeDeep(nsIContent& aNode, nsIContent& aSplitPointParent, int32_t aSplitPointOffset, - EmptyContainers aEmptyContainers, + SplitAtEdges aSplitAtEdges, nsIContent** aOutLeftNode, nsIContent** aOutRightNode, nsCOMPtr* ioChildAtSplitPointOffset) @@ -4079,7 +4079,7 @@ EditorBase::SplitNodeDeep(nsIContent& aNode, bool didSplit = false; - if ((aEmptyContainers == EmptyContainers::yes && + if ((aSplitAtEdges == SplitAtEdges::eAllowToCreateEmptyContainer && !nodeToSplit->GetAsText()) || (offset && offset != (int32_t)nodeToSplit->Length())) { didSplit = true; diff --git a/editor/libeditor/EditorBase.h b/editor/libeditor/EditorBase.h index ce9e2f2405eb..8f1badd7fb13 100644 --- a/editor/libeditor/EditorBase.h +++ b/editor/libeditor/EditorBase.h @@ -209,6 +209,23 @@ private: #define kMOZEditorBogusNodeAttrAtom nsGkAtoms::mozeditorbogusnode #define kMOZEditorBogusNodeValue NS_LITERAL_STRING("TRUE") +/** + * SplitAtEdges is for EditorBase::SplitNodeDeep(), + * HTMLEditor::InsertNodeAtPoint() + */ +enum class SplitAtEdges +{ + // EditorBase::SplitNodeDeep() won't split container element nodes at + // their edges. I.e., when split point is start or end of container, + // it won't be split. + eDoNotCreateEmptyContainer, + // EditorBase::SplitNodeDeep() always splits containers even if the split + // point is at edge of a container. E.g., if split point is start of an + // inline element, empty inline element is created as a new left node. + eAllowToCreateEmptyContainer +}; + + /** * Implementation of an editor object. it will be the controller/focal point * for the main editor services. i.e. the GUIManager, publishing, transaction @@ -1130,11 +1147,9 @@ public: nsresult IsPreformatted(nsIDOMNode* aNode, bool* aResult); - enum class EmptyContainers { no, yes }; int32_t SplitNodeDeep(nsIContent& aNode, nsIContent& aSplitPointParent, int32_t aSplitPointOffset, - EmptyContainers aEmptyContainers = - EmptyContainers::yes, + SplitAtEdges aSplitAtEdges, nsIContent** outLeftNode = nullptr, nsIContent** outRightNode = nullptr, nsCOMPtr* ioChildAtSplitPointOffset = diff --git a/editor/libeditor/HTMLEditRules.cpp b/editor/libeditor/HTMLEditRules.cpp index 4f5a8aaefcee..077b77501ee5 100644 --- a/editor/libeditor/HTMLEditRules.cpp +++ b/editor/libeditor/HTMLEditRules.cpp @@ -1857,9 +1857,9 @@ HTMLEditRules::StandardBreakImpl(nsINode& aNode, nsCOMPtr linkNode = do_QueryInterface(linkDOMNode); NS_ENSURE_STATE(linkNode || !linkDOMNode); nsCOMPtr linkParent = linkNode->GetParentNode(); - aOffset = htmlEditor->SplitNodeDeep(*linkNode, *node->AsContent(), - aOffset, - HTMLEditor::EmptyContainers::no); + aOffset = + htmlEditor->SplitNodeDeep(*linkNode, *node->AsContent(), aOffset, + SplitAtEdges::eDoNotCreateEmptyContainer); NS_ENSURE_STATE(aOffset != -1); node = linkParent; } @@ -1967,9 +1967,11 @@ HTMLEditRules::SplitMailCites(Selection* aSelection, NS_ENSURE_STATE(mHTMLEditor); NS_ENSURE_STATE(selNode->IsContent()); - int32_t newOffset = mHTMLEditor->SplitNodeDeep(*citeNode, - *selNode->AsContent(), selOffset, HTMLEditor::EmptyContainers::no, - getter_AddRefs(leftCite), getter_AddRefs(rightCite)); + int32_t newOffset = + mHTMLEditor->SplitNodeDeep(*citeNode, *selNode->AsContent(), selOffset, + SplitAtEdges::eDoNotCreateEmptyContainer, + getter_AddRefs(leftCite), + getter_AddRefs(rightCite)); NS_ENSURE_STATE(newOffset != -1); // Add an invisible
to the end of the left part if it was a of @@ -3840,9 +3842,9 @@ HTMLEditRules::MakeBasicBlock(Selection& aSelection, nsAtom& blockType) NS_ENSURE_SUCCESS(rv, rv); } // Do the splits! - offset = htmlEditor->SplitNodeDeep(curBlock, *container->AsContent(), - offset, - HTMLEditor::EmptyContainers::no); + offset = + htmlEditor->SplitNodeDeep(curBlock, *container->AsContent(), offset, + SplitAtEdges::eDoNotCreateEmptyContainer); NS_ENSURE_STATE(offset != -1); // Put a br at the split point brNode = htmlEditor->CreateBR(curBlock->GetParentNode(), offset); @@ -4716,7 +4718,7 @@ HTMLEditRules::SplitBlock(Element& aBlock, // Do the splits! nsCOMPtr newMiddleNode1; htmlEditor->SplitNodeDeep(aBlock, startParent, startOffset, - HTMLEditor::EmptyContainers::no, + SplitAtEdges::eDoNotCreateEmptyContainer, aOutLeftNode, getter_AddRefs(newMiddleNode1)); // Get split point location @@ -4727,7 +4729,7 @@ HTMLEditRules::SplitBlock(Element& aBlock, // Do the splits! nsCOMPtr newMiddleNode2; htmlEditor->SplitNodeDeep(aBlock, endParent, endOffset, - HTMLEditor::EmptyContainers::no, + SplitAtEdges::eDoNotCreateEmptyContainer, getter_AddRefs(newMiddleNode2), aOutRightNode); if (aOutMiddleNode) { @@ -4851,7 +4853,9 @@ HTMLEditRules::CreateStyleForInsertText(Selection& aSelection, if (RefPtr text = node->GetAsText()) { // if we are in a text node, split it NS_ENSURE_STATE(mHTMLEditor); - offset = mHTMLEditor->SplitNodeDeep(*text, *text, offset); + offset = + mHTMLEditor->SplitNodeDeep(*text, *text, offset, + SplitAtEdges::eAllowToCreateEmptyContainer); NS_ENSURE_STATE(offset != -1); node = node->GetParentNode(); } @@ -6406,7 +6410,7 @@ HTMLEditRules::BustUpInlinesAtRangeEndpoints(RangeItem& item) int32_t resultEndOffset = mHTMLEditor->SplitNodeDeep(*endInline, *item.mEndContainer->AsContent(), item.mEndOffset, - EditorBase::EmptyContainers::no); + SplitAtEdges::eDoNotCreateEmptyContainer); NS_ENSURE_TRUE(resultEndOffset != -1, NS_ERROR_FAILURE); // reset range item.mEndContainer = resultEndNode; @@ -6423,7 +6427,7 @@ HTMLEditRules::BustUpInlinesAtRangeEndpoints(RangeItem& item) mHTMLEditor->SplitNodeDeep(*startInline, *item.mStartContainer->AsContent(), item.mStartOffset, - EditorBase::EmptyContainers::no); + SplitAtEdges::eDoNotCreateEmptyContainer); NS_ENSURE_TRUE(resultStartOffset != -1, NS_ERROR_FAILURE); // reset range item.mStartContainer = resultStartNode; @@ -6467,7 +6471,7 @@ HTMLEditRules::BustUpInlinesAtBRs( int32_t resultOffset = htmlEditor->SplitNodeDeep(*splitDeepNode, splitParentNode, splitOffset, - HTMLEditor::EmptyContainers::yes, + SplitAtEdges::eAllowToCreateEmptyContainer, getter_AddRefs(leftNode), getter_AddRefs(rightNode)); NS_ENSURE_STATE(resultOffset != -1); @@ -6678,7 +6682,8 @@ HTMLEditRules::ReturnInHeader(Selection& aSelection, // Split the header NS_ENSURE_STATE(node->IsContent()); - htmlEditor->SplitNodeDeep(aHeader, *node->AsContent(), aOffset); + htmlEditor->SplitNodeDeep(aHeader, *node->AsContent(), aOffset, + SplitAtEdges::eAllowToCreateEmptyContainer); // If the left-hand heading is empty, put a mozbr in it nsCOMPtr prevItem = htmlEditor->GetPriorHTMLSibling(&aHeader); @@ -6897,7 +6902,7 @@ HTMLEditRules::SplitParagraph(Selection& aSelection, NS_ENSURE_STATE(selNode->IsContent()); int32_t offset = htmlEditor->SplitNodeDeep(aParentDivOrP, *selNode->AsContent(), selOffset, - HTMLEditor::EmptyContainers::yes, + SplitAtEdges::eAllowToCreateEmptyContainer, getter_AddRefs(leftPara), getter_AddRefs(rightPara)); if (NS_WARN_IF(offset == -1)) { @@ -7020,7 +7025,8 @@ HTMLEditRules::ReturnInListItem(Selection& aSelection, NS_ENSURE_SUCCESS(rv, rv); // Now split list item NS_ENSURE_STATE(selNode->IsContent()); - htmlEditor->SplitNodeDeep(aListItem, *selNode->AsContent(), aOffset); + htmlEditor->SplitNodeDeep(aListItem, *selNode->AsContent(), aOffset, + SplitAtEdges::eAllowToCreateEmptyContainer); // Hack: until I can change the damaged doc range code back to being // extra-inclusive, I have to manually detect certain list items that may be @@ -7452,12 +7458,11 @@ HTMLEditRules::SplitAsNeeded(nsAtom& aTag, if (splitNode && splitNode->IsContent() && inOutParent->IsContent()) { // We found a place for block, but above inOutParent. We need to split. NS_ENSURE_STATE(mHTMLEditor); - int32_t offset = mHTMLEditor->SplitNodeDeep(*splitNode->AsContent(), - *inOutParent->AsContent(), - inOutOffset, - EditorBase::EmptyContainers::yes, - nullptr, nullptr, - inOutChildAtOffset); + int32_t offset = + mHTMLEditor->SplitNodeDeep(*splitNode->AsContent(), + *inOutParent->AsContent(), inOutOffset, + SplitAtEdges::eAllowToCreateEmptyContainer, + nullptr, nullptr, inOutChildAtOffset); NS_ENSURE_STATE(offset != -1); inOutParent = tagParent; inOutOffset = offset; diff --git a/editor/libeditor/HTMLEditor.cpp b/editor/libeditor/HTMLEditor.cpp index 652df046067d..1a390e141a66 100644 --- a/editor/libeditor/HTMLEditor.cpp +++ b/editor/libeditor/HTMLEditor.cpp @@ -1522,7 +1522,8 @@ HTMLEditor::InsertElementAtSelection(nsIDOMElement* aElement, &offsetForInsert); rv = InsertNodeAtPoint(node, address_of(parentSelectedDOMNode), - &offsetForInsert, false); + &offsetForInsert, + SplitAtEdges::eAllowToCreateEmptyContainer); NS_ENSURE_SUCCESS(rv, rv); // Set caret after element, but check for special case // of inserting table-related elements: set in first cell instead @@ -1564,14 +1565,14 @@ HTMLEditor::InsertElementAtSelection(nsIDOMElement* aElement, * @param aNode Node to insert. * @param ioParent Insertion parent. * @param ioOffset Insertion offset. - * @param aNoEmptyNodes Splitting can result in empty nodes? + * @param aSplitAtEdges Splitting can result in empty nodes? * @param ioChildAtOffset Child node at insertion offset (optional). */ nsresult HTMLEditor::InsertNodeAtPoint(nsIDOMNode* aNode, nsCOMPtr* ioParent, int32_t* ioOffset, - bool aNoEmptyNodes, + SplitAtEdges aSplitAtEdges, nsCOMPtr* ioChildAtOffset) { nsCOMPtr node = do_QueryInterface(aNode); @@ -1624,8 +1625,7 @@ HTMLEditor::InsertNodeAtPoint(nsIDOMNode* aNode, } // we need to split some levels above the original selection parent int32_t offset = SplitNodeDeep(*topChild, *origParent, *ioOffset, - aNoEmptyNodes ? EmptyContainers::no - : EmptyContainers::yes, + aSplitAtEdges, nullptr, nullptr, address_of(child)); NS_ENSURE_STATE(offset != -1); *ioParent = GetAsDOMNode(parent); @@ -2003,7 +2003,8 @@ HTMLEditor::MakeOrChangeList(const nsAString& aListType, if (parent != node) { // we need to split up to the child of parent offset = SplitNodeDeep(*topChild, *node, offset, - EmptyContainers::yes, nullptr, nullptr, + SplitAtEdges::eAllowToCreateEmptyContainer, + nullptr, nullptr, address_of(child)); NS_ENSURE_STATE(offset != -1); } @@ -2148,7 +2149,8 @@ HTMLEditor::InsertBasicBlock(const nsAString& aBlockType) if (parent != node) { // we need to split up to the child of parent offset = SplitNodeDeep(*topChild, *node, offset, - EmptyContainers::yes, nullptr, nullptr, + SplitAtEdges::eAllowToCreateEmptyContainer, + nullptr, nullptr, address_of(child)); NS_ENSURE_STATE(offset != -1); } @@ -2224,7 +2226,8 @@ HTMLEditor::Indent(const nsAString& aIndent) if (parent != node) { // we need to split up to the child of parent offset = SplitNodeDeep(*topChild, *node, offset, - EmptyContainers::yes, nullptr, nullptr, + SplitAtEdges::eAllowToCreateEmptyContainer, + nullptr, nullptr, address_of(child)); NS_ENSURE_STATE(offset != -1); } diff --git a/editor/libeditor/HTMLEditor.h b/editor/libeditor/HTMLEditor.h index e7046324c974..0ee1fcc66ade 100644 --- a/editor/libeditor/HTMLEditor.h +++ b/editor/libeditor/HTMLEditor.h @@ -341,7 +341,7 @@ public: nsresult InsertNodeAtPoint(nsIDOMNode* aNode, nsCOMPtr* ioParent, int32_t* ioOffset, - bool aNoEmptyNodes, + SplitAtEdges aSplitAtEdges, nsCOMPtr* ioChildAtOffset = nullptr); /** diff --git a/editor/libeditor/HTMLEditorDataTransfer.cpp b/editor/libeditor/HTMLEditorDataTransfer.cpp index 6c1e5c7338c5..6231dff8efca 100644 --- a/editor/libeditor/HTMLEditorDataTransfer.cpp +++ b/editor/libeditor/HTMLEditorDataTransfer.cpp @@ -358,8 +358,9 @@ HTMLEditor::DoInsertHTMLWithContext(const nsAString& aInputString, if (IsTextNode(parentNode)) { nsCOMPtr parentContent = do_QueryInterface(parentNode); NS_ENSURE_STATE(parentContent || !parentNode); - offsetOfNewNode = SplitNodeDeep(*parentContent, *parentContent, - offsetOfNewNode); + offsetOfNewNode = + SplitNodeDeep(*parentContent, *parentContent, offsetOfNewNode, + SplitAtEdges::eAllowToCreateEmptyContainer); NS_ENSURE_STATE(offsetOfNewNode != -1); nsCOMPtr temp; rv = parentNode->GetParentNode(getter_AddRefs(temp)); @@ -446,7 +447,9 @@ HTMLEditor::DoInsertHTMLWithContext(const nsAString& aInputString, nsCOMPtr child; curNode->GetFirstChild(getter_AddRefs(child)); while (child) { - rv = InsertNodeAtPoint(child, address_of(parentNode), &offsetOfNewNode, true); + rv = InsertNodeAtPoint(child, address_of(parentNode), + &offsetOfNewNode, + SplitAtEdges::eDoNotCreateEmptyContainer); if (NS_FAILED(rv)) { break; } @@ -485,7 +488,9 @@ HTMLEditor::DoInsertHTMLWithContext(const nsAString& aInputString, } } } - rv = InsertNodeAtPoint(child, address_of(parentNode), &offsetOfNewNode, true); + rv = InsertNodeAtPoint(child, address_of(parentNode), + &offsetOfNewNode, + SplitAtEdges::eDoNotCreateEmptyContainer); if (NS_FAILED(rv)) { break; } @@ -504,7 +509,9 @@ HTMLEditor::DoInsertHTMLWithContext(const nsAString& aInputString, nsCOMPtr child; curNode->GetFirstChild(getter_AddRefs(child)); while (child) { - rv = InsertNodeAtPoint(child, address_of(parentNode), &offsetOfNewNode, true); + rv = InsertNodeAtPoint(child, address_of(parentNode), + &offsetOfNewNode, + SplitAtEdges::eDoNotCreateEmptyContainer); if (NS_FAILED(rv)) { break; } @@ -519,7 +526,9 @@ HTMLEditor::DoInsertHTMLWithContext(const nsAString& aInputString, if (!bDidInsert || NS_FAILED(rv)) { // try to insert - rv = InsertNodeAtPoint(curNode, address_of(parentNode), &offsetOfNewNode, true); + rv = InsertNodeAtPoint(curNode, address_of(parentNode), + &offsetOfNewNode, + SplitAtEdges::eDoNotCreateEmptyContainer); if (NS_SUCCEEDED(rv)) { bDidInsert = true; lastInsertNode = curNode; @@ -531,7 +540,9 @@ HTMLEditor::DoInsertHTMLWithContext(const nsAString& aInputString, while (NS_FAILED(rv) && curNode) { curNode->GetParentNode(getter_AddRefs(parent)); if (parent && !TextEditUtils::IsBody(parent)) { - rv = InsertNodeAtPoint(parent, address_of(parentNode), &offsetOfNewNode, true, + rv = InsertNodeAtPoint(parent, address_of(parentNode), + &offsetOfNewNode, + SplitAtEdges::eDoNotCreateEmptyContainer, address_of(lastInsertNode)); if (NS_SUCCEEDED(rv)) { bDidInsert = true; @@ -640,7 +651,8 @@ HTMLEditor::DoInsertHTMLWithContext(const nsAString& aInputString, NS_ENSURE_STATE(selContent || !selNode); nsCOMPtr leftLink; SplitNodeDeep(*linkContent, *selContent, selOffset, - EmptyContainers::no, getter_AddRefs(leftLink)); + SplitAtEdges::eDoNotCreateEmptyContainer, + getter_AddRefs(leftLink)); if (leftLink) { EditorRawDOMPoint afterLeftLink(leftLink); if (afterLeftLink.AdvanceOffset()) { diff --git a/editor/libeditor/HTMLStyleEditor.cpp b/editor/libeditor/HTMLStyleEditor.cpp index 2311e3f047ed..12e7ea8e73d2 100644 --- a/editor/libeditor/HTMLStyleEditor.cpp +++ b/editor/libeditor/HTMLStyleEditor.cpp @@ -554,8 +554,8 @@ HTMLEditor::SplitStyleAbovePoint(nsCOMPtr* aNode, isSet) { // Found a style node we need to split int32_t offset = SplitNodeDeep(*node, *(*aNode)->AsContent(), *aOffset, - EmptyContainers::yes, aOutLeftNode, - aOutRightNode); + SplitAtEdges::eAllowToCreateEmptyContainer, + aOutLeftNode, aOutRightNode); NS_ENSURE_TRUE(offset != -1, NS_ERROR_FAILURE); // reset startNode/startOffset *aNode = node->GetParent(); From d8cfeab3e41f35221f47f586a091b02d62270df2 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Mon, 13 Nov 2017 15:38:23 +0900 Subject: [PATCH 29/78] Bug 1413181 - part 7: EditorBase::SplitNodeDeep() should stop splitting orphan node if it meets an orphan node before meeting the most ancestor node to be split r=m_kato This doesn't change any meaning of the loop. It is a bug if the loop meets orphan node before meeting the most ancestor node to be split which is given as aNode. So, we can check it before trying to split it. MozReview-Commit-ID: 1TD7WHCoZh1 --HG-- extra : rebase_source : 17b8d7b3db458e29fb52be5cedb900560e1b70a4 --- editor/libeditor/EditorBase.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/editor/libeditor/EditorBase.cpp b/editor/libeditor/EditorBase.cpp index 7fba450e8600..0bdd325c5eaf 100644 --- a/editor/libeditor/EditorBase.cpp +++ b/editor/libeditor/EditorBase.cpp @@ -4072,6 +4072,13 @@ EditorBase::SplitNodeDeep(nsIContent& aNode, nsCOMPtr leftNode, rightNode; OwningNonNull nodeToSplit = aSplitPointParent; while (true) { + // If we meet an orphan node before meeting aNode, we need to stop + // splitting. This is a bug of the caller. + nsCOMPtr parent = nodeToSplit->GetParent(); + if (NS_WARN_IF(nodeToSplit != &aNode && !parent)) { + return -1; + } + // Need to insert rules code call here to do things like not split a list // if you are after the last
  • or before the first, etc. For now we // just have some smarts about unneccessarily splitting text nodes, which @@ -4099,15 +4106,12 @@ EditorBase::SplitNodeDeep(nsIContent& aNode, leftNode = newLeftNode; } - NS_ENSURE_TRUE(nodeToSplit->GetParent(), -1); - OwningNonNull parentNode = *nodeToSplit->GetParent(); - if (!didSplit && offset) { // Must be "end of text node" case, we didn't split it, just move past it - offset = parentNode->IndexOf(nodeToSplit) + 1; + offset = parent->IndexOf(nodeToSplit) + 1; leftNode = nodeToSplit; } else { - offset = parentNode->IndexOf(nodeToSplit); + offset = parent->IndexOf(nodeToSplit); rightNode = nodeToSplit; } @@ -4116,7 +4120,7 @@ EditorBase::SplitNodeDeep(nsIContent& aNode, break; } - nodeToSplit = parentNode; + nodeToSplit = *parent; } if (aOutLeftNode) { From ebd9a98d134b0a6699e760f67b1f456510935e2f Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Mon, 13 Nov 2017 15:51:56 +0900 Subject: [PATCH 30/78] Bug 1413181 - part 8: Merge two if blocks in the loop of EditorBase::SplitNodeDeep() r=m_kato Now, we can merge two if blocks in the loop of EditorBase::SplitNodeDeep() and get rid of |didSplit| variable. MozReview-Commit-ID: LJZHF6x2GLR --HG-- extra : rebase_source : 5f58508f6fc0928236252670c85383a13200fc2c --- editor/libeditor/EditorBase.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/editor/libeditor/EditorBase.cpp b/editor/libeditor/EditorBase.cpp index 0bdd325c5eaf..ad908c6a05ca 100644 --- a/editor/libeditor/EditorBase.cpp +++ b/editor/libeditor/EditorBase.cpp @@ -4084,12 +4084,11 @@ EditorBase::SplitNodeDeep(nsIContent& aNode, // just have some smarts about unneccessarily splitting text nodes, which // should be universal enough to put straight in this EditorBase routine. - bool didSplit = false; - + // If the split point is middle of the node or the node is not a text node + // and we're allowed to create empty element node, split it. if ((aSplitAtEdges == SplitAtEdges::eAllowToCreateEmptyContainer && !nodeToSplit->GetAsText()) || (offset && offset != (int32_t)nodeToSplit->Length())) { - didSplit = true; ErrorResult error; int32_t offsetAtStartOfRightNode = std::min(std::max(offset, 0), @@ -4102,15 +4101,20 @@ EditorBase::SplitNodeDeep(nsIContent& aNode, return -1; } + // Then, try to split its parent. + offset = parent->IndexOf(nodeToSplit); rightNode = nodeToSplit; leftNode = newLeftNode; } - - if (!didSplit && offset) { - // Must be "end of text node" case, we didn't split it, just move past it + // If the split point is end of the node and it is a text node or we're not + // allowed to create empty container node, try to split its parent after it. + else if (offset) { offset = parent->IndexOf(nodeToSplit) + 1; leftNode = nodeToSplit; - } else { + } + // If the split point is start of the node and it is a text node or we're + // not allowed to create empty container node, try to split its parent. + else { offset = parent->IndexOf(nodeToSplit); rightNode = nodeToSplit; } From f9e1aa29a00672f547deab7a6aa20bea0a734406 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Mon, 13 Nov 2017 16:44:58 +0900 Subject: [PATCH 31/78] Bug 1413181 - part 9: Make EditorBase::SplitNodeDeep() use EditorDOMPoint in the loop r=m_kato Make the loop in EditorBase::SplitNodeDeep() use EditorDOMPoint for making the code simpler. MozReview-Commit-ID: 3do3rWV4eIh --HG-- extra : rebase_source : 480a5b5b133d8a735bda6ddec07e4edf9ef34035 --- editor/libeditor/EditorBase.cpp | 74 +++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 26 deletions(-) diff --git a/editor/libeditor/EditorBase.cpp b/editor/libeditor/EditorBase.cpp index ad908c6a05ca..d1813d2a5cf1 100644 --- a/editor/libeditor/EditorBase.cpp +++ b/editor/libeditor/EditorBase.cpp @@ -4067,15 +4067,22 @@ EditorBase::SplitNodeDeep(nsIContent& aNode, { MOZ_ASSERT(&aSplitPointParent == &aNode || EditorUtils::IsDescendantOf(aSplitPointParent, aNode)); - int32_t offset = aSplitPointOffset; + + int32_t offset = + std::min(std::max(aSplitPointOffset, 0), + static_cast(aSplitPointParent.Length())); + EditorDOMPoint atStartOfRightNode(&aSplitPointParent, offset); + if (NS_WARN_IF(!atStartOfRightNode.IsSet())) { + return -1; + } + MOZ_ASSERT(atStartOfRightNode.IsSetAndValid()); nsCOMPtr leftNode, rightNode; - OwningNonNull nodeToSplit = aSplitPointParent; while (true) { // If we meet an orphan node before meeting aNode, we need to stop // splitting. This is a bug of the caller. - nsCOMPtr parent = nodeToSplit->GetParent(); - if (NS_WARN_IF(nodeToSplit != &aNode && !parent)) { + if (NS_WARN_IF(atStartOfRightNode.Container() != &aNode && + !atStartOfRightNode.Container()->GetParent())) { return -1; } @@ -4084,47 +4091,62 @@ EditorBase::SplitNodeDeep(nsIContent& aNode, // just have some smarts about unneccessarily splitting text nodes, which // should be universal enough to put straight in this EditorBase routine. + if (NS_WARN_IF(!atStartOfRightNode.Container()->IsContent())) { + return -1; + } + nsIContent* currentRightNode = atStartOfRightNode.Container()->AsContent(); + // If the split point is middle of the node or the node is not a text node // and we're allowed to create empty element node, split it. if ((aSplitAtEdges == SplitAtEdges::eAllowToCreateEmptyContainer && - !nodeToSplit->GetAsText()) || - (offset && offset != (int32_t)nodeToSplit->Length())) { + !atStartOfRightNode.Container()->GetAsText()) || + (!atStartOfRightNode.IsStartOfContainer() && + !atStartOfRightNode.IsEndOfContainer())) { ErrorResult error; - int32_t offsetAtStartOfRightNode = - std::min(std::max(offset, 0), - static_cast(nodeToSplit->Length())); - nsCOMPtr newLeftNode = - SplitNode(EditorRawDOMPoint(nodeToSplit, offsetAtStartOfRightNode), - error); + rightNode = currentRightNode; + leftNode = SplitNode(atStartOfRightNode.AsRaw(), error); if (NS_WARN_IF(error.Failed())) { error.SuppressException(); return -1; } - // Then, try to split its parent. - offset = parent->IndexOf(nodeToSplit); - rightNode = nodeToSplit; - leftNode = newLeftNode; + // Then, try to split its parent before current node. + atStartOfRightNode.Set(currentRightNode); } // If the split point is end of the node and it is a text node or we're not // allowed to create empty container node, try to split its parent after it. - else if (offset) { - offset = parent->IndexOf(nodeToSplit) + 1; - leftNode = nodeToSplit; + else if (!atStartOfRightNode.IsStartOfContainer()) { + // XXX Making current node which wasn't split treated as new left node + // here. However, rightNode still may keep referring a descendant + // of the leftNode, which was split. This must be odd behavior for + // the callers. + // Perhaps, we should set rightNode to currentRightNode? + leftNode = currentRightNode; + + // Try to split its parent after current node. + atStartOfRightNode.Set(currentRightNode); + DebugOnly advanced = atStartOfRightNode.AdvanceOffset(); + NS_WARNING_ASSERTION(advanced, + "Failed to advance offset after current node"); } // If the split point is start of the node and it is a text node or we're // not allowed to create empty container node, try to split its parent. else { - offset = parent->IndexOf(nodeToSplit); - rightNode = nodeToSplit; + // XXX Making current node which wasn't split treated as exiting right + // node here. However, leftNode still may keep referring a + // descendant of rightNode, which was created at splitting. This + // must be odd behavior for the callers. + // Perhaps, we should set leftNode to nullptr? + rightNode = currentRightNode; + + // Try to split its parent before current node. + atStartOfRightNode.Set(currentRightNode); } - if (nodeToSplit == &aNode) { + if (currentRightNode == &aNode) { // we split all the way up to (and including) aNode; we're done break; } - - nodeToSplit = *parent; } if (aOutLeftNode) { @@ -4134,10 +4156,10 @@ EditorBase::SplitNodeDeep(nsIContent& aNode, rightNode.forget(aOutRightNode); } if (ioChildAtSplitPointOffset) { - *ioChildAtSplitPointOffset = nodeToSplit; + *ioChildAtSplitPointOffset = atStartOfRightNode.GetChildAtOffset(); } - return offset; + return atStartOfRightNode.Offset(); } /** From 419273aff17961a37f763029a145e7dcc36a63b5 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Thu, 16 Nov 2017 12:09:57 +0900 Subject: [PATCH 32/78] Bug 1413181 - part 10: Redesign EditorBase::SplitNodeDeep() r=m_kato First of all, this patches fixes a bug of EditorBase::CreateNode(). It takes |EditorRawDOMPoint&| but it should be |const EditorRawDOMPoint&| for making callers can specify temporary instances. Next, this patch creates |SplitNodeResult| stack class for result of EditorBase::SplitNodeDeep(). SplitNodeDeep() needs to return previous node and next node of split point. They are called as left node and right node, but these calls are really different term usage. Therefore, this patch names: aOutLeftNode -> SplitNodeResult::GetPreviousNode() aOutRightNode -> SplitNodeResult::GetNextNode() and also declares SplitNodeResult::GetLeftNode() and SplitNodeResult::GetRightNode() which are same meaning as left/right node of other splitting methods. Additionally, of course, this patch makes SplitNodeDeep() use |const EditorRawDOMPoint&| to receive the start point of right node. MozReview-Commit-ID: FnJpeKgtzm4 --HG-- extra : rebase_source : 3829e5528ef837b13fed305e0df1dbbf00e02a07 --- editor/libeditor/EditorBase.cpp | 115 ++-- editor/libeditor/EditorBase.h | 33 +- editor/libeditor/EditorUtils.h | 108 ++++ editor/libeditor/HTMLEditRules.cpp | 554 ++++++++++++-------- editor/libeditor/HTMLEditor.cpp | 304 +++++------ editor/libeditor/HTMLEditorDataTransfer.cpp | 42 +- editor/libeditor/HTMLStyleEditor.cpp | 29 +- 7 files changed, 710 insertions(+), 475 deletions(-) diff --git a/editor/libeditor/EditorBase.cpp b/editor/libeditor/EditorBase.cpp index d1813d2a5cf1..c89996e57187 100644 --- a/editor/libeditor/EditorBase.cpp +++ b/editor/libeditor/EditorBase.cpp @@ -1419,15 +1419,17 @@ EditorBase::SetSpellcheckUserOverride(bool enable) already_AddRefed EditorBase::CreateNode(nsAtom* aTag, - EditorRawDOMPoint& aPointToInsert) + const EditorRawDOMPoint& aPointToInsert) { MOZ_ASSERT(aTag); MOZ_ASSERT(aPointToInsert.IsSetAndValid()); + EditorRawDOMPoint pointToInsert(aPointToInsert); + // XXX We need offset at new node for mRangeUpdater. Therefore, we need // to compute the offset now but this is expensive. So, if it's possible, // we need to redesign mRangeUpdater as avoiding using indices. - int32_t offset = static_cast(aPointToInsert.Offset()); + int32_t offset = static_cast(pointToInsert.Offset()); AutoRules beginRulesSniffing(this, EditAction::createNode, nsIEditor::eNext); @@ -1435,14 +1437,14 @@ EditorBase::CreateNode(nsAtom* aTag, AutoActionListenerArray listeners(mActionListeners); for (auto& listener : listeners) { listener->WillCreateNode(nsDependentAtomString(aTag), - GetAsDOMNode(aPointToInsert.GetChildAtOffset())); + GetAsDOMNode(pointToInsert.GetChildAtOffset())); } } nsCOMPtr ret; RefPtr transaction = - CreateTxnForCreateElement(*aTag, aPointToInsert); + CreateTxnForCreateElement(*aTag, pointToInsert); nsresult rv = DoTransaction(transaction); if (NS_SUCCEEDED(rv)) { ret = transaction->GetNewNode(); @@ -1450,10 +1452,10 @@ EditorBase::CreateNode(nsAtom* aTag, // Now, aPointToInsert may be invalid. I.e., ChildAtOffset() keeps // referring the next sibling of new node but Offset() refers the // new node. Let's make refer the new node. - aPointToInsert.Set(ret); + pointToInsert.Set(ret); } - mRangeUpdater.SelAdjCreateNode(aPointToInsert.Container(), offset); + mRangeUpdater.SelAdjCreateNode(pointToInsert.Container(), offset); { AutoActionListenerArray listeners(mActionListeners); @@ -4042,48 +4044,28 @@ EditorBase::IsPreformatted(nsIDOMNode* aNode, return NS_OK; } - -/** - * This splits a node "deeply", splitting children as appropriate. The place - * to split is represented by a DOM point at {splitPointParent, - * splitPointOffset}. That DOM point must be inside aNode, which is the node - * to split. We return the offset in the parent of aNode where the split - * terminates - where you would want to insert a new element, for instance, if - * that's why you were splitting the node. - * - * -1 is returned on failure, in unlikely cases like the selection being - * unavailable or cloning the node failing. Make sure not to use the returned - * offset for anything without checking that it's valid! If you're not using - * the offset, it's okay to ignore the return value. - */ -int32_t -EditorBase::SplitNodeDeep(nsIContent& aNode, - nsIContent& aSplitPointParent, - int32_t aSplitPointOffset, - SplitAtEdges aSplitAtEdges, - nsIContent** aOutLeftNode, - nsIContent** aOutRightNode, - nsCOMPtr* ioChildAtSplitPointOffset) +SplitNodeResult +EditorBase::SplitNodeDeep(nsIContent& aMostAncestorToSplit, + const EditorRawDOMPoint& aStartOfDeepestRightNode, + SplitAtEdges aSplitAtEdges) { - MOZ_ASSERT(&aSplitPointParent == &aNode || - EditorUtils::IsDescendantOf(aSplitPointParent, aNode)); + MOZ_ASSERT(aStartOfDeepestRightNode.IsSetAndValid()); + MOZ_ASSERT(aStartOfDeepestRightNode.Container() == &aMostAncestorToSplit || + EditorUtils::IsDescendantOf(*aStartOfDeepestRightNode.Container(), + aMostAncestorToSplit)); - int32_t offset = - std::min(std::max(aSplitPointOffset, 0), - static_cast(aSplitPointParent.Length())); - EditorDOMPoint atStartOfRightNode(&aSplitPointParent, offset); - if (NS_WARN_IF(!atStartOfRightNode.IsSet())) { - return -1; + if (NS_WARN_IF(!aStartOfDeepestRightNode.IsSet())) { + return SplitNodeResult(NS_ERROR_INVALID_ARG); } - MOZ_ASSERT(atStartOfRightNode.IsSetAndValid()); - nsCOMPtr leftNode, rightNode; + nsCOMPtr newLeftNodeOfMostAncestor; + EditorDOMPoint atStartOfRightNode(aStartOfDeepestRightNode); while (true) { - // If we meet an orphan node before meeting aNode, we need to stop - // splitting. This is a bug of the caller. - if (NS_WARN_IF(atStartOfRightNode.Container() != &aNode && + // If we meet an orphan node before meeting aMostAncestorToSplit, we need + // to stop splitting. This is a bug of the caller. + if (NS_WARN_IF(atStartOfRightNode.Container() != &aMostAncestorToSplit && !atStartOfRightNode.Container()->GetParent())) { - return -1; + return SplitNodeResult(NS_ERROR_FAILURE); } // Need to insert rules code call here to do things like not split a list @@ -4092,7 +4074,7 @@ EditorBase::SplitNodeDeep(nsIContent& aNode, // should be universal enough to put straight in this EditorBase routine. if (NS_WARN_IF(!atStartOfRightNode.Container()->IsContent())) { - return -1; + return SplitNodeResult(NS_ERROR_FAILURE); } nsIContent* currentRightNode = atStartOfRightNode.Container()->AsContent(); @@ -4103,11 +4085,15 @@ EditorBase::SplitNodeDeep(nsIContent& aNode, (!atStartOfRightNode.IsStartOfContainer() && !atStartOfRightNode.IsEndOfContainer())) { ErrorResult error; - rightNode = currentRightNode; - leftNode = SplitNode(atStartOfRightNode.AsRaw(), error); + nsCOMPtr newLeftNode = + SplitNode(atStartOfRightNode.AsRaw(), error); if (NS_WARN_IF(error.Failed())) { - error.SuppressException(); - return -1; + return SplitNodeResult(NS_ERROR_FAILURE); + } + + if (currentRightNode == &aMostAncestorToSplit) { + // Actually, we split aMostAncestorToSplit. + return SplitNodeResult(newLeftNode, &aMostAncestorToSplit); } // Then, try to split its parent before current node. @@ -4116,12 +4102,9 @@ EditorBase::SplitNodeDeep(nsIContent& aNode, // If the split point is end of the node and it is a text node or we're not // allowed to create empty container node, try to split its parent after it. else if (!atStartOfRightNode.IsStartOfContainer()) { - // XXX Making current node which wasn't split treated as new left node - // here. However, rightNode still may keep referring a descendant - // of the leftNode, which was split. This must be odd behavior for - // the callers. - // Perhaps, we should set rightNode to currentRightNode? - leftNode = currentRightNode; + if (currentRightNode == &aMostAncestorToSplit) { + return SplitNodeResult(&aMostAncestorToSplit, nullptr); + } // Try to split its parent after current node. atStartOfRightNode.Set(currentRightNode); @@ -4132,34 +4115,16 @@ EditorBase::SplitNodeDeep(nsIContent& aNode, // If the split point is start of the node and it is a text node or we're // not allowed to create empty container node, try to split its parent. else { - // XXX Making current node which wasn't split treated as exiting right - // node here. However, leftNode still may keep referring a - // descendant of rightNode, which was created at splitting. This - // must be odd behavior for the callers. - // Perhaps, we should set leftNode to nullptr? - rightNode = currentRightNode; + if (currentRightNode == &aMostAncestorToSplit) { + return SplitNodeResult(nullptr, &aMostAncestorToSplit); + } // Try to split its parent before current node. atStartOfRightNode.Set(currentRightNode); } - - if (currentRightNode == &aNode) { - // we split all the way up to (and including) aNode; we're done - break; - } } - if (aOutLeftNode) { - leftNode.forget(aOutLeftNode); - } - if (aOutRightNode) { - rightNode.forget(aOutRightNode); - } - if (ioChildAtSplitPointOffset) { - *ioChildAtSplitPointOffset = atStartOfRightNode.GetChildAtOffset(); - } - - return atStartOfRightNode.Offset(); + return SplitNodeResult(NS_ERROR_FAILURE); } /** diff --git a/editor/libeditor/EditorBase.h b/editor/libeditor/EditorBase.h index 8f1badd7fb13..c8063e8b3374 100644 --- a/editor/libeditor/EditorBase.h +++ b/editor/libeditor/EditorBase.h @@ -122,6 +122,7 @@ class InsertTextTransaction; class JoinNodeTransaction; class PlaceholderTransaction; class RemoveStyleSheetTransaction; +class SplitNodeResult; class SplitNodeTransaction; class TextComposition; class TextEditor; @@ -225,7 +226,6 @@ enum class SplitAtEdges eAllowToCreateEmptyContainer }; - /** * Implementation of an editor object. it will be the controller/focal point * for the main editor services. i.e. the GUIManager, publishing, transaction @@ -479,7 +479,7 @@ protected: * @return The created new element node. */ already_AddRefed CreateNode(nsAtom* aTag, - EditorRawDOMPoint& aPointToInsert); + const EditorRawDOMPoint& aPointToInsert); /** * Create a transaction for inserting aNode as a child of aParent. @@ -1147,13 +1147,28 @@ public: nsresult IsPreformatted(nsIDOMNode* aNode, bool* aResult); - int32_t SplitNodeDeep(nsIContent& aNode, nsIContent& aSplitPointParent, - int32_t aSplitPointOffset, - SplitAtEdges aSplitAtEdges, - nsIContent** outLeftNode = nullptr, - nsIContent** outRightNode = nullptr, - nsCOMPtr* ioChildAtSplitPointOffset = - nullptr); + /** + * SplitNodeDeep() splits aMostAncestorToSplit deeply. + * + * @param aMostAncestorToSplit The most ancestor node which should be + * split. + * @param aStartOfDeepestRightNode The start point of deepest right node. + * This point must be descendant of + * aMostAncestorToSplit. + * @param aSplitAtEdges Whether the caller allows this to + * create empty container element when + * split point is start or end of an + * element. + * @return SplitPoint() returns split point in + * aMostAncestorToSplit. The point must + * be good to insert something if the + * caller want to do it. + */ + SplitNodeResult + SplitNodeDeep(nsIContent& aMostAncestorToSplit, + const EditorRawDOMPoint& aDeepestStartOfRightNode, + SplitAtEdges aSplitAtEdges); + EditorDOMPoint JoinNodeDeep(nsIContent& aLeftNode, nsIContent& aRightNode); diff --git a/editor/libeditor/EditorUtils.h b/editor/libeditor/EditorUtils.h index f585247cd198..f2d2e824c0f4 100644 --- a/editor/libeditor/EditorUtils.h +++ b/editor/libeditor/EditorUtils.h @@ -141,6 +141,114 @@ EditActionCanceled(nsresult aRv = NS_OK) return EditActionResult(aRv, true, true); } +/*************************************************************************** + * SplitNodeResult is a simple class for EditorBase::SplitNodeDeep(). + * This makes the callers' code easier to read. + */ +class MOZ_STACK_CLASS SplitNodeResult final +{ +public: + bool Succeeded() const { return NS_SUCCEEDED(mRv); } + bool Failed() const { return NS_FAILED(mRv); } + nsresult Rv() const { return mRv; } + + /** + * DidSplit() returns true if a node was actually split. + */ + bool DidSplit() const + { + return mPreviousNode && mNextNode; + } + + /** + * GetLeftNode() simply returns the left node which was created at splitting. + * This returns nullptr if the node wasn't split. + */ + nsIContent* GetLeftNode() const + { + return mPreviousNode && mNextNode ? mPreviousNode.get() : nullptr; + } + + /** + * GetRightNode() simply returns the right node which was split. + * This won't return nullptr unless failed to split due to invalid arguments. + */ + nsIContent* GetRightNode() const + { + return mPreviousNode && !mNextNode ? mPreviousNode : mNextNode; + } + + /** + * GetPreviousNode() returns previous node at the split point. + */ + nsIContent* GetPreviousNode() const { return mPreviousNode; } + + /** + * GetNextNode() returns next node at the split point. + */ + nsIContent* GetNextNode() const { return mNextNode; } + + /** + * SplitPoint() returns the split point in the container. + * This is useful when callers insert an element at split point with + * EditorBase::CreateNode() or something similar methods. + * + * Note that the result is EditorRawDOMPoint but the nodes are grabbed + * by this instance. Therefore, the life time of both container node + * and child node are guaranteed while using the result temporarily. + */ + EditorRawDOMPoint SplitPoint() const + { + if (Failed()) { + return EditorRawDOMPoint(); + } + if (!mPreviousNode) { + return EditorRawDOMPoint(mNextNode); + } + EditorRawDOMPoint point(mPreviousNode); + DebugOnly advanced = point.AdvanceOffset(); + NS_WARNING_ASSERTION(advanced, + "Failed to advance offset to after previous node"); + return point; + } + + /** + * This constructor shouldn't be used by anybody except methods which + * use this as result when it succeeds. + * + * @param aPreviousNodeOfSplitPoint Previous node immediately before + * split point. + * @param aNextNodeOfSplitPoint Next node immediately after split + * point. + */ + SplitNodeResult(nsIContent* aPreviousNodeOfSplitPoint, + nsIContent* aNextNodeOfSplitPoint) + : mPreviousNode(aPreviousNodeOfSplitPoint) + , mNextNode(aNextNodeOfSplitPoint) + , mRv(NS_OK) + { + MOZ_DIAGNOSTIC_ASSERT(mPreviousNode || mNextNode); + } + + /** + * This constructor shouldn't be used by anybody except methods which + * use this as error result when it fails. + */ + explicit SplitNodeResult(nsresult aRv) + : mRv(aRv) + { + MOZ_DIAGNOSTIC_ASSERT(NS_FAILED(mRv)); + } + +private: + nsCOMPtr mPreviousNode; + nsCOMPtr mNextNode; + + nsresult mRv; + + SplitNodeResult() = delete; +}; + /*************************************************************************** * stack based helper class for batching a collection of transactions inside a * placeholder transaction. diff --git a/editor/libeditor/HTMLEditRules.cpp b/editor/libeditor/HTMLEditRules.cpp index 077b77501ee5..50178296c055 100644 --- a/editor/libeditor/HTMLEditRules.cpp +++ b/editor/libeditor/HTMLEditRules.cpp @@ -1856,12 +1856,15 @@ HTMLEditRules::StandardBreakImpl(nsINode& aNode, // Split the link nsCOMPtr linkNode = do_QueryInterface(linkDOMNode); NS_ENSURE_STATE(linkNode || !linkDOMNode); - nsCOMPtr linkParent = linkNode->GetParentNode(); - aOffset = - htmlEditor->SplitNodeDeep(*linkNode, *node->AsContent(), aOffset, + SplitNodeResult splitLinkNodeResult = + htmlEditor->SplitNodeDeep(*linkNode, EditorRawDOMPoint(node, aOffset), SplitAtEdges::eDoNotCreateEmptyContainer); - NS_ENSURE_STATE(aOffset != -1); - node = linkParent; + if (NS_WARN_IF(splitLinkNodeResult.Failed())) { + return splitLinkNodeResult.Rv(); + } + EditorRawDOMPoint splitPoint(splitLinkNodeResult.SplitPoint()); + node = splitPoint.Container(); + aOffset = splitPoint.Offset(); } brNode = wsObj.InsertBreak(address_of(node), &aOffset, nsIEditor::eNone); NS_ENSURE_TRUE(brNode, NS_ERROR_FAILURE); @@ -1967,38 +1970,59 @@ HTMLEditRules::SplitMailCites(Selection* aSelection, NS_ENSURE_STATE(mHTMLEditor); NS_ENSURE_STATE(selNode->IsContent()); - int32_t newOffset = - mHTMLEditor->SplitNodeDeep(*citeNode, *selNode->AsContent(), selOffset, - SplitAtEdges::eDoNotCreateEmptyContainer, - getter_AddRefs(leftCite), - getter_AddRefs(rightCite)); - NS_ENSURE_STATE(newOffset != -1); + SplitNodeResult splitCiteNodeResult = + mHTMLEditor->SplitNodeDeep(*citeNode, + EditorRawDOMPoint(selNode, selOffset), + SplitAtEdges::eDoNotCreateEmptyContainer); + if (NS_WARN_IF(splitCiteNodeResult.Failed())) { + return splitCiteNodeResult.Rv(); + } - // Add an invisible
    to the end of the left part if it was a of - // style="display: block". This is important, since when serialising the - // cite to plain text, the span which caused the visual break is discarded. - // So the added
    will guarantee that the serialiser will insert a - // break where the user saw one. - if (leftCite && - leftCite->IsHTMLElement(nsGkAtoms::span) && - leftCite->GetPrimaryFrame()->IsFrameOfType(nsIFrame::eBlockFrame)) { - nsCOMPtr lastChild = leftCite->GetLastChild(); - if (lastChild && !lastChild->IsHTMLElement(nsGkAtoms::br)) { - // We ignore the result here. - nsCOMPtr invisBR = - mHTMLEditor->CreateBR(leftCite, leftCite->Length()); + // Add an invisible
    to the end of current cite node (If new left cite + // has not been created, we're at the end of it. Otherwise, we're still at + // the right node) if it was a of style="display: block". This is + // important, since when serializing the cite to plain text, the span which + // caused the visual break is discarded. So the added
    will guarantee + // that the serializer will insert a break where the user saw one. + nsIContent* preveiousNodeOfSplitPoint = + splitCiteNodeResult.GetPreviousNode(); + if (preveiousNodeOfSplitPoint && + preveiousNodeOfSplitPoint->IsHTMLElement(nsGkAtoms::span) && + preveiousNodeOfSplitPoint->GetPrimaryFrame()-> + IsFrameOfType(nsIFrame::eBlockFrame)) { + nsCOMPtr lastChild = + preveiousNodeOfSplitPoint->GetLastChild(); + if (lastChild && !lastChild->IsHTMLElement(nsGkAtoms::br)) { + // We ignore the result here. + nsCOMPtr invisBR = + mHTMLEditor->CreateBR(preveiousNodeOfSplitPoint, + preveiousNodeOfSplitPoint->Length()); } } - selNode = citeNode->GetParentNode(); + // In most cases,
    should be inserted after current cite. However, if + // left cite hasn't been created because the split point was start of the + // cite node,
    should be inserted before the current cite. + EditorRawDOMPoint pointToInsertBrNode(splitCiteNodeResult.SplitPoint()); NS_ENSURE_STATE(mHTMLEditor); - nsCOMPtr brNode = mHTMLEditor->CreateBR(selNode, newOffset); + nsCOMPtr brNode = + mHTMLEditor->CreateBR(pointToInsertBrNode.Container(), + pointToInsertBrNode.Offset()); NS_ENSURE_STATE(brNode); + // Now, offset of pointToInsertBrNode is invalid. Let's clear it. + pointToInsertBrNode.Clear(); - // want selection before the break, and on same line + // Want selection before the break, and on same line. + EditorRawDOMPoint atBrNode(brNode); aSelection->SetInterlinePosition(true); - rv = aSelection->Collapse(selNode, newOffset); - NS_ENSURE_SUCCESS(rv, rv); + ErrorResult error; + aSelection->Collapse(atBrNode, error); + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); + } + + selNode = atBrNode.Container(); + selOffset = atBrNode.Offset(); // if citeNode wasn't a block, we might also want another break before it. // We need to examine the content both before the br we just added and also @@ -2006,24 +2030,24 @@ HTMLEditRules::SplitMailCites(Selection* aSelection, // then we will need a 2nd br added to achieve blank line that user expects. if (IsInlineNode(*citeNode)) { NS_ENSURE_STATE(mHTMLEditor); - WSRunObject wsObj(mHTMLEditor, selNode, newOffset); + WSRunObject wsObj(mHTMLEditor, selNode, selOffset); nsCOMPtr visNode; int32_t visOffset=0; WSType wsType; - wsObj.PriorVisibleNode(selNode, newOffset, address_of(visNode), + wsObj.PriorVisibleNode(selNode, selOffset, address_of(visNode), &visOffset, &wsType); if (wsType == WSType::normalWS || wsType == WSType::text || wsType == WSType::special) { NS_ENSURE_STATE(mHTMLEditor); - WSRunObject wsObjAfterBR(mHTMLEditor, selNode, newOffset+1); - wsObjAfterBR.NextVisibleNode(selNode, newOffset + 1, + WSRunObject wsObjAfterBR(mHTMLEditor, selNode, selOffset + 1); + wsObjAfterBR.NextVisibleNode(selNode, selOffset + 1, address_of(visNode), &visOffset, &wsType); if (wsType == WSType::normalWS || wsType == WSType::text || wsType == WSType::special || // In case we're at the very end. wsType == WSType::thisBlock) { NS_ENSURE_STATE(mHTMLEditor); - brNode = mHTMLEditor->CreateBR(selNode, newOffset); + brNode = mHTMLEditor->CreateBR(selNode, selOffset); NS_ENSURE_STATE(brNode); } } @@ -2046,15 +2070,15 @@ HTMLEditRules::SplitMailCites(Selection* aSelection, } } - if (rightCite) { + if (citeNode) { NS_ENSURE_STATE(mHTMLEditor); - rv = mHTMLEditor->IsEmptyNode(rightCite, &bEmptyCite, true, false); + rv = mHTMLEditor->IsEmptyNode(citeNode, &bEmptyCite, true, false); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } if (bEmptyCite) { NS_ENSURE_STATE(mHTMLEditor); - rv = mHTMLEditor->DeleteNode(rightCite); + rv = mHTMLEditor->DeleteNode(citeNode); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -3830,67 +3854,78 @@ HTMLEditRules::MakeBasicBlock(Selection& aSelection, nsAtom& blockType) // We are removing blocks (going to "body text") NS_ENSURE_TRUE(htmlEditor->GetBlock(container), NS_ERROR_NULL_POINTER); OwningNonNull curBlock = *htmlEditor->GetBlock(container); - if (HTMLEditUtils::IsFormatNode(curBlock)) { - // If the first editable node after selection is a br, consume it. - // Otherwise it gets pushed into a following block after the split, - // which is visually bad. - nsCOMPtr brNode = - htmlEditor->GetNextEditableHTMLNode( - EditorRawDOMPoint(container, child, offset)); - if (brNode && brNode->IsHTMLElement(nsGkAtoms::br)) { - rv = htmlEditor->DeleteNode(brNode); - NS_ENSURE_SUCCESS(rv, rv); - } - // Do the splits! - offset = - htmlEditor->SplitNodeDeep(curBlock, *container->AsContent(), offset, - SplitAtEdges::eDoNotCreateEmptyContainer); - NS_ENSURE_STATE(offset != -1); - // Put a br at the split point - brNode = htmlEditor->CreateBR(curBlock->GetParentNode(), offset); - NS_ENSURE_STATE(brNode); - // Put selection at the split point - rv = aSelection.Collapse(curBlock->GetParentNode(), offset); - // Don't restore the selection - selectionRestorer.Abort(); - NS_ENSURE_SUCCESS(rv, rv); + if (!HTMLEditUtils::IsFormatNode(curBlock)) { + return NS_OK; } - // Else nothing to do! - } else { - // We are making a block. Consume a br, if needed. + + // If the first editable node after selection is a br, consume it. + // Otherwise it gets pushed into a following block after the split, + // which is visually bad. nsCOMPtr brNode = - htmlEditor->GetNextEditableHTMLNodeInBlock( + htmlEditor->GetNextEditableHTMLNode( EditorRawDOMPoint(container, child, offset)); if (brNode && brNode->IsHTMLElement(nsGkAtoms::br)) { rv = htmlEditor->DeleteNode(brNode); NS_ENSURE_SUCCESS(rv, rv); - // We don't need to act on this node any more - arrayOfNodes.RemoveElement(brNode); - // XXX We need to recompute child here because SplitAsNeeded() and - // EditorBase::SplitNodeDeep() don't compute child in some cases. - child = container->GetChildAt(offset); } - // Make sure we can put a block here - rv = SplitAsNeeded(blockType, container, offset, address_of(child)); - NS_ENSURE_SUCCESS(rv, rv); - EditorRawDOMPoint atChild(container, child, offset); - RefPtr block = htmlEditor->CreateNode(&blockType, atChild); - NS_ENSURE_STATE(block); - // Remember our new block for postprocessing - mNewBlock = block; - // Delete anything that was in the list of nodes - while (!arrayOfNodes.IsEmpty()) { - OwningNonNull curNode = arrayOfNodes[0]; - rv = htmlEditor->DeleteNode(curNode); - NS_ENSURE_SUCCESS(rv, rv); - arrayOfNodes.RemoveElementAt(0); + // Do the splits! + SplitNodeResult splitNodeResult = + htmlEditor->SplitNodeDeep(curBlock, + EditorRawDOMPoint(container, offset), + SplitAtEdges::eDoNotCreateEmptyContainer); + if (NS_WARN_IF(splitNodeResult.Failed())) { + return splitNodeResult.Rv(); } - // Put selection in new block - rv = aSelection.Collapse(block, 0); + EditorRawDOMPoint pointToInsertBrNode(splitNodeResult.SplitPoint()); + // Put a br at the split point + brNode = htmlEditor->CreateBR(pointToInsertBrNode.Container(), + pointToInsertBrNode.Offset()); + NS_ENSURE_STATE(brNode); + // Put selection at the split point + EditorRawDOMPoint atBrNode(brNode); + ErrorResult error; + aSelection.Collapse(atBrNode, error); // Don't restore the selection selectionRestorer.Abort(); - NS_ENSURE_SUCCESS(rv, rv); + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); + } + return NS_OK; } + + // We are making a block. Consume a br, if needed. + nsCOMPtr brNode = + htmlEditor->GetNextEditableHTMLNodeInBlock( + EditorRawDOMPoint(container, child, offset)); + if (brNode && brNode->IsHTMLElement(nsGkAtoms::br)) { + rv = htmlEditor->DeleteNode(brNode); + NS_ENSURE_SUCCESS(rv, rv); + // We don't need to act on this node any more + arrayOfNodes.RemoveElement(brNode); + // XXX We need to recompute child here because SplitAsNeeded() don't + // compute child in some cases. + child = container->GetChildAt(offset); + } + // Make sure we can put a block here + rv = SplitAsNeeded(blockType, container, offset, address_of(child)); + NS_ENSURE_SUCCESS(rv, rv); + EditorRawDOMPoint atChild(container, child, offset); + RefPtr block = htmlEditor->CreateNode(&blockType, atChild); + NS_ENSURE_STATE(block); + // Remember our new block for postprocessing + mNewBlock = block; + // Delete anything that was in the list of nodes + while (!arrayOfNodes.IsEmpty()) { + OwningNonNull curNode = arrayOfNodes[0]; + rv = htmlEditor->DeleteNode(curNode); + NS_ENSURE_SUCCESS(rv, rv); + arrayOfNodes.RemoveElementAt(0); + } + // Put selection in new block + rv = aSelection.Collapse(block, 0); + // Don't restore the selection + selectionRestorer.Abort(); + NS_ENSURE_SUCCESS(rv, rv); return NS_OK; } // Okay, now go through all the nodes and make the right kind of blocks, or @@ -4711,32 +4746,37 @@ HTMLEditRules::SplitBlock(Element& aBlock, NS_ENSURE_TRUE_VOID(mHTMLEditor); RefPtr htmlEditor(mHTMLEditor); - // Get split point location - OwningNonNull startParent = *aStartChild.GetParent(); - int32_t startOffset = startParent->IndexOf(&aStartChild); + // Split at the start. + SplitNodeResult splitAtStartResult = + htmlEditor->SplitNodeDeep(aBlock, EditorRawDOMPoint(&aStartChild), + SplitAtEdges::eDoNotCreateEmptyContainer); + NS_WARNING_ASSERTION(splitAtStartResult.Succeeded(), + "Failed to split aBlock at start"); - // Do the splits! - nsCOMPtr newMiddleNode1; - htmlEditor->SplitNodeDeep(aBlock, startParent, startOffset, - SplitAtEdges::eDoNotCreateEmptyContainer, - aOutLeftNode, getter_AddRefs(newMiddleNode1)); + // Split at after the end + EditorRawDOMPoint atAfterEnd(&aEndChild); + DebugOnly advanced = atAfterEnd.AdvanceOffset(); + NS_WARNING_ASSERTION(advanced, + "Failed to advance offset after the end node"); + SplitNodeResult splitAtEndResult = + htmlEditor->SplitNodeDeep(aBlock, atAfterEnd, + SplitAtEdges::eDoNotCreateEmptyContainer); + NS_WARNING_ASSERTION(splitAtEndResult.Succeeded(), + "Failed to split aBlock at after end"); - // Get split point location - OwningNonNull endParent = *aEndChild.GetParent(); - // +1 because we want to be after the child - int32_t endOffset = 1 + endParent->IndexOf(&aEndChild); + if (aOutLeftNode) { + NS_IF_ADDREF(*aOutLeftNode = splitAtStartResult.GetPreviousNode()); + } - // Do the splits! - nsCOMPtr newMiddleNode2; - htmlEditor->SplitNodeDeep(aBlock, endParent, endOffset, - SplitAtEdges::eDoNotCreateEmptyContainer, - getter_AddRefs(newMiddleNode2), aOutRightNode); + if (aOutRightNode) { + NS_IF_ADDREF(*aOutRightNode = splitAtEndResult.GetNextNode()); + } if (aOutMiddleNode) { - if (newMiddleNode2) { - newMiddleNode2.forget(aOutMiddleNode); + if (splitAtEndResult.GetPreviousNode()) { + NS_IF_ADDREF(*aOutMiddleNode = splitAtEndResult.GetPreviousNode()); } else { - newMiddleNode1.forget(aOutMiddleNode); + NS_IF_ADDREF(*aOutMiddleNode = splitAtStartResult.GetNextNode()); } } } @@ -4851,13 +4891,19 @@ HTMLEditRules::CreateStyleForInsertText(Selection& aSelection, // we have at least one style to add; make a new text node to insert style // nodes above. if (RefPtr text = node->GetAsText()) { + if (NS_WARN_IF(!mHTMLEditor)) { + return NS_ERROR_FAILURE; + } // if we are in a text node, split it - NS_ENSURE_STATE(mHTMLEditor); - offset = - mHTMLEditor->SplitNodeDeep(*text, *text, offset, + SplitNodeResult splitTextNodeResult = + mHTMLEditor->SplitNodeDeep(*text, EditorRawDOMPoint(text, offset), SplitAtEdges::eAllowToCreateEmptyContainer); - NS_ENSURE_STATE(offset != -1); - node = node->GetParentNode(); + if (NS_WARN_IF(splitTextNodeResult.Failed())) { + return splitTextNodeResult.Rv(); + } + EditorRawDOMPoint splitPoint(splitTextNodeResult.SplitPoint()); + node = splitPoint.Container(); + offset = splitPoint.Offset(); } if (!mHTMLEditor->IsContainer(node)) { return NS_OK; @@ -6397,41 +6443,60 @@ HTMLEditRules::GetParagraphFormatNodes( nsresult HTMLEditRules::BustUpInlinesAtRangeEndpoints(RangeItem& item) { + if (NS_WARN_IF(!mHTMLEditor)) { + return NS_ERROR_NOT_AVAILABLE; + } + bool isCollapsed = item.mStartContainer == item.mEndContainer && item.mStartOffset == item.mEndOffset; nsCOMPtr endInline = GetHighestInlineParent(*item.mEndContainer); + if (NS_WARN_IF(!mHTMLEditor)) { + return NS_ERROR_FAILURE; + } - // if we have inline parents above range endpoints, split them + // XXX Oh, then, if the range is collapsed, we don't need to call + // GetHighestInlineParent(), isn't it? if (endInline && !isCollapsed) { - nsCOMPtr resultEndNode = endInline->GetParentNode(); - NS_ENSURE_STATE(mHTMLEditor); - // item.mEndContainer must be content if endInline isn't null - int32_t resultEndOffset = - mHTMLEditor->SplitNodeDeep(*endInline, *item.mEndContainer->AsContent(), - item.mEndOffset, - SplitAtEdges::eDoNotCreateEmptyContainer); - NS_ENSURE_TRUE(resultEndOffset != -1, NS_ERROR_FAILURE); - // reset range - item.mEndContainer = resultEndNode; - item.mEndOffset = resultEndOffset; + RefPtr htmlEditor(mHTMLEditor); + SplitNodeResult splitEndInlineResult = + htmlEditor->SplitNodeDeep(*endInline, + EditorRawDOMPoint(item.mEndContainer, + item.mEndOffset), + SplitAtEdges::eDoNotCreateEmptyContainer); + if (NS_WARN_IF(splitEndInlineResult.Failed())) { + return splitEndInlineResult.Rv(); + } + if (NS_WARN_IF(!mHTMLEditor)) { + return NS_ERROR_FAILURE; + } + EditorRawDOMPoint splitPointAtEnd(splitEndInlineResult.SplitPoint()); + item.mEndContainer = splitPointAtEnd.Container(); + item.mEndOffset = splitPointAtEnd.Offset(); } nsCOMPtr startInline = GetHighestInlineParent(*item.mStartContainer); + if (NS_WARN_IF(!mHTMLEditor)) { + return NS_ERROR_FAILURE; + } if (startInline) { - nsCOMPtr resultStartNode = startInline->GetParentNode(); - NS_ENSURE_STATE(mHTMLEditor); - int32_t resultStartOffset = - mHTMLEditor->SplitNodeDeep(*startInline, - *item.mStartContainer->AsContent(), - item.mStartOffset, - SplitAtEdges::eDoNotCreateEmptyContainer); - NS_ENSURE_TRUE(resultStartOffset != -1, NS_ERROR_FAILURE); - // reset range - item.mStartContainer = resultStartNode; - item.mStartOffset = resultStartOffset; + RefPtr htmlEditor(mHTMLEditor); + SplitNodeResult splitStartInlineResult = + htmlEditor->SplitNodeDeep(*startInline, + EditorRawDOMPoint(item.mStartContainer, + item.mStartOffset), + SplitAtEdges::eDoNotCreateEmptyContainer); + if (NS_WARN_IF(splitStartInlineResult.Failed())) { + return splitStartInlineResult.Rv(); + } + if (NS_WARN_IF(!mHTMLEditor)) { + return NS_ERROR_FAILURE; + } + EditorRawDOMPoint splitPointAtStart(splitStartInlineResult.SplitPoint()); + item.mStartContainer = splitPointAtStart.Container(); + item.mStartOffset = splitPointAtStart.Offset(); } return NS_OK; @@ -6457,45 +6522,42 @@ HTMLEditRules::BustUpInlinesAtBRs( return NS_OK; } - // Else we need to bust up inNode along all the breaks - nsCOMPtr inlineParentNode = aNode.GetParentNode(); - nsCOMPtr splitDeepNode = &aNode; - nsCOMPtr leftNode, rightNode; + // Else we need to bust up aNode along all the breaks + nsCOMPtr nextNode = &aNode; + for (OwningNonNull& brNode : arrayOfBreaks) { + EditorRawDOMPoint atBrNode(brNode); + if (NS_WARN_IF(!atBrNode.IsSet())) { + return NS_ERROR_FAILURE; + } + SplitNodeResult splitNodeResult = + htmlEditor->SplitNodeDeep(*nextNode, atBrNode, + SplitAtEdges::eAllowToCreateEmptyContainer); + if (NS_WARN_IF(splitNodeResult.Failed())) { + return splitNodeResult.Rv(); + } - for (uint32_t i = 0; i < arrayOfBreaks.Length(); i++) { - OwningNonNull breakNode = *arrayOfBreaks[i]->AsElement(); - NS_ENSURE_TRUE(splitDeepNode, NS_ERROR_NULL_POINTER); - NS_ENSURE_TRUE(breakNode->GetParent(), NS_ERROR_NULL_POINTER); - OwningNonNull splitParentNode = *breakNode->GetParent(); - int32_t splitOffset = splitParentNode->IndexOf(breakNode); - - int32_t resultOffset = - htmlEditor->SplitNodeDeep(*splitDeepNode, splitParentNode, splitOffset, - SplitAtEdges::eAllowToCreateEmptyContainer, - getter_AddRefs(leftNode), - getter_AddRefs(rightNode)); - NS_ENSURE_STATE(resultOffset != -1); - - // Put left node in node list - if (leftNode) { + // Put previous node at the split point. + if (splitNodeResult.GetPreviousNode()) { // Might not be a left node. A break might have been at the very // beginning of inline container, in which case SplitNodeDeep would not // actually split anything - aOutArrayOfNodes.AppendElement(*leftNode); + aOutArrayOfNodes.AppendElement(*splitNodeResult.GetPreviousNode()); } - // Move break outside of container and also put in node list - nsresult rv = - htmlEditor->MoveNode(breakNode, inlineParentNode, resultOffset); - NS_ENSURE_SUCCESS(rv, rv); - aOutArrayOfNodes.AppendElement(*breakNode); - // Now rightNode becomes the new node to split - splitDeepNode = rightNode; - } - // Now tack on remaining rightNode, if any, to the list - if (rightNode) { - aOutArrayOfNodes.AppendElement(*rightNode); + // Move break outside of container and also put in node list + EditorRawDOMPoint atNextNode(splitNodeResult.GetNextNode()); + nsresult rv = + htmlEditor->MoveNode(brNode->AsContent(), atNextNode.Container(), + atNextNode.Offset()); + NS_ENSURE_SUCCESS(rv, rv); + aOutArrayOfNodes.AppendElement(*brNode); + + nextNode = splitNodeResult.GetNextNode(); } + + // Now tack on remaining next node. + aOutArrayOfNodes.AppendElement(*nextNode); + return NS_OK; } @@ -6679,15 +6741,23 @@ HTMLEditRules::ReturnInHeader(Selection& aSelection, address_of(node), &aOffset); NS_ENSURE_SUCCESS(rv, rv); + if (NS_WARN_IF(!node->IsContent())) { + return NS_ERROR_FAILURE; + } // Split the header - NS_ENSURE_STATE(node->IsContent()); - htmlEditor->SplitNodeDeep(aHeader, *node->AsContent(), aOffset, - SplitAtEdges::eAllowToCreateEmptyContainer); + ErrorResult error; + SplitNodeResult splitHeaderResult = + htmlEditor->SplitNodeDeep(aHeader, EditorRawDOMPoint(node, aOffset), + SplitAtEdges::eAllowToCreateEmptyContainer); + NS_WARNING_ASSERTION(splitHeaderResult.Succeeded(), + "Failed to split aHeader"); - // If the left-hand heading is empty, put a mozbr in it + // If the previous heading of split point is empty, put a mozbr into it. nsCOMPtr prevItem = htmlEditor->GetPriorHTMLSibling(&aHeader); - if (prevItem && HTMLEditUtils::IsHeader(*prevItem)) { + if (prevItem) { + MOZ_DIAGNOSTIC_ASSERT( + HTMLEditUtils::IsHeader(*prevItem)); bool isEmptyNode; rv = htmlEditor->IsEmptyNode(prevItem, &isEmptyNode); NS_ENSURE_SUCCESS(rv, rv); @@ -6889,25 +6959,28 @@ HTMLEditRules::SplitParagraph(Selection& aSelection, // split para // get ws code to adjust any ws - nsCOMPtr leftPara, rightPara; nsCOMPtr selNode = aStartOfRightNode.Container(); int32_t selOffset = aStartOfRightNode.Offset(); nsresult rv = WSRunObject::PrepareToSplitAcrossBlocks(htmlEditor, address_of(selNode), &selOffset); - // XXX When it fails, why do we need to return selection node? (Why can the - // caller trust the result even when it returns error?) NS_ENSURE_SUCCESS(rv, rv); - // split the paragraph - NS_ENSURE_STATE(selNode->IsContent()); - int32_t offset = - htmlEditor->SplitNodeDeep(aParentDivOrP, *selNode->AsContent(), selOffset, - SplitAtEdges::eAllowToCreateEmptyContainer, - getter_AddRefs(leftPara), - getter_AddRefs(rightPara)); - if (NS_WARN_IF(offset == -1)) { + if (NS_WARN_IF(!selNode->IsContent())) { return NS_ERROR_FAILURE; } + + // Split the paragraph. + SplitNodeResult splitDivOrPResult = + htmlEditor->SplitNodeDeep(aParentDivOrP, + EditorRawDOMPoint(selNode, selOffset), + SplitAtEdges::eAllowToCreateEmptyContainer); + if (NS_WARN_IF(splitDivOrPResult.Failed())) { + return splitDivOrPResult.Rv(); + } + if (NS_WARN_IF(!splitDivOrPResult.DidSplit())) { + return NS_ERROR_FAILURE; + } + // Get rid of the break, if it is visible (otherwise it may be needed to // prevent an empty p). if (aNextBRNode && htmlEditor->IsVisibleBRElement(aNextBRNode)) { @@ -6915,8 +6988,8 @@ HTMLEditRules::SplitParagraph(Selection& aSelection, NS_ENSURE_SUCCESS(rv, rv); } - // remove ID attribute on the paragraph we just created - rv = htmlEditor->RemoveAttribute(rightPara->AsElement(), nsGkAtoms::id); + // Remove ID attribute on the paragraph from the existing right node. + rv = htmlEditor->RemoveAttribute(aParentDivOrP.AsElement(), nsGkAtoms::id); NS_ENSURE_SUCCESS(rv, rv); // We need to ensure to both paragraphs visible even if they are empty. @@ -6925,19 +6998,28 @@ HTMLEditRules::SplitParagraph(Selection& aSelection, // moz-
    will be exposed as
    with Element.innerHTML. Therefore, // we can use normal
    elements for placeholder in this case. // Note that Chromium also behaves so. - rv = InsertBRIfNeeded(*leftPara); + rv = InsertBRIfNeeded(*splitDivOrPResult.GetPreviousNode()); NS_ENSURE_SUCCESS(rv, rv); - rv = InsertBRIfNeeded(*rightPara); + rv = InsertBRIfNeeded(*splitDivOrPResult.GetNextNode()); NS_ENSURE_SUCCESS(rv, rv); // selection to beginning of right hand para; // look inside any containers that are up front. - nsIContent* child = htmlEditor->GetLeftmostChild(rightPara, true); + nsIContent* child = htmlEditor->GetLeftmostChild(&aParentDivOrP, true); if (EditorBase::IsTextNode(child) || htmlEditor->IsContainer(child)) { - aSelection.Collapse(child, 0); + EditorRawDOMPoint atStartOfChild(child, 0); + ErrorResult error; + aSelection.Collapse(atStartOfChild, error); + if (NS_WARN_IF(error.Failed())) { + error.SuppressException(); + } } else { EditorRawDOMPoint atChild(child); - aSelection.Collapse(atChild); + ErrorResult error; + aSelection.Collapse(atChild, error); + if (NS_WARN_IF(error.Failed())) { + error.SuppressException(); + } } return NS_OK; } @@ -7023,10 +7105,16 @@ HTMLEditRules::ReturnInListItem(Selection& aSelection, rv = WSRunObject::PrepareToSplitAcrossBlocks(htmlEditor, address_of(selNode), &aOffset); NS_ENSURE_SUCCESS(rv, rv); - // Now split list item - NS_ENSURE_STATE(selNode->IsContent()); - htmlEditor->SplitNodeDeep(aListItem, *selNode->AsContent(), aOffset, - SplitAtEdges::eAllowToCreateEmptyContainer); + if (NS_WARN_IF(!selNode->IsContent())) { + return NS_ERROR_FAILURE; + } + + // Now split the list item. + SplitNodeResult splitListItemResult = + htmlEditor->SplitNodeDeep(aListItem, EditorRawDOMPoint(selNode, aOffset), + SplitAtEdges::eAllowToCreateEmptyContainer); + NS_WARNING_ASSERTION(splitListItemResult.Succeeded(), + "Failed to split the list item"); // Hack: until I can change the damaged doc range code back to being // extra-inclusive, I have to manually detect certain list items that may be @@ -7074,8 +7162,11 @@ HTMLEditRules::ReturnInListItem(Selection& aSelection, if (NS_WARN_IF(!atBrNode.IsSetAndValid())) { return NS_ERROR_FAILURE; } - rv = aSelection.Collapse(atBrNode); - NS_ENSURE_SUCCESS(rv, rv); + ErrorResult error; + aSelection.Collapse(atBrNode, error); + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); + } return NS_OK; } } else { @@ -7091,19 +7182,26 @@ HTMLEditRules::ReturnInListItem(Selection& aSelection, if (NS_WARN_IF(!atVisNode.IsSetAndValid())) { return NS_ERROR_FAILURE; } - rv = aSelection.Collapse(atVisNode); - NS_ENSURE_SUCCESS(rv, rv); - return NS_OK; - } else { - rv = aSelection.Collapse(visNode, visOffset); - NS_ENSURE_SUCCESS(rv, rv); + ErrorResult error; + aSelection.Collapse(atVisNode, error); + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); + } return NS_OK; } + + rv = aSelection.Collapse(visNode, visOffset); + NS_ENSURE_SUCCESS(rv, rv); + return NS_OK; } } } - rv = aSelection.Collapse(&aListItem, 0); - NS_ENSURE_SUCCESS(rv, rv); + + ErrorResult error; + aSelection.Collapse(EditorRawDOMPoint(&aListItem, 0), error); + if (NS_WARN_IF(error.Failed())) { + return error.StealNSResult(); + } return NS_OK; } @@ -7424,7 +7522,14 @@ HTMLEditRules::SplitAsNeeded(nsAtom& aTag, int32_t& inOutOffset, nsCOMPtr* inOutChildAtOffset) { - NS_ENSURE_TRUE(inOutParent, NS_ERROR_NULL_POINTER); + if (NS_WARN_IF(!inOutParent)) { + return NS_ERROR_INVALID_ARG; + } + + if (NS_WARN_IF(!mHTMLEditor)) { + return NS_ERROR_NOT_AVAILABLE; + } + RefPtr htmlEditor(mHTMLEditor); // Check that we have a place that can legally contain the tag nsCOMPtr tagParent, splitNode; @@ -7434,16 +7539,15 @@ HTMLEditRules::SplitAsNeeded(nsAtom& aTag, // Don't leave the active editing host NS_ENSURE_STATE(mHTMLEditor); - if (!mHTMLEditor->IsDescendantOfEditorRoot(parent)) { + if (!htmlEditor->IsDescendantOfEditorRoot(parent)) { // XXX Why do we need to check mHTMLEditor again here? NS_ENSURE_STATE(mHTMLEditor); - if (parent != mHTMLEditor->GetActiveEditingHost()) { + if (parent != htmlEditor->GetActiveEditingHost()) { return NS_ERROR_FAILURE; } } - NS_ENSURE_STATE(mHTMLEditor); - if (mHTMLEditor->CanContainTag(*parent, aTag)) { + if (htmlEditor->CanContainTag(*parent, aTag)) { // Success tagParent = parent; break; @@ -7451,21 +7555,31 @@ HTMLEditRules::SplitAsNeeded(nsAtom& aTag, splitNode = parent; } + if (!tagParent) { // Could not find a place to build tag! return NS_ERROR_FAILURE; } - if (splitNode && splitNode->IsContent() && inOutParent->IsContent()) { - // We found a place for block, but above inOutParent. We need to split. - NS_ENSURE_STATE(mHTMLEditor); - int32_t offset = - mHTMLEditor->SplitNodeDeep(*splitNode->AsContent(), - *inOutParent->AsContent(), inOutOffset, - SplitAtEdges::eAllowToCreateEmptyContainer, - nullptr, nullptr, inOutChildAtOffset); - NS_ENSURE_STATE(offset != -1); - inOutParent = tagParent; - inOutOffset = offset; + + if (!splitNode || !splitNode->IsContent() || !inOutParent->IsContent()) { + return NS_OK; + } + + // We found a place for block, but above inOutParent. We need to split. + NS_ENSURE_STATE(mHTMLEditor); + SplitNodeResult splitNodeResult = + mHTMLEditor->SplitNodeDeep(*splitNode->AsContent(), + EditorRawDOMPoint(inOutParent, inOutOffset), + SplitAtEdges::eAllowToCreateEmptyContainer); + if (NS_WARN_IF(splitNodeResult.Failed())) { + return splitNodeResult.Rv(); + } + + EditorRawDOMPoint splitPoint(splitNodeResult.SplitPoint()); + inOutParent = splitPoint.Container(); + inOutOffset = splitPoint.Offset(); + if (inOutChildAtOffset) { + *inOutChildAtOffset = splitPoint.GetChildAtOffset(); } return NS_OK; } diff --git a/editor/libeditor/HTMLEditor.cpp b/editor/libeditor/HTMLEditor.cpp index 1a390e141a66..02c88531077c 100644 --- a/editor/libeditor/HTMLEditor.cpp +++ b/editor/libeditor/HTMLEditor.cpp @@ -1619,19 +1619,18 @@ HTMLEditor::InsertNodeAtPoint(nsIDOMNode* aNode, parent = parent->GetParent(); } if (parent != topChild) { - nsCOMPtr child; - if (ioChildAtOffset) { - child = do_QueryInterface(*ioChildAtOffset); + // We need to split some levels above the original selection parent. + SplitNodeResult splitNodeResult = + SplitNodeDeep(*topChild, EditorRawDOMPoint(origParent, *ioOffset), + aSplitAtEdges); + if (NS_WARN_IF(splitNodeResult.Failed())) { + return splitNodeResult.Rv(); } - // we need to split some levels above the original selection parent - int32_t offset = SplitNodeDeep(*topChild, *origParent, *ioOffset, - aSplitAtEdges, - nullptr, nullptr, address_of(child)); - NS_ENSURE_STATE(offset != -1); - *ioParent = GetAsDOMNode(parent); - *ioOffset = offset; + EditorRawDOMPoint splitPoint(splitNodeResult.SplitPoint()); + *ioParent = GetAsDOMNode(splitPoint.Container()); + *ioOffset = splitPoint.Offset(); if (ioChildAtOffset) { - *ioChildAtOffset = GetAsDOMNode(child); + *ioChildAtOffset = GetAsDOMNode(splitPoint.GetChildAtOffset()); } } // Now we can insert the new node @@ -1975,52 +1974,56 @@ HTMLEditor::MakeOrChangeList(const nsAString& aListType, return rv; } - if (!handled) { - // Find out if the selection is collapsed: - bool isCollapsed = selection->Collapsed(); - - NS_ENSURE_TRUE(selection->GetRangeAt(0) && - selection->GetRangeAt(0)->GetStartContainer() && - selection->GetRangeAt(0)->GetStartContainer()->IsContent(), - NS_ERROR_FAILURE); - OwningNonNull node = - *selection->GetRangeAt(0)->GetStartContainer()->AsContent(); - int32_t offset = selection->GetRangeAt(0)->StartOffset(); - nsCOMPtr child = - selection->GetRangeAt(0)->GetChildAtStartOffset(); - - if (isCollapsed) { - // have to find a place to put the list - nsCOMPtr parent = node; - nsCOMPtr topChild = node; - - RefPtr listAtom = NS_Atomize(aListType); - while (!CanContainTag(*parent, *listAtom)) { - topChild = parent; - parent = parent->GetParent(); - } - - if (parent != node) { - // we need to split up to the child of parent - offset = SplitNodeDeep(*topChild, *node, offset, - SplitAtEdges::eAllowToCreateEmptyContainer, - nullptr, nullptr, - address_of(child)); - NS_ENSURE_STATE(offset != -1); - } - - // make a list - MOZ_DIAGNOSTIC_ASSERT(child); - EditorRawDOMPoint atChild(parent, child, offset); - RefPtr newList = CreateNode(listAtom, atChild); - NS_ENSURE_STATE(newList); - // make a list item - EditorRawDOMPoint atStartOfNewList(newList, 0); - RefPtr newItem = CreateNode(nsGkAtoms::li, atStartOfNewList); - NS_ENSURE_STATE(newItem); - rv = selection->Collapse(newItem, 0); - NS_ENSURE_SUCCESS(rv, rv); + if (!handled && selection->Collapsed()) { + nsRange* firstRange = selection->GetRangeAt(0); + if (NS_WARN_IF(!firstRange)) { + return NS_ERROR_FAILURE; } + + EditorRawDOMPoint atStartOfSelection(firstRange->StartRef()); + if (NS_WARN_IF(!atStartOfSelection.IsSet()) || + NS_WARN_IF(!atStartOfSelection.Container()->IsContent())) { + return NS_ERROR_FAILURE; + } + + // Have to find a place to put the list. + EditorDOMPoint pointToInsertList(atStartOfSelection); + + RefPtr listAtom = NS_Atomize(aListType); + while (!CanContainTag(*pointToInsertList.Container(), *listAtom)) { + pointToInsertList.Set(pointToInsertList.Container()); + if (NS_WARN_IF(!pointToInsertList.IsSet()) || + NS_WARN_IF(!pointToInsertList.Container()->IsContent())) { + return NS_ERROR_FAILURE; + } + } + + if (pointToInsertList.Container() != atStartOfSelection.Container()) { + // We need to split up to the child of parent. + SplitNodeResult splitNodeResult = + SplitNodeDeep(*pointToInsertList.GetChildAtOffset(), + atStartOfSelection, + SplitAtEdges::eAllowToCreateEmptyContainer); + if (NS_WARN_IF(splitNodeResult.Failed())) { + return splitNodeResult.Rv(); + } + pointToInsertList = splitNodeResult.SplitPoint(); + if (NS_WARN_IF(!pointToInsertList.IsSet())) { + return NS_ERROR_FAILURE; + } + } + + // Create a list and insert it before the right node if we split some + // parents of start of selection above, or just start of selection + // otherwise. + RefPtr newList = CreateNode(listAtom, pointToInsertList.AsRaw()); + NS_ENSURE_STATE(newList); + // make a list item + EditorRawDOMPoint atStartOfNewList(newList, 0); + RefPtr newItem = CreateNode(nsGkAtoms::li, atStartOfNewList); + NS_ENSURE_STATE(newItem); + rv = selection->Collapse(newItem, 0); + NS_ENSURE_SUCCESS(rv, rv); } return rules->DidDoAction(selection, &ruleInfo, rv); @@ -2120,51 +2123,55 @@ HTMLEditor::InsertBasicBlock(const nsAString& aBlockType) return rv; } - if (!handled) { - // Find out if the selection is collapsed: - bool isCollapsed = selection->Collapsed(); - - NS_ENSURE_TRUE(selection->GetRangeAt(0) && - selection->GetRangeAt(0)->GetStartContainer() && - selection->GetRangeAt(0)->GetStartContainer()->IsContent(), - NS_ERROR_FAILURE); - OwningNonNull node = - *selection->GetRangeAt(0)->GetStartContainer()->AsContent(); - int32_t offset = selection->GetRangeAt(0)->StartOffset(); - nsCOMPtr child = - selection->GetRangeAt(0)->GetChildAtStartOffset(); - - if (isCollapsed) { - // have to find a place to put the block - nsCOMPtr parent = node; - nsCOMPtr topChild = node; - - RefPtr blockAtom = NS_Atomize(aBlockType); - while (!CanContainTag(*parent, *blockAtom)) { - NS_ENSURE_TRUE(parent->GetParent(), NS_ERROR_FAILURE); - topChild = parent; - parent = parent->GetParent(); - } - - if (parent != node) { - // we need to split up to the child of parent - offset = SplitNodeDeep(*topChild, *node, offset, - SplitAtEdges::eAllowToCreateEmptyContainer, - nullptr, nullptr, - address_of(child)); - NS_ENSURE_STATE(offset != -1); - } - - // make a block - MOZ_DIAGNOSTIC_ASSERT(child); - EditorRawDOMPoint atChild(parent, child, offset); - RefPtr newBlock = CreateNode(blockAtom, atChild); - NS_ENSURE_STATE(newBlock); - - // reposition selection to inside the block - rv = selection->Collapse(newBlock, 0); - NS_ENSURE_SUCCESS(rv, rv); + if (!handled && selection->Collapsed()) { + nsRange* firstRange = selection->GetRangeAt(0); + if (NS_WARN_IF(!firstRange)) { + return NS_ERROR_FAILURE; } + + EditorRawDOMPoint atStartOfSelection(firstRange->StartRef()); + if (NS_WARN_IF(!atStartOfSelection.IsSet()) || + NS_WARN_IF(!atStartOfSelection.Container()->IsContent())) { + return NS_ERROR_FAILURE; + } + + // Have to find a place to put the block. + EditorDOMPoint pointToInsertBlock(atStartOfSelection); + + RefPtr blockAtom = NS_Atomize(aBlockType); + while (!CanContainTag(*pointToInsertBlock.Container(), *blockAtom)) { + pointToInsertBlock.Set(pointToInsertBlock.Container()); + if (NS_WARN_IF(!pointToInsertBlock.IsSet()) || + NS_WARN_IF(!pointToInsertBlock.Container()->IsContent())) { + return NS_ERROR_FAILURE; + } + } + + if (pointToInsertBlock.Container() != atStartOfSelection.Container()) { + // We need to split up to the child of the point to insert a block. + SplitNodeResult splitBlockResult = + SplitNodeDeep(*pointToInsertBlock.GetChildAtOffset(), + atStartOfSelection, + SplitAtEdges::eAllowToCreateEmptyContainer); + if (NS_WARN_IF(splitBlockResult.Failed())) { + return splitBlockResult.Rv(); + } + pointToInsertBlock = splitBlockResult.SplitPoint(); + if (NS_WARN_IF(!pointToInsertBlock.IsSet())) { + return NS_ERROR_FAILURE; + } + } + + // Create a block and insert it before the right node if we split some + // parents of start of selection above, or just start of selection + // otherwise. + RefPtr newBlock = + CreateNode(blockAtom, pointToInsertBlock.AsRaw()); + NS_ENSURE_STATE(newBlock); + + // reposition selection to inside the block + rv = selection->Collapse(newBlock, 0); + NS_ENSURE_SUCCESS(rv, rv); } return rules->DidDoAction(selection, &ruleInfo, rv); @@ -2198,57 +2205,62 @@ HTMLEditor::Indent(const nsAString& aIndent) return rv; } - if (!handled) { - // Do default - insert a blockquote node if selection collapsed - bool isCollapsed = selection->Collapsed(); + if (!handled && selection->Collapsed() && aIndent.EqualsLiteral("indent")) { + nsRange* firstRange = selection->GetRangeAt(0); + if (NS_WARN_IF(!firstRange)) { + return NS_ERROR_FAILURE; + } - NS_ENSURE_TRUE(selection->GetRangeAt(0) && - selection->GetRangeAt(0)->GetStartContainer() && - selection->GetRangeAt(0)->GetStartContainer()->IsContent(), - NS_ERROR_FAILURE); - OwningNonNull node = - *selection->GetRangeAt(0)->GetStartContainer()->AsContent(); - int32_t offset = selection->GetRangeAt(0)->StartOffset(); - nsCOMPtr child = - selection->GetRangeAt(0)->GetChildAtStartOffset(); + EditorRawDOMPoint atStartOfSelection(firstRange->StartRef()); + if (NS_WARN_IF(!atStartOfSelection.IsSet()) || + NS_WARN_IF(!atStartOfSelection.Container()->IsContent())) { + return NS_ERROR_FAILURE; + } - if (aIndent.EqualsLiteral("indent")) { - if (isCollapsed) { - // have to find a place to put the blockquote - nsCOMPtr parent = node; - nsCOMPtr topChild = node; - while (!CanContainTag(*parent, *nsGkAtoms::blockquote)) { - NS_ENSURE_TRUE(parent->GetParent(), NS_ERROR_FAILURE); - topChild = parent; - parent = parent->GetParent(); - } + // Have to find a place to put the blockquote. + EditorDOMPoint pointToInsertBlockquote(atStartOfSelection); - if (parent != node) { - // we need to split up to the child of parent - offset = SplitNodeDeep(*topChild, *node, offset, - SplitAtEdges::eAllowToCreateEmptyContainer, - nullptr, nullptr, - address_of(child)); - NS_ENSURE_STATE(offset != -1); - } - - // make a blockquote - MOZ_DIAGNOSTIC_ASSERT(child); - EditorRawDOMPoint atChild(parent, child, offset); - RefPtr newBQ = CreateNode(nsGkAtoms::blockquote, atChild); - NS_ENSURE_STATE(newBQ); - // put a space in it so layout will draw the list item - rv = selection->Collapse(newBQ, 0); - NS_ENSURE_SUCCESS(rv, rv); - rv = InsertText(NS_LITERAL_STRING(" ")); - NS_ENSURE_SUCCESS(rv, rv); - // reposition selection to before the space character - NS_ENSURE_STATE(selection->GetRangeAt(0)); - rv = selection->Collapse(selection->GetRangeAt(0)->GetStartContainer(), - 0); - NS_ENSURE_SUCCESS(rv, rv); + while (!CanContainTag(*pointToInsertBlockquote.Container(), + *nsGkAtoms::blockquote)) { + pointToInsertBlockquote.Set(pointToInsertBlockquote.Container()); + if (NS_WARN_IF(!pointToInsertBlockquote.IsSet()) || + NS_WARN_IF(!pointToInsertBlockquote.Container()->IsContent())) { + return NS_ERROR_FAILURE; } } + + if (pointToInsertBlockquote.Container() != + atStartOfSelection.Container()) { + // We need to split up to the child of parent. + SplitNodeResult splitBlockquoteResult = + SplitNodeDeep(*pointToInsertBlockquote.GetChildAtOffset(), + atStartOfSelection, + SplitAtEdges::eAllowToCreateEmptyContainer); + if (NS_WARN_IF(splitBlockquoteResult.Failed())) { + return splitBlockquoteResult.Rv(); + } + pointToInsertBlockquote = splitBlockquoteResult.SplitPoint(); + if (NS_WARN_IF(!pointToInsertBlockquote.IsSet())) { + return NS_ERROR_FAILURE; + } + } + + // Create a list and insert it before the right node if we split some + // parents of start of selection above, or just start of selection + // otherwise. + RefPtr newBQ = + CreateNode(nsGkAtoms::blockquote, pointToInsertBlockquote.AsRaw()); + NS_ENSURE_STATE(newBQ); + // put a space in it so layout will draw the list item + rv = selection->Collapse(newBQ, 0); + NS_ENSURE_SUCCESS(rv, rv); + rv = InsertText(NS_LITERAL_STRING(" ")); + NS_ENSURE_SUCCESS(rv, rv); + // reposition selection to before the space character + NS_ENSURE_STATE(selection->GetRangeAt(0)); + rv = selection->Collapse(selection->GetRangeAt(0)->GetStartContainer(), + 0); + NS_ENSURE_SUCCESS(rv, rv); } return rules->DidDoAction(selection, &ruleInfo, rv); } diff --git a/editor/libeditor/HTMLEditorDataTransfer.cpp b/editor/libeditor/HTMLEditorDataTransfer.cpp index 6231dff8efca..1e391555222a 100644 --- a/editor/libeditor/HTMLEditorDataTransfer.cpp +++ b/editor/libeditor/HTMLEditorDataTransfer.cpp @@ -272,10 +272,6 @@ HTMLEditor::DoInsertHTMLWithContext(const nsAString& aInputString, } // Are there any table elements in the list? - // node and offset for insertion - nsCOMPtr parentNode; - int32_t offsetOfNewNode; - // check for table cell selection mode bool cellSelectionMode = false; nsCOMPtr cell; @@ -332,6 +328,8 @@ HTMLEditor::DoInsertHTMLWithContext(const nsAString& aInputString, if (!handled) { // The rules code (WillDoAction above) might have changed the selection. // refresh our memory... + nsCOMPtr parentNode; + int32_t offsetOfNewNode; rv = GetStartNodeAndOffset(selection, getter_AddRefs(parentNode), &offsetOfNewNode); NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_TRUE(parentNode, NS_ERROR_FAILURE); @@ -357,15 +355,22 @@ HTMLEditor::DoInsertHTMLWithContext(const nsAString& aInputString, // Are we in a text node? If so, split it. if (IsTextNode(parentNode)) { nsCOMPtr parentContent = do_QueryInterface(parentNode); - NS_ENSURE_STATE(parentContent || !parentNode); - offsetOfNewNode = - SplitNodeDeep(*parentContent, *parentContent, offsetOfNewNode, + EditorRawDOMPoint pointToSplit(parentContent, offsetOfNewNode); + if (NS_WARN_IF(!pointToSplit.IsSet())) { + return NS_ERROR_FAILURE; + } + SplitNodeResult splitNodeResult = + SplitNodeDeep(*parentContent, pointToSplit, SplitAtEdges::eAllowToCreateEmptyContainer); - NS_ENSURE_STATE(offsetOfNewNode != -1); - nsCOMPtr temp; - rv = parentNode->GetParentNode(getter_AddRefs(temp)); - NS_ENSURE_SUCCESS(rv, rv); - parentNode = temp; + if (NS_WARN_IF(splitNodeResult.Failed())) { + return splitNodeResult.Rv(); + } + EditorRawDOMPoint splitPoint(splitNodeResult.SplitPoint()); + if (NS_WARN_IF(!splitPoint.IsSet())) { + return NS_ERROR_FAILURE; + } + parentNode = do_QueryInterface(splitPoint.Container()); + offsetOfNewNode = splitPoint.Offset(); } // build up list of parents of first node in list that are either @@ -649,12 +654,13 @@ HTMLEditor::DoInsertHTMLWithContext(const nsAString& aInputString, NS_ENSURE_STATE(linkContent || !link); nsCOMPtr selContent = do_QueryInterface(selNode); NS_ENSURE_STATE(selContent || !selNode); - nsCOMPtr leftLink; - SplitNodeDeep(*linkContent, *selContent, selOffset, - SplitAtEdges::eDoNotCreateEmptyContainer, - getter_AddRefs(leftLink)); - if (leftLink) { - EditorRawDOMPoint afterLeftLink(leftLink); + SplitNodeResult splitLinkResult = + SplitNodeDeep(*linkContent, EditorRawDOMPoint(selContent, selOffset), + SplitAtEdges::eDoNotCreateEmptyContainer); + NS_WARNING_ASSERTION(splitLinkResult.Succeeded(), + "Failed to split the link"); + if (splitLinkResult.GetPreviousNode()) { + EditorRawDOMPoint afterLeftLink(splitLinkResult.GetPreviousNode()); if (afterLeftLink.AdvanceOffset()) { selection->Collapse(afterLeftLink); } diff --git a/editor/libeditor/HTMLStyleEditor.cpp b/editor/libeditor/HTMLStyleEditor.cpp index 12e7ea8e73d2..4d2e51631cd9 100644 --- a/editor/libeditor/HTMLStyleEditor.cpp +++ b/editor/libeditor/HTMLStyleEditor.cpp @@ -525,6 +525,13 @@ HTMLEditor::SplitStyleAbovePoint(nsCOMPtr* aNode, NS_ENSURE_TRUE(aNode && *aNode && aOffset, NS_ERROR_NULL_POINTER); NS_ENSURE_TRUE((*aNode)->IsContent(), NS_OK); + if (aOutLeftNode) { + *aOutLeftNode = nullptr; + } + if (aOutRightNode) { + *aOutRightNode = nullptr; + } + // Split any matching style nodes above the node/offset OwningNonNull node = *(*aNode)->AsContent(); @@ -553,13 +560,21 @@ HTMLEditor::SplitStyleAbovePoint(nsCOMPtr* aNode, // or the style is specified in the style attribute isSet) { // Found a style node we need to split - int32_t offset = SplitNodeDeep(*node, *(*aNode)->AsContent(), *aOffset, - SplitAtEdges::eAllowToCreateEmptyContainer, - aOutLeftNode, aOutRightNode); - NS_ENSURE_TRUE(offset != -1, NS_ERROR_FAILURE); - // reset startNode/startOffset - *aNode = node->GetParent(); - *aOffset = offset; + SplitNodeResult splitNodeResult = + SplitNodeDeep(*node, EditorRawDOMPoint(*aNode, *aOffset), + SplitAtEdges::eAllowToCreateEmptyContainer); + NS_WARNING_ASSERTION(splitNodeResult.Succeeded(), + "Failed to split the node"); + + EditorRawDOMPoint atRightNode(splitNodeResult.SplitPoint()); + *aNode = atRightNode.Container(); + *aOffset = atRightNode.Offset(); + if (aOutLeftNode) { + NS_IF_ADDREF(*aOutLeftNode = splitNodeResult.GetPreviousNode()); + } + if (aOutRightNode) { + NS_IF_ADDREF(*aOutRightNode = splitNodeResult.GetNextNode()); + } } node = node->GetParent(); } From 02038d75da918611935c6e80fe0a9d5b1822272c Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Fri, 17 Nov 2017 17:00:56 +0900 Subject: [PATCH 33/78] Bug 1413181 - part 11: Create AutoEditorDOMPointOffsetInvalidator stack class for automatically invalidate offset of EditorDOMPoint r=m_kato In the following patch, we need to invalidate offset a lot of places after splitting nodes. Therefore, there should be a helper stack class before that. MozReview-Commit-ID: BgijAU7OizU --HG-- extra : rebase_source : 520f29dacdffe5f7137ba7f11b289241b5fbface --- editor/libeditor/EditorDOMPoint.h | 96 +++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/editor/libeditor/EditorDOMPoint.h b/editor/libeditor/EditorDOMPoint.h index 68f56e0657a4..1020a8c751cf 100644 --- a/editor/libeditor/EditorDOMPoint.h +++ b/editor/libeditor/EditorDOMPoint.h @@ -120,6 +120,102 @@ private: } }; +/** + * AutoEditorDOMPointOffsetInvalidator is useful if DOM tree will be changed + * when EditorDOMPoint instance is available and keeps referring same child + * node. + * + * This class automatically guarantees that given EditorDOMPoint instance + * stores the child node and invalidates its offset when the instance is + * destroyed. Additionally, users of this class can invalidate the offset + * manually when they need. + */ +class MOZ_STACK_CLASS AutoEditorDOMPointOffsetInvalidator final +{ +public: + explicit AutoEditorDOMPointOffsetInvalidator(EditorDOMPoint& aPoint) + : mPoint(aPoint) + { + MOZ_ASSERT(aPoint.IsSetAndValid()); + mChild = mPoint.GetChildAtOffset(); + } + + ~AutoEditorDOMPointOffsetInvalidator() + { + InvalidateOffset(); + } + + /** + * Manually, invalidate offset of the given point. + */ + void InvalidateOffset() + { + if (mChild) { + mPoint.Set(mChild); + } else { + // If the point referred after the last child, let's keep referring + // after current last node of the old container. + mPoint.Set(mPoint.Container(), mPoint.Container()->Length()); + } + } + +private: + EditorDOMPoint& mPoint; + // Needs to store child node by ourselves because EditorDOMPoint stores + // child node with mRef which is previous sibling of current child node. + // Therefore, we cannot keep referring it if it's first child. + nsCOMPtr mChild; + + AutoEditorDOMPointOffsetInvalidator() = delete; + AutoEditorDOMPointOffsetInvalidator( + const AutoEditorDOMPointOffsetInvalidator& aOther) = delete; + const AutoEditorDOMPointOffsetInvalidator& operator=( + const AutoEditorDOMPointOffsetInvalidator& aOther) = delete; +}; + +/** + * AutoEditorDOMPointChildInvalidator is useful if DOM tree will be changed + * when EditorDOMPoint instance is available and keeps referring same container + * and offset in it. + * + * This class automatically guarantees that given EditorDOMPoint instance + * stores offset and invalidates its child node when the instance is destroyed. + * Additionally, users of this class can invalidate the child manually when + * they need. + */ +class MOZ_STACK_CLASS AutoEditorDOMPointChildInvalidator final +{ +public: + explicit AutoEditorDOMPointChildInvalidator(EditorDOMPoint& aPoint) + : mPoint(aPoint) + { + MOZ_ASSERT(aPoint.IsSetAndValid()); + Unused << mPoint.Offset(); + } + + ~AutoEditorDOMPointChildInvalidator() + { + InvalidateChild(); + } + + /** + * Manually, invalidate child of the given point. + */ + void InvalidateChild() + { + mPoint.Set(mPoint.Container(), mPoint.Offset()); + } + +private: + EditorDOMPoint& mPoint; + + AutoEditorDOMPointChildInvalidator() = delete; + AutoEditorDOMPointChildInvalidator( + const AutoEditorDOMPointChildInvalidator& aOther) = delete; + const AutoEditorDOMPointChildInvalidator& operator=( + const AutoEditorDOMPointChildInvalidator& aOther) = delete; +}; + } // namespace mozilla #endif // #ifndef mozilla_EditorDOMPoint_h From 7537ae3755487c29c5d1bcadc6c2aff1c3b49af7 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Fri, 17 Nov 2017 16:03:11 +0900 Subject: [PATCH 34/78] Bug 1413181 - part 12: Redesign and rename HTMLEditRules::SplitAsNeeded() r=m_kato Now, we can make HTMLEditRules::SplitAsNeeded() use |SplitNodeResult| as its result and |const EditorRawDOMPoint&| as specifying start of the deepest right node. Then, the implementation becomes simpler. And I think that we should rename it to MaybeSplitAncestorsForInsert(). Additionally, this patch makes it stop calling EditorBase::IsDescendantOfEditorRoot() and HTMLEditor::GetActiveEditingHost() because they are really expensive. Instead, it should check if the given start point of the deepest right node is in active editing host before the loop and if the loop reaches editing host. MozReview-Commit-ID: KKpj5uyT2J --HG-- extra : rebase_source : 0c9e9e9e28505b0fb5752e1cd4d42f64d22af3e7 --- editor/libeditor/HTMLEditRules.cpp | 1180 ++++++++++++++-------------- editor/libeditor/HTMLEditRules.h | 29 +- 2 files changed, 604 insertions(+), 605 deletions(-) diff --git a/editor/libeditor/HTMLEditRules.cpp b/editor/libeditor/HTMLEditRules.cpp index 50178296c055..357ddd464cc6 100644 --- a/editor/libeditor/HTMLEditRules.cpp +++ b/editor/libeditor/HTMLEditRules.cpp @@ -3410,6 +3410,11 @@ HTMLEditRules::WillMakeList(Selection* aSelection, if (!aSelection || !aListType || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; } + if (NS_WARN_IF(!mHTMLEditor)) { + return NS_ERROR_NOT_AVAILABLE; + } + RefPtr htmlEditor(mHTMLEditor); + OwningNonNull listType = NS_Atomize(*aListType); WillInsert(*aSelection, aCancel); @@ -3439,8 +3444,8 @@ HTMLEditRules::WillMakeList(Selection* aSelection, nsresult rv = NormalizeSelection(aSelection); NS_ENSURE_SUCCESS(rv, rv); - NS_ENSURE_STATE(mHTMLEditor); - AutoSelectionRestorer selectionRestorer(aSelection, mHTMLEditor); + + AutoSelectionRestorer selectionRestorer(aSelection, htmlEditor); nsTArray> arrayOfNodes; rv = GetListActionNodes(arrayOfNodes, @@ -3464,40 +3469,41 @@ HTMLEditRules::WillMakeList(Selection* aSelection, // if only breaks, delete them if (bOnlyBreaks) { for (auto& node : arrayOfNodes) { - NS_ENSURE_STATE(mHTMLEditor); - rv = mHTMLEditor->DeleteNode(node); + rv = htmlEditor->DeleteNode(node); NS_ENSURE_SUCCESS(rv, rv); } } - // get selection location - NS_ENSURE_STATE(aSelection->RangeCount()); - nsCOMPtr container = - aSelection->GetRangeAt(0)->GetStartContainer(); - int32_t offset = aSelection->GetRangeAt(0)->StartOffset(); - nsCOMPtr child = - aSelection->GetRangeAt(0)->GetChildAtStartOffset(); - NS_ENSURE_STATE(container); + nsRange* firstRange = aSelection->GetRangeAt(0); + if (NS_WARN_IF(!firstRange)) { + return NS_ERROR_FAILURE; + } - // make sure we can put a list here - NS_ENSURE_STATE(mHTMLEditor); - if (!mHTMLEditor->CanContainTag(*container, listType)) { + EditorDOMPoint atStartOfSelection(firstRange->StartRef()); + if (NS_WARN_IF(!atStartOfSelection.IsSet())) { + return NS_ERROR_FAILURE; + } + + // Make sure we can put a list here. + if (!htmlEditor->CanContainTag(*atStartOfSelection.Container(), + listType)) { *aCancel = true; return NS_OK; } - rv = SplitAsNeeded(listType, container, offset, - address_of(child)); - NS_ENSURE_SUCCESS(rv, rv); - NS_ENSURE_STATE(mHTMLEditor); - EditorRawDOMPoint atListItemToInsertBefore(container, child, offset); + + SplitNodeResult splitAtSelectionStartResult = + MaybeSplitAncestorsForInsert(listType, atStartOfSelection.AsRaw()); + if (NS_WARN_IF(splitAtSelectionStartResult.Failed())) { + return splitAtSelectionStartResult.Rv(); + } RefPtr theList = - mHTMLEditor->CreateNode(listType, atListItemToInsertBefore); + htmlEditor->CreateNode(listType, + splitAtSelectionStartResult.SplitPoint()); NS_ENSURE_STATE(theList); - NS_ENSURE_STATE(mHTMLEditor); EditorRawDOMPoint atFirstListItemToInsertBefore(theList, 0); RefPtr theListItem = - mHTMLEditor->CreateNode(itemType, atFirstListItemToInsertBefore); + htmlEditor->CreateNode(itemType, atFirstListItemToInsertBefore); NS_ENSURE_STATE(theListItem); // remember our new block for postprocessing @@ -3530,7 +3536,6 @@ HTMLEditRules::WillMakeList(Selection* aSelection, nsCOMPtr newBlock; NS_ENSURE_STATE(arrayOfNodes[i]->IsContent()); OwningNonNull curNode = *arrayOfNodes[i]->AsContent(); - nsCOMPtr curChild(curNode); // make sure we don't assemble content that is in different table cells // into the same list. respect table cell boundaries when listifying. @@ -3541,11 +3546,9 @@ HTMLEditRules::WillMakeList(Selection* aSelection, // If curNode is a break, delete it, and quit remembering prev list item. // If an empty inline container, delete it, but still remember the previous // item. - NS_ENSURE_STATE(mHTMLEditor); - if (mHTMLEditor->IsEditable(curNode) && (TextEditUtils::IsBreak(curNode) || - IsEmptyInline(curNode))) { - NS_ENSURE_STATE(mHTMLEditor); - rv = mHTMLEditor->DeleteNode(curNode); + if (htmlEditor->IsEditable(curNode) && (TextEditUtils::IsBreak(curNode) || + IsEmptyInline(curNode))) { + rv = htmlEditor->DeleteNode(curNode); NS_ENSURE_SUCCESS(rv, rv); if (TextEditUtils::IsBreak(curNode)) { prevListItem = nullptr; @@ -3560,15 +3563,13 @@ HTMLEditRules::WillMakeList(Selection* aSelection, // whole list and then RemoveContainer() on the list. ConvertListType // first: that routine handles converting the list item types, if // needed - NS_ENSURE_STATE(mHTMLEditor); - rv = mHTMLEditor->MoveNode(curNode, curList, -1); + rv = htmlEditor->MoveNode(curNode, curList, -1); NS_ENSURE_SUCCESS(rv, rv); newBlock = ConvertListType(curNode->AsElement(), listType, itemType); if (NS_WARN_IF(!newBlock)) { return NS_ERROR_FAILURE; } - NS_ENSURE_STATE(mHTMLEditor); - rv = mHTMLEditor->RemoveBlockContainer(*newBlock); + rv = htmlEditor->RemoveBlockContainer(*newBlock); NS_ENSURE_SUCCESS(rv, rv); } else { // replace list with new list type @@ -3587,37 +3588,31 @@ HTMLEditRules::WillMakeList(Selection* aSelection, } MOZ_ASSERT(atCurNode.IsSetAndValid()); if (HTMLEditUtils::IsListItem(curNode)) { - NS_ENSURE_STATE(mHTMLEditor); if (!atCurNode.Container()->IsHTMLElement(listType)) { // list item is in wrong type of list. if we don't have a curList, // split the old list and make a new list of correct type. if (!curList || EditorUtils::IsDescendantOf(*curNode, *curList)) { - NS_ENSURE_STATE(mHTMLEditor); if (NS_WARN_IF(!atCurNode.Container()->IsContent())) { return NS_ERROR_FAILURE; } ErrorResult error; nsCOMPtr newLeftNode = - mHTMLEditor->SplitNode(atCurNode, error); + htmlEditor->SplitNode(atCurNode, error); if (NS_WARN_IF(error.Failed())) { return error.StealNSResult(); } newBlock = newLeftNode ? newLeftNode->AsElement() : nullptr; - NS_ENSURE_STATE(mHTMLEditor); EditorRawDOMPoint atParentOfCurNode(atCurNode.Container()); - curList = mHTMLEditor->CreateNode(listType, atParentOfCurNode); + curList = htmlEditor->CreateNode(listType, atParentOfCurNode); NS_ENSURE_STATE(curList); } // move list item to new list - NS_ENSURE_STATE(mHTMLEditor); - rv = mHTMLEditor->MoveNode(curNode, curList, -1); + rv = htmlEditor->MoveNode(curNode, curList, -1); NS_ENSURE_SUCCESS(rv, rv); // convert list item type if needed - NS_ENSURE_STATE(mHTMLEditor); if (!curNode->IsHTMLElement(itemType)) { - NS_ENSURE_STATE(mHTMLEditor); - newBlock = mHTMLEditor->ReplaceContainer(curNode->AsElement(), - itemType); + newBlock = htmlEditor->ReplaceContainer(curNode->AsElement(), + itemType); NS_ENSURE_STATE(newBlock); } } else { @@ -3627,28 +3622,24 @@ HTMLEditRules::WillMakeList(Selection* aSelection, curList = atCurNode.Container()->AsElement(); } else if (atCurNode.Container() != curList) { // move list item to new list - NS_ENSURE_STATE(mHTMLEditor); - rv = mHTMLEditor->MoveNode(curNode, curList, -1); + rv = htmlEditor->MoveNode(curNode, curList, -1); NS_ENSURE_SUCCESS(rv, rv); } - NS_ENSURE_STATE(mHTMLEditor); if (!curNode->IsHTMLElement(itemType)) { - NS_ENSURE_STATE(mHTMLEditor); - newBlock = mHTMLEditor->ReplaceContainer(curNode->AsElement(), - itemType); + newBlock = htmlEditor->ReplaceContainer(curNode->AsElement(), + itemType); NS_ENSURE_STATE(newBlock); } } - NS_ENSURE_STATE(mHTMLEditor); nsCOMPtr curElement = do_QueryInterface(curNode); if (aBulletType && !aBulletType->IsEmpty()) { - rv = mHTMLEditor->SetAttribute(curElement, nsGkAtoms::type, - *aBulletType); + rv = htmlEditor->SetAttribute(curElement, nsGkAtoms::type, + *aBulletType); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } } else { - rv = mHTMLEditor->RemoveAttribute(curElement, nsGkAtoms::type); + rv = htmlEditor->RemoveAttribute(curElement, nsGkAtoms::type); if (NS_WARN_IF(NS_FAILED(rv))) { return rv; } @@ -3662,8 +3653,7 @@ HTMLEditRules::WillMakeList(Selection* aSelection, prevListItem = nullptr; int32_t j = i + 1; GetInnerContent(*curNode, arrayOfNodes, &j); - NS_ENSURE_STATE(mHTMLEditor); - rv = mHTMLEditor->RemoveContainer(curNode); + rv = htmlEditor->RemoveContainer(curNode); NS_ENSURE_SUCCESS(rv, rv); listCount = arrayOfNodes.Length(); continue; @@ -3671,21 +3661,19 @@ HTMLEditRules::WillMakeList(Selection* aSelection, // need to make a list to put things in if we haven't already, if (!curList) { - nsCOMPtr curParent(atCurNode.Container()); - nsCOMPtr curChild(curNode); - int32_t offset = atCurNode.Offset(); - rv = SplitAsNeeded(listType, curParent, offset, - address_of(curChild)); - NS_ENSURE_SUCCESS(rv, rv); - NS_ENSURE_STATE(mHTMLEditor); - EditorRawDOMPoint atCurChild(curParent, curChild, offset); - curList = mHTMLEditor->CreateNode(listType, atCurChild); + SplitNodeResult splitCurNodeResult = + MaybeSplitAncestorsForInsert(listType, atCurNode); + if (NS_WARN_IF(splitCurNodeResult.Failed())) { + return splitCurNodeResult.Rv(); + } + curList = + htmlEditor->CreateNode(listType, splitCurNodeResult.SplitPoint()); // remember our new block for postprocessing mNewBlock = curList; // curList is now the correct thing to put curNode in prevListItem = nullptr; - // atCurChild is now referring the right node with mOffset but + // atCurNode is now referring the right node with mOffset but // referring the left node with mRef. So, invalidate it now. atCurNode.Clear(); } @@ -3696,19 +3684,16 @@ HTMLEditRules::WillMakeList(Selection* aSelection, if (IsInlineNode(curNode) && prevListItem) { // this is a continuation of some inline nodes that belong together in // the same list item. use prevListItem - NS_ENSURE_STATE(mHTMLEditor); - rv = mHTMLEditor->MoveNode(curNode, prevListItem, -1); + rv = htmlEditor->MoveNode(curNode, prevListItem, -1); NS_ENSURE_SUCCESS(rv, rv); } else { // don't wrap li around a paragraph. instead replace paragraph with li if (curNode->IsHTMLElement(nsGkAtoms::p)) { - NS_ENSURE_STATE(mHTMLEditor); - listItem = mHTMLEditor->ReplaceContainer(curNode->AsElement(), - itemType); + listItem = htmlEditor->ReplaceContainer(curNode->AsElement(), + itemType); NS_ENSURE_STATE(listItem); } else { - NS_ENSURE_STATE(mHTMLEditor); - listItem = mHTMLEditor->InsertContainerAbove(curNode, itemType); + listItem = htmlEditor->InsertContainerAbove(curNode, itemType); NS_ENSURE_STATE(listItem); } if (IsInlineNode(curNode)) { @@ -3724,8 +3709,7 @@ HTMLEditRules::WillMakeList(Selection* aSelection, if (listItem) { // if we made a new list item, deal with it: tuck the listItem into the // end of the active list - NS_ENSURE_STATE(mHTMLEditor); - rv = mHTMLEditor->MoveNode(listItem, curList, -1); + rv = htmlEditor->MoveNode(listItem, curList, -1); NS_ENSURE_SUCCESS(rv, rv); } } @@ -3840,20 +3824,20 @@ HTMLEditRules::MakeBasicBlock(Selection& aSelection, nsAtom& blockType) // If nothing visible in list, make an empty block if (ListIsEmptyLine(arrayOfNodes)) { - // Get selection location - NS_ENSURE_STATE(aSelection.GetRangeAt(0) && - aSelection.GetRangeAt(0)->GetStartContainer()); - OwningNonNull container = - *aSelection.GetRangeAt(0)->GetStartContainer(); - nsCOMPtr child = - aSelection.GetRangeAt(0)->GetChildAtStartOffset(); - int32_t offset = aSelection.GetRangeAt(0)->StartOffset(); + nsRange* firstRange = aSelection.GetRangeAt(0); + if (NS_WARN_IF(!firstRange)) { + return NS_ERROR_FAILURE; + } + EditorDOMPoint pointToInsertBlock(firstRange->StartRef()); if (&blockType == nsGkAtoms::normal || &blockType == nsGkAtoms::_empty) { // We are removing blocks (going to "body text") - NS_ENSURE_TRUE(htmlEditor->GetBlock(container), NS_ERROR_NULL_POINTER); - OwningNonNull curBlock = *htmlEditor->GetBlock(container); + RefPtr curBlock = + htmlEditor->GetBlock(*pointToInsertBlock.Container()); + if (NS_WARN_IF(!curBlock)) { + return NS_ERROR_FAILURE; + } if (!HTMLEditUtils::IsFormatNode(curBlock)) { return NS_OK; } @@ -3862,16 +3846,15 @@ HTMLEditRules::MakeBasicBlock(Selection& aSelection, nsAtom& blockType) // Otherwise it gets pushed into a following block after the split, // which is visually bad. nsCOMPtr brNode = - htmlEditor->GetNextEditableHTMLNode( - EditorRawDOMPoint(container, child, offset)); + htmlEditor->GetNextEditableHTMLNode(pointToInsertBlock.AsRaw()); if (brNode && brNode->IsHTMLElement(nsGkAtoms::br)) { + AutoEditorDOMPointChildInvalidator lockOffset(pointToInsertBlock); rv = htmlEditor->DeleteNode(brNode); NS_ENSURE_SUCCESS(rv, rv); } // Do the splits! SplitNodeResult splitNodeResult = - htmlEditor->SplitNodeDeep(curBlock, - EditorRawDOMPoint(container, offset), + htmlEditor->SplitNodeDeep(*curBlock, pointToInsertBlock.AsRaw(), SplitAtEdges::eDoNotCreateEmptyContainer); if (NS_WARN_IF(splitNodeResult.Failed())) { return splitNodeResult.Rv(); @@ -3895,22 +3878,22 @@ HTMLEditRules::MakeBasicBlock(Selection& aSelection, nsAtom& blockType) // We are making a block. Consume a br, if needed. nsCOMPtr brNode = - htmlEditor->GetNextEditableHTMLNodeInBlock( - EditorRawDOMPoint(container, child, offset)); + htmlEditor->GetNextEditableHTMLNodeInBlock(pointToInsertBlock.AsRaw()); if (brNode && brNode->IsHTMLElement(nsGkAtoms::br)) { + AutoEditorDOMPointChildInvalidator lockOffset(pointToInsertBlock); rv = htmlEditor->DeleteNode(brNode); NS_ENSURE_SUCCESS(rv, rv); // We don't need to act on this node any more arrayOfNodes.RemoveElement(brNode); - // XXX We need to recompute child here because SplitAsNeeded() don't - // compute child in some cases. - child = container->GetChildAt(offset); } - // Make sure we can put a block here - rv = SplitAsNeeded(blockType, container, offset, address_of(child)); - NS_ENSURE_SUCCESS(rv, rv); - EditorRawDOMPoint atChild(container, child, offset); - RefPtr block = htmlEditor->CreateNode(&blockType, atChild); + // Make sure we can put a block here. + SplitNodeResult splitNodeResult = + MaybeSplitAncestorsForInsert(blockType, pointToInsertBlock.AsRaw()); + if (NS_WARN_IF(splitNodeResult.Failed())) { + return splitNodeResult.Rv(); + } + RefPtr block = + htmlEditor->CreateNode(&blockType, splitNodeResult.SplitPoint()); NS_ENSURE_STATE(block); // Remember our new block for postprocessing mNewBlock = block; @@ -3993,6 +3976,11 @@ HTMLEditRules::WillCSSIndent(Selection* aSelection, return NS_ERROR_NULL_POINTER; } + if (NS_WARN_IF(!mHTMLEditor)) { + return NS_ERROR_NOT_AVAILABLE; + } + RefPtr htmlEditor(mHTMLEditor); + WillInsert(*aSelection, aCancel); // initialize out param @@ -4002,8 +3990,7 @@ HTMLEditRules::WillCSSIndent(Selection* aSelection, nsresult rv = NormalizeSelection(aSelection); NS_ENSURE_SUCCESS(rv, rv); - NS_ENSURE_STATE(mHTMLEditor); - AutoSelectionRestorer selectionRestorer(aSelection, mHTMLEditor); + AutoSelectionRestorer selectionRestorer(aSelection, htmlEditor); nsTArray> arrayOfRanges; nsTArray> arrayOfNodes; @@ -4018,8 +4005,7 @@ HTMLEditRules::WillCSSIndent(Selection* aSelection, EditorBase::GetStartNodeAndOffset(aSelection, getter_AddRefs(node), &offset); NS_ENSURE_SUCCESS(rv, rv); - NS_ENSURE_STATE(mHTMLEditor); - nsCOMPtr block = mHTMLEditor->GetBlock(*node); + RefPtr block = htmlEditor->GetBlock(*node); if (block && HTMLEditUtils::IsListItem(block)) { liNode = block; } @@ -4039,20 +4025,24 @@ HTMLEditRules::WillCSSIndent(Selection* aSelection, // if nothing visible in list, make an empty block if (ListIsEmptyLine(arrayOfNodes)) { // get selection location - NS_ENSURE_STATE(aSelection->RangeCount()); - nsCOMPtr container = aSelection->GetRangeAt(0)->GetStartContainer(); - int32_t offset = aSelection->GetRangeAt(0)->StartOffset(); - NS_ENSURE_STATE(container); - nsCOMPtr child = - aSelection->GetRangeAt(0)->GetChildAtStartOffset(); + nsRange* firstRange = aSelection->GetRangeAt(0); + if (NS_WARN_IF(!firstRange)) { + return NS_ERROR_FAILURE; + } + + EditorDOMPoint atStartOfSelection(firstRange->StartRef()); + if (NS_WARN_IF(!atStartOfSelection.IsSet())) { + return NS_ERROR_FAILURE; + } // make sure we can put a block here - rv = SplitAsNeeded(*nsGkAtoms::div, container, offset, address_of(child)); - NS_ENSURE_SUCCESS(rv, rv); - NS_ENSURE_STATE(mHTMLEditor); - EditorRawDOMPoint atChild(container, child, offset); + SplitNodeResult splitNodeResult = + MaybeSplitAncestorsForInsert(*nsGkAtoms::div, atStartOfSelection.AsRaw()); + if (NS_WARN_IF(splitNodeResult.Failed())) { + return splitNodeResult.Rv(); + } RefPtr theBlock = - mHTMLEditor->CreateNode(nsGkAtoms::div, atChild); + htmlEditor->CreateNode(nsGkAtoms::div, splitNodeResult.SplitPoint()); NS_ENSURE_STATE(theBlock); // remember our new block for postprocessing mNewBlock = theBlock; @@ -4060,8 +4050,7 @@ HTMLEditRules::WillCSSIndent(Selection* aSelection, // delete anything that was in the list of nodes while (!arrayOfNodes.IsEmpty()) { OwningNonNull curNode = arrayOfNodes[0]; - NS_ENSURE_STATE(mHTMLEditor); - rv = mHTMLEditor->DeleteNode(curNode); + rv = htmlEditor->DeleteNode(curNode); NS_ENSURE_SUCCESS(rv, rv); arrayOfNodes.RemoveElementAt(0); } @@ -4082,79 +4071,65 @@ HTMLEditRules::WillCSSIndent(Selection* aSelection, // or whatever is appropriate. Wohoo! nsCOMPtr curList, curQuote; nsCOMPtr sibling; - int32_t listCount = arrayOfNodes.Length(); - for (int32_t i = 0; i < listCount; i++) { - // here's where we actually figure out what to do - NS_ENSURE_STATE(arrayOfNodes[i]->IsContent()); - nsCOMPtr curNode = arrayOfNodes[i]->AsContent(); - - // Ignore all non-editable nodes. Leave them be. - NS_ENSURE_STATE(mHTMLEditor); - if (!mHTMLEditor->IsEditable(curNode)) { + for (OwningNonNull& curNode : arrayOfNodes) { + // Here's where we actually figure out what to do. + EditorDOMPoint atCurNode(curNode); + if (NS_WARN_IF(!atCurNode.IsSet())) { continue; } - int32_t offset; - nsCOMPtr curParent = - EditorBase::GetNodeLocation(curNode, &offset); - if (!curParent) { + // Ignore all non-editable nodes. Leave them be. + if (!htmlEditor->IsEditable(curNode)) { continue; } // some logic for putting list items into nested lists... - if (HTMLEditUtils::IsList(curParent)) { - sibling = nullptr; - + if (HTMLEditUtils::IsList(atCurNode.Container())) { // Check for whether we should join a list that follows curNode. // We do this if the next element is a list, and the list is of the // same type (li/ol) as curNode was a part it. - NS_ENSURE_STATE(mHTMLEditor); - sibling = mHTMLEditor->GetNextHTMLSibling(curNode); + sibling = htmlEditor->GetNextHTMLSibling(curNode); if (sibling && HTMLEditUtils::IsList(sibling) && - curParent->NodeInfo()->NameAtom() == + atCurNode.Container()->NodeInfo()->NameAtom() == sibling->NodeInfo()->NameAtom() && - curParent->NodeInfo()->NamespaceID() == + atCurNode.Container()->NodeInfo()->NamespaceID() == sibling->NodeInfo()->NamespaceID()) { - NS_ENSURE_STATE(mHTMLEditor); - rv = mHTMLEditor->MoveNode(curNode, sibling, 0); + rv = htmlEditor->MoveNode(curNode->AsContent(), sibling, 0); NS_ENSURE_SUCCESS(rv, rv); continue; } + // Check for whether we should join a list that preceeds curNode. // We do this if the previous element is a list, and the list is of // the same type (li/ol) as curNode was a part of. - NS_ENSURE_STATE(mHTMLEditor); - sibling = mHTMLEditor->GetPriorHTMLSibling(curNode); + sibling = htmlEditor->GetPriorHTMLSibling(curNode); if (sibling && HTMLEditUtils::IsList(sibling) && - curParent->NodeInfo()->NameAtom() == + atCurNode.Container()->NodeInfo()->NameAtom() == sibling->NodeInfo()->NameAtom() && - curParent->NodeInfo()->NamespaceID() == + atCurNode.Container()->NodeInfo()->NamespaceID() == sibling->NodeInfo()->NamespaceID()) { - NS_ENSURE_STATE(mHTMLEditor); - rv = mHTMLEditor->MoveNode(curNode, sibling, -1); + rv = htmlEditor->MoveNode(curNode->AsContent(), sibling, -1); NS_ENSURE_SUCCESS(rv, rv); continue; } - sibling = nullptr; // check to see if curList is still appropriate. Which it is if // curNode is still right after it in the same list. + sibling = nullptr; if (curList) { - NS_ENSURE_STATE(mHTMLEditor); - sibling = mHTMLEditor->GetPriorHTMLSibling(curNode); + sibling = htmlEditor->GetPriorHTMLSibling(curNode); } if (!curList || (sibling && sibling != curList)) { - // create a new nested list of correct type - nsCOMPtr curChild(curNode); - rv = - SplitAsNeeded(*curParent->NodeInfo()->NameAtom(), curParent, offset, - address_of(curChild)); - NS_ENSURE_SUCCESS(rv, rv); - NS_ENSURE_STATE(mHTMLEditor); - EditorRawDOMPoint atCurChild(curParent, curChild, offset); - curList = mHTMLEditor->CreateNode(curParent->NodeInfo()->NameAtom(), - atCurChild); + nsAtom* containerName = atCurNode.Container()->NodeInfo()->NameAtom(); + // Create a new nested list of correct type. + SplitNodeResult splitNodeResult = + MaybeSplitAncestorsForInsert(*containerName, atCurNode.AsRaw()); + if (NS_WARN_IF(splitNodeResult.Failed())) { + return splitNodeResult.Rv(); + } + curList = htmlEditor->CreateNode(containerName, + splitNodeResult.SplitPoint()); NS_ENSURE_STATE(curList); // curList is now the correct thing to put curNode in // remember our new block for postprocessing @@ -4162,46 +4137,45 @@ HTMLEditRules::WillCSSIndent(Selection* aSelection, } // tuck the node into the end of the active list uint32_t listLen = curList->Length(); - NS_ENSURE_STATE(mHTMLEditor); - rv = mHTMLEditor->MoveNode(curNode, curList, listLen); + rv = htmlEditor->MoveNode(curNode->AsContent(), curList, listLen); NS_ENSURE_SUCCESS(rv, rv); + + continue; } + // Not a list item. - else { - if (curNode && IsBlockNode(*curNode)) { - ChangeIndentation(*curNode->AsElement(), Change::plus); - curQuote = nullptr; - } else { - if (!curQuote) { - // First, check that our element can contain a div. - if (NS_WARN_IF(!mHTMLEditor)) { - return NS_ERROR_UNEXPECTED; - } - if (!mHTMLEditor->CanContainTag(*curParent, *nsGkAtoms::div)) { - return NS_OK; // cancelled - } - nsCOMPtr curChild(curNode); - rv = SplitAsNeeded(*nsGkAtoms::div, curParent, offset, - address_of(curChild)); - NS_ENSURE_SUCCESS(rv, rv); - NS_ENSURE_STATE(mHTMLEditor); - EditorRawDOMPoint atCurChild(curParent, curChild, offset); - curQuote = mHTMLEditor->CreateNode(nsGkAtoms::div, atCurChild); - NS_ENSURE_STATE(curQuote); - ChangeIndentation(*curQuote, Change::plus); - // remember our new block for postprocessing - mNewBlock = curQuote; - // curQuote is now the correct thing to put curNode in - } - - // tuck the node into the end of the active blockquote - uint32_t quoteLen = curQuote->Length(); - NS_ENSURE_STATE(mHTMLEditor); - rv = mHTMLEditor->MoveNode(curNode, curQuote, quoteLen); - NS_ENSURE_SUCCESS(rv, rv); - } + if (IsBlockNode(*curNode)) { + ChangeIndentation(*curNode->AsElement(), Change::plus); + curQuote = nullptr; + continue; } + + if (!curQuote) { + // First, check that our element can contain a div. + if (!htmlEditor->CanContainTag(*atCurNode.Container(), + *nsGkAtoms::div)) { + return NS_OK; // cancelled + } + + SplitNodeResult splitNodeResult = + MaybeSplitAncestorsForInsert(*nsGkAtoms::div, atCurNode.AsRaw()); + if (NS_WARN_IF(splitNodeResult.Failed())) { + return splitNodeResult.Rv(); + } + curQuote = + htmlEditor->CreateNode(nsGkAtoms::div, splitNodeResult.SplitPoint()); + NS_ENSURE_STATE(curQuote); + ChangeIndentation(*curQuote, Change::plus); + // remember our new block for postprocessing + mNewBlock = curQuote; + // curQuote is now the correct thing to put curNode in + } + + // tuck the node into the end of the active blockquote + uint32_t quoteLen = curQuote->Length(); + rv = htmlEditor->MoveNode(curNode->AsContent(), curQuote, quoteLen); + NS_ENSURE_SUCCESS(rv, rv); } return NS_OK; } @@ -4214,6 +4188,12 @@ HTMLEditRules::WillHTMLIndent(Selection* aSelection, if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; } + + if (NS_WARN_IF(!mHTMLEditor)) { + return NS_ERROR_NOT_AVAILABLE; + } + RefPtr htmlEditor(mHTMLEditor); + WillInsert(*aSelection, aCancel); // initialize out param @@ -4223,8 +4203,8 @@ HTMLEditRules::WillHTMLIndent(Selection* aSelection, nsresult rv = NormalizeSelection(aSelection); NS_ENSURE_SUCCESS(rv, rv); - NS_ENSURE_STATE(mHTMLEditor); - AutoSelectionRestorer selectionRestorer(aSelection, mHTMLEditor); + + AutoSelectionRestorer selectionRestorer(aSelection, htmlEditor); // convert the selection ranges into "promoted" selection ranges: // this basically just expands the range to include the immediate @@ -4241,31 +4221,33 @@ HTMLEditRules::WillHTMLIndent(Selection* aSelection, // if nothing visible in list, make an empty block if (ListIsEmptyLine(arrayOfNodes)) { - // get selection location - NS_ENSURE_STATE(aSelection->RangeCount()); - nsCOMPtr container = - aSelection->GetRangeAt(0)->GetStartContainer(); - int32_t offset = aSelection->GetRangeAt(0)->StartOffset(); - NS_ENSURE_STATE(container); - nsCOMPtr child = - aSelection->GetRangeAt(0)->GetChildAtStartOffset(); + nsRange* firstRange = aSelection->GetRangeAt(0); + if (NS_WARN_IF(!firstRange)) { + return NS_ERROR_FAILURE; + } - // make sure we can put a block here - rv = SplitAsNeeded(*nsGkAtoms::blockquote, container, offset, - address_of(child)); - NS_ENSURE_SUCCESS(rv, rv); - NS_ENSURE_STATE(mHTMLEditor); - EditorRawDOMPoint atChild(container, child, offset); + EditorDOMPoint atStartOfSelection(firstRange->StartRef()); + if (NS_WARN_IF(!atStartOfSelection.IsSet())) { + return NS_ERROR_FAILURE; + } + + // Make sure we can put a block here. + SplitNodeResult splitNodeResult = + MaybeSplitAncestorsForInsert(*nsGkAtoms::blockquote, + atStartOfSelection.AsRaw()); + if (NS_WARN_IF(splitNodeResult.Failed())) { + return splitNodeResult.Rv(); + } RefPtr theBlock = - mHTMLEditor->CreateNode(nsGkAtoms::blockquote, atChild); + htmlEditor->CreateNode(nsGkAtoms::blockquote, + splitNodeResult.SplitPoint()); NS_ENSURE_STATE(theBlock); // remember our new block for postprocessing mNewBlock = theBlock; // delete anything that was in the list of nodes while (!arrayOfNodes.IsEmpty()) { OwningNonNull curNode = arrayOfNodes[0]; - NS_ENSURE_STATE(mHTMLEditor); - rv = mHTMLEditor->DeleteNode(curNode); + rv = htmlEditor->DeleteNode(curNode); NS_ENSURE_SUCCESS(rv, rv); arrayOfNodes.RemoveElementAt(0); } @@ -4286,40 +4268,30 @@ HTMLEditRules::WillHTMLIndent(Selection* aSelection, // or whatever is appropriate. Wohoo! nsCOMPtr sibling; nsCOMPtr curList, curQuote, indentedLI; - int32_t listCount = arrayOfNodes.Length(); - for (int32_t i = 0; i < listCount; i++) { - // here's where we actually figure out what to do - NS_ENSURE_STATE(arrayOfNodes[i]->IsContent()); - nsCOMPtr curNode = arrayOfNodes[i]->AsContent(); - - // Ignore all non-editable nodes. Leave them be. - NS_ENSURE_STATE(mHTMLEditor); - if (!mHTMLEditor->IsEditable(curNode)) { + for (OwningNonNull& curNode: arrayOfNodes) { + // Here's where we actually figure out what to do. + EditorDOMPoint atCurNode(curNode); + if (NS_WARN_IF(!atCurNode.IsSet())) { continue; } - int32_t offset; - nsCOMPtr curParent = EditorBase::GetNodeLocation(curNode, &offset); - if (!curParent) { + // Ignore all non-editable nodes. Leave them be. + if (!htmlEditor->IsEditable(curNode)) { continue; } // some logic for putting list items into nested lists... - if (HTMLEditUtils::IsList(curParent)) { - sibling = nullptr; - + if (HTMLEditUtils::IsList(atCurNode.Container())) { // Check for whether we should join a list that follows curNode. // We do this if the next element is a list, and the list is of the // same type (li/ol) as curNode was a part it. - NS_ENSURE_STATE(mHTMLEditor); - sibling = mHTMLEditor->GetNextHTMLSibling(curNode); + sibling = htmlEditor->GetNextHTMLSibling(curNode); if (sibling && HTMLEditUtils::IsList(sibling) && - curParent->NodeInfo()->NameAtom() == + atCurNode.Container()->NodeInfo()->NameAtom() == sibling->NodeInfo()->NameAtom() && - curParent->NodeInfo()->NamespaceID() == + atCurNode.Container()->NodeInfo()->NamespaceID() == sibling->NodeInfo()->NamespaceID()) { - NS_ENSURE_STATE(mHTMLEditor); - rv = mHTMLEditor->MoveNode(curNode, sibling, 0); + rv = htmlEditor->MoveNode(curNode->AsContent(), sibling, 0); NS_ENSURE_SUCCESS(rv, rv); continue; } @@ -4327,131 +4299,128 @@ HTMLEditRules::WillHTMLIndent(Selection* aSelection, // Check for whether we should join a list that preceeds curNode. // We do this if the previous element is a list, and the list is of // the same type (li/ol) as curNode was a part of. - NS_ENSURE_STATE(mHTMLEditor); - sibling = mHTMLEditor->GetPriorHTMLSibling(curNode); + sibling = htmlEditor->GetPriorHTMLSibling(curNode); if (sibling && HTMLEditUtils::IsList(sibling) && - curParent->NodeInfo()->NameAtom() == + atCurNode.Container()->NodeInfo()->NameAtom() == sibling->NodeInfo()->NameAtom() && - curParent->NodeInfo()->NamespaceID() == + atCurNode.Container()->NodeInfo()->NamespaceID() == sibling->NodeInfo()->NamespaceID()) { - NS_ENSURE_STATE(mHTMLEditor); - rv = mHTMLEditor->MoveNode(curNode, sibling, -1); + rv = htmlEditor->MoveNode(curNode->AsContent(), sibling, -1); NS_ENSURE_SUCCESS(rv, rv); continue; } - sibling = nullptr; - // check to see if curList is still appropriate. Which it is if // curNode is still right after it in the same list. + sibling = nullptr; if (curList) { - NS_ENSURE_STATE(mHTMLEditor); - sibling = mHTMLEditor->GetPriorHTMLSibling(curNode); + sibling = htmlEditor->GetPriorHTMLSibling(curNode); } if (!curList || (sibling && sibling != curList)) { - // create a new nested list of correct type - nsCOMPtr curChild(curNode); - rv = - SplitAsNeeded(*curParent->NodeInfo()->NameAtom(), curParent, offset, - address_of(curChild)); - NS_ENSURE_SUCCESS(rv, rv); - NS_ENSURE_STATE(mHTMLEditor); - EditorRawDOMPoint atCurChild(curParent, curChild, offset); - curList = mHTMLEditor->CreateNode(curParent->NodeInfo()->NameAtom(), - atCurChild); + nsAtom* containerName = atCurNode.Container()->NodeInfo()->NameAtom(); + // Create a new nested list of correct type. + SplitNodeResult splitNodeResult = + MaybeSplitAncestorsForInsert(*containerName, atCurNode.AsRaw()); + if (NS_WARN_IF(splitNodeResult.Failed())) { + return splitNodeResult.Rv(); + } + curList = + htmlEditor->CreateNode(containerName, splitNodeResult.SplitPoint()); NS_ENSURE_STATE(curList); // curList is now the correct thing to put curNode in // remember our new block for postprocessing mNewBlock = curList; } // tuck the node into the end of the active list - NS_ENSURE_STATE(mHTMLEditor); - rv = mHTMLEditor->MoveNode(curNode, curList, -1); + rv = htmlEditor->MoveNode(curNode->AsContent(), curList, -1); NS_ENSURE_SUCCESS(rv, rv); // forget curQuote, if any curQuote = nullptr; + + continue; } + // Not a list item, use blockquote? - else { - // if we are inside a list item, we don't want to blockquote, we want - // to sublist the list item. We may have several nodes listed in the - // array of nodes to act on, that are in the same list item. Since - // we only want to indent that li once, we must keep track of the most - // recent indented list item, and not indent it if we find another node - // to act on that is still inside the same li. - nsCOMPtr listItem = IsInListItem(curNode); - if (listItem) { - if (indentedLI == listItem) { - // already indented this list item - continue; - } - curParent = listItem->GetParentNode(); - offset = curParent ? curParent->IndexOf(listItem) : -1; - // check to see if curList is still appropriate. Which it is if - // curNode is still right after it in the same list. - if (curList) { - sibling = nullptr; - NS_ENSURE_STATE(mHTMLEditor); - sibling = mHTMLEditor->GetPriorHTMLSibling(curNode); - } - if (!curList || (sibling && sibling != curList)) { - // create a new nested list of correct type - nsCOMPtr curChild(listItem); - rv = SplitAsNeeded(*curParent->NodeInfo()->NameAtom(), curParent, - offset, address_of(curChild)); - NS_ENSURE_SUCCESS(rv, rv); - NS_ENSURE_STATE(mHTMLEditor); - EditorRawDOMPoint atCurChild(curParent, curChild, offset); - curList = mHTMLEditor->CreateNode(curParent->NodeInfo()->NameAtom(), - atCurChild); - NS_ENSURE_STATE(curList); - } - NS_ENSURE_STATE(mHTMLEditor); - rv = mHTMLEditor->MoveNode(listItem, curList, -1); - NS_ENSURE_SUCCESS(rv, rv); - // remember we indented this li - indentedLI = listItem; - } else { - // need to make a blockquote to put things in if we haven't already, - // or if this node doesn't go in blockquote we used earlier. - // One reason it might not go in prio blockquote is if we are now - // in a different table cell. - if (curQuote && InDifferentTableElements(curQuote, curNode)) { - curQuote = nullptr; - } - - if (!curQuote) { - // First, check that our element can contain a blockquote. - if (NS_WARN_IF(!mHTMLEditor)) { - return NS_ERROR_UNEXPECTED; - } - if (!mHTMLEditor->CanContainTag(*curParent, *nsGkAtoms::blockquote)) { - return NS_OK; // cancelled - } - - nsCOMPtr curChild(curNode); - rv = SplitAsNeeded(*nsGkAtoms::blockquote, curParent, offset, - address_of(curChild)); - NS_ENSURE_SUCCESS(rv, rv); - NS_ENSURE_STATE(mHTMLEditor); - EditorRawDOMPoint atCurChild(curParent, curChild, offset); - curQuote = mHTMLEditor->CreateNode(nsGkAtoms::blockquote, atCurChild); - NS_ENSURE_STATE(curQuote); - // remember our new block for postprocessing - mNewBlock = curQuote; - // curQuote is now the correct thing to put curNode in - } - - // tuck the node into the end of the active blockquote - NS_ENSURE_STATE(mHTMLEditor); - rv = mHTMLEditor->MoveNode(curNode, curQuote, -1); - NS_ENSURE_SUCCESS(rv, rv); - // forget curList, if any - curList = nullptr; + // if we are inside a list item, we don't want to blockquote, we want + // to sublist the list item. We may have several nodes listed in the + // array of nodes to act on, that are in the same list item. Since + // we only want to indent that li once, we must keep track of the most + // recent indented list item, and not indent it if we find another node + // to act on that is still inside the same li. + RefPtr listItem = IsInListItem(curNode); + if (listItem) { + if (indentedLI == listItem) { + // already indented this list item + continue; } + // check to see if curList is still appropriate. Which it is if + // curNode is still right after it in the same list. + if (curList) { + sibling = htmlEditor->GetPriorHTMLSibling(listItem); + } + + if (!curList || (sibling && sibling != curList)) { + EditorDOMPoint atListItem(listItem); + if (NS_WARN_IF(!listItem)) { + return NS_ERROR_FAILURE; + } + nsAtom* containerName = atListItem.Container()->NodeInfo()->NameAtom(); + // Create a new nested list of correct type. + SplitNodeResult splitNodeResult = + MaybeSplitAncestorsForInsert(*containerName, atListItem.AsRaw()); + if (NS_WARN_IF(splitNodeResult.Failed())) { + return splitNodeResult.Rv(); + } + curList = htmlEditor->CreateNode(containerName, + splitNodeResult.SplitPoint()); + NS_ENSURE_STATE(curList); + } + + rv = htmlEditor->MoveNode(listItem, curList, -1); + NS_ENSURE_SUCCESS(rv, rv); + + // remember we indented this li + indentedLI = listItem; + + continue; } + + // need to make a blockquote to put things in if we haven't already, + // or if this node doesn't go in blockquote we used earlier. + // One reason it might not go in prio blockquote is if we are now + // in a different table cell. + if (curQuote && InDifferentTableElements(curQuote, curNode)) { + curQuote = nullptr; + } + + if (!curQuote) { + // First, check that our element can contain a blockquote. + if (!htmlEditor->CanContainTag(*atCurNode.Container(), + *nsGkAtoms::blockquote)) { + return NS_OK; // cancelled + } + + SplitNodeResult splitNodeResult = + MaybeSplitAncestorsForInsert(*nsGkAtoms::blockquote, atCurNode.AsRaw()); + if (NS_WARN_IF(splitNodeResult.Failed())) { + return splitNodeResult.Rv(); + } + curQuote = + htmlEditor->CreateNode(nsGkAtoms::blockquote, + splitNodeResult.SplitPoint()); + NS_ENSURE_STATE(curQuote); + // remember our new block for postprocessing + mNewBlock = curQuote; + // curQuote is now the correct thing to put curNode in + } + + // tuck the node into the end of the active blockquote + rv = htmlEditor->MoveNode(curNode->AsContent(), curQuote, -1); + NS_ENSURE_SUCCESS(rv, rv); + // forget curList, if any + curList = nullptr; } return NS_OK; } @@ -5036,36 +5005,44 @@ HTMLEditRules::WillAlign(Selection& aSelection, } } if (emptyDiv) { - nsCOMPtr parent = - aSelection.GetRangeAt(0) ? aSelection.GetRangeAt(0)->GetStartContainer() - : nullptr; - NS_ENSURE_STATE(parent); - int32_t offset = aSelection.GetRangeAt(0)->StartOffset(); - nsCOMPtr child = - aSelection.GetRangeAt(0)->GetChildAtStartOffset(); + nsRange* firstRange = aSelection.GetRangeAt(0); + if (NS_WARN_IF(!firstRange)) { + return NS_ERROR_FAILURE; + } + + EditorDOMPoint atStartOfSelection(firstRange->StartRef()); + if (NS_WARN_IF(!atStartOfSelection.IsSet())) { + return NS_ERROR_FAILURE; + } + + SplitNodeResult splitNodeResult = + MaybeSplitAncestorsForInsert(*nsGkAtoms::div, atStartOfSelection.AsRaw()); + if (NS_WARN_IF(splitNodeResult.Failed())) { + return splitNodeResult.Rv(); + } - rv = SplitAsNeeded(*nsGkAtoms::div, parent, offset, - address_of(child)); - NS_ENSURE_SUCCESS(rv, rv); // Consume a trailing br, if any. This is to keep an alignment from // creating extra lines, if possible. - EditorRawDOMPoint atChild(parent, child, offset); nsCOMPtr brContent = - htmlEditor->GetNextEditableHTMLNodeInBlock(atChild); + htmlEditor->GetNextEditableHTMLNodeInBlock(splitNodeResult.SplitPoint()); + EditorDOMPoint pointToInsertDiv(splitNodeResult.SplitPoint()); if (brContent && TextEditUtils::IsBreak(brContent)) { // Making use of html structure... if next node after where we are // putting our div is not a block, then the br we found is in same block // we are, so it's safe to consume it. nsCOMPtr sibling; - if (child) { - sibling = htmlEditor->GetNextHTMLSibling(child); + if (pointToInsertDiv.GetChildAtOffset()) { + sibling = + htmlEditor->GetNextHTMLSibling(pointToInsertDiv.GetChildAtOffset()); } if (sibling && !IsBlockNode(*sibling)) { + AutoEditorDOMPointChildInvalidator lockOffset(pointToInsertDiv); rv = htmlEditor->DeleteNode(brContent); NS_ENSURE_SUCCESS(rv, rv); } } - RefPtr div = htmlEditor->CreateNode(nsGkAtoms::div, atChild); + RefPtr div = + htmlEditor->CreateNode(nsGkAtoms::div, pointToInsertDiv.AsRaw()); NS_ENSURE_STATE(div); // Remember our new block for postprocessing mNewBlock = div; @@ -5098,9 +5075,9 @@ HTMLEditRules::WillAlign(Selection& aSelection, nsCOMPtr curDiv; bool useCSS = htmlEditor->IsCSSEnabled(); - for (size_t i = 0; i < nodeArray.Length(); i++) { - auto& curNode = nodeArray[i]; - // Here's where we actually figure out what to do + int32_t indexOfTransitionList = -1; + for (OwningNonNull& curNode : nodeArray) { + ++indexOfTransitionList; // Ignore all non-editable nodes. Leave them be. if (!htmlEditor->IsEditable(curNode)) { @@ -5119,9 +5096,8 @@ HTMLEditRules::WillAlign(Selection& aSelection, continue; } - int32_t offset; - nsCOMPtr curParent = EditorBase::GetNodeLocation(curNode, &offset); - if (!curParent) { + EditorDOMPoint atCurNode(curNode); + if (NS_WARN_IF(!atCurNode.IsSet())) { continue; } @@ -5129,9 +5105,9 @@ HTMLEditRules::WillAlign(Selection& aSelection, // structure splitting! bool isEmptyTextNode = false; if (curNode->GetAsText() && - ((HTMLEditUtils::IsTableElement(curParent) && - !HTMLEditUtils::IsTableCellOrCaption(*curParent)) || - HTMLEditUtils::IsList(curParent) || + ((HTMLEditUtils::IsTableElement(atCurNode.Container()) && + !HTMLEditUtils::IsTableCellOrCaption(*atCurNode.Container())) || + HTMLEditUtils::IsList(atCurNode.Container()) || (NS_SUCCEEDED(htmlEditor->IsEmptyNode(curNode, &isEmptyTextNode)) && isEmptyTextNode))) { continue; @@ -5141,16 +5117,17 @@ HTMLEditRules::WillAlign(Selection& aSelection, // and instead put divs inside the appropriate block (td, li, etc.) if (HTMLEditUtils::IsListItem(curNode) || HTMLEditUtils::IsList(curNode)) { + AutoEditorDOMPointOffsetInvalidator lockChild(atCurNode); rv = RemoveAlignment(*curNode, aAlignType, true); NS_ENSURE_SUCCESS(rv, rv); if (useCSS) { htmlEditor->mCSSEditUtils->SetCSSEquivalentToHTMLStyle( - curNode->AsElement(), nullptr, nsGkAtoms::align, - &aAlignType, false); + curNode->AsElement(), nullptr, + nsGkAtoms::align, &aAlignType, false); curDiv = nullptr; continue; } - if (HTMLEditUtils::IsList(curParent)) { + if (HTMLEditUtils::IsList(atCurNode.Container())) { // If we don't use CSS, add a contraint to list element: they have to // be inside another list, i.e., >= second level of nesting rv = AlignInnerBlocks(*curNode, &aAlignType); @@ -5163,19 +5140,20 @@ HTMLEditRules::WillAlign(Selection& aSelection, // Need to make a div to put things in if we haven't already, or if this // node doesn't go in div we used earlier. - if (!curDiv || transitionList[i]) { + if (!curDiv || transitionList[indexOfTransitionList]) { // First, check that our element can contain a div. - if (!htmlEditor->CanContainTag(*curParent, *nsGkAtoms::div)) { + if (!htmlEditor->CanContainTag(*atCurNode.Container(), *nsGkAtoms::div)) { // Cancelled return NS_OK; } - nsCOMPtr curChild(curNode->AsContent()); - rv = SplitAsNeeded(*nsGkAtoms::div, curParent, offset, - address_of(curChild)); - NS_ENSURE_SUCCESS(rv, rv); - EditorRawDOMPoint atCurChild(curParent, curChild, offset); - curDiv = htmlEditor->CreateNode(nsGkAtoms::div, atCurChild); + SplitNodeResult splitNodeResult = + MaybeSplitAncestorsForInsert(*nsGkAtoms::div, atCurNode.AsRaw()); + if (NS_WARN_IF(splitNodeResult.Failed())) { + return splitNodeResult.Rv(); + } + curDiv = + htmlEditor->CreateNode(nsGkAtoms::div, splitNodeResult.SplitPoint()); NS_ENSURE_STATE(curDiv); // Remember our new block for postprocessing mNewBlock = curDiv; @@ -5183,8 +5161,6 @@ HTMLEditRules::WillAlign(Selection& aSelection, rv = AlignBlock(*curDiv, aAlignType, ContentsOnly::yes); } - NS_ENSURE_STATE(curNode->IsContent()); - // Tuck the node into the end of the active div rv = htmlEditor->MoveNode(curNode->AsContent(), curDiv, -1); NS_ENSURE_SUCCESS(rv, rv); @@ -7211,6 +7187,11 @@ HTMLEditRules::ReturnInListItem(Selection& aSelection, nsresult HTMLEditRules::MakeBlockquote(nsTArray>& aNodeArray) { + if (NS_WARN_IF(!mHTMLEditor)) { + return NS_ERROR_NOT_AVAILABLE; + } + RefPtr htmlEditor(mHTMLEditor); + // The idea here is to put the nodes into a minimal number of blockquotes. // When the user blockquotes something, they expect one blockquote. That may // not be possible (for instance, if they have two table cells selected, you @@ -7248,23 +7229,21 @@ HTMLEditRules::MakeBlockquote(nsTArray>& aNodeArray) // If no curBlock, make one if (!curBlock) { - nsCOMPtr curParent = curNode->GetParentNode(); - int32_t offset = curParent ? curParent->IndexOf(curNode) : -1; - nsCOMPtr curChild(curNode->AsContent()); - nsresult rv = SplitAsNeeded(*nsGkAtoms::blockquote, curParent, offset, - address_of(curChild)); - NS_ENSURE_SUCCESS(rv, rv); - NS_ENSURE_STATE(mHTMLEditor); - EditorRawDOMPoint atCurChild(curParent, curChild, offset); - curBlock = mHTMLEditor->CreateNode(nsGkAtoms::blockquote, atCurChild); + EditorDOMPoint atCurNode(curNode); + SplitNodeResult splitNodeResult = + MaybeSplitAncestorsForInsert(*nsGkAtoms::blockquote, atCurNode.AsRaw()); + if (NS_WARN_IF(splitNodeResult.Failed())) { + return splitNodeResult.Rv(); + } + curBlock = htmlEditor->CreateNode(nsGkAtoms::blockquote, + splitNodeResult.SplitPoint()); NS_ENSURE_STATE(curBlock); // remember our new block for postprocessing mNewBlock = curBlock; // note: doesn't matter if we set mNewBlock multiple times. } - NS_ENSURE_STATE(mHTMLEditor); - nsresult rv = mHTMLEditor->MoveNode(curNode->AsContent(), curBlock, -1); + nsresult rv = htmlEditor->MoveNode(curNode->AsContent(), curBlock, -1); NS_ENSURE_SUCCESS(rv, rv); } return NS_OK; @@ -7373,15 +7352,16 @@ HTMLEditRules::ApplyBlockStyle(nsTArray>& aNodeArray, // Intent of this routine is to be used for converting to/from headers, // paragraphs, pre, and address. Those blocks that pretty much just contain // inline things... - NS_ENSURE_STATE(mHTMLEditor); + if (NS_WARN_IF(!mHTMLEditor)) { + return NS_ERROR_NOT_AVAILABLE; + } RefPtr htmlEditor(mHTMLEditor); nsCOMPtr newBlock; nsCOMPtr curBlock; for (auto& curNode : aNodeArray) { - nsCOMPtr curParent = curNode->GetParentNode(); - int32_t offset = curParent ? curParent->IndexOf(curNode) : -1; + EditorDOMPoint atCurNode(curNode); // Is it already the right kind of block, or an uneditable block? if (curNode->IsHTMLElement(&aBlockTag) || @@ -7399,18 +7379,22 @@ HTMLEditRules::ApplyBlockStyle(nsTArray>& aNodeArray, HTMLEditUtils::IsFormatNode(curNode)) { // Forget any previous block used for previous inline nodes curBlock = nullptr; - newBlock = htmlEditor->ReplaceContainer(curNode->AsElement(), - &aBlockTag, nullptr, nullptr, - EditorBase::eCloneAttributes); + newBlock = + htmlEditor->ReplaceContainer(curNode->AsElement(), + &aBlockTag, nullptr, nullptr, + EditorBase::eCloneAttributes); NS_ENSURE_STATE(newBlock); - } else if (HTMLEditUtils::IsTable(curNode) || - HTMLEditUtils::IsList(curNode) || - curNode->IsAnyOfHTMLElements(nsGkAtoms::tbody, - nsGkAtoms::tr, - nsGkAtoms::td, - nsGkAtoms::li, - nsGkAtoms::blockquote, - nsGkAtoms::div)) { + continue; + } + + if (HTMLEditUtils::IsTable(curNode) || + HTMLEditUtils::IsList(curNode) || + curNode->IsAnyOfHTMLElements(nsGkAtoms::tbody, + nsGkAtoms::tr, + nsGkAtoms::td, + nsGkAtoms::li, + nsGkAtoms::blockquote, + nsGkAtoms::div)) { // Forget any previous block used for previous inline nodes curBlock = nullptr; // Recursion time @@ -7419,20 +7403,24 @@ HTMLEditRules::ApplyBlockStyle(nsTArray>& aNodeArray, if (!childArray.IsEmpty()) { nsresult rv = ApplyBlockStyle(childArray, aBlockTag); NS_ENSURE_SUCCESS(rv, rv); - } else { - // Make sure we can put a block here - nsCOMPtr curChild(curNode->AsContent()); - nsresult rv = SplitAsNeeded(aBlockTag, curParent, offset, - address_of(curChild)); - NS_ENSURE_SUCCESS(rv, rv); - EditorRawDOMPoint atCurChild(curParent, curChild, offset); - RefPtr theBlock = - htmlEditor->CreateNode(&aBlockTag, atCurChild); - NS_ENSURE_STATE(theBlock); - // Remember our new block for postprocessing - mNewBlock = theBlock; + continue; } - } else if (curNode->IsHTMLElement(nsGkAtoms::br)) { + + // Make sure we can put a block here + SplitNodeResult splitNodeResult = + MaybeSplitAncestorsForInsert(aBlockTag, atCurNode.AsRaw()); + if (NS_WARN_IF(splitNodeResult.Failed())) { + return splitNodeResult.Rv(); + } + RefPtr theBlock = + htmlEditor->CreateNode(&aBlockTag, splitNodeResult.SplitPoint()); + NS_ENSURE_STATE(theBlock); + // Remember our new block for postprocessing + mNewBlock = theBlock; + continue; + } + + if (curNode->IsHTMLElement(nsGkAtoms::br)) { // If the node is a break, we honor it by putting further nodes in a new // parent if (curBlock) { @@ -7440,23 +7428,28 @@ HTMLEditRules::ApplyBlockStyle(nsTArray>& aNodeArray, curBlock = nullptr; nsresult rv = htmlEditor->DeleteNode(curNode); NS_ENSURE_SUCCESS(rv, rv); - } else { - // The break is the first (or even only) node we encountered. Create a - // block for it. - nsCOMPtr curChild(curNode->AsContent()); - nsresult rv = SplitAsNeeded(aBlockTag, curParent, offset, - address_of(curChild)); - NS_ENSURE_SUCCESS(rv, rv); - EditorRawDOMPoint atCurChild(curParent, curChild, offset); - curBlock = htmlEditor->CreateNode(&aBlockTag, atCurChild); - NS_ENSURE_STATE(curBlock); - // Remember our new block for postprocessing - mNewBlock = curBlock; - // Note: doesn't matter if we set mNewBlock multiple times. - rv = htmlEditor->MoveNode(curNode->AsContent(), curBlock, -1); - NS_ENSURE_SUCCESS(rv, rv); + continue; } - } else if (IsInlineNode(curNode)) { + + // The break is the first (or even only) node we encountered. Create a + // block for it. + SplitNodeResult splitNodeResult = + MaybeSplitAncestorsForInsert(aBlockTag, atCurNode.AsRaw()); + if (NS_WARN_IF(splitNodeResult.Failed())) { + return splitNodeResult.Rv(); + } + curBlock = + htmlEditor->CreateNode(&aBlockTag, splitNodeResult.SplitPoint()); + NS_ENSURE_STATE(curBlock); + // Remember our new block for postprocessing + mNewBlock = curBlock; + // Note: doesn't matter if we set mNewBlock multiple times. + nsresult rv = htmlEditor->MoveNode(curNode->AsContent(), curBlock, -1); + NS_ENSURE_SUCCESS(rv, rv); + continue; + } + + if (IsInlineNode(curNode)) { // If curNode is inline, pull it into curBlock. Note: it's assumed that // consecutive inline nodes in aNodeArray are actually members of the // same block parent. This happens to be true now as a side effect of @@ -7471,19 +7464,22 @@ HTMLEditRules::ApplyBlockStyle(nsTArray>& aNodeArray, // If no curBlock, make one if (!curBlock) { - nsCOMPtr curChild(curNode->AsContent()); - nsresult rv = SplitAsNeeded(aBlockTag, curParent, offset, - address_of(curChild)); - NS_ENSURE_SUCCESS(rv, rv); - EditorRawDOMPoint atCurChild(curParent, curChild, offset); - curBlock = htmlEditor->CreateNode(&aBlockTag, atCurChild); + AutoEditorDOMPointOffsetInvalidator lockChild(atCurNode); + + SplitNodeResult splitNodeResult = + MaybeSplitAncestorsForInsert(aBlockTag, atCurNode.AsRaw()); + if (NS_WARN_IF(splitNodeResult.Failed())) { + return splitNodeResult.Rv(); + } + curBlock = + htmlEditor->CreateNode(&aBlockTag, splitNodeResult.SplitPoint()); NS_ENSURE_STATE(curBlock); // Remember our new block for postprocessing mNewBlock = curBlock; // Note: doesn't matter if we set mNewBlock multiple times. } - if (NS_WARN_IF(!curNode->GetParentNode())) { + if (NS_WARN_IF(!atCurNode.IsSet())) { // This is possible due to mutation events, let's not assert return NS_ERROR_UNEXPECTED; } @@ -7499,89 +7495,64 @@ HTMLEditRules::ApplyBlockStyle(nsTArray>& aNodeArray, return NS_OK; } -/** - * Given a tag name, split inOutParent up to the point where we can insert the - * tag. Adjust inOutParent and inOutOffset to point to new location for tag. - */ -nsresult -HTMLEditRules::SplitAsNeeded(nsAtom& aTag, - OwningNonNull& aInOutParent, - int32_t& inOutOffset, - nsCOMPtr* inOutChildAtOffset) +SplitNodeResult +HTMLEditRules::MaybeSplitAncestorsForInsert( + nsAtom& aTag, + const EditorRawDOMPoint& aStartOfDeepestRightNode) { - // XXX Is there a better way to do this? - nsCOMPtr parent = aInOutParent.forget(); - nsresult rv = SplitAsNeeded(aTag, parent, inOutOffset, inOutChildAtOffset); - aInOutParent = parent.forget(); - return rv; -} - -nsresult -HTMLEditRules::SplitAsNeeded(nsAtom& aTag, - nsCOMPtr& inOutParent, - int32_t& inOutOffset, - nsCOMPtr* inOutChildAtOffset) -{ - if (NS_WARN_IF(!inOutParent)) { - return NS_ERROR_INVALID_ARG; + if (NS_WARN_IF(!aStartOfDeepestRightNode.IsSet())) { + return SplitNodeResult(NS_ERROR_INVALID_ARG); } + MOZ_ASSERT(aStartOfDeepestRightNode.IsSetAndValid()); if (NS_WARN_IF(!mHTMLEditor)) { - return NS_ERROR_NOT_AVAILABLE; + return SplitNodeResult(NS_ERROR_NOT_AVAILABLE); } RefPtr htmlEditor(mHTMLEditor); - // Check that we have a place that can legally contain the tag - nsCOMPtr tagParent, splitNode; - for (nsCOMPtr parent = inOutParent; parent; - parent = parent->GetParentNode()) { - // Sniffing up the parent tree until we find a legal place for the block + RefPtr host = htmlEditor->GetActiveEditingHost(); + if (NS_WARN_IF(!host)) { + return SplitNodeResult(NS_ERROR_FAILURE); + } - // Don't leave the active editing host - NS_ENSURE_STATE(mHTMLEditor); - if (!htmlEditor->IsDescendantOfEditorRoot(parent)) { - // XXX Why do we need to check mHTMLEditor again here? - NS_ENSURE_STATE(mHTMLEditor); - if (parent != htmlEditor->GetActiveEditingHost()) { - return NS_ERROR_FAILURE; - } + // The point must be descendant of editing host. + if (NS_WARN_IF(aStartOfDeepestRightNode.Container() != host && + !EditorUtils::IsDescendantOf( + *aStartOfDeepestRightNode.Container(), *host))) { + return SplitNodeResult(NS_ERROR_INVALID_ARG); + } + + // Look for a node that can legally contain the tag. + EditorRawDOMPoint pointToInsert(aStartOfDeepestRightNode); + for (; pointToInsert.IsSet(); pointToInsert.Set(pointToInsert.Container())) { + // We cannot split active editing host and its ancestor. So, there is + // no element to contain the specified element. + if (NS_WARN_IF(pointToInsert.GetChildAtOffset() == host)) { + return SplitNodeResult(NS_ERROR_FAILURE); } - if (htmlEditor->CanContainTag(*parent, aTag)) { - // Success - tagParent = parent; + if (htmlEditor->CanContainTag(*pointToInsert.Container(), aTag)) { + // Found an ancestor node which can contain the element. break; } - - splitNode = parent; } - if (!tagParent) { - // Could not find a place to build tag! - return NS_ERROR_FAILURE; + MOZ_DIAGNOSTIC_ASSERT(pointToInsert.IsSet()); + + // If the point itself can contain the tag, we don't need to split any + // ancestor nodes. + if (pointToInsert.Container() == aStartOfDeepestRightNode.Container()) { + return SplitNodeResult(nullptr, + aStartOfDeepestRightNode.GetChildAtOffset()); } - if (!splitNode || !splitNode->IsContent() || !inOutParent->IsContent()) { - return NS_OK; - } - - // We found a place for block, but above inOutParent. We need to split. - NS_ENSURE_STATE(mHTMLEditor); SplitNodeResult splitNodeResult = - mHTMLEditor->SplitNodeDeep(*splitNode->AsContent(), - EditorRawDOMPoint(inOutParent, inOutOffset), - SplitAtEdges::eAllowToCreateEmptyContainer); - if (NS_WARN_IF(splitNodeResult.Failed())) { - return splitNodeResult.Rv(); - } - - EditorRawDOMPoint splitPoint(splitNodeResult.SplitPoint()); - inOutParent = splitPoint.Container(); - inOutOffset = splitPoint.Offset(); - if (inOutChildAtOffset) { - *inOutChildAtOffset = splitPoint.GetChildAtOffset(); - } - return NS_OK; + htmlEditor->SplitNodeDeep(*pointToInsert.GetChildAtOffset(), + aStartOfDeepestRightNode, + SplitAtEdges::eAllowToCreateEmptyContainer); + NS_WARNING_ASSERTION(splitNodeResult.Succeeded(), + "Failed to split the node for insert the element"); + return splitNodeResult; } /** @@ -9186,7 +9157,10 @@ HTMLEditRules::WillAbsolutePosition(Selection& aSelection, bool* aHandled) { MOZ_ASSERT(aCancel && aHandled); - NS_ENSURE_STATE(mHTMLEditor); + + if (NS_WARN_IF(!mHTMLEditor)) { + return NS_ERROR_NOT_AVAILABLE; + } RefPtr htmlEditor(mHTMLEditor); WillInsert(aSelection, aCancel); @@ -9222,22 +9196,24 @@ HTMLEditRules::WillAbsolutePosition(Selection& aSelection, // If nothing visible in list, make an empty block if (ListIsEmptyLine(arrayOfNodes)) { - // Get selection location - NS_ENSURE_STATE(aSelection.GetRangeAt(0) && - aSelection.GetRangeAt(0)->GetStartContainer()); - OwningNonNull parent = - *aSelection.GetRangeAt(0)->GetStartContainer(); - int32_t offset = aSelection.GetRangeAt(0)->StartOffset(); - nsCOMPtr child = - aSelection.GetRangeAt(0)->GetChildAtStartOffset(); + nsRange* firstRange = aSelection.GetRangeAt(0); + if (NS_WARN_IF(!firstRange)) { + return NS_ERROR_FAILURE; + } - // Make sure we can put a block here - rv = SplitAsNeeded(*nsGkAtoms::div, parent, offset, - address_of(child)); - NS_ENSURE_SUCCESS(rv, rv); - EditorRawDOMPoint atChild(parent, child, offset); + EditorDOMPoint atStartOfSelection(firstRange->StartRef()); + if (NS_WARN_IF(!atStartOfSelection.IsSet())) { + return NS_ERROR_FAILURE; + } + + // Make sure we can put a block here. + SplitNodeResult splitNodeResult = + MaybeSplitAncestorsForInsert(*nsGkAtoms::div, atStartOfSelection.AsRaw()); + if (NS_WARN_IF(splitNodeResult.Failed())) { + return splitNodeResult.Rv(); + } RefPtr positionedDiv = - htmlEditor->CreateNode(nsGkAtoms::div, atChild); + htmlEditor->CreateNode(nsGkAtoms::div, splitNodeResult.SplitPoint()); NS_ENSURE_STATE(positionedDiv); // Remember our new block for postprocessing mNewBlock = positionedDiv; @@ -9260,10 +9236,12 @@ HTMLEditRules::WillAbsolutePosition(Selection& aSelection, // Okay, now go through all the nodes and put them in a blockquote, or // whatever is appropriate. Woohoo! nsCOMPtr curList, curPositionedDiv, indentedLI; - for (uint32_t i = 0; i < arrayOfNodes.Length(); i++) { - // Here's where we actually figure out what to do - NS_ENSURE_STATE(arrayOfNodes[i]->IsContent()); - OwningNonNull curNode = *arrayOfNodes[i]->AsContent(); + for (OwningNonNull& curNode : arrayOfNodes) { + // Here's where we actually figure out what to do. + EditorDOMPoint atCurNode(curNode); + if (NS_WARN_IF(!atCurNode.IsSet())) { + return NS_ERROR_FAILURE; // XXX not continue?? + } // Ignore all non-editable nodes. Leave them be. if (!htmlEditor->IsEditable(curNode)) { @@ -9272,14 +9250,8 @@ HTMLEditRules::WillAbsolutePosition(Selection& aSelection, nsCOMPtr sibling; - int32_t offset; - nsCOMPtr curParent = EditorBase::GetNodeLocation(curNode, &offset); - if (!curParent) { - continue; - } - // Some logic for putting list items into nested lists... - if (HTMLEditUtils::IsList(curParent)) { + if (HTMLEditUtils::IsList(atCurNode.Container())) { // Check to see if curList is still appropriate. Which it is if curNode // is still right after it in the same list. if (curList) { @@ -9287,98 +9259,108 @@ HTMLEditRules::WillAbsolutePosition(Selection& aSelection, } if (!curList || (sibling && sibling != curList)) { - // Create a new nested list of correct type - rv = - SplitAsNeeded(*curParent->NodeInfo()->NameAtom(), curParent, offset); - NS_ENSURE_SUCCESS(rv, rv); + nsAtom* containerName = atCurNode.Container()->NodeInfo()->NameAtom(); + // Create a new nested list of correct type. + SplitNodeResult splitNodeResult = + MaybeSplitAncestorsForInsert(*containerName, atCurNode.AsRaw()); + if (NS_WARN_IF(splitNodeResult.Failed())) { + return splitNodeResult.Rv(); + } if (!curPositionedDiv) { - EditorRawDOMPoint atCurParent(curParent); curPositionedDiv = - htmlEditor->CreateNode(nsGkAtoms::div, atCurParent); + htmlEditor->CreateNode(nsGkAtoms::div, + splitNodeResult.SplitPoint()); mNewBlock = curPositionedDiv; } EditorRawDOMPoint atEndOfCurPositionedDiv(curPositionedDiv, curPositionedDiv->Length()); - curList = htmlEditor->CreateNode(curParent->NodeInfo()->NameAtom(), - atEndOfCurPositionedDiv); + curList = + htmlEditor->CreateNode(containerName, atEndOfCurPositionedDiv); NS_ENSURE_STATE(curList); // curList is now the correct thing to put curNode in. Remember our // new block for postprocessing. } // Tuck the node into the end of the active list - rv = htmlEditor->MoveNode(curNode, curList, -1); + rv = htmlEditor->MoveNode(curNode->AsContent(), curList, -1); NS_ENSURE_SUCCESS(rv, rv); - } else { - // Not a list item, use blockquote? If we are inside a list item, we - // don't want to blockquote, we want to sublist the list item. We may - // have several nodes listed in the array of nodes to act on, that are in - // the same list item. Since we only want to indent that li once, we - // must keep track of the most recent indented list item, and not indent - // it if we find another node to act on that is still inside the same li. - nsCOMPtr listItem = IsInListItem(curNode); - if (listItem) { - if (indentedLI == listItem) { - // Already indented this list item - continue; - } - curParent = listItem->GetParentNode(); - offset = curParent ? curParent->IndexOf(listItem) : -1; - // Check to see if curList is still appropriate. Which it is if - // curNode is still right after it in the same list. - if (curList) { - sibling = htmlEditor->GetPriorHTMLSibling(curNode); - } - - if (!curList || (sibling && sibling != curList)) { - // Create a new nested list of correct type - rv = SplitAsNeeded(*curParent->NodeInfo()->NameAtom(), curParent, - offset); - NS_ENSURE_SUCCESS(rv, rv); - if (!curPositionedDiv) { - EditorRawDOMPoint atCurParent(curParent); - curPositionedDiv = - htmlEditor->CreateNode(nsGkAtoms::div, atCurParent); - mNewBlock = curPositionedDiv; - } - EditorRawDOMPoint atEndOfCurPositionedDiv(curPositionedDiv, - curPositionedDiv->Length()); - curList = htmlEditor->CreateNode(curParent->NodeInfo()->NameAtom(), - atEndOfCurPositionedDiv); - NS_ENSURE_STATE(curList); - } - rv = htmlEditor->MoveNode(listItem, curList, -1); - NS_ENSURE_SUCCESS(rv, rv); - // Remember we indented this li - indentedLI = listItem; - } else { - // Need to make a div to put things in if we haven't already - - if (!curPositionedDiv) { - if (curNode->IsHTMLElement(nsGkAtoms::div)) { - curPositionedDiv = curNode->AsElement(); - mNewBlock = curPositionedDiv; - curList = nullptr; - continue; - } - nsCOMPtr curChild(curNode); - rv = SplitAsNeeded(*nsGkAtoms::div, curParent, offset, - address_of(curChild)); - NS_ENSURE_SUCCESS(rv, rv); - EditorRawDOMPoint atCurChild(curParent, curChild, offset); - curPositionedDiv = htmlEditor->CreateNode(nsGkAtoms::div, atCurChild); - NS_ENSURE_STATE(curPositionedDiv); - // Remember our new block for postprocessing - mNewBlock = curPositionedDiv; - // curPositionedDiv is now the correct thing to put curNode in - } - - // Tuck the node into the end of the active blockquote - rv = htmlEditor->MoveNode(curNode, curPositionedDiv, -1); - NS_ENSURE_SUCCESS(rv, rv); - // Forget curList, if any - curList = nullptr; - } + continue; } + + // Not a list item, use blockquote? If we are inside a list item, we + // don't want to blockquote, we want to sublist the list item. We may + // have several nodes listed in the array of nodes to act on, that are in + // the same list item. Since we only want to indent that li once, we + // must keep track of the most recent indented list item, and not indent + // it if we find another node to act on that is still inside the same li. + RefPtr listItem = IsInListItem(curNode); + if (listItem) { + if (indentedLI == listItem) { + // Already indented this list item + continue; + } + // Check to see if curList is still appropriate. Which it is if + // curNode is still right after it in the same list. + if (curList) { + sibling = htmlEditor->GetPriorHTMLSibling(listItem); + } + + if (!curList || (sibling && sibling != curList)) { + EditorDOMPoint atListItem(listItem); + if (NS_WARN_IF(!atListItem.IsSet())) { + return NS_ERROR_FAILURE; + } + nsAtom* containerName = atListItem.Container()->NodeInfo()->NameAtom(); + // Create a new nested list of correct type + SplitNodeResult splitNodeResult = + MaybeSplitAncestorsForInsert(*containerName, atListItem.AsRaw()); + if (NS_WARN_IF(splitNodeResult.Failed())) { + return splitNodeResult.Rv(); + } + if (!curPositionedDiv) { + EditorRawDOMPoint atListItemParent(atListItem.Container()); + curPositionedDiv = + htmlEditor->CreateNode(nsGkAtoms::div, atListItemParent); + mNewBlock = curPositionedDiv; + } + EditorRawDOMPoint atEndOfCurPositionedDiv(curPositionedDiv, + curPositionedDiv->Length()); + curList = + htmlEditor->CreateNode(containerName, atEndOfCurPositionedDiv); + NS_ENSURE_STATE(curList); + } + rv = htmlEditor->MoveNode(listItem, curList, -1); + NS_ENSURE_SUCCESS(rv, rv); + // Remember we indented this li + indentedLI = listItem; + continue; + } + + // Need to make a div to put things in if we haven't already + if (!curPositionedDiv) { + if (curNode->IsHTMLElement(nsGkAtoms::div)) { + curPositionedDiv = curNode->AsElement(); + mNewBlock = curPositionedDiv; + curList = nullptr; + continue; + } + SplitNodeResult splitNodeResult = + MaybeSplitAncestorsForInsert(*nsGkAtoms::div, atCurNode.AsRaw()); + if (NS_WARN_IF(splitNodeResult.Failed())) { + return splitNodeResult.Rv(); + } + curPositionedDiv = + htmlEditor->CreateNode(nsGkAtoms::div, splitNodeResult.SplitPoint()); + NS_ENSURE_STATE(curPositionedDiv); + // Remember our new block for postprocessing + mNewBlock = curPositionedDiv; + // curPositionedDiv is now the correct thing to put curNode in + } + + // Tuck the node into the end of the active blockquote + rv = htmlEditor->MoveNode(curNode->AsContent(), curPositionedDiv, -1); + NS_ENSURE_SUCCESS(rv, rv); + // Forget curList, if any + curList = nullptr; } return NS_OK; } diff --git a/editor/libeditor/HTMLEditRules.h b/editor/libeditor/HTMLEditRules.h index 6be6c5d8ce0c..98adcab4eb8e 100644 --- a/editor/libeditor/HTMLEditRules.h +++ b/editor/libeditor/HTMLEditRules.h @@ -32,6 +32,7 @@ namespace mozilla { class EditActionResult; class HTMLEditor; class RulesInfo; +class SplitNodeResult; class TextEditor; namespace dom { class Element; @@ -415,12 +416,28 @@ protected: nsresult ApplyBlockStyle(nsTArray>& aNodeArray, nsAtom& aBlockTag); nsresult MakeBlockquote(nsTArray>& aNodeArray); - nsresult SplitAsNeeded(nsAtom& aTag, OwningNonNull& inOutParent, - int32_t& inOutOffset, - nsCOMPtr* inOutChildAtOffset = nullptr); - nsresult SplitAsNeeded(nsAtom& aTag, nsCOMPtr& inOutParent, - int32_t& inOutOffset, - nsCOMPtr* inOutChildAtOffset = nullptr); + + /** + * MaybeSplitAncestorsForInsert() does nothing if container of + * aStartOfDeepestRightNode can have an element whose tag name is aTag. + * Otherwise, looks for an ancestor node which is or is in active editing + * host and can have an element whose name is aTag. If there is such + * ancestor, its descendants are split. + * + * Note that this may create empty elements while splitting ancestors. + * + * @param aTag The name of element to be inserted + * after calling this method. + * @param aStartOfDeepestRightNode The start point of deepest right node. + * This point must be descendant of + * active editing host. + * @return When succeeded, SplitPoint() returns + * the point to insert the element. + */ + SplitNodeResult MaybeSplitAncestorsForInsert( + nsAtom& aTag, + const EditorRawDOMPoint& aStartOfDeepestRightNode); + nsresult AddTerminatingBR(nsIDOMNode *aBlock); EditorDOMPoint JoinNodesSmart(nsIContent& aNodeLeft, nsIContent& aNodeRight); From c06378ebc95c4ab2b3dc4feab173c2468f7d4c57 Mon Sep 17 00:00:00 2001 From: Masayuki Nakano Date: Sun, 19 Nov 2017 11:05:26 +0900 Subject: [PATCH 35/78] Bug 1413181 - part 13: HTMLEditRules::MaybeSplitAncestorsForInsert() should be able to return a DOM point in text node r=m_kato HTMLEditRules::MaybeSplitAncestorsForInsert() may be called with a point in a text and it needs to return given split point as is. Additionally, the given point may be in a text node. So, it may not be represented with an nsCOMPtr. Therefore, we need to add new member, EditorDOMPoint, to SplitNodeResult and when MaybeSplitAncestorsForInsert() needs to return the given point as is, it should use it. Note that if the methods which return SplitNodeResult split some nodes actually, the left node and/or the right node may be removed from the DOM tree. In this case, EditorDOMPoint cannot store such orphan node. Therefore, we cannot make mNextNode nor mPreviousNode EditorDOMPoint. MozReview-Commit-ID: LwH8RZzkrmT --HG-- extra : rebase_source : a5ae2328bef3d887c0bf4e1b9c4a4247b93a4ac0 --- editor/libeditor/EditorUtils.h | 48 ++++++++++++++++++++++++++++-- editor/libeditor/HTMLEditRules.cpp | 6 ++-- 2 files changed, 49 insertions(+), 5 deletions(-) diff --git a/editor/libeditor/EditorUtils.h b/editor/libeditor/EditorUtils.h index f2d2e824c0f4..fe9c45c322e3 100644 --- a/editor/libeditor/EditorUtils.h +++ b/editor/libeditor/EditorUtils.h @@ -175,18 +175,35 @@ public: */ nsIContent* GetRightNode() const { + if (mGivenSplitPoint.IsSet()) { + return mGivenSplitPoint.GetChildAtOffset(); + } return mPreviousNode && !mNextNode ? mPreviousNode : mNextNode; } /** * GetPreviousNode() returns previous node at the split point. */ - nsIContent* GetPreviousNode() const { return mPreviousNode; } + nsIContent* GetPreviousNode() const + { + if (mGivenSplitPoint.IsSet()) { + return mGivenSplitPoint.IsEndOfContainer() ? + mGivenSplitPoint.GetChildAtOffset() : nullptr; + } + return mPreviousNode; + } /** * GetNextNode() returns next node at the split point. */ - nsIContent* GetNextNode() const { return mNextNode; } + nsIContent* GetNextNode() const + { + if (mGivenSplitPoint.IsSet()) { + return !mGivenSplitPoint.IsEndOfContainer() ? + mGivenSplitPoint.GetChildAtOffset() : nullptr; + } + return mNextNode; + } /** * SplitPoint() returns the split point in the container. @@ -202,6 +219,9 @@ public: if (Failed()) { return EditorRawDOMPoint(); } + if (mGivenSplitPoint.IsSet()) { + return mGivenSplitPoint.AsRaw(); + } if (!mPreviousNode) { return EditorRawDOMPoint(mNextNode); } @@ -230,6 +250,17 @@ public: MOZ_DIAGNOSTIC_ASSERT(mPreviousNode || mNextNode); } + /** + * This constructor should be used when the method didn't split any nodes + * but want to return given split point as right point. + */ + explicit SplitNodeResult(const EditorRawDOMPoint& aGivenSplitPoint) + : mGivenSplitPoint(aGivenSplitPoint) + , mRv(NS_OK) + { + MOZ_DIAGNOSTIC_ASSERT(mGivenSplitPoint.IsSet()); + } + /** * This constructor shouldn't be used by anybody except methods which * use this as error result when it fails. @@ -241,9 +272,22 @@ public: } private: + // When methods which return this class split some nodes actually, they + // need to set a set of left node and right node to this class. However, + // one or both of them may be moved or removed by mutation observer. + // In such case, we cannot represent the point with EditorDOMPoint since + // it requires current container node. Therefore, we need to use + // nsCOMPtr here instead. nsCOMPtr mPreviousNode; nsCOMPtr mNextNode; + // Methods which return this class may not split any nodes actually. Then, + // they may want to return given split point as is since such behavior makes + // their callers simpler. In this case, the point may be in a text node + // which cannot be represented as a node. Therefore, we need EditorDOMPoint + // for representing the point. + EditorDOMPoint mGivenSplitPoint; + nsresult mRv; SplitNodeResult() = delete; diff --git a/editor/libeditor/HTMLEditRules.cpp b/editor/libeditor/HTMLEditRules.cpp index 357ddd464cc6..fca00eda3021 100644 --- a/editor/libeditor/HTMLEditRules.cpp +++ b/editor/libeditor/HTMLEditRules.cpp @@ -7540,10 +7540,10 @@ HTMLEditRules::MaybeSplitAncestorsForInsert( MOZ_DIAGNOSTIC_ASSERT(pointToInsert.IsSet()); // If the point itself can contain the tag, we don't need to split any - // ancestor nodes. + // ancestor nodes. In this case, we should return the given split point + // as is. if (pointToInsert.Container() == aStartOfDeepestRightNode.Container()) { - return SplitNodeResult(nullptr, - aStartOfDeepestRightNode.GetChildAtOffset()); + return SplitNodeResult(aStartOfDeepestRightNode); } SplitNodeResult splitNodeResult = From 08419a75f3627799af7e1620a6aaf594d709f423 Mon Sep 17 00:00:00 2001 From: Alexandre Poirot Date: Wed, 15 Nov 2017 06:12:09 -0800 Subject: [PATCH 36/78] Bug 1372115 - Prevent exception in network monitor when JS file is loaded throught the bytecode cache. r=Honza MozReview-Commit-ID: 5w6Bj9213ba --HG-- extra : rebase_source : 13b4ff6ca93066c9e029e1c326353962407a12ec --- devtools/shared/webconsole/network-monitor.js | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/devtools/shared/webconsole/network-monitor.js b/devtools/shared/webconsole/network-monitor.js index b966c52aaa78..4cc4a6c48972 100644 --- a/devtools/shared/webconsole/network-monitor.js +++ b/devtools/shared/webconsole/network-monitor.js @@ -439,13 +439,34 @@ NetworkResponseListener.prototype = { // we pass the data from our pipe to the converter. this.offset = 0; + let channel = this.request; + + // Bug 1372115 - We should load bytecode cached requests from cache as the actual + // channel content is going to be optimized data that reflects platform internals + // instead of the content user expects (i.e. content served by HTTP server) + // Note that bytecode cached is one example, there may be wasm or other usecase in + // future. + let isOptimizedContent = false; + try { + if (channel instanceof Ci.nsICacheInfoChannel) { + isOptimizedContent = channel.alternativeDataType; + } + } catch (e) { + // Accessing `alternativeDataType` for some SW requests throws. + } + if (isOptimizedContent) { + let charset = this.request.contentCharset || this.httpActivity.charset; + NetworkHelper.loadFromCache(this.httpActivity.url, charset, + this._onComplete.bind(this)); + return; + } + // In the multi-process mode, the conversion happens on the child // side while we can only monitor the channel on the parent // side. If the content is gzipped, we have to unzip it // ourself. For that we use the stream converter services. Do not // do that for Service workers as they are run in the child // process. - let channel = this.request; if (!this.httpActivity.fromServiceWorker && channel instanceof Ci.nsIEncodedChannel && channel.contentEncodings && From c75cfab8161a55bcf99ec8cf89b69c2cb0bba839 Mon Sep 17 00:00:00 2001 From: Ting-Yu Lin Date: Tue, 21 Nov 2017 01:39:44 -0600 Subject: [PATCH 37/78] servo: Merge #19312 - style: Use ComputedUrl instead of SpecifiedUrl in conversion.rs (from aethanyc:use-computedurl); r=heycam In stylo, ComputedUrl and SpecifiedUrl happen to be the same. However, using ComputedUrl can make code clearer that conversion.rs is for converting computed values between gecko and servo types. Source-Repo: https://github.com/servo/servo Source-Revision: b74e71fdd1b20b66e59f4ccefb0706f89c789d0a --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : a38a7082be57b9435da370e6d84bd7499c35ad5c --- servo/components/style/gecko/conversions.rs | 15 +++++++-------- .../style/values/computed/basic_shape.rs | 4 ++-- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/servo/components/style/gecko/conversions.rs b/servo/components/style/gecko/conversions.rs index cc879dfd78c6..c23f760fa04f 100644 --- a/servo/components/style/gecko/conversions.rs +++ b/servo/components/style/gecko/conversions.rs @@ -17,13 +17,12 @@ use gecko_bindings::structs::{nsStyleImage, nsresult, SheetType}; use gecko_bindings::sugar::ns_style_coord::{CoordDataValue, CoordData, CoordDataMut}; use std::f32::consts::PI; use stylesheets::{Origin, RulesMutateError}; -use values::computed::{Angle, CalcLengthOrPercentage, Gradient, Image}; +use values::computed::{Angle, CalcLengthOrPercentage, ComputedUrl, Gradient, Image}; use values::computed::{Integer, LengthOrPercentage, LengthOrPercentageOrAuto, Percentage}; use values::generics::box_::VerticalAlign; use values::generics::grid::{TrackListValue, TrackSize}; use values::generics::image::{CompatMode, Image as GenericImage, GradientItem}; use values::generics::rect::Rect; -use values::specified::url::SpecifiedUrl; impl From for nsStyleCoord_CalcValue { fn from(other: CalcLengthOrPercentage) -> nsStyleCoord_CalcValue { @@ -420,11 +419,11 @@ impl nsStyleImage { } } - unsafe fn get_image_url(self: &nsStyleImage) -> SpecifiedUrl { + unsafe fn get_image_url(self: &nsStyleImage) -> ComputedUrl { use gecko_bindings::bindings::Gecko_GetURLValue; let url_value = Gecko_GetURLValue(self); - let mut url = SpecifiedUrl::from_url_value_data(url_value.as_ref().unwrap()) - .expect("Could not convert to SpecifiedUrl"); + let mut url = ComputedUrl::from_url_value_data(url_value.as_ref().unwrap()) + .expect("Could not convert to ComputedUrl"); url.build_image_value(); url } @@ -596,6 +595,7 @@ pub mod basic_shape { use gecko_bindings::structs::{nsStyleCoord, nsStyleCorners}; use gecko_bindings::sugar::ns_style_coord::{CoordDataMut, CoordDataValue}; use std::borrow::Borrow; + use values::computed::ComputedUrl; use values::computed::basic_shape::{BasicShape, ShapeRadius}; use values::computed::border::{BorderCornerRadius, BorderRadius}; use values::computed::length::LengthOrPercentage; @@ -605,9 +605,8 @@ pub mod basic_shape { use values::generics::basic_shape::{GeometryBox, ShapeBox, ShapeSource}; use values::generics::border::BorderRadius as GenericBorderRadius; use values::generics::rect::Rect; - use values::specified::url::SpecifiedUrl; - impl<'a, ReferenceBox> From<&'a StyleShapeSource> for ShapeSource + impl<'a, ReferenceBox> From<&'a StyleShapeSource> for ShapeSource where ReferenceBox: From, { @@ -619,7 +618,7 @@ pub mod basic_shape { unsafe { let shape_image = &*other.mShapeImage.mPtr; let other_url = &(**shape_image.__bindgen_anon_1.mURLValue.as_ref()); - let url = SpecifiedUrl::from_url_value_data(&other_url._base).unwrap(); + let url = ComputedUrl::from_url_value_data(&other_url._base).unwrap(); ShapeSource::Url(url) } }, diff --git a/servo/components/style/values/computed/basic_shape.rs b/servo/components/style/values/computed/basic_shape.rs index b9c82be1fb90..2b4feecfba88 100644 --- a/servo/components/style/values/computed/basic_shape.rs +++ b/servo/components/style/values/computed/basic_shape.rs @@ -15,10 +15,10 @@ use values::generics::basic_shape::{Circle as GenericCircle, ClippingShape as Ge use values::generics::basic_shape::{Ellipse as GenericEllipse, FloatAreaShape as GenericFloatAreaShape}; use values::generics::basic_shape::{InsetRect as GenericInsetRect, ShapeRadius as GenericShapeRadius}; -/// A specified clipping shape. +/// A computed clipping shape. pub type ClippingShape = GenericClippingShape; -/// A specified float area shape. +/// A computed float area shape. pub type FloatAreaShape = GenericFloatAreaShape; /// A computed basic shape. From 4e69e9cedbcf4cc6f923ea1730c83005c989288b Mon Sep 17 00:00:00 2001 From: Michael Wilson Date: Tue, 21 Nov 2017 02:56:49 -0600 Subject: [PATCH 38/78] servo: Merge #19195 - style: :dir() pseudo class now represented by enum (from wilsoniya:issue-16840); r=emilio `:dir()` pseudo class param now represented as enum variants. --- - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #16840 - [X] There are tests for these changes Source-Repo: https://github.com/servo/servo Source-Revision: 006202732f0bd8d2239bdd51898380bdbe0f0f1a --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : e9778d171eef1db2ebbf52b99d3255d50b2a60ec --- .../components/selectors/gecko_like_types.rs | 1 + .../style/gecko/non_ts_pseudo_class_list.rs | 1 - .../components/style/gecko/selector_parser.rs | 26 ++++++++++++++-- servo/components/style/gecko/wrapper.rs | 12 ++++++-- .../invalidation/element/element_wrapper.rs | 4 +-- .../invalidation/element/invalidation_map.rs | 30 ++++++++----------- servo/components/style/selector_parser.rs | 26 ++++++++++++++-- 7 files changed, 73 insertions(+), 27 deletions(-) diff --git a/servo/components/selectors/gecko_like_types.rs b/servo/components/selectors/gecko_like_types.rs index e0ef0f81e9dc..de0c4034e8c8 100644 --- a/servo/components/selectors/gecko_like_types.rs +++ b/servo/components/selectors/gecko_like_types.rs @@ -10,6 +10,7 @@ pub enum PseudoClass { Bare, String(Box<[u16]>), + Dir(Box<()>), MozAny(Box<[()]>), } diff --git a/servo/components/style/gecko/non_ts_pseudo_class_list.rs b/servo/components/style/gecko/non_ts_pseudo_class_list.rs index 6a16d4dc3db9..f7a2077e7886 100644 --- a/servo/components/style/gecko/non_ts_pseudo_class_list.rs +++ b/servo/components/style/gecko/non_ts_pseudo_class_list.rs @@ -120,7 +120,6 @@ macro_rules! apply_non_ts_list { ], keyword: [ ("-moz-locale-dir", MozLocaleDir, mozLocaleDir, _, _), - ("dir", Dir, dir, _, _), ] } } diff --git a/servo/components/style/gecko/selector_parser.rs b/servo/components/style/gecko/selector_parser.rs index 5d6c46af464f..db4372a46104 100644 --- a/servo/components/style/gecko/selector_parser.rs +++ b/servo/components/style/gecko/selector_parser.rs @@ -9,13 +9,13 @@ use element_state::{DocumentState, ElementState}; use gecko_bindings::structs::CSSPseudoClassType; use gecko_bindings::structs::RawServoSelectorList; use gecko_bindings::sugar::ownership::{HasBoxFFI, HasFFI, HasSimpleFFI}; -use selector_parser::{SelectorParser, PseudoElementCascadeType}; +use selector_parser::{Direction, SelectorParser, PseudoElementCascadeType}; use selectors::SelectorList; use selectors::parser::{Selector, SelectorMethods, SelectorParseErrorKind}; use selectors::visitor::SelectorVisitor; use std::fmt; use string_cache::{Atom, Namespace, WeakAtom, WeakNamespace}; -use style_traits::{ParseError, StyleParseErrorKind}; +use style_traits::{ParseError, StyleParseErrorKind, ToCss as ToCss_}; pub use gecko::pseudo_element::{PseudoElement, EAGER_PSEUDOS, EAGER_PSEUDO_COUNT, PSEUDO_COUNT}; pub use gecko::snapshot::SnapshotMap; @@ -53,6 +53,8 @@ macro_rules! pseudo_class_name { #[doc = $k_css] $k_name(Box<[u16]>), )* + /// The `:dir` pseudo-class. + Dir(Box), /// The non-standard `:-moz-any` pseudo-class. /// /// TODO(emilio): We disallow combinators and pseudos here, so we @@ -92,6 +94,12 @@ impl ToCss for NonTSPseudoClass { dest.write_str(&value)?; return dest.write_char(')') }, )* + NonTSPseudoClass::Dir(ref dir) => { + dest.write_str(":dir(")?; + // FIXME: This should be escaped as an identifier; see #19231 + (**dir).to_css(dest)?; + return dest.write_char(')') + }, NonTSPseudoClass::MozAny(ref selectors) => { dest.write_str(":-moz-any(")?; let mut iter = selectors.iter(); @@ -145,6 +153,7 @@ impl NonTSPseudoClass { $(NonTSPseudoClass::$name => check_flag!($flags),)* $(NonTSPseudoClass::$s_name(..) => check_flag!($s_flags),)* $(NonTSPseudoClass::$k_name(..) => check_flag!($k_flags),)* + NonTSPseudoClass::Dir(_) => false, NonTSPseudoClass::MozAny(_) => false, } } @@ -189,6 +198,7 @@ impl NonTSPseudoClass { $(NonTSPseudoClass::$name => flag!($state),)* $(NonTSPseudoClass::$s_name(..) => flag!($s_state),)* $(NonTSPseudoClass::$k_name(..) => flag!($k_state),)* + NonTSPseudoClass::Dir(..) => ElementState::empty(), NonTSPseudoClass::MozAny(..) => ElementState::empty(), } } @@ -253,6 +263,7 @@ impl NonTSPseudoClass { $(NonTSPseudoClass::$name => gecko_type!($gecko_type),)* $(NonTSPseudoClass::$s_name(..) => gecko_type!($s_gecko_type),)* $(NonTSPseudoClass::$k_name(..) => gecko_type!($k_gecko_type),)* + NonTSPseudoClass::Dir(_) => gecko_type!(dir), NonTSPseudoClass::MozAny(_) => gecko_type!(any), } } @@ -360,6 +371,17 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { .chain(Some(0u16)).collect(); NonTSPseudoClass::$k_name(utf16.into_boxed_slice()) }, )* + "dir" => { + let name: &str = parser.expect_ident()?; + let direction = match_ignore_ascii_case! { name, + "rtl" => Direction::Rtl, + "ltr" => Direction::Ltr, + _ => { + Direction::Other(Box::from(name)) + }, + }; + NonTSPseudoClass::Dir(Box::new(direction)) + }, "-moz-any" => { let selectors = parser.parse_comma_separated(|input| { Selector::parse(self, input) diff --git a/servo/components/style/gecko/wrapper.rs b/servo/components/style/gecko/wrapper.rs index ec3d6f91968b..15d3f785b6e2 100644 --- a/servo/components/style/gecko/wrapper.rs +++ b/servo/components/style/gecko/wrapper.rs @@ -74,7 +74,7 @@ use properties::animated_properties::{AnimationValue, AnimationValueMap}; use properties::animated_properties::TransitionProperty; use properties::style_structs::Font; use rule_tree::CascadeLevel as ServoCascadeLevel; -use selector_parser::{AttrValue, PseudoClassStringArg}; +use selector_parser::{AttrValue, Direction, PseudoClassStringArg}; use selectors::{Element, OpaqueElement}; use selectors::attr::{AttrSelectorOperation, AttrSelectorOperator, CaseSensitivity, NamespaceConstraint}; use selectors::matching::{ElementSelectorFlags, MatchingContext}; @@ -2070,8 +2070,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { NonTSPseudoClass::Lang(ref lang_arg) => { self.match_element_lang(None, lang_arg) } - NonTSPseudoClass::MozLocaleDir(ref s) | - NonTSPseudoClass::Dir(ref s) => { + NonTSPseudoClass::MozLocaleDir(ref s) => { unsafe { Gecko_MatchStringArgPseudo( self.0, @@ -2080,6 +2079,13 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { ) } } + NonTSPseudoClass::Dir(ref dir) => { + match **dir { + Direction::Ltr => self.get_state().intersects(ElementState::IN_LTR_STATE), + Direction::Rtl => self.get_state().intersects(ElementState::IN_RTL_STATE), + Direction::Other(..) => false, + } + } } } diff --git a/servo/components/style/invalidation/element/element_wrapper.rs b/servo/components/style/invalidation/element/element_wrapper.rs index 8b3fb0385bbd..feab46d8f7e4 100644 --- a/servo/components/style/invalidation/element/element_wrapper.rs +++ b/servo/components/style/invalidation/element/element_wrapper.rs @@ -182,9 +182,9 @@ impl<'a, E> Element for ElementWrapper<'a, E> // FIXME(bz): How can I set this up so once Servo adds :dir() // support we don't forget to update this code? #[cfg(feature = "gecko")] - NonTSPseudoClass::Dir(ref s) => { + NonTSPseudoClass::Dir(ref dir) => { use invalidation::element::invalidation_map::dir_selector_to_state; - let selector_flag = dir_selector_to_state(s); + let selector_flag = dir_selector_to_state(dir); if selector_flag.is_empty() { // :dir() with some random argument; does not match. return false; diff --git a/servo/components/style/invalidation/element/invalidation_map.rs b/servo/components/style/invalidation/element/invalidation_map.rs index e1eaa2721c32..0ae08aa0bfa4 100644 --- a/servo/components/style/invalidation/element/invalidation_map.rs +++ b/servo/components/style/invalidation/element/invalidation_map.rs @@ -10,6 +10,8 @@ use element_state::ElementState; use fallible::FallibleVec; use hashglobe::FailedAllocationError; use selector_map::{MaybeCaseInsensitiveHashMap, SelectorMap, SelectorMapEntry}; +#[cfg(feature = "gecko")] +use selector_parser::Direction; use selector_parser::SelectorImpl; use selectors::attr::NamespaceConstraint; use selectors::parser::{Combinator, Component}; @@ -19,21 +21,15 @@ use smallvec::SmallVec; #[cfg(feature = "gecko")] /// Gets the element state relevant to the given `:dir` pseudo-class selector. -pub fn dir_selector_to_state(s: &[u16]) -> ElementState { - use element_state::ElementState; - - // Jump through some hoops to deal with our Box<[u16]> thing. - const LTR: [u16; 4] = [b'l' as u16, b't' as u16, b'r' as u16, 0]; - const RTL: [u16; 4] = [b'r' as u16, b't' as u16, b'l' as u16, 0]; - - if LTR == *s { - ElementState::IN_LTR_STATE - } else if RTL == *s { - ElementState::IN_RTL_STATE - } else { - // :dir(something-random) is a valid selector, but shouldn't - // match anything. - ElementState::empty() +pub fn dir_selector_to_state(dir: &Direction) -> ElementState { + match *dir { + Direction::Ltr => ElementState::IN_LTR_STATE, + Direction::Rtl => ElementState::IN_RTL_STATE, + Direction::Other(_) => { + // :dir(something-random) is a valid selector, but shouldn't + // match anything. + ElementState::empty() + }, } } @@ -342,8 +338,8 @@ impl SelectorVisitor for CompoundSelectorDependencyCollector { self.other_attributes |= pc.is_attr_based(); self.state |= match *pc { #[cfg(feature = "gecko")] - NonTSPseudoClass::Dir(ref s) => { - dir_selector_to_state(s) + NonTSPseudoClass::Dir(ref dir) => { + dir_selector_to_state(dir) } _ => pc.state_flag(), }; diff --git a/servo/components/style/selector_parser.rs b/servo/components/style/selector_parser.rs index 62d88f2bf3b6..d2f86092c8a6 100644 --- a/servo/components/style/selector_parser.rs +++ b/servo/components/style/selector_parser.rs @@ -8,8 +8,8 @@ use cssparser::{Parser as CssParser, ParserInput}; use selectors::parser::SelectorList; -use std::fmt::{self, Debug}; -use style_traits::ParseError; +use std::fmt::{self, Debug, Write}; +use style_traits::{ParseError, ToCss}; use stylesheets::{Origin, Namespaces, UrlExtraData}; /// A convenient alias for the type that represents an attribute value used for @@ -173,3 +173,25 @@ impl PerPseudoElementMap { self.entries.iter() } } + +/// Values for the :dir() pseudo class +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum Direction { + /// left-to-right semantic directionality + Ltr, + /// right-to-left semantic directionality + Rtl, + /// Some other provided directionality value + Other(Box), +} + +impl ToCss for Direction { + fn to_css(&self, dest: &mut W) -> fmt::Result where W: Write { + let dir_str = match *self { + Direction::Rtl => "rtl", + Direction::Ltr => "ltr", + Direction::Other(ref other) => other, + }; + dest.write_str(dir_str) + } +} From e8f24cc6abc8ba3361c2aef3109e8dba1cb45c08 Mon Sep 17 00:00:00 2001 From: Alexandre Poirot Date: Thu, 16 Nov 2017 01:37:46 -0800 Subject: [PATCH 39/78] Bug 1411889 - Record netmonitor reload time. r=Honza MozReview-Commit-ID: EwXuODxvm8B --HG-- extra : rebase_source : 5e9d82f268f1c0f7423e6839d051766c3adb6702 --- devtools/client/framework/toolbox.js | 4 ++-- devtools/client/netmonitor/index.html | 3 ++- devtools/client/netmonitor/panel.js | 1 + .../src/connector/firefox-connector.js | 22 +++++++++++++++++++ .../src/connector/firefox-data-provider.js | 9 ++++++++ 5 files changed, 36 insertions(+), 3 deletions(-) diff --git a/devtools/client/framework/toolbox.js b/devtools/client/framework/toolbox.js index 310ff7014b1a..6ce0c57056d6 100644 --- a/devtools/client/framework/toolbox.js +++ b/devtools/client/framework/toolbox.js @@ -1989,8 +1989,8 @@ Toolbox.prototype = { */ async _onWillNavigate() { let toolId = this.currentToolId; - // For now, only inspector and webconsole fires "reloaded" event - if (toolId != "inspector" && toolId != "webconsole") { + // For now, only inspector, webconsole and netmonitor fire "reloaded" event + if (toolId != "inspector" && toolId != "webconsole" && toolId != "netmonitor") { return; } diff --git a/devtools/client/netmonitor/index.html b/devtools/client/netmonitor/index.html index 39b56228a276..e224ae0b412c 100644 --- a/devtools/client/netmonitor/index.html +++ b/devtools/client/netmonitor/index.html @@ -45,7 +45,7 @@ window.connector = connector; window.Netmonitor = { - bootstrap({ toolbox }) { + bootstrap({ toolbox, panel }) { this.mount = document.querySelector("#mount"); const connection = { @@ -53,6 +53,7 @@ tabTarget: toolbox.target, }, toolbox, + panel, }; const openLink = (link) => { diff --git a/devtools/client/netmonitor/panel.js b/devtools/client/netmonitor/panel.js index 4bdcf4a84098..ff3a084f1216 100644 --- a/devtools/client/netmonitor/panel.js +++ b/devtools/client/netmonitor/panel.js @@ -16,6 +16,7 @@ NetMonitorPanel.prototype = { } await this.panelWin.Netmonitor.bootstrap({ toolbox: this.toolbox, + panel: this, }); this.emit("ready"); this.isReady = true; diff --git a/devtools/client/netmonitor/src/connector/firefox-connector.js b/devtools/client/netmonitor/src/connector/firefox-connector.js index 422590d810ed..5f7b25994deb 100644 --- a/devtools/client/netmonitor/src/connector/firefox-connector.js +++ b/devtools/client/netmonitor/src/connector/firefox-connector.js @@ -15,6 +15,7 @@ class FirefoxConnector { this.connect = this.connect.bind(this); this.disconnect = this.disconnect.bind(this); this.willNavigate = this.willNavigate.bind(this); + this.navigate = this.navigate.bind(this); this.displayCachedEvents = this.displayCachedEvents.bind(this); this.onDocLoadingMarker = this.onDocLoadingMarker.bind(this); this.sendHTTPRequest = this.sendHTTPRequest.bind(this); @@ -34,6 +35,7 @@ class FirefoxConnector { this.getState = getState; this.tabTarget = connection.tabConnection.tabTarget; this.toolbox = connection.toolbox; + this.panel = connection.panel; this.webConsoleClient = this.tabTarget.activeConsole; @@ -50,6 +52,7 @@ class FirefoxConnector { // Paused network panel should be automatically resumed when page // reload, so `will-navigate` listener needs to be there all the time. this.tabTarget.on("will-navigate", this.willNavigate); + this.tabTarget.on("navigate", this.navigate); // Don't start up waiting for timeline markers if the server isn't // recent enough to emit the markers we're interested in. @@ -120,6 +123,25 @@ class FirefoxConnector { } } + navigate() { + if (this.dataProvider.isPayloadQueueEmpty()) { + this.onReloaded(); + return; + } + let listener = () => { + if (!this.dataProvider.isPayloadQueueEmpty()) { + return; + } + window.off(EVENTS.PAYLOAD_READY, listener); + this.onReloaded(); + }; + window.on(EVENTS.PAYLOAD_READY, listener); + } + + onReloaded() { + this.panel.emit("reloaded"); + } + /** * Display any network events already in the cache. */ diff --git a/devtools/client/netmonitor/src/connector/firefox-data-provider.js b/devtools/client/netmonitor/src/connector/firefox-data-provider.js index bf0c3b41d035..4a0d20166af2 100644 --- a/devtools/client/netmonitor/src/connector/firefox-data-provider.js +++ b/devtools/client/netmonitor/src/connector/firefox-data-provider.js @@ -231,6 +231,15 @@ class FirefoxDataProvider { return this.payloadQueue.find((item) => item.id === id); } + /** + * Public API used by the Toolbox: Tells if there is still any pending request. + * + * @return {boolean} returns true if the payload queue is empty + */ + isPayloadQueueEmpty() { + return this.payloadQueue.length === 0; + } + /** * Return true if payload is ready (all data fetched from the backend) * From e89a6b8d0403104bb4bf1d025d1f573c71aab880 Mon Sep 17 00:00:00 2001 From: Alexandre Poirot Date: Tue, 24 Oct 2017 02:38:21 -0700 Subject: [PATCH 40/78] Bug 1399242 - Add DAMP test to track performance of background panels. r=nchevobbe MozReview-Commit-ID: JwZaa3AA0iN --HG-- extra : rebase_source : 91a2fc3003bc191a4408c5671f49094a7b2ec504 --- .../tests/devtools/addon/content/damp.html | 4 ++++ .../tests/devtools/addon/content/damp.js | 24 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/testing/talos/talos/tests/devtools/addon/content/damp.html b/testing/talos/talos/tests/devtools/addon/content/damp.html index 202886d11bed..9e31f09590fb 100644 --- a/testing/talos/talos/tests/devtools/addon/content/damp.html +++ b/testing/talos/talos/tests/devtools/addon/content/damp.html @@ -33,6 +33,8 @@ var defaultConfig = { "console.objectexpand": true, "console.openwithcache": true, "inspector.mutations": true, + + "panelsInBackground.reload": true, } }; @@ -60,6 +62,8 @@ var testsInfo = { "console.objectexpand": "Measure time to expand a large object and close the console", "console.openwithcache": "Measure time to render last logged messages in console for a page with 100 logged messages", "inspector.mutations": "Measure the time to perform childList mutations when inspector is enabled", + + "panelsInBackground.reload": "Measure page reload time when all panels are in background", }; function updateConfig() { diff --git a/testing/talos/talos/tests/devtools/addon/content/damp.js b/testing/talos/talos/tests/devtools/addon/content/damp.js index c356f4e16742..9c8d97304fb4 100644 --- a/testing/talos/talos/tests/devtools/addon/content/damp.js +++ b/testing/talos/talos/tests/devtools/addon/content/damp.js @@ -456,6 +456,28 @@ async _consoleOpenWithCachedMessagesTest() { await this.testTeardown(); }, + async _panelsInBackgroundReload() { + let url = "data:text/html;charset=UTF-8," + encodeURIComponent(` + + `); + await this.testSetup(url); + let {toolbox} = await this.openToolbox("webconsole"); + + // Select the options panel to make the console be in background. + // Options panel should not do anything on page reload. + await toolbox.selectTool("options"); + + await this.reloadPageAndLog("panelsInBackground"); + + await this.closeToolbox(); + await this.testTeardown(); + }, + _getToolLoadingTests(url, label, { expectedMessages, expectedSources }) { let tests = { inspector: Task.async(function* () { @@ -738,6 +760,8 @@ async _consoleOpenWithCachedMessagesTest() { tests["cold.inspector"] = this._coldInspectorOpen; } + tests["panelsInBackground.reload"] = this._panelsInBackgroundReload; + Object.assign(tests, this._getToolLoadingTests(SIMPLE_URL, "simple", { expectedMessages: 1, expectedSources: 1, From fb08f4c0981218c9c989d4ebad5eadeab9c18db0 Mon Sep 17 00:00:00 2001 From: Alexandre Poirot Date: Mon, 9 Oct 2017 20:16:01 +0200 Subject: [PATCH 41/78] Bug 1399242 - Ensure firing visibilitychange event and set document.visibiltyState attribute when hidding devtools panels. r=gregtatum MozReview-Commit-ID: Gh6jp4KEZkX --HG-- extra : rebase_source : 2125a8ceb5e235b1db525cfec9bc3268e1edce54 --- devtools/client/framework/toolbox.js | 34 ++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/devtools/client/framework/toolbox.js b/devtools/client/framework/toolbox.js index 6ce0c57056d6..b9a87838f96a 100644 --- a/devtools/client/framework/toolbox.js +++ b/devtools/client/framework/toolbox.js @@ -1755,9 +1755,43 @@ Toolbox.prototype = { node.removeAttribute("selected"); node.removeAttribute("aria-selected"); } + // The webconsole panel is in a special location due to split console + if (!node.id) { + node = this.webconsolePanel; + } + + let iframe = node.querySelector(".toolbox-panel-iframe"); + if (iframe) { + let visible = node.id == id; + this.setIframeVisible(iframe, visible); + } }); }, + /** + * Make a privileged iframe visible/hidden. + * + * For now, XUL Iframes loading chrome documents (i.e.