import { ApproxStructure, Assertions, Logger, Mouse, Pipeline, Step } from '@ephox/agar'; import { UnitTest } from '@ephox/bedrock-client'; import { Optional } from '@ephox/katamari'; import { type EventArgs, Html, Insert, Remove, SugarBody, SugarElement, SugarNode, Traverse } from '@ephox/sugar'; import * as Behaviour from 'ephox/alloy/api/behaviour/Behaviour'; import { Toggling } from 'ephox/alloy/api/behaviour/Toggling'; import * as AlloyEvents from 'ephox/alloy/api/events/AlloyEvents'; import * as NativeEvents from 'ephox/alloy/api/events/NativeEvents'; import * as SystemEvents from 'ephox/alloy/api/events/SystemEvents'; import * as ForeignGui from 'ephox/alloy/api/system/ForeignGui'; import * as Tagger from 'ephox/alloy/registry/Tagger'; import * as GuiSetup from 'ephox/alloy/test/GuiSetup'; UnitTest.asynctest('Browser Test: api.ForeignGuiTest', (success, failure) => { const root = SugarElement.fromTag('div'); Html.set(root, 'A and B'); Insert.append(SugarBody.body(), root); const connection = ForeignGui.engage({ root, insertion: (parent, system) => { Insert.append(parent, system.element); }, dispatchers: [ { getTarget: (elem) => SugarNode.name(elem) === 'span' ? Optional.some(elem) : Optional.none(), alloyConfig: { behaviours: Behaviour.derive([ Toggling.config({ toggleClass: 'selected' }) ]), events: AlloyEvents.derive([ AlloyEvents.run(NativeEvents.click(), (component, simulatedEvent) => { // We have to remove the proxy first, because we are during a proxied event (click) connection.unproxy(component); connection.dispatchTo(SystemEvents.execute(), simulatedEvent.event); }) ]) } } ] }); const sAssertChildHasRandomUid = (label: string, index: number) => Logger.t( label, Step.sync(() => { const child = Traverse.child(root, index).getOrDie('Could not find child at index: ' + index); const alloyUid = Tagger.readOrDie(child); Assertions.assertEq('Uid should have been initialised', true, alloyUid.startsWith('uid_')); }) ); const sAssertChildHasNoUid = (label: string, index: number) => Logger.t( label, Step.sync(() => { const child = Traverse.child(root, index).getOrDie('Could not find child at index: ' + index); const optUid = Tagger.read(child); Assertions.assertEq('Uid should NOT be set', true, optUid.isNone()); }) ); Pipeline.async({}, [ GuiSetup.mAddStyles(SugarElement.fromDom(document), [ '.selected { color: white; background: black; }' ]), Assertions.sAssertStructure( 'Checking initial structure ... nothing is selected', ApproxStructure.build((s, str, arr) => s.element('div', { children: [ s.element('span', { classes: [ arr.not('selected') ] }), s.text(str.is(' and ')), s.element('span', { classes: [ arr.not('selected') ] }), s.element('div', { // TODO: Test that the field is set. attrs: { 'data-alloy-id': str.none() } }) ] })), root ), sAssertChildHasNoUid('First child should have no uid', 0), sAssertChildHasRandomUid('Div should have a uid', 3), Mouse.sClickOn(root, 'span.clicker:first-child'), Assertions.sAssertStructure( 'Checking structure after the first span is clicked', ApproxStructure.build((s, str, arr) => s.element('div', { children: [ s.element('span', { attrs: { 'data-alloy-id': str.none() }, classes: [ arr.has('selected') ] }), s.text(str.is(' and ')), s.element('span', { classes: [ arr.not('selected') ] }), s.element('div', { attrs: { 'data-alloy-id': str.none() } }) ] })), root ), sAssertChildHasNoUid('First child should still have no uid', 0), sAssertChildHasRandomUid('Div should still have a uid', 3), Step.sync(() => { connection.disengage(); Remove.remove(root); }) ], success, failure); });