Uploaded image for project: 'Cockpit'
  1. Cockpit
  2. COCKPIT-1392

[cockpit-project/cockpit] Replace sizzle with our own contains implementation

XMLWordPrintable

    • Icon: Task Task
    • Resolution: Done
    • Icon: Undefined Undefined
    • None
    • None
    • cockpit
    • 2
    • False
    • Hide

      None

      Show
      None
    • False
    • Testable
    • ?
    • ?
    • rhel-cockpit
    • ?
    • 26Q1 - Jan 7

      [1817946091] Upstream Reporter: Jelle van der Waa
      Upstream issue status: Closed
      Upstream description:

      Cockpit uses sizzle for ph_select the function which selects dom elements, but in reality we only use own special selector from sizzle contains. If we would either stop using contains or write our own contains implementation we can drop sizzle and most of our tests can be normal query selectors which has the benefit of testing them in a browser console.

      Recently we made sizzle optional for tests, so if sizzle is not installed we would not load it. This works nicely for starterkit where sizzle is not required.

      In reality Cockpit and other projects only uses :contains heavily so I tried to only call sizzle when required, this gave a ton of failures https://github.com/cockpit-project/cockpit/pull/18896 which needs to be resolved. Then we can write own our :contains.

      Plan of attack:

      Re-implementating :contains

      We have various uses of :contains the simplest:

      "button:contains(Create new logical volume)"

      The hardest:

      b.wait_js_cond("Number(ph_text('#detail-header dt:contains(Capacity) + dd').split(' ')[0]) >= 96")

      We probably want to re-implement this as following:

      let domElem = document;
      for x in selector.split(":contains") {
            // Handle contains
            domElem.querySelector(x)
      }

      Note: the :contains('xx') + dd case can't be handled this way. So we either can't support that or need to do something different.

      An old attempt, with the wrong approach:

      const containsRe = /(?<elem>.*?)(?<selector>:contains((?<text>[a-zA-Z'"]+)))(?<selectors>:[a-zA-Z-[]()=:]+)?/g;
      
      function ph_select(sel) {
        console.log("ph_select", sel);
        const matches = [...sel.matchAll(containsRe)];
        let elements = [];
        if (matches.length === 0) {
          elements = Array.from(document.querySelectorAll(sel));
        } else {
          // if (matches.length === 1) {
          //   console.log("single", matches);
          //   const containsSelector = matches[0][0];
          //   const text = matches[0][1];
          //   const [mainElem, cssSelectors] = sel.split(containsSelector);
          //   elements = Array.from(document.querySelectorAll(mainElem + cssSelectors)).filter(elem => elem.textContent.indexOf(text) > -1)
          // } else {
          console.log("matches", matches);
          matches.forEach((match, idx) => {
              // console.log(sel, match);
              // const containsSelector = match;
              // const text = match[1];
              // console.log("matches", containsSelector, text);
              // const [mainElem, cssSelectors] = sel.split(containsSelector);
              // console.log(mainElem, cssSelectors);
              const tempSelector = match.groups.elem + (match.groups.selectors || "");
              console.log("selectors", tempSelector);
              console.log(match.groups.text);
              console.log(Array.from(document.querySelectorAll(tempSelector)));
              elements = elements.concat(Array.from(document.querySelectorAll(tempSelector)).filter(
                  elem => elem.textContent.indexOf(match.groups.text) > -1)
              );
          })
        }
      
        return elements;
      }

      Upstream URL: https://github.com/cockpit-project/cockpit/issues/19122

              jvanderw@redhat.com Jelle van der Waa
              upstream-sync Upstream Sync
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Created:
                Updated:
                Resolved: