ggallozz

My home icon arrange

May 9th, 2026
29
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 20.96 KB | Source Code | 0 0
  1. <!DOCTYPE html>
  2. <html lang="it">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>GG Home — Reorder Tool</title>
  6. <script src="https://cdnjs.cloudflare.com/ajax/libs/Sortable/1.15.2/Sortable.min.js"></script>
  7. <style>
  8.   :root {
  9.     --bg: #07080f;
  10.     --card-bg: rgba(255,255,255,0.06);
  11.     --card-hover: rgba(255,255,255,0.13);
  12.     --label: #9ba8c0;
  13.     --accent: #3a6fff;
  14.   }
  15.   * { box-sizing: border-box; margin: 0; padding: 0; }
  16.   body {
  17.     background: var(--bg);
  18.     min-height: 100vh;
  19.     padding: 30px;
  20.     font-family: 'Segoe UI', system-ui, sans-serif;
  21.     color: #c8d4f0;
  22.   }
  23.   header {
  24.     display: flex;
  25.     align-items: center;
  26.     gap: 12px;
  27.     margin-bottom: 8px;
  28.   }
  29.   header h1 {
  30.     font-size: 20px;
  31.     font-weight: 300;
  32.     letter-spacing: 3px;
  33.     text-transform: uppercase;
  34.   }
  35.   .note {
  36.     font-size: 12px;
  37.     color: #5a6a8a;
  38.     margin-bottom: 24px;
  39.   }
  40.   #grid {
  41.     display: flex;
  42.     flex-wrap: wrap;
  43.     gap: 10px;
  44.     align-items: flex-start;
  45.     max-width: 1000px;
  46.   }
  47.   .item {
  48.     display: flex;
  49.     flex-direction: column;
  50.     align-items: center;
  51.     gap: 8px;
  52.     padding: 14px 10px;
  53.     border-radius: 12px;
  54.     background: var(--card-bg);
  55.     border: 1px solid rgba(255,255,255,0.05);
  56.     cursor: grab;
  57.     width: 95px;
  58.     user-select: none;
  59.     transition: background 0.15s, border-color 0.15s;
  60.   }
  61.   .item:hover {
  62.     background: var(--card-hover);
  63.     border-color: rgba(58,111,255,0.25);
  64.   }
  65.   .item:active { cursor: grabbing; }
  66.   .item.sortable-ghost { opacity: 0.25; }
  67.   .item.sortable-chosen {
  68.     border-color: var(--accent);
  69.     box-shadow: 0 4px 18px rgba(58,111,255,0.3);
  70.   }
  71.   .icon-wrap {
  72.     width: 50px; height: 50px;
  73.     border-radius: 10px;
  74.     background: rgba(255,255,255,0.08);
  75.     display: flex; align-items: center; justify-content: center;
  76.     overflow: hidden;
  77.     flex-shrink: 0;
  78.   }
  79.   .icon-wrap img { width: 42px; height: 42px; object-fit: contain; }
  80.   .icon-wrap.local { font-size: 22px; background: #1a2a1a; }
  81.   .label {
  82.     font-size: 11px;
  83.     color: var(--label);
  84.     text-align: center;
  85.     width: 100%;
  86.     white-space: nowrap;
  87.     overflow: hidden;
  88.     text-overflow: ellipsis;
  89.     font-weight: 600;
  90.   }
  91.   .sep {
  92.     width: 100%;
  93.     display: flex;
  94.     align-items: center;
  95.     gap: 10px;
  96.     padding: 4px 0;
  97.     cursor: grab;
  98.     color: #4a5a7a;
  99.     font-size: 10px;
  100.     letter-spacing: 2px;
  101.     text-transform: uppercase;
  102.     user-select: none;
  103.     transition: color 0.15s;
  104.   }
  105.   .sep:hover { color: #7a8ab0; }
  106.   .sep::before, .sep::after {
  107.     content: '';
  108.     flex: 1;
  109.     height: 1px;
  110.     background: rgba(255,255,255,0.06);
  111.   }
  112.   .sep.sortable-chosen { color: var(--accent); }
  113.  
  114.   .controls {
  115.     margin-top: 28px;
  116.     display: flex;
  117.     gap: 12px;
  118.     align-items: center;
  119.     flex-wrap: wrap;
  120.   }
  121.   button {
  122.     background: var(--accent);
  123.     color: white;
  124.     border: none;
  125.     padding: 10px 22px;
  126.     border-radius: 8px;
  127.     font-size: 13px;
  128.     cursor: pointer;
  129.     font-family: inherit;
  130.     font-weight: 500;
  131.     transition: opacity 0.15s;
  132.   }
  133.   button:hover { opacity: 0.82; }
  134.   button.sec {
  135.     background: rgba(255,255,255,0.07);
  136.     border: 1px solid rgba(255,255,255,0.1);
  137.   }
  138.   #copymsg { font-size: 12px; color: #3aff8a; }
  139.  
  140.   #output {
  141.     margin-top: 20px;
  142.     width: 100%;
  143.     max-width: 900px;
  144.     height: 280px;
  145.     background: rgba(255,255,255,0.03);
  146.     border: 1px solid rgba(255,255,255,0.08);
  147.     border-radius: 10px;
  148.     color: #8a9fcc;
  149.     font-family: 'Consolas', 'Courier New', monospace;
  150.     font-size: 11.5px;
  151.     padding: 14px;
  152.     resize: vertical;
  153.     display: none;
  154.     line-height: 1.5;
  155.   }
  156. </style>
  157. </head>
  158. <body>
  159.  
  160. <header>
  161.   <span style="font-size:24px">🐟</span>
  162.   <h1>GG Home — Riordina</h1>
  163. </header>
  164. <p class="note">Trascina le card e i separatori di sezione per riordinarli, poi genera l'HTML da incollare nel file.</p>
  165.  
  166. <div id="grid">
  167.  
  168.   <!-- ═══════════════ RIGA 1 — News & Social ═══════════════ -->
  169.   <a class="item" href="https://www.meteoam.it/it/meteo-citta/ravenna" >
  170.     <div class="icon-wrap">
  171.         <img class="iconsize" src="https://www.google.com/s2/favicons?domain=meteoam.it"
  172.             onerror="this.src='https://www.google.com/s2/favicons?domain=meteoam.it&sz=32'"
  173.             alt="">
  174.     </div>
  175.     <span class="label">Meteo RA</span>
  176.   </a>
  177.   <a class="item" href="https://www.ilfattoquotidiano.it/" >
  178.     <div class="icon-wrap">
  179.     <img class="iconsize" src="https://www.google.com/s2/favicons?domain=ilfattoquotidiano.it" alt="">
  180.     </div>
  181.     <span class="label">Il Fatto Q.</span>
  182.   </a>
  183.   <a class="item" href="https://www.facebook.com/" >
  184.     <div class="icon-wrap">
  185.     <img class="iconsize" src="https://www.google.com/s2/favicons?domain=facebook.com" alt="">
  186.     </div>
  187.     <span class="label">Facebook</span>
  188.   </a>
  189.   <a class="item" href="https://mastodon.social/@GGfrancison" >
  190.     <div class="icon-wrap">
  191.     <img class="iconsize" src="https://www.google.com/s2/favicons?domain=mastodon.social" alt="">
  192.     </div>
  193.     <span class="label">Mastodon</span>
  194.   </a>
  195.   <a class="item" href="https://web.telegram.org" >
  196.     <div class="icon-wrap">
  197.     <img class="iconsize" src="https://www.google.com/s2/favicons?domain=web.telegram.org" alt="">
  198.     </div>
  199.     <span class="label">Telegram</span>
  200.   </a>
  201.   <a class="item" href="https://web.whatsapp.com/" >
  202.     <div class="icon-wrap">
  203.     <img class="iconsize" src="https://e7.pngegg.com/pngimages/132/965/png-clipart-whatsapp-email-web-design-message-icon-whatsapp-whatsapp-logo-text-logo-thumbnail.png" alt="">
  204.     </div>
  205.     <span class="label">WazApp</span>
  206.   </a>
  207.   <a class="item" href="https://bsky.app" >
  208.     <div class="icon-wrap">
  209.     <img class="iconsize" src="https://www.google.com/s2/favicons?domain=bsky.app" alt="">
  210.     </div>
  211.     <span class="label">Bluesky</span>
  212.   </a>
  213.   <a class="item" href="https://account.ring.com/account/dashboard" >
  214.     <div class="icon-wrap">
  215.     <img class="iconsize" src="https://www.google.com/s2/favicons?domain=ring.com" alt="">
  216.     </div>
  217.     <span class="label">Ring</span>
  218.   </a>
  219.  
  220.   <!-- ═══════════════ RIGA 2 — Google & Shopping ═══════════════ -->
  221.   <a class="item" href="https://mail.google.com" >
  222.     <div class="icon-wrap">
  223.     <img class="iconsize" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAdVBMVEVHcEznQDPFIh/8vwP7vAT8vATFIh/FIR77vAP8vQPGIBnsRDbqNTf8wwDrQzXqQzXqQzXqQzWTVZHLFwX/vQCwszFBhfVedtZdq0kyqFM4iPo+hfStPV3xPSnTtx8eqFUzqFNChfSIXJ+dsTfpQzRChfQ0qFPrNgnEAAAAJ3RSTlMAJl0FXB6x//+vuPT///9x+sGw//+ot///sf///7P///////8IfXUnM3N5AAAAzElEQVR4Ac3NRRbCUBBE0Yr7F9wd9r9EUjHiI+xN+55q/EmGib4s2wGY63me2XP2fT9AmumxEK0Cn9n5AIsM1DLixGecCHMghESVFH1AaRRpUQeTaQ7S8jeGEiWYzQEslh6JYEpynhHM/NWaYLPdpULk7feiBLPD8ZSB83lzmZZAiRLMrsdTAVKxLIGowOp4KgHFZt8Ee54rwCBFLYlTB8AQZcpAHwB0ftfAAIDM54cBDM6PAdxuGAPsA+A+Bh6gWDC0WjPeh7IsWPiTnqu9I/fRLtEVAAAAAElFTkSuQmCC" alt="">
  224.     </div>
  225.     <span class="label">Gmail</span>
  226.   </a>
  227.   <a class="item" href="https://contacts.google.com" >
  228.     <div class="icon-wrap">
  229.     <img class="iconsize" src="https://www.gstatic.com/images/branding/product/2x/contacts_2022_48dp.png" alt="">
  230.     </div>
  231.     <span class="label">Contacts</span>
  232.   </a>
  233.   <a class="item" href="https://keep.google.com" >
  234.     <div class="icon-wrap">
  235.     <img class="iconsize" src="https://www.gstatic.com/images/branding/product/1x/keep_2020q4_48dp.png" alt="">
  236.     </div>
  237.     <span class="label">G Keep</span>
  238.   </a>
  239.   <a class="item" href="https://maps.google.com" >
  240.     <div class="icon-wrap">
  241.     <img class="iconsize" src="https://www.google.com/s2/favicons?domain=maps.google.com" alt="">
  242.     </div>
  243.     <span class="label">Maps</span>
  244.   </a>
  245.   <a class="item" href="https://photos.google.com" >
  246.     <div class="icon-wrap">
  247.     <img class="iconsize" src="https://www.google.com/s2/favicons?domain=photos.google.com" alt="">
  248.     </div>
  249.     <span class="label">G Foto</span>
  250.   </a>
  251.   <a class="item" href="https://www.amazon.it" >
  252.     <div class="icon-wrap">
  253.     <img class="iconsize" src="https://www.google.com/s2/favicons?domain=amazon.it" alt="">
  254.     </div>
  255.     <span class="label">Amazon</span>
  256.   </a>
  257.   <a class="item" href="https://www.zooplus.it" >
  258.     <div class="icon-wrap">
  259.     <img class="iconsize" src="https://www.google.com/s2/favicons?domain=zooplus.it" alt="">
  260.     </div>
  261.     <span class="label">Zooplus</span>
  262.   </a>
  263.   <a class="item" href="https://www.ebay.it" >
  264.     <div class="icon-wrap">
  265.     <img class="iconsize" src="https://www.google.com/s2/favicons?domain=ebay.it" alt="">
  266.     </div>
  267.     <span class="label">eBay</span>
  268.   </a>
  269.   <a class="item" href="https://www.temu.com" >
  270.     <div class="icon-wrap">
  271.     <img class="iconsize" src="https://www.google.com/s2/favicons?domain=temu.com" alt="">
  272.     </div>
  273.     <span class="label">Temu</span>
  274.   </a>
  275.   <a class="item" href="https://www.aliexpress.com" >
  276.     <div class="icon-wrap">
  277.     <img class="iconsize" src="https://www.google.com/s2/favicons?domain=aliexpress.com" alt="">
  278.     </div>
  279.     <span class="label">AliExpress</span>
  280.   </a>
  281.   <a class="item" href="https://my.conad.it/login" >
  282.     <div class="icon-wrap">
  283.     <img class="iconsize" src="https://www.google.com/s2/favicons?domain=conad.it" alt="">
  284.     </div>
  285.     <span class="label">My Conad</span>
  286.   </a>
  287.  
  288.   <!-- ═══════════════ RIGA 3 — Banche & Retraite ═══════════════ -->
  289.   <a class="item" href="https://clients.boursobank.com/connexion/" >
  290.     <div class="icon-wrap">
  291.     <img class="iconsize" src="https://www.google.com/s2/favicons?domain=boursobank.com" alt="">
  292.     </div>
  293.     <span class="label">Boursobank</span>
  294.   </a>
  295.   <a class="item" href="https://nowbanking.credit-agricole.it" >
  296.     <div class="icon-wrap">
  297.     <img class="iconsize" src="https://www.google.com/s2/favicons?domain=credit-agricole.it" alt="">
  298.     </div>
  299.     <span class="label">C.A. Bank</span>
  300.   </a>
  301.   <a class="item" href="https://www.lassuranceretraite.fr/portail-info/home.html" >
  302.     <div class="icon-wrap">
  303.     <img class="iconsize" src="https://www.google.com/s2/favicons?domain=lassuranceretraite.fr" alt="">
  304.     </div>
  305.     <span class="label">Ass.Retraite</span>
  306.   </a>
  307.   <a class="item" href="https://www.info-retraite.fr/portail-services/login" >
  308.     <div class="icon-wrap">
  309.     <img class="iconsize" src="https://www.google.com/s2/favicons?domain=info-retraite.fr" alt="">
  310.     </div>
  311.     <span class="label">Info Retraite</span>
  312.   </a>
  313.   <a class="item" href="https://www.inps.it/" >
  314.     <div class="icon-wrap">
  315.     <img class="iconsize" src="https://www.google.com/s2/favicons?domain=inps.it" alt="">
  316.     </div>
  317.     <span class="label">INPS</span>
  318.   </a>
  319.  
  320.   <!-- ═══════════════ RIGA 3 cont. — Servizi ═══════════════ -->
  321.   <a class="item" href="https://www.fascicolo-sanitario.it" >
  322.     <div class="icon-wrap">
  323.     <img class="iconsize" src="https://www.google.com/s2/favicons?domain=fascicolo-sanitario.it" alt="">
  324.     </div>
  325.     <span class="label">Fasc. Sanitario</span>
  326.   </a>
  327.   <a class="item" href="https://servizionline.gruppohera.it/auth/hera/login" >
  328.     <div class="icon-wrap">
  329.     <img class="iconsize" src="https://www.google.com/s2/favicons?domain=gruppohera.it" alt="">
  330.     </div>
  331.     <span class="label">HERA</span>
  332.   </a>
  333.   <a class="item" href="https://www.enel.it/it-it/login" >
  334.     <div class="icon-wrap">
  335.     <img class="iconsize" src="https://www.google.com/s2/favicons?domain=enel.it" alt="">
  336.     </div>
  337.     <span class="label">ENEL</span>
  338.   </a>
  339.   <a class="item" href="https://claude.ai/" >
  340.     <div class="icon-wrap">
  341.     <img class="iconsize" src="https://www.google.com/s2/favicons?domain=claude.ai" alt="">
  342.     </div>
  343.     <span class="label">Claude AI</span>
  344.   </a>
  345.   <a class="item" href="https://github.com" >
  346.     <div class="icon-wrap">
  347.     <img class="iconsize" src="https://www.google.com/s2/favicons?domain=github.com" alt="">
  348.     </div>
  349.     <span class="label">GitHub</span>
  350.   </a>
  351.  
  352.   <!-- ═══════════════ RIGA 4 — Locale ═══════════════ -->
  353.   <a class="item" href="http://127.0.0.1:9117/UI/Dashboard" >
  354.     <div class="icon-wrap icon-local">🧲</div>
  355.     <span class="label">Jackett</span>
  356.   </a>
  357.   <a class="item" href="http://localhost:8080" >
  358.     <div class="icon-wrap icon-local">⬇️</div>
  359.     <span class="label">qBittorrent</span>
  360.   </a>
  361.  
  362. </div>
  363.  
  364. <div class="controls">
  365.   <button onclick="generateHTML()">Genera HTML</button>
  366.   <button class="sec" onclick="copyHTML()">Copia negli appunti</button>
  367.   <span id="copymsg"></span>
  368. </div>
  369. <textarea id="output" readonly spellcheck="false"></textarea>
  370.  
  371. <script>
  372. const GMAIL_B64 = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAdVBMVEVHcEznQDPFIh/8vwP7vAT8vATFIh/FIR77vAP8vQPGIBnsRDbqNTf8wwDrQzXqQzXqQzXqQzWTVZHLFwX/vQCwszFBhfVedtZdq0kyqFM4iPo+hfStPV3xPSnTtx8eqFUzqFNChfSIXJ+dsTfpQzRChfQ0qFPrNgnEAAAAJ3RSTlMAJl0FXB6x//+vuPT///9x+sGw//+ot///sf///7P///////8IfXUnM3N5AAAAzElEQVR4Ac3NRRbCUBBE0Yr7F9wd9r9EUjHiI+xN+55q/EmGib4s2wGY63me2XP2fT9AmumxEK0Cn9n5AIsM1DLixGecCHMghESVFH1AaRRpUQeTaQ7S8jeGEiWYzQEslh6JYEpynhHM/NWaYLPdpULk7feiBLPD8ZSB83lzmZZAiRLMrsdTAVKxLIGowOp4KgHFZt8Ee54rwCBFLYlTB8AQZcpAHwB0ftfAAIDM54cBDM6PAdxuGAPsA+A+Bh6gWDC0WjPeh7IsWPiTnqu9I/fRLtEVAAAAAElFTkSuQmCC';
  373.  
  374. const data = [
  375.   { type:'sep', label:'RIGA 1 — News & Social' },
  376.  { type:'link', label:'Meteo RA',      href:'https://www.meteoam.it/it/meteo-citta/ravenna', icon:'https://www.google.com/s2/favicons?domain=meteoam.it', fallback:'https://www.google.com/s2/favicons?domain=meteoam.it&sz=32' },
  377.  { type:'link', label:'Il Fatto Q.',   href:'https://www.ilfattoquotidiano.it/',              icon:'https://www.google.com/s2/favicons?domain=ilfattoquotidiano.it' },
  378.  { type:'link', label:'Facebook',      href:'https://www.facebook.com/',                     icon:'https://www.google.com/s2/favicons?domain=facebook.com' },
  379.  { type:'link', label:'Gmail',         href:'https://mail.google.com',                       icon:GMAIL_B64, b64:true },
  380.  { type:'link', label:'Mastodon',      href:'https://mastodon.social/@GGfrancison',          icon:'https://www.google.com/s2/favicons?domain=mastodon.social' },
  381.  { type:'link', label:'Contacts',      href:'https://contacts.google.com',                   icon:'https://www.gstatic.com/images/branding/product/2x/contacts_2022_48dp.png' },
  382.  { type:'link', label:'Telegram',      href:'https://web.telegram.org',                      icon:'https://www.google.com/s2/favicons?domain=web.telegram.org' },
  383.  { type:'link', label:'WazApp',        href:'https://web.whatsapp.com/',                     icon:'https://e7.pngegg.com/pngimages/132/965/png-clipart-whatsapp-email-web-design-message-icon-whatsapp-whatsapp-logo-text-logo-thumbnail.png' },
  384.  { type:'link', label:'Bluesky',       href:'https://bsky.app',                              icon:'https://www.google.com/s2/favicons?domain=bsky.app' },
  385.  { type:'link', label:'Ring',          href:'https://account.ring.com/account/dashboard',    icon:'https://www.google.com/s2/favicons?domain=ring.com' },
  386.  
  387.  { type:'sep', label:'RIGA 2 — Google & Shopping' },
  388.  { type:'link', label:'G Keep',        href:'https://keep.google.com',       icon:'https://www.gstatic.com/images/branding/product/1x/keep_2020q4_48dp.png' },
  389.  { type:'link', label:'Maps',          href:'https://maps.google.com',       icon:'https://www.google.com/s2/favicons?domain=maps.google.com' },
  390.  { type:'link', label:'G Foto',        href:'https://photos.google.com',     icon:'https://www.google.com/s2/favicons?domain=photos.google.com' },
  391.  { type:'link', label:'Amazon',        href:'https://www.amazon.it',         icon:'https://www.google.com/s2/favicons?domain=amazon.it' },
  392.  { type:'link', label:'eBay',          href:'https://www.ebay.it',           icon:'https://www.google.com/s2/favicons?domain=ebay.it' },
  393.  { type:'link', label:'Temu',          href:'https://www.temu.com',          icon:'https://www.google.com/s2/favicons?domain=temu.com' },
  394.  { type:'link', label:'AliExpress',    href:'https://www.aliexpress.com',    icon:'https://www.google.com/s2/favicons?domain=aliexpress.com' },
  395.  { type:'link', label:'Zooplus',       href:'https://www.zooplus.it',        icon:'https://www.google.com/s2/favicons?domain=zooplus.it' },
  396.  { type:'link', label:'My Conad',      href:'https://my.conad.it/login',     icon:'https://www.google.com/s2/favicons?domain=conad.it' },
  397.  { type:'link', label:'GitHub',        href:'https://github.com',            icon:'https://www.google.com/s2/favicons?domain=github.com' },
  398.  
  399.  { type:'sep', label:'RIGA 3 — Banche & Retraite' },
  400.  { type:'link', label:'Boursobank',    href:'https://clients.boursobank.com/connexion/',                    icon:'https://www.google.com/s2/favicons?domain=boursobank.com' },
  401.  { type:'link', label:'C.A. Bank',    href:'https://nowbanking.credit-agricole.it',                        icon:'https://www.google.com/s2/favicons?domain=credit-agricole.it' },
  402.  { type:'link', label:'Ass.Retraite', href:'https://www.lassuranceretraite.fr/portail-info/home.html',     icon:'https://www.google.com/s2/favicons?domain=lassuranceretraite.fr' },
  403.  { type:'link', label:'Info Retraite',href:'https://www.info-retraite.fr/portail-services/login',          icon:'https://www.google.com/s2/favicons?domain=info-retraite.fr' },
  404.  { type:'link', label:'INPS',         href:'https://www.inps.it/',                                         icon:'https://www.google.com/s2/favicons?domain=inps.it' },
  405.  
  406.  { type:'sep', label:'RIGA 3 cont. — Servizi' },
  407.  { type:'link', label:'Fasc. Sanitario', href:'https://www.fascicolo-sanitario.it',                        icon:'https://www.google.com/s2/favicons?domain=fascicolo-sanitario.it' },
  408.  { type:'link', label:'HERA',         href:'https://servizionline.gruppohera.it/auth/hera/login',          icon:'https://www.google.com/s2/favicons?domain=gruppohera.it' },
  409.  { type:'link', label:'ENEL',         href:'https://www.enel.it/it-it/login',                              icon:'https://www.google.com/s2/favicons?domain=enel.it' },
  410.  { type:'link', label:'Claude AI',    href:'https://claude.ai/',                                           icon:'https://www.google.com/s2/favicons?domain=claude.ai' },
  411.  
  412.  { type:'sep', label:'RIGA 4 — Locale' },
  413.  { type:'link', label:'Jackett',      href:'http://127.0.0.1:9117/UI/Dashboard', emoji:'🧲', local:true },
  414.  { type:'link', label:'qBittorrent',  href:'http://localhost:8080',              emoji:'⬇️', local:true },
  415. ];
  416.  
  417. const grid = document.getElementById('grid');
  418.  
  419. function renderEl(d, idx) {
  420.   const el = document.createElement('div');
  421.   el.dataset.idx = idx;
  422.   if (d.type === 'sep') {
  423.     el.className = 'sep';
  424.     el.innerHTML = `<span>${d.label}</span>`;
  425.   } else {
  426.     el.className = 'item';
  427.     let iconH;
  428.     if (d.local)        iconH = `<div class="icon-wrap local">${d.emoji}</div>`;
  429.     else if (d.fallback) iconH = `<div class="icon-wrap"><img src="${d.icon}" onerror="this.src='${d.fallback}'" alt=""></div>`;
  430.     else                 iconH = `<div class="icon-wrap"><img src="${d.icon}" alt=""></div>`;
  431.     el.innerHTML = `${iconH}<span class="label">${d.label}</span>`;
  432.   }
  433.   return el;
  434. }
  435.  
  436. data.forEach((d, i) => grid.appendChild(renderEl(d, i)));
  437.  
  438. Sortable.create(grid, {
  439.   animation: 140,
  440.   ghostClass: 'sortable-ghost',
  441.   chosenClass: 'sortable-chosen',
  442.   dragClass: 'sortable-drag',
  443. });
  444.  
  445. function getOrder() {
  446.   return [...grid.querySelectorAll('[data-idx]')].map(el => data[+el.dataset.idx]);
  447. }
  448.  
  449. function itemHTML(d) {
  450.   if (d.type === 'sep') {
  451.     return `\n  <!-- ═══════════════ ${d.label} ═══════════════ -->\n`;
  452.   }
  453.   if (d.local) {
  454.     return (
  455.       `  <a class="item" href="${d.href}" >\n` +
  456.       `    <div class="icon-wrap icon-local">${d.emoji}</div>\n` +
  457.       `    <span class="label">${d.label}</span>\n` +
  458.       `  </a>\n`
  459.     );
  460.   }
  461.   if (d.fallback) {
  462.     return (
  463.       `  <a class="item" href="${d.href}" >\n` +
  464.       `    <div class="icon-wrap">\n` +
  465.       `    \t<img class="iconsize" src="${d.icon}"\n` +
  466.      `    \t\tonerror="this.src='${d.fallback}'"\n` +
  467.      `    \t\talt="">\n` +
  468.       `    </div>\n` +
  469.       `    <span class="label">${d.label}</span>\n` +
  470.       `  </a>\n`
  471.     );
  472.   }
  473.   return (
  474.     `  <a class="item" href="${d.href}" >\n` +
  475.     `    <div class="icon-wrap">\n` +
  476.     `\t<img class="iconsize" src="${d.icon}" alt="">\n` +
  477.     `\t</div>\n` +
  478.     `    <span class="label">${d.label}</span>\n` +
  479.     `  </a>\n`
  480.   );
  481. }
  482.  
  483. function generateHTML() {
  484.   const html = getOrder().map(itemHTML).join('');
  485.   const out = document.getElementById('output');
  486.   out.value = html;
  487.   out.style.display = 'block';
  488.   return html;
  489. }
  490.  
  491. function copyHTML() {
  492.   const html = generateHTML();
  493.   navigator.clipboard.writeText(html).then(() => {
  494.     const msg = document.getElementById('copymsg');
  495.     msg.textContent = '✓ Copiato!';
  496.     setTimeout(() => msg.textContent = '', 2500);
  497.   });
  498. }
  499. </script>
  500. </body>
  501. </html>
Add Comment
Please, Sign In to add comment