@markdy/renderer-dom 1.0.15 → 1.0.17

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.
Files changed (2) hide show
  1. package/dist/index.js +139 -13
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -2997,6 +2997,69 @@ function ensureSceneStyles(doc) {
2997
2997
  opacity: 1 !important;
2998
2998
  color: #64748b !important;
2999
2999
  }
3000
+ /* Fullscreen & Fallback Pseudo-Fullscreen Views */
3001
+ .markdy-fullscreen-host,
3002
+ :fullscreen {
3003
+ background-color: var(--md-canvas, #0b101b) !important;
3004
+ width: 100vw !important;
3005
+ height: 100vh !important;
3006
+ max-width: 100vw !important;
3007
+ max-height: 100vh !important;
3008
+ box-sizing: border-box !important;
3009
+ display: flex !important;
3010
+ flex-direction: column !important;
3011
+ justify-content: space-between !important;
3012
+ align-items: center !important;
3013
+ padding: 16px 20px 12px !important;
3014
+ overflow: hidden !important;
3015
+ }
3016
+ .markdy-fullscreen-host .markdy-viewport,
3017
+ :fullscreen .markdy-viewport {
3018
+ flex: 1 1 auto !important;
3019
+ width: 100% !important;
3020
+ height: 100% !important;
3021
+ max-width: 100% !important;
3022
+ max-height: calc(100vh - 64px) !important;
3023
+ }
3024
+ .markdy-fullscreen-host .markdy-footer,
3025
+ :fullscreen .markdy-footer {
3026
+ flex-shrink: 0 !important;
3027
+ width: 100% !important;
3028
+ max-width: 1400px !important;
3029
+ margin: 0 auto !important;
3030
+ padding: 8px 12px 4px !important;
3031
+ }
3032
+ .markdy--pseudo-fullscreen {
3033
+ position: fixed !important;
3034
+ inset: 0 !important;
3035
+ z-index: 999999 !important;
3036
+ width: 100vw !important;
3037
+ height: 100vh !important;
3038
+ max-width: 100vw !important;
3039
+ max-height: 100vh !important;
3040
+ background-color: var(--md-canvas, #0b101b) !important;
3041
+ display: flex !important;
3042
+ flex-direction: column !important;
3043
+ justify-content: space-between !important;
3044
+ align-items: center !important;
3045
+ padding: 16px 20px 12px !important;
3046
+ box-sizing: border-box !important;
3047
+ overflow: hidden !important;
3048
+ }
3049
+ .markdy--pseudo-fullscreen .markdy-viewport {
3050
+ flex: 1 1 auto !important;
3051
+ width: 100% !important;
3052
+ height: 100% !important;
3053
+ max-width: 100% !important;
3054
+ max-height: calc(100vh - 64px) !important;
3055
+ }
3056
+ .markdy--pseudo-fullscreen .markdy-footer {
3057
+ flex-shrink: 0 !important;
3058
+ width: 100% !important;
3059
+ max-width: 1400px !important;
3060
+ margin: 0 auto !important;
3061
+ padding: 8px 12px 4px !important;
3062
+ }
3000
3063
  @media (prefers-reduced-motion: reduce) {
3001
3064
  .markdy-node,
3002
3065
  .markdy-beat-caption,
@@ -3695,6 +3758,7 @@ function createDiagram(opts) {
3695
3758
  }
3696
3759
  for (const anim of allAnims) anim.cancel();
3697
3760
  resizeObserver?.disconnect();
3761
+ removeFullscreenListeners?.();
3698
3762
  if (progressEl?.parentNode === viewport) viewport.removeChild(progressEl);
3699
3763
  if (badge?.parentNode) badge.parentNode.removeChild(badge);
3700
3764
  if (footer?.parentNode) footer.parentNode.removeChild(footer);
@@ -3978,37 +4042,99 @@ function createDiagram(opts) {
3978
4042
  button.addEventListener("click", resetViewportTransform);
3979
4043
  toolbar.appendChild(button);
3980
4044
  }
4045
+ let removeFullscreenListeners = null;
3981
4046
  function mountFullscreenControl(toolbar) {
3982
4047
  if (!fullscreenButton) return;
3983
4048
  const button = makeControlButton("Full", "Toggle fullscreen view", ICONS2.fullscreen);
3984
4049
  button.className = "markdy-control-fullscreen";
3985
4050
  button.setAttribute("aria-pressed", "false");
3986
- const host = container.parentElement ?? container;
4051
+ const host = footer && footer.parentElement ? footer.parentElement : container.parentElement ?? container;
4052
+ let isPseudoFull = false;
3987
4053
  function syncFullscreenState() {
3988
- const isFull = document.fullscreenElement === host || document.fullscreenElement === container || document.fullscreenElement === viewport;
4054
+ const isFull = isPseudoFull || document.fullscreenElement === host || document.fullscreenElement === container || document.fullscreenElement === viewport || document.webkitFullscreenElement === host || document.webkitFullscreenElement === container;
3989
4055
  button.setAttribute("aria-pressed", isFull ? "true" : "false");
3990
4056
  button.title = isFull ? "Exit fullscreen" : "Toggle fullscreen view";
4057
+ button.innerHTML = isFull ? `${ICONS2.fullscreen}Exit` : `${ICONS2.fullscreen}Full`;
4058
+ if (isFull) {
4059
+ host.classList.add("markdy-fullscreen-host");
4060
+ } else {
4061
+ host.classList.remove("markdy-fullscreen-host");
4062
+ host.classList.remove("markdy--pseudo-fullscreen");
4063
+ }
4064
+ requestAnimationFrame(() => {
4065
+ applyViewportTransform();
4066
+ syncControls();
4067
+ });
3991
4068
  }
3992
- button.addEventListener("click", async () => {
4069
+ async function toggleFullscreen() {
3993
4070
  try {
3994
- if (!document.fullscreenElement) {
3995
- if (host.requestFullscreen) {
3996
- await host.requestFullscreen();
3997
- } else if (host.webkitRequestFullscreen) {
3998
- await host.webkitRequestFullscreen();
4071
+ const isCurrentlyFull = isPseudoFull || document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement;
4072
+ if (!isCurrentlyFull) {
4073
+ const req = host.requestFullscreen?.bind(host) || host.webkitRequestFullscreen?.bind(host) || host.mozRequestFullScreen?.bind(host) || host.msRequestFullscreen?.bind(host) || container.requestFullscreen?.bind(container) || container.webkitRequestFullscreen?.bind(container);
4074
+ if (req) {
4075
+ try {
4076
+ await req();
4077
+ } catch {
4078
+ isPseudoFull = true;
4079
+ host.classList.add("markdy--pseudo-fullscreen");
4080
+ syncFullscreenState();
4081
+ }
4082
+ } else {
4083
+ isPseudoFull = true;
4084
+ host.classList.add("markdy--pseudo-fullscreen");
4085
+ syncFullscreenState();
3999
4086
  }
4000
4087
  } else {
4001
- if (document.exitFullscreen) {
4002
- await document.exitFullscreen();
4003
- } else if (document.webkitExitFullscreen) {
4004
- await document.webkitExitFullscreen();
4088
+ if (isPseudoFull) {
4089
+ isPseudoFull = false;
4090
+ host.classList.remove("markdy--pseudo-fullscreen");
4091
+ syncFullscreenState();
4092
+ } else {
4093
+ const exit = document.exitFullscreen?.bind(document) || document.webkitExitFullscreen?.bind(document) || document.mozCancelFullScreen?.bind(document) || document.msExitFullscreen?.bind(document);
4094
+ if (exit) {
4095
+ await exit();
4096
+ }
4005
4097
  }
4006
4098
  }
4007
4099
  } catch (err) {
4008
- onWarning({ severity: "warning", message: `Fullscreen toggle failed: ${String(err)}`, line: 0 });
4100
+ if (!isPseudoFull) {
4101
+ isPseudoFull = true;
4102
+ host.classList.add("markdy--pseudo-fullscreen");
4103
+ syncFullscreenState();
4104
+ } else {
4105
+ isPseudoFull = false;
4106
+ host.classList.remove("markdy--pseudo-fullscreen");
4107
+ syncFullscreenState();
4108
+ }
4009
4109
  }
4110
+ }
4111
+ button.addEventListener("click", (e) => {
4112
+ e.stopPropagation();
4113
+ toggleFullscreen();
4010
4114
  });
4115
+ const handleEscKey = (e) => {
4116
+ if (e.key === "Escape" && isPseudoFull) {
4117
+ isPseudoFull = false;
4118
+ host.classList.remove("markdy--pseudo-fullscreen");
4119
+ syncFullscreenState();
4120
+ }
4121
+ };
4011
4122
  document.addEventListener("fullscreenchange", syncFullscreenState);
4123
+ document.addEventListener("webkitfullscreenchange", syncFullscreenState);
4124
+ document.addEventListener("mozfullscreenchange", syncFullscreenState);
4125
+ document.addEventListener("MSFullscreenChange", syncFullscreenState);
4126
+ window.addEventListener("keydown", handleEscKey);
4127
+ removeFullscreenListeners = () => {
4128
+ document.removeEventListener("fullscreenchange", syncFullscreenState);
4129
+ document.removeEventListener("webkitfullscreenchange", syncFullscreenState);
4130
+ document.removeEventListener("mozfullscreenchange", syncFullscreenState);
4131
+ document.removeEventListener("MSFullscreenChange", syncFullscreenState);
4132
+ window.removeEventListener("keydown", handleEscKey);
4133
+ if (isPseudoFull) {
4134
+ host.classList.remove("markdy--pseudo-fullscreen");
4135
+ host.classList.remove("markdy-fullscreen-host");
4136
+ }
4137
+ };
4012
4138
  toolbar.appendChild(button);
4013
4139
  }
4014
4140
  function handleKeyDown(event) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@markdy/renderer-dom",
3
- "version": "1.0.15",
3
+ "version": "1.0.17",
4
4
  "description": "Browser renderer for diagram-native animated MarkdyScript architecture diagrams, built on the Web Animations API.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -45,14 +45,14 @@
45
45
  },
46
46
  "dependencies": {
47
47
  "html2canvas": "^1.4.1",
48
- "@markdy/core": "1.0.15"
48
+ "@markdy/core": "1.0.17"
49
49
  },
50
50
  "devDependencies": {
51
51
  "jsdom": "^29.1.1",
52
52
  "tsup": "^8.5.1",
53
53
  "typescript": "^5.9.3",
54
54
  "vitest": "^4.1.7",
55
- "@markdy/stdlib-systems": "1.0.15"
55
+ "@markdy/stdlib-systems": "1.0.17"
56
56
  },
57
57
  "scripts": {
58
58
  "build": "tsup",