+ Tooltip: Copy +
Tooltip: Contains AI suggestions.
diff --git a/static/ejs/partials/scripts/categorySummary.ejs b/static/ejs/partials/scripts/categorySummary.ejs index 747de68c..f20834d2 100644 --- a/static/ejs/partials/scripts/categorySummary.ejs +++ b/static/ejs/partials/scripts/categorySummary.ejs @@ -38,7 +38,7 @@ scanItems[category].rules.forEach((rule, index) => { const buttonAriaLabel = `${rule.description}, ${rule.totalItems} occurrences`; const purpleAiSvgId = `${category}-${rule.rule}-${index}`; - const isPurpleAiRule = purpleAiRules.includes(rule.rule) && showPurpleAi; + const isPurpleAiRule = purpleAiRules.includes(rule.rule); const ruleItem = createElementFromString(`+ ` + :`` + }
\n Elements assigned invalid ARIA role values are not interpreted by assistive\n technology as intended by the developer.\n
', label: '\n Effective form labels are required to make forms accessible. The purpose of\n form elements such as checkboxes, radio buttons, input fields, etcetera, is\n often apparent to sighted users, even if the form element is not\n programmatically labeled. Screen readers users require useful form labels to\n identify form fields. Adding a label to all form elements eliminates ambiguity\n and contributes to a more accessible product.\n
', 'landmark-one-main': '\n Navigating a web page is far simpler for screen reader users if all of the\n content splits between one or more high-level sections. Content outside of\n these sections is difficult to find, and its purpose may be unclear.\n
', - 'aria-braille-equivalent': '\nARIA braille attributes were introduced to adjust how labels and role descriptions appear on braille displays, but they cannot be the only attribute providing a label, or a role description. aria-braillelabel
must only be applied to elements with an accessible name, like aria-label
, and aria-brailleroledescription
should only be used with aria-roledescription
.\n
\nARIA attributes should be used according to their specified roles for elements, as using them incorrectly can result in unpredictable behavior for assistive technologies. This can lead to a poor user experience for people with disabilities who rely on these technologies.\n
', - 'aria-deprecated-role': '\nDeprecated ARIA roles are not recognized or properly processed by screen readers and other assistive technologies. Using these means may hinder some users access to essential information. Always assign values to role that align with current, non-deprecated or abstract ARIA roles.\n
', - 'aria-prohibited-attr': '\nThis rule specifically checks that none of the attributes used with a particular role are marked as "prohibited" for that role in the latest version of ARIA. For instance, attributes like aria-label
and aria-labelledby
are not permitted on roles like presentation
and none
, as well as on text-like roles such as code
, insertion
, strong
and others.\n
\nARIA braille attributes were introduced to allow adjusting how labels and role descriptions are rendered on a braille display. They cannot be the only attribute providing a label, or a role description. When used without a corresponding label or role description ARIA says to ignore these attributes, although this may not happen consistently in screen readers and other assistive technologies.\n
', + 'aria-conditional-attr': '\nUsing ARIA attributes on elements where they are not expected can result in unpredictable behavior for assistive technologies. This can lead to a poor user experience for people with disabilities who rely on these technologies. It is important to follow the ARIA specification to ensure that assistive technologies can properly interpret and communicate the intended meaning of the content.\n
', + 'aria-deprecated-role': '\nUsing deprecated WAI-ARIA roles is bad for accessibility. They will not be recognized or correctly processed by screen readers and other assistive technologies. Using these means not everyone will be able to access essential information.\n
', + 'aria-prohibited-attr': '\nUsing ARIA attributes in roles where they are prohibited can mean that important information is not communicated to users of assistive technologies. assistive technologies may also attempt to compensate for the issue, resulting in inconsistent and confusing behavior of these tools.\n
' }; \ No newline at end of file diff --git a/static/ejs/partials/scripts/screenshotLightbox.ejs b/static/ejs/partials/scripts/screenshotLightbox.ejs new file mode 100644 index 00000000..30822885 --- /dev/null +++ b/static/ejs/partials/scripts/screenshotLightbox.ejs @@ -0,0 +1,66 @@ +<%# functions used to show lightbox of screenshot when thumbnail is clicked on %> + \ No newline at end of file diff --git a/static/ejs/partials/scripts/utils.ejs b/static/ejs/partials/scripts/utils.ejs index 9345d403..eb51120f 100644 --- a/static/ejs/partials/scripts/utils.ejs +++ b/static/ejs/partials/scripts/utils.ejs @@ -215,7 +215,7 @@ }) .catch((error) => { delete ongoingPromise[key]; // remove the promise from the queue in case of an error - throw error; + throw new Error('Network Error'); }); // add the promise to the queue @@ -232,26 +232,19 @@ getRuleIdData: (ruleId) => `https://govtechsg.github.io/purple-ai/results/${ruleId}.json` } - const hasProxy = `<%=proxy%>`; + const isOffline = () => !window.navigator.onLine; - const checkPurpleAiAvail = async () => { - // check if catalog is empty - try { - return api(apiUrls.catalog).then(catalogData => { - const catalogHasData = Object.keys(catalogData).length > 1; - return catalogHasData; - }) - } catch (e) { - console.error('Unable to fetch Purple AI catalog'); - return false; + const checkPurpleAiQueryLabel = async (ruleId, ruleHtml) => { + const purpleAiQueryLabel = { + label: null, + hasNetworkError: false, + hasGenericError: false } - } - const checkPurpleAiQueryLabel = async (ruleId, ruleHtml) => { return api(apiUrls.catalog).then(catalogData => { // no information for current rule if (!catalogData[ruleId] || catalogData[ruleId].length === 0) { - return null; + return purpleAiQueryLabel; } if (rulesUsingRoles.includes(ruleId)) { @@ -262,7 +255,8 @@ if (roleForHtml) { const currentLabel = `${htmlElement}_${roleForHtml}`; const foundLabel = catalogData[ruleId].find(label => label === currentLabel); - return foundLabel ? escapeHtmlForAI(currentLabel) : null; + purpleAiQueryLabel.label = foundLabel ? escapeHtmlForAI(currentLabel) : null; + return purpleAiQueryLabel; } } @@ -272,7 +266,8 @@ const currentLabel = currentLabelList.join('_'); if (catalogData[ruleId].includes(currentLabel)) { - return escapeHtmlForAI(currentLabel); + purpleAiQueryLabel.label = escapeHtmlForAI(currentLabel); + return purpleAiQueryLabel; } // count the number of elements in keyArr that @@ -286,15 +281,53 @@ return attrMatch.length >= 3; }) - return foundLabel ? escapeHtmlForAI(foundLabel) : null; + purpleAiQueryLabel.label = foundLabel ? escapeHtmlForAI(foundLabel) : null; + return purpleAiQueryLabel; }) .catch(err => { console.error(`An error has occured while checking if ${ruleId} needs AI query`); - return null; + if (err.message === 'Network Error') { + return { + label: null, + hasNetworkError: true, + hasGenericError: false + } + } else { + return { + label: null, + hasNetworkError: false, + hasGenericError: true + } + } }); } - const getPurpleAiAnswer = async (ruleId, accordionDiv, ruleHtmlLabel, buttonsDiv, aiErrorDiv) => { + const handleOfflinePurpleAi = async (ruleId, accordionDiv, html, buttonsDiv, aiErrorDiv) => { + let purpleAiQueryLabel = await checkPurpleAiQueryLabel(ruleId, html); + if (purpleAiQueryLabel.hasNetworkError) { + document + .getElementById(aiErrorDiv) + .replaceChildren( + createElementFromString( + `$1
`,
);
const replacedRuleHtmlLabel = escapeHtmlForAI(ruleHtmlLabel);
- const aiVoteFeedback = JSON.parse(localStorage.getItem(storagePath));
- if (aiVoteFeedback && aiVoteFeedback[buttonsDiv]) {
- var voteString = aiVoteFeedback[buttonsDiv] === 'useful' ?
- `You rated this AI suggestion useful.` :
- `You rated this AI suggestion not useful`;
- document.getElementById(accordionDiv).innerHTML = `
${replacedString.replace(/\n/g, '
')}
- ${replacedString.replace(/\n/g, '
')}
-