Toggle menu
Toggle preferences menu
Toggle personal menu
Nejste přihlášen(a)
Your IP address will be publicly visible if you make any edits.

MediaWiki:Common.js: Porovnání verzí

MediaWiki interface page
Bez shrnutí editace
Bez shrnutí editace
Řádek 6: Řádek 6:
});
});


/// Mini-toolbar nad PRVNÍM <textarea> parametru `text` v dialogu šablony (VE)
// Mini-toolbar pro parametr `text` v dialogu šablony (VisualEditor)
(function () {
(function () {
   // --- helpers ---
   // ---- helpers ----
  function escRe(s){ return s.replace(/[.*+?^${}()|[\]\\]/g,'\\$&'); }
   function toggleWrap(input, before, after) {
   function toggleWrap(input, before, after) {
     const s = input.selectionStart, e = input.selectionEnd, v = input.value;
     const s = input.selectionStart, e = input.selectionEnd, v = input.value;
     const hasBefore = v.slice(s - before.length, s) === before;
     const hasB = v.slice(s - before.length, s) === before;
     const hasAfter  = v.slice(e, e + after.length) === after;
     const hasA = v.slice(e, e + after.length) === after;
     if (hasBefore && hasAfter) {
     if (hasB && hasA) {
       input.value = v.slice(0, s - before.length) + v.slice(s, e) + v.slice(e + after.length);
       input.value = v.slice(0, s - before.length) + v.slice(s, e) + v.slice(e + after.length);
       input.setSelectionRange(s - before.length, e - before.length);
       input.setSelectionRange(s - before.length, e - before.length);
Řádek 27: Řádek 28:
     const allHave = lines.filter(l => l.trim()).every(l => l.startsWith(prefix));
     const allHave = lines.filter(l => l.trim()).every(l => l.startsWith(prefix));
     const out = lines.map(l => !l.trim() ? l :
     const out = lines.map(l => !l.trim() ? l :
       (allHave ? l.replace(new RegExp('^' + prefix.replace(/[.*+?^${}()|[\]\\]/g,'\\$&')), '') : prefix + l)
       (allHave ? l.replace(new RegExp('^' + escRe(prefix)), '') : prefix + l)
     ).join('\n');
     ).join('\n');
     input.value = v.slice(0, s) + out + v.slice(e);
     input.value = v.slice(0, s) + out + v.slice(e);
Řádek 47: Řádek 48:
     const s = input.selectionStart, e = input.selectionEnd, v = input.value, sel = v.slice(s, e) || 'Cíl';
     const s = input.selectionStart, e = input.selectionEnd, v = input.value, sel = v.slice(s, e) || 'Cíl';
     input.value = v.slice(0, s) + '[[' + sel + '|' + sel + ']]' + v.slice(e);
     input.value = v.slice(0, s) + '[[' + sel + '|' + sel + ']]' + v.slice(e);
     input.focus(); input.setSelectionRange(s + 4 + sel.length + 1 + sel.length + 2, s + 4 + sel.length + 1 + sel.length + 2);
     const pos = s + 4 + sel.length + 1 + sel.length + 2;
    input.focus(); input.setSelectionRange(pos, pos);
   }
   }
   function makeBar(input){
   function makeBar(input){
Řádek 53: Řádek 55:
     const add = (label, title, fn) => $('<button type="button" class="pmt-btn" />')
     const add = (label, title, fn) => $('<button type="button" class="pmt-btn" />')
       .text(label).attr('title', title).on('click', () => fn(input)).appendTo($bar);
       .text(label).attr('title', title).on('click', () => fn(input)).appendTo($bar);
     add('B','Tučné (toggle)', el=>toggleWrap(el,"'''","'''"));
     add('B','Tučné (toggle)',     el=>toggleWrap(el,"'''","'''"));
     add('I','Kurzíva (toggle)', el=>toggleWrap(el,"''","''"));
     add('I','Kurzíva (toggle)',   el=>toggleWrap(el,"''","''"));
     add('H2','Nadpis H2', el=>headingOnLines(el,2));
     add('H2','Nadpis H2',         el=>headingOnLines(el,2));
     add('H3','Nadpis H3', el=>headingOnLines(el,3));
     add('H3','Nadpis H3',         el=>headingOnLines(el,3));
     add('H4','Nadpis H4', el=>headingOnLines(el,4));
     add('H4','Nadpis H4',         el=>headingOnLines(el,4));
     add('H5','Nadpis H5', el=>headingOnLines(el,5));
     add('H5','Nadpis H5',         el=>headingOnLines(el,5));
     add('•','Odrážky (toggle)', el=>toggleLinesPrefix(el,'* '));
     add('•','Odrážky (toggle)',   el=>toggleLinesPrefix(el,'* '));
     add('[]','Odkaz [[…]]', insertLink);
     add('[]','Odkaz [[…]]',       insertLink);
     return $bar;
     return $bar;
   }
   }


   // vlož lištu PŘÍMO nad první <textarea>
   // vlož lištu NAD první viditelné textarea param-stránky
   function addToolbarForPage(pageEl){
   function addToolbarForParamPage(pageEl){
     const $page = $(pageEl);
     const $page = $(pageEl);
     if ($page.data('privateToolbar')) return;
     if ($page.data('privateToolbar')) return;
    const $firstTA = $page.find('textarea.oo-ui-inputWidget-input').first(); // první textarea v poli
    if (!$firstTA.length) return;
    if ($firstTA.prev('.private-mini-toolbar').length) return; // už je


     $firstTA.addClass('pmt-textarea');
    // první VIDITELNÉ textarea (VE vyrábí i skryté kopie)
     $firstTA.before( makeBar($firstTA.get(0)) ); // vlož lištu hned nad něj
    const $ta = $page.find('textarea.oo-ui-inputWidget-input:not(.oo-ui-element-hidden):visible').first();
    if (!$ta.length) return;
 
    if ($ta.prev('.private-mini-toolbar').length) return;
     $ta.addClass('pmt-textarea');
     $ta.before( makeBar($ta.get(0)) );
     $page.data('privateToolbar', true);
     $page.data('privateToolbar', true);
   }
   }


  // najdi param stránky s názvem "text" NEBO "1" (pro jistotu)
   function scan(root){
   function scan(root){
     $(root).find('.ve-ui-mwTemplateDialog .ve-ui-mwParameterPage[data-param-name="text"]')
     $(root).find('.ve-ui-mwTemplateDialog .ve-ui-mwParameterPage')
       .each((_, el) => addToolbarForPage(el));
      .filter(function(){
        const n = this.getAttribute('data-param-name') || this.getAttribute('data-name') || '';
        return n === 'text' || n === '1';
      })
       .each((_, el) => addToolbarForParamPage(el));
   }
   }


   function init(){
   function init(){
    // znovu přidat i po rerenderu
     const mo = new MutationObserver(muts => muts.forEach(m => scan(m.target)));
     const mo = new MutationObserver(muts => muts.forEach(m => scan(m.target)));
     mo.observe(document.body, { childList:true, subtree:true });
     mo.observe(document.body, { childList:true, subtree:true });
     // když textarea chytí focus, zkontroluj znovu
 
     // když textarea chytí focus, ještě jednou se pojisti
     $(document).on('focus', '.ve-ui-mwTemplateDialog textarea.oo-ui-inputWidget-input', function(){
     $(document).on('focus', '.ve-ui-mwTemplateDialog textarea.oo-ui-inputWidget-input', function(){
       const page = $(this).closest('.ve-ui-mwParameterPage[data-param-name="text"]')[0];
       const page = $(this).closest('.ve-ui-mwParameterPage')[0];
       if (page) addToolbarForPage(page);
       if (page) addToolbarForParamPage(page);
     });
     });
     scan(document);
     scan(document);
   }
   }

Verze z 9. 10. 2025, 23:29

mw.hook('wikipage.content').add(function ($c) {
  var $ph = $c.find('.private-placeholder');
  if ($ph.length > 1) {
    $ph.slice(1).remove();
  }
});

// Mini-toolbar pro parametr `text` v dialogu šablony (VisualEditor)
(function () {
  // ---- helpers ----
  function escRe(s){ return s.replace(/[.*+?^${}()|[\]\\]/g,'\\$&'); }
  function toggleWrap(input, before, after) {
    const s = input.selectionStart, e = input.selectionEnd, v = input.value;
    const hasB = v.slice(s - before.length, s) === before;
    const hasA = v.slice(e, e + after.length) === after;
    if (hasB && hasA) {
      input.value = v.slice(0, s - before.length) + v.slice(s, e) + v.slice(e + after.length);
      input.setSelectionRange(s - before.length, e - before.length);
    } else {
      input.value = v.slice(0, s) + before + v.slice(s, e) + after + v.slice(e);
      input.setSelectionRange(e + before.length + after.length, e + before.length + after.length);
    }
    input.focus();
  }
  function toggleLinesPrefix(input, prefix) {
    const s = input.selectionStart, e = input.selectionEnd, v = input.value, sel = v.slice(s, e);
    const lines = sel.split('\n');
    const allHave = lines.filter(l => l.trim()).every(l => l.startsWith(prefix));
    const out = lines.map(l => !l.trim() ? l :
      (allHave ? l.replace(new RegExp('^' + escRe(prefix)), '') : prefix + l)
    ).join('\n');
    input.value = v.slice(0, s) + out + v.slice(e);
    input.focus(); input.setSelectionRange(s + out.length, s + out.length);
  }
  function headingOnLines(input, level) {
    const open = '='.repeat(level) + ' ', close = ' ' + '='.repeat(level);
    const s = input.selectionStart, e = input.selectionEnd, v = input.value, sel = v.slice(s, e);
    const lines = sel.split('\n');
    const isAllSame = lines.filter(l => l.trim()).every(l => {
      const m = l.match(/^\s*(=+)\s*(.*?)\s*(=+)\s*$/); return m && m[1].length === level && m[3].length === level;
    });
    const strip = l => { const m = l.match(/^\s*(=+)\s*(.*?)\s*(=+)\s*$/); return m ? m[2] : l.trim(); };
    const out = lines.map(l => !l.trim() ? l : (isAllSame ? strip(l) : open + strip(l) + close)).join('\n');
    input.value = v.slice(0, s) + out + v.slice(e);
    input.focus(); input.setSelectionRange(s + out.length, s + out.length);
  }
  function insertLink(input){
    const s = input.selectionStart, e = input.selectionEnd, v = input.value, sel = v.slice(s, e) || 'Cíl';
    input.value = v.slice(0, s) + '[[' + sel + '|' + sel + ']]' + v.slice(e);
    const pos = s + 4 + sel.length + 1 + sel.length + 2;
    input.focus(); input.setSelectionRange(pos, pos);
  }
  function makeBar(input){
    const $bar = $('<div class="private-mini-toolbar" />');
    const add = (label, title, fn) => $('<button type="button" class="pmt-btn" />')
      .text(label).attr('title', title).on('click', () => fn(input)).appendTo($bar);
    add('B','Tučné (toggle)',     el=>toggleWrap(el,"'''","'''"));
    add('I','Kurzíva (toggle)',   el=>toggleWrap(el,"''","''"));
    add('H2','Nadpis H2',         el=>headingOnLines(el,2));
    add('H3','Nadpis H3',         el=>headingOnLines(el,3));
    add('H4','Nadpis H4',         el=>headingOnLines(el,4));
    add('H5','Nadpis H5',         el=>headingOnLines(el,5));
    add('•','Odrážky (toggle)',   el=>toggleLinesPrefix(el,'* '));
    add('[]','Odkaz [[…]]',       insertLink);
    return $bar;
  }

  // vlož lištu NAD první viditelné textarea param-stránky
  function addToolbarForParamPage(pageEl){
    const $page = $(pageEl);
    if ($page.data('privateToolbar')) return;

    // první VIDITELNÉ textarea (VE vyrábí i skryté kopie)
    const $ta = $page.find('textarea.oo-ui-inputWidget-input:not(.oo-ui-element-hidden):visible').first();
    if (!$ta.length) return;

    if ($ta.prev('.private-mini-toolbar').length) return;
    $ta.addClass('pmt-textarea');
    $ta.before( makeBar($ta.get(0)) );
    $page.data('privateToolbar', true);
  }

  // najdi param stránky s názvem "text" NEBO "1" (pro jistotu)
  function scan(root){
    $(root).find('.ve-ui-mwTemplateDialog .ve-ui-mwParameterPage')
      .filter(function(){
        const n = this.getAttribute('data-param-name') || this.getAttribute('data-name') || '';
        return n === 'text' || n === '1';
      })
      .each((_, el) => addToolbarForParamPage(el));
  }

  function init(){
    const mo = new MutationObserver(muts => muts.forEach(m => scan(m.target)));
    mo.observe(document.body, { childList:true, subtree:true });

    // když textarea chytí focus, ještě jednou se pojisti
    $(document).on('focus', '.ve-ui-mwTemplateDialog textarea.oo-ui-inputWidget-input', function(){
      const page = $(this).closest('.ve-ui-mwParameterPage')[0];
      if (page) addToolbarForParamPage(page);
    });

    scan(document);
  }

  if (mw.loader.getState('ext.visualEditor.desktopArticleTarget.init')) init();
  else mw.loader.using('ext.visualEditor.desktopArticleTarget.init').then(init);
})();