Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: CI

on:
push:
branches: [main]
pull_request:

concurrency:
group: ci-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
quality:
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm

- name: Install dependencies
run: npm ci

- name: Prettier check
run: npm run format:check

- name: ESLint
run: npm run lint

- name: Tests
run: npm test

- name: Build
run: npm run build
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dist/
node_modules/
package-lock.json
6 changes: 6 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"singleQuote": true,
"trailingComma": "all",
"printWidth": 90,
"semi": true
}
148 changes: 69 additions & 79 deletions dist/content.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
headerAppUserName: "ecac-header-app-user-name font-medium truncate",
headerAppUserDoc: "ecac-header-app-user-doc font-mono bg-white/10 px-1.5 py-px rounded text-[10px] shrink-0",
headerAppActions: "ecac-header-app-actions flex items-center gap-1 shrink-0",
appContent: "ecac-app-content flex-1 flex flex-col min-h-0 w-full overflow-hidden bg-ecac-surface",
appContent: "ecac-app-content flex-1 flex flex-col min-h-0 w-full overflow-hidden bg-white",
appBack: "ecac-app-back inline-flex items-center gap-1.5 text-xs font-medium text-white/90 hover:text-white no-underline transition-colors shrink-0 px-2 py-1.5 rounded-md hover:bg-white/10",
appBackIcon: "ecac-app-back-icon text-base leading-none opacity-90",
appBackLabel: "ecac-app-back-label hidden sm:inline",
Expand All @@ -95,6 +95,9 @@
}
return normalized;
}
function calculateIframeHeight({ windowHeight, headerHeight, padding = 0 }) {
return Math.max(0, windowHeight - headerHeight - padding);
}

// src/utils/profile.js
function parseProfileInfo(text) {
Expand Down Expand Up @@ -336,102 +339,90 @@
return main;
}

// src/content/shared/page-utils.js
function isRedesignVariantCorrect(root, href) {
if (!root) return false;
const isApp = isEcacApplicationPage(href);
const hasAppRoot = root.classList.contains("ecac-app-root");
const hasAppLayout = Boolean(root.querySelector(".ecac-layout-app"));
const hasStaleToolbar = Boolean(root.querySelector(".ecac-app-toolbar"));
const hasHomeHeaderOnApp = isApp && Boolean(root.querySelector(".ecac-header:not(.ecac-header-app)"));
if (isApp) {
return hasAppRoot && hasAppLayout && !hasStaleToolbar && !hasHomeHeaderOnApp;
}
return !hasAppRoot && Boolean(root.querySelector(".ecac-layout"));
}
function restoreIframeToLegacyContainer(doc) {
const iframe = doc.getElementById("frmApp");
const divApp = doc.getElementById("divApp");
if (!iframe || !divApp || divApp.contains(iframe)) return;
divApp.appendChild(iframe);
}
function removeStaleRedesign(doc, href) {
const root = doc.getElementById("ecac-redesign-root");
if (!root || isRedesignVariantCorrect(root, href)) return false;
restoreIframeToLegacyContainer(doc);
root.remove();
doc.body.classList.remove("ecac-redesign", "ecac-app-page");
doc.documentElement.style.height = "";
return true;
}
function lockApplicationIframe(doc, win = window) {
const iframe = doc.getElementById("frmApp");
if (!iframe) return () => {
};
const applyLayout = () => {
if (!iframe.isConnected) return;
iframe.style.setProperty("display", "block", "important");
iframe.style.setProperty("width", "100%", "important");
iframe.style.setProperty("height", "100%", "important");
iframe.style.setProperty("border", "0", "important");
iframe.style.setProperty("min-height", "0", "important");
};
applyLayout();
const onResize = () => applyLayout();
win.addEventListener("resize", onResize);
const timers = [100, 500, 1500].map((delay) => win.setTimeout(applyLayout, delay));
return () => {
win.removeEventListener("resize", onResize);
timers.forEach((id) => win.clearTimeout(id));
};
}

