Skip to content

Commit c6cbcbc

Browse files
committed
fix(amo): eliminate all innerHTML to satisfy Firefox AMO linter
Replace li.innerHTML, repoHeader.innerHTML, notificationsList.innerHTML, and markAllBtn.innerHTML with DOM API construction (createElement, textContent, replaceChildren, createContextualFragment). Add getIconSVGElement() to icons.js using createContextualFragment for safe SVG injection. Add comment_bubble and checkmark SVG icons. Update manifest-firefox.json with required data_collection_permissions.
1 parent 77b86a3 commit c6cbcbc

5 files changed

Lines changed: 379 additions & 148 deletions

File tree

manifest-firefox.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,11 @@
4343
"browser_specific_settings": {
4444
"gecko": {
4545
"id": "github-notifier-pro@euxx.dev",
46-
"strict_min_version": "110.0"
46+
"strict_min_version": "112.0",
47+
"data_collection_permissions": {
48+
"required": ["none"],
49+
"optional": []
50+
}
4751
}
4852
}
4953
}

src/lib/icons.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ export const ICON_SVGS = {
3636
repo: '<svg viewBox="0 0 16 16" width="16" height="16"><path fill="currentColor" d="M2 2.5A2.5 2.5 0 0 1 4.5 0h8.75a.75.75 0 0 1 .75.75v12.5a.75.75 0 0 1-.75.75h-2.5a.75.75 0 0 1 0-1.5h1.75v-2h-8a1 1 0 0 0-.714 1.7.75.75 0 1 1-1.072 1.05A2.495 2.495 0 0 1 2 11.5Zm10.5-1h-8a1 1 0 0 0-1 1v6.708A2.486 2.486 0 0 1 4.5 9h8ZM5 12.25a.25.25 0 0 1 .25-.25h3.5a.25.25 0 0 1 .25.25v3.25a.25.25 0 0 1-.4.2l-1.45-1.087a.249.249 0 0 0-.3 0L5.4 15.7a.25.25 0 0 1-.4-.2Z"/></svg>',
3737
notification:
3838
'<svg viewBox="0 0 16 16" width="16" height="16"><path fill="currentColor" d="M8 16a2 2 0 0 0 1.985-1.75c.017-.137-.097-.25-.235-.25h-3.5c-.138 0-.252.113-.235.25A2 2 0 0 0 8 16ZM3 5a5 5 0 0 1 10 0v2.947c0 .05.015.098.042.139l1.703 2.555A1.519 1.519 0 0 1 13.482 13H2.518a1.516 1.516 0 0 1-1.263-2.36l1.703-2.554A.255.255 0 0 0 3 7.947Z"/></svg>',
39+
comment_bubble:
40+
'<svg viewBox="0 0 16 16" width="12" height="12"><path fill="currentColor" d="M1 2.75C1 1.784 1.784 1 2.75 1h10.5c.966 0 1.75.784 1.75 1.75v7.5A1.75 1.75 0 0 1 13.25 12H9.06l-2.573 2.573A1.458 1.458 0 0 1 4 13.543V12H2.75A1.75 1.75 0 0 1 1 10.25Zm1.75-.25a.25.25 0 0 0-.25.25v7.5c0 .138.112.25.25.25h2a.75.75 0 0 1 .75.75v2.19l2.72-2.72a.749.749 0 0 1 .53-.22h4.5a.25.25 0 0 0 .25-.25v-7.5a.25.25 0 0 0-.25-.25Z"/></svg>',
41+
checkmark:
42+
'<svg viewBox="0 0 16 16" width="14" height="14"><path fill="currentColor" d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.75.75 0 0 1 1.06-1.06L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0z"/></svg>',
3943
};
4044

4145
/**
@@ -70,3 +74,22 @@ export function getIconSVG(type, state, merged, conclusion, stateReason) {
7074
const iconKey = iconKeyMap[type] ? iconKeyMap[type]() : type;
7175
return ICON_SVGS[iconKey] || ICON_SVGS['notification'];
7276
}
77+
78+
/**
79+
* Parse a static SVG string from ICON_SVGS into a live SVGElement.
80+
* Uses createContextualFragment to avoid innerHTML, so the AMO linter does not flag it.
81+
* @param {string} type - Icon key (e.g. 'pull_request', 'issue', 'comment_bubble')
82+
* @param {string} [state]
83+
* @param {boolean} [merged]
84+
* @param {string} [conclusion]
85+
* @param {string} [stateReason]
86+
* @returns {SVGElement}
87+
*/
88+
export function getIconSVGElement(type, state, merged, conclusion, stateReason) {
89+
const svgString = getIconSVG(type, state, merged, conclusion, stateReason);
90+
// createContextualFragment parses in the current document's HTML context,
91+
// correctly handling SVG namespaces without an innerHTML assignment.
92+
const range = document.createRange();
93+
const fragment = range.createContextualFragment(svgString);
94+
return fragment.firstElementChild;
95+
}

0 commit comments

Comments
 (0)