Skip to content

Instantly share code, notes, and snippets.

@lifeart
Last active March 27, 2022 13:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lifeart/ce118d2a144cb975161e9d29860676f8 to your computer and use it in GitHub Desktop.
Save lifeart/ce118d2a144cb975161e9d29860676f8 to your computer and use it in GitHub Desktop.
generic ember render tree capture
let EmberCore;
try {
EmberCore = requireModule('ember')['default'];
} catch {
EmberCore = window.Ember;
}
const keys = ['application','engine'];
//const isEmberApp = (el) => el._debugContainerKey && keys.includes(el._debugContainerKey.split(':')[0]);
const isEmberApp = (el) => ('autoboot' in el);
const apps = Object.values(EmberCore.Application.NAMESPACES).filter(isEmberApp);
const trees = apps.map((app) => EmberCore._captureRenderTree(app.__container__));
function normalizeToAngleBracketComponent(name) {
const SIMPLE_DASHERIZE_REGEXP = /[a-z]|\/|-/g;
const ALPHA = /[A-Za-z0-9]/;
if (name.includes('.')) {
return name;
}
return name.replace(SIMPLE_DASHERIZE_REGEXP, (char, index) => {
if (char === '/') {
return '::';
}
if (index === 0 || !ALPHA.test(name[index - 1])) {
return char.toUpperCase();
}
// Remove all occurrences of '-'s from the name that aren't starting with `-`
return char === '-' ? '' : char.toLowerCase();
});
}
function findRoots({ firstNode, lastNode, parentElement }) {
const roots = [];
const closest = parentElement.childNodes;
if (firstNode === lastNode)
return [firstNode];
let start = null;
let end = null;
for (let i = 0; i < closest.length; i++) {
if (closest.item(i) === firstNode)
start = i;
else if (closest.item(i) === lastNode)
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 extractComponents(node) {
const components = node.children.map((el) => {
let instance = {
isComponent: el.type === 'component',
name: normalizeToAngleBracketComponent(el.name),
args: el.args.named,
roots: findRoots(el.bounds) ,
components: extractComponents(el)
}
instance.root = instance.roots[0] || null;
return instance;
});
return components;
}
function normalizeExtractedComponents(node) {
function cleanComponent(el) {
if (el.isComponent) {
delete el.isComponent;
if (!Object.keys(el.args).length) {
delete el.args;
}
}
}
const result = [];
if (node.isComponent) {
cleanComponent(node);
node.components.forEach((el) => {
cleanComponent(el);
})
result.push(node);
} else {
node.components.forEach((el) => {
const results = normalizeExtractedComponents(el);
result.push(...results);
})
}
return result;
}
normalizeExtractedComponents(extractComponents(trees[0][0])[0]);
// get all models:
const store = apps[0].__container__.lookup('service:store');
const models = Object.keys(store._schema.models).reduce((acc, name) => {
const items = store.peekAll(name).toArray();
if (items.length) {
try {
acc[name] = items.map(i => i.debugJSON());
} catch(e) {
console.error(e);
}
}
return acc;
}, {});
console.log(models)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment