שיתוף | סקריפט לטמפרמונקי להפיכת קישורים לניתנים ללחיצה במערכת הסמסים של וירטואל פלוס
עזרה הדדית - מחשבים וטכנולוגיה
1
פוסטים
1
כותבים
35
צפיות
1
עוקבים
-
לא יודע איך לא חשבתי על זה עד היום..
תמיד הייתי מסמן את הקישור ולוחץ לחיצה ימנית, מעבר אל,
הבעיה מתחילה כשהקישורים ארוכים יותר משורה אחת..
שאז הוא כן תופס הכל או לא תופס הכל...
אז פניתי ל AI וביקשתי ממנו לכתוב סקריפט לטמפרמונקי שיהפוך את הקישורים מטקסט פשוט ל"קישורים"
תהנו:// ==UserScript== // @name הפיכת קישורים לניתנים ללחיצה במערכת הסמסים של וירטואל פלוס // @namespace http://tampermonkey.net/ // @version 4.0 // @description הופך URL/Email/טלפון/קודי OTP/Tracking ללחיצים ומוסיף כפתור העתקה בהובר בלבד, בלי כפילויות // @author שאול 208 // @match https://www.call2all.co.il/ym/index.php?view=Incoming_sms // @grant none // ==/UserScript== (function() { 'use strict'; // ===== CSS ===== const style = document.createElement('style'); style.textContent = ` .copy-wrap{display:inline-flex;align-items:center;gap:4px} .copy-btn{display:none;border:0;background:transparent;cursor:pointer;font-size:.8em} .copy-wrap:hover .copy-btn{display:inline} .code-strong{font-weight:700} a { color: blue; text-decoration: underline; } `; document.head.appendChild(style); // ===== Regexים ===== const urlRegex = /\b((https?:\/\/|www\.)[^\s<]+)/gi; const emailRegex = /\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b/gi; const phoneRegex = /\b972\d{8,9}\b/g; // טלפון ישראלי const otpRegex = /\b\d{4,8}\b/g; // קוד אימות 4–8 ספרות const trackingRegex = /\b(?=[A-Z0-9]{6,20}\b)(?=.*\d)(?=.*[A-Z])[A-Z0-9]+\b/gi; // ===== עזר ===== function createCopyButton(text) { const btn = document.createElement('button'); btn.className = 'copy-btn'; btn.type = 'button'; btn.title = 'העתקה'; btn.textContent = '📋'; btn.addEventListener('click', e => { e.preventDefault(); e.stopPropagation(); navigator.clipboard.writeText(text).then(() => { const old = btn.textContent; btn.textContent = '✅'; setTimeout(() => btn.textContent = old, 900); }); }); return btn; } function buildWrap(el, copyText) { const wrap = document.createElement('span'); wrap.className = 'copy-wrap'; wrap.appendChild(el); wrap.appendChild(createCopyButton(copyText)); return wrap; } function augmentAnchors(root) { root.querySelectorAll('a').forEach(a => { if (a.closest('.copy-wrap')) return; const copyText = (a.textContent || a.getAttribute('href') || '').trim(); const wrap = document.createElement('span'); wrap.className = 'copy-wrap'; a.replaceWith(wrap); wrap.appendChild(a); wrap.appendChild(createCopyButton(copyText)); }); } function hasOverlap(start, end, ranges) { return ranges.some(([s, e]) => !(end <= s || start >= e)); } function addRange(start, end, ranges) { ranges.push([start, end]); } function collectMatches(text) { const matches = []; const taken = []; function addByRegex(regex, type, build) { regex.lastIndex = 0; let m; while ((m = regex.exec(text)) !== null) { const start = m.index; const end = start + m[0].length; if (!hasOverlap(start, end, taken)) { matches.push(build(m, start, end, type)); addRange(start, end, taken); } } } addByRegex(urlRegex, 'url', (m, start, end) => { const raw = m[1]; const href = raw.startsWith('http') ? raw : 'http://' + raw; return { type: 'url', start, end, text: raw, href }; }); addByRegex(emailRegex, 'email', (m, start, end) => { const mail = m[0]; return { type: 'email', start, end, text: mail, href: 'mailto:' + mail }; }); addByRegex(phoneRegex, 'phone', (m, start, end) => { const phone = m[0]; const href = 'tel:' + phone; return { type: 'phone', start, end, text: phone, href }; }); addByRegex(otpRegex, 'otp', (m, start, end) => { return { type: 'otp', start, end, text: m[0] }; }); addByRegex(trackingRegex, 'tracking', (m, start, end) => { return { type: 'tracking', start, end, text: m[0] }; }); return matches.sort((a,b) => a.start - b.start); } function processTextNode(node) { if (node.parentNode.closest('a')) return; const text = node.textContent; const matches = collectMatches(text); if (!matches.length) return; const frag = document.createDocumentFragment(); let cursor = 0; for (const m of matches) { if (cursor < m.start) frag.appendChild(document.createTextNode(text.slice(cursor, m.start))); if (['url','email','phone'].includes(m.type)) { const a = document.createElement('a'); a.href = m.href; a.textContent = m.text; a.target = '_blank'; a.rel = 'noopener'; frag.appendChild(buildWrap(a, m.text)); } else if (['otp','tracking'].includes(m.type)) { const strong = document.createElement('strong'); strong.className = 'code-strong'; strong.textContent = m.text; frag.appendChild(buildWrap(strong, m.text)); } cursor = m.end; } if (cursor < text.length) frag.appendChild(document.createTextNode(text.slice(cursor))); node.parentNode.replaceChild(frag, node); } function processContainer(root = document) { augmentAnchors(root); const elements = root.querySelectorAll('.sms-message, .message, td, p, span, div'); elements.forEach(el => { if (el.classList.contains('processed')) return; Array.from(el.childNodes).forEach(n => { if (n.nodeType === Node.TEXT_NODE) processTextNode(n); }); el.classList.add('processed'); }); } window.addEventListener('load', () => { processContainer(document); }); const target = document.querySelector('#main-view') || document.body; const observer = new MutationObserver(mutations => { mutations.forEach(m => { m.addedNodes.forEach(node => { if (node.nodeType === Node.ELEMENT_NODE) processContainer(node); }); }); }); observer.observe(target, { childList:true, subtree:true }); })();
עדכנו אם יש בעיה וכו'