Bug 1523335 - Make use of parentFlexElement in Flexbox inspector r=pbro

This gives a very noticable increase in speed. When Brad finishes https://bugzil.la/1523336 we can stop walking the DOM and simply use `parentFlexElement` and `parentGridElement`.

#### Try

https://treeherder.mozilla.org/#/jobs?repo=try&revision=47d38f2c7dca6ca764862c8b00921644a974a975&group_state=expanded

Differential Revision: https://phabricator.services.mozilla.com/D18674

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Michael Ratcliffe 2019-02-06 17:35:20 +00:00
Родитель 42ff7a7ef2
Коммит 991e8e8313
4 изменённых файлов: 13 добавлений и 137 удалений

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

@ -16,7 +16,6 @@ const {
moveInfobar,
} = require("./utils/markup");
const {
findFlexOrGridParentContainerForNode,
getCurrentZoom,
setIgnoreLayoutChanges,
} = require("devtools/shared/layout/utils");
@ -440,7 +439,7 @@ class BoxModelHighlighter extends AutoRefreshHighlighter {
} else {
// The highlighted element is not a flexbox container so we need to check
// if it is a flex item.
const container = findFlexOrGridParentContainerForNode(node, "flex");
const container = node.parentFlexElement;
if (container) {
for (const region of BOX_MODEL_REGIONS) {

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

@ -36,7 +36,6 @@ loader.lazyRequireGetter(this, "SKIP_TO_SIBLING", "devtools/server/actors/inspec
loader.lazyRequireGetter(this, "NodeActor", "devtools/server/actors/inspector/node", true);
loader.lazyRequireGetter(this, "NodeListActor", "devtools/server/actors/inspector/node", true);
loader.lazyRequireGetter(this, "LayoutActor", "devtools/server/actors/layout", true);
loader.lazyRequireGetter(this, "findFlexOrGridParentContainerForNode", "devtools/server/actors/layout", true);
loader.lazyRequireGetter(this, "getLayoutChangesObserver", "devtools/server/actors/reflow", true);
loader.lazyRequireGetter(this, "releaseLayoutChangesObserver", "devtools/server/actors/reflow", true);
loader.lazyRequireGetter(this, "WalkerSearch", "devtools/server/actors/utils/walker-search", true);
@ -560,9 +559,7 @@ var WalkerActor = protocol.ActorClassWithSpec(walkerSpec, {
rawNode.nodeName === "SLOT" &&
isDirectShadowHostChild(firstChild);
const isFlexItem =
!!firstChild &&
findFlexOrGridParentContainerForNode(firstChild, "flex", this);
const isFlexItem = !!(firstChild && firstChild.parentFlexElement);
if (!firstChild ||
walker.nextSibling() ||

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

@ -355,8 +355,7 @@ const LayoutActor = ActorClassWithSpec(layoutSpec, {
return new FlexboxActor(this, node);
}
const container = findFlexOrGridParentContainerForNode(node, type, this.walker);
const container = node.parentFlexElement;
if (container) {
return new FlexboxActor(this, container);
}
@ -372,10 +371,11 @@ const LayoutActor = ActorClassWithSpec(layoutSpec, {
// Note that text nodes that are children of flex/grid containers are wrapped in
// anonymous containers, so even if their displayType getter returns null we still
// want to walk up the chain to find their container.
const container = findFlexOrGridParentContainerForNode(node, type, this.walker);
if (container && flexType) {
return new FlexboxActor(this, container);
const parentFlexElement = node.parentFlexElement;
if (parentFlexElement && flexType) {
return new FlexboxActor(this, parentFlexElement);
}
const container = findGridParentContainerForNode(node, this.walker);
if (container && gridType) {
return new GridActor(this, container);
}
@ -457,25 +457,19 @@ function isNodeDead(node) {
}
/**
* If the provided node is a grid of flex item, then return its parent grid or flex
* container.
* If the provided node is a grid item, then return its parent grid.
*
* @param {DOMNode} node
* The node that is supposedly a grid or flex item.
* @param {String} type
* The type of container/item to look for: "flex" or "grid".
* The node that is supposedly a grid item.
* @param {WalkerActor} walkerActor
* The current instance of WalkerActor.
* @return {DOMNode|null}
* The parent grid or flex container if found, null otherwise.
* The parent grid if found, null otherwise.
*/
function findFlexOrGridParentContainerForNode(node, type, walker) {
function findGridParentContainerForNode(node, walker) {
const treeWalker = walker.getDocumentWalker(node, SHOW_ELEMENT);
let currentNode = treeWalker.currentNode;
const flexType = type === "flex";
const gridType = type === "grid";
try {
while ((currentNode = treeWalker.parentNode())) {
const displayType = walker.getNode(currentNode).displayType;
@ -483,11 +477,7 @@ function findFlexOrGridParentContainerForNode(node, type, walker) {
break;
}
if (flexType && displayType.includes("flex")) {
if (isNodeAFlexItemInContainer(node, currentNode, walker)) {
return currentNode;
}
} else if (gridType && displayType.includes("grid")) {
if (displayType.includes("grid")) {
return currentNode;
} else if (displayType === "contents") {
// Continue walking up the tree since the parent node is a content element.
@ -503,36 +493,7 @@ function findFlexOrGridParentContainerForNode(node, type, walker) {
return null;
}
/**
* Returns whether or not the given node is actually considered a flex item by its
* container.
*
* @param {Node|NodeActor} supposedItem
* The node that might be a flex item of its container.
* @param {Node} container
* The node's container.
* @return {Boolean}
* Whether or not the node we are looking at is a flex item of its container.
*/
function isNodeAFlexItemInContainer(supposedItem, container, walker) {
const containerDisplayType = walker.getNode(container).displayType;
if (containerDisplayType.includes("flex")) {
const containerFlex = container.getAsFlexContainer();
for (const line of containerFlex.getLines()) {
for (const item of line.getItems()) {
if (item.node === supposedItem) {
return true;
}
}
}
}
return false;
}
exports.findFlexOrGridParentContainerForNode = findFlexOrGridParentContainerForNode;
exports.findGridParentContainerForNode = findGridParentContainerForNode;
exports.FlexboxActor = FlexboxActor;
exports.FlexItemActor = FlexItemActor;
exports.GridActor = GridActor;

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

@ -907,87 +907,6 @@ function getUntransformedQuad(node, region = "border") {
}
exports.getUntransformedQuad = getUntransformedQuad;
/**
* If the provided node is a grid of flex item, then return its parent grid or flex
* container.
*
* @param {DOMNode} node
* The node that is supposedly a grid or flex item.
* @param {String} type
* The type of container/item to look for: "flex" or "grid".
* @return {DOMNode|null}
* The parent grid or flex container if found, null otherwise.
*/
function findFlexOrGridParentContainerForNode(node, type) {
const doc = node.ownerDocument;
const win = doc.defaultView;
const treeWalker = doc.createTreeWalker(doc.body, NodeFilter.SHOW_ELEMENT);
const flexType = type === "flex";
const gridType = type === "grid";
let currentNode = null;
treeWalker.currentNode = node;
try {
while ((currentNode = treeWalker.parentNode())) {
const displayType = win.getComputedStyle(currentNode).display;
if (!displayType) {
break;
}
if (flexType && displayType.includes("flex")) {
if (isNodeAFlexItemInContainer(node, currentNode)) {
return currentNode;
}
} else if (gridType && displayType.includes("grid")) {
return currentNode;
} else if (displayType === "contents") {
// Continue walking up the tree since the parent node is a content element.
continue;
}
break;
}
} catch (e) {
// Getting the parentNode can fail when the supplied node is in shadow DOM.
}
return null;
}
exports.findFlexOrGridParentContainerForNode = findFlexOrGridParentContainerForNode;
/**
* Returns whether or not the given node is actually considered a flex item by its
* container.
*
* @param {DOMNode} supposedItem
* The node that might be a flex item of its container.
* @param {DOMNode} container
* The node's container.
* @return {Boolean}
* Whether or not the node we are looking at is a flex item of its container.
*/
function isNodeAFlexItemInContainer(supposedItem, container) {
const doc = container.ownerDocument;
const win = doc.defaultView;
const containerDisplayType = win.getComputedStyle(container).display;
if (containerDisplayType.includes("flex")) {
const containerFlex = container.getAsFlexContainer();
for (const line of containerFlex.getLines()) {
for (const item of line.getItems()) {
if (item.node === supposedItem) {
return true;
}
}
}
}
return false;
}
exports.isNodeAFlexItemInContainer = isNodeAFlexItemInContainer;
/**
* Calculate the total of the node and all of its ancestor's scrollTop and
* scrollLeft values.