-
Notifications
You must be signed in to change notification settings - Fork 10
Feature/api definitions #171
base: master
Are you sure you want to change the base?
Changes from all commits
601c6f1
9d2df4c
c5ec81d
618fff7
05996d3
692cffe
dc3e0ec
3499feb
ec42429
336f251
4ef36d0
79ce8b6
017c641
5e6e4cd
ca5ae28
24c1dc7
397ab4f
a1c780d
98491cd
96bd363
8c17293
2da0091
9203533
f603530
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -76,3 +76,6 @@ build/ | |
|
||
# Visual Studio Code | ||
.vscode | ||
|
||
|
||
.idea/ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
export interface ApplicationAPI { | ||
/** | ||
* Returns an array containing the command line arguments passed when application was launched | ||
*/ | ||
argv: string[]; | ||
|
||
/** | ||
* Application configuration object (as defined in app.json file) | ||
*/ | ||
config: ApplicationConfig; | ||
|
||
/** | ||
* The current value displayed in the counter badge. | ||
*/ | ||
getBadgeCount(): number; | ||
|
||
/** | ||
* Sets the counter badge for current app. Setting the count to 0 will hide the badge. | ||
*/ | ||
setBadgeCount(count: number); | ||
|
||
/** | ||
* Shutdown the application | ||
*/ | ||
shutdown: () => void; | ||
} | ||
|
||
export interface ApplicationConfig { | ||
name: string; | ||
url: string; | ||
uuid: string; | ||
autoShow: boolean; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
// contains common types | ||
export interface Bounds { | ||
top: number; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In Electron, |
||
left: number; | ||
width: number; | ||
height: number; | ||
} | ||
|
||
export interface Size{ | ||
width: number; | ||
height: number; | ||
} | ||
|
||
/** | ||
* Function returned from event subscription functions (e.g. onWindowBoundsChanged). | ||
* Executing it will remove the event handler. | ||
*/ | ||
export interface UnsubscribeFunction { | ||
(): void; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
## [Activate API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/Activate+API) | ||
|
||
> This api allows a window to be move to the front and given focus. This API is needed since JS web apps have no capability to perform such a function. | ||
> An example use case might be: the main window might be minimized (or otherwise hidden) and the notification shows that the user then clicks on. The web app needs to ability to bring the window to the foreground and give focus. | ||
|
||
The API proposal introduces window management section that enables the user to create, discover and manage windows. | ||
It also defines a window object that has a set of properties and methods. | ||
|
||
One of these methods is activate that will bring the window to front and focus it: | ||
```javascript | ||
// activate my window | ||
var myWindow = ssf.windows.current; | ||
myWindow.activate(); | ||
|
||
// activate some other window | ||
var someWindow = ssf.windows.getById('4'); | ||
someWindow.activate(); | ||
``` | ||
|
||
## [RegisterBoundsChange API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/RegisterBoundsChange+API) | ||
> This API allows JS web app to register a callback that will be notified whenever any child window's size or position changes. The primary motivation is to support a feature called "saved layout". This feature allows the symphony web app to save the size and location of child windows and restore them when the app is restarted (or refreshed). | ||
|
||
Using the windows API the application can subscribe for | ||
```javascript | ||
ssf.windows.onWindowBoundsChanged(function(window, bounds){ | ||
|
||
}) | ||
``` | ||
|
||
or subscribe for each window individually | ||
```javascript | ||
someWindow.on('boundsChanged', function(bounds){ | ||
|
||
}); | ||
``` | ||
|
||
or iterate the windows when the layout should be saved | ||
```javascript | ||
ssf.windows.all.forEach(function(window){ | ||
var boundsToSave = window.getBounds(); | ||
}); | ||
``` | ||
## [Activity API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/Activity+API) | ||
> The application needs to be informed if activity (keyboard or mouse input) has occurred. | ||
|
||
Another section in the proposal is system API that allows the application to access system specific stuff. | ||
|
||
The application can subscribe for user activity events: | ||
```javascript | ||
ssf.system.onUserActivity(function(){ | ||
|
||
}, 1000); | ||
``` | ||
|
||
## [getMediaSources API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/getMediaSources+API) and [ScreenSnippet API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/ScreenSnippet+API) | ||
> In order to support screen sharing the client api needs enumerate screens and windows. | ||
> This api provided a list of screens (each monitor) and list of windows available; providing title, id and thumbnail. This api is essentially equivalent of electron api: https://electron.atom.io/docs/api/desktop-capturer/#desktopcapturergetsourcesoptions-callback | ||
|
||
> The ScreenSnippet API is used to capture a snippet of their desktop (unconstrained by the host application window) and highlight portions of this snippet so it can then be consumed by the host application. This functionality is similar to the Windows Screen Snippet tool when used in rectangle capture mode. This lets a user captures portions of the Windows Desktop, highlight aspects of the image and then save this image for sharing. | ||
Using the system API the user can enumerate the displays and capture any of them | ||
```javascript | ||
// capture all screens | ||
ssf.system.capture().then(function(image){ | ||
|
||
}); | ||
|
||
// capture each screen as separate image | ||
ssf.system.captureAllDisplays().then(function(images) { | ||
|
||
}); | ||
|
||
// capture specific display only | ||
ssf.system.displays[0].capture(); | ||
|
||
// Capture all windows as separate images with custom size | ||
ssf.system.captureAllWindows({imageSize: {width: 100, height: 100}}) | ||
.then(function(images){ | ||
|
||
}); | ||
|
||
// Capture specific window (this goes throught the window API) | ||
var window = ssf.windows.current; | ||
window.capture(); | ||
``` | ||
|
||
## [BadgeCount API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/BadgeCount+API) | ||
> Display a number on the application icon in the desktop tray... usually to indicate number of unread messages for given application. | ||
|
||
There is application section that provides information about application config and allows | ||
interactions with app specific functionalities like badgeCounts | ||
|
||
```javascript | ||
ssf.application.setBadgeCount(11); | ||
``` | ||
## [Notification API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/Notification+API) | ||
>The Notifications API is used to configure and display desktop notifications to the user. It is exposed as an extension to the HTML5 Notification API, providing additional functionality that is useful for financial desktop applications. | ||
> | ||
>The exact visual style and the extent of the OS-level integration is container dependent and hence out-of-scope of this specification. | ||
|
||
The notification API that we propose is following the HTML5 notifications standard (https://developer.mozilla.org/en-US/docs/Web/API/notification) | ||
|
||
If we need any extensions these can be added on top of it. | ||
|
||
## [Version API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/Version+API) | ||
> This API allows the JS web app to interrogate the container to find version support information. One possible use case is to get ssf API version supported so that in future it is possible to deprecate older containers that do not support latest version of API. Another possible use case is for logging purposes to help support track down issues. | ||
|
||
There is an info section in the API that provides the api version and also container information (version, capabilities, etc) | ||
|
||
```javascript | ||
var apiVersion = ssf.info.apiVersion; | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
export interface SSFInfo{ | ||
/** Version of the API **/ | ||
apiVersion: string; | ||
|
||
/** Container information **/ | ||
container: ContainerInfo; | ||
} | ||
|
||
export interface ContainerInfo { | ||
/** Name of the container */ | ||
name: string; | ||
|
||
/** Version of the container */ | ||
version: string; | ||
|
||
/** | ||
* Capabilities supported by the container. | ||
* Expressed as object where each property is a capability and the value | ||
* is the level of support in the container | ||
*/ | ||
capabilities: {[key:string]: string}; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/** | ||
* Currently this is based on OpenFin InterApplicationBus - http://cdn.openfin.co/jsdocs/stable/fin.desktop.InterApplicationBus.html | ||
* | ||
* TBD - Request/response and streaming | ||
*/ | ||
export interface MessagesAPI{ | ||
send(windowId: string, topic :string, message: string|object): void; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what is windowId here? |
||
subscribe(windowId: string, topic :string, listener: Function): void; | ||
unsubscribe(windowId: string, topic :string, listener: Function): void; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/** | ||
* Currently following HTML5 notification specs | ||
* | ||
* Imported from typescript definition files | ||
* https://github.com/Microsoft/TSJS-lib-generator/blob/cd60588b72a9188e89346b3c440a76508b4c0e76/baselines/dom.generated.d.ts#L8360-L8381 | ||
*/ | ||
export interface NotificationsAPI { | ||
permission: NotificationPermission; | ||
maxActions: number; | ||
|
||
requestPermission(): Promise<NotificationPermission>; | ||
} | ||
|
||
export type NotificationPermission = "default" | "denied" | "granted"; | ||
|
||
export type NotificationDirection = "auto" | "ltr" | "rtl"; | ||
|
||
export interface NotificationPermissionCallback { | ||
(permission: NotificationPermission): void; | ||
} | ||
|
||
export interface NotificationOptions { | ||
dir?: NotificationDirection; | ||
lang?: string; | ||
body?: string; | ||
tag?: string; | ||
image?: string; | ||
icon?: string; | ||
badge?: string; | ||
sound?: string; | ||
vibrate?: number | number[], | ||
timestamp?: number, | ||
renotify?: boolean; | ||
silent?: boolean; | ||
requireInteraction?: boolean; | ||
data?: any; | ||
actions?: NotificationAction[] | ||
} | ||
|
||
export interface NotificationAction { | ||
action: string; | ||
title: string; | ||
icon?: string; | ||
} | ||
|
||
declare class Notification extends EventTarget { | ||
constructor(title: string, options?: NotificationOptions); | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. looks like missing requestPermission method. |
||
onclick: EventListenerOrEventListenerObject; | ||
onerror: EventListenerOrEventListenerObject; | ||
|
||
close(): void; | ||
|
||
readonly title: string; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also need likely need a sticky option There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this a standard field? |
||
readonly dir: NotificationDirection; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. need to think how we might handle non-std fields. e.g., blink and blink color. |
||
readonly lang: string; | ||
readonly body: string; | ||
readonly tag: string; | ||
readonly image: string; | ||
readonly icon: string; | ||
readonly badge: string; | ||
readonly sound: string; | ||
readonly vibrate: number[]; | ||
readonly timestamp: number; | ||
readonly renotify: boolean; | ||
readonly silent: boolean; | ||
readonly requireInteraction: boolean; | ||
readonly data: any; | ||
readonly actions: NotificationAction[] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
This is an attempt to define an API that tries to unify what we currently have in ContainerJS, [the working group APIs](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/Proposed+Standard+API+Specifications) | ||
and things that we at Tick42 think are useful based on our experience. | ||
|
||
This is an initial version that aims to start a discussion - some parts of it are not fully defined (e.g. window events) and some | ||
upcoming parts are just mentioned in comments (e.g. interop). | ||
|
||
This also contains a [document](./confluence.md) describing how to map the [confluence API](https://symphonyoss.atlassian.net/wiki/display/WGDWAPI/Proposed+Standard+API+Specifications) to the current API. | ||
|
||
The starting point when reading the code should be [ssf.ts](./ssf.ts) file that describes the ssf root object as exposed to clients applications. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import {SystemAPI} from "./system"; | ||
import {WindowsAPI} from "./windows"; | ||
import {MessagesAPI} from "./messages"; | ||
import {NotificationsAPI} from "./notifications"; | ||
import {ApplicationAPI} from "./application"; | ||
import {SSFInfo} from "./info"; | ||
|
||
/** | ||
* Describes the ssf object as exposed to clients applications | ||
* | ||
* SSF object groups different APIs, where specific API methods can be accessed using the corresponding sub-object, e.g. | ||
* to access window management API : | ||
* | ||
* ssf.windows.open({name:'search', url: 'http://google.com'}); | ||
*/ | ||
export interface SSF { | ||
/** | ||
* Window management API - create, discover and manage windows | ||
*/ | ||
windows: WindowsAPI; | ||
|
||
/** | ||
* Messaging API - communicate with other windows | ||
*/ | ||
messages: MessagesAPI; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. how is this diff than window.sendMessage (postMesage) below? |
||
|
||
/** | ||
* Notifications API - publish notifications to the user | ||
*/ | ||
notifications: NotificationsAPI; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess the interesting thing here is that both within the browser and Electron container users will see two notification APIs:
This is probably unavoidable, but something that users need to be warned about. |
||
|
||
/** | ||
* Application API - access application specific information | ||
*/ | ||
application: ApplicationAPI; | ||
|
||
/** | ||
* System API - access system specific stuff,e.g. display information, user activity, os information... | ||
*/ | ||
system : SystemAPI; | ||
|
||
/** | ||
* Info API - general info about the API and the host container | ||
*/ | ||
info: SSFInfo; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might need to clarify the meaning of
Application
for OpenFin, as currently OpenFin windows that are not child windows are created usingfin.desktop.Application()
. Would this API be used for each OpenFin application, or ContainerJS application? If we want this per ContainerJS application, then we might need to rethink thesetBadgeCount()
or the window creation implementation as each ContainerJS application could have multiple top level windows, which could have different badge counts.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess a wider question is, should the API support multiple applications?
With OpenFin you can create a new Application instance through the JavaScript API.
Personally I think this is a bit of an edge case. I can't see when you'd want to do this in practice? I'd be happy with ContainerJS treating the Application as a singleton.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't know that.
We should decide if we want to have access to other applications and be able to start some of them (however I'm not sure how other apps will be discovered in Electron case)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can keep it as is for the time being, and have this as a single ContainerJS application. We can always change it in the future if we hit any problems
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in general need to think about which aspects are mandatory and optional