< Day Day Up > |
Change Google's layout to make it easier for low-vision users to read. As a class of disabilities, low-vision users are often ignored by accessibility experts. However, accessibility expert Joe Clark has recently published his research into the needs of web users with limited vision. He pioneered a technique known as the zoom layout: a special alternate style applied to a web page that specifically caters to low-vision users. As I was learning about zoom layouts, it occurred to me that this would be a perfect application of Greasemonkey. (Actually, that thought occurs to me a lot these days.) This hack is my first attempt at transforming a site into a zoom layout.
8.11.1. The CodeThis user script runs on several specific Google pages:
Save the following user script as zoom-google.user.js: // ==UserScript== // @name Zoom Google // @namespace http://diveintomark.org/projects/greasemonkey/ // @description make Google more accessible to low-vision users // @include http://www.google.tld/ // @include http://www.google.tld/?* // @include http://www.google.tld/webhp* // @include http://www.google.tld/imghp* // @include http://www.google.tld/search* // @include http://images.google.tld/ // @include http://images.google.tld/?* // @include http://images.google.tld/images* // ==/UserScript== function addGlobalStyle(css) { var elmHead, elmStyle; elmHead = document.getElementsByTagName('head')[0]; elmStyle = document.createElement('style'); elmStyle.type = 'text/css'; elmHead.appendChild(elmStyle); elmStyle.innerHTML = css; } function getElementsByClassName(sTag, sClassName) { sClassName = sClassName.toLowerCase( ) + ' '; var arElements = document.getElementsByTagName(sTag); var iMax = arElements.length; var arResults = new Array( ); for (var i = 0; i < iMax; i++) { var elm = arElements[i]; var sThisClassName = elm.className; if (!sThisClassName) { continue; } sThisClassName = sThisClassName.toLowerCase( ) + ' '; if (sThisClassName.indexOf(sClassName) != -1) { arResults.push(elm); } } return arResults; } function removeFontTags( ) { // remove font tags var arFonts = document.getElementsByTagName('font'); for (var i = arFonts.length - 1; i >= 0; i--) { var elmFont = arFonts[i]; var elmSpan = document.createElement('span'); elmSpan.innerHTML = elmFont.innerHTML; elmFont.parentNode.replaceChild(elmSpan, elmFont); } } function zoomStyle( ) { addGlobalStyle('body { margin: 30px; } \n' + 'body, td { font-size: large ! important; } \n' + 'html>body, html>body td { font-size: x-large ! important; } \n' + 'body, div, td { background: navy ! important; ' + 'color: white ! important; } \n' + 'a:link { background: transparent ! important; ' + 'color: yellow ! important; } \n' + 'a:visited { background: transparent ! important; ' + 'color: lime ! important; } \n' + 'a.fl { background: transparent ! important; ' + 'color: white ! important; } \n' + 'input { font-size: large ! important; } \n' + 'html>body input { font-size: x-large ! important; } \n' + '.g { width: auto ! important; } \n' + '.n a, .n .i { font-size: large ! important; } \n' + 'html>body .n a, html.body .n .i { font-size: x-large ! important; } \n' + '.j { width: auto ! important; }'); } function accHomePage( ) { // remove personalized header, if any var arTable = document.getElementsByTagName('table'); for (var i = arTable.length - 1; i >= 0; i--) { var elmTable = arTable = ar var html = elmTable.innerHTML; if (/\/accounts\/Logout/.test(html)) { elmTable.parentNode.removeChild(elmTable); } } // simplify logo var arImages = document.getElementsByTagName('img'); for (var i = arImages.length - 1; i >= 0; i--) { var elmLogo = arImages[i]; if (elmLogo.alt) { var elmTextLogo = document.createElement('h1'); elmTextLogo.style.fontSize = '400%'; var sAlt = /Firefox/.test(elmLogo.alt) ? '' : elmLogo.alt; elmTextLogo.appendChild(document.createTextNode(sAlt)); elmLogo.parentNode.replaceChild(elmTextLogo, elmLogo); var elmLink = elmTextLogo.parentNode; while (elmLink.nodeName != 'BODY' && elmLink.nodeName != 'HTML' && elmLink.nodeName != 'A') { elmLink = elmLink.parentNode; } elmLink.style.textDecoration = 'none'; } else { elmLogo.parentNode.removeChild(elmLogo); } } // simplify search form if (document.forms.length) { var arTD = document.getElementsByTagName('td'); for (var i = arTD.length - 1; i >= 0; i--) { var elmTD = arTD[i]; if (/Advanced/.test(elmTD.innerHTML)) { elmTD.innerHTML = ''; } } } } function accSearchResults( ) { // simplify logo var elmLogo = document.getElementsByTagName('img')[0]; var elmTextLogo = document.createElement('h1'); elmTextLogo.appendChild(document.createTextNode('Google')); elmTextLogo.style.marginTop = '0.2em'; elmTextLogo.style.marginRight = '0.3em'; elmLogo.parentNode.replaceChild(elmTextLogo, elmLogo); elmTextLogo.parentNode.style.textDecoration = 'none'; // simplify top form var elmAdvancedWrapper = document.getElementsByTagName('table')[3]; var elmAdvanced = elmAdvancedWrapper.getElementsByTagName('td')[1]; elmAdvanced.parentNode.removeChild(elmAdvanced); // remove "tip" if present var elmTip = document.getElementsByTagName('table')[7]; if (/Tip/.test(elmTip.innerHTML)) { elmTip.parentNode.removeChild(elmTip); } // remove ads, if any var aw1 = document.getElementById('aw1'); while (aw1) { var table = aw1.parentNode; while (table.nodeName != 'TABLE') { table = table.parentNode; } table.parentNode.removeChild(table); aw1 = document.getElementById('aw1'); } var tpa1 = document.getElementById('tpa1'); if (tpa1) { while (tpa1.nodeName != 'DIV' && tpa1.nodeName != 'P') { tpa1 = tpa1.parentNode; } tpa1.parentNode.removeChild(tpa1); } var tpa2 = document.getElementById('tpa2'); if (tpa2) { while (tpa2.nodeName != 'DIV' && tpa2.nodeName != 'P') { tpa2 = tpa2.parentNode; } tpa2.parentNode.removeChild(tpa2); } addGlobalStyle('iframe[name="google_ads_frame"] { ' + 'display: none ! important }'); // simplify results count var elmDivider = document.getElementsByTagName('table')[5]; elmDivider.parentNode.removeChild(elmDivider); var elmResultsContainer = document.getElementsByTagName('table')[5]; var arTD = elmResultsContainer.getElementsByTagName('td'); if (arTD.length > 1) { var sResults = arTD[1].textContent; var iParen = sResults.indexOf('('); if (iParen != -1) { sResults = sResults.substring(0, iParen); } var iDef = sResults.indexOf('['); if (iDef != -1) { sResults = sResults.substring(0, iDef); } var elmResults = document.createElement('h2'); elmResults.appendChild(document.createTextNode(sResults)); elmResultsContainer.parentNode.replaceChild(elmResults, elmResultsContainer); } else { elmResultsContainer.parentNode.removeChild(elmResultsContainer); } // make search results use real headers var arResults = getElementsByClassName('p', 'g'); for (var i = arResults.length - 1; i >= 0; i--) { var elmResult = arResults[i]; var arLink = elmResult.getElementsByTagName('a'); if (!arLink.length) { continue; } var elmLink = arLink[0]; var elmWrapper = document.createElement('div'); var elmHeader = document.createElement('h3'); elmHeader.style.margin = elmHeader.style.padding = 0; elmHeader.innerHTML = '<a href="' + elmLink.href + '">' + elmLink.innerHTML + '</a>'; var elmContent = elmResult.cloneNode(true); elmContent.innerHTML = elmContent.innerHTML.replace(/<nobr>/g, ''); arLink = elmContent.getElementsByTagName('a'); if (!arLink.length) { continue; } elmLink = arLink[0]; elmContent.removeChild(elmLink); elmContent.style.marginTop = 0; elmWrapper.appendChild(elmHeader); elmWrapper.appendChild(elmContent); elmResult.parentNode.replaceChild(elmWrapper, elmResult); } // simplify next page link var arFont = document.getElementsByTagName('font'); for (var i = arFont.length - 1; i >= 0; i--) { var elmFont = arFont[i]; var html = elmFont.innerHTML; if (/Result\ \;Page\:/.test(html)) { var elmTable = elmFont.parentNode; while (elmTable.nodeName != 'TABLE') { elmTable = elmTable = elm } var arTD = elmTable.getElementsByTagName('td'); if (arTD.length) { var elmTD = arTD[arTD.length - 1]; var arNext = elmTD.getElementsByTagName('a'); if (arNext.length) { var elmNext = arNext[0]; var elmTextNext = document.createElement('center'); elmTextNext.innerHTML = '<p style="font-size: ' + 'xx-large; margin-bottom: 4em;">b><a href="' + elmNext.href + '">More Results ' + '→</a></b></p>'; elmTable.parentNode.replaceChild(elmTextNext, elmTable); } } break; } } // remove bottom ads var arCenter = document.getElementsByTagName('center'); if (arCenter.length > 1) { var elmCenter = arCenter[1]; elmCenter.parentNode.removeChild(elmCenter); elmCenter = arCenter[0]; for (var i = 0; i < 4; i++) { elmCenter.innerHTML = elmCenter.innerHTML.replace(/<br>/, ''); } } } document.forms.namedItem('f') && accHomePage( ); document.forms.namedItem('gs') && accSearchResults( ); removeFontTags( ); zoomStyle( ); 8.11.2. Running the HackAfter installing the user script (Tools Install This User Script), go to http://www.google.com. The normally spartan search form has been magnified and simplified even further, as shown in Figure 8-19. Accessibility studies have shown that low-vision users have an easier time reading light text on a dark background, so therefore the page is displayed as white-on-navy. Unvisited links are displayed in yellow; visited links are displayed in light green. The hack removes several elements from the page, including the Advanced Search link, plus any advertisements for Google services or other messages that occasionally appear below the search box. Figure 8-19. Google home page, zoomedWhen you execute a search, the search results are displayed differently, as shown in Figures 8-20 and 8-21, with the following notable differences:
Figure 8-20. Google search results, zoomedFigure 8-21. Bottom of Google search results, zoomedIf you click the Images link at the top of the page to search for the same keywords in Google Image Search, you will see that the image search results have been similarly hacked, as shown in Figure 8-22. Figure 8-22. Google image results, zoomedAs with the web search results, the top navigation has been simplified, the number of results is more prominent, and the "Goooooooogle" navigation bar has been replaced by a single "More results" link that moves to the next page of images. The image thumbnails themselves cannot be magnified, since Google provides them only in a specific size. |
< Day Day Up > |