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
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
**Requires at least:** 6.6 \
**Tested up to:** 6.8 \
**Requires PHP:** 7.4 \
**Stable tag:** 3.5.0 \
**Stable tag:** 3.5.1 \
**License:** GPLv2 or later

Ally: Make your site more inclusive by scanning for accessibility violations, fixing them easily, and adding a usability widget and accessibility statement.
Expand Down Expand Up @@ -213,6 +213,16 @@ These are smart suggestions generated by Ally to help you resolve issues more ef

## Changelog

### 3.5.1 - 2025-07-23

* Tweak: Admin panel UI updates
* Tweak: Assistant UI updates
* Tweak: Ensure case sensitive attributes in remediations
* Fix: Assistant accessibility issues
* Fix: Custom Icon issue in edge cases
* Fix: Critical Error on plugin conflict


### 3.5.0 - 2025-07-08

* New: Introducing URL Scanner – find 180+ issues instantly (WCAG 2.1 AA)
Expand Down
8 changes: 4 additions & 4 deletions modules/remediation/actions/attribute.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ public function run() : ?DOMDocument {
//Disable duplicates attr for image

$exclusions = [
'alt' => ['role', 'title'],
'role' => ['alt', 'title']
'alt' => [ 'role', 'title' ],
'role' => [ 'alt', 'title' ],
];
if ( isset( $exclusions[$this->data['attribute_name']] ) ) {
foreach ( $exclusions[$this->data['attribute_name']] as $attr_to_remove ) {
if ( isset( $exclusions[ $this->data['attribute_name'] ] ) ) {
foreach ( $exclusions[ $this->data['attribute_name'] ] as $attr_to_remove ) {
$element_node->removeAttribute( $attr_to_remove );
}
}
Expand Down
8 changes: 4 additions & 4 deletions modules/remediation/actions/replace.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,19 @@ public function run() : ?DOMDocument {

$outer_html = $this->dom->saveHTML( $element_node );

if ( strpos( $outer_html, $this->data['find'] ) === false ) {
if ( stripos( $outer_html, $this->data['find'] ) === false ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐞 Bug - Breaking Change: Consider making case sensitivity configurable or adding a migration strategy to ensure existing remediation rules continue to work as expected. Document this breaking change clearly.

Suggested change
if ( stripos( $outer_html, $this->data['find'] ) === false ) {
if ( strpos( $outer_html, $this->data['find'] ) === false ) {

return $this->dom;
}

$updated_html = str_replace( $this->data['find'], $this->data['replace'], $outer_html );
$updated_html = str_ireplace( $this->data['find'], $this->data['replace'], $outer_html );

if ( $updated_html === $outer_html ) {
return $this->dom;
}

$tmp_dom = new DOMDocument('1.0', 'UTF-8');
$tmp_dom = new DOMDocument( '1.0', 'UTF-8' );
$tmp_dom->loadHTML(
mb_convert_encoding($updated_html, 'HTML-ENTITIES', 'UTF-8'),
mb_convert_encoding( $updated_html, 'HTML-ENTITIES', 'UTF-8' ),
LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD | LIBXML_NOERROR | LIBXML_NOWARNING
);

Expand Down
27 changes: 25 additions & 2 deletions modules/remediation/assets/js/actions/replace.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
import { RemediationBase } from './base';

export class ReplaceRemediation extends RemediationBase {
replaceIgnoreCase(outerHtml, find, replace, lowerOuterHTML, lowerFind) {
const index = lowerOuterHTML.indexOf(lowerFind);
if (index === -1) {
return outerHtml;
}
return (
outerHtml.substring(0, index) +
replace +
outerHtml.substring(index + find.length)
);
}

run() {
const { xpath, find, replace } = this.data;
const el = this.getElementByXPath(xpath);
Expand All @@ -11,13 +23,24 @@ export class ReplaceRemediation extends RemediationBase {
if (typeof find !== 'string' || typeof replace !== 'string') {
return false;
}
if (!outerHTML.includes(find)) {
const lowerOuterHTML = outerHTML.toLowerCase();
const lowerFind = find.toLowerCase();
if (!lowerOuterHTML.includes(lowerFind)) {
return false;
}
const updatedHTML = outerHTML.replace(find, replace);

const updatedHTML = this.replaceIgnoreCase(
outerHTML,
find,
replace,
lowerOuterHTML,
lowerFind,
);

if (updatedHTML === outerHTML) {
return false;
}

// Create a temporary container to parse the HTML string
const tmp = document.createElement('div');
tmp.innerHTML = updatedHTML;
Expand Down
2 changes: 1 addition & 1 deletion modules/remediation/classes/utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public static function get_current_object_type() : string {

if ( $wp_query->is_singular() ) {
if ( $wp_query->is_single() ) {
return $wp_query->query_vars['post_type'] ?? 'unknown';
return get_post_type($wp_query->get_queried_object_id()) ?? 'unknown';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐞 Bug - Method Change Risk: Add fallback logic to the original method if get_post_type returns null or false, ensuring backward compatibility.

Suggested change
return get_post_type($wp_query->get_queried_object_id()) ?? 'unknown';
return get_post_type($wp_query->get_queried_object_id()) ?: ($wp_query->query_vars['post_type'] ?? 'post');

} elseif ( $wp_query->is_page() ) {
return 'page';
} elseif ( $wp_query->is_attachment() ) {
Expand Down
2 changes: 2 additions & 0 deletions modules/scanner/assets/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ const App = () => {
<StyledPaper>
<ErrorBoundary fallback={<ErrorMessage />}>
<Header />

{showResolvedMessage ? <ResolvedMessage /> : getBlock()}

<Notifications message={notificationMessage} type={notificationType} />
</ErrorBoundary>
</StyledPaper>
Expand Down
7 changes: 6 additions & 1 deletion modules/scanner/assets/js/components/block-button/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,17 @@ export const BlockButton = ({
color={resolved ? 'success' : 'default'}
>
<Box display="flex" alignItems="center" gap={0.5}>
<Typography variant="subtitle2">{title}</Typography>
<Typography variant="subtitle2" as="h4">
{title}
</Typography>

{showChip && (
<Chip label={count} color="error" variant="standard" size="tiny" />
)}
</Box>

{resolved && <CircleCheckFilledIcon color="success" />}

{isManage && (
<Chip
label={sprintf(
Expand Down
5 changes: 4 additions & 1 deletion modules/scanner/assets/js/components/header/breadcrumbs.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,15 @@ export const Breadcrumbs = () => {
>
<ArrowLeftIcon />
</IconButton>

<Box display="flex" alignItems="center" gap={1}>
<Typography variant="subtitle2" sx={{ maxWidth: '180px' }}>
<Typography variant="subtitle2" as="h3">
{BLOCK_TITLES[openedBlock]}
</Typography>

{BLOCK_INFO[openedBlock] && (
<Infotip
tabIndex="0"
PopperProps={{
disablePortal: true,
}}
Expand Down
18 changes: 12 additions & 6 deletions modules/scanner/assets/js/components/header/dropdown-menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,9 @@ export const DropdownMenu = () => {
});
};

const onRunNewScan = () => {
const onRescan = () => {
runNewScan();
sendOnClickEvent('New Scan');
sendOnClickEvent('Rescan');
};

const goToManagement = () => {
Expand All @@ -61,12 +61,14 @@ export const DropdownMenu = () => {
>
<DotsHorizontalIcon />
</IconButton>

<Menu
open={isOpened}
id="assistant-menu"
anchorEl={anchorEl.current}
container={anchorEl.current}
onClose={handleClose}
anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }}
transformOrigin={{ vertical: 'top', horizontal: 'right' }}
MenuListProps={{
'aria-labelledby': 'menu-button',
}}
Expand All @@ -77,12 +79,14 @@ export const DropdownMenu = () => {
}}
disablePortal
>
<MenuItem onClick={onRunNewScan}>
<MenuItem onClick={onRescan} dense>
<MenuItemIcon>
<RefreshIcon />
</MenuItemIcon>
<MenuItemText>{__('New Scan', 'pojo-accessibility')}</MenuItemText>

<MenuItemText>{__('Rescan', 'pojo-accessibility')}</MenuItemText>
</MenuItem>

{!remediations.length ? (
<Tooltip
arrow
Expand All @@ -103,7 +107,7 @@ export const DropdownMenu = () => {
],
}}
>
<MenuItem>
<MenuItem dense>
<MenuItemIcon>
<SettingsIcon color="disabled" />
</MenuItemIcon>
Expand All @@ -117,6 +121,7 @@ export const DropdownMenu = () => {
onClick={goToManagement}
disabled={isManage}
selected={isManage}
dense
>
<MenuItemIcon>
<SettingsIcon />
Expand All @@ -133,6 +138,7 @@ export const DropdownMenu = () => {
target="_blank"
rel="noreferrer"
onClick={() => sendOnClickEvent('View subscription')}
dense
>
<MenuItemIcon>
<CalendarDollarIcon />
Expand Down
15 changes: 12 additions & 3 deletions modules/scanner/assets/js/components/header/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,10 @@ export const Header = () => {
<TitleBox
sx={{ mb: window.ea11yScannerData?.isConnected && !isError ? 2 : 0 }}
>
<Typography variant="subtitle1" color="text.primary">
<Typography variant="subtitle1" as="h3" color="text.primary">
{window?.ea11yScannerData?.pageData?.title}
</Typography>

{showChip && (
<Chip
size="tiny"
Expand Down Expand Up @@ -119,15 +120,16 @@ export const Header = () => {
{isManage ? (
<>
<SettingsIcon size="small" color="action" />
<StyledTitle variant="subtitle1">

<StyledTitle variant="subtitle1" as="h2">
{__('Manage AI fixes', 'pojo-accessibility')}
</StyledTitle>
</>
) : (
<>
<Logo />

<StyledTitle variant="subtitle1">
<StyledTitle variant="subtitle1" as="h2">
{__('Accessibility Assistant', 'pojo-accessibility')}

<Chip
Expand All @@ -153,6 +155,7 @@ export const Header = () => {
</Box>
</HeaderContent>
</Paper>

{showMainBlock && (
<HeaderContent>
{isMainHeader ? (
Expand All @@ -176,6 +179,12 @@ const StyledCard = styled(Card)`
`;

const StyledTitle = styled(Typography)`
font-size: 16px;
font-weight: 500;
line-height: 130%;
letter-spacing: 0.15px;
margin: 0;

.MuiChip-root {
margin-inline-start: ${({ theme }) => theme.spacing(1)};

Expand Down
Loading
Loading