1/* 2 * jQuery Remove Uppercase Accents v1.2.0 3 * http://github.com/ebababi/jquery-remove-upcase-accents/ 4 * 5 * Automatically removes accented characters (currently greek) from elements 6 * having their text content uppercase transformed through CSS. 7 * 8 * Copyright © 2012-2017 Nikolaos Anastopoulos 9 * All rights reserved. 10 * 11 * This program is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation, either version 3 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program. If not, see <http://www.gnu.org/licenses/>. 23 */ 24 25(function( jQuery ) { 26 27jQuery.extend(jQuery.expr[":"], { 28 uppercase: function( elem ) { 29 var attr = jQuery( elem ).css( "text-transform" ); 30 return ( typeof attr !== "undefined" && attr === "uppercase" ); 31 }, 32 smallcaps: function( elem ) { 33 var attr = jQuery( elem ).css( "font-variant" ); 34 return ( typeof attr !== "undefined" && attr === "small-caps" ); 35 } 36}); 37 38jQuery.extend({ 39 removeAcc: function( elem ) { 40 // Replace uppercase accented greek characters 41 function removeAccEL( text ) { 42 return typeof text !== "string" ? 43 // handle cases that text is not a string 44 text : 45 // global replace of uppercase accented characters 46 text. 47 replace( /\u0386/g, "\u0391" ). // 'Î':'Î' 48 replace( /\u0388/g, "\u0395" ). // 'Î':'Î' 49 replace( /\u0389/g, "\u0397" ). // 'Î':'Î' 50 replace( /\u038A/g, "\u0399" ). // 'Î':'Î' 51 replace( /\u038C/g, "\u039F" ). // 'Î':'Î' 52 replace( /\u038E/g, "\u03A5" ). // 'Î':'Î¥' 53 replace( /\u038F/g, "\u03A9" ). // 'Î':'Ω' 54 replace( /\u0390/g, "\u03CA" ). // 'Î':'Ï' 55 replace( /\u03AC/g, "\u03B1" ). // 'ά':'α' 56 replace( /\u03AD/g, "\u03B5" ). // 'Î':'ε' 57 replace( /\u03AE/g, "\u03B7" ). // 'ή':'η' 58 replace( /\u03AF/g, "\u03B9" ). // 'ί':'ι' 59 replace( /\u03B0/g, "\u03CB" ). // 'ΰ':'Ï' 60 replace( /\u03CC/g, "\u03BF" ). // 'Ï':'ο' 61 replace( /\u03CD/g, "\u03C5" ). // 'Ï':'Ï ' 62 replace( /\u03CE/g, "\u03C9" ); // 'Ï':'Ï' 63 } 64 65 jQuery( elem ).each(function() { 66 this.value = removeAccEL( this.value ); 67 }).contents().filter(function() { 68 return this.nodeType === 3; // Node.TEXT_NODE 69 }).each(function() { 70 this.nodeValue = removeAccEL( this.nodeValue ); 71 }); 72 } 73}); 74 75jQuery.fn.extend({ 76 removeAcc: function() { 77 return this.each(function() { 78 jQuery.removeAcc( this ); 79 }); 80 } 81}); 82 83})( jQuery ); 84 85jQuery( document ).ready(function($) { 86 /** 87 * Apply accent removal to all matching elements. 88 * Scoped to an optional root element for performance with MutationObserver. 89 */ 90 function grmltApplyAccentRemoval( root ) { 91 var $scope = root ? $( root ) : $( document ); 92 $scope.find( ":uppercase:not(input[type!=submit], textarea, .no-remove-accents)" ).removeAcc(); 93 $scope.find( ":smallcaps:not(input[type!=submit], textarea, .no-remove-accents)" ).removeAcc(); 94 $scope.find( ".remove-accents, .remove-accents > *:not(input[type!=submit], textarea, .no-remove-accents)" ).removeAcc(); 95 // Also apply to root itself if it matches 96 if ( root ) { 97 $( root ).filter( ":uppercase:not(input[type!=submit], textarea, .no-remove-accents)" ).removeAcc(); 98 $( root ).filter( ":smallcaps:not(input[type!=submit], textarea, .no-remove-accents)" ).removeAcc(); 99 } 100 } 101 102 // Initial application on page load 103 grmltApplyAccentRemoval(); 104 105 // Re-apply after any AJAX request (covers classic WP AJAX, WP Bakery AJAX loading, etc.) 106 $( document ).ajaxComplete(function( event, request, settings ) { 107 grmltApplyAccentRemoval(); 108 }); 109 110 /** 111 * MutationObserver for dynamic content loaded by page builders. 112 * 113 * WP Bakery (frontend editor), Elementor, and other page builders insert 114 * content dynamically into the DOM. The MutationObserver watches for new 115 * nodes and applies accent removal to them automatically. 116 */ 117 if ( typeof MutationObserver !== 'undefined' ) { 118 var grmltDebounceTimer = null; 119 var grmltObserver = new MutationObserver(function( mutations ) { 120 // Debounce to avoid running on every tiny DOM change 121 if ( grmltDebounceTimer ) { 122 clearTimeout( grmltDebounceTimer ); 123 } 124 grmltDebounceTimer = setTimeout(function() { 125 var hasNewContent = false; 126 for ( var i = 0; i < mutations.length; i++ ) { 127 if ( mutations[ i ].addedNodes && mutations[ i ].addedNodes.length > 0 ) { 128 for ( var j = 0; j < mutations[ i ].addedNodes.length; j++ ) { 129 var node = mutations[ i ].addedNodes[ j ]; 130 if ( node.nodeType === 1 ) { // Element nodes only 131 grmltApplyAccentRemoval( node ); 132 hasNewContent = true; 133 } 134 } 135 } 136 } 137 // Full re-scan if many nodes changed (page builder re-render) 138 if ( hasNewContent ) { 139 grmltApplyAccentRemoval(); 140 } 141 }, 100 ); 142 }); 143 144 grmltObserver.observe( document.body, { 145 childList: true, 146 subtree: true 147 }); 148 149 // Elementor frontend: also observe the preview iframe if present 150 $( window ).on( 'elementor/frontend/init', function() { 151 setTimeout(function() { 152 grmltApplyAccentRemoval(); 153 }, 500 ); 154 }); 155 } 156 157 // WP Bakery frontend editor: listen for vc-shortcode-render events 158 $( document ).on( 'vc-full-width-row vc-shortcodes-rendered', function() { 159 grmltApplyAccentRemoval(); 160 }); 161 162 // Elementor: listen for its frontend initialization events 163 $( window ).on( 'elementor/frontend/init', function() { 164 if ( typeof elementorFrontend !== 'undefined' && elementorFrontend.hooks ) { 165 elementorFrontend.hooks.addAction( 'frontend/element_ready/global', function( $element ) { 166 grmltApplyAccentRemoval( $element[0] ); 167 }); 168 } 169 }); 170});
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.