Copilot commented on code in PR #496:
URL: https://github.com/apache/hugegraph-doc/pull/496#discussion_r4080459550


##########
.github/workflows/hugo.yml:
##########
@@ -358,12 +346,12 @@ jobs:
       - name: Run blocking Chromium contracts
         working-directory: tests/e2e
         env:
-          SITE_ROOT: ${{ github.workspace }}/public-site
+          SITE_ROOT: ${{ runner.temp }}/public-site
           AI_SITE_ROOT: ${{ runner.temp }}/ai-site
           EXPECTED_VERSIONS: ${{ needs.prepare.outputs.selection }}
         run: npm run test:ci
       - name: Upload E2E report
-        if: always()
+        if: ${{ !cancelled() }}

Review Comment:
   Switching from `if: always()` to `if: ${{ !cancelled() }}` means these 
upload steps will be skipped on test failures (because step defaults to 
`success()` after a failing `npm run test:ci` / `npm run test:visual`). That 
reduces diagnostics exactly when they’re most needed. If the intent is 'upload 
on success or failure, but not when cancelled', use a condition equivalent to 
`always() && !cancelled()` so reports still upload on failures while superseded 
runs avoid wasting time.



##########
.github/workflows/hugo.yml:
##########
@@ -402,7 +390,7 @@ jobs:
           npx playwright install --with-deps chromium
           npm run test:visual
       - name: Upload advisory visual evidence
-        if: always()
+        if: ${{ !cancelled() }}

Review Comment:
   Switching from `if: always()` to `if: ${{ !cancelled() }}` means these 
upload steps will be skipped on test failures (because step defaults to 
`success()` after a failing `npm run test:ci` / `npm run test:visual`). That 
reduces diagnostics exactly when they’re most needed. If the intent is 'upload 
on success or failure, but not when cancelled', use a condition equivalent to 
`always() && !cancelled()` so reports still upload on failures while superseded 
runs avoid wasting time.



##########
assets/js/kapa-adapter.js:
##########
@@ -244,23 +256,49 @@
       renderState('idle', '');
       if (consent && consent.open) consent.close();
       restoreFocus();
+      settle();
     }
 
