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
26 changes: 26 additions & 0 deletions code-gen-library/TestsAccessibilityNodeAddAction/Android.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
//begin imports
import com.infragistics.mobile.controls.IgaAccessibilityNodeCreatingEventArgs;
import com.infragistics.mobile.controls.IgaAccessibilityAction;
import com.infragistics.mobile.controls.IgaAccessibilityActionCollection;
import com.infragistics.mobile.controls.IgaAccessibilityRole;
//end imports

public class TestsAccessibilityNodeAddAction {
//begin eventHandler
public fun testsAccessibilityNodeAddAction(sender: Any?, args: IgaAccessibilityNodeCreatingEventArgs) {
var node = args.node;
if (node != null && node.role == IgaAccessibilityRole.ITEM) {
// Assign the collection first, then add to it through the property.
// The wrapper's getter lazily builds a collection that reads from the
// implementation but carries no sync target, so items added through it
// never reach the implementation; only the setter wires that
// write-through. It also means the null check the other platforms make
// would never fire here -- this getter does not return null.
node.actions = IgaAccessibilityActionCollection();
var action = IgaAccessibilityAction();
action.name = "Activate";
node.actions!!.add(action);
}
}
//end eventHandler
}
23 changes: 23 additions & 0 deletions code-gen-library/TestsAccessibilityNodeAddAction/Desktop.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//begin imports
using Infragistics.Controls;
using Infragistics.Controls.Charts;
//end imports

public class TestsAccessibilityNodeAddAction
{

//begin eventHandler
//WPF: Infragistics.Controls.Charts.AccessibilityNodeCreatingEventHandler
public void TestsAccessibilityNodeAddAction(object sender, AccessibilityNodeCreatingEventArgs args)
{
if (args.Node != null && args.Node.Role == AccessibilityRole.Item)
{
if (args.Node.Actions == null)
{
args.Node.Actions = new AccessibilityActionCollection();
}
args.Node.Actions.Add(new AccessibilityAction() { Name = "Activate" });
}
}
//end eventHandler
}
16 changes: 16 additions & 0 deletions code-gen-library/TestsAccessibilityNodeCancelAuto/Android.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//begin imports
import com.infragistics.mobile.controls.IgaAccessibilityNodeCreatingEventArgs;
import com.infragistics.mobile.controls.IgaAccessibilityRole;
//end imports

public class TestsAccessibilityNodeCancelAuto {
//begin eventHandler
public fun testsAccessibilityNodeCancelAuto(sender: Any?, args: IgaAccessibilityNodeCreatingEventArgs) {
var node = args.node;
if (node != null && node.role == IgaAccessibilityRole.ITEM) {
node.descriptionText = "";
args.cancelAuto = true;
}
}
//end eventHandler
}
20 changes: 20 additions & 0 deletions code-gen-library/TestsAccessibilityNodeCancelAuto/Desktop.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
//begin imports
using Infragistics.Controls;
using Infragistics.Controls.Charts;
//end imports

