Merge mozilla-central to mozilla-inbound. r=merge a=merge CLOSED TREE

This commit is contained in:
Attila Craciun 2017-10-31 12:54:14 +02:00
Родитель c7f4d8ad1c a63fdbeabb
Коммит eaa25de8e4
249 изменённых файлов: 17607 добавлений и 8140 удалений

Просмотреть файл

@ -48,6 +48,24 @@ var BrowserPageActions = {
*/
init() {
this.placeAllActions();
// Add a click listener to #page-action-buttons for blocking clicks on
// disabled actions in the urlbar. Normally we'd do this by setting
// `pointer-events: none` in the CSS, but that also blocks context menu
// events, and we want the context menu even on disabled actions so that
// they can be removed from the urlbar.
this.mainButtonNode.parentNode.addEventListener("click", event => {
if (event.button == 2) {
// Let context-clicks be handled normally.
return;
}
let node = event.originalTarget;
let action = this.actionForNode(node);
if (action && action.getDisabled(window)) {
event.preventDefault();
event.stopPropagation();
}
}, true);
},
/**
@ -128,6 +146,7 @@ var BrowserPageActions = {
"subviewbutton-iconic",
"pageAction-panel-button"
);
buttonNode.setAttribute("actionid", action.id);
if (action.nodeAttributes) {
for (let name in action.nodeAttributes) {
buttonNode.setAttribute(name, action.nodeAttributes[name]);
@ -391,8 +410,8 @@ var BrowserPageActions = {
_makeUrlbarButtonNode(action) {
let buttonNode = document.createElement("image");
buttonNode.classList.add("urlbar-icon", "urlbar-page-action");
buttonNode.setAttribute("actionid", action.id);
buttonNode.setAttribute("role", "button");
buttonNode.setAttribute("context", "pageActionPanelContextMenu");
buttonNode.addEventListener("contextmenu", event => {
BrowserPageActions.onContextMenu(event);
});
@ -416,6 +435,7 @@ var BrowserPageActions = {
removeAction(action) {
this._removeActionFromPanel(action);
this._removeActionFromUrlbar(action);
action.onRemovedFromWindow(window);
},
_removeActionFromPanel(action) {

Просмотреть файл

@ -1443,11 +1443,6 @@ toolbarpaletteitem[place="palette"][hidden] {
}
}
.urlbar-page-action[disabled] {
pointer-events: none;
-moz-user-focus: ignore;
}
/* WebExtension Sidebars */
#sidebar-box[sidebarcommand$="-sidebar-action"] > #sidebar-header > #sidebar-switcher-target > #sidebar-icon {
list-style-image: var(--webextension-menuitem-image, inherit);

Просмотреть файл

@ -421,7 +421,7 @@
mainViewId="pageActionPanelMainView"
viewCacheId="appMenu-viewCache">
<panelview id="pageActionPanelMainView"
context="pageActionPanelContextMenu"
context="pageActionContextMenu"
oncontextmenu="BrowserPageActions.onContextMenu(event);"
class="PanelUI-subView">
<vbox class="panel-subview-body"/>
@ -444,9 +444,9 @@
<label id="pageActionFeedbackMessage"/>
</panel>
<menupopup id="pageActionPanelContextMenu"
<menupopup id="pageActionContextMenu"
onpopupshowing="BrowserPageActions.onContextMenuShowing(event, this);">
<menuitem id="pageActionPanelContextMenu-toggleUrlbar"
<menuitem id="pageActionContextMenu-toggleUrlbar"
add-label="&pageAction.addToUrlbar.label;"
remove-label="&pageAction.removeFromUrlbar.label;"
label="&pageAction.addToUrlbar.label;"
@ -859,7 +859,9 @@
<label id="switchtab" class="urlbar-display urlbar-display-switchtab" value="&urlbar.switchToTab.label;"/>
<label id="extension" class="urlbar-display urlbar-display-extension" value="&urlbar.extension.label;"/>
</box>
<hbox id="page-action-buttons">
<hbox id="page-action-buttons"
context="pageActionContextMenu"
oncontextmenu="BrowserPageActions.onContextMenu(event);">
<hbox id="userContext-icons" hidden="true">
<label id="userContext-label"/>
<image id="userContext-indicator"/>
@ -882,8 +884,6 @@
<hbox id="star-button-box"
hidden="true"
class="urlbar-icon-wrapper urlbar-page-action"
context="pageActionPanelContextMenu"
oncontextmenu="BrowserPageActions.onContextMenu(event);"
onclick="BrowserPageActions.doCommandForAction(PageActions.actionForID('bookmark'), event, this);">
<image id="star-button"
class="urlbar-icon"

Просмотреть файл

@ -635,7 +635,7 @@ add_task(async function contextMenu() {
// Open the panel and then open the context menu on the bookmark button.
await promisePageActionPanelOpen();
let bookmarkButton = document.getElementById("pageAction-panel-bookmark");
let contextMenuPromise = promisePanelShown("pageActionPanelContextMenu");
let contextMenuPromise = promisePanelShown("pageActionContextMenu");
EventUtils.synthesizeMouseAtCenter(bookmarkButton, {
type: "contextmenu",
button: 2,
@ -643,12 +643,12 @@ add_task(async function contextMenu() {
await contextMenuPromise;
// The context menu should show "Remove from Address Bar". Click it.
let contextMenuNode = document.getElementById("pageActionPanelContextMenu");
let contextMenuNode = document.getElementById("pageActionContextMenu");
Assert.equal(contextMenuNode.childNodes.length, 1,
"Context menu has one child");
Assert.equal(contextMenuNode.childNodes[0].label, "Remove from Address Bar",
"Context menu is in the 'remove' state");
contextMenuPromise = promisePanelHidden("pageActionPanelContextMenu");
contextMenuPromise = promisePanelHidden("pageActionContextMenu");
EventUtils.synthesizeMouseAtCenter(contextMenuNode.childNodes[0], {});
await contextMenuPromise;
@ -661,7 +661,7 @@ add_task(async function contextMenu() {
// Open the context menu again on the bookmark button. (The page action
// panel remains open.)
contextMenuPromise = promisePanelShown("pageActionPanelContextMenu");
contextMenuPromise = promisePanelShown("pageActionContextMenu");
EventUtils.synthesizeMouseAtCenter(bookmarkButton, {
type: "contextmenu",
button: 2,
@ -673,7 +673,7 @@ add_task(async function contextMenu() {
"Context menu has one child");
Assert.equal(contextMenuNode.childNodes[0].label, "Add to Address Bar",
"Context menu is in the 'add' state");
contextMenuPromise = promisePanelHidden("pageActionPanelContextMenu");
contextMenuPromise = promisePanelHidden("pageActionContextMenu");
EventUtils.synthesizeMouseAtCenter(contextMenuNode.childNodes[0], {});
await contextMenuPromise;
@ -683,7 +683,7 @@ add_task(async function contextMenu() {
}, "Waiting for star button to become unhidden");
// Open the context menu on the bookmark star in the urlbar.
contextMenuPromise = promisePanelShown("pageActionPanelContextMenu");
contextMenuPromise = promisePanelShown("pageActionContextMenu");
EventUtils.synthesizeMouseAtCenter(starButtonBox, {
type: "contextmenu",
button: 2,
@ -695,7 +695,7 @@ add_task(async function contextMenu() {
"Context menu has one child");
Assert.equal(contextMenuNode.childNodes[0].label, "Remove from Address Bar",
"Context menu is in the 'remove' state");
contextMenuPromise = promisePanelHidden("pageActionPanelContextMenu");
contextMenuPromise = promisePanelHidden("pageActionContextMenu");
EventUtils.synthesizeMouseAtCenter(contextMenuNode.childNodes[0], {});
await contextMenuPromise;
@ -707,7 +707,7 @@ add_task(async function contextMenu() {
// Finally, add the bookmark star back to the urlbar so that other tests
// that rely on it are OK.
await promisePageActionPanelOpen();
contextMenuPromise = promisePanelShown("pageActionPanelContextMenu");
contextMenuPromise = promisePanelShown("pageActionContextMenu");
EventUtils.synthesizeMouseAtCenter(bookmarkButton, {
type: "contextmenu",
button: 2,
@ -717,7 +717,7 @@ add_task(async function contextMenu() {
"Context menu has one child");
Assert.equal(contextMenuNode.childNodes[0].label, "Add to Address Bar",
"Context menu is in the 'add' state");
contextMenuPromise = promisePanelHidden("pageActionPanelContextMenu");
contextMenuPromise = promisePanelHidden("pageActionContextMenu");
EventUtils.synthesizeMouseAtCenter(contextMenuNode.childNodes[0], {});
await contextMenuPromise;
await BrowserTestUtils.waitForCondition(() => {

Просмотреть файл

@ -73,6 +73,15 @@ this.pageAction = class extends ExtensionAPI {
onCommand: (event, buttonNode) => {
this.handleClick(event.target.ownerGlobal);
},
onBeforePlacedInWindow: browserWindow => {
if (this.extension.hasPermission("menus") ||
this.extension.hasPermission("contextMenus")) {
browserWindow.document.addEventListener("popupshowing", this);
}
},
onRemovedFromWindow: browserWindow => {
browserWindow.document.removeEventListener("popupshowing", this);
},
}));
}
}
@ -151,6 +160,25 @@ this.pageAction = class extends ExtensionAPI {
}
}
handleEvent(event) {
switch (event.type) {
case "popupshowing":
const menu = event.target;
const trigger = menu.triggerNode;
if (menu.id === "pageActionContextMenu" &&
trigger &&
trigger.getAttribute("actionid") === this.browserPageAction.id) {
global.actionContextMenu({
extension: this.extension,
onPageAction: true,
menu: menu,
});
}
break;
}
}
// Handles a click event on the page action button for the given
// window.
// If the page action has a |popup| property, a panel is opened to

Просмотреть файл

@ -68,10 +68,7 @@ add_task(async function test_actionContextMenus() {
await extension.startup();
const tabId = await extension.awaitMessage("ready");
// TODO bug 1412170: Allow WebExtensions to hook into the browser page action
// context menu.
// for (const kind of ["page", "browser"]) {
for (const kind of ["browser"]) {
for (const kind of ["page", "browser"]) {
const menu = await openActionContextMenu(extension, kind);
const [submenu, second, , , , last, separator] = menu.children;
@ -92,7 +89,7 @@ add_task(async function test_actionContextMenus() {
is(last.id, `${idPrefix}5`, "Last menu item id is correct");
is(separator.tagName, "menuseparator", "Separator after last menu item");
await closeActionContextMenu(popup.firstChild);
await closeActionContextMenu(popup.firstChild, kind);
const {info, tab} = await extension.awaitMessage("click");
is(info.pageUrl, "http://example.com/", "Click info pageUrl is correct");
is(tab.id, tabId, "Click event tab ID is correct");

Просмотреть файл

@ -393,15 +393,21 @@ async function openActionContextMenu(extension, kind, win = window) {
// See comment from clickPageAction below.
SetPageProxyState("valid");
await promiseAnimationFrame(win);
const id =
kind == "page" ?
`#${BrowserPageActions.urlbarButtonNodeIDForActionID(makeWidgetId(extension.id))}` :
`#${makeWidgetId(extension.id)}-${kind}-action`;
return openChromeContextMenu("toolbar-context-menu", id, win);
let buttonID;
let menuID;
if (kind == "page") {
buttonID = "#" + BrowserPageActions.urlbarButtonNodeIDForActionID(makeWidgetId(extension.id));
menuID = "pageActionContextMenu";
} else {
buttonID = `#${makeWidgetId(extension.id)}-${kind}-action`;
menuID = "toolbar-context-menu";
}
return openChromeContextMenu(menuID, buttonID, win);
}
function closeActionContextMenu(itemToSelect, win = window) {
return closeChromeContextMenu("toolbar-context-menu", itemToSelect, win);
function closeActionContextMenu(itemToSelect, kind, win = window) {
let menuID = kind == "page" ? "pageActionContextMenu" : "toolbar-context-menu";
return closeChromeContextMenu(menuID, itemToSelect, win);
}
function openTabContextMenu(win = window) {

4
browser/extensions/pocket/bootstrap.js поставляемый
Просмотреть файл

@ -110,10 +110,6 @@ var PocketPageAction = {
let wrapper = doc.createElement("hbox");
wrapper.id = "pocket-button-box";
wrapper.classList.add("urlbar-icon-wrapper", "urlbar-page-action");
wrapper.setAttribute("context", "pageActionPanelContextMenu");
wrapper.addEventListener("contextmenu", event => {
window.BrowserPageActions.onContextMenu(event);
});
let animatableBox = doc.createElement("hbox");
animatableBox.id = "pocket-animatable-box";
let animatableImage = doc.createElement("image");

Просмотреть файл

@ -533,6 +533,10 @@ this.PageActions = {
* Called when the action is added to the urlbar in a browser window:
* onPlacedInUrlbar(buttonNode)
* * buttonNode: The action's node in the urlbar.
* @param onRemovedFromWindow (function, optional)
* Called after the action is removed from a browser window:
* onRemovedFromWindow(browserWindow)
* * browserWindow: The browser window that the action was removed from.
* @param onShowingInPanel (function, optional)
* Called when a browser window's page action panel is showing:
* onShowingInPanel(buttonNode)
@ -571,6 +575,7 @@ function Action(options) {
onLocationChange: false,
onPlacedInPanel: false,
onPlacedInUrlbar: false,
onRemovedFromWindow: false,
onShowingInPanel: false,
shownInUrlbar: false,
subview: false,
@ -924,6 +929,19 @@ Action.prototype = {
}
},
/**
* Call this when the DOM nodes for the action are removed from a browser
* window.
*
* @param browserWindow (DOM window, required)
* The browser window the action was removed from.
*/
onRemovedFromWindow(browserWindow) {
if (this._onRemovedFromWindow) {
this._onRemovedFromWindow(browserWindow);
}
},
/**
* Call this when the action's button is shown in the page action panel.
*

Просмотреть файл

@ -210,14 +210,14 @@
height: 30px;
}
.urlbar-icon:hover,
.urlbar-icon-wrapper:hover {
.urlbar-icon:not([disabled]):hover,
.urlbar-icon-wrapper:not([disabled]):hover {
background-color: hsla(0,0%,80%,.4);
}
.urlbar-icon[open],
.urlbar-icon-wrapper[open],
.urlbar-icon:hover:active,
.urlbar-icon:not([disabled]):hover:active,
.urlbar-icon-wrapper:hover:active {
background-color: hsla(0,0%,80%,.6);
}

Просмотреть файл

@ -38,13 +38,6 @@ e.g.::
mk_add_options AUTOCLOBBER=1
ac_add_options
^^^^^^^^^^^^^^
This is a variant of ac_add_options() which only adds configure options
for a specified application. This is only used when building multiple
applications through client.mk. This function is typically not needed.
Special mk_add_options Variables
--------------------------------

Просмотреть файл

@ -0,0 +1,49 @@
# This file exists to support comm-central from building with mozilla-central
# as a subdirectory to building as a subdirectory of mozilla-central.
# In order to have mozconfig files that support building in either
# configuration during the transition, without duplicating the logic
# in every mozconfig file, there needs to exist a file that exists at the
# same path in mozilla-central and comm-central.
# This file gets included under two circumstances.
# 1. comm-central is being built as a subdirectory of mozilla-central.
# 2. comm-central is being built as a parent directory of mozilla-central,
# but `mach` was invoked from the objdir and thinks that $topsrcdir is
# the mozilla-central directory. If we detect this is the case, we fix
# $topsrcdir before proceeding.
# In either case, we then invoke the identically named file that lives in
# comm-central, which sets some variables that can be used by the rest of the
# mozconfig.
# Note that the top-level mozconfig file is in $2.
if [ "$(dirname "$2")" = "$topsrcdir" ]; then
# No weirdness
if [ -d "$topsrcdir/mail" ]; then
# Building with comm-central as top-level directory.
echo "ERROR: Should not include mozilla/build/mozconfig.comm when building"
echo " with comm-central as top-level directory."
exit 1
elif [ -d "$topsrcdir/comm/mail" ]; then
# Building with mozila-central as top-level directory.
. "$topsrcdir/comm/build/mozconfig.comm-support"
else
echo "ERROR: Unknown build directory layout."
exit 1
fi
elif [ "$(dirname "$2")" = "$(dirname "$topsrcdir")" ]; then
if [ -d "$topsrcdir/../mail" ]; then
# Building with comm-central as top-level directory;
# but invoked with $topsrcdir as "mozilla/".
topsrcdir=$(dirname "$topsrcdir")
. "$topsrcdir/build/mozconfig.comm-support"
else
echo "ERROR: Unknown build directory layout."
exit 1
fi
else
echo "ERROR: Unknown build directory layout."
exit 1
fi

Просмотреть файл

@ -4,6 +4,7 @@
# These files are read as part of generating the taskgraph.
path:browser/locales/l10n-changesets.json
path:mobile/locales/l10n-changesets.json
path:browser/config/version_display.txt
# Lots of random files in here are read. Just pull in the whole thing.
path:build/

Просмотреть файл

@ -37,7 +37,7 @@ const OPEN_DEVICE_MODAL_VALUE = "OPEN_DEVICE_MODAL";
const { _loadPreferredDevices } = require("devtools/client/responsive.html/actions/devices");
const asyncStorage = require("devtools/shared/async-storage");
const { addDevice, removeDevice } = require("devtools/client/shared/devices");
const { addDevice, removeDevice, removeLocalDevices } = require("devtools/client/shared/devices");
SimpleTest.requestCompleteLog();
SimpleTest.waitForExplicitFinish();
@ -52,12 +52,12 @@ Services.prefs.clearUserPref("devtools.responsive.html.displayedDeviceList");
Services.prefs.setCharPref("devtools.devices.url",
TEST_URI_ROOT + "devices.json");
registerCleanupFunction(() => {
registerCleanupFunction(async () => {
flags.testing = false;
Services.prefs.clearUserPref("devtools.devices.url");
Services.prefs.clearUserPref("devtools.responsive.html.displayedDeviceList");
asyncStorage.removeItem("devtools.devices.url_cache");
asyncStorage.removeItem("devtools.devices.local");
await asyncStorage.removeItem("devtools.devices.url_cache");
await removeLocalDevices();
});
loader.lazyRequireGetter(this, "ResponsiveUIManager", "devtools/client/responsive.html/manager", true);

Просмотреть файл

@ -4,7 +4,6 @@
"use strict";
const { Task } = require("devtools/shared/task");
const { getJSON } = require("devtools/client/shared/getjson");
const { LocalizationHelper } = require("devtools/shared/l10n");
const L10N = new LocalizationHelper("devtools/client/locales/device.properties");
@ -43,35 +42,40 @@ const LOCAL_DEVICES = "devtools.devices.local";
let localDevices;
let localDevicesLoaded = false;
// Load local devices from storage.
let loadLocalDevices = Task.async(function* () {
/**
* Load local devices from storage.
*/
async function loadLocalDevices() {
if (localDevicesLoaded) {
return;
}
let devicesJSON = yield asyncStorage.getItem(LOCAL_DEVICES);
let devicesJSON = await asyncStorage.getItem(LOCAL_DEVICES);
if (!devicesJSON) {
devicesJSON = "{}";
}
localDevices = JSON.parse(devicesJSON);
localDevicesLoaded = true;
});
}
// Add a device to the local catalog.
let addDevice = Task.async(function* (device, type = "phones") {
yield loadLocalDevices();
/**
* Add a device to the local catalog.
*/
async function addDevice(device, type = "phones") {
await loadLocalDevices();
let list = localDevices[type];
if (!list) {
list = localDevices[type] = [];
}
list.push(Object.assign({}, device));
yield asyncStorage.setItem(LOCAL_DEVICES, JSON.stringify(localDevices));
});
exports.addDevice = addDevice;
await asyncStorage.setItem(LOCAL_DEVICES, JSON.stringify(localDevices));
}
// Remove a device from the local catalog.
// returns `true` if the device is removed, `false` otherwise.
let removeDevice = Task.async(function* (device, type = "phones") {
yield loadLocalDevices();
/**
* Remove a device from the local catalog.
* Returns `true` if the device is removed, `false` otherwise.
*/
async function removeDevice(device, type = "phones") {
await loadLocalDevices();
let list = localDevices[type];
if (!list) {
return false;
@ -84,17 +88,26 @@ let removeDevice = Task.async(function* (device, type = "phones") {
}
list.splice(index, 1);
yield asyncStorage.setItem(LOCAL_DEVICES, JSON.stringify(localDevices));
await asyncStorage.setItem(LOCAL_DEVICES, JSON.stringify(localDevices));
return true;
});
exports.removeDevice = removeDevice;
}
// Get the complete devices catalog.
let getDevices = Task.async(function* () {
/**
* Remove all local devices. Useful to clear everything when testing.
*/
async function removeLocalDevices() {
await asyncStorage.removeItem(LOCAL_DEVICES);
localDevices = {};
}
/**
* Get the complete devices catalog.
*/
async function getDevices() {
// Fetch common devices from Mozilla's CDN.
let devices = yield getJSON(DEVICES_URL);
yield loadLocalDevices();
let devices = await getJSON(DEVICES_URL);
await loadLocalDevices();
for (let type in localDevices) {
if (!devices[type]) {
devices.TYPES.push(type);
@ -103,11 +116,19 @@ let getDevices = Task.async(function* () {
devices[type] = localDevices[type].concat(devices[type]);
}
return devices;
});
exports.getDevices = getDevices;
}
// Get the localized string for a device type.
/**
* Get the localized string for a device type.
*/
function getDeviceString(deviceType) {
return L10N.getStr("device." + deviceType);
}
exports.getDeviceString = getDeviceString;
module.exports = {
addDevice,
removeDevice,
removeLocalDevices,
getDevices,
getDeviceString,
};

Просмотреть файл

@ -14462,6 +14462,12 @@ nsDocShell::OnLinkClickSync(nsIContent* aContent,
aTriggeringPrincipal ? aTriggeringPrincipal
: aContent->NodePrincipal();
// Link click (or form submission) can be triggered inside an onload handler,
// and we don't want to add history entry in this case.
bool inOnLoadHandler = false;
GetIsExecutingOnLoadHandler(&inOnLoadHandler);
uint32_t loadType = inOnLoadHandler ? LOAD_NORMAL_REPLACE : LOAD_LINK;
nsresult rv = InternalLoad(clonedURI, // New URI
nullptr, // Original URI
Nothing(), // Let the protocol handler assign it
@ -14477,7 +14483,7 @@ nsDocShell::OnLinkClickSync(nsIContent* aContent,
aPostDataStream, // Post data stream
aPostDataStreamLength, // Post data stream length
aHeadersDataStream, // Headers stream
LOAD_LINK, // Load type
loadType, // Load type
nullptr, // No SHEntry
true, // first party site
VoidString(), // No srcdoc

Просмотреть файл

@ -733,6 +733,24 @@ KeyframeEffectReadOnly::ComposeStyle(
*segment,
computedTiming);
}
// If the animation produces any transform change hint, we need to record the
// current time to unthrottle the animation periodically when the animation is
// being throttled because it's scrolled out of view.
if (mCumulativeChangeHint & (nsChangeHint_UpdatePostTransformOverflow |
nsChangeHint_AddOrRemoveTransform |
nsChangeHint_UpdateTransformLayer)) {
nsPresContext* presContext =
nsContentUtils::GetContextForContent(mTarget->mElement);
if (presContext) {
TimeStamp now = presContext->RefreshDriver()->MostRecentRefresh();
EffectSet* effectSet =
EffectSet::GetEffectSet(mTarget->mElement, mTarget->mPseudoType);
MOZ_ASSERT(effectSet, "ComposeStyle should only be called on an effect "
"that is part of an effect set");
effectSet->UpdateLastTransformSyncTime(now);
}
}
}
bool
@ -1392,8 +1410,17 @@ KeyframeEffectReadOnly::CanThrottle() const
// is in background tabs.
if (mInEffectOnLastAnimationTimingUpdate && CanIgnoreIfNotVisible()) {
nsIPresShell* presShell = GetPresShell();
if ((presShell && !presShell->IsActive()) ||
frame->IsScrolledOutOfView()) {
if (presShell && !presShell->IsActive()) {
return true;
}
if (frame->IsScrolledOutOfView()) {
// If there are transform change hints, unthrottle the animation
// periodically since it might affect the overflow region.
if (mCumulativeChangeHint & (nsChangeHint_UpdatePostTransformOverflow |
nsChangeHint_AddOrRemoveTransform |
nsChangeHint_UpdateTransformLayer)) {
return CanThrottleTransformChanges(*frame);
}
return true;
}
}

Просмотреть файл

@ -114,7 +114,6 @@ support-files =
[mozilla/test_hide_and_show.html]
[mozilla/test_moz-prefixed-properties.html]
[mozilla/test_restyles.html]
skip-if = os == 'android' # bug 1335986
[mozilla/test_restyling_xhr_doc.html]
[mozilla/test_set-easing.html]
[mozilla/test_transform_limits.html]

Просмотреть файл

@ -300,6 +300,49 @@ waitForAllPaints(function() {
await ensureElementRemoval(parentElement);
});
add_task(
async function restyling_transform_animations_in_scrolled_out_element() {
if (!offscreenThrottlingEnabled) {
return;
}
await SpecialPowers.pushPrefEnv({ set: [["ui.showHideScrollbars", 1]] });
var parentElement = addDiv(null,
{ style: 'overflow-y: scroll; height: 20px;' });
var div = addDiv(null,
{ style: 'animation: rotate 100s; position: relative; top: 100px;' });
parentElement.appendChild(div);
var animation = div.getAnimations()[0];
var timeAtStart = document.timeline.currentTime;
ok(!animation.isRunningOnCompositor,
'The transform animation is not running on the compositor');
var markers;
var now;
while (true) {
markers = await observeStyling(1);
// Check restyle markers until 200ms is elapsed.
now = document.timeline.currentTime;
if ((now - timeAtStart) >= 200) {
break;
}
is(markers.length, 0,
'Transform animation running on the element which is scrolled out ' +
'should be throttled until 200ms is elapsed');
}
is(markers.length, 1,
'Transform animation running on the element which is scrolled out ' +
'should be unthrottled after around 200ms have elapsed. now: ' +
now + ' start time: ' + timeAtStart);
await ensureElementRemoval(parentElement);
}
);
add_task(async function restyling_main_thread_animations_in_scrolled_out_element() {
if (!offscreenThrottlingEnabled) {
return;

Просмотреть файл

@ -11,7 +11,6 @@
#include "mozilla/Maybe.h"
#include "MediaDataDemuxer.h"
#include "MediaResource.h"
#include "mp4_demuxer/ByteReader.h"
namespace mozilla {

Просмотреть файл

@ -26,6 +26,7 @@
#include "nsIPrincipal.h"
#include "nsISeekableStream.h"
#include "nsPrintfCString.h"
#include "nsProxyRelease.h"
#include "nsThreadUtils.h"
#include "prio.h"
#include <algorithm>
@ -1537,6 +1538,10 @@ public:
NS_IMETHOD Run() override
{
mMediaCache->Update();
// Ensure MediaCache is deleted on the main thread.
NS_ProxyRelease("UpdateEvent::mMediaCache",
SystemGroup::EventTargetFor(mozilla::TaskCategory::Other),
mMediaCache.forget());
return NS_OK;
}

Просмотреть файл

@ -903,29 +903,6 @@ VRFrameInfo::Update(const gfx::VRDisplayInfo& aInfo,
}
mVRState.timestamp = aState.timestamp + mTimeStampOffset;
gfx::Quaternion qt;
if (mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Orientation) {
qt.x = mVRState.orientation[0];
qt.y = mVRState.orientation[1];
qt.z = mVRState.orientation[2];
qt.w = mVRState.orientation[3];
}
gfx::Point3D pos;
if (mVRState.flags & gfx::VRDisplayCapabilityFlags::Cap_Position) {
pos.x = -mVRState.position[0];
pos.y = -mVRState.position[1];
pos.z = -mVRState.position[2];
}
gfx::Matrix4x4 matHead;
matHead.SetRotationFromQuaternion(qt);
matHead.PreTranslate(pos);
mLeftView = matHead;
mLeftView.PostTranslate(-aInfo.mEyeTranslation[gfx::VRDisplayInfo::Eye_Left]);
mRightView = matHead;
mRightView.PostTranslate(-aInfo.mEyeTranslation[gfx::VRDisplayInfo::Eye_Right]);
// Avoid division by zero within ConstructProjectionMatrix
const float kEpsilon = 0.00001f;
if (fabs(aDepthFar - aDepthNear) < kEpsilon) {
@ -936,6 +913,8 @@ VRFrameInfo::Update(const gfx::VRDisplayInfo& aInfo,
mLeftProjection = leftFOV.ConstructProjectionMatrix(aDepthNear, aDepthFar, true);
const gfx::VRFieldOfView rightFOV = aInfo.mEyeFOV[gfx::VRDisplayInfo::Eye_Right];
mRightProjection = rightFOV.ConstructProjectionMatrix(aDepthNear, aDepthFar, true);
memcpy(mLeftView.components, aState.leftViewMatrix, sizeof(aState.leftViewMatrix));
memcpy(mRightView.components, aState.rightViewMatrix, sizeof(aState.rightViewMatrix));
}
VRFrameInfo::VRFrameInfo()

Просмотреть файл

@ -1118,40 +1118,47 @@ ServiceWorkerRegistrar::GetState(nsIPropertyBag**)
return NS_OK;
}
#define RELEASE_ASSERT_SUCCEEDED(rv, name) do { \
if (NS_FAILED(rv)) { \
if (rv == NS_ERROR_XPC_JAVASCRIPT_ERROR_WITH_DETAILS) { \
if (auto* context = CycleCollectedJSContext::Get()) { \
if (nsCOMPtr<nsIException> exn = context->GetPendingException()) { \
nsAutoCString msg; \
if (NS_SUCCEEDED(exn->GetMessageMoz(msg))) { \
MOZ_CRASH_UNSAFE_PRINTF("Failed to get " name ": %s", msg.get());\
} \
} \
} \
} \
\
nsAutoCString errorName; \
GetErrorName(rv, errorName); \
MOZ_CRASH_UNSAFE_PRINTF("Failed to get " name ": %s", \
errorName.get()); \
} \
} while (0)
nsCOMPtr<nsIAsyncShutdownClient>
ServiceWorkerRegistrar::GetShutdownPhase() const
{
nsCOMPtr<nsIAsyncShutdownService> svc = services::GetAsyncShutdown();
MOZ_RELEASE_ASSERT(svc);
nsCOMPtr<nsIAsyncShutdownClient> client;
nsresult rv = svc->GetProfileBeforeChange(getter_AddRefs(client));
nsresult rv;
nsCOMPtr<nsIAsyncShutdownService> svc = do_GetService(
"@mozilla.org/async-shutdown-service;1", &rv);
// If this fails, something is very wrong on the JS side (or we're out of
// memory), and there's no point in continuing startup. Include as much
// information as possible in the crash report.
if (NS_FAILED(rv)) {
if (rv == NS_ERROR_XPC_JAVASCRIPT_ERROR_WITH_DETAILS) {
if (auto* context = CycleCollectedJSContext::Get()) {
if (nsCOMPtr<nsIException> exn = context->GetPendingException()) {
nsAutoCString msg;
if (NS_SUCCEEDED(exn->GetMessageMoz(msg))) {
MOZ_CRASH_UNSAFE_PRINTF("Failed to get profileBeforeChange shutdown blocker: %s",
msg.get());
RELEASE_ASSERT_SUCCEEDED(rv, "async shutdown service");
}
}
}
}
nsAutoCString errorName;
GetErrorName(rv, errorName);
MOZ_CRASH_UNSAFE_PRINTF("Failed to get profileBeforeChange shutdown blocker: %s",
errorName.get());
}
MOZ_RELEASE_ASSERT(client);
nsCOMPtr<nsIAsyncShutdownClient> client;
rv = svc->GetProfileBeforeChange(getter_AddRefs(client));
RELEASE_ASSERT_SUCCEEDED(rv, "profileBeforeChange shutdown blocker");
return Move(client);
}
#undef RELEASE_ASSERT_SUCCEEDED
void
ServiceWorkerRegistrar::Shutdown()
{

Просмотреть файл

@ -1437,6 +1437,59 @@ public:
*((&_41)+aIndex) = aVector.w;
}
bool Decompose(Point3D& translation, Quaternion& rotation, Point3D& scale) const
{
// Ensure matrix can be normalized
if (gfx::FuzzyEqual(_44, 0.0f)) {
return false;
}
Matrix4x4Typed mat = *this;
mat.Normalize();
if (HasPerspectiveComponent()) {
// We do not support projection matrices
return false;
}
// Extract translation
translation.x = mat._41;
translation.y = mat._42;
translation.z = mat._43;
// Remove translation
mat._41 = 0.0f;
mat._42 = 0.0f;
mat._43 = 0.0f;
// Extract scale
scale.x = sqrtf(_11 * _11 + _21 * _21 + _31 * _31);
scale.y = sqrtf(_12 * _12 + _22 * _22 + _32 * _32);
scale.z = sqrtf(_13 * _13 + _23 * _23 + _33 * _33);
// Remove scale
if (gfx::FuzzyEqual(scale.x, 0.0f) ||
gfx::FuzzyEqual(scale.y, 0.0f) ||
gfx::FuzzyEqual(scale.z, 0.0f)) {
// We do not support matrices with a zero scale component
return false;
}
Float invXS = 1.0f / scale.x;
Float invYS = 1.0f / scale.y;
Float invZS = 1.0f / scale.z;
mat._11 *= invXS;
mat._21 *= invXS;
mat._31 *= invXS;
mat._12 *= invYS;
mat._22 *= invYS;
mat._32 *= invYS;
mat._13 *= invZS;
mat._23 *= invZS;
mat._33 *= invZS;
// Extract rotation
rotation.SetFromRotationMatrix(mat);
return true;
}
// Sets this matrix to a rotation matrix given by aQuat.
// This quaternion *MUST* be normalized!
// Implemented in Quaternion.cpp

Просмотреть файл

@ -130,3 +130,21 @@ VRSystemManager::NewHandChangeEvent(uint32_t aIndex,
vm->NotifyGamepadChange<dom::GamepadHandInformation>(aIndex, a);
}
void
VRHMDSensorState::CalcViewMatrices(const gfx::Matrix4x4* aHeadToEyeTransforms)
{
gfx::Matrix4x4 matHead;
if (flags & VRDisplayCapabilityFlags::Cap_Orientation) {
matHead.SetRotationFromQuaternion(gfx::Quaternion(orientation[0], orientation[1],
orientation[2], orientation[3]));
}
matHead.PreTranslate(-position[0], -position[1], -position[2]);
gfx::Matrix4x4 matView = matHead * aHeadToEyeTransforms[VRDisplayInfo::Eye_Left];
matView.Normalize();
memcpy(leftViewMatrix, matView.components, sizeof(matView.components));
matView = matHead * aHeadToEyeTransforms[VRDisplayInfo::Eye_Right];
matView.Normalize();
memcpy(rightViewMatrix, matView.components, sizeof(matView.components));
}

Просмотреть файл

@ -145,6 +145,8 @@ struct VRHMDSensorState {
// These members will only change with inputFrameID:
float orientation[4];
float position[3];
float leftViewMatrix[16];
float rightViewMatrix[16];
float angularVelocity[3];
float angularAcceleration[3];
float linearVelocity[3];
@ -162,6 +164,7 @@ struct VRHMDSensorState {
bool operator!=(const VRHMDSensorState& other) const {
return !(*this == other);
}
void CalcViewMatrices(const gfx::Matrix4x4* aHeadToEyeTransforms);
};
// The maximum number of frames of latency that we would expect before we

Просмотреть файл

@ -261,6 +261,15 @@ VRDisplayOSVR::VRDisplayOSVR(OSVR_ClientContext* context,
mDisplayInfo.mEyeTranslation[eye].x = eyePose.translation.data[0];
mDisplayInfo.mEyeTranslation[eye].y = eyePose.translation.data[1];
mDisplayInfo.mEyeTranslation[eye].z = eyePose.translation.data[2];
Matrix4x4 pose;
pose.SetRotationFromQuaternion(gfx::Quaternion(osvrQuatGetX(&eyePose.rotation),
osvrQuatGetY(&eyePose.rotation),
osvrQuatGetZ(&eyePose.rotation),
osvrQuatGetW(&eyePose.rotation)));
pose.PreTranslate(eyePose.translation.data[0], eyePose.translation.data[1], eyePose.translation.data[2]);
pose.Invert();
mHeadToEye[eye] = pose;
}
}
@ -305,6 +314,9 @@ VRDisplayOSVR::GetSensorState()
result.orientation[1] = orientation.data[2];
result.orientation[2] = orientation.data[3];
result.orientation[3] = orientation.data[0];
} else {
// default to an identity quaternion
result.orientation[3] = 1.0f;
}
OSVR_PositionState position;
@ -316,6 +328,8 @@ VRDisplayOSVR::GetSensorState()
result.position[2] = position.data[2];
}
result.CalcViewMatrices(mHeadToEye);
return result;
}

Просмотреть файл

@ -64,6 +64,8 @@ protected:
OSVR_ClientContext* m_ctx;
OSVR_ClientInterface* m_iface;
OSVR_DisplayConfig* m_display;
gfx::Matrix4x4 mHeadToEye[2];
};
} // namespace impl

Просмотреть файл

@ -75,6 +75,8 @@ static pfn_ovr_GetTrackerDesc ovr_GetTrackerDesc = nullptr;
static pfn_ovr_Create ovr_Create = nullptr;
static pfn_ovr_Destroy ovr_Destroy = nullptr;
static pfn_ovr_GetSessionStatus ovr_GetSessionStatus = nullptr;
static pfn_ovr_IsExtensionSupported ovr_IsExtensionSupported = nullptr;
static pfn_ovr_EnableExtension ovr_EnableExtension = nullptr;
static pfn_ovr_SetTrackingOriginType ovr_SetTrackingOriginType = nullptr;
static pfn_ovr_GetTrackingOriginType ovr_GetTrackingOriginType = nullptr;
static pfn_ovr_RecenterTrackingOrigin ovr_RecenterTrackingOrigin = nullptr;
@ -104,7 +106,10 @@ static pfn_ovr_CommitTextureSwapChain ovr_CommitTextureSwapChain = nullptr;
static pfn_ovr_DestroyTextureSwapChain ovr_DestroyTextureSwapChain = nullptr;
static pfn_ovr_DestroyMirrorTexture ovr_DestroyMirrorTexture = nullptr;
static pfn_ovr_GetFovTextureSize ovr_GetFovTextureSize = nullptr;
static pfn_ovr_GetRenderDesc ovr_GetRenderDesc = nullptr;
static pfn_ovr_GetRenderDesc2 ovr_GetRenderDesc2 = nullptr;
static pfn_ovr_WaitToBeginFrame ovr_WaitToBeginFrame = nullptr;
static pfn_ovr_BeginFrame ovr_BeginFrame = nullptr;
static pfn_ovr_EndFrame ovr_EndFrame = nullptr;
static pfn_ovr_SubmitFrame ovr_SubmitFrame = nullptr;
static pfn_ovr_GetPerfStats ovr_GetPerfStats = nullptr;
static pfn_ovr_ResetPerfStats ovr_ResetPerfStats = nullptr;
@ -143,7 +148,7 @@ static pfn_ovr_GetMirrorTextureBufferGL ovr_GetMirrorTextureBufferGL = nullptr;
#define OVR_PRODUCT_VERSION 1
#define OVR_MAJOR_VERSION 1
#define OVR_MINOR_VERSION 15
#define OVR_MINOR_VERSION 19
enum class OculusLeftControllerButtonType : uint16_t {
LThumb,
@ -635,6 +640,8 @@ VROculusSession::LoadOvrLib()
REQUIRE_FUNCTION(ovr_Create);
REQUIRE_FUNCTION(ovr_Destroy);
REQUIRE_FUNCTION(ovr_GetSessionStatus);
REQUIRE_FUNCTION(ovr_IsExtensionSupported);
REQUIRE_FUNCTION(ovr_EnableExtension);
REQUIRE_FUNCTION(ovr_SetTrackingOriginType);
REQUIRE_FUNCTION(ovr_GetTrackingOriginType);
REQUIRE_FUNCTION(ovr_RecenterTrackingOrigin);
@ -664,7 +671,10 @@ VROculusSession::LoadOvrLib()
REQUIRE_FUNCTION(ovr_DestroyTextureSwapChain);
REQUIRE_FUNCTION(ovr_DestroyMirrorTexture);
REQUIRE_FUNCTION(ovr_GetFovTextureSize);
REQUIRE_FUNCTION(ovr_GetRenderDesc);
REQUIRE_FUNCTION(ovr_GetRenderDesc2);
REQUIRE_FUNCTION(ovr_WaitToBeginFrame);
REQUIRE_FUNCTION(ovr_BeginFrame);
REQUIRE_FUNCTION(ovr_EndFrame);
REQUIRE_FUNCTION(ovr_SubmitFrame);
REQUIRE_FUNCTION(ovr_GetPerfStats);
REQUIRE_FUNCTION(ovr_ResetPerfStats);
@ -779,14 +789,8 @@ VRDisplayOculus::VRDisplayOculus(VROculusSession* aSession)
float pixelsPerDisplayPixel = 1.0;
ovrSizei texSize[2];
// get eye parameters and create the mesh
// get eye texture sizes
for (uint32_t eye = 0; eye < VRDisplayInfo::NumEyes; eye++) {
ovrEyeRenderDesc renderDesc = ovr_GetRenderDesc(mSession->Get(), (ovrEyeType)eye, mFOVPort[eye]);
// As of Oculus 0.6.0, the HmdToEyeOffset values are correct and don't need to be negated.
mDisplayInfo.mEyeTranslation[eye] = Point3D(renderDesc.HmdToEyeOffset.x, renderDesc.HmdToEyeOffset.y, renderDesc.HmdToEyeOffset.z);
texSize[eye] = ovr_GetFovTextureSize(mSession->Get(), (ovrEyeType)eye, mFOVPort[eye], pixelsPerDisplayPixel);
}
@ -794,6 +798,7 @@ VRDisplayOculus::VRDisplayOculus(VROculusSession* aSession)
mDisplayInfo.mEyeResolution.width = std::max(texSize[VRDisplayInfo::Eye_Left].w, texSize[VRDisplayInfo::Eye_Right].w);
mDisplayInfo.mEyeResolution.height = std::max(texSize[VRDisplayInfo::Eye_Left].h, texSize[VRDisplayInfo::Eye_Right].h);
UpdateEyeParameters();
UpdateStageParameters();
}
@ -809,6 +814,29 @@ VRDisplayOculus::Destroy()
mSession = nullptr;
}
void
VRDisplayOculus::UpdateEyeParameters(gfx::Matrix4x4* aHeadToEyeTransforms /* = nullptr */)
{
// Note this must be called every frame, as the IPD adjustment can be changed
// by the user during a VR session.
for (uint32_t eye = 0; eye < VRDisplayInfo::NumEyes; eye++) {
// As of Oculus 1.17 SDK, we must use the ovr_GetRenderDesc2 function to return the updated
// version of ovrEyeRenderDesc. This is normally done by the Oculus static lib shim, but we
// need to do this explicitly as we are loading the Oculus runtime dll directly.
ovrEyeRenderDesc renderDesc = ovr_GetRenderDesc2(mSession->Get(), (ovrEyeType)eye, mFOVPort[eye]);
mDisplayInfo.mEyeTranslation[eye].x = renderDesc.HmdToEyePose.Position.x;
mDisplayInfo.mEyeTranslation[eye].y = renderDesc.HmdToEyePose.Position.y;
mDisplayInfo.mEyeTranslation[eye].z = renderDesc.HmdToEyePose.Position.z;
if (aHeadToEyeTransforms) {
Matrix4x4 pose;
pose.SetRotationFromQuaternion(gfx::Quaternion(renderDesc.HmdToEyePose.Orientation.x, renderDesc.HmdToEyePose.Orientation.y, renderDesc.HmdToEyePose.Orientation.z, renderDesc.HmdToEyePose.Orientation.w));
pose.PreTranslate(renderDesc.HmdToEyePose.Position.x, renderDesc.HmdToEyePose.Position.y, renderDesc.HmdToEyePose.Position.z);
pose.Invert();
aHeadToEyeTransforms[eye] = pose;
}
}
}
void
VRDisplayOculus::UpdateStageParameters()
{
@ -865,6 +893,8 @@ VRDisplayOculus::GetSensorState()
{
VRHMDSensorState result;
if (mSession->IsTrackingReady()) {
gfx::Matrix4x4 headToEyeTransforms[2];
UpdateEyeParameters(headToEyeTransforms);
double predictedFrameTime = 0.0f;
if (gfxPrefs::VRPosePredictionEnabled()) {
// XXX We might need to call ovr_GetPredictedDisplayTime even if we don't use the result.
@ -872,10 +902,11 @@ VRDisplayOculus::GetSensorState()
predictedFrameTime = ovr_GetPredictedDisplayTime(mSession->Get(), 0);
}
result = GetSensorState(predictedFrameTime);
result.position[1] -= mEyeHeight;
result.CalcViewMatrices(headToEyeTransforms);
}
result.inputFrameID = mDisplayInfo.mFrameId;
result.position[1] -= mEyeHeight;
mDisplayInfo.mLastSensorState[result.inputFrameID % kVRMaxLatencyFrames] = result;
return result;
}
@ -906,6 +937,9 @@ VRDisplayOculus::GetSensorState(double absTime)
result.angularAcceleration[0] = pose.AngularAcceleration.x;
result.angularAcceleration[1] = pose.AngularAcceleration.y;
result.angularAcceleration[2] = pose.AngularAcceleration.z;
} else {
// default to an identity quaternion
result.orientation[3] = 1.0f;
}
if (state.StatusFlags & ovrStatus_PositionTracked) {
@ -1172,27 +1206,25 @@ VRDisplayOculus::SubmitFrame(ID3D11Texture2D* aSource,
layer.Viewport[1].Size.w = aSize.width * aRightEyeRect.Width();
layer.Viewport[1].Size.h = aSize.height * aRightEyeRect.Height();
const Point3D& l = mDisplayInfo.mEyeTranslation[0];
const Point3D& r = mDisplayInfo.mEyeTranslation[1];
const ovrVector3f hmdToEyeViewOffset[2] = { { l.x, l.y, l.z },
{ r.x, r.y, r.z } };
const VRHMDSensorState& sensorState = mDisplayInfo.GetSensorState();
gfx::Matrix4x4 matView[2];
memcpy(matView[0].components, sensorState.leftViewMatrix, sizeof(sensorState.leftViewMatrix));
memcpy(matView[1].components, sensorState.rightViewMatrix, sizeof(sensorState.rightViewMatrix));
for (uint32_t i = 0; i < 2; ++i) {
Quaternion o(sensorState.orientation[0],
sensorState.orientation[1],
sensorState.orientation[2],
sensorState.orientation[3]);
Point3D vo(hmdToEyeViewOffset[i].x, hmdToEyeViewOffset[i].y, hmdToEyeViewOffset[i].z);
Point3D p = o.RotatePoint(vo);
layer.RenderPose[i].Orientation.x = o.x;
layer.RenderPose[i].Orientation.y = o.y;
layer.RenderPose[i].Orientation.z = o.z;
layer.RenderPose[i].Orientation.w = o.w;
layer.RenderPose[i].Position.x = p.x + sensorState.position[0];
layer.RenderPose[i].Position.y = p.y + sensorState.position[1];
layer.RenderPose[i].Position.z = p.z + sensorState.position[2];
Point3D eyeTranslation;
Quaternion eyeRotation;
Point3D eyeScale;
if (!matView[i].Decompose(eyeTranslation, eyeRotation, eyeScale)) {
NS_WARNING("Failed to decompose eye pose matrix for Oculus");
}
layer.RenderPose[i].Orientation.x = eyeRotation.x;
layer.RenderPose[i].Orientation.y = eyeRotation.y;
layer.RenderPose[i].Orientation.z = eyeRotation.z;
layer.RenderPose[i].Orientation.w = eyeRotation.w;
layer.RenderPose[i].Position.x = eyeTranslation.x;
layer.RenderPose[i].Position.y = eyeTranslation.y;
layer.RenderPose[i].Position.z = eyeTranslation.z;
}
ovrLayerHeader *layers = &layer.Header;

Просмотреть файл

@ -123,6 +123,7 @@ protected:
float mEyeHeight;
bool UpdateConstantBuffers();
void UpdateEyeParameters(gfx::Matrix4x4* aHeadToEyeTransforms = nullptr);
struct Vertex
{

Просмотреть файл

@ -87,14 +87,8 @@ VRDisplayOpenVR::VRDisplayOpenVR(::vr::IVRSystem *aVRSystem,
float l, r, t, b;
mVRSystem->GetProjectionRaw(static_cast<::vr::Hmd_Eye>(eye), &l, &r, &t, &b);
mDisplayInfo.mEyeFOV[eye].SetFromTanRadians(-t, r, b, -l);
::vr::HmdMatrix34_t eyeToHead = mVRSystem->GetEyeToHeadTransform(static_cast<::vr::Hmd_Eye>(eye));
mDisplayInfo.mEyeTranslation[eye].x = eyeToHead.m[0][3];
mDisplayInfo.mEyeTranslation[eye].y = eyeToHead.m[1][3];
mDisplayInfo.mEyeTranslation[eye].z = eyeToHead.m[2][3];
}
UpdateEyeParameters();
UpdateStageParameters();
}
@ -111,6 +105,31 @@ VRDisplayOpenVR::Destroy()
::vr::VR_Shutdown();
}
void
VRDisplayOpenVR::UpdateEyeParameters(gfx::Matrix4x4* aHeadToEyeTransforms /* = nullptr */)
{
// Note this must be called every frame, as the IPD adjustment can be changed
// by the user during a VR session.
for (uint32_t eye = 0; eye < VRDisplayInfo::NumEyes; eye++) {
::vr::HmdMatrix34_t eyeToHead = mVRSystem->GetEyeToHeadTransform(static_cast<::vr::Hmd_Eye>(eye));
mDisplayInfo.mEyeTranslation[eye].x = eyeToHead.m[0][3];
mDisplayInfo.mEyeTranslation[eye].y = eyeToHead.m[1][3];
mDisplayInfo.mEyeTranslation[eye].z = eyeToHead.m[2][3];
if (aHeadToEyeTransforms) {
Matrix4x4 pose;
// NOTE! eyeToHead.m is a 3x4 matrix, not 4x4. But
// because of its arrangement, we can copy the 12 elements in and
// then transpose them to the right place.
memcpy(&pose._11, &eyeToHead.m, sizeof(eyeToHead.m));
pose.Transpose();
pose.Invert();
aHeadToEyeTransforms[eye] = pose;
}
}
}
void
VRDisplayOpenVR::UpdateStageParameters()
{
@ -231,6 +250,8 @@ VRDisplayOpenVR::GetSensorState()
::vr::TrackedDevicePose_t poses[posesSize];
// Note: We *must* call WaitGetPoses in order for any rendering to happen at all.
mVRCompositor->WaitGetPoses(nullptr, 0, poses, posesSize);
gfx::Matrix4x4 headToEyeTransforms[2];
UpdateEyeParameters(headToEyeTransforms);
VRHMDSensorState result;
@ -254,7 +275,7 @@ VRDisplayOpenVR::GetSensorState()
// because of its arrangement, we can copy the 12 elements in and
// then transpose them to the right place. We do this so we can
// pull out a Quaternion.
memcpy(&m._11, &pose.mDeviceToAbsoluteTracking, sizeof(float) * 12);
memcpy(&m._11, &pose.mDeviceToAbsoluteTracking, sizeof(pose.mDeviceToAbsoluteTracking));
m.Transpose();
gfx::Quaternion rot;
@ -277,8 +298,12 @@ VRDisplayOpenVR::GetSensorState()
result.linearVelocity[0] = pose.vVelocity.v[0];
result.linearVelocity[1] = pose.vVelocity.v[1];
result.linearVelocity[2] = pose.vVelocity.v[2];
} else {
// default to an identity quaternion
result.orientation[3] = 1.0f;
}
result.CalcViewMatrices(headToEyeTransforms);
result.inputFrameID = mDisplayInfo.mFrameId;
return result;
}
@ -816,7 +841,7 @@ VRSystemManagerOpenVR::HandleInput()
// because of its arrangement, we can copy the 12 elements in and
// then transpose them to the right place. We do this so we can
// pull out a Quaternion.
memcpy(&m.components, &pose.mDeviceToAbsoluteTracking, sizeof(float) * 12);
memcpy(&m.components, &pose.mDeviceToAbsoluteTracking, sizeof(pose.mDeviceToAbsoluteTracking));
m.Transpose();
gfx::Quaternion rot;

Просмотреть файл

@ -69,6 +69,7 @@ protected:
bool mIsHmdPresent;
void UpdateStageParameters();
void UpdateEyeParameters(gfx::Matrix4x4* aHeadToEyeTransforms = nullptr);
void PollEvents();
bool SubmitFrame(void* aTextureHandle,
::vr::ETextureType aTextureType,

Просмотреть файл

@ -150,6 +150,13 @@ VRHMDSensorState
VRDisplayPuppet::GetSensorState()
{
mSensorState.inputFrameID = mDisplayInfo.mFrameId;
Matrix4x4 matHeadToEye[2];
for (uint32_t eye = 0; eye < 2; ++eye) {
matHeadToEye[eye].PreTranslate(mDisplayInfo.mEyeTranslation[eye]);
}
mSensorState.CalcViewMatrices(matHeadToEye);
return mSensorState;
}

Просмотреть файл

@ -115,6 +115,12 @@ struct ParamTraits<mozilla::gfx::VRHMDSensorState>
WriteParam(aMsg, aParam.linearAcceleration[0]);
WriteParam(aMsg, aParam.linearAcceleration[1]);
WriteParam(aMsg, aParam.linearAcceleration[2]);
for (int i=0; i < 16; i++) {
WriteParam(aMsg, aParam.leftViewMatrix[i]);
}
for (int i=0; i < 16; i++) {
WriteParam(aMsg, aParam.rightViewMatrix[i]);
}
}
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
@ -143,6 +149,16 @@ struct ParamTraits<mozilla::gfx::VRHMDSensorState>
!ReadParam(aMsg, aIter, &(aResult->linearAcceleration[2]))) {
return false;
}
for (int i=0; i < 16; i++) {
if (!ReadParam(aMsg, aIter, &(aResult->leftViewMatrix[i]))) {
return false;
}
}
for (int i=0; i < 16; i++) {
if (!ReadParam(aMsg, aIter, &(aResult->rightViewMatrix[i]))) {
return false;
}
}
return true;
}
};

Просмотреть файл

@ -126,6 +126,12 @@ typedef enum
ovrTrackingCap_EnumSize = 0x7fffffff
} ovrTrackingCaps;
typedef enum {
ovrExtension_TextureLayout_Octilinear = 0,
ovrExtension_Count,
ovrExtension_EnumSize = 0x7fffffff
} ovrExtensions;
typedef enum {
ovrEye_Left = 0,
ovrEye_Right = 1,
@ -211,7 +217,7 @@ typedef struct OVR_ALIGNAS(4) {
ovrFovPort Fov;
ovrRecti DistortedViewport;
ovrVector2f PixelsPerTanAngleAtCenter;
ovrVector3f HmdToEyeOffset;
ovrPosef HmdToEyePose;
} ovrEyeRenderDesc;
typedef struct OVR_ALIGNAS(4) {
@ -221,7 +227,7 @@ typedef struct OVR_ALIGNAS(4) {
} ovrTimewarpProjectionDesc;
typedef struct OVR_ALIGNAS(4) {
ovrVector3f HmdToEyeOffset[ovrEye_Count];
ovrPosef HmdToEyePose[ovrEye_Count];
float HmdSpaceToWorldScaleInMeters;
} ovrViewScaleDesc;
@ -277,6 +283,7 @@ typedef enum {
ovrTextureMisc_DX_Typeless = 0x0001,
ovrTextureMisc_AllowGenerateMips = 0x0002,
ovrTextureMisc_ProtectedContent = 0x0004,
ovrTextureMisc_AutoGenerateMips = 0x0008,
ovrTextureMisc_EnumSize = 0x7fffffff
} ovrTextureFlags;
@ -378,6 +385,8 @@ typedef enum {
ovrHapticsBufferSubmit_Enqueue
} ovrHapticsBufferSubmitMode;
#define OVR_HAPTICS_BUFFER_SAMPLES_MAX 256
typedef struct {
const void* Samples;
int SamplesCount;
@ -483,6 +492,7 @@ typedef enum {
ovrInit_RequestVersion = 0x00000004,
ovrInit_Invisible = 0x00000010,
ovrInit_MixedRendering = 0x00000020,
ovrInit_FocusAware = 0x00000040,
ovrinit_WritableBits = 0x00ffffff,
ovrInit_EnumSize = 0x7fffffff
} ovrInitFlags;
@ -530,9 +540,15 @@ typedef struct {
ovrBool DisplayLost;
ovrBool ShouldQuit;
ovrBool ShouldRecenter;
ovrBool HasInputFocus;
ovrBool OverlayPresent;
} ovrSessionStatus;
typedef ovrResult (OVR_PFN* pfn_ovr_GetSessionStatus)(ovrSession session, ovrSessionStatus* sessionStatus);
typedef ovrResult (OVR_PFN* pfn_ovr_IsExtensionSupported)(ovrSession session,
ovrExtensions extension,
ovrBool* outExtensionSupported);
typedef ovrResult (OVR_PFN* pfn_ovr_EnableExtension)(ovrSession session, ovrExtensions extension);
typedef ovrResult (OVR_PFN* pfn_ovr_SetTrackingOriginType)(ovrSession session, ovrTrackingOrigin origin);
typedef ovrTrackingOrigin (OVR_PFN* pfn_ovr_GetTrackingOriginType)(ovrSession session);
typedef ovrResult (OVR_PFN* pfn_ovr_RecenterTrackingOrigin)(ovrSession session);
@ -584,6 +600,8 @@ typedef enum {
ovrLayerType_EyeFov = 1,
ovrLayerType_Quad = 3,
ovrLayerType_EyeMatrix = 5,
ovrLayerType_EyeFovMultires = 7,
ovrLayerType_Cube = 10,
ovrLayerType_EnumSize = 0x7fffffff
} ovrLayerType;
@ -607,6 +625,39 @@ typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) {
double SensorSampleTime;
} ovrLayerEyeFov;
typedef enum {
ovrTextureLayout_Rectilinear = 0,
ovrTextureLayout_Octilinear = 1,
ovrTextureLayout_EnumSize = 0x7fffffff
} ovrTextureLayout;
typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) {
float WarpLeft;
float WarpRight;
float WarpUp;
float WarpDown;
float SizeLeft;
float SizeRight;
float SizeUp;
float SizeDown;
} ovrTextureLayoutOctilinear;
typedef union OVR_ALIGNAS(OVR_PTR_SIZE) {
ovrTextureLayoutOctilinear Octilinear[ovrEye_Count];
} ovrTextureLayoutDesc_Union;
typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) {
ovrLayerHeader Header;
ovrTextureSwapChain ColorTexture[ovrEye_Count];
ovrRecti Viewport[ovrEye_Count];
ovrFovPort Fov[ovrEye_Count];
ovrPosef RenderPose[ovrEye_Count];
double SensorSampleTime;
ovrTextureLayout TextureLayout;
ovrTextureLayoutDesc_Union TextureLayoutDesc;
} ovrLayerEyeFovMultires;
typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) {
ovrLayerHeader Header;
ovrTextureSwapChain ColorTexture[ovrEye_Count];
@ -624,10 +675,18 @@ typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) {
ovrVector2f QuadSize;
} ovrLayerQuad;
typedef struct OVR_ALIGNAS(OVR_PTR_SIZE) {
ovrLayerHeader Header;
ovrQuatf Orientation;
ovrTextureSwapChain CubeMapTexture;
} ovrLayerCube;
typedef union {
ovrLayerHeader Header;
ovrLayerEyeFov EyeFov;
ovrLayerQuad Quad;
ovrLayerEyeFovMultires Multires;
ovrLayerCube Cube;
} ovrLayer_Union;
@ -638,7 +697,14 @@ typedef ovrResult (OVR_PFN* pfn_ovr_CommitTextureSwapChain)(ovrSession session,
typedef void (OVR_PFN* pfn_ovr_DestroyTextureSwapChain)(ovrSession session, ovrTextureSwapChain chain);
typedef void (OVR_PFN* pfn_ovr_DestroyMirrorTexture)(ovrSession session, ovrMirrorTexture mirrorTexture);
typedef ovrSizei(OVR_PFN* pfn_ovr_GetFovTextureSize)(ovrSession session, ovrEyeType eye, ovrFovPort fov, float pixelsPerDisplayPixel);
typedef ovrEyeRenderDesc(OVR_PFN* pfn_ovr_GetRenderDesc)(ovrSession session, ovrEyeType eyeType, ovrFovPort fov);
typedef ovrEyeRenderDesc(OVR_PFN* pfn_ovr_GetRenderDesc2)(ovrSession session, ovrEyeType eyeType, ovrFovPort fov);
typedef ovrResult (OVR_PFN* pfn_ovr_WaitToBeginFrame)(ovrSession session, long long frameIndex);
typedef ovrResult (OVR_PFN* pfn_ovr_BeginFrame)(ovrSession session, long long frameIndex);
typedef ovrResult (OVR_PFN* pfn_ovr_EndFrame)(ovrSession session,
long long frameIndex,
const ovrViewScaleDesc* viewScaleDesc,
ovrLayerHeader const* const* layerPtrList,
unsigned int layerCount);
typedef ovrResult(OVR_PFN* pfn_ovr_SubmitFrame)(ovrSession session, long long frameIndex,
const ovrViewScaleDesc* viewScaleDesc,
ovrLayerHeader const * const * layerPtrList, unsigned int layerCount);
@ -753,6 +819,7 @@ typedef enum {
ovrError_InvalidOperation = -1015,
ovrError_InsufficientArraySize = -1016,
ovrError_NoExternalCameraInfo = -1017,
ovrError_LostTracking = -1018,
ovrError_AudioDeviceNotFound = -2001,
ovrError_AudioComError = -2002,
ovrError_Initialize = -3000,

Просмотреть файл

@ -36,6 +36,7 @@
#include "xpcprivate.h"
#include "xpcpublic.h"
#include "nsContentUtils.h"
#include "nsReadableUtils.h"
#include "nsXULAppAPI.h"
#include "GeckoProfiler.h"
#include "WrapperFactory.h"
@ -388,11 +389,29 @@ mozJSComponentLoader::LoadModule(FileLocation& aFile)
jsapi.Init();
JSContext* cx = jsapi.cx();
bool isCriticalModule = StringEndsWith(spec, NS_LITERAL_CSTRING("/nsAsyncShutdown.js"));
nsAutoPtr<ModuleEntry> entry(new ModuleEntry(RootingContext::get(cx)));
RootedValue dummy(cx);
RootedValue exn(cx);
rv = ObjectForLocation(info, file, &entry->obj, &entry->thisObjectKey,
&entry->location, false, &dummy);
&entry->location, isCriticalModule, &exn);
if (NS_FAILED(rv)) {
// Temporary debugging assertion for bug 1403348:
if (isCriticalModule && !exn.isUndefined()) {
JSAutoCompartment ac(cx, xpc::PrivilegedJunkScope());
JS_WrapValue(cx, &exn);
nsAutoCString file;
uint32_t line;
uint32_t column;
nsAutoString msg;
nsContentUtils::ExtractErrorValues(cx, exn, file, &line, &column, msg);
NS_ConvertUTF16toUTF8 cMsg(msg);
MOZ_CRASH_UNSAFE_PRINTF("Failed to load module \"%s\": "
"[\"%s\" {file: \"%s\", line: %u}]",
spec.get(), cMsg.get(), file.get(), line);
}
return nullptr;
}

Просмотреть файл

@ -449,11 +449,13 @@ static_assert(!(nsChangeHint_Hints_AlwaysHandledForDescendants &
#define NS_STYLE_HINT_REFLOW \
nsChangeHint(NS_STYLE_HINT_VISUAL | nsChangeHint_AllReflowHints)
#define nsChangeHint_Hints_CanIgnoreIfNotVisible \
nsChangeHint(NS_STYLE_HINT_VISUAL | \
nsChangeHint_NeutralChange | \
nsChangeHint_UpdateOpacityLayer | \
nsChangeHint_UpdateTransformLayer | \
#define nsChangeHint_Hints_CanIgnoreIfNotVisible \
nsChangeHint(NS_STYLE_HINT_VISUAL | \
nsChangeHint_NeutralChange | \
nsChangeHint_UpdateOpacityLayer | \
nsChangeHint_AddOrRemoveTransform | \
nsChangeHint_UpdatePostTransformOverflow | \
nsChangeHint_UpdateTransformLayer | \
nsChangeHint_UpdateUsesOpacity)
// NB: Once we drop support for the old style system, this logic should be

Просмотреть файл

@ -684,10 +684,6 @@ AddAnimationsForProperty(nsIFrame* aFrame, nsDisplayListBuilder* aBuilder,
CSS_PROPERTY_CAN_ANIMATE_ON_COMPOSITOR),
"inconsistent property flags");
EffectSet* effects = EffectSet::GetEffectSet(aFrame);
MOZ_ASSERT(effects);
bool sentAnimations = false;
// Add from first to last (since last overrides)
for (size_t animIdx = 0; animIdx < compositorAnimations.Length(); animIdx++) {
dom::Animation* anim = compositorAnimations[animIdx];
@ -711,7 +707,7 @@ AddAnimationsForProperty(nsIFrame* aFrame, nsDisplayListBuilder* aBuilder,
// !important rules, we don't want to send them to the compositor.
MOZ_ASSERT(anim->CascadeLevel() !=
EffectCompositor::CascadeLevel::Animations ||
!effects->PropertiesWithImportantRules()
!EffectSet::GetEffectSet(aFrame)->PropertiesWithImportantRules()
.HasProperty(aProperty),
"GetEffectiveAnimationOfProperty already tested the property "
"is not overridden by !important rules");
@ -734,12 +730,6 @@ AddAnimationsForProperty(nsIFrame* aFrame, nsDisplayListBuilder* aBuilder,
AddAnimationForProperty(aFrame, *property, anim, aAnimationInfo, data, aPending);
keyframeEffect->SetIsRunningOnCompositor(aProperty, true);
sentAnimations = true;
}
if (sentAnimations && aProperty == eCSSProperty_transform) {
TimeStamp now = aFrame->PresContext()->RefreshDriver()->MostRecentRefresh();
effects->UpdateLastTransformSyncTime(now);
}
}

Просмотреть файл

@ -41,6 +41,40 @@ using namespace mozilla;
using namespace mozilla::gfx;
using namespace mozilla::image;
class nsDisplayTableCellSelection final : public nsDisplayItem {
public:
nsDisplayTableCellSelection(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame)
: nsDisplayItem(aBuilder, aFrame)
{
MOZ_COUNT_CTOR(nsDisplayTableCellSelection);
}
#ifdef NS_BUILD_REFCNT_LOGGING
virtual ~nsDisplayTableCellSelection() {
MOZ_COUNT_DTOR(nsDisplayTableCellSelection);
}
#endif
void Paint(nsDisplayListBuilder* aBuilder, gfxContext* aCtx) override
{
static_cast<nsTableCellFrame*>(mFrame)->DecorateForSelection(aCtx->GetDrawTarget(), ToReferenceFrame());
}
NS_DISPLAY_DECL_NAME("TableCellSelection", TYPE_TABLE_CELL_SELECTION)
bool CreateWebRenderCommands(mozilla::wr::DisplayListBuilder& aBuilder,
mozilla::wr::IpcResourceUpdateQueue& aResources,
const StackingContextHelper& aSc,
mozilla::layers::WebRenderLayerManager* aManager,
nsDisplayListBuilder* aDisplayListBuilder) override
{
RefPtr<nsFrameSelection> frameSelection = mFrame->PresContext()->PresShell()->FrameSelection();
if (frameSelection->GetTableCellSelection()) {
return false;
}
return true;
}
};
nsTableCellFrame::nsTableCellFrame(nsStyleContext* aContext,
nsTableFrame* aTableFrame,
ClassID aID)
@ -423,14 +457,6 @@ void nsTableCellFrame::InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDi
GetParent()->InvalidateFrameWithRect(aRect + GetPosition(), aDisplayItemKey);
}
static void
PaintTableCellSelection(nsIFrame* aFrame, DrawTarget* aDrawTarget,
const nsRect& aRect, nsPoint aPt)
{
static_cast<nsTableCellFrame*>(aFrame)->DecorateForSelection(aDrawTarget,
aPt);
}
bool
nsTableCellFrame::ShouldPaintBordersAndBackgrounds() const
{
@ -493,9 +519,7 @@ nsTableCellFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder,
// and display the selection border if we need to
if (IsSelected()) {
aLists.BorderBackground()->AppendNewToTop(new (aBuilder)
nsDisplayGeneric(aBuilder, this, ::PaintTableCellSelection,
"TableCellSelection",
DisplayItemType::TYPE_TABLE_CELL_SELECTION));
nsDisplayTableCellSelection(aBuilder, this));
}
}

Просмотреть файл

@ -223,36 +223,6 @@ public:
return mozilla::BigEndian::readUint32(ptr);
}
int32_t Peek32() const
{
auto ptr = Peek(4);
if (!ptr) {
NS_WARNING("Failed to peek data");
return 0;
}
return mozilla::BigEndian::readInt32(ptr);
}
uint64_t PeekU64() const
{
auto ptr = Peek(8);
if (!ptr) {
NS_WARNING("Failed to peek data");
return 0;
}
return mozilla::BigEndian::readUint64(ptr);
}
int64_t Peek64() const
{
auto ptr = Peek(8);
if (!ptr) {
NS_WARNING("Failed to peek data");
return 0;
}
return mozilla::BigEndian::readInt64(ptr);
}
const uint8_t* Peek(size_t aCount) const
{
if (aCount > mRemaining) {

Просмотреть файл

@ -1,346 +0,0 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef BYTE_READER_H_
#define BYTE_READER_H_
#include "mozilla/EndianUtils.h"
#include "nsTArray.h"
#include "MediaData.h"
namespace mp4_demuxer {
class MOZ_RAII ByteReader
{
public:
ByteReader() : mPtr(nullptr), mRemaining(0) {}
ByteReader(const uint8_t* aData, size_t aSize)
: mPtr(aData), mRemaining(aSize), mLength(aSize)
{
}
template<size_t S>
explicit ByteReader(const AutoTArray<uint8_t, S>& aData)
: mPtr(aData.Elements()), mRemaining(aData.Length()), mLength(aData.Length())
{
}
explicit ByteReader(const nsTArray<uint8_t>& aData)
: mPtr(aData.Elements()), mRemaining(aData.Length()), mLength(aData.Length())
{
}
explicit ByteReader(const mozilla::MediaByteBuffer* aData)
: mPtr(aData->Elements()), mRemaining(aData->Length()), mLength(aData->Length())
{
}
void SetData(const nsTArray<uint8_t>& aData)
{
MOZ_ASSERT(!mPtr && !mRemaining);
mPtr = aData.Elements();
mRemaining = aData.Length();
mLength = mRemaining;
}
~ByteReader()
{
}
size_t Offset() const
{
return mLength - mRemaining;
}
size_t Remaining() const { return mRemaining; }
bool CanRead8() const { return mRemaining >= 1; }
uint8_t ReadU8()
{
auto ptr = Read(1);
if (!ptr) {
NS_WARNING("Failed to read data");
return 0;
}
return *ptr;
}
bool CanRead16() { return mRemaining >= 2; }
uint16_t ReadU16()
{
auto ptr = Read(2);
if (!ptr) {
NS_WARNING("Failed to read data");
return 0;
}
return mozilla::BigEndian::readUint16(ptr);
}
int16_t ReadLE16()
{
auto ptr = Read(2);
if (!ptr) {
NS_WARNING("Failed to read data");
return 0;
}
return mozilla::LittleEndian::readInt16(ptr);
}
uint32_t ReadU24()
{
auto ptr = Read(3);
if (!ptr) {
NS_WARNING("Failed to read data");
return 0;
}
return ptr[0] << 16 | ptr[1] << 8 | ptr[2];
}
uint32_t Read24()
{
return (uint32_t)ReadU24();
}
int32_t ReadLE24()
{
auto ptr = Read(3);
if (!ptr) {
NS_WARNING("Failed to read data");
return 0;
}
int32_t result = int32_t(ptr[2] << 16 | ptr[1] << 8 | ptr[0]);
if (result & 0x00800000u) {
result -= 0x1000000;
}
return result;
}
bool CanRead32() { return mRemaining >= 4; }
uint32_t ReadU32()
{
auto ptr = Read(4);
if (!ptr) {
NS_WARNING("Failed to read data");
return 0;
}
return mozilla::BigEndian::readUint32(ptr);
}
int32_t Read32()
{
auto ptr = Read(4);
if (!ptr) {
NS_WARNING("Failed to read data");
return 0;
}
return mozilla::BigEndian::readInt32(ptr);
}
uint64_t ReadU64()
{
auto ptr = Read(8);
if (!ptr) {
NS_WARNING("Failed to read data");
return 0;
}
return mozilla::BigEndian::readUint64(ptr);
}
int64_t Read64()
{
auto ptr = Read(8);
if (!ptr) {
NS_WARNING("Failed to read data");
return 0;
}
return mozilla::BigEndian::readInt64(ptr);
}
const uint8_t* Read(size_t aCount)
{
if (aCount > mRemaining) {
mRemaining = 0;
return nullptr;
}
mRemaining -= aCount;
const uint8_t* result = mPtr;
mPtr += aCount;
return result;
}
const uint8_t* Rewind(size_t aCount)
{
MOZ_ASSERT(aCount <= Offset());
size_t rewind = Offset();
if (aCount < rewind) {
rewind = aCount;
}
mRemaining += rewind;
mPtr -= rewind;
return mPtr;
}
uint8_t PeekU8() const
{
auto ptr = Peek(1);
if (!ptr) {
NS_WARNING("Failed to peek data");
return 0;
}
return *ptr;
}
uint16_t PeekU16() const
{
auto ptr = Peek(2);
if (!ptr) {
NS_WARNING("Failed to peek data");
return 0;
}
return mozilla::BigEndian::readUint16(ptr);
}
uint32_t PeekU24() const
{
auto ptr = Peek(3);
if (!ptr) {
NS_WARNING("Failed to peek data");
return 0;
}
return ptr[0] << 16 | ptr[1] << 8 | ptr[2];
}
uint32_t Peek24() const
{
return (uint32_t)PeekU24();
}
uint32_t PeekU32() const
{
auto ptr = Peek(4);
if (!ptr) {
NS_WARNING("Failed to peek data");
return 0;
}
return mozilla::BigEndian::readUint32(ptr);
}
int32_t Peek32() const
{
auto ptr = Peek(4);
if (!ptr) {
NS_WARNING("Failed to peek data");
return 0;
}
return mozilla::BigEndian::readInt32(ptr);
}
uint64_t PeekU64() const
{
auto ptr = Peek(8);
if (!ptr) {
NS_WARNING("Failed to peek data");
return 0;
}
return mozilla::BigEndian::readUint64(ptr);
}
int64_t Peek64() const
{
auto ptr = Peek(8);
if (!ptr) {
NS_WARNING("Failed to peek data");
return 0;
}
return mozilla::BigEndian::readInt64(ptr);
}
const uint8_t* Peek(size_t aCount) const
{
if (aCount > mRemaining) {
return nullptr;
}
return mPtr;
}
const uint8_t* Seek(size_t aOffset)
{
if (aOffset >= mLength) {
NS_WARNING("Seek failed");
return nullptr;
}
mPtr = mPtr - Offset() + aOffset;
mRemaining = mLength - aOffset;
return mPtr;
}
const uint8_t* Reset()
{
mPtr -= Offset();
mRemaining = mLength;
return mPtr;
}
uint32_t Align() const
{
return 4 - ((intptr_t)mPtr & 3);
}
template <typename T> bool CanReadType() const { return mRemaining >= sizeof(T); }
template <typename T> T ReadType()
{
auto ptr = Read(sizeof(T));
if (!ptr) {
NS_WARNING("ReadType failed");
return 0;
}
return *reinterpret_cast<const T*>(ptr);
}
template <typename T>
MOZ_MUST_USE bool ReadArray(nsTArray<T>& aDest, size_t aLength)
{
auto ptr = Read(aLength * sizeof(T));
if (!ptr) {
NS_WARNING("ReadArray failed");
return false;
}
aDest.Clear();
aDest.AppendElements(reinterpret_cast<const T*>(ptr), aLength);
return true;
}
template <typename T>
MOZ_MUST_USE bool ReadArray(FallibleTArray<T>& aDest, size_t aLength)
{
auto ptr = Read(aLength * sizeof(T));
if (!ptr) {
NS_WARNING("ReadArray failed");
return false;
}
aDest.Clear();
if (!aDest.SetCapacity(aLength, mozilla::fallible)) {
return false;
}
MOZ_ALWAYS_TRUE(aDest.AppendElements(reinterpret_cast<const T*>(ptr),
aLength,
mozilla::fallible));
return true;
}
private:
const uint8_t* mPtr;
size_t mRemaining;
size_t mLength;
};
} // namespace mp4_demuxer
#endif

Просмотреть файл

@ -61,7 +61,6 @@ EXPORTS.mp4_demuxer += [
'binding/include/mp4_demuxer/BitReader.h',
'binding/include/mp4_demuxer/BufferReader.h',
'binding/include/mp4_demuxer/BufferStream.h',
'binding/include/mp4_demuxer/ByteReader.h',
'binding/include/mp4_demuxer/ByteWriter.h',
'binding/include/mp4_demuxer/DecoderData.h',
'binding/include/mp4_demuxer/H264.h',

Просмотреть файл

@ -1467,12 +1467,12 @@ nsNSSCertList::SegmentCertificateChain(/* out */ nsCOMPtr<nsIX509Cert>& aRoot,
nsresult rv = ForEachCertificateInChain(
[&aRoot, &aIntermediates, &aEndEntity] (nsCOMPtr<nsIX509Cert> aCert,
bool hasMore, bool& aContinue) {
if (!aRoot) {
// This is the root
aRoot = aCert;
} else if (!hasMore) {
if (!aEndEntity) {
// This is the end entity
aEndEntity = aCert;
} else if (!hasMore) {
// This is the root
aRoot = aCert;
} else {
// One of (potentially many) intermediates
if (NS_FAILED(aIntermediates->AddCert(aCert))) {

Просмотреть файл

@ -100,7 +100,7 @@ public:
// Split a certificate chain into the root, intermediates (if any), and end
// entity. This method does so blindly, assuming that the current list object
// is ordered [root, intermediates..., end entity]. If that isn't true, this
// is ordered [end entity, intermediates..., root]. If that isn't true, this
// method will return the certificates at the two ends without regard to the
// actual chain of trust. Callers are encouraged to check, if there's any
// doubt.

Просмотреть файл

@ -189,9 +189,9 @@ TEST_F(psm_CertList, TestValidSegmenting)
{
RefPtr<nsNSSCertList> certList = new nsNSSCertList();
nsresult rv = AddCertFromStringToList(kCaPem, certList);
nsresult rv = AddCertFromStringToList(kEePem, certList);
ASSERT_EQ(rv, NS_OK) << "Should have loaded OK";
rv = AddCertFromStringToList(kCaIntermediatePem, certList);
rv = AddCertFromStringToList(kCaSecondIntermediatePem, certList);
ASSERT_EQ(rv, NS_OK) << "Should have loaded OK";
nsCOMPtr<nsIX509Cert> rootCert;
@ -206,13 +206,13 @@ TEST_F(psm_CertList, TestValidSegmenting)
bool selfSigned;
ASSERT_TRUE(NS_SUCCEEDED(rootCert->GetIsSelfSigned(&selfSigned))) << "Getters should work.";
ASSERT_TRUE(selfSigned) << "Roots are self signed.";
ASSERT_FALSE(selfSigned) << "Roots are self signed, but this was ca-second-intermediate";
nsAutoString rootCn;
ASSERT_TRUE(NS_SUCCEEDED(rootCert->GetCommonName(rootCn))) << "Getters should work.";
ASSERT_TRUE(rootCn.EqualsLiteral("ca")) << "Root CN should match";
ASSERT_TRUE(rootCn.EqualsLiteral("ca-second-intermediate")) << "Second Intermediate CN should match";
rv = AddCertFromStringToList(kCaSecondIntermediatePem, certList);
rv = AddCertFromStringToList(kCaIntermediatePem, certList);
ASSERT_EQ(rv, NS_OK) << "Should have loaded OK";
intCerts = nullptr;
@ -225,7 +225,7 @@ TEST_F(psm_CertList, TestValidSegmenting)
ASSERT_TRUE(eeCert) << "End entity cert should be filled in";
ASSERT_EQ(CountCertsInList(intCerts), 1) << "There should be one intermediate";
rv = AddCertFromStringToList(kEePem, certList);
rv = AddCertFromStringToList(kCaPem, certList);
ASSERT_EQ(rv, NS_OK) << "Should have loaded OK";
intCerts = nullptr;
@ -238,6 +238,9 @@ TEST_F(psm_CertList, TestValidSegmenting)
ASSERT_TRUE(eeCert) << "End entity cert should be filled in";
ASSERT_EQ(CountCertsInList(intCerts), 2) << "There should be two intermediates";
ASSERT_TRUE(NS_SUCCEEDED(rootCert->GetIsSelfSigned(&selfSigned))) << "Getters should work.";
ASSERT_TRUE(selfSigned) << "Roots are self signed";
ASSERT_TRUE(NS_SUCCEEDED(rootCert->GetCommonName(rootCn))) << "Getters should work.";
ASSERT_TRUE(rootCn.EqualsLiteral("ca")) << "Root CN should match";
@ -254,11 +257,11 @@ TEST_F(psm_CertList, TestValidSegmenting)
}
if (aHasMore) {
if (!cn.EqualsLiteral("ca-intermediate")) {
if (!cn.EqualsLiteral("ca-second-intermediate")) {
return NS_ERROR_FAILURE;
}
} else {
if (!cn.EqualsLiteral("ca-second-intermediate")) {
if (!cn.EqualsLiteral("ca-intermediate")) {
return NS_ERROR_FAILURE;
}
}

Просмотреть файл

@ -539,6 +539,40 @@ private:
return ConvertError(socketpair(AF_UNIX, SOCK_SEQPACKET, 0, fds));
}
static intptr_t StatFsTrap(ArgsRef aArgs, void* aux) {
// Warning: the kernel interface is not the C interface. The
// structs are different (<asm/statfs.h> vs. <sys/statfs.h>), and
// the statfs64 version takes an additional size parameter.
auto path = reinterpret_cast<const char*>(aArgs.args[0]);
int fd = open(path, O_RDONLY | O_LARGEFILE);
if (fd < 0) {
return -errno;
}
intptr_t rv;
switch (aArgs.nr) {
case __NR_statfs: {
auto buf = reinterpret_cast<void*>(aArgs.args[1]);
rv = DoSyscall(__NR_fstatfs, fd, buf);
break;
}
#ifdef __NR_statfs64
case __NR_statfs64: {
auto sz = static_cast<size_t>(aArgs.args[1]);
auto buf = reinterpret_cast<void*>(aArgs.args[2]);
rv = DoSyscall(__NR_fstatfs64, fd, sz, buf);
break;
}
#endif
default:
MOZ_ASSERT(false);
rv = -ENOSYS;
}
close(fd);
return rv;
}
public:
explicit ContentSandboxPolicy(SandboxBrokerClient* aBroker,
const std::vector<int>& aSyscallWhitelist)
@ -691,12 +725,13 @@ public:
case __NR_getppid:
return Trap(GetPPidTrap, nullptr);
CASES_FOR_statfs:
return Trap(StatFsTrap, nullptr);
// Filesystem syscalls that need more work to determine who's
// using them, if they need to be, and what we intend to about it.
case __NR_getcwd:
CASES_FOR_statfs:
CASES_FOR_fstatfs:
case __NR_quotactl:
CASES_FOR_fchown:
case __NR_fchmod:
case __NR_flock:
@ -784,7 +819,12 @@ public:
If((flags & ~allowed_flags) == 0, Allow())
.Else(InvalidSyscall()))
.Case(F_DUPFD_CLOEXEC, Allow())
// Pulseaudio uses F_SETLKW.
// Nvidia GL and fontconfig (newer versions) use fcntl file locking.
.Case(F_SETLK, Allow())
#ifdef F_SETLK64
.Case(F_SETLK64, Allow())
#endif
// Pulseaudio uses F_SETLKW, as does fontconfig.
.Case(F_SETLKW, Allow())
#ifdef F_SETLKW64
.Case(F_SETLKW64, Allow())

67
servo/Cargo.lock сгенерированный
Просмотреть файл

@ -1,13 +1,3 @@
[root]
name = "webvr_traits"
version = "0.0.1"
dependencies = [
"ipc-channel 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"rust-webvr-api 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "adler32"
version = "1.0.0"
@ -210,7 +200,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "bluetooth"
version = "0.0.1"
dependencies = [
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bluetooth_traits 0.0.1",
"device 0.0.1 (git+https://github.com/servo/devices)",
"ipc-channel 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -717,7 +707,7 @@ dependencies = [
name = "devtools_traits"
version = "0.0.1"
dependencies = [
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.10.13 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper_serde 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1031,7 +1021,7 @@ dependencies = [
[[package]]
name = "gamma-lut"
version = "0.2.1"
version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1091,7 +1081,7 @@ name = "gfx"
version = "0.0.1"
dependencies = [
"app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1190,7 +1180,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
name = "glutin_app"
version = "0.0.1"
dependencies = [
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"compositing 0.0.1",
"euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)",
"gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1447,7 +1437,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "jemalloc-sys"
version = "0.1.3"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cc 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1456,10 +1446,10 @@ dependencies = [
[[package]]
name = "jemallocator"
version = "0.1.3"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"jemalloc-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"jemalloc-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -1520,7 +1510,7 @@ version = "0.0.1"
dependencies = [
"app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"canvas_traits 0.0.1",
"euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
@ -1932,7 +1922,7 @@ dependencies = [
name = "msg"
version = "0.0.1"
dependencies = [
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"malloc_size_of 0.0.1",
"malloc_size_of_derive 0.0.1",
"nonzero 0.0.1",
@ -2086,7 +2076,7 @@ dependencies = [
name = "nsstring"
version = "0.1.0"
dependencies = [
"bitflags 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -2391,7 +2381,7 @@ dependencies = [
"heartbeats-simple 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"influent 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ipc-channel 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"jemalloc-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"jemalloc-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"profile_traits 0.0.1",
@ -2607,7 +2597,7 @@ dependencies = [
"app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"audio-video-metadata 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"base64 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bluetooth_traits 0.0.1",
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"canvas_traits 0.0.1",
@ -2762,7 +2752,7 @@ dependencies = [
name = "selectors"
version = "0.19.0"
dependencies = [
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2956,8 +2946,9 @@ dependencies = [
name = "servo_allocator"
version = "0.0.1"
dependencies = [
"jemallocator 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"jemallocator 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@ -3161,7 +3152,7 @@ dependencies = [
"arrayvec 0.3.23 (registry+https://github.com/rust-lang/crates.io-index)",
"atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bindgen 0.29.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3244,7 +3235,7 @@ name = "style_traits"
version = "0.0.1"
dependencies = [
"app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"cssparser 0.22.0 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)",
"malloc_size_of 0.0.1",
@ -3624,7 +3615,7 @@ dependencies = [
[[package]]
name = "webrender"
version = "0.53.1"
source = "git+https://github.com/servo/webrender#9110e7498fbe9e9d58c480c6ccae0f1461e3dbfb"
source = "git+https://github.com/servo/webrender#f80760ffc8d073f90c7b2b29ded28a6f8879e63f"
dependencies = [
"app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"bincode 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3637,7 +3628,7 @@ dependencies = [
"euclid 0.15.3 (registry+https://github.com/rust-lang/crates.io-index)",
"freetype 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gamma-lut 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gamma-lut 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3652,7 +3643,7 @@ dependencies = [
[[package]]
name = "webrender_api"
version = "0.53.1"
source = "git+https://github.com/servo/webrender#9110e7498fbe9e9d58c480c6ccae0f1461e3dbfb"
source = "git+https://github.com/servo/webrender#f80760ffc8d073f90c7b2b29ded28a6f8879e63f"
dependencies = [
"app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"bincode 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
@ -3682,6 +3673,16 @@ dependencies = [
"webvr_traits 0.0.1",
]
[[package]]
name = "webvr_traits"
version = "0.0.1"
dependencies = [
"ipc-channel 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"msg 0.0.1",
"rust-webvr-api 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi"
version = "0.2.8"
@ -3880,7 +3881,7 @@ dependencies = [
"checksum futf 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "51f93f3de6ba1794dcd5810b3546d004600a59a98266487c8407bc4b24e398f3"
"checksum futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "55f0008e13fc853f79ea8fc86e931486860d4c4c156cdffb59fa5f7fa833660a"
"checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
"checksum gamma-lut 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dd65074503368cef99b98844012adfed8d7f99ff3e1e6d05e9055232f2d59dc9"
"checksum gamma-lut 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "250cfe9e6ad3057a290c2107a60c1c6c74ac57b5095e46b8a5c0bc5626d72857"
"checksum gaol 0.0.1 (git+https://github.com/servo/gaol)" = "<none>"
"checksum gcc 0.3.47 (registry+https://github.com/rust-lang/crates.io-index)" = "5773372df827453bc38d4fd8efe425c7f28b1f54468816183fc8716cfb90bd30"
"checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518"
@ -3912,8 +3913,8 @@ dependencies = [
"checksum ipc-channel 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c10ed089b1921b01ef342c736a37ee0788eeb9a5f373bb2df1ba88d01125064f"
"checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc"
"checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c"
"checksum jemalloc-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94fb624d7e8345e5c42caab8d1db6ec925fdadff3fd0cb7dd781b41be8442828"
"checksum jemallocator 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1850725977c344d63af66e8fd00857646e3ec936c490cd63667860b7b03ab5c1"
"checksum jemalloc-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "479294d130502fada93c7a957e8d059b632b03d6204aca37af557dee947f30a9"
"checksum jemallocator 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "28b211ca65c440322b6d4d9b5b850b01e8e298393b7ebcb8205b7cbb14ea6329"
"checksum jpeg-decoder 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "2805ccb10ffe4d10e06ef68a158ff94c255211ecbae848fbde2146b098f93ce7"
"checksum js 0.1.6 (git+https://github.com/servo/rust-mozjs)" = "<none>"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"

Просмотреть файл

@ -11,8 +11,11 @@ path = "lib.rs"
[features]
unstable = ["kernel32-sys", "jemallocator"]
[dependencies]
libc = "0.2" # Only used when 'unstable' is disabled, but looks like Cargo cannot express that.
[target.'cfg(not(windows))'.dependencies]
jemallocator = { version = "0.1.3", optional = true }
jemallocator = { version = "0.1.4", optional = true }
[target.'cfg(windows)'.dependencies]
kernel32-sys = { version = "0.2.1", optional = true }

Просмотреть файл

@ -9,9 +9,9 @@
#[cfg(feature = "unstable")]
#[global_allocator]
static ALLOC: platform::Allocator = platform::Allocator;
static ALLOC: Allocator = Allocator;
pub use platform::usable_size;
pub use platform::*;
#[cfg(all(feature = "unstable", not(windows)))]
@ -25,6 +25,11 @@ mod platform {
pub unsafe extern "C" fn usable_size(ptr: *const c_void) -> usize {
jemallocator::usable_size(ptr)
}
/// Memory allocation APIs compatible with libc
pub mod libc_compat {
pub use super::jemallocator::ffi::{malloc, realloc, free};
}
}
#[cfg(all(feature = "unstable", windows))]
@ -57,6 +62,10 @@ mod platform {
pub unsafe extern "C" fn usable_size(_ptr: *const c_void) -> usize {
0
}
/// Memory allocation APIs compatible with libc
pub mod libc_compat {
extern crate libc;
pub use self::libc::{malloc, realloc, free};
}
}

Просмотреть файл

@ -10,7 +10,7 @@ name = "bluetooth"
path = "lib.rs"
[dependencies]
bitflags = "0.7"
bitflags = "1.0"
bluetooth_traits = {path = "../bluetooth_traits"}
device = {git = "https://github.com/servo/devices", features = ["bluetooth-test"]}
ipc-channel = "0.9"

Просмотреть файл

@ -47,16 +47,16 @@ const DIALOG_COLUMN_ID: &'static str = "Id";
const DIALOG_COLUMN_NAME: &'static str = "Name";
bitflags! {
flags Flags: u32 {
const BROADCAST = 0b000000001,
const READ = 0b000000010,
const WRITE_WITHOUT_RESPONSE = 0b000000100,
const WRITE = 0b000001000,
const NOTIFY = 0b000010000,
const INDICATE = 0b000100000,
const AUTHENTICATED_SIGNED_WRITES = 0b001000000,
const RELIABLE_WRITE = 0b010000000,
const WRITABLE_AUXILIARIES = 0b100000000,
struct Flags: u32 {
const BROADCAST = 0b000000001;
const READ = 0b000000010;
const WRITE_WITHOUT_RESPONSE = 0b000000100;
const WRITE = 0b000001000;
const NOTIFY = 0b000010000;
const INDICATE = 0b000100000;
const AUTHENTICATED_SIGNED_WRITES = 0b001000000;
const RELIABLE_WRITE = 0b010000000;
const WRITABLE_AUXILIARIES = 0b100000000;
}
}
@ -507,15 +507,15 @@ impl BluetoothManager {
let flags = characteristic.get_flags().unwrap_or(vec!());
for flag in flags {
match flag.as_ref() {
"broadcast" => props.insert(BROADCAST),
"read" => props.insert(READ),
"write-without-response" => props.insert(WRITE_WITHOUT_RESPONSE),
"write" => props.insert(WRITE),
"notify" => props.insert(NOTIFY),
"indicate" => props.insert(INDICATE),
"authenticated-signed-writes" => props.insert(AUTHENTICATED_SIGNED_WRITES),
"reliable-write" => props.insert(RELIABLE_WRITE),
"writable-auxiliaries" => props.insert(WRITABLE_AUXILIARIES),
"broadcast" => props.insert(Flags::BROADCAST),
"read" => props.insert(Flags::READ),
"write-without-response" => props.insert(Flags::WRITE_WITHOUT_RESPONSE),
"write" => props.insert(Flags::WRITE),
"notify" => props.insert(Flags::NOTIFY),
"indicate" => props.insert(Flags::INDICATE),
"authenticated-signed-writes" => props.insert(Flags::AUTHENTICATED_SIGNED_WRITES),
"reliable-write" => props.insert(Flags::RELIABLE_WRITE),
"writable-auxiliaries" => props.insert(Flags::WRITABLE_AUXILIARIES),
_ => (),
}
}
@ -729,15 +729,15 @@ impl BluetoothManager {
BluetoothCharacteristicMsg {
uuid: uuid,
instance_id: characteristic.get_id(),
broadcast: properties.contains(BROADCAST),
read: properties.contains(READ),
write_without_response: properties.contains(WRITE_WITHOUT_RESPONSE),
write: properties.contains(WRITE),
notify: properties.contains(NOTIFY),
indicate: properties.contains(INDICATE),
authenticated_signed_writes: properties.contains(AUTHENTICATED_SIGNED_WRITES),
reliable_write: properties.contains(RELIABLE_WRITE),
writable_auxiliaries: properties.contains(WRITABLE_AUXILIARIES),
broadcast: properties.contains(Flags::BROADCAST),
read: properties.contains(Flags::READ),
write_without_response: properties.contains(Flags::WRITE_WITHOUT_RESPONSE),
write: properties.contains(Flags::WRITE),
notify: properties.contains(Flags::NOTIFY),
indicate: properties.contains(Flags::INDICATE),
authenticated_signed_writes: properties.contains(Flags::AUTHENTICATED_SIGNED_WRITES),
reliable_write: properties.contains(Flags::RELIABLE_WRITE),
writable_auxiliaries: properties.contains(Flags::WRITABLE_AUXILIARIES),
}
);
}

Просмотреть файл

@ -9,7 +9,7 @@
use actor::{Actor, ActorMessageStatus, ActorRegistry};
use actors::object::ObjectActor;
use devtools_traits::{CONSOLE_API, CachedConsoleMessageTypes, DevtoolScriptControlMsg, PAGE_ERROR};
use devtools_traits::{CachedConsoleMessageTypes, DevtoolScriptControlMsg};
use devtools_traits::CachedConsoleMessage;
use devtools_traits::EvaluateJSReply::{ActorValue, BooleanValue, StringValue};
use devtools_traits::EvaluateJSReply::{NullValue, NumberValue, VoidValue};
@ -107,8 +107,8 @@ impl Actor for ConsoleActor {
let mut message_types = CachedConsoleMessageTypes::empty();
for str_type in str_types {
match str_type {
"PageError" => message_types.insert(PAGE_ERROR),
"ConsoleAPI" => message_types.insert(CONSOLE_API),
"PageError" => message_types.insert(CachedConsoleMessageTypes::PAGE_ERROR),
"ConsoleAPI" => message_types.insert(CachedConsoleMessageTypes::CONSOLE_API),
s => debug!("unrecognized message type requested: \"{}\"", s),
};
};

Просмотреть файл

@ -10,7 +10,7 @@ name = "devtools_traits"
path = "lib.rs"
[dependencies]
bitflags = "0.7"
bitflags = "1.0"
hyper = "0.10"
hyper_serde = "0.7"
ipc-channel = "0.9"

Просмотреть файл

@ -243,9 +243,9 @@ pub struct ConsoleMessage {
bitflags! {
#[derive(Deserialize, Serialize)]
pub flags CachedConsoleMessageTypes: u8 {
const PAGE_ERROR = 1 << 0,
const CONSOLE_API = 1 << 1,
pub struct CachedConsoleMessageTypes: u8 {
const PAGE_ERROR = 1 << 0;
const CONSOLE_API = 1 << 1;
}
}

Просмотреть файл

@ -15,7 +15,7 @@ unstable = ["simd"]
[dependencies]
app_units = "0.5"
bitflags = "0.7"
bitflags = "1.0"
euclid = "0.15"
fnv = "1.0"
fontsan = {git = "https://github.com/servo/fontsan"}

Просмотреть файл

@ -34,7 +34,7 @@ use style_traits::cursor::Cursor;
use text::TextRun;
use text::glyph::ByteIndex;
use webrender_api::{self, ClipId, ColorF, GradientStop, LocalClip, MixBlendMode, ScrollPolicy};
use webrender_api::{ScrollSensitivity, StickyFrameInfo, TransformStyle};
use webrender_api::{ScrollSensitivity, StickyOffsetBounds, TransformStyle};
pub use style::dom::OpaqueNode;
@ -321,10 +321,17 @@ impl fmt::Debug for StackingContext {
}
}
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
pub struct StickyFrameData {
pub margins: SideOffsets2D<Option<f32>>,
pub vertical_offset_bounds: StickyOffsetBounds,
pub horizontal_offset_bounds: StickyOffsetBounds,
}
#[derive(Clone, Debug, Deserialize, MallocSizeOf, Serialize)]
pub enum ClipScrollNodeType {
ScrollFrame(ScrollSensitivity),
StickyFrame(StickyFrameInfo),
StickyFrame(StickyFrameData),
Clip,
}

Просмотреть файл

@ -139,17 +139,17 @@ impl Font {
}
bitflags! {
pub flags ShapingFlags: u8 {
pub struct ShapingFlags: u8 {
#[doc = "Set if the text is entirely whitespace."]
const IS_WHITESPACE_SHAPING_FLAG = 0x01,
const IS_WHITESPACE_SHAPING_FLAG = 0x01;
#[doc = "Set if we are to ignore ligatures."]
const IGNORE_LIGATURES_SHAPING_FLAG = 0x02,
const IGNORE_LIGATURES_SHAPING_FLAG = 0x02;
#[doc = "Set if we are to disable kerning."]
const DISABLE_KERNING_SHAPING_FLAG = 0x04,
const DISABLE_KERNING_SHAPING_FLAG = 0x04;
#[doc = "Text direction is right-to-left."]
const RTL_FLAG = 0x08,
const RTL_FLAG = 0x08;
#[doc = "Set if word-break is set to keep-all."]
const KEEP_ALL_FLAG = 0x10,
const KEEP_ALL_FLAG = 0x10;
}
}
@ -186,8 +186,8 @@ impl Font {
let result = self.shape_cache.borrow_mut().entry(lookup_key).or_insert_with(|| {
let start_time = time::precise_time_ns();
let mut glyphs = GlyphStore::new(text.len(),
options.flags.contains(IS_WHITESPACE_SHAPING_FLAG),
options.flags.contains(RTL_FLAG));
options.flags.contains(ShapingFlags::IS_WHITESPACE_SHAPING_FLAG),
options.flags.contains(ShapingFlags::RTL_FLAG));
if self.can_do_fast_shaping(text, options) {
debug!("shape_text: Using ASCII fast path.");
@ -211,7 +211,7 @@ impl Font {
fn can_do_fast_shaping(&self, text: &str, options: &ShapingOptions) -> bool {
options.script == Script::Latin &&
!options.flags.contains(RTL_FLAG) &&
!options.flags.contains(ShapingFlags::RTL_FLAG) &&
self.handle.can_do_fast_shaping() &&
text.is_ascii()
}

Просмотреть файл

@ -9,8 +9,8 @@ use freetype::freetype::FT_Memory;
use freetype::freetype::FT_MemoryRec_;
use freetype::freetype::FT_New_Library;
use malloc_size_of::{MallocSizeOf, MallocSizeOfOps};
use servo_allocator::libc_compat::{malloc, realloc, free};
use servo_allocator::usable_size;
use std::mem;
use std::os::raw::{c_long, c_void};
use std::ptr;
use std::rc::Rc;
@ -22,64 +22,38 @@ pub struct User {
size: usize,
}
// FreeType doesn't require any particular alignment for allocations.
const FT_ALIGNMENT: usize = 1;
extern fn ft_alloc(mem: FT_Memory, req_size: c_long) -> *mut c_void {
assert!(FT_ALIGNMENT == 1);
let mut vec = Vec::<u8>::with_capacity(req_size as usize);
let ptr = vec.as_mut_ptr() as *mut c_void;
mem::forget(vec);
unsafe {
let actual_size = usable_size(ptr as *const _);
let ptr = malloc(req_size as usize);
let ptr = ptr as *mut c_void; // libc::c_void vs std::os::raw::c_void
let actual_size = usable_size(ptr);
let user = (*mem).user as *mut User;
(*user).size += actual_size;
ptr
}
ptr
}
extern fn ft_free(mem: FT_Memory, ptr: *mut c_void) {
unsafe {
let actual_size = usable_size(ptr as *const _);
let actual_size = usable_size(ptr);
let user = (*mem).user as *mut User;
(*user).size -= actual_size;
assert!(FT_ALIGNMENT == 1);
mem::drop(Vec::<u8>::from_raw_parts(ptr as *mut u8, actual_size, 0))
free(ptr as *mut _);
}
}
extern fn ft_realloc(mem: FT_Memory, _old_size: c_long, new_req_size: c_long,
old_ptr: *mut c_void) -> *mut c_void {
let old_actual_size;
let mut vec;
unsafe {
old_actual_size = usable_size(old_ptr as *const _);
let old_size = old_actual_size as usize;
vec = Vec::<u8>::from_raw_parts(old_ptr as *mut u8, old_size, old_size);
};
let new_req_size = new_req_size as usize;
if new_req_size > old_actual_size {
vec.reserve_exact(new_req_size - old_actual_size)
} else if new_req_size < old_actual_size {
vec.truncate(new_req_size);
vec.shrink_to_fit()
}
let new_ptr = vec.as_mut_ptr() as *mut c_void;
mem::forget(vec);
unsafe {
let new_actual_size = usable_size(new_ptr as *const _);
let old_actual_size = usable_size(old_ptr);
let new_ptr = realloc(old_ptr as *mut _, new_req_size as usize);
let new_ptr = new_ptr as *mut c_void;
let new_actual_size = usable_size(new_ptr);
let user = (*mem).user as *mut User;
(*user).size += new_actual_size;
(*user).size -= old_actual_size;
new_ptr
}
new_ptr
}
// A |*mut User| field in a struct triggers a "use of `#[derive]` with a raw pointer" warning from

Просмотреть файл

@ -6,8 +6,7 @@
use app_units::Au;
use euclid::Point2D;
use font::{DISABLE_KERNING_SHAPING_FLAG, Font, FontTableMethods, FontTableTag};
use font::{IGNORE_LIGATURES_SHAPING_FLAG, KERN, RTL_FLAG, ShapingOptions};
use font::{ShapingFlags, Font, FontTableMethods, FontTableTag, ShapingOptions, KERN};
use harfbuzz::{HB_DIRECTION_LTR, HB_DIRECTION_RTL, HB_MEMORY_MODE_READONLY};
use harfbuzz::{hb_blob_create, hb_face_create_for_tables};
use harfbuzz::{hb_buffer_create, hb_font_destroy};
@ -189,7 +188,7 @@ impl ShaperMethods for Shaper {
fn shape_text(&self, text: &str, options: &ShapingOptions, glyphs: &mut GlyphStore) {
unsafe {
let hb_buffer: *mut hb_buffer_t = hb_buffer_create();
hb_buffer_set_direction(hb_buffer, if options.flags.contains(RTL_FLAG) {
hb_buffer_set_direction(hb_buffer, if options.flags.contains(ShapingFlags::RTL_FLAG) {
HB_DIRECTION_RTL
} else {
HB_DIRECTION_LTR
@ -204,7 +203,7 @@ impl ShaperMethods for Shaper {
text.len() as c_int);
let mut features = Vec::new();
if options.flags.contains(IGNORE_LIGATURES_SHAPING_FLAG) {
if options.flags.contains(ShapingFlags::IGNORE_LIGATURES_SHAPING_FLAG) {
features.push(hb_feature_t {
tag: LIGA,
value: 0,
@ -212,7 +211,7 @@ impl ShaperMethods for Shaper {
end: hb_buffer_get_length(hb_buffer),
})
}
if options.flags.contains(DISABLE_KERNING_SHAPING_FLAG) {
if options.flags.contains(ShapingFlags::DISABLE_KERNING_SHAPING_FLAG) {
features.push(hb_feature_t {
tag: KERN,
value: 0,

Просмотреть файл

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use app_units::Au;
use font::{Font, FontHandleMethods, FontMetrics, IS_WHITESPACE_SHAPING_FLAG, KEEP_ALL_FLAG};
use font::{Font, FontHandleMethods, FontMetrics, ShapingFlags};
use font::{RunMetrics, ShapingOptions};
use platform::font_template::FontTemplateData;
use range::Range;
@ -210,7 +210,7 @@ impl<'a> TextRun {
.take_while(|&(_, c)| char_is_whitespace(c)).last() {
whitespace.start = slice.start + i;
slice.end = whitespace.start;
} else if idx != text.len() && options.flags.contains(KEEP_ALL_FLAG) {
} else if idx != text.len() && options.flags.contains(ShapingFlags::KEEP_ALL_FLAG) {
// If there's no whitespace and word-break is set to
// keep-all, try increasing the slice.
continue;
@ -224,7 +224,7 @@ impl<'a> TextRun {
}
if whitespace.len() > 0 {
let mut options = options.clone();
options.flags.insert(IS_WHITESPACE_SHAPING_FLAG);
options.flags.insert(ShapingFlags::IS_WHITESPACE_SHAPING_FLAG);
glyphs.push(GlyphRun {
glyph_store: font.shape_text(&text[whitespace.clone()], &options),
range: Range::new(ByteIndex(whitespace.start as isize),

Просмотреть файл

@ -12,7 +12,7 @@ path = "lib.rs"
[dependencies]
app_units = "0.5"
atomic_refcell = "0.1"
bitflags = "0.8"
bitflags = "1.0"
canvas_traits = {path = "../canvas_traits"}
euclid = "0.15"
fnv = "1.0"

Просмотреть файл

@ -35,13 +35,9 @@ use display_list_builder::StackingContextCollectionState;
use euclid::{Point2D, Rect, SideOffsets2D, Size2D};
use floats::{ClearType, FloatKind, Floats, PlacementInfo};
use flow::{self, BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ForceNonfloatedFlag};
use flow::{BLOCK_POSITION_IS_STATIC, CLEARS_LEFT, CLEARS_RIGHT};
use flow::{CONTAINS_TEXT_OR_REPLACED_FRAGMENTS, INLINE_POSITION_IS_STATIC};
use flow::{IS_ABSOLUTELY_POSITIONED, FragmentationContext, MARGINS_CANNOT_COLLAPSE};
use flow::{ImmutableFlowUtils, LateAbsolutePositionInfo, OpaqueFlow};
use flow::{ImmutableFlowUtils, LateAbsolutePositionInfo, OpaqueFlow, FragmentationContext, FlowFlags};
use flow_list::FlowList;
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow};
use fragment::{IS_INLINE_FLEX_ITEM, IS_BLOCK_FLEX_ITEM};
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow, FragmentFlags};
use gfx_traits::print_tree::PrintTree;
use incremental::RelayoutMode;
use layout_debug;
@ -57,7 +53,7 @@ use style::computed_values::{position, text_align};
use style::context::SharedStyleContext;
use style::logical_geometry::{LogicalMargin, LogicalPoint, LogicalRect, LogicalSize, WritingMode};
use style::properties::ComputedValues;
use style::servo::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW};
use style::servo::restyle_damage::ServoRestyleDamage;
use style::values::computed::{LengthOrPercentageOrNone, LengthOrPercentage};
use style::values::computed::LengthOrPercentageOrAuto;
use traversal::PreorderFlowTraversal;
@ -455,11 +451,11 @@ impl<'a> PreorderFlowTraversal for AbsoluteAssignBSizesTraversal<'a> {
// This flow might not be an absolutely positioned flow if it is the root of the tree.
let block = flow.as_mut_block();
if !block.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
if !block.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) {
return;
}
if !block.base.restyle_damage.intersects(REFLOW_OUT_OF_FLOW | REFLOW) {
if !block.base.restyle_damage.intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW) {
return
}
@ -513,11 +509,11 @@ pub struct BlockFlow {
}
bitflags! {
flags BlockFlowFlags: u8 {
struct BlockFlowFlags: u8 {
#[doc = "If this is set, then this block flow is the root flow."]
const IS_ROOT = 0b0000_0001,
const IS_ROOT = 0b0000_0001;
#[doc = "If this is set, then this block flow has overflow and it will scroll."]
const HAS_SCROLLING_OVERFLOW = 0b0000_0010,
const HAS_SCROLLING_OVERFLOW = 0b0000_0010;
}
}
@ -551,7 +547,7 @@ impl BlockFlow {
/// This determines the algorithm used to calculate inline-size, block-size, and the
/// relevant margins for this Block.
pub fn block_type(&self) -> BlockType {
if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) {
if self.fragment.is_replaced() {
BlockType::AbsoluteReplaced
} else {
@ -664,7 +660,7 @@ impl BlockFlow {
#[inline]
pub fn containing_block_size(&self, viewport_size: &Size2D<Au>, descendant: OpaqueFlow)
-> LogicalSize<Au> {
debug_assert!(self.base.flags.contains(IS_ABSOLUTELY_POSITIONED));
debug_assert!(self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED));
if self.is_fixed() || self.is_root() {
// Initial containing block is the CB for the root
LogicalSize::from_physical(self.base.writing_mode, *viewport_size)
@ -783,13 +779,13 @@ impl BlockFlow {
let mut break_at = None;
let content_box = self.fragment.content_box();
if self.base.restyle_damage.contains(REFLOW) {
if self.base.restyle_damage.contains(ServoRestyleDamage::REFLOW) {
// Our current border-box position.
let mut cur_b = Au(0);
// Absolute positioning establishes a block formatting context. Don't propagate floats
// in or out. (But do propagate them between kids.)
if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) ||
if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) ||
margins_may_collapse != MarginsMayCollapseFlag::MarginsMayCollapse {
self.base.floats = Floats::new(self.fragment.style.writing_mode);
}
@ -805,7 +801,7 @@ impl BlockFlow {
let can_collapse_block_start_margin_with_kids =
margins_may_collapse == MarginsMayCollapseFlag::MarginsMayCollapse &&
!self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) &&
!self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) &&
self.fragment.border_padding.block_start == Au(0);
margin_collapse_info.initialize_block_start_margin(
&self.fragment,
@ -816,10 +812,10 @@ impl BlockFlow {
let thread_id = self.base.thread_id;
let (mut had_floated_children, mut had_children_with_clearance) = (false, false);
for (child_index, kid) in self.base.child_iter_mut().enumerate() {
if flow::base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED) {
if flow::base(kid).flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) {
// Assume that the *hypothetical box* for an absolute flow starts immediately
// after the margin-end border edge of the previous flow.
if flow::base(kid).flags.contains(BLOCK_POSITION_IS_STATIC) {
if flow::base(kid).flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) {
let previous_bottom_margin = margin_collapse_info.current_float_ceiling();
flow::mut_base(kid).position.start.b = cur_b +
@ -887,8 +883,8 @@ impl BlockFlow {
if !had_children_with_clearance &&
floats.is_present() &&
(flow::base(kid).flags.contains(CLEARS_LEFT) ||
flow::base(kid).flags.contains(CLEARS_RIGHT)) {
(flow::base(kid).flags.contains(FlowFlags::CLEARS_LEFT) ||
flow::base(kid).flags.contains(FlowFlags::CLEARS_RIGHT)) {
had_children_with_clearance = true
}
@ -905,8 +901,8 @@ impl BlockFlow {
}
// Clear past the floats that came in, if necessary.
let clearance = match (flow::base(kid).flags.contains(CLEARS_LEFT),
flow::base(kid).flags.contains(CLEARS_RIGHT)) {
let clearance = match (flow::base(kid).flags.contains(FlowFlags::CLEARS_LEFT),
flow::base(kid).flags.contains(FlowFlags::CLEARS_RIGHT)) {
(false, false) => Au(0),
(true, false) => floats.clearance(ClearType::Left),
(false, true) => floats.clearance(ClearType::Right),
@ -967,7 +963,7 @@ impl BlockFlow {
// Add in our block-end margin and compute our collapsible margins.
let can_collapse_block_end_margin_with_kids =
margins_may_collapse == MarginsMayCollapseFlag::MarginsMayCollapse &&
!self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) &&
!self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) &&
self.fragment.border_padding.block_end == Au(0);
let (collapsible_margins, delta) =
margin_collapse_info.finish_and_compute_collapsible_margins(
@ -982,13 +978,13 @@ impl BlockFlow {
let is_root = self.is_root();
if is_root || self.formatting_context_type() != FormattingContextType::None ||
self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) {
// The content block-size includes all the floats per CSS 2.1 § 10.6.7. The easiest
// way to handle this is to just treat it as clearance.
block_size = block_size + floats.clearance(ClearType::Both);
}
if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) {
// FIXME(#2003, pcwalton): The max is taken here so that you can scroll the page,
// but this is not correct behavior according to CSS 2.1 § 10.5. Instead I think we
// should treat the root element as having `overflow: scroll` and use the layers-
@ -1008,7 +1004,7 @@ impl BlockFlow {
}
if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) {
self.propagate_early_absolute_position_info_to_children();
return None
}
@ -1076,9 +1072,9 @@ impl BlockFlow {
// size has not yet been computed. (See `assign_inline_position_for_formatting_context()`.)
if (self.base.flags.is_float() ||
self.formatting_context_type() == FormattingContextType::None) &&
!self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
self.fragment.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
!self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) {
self.base.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW);
self.fragment.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW);
}
break_at.and_then(|(i, child_remaining)| {
@ -1162,7 +1158,7 @@ impl BlockFlow {
let viewport_size = LogicalSize::from_physical(self.fragment.style.writing_mode,
shared_context.viewport_size());
Some(viewport_size.block)
} else if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) &&
} else if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) &&
self.base.block_container_explicit_block_size.is_none() {
self.base.absolute_cb.explicit_block_containing_size(shared_context)
} else {
@ -1300,7 +1296,7 @@ impl BlockFlow {
self.fragment.margin.block_end = solution.margin_block_end;
self.fragment.border_box.start.b = Au(0);
if !self.base.flags.contains(BLOCK_POSITION_IS_STATIC) {
if !self.base.flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) {
self.base.position.start.b = solution.block_start + self.fragment.margin.block_start
}
@ -1308,8 +1304,8 @@ impl BlockFlow {
self.fragment.border_box.size.block = block_size;
self.base.position.size.block = block_size;
self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
self.fragment.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
self.base.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW);
self.fragment.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW);
}
/// Compute inline size based using the `block_container_inline_size` set by the parent flow.
@ -1358,7 +1354,7 @@ impl BlockFlow {
.map(|x| if x < box_border { Au(0) } else { x - box_border });
if self.is_root() { explicit_content_size = max(parent_container_size, explicit_content_size); }
// Calculate containing block inline size.
let containing_block_size = if flags.contains(IS_ABSOLUTELY_POSITIONED) {
let containing_block_size = if flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) {
self.containing_block_size(&shared_context.viewport_size(), opaque_self).inline
} else {
content_inline_size
@ -1386,12 +1382,12 @@ impl BlockFlow {
// float child does not have `REFLOW` set, we must be careful to avoid touching its
// inline position, as no logic will run afterward to set its true value.
let kid_base = flow::mut_base(kid);
let reflow_damage = if kid_base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
REFLOW_OUT_OF_FLOW
let reflow_damage = if kid_base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) {
ServoRestyleDamage::REFLOW_OUT_OF_FLOW
} else {
REFLOW
ServoRestyleDamage::REFLOW
};
if kid_base.flags.contains(INLINE_POSITION_IS_STATIC) &&
if kid_base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) &&
kid_base.restyle_damage.contains(reflow_damage) {
kid_base.position.start.i =
if kid_mode.is_bidi_ltr() == containing_block_mode.is_bidi_ltr() {
@ -1475,13 +1471,13 @@ impl BlockFlow {
content_box: LogicalRect<Au>) {
debug_assert!(self.formatting_context_type() != FormattingContextType::None);
if !self.base.restyle_damage.intersects(REFLOW_OUT_OF_FLOW | REFLOW) {
if !self.base.restyle_damage.intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW) {
return
}
// We do this first to avoid recomputing our inline size when we propagate it.
self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
self.fragment.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
self.base.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW);
self.fragment.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW);
// The code below would completely wreck the layout if run on a flex item, however:
// * Flex items are always the children of flex containers.
@ -1591,14 +1587,14 @@ impl BlockFlow {
// This is kind of a hack for Acid2. But it's a harmless one, because (a) this behavior
// is unspecified; (b) it matches the behavior one would intuitively expect, since
// floats don't flow around blocks that take up no space in the block direction.
flags.remove(CONTAINS_TEXT_OR_REPLACED_FRAGMENTS);
flags.remove(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS);
} else if self.fragment.is_text_or_replaced() {
flags.insert(CONTAINS_TEXT_OR_REPLACED_FRAGMENTS);
flags.insert(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS);
} else {
flags.remove(CONTAINS_TEXT_OR_REPLACED_FRAGMENTS);
flags.remove(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS);
for kid in self.base.children.iter() {
if flow::base(kid).flags.contains(CONTAINS_TEXT_OR_REPLACED_FRAGMENTS) {
flags.insert(CONTAINS_TEXT_OR_REPLACED_FRAGMENTS);
if flow::base(kid).flags.contains(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS) {
flags.insert(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS);
break
}
}
@ -1615,7 +1611,7 @@ impl BlockFlow {
let (mut left_float_width_accumulator, mut right_float_width_accumulator) = (Au(0), Au(0));
let mut preferred_inline_size_of_children_without_text_or_replaced_fragments = Au(0);
for kid in self.base.child_iter_mut() {
if flow::base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED) || !consult_children {
if flow::base(kid).flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) || !consult_children {
continue
}
@ -1625,16 +1621,16 @@ impl BlockFlow {
max(computation.content_intrinsic_sizes.minimum_inline_size,
child_base.intrinsic_inline_sizes.minimum_inline_size);
if child_base.flags.contains(CLEARS_LEFT) {
if child_base.flags.contains(FlowFlags::CLEARS_LEFT) {
left_float_width = max(left_float_width, left_float_width_accumulator);
left_float_width_accumulator = Au(0)
}
if child_base.flags.contains(CLEARS_RIGHT) {
if child_base.flags.contains(FlowFlags::CLEARS_RIGHT) {
right_float_width = max(right_float_width, right_float_width_accumulator);
right_float_width_accumulator = Au(0)
}
match (float_kind, child_base.flags.contains(CONTAINS_TEXT_OR_REPLACED_FRAGMENTS)) {
match (float_kind, child_base.flags.contains(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS)) {
(float::T::none, true) => {
computation.content_intrinsic_sizes.preferred_inline_size =
max(computation.content_intrinsic_sizes.preferred_inline_size,
@ -1681,7 +1677,7 @@ impl BlockFlow {
}
pub fn compute_inline_sizes(&mut self, shared_context: &SharedStyleContext) {
if !self.base.restyle_damage.intersects(REFLOW_OUT_OF_FLOW | REFLOW) {
if !self.base.restyle_damage.intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW) {
return
}
@ -1762,23 +1758,23 @@ impl BlockFlow {
}
pub fn is_inline_flex_item(&self) -> bool {
self.fragment.flags.contains(IS_INLINE_FLEX_ITEM)
self.fragment.flags.contains(FragmentFlags::IS_INLINE_FLEX_ITEM)
}
pub fn is_block_flex_item(&self) -> bool {
self.fragment.flags.contains(IS_BLOCK_FLEX_ITEM)
self.fragment.flags.contains(FragmentFlags::IS_BLOCK_FLEX_ITEM)
}
pub fn mark_scrolling_overflow(&mut self, has_scrolling_overflow: bool) {
if has_scrolling_overflow {
self.flags.insert(HAS_SCROLLING_OVERFLOW);
self.flags.insert(BlockFlowFlags::HAS_SCROLLING_OVERFLOW);
} else {
self.flags.remove(HAS_SCROLLING_OVERFLOW);
self.flags.remove(BlockFlowFlags::HAS_SCROLLING_OVERFLOW);
}
}
pub fn has_scrolling_overflow(&mut self) -> bool {
self.flags.contains(HAS_SCROLLING_OVERFLOW)
self.flags.contains(BlockFlowFlags::HAS_SCROLLING_OVERFLOW)
}
// Return offset from original position because of `position: sticky`.
@ -1824,7 +1820,7 @@ impl Flow for BlockFlow {
_ => true,
};
self.bubble_inline_sizes_for_block(consult_children);
self.fragment.restyle_damage.remove(BUBBLE_ISIZES);
self.fragment.restyle_damage.remove(ServoRestyleDamage::BUBBLE_ISIZES);
}
/// Recursively (top-down) determines the actual inline-size of child contexts and fragments.
@ -1874,13 +1870,14 @@ impl Flow for BlockFlow {
}
let is_formatting_context = self.formatting_context_type() != FormattingContextType::None;
if !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) && is_formatting_context {
if !self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) && is_formatting_context {
self.assign_inline_position_for_formatting_context(layout_context, content_box);
}
if (self as &Flow).floats_might_flow_through() {
self.base.thread_id = parent_thread_id;
if self.base.restyle_damage.intersects(REFLOW_OUT_OF_FLOW | REFLOW) {
if self.base.restyle_damage.intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW |
ServoRestyleDamage::REFLOW) {
self.assign_block_size(layout_context);
// Don't remove the restyle damage; `assign_block_size` decides whether that is
// appropriate (which in the case of e.g. absolutely-positioned flows, it is not).
@ -1914,7 +1911,7 @@ impl Flow for BlockFlow {
// Assign block-size for fragment if it is an image fragment.
self.fragment.assign_replaced_block_size_if_necessary();
if !self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
if !self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) {
self.base.position.size.block = self.fragment.border_box.size.block;
let mut block_start = AdjoiningMargins::from_margin(self.fragment.margin.block_start);
let block_end = AdjoiningMargins::from_margin(self.fragment.margin.block_end);
@ -1924,13 +1921,14 @@ impl Flow for BlockFlow {
} else {
self.base.collapsible_margins = CollapsibleMargins::Collapse(block_start, block_end);
}
self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
self.fragment.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
self.base.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW);
self.fragment.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW |
ServoRestyleDamage::REFLOW);
}
None
} else if self.is_root() ||
self.formatting_context_type() != FormattingContextType::None ||
self.base.flags.contains(MARGINS_CANNOT_COLLAPSE) {
self.base.flags.contains(FlowFlags::MARGINS_CANNOT_COLLAPSE) {
// Root element margins should never be collapsed according to CSS § 8.3.1.
debug!("assign_block_size: assigning block_size for root flow {:?}",
flow::base(self).debug_id());
@ -1957,7 +1955,7 @@ impl Flow for BlockFlow {
self.base.clip = max_rect();
}
if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) {
let position_start = self.base.position.start.to_physical(self.base.writing_mode,
container_size);
@ -1975,17 +1973,17 @@ impl Flow for BlockFlow {
};
if !self.base.writing_mode.is_vertical() {
if !self.base.flags.contains(INLINE_POSITION_IS_STATIC) {
if !self.base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) {
self.base.stacking_relative_position.x = absolute_stacking_relative_position.x
}
if !self.base.flags.contains(BLOCK_POSITION_IS_STATIC) {
if !self.base.flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) {
self.base.stacking_relative_position.y = absolute_stacking_relative_position.y
}
} else {
if !self.base.flags.contains(INLINE_POSITION_IS_STATIC) {
if !self.base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) {
self.base.stacking_relative_position.y = absolute_stacking_relative_position.y
}
if !self.base.flags.contains(BLOCK_POSITION_IS_STATIC) {
if !self.base.flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) {
self.base.stacking_relative_position.x = absolute_stacking_relative_position.x
}
}
@ -2058,28 +2056,28 @@ impl Flow for BlockFlow {
// Process children.
for kid in self.base.child_iter_mut() {
if flow::base(kid).flags.contains(INLINE_POSITION_IS_STATIC) ||
flow::base(kid).flags.contains(BLOCK_POSITION_IS_STATIC) {
if flow::base(kid).flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) ||
flow::base(kid).flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) {
let kid_base = flow::mut_base(kid);
let physical_position = kid_base.position.to_physical(kid_base.writing_mode,
container_size_for_children);
// Set the inline and block positions as necessary.
if !kid_base.writing_mode.is_vertical() {
if kid_base.flags.contains(INLINE_POSITION_IS_STATIC) {
if kid_base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) {
kid_base.stacking_relative_position.x = origin_for_children.x +
physical_position.origin.x
}
if kid_base.flags.contains(BLOCK_POSITION_IS_STATIC) {
if kid_base.flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) {
kid_base.stacking_relative_position.y = origin_for_children.y +
physical_position.origin.y
}
} else {
if kid_base.flags.contains(INLINE_POSITION_IS_STATIC) {
if kid_base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) {
kid_base.stacking_relative_position.y = origin_for_children.y +
physical_position.origin.y
}
if kid_base.flags.contains(BLOCK_POSITION_IS_STATIC) {
if kid_base.flags.contains(FlowFlags::BLOCK_POSITION_IS_STATIC) {
kid_base.stacking_relative_position.x = origin_for_children.x +
physical_position.origin.x
}
@ -2092,11 +2090,11 @@ impl Flow for BlockFlow {
}
fn mark_as_root(&mut self) {
self.flags.insert(IS_ROOT)
self.flags.insert(BlockFlowFlags::IS_ROOT)
}
fn is_root(&self) -> bool {
self.flags.contains(IS_ROOT)
self.flags.contains(BlockFlowFlags::IS_ROOT)
}
/// The 'position' property of this flow.
@ -2122,7 +2120,7 @@ impl Flow for BlockFlow {
}
fn update_late_computed_inline_position_if_necessary(&mut self, inline_position: Au) {
if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) &&
if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) &&
self.fragment.style().logical_position().inline_start ==
LengthOrPercentageOrAuto::Auto &&
self.fragment.style().logical_position().inline_end ==
@ -2132,7 +2130,7 @@ impl Flow for BlockFlow {
}
fn update_late_computed_block_position_if_necessary(&mut self, block_position: Au) {
if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) &&
if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) &&
self.fragment.style().logical_position().block_start ==
LengthOrPercentageOrAuto::Auto &&
self.fragment.style().logical_position().block_end ==
@ -2748,7 +2746,7 @@ impl ISizeAndMarginsComputer for AbsoluteNonReplaced {
block: &mut BlockFlow,
solution: ISizeConstraintSolution) {
// Set the inline position of the absolute flow wrt to its containing block.
if !block.base.flags.contains(INLINE_POSITION_IS_STATIC) {
if !block.base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) {
block.base.position.start.i = solution.inline_start;
}
}

Просмотреть файл

@ -16,22 +16,19 @@
use ServoArc;
use block::BlockFlow;
use context::{LayoutContext, with_thread_local_font_context};
use data::{HAS_NEWLY_CONSTRUCTED_FLOW, LayoutData};
use data::{LayoutDataFlags, LayoutData};
use flex::FlexFlow;
use floats::FloatKind;
use flow::{self, AbsoluteDescendants, Flow, FlowClass, ImmutableFlowUtils};
use flow::{CAN_BE_FRAGMENTED, IS_ABSOLUTELY_POSITIONED, MARGINS_CANNOT_COLLAPSE};
use flow::{MutableFlowUtils, MutableOwnedFlowUtils};
use flow::{FlowFlags, MutableFlowUtils, MutableOwnedFlowUtils};
use flow_ref::FlowRef;
use fragment::{CanvasFragmentInfo, ImageFragmentInfo, InlineAbsoluteFragmentInfo, SvgFragmentInfo};
use fragment::{Fragment, GeneratedContentInfo, IframeFragmentInfo};
use fragment::{IS_INLINE_FLEX_ITEM, IS_BLOCK_FLEX_ITEM};
use fragment::{Fragment, GeneratedContentInfo, IframeFragmentInfo, FragmentFlags};
use fragment::{InlineAbsoluteHypotheticalFragmentInfo, TableColumnFragmentInfo};
use fragment::{InlineBlockFragmentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo};
use fragment::WhitespaceStrippingResult;
use gfx::display_list::OpaqueNode;
use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFlow};
use inline::{InlineFragmentNodeInfo, LAST_FRAGMENT_OF_ELEMENT};
use inline::{InlineFlow, InlineFragmentNodeInfo, InlineFragmentNodeFlags};
use linked_list::prepend_from;
use list_item::{ListItemFlow, ListStyleTypeContent};
use multicol::{MulticolColumnFlow, MulticolFlow};
@ -54,7 +51,7 @@ use style::logical_geometry::Direction;
use style::properties::ComputedValues;
use style::properties::longhands::list_style_image;
use style::selector_parser::{PseudoElement, RestyleDamage};
use style::servo::restyle_damage::{BUBBLE_ISIZES, RECONSTRUCT_FLOW};
use style::servo::restyle_damage::ServoRestyleDamage;
use style::values::Either;
use table::TableFlow;
use table_caption::TableCaptionFlow;
@ -173,7 +170,7 @@ impl InlineBlockSplit {
-> InlineBlockSplit {
fragment_accumulator.enclosing_node.as_mut().expect(
"enclosing_node is None; Are {ib} splits being generated outside of an inline node?"
).flags.remove(LAST_FRAGMENT_OF_ELEMENT);
).flags.remove(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT);
let split = InlineBlockSplit {
predecessors: mem::replace(
@ -183,7 +180,8 @@ impl InlineBlockSplit {
flow: flow,
};
fragment_accumulator.enclosing_node.as_mut().unwrap().flags.remove(FIRST_FRAGMENT_OF_ELEMENT);
fragment_accumulator.enclosing_node.as_mut().unwrap().flags.remove(
InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT);
split
}
@ -258,7 +256,8 @@ impl InlineFragmentsAccumulator {
pseudo: node.get_pseudo_element_type().strip(),
style: node.style(style_context),
selected_style: node.selected_style(),
flags: FIRST_FRAGMENT_OF_ELEMENT | LAST_FRAGMENT_OF_ELEMENT,
flags: InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT |
InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT,
}),
bidi_control_chars: None,
restyle_damage: node.restyle_damage(),
@ -287,17 +286,18 @@ impl InlineFragmentsAccumulator {
for (index, fragment) in fragments.fragments.iter_mut().enumerate() {
let mut enclosing_node = enclosing_node.clone();
if index != 0 {
enclosing_node.flags.remove(FIRST_FRAGMENT_OF_ELEMENT)
enclosing_node.flags.remove(InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT)
}
if index != fragment_count - 1 {
enclosing_node.flags.remove(LAST_FRAGMENT_OF_ELEMENT)
enclosing_node.flags.remove(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT)
}
fragment.add_inline_context_style(enclosing_node);
}
// Control characters are later discarded in transform_text, so they don't affect the
// is_first/is_last styles above.
enclosing_node.flags.remove(FIRST_FRAGMENT_OF_ELEMENT | LAST_FRAGMENT_OF_ELEMENT);
enclosing_node.flags.remove(InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT |
InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT);
if let Some((start, end)) = bidi_control_chars {
fragments.fragments.push_front(
@ -493,7 +493,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
ConstructionResult::Flow(kid_flow, AbsoluteDescendants::new());
self.set_flow_construction_result(&kid, construction_result)
} else {
if !flow::base(&*kid_flow).flags.contains(IS_ABSOLUTELY_POSITIONED) {
if !flow::base(&*kid_flow).flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) {
// Flush any inline fragments that we were gathering up. This allows us to
// handle {ib} splits.
let old_inline_fragment_accumulator =
@ -621,7 +621,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
flow.set_absolute_descendants(abs_descendants);
abs_descendants = AbsoluteDescendants::new();
if flow::base(&*flow).flags.contains(IS_ABSOLUTELY_POSITIONED) {
if flow::base(&*flow).flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) {
// This is now the only absolute flow in the subtree which hasn't yet
// reached its CB.
abs_descendants.push(flow.clone());
@ -776,7 +776,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
match kid.get_construction_result() {
ConstructionResult::None => {}
ConstructionResult::Flow(flow, kid_abs_descendants) => {
if !flow::base(&*flow).flags.contains(IS_ABSOLUTELY_POSITIONED) {
if !flow::base(&*flow).flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) {
opt_inline_block_splits.push_back(InlineBlockSplit::new(
&mut fragment_accumulator, node, self.style_context(), flow));
abs_descendants.push_descendants(kid_abs_descendants);
@ -1066,7 +1066,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
abs_descendants = AbsoluteDescendants::new();
if flow::base(&*flow).flags.contains(IS_ABSOLUTELY_POSITIONED) {
if flow::base(&*flow).flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) {
// This is now the only absolute flow in the subtree which hasn't yet
// reached its containing block.
abs_descendants.push(flow.clone());
@ -1137,7 +1137,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
abs_descendants = AbsoluteDescendants::new();
if flow::base(&*wrapper_flow).flags.contains(IS_ABSOLUTELY_POSITIONED) {
if flow::base(&*wrapper_flow).flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) {
// This is now the only absolute flow in the subtree which hasn't yet
// reached its containing block.
abs_descendants.push(wrapper_flow.clone());
@ -1332,8 +1332,8 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
}
for kid in node.children() {
if kid.flags().contains(HAS_NEWLY_CONSTRUCTED_FLOW) {
kid.remove_flags(HAS_NEWLY_CONSTRUCTED_FLOW);
if kid.flags().contains(LayoutDataFlags::HAS_NEWLY_CONSTRUCTED_FLOW) {
kid.remove_flags(LayoutDataFlags::HAS_NEWLY_CONSTRUCTED_FLOW);
need_to_reconstruct = true
}
}
@ -1342,7 +1342,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
return false
}
if node.restyle_damage().contains(RECONSTRUCT_FLOW) {
if node.restyle_damage().contains(ServoRestyleDamage::RECONSTRUCT_FLOW) {
return false
}
@ -1436,7 +1436,7 @@ impl<'a, ConcreteThreadSafeLayoutNode: ThreadSafeLayoutNode>
}
};
if set_has_newly_constructed_flow_flag {
node.insert_flags(HAS_NEWLY_CONSTRUCTED_FLOW);
node.insert_flags(LayoutDataFlags::HAS_NEWLY_CONSTRUCTED_FLOW);
}
return result;
}
@ -1452,7 +1452,7 @@ impl<'a, ConcreteThreadSafeLayoutNode> PostorderNodeMutTraversal<ConcreteThreadS
// TODO: This should actually consult the table in that section to get the
// final computed value for 'display'.
fn process(&mut self, node: &ConcreteThreadSafeLayoutNode) {
node.insert_flags(HAS_NEWLY_CONSTRUCTED_FLOW);
node.insert_flags(LayoutDataFlags::HAS_NEWLY_CONSTRUCTED_FLOW);
// Bail out if this node has an ancestor with display: none.
if node.style(self.style_context()).is_in_display_none_subtree() {
@ -1654,7 +1654,7 @@ impl<ConcreteThreadSafeLayoutNode> NodeUtils for ConcreteThreadSafeLayoutNode
fn set_flow_construction_result(self, mut result: ConstructionResult) {
if self.can_be_fragmented() {
if let ConstructionResult::Flow(ref mut flow, _) = result {
flow::mut_base(FlowRef::deref_mut(flow)).flags.insert(CAN_BE_FRAGMENTED);
flow::mut_base(FlowRef::deref_mut(flow)).flags.insert(FlowFlags::CAN_BE_FRAGMENTED);
}
}
@ -1744,7 +1744,7 @@ impl FlowConstructionUtils for FlowRef {
fn finish(&mut self) {
if !opts::get().bubble_inline_sizes_separately {
FlowRef::deref_mut(self).bubble_inline_sizes();
flow::mut_base(FlowRef::deref_mut(self)).restyle_damage.remove(BUBBLE_ISIZES);
flow::mut_base(FlowRef::deref_mut(self)).restyle_damage.remove(ServoRestyleDamage::BUBBLE_ISIZES);
}
}
}
@ -1945,7 +1945,7 @@ impl Legalizer {
}
(FlowClass::Flex, FlowClass::Inline) => {
flow::mut_base(FlowRef::deref_mut(child)).flags.insert(MARGINS_CANNOT_COLLAPSE);
flow::mut_base(FlowRef::deref_mut(child)).flags.insert(FlowFlags::MARGINS_CANNOT_COLLAPSE);
let mut block_wrapper =
Legalizer::create_anonymous_flow(context,
parent,
@ -1954,12 +1954,12 @@ impl Legalizer {
BlockFlow::from_fragment);
{
let flag = if parent.as_flex().main_mode() == Direction::Inline {
IS_INLINE_FLEX_ITEM
FragmentFlags::IS_INLINE_FLEX_ITEM
} else {
IS_BLOCK_FLEX_ITEM
FragmentFlags::IS_BLOCK_FLEX_ITEM
};
let block = FlowRef::deref_mut(&mut block_wrapper).as_mut_block();
block.base.flags.insert(MARGINS_CANNOT_COLLAPSE);
block.base.flags.insert(FlowFlags::MARGINS_CANNOT_COLLAPSE);
block.fragment.flags.insert(flag);
}
block_wrapper.add_new_child((*child).clone());
@ -1971,12 +1971,12 @@ impl Legalizer {
(FlowClass::Flex, _) => {
{
let flag = if parent.as_flex().main_mode() == Direction::Inline {
IS_INLINE_FLEX_ITEM
FragmentFlags::IS_INLINE_FLEX_ITEM
} else {
IS_BLOCK_FLEX_ITEM
FragmentFlags::IS_BLOCK_FLEX_ITEM
};
let block = FlowRef::deref_mut(child).as_mut_block();
block.base.flags.insert(MARGINS_CANNOT_COLLAPSE);
block.base.flags.insert(FlowFlags::MARGINS_CANNOT_COLLAPSE);
block.fragment.flags.insert(flag);
}
parent.add_new_child((*child).clone());

Просмотреть файл

@ -60,10 +60,10 @@ impl LayoutData {
}
bitflags! {
pub flags LayoutDataFlags: u8 {
pub struct LayoutDataFlags: u8 {
#[doc = "Whether a flow has been newly constructed."]
const HAS_NEWLY_CONSTRUCTED_FLOW = 0x01,
const HAS_NEWLY_CONSTRUCTED_FLOW = 0x01;
#[doc = "Whether this node has been traversed by layout."]
const HAS_BEEN_TRAVERSED = 0x02,
const HAS_BEEN_TRAVERSED = 0x02;
}
}

Просмотреть файл

@ -16,7 +16,7 @@ use canvas_traits::canvas::{CanvasMsg, FromLayoutMsg};
use context::LayoutContext;
use euclid::{Point2D, Rect, SideOffsets2D, Size2D, Transform3D, TypedRect, TypedSize2D, Vector2D};
use flex::FlexFlow;
use flow::{BaseFlow, Flow, IS_ABSOLUTELY_POSITIONED};
use flow::{BaseFlow, Flow, FlowFlags};
use flow_ref::FlowRef;
use fnv::FnvHashMap;
use fragment::{CanvasFragmentSource, CoordinateSystem, Fragment, ImageFragmentInfo, ScannedTextFragmentInfo};
@ -24,15 +24,16 @@ use fragment::SpecificFragmentInfo;
use gfx::display_list;
use gfx::display_list::{BLUR_INFLATION_FACTOR, BaseDisplayItem, BorderDetails, BorderDisplayItem};
use gfx::display_list::{BorderRadii, BoxShadowClipMode, BoxShadowDisplayItem, ClipScrollNode};
use gfx::display_list::{ClipScrollNodeIndex, ClippingAndScrolling, ClipScrollNodeType};
use gfx::display_list::{ClipScrollNodeIndex, ClipScrollNodeType, ClippingAndScrolling};
use gfx::display_list::{ClippingRegion, DisplayItem, DisplayItemMetadata, DisplayList};
use gfx::display_list::{DisplayListSection, GradientDisplayItem, IframeDisplayItem, ImageBorder};
use gfx::display_list::{ImageDisplayItem, LineDisplayItem, NormalBorder, OpaqueNode};
use gfx::display_list::{PopAllTextShadowsDisplayItem, PushTextShadowDisplayItem};
use gfx::display_list::{RadialGradientDisplayItem, SolidColorDisplayItem, StackingContext};
use gfx::display_list::{StackingContextType, TextDisplayItem, TextOrientation, WebRenderImageInfo};
use gfx::display_list::{StackingContextType, StickyFrameData, TextDisplayItem, TextOrientation};
use gfx::display_list::WebRenderImageInfo;
use gfx_traits::{combine_id_with_fragment_type, FragmentType, StackingContextId};
use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFlow, LAST_FRAGMENT_OF_ELEMENT};
use inline::{InlineFragmentNodeFlags, InlineFlow};
use ipc_channel::ipc;
use list_item::ListItemFlow;
use model::{self, MaybeAuto};
@ -54,7 +55,7 @@ use style::logical_geometry::{LogicalMargin, LogicalPoint, LogicalRect, LogicalS
use style::properties::ComputedValues;
use style::properties::longhands::border_image_repeat::computed_value::RepeatKeyword;
use style::properties::style_structs;
use style::servo::restyle_damage::REPAINT;
use style::servo::restyle_damage::ServoRestyleDamage;
use style::values::{Either, RGBA};
use style::values::computed::{Angle, Gradient, GradientItem, LengthOrPercentage, Percentage};
use style::values::computed::{LengthOrPercentageOrAuto, NumberOrPercentage, Position};
@ -73,8 +74,7 @@ use style_traits::ToCss;
use style_traits::cursor::Cursor;
use table_cell::CollapsedBordersForCell;
use webrender_api::{ClipId, ClipMode, ColorF, ComplexClipRegion, GradientStop, LineStyle};
use webrender_api::{LocalClip, RepeatMode, ScrollPolicy, ScrollSensitivity, StickyFrameInfo};
use webrender_api::StickySideConstraint;
use webrender_api::{LocalClip, RepeatMode, ScrollPolicy, ScrollSensitivity, StickyOffsetBounds};
use webrender_helpers::{ToBorderRadius, ToMixBlendMode, ToRectF, ToTransformStyle};
trait ResolvePercentage {
@ -106,7 +106,8 @@ fn convert_repeat_mode(from: RepeatKeyword) -> RepeatMode {
fn establishes_containing_block_for_absolute(flags: StackingContextCollectionFlags,
positioning: position::T)
-> bool {
!flags.contains(NEVER_CREATES_CONTAINING_BLOCK) && position::T::static_ != positioning
!flags.contains(StackingContextCollectionFlags::NEVER_CREATES_CONTAINING_BLOCK) &&
position::T::static_ != positioning
}
trait RgbColor {
@ -1878,7 +1879,7 @@ impl FragmentDisplayListBuilding for Fragment {
border_painting_mode: BorderPaintingMode,
display_list_section: DisplayListSection,
clip: &Rect<Au>) {
self.restyle_damage.remove(REPAINT);
self.restyle_damage.remove(ServoRestyleDamage::REPAINT);
if self.style().get_inheritedbox().visibility != visibility::T::visible {
return
}
@ -1924,8 +1925,10 @@ impl FragmentDisplayListBuilding for Fragment {
state,
&*node.style,
Some(InlineNodeBorderInfo {
is_first_fragment_of_element: node.flags.contains(FIRST_FRAGMENT_OF_ELEMENT),
is_last_fragment_of_element: node.flags.contains(LAST_FRAGMENT_OF_ELEMENT),
is_first_fragment_of_element:
node.flags.contains(InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT),
is_last_fragment_of_element:
node.flags.contains(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT),
}),
border_painting_mode,
&stacking_relative_border_box,
@ -2407,13 +2410,13 @@ impl FragmentDisplayListBuilding for Fragment {
}
bitflags! {
pub flags StackingContextCollectionFlags: u8 {
pub struct StackingContextCollectionFlags: u8 {
/// This flow never establishes a containing block.
const NEVER_CREATES_CONTAINING_BLOCK = 0b001,
const NEVER_CREATES_CONTAINING_BLOCK = 0b001;
/// This flow never creates a ClipScrollNode.
const NEVER_CREATES_CLIP_SCROLL_NODE = 0b010,
const NEVER_CREATES_CLIP_SCROLL_NODE = 0b010;
/// This flow never creates a stacking context.
const NEVER_CREATES_STACKING_CONTEXT = 0b100,
const NEVER_CREATES_STACKING_CONTEXT = 0b100;
}
}
@ -2679,7 +2682,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
self.transform_clip_to_coordinate_space(state, preserved_state);
}
if !flags.contains(NEVER_CREATES_CLIP_SCROLL_NODE) {
if !flags.contains(StackingContextCollectionFlags::NEVER_CREATES_CLIP_SCROLL_NODE) {
self.setup_clip_scroll_node_for_position(state, &stacking_relative_border_box);
self.setup_clip_scroll_node_for_overflow(state, &stacking_relative_border_box);
self.setup_clip_scroll_node_for_css_clip(state, preserved_state,
@ -2689,7 +2692,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
// We keep track of our position so that any stickily positioned elements can
// properly determine the extent of their movement relative to scrolling containers.
if !flags.contains(NEVER_CREATES_CONTAINING_BLOCK) {
if !flags.contains(StackingContextCollectionFlags::NEVER_CREATES_CONTAINING_BLOCK) {
let border_box = if self.fragment.establishes_stacking_context() {
stacking_relative_border_box
} else {
@ -2734,27 +2737,32 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
// positioned items: just the parent block.
let constraint_rect = state.parent_stacking_relative_content_box;
let to_max_offset = |constraint_edge: Au, moving_edge: Au| -> f32 {
let to_offset_bound = |constraint_edge: Au, moving_edge: Au| -> f32 {
(constraint_edge - moving_edge).to_f32_px()
};
let to_sticky_info = |margin: MaybeAuto, max_offset: f32| -> Option<StickySideConstraint> {
match margin {
MaybeAuto::Auto => None,
MaybeAuto::Specified(value) =>
Some(StickySideConstraint { margin: value.to_f32_px(), max_offset }),
}
};
// This is the minimum negative offset and then the maximum positive offset. We just
// specify every edge, but if the corresponding margin is None, that offset has no effect.
let vertical_offset_bounds = StickyOffsetBounds::new(
to_offset_bound(constraint_rect.min_y(), border_box_in_parent.min_y() - margins.top),
to_offset_bound(constraint_rect.max_y(), border_box_in_parent.max_y()),
);
let horizontal_offset_bounds = StickyOffsetBounds::new(
to_offset_bound(constraint_rect.min_x(), border_box_in_parent.min_x() - margins.left),
to_offset_bound(constraint_rect.max_x(), border_box_in_parent.max_x()),
);
let sticky_frame_info = StickyFrameInfo::new(
to_sticky_info(sticky_position.top,
to_max_offset(constraint_rect.max_y(), border_box_in_parent.max_y())),
to_sticky_info(sticky_position.right,
to_max_offset(constraint_rect.min_x(), border_box_in_parent.min_x() - margins.left)),
to_sticky_info(sticky_position.bottom,
to_max_offset(constraint_rect.min_y(), border_box_in_parent.min_y() - margins.top)),
to_sticky_info(sticky_position.left,
to_max_offset(constraint_rect.max_x(), border_box_in_parent.max_x())));
// The margins control which edges have sticky behavior.
let sticky_frame_data = StickyFrameData {
margins: SideOffsets2D::new(
sticky_position.top.to_option().map(|v| v.to_f32_px()),
sticky_position.right.to_option().map(|v| v.to_f32_px()),
sticky_position.bottom.to_option().map(|v| v.to_f32_px()),
sticky_position.left.to_option().map(|v| v.to_f32_px()),
),
vertical_offset_bounds,
horizontal_offset_bounds
};
let new_clip_scroll_index = state.add_clip_scroll_node(
ClipScrollNode {
@ -2762,7 +2770,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
parent_index: self.clipping_and_scrolling().scrolling,
clip: ClippingRegion::from_rect(border_box),
content_rect: Rect::zero(),
node_type: ClipScrollNodeType::StickyFrame(sticky_frame_info),
node_type: ClipScrollNodeType::StickyFrame(sticky_frame_data),
},
);
@ -2882,7 +2890,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
parent_clipping_and_scrolling: ClippingAndScrolling,
state: &mut StackingContextCollectionState
) {
let creation_mode = if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) ||
let creation_mode = if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) ||
self.fragment.style.get_box().position != position::T::static_ {
StackingContextType::PseudoPositioned
} else {
@ -2941,7 +2949,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
border_painting_mode: BorderPaintingMode) {
let background_border_section = if self.base.flags.is_float() {
DisplayListSection::BackgroundAndBorders
} else if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
} else if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) {
if self.fragment.establishes_stacking_context() {
DisplayListSection::BackgroundAndBorders
} else {
@ -2977,7 +2985,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
&self,
flags: StackingContextCollectionFlags,
) -> BlockStackingContextType {
if flags.contains(NEVER_CREATES_STACKING_CONTEXT) {
if flags.contains(StackingContextCollectionFlags::NEVER_CREATES_STACKING_CONTEXT) {
return BlockStackingContextType::NonstackingContext;
}
@ -2985,7 +2993,7 @@ impl BlockFlowDisplayListBuilding for BlockFlow {
return BlockStackingContextType::StackingContext
}
if self.base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
if self.base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) {
return BlockStackingContextType::PseudoStackingContext
}

Просмотреть файл

@ -14,8 +14,7 @@ use display_list_builder::StackingContextCollectionState;
use euclid::Point2D;
use floats::FloatKind;
use flow;
use flow::{Flow, FlowClass, ImmutableFlowUtils, OpaqueFlow};
use flow::{INLINE_POSITION_IS_STATIC, IS_ABSOLUTELY_POSITIONED};
use flow::{Flow, FlowClass, ImmutableFlowUtils, OpaqueFlow, FlowFlags};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use layout_debug;
use model::{AdjoiningMargins, CollapsibleMargins};
@ -25,7 +24,7 @@ use std::ops::Range;
use style::computed_values::{align_content, align_self, flex_direction, flex_wrap, justify_content};
use style::logical_geometry::{Direction, LogicalSize};
use style::properties::ComputedValues;
use style::servo::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW};
use style::servo::restyle_damage::ServoRestyleDamage;
use style::values::computed::{LengthOrPercentage, LengthOrPercentageOrAuto, LengthOrPercentageOrNone};
use style::values::computed::flex::FlexBasis;
use style::values::generics::flex::FlexBasis as GenericFlexBasis;
@ -449,7 +448,7 @@ impl FlexFlow {
if !fixed_width {
for kid in self.block_flow.base.children.iter_mut() {
let base = flow::mut_base(kid);
let is_absolutely_positioned = base.flags.contains(IS_ABSOLUTELY_POSITIONED);
let is_absolutely_positioned = base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED);
if !is_absolutely_positioned {
let flex_item_inline_sizes = IntrinsicISizes {
minimum_inline_size: base.intrinsic_inline_sizes.minimum_inline_size,
@ -475,7 +474,7 @@ impl FlexFlow {
if !fixed_width {
for kid in self.block_flow.base.children.iter_mut() {
let base = flow::mut_base(kid);
let is_absolutely_positioned = base.flags.contains(IS_ABSOLUTELY_POSITIONED);
let is_absolutely_positioned = base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED);
if !is_absolutely_positioned {
computation.content_intrinsic_sizes.minimum_inline_size =
max(computation.content_intrinsic_sizes.minimum_inline_size,
@ -518,7 +517,7 @@ impl FlexFlow {
for kid in &mut self.items {
let kid_base = flow::mut_base(children.get(kid.index));
kid_base.block_container_explicit_block_size = container_block_size;
if kid_base.flags.contains(INLINE_POSITION_IS_STATIC) {
if kid_base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) {
// The inline-start margin edge of the child flow is at our inline-start content
// edge, and its inline-size is our content inline-size.
kid_base.position.start.i =
@ -855,7 +854,7 @@ impl Flow for FlexFlow {
.iter()
.enumerate()
.filter(|&(_, flow)| {
!flow.as_block().base.flags.contains(IS_ABSOLUTELY_POSITIONED)
!flow.as_block().base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED)
})
.map(|(index, flow)| FlexItem::new(index, flow))
.collect();
@ -873,7 +872,8 @@ impl Flow for FlexFlow {
let _scope = layout_debug_scope!("flex::assign_inline_sizes {:x}", self.block_flow.base.debug_id());
debug!("assign_inline_sizes");
if !self.block_flow.base.restyle_damage.intersects(REFLOW_OUT_OF_FLOW | REFLOW) {
if !self.block_flow.base.restyle_damage.intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW |
ServoRestyleDamage::REFLOW) {
return
}

Просмотреть файл

@ -4,7 +4,7 @@
use app_units::{Au, MAX_AU};
use block::FormattingContextType;
use flow::{self, CLEARS_LEFT, CLEARS_RIGHT, Flow, ImmutableFlowUtils};
use flow::{self, Flow, FlowFlags, ImmutableFlowUtils};
use persistent_list::PersistentList;
use std::cmp::{max, min};
use std::fmt;
@ -459,10 +459,10 @@ impl SpeculatedFloatPlacement {
/// flow, computes the speculated inline size of the floats flowing in.
pub fn compute_floats_in(&mut self, flow: &mut Flow) {
let base_flow = flow::base(flow);
if base_flow.flags.contains(CLEARS_LEFT) {
if base_flow.flags.contains(FlowFlags::CLEARS_LEFT) {
self.left = Au(0)
}
if base_flow.flags.contains(CLEARS_RIGHT) {
if base_flow.flags.contains(FlowFlags::CLEARS_RIGHT) {
self.right = Au(0)
}
}

Просмотреть файл

@ -54,7 +54,7 @@ use style::context::SharedStyleContext;
use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode};
use style::properties::ComputedValues;
use style::selector_parser::RestyleDamage;
use style::servo::restyle_damage::{RECONSTRUCT_FLOW, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT};
use style::servo::restyle_damage::ServoRestyleDamage;
use style::values::computed::LengthOrPercentageOrAuto;
use table::TableFlow;
use table_caption::TableCaptionFlow;
@ -252,7 +252,7 @@ pub trait Flow: HasBaseFlow + fmt::Debug + Sync + Send + 'static {
if might_have_floats_in_or_out {
mut_base(self).thread_id = parent_thread_id;
self.assign_block_size(layout_context);
mut_base(self).restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
mut_base(self).restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW);
}
might_have_floats_in_or_out
}
@ -402,7 +402,7 @@ pub trait Flow: HasBaseFlow + fmt::Debug + Sync + Send + 'static {
fn contains_positioned_fragments(&self) -> bool {
self.contains_relatively_positioned_fragments() ||
base(self).flags.contains(IS_ABSOLUTELY_POSITIONED)
base(self).flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED)
}
fn contains_relatively_positioned_fragments(&self) -> bool {
@ -591,52 +591,52 @@ impl FlowClass {
bitflags! {
#[doc = "Flags used in flows."]
pub flags FlowFlags: u32 {
pub struct FlowFlags: u32 {
// text align flags
#[doc = "Whether this flow is absolutely positioned. This is checked all over layout, so a"]
#[doc = "virtual call is too expensive."]
const IS_ABSOLUTELY_POSITIONED = 0b0000_0000_0000_0000_0100_0000,
const IS_ABSOLUTELY_POSITIONED = 0b0000_0000_0000_0000_0100_0000;
#[doc = "Whether this flow clears to the left. This is checked all over layout, so a"]
#[doc = "virtual call is too expensive."]
const CLEARS_LEFT = 0b0000_0000_0000_0000_1000_0000,
const CLEARS_LEFT = 0b0000_0000_0000_0000_1000_0000;
#[doc = "Whether this flow clears to the right. This is checked all over layout, so a"]
#[doc = "virtual call is too expensive."]
const CLEARS_RIGHT = 0b0000_0000_0000_0001_0000_0000,
const CLEARS_RIGHT = 0b0000_0000_0000_0001_0000_0000;
#[doc = "Whether this flow is left-floated. This is checked all over layout, so a"]
#[doc = "virtual call is too expensive."]
const FLOATS_LEFT = 0b0000_0000_0000_0010_0000_0000,
const FLOATS_LEFT = 0b0000_0000_0000_0010_0000_0000;
#[doc = "Whether this flow is right-floated. This is checked all over layout, so a"]
#[doc = "virtual call is too expensive."]
const FLOATS_RIGHT = 0b0000_0000_0000_0100_0000_0000,
const FLOATS_RIGHT = 0b0000_0000_0000_0100_0000_0000;
#[doc = "Text alignment. \
NB: If you update this, update `TEXT_ALIGN_SHIFT` below."]
const TEXT_ALIGN = 0b0000_0000_0111_1000_0000_0000,
const TEXT_ALIGN = 0b0000_0000_0111_1000_0000_0000;
#[doc = "Whether this flow has a fragment with `counter-reset` or `counter-increment` \
styles."]
const AFFECTS_COUNTERS = 0b0000_0000_1000_0000_0000_0000,
const AFFECTS_COUNTERS = 0b0000_0000_1000_0000_0000_0000;
#[doc = "Whether this flow's descendants have fragments that affect `counter-reset` or \
`counter-increment` styles."]
const HAS_COUNTER_AFFECTING_CHILDREN = 0b0000_0001_0000_0000_0000_0000,
const HAS_COUNTER_AFFECTING_CHILDREN = 0b0000_0001_0000_0000_0000_0000;
#[doc = "Whether this flow behaves as though it had `position: static` for the purposes \
of positioning in the inline direction. This is set for flows with `position: \
static` and `position: relative` as well as absolutely-positioned flows with \
unconstrained positions in the inline direction."]
const INLINE_POSITION_IS_STATIC = 0b0000_0010_0000_0000_0000_0000,
const INLINE_POSITION_IS_STATIC = 0b0000_0010_0000_0000_0000_0000;
#[doc = "Whether this flow behaves as though it had `position: static` for the purposes \
of positioning in the block direction. This is set for flows with `position: \
static` and `position: relative` as well as absolutely-positioned flows with \
unconstrained positions in the block direction."]
const BLOCK_POSITION_IS_STATIC = 0b0000_0100_0000_0000_0000_0000,
const BLOCK_POSITION_IS_STATIC = 0b0000_0100_0000_0000_0000_0000;
/// Whether any ancestor is a fragmentation container
const CAN_BE_FRAGMENTED = 0b0000_1000_0000_0000_0000_0000,
const CAN_BE_FRAGMENTED = 0b0000_1000_0000_0000_0000_0000;
/// Whether this flow contains any text and/or replaced fragments.
const CONTAINS_TEXT_OR_REPLACED_FRAGMENTS = 0b0001_0000_0000_0000_0000_0000,
const CONTAINS_TEXT_OR_REPLACED_FRAGMENTS = 0b0001_0000_0000_0000_0000_0000;
/// Whether margins are prohibited from collapsing with this flow.
const MARGINS_CANNOT_COLLAPSE = 0b0010_0000_0000_0000_0000_0000,
const MARGINS_CANNOT_COLLAPSE = 0b0010_0000_0000_0000_0000_0000;
}
}
@ -648,20 +648,20 @@ static TEXT_ALIGN_SHIFT: usize = 11;
impl FlowFlags {
#[inline]
pub fn text_align(self) -> text_align::T {
text_align::T::from_u32((self & TEXT_ALIGN).bits() >> TEXT_ALIGN_SHIFT).unwrap()
text_align::T::from_u32((self & FlowFlags::TEXT_ALIGN).bits() >> TEXT_ALIGN_SHIFT).unwrap()
}
#[inline]
pub fn set_text_align(&mut self, value: text_align::T) {
*self = (*self & !TEXT_ALIGN) |
*self = (*self & !FlowFlags::TEXT_ALIGN) |
FlowFlags::from_bits(value.to_u32() << TEXT_ALIGN_SHIFT).unwrap();
}
#[inline]
pub fn float_kind(&self) -> float::T {
if self.contains(FLOATS_LEFT) {
if self.contains(FlowFlags::FLOATS_LEFT) {
float::T::left
} else if self.contains(FLOATS_RIGHT) {
} else if self.contains(FlowFlags::FLOATS_RIGHT) {
float::T::right
} else {
float::T::none
@ -670,12 +670,12 @@ impl FlowFlags {
#[inline]
pub fn is_float(&self) -> bool {
self.contains(FLOATS_LEFT) || self.contains(FLOATS_RIGHT)
self.contains(FlowFlags::FLOATS_LEFT) || self.contains(FlowFlags::FLOATS_RIGHT)
}
#[inline]
pub fn clears_floats(&self) -> bool {
self.contains(CLEARS_LEFT) || self.contains(CLEARS_RIGHT)
self.contains(FlowFlags::CLEARS_LEFT) || self.contains(FlowFlags::CLEARS_RIGHT)
}
}
@ -947,8 +947,8 @@ impl fmt::Debug for BaseFlow {
overflow={:?}{}{}{}",
self.stacking_context_id,
self.position,
if self.flags.contains(FLOATS_LEFT) { "FL" } else { "" },
if self.flags.contains(FLOATS_RIGHT) { "FR" } else { "" },
if self.flags.contains(FlowFlags::FLOATS_LEFT) { "FL" } else { "" },
if self.flags.contains(FlowFlags::FLOATS_RIGHT) { "FR" } else { "" },
self.speculated_float_placement_in,
self.speculated_float_placement_out,
self.overflow,
@ -991,50 +991,50 @@ impl BaseFlow {
Some(style) => {
match style.get_box().position {
position::T::absolute | position::T::fixed => {
flags.insert(IS_ABSOLUTELY_POSITIONED);
flags.insert(FlowFlags::IS_ABSOLUTELY_POSITIONED);
let logical_position = style.logical_position();
if logical_position.inline_start == LengthOrPercentageOrAuto::Auto &&
logical_position.inline_end == LengthOrPercentageOrAuto::Auto {
flags.insert(INLINE_POSITION_IS_STATIC);
flags.insert(FlowFlags::INLINE_POSITION_IS_STATIC);
}
if logical_position.block_start == LengthOrPercentageOrAuto::Auto &&
logical_position.block_end == LengthOrPercentageOrAuto::Auto {
flags.insert(BLOCK_POSITION_IS_STATIC);
flags.insert(FlowFlags::BLOCK_POSITION_IS_STATIC);
}
}
_ => flags.insert(BLOCK_POSITION_IS_STATIC | INLINE_POSITION_IS_STATIC),
_ => flags.insert(FlowFlags::BLOCK_POSITION_IS_STATIC | FlowFlags::INLINE_POSITION_IS_STATIC),
}
if force_nonfloated == ForceNonfloatedFlag::FloatIfNecessary {
match style.get_box().float {
float::T::none => {}
float::T::left => flags.insert(FLOATS_LEFT),
float::T::right => flags.insert(FLOATS_RIGHT),
float::T::left => flags.insert(FlowFlags::FLOATS_LEFT),
float::T::right => flags.insert(FlowFlags::FLOATS_RIGHT),
}
}
match style.get_box().clear {
clear::T::none => {}
clear::T::left => flags.insert(CLEARS_LEFT),
clear::T::right => flags.insert(CLEARS_RIGHT),
clear::T::left => flags.insert(FlowFlags::CLEARS_LEFT),
clear::T::right => flags.insert(FlowFlags::CLEARS_RIGHT),
clear::T::both => {
flags.insert(CLEARS_LEFT);
flags.insert(CLEARS_RIGHT);
flags.insert(FlowFlags::CLEARS_LEFT);
flags.insert(FlowFlags::CLEARS_RIGHT);
}
}
if !style.get_counters().counter_reset.0.is_empty() ||
!style.get_counters().counter_increment.0.is_empty() {
flags.insert(AFFECTS_COUNTERS)
flags.insert(FlowFlags::AFFECTS_COUNTERS)
}
}
None => flags.insert(BLOCK_POSITION_IS_STATIC | INLINE_POSITION_IS_STATIC),
None => flags.insert(FlowFlags::BLOCK_POSITION_IS_STATIC | FlowFlags::INLINE_POSITION_IS_STATIC),
}
// New flows start out as fully damaged.
let mut damage = RestyleDamage::rebuild_and_reflow();
damage.remove(RECONSTRUCT_FLOW);
damage.remove(ServoRestyleDamage::RECONSTRUCT_FLOW);
BaseFlow {
restyle_damage: damage,
@ -1071,15 +1071,15 @@ impl BaseFlow {
pub fn update_flags_if_needed(&mut self, style: &ComputedValues) {
// For absolutely-positioned flows, changes to top/bottom/left/right can cause these flags
// to get out of date:
if self.restyle_damage.contains(REFLOW_OUT_OF_FLOW) {
if self.restyle_damage.contains(ServoRestyleDamage::REFLOW_OUT_OF_FLOW) {
// Note: We don't need to check whether IS_ABSOLUTELY_POSITIONED has changed, because
// changes to the 'position' property trigger flow reconstruction.
if self.flags.contains(IS_ABSOLUTELY_POSITIONED) {
if self.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) {
let logical_position = style.logical_position();
self.flags.set(INLINE_POSITION_IS_STATIC,
self.flags.set(FlowFlags::INLINE_POSITION_IS_STATIC,
logical_position.inline_start == LengthOrPercentageOrAuto::Auto &&
logical_position.inline_end == LengthOrPercentageOrAuto::Auto);
self.flags.set(BLOCK_POSITION_IS_STATIC,
self.flags.set(FlowFlags::BLOCK_POSITION_IS_STATIC,
logical_position.block_start == LengthOrPercentageOrAuto::Auto &&
logical_position.block_end == LengthOrPercentageOrAuto::Auto);
}
@ -1090,7 +1090,8 @@ impl BaseFlow {
pub fn clone_with_children(&self, children: FlowList) -> BaseFlow {
BaseFlow {
children: children,
restyle_damage: self.restyle_damage | REPAINT | REFLOW_OUT_OF_FLOW | REFLOW,
restyle_damage: self.restyle_damage | ServoRestyleDamage::REPAINT |
ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW,
parallel: FlowParallelInfo::new(),
floats: self.floats.clone(),
abs_descendants: self.abs_descendants.clone(),
@ -1288,7 +1289,7 @@ impl<'a> ImmutableFlowUtils for &'a Flow {
return Some(base(kid).position.start.b + baseline_offset)
}
}
if kid.is_block_like() && !base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED) {
if kid.is_block_like() && !base(kid).flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) {
if let Some(baseline_offset) = kid.baseline_offset_of_last_line_box_in_flow() {
return Some(base(kid).position.start.b + baseline_offset)
}

Просмотреть файл

@ -19,8 +19,8 @@ use gfx::display_list::{BLUR_INFLATION_FACTOR, OpaqueNode};
use gfx::text::glyph::ByteIndex;
use gfx::text::text_run::{TextRun, TextRunSlice};
use gfx_traits::StackingContextId;
use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFragmentContext, InlineFragmentNodeInfo};
use inline::{InlineMetrics, LAST_FRAGMENT_OF_ELEMENT, LineMetrics};
use inline::{InlineFragmentNodeFlags, InlineFragmentContext, InlineFragmentNodeInfo};
use inline::{InlineMetrics, LineMetrics};
use ipc_channel::ipc::IpcSender;
#[cfg(debug_assertions)]
use layout_debug;
@ -48,7 +48,7 @@ use style::logical_geometry::{Direction, LogicalMargin, LogicalRect, LogicalSize
use style::properties::ComputedValues;
use style::properties::longhands::transform::computed_value::T as TransformList;
use style::selector_parser::RestyleDamage;
use style::servo::restyle_damage::RECONSTRUCT_FLOW;
use style::servo::restyle_damage::ServoRestyleDamage;
use style::str::char_is_whitespace;
use style::values::{self, Either, Auto};
use style::values::computed::{Length, LengthOrPercentage, LengthOrPercentageOrAuto};
@ -533,13 +533,13 @@ pub struct ScannedTextFragmentInfo {
}
bitflags! {
pub flags ScannedTextFlags: u8 {
pub struct ScannedTextFlags: u8 {
/// Whether a line break is required after this fragment if wrapping on newlines (e.g. if
/// `white-space: pre` is in effect).
const REQUIRES_LINE_BREAK_AFTERWARD_IF_WRAPPING_ON_NEWLINES = 0x01,
const REQUIRES_LINE_BREAK_AFTERWARD_IF_WRAPPING_ON_NEWLINES = 0x01;
/// Is this fragment selected?
const SELECTED = 0x02,
const SELECTED = 0x02;
}
}
@ -566,11 +566,11 @@ impl ScannedTextFragmentInfo {
}
pub fn requires_line_break_afterward_if_wrapping_on_newlines(&self) -> bool {
self.flags.contains(REQUIRES_LINE_BREAK_AFTERWARD_IF_WRAPPING_ON_NEWLINES)
self.flags.contains(ScannedTextFlags::REQUIRES_LINE_BREAK_AFTERWARD_IF_WRAPPING_ON_NEWLINES)
}
pub fn selected(&self) -> bool {
self.flags.contains(SELECTED)
self.flags.contains(ScannedTextFlags::SELECTED)
}
}
@ -671,7 +671,7 @@ impl Fragment {
let writing_mode = style.writing_mode;
let mut restyle_damage = node.restyle_damage();
restyle_damage.remove(RECONSTRUCT_FLOW);
restyle_damage.remove(ServoRestyleDamage::RECONSTRUCT_FLOW);
Fragment {
node: node.opaque(),
@ -700,7 +700,7 @@ impl Fragment {
-> Fragment {
let writing_mode = style.writing_mode;
restyle_damage.remove(RECONSTRUCT_FLOW);
restyle_damage.remove(ServoRestyleDamage::RECONSTRUCT_FLOW);
Fragment {
node: node,
@ -753,7 +753,7 @@ impl Fragment {
size);
let mut restyle_damage = RestyleDamage::rebuild_and_reflow();
restyle_damage.remove(RECONSTRUCT_FLOW);
restyle_damage.remove(ServoRestyleDamage::RECONSTRUCT_FLOW);
Fragment {
node: self.node,
@ -818,7 +818,7 @@ impl Fragment {
});
debug_assert!(ellipsis_fragments.len() == 1);
ellipsis_fragment = ellipsis_fragments.fragments.into_iter().next().unwrap();
ellipsis_fragment.flags |= IS_ELLIPSIS;
ellipsis_fragment.flags |= FragmentFlags::IS_ELLIPSIS;
ellipsis_fragment
}
@ -858,35 +858,36 @@ impl Fragment {
QuantitiesIncludedInIntrinsicInlineSizes::all()
}
SpecificFragmentInfo::Table => {
INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED |
INTRINSIC_INLINE_SIZE_INCLUDES_PADDING |
INTRINSIC_INLINE_SIZE_INCLUDES_BORDER
QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED |
QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_PADDING |
QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_BORDER
}
SpecificFragmentInfo::TableCell => {
let base_quantities = INTRINSIC_INLINE_SIZE_INCLUDES_PADDING |
INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED;
let base_quantities = QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_PADDING |
QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED;
if self.style.get_inheritedtable().border_collapse ==
border_collapse::T::separate {
base_quantities | INTRINSIC_INLINE_SIZE_INCLUDES_BORDER
base_quantities | QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_BORDER
} else {
base_quantities
}
}
SpecificFragmentInfo::TableWrapper => {
let base_quantities = INTRINSIC_INLINE_SIZE_INCLUDES_MARGINS |
INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED;
let base_quantities = QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_MARGINS |
QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED;
if self.style.get_inheritedtable().border_collapse ==
border_collapse::T::separate {
base_quantities | INTRINSIC_INLINE_SIZE_INCLUDES_BORDER
base_quantities | QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_BORDER
} else {
base_quantities
}
}
SpecificFragmentInfo::TableRow => {
let base_quantities = INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED;
let base_quantities =
QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED;
if self.style.get_inheritedtable().border_collapse ==
border_collapse::T::separate {
base_quantities | INTRINSIC_INLINE_SIZE_INCLUDES_BORDER
base_quantities | QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_BORDER
} else {
base_quantities
}
@ -914,7 +915,8 @@ impl Fragment {
// FIXME(pcwalton): Percentages should be relative to any definite size per CSS-SIZING.
// This will likely need to be done by pushing down definite sizes during selector
// cascading.
let margin = if flags.contains(INTRINSIC_INLINE_SIZE_INCLUDES_MARGINS) {
let margin = if flags.contains(
QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_MARGINS) {
let margin = style.logical_margin();
(MaybeAuto::from_style(margin.inline_start, Au(0)).specified_or_zero() +
MaybeAuto::from_style(margin.inline_end, Au(0)).specified_or_zero())
@ -925,7 +927,8 @@ impl Fragment {
// FIXME(pcwalton): Percentages should be relative to any definite size per CSS-SIZING.
// This will likely need to be done by pushing down definite sizes during selector
// cascading.
let padding = if flags.contains(INTRINSIC_INLINE_SIZE_INCLUDES_PADDING) {
let padding = if flags.contains(
QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_PADDING) {
let padding = style.logical_padding();
(padding.inline_start.to_used_value(Au(0)) +
padding.inline_end.to_used_value(Au(0)))
@ -933,7 +936,8 @@ impl Fragment {
Au(0)
};
let border = if flags.contains(INTRINSIC_INLINE_SIZE_INCLUDES_BORDER) {
let border = if flags.contains(
QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_BORDER) {
self.border_width().inline_start_end()
} else {
Au(0)
@ -952,7 +956,7 @@ impl Fragment {
let (border_padding, margin) = self.surrounding_intrinsic_inline_size();
let mut specified = Au(0);
if flags.contains(INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED) {
if flags.contains(QuantitiesIncludedInIntrinsicInlineSizes::INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED) {
specified = MaybeAuto::from_style(style.content_inline_size(),
Au(0)).specified_or_zero();
specified = max(style.min_inline_size().to_used_value(Au(0)), specified);
@ -1203,10 +1207,10 @@ impl Fragment {
inline_fragment_context.nodes.iter().fold(style_border_width, |accumulator, node| {
let mut this_border_width =
node.style.border_width_for_writing_mode(writing_mode);
if !node.flags.contains(FIRST_FRAGMENT_OF_ELEMENT) {
if !node.flags.contains(InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT) {
this_border_width.inline_start = Au(0)
}
if !node.flags.contains(LAST_FRAGMENT_OF_ELEMENT) {
if !node.flags.contains(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT) {
this_border_width.inline_end = Au(0)
}
accumulator + this_border_width
@ -1260,13 +1264,15 @@ impl Fragment {
if let Some(ref inline_context) = self.inline_context {
for node in &inline_context.nodes {
let margin = node.style.logical_margin();
let this_inline_start_margin = if !node.flags.contains(FIRST_FRAGMENT_OF_ELEMENT) {
let this_inline_start_margin = if !node.flags.contains(
InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT) {
Au(0)
} else {
MaybeAuto::from_style(margin.inline_start,
containing_block_inline_size).specified_or_zero()
};
let this_inline_end_margin = if !node.flags.contains(LAST_FRAGMENT_OF_ELEMENT) {
let this_inline_end_margin = if!node.flags.contains(
InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT) {
Au(0)
} else {
MaybeAuto::from_style(margin.inline_end,
@ -1339,10 +1345,10 @@ impl Fragment {
let zero_padding = LogicalMargin::zero(writing_mode);
inline_fragment_context.nodes.iter().fold(zero_padding, |accumulator, node| {
let mut padding = model::padding_from_style(&*node.style, Au(0), writing_mode);
if !node.flags.contains(FIRST_FRAGMENT_OF_ELEMENT) {
if !node.flags.contains(InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT) {
padding.inline_start = Au(0)
}
if !node.flags.contains(LAST_FRAGMENT_OF_ELEMENT) {
if !node.flags.contains(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT) {
padding.inline_end = Au(0)
}
accumulator + padding
@ -1584,12 +1590,12 @@ impl Fragment {
let mut border_width = node.style.logical_border_width();
let mut padding = model::padding_from_style(&*node.style, Au(0), writing_mode);
let mut margin = model::specified_margin_from_style(&*node.style, writing_mode);
if !node.flags.contains(FIRST_FRAGMENT_OF_ELEMENT) {
if !node.flags.contains(InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT) {
border_width.inline_start = Au(0);
padding.inline_start = Au(0);
margin.inline_start = Au(0);
}
if !node.flags.contains(LAST_FRAGMENT_OF_ELEMENT) {
if !node.flags.contains(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT) {
border_width.inline_end = Au(0);
padding.inline_end = Au(0);
margin.inline_end = Au(0);
@ -1647,9 +1653,9 @@ impl Fragment {
let mut flags = SplitOptions::empty();
if starts_line {
flags.insert(STARTS_LINE);
flags.insert(SplitOptions::STARTS_LINE);
if self.style().get_inheritedtext().overflow_wrap == overflow_wrap::T::break_word {
flags.insert(RETRY_AT_CHARACTER_BOUNDARIES)
flags.insert(SplitOptions::RETRY_AT_CHARACTER_BOUNDARIES)
}
}
@ -1667,7 +1673,7 @@ impl Fragment {
// Break at character boundaries.
let character_breaking_strategy =
text_fragment_info.run.character_slices_in_range(&text_fragment_info.range);
flags.remove(RETRY_AT_CHARACTER_BOUNDARIES);
flags.remove(SplitOptions::RETRY_AT_CHARACTER_BOUNDARIES);
self.calculate_split_position_using_breaking_strategy(
character_breaking_strategy,
max_inline_size,
@ -1830,12 +1836,12 @@ impl Fragment {
if split_is_empty || overflowing {
// If we've been instructed to retry at character boundaries (probably via
// `overflow-wrap: break-word`), do so.
if flags.contains(RETRY_AT_CHARACTER_BOUNDARIES) {
if flags.contains(SplitOptions::RETRY_AT_CHARACTER_BOUNDARIES) {
let character_breaking_strategy =
text_fragment_info.run
.character_slices_in_range(&text_fragment_info.range);
let mut flags = flags;
flags.remove(RETRY_AT_CHARACTER_BOUNDARIES);
flags.remove(SplitOptions::RETRY_AT_CHARACTER_BOUNDARIES);
return self.calculate_split_position_using_breaking_strategy(
character_breaking_strategy,
max_inline_size,
@ -1844,7 +1850,7 @@ impl Fragment {
// We aren't at the start of the line, so don't overflow. Let inline layout wrap to
// the next line instead.
if !flags.contains(STARTS_LINE) {
if !flags.contains(SplitOptions::STARTS_LINE) {
return None
}
}
@ -1880,7 +1886,7 @@ impl Fragment {
this_info.range_end_including_stripped_whitespace =
other_info.range_end_including_stripped_whitespace;
if other_info.requires_line_break_afterward_if_wrapping_on_newlines() {
this_info.flags.insert(REQUIRES_LINE_BREAK_AFTERWARD_IF_WRAPPING_ON_NEWLINES);
this_info.flags.insert(ScannedTextFlags::REQUIRES_LINE_BREAK_AFTERWARD_IF_WRAPPING_ON_NEWLINES);
}
if other_info.insertion_point.is_some() {
this_info.insertion_point = other_info.insertion_point;
@ -2340,7 +2346,7 @@ impl Fragment {
// side, then we can't merge with the next fragment.
if let Some(ref inline_context) = self.inline_context {
for inline_context_node in inline_context.nodes.iter() {
if !inline_context_node.flags.contains(LAST_FRAGMENT_OF_ELEMENT) {
if !inline_context_node.flags.contains(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT) {
continue
}
if inline_context_node.style.logical_margin().inline_end !=
@ -2361,7 +2367,7 @@ impl Fragment {
// preceding side, then it can't merge with us.
if let Some(ref inline_context) = other.inline_context {
for inline_context_node in inline_context.nodes.iter() {
if !inline_context_node.flags.contains(FIRST_FRAGMENT_OF_ELEMENT) {
if !inline_context_node.flags.contains(InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT) {
continue
}
if inline_context_node.style.logical_margin().inline_start !=
@ -2807,14 +2813,15 @@ impl Fragment {
.zip(inline_context_of_next_fragment.nodes.iter().rev())
{
if !inline_context_node_from_next_fragment.flags.contains(
LAST_FRAGMENT_OF_ELEMENT) {
InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT) {
continue
}
if inline_context_node_from_next_fragment.address !=
inline_context_node_from_this_fragment.address {
continue
}
inline_context_node_from_this_fragment.flags.insert(LAST_FRAGMENT_OF_ELEMENT);
inline_context_node_from_this_fragment.flags.insert(
InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT);
}
}
}
@ -2829,7 +2836,7 @@ impl Fragment {
inline_context_of_this_fragment.nodes.iter_mut().rev())
{
if !inline_context_node_from_prev_fragment.flags.contains(
FIRST_FRAGMENT_OF_ELEMENT) {
InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT) {
continue
}
if inline_context_node_from_prev_fragment.address !=
@ -2837,7 +2844,7 @@ impl Fragment {
continue
}
inline_context_node_from_this_fragment.flags.insert(
FIRST_FRAGMENT_OF_ELEMENT);
InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT);
}
}
}
@ -2975,23 +2982,23 @@ impl fmt::Debug for Fragment {
}
bitflags! {
flags QuantitiesIncludedInIntrinsicInlineSizes: u8 {
const INTRINSIC_INLINE_SIZE_INCLUDES_MARGINS = 0x01,
const INTRINSIC_INLINE_SIZE_INCLUDES_PADDING = 0x02,
const INTRINSIC_INLINE_SIZE_INCLUDES_BORDER = 0x04,
const INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED = 0x08,
struct QuantitiesIncludedInIntrinsicInlineSizes: u8 {
const INTRINSIC_INLINE_SIZE_INCLUDES_MARGINS = 0x01;
const INTRINSIC_INLINE_SIZE_INCLUDES_PADDING = 0x02;
const INTRINSIC_INLINE_SIZE_INCLUDES_BORDER = 0x04;
const INTRINSIC_INLINE_SIZE_INCLUDES_SPECIFIED = 0x08;
}
}
bitflags! {
// Various flags we can use when splitting fragments. See
// `calculate_split_position_using_breaking_strategy()`.
flags SplitOptions: u8 {
struct SplitOptions: u8 {
#[doc = "True if this is the first fragment on the line."]
const STARTS_LINE = 0x01,
const STARTS_LINE = 0x01;
#[doc = "True if we should attempt to split at character boundaries if this split fails. \
This is used to implement `overflow-wrap: break-word`."]
const RETRY_AT_CHARACTER_BOUNDARIES = 0x02,
const RETRY_AT_CHARACTER_BOUNDARIES = 0x02;
}
}
@ -3104,14 +3111,14 @@ impl Overflow {
}
bitflags! {
pub flags FragmentFlags: u8 {
pub struct FragmentFlags: u8 {
// TODO(stshine): find a better name since these flags can also be used for grid item.
/// Whether this fragment represents a child in a row flex container.
const IS_INLINE_FLEX_ITEM = 0b0000_0001,
const IS_INLINE_FLEX_ITEM = 0b0000_0001;
/// Whether this fragment represents a child in a column flex container.
const IS_BLOCK_FLEX_ITEM = 0b0000_0010,
const IS_BLOCK_FLEX_ITEM = 0b0000_0010;
/// Whether this fragment represents the generated text from a text-overflow clip.
const IS_ELLIPSIS = 0b0000_0100,
const IS_ELLIPSIS = 0b0000_0100;
}
}

Просмотреть файл

@ -9,7 +9,7 @@
//! as possible.
use context::{LayoutContext, with_thread_local_font_context};
use flow::{self, AFFECTS_COUNTERS, Flow, HAS_COUNTER_AFFECTING_CHILDREN, ImmutableFlowUtils};
use flow::{self, Flow, FlowFlags, ImmutableFlowUtils};
use fragment::{Fragment, GeneratedContentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo};
use gfx::display_list::OpaqueNode;
use script_layout_interface::wrapper_traits::PseudoElementType;
@ -19,7 +19,7 @@ use style::computed_values::{display, list_style_type};
use style::computed_values::content::ContentItem;
use style::properties::ComputedValues;
use style::selector_parser::RestyleDamage;
use style::servo::restyle_damage::RESOLVE_GENERATED_CONTENT;
use style::servo::restyle_damage::ServoRestyleDamage;
use text::TextRunScanner;
use traversal::InorderFlowTraversal;
@ -131,8 +131,8 @@ impl<'a> InorderFlowTraversal for ResolveGeneratedContent<'a> {
#[inline]
fn should_process_subtree(&mut self, flow: &mut Flow) -> bool {
flow::base(flow).restyle_damage.intersects(RESOLVE_GENERATED_CONTENT) ||
flow::base(flow).flags.intersects(AFFECTS_COUNTERS | HAS_COUNTER_AFFECTING_CHILDREN)
flow::base(flow).restyle_damage.intersects(ServoRestyleDamage::RESOLVE_GENERATED_CONTENT) ||
flow::base(flow).flags.intersects(FlowFlags::AFFECTS_COUNTERS | FlowFlags::HAS_COUNTER_AFFECTING_CHILDREN)
}
}

Просмотреть файл

@ -2,10 +2,10 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use flow::{self, AFFECTS_COUNTERS, Flow, HAS_COUNTER_AFFECTING_CHILDREN, IS_ABSOLUTELY_POSITIONED};
use flow::{self, FlowFlags, Flow};
use style::computed_values::float;
use style::selector_parser::RestyleDamage;
use style::servo::restyle_damage::{REFLOW, RECONSTRUCT_FLOW};
use style::servo::restyle_damage::ServoRestyleDamage;
/// Used in a flow traversal to indicate whether this re-layout should be incremental or not.
#[derive(Clone, Copy, PartialEq)]
@ -15,10 +15,10 @@ pub enum RelayoutMode {
}
bitflags! {
pub flags SpecialRestyleDamage: u8 {
pub struct SpecialRestyleDamage: u8 {
#[doc = "If this flag is set, we need to reflow the entire document. This is more or less a \
temporary hack to deal with cases that we don't handle incrementally yet."]
const REFLOW_ENTIRE_DOCUMENT = 0x01,
const REFLOW_ENTIRE_DOCUMENT = 0x01;
}
}
@ -30,7 +30,7 @@ pub trait LayoutDamageComputation {
impl<'a> LayoutDamageComputation for &'a mut Flow {
fn compute_layout_damage(self) -> SpecialRestyleDamage {
let mut special_damage = SpecialRestyleDamage::empty();
let is_absolutely_positioned = flow::base(self).flags.contains(IS_ABSOLUTELY_POSITIONED);
let is_absolutely_positioned = flow::base(self).flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED);
// In addition to damage, we use this phase to compute whether nodes affect CSS counters.
let mut has_counter_affecting_children = false;
@ -42,7 +42,7 @@ impl<'a> LayoutDamageComputation for &'a mut Flow {
for kid in self_base.children.iter_mut() {
let child_is_absolutely_positioned =
flow::base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED);
flow::base(kid).flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED);
flow::mut_base(kid).restyle_damage.insert(
parent_damage.damage_for_child(is_absolutely_positioned,
child_is_absolutely_positioned));
@ -55,21 +55,21 @@ impl<'a> LayoutDamageComputation for &'a mut Flow {
child_is_absolutely_positioned));
has_counter_affecting_children = has_counter_affecting_children ||
flow::base(kid).flags.intersects(AFFECTS_COUNTERS |
HAS_COUNTER_AFFECTING_CHILDREN);
flow::base(kid).flags.intersects(FlowFlags::AFFECTS_COUNTERS |
FlowFlags::HAS_COUNTER_AFFECTING_CHILDREN);
}
}
let self_base = flow::mut_base(self);
if self_base.flags.float_kind() != float::T::none &&
self_base.restyle_damage.intersects(REFLOW) {
special_damage.insert(REFLOW_ENTIRE_DOCUMENT);
self_base.restyle_damage.intersects(ServoRestyleDamage::REFLOW) {
special_damage.insert(SpecialRestyleDamage::REFLOW_ENTIRE_DOCUMENT);
}
if has_counter_affecting_children {
self_base.flags.insert(HAS_COUNTER_AFFECTING_CHILDREN)
self_base.flags.insert(FlowFlags::HAS_COUNTER_AFFECTING_CHILDREN)
} else {
self_base.flags.remove(HAS_COUNTER_AFFECTING_CHILDREN)
self_base.flags.remove(FlowFlags::HAS_COUNTER_AFFECTING_CHILDREN)
}
special_damage
@ -78,7 +78,7 @@ impl<'a> LayoutDamageComputation for &'a mut Flow {
fn reflow_entire_document(self) {
let self_base = flow::mut_base(self);
self_base.restyle_damage.insert(RestyleDamage::rebuild_and_reflow());
self_base.restyle_damage.remove(RECONSTRUCT_FLOW);
self_base.restyle_damage.remove(ServoRestyleDamage::RECONSTRUCT_FLOW);
for kid in self_base.children.iter_mut() {
kid.reflow_entire_document();
}

Просмотреть файл

@ -13,10 +13,10 @@ use display_list_builder::StackingContextCollectionState;
use euclid::{Point2D, Size2D};
use floats::{FloatKind, Floats, PlacementInfo};
use flow::{self, BaseFlow, Flow, FlowClass, ForceNonfloatedFlag};
use flow::{CONTAINS_TEXT_OR_REPLACED_FRAGMENTS, EarlyAbsolutePositionInfo, OpaqueFlow};
use flow::{FlowFlags, EarlyAbsolutePositionInfo, OpaqueFlow};
use flow_ref::FlowRef;
use fragment::{CoordinateSystem, Fragment, FragmentBorderBoxIterator, Overflow};
use fragment::IS_ELLIPSIS;
use fragment::FragmentFlags;
use fragment::SpecificFragmentInfo;
use gfx::display_list::OpaqueNode;
use gfx::font::FontMetrics;
@ -33,9 +33,10 @@ use std::sync::Arc;
use style::computed_values::{display, overflow_x, position, text_align, text_justify};
use style::computed_values::{vertical_align, white_space};
use style::logical_geometry::{LogicalRect, LogicalSize, WritingMode};
use style::properties::{longhands, ComputedValues};
use style::servo::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, RESOLVE_GENERATED_CONTENT};
use style::properties::ComputedValues;
use style::servo::restyle_damage::ServoRestyleDamage;
use style::values::generics::box_::VerticalAlign;
use style::values::specified::text::TextOverflowSide;
use text;
use traversal::PreorderFlowTraversal;
use unicode_bidi as bidi;
@ -344,7 +345,7 @@ impl LineBreaker {
};
// Do not reflow truncated fragments. Reflow the original fragment only.
let fragment = if fragment.flags.contains(IS_ELLIPSIS) {
let fragment = if fragment.flags.contains(FragmentFlags::IS_ELLIPSIS) {
continue
} else if let SpecificFragmentInfo::TruncatedFragment(info) = fragment.specific {
info.full
@ -664,7 +665,7 @@ impl LineBreaker {
inline_start_fragment.border_padding.inline_end = Au(0);
if let Some(ref mut inline_context) = inline_start_fragment.inline_context {
for node in &mut inline_context.nodes {
node.flags.remove(LAST_FRAGMENT_OF_ELEMENT);
node.flags.remove(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT);
}
}
inline_start_fragment.border_box.size.inline += inline_start_fragment.border_padding.inline_start;
@ -672,7 +673,7 @@ impl LineBreaker {
inline_end_fragment.border_padding.inline_start = Au(0);
if let Some(ref mut inline_context) = inline_end_fragment.inline_context {
for node in &mut inline_context.nodes {
node.flags.remove(FIRST_FRAGMENT_OF_ELEMENT);
node.flags.remove(InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT);
}
}
inline_end_fragment.border_box.size.inline += inline_end_fragment.border_padding.inline_end;
@ -714,15 +715,15 @@ impl LineBreaker {
let ellipsis = match (&fragment.style().get_text().text_overflow.second,
fragment.style().get_box().overflow_x) {
(&longhands::text_overflow::Side::Clip, _) | (_, overflow_x::T::visible) => None,
(&longhands::text_overflow::Side::Ellipsis, _) => {
(&TextOverflowSide::Clip, _) | (_, overflow_x::T::visible) => None,
(&TextOverflowSide::Ellipsis, _) => {
if fragment.margin_box_inline_size() > available_inline_size {
Some("".to_string())
} else {
None
}
},
(&longhands::text_overflow::Side::String(ref string), _) => {
(&TextOverflowSide::String(ref string), _) => {
if fragment.margin_box_inline_size() > available_inline_size {
Some(string.to_string())
} else {
@ -896,7 +897,7 @@ impl InlineFlow {
};
if flow.fragments.fragments.iter().any(Fragment::is_unscanned_generated_content) {
flow.base.restyle_damage.insert(RESOLVE_GENERATED_CONTENT);
flow.base.restyle_damage.insert(ServoRestyleDamage::RESOLVE_GENERATED_CONTENT);
}
flow
@ -1312,7 +1313,7 @@ impl Flow for InlineFlow {
flow::mut_base(kid).floats = Floats::new(writing_mode);
}
self.base.flags.remove(CONTAINS_TEXT_OR_REPLACED_FRAGMENTS);
self.base.flags.remove(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS);
let mut intrinsic_sizes_for_flow = IntrinsicISizesContribution::new();
let mut intrinsic_sizes_for_inline_run = IntrinsicISizesContribution::new();
@ -1371,10 +1372,10 @@ impl Flow for InlineFlow {
}
}
fragment.restyle_damage.remove(BUBBLE_ISIZES);
fragment.restyle_damage.remove(ServoRestyleDamage::BUBBLE_ISIZES);
if fragment.is_text_or_replaced() {
self.base.flags.insert(CONTAINS_TEXT_OR_REPLACED_FRAGMENTS);
self.base.flags.insert(FlowFlags::CONTAINS_TEXT_OR_REPLACED_FRAGMENTS);
}
}
@ -1534,9 +1535,9 @@ impl Flow for InlineFlow {
}
});
self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
self.base.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW);
for fragment in &mut self.fragments.fragments {
fragment.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
fragment.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW);
}
}
@ -1765,9 +1766,9 @@ pub struct InlineFragmentNodeInfo {
}
bitflags! {
pub flags InlineFragmentNodeFlags: u8 {
const FIRST_FRAGMENT_OF_ELEMENT = 0x01,
const LAST_FRAGMENT_OF_ELEMENT = 0x02,
pub struct InlineFragmentNodeFlags: u8 {
const FIRST_FRAGMENT_OF_ELEMENT = 0x01;
const LAST_FRAGMENT_OF_ELEMENT = 0x02;
}
}

Просмотреть файл

@ -22,7 +22,7 @@ use inline::InlineFlow;
use style::computed_values::{list_style_type, position};
use style::logical_geometry::LogicalSize;
use style::properties::ComputedValues;
use style::servo::restyle_damage::RESOLVE_GENERATED_CONTENT;
use style::servo::restyle_damage::ServoRestyleDamage;
#[allow(unsafe_code)]
unsafe impl ::flow::HasBaseFlow for ListItemFlow {}
@ -56,7 +56,7 @@ impl ListItemFlow {
list_style_type::T::square |
list_style_type::T::disclosure_open |
list_style_type::T::disclosure_closed => {}
_ => this.block_flow.base.restyle_damage.insert(RESOLVE_GENERATED_CONTENT),
_ => this.block_flow.base.restyle_damage.insert(ServoRestyleDamage::RESOLVE_GENERATED_CONTENT),
}
}

Просмотреть файл

@ -424,6 +424,14 @@ impl MaybeAuto {
}
}
#[inline]
pub fn to_option(&self) -> Option<Au> {
match *self {
MaybeAuto::Specified(value) => Some(value),
MaybeAuto::Auto => None,
}
}
#[inline]
pub fn specified_or_default(&self, default: Au) -> Au {
match *self {

Просмотреть файл

@ -11,7 +11,7 @@ use euclid::{Point2D, Vector2D, Rect, Size2D};
use flow::{self, Flow};
use fragment::{Fragment, FragmentBorderBoxIterator, SpecificFragmentInfo};
use gfx::display_list::{DisplayList, OpaqueNode, ScrollOffsetMap};
use inline::LAST_FRAGMENT_OF_ELEMENT;
use inline::InlineFragmentNodeFlags;
use ipc_channel::ipc::IpcSender;
use msg::constellation_msg::PipelineId;
use opaque_node::OpaqueNodeMethods;
@ -562,7 +562,7 @@ impl FragmentBorderBoxIterator for ParentOffsetBorderBoxIterator {
},
}
if node.flags.contains(LAST_FRAGMENT_OF_ELEMENT) {
if node.flags.contains(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT) {
self.has_processed_node = true;
}
} else if self.node_offset_box.is_none() {

Просмотреть файл

@ -9,12 +9,12 @@ use context::LayoutContext;
use display_list_builder::{DisplayListBuildState, StackingContextCollectionState};
use euclid::{Point2D, Vector2D};
use floats::SpeculatedFloatPlacement;
use flow::{self, Flow, ImmutableFlowUtils, IS_ABSOLUTELY_POSITIONED};
use flow::{self, Flow, ImmutableFlowUtils, FlowFlags};
use fragment::{FragmentBorderBoxIterator, CoordinateSystem};
use generated_content::ResolveGeneratedContent;
use incremental::RelayoutMode;
use servo_config::opts;
use style::servo::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW, STORE_OVERFLOW};
use style::servo::restyle_damage::ServoRestyleDamage;
use traversal::{AssignBSizes, AssignISizes, BubbleISizes, BuildDisplayList};
use traversal::{InorderFlowTraversal, PostorderFlowTraversal, PreorderFlowTraversal};
@ -33,7 +33,7 @@ pub fn reflow(root: &mut Flow, layout_context: &LayoutContext, relayout_mode: Re
if relayout_mode == RelayoutMode::Force {
flow::mut_base(flow)
.restyle_damage
.insert(REFLOW_OUT_OF_FLOW | REFLOW);
.insert(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW);
}
if assign_inline_sizes.should_process(flow) {
@ -112,7 +112,7 @@ pub fn iterate_through_flow_tree_fragment_border_boxes(root: &mut Flow, iterator
}
pub fn store_overflow(layout_context: &LayoutContext, flow: &mut Flow) {
if !flow::base(flow).restyle_damage.contains(STORE_OVERFLOW) {
if !flow::base(flow).restyle_damage.contains(ServoRestyleDamage::STORE_OVERFLOW) {
return;
}
@ -124,20 +124,20 @@ pub fn store_overflow(layout_context: &LayoutContext, flow: &mut Flow) {
flow::mut_base(flow)
.restyle_damage
.remove(STORE_OVERFLOW);
.remove(ServoRestyleDamage::STORE_OVERFLOW);
}
/// Guesses how much inline size will be taken up by floats on the left and right sides of the
/// given flow. This is needed to speculatively calculate the inline sizes of block formatting
/// contexts. The speculation typically succeeds, but if it doesn't we have to lay it out again.
pub fn guess_float_placement(flow: &mut Flow) {
if !flow::base(flow).restyle_damage.intersects(REFLOW) {
if !flow::base(flow).restyle_damage.intersects(ServoRestyleDamage::REFLOW) {
return;
}
let mut floats_in = SpeculatedFloatPlacement::compute_floats_in_for_first_child(flow);
for kid in flow::mut_base(flow).child_iter_mut() {
if flow::base(kid).flags.contains(IS_ABSOLUTELY_POSITIONED) {
if flow::base(kid).flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) {
// Do not propagate floats in or out, but do propogate between kids.
guess_float_placement(kid);
} else {

Просмотреть файл

@ -11,8 +11,7 @@ use block::{BlockFlow, CandidateBSizeIterator, ISizeAndMarginsComputer};
use block::{ISizeConstraintInput, ISizeConstraintSolution};
use context::LayoutContext;
use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode};
use display_list_builder::{DisplayListBuildState, NEVER_CREATES_STACKING_CONTEXT};
use display_list_builder::StackingContextCollectionState;
use display_list_builder::{DisplayListBuildState, StackingContextCollectionFlags, StackingContextCollectionState};
use euclid::Point2D;
use flow;
use flow::{BaseFlow, EarlyAbsolutePositionInfo, Flow, FlowClass, ImmutableFlowUtils, OpaqueFlow};
@ -27,7 +26,7 @@ use style::computed_values::{border_collapse, border_spacing, table_layout};
use style::context::SharedStyleContext;
use style::logical_geometry::LogicalSize;
use style::properties::ComputedValues;
use style::servo::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW};
use style::servo::restyle_damage::ServoRestyleDamage;
use style::values::CSSFloat;
use style::values::computed::LengthOrPercentageOrAuto;
use table_row::{self, CellIntrinsicInlineSize, CollapsedBorder, CollapsedBorderProvenance};
@ -505,7 +504,8 @@ impl Flow for TableFlow {
fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) {
// Stacking contexts are collected by the table wrapper.
self.block_flow.collect_stacking_contexts_for_block(state, NEVER_CREATES_STACKING_CONTEXT);
self.block_flow.collect_stacking_contexts_for_block(state,
StackingContextCollectionFlags::NEVER_CREATES_STACKING_CONTEXT);
}
fn repair_style(&mut self, new_style: &::ServoArc<ComputedValues>) {
@ -735,7 +735,7 @@ impl TableLikeFlow for BlockFlow {
debug_assert!(self.fragment.style.get_inheritedtable().border_collapse ==
border_collapse::T::separate || block_direction_spacing == Au(0));
if self.base.restyle_damage.contains(REFLOW) {
if self.base.restyle_damage.contains(ServoRestyleDamage::REFLOW) {
// Our current border-box position.
let block_start_border_padding = self.fragment.border_padding.block_start;
let mut current_block_offset = block_start_border_padding;
@ -809,7 +809,7 @@ impl TableLikeFlow for BlockFlow {
}
}
self.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
self.base.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW);
}
}

Просмотреть файл

@ -13,7 +13,7 @@ use display_list_builder::{BlockFlowDisplayListBuilding, BorderPaintingMode};
use display_list_builder::{DisplayListBuildState, StackingContextCollectionFlags};
use display_list_builder::StackingContextCollectionState;
use euclid::{Point2D, Rect, SideOffsets2D, Size2D};
use flow::{self, Flow, FlowClass, IS_ABSOLUTELY_POSITIONED, OpaqueFlow};
use flow::{self, Flow, FlowClass, FlowFlags, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use gfx_traits::print_tree::PrintTree;
use layout_debug;
@ -102,7 +102,7 @@ impl TableCellFlow {
let mut extents = None;
for kid in flow::base(self).children.iter() {
let kid_base = flow::base(kid);
if kid_base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
if kid_base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) {
continue
}
let start = kid_base.position.start.b -
@ -144,7 +144,7 @@ impl TableCellFlow {
for kid in flow::mut_base(self).children.iter_mut() {
let kid_base = flow::mut_base(kid);
if !kid_base.flags.contains(IS_ABSOLUTELY_POSITIONED) {
if !kid_base.flags.contains(FlowFlags::IS_ABSOLUTELY_POSITIONED) {
kid_base.position.start.b += offset
}
}

Просмотреть файл

@ -26,7 +26,7 @@ use std::iter::{Enumerate, IntoIterator, Peekable};
use style::computed_values::{border_collapse, border_spacing, border_top_style};
use style::logical_geometry::{LogicalSize, PhysicalSide, WritingMode};
use style::properties::ComputedValues;
use style::servo::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW};
use style::servo::restyle_damage::ServoRestyleDamage;
use style::values::computed::{Color, LengthOrPercentageOrAuto};
use table::{ColumnComputedInlineSize, ColumnIntrinsicInlineSize, InternalTable, VecExt};
use table_cell::{CollapsedBordersForCell, TableCellFlow};
@ -114,7 +114,7 @@ impl TableRowFlow {
/// methods
#[inline(always)]
fn assign_block_size_table_row_base(&mut self, layout_context: &LayoutContext) {
if self.block_flow.base.restyle_damage.contains(REFLOW) {
if self.block_flow.base.restyle_damage.contains(ServoRestyleDamage::REFLOW) {
// Per CSS 2.1 § 17.5.3, find max_y = max(computed `block-size`, minimum block-size of
// all cells).
let mut max_block_size = Au(0);
@ -195,7 +195,7 @@ impl TableRowFlow {
}
}
self.block_flow.base.restyle_damage.remove(REFLOW_OUT_OF_FLOW | REFLOW);
self.block_flow.base.restyle_damage.remove(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW);
}
pub fn populate_collapsed_border_spacing<'a, I>(

Просмотреть файл

@ -10,7 +10,7 @@ use app_units::Au;
use block::{BlockFlow, ISizeAndMarginsComputer};
use context::LayoutContext;
use display_list_builder::{BlockFlowDisplayListBuilding, DisplayListBuildState};
use display_list_builder::{NEVER_CREATES_CONTAINING_BLOCK, StackingContextCollectionState};
use display_list_builder::{StackingContextCollectionFlags, StackingContextCollectionState};
use euclid::Point2D;
use flow::{Flow, FlowClass, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
@ -184,7 +184,8 @@ impl Flow for TableRowGroupFlow {
}
fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) {
self.block_flow.collect_stacking_contexts_for_block(state, NEVER_CREATES_CONTAINING_BLOCK);
self.block_flow.collect_stacking_contexts_for_block(state,
StackingContextCollectionFlags::NEVER_CREATES_CONTAINING_BLOCK);
}
fn repair_style(&mut self, new_style: &::ServoArc<ComputedValues>) {

Просмотреть файл

@ -17,12 +17,11 @@ use app_units::Au;
use block::{AbsoluteNonReplaced, BlockFlow, FloatNonReplaced, ISizeAndMarginsComputer, ISizeConstraintInput};
use block::{ISizeConstraintSolution, MarginsMayCollapseFlag};
use context::LayoutContext;
use display_list_builder::{BlockFlowDisplayListBuilding, DisplayListBuildState};
use display_list_builder::{NEVER_CREATES_CLIP_SCROLL_NODE, NEVER_CREATES_CONTAINING_BLOCK};
use display_list_builder::{BlockFlowDisplayListBuilding, DisplayListBuildState, StackingContextCollectionFlags};
use display_list_builder::StackingContextCollectionState;
use euclid::Point2D;
use floats::FloatKind;
use flow::{Flow, FlowClass, ImmutableFlowUtils, INLINE_POSITION_IS_STATIC, OpaqueFlow};
use flow::{Flow, FlowClass, ImmutableFlowUtils, FlowFlags, OpaqueFlow};
use fragment::{Fragment, FragmentBorderBoxIterator, Overflow};
use gfx_traits::print_tree::PrintTree;
use model::MaybeAuto;
@ -256,7 +255,7 @@ impl TableWrapperFlow {
return
}
if !self.block_flow.base.flags.contains(INLINE_POSITION_IS_STATIC) {
if !self.block_flow.base.flags.contains(FlowFlags::INLINE_POSITION_IS_STATIC) {
let inline_size_computer = AbsoluteTable {
minimum_width_of_all_columns: minimum_width_of_all_columns,
preferred_width_of_all_columns: preferred_width_of_all_columns,
@ -464,7 +463,9 @@ impl Flow for TableWrapperFlow {
fn collect_stacking_contexts(&mut self, state: &mut StackingContextCollectionState) {
self.block_flow.collect_stacking_contexts_for_block(
state, NEVER_CREATES_CONTAINING_BLOCK | NEVER_CREATES_CLIP_SCROLL_NODE);
state,
StackingContextCollectionFlags::NEVER_CREATES_CONTAINING_BLOCK |
StackingContextCollectionFlags::NEVER_CREATES_CLIP_SCROLL_NODE);
}
fn repair_style(&mut self, new_style: &::ServoArc<ComputedValues>) {

Просмотреть файл

@ -7,15 +7,14 @@
#![deny(unsafe_code)]
use app_units::Au;
use fragment::{Fragment, REQUIRES_LINE_BREAK_AFTERWARD_IF_WRAPPING_ON_NEWLINES, ScannedTextFlags};
use fragment::{SELECTED, ScannedTextFragmentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo};
use gfx::font::{DISABLE_KERNING_SHAPING_FLAG, FontMetrics, IGNORE_LIGATURES_SHAPING_FLAG};
use gfx::font::{KEEP_ALL_FLAG, RTL_FLAG, RunMetrics, ShapingFlags, ShapingOptions};
use fragment::{Fragment, ScannedTextFlags};
use fragment::{ScannedTextFragmentInfo, SpecificFragmentInfo, UnscannedTextFragmentInfo};
use gfx::font::{FontMetrics, RunMetrics, ShapingFlags, ShapingOptions};
use gfx::font_context::FontContext;
use gfx::text::glyph::ByteIndex;
use gfx::text::text_run::TextRun;
use gfx::text::util::{self, CompressionMode};
use inline::{FIRST_FRAGMENT_OF_ELEMENT, InlineFragments, LAST_FRAGMENT_OF_ELEMENT};
use inline::{InlineFragmentNodeFlags, InlineFragments};
use linked_list::split_off_head;
use ordered_float::NotNaN;
use range::Range;
@ -291,15 +290,15 @@ impl TextRunScanner {
let mut flags = ShapingFlags::empty();
if let Some(v) = letter_spacing.value() {
if v.px() != 0. {
flags.insert(IGNORE_LIGATURES_SHAPING_FLAG);
flags.insert(ShapingFlags::IGNORE_LIGATURES_SHAPING_FLAG);
}
}
if text_rendering == text_rendering::T::optimizespeed {
flags.insert(IGNORE_LIGATURES_SHAPING_FLAG);
flags.insert(DISABLE_KERNING_SHAPING_FLAG)
flags.insert(ShapingFlags::IGNORE_LIGATURES_SHAPING_FLAG);
flags.insert(ShapingFlags::DISABLE_KERNING_SHAPING_FLAG)
}
if word_break == word_break::T::keep_all {
flags.insert(KEEP_ALL_FLAG);
flags.insert(ShapingFlags::KEEP_ALL_FLAG);
}
let options = ShapingOptions {
letter_spacing: letter_spacing.value().cloned().map(Au::from),
@ -313,7 +312,7 @@ impl TextRunScanner {
let mut options = options;
options.script = run_info.script;
if run_info.bidi_level.is_rtl() {
options.flags.insert(RTL_FLAG);
options.flags.insert(ShapingFlags::RTL_FLAG);
}
let mut font = fontgroup.fonts.get(run_info.font_index).unwrap().borrow_mut();
ScannedTextRun {
@ -364,11 +363,11 @@ impl TextRunScanner {
if requires_line_break_afterward_if_wrapping_on_newlines {
byte_range.extend_by(ByteIndex(-1)); // Trim the '\n'
flags.insert(REQUIRES_LINE_BREAK_AFTERWARD_IF_WRAPPING_ON_NEWLINES);
flags.insert(ScannedTextFlags::REQUIRES_LINE_BREAK_AFTERWARD_IF_WRAPPING_ON_NEWLINES);
}
if mapping.selected {
flags.insert(SELECTED);
flags.insert(ScannedTextFlags::SELECTED);
}
let insertion_point = if mapping.contains_insertion_point(scanned_run.insertion_point) {
@ -402,10 +401,10 @@ impl TextRunScanner {
if let Some(ref mut context) = new_fragment.inline_context {
for node in &mut context.nodes {
if !is_last_mapping_of_this_old_fragment {
node.flags.remove(LAST_FRAGMENT_OF_ELEMENT);
node.flags.remove(InlineFragmentNodeFlags::LAST_FRAGMENT_OF_ELEMENT);
}
if !is_first_mapping_of_this_old_fragment {
node.flags.remove(FIRST_FRAGMENT_OF_ELEMENT);
node.flags.remove(InlineFragmentNodeFlags::FIRST_FRAGMENT_OF_ELEMENT);
}
}
}

Просмотреть файл

@ -7,14 +7,14 @@
use construct::FlowConstructor;
use context::LayoutContext;
use display_list_builder::DisplayListBuildState;
use flow::{self, CAN_BE_FRAGMENTED, Flow, ImmutableFlowUtils};
use flow::{self, FlowFlags, Flow, ImmutableFlowUtils};
use script_layout_interface::wrapper_traits::{LayoutNode, ThreadSafeLayoutNode};
use servo_config::opts;
use style::context::{SharedStyleContext, StyleContext};
use style::data::ElementData;
use style::dom::{NodeInfo, TElement, TNode};
use style::selector_parser::RestyleDamage;
use style::servo::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, REPOSITION};
use style::servo::restyle_damage::ServoRestyleDamage;
use style::traversal::{DomTraversal, recalc_style_at};
use style::traversal::PerLevelTraversalData;
use wrapper::{GetRawData, LayoutNodeLayoutData};
@ -209,7 +209,7 @@ fn construct_flows_at<N>(context: &LayoutContext, node: N)
}
}
tnode.mutate_layout_data().unwrap().flags.insert(::data::HAS_BEEN_TRAVERSED);
tnode.mutate_layout_data().unwrap().flags.insert(::data::LayoutDataFlags::HAS_BEEN_TRAVERSED);
}
if let Some(el) = node.as_element() {
@ -227,12 +227,12 @@ impl<'a> PostorderFlowTraversal for BubbleISizes<'a> {
#[inline]
fn process(&self, flow: &mut Flow) {
flow.bubble_inline_sizes();
flow::mut_base(flow).restyle_damage.remove(BUBBLE_ISIZES);
flow::mut_base(flow).restyle_damage.remove(ServoRestyleDamage::BUBBLE_ISIZES);
}
#[inline]
fn should_process(&self, flow: &mut Flow) -> bool {
flow::base(flow).restyle_damage.contains(BUBBLE_ISIZES)
flow::base(flow).restyle_damage.contains(ServoRestyleDamage::BUBBLE_ISIZES)
}
}
@ -250,7 +250,7 @@ impl<'a> PreorderFlowTraversal for AssignISizes<'a> {
#[inline]
fn should_process(&self, flow: &mut Flow) -> bool {
flow::base(flow).restyle_damage.intersects(REFLOW_OUT_OF_FLOW | REFLOW)
flow::base(flow).restyle_damage.intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW)
}
}
@ -280,9 +280,9 @@ impl<'a> PostorderFlowTraversal for AssignBSizes<'a> {
#[inline]
fn should_process(&self, flow: &mut Flow) -> bool {
let base = flow::base(flow);
base.restyle_damage.intersects(REFLOW_OUT_OF_FLOW | REFLOW) &&
base.restyle_damage.intersects(ServoRestyleDamage::REFLOW_OUT_OF_FLOW | ServoRestyleDamage::REFLOW) &&
// The fragmentation countainer is responsible for calling Flow::fragment recursively
!base.flags.contains(CAN_BE_FRAGMENTED)
!base.flags.contains(FlowFlags::CAN_BE_FRAGMENTED)
}
}
@ -293,13 +293,13 @@ pub struct ComputeStackingRelativePositions<'a> {
impl<'a> PreorderFlowTraversal for ComputeStackingRelativePositions<'a> {
#[inline]
fn should_process_subtree(&self, flow: &mut Flow) -> bool {
flow::base(flow).restyle_damage.contains(REPOSITION)
flow::base(flow).restyle_damage.contains(ServoRestyleDamage::REPOSITION)
}
#[inline]
fn process(&self, flow: &mut Flow) {
flow.compute_stacking_relative_position(self.layout_context);
flow::mut_base(flow).restyle_damage.remove(REPOSITION)
flow::mut_base(flow).restyle_damage.remove(ServoRestyleDamage::REPOSITION)
}
}
@ -317,7 +317,7 @@ impl<'a> BuildDisplayList<'a> {
self.state.current_clipping_and_scrolling = flow.clipping_and_scrolling();
flow.build_display_list(&mut self.state);
flow::mut_base(flow).restyle_damage.remove(REPAINT);
flow::mut_base(flow).restyle_damage.remove(ServoRestyleDamage::REPAINT);
for kid in flow::child_iter_mut(flow) {
self.traverse(kid);

Просмотреть файл

@ -540,10 +540,16 @@ impl WebRenderDisplayItemConverter for DisplayItem {
scroll_sensitivity
)
}
ClipScrollNodeType::StickyFrame(sticky_frame_info) => {
ClipScrollNodeType::StickyFrame(ref sticky_data) => {
// TODO: Add define_sticky_frame_with_parent to WebRender.
builder.push_clip_id(parent_id);
let id = builder.define_sticky_frame(node.id, item_rect, sticky_frame_info);
let id = builder.define_sticky_frame(
node.id,
item_rect,
sticky_data.margins,
sticky_data.vertical_offset_bounds,
sticky_data.horizontal_offset_bounds,
);
builder.pop_clip_id();
id
}

Просмотреть файл

@ -140,7 +140,7 @@ impl<T: ThreadSafeLayoutNode> ThreadSafeLayoutNodeHelpers for T {
let damage = {
let data = node.get_raw_data().unwrap();
if !data.layout_data.borrow().flags.contains(::data::HAS_BEEN_TRAVERSED) {
if !data.layout_data.borrow().flags.contains(::data::LayoutDataFlags::HAS_BEEN_TRAVERSED) {
// We're reflowing a node that was styled for the first time and
// has never been visited by layout. Return rebuild_and_reflow,
// because that's what the code expects.

Просмотреть файл

@ -38,13 +38,11 @@ use layout::wrapper::GetRawData;
use msg::constellation_msg::{BrowsingContextId, PipelineId};
use nonzero::NonZero;
use range::Range;
use script::layout_exports::{CAN_BE_FRAGMENTED, HAS_DIRTY_DESCENDANTS, IS_IN_DOC};
use script::layout_exports::{CharacterDataTypeId, ElementTypeId, HTMLElementTypeId, NodeTypeId};
use script::layout_exports::{Document, Element, Node, Text};
use script::layout_exports::{HANDLED_SNAPSHOT, HAS_SNAPSHOT};
use script::layout_exports::{LayoutCharacterDataHelpers, LayoutDocumentHelpers};
use script::layout_exports::{LayoutElementHelpers, LayoutNodeHelpers, RawLayoutElementHelpers};
use script::layout_exports::LayoutDom;
use script::layout_exports::{LayoutElementHelpers, LayoutNodeHelpers, LayoutDom, RawLayoutElementHelpers};
use script::layout_exports::NodeFlags;
use script::layout_exports::PendingRestyle;
use script_layout_interface::{HTMLCanvasData, LayoutNodeType, SVGSVGData, TrustedNodeAddress};
use script_layout_interface::{OpaqueStyleAndLayoutData, StyleData};
@ -212,11 +210,11 @@ impl<'ln> TNode for ServoLayoutNode<'ln> {
}
fn can_be_fragmented(&self) -> bool {
unsafe { self.node.get_flag(CAN_BE_FRAGMENTED) }
unsafe { self.node.get_flag(NodeFlags::CAN_BE_FRAGMENTED) }
}
unsafe fn set_can_be_fragmented(&self, value: bool) {
self.node.set_flag(CAN_BE_FRAGMENTED, value)
self.node.set_flag(NodeFlags::CAN_BE_FRAGMENTED, value)
}
}
@ -403,28 +401,28 @@ impl<'le> TElement for ServoLayoutElement<'le> {
}
fn has_dirty_descendants(&self) -> bool {
unsafe { self.as_node().node.get_flag(HAS_DIRTY_DESCENDANTS) }
unsafe { self.as_node().node.get_flag(NodeFlags::HAS_DIRTY_DESCENDANTS) }
}
fn has_snapshot(&self) -> bool {
unsafe { self.as_node().node.get_flag(HAS_SNAPSHOT) }
unsafe { self.as_node().node.get_flag(NodeFlags::HAS_SNAPSHOT) }
}
fn handled_snapshot(&self) -> bool {
unsafe { self.as_node().node.get_flag(HANDLED_SNAPSHOT) }
unsafe { self.as_node().node.get_flag(NodeFlags::HANDLED_SNAPSHOT) }
}
unsafe fn set_handled_snapshot(&self) {
self.as_node().node.set_flag(HANDLED_SNAPSHOT, true);
self.as_node().node.set_flag(NodeFlags::HANDLED_SNAPSHOT, true);
}
unsafe fn set_dirty_descendants(&self) {
debug_assert!(self.as_node().node.get_flag(IS_IN_DOC));
self.as_node().node.set_flag(HAS_DIRTY_DESCENDANTS, true)
debug_assert!(self.as_node().node.get_flag(NodeFlags::IS_IN_DOC));
self.as_node().node.set_flag(NodeFlags::HAS_DIRTY_DESCENDANTS, true)
}
unsafe fn unset_dirty_descendants(&self) {
self.as_node().node.set_flag(HAS_DIRTY_DESCENDANTS, false)
self.as_node().node.set_flag(NodeFlags::HAS_DIRTY_DESCENDANTS, false)
}
fn store_children_to_process(&self, n: isize) {
@ -583,11 +581,11 @@ impl<'le> ServoLayoutElement<'le> {
}
pub unsafe fn unset_snapshot_flags(&self) {
self.as_node().node.set_flag(HAS_SNAPSHOT | HANDLED_SNAPSHOT, false);
self.as_node().node.set_flag(NodeFlags::HAS_SNAPSHOT | NodeFlags::HANDLED_SNAPSHOT, false);
}
pub unsafe fn set_has_snapshot(&self) {
self.as_node().node.set_flag(HAS_SNAPSHOT, true);
self.as_node().node.set_flag(NodeFlags::HAS_SNAPSHOT, true);
}
pub unsafe fn note_dirty_descendant(&self) {

Просмотреть файл

@ -72,7 +72,7 @@ use layout::context::malloc_size_of_persistent_local_context;
use layout::display_list_builder::ToGfxColor;
use layout::flow::{self, Flow, ImmutableFlowUtils, MutableOwnedFlowUtils};
use layout::flow_ref::FlowRef;
use layout::incremental::{LayoutDamageComputation, REFLOW_ENTIRE_DOCUMENT, RelayoutMode};
use layout::incremental::{LayoutDamageComputation, RelayoutMode, SpecialRestyleDamage};
use layout::layout_debug;
use layout::parallel;
use layout::query::{LayoutRPCImpl, LayoutThreadData, process_content_box_request, process_content_boxes_request};
@ -132,11 +132,11 @@ use style::logical_geometry::LogicalPoint;
use style::media_queries::{Device, MediaList, MediaType};
use style::properties::PropertyId;
use style::selector_parser::SnapshotMap;
use style::servo::restyle_damage::{REFLOW, REFLOW_OUT_OF_FLOW, REPAINT, REPOSITION, STORE_OVERFLOW};
use style::servo::restyle_damage::ServoRestyleDamage;
use style::shared_lock::{SharedRwLock, SharedRwLockReadGuard, StylesheetGuards};
use style::stylesheets::{Origin, Stylesheet, DocumentStyleSheet, StylesheetInDocument, UserAgentStylesheets};
use style::stylist::Stylist;
use style::thread_state;
use style::thread_state::{self, ThreadState};
use style::timer::Timer;
use style::traversal::DomTraversal;
use style::traversal_flags::TraversalFlags;
@ -285,7 +285,7 @@ impl LayoutThreadFactory for LayoutThread {
layout_threads: usize,
paint_time_metrics: PaintTimeMetrics) {
thread::Builder::new().name(format!("LayoutThread {:?}", id)).spawn(move || {
thread_state::initialize(thread_state::LAYOUT);
thread_state::initialize(ThreadState::LAYOUT);
// In order to get accurate crash reports, we install the top-level bc id.
TopLevelBrowsingContextId::install(top_level_browsing_context_id);
@ -971,7 +971,7 @@ impl LayoutThread {
let traversal = ComputeStackingRelativePositions { layout_context: layout_context };
traversal.traverse(layout_root);
if flow::base(layout_root).restyle_damage.contains(REPAINT) ||
if flow::base(layout_root).restyle_damage.contains(ServoRestyleDamage::REPAINT) ||
rw_data.display_list.is_none() {
if reflow_goal.needs_display_list() {
let mut build_state =
@ -1541,7 +1541,7 @@ impl LayoutThread {
// that are needed in both incremental and non-incremental traversals.
let damage = FlowRef::deref_mut(root_flow).compute_layout_damage();
if opts::get().nonincremental_layout || damage.contains(REFLOW_ENTIRE_DOCUMENT) {
if opts::get().nonincremental_layout || damage.contains(SpecialRestyleDamage::REFLOW_ENTIRE_DOCUMENT) {
FlowRef::deref_mut(root_flow).reflow_entire_document()
}
});
@ -1564,7 +1564,8 @@ impl LayoutThread {
// Perform the primary layout passes over the flow tree to compute the locations of all
// the boxes.
if flow::base(&**root_flow).restyle_damage.intersects(REFLOW | REFLOW_OUT_OF_FLOW) {
if flow::base(&**root_flow).restyle_damage.intersects(ServoRestyleDamage::REFLOW |
ServoRestyleDamage::REFLOW_OUT_OF_FLOW) {
profile(time::ProfilerCategory::LayoutMain,
self.profiler_metadata(),
self.time_profiler_chan.clone(),
@ -1631,7 +1632,8 @@ impl LayoutThread {
debug!("reflowing all nodes!");
flow::mut_base(flow)
.restyle_damage
.insert(REPAINT | STORE_OVERFLOW | REFLOW | REPOSITION);
.insert(ServoRestyleDamage::REPAINT | ServoRestyleDamage::STORE_OVERFLOW |
ServoRestyleDamage::REFLOW | ServoRestyleDamage::REPOSITION);
for child in flow::child_iter_mut(flow) {
LayoutThread::reflow_all_nodes(child);

Просмотреть файл

@ -728,7 +728,7 @@ malloc_size_of_is_0!(webrender_api::ScrollPolicy);
#[cfg(feature = "servo")]
malloc_size_of_is_0!(webrender_api::ScrollSensitivity);
#[cfg(feature = "servo")]
malloc_size_of_is_0!(webrender_api::StickySideConstraint);
malloc_size_of_is_0!(webrender_api::StickyOffsetBounds);
#[cfg(feature = "servo")]
malloc_size_of_is_0!(webrender_api::TransformStyle);

Просмотреть файл

@ -13,7 +13,7 @@ path = "lib.rs"
unstable = ["nonzero/unstable"]
[dependencies]
bitflags = "0.7"
bitflags = "1.0"
malloc_size_of = { path = "../malloc_size_of" }
malloc_size_of_derive = { path = "../malloc_size_of_derive" }
nonzero = {path = "../nonzero"}

Просмотреть файл

@ -148,12 +148,12 @@ pub enum Key {
bitflags! {
#[derive(Deserialize, Serialize)]
pub flags KeyModifiers: u8 {
const NONE = 0x00,
const SHIFT = 0x01,
const CONTROL = 0x02,
const ALT = 0x04,
const SUPER = 0x08,
pub struct KeyModifiers: u8 {
const NONE = 0x00;
const SHIFT = 0x01;
const CONTROL = 0x02;
const ALT = 0x04;
const SUPER = 0x08;
}
}

Просмотреть файл

@ -28,7 +28,7 @@ tinyfiledialogs = "2.5.9"
app_units = "0.5"
audio-video-metadata = "0.1.4"
base64 = "0.6"
bitflags = "0.7"
bitflags = "1.0"
bluetooth_traits = {path = "../bluetooth_traits"}
byteorder = "1.0"
canvas_traits = {path = "../canvas_traits"}

Просмотреть файл

@ -2,9 +2,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use devtools_traits::{AutoMargins, CONSOLE_API, CachedConsoleMessage, CachedConsoleMessageTypes};
use devtools_traits::{AutoMargins, CachedConsoleMessage, CachedConsoleMessageTypes};
use devtools_traits::{ComputedNodeLayout, ConsoleAPI, PageError};
use devtools_traits::{EvaluateJSReply, Modification, NodeInfo, PAGE_ERROR, TimelineMarker};
use devtools_traits::{EvaluateJSReply, Modification, NodeInfo, TimelineMarker};
use devtools_traits::TimelineMarkerType;
use dom::bindings::codegen::Bindings::CSSStyleDeclarationBinding::CSSStyleDeclarationMethods;
use dom::bindings::codegen::Bindings::DOMRectBinding::DOMRectMethods;
@ -168,7 +168,7 @@ pub fn handle_get_cached_messages(_pipeline_id: PipelineId,
reply: IpcSender<Vec<CachedConsoleMessage>>) {
// TODO: check the messageTypes against a global Cache for console messages and page exceptions
let mut messages = Vec::new();
if message_types.contains(PAGE_ERROR) {
if message_types.contains(CachedConsoleMessageTypes::PAGE_ERROR) {
// TODO: make script error reporter pass all reported errors
// to devtools and cache them for returning here.
let msg = PageError {
@ -188,7 +188,7 @@ pub fn handle_get_cached_messages(_pipeline_id: PipelineId,
};
messages.push(CachedConsoleMessage::PageError(msg));
}
if message_types.contains(CONSOLE_API) {
if message_types.contains(CachedConsoleMessageTypes::CONSOLE_API) {
// TODO: do for real
let msg = ConsoleAPI {
type_: "ConsoleAPI".to_owned(),

Просмотреть файл

@ -5,7 +5,7 @@
//! A shareable mutable container for the DOM.
use std::cell::{BorrowError, BorrowMutError, Ref, RefCell, RefMut};
use style::thread_state;
use style::thread_state::{self, ThreadState};
/// A mutable field in the DOM.
///
@ -45,7 +45,7 @@ impl<T> DomRefCell<T> {
///
#[allow(unsafe_code)]
pub unsafe fn borrow_for_script_deallocation(&self) -> &mut T {
debug_assert!(thread_state::get().contains(thread_state::SCRIPT));
debug_assert!(thread_state::get().contains(ThreadState::SCRIPT));
&mut *self.value.as_ptr()
}

Просмотреть файл

@ -2039,7 +2039,7 @@ DOMClass {
interface_chain: [ %s ],
type_id: %s,
malloc_size_of: %s as unsafe fn(&mut _, _) -> _,
global: InterfaceObjectMap::%s,
global: InterfaceObjectMap::Globals::%s,
}""" % (prototypeChainString, DOMClassTypeId(descriptor), mallocSizeOf, globals_)
@ -2445,7 +2445,7 @@ class CGConstructorEnabled(CGAbstractMethod):
iface = self.descriptor.interface
bits = " | ".join(sorted(
"InterfaceObjectMap::" + camel_to_upper_snake(i) for i in iface.exposureSet
"InterfaceObjectMap::Globals::" + camel_to_upper_snake(i) for i in iface.exposureSet
))
conditions.append("is_exposed_in(aObj, %s)" % bits)
@ -7102,9 +7102,9 @@ class GlobalGenRoots():
for (idx, d) in enumerate(global_descriptors)
)
global_flags = CGWrapper(CGIndenter(CGList([
CGGeneric("const %s = %#x," % args)
CGGeneric("const %s = %#x;" % args)
for args in flags
], "\n")), pre="pub flags Globals: u8 {\n", post="\n}")
], "\n")), pre="pub struct Globals: u8 {\n", post="\n}")
globals_ = CGWrapper(CGIndenter(global_flags), pre="bitflags! {\n", post="\n}")
phf = CGGeneric("include!(concat!(env!(\"OUT_DIR\"), \"/InterfaceObjectMapPhf.rs\"));")

Просмотреть файл

@ -13,7 +13,7 @@ use style::context::QuirksMode;
use style::parser::ParserContext;
use style::stylesheets::CssRuleType;
use style::stylesheets::supports_rule::{Declaration, parse_condition_or_declaration};
use style_traits::PARSING_MODE_DEFAULT;
use style_traits::ParsingMode;
#[dom_struct]
pub struct CSS {
@ -39,7 +39,7 @@ impl CSS {
let context = ParserContext::new_for_cssom(
&url,
Some(CssRuleType::Style),
PARSING_MODE_DEFAULT,
ParsingMode::DEFAULT,
QuirksMode::NoQuirks
);
decl.eval(&context)
@ -55,7 +55,7 @@ impl CSS {
let context = ParserContext::new_for_cssom(
&url,
Some(CssRuleType::Style),
PARSING_MODE_DEFAULT,
ParsingMode::DEFAULT,
QuirksMode::NoQuirks
);
cond.eval(&context)

Просмотреть файл

@ -20,7 +20,7 @@ use style::media_queries::parse_media_query_list;
use style::parser::ParserContext;
use style::shared_lock::{Locked, ToCssWithGuard};
use style::stylesheets::{CssRuleType, MediaRule};
use style_traits::{PARSING_MODE_DEFAULT, ToCss};
use style_traits::{ParsingMode, ToCss};
#[dom_struct]
pub struct CSSMediaRule {
@ -76,7 +76,7 @@ impl CSSMediaRule {
let url = window.get_url();
let quirks_mode = window.Document().quirks_mode();
let context = ParserContext::new_for_cssom(&url, Some(CssRuleType::Media),
PARSING_MODE_DEFAULT,
ParsingMode::DEFAULT,
quirks_mode);
let new_medialist = parse_media_query_list(&context, &mut input,

Просмотреть файл

@ -22,7 +22,7 @@ use style::properties::{DeclarationSource, Importance, PropertyDeclarationBlock,
use style::properties::{parse_one_declaration_into, parse_style_attribute, SourcePropertyDeclaration};
use style::selector_parser::PseudoElement;
use style::shared_lock::Locked;
use style_traits::{PARSING_MODE_DEFAULT, ToCss};
use style_traits::{ParsingMode, ToCss};
// http://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface
#[dom_struct]
@ -261,7 +261,7 @@ impl CSSStyleDeclaration {
let mut declarations = SourcePropertyDeclaration::new();
let result = parse_one_declaration_into(
&mut declarations, id, &value, &self.owner.base_url(),
window.css_error_reporter(), PARSING_MODE_DEFAULT, quirks_mode);
window.css_error_reporter(), ParsingMode::DEFAULT, quirks_mode);
// Step 6
match result {

Просмотреть файл

@ -18,7 +18,7 @@ use style::parser::ParserContext;
use style::shared_lock::{Locked, ToCssWithGuard};
use style::stylesheets::{CssRuleType, SupportsRule};
use style::stylesheets::supports_rule::SupportsCondition;
use style_traits::{PARSING_MODE_DEFAULT, ToCss};
use style_traits::{ParsingMode, ToCss};
#[dom_struct]
pub struct CSSSupportsRule {
@ -64,7 +64,7 @@ impl CSSSupportsRule {
let url = win.Document().url();
let quirks_mode = win.Document().quirks_mode();
let context = ParserContext::new_for_cssom(&url, Some(CssRuleType::Supports),
PARSING_MODE_DEFAULT,
ParsingMode::DEFAULT,
quirks_mode);
let enabled = cond.eval(&context);
let mut guard = self.cssconditionrule.shared_lock().write();

Просмотреть файл

@ -41,7 +41,7 @@ use std::sync::{Arc, Mutex};
use std::sync::atomic::AtomicBool;
use std::sync::mpsc::{Receiver, RecvError, Select, Sender, channel};
use std::thread;
use style::thread_state;
use style::thread_state::{self, ThreadState};
/// Set the `worker` field of a related DedicatedWorkerGlobalScope object to a particular
/// value for the duration of this object's lifetime. This ensures that the related Worker
@ -166,7 +166,7 @@ impl DedicatedWorkerGlobalScope {
let origin = GlobalScope::current().expect("No current global object").origin().immutable().clone();
thread::Builder::new().name(name).spawn(move || {
thread_state::initialize(thread_state::SCRIPT | thread_state::IN_WORKER);
thread_state::initialize(ThreadState::SCRIPT | ThreadState::IN_WORKER);
if let Some(top_level_browsing_context_id) = top_level_browsing_context_id {
TopLevelBrowsingContextId::install(top_level_browsing_context_id);

Просмотреть файл

@ -66,7 +66,7 @@ use dom::keyboardevent::KeyboardEvent;
use dom::location::Location;
use dom::messageevent::MessageEvent;
use dom::mouseevent::MouseEvent;
use dom::node::{self, CloneChildrenFlag, Node, NodeDamage, window_from_node, IS_IN_DOC, LayoutNodeHelpers};
use dom::node::{self, CloneChildrenFlag, Node, NodeDamage, window_from_node, NodeFlags, LayoutNodeHelpers};
use dom::node::VecPreOrderInsertionHelper;
use dom::nodeiterator::NodeIterator;
use dom::nodelist::NodeList;
@ -100,7 +100,6 @@ use ipc_channel::ipc::{self, IpcSender};
use js::jsapi::{JSContext, JSRuntime};
use js::jsapi::JS_GetRuntime;
use metrics::{InteractiveFlag, InteractiveMetrics, InteractiveWindow, ProfilerMetadataFactory};
use msg::constellation_msg::{ALT, CONTROL, SHIFT, SUPER};
use msg::constellation_msg::{BrowsingContextId, Key, KeyModifiers, KeyState, TopLevelBrowsingContextId};
use net_traits::{FetchResponseMsg, IpcSend, ReferrerPolicy};
use net_traits::CookieSource::NonHTTP;
@ -132,7 +131,7 @@ use std::rc::Rc;
use std::time::{Duration, Instant};
use style::attr::AttrValue;
use style::context::QuirksMode;
use style::invalidation::element::restyle_hints::{RestyleHint, RESTYLE_SELF, RESTYLE_STYLE_ATTRIBUTE};
use style::invalidation::element::restyle_hints::RestyleHint;
use style::media_queries::{Device, MediaList, MediaType};
use style::selector_parser::{RestyleDamage, Snapshot};
use style::shared_lock::{SharedRwLock as StyleSharedRwLock, SharedRwLockReadGuard};
@ -1296,10 +1295,10 @@ impl Document {
(&None, &None) => self.window.upcast(),
};
let ctrl = modifiers.contains(CONTROL);
let alt = modifiers.contains(ALT);
let shift = modifiers.contains(SHIFT);
let meta = modifiers.contains(SUPER);
let ctrl = modifiers.contains(KeyModifiers::CONTROL);
let alt = modifiers.contains(KeyModifiers::ALT);
let shift = modifiers.contains(KeyModifiers::SHIFT);
let meta = modifiers.contains(KeyModifiers::SUPER);
let is_composing = false;
let is_repeating = state == KeyState::Repeated;
@ -2066,7 +2065,7 @@ impl LayoutDocumentHelpers for LayoutDom<Document> {
// may no longer be true when the next layout occurs.
let result = elements.drain()
.map(|(k, v)| (k.to_layout(), v))
.filter(|&(ref k, _)| k.upcast::<Node>().get_flag(IS_IN_DOC))
.filter(|&(ref k, _)| k.upcast::<Node>().get_flag(NodeFlags::IS_IN_DOC))
.collect();
result
}
@ -2512,11 +2511,11 @@ impl Document {
entry.snapshot = Some(Snapshot::new(el.html_element_in_html_document()));
}
if attr.local_name() == &local_name!("style") {
entry.hint.insert(RESTYLE_STYLE_ATTRIBUTE);
entry.hint.insert(RestyleHint::RESTYLE_STYLE_ATTRIBUTE);
}
if vtable_for(el.upcast()).attribute_affects_presentational_hints(attr) {
entry.hint.insert(RESTYLE_SELF);
entry.hint.insert(RestyleHint::RESTYLE_SELF);
}
let snapshot = entry.snapshot.as_mut().unwrap();

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше