Best JavaScript code snippet using wpt
webxr-test.js
Source:webxr-test.js
...251 }252 _markProcessed() {253 this.dirty_ = false;254 }255 _getAnchorOrigin() {256 return this.anchorOrigin_;257 }258}259// Implements XRFrameDataProvider and XRPresentationProvider. Maintains a mock260// for XRPresentationProvider. Implements FakeXRDevice test API.261class MockRuntime {262 // Mapping from string feature names to the corresponding mojo types.263 // This is exposed as a member for extensibility.264 static _featureToMojoMap = {265 'viewer': vrMojom.XRSessionFeature.REF_SPACE_VIEWER,266 'local': vrMojom.XRSessionFeature.REF_SPACE_LOCAL,267 'local-floor': vrMojom.XRSessionFeature.REF_SPACE_LOCAL_FLOOR,268 'bounded-floor': vrMojom.XRSessionFeature.REF_SPACE_BOUNDED_FLOOR,269 'unbounded': vrMojom.XRSessionFeature.REF_SPACE_UNBOUNDED,270 'hit-test': vrMojom.XRSessionFeature.HIT_TEST,271 'dom-overlay': vrMojom.XRSessionFeature.DOM_OVERLAY,272 'light-estimation': vrMojom.XRSessionFeature.LIGHT_ESTIMATION,273 'anchors': vrMojom.XRSessionFeature.ANCHORS,274 'depth-sensing': vrMojom.XRSessionFeature.DEPTH,275 'secondary-views': vrMojom.XRSessionFeature.SECONDARY_VIEWS,276 };277 static _sessionModeToMojoMap = {278 "inline": vrMojom.XRSessionMode.kInline,279 "immersive-vr": vrMojom.XRSessionMode.kImmersiveVr,280 "immersive-ar": vrMojom.XRSessionMode.kImmersiveAr,281 };282 static _environmentBlendModeToMojoMap = {283 "opaque": vrMojom.XREnvironmentBlendMode.kOpaque,284 "alpha-blend": vrMojom.XREnvironmentBlendMode.kAlphaBlend,285 "additive": vrMojom.XREnvironmentBlendMode.kAdditive,286 };287 static _interactionModeToMojoMap = {288 "screen-space": vrMojom.XRInteractionMode.kScreenSpace,289 "world-space": vrMojom.XRInteractionMode.kWorldSpace,290 };291 constructor(fakeDeviceInit, service) {292 this.sessionClient_ = null;293 this.presentation_provider_ = new MockXRPresentationProvider();294 this.pose_ = null;295 this.next_frame_id_ = 0;296 this.bounds_ = null;297 this.send_mojo_space_reset_ = false;298 this.stageParameters_ = null;299 this.stageParametersId_ = 1;300 this.service_ = service;301 this.framesOfReference = {};302 this.input_sources_ = new Map();303 this.next_input_source_index_ = 1;304 // Currently active hit test subscriptons.305 this.hitTestSubscriptions_ = new Map();306 // Currently active transient hit test subscriptions.307 this.transientHitTestSubscriptions_ = new Map();308 // ID of the next subscription to be assigned.309 this.next_hit_test_id_ = 1n;310 this.anchor_controllers_ = new Map();311 // ID of the next anchor to be assigned.312 this.next_anchor_id_ = 1n;313 // Anchor creation callback (initially null, can be set by tests).314 this.anchor_creation_callback_ = null;315 this.depthSensingData_ = null;316 this.depthSensingDataDirty_ = false;317 let supportedModes = [];318 if (fakeDeviceInit.supportedModes) {319 supportedModes = fakeDeviceInit.supportedModes.slice();320 if (fakeDeviceInit.supportedModes.length === 0) {321 supportedModes = ["inline"];322 }323 } else {324 // Back-compat mode.325 console.warn("Please use `supportedModes` to signal which modes are supported by this device.");326 if (fakeDeviceInit.supportsImmersive == null) {327 throw new TypeError("'supportsImmersive' must be set");328 }329 supportedModes = ["inline"];330 if (fakeDeviceInit.supportsImmersive) {331 supportedModes.push("immersive-vr");332 }333 }334 this.supportedModes_ = this._convertModesToEnum(supportedModes);335 // Initialize DisplayInfo first to set the defaults, then override with336 // anything from the deviceInit337 if (this.supportedModes_.includes(vrMojom.XRSessionMode.kImmersiveVr) ||338 this.supportedModes_.includes(vrMojom.XRSessionMode.kImmersiveAr)) {339 this.displayInfo_ = this._getImmersiveDisplayInfo();340 } else if (this.supportedModes_.includes(vrMojom.XRSessionMode.kInline)) {341 this.displayInfo_ = this._getNonImmersiveDisplayInfo();342 } else {343 // This should never happen!344 console.error("Device has empty supported modes array!");345 throw new InvalidStateError();346 }347 if (fakeDeviceInit.viewerOrigin != null) {348 this.setViewerOrigin(fakeDeviceInit.viewerOrigin);349 }350 if (fakeDeviceInit.floorOrigin != null) {351 this.setFloorOrigin(fakeDeviceInit.floorOrigin);352 }353 if (fakeDeviceInit.world) {354 this.setWorld(fakeDeviceInit.world);355 }356 if (fakeDeviceInit.depthSensingData) {357 this.setDepthSensingData(fakeDeviceInit.depthSensingData);358 }359 this.defaultFramebufferScale_ = default_framebuffer_scale;360 this.enviromentBlendMode_ = this._convertBlendModeToEnum(fakeDeviceInit.environmentBlendMode);361 this.interactionMode_ = this._convertInteractionModeToEnum(fakeDeviceInit.interactionMode);362 // This appropriately handles if the coordinates are null363 this.setBoundsGeometry(fakeDeviceInit.boundsCoordinates);364 this.setViews(fakeDeviceInit.views, fakeDeviceInit.secondaryViews);365 // Need to support webVR which doesn't have a notion of features366 this._setFeatures(fakeDeviceInit.supportedFeatures || []);367 }368 // WebXR Test API369 setViews(primaryViews, secondaryViews) {370 this.primaryViews_ = [];371 this.secondaryViews_ = [];372 let xOffset = 0;373 if (primaryViews) {374 this.primaryViews_ = [];375 xOffset = this._setViews(primaryViews, xOffset, this.primaryViews_);376 }377 if (secondaryViews) {378 this.secondaryViews_ = [];379 this._setViews(secondaryViews, xOffset, this.secondaryViews_);380 }381 // Do not include secondary views here because they are only exposed to382 // WebXR if requested by the session. getFrameData() will send back the383 // secondary views when enabled.384 this.displayInfo_.views = this.primaryViews_;385 if (this.sessionClient_) {386 this.sessionClient_.onChanged(this.displayInfo_);387 }388 }389 disconnect() {390 this.service_._removeRuntime(this);391 this.presentation_provider_._close();392 if (this.sessionClient_) {393 this.sessionClient_.$.close();394 this.sessionClient_ = null;395 }396 return Promise.resolve();397 }398 setViewerOrigin(origin, emulatedPosition = false) {399 const p = origin.position;400 const q = origin.orientation;401 this.pose_ = {402 orientation: { x: q[0], y: q[1], z: q[2], w: q[3] },403 position: { x: p[0], y: p[1], z: p[2] },404 emulatedPosition: emulatedPosition,405 angularVelocity: null,406 linearVelocity: null,407 angularAcceleration: null,408 linearAcceleration: null,409 inputState: null,410 poseIndex: 0411 };412 }413 clearViewerOrigin() {414 this.pose_ = null;415 }416 setFloorOrigin(floorOrigin) {417 if (!this.stageParameters_) {418 this.stageParameters_ = default_stage_parameters;419 this.stageParameters_.bounds = this.bounds_;420 }421 // floorOrigin is passed in as mojoFromFloor.422 this.stageParameters_.mojoFromFloor =423 {matrix: getMatrixFromTransform(floorOrigin)};424 this._onStageParametersUpdated();425 }426 clearFloorOrigin() {427 if (this.stageParameters_) {428 this.stageParameters_ = null;429 this._onStageParametersUpdated();430 }431 }432 setBoundsGeometry(bounds) {433 if (bounds == null) {434 this.bounds_ = null;435 } else if (bounds.length < 3) {436 throw new Error("Bounds must have a length of at least 3");437 } else {438 this.bounds_ = bounds;439 }440 // We can only set bounds if we have stageParameters set; otherwise, we441 // don't know the transform from local space to bounds space.442 // We'll cache the bounds so that they can be set in the future if the443 // floorLevel transform is set, but we won't update them just yet.444 if (this.stageParameters_) {445 this.stageParameters_.bounds = this.bounds_;446 this._onStageParametersUpdated();447 }448 }449 simulateResetPose() {450 this.send_mojo_space_reset_ = true;451 }452 simulateVisibilityChange(visibilityState) {453 let mojoState = null;454 switch (visibilityState) {455 case "visible":456 mojoState = vrMojom.XRVisibilityState.VISIBLE;457 break;458 case "visible-blurred":459 mojoState = vrMojom.XRVisibilityState.VISIBLE_BLURRED;460 break;461 case "hidden":462 mojoState = vrMojom.XRVisibilityState.HIDDEN;463 break;464 }465 if (mojoState && this.sessionClient_) {466 this.sessionClient_.onVisibilityStateChanged(mojoState);467 }468 }469 simulateInputSourceConnection(fakeInputSourceInit) {470 const index = this.next_input_source_index_;471 this.next_input_source_index_++;472 const source = new MockXRInputSource(fakeInputSourceInit, index, this);473 this.input_sources_.set(index, source);474 return source;475 }476 // WebXR Test API Hit Test extensions477 setWorld(world) {478 this.world_ = world;479 }480 clearWorld() {481 this.world_ = null;482 }483 // WebXR Test API Anchor extensions484 setAnchorCreationCallback(callback) {485 this.anchor_creation_callback_ = callback;486 }487 setHitTestSourceCreationCallback(callback) {488 this.hit_test_source_creation_callback_ = callback;489 }490 // WebXR Test API Lighting estimation extensions491 setLightEstimate(fakeXrLightEstimateInit) {492 if (!fakeXrLightEstimateInit.sphericalHarmonicsCoefficients) {493 throw new TypeError("sphericalHarmonicsCoefficients must be set");494 }495 if (fakeXrLightEstimateInit.sphericalHarmonicsCoefficients.length != 27) {496 throw new TypeError("Must supply all 27 sphericalHarmonicsCoefficients");497 }498 if (fakeXrLightEstimateInit.primaryLightDirection && fakeXrLightEstimateInit.primaryLightDirection.w != 0) {499 throw new TypeError("W component of primaryLightDirection must be 0");500 }501 if (fakeXrLightEstimateInit.primaryLightIntensity && fakeXrLightEstimateInit.primaryLightIntensity.w != 1) {502 throw new TypeError("W component of primaryLightIntensity must be 1");503 }504 // If the primaryLightDirection or primaryLightIntensity aren't set, we need to set them505 // to the defaults that the spec expects. ArCore will either give us everything or nothing,506 // so these aren't nullable on the mojom.507 if (!fakeXrLightEstimateInit.primaryLightDirection) {508 fakeXrLightEstimateInit.primaryLightDirection = { x: 0.0, y: 1.0, z: 0.0, w: 0.0 };509 }510 if (!fakeXrLightEstimateInit.primaryLightIntensity) {511 fakeXrLightEstimateInit.primaryLightIntensity = { x: 0.0, y: 0.0, z: 0.0, w: 1.0 };512 }513 let c = fakeXrLightEstimateInit.sphericalHarmonicsCoefficients;514 this.light_estimate_ = {515 lightProbe: {516 // XRSphereicalHarmonics517 sphericalHarmonics: {518 coefficients: [519 { red: c[0], green: c[1], blue: c[2] },520 { red: c[3], green: c[4], blue: c[5] },521 { red: c[6], green: c[7], blue: c[8] },522 { red: c[9], green: c[10], blue: c[11] },523 { red: c[12], green: c[13], blue: c[14] },524 { red: c[15], green: c[16], blue: c[17] },525 { red: c[18], green: c[19], blue: c[20] },526 { red: c[21], green: c[22], blue: c[23] },527 { red: c[24], green: c[25], blue: c[26] }528 ]529 },530 // Vector3dF531 mainLightDirection: {532 x: fakeXrLightEstimateInit.primaryLightDirection.x,533 y: fakeXrLightEstimateInit.primaryLightDirection.y,534 z: fakeXrLightEstimateInit.primaryLightDirection.z535 },536 // RgbTupleF32537 mainLightIntensity: {538 red: fakeXrLightEstimateInit.primaryLightIntensity.x,539 green: fakeXrLightEstimateInit.primaryLightIntensity.y,540 blue: fakeXrLightEstimateInit.primaryLightIntensity.z541 }542 }543 }544 }545 // WebXR Test API depth Sensing Extensions546 setDepthSensingData(depthSensingData) {547 for(const key of ["depthData", "normDepthBufferFromNormView", "rawValueToMeters", "width", "height"]) {548 if(!(key in depthSensingData)) {549 throw new TypeError("Required key not present. Key: " + key);550 }551 }552 if(depthSensingData.depthData != null) {553 // Create new object w/ properties based on the depthSensingData, but554 // convert the FakeXRRigidTransformInit into a transformation matrix object.555 this.depthSensingData_ = Object.assign({},556 depthSensingData, {557 normDepthBufferFromNormView: composeGFXTransform(depthSensingData.normDepthBufferFromNormView),558 });559 } else {560 throw new TypeError("`depthData` is not set");561 }562 this.depthSensingDataDirty_ = true;563 }564 clearDepthSensingData() {565 this.depthSensingData_ = null;566 this.depthSensingDataDirty_ = true;567 }568 // Internal Implementation/Helper Methods569 _convertModeToEnum(sessionMode) {570 if (sessionMode in MockRuntime._sessionModeToMojoMap) {571 return MockRuntime._sessionModeToMojoMap[sessionMode];572 }573 throw new TypeError("Unrecognized value for XRSessionMode enum: " + sessionMode);574 }575 _convertModesToEnum(sessionModes) {576 return sessionModes.map(mode => this._convertModeToEnum(mode));577 }578 _convertBlendModeToEnum(blendMode) {579 if (blendMode in MockRuntime._environmentBlendModeToMojoMap) {580 return MockRuntime._environmentBlendModeToMojoMap[blendMode];581 } else {582 if (this.supportedModes_.includes(vrMojom.XRSessionMode.kImmersiveAr)) {583 return vrMojom.XREnvironmentBlendMode.kAdditive;584 } else if (this.supportedModes_.includes(585 vrMojom.XRSessionMode.kImmersiveVr)) {586 return vrMojom.XREnvironmentBlendMode.kOpaque;587 }588 }589 }590 _convertInteractionModeToEnum(interactionMode) {591 if (interactionMode in MockRuntime._interactionModeToMojoMap) {592 return MockRuntime._interactionModeToMojoMap[interactionMode];593 } else {594 return vrMojom.XRInteractionMode.kWorldSpace;595 }596 }597 _setViews(deviceViews, xOffset, views) {598 for (let i = 0; i < deviceViews.length; i++) {599 views[i] = this._getView(deviceViews[i], xOffset);600 xOffset += deviceViews[i].resolution.width;601 }602 return xOffset;603 }604 _onStageParametersUpdated() {605 // Indicate for the frame loop that the stage parameters have been updated.606 this.stageParametersId_++;607 }608 _getNonImmersiveDisplayInfo() {609 const displayInfo = this._getImmersiveDisplayInfo();610 displayInfo.capabilities.canPresent = false;611 displayInfo.views = [];612 return displayInfo;613 }614 // Function to generate some valid display information for the device.615 _getImmersiveDisplayInfo() {616 const viewport_size = 20;617 return {618 displayName: 'FakeDevice',619 capabilities: {620 hasPosition: false,621 hasExternalDisplay: false,622 canPresent: true,623 maxLayers: 1624 },625 stageParameters: null,626 views: [{627 eye: vrMojom.XREye.kLeft,628 fieldOfView: {629 upDegrees: 48.316,630 downDegrees: 50.099,631 leftDegrees: 50.899,632 rightDegrees: 35.197633 },634 mojoFromView: this._getMojoFromViewerWithOffset(composeGFXTransform({635 position: [-0.032, 0, 0],636 orientation: [0, 0, 0, 1]637 })),638 viewport: { x: 0, y: 0, width: viewport_size, height: viewport_size }639 },640 {641 eye: vrMojom.XREye.kRight,642 fieldOfView: {643 upDegrees: 48.316,644 downDegrees: 50.099,645 leftDegrees: 50.899,646 rightDegrees: 35.197647 },648 mojoFromView: this._getMojoFromViewerWithOffset(composeGFXTransform({649 position: [0.032, 0, 0],650 orientation: [0, 0, 0, 1]651 })),652 viewport: { x: viewport_size, y: 0, width: viewport_size, height: viewport_size }653 }]654 };655 }656 // This function converts between the matrix provided by the WebXR test API657 // and the internal data representation.658 _getView(fakeXRViewInit, xOffset) {659 let fov = null;660 if (fakeXRViewInit.fieldOfView) {661 fov = {662 upDegrees: fakeXRViewInit.fieldOfView.upDegrees,663 downDegrees: fakeXRViewInit.fieldOfView.downDegrees,664 leftDegrees: fakeXRViewInit.fieldOfView.leftDegrees,665 rightDegrees: fakeXRViewInit.fieldOfView.rightDegrees666 };667 } else {668 const m = fakeXRViewInit.projectionMatrix;669 function toDegrees(tan) {670 return Math.atan(tan) * 180 / Math.PI;671 }672 const leftTan = (1 - m[8]) / m[0];673 const rightTan = (1 + m[8]) / m[0];674 const upTan = (1 + m[9]) / m[5];675 const downTan = (1 - m[9]) / m[5];676 fov = {677 upDegrees: toDegrees(upTan),678 downDegrees: toDegrees(downTan),679 leftDegrees: toDegrees(leftTan),680 rightDegrees: toDegrees(rightTan)681 };682 }683 let viewEye = vrMojom.XREye.kNone;684 // The eye passed in corresponds to the values in the WebXR spec, which are685 // the strings "none", "left", and "right". They should be converted to the686 // corresponding values of XREye in vr_service.mojom.687 switch(fakeXRViewInit.eye) {688 case "none":689 viewEye = vrMojom.XREye.kNone;690 break;691 case "left":692 viewEye = vrMojom.XREye.kLeft;693 break;694 case "right":695 viewEye = vrMojom.XREye.kRight;696 break;697 }698 return {699 eye: viewEye,700 fieldOfView: fov,701 mojoFromView: this._getMojoFromViewerWithOffset(composeGFXTransform(fakeXRViewInit.viewOffset)),702 viewport: {703 x: xOffset,704 y: 0,705 width: fakeXRViewInit.resolution.width,706 height: fakeXRViewInit.resolution.height707 },708 isFirstPersonObserver: fakeXRViewInit.isFirstPersonObserver ? true : false,709 viewOffset: composeGFXTransform(fakeXRViewInit.viewOffset)710 };711 }712 _setFeatures(supportedFeatures) {713 function convertFeatureToMojom(feature) {714 if (feature in MockRuntime._featureToMojoMap) {715 return MockRuntime._featureToMojoMap[feature];716 } else {717 return vrMojom.XRSessionFeature.INVALID;718 }719 }720 this.supportedFeatures_ = [];721 for (let i = 0; i < supportedFeatures.length; i++) {722 const feature = convertFeatureToMojom(supportedFeatures[i]);723 if (feature !== vrMojom.XRSessionFeature.INVALID) {724 this.supportedFeatures_.push(feature);725 }726 }727 }728 // These methods are intended to be used by MockXRInputSource only.729 _addInputSource(source) {730 if (!this.input_sources_.has(source.source_id_)) {731 this.input_sources_.set(source.source_id_, source);732 }733 }734 _removeInputSource(source) {735 this.input_sources_.delete(source.source_id_);736 }737 // These methods are intended to be used by FakeXRAnchorController only.738 _deleteAnchorController(controllerId) {739 this.anchor_controllers_.delete(controllerId);740 }741 // Extension point for non-standard modules.742 _injectAdditionalFrameData(options, frameData) {743 }744 // Mojo function implementations.745 // XRFrameDataProvider implementation.746 getFrameData(options) {747 return new Promise((resolve) => {748 const populatePose = () => {749 const mojo_space_reset = this.send_mojo_space_reset_;750 this.send_mojo_space_reset_ = false;751 if (this.pose_) {752 this.pose_.poseIndex++;753 }754 // Setting the input_state to null tests a slightly different path than755 // the browser tests where if the last input source is removed, the device756 // code always sends up an empty array, but it's also valid mojom to send757 // up a null array.758 let input_state = null;759 if (this.input_sources_.size > 0) {760 input_state = [];761 for (const input_source of this.input_sources_.values()) {762 input_state.push(input_source._getInputSourceState());763 }764 }765 let frame_views = this.primaryViews_;766 for (let i = 0; i < this.primaryViews_.length; i++) {767 this.primaryViews_[i].mojoFromView =768 this._getMojoFromViewerWithOffset(this.primaryViews_[i].viewOffset);769 }770 if (this.enabledFeatures_.includes(vrMojom.XRSessionFeature.SECONDARY_VIEWS)) {771 for (let i = 0; i < this.secondaryViews_.length; i++) {772 this.secondaryViews_[i].mojoFromView =773 this._getMojoFromViewerWithOffset(this.secondaryViews_[i].viewOffset);774 }775 frame_views = frame_views.concat(this.secondaryViews_);776 }777 const frameData = {778 mojoFromViewer: this.pose_,779 views: frame_views,780 mojoSpaceReset: mojo_space_reset,781 inputState: input_state,782 timeDelta: {783 // window.performance.now() is in milliseconds, so convert to microseconds.784 microseconds: BigInt(Math.floor(window.performance.now() * 1000)),785 },786 frameId: this.next_frame_id_,787 bufferHolder: null,788 bufferSize: {},789 renderingTimeRatio: 0,790 stageParameters: this.stageParameters_,791 stageParametersId: this.stageParametersId_,792 lightEstimationData: this.light_estimate_793 };794 this.next_frame_id_++;795 this._calculateHitTestResults(frameData);796 this._calculateAnchorInformation(frameData);797 this._calculateDepthInformation(frameData);798 this._injectAdditionalFrameData(options, frameData);799 resolve({frameData});800 };801 if(this.sessionOptions_.mode == vrMojom.XRSessionMode.kInline) {802 // Inline sessions should not have a delay introduced since it causes them803 // to miss a vsync blink-side and delays propagation of changes that happened804 // within a rAFcb by one frame (e.g. setViewerOrigin() calls would take 2 frames805 // to propagate).806 populatePose();807 } else {808 // For immerive sessions, add additional delay to allow for anchor creation809 // promises to run.810 setTimeout(populatePose, 3); // note: according to MDN, the timeout is not exact811 }812 });813 }814 getEnvironmentIntegrationProvider(environmentProviderRequest) {815 if (this.environmentProviderReceiver_) {816 this.environmentProviderReceiver_.$.close();817 }818 this.environmentProviderReceiver_ =819 new vrMojom.XREnvironmentIntegrationProviderReceiver(this);820 this.environmentProviderReceiver_.$.bindHandle(821 environmentProviderRequest.handle);822 }823 setInputSourceButtonListener(listener) { listener.$.close(); }824 // XREnvironmentIntegrationProvider implementation:825 subscribeToHitTest(nativeOriginInformation, entityTypes, ray) {826 if (!this.supportedModes_.includes(vrMojom.XRSessionMode.kImmersiveAr)) {827 // Reject outside of AR.828 return Promise.resolve({829 result : vrMojom.SubscribeToHitTestResult.FAILURE_GENERIC,830 subscriptionId : 0n831 });832 }833 if (!this._nativeOriginKnown(nativeOriginInformation)) {834 return Promise.resolve({835 result : vrMojom.SubscribeToHitTestResult.FAILURE_GENERIC,836 subscriptionId : 0n837 });838 }839 // Reserve the id for hit test source:840 const id = this.next_hit_test_id_++;841 const hitTestParameters = { isTransient: false, profileName: null };842 const controller = new FakeXRHitTestSourceController(id);843 return this._shouldHitTestSourceCreationSucceed(hitTestParameters, controller)844 .then((succeeded) => {845 if(succeeded) {846 // Store the subscription information as-is (including controller):847 this.hitTestSubscriptions_.set(id, { nativeOriginInformation, entityTypes, ray, controller });848 return Promise.resolve({849 result : vrMojom.SubscribeToHitTestResult.SUCCESS,850 subscriptionId : id851 });852 } else {853 return Promise.resolve({854 result : vrMojom.SubscribeToHitTestResult.FAILURE_GENERIC,855 subscriptionId : 0n856 });857 }858 });859 }860 subscribeToHitTestForTransientInput(profileName, entityTypes, ray){861 if (!this.supportedModes_.includes(vrMojom.XRSessionMode.kImmersiveAr)) {862 // Reject outside of AR.863 return Promise.resolve({864 result : vrMojom.SubscribeToHitTestResult.FAILURE_GENERIC,865 subscriptionId : 0n866 });867 }868 const id = this.next_hit_test_id_++;869 const hitTestParameters = { isTransient: true, profileName: profileName };870 const controller = new FakeXRHitTestSourceController(id);871 // Check if we have hit test source creation callback.872 // If yes, ask it if the hit test source creation should succeed.873 // If no, for back-compat, assume the hit test source creation succeeded.874 return this._shouldHitTestSourceCreationSucceed(hitTestParameters, controller)875 .then((succeeded) => {876 if(succeeded) {877 // Store the subscription information as-is (including controller):878 this.transientHitTestSubscriptions_.set(id, { profileName, entityTypes, ray, controller });879 return Promise.resolve({880 result : vrMojom.SubscribeToHitTestResult.SUCCESS,881 subscriptionId : id882 });883 } else {884 return Promise.resolve({885 result : vrMojom.SubscribeToHitTestResult.FAILURE_GENERIC,886 subscriptionId : 0n887 });888 }889 });890 }891 unsubscribeFromHitTest(subscriptionId) {892 let controller = null;893 if(this.transientHitTestSubscriptions_.has(subscriptionId)){894 controller = this.transientHitTestSubscriptions_.get(subscriptionId).controller;895 this.transientHitTestSubscriptions_.delete(subscriptionId);896 } else if(this.hitTestSubscriptions_.has(subscriptionId)){897 controller = this.hitTestSubscriptions_.get(subscriptionId).controller;898 this.hitTestSubscriptions_.delete(subscriptionId);899 }900 if(controller) {901 controller.deleted = true;902 }903 }904 createAnchor(nativeOriginInformation, nativeOriginFromAnchor) {905 return new Promise((resolve) => {906 if(this.anchor_creation_callback_ == null) {907 resolve({908 result : vrMojom.CreateAnchorResult.FAILURE,909 anchorId : 0n910 });911 return;912 }913 const mojoFromNativeOrigin = this._getMojoFromNativeOrigin(nativeOriginInformation);914 if(mojoFromNativeOrigin == null) {915 resolve({916 result : vrMojom.CreateAnchorResult.FAILURE,917 anchorId : 0n918 });919 return;920 }921 const mojoFromAnchor = XRMathHelper.mul4x4(mojoFromNativeOrigin, nativeOriginFromAnchor);922 const anchorCreationParameters = {923 requestedAnchorOrigin: mojoFromAnchor,924 isAttachedToEntity: false,925 };926 const anchorController = new FakeXRAnchorController();927 this.anchor_creation_callback_(anchorCreationParameters, anchorController)928 .then((result) => {929 if(result) {930 // If the test allowed the anchor creation,931 // store the anchor controller & return success.932 const anchor_id = this.next_anchor_id_;933 this.next_anchor_id_++;934 this.anchor_controllers_.set(anchor_id, anchorController);935 anchorController.device = this;936 anchorController.id = anchor_id;937 resolve({938 result : vrMojom.CreateAnchorResult.SUCCESS,939 anchorId : anchor_id940 });941 } else {942 // The test has rejected anchor creation.943 resolve({944 result : vrMojom.CreateAnchorResult.FAILURE,945 anchorId : 0n946 });947 }948 })949 .catch(() => {950 // The test threw an error, treat anchor creation as failed.951 resolve({952 result : vrMojom.CreateAnchorResult.FAILURE,953 anchorId : 0n954 });955 });956 });957 }958 createPlaneAnchor(planeFromAnchor, planeId) {959 return new Promise((resolve) => {960 // Not supported yet.961 resolve({962 result : vrMojom.CreateAnchorResult.FAILURE,963 anchorId : 0n,964 });965 });966 }967 detachAnchor(anchorId) {}968 // Utility function969 _requestRuntimeSession(sessionOptions) {970 return this._runtimeSupportsSession(sessionOptions).then((result) => {971 // The JavaScript bindings convert c_style_names to camelCase names.972 const options = {973 transportMethod:974 vrMojom.XRPresentationTransportMethod.SUBMIT_AS_MAILBOX_HOLDER,975 waitForTransferNotification: true,976 waitForRenderNotification: true,977 waitForGpuFence: false,978 };979 let submit_frame_sink;980 if (result.supportsSession) {981 submit_frame_sink = {982 clientReceiver: this.presentation_provider_._getClientReceiver(),983 provider: this.presentation_provider_._bindProvider(sessionOptions),984 transportOptions: options985 };986 const dataProviderPtr = new vrMojom.XRFrameDataProviderRemote();987 this.dataProviderReceiver_ =988 new vrMojom.XRFrameDataProviderReceiver(this);989 this.dataProviderReceiver_.$.bindHandle(990 dataProviderPtr.$.bindNewPipeAndPassReceiver().handle);991 this.sessionOptions_ = sessionOptions;992 this.sessionClient_ = new vrMojom.XRSessionClientRemote();993 const clientReceiver = this.sessionClient_.$.bindNewPipeAndPassReceiver();994 const enabled_features = [];995 for (let i = 0; i < sessionOptions.requiredFeatures.length; i++) {996 if (this.supportedFeatures_.indexOf(sessionOptions.requiredFeatures[i]) !== -1) {997 enabled_features.push(sessionOptions.requiredFeatures[i]);998 } else {999 return Promise.resolve({session: null});1000 }1001 }1002 for (let i =0; i < sessionOptions.optionalFeatures.length; i++) {1003 if (this.supportedFeatures_.indexOf(sessionOptions.optionalFeatures[i]) !== -1) {1004 enabled_features.push(sessionOptions.optionalFeatures[i]);1005 }1006 }1007 this.enabledFeatures_ = enabled_features;1008 return Promise.resolve({1009 session: {1010 submitFrameSink: submit_frame_sink,1011 dataProvider: dataProviderPtr,1012 clientReceiver: clientReceiver,1013 displayInfo: this.displayInfo_,1014 enabledFeatures: enabled_features,1015 deviceConfig: {1016 usesInputEventing: false,1017 defaultFramebufferScale: this.defaultFramebufferScale_,1018 supportsViewportScaling: true,1019 depthConfiguration:1020 enabled_features.includes(vrMojom.XRSessionFeature.DEPTH) ? {1021 depthUsage: vrMojom.XRDepthUsage.kCPUOptimized,1022 depthDataFormat: vrMojom.XRDepthDataFormat.kLuminanceAlpha,1023 } : null,1024 },1025 enviromentBlendMode: this.enviromentBlendMode_,1026 interactionMode: this.interactionMode_1027 }1028 });1029 } else {1030 return Promise.resolve({session: null});1031 }1032 });1033 }1034 _runtimeSupportsSession(options) {1035 let result = this.supportedModes_.includes(options.mode);1036 if (options.requiredFeatures.includes(vrMojom.XRSessionFeature.DEPTH)1037 || options.optionalFeatures.includes(vrMojom.XRSessionFeature.DEPTH)) {1038 result &= options.depthOptions.usagePreferences.includes(vrMojom.XRDepthUsage.kCPUOptimized);1039 result &= options.depthOptions.dataFormatPreferences.includes(vrMojom.XRDepthDataFormat.kLuminanceAlpha);1040 }1041 return Promise.resolve({1042 supportsSession: result,1043 });1044 }1045 // Private functions - utilities:1046 _nativeOriginKnown(nativeOriginInformation){1047 if (nativeOriginInformation.inputSourceSpaceInfo !== undefined) {1048 if (!this.input_sources_.has(nativeOriginInformation.inputSourceSpaceInfo.inputSourceId)) {1049 // Unknown input source.1050 return false;1051 }1052 return true;1053 } else if (nativeOriginInformation.referenceSpaceType !== undefined) {1054 // Bounded_floor & unbounded ref spaces are not yet supported for AR:1055 if (nativeOriginInformation.referenceSpaceType == vrMojom.XRReferenceSpaceType.kUnbounded1056 || nativeOriginInformation.referenceSpaceType == vrMojom.XRReferenceSpaceType.kBoundedFloor) {1057 return false;1058 }1059 return true;1060 } else {1061 // Planes and anchors are not yet supported by the mock interface.1062 return false;1063 }1064 }1065 // Private functions - anchors implementation:1066 // Modifies passed in frameData to add anchor information.1067 _calculateAnchorInformation(frameData) {1068 if (!this.supportedModes_.includes(vrMojom.XRSessionMode.kImmersiveAr)) {1069 return;1070 }1071 frameData.anchorsData = {allAnchorsIds: [], updatedAnchorsData: []};1072 for(const [id, controller] of this.anchor_controllers_) {1073 frameData.anchorsData.allAnchorsIds.push(id);1074 // Send the entire anchor data over if there was a change since last GetFrameData().1075 if(controller.dirty) {1076 const anchorData = {id};1077 if(!controller.paused) {1078 anchorData.mojoFromAnchor = getPoseFromTransform(1079 XRMathHelper.decomposeRigidTransform(1080 controller._getAnchorOrigin()));1081 }1082 controller._markProcessed();1083 frameData.anchorsData.updatedAnchorsData.push(anchorData);1084 }1085 }1086 }1087 // Private functions - depth sensing implementation:1088 // Modifies passed in frameData to add anchor information.1089 _calculateDepthInformation(frameData) {1090 if (!this.supportedModes_.includes(vrMojom.XRSessionMode.kImmersiveAr)) {1091 return;1092 }1093 if (!this.enabledFeatures_.includes(vrMojom.XRSessionFeature.DEPTH)) {1094 return;...
anchor-click.navigation-trigger.js
Source:anchor-click.navigation-trigger.js
...56 return;57 }58 // ignore the click if the target is external to the app59 // In IE11 HTMLAnchorElement does not have the `origin` property60 const origin = anchor.origin || this._getAnchorOrigin(anchor);61 if (origin !== window.location.origin) {62 return;63 }64 // if none of the above, convert the click into a navigation event65 const { pathname, search, hash } = anchor;66 event.preventDefault();67 this._clickObserver$.next({ pathname, search, hash });68 }69 _getAnchorOrigin(anchor) {70 // IE11: on HTTP and HTTPS the default port is not included into71 // window.location.origin, so won't include it here either.72 const { port, protocol } = anchor;73 const defaultHttp = protocol === 'http:' && port === '80';74 const defaultHttps = protocol === 'https:' && port === '443';75 const host = (defaultHttp || defaultHttps)76 ? anchor.hostname // does not include the port number (e.g. www.example.org)77 : anchor.host; // does include the port number (e.g. www.example.org:80)78 return `${protocol}//${host}`;79 }...
Using AI Code Generation
1var wptooltip = require('./wptooltip');2var anchorOrigin = wptooltip._getAnchorOrigin();3console.log(anchorOrigin);4var wptooltip = require('./wptooltip');5var anchorOrigin = wptooltip._getAnchorOrigin();6console.log(anchorOrigin);
Using AI Code Generation
1function test()2{3 var toolbar = document.getElementById("wptoolbar");4 var anchorOrigin = toolbar._getAnchorOrigin();5 alert("anchorOrigin: " + anchorOrigin);6}
Using AI Code Generation
1var toolbar = require("toolbar");2var assert = require("assert");3var xulApp = require("xul-app");4var { Loader } = require('sdk/test/loader');5exports.testGetAnchorOrigin = function(test) {6 let dummyButton = toolbar.ToolbarButton({7 });8 let dummyPanel = require("panel").Panel({9 contentURL: "data:text/html;charset=utf-8,<p>dummy panel</p>",10 contentScript: "self.port.emit('show')",11 });12 dummyButton.panel = dummyPanel;13 dummyButton.panel.show();14 let anchorOrigin = dummyButton.panel._getAnchorOrigin();15 assert.equal(anchorOrigin, "toolbarbutton", "Anchor origin is correct");16 dummyButton.panel.hide();17 dummyButton.panel.destroy();18 dummyButton.destroy();19}20exports.testGetAnchorOriginWithNoToolbarButton = function(test) {21 let dummyPanel = require("panel").Panel({22 contentURL: "data:text/html;charset=utf-8,<p>dummy panel</p>",23 contentScript: "self.port.emit('show')",24 });25 dummyPanel.show();26 let anchorOrigin = dummyPanel._getAnchorOrigin();27 assert.equal(anchorOrigin, "topleft", "Anchor origin is correct");28 dummyPanel.hide();29 dummyPanel.destroy();30}31exports.testGetAnchorOriginWithNoToolbarButtonAndNoAnchor = function(test) {32 let dummyPanel = require("panel").Panel({33 contentURL: "data:text/html;charset
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!!