Jump to content

MediaWiki:Common.js: Difference between revisions

From Vampiro
Adicionada barra de ferramentas rápida gótica e integração WikiEditor
Integração completa com VisualEditor OOUI, WikiEditor e Barra Rápida Gótica
Line 1: Line 1:
/* ==========================================================================
/* ==========================================================================
   VAMPIRO: A MÁSCARA — SCRIPTS GLOBAIS, INTERATIVIDADE & BOTÕES DO EDITOR
   VAMPIRO: A MÁSCARA — SCRIPTS GLOBAIS, SEGREDO DINÂMICO & VISUALEDITOR TOOL
   ========================================================================== */
   ========================================================================== */


Line 68: Line 68:


   // ------------------------------------------------------------------------
   // ------------------------------------------------------------------------
   // 2. FERRAMENTAS DO EDITOR (BARRA RÁPIDA GÓTICA + WIKIEDITOR + VISUALEDITOR)
   // 2. INTEGRAÇÃO COM VISUALEDITOR (EDITOR VISUAL OOUI)
   // ------------------------------------------------------------------------
   // ------------------------------------------------------------------------
  function setupVisualEditorTool() {
    if (!window.mw || !mw.hook) return;


   // A) Barra Rápida Gótica (Injetada diretamente acima da área de texto)
    mw.hook('ve.loadModules').add(function (addPlugin) {
      addPlugin(function () {
        if (!window.ve || !ve.ui || !ve.ui.toolFactory) return;
 
        // Cria o comando no VisualEditor
        ve.ui.commandRegistry.register(
          new ve.ui.Command(
            'insertVtmSecret', 'content', 'insert',
            {
              args: [
                [
                  {
                    type: 'mwTransclusionInline',
                    attributes: {
                      mw: {
                        parts: [
                          {
                            template: {
                              target: { href: 'Template:Segredo', wt: 'Segredo' },
                              params: {
                                '1': { wt: 'Texto confidencial a ser censurado' },
                                'data': { wt: 'AAAA-MM-DD' },
                                'liberado': { wt: 'nao' }
                              }
                            }
                          }
                        ]
                      }
                    }
                  },
                  { type: '/mwTransclusionInline' }
                ]
              ],
              supportedSelections: ['linear']
            }
          )
        );
 
        // Define a ferramenta no menu Inserir do VisualEditor
        function VtmSecretVeTool() {
          VtmSecretVeTool.super.apply(this, arguments);
        }
        OO.inheritClass(VtmSecretVeTool, ve.ui.Tool);
        VtmSecretVeTool.static.name = 'vtmSecret';
        VtmSecretVeTool.static.group = 'insert';
        VtmSecretVeTool.static.icon = 'lock';
        VtmSecretVeTool.static.title = '🔒 Censura / Segredo (Confidencial)';
        VtmSecretVeTool.static.commandName = 'insertVtmSecret';
 
        ve.ui.toolFactory.register(VtmSecretVeTool);
      });
    });
  }
 
  // ------------------------------------------------------------------------
   // 3. BARRA RÁPIDA GÓTICA NO EDITOR DE CÓDIGO-FONTE (#wpTextbox1)
  // ------------------------------------------------------------------------
   function initVtmQuickToolbar() {
   function initVtmQuickToolbar() {
     var textbox = document.getElementById('wpTextbox1');
     var textbox = document.getElementById('wpTextbox1');
     if (!textbox) return;
     if (!textbox) return;
     if (document.getElementById('vtm-editor-quickbar')) return;
     if (document.getElementById('vtm-editor-quickbar')) return;


Line 81: Line 138:
     bar.id = 'vtm-editor-quickbar';
     bar.id = 'vtm-editor-quickbar';
     bar.className = 'vtm-editor-quickbar';
     bar.className = 'vtm-editor-quickbar';
     bar.style.cssText = 'display:flex; gap:8px; align-items:center; padding:8px 12px; margin-bottom:8px; background:linear-gradient(90deg, #181014 0%, #0d0d12 100%); border:1px solid #3d0a12; border-left:4px solid #8b0000; border-radius:4px; font-family:"Cinzel", Georgia, serif; box-shadow:0 4px 14px rgba(0,0,0,0.6);';
     bar.style.cssText = 'display:flex; flex-wrap:wrap; gap:8px; align-items:center; padding:10px 14px; margin:10px 0; background:linear-gradient(90deg, #181014 0%, #0d0d12 100%); border:1px solid #3d0a12; border-left:4px solid #8b0000; border-radius:4px; font-family:"Cinzel", Georgia, serif; box-shadow:0 4px 14px rgba(0,0,0,0.6); z-index:99;';


     // Rótulo da Barra
     // Rótulo da Barra
     var label = document.createElement('span');
     var label = document.createElement('span');
     label.style.cssText = 'color:#c5a059; font-size:0.82em; font-weight:700; text-transform:uppercase; letter-spacing:1px; margin-right:4px;';
     label.style.cssText = 'color:#c5a059; font-size:0.85em; font-weight:700; text-transform:uppercase; letter-spacing:1px; margin-right:6px;';
     label.innerHTML = '🩸 Ferramentas Góticas:';
     label.innerHTML = '🩸 Ferramentas Góticas:';
     bar.appendChild(label);
     bar.appendChild(label);


     // Botão 1: Inserir Tarja de Censura / Segredo Inline
     // Botão 1: Inline
     var btnInline = document.createElement('button');
     var btnInline = document.createElement('button');
     btnInline.type = 'button';
     btnInline.type = 'button';
     btnInline.className = 'vtm-quick-btn';
     btnInline.className = 'vtm-quick-btn';
     btnInline.style.cssText = 'background:#240c12; color:#ffffff; border:1px solid #ff2a3f; border-radius:3px; padding:4px 10px; font-size:0.8em; font-weight:700; cursor:pointer; display:flex; align-items:center; gap:6px; transition:all 0.2s ease; box-shadow:0 0 8px rgba(201,24,43,0.4);';
     btnInline.style.cssText = 'background:#240c12; color:#ffffff; border:1px solid #ff2a3f; border-radius:3px; padding:6px 12px; font-size:0.82em; font-weight:700; cursor:pointer; display:inline-flex; align-items:center; gap:6px; transition:all 0.2s ease; box-shadow:0 0 8px rgba(201,24,43,0.4);';
     btnInline.innerHTML = '🔒 Inserir Tarja de Censura (Segredo)';
     btnInline.innerHTML = '🔒 Inserir Tarja de Censura (Segredo)';
     btnInline.title = 'Envolve o texto selecionado na predefinição {{Segredo}} com bloqueio anti-spoiler';
     btnInline.title = 'Envolve o texto selecionado na predefinição {{Segredo}}';


     btnInline.addEventListener('mouseover', function () {
     btnInline.onmouseover = function () {
       btnInline.style.background = '#4a0f1b';
       btnInline.style.background = '#4a0f1b';
       btnInline.style.boxShadow = '0 0 14px rgba(255,42,63,0.8)';
       btnInline.style.boxShadow = '0 0 14px rgba(255,42,63,0.85)';
     });
     };
     btnInline.addEventListener('mouseout', function () {
     btnInline.onmouseout = function () {
       btnInline.style.background = '#240c12';
       btnInline.style.background = '#240c12';
       btnInline.style.boxShadow = '0 0 8px rgba(201,24,43,0.4)';
       btnInline.style.boxShadow = '0 0 8px rgba(201,24,43,0.4)';
     });
     };
 
     btnInline.onclick = function (e) {
     btnInline.addEventListener('click', function (e) {
       e.preventDefault();
       e.preventDefault();
       insertSecretTemplate(textbox, false);
       insertSecretTemplate(textbox, false);
     });
     };
     bar.appendChild(btnInline);
     bar.appendChild(btnInline);


     // Botão 2: Inserir Bloco Dossiê Confidencial
     // Botão 2: Bloco
     var btnBlock = document.createElement('button');
     var btnBlock = document.createElement('button');
     btnBlock.type = 'button';
     btnBlock.type = 'button';
     btnBlock.className = 'vtm-quick-btn';
     btnBlock.className = 'vtm-quick-btn';
     btnBlock.style.cssText = 'background:#181822; color:#c5a059; border:1px solid #3d0a12; border-radius:3px; padding:4px 10px; font-size:0.8em; font-weight:700; cursor:pointer; display:flex; align-items:center; gap:6px; transition:all 0.2s ease;';
     btnBlock.style.cssText = 'background:#181822; color:#c5a059; border:1px solid #3d0a12; border-radius:3px; padding:6px 12px; font-size:0.82em; font-weight:700; cursor:pointer; display:inline-flex; align-items:center; gap:6px; transition:all 0.2s ease;';
     btnBlock.innerHTML = '📁 Dossiê Confidencial (Bloco)';
     btnBlock.innerHTML = '📁 Dossiê Confidencial (Bloco)';
     btnBlock.title = 'Insere uma caixa completa de relatório confidencial em bloco';
     btnBlock.title = 'Insere relatório confidencial em formato de bloco';


     btnBlock.addEventListener('mouseover', function () {
     btnBlock.onmouseover = function () {
       btnBlock.style.background = '#281c20';
       btnBlock.style.background = '#281c20';
       btnBlock.style.borderColor = '#c5a059';
       btnBlock.style.borderColor = '#c5a059';
     });
     };
     btnBlock.addEventListener('mouseout', function () {
     btnBlock.onmouseout = function () {
       btnBlock.style.background = '#181822';
       btnBlock.style.background = '#181822';
       btnBlock.style.borderColor = '#3d0a12';
       btnBlock.style.borderColor = '#3d0a12';
     });
     };
 
     btnBlock.onclick = function (e) {
     btnBlock.addEventListener('click', function (e) {
       e.preventDefault();
       e.preventDefault();
       insertSecretTemplate(textbox, true);
       insertSecretTemplate(textbox, true);
     });
     };
     bar.appendChild(btnBlock);
     bar.appendChild(btnBlock);


     // Insere antes do textarea ou da toolbar existente
     textbox.parentNode.insertBefore(bar, textbox);
    var parent = textbox.parentNode;
    parent.insertBefore(bar, textbox);
   }
   }


  // Função auxiliar de inserção no textarea
   function insertSecretTemplate(textbox, isBlock) {
   function insertSecretTemplate(textbox, isBlock) {
     var start = textbox.selectionStart;
     var start = textbox.selectionStart;
Line 154: Line 206:
     textbox.value = text.substring(0, start) + replacement + text.substring(end);
     textbox.value = text.substring(0, start) + replacement + text.substring(end);


    // Posiciona o cursor de volta
     var newCursor = start + pre.length;
     var newCursor = start + pre.length;
     textbox.focus();
     textbox.focus();
     textbox.setSelectionRange(newCursor, newCursor + defaultText.length);
     textbox.setSelectionRange(newCursor, newCursor + defaultText.length);


    // Dispara evento de input para o MediaWiki registrar a mudança
     if (window.$) {
     if (window.$) {
       $(textbox).trigger('input').trigger('change');
       $(textbox).trigger('input').trigger('change');
     }
     }
  }
  // B) Integração nativa no WikiEditor (Barra oficial do MediaWiki)
  function setupWikiEditorIntegration() {
    if (!window.mw || !window.$) return;
    mw.loader.using('ext.wikiEditor', function () {
      var $textbox = $('#wpTextbox1');
      if (!$textbox.length) return;
      var toolConfig = {
        section: 'main',
        group: 'format',
        tools: {
          vtmSecret: {
            label: 'Inserir Tarja de Censura / Segredo',
            type: 'button',
            icon: 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="22" height="22" viewBox="0 0 24 24"><rect x="2" y="5" width="20" height="14" rx="2" fill="%23101015" stroke="%23ff2a3f" stroke-width="1.5"/><rect x="5" y="9" width="14" height="6" fill="%23ff2a3f"/><path d="M12 2v3M8 2h8" stroke="%23ff2a3f" stroke-width="1.5" stroke-linecap="round"/></svg>',
            action: {
              type: 'encapsulate',
              options: {
                pre: '{{Segredo|',
                peri: 'Texto confidencial',
                post: '|data=AAAA-MM-DD|liberado=nao}}'
              }
            }
          }
        }
      };
      $textbox.wikiEditor('addToToolbar', toolConfig);
    });
   }
   }


   // ------------------------------------------------------------------------
   // ------------------------------------------------------------------------
   // 3. ANIMAÇÃO DE CASCATA DAS SEÇÕES (.vtm-section-block)
   // 4. ANIMAÇÃO DE CASCATA DAS SEÇÕES (.vtm-section-block)
   // ------------------------------------------------------------------------
   // ------------------------------------------------------------------------
   function initSectionAnimation() {
   function initSectionAnimation() {
Line 256: Line 274:
   }
   }


   // ------------------------------------------------------------------------
   // Execução
  // INICIALIZAÇÃO GLOBAL
  // ------------------------------------------------------------------------
   function initAll() {
   function initAll() {
     initVtmSecrets();
     initVtmSecrets();
     initSectionAnimation();
     initSectionAnimation();
     initVtmQuickToolbar();
     initVtmQuickToolbar();
     setupWikiEditorIntegration();
     setupVisualEditorTool();
   }
   }