// src/content/application-page.js
var unlockIframeLayout = null;
var IFRAME_RESIZE_DELAYS_MS = [100, 500, 1500];
function applyApplicationPageRedesign(doc, win = window) {
const existingRoot = doc.getElementById("ecac-redesign-root");
const existingIframe = doc.getElementById("frmApp");
if (existingRoot?.contains(existingIframe)) {
resizeApplicationIframe(doc, win);
return;
}
const cabecalho = doc.getElementById("cabecalho");
const conteudo = doc.getElementById("conteudo");
if (!cabecalho || !conteudo) return;
unlockIframeLayout?.();
unlockIframeLayout = null;
hideLegacyChrome(doc);
doc.body.classList.add("ecac-app-page");
const iframe = doc.getElementById("frmApp");
if (!cabecalho || !iframe) return;
const root = createRoot(doc, { variant: "app" });
const layout = doc.createElement("div");
layout.className = tw.layoutApp;
doc.documentElement.style.height = "100%";
const appTitle = getApplicationTitle(doc);
const header = createAppHeader(doc, cabecalho, appTitle);
layout.appendChild(header);
const appContent = createAppContent(doc, conteudo);
const appContent = createAppContent(doc, iframe);
layout.appendChild(appContent);
root.appendChild(layout);
mountRoot(doc, root);
unlockIframeLayout = lockApplicationIframe(doc);
const resize = () => resizeApplicationIframe(doc);
hideLegacyChrome(doc);
doc.body.classList.add("ecac-app-page");
const resize = () => resizeApplicationIframe(doc, win);
resize();
win.addEventListener("resize", resize);
IFRAME_RESIZE_DELAYS_MS.forEach((delay) => win.setTimeout(resize, delay));
}
function createAppContent(doc, conteudo) {
function createAppContent(doc, iframe) {
const appContent = doc.createElement("div");
appContent.className = tw.appContent;
const frame = doc.createElement("div");
frame.className = tw.appFrame;
const iframe = conteudo.querySelector("#frmApp");
if (iframe) {
iframe.classList.add("ecac-app-iframe");
frame.appendChild(iframe);
}
iframe.classList.add("ecac-app-iframe");
iframe.style.removeProperty("display");
frame.appendChild(iframe);
appContent.appendChild(frame);
return appContent;
}
function resizeApplicationIframe(doc) {
function resizeApplicationIframe(doc, win = window) {
const iframe = doc.getElementById("frmApp");
const header = doc.querySelector(".ecac-header-app");
if (!iframe) return;
const headerHeight = header?.getBoundingClientRect().height ?? 0;
const height = calculateIframeHeight({
windowHeight: win.innerHeight,
headerHeight
});
iframe.style.setProperty("display", "block", "important");
iframe.style.setProperty("width", "100%", "important");
iframe.style.setProperty("height", "100%", "important");
iframe.style.setProperty("height", `${height}px`, "important");
iframe.style.setProperty("border", "0", "important");
iframe.style.setProperty("min-height", "0", "important");
}

// src/content/shared/page-utils.js
function isRedesignVariantCorrect(root, href) {
if (!root) return false;
const isApp = isEcacApplicationPage(href);
const hasAppRoot = root.classList.contains("ecac-app-root");
const hasAppLayout = Boolean(root.querySelector(".ecac-layout-app"));
const hasStaleToolbar = Boolean(root.querySelector(".ecac-app-toolbar"));
const hasHomeHeaderOnApp = isApp && Boolean(root.querySelector(".ecac-header:not(.ecac-header-app)"));
if (isApp) {
return hasAppRoot && hasAppLayout && !hasStaleToolbar && !hasHomeHeaderOnApp;
}
return !hasAppRoot && Boolean(root.querySelector(".ecac-layout"));
}
function restoreIframeToLegacyContainer(doc) {
const iframe = doc.getElementById("frmApp");
const divApp = doc.getElementById("divApp");
if (!iframe || !divApp || divApp.contains(iframe)) return;
divApp.appendChild(iframe);
}
function removeStaleRedesign(doc, href) {
const root = doc.getElementById("ecac-redesign-root");
if (!root || isRedesignVariantCorrect(root, href)) return false;
restoreIframeToLegacyContainer(doc);
root.remove();
doc.body.classList.remove("ecac-redesign", "ecac-app-page");
doc.documentElement.style.height = "";
return true;
}

// src/content/index.js
Expand All @@ -448,25 +439,24 @@
const href = window.location.href;
const run = getRedesignRunner(href);
if (!run) return;
removeStaleRedesign(document, href);
const root = document.getElementById("ecac-redesign-root");
if (root && isRedesignVariantCorrect(root, href)) return;
if (root && isRedesignVariantCorrect(root, href)) {
if (isEcacApplicationPage(href)) {
applyApplicationPageRedesign(document, window);
}
return;
}
removeStaleRedesign(document, href);
run();
}
function init() {
applyRedesign();
const observer = new MutationObserver(() => {
const root = document.getElementById("ecac-redesign-root");
const href = window.location.href;
if (!root) {
applyRedesign();
return;
}
if (!isRedesignVariantCorrect(root, href)) {
if (!document.getElementById("ecac-redesign-root")) {
applyRedesign();
}
});
observer.observe(document.body, { childList: true, subtree: true });
observer.observe(document.body, { childList: true });
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);
Expand Down
48 changes: 48 additions & 0 deletions dist/leilao-content.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
(() => {
// src/utils/leilao-url.js
function isLeilaoEletronicoApp(url) {
try {
const { hostname, pathname } = new URL(url);
return hostname === "www3.cav.receita.fazenda.gov.br" && pathname.startsWith("/leilaoEletronicoInter");
} catch {
return false;
}
}

// src/iframe/leilao/leilao-redesign.js
var BODY_CLASS = "ecac-leilao-redesign";
function markRedesign(doc) {
doc.documentElement.classList.add(BODY_CLASS);
doc.body.classList.add(BODY_CLASS);
}
function hideRedundantChrome(doc) {
doc.querySelectorAll("breadcrumb, .breadcrumb").forEach((el) => {
el.style.display = "none";
el.setAttribute("aria-hidden", "true");
});
}
function applyLeilaoRedesign(doc = document) {
const href = doc.defaultView?.location?.href ?? "";
if (!isLeilaoEletronicoApp(href)) return;
markRedesign(doc);
hideRedundantChrome(doc);
}

// src/iframe/leilao/index.js
function init() {
applyLeilaoRedesign(document);
const observer = new MutationObserver(() => {
if (!document.body.classList.contains("ecac-leilao-redesign")) {
applyLeilaoRedesign(document);
} else {
hideRedundantChrome(document);
}
});
observer.observe(document.body, { childList: true, subtree: true });
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);
} else {
init();
}
})();
Loading
Loading