Skip to content

Commit

Permalink
Add support for Facebook Container extenstion (#280)
Browse files Browse the repository at this point in the history
* Insert before newtab if parentNode not found
* Parse SVG and rewrite if color is not predefined
  • Loading branch information
asamuzaK authored Jan 20, 2024
1 parent 6e9e7d3 commit 299c501
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 19 deletions.
3 changes: 2 additions & 1 deletion src/mjs/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -745,10 +745,11 @@ export const handleCreatedTab = async (tabsTab, opt = {}) => {
logErr(e);
}
if (isObjectNotEmpty(ident)) {
const { color, icon, name } = ident;
const { color, colorCode, icon, name } = ident;
const identIcon = tab.querySelector(`.${CLASS_TAB_IDENT_ICON}`);
func.push(setContextualIdentitiesIcon(identIcon, {
color,
colorCode,
icon,
name
}));
Expand Down
24 changes: 19 additions & 5 deletions src/mjs/tab-content.js
Original file line number Diff line number Diff line change
Expand Up @@ -330,12 +330,26 @@ export const addTabCloseClickListener = async elm => {
export const setContextualIdentitiesIcon = async (elm, info) => {
if (elm?.nodeType === Node.ELEMENT_NODE && elm?.localName === 'img' &&
isObjectNotEmpty(info)) {
const { color, icon, name } = info;
if (contextualIdentitiesIconColor.has(color) &&
contextualIdentitiesIconName.has(icon) &&
isString(name)) {
const { color, colorCode, icon, name } = info;
if (contextualIdentitiesIconName.has(icon) && isString(name)) {
let src;
if (contextualIdentitiesIconColor.has(color)) {
src = `../img/${icon}.svg#${color}`;
} else if (colorCode) {
const { href } = new URL(`../img/${icon}.svg`, import.meta.url);
const file = await fetch(href);
const content = await file.text();
const doc = new DOMParser().parseFromString(content, 'image/svg+xml');
const current = doc.getElementById('current');
current.setAttribute('fill', colorCode);
const domstr = new XMLSerializer().serializeToString(doc);
const data = btoa(domstr);
src = `data:image/svg+xml;base64,${data}`;
} else {
src = `../img/${icon}.svg#current`;
}
elm.src = src;
elm.alt = name;
elm.src = `../img/${icon}.svg#${color}`;
elm.parentNode.classList.add(IDENTIFIED);
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/mjs/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ export const createSidebarTab = (node, target) => {
container.appendChild(tab);
container.removeAttribute('hidden');
if (!target || target.nodeType !== Node.ELEMENT_NODE ||
!target.classList.contains(CLASS_TAB_CONTAINER)) {
!target.classList.contains(CLASS_TAB_CONTAINER) ||
!target?.parentNode) {
target = document.getElementById(NEW_TAB);
}
target.parentNode.insertBefore(container, target);
Expand Down
49 changes: 37 additions & 12 deletions test/tab-content.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import {
} from '../src/mjs/constant.js';

describe('tab-content', () => {
const globalKeys = ['Node'];
const globalKeys = ['DOMParser', 'Node', 'XMLSerializer'];
let window, document;
beforeEach(() => {
const dom = createJsdom();
Expand Down Expand Up @@ -1098,7 +1098,7 @@ describe('tab-content', () => {
assert.isFalse(parent.classList.contains(IDENTIFIED), 'class');
});

it('should not set icon if color and/or icon does not match', async () => {
it('should not set icon if icon does not match', async () => {
const parent = document.createElement('p');
const elm = document.createElement('img');
const body = document.querySelector('body');
Expand All @@ -1114,7 +1114,7 @@ describe('tab-content', () => {
assert.isFalse(parent.classList.contains(IDENTIFIED), 'class');
});

it('should not set icon if one of keys lacks', async () => {
it('should not set icon if name is not a string', async () => {
const parent = document.createElement('p');
const elm = document.createElement('img');
const body = document.querySelector('body');
Expand All @@ -1130,7 +1130,7 @@ describe('tab-content', () => {
assert.isFalse(parent.classList.contains(IDENTIFIED), 'class');
});

it('should not set icon if one of keys lacks', async () => {
it('should not set icon if icon and/or name lacks', async () => {
const parent = document.createElement('p');
const elm = document.createElement('img');
const body = document.querySelector('body');
Expand All @@ -1145,34 +1145,35 @@ describe('tab-content', () => {
assert.isFalse(parent.classList.contains(IDENTIFIED), 'class');
});

it('should not set icon if one of keys lacks', async () => {
it('should not set icon if icon and/or name lacks', async () => {
const parent = document.createElement('p');
const elm = document.createElement('img');
const body = document.querySelector('body');
parent.appendChild(elm);
body.appendChild(parent);
await func(elm, {
icon: 'briefcase',
color: 'blue',
name: 'foo'
});
assert.strictEqual(elm.alt, '', 'alt');
assert.strictEqual(elm.src, '', 'src');
assert.isFalse(parent.classList.contains(IDENTIFIED), 'class');
});

it('should not set icon if one of keys lacks', async () => {
it('should set icon', async () => {
const parent = document.createElement('p');
const elm = document.createElement('img');
const body = document.querySelector('body');
parent.appendChild(elm);
body.appendChild(parent);
await func(elm, {
color: 'blue',
icon: 'briefcase',
name: 'foo'
});
assert.strictEqual(elm.alt, '', 'alt');
assert.strictEqual(elm.src, '', 'src');
assert.isFalse(parent.classList.contains(IDENTIFIED), 'class');
assert.strictEqual(elm.alt, 'foo', 'alt');
assert.strictEqual(elm.src, '../img/briefcase.svg#blue', 'src');
assert.isTrue(parent.classList.contains(IDENTIFIED), 'class');
});

it('should set icon', async () => {
Expand All @@ -1182,12 +1183,36 @@ describe('tab-content', () => {
parent.appendChild(elm);
body.appendChild(parent);
await func(elm, {
color: 'blue',
color: 'bar',
icon: 'briefcase',
name: 'foo'
});
assert.strictEqual(elm.alt, 'foo', 'alt');
assert.strictEqual(elm.src, '../img/briefcase.svg#blue', 'src');
assert.strictEqual(elm.src, '../img/briefcase.svg#current', 'src');
assert.isTrue(parent.classList.contains(IDENTIFIED), 'class');
});

it('should set icon', async () => {
const stubFetch = sinon.stub(globalThis, 'fetch').resolves({
text: async () => {
const str = '<svg><g id="current"/></svg>';
return str;
}
})
const parent = document.createElement('p');
const elm = document.createElement('img');
const body = document.querySelector('body');
parent.appendChild(elm);
body.appendChild(parent);
await func(elm, {
color: 'bar',
colorCode: 'gray',
icon: 'briefcase',
name: 'foo'
});
stubFetch.restore();
assert.strictEqual(elm.alt, 'foo', 'alt');
assert.isTrue(elm.src.startsWith('data:'), 'src');
assert.isTrue(parent.classList.contains(IDENTIFIED), 'class');
});
});
Expand Down
18 changes: 18 additions & 0 deletions test/util.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,24 @@ describe('util', () => {
assert.deepEqual(res, elm, 'result');
assert.deepEqual(res.parentNode.nextElementSibling, div2, 'position');
});

it('should get result', async () => {
const tmpl = document.createElement('template');
const div = document.createElement('div');
const elm = document.createElement('div');
const target = document.createElement('div')
const newTab = document.createElement('div');
const body = document.querySelector('body');
tmpl.id = CLASS_TAB_CONTAINER_TMPL;
tmpl.content.appendChild(div);
newTab.id = NEW_TAB;
body.appendChild(tmpl);
body.appendChild(newTab);
const res = await func(elm, target);
assert.isNull(target.parentNode, 'parent');
assert.deepEqual(res, elm, 'result');
assert.deepEqual(res.parentNode.nextElementSibling, newTab, 'position');
});
});

describe('get sidebar tab from parent node', () => {
Expand Down

0 comments on commit 299c501

Please sign in to comment.