Пользовательская кнопка TinyMCE 4.x для увеличения межбуквенного интервала не работает

Я реализовал кнопку TinyMCE, чтобы увеличить расстояние между буквами на http://fiddle.tinymce.com/Z9eaab/31. Если вы вводите слова "некоторый текст" в текстовую область внизу, а затем выбираете "некоторые" и нажимаете кнопку "Увеличить межбуквенный интервал" несколько раз, межбуквенный интервал увеличивается только в первый раз. Если вы выберете второе слово "текст", интервал будет увеличиваться каждый раз, когда вы нажимаете "Увеличить интервал между буквами". как это должно.

Я могу видеть из console.log в строке 9, что, когда он не работает, это потому, что текущее чтение интервала не отражает последнее увеличение, поэтому оно просто повторяет первое.

<script type="text/javascript">
  tinymce.PluginManager.add('example', function(editor, url) {
    // Add a button that opens a window
    editor.addButton('example1', {
      text: 'Increase letter spacing',
      icon: false,
      onclick: function() {
        var currentSpacing = new Number($(tinyMCE.activeEditor.selection.getNode()).css('letter-spacing').replace('px', ''));
        console.log("spacing read is" + currentSpacing);
        currentSpacing = currentSpacing + 1;

        tinymce.activeEditor.formatter.register('increaseSpacing', {
          inline: 'span',
          styles: {
            'letter-spacing': currentSpacing + 'px'
          }
        });

        tinymce.activeEditor.formatter.apply('increaseSpacing');
      }
    });

    editor.addButton('example2', {
      text: 'Decrease letter spacing',
      icon: false,
      onclick: function() {
        var currentSpacing = new Number($(tinyMCE.activeEditor.selection.getNode()).css('letter-spacing').replace('px', ''));
        currentSpacing = currentSpacing - 1;

        tinymce.activeEditor.formatter.register('decreaseSpacing', {
          inline: 'span',
          styles: {
            'letter-spacing': currentSpacing + 'px'
          }
        });

        tinymce.activeEditor.formatter.apply('decreaseSpacing');
      }
    });

    // Adds a menu item to the tools menu
    editor.addMenuItem('example', {
      text: 'Example plugin',
      context: 'tools',
      onclick: function() {
        // Open window with a specific url
        editor.windowManager.open({
          title: 'TinyMCE site',
          url: 'http://www.tinymce.com',
          width: 400,
          height: 300,
          buttons: [{
            text: 'Close',
            onclick: 'close'
          }]
        });
      }
    });
  });

  tinymce.init({
    selector: "textarea",
    plugins: "example",
    toolbar: "example1 example2 undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image"
  });
</script>

<form method="post" action="dump.php">
  <textarea name="content"></textarea>
</form>

Кто-нибудь знает, что происходит?

2 ответа

Решение

Вы используете selection.getNode() который находит общий родительский узел начальной и конечной точек выбора. Это не тот узел, который находится в текущем выборе.

В вашем случае вы хотите <span> вы создали, но то, что вы на самом деле просили, это его вложение <p> (впоследствии вы проверяете свой текущий letter-spacing Значение CSS, которого у него не будет).

Чтобы исправить это, после применения форматирования возьмите диапазон (либо созданный ранее, либо недавно добавленный) и установите для него текущий выбор. Вы можете сделать это используя selection.getStart():

var spanNode = tinyMCE.activeEditor.selection.getStart();
tinymce.activeEditor.selection.select(spanNode);

Когда используется после tinymce.activeEditor.formatter.apply(), это будет правильный промежуток.

Вот обновленный код (я сделал ряд других изменений форматирования):

