Skip to content

Commit

Permalink
Use bounds to find component instead of id
Browse files Browse the repository at this point in the history
  • Loading branch information
Bing Dai committed Sep 26, 2021
1 parent 2fbafba commit 5a360b3
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 37 deletions.
98 changes: 97 additions & 1 deletion ember_debug/models/profile-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,84 @@ import ProfileNode from './profile-node';
import Ember from '../utils/ember';

const {
run: { later, scheduleOnce },
run: { later, scheduleOnce }, guidFor
} = Ember;

function _findRoots({ first, last, parent }) {
const roots = [];
const closest = parent.childNodes;
if (first.node === last.node)
return [first.node];

let start = null;
let end = null;
for (let i = 0; i < closest.length; i++) {
if (closest.item(i) === first.node)
start = i;
else if (closest.item(i) === last.node)
end = i;
}

if (start === null || end === null)
return [];


for (let i = start; i <= end; i++)
roots.push(closest.item(i));


return roots.filter((el) => {
if (el.nodeType === 3) {
if (el.nodeValue.trim() === '') {
return false;
}
}
return el;
})
}

function makeHighlight(id) {
return `<div id="ember-inspector-render-highlight-${id}" role="presentation" class="ember-inspector-render-highlight"></div>`;
}
function _insertHTML(id) {
document.body.insertAdjacentHTML('beforeend', makeHighlight(id).trim());
return document.body.lastChild;
}

function _insertStylesheet() {
const content = `
.ember-inspector-render-highlight {
border: 1px solid red;
}
`
const style = document.createElement('style');
style.appendChild(document.createTextNode(content));
document.head.appendChild(style);
return style;
}

function _renderHighlight(node, guid) {
if (!node?.getBoundingClientRect) {
return;
}
const rect = node.getBoundingClientRect()
const id = guid || (Math.random() * 100000000).toFixed(0);
const highlight = _insertHTML(id);
const { top, left, width, height } = rect;
const { scrollX, scrollY } = window;
const { style } = highlight;
if (style) {
style.position = 'absolute';
style.top = `${top + scrollY}px`;
style.left = `${left + scrollX}px`;
style.width = `${width}px`;
style.height = `${height}px`;
style.zIndex = `1000000`;
}
setTimeout(() => {
highlight.remove()
}, 1000);
}
/**
* A class for keeping track of active rendering profiles as a list.
*/
Expand All @@ -15,11 +90,16 @@ export default class ProfileManager {
this.currentSet = [];
this._profilesAddedCallbacks = [];
this.queue = [];
this.shouldHighlightRender = false;
this.stylesheet = _insertStylesheet();
}

began(timestamp, payload, now) {
return this.wrapForErrors(this, function () {
this.current = new ProfileNode(timestamp, payload, this.current, now);
if (this.shouldHighlightRender && payload.view) {
this.renderHighLight(payload.view);
}
return this.current;
});
}
Expand All @@ -45,6 +125,16 @@ export default class ProfileManager {
return callback.call(context);
}

renderHighLight(view) {
const symbols = Object.getOwnPropertySymbols(view);
const bounds = view[symbols.find(sym => sym.description === "BOUNDS")];
const elements = _findRoots(bounds);

elements.forEach((node) => {
_renderHighlight(node, guidFor(view))
});
}

/**
* Push a new profile into the queue
* @param info
Expand Down Expand Up @@ -80,6 +170,12 @@ export default class ProfileManager {
}
}

teardown() {
this.stylesheet.remove();
}



_flush() {
let entry, i;
for (i = 0; i < this.queue.length; i++) {
Expand Down
7 changes: 3 additions & 4 deletions ember_debug/models/profile-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import Ember from '../utils/ember';

const { get, guidFor } = Ember;

const ProfileNode = function (start, payload, parent, now) {
let name;
this.start = start;
Expand All @@ -15,15 +14,15 @@ const ProfileNode = function (start, payload, parent, now) {
if (payload) {
if (payload.template) {
name = payload.template;
debugger;
} else if (payload.view) {
debugger;
const view = payload.view;
this.viewGuid = guidFor(view);

name = get(view, 'instrumentDisplay') || get(view, '_debugContainerKey');
if (name) {
name = name.replace(/^view:/, '');
}
this.viewGuid = guidFor(view);

}

if (!name && payload.object) {
Expand Down
34 changes: 2 additions & 32 deletions ember_debug/render-debug.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,42 +33,13 @@ export default EmberObject.extend(PortMixin, {

this.profileManager.offProfilesAdded(this, this.sendAdded);
this.profileManager.offProfilesAdded(this, this._updateComponentTree);
this.profileManager.teardown()
},

sendAdded(profiles) {
if (this.shouldHighlightRender) {
profiles.forEach((profile) => {
this._hightLightNode(profile);
});
}
this.sendMessage('profilesAdded', { profiles });
},

_hightLightNode({ viewGuid, children }) {
const hasChildren = children?.length > 0;
if (viewGuid) {
this._createOutline(viewGuid, hasChildren);
}
if (hasChildren) {
children.forEach((childNode) => {
this._hightLightNode(childNode);
});
}
},

_createOutline(viewGuid, hasChildren) {
const element = document.getElementById(viewGuid);
if (element) {
const outline = element.style.outline;
element.style.outline = `${hasChildren ? '0.5' : '1'}px solid ${
hasChildren ? 'blue' : 'red'
}`;
setTimeout(() => {
element.style.outline = outline ?? 'none';
}, 1000);
}
},

/**
* Update the components tree. Called on each `render.component` event.
* @private
Expand All @@ -95,7 +66,7 @@ export default EmberObject.extend(PortMixin, {
},

updateShouldHighlightRender({ shouldHighlightRender }) {
this.shouldHighlightRender = shouldHighlightRender;
this.profileManager.shouldHighlightRender = shouldHighlightRender;
},
},
});
Expand All @@ -114,7 +85,6 @@ function _subscribeToRenderEvents() {
payload,
now: Date.now(),
};

return profileManager.addToQueue(info);
},

Expand Down

0 comments on commit 5a360b3

Please sign in to comment.