@underpostnet/underpost 2.98.1 → 2.98.3

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/README.md CHANGED
@@ -18,7 +18,7 @@
18
18
 
19
19
  <!-- badges -->
20
20
 
21
- [![Node.js CI](https://github.com/underpostnet/engine/actions/workflows/docker-image.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/docker-image.yml) [![Test](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml) [![Downloads](https://img.shields.io/npm/dm/underpost.svg)](https://www.npmjs.com/package/underpost) [![Socket Badge](https://socket.dev/api/badge/npm/package/underpost/2.98.1)](https://socket.dev/npm/package/underpost/overview/2.98.1) [![Coverage Status](https://coveralls.io/repos/github/underpostnet/engine/badge.svg?branch=master)](https://coveralls.io/github/underpostnet/engine?branch=master) [![Version](https://img.shields.io/npm/v/underpost.svg)](https://www.npmjs.org/package/underpost) [![License](https://img.shields.io/npm/l/underpost.svg)](https://www.npmjs.com/package/underpost)
21
+ [![Node.js CI](https://github.com/underpostnet/engine/actions/workflows/docker-image.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/docker-image.yml) [![Test](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml/badge.svg?branch=master)](https://github.com/underpostnet/engine/actions/workflows/coverall.ci.yml) [![Downloads](https://img.shields.io/npm/dm/underpost.svg)](https://www.npmjs.com/package/underpost) [![Socket Badge](https://socket.dev/api/badge/npm/package/underpost/2.98.3)](https://socket.dev/npm/package/underpost/overview/2.98.3) [![Coverage Status](https://coveralls.io/repos/github/underpostnet/engine/badge.svg?branch=master)](https://coveralls.io/github/underpostnet/engine?branch=master) [![Version](https://img.shields.io/npm/v/underpost.svg)](https://www.npmjs.org/package/underpost) [![License](https://img.shields.io/npm/l/underpost.svg)](https://www.npmjs.com/package/underpost)
22
22
 
23
23
  <!-- end-badges -->
24
24
 
@@ -66,7 +66,7 @@ Run dev client server
66
66
  npm run dev
67
67
  ```
68
68
  <!-- -->
69
- ## underpost ci/cd cli v2.98.1
69
+ ## underpost ci/cd cli v2.98.3
70
70
 
71
71
  ### Usage: `underpost [options] [command]`
72
72
  ```
package/bin/build.js CHANGED
@@ -181,11 +181,11 @@ const { DefaultConf } = await import(`../conf.${confName}.js`);
181
181
  'atlas-sprite-sheet',
182
182
  ];
183
183
  packageJson.description = 'Cyberia Engine - Object Layer and Assets Management Microservice';
184
- packageJson.dependencies = originPackageJson.dependencies;
185
- packageJson.dependencies['maxrects-packer'] = '^2.7.3';
186
- packageJson.dependencies['pngjs'] = '^7.0.0';
187
- packageJson.dependencies['jimp'] = '^1.6.0';
188
- packageJson.dependencies['sharp'] = '^0.32.5';
184
+ const { CyberiaDependencies } = await import(`../src/client/components/cyberia-portal/CommonCyberiaPortal.js`);
185
+ packageJson.dependencies = {
186
+ ...packageJson.dependencies,
187
+ ...CyberiaDependencies,
188
+ };
189
189
  fs.writeFileSync(`${basePath}/bin/index.js`, fs.readFileSync(`./bin/cyberia.js`, 'utf8'), 'utf8');
190
190
  fs.copyFileSync(`./src/api/object-layer/README.md`, `${basePath}/README.md`);
191
191
  fs.copySync(`./hardhat`, `${basePath}/hardhat`);
package/bin/deploy.js CHANGED
@@ -1134,6 +1134,15 @@ nvidia/gpu-operator \
1134
1134
  }
1135
1135
  break;
1136
1136
  }
1137
+
1138
+ case 'cyberia': {
1139
+ const { CyberiaDependencies } = await import(`../src/client/components/cyberia-portal/CommonCyberiaPortal.js`);
1140
+ for (const dep of Object.keys(CyberiaDependencies)) {
1141
+ const ver = CyberiaDependencies[dep];
1142
+ shellExec(`npm install ${dep}@${ver}`);
1143
+ }
1144
+ break;
1145
+ }
1137
1146
  }
