/**
* @module VerifoneControls
*/
import { blobToBase64, checkResponse } from './Common.js'
import { DisplayWidget } from './SignatureTabletWidgets.js'
/**
* AccessKey
* @classdesc Special keys which can be mapped to a button
* @see {@link Verifone}
*/
export class AccessKey {
static STAR = 'Š'
static HASH = '‹'
static CANCEL = ''
static BACK = ''
static ENTER = ' '
}
/**
* Button
* @classdesc A button for displaying clickable text on a tablet
* @extends DisplayWidget
* @see {@link Verifone}
*/
export class Button extends DisplayWidget {
id
text
width = 200
height = 100
font
border
background
padding
accessKey
beep = false
/**
* Instantiate a Button
* @constructor
* @param {number} id - ID of the button that will be returned when it is
* clicked
* @param {string} text - Text to display on the button
* @param {number} x - X position to draw the button
* @param {number} y - Y position to draw the button
*
* @param {object} [options] - Additional configuration options.
* @param {number} [options.width=200] - Width of button in pixesl
* @param {number} [options.height=100] - height of button in pixels
* @param {object} [options.border] - Border styles
* @param {string} [options.background] - Background color (hex or RGB)
* @param {array} [options.padding] - Padding
* @param {string} [options.accessKey] - Map button to a key on the keypad
* @param {object} [options.font] - Font styles
* @param {boolean} [options.beep=false] - On press, emit a beep
*/
constructor (id, text, x, y, options) {
super(x, y)
this.id = id
this.text = text
if (typeof options === 'object') {
Object.assign(this, options)
}
}
toJSON () {
return {
type: 'button',
text: this.text,
x: this.x,
y: this.y,
id: this.id,
width: this.width,
height: this.height,
font: this.font,
border: this.border,
padding: this.padding,
background: this.background,
access_key: this.accessKey,
beep: this.beep
}
}
}
/**
* Text
* @classdesc Text to be displayed on a tablet
* @extends DisplayWidget
* @see {@link Verifone}
*/
export class Text extends DisplayWidget {
id
text
width
height
font
border
background
padding
align = 'left'
lineHeight
escape = true
style
/**
* Instantiate a Text object
* @constructor
* @param {number} id - ID of the text object
* @param {string} text - Text to display
* @param {number} x - X position to draw the text
* @param {number} y - Y position to draw the text
*
* @param {object} [options] - Additional configuration options.
* @param {number} [options.width] - Width of text bounding box in pixesl
* @param {number} [options.height] - height of text bounding in pixels
* @param {object} [options.border] - Border styles
* @param {string} [options.background] - Background color (hex or RGB)
* @param {array} [options.padding] - Padding
* @param {string} [options.align] - Align text `left`, `right`, or `center`
* @param {object} [options.font] - Font styles
* @param {number} [options.lineHeight] - Text line height
* @param {bool} [options.escape=true] - If false allows for raw HTML content
* @param {string?} [options.style] - If set, will embed inline style
*/
constructor (id, text, x, y, options) {
super(x, y)
this.id = id
this.text = text
if (typeof options === 'object') {
Object.assign(this, options)
}
}
toJSON () {
return {
type: 'text',
text: this.text,
align: this.align,
x: this.x,
y: this.y,
id: this.id,
width: this.width,
height: this.height,
font: this.font,
border: this.border,
padding: this.padding,
background: this.background,
line_height: this.lineHeight,
escape: this.escape,
style: this.style
}
}
}
/**
* Image
* @classdesc Image to be displayed on a tablet
* @extends DisplayWidget
* @see {@link Verifone}
*/
export class Image extends DisplayWidget {
id
url
imageData
format = 'jpg'
height
width
border
/**
* Instantiate an Image object
* @constructor
* @param {number} id - ID of the image object
* @param {string} url - URL of the image. To provide the image data directly
* set the `url` argument to `null`, set the`imageData` property to the
* base64 encoded contents of the image, and set the `format` property to
* the file extension of the image (e.g. `jpg` or `png`)
* @param {number} x - X position to draw the image
* @param {number} y - Y position to draw the image
*
* @param {object} [options] - Additional configuration options
* @param {string} [options.format] - `jpg` or `png`
* @param {string} [options.imageData] - base64 encoded image data
* @param {number} [options.width] - Width of image in pixels
* @param {number} [options.height] - height of image in pixels
* @param {object} [options.border] - Border styles
*/
constructor (id, url, x = 0, y = 0, options) {
super(x, y)
this.id = id
this.url = url
// if no format is provided look for the file extension
if ((!options || !options.format) && url) {
this.format = /(?:\.([^.]+))?$/.exec(url)[1]
}
if (typeof options === 'object') {
Object.assign(this, options)
}
}
/**
* Fetch the image data and base64 encode it
* @async
*/
async data () {
if (!this.imageData && this.url) {
const response = await fetch(this.url)
await checkResponse(response)
const blob = await response.blob()
this.imageData = await blobToBase64(blob)
}
return this.imageData
}
toJSON () {
return {
id: this.id,
width: this.width,
height: this.height,
format: this.format,
type: 'image',
data: this.imageData,
x: this.x,
y: this.y,
border: this.border ? this.border.toJSON() : undefined
}
}
}
/**
* SignatureBox
* @classdesc Bounding box to capture a signature
* @extends DisplayWidget
* @see {@link Verifone}
*/
export class SignatureBox extends DisplayWidget {
id
width
height
postSignTimeout = 25
/**
* Instantiate a SignatureBox object
* @constructor
* @param {number} id - ID of the signature box object
* @param {number} x - X position to draw the sig box
* @param {number} y - Y position to draw the sig box
*
* @param {object} [options] - Additional configuration options
* @param {string} [options.format] - `jpg` or `png`
* @param {number} [options.width] - Width of sig box in pixels
* @param {number} [options.height] - height of sig box in pixels
* @param {number} [options.postSignTimeout] - Timeout after signing has started
*/
constructor (id, x, y, options) {
super(x, y)
this.id = id
if (typeof options === 'object') {
Object.assign(this, options)
}
}
toJSON () {
return {
id: this.id,
type: 'signature',
x: this.x,
y: this.y,
width: this.width,
height: this.height,
post_sign_timeout: this.postSignTimeout
}
}
}
/**
* Rect
* @classdesc A rectangle
* @extends DisplayWidget
* @see {@link Verifone}
*/
export class Rect extends DisplayWidget {
id
width = 100
height = 100
background
opacity
border
zIndex
/**
* Instantiate a Rect object
* @constructor
* @param {number} id - ID of the rectangle object
* @param {number} x - X position to draw the rectangle
* @param {number} y - Y position to draw the rectangle
*
* @param {object} [options] - Additional configuration options
* @param {number} [options.width=100] - Width of rectangle in pixels
* @param {number} [options.height=100] - height of rectangle in pixels
* @param {object} [options.border] - Border styles
* @param {float} [options.opacity] - Set object opacity (0.0 to 1)
* @param {number} [options.zIndex] - Manually set z-index
*/
constructor (id, x, y, options) {
super(x, y)
this.id = id
if (typeof options === 'object') {
Object.assign(this, options)
}
}
toJSON () {
return {
id: this.id,
type: 'rect',
x: this.x,
y: this.y,
width: this.width,
height: this.height,
border: this.border,
opacity: this.opacity,
background: this.background,
z_index: this.zIndex
}
}
}
/**
* CheckBox
* @classdesc A check box object
* @extends DisplayWidget
* @see {@link Verifone}
*/
export class CheckBox extends DisplayWidget {
id
width = 50
height = 50
checked
/**
* Instantiate a check box object
* @constructor
* @param {number} id - ID of the rectangle object
* @param {number} x - X position to draw the check box
* @param {number} y - Y position to draw the check box
*
* @param {object} [options] - Additional configuration options
* @param {number} [options.width=50] - Width of check box in pixels
* @param {number} [options.height=50] - height of check box in pixels
* @param {boolean} [options.boolean=false] - Set the checked state
*/
constructor (id, x, y, options) {
super(x, y)
this.id = id
if (typeof options === 'object') {
Object.assign(this, options)
}
}
toJSON () {
return {
type: 'checkbox',
x: this.x,
y: this.y,
id: this.id,
width: this.width,
height: this.height,
checked: this.checked
}
}
}
/**
* RadioButton
* @classdesc A radio button object
* @extends DisplayWidget
* @see {@link Verifone}
*/
export class RadioButton extends DisplayWidget {
id
groupId
width = 50
height = 50
checked
value
/**
* Instantiate a radio button object
* @constructor
* @param {number} id - ID of the radio button object
* @param {number} groupId - Group ID of the radio button object
* @param {number} x - X position to draw the radio button
* @param {number} y - Y position to draw the radio button
*
* @param {object} [options] - Additional configuration options
* @param {number} [options.width=50] - Width of radio button in pixels
* @param {number} [options.height=50] - height of radio button in pixels
* @param {boolean} [options.boolean=false] - Set the checked state
*/
constructor (id, groupId, value, x, y, options) {
super(x, y)
this.id = id
this.groupId = groupId
this.value = value
if (typeof options === 'object') {
Object.assign(this, options)
}
}
toJSON () {
return {
type: 'radio',
x: this.x,
y: this.y,
id: this.id,
group_id: this.groupId,
width: this.width,
height: this.height,
checked: this.checked,
value: this.value
}
}
}
/**
* TextInput
* @classdesc A text input object
* @extends DisplayWidget
* @see {@link Verifone}
*/
export class TextInput extends DisplayWidget {
id
width
height
value
font
border
background
padding
placeholder
allowedChars
minLength
maxLength
align = 'left'
/**
* Instantiate a text input object
* @constructor
* @param {number} id - ID of the radio button object
* @param {number} x - X position to draw the text input
* @param {number} y - Y position to draw the text input
*
* @param {object} [options] - Additional configuration options
* @param {number} [options.width] - Width of text input in pixels
* @param {number} [options.height] - height of text input in pixels
* @param {string} [options.value] - Set the value of the text input
* @param {object} [options.font] - Font styles
* @param {object} [options.border] - Border styles
* @param {string} [options.background] - Background color
* @param {array} [options.padding] - Padding
* @param {string} [options.placeholder] - Placeholder text
* @param {string} [options.allowedChars] - Characters allowed for input
* @param {number} [options.minLength] - Minimum allowed number of characters
* @param {number} [options.maxLength] - Maximum allowed number of characters
* @param {string} [options.align] - Align text `left`, `right`, or `center`
*/
constructor (id, x, y, options) {
super(x, y)
this.id = id
if (typeof options === 'object') {
Object.assign(this, options)
}
}
toJSON () {
return {
type: 'input',
id: this.id,
x: this.x,
y: this.y,
width: this.width,
height: this.height,
value: this.value,
font: this.font,
border: this.border,
background: this.background,
padding: this.padding,
placeholder: this.placeholder,
allowed_chars: this.allowedChars,
min_length: this.minLength,
max_length: this.maxLength,
align: this.align
}
}
}