sieukrem / jn-npp-plugin

Plugin for Notepad++ allowing you to automate some tasks using JavaScript
https://github.com/sieukrem/jn-npp-plugin/wiki
110 stars 24 forks source link

menus with check/uncheck values becomes assigned to different ones when a submenu exist above them #117

Closed nokotto closed 1 year ago

nokotto commented 1 year ago

Hi, it may be some kind of array key misaligned? but I wasn't able to locate were. I hope it don't takes much of your time,

Description of the Issue

The menus with check/uncheck values becomes assigned to different ones when a submenu exist above them. Adding a sepparator or other menu also affects such wrong assigment.

To Reproduce

var mainmenu = Editor.addMenu('DebugMenu');
var submenu  = mainmenu.addMenu('SubmenuOne');

var menu_1 = submenu.addItem({ text: 'menu_1', 
    cmd :function(){
        menu_1.checked = !menu_1.checked;
    }
});
menu_1.checked = false;

var menu_2 = submenu.addItem({ text: 'menu_2', 
    cmd :function(){
        menu_2.checked = !menu_2.checked;
    }
});
menu_2.checked = false;

var menu_3 = submenu.addItem({ text: 'menu_3', 
    cmd :function(){
        menu_3.checked = !menu_3.checked;
    }
});
menu_3.checked = false;

//mainmenu.addSeparator(); //This separator affects the order of above checked items also.

var menu_4 = mainmenu.addItem({ text: 'menu_4', 
    cmd :function(){
        menu_4.checked = !menu_4.checked;
    }
});
menu_4.checked = true;

var menu_5 = mainmenu.addItem({ text: 'menu_5', 
    cmd :function(){
        menu_5.checked = !menu_5.checked;
    }
});
menu_5.checked = true;

Expected behavior It's expected the above code render as,

SubmenuOne > menu_1 : unchecked menu_2 : unchecked menu_3 : unchecked menu_4 : checked << menu_5 : checked <<

if a menu is clicked it gets checked/unchecked and none of the other menus gets affected. A separator or other menu would not affect the above neither.

Actual Behavior Actually the menus are wrongly rendered as,

SubMenu 1 > menu_1 : checked << menu_2 : checked << menu_3 : unchecked menu_4 : unchecked menu_5 : unchecked

if menu_4 is clicked, what gets checked/unchecked is menu_1 if menu_5 is clicked, what gets checked/unchecked is menu_2

If a separator or menu is added before menu_4, then menu_1 renders unchecked, and menu_2 and menu_3 as checked.

I took as temporal workaround not to use submenus at the top.

.

sieukrem commented 1 year ago

Thanks for investigation and report. I can not check now. Could you please check whether menu.text is expected one in the cmd functions!

nokotto commented 1 year ago

don't worry, for when you have a spare time,

menu.text is Not the expected one in cmd functions:

If a separator is added before menu_4, it get displaced one element:

In both cases the submenu behavior seems the expected:

Also it gets displaced if it's added a menu at the top:

var mainmenu = Editor.addMenu('DebugMenu2');

// menu_0

var menu_0 = mainmenu.addItem({ text: 'menu_0', 
    cmd :function(){
        menu_0.checked = !menu_0.checked;
        alert(menu_0.text);
    }
});
menu_0.checked = false;

// SubMenuOne

var submenu  = mainmenu.addMenu('SubmenuOne');

var menu_1 = submenu.addItem({ text: 'menu_1', 
    cmd :function(){
        menu_1.checked = !menu_1.checked;
        alert(menu_1.text);
    }
});
menu_1.checked = false;

var menu_2 = submenu.addItem({ text: 'menu_2', 
    cmd :function(){
        menu_2.checked = !menu_2.checked;
        alert(menu_2.text);
    }
});
menu_2.checked = false;

var menu_3 = submenu.addItem({ text: 'menu_3', 
    cmd :function(){
        menu_3.checked = !menu_3.checked;
        alert(menu_3.text);
    }
});
menu_3.checked = false;

// SubMenuTwo

var submenu2  = mainmenu.addMenu('SubmenuTwo');

var menu_21 = submenu2.addItem({ text: 'menu_21', 
    cmd :function(){
        menu_21.checked = !menu_21.checked;
        alert(menu_21.text);
    }
});
menu_21.checked = false;

var menu_22 = submenu2.addItem({ text: 'menu_22', 
    cmd :function(){
        menu_22.checked = !menu_22.checked;
        alert(menu_22.text);
    }
});
menu_22.checked = false;

var menu_23 = submenu2.addItem({ text: 'menu_23', 
    cmd :function(){
        menu_23.checked = !menu_23.checked;
        alert(menu_23.text);
    }
});
menu_23.checked = false;

//mainmenu.addSeparator(); //This separator affects the order of above checked items also.

var menu_4 = mainmenu.addItem({ text: 'menu_4', 
    cmd :function(){
        menu_4.checked = !menu_4.checked;
        alert(menu_4.text);
    }
});
menu_4.checked = true;

