Skip to content

Commit

Permalink
Create toast action setter
Browse files Browse the repository at this point in the history
Additionally, this CL adds support for passing Elements
as action in showToast, using the action setter.
This change is the latest in a series of changes implementing
new behavior added to the toast explainer in PR #43
jackbsteinberg/std-toast#43.

Bug: 972945
Change-Id: I46004883cb3b794981029aa02369918dd0077391
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1686786
Commit-Queue: Jack Steinberg <jacksteinberg@chromium.org>
Reviewed-by: Fergal Daly <fergal@chromium.org>
Cr-Commit-Position: refs/heads/master@{#676482}
  • Loading branch information
Jack Steinberg authored and chromium-wpt-export-bot committed Jul 11, 2019
1 parent 14acac0 commit f7ffd40
Showing 1 changed file with 85 additions and 0 deletions.
85 changes: 85 additions & 0 deletions std-toast/actions.html
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,89 @@

assert_equals(actionButton, null);
}, 'passing non-string (undefined) as action option does not create an action button');

testToastElement((toast) => {
const actionButton = document.createElement('button');
actionButton.textContent = 'action';
toast.action = actionButton;

assertActionButtonOnToast(actionButton, toast);
}, 'setting the action on an actionless toast inserts the element into the slot');

testActionToast((toast, action) => {
const actionButton = document.createElement('button');
actionButton.textContent = 'replacement';
toast.action = actionButton;

assert_false(document.contains(action));
assertActionButtonOnToast(actionButton, toast);
}, 'resetting the action on an action toast changes the action element');

testToastElement((toast) => {
const text = document.createTextNode('some text');
assert_throws(new TypeError(), () => {
toast.action = text;
});
}, 'setting the action to an invalid type (Text node) throws an error');

testToastElement((toast) => {
const text = 'some text';
assert_throws(new TypeError(), () => {
toast.action = text;
});
}, 'setting the action to an invalid type (string) throws an error');

test(() => {
const actionButton = document.createElement('button');
actionButton.textContent = 'action';
const toast = showToast('Message', {action: actionButton});

assertActionButtonOnToast(actionButton, toast);
}, 'showToast can take an Element as the action parameter');

testActionToast((toast, action) => {
toast.action = null;

assert_not_equals(toast.action, action);
assert_equals(toast.querySelector('button'), null);
}, 'setting toast.action to null removes the action from the toast');

testActionToast((toast, action) => {
const wrongAction = document.createElement('button');
wrongAction.textContent = 'wrong';
wrongAction.setAttribute('slot', 'action');
toast.appendChild(wrongAction);

const correctAction = document.createElement('button');
correctAction.textContent = 'correct';
toast.action = correctAction;

assertActionButtonOnToast(correctAction, toast);
}, 'resetting toast.action on a toast with multiple actions slotted sets properly');

test(() => {
try {
Object.defineProperty(Element, Symbol.hasInstance, {
value: () => true,
configurable: true
});

const fakeElement = {};
const toast = showToast('Message');
assert_throws(new TypeError(), () => toast.action = fakeElement);
} finally {
delete Element[Symbol.hasInstance];
}
}, 'spoofing element instance will not register as element to action setter');

test(() => {
const iframe = document.createElement('iframe');
document.body.append(iframe);
iframe.contentDocument.body.innerHTML = '<div></div>';
const elementFromAnotherFrame = iframe.contentDocument.querySelector('div');

// Should not throw:
const toast = showToast('Message');
toast.action = elementFromAnotherFrame;
}, 'element from iframe instance will pass correctly to action without throwing an error');
</script>

0 comments on commit f7ffd40

Please sign in to comment.