Guest User

Dictionary lookup.js for Calibre E-Viewer

a guest
Dec 29th, 2025
42
0
142 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
JavaScript 8.59 KB | Source Code | 0 0
  1. /* vim:fileencoding=utf-8
  2.  *
  3.  * Copyright (C) 2019 Kovid Goyal <kovid at kovidgoyal.net>
  4.  *
  5.  * Distributed under terms of the GPLv3 license
  6.  */
  7.  
  8. (function() {
  9.     "use strict";
  10.  
  11.     var num_tries = 0;
  12.     var style_id = 'a' + Math.random().toString(36).slice(2);
  13.  
  14.     // ========== GOOGLE.COM HANDLER ==========
  15.     function fix_google_markup() {
  16.         try {
  17.             var cc = document.getElementById('center_col');
  18.             if (!cc) {
  19.                 if (++num_tries > 10) return;
  20.                 return setTimeout(fix_google_markup, 100);
  21.             }
  22.  
  23.             // figure out if they actually got a dictionary card
  24.             var is_dictionary_result = !!document.querySelector('.lr_container, .lr_dct_ent');
  25.             // grab the raw query
  26.             var q = new URLSearchParams(location.search.slice(1)).get('q') || ''
  27.  
  28.             if (is_dictionary_result) {
  29.                 // Only add styles once to prevent duplication
  30.                 if (!document.getElementById(style_id)) {
  31.                     var style = document.createElement('style');
  32.                     style.id = style_id;
  33.                     style.textContent = `
  34.                         * {
  35.                             column-gap: 0!important;
  36.                             -webkit-column-gap: 0!important;
  37.                         }
  38.                         #center_col {
  39.                             position: absolute !important;
  40.                             top: 1px !important;
  41.                             left: 0 !important;
  42.                             z-index: 100;
  43.                         }
  44.                         #cnt {
  45.                             position: relative;
  46.                             min-height: 100vh;
  47.                         }
  48.                         /* Clear the space where search form was */
  49.                         #searchform, #appbar, #before-appbar {
  50.                             display: none !important;
  51.                         }
  52.                     `;
  53.                     document.head.appendChild(style);
  54.                 }
  55.  
  56.                 var maxW = 'calc(100vw - 25px)';
  57.                 cc.style.maxWidth   = maxW;
  58.                 cc.style.marginLeft = '0';
  59.  
  60.                 ['rcnt','cnt','search']
  61.                 .forEach(function(id) {
  62.                     var e = document.getElementById(id);
  63.                     if (e) {
  64.                         if (id==='search') e.style.maxWidth = maxW;
  65.                         else if (id==='cnt')  e.style.paddingTop = '0';
  66.                         else                  e.style.marginLeft = '0';
  67.                     }
  68.                 });
  69.  
  70.                 cc.style.paddingLeft  = '0';
  71.                 cc.style.paddingRight = '6px';
  72.  
  73.                 // constrain define text
  74.                 document.querySelectorAll('[data-topic]')
  75.                     .forEach(e => e.style.maxWidth = maxW);
  76.  
  77.                 // Ensure footer stays at bottom - with null check
  78.                 var cnt = document.getElementById('cnt');
  79.                 if (cnt) cnt.style.minHeight = '100vh';
  80.             }
  81.  
  82.             // hide bunch of useful UI elements
  83.             ['sfcnt', 'top_nav', 'easter-egg', 'topstuff', 'searchform', 'appbar', 'before-appbar']
  84.             .forEach(function(id){
  85.                 var e = document.getElementById(id);
  86.                 if (e && e.style) e.style.display = 'none';
  87.             });
  88.             // remove that promo sidebar, wrap rest nicely
  89.             var promo = document.getElementById('promos');
  90.             if (promo) promo.remove();
  91.  
  92.             document.querySelectorAll('[data-ved]')
  93.             .forEach(e => e.style.maxWidth = '100%');
  94.  
  95.             document.querySelectorAll('cite')
  96.             .forEach(c => {
  97.                 var wrap = c.closest('div');
  98.                 if (wrap) wrap.style.position = 'static';
  99.             });
  100.         } catch(e) {
  101.             console.error("fix_google_markup() failed with error:");
  102.             console.error(e);
  103.         }
  104.     }
  105.  
  106.     // ========== DICTIONARY.COM HANDLER ==========
  107.     function fix_dictionary_com_markup() {
  108.         try {
  109.             // Only apply styles to https://www.dictionary.com/browse/{word}
  110.             if (!location.pathname.startsWith('/browse/')) {
  111.                 return; // Not a word definition page, exit early
  112.             }
  113.  
  114.             // Check if we're on an actual dictionary entry page
  115.             // (not the homepage or search results)
  116.             var has_definition = !!document.querySelector('.dictionary-entry, [class*="primary-definition"]');
  117.            
  118.             if (!has_definition) {
  119.                 if (++num_tries > 10) return;
  120.                 return setTimeout(fix_dictionary_com_markup, 100);
  121.             }
  122.  
  123.             // Only add styles once to prevent duplication
  124.             if (!document.getElementById(style_id)) {
  125.                 var style = document.createElement('style');
  126.                 style.id = style_id;
  127.                 style.textContent = `
  128.                     /* Declutter the webpage */
  129.                     aside, nav, [class*="sidebar"], [class*="nav"],
  130.                     header, hr, footer, video,
  131.                     .acw, .cmasAdRoot, .grecaptcha-badge, .grecaptcha-logo,
  132.                     .box-additional-after-first-entry.box-additional-anyclip.box-additional,
  133.                     .copyright-txt,
  134.                     [data-type="browse-module"],
  135.                     [data-type="common-quiz-module"],
  136.                     [data-type="dictionary-carambola-ad"],
  137.                     [data-type="dictionary-page-navigation-module"],
  138.                     [data-type="view-definitions-or-synonyms-for"],
  139.                     [data-type="words-nearby-module"],
  140.                     [data-type="xotd-module"]
  141.                     {
  142.                         display: none !important;
  143.                     }
  144.  
  145.                     /* Links' colour */
  146.                     a {
  147.                         color: #0059d1 !important;
  148.                     }
  149.  
  150.                     /* Webpage colour */
  151.                     [data-type="page"] {
  152.                         background-color: #343a40 !important;
  153.                         color: #f8f8f2 !important;
  154.                     }
  155.  
  156.                     /* 'Discover More' text colour */
  157.                     #example-sentences,
  158.                     #idioms-and-phrases,
  159.                     #other-words-from,
  160.                     #related-words,
  161.                     #synonym-study,
  162.                     #word-history-and-origins {
  163.                         color: #343a40 !important;
  164.                     }
  165.  
  166.                     /* Ensure the lookup word section remains visible */
  167.                     .dictionary-entry, [class*="primary-definition"], .part-of-speech {
  168.                         display: block !important;
  169.                         margin: 0 auto !important;
  170.                         width: 100% !important;
  171.                     }
  172.                 `;
  173.                 document.head.appendChild(style);
  174.             }
  175.  
  176.             console.log("Dictionary.com styling applied successfully");
  177.  
  178.         } catch(e) {
  179.             console.error("fix_dictionary_com_markup() failed with error:");
  180.             console.error(e);
  181.         }
  182.     }
  183.  
  184.     // ========== SITE DETECTION AND INITIALIZATION ==========
  185.     if (location.hostname === 'www.google.com') {
  186.         window.addEventListener('DOMContentLoaded', fix_google_markup);
  187.  
  188.         // Re-run on resize to handle Google's dynamic layout changes
  189.         window.addEventListener('resize', function() {
  190.             num_tries = 0;
  191.             fix_google_markup();
  192.         });
  193.     }
  194.     else if (location.hostname === 'www.dictionary.com') {
  195.         window.addEventListener('DOMContentLoaded', fix_dictionary_com_markup);
  196.  
  197.         // Re-run on resize for dictionary.com as well
  198.         window.addEventListener('resize', function() {
  199.             num_tries = 0;
  200.             fix_dictionary_com_markup();
  201.         });
  202.  
  203.         // Dictionary.com often loads content dynamically, so watch for changes
  204.         // This will re-apply styles if the page content changes
  205.         var observer = new MutationObserver(function(mutations) {
  206.             // Only reapply if we haven't already styled the page
  207.             if (!document.getElementById(style_id)) {
  208.                 num_tries = 0;
  209.                 fix_dictionary_com_markup();
  210.             }
  211.         });
  212.  
  213.         // Start observing once the DOM is ready
  214.         window.addEventListener('DOMContentLoaded', function() {
  215.             observer.observe(document.body, {
  216.                 childList: true,
  217.                 subtree: true
  218.             });
  219.         });
  220.     }
  221. })();
Advertisement
Add Comment
Please, Sign In to add comment