-    function activate(query, submit, trigger) {
+    function activate(query, submit, trigger, context) {
       if (state === 'loading' || state === 'consent') return;
+      if (context && context.signal.aborted) return Promise.resolve();
       lastTrigger = trigger || documentObject.activeElement;
+      var completion;

Review Comment:
   `activate()` can return `undefined` when invoked while `state` is 
`'loading'`/`'consent'`. With the new `registerSearchTail` integration, callers 
may rely on a returned Promise to track completion/cancellation; returning 
`undefined` breaks that contract and can lead to missed cancellation/focus 
handoff semantics. Consider always returning a Promise when `context` is 
provided (e.g., return the in-flight operation's completion, or 
`Promise.resolve()`), and ensure repeated activations during consent/loading 
deterministically settle without starting a second operation.



##########
assets/js/kapa-adapter.js:
##########
@@ -306,119 +344,32 @@
     var config = readConfig(documentObject);
     if (!config) return null;
     var controller = createController(windowObject, documentObject, config);
-    var root = documentObject.getElementById('td-shell-search');
-    var input = root && root.querySelector('.td-shell-search__input');
-    var list = root && root.querySelector('.td-shell-search__list');
-    var syncing = false;
-
-    function bind(button) {
+    documentObject.querySelectorAll('[data-hg-ask-ai]').forEach(function 
(button) {
       if (button.dataset.hgAiBound !== undefined) return;
       button.dataset.hgAiBound = '';
       button.addEventListener('click', function () {
-        controller.activate(
-          button.dataset.hgAiQuery || '',
-          button.dataset.hgAiSubmit === 'true',
-          button,
-        );
+        controller.activate('', false, button);
       });
-    }
-    documentObject.querySelectorAll('[data-hg-ask-ai]').forEach(bind);
-
-    if (!input || !list) return controller;
+    });
 
-    // Keep the OINK palette untouched: only intercept Enter when local search
-    // is empty and the site-owned Ask AI tail is the available follow-up.
-    input.addEventListener('keydown', function (event) {
-      if (event.isComposing || event.keyCode === 229 || event.key !== 'Enter') 
return;
-      var empty = list.querySelector('.td-shell-search__empty');
-      var localRow = 
list.querySelector('.td-shell-search__item:not(.hg-ai-search-tail__button)');
-      var tailButton = list.querySelector('[data-hg-ai-search-tail] 
[data-hg-ask-ai]');
-      if (!empty || localRow || !tailButton) return;
-      event.preventDefault();
-      event.stopImmediatePropagation();
-      controller.activate(input.value, true, tailButton);
-    }, true);
-
-    function syncTail() {
-      syncing = false;
-      if (!root || !input || !list || root.hidden) return;
-      var old = list.querySelector('[data-hg-ai-search-tail]');
-      var query = trimmedQuery(input.value);
-      if (!query || query.charAt(0) === '>') {
-        if (old) old.remove();
-        return;
-      }
-      var choiceLabel = root.dataset.tdTChoice || '';
-      if (
-        choiceLabel &&
-        Array.prototype.some.call(
-          list.querySelectorAll('.td-shell-search__group-label'),
-          function (label) { return label.textContent.trim() === choiceLabel; 
},
-        )
-      ) {
-        if (old) old.remove();
-        return;
-      }
-      var loading = root.dataset.tdTLoading || '';
-      if (
-        loading &&
-        Array.prototype.some.call(
-          list.querySelectorAll('.td-shell-search__empty'),
-          function (node) { return node.textContent.trim() === loading; },
-        )
-      ) {
-        if (old) old.remove();
-        return;
-      }
-      var empty = list.querySelector('.td-shell-search__empty');
-      if (empty && config.labels.noResults) empty.textContent = 
config.labels.noResults;
-      var oldButton = old && old.querySelector('[data-hg-ask-ai]');
-      if (oldButton && oldButton.dataset.hgAiQuery === query) return;
-      if (old) old.remove();
-
-      var group = documentObject.createElement('div');
-      group.className = 'td-shell-search__group hg-ai-search-tail';
-      group.dataset.hgAiSearchTail = '';
-      group.setAttribute('role', 'group');
-      var label = documentObject.createElement('div');
-      label.className = 'td-shell-search__group-label';
-      label.textContent = config.labels.ask;
-      var row = documentObject.createElement('button');
-      row.type = 'button';
-      row.className = 'td-shell-search__item hg-ai-search-tail__button';
-      row.dataset.hgAskAi = '';
-      row.dataset.hgAiQuery = query;
-      row.dataset.hgAiSubmit = 'true';
-      var icon = documentObject.createElement('i');
-      icon.className =
-        'fa-solid fa-wand-magic-sparkles td-shell-search__item-icon';
-      icon.setAttribute('aria-hidden', 'true');
-      var meta = documentObject.createElement('span');
-      meta.className = 'td-shell-search__item-meta';
-      var title = documentObject.createElement('span');
-      title.className = 'td-shell-search__item-title';
-      title.textContent = config.labels.ask + ': “' + query + '”';
-      var detail = documentObject.createElement('span');
-      detail.className = 'td-shell-search__item-ref';
-      detail.textContent = config.historical ? config.labels.latest + '.' : '';
-      meta.appendChild(title);
-      meta.appendChild(detail);
-      row.appendChild(icon);
-      row.appendChild(meta);
-      group.appendChild(label);
-      group.appendChild(row);
-      list.appendChild(group);
-      bind(row);
-    }
-
-    if (list) {
-      new MutationObserver(function () {
-        if (syncing) return;
-        syncing = true;
-        windowObject.requestAnimationFrame(syncTail);
-      }).observe(list, { childList: true, subtree: true });
-      input.addEventListener('input', syncTail);
-      syncTail();
+    var palette = windowObject.OinkCommandPalette;
+    if (palette && typeof palette.registerSearchTail === 'function') {
+      palette.registerSearchTail({
+        id: 'hugegraph-ai',
+        rows: function (context) {
+          return [{
+            id: 'ask',
+            title: config.labels.ask + ': “' + context.query + '”',
+            description: config.historical ? config.labels.latest + '.' : '',
+            icon: 'fa-solid fa-wand-magic-sparkles',
+          }];
+        },

Review Comment:
   The previous implementation suppressed the Ask AI tail for empty queries and 
command-prefixed queries (e.g., `>...`). With the native tail API, this 
`rows()` implementation always returns a row, which risks reintroducing 
undesired rows if OINK calls the extension for empty/command queries now or in 
a future theme update. Consider defensively mirroring the old eligibility 
checks (trimmed query non-empty and not starting with `>`), returning an empty 
list when the tail should be hidden.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to