Path: blob/trunk/javascript/selenium-webdriver/bidi/protocolValue.js
2884 views
// Licensed to the Software Freedom Conservancy (SFC) under one1// or more contributor license agreements. See the NOTICE file2// distributed with this work for additional information3// regarding copyright ownership. The SFC licenses this file4// to you under the Apache License, Version 2.0 (the5// "License"); you may not use this file except in compliance6// with the License. You may obtain a copy of the License at7//8// http://www.apache.org/licenses/LICENSE-2.09//10// Unless required by applicable law or agreed to in writing,11// software distributed under the License is distributed on an12// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY13// KIND, either express or implied. See the License for the14// specific language governing permissions and limitations15// under the License.1617const { PrimitiveType, NonPrimitiveType, RemoteType, SpecialNumberType } = require('./protocolType')1819const TYPE_CONSTANT = 'type'20const VALUE_CONSTANT = 'value'21/**22* Represents the types of remote reference.23* @enum {string}24*/25const RemoteReferenceType = {26HANDLE: 'handle',27SHARED_ID: 'sharedId',28}2930/**31* Represents a local value with a specified type and optional value.32* @class33* Described in https://w3c.github.io/webdriver-bidi/#type-script-LocalValue34*/35class LocalValue {36constructor(type, value = null) {37if (type === PrimitiveType.UNDEFINED || type === PrimitiveType.NULL) {38this.type = type39} else {40this.type = type41this.value = value42}43}4445/**46* Creates a new LocalValue object with a string value.47*48* @param {string} value - The string value to be stored in the LocalValue object.49* @returns {LocalValue} - The created LocalValue object.50*/51static createStringValue(value) {52return new LocalValue(PrimitiveType.STRING, value)53}5455/**56* Creates a new LocalValue object with a number value.57*58* @param {number} value - The number value.59* @returns {LocalValue} - The created LocalValue object.60*/61static createNumberValue(value) {62return new LocalValue(PrimitiveType.NUMBER, value)63}6465/**66* Creates a new LocalValue object with a special number value.67*68* @param {number} value - The value of the special number.69* @returns {LocalValue} - The created LocalValue object.70*/71static createSpecialNumberValue(value) {72return new LocalValue(PrimitiveType.SPECIAL_NUMBER, value)73}7475/**76* Creates a new LocalValue object with an undefined value.77* @returns {LocalValue} - The created LocalValue object.78*/79static createUndefinedValue() {80return new LocalValue(PrimitiveType.UNDEFINED)81}8283/**84* Creates a new LocalValue object with a null value.85* @returns {LocalValue} - The created LocalValue object.86*/87static createNullValue() {88return new LocalValue(PrimitiveType.NULL)89}9091/**92* Creates a new LocalValue object with a boolean value.93*94* @param {boolean} value - The boolean value.95* @returns {LocalValue} - The created LocalValue object.96*/97static createBooleanValue(value) {98return new LocalValue(PrimitiveType.BOOLEAN, value)99}100101/**102* Creates a new LocalValue object with a BigInt value.103*104* @param {BigInt} value - The BigInt value.105* @returns {LocalValue} - The created LocalValue object.106*/107static createBigIntValue(value) {108return new LocalValue(PrimitiveType.BIGINT, value)109}110111/**112* Creates a new LocalValue object with an array.113*114* @param {Array} value - The array.115* @returns {LocalValue} - The created LocalValue object.116*/117static createArrayValue(value) {118return new LocalValue(NonPrimitiveType.ARRAY, value)119}120121/**122* Creates a new LocalValue object with date value.123*124* @param {string} value - The date.125* @returns {LocalValue} - The created LocalValue object.126*/127static createDateValue(value) {128return new LocalValue(NonPrimitiveType.DATE, value)129}130131/**132* Creates a new LocalValue object of map value.133* @param {Map} map - The map.134* @returns {LocalValue} - The created LocalValue object.135*/136static createMapValue(map) {137let value = []138Object.entries(map).forEach((entry) => {139value.push(entry)140})141return new LocalValue(NonPrimitiveType.MAP, value)142}143144/**145* Creates a new LocalValue object from the passed object.146*147* @param {Object} object - The object.148* @returns {LocalValue} - The created LocalValue object.149*/150static createObjectValue(object) {151let value = []152Object.entries(object).forEach((entry) => {153value.push(entry)154})155return new LocalValue(NonPrimitiveType.OBJECT, value)156}157158/**159* Creates a new LocalValue object of regular expression value.160*161* @param {string} value - The value of the regular expression.162* @returns {LocalValue} - The created LocalValue object.163*/164static createRegularExpressionValue(value) {165return new LocalValue(NonPrimitiveType.REGULAR_EXPRESSION, value)166}167168/**169* Creates a new LocalValue object with the specified value.170* @param {Set} value - The value to be set.171* @returns {LocalValue} - The created LocalValue object.172*/173static createSetValue(value) {174return new LocalValue(NonPrimitiveType.SET, value)175}176177/**178* Creates a new LocalValue object with the given channel value179*180* @param {ChannelValue} value - The channel value.181* @returns {LocalValue} - The created LocalValue object.182*/183static createChannelValue(value) {184return new LocalValue(NonPrimitiveType.CHANNEL, value)185}186187static createReferenceValue(handle, sharedId) {188return new ReferenceValue(handle, sharedId)189}190191static getArgument(argument) {192let localValue = null193194if (195argument === SpecialNumberType.NAN ||196argument === SpecialNumberType.MINUS_ZERO ||197argument === SpecialNumberType.INFINITY ||198argument === SpecialNumberType.MINUS_INFINITY199) {200localValue = LocalValue.createSpecialNumberValue(argument)201return localValue202}203204const type = typeof argument205206switch (type) {207case PrimitiveType.STRING:208localValue = LocalValue.createStringValue(argument)209break210case PrimitiveType.NUMBER:211localValue = LocalValue.createNumberValue(argument)212break213case PrimitiveType.BOOLEAN:214localValue = LocalValue.createBooleanValue(argument)215break216case PrimitiveType.BIGINT:217localValue = LocalValue.createBigIntValue(argument.toString())218break219case PrimitiveType.UNDEFINED:220localValue = LocalValue.createUndefinedValue()221break222case NonPrimitiveType.OBJECT:223if (argument === null) {224localValue = LocalValue.createNullValue()225break226}227if (argument instanceof Date) {228localValue = LocalValue.createDateValue(argument)229} else if (argument instanceof Map) {230const map = []231232argument.forEach((value, key) => {233let objectKey234if (typeof key === 'string') {235objectKey = key236} else {237objectKey = LocalValue.getArgument(key)238}239const objectValue = LocalValue.getArgument(value)240map.push([objectKey, objectValue])241})242localValue = new LocalValue(NonPrimitiveType.MAP, map)243} else if (argument instanceof Set) {244const set = []245argument.forEach((value) => {246set.push(LocalValue.getArgument(value))247})248localValue = LocalValue.createSetValue(set)249} else if (argument instanceof Array) {250const arr = []251argument.forEach((value) => {252arr.push(LocalValue.getArgument(value))253})254localValue = LocalValue.createArrayValue(arr)255} else if (argument instanceof RegExp) {256localValue = LocalValue.createRegularExpressionValue({257pattern: argument.source,258flags: argument.flags,259})260} else {261let value = []262Object.entries(argument).forEach((entry) => {263value.push([LocalValue.getArgument(entry[0]), LocalValue.getArgument(entry[1])])264})265localValue = new LocalValue(NonPrimitiveType.OBJECT, value)266}267break268}269270return localValue271}272273asMap() {274let toReturn = {}275toReturn[TYPE_CONSTANT] = this.type276277if (!(this.type === PrimitiveType.NULL || this.type === PrimitiveType.UNDEFINED)) {278toReturn[VALUE_CONSTANT] = this.value279}280return toReturn281}282}283284/**285* Represents a remote value.286* Described in https://w3c.github.io/webdriver-bidi/#type-script-RemoteValue.287* @class288*/289class RemoteValue {290constructor(remoteValue) {291this.type = null292this.handle = null293this.internalId = null294this.value = null295this.sharedId = null296297if ('type' in remoteValue) {298const typeString = remoteValue['type']299if (PrimitiveType.findByName(typeString) != null) {300this.type = PrimitiveType.findByName(typeString)301} else if (NonPrimitiveType.findByName(typeString) != null) {302this.type = NonPrimitiveType.findByName(typeString)303} else {304this.type = RemoteType.findByName(typeString)305}306}307308if ('handle' in remoteValue) {309this.handle = remoteValue['handle']310}311312if ('internalId' in remoteValue) {313this.internalId = remoteValue['internalId']314}315316if ('value' in remoteValue) {317this.value = remoteValue['value']318}319320if ('sharedId' in remoteValue) {321this.sharedId = remoteValue['sharedId']322}323324if (this.value != null) {325this.value = this.deserializeValue(this.value, this.type)326}327}328329deserializeValue(value, type) {330if (type === NonPrimitiveType.OBJECT) {331return Object.fromEntries(value)332} else if (type === NonPrimitiveType.REGULAR_EXPRESSION) {333return new RegExpValue(value.pattern, value.flags)334}335return value336}337}338339/**340* Represents a reference value in the protocol.341* Described in https://w3c.github.io/webdriver-bidi/#type-script-RemoteReference.342*/343class ReferenceValue {344#handle345#sharedId346347/**348* Constructs a new ReferenceValue object.349* @param {string} handle - The handle value.350* @param {string} sharedId - The shared ID value.351*/352constructor(handle, sharedId) {353if (handle === RemoteReferenceType.HANDLE) {354this.#handle = sharedId355} else if (handle === RemoteReferenceType.SHARED_ID) {356this.#sharedId = sharedId357} else {358this.#handle = handle359this.#sharedId = sharedId360}361}362363asMap() {364const toReturn = {}365if (this.#handle != null) {366toReturn[RemoteReferenceType.HANDLE] = this.#handle367}368369if (this.#sharedId != null) {370toReturn[RemoteReferenceType.SHARED_ID] = this.#sharedId371}372373return toReturn374}375}376377/**378* Represents a regular expression value.379* Described in https://w3c.github.io/webdriver-bidi/#type-script-LocalValue.380*/381class RegExpValue {382/**383* Constructs a new RegExpValue object.384* @param {string} pattern - The pattern of the regular expression.385* @param {string|null} [flags=null] - The flags of the regular expression.386*/387constructor(pattern, flags = null) {388this.pattern = pattern389this.flags = flags390}391}392393/**394* Represents serialization options.395* Described in https://w3c.github.io/webdriver-bidi/#type-script-SerializationOptions.396*/397class SerializationOptions {398/**399* Constructs a new instance of SerializationOptions.400* @param {number} [maxDomDepth=0] - The maximum depth to serialize the DOM.401* @param {number|null} [maxObjectDepth=null] - The maximum depth to serialize objects.402* @param {'none'|'open'|'all'} [includeShadowTree='none'] - The inclusion level of the shadow tree.403* @throws {Error} If the `includeShadowTree` value is not one of 'none', 'open', or 'all'.404*/405constructor(maxDomDepth = 0, maxObjectDepth = null, includeShadowTree = 'none') {406this._maxDomDepth = maxDomDepth407this._maxObjectDepth = maxObjectDepth408409if (['none', 'open', 'all'].includes(includeShadowTree)) {410throw Error(`Valid types are 'none', 'open', and 'all'. Received: ${includeShadowTree}`)411}412this._includeShadowTree = includeShadowTree413}414}415416/**417* Represents a channel value.418* Described in https://w3c.github.io/webdriver-bidi/#type-script-ChannelValue.419* @class420*/421class ChannelValue {422constructor(channel, options = undefined, resultOwnership = undefined) {423this.channel = channel424425if (options !== undefined) {426if (options instanceof SerializationOptions) {427this.options = options428} else {429throw Error(`Pass in SerializationOptions object. Received: ${options} `)430}431}432433if (resultOwnership !== undefined) {434if (['root', 'none'].includes(resultOwnership)) {435this.resultOwnership = resultOwnership436} else {437throw Error(`Valid types are 'root' and 'none. Received: ${resultOwnership}`)438}439}440}441}442443module.exports = {444ChannelValue,445LocalValue,446RemoteValue,447ReferenceValue,448RemoteReferenceType,449RegExpValue,450SerializationOptions,451}452453454