Changeset 3174459
- Timestamp:
- 10/23/2024 03:40:03 PM (16 months ago)
- Location:
- accessibility-new-window-warnings
- Files:
-
- 8 edited
- 1 copied
-
tags/1.0.10 (copied) (copied from accessibility-new-window-warnings/trunk)
-
tags/1.0.10/README.txt (modified) (2 diffs)
-
tags/1.0.10/accessibility-new-window-warnings.php (modified) (2 diffs)
-
tags/1.0.10/assets/js/accessibility-new-window-warnings-min.js (modified) (1 diff)
-
tags/1.0.10/assets/js/accessibility-new-window-warnings.js (modified) (1 diff)
-
trunk/README.txt (modified) (2 diffs)
-
trunk/accessibility-new-window-warnings.php (modified) (2 diffs)
-
trunk/assets/js/accessibility-new-window-warnings-min.js (modified) (1 diff)
-
trunk/assets/js/accessibility-new-window-warnings.js (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
accessibility-new-window-warnings/tags/1.0.10/README.txt
r3137333 r3174459 3 3 Tags: accessibility, accessible, wcag, ada, a11y, section 508, links, open new window, open new tab 4 4 Requires at least: 6.4.0 5 Tested up to: 6.6. 16 Stable tag: 1.0. 95 Tested up to: 6.6.2 6 Stable tag: 1.0.10 7 7 License: GPLv2 or later 8 8 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 75 75 == Changelog == 76 76 77 = 1.0.10 = 78 * Added - detection and processing of window.open() links with consistent tooltip/ARIA label handling for both target="_blank" and window.open() 79 77 80 = 1.0.9 = 78 81 * Updated - tested up to version -
accessibility-new-window-warnings/tags/1.0.10/accessibility-new-window-warnings.php
r3137333 r3174459 4 4 * Plugin URI: https://a11ychecker.com 5 5 * Description: Make links that open in a new window accessible by adding a warning. 6 * Version: 1.0. 96 * Version: 1.0.10 7 7 * Author: Equalize Digital 8 8 * Author URI: https://equalizedigital.com … … 14 14 */ 15 15 16 define( 'ANWW_VERSION', '1.0. 9' );16 define( 'ANWW_VERSION', '1.0.10' ); 17 17 define( 'ANWW_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); 18 18 define( 'ANWW_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); -
accessibility-new-window-warnings/tags/1.0.10/assets/js/accessibility-new-window-warnings-min.js
r2960276 r3174459 1 !function($){"use strict";var n;function t(){var t="";$(".anww-external-link-icon").remove(),$("a[target=_blank]").each((function(){$(":header",this).length?$(":header",this).append('<i class="anww-external-link-icon" aria-hidden="true"></i>'):$(this).append('<i class="anww-external-link-icon" aria-hidden="true"></i>'),$(this).attr("aria-label")?t=$(this).attr("aria-label"):$("img",$(this)).length?t=$(this).find("img").attr("alt"):$(this).text()&&(t=$(this).text()),t?(t=t.trimEnd(),t+=", "+anww_localized.opens_a_new_window):t+=anww_localized.opens_a_new_window,$(this).attr("aria-label",t),$(this).mousemove((function(t){n.css({top:t.pageY+10+"px",left:t.pageX+10+"px"})})).hover((function(){n.show().html(anww_localized.opens_a_new_window)}),(function(){n.hide()})),$(this).on({focusin:function(){var t=$(this).offset();n.css({top:t.top+$(this).outerHeight()+"px",left:t.left+"px"}),n.show().html(anww_localized.opens_a_new_window)},focusout:function(){n.hide()}})}))}$(window).on("load",(function(){n=$("<div/>").css({position:"absolute",background:"white",color:"#1e1e1e",fontSize:"16px",border:"1px solid black",padding:"5px 10px",zIndex:9999,display:"none"}).addClass("anww-tooltip").appendTo("body"),t()})),$(document).on("facetwp-loaded",t)}(jQuery);1 !function($){"use strict";var n;function e(){var e="";$(".anww-external-link-icon").remove(),$("a").each((function(){var t=$(this).attr("onclick");if("_blank"===$(this).attr("target")&&(o($(this)),l($(this)),d($(this)),!0),t&&t.includes("window.open")){var a=t.match(/window\.open\([^,]+,\s*['"]([^'"]+)['"]/),i=a?a[1]:"";"_blank"!==i&&""!==i||(o($(this)),l($(this)),d($(this)),!0)}function o(n){$(":header",n).length?$(":header",n).append('<i class="anww-external-link-icon" aria-hidden="true"></i>'):n.append('<i class="anww-external-link-icon" aria-hidden="true"></i>')}function l(n){n.attr("aria-label")?e=n.attr("aria-label"):$("img",n).length?e=n.find("img").attr("alt"):n.text()&&(e=n.text()),e?(e=e.trimEnd(),e+=", "+anww_localized.opens_a_new_window):e+=anww_localized.opens_a_new_window,n.attr("aria-label",e)}function d(e){e.mousemove((function(e){n.css({top:e.pageY+10+"px",left:e.pageX+10+"px"})})).hover((function(){n.show().html(anww_localized.opens_a_new_window)}),(function(){n.hide()})),e.on({focusin:function(){var t=e.offset();n.css({top:t.top+e.outerHeight()+"px",left:t.left+"px"}),n.show().html(anww_localized.opens_a_new_window)},focusout:function(){n.hide()}})}}))}$(window).on("load",(function(){n=$("<div/>").css({position:"absolute",background:"white",color:"#1e1e1e",fontSize:"16px",border:"1px solid black",padding:"5px 10px",zIndex:9999,display:"none"}).addClass("anww-tooltip").appendTo("body"),e()})),$(document).on("facetwp-loaded",e)}(jQuery); -
accessibility-new-window-warnings/tags/1.0.10/assets/js/accessibility-new-window-warnings.js
r2960276 r3174459 1 1 (function ($) { 2 "use strict";2 "use strict"; 3 3 4 var anww_link_tooltip;4 var anww_link_tooltip; 5 5 6 function initializeTooltip() {7 anww_link_tooltip = $('<div/>').css({8 position: 'absolute',9 background: 'white',10 color: '#1e1e1e',11 fontSize: '16px',12 border: '1px solid black',13 padding: '5px 10px',14 zIndex: 9999,15 display: 'none'16 }).addClass('anww-tooltip').appendTo('body');17 }6 function initializeTooltip() { 7 anww_link_tooltip = $('<div/>').css({ 8 position: 'absolute', 9 background: 'white', 10 color: '#1e1e1e', 11 fontSize: '16px', 12 border: '1px solid black', 13 padding: '5px 10px', 14 zIndex: 9999, 15 display: 'none' 16 }).addClass('anww-tooltip').appendTo('body'); 17 } 18 18 19 function processLinks() {20 var anww_label = '';19 function processLinks() { 20 var anww_label = ''; 21 21 22 // Remove previously appended icons to avoid duplication23 $(".anww-external-link-icon").remove();22 // Remove previously appended icons to avoid duplication 23 $(".anww-external-link-icon").remove(); 24 24 25 $("a[target=_blank]").each(function () { 26 // Add icon to link 27 if ($(':header', this).length) { 28 $(':header', this).append('<i class="anww-external-link-icon" aria-hidden="true"></i>'); 29 } else { 30 $(this).append('<i class="anww-external-link-icon" aria-hidden="true"></i>'); 31 } 25 $("a").each(function () { 26 var hasIcon = false; 27 var onclickAttr = $(this).attr("onclick"); 32 28 33 // Get aria label text 34 if ($(this).attr("aria-label")) { 35 anww_label = $(this).attr("aria-label"); 36 } else if ($('img', $(this)).length) { 37 anww_label = $(this).find("img").attr("alt"); 38 } else if ($(this).text()) { 39 anww_label = $(this).text(); 40 } 29 // Check if the link opens a new window using target="_blank" 30 if ($(this).attr("target") === "_blank") { 31 addExternalLinkIcon($(this)); 32 updateAriaLabel($(this)); 33 addTooltipHandlers($(this)); 34 hasIcon = true; 35 } 41 36 42 // Add warning label 43 if (anww_label) { 44 anww_label = anww_label.trimEnd(); 45 anww_label += ", " + anww_localized.opens_a_new_window; 46 } else { 47 anww_label += anww_localized.opens_a_new_window; 48 } 37 // Check if the link uses window.open in the onclick attribute 38 if (onclickAttr && onclickAttr.includes("window.open")) { 39 // Extract window.open arguments 40 var windowOpenMatch = onclickAttr.match(/window\.open\([^,]+,\s*['"]([^'"]+)['"]/); 41 var targetWindow = windowOpenMatch ? windowOpenMatch[1] : ''; 49 42 50 // Add aria-label to link 51 $(this).attr("aria-label", anww_label); 43 // Ensure window.open is opening a new window (i.e., '_blank') 44 if (targetWindow === '_blank' || targetWindow === '') { 45 addExternalLinkIcon($(this)); 46 updateAriaLabel($(this)); 47 addTooltipHandlers($(this)); 48 hasIcon = true; 49 } 50 } 52 51 53 // Position and show link_tooltip on hover 54 $(this).mousemove(function (e) { 55 anww_link_tooltip.css({ 56 top: e.pageY + 10 + 'px', 57 left: e.pageX + 10 + 'px' 58 }); 59 }) 60 .hover(function () { 61 anww_link_tooltip.show().html(anww_localized.opens_a_new_window); 62 }, function () { 63 anww_link_tooltip.hide(); 64 }); 52 // If no external link behavior detected, do not proceed with tooltip 53 if (!hasIcon) { 54 return; 55 } 65 56 66 // Position and show link_tooltip on focus 67 $(this).on({ 68 focusin: function () {69 var position = $(this).offset();70 anww_link_tooltip.css({71 top: position.top + $(this).outerHeight() + 'px', 72 left: position.left + 'px' 73 }); 57 function addExternalLinkIcon(link) { 58 // Add icon to link 59 if ($(':header', link).length) { 60 $(':header', link).append('<i class="anww-external-link-icon" aria-hidden="true"></i>'); 61 } else { 62 link.append('<i class="anww-external-link-icon" aria-hidden="true"></i>'); 63 } 64 } 74 65 75 anww_link_tooltip.show().html(anww_localized.opens_a_new_window); 76 }, 77 focusout: function () { 78 anww_link_tooltip.hide(); 79 } 80 }); 81 }); 82 } 66 function updateAriaLabel(link) { 67 // Get aria label text 68 if (link.attr("aria-label")) { 69 anww_label = link.attr("aria-label"); 70 } else if ($('img', link).length) { 71 anww_label = link.find("img").attr("alt"); 72 } else if (link.text()) { 73 anww_label = link.text(); 74 } 83 75 84 $(window).on('load', function () { 85 initializeTooltip(); 86 processLinks(); 87 }); 76 // Add warning label 77 if (anww_label) { 78 anww_label = anww_label.trimEnd(); 79 anww_label += ", " + anww_localized.opens_a_new_window; 80 } else { 81 anww_label += anww_localized.opens_a_new_window; 82 } 88 83 89 // Support for FacetWP: Re-run the processLinks function when FacetWP refreshes the page 90 $(document).on('facetwp-loaded', processLinks); 84 // Add aria-label to link 85 link.attr("aria-label", anww_label); 86 } 87 88 function addTooltipHandlers(link) { 89 // Position and show link_tooltip on hover 90 link.mousemove(function (e) { 91 anww_link_tooltip.css({ 92 top: e.pageY + 10 + 'px', 93 left: e.pageX + 10 + 'px' 94 }); 95 }) 96 .hover(function () { 97 anww_link_tooltip.show().html(anww_localized.opens_a_new_window); 98 }, function () { 99 anww_link_tooltip.hide(); 100 }); 101 102 // Position and show link_tooltip on focus 103 link.on({ 104 focusin: function () { 105 var position = link.offset(); 106 anww_link_tooltip.css({ 107 top: position.top + link.outerHeight() + 'px', 108 left: position.left + 'px' 109 }); 110 111 anww_link_tooltip.show().html(anww_localized.opens_a_new_window); 112 }, 113 focusout: function () { 114 anww_link_tooltip.hide(); 115 } 116 }); 117 } 118 }); 119 } 120 121 $(window).on('load', function () { 122 initializeTooltip(); 123 processLinks(); 124 }); 125 126 // Support for FacetWP: Re-run the processLinks function when FacetWP refreshes the page 127 $(document).on('facetwp-loaded', processLinks); 91 128 92 129 })(jQuery); -
accessibility-new-window-warnings/trunk/README.txt
r3137333 r3174459 3 3 Tags: accessibility, accessible, wcag, ada, a11y, section 508, links, open new window, open new tab 4 4 Requires at least: 6.4.0 5 Tested up to: 6.6. 16 Stable tag: 1.0. 95 Tested up to: 6.6.2 6 Stable tag: 1.0.10 7 7 License: GPLv2 or later 8 8 License URI: http://www.gnu.org/licenses/gpl-2.0.html … … 75 75 == Changelog == 76 76 77 = 1.0.10 = 78 * Added - detection and processing of window.open() links with consistent tooltip/ARIA label handling for both target="_blank" and window.open() 79 77 80 = 1.0.9 = 78 81 * Updated - tested up to version -
accessibility-new-window-warnings/trunk/accessibility-new-window-warnings.php
r3137333 r3174459 4 4 * Plugin URI: https://a11ychecker.com 5 5 * Description: Make links that open in a new window accessible by adding a warning. 6 * Version: 1.0. 96 * Version: 1.0.10 7 7 * Author: Equalize Digital 8 8 * Author URI: https://equalizedigital.com … … 14 14 */ 15 15 16 define( 'ANWW_VERSION', '1.0. 9' );16 define( 'ANWW_VERSION', '1.0.10' ); 17 17 define( 'ANWW_PLUGIN_DIR', plugin_dir_path( __FILE__ ) ); 18 18 define( 'ANWW_PLUGIN_URL', plugin_dir_url( __FILE__ ) ); -
accessibility-new-window-warnings/trunk/assets/js/accessibility-new-window-warnings-min.js
r2960276 r3174459 1 !function($){"use strict";var n;function t(){var t="";$(".anww-external-link-icon").remove(),$("a[target=_blank]").each((function(){$(":header",this).length?$(":header",this).append('<i class="anww-external-link-icon" aria-hidden="true"></i>'):$(this).append('<i class="anww-external-link-icon" aria-hidden="true"></i>'),$(this).attr("aria-label")?t=$(this).attr("aria-label"):$("img",$(this)).length?t=$(this).find("img").attr("alt"):$(this).text()&&(t=$(this).text()),t?(t=t.trimEnd(),t+=", "+anww_localized.opens_a_new_window):t+=anww_localized.opens_a_new_window,$(this).attr("aria-label",t),$(this).mousemove((function(t){n.css({top:t.pageY+10+"px",left:t.pageX+10+"px"})})).hover((function(){n.show().html(anww_localized.opens_a_new_window)}),(function(){n.hide()})),$(this).on({focusin:function(){var t=$(this).offset();n.css({top:t.top+$(this).outerHeight()+"px",left:t.left+"px"}),n.show().html(anww_localized.opens_a_new_window)},focusout:function(){n.hide()}})}))}$(window).on("load",(function(){n=$("<div/>").css({position:"absolute",background:"white",color:"#1e1e1e",fontSize:"16px",border:"1px solid black",padding:"5px 10px",zIndex:9999,display:"none"}).addClass("anww-tooltip").appendTo("body"),t()})),$(document).on("facetwp-loaded",t)}(jQuery);1 !function($){"use strict";var n;function e(){var e="";$(".anww-external-link-icon").remove(),$("a").each((function(){var t=$(this).attr("onclick");if("_blank"===$(this).attr("target")&&(o($(this)),l($(this)),d($(this)),!0),t&&t.includes("window.open")){var a=t.match(/window\.open\([^,]+,\s*['"]([^'"]+)['"]/),i=a?a[1]:"";"_blank"!==i&&""!==i||(o($(this)),l($(this)),d($(this)),!0)}function o(n){$(":header",n).length?$(":header",n).append('<i class="anww-external-link-icon" aria-hidden="true"></i>'):n.append('<i class="anww-external-link-icon" aria-hidden="true"></i>')}function l(n){n.attr("aria-label")?e=n.attr("aria-label"):$("img",n).length?e=n.find("img").attr("alt"):n.text()&&(e=n.text()),e?(e=e.trimEnd(),e+=", "+anww_localized.opens_a_new_window):e+=anww_localized.opens_a_new_window,n.attr("aria-label",e)}function d(e){e.mousemove((function(e){n.css({top:e.pageY+10+"px",left:e.pageX+10+"px"})})).hover((function(){n.show().html(anww_localized.opens_a_new_window)}),(function(){n.hide()})),e.on({focusin:function(){var t=e.offset();n.css({top:t.top+e.outerHeight()+"px",left:t.left+"px"}),n.show().html(anww_localized.opens_a_new_window)},focusout:function(){n.hide()}})}}))}$(window).on("load",(function(){n=$("<div/>").css({position:"absolute",background:"white",color:"#1e1e1e",fontSize:"16px",border:"1px solid black",padding:"5px 10px",zIndex:9999,display:"none"}).addClass("anww-tooltip").appendTo("body"),e()})),$(document).on("facetwp-loaded",e)}(jQuery); -
accessibility-new-window-warnings/trunk/assets/js/accessibility-new-window-warnings.js
r2960276 r3174459 1 1 (function ($) { 2 "use strict";2 "use strict"; 3 3 4 var anww_link_tooltip;4 var anww_link_tooltip; 5 5 6 function initializeTooltip() {7 anww_link_tooltip = $('<div/>').css({8 position: 'absolute',9 background: 'white',10 color: '#1e1e1e',11 fontSize: '16px',12 border: '1px solid black',13 padding: '5px 10px',14 zIndex: 9999,15 display: 'none'16 }).addClass('anww-tooltip').appendTo('body');17 }6 function initializeTooltip() { 7 anww_link_tooltip = $('<div/>').css({ 8 position: 'absolute', 9 background: 'white', 10 color: '#1e1e1e', 11 fontSize: '16px', 12 border: '1px solid black', 13 padding: '5px 10px', 14 zIndex: 9999, 15 display: 'none' 16 }).addClass('anww-tooltip').appendTo('body'); 17 } 18 18 19 function processLinks() {20 var anww_label = '';19 function processLinks() { 20 var anww_label = ''; 21 21 22 // Remove previously appended icons to avoid duplication23 $(".anww-external-link-icon").remove();22 // Remove previously appended icons to avoid duplication 23 $(".anww-external-link-icon").remove(); 24 24 25 $("a[target=_blank]").each(function () { 26 // Add icon to link 27 if ($(':header', this).length) { 28 $(':header', this).append('<i class="anww-external-link-icon" aria-hidden="true"></i>'); 29 } else { 30 $(this).append('<i class="anww-external-link-icon" aria-hidden="true"></i>'); 31 } 25 $("a").each(function () { 26 var hasIcon = false; 27 var onclickAttr = $(this).attr("onclick"); 32 28 33 // Get aria label text 34 if ($(this).attr("aria-label")) { 35 anww_label = $(this).attr("aria-label"); 36 } else if ($('img', $(this)).length) { 37 anww_label = $(this).find("img").attr("alt"); 38 } else if ($(this).text()) { 39 anww_label = $(this).text(); 40 } 29 // Check if the link opens a new window using target="_blank" 30 if ($(this).attr("target") === "_blank") { 31 addExternalLinkIcon($(this)); 32 updateAriaLabel($(this)); 33 addTooltipHandlers($(this)); 34 hasIcon = true; 35 } 41 36 42 // Add warning label 43 if (anww_label) { 44 anww_label = anww_label.trimEnd(); 45 anww_label += ", " + anww_localized.opens_a_new_window; 46 } else { 47 anww_label += anww_localized.opens_a_new_window; 48 } 37 // Check if the link uses window.open in the onclick attribute 38 if (onclickAttr && onclickAttr.includes("window.open")) { 39 // Extract window.open arguments 40 var windowOpenMatch = onclickAttr.match(/window\.open\([^,]+,\s*['"]([^'"]+)['"]/); 41 var targetWindow = windowOpenMatch ? windowOpenMatch[1] : ''; 49 42 50 // Add aria-label to link 51 $(this).attr("aria-label", anww_label); 43 // Ensure window.open is opening a new window (i.e., '_blank') 44 if (targetWindow === '_blank' || targetWindow === '') { 45 addExternalLinkIcon($(this)); 46 updateAriaLabel($(this)); 47 addTooltipHandlers($(this)); 48 hasIcon = true; 49 } 50 } 52 51 53 // Position and show link_tooltip on hover 54 $(this).mousemove(function (e) { 55 anww_link_tooltip.css({ 56 top: e.pageY + 10 + 'px', 57 left: e.pageX + 10 + 'px' 58 }); 59 }) 60 .hover(function () { 61 anww_link_tooltip.show().html(anww_localized.opens_a_new_window); 62 }, function () { 63 anww_link_tooltip.hide(); 64 }); 52 // If no external link behavior detected, do not proceed with tooltip 53 if (!hasIcon) { 54 return; 55 } 65 56 66 // Position and show link_tooltip on focus 67 $(this).on({ 68 focusin: function () {69 var position = $(this).offset();70 anww_link_tooltip.css({71 top: position.top + $(this).outerHeight() + 'px', 72 left: position.left + 'px' 73 }); 57 function addExternalLinkIcon(link) { 58 // Add icon to link 59 if ($(':header', link).length) { 60 $(':header', link).append('<i class="anww-external-link-icon" aria-hidden="true"></i>'); 61 } else { 62 link.append('<i class="anww-external-link-icon" aria-hidden="true"></i>'); 63 } 64 } 74 65 75 anww_link_tooltip.show().html(anww_localized.opens_a_new_window); 76 }, 77 focusout: function () { 78 anww_link_tooltip.hide(); 79 } 80 }); 81 }); 82 } 66 function updateAriaLabel(link) { 67 // Get aria label text 68 if (link.attr("aria-label")) { 69 anww_label = link.attr("aria-label"); 70 } else if ($('img', link).length) { 71 anww_label = link.find("img").attr("alt"); 72 } else if (link.text()) { 73 anww_label = link.text(); 74 } 83 75 84 $(window).on('load', function () { 85 initializeTooltip(); 86 processLinks(); 87 }); 76 // Add warning label 77 if (anww_label) { 78 anww_label = anww_label.trimEnd(); 79 anww_label += ", " + anww_localized.opens_a_new_window; 80 } else { 81 anww_label += anww_localized.opens_a_new_window; 82 } 88 83 89 // Support for FacetWP: Re-run the processLinks function when FacetWP refreshes the page 90 $(document).on('facetwp-loaded', processLinks); 84 // Add aria-label to link 85 link.attr("aria-label", anww_label); 86 } 87 88 function addTooltipHandlers(link) { 89 // Position and show link_tooltip on hover 90 link.mousemove(function (e) { 91 anww_link_tooltip.css({ 92 top: e.pageY + 10 + 'px', 93 left: e.pageX + 10 + 'px' 94 }); 95 }) 96 .hover(function () { 97 anww_link_tooltip.show().html(anww_localized.opens_a_new_window); 98 }, function () { 99 anww_link_tooltip.hide(); 100 }); 101 102 // Position and show link_tooltip on focus 103 link.on({ 104 focusin: function () { 105 var position = link.offset(); 106 anww_link_tooltip.css({ 107 top: position.top + link.outerHeight() + 'px', 108 left: position.left + 'px' 109 }); 110 111 anww_link_tooltip.show().html(anww_localized.opens_a_new_window); 112 }, 113 focusout: function () { 114 anww_link_tooltip.hide(); 115 } 116 }); 117 } 118 }); 119 } 120 121 $(window).on('load', function () { 122 initializeTooltip(); 123 processLinks(); 124 }); 125 126 // Support for FacetWP: Re-run the processLinks function when FacetWP refreshes the page 127 $(document).on('facetwp-loaded', processLinks); 91 128 92 129 })(jQuery);
Note: See TracChangeset
for help on using the changeset viewer.