1138
1147
  } catch (error) {
1139
1148
  logger.error(error, error.stack);
package/cli.md CHANGED
@@ -1,4 +1,4 @@
1
- ## underpost ci/cd cli v2.98.1
1
+ ## underpost ci/cd cli v2.98.3
2
2
 
3
3
  ### Usage: `underpost [options] [command]`
4
4
  ```
@@ -17,7 +17,7 @@ spec:
17
17
  spec:
18
18
  containers:
19
19
  - name: dd-default-development-blue
20
- image: localhost/rockylinux9-underpost:v2.98.1
20
+ image: localhost/rockylinux9-underpost:v2.98.3
21
21
  # resources:
22
22
  # requests:
23
23
  # memory: "124Ki"
@@ -100,7 +100,7 @@ spec:
100
100
  spec:
101
101
  containers:
102
102
  - name: dd-default-development-green
103
- image: localhost/rockylinux9-underpost:v2.98.1
103
+ image: localhost/rockylinux9-underpost:v2.98.3
104
104
  # resources:
105
105
  # requests:
106
106
  # memory: "124Ki"
@@ -18,7 +18,7 @@ spec:
18
18
  spec:
19
19
  containers:
20
20
  - name: dd-test-development-blue
21
- image: localhost/rockylinux9-underpost:v2.98.1
21
+ image: localhost/rockylinux9-underpost:v2.98.3
22
22
 
23
23
  command:
24
24
  - /bin/sh
@@ -103,7 +103,7 @@ spec:
103
103
  spec:
104
104
  containers:
105
105
  - name: dd-test-development-green
106
- image: localhost/rockylinux9-underpost:v2.98.1
106
+ image: localhost/rockylinux9-underpost:v2.98.3
107
107
 
108
108
  command:
109
109
  - /bin/sh
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "type": "module",
3
3
  "main": "src/index.js",
4
4
  "name": "@underpostnet/underpost",
5
- "version": "2.98.1",
5
+ "version": "2.98.3",
6
6
  "description": "pwa api rest template",
7
7
  "scripts": {
8
8
  "start": "env-cmd -f .env.production node --max-old-space-size=8192 src/server",
@@ -8,50 +8,50 @@ import { DocumentService } from '../../services/document/document.service.js';
8
8
  import { CoreService, getApiBaseUrl, headersFactory } from '../../services/core/core.service.js';
9
9
  import { loggerFactory } from './Logger.js';
10
10
  import { imageShimmer, renderChessPattern, renderCssAttr, styleFactory } from './Css.js';
11
- import { getQueryParams } from './Router.js';
11
+ import { getQueryParams, setPath } from './Router.js';
12
12
 
13
13
  const logger = loggerFactory(import.meta);
14
14
 
15
15
  const attachMarkdownLinkHandlers = (containerSelector) => {
16
- const links = sa(`${containerSelector} a[href]`);
17
- links.forEach((link) => {
18
- link.addEventListener('click', async (e) => {
19
- e.preventDefault();
20
- const href = link.getAttribute('href');
21
-
22
- // Check if link is external
23
- const isExternal = href.startsWith('http://') || href.startsWith('https://');
24
-
25
- if (isExternal) {
26
- // Show warning modal for external links
27
- const result = await Modal.RenderConfirm({
28
- id: `external-link-${s4()}`,
29
- html: async () => html`
30
- <div class="in section-mp" style="text-align: center; padding: 20px;">
31
- <p>${Translate.Render('external-link-warning')}</p>
32
- <p style="word-break: break-all; margin-top: 10px;"><strong>${href}</strong></p>
33
- </div>
34
- `,
35
- icon: html`<i class="fas fa-external-link-alt"></i>`,
36
- style: {
37
- width: '350px',
38
- height: '500px',
39
- overflow: 'auto',
40
- 'z-index': '11',
41
- resize: 'none',
42
- },
43
- });
44
-
45
- // Only open link if user confirmed (not cancelled or closed)
46
- if (result && result.status === 'confirm') {
47
- window.open(href, '_blank', 'noopener,noreferrer');
48
- }
49
- // If cancelled, do nothing - don't navigate
50
- } else {
51
- // Internal link - navigate normally
52
- window.location.href = href;
16
+ const container = s(containerSelector);
17
+ if (!container || container.dataset.mdLinkHandler) return;
18
+ container.dataset.mdLinkHandler = 'true';
19
+
20
+ container.addEventListener('click', async (e) => {
21
+ const link = e.target.closest('.markdown-content a[href]');
22
+ if (!link) return;
23
+
24
+ const href = link.getAttribute('href');
25
+ if (!href || href.startsWith('#')) return;
26
+
27
+ e.preventDefault();
28
+ const isExternal = href.startsWith('http://') || href.startsWith('https://');
29
+
30
+ if (isExternal) {
31
+ const result = await Modal.RenderConfirm({
32
+ id: `external-link-${s4()}`,
33
+ html: async () => html`
34
+ <div class="in section-mp" style="text-align: center; padding: 20px;">
35
+ <p>${Translate.Render('external-link-warning')}</p>
36
+ <p style="word-break: break-all; margin-top: 10px;"><strong>${href}</strong></p>
37
+ </div>
38
+ `,
39
+ icon: html`<i class="fas fa-external-link-alt"></i>`,
40
+ style: {
41
+ width: '350px',
42
+ height: '500px',
43
+ overflow: 'auto',
44
+ 'z-index': '11',
45
+ resize: 'none',
46
+ },
47
+ });
48
+
49
+ if (result && result.status === 'confirm') {
50
+ window.open(href, '_blank', 'noopener,noreferrer');
53
51
  }
54
- });
52
+ } else {
53
+ setPath(href);
54
+ }
55
55
  });
56
56
  };
57
57
 
@@ -214,7 +214,9 @@ const Content = {
214
214
  case 'md':
215
215
  {
216
216
  const content = await Content.getFileContent(file, options);
217
- render += html`<div class="${options.class}" ${styleFactory(options.style)}>${marked.parse(content)}</div>`;
217
+ render += html`<div class="${options.class} markdown-content" ${styleFactory(options.style)}>
218
+ ${marked.parse(content)}
219
+ </div>`;
218
220
  }
219
221
  break;
220
222
 
@@ -1,31 +1,224 @@
1
+ /**
2
+ * Utility module for fullscreen mode management with cross-browser and PWA compatibility.
3
+ * Provides robust fullscreen detection, event handling, and UI synchronization.
4
+ * @module src/client/components/core/FullScreen.js
5
+ * @namespace FullScreenClient
6
+ */
7
+
1
8
  import { Responsive } from './Responsive.js';
2
9
  import { ToggleSwitch } from './ToggleSwitch.js';
3
10
  import { Translate } from './Translate.js';
4
11
  import { checkFullScreen, fullScreenIn, fullScreenOut, s } from './VanillaJs.js';
5
12
 
13
+ /**
14
+ * Manages fullscreen mode state, event handling, and UI synchronization.
15
+ * Supports all major browsers and PWA/Nativefier environments with comprehensive
16
+ * vendor-prefixed API detection.
17
+ * @memberof FullScreenClient
18
+ */
6
19
  const FullScreen = {
20
+ /**
21
+ * Internal state flag tracking the intended fullscreen mode.
22
+ * @type {boolean}
23
+ * @private
24
+ */
25
+ _fullScreenSwitch: false,
26
+
27
+ /**
28
+ * Flag indicating whether event listeners have been attached.
29
+ * Prevents duplicate event listener registration.
30
+ * @type {boolean}
31
+ * @private
32
+ */
33
+ _eventListenersAdded: false,
34
+
35
+ /**
36
+ * Flag preventing concurrent sync operations.
37
+ * Ensures state synchronization happens sequentially.
38
+ * @type {boolean}
39
+ * @private
40
+ */
41
+ _syncInProgress: false,
42
+
43
+ /**
44
+ * Checks if the browser is currently in fullscreen mode.
45
+ * Supports all vendor-prefixed fullscreen APIs for maximum compatibility:
46
+ * - Standard Fullscreen API
47
+ * - Webkit (Chrome, Safari, Opera)
48
+ * - Mozilla (Firefox)
49
+ * - Microsoft (IE/Edge)
50
+ * @private
51
+ * @memberof FullScreenClient.FullScreen
52
+ * @returns {boolean} True if currently in fullscreen mode, false otherwise.
53
+ */
54
+ _isFullScreen: function () {
55
+ return !!(
56
+ document.fullscreenElement ||
57
+ document.webkitFullscreenElement ||
58
+ document.mozFullScreenElement ||
59
+ document.msFullscreenElement ||
60
+ document.fullscreen ||
61
+ document.webkitIsFullScreen ||
62
+ document.mozFullScreen
63
+ );
64
+ },
65
+
66
+ /**
67
+ * Synchronizes the toggle switch UI state with the actual fullscreen state.
68
+ * Prevents race conditions using the _syncInProgress flag.
69
+ * Updates the toggle switch only if there's a mismatch between UI and actual state.
70
+ * @private
71
+ * @memberof FullScreenClient.FullScreen
72
+ * @returns {void}
73
+ */
74
+ _syncToggleState: function () {
75
+ if (this._syncInProgress) return;
76
+ this._syncInProgress = true;
77
+
78
+ const actualFullScreen = this._isFullScreen();
79
+
80
+ // Only update if there's a mismatch
81
+ if (this._fullScreenSwitch !== actualFullScreen) {
82
+ this._fullScreenSwitch = actualFullScreen;
83
+
84
+ // Update toggle switch UI if it exists
85
+ const toggle = s('.fullscreen');
86
+ if (toggle && ToggleSwitch.Tokens[`fullscreen`]) {
87
+ const switchState = ToggleSwitch.Tokens[`fullscreen`].checked;
88
+ if (switchState !== actualFullScreen) {
89
+ ToggleSwitch.Tokens[`fullscreen`].click();
90
+ }
91
+ }
92
+ }
93
+
94
+ setTimeout(() => {
95
+ this._syncInProgress = false;
96
+ }, 100);
97
+ },
98
+
99
+ /**
100
+ * Event handler for fullscreen change events.
101
+ * Triggers UI state synchronization when fullscreen mode changes.
102
+ * @private
103
+ * @memberof FullScreenClient.FullScreen
104
+ * @returns {void}
105
+ */
106
+ _handleFullScreenChange: function () {
107
+ this._syncToggleState();
108
+ },
109
+
110
+ /**
111
+ * Attaches all necessary event listeners for fullscreen mode detection.
112
+ * Handles multiple scenarios:
113
+ * - Vendor-prefixed fullscreen change events (Chrome, Firefox, IE/Edge)
114
+ * - Window resize events (for PWA/Nativefier compatibility)
115
+ * - ESC key detection (fallback for manual fullscreen exit)
116
+ * Only attaches listeners once to prevent duplicates.
117
+ * @private
118
+ * @memberof FullScreenClient.FullScreen
119
+ * @returns {void}
120
+ */
121
+ _addEventListeners: function () {
122
+ if (this._eventListenersAdded) return;
123
+
124
+ const events = ['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange', 'MSFullscreenChange'];
125
+
126
+ events.forEach((eventName) => {
127
+ document.addEventListener(eventName, () => this._handleFullScreenChange(), false);
128
+ });
129
+
130
+ // Additional check for PWA/Nativefier window resize events
131
+ window.addEventListener(
132
+ 'resize',
133
+ () => {
134
+ setTimeout(() => this._syncToggleState(), 150);
135
+ },
136
+ false,
137
+ );
138
+
139
+ // ESC key detection fallback
140
+ document.addEventListener(
141
+ 'keydown',
142
+ (e) => {
143
+ if (e.key === 'Escape' || e.keyCode === 27) {
144
+ setTimeout(() => this._syncToggleState(), 100);
145
+ }
146
+ },
147
+ false,
148
+ );
149
+
150
+ this._eventListenersAdded = true;
151
+ },
152
+
153
+ /**
154
+ * Enters fullscreen mode if not already in fullscreen.
155
+ * Updates internal state and triggers fullscreen API.
156
+ * Verifies the state change after a delay to ensure synchronization.
157
+ * @private
158
+ * @memberof FullScreenClient.FullScreen
159
+ * @returns {void}
160
+ */
161
+ _enterFullScreen: function () {
162
+ if (this._isFullScreen()) return;
163
+
164
+ this._fullScreenSwitch = true;
165
+ fullScreenIn();
166
+
167
+ // Verify after attempt
168
+ setTimeout(() => this._syncToggleState(), 300);
169
+ },
170
+
171
+ /**
172
+ * Exits fullscreen mode if currently in fullscreen.
173
+ * Updates internal state and triggers fullscreen exit API.
174
+ * Verifies the state change after a delay to ensure synchronization.
175
+ * @private
176
+ * @memberof FullScreenClient.FullScreen
177
+ * @returns {void}
178
+ */
179
+ _exitFullScreen: function () {
180
+ if (!this._isFullScreen()) return;
181
+
182
+ this._fullScreenSwitch = false;
183
+ fullScreenOut();
184
+
185
+ // Verify after attempt
186
+ setTimeout(() => this._syncToggleState(), 300);
187
+ },
188
+
189
+ /**
190
+ * Renders the fullscreen toggle setting UI component.
191
+ * Initializes fullscreen state detection, sets up event listeners,
192
+ * and creates a toggle switch for user interaction.
193
+ * Integrates with the Responsive system for dynamic updates.
194
+ * @memberof FullScreenClient.FullScreen
195
+ * @returns {Promise<string>} A promise resolving to the HTML string for the fullscreen setting component.
196
+ */
7
197
  RenderSetting: async function () {
8
- let fullScreenSwitch = checkFullScreen();
198
+ // Initialize state from actual fullscreen status
199
+ this._fullScreenSwitch = this._isFullScreen();
200
+
201
+ // Setup event listeners once
202
+ this._addEventListeners();
203
+
204
+ // Update responsive event
9
205
  Responsive.Event['full-screen-settings'] = () => {
10
- let fullScreenMode = checkFullScreen();
11
- if ((fullScreenSwitch && !fullScreenMode) || (!fullScreenSwitch && fullScreenMode))
12
- if (s('.fullscreen')) ToggleSwitch.Tokens[`fullscreen`].click();
206
+ this._syncToggleState();
13
207
  };
208
+
14
209
  return html`<div class="in section-mp">
15
210
  ${await ToggleSwitch.Render({
16
211
  wrapper: true,
17
212
  wrapperLabel: html`<i class="fa-solid fa-expand"></i> ${Translate.Render('fullscreen')}`,
18
213
  id: 'fullscreen',
19
214
  disabledOnClick: true,
20
- checked: fullScreenSwitch,
215
+ checked: this._fullScreenSwitch,
21
216
  on: {
22
217
  unchecked: () => {
23
- fullScreenSwitch = false;
24
- if (checkFullScreen()) fullScreenOut();
218
+ this._exitFullScreen();
25
219
  },
26
220
  checked: () => {
27
- fullScreenSwitch = true;
28
- if (!checkFullScreen()) fullScreenIn();
221
+ this._enterFullScreen();
29
222
  },
30
223
  },
31
224
  })}
@@ -455,7 +455,9 @@ const PanelForm = {
455
455
 
456
456
  const baseNewDoc = newInstance(data);
457
457
  baseNewDoc.tags = tags.filter((t) => !prefixTags.includes(t));
458
- baseNewDoc.mdFileId = hasMdContent ? marked.parse(data.mdFileId) : null;
458
+ baseNewDoc.mdFileId = hasMdContent
459
+ ? `<div class="markdown-content">${marked.parse(data.mdFileId)}</div>`
460
+ : null;
459
461
  baseNewDoc.userId = Elements.Data.user?.main?.model?.user?._id;
460
462
 
461
463
  // Ensure profileImageId is properly formatted as object with _id property
@@ -677,7 +679,7 @@ const PanelForm = {
677
679
  mdPlain = await blobArray[0].text();
678
680
  // Parse markdown with proper error handling
679
681
  try {
680
- parsedMarkdown = mdPlain ? marked.parse(mdPlain) : '';
682
+ parsedMarkdown = mdPlain ? `<div class="markdown-content">${marked.parse(mdPlain)}</div>` : '';
681
683
  } catch (parseError) {
682
684
  logger.error('Error parsing markdown for document:', documentObject._id, parseError);
683
685
  parsedMarkdown = `<p><strong>Error rendering markdown:</strong> ${parseError.message}</p>`;
@@ -174,52 +174,103 @@ const disableOptionsClick = (element, types) => {
174
174
 
175
175
  /**
176
176
  * The function `checkFullScreen` checks if the document is in full screen mode and returns a boolean
177
- * value accordingly.
178
- * @returns The function `checkFullScreen` is returning `true` if `document.fullscreenElement` is
179
- * truthy, otherwise it returns `false`.
177
+ * value accordingly. Checks all vendor-prefixed APIs for maximum compatibility.
178
+ * @returns The function `checkFullScreen` is returning `true` if any fullscreen API indicates
179
+ * fullscreen mode is active, otherwise it returns `false`.
180
180
  * @memberof VanillaJS
181
181
  */
182
182
  const checkFullScreen = () => {
183
- // !(!window.screenTop && !window.screenY) ||
184
- return document.fullscreenElement ? true : false;
183
+ return !!(
184
+ document.fullscreenElement ||
185
+ document.webkitFullscreenElement ||
186
+ document.mozFullScreenElement ||
187
+ document.msFullscreenElement ||
188
+ document.fullscreen ||
189
+ document.webkitIsFullScreen ||
190
+ document.mozFullScreen
191
+ );
185
192
  };
186
193
 
187
194
  /**
188
195
  * The function `fullScreenOut` is used to exit full screen mode in a web browser.
196
+ * Handles all vendor-prefixed APIs and returns a promise for better control flow.
197
+ * @returns {Promise<boolean>} Promise that resolves to true if exit was attempted
189
198
  * @memberof VanillaJS
190
199
  */
191
200
  const fullScreenOut = () => {
192
- if (document.exitFullscreen) {
193
- document.exitFullscreen();
194
- } else if (document.mozCancelFullScreen) {
195
- document.mozCancelFullScreen();
196
- } else if (document.webkitExitFullscreen) {
197
- document.webkitExitFullscreen();
198
- } else if (document.msExitFullscreen) {
199
- window.top.document.msExitFullscreen();
200
- }
201
+ return new Promise((resolve) => {
202
+ if (!checkFullScreen()) {
203
+ resolve(true);
204
+ return;
205
+ }
206
+
207
+ try {
208
+ if (document.exitFullscreen) {
209
+ document
210
+ .exitFullscreen()
211
+ .then(() => resolve(true))
212
+ .catch(() => resolve(false));
213
+ } else if (document.webkitExitFullscreen) {
214
+ document.webkitExitFullscreen();
215
+ setTimeout(() => resolve(true), 100);
216
+ } else if (document.mozCancelFullScreen) {
217
+ document.mozCancelFullScreen();
218
+ setTimeout(() => resolve(true), 100);
219
+ } else if (document.msExitFullscreen) {
220
+ document.msExitFullscreen();
221
+ setTimeout(() => resolve(true), 100);
222
+ } else {
223
+ resolve(false);
224
+ }
225
+ } catch (err) {
226
+ console.warn('Fullscreen exit error:', err);
227
+ resolve(false);
228
+ }
229
+ });
201
230
  };
202
231
 
203
232
  /**
204
233
  * The `fullScreenIn` function is used to request full screen mode in a web browser using different
205
- * vendor-specific methods.
234
+ * vendor-specific methods. Returns a promise for better control flow.
235
+ * @returns {Promise<boolean>} Promise that resolves to true if fullscreen was requested
206
236
  * @memberof VanillaJS
207
237
  */
208
238
  const fullScreenIn = () => {
209
- const elem = document.documentElement;
210
- if (elem.requestFullscreen) {
211
- elem.requestFullscreen();
212
- } else if (elem.mozRequestFullScreen) {
213
- /* Firefox */
214
- elem.mozRequestFullScreen();
215
- } else if (elem.webkitRequestFullscreen) {
216
- /* Chrome, Safari & Opera */
217
- elem.webkitRequestFullscreen();
218
- } else if (elem.msRequestFullscreen) {
219
- /* IE/Edge */
220
- elem = window.top.document.body; //To break out of frame in IE
221
- elem.msRequestFullscreen();
222
- }
239
+ return new Promise((resolve) => {
240
+ if (checkFullScreen()) {
241
+ resolve(true);
242
+ return;
243
+ }
244
+
245
+ const elem = document.documentElement;
246
+
247
+ try {
248
+ if (elem.requestFullscreen) {
249
+ elem
250
+ .requestFullscreen()
251
+ .then(() => resolve(true))
252
+ .catch(() => resolve(false));
253
+ } else if (elem.webkitRequestFullscreen) {
254
+ /* Chrome, Safari & Opera */
255
+ elem.webkitRequestFullscreen();
256
+ setTimeout(() => resolve(true), 100);
257
+ } else if (elem.mozRequestFullScreen) {
258
+ /* Firefox */
259
+ elem.mozRequestFullScreen();
260
+ setTimeout(() => resolve(true), 100);
261
+ } else if (elem.msRequestFullscreen) {
262
+ /* IE/Edge */
263
+ const msElem = window.top.document.body;
264
+ msElem.msRequestFullscreen();
265
+ setTimeout(() => resolve(true), 100);
266
+ } else {
267
+ resolve(false);
268
+ }
269
+ } catch (err) {
270
+ console.warn('Fullscreen request error:', err);
271
+ resolve(false);
272
+ }
273
+ });
223
274
  };
224
275
 
225
276
  /**
package/src/index.js CHANGED
@@ -36,7 +36,7 @@ class Underpost {
36
36
  * @type {String}
37
37
  * @memberof Underpost
38
38
  */
39
- static version = 'v2.98.1';
39
+ static version = 'v2.98.3';
40
40
  /**
41
41
  * Repository cli API
42
42
  * @static