Ver código fonte

Allow blocking redirect in Stimulus Action controller #10035

- If values were false/empty string, it would fall back to the event value
- Instead, ensure that the custom event details OR the param can be used to override this and stop redirection
LB Johnston 1 ano atrás
pai
commit
dd2a21bad1

+ 30 - 0
client/src/controllers/ActionController.test.js

@@ -137,9 +137,39 @@ describe('ActionController', () => {
       select.dispatchEvent(
         new CustomEvent('change', { detail: { url: '/its/in/the/detail/' } }),
       );
+
       expect(window.location.assign).toHaveBeenCalledWith(
         '/check/out/the/param/',
       );
     });
+
+    it('should allow redirection blocking via the event detail', () => {
+      const select = document.querySelector('select');
+
+      expect(window.location.href).toEqual('http://localhost/');
+      expect(window.location.assign).not.toHaveBeenCalled();
+
+      // setting to a non-null/undefined value should allow blocking
+      select.dispatchEvent(new CustomEvent('change', { detail: { url: '' } }));
+      select.dispatchEvent(
+        new CustomEvent('change', { detail: { url: false } }),
+      );
+
+      expect(window.location.assign).not.toHaveBeenCalled();
+    });
+
+    it('should allow redirection blocking via the Stimulus param approach', () => {
+      const select = document.querySelector('select');
+
+      expect(window.location.href).toEqual('http://localhost/');
+      expect(window.location.assign).not.toHaveBeenCalled();
+
+      // setting to a non-null/undefined value should allow blocking
+      select.dataset.wActionUrlParam = '';
+
+      select.dispatchEvent(new CustomEvent('change'));
+
+      expect(window.location.assign).not.toHaveBeenCalled();
+    });
   });
 });

+ 1 - 1
client/src/controllers/ActionController.ts

@@ -87,7 +87,7 @@ export class ActionController extends Controller<
   redirect(
     event: CustomEvent<{ url?: string }> & { params?: { url?: string } },
   ) {
-    const url = event?.params?.url || event?.detail?.url || this.element.value;
+    const url = event?.params?.url ?? event?.detail?.url ?? this.element.value;
     if (!url) return;
     window.location.assign(url);
   }