Skip to content

Commit

Permalink
May 2022 Release of the APL 2022.1 compliant APL Viewhost Web
Browse files Browse the repository at this point in the history
For more details on this release refer to CHANGELOG.md

To learn about APL see: https://developer.amazon.com/docs/alexa-presentation-language/understand-apl.html
  • Loading branch information
bddufour committed May 4, 2022
1 parent 20ad8fe commit 955c5fa
Show file tree
Hide file tree
Showing 30 changed files with 365 additions and 134 deletions.
16 changes: 16 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Changelog for apl-viewhost-web

## [2022.1]

This release adds support for version 2022.1 of the APL specification. Please also see APL Core Library for changes: [apl-core-library CHANGELOG](https://github.com/alexa/apl-core-library/blob/master/CHANGELOG.md)

### Added

- Added muted property to video component
- Exposed scrollCommandDuration

### Changed

- Improved support for HLS video
- Scale factor can be specified independently per renderer
- Changed clipping behaviour for documents using APL <= 1.5 for backwards compatibility
- Bug fixes

## [1.9.0]

This release adds support for version 1.9 of the APL specification. Please also see APL Core Library for changes: [apl-core-library CHANGELOG](https://github.com/alexa/apl-core-library/blob/master/CHANGELOG.md)
Expand Down
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ option(WEBSOCKET "Build Websocket Server" OFF)
option(EMSCRIPTEN_SOURCEMAPS "Builds source maps." OFF)
option(WASM_PROFILING "WASM profiling mode." OFF)

if(WASM)
# make sure we enable exception support when building APL core, since PEGTL
# relies on it
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexceptions")
endif()

if(${APL_CORE_PATH} STREQUAL "OFF")
set(APL_CORE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../APLCoreEngine)
endif()
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Alexa Presentation Language (APL) Viewhost Web

<p>
<a href="https://github.com/alexa/apl-viewhost-web/tree/v1.9.0" alt="version">
<img src="https://img.shields.io/badge/stable%20version-1.9.0-brightgreen" /></a>
<a href="https://github.com/alexa/apl-core-library/tree/v1.9.1" alt="APLCore">
<img src="https://img.shields.io/badge/apl%20core%20library-1.9.1-navy" /></a>
<a href="https://github.com/alexa/apl-viewhost-web/tree/v2022.1" alt="version">
<img src="https://img.shields.io/badge/stable%20version-2022.1-brightgreen" /></a>
<a href="https://github.com/alexa/apl-core-library/tree/v2022.1" alt="APLCore">
<img src="https://img.shields.io/badge/apl%20core%20library-2022.1-navy" /></a>
</p>

## Introduction
Expand Down
4 changes: 2 additions & 2 deletions js/apl-html/lib/dts/Context.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ declare namespace APL {

public setBackground(background: APL.IBackground): void;

public getDataSourceContext(): string;
public getDataSourceContext(): Promise<string>;

public getVisualContext(): string;
public getVisualContext(): Promise<string>;

public clearPending(): void;

Expand Down
22 changes: 22 additions & 0 deletions js/apl-html/src/APLRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { IExtensionManager } from './extensions/IExtensionManager';
import { ILogger } from './logging/ILogger';
import { LoggerFactory } from './logging/LoggerFactory';
import { AudioPlayerFactory } from './media/audio/AudioPlayer';
import { createAplVersionUtils } from './utils/AplVersionUtils';
import { browserIsEdge } from './utils/BrowserUtils';
import { ARROW_DOWN, ARROW_LEFT, ARROW_RIGHT, ARROW_UP, ENTER_KEY, HttpStatusCodes } from './utils/Constant';
import { isDisplayState } from './utils/DisplayStateUtils';
Expand All @@ -31,6 +32,8 @@ import { fetchMediaResource } from './utils/MediaRequestUtils';

const agentName = 'AplWebRenderer';
const agentVersion = '1.0.0';
const MAX_LEGACY_CLIPPING_APL_VERSION = '1.5';

// For touch enabled browser, touch event will be followed by a mouse event after 300ms-500ms up to browser.
// This will cause issue which triggers click or press events twice.
// setup a 500ms gap between two events.
Expand Down Expand Up @@ -301,6 +304,12 @@ export default abstract class APLRenderer<Options = any> {
*/
public abstract getLegacyKaraoke(): boolean;

/**
* @internal
* @ignore
*/
protected abstract getDocumentAplVersion(): string;

/** A reference to the APL root context */
public context: APL.Context;

Expand Down Expand Up @@ -910,6 +919,19 @@ export default abstract class APLRenderer<Options = any> {
}
}

/**
* @internal
* @ignore
*/
public getLegacyClippingEnabled(): boolean {
const aplVersionUtils = createAplVersionUtils();

const documentAplVersion: number = aplVersionUtils.getVersionCode(this.getDocumentAplVersion());
const legacyClippingAplVersion: number = aplVersionUtils.getVersionCode(MAX_LEGACY_CLIPPING_APL_VERSION);

return documentAplVersion <= legacyClippingAplVersion;
}

/**
* @internal
* @ignore
Expand Down
50 changes: 50 additions & 0 deletions js/apl-html/src/components/Component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {applyAplRectToStyle, applyPaddingToStyle} from './helpers/StylesUtil';
*/
const COMPONENT_TYPE_MAP = {
[ComponentType.kComponentTypeContainer]: 'Container',
[ComponentType.kComponentTypeEditText]: 'EditText',
[ComponentType.kComponentTypeFrame]: 'Frame',
[ComponentType.kComponentTypeImage]: 'Image',
[ComponentType.kComponentTypePager]: 'Pager',
Expand All @@ -46,6 +47,22 @@ const SUPPORTED_LAYOUT_DIRECTIONS = {
[LayoutDirection.kLayoutDirectionRTL]: 'rtl'
};

const LEGACY_CLIPPING_COMPONENTS_SET = new Set([
ComponentType.kComponentTypeFrame,
ComponentType.kComponentTypePager,
ComponentType.kComponentTypeScrollView,
ComponentType.kComponentTypeSequence,
ComponentType.kComponentTypeGridSequence
]);

const NO_CLIPPING_COMPONENTS_SET = new Set([
ComponentType.kComponentTypeEditText,
ComponentType.kComponentTypeImage,
ComponentType.kComponentTypeText,
ComponentType.kComponentTypeTouchWrapper,
ComponentType.kComponentTypeVideo
]);

export const SVG_NS = 'http://www.w3.org/2000/svg';
export const uuidv4 = require('uuid/v4');
export const IDENTITY_TRANSFORM = 'matrix(1.000000,0.000000,0.000000,1.000000,0.000000,0.000000)';
Expand Down Expand Up @@ -151,6 +168,7 @@ export abstract class Component<PropsType = IGenericPropType> extends EventEmitt
'-moz-box-sizing': 'border-box',
'box-sizing': 'border-box'
});
this.checkComponentTypeAndEnableClipping();
this.id = component.getUniqueId();
this.$container.attr('id', this.id);

Expand Down Expand Up @@ -415,6 +433,9 @@ export abstract class Component<PropsType = IGenericPropType> extends EventEmitt
* Resizes child component to fit parent component when applicable
*/
private sizeToFit(): void {
if (this.renderer && this.renderer.getLegacyClippingEnabled()) {
return;
}
// adjust bounds
const componentHasBounds = !!this.bounds;
const componentHasParent = !!this.parent;
Expand Down Expand Up @@ -702,4 +723,33 @@ export abstract class Component<PropsType = IGenericPropType> extends EventEmitt
}
return '';
}

/**
* Enable clipping if version is <= 1.5 or if component is part the legacy-clipping set.
* Never enable clipping for if component is part of the no-clipping set.
*
*/
private checkComponentTypeAndEnableClipping() {
const componentType = this.component.getType();

// Don't clip for these components
if (NO_CLIPPING_COMPONENTS_SET.has(componentType)) {
return;
}

const isParentLegacy = this.parent && LEGACY_CLIPPING_COMPONENTS_SET.has(this.parent.component.getType());
const isLegacyComponentType: boolean = LEGACY_CLIPPING_COMPONENTS_SET.has(componentType);
const isLegacyAplVersion: boolean = this.renderer && this.renderer.getLegacyClippingEnabled();

if (isLegacyComponentType || isParentLegacy || !isLegacyAplVersion) {
this.enableClipping();
}
}

/**
* Enable clipping
*/
protected enableClipping() {
this.$container.css('overflow', 'hidden');
}
}
4 changes: 0 additions & 4 deletions js/apl-html/src/components/Container.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,6 @@ import { Component, FactoryFunction } from './Component';
export class Container extends Component {
constructor(renderer: APLRenderer, component: APL.Component, factory: FactoryFunction, parent?: Component) {
super(renderer, component, factory, parent);

this.$container.css({
overflow: 'hidden'
});
}

protected isLayout(): boolean {
Expand Down
3 changes: 1 addition & 2 deletions js/apl-html/src/components/Frame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ export class Frame extends Component<IFrameProperties> {
constructor(renderer: APLRenderer, component: APL.Component, factory: FactoryFunction, parent?: Component) {
super(renderer, component, factory, parent);
this.$container.css({
'border-style': 'solid',
'overflow': 'hidden'
'border-style': 'solid'
});
this.propExecutor
(this.setBackgroundColor, PropertyKey.kPropertyBackgroundColor)
Expand Down
1 change: 0 additions & 1 deletion js/apl-html/src/components/MultiChildScrollable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ export abstract class MultiChildScrollable extends Scrollable<IMultiChildScrolla

public init() {
super.init();
this.$container.css('overflow', 'hidden');
}

protected allowFocus(requestedDistance: number, moveTo: HTMLDivElement) {
Expand Down
1 change: 0 additions & 1 deletion js/apl-html/src/components/ScrollView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ export class ScrollView extends Scrollable<IScrollViewProperties> {

public init() {
super.init();
this.$container.css('overflow', 'hidden');
}

/**
Expand Down
2 changes: 1 addition & 1 deletion js/apl-html/src/components/TouchWrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export class TouchWrapper extends ActionableComponent<ITouchWrapperProperties> {
if (child.action === ChildAction.Insert) {
// hide the overflow caused by insert.
// It will even temporary hide eg.shadow which renders out of box during the insert.
this.$container.css('overflow', 'hidden');
this.enableClipping();
} else {
// make sure the wrapper renders child element as expected.
this.$container.css('overflow', 'visible');
Expand Down
1 change: 0 additions & 1 deletion js/apl-html/src/components/avg/VectorGraphic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,6 @@ export class VectorGraphic extends ActionableComponent<IVectorGraphicProperties>
super(renderer, component, factory, parent);
this.svg = document.createElementNS(VectorGraphic.SVG_NS, 'svg') as SVGElement;
this.container.appendChild(this.svg);
this.$container.css('overflow', 'hidden');
this.vectorGraphicUpdater = vectorGraphicUpdater;
}

Expand Down
3 changes: 0 additions & 3 deletions js/apl-html/src/components/pager/PagerComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@ export class PagerComponent extends ActionableComponent<IPagerProperties> {

constructor(renderer: APLRenderer, component: APL.Component, factory: FactoryFunction, parent?: Component) {
super(renderer, component, factory, parent);
this.$container.css({
overflow: 'hidden'
});
}

protected isLayout(): boolean {
Expand Down
7 changes: 7 additions & 0 deletions js/apl-html/src/components/video/AbstractVideoComponent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ export abstract class AbstractVideoComponent extends Component<IVideoProperties>
this.propExecutor
(this.setScaleFromProp, PropertyKey.kPropertyScale)
(this.setAudioTrackFromProp, PropertyKey.kPropertyAudioTrack)
(this.setMutedFromProp, PropertyKey.kPropertyMuted)
(this.setTrackCurrentTimeFromProp, PropertyKey.kPropertyTrackCurrentTime)
(this.setPauseFromProp, PropertyKey.kPropertyTrackPaused)
(this.setSourceFromProp, PropertyKey.kPropertySource)
Expand Down Expand Up @@ -70,6 +71,8 @@ export abstract class AbstractVideoComponent extends Component<IVideoProperties>

protected abstract setAudioTrack(audioTrack: AudioTrack);

protected abstract setMuted(muted: boolean);

protected abstract async setSource(source: IMediaSource | IMediaSource[]);

protected abstract setTrackCurrentTime(trackCurrentTime: number);
Expand All @@ -89,6 +92,10 @@ export abstract class AbstractVideoComponent extends Component<IVideoProperties>
this.setAudioTrack(this.props[PropertyKey.kPropertyAudioTrack]);
}

private setMutedFromProp = () => {
this.setMuted(this.props[PropertyKey.kPropertyMuted]);
}

private setSourceFromProp = () => {
this.setSource(this.props[PropertyKey.kPropertySource]);
}
Expand Down
13 changes: 13 additions & 0 deletions js/apl-html/src/components/video/Video.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ export class Video extends AbstractVideoComponent {
});
}

public async end(): Promise<any> {
this.videoEventSequencer.enqueueForProcessing(VideoInterface.END, {
fromEvent: this.fromEvent
});
}

public async seek(offset: number): Promise<any> {
this.videoEventSequencer.enqueueForProcessing(VideoInterface.SEEK, {
seekOffset: offset,
Expand Down Expand Up @@ -114,6 +120,13 @@ export class Video extends AbstractVideoComponent {
});
}

protected setMuted(muted: boolean) {
this.videoEventSequencer.enqueueForProcessing(VideoInterface.SET_MUTED, {
muted,
fromEvent: this.fromEvent
});
}

protected async setSource(source: IMediaSource | IMediaSource[]): Promise<any> {
this.videoEventSequencer.enqueueForProcessing(VideoInterface.SET_SOURCE, {
source
Expand Down
Loading

0 comments on commit 955c5fa

Please sign in to comment.