Skip to content

Commit 72a64fd

Browse files
committed
Add isSubtype
1 parent 24600f7 commit 72a64fd

File tree

4 files changed

+94
-2
lines changed

4 files changed

+94
-2
lines changed

client/src/OnDeviceComponent.spec.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1786,6 +1786,46 @@ describe('OnDeviceComponent', function () {
17861786
});
17871787
});
17881788

1789+
describe('isSubtype', function () {
1790+
it('should return true if self subtype matches by default', async () => {
1791+
const isSubtype = await odc.isSubtype({
1792+
keyPath: '#pagesContainerGroup',
1793+
subtype: 'Group'
1794+
});
1795+
expect(isSubtype).to.be.true;
1796+
});
1797+
1798+
it('should return false if self subtype matches and matchOnSelfSubtype=false', async () => {
1799+
const isSubtype = await odc.isSubtype({
1800+
keyPath: '#pagesContainerGroup',
1801+
matchOnSelfSubtype: false,
1802+
subtype: 'Group'
1803+
});
1804+
expect(isSubtype).to.be.false;
1805+
});
1806+
1807+
it('should return false if subtype does not match', async () => {
1808+
const isSubtype = await odc.isSubtype({
1809+
keyPath: '#pagesContainerGroup',
1810+
subtype: 'RowList'
1811+
});
1812+
expect(isSubtype).to.be.false;
1813+
});
1814+
1815+
it('should throw an error if node does not exist', async () => {
1816+
try {
1817+
await odc.isSubtype({
1818+
keyPath: '#doesNotExist',
1819+
subtype: 'Group'
1820+
});
1821+
} catch (e) {
1822+
// failed as expected
1823+
return;
1824+
}
1825+
assert.fail('Should have thrown an exception');
1826+
});
1827+
});
1828+
17891829
describe('setValue', function () {
17901830
it('should be able to set a key on global', async () => {
17911831
await setAndVerifyValue({

client/src/OnDeviceComponent.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ export class OnDeviceComponent {
605605
return result.json as ODC.ReturnTimeTaken;
606606
}
607607

608-
public async isShowingOnScreen(args: ODC.GetValueArgs, options: ODC.RequestOptions = {}) {
608+
public async isShowingOnScreen(args: ODC.IsShowingOnScreenArgs, options: ODC.RequestOptions = {}) {
609609
this.conditionallyAddDefaultBase(args);
610610
this.conditionallyAddDefaultNodeReferenceKey(args);
611611
const result = await this.sendRequest(ODC.RequestType.isShowingOnScreen, args, options);
@@ -614,6 +614,12 @@ export class OnDeviceComponent {
614614
isFullyShowing: boolean;
615615
};
616616
}
617+
618+
public async isSubtype(args: ODC.IsSubtypeArgs, options: ODC.RequestOptions = {}) {
619+
this.conditionallyAddDefaultBase(args);
620+
const result = await this.sendRequest(ODC.RequestType.isSubtype, {...args, convertResponseToJsonCompatible: false}, options);
621+
return result.json.isSubtype as boolean;
622+
}
617623
//#endregion
618624

619625
//#region requests run on task thread

client/src/types/OnDeviceComponent.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ export enum RequestType {
2424
getVolumeList = 'getVolumeList',
2525
hasFocus = 'hasFocus',
2626
isInFocusChain = 'isInFocusChain',
27+
isSubtype = 'isSubtype',
2728
isShowingOnScreen = 'isShowingOnScreen',
2829
onFieldChangeOnce = 'onFieldChangeOnce',
2930
readFile = 'readFile',
@@ -42,7 +43,7 @@ export enum RequestType {
4243
writeRegistry = 'writeRegistry',
4344
}
4445

45-
export type RequestArgs = CallFuncArgs | CreateChildArgs | GetFocusedNodeArgs | GetValueArgs | GetValuesArgs | HasFocusArgs | IsInFocusChainArgs | OnFieldChangeOnceArgs | SetValueArgs | ReadRegistryArgs | WriteRegistryArgs | DeleteRegistrySectionsArgs | DeleteEntireRegistrySectionsArgs | StoreNodeReferencesArgs | GetNodesInfoArgs | FindNodesAtLocationArgs | CreateDirectoryArgs | DeleteEntireRegistrySectionsArgs | DeleteFileArgs | DeleteNodeReferencesArgs | DisableScreensaverArgs | FocusNodeArgs | GetAllCountArgs | GetDirectoryListingArgs | GetNodesWithPropertiesArgs | GetRootsCountArgs | GetServerHostArgs | GetVolumeListArgs | ReadFileArgs | RenameFileArgs | SetSettingsArgs | StartResponsivenessTestingArgs | StatPathArgs | WriteFileArgs | RemoveNodeArgs |RemoveNodeChildrenArgs | DisableScreensaverArgs;
46+
export type RequestArgs = CallFuncArgs | CreateChildArgs | GetFocusedNodeArgs | GetValueArgs | GetValuesArgs | HasFocusArgs | IsInFocusChainArgs | OnFieldChangeOnceArgs | SetValueArgs | ReadRegistryArgs | WriteRegistryArgs | DeleteRegistrySectionsArgs | DeleteEntireRegistrySectionsArgs | StoreNodeReferencesArgs | GetNodesInfoArgs | FindNodesAtLocationArgs | CreateDirectoryArgs | DeleteEntireRegistrySectionsArgs | DeleteFileArgs | DeleteNodeReferencesArgs | DisableScreensaverArgs | FocusNodeArgs | GetAllCountArgs | GetDirectoryListingArgs | GetNodesWithPropertiesArgs | GetRootsCountArgs | GetServerHostArgs | GetVolumeListArgs | IsShowingOnScreenArgs | IsSubtypeArgs | ReadFileArgs | RenameFileArgs | SetSettingsArgs | StartResponsivenessTestingArgs | StatPathArgs | WriteFileArgs | RemoveNodeArgs |RemoveNodeChildrenArgs | DisableScreensaverArgs;
4647

4748
export enum BaseType {
4849
global = 'global',
@@ -355,6 +356,18 @@ export interface FindNodesAtLocationArgs extends StoreNodeReferencesArgs {
355356
includeBoundingRectInfo?: true;
356357
}
357358

359+
export interface IsShowingOnScreenArgs extends BaseKeyPath {}
360+
361+
export interface IsSubtypeArgs extends BaseKeyPath {
362+
/** The subtype we are checking against */
363+
subtype: string;
364+
365+
/** isSubtype does not normally match the current node's subtype which is usually not the desired behavior.
366+
* Because of this we also will match on the node's own subtype by default.
367+
* Setting this to false will make it match on only a descendant subtype. */
368+
matchOnSelfSubtype?: boolean;
369+
}
370+
358371
interface MatchObject extends BaseKeyPath {
359372
/** If the match value is passed in then the observer will be fired when the field value equals to the value in match */
360373
value: ComparableValueTypes;

device/components/RTA_OnDeviceComponent.brs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ sub init()
2121
"hasFocus": processHasFocusRequest
2222
"isInFocusChain": processIsInFocusChainRequest
2323
"isShowingOnScreen": processIsShowingOnScreenRequest
24+
"isSubtype": processIsSubtypeRequest
2425
"onFieldChangeOnce": processOnFieldChangeOnceRequest
2526
"removeNode": processRemoveNodeRequest
2627
"removeNodeChildren": processRemoveNodeChildrenRequest
@@ -577,6 +578,38 @@ function calculateNodeCount(nodes) as Object
577578
return result
578579
end function
579580

581+
function processIsSubtypeRequest(request) as Object
582+
args = request.args
583+
584+
subtype = args.subtype
585+
if NOT RTA_isString(subtype) then
586+
return RTA_buildErrorResponseObject("Missing valid 'subtype' param")
587+
end if
588+
589+
result = processGetValueRequest(args)
590+
if RTA_isErrorObject(result) then
591+
return result
592+
end if
593+
594+
if result.found <> true then
595+
return RTA_buildErrorResponseObject("No value found at key path '" + RTA_getStringAtKeyPath(args, "keyPath") + "'")
596+
end if
597+
598+
node = result.value
599+
if NOT RTA_isNode(node) then
600+
return RTA_buildErrorResponseObject("Value at key path '" + RTA_getStringAtKeyPath(args, "keyPath") + "' was not a node")
601+
end if
602+
603+
isSubtype = node.isSubtype(subtype)
604+
if NOT isSubtype AND RTA_getBooleanAtKeyPath(args, "matchOnSelfSubtype", true) then
605+
isSubtype = (node.subtype() = subtype)
606+
end if
607+
608+
return {
609+
"isSubtype": isSubtype
610+
}
611+
end function
612+
580613
function processStoreNodeReferencesRequest(request as Object) as Object
581614
args = request.args
582615
nodeRefKey = args.nodeRefKey

0 commit comments

Comments
 (0)