diff --git a/pages/popup/error.htm b/pages/popup/error.htm index fc8feef..d2bf86d 100644 --- a/pages/popup/error.htm +++ b/pages/popup/error.htm @@ -1,12 +1,15 @@ - + -

:(

- - +

+ + + + + \ No newline at end of file diff --git a/scripts/GUI/builder/windowman.js b/scripts/GUI/builder/windowman.js index 5027f5c..8d40138 100644 --- a/scripts/GUI/builder/windowman.js +++ b/scripts/GUI/builder/windowman.js @@ -86,9 +86,9 @@ export default class windowman { } function icons() { - let target_elements = document.querySelectorAll(`[data-icon]`); - - target_elements.forEach((element) => { + let TARGET_ELEMENTS = document.querySelectorAll(`[data-icon]`); + + (TARGET_ELEMENTS).forEach((element) => { // Get the content before removing it. let element_data = {}; @@ -122,6 +122,8 @@ export default class windowman { iconify(); clean(); }); + + return TARGET_ELEMENTS; } function text() { @@ -151,9 +153,8 @@ export default class windowman { } }); - delete text_elements[`content`]; Object.keys(text_elements).forEach((key) => { - if (text_elements[key]) { + if (text_elements[key] && !key.includes(`content`)) { text_elements[key].forEach((text_element) => { let text_inserted = texts.localized( text_element.getAttribute(key.concat(`-for`)), @@ -175,11 +176,16 @@ export default class windowman { }); } }); - } + return text_elements; + }; + + let ELEMENTS = {}; elements(); - text(); - icons(); + ELEMENTS[`text`] = text(); + ELEMENTS[`icons`] = icons(); + + return (ELEMENTS); } // Adds events to the window. diff --git a/scripts/external/processor.js b/scripts/external/processor.js index e2ca942..bc07213 100644 --- a/scripts/external/processor.js +++ b/scripts/external/processor.js @@ -32,7 +32,12 @@ export default class processor { await this.product.analyze(); } catch(err) { logging.error(err.name, err.message, err.stack, false); - this.product.status[`error`] = err; + + // Convert the error to an object. + this.product.status[`error`] = {}; + [`name`, `message`, `stack`].forEach((KEY) => { + this.product.status.error[KEY] = String(err[KEY]); + }) }; // Indicate that the process is done. diff --git a/scripts/pages/error.js b/scripts/pages/error.js new file mode 100644 index 0000000..266de3c --- /dev/null +++ b/scripts/pages/error.js @@ -0,0 +1,122 @@ +/* +Display the error screen details. +*/ + +import Page from "/scripts/pages/page.js"; +import Tabs from "/scripts/GUI/tabs.js"; + +import {global, observe} from "/scripts/secretariat.js"; +import pointer from "/scripts/data/pointer.js"; + +import logging from "/scripts/logging.js"; + +class Page_Error extends Page { + constructor() { + super(); + this.content(); + this.background(); + this.events(); + }; + + async background() { + // Wait until a change in the session storage. + observe(async (changes) => { + await this.update(); + this.fill(); + }); + } + + /* + Update the data. + */ + async update() { + // Set the reference website when overriding or unset. + if (!this[`ref`]) {this[`ref`] = await pointer.read(`URL`)}; + + // Get all the data to be used here. + let STORAGE_DATA = await global.read([`sites`, this[`ref`], `status`], -1) + + // Update all other data. + this[`status`] = ((STORAGE_DATA != null && (typeof STORAGE_DATA).includes(`obj`)) ? (Object.keys(STORAGE_DATA).length) : false) + ? STORAGE_DATA + // Accomodate data erasure. + : ((this[`status`]) + ? this[`status`] + : {}); + } + + /* + Extract the contents of the page. + */ + content () { + this[`elements`] = (this[`elements`]) ? this[`elements`] : {}; + + const error_display = () => { + this[`elements`][`error display`] = {}; + let ERROR_CONTENTS = document.querySelectorAll(`[data-error]`); + + ERROR_CONTENTS.forEach((ELEMENT) => { + let PROPERTY = ELEMENT.getAttribute(`data-error`).trim(); + this[`elements`][`error display`][PROPERTY] = ELEMENT; + + // Remove properties used to construct since it is already saved. + ELEMENT.removeAttribute(`data-error`); + }); + }; + + error_display(); + this.fill(); + }; + + /* + Fill in the content of the page. + */ + fill () { + this.update(); + + console.log(this); + + (this[`elements`][`error display`] && this[`status`][`error`]) + ? (Object.keys(this[`elements`][`error display`]).forEach((KEY) => { + this[`elements`][`error display`][KEY].innerText = String(this[`status`][`error`][KEY]) + })) + : false; + } + + /* + Add event listeners to the page. + */ + events () { + this[`elements`] = (this[`elements`]) ? this[`elements`] : {}; + this[`elements`][`button`] = {}; + + document.querySelectorAll(`[data-action]`).forEach((ELEMENT) => { + let ACTION = ELEMENT.getAttribute(`data-action`); + this[`elements`][`button`][ACTION] = ELEMENT; + + // Remove the data-action attribute. + ELEMENT.removeAttribute(`data-action`); + }) + + // Add an event listener to the refresh button. + this[`elements`][`button`][`refresh`].addEventListener(`click`, () => { + this.send(); + }); + }; + + /* + Send a request to the content script to scrape the page. + */ + send() { + try { + // Send a message to the content script. + Tabs.query(null, 0).then((TAB) => { + chrome.tabs.sendMessage(TAB.id, {"refresh": true}); + }); + } catch(err) { + logging.error(err.name, err.message, err.stack); + }; + }; +} + +new Page_Error() \ No newline at end of file diff --git a/scripts/pages/popup.js b/scripts/pages/popup.js index 22c26fb..23f8a61 100644 --- a/scripts/pages/popup.js +++ b/scripts/pages/popup.js @@ -13,9 +13,9 @@ import logging from "/scripts/logging.js"; class Page_Popup extends Page { constructor() { super(); - (this.events) ? this.events() : false; this.content(); this.background(); + this.events(); }; async background() { @@ -83,25 +83,21 @@ class Page_Popup extends Page { : `loading`)]; // Replace the iframe src with the new page. - this.elements[`frame`].forEach((frame) => { - frame.src = PAGE; - }) + this.elements[`frame`].src = PAGE; // The results page has its own container. - this.elements[`container`].forEach((CONTAINER) => { - CONTAINER.classList[(PAGE.includes(`results`)) ? `remove` : `add`](`container`); - }); + this.elements[`container`].classList[(PAGE.includes(`results`)) ? `remove` : `add`](`container`); }; }; async content() { this.elements = {}; - this.elements[`container`] = document.querySelectorAll(`main`); - this.elements[`frame`] = document.querySelectorAll(`main > iframe.viewer`); - + this.elements[`container`] = document.querySelector(`main`); + this.elements[`frame`] = document.querySelector(`main > iframe.viewer`); + this.elements[`nav`] = document.querySelector(`nav`); // Check if the frame is available. - if (this.elements[`frame`].length) { + if (this.elements[`frame`]) { await this.switch(); this.background(); } else { @@ -119,18 +115,33 @@ class Page_Popup extends Page { logging.error(err.name, err.message, err.stack); throw (err); }; - } + }; events() { - (document.querySelector(`[data-action="open,settings"]`)) ? document.querySelector(`[data-action="open,settings"]`).addEventListener("click", () => { + this[`elements`] = (this[`elements`]) ? this[`elements`] : {}; + this[`elements`][`button`] = {}; + + document.querySelectorAll(`[data-action]`).forEach((ELEMENT) => { + let ACTION = ELEMENT.getAttribute(`data-action`).trim(); + this[`elements`][`button`][ACTION] = ELEMENT; + + // Remove the data-action attribute. + ELEMENT.removeAttribute(`data-action`); + }); + + console.log(this[`elements`]); + + this[`elements`][`button`][`open,settings`].addEventListener("click", () => { chrome.runtime.openOptionsPage(); - }) : false; - (document.querySelector(`[data-action="open,help"]`)) ? document.querySelector(`[data-action="open,help"]`).addEventListener("click", () => { + }); + + this[`elements`][`button`][`open,help`].addEventListener("click", () => { new Window(`help.htm`); - }) : false; - (document.querySelector(`[data-action="analysis,reload"]`)) ? document.querySelector(`[data-action="analysis,reload"]`).addEventListener("click", () => { + }); + + this[`elements`][`button`][`analysis,reload`].addEventListener("click", () => { this.send(); - }) : false; + }); } } diff --git a/scripts/pages/results.js b/scripts/pages/results.js index b796a50..ea8e45c 100644 --- a/scripts/pages/results.js +++ b/scripts/pages/results.js @@ -35,13 +35,15 @@ class Page_Results extends Page { // Set the reference website when overriding or unset. if (override || !this[`ref`]) {this[`ref`] = await global.read([`last`])}; - // Get all the data. - let DATA = { - "data": await global.read([`sites`, this[`ref`]]) - } - - // Set the data. - this[`data`] = ((DATA[`data`] != null) && !((typeof DATA[`data`]).includes(`undef`))) ? (DATA[`data`]) : (this[`data`] ? this[`data`] : {}); + if (this[`ref`]) { + // Get all the data. + let DATA = { + "data": await global.read([`sites`, this[`ref`]]) + } + + // Set the data. + this[`data`] = (DATA[`data`] && (typeof DATA[`data`]).includes(`obj`)) ? DATA[`data`] : (this[`data`] ? this[`data`] : {}); + } } async content() { @@ -78,59 +80,63 @@ class Page_Results extends Page { Populate the contents. */ async fill() { - (this.elements && !((typeof this.elements).includes(`undef`))) - ? (Object.keys(this.elements)).forEach(async (SOURCE) => { - if (SOURCE.indexOf(`*`) < SOURCE.length - 1) { - let DATA = (nested.dictionary.get(this[`data`][`analysis`], SOURCE)); - - this.elements[SOURCE][(this.elements[SOURCE].nodeName.toLowerCase().includes(`input`) || this.elements[SOURCE].nodeName.toLowerCase().includes(`progress`)) ? `value` : `innerHTML`] = (DATA) - ? (((typeof DATA).includes(`obj`) && !Array.isArray(DATA)) - ? JSON.stringify(DATA) - : String(DATA)) - : null; - } else if (SOURCE.indexOf(`*`) >= SOURCE.length - 1) { - let DATA = (nested.dictionary.get(this[`data`][`analysis`], SOURCE.split(`,`).slice(0, -1))); - - (!Array.isArray(DATA) && (typeof DATA).includes(`obj`) && DATA != null) - - let ELEMENT_TYPES = { - "container": "section", - "content": "article", - "title": "p", - "body": "p" - }; - - (DATA) ? (Object.keys(DATA)).forEach((ITEM) => { - let ELEMENTS = {}; - - // Create the elements. - (Object.keys(ELEMENT_TYPES)).forEach((TYPE) => { - ELEMENTS[TYPE] = document.createElement(ELEMENT_TYPES[TYPE]); - - (([`content`, `action`, `title`].includes(TYPE) || TYPE.includes(`container`)) && this.elements[SOURCE][`target element type`]) - ? ELEMENTS[TYPE].classList.add(this.elements[SOURCE][`target element type`].concat((!TYPE.includes(`container`)) - ? `-${TYPE}` - : ``)) - : false; - }); - - ELEMENTS[`title`].innerText = String(ITEM).trim(); - ELEMENTS[`title`].classList.add(`flow-text`); - ELEMENTS[`body`].innerText = String(DATA[ITEM]).trim(); - - // Inject the elements. - [`title`, `body`].forEach((CONTENT) => { - ELEMENTS[`content`].appendChild(ELEMENTS[CONTENT]); - }); - ELEMENTS[`container`].appendChild(ELEMENTS[`content`]); - this.elements[SOURCE].appendChild(ELEMENTS[`container`]); - }) : false; - } - }) - : false; - - // Set the color. - (nested.dictionary.get(this[`data`][`analysis`], [`Rating`, `Trust`]) && document.querySelector(`summary`)) ? document.querySelector(`summary`).setAttribute(`result`, (nested.dictionary.get(this[`data`][`analysis`], [`Rating`, `Trust`]))) : false; + if (this.data) { + (this.elements) + ? (Object.keys(this.elements)).forEach(async (SOURCE) => { + if (SOURCE.indexOf(`*`) < SOURCE.length - 1) { + let DATA = (nested.dictionary.get(this[`data`][`analysis`], SOURCE)); + + this.elements[SOURCE][(this.elements[SOURCE].nodeName.toLowerCase().includes(`input`) || this.elements[SOURCE].nodeName.toLowerCase().includes(`progress`)) ? `value` : `innerHTML`] = (DATA) + ? (((typeof DATA).includes(`obj`) && !Array.isArray(DATA)) + ? JSON.stringify(DATA) + : String(DATA)) + : null; + } else if (SOURCE.indexOf(`*`) >= SOURCE.length - 1) { + let DATA = (nested.dictionary.get(this[`data`][`analysis`], SOURCE.split(`,`).slice(0, -1))); + + (!Array.isArray(DATA) && (typeof DATA).includes(`obj`) && DATA != null) + + let ELEMENT_TYPES = { + "container": "section", + "content": "article", + "title": "p", + "body": "p" + }; + + (DATA) + ? (Object.keys(DATA)).forEach((ITEM) => { + let ELEMENTS = {}; + + // Create the elements. + (Object.keys(ELEMENT_TYPES)).forEach((TYPE) => { + ELEMENTS[TYPE] = document.createElement(ELEMENT_TYPES[TYPE]); + + (([`content`, `action`, `title`].includes(TYPE) || TYPE.includes(`container`)) && this.elements[SOURCE][`target element type`]) + ? ELEMENTS[TYPE].classList.add(this.elements[SOURCE][`target element type`].concat((!TYPE.includes(`container`)) + ? `-${TYPE}` + : ``)) + : false; + }); + + ELEMENTS[`title`].innerText = String(ITEM).trim(); + ELEMENTS[`title`].classList.add(`flow-text`); + ELEMENTS[`body`].innerText = String(DATA[ITEM]).trim(); + + // Inject the elements. + [`title`, `body`].forEach((CONTENT) => { + ELEMENTS[`content`].appendChild(ELEMENTS[CONTENT]); + }); + ELEMENTS[`container`].appendChild(ELEMENTS[`content`]); + this.elements[SOURCE].appendChild(ELEMENTS[`container`]); + }) + : false + } + }) + : false; + + // Set the color. + (nested.dictionary.get(this[`data`][`analysis`], [`Rating`, `Trust`]) && document.querySelector(`summary`)) ? document.querySelector(`summary`).setAttribute(`result`, (nested.dictionary.get(this[`data`][`analysis`], [`Rating`, `Trust`]))) : false; + } // Display the results in the console. console.log(this[`data`][`analysis`]) diff --git a/styles/colors/defaults.css b/styles/colors/defaults.css index 9f2a884..4e93e85 100644 --- a/styles/colors/defaults.css +++ b/styles/colors/defaults.css @@ -1,5 +1,5 @@ :root { - --surface-color: rgba(252, 162, 133) !important; + --surface-color: rgba(255, 134, 57, .1) !important; --font-color-main: rgba(0, 0, 0) !important; --font-color-medium: rgba(25, 25, 25) !important; @@ -12,14 +12,39 @@ --primary-color-numeric: 255, 134, 57 !important; --primary-color-raised-hover-solid: rgba(252, 162, 133) !important; --primary-color-raised-focus-solid: rgba(221, 106, 59) !important; + --primary-color-gradient: linear-gradient( + 43deg, + var(--primary-color-dark) 0%, + var(--primary-color) 62%, + var(--primary-color-raised-hover-solid) 100% + ) !important; + --background-color-disabled: rgba(125, 125, 125) !important; + --background-color-level-4dp: rgba(229, 229, 229) !important; --background-color-level-16dp-solid: rgba(255, 238, 235) !important; + --background-color-card: rgba(242, 242, 242) !important; + --background-color-slight-emphasis: rgba(252, 162, 133) !important; + --secondary-color: rgba(221, 106, 59, 1) !important; --secondary-color-hover-solid: rgba(252, 162, 133) !important; --secondary-color-focus-solid: rgba(221, 106, 59) !important; --secondary-container-color: rgba(252, 162, 133) !important; + --secondary-color-lighter: rgba(221, 106, 59) !important; + --secondary-color: rgba(190, 80, 1) !important; + --secondary-color-dark: rgba(159, 55, 0) !important; + --secondary-color-hover-solid: rgba(252, 162, 133) !important; + --secondary-color-focus-solid: rgba(159, 55, 0) !important; + --font-on-secondary-container-color: rgba(255, 255, 255) !important; + + --hover-color: rgba(255, 255, 255, 0.3) !important; + --focus-color: rgba(255, 255, 255, 0.3) !important; + --focus-color-solid: rgb(76.5, 76.5, 76.5) !important; + --active-color: rgba(255, 255, 255, 0.3) !important; + + --separator-color: rgba(178,178,178) !important; + --error-color: #cf6679 !important; } @media (prefers-color-scheme: dark) { diff --git a/styles/colors/defaults.results.css b/styles/colors/defaults.results.css index 75352a7..259c6ce 100644 --- a/styles/colors/defaults.results.css +++ b/styles/colors/defaults.results.css @@ -1,13 +1,21 @@ :root { --color-results_bad_dark: #AF3119; --color-results_bad_light: #EC6342; - --color-results_bad_gradient: linear-gradient(43deg, var(--color-results_bad_dark) 0%, var(--color-results_bad_light) 100%); + --color-results_bad_gradient: linear-gradient(43deg, var(--color-results_bad_dark) 100%, var(--color-results_bad_light) 0%); - --color-results_ok_dark: #E8A87C; - --color-results_ok_light: #F6C7A1; - --color-results_ok_gradient: linear-gradient(43deg, var(--color-results_ok_dark) 0%, var(--color-results_ok_light) 100%); + --color-results_ok_dark: rgba(221, 106, 59); + --color-results_ok_light: rgba(255, 134, 57); + --color-results_ok_gradient: linear-gradient(43deg, var(--color-results_ok_dark) 100%, var(--color-results_ok_light) 0%); --color-results_good_dark: #487858; --color-results_good_light: #5BBF4B; - --color-results_good_gradient: linear-gradient(43deg, var(--color-results_good_dark) 0%, var(--color-results_good_light) 100%); + --color-results_good_gradient: linear-gradient(43deg, var(--color-results_good_dark) 100%, var(--color-results_good_light) 0%); +} + +@media (prefers-color-scheme: dark) { + :root { + --color-results_bad_gradient: linear-gradient(43deg, var(--color-results_bad_dark) 0%, var(--color-results_bad_light) 100%); + --color-results_ok_gradient: linear-gradient(43deg, var(--color-results_ok_dark) 0%, var(--color-results_ok_light) 100%); + --color-results_good_gradient: linear-gradient(43deg, var(--color-results_good_dark) 0%, var(--color-results_good_light) 100%); + } } \ No newline at end of file diff --git a/styles/layouts/all.css b/styles/layouts/all.css index 18baa1d..fe25727 100644 --- a/styles/layouts/all.css +++ b/styles/layouts/all.css @@ -89,7 +89,6 @@ iframe.viewer { body[role="window"] { width: 300pt; - height: 300pt; } *:has(summary + details) summary:not(:last-child) { diff --git a/styles/layouts/popup.css b/styles/layouts/popup.css index cd9e0fa..63e69c0 100644 --- a/styles/layouts/popup.css +++ b/styles/layouts/popup.css @@ -11,7 +11,3 @@ margin-bottom: auto; } -#results:not(:has(details[open])) summary { - height: 80vh; -} -