MediaWiki:Common.js: Difference between revisions
| IssuePress (talk | contribs) No edit summary | IssuePress (talk | contribs)  No edit summary | ||
| (6 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
| / | mw.loader.using(['mediawiki.util']).then(function () { | ||
|     // Load Vue.js from CDN | |||
|     var script = document.createElement('script'); | |||
|     script.src = 'https://cdn.jsdelivr.net/npm/vue@2/dist/vue.min.js'; // Use Vue 2 | |||
|     script.defer = true; | |||
|     script.onload = function () { | |||
|         // Ensure DOM is ready | |||
|         document.addEventListener("DOMContentLoaded", function () { | |||
|             if (typeof Vue === 'undefined') return; // Ensure Vue is loaded | |||
|             // Define the reusable Vue component | |||
|             Vue.component('tutorial-list', { | |||
|                 props: ['items'], | |||
|                 methods: { | |||
|                     splitContent: function (text) { | |||
|                         var firstSentenceEnd = text.indexOf(".") + 1; | |||
|                         if (firstSentenceEnd > 0) { | |||
|                             return { | |||
|                                 first: text.slice(0, firstSentenceEnd), | |||
|                                 rest: text.slice(firstSentenceEnd).trim() | |||
|                             }; | |||
|                         } | |||
|                         return { first: text, rest: "" }; | |||
|                     } | |||
|                 }, | |||
|                 template: '<ol>' + | |||
|                             '<li v-for="item in items">' + | |||
|                                 '<strong>{{ splitContent(item).first }}</strong> ' + | |||
|                                 '{{ splitContent(item).rest }}' + | |||
|                             '</li>' + | |||
|                           '</ol>' | |||
|             }); | |||
|             // Find all tutorial sections dynamically | |||
|             var tutorialHeaders = document.querySelectorAll("h2 > span#Steps"); | |||
|             tutorialHeaders.forEach(function (header) { | |||
|                 var orderedList = header.parentElement.nextElementSibling; | |||
|                 if (orderedList && orderedList.tagName === "OL") { | |||
|                     var listItems = Array.from(orderedList.querySelectorAll("li")).map(function (li) { | |||
|                         return li.textContent.trim(); | |||
|                     }); | |||
|                     var vueAppContainer = document.createElement('div'); | |||
|                     orderedList.parentElement.replaceChild(vueAppContainer, orderedList); | |||
|                     new Vue({ | |||
|                         el: vueAppContainer, | |||
|                         data: { | |||
|                             listItems: listItems | |||
|                         }, | |||
|                         template: '<tutorial-list :items="listItems"></tutorial-list>' | |||
|                      }); | |||
|                  } |                  } | ||
|              }); |              }); | ||
|          } |          }); | ||
|      } |      }; | ||
|     document.head.appendChild(script); | |||
| }); | }); | ||
Latest revision as of 02:15, 14 January 2025
mw.loader.using(['mediawiki.util']).then(function () {
    // Load Vue.js from CDN
    var script = document.createElement('script');
    script.src = 'https://cdn.jsdelivr.net/npm/vue@2/dist/vue.min.js'; // Use Vue 2
    script.defer = true;
    script.onload = function () {
        // Ensure DOM is ready
        document.addEventListener("DOMContentLoaded", function () {
            if (typeof Vue === 'undefined') return; // Ensure Vue is loaded
            // Define the reusable Vue component
            Vue.component('tutorial-list', {
                props: ['items'],
                methods: {
                    splitContent: function (text) {
                        var firstSentenceEnd = text.indexOf(".") + 1;
                        if (firstSentenceEnd > 0) {
                            return {
                                first: text.slice(0, firstSentenceEnd),
                                rest: text.slice(firstSentenceEnd).trim()
                            };
                        }
                        return { first: text, rest: "" };
                    }
                },
                template: '<ol>' +
                            '<li v-for="item in items">' +
                                '<strong>{{ splitContent(item).first }}</strong> ' +
                                '{{ splitContent(item).rest }}' +
                            '</li>' +
                          '</ol>'
            });
            // Find all tutorial sections dynamically
            var tutorialHeaders = document.querySelectorAll("h2 > span#Steps");
            tutorialHeaders.forEach(function (header) {
                var orderedList = header.parentElement.nextElementSibling;
                if (orderedList && orderedList.tagName === "OL") {
                    var listItems = Array.from(orderedList.querySelectorAll("li")).map(function (li) {
                        return li.textContent.trim();
                    });
                    var vueAppContainer = document.createElement('div');
                    orderedList.parentElement.replaceChild(vueAppContainer, orderedList);
                    new Vue({
                        el: vueAppContainer,
                        data: {
                            listItems: listItems
                        },
                        template: '<tutorial-list :items="listItems"></tutorial-list>'
                    });
                }
            });
        });
    };
    document.head.appendChild(script);
});