froala / wysiwyg-editor

The next generation Javascript WYSIWYG HTML Editor.
https://www.froala.com/wysiwyg-editor
Other
5.3k stars 672 forks source link

Separators not working as expected #4114

Open sovanny opened 3 years ago

sovanny commented 3 years ago

Expected behavior.

Using arrays within arrays or "|" in button array as toolbarButtons option create vertical separators.

Actual behavior.

Using arrays within arrays

Creates empty space between button groups

Using "|", in the button array in a button object like moreText

Creates vertical separators, but as soon as the window is resized they dissapear and create a blank line in the top of the toolbar.

Steps to reproduce the problem.

Even the live example isn't working. Array within array example: https://jsfiddle.net/o5kshxun/2/ "|" example. Make browser window wider to see the resize bug: https://jsfiddle.net/o5kshxun/1/

Editor version.

v3.2.5

OS.

MacOS

Browser.

Chrome 87.0.4280.88

Images.

Bug when separator sits in top left corner on a new line image

alexgritton commented 2 years ago

For the "|" separator issue, we are creating a custom button, which overrides the Froala "|" divider.

To do this we register a Froala command with the same name "|". It doesn't look as nice but it works when resizing the page.


FroalaEditor.RegisterCommand('|', {
      title: '',
      undo: false,
      focus: false,
      showOnMobile: true,

      refresh: function ($btn) {
        $btn.addClass('fr-no-hover');
      }
})

.fr-no-hover {
  &:hover {
    background-color: inherit !important;
  }
}
IchigoWalker commented 1 year ago

Still reproducible. On Froala v4 custom button behave the same way as default separators. The problem is in Froala's breakpoints, it's appear that separators gets collapsed and placed outside on group on 1200px which is internal breakpoint. Just in case there's a way to disable of bypass breakpoints and responsiveness, please let me know. Thanks!

praveen-ks commented 1 year ago

Happening because froala try to reload the toolbar icons everytime we resize the window. In this process it removes all the btn-group wrapper and the buttons but not the separators because they don't have any command attribute. According to window size it will recreate the toolbar with btn-groups but without separators but the original separators are still present and moved to start of toolbar. So we should remove all the separator while removing the btn-groups and add it back to btn-groups while it's creation. function _showScreenButtons is the culprit.

I have overriden the function for vertical separator. Make changes if you need to fix it for horizontal-separator.

