MediaWiki:Common.js: Difference between revisions

no edit summary
No edit summary
No edit summary
Line 780: Line 780:
     });
     });
});
});
( function () {
    function convertSingleQuotes(text) {
        // Opening single quote -> ‘ when at start or after whitespace/opening punctuation and before letter/digit
        text = text.replace(/(^|[\s\(\[\{\"'«—])'(?=[A-Za-z0-9])/g, '$1‘');
        // Closing single quote -> ’ when after letter/digit
        text = text.replace(/(?<=[A-Za-z0-9])'(?=$|[^\w\d])/g, '’');
        // fallback
        text = text.replace(/'/g, '’');
        return text;
    }
    function walkAndReplace(root) {
        var walker = document.createTreeWalker(root, NodeFilter.SHOW_TEXT, null, false);
        var node;
        var blacklist = new Set(['CODE','PRE','SCRIPT','STYLE','TEXTAREA','NOSCRIPT','MATH','SPAN']); // adjust span if needed
        while (node = walker.nextNode()) {
            var parent = node.parentNode;
            if (!parent) continue;
            if (blacklist.has(parent.nodeName)) continue;
            // skip if inside a link? (optional)
            var ancestor = parent;
            var skip = false;
            while (ancestor && ancestor !== root) {
                if (blacklist.has(ancestor.nodeName)) { skip = true; break; }
                ancestor = ancestor.parentNode;
            }
            if (skip) continue;
            var newText = convertSingleQuotes(node.nodeValue);
            if (newText !== node.nodeValue) node.nodeValue = newText;
        }
    }
    // Run after page load and on ajax content updates
    mw.hook('wikipage.content').add(function($content) {
        walkAndReplace($content[0]);
    });
    document.addEventListener('DOMContentLoaded', function() {
        walkAndReplace(document.body);
    });
}() );