public class TestsAccessibilityNodeCancelAuto
{

//begin eventHandler
//WPF: Infragistics.Controls.Charts.AccessibilityNodeCreatingEventHandler
public void TestsAccessibilityNodeCancelAuto(object sender, AccessibilityNodeCreatingEventArgs args)
{
if (args.Node != null && args.Node.Role == AccessibilityRole.Item)
{
args.Node.DescriptionText = "";
args.CancelAuto = true;
}
}
//end eventHandler
}
2 changes: 1 addition & 1 deletion code-gen-library/TestsAccessibilityNodeCancelAuto/GTK.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public void TestsAccessibilityNodeCancelAuto(object sender, AccessibilityNodeCre
{
if (args.Node != null && args.Node.Role == AccessibilityRole.Item)
{
args.Node.Description = "";
args.Node.DescriptionText = "";
args.CancelAuto = true;
}
}
Expand Down
2 changes: 1 addition & 1 deletion code-gen-library/TestsAccessibilityNodeCancelAuto/Web.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export class TestsAccessibilityNodeCancelAuto {
//begin eventHandler
public testsAccessibilityNodeCancelAuto(sender: any, args: IgcAccessibilityNodeCreatingEventArgs): void {
if (args.node != null && args.node.role == AccessibilityRole.Item) {
args.node.description = "";
args.node.descriptionText = "";
args.cancelAuto = true;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//begin imports
import com.infragistics.mobile.controls.IgaAccessibilityNodeCreatingEventArgs;
import com.infragistics.mobile.controls.IgaAccessibilityRole;
//end imports

public class TestsAccessibilityNodeOverrideDescription {
//begin eventHandler
public fun testsAccessibilityNodeOverrideDescription(sender: Any?, args: IgaAccessibilityNodeCreatingEventArgs) {
var node = args.node;
if (node != null && node.role == IgaAccessibilityRole.ITEM) {
node.descriptionText = "custom override";
}
}
//end eventHandler
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
//begin imports
using Infragistics.Controls;
using Infragistics.Controls.Charts;
//end imports

public class TestsAccessibilityNodeOverrideDescription
{

//begin eventHandler
//WPF: Infragistics.Controls.Charts.AccessibilityNodeCreatingEventHandler
public void TestsAccessibilityNodeOverrideDescription(object sender, AccessibilityNodeCreatingEventArgs args)
{
if (args.Node != null && args.Node.Role == AccessibilityRole.Item)
{
args.Node.DescriptionText = "custom override";
}
}
//end eventHandler
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public void TestsAccessibilityNodeOverrideDescription(object sender, Accessibili
{
if (args.Node != null && args.Node.Role == AccessibilityRole.Item)
{
args.Node.Description = "custom override";
args.Node.DescriptionText = "custom override";
}
}
//end eventHandler
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export class TestsAccessibilityNodeOverrideDescription {
//begin eventHandler
public testsAccessibilityNodeOverrideDescription(sender: any, args: IgcAccessibilityNodeCreatingEventArgs): void {
if (args.node != null && args.node.role == AccessibilityRole.Item) {
args.node.description = "custom override";
args.node.descriptionText = "custom override";
}
}
//end eventHandler
Expand Down
35 changes: 17 additions & 18 deletions tooling/src/codegen-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1105,8 +1105,7 @@ export function emitLibrary(platformName: string, opts: {

const templateDir = itemTemplateDirFor(platformName, opts.templatesRoot);
const library: any = libraryFor(opts.examplesRoot);
const names: string[] = (opts.only ?? (library.getItemNames?.() ?? library.getKeys()))
.filter((name: string) => !isAccessibilityLibraryItem(name));
const names: string[] = opts.only ?? (library.getItemNames?.() ?? library.getKeys());

// A renderer per item, sharing one registered context — which is what the library project
// emitter does, and not an optimisation. An emitter keeps state across an emission: the set of
Expand Down Expand Up @@ -1156,7 +1155,7 @@ export function emitLibrary(platformName: string, opts: {
const requires: string[] | null = item.getRequiresForPlatform(platform);
if (requires !== null && requires !== undefined) {
for (const required of requires) {
if (isAccessibilityLibraryItem(required) || seen.has(required) || !library.hasItem(required)) continue;
if (seen.has(required) || !library.hasItem(required)) continue;
seen.add(required);
queue.push(required);
}
Expand Down Expand Up @@ -1260,12 +1259,13 @@ function emitBlazorLibrary(platform: any, opts: {
if (!fs.existsSync(templateDir)) throw new Error(`no blazor-template found at ${templateDir}`);
const excluded = new Set(opts.exclude ?? []);
const names: string[] = (opts.only ?? (library.getItemNames?.() ?? library.getKeys()))
.filter((name: string) => !excluded.has(name) && !isAccessibilityLibraryItem(name));
.filter((name: string) => !excluded.has(name));
const queue = [...names];
const seen = new Set(names);
const files: Record<string, string> = {};
const problems: { item: string; reason: string }[] = [];
const tracked: { name: string; access?: string; script?: boolean }[] = [];
let needsBlazorNamespace = false;
let dataItems = 0;
let handlerItems = 0;
let context: any = null;
Expand All @@ -1286,8 +1286,7 @@ function emitBlazorLibrary(platform: any, opts: {
const item: any = library.getItem(name);
const requires: string[] | null = item.getRequiresForPlatform(platform);
for (const required of requires ?? []) {
if (!excluded.has(required) && !isAccessibilityLibraryItem(required) &&
!seen.has(required) && library.hasItem(required)) {
if (!excluded.has(required) && !seen.has(required) && library.hasItem(required)) {
seen.add(required); queue.push(required);
}
}
Expand Down Expand Up @@ -1333,6 +1332,7 @@ function emitBlazorLibrary(platform: any, opts: {
const source = emitted[`${stem}.razor`];
if (source === undefined) { problems.push({ item: name, reason: "no Razor source emitted" }); continue; }
files[`${name}Holder.razor`] = source.split("PlaceholderHolder").join(`${name}Holder`);
needsBlazorNamespace = true;
tracked.push({ name, access: `new Tuple<Func<object>, Func<object>>(() => new ${name}Holder(), () => new ${name}Holder().${name})` });
}
const css = emitted[`${stem}.css`];
Expand All @@ -1341,7 +1341,14 @@ function emitBlazorLibrary(platform: any, opts: {
}

files["BlazorLibrary.csproj"] = fs.readFileSync(path.join(templateDir, "BlazorLibrary.csproj"), "utf8");
return { files, manager: dotNetManagerFor(tracked, "BlazorLibrary"), managerFile: "LibraryManager.cs", problems, dataItems, handlerItems };
return {
files,
manager: dotNetManagerFor(tracked, needsBlazorNamespace ? "BlazorLibrary" : undefined),
managerFile: "LibraryManager.cs",
problems,
dataItems,
handlerItems,
};
}

function emitNativeXamlLibrary(platformName: "WinUI" | "Uno", platform: any, opts: {
Expand All @@ -1352,8 +1359,7 @@ function emitNativeXamlLibrary(platformName: "WinUI" | "Uno", platform: any, opt
}, library: any): EmittedLibrary {
const templateDir = path.join(opts.templatesRoot ?? "", "winui-template");
if (!fs.existsSync(templateDir)) throw new Error(`no winui-template found at ${templateDir}`);
const names: string[] = (opts.only ?? (library.getItemNames?.() ?? library.getKeys()))
.filter((name: string) => !isAccessibilityLibraryItem(name));
const names: string[] = opts.only ?? (library.getItemNames?.() ?? library.getKeys());
const queue = [...names];
const seen = new Set(names);
const files: Record<string, string> = {};
Expand Down Expand Up @@ -1389,9 +1395,7 @@ function emitNativeXamlLibrary(platformName: "WinUI" | "Uno", platform: any, opt
const item: any = library.getItem(name);
const requires: string[] | null = item.getRequiresForPlatform(platform);
for (const required of requires ?? []) {
if (!isAccessibilityLibraryItem(required) && !seen.has(required) && library.hasItem(required)) {
seen.add(required); queue.push(required);
}
if (!seen.has(required) && library.hasItem(required)) { seen.add(required); queue.push(required); }
}
const content = contentFor(item);
if (content === null || content === undefined) continue;
Expand Down Expand Up @@ -1504,17 +1508,12 @@ function enqueueSiblings(content: string, library: any, seen: Set<string>, queue
let match: RegExpExecArray | null;
while ((match = pattern.exec(content)) !== null) {
const name = match[1];
if (name === "libraryManager" || isAccessibilityLibraryItem(name) ||
seen.has(name) || !library.hasItem(name)) continue;
if (name === "libraryManager" || seen.has(name) || !library.hasItem(name)) continue;
seen.add(name);
queue.push(name);
}
}

function isAccessibilityLibraryItem(name: string): boolean {
return name.startsWith("Accessibility") || name.startsWith("TestsAccessibility");
}

/** Where the per-item templates live: the library project emitter's own copy of them. */
function itemTemplateDirFor(platformName: string, templatesRoot?: string): string {
const folder = platformName === "WebComponents" ? "webcomponents-template"
Expand Down
32 changes: 15 additions & 17 deletions tooling/test/tooling.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
const CLI = path.join(ROOT, 'src', 'cli.mjs');
const require = createRequire(import.meta.url);
require('../src/dom-shim.cjs');
const { emitLibrary, emitProject } = require('../dist/codegen-api.cjs');
const { emitProject } = require('../dist/codegen-api.cjs');

test('maps emitted folder diffs back to added, modified, and removed samples', () => {
const workspace = fs.mkdtempSync(path.join(os.tmpdir(), 'xplat-impact-test-'));
Expand Down Expand Up @@ -465,22 +465,6 @@ test('emits and type-compiles a library item on every hosted web platform', () =
}
});

test('temporarily skips accessibility items during library emission', () => {
for (const platform of ['Angular', 'React', 'WebComponents', 'Blazor', 'WinUI', 'Uno']) {
const emitted = emitLibrary(platform, {
examplesRoot: path.resolve(ROOT, '..'),
templatesRoot: path.join(ROOT, 'library-templates'),
only: ['SalesData', 'AccessibilityFutureItem', 'TestsAccessibilityNodeAddAction'],
});

assert.deepEqual(emitted.problems, []);
assert.equal(Object.keys(emitted.files)
.some(name => name.startsWith('TestsAccessibilityNodeAddAction')), false);
assert.doesNotMatch(emitted.manager, /TestsAccessibilityNodeAddAction/);
assert.ok(emitted.files[`SalesData.${['Angular', 'React', 'WebComponents'].includes(platform) ? 'ts' : 'cs'}`]);
}
});

test('emits a Blazor Razor library with data, handlers, manager, and project', () => {
const output = fs.mkdtempSync(path.join(os.tmpdir(), 'xplat-blazor-library-test-'));
try {
Expand All @@ -501,6 +485,20 @@ test('emits a Blazor Razor library with data, handlers, manager, and project', (
}
});

test('emits a Blazor data-only library manager without importing Blazor holder namespace', () => {
const output = fs.mkdtempSync(path.join(os.tmpdir(), 'xplat-blazor-data-only-library-test-'));
try {
execFileSync(process.execPath, [
CLI, 'library', '--platform=Blazor',
'--only=SalesData',
`--output=${output}`, '--clean',
], { cwd: ROOT, stdio: 'pipe' });
assert.doesNotMatch(fs.readFileSync(path.join(output, 'LibraryManager.cs'), 'utf8'), /using BlazorLibrary;/);
} finally {
fs.rmSync(output, { recursive: true, force: true });
}
});

test('emits WinUI and Uno libraries through the native product renderers', () => {
for (const platform of ['WinUI', 'Uno']) {
const output = fs.mkdtempSync(path.join(os.tmpdir(), `xplat-${platform.toLowerCase()}-library-test-`));
Expand Down
Loading