Global search on Autocontrol Configuration Page

127 views
Skip to first unread message

Rightclick

unread,
Jul 20, 2023, 12:45:57 AM7/20/23
to AutoControl
I would like a query or something that I can execute from Devtools to:
  1. List all section names that have a trigger string (ie: any trigger that uses any combination with "F4" in it).
  2. List all section names that have a given partial string match in it's action name title.
I also suggest that this ability be built in to the configuration page.

AutoControl support

unread,
Jul 21, 2023, 11:11:16 AM7/21/23
to AutoControl
Are you looking for a javascript snippet?
The following one-liner gives you all section names that contain an F4 trigger.
[...document.querySelectorAll('event')].filter(elem => elem.innerText.startsWith('F4')).map( elem => elem.closest('[pnlId]').getAttribute('pnlId') )
Message has been deleted

Rightclick

unread,
Jul 22, 2023, 8:22:17 PM7/22/23
to AutoControl
Yes, that was the idea. I'm finding though I won't get accurate results unless I first click on each section tab to force them to create the information in the DOM. I've tried to do this programmatically with no luck. Is there a way I can do this? 

AutoControl support

unread,
Jul 24, 2023, 1:58:23 PM7/24/23
to AutoControl
Try this:
$('tabs [pnlId]').triggerEvt('mousedown mouseup', true)

Rightclick

unread,
Jul 25, 2023, 7:15:00 AM7/25/23
to AutoControl
That did the trick. I'm finding this very helpful and informative so I am including the script below in case others want to use it. If you have a lot of actions in many sections this script can help locate them. It is easier to solve trigger conflicts or find action names that could have been filed in a number of possible sections. I really suggest this functionality be native in the extension.

/*
    AutoControl configuration page Global Search
   
    1) Open AutoControl configuration page in Devtools.
    2) Run this code as a Devtools snippet.
    3) In console perform search as shown in examples.
       st("<search_expression") // search_trigger
       sa("<search_expression") // search_action_name      

    Notes:
        - Searches are case insensitive.
        - Searches accept regular expressions (use DOUBLE \\ for escape chars).
        - Disabled action results are displayed in dimgrey color.
        - At the moment searches only Triggers or Action Names.

    Examples search_trigger:
        st("f1")    // return all actions that contain F1 in their trigger definition (will include F10, F11, F12...)
        st("f1\\b") // return all actions that contain only F1 in their trigger definition (will include Shift + F1, Ctrl + F1... note \\b escape sequence)
        st("^f1$")  // return all actions that contain only F1 in their trigger.
       
    Examples search_action_name:
        sa("reload")            // return all actions with reload in their action names.
        sa("actl|autocontrol")  // return all actions with either actl or autocontrol in their action names.
        sa("^tw-")              // return all actions that start with tw- prefix.
       
*/
"use strict";
console.clear();
const dummy = render_tabs();

// aliases for search functions
const st = search_trigger;
const sa = search_action_name;

function search_action_name(p_search_expr) {

    function draw_heading(c1, c2, c3) {
        const heading_style = "color: yellow; font: larger 800;";
        console.log(`%c ${pad("Section Name", c1)}${pad("Action Name", c2)}`, heading_style);
        console.log(`%c ${pad("─", c1, "─")}${pad("─", c2, "─")}`, heading_style);
    }

    const c1 = 30, c2 = 50;
    const trigactlists = [...document.querySelectorAll("trigactlist")];
    const regex = new RegExp(p_search_expr, "i");

    draw_heading(c1, c2);
    for (const trigactlist of trigactlists) {
        const trigacts = Array.from(trigactlist.querySelectorAll("trigact"));
        for (const trigact of trigacts) {
            const action_name = trigact.querySelector("header > desc > input[type=text]").value || "<<< UNNAMED >>>";
            if (!action_name.match(regex)) {
                continue;
            }

            const panel_id = trigact.closest("[pnlId]").getAttribute("pnlId");
            const section_name = document.querySelector(`tab[pnlId="${panel_id}"]`).innerText;
            const enabled = (trigact.classList.contains("disabled")) ? "disabled" : "enabled";
            const color = (enabled === "disabled") ? "dimgrey" : "white";
            console.log(`%c ${pad(section_name, c1)}${action_name}`, `color: ${color}`);
        }
    }
}