Line 277: Line 293:
       initSectionAnimation();
       initSectionAnimation();
     });
     });
     window.mw.hook('wikiEditor.toolbarReady').add(function () {
     window.mw.hook('ve.activationComplete').add(function () {
       setupWikiEditorIntegration();
       setupVisualEditorTool();
     });
     });
   }
   }
})();
})();

Revision as of 19:28, 1 September 2026

/* ==========================================================================
   VAMPIRO: A MÁSCARA — SCRIPTS GLOBAIS, SEGREDO DINÂMICO & VISUALEDITOR TOOL
   ========================================================================== */

(function () {
  'use strict';

  // ------------------------------------------------------------------------
  // 1. LÓGICA DE CENSURA & REVELAÇÃO DINÂMICA ({{Segredo}})
  // ------------------------------------------------------------------------
  function initVtmSecrets() {
    var secretElements = document.querySelectorAll('[data-vtm-secret="true"]');
    if (!secretElements || secretElements.length === 0) return;

    var now = new Date();

    secretElements.forEach(function (el) {
      var liberado = (el.getAttribute('data-liberado') || '').toLowerCase().trim();
      var dateStr = (el.getAttribute('data-reveal-date') || '').trim();
      var dica = (el.getAttribute('data-dica') || '').trim();
      var isRevealed = false;
      var tooltipText = '🔒 [ARQUIVO CONFIDENCIAL - ACESSO RESTRITO]';

      if (liberado === 'sim' || liberado === 'true' || liberado === '1') {
        isRevealed = true;
      } else if (liberado === 'nao' || liberado === 'false' || liberado === '0') {
        isRevealed = false;
        tooltipText = '🔒 [ARQUIVO CLASSIFICADO' + (dica ? ' // ' + dica : '') + ' - LIBERAÇÃO RESTRITA]';
      } else if (dateStr) {
        var targetDate = null;
        if (dateStr.indexOf('/') !== -1) {
          var parts = dateStr.split('/');
          if (parts.length === 3) {
            targetDate = new Date(parts[2], parseInt(parts[1], 10) - 1, parts[0], 0, 0, 0);
          }
        } else {
          targetDate = new Date(dateStr);
        }

        if (targetDate && !isNaN(targetDate.getTime())) {
          if (now >= targetDate) {
            isRevealed = true;
          } else {
            isRevealed = false;
            var formatted = ('0' + targetDate.getDate()).slice(-2) + '/' +
                            ('0' + (targetDate.getMonth() + 1)).slice(-2) + '/' +
                            targetDate.getFullYear();
            tooltipText = '🔒 [CLASSIFICADO' + (dica ? ' // ' + dica : '') + ' - Desclassificação em: ' + formatted + ']';
          }
        } else {
          isRevealed = false;
        }
      } else {
        isRevealed = false;
      }

      if (isRevealed) {
        el.classList.add('is-revealed');
        el.classList.remove('is-redacted');
        el.title = '🔓 [DOCUMENTO DESCLASSIFICADO' + (dica ? ' // ' + dica : '') + ']';
      } else {
        el.classList.add('is-redacted');
        el.classList.remove('is-revealed');
        el.title = tooltipText;
      }
    });
  }

  // ------------------------------------------------------------------------
  // 2. INTEGRAÇÃO COM VISUALEDITOR (EDITOR VISUAL OOUI)
  // ------------------------------------------------------------------------
  function setupVisualEditorTool() {
    if (!window.mw || !mw.hook) return;

    mw.hook('ve.loadModules').add(function (addPlugin) {
      addPlugin(function () {
        if (!window.ve || !ve.ui || !ve.ui.toolFactory) return;

        // Cria o comando no VisualEditor
        ve.ui.commandRegistry.register(
          new ve.ui.Command(
            'insertVtmSecret', 'content', 'insert',
            {
              args: [
                [
                  {
                    type: 'mwTransclusionInline',
                    attributes: {
                      mw: {
                        parts: [
                          {
                            template: {
                              target: { href: 'Template:Segredo', wt: 'Segredo' },
                              params: {
                                '1': { wt: 'Texto confidencial a ser censurado' },
                                'data': { wt: 'AAAA-MM-DD' },
                                'liberado': { wt: 'nao' }
                              }
                            }
                          }
                        ]
                      }
                    }
                  },
                  { type: '/mwTransclusionInline' }
                ]
              ],
              supportedSelections: ['linear']
            }
          )
        );

        // Define a ferramenta no menu Inserir do VisualEditor
        function VtmSecretVeTool() {
          VtmSecretVeTool.super.apply(this, arguments);
        }
        OO.inheritClass(VtmSecretVeTool, ve.ui.Tool);
        VtmSecretVeTool.static.name = 'vtmSecret';
        VtmSecretVeTool.static.group = 'insert';
        VtmSecretVeTool.static.icon = 'lock';
        VtmSecretVeTool.static.title = '🔒 Censura / Segredo (Confidencial)';
        VtmSecretVeTool.static.commandName = 'insertVtmSecret';

        ve.ui.toolFactory.register(VtmSecretVeTool);
      });
    });
  }

  // ------------------------------------------------------------------------
  // 3. BARRA RÁPIDA GÓTICA NO EDITOR DE CÓDIGO-FONTE (#wpTextbox1)
  // ------------------------------------------------------------------------
  function initVtmQuickToolbar() {
    var textbox = document.getElementById('wpTextbox1');
    if (!textbox) return;
    if (document.getElementById('vtm-editor-quickbar')) return;

    var bar = document.createElement('div');
    bar.id = 'vtm-editor-quickbar';
    bar.className = 'vtm-editor-quickbar';
    bar.style.cssText = 'display:flex; flex-wrap:wrap; gap:8px; align-items:center; padding:10px 14px; margin:10px 0; background:linear-gradient(90deg, #181014 0%, #0d0d12 100%); border:1px solid #3d0a12; border-left:4px solid #8b0000; border-radius:4px; font-family:"Cinzel", Georgia, serif; box-shadow:0 4px 14px rgba(0,0,0,0.6); z-index:99;';

    // Rótulo da Barra
    var label = document.createElement('span');
    label.style.cssText = 'color:#c5a059; font-size:0.85em; font-weight:700; text-transform:uppercase; letter-spacing:1px; margin-right:6px;';
    label.innerHTML = '🩸 Ferramentas Góticas:';
    bar.appendChild(label);

    // Botão 1: Inline
    var btnInline = document.createElement('button');
    btnInline.type = 'button';
    btnInline.className = 'vtm-quick-btn';
    btnInline.style.cssText = 'background:#240c12; color:#ffffff; border:1px solid #ff2a3f; border-radius:3px; padding:6px 12px; font-size:0.82em; font-weight:700; cursor:pointer; display:inline-flex; align-items:center; gap:6px; transition:all 0.2s ease; box-shadow:0 0 8px rgba(201,24,43,0.4);';
    btnInline.innerHTML = '🔒 Inserir Tarja de Censura (Segredo)';
    btnInline.title = 'Envolve o texto selecionado na predefinição {{Segredo}}';

    btnInline.onmouseover = function () {
      btnInline.style.background = '#4a0f1b';
      btnInline.style.boxShadow = '0 0 14px rgba(255,42,63,0.85)';
    };
    btnInline.onmouseout = function () {
      btnInline.style.background = '#240c12';
      btnInline.style.boxShadow = '0 0 8px rgba(201,24,43,0.4)';
    };
    btnInline.onclick = function (e) {
      e.preventDefault();
      insertSecretTemplate(textbox, false);
    };
    bar.appendChild(btnInline);

    // Botão 2: Bloco
    var btnBlock = document.createElement('button');
    btnBlock.type = 'button';
    btnBlock.className = 'vtm-quick-btn';
    btnBlock.style.cssText = 'background:#181822; color:#c5a059; border:1px solid #3d0a12; border-radius:3px; padding:6px 12px; font-size:0.82em; font-weight:700; cursor:pointer; display:inline-flex; align-items:center; gap:6px; transition:all 0.2s ease;';
    btnBlock.innerHTML = '📁 Dossiê Confidencial (Bloco)';
    btnBlock.title = 'Insere relatório confidencial em formato de bloco';

    btnBlock.onmouseover = function () {
      btnBlock.style.background = '#281c20';
      btnBlock.style.borderColor = '#c5a059';
    };
    btnBlock.onmouseout = function () {
      btnBlock.style.background = '#181822';
      btnBlock.style.borderColor = '#3d0a12';
    };
    btnBlock.onclick = function (e) {
      e.preventDefault();
      insertSecretTemplate(textbox, true);
    };
    bar.appendChild(btnBlock);

    textbox.parentNode.insertBefore(bar, textbox);
  }

  function insertSecretTemplate(textbox, isBlock) {
    var start = textbox.selectionStart;
    var end = textbox.selectionEnd;
    var text = textbox.value;
    var selected = text.substring(start, end);

    var pre = isBlock ? '\n{{Segredo|tipo=bloco|nivel=RELATÓRIO SAD // CONFIDENCIAL|data=AAAA-MM-DD|dica=Alvo Restrito|\n' : '{{Segredo|';
    var defaultText = selected || (isBlock ? 'Escreva aqui o relatório confidencial...' : 'Texto sensível a ser censurado');
    var post = isBlock ? '\n}}\n' : '|data=AAAA-MM-DD|liberado=nao}}';

    var replacement = pre + defaultText + post;
    textbox.value = text.substring(0, start) + replacement + text.substring(end);

    var newCursor = start + pre.length;
    textbox.focus();
    textbox.setSelectionRange(newCursor, newCursor + defaultText.length);

    if (window.$) {
      $(textbox).trigger('input').trigger('change');
    }
  }

  // ------------------------------------------------------------------------
  // 4. ANIMAÇÃO DE CASCATA DAS SEÇÕES (.vtm-section-block)
  // ------------------------------------------------------------------------
  function initSectionAnimation() {
    var content = document.querySelector('.mw-parser-output');
    if (!content || content.dataset.vtmAnimated === 'true') return;

    if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
      return;
    }

    content.dataset.vtmAnimated = 'true';
    var children = Array.from(content.children);
    var sections = [];
    var currentSection = [];

    children.forEach(function (child) {
      if (
        child.classList.contains('catlinks') ||
        child.classList.contains('mw-category-generated') ||
        child.tagName === 'SCRIPT' ||
        child.tagName === 'STYLE' ||
        child.id === 'vtm-editor-quickbar'
      ) {
        if (currentSection.length > 0) {
          sections.push(currentSection);
          currentSection = [];
        }
        return;
      }

      var isH2 = child.tagName === 'H2' || child.classList.contains('mw-heading2');
      if (isH2 && currentSection.length > 0) {
        sections.push(currentSection);
        currentSection = [];
      }
      currentSection.push(child);
    });

    if (currentSection.length > 0) {
      sections.push(currentSection);
    }

    sections.forEach(function (sectionElements, index) {
      var wrapper = document.createElement('div');
      wrapper.className = 'vtm-section-block';
      var delay = (0.12 + index * 0.42).toFixed(2);
      wrapper.style.animationDelay = delay + 's';

      var firstElem = sectionElements[0];
      if (firstElem && firstElem.parentNode) {
        firstElem.parentNode.insertBefore(wrapper, firstElem);
        sectionElements.forEach(function (el) {
          wrapper.appendChild(el);
        });
      }
    });
  }

  // Execução
  function initAll() {
    initVtmSecrets();
    initSectionAnimation();
    initVtmQuickToolbar();
    setupVisualEditorTool();
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', initAll);
  } else {
    initAll();
  }

  if (window.mw && window.mw.hook) {
    window.mw.hook('wikipage.content').add(function () {
      initVtmSecrets();
      initSectionAnimation();
    });
    window.mw.hook('ve.activationComplete').add(function () {
      setupVisualEditorTool();
    });
  }
})();