xref: /plugin/fontello/script.js (revision 1776c5c5befa8de3cc97e981444f6918b129ab85)
1*1776c5c5Sdh-tools(function () {
2*1776c5c5Sdh-tools    'use strict';
3*1776c5c5Sdh-tools
4*1776c5c5Sdh-tools    var iconTokenPattern = /<icon:([A-Za-z0-9_-]+)(?:\|(toc|notoc))?>/g;
5*1776c5c5Sdh-tools
6*1776c5c5Sdh-tools    function getFontelloInfo() {
7*1776c5c5Sdh-tools        if (!window.JSINFO || !window.JSINFO.plugin_fontello) return null;
8*1776c5c5Sdh-tools        return window.JSINFO.plugin_fontello;
9*1776c5c5Sdh-tools    }
10*1776c5c5Sdh-tools
11*1776c5c5Sdh-tools    function tokenShowsInToc(flag, info) {
12*1776c5c5Sdh-tools        if (flag === 'notoc') return false;
13*1776c5c5Sdh-tools        if (flag === 'toc') return true;
14*1776c5c5Sdh-tools
15*1776c5c5Sdh-tools        return !!info.showInToc;
16*1776c5c5Sdh-tools    }
17*1776c5c5Sdh-tools
18*1776c5c5Sdh-tools    function createIconSpan(cssClass) {
19*1776c5c5Sdh-tools        var span = document.createElement('span');
20*1776c5c5Sdh-tools        span.className = 'fontello-icon ' + cssClass;
21*1776c5c5Sdh-tools        span.setAttribute('aria-hidden', 'true');
22*1776c5c5Sdh-tools        return span;
23*1776c5c5Sdh-tools    }
24*1776c5c5Sdh-tools
25*1776c5c5Sdh-tools    function replaceTextNodeTokens(textNode, info) {
26*1776c5c5Sdh-tools        var text = textNode.nodeValue;
27*1776c5c5Sdh-tools        var fragment = document.createDocumentFragment();
28*1776c5c5Sdh-tools        var lastIndex = 0;
29*1776c5c5Sdh-tools        var changed = false;
30*1776c5c5Sdh-tools        var match;
31*1776c5c5Sdh-tools
32*1776c5c5Sdh-tools        iconTokenPattern.lastIndex = 0;
33*1776c5c5Sdh-tools        while ((match = iconTokenPattern.exec(text)) !== null) {
34*1776c5c5Sdh-tools            var raw = match[0];
35*1776c5c5Sdh-tools            var name = match[1];
36*1776c5c5Sdh-tools            var flag = match[2] || '';
37*1776c5c5Sdh-tools            var cssClass = info.icons && info.icons[name];
38*1776c5c5Sdh-tools            var visible = tokenShowsInToc(flag, info);
39*1776c5c5Sdh-tools
40*1776c5c5Sdh-tools            if (match.index > lastIndex) {
41*1776c5c5Sdh-tools                fragment.appendChild(document.createTextNode(text.slice(lastIndex, match.index)));
42*1776c5c5Sdh-tools            }
43*1776c5c5Sdh-tools
44*1776c5c5Sdh-tools            if (cssClass && visible) {
45*1776c5c5Sdh-tools                fragment.appendChild(createIconSpan(cssClass));
46*1776c5c5Sdh-tools                changed = true;
47*1776c5c5Sdh-tools            } else if (cssClass) {
48*1776c5c5Sdh-tools                changed = true;
49*1776c5c5Sdh-tools            } else {
50*1776c5c5Sdh-tools                fragment.appendChild(document.createTextNode(raw));
51*1776c5c5Sdh-tools            }
52*1776c5c5Sdh-tools
53*1776c5c5Sdh-tools            lastIndex = match.index + raw.length;
54*1776c5c5Sdh-tools        }
55*1776c5c5Sdh-tools
56*1776c5c5Sdh-tools        if (!changed) return;
57*1776c5c5Sdh-tools        if (lastIndex < text.length) {
58*1776c5c5Sdh-tools            fragment.appendChild(document.createTextNode(text.slice(lastIndex)));
59*1776c5c5Sdh-tools        }
60*1776c5c5Sdh-tools
61*1776c5c5Sdh-tools        textNode.parentNode.replaceChild(fragment, textNode);
62*1776c5c5Sdh-tools    }
63*1776c5c5Sdh-tools
64*1776c5c5Sdh-tools    function replaceTocLinkTokens(link, info) {
65*1776c5c5Sdh-tools        var walker = document.createTreeWalker(link, NodeFilter.SHOW_TEXT, null, false);
66*1776c5c5Sdh-tools        var nodes = [];
67*1776c5c5Sdh-tools        var node;
68*1776c5c5Sdh-tools
69*1776c5c5Sdh-tools        while ((node = walker.nextNode()) !== null) {
70*1776c5c5Sdh-tools            if (node.nodeValue.indexOf('<icon:') !== -1) {
71*1776c5c5Sdh-tools                nodes.push(node);
72*1776c5c5Sdh-tools            }
73*1776c5c5Sdh-tools        }
74*1776c5c5Sdh-tools
75*1776c5c5Sdh-tools        nodes.forEach(function (textNode) {
76*1776c5c5Sdh-tools            replaceTextNodeTokens(textNode, info);
77*1776c5c5Sdh-tools        });
78*1776c5c5Sdh-tools    }
79*1776c5c5Sdh-tools
80*1776c5c5Sdh-tools    function renderTocIcons() {
81*1776c5c5Sdh-tools        var info = getFontelloInfo();
82*1776c5c5Sdh-tools        if (!info || !info.icons) return;
83*1776c5c5Sdh-tools
84*1776c5c5Sdh-tools        Array.prototype.forEach.call(document.querySelectorAll('#dw__toc a'), function (link) {
85*1776c5c5Sdh-tools            replaceTocLinkTokens(link, info);
86*1776c5c5Sdh-tools        });
87*1776c5c5Sdh-tools    }
88*1776c5c5Sdh-tools
89*1776c5c5Sdh-tools    function scheduleTocIconRendering() {
90*1776c5c5Sdh-tools        window.setTimeout(renderTocIcons, 0);
91*1776c5c5Sdh-tools    }
92*1776c5c5Sdh-tools
93*1776c5c5Sdh-tools    if (document.readyState === 'loading') {
94*1776c5c5Sdh-tools        document.addEventListener('DOMContentLoaded', scheduleTocIconRendering);
95*1776c5c5Sdh-tools    } else {
96*1776c5c5Sdh-tools        scheduleTocIconRendering();
97*1776c5c5Sdh-tools    }
98*1776c5c5Sdh-tools
99*1776c5c5Sdh-tools    window.addBtnActionFontello = function ($btn, props, edid) {
100*1776c5c5Sdh-tools        if (!props.list || !props.list.length) return '';
101*1776c5c5Sdh-tools
102*1776c5c5Sdh-tools        var pickerid = 'picker' + (pickercounter++);
103*1776c5c5Sdh-tools        var $picker = jQuery(document.createElement('div'))
104*1776c5c5Sdh-tools            .addClass('picker a11y pk_fontello')
105*1776c5c5Sdh-tools            .attr('id', pickerid)
106*1776c5c5Sdh-tools            .css('position', 'absolute')
107*1776c5c5Sdh-tools            .prop('hidden', true);
108*1776c5c5Sdh-tools
109*1776c5c5Sdh-tools        jQuery.each(props.list, function (_, icon) {
110*1776c5c5Sdh-tools            var name = icon.name || '';
111*1776c5c5Sdh-tools            var cssClass = icon['class'] || '';
112*1776c5c5Sdh-tools            var insert = icon.insert || '<icon:' + name + '>';
113*1776c5c5Sdh-tools            if (!name || !cssClass) return;
114*1776c5c5Sdh-tools
115*1776c5c5Sdh-tools            jQuery(document.createElement('button'))
116*1776c5c5Sdh-tools                .addClass('pickerbutton fontello-picker-button')
117*1776c5c5Sdh-tools                .attr('type', 'button')
118*1776c5c5Sdh-tools                .attr('title', name)
119*1776c5c5Sdh-tools                .attr('aria-label', name)
120*1776c5c5Sdh-tools                .attr('aria-controls', edid)
121*1776c5c5Sdh-tools                .on('click', function (event) {
122*1776c5c5Sdh-tools                    insertAtCarret(edid, insert);
123*1776c5c5Sdh-tools                    pickerClose();
124*1776c5c5Sdh-tools                    event.preventDefault();
125*1776c5c5Sdh-tools                })
126*1776c5c5Sdh-tools                .append(
127*1776c5c5Sdh-tools                    jQuery(document.createElement('span'))
128*1776c5c5Sdh-tools                        .addClass('fontello-icon ' + cssClass)
129*1776c5c5Sdh-tools                        .attr('aria-hidden', 'true')
130*1776c5c5Sdh-tools                )
131*1776c5c5Sdh-tools                .appendTo($picker);
132*1776c5c5Sdh-tools        });
133*1776c5c5Sdh-tools
134*1776c5c5Sdh-tools        jQuery('body').append($picker);
135*1776c5c5Sdh-tools
136*1776c5c5Sdh-tools        $btn.on('click', function (event) {
137*1776c5c5Sdh-tools            pickerToggle(pickerid, $btn);
138*1776c5c5Sdh-tools            event.preventDefault();
139*1776c5c5Sdh-tools        });
140*1776c5c5Sdh-tools
141*1776c5c5Sdh-tools        return pickerid;
142*1776c5c5Sdh-tools    };
143*1776c5c5Sdh-tools}());
144