1/*  DokuWiki MoaiEditor Match_media.js file
2    Author  : MoaiTools <info@moaitools.org>
3    License : GPL 3 (http://www.gnu.org/licenses/gpl.html) */
4
5MoaiEditor.MatchMedia = class {
6
7    constructor(outer) {
8        this.tools = outer;
9    }
10
11    same (score, block, node) {
12
13        // Gather media tags in the text (if not cached)
14        if (!('media' in block))
15            this.gatherFromText(block);
16
17        // Gather media elements in the htlm element (if not cached)
18        if (!('media' in node))
19            this.gatherFromNode(node);
20
21
22        // Copy array because it will be trimmed
23        var textMedia = block.media.slice();
24
25        // Check matches
26        var n = 0;
27        var m = 0;
28        for (let pathname of node.media) {
29            var i = 0;
30            for (let words of textMedia)
31                if (this.tools.wordsInString(words, pathname).score == 1) {
32                    m += 1;
33                    textMedia.splice(i,1);
34                    break;
35                }
36            n += 1;
37        }
38
39        // Update the score
40        score.m += m;
41        score.n += n;
42    }
43
44    gatherFromText (block) {
45
46        // Get the text from the block
47        var text = block.text;
48        if ('cleantext' in block)
49            text = block.cleantext;
50
51        // Define patterns
52        const patterns = [
53        /*  /\[\{\{(?:[^\}]|(?:\}[^\}]))+\}\}\]/gu,       //  Imagebox plugin [{{ }}] */
54            /\{\{(?:[^\}]|(?:\}[^\}]))+\}\}/gu,           //  Bundled dokuwiki media tag {{wiki:dokuwiki-128.png?linkonly|Description}}
55        ];
56        // Gather media tags in the text
57        var media = [];
58        for (let pattern of patterns) {
59            const matches = text.match(pattern);
60            if (matches === null)
61                continue;
62            // Remove the matches from the text to avoid double matching
63            for (let match of matches)
64                text = text.replace(match,'');
65            // Parse the filename with namespace part
66            for (let match of matches) {
67                const filepath = match.match(/[^{]*?(?=[?|}])/);
68                if (filepath !== null) {
69                    var parts = filepath[0].trim().split(/[:/\\]/);
70                    parts = parts.filter(str => (str !== ''));
71                    if (parts.length > 0)
72                        media.push(parts);
73                }
74            }
75        }
76        // Store
77        block.media = media;
78        block.cleantext = text;
79    }
80
81    gatherFromNode (node) {
82
83        // Gather media files
84        var pathnames = [];
85        for (let mediaElement of node.handle.querySelectorAll(":scope > .media")) {       // The filename can be either in 'src' or 'href'
86            var pathname = null;
87            const tag = mediaElement.tagName;
88            if (tag == 'A')
89                pathname = mediaElement.querySelector(":scope > img")?.src;
90            if (tag == 'VIDEO')
91                pathname = mediaElement.querySelector(":scope source")?.src;
92            if (pathname !== undefined  &&  pathname !== null) {
93                pathnames.push(pathname);
94            }
95        }
96        node.media = pathnames;
97    }
98
99}; // End Class
100