Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions packages/main/cypress/specs/Tokenizer.cy.tsx
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can add test for the case when we have selected tokens and focused is not from the selected ones so its clear what should happen. I'm not sure that "should cut multiple selected tokens when Ctrl+X is pressed" is enough to clarify that.

Original file line number Diff line number Diff line change
Expand Up @@ -1824,6 +1824,52 @@ describe("Clipboard Operations", () => {
// Only the selected token should be copied
cy.get("@clipboardWrite").should("have.been.calledOnceWith", "Selected");
});

it("should copy focused token text when no tokens are selected", () => {
cy.mount(
<Tokenizer>
<Token text="Focused"></Token>
<Token text="Other"></Token>
</Tokenizer>
);

// Tab into the tokenizer to focus the first token without selecting it
cy.realPress("Tab");
cy.get("[ui5-token]").eq(0).should("have.prop", "focused", true);
cy.get("[ui5-token]").eq(0).should("have.prop", "selected", false);

cy.window().then((win) => {
cy.stub(win.navigator.clipboard, "writeText").as("clipboardWrite");
Object.defineProperty(win, "isSecureContext", { value: true, writable: true });
});

cy.realPress(["Control", "c"]);

cy.get("@clipboardWrite").should("have.been.calledOnceWith", "Focused");
});

it("should not cut token in readonly mode", () => {
cy.mount(
<Tokenizer readonly={true}>
<Token text="ReadonlyToken"></Token>
<Token text="Other"></Token>
</Tokenizer>
);

cy.realPress("Tab");
cy.get("[ui5-token]").eq(0).should("have.prop", "focused", true);

cy.window().then((win) => {
cy.stub(win.navigator.clipboard, "writeText").as("clipboardWrite");
Object.defineProperty(win, "isSecureContext", { value: true, writable: true });
});

cy.realPress(["Control", "x"]);

// Should copy but not delete in readonly mode
cy.get("@clipboardWrite").should("have.been.calledOnceWith", "ReadonlyToken");
cy.get("[ui5-token]").should("have.length", 2);
});
});

describe("Tokenizer - getFocusDomRef Method", () => {
Expand Down
12 changes: 8 additions & 4 deletions packages/main/src/Tokenizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -720,10 +720,14 @@ class Tokenizer extends UI5Element implements IFormInputElement {
e.preventDefault();

const isCut = e.key.toLowerCase() === "x" || isDeleteShift(e);
const selectedTokens = this._tokens.filter(token => token.selected);
const focusedToken = selectedTokens.find(token => token.focused);
let selectedTokens = this._tokens.filter(token => token.selected);
const focusedToken = this._tokens.find(token => token.focused);

if (isCut) {
if (!selectedTokens.length && focusedToken) {
selectedTokens = [focusedToken];
}

if (isCut && !this.readonly) {
const cutResult = this._fillClipboard(ClipboardDataOperation.cut, selectedTokens);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the sample we can see the token is deleted before the clipboard is filled.

Actually I tried how it worked before and it was buggy anyway -> if we have selected and focused token -> CUT -> it deletes without filling the clipboard, in the same time if selected token is not the focused, CUT does nothing. We can discuss it.


focusedToken && this.deleteToken(focusedToken);
Expand Down Expand Up @@ -1079,7 +1083,7 @@ class Tokenizer extends UI5Element implements IFormInputElement {
}

_fillClipboard(shortcutName: ClipboardDataOperation, tokens: Array<IToken>) {
const tokensTexts = tokens.filter(token => token.selected).map(token => token.text).join("\r\n");
const tokensTexts = tokens.map(token => token.text).join("\r\n");

// Async clipboard API (works in secure contexts - HTTPS/localhost)
if (navigator.clipboard?.writeText && window.isSecureContext) {
Expand Down
Loading