var menu_5 = mainmenu.addItem({ text: 'menu_5', 
    cmd :function(){
        menu_5.checked = !menu_5.checked;
        alert(menu_5.text);
    }
});
menu_5.checked = true;

The above rendered as:

menu_0 : unchecked SubmenuOne > menu_1 : unchecked menu_2 : checked << unchecked expected menu_3 : checked << unchecked expected SubmenuTwo > menu_21 : unchecked menu_22 : unchecked menu_23 : unchecked menu_4 : unchecked << checked expected. In cmd behaves as menu_2 ( menu.text and menu.checked ) menu_5 : unchecked << checked expected. In cmd behaves as menu_3 ( menu.text and menu.checked )

And if the separator before menu_4 is enabled, it gets displaced again (with strange pattern) , rendered as:

menu_0 : unchecked SubmenuOne > menu_1 : unchecked menu_2 : unchecked menu_3 : checked << unchecked expected SubmenuTwo > menu_21 : unchecked menu_22 : unchecked menu_23 : unchecked ------------- menu_4 : unchecked << checked expected. In cmd behaves as menu_3 ( menu.text and menu.checked ) menu_5 : checked << OK

there menu_5.text in cmd is menu_5 (just as happens with .checked ), what is the expected behavior.

In all cases the submenus behavior seems correct.

sieukrem commented 1 year ago

@nokotto I could reproduce this issue. Please check the build.

nokotto commented 1 year ago

Thank you so much @sieukrem

The build works as expected with the second debug code ( DebugMenu2 ) , but with the code of the first post ( DebugMenu ) the issue keeps happening .

First post "DebugMenu", before patched build:

SubMenu 1 > menu_1 : checked < menu_2 : checked < menu_3 : unchecked menu_4 : unchecked << behaves as menu_1 menu_5 : unchecked << behaves as menu_2

First post "DebugMenu", with patched build ( gets one element displaced ):

SubMenu 1 > menu_1 : unchecked menu_2 : checked < menu_3 : checked < menu_4 : unchecked << behaves as menu_2 menu_5 : unchecked << behaves as menu_3

First post "DebugMenu", with patched build, enabled separator ( gets two elements displaced ):

SubMenu 1 > menu_1 : unchecked menu_2 : unchecked menu_3 : checked < ---------------- menu_4 : unchecked << behaves as menu_3 menu_5 : checked << OK

I disabled menu elements of DebugMenu2 with the patched build until the issue raised. It seems the menu_0 and SubmenuTwo absence may be what alters the elements position that are seen with DebugMenu in the patched build:

New debug code DebugMenu3

enable_menu0     = 1;  // 0 or 1
nsubmenu_one     = 3;  // number of elements in menu, 0 to 3
nsubmenu_two     = 3;  // number of elements in menu, 0 to 3
enable_separator = 1;  // 0 or 1

//Test1: Issue keeps with the first patch
enable_menu0     = 0;
nsubmenu_one     = 2;
nsubmenu_two     = 0;
enable_separator = 0;

/* //Test2: Issue keeps with the first patch
enable_menu0     = 0;
nsubmenu_one     = 3;
nsubmenu_two     = 0;
enable_separator = 0; */

/* //Test3: Issue keeps with the first patch
enable_menu0     = 1;
nsubmenu_one     = 3;
nsubmenu_two     = 0;
enable_separator = 0; */

/* //Test4: Issue SOLVED with the first patch
enable_menu0     = 1;
nsubmenu_one     = 3;
nsubmenu_two     = 3;
enable_separator = 0; */

/* //Test5: Issue SOLVED with the first patch
enable_menu0     = 1;
nsubmenu_one     = 3;
nsubmenu_two     = 3;
enable_separator = 1; */

var mainmenu = Editor.addMenu('DebugMenu3');

// menu_0
if(enable_menu0){
    var menu_0 = mainmenu.addItem({ text: 'menu_0', 
        cmd :function(){
            menu_0.checked = !menu_0.checked;
            alert(menu_0.text);
        }
    });
    menu_0.checked = false;
}

// SubMenuOne
if(nsubmenu_one){
    var submenu  = mainmenu.addMenu('SubmenuOne');

    if(nsubmenu_one > 0){
      var menu_1 = submenu.addItem({ text: 'menu_1', 
        cmd :function(){
            menu_1.checked = !menu_1.checked;
            alert(menu_1.text);
        }
      });
      menu_1.checked = false;
    }

    if(nsubmenu_one > 1){
      var menu_2 = submenu.addItem({ text: 'menu_2', 
        cmd :function(){
            menu_2.checked = !menu_2.checked;
            alert(menu_2.text);
        }
      });
    }
    menu_2.checked = false;

    if(nsubmenu_one > 2){
      var menu_3 = submenu.addItem({ text: 'menu_3', 
        cmd :function(){
            menu_3.checked = !menu_3.checked;
            alert(menu_3.text);
        }
      });
      menu_3.checked = false;
    }
}