// OVERRIDE STARTS
look for overrides here....
// OVERRIDE ENDS
function _showScreenButtons() {
    // don't add trackChanges button if plugin is not enabled
    if (editor.$tb.find("[data-name='trackChanges-".concat(editor.id, "']")).length == 0 && editor.opts.pluginsEnabled.indexOf('track_changes') > -1) {
      var trackingBtns = ['showChanges', 'applyAll', 'removeAll', 'applyLast', 'removeLast'];
      editor.$tb.append($('<div class="fr-more-toolbar"></div>').data('name', "trackChanges-".concat(editor.id)));

      for (var _i = 0, _trackingBtns = trackingBtns; _i < _trackingBtns.length; _i++) {
        var cmdName = _trackingBtns[_i];
        var cmdInfo = FroalaEditor.COMMANDS[cmdName];

        if (!cmdInfo) {
          continue;
        }

        cmdInfo.more_btn = true;
        var $moreButton = $(editor.button.build(cmdName, cmdInfo, true)); // Register the more button

        editor.button.addButtons($moreButton);
        editor.$tb.find("[data-name='trackChanges-".concat(editor.id, "']")).append($moreButton);
      }
    } // Update the toolbar only if screen size is changed

    if (previousScreenSize !== editor.helpers.screenSize()) {
      // Get screen button groups
      var buttonGroups = _screenButtons(); // Toolbar groups

      var mainToolbarButtonGroups = $();
      var moreToolbarButtonGroups = $(); // Hide all buttons

      editor.$tb.find('.fr-btn-grp > .fr-command, .fr-more-toolbar > .fr-command, .fr-btn-grp > .fr-btn-wrap > .fr-command, .fr-more-toolbar > .fr-btn-wrap > .fr-command').addClass('fr-hidden'); // Remove wrapper div from button groups

      _removeButtonGroupWrappers();
      // OVERRIDE STARTS
      // On window resize it removes all the vertical separators from the button groups.
      editor.$tb.find('.fr-separator.fr-vs').remove();
      editor.$tb.find('.fr-separator.fr-hs').remove();
      // OVERRIDE ENDS

      for (var groupName in buttonGroups) {
        // Current button group
        var buttonGroup = buttonGroups[groupName]; // Ignore non-button groups

        if (!buttonGroup.buttons) {
          continue;
        } // skip trackChanges extra toolbar if plugin is not enabled

        if (groupName === 'trackChanges' && editor.opts.pluginsEnabled.indexOf('track_changes') === -1) {
          continue;
        } // Current button group Details

        var moreToolbarButtons = void 0;
        var buttonCount = 0;
        var visibleButtons = 3;
        var mainToolbarButtons = void 0; // No need to create a track change primary button as it is already present in moreRich group

        if (groupName !== 'trackChanges') {
          mainToolbarButtons = $("<div class=\"fr-btn-grp fr-float-".concat(buttonGroups[groupName].align ? buttonGroups[groupName].align : 'left', "\"></div>"));
        }

        if (buttonGroups.showMoreButtons) {
          moreToolbarButtons = $('<div class="fr-more-toolbar"></div>').data('name', "".concat(groupName, "-").concat(editor.id)); // On screen resize, maintain the expanded state of moreRich and trackChanges section

          if ((groupName === 'trackChanges' || groupName === 'moreRich') && editor.opts.trackChangesEnabled) {
            moreToolbarButtons.addClass('fr-expanded');
          }
        }

        for (var i = 0; i < buttonGroup.buttons.length; i++) {
          // If buttonVisible is provided then use it
          if (buttonGroup.buttonsVisible !== undefined) {
            visibleButtons = buttonGroup.buttonsVisible;
          } // Get the button for the command

          // OVERRIDE STARTS
          // On window resize it adds a vertical & horizontal separator for command | & - to button group.
          if (buttonGroup.buttons[i] === '|') {
              mainToolbarButtons.append($(`<div class="fr-separator fr-vs" role="separator" aria-orientation="vertical"></div>`));
              continue;
            }
            else if (buttonGroup.buttons[i] === '-') {
              mainToolbarButtons.append($(`<div class="fr-separator fr-hs" role="separator" aria-orientation="horizontal"></div>`));
              continue;
            }
          // OVERRIDE ENDS

          var $btn = editor.$tb.find('> .fr-command[data-cmd="' + buttonGroup.buttons[i] + '"], > div.fr-btn-wrap > .fr-command[data-cmd="' + buttonGroup.buttons[i] + '"]');
          var $dropdown = null; // If it is a dropdown button

          if (editor.node.hasClass($btn.next().get(0), 'fr-dropdown-menu')) {
            $dropdown = $btn.next();
          } // If it is a button with options

          if (editor.node.hasClass($btn.next().get(0), 'fr-options')) {
            $btn.removeClass('fr-hidden');
            $btn.next().removeClass('fr-hidden');
            $btn = $btn.parent();
          } // Show the buttons in the toolbar

          $btn.removeClass('fr-hidden'); // Wrap the buttons in a button group

          if (buttonGroups.showMoreButtons && buttonCount >= visibleButtons) {
            moreToolbarButtons.append($btn);

            if ($dropdown) {
              moreToolbarButtons.append($dropdown);
            }
          } else {
            mainToolbarButtons.append($btn);

            if ($dropdown) {
              mainToolbarButtons.append($dropdown);
            }
          }

          buttonCount++;
        } // Add more button if buttons in group are more than 'buttonsVisible'

        if (buttonGroups.showMoreButtons && buttonCount > visibleButtons) {
          var _$moreButton = editor.$tb.find(".fr-command[data-cmd=\"".concat(groupName, "\"]"));

          if (_$moreButton.length > 0) {
            _$moreButton.removeClass('fr-hidden fr-open');
          } else {
            // Create a new more button if not present already
            var _cmdName = groupName;
            var _cmdInfo = FroalaEditor.COMMANDS[_cmdName];

            if (_cmdInfo) {
              _cmdInfo.more_btn = true;
              _$moreButton = $(editor.button.build(_cmdName, _cmdInfo, true)); // Register the more button

              editor.button.addButtons(_$moreButton);
            }
          }

          if (mainToolbarButtons) {
            mainToolbarButtons.append(_$moreButton);
          }
        } // Append visible buttons on the main toolbar

        if (mainToolbarButtons) {
          mainToolbarButtonGroups.push(mainToolbarButtons);
        } // Append more toolbar buttons

        if (buttonGroups.showMoreButtons) {
          moreToolbarButtonGroups.push(moreToolbarButtons);
        }
      } // Append button groups to the editor

      if (editor.opts.toolbarBottom) {
        editor.$tb.append(moreToolbarButtonGroups);
        editor.$tb.find('.fr-newline').remove();
        editor.$tb.append('<div class="fr-newline"></div>');
        editor.$tb.append(mainToolbarButtonGroups);
      } else {
        editor.$tb.append(mainToolbarButtonGroups);
        editor.$tb.find('.fr-newline').remove();
        editor.$tb.append('<div class="fr-newline"></div>');
        editor.$tb.append(moreToolbarButtonGroups);
      } // Close the more toolbar

      editor.$tb.removeClass('fr-toolbar-open');
      editor.$box.removeClass('fr-toolbar-open'); // Switch to normal view if in code view

      editor.events.trigger('codeView.toggle');
    } // Refresh more toolbar height on resize

    setMoreToolbarsHeight();
  }