@plastic-software/three 0.183.3 → 0.184.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/three.cjs +783 -290
- package/build/three.core.js +372 -110
- package/build/three.core.min.js +1 -1
- package/build/three.module.js +436 -184
- package/build/three.module.min.js +1 -1
- package/build/three.tsl.js +7 -1
- package/build/three.tsl.min.js +1 -1
- package/build/three.webgpu.js +2979 -1281
- package/build/three.webgpu.min.js +1 -1
- package/build/three.webgpu.nodes.js +2942 -1281
- package/build/three.webgpu.nodes.min.js +1 -1
- package/examples/jsm/Addons.js +11 -0
- package/examples/jsm/animation/CCDIKSolver.js +5 -1
- package/examples/jsm/controls/ArcballControls.js +4 -1
- package/examples/jsm/controls/DragControls.js +2 -2
- package/examples/jsm/controls/FirstPersonControls.js +58 -54
- package/examples/jsm/controls/FlyControls.js +4 -0
- package/examples/jsm/controls/OrbitControls.js +2 -2
- package/examples/jsm/controls/TrackballControls.js +2 -2
- package/examples/jsm/controls/TransformControls.js +34 -2
- package/examples/jsm/csm/CSMShadowNode.js +6 -2
- package/examples/jsm/exporters/GLTFExporter.js +21 -5
- package/examples/jsm/geometries/TextGeometry.js +18 -0
- package/examples/jsm/helpers/LightProbeGridHelper.js +221 -0
- package/examples/jsm/inspector/Extension.js +13 -0
- package/examples/jsm/inspector/Inspector.js +169 -114
- package/examples/jsm/inspector/RendererInspector.js +2 -2
- package/examples/jsm/inspector/extensions/extensions.json +6 -0
- package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphEditor.js +916 -0
- package/examples/jsm/inspector/extensions/tsl-graph/TSLGraphLoader.js +281 -0
- package/examples/jsm/inspector/tabs/Memory.js +128 -0
- package/examples/jsm/inspector/tabs/Parameters.js +34 -2
- package/examples/jsm/inspector/tabs/Performance.js +2 -2
- package/examples/jsm/inspector/tabs/Settings.js +264 -0
- package/examples/jsm/inspector/tabs/Timeline.js +1611 -0
- package/examples/jsm/inspector/tabs/Viewer.js +105 -3
- package/examples/jsm/inspector/ui/Graph.js +2 -2
- package/examples/jsm/inspector/ui/List.js +1 -1
- package/examples/jsm/inspector/ui/Profiler.js +273 -176
- package/examples/jsm/inspector/ui/Style.js +64 -10
- package/examples/jsm/inspector/ui/Tab.js +39 -7
- package/examples/jsm/inspector/ui/Values.js +39 -2
- package/examples/jsm/inspector/ui/utils.js +13 -0
- package/examples/jsm/interaction/InteractionManager.js +226 -0
- package/examples/jsm/libs/meshopt_decoder.module.js +8 -8
- package/examples/jsm/lighting/DynamicLighting.js +82 -0
- package/examples/jsm/lighting/LightProbeGrid.js +651 -0
- package/examples/jsm/lines/LineMaterial.js +1 -1
- package/examples/jsm/loaders/EXRLoader.js +682 -43
- package/examples/jsm/loaders/FBXLoader.js +233 -33
- package/examples/jsm/loaders/GLTFLoader.js +24 -7
- package/examples/jsm/loaders/HDRLoader.js +1 -1
- package/examples/jsm/loaders/KTX2Loader.js +8 -2
- package/examples/jsm/loaders/LDrawLoader.js +39 -47
- package/examples/jsm/loaders/SVGLoader.js +1 -1
- package/examples/jsm/loaders/VTKLoader.js +5 -1
- package/examples/jsm/loaders/collada/ColladaComposer.js +101 -7
- package/examples/jsm/loaders/collada/ColladaParser.js +19 -4
- package/examples/jsm/loaders/usd/USDAParser.js +6 -0
- package/examples/jsm/loaders/usd/USDCParser.js +26 -0
- package/examples/jsm/loaders/usd/USDComposer.js +656 -103
- package/examples/jsm/misc/GPUComputationRenderer.js +2 -0
- package/examples/jsm/misc/RollerCoaster.js +42 -4
- package/examples/jsm/modifiers/TessellateModifier.js +1 -1
- package/examples/jsm/objects/Reflector.js +73 -25
- package/examples/jsm/objects/Sky.js +14 -2
- package/examples/jsm/objects/SkyMesh.js +23 -6
- package/examples/jsm/renderers/Projector.js +18 -38
- package/examples/jsm/renderers/SVGRenderer.js +6 -25
- package/examples/jsm/transpiler/GLSLDecoder.js +2 -2
- package/examples/jsm/tsl/WebGLNodesHandler.js +605 -0
- package/examples/jsm/tsl/display/AfterImageNode.js +10 -0
- package/examples/jsm/tsl/display/AnamorphicNode.js +11 -0
- package/examples/jsm/tsl/display/BilateralBlurNode.js +10 -0
- package/examples/jsm/tsl/display/ChromaticAberrationNode.js +3 -36
- package/examples/jsm/tsl/display/FSR1Node.js +477 -0
- package/examples/jsm/tsl/display/GTAONode.js +2 -1
- package/examples/jsm/tsl/display/GaussianBlurNode.js +10 -0
- package/examples/jsm/tsl/display/GodraysNode.js +2 -11
- package/examples/jsm/tsl/display/OutlineNode.js +66 -16
- package/examples/jsm/tsl/display/SSGINode.js +0 -4
- package/examples/jsm/tsl/display/SharpenNode.js +283 -0
- package/examples/jsm/tsl/display/TAAUNode.js +835 -0
- package/examples/jsm/tsl/display/TRAANode.js +48 -7
- package/examples/jsm/tsl/lighting/DynamicLightsNode.js +300 -0
- package/examples/jsm/tsl/lighting/data/AmbientLightDataNode.js +61 -0
- package/examples/jsm/tsl/lighting/data/DirectionalLightDataNode.js +111 -0
- package/examples/jsm/tsl/lighting/data/HemisphereLightDataNode.js +99 -0
- package/examples/jsm/tsl/lighting/data/PointLightDataNode.js +134 -0
- package/examples/jsm/tsl/lighting/data/SpotLightDataNode.js +161 -0
- package/examples/jsm/tsl/math/Bayer.js +13 -2
- package/examples/jsm/utils/BufferGeometryUtils.js +2 -3
- package/examples/jsm/utils/ColorUtils.js +76 -0
- package/examples/jsm/utils/SkeletonUtils.js +14 -8
- package/examples/jsm/webxr/XRHandMeshModel.js +36 -10
- package/examples/jsm/webxr/XRHandModelFactory.js +2 -1
- package/package.json +4 -4
- package/src/Three.Core.js +1 -0
- package/src/Three.TSL.js +6 -0
- package/src/Three.WebGPU.Nodes.js +3 -0
- package/src/Three.WebGPU.js +6 -0
- package/src/animation/AnimationAction.js +11 -1
- package/src/audio/AudioContext.js +2 -2
- package/src/constants.js +1 -1
- package/src/core/BufferAttribute.js +13 -1
- package/src/core/Clock.js +1 -1
- package/src/core/Object3D.js +1 -5
- package/src/core/RenderTarget.js +1 -0
- package/src/extras/PMREMGenerator.js +1 -1
- package/src/extras/curves/CatmullRomCurve3.js +3 -2
- package/src/loaders/AudioLoader.js +11 -1
- package/src/loaders/DataTextureLoader.js +6 -4
- package/src/loaders/FileLoader.js +1 -2
- package/src/loaders/ImageBitmapLoader.js +4 -6
- package/src/loaders/MaterialLoader.js +1 -1
- package/src/loaders/ObjectLoader.js +25 -4
- package/src/loaders/nodes/NodeObjectLoader.js +18 -0
- package/src/materials/MeshToonMaterial.js +1 -1
- package/src/materials/nodes/Line2NodeMaterial.js +27 -0
- package/src/materials/nodes/NodeMaterial.js +0 -27
- package/src/materials/nodes/manager/NodeMaterialObserver.js +188 -89
- package/src/math/Line3.js +3 -0
- package/src/math/Matrix2.js +13 -9
- package/src/math/Matrix3.js +13 -9
- package/src/math/Matrix4.js +13 -9
- package/src/math/Plane.js +4 -3
- package/src/math/Triangle.js +1 -1
- package/src/math/Vector2.js +11 -7
- package/src/math/Vector3.js +12 -8
- package/src/math/Vector4.js +13 -9
- package/src/nodes/Nodes.js +0 -1
- package/src/nodes/TSL.js +1 -1
- package/src/nodes/accessors/BufferAttributeNode.js +9 -3
- package/src/nodes/accessors/CubeTextureNode.js +7 -1
- package/src/nodes/accessors/MaterialProperties.js +2 -5
- package/src/nodes/accessors/Object3DNode.js +1 -1
- package/src/nodes/accessors/ReferenceBaseNode.js +2 -2
- package/src/nodes/accessors/ReferenceNode.js +4 -4
- package/src/nodes/accessors/SceneProperties.js +2 -8
- package/src/nodes/accessors/StorageBufferNode.js +10 -4
- package/src/nodes/accessors/StorageTextureNode.js +4 -9
- package/src/nodes/accessors/TextureNode.js +10 -2
- package/src/nodes/accessors/UniformArrayNode.js +2 -2
- package/src/nodes/code/FunctionCallNode.js +1 -1
- package/src/nodes/code/FunctionNode.js +1 -1
- package/src/nodes/core/ArrayNode.js +1 -1
- package/src/nodes/core/AssignNode.js +1 -1
- package/src/nodes/core/AttributeNode.js +1 -1
- package/src/nodes/core/BypassNode.js +1 -1
- package/src/nodes/core/ContextNode.js +1 -1
- package/src/nodes/core/IndexNode.js +2 -1
- package/src/nodes/core/InputNode.js +1 -1
- package/src/nodes/core/InspectorNode.js +1 -1
- package/src/nodes/core/IsolateNode.js +1 -1
- package/src/nodes/core/Node.js +83 -12
- package/src/nodes/core/NodeBuilder.js +117 -16
- package/src/nodes/core/NodeUtils.js +1 -1
- package/src/nodes/core/OutputStructNode.js +1 -1
- package/src/nodes/core/ParameterNode.js +1 -1
- package/src/nodes/core/StackNode.js +1 -1
- package/src/nodes/core/StructNode.js +1 -1
- package/src/nodes/core/StructTypeNode.js +1 -1
- package/src/nodes/core/SubBuildNode.js +1 -1
- package/src/nodes/core/UniformGroupNode.js +36 -6
- package/src/nodes/core/VarNode.js +1 -1
- package/src/nodes/core/VaryingNode.js +1 -1
- package/src/nodes/display/NormalMapNode.js +2 -2
- package/src/nodes/display/PassNode.js +27 -7
- package/src/nodes/display/RenderOutputNode.js +4 -4
- package/src/nodes/display/ScreenNode.js +1 -1
- package/src/nodes/display/ViewportDepthTextureNode.js +11 -15
- package/src/nodes/display/ViewportTextureNode.js +18 -7
- package/src/nodes/functions/BSDF/V_GGX_SmithCorrelated_Anisotropic.js +2 -2
- package/src/nodes/geometry/RangeNode.js +1 -1
- package/src/nodes/gpgpu/AtomicFunctionNode.js +1 -1
- package/src/nodes/gpgpu/BarrierNode.js +9 -0
- package/src/nodes/gpgpu/ComputeBuiltinNode.js +1 -1
- package/src/nodes/gpgpu/ComputeNode.js +69 -44
- package/src/nodes/gpgpu/SubgroupFunctionNode.js +1 -1
- package/src/nodes/lighting/LightsNode.js +6 -27
- package/src/nodes/lighting/ShadowNode.js +24 -2
- package/src/nodes/math/BitcastNode.js +1 -1
- package/src/nodes/math/ConditionalNode.js +1 -1
- package/src/nodes/math/MathNode.js +73 -1
- package/src/nodes/math/OperatorNode.js +1 -1
- package/src/nodes/math/PackFloatNode.js +1 -1
- package/src/nodes/math/UnpackFloatNode.js +1 -1
- package/src/nodes/tsl/TSLBase.js +1 -1
- package/src/nodes/tsl/TSLCore.js +21 -3
- package/src/nodes/utils/ArrayElementNode.js +1 -1
- package/src/nodes/utils/ConvertNode.js +1 -1
- package/src/nodes/utils/DebugNode.js +1 -1
- package/src/nodes/utils/EventNode.js +30 -0
- package/src/nodes/utils/FlipNode.js +1 -1
- package/src/nodes/utils/FunctionOverloadingNode.js +1 -1
- package/src/nodes/utils/JoinNode.js +1 -1
- package/src/nodes/utils/MemberNode.js +1 -1
- package/src/nodes/utils/Remap.js +48 -0
- package/src/nodes/utils/RotateNode.js +1 -1
- package/src/nodes/utils/SetNode.js +1 -1
- package/src/nodes/utils/SplitNode.js +1 -1
- package/src/objects/BatchedMesh.js +17 -2
- package/src/objects/InstancedMesh.js +19 -3
- package/src/objects/SkinnedMesh.js +26 -9
- package/src/renderers/WebGLRenderer.js +148 -49
- package/src/renderers/common/Animation.js +3 -3
- package/src/renderers/common/Attributes.js +15 -1
- package/src/renderers/common/Backend.js +0 -8
- package/src/renderers/common/Background.js +2 -2
- package/src/renderers/common/BindGroup.js +1 -8
- package/src/renderers/common/Bindings.js +2 -2
- package/src/renderers/common/ComputePipeline.js +1 -1
- package/src/renderers/common/CubeRenderTarget.js +1 -1
- package/src/renderers/common/Info.js +333 -4
- package/src/renderers/common/InspectorBase.js +6 -1
- package/src/renderers/common/Pipelines.js +36 -3
- package/src/renderers/common/ReadbackBuffer.js +78 -0
- package/src/renderers/common/RenderBundle.js +3 -1
- package/src/renderers/common/RenderBundles.js +5 -2
- package/src/renderers/common/RenderObject.js +2 -2
- package/src/renderers/common/RenderObjects.js +3 -3
- package/src/renderers/common/RenderPipeline.js +35 -6
- package/src/renderers/common/Renderer.js +232 -53
- package/src/renderers/common/Textures.js +72 -3
- package/src/renderers/common/UniformsGroup.js +1 -1
- package/src/renderers/common/XRManager.js +34 -27
- package/src/renderers/common/extras/PMREMGenerator.js +23 -15
- package/src/renderers/common/nodes/NodeBuilderState.js +1 -1
- package/src/renderers/common/nodes/NodeManager.js +230 -99
- package/src/renderers/shaders/ShaderChunk/batching_pars_vertex.glsl.js +20 -0
- package/src/renderers/shaders/ShaderChunk/beginnormal_vertex.glsl.js +9 -1
- package/src/renderers/shaders/ShaderChunk/envmap_common_pars_fragment.glsl.js +0 -1
- package/src/renderers/shaders/ShaderChunk/envmap_fragment.glsl.js +1 -1
- package/src/renderers/shaders/ShaderChunk/lightprobes_pars_fragment.glsl.js +80 -0
- package/src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js +8 -0
- package/src/renderers/shaders/ShaderChunk/lights_pars_begin.glsl.js +2 -0
- package/src/renderers/shaders/ShaderChunk/lights_physical_pars_fragment.glsl.js +1 -3
- package/src/renderers/shaders/ShaderChunk/normal_fragment_maps.glsl.js +7 -0
- package/src/renderers/shaders/ShaderChunk/premultiplied_alpha_fragment.glsl.js +0 -1
- package/src/renderers/shaders/ShaderChunk/shadowmap_vertex.glsl.js +12 -2
- package/src/renderers/shaders/ShaderChunk.js +2 -0
- package/src/renderers/shaders/ShaderLib/backgroundCube.glsl.js +1 -2
- package/src/renderers/shaders/ShaderLib.js +0 -1
- package/src/renderers/shaders/UniformsLib.js +7 -2
- package/src/renderers/shaders/UniformsUtils.js +27 -5
- package/src/renderers/webgl/WebGLAnimation.js +2 -1
- package/src/renderers/webgl/WebGLBackground.js +13 -13
- package/src/renderers/webgl/WebGLBufferRenderer.js +0 -32
- package/src/renderers/webgl/WebGLCapabilities.js +6 -0
- package/src/renderers/webgl/WebGLIndexedBufferRenderer.js +0 -32
- package/src/renderers/webgl/WebGLMaterials.js +12 -13
- package/src/renderers/webgl/WebGLOutput.js +4 -1
- package/src/renderers/webgl/WebGLProgram.js +5 -0
- package/src/renderers/webgl/WebGLPrograms.js +24 -3
- package/src/renderers/webgl/WebGLRenderStates.js +13 -2
- package/src/renderers/webgl/WebGLState.js +43 -0
- package/src/renderers/webgl/WebGLTextures.js +129 -26
- package/src/renderers/webgl/WebGLUniformsGroups.js +19 -0
- package/src/renderers/webgl-fallback/WebGLBackend.js +106 -65
- package/src/renderers/webgl-fallback/WebGLBufferRenderer.js +0 -41
- package/src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js +29 -51
- package/src/renderers/webgl-fallback/utils/WebGLAttributeUtils.js +53 -19
- package/src/renderers/webgl-fallback/utils/WebGLCapabilities.js +25 -0
- package/src/renderers/webgl-fallback/utils/WebGLState.js +42 -1
- package/src/renderers/webgl-fallback/utils/WebGLTextureUtils.js +63 -50
- package/src/renderers/webgl-fallback/utils/WebGLTimestampQueryPool.js +1 -1
- package/src/renderers/webgpu/WebGPUBackend.js +160 -146
- package/src/renderers/webgpu/nodes/WGSLNodeBuilder.js +55 -33
- package/src/renderers/webgpu/utils/WebGPUAttributeUtils.js +103 -17
- package/src/renderers/webgpu/utils/WebGPUBindingUtils.js +1 -1
- package/src/renderers/webgpu/utils/WebGPUCapabilities.js +48 -0
- package/src/renderers/webgpu/utils/WebGPUConstants.js +8 -0
- package/src/renderers/webgpu/utils/WebGPUTextureUtils.js +91 -17
- package/src/renderers/webgpu/utils/WebGPUUtils.js +18 -2
- package/src/renderers/webxr/WebXRController.js +12 -0
- package/src/textures/HTMLTexture.js +74 -0
- package/src/textures/Source.js +1 -1
- package/src/textures/Texture.js +13 -2
- package/src/utils.js +23 -1
- package/src/nodes/utils/RemapNode.js +0 -125
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
import { EventDispatcher } from 'three';
|
|
1
2
|
import { Style } from './Style.js';
|
|
3
|
+
import { getItem, setItem } from '../Inspector.js';
|
|
2
4
|
|
|
3
|
-
export class Profiler {
|
|
5
|
+
export class Profiler extends EventDispatcher {
|
|
4
6
|
|
|
5
|
-
constructor() {
|
|
7
|
+
constructor( inspector ) {
|
|
6
8
|
|
|
9
|
+
super();
|
|
10
|
+
|
|
11
|
+
this.inspector = inspector;
|
|
7
12
|
this.tabs = {};
|
|
8
13
|
this.activeTabId = null;
|
|
9
14
|
this.isResizing = false;
|
|
@@ -11,7 +16,6 @@ export class Profiler {
|
|
|
11
16
|
this.lastWidthRight = 450; // Width for right position
|
|
12
17
|
this.position = 'bottom'; // 'bottom' or 'right'
|
|
13
18
|
this.detachedWindows = []; // Array to store detached tab windows
|
|
14
|
-
this.isMobile = this.detectMobile();
|
|
15
19
|
this.maxZIndex = 1002; // Track the highest z-index for detached windows (starts at base z-index from CSS)
|
|
16
20
|
this.nextTabOriginalIndex = 0; // Track the original order of tabs as they are added
|
|
17
21
|
|
|
@@ -20,15 +24,43 @@ export class Profiler {
|
|
|
20
24
|
this.setupShell();
|
|
21
25
|
this.setupResizing();
|
|
22
26
|
|
|
27
|
+
// Setup window resize listener and update mobile status
|
|
28
|
+
this.setupWindowResizeListener();
|
|
29
|
+
|
|
23
30
|
// Setup orientation change listener for mobile devices
|
|
24
|
-
|
|
31
|
+
this.setupOrientationListener();
|
|
32
|
+
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
getSize() {
|
|
36
|
+
|
|
37
|
+
if ( this.panel.classList.contains( 'visible' ) === false || this.panel.classList.contains( 'no-tabs' ) ) {
|
|
25
38
|
|
|
26
|
-
|
|
39
|
+
return { width: 0, height: 0 };
|
|
27
40
|
|
|
28
41
|
}
|
|
29
42
|
|
|
30
|
-
|
|
31
|
-
|
|
43
|
+
if ( this.position === 'right' ) {
|
|
44
|
+
|
|
45
|
+
return { width: this.panel.offsetWidth, height: 0 };
|
|
46
|
+
|
|
47
|
+
} else {
|
|
48
|
+
|
|
49
|
+
return { width: 0, height: this.panel.offsetHeight };
|
|
50
|
+
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
get isMobile() {
|
|
56
|
+
|
|
57
|
+
return this.detectMobile();
|
|
58
|
+
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
get isSmallScreen() {
|
|
62
|
+
|
|
63
|
+
return window.innerWidth <= 768;
|
|
32
64
|
|
|
33
65
|
}
|
|
34
66
|
|
|
@@ -38,9 +70,8 @@ export class Profiler {
|
|
|
38
70
|
const userAgent = navigator.userAgent || navigator.vendor || window.opera;
|
|
39
71
|
const isMobileUA = /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test( userAgent );
|
|
40
72
|
const isTouchDevice = ( 'ontouchstart' in window ) || ( navigator.maxTouchPoints > 0 );
|
|
41
|
-
const isSmallScreen = window.innerWidth <= 768;
|
|
42
73
|
|
|
43
|
-
return isMobileUA || ( isTouchDevice && isSmallScreen );
|
|
74
|
+
return isMobileUA || ( isTouchDevice && this.isSmallScreen );
|
|
44
75
|
|
|
45
76
|
}
|
|
46
77
|
|
|
@@ -48,6 +79,8 @@ export class Profiler {
|
|
|
48
79
|
|
|
49
80
|
const handleOrientationChange = () => {
|
|
50
81
|
|
|
82
|
+
if ( ! this.isMobile ) return;
|
|
83
|
+
|
|
51
84
|
// Check if device is in landscape or portrait mode
|
|
52
85
|
const isLandscape = window.innerWidth > window.innerHeight;
|
|
53
86
|
|
|
@@ -123,6 +156,28 @@ export class Profiler {
|
|
|
123
156
|
// Listen for window resize events
|
|
124
157
|
window.addEventListener( 'resize', () => {
|
|
125
158
|
|
|
159
|
+
if ( this.isSmallScreen ) {
|
|
160
|
+
|
|
161
|
+
this.floatingBtn.style.display = 'none';
|
|
162
|
+
this.panel.classList.add( 'hide-position-toggle' );
|
|
163
|
+
|
|
164
|
+
} else {
|
|
165
|
+
|
|
166
|
+
this.floatingBtn.style.display = '';
|
|
167
|
+
this.panel.classList.remove( 'hide-position-toggle' );
|
|
168
|
+
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if ( this.isMobile ) {
|
|
172
|
+
|
|
173
|
+
this.panel.classList.add( 'is-mobile' );
|
|
174
|
+
|
|
175
|
+
} else {
|
|
176
|
+
|
|
177
|
+
this.panel.classList.remove( 'is-mobile' );
|
|
178
|
+
|
|
179
|
+
}
|
|
180
|
+
|
|
126
181
|
constrainDetachedWindows();
|
|
127
182
|
constrainMainPanel();
|
|
128
183
|
|
|
@@ -210,6 +265,19 @@ export class Profiler {
|
|
|
210
265
|
|
|
211
266
|
const header = document.createElement( 'div' );
|
|
212
267
|
header.className = 'profiler-header';
|
|
268
|
+
|
|
269
|
+
// Enable horizontal scrolling with vertical mouse wheel
|
|
270
|
+
header.addEventListener( 'wheel', ( e ) => {
|
|
271
|
+
|
|
272
|
+
if ( e.deltaY !== 0 ) {
|
|
273
|
+
|
|
274
|
+
e.preventDefault();
|
|
275
|
+
header.scrollLeft += e.deltaY * .25;
|
|
276
|
+
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
}, { passive: false } );
|
|
280
|
+
|
|
213
281
|
this.tabsContainer = document.createElement( 'div' );
|
|
214
282
|
this.tabsContainer.className = 'profiler-tabs';
|
|
215
283
|
|
|
@@ -222,14 +290,20 @@ export class Profiler {
|
|
|
222
290
|
this.floatingBtn.innerHTML = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><line x1="15" y1="3" x2="15" y2="21"></line></svg>';
|
|
223
291
|
this.floatingBtn.onclick = () => this.togglePosition();
|
|
224
292
|
|
|
225
|
-
// Hide position toggle button on
|
|
226
|
-
if ( this.
|
|
293
|
+
// Hide position toggle button on small screens
|
|
294
|
+
if ( this.isSmallScreen ) {
|
|
227
295
|
|
|
228
296
|
this.floatingBtn.style.display = 'none';
|
|
229
297
|
this.panel.classList.add( 'hide-position-toggle' );
|
|
230
298
|
|
|
231
299
|
}
|
|
232
300
|
|
|
301
|
+
if ( this.isMobile ) {
|
|
302
|
+
|
|
303
|
+
this.panel.classList.add( 'is-mobile' );
|
|
304
|
+
|
|
305
|
+
}
|
|
306
|
+
|
|
233
307
|
this.maximizeBtn = document.createElement( 'button' );
|
|
234
308
|
this.maximizeBtn.id = 'maximize-btn';
|
|
235
309
|
this.maximizeBtn.innerHTML = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3"/></svg>';
|
|
@@ -256,6 +330,13 @@ export class Profiler {
|
|
|
256
330
|
// Set initial position class
|
|
257
331
|
this.panel.classList.add( `position-${this.position}` );
|
|
258
332
|
|
|
333
|
+
if ( this.position === 'right' ) {
|
|
334
|
+
|
|
335
|
+
this.toggleButton.classList.add( 'position-right' );
|
|
336
|
+
this.miniPanel.classList.add( 'position-right' );
|
|
337
|
+
|
|
338
|
+
}
|
|
339
|
+
|
|
259
340
|
}
|
|
260
341
|
|
|
261
342
|
setupResizing() {
|
|
@@ -303,6 +384,8 @@ export class Profiler {
|
|
|
303
384
|
|
|
304
385
|
}
|
|
305
386
|
|
|
387
|
+
this.dispatchEvent( { type: 'resize' } );
|
|
388
|
+
|
|
306
389
|
};
|
|
307
390
|
|
|
308
391
|
const onEnd = () => {
|
|
@@ -395,6 +478,47 @@ export class Profiler {
|
|
|
395
478
|
|
|
396
479
|
}
|
|
397
480
|
|
|
481
|
+
this.dispatchEvent( { type: 'resize' } );
|
|
482
|
+
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
hide() {
|
|
486
|
+
|
|
487
|
+
this.miniPanel.classList.remove( 'visible' );
|
|
488
|
+
|
|
489
|
+
this.miniPanel.querySelectorAll( '.mini-panel-content' ).forEach( content => {
|
|
490
|
+
|
|
491
|
+
content.style.display = 'none';
|
|
492
|
+
|
|
493
|
+
} );
|
|
494
|
+
|
|
495
|
+
this.builtinTabsContainer.querySelectorAll( '.builtin-tab-btn' ).forEach( btn => {
|
|
496
|
+
|
|
497
|
+
btn.classList.remove( 'active' );
|
|
498
|
+
|
|
499
|
+
} );
|
|
500
|
+
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
show( tab ) {
|
|
504
|
+
|
|
505
|
+
this.hide();
|
|
506
|
+
|
|
507
|
+
tab.builtinButton.classList.add( 'active' );
|
|
508
|
+
|
|
509
|
+
if ( ! tab.miniContent.firstChild ) {
|
|
510
|
+
|
|
511
|
+
while ( tab.content.firstChild ) {
|
|
512
|
+
|
|
513
|
+
tab.miniContent.appendChild( tab.content.firstChild );
|
|
514
|
+
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
tab.miniContent.style.display = 'block';
|
|
520
|
+
this.miniPanel.classList.add( 'visible' );
|
|
521
|
+
|
|
398
522
|
}
|
|
399
523
|
|
|
400
524
|
addTab( tab ) {
|
|
@@ -416,7 +540,12 @@ export class Profiler {
|
|
|
416
540
|
|
|
417
541
|
this.setupTabDragAndDrop( tab );
|
|
418
542
|
|
|
419
|
-
|
|
543
|
+
if ( ! tab.builtin ) {
|
|
544
|
+
|
|
545
|
+
this.tabsContainer.appendChild( tab.button );
|
|
546
|
+
|
|
547
|
+
}
|
|
548
|
+
|
|
420
549
|
this.contentWrapper.appendChild( tab.content );
|
|
421
550
|
|
|
422
551
|
// Apply the current visibility state to the DOM elements
|
|
@@ -437,6 +566,9 @@ export class Profiler {
|
|
|
437
566
|
// Update panel size when tabs change
|
|
438
567
|
this.updatePanelSize();
|
|
439
568
|
|
|
569
|
+
// Set profiler reference
|
|
570
|
+
tab.profiler = this;
|
|
571
|
+
|
|
440
572
|
}
|
|
441
573
|
|
|
442
574
|
addBuiltinTab( tab ) {
|
|
@@ -473,107 +605,94 @@ export class Profiler {
|
|
|
473
605
|
|
|
474
606
|
e.stopPropagation(); // Prevent toggle panel from triggering
|
|
475
607
|
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
if ( isPanelVisible ) {
|
|
608
|
+
// Toggle mini-panel for this tab
|
|
609
|
+
const isCurrentlyActive = miniContent.style.display !== 'none' && miniContent.children.length > 0;
|
|
479
610
|
|
|
480
|
-
|
|
481
|
-
if ( ! tab.isVisible ) {
|
|
611
|
+
if ( isCurrentlyActive ) {
|
|
482
612
|
|
|
483
|
-
|
|
613
|
+
this.hide();
|
|
484
614
|
|
|
485
|
-
|
|
615
|
+
} else {
|
|
486
616
|
|
|
487
|
-
|
|
617
|
+
this.show( tab );
|
|
488
618
|
|
|
489
|
-
|
|
490
|
-
if ( tab.detachedWindow ) {
|
|
619
|
+
}
|
|
491
620
|
|
|
492
|
-
|
|
621
|
+
};
|
|
493
622
|
|
|
494
|
-
|
|
623
|
+
this.builtinTabsContainer.appendChild( builtinButton );
|
|
495
624
|
|
|
496
|
-
|
|
625
|
+
// Store references
|
|
626
|
+
tab.builtinButton = builtinButton;
|
|
627
|
+
tab.miniContent = miniContent;
|
|
497
628
|
|
|
498
|
-
|
|
499
|
-
|
|
629
|
+
// If the tab was hidden before being added, hide the builtin button
|
|
630
|
+
if ( ! tab.isVisible ) {
|
|
500
631
|
|
|
501
|
-
|
|
632
|
+
builtinButton.style.display = 'none';
|
|
633
|
+
miniContent.style.display = 'none';
|
|
502
634
|
|
|
503
|
-
|
|
635
|
+
// Hide the builtin-tabs-container if all builtin buttons are hidden
|
|
636
|
+
const hasVisibleBuiltinButtons = Array.from( this.builtinTabsContainer.querySelectorAll( '.builtin-tab-btn' ) )
|
|
637
|
+
.some( btn => btn.style.display !== 'none' );
|
|
504
638
|
|
|
505
|
-
|
|
506
|
-
const isCurrentlyActive = miniContent.style.display !== 'none' && miniContent.children.length > 0;
|
|
639
|
+
if ( ! hasVisibleBuiltinButtons ) {
|
|
507
640
|
|
|
508
|
-
|
|
509
|
-
this.miniPanel.querySelectorAll( '.mini-panel-content' ).forEach( content => {
|
|
641
|
+
this.builtinTabsContainer.style.display = 'none';
|
|
510
642
|
|
|
511
|
-
|
|
643
|
+
}
|
|
512
644
|
|
|
513
|
-
|
|
645
|
+
}
|
|
514
646
|
|
|
515
|
-
|
|
516
|
-
this.builtinTabsContainer.querySelectorAll( '.builtin-tab-btn' ).forEach( btn => {
|
|
647
|
+
}
|
|
517
648
|
|
|
518
|
-
|
|
649
|
+
removeTab( tab ) {
|
|
519
650
|
|
|
520
|
-
|
|
651
|
+
if ( ! tab || this.tabs[ tab.id ] === undefined ) return;
|
|
521
652
|
|
|
522
|
-
|
|
653
|
+
delete this.tabs[ tab.id ];
|
|
523
654
|
|
|
524
|
-
|
|
525
|
-
this.miniPanel.classList.remove( 'visible' );
|
|
526
|
-
miniContent.style.display = 'none';
|
|
655
|
+
if ( tab.isDetached && tab.detachedWindow ) {
|
|
527
656
|
|
|
528
|
-
|
|
529
|
-
if ( miniContent.firstChild ) {
|
|
657
|
+
if ( tab.detachedWindow.panel && tab.detachedWindow.panel.parentNode ) {
|
|
530
658
|
|
|
531
|
-
|
|
659
|
+
tab.detachedWindow.panel.parentNode.removeChild( tab.detachedWindow.panel );
|
|
532
660
|
|
|
533
|
-
|
|
661
|
+
}
|
|
534
662
|
|
|
535
|
-
|
|
663
|
+
const index = this.detachedWindows.indexOf( tab.detachedWindow );
|
|
536
664
|
|
|
537
|
-
|
|
538
|
-
builtinButton.classList.add( 'active' );
|
|
665
|
+
if ( index !== - 1 ) {
|
|
539
666
|
|
|
540
|
-
|
|
541
|
-
if ( ! miniContent.firstChild ) {
|
|
667
|
+
this.detachedWindows.splice( index, 1 );
|
|
542
668
|
|
|
543
|
-
|
|
669
|
+
}
|
|
544
670
|
|
|
545
|
-
|
|
671
|
+
}
|
|
546
672
|
|
|
547
|
-
|
|
673
|
+
if ( ! tab.builtin ) {
|
|
548
674
|
|
|
549
|
-
|
|
675
|
+
if ( tab.button && tab.button.parentNode ) {
|
|
550
676
|
|
|
551
|
-
|
|
677
|
+
tab.button.parentNode.removeChild( tab.button );
|
|
552
678
|
|
|
553
|
-
|
|
554
|
-
miniContent.style.display = 'block';
|
|
555
|
-
this.miniPanel.classList.add( 'visible' );
|
|
679
|
+
}
|
|
556
680
|
|
|
557
|
-
|
|
681
|
+
} else {
|
|
558
682
|
|
|
559
|
-
|
|
683
|
+
if ( tab.builtinButton && tab.builtinButton.parentNode ) {
|
|
560
684
|
|
|
561
|
-
|
|
685
|
+
tab.builtinButton.parentNode.removeChild( tab.builtinButton );
|
|
562
686
|
|
|
563
|
-
|
|
687
|
+
}
|
|
564
688
|
|
|
565
|
-
|
|
566
|
-
tab.builtinButton = builtinButton;
|
|
567
|
-
tab.miniContent = miniContent;
|
|
568
|
-
tab.profiler = this;
|
|
689
|
+
if ( tab.miniContent && tab.miniContent.parentNode ) {
|
|
569
690
|
|
|
570
|
-
|
|
571
|
-
if ( ! tab.isVisible ) {
|
|
691
|
+
tab.miniContent.parentNode.removeChild( tab.miniContent );
|
|
572
692
|
|
|
573
|
-
|
|
574
|
-
miniContent.style.display = 'none';
|
|
693
|
+
}
|
|
575
694
|
|
|
576
|
-
//
|
|
695
|
+
// Clean up builtin container if empty
|
|
577
696
|
const hasVisibleBuiltinButtons = Array.from( this.builtinTabsContainer.querySelectorAll( '.builtin-tab-btn' ) )
|
|
578
697
|
.some( btn => btn.style.display !== 'none' );
|
|
579
698
|
|
|
@@ -585,6 +704,38 @@ export class Profiler {
|
|
|
585
704
|
|
|
586
705
|
}
|
|
587
706
|
|
|
707
|
+
if ( tab.content && tab.content.parentNode ) {
|
|
708
|
+
|
|
709
|
+
tab.content.parentNode.removeChild( tab.content );
|
|
710
|
+
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
if ( this.activeTabId === tab.id ) {
|
|
714
|
+
|
|
715
|
+
this.activeTabId = null;
|
|
716
|
+
|
|
717
|
+
// Try to activate another tab
|
|
718
|
+
const remainingTabs = Object.values( this.tabs ).filter( t => ! t.isDetached && t.isVisible );
|
|
719
|
+
|
|
720
|
+
if ( remainingTabs.length > 0 ) {
|
|
721
|
+
|
|
722
|
+
this.setActiveTab( remainingTabs[ 0 ].id );
|
|
723
|
+
|
|
724
|
+
} else {
|
|
725
|
+
|
|
726
|
+
this.updatePanelSize();
|
|
727
|
+
|
|
728
|
+
}
|
|
729
|
+
|
|
730
|
+
} else {
|
|
731
|
+
|
|
732
|
+
this.updatePanelSize();
|
|
733
|
+
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
tab.onVisibilityChange = null;
|
|
737
|
+
tab.profiler = null;
|
|
738
|
+
|
|
588
739
|
}
|
|
589
740
|
|
|
590
741
|
updatePanelSize() {
|
|
@@ -648,32 +799,26 @@ export class Profiler {
|
|
|
648
799
|
|
|
649
800
|
}
|
|
650
801
|
|
|
802
|
+
this.dispatchEvent( { type: 'resize' } );
|
|
803
|
+
|
|
651
804
|
}
|
|
652
805
|
|
|
653
806
|
setupTabDragAndDrop( tab ) {
|
|
654
807
|
|
|
655
|
-
//
|
|
656
|
-
|
|
808
|
+
// Always handle basic click
|
|
809
|
+
tab.button.addEventListener( 'click', () => {
|
|
657
810
|
|
|
658
|
-
|
|
811
|
+
if ( ! isDragging ) {
|
|
659
812
|
|
|
660
813
|
this.setActiveTab( tab.id );
|
|
661
814
|
|
|
662
|
-
}
|
|
663
|
-
|
|
664
|
-
return;
|
|
815
|
+
}
|
|
665
816
|
|
|
666
|
-
}
|
|
817
|
+
} );
|
|
667
818
|
|
|
668
819
|
// Disable drag and drop if tab doesn't allow detach
|
|
669
820
|
if ( tab.allowDetach === false ) {
|
|
670
821
|
|
|
671
|
-
tab.button.addEventListener( 'click', () => {
|
|
672
|
-
|
|
673
|
-
this.setActiveTab( tab.id );
|
|
674
|
-
|
|
675
|
-
} );
|
|
676
|
-
|
|
677
822
|
tab.button.style.cursor = 'default';
|
|
678
823
|
|
|
679
824
|
return;
|
|
@@ -778,6 +923,8 @@ export class Profiler {
|
|
|
778
923
|
|
|
779
924
|
tab.button.addEventListener( 'pointerdown', ( e ) => {
|
|
780
925
|
|
|
926
|
+
if ( this.isMobile && e.pointerType !== 'mouse' ) return;
|
|
927
|
+
|
|
781
928
|
onDragStart( e );
|
|
782
929
|
tab.button.addEventListener( 'pointermove', onDragMove );
|
|
783
930
|
tab.button.addEventListener( 'pointerup', onDragEnd );
|
|
@@ -1466,92 +1613,18 @@ export class Profiler {
|
|
|
1466
1613
|
|
|
1467
1614
|
}
|
|
1468
1615
|
|
|
1616
|
+
this.saveLayout();
|
|
1617
|
+
|
|
1469
1618
|
}
|
|
1470
1619
|
|
|
1471
1620
|
togglePanel() {
|
|
1472
1621
|
|
|
1473
1622
|
this.panel.classList.toggle( 'visible' );
|
|
1474
|
-
this.toggleButton.classList.toggle( '
|
|
1623
|
+
this.toggleButton.classList.toggle( 'panel-open' );
|
|
1624
|
+
this.miniPanel.classList.toggle( 'panel-open' );
|
|
1475
1625
|
|
|
1476
1626
|
const isVisible = this.panel.classList.contains( 'visible' );
|
|
1477
1627
|
|
|
1478
|
-
if ( isVisible ) {
|
|
1479
|
-
|
|
1480
|
-
// Save mini-panel state before hiding
|
|
1481
|
-
this.savedMiniPanelState = {
|
|
1482
|
-
isVisible: this.miniPanel.classList.contains( 'visible' ),
|
|
1483
|
-
activeTabId: null,
|
|
1484
|
-
contentMap: {}
|
|
1485
|
-
};
|
|
1486
|
-
|
|
1487
|
-
// Find which tab was active in mini-panel
|
|
1488
|
-
this.miniPanel.querySelectorAll( '.mini-panel-content' ).forEach( content => {
|
|
1489
|
-
|
|
1490
|
-
if ( content.style.display !== 'none' && content.firstChild ) {
|
|
1491
|
-
|
|
1492
|
-
// Find the tab that owns this content
|
|
1493
|
-
Object.values( this.tabs ).forEach( tab => {
|
|
1494
|
-
|
|
1495
|
-
if ( tab.miniContent === content ) {
|
|
1496
|
-
|
|
1497
|
-
this.savedMiniPanelState.activeTabId = tab.id;
|
|
1498
|
-
// Move content back to main panel
|
|
1499
|
-
tab.content.appendChild( content.firstChild );
|
|
1500
|
-
|
|
1501
|
-
}
|
|
1502
|
-
|
|
1503
|
-
} );
|
|
1504
|
-
|
|
1505
|
-
}
|
|
1506
|
-
|
|
1507
|
-
} );
|
|
1508
|
-
|
|
1509
|
-
// Hide mini-panel temporarily
|
|
1510
|
-
this.miniPanel.classList.remove( 'visible' );
|
|
1511
|
-
|
|
1512
|
-
// Hide all mini-panel contents
|
|
1513
|
-
this.miniPanel.querySelectorAll( '.mini-panel-content' ).forEach( content => {
|
|
1514
|
-
|
|
1515
|
-
content.style.display = 'none';
|
|
1516
|
-
|
|
1517
|
-
} );
|
|
1518
|
-
|
|
1519
|
-
// Remove active state from builtin buttons
|
|
1520
|
-
this.builtinTabsContainer.querySelectorAll( '.builtin-tab-btn' ).forEach( btn => {
|
|
1521
|
-
|
|
1522
|
-
btn.classList.remove( 'active' );
|
|
1523
|
-
|
|
1524
|
-
} );
|
|
1525
|
-
|
|
1526
|
-
} else {
|
|
1527
|
-
|
|
1528
|
-
// Restore mini-panel state when minimizing
|
|
1529
|
-
if ( this.savedMiniPanelState && this.savedMiniPanelState.isVisible && this.savedMiniPanelState.activeTabId ) {
|
|
1530
|
-
|
|
1531
|
-
const tab = this.tabs[ this.savedMiniPanelState.activeTabId ];
|
|
1532
|
-
|
|
1533
|
-
if ( tab && tab.miniContent && tab.builtinButton ) {
|
|
1534
|
-
|
|
1535
|
-
// Restore mini-panel visibility
|
|
1536
|
-
this.miniPanel.classList.add( 'visible' );
|
|
1537
|
-
tab.miniContent.style.display = 'block';
|
|
1538
|
-
tab.builtinButton.classList.add( 'active' );
|
|
1539
|
-
|
|
1540
|
-
// Move content back to mini-panel
|
|
1541
|
-
const actualContent = tab.content.querySelector( '.list-scroll-wrapper, .profiler-content > *' );
|
|
1542
|
-
|
|
1543
|
-
if ( actualContent ) {
|
|
1544
|
-
|
|
1545
|
-
tab.miniContent.appendChild( actualContent );
|
|
1546
|
-
|
|
1547
|
-
}
|
|
1548
|
-
|
|
1549
|
-
}
|
|
1550
|
-
|
|
1551
|
-
}
|
|
1552
|
-
|
|
1553
|
-
}
|
|
1554
|
-
|
|
1555
1628
|
this.detachedWindows.forEach( detachedWindow => {
|
|
1556
1629
|
|
|
1557
1630
|
if ( isVisible ) {
|
|
@@ -1570,6 +1643,10 @@ export class Profiler {
|
|
|
1570
1643
|
|
|
1571
1644
|
} );
|
|
1572
1645
|
|
|
1646
|
+
this.dispatchEvent( { type: 'resize' } );
|
|
1647
|
+
|
|
1648
|
+
this.saveLayout();
|
|
1649
|
+
|
|
1573
1650
|
}
|
|
1574
1651
|
|
|
1575
1652
|
togglePosition() {
|
|
@@ -1598,6 +1675,8 @@ export class Profiler {
|
|
|
1598
1675
|
// Apply right position styles
|
|
1599
1676
|
this.panel.classList.remove( 'position-bottom' );
|
|
1600
1677
|
this.panel.classList.add( 'position-right' );
|
|
1678
|
+
this.toggleButton.classList.add( 'position-right' );
|
|
1679
|
+
this.miniPanel.classList.add( 'position-right' );
|
|
1601
1680
|
this.panel.style.bottom = '';
|
|
1602
1681
|
this.panel.style.top = '0';
|
|
1603
1682
|
this.panel.style.right = '0';
|
|
@@ -1626,6 +1705,8 @@ export class Profiler {
|
|
|
1626
1705
|
// Apply bottom position styles
|
|
1627
1706
|
this.panel.classList.remove( 'position-right' );
|
|
1628
1707
|
this.panel.classList.add( 'position-bottom' );
|
|
1708
|
+
this.toggleButton.classList.remove( 'position-right' );
|
|
1709
|
+
this.miniPanel.classList.remove( 'position-right' );
|
|
1629
1710
|
this.panel.style.top = '';
|
|
1630
1711
|
this.panel.style.right = '';
|
|
1631
1712
|
this.panel.style.bottom = '0';
|
|
@@ -1663,12 +1744,15 @@ export class Profiler {
|
|
|
1663
1744
|
|
|
1664
1745
|
saveLayout() {
|
|
1665
1746
|
|
|
1747
|
+
if ( this.isLoadingLayout ) return;
|
|
1748
|
+
|
|
1666
1749
|
const layout = {
|
|
1667
1750
|
position: this.position,
|
|
1668
1751
|
lastHeightBottom: this.lastHeightBottom,
|
|
1669
1752
|
lastWidthRight: this.lastWidthRight,
|
|
1670
1753
|
activeTabId: this.activeTabId,
|
|
1671
|
-
detachedTabs: []
|
|
1754
|
+
detachedTabs: [],
|
|
1755
|
+
isVisible: this.panel.classList.contains( 'visible' )
|
|
1672
1756
|
};
|
|
1673
1757
|
|
|
1674
1758
|
// Save detached windows state
|
|
@@ -1696,7 +1780,7 @@ export class Profiler {
|
|
|
1696
1780
|
|
|
1697
1781
|
try {
|
|
1698
1782
|
|
|
1699
|
-
|
|
1783
|
+
setItem( 'layout', layout );
|
|
1700
1784
|
|
|
1701
1785
|
} catch ( e ) {
|
|
1702
1786
|
|
|
@@ -1708,13 +1792,13 @@ export class Profiler {
|
|
|
1708
1792
|
|
|
1709
1793
|
loadLayout() {
|
|
1710
1794
|
|
|
1711
|
-
|
|
1795
|
+
this.isLoadingLayout = true;
|
|
1712
1796
|
|
|
1713
|
-
|
|
1797
|
+
try {
|
|
1714
1798
|
|
|
1715
|
-
|
|
1799
|
+
const layout = getItem( 'layout' );
|
|
1716
1800
|
|
|
1717
|
-
|
|
1801
|
+
if ( Object.keys( layout ).length === 0 ) return;
|
|
1718
1802
|
|
|
1719
1803
|
// Constrain detached tabs positions to current screen bounds
|
|
1720
1804
|
if ( layout.detachedTabs && layout.detachedTabs.length > 0 ) {
|
|
@@ -1827,6 +1911,8 @@ export class Profiler {
|
|
|
1827
1911
|
|
|
1828
1912
|
this.panel.classList.remove( 'position-bottom' );
|
|
1829
1913
|
this.panel.classList.add( 'position-right' );
|
|
1914
|
+
this.toggleButton.classList.add( 'position-right' );
|
|
1915
|
+
this.miniPanel.classList.add( 'position-right' );
|
|
1830
1916
|
this.panel.style.bottom = '';
|
|
1831
1917
|
this.panel.style.top = '0';
|
|
1832
1918
|
this.panel.style.right = '0';
|
|
@@ -1840,16 +1926,16 @@ export class Profiler {
|
|
|
1840
1926
|
|
|
1841
1927
|
}
|
|
1842
1928
|
|
|
1843
|
-
if ( layout.
|
|
1929
|
+
if ( layout.isVisible ) {
|
|
1844
1930
|
|
|
1845
|
-
|
|
1846
|
-
|
|
1931
|
+
this.panel.classList.add( 'visible' );
|
|
1932
|
+
this.toggleButton.classList.add( 'panel-open' );
|
|
1847
1933
|
|
|
1848
|
-
|
|
1934
|
+
}
|
|
1849
1935
|
|
|
1850
|
-
|
|
1936
|
+
if ( layout.activeTabId ) {
|
|
1851
1937
|
|
|
1852
|
-
|
|
1938
|
+
this.setActiveTab( layout.activeTabId );
|
|
1853
1939
|
|
|
1854
1940
|
}
|
|
1855
1941
|
|
|
@@ -1863,10 +1949,21 @@ export class Profiler {
|
|
|
1863
1949
|
// Update panel size after loading layout
|
|
1864
1950
|
this.updatePanelSize();
|
|
1865
1951
|
|
|
1952
|
+
// Ensure initial open state applies to mini panel as well
|
|
1953
|
+
if ( this.panel.classList.contains( 'visible' ) ) {
|
|
1954
|
+
|
|
1955
|
+
this.miniPanel.classList.add( 'panel-open' );
|
|
1956
|
+
|
|
1957
|
+
}
|
|
1958
|
+
|
|
1866
1959
|
} catch ( e ) {
|
|
1867
1960
|
|
|
1868
1961
|
console.warn( 'Failed to load profiler layout:', e );
|
|
1869
1962
|
|
|
1963
|
+
} finally {
|
|
1964
|
+
|
|
1965
|
+
this.isLoadingLayout = false;
|
|
1966
|
+
|
|
1870
1967
|
}
|
|
1871
1968
|
|
|
1872
1969
|
}
|