Best JavaScript code snippet using wpt
webxr-test.js
Source:webxr-test.js
1'use strict';2// This polyfill library implements the WebXR Test API as specified here:3// https://github.com/immersive-web/webxr-test-api4let default_standing = new gfx.mojom.Transform();5default_standing.matrix = [1, 0, 0, 0,6 0, 1, 0, 0,7 0, 0, 1, 0,8 0, 1.65, 0, 1];9const default_stage_parameters = {10 standingTransform: default_standing,11 sizeX: 0,12 sizeZ: 0,13 bounds: null14};15function getMatrixFromTransform(transform) {16 let x = transform.orientation[0];17 let y = transform.orientation[1];18 let z = transform.orientation[2];19 let w = transform.orientation[3];20 let m11 = 1.0 - 2.0 * (y * y + z * z);21 let m21 = 2.0 * (x * y + z * w);22 let m31 = 2.0 * (x * z - y * w);23 let m12 = 2.0 * (x * y - z * w);24 let m22 = 1.0 - 2.0 * (x * x + z * z);25 let m32 = 2.0 * (y * z + x * w);26 let m13 = 2.0 * (x * z + y * w);27 let m23 = 2.0 * (y * z - x * w);28 let m33 = 1.0 - 2.0 * (x * x + y * y);29 let m14 = transform.position[0];30 let m24 = transform.position[1];31 let m34 = transform.position[2];32 // Column-major linearized order is expected.33 return [m11, m21, m31, 0,34 m12, m22, m32, 0,35 m13, m23, m33, 0,36 m14, m24, m34, 1];37}38class ChromeXRTest {39 constructor() {40 this.mockVRService_ = new MockVRService(mojo.frameInterfaces);41 }42 simulateDeviceConnection(init_params) {43 return Promise.resolve(this.mockVRService_.addRuntime(init_params));44 }45 disconnectAllDevices() {46 this.mockVRService_.removeAllRuntimes(device);47 return Promise.resolve();48 }49 simulateUserActivation(callback) {50 return new Promise(resolve => {51 let button = document.createElement('button');52 button.textContent = 'click to continue test';53 button.style.display = 'block';54 button.style.fontSize = '20px';55 button.style.padding = '10px';56 button.onclick = () => {57 resolve(callback());58 document.body.removeChild(button);59 };60 document.body.appendChild(button);61 test_driver.click(button);62 });63 }64}65// Mocking class definitions66// Mock service implements both the VRService and XRDevice mojo interfaces.67class MockVRService {68 constructor() {69 this.bindingSet_ = new mojo.BindingSet(device.mojom.VRService);70 this.runtimes_ = [];71 this.interceptor_ =72 new MojoInterfaceInterceptor(device.mojom.VRService.name);73 this.interceptor_.oninterfacerequest = e =>74 this.bindingSet_.addBinding(this, e.handle);75 this.interceptor_.start();76 }77 // Test methods78 addRuntime(fakeDeviceInit) {79 let runtime = new MockRuntime(fakeDeviceInit, this);80 this.runtimes_.push(runtime);81 if (this.client_) {82 this.client_.onDeviceChanged();83 }84 return runtime;85 }86 removeAllRuntimes() {87 if (this.client_) {88 this.client_.onDeviceChanged();89 }90 this.runtimes_ = [];91 }92 removeRuntime(device) {93 let index = this.runtimes_.indexOf(device);94 if (index >= 0) {95 this.runtimes_.splice(index, 1);96 if (this.client_) {97 console.error("Notifying client");98 this.client_.onDeviceChanged();99 }100 }101 }102 // VRService implementation.103 requestDevice() {104 if (this.runtimes_.length > 0) {105 let devicePtr = new device.mojom.XRDevicePtr();106 new mojo.Binding(107 device.mojom.XRDevice, this, mojo.makeRequest(devicePtr));108 return Promise.resolve({device: devicePtr});109 } else {110 return Promise.resolve({device: null});111 }112 }113 setClient(client) {114 this.client_ = client;115 }116 // XRDevice implementation.117 requestSession(sessionOptions, was_activation) {118 let requests = [];119 // Request a session from all the runtimes.120 for (let i = 0; i < this.runtimes_.length; i++) {121 requests[i] = this.runtimes_[i].requestRuntimeSession(sessionOptions);122 }123 return Promise.all(requests).then((results) => {124 // Find and return the first successful result.125 for (let i = 0; i < results.length; i++) {126 if (results[i].session) {127 return {128 result: {129 session : results[i].session,130 $tag : 0131 }132 };133 }134 }135 // If there were no successful results, returns a null session.136 return {137 result: {138 failureReason : device.mojom.RequestSessionResult.NO_RUNTIME_FOUND,139 $tag : 1140 }141 };142 });143 }144 supportsSession(sessionOptions) {145 let requests = [];146 // Check supports on all the runtimes.147 for (let i = 0; i < this.runtimes_.length; i++) {148 requests[i] = this.runtimes_[i].runtimeSupportsSession(sessionOptions);149 }150 return Promise.all(requests).then((results) => {151 // Find and return the first successful result.152 for (let i = 0; i < results.length; i++) {153 if (results[i].supportsSession) {154 return results[i];155 }156 }157 // If there were no successful results, returns false.158 return {supportsSession: false};159 });160 };161}162// Implements XRFrameDataProvider and XRPresentationProvider. Maintains a mock163// for XRPresentationProvider.164class MockRuntime {165 constructor(fakeDeviceInit, service) {166 this.sessionClient_ = new device.mojom.XRSessionClientPtr();167 this.presentation_provider_ = new MockXRPresentationProvider();168 this.pose_ = null;169 this.next_frame_id_ = 0;170 this.bounds_ = null;171 this.send_pose_reset_ = false;172 this.service_ = service;173 this.framesOfReference = {};174 this.input_sources_ = [];175 this.next_input_source_index_ = 1;176 // Initialize DisplayInfo first to set the defaults, then override with177 // anything from the deviceInit178 if (fakeDeviceInit.supportsImmersive) {179 this.displayInfo_ = this.getImmersiveDisplayInfo();180 } else {181 this.displayInfo_ = this.getNonImmersiveDisplayInfo();182 }183 if (fakeDeviceInit.supportsEnvironmentIntegration) {184 this.displayInfo_.capabilities.canProvideEnvironmentIntegration = true;185 }186 if (fakeDeviceInit.viewerOrigin != null) {187 this.setViewerOrigin(fakeDeviceInit.viewerOrigin);188 }189 if (fakeDeviceInit.floorOrigin != null) {190 this.setFloorOrigin(fakeDeviceInit.floorOrigin);191 }192 // This appropriately handles if the coordinates are null193 this.setBoundsGeometry(fakeDeviceInit.boundsCoordinates);194 this.setViews(fakeDeviceInit.views);195 }196 // Test API methods.197 disconnect() {198 this.service_.removeRuntime(this);199 this.presentation_provider_.Close();200 if (this.sessionClient_.ptr.isBound()) {201 this.sessionClient_.ptr.reset();202 }203 return Promise.resolve();204 }205 setViews(views) {206 if (views) {207 let changed = false;208 for (let i = 0; i < views.length; i++) {209 if (views[i].eye == 'left') {210 this.displayInfo_.leftEye = this.getEye(views[i]);211 changed = true;212 } else if (views[i].eye == 'right') {213 this.displayInfo_.rightEye = this.getEye(views[i]);214 changed = true;215 }216 }217 if (changed && this.sessionClient_.ptr.isBound()) {218 this.sessionClient_.onChanged(this.displayInfo_);219 }220 }221 }222 setViewerOrigin(origin, emulatedPosition = false) {223 let p = origin.position;224 let q = origin.orientation;225 this.pose_ = {226 orientation: { x: q[0], y: q[1], z: q[2], w: q[3] },227 position: { x: p[0], y: p[1], z: p[2] },228 angularVelocity: null,229 linearVelocity: null,230 angularAcceleration: null,231 linearAcceleration: null,232 inputState: null,233 poseIndex: 0234 };235 }236 clearViewerOrigin() {237 this.pose_ = null;238 }239 simulateVisibilityChange(visibilityState) {240 // TODO(https://crbug.com/982099): Chrome currently does not have a way for241 // devices to bubble up any form of visibilityChange.242 }243 setBoundsGeometry(bounds) {244 if (bounds == null) {245 this.bounds_ = null;246 } else if (bounds.length < 3) {247 throw new Error("Bounds must have a length of at least 3");248 } else {249 this.bounds_ = bounds;250 }251 // We can only set bounds if we have stageParameters set; otherwise, we252 // don't know the transform from local space to bounds space.253 // We'll cache the bounds so that they can be set in the future if the254 // floorLevel transform is set, but we won't update them just yet.255 if (this.displayInfo_.stageParameters) {256 this.displayInfo_.stageParameters.bounds = this.bounds_;257 if (this.sessionClient_.ptr.isBound()) {258 this.sessionClient_.onChanged(this.displayInfo_);259 }260 }261 }262 setFloorOrigin(floorOrigin) {263 if (!this.displayInfo_.stageParameters) {264 this.displayInfo_.stageParameters = default_stage_parameters;265 this.displayInfo_.stageParameters.bounds = this.bounds_;266 }267 this.displayInfo_.stageParameters.standingTransform = new gfx.mojom.Transform();268 this.displayInfo_.stageParameters.standingTransform.matrix =269 getMatrixFromTransform(floorOrigin);270 if (this.sessionClient_.ptr.isBound()) {271 this.sessionClient_.onChanged(this.displayInfo_);272 }273 }274 clearFloorOrigin() {275 if (this.displayInfo_.stageParameters) {276 this.displayInfo_.stageParameters = null;277 if (this.sessionClient_.ptr.isBound()) {278 this.sessionClient_.onChanged(this.displayInfo_);279 }280 }281 }282 simulateResetPose() {283 this.send_pose_reset_ = true;284 }285 simulateInputSourceConnection(fakeInputSourceInit) {286 let index = this.next_input_source_index_;287 this.next_input_source_index_++;288 let source = new MockXRInputSource(fakeInputSourceInit, index, this);289 this.input_sources_.push(source);290 return source;291 }292 // Helper methods293 getNonImmersiveDisplayInfo() {294 let displayInfo = this.getImmersiveDisplayInfo();295 displayInfo.capabilities.canPresent = false;296 displayInfo.leftEye = null;297 displayInfo.rightEye = null;298 return displayInfo;299 }300 // Function to generate some valid display information for the device.301 getImmersiveDisplayInfo() {302 return {303 displayName: 'FakeDevice',304 capabilities: {305 hasPosition: false,306 hasExternalDisplay: false,307 canPresent: true,308 maxLayers: 1309 },310 stageParameters: null,311 leftEye: {312 fieldOfView: {313 upDegrees: 48.316,314 downDegrees: 50.099,315 leftDegrees: 50.899,316 rightDegrees: 35.197317 },318 offset: { x: -0.032, y: 0, z: 0 },319 renderWidth: 20,320 renderHeight: 20321 },322 rightEye: {323 fieldOfView: {324 upDegrees: 48.316,325 downDegrees: 50.099,326 leftDegrees: 50.899,327 rightDegrees: 35.197328 },329 offset: { x: 0.032, y: 0, z: 0 },330 renderWidth: 20,331 renderHeight: 20332 },333 webxrDefaultFramebufferScale: 0.7,334 };335 }336 // This function converts between the matrix provided by the WebXR test API337 // and the internal data representation.338 getEye(fakeXRViewInit) {339 let m = fakeXRViewInit.projectionMatrix;340 function toDegrees(tan) {341 return Math.atan(tan) * 180 / Math.PI;342 }343 let xScale = m[0];344 let yScale = m[5];345 let near = m[14] / (m[10] - 1);346 let far = m[14] / (m[10] - 1);347 let leftTan = (1 - m[8]) / m[0];348 let rightTan = (1 + m[8]) / m[0];349 let upTan = (1 + m[9]) / m[5];350 let downTan = (1 - m[9]) / m[5];351 let offset = fakeXRViewInit.viewOffset.position;352 return {353 fieldOfView: {354 upDegrees: toDegrees(upTan),355 downDegrees: toDegrees(downTan),356 leftDegrees: toDegrees(leftTan),357 rightDegrees: toDegrees(rightTan)358 },359 offset: { x: offset[0], y: offset[1], z: offset[2] },360 renderWidth: fakeXRViewInit.resolution.width,361 renderHeight: fakeXRViewInit.resolution.height362 };363 }364 // These methods are intended to be used by MockXRInputSource only.365 addInputSource(source) {366 let index = this.input_sources_.indexOf(source);367 if (index == -1) {368 this.input_sources_.push(source);369 }370 }371 removeInputSource(source) {372 let index = this.input_sources_.indexOf(source);373 if (index >= 0) {374 this.input_sources_.splice(index, 1);375 }376 }377 // Mojo function implementations.378 // XRFrameDataProvider implementation.379 getFrameData() {380 if (this.pose_) {381 this.pose_.poseIndex++;382 this.pose_.poseReset = this.send_pose_reset_;383 this.send_pose_reset_ = false;384 // Setting the input_state to null tests a slightly different path than385 // the browser tests where if the last input source is removed, the device386 // code always sends up an empty array, but it's also valid mojom to send387 // up a null array.388 if (this.input_sources_.length > 0) {389 this.pose_.inputState = [];390 for (let i = 0; i < this.input_sources_.length; i++) {391 this.pose_.inputState.push(this.input_sources_[i].getInputSourceState());392 }393 } else {394 this.pose_.inputState = null;395 }396 }397 // Convert current document time to monotonic time.398 let now = window.performance.now() / 1000.0;399 let diff = now - internals.monotonicTimeToZeroBasedDocumentTime(now);400 now += diff;401 now *= 1000000;402 return Promise.resolve({403 frameData: {404 pose: this.pose_,405 timeDelta: {406 microseconds: now,407 },408 frameId: this.next_frame_id_++,409 bufferHolder: null,410 bufferSize: {}411 }412 });413 }414 getEnvironmentIntegrationProvider(environmentProviderRequest) {415 this.environmentProviderBinding_ = new mojo.AssociatedBinding(416 device.mojom.XREnvironmentIntegrationProvider, this,417 environmentProviderRequest);418 }419 // Note that if getEnvironmentProvider hasn't finished running yet this will420 // be undefined. It's recommended that you allow a successful task to post421 // first before attempting to close.422 closeEnvironmentIntegrationProvider() {423 this.environmentProviderBinding_.close();424 }425 closeDataProvider() {426 this.dataProviderBinding_.close();427 }428 updateSessionGeometry(frame_size, display_rotation) {429 // This function must exist to ensure that calls to it do not crash, but we430 // do not have any use for this data at present.431 }432 // Utility function433 requestRuntimeSession(sessionOptions) {434 return this.runtimeSupportsSession(sessionOptions).then((result) => {435 // The JavaScript bindings convert c_style_names to camelCase names.436 let options = new device.mojom.XRPresentationTransportOptions();437 options.transportMethod =438 device.mojom.XRPresentationTransportMethod.SUBMIT_AS_MAILBOX_HOLDER;439 options.waitForTransferNotification = true;440 options.waitForRenderNotification = true;441 let submit_frame_sink;442 if (result.supportsSession) {443 submit_frame_sink = {444 clientRequest: this.presentation_provider_.getClientRequest(),445 provider: this.presentation_provider_.bindProvider(sessionOptions),446 transportOptions: options447 };448 let dataProviderPtr = new device.mojom.XRFrameDataProviderPtr();449 let dataProviderRequest = mojo.makeRequest(dataProviderPtr);450 this.dataProviderBinding_ = new mojo.Binding(451 device.mojom.XRFrameDataProvider, this, dataProviderRequest);452 let clientRequest = mojo.makeRequest(this.sessionClient_);453 return Promise.resolve({454 session: {455 submitFrameSink: submit_frame_sink,456 dataProvider: dataProviderPtr,457 clientRequest: clientRequest,458 displayInfo: this.displayInfo_459 }460 });461 } else {462 return Promise.resolve({session: null});463 }464 });465 }466 runtimeSupportsSession(options) {467 return Promise.resolve({468 supportsSession:469 !options.immersive || this.displayInfo_.capabilities.canPresent470 });471 };472}473class MockXRInputSource {474 constructor(fakeInputSourceInit, id, pairedDevice) {475 this.source_id_ = id;476 this.pairedDevice_ = pairedDevice;477 this.handedness_ = fakeInputSourceInit.handedness;478 this.target_ray_mode_ = fakeInputSourceInit.targetRayMode;479 this.setPointerOrigin(fakeInputSourceInit.pointerOrigin);480 this.primary_input_pressed_ = false;481 if (fakeInputSourceInit.selectionStarted != null) {482 this.primary_input_pressed_ = fakeInputSourceInit.selectionStarted;483 }484 this.primary_input_clicked_ = false;485 if (fakeInputSourceInit.selectionClicked != null) {486 this.primary_input_clicked_ = fakeInputSourceInit.selectionClicked;487 }488 this.grip_ = null;489 if (fakeInputSourceInit.gripOrigin != null) {490 this.setGripOrigin(fakeInputSourceInit.gripOrigin);491 }492 // This properly handles if supportedButtons were not specified.493 this.setSupportedButtons(fakeInputSourceInit.supportedButtons);494 this.emulated_position_ = false;495 this.desc_dirty_ = true;496 }497 // Webxr-test-api498 setHandedness(handedness) {499 if (this.handedness_ != handedness) {500 this.desc_dirty_ = true;501 this.handedness_ = handedness;502 }503 }504 setTargetRayMode(targetRayMode) {505 if (this.target_ray_mode_ != targetRayMode) {506 this.desc_dirty_ = true;507 this.target_ray_mode_ = targetRayMode;508 }509 }510 setProfiles(profiles) {511 // Profiles are not yet implemented by chromium512 }513 setGripOrigin(transform, emulatedPosition = false) {514 this.grip_ = new gfx.mojom.Transform();515 this.grip_.matrix = getMatrixFromTransform(transform);516 this.emulated_position_ = emulatedPosition;517 }518 clearGripOrigin() {519 if (this.grip_ != null) {520 this.grip_ = null;521 this.emulated_position_ = false;522 }523 }524 setPointerOrigin(transform, emulatedPosition = false) {525 this.desc_dirty_ = true;526 this.pointer_offset_ = new gfx.mojom.Transform();527 this.pointer_offset_.matrix = getMatrixFromTransform(transform);528 }529 disconnect() {530 this.pairedDevice_.removeInputSource(this);531 }532 reconnect() {533 this.pairedDevice_.addInputSource(this);534 }535 startSelection() {536 this.primary_input_pressed_ = true;537 if (this.gamepad_) {538 this.gamepad_.buttons[0].pressed = true;539 this.gamepad_.buttons[0].touched = true;540 }541 }542 endSelection() {543 if (!this.primary_input_pressed_) {544 throw new Error("Attempted to end selection which was not started");545 }546 this.primary_input_pressed_ = false;547 this.primary_input_clicked_ = true;548 if (this.gamepad_) {549 this.gamepad_.buttons[0].pressed = false;550 this.gamepad_.buttons[0].touched = false;551 }552 }553 simulateSelect() {554 this.primary_input_clicked_ = true;555 }556 setSupportedButtons(supportedButtons) {557 this.gamepad_ = null;558 this.supported_buttons_ = [];559 // If there are no supported buttons, we can stop now.560 if (supportedButtons == null || supportedButtons.length < 1) {561 return;562 }563 let supported_button_map = {};564 this.gamepad_ = this.getEmptyGamepad();565 for (let i = 0; i < supportedButtons.length; i++) {566 let buttonType = supportedButtons[i].buttonType;567 this.supported_buttons_.push(buttonType);568 supported_button_map[buttonType] = supportedButtons[i];569 }570 // Let's start by building the button state in order of priority:571 // Primary button is index 0.572 this.gamepad_.buttons.push({573 pressed: this.primary_input_pressed_,574 touched: this.primary_input_pressed_,575 value: this.primary_input_pressed_ ? 1.0 : 0.0576 });577 // Now add the rest of our buttons578 this.addGamepadButton(supported_button_map['grip']);579 this.addGamepadButton(supported_button_map['touchpad']);580 this.addGamepadButton(supported_button_map['thumbstick']);581 this.addGamepadButton(supported_button_map['optional-button']);582 this.addGamepadButton(supported_button_map['optional-thumbstick']);583 // Finally, back-fill placeholder buttons/axes584 for (let i = 0; i < this.gamepad_.buttons.length; i++) {585 if (this.gamepad_.buttons[i] == null) {586 this.gamepad_.buttons[i] = {587 pressed: false,588 touched: false,589 value: 0590 }591 }592 }593 for (let i=0; i < this.gamepad_.axes.length; i++) {594 if (this.gamepad_.axes[i] == null) {595 this.gamepad_.axes[i] = 0;596 }597 }598 }599 updateButtonState(buttonState) {600 if (this.supported_buttons_.indexOf(buttonState.buttonType) == -1) {601 throw new Error("Tried to update state on an unsupported button");602 }603 let buttonIndex = this.getButtonIndex(buttonState.buttonType);604 let axesStartIndex = this.getAxesStartIndex(buttonState.buttonType);605 if (buttonIndex == -1) {606 throw new Error("Unknown Button Type!");607 }608 this.gamepad_.buttons[buttonIndex].pressed = buttonState.pressed;609 this.gamepad_.buttons[buttonIndex].touched = buttonState.touched;610 this.gamepad_.buttons[buttonIndex].value = buttonState.pressedValue;611 if (axesStartIndex != -1) {612 this.gamepad_.axes[axesStartIndex] = buttonState.xValue == null ? 0.0 : buttonState.xValue;613 this.gamepad_.axes[axesStartIndex + 1] = buttonState.yValue == null ? 0.0 : buttonState.yValue;614 }615 }616 // Helpers for Mojom617 getInputSourceState() {618 let input_state = new device.mojom.XRInputSourceState();619 input_state.sourceId = this.source_id_;620 input_state.primaryInputPressed = this.primary_input_pressed_;621 input_state.primaryInputClicked = this.primary_input_clicked_;622 input_state.grip = this.grip_;623 input_state.gamepad = this.gamepad_;624 if (this.desc_dirty_) {625 let input_desc = new device.mojom.XRInputSourceDescription();626 input_desc.emulatedPosition = this.emulated_position_;627 switch (this.target_ray_mode_) {628 case 'gaze':629 input_desc.targetRayMode = device.mojom.XRTargetRayMode.GAZING;630 break;631 case 'tracked-pointer':632 input_desc.targetRayMode = device.mojom.XRTargetRayMode.POINTING;633 break;634 }635 switch (this.handedness_) {636 case 'left':637 input_desc.handedness = device.mojom.XRHandedness.LEFT;638 break;639 case 'right':640 input_desc.handedness = device.mojom.XRHandedness.RIGHT;641 break;642 default:643 input_desc.handedness = device.mojom.XRHandedness.NONE;644 break;645 }646 input_desc.pointerOffset = this.pointer_offset_;647 input_state.description = input_desc;648 this.desc_dirty_ = false;649 }650 return input_state;651 }652 getEmptyGamepad() {653 // Mojo complains if some of the properties on Gamepad are null, so set654 // everything to reasonable defaults that tests can override.655 let gamepad = new device.mojom.Gamepad();656 gamepad.connected = true;657 gamepad.id = "";658 gamepad.timestamp = 0;659 gamepad.axes = [];660 gamepad.buttons = [];661 gamepad.mapping = "xr-standard";662 gamepad.display_id = 0;663 switch (this.handedness_) {664 case 'left':665 gamepad.hand = device.mojom.GamepadHand.GamepadHandLeft;666 break;667 case 'right':668 gamepad.hand = device.mojom.GamepadHand.GamepadHandRight;669 break;670 default:671 gamepad.hand = device.mojom.GamepadHand.GamepadHandNone;672 break;673 }674 return gamepad;675 }676 addGamepadButton(buttonState) {677 if (buttonState == null) {678 return;679 }680 let buttonIndex = this.getButtonIndex(buttonState.buttonType);681 let axesStartIndex = this.getAxesStartIndex(buttonState.buttonType);682 if (buttonIndex == -1) {683 throw new Error("Unknown Button Type!");684 }685 this.gamepad_.buttons[buttonIndex] = {686 pressed: buttonState.pressed,687 touched: buttonState.touched,688 value: buttonState.pressedValue689 };690 // Add x/y value if supported.691 if (axesStartIndex != -1) {692 this.gamepad_.axes[axesStartIndex] = (buttonState.xValue == null ? 0.0 : buttonSate.xValue);693 this.gamepad_.axes[axesStartIndex + 1] = (buttonState.yValue == null ? 0.0 : buttonSate.yValue);694 }695 }696 // General Helper methods697 getButtonIndex(buttonType) {698 switch (buttonType) {699 case 'grip':700 return 1;701 case 'touchpad':702 return 2;703 case 'thumbstick':704 return 3;705 case 'optional-button':706 return 4;707 case 'optional-thumbstick':708 return 5;709 default:710 return -1;711 }712 }713 getAxesStartIndex(buttonType) {714 switch (buttonType) {715 case 'touchpad':716 return 0;717 case 'thumbstick':718 return 2;719 case 'optional-thumbstick':720 return 4;721 default:722 return -1;723 }724 }725}726// Mojo helper classes727class MockXRPresentationProvider {728 constructor() {729 this.binding_ = new mojo.Binding(device.mojom.XRPresentationProvider, this);730 this.submit_frame_count_ = 0;731 this.missing_frame_count_ = 0;732 }733 bindProvider(request) {734 let providerPtr = new device.mojom.XRPresentationProviderPtr();735 let providerRequest = mojo.makeRequest(providerPtr);736 this.binding_.close();737 this.binding_ = new mojo.Binding(738 device.mojom.XRPresentationProvider, this, providerRequest);739 return providerPtr;740 }741 getClientRequest() {742 this.submitFrameClient_ = new device.mojom.XRPresentationClientPtr();743 return mojo.makeRequest(this.submitFrameClient_);744 }745 // XRPresentationProvider mojo implementation746 submitFrameMissing(frameId, mailboxHolder, timeWaited) {747 this.missing_frame_count_++;748 }749 submitFrame(frameId, mailboxHolder, timeWaited) {750 this.submit_frame_count_++;751 // Trigger the submit completion callbacks here. WARNING: The752 // Javascript-based mojo mocks are *not* re-entrant. It's OK to753 // wait for these notifications on the next frame, but waiting754 // within the current frame would never finish since the incoming755 // calls would be queued until the current execution context finishes.756 this.submitFrameClient_.onSubmitFrameTransferred(true);757 this.submitFrameClient_.onSubmitFrameRendered();758 }759 // Utility methods760 Close() {761 this.binding_.close();762 }763}764// This is a temporary workaround for the fact that spinning up webxr before765// the mojo interceptors are created will cause the interceptors to not get766// registered, so we have to create this before we query xr;767let XRTest = new ChromeXRTest();768// This test API is also used to run Chrome's internal legacy VR tests; however,769// those fail if navigator.xr has been used. Those tests will set a bool telling770// us not to try to check navigator.xr771if ((typeof legacy_vr_test === 'undefined') || !legacy_vr_test) {772 // Some tests may run in the http context where navigator.xr isn't exposed773 // This should just be to test that it isn't exposed, but don't try to set up774 // the test framework in this case.775 if (navigator.xr) {776 navigator.xr.test = XRTest;777 }778} else {779 navigator.vr = { test: XRTest };...
Using AI Code Generation
1wptChart.axesStartIndex(1);2wptChart.axesEndIndex(1);3wptChart.axesStartValue(1, 10);4wptChart.axesEndValue(1, 10);5wptChart.axesLabel(1, "label");6wptChart.axesLabelFormat(1, "d");7wptChart.axesLabelAngle(1, 30);8wptChart.axesLabelPosition(1, "right");9wptChart.axesLabelColor(1, "#000000");10wptChart.axesLabelSize(1, 10);11wptChart.axesLabelFont(1, "Arial");12wptChart.axesLabelFontStyle(1, "normal");13wptChart.axesLabelFontWeight(1, "normal");14wptChart.axesLabelFontVariant(1, "normal");15wptChart.axesMajorTickColor(1, "#000000");16wptChart.axesMajorTickSize(1, 10);
Using AI Code Generation
1var chart = new WptChart();2chart.axesStartIndex(0);3chart.render();4var chart = new WptChart();5chart.axesStartIndex(1);6chart.render();7var chart = new WptChart();8chart.axesStartIndex(2);9chart.render();10var chart = new WptChart();11chart.axesStartIndex(3);12chart.render();13var chart = new WptChart();14chart.axesStartIndex(4);15chart.render();16var chart = new WptChart();17chart.axesStartIndex(5);18chart.render();19var chart = new WptChart();20chart.axesStartIndex(6);21chart.render();22var chart = new WptChart();23chart.axesStartIndex(7);24chart.render();25var chart = new WptChart();26chart.axesStartIndex(8);27chart.render();28var chart = new WptChart();29chart.axesStartIndex(9);30chart.render();31var chart = new WptChart();32chart.axesStartIndex(10);33chart.render();34var chart = new WptChart();35chart.axesStartIndex(11);36chart.render();37var chart = new WptChart();38chart.axesStartIndex(12);39chart.render();40var chart = new WptChart();41chart.axesStartIndex(13);
Using AI Code Generation
1var myChart = new wptChart();2myChart.axesStartIndex(1);3myChart.axesStartIndex(0);4myChart.axesStartIndex(2);5var myChart = new wptChart();6myChart.axesStartIndex(1);7myChart.axesStartIndex(0);8myChart.axesStartIndex(2);9var myChart = new wptChart();10myChart.axesStartIndex(1);11myChart.axesStartIndex(0);12myChart.axesStartIndex(2);13var myChart = new wptChart();14myChart.axesStartIndex(1);15myChart.axesStartIndex(0);16myChart.axesStartIndex(2);17var myChart = new wptChart();18myChart.axesStartIndex(1);19myChart.axesStartIndex(0);20myChart.axesStartIndex(2);21var myChart = new wptChart();22myChart.axesStartIndex(1);23myChart.axesStartIndex(0);24myChart.axesStartIndex(2);25var myChart = new wptChart();26myChart.axesStartIndex(1);27myChart.axesStartIndex(0);28myChart.axesStartIndex(2);29var myChart = new wptChart();30myChart.axesStartIndex(1);31myChart.axesStartIndex(0);32myChart.axesStartIndex(2);33var myChart = new wptChart();34myChart.axesStartIndex(1);35myChart.axesStartIndex(0);36myChart.axesStartIndex(2);37var myChart = new wptChart();38myChart.axesStartIndex(1);
Using AI Code Generation
1var chart = new wptChart();2chart.axesStartIndex(1,1);3var chart = new wptChart();4chart.axesStartIndex(1,1);5var chart = new wptChart();6chart.axesStartIndex(1,1);7var chart = new wptChart();8chart.axesStartIndex(1,1);9var chart = new wptChart();10chart.axesStartIndex(1,1);11var chart = new wptChart();12chart.axesStartIndex(1,1);13var chart = new wptChart();14chart.axesStartIndex(1,1);15var chart = new wptChart();16chart.axesStartIndex(1,1);17var chart = new wptChart();18chart.axesStartIndex(1,1);19var chart = new wptChart();20chart.axesStartIndex(1,1);
Using AI Code Generation
1var chartObj = FusionCharts("chart1");2chartObj.axesStartIndex("xaxis", 1);3chartObj.axesStartIndex("yaxis", 1);4chartObj.axesStartIndex(axisName, startIndex);5var chartObj = FusionCharts("chart1");6chartObj.axesStartIndex("xaxis", 1);7chartObj.axesStartIndex("yaxis", 1);
Using AI Code Generation
1var chart;2 {x: 1, y: 10},3 {x: 2, y: 20},4 {x: 3, y: 30},5 {x: 4, y: 40},6 {x: 5, y: 50},7 {x: 6, y: 60},8 {x: 7, y: 70},9 {x: 8, y: 80},10 {x: 9, y: 90},11 {x: 10, y: 100}12];13function loadChart() {14 chart = new wptchart.Chart("chartContainer");15 chart.setChartType("line");16 chart.setData(chartData);17 chart.render();18}19function getAxesStartIndex() {20 alert("Axes start index: " + chart.axesStartIndex());21}22function getAxesEndIndex() {23 alert("Axes end index: " + chart.axesEndIndex());24}25function getVisibleAxesStartIndex() {26 alert("Visible axes start index: " + chart.visibleAxesStartIndex());27}28function getVisibleAxesEndIndex() {29 alert("Visible axes end index: " + chart.visibleAxesEndIndex());30}31function getVisibleDataStartIndex() {32 alert("Visible data start index: " + chart.visibleDataStartIndex());33}34function getVisibleDataEndIndex() {35 alert("Visible data end index: " + chart.visibleDataEndIndex());36}37function getVisibleDataPoints() {38 var visibleDataPoints = chart.visibleDataPoints();39 var visibleDataPointsString = "";40 for (var i = 0; i < visibleDataPoints.length; i++) {41";42 }43 alert("Visible data points: " + visibleDataPointsString);44}45function getVisibleDataPointsFromIndex() {46 var visibleDataPoints = chart.visibleDataPoints(3);47 var visibleDataPointsString = "";48 for (var i = 0; i < visibleDataPoints.length; i++) {49";50 }51 alert("Visible data points
Using AI Code Generation
1var myChart = new wptChart();2var data = new Array();3data[0] = 10;4data[1] = 20;5data[2] = 30;6data[3] = 40;7data[4] = 50;8myChart.addSeries(data);9myChart.axesStartIndex(2);10myChart.render("chart1");
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!