NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name Skype-линкификатор // @version 1.2 // @description Linkifies Russian phone numbers to Skype links. // @include http://* // @include https://* // @run-at document-start // @grant none // ==/UserScript== document.addEventListener('DOMContentLoaded',function(){ // Регэксп для телефонов - первые два общие, последний для слитных номеров в РФ // надеюсь никто не смотрит странички про сложение 11 значных чисел и текстовые url с +№ в них? :) const numberRegex = /(\+?\d{1,3}[\s\-]*\(\s*\d{2,4}\s*\)([\s\-]*\d{2,4}){2,3})|(\+?\d{0,3}[\s\(]+\d{2,3}[\s\)]+((\d{2,3}\-\d{2}\-\d{2})|(\d{2,3}\-\d{4})))|((\+7|^8)[\s\-\(]{0,2}\d{3}[\)\s\-]{0,2}\d{2,3}\-?\d{2}-?\d{2})/g; function skypeURL(t) { // Замена кода межгорода 8 на префикс страны +7 или добавление + к коду страны var fixedNum; if (String(t).charAt(0) == '(') t = '+7' + t; fixedNum = (String(t).replace(/[\-\s\/\(\)\.]/g, '')); if (String(fixedNum).charAt(0) != '+') { fixedNum = String(fixedNum).replace( /^8/, '7' ); fixedNum = '+' + fixedNum; } return 'skype:' + fixedNum + '?call'; } // теги, в содержимом которых может быть номер телефона var allowedParents = [ 'address', 'b', 'bdo', 'big', 'article', 'section', 'aside', 'footer', 'blockquote', 'body', 'caption', 'cite', 'dd', 'del', 'div', 'dfn', 'dt', 'em', 'fieldset', 'font', 'form', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'i', 'iframe', 'ins', 'kdb', 'li', 'nobr', 'object', 'pre', 'p', 'q', 'samp', 'small', 'span', 'strike', 's', 'strong', 'sub', 'sup', 'td', 'th', 'tt', 'u', 'var' ]; // иконка Skype var skypeImage = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2hJREFUeNo8k92LG1UYxp/zMTOZJJM02bjpdrfb1uqytF1LsWJVbKmKpSBe1F71ooJe6IV44Y32QrSgiGL/gl6ISAWxFUWhVCsLtWCtu25bFttK3N2yGxOTbDaTj/nIzDnHkygOHBhmznne9/09zyH3lIIpgVK9e+SO67+xEsppi/L6hEUu2kz1AtBRCX5t+yZrbrPNlixIUGXANABKAFKWCjfLzbfmWuKDrRkHnFBsRBK32zFqgYAfK3QEBVNxuMvBhRe3macns+k/BPlP4Hqt9+Slamf2kbER5sdAsw+seQIKAgkK+FKi7FEsdiRWfYlR+M0PZzIn9o/bl7Q++I1G+6Wc4+jDBPVQoerF2OMIHC5ayBkMg2cg8mMlwEclhflOKv/yr62vLljqmftziZ9pU8lRg3Fs9CWqvsDOtMCxCRuxHu2zez7OLgVY6UR4btzGxzMmMkxgDcnkmd/d96SMwBORapQ9iQKnaPVjPFDQg4Hg85UuPlljoJTji3If705LeFp00iaYdAwsuOFTC5XeQb7b4Ze/3AhP5vMcjFK0hRq2fXxrEjkrxlIgcbfD8drNEE1NzuYcUkhUYgO/1XpHeZ8lulQjGwArJhjm2wITyRDTusrJ7da/DESE63WFNxcD/LKhO2R6adirntzBo1hyqq1zONEOSCy0gHN69ocyIfZkGZ4YYdiXpTi0OY1vNpl4bLaL5UDDpTodFIJvMeI//9Y2XV2PcNuNMZUCXtjCcaYkcW5V+6RC7MtI/HDQ0R1qgTzD8qoahkAIbtDxJLvL+tGdORdoaBuPjXG8syuFU1MUaa6DocdjnMGgbPje7IshZMDAvIe9NGWq3pGR+NNa2wPlBs6XQ3hRjFPTSZSeTeHW00lcPZRFxmT47i8P11yCdAKwrUE+kCWV9TpMSPvtG+7lWTX2eFHTHNWVjxYZdjsMKa7zERBcaca4WBvUpnp2go4imBG1RdL2KsMPLTcqvn/L//onkTuws5BGSoNliPUdGISaQO+HRQeHAUENlBoNvJr1ThO3VxlaxSVF6Ivs+WXv9Sst+UqX2uPUNPUfCZ1kjOUdFFImukGM6vo6DrD29yemCs//L6A0rziiiCKlV5BbavcPV335sJRUWlyxhbbY26PGfVkZ+vsz/NtHH8ydRdJw/xFgAH1MlPmzQ5cxAAAAAElFTkSuQmCC'; var xpath = '//text()[normalize-space() and (parent::' + allowedParents.join(' or parent::') + ')]'; var candidates = document.evaluate(xpath, document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); for (var cnd = null, i = 0; (cnd = candidates.snapshotItem(i)); i++) { if (numberRegex.test(cnd.nodeValue)) { var span = document.createElement('span'); var source = cnd.nodeValue; cnd.parentNode.replaceChild(span, cnd); numberRegex.lastIndex = 0; for (var match = null, lastLastIndex = 0; (match = numberRegex.exec(source)); ) { span.appendChild(document.createTextNode(source.substring(lastLastIndex, match.index))); var img = document.createElement('img'); img.setAttribute('alt','Skype'); img.setAttribute('title', 'Skype'); img.setAttribute('style', 'vertical-align:middle; margin-right: 4px;'); img.setAttribute('src', skypeImage); var a = document.createElement('a'); a.setAttribute('href', skypeURL(match[0])); a.setAttribute('style', 'vertical-align:middle;'); a.appendChild(document.createTextNode(match[0])); span.appendChild(img); span.appendChild(a); lastLastIndex = numberRegex.lastIndex; } span.appendChild(document.createTextNode(source.substring(lastLastIndex))); span.normalize(); } } }, false);