<script type="text/javascript">
  tinymce.PluginManager.add('example', function(editor, url) {
    // Add a button that opens a window
    editor.addButton('example1', {
      text: 'Increase letter spacing',
      icon: false,
      onclick: function() {

        var currentSpacing = 0;
        var $selectedContent = $(tinyMCE.activeEditor.selection.getContent({'format': 'html'}));

        if ($selectedContent.is("span") && $selectedContent.css('letter-spacing')) {
          currentSpacing = +($selectedContent.css('letter-spacing').replace('px', ''));
        }

        currentSpacing += 1;

        tinymce.activeEditor.formatter.apply('letterSpacing', {
          value: currentSpacing + 'px'
        });

        var spanNode = tinyMCE.activeEditor.selection.getStart();
        tinymce.activeEditor.selection.select(spanNode);

      }
    });

    editor.addButton('example2', {
      text: 'Decrease letter spacing',
      icon: false,
      onclick: function() {

        var currentSpacing = 0;
        var $selectedContent = $(tinyMCE.activeEditor.selection.getContent({'format': 'html'}));

        if ($selectedContent.is("span") && $selectedContent.css('letter-spacing')) {
          currentSpacing = +($selectedContent.css('letter-spacing').replace('px', ''));
        }

        currentSpacing -= 1;

        tinymce.activeEditor.formatter.apply('letterSpacing', {
          value: currentSpacing + 'px'
        });

        var spanNode = tinyMCE.activeEditor.selection.getStart();
        tinymce.activeEditor.selection.select(spanNode);

      }
    });

    // Adds a menu item to the tools menu
    editor.addMenuItem('example', {
      text: 'Example plugin',
      context: 'tools',
      onclick: function() {
        // Open window with a specific url
        editor.windowManager.open({
          title: 'TinyMCE site',
          url: 'http://www.tinymce.com',
          width: 400,
          height: 300,
          buttons: [{
            text: 'Close',
            onclick: 'close'
          }]
        });
      }
    });
  });

  tinymce.init({
    selector: "textarea",
    plugins: "example",
    toolbar: "example1 example2 undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image",
    formats: {
      'letterSpacing': {
        inline: 'span',
        styles: {
          'letter-spacing': '%value'
        }
      }
    }
  });
</script>

<form method="post" action="dump.php">
  <textarea name="content"></textarea>
</form>

Демо: http://fiddle.tinymce.com/wYfaab/2

Для меня внесены некоторые изменения в приведенный выше код, и это работает:

      <script>
tinymce.PluginManager.add('example', function(editor, url) {
    // Add a button that opens a window
    editor.addButton('example1', {
      text: 'Increase letter spacing',
      icon: false,
      onclick: function() {

        var currentSpacing = 0;
        var $selectedContent = $(tinyMCE.activeEditor.selection.getContent({'format': 'html'}));

        
        
        if ($selectedContent.is("span") && $selectedContent.css('letter-spacing')) {
          currentSpacing = +($selectedContent.css('letter-spacing').replace('px', ''));
        }
        currentSpacing += 1;
        
        tinymce.activeEditor.formatter.register('mycustomformat', {
           inline: 'span',
           styles: {'letterSpacing': currentSpacing+'px'}
         });
        tinymce.activeEditor.formatter.apply('mycustomformat');
        
        var spanNode = tinyMCE.activeEditor.selection.getStart();
        tinymce.activeEditor.selection.select(spanNode);

      }
    });

    editor.addButton('example2', {
      text: 'Decrease letter spacing',
      icon: false,
      onclick: function() {

        var currentSpacing = 0;
        var $selectedContent = $(tinyMCE.activeEditor.selection.getContent({'format': 'html'}));

        if ($selectedContent.is("span") && $selectedContent.css('letter-spacing')) {
          currentSpacing = +($selectedContent.css('letter-spacing').replace('px', ''));
        }

        currentSpacing -= 1;

        tinymce.activeEditor.formatter.register('mycustomformat2', {
           inline: 'span',
           styles: {'letterSpacing': currentSpacing+'px'}
         });
        tinymce.activeEditor.formatter.apply('mycustomformat2');

        var spanNode = tinyMCE.activeEditor.selection.getStart();
        tinymce.activeEditor.selection.select(spanNode);

      }
    });

    // Adds a menu item to the tools menu
    editor.addMenuItem('example', {
      text: 'Example plugin',
      context: 'tools',
      onclick: function() {
        // Open window with a specific url
        editor.windowManager.open({
          title: 'TinyMCE site',
          url: 'http://www.tinymce.com',
          width: 400,
          height: 300,
          buttons: [{
            text: 'Close',
            onclick: 'close'
          }]
        });
      }
    });
});


tinymce.init({
    selector: "textarea",
    plugins: "example",
    toolbar: "example1 example2 undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link image",
    formats: {
      'letterSpacing': {
        inline: 'span',
        styles: {
          'letter-spacing': '%value'
        }
      }
    }
  });

</script>
<form method="post" action="dump.php">
  <textarea name="content"></textarea>
</form>
Другие вопросы по тегам