function search_trigger(p_search_expr) {
    function draw_heading(c1, c2, c3) {
        const heading_style = "color: yellow; font: larger 800;";
        console.log(`%c ${pad("Section Name", c1)}${pad("Action Name", c2)}${pad("Matched Trigger", c3)}`, heading_style);
        console.log(`%c ${pad("─", c1, "─")}${pad("─", c2 + 1, "─")}${pad("─", c3, "─")}`, heading_style);
    }

    const c1 = 20, c2 = 60, c3 = 40;
    const cont_nodes = [...document.querySelectorAll("content > triggers > content > trigger > combinseq > combin > cont")];
    const regex = new RegExp(p_search_expr, "i");
    const filtered_events = cont_nodes.filter(cont => cont.innerText.match(regex));

    draw_heading(c1, c2, c3);
    for (const cont of filtered_events) {
        const panel_id = cont.closest("[pnlId]").getAttribute("pnlId");
        const section_name = document.querySelector(`tab[pnlId="${panel_id}"]`).innerText;
        // const trigger = cont.innerText.replace(/\n|left\s|right\s/gi, "");
        const trigger = cont.innerText.replace(/\n/gi, "");
        const trigact = cont.closest("trigact");
        const enabled = (trigact.classList.contains("disabled")) ? "disabled" : "enabled";
        const action_name = trigact.querySelector("header > desc > input[type=text]").value || "<<< UNNAMED >>>";
        const color = (enabled === "disabled") ? "dimgrey" : "white";
        console.log(`%c ${pad(section_name, c1)}${pad(action_name, c2)}${pad(trigger, c3)}`, `color: ${color}`);
    }
}

function pad(p_string, p_length, p_char = " ") {
    if (p_string.length > p_length) {
        return p_string.slice(0, p_length - 3) + "...";
    } else {
        return p_string.padEnd(p_length, p_char);
    };
}

async function render_tabs() {
    // this clicks all the section tabs so that their info is available in the DOM.
    function sleep(p_sleep_ms) {
        return new Promise(resolve => setTimeout(resolve, p_sleep_ms));
    };

    $('tabs [pnlId]').triggerEvt('mousedown mouseup', true); // render section info in DOM
    await sleep(2000); // wait for rendering to finish
    $('tabs [pnlId]:first').triggerEvt('mousedown mouseup', true); // setfocus on first section
    console.clear();  // remove array info displayed by this operation.
}


AutoControl support

unread,
Jul 25, 2023, 9:31:33 PM7/25/23
to AutoControl
Thanks for your suggestion and the use case implementation. A global search will be a nice feature to have indeed.

cw noway

unread,
Jul 5, 2024, 11:55:13 AM (16 hours ago) Jul 5
to AutoControl
This is a great script.  I’ve been using it ever since RightClick posted it, and it saves a lot of time finding “Action Names” and “Trigger Names” in the AC Config.


QUESTION for RightClick and AC Support:

How can this script be edited (modified) to find (search for) two additional elements? (see attached pic)

Such as (for example):

1. How can it be edited to search for an actual “Action” such as “Stop Entire Seq,” or “Move/Resize” that is listed under the “Action” section?

2. How can it be edited to search for the name listed as the “Apply to:,” such as “Event Tab?”


Any help would be greatly appreciated

Thanks in advance

RightClick_Search Config_Additional Search Request.png
RightClick_Search Config_Additional Search Request.png

Rightclick

unread,
Jul 5, 2024, 3:40:38 PM (12 hours ago) Jul 5
to AutoControl
Glad you`re finding it useful. I use it all the time and it has made life easier. 

All the script does is a querySelectAll for any element you are looking for, filters it based on the search criteria, then displays the results. So copy an existing function and change the query for the element and you`re 80% of the way there. You will probably have to make some adjustments to get the displayed results to be meaningful.


    const cont_nodes = [...document.querySelectorAll("content > triggers > content > trigger > combinseq > combin > cont")];
    const regex = new RegExp(p_search_expr, "i");
    const filtered_events = cont_nodes.filter(cont => cont.innerText.match(regex));

For instance to find saa would use a query like:
const actionsteps = document.querySelectorAll("body > content > panel > cont >
trigactlist > trigact:nth-child(2) > content > actions >
content > action > actseq > actionstep > l");


and filter it based on its VALUE attribute (rather than its INNERTEXT value)
const filtered_events = actionsteps.filter(actionstep => actionstep.value.match(regex));


That is roughly (untested) how I would do it but I don't have the time to (or need) to test and make the necessary display refinements. Hope that helps and I would appreciate it if you could upload your version once you get it working.
Reply all
Reply to author
Forward
0 new messages