// SubMenuTwo
if(nsubmenu_two){
    var submenu2  = mainmenu.addMenu('SubmenuTwo');

    if(nsubmenu_two > 0){
     var menu_21 = submenu2.addItem({ text: 'menu_21', 
        cmd :function(){
            menu_21.checked = !menu_21.checked;
            alert(menu_21.text);
        }
     });
     menu_21.checked = false;
    }

    if(nsubmenu_two > 1){
     var menu_22 = submenu2.addItem({ text: 'menu_22', 
        cmd :function(){
            menu_22.checked = !menu_22.checked;
            alert(menu_22.text);
        }
     });
     menu_22.checked = false;
    }

    if(nsubmenu_two > 2){
     var menu_23 = submenu2.addItem({ text: 'menu_23', 
        cmd :function(){
            menu_23.checked = !menu_23.checked;
            alert(menu_23.text);
        }
     });
     menu_23.checked = false;
    }
}

if(enable_separator){
    mainmenu.addSeparator(); //This separator affects the order of above checked items also.
}

var menu_4 = mainmenu.addItem({ text: 'menu_4', 
    cmd :function(){
        menu_4.checked = !menu_4.checked;
        alert(menu_4.text);
    }
});
menu_4.checked = true;

var menu_5 = mainmenu.addItem({ text: 'menu_5', 
    cmd :function(){
        menu_5.checked = !menu_5.checked;
        alert(menu_5.text);
    }
});
menu_5.checked = true;

Test1: Issue keeps with the first patch

enable_menu0 = 0; nsubmenu_one = 2; nsubmenu_two = 0; enable_separator = 0;

SubMenu 1 > menu_1 : unchecked menu_2 : checked < menu_4 : unchecked << behaves as menu_2 menu_5 : checked << OK

Before the first patch: menu_4 behaves as menu_1 menu_5 behaves as menu_2

--

Test2: Issue keeps with the first patch

enable_menu0 = 0; nsubmenu_one = 3; nsubmenu_two = 0; enable_separator = 0;

SubMenu 1 > menu_1 : unchecked menu_2 : checked < menu_3 : checked < menu_4 : unchecked << behaves as menu_2 menu_5 : unchecked << behaves as menu_3

Before the first patch: menu_4 behaves as menu_1 menu_5 behaves as menu_2

--

Test3: Issue keeps with the first patch

enable_menu0 = 1; nsubmenu_one = 3; nsubmenu_two = 0; enable_separator = 0;

menu_0 : unchecked SubMenu 1 > menu_1 : unchecked menu_2 : unchecked menu_3 : checked < menu_4 : unchecked << behaves as menu_3 menu_5 : checked << OK

Before the first patch: menu_4 behaves as menu_2 menu_5 behaves as menu_3

--

Test:4: Issue SOLVED with the first patch

enable_menu0 = 1; nsubmenu_one = 3; nsubmenu_two = 3; enable_separator = 0;

menu_0 : unchecked SubMenu 1 > menu_1 : unchecked menu_2 : unchecked menu_3 : unchecked SubMenu 2 > menu_21 : unchecked menu_22 : unchecked menu_23 : unchecked menu_4 : unchecked << OK menu_5 : checked << OK

Before the first patch: menu_4 behaves as menu_2 menu_5 behaves as menu_3

--

Test5: Issue SOLVED with the first patch

enable_menu0 = 1; nsubmenu_one = 3; nsubmenu_two = 3; enable_separator = 1;

menu_0 : unchecked SubMenu 1 > menu_1 : unchecked menu_2 : unchecked menu_3 : unchecked SubMenu 2 > menu_21 : unchecked menu_22 : unchecked menu_23 : unchecked -------------------- menu_4 : unchecked << OK menu_5 : checked << OK

Before the first patch: menu_4 behaves as menu_3 menu_5 behaves OK

--

PS: Take care when you uncomment the blocks in the above debug code by selecting the lines and right-clicking, as I just realized there is some kind of issue with Notepad++ what do an unexpected uncomment of unselected lines. One select Test2 variables for uncomment, and it turns that Test2 and Test3 variables becomes uncommented.

Edit: updated code to 5 test

sieukrem commented 1 year ago

@nokotto please check the next build

nokotto commented 1 year ago

Perfect. This new build seems to solve all the issues @sieukrem , thank you so much for your time!

The tests what I've tried are:

// OK enable_menu0 = 0; nsubmenu_one = 2; nsubmenu_two = 0; enable_separator = 0;

// OK enable_menu0 = 0; nsubmenu_one = 3; nsubmenu_two = 0; enable_separator = 0;

// OK enable_menu0 = 0; nsubmenu_one = 3; nsubmenu_two = 0; enable_separator = 1;

// OK enable_menu0 = 1; nsubmenu_one = 3; nsubmenu_two = 0; enable_separator = 1;

// OK enable_menu0 = 1; nsubmenu_one = 3; nsubmenu_two = 0; enable_separator = 0;

// OK enable_menu0 = 1; nsubmenu_one = 3; nsubmenu_two = 3; enable_separator = 0;

// OK enable_menu0 = 1; nsubmenu_one = 3; nsubmenu_two = 3; enable_separator = 1;

Additionally, I added more submenus, submenus of submenus, separators, and other combinations, in Notepad++ v8.4 and 8.5.

All works as expected with this build.